From debbf07823cfcda61abe35eb30dca2980af67639 Mon Sep 17 00:00:00 2001 From: Matthieu Balmes Date: Sun, 21 Jan 2024 20:51:54 +0100 Subject: [PATCH] feat(thread): add a ID to thread to help the application identify them --- dist/index.cjs | 16 +++++----- dist/index.cjs.map | 2 +- dist/index.esm.js | 12 +++---- dist/index.esm.js.map | 2 +- dist/index.js | 16 +++++----- dist/index.js.map | 2 +- dist/index.mjs | 12 +++---- dist/index.mjs.map | 2 +- docs/README.md | 22 ++++++------- docs/classes/Assistant.md | 14 ++++----- docs/classes/RequiredAction.md | 6 ++-- docs/classes/Thread.md | 40 +++++++++++++++--------- docs/interfaces/AssistantCreateParams.md | 10 +++--- docs/interfaces/ToolOutput.md | 6 ++-- package.json | 2 +- src/thread/thread.spec.ts | 4 ++- src/thread/thread.ts | 17 +++++----- types/thread/thread.d.ts | 3 +- types/thread/thread.d.ts.map | 2 +- 19 files changed, 98 insertions(+), 92 deletions(-) diff --git a/dist/index.cjs b/dist/index.cjs index 7b86844..a501a93 100644 --- a/dist/index.cjs +++ b/dist/index.cjs @@ -127,26 +127,21 @@ class ThreadMessageConverter { } class Thread extends EventEmitter { - constructor(messages = []) { + constructor(id, messages = []) { super(); + this.id = id; this.messages = messages; this._stream = null; this.converter = new ThreadMessageConverter(); this.toolEmulator = new ToolEmulator(); } get stream() { - if (!this._stream) { - return null; - } return this._stream; } addMessage(message) { this.doAddMessage(message); } async run(assistant) { - this._stream = new stream.Readable({ - read: () => { }, - }); try { return await this.doRun(assistant); } @@ -155,13 +150,16 @@ class Thread extends EventEmitter { } } async doRun(assistant) { + this._stream = new stream.Readable({ + read: () => { }, + }); this.emitImmediate('in_progress'); const messages = this.converter.convert(this.messages); - const stream = await assistant.streamChatCompletions(messages); + const stream$1 = await assistant.streamChatCompletions(messages); let content = null; const toolCalls = []; let functionCall = undefined; - stream.on('data', (completion) => { + stream$1.on('data', (completion) => { if (!completion.id || completion.id === '') { // First completion is empty when using old models like gpt-35-turbo return; diff --git a/dist/index.cjs.map b/dist/index.cjs.map index e239268..805856f 100644 --- a/dist/index.cjs.map +++ b/dist/index.cjs.map @@ -1 +1 @@ -{"version":3,"file":"index.cjs","sources":["../src/assistant/assistant.ts","../src/thread/tool.emulator.ts","../src/thread/message.converter.ts","../src/thread/thread.ts"],"sourcesContent":["import type {\n ChatRequestMessage,\n ChatRequestSystemMessage,\n GetChatCompletionsOptions,\n OpenAIClient,\n} from '@azure/openai';\nimport type { ChatCompletionsToolDefinition } from '@azure/openai/types/src/models/models';\nimport { Readable } from 'stream';\n\nexport interface AssistantCreateParams {\n client: OpenAIClient;\n instructions: string;\n tools: ChatCompletionsToolDefinition[];\n deployment: string;\n useLegacyFunctions?: boolean;\n}\n\nexport class Assistant {\n public readonly client: OpenAIClient;\n\n private readonly instructions: string;\n private readonly tools: ChatCompletionsToolDefinition[];\n private readonly deployment: string;\n private readonly useLegacyFunctions: boolean;\n\n constructor(params: AssistantCreateParams) {\n this.client = params.client;\n this.instructions = params.instructions;\n this.tools = params.tools;\n this.deployment = params.deployment;\n this.useLegacyFunctions = params.useLegacyFunctions ?? false;\n }\n\n async streamChatCompletions(\n messages: ChatRequestMessage[],\n ): Promise {\n // Prepend the messages with our instructions as a \"system\" message\n const systemMessage: ChatRequestSystemMessage = {\n role: 'system',\n content: this.instructions,\n };\n messages = [systemMessage, ...messages];\n\n const options: GetChatCompletionsOptions = {};\n\n if (this.tools.length > 0) {\n if (this.useLegacyFunctions) {\n // Convert tools to functions\n options.functions = this.tools.map((tool) => {\n return tool.function;\n });\n } else {\n options.tools = this.tools;\n }\n }\n const events = await this.client.streamChatCompletions(\n this.deployment,\n messages,\n options,\n );\n\n return Readable.from(events);\n }\n}\n","import type { FunctionCall } from '@azure/openai';\n\nconst EMULATED_CALL_PREFIX = 'emulated_call_';\n\n/**\n * Helps with the conversion of tool calls to function calls and vice versa.\n */\nexport class ToolEmulator {\n generateEmulatedToolCallId(functionCall: FunctionCall): string {\n return `${EMULATED_CALL_PREFIX}${functionCall.name}`;\n }\n\n isEmulatedToolCallId(toolCallId: string): boolean {\n return toolCallId.startsWith(EMULATED_CALL_PREFIX);\n }\n\n extractFunctionNameFromEmulatedToolCallId(toolCallId: string): string {\n return toolCallId.replace(EMULATED_CALL_PREFIX, '');\n }\n}\n","import type {\n ChatRequestAssistantMessage,\n ChatRequestFunctionMessage,\n ChatRequestMessage,\n ChatRequestSystemMessage,\n ChatRequestToolMessage,\n ChatRequestUserMessage,\n} from '@azure/openai';\nimport type {\n ChatMessage,\n ChatRequestSystemMessageWithMetadata,\n ChatRequestToolMessageWithMetadata,\n ChatRequestUserMessageWithMetadata,\n ChatResponseMessageWithMetadata,\n} from '../message';\nimport { ToolEmulator } from './tool.emulator';\n\nexport class ThreadMessageConverter {\n private readonly toolEmulator = new ToolEmulator();\n\n /**\n * Convert the mix of ChatRequestMessages and ChatResponseMessages to ChatRequestMessages only\n * so they can be sent again to the LLM.\n */\n convert(messages: ChatMessage[]): ChatRequestMessage[] {\n return messages.map((m) => {\n switch (m.role) {\n case 'system': {\n const systemMessage =\n m as ChatRequestSystemMessageWithMetadata;\n return {\n role: 'system',\n content: systemMessage.content,\n } as ChatRequestSystemMessage;\n }\n case 'user': {\n const userMessage = m as ChatRequestUserMessageWithMetadata;\n return {\n role: 'user',\n content: userMessage.content,\n name: userMessage.name,\n } as ChatRequestUserMessage;\n }\n case 'tool': {\n const toolMessage = m as ChatRequestToolMessageWithMetadata;\n if (\n this.toolEmulator.isEmulatedToolCallId(\n toolMessage.toolCallId,\n )\n ) {\n return {\n role: 'function',\n content: toolMessage.content,\n name: this.toolEmulator.extractFunctionNameFromEmulatedToolCallId(\n toolMessage.toolCallId,\n ),\n } as ChatRequestFunctionMessage;\n }\n return {\n role: 'tool',\n content: toolMessage.content,\n toolCallId: toolMessage.toolCallId,\n } as ChatRequestToolMessage;\n }\n case 'assistant': {\n const assistantMessage =\n m as ChatResponseMessageWithMetadata;\n\n if (\n assistantMessage.toolCalls[0] &&\n this.toolEmulator.isEmulatedToolCallId(\n assistantMessage.toolCalls[0].id,\n )\n ) {\n // This is a function call\n return {\n role: 'assistant',\n content: assistantMessage.content,\n functionCall: {\n name: this.toolEmulator.extractFunctionNameFromEmulatedToolCallId(\n assistantMessage.toolCalls[0].id,\n ),\n arguments:\n assistantMessage.toolCalls[0].function\n .arguments,\n },\n } as ChatRequestAssistantMessage;\n }\n\n return {\n role: 'assistant',\n content: assistantMessage.content,\n toolCalls: assistantMessage.toolCalls,\n } as ChatRequestAssistantMessage;\n }\n default:\n throw new Error(`Unknown message role ${m.role}`);\n }\n });\n }\n}\n","import type {\n ChatCompletions,\n ChatCompletionsToolCall,\n ChatRequestMessage,\n ChatResponseMessage,\n FunctionCall,\n} from '@azure/openai';\nimport EventEmitter from 'events';\nimport { Readable } from 'stream';\nimport { Assistant } from '../assistant';\nimport type {\n ChatMessage,\n ChatRequestMessageWithMetadata,\n ChatRequestToolMessageWithMetadata,\n} from '../message';\nimport { ThreadMessageConverter } from './message.converter';\nimport { ToolEmulator } from './tool.emulator';\n\nexport class Thread extends EventEmitter {\n private _stream: Readable | null = null;\n private readonly converter = new ThreadMessageConverter();\n private readonly toolEmulator = new ToolEmulator();\n\n constructor(private readonly messages: ChatMessage[] = []) {\n super();\n }\n\n get stream(): Readable | null {\n if (!this._stream) {\n return null;\n }\n\n return this._stream;\n }\n\n addMessage(message: ChatRequestMessageWithMetadata): void {\n this.doAddMessage(message);\n }\n\n async run(assistant: Assistant): Promise {\n this._stream = new Readable({\n read: () => {},\n });\n\n try {\n return await this.doRun(assistant);\n } catch (e) {\n this.emitImmediate('error', e);\n }\n }\n\n private async doRun(assistant: Assistant): Promise {\n this.emitImmediate('in_progress');\n\n const messages = this.converter.convert(this.messages);\n\n const stream = await assistant.streamChatCompletions(messages);\n\n let content: string | null = null;\n const toolCalls: ChatCompletionsToolCall[] = [];\n let functionCall: FunctionCall | undefined = undefined;\n\n stream.on('data', (completion: ChatCompletions) => {\n if (!completion.id || completion.id === '') {\n // First completion is empty when using old models like gpt-35-turbo\n return;\n }\n const choice = completion.choices[0];\n if (!choice) {\n const err = new Error('No completions returned');\n return this.emitImmediate('error', err);\n }\n\n const delta = choice.delta;\n if (!delta) {\n const err = new Error('No delta returned');\n return this.emitImmediate('error', err);\n }\n\n if (delta.content) {\n content = content ? content + delta.content : delta.content;\n\n // Write also to the stream of the thread\n if (!this._stream) {\n const err = new Error('No stream available');\n return this.emitImmediate('error', err);\n }\n this._stream?.push(delta.content);\n }\n\n // Merge toolCalls\n if (delta.toolCalls) {\n for (const toolCall of delta.toolCalls) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n const index = toolCall['index']; // Not typed yet by the @azure/openai package\n const existingToolCall = toolCalls[index];\n\n if (existingToolCall) {\n existingToolCall.function.arguments +=\n toolCall.function.arguments;\n } else {\n toolCalls.push({\n type: toolCall.type,\n function: toolCall.function,\n id: toolCall.id,\n });\n }\n }\n }\n\n // Merge functionCalls\n if (delta.functionCall) {\n if (functionCall) {\n functionCall.arguments += delta.functionCall.arguments;\n } else {\n functionCall = {\n ...delta.functionCall,\n arguments: '',\n };\n }\n }\n\n if (choice.finishReason === null) {\n return;\n }\n\n let finalToolCalls: ChatCompletionsToolCall[];\n\n if (toolCalls.length > 0) {\n finalToolCalls = [...toolCalls];\n } else if (functionCall) {\n /**\n * We received a legacy function call, we convert it to a tool call with an emulated ID\n */\n const toolCall: ChatCompletionsToolCall = {\n type: 'function',\n function: functionCall,\n id: this.toolEmulator.generateEmulatedToolCallId(\n functionCall,\n ),\n };\n finalToolCalls = [toolCall];\n } else {\n finalToolCalls = [];\n }\n\n const message: ChatResponseMessage = {\n role: 'assistant',\n content,\n toolCalls: finalToolCalls,\n };\n\n content = null;\n toolCalls.splice(0, toolCalls.length);\n functionCall = undefined;\n\n this.doAddMessage(message);\n\n switch (choice.finishReason) {\n case 'stop':\n this._stream?.push(null);\n this.emitImmediate('completed');\n break;\n case 'tool_calls':\n case 'function_call': {\n if (message.toolCalls.length === 0) {\n const err = new Error('No tool calls returned');\n return this.emitImmediate('error', err);\n }\n this.dispatchRequiredAction(message.toolCalls, assistant);\n break;\n }\n default: {\n const err = new Error(\n `Unknown finish reason ${choice.finishReason}`,\n );\n return this.emitImmediate('error', err);\n }\n }\n });\n }\n\n private dispatchRequiredAction(\n toolCalls: ChatCompletionsToolCall[],\n assistant: Assistant,\n ): void {\n const requiredAction = new RequiredAction(toolCalls);\n requiredAction.on('submitting', async (toolOutputs: ToolOutput[]) =>\n this.handleSubmittedToolOutputs(toolOutputs, assistant),\n );\n this.emitImmediate('requires_action', requiredAction);\n }\n\n private async handleSubmittedToolOutputs(\n toolOutputs: ToolOutput[],\n assistant: Assistant,\n ): Promise {\n // Adds the tool outputs to the messages\n for (const toolOutput of toolOutputs) {\n const message: ChatRequestToolMessageWithMetadata = {\n role: 'tool',\n content: JSON.stringify(toolOutput.value),\n toolCallId: toolOutput.callId,\n };\n if (toolOutput.metadata !== void 0) {\n message.metadata = toolOutput.metadata;\n }\n this.doAddMessage(message);\n }\n\n return this.doRun(assistant);\n }\n\n private doAddMessage(\n message: ChatRequestMessage | ChatResponseMessage,\n ): void {\n this.messages.push(message);\n\n this.emitImmediate('message', message);\n\n if (isChatRequestMessage(message)) {\n this.emitImmediate('message:request', message);\n } else {\n this.emitImmediate('message:response', message);\n }\n }\n\n private emitImmediate(event: string, ...args: unknown[]): void {\n if (event === 'error') {\n this.emit(event, ...args);\n } else {\n setImmediate(() => {\n this.emit(event, ...args);\n });\n }\n }\n}\n\nexport class RequiredAction extends EventEmitter {\n constructor(public readonly toolCalls: ChatCompletionsToolCall[]) {\n super();\n }\n\n submitToolOutputs(toolOutputs: ToolOutput[]): void {\n this.emit('submitting', toolOutputs);\n }\n}\n\nexport interface ToolOutput {\n callId: string;\n value: unknown;\n metadata?: unknown;\n}\n\nexport function isChatResponseMessage(\n m: ChatRequestMessage | ChatResponseMessage,\n): m is ChatResponseMessage {\n return 'toolCalls' in m;\n}\n\nexport function isChatRequestMessage(\n m: ChatRequestMessage | ChatResponseMessage,\n): m is ChatRequestMessage {\n return !isChatResponseMessage(m);\n}\n"],"names":["Readable"],"mappings":";;;;;;;;;;;MAiBa,SAAS,CAAA;AAQlB,IAAA,WAAA,CAAY,MAA6B,EAAA;AACrC,QAAA,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;AAC5B,QAAA,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC;AACxC,QAAA,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;AAC1B,QAAA,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;QACpC,IAAI,CAAC,kBAAkB,GAAG,MAAM,CAAC,kBAAkB,IAAI,KAAK,CAAC;KAChE;IAED,MAAM,qBAAqB,CACvB,QAA8B,EAAA;;AAG9B,QAAA,MAAM,aAAa,GAA6B;AAC5C,YAAA,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,IAAI,CAAC,YAAY;SAC7B,CAAC;AACF,QAAA,QAAQ,GAAG,CAAC,aAAa,EAAE,GAAG,QAAQ,CAAC,CAAC;QAExC,MAAM,OAAO,GAA8B,EAAE,CAAC;AAE9C,QAAA,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE;YACvB,IAAI,IAAI,CAAC,kBAAkB,EAAE;;AAEzB,gBAAA,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,KAAI;oBACxC,OAAO,IAAI,CAAC,QAAQ,CAAC;AACzB,iBAAC,CAAC,CAAC;AACN,aAAA;AAAM,iBAAA;AACH,gBAAA,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;AAC9B,aAAA;AACJ,SAAA;AACD,QAAA,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,qBAAqB,CAClD,IAAI,CAAC,UAAU,EACf,QAAQ,EACR,OAAO,CACV,CAAC;AAEF,QAAA,OAAOA,eAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;KAChC;AACJ;;AC7DD,MAAM,oBAAoB,GAAG,gBAAgB,CAAC;AAE9C;;AAEG;MACU,YAAY,CAAA;AACrB,IAAA,0BAA0B,CAAC,YAA0B,EAAA;AACjD,QAAA,OAAO,GAAG,oBAAoB,CAAA,EAAG,YAAY,CAAC,IAAI,EAAE,CAAC;KACxD;AAED,IAAA,oBAAoB,CAAC,UAAkB,EAAA;AACnC,QAAA,OAAO,UAAU,CAAC,UAAU,CAAC,oBAAoB,CAAC,CAAC;KACtD;AAED,IAAA,yCAAyC,CAAC,UAAkB,EAAA;QACxD,OAAO,UAAU,CAAC,OAAO,CAAC,oBAAoB,EAAE,EAAE,CAAC,CAAC;KACvD;AACJ;;MCFY,sBAAsB,CAAA;AAAnC,IAAA,WAAA,GAAA;AACqB,QAAA,IAAA,CAAA,YAAY,GAAG,IAAI,YAAY,EAAE,CAAC;KAkFtD;AAhFG;;;AAGG;AACH,IAAA,OAAO,CAAC,QAAuB,EAAA;AAC3B,QAAA,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,KAAI;YACtB,QAAQ,CAAC,CAAC,IAAI;gBACV,KAAK,QAAQ,EAAE;oBACX,MAAM,aAAa,GACf,CAAyC,CAAC;oBAC9C,OAAO;AACH,wBAAA,IAAI,EAAE,QAAQ;wBACd,OAAO,EAAE,aAAa,CAAC,OAAO;qBACL,CAAC;AACjC,iBAAA;gBACD,KAAK,MAAM,EAAE;oBACT,MAAM,WAAW,GAAG,CAAuC,CAAC;oBAC5D,OAAO;AACH,wBAAA,IAAI,EAAE,MAAM;wBACZ,OAAO,EAAE,WAAW,CAAC,OAAO;wBAC5B,IAAI,EAAE,WAAW,CAAC,IAAI;qBACC,CAAC;AAC/B,iBAAA;gBACD,KAAK,MAAM,EAAE;oBACT,MAAM,WAAW,GAAG,CAAuC,CAAC;oBAC5D,IACI,IAAI,CAAC,YAAY,CAAC,oBAAoB,CAClC,WAAW,CAAC,UAAU,CACzB,EACH;wBACE,OAAO;AACH,4BAAA,IAAI,EAAE,UAAU;4BAChB,OAAO,EAAE,WAAW,CAAC,OAAO;4BAC5B,IAAI,EAAE,IAAI,CAAC,YAAY,CAAC,yCAAyC,CAC7D,WAAW,CAAC,UAAU,CACzB;yBAC0B,CAAC;AACnC,qBAAA;oBACD,OAAO;AACH,wBAAA,IAAI,EAAE,MAAM;wBACZ,OAAO,EAAE,WAAW,CAAC,OAAO;wBAC5B,UAAU,EAAE,WAAW,CAAC,UAAU;qBACX,CAAC;AAC/B,iBAAA;gBACD,KAAK,WAAW,EAAE;oBACd,MAAM,gBAAgB,GAClB,CAAoC,CAAC;AAEzC,oBAAA,IACI,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC;AAC7B,wBAAA,IAAI,CAAC,YAAY,CAAC,oBAAoB,CAClC,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CACnC,EACH;;wBAEE,OAAO;AACH,4BAAA,IAAI,EAAE,WAAW;4BACjB,OAAO,EAAE,gBAAgB,CAAC,OAAO;AACjC,4BAAA,YAAY,EAAE;AACV,gCAAA,IAAI,EAAE,IAAI,CAAC,YAAY,CAAC,yCAAyC,CAC7D,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CACnC;gCACD,SAAS,EACL,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,QAAQ;qCACjC,SAAS;AACrB,6BAAA;yBAC2B,CAAC;AACpC,qBAAA;oBAED,OAAO;AACH,wBAAA,IAAI,EAAE,WAAW;wBACjB,OAAO,EAAE,gBAAgB,CAAC,OAAO;wBACjC,SAAS,EAAE,gBAAgB,CAAC,SAAS;qBACT,CAAC;AACpC,iBAAA;AACD,gBAAA;oBACI,MAAM,IAAI,KAAK,CAAC,CAAA,qBAAA,EAAwB,CAAC,CAAC,IAAI,CAAE,CAAA,CAAC,CAAC;AACzD,aAAA;AACL,SAAC,CAAC,CAAC;KACN;AACJ;;AClFK,MAAO,MAAO,SAAQ,YAAY,CAAA;AAKpC,IAAA,WAAA,CAA6B,WAA0B,EAAE,EAAA;AACrD,QAAA,KAAK,EAAE,CAAC;QADiB,IAAQ,CAAA,QAAA,GAAR,QAAQ,CAAoB;QAJjD,IAAO,CAAA,OAAA,GAAoB,IAAI,CAAC;AACvB,QAAA,IAAA,CAAA,SAAS,GAAG,IAAI,sBAAsB,EAAE,CAAC;AACzC,QAAA,IAAA,CAAA,YAAY,GAAG,IAAI,YAAY,EAAE,CAAC;KAIlD;AAED,IAAA,IAAI,MAAM,GAAA;AACN,QAAA,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;AACf,YAAA,OAAO,IAAI,CAAC;AACf,SAAA;QAED,OAAO,IAAI,CAAC,OAAO,CAAC;KACvB;AAED,IAAA,UAAU,CAAC,OAAuC,EAAA;AAC9C,QAAA,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;KAC9B;IAED,MAAM,GAAG,CAAC,SAAoB,EAAA;AAC1B,QAAA,IAAI,CAAC,OAAO,GAAG,IAAIA,eAAQ,CAAC;AACxB,YAAA,IAAI,EAAE,MAAK,GAAG;AACjB,SAAA,CAAC,CAAC;QAEH,IAAI;AACA,YAAA,OAAO,MAAM,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;AACtC,SAAA;AAAC,QAAA,OAAO,CAAC,EAAE;AACR,YAAA,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;AAClC,SAAA;KACJ;IAEO,MAAM,KAAK,CAAC,SAAoB,EAAA;AACpC,QAAA,IAAI,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;AAElC,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAEvD,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC;QAE/D,IAAI,OAAO,GAAkB,IAAI,CAAC;QAClC,MAAM,SAAS,GAA8B,EAAE,CAAC;QAChD,IAAI,YAAY,GAA6B,SAAS,CAAC;QAEvD,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,UAA2B,KAAI;YAC9C,IAAI,CAAC,UAAU,CAAC,EAAE,IAAI,UAAU,CAAC,EAAE,KAAK,EAAE,EAAE;;gBAExC,OAAO;AACV,aAAA;YACD,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YACrC,IAAI,CAAC,MAAM,EAAE;AACT,gBAAA,MAAM,GAAG,GAAG,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;gBACjD,OAAO,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;AAC3C,aAAA;AAED,YAAA,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;YAC3B,IAAI,CAAC,KAAK,EAAE;AACR,gBAAA,MAAM,GAAG,GAAG,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;gBAC3C,OAAO,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;AAC3C,aAAA;YAED,IAAI,KAAK,CAAC,OAAO,EAAE;AACf,gBAAA,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;;AAG5D,gBAAA,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;AACf,oBAAA,MAAM,GAAG,GAAG,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;oBAC7C,OAAO,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;AAC3C,iBAAA;gBACD,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;AACrC,aAAA;;YAGD,IAAI,KAAK,CAAC,SAAS,EAAE;AACjB,gBAAA,KAAK,MAAM,QAAQ,IAAI,KAAK,CAAC,SAAS,EAAE;;;oBAGpC,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;AAChC,oBAAA,MAAM,gBAAgB,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;AAE1C,oBAAA,IAAI,gBAAgB,EAAE;wBAClB,gBAAgB,CAAC,QAAQ,CAAC,SAAS;AAC/B,4BAAA,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC;AACnC,qBAAA;AAAM,yBAAA;wBACH,SAAS,CAAC,IAAI,CAAC;4BACX,IAAI,EAAE,QAAQ,CAAC,IAAI;4BACnB,QAAQ,EAAE,QAAQ,CAAC,QAAQ;4BAC3B,EAAE,EAAE,QAAQ,CAAC,EAAE;AAClB,yBAAA,CAAC,CAAC;AACN,qBAAA;AACJ,iBAAA;AACJ,aAAA;;YAGD,IAAI,KAAK,CAAC,YAAY,EAAE;AACpB,gBAAA,IAAI,YAAY,EAAE;oBACd,YAAY,CAAC,SAAS,IAAI,KAAK,CAAC,YAAY,CAAC,SAAS,CAAC;AAC1D,iBAAA;AAAM,qBAAA;AACH,oBAAA,YAAY,GAAG;wBACX,GAAG,KAAK,CAAC,YAAY;AACrB,wBAAA,SAAS,EAAE,EAAE;qBAChB,CAAC;AACL,iBAAA;AACJ,aAAA;AAED,YAAA,IAAI,MAAM,CAAC,YAAY,KAAK,IAAI,EAAE;gBAC9B,OAAO;AACV,aAAA;AAED,YAAA,IAAI,cAAyC,CAAC;AAE9C,YAAA,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE;AACtB,gBAAA,cAAc,GAAG,CAAC,GAAG,SAAS,CAAC,CAAC;AACnC,aAAA;AAAM,iBAAA,IAAI,YAAY,EAAE;AACrB;;AAEG;AACH,gBAAA,MAAM,QAAQ,GAA4B;AACtC,oBAAA,IAAI,EAAE,UAAU;AAChB,oBAAA,QAAQ,EAAE,YAAY;oBACtB,EAAE,EAAE,IAAI,CAAC,YAAY,CAAC,0BAA0B,CAC5C,YAAY,CACf;iBACJ,CAAC;AACF,gBAAA,cAAc,GAAG,CAAC,QAAQ,CAAC,CAAC;AAC/B,aAAA;AAAM,iBAAA;gBACH,cAAc,GAAG,EAAE,CAAC;AACvB,aAAA;AAED,YAAA,MAAM,OAAO,GAAwB;AACjC,gBAAA,IAAI,EAAE,WAAW;gBACjB,OAAO;AACP,gBAAA,SAAS,EAAE,cAAc;aAC5B,CAAC;YAEF,OAAO,GAAG,IAAI,CAAC;YACf,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;YACtC,YAAY,GAAG,SAAS,CAAC;AAEzB,YAAA,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;YAE3B,QAAQ,MAAM,CAAC,YAAY;AACvB,gBAAA,KAAK,MAAM;AACP,oBAAA,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;AACzB,oBAAA,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;oBAChC,MAAM;AACV,gBAAA,KAAK,YAAY,CAAC;gBAClB,KAAK,eAAe,EAAE;AAClB,oBAAA,IAAI,OAAO,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE;AAChC,wBAAA,MAAM,GAAG,GAAG,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;wBAChD,OAAO,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;AAC3C,qBAAA;oBACD,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;oBAC1D,MAAM;AACT,iBAAA;AACD,gBAAA,SAAS;oBACL,MAAM,GAAG,GAAG,IAAI,KAAK,CACjB,CAAyB,sBAAA,EAAA,MAAM,CAAC,YAAY,CAAE,CAAA,CACjD,CAAC;oBACF,OAAO,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;AAC3C,iBAAA;AACJ,aAAA;AACL,SAAC,CAAC,CAAC;KACN;IAEO,sBAAsB,CAC1B,SAAoC,EACpC,SAAoB,EAAA;AAEpB,QAAA,MAAM,cAAc,GAAG,IAAI,cAAc,CAAC,SAAS,CAAC,CAAC;QACrD,cAAc,CAAC,EAAE,CAAC,YAAY,EAAE,OAAO,WAAyB,KAC5D,IAAI,CAAC,0BAA0B,CAAC,WAAW,EAAE,SAAS,CAAC,CAC1D,CAAC;AACF,QAAA,IAAI,CAAC,aAAa,CAAC,iBAAiB,EAAE,cAAc,CAAC,CAAC;KACzD;AAEO,IAAA,MAAM,0BAA0B,CACpC,WAAyB,EACzB,SAAoB,EAAA;;AAGpB,QAAA,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE;AAClC,YAAA,MAAM,OAAO,GAAuC;AAChD,gBAAA,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC;gBACzC,UAAU,EAAE,UAAU,CAAC,MAAM;aAChC,CAAC;AACF,YAAA,IAAI,UAAU,CAAC,QAAQ,KAAK,KAAK,CAAC,EAAE;AAChC,gBAAA,OAAO,CAAC,QAAQ,GAAG,UAAU,CAAC,QAAQ,CAAC;AAC1C,aAAA;AACD,YAAA,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;AAC9B,SAAA;AAED,QAAA,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;KAChC;AAEO,IAAA,YAAY,CAChB,OAAiD,EAAA;AAEjD,QAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAE5B,QAAA,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;AAEvC,QAAA,IAAI,oBAAoB,CAAC,OAAO,CAAC,EAAE;AAC/B,YAAA,IAAI,CAAC,aAAa,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAC;AAClD,SAAA;AAAM,aAAA;AACH,YAAA,IAAI,CAAC,aAAa,CAAC,kBAAkB,EAAE,OAAO,CAAC,CAAC;AACnD,SAAA;KACJ;AAEO,IAAA,aAAa,CAAC,KAAa,EAAE,GAAG,IAAe,EAAA;QACnD,IAAI,KAAK,KAAK,OAAO,EAAE;YACnB,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,CAAC;AAC7B,SAAA;AAAM,aAAA;YACH,YAAY,CAAC,MAAK;gBACd,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,CAAC;AAC9B,aAAC,CAAC,CAAC;AACN,SAAA;KACJ;AACJ,CAAA;AAEK,MAAO,cAAe,SAAQ,YAAY,CAAA;AAC5C,IAAA,WAAA,CAA4B,SAAoC,EAAA;AAC5D,QAAA,KAAK,EAAE,CAAC;QADgB,IAAS,CAAA,SAAA,GAAT,SAAS,CAA2B;KAE/D;AAED,IAAA,iBAAiB,CAAC,WAAyB,EAAA;AACvC,QAAA,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;KACxC;AACJ,CAAA;AAQK,SAAU,qBAAqB,CACjC,CAA2C,EAAA;IAE3C,OAAO,WAAW,IAAI,CAAC,CAAC;AAC5B,CAAC;AAEK,SAAU,oBAAoB,CAChC,CAA2C,EAAA;AAE3C,IAAA,OAAO,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;AACrC;;;;;;;;"} \ No newline at end of file +{"version":3,"file":"index.cjs","sources":["../src/assistant/assistant.ts","../src/thread/tool.emulator.ts","../src/thread/message.converter.ts","../src/thread/thread.ts"],"sourcesContent":["import type {\n ChatRequestMessage,\n ChatRequestSystemMessage,\n GetChatCompletionsOptions,\n OpenAIClient,\n} from '@azure/openai';\nimport type { ChatCompletionsToolDefinition } from '@azure/openai/types/src/models/models';\nimport { Readable } from 'stream';\n\nexport interface AssistantCreateParams {\n client: OpenAIClient;\n instructions: string;\n tools: ChatCompletionsToolDefinition[];\n deployment: string;\n useLegacyFunctions?: boolean;\n}\n\nexport class Assistant {\n public readonly client: OpenAIClient;\n\n private readonly instructions: string;\n private readonly tools: ChatCompletionsToolDefinition[];\n private readonly deployment: string;\n private readonly useLegacyFunctions: boolean;\n\n constructor(params: AssistantCreateParams) {\n this.client = params.client;\n this.instructions = params.instructions;\n this.tools = params.tools;\n this.deployment = params.deployment;\n this.useLegacyFunctions = params.useLegacyFunctions ?? false;\n }\n\n async streamChatCompletions(\n messages: ChatRequestMessage[],\n ): Promise {\n // Prepend the messages with our instructions as a \"system\" message\n const systemMessage: ChatRequestSystemMessage = {\n role: 'system',\n content: this.instructions,\n };\n messages = [systemMessage, ...messages];\n\n const options: GetChatCompletionsOptions = {};\n\n if (this.tools.length > 0) {\n if (this.useLegacyFunctions) {\n // Convert tools to functions\n options.functions = this.tools.map((tool) => {\n return tool.function;\n });\n } else {\n options.tools = this.tools;\n }\n }\n const events = await this.client.streamChatCompletions(\n this.deployment,\n messages,\n options,\n );\n\n return Readable.from(events);\n }\n}\n","import type { FunctionCall } from '@azure/openai';\n\nconst EMULATED_CALL_PREFIX = 'emulated_call_';\n\n/**\n * Helps with the conversion of tool calls to function calls and vice versa.\n */\nexport class ToolEmulator {\n generateEmulatedToolCallId(functionCall: FunctionCall): string {\n return `${EMULATED_CALL_PREFIX}${functionCall.name}`;\n }\n\n isEmulatedToolCallId(toolCallId: string): boolean {\n return toolCallId.startsWith(EMULATED_CALL_PREFIX);\n }\n\n extractFunctionNameFromEmulatedToolCallId(toolCallId: string): string {\n return toolCallId.replace(EMULATED_CALL_PREFIX, '');\n }\n}\n","import type {\n ChatRequestAssistantMessage,\n ChatRequestFunctionMessage,\n ChatRequestMessage,\n ChatRequestSystemMessage,\n ChatRequestToolMessage,\n ChatRequestUserMessage,\n} from '@azure/openai';\nimport type {\n ChatMessage,\n ChatRequestSystemMessageWithMetadata,\n ChatRequestToolMessageWithMetadata,\n ChatRequestUserMessageWithMetadata,\n ChatResponseMessageWithMetadata,\n} from '../message';\nimport { ToolEmulator } from './tool.emulator';\n\nexport class ThreadMessageConverter {\n private readonly toolEmulator = new ToolEmulator();\n\n /**\n * Convert the mix of ChatRequestMessages and ChatResponseMessages to ChatRequestMessages only\n * so they can be sent again to the LLM.\n */\n convert(messages: ChatMessage[]): ChatRequestMessage[] {\n return messages.map((m) => {\n switch (m.role) {\n case 'system': {\n const systemMessage =\n m as ChatRequestSystemMessageWithMetadata;\n return {\n role: 'system',\n content: systemMessage.content,\n } as ChatRequestSystemMessage;\n }\n case 'user': {\n const userMessage = m as ChatRequestUserMessageWithMetadata;\n return {\n role: 'user',\n content: userMessage.content,\n name: userMessage.name,\n } as ChatRequestUserMessage;\n }\n case 'tool': {\n const toolMessage = m as ChatRequestToolMessageWithMetadata;\n if (\n this.toolEmulator.isEmulatedToolCallId(\n toolMessage.toolCallId,\n )\n ) {\n return {\n role: 'function',\n content: toolMessage.content,\n name: this.toolEmulator.extractFunctionNameFromEmulatedToolCallId(\n toolMessage.toolCallId,\n ),\n } as ChatRequestFunctionMessage;\n }\n return {\n role: 'tool',\n content: toolMessage.content,\n toolCallId: toolMessage.toolCallId,\n } as ChatRequestToolMessage;\n }\n case 'assistant': {\n const assistantMessage =\n m as ChatResponseMessageWithMetadata;\n\n if (\n assistantMessage.toolCalls[0] &&\n this.toolEmulator.isEmulatedToolCallId(\n assistantMessage.toolCalls[0].id,\n )\n ) {\n // This is a function call\n return {\n role: 'assistant',\n content: assistantMessage.content,\n functionCall: {\n name: this.toolEmulator.extractFunctionNameFromEmulatedToolCallId(\n assistantMessage.toolCalls[0].id,\n ),\n arguments:\n assistantMessage.toolCalls[0].function\n .arguments,\n },\n } as ChatRequestAssistantMessage;\n }\n\n return {\n role: 'assistant',\n content: assistantMessage.content,\n toolCalls: assistantMessage.toolCalls,\n } as ChatRequestAssistantMessage;\n }\n default:\n throw new Error(`Unknown message role ${m.role}`);\n }\n });\n }\n}\n","import type {\n ChatCompletions,\n ChatCompletionsToolCall,\n ChatRequestMessage,\n ChatResponseMessage,\n FunctionCall,\n} from '@azure/openai';\nimport EventEmitter from 'events';\nimport { Readable } from 'stream';\nimport { Assistant } from '../assistant';\nimport type {\n ChatMessage,\n ChatRequestMessageWithMetadata,\n ChatRequestToolMessageWithMetadata,\n} from '../message';\nimport { ThreadMessageConverter } from './message.converter';\nimport { ToolEmulator } from './tool.emulator';\n\nexport class Thread extends EventEmitter {\n private _stream: Readable | null = null;\n private readonly converter = new ThreadMessageConverter();\n private readonly toolEmulator = new ToolEmulator();\n\n constructor(\n public readonly id: string,\n private readonly messages: ChatMessage[] = [],\n ) {\n super();\n }\n\n get stream(): Readable | null {\n return this._stream;\n }\n\n addMessage(message: ChatRequestMessageWithMetadata): void {\n this.doAddMessage(message);\n }\n\n async run(assistant: Assistant): Promise {\n try {\n return await this.doRun(assistant);\n } catch (e) {\n this.emitImmediate('error', e);\n }\n }\n\n private async doRun(assistant: Assistant): Promise {\n this._stream = new Readable({\n read: () => {},\n });\n\n this.emitImmediate('in_progress');\n\n const messages = this.converter.convert(this.messages);\n\n const stream = await assistant.streamChatCompletions(messages);\n\n let content: string | null = null;\n const toolCalls: ChatCompletionsToolCall[] = [];\n let functionCall: FunctionCall | undefined = undefined;\n\n stream.on('data', (completion: ChatCompletions) => {\n if (!completion.id || completion.id === '') {\n // First completion is empty when using old models like gpt-35-turbo\n return;\n }\n const choice = completion.choices[0];\n if (!choice) {\n const err = new Error('No completions returned');\n return this.emitImmediate('error', err);\n }\n\n const delta = choice.delta;\n if (!delta) {\n const err = new Error('No delta returned');\n return this.emitImmediate('error', err);\n }\n\n if (delta.content) {\n content = content ? content + delta.content : delta.content;\n\n // Write also to the stream of the thread\n if (!this._stream) {\n const err = new Error('No stream available');\n return this.emitImmediate('error', err);\n }\n this._stream?.push(delta.content);\n }\n\n // Merge toolCalls\n if (delta.toolCalls) {\n for (const toolCall of delta.toolCalls) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n const index = toolCall['index']; // Not typed yet by the @azure/openai package\n const existingToolCall = toolCalls[index];\n\n if (existingToolCall) {\n existingToolCall.function.arguments +=\n toolCall.function.arguments;\n } else {\n toolCalls.push({\n type: toolCall.type,\n function: toolCall.function,\n id: toolCall.id,\n });\n }\n }\n }\n\n // Merge functionCalls\n if (delta.functionCall) {\n if (functionCall) {\n functionCall.arguments += delta.functionCall.arguments;\n } else {\n functionCall = {\n ...delta.functionCall,\n arguments: '',\n };\n }\n }\n\n if (choice.finishReason === null) {\n return;\n }\n\n let finalToolCalls: ChatCompletionsToolCall[];\n\n if (toolCalls.length > 0) {\n finalToolCalls = [...toolCalls];\n } else if (functionCall) {\n /**\n * We received a legacy function call, we convert it to a tool call with an emulated ID\n */\n const toolCall: ChatCompletionsToolCall = {\n type: 'function',\n function: functionCall,\n id: this.toolEmulator.generateEmulatedToolCallId(\n functionCall,\n ),\n };\n finalToolCalls = [toolCall];\n } else {\n finalToolCalls = [];\n }\n\n const message: ChatResponseMessage = {\n role: 'assistant',\n content,\n toolCalls: finalToolCalls,\n };\n\n content = null;\n toolCalls.splice(0, toolCalls.length);\n functionCall = undefined;\n\n this.doAddMessage(message);\n\n switch (choice.finishReason) {\n case 'stop':\n this._stream?.push(null);\n this.emitImmediate('completed');\n break;\n case 'tool_calls':\n case 'function_call': {\n if (message.toolCalls.length === 0) {\n const err = new Error('No tool calls returned');\n return this.emitImmediate('error', err);\n }\n this.dispatchRequiredAction(message.toolCalls, assistant);\n break;\n }\n default: {\n const err = new Error(\n `Unknown finish reason ${choice.finishReason}`,\n );\n return this.emitImmediate('error', err);\n }\n }\n });\n }\n\n private dispatchRequiredAction(\n toolCalls: ChatCompletionsToolCall[],\n assistant: Assistant,\n ): void {\n const requiredAction = new RequiredAction(toolCalls);\n requiredAction.on('submitting', async (toolOutputs: ToolOutput[]) =>\n this.handleSubmittedToolOutputs(toolOutputs, assistant),\n );\n this.emitImmediate('requires_action', requiredAction);\n }\n\n private async handleSubmittedToolOutputs(\n toolOutputs: ToolOutput[],\n assistant: Assistant,\n ): Promise {\n // Adds the tool outputs to the messages\n for (const toolOutput of toolOutputs) {\n const message: ChatRequestToolMessageWithMetadata = {\n role: 'tool',\n content: JSON.stringify(toolOutput.value),\n toolCallId: toolOutput.callId,\n };\n if (toolOutput.metadata !== void 0) {\n message.metadata = toolOutput.metadata;\n }\n this.doAddMessage(message);\n }\n\n return this.doRun(assistant);\n }\n\n private doAddMessage(\n message: ChatRequestMessage | ChatResponseMessage,\n ): void {\n this.messages.push(message);\n\n this.emitImmediate('message', message);\n\n if (isChatRequestMessage(message)) {\n this.emitImmediate('message:request', message);\n } else {\n this.emitImmediate('message:response', message);\n }\n }\n\n private emitImmediate(event: string, ...args: unknown[]): void {\n if (event === 'error') {\n this.emit(event, ...args);\n } else {\n setImmediate(() => {\n this.emit(event, ...args);\n });\n }\n }\n}\n\nexport class RequiredAction extends EventEmitter {\n constructor(public readonly toolCalls: ChatCompletionsToolCall[]) {\n super();\n }\n\n submitToolOutputs(toolOutputs: ToolOutput[]): void {\n this.emit('submitting', toolOutputs);\n }\n}\n\nexport interface ToolOutput {\n callId: string;\n value: unknown;\n metadata?: unknown;\n}\n\nexport function isChatResponseMessage(\n m: ChatRequestMessage | ChatResponseMessage,\n): m is ChatResponseMessage {\n return 'toolCalls' in m;\n}\n\nexport function isChatRequestMessage(\n m: ChatRequestMessage | ChatResponseMessage,\n): m is ChatRequestMessage {\n return !isChatResponseMessage(m);\n}\n"],"names":["Readable","stream"],"mappings":"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"} \ No newline at end of file diff --git a/dist/index.esm.js b/dist/index.esm.js index 719c220..805629b 100644 --- a/dist/index.esm.js +++ b/dist/index.esm.js @@ -125,26 +125,21 @@ class ThreadMessageConverter { } class Thread extends EventEmitter { - constructor(messages = []) { + constructor(id, messages = []) { super(); + this.id = id; this.messages = messages; this._stream = null; this.converter = new ThreadMessageConverter(); this.toolEmulator = new ToolEmulator(); } get stream() { - if (!this._stream) { - return null; - } return this._stream; } addMessage(message) { this.doAddMessage(message); } async run(assistant) { - this._stream = new Readable({ - read: () => { }, - }); try { return await this.doRun(assistant); } @@ -153,6 +148,9 @@ class Thread extends EventEmitter { } } async doRun(assistant) { + this._stream = new Readable({ + read: () => { }, + }); this.emitImmediate('in_progress'); const messages = this.converter.convert(this.messages); const stream = await assistant.streamChatCompletions(messages); diff --git a/dist/index.esm.js.map b/dist/index.esm.js.map index 68984f3..e6c935e 100644 --- a/dist/index.esm.js.map +++ b/dist/index.esm.js.map @@ -1 +1 @@ -{"version":3,"file":"index.esm.js","sources":["../src/assistant/assistant.ts","../src/thread/tool.emulator.ts","../src/thread/message.converter.ts","../src/thread/thread.ts"],"sourcesContent":["import type {\n ChatRequestMessage,\n ChatRequestSystemMessage,\n GetChatCompletionsOptions,\n OpenAIClient,\n} from '@azure/openai';\nimport type { ChatCompletionsToolDefinition } from '@azure/openai/types/src/models/models';\nimport { Readable } from 'stream';\n\nexport interface AssistantCreateParams {\n client: OpenAIClient;\n instructions: string;\n tools: ChatCompletionsToolDefinition[];\n deployment: string;\n useLegacyFunctions?: boolean;\n}\n\nexport class Assistant {\n public readonly client: OpenAIClient;\n\n private readonly instructions: string;\n private readonly tools: ChatCompletionsToolDefinition[];\n private readonly deployment: string;\n private readonly useLegacyFunctions: boolean;\n\n constructor(params: AssistantCreateParams) {\n this.client = params.client;\n this.instructions = params.instructions;\n this.tools = params.tools;\n this.deployment = params.deployment;\n this.useLegacyFunctions = params.useLegacyFunctions ?? false;\n }\n\n async streamChatCompletions(\n messages: ChatRequestMessage[],\n ): Promise {\n // Prepend the messages with our instructions as a \"system\" message\n const systemMessage: ChatRequestSystemMessage = {\n role: 'system',\n content: this.instructions,\n };\n messages = [systemMessage, ...messages];\n\n const options: GetChatCompletionsOptions = {};\n\n if (this.tools.length > 0) {\n if (this.useLegacyFunctions) {\n // Convert tools to functions\n options.functions = this.tools.map((tool) => {\n return tool.function;\n });\n } else {\n options.tools = this.tools;\n }\n }\n const events = await this.client.streamChatCompletions(\n this.deployment,\n messages,\n options,\n );\n\n return Readable.from(events);\n }\n}\n","import type { FunctionCall } from '@azure/openai';\n\nconst EMULATED_CALL_PREFIX = 'emulated_call_';\n\n/**\n * Helps with the conversion of tool calls to function calls and vice versa.\n */\nexport class ToolEmulator {\n generateEmulatedToolCallId(functionCall: FunctionCall): string {\n return `${EMULATED_CALL_PREFIX}${functionCall.name}`;\n }\n\n isEmulatedToolCallId(toolCallId: string): boolean {\n return toolCallId.startsWith(EMULATED_CALL_PREFIX);\n }\n\n extractFunctionNameFromEmulatedToolCallId(toolCallId: string): string {\n return toolCallId.replace(EMULATED_CALL_PREFIX, '');\n }\n}\n","import type {\n ChatRequestAssistantMessage,\n ChatRequestFunctionMessage,\n ChatRequestMessage,\n ChatRequestSystemMessage,\n ChatRequestToolMessage,\n ChatRequestUserMessage,\n} from '@azure/openai';\nimport type {\n ChatMessage,\n ChatRequestSystemMessageWithMetadata,\n ChatRequestToolMessageWithMetadata,\n ChatRequestUserMessageWithMetadata,\n ChatResponseMessageWithMetadata,\n} from '../message';\nimport { ToolEmulator } from './tool.emulator';\n\nexport class ThreadMessageConverter {\n private readonly toolEmulator = new ToolEmulator();\n\n /**\n * Convert the mix of ChatRequestMessages and ChatResponseMessages to ChatRequestMessages only\n * so they can be sent again to the LLM.\n */\n convert(messages: ChatMessage[]): ChatRequestMessage[] {\n return messages.map((m) => {\n switch (m.role) {\n case 'system': {\n const systemMessage =\n m as ChatRequestSystemMessageWithMetadata;\n return {\n role: 'system',\n content: systemMessage.content,\n } as ChatRequestSystemMessage;\n }\n case 'user': {\n const userMessage = m as ChatRequestUserMessageWithMetadata;\n return {\n role: 'user',\n content: userMessage.content,\n name: userMessage.name,\n } as ChatRequestUserMessage;\n }\n case 'tool': {\n const toolMessage = m as ChatRequestToolMessageWithMetadata;\n if (\n this.toolEmulator.isEmulatedToolCallId(\n toolMessage.toolCallId,\n )\n ) {\n return {\n role: 'function',\n content: toolMessage.content,\n name: this.toolEmulator.extractFunctionNameFromEmulatedToolCallId(\n toolMessage.toolCallId,\n ),\n } as ChatRequestFunctionMessage;\n }\n return {\n role: 'tool',\n content: toolMessage.content,\n toolCallId: toolMessage.toolCallId,\n } as ChatRequestToolMessage;\n }\n case 'assistant': {\n const assistantMessage =\n m as ChatResponseMessageWithMetadata;\n\n if (\n assistantMessage.toolCalls[0] &&\n this.toolEmulator.isEmulatedToolCallId(\n assistantMessage.toolCalls[0].id,\n )\n ) {\n // This is a function call\n return {\n role: 'assistant',\n content: assistantMessage.content,\n functionCall: {\n name: this.toolEmulator.extractFunctionNameFromEmulatedToolCallId(\n assistantMessage.toolCalls[0].id,\n ),\n arguments:\n assistantMessage.toolCalls[0].function\n .arguments,\n },\n } as ChatRequestAssistantMessage;\n }\n\n return {\n role: 'assistant',\n content: assistantMessage.content,\n toolCalls: assistantMessage.toolCalls,\n } as ChatRequestAssistantMessage;\n }\n default:\n throw new Error(`Unknown message role ${m.role}`);\n }\n });\n }\n}\n","import type {\n ChatCompletions,\n ChatCompletionsToolCall,\n ChatRequestMessage,\n ChatResponseMessage,\n FunctionCall,\n} from '@azure/openai';\nimport EventEmitter from 'events';\nimport { Readable } from 'stream';\nimport { Assistant } from '../assistant';\nimport type {\n ChatMessage,\n ChatRequestMessageWithMetadata,\n ChatRequestToolMessageWithMetadata,\n} from '../message';\nimport { ThreadMessageConverter } from './message.converter';\nimport { ToolEmulator } from './tool.emulator';\n\nexport class Thread extends EventEmitter {\n private _stream: Readable | null = null;\n private readonly converter = new ThreadMessageConverter();\n private readonly toolEmulator = new ToolEmulator();\n\n constructor(private readonly messages: ChatMessage[] = []) {\n super();\n }\n\n get stream(): Readable | null {\n if (!this._stream) {\n return null;\n }\n\n return this._stream;\n }\n\n addMessage(message: ChatRequestMessageWithMetadata): void {\n this.doAddMessage(message);\n }\n\n async run(assistant: Assistant): Promise {\n this._stream = new Readable({\n read: () => {},\n });\n\n try {\n return await this.doRun(assistant);\n } catch (e) {\n this.emitImmediate('error', e);\n }\n }\n\n private async doRun(assistant: Assistant): Promise {\n this.emitImmediate('in_progress');\n\n const messages = this.converter.convert(this.messages);\n\n const stream = await assistant.streamChatCompletions(messages);\n\n let content: string | null = null;\n const toolCalls: ChatCompletionsToolCall[] = [];\n let functionCall: FunctionCall | undefined = undefined;\n\n stream.on('data', (completion: ChatCompletions) => {\n if (!completion.id || completion.id === '') {\n // First completion is empty when using old models like gpt-35-turbo\n return;\n }\n const choice = completion.choices[0];\n if (!choice) {\n const err = new Error('No completions returned');\n return this.emitImmediate('error', err);\n }\n\n const delta = choice.delta;\n if (!delta) {\n const err = new Error('No delta returned');\n return this.emitImmediate('error', err);\n }\n\n if (delta.content) {\n content = content ? content + delta.content : delta.content;\n\n // Write also to the stream of the thread\n if (!this._stream) {\n const err = new Error('No stream available');\n return this.emitImmediate('error', err);\n }\n this._stream?.push(delta.content);\n }\n\n // Merge toolCalls\n if (delta.toolCalls) {\n for (const toolCall of delta.toolCalls) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n const index = toolCall['index']; // Not typed yet by the @azure/openai package\n const existingToolCall = toolCalls[index];\n\n if (existingToolCall) {\n existingToolCall.function.arguments +=\n toolCall.function.arguments;\n } else {\n toolCalls.push({\n type: toolCall.type,\n function: toolCall.function,\n id: toolCall.id,\n });\n }\n }\n }\n\n // Merge functionCalls\n if (delta.functionCall) {\n if (functionCall) {\n functionCall.arguments += delta.functionCall.arguments;\n } else {\n functionCall = {\n ...delta.functionCall,\n arguments: '',\n };\n }\n }\n\n if (choice.finishReason === null) {\n return;\n }\n\n let finalToolCalls: ChatCompletionsToolCall[];\n\n if (toolCalls.length > 0) {\n finalToolCalls = [...toolCalls];\n } else if (functionCall) {\n /**\n * We received a legacy function call, we convert it to a tool call with an emulated ID\n */\n const toolCall: ChatCompletionsToolCall = {\n type: 'function',\n function: functionCall,\n id: this.toolEmulator.generateEmulatedToolCallId(\n functionCall,\n ),\n };\n finalToolCalls = [toolCall];\n } else {\n finalToolCalls = [];\n }\n\n const message: ChatResponseMessage = {\n role: 'assistant',\n content,\n toolCalls: finalToolCalls,\n };\n\n content = null;\n toolCalls.splice(0, toolCalls.length);\n functionCall = undefined;\n\n this.doAddMessage(message);\n\n switch (choice.finishReason) {\n case 'stop':\n this._stream?.push(null);\n this.emitImmediate('completed');\n break;\n case 'tool_calls':\n case 'function_call': {\n if (message.toolCalls.length === 0) {\n const err = new Error('No tool calls returned');\n return this.emitImmediate('error', err);\n }\n this.dispatchRequiredAction(message.toolCalls, assistant);\n break;\n }\n default: {\n const err = new Error(\n `Unknown finish reason ${choice.finishReason}`,\n );\n return this.emitImmediate('error', err);\n }\n }\n });\n }\n\n private dispatchRequiredAction(\n toolCalls: ChatCompletionsToolCall[],\n assistant: Assistant,\n ): void {\n const requiredAction = new RequiredAction(toolCalls);\n requiredAction.on('submitting', async (toolOutputs: ToolOutput[]) =>\n this.handleSubmittedToolOutputs(toolOutputs, assistant),\n );\n this.emitImmediate('requires_action', requiredAction);\n }\n\n private async handleSubmittedToolOutputs(\n toolOutputs: ToolOutput[],\n assistant: Assistant,\n ): Promise {\n // Adds the tool outputs to the messages\n for (const toolOutput of toolOutputs) {\n const message: ChatRequestToolMessageWithMetadata = {\n role: 'tool',\n content: JSON.stringify(toolOutput.value),\n toolCallId: toolOutput.callId,\n };\n if (toolOutput.metadata !== void 0) {\n message.metadata = toolOutput.metadata;\n }\n this.doAddMessage(message);\n }\n\n return this.doRun(assistant);\n }\n\n private doAddMessage(\n message: ChatRequestMessage | ChatResponseMessage,\n ): void {\n this.messages.push(message);\n\n this.emitImmediate('message', message);\n\n if (isChatRequestMessage(message)) {\n this.emitImmediate('message:request', message);\n } else {\n this.emitImmediate('message:response', message);\n }\n }\n\n private emitImmediate(event: string, ...args: unknown[]): void {\n if (event === 'error') {\n this.emit(event, ...args);\n } else {\n setImmediate(() => {\n this.emit(event, ...args);\n });\n }\n }\n}\n\nexport class RequiredAction extends EventEmitter {\n constructor(public readonly toolCalls: ChatCompletionsToolCall[]) {\n super();\n }\n\n submitToolOutputs(toolOutputs: ToolOutput[]): void {\n this.emit('submitting', toolOutputs);\n }\n}\n\nexport interface ToolOutput {\n callId: string;\n value: unknown;\n metadata?: unknown;\n}\n\nexport function isChatResponseMessage(\n m: ChatRequestMessage | ChatResponseMessage,\n): m is ChatResponseMessage {\n return 'toolCalls' in m;\n}\n\nexport function isChatRequestMessage(\n m: ChatRequestMessage | ChatResponseMessage,\n): m is ChatRequestMessage {\n return !isChatResponseMessage(m);\n}\n"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"index.esm.js","sources":["../src/assistant/assistant.ts","../src/thread/tool.emulator.ts","../src/thread/message.converter.ts","../src/thread/thread.ts"],"sourcesContent":["import type {\n ChatRequestMessage,\n ChatRequestSystemMessage,\n GetChatCompletionsOptions,\n OpenAIClient,\n} from '@azure/openai';\nimport type { ChatCompletionsToolDefinition } from '@azure/openai/types/src/models/models';\nimport { Readable } from 'stream';\n\nexport interface AssistantCreateParams {\n client: OpenAIClient;\n instructions: string;\n tools: ChatCompletionsToolDefinition[];\n deployment: string;\n useLegacyFunctions?: boolean;\n}\n\nexport class Assistant {\n public readonly client: OpenAIClient;\n\n private readonly instructions: string;\n private readonly tools: ChatCompletionsToolDefinition[];\n private readonly deployment: string;\n private readonly useLegacyFunctions: boolean;\n\n constructor(params: AssistantCreateParams) {\n this.client = params.client;\n this.instructions = params.instructions;\n this.tools = params.tools;\n this.deployment = params.deployment;\n this.useLegacyFunctions = params.useLegacyFunctions ?? false;\n }\n\n async streamChatCompletions(\n messages: ChatRequestMessage[],\n ): Promise {\n // Prepend the messages with our instructions as a \"system\" message\n const systemMessage: ChatRequestSystemMessage = {\n role: 'system',\n content: this.instructions,\n };\n messages = [systemMessage, ...messages];\n\n const options: GetChatCompletionsOptions = {};\n\n if (this.tools.length > 0) {\n if (this.useLegacyFunctions) {\n // Convert tools to functions\n options.functions = this.tools.map((tool) => {\n return tool.function;\n });\n } else {\n options.tools = this.tools;\n }\n }\n const events = await this.client.streamChatCompletions(\n this.deployment,\n messages,\n options,\n );\n\n return Readable.from(events);\n }\n}\n","import type { FunctionCall } from '@azure/openai';\n\nconst EMULATED_CALL_PREFIX = 'emulated_call_';\n\n/**\n * Helps with the conversion of tool calls to function calls and vice versa.\n */\nexport class ToolEmulator {\n generateEmulatedToolCallId(functionCall: FunctionCall): string {\n return `${EMULATED_CALL_PREFIX}${functionCall.name}`;\n }\n\n isEmulatedToolCallId(toolCallId: string): boolean {\n return toolCallId.startsWith(EMULATED_CALL_PREFIX);\n }\n\n extractFunctionNameFromEmulatedToolCallId(toolCallId: string): string {\n return toolCallId.replace(EMULATED_CALL_PREFIX, '');\n }\n}\n","import type {\n ChatRequestAssistantMessage,\n ChatRequestFunctionMessage,\n ChatRequestMessage,\n ChatRequestSystemMessage,\n ChatRequestToolMessage,\n ChatRequestUserMessage,\n} from '@azure/openai';\nimport type {\n ChatMessage,\n ChatRequestSystemMessageWithMetadata,\n ChatRequestToolMessageWithMetadata,\n ChatRequestUserMessageWithMetadata,\n ChatResponseMessageWithMetadata,\n} from '../message';\nimport { ToolEmulator } from './tool.emulator';\n\nexport class ThreadMessageConverter {\n private readonly toolEmulator = new ToolEmulator();\n\n /**\n * Convert the mix of ChatRequestMessages and ChatResponseMessages to ChatRequestMessages only\n * so they can be sent again to the LLM.\n */\n convert(messages: ChatMessage[]): ChatRequestMessage[] {\n return messages.map((m) => {\n switch (m.role) {\n case 'system': {\n const systemMessage =\n m as ChatRequestSystemMessageWithMetadata;\n return {\n role: 'system',\n content: systemMessage.content,\n } as ChatRequestSystemMessage;\n }\n case 'user': {\n const userMessage = m as ChatRequestUserMessageWithMetadata;\n return {\n role: 'user',\n content: userMessage.content,\n name: userMessage.name,\n } as ChatRequestUserMessage;\n }\n case 'tool': {\n const toolMessage = m as ChatRequestToolMessageWithMetadata;\n if (\n this.toolEmulator.isEmulatedToolCallId(\n toolMessage.toolCallId,\n )\n ) {\n return {\n role: 'function',\n content: toolMessage.content,\n name: this.toolEmulator.extractFunctionNameFromEmulatedToolCallId(\n toolMessage.toolCallId,\n ),\n } as ChatRequestFunctionMessage;\n }\n return {\n role: 'tool',\n content: toolMessage.content,\n toolCallId: toolMessage.toolCallId,\n } as ChatRequestToolMessage;\n }\n case 'assistant': {\n const assistantMessage =\n m as ChatResponseMessageWithMetadata;\n\n if (\n assistantMessage.toolCalls[0] &&\n this.toolEmulator.isEmulatedToolCallId(\n assistantMessage.toolCalls[0].id,\n )\n ) {\n // This is a function call\n return {\n role: 'assistant',\n content: assistantMessage.content,\n functionCall: {\n name: this.toolEmulator.extractFunctionNameFromEmulatedToolCallId(\n assistantMessage.toolCalls[0].id,\n ),\n arguments:\n assistantMessage.toolCalls[0].function\n .arguments,\n },\n } as ChatRequestAssistantMessage;\n }\n\n return {\n role: 'assistant',\n content: assistantMessage.content,\n toolCalls: assistantMessage.toolCalls,\n } as ChatRequestAssistantMessage;\n }\n default:\n throw new Error(`Unknown message role ${m.role}`);\n }\n });\n }\n}\n","import type {\n ChatCompletions,\n ChatCompletionsToolCall,\n ChatRequestMessage,\n ChatResponseMessage,\n FunctionCall,\n} from '@azure/openai';\nimport EventEmitter from 'events';\nimport { Readable } from 'stream';\nimport { Assistant } from '../assistant';\nimport type {\n ChatMessage,\n ChatRequestMessageWithMetadata,\n ChatRequestToolMessageWithMetadata,\n} from '../message';\nimport { ThreadMessageConverter } from './message.converter';\nimport { ToolEmulator } from './tool.emulator';\n\nexport class Thread extends EventEmitter {\n private _stream: Readable | null = null;\n private readonly converter = new ThreadMessageConverter();\n private readonly toolEmulator = new ToolEmulator();\n\n constructor(\n public readonly id: string,\n private readonly messages: ChatMessage[] = [],\n ) {\n super();\n }\n\n get stream(): Readable | null {\n return this._stream;\n }\n\n addMessage(message: ChatRequestMessageWithMetadata): void {\n this.doAddMessage(message);\n }\n\n async run(assistant: Assistant): Promise {\n try {\n return await this.doRun(assistant);\n } catch (e) {\n this.emitImmediate('error', e);\n }\n }\n\n private async doRun(assistant: Assistant): Promise {\n this._stream = new Readable({\n read: () => {},\n });\n\n this.emitImmediate('in_progress');\n\n const messages = this.converter.convert(this.messages);\n\n const stream = await assistant.streamChatCompletions(messages);\n\n let content: string | null = null;\n const toolCalls: ChatCompletionsToolCall[] = [];\n let functionCall: FunctionCall | undefined = undefined;\n\n stream.on('data', (completion: ChatCompletions) => {\n if (!completion.id || completion.id === '') {\n // First completion is empty when using old models like gpt-35-turbo\n return;\n }\n const choice = completion.choices[0];\n if (!choice) {\n const err = new Error('No completions returned');\n return this.emitImmediate('error', err);\n }\n\n const delta = choice.delta;\n if (!delta) {\n const err = new Error('No delta returned');\n return this.emitImmediate('error', err);\n }\n\n if (delta.content) {\n content = content ? content + delta.content : delta.content;\n\n // Write also to the stream of the thread\n if (!this._stream) {\n const err = new Error('No stream available');\n return this.emitImmediate('error', err);\n }\n this._stream?.push(delta.content);\n }\n\n // Merge toolCalls\n if (delta.toolCalls) {\n for (const toolCall of delta.toolCalls) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n const index = toolCall['index']; // Not typed yet by the @azure/openai package\n const existingToolCall = toolCalls[index];\n\n if (existingToolCall) {\n existingToolCall.function.arguments +=\n toolCall.function.arguments;\n } else {\n toolCalls.push({\n type: toolCall.type,\n function: toolCall.function,\n id: toolCall.id,\n });\n }\n }\n }\n\n // Merge functionCalls\n if (delta.functionCall) {\n if (functionCall) {\n functionCall.arguments += delta.functionCall.arguments;\n } else {\n functionCall = {\n ...delta.functionCall,\n arguments: '',\n };\n }\n }\n\n if (choice.finishReason === null) {\n return;\n }\n\n let finalToolCalls: ChatCompletionsToolCall[];\n\n if (toolCalls.length > 0) {\n finalToolCalls = [...toolCalls];\n } else if (functionCall) {\n /**\n * We received a legacy function call, we convert it to a tool call with an emulated ID\n */\n const toolCall: ChatCompletionsToolCall = {\n type: 'function',\n function: functionCall,\n id: this.toolEmulator.generateEmulatedToolCallId(\n functionCall,\n ),\n };\n finalToolCalls = [toolCall];\n } else {\n finalToolCalls = [];\n }\n\n const message: ChatResponseMessage = {\n role: 'assistant',\n content,\n toolCalls: finalToolCalls,\n };\n\n content = null;\n toolCalls.splice(0, toolCalls.length);\n functionCall = undefined;\n\n this.doAddMessage(message);\n\n switch (choice.finishReason) {\n case 'stop':\n this._stream?.push(null);\n this.emitImmediate('completed');\n break;\n case 'tool_calls':\n case 'function_call': {\n if (message.toolCalls.length === 0) {\n const err = new Error('No tool calls returned');\n return this.emitImmediate('error', err);\n }\n this.dispatchRequiredAction(message.toolCalls, assistant);\n break;\n }\n default: {\n const err = new Error(\n `Unknown finish reason ${choice.finishReason}`,\n );\n return this.emitImmediate('error', err);\n }\n }\n });\n }\n\n private dispatchRequiredAction(\n toolCalls: ChatCompletionsToolCall[],\n assistant: Assistant,\n ): void {\n const requiredAction = new RequiredAction(toolCalls);\n requiredAction.on('submitting', async (toolOutputs: ToolOutput[]) =>\n this.handleSubmittedToolOutputs(toolOutputs, assistant),\n );\n this.emitImmediate('requires_action', requiredAction);\n }\n\n private async handleSubmittedToolOutputs(\n toolOutputs: ToolOutput[],\n assistant: Assistant,\n ): Promise {\n // Adds the tool outputs to the messages\n for (const toolOutput of toolOutputs) {\n const message: ChatRequestToolMessageWithMetadata = {\n role: 'tool',\n content: JSON.stringify(toolOutput.value),\n toolCallId: toolOutput.callId,\n };\n if (toolOutput.metadata !== void 0) {\n message.metadata = toolOutput.metadata;\n }\n this.doAddMessage(message);\n }\n\n return this.doRun(assistant);\n }\n\n private doAddMessage(\n message: ChatRequestMessage | ChatResponseMessage,\n ): void {\n this.messages.push(message);\n\n this.emitImmediate('message', message);\n\n if (isChatRequestMessage(message)) {\n this.emitImmediate('message:request', message);\n } else {\n this.emitImmediate('message:response', message);\n }\n }\n\n private emitImmediate(event: string, ...args: unknown[]): void {\n if (event === 'error') {\n this.emit(event, ...args);\n } else {\n setImmediate(() => {\n this.emit(event, ...args);\n });\n }\n }\n}\n\nexport class RequiredAction extends EventEmitter {\n constructor(public readonly toolCalls: ChatCompletionsToolCall[]) {\n super();\n }\n\n submitToolOutputs(toolOutputs: ToolOutput[]): void {\n this.emit('submitting', toolOutputs);\n }\n}\n\nexport interface ToolOutput {\n callId: string;\n value: unknown;\n metadata?: unknown;\n}\n\nexport function isChatResponseMessage(\n m: ChatRequestMessage | ChatResponseMessage,\n): m is ChatResponseMessage {\n return 'toolCalls' in m;\n}\n\nexport function isChatRequestMessage(\n m: ChatRequestMessage | ChatResponseMessage,\n): m is ChatRequestMessage {\n return !isChatResponseMessage(m);\n}\n"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/index.js b/dist/index.js index 1704592..a792e9f 100644 --- a/dist/index.js +++ b/dist/index.js @@ -127,26 +127,21 @@ class ThreadMessageConverter { } class Thread extends EventEmitter { - constructor(messages = []) { + constructor(id, messages = []) { super(); + this.id = id; this.messages = messages; this._stream = null; this.converter = new ThreadMessageConverter(); this.toolEmulator = new ToolEmulator(); } get stream() { - if (!this._stream) { - return null; - } return this._stream; } addMessage(message) { this.doAddMessage(message); } async run(assistant) { - this._stream = new stream.Readable({ - read: () => { }, - }); try { return await this.doRun(assistant); } @@ -155,13 +150,16 @@ class Thread extends EventEmitter { } } async doRun(assistant) { + this._stream = new stream.Readable({ + read: () => { }, + }); this.emitImmediate('in_progress'); const messages = this.converter.convert(this.messages); - const stream = await assistant.streamChatCompletions(messages); + const stream$1 = await assistant.streamChatCompletions(messages); let content = null; const toolCalls = []; let functionCall = undefined; - stream.on('data', (completion) => { + stream$1.on('data', (completion) => { if (!completion.id || completion.id === '') { // First completion is empty when using old models like gpt-35-turbo return; diff --git a/dist/index.js.map b/dist/index.js.map index 5da8615..52340be 100644 --- a/dist/index.js.map +++ b/dist/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sources":["../src/assistant/assistant.ts","../src/thread/tool.emulator.ts","../src/thread/message.converter.ts","../src/thread/thread.ts"],"sourcesContent":["import type {\n ChatRequestMessage,\n ChatRequestSystemMessage,\n GetChatCompletionsOptions,\n OpenAIClient,\n} from '@azure/openai';\nimport type { ChatCompletionsToolDefinition } from '@azure/openai/types/src/models/models';\nimport { Readable } from 'stream';\n\nexport interface AssistantCreateParams {\n client: OpenAIClient;\n instructions: string;\n tools: ChatCompletionsToolDefinition[];\n deployment: string;\n useLegacyFunctions?: boolean;\n}\n\nexport class Assistant {\n public readonly client: OpenAIClient;\n\n private readonly instructions: string;\n private readonly tools: ChatCompletionsToolDefinition[];\n private readonly deployment: string;\n private readonly useLegacyFunctions: boolean;\n\n constructor(params: AssistantCreateParams) {\n this.client = params.client;\n this.instructions = params.instructions;\n this.tools = params.tools;\n this.deployment = params.deployment;\n this.useLegacyFunctions = params.useLegacyFunctions ?? false;\n }\n\n async streamChatCompletions(\n messages: ChatRequestMessage[],\n ): Promise {\n // Prepend the messages with our instructions as a \"system\" message\n const systemMessage: ChatRequestSystemMessage = {\n role: 'system',\n content: this.instructions,\n };\n messages = [systemMessage, ...messages];\n\n const options: GetChatCompletionsOptions = {};\n\n if (this.tools.length > 0) {\n if (this.useLegacyFunctions) {\n // Convert tools to functions\n options.functions = this.tools.map((tool) => {\n return tool.function;\n });\n } else {\n options.tools = this.tools;\n }\n }\n const events = await this.client.streamChatCompletions(\n this.deployment,\n messages,\n options,\n );\n\n return Readable.from(events);\n }\n}\n","import type { FunctionCall } from '@azure/openai';\n\nconst EMULATED_CALL_PREFIX = 'emulated_call_';\n\n/**\n * Helps with the conversion of tool calls to function calls and vice versa.\n */\nexport class ToolEmulator {\n generateEmulatedToolCallId(functionCall: FunctionCall): string {\n return `${EMULATED_CALL_PREFIX}${functionCall.name}`;\n }\n\n isEmulatedToolCallId(toolCallId: string): boolean {\n return toolCallId.startsWith(EMULATED_CALL_PREFIX);\n }\n\n extractFunctionNameFromEmulatedToolCallId(toolCallId: string): string {\n return toolCallId.replace(EMULATED_CALL_PREFIX, '');\n }\n}\n","import type {\n ChatRequestAssistantMessage,\n ChatRequestFunctionMessage,\n ChatRequestMessage,\n ChatRequestSystemMessage,\n ChatRequestToolMessage,\n ChatRequestUserMessage,\n} from '@azure/openai';\nimport type {\n ChatMessage,\n ChatRequestSystemMessageWithMetadata,\n ChatRequestToolMessageWithMetadata,\n ChatRequestUserMessageWithMetadata,\n ChatResponseMessageWithMetadata,\n} from '../message';\nimport { ToolEmulator } from './tool.emulator';\n\nexport class ThreadMessageConverter {\n private readonly toolEmulator = new ToolEmulator();\n\n /**\n * Convert the mix of ChatRequestMessages and ChatResponseMessages to ChatRequestMessages only\n * so they can be sent again to the LLM.\n */\n convert(messages: ChatMessage[]): ChatRequestMessage[] {\n return messages.map((m) => {\n switch (m.role) {\n case 'system': {\n const systemMessage =\n m as ChatRequestSystemMessageWithMetadata;\n return {\n role: 'system',\n content: systemMessage.content,\n } as ChatRequestSystemMessage;\n }\n case 'user': {\n const userMessage = m as ChatRequestUserMessageWithMetadata;\n return {\n role: 'user',\n content: userMessage.content,\n name: userMessage.name,\n } as ChatRequestUserMessage;\n }\n case 'tool': {\n const toolMessage = m as ChatRequestToolMessageWithMetadata;\n if (\n this.toolEmulator.isEmulatedToolCallId(\n toolMessage.toolCallId,\n )\n ) {\n return {\n role: 'function',\n content: toolMessage.content,\n name: this.toolEmulator.extractFunctionNameFromEmulatedToolCallId(\n toolMessage.toolCallId,\n ),\n } as ChatRequestFunctionMessage;\n }\n return {\n role: 'tool',\n content: toolMessage.content,\n toolCallId: toolMessage.toolCallId,\n } as ChatRequestToolMessage;\n }\n case 'assistant': {\n const assistantMessage =\n m as ChatResponseMessageWithMetadata;\n\n if (\n assistantMessage.toolCalls[0] &&\n this.toolEmulator.isEmulatedToolCallId(\n assistantMessage.toolCalls[0].id,\n )\n ) {\n // This is a function call\n return {\n role: 'assistant',\n content: assistantMessage.content,\n functionCall: {\n name: this.toolEmulator.extractFunctionNameFromEmulatedToolCallId(\n assistantMessage.toolCalls[0].id,\n ),\n arguments:\n assistantMessage.toolCalls[0].function\n .arguments,\n },\n } as ChatRequestAssistantMessage;\n }\n\n return {\n role: 'assistant',\n content: assistantMessage.content,\n toolCalls: assistantMessage.toolCalls,\n } as ChatRequestAssistantMessage;\n }\n default:\n throw new Error(`Unknown message role ${m.role}`);\n }\n });\n }\n}\n","import type {\n ChatCompletions,\n ChatCompletionsToolCall,\n ChatRequestMessage,\n ChatResponseMessage,\n FunctionCall,\n} from '@azure/openai';\nimport EventEmitter from 'events';\nimport { Readable } from 'stream';\nimport { Assistant } from '../assistant';\nimport type {\n ChatMessage,\n ChatRequestMessageWithMetadata,\n ChatRequestToolMessageWithMetadata,\n} from '../message';\nimport { ThreadMessageConverter } from './message.converter';\nimport { ToolEmulator } from './tool.emulator';\n\nexport class Thread extends EventEmitter {\n private _stream: Readable | null = null;\n private readonly converter = new ThreadMessageConverter();\n private readonly toolEmulator = new ToolEmulator();\n\n constructor(private readonly messages: ChatMessage[] = []) {\n super();\n }\n\n get stream(): Readable | null {\n if (!this._stream) {\n return null;\n }\n\n return this._stream;\n }\n\n addMessage(message: ChatRequestMessageWithMetadata): void {\n this.doAddMessage(message);\n }\n\n async run(assistant: Assistant): Promise {\n this._stream = new Readable({\n read: () => {},\n });\n\n try {\n return await this.doRun(assistant);\n } catch (e) {\n this.emitImmediate('error', e);\n }\n }\n\n private async doRun(assistant: Assistant): Promise {\n this.emitImmediate('in_progress');\n\n const messages = this.converter.convert(this.messages);\n\n const stream = await assistant.streamChatCompletions(messages);\n\n let content: string | null = null;\n const toolCalls: ChatCompletionsToolCall[] = [];\n let functionCall: FunctionCall | undefined = undefined;\n\n stream.on('data', (completion: ChatCompletions) => {\n if (!completion.id || completion.id === '') {\n // First completion is empty when using old models like gpt-35-turbo\n return;\n }\n const choice = completion.choices[0];\n if (!choice) {\n const err = new Error('No completions returned');\n return this.emitImmediate('error', err);\n }\n\n const delta = choice.delta;\n if (!delta) {\n const err = new Error('No delta returned');\n return this.emitImmediate('error', err);\n }\n\n if (delta.content) {\n content = content ? content + delta.content : delta.content;\n\n // Write also to the stream of the thread\n if (!this._stream) {\n const err = new Error('No stream available');\n return this.emitImmediate('error', err);\n }\n this._stream?.push(delta.content);\n }\n\n // Merge toolCalls\n if (delta.toolCalls) {\n for (const toolCall of delta.toolCalls) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n const index = toolCall['index']; // Not typed yet by the @azure/openai package\n const existingToolCall = toolCalls[index];\n\n if (existingToolCall) {\n existingToolCall.function.arguments +=\n toolCall.function.arguments;\n } else {\n toolCalls.push({\n type: toolCall.type,\n function: toolCall.function,\n id: toolCall.id,\n });\n }\n }\n }\n\n // Merge functionCalls\n if (delta.functionCall) {\n if (functionCall) {\n functionCall.arguments += delta.functionCall.arguments;\n } else {\n functionCall = {\n ...delta.functionCall,\n arguments: '',\n };\n }\n }\n\n if (choice.finishReason === null) {\n return;\n }\n\n let finalToolCalls: ChatCompletionsToolCall[];\n\n if (toolCalls.length > 0) {\n finalToolCalls = [...toolCalls];\n } else if (functionCall) {\n /**\n * We received a legacy function call, we convert it to a tool call with an emulated ID\n */\n const toolCall: ChatCompletionsToolCall = {\n type: 'function',\n function: functionCall,\n id: this.toolEmulator.generateEmulatedToolCallId(\n functionCall,\n ),\n };\n finalToolCalls = [toolCall];\n } else {\n finalToolCalls = [];\n }\n\n const message: ChatResponseMessage = {\n role: 'assistant',\n content,\n toolCalls: finalToolCalls,\n };\n\n content = null;\n toolCalls.splice(0, toolCalls.length);\n functionCall = undefined;\n\n this.doAddMessage(message);\n\n switch (choice.finishReason) {\n case 'stop':\n this._stream?.push(null);\n this.emitImmediate('completed');\n break;\n case 'tool_calls':\n case 'function_call': {\n if (message.toolCalls.length === 0) {\n const err = new Error('No tool calls returned');\n return this.emitImmediate('error', err);\n }\n this.dispatchRequiredAction(message.toolCalls, assistant);\n break;\n }\n default: {\n const err = new Error(\n `Unknown finish reason ${choice.finishReason}`,\n );\n return this.emitImmediate('error', err);\n }\n }\n });\n }\n\n private dispatchRequiredAction(\n toolCalls: ChatCompletionsToolCall[],\n assistant: Assistant,\n ): void {\n const requiredAction = new RequiredAction(toolCalls);\n requiredAction.on('submitting', async (toolOutputs: ToolOutput[]) =>\n this.handleSubmittedToolOutputs(toolOutputs, assistant),\n );\n this.emitImmediate('requires_action', requiredAction);\n }\n\n private async handleSubmittedToolOutputs(\n toolOutputs: ToolOutput[],\n assistant: Assistant,\n ): Promise {\n // Adds the tool outputs to the messages\n for (const toolOutput of toolOutputs) {\n const message: ChatRequestToolMessageWithMetadata = {\n role: 'tool',\n content: JSON.stringify(toolOutput.value),\n toolCallId: toolOutput.callId,\n };\n if (toolOutput.metadata !== void 0) {\n message.metadata = toolOutput.metadata;\n }\n this.doAddMessage(message);\n }\n\n return this.doRun(assistant);\n }\n\n private doAddMessage(\n message: ChatRequestMessage | ChatResponseMessage,\n ): void {\n this.messages.push(message);\n\n this.emitImmediate('message', message);\n\n if (isChatRequestMessage(message)) {\n this.emitImmediate('message:request', message);\n } else {\n this.emitImmediate('message:response', message);\n }\n }\n\n private emitImmediate(event: string, ...args: unknown[]): void {\n if (event === 'error') {\n this.emit(event, ...args);\n } else {\n setImmediate(() => {\n this.emit(event, ...args);\n });\n }\n }\n}\n\nexport class RequiredAction extends EventEmitter {\n constructor(public readonly toolCalls: ChatCompletionsToolCall[]) {\n super();\n }\n\n submitToolOutputs(toolOutputs: ToolOutput[]): void {\n this.emit('submitting', toolOutputs);\n }\n}\n\nexport interface ToolOutput {\n callId: string;\n value: unknown;\n metadata?: unknown;\n}\n\nexport function isChatResponseMessage(\n m: ChatRequestMessage | ChatResponseMessage,\n): m is ChatResponseMessage {\n return 'toolCalls' in m;\n}\n\nexport function isChatRequestMessage(\n m: ChatRequestMessage | ChatResponseMessage,\n): m is ChatRequestMessage {\n return !isChatResponseMessage(m);\n}\n"],"names":["Readable"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"index.js","sources":["../src/assistant/assistant.ts","../src/thread/tool.emulator.ts","../src/thread/message.converter.ts","../src/thread/thread.ts"],"sourcesContent":["import type {\n ChatRequestMessage,\n ChatRequestSystemMessage,\n GetChatCompletionsOptions,\n OpenAIClient,\n} from '@azure/openai';\nimport type { ChatCompletionsToolDefinition } from '@azure/openai/types/src/models/models';\nimport { Readable } from 'stream';\n\nexport interface AssistantCreateParams {\n client: OpenAIClient;\n instructions: string;\n tools: ChatCompletionsToolDefinition[];\n deployment: string;\n useLegacyFunctions?: boolean;\n}\n\nexport class Assistant {\n public readonly client: OpenAIClient;\n\n private readonly instructions: string;\n private readonly tools: ChatCompletionsToolDefinition[];\n private readonly deployment: string;\n private readonly useLegacyFunctions: boolean;\n\n constructor(params: AssistantCreateParams) {\n this.client = params.client;\n this.instructions = params.instructions;\n this.tools = params.tools;\n this.deployment = params.deployment;\n this.useLegacyFunctions = params.useLegacyFunctions ?? false;\n }\n\n async streamChatCompletions(\n messages: ChatRequestMessage[],\n ): Promise {\n // Prepend the messages with our instructions as a \"system\" message\n const systemMessage: ChatRequestSystemMessage = {\n role: 'system',\n content: this.instructions,\n };\n messages = [systemMessage, ...messages];\n\n const options: GetChatCompletionsOptions = {};\n\n if (this.tools.length > 0) {\n if (this.useLegacyFunctions) {\n // Convert tools to functions\n options.functions = this.tools.map((tool) => {\n return tool.function;\n });\n } else {\n options.tools = this.tools;\n }\n }\n const events = await this.client.streamChatCompletions(\n this.deployment,\n messages,\n options,\n );\n\n return Readable.from(events);\n }\n}\n","import type { FunctionCall } from '@azure/openai';\n\nconst EMULATED_CALL_PREFIX = 'emulated_call_';\n\n/**\n * Helps with the conversion of tool calls to function calls and vice versa.\n */\nexport class ToolEmulator {\n generateEmulatedToolCallId(functionCall: FunctionCall): string {\n return `${EMULATED_CALL_PREFIX}${functionCall.name}`;\n }\n\n isEmulatedToolCallId(toolCallId: string): boolean {\n return toolCallId.startsWith(EMULATED_CALL_PREFIX);\n }\n\n extractFunctionNameFromEmulatedToolCallId(toolCallId: string): string {\n return toolCallId.replace(EMULATED_CALL_PREFIX, '');\n }\n}\n","import type {\n ChatRequestAssistantMessage,\n ChatRequestFunctionMessage,\n ChatRequestMessage,\n ChatRequestSystemMessage,\n ChatRequestToolMessage,\n ChatRequestUserMessage,\n} from '@azure/openai';\nimport type {\n ChatMessage,\n ChatRequestSystemMessageWithMetadata,\n ChatRequestToolMessageWithMetadata,\n ChatRequestUserMessageWithMetadata,\n ChatResponseMessageWithMetadata,\n} from '../message';\nimport { ToolEmulator } from './tool.emulator';\n\nexport class ThreadMessageConverter {\n private readonly toolEmulator = new ToolEmulator();\n\n /**\n * Convert the mix of ChatRequestMessages and ChatResponseMessages to ChatRequestMessages only\n * so they can be sent again to the LLM.\n */\n convert(messages: ChatMessage[]): ChatRequestMessage[] {\n return messages.map((m) => {\n switch (m.role) {\n case 'system': {\n const systemMessage =\n m as ChatRequestSystemMessageWithMetadata;\n return {\n role: 'system',\n content: systemMessage.content,\n } as ChatRequestSystemMessage;\n }\n case 'user': {\n const userMessage = m as ChatRequestUserMessageWithMetadata;\n return {\n role: 'user',\n content: userMessage.content,\n name: userMessage.name,\n } as ChatRequestUserMessage;\n }\n case 'tool': {\n const toolMessage = m as ChatRequestToolMessageWithMetadata;\n if (\n this.toolEmulator.isEmulatedToolCallId(\n toolMessage.toolCallId,\n )\n ) {\n return {\n role: 'function',\n content: toolMessage.content,\n name: this.toolEmulator.extractFunctionNameFromEmulatedToolCallId(\n toolMessage.toolCallId,\n ),\n } as ChatRequestFunctionMessage;\n }\n return {\n role: 'tool',\n content: toolMessage.content,\n toolCallId: toolMessage.toolCallId,\n } as ChatRequestToolMessage;\n }\n case 'assistant': {\n const assistantMessage =\n m as ChatResponseMessageWithMetadata;\n\n if (\n assistantMessage.toolCalls[0] &&\n this.toolEmulator.isEmulatedToolCallId(\n assistantMessage.toolCalls[0].id,\n )\n ) {\n // This is a function call\n return {\n role: 'assistant',\n content: assistantMessage.content,\n functionCall: {\n name: this.toolEmulator.extractFunctionNameFromEmulatedToolCallId(\n assistantMessage.toolCalls[0].id,\n ),\n arguments:\n assistantMessage.toolCalls[0].function\n .arguments,\n },\n } as ChatRequestAssistantMessage;\n }\n\n return {\n role: 'assistant',\n content: assistantMessage.content,\n toolCalls: assistantMessage.toolCalls,\n } as ChatRequestAssistantMessage;\n }\n default:\n throw new Error(`Unknown message role ${m.role}`);\n }\n });\n }\n}\n","import type {\n ChatCompletions,\n ChatCompletionsToolCall,\n ChatRequestMessage,\n ChatResponseMessage,\n FunctionCall,\n} from '@azure/openai';\nimport EventEmitter from 'events';\nimport { Readable } from 'stream';\nimport { Assistant } from '../assistant';\nimport type {\n ChatMessage,\n ChatRequestMessageWithMetadata,\n ChatRequestToolMessageWithMetadata,\n} from '../message';\nimport { ThreadMessageConverter } from './message.converter';\nimport { ToolEmulator } from './tool.emulator';\n\nexport class Thread extends EventEmitter {\n private _stream: Readable | null = null;\n private readonly converter = new ThreadMessageConverter();\n private readonly toolEmulator = new ToolEmulator();\n\n constructor(\n public readonly id: string,\n private readonly messages: ChatMessage[] = [],\n ) {\n super();\n }\n\n get stream(): Readable | null {\n return this._stream;\n }\n\n addMessage(message: ChatRequestMessageWithMetadata): void {\n this.doAddMessage(message);\n }\n\n async run(assistant: Assistant): Promise {\n try {\n return await this.doRun(assistant);\n } catch (e) {\n this.emitImmediate('error', e);\n }\n }\n\n private async doRun(assistant: Assistant): Promise {\n this._stream = new Readable({\n read: () => {},\n });\n\n this.emitImmediate('in_progress');\n\n const messages = this.converter.convert(this.messages);\n\n const stream = await assistant.streamChatCompletions(messages);\n\n let content: string | null = null;\n const toolCalls: ChatCompletionsToolCall[] = [];\n let functionCall: FunctionCall | undefined = undefined;\n\n stream.on('data', (completion: ChatCompletions) => {\n if (!completion.id || completion.id === '') {\n // First completion is empty when using old models like gpt-35-turbo\n return;\n }\n const choice = completion.choices[0];\n if (!choice) {\n const err = new Error('No completions returned');\n return this.emitImmediate('error', err);\n }\n\n const delta = choice.delta;\n if (!delta) {\n const err = new Error('No delta returned');\n return this.emitImmediate('error', err);\n }\n\n if (delta.content) {\n content = content ? content + delta.content : delta.content;\n\n // Write also to the stream of the thread\n if (!this._stream) {\n const err = new Error('No stream available');\n return this.emitImmediate('error', err);\n }\n this._stream?.push(delta.content);\n }\n\n // Merge toolCalls\n if (delta.toolCalls) {\n for (const toolCall of delta.toolCalls) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n const index = toolCall['index']; // Not typed yet by the @azure/openai package\n const existingToolCall = toolCalls[index];\n\n if (existingToolCall) {\n existingToolCall.function.arguments +=\n toolCall.function.arguments;\n } else {\n toolCalls.push({\n type: toolCall.type,\n function: toolCall.function,\n id: toolCall.id,\n });\n }\n }\n }\n\n // Merge functionCalls\n if (delta.functionCall) {\n if (functionCall) {\n functionCall.arguments += delta.functionCall.arguments;\n } else {\n functionCall = {\n ...delta.functionCall,\n arguments: '',\n };\n }\n }\n\n if (choice.finishReason === null) {\n return;\n }\n\n let finalToolCalls: ChatCompletionsToolCall[];\n\n if (toolCalls.length > 0) {\n finalToolCalls = [...toolCalls];\n } else if (functionCall) {\n /**\n * We received a legacy function call, we convert it to a tool call with an emulated ID\n */\n const toolCall: ChatCompletionsToolCall = {\n type: 'function',\n function: functionCall,\n id: this.toolEmulator.generateEmulatedToolCallId(\n functionCall,\n ),\n };\n finalToolCalls = [toolCall];\n } else {\n finalToolCalls = [];\n }\n\n const message: ChatResponseMessage = {\n role: 'assistant',\n content,\n toolCalls: finalToolCalls,\n };\n\n content = null;\n toolCalls.splice(0, toolCalls.length);\n functionCall = undefined;\n\n this.doAddMessage(message);\n\n switch (choice.finishReason) {\n case 'stop':\n this._stream?.push(null);\n this.emitImmediate('completed');\n break;\n case 'tool_calls':\n case 'function_call': {\n if (message.toolCalls.length === 0) {\n const err = new Error('No tool calls returned');\n return this.emitImmediate('error', err);\n }\n this.dispatchRequiredAction(message.toolCalls, assistant);\n break;\n }\n default: {\n const err = new Error(\n `Unknown finish reason ${choice.finishReason}`,\n );\n return this.emitImmediate('error', err);\n }\n }\n });\n }\n\n private dispatchRequiredAction(\n toolCalls: ChatCompletionsToolCall[],\n assistant: Assistant,\n ): void {\n const requiredAction = new RequiredAction(toolCalls);\n requiredAction.on('submitting', async (toolOutputs: ToolOutput[]) =>\n this.handleSubmittedToolOutputs(toolOutputs, assistant),\n );\n this.emitImmediate('requires_action', requiredAction);\n }\n\n private async handleSubmittedToolOutputs(\n toolOutputs: ToolOutput[],\n assistant: Assistant,\n ): Promise {\n // Adds the tool outputs to the messages\n for (const toolOutput of toolOutputs) {\n const message: ChatRequestToolMessageWithMetadata = {\n role: 'tool',\n content: JSON.stringify(toolOutput.value),\n toolCallId: toolOutput.callId,\n };\n if (toolOutput.metadata !== void 0) {\n message.metadata = toolOutput.metadata;\n }\n this.doAddMessage(message);\n }\n\n return this.doRun(assistant);\n }\n\n private doAddMessage(\n message: ChatRequestMessage | ChatResponseMessage,\n ): void {\n this.messages.push(message);\n\n this.emitImmediate('message', message);\n\n if (isChatRequestMessage(message)) {\n this.emitImmediate('message:request', message);\n } else {\n this.emitImmediate('message:response', message);\n }\n }\n\n private emitImmediate(event: string, ...args: unknown[]): void {\n if (event === 'error') {\n this.emit(event, ...args);\n } else {\n setImmediate(() => {\n this.emit(event, ...args);\n });\n }\n }\n}\n\nexport class RequiredAction extends EventEmitter {\n constructor(public readonly toolCalls: ChatCompletionsToolCall[]) {\n super();\n }\n\n submitToolOutputs(toolOutputs: ToolOutput[]): void {\n this.emit('submitting', toolOutputs);\n }\n}\n\nexport interface ToolOutput {\n callId: string;\n value: unknown;\n metadata?: unknown;\n}\n\nexport function isChatResponseMessage(\n m: ChatRequestMessage | ChatResponseMessage,\n): m is ChatResponseMessage {\n return 'toolCalls' in m;\n}\n\nexport function isChatRequestMessage(\n m: ChatRequestMessage | ChatResponseMessage,\n): m is ChatRequestMessage {\n return !isChatResponseMessage(m);\n}\n"],"names":["Readable","stream"],"mappings":"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"} \ No newline at end of file diff --git a/dist/index.mjs b/dist/index.mjs index cf17da8..439bcc7 100644 --- a/dist/index.mjs +++ b/dist/index.mjs @@ -125,26 +125,21 @@ class ThreadMessageConverter { } class Thread extends EventEmitter { - constructor(messages = []) { + constructor(id, messages = []) { super(); + this.id = id; this.messages = messages; this._stream = null; this.converter = new ThreadMessageConverter(); this.toolEmulator = new ToolEmulator(); } get stream() { - if (!this._stream) { - return null; - } return this._stream; } addMessage(message) { this.doAddMessage(message); } async run(assistant) { - this._stream = new Readable({ - read: () => { }, - }); try { return await this.doRun(assistant); } @@ -153,6 +148,9 @@ class Thread extends EventEmitter { } } async doRun(assistant) { + this._stream = new Readable({ + read: () => { }, + }); this.emitImmediate('in_progress'); const messages = this.converter.convert(this.messages); const stream = await assistant.streamChatCompletions(messages); diff --git a/dist/index.mjs.map b/dist/index.mjs.map index 4ad2590..7f3864d 100644 --- a/dist/index.mjs.map +++ b/dist/index.mjs.map @@ -1 +1 @@ -{"version":3,"file":"index.mjs","sources":["../src/assistant/assistant.ts","../src/thread/tool.emulator.ts","../src/thread/message.converter.ts","../src/thread/thread.ts"],"sourcesContent":["import type {\n ChatRequestMessage,\n ChatRequestSystemMessage,\n GetChatCompletionsOptions,\n OpenAIClient,\n} from '@azure/openai';\nimport type { ChatCompletionsToolDefinition } from '@azure/openai/types/src/models/models';\nimport { Readable } from 'stream';\n\nexport interface AssistantCreateParams {\n client: OpenAIClient;\n instructions: string;\n tools: ChatCompletionsToolDefinition[];\n deployment: string;\n useLegacyFunctions?: boolean;\n}\n\nexport class Assistant {\n public readonly client: OpenAIClient;\n\n private readonly instructions: string;\n private readonly tools: ChatCompletionsToolDefinition[];\n private readonly deployment: string;\n private readonly useLegacyFunctions: boolean;\n\n constructor(params: AssistantCreateParams) {\n this.client = params.client;\n this.instructions = params.instructions;\n this.tools = params.tools;\n this.deployment = params.deployment;\n this.useLegacyFunctions = params.useLegacyFunctions ?? false;\n }\n\n async streamChatCompletions(\n messages: ChatRequestMessage[],\n ): Promise {\n // Prepend the messages with our instructions as a \"system\" message\n const systemMessage: ChatRequestSystemMessage = {\n role: 'system',\n content: this.instructions,\n };\n messages = [systemMessage, ...messages];\n\n const options: GetChatCompletionsOptions = {};\n\n if (this.tools.length > 0) {\n if (this.useLegacyFunctions) {\n // Convert tools to functions\n options.functions = this.tools.map((tool) => {\n return tool.function;\n });\n } else {\n options.tools = this.tools;\n }\n }\n const events = await this.client.streamChatCompletions(\n this.deployment,\n messages,\n options,\n );\n\n return Readable.from(events);\n }\n}\n","import type { FunctionCall } from '@azure/openai';\n\nconst EMULATED_CALL_PREFIX = 'emulated_call_';\n\n/**\n * Helps with the conversion of tool calls to function calls and vice versa.\n */\nexport class ToolEmulator {\n generateEmulatedToolCallId(functionCall: FunctionCall): string {\n return `${EMULATED_CALL_PREFIX}${functionCall.name}`;\n }\n\n isEmulatedToolCallId(toolCallId: string): boolean {\n return toolCallId.startsWith(EMULATED_CALL_PREFIX);\n }\n\n extractFunctionNameFromEmulatedToolCallId(toolCallId: string): string {\n return toolCallId.replace(EMULATED_CALL_PREFIX, '');\n }\n}\n","import type {\n ChatRequestAssistantMessage,\n ChatRequestFunctionMessage,\n ChatRequestMessage,\n ChatRequestSystemMessage,\n ChatRequestToolMessage,\n ChatRequestUserMessage,\n} from '@azure/openai';\nimport type {\n ChatMessage,\n ChatRequestSystemMessageWithMetadata,\n ChatRequestToolMessageWithMetadata,\n ChatRequestUserMessageWithMetadata,\n ChatResponseMessageWithMetadata,\n} from '../message';\nimport { ToolEmulator } from './tool.emulator';\n\nexport class ThreadMessageConverter {\n private readonly toolEmulator = new ToolEmulator();\n\n /**\n * Convert the mix of ChatRequestMessages and ChatResponseMessages to ChatRequestMessages only\n * so they can be sent again to the LLM.\n */\n convert(messages: ChatMessage[]): ChatRequestMessage[] {\n return messages.map((m) => {\n switch (m.role) {\n case 'system': {\n const systemMessage =\n m as ChatRequestSystemMessageWithMetadata;\n return {\n role: 'system',\n content: systemMessage.content,\n } as ChatRequestSystemMessage;\n }\n case 'user': {\n const userMessage = m as ChatRequestUserMessageWithMetadata;\n return {\n role: 'user',\n content: userMessage.content,\n name: userMessage.name,\n } as ChatRequestUserMessage;\n }\n case 'tool': {\n const toolMessage = m as ChatRequestToolMessageWithMetadata;\n if (\n this.toolEmulator.isEmulatedToolCallId(\n toolMessage.toolCallId,\n )\n ) {\n return {\n role: 'function',\n content: toolMessage.content,\n name: this.toolEmulator.extractFunctionNameFromEmulatedToolCallId(\n toolMessage.toolCallId,\n ),\n } as ChatRequestFunctionMessage;\n }\n return {\n role: 'tool',\n content: toolMessage.content,\n toolCallId: toolMessage.toolCallId,\n } as ChatRequestToolMessage;\n }\n case 'assistant': {\n const assistantMessage =\n m as ChatResponseMessageWithMetadata;\n\n if (\n assistantMessage.toolCalls[0] &&\n this.toolEmulator.isEmulatedToolCallId(\n assistantMessage.toolCalls[0].id,\n )\n ) {\n // This is a function call\n return {\n role: 'assistant',\n content: assistantMessage.content,\n functionCall: {\n name: this.toolEmulator.extractFunctionNameFromEmulatedToolCallId(\n assistantMessage.toolCalls[0].id,\n ),\n arguments:\n assistantMessage.toolCalls[0].function\n .arguments,\n },\n } as ChatRequestAssistantMessage;\n }\n\n return {\n role: 'assistant',\n content: assistantMessage.content,\n toolCalls: assistantMessage.toolCalls,\n } as ChatRequestAssistantMessage;\n }\n default:\n throw new Error(`Unknown message role ${m.role}`);\n }\n });\n }\n}\n","import type {\n ChatCompletions,\n ChatCompletionsToolCall,\n ChatRequestMessage,\n ChatResponseMessage,\n FunctionCall,\n} from '@azure/openai';\nimport EventEmitter from 'events';\nimport { Readable } from 'stream';\nimport { Assistant } from '../assistant';\nimport type {\n ChatMessage,\n ChatRequestMessageWithMetadata,\n ChatRequestToolMessageWithMetadata,\n} from '../message';\nimport { ThreadMessageConverter } from './message.converter';\nimport { ToolEmulator } from './tool.emulator';\n\nexport class Thread extends EventEmitter {\n private _stream: Readable | null = null;\n private readonly converter = new ThreadMessageConverter();\n private readonly toolEmulator = new ToolEmulator();\n\n constructor(private readonly messages: ChatMessage[] = []) {\n super();\n }\n\n get stream(): Readable | null {\n if (!this._stream) {\n return null;\n }\n\n return this._stream;\n }\n\n addMessage(message: ChatRequestMessageWithMetadata): void {\n this.doAddMessage(message);\n }\n\n async run(assistant: Assistant): Promise {\n this._stream = new Readable({\n read: () => {},\n });\n\n try {\n return await this.doRun(assistant);\n } catch (e) {\n this.emitImmediate('error', e);\n }\n }\n\n private async doRun(assistant: Assistant): Promise {\n this.emitImmediate('in_progress');\n\n const messages = this.converter.convert(this.messages);\n\n const stream = await assistant.streamChatCompletions(messages);\n\n let content: string | null = null;\n const toolCalls: ChatCompletionsToolCall[] = [];\n let functionCall: FunctionCall | undefined = undefined;\n\n stream.on('data', (completion: ChatCompletions) => {\n if (!completion.id || completion.id === '') {\n // First completion is empty when using old models like gpt-35-turbo\n return;\n }\n const choice = completion.choices[0];\n if (!choice) {\n const err = new Error('No completions returned');\n return this.emitImmediate('error', err);\n }\n\n const delta = choice.delta;\n if (!delta) {\n const err = new Error('No delta returned');\n return this.emitImmediate('error', err);\n }\n\n if (delta.content) {\n content = content ? content + delta.content : delta.content;\n\n // Write also to the stream of the thread\n if (!this._stream) {\n const err = new Error('No stream available');\n return this.emitImmediate('error', err);\n }\n this._stream?.push(delta.content);\n }\n\n // Merge toolCalls\n if (delta.toolCalls) {\n for (const toolCall of delta.toolCalls) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n const index = toolCall['index']; // Not typed yet by the @azure/openai package\n const existingToolCall = toolCalls[index];\n\n if (existingToolCall) {\n existingToolCall.function.arguments +=\n toolCall.function.arguments;\n } else {\n toolCalls.push({\n type: toolCall.type,\n function: toolCall.function,\n id: toolCall.id,\n });\n }\n }\n }\n\n // Merge functionCalls\n if (delta.functionCall) {\n if (functionCall) {\n functionCall.arguments += delta.functionCall.arguments;\n } else {\n functionCall = {\n ...delta.functionCall,\n arguments: '',\n };\n }\n }\n\n if (choice.finishReason === null) {\n return;\n }\n\n let finalToolCalls: ChatCompletionsToolCall[];\n\n if (toolCalls.length > 0) {\n finalToolCalls = [...toolCalls];\n } else if (functionCall) {\n /**\n * We received a legacy function call, we convert it to a tool call with an emulated ID\n */\n const toolCall: ChatCompletionsToolCall = {\n type: 'function',\n function: functionCall,\n id: this.toolEmulator.generateEmulatedToolCallId(\n functionCall,\n ),\n };\n finalToolCalls = [toolCall];\n } else {\n finalToolCalls = [];\n }\n\n const message: ChatResponseMessage = {\n role: 'assistant',\n content,\n toolCalls: finalToolCalls,\n };\n\n content = null;\n toolCalls.splice(0, toolCalls.length);\n functionCall = undefined;\n\n this.doAddMessage(message);\n\n switch (choice.finishReason) {\n case 'stop':\n this._stream?.push(null);\n this.emitImmediate('completed');\n break;\n case 'tool_calls':\n case 'function_call': {\n if (message.toolCalls.length === 0) {\n const err = new Error('No tool calls returned');\n return this.emitImmediate('error', err);\n }\n this.dispatchRequiredAction(message.toolCalls, assistant);\n break;\n }\n default: {\n const err = new Error(\n `Unknown finish reason ${choice.finishReason}`,\n );\n return this.emitImmediate('error', err);\n }\n }\n });\n }\n\n private dispatchRequiredAction(\n toolCalls: ChatCompletionsToolCall[],\n assistant: Assistant,\n ): void {\n const requiredAction = new RequiredAction(toolCalls);\n requiredAction.on('submitting', async (toolOutputs: ToolOutput[]) =>\n this.handleSubmittedToolOutputs(toolOutputs, assistant),\n );\n this.emitImmediate('requires_action', requiredAction);\n }\n\n private async handleSubmittedToolOutputs(\n toolOutputs: ToolOutput[],\n assistant: Assistant,\n ): Promise {\n // Adds the tool outputs to the messages\n for (const toolOutput of toolOutputs) {\n const message: ChatRequestToolMessageWithMetadata = {\n role: 'tool',\n content: JSON.stringify(toolOutput.value),\n toolCallId: toolOutput.callId,\n };\n if (toolOutput.metadata !== void 0) {\n message.metadata = toolOutput.metadata;\n }\n this.doAddMessage(message);\n }\n\n return this.doRun(assistant);\n }\n\n private doAddMessage(\n message: ChatRequestMessage | ChatResponseMessage,\n ): void {\n this.messages.push(message);\n\n this.emitImmediate('message', message);\n\n if (isChatRequestMessage(message)) {\n this.emitImmediate('message:request', message);\n } else {\n this.emitImmediate('message:response', message);\n }\n }\n\n private emitImmediate(event: string, ...args: unknown[]): void {\n if (event === 'error') {\n this.emit(event, ...args);\n } else {\n setImmediate(() => {\n this.emit(event, ...args);\n });\n }\n }\n}\n\nexport class RequiredAction extends EventEmitter {\n constructor(public readonly toolCalls: ChatCompletionsToolCall[]) {\n super();\n }\n\n submitToolOutputs(toolOutputs: ToolOutput[]): void {\n this.emit('submitting', toolOutputs);\n }\n}\n\nexport interface ToolOutput {\n callId: string;\n value: unknown;\n metadata?: unknown;\n}\n\nexport function isChatResponseMessage(\n m: ChatRequestMessage | ChatResponseMessage,\n): m is ChatResponseMessage {\n return 'toolCalls' in m;\n}\n\nexport function isChatRequestMessage(\n m: ChatRequestMessage | ChatResponseMessage,\n): m is ChatRequestMessage {\n return !isChatResponseMessage(m);\n}\n"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"index.mjs","sources":["../src/assistant/assistant.ts","../src/thread/tool.emulator.ts","../src/thread/message.converter.ts","../src/thread/thread.ts"],"sourcesContent":["import type {\n ChatRequestMessage,\n ChatRequestSystemMessage,\n GetChatCompletionsOptions,\n OpenAIClient,\n} from '@azure/openai';\nimport type { ChatCompletionsToolDefinition } from '@azure/openai/types/src/models/models';\nimport { Readable } from 'stream';\n\nexport interface AssistantCreateParams {\n client: OpenAIClient;\n instructions: string;\n tools: ChatCompletionsToolDefinition[];\n deployment: string;\n useLegacyFunctions?: boolean;\n}\n\nexport class Assistant {\n public readonly client: OpenAIClient;\n\n private readonly instructions: string;\n private readonly tools: ChatCompletionsToolDefinition[];\n private readonly deployment: string;\n private readonly useLegacyFunctions: boolean;\n\n constructor(params: AssistantCreateParams) {\n this.client = params.client;\n this.instructions = params.instructions;\n this.tools = params.tools;\n this.deployment = params.deployment;\n this.useLegacyFunctions = params.useLegacyFunctions ?? false;\n }\n\n async streamChatCompletions(\n messages: ChatRequestMessage[],\n ): Promise {\n // Prepend the messages with our instructions as a \"system\" message\n const systemMessage: ChatRequestSystemMessage = {\n role: 'system',\n content: this.instructions,\n };\n messages = [systemMessage, ...messages];\n\n const options: GetChatCompletionsOptions = {};\n\n if (this.tools.length > 0) {\n if (this.useLegacyFunctions) {\n // Convert tools to functions\n options.functions = this.tools.map((tool) => {\n return tool.function;\n });\n } else {\n options.tools = this.tools;\n }\n }\n const events = await this.client.streamChatCompletions(\n this.deployment,\n messages,\n options,\n );\n\n return Readable.from(events);\n }\n}\n","import type { FunctionCall } from '@azure/openai';\n\nconst EMULATED_CALL_PREFIX = 'emulated_call_';\n\n/**\n * Helps with the conversion of tool calls to function calls and vice versa.\n */\nexport class ToolEmulator {\n generateEmulatedToolCallId(functionCall: FunctionCall): string {\n return `${EMULATED_CALL_PREFIX}${functionCall.name}`;\n }\n\n isEmulatedToolCallId(toolCallId: string): boolean {\n return toolCallId.startsWith(EMULATED_CALL_PREFIX);\n }\n\n extractFunctionNameFromEmulatedToolCallId(toolCallId: string): string {\n return toolCallId.replace(EMULATED_CALL_PREFIX, '');\n }\n}\n","import type {\n ChatRequestAssistantMessage,\n ChatRequestFunctionMessage,\n ChatRequestMessage,\n ChatRequestSystemMessage,\n ChatRequestToolMessage,\n ChatRequestUserMessage,\n} from '@azure/openai';\nimport type {\n ChatMessage,\n ChatRequestSystemMessageWithMetadata,\n ChatRequestToolMessageWithMetadata,\n ChatRequestUserMessageWithMetadata,\n ChatResponseMessageWithMetadata,\n} from '../message';\nimport { ToolEmulator } from './tool.emulator';\n\nexport class ThreadMessageConverter {\n private readonly toolEmulator = new ToolEmulator();\n\n /**\n * Convert the mix of ChatRequestMessages and ChatResponseMessages to ChatRequestMessages only\n * so they can be sent again to the LLM.\n */\n convert(messages: ChatMessage[]): ChatRequestMessage[] {\n return messages.map((m) => {\n switch (m.role) {\n case 'system': {\n const systemMessage =\n m as ChatRequestSystemMessageWithMetadata;\n return {\n role: 'system',\n content: systemMessage.content,\n } as ChatRequestSystemMessage;\n }\n case 'user': {\n const userMessage = m as ChatRequestUserMessageWithMetadata;\n return {\n role: 'user',\n content: userMessage.content,\n name: userMessage.name,\n } as ChatRequestUserMessage;\n }\n case 'tool': {\n const toolMessage = m as ChatRequestToolMessageWithMetadata;\n if (\n this.toolEmulator.isEmulatedToolCallId(\n toolMessage.toolCallId,\n )\n ) {\n return {\n role: 'function',\n content: toolMessage.content,\n name: this.toolEmulator.extractFunctionNameFromEmulatedToolCallId(\n toolMessage.toolCallId,\n ),\n } as ChatRequestFunctionMessage;\n }\n return {\n role: 'tool',\n content: toolMessage.content,\n toolCallId: toolMessage.toolCallId,\n } as ChatRequestToolMessage;\n }\n case 'assistant': {\n const assistantMessage =\n m as ChatResponseMessageWithMetadata;\n\n if (\n assistantMessage.toolCalls[0] &&\n this.toolEmulator.isEmulatedToolCallId(\n assistantMessage.toolCalls[0].id,\n )\n ) {\n // This is a function call\n return {\n role: 'assistant',\n content: assistantMessage.content,\n functionCall: {\n name: this.toolEmulator.extractFunctionNameFromEmulatedToolCallId(\n assistantMessage.toolCalls[0].id,\n ),\n arguments:\n assistantMessage.toolCalls[0].function\n .arguments,\n },\n } as ChatRequestAssistantMessage;\n }\n\n return {\n role: 'assistant',\n content: assistantMessage.content,\n toolCalls: assistantMessage.toolCalls,\n } as ChatRequestAssistantMessage;\n }\n default:\n throw new Error(`Unknown message role ${m.role}`);\n }\n });\n }\n}\n","import type {\n ChatCompletions,\n ChatCompletionsToolCall,\n ChatRequestMessage,\n ChatResponseMessage,\n FunctionCall,\n} from '@azure/openai';\nimport EventEmitter from 'events';\nimport { Readable } from 'stream';\nimport { Assistant } from '../assistant';\nimport type {\n ChatMessage,\n ChatRequestMessageWithMetadata,\n ChatRequestToolMessageWithMetadata,\n} from '../message';\nimport { ThreadMessageConverter } from './message.converter';\nimport { ToolEmulator } from './tool.emulator';\n\nexport class Thread extends EventEmitter {\n private _stream: Readable | null = null;\n private readonly converter = new ThreadMessageConverter();\n private readonly toolEmulator = new ToolEmulator();\n\n constructor(\n public readonly id: string,\n private readonly messages: ChatMessage[] = [],\n ) {\n super();\n }\n\n get stream(): Readable | null {\n return this._stream;\n }\n\n addMessage(message: ChatRequestMessageWithMetadata): void {\n this.doAddMessage(message);\n }\n\n async run(assistant: Assistant): Promise {\n try {\n return await this.doRun(assistant);\n } catch (e) {\n this.emitImmediate('error', e);\n }\n }\n\n private async doRun(assistant: Assistant): Promise {\n this._stream = new Readable({\n read: () => {},\n });\n\n this.emitImmediate('in_progress');\n\n const messages = this.converter.convert(this.messages);\n\n const stream = await assistant.streamChatCompletions(messages);\n\n let content: string | null = null;\n const toolCalls: ChatCompletionsToolCall[] = [];\n let functionCall: FunctionCall | undefined = undefined;\n\n stream.on('data', (completion: ChatCompletions) => {\n if (!completion.id || completion.id === '') {\n // First completion is empty when using old models like gpt-35-turbo\n return;\n }\n const choice = completion.choices[0];\n if (!choice) {\n const err = new Error('No completions returned');\n return this.emitImmediate('error', err);\n }\n\n const delta = choice.delta;\n if (!delta) {\n const err = new Error('No delta returned');\n return this.emitImmediate('error', err);\n }\n\n if (delta.content) {\n content = content ? content + delta.content : delta.content;\n\n // Write also to the stream of the thread\n if (!this._stream) {\n const err = new Error('No stream available');\n return this.emitImmediate('error', err);\n }\n this._stream?.push(delta.content);\n }\n\n // Merge toolCalls\n if (delta.toolCalls) {\n for (const toolCall of delta.toolCalls) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n const index = toolCall['index']; // Not typed yet by the @azure/openai package\n const existingToolCall = toolCalls[index];\n\n if (existingToolCall) {\n existingToolCall.function.arguments +=\n toolCall.function.arguments;\n } else {\n toolCalls.push({\n type: toolCall.type,\n function: toolCall.function,\n id: toolCall.id,\n });\n }\n }\n }\n\n // Merge functionCalls\n if (delta.functionCall) {\n if (functionCall) {\n functionCall.arguments += delta.functionCall.arguments;\n } else {\n functionCall = {\n ...delta.functionCall,\n arguments: '',\n };\n }\n }\n\n if (choice.finishReason === null) {\n return;\n }\n\n let finalToolCalls: ChatCompletionsToolCall[];\n\n if (toolCalls.length > 0) {\n finalToolCalls = [...toolCalls];\n } else if (functionCall) {\n /**\n * We received a legacy function call, we convert it to a tool call with an emulated ID\n */\n const toolCall: ChatCompletionsToolCall = {\n type: 'function',\n function: functionCall,\n id: this.toolEmulator.generateEmulatedToolCallId(\n functionCall,\n ),\n };\n finalToolCalls = [toolCall];\n } else {\n finalToolCalls = [];\n }\n\n const message: ChatResponseMessage = {\n role: 'assistant',\n content,\n toolCalls: finalToolCalls,\n };\n\n content = null;\n toolCalls.splice(0, toolCalls.length);\n functionCall = undefined;\n\n this.doAddMessage(message);\n\n switch (choice.finishReason) {\n case 'stop':\n this._stream?.push(null);\n this.emitImmediate('completed');\n break;\n case 'tool_calls':\n case 'function_call': {\n if (message.toolCalls.length === 0) {\n const err = new Error('No tool calls returned');\n return this.emitImmediate('error', err);\n }\n this.dispatchRequiredAction(message.toolCalls, assistant);\n break;\n }\n default: {\n const err = new Error(\n `Unknown finish reason ${choice.finishReason}`,\n );\n return this.emitImmediate('error', err);\n }\n }\n });\n }\n\n private dispatchRequiredAction(\n toolCalls: ChatCompletionsToolCall[],\n assistant: Assistant,\n ): void {\n const requiredAction = new RequiredAction(toolCalls);\n requiredAction.on('submitting', async (toolOutputs: ToolOutput[]) =>\n this.handleSubmittedToolOutputs(toolOutputs, assistant),\n );\n this.emitImmediate('requires_action', requiredAction);\n }\n\n private async handleSubmittedToolOutputs(\n toolOutputs: ToolOutput[],\n assistant: Assistant,\n ): Promise {\n // Adds the tool outputs to the messages\n for (const toolOutput of toolOutputs) {\n const message: ChatRequestToolMessageWithMetadata = {\n role: 'tool',\n content: JSON.stringify(toolOutput.value),\n toolCallId: toolOutput.callId,\n };\n if (toolOutput.metadata !== void 0) {\n message.metadata = toolOutput.metadata;\n }\n this.doAddMessage(message);\n }\n\n return this.doRun(assistant);\n }\n\n private doAddMessage(\n message: ChatRequestMessage | ChatResponseMessage,\n ): void {\n this.messages.push(message);\n\n this.emitImmediate('message', message);\n\n if (isChatRequestMessage(message)) {\n this.emitImmediate('message:request', message);\n } else {\n this.emitImmediate('message:response', message);\n }\n }\n\n private emitImmediate(event: string, ...args: unknown[]): void {\n if (event === 'error') {\n this.emit(event, ...args);\n } else {\n setImmediate(() => {\n this.emit(event, ...args);\n });\n }\n }\n}\n\nexport class RequiredAction extends EventEmitter {\n constructor(public readonly toolCalls: ChatCompletionsToolCall[]) {\n super();\n }\n\n submitToolOutputs(toolOutputs: ToolOutput[]): void {\n this.emit('submitting', toolOutputs);\n }\n}\n\nexport interface ToolOutput {\n callId: string;\n value: unknown;\n metadata?: unknown;\n}\n\nexport function isChatResponseMessage(\n m: ChatRequestMessage | ChatResponseMessage,\n): m is ChatResponseMessage {\n return 'toolCalls' in m;\n}\n\nexport function isChatRequestMessage(\n m: ChatRequestMessage | ChatResponseMessage,\n): m is ChatRequestMessage {\n return !isChatResponseMessage(m);\n}\n"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/docs/README.md b/docs/README.md index a105b30..2a99fc8 100644 --- a/docs/README.md +++ b/docs/README.md @@ -40,7 +40,7 @@ LLobotoMy for Azure #### Defined in -[src/message/message.ts:32](https://github.com/paztek/llobotomy-azure/blob/26afba8/src/message/message.ts#L32) +[src/message/message.ts:32](https://github.com/paztek/llobotomy-azure/blob/9df98ed/src/message/message.ts#L32) ___ @@ -50,7 +50,7 @@ ___ #### Defined in -[src/message/message.ts:16](https://github.com/paztek/llobotomy-azure/blob/26afba8/src/message/message.ts#L16) +[src/message/message.ts:16](https://github.com/paztek/llobotomy-azure/blob/9df98ed/src/message/message.ts#L16) ___ @@ -60,7 +60,7 @@ ___ #### Defined in -[src/message/message.ts:20](https://github.com/paztek/llobotomy-azure/blob/26afba8/src/message/message.ts#L20) +[src/message/message.ts:20](https://github.com/paztek/llobotomy-azure/blob/9df98ed/src/message/message.ts#L20) ___ @@ -70,7 +70,7 @@ ___ #### Defined in -[src/message/message.ts:25](https://github.com/paztek/llobotomy-azure/blob/26afba8/src/message/message.ts#L25) +[src/message/message.ts:25](https://github.com/paztek/llobotomy-azure/blob/9df98ed/src/message/message.ts#L25) ___ @@ -80,7 +80,7 @@ ___ #### Defined in -[src/message/message.ts:12](https://github.com/paztek/llobotomy-azure/blob/26afba8/src/message/message.ts#L12) +[src/message/message.ts:12](https://github.com/paztek/llobotomy-azure/blob/9df98ed/src/message/message.ts#L12) ___ @@ -90,7 +90,7 @@ ___ #### Defined in -[src/message/message.ts:18](https://github.com/paztek/llobotomy-azure/blob/26afba8/src/message/message.ts#L18) +[src/message/message.ts:18](https://github.com/paztek/llobotomy-azure/blob/9df98ed/src/message/message.ts#L18) ___ @@ -100,7 +100,7 @@ ___ #### Defined in -[src/message/message.ts:14](https://github.com/paztek/llobotomy-azure/blob/26afba8/src/message/message.ts#L14) +[src/message/message.ts:14](https://github.com/paztek/llobotomy-azure/blob/9df98ed/src/message/message.ts#L14) ___ @@ -110,7 +110,7 @@ ___ #### Defined in -[src/message/message.ts:23](https://github.com/paztek/llobotomy-azure/blob/26afba8/src/message/message.ts#L23) +[src/message/message.ts:23](https://github.com/paztek/llobotomy-azure/blob/9df98ed/src/message/message.ts#L23) ___ @@ -127,7 +127,7 @@ ___ #### Defined in -[src/message/message.ts:10](https://github.com/paztek/llobotomy-azure/blob/26afba8/src/message/message.ts#L10) +[src/message/message.ts:10](https://github.com/paztek/llobotomy-azure/blob/9df98ed/src/message/message.ts#L10) ## Functions @@ -147,7 +147,7 @@ m is ChatRequestMessage #### Defined in -[src/thread/thread.ts:262](https://github.com/paztek/llobotomy-azure/blob/26afba8/src/thread/thread.ts#L262) +[src/thread/thread.ts:261](https://github.com/paztek/llobotomy-azure/blob/9df98ed/src/thread/thread.ts#L261) ___ @@ -167,4 +167,4 @@ m is ChatResponseMessage #### Defined in -[src/thread/thread.ts:256](https://github.com/paztek/llobotomy-azure/blob/26afba8/src/thread/thread.ts#L256) +[src/thread/thread.ts:255](https://github.com/paztek/llobotomy-azure/blob/9df98ed/src/thread/thread.ts#L255) diff --git a/docs/classes/Assistant.md b/docs/classes/Assistant.md index 3db610a..315f1d0 100644 --- a/docs/classes/Assistant.md +++ b/docs/classes/Assistant.md @@ -34,7 +34,7 @@ #### Defined in -[src/assistant/assistant.ts:26](https://github.com/paztek/llobotomy-azure/blob/26afba8/src/assistant/assistant.ts#L26) +[src/assistant/assistant.ts:26](https://github.com/paztek/llobotomy-azure/blob/9df98ed/src/assistant/assistant.ts#L26) ## Properties @@ -44,7 +44,7 @@ #### Defined in -[src/assistant/assistant.ts:19](https://github.com/paztek/llobotomy-azure/blob/26afba8/src/assistant/assistant.ts#L19) +[src/assistant/assistant.ts:19](https://github.com/paztek/llobotomy-azure/blob/9df98ed/src/assistant/assistant.ts#L19) ___ @@ -54,7 +54,7 @@ ___ #### Defined in -[src/assistant/assistant.ts:23](https://github.com/paztek/llobotomy-azure/blob/26afba8/src/assistant/assistant.ts#L23) +[src/assistant/assistant.ts:23](https://github.com/paztek/llobotomy-azure/blob/9df98ed/src/assistant/assistant.ts#L23) ___ @@ -64,7 +64,7 @@ ___ #### Defined in -[src/assistant/assistant.ts:21](https://github.com/paztek/llobotomy-azure/blob/26afba8/src/assistant/assistant.ts#L21) +[src/assistant/assistant.ts:21](https://github.com/paztek/llobotomy-azure/blob/9df98ed/src/assistant/assistant.ts#L21) ___ @@ -74,7 +74,7 @@ ___ #### Defined in -[src/assistant/assistant.ts:22](https://github.com/paztek/llobotomy-azure/blob/26afba8/src/assistant/assistant.ts#L22) +[src/assistant/assistant.ts:22](https://github.com/paztek/llobotomy-azure/blob/9df98ed/src/assistant/assistant.ts#L22) ___ @@ -84,7 +84,7 @@ ___ #### Defined in -[src/assistant/assistant.ts:24](https://github.com/paztek/llobotomy-azure/blob/26afba8/src/assistant/assistant.ts#L24) +[src/assistant/assistant.ts:24](https://github.com/paztek/llobotomy-azure/blob/9df98ed/src/assistant/assistant.ts#L24) ## Methods @@ -104,4 +104,4 @@ ___ #### Defined in -[src/assistant/assistant.ts:34](https://github.com/paztek/llobotomy-azure/blob/26afba8/src/assistant/assistant.ts#L34) +[src/assistant/assistant.ts:34](https://github.com/paztek/llobotomy-azure/blob/9df98ed/src/assistant/assistant.ts#L34) diff --git a/docs/classes/RequiredAction.md b/docs/classes/RequiredAction.md index 3d2ec54..21a0f30 100644 --- a/docs/classes/RequiredAction.md +++ b/docs/classes/RequiredAction.md @@ -67,7 +67,7 @@ EventEmitter.constructor #### Defined in -[src/thread/thread.ts:241](https://github.com/paztek/llobotomy-azure/blob/26afba8/src/thread/thread.ts#L241) +[src/thread/thread.ts:240](https://github.com/paztek/llobotomy-azure/blob/9df98ed/src/thread/thread.ts#L240) ## Properties @@ -77,7 +77,7 @@ EventEmitter.constructor #### Defined in -[src/thread/thread.ts:241](https://github.com/paztek/llobotomy-azure/blob/26afba8/src/thread/thread.ts#L241) +[src/thread/thread.ts:240](https://github.com/paztek/llobotomy-azure/blob/9df98ed/src/thread/thread.ts#L240) ___ @@ -934,7 +934,7 @@ ___ #### Defined in -[src/thread/thread.ts:245](https://github.com/paztek/llobotomy-azure/blob/26afba8/src/thread/thread.ts#L245) +[src/thread/thread.ts:244](https://github.com/paztek/llobotomy-azure/blob/9df98ed/src/thread/thread.ts#L244) ___ diff --git a/docs/classes/Thread.md b/docs/classes/Thread.md index 67ba238..b2275ee 100644 --- a/docs/classes/Thread.md +++ b/docs/classes/Thread.md @@ -18,6 +18,7 @@ - [\_stream](Thread.md#_stream) - [converter](Thread.md#converter) +- [id](Thread.md#id) - [messages](Thread.md#messages) - [toolEmulator](Thread.md#toolemulator) - [captureRejectionSymbol](Thread.md#capturerejectionsymbol) @@ -66,12 +67,13 @@ ### constructor -• **new Thread**(`messages?`) +• **new Thread**(`id`, `messages?`) #### Parameters | Name | Type | Default value | | :------ | :------ | :------ | +| `id` | `string` | `undefined` | | `messages` | [`ChatMessage`](../README.md#chatmessage)[] | `[]` | #### Overrides @@ -80,7 +82,7 @@ EventEmitter.constructor #### Defined in -[src/thread/thread.ts:24](https://github.com/paztek/llobotomy-azure/blob/26afba8/src/thread/thread.ts#L24) +[src/thread/thread.ts:24](https://github.com/paztek/llobotomy-azure/blob/9df98ed/src/thread/thread.ts#L24) ## Properties @@ -90,7 +92,7 @@ EventEmitter.constructor #### Defined in -[src/thread/thread.ts:20](https://github.com/paztek/llobotomy-azure/blob/26afba8/src/thread/thread.ts#L20) +[src/thread/thread.ts:20](https://github.com/paztek/llobotomy-azure/blob/9df98ed/src/thread/thread.ts#L20) ___ @@ -100,7 +102,17 @@ ___ #### Defined in -[src/thread/thread.ts:21](https://github.com/paztek/llobotomy-azure/blob/26afba8/src/thread/thread.ts#L21) +[src/thread/thread.ts:21](https://github.com/paztek/llobotomy-azure/blob/9df98ed/src/thread/thread.ts#L21) + +___ + +### id + +• `Readonly` **id**: `string` + +#### Defined in + +[src/thread/thread.ts:25](https://github.com/paztek/llobotomy-azure/blob/9df98ed/src/thread/thread.ts#L25) ___ @@ -110,7 +122,7 @@ ___ #### Defined in -[src/thread/thread.ts:24](https://github.com/paztek/llobotomy-azure/blob/26afba8/src/thread/thread.ts#L24) +[src/thread/thread.ts:26](https://github.com/paztek/llobotomy-azure/blob/9df98ed/src/thread/thread.ts#L26) ___ @@ -120,7 +132,7 @@ ___ #### Defined in -[src/thread/thread.ts:22](https://github.com/paztek/llobotomy-azure/blob/26afba8/src/thread/thread.ts#L22) +[src/thread/thread.ts:22](https://github.com/paztek/llobotomy-azure/blob/9df98ed/src/thread/thread.ts#L22) ___ @@ -253,7 +265,7 @@ node_modules/@types/node/events.d.ts:395 #### Defined in -[src/thread/thread.ts:28](https://github.com/paztek/llobotomy-azure/blob/26afba8/src/thread/thread.ts#L28) +[src/thread/thread.ts:31](https://github.com/paztek/llobotomy-azure/blob/9df98ed/src/thread/thread.ts#L31) ## Methods @@ -330,7 +342,7 @@ ___ #### Defined in -[src/thread/thread.ts:36](https://github.com/paztek/llobotomy-azure/blob/26afba8/src/thread/thread.ts#L36) +[src/thread/thread.ts:35](https://github.com/paztek/llobotomy-azure/blob/9df98ed/src/thread/thread.ts#L35) ___ @@ -351,7 +363,7 @@ ___ #### Defined in -[src/thread/thread.ts:184](https://github.com/paztek/llobotomy-azure/blob/26afba8/src/thread/thread.ts#L184) +[src/thread/thread.ts:183](https://github.com/paztek/llobotomy-azure/blob/9df98ed/src/thread/thread.ts#L183) ___ @@ -371,7 +383,7 @@ ___ #### Defined in -[src/thread/thread.ts:215](https://github.com/paztek/llobotomy-azure/blob/26afba8/src/thread/thread.ts#L215) +[src/thread/thread.ts:214](https://github.com/paztek/llobotomy-azure/blob/9df98ed/src/thread/thread.ts#L214) ___ @@ -391,7 +403,7 @@ ___ #### Defined in -[src/thread/thread.ts:52](https://github.com/paztek/llobotomy-azure/blob/26afba8/src/thread/thread.ts#L52) +[src/thread/thread.ts:47](https://github.com/paztek/llobotomy-azure/blob/9df98ed/src/thread/thread.ts#L47) ___ @@ -479,7 +491,7 @@ ___ #### Defined in -[src/thread/thread.ts:229](https://github.com/paztek/llobotomy-azure/blob/26afba8/src/thread/thread.ts#L229) +[src/thread/thread.ts:228](https://github.com/paztek/llobotomy-azure/blob/9df98ed/src/thread/thread.ts#L228) ___ @@ -564,7 +576,7 @@ ___ #### Defined in -[src/thread/thread.ts:195](https://github.com/paztek/llobotomy-azure/blob/26afba8/src/thread/thread.ts#L195) +[src/thread/thread.ts:194](https://github.com/paztek/llobotomy-azure/blob/9df98ed/src/thread/thread.ts#L194) ___ @@ -1079,7 +1091,7 @@ ___ #### Defined in -[src/thread/thread.ts:40](https://github.com/paztek/llobotomy-azure/blob/26afba8/src/thread/thread.ts#L40) +[src/thread/thread.ts:39](https://github.com/paztek/llobotomy-azure/blob/9df98ed/src/thread/thread.ts#L39) ___ diff --git a/docs/interfaces/AssistantCreateParams.md b/docs/interfaces/AssistantCreateParams.md index 95dbd91..9980a94 100644 --- a/docs/interfaces/AssistantCreateParams.md +++ b/docs/interfaces/AssistantCreateParams.md @@ -20,7 +20,7 @@ #### Defined in -[src/assistant/assistant.ts:11](https://github.com/paztek/llobotomy-azure/blob/26afba8/src/assistant/assistant.ts#L11) +[src/assistant/assistant.ts:11](https://github.com/paztek/llobotomy-azure/blob/9df98ed/src/assistant/assistant.ts#L11) ___ @@ -30,7 +30,7 @@ ___ #### Defined in -[src/assistant/assistant.ts:14](https://github.com/paztek/llobotomy-azure/blob/26afba8/src/assistant/assistant.ts#L14) +[src/assistant/assistant.ts:14](https://github.com/paztek/llobotomy-azure/blob/9df98ed/src/assistant/assistant.ts#L14) ___ @@ -40,7 +40,7 @@ ___ #### Defined in -[src/assistant/assistant.ts:12](https://github.com/paztek/llobotomy-azure/blob/26afba8/src/assistant/assistant.ts#L12) +[src/assistant/assistant.ts:12](https://github.com/paztek/llobotomy-azure/blob/9df98ed/src/assistant/assistant.ts#L12) ___ @@ -50,7 +50,7 @@ ___ #### Defined in -[src/assistant/assistant.ts:13](https://github.com/paztek/llobotomy-azure/blob/26afba8/src/assistant/assistant.ts#L13) +[src/assistant/assistant.ts:13](https://github.com/paztek/llobotomy-azure/blob/9df98ed/src/assistant/assistant.ts#L13) ___ @@ -60,4 +60,4 @@ ___ #### Defined in -[src/assistant/assistant.ts:15](https://github.com/paztek/llobotomy-azure/blob/26afba8/src/assistant/assistant.ts#L15) +[src/assistant/assistant.ts:15](https://github.com/paztek/llobotomy-azure/blob/9df98ed/src/assistant/assistant.ts#L15) diff --git a/docs/interfaces/ToolOutput.md b/docs/interfaces/ToolOutput.md index 343c27a..be88641 100644 --- a/docs/interfaces/ToolOutput.md +++ b/docs/interfaces/ToolOutput.md @@ -18,7 +18,7 @@ #### Defined in -[src/thread/thread.ts:251](https://github.com/paztek/llobotomy-azure/blob/26afba8/src/thread/thread.ts#L251) +[src/thread/thread.ts:250](https://github.com/paztek/llobotomy-azure/blob/9df98ed/src/thread/thread.ts#L250) ___ @@ -28,7 +28,7 @@ ___ #### Defined in -[src/thread/thread.ts:253](https://github.com/paztek/llobotomy-azure/blob/26afba8/src/thread/thread.ts#L253) +[src/thread/thread.ts:252](https://github.com/paztek/llobotomy-azure/blob/9df98ed/src/thread/thread.ts#L252) ___ @@ -38,4 +38,4 @@ ___ #### Defined in -[src/thread/thread.ts:252](https://github.com/paztek/llobotomy-azure/blob/26afba8/src/thread/thread.ts#L252) +[src/thread/thread.ts:251](https://github.com/paztek/llobotomy-azure/blob/9df98ed/src/thread/thread.ts#L251) diff --git a/package.json b/package.json index cbc5100..a68d909 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "llobotomy-azure", - "version": "0.0.4", + "version": "0.0.5", "description": "Thin wrapper around the Azure OpenAI Chat Completions API + Tools / Function Calling to emulate the missing Assistants API", "main": "dist/index.js", "module": "dist/index.esm.js", diff --git a/src/thread/thread.spec.ts b/src/thread/thread.spec.ts index d8af277..462773d 100644 --- a/src/thread/thread.spec.ts +++ b/src/thread/thread.spec.ts @@ -17,8 +17,10 @@ describe('Thread', () => { const assistant = mock(); let emitSpy: jest.SpyInstance; + const id = 'my id'; + beforeEach(() => { - thread = new Thread(); + thread = new Thread(id); emitSpy = jest.spyOn(thread, 'emit'); }); diff --git a/src/thread/thread.ts b/src/thread/thread.ts index 52a370c..43765e0 100644 --- a/src/thread/thread.ts +++ b/src/thread/thread.ts @@ -21,15 +21,14 @@ export class Thread extends EventEmitter { private readonly converter = new ThreadMessageConverter(); private readonly toolEmulator = new ToolEmulator(); - constructor(private readonly messages: ChatMessage[] = []) { + constructor( + public readonly id: string, + private readonly messages: ChatMessage[] = [], + ) { super(); } get stream(): Readable | null { - if (!this._stream) { - return null; - } - return this._stream; } @@ -38,10 +37,6 @@ export class Thread extends EventEmitter { } async run(assistant: Assistant): Promise { - this._stream = new Readable({ - read: () => {}, - }); - try { return await this.doRun(assistant); } catch (e) { @@ -50,6 +45,10 @@ export class Thread extends EventEmitter { } private async doRun(assistant: Assistant): Promise { + this._stream = new Readable({ + read: () => {}, + }); + this.emitImmediate('in_progress'); const messages = this.converter.convert(this.messages); diff --git a/types/thread/thread.d.ts b/types/thread/thread.d.ts index fb2f8c7..fce0212 100644 --- a/types/thread/thread.d.ts +++ b/types/thread/thread.d.ts @@ -6,11 +6,12 @@ import { Readable } from 'stream'; import { Assistant } from '../assistant'; import type { ChatMessage, ChatRequestMessageWithMetadata } from '../message'; export declare class Thread extends EventEmitter { + readonly id: string; private readonly messages; private _stream; private readonly converter; private readonly toolEmulator; - constructor(messages?: ChatMessage[]); + constructor(id: string, messages?: ChatMessage[]); get stream(): Readable | null; addMessage(message: ChatRequestMessageWithMetadata): void; run(assistant: Assistant): Promise; diff --git a/types/thread/thread.d.ts.map b/types/thread/thread.d.ts.map index 38fb058..b5f35ee 100644 --- a/types/thread/thread.d.ts.map +++ b/types/thread/thread.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"thread.d.ts","sourceRoot":"","sources":["../../src/thread/thread.ts"],"names":[],"mappings":";;AAAA,OAAO,KAAK,EAER,uBAAuB,EACvB,kBAAkB,EAClB,mBAAmB,EAEtB,MAAM,eAAe,CAAC;AACvB,OAAO,YAAY,MAAM,QAAQ,CAAC;AAClC,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,KAAK,EACR,WAAW,EACX,8BAA8B,EAEjC,MAAM,YAAY,CAAC;AAIpB,qBAAa,MAAO,SAAQ,YAAY;IAKxB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAJrC,OAAO,CAAC,OAAO,CAAyB;IACxC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAgC;IAC1D,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAsB;gBAEtB,QAAQ,GAAE,WAAW,EAAO;IAIzD,IAAI,MAAM,IAAI,QAAQ,GAAG,IAAI,CAM5B;IAED,UAAU,CAAC,OAAO,EAAE,8BAA8B,GAAG,IAAI;IAInD,GAAG,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;YAYhC,KAAK;IAoInB,OAAO,CAAC,sBAAsB;YAWhB,0BAA0B;IAoBxC,OAAO,CAAC,YAAY;IAcpB,OAAO,CAAC,aAAa;CASxB;AAED,qBAAa,cAAe,SAAQ,YAAY;aAChB,SAAS,EAAE,uBAAuB,EAAE;gBAApC,SAAS,EAAE,uBAAuB,EAAE;IAIhE,iBAAiB,CAAC,WAAW,EAAE,UAAU,EAAE,GAAG,IAAI;CAGrD;AAED,MAAM,WAAW,UAAU;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,wBAAgB,qBAAqB,CACjC,CAAC,EAAE,kBAAkB,GAAG,mBAAmB,GAC5C,CAAC,IAAI,mBAAmB,CAE1B;AAED,wBAAgB,oBAAoB,CAChC,CAAC,EAAE,kBAAkB,GAAG,mBAAmB,GAC5C,CAAC,IAAI,kBAAkB,CAEzB"} \ No newline at end of file +{"version":3,"file":"thread.d.ts","sourceRoot":"","sources":["../../src/thread/thread.ts"],"names":[],"mappings":";;AAAA,OAAO,KAAK,EAER,uBAAuB,EACvB,kBAAkB,EAClB,mBAAmB,EAEtB,MAAM,eAAe,CAAC;AACvB,OAAO,YAAY,MAAM,QAAQ,CAAC;AAClC,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,KAAK,EACR,WAAW,EACX,8BAA8B,EAEjC,MAAM,YAAY,CAAC;AAIpB,qBAAa,MAAO,SAAQ,YAAY;aAMhB,EAAE,EAAE,MAAM;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAN7B,OAAO,CAAC,OAAO,CAAyB;IACxC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAgC;IAC1D,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAsB;gBAG/B,EAAE,EAAE,MAAM,EACT,QAAQ,GAAE,WAAW,EAAO;IAKjD,IAAI,MAAM,IAAI,QAAQ,GAAG,IAAI,CAE5B;IAED,UAAU,CAAC,OAAO,EAAE,8BAA8B,GAAG,IAAI;IAInD,GAAG,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;YAQhC,KAAK;IAwInB,OAAO,CAAC,sBAAsB;YAWhB,0BAA0B;IAoBxC,OAAO,CAAC,YAAY;IAcpB,OAAO,CAAC,aAAa;CASxB;AAED,qBAAa,cAAe,SAAQ,YAAY;aAChB,SAAS,EAAE,uBAAuB,EAAE;gBAApC,SAAS,EAAE,uBAAuB,EAAE;IAIhE,iBAAiB,CAAC,WAAW,EAAE,UAAU,EAAE,GAAG,IAAI;CAGrD;AAED,MAAM,WAAW,UAAU;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,wBAAgB,qBAAqB,CACjC,CAAC,EAAE,kBAAkB,GAAG,mBAAmB,GAC5C,CAAC,IAAI,mBAAmB,CAE1B;AAED,wBAAgB,oBAAoB,CAChC,CAAC,EAAE,kBAAkB,GAAG,mBAAmB,GAC5C,CAAC,IAAI,kBAAkB,CAEzB"} \ No newline at end of file