@cloudbase/agent-adapter-yuanqi 1.0.1-alpha.12 → 1.0.1-alpha.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +14 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +14 -3
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -82,6 +82,7 @@ async function* processYuanqiStream(stream, context) {
|
|
|
82
82
|
if (!delta) continue;
|
|
83
83
|
if (delta.content) {
|
|
84
84
|
if (reasoningState.hasStarted) {
|
|
85
|
+
reasoningState.hasStarted = false;
|
|
85
86
|
yield {
|
|
86
87
|
type: import_client.EventType.THINKING_TEXT_MESSAGE_END,
|
|
87
88
|
threadId,
|
|
@@ -280,6 +281,7 @@ var YuanqiAgent = class extends import_client2.AbstractAgent {
|
|
|
280
281
|
message: error instanceof Error ? error.message : String(error),
|
|
281
282
|
code: error instanceof Error ? error.name : "UNKNOWN_ERROR"
|
|
282
283
|
});
|
|
284
|
+
} finally {
|
|
283
285
|
subscriber.complete();
|
|
284
286
|
}
|
|
285
287
|
}
|
|
@@ -296,12 +298,21 @@ function convertMessagesToOpenAI(messages, systemPrompt) {
|
|
|
296
298
|
if (msg.role === "user") {
|
|
297
299
|
openaiMessages.push({
|
|
298
300
|
role: "user",
|
|
299
|
-
content: typeof msg.content === "string" ? msg.content :
|
|
301
|
+
content: typeof msg.content === "string" ? [{ type: "text", text: msg.content }] : msg.content.map((item) => {
|
|
302
|
+
if (item.type === "text") {
|
|
303
|
+
return { type: "text", text: item.text };
|
|
304
|
+
} else {
|
|
305
|
+
return {
|
|
306
|
+
type: "image_url",
|
|
307
|
+
image_url: { url: item.url || "" }
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
})
|
|
300
311
|
});
|
|
301
312
|
} else if (msg.role === "assistant") {
|
|
302
313
|
openaiMessages.push({
|
|
303
314
|
role: "assistant",
|
|
304
|
-
content:
|
|
315
|
+
content: msg.content ? [{ type: "text", text: msg.content }] : [],
|
|
305
316
|
tool_calls: msg.toolCalls?.map((tc) => ({
|
|
306
317
|
id: tc.id,
|
|
307
318
|
type: "function",
|
|
@@ -315,7 +326,7 @@ function convertMessagesToOpenAI(messages, systemPrompt) {
|
|
|
315
326
|
openaiMessages.push({
|
|
316
327
|
role: "tool",
|
|
317
328
|
tool_call_id: msg.toolCallId,
|
|
318
|
-
content:
|
|
329
|
+
content: msg.content ? [{ type: "text", text: msg.content }] : []
|
|
319
330
|
});
|
|
320
331
|
}
|
|
321
332
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/agent.ts","../src/utils.ts","../src/stream.ts"],"sourcesContent":["export * from \"./agent\";\n\nexport * from \"./utils\";\n","import {\n RunAgentInput,\n Message,\n AbstractAgent,\n AgentConfig,\n BaseEvent,\n EventType,\n} from \"@ag-ui/client\";\n// import tcb from \"@cloudbase/node-sdk\";\nimport OpenAI from \"openai\";\nimport { randomUUID } from \"crypto\";\nimport { camelToSnakeKeys } from \"./utils\";\nimport { processYuanqiStream } from \"./stream\";\nimport { Observable } from \"rxjs\";\n\nexport interface YuanqiConfig {\n request?: {\n baseUrl?: string;\n body?: Partial<YuanqiChatRequest>;\n headers?: Record<string, string>;\n };\n appId?: string;\n appKey?: string;\n}\n\nexport type ChatMessage = OpenAI.Chat.Completions.ChatCompletionMessageParam;\n\nexport interface YuanqiChatRequest {\n assistantId: string;\n userId: string;\n messages: ChatMessage[];\n stream?: boolean;\n customVariables?: Record<string, string>;\n version?: number;\n chatType?: \"published\" | \"preview\";\n [key: string]: any;\n}\n\nexport class YuanqiAgent extends AbstractAgent {\n protected yuanqiConfig: YuanqiConfig;\n private finalAppId: string;\n private model: OpenAI;\n constructor(config: AgentConfig & { yuanqiConfig: YuanqiConfig }) {\n super(config);\n this.yuanqiConfig = config.yuanqiConfig;\n this.model = new OpenAI({\n apiKey: \"\",\n baseURL:\n this.yuanqiConfig.request?.baseUrl ||\n \"https://yuanqi.tencent.com/openapi/v1/agent\",\n });\n this.finalAppId =\n this.yuanqiConfig.appId ||\n this.yuanqiConfig.request?.body?.assistantId ||\n process.env.YUANQI_APP_ID ||\n \"\";\n }\n\n generateRequestBody({\n messages,\n input,\n }: {\n messages: ChatMessage[];\n input: RunAgentInput;\n }): YuanqiChatRequest {\n const { state, forwardedProps } = input;\n const requestBody: YuanqiChatRequest = {\n stream: true,\n ...(this.yuanqiConfig.request?.body || {}),\n ...(forwardedProps || {}),\n\n assistantId: this.finalAppId,\n userId:\n state?.__request_context__?.id ||\n forwardedProps?.userId ||\n randomUUID(),\n messages,\n };\n return requestBody;\n }\n\n run(input: RunAgentInput): Observable<BaseEvent> {\n return new Observable<BaseEvent>((subscriber) => {\n this._run(subscriber, input);\n });\n }\n\n private async _run(subscriber: any, input: RunAgentInput): Promise<void> {\n try {\n const { messages, runId, threadId, forwardedProps } = input;\n\n subscriber.next({\n type: EventType.RUN_STARTED,\n threadId,\n runId,\n });\n\n // if (!getCloudbaseEnvId()) {\n // throw new Error(\n // \"CLOUDBASE_ENV_ID is required, check your env variables or config passed with the adapter\"\n // );\n // }\n if (!this.finalAppId) {\n throw new Error(\n \"YUANQI_APP_ID is required, check your env variables or config passed with the adapter\"\n );\n }\n if (!this.yuanqiConfig.appKey && !process.env.YUANQI_APP_KEY) {\n throw new Error(\n \"YUANQI_APP_KEY is required, check your env variables or config passed with the adapter\"\n );\n }\n\n // const tcbClient = tcb.init({\n // env: getCloudbaseEnvId(),\n // });\n\n const openai = this.model as OpenAI;\n\n // Convert AGUI messages to OpenAI format\n const openaiMessages = convertMessagesToOpenAI(messages);\n\n const body = this.generateRequestBody({\n messages: openaiMessages,\n input,\n });\n\n const stream = await openai.chat.completions.create(\n {\n stream: true,\n messages: [],\n model: \"\",\n },\n {\n body: camelToSnakeKeys(body),\n headers: {\n ...this.yuanqiConfig.request?.headers,\n Authorization: `Bearer ${\n this.yuanqiConfig.appKey || process.env.YUANQI_APP_KEY\n }`,\n },\n }\n );\n\n // Process stream and emit AGUI events\n const messageId = `msg_${Date.now()}`;\n const context = { threadId, runId, messageId };\n\n for await (const event of processYuanqiStream(stream, context)) {\n subscriber.next(event);\n }\n } catch (error: any) {\n if (error instanceof Error) {\n console.error(`Error ${error.name}: ${error.message}`);\n } else {\n console.error(JSON.stringify(error));\n }\n subscriber.next({\n type: EventType.RUN_ERROR,\n message: error instanceof Error ? error.message : String(error),\n code: error instanceof Error ? error.name : \"UNKNOWN_ERROR\",\n } as any);\n subscriber.complete();\n }\n }\n}\n\nfunction getCloudbaseEnvId() {\n if (!!process.env.CBR_ENV_ID) {\n return process.env.CBR_ENV_ID;\n } else if (!!process.env.SCF_NAMESPACE) {\n return process.env.SCF_NAMESPACE;\n } else {\n return process.env.CLOUDBASE_ENV_ID || \"\";\n }\n}\n\n/**\n * Convert AGUI messages to OpenAI chat completion format\n */\nexport function convertMessagesToOpenAI(\n messages: Message[],\n systemPrompt?: string\n): OpenAI.Chat.ChatCompletionMessageParam[] {\n const openaiMessages: OpenAI.Chat.ChatCompletionMessageParam[] = [];\n\n // Add system prompt if provided\n if (systemPrompt) {\n openaiMessages.push({\n role: \"system\",\n content: systemPrompt,\n });\n }\n\n // Convert messages\n for (const msg of messages) {\n if (msg.role === \"user\") {\n openaiMessages.push({\n role: \"user\",\n content:\n typeof msg.content === \"string\"\n ? msg.content\n : JSON.stringify(msg.content),\n });\n } else if (msg.role === \"assistant\") {\n openaiMessages.push({\n role: \"assistant\",\n content:\n typeof msg.content === \"string\"\n ? msg.content\n : JSON.stringify(msg.content) || \"\",\n tool_calls: msg.toolCalls?.map((tc: any) => ({\n id: tc.id,\n type: \"function\" as const,\n function: {\n name: tc.function.name,\n arguments: tc.function.arguments,\n },\n })),\n });\n } else if (msg.role === \"tool\") {\n openaiMessages.push({\n role: \"tool\",\n tool_call_id: msg.toolCallId!,\n content:\n typeof msg.content === \"string\"\n ? msg.content\n : JSON.stringify(msg.content),\n });\n }\n }\n\n return openaiMessages;\n}\n","/**\n * 将小驼峰字符串转换为下划线格式\n * 例如: \"userName\" -> \"user_name\"\n */\nfunction camelToSnake(str: string): string {\n return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);\n}\n\n/**\n * 递归地将对象的所有小驼峰属性名转换为下划线格式\n */\nexport function camelToSnakeKeys<T>(obj: T): T {\n if (obj === null || obj === undefined) {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => camelToSnakeKeys(item)) as T;\n }\n\n if (typeof obj === \"object\") {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n const snakeKey = camelToSnake(key);\n result[snakeKey] = camelToSnakeKeys(value);\n }\n return result as T;\n }\n\n return obj;\n}\n","import OpenAI from \"openai\";\nimport { EventType } from \"@ag-ui/client\";\n\nexport interface StreamContext {\n threadId: string;\n runId: string;\n messageId: string;\n}\n\nexport interface StreamState {\n hasStarted: boolean;\n fullContent: string;\n toolCallsMap: Map<string, { name: string; args: string }>;\n}\n\nexport type Delta =\n OpenAI.Chat.Completions.ChatCompletionChunk[\"choices\"][number][\"delta\"] & {\n reasoning_content?: string;\n };\n\nexport async function* processYuanqiStream(\n stream: AsyncIterable<OpenAI.Chat.Completions.ChatCompletionChunk>,\n context: StreamContext\n) {\n const { threadId, runId, messageId } = context;\n const state: StreamState = {\n hasStarted: false,\n fullContent: \"\",\n toolCallsMap: new Map(),\n };\n const reasoningState: StreamState = {\n hasStarted: false,\n fullContent: \"\",\n toolCallsMap: new Map(),\n };\n\n for await (const chunk of stream) {\n const delta = chunk.choices[0]?.delta as Delta;\n if (!delta) continue;\n\n // Handle text content\n if (delta.content) {\n // End reasoning message if it was started\n if (reasoningState.hasStarted) {\n yield {\n type: EventType.THINKING_TEXT_MESSAGE_END,\n threadId,\n runId,\n messageId,\n };\n yield {\n type: EventType.THINKING_END,\n threadId,\n runId,\n messageId,\n };\n }\n\n if (!state.hasStarted) {\n yield {\n type: EventType.TEXT_MESSAGE_START,\n threadId,\n runId,\n messageId,\n role: \"assistant\",\n };\n state.hasStarted = true;\n }\n\n state.fullContent += delta.content;\n yield {\n type: EventType.TEXT_MESSAGE_CONTENT,\n threadId,\n runId,\n messageId,\n delta: delta.content,\n };\n }\n\n // Handle reasoning content\n if (delta.reasoning_content) {\n if (!reasoningState.hasStarted) {\n yield {\n type: EventType.THINKING_START,\n threadId,\n runId,\n messageId,\n };\n yield {\n type: EventType.THINKING_TEXT_MESSAGE_START,\n threadId,\n runId,\n messageId,\n role: \"assistant\",\n };\n reasoningState.hasStarted = true;\n }\n\n reasoningState.fullContent += delta.reasoning_content;\n yield {\n type: EventType.THINKING_TEXT_MESSAGE_CONTENT,\n threadId,\n runId,\n messageId,\n delta: delta.reasoning_content,\n };\n }\n\n // Handle tool calls\n if (delta.tool_calls) {\n for (const toolCall of delta.tool_calls) {\n const toolCallId = toolCall.id || `tool_${toolCall.index}`;\n\n if (toolCall.function?.name) {\n // Tool call start\n yield {\n type: EventType.TOOL_CALL_START,\n threadId,\n runId,\n toolCallId,\n toolCallName: toolCall.function.name,\n };\n\n state.toolCallsMap.set(toolCallId, {\n name: toolCall.function.name,\n args: toolCall.function.arguments || \"\",\n });\n } else if (toolCall.function?.arguments) {\n // Tool call arguments delta\n const existing = state.toolCallsMap.get(toolCallId);\n if (existing) {\n existing.args += toolCall.function.arguments;\n\n yield {\n type: EventType.TOOL_CALL_ARGS,\n threadId,\n runId,\n toolCallId,\n delta: toolCall.function.arguments,\n };\n }\n }\n }\n }\n }\n\n // Emit TEXT_MESSAGE_END if we had text content\n if (state.hasStarted) {\n yield {\n type: EventType.TEXT_MESSAGE_END,\n threadId,\n runId,\n messageId,\n };\n }\n\n // Emit TOOL_CALL_END for all tool calls\n for (const [toolCallId] of state.toolCallsMap) {\n yield {\n type: EventType.TOOL_CALL_END,\n threadId,\n runId,\n toolCallId,\n };\n }\n\n // Emit RUN_FINISHED\n yield {\n type: EventType.RUN_FINISHED,\n threadId,\n runId,\n };\n}\n"],"mappings":"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","names":["import_client","OpenAI"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/agent.ts","../src/utils.ts","../src/stream.ts"],"sourcesContent":["export * from \"./agent\";\n\nexport * from \"./utils\";\n","import {\n RunAgentInput,\n Message,\n AbstractAgent,\n AgentConfig,\n BaseEvent,\n EventType,\n} from \"@ag-ui/client\";\n// import tcb from \"@cloudbase/node-sdk\";\nimport OpenAI from \"openai\";\nimport { randomUUID } from \"crypto\";\nimport { camelToSnakeKeys } from \"./utils\";\nimport { processYuanqiStream } from \"./stream\";\nimport { Observable } from \"rxjs\";\n\nexport interface YuanqiConfig {\n request?: {\n baseUrl?: string;\n body?: Partial<YuanqiChatRequest>;\n headers?: Record<string, string>;\n };\n appId?: string;\n appKey?: string;\n}\n\nexport type ChatMessage = OpenAI.Chat.Completions.ChatCompletionMessageParam;\n\nexport interface YuanqiChatRequest {\n assistantId: string;\n userId: string;\n messages: ChatMessage[];\n stream?: boolean;\n customVariables?: Record<string, string>;\n version?: number;\n chatType?: \"published\" | \"preview\";\n [key: string]: any;\n}\n\nexport class YuanqiAgent extends AbstractAgent {\n protected yuanqiConfig: YuanqiConfig;\n private finalAppId: string;\n private model: OpenAI;\n constructor(config: AgentConfig & { yuanqiConfig: YuanqiConfig }) {\n super(config);\n this.yuanqiConfig = config.yuanqiConfig;\n this.model = new OpenAI({\n apiKey: \"\",\n baseURL:\n this.yuanqiConfig.request?.baseUrl ||\n \"https://yuanqi.tencent.com/openapi/v1/agent\",\n });\n this.finalAppId =\n this.yuanqiConfig.appId ||\n this.yuanqiConfig.request?.body?.assistantId ||\n process.env.YUANQI_APP_ID ||\n \"\";\n }\n\n generateRequestBody({\n messages,\n input,\n }: {\n messages: ChatMessage[];\n input: RunAgentInput;\n }): YuanqiChatRequest {\n const { state, forwardedProps } = input;\n const requestBody: YuanqiChatRequest = {\n stream: true,\n ...(this.yuanqiConfig.request?.body || {}),\n ...(forwardedProps || {}),\n\n assistantId: this.finalAppId,\n userId:\n state?.__request_context__?.id ||\n forwardedProps?.userId ||\n randomUUID(),\n messages,\n };\n return requestBody;\n }\n\n run(input: RunAgentInput): Observable<BaseEvent> {\n return new Observable<BaseEvent>((subscriber) => {\n this._run(subscriber, input);\n });\n }\n\n private async _run(subscriber: any, input: RunAgentInput): Promise<void> {\n try {\n const { messages, runId, threadId, forwardedProps } = input;\n\n subscriber.next({\n type: EventType.RUN_STARTED,\n threadId,\n runId,\n });\n\n // if (!getCloudbaseEnvId()) {\n // throw new Error(\n // \"CLOUDBASE_ENV_ID is required, check your env variables or config passed with the adapter\"\n // );\n // }\n if (!this.finalAppId) {\n throw new Error(\n \"YUANQI_APP_ID is required, check your env variables or config passed with the adapter\"\n );\n }\n if (!this.yuanqiConfig.appKey && !process.env.YUANQI_APP_KEY) {\n throw new Error(\n \"YUANQI_APP_KEY is required, check your env variables or config passed with the adapter\"\n );\n }\n\n // const tcbClient = tcb.init({\n // env: getCloudbaseEnvId(),\n // });\n\n const openai = this.model as OpenAI;\n\n // Convert AGUI messages to OpenAI format\n const openaiMessages = convertMessagesToOpenAI(messages);\n\n const body = this.generateRequestBody({\n messages: openaiMessages,\n input,\n });\n\n const stream = await openai.chat.completions.create(\n {\n stream: true,\n messages: [],\n model: \"\",\n },\n {\n body: camelToSnakeKeys(body),\n headers: {\n ...this.yuanqiConfig.request?.headers,\n Authorization: `Bearer ${\n this.yuanqiConfig.appKey || process.env.YUANQI_APP_KEY\n }`,\n },\n }\n );\n\n // Process stream and emit AGUI events\n const messageId = `msg_${Date.now()}`;\n const context = { threadId, runId, messageId };\n\n for await (const event of processYuanqiStream(stream, context)) {\n subscriber.next(event);\n }\n } catch (error: any) {\n if (error instanceof Error) {\n console.error(`Error ${error.name}: ${error.message}`);\n } else {\n console.error(JSON.stringify(error));\n }\n subscriber.next({\n type: EventType.RUN_ERROR,\n message: error instanceof Error ? error.message : String(error),\n code: error instanceof Error ? error.name : \"UNKNOWN_ERROR\",\n } as any);\n } finally {\n subscriber.complete();\n }\n }\n}\n\nfunction getCloudbaseEnvId() {\n if (!!process.env.CBR_ENV_ID) {\n return process.env.CBR_ENV_ID;\n } else if (!!process.env.SCF_NAMESPACE) {\n return process.env.SCF_NAMESPACE;\n } else {\n return process.env.CLOUDBASE_ENV_ID || \"\";\n }\n}\n\n/**\n * Convert AGUI messages to OpenAI chat completion format\n */\nexport function convertMessagesToOpenAI(\n messages: Message[],\n systemPrompt?: string\n): OpenAI.Chat.ChatCompletionMessageParam[] {\n const openaiMessages: OpenAI.Chat.ChatCompletionMessageParam[] = [];\n\n // Add system prompt if provided\n if (systemPrompt) {\n openaiMessages.push({\n role: \"system\",\n content: systemPrompt,\n });\n }\n\n // Convert messages\n for (const msg of messages) {\n if (msg.role === \"user\") {\n openaiMessages.push({\n role: \"user\",\n content:\n typeof msg.content === \"string\"\n ? [{ type: \"text\", text: msg.content }]\n : msg.content.map((item) => {\n if (item.type === \"text\") {\n return { type: \"text\", text: item.text };\n } else {\n return {\n type: \"image_url\",\n image_url: { url: item.url || \"\" },\n };\n }\n }),\n });\n } else if (msg.role === \"assistant\") {\n openaiMessages.push({\n role: \"assistant\",\n content: msg.content ? [{ type: \"text\", text: msg.content }] : [],\n tool_calls: msg.toolCalls?.map((tc: any) => ({\n id: tc.id,\n type: \"function\" as const,\n function: {\n name: tc.function.name,\n arguments: tc.function.arguments,\n },\n })),\n });\n } else if (msg.role === \"tool\") {\n openaiMessages.push({\n role: \"tool\",\n tool_call_id: msg.toolCallId!,\n content: msg.content ? [{ type: \"text\", text: msg.content }] : [],\n });\n }\n }\n\n return openaiMessages;\n}\n","/**\n * 将小驼峰字符串转换为下划线格式\n * 例如: \"userName\" -> \"user_name\"\n */\nfunction camelToSnake(str: string): string {\n return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);\n}\n\n/**\n * 递归地将对象的所有小驼峰属性名转换为下划线格式\n */\nexport function camelToSnakeKeys<T>(obj: T): T {\n if (obj === null || obj === undefined) {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => camelToSnakeKeys(item)) as T;\n }\n\n if (typeof obj === \"object\") {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n const snakeKey = camelToSnake(key);\n result[snakeKey] = camelToSnakeKeys(value);\n }\n return result as T;\n }\n\n return obj;\n}\n","import OpenAI from \"openai\";\nimport { EventType } from \"@ag-ui/client\";\n\nexport interface StreamContext {\n threadId: string;\n runId: string;\n messageId: string;\n}\n\nexport interface StreamState {\n hasStarted: boolean;\n fullContent: string;\n toolCallsMap: Map<string, { name: string; args: string }>;\n}\n\nexport type Delta =\n OpenAI.Chat.Completions.ChatCompletionChunk[\"choices\"][number][\"delta\"] & {\n reasoning_content?: string;\n };\n\nexport async function* processYuanqiStream(\n stream: AsyncIterable<OpenAI.Chat.Completions.ChatCompletionChunk>,\n context: StreamContext\n) {\n const { threadId, runId, messageId } = context;\n const state: StreamState = {\n hasStarted: false,\n fullContent: \"\",\n toolCallsMap: new Map(),\n };\n const reasoningState: StreamState = {\n hasStarted: false,\n fullContent: \"\",\n toolCallsMap: new Map(),\n };\n\n for await (const chunk of stream) {\n const delta = chunk.choices[0]?.delta as Delta;\n if (!delta) continue;\n\n // Handle text content\n if (delta.content) {\n // End reasoning message if it was started\n if (reasoningState.hasStarted) {\n reasoningState.hasStarted = false;\n yield {\n type: EventType.THINKING_TEXT_MESSAGE_END,\n threadId,\n runId,\n messageId,\n };\n yield {\n type: EventType.THINKING_END,\n threadId,\n runId,\n messageId,\n };\n }\n\n if (!state.hasStarted) {\n yield {\n type: EventType.TEXT_MESSAGE_START,\n threadId,\n runId,\n messageId,\n role: \"assistant\",\n };\n state.hasStarted = true;\n }\n\n state.fullContent += delta.content;\n yield {\n type: EventType.TEXT_MESSAGE_CONTENT,\n threadId,\n runId,\n messageId,\n delta: delta.content,\n };\n }\n\n // Handle reasoning content\n if (delta.reasoning_content) {\n if (!reasoningState.hasStarted) {\n yield {\n type: EventType.THINKING_START,\n threadId,\n runId,\n messageId,\n };\n yield {\n type: EventType.THINKING_TEXT_MESSAGE_START,\n threadId,\n runId,\n messageId,\n role: \"assistant\",\n };\n reasoningState.hasStarted = true;\n }\n\n reasoningState.fullContent += delta.reasoning_content;\n yield {\n type: EventType.THINKING_TEXT_MESSAGE_CONTENT,\n threadId,\n runId,\n messageId,\n delta: delta.reasoning_content,\n };\n }\n\n // Handle tool calls\n if (delta.tool_calls) {\n for (const toolCall of delta.tool_calls) {\n const toolCallId = toolCall.id || `tool_${toolCall.index}`;\n\n if (toolCall.function?.name) {\n // Tool call start\n yield {\n type: EventType.TOOL_CALL_START,\n threadId,\n runId,\n toolCallId,\n toolCallName: toolCall.function.name,\n };\n\n state.toolCallsMap.set(toolCallId, {\n name: toolCall.function.name,\n args: toolCall.function.arguments || \"\",\n });\n } else if (toolCall.function?.arguments) {\n // Tool call arguments delta\n const existing = state.toolCallsMap.get(toolCallId);\n if (existing) {\n existing.args += toolCall.function.arguments;\n\n yield {\n type: EventType.TOOL_CALL_ARGS,\n threadId,\n runId,\n toolCallId,\n delta: toolCall.function.arguments,\n };\n }\n }\n }\n }\n }\n\n // Emit TEXT_MESSAGE_END if we had text content\n if (state.hasStarted) {\n yield {\n type: EventType.TEXT_MESSAGE_END,\n threadId,\n runId,\n messageId,\n };\n }\n\n // Emit TOOL_CALL_END for all tool calls\n for (const [toolCallId] of state.toolCallsMap) {\n yield {\n type: EventType.TOOL_CALL_END,\n threadId,\n runId,\n toolCallId,\n };\n }\n\n // Emit RUN_FINISHED\n yield {\n type: EventType.RUN_FINISHED,\n threadId,\n runId,\n };\n}\n"],"mappings":"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","names":["import_client","OpenAI"]}
|
package/dist/index.mjs
CHANGED
|
@@ -47,6 +47,7 @@ async function* processYuanqiStream(stream, context) {
|
|
|
47
47
|
if (!delta) continue;
|
|
48
48
|
if (delta.content) {
|
|
49
49
|
if (reasoningState.hasStarted) {
|
|
50
|
+
reasoningState.hasStarted = false;
|
|
50
51
|
yield {
|
|
51
52
|
type: EventType.THINKING_TEXT_MESSAGE_END,
|
|
52
53
|
threadId,
|
|
@@ -245,6 +246,7 @@ var YuanqiAgent = class extends AbstractAgent {
|
|
|
245
246
|
message: error instanceof Error ? error.message : String(error),
|
|
246
247
|
code: error instanceof Error ? error.name : "UNKNOWN_ERROR"
|
|
247
248
|
});
|
|
249
|
+
} finally {
|
|
248
250
|
subscriber.complete();
|
|
249
251
|
}
|
|
250
252
|
}
|
|
@@ -261,12 +263,21 @@ function convertMessagesToOpenAI(messages, systemPrompt) {
|
|
|
261
263
|
if (msg.role === "user") {
|
|
262
264
|
openaiMessages.push({
|
|
263
265
|
role: "user",
|
|
264
|
-
content: typeof msg.content === "string" ? msg.content :
|
|
266
|
+
content: typeof msg.content === "string" ? [{ type: "text", text: msg.content }] : msg.content.map((item) => {
|
|
267
|
+
if (item.type === "text") {
|
|
268
|
+
return { type: "text", text: item.text };
|
|
269
|
+
} else {
|
|
270
|
+
return {
|
|
271
|
+
type: "image_url",
|
|
272
|
+
image_url: { url: item.url || "" }
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
})
|
|
265
276
|
});
|
|
266
277
|
} else if (msg.role === "assistant") {
|
|
267
278
|
openaiMessages.push({
|
|
268
279
|
role: "assistant",
|
|
269
|
-
content:
|
|
280
|
+
content: msg.content ? [{ type: "text", text: msg.content }] : [],
|
|
270
281
|
tool_calls: msg.toolCalls?.map((tc) => ({
|
|
271
282
|
id: tc.id,
|
|
272
283
|
type: "function",
|
|
@@ -280,7 +291,7 @@ function convertMessagesToOpenAI(messages, systemPrompt) {
|
|
|
280
291
|
openaiMessages.push({
|
|
281
292
|
role: "tool",
|
|
282
293
|
tool_call_id: msg.toolCallId,
|
|
283
|
-
content:
|
|
294
|
+
content: msg.content ? [{ type: "text", text: msg.content }] : []
|
|
284
295
|
});
|
|
285
296
|
}
|
|
286
297
|
}
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/agent.ts","../src/utils.ts","../src/stream.ts"],"sourcesContent":["import {\n RunAgentInput,\n Message,\n AbstractAgent,\n AgentConfig,\n BaseEvent,\n EventType,\n} from \"@ag-ui/client\";\n// import tcb from \"@cloudbase/node-sdk\";\nimport OpenAI from \"openai\";\nimport { randomUUID } from \"crypto\";\nimport { camelToSnakeKeys } from \"./utils\";\nimport { processYuanqiStream } from \"./stream\";\nimport { Observable } from \"rxjs\";\n\nexport interface YuanqiConfig {\n request?: {\n baseUrl?: string;\n body?: Partial<YuanqiChatRequest>;\n headers?: Record<string, string>;\n };\n appId?: string;\n appKey?: string;\n}\n\nexport type ChatMessage = OpenAI.Chat.Completions.ChatCompletionMessageParam;\n\nexport interface YuanqiChatRequest {\n assistantId: string;\n userId: string;\n messages: ChatMessage[];\n stream?: boolean;\n customVariables?: Record<string, string>;\n version?: number;\n chatType?: \"published\" | \"preview\";\n [key: string]: any;\n}\n\nexport class YuanqiAgent extends AbstractAgent {\n protected yuanqiConfig: YuanqiConfig;\n private finalAppId: string;\n private model: OpenAI;\n constructor(config: AgentConfig & { yuanqiConfig: YuanqiConfig }) {\n super(config);\n this.yuanqiConfig = config.yuanqiConfig;\n this.model = new OpenAI({\n apiKey: \"\",\n baseURL:\n this.yuanqiConfig.request?.baseUrl ||\n \"https://yuanqi.tencent.com/openapi/v1/agent\",\n });\n this.finalAppId =\n this.yuanqiConfig.appId ||\n this.yuanqiConfig.request?.body?.assistantId ||\n process.env.YUANQI_APP_ID ||\n \"\";\n }\n\n generateRequestBody({\n messages,\n input,\n }: {\n messages: ChatMessage[];\n input: RunAgentInput;\n }): YuanqiChatRequest {\n const { state, forwardedProps } = input;\n const requestBody: YuanqiChatRequest = {\n stream: true,\n ...(this.yuanqiConfig.request?.body || {}),\n ...(forwardedProps || {}),\n\n assistantId: this.finalAppId,\n userId:\n state?.__request_context__?.id ||\n forwardedProps?.userId ||\n randomUUID(),\n messages,\n };\n return requestBody;\n }\n\n run(input: RunAgentInput): Observable<BaseEvent> {\n return new Observable<BaseEvent>((subscriber) => {\n this._run(subscriber, input);\n });\n }\n\n private async _run(subscriber: any, input: RunAgentInput): Promise<void> {\n try {\n const { messages, runId, threadId, forwardedProps } = input;\n\n subscriber.next({\n type: EventType.RUN_STARTED,\n threadId,\n runId,\n });\n\n // if (!getCloudbaseEnvId()) {\n // throw new Error(\n // \"CLOUDBASE_ENV_ID is required, check your env variables or config passed with the adapter\"\n // );\n // }\n if (!this.finalAppId) {\n throw new Error(\n \"YUANQI_APP_ID is required, check your env variables or config passed with the adapter\"\n );\n }\n if (!this.yuanqiConfig.appKey && !process.env.YUANQI_APP_KEY) {\n throw new Error(\n \"YUANQI_APP_KEY is required, check your env variables or config passed with the adapter\"\n );\n }\n\n // const tcbClient = tcb.init({\n // env: getCloudbaseEnvId(),\n // });\n\n const openai = this.model as OpenAI;\n\n // Convert AGUI messages to OpenAI format\n const openaiMessages = convertMessagesToOpenAI(messages);\n\n const body = this.generateRequestBody({\n messages: openaiMessages,\n input,\n });\n\n const stream = await openai.chat.completions.create(\n {\n stream: true,\n messages: [],\n model: \"\",\n },\n {\n body: camelToSnakeKeys(body),\n headers: {\n ...this.yuanqiConfig.request?.headers,\n Authorization: `Bearer ${\n this.yuanqiConfig.appKey || process.env.YUANQI_APP_KEY\n }`,\n },\n }\n );\n\n // Process stream and emit AGUI events\n const messageId = `msg_${Date.now()}`;\n const context = { threadId, runId, messageId };\n\n for await (const event of processYuanqiStream(stream, context)) {\n subscriber.next(event);\n }\n } catch (error: any) {\n if (error instanceof Error) {\n console.error(`Error ${error.name}: ${error.message}`);\n } else {\n console.error(JSON.stringify(error));\n }\n subscriber.next({\n type: EventType.RUN_ERROR,\n message: error instanceof Error ? error.message : String(error),\n code: error instanceof Error ? error.name : \"UNKNOWN_ERROR\",\n } as any);\n subscriber.complete();\n }\n }\n}\n\nfunction getCloudbaseEnvId() {\n if (!!process.env.CBR_ENV_ID) {\n return process.env.CBR_ENV_ID;\n } else if (!!process.env.SCF_NAMESPACE) {\n return process.env.SCF_NAMESPACE;\n } else {\n return process.env.CLOUDBASE_ENV_ID || \"\";\n }\n}\n\n/**\n * Convert AGUI messages to OpenAI chat completion format\n */\nexport function convertMessagesToOpenAI(\n messages: Message[],\n systemPrompt?: string\n): OpenAI.Chat.ChatCompletionMessageParam[] {\n const openaiMessages: OpenAI.Chat.ChatCompletionMessageParam[] = [];\n\n // Add system prompt if provided\n if (systemPrompt) {\n openaiMessages.push({\n role: \"system\",\n content: systemPrompt,\n });\n }\n\n // Convert messages\n for (const msg of messages) {\n if (msg.role === \"user\") {\n openaiMessages.push({\n role: \"user\",\n content:\n typeof msg.content === \"string\"\n ? msg.content\n : JSON.stringify(msg.content),\n });\n } else if (msg.role === \"assistant\") {\n openaiMessages.push({\n role: \"assistant\",\n content:\n typeof msg.content === \"string\"\n ? msg.content\n : JSON.stringify(msg.content) || \"\",\n tool_calls: msg.toolCalls?.map((tc: any) => ({\n id: tc.id,\n type: \"function\" as const,\n function: {\n name: tc.function.name,\n arguments: tc.function.arguments,\n },\n })),\n });\n } else if (msg.role === \"tool\") {\n openaiMessages.push({\n role: \"tool\",\n tool_call_id: msg.toolCallId!,\n content:\n typeof msg.content === \"string\"\n ? msg.content\n : JSON.stringify(msg.content),\n });\n }\n }\n\n return openaiMessages;\n}\n","/**\n * 将小驼峰字符串转换为下划线格式\n * 例如: \"userName\" -> \"user_name\"\n */\nfunction camelToSnake(str: string): string {\n return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);\n}\n\n/**\n * 递归地将对象的所有小驼峰属性名转换为下划线格式\n */\nexport function camelToSnakeKeys<T>(obj: T): T {\n if (obj === null || obj === undefined) {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => camelToSnakeKeys(item)) as T;\n }\n\n if (typeof obj === \"object\") {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n const snakeKey = camelToSnake(key);\n result[snakeKey] = camelToSnakeKeys(value);\n }\n return result as T;\n }\n\n return obj;\n}\n","import OpenAI from \"openai\";\nimport { EventType } from \"@ag-ui/client\";\n\nexport interface StreamContext {\n threadId: string;\n runId: string;\n messageId: string;\n}\n\nexport interface StreamState {\n hasStarted: boolean;\n fullContent: string;\n toolCallsMap: Map<string, { name: string; args: string }>;\n}\n\nexport type Delta =\n OpenAI.Chat.Completions.ChatCompletionChunk[\"choices\"][number][\"delta\"] & {\n reasoning_content?: string;\n };\n\nexport async function* processYuanqiStream(\n stream: AsyncIterable<OpenAI.Chat.Completions.ChatCompletionChunk>,\n context: StreamContext\n) {\n const { threadId, runId, messageId } = context;\n const state: StreamState = {\n hasStarted: false,\n fullContent: \"\",\n toolCallsMap: new Map(),\n };\n const reasoningState: StreamState = {\n hasStarted: false,\n fullContent: \"\",\n toolCallsMap: new Map(),\n };\n\n for await (const chunk of stream) {\n const delta = chunk.choices[0]?.delta as Delta;\n if (!delta) continue;\n\n // Handle text content\n if (delta.content) {\n // End reasoning message if it was started\n if (reasoningState.hasStarted) {\n yield {\n type: EventType.THINKING_TEXT_MESSAGE_END,\n threadId,\n runId,\n messageId,\n };\n yield {\n type: EventType.THINKING_END,\n threadId,\n runId,\n messageId,\n };\n }\n\n if (!state.hasStarted) {\n yield {\n type: EventType.TEXT_MESSAGE_START,\n threadId,\n runId,\n messageId,\n role: \"assistant\",\n };\n state.hasStarted = true;\n }\n\n state.fullContent += delta.content;\n yield {\n type: EventType.TEXT_MESSAGE_CONTENT,\n threadId,\n runId,\n messageId,\n delta: delta.content,\n };\n }\n\n // Handle reasoning content\n if (delta.reasoning_content) {\n if (!reasoningState.hasStarted) {\n yield {\n type: EventType.THINKING_START,\n threadId,\n runId,\n messageId,\n };\n yield {\n type: EventType.THINKING_TEXT_MESSAGE_START,\n threadId,\n runId,\n messageId,\n role: \"assistant\",\n };\n reasoningState.hasStarted = true;\n }\n\n reasoningState.fullContent += delta.reasoning_content;\n yield {\n type: EventType.THINKING_TEXT_MESSAGE_CONTENT,\n threadId,\n runId,\n messageId,\n delta: delta.reasoning_content,\n };\n }\n\n // Handle tool calls\n if (delta.tool_calls) {\n for (const toolCall of delta.tool_calls) {\n const toolCallId = toolCall.id || `tool_${toolCall.index}`;\n\n if (toolCall.function?.name) {\n // Tool call start\n yield {\n type: EventType.TOOL_CALL_START,\n threadId,\n runId,\n toolCallId,\n toolCallName: toolCall.function.name,\n };\n\n state.toolCallsMap.set(toolCallId, {\n name: toolCall.function.name,\n args: toolCall.function.arguments || \"\",\n });\n } else if (toolCall.function?.arguments) {\n // Tool call arguments delta\n const existing = state.toolCallsMap.get(toolCallId);\n if (existing) {\n existing.args += toolCall.function.arguments;\n\n yield {\n type: EventType.TOOL_CALL_ARGS,\n threadId,\n runId,\n toolCallId,\n delta: toolCall.function.arguments,\n };\n }\n }\n }\n }\n }\n\n // Emit TEXT_MESSAGE_END if we had text content\n if (state.hasStarted) {\n yield {\n type: EventType.TEXT_MESSAGE_END,\n threadId,\n runId,\n messageId,\n };\n }\n\n // Emit TOOL_CALL_END for all tool calls\n for (const [toolCallId] of state.toolCallsMap) {\n yield {\n type: EventType.TOOL_CALL_END,\n threadId,\n runId,\n toolCallId,\n };\n }\n\n // Emit RUN_FINISHED\n yield {\n type: EventType.RUN_FINISHED,\n threadId,\n runId,\n };\n}\n"],"mappings":"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","names":["EventType","EventType"]}
|
|
1
|
+
{"version":3,"sources":["../src/agent.ts","../src/utils.ts","../src/stream.ts"],"sourcesContent":["import {\n RunAgentInput,\n Message,\n AbstractAgent,\n AgentConfig,\n BaseEvent,\n EventType,\n} from \"@ag-ui/client\";\n// import tcb from \"@cloudbase/node-sdk\";\nimport OpenAI from \"openai\";\nimport { randomUUID } from \"crypto\";\nimport { camelToSnakeKeys } from \"./utils\";\nimport { processYuanqiStream } from \"./stream\";\nimport { Observable } from \"rxjs\";\n\nexport interface YuanqiConfig {\n request?: {\n baseUrl?: string;\n body?: Partial<YuanqiChatRequest>;\n headers?: Record<string, string>;\n };\n appId?: string;\n appKey?: string;\n}\n\nexport type ChatMessage = OpenAI.Chat.Completions.ChatCompletionMessageParam;\n\nexport interface YuanqiChatRequest {\n assistantId: string;\n userId: string;\n messages: ChatMessage[];\n stream?: boolean;\n customVariables?: Record<string, string>;\n version?: number;\n chatType?: \"published\" | \"preview\";\n [key: string]: any;\n}\n\nexport class YuanqiAgent extends AbstractAgent {\n protected yuanqiConfig: YuanqiConfig;\n private finalAppId: string;\n private model: OpenAI;\n constructor(config: AgentConfig & { yuanqiConfig: YuanqiConfig }) {\n super(config);\n this.yuanqiConfig = config.yuanqiConfig;\n this.model = new OpenAI({\n apiKey: \"\",\n baseURL:\n this.yuanqiConfig.request?.baseUrl ||\n \"https://yuanqi.tencent.com/openapi/v1/agent\",\n });\n this.finalAppId =\n this.yuanqiConfig.appId ||\n this.yuanqiConfig.request?.body?.assistantId ||\n process.env.YUANQI_APP_ID ||\n \"\";\n }\n\n generateRequestBody({\n messages,\n input,\n }: {\n messages: ChatMessage[];\n input: RunAgentInput;\n }): YuanqiChatRequest {\n const { state, forwardedProps } = input;\n const requestBody: YuanqiChatRequest = {\n stream: true,\n ...(this.yuanqiConfig.request?.body || {}),\n ...(forwardedProps || {}),\n\n assistantId: this.finalAppId,\n userId:\n state?.__request_context__?.id ||\n forwardedProps?.userId ||\n randomUUID(),\n messages,\n };\n return requestBody;\n }\n\n run(input: RunAgentInput): Observable<BaseEvent> {\n return new Observable<BaseEvent>((subscriber) => {\n this._run(subscriber, input);\n });\n }\n\n private async _run(subscriber: any, input: RunAgentInput): Promise<void> {\n try {\n const { messages, runId, threadId, forwardedProps } = input;\n\n subscriber.next({\n type: EventType.RUN_STARTED,\n threadId,\n runId,\n });\n\n // if (!getCloudbaseEnvId()) {\n // throw new Error(\n // \"CLOUDBASE_ENV_ID is required, check your env variables or config passed with the adapter\"\n // );\n // }\n if (!this.finalAppId) {\n throw new Error(\n \"YUANQI_APP_ID is required, check your env variables or config passed with the adapter\"\n );\n }\n if (!this.yuanqiConfig.appKey && !process.env.YUANQI_APP_KEY) {\n throw new Error(\n \"YUANQI_APP_KEY is required, check your env variables or config passed with the adapter\"\n );\n }\n\n // const tcbClient = tcb.init({\n // env: getCloudbaseEnvId(),\n // });\n\n const openai = this.model as OpenAI;\n\n // Convert AGUI messages to OpenAI format\n const openaiMessages = convertMessagesToOpenAI(messages);\n\n const body = this.generateRequestBody({\n messages: openaiMessages,\n input,\n });\n\n const stream = await openai.chat.completions.create(\n {\n stream: true,\n messages: [],\n model: \"\",\n },\n {\n body: camelToSnakeKeys(body),\n headers: {\n ...this.yuanqiConfig.request?.headers,\n Authorization: `Bearer ${\n this.yuanqiConfig.appKey || process.env.YUANQI_APP_KEY\n }`,\n },\n }\n );\n\n // Process stream and emit AGUI events\n const messageId = `msg_${Date.now()}`;\n const context = { threadId, runId, messageId };\n\n for await (const event of processYuanqiStream(stream, context)) {\n subscriber.next(event);\n }\n } catch (error: any) {\n if (error instanceof Error) {\n console.error(`Error ${error.name}: ${error.message}`);\n } else {\n console.error(JSON.stringify(error));\n }\n subscriber.next({\n type: EventType.RUN_ERROR,\n message: error instanceof Error ? error.message : String(error),\n code: error instanceof Error ? error.name : \"UNKNOWN_ERROR\",\n } as any);\n } finally {\n subscriber.complete();\n }\n }\n}\n\nfunction getCloudbaseEnvId() {\n if (!!process.env.CBR_ENV_ID) {\n return process.env.CBR_ENV_ID;\n } else if (!!process.env.SCF_NAMESPACE) {\n return process.env.SCF_NAMESPACE;\n } else {\n return process.env.CLOUDBASE_ENV_ID || \"\";\n }\n}\n\n/**\n * Convert AGUI messages to OpenAI chat completion format\n */\nexport function convertMessagesToOpenAI(\n messages: Message[],\n systemPrompt?: string\n): OpenAI.Chat.ChatCompletionMessageParam[] {\n const openaiMessages: OpenAI.Chat.ChatCompletionMessageParam[] = [];\n\n // Add system prompt if provided\n if (systemPrompt) {\n openaiMessages.push({\n role: \"system\",\n content: systemPrompt,\n });\n }\n\n // Convert messages\n for (const msg of messages) {\n if (msg.role === \"user\") {\n openaiMessages.push({\n role: \"user\",\n content:\n typeof msg.content === \"string\"\n ? [{ type: \"text\", text: msg.content }]\n : msg.content.map((item) => {\n if (item.type === \"text\") {\n return { type: \"text\", text: item.text };\n } else {\n return {\n type: \"image_url\",\n image_url: { url: item.url || \"\" },\n };\n }\n }),\n });\n } else if (msg.role === \"assistant\") {\n openaiMessages.push({\n role: \"assistant\",\n content: msg.content ? [{ type: \"text\", text: msg.content }] : [],\n tool_calls: msg.toolCalls?.map((tc: any) => ({\n id: tc.id,\n type: \"function\" as const,\n function: {\n name: tc.function.name,\n arguments: tc.function.arguments,\n },\n })),\n });\n } else if (msg.role === \"tool\") {\n openaiMessages.push({\n role: \"tool\",\n tool_call_id: msg.toolCallId!,\n content: msg.content ? [{ type: \"text\", text: msg.content }] : [],\n });\n }\n }\n\n return openaiMessages;\n}\n","/**\n * 将小驼峰字符串转换为下划线格式\n * 例如: \"userName\" -> \"user_name\"\n */\nfunction camelToSnake(str: string): string {\n return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);\n}\n\n/**\n * 递归地将对象的所有小驼峰属性名转换为下划线格式\n */\nexport function camelToSnakeKeys<T>(obj: T): T {\n if (obj === null || obj === undefined) {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => camelToSnakeKeys(item)) as T;\n }\n\n if (typeof obj === \"object\") {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n const snakeKey = camelToSnake(key);\n result[snakeKey] = camelToSnakeKeys(value);\n }\n return result as T;\n }\n\n return obj;\n}\n","import OpenAI from \"openai\";\nimport { EventType } from \"@ag-ui/client\";\n\nexport interface StreamContext {\n threadId: string;\n runId: string;\n messageId: string;\n}\n\nexport interface StreamState {\n hasStarted: boolean;\n fullContent: string;\n toolCallsMap: Map<string, { name: string; args: string }>;\n}\n\nexport type Delta =\n OpenAI.Chat.Completions.ChatCompletionChunk[\"choices\"][number][\"delta\"] & {\n reasoning_content?: string;\n };\n\nexport async function* processYuanqiStream(\n stream: AsyncIterable<OpenAI.Chat.Completions.ChatCompletionChunk>,\n context: StreamContext\n) {\n const { threadId, runId, messageId } = context;\n const state: StreamState = {\n hasStarted: false,\n fullContent: \"\",\n toolCallsMap: new Map(),\n };\n const reasoningState: StreamState = {\n hasStarted: false,\n fullContent: \"\",\n toolCallsMap: new Map(),\n };\n\n for await (const chunk of stream) {\n const delta = chunk.choices[0]?.delta as Delta;\n if (!delta) continue;\n\n // Handle text content\n if (delta.content) {\n // End reasoning message if it was started\n if (reasoningState.hasStarted) {\n reasoningState.hasStarted = false;\n yield {\n type: EventType.THINKING_TEXT_MESSAGE_END,\n threadId,\n runId,\n messageId,\n };\n yield {\n type: EventType.THINKING_END,\n threadId,\n runId,\n messageId,\n };\n }\n\n if (!state.hasStarted) {\n yield {\n type: EventType.TEXT_MESSAGE_START,\n threadId,\n runId,\n messageId,\n role: \"assistant\",\n };\n state.hasStarted = true;\n }\n\n state.fullContent += delta.content;\n yield {\n type: EventType.TEXT_MESSAGE_CONTENT,\n threadId,\n runId,\n messageId,\n delta: delta.content,\n };\n }\n\n // Handle reasoning content\n if (delta.reasoning_content) {\n if (!reasoningState.hasStarted) {\n yield {\n type: EventType.THINKING_START,\n threadId,\n runId,\n messageId,\n };\n yield {\n type: EventType.THINKING_TEXT_MESSAGE_START,\n threadId,\n runId,\n messageId,\n role: \"assistant\",\n };\n reasoningState.hasStarted = true;\n }\n\n reasoningState.fullContent += delta.reasoning_content;\n yield {\n type: EventType.THINKING_TEXT_MESSAGE_CONTENT,\n threadId,\n runId,\n messageId,\n delta: delta.reasoning_content,\n };\n }\n\n // Handle tool calls\n if (delta.tool_calls) {\n for (const toolCall of delta.tool_calls) {\n const toolCallId = toolCall.id || `tool_${toolCall.index}`;\n\n if (toolCall.function?.name) {\n // Tool call start\n yield {\n type: EventType.TOOL_CALL_START,\n threadId,\n runId,\n toolCallId,\n toolCallName: toolCall.function.name,\n };\n\n state.toolCallsMap.set(toolCallId, {\n name: toolCall.function.name,\n args: toolCall.function.arguments || \"\",\n });\n } else if (toolCall.function?.arguments) {\n // Tool call arguments delta\n const existing = state.toolCallsMap.get(toolCallId);\n if (existing) {\n existing.args += toolCall.function.arguments;\n\n yield {\n type: EventType.TOOL_CALL_ARGS,\n threadId,\n runId,\n toolCallId,\n delta: toolCall.function.arguments,\n };\n }\n }\n }\n }\n }\n\n // Emit TEXT_MESSAGE_END if we had text content\n if (state.hasStarted) {\n yield {\n type: EventType.TEXT_MESSAGE_END,\n threadId,\n runId,\n messageId,\n };\n }\n\n // Emit TOOL_CALL_END for all tool calls\n for (const [toolCallId] of state.toolCallsMap) {\n yield {\n type: EventType.TOOL_CALL_END,\n threadId,\n runId,\n toolCallId,\n };\n }\n\n // Emit RUN_FINISHED\n yield {\n type: EventType.RUN_FINISHED,\n threadId,\n runId,\n };\n}\n"],"mappings":"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","names":["EventType","EventType"]}
|