UNPKG

@copilotkit/runtime

Version:

<img src="https://github.com/user-attachments/assets/0a6b64d9-e193-4940-a3f6-60334ac34084" alt="banner" style="border-radius: 12px; border: 2px solid #d6d4fa;" />

180 lines (178 loc) • 6.75 kB
import "reflect-metadata"; import { convertJsonSchemaToZodSchema, randomId } from "@copilotkit/shared"; import { AIMessage, HumanMessage, SystemMessage, ToolMessage } from "@langchain/core/messages"; import { DynamicStructuredTool } from "@langchain/core/tools"; //#region src/service-adapters/langchain/utils.ts function convertMessageToLangChainMessage(message) { if (message.isTextMessage()) { if (message.role == "user") return new HumanMessage(message.content); else if (message.role == "assistant") return new AIMessage(message.content); else if (message.role === "system") return new SystemMessage(message.content); } else if (message.isActionExecutionMessage()) return new AIMessage({ content: "", tool_calls: [{ id: message.id, args: message.arguments, name: message.name }] }); else if (message.isResultMessage()) return new ToolMessage({ content: message.result, tool_call_id: message.actionExecutionId }); } function convertActionInputToLangChainTool(actionInput) { return new DynamicStructuredTool({ ...actionInput, name: actionInput.name, description: actionInput.description, schema: convertJsonSchemaToZodSchema(JSON.parse(actionInput.jsonSchema), true), func: async () => { return ""; } }); } function isAIMessage(message) { return Object.prototype.toString.call(message) === "[object AIMessage]"; } function isAIMessageChunk(message) { return Object.prototype.toString.call(message) === "[object AIMessageChunk]"; } function isBaseMessageChunk(message) { return Object.prototype.toString.call(message) === "[object BaseMessageChunk]"; } function maybeSendActionExecutionResultIsMessage(eventStream$, actionExecution) { if (actionExecution) eventStream$.sendActionExecutionResult({ actionExecutionId: actionExecution.id, actionName: actionExecution.name, result: "Sending a message" }); } async function streamLangChainResponse({ result, eventStream$, actionExecution }) { if (typeof result === "string") if (!actionExecution || actionExecution?.returnDirect) { eventStream$.sendActionExecutionResult({ actionExecutionId: actionExecution.id, actionName: actionExecution.name, result }); eventStream$.sendTextMessage(randomId(), result); } else eventStream$.sendActionExecutionResult({ actionExecutionId: actionExecution.id, actionName: actionExecution.name, result }); else if (isAIMessage(result)) { maybeSendActionExecutionResultIsMessage(eventStream$, actionExecution); if (result.content) eventStream$.sendTextMessage(randomId(), result.content); for (const toolCall of result.tool_calls) eventStream$.sendActionExecution({ actionExecutionId: toolCall.id || randomId(), actionName: toolCall.name, args: JSON.stringify(toolCall.args) }); } else if (isBaseMessageChunk(result)) { maybeSendActionExecutionResultIsMessage(eventStream$, actionExecution); if (result.lc_kwargs?.content) eventStream$.sendTextMessage(randomId(), result.content); if (result.lc_kwargs?.tool_calls) for (const toolCall of result.lc_kwargs?.tool_calls) eventStream$.sendActionExecution({ actionExecutionId: toolCall.id || randomId(), actionName: toolCall.name, args: JSON.stringify(toolCall.args) }); } else if (result && "getReader" in result) { maybeSendActionExecutionResultIsMessage(eventStream$, actionExecution); let reader = result.getReader(); let mode = null; let currentMessageId; const toolCallDetails = { name: null, id: null, index: null, prevIndex: null }; while (true) try { const { done, value } = await reader.read(); let toolCallName = void 0; let toolCallId = void 0; let toolCallArgs = void 0; let hasToolCall = false; let content = ""; if (value && value.content) content = Array.isArray(value.content) ? value.content[0]?.text ?? "" : value.content; if (isAIMessageChunk(value)) { let chunk = value.tool_call_chunks?.[0]; toolCallArgs = chunk?.args; hasToolCall = chunk != void 0; if (chunk?.name) toolCallDetails.name = chunk.name; if (chunk?.index != null) { toolCallDetails.index = chunk.index; if (toolCallDetails.prevIndex == null) toolCallDetails.prevIndex = chunk.index; } if (chunk?.id) toolCallDetails.id = chunk.index != null ? `${chunk.id}-idx-${chunk.index}` : chunk.id; toolCallName = toolCallDetails.name; toolCallId = toolCallDetails.id; } else if (isBaseMessageChunk(value)) { let chunk = value.additional_kwargs?.tool_calls?.[0]; toolCallName = chunk?.function?.name; toolCallId = chunk?.id; toolCallArgs = chunk?.function?.arguments; hasToolCall = chunk?.function != void 0; } if (mode === "message" && (toolCallId || done)) { mode = null; eventStream$.sendTextMessageEnd({ messageId: currentMessageId }); } else if (mode === "function" && (!hasToolCall || done)) { mode = null; eventStream$.sendActionExecutionEnd({ actionExecutionId: toolCallId }); } if (done) break; if (mode === null) { if (hasToolCall && toolCallId && toolCallName) { mode = "function"; eventStream$.sendActionExecutionStart({ actionExecutionId: toolCallId, actionName: toolCallName, parentMessageId: value.lc_kwargs?.id }); } else if (content) { mode = "message"; currentMessageId = randomId(); eventStream$.sendTextMessageStart({ messageId: currentMessageId }); } } if (mode === "message" && content) eventStream$.sendTextMessageContent({ messageId: currentMessageId, content }); else if (mode === "function" && toolCallArgs) { if (toolCallDetails.index !== toolCallDetails.prevIndex) { eventStream$.sendActionExecutionEnd({ actionExecutionId: toolCallId }); eventStream$.sendActionExecutionStart({ actionExecutionId: toolCallId, actionName: toolCallName, parentMessageId: value.lc_kwargs?.id }); toolCallDetails.prevIndex = toolCallDetails.index; } eventStream$.sendActionExecutionArgs({ actionExecutionId: toolCallId, args: toolCallArgs }); } } catch (error) { console.error("Error reading from stream", error); break; } } else if (actionExecution) eventStream$.sendActionExecutionResult({ actionExecutionId: actionExecution.id, actionName: actionExecution.name, result: encodeResult(result) }); else throw new Error("Invalid return type from LangChain function."); eventStream$.complete(); } function encodeResult(result) { if (result === void 0) return ""; else if (typeof result === "string") return result; else return JSON.stringify(result); } //#endregion export { convertActionInputToLangChainTool, convertMessageToLangChainMessage, streamLangChainResponse }; //# sourceMappingURL=utils.mjs.map