@assistant-ui/react-google-adk 0.0.13 → 0.0.15

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.
@@ -1 +1 @@
1
- {"version":3,"file":"AdkClient.js","names":[],"sources":["../src/AdkClient.ts"],"sourcesContent":["import { contentToParts } from \"./contentToParts\";\nimport type {\n AdkEvent,\n AdkEventPart,\n AdkMessage,\n AdkStreamCallback,\n} from \"./types\";\n\nexport type CreateAdkStreamOptions = {\n /**\n * URL to POST to. Either a proxy route (e.g. \"/api/adk\") or\n * an ADK server base URL (e.g. \"http://localhost:8000\").\n *\n * When `appName` and `userId` are provided, POSTs to `${api}/run_sse`\n * in ADK-native format. Otherwise POSTs directly to `api` in proxy format\n * (compatible with `parseAdkRequest`).\n */\n api: string;\n\n /**\n * ADK application name. When provided along with `userId`,\n * enables direct connection to an ADK server.\n */\n appName?: string | undefined;\n\n /**\n * ADK user ID. Required when `appName` is provided.\n */\n userId?: string | undefined;\n\n /**\n * Extra headers to send with every request.\n * Can be a static object or an async function for dynamic auth tokens.\n */\n headers?:\n | Record<string, string>\n | (() => Record<string, string> | Promise<Record<string, string>>)\n | undefined;\n};\n\n/**\n * Creates an `AdkStreamCallback` that connects to an ADK endpoint.\n *\n * @example Proxy mode (with a Next.js API route)\n * ```ts\n * const stream = createAdkStream({ api: \"/api/adk\" });\n * ```\n *\n * @example Direct mode (connecting to ADK server)\n * ```ts\n * const stream = createAdkStream({\n * api: \"http://localhost:8000\",\n * appName: \"my-app\",\n * userId: \"user-1\",\n * });\n * ```\n */\nexport function createAdkStream(\n options: CreateAdkStreamOptions,\n): AdkStreamCallback {\n const isDirect = options.appName != null;\n\n return async function* (messages, config) {\n const headers = await resolveHeaders(options.headers);\n\n let url: string;\n let body: unknown;\n\n if (isDirect) {\n // Direct mode: POST to ADK server's /run_sse\n url = `${options.api}/run_sse`;\n const { externalId } = await config.initialize();\n body = {\n appName: options.appName,\n userId: options.userId,\n sessionId: externalId,\n newMessage: messagesToContent(messages),\n streaming: true,\n ...(config.stateDelta != null && { stateDelta: config.stateDelta }),\n };\n } else {\n // Proxy mode: POST in parseAdkRequest-compatible format\n url = options.api;\n body = messagesToProxyBody(messages, config);\n }\n\n const response = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", ...headers },\n body: JSON.stringify(body),\n signal: config.abortSignal,\n });\n\n if (!response.ok) {\n throw new Error(\n `ADK request failed: ${response.status} ${response.statusText}`,\n );\n }\n\n yield* parseSSEResponse(response);\n };\n}\n\n// ── Internal helpers ──\n\nasync function resolveHeaders(\n headers:\n | Record<string, string>\n | (() => Record<string, string> | Promise<Record<string, string>>)\n | undefined,\n): Promise<Record<string, string>> {\n if (!headers) return {};\n if (typeof headers === \"function\") return await headers();\n return headers;\n}\n\n/**\n * Converts AdkMessage[] (new messages) into ADK Content format\n * for the direct `/run_sse` endpoint.\n */\nfunction messagesToContent(messages: AdkMessage[]): {\n role: string;\n parts: AdkEventPart[];\n} {\n const parts: AdkEventPart[] = [];\n\n for (const msg of messages) {\n if (msg.type === \"human\") {\n for (const part of contentToParts(msg.content)) {\n parts.push(part);\n }\n } else if (msg.type === \"tool\") {\n let response: unknown;\n try {\n response = JSON.parse(msg.content);\n } catch {\n response = msg.content;\n }\n parts.push({\n functionResponse: {\n name: msg.name,\n id: msg.tool_call_id,\n response,\n },\n });\n }\n }\n\n if (parts.length === 0) {\n parts.push({ text: \"\" });\n }\n\n return { role: \"user\", parts };\n}\n\n/**\n * Converts AdkMessage[] into the proxy request body format\n * (compatible with `parseAdkRequest`).\n */\nfunction messagesToProxyBody(\n messages: AdkMessage[],\n config: {\n runConfig?: unknown;\n checkpointId?: string | undefined;\n stateDelta?: Record<string, unknown> | undefined;\n },\n): Record<string, unknown> {\n const body: Record<string, unknown> = {};\n\n if (config.runConfig != null) body.runConfig = config.runConfig;\n if (config.checkpointId != null) body.checkpointId = config.checkpointId;\n if (config.stateDelta != null) body.stateDelta = config.stateDelta;\n\n // Check if there's a tool result\n const toolMsg = messages.find((m) => m.type === \"tool\");\n if (toolMsg && toolMsg.type === \"tool\") {\n // If there are also other messages (e.g. cancellations), send as parts\n if (messages.length > 1) {\n body.parts = messagesToContent(messages).parts;\n return body;\n }\n\n let result: unknown;\n try {\n result = JSON.parse(toolMsg.content);\n } catch {\n result = toolMsg.content;\n }\n body.type = \"tool-result\";\n body.toolCallId = toolMsg.tool_call_id;\n body.toolName = toolMsg.name;\n body.result = result;\n body.isError = toolMsg.status === \"error\";\n return body;\n }\n\n // Human message(s) - possibly with cancellation tool results prepended\n if (messages.length === 1 && messages[0]!.type === \"human\") {\n const msg = messages[0]!;\n if (typeof msg.content === \"string\") {\n body.message = msg.content;\n } else {\n body.parts = contentToParts(msg.content);\n }\n return body;\n }\n\n // Multiple messages (e.g. cancellations + human): send as parts array\n body.parts = messagesToContent(messages).parts;\n return body;\n}\n\nasync function* parseSSEResponse(response: Response): AsyncGenerator<AdkEvent> {\n const reader = response.body!.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const parts = buffer.split(\"\\n\\n\");\n buffer = parts.pop() ?? \"\";\n\n for (const part of parts) {\n for (const line of part.split(\"\\n\")) {\n if (line.startsWith(\"data: \")) {\n yield JSON.parse(line.slice(6)) as AdkEvent;\n }\n }\n }\n }\n\n // Handle remaining buffer\n if (buffer.trim()) {\n for (const line of buffer.split(\"\\n\")) {\n if (line.startsWith(\"data: \")) {\n yield JSON.parse(line.slice(6)) as AdkEvent;\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"AdkClient.js","names":[],"sources":["../src/AdkClient.ts"],"sourcesContent":["import { contentToParts } from \"./contentToParts\";\nimport type {\n AdkEvent,\n AdkEventPart,\n AdkMessage,\n AdkStreamCallback,\n} from \"./types\";\n\nexport type CreateAdkStreamOptions = {\n /**\n * URL to POST to. Either a proxy route (e.g. \"/api/adk\") or\n * an ADK server base URL (e.g. \"http://localhost:8000\").\n *\n * When `appName` and `userId` are provided, POSTs to `${api}/run_sse`\n * in ADK-native format. Otherwise POSTs directly to `api` in proxy format\n * (compatible with `parseAdkRequest`).\n */\n api: string;\n\n /**\n * ADK application name. When provided along with `userId`,\n * enables direct connection to an ADK server.\n */\n appName?: string | undefined;\n\n /**\n * ADK user ID. Required when `appName` is provided.\n */\n userId?: string | undefined;\n\n /**\n * Extra headers to send with every request.\n * Can be a static object or an async function for dynamic auth tokens.\n */\n headers?:\n | Record<string, string>\n | (() => Record<string, string> | Promise<Record<string, string>>)\n | undefined;\n};\n\n/**\n * Creates an `AdkStreamCallback` that connects to an ADK endpoint.\n *\n * @example Proxy mode (with a Next.js API route)\n * ```ts\n * const stream = createAdkStream({ api: \"/api/adk\" });\n * ```\n *\n * @example Direct mode (connecting to ADK server)\n * ```ts\n * const stream = createAdkStream({\n * api: \"http://localhost:8000\",\n * appName: \"my-app\",\n * userId: \"user-1\",\n * });\n * ```\n */\nexport function createAdkStream(\n options: CreateAdkStreamOptions,\n): AdkStreamCallback {\n const isDirect = options.appName != null;\n\n return async function* (messages, config) {\n const headers = await resolveHeaders(options.headers);\n\n let url: string;\n let body: unknown;\n\n if (isDirect) {\n // Direct mode: POST to ADK server's /run_sse\n url = `${options.api}/run_sse`;\n const { externalId } = await config.initialize();\n body = {\n appName: options.appName,\n userId: options.userId,\n sessionId: externalId,\n newMessage: messagesToContent(messages),\n streaming: true,\n ...(config.stateDelta != null && { stateDelta: config.stateDelta }),\n };\n } else {\n // Proxy mode: POST in parseAdkRequest-compatible format\n url = options.api;\n body = messagesToProxyBody(messages, config);\n }\n\n const response = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", ...headers },\n body: JSON.stringify(body),\n signal: config.abortSignal,\n });\n\n if (!response.ok) {\n throw new Error(\n `ADK request failed: ${response.status} ${response.statusText}`,\n );\n }\n\n yield* parseSSEResponse(response);\n };\n}\n\n// ── Internal helpers ──\n\nasync function resolveHeaders(\n headers:\n | Record<string, string>\n | (() => Record<string, string> | Promise<Record<string, string>>)\n | undefined,\n): Promise<Record<string, string>> {\n if (!headers) return {};\n if (typeof headers === \"function\") return await headers();\n return headers;\n}\n\n/**\n * Converts AdkMessage[] (new messages) into ADK Content format\n * for the direct `/run_sse` endpoint.\n */\nfunction messagesToContent(messages: AdkMessage[]): {\n role: string;\n parts: AdkEventPart[];\n} {\n const parts: AdkEventPart[] = [];\n\n for (const msg of messages) {\n if (msg.type === \"human\") {\n for (const part of contentToParts(msg.content)) {\n parts.push(part);\n }\n } else if (msg.type === \"tool\") {\n let response: unknown;\n try {\n response = JSON.parse(msg.content);\n } catch {\n response = msg.content;\n }\n parts.push({\n functionResponse: {\n name: msg.name,\n id: msg.tool_call_id,\n response,\n },\n });\n }\n }\n\n if (parts.length === 0) {\n parts.push({ text: \"\" });\n }\n\n return { role: \"user\", parts };\n}\n\n/**\n * Converts AdkMessage[] into the proxy request body format\n * (compatible with `parseAdkRequest`).\n */\nfunction messagesToProxyBody(\n messages: AdkMessage[],\n config: {\n runConfig?: unknown;\n checkpointId?: string | undefined;\n stateDelta?: Record<string, unknown> | undefined;\n },\n): Record<string, unknown> {\n const body: Record<string, unknown> = {};\n\n if (config.runConfig != null) body.runConfig = config.runConfig;\n if (config.checkpointId != null) body.checkpointId = config.checkpointId;\n if (config.stateDelta != null) body.stateDelta = config.stateDelta;\n\n // Check if there's a tool result\n const toolMsg = messages.find((m) => m.type === \"tool\");\n if (toolMsg && toolMsg.type === \"tool\") {\n // If there are also other messages (e.g. cancellations), send as parts\n if (messages.length > 1) {\n body.parts = messagesToContent(messages).parts;\n return body;\n }\n\n let result: unknown;\n try {\n result = JSON.parse(toolMsg.content);\n } catch {\n result = toolMsg.content;\n }\n body.type = \"tool-result\";\n body.toolCallId = toolMsg.tool_call_id;\n body.toolName = toolMsg.name;\n body.result = result;\n body.isError = toolMsg.status === \"error\";\n return body;\n }\n\n // Human message(s) - possibly with cancellation tool results prepended\n if (messages.length === 1 && messages[0]!.type === \"human\") {\n const msg = messages[0]!;\n if (typeof msg.content === \"string\") {\n body.message = msg.content;\n } else {\n body.parts = contentToParts(msg.content);\n }\n return body;\n }\n\n // Multiple messages (e.g. cancellations + human): send as parts array\n body.parts = messagesToContent(messages).parts;\n return body;\n}\n\nasync function* parseSSEResponse(response: Response): AsyncGenerator<AdkEvent> {\n const reader = response.body!.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const parts = buffer.split(\"\\n\\n\");\n buffer = parts.pop() ?? \"\";\n\n for (const part of parts) {\n for (const line of part.split(\"\\n\")) {\n if (line.startsWith(\"data: \")) {\n yield JSON.parse(line.slice(6)) as AdkEvent;\n }\n }\n }\n }\n\n // Handle remaining buffer\n if (buffer.trim()) {\n for (const line of buffer.split(\"\\n\")) {\n if (line.startsWith(\"data: \")) {\n yield JSON.parse(line.slice(6)) as AdkEvent;\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"AdkEventAccumulator.js","names":["uuidv4"],"sources":["../src/AdkEventAccumulator.ts"],"sourcesContent":["import { v4 as uuidv4 } from \"uuid\";\nimport type { MessageStatus } from \"@assistant-ui/core\";\nimport type {\n AdkEvent,\n AdkEventPart,\n AdkMessage,\n AdkMessageContentPart,\n AdkToolCall,\n AdkToolConfirmation,\n AdkAuthRequest,\n AdkMessageMetadata,\n} from \"./types\";\nimport type { ReadonlyJSONObject } from \"assistant-stream/utils\";\n\ntype InProgressMessage = AdkMessage & { type: \"ai\" };\n\nconst ADK_REQUEST_CONFIRMATION = \"adk_request_confirmation\";\nconst ADK_REQUEST_CREDENTIAL = \"adk_request_credential\";\n\n/**\n * Checks if an event is a final response using the same logic as ADK's\n * `isFinalResponse()`.\n */\nexport const isFinalResponse = (event: AdkEvent): boolean => {\n if (\n event.actions?.skipSummarization ||\n (event.longRunningToolIds && event.longRunningToolIds.length > 0)\n ) {\n return true;\n }\n\n const parts = event.content?.parts;\n return (\n !event.partial &&\n (parts?.length ?? 0) > 0 &&\n !parts!.some((p) => p.functionCall) &&\n !parts!.some((p) => p.functionResponse) &&\n !parts![parts!.length - 1]?.codeExecutionResult\n );\n};\n\nconst CONTENT_FILTER_REASONS = new Set([\n \"SAFETY\",\n \"RECITATION\",\n \"BLOCKLIST\",\n \"PROHIBITED_CONTENT\",\n \"SPII\",\n \"LANGUAGE\",\n \"IMAGE_SAFETY\",\n \"IMAGE_RECITATION\",\n \"IMAGE_OTHER\",\n \"IMAGE_PROHIBITED_CONTENT\",\n]);\n\nconst ERROR_REASONS = new Set([\n \"MALFORMED_FUNCTION_CALL\",\n \"UNEXPECTED_TOOL_CALL\",\n]);\n\nconst finishReasonToStatus = (\n finishReason: string | undefined,\n): MessageStatus => {\n if (finishReason === \"MAX_TOKENS\") {\n return { type: \"incomplete\", reason: \"length\" };\n }\n if (finishReason && CONTENT_FILTER_REASONS.has(finishReason)) {\n return {\n type: \"incomplete\",\n reason: \"content-filter\",\n error: `Content filtered: ${finishReason}`,\n };\n }\n if (finishReason && ERROR_REASONS.has(finishReason)) {\n return {\n type: \"incomplete\",\n reason: \"error\",\n error: `LLM error: ${finishReason}`,\n };\n }\n return { type: \"complete\", reason: \"stop\" };\n};\n\nconst inlineDataToPart = (\n mimeType: string,\n data: string,\n): AdkMessageContentPart =>\n mimeType.startsWith(\"image/\")\n ? { type: \"image\", mimeType, data }\n : { type: \"file\", mimeType, data };\n\nconst fileDataToPart = (\n fileUri: string,\n mimeType: string | undefined,\n): AdkMessageContentPart =>\n mimeType == null || mimeType.startsWith(\"image/\")\n ? { type: \"image_url\", url: fileUri }\n : { type: \"file_url\", url: fileUri, mimeType };\n\n// ── Snake_case normalization ──\n\nconst normalizeEventPart = (part: AdkEventPart): AdkEventPart => {\n const p = part as Record<string, unknown>;\n const result: Record<string, unknown> = { ...p };\n if (\"function_call\" in p && !(\"functionCall\" in p))\n result.functionCall = p.function_call;\n if (\"function_response\" in p && !(\"functionResponse\" in p))\n result.functionResponse = p.function_response;\n if (\"inline_data\" in p && !(\"inlineData\" in p))\n result.inlineData = p.inline_data;\n if (\"file_data\" in p && !(\"fileData\" in p)) result.fileData = p.file_data;\n if (\"executable_code\" in p && !(\"executableCode\" in p))\n result.executableCode = p.executable_code;\n if (\"code_execution_result\" in p && !(\"codeExecutionResult\" in p))\n result.codeExecutionResult = p.code_execution_result;\n return result as AdkEventPart;\n};\n\nconst normalizeEvent = (event: AdkEvent): AdkEvent => {\n const e = event as Record<string, unknown>;\n const result: Record<string, unknown> = { ...e };\n if (\"error_code\" in e && !(\"errorCode\" in e)) result.errorCode = e.error_code;\n if (\"error_message\" in e && !(\"errorMessage\" in e))\n result.errorMessage = e.error_message;\n if (\"long_running_tool_ids\" in e && !(\"longRunningToolIds\" in e))\n result.longRunningToolIds = e.long_running_tool_ids;\n if (\"turn_complete\" in e && !(\"turnComplete\" in e))\n result.turnComplete = e.turn_complete;\n if (\"finish_reason\" in e && !(\"finishReason\" in e))\n result.finishReason = e.finish_reason;\n if (\"invocation_id\" in e && !(\"invocationId\" in e))\n result.invocationId = e.invocation_id;\n if (\"custom_metadata\" in e && !(\"customMetadata\" in e))\n result.customMetadata = e.custom_metadata;\n if (\"grounding_metadata\" in e && !(\"groundingMetadata\" in e))\n result.groundingMetadata = e.grounding_metadata;\n if (\"citation_metadata\" in e && !(\"citationMetadata\" in e))\n result.citationMetadata = e.citation_metadata;\n if (\"usage_metadata\" in e && !(\"usageMetadata\" in e))\n result.usageMetadata = e.usage_metadata;\n\n if (result.actions) {\n const a = result.actions as Record<string, unknown>;\n const na: Record<string, unknown> = { ...a };\n if (\"state_delta\" in a && !(\"stateDelta\" in a))\n na.stateDelta = a.state_delta;\n if (\"artifact_delta\" in a && !(\"artifactDelta\" in a))\n na.artifactDelta = a.artifact_delta;\n if (\"transfer_to_agent\" in a && !(\"transferToAgent\" in a))\n na.transferToAgent = a.transfer_to_agent;\n if (\"skip_summarization\" in a && !(\"skipSummarization\" in a))\n na.skipSummarization = a.skip_summarization;\n if (\"requested_auth_configs\" in a && !(\"requestedAuthConfigs\" in a))\n na.requestedAuthConfigs = a.requested_auth_configs;\n if (\n \"requested_tool_confirmations\" in a &&\n !(\"requestedToolConfirmations\" in a)\n )\n na.requestedToolConfirmations = a.requested_tool_confirmations;\n result.actions = na;\n }\n\n if (result.content && (result.content as Record<string, unknown>).parts) {\n const content = result.content as Record<string, unknown>;\n const parts = content.parts as AdkEventPart[];\n result.content = { ...content, parts: parts.map(normalizeEventPart) };\n }\n\n return result as AdkEvent;\n};\n\n// ── Accumulator ──\n\nexport class AdkEventAccumulator {\n private messagesMap = new Map<string, AdkMessage>();\n private currentMessageId: string | null = null;\n private partialTextBuffer = \"\";\n private partialReasoningBuffer = \"\";\n private accumulatedStateDelta: Record<string, unknown> = {};\n private accumulatedArtifactDelta: Record<string, number> = {};\n private lastAgentInfo: {\n name?: string | undefined;\n branch?: string | undefined;\n } = {};\n private lastTransferToAgent: string | undefined;\n private pendingLongRunningToolIds = new Set<string>();\n private toolConfirmations: AdkToolConfirmation[] = [];\n private authRequests: AdkAuthRequest[] = [];\n private escalated = false;\n private messageMetadataMap = new Map<string, AdkMessageMetadata>();\n constructor(initialMessages?: AdkMessage[]) {\n if (initialMessages) {\n for (const msg of initialMessages) {\n this.messagesMap.set(msg.id, msg);\n }\n }\n }\n\n processEvent(rawEvent: AdkEvent): AdkMessage[] {\n const event = normalizeEvent(rawEvent);\n\n // Accumulate state delta\n if (event.actions?.stateDelta) {\n Object.assign(this.accumulatedStateDelta, event.actions.stateDelta);\n }\n\n // Accumulate artifact delta\n if (event.actions?.artifactDelta) {\n Object.assign(this.accumulatedArtifactDelta, event.actions.artifactDelta);\n }\n\n // Track escalation\n if (event.actions?.escalate) {\n this.escalated = true;\n }\n\n // Track agent transfer\n if (event.actions?.transferToAgent) {\n this.lastTransferToAgent = event.actions.transferToAgent;\n }\n\n // Track long-running tool IDs. Accumulate across events so that multiple\n // HITL interrupts emitted in the same turn are all tracked — a\n // single-event replacement would drop earlier ids.\n if (event.longRunningToolIds?.length) {\n for (const id of event.longRunningToolIds) {\n this.pendingLongRunningToolIds.add(id);\n }\n }\n\n // Track tool confirmations from actions\n if (event.actions?.requestedToolConfirmations) {\n for (const [tcId, conf] of Object.entries(\n event.actions.requestedToolConfirmations,\n )) {\n const c = conf as Record<string, unknown>;\n this.toolConfirmations.push({\n toolCallId: tcId,\n toolName: \"\",\n args: {},\n hint: (c.hint as string) ?? \"\",\n confirmed: false,\n payload: c.payload,\n });\n }\n }\n\n // Track auth requests from actions\n if (event.actions?.requestedAuthConfigs) {\n for (const [tcId, authConf] of Object.entries(\n event.actions.requestedAuthConfigs,\n )) {\n this.authRequests.push({ toolCallId: tcId, authConfig: authConf });\n }\n }\n\n // Track agent info\n if (event.author && event.author !== \"user\") {\n this.lastAgentInfo = {\n name: event.author ?? undefined,\n branch: event.branch ?? undefined,\n };\n }\n\n // Handle interrupted events\n if (event.interrupted) {\n if (this.currentMessageId) {\n const msg = this.messagesMap.get(this.currentMessageId);\n if (msg && msg.type === \"ai\" && !msg.status) {\n const updated: InProgressMessage = {\n ...msg,\n content: [...this.getContentArray(msg)],\n status: { type: \"incomplete\", reason: \"cancelled\" },\n };\n this.messagesMap.set(updated.id, updated);\n }\n }\n this.finalizeCurrentMessage();\n return this.getMessages();\n }\n\n // Handle error events\n if (event.errorCode || event.errorMessage) {\n this.finalizeCurrentMessage();\n const errorMsg = this.getOrCreateAiMessage(event);\n const errorText =\n event.errorMessage ?? event.errorCode ?? \"Unknown error\";\n const updated: InProgressMessage = {\n ...errorMsg,\n content: [\n ...this.getContentArray(errorMsg),\n { type: \"text\", text: errorText },\n ],\n status: { type: \"incomplete\", reason: \"error\", error: errorText },\n };\n this.messagesMap.set(updated.id, updated);\n this.currentMessageId = null;\n return this.getMessages();\n }\n\n const parts = event.content?.parts;\n if (!parts?.length) {\n // Track metadata even for content-less events (e.g. turnComplete)\n this.trackMessageMetadata(event);\n return this.getMessages();\n }\n\n // User-authored events → create human message, not AI.\n // Without this, user events fall through to processPart →\n // getOrCreateAiMessage, producing type:\"ai\" messages that\n // convertAdkMessage maps to role:\"assistant\".\n if (event.author === \"user\") {\n this.finalizeCurrentMessage();\n const humanParts: AdkMessageContentPart[] = [];\n for (const part of parts) {\n if (part.text != null && !part.thought) {\n humanParts.push({ type: \"text\", text: part.text });\n } else if (part.inlineData) {\n humanParts.push(\n inlineDataToPart(part.inlineData.mimeType, part.inlineData.data),\n );\n } else if (part.fileData) {\n humanParts.push(\n fileDataToPart(part.fileData.fileUri, part.fileData.mimeType),\n );\n }\n }\n if (humanParts.length > 0) {\n const id = event.id ?? uuidv4();\n const first = humanParts[0];\n const content: string | AdkMessageContentPart[] =\n humanParts.length === 1 && first?.type === \"text\"\n ? first.text\n : humanParts;\n this.messagesMap.set(id, { id, type: \"human\", content });\n }\n return this.getMessages();\n }\n\n // If author changed, finalize previous message\n if (this.currentMessageId && event.author && event.author !== \"user\") {\n const current = this.messagesMap.get(this.currentMessageId);\n if (current && current.type === \"ai\" && current.author !== event.author) {\n this.finalizeCurrentMessage();\n }\n }\n\n for (const part of parts) {\n this.processPart(part, event);\n }\n\n // Track per-message metadata (grounding, citation, usage)\n this.trackMessageMetadata(event);\n\n // Check isFinalResponse (can be true even for partial events via skipSummarization/longRunningToolIds)\n if (isFinalResponse(event) && this.currentMessageId) {\n const msg = this.messagesMap.get(this.currentMessageId);\n // Skip manual \"complete\" when longRunningToolIds is the sole reason for\n // isFinalResponse — let auto-status apply requires-action for pending tool calls.\n const isHitlOnly =\n event.longRunningToolIds &&\n event.longRunningToolIds.length > 0 &&\n !event.actions?.skipSummarization;\n if (msg && msg.type === \"ai\" && !msg.status && !isHitlOnly) {\n const status = finishReasonToStatus(event.finishReason);\n const updated: InProgressMessage = {\n ...msg,\n content: [...this.getContentArray(msg)],\n status,\n };\n this.messagesMap.set(updated.id, updated);\n }\n }\n\n // Non-partial event finalizes the current message\n if (!event.partial || isFinalResponse(event)) {\n this.finalizeCurrentMessage();\n }\n\n return this.getMessages();\n }\n\n private processPart(part: AdkEventPart, event: AdkEvent): void {\n // Detect special ADK function calls\n if (part.functionCall && !event.partial) {\n const name = part.functionCall.name;\n\n // Tool confirmation request\n if (name === ADK_REQUEST_CONFIRMATION) {\n const callArgs = part.functionCall.args;\n // ADK JS: args keys are \"originalFunctionCall\" and \"toolConfirmation\"\n // ADK Python: args keys are \"original_function_call\" and \"tool_confirmation\"\n const original =\n (callArgs.originalFunctionCall as Record<string, unknown>) ??\n (callArgs.original_function_call as Record<string, unknown>);\n const conf =\n (callArgs.toolConfirmation as Record<string, unknown>) ??\n (callArgs.tool_confirmation as Record<string, unknown>);\n this.toolConfirmations.push({\n toolCallId: part.functionCall.id ?? \"\",\n toolName: (original?.name as string) ?? \"\",\n args: (original?.args as Record<string, unknown>) ?? {},\n hint: (conf?.hint as string) ?? \"\",\n confirmed: false,\n payload: conf?.payload,\n });\n }\n\n // Auth credential request\n if (name === ADK_REQUEST_CREDENTIAL) {\n const credArgs = part.functionCall.args;\n // ADK JS: args keys are \"function_call_id\" and \"auth_config\"\n const originalToolCallId =\n (credArgs.function_call_id as string) ?? part.functionCall.id ?? \"\";\n const authConfig = credArgs.auth_config ?? credArgs;\n this.authRequests.push({\n toolCallId: originalToolCallId,\n authConfig,\n });\n }\n }\n\n // Text with thought=true → reasoning (accumulated)\n if (part.text != null && part.thought) {\n const msg = this.getOrCreateAiMessage(event);\n if (event.partial) {\n this.partialReasoningBuffer += part.text;\n this.replaceLastReasoningContent(msg, this.partialReasoningBuffer);\n } else {\n this.partialReasoningBuffer = \"\";\n this.replaceLastReasoningContent(msg, part.text);\n }\n return;\n }\n\n // Regular text\n if (part.text != null) {\n const msg = this.getOrCreateAiMessage(event);\n if (event.partial) {\n this.partialTextBuffer += part.text;\n this.replaceLastTextContent(msg, this.partialTextBuffer);\n } else {\n this.partialTextBuffer = \"\";\n this.replaceLastTextContent(msg, part.text);\n }\n return;\n }\n\n // Function call — skip partial events (args may be incomplete)\n if (part.functionCall) {\n if (event.partial) return;\n const msg = this.getOrCreateAiMessage(event);\n const toolCall: AdkToolCall = {\n id: part.functionCall.id ?? uuidv4(),\n name: part.functionCall.name,\n args: part.functionCall.args as ReadonlyJSONObject,\n argsText: JSON.stringify(part.functionCall.args),\n };\n const existing = [...(msg.tool_calls ?? [])];\n const idx = existing.findIndex((tc) => tc.id === toolCall.id);\n if (idx >= 0) {\n existing[idx] = toolCall;\n } else {\n existing.push(toolCall);\n }\n const updated: InProgressMessage = {\n ...msg,\n content: [...this.getContentArray(msg)],\n tool_calls: existing,\n };\n this.messagesMap.set(updated.id, updated);\n return;\n }\n\n // Function response → tool message\n if (part.functionResponse) {\n this.finalizeCurrentMessage();\n const toolMsg: AdkMessage = {\n id: uuidv4(),\n type: \"tool\",\n tool_call_id: part.functionResponse.id ?? \"\",\n name: part.functionResponse.name,\n content: JSON.stringify(part.functionResponse.response),\n status: \"success\",\n };\n this.messagesMap.set(toolMsg.id, toolMsg);\n return;\n }\n\n // Executable code\n if (part.executableCode) {\n const msg = this.getOrCreateAiMessage(event);\n this.appendContent(msg, {\n type: \"code\",\n code: part.executableCode.code,\n language: part.executableCode.language ?? \"python\",\n });\n return;\n }\n\n // Code execution result\n if (part.codeExecutionResult) {\n const msg = this.getOrCreateAiMessage(event);\n this.appendContent(msg, {\n type: \"code_result\",\n output: part.codeExecutionResult.output,\n outcome: part.codeExecutionResult.outcome ?? \"OUTCOME_OK\",\n });\n return;\n }\n\n if (part.inlineData) {\n const msg = this.getOrCreateAiMessage(event);\n this.appendContent(\n msg,\n inlineDataToPart(part.inlineData.mimeType, part.inlineData.data),\n );\n return;\n }\n\n if (part.fileData) {\n const msg = this.getOrCreateAiMessage(event);\n this.appendContent(\n msg,\n fileDataToPart(part.fileData.fileUri, part.fileData.mimeType),\n );\n }\n }\n\n private trackMessageMetadata(event: AdkEvent): void {\n if (\n !this.currentMessageId ||\n (!event.groundingMetadata &&\n !event.citationMetadata &&\n !event.usageMetadata)\n )\n return;\n\n const existing = this.messageMetadataMap.get(this.currentMessageId) ?? {};\n const updated: AdkMessageMetadata = { ...existing };\n if (event.groundingMetadata)\n updated.groundingMetadata = event.groundingMetadata;\n if (event.citationMetadata)\n updated.citationMetadata = event.citationMetadata;\n if (event.usageMetadata) updated.usageMetadata = event.usageMetadata;\n this.messageMetadataMap.set(this.currentMessageId, updated);\n }\n\n private getContentArray(msg: AdkMessage): AdkMessageContentPart[] {\n return Array.isArray(msg.content)\n ? (msg.content as AdkMessageContentPart[])\n : [];\n }\n\n private getOrCreateAiMessage(event: AdkEvent): InProgressMessage {\n if (this.currentMessageId) {\n const existing = this.messagesMap.get(this.currentMessageId);\n if (existing && existing.type === \"ai\") {\n return existing;\n }\n }\n\n const id = uuidv4();\n const msg: InProgressMessage = {\n id,\n type: \"ai\",\n content: [] as AdkMessageContentPart[],\n ...(event.author != null && { author: event.author }),\n ...(event.branch != null && { branch: event.branch }),\n };\n this.messagesMap.set(id, msg);\n this.currentMessageId = id;\n this.partialTextBuffer = \"\";\n this.partialReasoningBuffer = \"\";\n return msg;\n }\n\n private appendContent(\n msg: InProgressMessage,\n part: AdkMessageContentPart,\n ): void {\n const content = [...this.getContentArray(msg), part];\n const updated: InProgressMessage = { ...msg, content };\n this.messagesMap.set(updated.id, updated);\n }\n\n private replaceLastTextContent(msg: InProgressMessage, text: string): void {\n const content = [...this.getContentArray(msg)];\n const lastTextIdx = content.findLastIndex((p) => p.type === \"text\");\n if (lastTextIdx >= 0) {\n content[lastTextIdx] = { type: \"text\", text };\n } else {\n content.push({ type: \"text\", text });\n }\n const updated: InProgressMessage = { ...msg, content };\n this.messagesMap.set(updated.id, updated);\n }\n\n private replaceLastReasoningContent(\n msg: InProgressMessage,\n text: string,\n ): void {\n const content = [...this.getContentArray(msg)];\n const lastIdx = content.findLastIndex((p) => p.type === \"reasoning\");\n if (lastIdx >= 0) {\n content[lastIdx] = { type: \"reasoning\", text };\n } else {\n content.push({ type: \"reasoning\", text });\n }\n const updated: InProgressMessage = { ...msg, content };\n this.messagesMap.set(updated.id, updated);\n }\n\n private finalizeCurrentMessage(): void {\n this.partialTextBuffer = \"\";\n this.partialReasoningBuffer = \"\";\n this.currentMessageId = null;\n }\n\n getMessages(): AdkMessage[] {\n return [...this.messagesMap.values()];\n }\n\n getStateDelta(): Record<string, unknown> {\n return { ...this.accumulatedStateDelta };\n }\n\n getArtifactDelta(): Record<string, number> {\n return { ...this.accumulatedArtifactDelta };\n }\n\n getAgentInfo(): { name?: string | undefined; branch?: string | undefined } {\n return { ...this.lastAgentInfo };\n }\n\n getLastTransferToAgent(): string | undefined {\n return this.lastTransferToAgent;\n }\n\n getLongRunningToolIds(): string[] {\n return [...this.pendingLongRunningToolIds];\n }\n\n getToolConfirmations(): AdkToolConfirmation[] {\n return [...this.toolConfirmations];\n }\n\n getAuthRequests(): AdkAuthRequest[] {\n return [...this.authRequests];\n }\n\n isEscalated(): boolean {\n return this.escalated;\n }\n\n getMessageMetadata(): Map<string, AdkMessageMetadata> {\n return new Map(this.messageMetadataMap);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"AdkEventAccumulator.js","names":["uuidv4"],"sources":["../src/AdkEventAccumulator.ts"],"sourcesContent":["import { v4 as uuidv4 } from \"uuid\";\nimport type { MessageStatus } from \"@assistant-ui/core\";\nimport type {\n AdkEvent,\n AdkEventPart,\n AdkMessage,\n AdkMessageContentPart,\n AdkToolCall,\n AdkToolConfirmation,\n AdkAuthRequest,\n AdkMessageMetadata,\n} from \"./types\";\nimport type { ReadonlyJSONObject } from \"assistant-stream/utils\";\n\ntype InProgressMessage = AdkMessage & { type: \"ai\" };\n\nconst ADK_REQUEST_CONFIRMATION = \"adk_request_confirmation\";\nconst ADK_REQUEST_CREDENTIAL = \"adk_request_credential\";\n\n/**\n * Checks if an event is a final response using the same logic as ADK's\n * `isFinalResponse()`.\n */\nexport const isFinalResponse = (event: AdkEvent): boolean => {\n if (\n event.actions?.skipSummarization ||\n (event.longRunningToolIds && event.longRunningToolIds.length > 0)\n ) {\n return true;\n }\n\n const parts = event.content?.parts;\n return (\n !event.partial &&\n (parts?.length ?? 0) > 0 &&\n !parts!.some((p) => p.functionCall) &&\n !parts!.some((p) => p.functionResponse) &&\n !parts![parts!.length - 1]?.codeExecutionResult\n );\n};\n\nconst CONTENT_FILTER_REASONS = new Set([\n \"SAFETY\",\n \"RECITATION\",\n \"BLOCKLIST\",\n \"PROHIBITED_CONTENT\",\n \"SPII\",\n \"LANGUAGE\",\n \"IMAGE_SAFETY\",\n \"IMAGE_RECITATION\",\n \"IMAGE_OTHER\",\n \"IMAGE_PROHIBITED_CONTENT\",\n]);\n\nconst ERROR_REASONS = new Set([\n \"MALFORMED_FUNCTION_CALL\",\n \"UNEXPECTED_TOOL_CALL\",\n]);\n\nconst finishReasonToStatus = (\n finishReason: string | undefined,\n): MessageStatus => {\n if (finishReason === \"MAX_TOKENS\") {\n return { type: \"incomplete\", reason: \"length\" };\n }\n if (finishReason && CONTENT_FILTER_REASONS.has(finishReason)) {\n return {\n type: \"incomplete\",\n reason: \"content-filter\",\n error: `Content filtered: ${finishReason}`,\n };\n }\n if (finishReason && ERROR_REASONS.has(finishReason)) {\n return {\n type: \"incomplete\",\n reason: \"error\",\n error: `LLM error: ${finishReason}`,\n };\n }\n return { type: \"complete\", reason: \"stop\" };\n};\n\nconst inlineDataToPart = (\n mimeType: string,\n data: string,\n): AdkMessageContentPart =>\n mimeType.startsWith(\"image/\")\n ? { type: \"image\", mimeType, data }\n : { type: \"file\", mimeType, data };\n\nconst fileDataToPart = (\n fileUri: string,\n mimeType: string | undefined,\n): AdkMessageContentPart =>\n mimeType == null || mimeType.startsWith(\"image/\")\n ? { type: \"image_url\", url: fileUri }\n : { type: \"file_url\", url: fileUri, mimeType };\n\n// ── Snake_case normalization ──\n\nconst normalizeEventPart = (part: AdkEventPart): AdkEventPart => {\n const p = part as Record<string, unknown>;\n const result: Record<string, unknown> = { ...p };\n if (\"function_call\" in p && !(\"functionCall\" in p))\n result.functionCall = p.function_call;\n if (\"function_response\" in p && !(\"functionResponse\" in p))\n result.functionResponse = p.function_response;\n if (\"inline_data\" in p && !(\"inlineData\" in p))\n result.inlineData = p.inline_data;\n if (\"file_data\" in p && !(\"fileData\" in p)) result.fileData = p.file_data;\n if (\"executable_code\" in p && !(\"executableCode\" in p))\n result.executableCode = p.executable_code;\n if (\"code_execution_result\" in p && !(\"codeExecutionResult\" in p))\n result.codeExecutionResult = p.code_execution_result;\n return result as AdkEventPart;\n};\n\nconst normalizeEvent = (event: AdkEvent): AdkEvent => {\n const e = event as Record<string, unknown>;\n const result: Record<string, unknown> = { ...e };\n if (\"error_code\" in e && !(\"errorCode\" in e)) result.errorCode = e.error_code;\n if (\"error_message\" in e && !(\"errorMessage\" in e))\n result.errorMessage = e.error_message;\n if (\"long_running_tool_ids\" in e && !(\"longRunningToolIds\" in e))\n result.longRunningToolIds = e.long_running_tool_ids;\n if (\"turn_complete\" in e && !(\"turnComplete\" in e))\n result.turnComplete = e.turn_complete;\n if (\"finish_reason\" in e && !(\"finishReason\" in e))\n result.finishReason = e.finish_reason;\n if (\"invocation_id\" in e && !(\"invocationId\" in e))\n result.invocationId = e.invocation_id;\n if (\"custom_metadata\" in e && !(\"customMetadata\" in e))\n result.customMetadata = e.custom_metadata;\n if (\"grounding_metadata\" in e && !(\"groundingMetadata\" in e))\n result.groundingMetadata = e.grounding_metadata;\n if (\"citation_metadata\" in e && !(\"citationMetadata\" in e))\n result.citationMetadata = e.citation_metadata;\n if (\"usage_metadata\" in e && !(\"usageMetadata\" in e))\n result.usageMetadata = e.usage_metadata;\n\n if (result.actions) {\n const a = result.actions as Record<string, unknown>;\n const na: Record<string, unknown> = { ...a };\n if (\"state_delta\" in a && !(\"stateDelta\" in a))\n na.stateDelta = a.state_delta;\n if (\"artifact_delta\" in a && !(\"artifactDelta\" in a))\n na.artifactDelta = a.artifact_delta;\n if (\"transfer_to_agent\" in a && !(\"transferToAgent\" in a))\n na.transferToAgent = a.transfer_to_agent;\n if (\"skip_summarization\" in a && !(\"skipSummarization\" in a))\n na.skipSummarization = a.skip_summarization;\n if (\"requested_auth_configs\" in a && !(\"requestedAuthConfigs\" in a))\n na.requestedAuthConfigs = a.requested_auth_configs;\n if (\n \"requested_tool_confirmations\" in a &&\n !(\"requestedToolConfirmations\" in a)\n )\n na.requestedToolConfirmations = a.requested_tool_confirmations;\n result.actions = na;\n }\n\n if (result.content && (result.content as Record<string, unknown>).parts) {\n const content = result.content as Record<string, unknown>;\n const parts = content.parts as AdkEventPart[];\n result.content = { ...content, parts: parts.map(normalizeEventPart) };\n }\n\n return result as AdkEvent;\n};\n\n// ── Accumulator ──\n\nexport class AdkEventAccumulator {\n private messagesMap = new Map<string, AdkMessage>();\n private currentMessageId: string | null = null;\n private partialTextBuffer = \"\";\n private partialReasoningBuffer = \"\";\n private accumulatedStateDelta: Record<string, unknown> = {};\n private accumulatedArtifactDelta: Record<string, number> = {};\n private lastAgentInfo: {\n name?: string | undefined;\n branch?: string | undefined;\n } = {};\n private lastTransferToAgent: string | undefined;\n private pendingLongRunningToolIds = new Set<string>();\n private toolConfirmations: AdkToolConfirmation[] = [];\n private authRequests: AdkAuthRequest[] = [];\n private escalated = false;\n private messageMetadataMap = new Map<string, AdkMessageMetadata>();\n constructor(initialMessages?: AdkMessage[]) {\n if (initialMessages) {\n for (const msg of initialMessages) {\n this.messagesMap.set(msg.id, msg);\n }\n }\n }\n\n processEvent(rawEvent: AdkEvent): AdkMessage[] {\n const event = normalizeEvent(rawEvent);\n\n // Accumulate state delta\n if (event.actions?.stateDelta) {\n Object.assign(this.accumulatedStateDelta, event.actions.stateDelta);\n }\n\n // Accumulate artifact delta\n if (event.actions?.artifactDelta) {\n Object.assign(this.accumulatedArtifactDelta, event.actions.artifactDelta);\n }\n\n // Track escalation\n if (event.actions?.escalate) {\n this.escalated = true;\n }\n\n // Track agent transfer\n if (event.actions?.transferToAgent) {\n this.lastTransferToAgent = event.actions.transferToAgent;\n }\n\n // Track long-running tool IDs. Accumulate across events so that multiple\n // HITL interrupts emitted in the same turn are all tracked — a\n // single-event replacement would drop earlier ids.\n if (event.longRunningToolIds?.length) {\n for (const id of event.longRunningToolIds) {\n this.pendingLongRunningToolIds.add(id);\n }\n }\n\n // Track tool confirmations from actions\n if (event.actions?.requestedToolConfirmations) {\n for (const [tcId, conf] of Object.entries(\n event.actions.requestedToolConfirmations,\n )) {\n const c = conf as Record<string, unknown>;\n this.toolConfirmations.push({\n toolCallId: tcId,\n toolName: \"\",\n args: {},\n hint: (c.hint as string) ?? \"\",\n confirmed: false,\n payload: c.payload,\n });\n }\n }\n\n // Track auth requests from actions\n if (event.actions?.requestedAuthConfigs) {\n for (const [tcId, authConf] of Object.entries(\n event.actions.requestedAuthConfigs,\n )) {\n this.authRequests.push({ toolCallId: tcId, authConfig: authConf });\n }\n }\n\n // Track agent info\n if (event.author && event.author !== \"user\") {\n this.lastAgentInfo = {\n name: event.author ?? undefined,\n branch: event.branch ?? undefined,\n };\n }\n\n // Handle interrupted events\n if (event.interrupted) {\n if (this.currentMessageId) {\n const msg = this.messagesMap.get(this.currentMessageId);\n if (msg && msg.type === \"ai\" && !msg.status) {\n const updated: InProgressMessage = {\n ...msg,\n content: [...this.getContentArray(msg)],\n status: { type: \"incomplete\", reason: \"cancelled\" },\n };\n this.messagesMap.set(updated.id, updated);\n }\n }\n this.finalizeCurrentMessage();\n return this.getMessages();\n }\n\n // Handle error events\n if (event.errorCode || event.errorMessage) {\n this.finalizeCurrentMessage();\n const errorMsg = this.getOrCreateAiMessage(event);\n const errorText =\n event.errorMessage ?? event.errorCode ?? \"Unknown error\";\n const updated: InProgressMessage = {\n ...errorMsg,\n content: [\n ...this.getContentArray(errorMsg),\n { type: \"text\", text: errorText },\n ],\n status: { type: \"incomplete\", reason: \"error\", error: errorText },\n };\n this.messagesMap.set(updated.id, updated);\n this.currentMessageId = null;\n return this.getMessages();\n }\n\n const parts = event.content?.parts;\n if (!parts?.length) {\n // Track metadata even for content-less events (e.g. turnComplete)\n this.trackMessageMetadata(event);\n return this.getMessages();\n }\n\n // User-authored events → create human message, not AI.\n // Without this, user events fall through to processPart →\n // getOrCreateAiMessage, producing type:\"ai\" messages that\n // convertAdkMessage maps to role:\"assistant\".\n if (event.author === \"user\") {\n this.finalizeCurrentMessage();\n const humanParts: AdkMessageContentPart[] = [];\n for (const part of parts) {\n if (part.text != null && !part.thought) {\n humanParts.push({ type: \"text\", text: part.text });\n } else if (part.inlineData) {\n humanParts.push(\n inlineDataToPart(part.inlineData.mimeType, part.inlineData.data),\n );\n } else if (part.fileData) {\n humanParts.push(\n fileDataToPart(part.fileData.fileUri, part.fileData.mimeType),\n );\n }\n }\n if (humanParts.length > 0) {\n const id = event.id ?? uuidv4();\n const first = humanParts[0];\n const content: string | AdkMessageContentPart[] =\n humanParts.length === 1 && first?.type === \"text\"\n ? first.text\n : humanParts;\n this.messagesMap.set(id, { id, type: \"human\", content });\n }\n return this.getMessages();\n }\n\n // If author changed, finalize previous message\n if (this.currentMessageId && event.author && event.author !== \"user\") {\n const current = this.messagesMap.get(this.currentMessageId);\n if (current && current.type === \"ai\" && current.author !== event.author) {\n this.finalizeCurrentMessage();\n }\n }\n\n for (const part of parts) {\n this.processPart(part, event);\n }\n\n // Track per-message metadata (grounding, citation, usage)\n this.trackMessageMetadata(event);\n\n // Check isFinalResponse (can be true even for partial events via skipSummarization/longRunningToolIds)\n if (isFinalResponse(event) && this.currentMessageId) {\n const msg = this.messagesMap.get(this.currentMessageId);\n // Skip manual \"complete\" when longRunningToolIds is the sole reason for\n // isFinalResponse — let auto-status apply requires-action for pending tool calls.\n const isHitlOnly =\n event.longRunningToolIds &&\n event.longRunningToolIds.length > 0 &&\n !event.actions?.skipSummarization;\n if (msg && msg.type === \"ai\" && !msg.status && !isHitlOnly) {\n const status = finishReasonToStatus(event.finishReason);\n const updated: InProgressMessage = {\n ...msg,\n content: [...this.getContentArray(msg)],\n status,\n };\n this.messagesMap.set(updated.id, updated);\n }\n }\n\n // Non-partial event finalizes the current message\n if (!event.partial || isFinalResponse(event)) {\n this.finalizeCurrentMessage();\n }\n\n return this.getMessages();\n }\n\n private processPart(part: AdkEventPart, event: AdkEvent): void {\n // Detect special ADK function calls\n if (part.functionCall && !event.partial) {\n const name = part.functionCall.name;\n\n // Tool confirmation request\n if (name === ADK_REQUEST_CONFIRMATION) {\n const callArgs = part.functionCall.args;\n // ADK JS: args keys are \"originalFunctionCall\" and \"toolConfirmation\"\n // ADK Python: args keys are \"original_function_call\" and \"tool_confirmation\"\n const original =\n (callArgs.originalFunctionCall as Record<string, unknown>) ??\n (callArgs.original_function_call as Record<string, unknown>);\n const conf =\n (callArgs.toolConfirmation as Record<string, unknown>) ??\n (callArgs.tool_confirmation as Record<string, unknown>);\n this.toolConfirmations.push({\n toolCallId: part.functionCall.id ?? \"\",\n toolName: (original?.name as string) ?? \"\",\n args: (original?.args as Record<string, unknown>) ?? {},\n hint: (conf?.hint as string) ?? \"\",\n confirmed: false,\n payload: conf?.payload,\n });\n }\n\n // Auth credential request\n if (name === ADK_REQUEST_CREDENTIAL) {\n const credArgs = part.functionCall.args;\n // ADK JS: args keys are \"function_call_id\" and \"auth_config\"\n const originalToolCallId =\n (credArgs.function_call_id as string) ?? part.functionCall.id ?? \"\";\n const authConfig = credArgs.auth_config ?? credArgs;\n this.authRequests.push({\n toolCallId: originalToolCallId,\n authConfig,\n });\n }\n }\n\n // Text with thought=true → reasoning (accumulated)\n if (part.text != null && part.thought) {\n const msg = this.getOrCreateAiMessage(event);\n if (event.partial) {\n this.partialReasoningBuffer += part.text;\n this.replaceLastReasoningContent(msg, this.partialReasoningBuffer);\n } else {\n this.partialReasoningBuffer = \"\";\n this.replaceLastReasoningContent(msg, part.text);\n }\n return;\n }\n\n // Regular text\n if (part.text != null) {\n const msg = this.getOrCreateAiMessage(event);\n if (event.partial) {\n this.partialTextBuffer += part.text;\n this.replaceLastTextContent(msg, this.partialTextBuffer);\n } else {\n this.partialTextBuffer = \"\";\n this.replaceLastTextContent(msg, part.text);\n }\n return;\n }\n\n // Function call — skip partial events (args may be incomplete)\n if (part.functionCall) {\n if (event.partial) return;\n const msg = this.getOrCreateAiMessage(event);\n const toolCall: AdkToolCall = {\n id: part.functionCall.id ?? uuidv4(),\n name: part.functionCall.name,\n args: part.functionCall.args as ReadonlyJSONObject,\n argsText: JSON.stringify(part.functionCall.args),\n };\n const existing = [...(msg.tool_calls ?? [])];\n const idx = existing.findIndex((tc) => tc.id === toolCall.id);\n if (idx >= 0) {\n existing[idx] = toolCall;\n } else {\n existing.push(toolCall);\n }\n const updated: InProgressMessage = {\n ...msg,\n content: [...this.getContentArray(msg)],\n tool_calls: existing,\n };\n this.messagesMap.set(updated.id, updated);\n return;\n }\n\n // Function response → tool message\n if (part.functionResponse) {\n this.finalizeCurrentMessage();\n const toolMsg: AdkMessage = {\n id: uuidv4(),\n type: \"tool\",\n tool_call_id: part.functionResponse.id ?? \"\",\n name: part.functionResponse.name,\n content: JSON.stringify(part.functionResponse.response),\n status: \"success\",\n };\n this.messagesMap.set(toolMsg.id, toolMsg);\n return;\n }\n\n // Executable code\n if (part.executableCode) {\n const msg = this.getOrCreateAiMessage(event);\n this.appendContent(msg, {\n type: \"code\",\n code: part.executableCode.code,\n language: part.executableCode.language ?? \"python\",\n });\n return;\n }\n\n // Code execution result\n if (part.codeExecutionResult) {\n const msg = this.getOrCreateAiMessage(event);\n this.appendContent(msg, {\n type: \"code_result\",\n output: part.codeExecutionResult.output,\n outcome: part.codeExecutionResult.outcome ?? \"OUTCOME_OK\",\n });\n return;\n }\n\n if (part.inlineData) {\n const msg = this.getOrCreateAiMessage(event);\n this.appendContent(\n msg,\n inlineDataToPart(part.inlineData.mimeType, part.inlineData.data),\n );\n return;\n }\n\n if (part.fileData) {\n const msg = this.getOrCreateAiMessage(event);\n this.appendContent(\n msg,\n fileDataToPart(part.fileData.fileUri, part.fileData.mimeType),\n );\n }\n }\n\n private trackMessageMetadata(event: AdkEvent): void {\n if (\n !this.currentMessageId ||\n (!event.groundingMetadata &&\n !event.citationMetadata &&\n !event.usageMetadata)\n )\n return;\n\n const existing = this.messageMetadataMap.get(this.currentMessageId) ?? {};\n const updated: AdkMessageMetadata = { ...existing };\n if (event.groundingMetadata)\n updated.groundingMetadata = event.groundingMetadata;\n if (event.citationMetadata)\n updated.citationMetadata = event.citationMetadata;\n if (event.usageMetadata) updated.usageMetadata = event.usageMetadata;\n this.messageMetadataMap.set(this.currentMessageId, updated);\n }\n\n private getContentArray(msg: AdkMessage): AdkMessageContentPart[] {\n return Array.isArray(msg.content)\n ? (msg.content as AdkMessageContentPart[])\n : [];\n }\n\n private getOrCreateAiMessage(event: AdkEvent): InProgressMessage {\n if (this.currentMessageId) {\n const existing = this.messagesMap.get(this.currentMessageId);\n if (existing && existing.type === \"ai\") {\n return existing;\n }\n }\n\n const id = uuidv4();\n const msg: InProgressMessage = {\n id,\n type: \"ai\",\n content: [] as AdkMessageContentPart[],\n ...(event.author != null && { author: event.author }),\n ...(event.branch != null && { branch: event.branch }),\n };\n this.messagesMap.set(id, msg);\n this.currentMessageId = id;\n this.partialTextBuffer = \"\";\n this.partialReasoningBuffer = \"\";\n return msg;\n }\n\n private appendContent(\n msg: InProgressMessage,\n part: AdkMessageContentPart,\n ): void {\n const content = [...this.getContentArray(msg), part];\n const updated: InProgressMessage = { ...msg, content };\n this.messagesMap.set(updated.id, updated);\n }\n\n private replaceLastTextContent(msg: InProgressMessage, text: string): void {\n const content = [...this.getContentArray(msg)];\n const lastTextIdx = content.findLastIndex((p) => p.type === \"text\");\n if (lastTextIdx >= 0) {\n content[lastTextIdx] = { type: \"text\", text };\n } else {\n content.push({ type: \"text\", text });\n }\n const updated: InProgressMessage = { ...msg, content };\n this.messagesMap.set(updated.id, updated);\n }\n\n private replaceLastReasoningContent(\n msg: InProgressMessage,\n text: string,\n ): void {\n const content = [...this.getContentArray(msg)];\n const lastIdx = content.findLastIndex((p) => p.type === \"reasoning\");\n if (lastIdx >= 0) {\n content[lastIdx] = { type: \"reasoning\", text };\n } else {\n content.push({ type: \"reasoning\", text });\n }\n const updated: InProgressMessage = { ...msg, content };\n this.messagesMap.set(updated.id, updated);\n }\n\n private finalizeCurrentMessage(): void {\n this.partialTextBuffer = \"\";\n this.partialReasoningBuffer = \"\";\n this.currentMessageId = null;\n }\n\n getMessages(): AdkMessage[] {\n return [...this.messagesMap.values()];\n }\n\n getStateDelta(): Record<string, unknown> {\n return { ...this.accumulatedStateDelta };\n }\n\n getArtifactDelta(): Record<string, number> {\n return { ...this.accumulatedArtifactDelta };\n }\n\n getAgentInfo(): { name?: string | undefined; branch?: string | undefined } {\n return { ...this.lastAgentInfo };\n }\n\n getLastTransferToAgent(): string | undefined {\n return this.lastTransferToAgent;\n }\n\n getLongRunningToolIds(): string[] {\n return [...this.pendingLongRunningToolIds];\n }\n\n getToolConfirmations(): AdkToolConfirmation[] {\n return [...this.toolConfirmations];\n }\n\n getAuthRequests(): AdkAuthRequest[] {\n return [...this.authRequests];\n }\n\n isEscalated(): boolean {\n return this.escalated;\n }\n\n getMessageMetadata(): Map<string, AdkMessageMetadata> {\n return new Map(this.messageMetadataMap);\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"AdkSessionAdapter.js","names":[],"sources":["../src/AdkSessionAdapter.ts"],"sourcesContent":["import type { AssistantStream, AssistantStreamChunk } from \"assistant-stream\";\nimport type {\n RemoteThreadInitializeResponse,\n RemoteThreadListAdapter,\n RemoteThreadListResponse,\n RemoteThreadMetadata,\n} from \"@assistant-ui/core\";\nimport { AdkEventAccumulator } from \"./AdkEventAccumulator\";\nimport type { AdkEvent, AdkMessage } from \"./types\";\n\nexport type AdkSessionAdapterOptions = {\n /**\n * ADK server base URL (e.g. \"http://localhost:8000\").\n */\n apiUrl: string;\n\n /**\n * ADK application name.\n */\n appName: string;\n\n /**\n * ADK user ID.\n */\n userId: string;\n\n /**\n * Extra headers for API requests.\n */\n headers?:\n | Record<string, string>\n | (() => Record<string, string> | Promise<Record<string, string>>)\n | undefined;\n};\n\nexport type AdkArtifactData = {\n inlineData?: { mimeType: string; data: string } | undefined;\n text?: string | undefined;\n};\n\ntype AdkSessionAdapterResult = {\n adapter: RemoteThreadListAdapter;\n load: (sessionId: string) => Promise<{ messages: AdkMessage[] }>;\n artifacts: {\n list: (sessionId: string) => Promise<string[]>;\n load: (\n sessionId: string,\n artifactName: string,\n version?: number,\n ) => Promise<AdkArtifactData>;\n listVersions: (\n sessionId: string,\n artifactName: string,\n ) => Promise<number[]>;\n delete: (sessionId: string, artifactName: string) => Promise<void>;\n };\n};\n\n/**\n * Creates a `RemoteThreadListAdapter` backed by ADK's session REST API,\n * plus a `load` function that reconstructs messages from session events.\n *\n * @example\n * ```ts\n * const { adapter, load } = createAdkSessionAdapter({\n * apiUrl: \"http://localhost:8000\",\n * appName: \"my-app\",\n * userId: \"user-1\",\n * });\n *\n * const runtime = useAdkRuntime({\n * stream: createAdkStream({ ... }),\n * sessionAdapter: adapter,\n * load,\n * });\n * ```\n */\nexport function createAdkSessionAdapter(\n options: AdkSessionAdapterOptions,\n): AdkSessionAdapterResult {\n const { apiUrl, appName, userId } = options;\n const baseUrl = `${apiUrl}/apps/${encodeURIComponent(appName)}/users/${encodeURIComponent(userId)}/sessions`;\n\n const getHeaders = async (): Promise<Record<string, string>> => {\n if (!options.headers) return {};\n if (typeof options.headers === \"function\") return await options.headers();\n return options.headers;\n };\n\n const adapter: RemoteThreadListAdapter = {\n async list(): Promise<RemoteThreadListResponse> {\n const headers = await getHeaders();\n const res = await fetch(baseUrl, { headers });\n if (!res.ok) {\n throw new Error(`Failed to list sessions: ${res.status}`);\n }\n const data = (await res.json()) as Array<{\n id: string;\n app_name?: string;\n user_id?: string;\n last_update_time?: number;\n }>;\n\n const threads: RemoteThreadMetadata[] = data.map((session) => ({\n status: \"regular\" as const,\n remoteId: session.id,\n externalId: session.id,\n title: undefined,\n }));\n\n return { threads };\n },\n\n async initialize(\n _threadId: string,\n ): Promise<RemoteThreadInitializeResponse> {\n const headers = await getHeaders();\n const res = await fetch(baseUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", ...headers },\n body: JSON.stringify({}),\n });\n if (!res.ok) {\n throw new Error(`Failed to create session: ${res.status}`);\n }\n const session = (await res.json()) as { id: string };\n return { remoteId: session.id, externalId: session.id };\n },\n\n async delete(remoteId: string): Promise<void> {\n const headers = await getHeaders();\n const res = await fetch(`${baseUrl}/${encodeURIComponent(remoteId)}`, {\n method: \"DELETE\",\n headers,\n });\n if (!res.ok && res.status !== 404) {\n throw new Error(`Failed to delete session: ${res.status}`);\n }\n },\n\n async rename(): Promise<void> {\n // ADK sessions don't support titles\n },\n\n async archive(): Promise<void> {\n // ADK sessions don't support archiving\n },\n\n async unarchive(): Promise<void> {\n // ADK sessions don't support archiving\n },\n\n generateTitle(): Promise<AssistantStream> {\n // Title generation not supported without assistant-cloud\n return Promise.resolve(new ReadableStream<AssistantStreamChunk>());\n },\n\n async fetch(threadId: string): Promise<RemoteThreadMetadata> {\n const headers = await getHeaders();\n const res = await fetch(`${baseUrl}/${encodeURIComponent(threadId)}`, {\n headers,\n });\n if (!res.ok) {\n throw new Error(`Session not found: ${res.status}`);\n }\n const session = (await res.json()) as { id: string };\n return {\n status: \"regular\",\n remoteId: session.id,\n externalId: session.id,\n title: undefined,\n };\n },\n };\n\n const load = async (\n sessionId: string,\n ): Promise<{ messages: AdkMessage[] }> => {\n const headers = await getHeaders();\n const res = await fetch(`${baseUrl}/${encodeURIComponent(sessionId)}`, {\n headers,\n });\n if (!res.ok) {\n throw new Error(`Failed to load session: ${res.status}`);\n }\n const session = (await res.json()) as {\n id: string;\n events?: AdkEvent[];\n };\n\n if (!session.events?.length) {\n return { messages: [] };\n }\n\n const accumulator = new AdkEventAccumulator();\n let messages: AdkMessage[] = [];\n for (const event of session.events) {\n messages = accumulator.processEvent(event);\n }\n return { messages };\n };\n\n const artifactBaseUrl = (sessionId: string) =>\n `${baseUrl}/${encodeURIComponent(sessionId)}/artifacts`;\n\n const artifacts: AdkSessionAdapterResult[\"artifacts\"] = {\n async list(sessionId) {\n const headers = await getHeaders();\n const res = await fetch(artifactBaseUrl(sessionId), { headers });\n if (!res.ok) throw new Error(`Failed to list artifacts: ${res.status}`);\n const data = (await res.json()) as Array<{ filename: string }>;\n return data.map((a) => a.filename);\n },\n\n async load(sessionId, artifactName, version?) {\n const headers = await getHeaders();\n let url = `${artifactBaseUrl(sessionId)}/${encodeURIComponent(artifactName)}`;\n if (version != null) url += `/versions/${version}`;\n const res = await fetch(url, { headers });\n if (!res.ok) throw new Error(`Failed to load artifact: ${res.status}`);\n return (await res.json()) as AdkArtifactData;\n },\n\n async listVersions(sessionId, artifactName) {\n const headers = await getHeaders();\n const url = `${artifactBaseUrl(sessionId)}/${encodeURIComponent(artifactName)}/versions`;\n const res = await fetch(url, { headers });\n if (!res.ok) {\n throw new Error(`Failed to list artifact versions: ${res.status}`);\n }\n return (await res.json()) as number[];\n },\n\n async delete(sessionId, artifactName) {\n const headers = await getHeaders();\n const url = `${artifactBaseUrl(sessionId)}/${encodeURIComponent(artifactName)}`;\n const res = await fetch(url, { method: \"DELETE\", headers });\n if (!res.ok && res.status !== 404) {\n throw new Error(`Failed to delete artifact: ${res.status}`);\n }\n },\n };\n\n return { adapter, load, artifacts };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"AdkSessionAdapter.js","names":[],"sources":["../src/AdkSessionAdapter.ts"],"sourcesContent":["import type { AssistantStream, AssistantStreamChunk } from \"assistant-stream\";\nimport type {\n RemoteThreadInitializeResponse,\n RemoteThreadListAdapter,\n RemoteThreadListResponse,\n RemoteThreadMetadata,\n} from \"@assistant-ui/core\";\nimport { AdkEventAccumulator } from \"./AdkEventAccumulator\";\nimport type { AdkEvent, AdkMessage } from \"./types\";\n\nexport type AdkSessionAdapterOptions = {\n /**\n * ADK server base URL (e.g. \"http://localhost:8000\").\n */\n apiUrl: string;\n\n /**\n * ADK application name.\n */\n appName: string;\n\n /**\n * ADK user ID.\n */\n userId: string;\n\n /**\n * Extra headers for API requests.\n */\n headers?:\n | Record<string, string>\n | (() => Record<string, string> | Promise<Record<string, string>>)\n | undefined;\n};\n\nexport type AdkArtifactData = {\n inlineData?: { mimeType: string; data: string } | undefined;\n text?: string | undefined;\n};\n\ntype AdkSessionAdapterResult = {\n adapter: RemoteThreadListAdapter;\n load: (sessionId: string) => Promise<{ messages: AdkMessage[] }>;\n artifacts: {\n list: (sessionId: string) => Promise<string[]>;\n load: (\n sessionId: string,\n artifactName: string,\n version?: number,\n ) => Promise<AdkArtifactData>;\n listVersions: (\n sessionId: string,\n artifactName: string,\n ) => Promise<number[]>;\n delete: (sessionId: string, artifactName: string) => Promise<void>;\n };\n};\n\n/**\n * Creates a `RemoteThreadListAdapter` backed by ADK's session REST API,\n * plus a `load` function that reconstructs messages from session events.\n *\n * @example\n * ```ts\n * const { adapter, load } = createAdkSessionAdapter({\n * apiUrl: \"http://localhost:8000\",\n * appName: \"my-app\",\n * userId: \"user-1\",\n * });\n *\n * const runtime = useAdkRuntime({\n * stream: createAdkStream({ ... }),\n * sessionAdapter: adapter,\n * load,\n * });\n * ```\n */\nexport function createAdkSessionAdapter(\n options: AdkSessionAdapterOptions,\n): AdkSessionAdapterResult {\n const { apiUrl, appName, userId } = options;\n const baseUrl = `${apiUrl}/apps/${encodeURIComponent(appName)}/users/${encodeURIComponent(userId)}/sessions`;\n\n const getHeaders = async (): Promise<Record<string, string>> => {\n if (!options.headers) return {};\n if (typeof options.headers === \"function\") return await options.headers();\n return options.headers;\n };\n\n const adapter: RemoteThreadListAdapter = {\n async list(): Promise<RemoteThreadListResponse> {\n const headers = await getHeaders();\n const res = await fetch(baseUrl, { headers });\n if (!res.ok) {\n throw new Error(`Failed to list sessions: ${res.status}`);\n }\n const data = (await res.json()) as Array<{\n id: string;\n app_name?: string;\n user_id?: string;\n last_update_time?: number;\n }>;\n\n const threads: RemoteThreadMetadata[] = data.map((session) => ({\n status: \"regular\" as const,\n remoteId: session.id,\n externalId: session.id,\n title: undefined,\n }));\n\n return { threads };\n },\n\n async initialize(\n _threadId: string,\n ): Promise<RemoteThreadInitializeResponse> {\n const headers = await getHeaders();\n const res = await fetch(baseUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", ...headers },\n body: JSON.stringify({}),\n });\n if (!res.ok) {\n throw new Error(`Failed to create session: ${res.status}`);\n }\n const session = (await res.json()) as { id: string };\n return { remoteId: session.id, externalId: session.id };\n },\n\n async delete(remoteId: string): Promise<void> {\n const headers = await getHeaders();\n const res = await fetch(`${baseUrl}/${encodeURIComponent(remoteId)}`, {\n method: \"DELETE\",\n headers,\n });\n if (!res.ok && res.status !== 404) {\n throw new Error(`Failed to delete session: ${res.status}`);\n }\n },\n\n async rename(): Promise<void> {\n // ADK sessions don't support titles\n },\n\n async archive(): Promise<void> {\n // ADK sessions don't support archiving\n },\n\n async unarchive(): Promise<void> {\n // ADK sessions don't support archiving\n },\n\n generateTitle(): Promise<AssistantStream> {\n // Title generation not supported without assistant-cloud\n return Promise.resolve(new ReadableStream<AssistantStreamChunk>());\n },\n\n async fetch(threadId: string): Promise<RemoteThreadMetadata> {\n const headers = await getHeaders();\n const res = await fetch(`${baseUrl}/${encodeURIComponent(threadId)}`, {\n headers,\n });\n if (!res.ok) {\n throw new Error(`Session not found: ${res.status}`);\n }\n const session = (await res.json()) as { id: string };\n return {\n status: \"regular\",\n remoteId: session.id,\n externalId: session.id,\n title: undefined,\n };\n },\n };\n\n const load = async (\n sessionId: string,\n ): Promise<{ messages: AdkMessage[] }> => {\n const headers = await getHeaders();\n const res = await fetch(`${baseUrl}/${encodeURIComponent(sessionId)}`, {\n headers,\n });\n if (!res.ok) {\n throw new Error(`Failed to load session: ${res.status}`);\n }\n const session = (await res.json()) as {\n id: string;\n events?: AdkEvent[];\n };\n\n if (!session.events?.length) {\n return { messages: [] };\n }\n\n const accumulator = new AdkEventAccumulator();\n let messages: AdkMessage[] = [];\n for (const event of session.events) {\n messages = accumulator.processEvent(event);\n }\n return { messages };\n };\n\n const artifactBaseUrl = (sessionId: string) =>\n `${baseUrl}/${encodeURIComponent(sessionId)}/artifacts`;\n\n const artifacts: AdkSessionAdapterResult[\"artifacts\"] = {\n async list(sessionId) {\n const headers = await getHeaders();\n const res = await fetch(artifactBaseUrl(sessionId), { headers });\n if (!res.ok) throw new Error(`Failed to list artifacts: ${res.status}`);\n const data = (await res.json()) as Array<{ filename: string }>;\n return data.map((a) => a.filename);\n },\n\n async load(sessionId, artifactName, version?) {\n const headers = await getHeaders();\n let url = `${artifactBaseUrl(sessionId)}/${encodeURIComponent(artifactName)}`;\n if (version != null) url += `/versions/${version}`;\n const res = await fetch(url, { headers });\n if (!res.ok) throw new Error(`Failed to load artifact: ${res.status}`);\n return (await res.json()) as AdkArtifactData;\n },\n\n async listVersions(sessionId, artifactName) {\n const headers = await getHeaders();\n const url = `${artifactBaseUrl(sessionId)}/${encodeURIComponent(artifactName)}/versions`;\n const res = await fetch(url, { headers });\n if (!res.ok) {\n throw new Error(`Failed to list artifact versions: ${res.status}`);\n }\n return (await res.json()) as number[];\n },\n\n async delete(sessionId, artifactName) {\n const headers = await getHeaders();\n const url = `${artifactBaseUrl(sessionId)}/${encodeURIComponent(artifactName)}`;\n const res = await fetch(url, { method: \"DELETE\", headers });\n if (!res.ok && res.status !== 404) {\n throw new Error(`Failed to delete artifact: ${res.status}`);\n }\n },\n };\n\n return { adapter, load, artifacts };\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"convertAdkMessages.js","names":[],"sources":["../src/convertAdkMessages.ts"],"sourcesContent":["\"use client\";\n\nimport type { ToolCallMessagePart } from \"@assistant-ui/core\";\nimport type { useExternalMessageConverter } from \"@assistant-ui/core/react\";\nimport type { AdkMessage, AdkMessageContentPart } from \"./types\";\n\ntype ContentPart =\n | { type: \"text\"; text: string }\n | { type: \"reasoning\"; text: string }\n | { type: \"image\"; image: string }\n | { type: \"file\"; data: string; mimeType: string; filename?: string }\n | { type: \"data\"; name: string; data: unknown };\n\nconst contentToParts = (content: AdkMessage[\"content\"]): ContentPart[] => {\n if (typeof content === \"string\")\n return [{ type: \"text\" as const, text: content }];\n\n return (content as AdkMessageContentPart[])\n .map((part): ContentPart | null => {\n switch (part.type) {\n case \"text\":\n return { type: \"text\", text: part.text };\n case \"reasoning\":\n return { type: \"reasoning\", text: part.text };\n case \"image\":\n return {\n type: \"image\",\n image: `data:${part.mimeType};base64,${part.data}`,\n };\n case \"image_url\":\n return { type: \"image\", image: part.url };\n case \"file\":\n return {\n type: \"file\",\n data: part.data,\n mimeType: part.mimeType,\n ...(part.filename != null && { filename: part.filename }),\n };\n case \"file_url\":\n return {\n type: \"data\",\n name: \"file_url\",\n data: {\n url: part.url,\n ...(part.mimeType != null && { mimeType: part.mimeType }),\n },\n };\n case \"code\":\n return {\n type: \"data\",\n name: \"executable_code\",\n data: { code: part.code, language: part.language },\n };\n case \"code_result\":\n return {\n type: \"data\",\n name: \"code_execution_result\",\n data: { output: part.output, outcome: part.outcome },\n };\n default:\n return null;\n }\n })\n .filter((p): p is NonNullable<typeof p> => p !== null);\n};\n\nexport const convertAdkMessage: useExternalMessageConverter.Callback<\n AdkMessage\n> = (message) => {\n switch (message.type) {\n case \"human\":\n return {\n role: \"user\",\n id: message.id,\n content: contentToParts(message.content),\n };\n\n case \"ai\": {\n const toolCallParts: ToolCallMessagePart[] =\n message.tool_calls?.map((tc) => ({\n type: \"tool-call\",\n toolCallId: tc.id,\n toolName: tc.name,\n args: tc.args,\n argsText: tc.argsText ?? JSON.stringify(tc.args),\n })) ?? [];\n\n return {\n role: \"assistant\",\n id: message.id,\n content: [...contentToParts(message.content), ...toolCallParts],\n ...(message.status && { status: message.status }),\n ...(message.author && {\n metadata: {\n custom: { author: message.author, branch: message.branch },\n },\n }),\n };\n }\n\n case \"tool\":\n return {\n role: \"tool\",\n toolCallId: message.tool_call_id,\n toolName: message.name,\n result: message.content,\n isError: message.status === \"error\",\n };\n }\n};\n"],"mappings":";;AAaA,MAAM,kBAAkB,YAAkD;CACxE,IAAI,OAAO,YAAY,UACrB,OAAO,CAAC;EAAE,MAAM;EAAiB,MAAM;CAAQ,CAAC;CAElD,OAAQ,QACL,KAAK,SAA6B;EACjC,QAAQ,KAAK,MAAb;GACE,KAAK,QACH,OAAO;IAAE,MAAM;IAAQ,MAAM,KAAK;GAAK;GACzC,KAAK,aACH,OAAO;IAAE,MAAM;IAAa,MAAM,KAAK;GAAK;GAC9C,KAAK,SACH,OAAO;IACL,MAAM;IACN,OAAO,QAAQ,KAAK,SAAS,UAAU,KAAK;GAC9C;GACF,KAAK,aACH,OAAO;IAAE,MAAM;IAAS,OAAO,KAAK;GAAI;GAC1C,KAAK,QACH,OAAO;IACL,MAAM;IACN,MAAM,KAAK;IACX,UAAU,KAAK;IACf,GAAI,KAAK,YAAY,QAAQ,EAAE,UAAU,KAAK,SAAS;GACzD;GACF,KAAK,YACH,OAAO;IACL,MAAM;IACN,MAAM;IACN,MAAM;KACJ,KAAK,KAAK;KACV,GAAI,KAAK,YAAY,QAAQ,EAAE,UAAU,KAAK,SAAS;IACzD;GACF;GACF,KAAK,QACH,OAAO;IACL,MAAM;IACN,MAAM;IACN,MAAM;KAAE,MAAM,KAAK;KAAM,UAAU,KAAK;IAAS;GACnD;GACF,KAAK,eACH,OAAO;IACL,MAAM;IACN,MAAM;IACN,MAAM;KAAE,QAAQ,KAAK;KAAQ,SAAS,KAAK;IAAQ;GACrD;GACF,SACE,OAAO;EACX;CACF,CAAC,EACA,QAAQ,MAAkC,MAAM,IAAI;AACzD;AAEA,MAAa,qBAER,YAAY;CACf,QAAQ,QAAQ,MAAhB;EACE,KAAK,SACH,OAAO;GACL,MAAM;GACN,IAAI,QAAQ;GACZ,SAAS,eAAe,QAAQ,OAAO;EACzC;EAEF,KAAK,MAAM;GACT,MAAM,gBACJ,QAAQ,YAAY,KAAK,QAAQ;IAC/B,MAAM;IACN,YAAY,GAAG;IACf,UAAU,GAAG;IACb,MAAM,GAAG;IACT,UAAU,GAAG,YAAY,KAAK,UAAU,GAAG,IAAI;GACjD,EAAE,KAAK,CAAC;GAEV,OAAO;IACL,MAAM;IACN,IAAI,QAAQ;IACZ,SAAS,CAAC,GAAG,eAAe,QAAQ,OAAO,GAAG,GAAG,aAAa;IAC9D,GAAI,QAAQ,UAAU,EAAE,QAAQ,QAAQ,OAAO;IAC/C,GAAI,QAAQ,UAAU,EACpB,UAAU,EACR,QAAQ;KAAE,QAAQ,QAAQ;KAAQ,QAAQ,QAAQ;IAAO,EAC3D,EACF;GACF;EACF;EAEA,KAAK,QACH,OAAO;GACL,MAAM;GACN,YAAY,QAAQ;GACpB,UAAU,QAAQ;GAClB,QAAQ,QAAQ;GAChB,SAAS,QAAQ,WAAW;EAC9B;CACJ;AACF"}
1
+ {"version":3,"file":"convertAdkMessages.js","names":[],"sources":["../src/convertAdkMessages.ts"],"sourcesContent":["\"use client\";\n\nimport type { ToolCallMessagePart } from \"@assistant-ui/core\";\nimport type { useExternalMessageConverter } from \"@assistant-ui/core/react\";\nimport type { AdkMessage, AdkMessageContentPart } from \"./types\";\n\ntype ContentPart =\n | { type: \"text\"; text: string }\n | { type: \"reasoning\"; text: string }\n | { type: \"image\"; image: string }\n | { type: \"file\"; data: string; mimeType: string; filename?: string }\n | { type: \"data\"; name: string; data: unknown };\n\nconst contentToParts = (content: AdkMessage[\"content\"]): ContentPart[] => {\n if (typeof content === \"string\")\n return [{ type: \"text\" as const, text: content }];\n\n return (content as AdkMessageContentPart[])\n .map((part): ContentPart | null => {\n switch (part.type) {\n case \"text\":\n return { type: \"text\", text: part.text };\n case \"reasoning\":\n return { type: \"reasoning\", text: part.text };\n case \"image\":\n return {\n type: \"image\",\n image: `data:${part.mimeType};base64,${part.data}`,\n };\n case \"image_url\":\n return { type: \"image\", image: part.url };\n case \"file\":\n return {\n type: \"file\",\n data: part.data,\n mimeType: part.mimeType,\n ...(part.filename != null && { filename: part.filename }),\n };\n case \"file_url\":\n return {\n type: \"data\",\n name: \"file_url\",\n data: {\n url: part.url,\n ...(part.mimeType != null && { mimeType: part.mimeType }),\n },\n };\n case \"code\":\n return {\n type: \"data\",\n name: \"executable_code\",\n data: { code: part.code, language: part.language },\n };\n case \"code_result\":\n return {\n type: \"data\",\n name: \"code_execution_result\",\n data: { output: part.output, outcome: part.outcome },\n };\n default:\n return null;\n }\n })\n .filter((p): p is NonNullable<typeof p> => p !== null);\n};\n\nexport const convertAdkMessage: useExternalMessageConverter.Callback<\n AdkMessage\n> = (message) => {\n switch (message.type) {\n case \"human\":\n return {\n role: \"user\",\n id: message.id,\n content: contentToParts(message.content),\n };\n\n case \"ai\": {\n const toolCallParts: ToolCallMessagePart[] =\n message.tool_calls?.map((tc) => ({\n type: \"tool-call\",\n toolCallId: tc.id,\n toolName: tc.name,\n args: tc.args,\n argsText: tc.argsText ?? JSON.stringify(tc.args),\n })) ?? [];\n\n return {\n role: \"assistant\",\n id: message.id,\n content: [...contentToParts(message.content), ...toolCallParts],\n ...(message.status && { status: message.status }),\n ...(message.author && {\n metadata: {\n custom: { author: message.author, branch: message.branch },\n },\n }),\n };\n }\n\n case \"tool\":\n return {\n role: \"tool\",\n toolCallId: message.tool_call_id,\n toolName: message.name,\n result: message.content,\n isError: message.status === \"error\",\n };\n }\n};\n"],"mappings":";;AAaA,MAAM,kBAAkB,YAAkD;CACxE,IAAI,OAAO,YAAY,UACrB,OAAO,CAAC;EAAE,MAAM;EAAiB,MAAM;CAAQ,CAAC;CAElD,OAAQ,QACL,KAAK,SAA6B;EACjC,QAAQ,KAAK,MAAb;GACE,KAAK,QACH,OAAO;IAAE,MAAM;IAAQ,MAAM,KAAK;GAAK;GACzC,KAAK,aACH,OAAO;IAAE,MAAM;IAAa,MAAM,KAAK;GAAK;GAC9C,KAAK,SACH,OAAO;IACL,MAAM;IACN,OAAO,QAAQ,KAAK,SAAS,UAAU,KAAK;GAC9C;GACF,KAAK,aACH,OAAO;IAAE,MAAM;IAAS,OAAO,KAAK;GAAI;GAC1C,KAAK,QACH,OAAO;IACL,MAAM;IACN,MAAM,KAAK;IACX,UAAU,KAAK;IACf,GAAI,KAAK,YAAY,QAAQ,EAAE,UAAU,KAAK,SAAS;GACzD;GACF,KAAK,YACH,OAAO;IACL,MAAM;IACN,MAAM;IACN,MAAM;KACJ,KAAK,KAAK;KACV,GAAI,KAAK,YAAY,QAAQ,EAAE,UAAU,KAAK,SAAS;IACzD;GACF;GACF,KAAK,QACH,OAAO;IACL,MAAM;IACN,MAAM;IACN,MAAM;KAAE,MAAM,KAAK;KAAM,UAAU,KAAK;IAAS;GACnD;GACF,KAAK,eACH,OAAO;IACL,MAAM;IACN,MAAM;IACN,MAAM;KAAE,QAAQ,KAAK;KAAQ,SAAS,KAAK;IAAQ;GACrD;GACF,SACE,OAAO;EACX;CACF,CAAC,CAAC,CACD,QAAQ,MAAkC,MAAM,IAAI;AACzD;AAEA,MAAa,qBAER,YAAY;CACf,QAAQ,QAAQ,MAAhB;EACE,KAAK,SACH,OAAO;GACL,MAAM;GACN,IAAI,QAAQ;GACZ,SAAS,eAAe,QAAQ,OAAO;EACzC;EAEF,KAAK,MAAM;GACT,MAAM,gBACJ,QAAQ,YAAY,KAAK,QAAQ;IAC/B,MAAM;IACN,YAAY,GAAG;IACf,UAAU,GAAG;IACb,MAAM,GAAG;IACT,UAAU,GAAG,YAAY,KAAK,UAAU,GAAG,IAAI;GACjD,EAAE,KAAK,CAAC;GAEV,OAAO;IACL,MAAM;IACN,IAAI,QAAQ;IACZ,SAAS,CAAC,GAAG,eAAe,QAAQ,OAAO,GAAG,GAAG,aAAa;IAC9D,GAAI,QAAQ,UAAU,EAAE,QAAQ,QAAQ,OAAO;IAC/C,GAAI,QAAQ,UAAU,EACpB,UAAU,EACR,QAAQ;KAAE,QAAQ,QAAQ;KAAQ,QAAQ,QAAQ;IAAO,EAC3D,EACF;GACF;EACF;EAEA,KAAK,QACH,OAAO;GACL,MAAM;GACN,YAAY,QAAQ;GACpB,UAAU,QAAQ;GAClB,QAAQ,QAAQ;GAChB,SAAS,QAAQ,WAAW;EAC9B;CACJ;AACF"}
package/dist/hooks.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"hooks.js","names":["uuidv4"],"sources":["../src/hooks.ts"],"sourcesContent":["import { useAui, useAuiState } from \"@assistant-ui/store\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport type { ReadonlyJSONValue } from \"assistant-stream/utils\";\nimport type {\n AdkMessage,\n AdkSendMessageConfig,\n AdkToolConfirmation,\n AdkAuthCredential,\n AdkAuthRequest,\n AdkMessageMetadata,\n} from \"./types\";\n\nexport const symbolAdkRuntimeExtras = Symbol(\"adk-runtime-extras\");\n\nexport type AdkRuntimeExtras = {\n [symbolAdkRuntimeExtras]: true;\n send: (messages: AdkMessage[], config: AdkSendMessageConfig) => Promise<void>;\n agentInfo: { name?: string | undefined; branch?: string | undefined };\n stateDelta: Record<string, unknown>;\n artifactDelta: Record<string, number>;\n longRunningToolIds: string[];\n toolConfirmations: AdkToolConfirmation[];\n authRequests: AdkAuthRequest[];\n escalated: boolean;\n messageMetadata: Map<string, AdkMessageMetadata>;\n};\n\nconst asAdkRuntimeExtras = (extras: unknown): AdkRuntimeExtras => {\n if (\n typeof extras !== \"object\" ||\n extras == null ||\n !(symbolAdkRuntimeExtras in extras)\n )\n throw new Error(\n \"This method can only be called when you are using useAdkRuntime\",\n );\n\n return extras as AdkRuntimeExtras;\n};\n\n/** Returns the name and branch of the currently active ADK agent. */\nexport const useAdkAgentInfo = () => {\n return useAuiState((s) => {\n const extras = s.thread.extras;\n if (!extras) return undefined;\n return asAdkRuntimeExtras(extras).agentInfo;\n });\n};\n\n/** Returns the accumulated session state delta from ADK events. */\nexport const useAdkSessionState = () => {\n return useAuiState((s) => {\n const extras = s.thread.extras;\n if (!extras) return {};\n return asAdkRuntimeExtras(extras).stateDelta;\n });\n};\n\n/** Returns a function to send raw ADK messages. */\nexport const useAdkSend = () => {\n const aui = useAui();\n return (messages: AdkMessage[], config: AdkSendMessageConfig) => {\n const extras = aui.thread().getState().extras;\n const { send } = asAdkRuntimeExtras(extras);\n return send(messages, config);\n };\n};\n\n/** Returns the IDs of long-running tools awaiting external input. */\nexport const useAdkLongRunningToolIds = () => {\n return useAuiState((s) => {\n const extras = s.thread.extras;\n if (!extras) return [];\n return asAdkRuntimeExtras(extras).longRunningToolIds;\n });\n};\n\n/** Returns pending tool confirmation requests (from SecurityPlugin etc). */\nexport const useAdkToolConfirmations = () => {\n return useAuiState((s) => {\n const extras = s.thread.extras;\n if (!extras) return [];\n return asAdkRuntimeExtras(extras).toolConfirmations;\n });\n};\n\n/** Returns pending auth credential requests from tools. */\nexport const useAdkAuthRequests = () => {\n return useAuiState((s) => {\n const extras = s.thread.extras;\n if (!extras) return [];\n return asAdkRuntimeExtras(extras).authRequests;\n });\n};\n\n/** Returns the accumulated artifact delta (filename → version). */\nexport const useAdkArtifacts = () => {\n return useAuiState((s) => {\n const extras = s.thread.extras;\n if (!extras) return {};\n return asAdkRuntimeExtras(extras).artifactDelta;\n });\n};\n\n/** Returns whether any agent has escalated (requested human handoff). */\nexport const useAdkEscalation = () => {\n return useAuiState((s) => {\n const extras = s.thread.extras;\n if (!extras) return false;\n return asAdkRuntimeExtras(extras).escalated;\n });\n};\n\n/** Returns per-message metadata (grounding, citation, usage). Keyed by message ID. */\nexport const useAdkMessageMetadata = () => {\n return useAuiState((s) => {\n const extras = s.thread.extras;\n if (!extras) return new Map<string, AdkMessageMetadata>();\n return asAdkRuntimeExtras(extras).messageMetadata;\n });\n};\n\n// ── Convenience helpers for interactive flows ──\n\n/** Returns a function to confirm or deny a pending tool confirmation. */\nexport const useAdkConfirmTool = () => {\n const aui = useAui();\n return (\n toolCallId: string,\n confirmed: boolean,\n payload?: ReadonlyJSONValue,\n ) => {\n const extras = aui.thread().getState().extras;\n const { send } = asAdkRuntimeExtras(extras);\n return send(\n [\n {\n id: uuidv4(),\n type: \"tool\",\n tool_call_id: toolCallId,\n name: \"adk_request_confirmation\",\n content: JSON.stringify({\n confirmed,\n ...(payload != null && { payload }),\n }),\n status: \"success\",\n },\n ],\n {},\n );\n };\n};\n\n/** Returns a function to submit auth credentials for a pending auth request. */\nexport const useAdkSubmitAuth = () => {\n const aui = useAui();\n return (toolCallId: string, credential: AdkAuthCredential) => {\n const extras = aui.thread().getState().extras;\n const { send } = asAdkRuntimeExtras(extras);\n return send(\n [\n {\n id: uuidv4(),\n type: \"tool\",\n tool_call_id: toolCallId,\n name: \"adk_request_credential\",\n content: JSON.stringify(credential),\n status: \"success\",\n },\n ],\n {},\n );\n };\n};\n\n/** Returns a function to submit the user's answer for a pending `adk_request_input` HITL interrupt. */\nexport const useAdkSubmitInput = () => {\n const aui = useAui();\n return (toolCallId: string, result: ReadonlyJSONValue) => {\n const extras = aui.thread().getState().extras;\n const { send } = asAdkRuntimeExtras(extras);\n return send(\n [\n {\n id: uuidv4(),\n type: \"tool\",\n tool_call_id: toolCallId,\n name: \"adk_request_input\",\n content: JSON.stringify({ result }),\n status: \"success\",\n },\n ],\n {},\n );\n };\n};\n\n// ── State prefix helpers ──\n\nconst APP_PREFIX = \"app:\";\nconst USER_PREFIX = \"user:\";\nconst TEMP_PREFIX = \"temp:\";\n\nconst filterByPrefix = (\n state: Record<string, unknown>,\n prefix: string,\n): Record<string, unknown> => {\n const result: Record<string, unknown> = {};\n for (const key of Object.keys(state)) {\n if (key.startsWith(prefix)) {\n result[key.slice(prefix.length)] = state[key];\n }\n }\n return result;\n};\n\n/** Returns app-level state (keys prefixed with `app:`, prefix stripped). */\nexport const useAdkAppState = () => {\n return useAuiState((s) => {\n const extras = s.thread.extras;\n if (!extras) return {};\n return filterByPrefix(asAdkRuntimeExtras(extras).stateDelta, APP_PREFIX);\n });\n};\n\n/** Returns user-level state (keys prefixed with `user:`, prefix stripped). */\nexport const useAdkUserState = () => {\n return useAuiState((s) => {\n const extras = s.thread.extras;\n if (!extras) return {};\n return filterByPrefix(asAdkRuntimeExtras(extras).stateDelta, USER_PREFIX);\n });\n};\n\n/** Returns temp state (keys prefixed with `temp:`, prefix stripped). Not persisted. */\nexport const useAdkTempState = () => {\n return useAuiState((s) => {\n const extras = s.thread.extras;\n if (!extras) return {};\n return filterByPrefix(asAdkRuntimeExtras(extras).stateDelta, TEMP_PREFIX);\n });\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"hooks.js","names":["uuidv4"],"sources":["../src/hooks.ts"],"sourcesContent":["import { useAui, useAuiState } from \"@assistant-ui/store\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport type { ReadonlyJSONValue } from \"assistant-stream/utils\";\nimport type {\n AdkMessage,\n AdkSendMessageConfig,\n AdkToolConfirmation,\n AdkAuthCredential,\n AdkAuthRequest,\n AdkMessageMetadata,\n} from \"./types\";\n\nexport const symbolAdkRuntimeExtras = Symbol(\"adk-runtime-extras\");\n\nexport type AdkRuntimeExtras = {\n [symbolAdkRuntimeExtras]: true;\n send: (messages: AdkMessage[], config: AdkSendMessageConfig) => Promise<void>;\n agentInfo: { name?: string | undefined; branch?: string | undefined };\n stateDelta: Record<string, unknown>;\n artifactDelta: Record<string, number>;\n longRunningToolIds: string[];\n toolConfirmations: AdkToolConfirmation[];\n authRequests: AdkAuthRequest[];\n escalated: boolean;\n messageMetadata: Map<string, AdkMessageMetadata>;\n};\n\nconst asAdkRuntimeExtras = (extras: unknown): AdkRuntimeExtras => {\n if (\n typeof extras !== \"object\" ||\n extras == null ||\n !(symbolAdkRuntimeExtras in extras)\n )\n throw new Error(\n \"This method can only be called when you are using useAdkRuntime\",\n );\n\n return extras as AdkRuntimeExtras;\n};\n\n/** Returns the name and branch of the currently active ADK agent. */\nexport const useAdkAgentInfo = () => {\n return useAuiState((s) => {\n const extras = s.thread.extras;\n if (!extras) return undefined;\n return asAdkRuntimeExtras(extras).agentInfo;\n });\n};\n\n/** Returns the accumulated session state delta from ADK events. */\nexport const useAdkSessionState = () => {\n return useAuiState((s) => {\n const extras = s.thread.extras;\n if (!extras) return {};\n return asAdkRuntimeExtras(extras).stateDelta;\n });\n};\n\n/** Returns a function to send raw ADK messages. */\nexport const useAdkSend = () => {\n const aui = useAui();\n return (messages: AdkMessage[], config: AdkSendMessageConfig) => {\n const extras = aui.thread().getState().extras;\n const { send } = asAdkRuntimeExtras(extras);\n return send(messages, config);\n };\n};\n\n/** Returns the IDs of long-running tools awaiting external input. */\nexport const useAdkLongRunningToolIds = () => {\n return useAuiState((s) => {\n const extras = s.thread.extras;\n if (!extras) return [];\n return asAdkRuntimeExtras(extras).longRunningToolIds;\n });\n};\n\n/** Returns pending tool confirmation requests (from SecurityPlugin etc). */\nexport const useAdkToolConfirmations = () => {\n return useAuiState((s) => {\n const extras = s.thread.extras;\n if (!extras) return [];\n return asAdkRuntimeExtras(extras).toolConfirmations;\n });\n};\n\n/** Returns pending auth credential requests from tools. */\nexport const useAdkAuthRequests = () => {\n return useAuiState((s) => {\n const extras = s.thread.extras;\n if (!extras) return [];\n return asAdkRuntimeExtras(extras).authRequests;\n });\n};\n\n/** Returns the accumulated artifact delta (filename → version). */\nexport const useAdkArtifacts = () => {\n return useAuiState((s) => {\n const extras = s.thread.extras;\n if (!extras) return {};\n return asAdkRuntimeExtras(extras).artifactDelta;\n });\n};\n\n/** Returns whether any agent has escalated (requested human handoff). */\nexport const useAdkEscalation = () => {\n return useAuiState((s) => {\n const extras = s.thread.extras;\n if (!extras) return false;\n return asAdkRuntimeExtras(extras).escalated;\n });\n};\n\n/** Returns per-message metadata (grounding, citation, usage). Keyed by message ID. */\nexport const useAdkMessageMetadata = () => {\n return useAuiState((s) => {\n const extras = s.thread.extras;\n if (!extras) return new Map<string, AdkMessageMetadata>();\n return asAdkRuntimeExtras(extras).messageMetadata;\n });\n};\n\n// ── Convenience helpers for interactive flows ──\n\n/** Returns a function to confirm or deny a pending tool confirmation. */\nexport const useAdkConfirmTool = () => {\n const aui = useAui();\n return (\n toolCallId: string,\n confirmed: boolean,\n payload?: ReadonlyJSONValue,\n ) => {\n const extras = aui.thread().getState().extras;\n const { send } = asAdkRuntimeExtras(extras);\n return send(\n [\n {\n id: uuidv4(),\n type: \"tool\",\n tool_call_id: toolCallId,\n name: \"adk_request_confirmation\",\n content: JSON.stringify({\n confirmed,\n ...(payload != null && { payload }),\n }),\n status: \"success\",\n },\n ],\n {},\n );\n };\n};\n\n/** Returns a function to submit auth credentials for a pending auth request. */\nexport const useAdkSubmitAuth = () => {\n const aui = useAui();\n return (toolCallId: string, credential: AdkAuthCredential) => {\n const extras = aui.thread().getState().extras;\n const { send } = asAdkRuntimeExtras(extras);\n return send(\n [\n {\n id: uuidv4(),\n type: \"tool\",\n tool_call_id: toolCallId,\n name: \"adk_request_credential\",\n content: JSON.stringify(credential),\n status: \"success\",\n },\n ],\n {},\n );\n };\n};\n\n/** Returns a function to submit the user's answer for a pending `adk_request_input` HITL interrupt. */\nexport const useAdkSubmitInput = () => {\n const aui = useAui();\n return (toolCallId: string, result: ReadonlyJSONValue) => {\n const extras = aui.thread().getState().extras;\n const { send } = asAdkRuntimeExtras(extras);\n return send(\n [\n {\n id: uuidv4(),\n type: \"tool\",\n tool_call_id: toolCallId,\n name: \"adk_request_input\",\n content: JSON.stringify({ result }),\n status: \"success\",\n },\n ],\n {},\n );\n };\n};\n\n// ── State prefix helpers ──\n\nconst APP_PREFIX = \"app:\";\nconst USER_PREFIX = \"user:\";\nconst TEMP_PREFIX = \"temp:\";\n\nconst filterByPrefix = (\n state: Record<string, unknown>,\n prefix: string,\n): Record<string, unknown> => {\n const result: Record<string, unknown> = {};\n for (const key of Object.keys(state)) {\n if (key.startsWith(prefix)) {\n result[key.slice(prefix.length)] = state[key];\n }\n }\n return result;\n};\n\n/** Returns app-level state (keys prefixed with `app:`, prefix stripped). */\nexport const useAdkAppState = () => {\n return useAuiState((s) => {\n const extras = s.thread.extras;\n if (!extras) return {};\n return filterByPrefix(asAdkRuntimeExtras(extras).stateDelta, APP_PREFIX);\n });\n};\n\n/** Returns user-level state (keys prefixed with `user:`, prefix stripped). */\nexport const useAdkUserState = () => {\n return useAuiState((s) => {\n const extras = s.thread.extras;\n if (!extras) return {};\n return filterByPrefix(asAdkRuntimeExtras(extras).stateDelta, USER_PREFIX);\n });\n};\n\n/** Returns temp state (keys prefixed with `temp:`, prefix stripped). Not persisted. */\nexport const useAdkTempState = () => {\n return useAuiState((s) => {\n const extras = s.thread.extras;\n if (!extras) return {};\n return filterByPrefix(asAdkRuntimeExtras(extras).stateDelta, TEMP_PREFIX);\n });\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"useAdkMessages.js","names":["uuidv4"],"sources":["../src/useAdkMessages.ts"],"sourcesContent":["import { useState, useCallback, useRef, useMemo } from \"react\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport { useAui } from \"@assistant-ui/store\";\nimport { AdkEventAccumulator } from \"./AdkEventAccumulator\";\nimport { contentToParts } from \"./contentToParts\";\nimport type {\n AdkEvent,\n AdkMessage,\n AdkMessageMetadata,\n AdkSendMessageConfig,\n AdkStreamCallback,\n AdkToolConfirmation,\n AdkAuthRequest,\n OnAdkErrorCallback,\n OnAdkCustomEventCallback,\n OnAdkAgentTransferCallback,\n} from \"./types\";\n\nexport type UseAdkMessagesOptions = {\n stream: AdkStreamCallback;\n eventHandlers?: {\n onError?: OnAdkErrorCallback;\n onCustomEvent?: OnAdkCustomEventCallback;\n onAgentTransfer?: OnAdkAgentTransferCallback;\n };\n};\n\nexport const useAdkMessages = ({\n stream,\n eventHandlers,\n}: UseAdkMessagesOptions) => {\n const [messages, _setMessages] = useState<AdkMessage[]>([]);\n const [stateDelta, setStateDelta] = useState<Record<string, unknown>>({});\n const [agentInfo, setAgentInfo] = useState<{\n name?: string | undefined;\n branch?: string | undefined;\n }>({});\n const [longRunningToolIds, setLongRunningToolIds] = useState<string[]>([]);\n const [artifactDelta, setArtifactDelta] = useState<Record<string, number>>(\n {},\n );\n const [toolConfirmations, setToolConfirmations] = useState<\n AdkToolConfirmation[]\n >([]);\n const [authRequests, setAuthRequests] = useState<AdkAuthRequest[]>([]);\n const [escalated, setEscalated] = useState(false);\n const [messageMetadata, setMessageMetadata] = useState<\n Map<string, AdkMessageMetadata>\n >(new Map());\n const lastTransferToAgentRef = useRef<string | undefined>(undefined);\n const messagesRef = useRef(messages);\n messagesRef.current = messages;\n const stateDeltaRef = useRef(stateDelta);\n stateDeltaRef.current = stateDelta;\n const artifactDeltaRef = useRef(artifactDelta);\n artifactDeltaRef.current = artifactDelta;\n const messageMetadataRef = useRef(messageMetadata);\n messageMetadataRef.current = messageMetadata;\n\n const setMessagesImmediate = useCallback((msgs: AdkMessage[]) => {\n messagesRef.current = msgs;\n _setMessages(msgs);\n }, []);\n\n // Replace the message list AND reset derived per-turn HITL state.\n // Used by truncation paths (edit, reload, load) so that stale interrupt\n // markers and per-message metadata from the removed messages don't leak\n // into the next turn.\n const replaceMessages = useCallback(\n (msgs: AdkMessage[]) => {\n setMessagesImmediate(msgs);\n setLongRunningToolIds([]);\n setToolConfirmations([]);\n setAuthRequests([]);\n setEscalated(false);\n setMessageMetadata(new Map());\n },\n [setMessagesImmediate],\n );\n\n const abortControllerRef = useRef<AbortController | null>(null);\n\n const { onError, onCustomEvent, onAgentTransfer } = useMemo(\n () => eventHandlers ?? {},\n [eventHandlers],\n );\n\n const aui = useAui();\n const sendMessage = useCallback(\n async (newMessages: AdkMessage[], config: AdkSendMessageConfig) => {\n const newMessagesWithId = newMessages.map((m) =>\n m.id ? m : { ...m, id: uuidv4() },\n ) as AdkMessage[];\n\n const accumulator = new AdkEventAccumulator(messagesRef.current);\n for (const msg of newMessagesWithId) {\n accumulator.processEvent(messageToEvent(msg));\n }\n setMessagesImmediate(accumulator.getMessages());\n\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n\n try {\n const response = await stream(newMessagesWithId, {\n ...config,\n abortSignal: abortController.signal,\n initialize: async () => {\n return await aui.threadListItem().initialize();\n },\n });\n\n for await (const event of response) {\n const updatedMessages = accumulator.processEvent(event);\n setMessagesImmediate(updatedMessages);\n setStateDelta({\n ...stateDeltaRef.current,\n ...accumulator.getStateDelta(),\n });\n setAgentInfo(accumulator.getAgentInfo());\n setLongRunningToolIds(accumulator.getLongRunningToolIds());\n setArtifactDelta({\n ...artifactDeltaRef.current,\n ...accumulator.getArtifactDelta(),\n });\n setToolConfirmations(accumulator.getToolConfirmations());\n setAuthRequests(accumulator.getAuthRequests());\n setEscalated(accumulator.isEscalated());\n {\n const newMeta = accumulator.getMessageMetadata();\n if (newMeta.size > 0) {\n setMessageMetadata(\n new Map([...messageMetadataRef.current, ...newMeta]),\n );\n }\n }\n\n const transfer = accumulator.getLastTransferToAgent();\n if (transfer && transfer !== lastTransferToAgentRef.current) {\n lastTransferToAgentRef.current = transfer;\n onAgentTransfer?.(transfer);\n }\n\n // Fire custom event callback for events with customMetadata\n if (event.customMetadata && onCustomEvent) {\n for (const [key, value] of Object.entries(event.customMetadata)) {\n onCustomEvent(key, value);\n }\n }\n\n if (event.errorCode || event.errorMessage) {\n onError?.(event.errorMessage ?? event.errorCode);\n }\n }\n } catch (error) {\n if (\n !abortController.signal.aborted &&\n !(error instanceof Error && error.name === \"AbortError\")\n ) {\n throw error;\n }\n } finally {\n if (abortControllerRef.current === abortController) {\n abortControllerRef.current = null;\n }\n }\n },\n [\n aui,\n setMessagesImmediate,\n stream,\n onError,\n onCustomEvent,\n onAgentTransfer,\n ],\n );\n\n const cancel = useCallback(() => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n }, []);\n\n return {\n messages,\n stateDelta,\n agentInfo,\n longRunningToolIds,\n artifactDelta,\n toolConfirmations,\n authRequests,\n escalated,\n messageMetadata,\n sendMessage,\n cancel,\n setMessages: setMessagesImmediate,\n replaceMessages,\n };\n};\n\n/** @internal — exported for unit tests. */\nexport const messageToEvent = (msg: AdkMessage): AdkEvent => {\n if (msg.type === \"human\") {\n return {\n id: msg.id ?? uuidv4(),\n author: \"user\",\n content: { role: \"user\", parts: contentToParts(msg.content) },\n };\n }\n\n if (msg.type === \"tool\") {\n let response: unknown;\n try {\n response = JSON.parse(msg.content);\n } catch {\n response = msg.content;\n }\n return {\n id: msg.id ?? uuidv4(),\n content: {\n role: \"user\",\n parts: [\n {\n functionResponse: {\n name: msg.name,\n id: msg.tool_call_id,\n response,\n },\n },\n ],\n },\n };\n }\n\n const result: AdkEvent = { id: msg.id ?? uuidv4() };\n if (msg.author != null) result.author = msg.author;\n result.content = {\n role: \"model\",\n parts: [\n ...contentToParts(msg.content),\n ...(msg.tool_calls?.map((tc) => ({\n functionCall: { name: tc.name, id: tc.id, args: { ...tc.args } },\n })) ?? []),\n ],\n };\n return result;\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"useAdkMessages.js","names":["uuidv4"],"sources":["../src/useAdkMessages.ts"],"sourcesContent":["import { useState, useCallback, useRef, useMemo } from \"react\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport { useAui } from \"@assistant-ui/store\";\nimport { AdkEventAccumulator } from \"./AdkEventAccumulator\";\nimport { contentToParts } from \"./contentToParts\";\nimport type {\n AdkEvent,\n AdkMessage,\n AdkMessageMetadata,\n AdkSendMessageConfig,\n AdkStreamCallback,\n AdkToolConfirmation,\n AdkAuthRequest,\n OnAdkErrorCallback,\n OnAdkCustomEventCallback,\n OnAdkAgentTransferCallback,\n} from \"./types\";\n\nexport type UseAdkMessagesOptions = {\n stream: AdkStreamCallback;\n eventHandlers?: {\n onError?: OnAdkErrorCallback;\n onCustomEvent?: OnAdkCustomEventCallback;\n onAgentTransfer?: OnAdkAgentTransferCallback;\n };\n};\n\nexport const useAdkMessages = ({\n stream,\n eventHandlers,\n}: UseAdkMessagesOptions) => {\n const [messages, _setMessages] = useState<AdkMessage[]>([]);\n const [stateDelta, setStateDelta] = useState<Record<string, unknown>>({});\n const [agentInfo, setAgentInfo] = useState<{\n name?: string | undefined;\n branch?: string | undefined;\n }>({});\n const [longRunningToolIds, setLongRunningToolIds] = useState<string[]>([]);\n const [artifactDelta, setArtifactDelta] = useState<Record<string, number>>(\n {},\n );\n const [toolConfirmations, setToolConfirmations] = useState<\n AdkToolConfirmation[]\n >([]);\n const [authRequests, setAuthRequests] = useState<AdkAuthRequest[]>([]);\n const [escalated, setEscalated] = useState(false);\n const [messageMetadata, setMessageMetadata] = useState<\n Map<string, AdkMessageMetadata>\n >(new Map());\n const lastTransferToAgentRef = useRef<string | undefined>(undefined);\n const messagesRef = useRef(messages);\n messagesRef.current = messages;\n const stateDeltaRef = useRef(stateDelta);\n stateDeltaRef.current = stateDelta;\n const artifactDeltaRef = useRef(artifactDelta);\n artifactDeltaRef.current = artifactDelta;\n const messageMetadataRef = useRef(messageMetadata);\n messageMetadataRef.current = messageMetadata;\n\n const setMessagesImmediate = useCallback((msgs: AdkMessage[]) => {\n messagesRef.current = msgs;\n _setMessages(msgs);\n }, []);\n\n // Replace the message list AND reset derived per-turn HITL state.\n // Used by truncation paths (edit, reload, load) so that stale interrupt\n // markers and per-message metadata from the removed messages don't leak\n // into the next turn.\n const replaceMessages = useCallback(\n (msgs: AdkMessage[]) => {\n setMessagesImmediate(msgs);\n setLongRunningToolIds([]);\n setToolConfirmations([]);\n setAuthRequests([]);\n setEscalated(false);\n setMessageMetadata(new Map());\n },\n [setMessagesImmediate],\n );\n\n const abortControllerRef = useRef<AbortController | null>(null);\n\n const { onError, onCustomEvent, onAgentTransfer } = useMemo(\n () => eventHandlers ?? {},\n [eventHandlers],\n );\n\n const aui = useAui();\n const sendMessage = useCallback(\n async (newMessages: AdkMessage[], config: AdkSendMessageConfig) => {\n const newMessagesWithId = newMessages.map((m) =>\n m.id ? m : { ...m, id: uuidv4() },\n ) as AdkMessage[];\n\n const accumulator = new AdkEventAccumulator(messagesRef.current);\n for (const msg of newMessagesWithId) {\n accumulator.processEvent(messageToEvent(msg));\n }\n setMessagesImmediate(accumulator.getMessages());\n\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n\n try {\n const response = await stream(newMessagesWithId, {\n ...config,\n abortSignal: abortController.signal,\n initialize: async () => {\n return await aui.threadListItem().initialize();\n },\n });\n\n for await (const event of response) {\n const updatedMessages = accumulator.processEvent(event);\n setMessagesImmediate(updatedMessages);\n setStateDelta({\n ...stateDeltaRef.current,\n ...accumulator.getStateDelta(),\n });\n setAgentInfo(accumulator.getAgentInfo());\n setLongRunningToolIds(accumulator.getLongRunningToolIds());\n setArtifactDelta({\n ...artifactDeltaRef.current,\n ...accumulator.getArtifactDelta(),\n });\n setToolConfirmations(accumulator.getToolConfirmations());\n setAuthRequests(accumulator.getAuthRequests());\n setEscalated(accumulator.isEscalated());\n {\n const newMeta = accumulator.getMessageMetadata();\n if (newMeta.size > 0) {\n setMessageMetadata(\n new Map([...messageMetadataRef.current, ...newMeta]),\n );\n }\n }\n\n const transfer = accumulator.getLastTransferToAgent();\n if (transfer && transfer !== lastTransferToAgentRef.current) {\n lastTransferToAgentRef.current = transfer;\n onAgentTransfer?.(transfer);\n }\n\n // Fire custom event callback for events with customMetadata\n if (event.customMetadata && onCustomEvent) {\n for (const [key, value] of Object.entries(event.customMetadata)) {\n onCustomEvent(key, value);\n }\n }\n\n if (event.errorCode || event.errorMessage) {\n onError?.(event.errorMessage ?? event.errorCode);\n }\n }\n } catch (error) {\n if (\n !abortController.signal.aborted &&\n !(error instanceof Error && error.name === \"AbortError\")\n ) {\n throw error;\n }\n } finally {\n if (abortControllerRef.current === abortController) {\n abortControllerRef.current = null;\n }\n }\n },\n [\n aui,\n setMessagesImmediate,\n stream,\n onError,\n onCustomEvent,\n onAgentTransfer,\n ],\n );\n\n const cancel = useCallback(() => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n }, []);\n\n return {\n messages,\n stateDelta,\n agentInfo,\n longRunningToolIds,\n artifactDelta,\n toolConfirmations,\n authRequests,\n escalated,\n messageMetadata,\n sendMessage,\n cancel,\n setMessages: setMessagesImmediate,\n replaceMessages,\n };\n};\n\n/** @internal — exported for unit tests. */\nexport const messageToEvent = (msg: AdkMessage): AdkEvent => {\n if (msg.type === \"human\") {\n return {\n id: msg.id ?? uuidv4(),\n author: \"user\",\n content: { role: \"user\", parts: contentToParts(msg.content) },\n };\n }\n\n if (msg.type === \"tool\") {\n let response: unknown;\n try {\n response = JSON.parse(msg.content);\n } catch {\n response = msg.content;\n }\n return {\n id: msg.id ?? uuidv4(),\n content: {\n role: \"user\",\n parts: [\n {\n functionResponse: {\n name: msg.name,\n id: msg.tool_call_id,\n response,\n },\n },\n ],\n },\n };\n }\n\n const result: AdkEvent = { id: msg.id ?? uuidv4() };\n if (msg.author != null) result.author = msg.author;\n result.content = {\n role: \"model\",\n parts: [\n ...contentToParts(msg.content),\n ...(msg.tool_calls?.map((tc) => ({\n functionCall: { name: tc.name, id: tc.id, args: { ...tc.args } },\n })) ?? []),\n ],\n };\n return result;\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"useAdkRuntime.js","names":["_exhaustiveCheck","uuidv4"],"sources":["../src/useAdkRuntime.ts"],"sourcesContent":["import { useEffect, useRef, useState } from \"react\";\nimport {\n getExternalStoreMessages,\n pickExternalStoreSharedOptions,\n type AttachmentAdapter,\n type DictationAdapter,\n type ExternalStoreSharedOptions,\n type FeedbackAdapter,\n type RealtimeVoiceAdapter,\n type SpeechSynthesisAdapter,\n type AppendMessage,\n type ThreadMessage,\n type ToolExecutionStatus,\n} from \"@assistant-ui/core\";\nimport {\n useCloudThreadListAdapter,\n useRemoteThreadListRuntime,\n useExternalMessageConverter,\n useExternalStoreRuntime,\n} from \"@assistant-ui/core/react\";\nimport { useAui } from \"@assistant-ui/store\";\nimport type { AssistantCloud } from \"assistant-cloud\";\nimport type { RemoteThreadListAdapter } from \"@assistant-ui/core\";\nimport type {\n AdkMessage,\n AdkSendMessageConfig,\n AdkStreamCallback,\n OnAdkErrorCallback,\n OnAdkCustomEventCallback,\n OnAdkAgentTransferCallback,\n} from \"./types\";\nimport { useAdkMessages } from \"./useAdkMessages\";\nimport { convertAdkMessage } from \"./convertAdkMessages\";\nimport { symbolAdkRuntimeExtras, type AdkRuntimeExtras } from \"./hooks\";\nimport { v4 as uuidv4 } from \"uuid\";\n\n/** @internal — exported for unit tests. */\nexport const getMessageContent = (msg: AppendMessage) => {\n const allContent = [\n ...msg.content,\n ...(msg.attachments?.flatMap((a) => a.content) ?? []),\n ];\n const content = allContent.map((part) => {\n const type = part.type;\n switch (type) {\n case \"text\":\n return { type: \"text\" as const, text: part.text };\n case \"image\":\n return { type: \"image_url\" as const, url: part.image };\n case \"file\":\n return {\n type: \"file\" as const,\n mimeType: part.mimeType,\n data: part.data,\n ...(part.filename != null && { filename: part.filename }),\n };\n\n case \"tool-call\":\n throw new Error(\"Tool call appends are not supported.\");\n\n default: {\n const _exhaustiveCheck:\n | \"reasoning\"\n | \"source\"\n | \"audio\"\n | \"data\"\n | \"generative-ui\" = type;\n throw new Error(\n `Unsupported append message part type: ${_exhaustiveCheck}`,\n );\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\n/** @internal — exported for unit tests. */\nexport const getPendingToolCalls = (messages: AdkMessage[]) => {\n const pending = new Map<string, { id: string; name: string }>();\n for (const msg of messages) {\n if (msg.type === \"ai\" && msg.tool_calls) {\n for (const tc of msg.tool_calls) {\n pending.set(tc.id, tc);\n }\n }\n if (msg.type === \"tool\") {\n pending.delete(msg.tool_call_id);\n }\n }\n return [...pending.values()];\n};\n\n/**\n * @internal — exported for unit tests.\n *\n * Returns `{cancelled: true}` tool responses for pending tool calls when the\n * user sends a new turn, EXCEPT for HITL interrupts marked via\n * `long_running_tool_ids` (`adk_request_input`, `adk_request_confirmation`,\n * `adk_request_credential`). Those must be answered through a dedicated tool\n * UI + submit helper, not auto-cancelled.\n */\nexport const getPendingCancellations = (\n messages: AdkMessage[],\n longRunningToolIds: readonly string[],\n): Array<AdkMessage & { type: \"tool\" }> => {\n const longRunningSet = new Set(longRunningToolIds);\n return getPendingToolCalls(messages)\n .filter((t) => !longRunningSet.has(t.id))\n .map(\n (t) =>\n ({\n id: uuidv4(),\n type: \"tool\",\n name: t.name,\n tool_call_id: t.id,\n content: JSON.stringify({ cancelled: true }),\n status: \"error\",\n }) satisfies AdkMessage & { type: \"tool\" },\n );\n};\n\nconst truncateAdkMessages = (\n threadMessages: readonly ThreadMessage[],\n parentId: string | null,\n): AdkMessage[] => {\n if (parentId === null) return [];\n const parentIndex = threadMessages.findIndex((m) => m.id === parentId);\n if (parentIndex === -1) return [];\n const truncated: AdkMessage[] = [];\n for (let i = 0; i <= parentIndex && i < threadMessages.length; i++) {\n truncated.push(...getExternalStoreMessages<AdkMessage>(threadMessages[i]!));\n }\n return truncated;\n};\n\nexport type UseAdkRuntimeOptions = ExternalStoreSharedOptions & {\n stream: AdkStreamCallback;\n autoCancelPendingToolCalls?: boolean | undefined;\n unstable_allowCancellation?: boolean | undefined;\n getCheckpointId?: (\n threadId: string,\n parentMessages: AdkMessage[],\n ) => Promise<string | null>;\n load?: (threadId: string) => Promise<{ messages: AdkMessage[] }>;\n create?: () => Promise<{ externalId: string }>;\n delete?: (threadId: string) => Promise<void>;\n adapters?:\n | {\n attachments?: AttachmentAdapter;\n speech?: SpeechSynthesisAdapter;\n dictation?: DictationAdapter;\n voice?: RealtimeVoiceAdapter;\n feedback?: FeedbackAdapter;\n }\n | undefined;\n eventHandlers?:\n | {\n onError?: OnAdkErrorCallback;\n onCustomEvent?: OnAdkCustomEventCallback;\n onAgentTransfer?: OnAdkAgentTransferCallback;\n }\n | undefined;\n cloud?: AssistantCloud | undefined;\n /**\n * A `RemoteThreadListAdapter` to use instead of the cloud adapter.\n * Use with `createAdkSessionAdapter` for ADK session-backed persistence.\n */\n sessionAdapter?: RemoteThreadListAdapter | undefined;\n};\n\nconst useAdkRuntimeImpl = (options: UseAdkRuntimeOptions) => {\n const {\n autoCancelPendingToolCalls,\n adapters: { attachments, dictation, feedback, speech, voice } = {},\n unstable_allowCancellation,\n stream,\n load,\n getCheckpointId,\n eventHandlers,\n } = options;\n const aui = useAui();\n const {\n messages,\n stateDelta,\n agentInfo,\n longRunningToolIds,\n artifactDelta,\n toolConfirmations,\n authRequests,\n escalated,\n messageMetadata,\n sendMessage,\n cancel,\n replaceMessages,\n } = useAdkMessages({\n stream,\n ...(eventHandlers && { eventHandlers }),\n });\n\n const [isRunning, setIsRunning] = useState(false);\n const [toolStatuses, setToolStatuses] = useState<\n Record<string, ToolExecutionStatus>\n >({});\n const hasExecutingTools = Object.values(toolStatuses).some(\n (s) => s?.type === \"executing\",\n );\n const effectiveIsRunning = isRunning || hasExecutingTools;\n\n const handleSendMessage = async (\n msgs: AdkMessage[],\n config: AdkSendMessageConfig,\n ) => {\n try {\n setIsRunning(true);\n await sendMessage(msgs, config);\n } finally {\n setIsRunning(false);\n }\n };\n\n const threadMessages = useExternalMessageConverter({\n callback: convertAdkMessage,\n messages,\n isRunning: effectiveIsRunning,\n });\n\n const threadMessagesRef = useRef(threadMessages);\n threadMessagesRef.current = threadMessages;\n\n const runtime = useExternalStoreRuntime({\n ...pickExternalStoreSharedOptions(options),\n isRunning: effectiveIsRunning,\n messages: threadMessages,\n unstable_enableToolInvocations: true,\n setToolStatuses,\n adapters: { attachments, dictation, feedback, speech, voice },\n extras: {\n [symbolAdkRuntimeExtras]: true,\n agentInfo,\n stateDelta,\n artifactDelta,\n longRunningToolIds,\n toolConfirmations,\n authRequests,\n escalated,\n messageMetadata,\n send: handleSendMessage,\n } satisfies AdkRuntimeExtras,\n onNew: async (msg) => {\n const cancellations =\n autoCancelPendingToolCalls !== false\n ? getPendingCancellations(messages, longRunningToolIds)\n : [];\n\n return handleSendMessage(\n [\n ...cancellations,\n {\n id: uuidv4(),\n type: \"human\",\n content: getMessageContent(msg),\n },\n ],\n { runConfig: msg.runConfig },\n );\n },\n onEdit: getCheckpointId\n ? async (msg) => {\n const truncated = truncateAdkMessages(\n threadMessagesRef.current,\n msg.parentId,\n );\n replaceMessages(truncated);\n const externalId = aui.threadListItem().getState().externalId;\n const checkpointId = externalId\n ? await getCheckpointId(externalId, truncated)\n : null;\n return handleSendMessage(\n [\n {\n id: uuidv4(),\n type: \"human\",\n content: getMessageContent(msg),\n },\n ],\n {\n runConfig: msg.runConfig,\n ...(checkpointId && { checkpointId }),\n },\n );\n }\n : undefined,\n onReload: getCheckpointId\n ? async (parentId, config) => {\n const truncated = truncateAdkMessages(\n threadMessagesRef.current,\n parentId,\n );\n replaceMessages(truncated);\n const externalId = aui.threadListItem().getState().externalId;\n const checkpointId = externalId\n ? await getCheckpointId(externalId, truncated)\n : null;\n return handleSendMessage([], {\n runConfig: config.runConfig,\n ...(checkpointId && { checkpointId }),\n });\n }\n : undefined,\n onAddToolResult: async ({\n toolCallId,\n toolName,\n result,\n isError,\n artifact,\n }) => {\n await handleSendMessage(\n [\n {\n id: uuidv4(),\n type: \"tool\",\n name: toolName,\n tool_call_id: toolCallId,\n content: JSON.stringify(result),\n artifact,\n status: isError ? \"error\" : \"success\",\n },\n ],\n {},\n );\n },\n onCancel: unstable_allowCancellation\n ? async () => {\n cancel();\n }\n : undefined,\n });\n\n {\n const loadRef = useRef(load);\n useEffect(() => {\n loadRef.current = load;\n });\n\n useEffect(() => {\n const loadFn = loadRef.current;\n if (!loadFn) return;\n\n const externalId = aui.threadListItem().getState().externalId;\n if (externalId == null) return;\n\n loadFn(externalId).then(\n ({ messages: msgs }) => {\n replaceMessages(msgs);\n },\n (e) => {\n console.warn(\"Failed to load ADK session:\", e);\n },\n );\n }, [aui, replaceMessages]);\n }\n\n return runtime;\n};\n\nexport const useAdkRuntime = ({\n cloud,\n sessionAdapter,\n create,\n delete: deleteFn,\n ...options\n}: UseAdkRuntimeOptions) => {\n const aui = useAui();\n const cloudAdapter = useCloudThreadListAdapter({\n cloud,\n create: async () => {\n if (create) return create();\n if (aui.threadListItem.source) return aui.threadListItem().initialize();\n return { externalId: undefined };\n },\n delete: deleteFn,\n });\n\n const adapter = sessionAdapter ?? cloudAdapter;\n\n return useRemoteThreadListRuntime({\n runtimeHook: function RuntimeHook() {\n return useAdkRuntimeImpl(options);\n },\n adapter,\n allowNesting: true,\n });\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"useAdkRuntime.js","names":["_exhaustiveCheck","uuidv4"],"sources":["../src/useAdkRuntime.ts"],"sourcesContent":["import { useEffect, useRef, useState } from \"react\";\nimport {\n getExternalStoreMessages,\n pickExternalStoreSharedOptions,\n type AttachmentAdapter,\n type DictationAdapter,\n type ExternalStoreSharedOptions,\n type FeedbackAdapter,\n type RealtimeVoiceAdapter,\n type SpeechSynthesisAdapter,\n type AppendMessage,\n type ThreadMessage,\n type ToolExecutionStatus,\n} from \"@assistant-ui/core\";\nimport {\n useCloudThreadListAdapter,\n useRemoteThreadListRuntime,\n useExternalMessageConverter,\n useExternalStoreRuntime,\n} from \"@assistant-ui/core/react\";\nimport { useAui } from \"@assistant-ui/store\";\nimport type { AssistantCloud } from \"assistant-cloud\";\nimport type { RemoteThreadListAdapter } from \"@assistant-ui/core\";\nimport type {\n AdkMessage,\n AdkSendMessageConfig,\n AdkStreamCallback,\n OnAdkErrorCallback,\n OnAdkCustomEventCallback,\n OnAdkAgentTransferCallback,\n} from \"./types\";\nimport { useAdkMessages } from \"./useAdkMessages\";\nimport { convertAdkMessage } from \"./convertAdkMessages\";\nimport { symbolAdkRuntimeExtras, type AdkRuntimeExtras } from \"./hooks\";\nimport { v4 as uuidv4 } from \"uuid\";\n\n/** @internal — exported for unit tests. */\nexport const getMessageContent = (msg: AppendMessage) => {\n const allContent = [\n ...msg.content,\n ...(msg.attachments?.flatMap((a) => a.content) ?? []),\n ];\n const content = allContent.map((part) => {\n const type = part.type;\n switch (type) {\n case \"text\":\n return { type: \"text\" as const, text: part.text };\n case \"image\":\n return { type: \"image_url\" as const, url: part.image };\n case \"file\":\n return {\n type: \"file\" as const,\n mimeType: part.mimeType,\n data: part.data,\n ...(part.filename != null && { filename: part.filename }),\n };\n\n case \"tool-call\":\n throw new Error(\"Tool call appends are not supported.\");\n\n default: {\n const _exhaustiveCheck:\n | \"reasoning\"\n | \"source\"\n | \"audio\"\n | \"data\"\n | \"generative-ui\" = type;\n throw new Error(\n `Unsupported append message part type: ${_exhaustiveCheck}`,\n );\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\n/** @internal — exported for unit tests. */\nexport const getPendingToolCalls = (messages: AdkMessage[]) => {\n const pending = new Map<string, { id: string; name: string }>();\n for (const msg of messages) {\n if (msg.type === \"ai\" && msg.tool_calls) {\n for (const tc of msg.tool_calls) {\n pending.set(tc.id, tc);\n }\n }\n if (msg.type === \"tool\") {\n pending.delete(msg.tool_call_id);\n }\n }\n return [...pending.values()];\n};\n\n/**\n * @internal — exported for unit tests.\n *\n * Returns `{cancelled: true}` tool responses for pending tool calls when the\n * user sends a new turn, EXCEPT for HITL interrupts marked via\n * `long_running_tool_ids` (`adk_request_input`, `adk_request_confirmation`,\n * `adk_request_credential`). Those must be answered through a dedicated tool\n * UI + submit helper, not auto-cancelled.\n */\nexport const getPendingCancellations = (\n messages: AdkMessage[],\n longRunningToolIds: readonly string[],\n): Array<AdkMessage & { type: \"tool\" }> => {\n const longRunningSet = new Set(longRunningToolIds);\n return getPendingToolCalls(messages)\n .filter((t) => !longRunningSet.has(t.id))\n .map(\n (t) =>\n ({\n id: uuidv4(),\n type: \"tool\",\n name: t.name,\n tool_call_id: t.id,\n content: JSON.stringify({ cancelled: true }),\n status: \"error\",\n }) satisfies AdkMessage & { type: \"tool\" },\n );\n};\n\nconst truncateAdkMessages = (\n threadMessages: readonly ThreadMessage[],\n parentId: string | null,\n): AdkMessage[] => {\n if (parentId === null) return [];\n const parentIndex = threadMessages.findIndex((m) => m.id === parentId);\n if (parentIndex === -1) return [];\n const truncated: AdkMessage[] = [];\n for (let i = 0; i <= parentIndex && i < threadMessages.length; i++) {\n truncated.push(...getExternalStoreMessages<AdkMessage>(threadMessages[i]!));\n }\n return truncated;\n};\n\nexport type UseAdkRuntimeOptions = ExternalStoreSharedOptions & {\n stream: AdkStreamCallback;\n autoCancelPendingToolCalls?: boolean | undefined;\n unstable_allowCancellation?: boolean | undefined;\n getCheckpointId?: (\n threadId: string,\n parentMessages: AdkMessage[],\n ) => Promise<string | null>;\n load?: (threadId: string) => Promise<{ messages: AdkMessage[] }>;\n create?: () => Promise<{ externalId: string }>;\n delete?: (threadId: string) => Promise<void>;\n adapters?:\n | {\n attachments?: AttachmentAdapter;\n speech?: SpeechSynthesisAdapter;\n dictation?: DictationAdapter;\n voice?: RealtimeVoiceAdapter;\n feedback?: FeedbackAdapter;\n }\n | undefined;\n eventHandlers?:\n | {\n onError?: OnAdkErrorCallback;\n onCustomEvent?: OnAdkCustomEventCallback;\n onAgentTransfer?: OnAdkAgentTransferCallback;\n }\n | undefined;\n cloud?: AssistantCloud | undefined;\n /**\n * A `RemoteThreadListAdapter` to use instead of the cloud adapter.\n * Use with `createAdkSessionAdapter` for ADK session-backed persistence.\n */\n sessionAdapter?: RemoteThreadListAdapter | undefined;\n};\n\nconst useAdkRuntimeImpl = (options: UseAdkRuntimeOptions) => {\n const {\n autoCancelPendingToolCalls,\n adapters: { attachments, dictation, feedback, speech, voice } = {},\n unstable_allowCancellation,\n stream,\n load,\n getCheckpointId,\n eventHandlers,\n } = options;\n const aui = useAui();\n const {\n messages,\n stateDelta,\n agentInfo,\n longRunningToolIds,\n artifactDelta,\n toolConfirmations,\n authRequests,\n escalated,\n messageMetadata,\n sendMessage,\n cancel,\n replaceMessages,\n } = useAdkMessages({\n stream,\n ...(eventHandlers && { eventHandlers }),\n });\n\n const [isRunning, setIsRunning] = useState(false);\n const [toolStatuses, setToolStatuses] = useState<\n Record<string, ToolExecutionStatus>\n >({});\n const hasExecutingTools = Object.values(toolStatuses).some(\n (s) => s?.type === \"executing\",\n );\n const effectiveIsRunning = isRunning || hasExecutingTools;\n\n const handleSendMessage = async (\n msgs: AdkMessage[],\n config: AdkSendMessageConfig,\n ) => {\n try {\n setIsRunning(true);\n await sendMessage(msgs, config);\n } finally {\n setIsRunning(false);\n }\n };\n\n const threadMessages = useExternalMessageConverter({\n callback: convertAdkMessage,\n messages,\n isRunning: effectiveIsRunning,\n });\n\n const threadMessagesRef = useRef(threadMessages);\n threadMessagesRef.current = threadMessages;\n\n const runtime = useExternalStoreRuntime({\n ...pickExternalStoreSharedOptions(options),\n isRunning: effectiveIsRunning,\n messages: threadMessages,\n unstable_enableToolInvocations: true,\n setToolStatuses,\n adapters: { attachments, dictation, feedback, speech, voice },\n extras: {\n [symbolAdkRuntimeExtras]: true,\n agentInfo,\n stateDelta,\n artifactDelta,\n longRunningToolIds,\n toolConfirmations,\n authRequests,\n escalated,\n messageMetadata,\n send: handleSendMessage,\n } satisfies AdkRuntimeExtras,\n onNew: async (msg) => {\n const cancellations =\n autoCancelPendingToolCalls !== false\n ? getPendingCancellations(messages, longRunningToolIds)\n : [];\n\n return handleSendMessage(\n [\n ...cancellations,\n {\n id: uuidv4(),\n type: \"human\",\n content: getMessageContent(msg),\n },\n ],\n { runConfig: msg.runConfig },\n );\n },\n onEdit: getCheckpointId\n ? async (msg) => {\n const truncated = truncateAdkMessages(\n threadMessagesRef.current,\n msg.parentId,\n );\n replaceMessages(truncated);\n const externalId = aui.threadListItem().getState().externalId;\n const checkpointId = externalId\n ? await getCheckpointId(externalId, truncated)\n : null;\n return handleSendMessage(\n [\n {\n id: uuidv4(),\n type: \"human\",\n content: getMessageContent(msg),\n },\n ],\n {\n runConfig: msg.runConfig,\n ...(checkpointId && { checkpointId }),\n },\n );\n }\n : undefined,\n onReload: getCheckpointId\n ? async (parentId, config) => {\n const truncated = truncateAdkMessages(\n threadMessagesRef.current,\n parentId,\n );\n replaceMessages(truncated);\n const externalId = aui.threadListItem().getState().externalId;\n const checkpointId = externalId\n ? await getCheckpointId(externalId, truncated)\n : null;\n return handleSendMessage([], {\n runConfig: config.runConfig,\n ...(checkpointId && { checkpointId }),\n });\n }\n : undefined,\n onAddToolResult: async ({\n toolCallId,\n toolName,\n result,\n isError,\n artifact,\n }) => {\n await handleSendMessage(\n [\n {\n id: uuidv4(),\n type: \"tool\",\n name: toolName,\n tool_call_id: toolCallId,\n content: JSON.stringify(result),\n artifact,\n status: isError ? \"error\" : \"success\",\n },\n ],\n {},\n );\n },\n onCancel: unstable_allowCancellation\n ? async () => {\n cancel();\n }\n : undefined,\n });\n\n {\n const loadRef = useRef(load);\n useEffect(() => {\n loadRef.current = load;\n });\n\n useEffect(() => {\n const loadFn = loadRef.current;\n if (!loadFn) return;\n\n const externalId = aui.threadListItem().getState().externalId;\n if (externalId == null) return;\n\n loadFn(externalId).then(\n ({ messages: msgs }) => {\n replaceMessages(msgs);\n },\n (e) => {\n console.warn(\"Failed to load ADK session:\", e);\n },\n );\n }, [aui, replaceMessages]);\n }\n\n return runtime;\n};\n\nexport const useAdkRuntime = ({\n cloud,\n sessionAdapter,\n create,\n delete: deleteFn,\n ...options\n}: UseAdkRuntimeOptions) => {\n const aui = useAui();\n const cloudAdapter = useCloudThreadListAdapter({\n cloud,\n create: async () => {\n if (create) return create();\n if (aui.threadListItem.source) return aui.threadListItem().initialize();\n return { externalId: undefined };\n },\n delete: deleteFn,\n });\n\n const adapter = sessionAdapter ?? cloudAdapter;\n\n return useRemoteThreadListRuntime({\n runtimeHook: function RuntimeHook() {\n return useAdkRuntimeImpl(options);\n },\n adapter,\n allowNesting: true,\n });\n};\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@assistant-ui/react-google-adk",
3
- "version": "0.0.13",
3
+ "version": "0.0.15",
4
4
  "description": "Google ADK adapter for assistant-ui",
5
5
  "keywords": [
6
6
  "google-adk",
@@ -34,10 +34,10 @@
34
34
  ],
35
35
  "sideEffects": false,
36
36
  "dependencies": {
37
- "@assistant-ui/core": "^0.2.8",
38
- "@assistant-ui/store": "^0.2.13",
37
+ "@assistant-ui/core": "^0.2.11",
38
+ "@assistant-ui/store": "^0.2.14",
39
39
  "assistant-cloud": "*",
40
- "assistant-stream": "^0.3.18",
40
+ "assistant-stream": "^0.3.21",
41
41
  "uuid": "^14.0.0"
42
42
  },
43
43
  "peerDependencies": {
@@ -54,11 +54,11 @@
54
54
  }
55
55
  },
56
56
  "devDependencies": {
57
- "@types/react": "^19.2.15",
57
+ "@types/react": "^19.2.17",
58
58
  "@types/uuid": "^11.0.0",
59
- "react": "^19.2.6",
60
- "vitest": "^4.1.7",
61
- "@assistant-ui/x-buildutils": "0.0.10"
59
+ "react": "^19.2.7",
60
+ "vitest": "^4.1.8",
61
+ "@assistant-ui/x-buildutils": "0.0.12"
62
62
  },
63
63
  "publishConfig": {
64
64
  "access": "public",