fix: various fixes and doc updates

pull/38/head
Travis Fischer 2022-12-06 18:19:30 -06:00
rodzic ec49713843
commit c8b3ac7029
6 zmienionych plików z 62 dodań i 31 usunięć

Wyświetl plik

@ -10,6 +10,7 @@
"types": "./build/index.d.ts", "types": "./build/index.d.ts",
"exports": { "exports": {
".": { ".": {
"browser": "./build/browser/index.js",
"import": "./build/index.js", "import": "./build/index.js",
"types": "./build/index.d.ts", "types": "./build/index.d.ts",
"default": "./build/index.js" "default": "./build/index.js"
@ -26,7 +27,7 @@
"dev": "tsup --watch", "dev": "tsup --watch",
"clean": "del build", "clean": "del build",
"prebuild": "run-s clean", "prebuild": "run-s clean",
"postbuild": "sed -i 's/ *\\?\\? *(await import(\"undici\")).fetch//' build/browser/index.js", "postbuild": "[ -n CI ] && sed -i '' 's/ *\\?\\? *(await import(\"undici\")).fetch//' build/browser/index.js || echo 'skipping postbuild on CI'",
"predev": "run-s clean", "predev": "run-s clean",
"pretest": "run-s build", "pretest": "run-s build",
"docs": "typedoc", "docs": "typedoc",

Wyświetl plik

@ -13,6 +13,7 @@
- [Usage](#usage) - [Usage](#usage)
- [Docs](#docs) - [Docs](#docs)
- [How it works](#how-it-works) - [How it works](#how-it-works)
- [Compatibility](#compatibility)
- [Examples](#examples) - [Examples](#examples)
- [Credit](#credit) - [Credit](#credit)
- [License](#license) - [License](#license)
@ -114,6 +115,19 @@ If you want to run the built-in demo, store this value as `SESSION_TOKEN` in a l
> **Note** > **Note**
> Prior to v1.0.0, this package used a headless browser via [Playwright](https://playwright.dev/) to automate the web UI. Here are the [docs for the initial browser version](https://github.com/transitive-bullshit/chatgpt-api/tree/v0.4.2). > Prior to v1.0.0, this package used a headless browser via [Playwright](https://playwright.dev/) to automate the web UI. Here are the [docs for the initial browser version](https://github.com/transitive-bullshit/chatgpt-api/tree/v0.4.2).
## Compatibility
This package is ESM-only. It supports:
- Node.js >= 16.8
- If you need Node.js 14 support, use [`v1.4.0`](https://github.com/transitive-bullshit/chatgpt-api/releases/tag/v1.4.0)
- If you need CommonJS support, use [`v1.3.0`](https://github.com/transitive-bullshit/chatgpt-api/releases/tag/v1.3.0)
- Edge runtimes like CF workers and Vercel edge functions
- Modern browsers
- This is mainly intended for chrome extensions where your code is protected to a degree
- **We do not recommend using `chatgpt` from client-side browser code** because it would expose your private session token
- If you want to build a website with `chatgpt`, we recommend using it only from your backend API
## Examples ## Examples
All of these awesome projects are built using the `chatgpt` package. 🤯 All of these awesome projects are built using the `chatgpt` package. 🤯

Wyświetl plik

@ -12,9 +12,6 @@ const USER_AGENT =
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36' 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36'
export class ChatGPTAPI { export class ChatGPTAPI {
public conversationId: string = undefined
public parentMessageId: string = undefined
protected _sessionToken: string protected _sessionToken: string
protected _markdown: boolean protected _markdown: boolean
protected _apiBaseUrl: string protected _apiBaseUrl: string
@ -86,22 +83,15 @@ export class ChatGPTAPI {
* @param message - The prompt message to send * @param message - The prompt message to send
* @param opts.conversationId - Optional ID of a conversation to continue * @param opts.conversationId - Optional ID of a conversation to continue
* @param opts.parentMessageId - Optional ID of the previous message in the conversation * @param opts.parentMessageId - Optional ID of the previous message in the conversation
* @param opts.onProgress - Optional function which will be called every time the partial response is updated * @param opts.onProgress - Optional callback which will be invoked every time the partial response is updated
* @param opts.onConversationResponse - Optional function which will be called every time the partial response is updated with the full conversation response * @param opts.onConversationResponse - Optional callback which will be invoked every time the partial response is updated with the full conversation response
* @param opts.abortSignal - Optional function used to abort the underlying `fetch` call using an [AbortController](https://developer.mozilla.org/en-US/docs/Web/API/AbortController) * @param opts.abortSignal - Optional callback used to abort the underlying `fetch` call using an [AbortController](https://developer.mozilla.org/en-US/docs/Web/API/AbortController)
*
* @returns The response from ChatGPT * @returns The response from ChatGPT
*/ */
async sendMessage( async sendMessage(
message: string, message: string,
opts: { opts: types.SendMessageOptions = {}
conversationId?: string
parentMessageId?: string
onProgress?: (partialResponse: string) => void
onConversationResponse?: (
response: types.ConversationResponseEvent
) => void
abortSignal?: AbortSignal
} = {}
): Promise<string> { ): Promise<string> {
const { const {
conversationId, conversationId,
@ -161,6 +151,7 @@ export class ChatGPTAPI {
if (onConversationResponse) { if (onConversationResponse) {
onConversationResponse(parsedData) onConversationResponse(parsedData)
} }
const message = parsedData.message const message = parsedData.message
// console.log('event', JSON.stringify(parsedData, null, 2)) // console.log('event', JSON.stringify(parsedData, null, 2))
@ -201,7 +192,13 @@ export class ChatGPTAPI {
cookie: `__Secure-next-auth.session-token=${this._sessionToken}`, cookie: `__Secure-next-auth.session-token=${this._sessionToken}`,
'user-agent': this._userAgent 'user-agent': this._userAgent
} }
}).then((r) => r.json() as any as types.SessionResult) }).then((r) => {
if (!r.ok) {
throw new Error(`${r.status} ${r.statusText}`)
}
return r.json() as any as types.SessionResult
})
const accessToken = res?.accessToken const accessToken = res?.accessToken

Wyświetl plik

@ -39,28 +39,30 @@ export class ChatGPTConversation {
* for each message. * for each message.
* *
* @param message - The prompt message to send * @param message - The prompt message to send
* @param opts.onProgress - Optional listener which will be called every time the partial response is updated * @param opts.onProgress - Optional callback which will be invoked every time the partial response is updated
* @param opts.onConversationResponse - Optional listener which will be called every time a conversation response is received * @param opts.onConversationResponse - Optional callback which will be invoked every time the partial response is updated with the full conversation response
* @param opts.abortSignal - Optional callback used to abort the underlying `fetch` call using an [AbortController](https://developer.mozilla.org/en-US/docs/Web/API/AbortController)
*
* @returns The response from ChatGPT * @returns The response from ChatGPT
*/ */
async sendMessage( async sendMessage(
message: string, message: string,
opts: { opts: types.SendConversationMessageOptions = {}
onProgress?: (partialResponse: string) => void
onConversationResponse?: (
response: types.ConversationResponseEvent
) => void
} = {}
): Promise<string> { ): Promise<string> {
const { onProgress, onConversationResponse } = opts const { onConversationResponse, ...rest } = opts
return this.api.sendMessage(message, { return this.api.sendMessage(message, {
...rest,
conversationId: this.conversationId, conversationId: this.conversationId,
parentMessageId: this.parentMessageId, parentMessageId: this.parentMessageId,
onProgress,
onConversationResponse: (response) => { onConversationResponse: (response) => {
this.conversationId = response.conversation_id if (response.conversation_id) {
this.parentMessageId = response.message.id this.conversationId = response.conversation_id
}
if (response.message?.id) {
this.parentMessageId = response.message.id
}
if (onConversationResponse) { if (onConversationResponse) {
return onConversationResponse(response) return onConversationResponse(response)

Wyświetl plik

@ -8,14 +8,18 @@ export async function fetchSSE(
options: Parameters<typeof fetch>[1] & { onMessage: (data: string) => void } options: Parameters<typeof fetch>[1] & { onMessage: (data: string) => void }
) { ) {
const { onMessage, ...fetchOptions } = options const { onMessage, ...fetchOptions } = options
const resp = await fetch(url, fetchOptions) const res = await fetch(url, fetchOptions)
if (!res.ok) {
throw new Error(`ChatGPTAPI error ${res.status || res.statusText}`)
}
const parser = createParser((event) => { const parser = createParser((event) => {
if (event.type === 'event') { if (event.type === 'event') {
onMessage(event.data) onMessage(event.data)
} }
}) })
for await (const chunk of streamAsyncIterable(resp.body)) { for await (const chunk of streamAsyncIterable(res.body)) {
const str = new TextDecoder().decode(chunk) const str = new TextDecoder().decode(chunk)
parser.feed(str) parser.feed(str)
} }

Wyświetl plik

@ -273,3 +273,16 @@ export type MessageContent = {
} }
export type MessageMetadata = any export type MessageMetadata = any
export type SendMessageOptions = {
conversationId?: string
parentMessageId?: string
onProgress?: (partialResponse: string) => void
onConversationResponse?: (response: ConversationResponseEvent) => void
abortSignal?: AbortSignal
}
export type SendConversationMessageOptions = Omit<
SendMessageOptions,
'conversationId' | 'parentMessageId'
>