@better-agent/client 0.1.0-canary.6 → 0.2.0-beta.1
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/controller-B7G0xSYW.d.mts +365 -0
- package/dist/controller-B7G0xSYW.d.mts.map +1 -0
- package/dist/controller-xMlzSCc7.mjs +1342 -0
- package/dist/controller-xMlzSCc7.mjs.map +1 -0
- package/dist/index.d.mts +8 -262
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +240 -596
- package/dist/index.mjs.map +1 -1
- package/dist/preact/index.d.mts +21 -89
- package/dist/preact/index.d.mts.map +1 -1
- package/dist/preact/index.mjs +48 -122
- package/dist/preact/index.mjs.map +1 -1
- package/dist/react/index.d.mts +21 -89
- package/dist/react/index.d.mts.map +1 -1
- package/dist/react/index.mjs +47 -111
- package/dist/react/index.mjs.map +1 -1
- package/dist/solid/index.d.mts +27 -87
- package/dist/solid/index.d.mts.map +1 -1
- package/dist/solid/index.mjs +40 -108
- package/dist/solid/index.mjs.map +1 -1
- package/dist/svelte/index.d.mts +22 -75
- package/dist/svelte/index.d.mts.map +1 -1
- package/dist/svelte/index.mjs +18 -92
- package/dist/svelte/index.mjs.map +1 -1
- package/dist/vue/index.d.mts +27 -84
- package/dist/vue/index.d.mts.map +1 -1
- package/dist/vue/index.mjs +43 -136
- package/dist/vue/index.mjs.map +1 -1
- package/package.json +5 -9
- package/README.md +0 -3
- package/dist/controller-BrBUfjhZ.mjs +0 -2124
- package/dist/controller-BrBUfjhZ.mjs.map +0 -1
- package/dist/controller-CJ79_cSR.d.mts +0 -657
- package/dist/controller-CJ79_cSR.d.mts.map +0 -1
- package/dist/utils-CiHUj_BW.mjs +0 -34
- package/dist/utils-CiHUj_BW.mjs.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"controller-xMlzSCc7.mjs","names":[],"sources":["../src/core/errors.ts","../src/ui/helpers.ts","../src/ui/convert.ts","../src/ui/messages.ts","../src/ui/reducer.ts","../src/core/browser-lifecycle.ts","../src/core/controller.ts"],"sourcesContent":["export class BetterAgentClientError extends Error {\n readonly status?: number;\n readonly code?: string;\n readonly details?: unknown;\n\n constructor(\n message: string,\n options: {\n status?: number;\n code?: string;\n details?: unknown;\n cause?: unknown;\n } = {},\n ) {\n super(message, { cause: options.cause });\n this.name = \"BetterAgentClientError\";\n this.status = options.status;\n this.code = options.code;\n this.details = options.details;\n }\n}\n\nexport const toBetterAgentClientError = (error: unknown): BetterAgentClientError => {\n if (error instanceof BetterAgentClientError) {\n return error;\n }\n\n if (error instanceof Error) {\n return new BetterAgentClientError(error.message, { cause: error });\n }\n\n return new BetterAgentClientError(\"An unknown error occurred.\", { cause: error });\n};\n","import type { AgentMessageContent, AgentMessageRole } from \"@better-agent/core\";\nimport type { UIMessagePart } from \"../types\";\nimport type { UIMessageRole } from \"../types/ui\";\n\nexport const toMessageRole = (role: AgentMessageRole): UIMessageRole => {\n switch (role) {\n case \"user\":\n return \"user\";\n case \"system\":\n return \"system\";\n case \"developer\":\n return \"system\";\n default:\n return \"assistant\";\n }\n};\n\nconst sourceToUrl = (source: { type: string; value: string; mimeType?: string }) => {\n if (source.type === \"data\") {\n return `data:${source.mimeType ?? \"application/octet-stream\"};base64,${source.value}`;\n }\n return source.value;\n};\n\nconst urlToSource = (\n url: string,\n mimeType?: string,\n): Extract<Extract<AgentMessageContent, unknown[]>[number], { source: unknown }>[\"source\"] => {\n const match = /^data:([^;,]+)?;base64,(.*)$/.exec(url);\n\n if (match) {\n return {\n type: \"data\",\n value: match[2] ?? \"\",\n mimeType: mimeType ?? match[1] ?? \"application/octet-stream\",\n };\n }\n\n return {\n type: \"url\",\n value: url,\n ...(mimeType ? { mimeType } : {}),\n };\n};\n\nexport const contentToParts = (content: AgentMessageContent | undefined): UIMessagePart[] => {\n if (typeof content === \"string\") {\n return [{ type: \"text\", text: content }];\n }\n\n if (!Array.isArray(content)) {\n return [];\n }\n\n return content.flatMap((part): UIMessagePart[] => {\n if (part.type === \"text\") {\n return [{ type: \"text\", text: part.text }];\n }\n\n if (part.type === \"image\" || part.type === \"audio\" || part.type === \"video\") {\n return [\n {\n type: part.type,\n url: sourceToUrl(part.source),\n mimeType: part.source.mimeType,\n },\n ];\n }\n\n return [];\n });\n};\n\nexport const partsToContent = (parts: UIMessagePart[]): AgentMessageContent => {\n const content: Extract<AgentMessageContent, unknown[]>[number][] = [];\n\n for (const part of parts) {\n if (part.type === \"text\") {\n if (part.text) {\n content.push({ type: \"text\", text: part.text });\n }\n continue;\n }\n\n if (part.type === \"image\" || part.type === \"audio\" || part.type === \"video\") {\n content.push({\n type: part.type,\n source: urlToSource(part.url, part.mimeType),\n });\n continue;\n }\n\n if (part.type === \"file\") {\n content.push({\n type: \"document\",\n source: urlToSource(part.url, part.mimeType),\n });\n }\n }\n\n if (content.length === 1 && content[0]?.type === \"text\") {\n return content[0].text;\n }\n\n return content;\n};\n\nexport const contentToText = (content: AgentMessageContent): string => {\n if (typeof content === \"string\") {\n return content;\n }\n\n return content\n .filter((part) => part.type === \"text\")\n .map((part) => part.text)\n .join(\"\");\n};\n","import type { AgentMessage, AgentMessageContent } from \"@better-agent/core\";\nimport type { ReasoningUIPart, ToolCallUIPart, ToolResultUIPart, UIMessage } from \"../types\";\nimport { contentToParts, contentToText, partsToContent, toMessageRole } from \"./helpers\";\n\nconst isAgentMessageContent = (content: unknown): content is AgentMessageContent | undefined => {\n return content === undefined || typeof content === \"string\" || Array.isArray(content);\n};\n\nexport const fromAgentMessages = (messages: AgentMessage[]): UIMessage[] => {\n const parseToolInput = (input: string): unknown => {\n try {\n return JSON.parse(input);\n } catch {\n return undefined;\n }\n };\n\n const parseToolContent = (content: string): unknown => {\n try {\n return JSON.parse(content);\n } catch {\n return content;\n }\n };\n\n const toolResults = new Map<\n string,\n {\n content: string;\n error?: string;\n status?: \"success\" | \"error\" | \"denied\";\n approval?: {\n approved?: boolean;\n metadata?: Record<string, unknown>;\n };\n }\n >();\n\n for (const message of messages) {\n if (message.role === \"tool\") {\n toolResults.set(message.toolCallId, {\n content: message.content,\n error: message.error,\n status: message.status,\n approval: message.approval,\n });\n }\n }\n\n const uiMessages: UIMessage[] = [];\n let pendingReasoning: Array<{ id: string; part: ReasoningUIPart }> = [];\n\n for (const message of messages) {\n const parts = isAgentMessageContent(message.content) ? contentToParts(message.content) : [];\n\n if (message.role === \"reasoning\") {\n if (typeof message.content === \"string\") {\n pendingReasoning = [\n ...pendingReasoning,\n {\n id: message.id,\n part: { type: \"reasoning\", text: message.content },\n },\n ];\n }\n continue;\n }\n\n if (message.role === \"assistant\") {\n const assistantParts: UIMessage[\"parts\"] = [\n ...pendingReasoning.map((reasoning) => reasoning.part),\n ...parts,\n ];\n pendingReasoning = [];\n\n if (Array.isArray(message.toolCalls)) {\n for (const toolCall of message.toolCalls) {\n const result = toolResults.get(toolCall.id);\n\n const toolPart: ToolCallUIPart = {\n inputText: toolCall.function.arguments,\n input: parseToolInput(toolCall.function.arguments),\n toolCallId: toolCall.id,\n toolName: toolCall.function.name,\n type: \"tool-call\",\n ...(toolCall.providerExecuted ? { providerExecuted: true } : {}),\n state: \"input-available\",\n ...(result?.approval\n ? {\n approval: {\n interruptId: `${toolCall.id}:approval`,\n needsApproval: true,\n approved: result.approval.approved,\n ...(result.approval.metadata\n ? { metadata: result.approval.metadata }\n : {}),\n },\n state: \"approval-responded\" as const,\n }\n : {}),\n };\n\n assistantParts.push(toolPart);\n\n if (result) {\n const deniedResult =\n result.content.length > 0\n ? (() => {\n const parsed = parseToolContent(result.content);\n return typeof parsed === \"string\" ? parsed : undefined;\n })()\n : undefined;\n const resultPart: ToolResultUIPart =\n result.status === \"denied\"\n ? {\n type: \"tool-result\",\n toolCallId: toolCall.id,\n state: \"output-denied\",\n result: deniedResult,\n }\n : result.status === \"error\" || result.error\n ? {\n type: \"tool-result\",\n toolCallId: toolCall.id,\n state: \"output-error\",\n error: result.error ?? result.content,\n }\n : {\n type: \"tool-result\",\n toolCallId: toolCall.id,\n state: \"output-available\",\n result: parseToolContent(result.content),\n };\n\n assistantParts.push(resultPart);\n }\n }\n }\n\n for (const source of message.sources ?? []) {\n assistantParts.push({\n type: \"source\",\n sourceId: source.id,\n sourceType: \"url\",\n url: source.url,\n ...(source.title ? { title: source.title } : {}),\n });\n }\n\n uiMessages.push({\n id: message.id,\n role: message.role,\n parts: assistantParts,\n });\n continue;\n }\n\n if (message.role === \"user\" || message.role === \"system\" || message.role === \"developer\") {\n uiMessages.push({\n id: message.id,\n role: toMessageRole(message.role),\n parts,\n });\n }\n }\n\n if (pendingReasoning.length > 0) {\n for (const reasoning of pendingReasoning) {\n uiMessages.push({\n id: reasoning.id,\n role: \"assistant\",\n parts: [reasoning.part],\n });\n }\n }\n\n return uiMessages;\n};\n\nexport const toAgentMessages = (messages: UIMessage[]): AgentMessage[] => {\n return messages.map((message) => {\n const content = partsToContent(message.parts);\n\n if (message.role === \"assistant\") {\n const toolCalls = message.parts\n .filter((part): part is ToolCallUIPart => part.type === \"tool-call\")\n .map((part) => ({\n id: part.toolCallId,\n type: \"function\" as const,\n function: {\n name: part.toolName,\n arguments: part.inputText,\n },\n ...(part.providerExecuted ? { providerExecuted: true } : {}),\n }));\n\n return {\n id: message.id,\n role: \"assistant\",\n content,\n ...(toolCalls.length > 0 ? { toolCalls } : {}),\n };\n }\n\n if (message.role === \"system\") {\n return {\n id: message.id,\n role: \"system\",\n content: contentToText(content),\n };\n }\n\n return {\n id: message.id,\n role: \"user\",\n content,\n };\n });\n};\n","import type { UIMessage } from \"../types\";\n\nconst createMessageId = (): string => {\n const webCrypto = globalThis.crypto;\n\n if (typeof webCrypto?.randomUUID === \"function\") {\n return `msg_${webCrypto.randomUUID()}`;\n }\n\n if (typeof webCrypto?.getRandomValues === \"function\") {\n const bytes = webCrypto.getRandomValues(new Uint8Array(16));\n return `msg_${Array.from(bytes, (byte) => byte.toString(16).padStart(2, \"0\")).join(\"\")}`;\n }\n\n return `msg_${Date.now().toString(36)}_${Math.random().toString(36).slice(2)}`;\n};\n\nexport const createUserUIMessage = (content: string): UIMessage => ({\n id: createMessageId(),\n role: \"user\",\n parts: [{ type: \"text\", text: content }],\n});\n","import { type AgentEvent, EventType } from \"@better-agent/core\";\nimport type { UIMessage, UIMessagePart } from \"../types\";\nimport { fromAgentMessages } from \"./convert\";\nimport { toMessageRole } from \"./helpers\";\n\nexport interface UIReducerState {\n messages: UIMessage[];\n}\n\nconst updateMessage = (\n messages: UIMessage[],\n messageId: string,\n update: (message: UIMessage) => UIMessage,\n): UIMessage[] => {\n return messages.map((message) => (message.id === messageId ? update(message) : message));\n};\n\nconst upsertMessage = (\n messages: UIMessage[],\n message: UIMessage,\n update: (message: UIMessage) => UIMessage,\n): UIMessage[] => {\n return messages.some((current) => current.id === message.id)\n ? updateMessage(messages, message.id, update)\n : [...messages, update(message)];\n};\n\nconst updateToolPart = (\n messages: UIMessage[],\n toolCallId: string,\n update: (\n part: Extract<UIMessagePart, { type: \"tool-call\" }>,\n ) => Extract<UIMessagePart, { type: \"tool-call\" }>,\n): UIMessage[] => {\n return messages.map((message) => ({\n ...message,\n parts: message.parts.map((part) =>\n part.type === \"tool-call\" && part.toolCallId === toolCallId ? update(part) : part,\n ),\n }));\n};\n\nconst upsertToolResultPartByToolCallId = (\n messages: UIMessage[],\n toolCallId: string,\n update: (\n part: Extract<UIMessagePart, { type: \"tool-result\" }>,\n ) => Extract<UIMessagePart, { type: \"tool-result\" }>,\n): UIMessage[] => {\n return messages.map((message) => {\n const existingResultIndex = message.parts.findIndex(\n (part) => part.type === \"tool-result\" && part.toolCallId === toolCallId,\n );\n\n if (existingResultIndex !== -1) {\n return {\n ...message,\n parts: message.parts.map((part, index) =>\n index === existingResultIndex && part.type === \"tool-result\"\n ? update(part)\n : part,\n ),\n };\n }\n\n const toolCallIndex = message.parts.findIndex(\n (part) => part.type === \"tool-call\" && part.toolCallId === toolCallId,\n );\n\n if (toolCallIndex === -1) {\n return message;\n }\n\n const parts = [...message.parts];\n parts.splice(\n toolCallIndex + 1,\n 0,\n update({\n type: \"tool-result\",\n toolCallId,\n state: \"output-available\",\n }),\n );\n\n return {\n ...message,\n parts,\n };\n });\n};\n\nconst upsertSourcePart = (\n messages: UIMessage[],\n messageId: string,\n part: Extract<UIMessagePart, { type: \"source\" }>,\n): UIMessage[] => {\n return upsertMessage(\n messages,\n {\n id: messageId,\n role: \"assistant\",\n parts: [],\n },\n (message) => {\n const exists = message.parts.some(\n (current) => current.type === \"source\" && current.sourceId === part.sourceId,\n );\n\n return exists\n ? message\n : {\n ...message,\n parts: [...message.parts, part],\n };\n },\n );\n};\n\nconst parseToolContent = (content: string): unknown => {\n if (!content.trim()) {\n return \"\";\n }\n\n try {\n return JSON.parse(content);\n } catch {\n return content;\n }\n};\n\nexport const createUIReducerState = (messages: UIMessage[] = []): UIReducerState => {\n return {\n messages: messages,\n };\n};\n\nexport const applyUIEvent = (state: UIReducerState, event: AgentEvent): UIReducerState => {\n if (event.type === EventType.RUN_STARTED) {\n const messages = event.input?.messages?.filter((message) => message.role !== \"system\");\n\n if (!messages || messages.length === 0) {\n return state;\n }\n\n return {\n ...state,\n messages: fromAgentMessages(messages),\n };\n }\n\n if (event.type === EventType.TEXT_MESSAGE_START) {\n if (state.messages.some((message) => message.id === event.messageId)) {\n return state;\n }\n\n return {\n ...state,\n messages: [\n ...state.messages,\n {\n id: event.messageId,\n role: toMessageRole(event.role),\n parts: [],\n },\n ],\n };\n }\n\n if (event.type === EventType.TEXT_MESSAGE_CONTENT) {\n const messageIndex = state.messages.findIndex((message) => message.id === event.messageId);\n const targetMessage: UIMessage =\n messageIndex === -1\n ? {\n id: event.messageId,\n role: \"assistant\" as const,\n parts: [],\n }\n : (state.messages[messageIndex] as UIMessage);\n\n const parts: UIMessagePart[] = [...targetMessage.parts];\n const lastPart = parts[parts.length - 1];\n\n if (lastPart?.type === \"text\") {\n parts[parts.length - 1] = {\n ...lastPart,\n text: lastPart.text + event.delta,\n };\n } else {\n parts.push({ type: \"text\", text: event.delta });\n }\n\n const nextMessage = {\n ...targetMessage,\n parts,\n };\n\n return {\n ...state,\n messages:\n messageIndex === -1\n ? [...state.messages, nextMessage]\n : state.messages.map((message, index) =>\n index === messageIndex ? nextMessage : message,\n ),\n };\n }\n\n if (event.type === EventType.REASONING_MESSAGE_START) {\n if (state.messages.some((message) => message.id === event.messageId)) {\n return state;\n }\n\n return {\n ...state,\n messages: [\n ...state.messages,\n {\n id: event.messageId,\n role: \"assistant\",\n parts: [],\n },\n ],\n };\n }\n\n if (event.type === EventType.REASONING_MESSAGE_CONTENT) {\n const messageIndex = state.messages.findIndex((message) => message.id === event.messageId);\n const targetMessage: UIMessage =\n messageIndex === -1\n ? {\n id: event.messageId,\n role: \"assistant\" as const,\n parts: [],\n }\n : (state.messages[messageIndex] as UIMessage);\n\n const parts: UIMessagePart[] = [...targetMessage.parts];\n const lastPart = parts[parts.length - 1];\n\n if (lastPart?.type === \"reasoning\") {\n parts[parts.length - 1] = {\n ...lastPart,\n text: lastPart.text + event.delta,\n };\n } else {\n parts.push({ type: \"reasoning\", text: event.delta });\n }\n\n const nextMessage = {\n ...targetMessage,\n parts,\n };\n\n return {\n ...state,\n messages:\n messageIndex === -1\n ? [...state.messages, nextMessage]\n : state.messages.map((message, index) =>\n index === messageIndex ? nextMessage : message,\n ),\n };\n }\n\n if (event.type === EventType.REASONING_MESSAGE_END) {\n return state;\n }\n\n if (event.type === EventType.MESSAGES_SNAPSHOT) {\n return {\n ...state,\n messages: fromAgentMessages(event.messages),\n };\n }\n\n if (event.type === EventType.CUSTOM && event.name === \"source\" && event.value) {\n const value = event.value as {\n messageId: string;\n source: {\n id: string;\n sourceType: \"url\";\n url: string;\n title?: string;\n };\n };\n\n return {\n ...state,\n messages: upsertSourcePart(state.messages, value.messageId, {\n type: \"source\",\n sourceId: value.source.id,\n sourceType: \"url\",\n url: value.source.url,\n ...(value.source.title ? { title: value.source.title } : {}),\n }),\n };\n }\n\n if (event.type === EventType.TOOL_CALL_START) {\n if (!event.parentMessageId) return state;\n\n const alreadyExists = state.messages.some((message) =>\n message.parts.some(\n (part) => part.type === \"tool-call\" && part.toolCallId === event.toolCallId,\n ),\n );\n\n if (alreadyExists) {\n return state;\n }\n\n return {\n ...state,\n messages: upsertMessage(\n state.messages,\n {\n id: event.parentMessageId,\n role: \"assistant\",\n parts: [],\n },\n (message) => ({\n ...message,\n parts: [\n ...message.parts,\n {\n type: \"tool-call\",\n state: \"input-streaming\",\n toolCallId: event.toolCallId,\n toolName: event.toolCallName,\n inputText: \"\",\n ...(event.providerExecuted !== undefined\n ? { providerExecuted: event.providerExecuted }\n : {}),\n },\n ],\n }),\n ),\n };\n }\n\n if (event.type === EventType.TOOL_CALL_ARGS) {\n return {\n ...state,\n messages: updateToolPart(state.messages, event.toolCallId, (part) => ({\n ...part,\n inputText:\n part.inputText.length === 0\n ? event.delta\n : event.delta.startsWith(part.inputText)\n ? event.delta\n : part.inputText.endsWith(event.delta)\n ? part.inputText\n : part.inputText + event.delta,\n })),\n };\n }\n\n if (event.type === EventType.TOOL_CALL_CHUNK) {\n if (!event.toolCallId || !event.input || typeof event.input !== \"string\") return state;\n\n return {\n ...state,\n messages: updateToolPart(state.messages, event.toolCallId, (part) => ({\n ...part,\n inputText:\n part.inputText.length === 0\n ? (event.input as string)\n : (event.input as string).startsWith(part.inputText)\n ? (event.input as string)\n : part.inputText.startsWith(event.input as string)\n ? part.inputText\n : (event.input as string),\n })),\n };\n }\n\n if (event.type === EventType.TOOL_CALL_END) {\n return {\n ...state,\n messages: updateToolPart(state.messages, event.toolCallId, (part) => ({\n ...part,\n state: \"input-available\",\n input:\n typeof part.inputText === \"string\" && part.inputText.length > 0\n ? (() => {\n try {\n return JSON.parse(part.inputText);\n } catch {\n return part.input;\n }\n })()\n : part.input,\n })),\n };\n }\n\n if (event.type === EventType.TOOL_CALL_RESULT) {\n const status = \"status\" in event ? event.status : undefined;\n const parsedContent = parseToolContent(event.content);\n const deniedResult =\n status === \"denied\" && typeof parsedContent !== \"string\" ? undefined : parsedContent;\n\n return {\n ...state,\n messages: upsertToolResultPartByToolCallId(\n state.messages,\n event.toolCallId,\n (part) => ({\n ...part,\n state:\n status === \"denied\"\n ? \"output-denied\"\n : status === \"error\"\n ? \"output-error\"\n : \"output-available\",\n ...(status === \"error\"\n ? { error: event.content, result: undefined }\n : { result: deniedResult, error: undefined }),\n }),\n ),\n };\n }\n\n return {\n ...state,\n };\n};\n","declare global {\n interface Window {\n __baPageTeardown?: boolean;\n __baPageTeardownInstalled?: boolean;\n }\n}\n\nconst markPageTeardown = () => {\n if (typeof window !== \"undefined\") {\n window.__baPageTeardown = true;\n }\n};\n\nexport const ensureBrowserTeardownTracking = (): void => {\n if (typeof window === \"undefined\") {\n return;\n }\n\n window.__baPageTeardown ??= false;\n if (window.__baPageTeardownInstalled) {\n return;\n }\n\n window.__baPageTeardownInstalled = true;\n window.addEventListener(\"pagehide\", markPageTeardown);\n window.addEventListener(\"beforeunload\", markPageTeardown);\n};\n\nexport const isBrowserPageTearingDown = (): boolean =>\n typeof window !== \"undefined\" && window.__baPageTeardown === true;\n","import type { AgentEvent, RuntimeInterrupt } from \"@better-agent/core\";\nimport { EventType, RuntimeInterruptReason } from \"@better-agent/core\";\nimport { createRuntimeStateControl } from \"@better-agent/core/runtime\";\nimport type { AgentStreamResume, UIMessage } from \"../types\";\nimport type {\n AgentControllerFinish,\n AgentControllerLifecycleHooks,\n AgentControllerOptions,\n AgentControllerSnapshot,\n AgentControllerStatus,\n AgentMessageInput,\n BetterAgentClientAgentHandle,\n BetterAgentClientAgentMemoryHandle,\n PendingClientTool,\n PendingToolApproval,\n SendOptions,\n} from \"../types\";\nimport { fromAgentMessages, toAgentMessages } from \"../ui/convert\";\nimport { createUserUIMessage } from \"../ui/messages\";\nimport { applyUIEvent, createUIReducerState } from \"../ui/reducer\";\nimport { ensureBrowserTeardownTracking, isBrowserPageTearingDown } from \"./browser-lifecycle\";\nimport { BetterAgentClientError, toBetterAgentClientError } from \"./errors\";\nimport type { AgentNameOf } from \"./inference\";\n\ntype ClientToolInterrupt = RuntimeInterrupt & {\n reason: typeof RuntimeInterruptReason.ClientToolPending;\n toolCallId: string;\n};\n\ntype ApprovalInterrupt = RuntimeInterrupt & {\n reason: typeof RuntimeInterruptReason.ToolApprovalPending;\n toolCallId: string;\n};\n\ntype ResumeEntry = {\n interruptId: string;\n status: \"resolved\" | \"cancelled\";\n payload?: unknown;\n};\n\nexport class AgentController<TApp, TName extends AgentNameOf<TApp>> {\n private messages: UIMessage[];\n private stateControl: ReturnType<typeof createRuntimeStateControl<unknown>>;\n private status: AgentControllerStatus = \"ready\";\n private error: BetterAgentClientError | undefined;\n private runId: string | undefined;\n private threadId: string | undefined;\n private pendingClientTools: PendingClientTool[] = [];\n private pendingToolApprovals: PendingToolApproval[] = [];\n private stateRevision = 0;\n private snapshot: AgentControllerSnapshot;\n private listeners = new Set<() => void>();\n private activeAbortController: AbortController | undefined;\n private finishMessageStartIndex = 0;\n private stopRequested = false;\n private stopWaitTimer: ReturnType<typeof setTimeout> | undefined;\n private abortRequestedRunId: string | undefined;\n private started = false;\n\n constructor(\n private readonly agent: BetterAgentClientAgentHandle<TApp, TName>,\n private readonly options: AgentControllerOptions<TApp, TName>,\n ) {\n ensureBrowserTeardownTracking();\n this.messages = options.initialMessages ?? [];\n this.stateControl = createRuntimeStateControl(options.initialState);\n this.threadId = options.threadId;\n this.runId = options.initialInterruptState?.runId;\n this.pendingClientTools = [...(options.initialInterruptState?.pendingClientTools ?? [])];\n this.pendingToolApprovals = [\n ...(options.initialInterruptState?.pendingToolApprovals ?? []),\n ];\n this.status =\n options.initialInterruptState?.status ??\n (this.pendingClientTools.length > 0 || this.pendingToolApprovals.length > 0\n ? \"interrupted\"\n : \"ready\");\n\n for (const approval of this.pendingToolApprovals) {\n this.updateToolCallPart(approval.toolCallId, {\n state: \"approval-requested\",\n approval: {\n interruptId: approval.interruptId,\n needsApproval: true,\n ...(approval.metadata ? { metadata: approval.metadata } : {}),\n },\n });\n }\n\n this.snapshot = this.createSnapshot();\n }\n\n start(): void {\n if (this.started) {\n return;\n }\n this.started = true;\n\n const shouldAutoHydrateThread =\n this.threadId && this.options.initialMessages === undefined && \"memory\" in this.agent;\n\n if (this.options.resume) {\n void (async () => {\n try {\n if (shouldAutoHydrateThread) {\n await this.loadMessages(this.threadId, {\n beforeRunId: this.options.resume?.runId,\n });\n }\n await this.resume(this.options.resume);\n } catch {}\n })();\n } else if (this.pendingClientTools.length > 0 && !this.hasUndecidedApprovals()) {\n void this.runPendingInterruptsWithLifecycle();\n } else if (shouldAutoHydrateThread && this.threadId) {\n void this.loadThread(this.threadId).catch(() => {});\n }\n }\n\n getSnapshot(): AgentControllerSnapshot {\n return this.snapshot;\n }\n\n private createSnapshot(): AgentControllerSnapshot {\n return {\n messages: this.messages,\n state: this.stateControl.get(),\n status: this.status,\n error: this.error,\n runId: this.runId,\n threadId: this.threadId,\n isRunning: this.status === \"submitted\" || this.status === \"streaming\",\n pendingClientTools: this.pendingClientTools,\n pendingToolApprovals: this.getPendingToolApprovalsSnapshot(),\n };\n }\n\n private getPendingToolApprovalsSnapshot(): PendingToolApproval[] {\n return this.pendingToolApprovals.filter((approval) => approval.approved === undefined);\n }\n\n private isClientToolInterrupt(\n interrupt: RuntimeInterrupt | undefined,\n ): interrupt is ClientToolInterrupt {\n return Boolean(\n interrupt?.reason === RuntimeInterruptReason.ClientToolPending && interrupt.toolCallId,\n );\n }\n\n private isApprovalInterrupt(\n interrupt: RuntimeInterrupt | undefined,\n ): interrupt is ApprovalInterrupt {\n return Boolean(\n interrupt?.reason === RuntimeInterruptReason.ToolApprovalPending &&\n interrupt.toolCallId,\n );\n }\n\n private getToolCallPart(toolCallId: string) {\n for (const message of this.messages) {\n const part = message.parts.find(\n (\n candidate,\n ): candidate is Extract<UIMessage[\"parts\"][number], { type: \"tool-call\" }> =>\n candidate.type === \"tool-call\" && candidate.toolCallId === toolCallId,\n );\n\n if (part) {\n return part;\n }\n }\n\n return undefined;\n }\n\n private combineAbortSignals(primary: AbortSignal, secondary?: AbortSignal | null): AbortSignal {\n if (!secondary) {\n return primary;\n }\n\n return AbortSignal.any([primary, secondary]);\n }\n\n private hasUndecidedApprovals(): boolean {\n return this.pendingToolApprovals.some((approval) => approval.approved === undefined);\n }\n\n subscribe(listener: () => void): () => void {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n setMessages(messages: UIMessage[]): void {\n this.messages = messages;\n this.notify();\n }\n\n async loadMessages(\n threadId = this.threadId,\n options?: { beforeRunId?: string },\n ): Promise<void> {\n if (!threadId) {\n throw new BetterAgentClientError(\"Cannot load messages without a threadId.\");\n }\n const memory =\n \"memory\" in this.agent\n ? (this.agent as BetterAgentClientAgentMemoryHandle).memory\n : undefined;\n if (!memory) {\n throw new BetterAgentClientError(\"Agent memory is not available.\");\n }\n\n try {\n const messages = await memory.messages.list(threadId, options);\n this.threadId = threadId;\n this.messages = fromAgentMessages(\n messages.map((message) => {\n const {\n threadId: _threadId,\n runId: _runId,\n createdAt: _createdAt,\n ...rest\n } = message;\n return rest;\n }),\n );\n\n for (const approval of this.pendingToolApprovals) {\n this.updateToolCallPart(approval.toolCallId, {\n state: \"approval-requested\",\n approval: {\n interruptId: approval.interruptId,\n needsApproval: true,\n ...(approval.metadata ? { metadata: approval.metadata } : {}),\n },\n });\n }\n\n this.error = undefined;\n this.notify();\n } catch (error) {\n this.error = toBetterAgentClientError(error);\n this.status = \"error\";\n this.notify();\n throw this.error;\n }\n }\n\n private async loadThread(threadId: string): Promise<void> {\n const memory =\n \"memory\" in this.agent\n ? (this.agent as BetterAgentClientAgentMemoryHandle).memory\n : undefined;\n if (!memory) {\n throw new BetterAgentClientError(\"Agent memory is not available.\");\n }\n\n const runtime = await memory.threads.runtime(threadId);\n if (runtime.resumable) {\n await this.loadMessages(threadId, { beforeRunId: runtime.resumable.runId });\n await this.resume(runtime.resumable);\n return;\n }\n\n await this.loadMessages(threadId);\n\n if (runtime.interrupted) {\n this.hydrateInterrupts(runtime.interrupted.runId, runtime.interrupted.interrupts);\n if (this.pendingClientTools.length > 0 && !this.hasUndecidedApprovals()) {\n await this.runPendingInterruptsWithLifecycle();\n }\n }\n }\n\n private hydrateInterrupts(runId: string, interrupts: RuntimeInterrupt[]): void {\n const approvalInterrupts = interrupts.filter((interrupt): interrupt is ApprovalInterrupt =>\n this.isApprovalInterrupt(interrupt),\n );\n const clientToolInterrupts = interrupts.filter(\n (interrupt): interrupt is ClientToolInterrupt => this.isClientToolInterrupt(interrupt),\n );\n\n const approvals: PendingToolApproval[] = [];\n for (const interrupt of approvalInterrupts) {\n const pending = this.createPendingApproval(runId, interrupt);\n if (\"isError\" in pending) {\n return;\n }\n approvals.push(pending);\n this.updateToolCallPart(interrupt.toolCallId, {\n state: \"approval-requested\",\n approval: {\n interruptId: interrupt.id,\n needsApproval: true,\n ...(interrupt.metadata ? { metadata: interrupt.metadata } : {}),\n },\n });\n }\n\n const clientTools: PendingClientTool[] = [];\n for (const interrupt of clientToolInterrupts) {\n const pending = this.createPendingClientTool(runId, interrupt);\n if (\"isError\" in pending) {\n return;\n }\n clientTools.push(pending);\n }\n\n this.runId = runId;\n this.pendingToolApprovals = approvals;\n this.pendingClientTools = clientTools;\n this.status = \"interrupted\";\n this.error = undefined;\n this.notify();\n }\n\n async selectThread(threadId: string): Promise<void> {\n this.stop();\n await this.loadThread(threadId);\n }\n\n clearThread(): void {\n this.stop();\n this.messages = [];\n this.threadId = undefined;\n this.runId = undefined;\n this.error = undefined;\n this.pendingClientTools = [];\n this.pendingToolApprovals = [];\n this.status = \"ready\";\n this.notify();\n }\n\n private clearStopWaitTimer(): void {\n if (this.stopWaitTimer) {\n clearTimeout(this.stopWaitTimer);\n this.stopWaitTimer = undefined;\n }\n }\n\n private resetStopRequest(): void {\n this.stopRequested = false;\n this.abortRequestedRunId = undefined;\n this.clearStopWaitTimer();\n }\n\n private abortServerRun(runId: string): void {\n if (this.abortRequestedRunId === runId) {\n return;\n }\n\n this.abortRequestedRunId = runId;\n void this.agent.runs.abort(runId).catch((error: unknown) => {\n console.error(\"[better-agent] abortRun failed\", error);\n });\n }\n\n private abortActiveRequest(): void {\n this.activeAbortController?.abort();\n this.activeAbortController = undefined;\n }\n\n stop(): void {\n this.stopRequested = true;\n const runId = this.runId;\n if (runId) {\n this.clearStopWaitTimer();\n this.abortServerRun(runId);\n this.abortActiveRequest();\n } else if (this.activeAbortController && !this.stopWaitTimer) {\n const activeAbortController = this.activeAbortController;\n this.stopWaitTimer = setTimeout(() => {\n if (this.stopRequested && this.activeAbortController === activeAbortController) {\n this.abortActiveRequest();\n }\n this.clearStopWaitTimer();\n }, 2000);\n }\n\n if (this.status !== \"ready\") {\n this.status = \"ready\";\n this.notify();\n }\n }\n\n private safeLifecycle(name: string, fn: () => void | Promise<void>): void {\n try {\n const result = fn();\n if (\n result !== undefined &&\n typeof result === \"object\" &&\n \"then\" in result &&\n typeof (result as Promise<void>).then === \"function\"\n ) {\n void (result as Promise<void>).catch((err: unknown) => {\n console.error(`[better-agent] ${name} callback failed`, err);\n });\n }\n } catch (err) {\n console.error(`[better-agent] ${name} callback failed`, err);\n }\n }\n\n private emitEvent(hooks: AgentControllerLifecycleHooks, event: AgentEvent): void {\n const onEvent = hooks.onEvent;\n if (!onEvent) {\n return;\n }\n this.safeLifecycle(\"onEvent\", () => onEvent(event));\n }\n\n private invokeLifecycleFinish(\n hooks: AgentControllerLifecycleHooks,\n finish: AgentControllerFinish,\n ): void {\n this.safeLifecycle(\"onFinish\", () => hooks.onFinish?.(finish));\n const error = finish.error;\n if (finish.isError && error) {\n const onError = hooks.onError;\n if (onError) {\n this.safeLifecycle(\"onError\", () => onError(error));\n }\n }\n }\n\n private createFinish(\n finish: Pick<\n AgentControllerFinish,\n \"isAbort\" | \"isDisconnect\" | \"isError\" | \"isInterrupted\"\n > &\n Pick<AgentControllerFinish, \"error\" | \"interruptReason\"> & {\n pendingClientTools?: PendingClientTool[];\n pendingToolApprovals?: PendingToolApproval[];\n },\n ): AgentControllerFinish {\n const messages = [...this.messages];\n const generatedMessages = messages.slice(this.finishMessageStartIndex);\n const message = generatedMessages[generatedMessages.length - 1];\n return {\n ...(message ? { message } : {}),\n generatedMessages,\n messages,\n runId: this.runId,\n threadId: this.threadId,\n pendingClientTools: finish.pendingClientTools ?? [...this.pendingClientTools],\n pendingToolApprovals:\n finish.pendingToolApprovals ?? this.getPendingToolApprovalsSnapshot(),\n ...finish,\n };\n }\n\n async sendMessage(\n input: AgentMessageInput,\n sendOptions?: SendOptions<TApp, TName>,\n ): Promise<void> {\n const hooks = {\n onEvent: this.options.onEvent,\n onFinish: this.options.onFinish,\n onError: this.options.onError,\n };\n let terminal: AgentControllerFinish | undefined;\n\n this.stop();\n this.resetStopRequest();\n this.error = undefined;\n this.pendingClientTools = [];\n this.pendingToolApprovals = [];\n this.status = \"submitted\";\n const inputMessages = typeof input === \"string\" ? [createUserUIMessage(input)] : input;\n this.messages = [...this.messages, ...inputMessages];\n this.finishMessageStartIndex = this.messages.length;\n this.notify();\n\n const abortController = new AbortController();\n this.activeAbortController = abortController;\n\n const streamSignal = this.combineAbortSignals(\n abortController.signal,\n sendOptions?.signal ?? null,\n );\n\n const context = sendOptions?.context ?? this.options.context;\n\n try {\n const stream = this.agent.stream(\n {\n messages: toAgentMessages(this.threadId ? inputMessages : this.messages).map(\n ({ id: _id, ...message }) => message,\n ),\n ...(context !== undefined ? { context } : {}),\n ...(this.stateControl.get() !== undefined\n ? { state: this.stateControl.get() }\n : {}),\n ...(this.threadId !== undefined ? { threadId: this.threadId } : {}),\n },\n { signal: streamSignal },\n );\n\n terminal = await this.consumeStream(stream, hooks, streamSignal);\n } catch (error) {\n if (streamSignal.aborted || isBrowserPageTearingDown()) {\n this.status = \"ready\";\n this.notify();\n terminal = this.createFinish({\n isAbort: true,\n isDisconnect: false,\n isError: false,\n isInterrupted: false,\n });\n } else {\n this.error = toBetterAgentClientError(error);\n this.status = \"error\";\n this.notify();\n terminal = this.createFinish({\n isAbort: false,\n isDisconnect: false,\n isError: true,\n isInterrupted: false,\n error: this.error,\n });\n }\n } finally {\n if (this.activeAbortController === abortController) {\n this.activeAbortController = undefined;\n }\n if (terminal !== undefined) {\n this.invokeLifecycleFinish(hooks, terminal);\n }\n }\n }\n\n async approveToolCall(interruptId: string, metadata?: Record<string, unknown>): Promise<void> {\n await this.resolveApprovalDecision(interruptId, true, metadata);\n }\n\n async rejectToolCall(\n interruptId: string,\n metadata?: Record<string, unknown> | string,\n ): Promise<void> {\n await this.resolveApprovalDecision(interruptId, false, metadata);\n }\n\n async resume(resume?: AgentStreamResume): Promise<void> {\n const nextResume = resume ?? (this.runId ? { runId: this.runId } : undefined);\n if (!nextResume) {\n throw new BetterAgentClientError(\"Cannot resume without a runId.\");\n }\n\n const hooks = {\n onEvent: this.options.onEvent,\n onFinish: this.options.onFinish,\n onError: this.options.onError,\n };\n\n const abortController = new AbortController();\n this.resetStopRequest();\n this.activeAbortController?.abort();\n this.activeAbortController = abortController;\n this.runId = nextResume.runId;\n this.status = \"streaming\";\n this.finishMessageStartIndex = this.messages.length;\n this.notify();\n\n let terminal: AgentControllerFinish | undefined;\n\n try {\n const stream = this.agent.runs.resumeStream(\n {\n runId: nextResume.runId,\n afterSequence: nextResume.afterSequence,\n },\n { signal: abortController.signal },\n );\n\n terminal = await this.consumeStream(stream, hooks, abortController.signal);\n } catch (error) {\n if (abortController.signal.aborted || isBrowserPageTearingDown()) {\n this.status = \"ready\";\n this.notify();\n terminal = this.createFinish({\n isAbort: true,\n isDisconnect: false,\n isError: false,\n isInterrupted: false,\n });\n } else {\n this.error = toBetterAgentClientError(error);\n this.status = \"error\";\n this.notify();\n terminal = this.createFinish({\n isAbort: false,\n isDisconnect: false,\n isError: true,\n isInterrupted: false,\n error: this.error,\n });\n }\n } finally {\n if (this.activeAbortController === abortController) {\n this.activeAbortController = undefined;\n }\n if (terminal !== undefined) {\n this.invokeLifecycleFinish(hooks, terminal);\n }\n }\n }\n\n private async consumeStream(\n stream: AsyncIterable<AgentEvent>,\n hooks: AgentControllerLifecycleHooks,\n signal: AbortSignal,\n beforeSuccessFinish?: () => void,\n ): Promise<AgentControllerFinish> {\n for await (const event of stream) {\n if (signal.aborted) {\n break;\n }\n\n const terminal = await this.processStreamEvent(event, hooks, signal);\n if (terminal) {\n return terminal;\n }\n }\n\n if (signal.aborted) {\n return this.createFinish({\n isAbort: true,\n isDisconnect: false,\n isError: false,\n isInterrupted: false,\n });\n }\n\n beforeSuccessFinish?.();\n this.status = \"ready\";\n this.notify();\n return this.createFinish({\n isAbort: false,\n isDisconnect: false,\n isError: false,\n isInterrupted: false,\n });\n }\n\n private async processStreamEvent(\n event: AgentEvent,\n hooks: AgentControllerLifecycleHooks,\n signal: AbortSignal,\n ): Promise<AgentControllerFinish | undefined> {\n if (event.type === EventType.RUN_ERROR) {\n const message =\n \"message\" in event && typeof event.message === \"string\"\n ? event.message\n : \"Run failed.\";\n const code = \"code\" in event && typeof event.code === \"string\" ? event.code : undefined;\n this.error = new BetterAgentClientError(message, {\n code,\n details: event,\n });\n this.status = \"error\";\n this.notify();\n this.emitEvent(hooks, event);\n return this.createFinish({\n isAbort: false,\n isDisconnect: false,\n isError: true,\n isInterrupted: false,\n error: this.error,\n });\n }\n\n if (event.type === EventType.RUN_FINISHED && event.outcome === \"interrupt\") {\n this.applyEvent(event);\n this.notify();\n this.emitEvent(hooks, event);\n\n const interrupts = event.interrupts ?? [];\n const runId = event.runId ?? this.runId;\n\n if (!runId && interrupts.length > 0) {\n this.error = new BetterAgentClientError(\"Interrupt missing runId.\");\n this.status = \"error\";\n this.notify();\n return this.createFinish({\n isAbort: false,\n isDisconnect: false,\n isError: true,\n isInterrupted: false,\n error: this.error,\n });\n }\n\n if (runId && interrupts.length > 0) {\n this.runId = runId;\n return await this.resolveInterrupts({\n runId,\n interrupts,\n hooks,\n signal,\n });\n }\n\n this.status = \"interrupted\";\n this.notify();\n return this.createFinish({\n isAbort: false,\n isDisconnect: false,\n isError: false,\n isInterrupted: true,\n interruptReason: \"other\",\n });\n }\n\n this.applyEvent(event);\n if (this.stopRequested) {\n return this.createFinish({\n isAbort: true,\n isDisconnect: false,\n isError: false,\n isInterrupted: false,\n });\n }\n\n this.status = \"streaming\";\n this.notify();\n this.emitEvent(hooks, event);\n return undefined;\n }\n\n private createPendingClientTool(\n runId: string,\n interrupt: ClientToolInterrupt,\n ): PendingClientTool | AgentControllerFinish {\n const toolCall = this.getToolCallPart(interrupt.toolCallId);\n if (!toolCall) {\n this.error = new BetterAgentClientError(\n `Client tool call not found for toolCallId: ${interrupt.toolCallId}`,\n );\n this.status = \"error\";\n this.notify();\n return this.createFinish({\n isAbort: false,\n isDisconnect: false,\n isError: true,\n isInterrupted: false,\n error: this.error,\n });\n }\n\n return {\n interruptId: interrupt.id,\n runId,\n toolCallId: interrupt.toolCallId,\n toolName: toolCall.toolName,\n input: toolCall.input,\n ...(interrupt.expiresAt !== undefined ? { expiresAt: interrupt.expiresAt } : {}),\n };\n }\n\n private createPendingApproval(\n runId: string,\n interrupt: ApprovalInterrupt,\n ): PendingToolApproval | AgentControllerFinish {\n const toolCall = this.getToolCallPart(interrupt.toolCallId);\n\n if (!toolCall) {\n this.error = new BetterAgentClientError(\n `Approval tool call not found for toolCallId: ${interrupt.toolCallId}`,\n );\n this.status = \"error\";\n this.notify();\n return this.createFinish({\n isAbort: false,\n isDisconnect: false,\n isError: true,\n isInterrupted: false,\n error: this.error,\n });\n }\n\n return {\n interruptId: interrupt.id,\n runId,\n toolCallId: interrupt.toolCallId,\n toolName: toolCall.toolName,\n input: toolCall.input,\n metadata: interrupt.metadata,\n ...(interrupt.expiresAt !== undefined ? { expiresAt: interrupt.expiresAt } : {}),\n };\n }\n\n private async createClientToolResumeEntry(\n pending: PendingClientTool,\n ): Promise<ResumeEntry | undefined> {\n const handler = this.getToolHandler(pending.toolName);\n if (!handler) {\n return undefined;\n }\n\n try {\n const payload = await handler(pending.input);\n const resumePayload =\n payload === undefined\n ? { status: \"success\" as const, result: {} }\n : { status: \"success\" as const, result: payload };\n\n this.upsertToolResultPart(pending.toolCallId, {\n state: \"output-available\",\n result:\n typeof resumePayload.result === \"string\"\n ? resumePayload.result\n : JSON.stringify(resumePayload.result),\n });\n this.notify();\n\n return {\n interruptId: pending.interruptId,\n status: \"resolved\",\n payload: resumePayload,\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n const resumePayload = {\n status: \"error\" as const,\n error: message,\n };\n\n this.upsertToolResultPart(pending.toolCallId, {\n state: \"output-error\",\n error: message,\n });\n this.notify();\n\n return {\n interruptId: pending.interruptId,\n status: \"resolved\",\n payload: resumePayload,\n };\n }\n }\n\n private async resolveInterrupts(params: {\n runId: string;\n interrupts: RuntimeInterrupt[];\n hooks: AgentControllerLifecycleHooks;\n signal: AbortSignal;\n }): Promise<AgentControllerFinish> {\n const { hooks, runId, signal } = params;\n const approvalInterrupts = params.interrupts.filter(\n (interrupt): interrupt is ApprovalInterrupt => this.isApprovalInterrupt(interrupt),\n );\n const clientToolInterrupts = params.interrupts.filter(\n (interrupt): interrupt is ClientToolInterrupt => this.isClientToolInterrupt(interrupt),\n );\n\n if (approvalInterrupts.length > 0) {\n const approvals: PendingToolApproval[] = [];\n for (const interrupt of approvalInterrupts) {\n const pending = this.createPendingApproval(runId, interrupt);\n if (\"isError\" in pending) {\n return pending;\n }\n approvals.push(pending);\n this.updateToolCallPart(interrupt.toolCallId, {\n state: \"approval-requested\",\n approval: {\n interruptId: interrupt.id,\n needsApproval: true,\n ...(interrupt.metadata ? { metadata: interrupt.metadata } : {}),\n },\n });\n }\n\n const clientTools: PendingClientTool[] = [];\n for (const interrupt of clientToolInterrupts) {\n const pending = this.createPendingClientTool(runId, interrupt);\n if (\"isError\" in pending) {\n return pending;\n }\n clientTools.push(pending);\n }\n\n this.pendingToolApprovals = approvals;\n this.pendingClientTools = clientTools;\n this.status = \"interrupted\";\n this.notify();\n return this.createFinish({\n isAbort: false,\n isDisconnect: false,\n isError: false,\n isInterrupted: true,\n interruptReason: \"tool_approval_pending\",\n });\n }\n\n if (clientToolInterrupts.length > 0) {\n const clientTools: PendingClientTool[] = [];\n for (const interrupt of clientToolInterrupts) {\n const pending = this.createPendingClientTool(runId, interrupt);\n if (\"isError\" in pending) {\n return pending;\n }\n clientTools.push(pending);\n }\n\n this.pendingClientTools = clientTools;\n this.pendingToolApprovals = [];\n return this.resolvePendingInterruptBatch(hooks, signal);\n }\n\n this.pendingClientTools = [];\n this.pendingToolApprovals = [];\n this.status = \"interrupted\";\n this.notify();\n return this.createFinish({\n isAbort: false,\n isDisconnect: false,\n isError: false,\n isInterrupted: true,\n interruptReason: \"other\",\n });\n }\n\n private async streamWithResume(\n resume: ResumeEntry[],\n hooks: AgentControllerLifecycleHooks,\n signal: AbortSignal,\n ): Promise<AgentControllerFinish> {\n const stream = this.agent.stream(\n {\n resume,\n ...(this.stateControl.get() !== undefined\n ? { state: this.stateControl.get() }\n : {}),\n ...(this.threadId !== undefined ? { threadId: this.threadId } : {}),\n },\n { signal },\n );\n\n return this.consumeStream(stream, hooks, signal, () => {\n this.pendingClientTools = [];\n this.pendingToolApprovals = [];\n });\n }\n\n private async runPendingInterruptsWithLifecycle(): Promise<void> {\n const hooks = {\n onEvent: this.options.onEvent,\n onFinish: this.options.onFinish,\n onError: this.options.onError,\n };\n const abortController = new AbortController();\n this.resetStopRequest();\n this.activeAbortController?.abort();\n this.activeAbortController = abortController;\n this.error = undefined;\n this.finishMessageStartIndex = this.messages.length;\n this.status = \"streaming\";\n this.notify();\n\n let terminal: AgentControllerFinish | undefined;\n\n try {\n terminal = await this.resolvePendingInterruptBatch(hooks, abortController.signal);\n } catch (e) {\n if (abortController.signal.aborted) {\n terminal = this.createFinish({\n isAbort: true,\n isDisconnect: false,\n isError: false,\n isInterrupted: false,\n });\n } else {\n this.error = toBetterAgentClientError(e);\n this.status = \"error\";\n this.notify();\n terminal = this.createFinish({\n isAbort: false,\n isDisconnect: false,\n isError: true,\n isInterrupted: false,\n error: this.error,\n });\n }\n } finally {\n if (this.activeAbortController === abortController) {\n this.activeAbortController = undefined;\n }\n\n if (terminal !== undefined) {\n this.invokeLifecycleFinish(hooks, terminal);\n }\n }\n }\n\n private async resolvePendingInterruptBatch(\n hooks: AgentControllerLifecycleHooks,\n signal: AbortSignal,\n ): Promise<AgentControllerFinish> {\n if (this.hasUndecidedApprovals()) {\n this.status = \"interrupted\";\n this.notify();\n return this.createFinish({\n isAbort: false,\n isDisconnect: false,\n isError: false,\n isInterrupted: true,\n interruptReason: \"tool_approval_pending\",\n });\n }\n\n const runId =\n this.runId ?? this.pendingToolApprovals[0]?.runId ?? this.pendingClientTools[0]?.runId;\n\n if (!runId) {\n this.error = new BetterAgentClientError(\"Pending interrupt missing runId.\");\n this.status = \"error\";\n this.notify();\n return this.createFinish({\n isAbort: false,\n isDisconnect: false,\n isError: true,\n isInterrupted: false,\n error: this.error,\n });\n }\n\n const resume: ResumeEntry[] = this.pendingToolApprovals.map((approval) => ({\n interruptId: approval.interruptId,\n status: \"resolved\",\n payload: {\n approved: approval.approved,\n ...(approval.responseMetadata ? { metadata: approval.responseMetadata } : {}),\n },\n }));\n\n if (this.pendingClientTools.some((pending) => !this.getToolHandler(pending.toolName))) {\n this.status = \"interrupted\";\n this.notify();\n return this.createFinish({\n isAbort: false,\n isDisconnect: false,\n isError: false,\n isInterrupted: true,\n interruptReason: \"client_tool_pending\",\n });\n }\n\n for (const pending of this.pendingClientTools) {\n const entry = await this.createClientToolResumeEntry(pending);\n if (entry) {\n resume.push(entry);\n }\n }\n\n if (resume.length === 0) {\n this.status = \"interrupted\";\n this.notify();\n return this.createFinish({\n isAbort: false,\n isDisconnect: false,\n isError: false,\n isInterrupted: true,\n interruptReason: \"other\",\n });\n }\n\n this.runId = runId;\n return this.streamWithResume(resume, hooks, signal);\n }\n\n private getToolHandler(\n toolName: string,\n ): ((input: unknown) => unknown | Promise<unknown>) | undefined {\n const handlers = this.options.toolHandlers as\n | Record<string, ((input: unknown) => unknown | Promise<unknown>) | undefined>\n | undefined;\n return handlers?.[toolName];\n }\n\n private updateToolCallPart(\n toolCallId: string,\n update: Partial<Extract<UIMessage[\"parts\"][number], { type: \"tool-call\" }>>,\n ): void {\n this.messages = this.messages.map((message) => ({\n ...message,\n parts: message.parts.map((part) =>\n part.type === \"tool-call\" && part.toolCallId === toolCallId\n ? { ...part, ...update }\n : part,\n ),\n }));\n }\n\n private upsertToolResultPart(\n toolCallId: string,\n update: Partial<Extract<UIMessage[\"parts\"][number], { type: \"tool-result\" }>>,\n ): void {\n this.messages = this.messages.map((message) => {\n const existingResultIndex = message.parts.findIndex(\n (part) => part.type === \"tool-result\" && part.toolCallId === toolCallId,\n );\n const existingToolCallIndex = message.parts.findIndex(\n (part) => part.type === \"tool-call\" && part.toolCallId === toolCallId,\n );\n\n if (existingResultIndex === -1 && existingToolCallIndex === -1) {\n return message;\n }\n\n if (existingResultIndex !== -1) {\n return {\n ...message,\n parts: message.parts.map((part, index) =>\n index === existingResultIndex && part.type === \"tool-result\"\n ? { ...part, ...update }\n : part,\n ),\n };\n }\n\n const parts = [...message.parts];\n const insertIndex = existingToolCallIndex + 1;\n parts.splice(insertIndex, 0, {\n type: \"tool-result\",\n toolCallId,\n state: \"output-available\",\n ...update,\n });\n\n return {\n ...message,\n parts,\n };\n });\n }\n\n private async resolveApprovalDecision(\n interruptId: string,\n approved: boolean,\n metadata?: Record<string, unknown> | string,\n ): Promise<void> {\n const approvalIndex = this.pendingToolApprovals.findIndex(\n (approval) => approval.interruptId === interruptId,\n );\n if (approvalIndex === -1) {\n throw new BetterAgentClientError(\n `Pending approval not found for interruptId: ${interruptId}`,\n );\n }\n\n const approval = this.pendingToolApprovals[approvalIndex];\n if (!approval) {\n return;\n }\n\n const normalizedMetadata = typeof metadata === \"string\" ? { note: metadata } : metadata;\n\n this.error = undefined;\n this.pendingToolApprovals = this.pendingToolApprovals.map((pending, index) =>\n index === approvalIndex\n ? {\n ...pending,\n approved,\n responseMetadata: normalizedMetadata,\n }\n : pending,\n );\n this.updateToolCallPart(approval.toolCallId, {\n state: \"approval-responded\",\n approval: {\n interruptId: approval.interruptId,\n needsApproval: true,\n approved,\n ...(normalizedMetadata ? { metadata: normalizedMetadata } : {}),\n },\n });\n this.notify();\n\n if (this.hasUndecidedApprovals()) {\n this.status = \"interrupted\";\n this.notify();\n return;\n }\n\n await this.runPendingInterruptsWithLifecycle();\n }\n\n private applyEvent(event: AgentEvent): void {\n const rid = \"runId\" in event && typeof event.runId === \"string\" ? event.runId : undefined;\n const tid =\n \"threadId\" in event && typeof event.threadId === \"string\" && event.threadId.length > 0\n ? event.threadId\n : undefined;\n if (rid) {\n this.runId = rid;\n if (this.stopRequested) {\n this.clearStopWaitTimer();\n this.abortServerRun(rid);\n this.abortActiveRequest();\n return;\n }\n }\n\n if (tid) {\n this.threadId = tid;\n }\n\n if (this.stopRequested) {\n return;\n }\n\n this.stateControl.apply(event);\n if (event.type === EventType.STATE_SNAPSHOT || event.type === EventType.STATE_DELTA) {\n this.stateRevision += 1;\n }\n\n this.messages = applyUIEvent(createUIReducerState(this.messages), event).messages;\n }\n\n private notify(): void {\n this.snapshot = this.createSnapshot();\n for (const listener of this.listeners) {\n listener();\n }\n }\n}\n\nexport function createAgentController<TApp, TName extends AgentNameOf<TApp>>(\n agent: BetterAgentClientAgentHandle<TApp, TName>,\n options: AgentControllerOptions<TApp, TName>,\n): AgentController<TApp, TName> {\n return new AgentController<TApp, TName>(agent, options);\n}\n"],"mappings":"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"}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,266 +1,12 @@
|
|
|
1
|
-
import { A as
|
|
2
|
-
import {
|
|
3
|
-
import { ConversationItem, GenerativeModelInputItem } from "@better-agent/core/providers";
|
|
1
|
+
import { A as BetterAgentClient, B as PreparedRequest, C as ToolResultUIPart, D as VideoUIPart, E as UIMessageRole, F as BetterAgentClientRuns, G as ToolHandlersFor, H as AgentContextFor, I as ClientMemoryThread, L as ClientMemoryThreadCreateInput, M as BetterAgentClientAgentMemoryHandle, N as BetterAgentClientConfig, O as BetterAgentClientError, P as BetterAgentClientMemory, R as ClientMemoryThreadUpdateInput, S as ToolResultState, T as UIMessagePart, V as RequestOptions, W as AgentNameOf, _ as ReasoningUIPart, a as AgentControllerOptions, b as ToolCallState, c as AgentInterruptState, d as PendingClientTool, f as PendingToolApproval, g as ImageUIPart, h as FileUIPart, i as AgentControllerLifecycleHooks, j as BetterAgentClientAgentHandle, k as toBetterAgentClientError, l as AgentMessageInput, m as AudioUIPart, n as createAgentController, o as AgentControllerSnapshot, p as SendOptions, r as AgentControllerFinish, s as AgentControllerStatus, t as AgentController, u as AgentStreamResume, v as SourceUIPart, w as UIMessage, x as ToolCallUIPart, y as TextUIPart, z as ClientRunInput } from "./controller-B7G0xSYW.mjs";
|
|
2
|
+
import { AgentMessage } from "@better-agent/core";
|
|
4
3
|
|
|
5
|
-
//#region src/
|
|
6
|
-
|
|
7
|
-
* Creates a Better Agent client.
|
|
8
|
-
*
|
|
9
|
-
* @param config Client configuration.
|
|
10
|
-
* @returns A typed client.
|
|
11
|
-
*
|
|
12
|
-
* @example
|
|
13
|
-
* ```ts
|
|
14
|
-
* import { createClient } from "@better-agent/client";
|
|
15
|
-
*
|
|
16
|
-
* const client = createClient({
|
|
17
|
-
* baseURL: "http://localhost:3000/api",
|
|
18
|
-
* secret: "dev_secret",
|
|
19
|
-
* });
|
|
20
|
-
*
|
|
21
|
-
* const result = await client.run("helloAgent", {
|
|
22
|
-
* input: "Write one short sentence about TypeScript.",
|
|
23
|
-
* });
|
|
24
|
-
* ```
|
|
25
|
-
*
|
|
26
|
-
* @example
|
|
27
|
-
* ```ts
|
|
28
|
-
* import type ba from "./better-agent/server";
|
|
29
|
-
* import { createClient } from "@better-agent/client";
|
|
30
|
-
*
|
|
31
|
-
* const client = createClient<typeof ba>({
|
|
32
|
-
* baseURL: "http://localhost:3000/api",
|
|
33
|
-
* secret: "dev_secret",
|
|
34
|
-
* toolHandlers: {
|
|
35
|
-
* getClientTime: () => ({ now: new Date().toISOString() }),
|
|
36
|
-
* },
|
|
37
|
-
* });
|
|
38
|
-
*
|
|
39
|
-
* for await (const event of client.stream("helloAgent", {
|
|
40
|
-
* input: "Use tools if needed.",
|
|
41
|
-
* })) {
|
|
42
|
-
* console.log(event.type);
|
|
43
|
-
* }
|
|
44
|
-
* ```
|
|
45
|
-
*/
|
|
46
|
-
declare const createClient: <TApp = unknown>(config: ClientConfig<TApp>) => BetterAgentClient<NormalizeClientApp<TApp>>;
|
|
4
|
+
//#region src/create-client.d.ts
|
|
5
|
+
declare function createClient<TApp = unknown>(config: BetterAgentClientConfig): BetterAgentClient<TApp>;
|
|
47
6
|
//#endregion
|
|
48
|
-
//#region src/
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
*/
|
|
52
|
-
declare class AgentChatController<TApp = unknown, TAgentName extends AgentNameFromApp<TApp> = AgentNameFromApp<TApp>> {
|
|
53
|
-
private client;
|
|
54
|
-
private readonly id;
|
|
55
|
-
private state;
|
|
56
|
-
private status;
|
|
57
|
-
private error;
|
|
58
|
-
private lastStreamId;
|
|
59
|
-
private lastRunId;
|
|
60
|
-
private lastResponse;
|
|
61
|
-
private lastStructured;
|
|
62
|
-
private lastAppliedSeq;
|
|
63
|
-
private lastAppliedSeqByStream;
|
|
64
|
-
private initialMessages;
|
|
65
|
-
private listeners;
|
|
66
|
-
private destroyed;
|
|
67
|
-
private initialized;
|
|
68
|
-
private warnedHistoryCombo;
|
|
69
|
-
private options;
|
|
70
|
-
private activeAbortController;
|
|
71
|
-
constructor(client: BetterAgentClient<TApp>, options: AgentChatControllerOptions<TApp, TAgentName>);
|
|
72
|
-
/** Returns the current messages. */
|
|
73
|
-
getMessages(): UIMessage[];
|
|
74
|
-
/** Returns the current status. */
|
|
75
|
-
getStatus(): AgentStatus;
|
|
76
|
-
/** Returns the latest client error. */
|
|
77
|
-
getError(): AgentClientError | undefined;
|
|
78
|
-
/** Returns the latest stream id. */
|
|
79
|
-
getStreamId(): string | undefined;
|
|
80
|
-
/** Returns the latest run id. */
|
|
81
|
-
getRunId(): string | undefined;
|
|
82
|
-
/** True while a request is active. */
|
|
83
|
-
get isLoading(): boolean;
|
|
84
|
-
/** True while stream events are being consumed. */
|
|
85
|
-
get isStreaming(): boolean;
|
|
86
|
-
/** Returns pending tool approvals. */
|
|
87
|
-
getPendingToolApprovals(): PendingToolApproval[];
|
|
88
|
-
/** Returns an immutable snapshot. */
|
|
89
|
-
getSnapshot(): AgentChatSnapshot;
|
|
90
|
-
/** Stops the active run or stream. */
|
|
91
|
-
stop(): void;
|
|
92
|
-
/** Replaces the transport client. */
|
|
93
|
-
updateClient(client: BetterAgentClient<TApp>): void;
|
|
94
|
-
/**
|
|
95
|
-
* Subscribes to state updates.
|
|
96
|
-
*/
|
|
97
|
-
subscribe(listener: () => void): () => void;
|
|
98
|
-
/** Calls each subscribed listener after controller state changes. */
|
|
99
|
-
private notify;
|
|
100
|
-
/** Stores run and stream ids from response headers. */
|
|
101
|
-
private updateResponseIds;
|
|
102
|
-
/** Starts hydration or resume behavior. */
|
|
103
|
-
init(): void;
|
|
104
|
-
/** Starts resume behavior, even with messages when allowed. */
|
|
105
|
-
private initResume;
|
|
106
|
-
/** Hydrates from server history before resuming. */
|
|
107
|
-
private hydrateFromServer;
|
|
108
|
-
/** Sends one message. */
|
|
109
|
-
sendMessage(input: ControllerRunInput, options?: SendMessageOptions): Promise<SendResult>;
|
|
110
|
-
/** Retries a user message by local id. */
|
|
111
|
-
retryMessage(localId: string): Promise<RetryResult>;
|
|
112
|
-
/** Resumes an existing stream. */
|
|
113
|
-
resumeStream(options: {
|
|
114
|
-
streamId: string;
|
|
115
|
-
afterSeq?: number;
|
|
116
|
-
}): Promise<void>;
|
|
117
|
-
/** Resumes the active stream for the current conversation. */
|
|
118
|
-
resumeConversation(options?: {
|
|
119
|
-
afterSeq?: number;
|
|
120
|
-
}): Promise<void>;
|
|
121
|
-
/** Submits a tool approval decision. */
|
|
122
|
-
approveToolCall(params: ApproveToolCallParams): Promise<void>;
|
|
123
|
-
/** Clears the current error. */
|
|
124
|
-
clearError(): void;
|
|
125
|
-
/** Resets local state to the initial snapshot. */
|
|
126
|
-
reset(): void;
|
|
127
|
-
/** Replaces local messages. */
|
|
128
|
-
setMessages(value: SetMessagesInput): void;
|
|
129
|
-
/** Merges new options into the controller configuration. */
|
|
130
|
-
updateOptions(partial: Partial<AgentChatControllerOptions<TApp, TAgentName>>): void;
|
|
131
|
-
/** Destroys the controller. */
|
|
132
|
-
destroy(): void;
|
|
133
|
-
/** Applies one streamed event to local state. */
|
|
134
|
-
private applyEvent;
|
|
135
|
-
/** Reads streamed events until the stream finishes or a terminal event appears. */
|
|
136
|
-
private consumeStreamUntilTerminal;
|
|
137
|
-
/** Reads terminal state from one streamed event. */
|
|
138
|
-
private getTerminalStateFromEvent;
|
|
139
|
-
/** Sends one request through final or stream delivery. */
|
|
140
|
-
private submitWithInternalOptions;
|
|
141
|
-
/** Builds the mutable context for one submission. */
|
|
142
|
-
private createSubmissionContext;
|
|
143
|
-
/** Warns when client history will replace stored server history. */
|
|
144
|
-
private warnIfClientHistoryReplacesConversation;
|
|
145
|
-
/** Applies retry replacement or optimistic user insertion. */
|
|
146
|
-
private applyLocalSubmissionState;
|
|
147
|
-
/** Builds the request input for the next transport call. */
|
|
148
|
-
private buildRequestInput;
|
|
149
|
-
/** Runs one request through final delivery. */
|
|
150
|
-
private runFinalDelivery;
|
|
151
|
-
/** Runs one request through streamed delivery. */
|
|
152
|
-
private runStreamDelivery;
|
|
153
|
-
/** Handles aborts, fallback-to-run, and terminal submission errors. */
|
|
154
|
-
private handleSubmissionFailure;
|
|
155
|
-
/** Marks the optimistic user message as sent after a successful request. */
|
|
156
|
-
private markOptimisticMessageSent;
|
|
157
|
-
/** Applies optimistic-message failure handling. */
|
|
158
|
-
private applyOptimisticFailure;
|
|
159
|
-
/** Stores the latest run result from final delivery. */
|
|
160
|
-
private captureNormalizedRunResult;
|
|
161
|
-
private setStatus;
|
|
162
|
-
/** Stores the latest controller error without notifying listeners. */
|
|
163
|
-
private setError;
|
|
164
|
-
/** Normalizes unknown failures into an `Error` with a fallback message. */
|
|
165
|
-
private toError;
|
|
166
|
-
/** Starts one controller operation. */
|
|
167
|
-
private startOperation;
|
|
168
|
-
/** Clears the tracked active operation if it matches the provided controller. */
|
|
169
|
-
private finishOperation;
|
|
170
|
-
/** Aborts and forgets any in-flight controller operation. */
|
|
171
|
-
private cancelActiveWork;
|
|
172
|
-
/** Merges the controller abort signal with an optional external signal. */
|
|
173
|
-
private mergeSignals;
|
|
174
|
-
/** Throws an abort-shaped error when the given signal has already aborted. */
|
|
175
|
-
private throwIfAborted;
|
|
176
|
-
/** Rejects work after the controller has been destroyed. */
|
|
177
|
-
private throwIfDestroyed;
|
|
178
|
-
/** Returns `true` when a failure should be treated as an abort. */
|
|
179
|
-
private isAbortError;
|
|
180
|
-
/** Returns true when a failure came from stream disconnection. */
|
|
181
|
-
private isStreamDisconnectError;
|
|
182
|
-
/** Returns true when the page is being torn down during navigation or refresh. */
|
|
183
|
-
private isPageTeardownLike;
|
|
184
|
-
/** Converts an abort reason into a standard `AbortError` instance. */
|
|
185
|
-
private toAbortError;
|
|
186
|
-
/** Wraps one failure as a stream disconnect. */
|
|
187
|
-
private toStreamDisconnectError;
|
|
188
|
-
/** Binds an already-visible current user turn to the replay run identity. */
|
|
189
|
-
private reconcileReplayUserMessage;
|
|
190
|
-
/** Reconstructs the replayed current user turn from one RUN_STARTED event. */
|
|
191
|
-
private toReplayUserMessage;
|
|
192
|
-
/** Detects one structured replay message item. */
|
|
193
|
-
private isSingleReplayMessageInput;
|
|
194
|
-
/** Matches one already-visible user turn to its replayed equivalent. */
|
|
195
|
-
private isSameUserTurn;
|
|
196
|
-
/** Generates a local message id using the configured factory when present. */
|
|
197
|
-
private generateMessageId;
|
|
198
|
-
/** Ensures every incoming UI message has a stable local id. */
|
|
199
|
-
private normalizeMessages;
|
|
200
|
-
/** Detects option changes that require resetting conversation session state. */
|
|
201
|
-
private hasSessionConfigurationChanged;
|
|
202
|
-
/** Resets controller state after a session-defining option changes. */
|
|
203
|
-
private resetForSessionChange;
|
|
204
|
-
/** Reads the initial resume stream id from controller options. */
|
|
205
|
-
private getConfiguredInitialStreamId;
|
|
206
|
-
/** Returns one message by local id from the current message state. */
|
|
207
|
-
private getMessageByLocalId;
|
|
208
|
-
/** Updates one message by local id and notifies listeners when found. */
|
|
209
|
-
private updateMessageByLocalId;
|
|
210
|
-
/** Removes one local message from state and notifies listeners. */
|
|
211
|
-
private removeMessageByLocalId;
|
|
212
|
-
/** Resolves the effective delivery mode for the next submission. */
|
|
213
|
-
private shouldUseStreamDelivery;
|
|
214
|
-
/** Detects stream capability errors that should retry through `run()`. */
|
|
215
|
-
private shouldFallbackToRun;
|
|
216
|
-
/** Appends model response messages to local state after final delivery. */
|
|
217
|
-
private appendResponseMessages;
|
|
218
|
-
/** Normalizes supported final-run response shapes into one controller shape. */
|
|
219
|
-
private normalizeFinalRunResult;
|
|
220
|
-
/** Builds the input payload, optionally serializing client history into it. */
|
|
221
|
-
private prepareInputForRequest;
|
|
222
|
-
/** Builds the run payload for one request. */
|
|
223
|
-
private createRunPayload;
|
|
224
|
-
/** Builds stream request hooks for ids, callbacks, and optimistic updates. */
|
|
225
|
-
private buildStreamRequestOptions;
|
|
226
|
-
/** Replaces one user message slot with a pending retry version. */
|
|
227
|
-
private replaceRetryMessage;
|
|
228
|
-
/** Derives a pending user message from retry input when possible. */
|
|
229
|
-
private createPendingUserMessage;
|
|
230
|
-
/** Normalizes supported input shapes into input items when possible. */
|
|
231
|
-
private normalizeInputItems;
|
|
232
|
-
/** Returns true when input is safely representable as one optimistic user turn. */
|
|
233
|
-
private canOptimisticallyRenderUserTurn;
|
|
234
|
-
/** Returns true when serialized history can reuse the optimistic user turn. */
|
|
235
|
-
private canOmitSubmittedInputFromSerializedHistory;
|
|
236
|
-
/** Calls `onFinish` with the latest completion data. */
|
|
237
|
-
private emitFinish;
|
|
238
|
-
}
|
|
239
|
-
/**
|
|
240
|
-
* Creates an `AgentChatController`.
|
|
241
|
-
*/
|
|
242
|
-
declare function createAgentChatController<TApp, TAgentName extends AgentNameFromApp<TApp> = AgentNameFromApp<TApp>>(client: BetterAgentClient<TApp>, options: AgentChatControllerOptions<TApp, TAgentName>): AgentChatController<TApp, TAgentName>;
|
|
7
|
+
//#region src/ui/convert.d.ts
|
|
8
|
+
declare const fromAgentMessages: (messages: AgentMessage[]) => UIMessage[];
|
|
9
|
+
declare const toAgentMessages: (messages: UIMessage[]) => AgentMessage[];
|
|
243
10
|
//#endregion
|
|
244
|
-
|
|
245
|
-
/** Converts UI messages into model input messages. */
|
|
246
|
-
declare const toModelMessages: (msgs: UIMessage[]) => Array<GenerativeModelInputItem<{
|
|
247
|
-
inputModalities: {
|
|
248
|
-
text: true;
|
|
249
|
-
audio: true;
|
|
250
|
-
image: true;
|
|
251
|
-
file: true;
|
|
252
|
-
video: true;
|
|
253
|
-
};
|
|
254
|
-
additionalSupportedRoles: readonly string[];
|
|
255
|
-
}>>;
|
|
256
|
-
/** Converts model input messages back into UI messages. */
|
|
257
|
-
declare const fromModelMessages: (messages: GenerativeModelInputItem[], options?: {
|
|
258
|
-
generateId?: () => string;
|
|
259
|
-
}) => UIMessage[];
|
|
260
|
-
/** Converts durable conversation items back into UI messages. */
|
|
261
|
-
declare const fromConversationItems: (items: ConversationItem[], options?: {
|
|
262
|
-
generateId?: () => string;
|
|
263
|
-
}) => UIMessage[];
|
|
264
|
-
//#endregion
|
|
265
|
-
export { type AgentChatController, type AgentChatControllerOptions, type AgentChatSnapshot, type AgentClientError, type AgentContext, type AgentNameFromApp, type AgentRunInput, type AgentStatus, type AgentsFromApp, type ApproveToolCallParams, type AudioPart, type BetterAgentClient, type ClientConfig, type ClientEvent, type EmbeddingPart, type FilePart, type ImagePart, type InferClient, type ModalitiesForAgent, type NormalizeClientApp, type OnFinishParams, type OnToolCall, type PendingToolApproval, type PrepareMessages, type ReasoningPart, type ReplayInput, type RequestOptions, type ResumeOption, type RetryResult, type RunInputForAgent, type SendMessageOptions, type SendResult, type SetMessagesInput, type StreamRequestOptions, type SubmitInput, type SubmitToolApprovalRequest, type SubmitToolResultRequest, type TextInputShorthandForAgent, type TextPart, type ToolCallContext, type ToolCallPart, type ToolCallRequest, type ToolHandlers, type ToolResultPart, type TranscriptPart, type UIMessage, type UIMessageInput, type UIMessagePart, type VideoPart, createAgentChatController, createClient, fromConversationItems, fromModelMessages, getEventErrorMessage, pruneInputByCapabilities, toAgentClientError, toModelMessages };
|
|
11
|
+
export { type AgentContextFor, AgentController, type AgentControllerFinish, type AgentControllerLifecycleHooks, type AgentControllerOptions, type AgentControllerSnapshot, type AgentControllerStatus, type AgentInterruptState, type AgentMessageInput, type AgentNameOf, type AgentStreamResume, type AudioUIPart, type BetterAgentClient, type BetterAgentClientAgentHandle, type BetterAgentClientAgentMemoryHandle, type BetterAgentClientConfig, BetterAgentClientError, type BetterAgentClientMemory, type BetterAgentClientRuns, type ClientMemoryThread, type ClientMemoryThreadCreateInput, type ClientMemoryThreadUpdateInput, type ClientRunInput, type FileUIPart, type ImageUIPart, type PendingClientTool, type PendingToolApproval, type PreparedRequest, type ReasoningUIPart, type RequestOptions, type SendOptions, type SourceUIPart, type TextUIPart, type ToolCallState, type ToolCallUIPart, type ToolHandlersFor, type ToolResultState, type ToolResultUIPart, type UIMessage, type UIMessagePart, type UIMessageRole, type VideoUIPart, createAgentController, createClient, fromAgentMessages, toAgentMessages, toBetterAgentClientError };
|
|
266
12
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/create-client.ts","../src/ui/convert.ts"],"mappings":";;;;iBAWgB,YAAA,gBAAA,CACZ,MAAA,EAAQ,uBAAA,GACT,iBAAA,CAAkB,IAAA;;;cCLR,iBAAA,GAAiB,QAAA,EAAc,YAAA,OAAiB,SAAA;AAAA,cA2KhD,eAAA,GAAe,QAAA,EAAc,SAAA,OAAc,YAAA"}
|