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;" />

215 lines (213 loc) 6.53 kB
require("reflect-metadata"); const require_runtime = require('../../_virtual/_rolldown/runtime.cjs'); let _copilotkit_shared = require("@copilotkit/shared"); let _ag_ui_client = require("@ag-ui/client"); //#region src/agent/converters/aisdk.ts /** * Converts an AI SDK `fullStream` into AG-UI `BaseEvent` objects. * * This is a pure converter — it does NOT emit lifecycle events * (RUN_STARTED / RUN_FINISHED / RUN_ERROR). The caller (Agent class) * is responsible for those. * * Terminal stream events (finish, error, abort) cause the generator to * return so the caller can handle lifecycle appropriately. */ async function* convertAISDKStream(fullStream, abortSignal) { let messageId = (0, _copilotkit_shared.randomUUID)(); let reasoningMessageId = (0, _copilotkit_shared.randomUUID)(); let isInReasoning = false; const toolCallStates = /* @__PURE__ */ new Map(); const ensureToolCallState = (toolCallId) => { let state = toolCallStates.get(toolCallId); if (!state) { state = { started: false, hasArgsDelta: false, ended: false }; toolCallStates.set(toolCallId, state); } return state; }; /** * Auto-close an open reasoning lifecycle. * Some AI SDK providers (notably @ai-sdk/anthropic) never emit "reasoning-end", * which leaves downstream state machines stuck. This helper emits the * missing REASONING_MESSAGE_END + REASONING_END events so the stream * can transition to text, tool-call, or finish phases. */ function* closeReasoningIfOpen() { if (!isInReasoning) return; isInReasoning = false; yield { type: _ag_ui_client.EventType.REASONING_MESSAGE_END, messageId: reasoningMessageId }; yield { type: _ag_ui_client.EventType.REASONING_END, messageId: reasoningMessageId }; } try { for await (const part of fullStream) { const p = part; if (p.type !== "reasoning-delta") yield* closeReasoningIfOpen(); switch (p.type) { case "abort": return; case "reasoning-start": { const providedId = "id" in p ? p.id : void 0; reasoningMessageId = providedId && providedId !== "0" ? providedId : (0, _copilotkit_shared.randomUUID)(); yield { type: _ag_ui_client.EventType.REASONING_START, messageId: reasoningMessageId }; yield { type: _ag_ui_client.EventType.REASONING_MESSAGE_START, messageId: reasoningMessageId, role: "reasoning" }; isInReasoning = true; break; } case "reasoning-delta": { const delta = p.text ?? ""; if (!delta) break; yield { type: _ag_ui_client.EventType.REASONING_MESSAGE_CONTENT, messageId: reasoningMessageId, delta }; break; } case "reasoning-end": break; case "tool-input-start": { const toolCallId = p.id; const state = ensureToolCallState(toolCallId); state.toolName = p.toolName; if (!state.started) { state.started = true; yield { type: _ag_ui_client.EventType.TOOL_CALL_START, parentMessageId: messageId, toolCallId, toolCallName: p.toolName }; } break; } case "tool-input-delta": { const toolCallId = p.id; const state = ensureToolCallState(toolCallId); state.hasArgsDelta = true; yield { type: _ag_ui_client.EventType.TOOL_CALL_ARGS, toolCallId, delta: p.delta }; break; } case "tool-input-end": break; case "text-start": { const providedId = "id" in p ? p.id : void 0; messageId = providedId && providedId !== "0" ? providedId : (0, _copilotkit_shared.randomUUID)(); break; } case "text-delta": { const textDelta = "text" in p ? p.text : ""; yield { type: _ag_ui_client.EventType.TEXT_MESSAGE_CHUNK, role: "assistant", messageId, delta: textDelta }; break; } case "tool-call": { const toolCallId = p.toolCallId; const state = ensureToolCallState(toolCallId); state.toolName = p.toolName ?? state.toolName; if (!state.started) { state.started = true; yield { type: _ag_ui_client.EventType.TOOL_CALL_START, parentMessageId: messageId, toolCallId, toolCallName: p.toolName }; } if (!state.hasArgsDelta && "input" in p && p.input !== void 0) { let serializedInput = ""; if (typeof p.input === "string") serializedInput = p.input; else try { serializedInput = JSON.stringify(p.input); } catch { serializedInput = String(p.input); } if (serializedInput.length > 0) { yield { type: _ag_ui_client.EventType.TOOL_CALL_ARGS, toolCallId, delta: serializedInput }; state.hasArgsDelta = true; } } if (!state.ended) { state.ended = true; yield { type: _ag_ui_client.EventType.TOOL_CALL_END, toolCallId }; } break; } case "tool-result": { const toolResult = "output" in p ? p.output : "result" in p ? p.result : null; const toolName = "toolName" in p ? p.toolName : ""; toolCallStates.delete(p.toolCallId); if (toolName === "AGUISendStateSnapshot" && toolResult && typeof toolResult === "object") { const snapshot = toolResult.snapshot; if (snapshot !== void 0) yield { type: _ag_ui_client.EventType.STATE_SNAPSHOT, snapshot }; } else if (toolName === "AGUISendStateDelta" && toolResult && typeof toolResult === "object") { const delta = toolResult.delta; if (delta !== void 0) yield { type: _ag_ui_client.EventType.STATE_DELTA, delta }; } let serializedResult; try { serializedResult = JSON.stringify(toolResult); } catch { serializedResult = `[Unserializable tool result from ${toolName || "unknown tool"}]`; } yield { type: _ag_ui_client.EventType.TOOL_CALL_RESULT, role: "tool", messageId: (0, _copilotkit_shared.randomUUID)(), toolCallId: p.toolCallId, content: serializedResult }; break; } case "finish": return; case "error": { if (abortSignal.aborted) return; const err = p.error ?? p.message ?? p.cause; if (err instanceof Error) throw err; throw new Error(typeof err === "string" ? err : `AI SDK stream error: ${JSON.stringify(p)}`); } default: break; } } } finally { yield* closeReasoningIfOpen(); } } //#endregion exports.convertAISDKStream = convertAISDKStream; //# sourceMappingURL=aisdk.cjs.map