@assistant-ui/react-google-adk 0.0.28 → 0.0.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AdkClient.d.ts.map +1 -1
- package/dist/AdkClient.js +2 -1
- package/dist/AdkClient.js.map +1 -1
- package/dist/AdkEventAccumulator.d.ts +1 -1
- package/dist/AdkEventAccumulator.d.ts.map +1 -1
- package/dist/AdkEventAccumulator.js +33 -12
- package/dist/AdkEventAccumulator.js.map +1 -1
- package/dist/convertToAdkMessages.d.ts +10 -1
- package/dist/convertToAdkMessages.d.ts.map +1 -1
- package/dist/convertToAdkMessages.js +20 -6
- package/dist/convertToAdkMessages.js.map +1 -1
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +6 -8
- package/dist/hooks.js.map +1 -1
- package/dist/parseAdkEvent.d.ts.map +1 -1
- package/dist/parseAdkEvent.js +15 -2
- package/dist/parseAdkEvent.js.map +1 -1
- package/dist/sdkIdentity.d.ts +6 -0
- package/dist/sdkIdentity.d.ts.map +1 -0
- package/dist/sdkIdentity.js +9 -0
- package/dist/sdkIdentity.js.map +1 -0
- package/dist/server/parseAdkRequest.d.ts.map +1 -1
- package/dist/server/parseAdkRequest.js +2 -1
- package/dist/server/parseAdkRequest.js.map +1 -1
- package/dist/toAdkFunctionResponse.d.ts +6 -0
- package/dist/toAdkFunctionResponse.d.ts.map +1 -0
- package/dist/toAdkFunctionResponse.js +11 -0
- package/dist/toAdkFunctionResponse.js.map +1 -0
- package/dist/useAdkMessages.d.ts.map +1 -1
- package/dist/useAdkMessages.js +22 -10
- package/dist/useAdkMessages.js.map +1 -1
- package/dist/useAdkRuntime.d.ts.map +1 -1
- package/dist/useAdkRuntime.js +6 -2
- package/dist/useAdkRuntime.js.map +1 -1
- package/package.json +6 -6
- package/src/AdkClient.test.ts +192 -2
- package/src/AdkClient.ts +2 -1
- package/src/AdkEventAccumulator.test.ts +297 -0
- package/src/AdkEventAccumulator.ts +35 -5
- package/src/AdkSessionAdapter.test.ts +88 -0
- package/src/convertToAdkMessages.test.ts +70 -0
- package/src/convertToAdkMessages.ts +19 -4
- package/src/hooks.render.test.tsx +74 -0
- package/src/hooks.test.tsx +33 -0
- package/src/hooks.ts +17 -22
- package/src/parseAdkEvent.ts +36 -7
- package/src/sdkIdentity.ts +9 -0
- package/src/server/parseAdkRequest.test.ts +63 -0
- package/src/server/parseAdkRequest.ts +2 -1
- package/src/toAdkFunctionResponse.test.ts +46 -0
- package/src/toAdkFunctionResponse.ts +18 -0
- package/src/useAdkMessages.test.ts +247 -0
- package/src/useAdkMessages.ts +51 -15
- package/src/useAdkRuntime.replacement.test.tsx +138 -0
- package/src/useAdkRuntime.ts +5 -1
- package/src/useAdkRuntimeApproval.test.tsx +0 -1
package/dist/AdkClient.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdkClient.d.ts","names":[],"sources":["../src/AdkClient.ts"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"AdkClient.d.ts","names":[],"sources":["../src/AdkClient.ts"],"mappings":";;KAYY;;;;;;;;;EASV;;;;;EAMA;;;;EAKA;;;;;EAMA,UACI,gCACO,yBAAyB,QAAQ;;;;;;;;;;;;;;;;;;;iBAqB9B,gBACd,SAAS,yBACR"}
|
package/dist/AdkClient.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { contentToParts } from "./contentToParts.js";
|
|
2
2
|
import { parseAdkEventValue } from "./parseAdkEvent.js";
|
|
3
|
+
import { toAdkFunctionResponse } from "./toAdkFunctionResponse.js";
|
|
3
4
|
import { trimTrailingSlashes } from "./trimTrailingSlashes.js";
|
|
4
5
|
import { SSEEventDecoder } from "assistant-stream/utils";
|
|
5
6
|
//#region src/AdkClient.ts
|
|
@@ -96,7 +97,7 @@ function messagesToContent(messages) {
|
|
|
96
97
|
parts.push({ functionResponse: {
|
|
97
98
|
name: msg.name,
|
|
98
99
|
id: msg.tool_call_id,
|
|
99
|
-
response
|
|
100
|
+
response: toAdkFunctionResponse(response, msg.status === "error")
|
|
100
101
|
} });
|
|
101
102
|
}
|
|
102
103
|
if (parts.length === 0) parts.push({ text: "" });
|
package/dist/AdkClient.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdkClient.js","names":[],"sources":["../src/AdkClient.ts"],"sourcesContent":["import { SSEEventDecoder } from \"assistant-stream/utils\";\nimport { contentToParts } from \"./contentToParts\";\nimport { parseAdkEventValue } from \"./parseAdkEvent\";\nimport { trimTrailingSlashes } from \"./trimTrailingSlashes\";\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 if (options.appName === \"\") {\n throw new Error(\n 'createAdkStream direct mode requires a non-empty \"appName\".',\n );\n }\n\n const isDirect = options.appName != null;\n if (isDirect && (options.userId == null || options.userId === \"\")) {\n throw new Error(\n 'createAdkStream direct mode requires \"userId\" when \"appName\" is provided.',\n );\n }\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 = `${trimTrailingSlashes(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 validateEventStreamContentType(response);\n yield* parseSSEResponse(response);\n };\n}\n\n// ── Internal helpers ──\n\nfunction validateEventStreamContentType(response: Response): void {\n const contentType = response.headers.get(\"Content-Type\");\n const mediaType = contentType?.split(\";\", 1)[0]?.trim().toLowerCase();\n if (mediaType !== \"text/event-stream\") {\n const received = contentType\n ? `\"${contentType}\"`\n : \"no Content-Type header\";\n void response.body?.cancel().catch(() => undefined);\n throw new Error(\n `Expected ADK stream response Content-Type \"text/event-stream\", received ${received}`,\n );\n }\n}\n\nfunction parseAdkEvent(data: string): AdkEvent {\n let value: unknown;\n try {\n value = JSON.parse(data);\n } catch {\n throw new Error(\"Invalid ADK stream event: expected valid JSON.\");\n }\n\n return parseAdkEventValue(value, \"Invalid ADK stream event\");\n}\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 const sseDecoder = new SSEEventDecoder({ trailing: \"dispatch\" });\n\n let shouldCancel = true;\n try {\n while (true) {\n let result: ReadableStreamReadResult<Uint8Array>;\n try {\n result = await reader.read();\n } catch (error) {\n shouldCancel = false;\n throw error;\n }\n\n const { done, value } = result;\n if (done) {\n shouldCancel = false;\n for (const event of sseDecoder.push(decoder.decode())) {\n yield parseAdkEvent(event.data);\n }\n break;\n }\n\n for (const event of sseDecoder.push(\n decoder.decode(value, { stream: true }),\n )) {\n yield parseAdkEvent(event.data);\n }\n }\n\n const trailing = sseDecoder.flush();\n if (trailing !== null) yield parseAdkEvent(trailing.data);\n } finally {\n try {\n if (shouldCancel) await reader.cancel().catch(() => undefined);\n } finally {\n reader.releaseLock();\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AA4DA,SAAgB,gBACd,SACmB;CACnB,IAAI,QAAQ,YAAY,IACtB,MAAM,IAAI,MACR,+DACF;CAGF,MAAM,WAAW,QAAQ,WAAW;CACpC,IAAI,aAAa,QAAQ,UAAU,QAAQ,QAAQ,WAAW,KAC5D,MAAM,IAAI,MACR,+EACF;CAGF,OAAO,iBAAiB,UAAU,QAAQ;EACxC,MAAM,UAAU,MAAM,eAAe,QAAQ,OAAO;EAEpD,IAAI;EACJ,IAAI;EAEJ,IAAI,UAAU;GAEZ,MAAM,GAAG,oBAAoB,QAAQ,GAAG,EAAE;GAC1C,MAAM,EAAE,eAAe,MAAM,OAAO,WAAW;GAC/C,OAAO;IACL,SAAS,QAAQ;IACjB,QAAQ,QAAQ;IAChB,WAAW;IACX,YAAY,kBAAkB,QAAQ;IACtC,WAAW;IACX,GAAI,OAAO,cAAc,QAAQ,EAAE,YAAY,OAAO,WAAW;GACnE;EACF,OAAO;GAEL,MAAM,QAAQ;GACd,OAAO,oBAAoB,UAAU,MAAM;EAC7C;EAEA,MAAM,WAAW,MAAM,MAAM,KAAK;GAChC,QAAQ;GACR,SAAS;IAAE,gBAAgB;IAAoB,GAAG;GAAQ;GAC1D,MAAM,KAAK,UAAU,IAAI;GACzB,QAAQ,OAAO;EACjB,CAAC;EAED,IAAI,CAAC,SAAS,IACZ,MAAM,IAAI,MACR,uBAAuB,SAAS,OAAO,GAAG,SAAS,YACrD;EAGF,+BAA+B,QAAQ;EACvC,OAAO,iBAAiB,QAAQ;CAClC;AACF;AAIA,SAAS,+BAA+B,UAA0B;CAChE,MAAM,cAAc,SAAS,QAAQ,IAAI,cAAc;CAEvD,IADkB,aAAa,MAAM,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,YAAY,MAClD,qBAAqB;EACrC,MAAM,WAAW,cACb,IAAI,YAAY,KAChB;EACJ,SAAc,MAAM,OAAO,CAAC,CAAC,YAAY,KAAA,CAAS;EAClD,MAAM,IAAI,MACR,2EAA2E,UAC7E;CACF;AACF;AAEA,SAAS,cAAc,MAAwB;CAC7C,IAAI;CACJ,IAAI;EACF,QAAQ,KAAK,MAAM,IAAI;CACzB,QAAQ;EACN,MAAM,IAAI,MAAM,gDAAgD;CAClE;CAEA,OAAO,mBAAmB,OAAO,0BAA0B;AAC7D;AAEA,eAAe,eACb,SAIiC;CACjC,IAAI,CAAC,SAAS,OAAO,CAAC;CACtB,IAAI,OAAO,YAAY,YAAY,OAAO,MAAM,QAAQ;CACxD,OAAO;AACT;;;;;AAMA,SAAS,kBAAkB,UAGzB;CACA,MAAM,QAAwB,CAAC;CAE/B,KAAK,MAAM,OAAO,UAChB,IAAI,IAAI,SAAS,SACf,KAAK,MAAM,QAAQ,eAAe,IAAI,OAAO,GAC3C,MAAM,KAAK,IAAI;MAEZ,IAAI,IAAI,SAAS,QAAQ;EAC9B,IAAI;EACJ,IAAI;GACF,WAAW,KAAK,MAAM,IAAI,OAAO;EACnC,QAAQ;GACN,WAAW,IAAI;EACjB;EACA,MAAM,KAAK,EACT,kBAAkB;GAChB,MAAM,IAAI;GACV,IAAI,IAAI;GACR;EACF,EACF,CAAC;CACH;CAGF,IAAI,MAAM,WAAW,GACnB,MAAM,KAAK,EAAE,MAAM,GAAG,CAAC;CAGzB,OAAO;EAAE,MAAM;EAAQ;CAAM;AAC/B;;;;;AAMA,SAAS,oBACP,UACA,QAKyB;CACzB,MAAM,OAAgC,CAAC;CAEvC,IAAI,OAAO,aAAa,MAAM,KAAK,YAAY,OAAO;CACtD,IAAI,OAAO,gBAAgB,MAAM,KAAK,eAAe,OAAO;CAC5D,IAAI,OAAO,cAAc,MAAM,KAAK,aAAa,OAAO;CAGxD,MAAM,UAAU,SAAS,MAAM,MAAM,EAAE,SAAS,MAAM;CACtD,IAAI,WAAW,QAAQ,SAAS,QAAQ;EAEtC,IAAI,SAAS,SAAS,GAAG;GACvB,KAAK,QAAQ,kBAAkB,QAAQ,CAAC,CAAC;GACzC,OAAO;EACT;EAEA,IAAI;EACJ,IAAI;GACF,SAAS,KAAK,MAAM,QAAQ,OAAO;EACrC,QAAQ;GACN,SAAS,QAAQ;EACnB;EACA,KAAK,OAAO;EACZ,KAAK,aAAa,QAAQ;EAC1B,KAAK,WAAW,QAAQ;EACxB,KAAK,SAAS;EACd,KAAK,UAAU,QAAQ,WAAW;EAClC,OAAO;CACT;CAGA,IAAI,SAAS,WAAW,KAAK,SAAS,EAAE,CAAE,SAAS,SAAS;EAC1D,MAAM,MAAM,SAAS;EACrB,IAAI,OAAO,IAAI,YAAY,UACzB,KAAK,UAAU,IAAI;OAEnB,KAAK,QAAQ,eAAe,IAAI,OAAO;EAEzC,OAAO;CACT;CAGA,KAAK,QAAQ,kBAAkB,QAAQ,CAAC,CAAC;CACzC,OAAO;AACT;AAEA,gBAAgB,iBAAiB,UAA8C;CAC7E,MAAM,SAAS,SAAS,KAAM,UAAU;CACxC,MAAM,UAAU,IAAI,YAAY;CAChC,MAAM,aAAa,IAAI,gBAAgB,EAAE,UAAU,WAAW,CAAC;CAE/D,IAAI,eAAe;CACnB,IAAI;EACF,OAAO,MAAM;GACX,IAAI;GACJ,IAAI;IACF,SAAS,MAAM,OAAO,KAAK;GAC7B,SAAS,OAAO;IACd,eAAe;IACf,MAAM;GACR;GAEA,MAAM,EAAE,MAAM,UAAU;GACxB,IAAI,MAAM;IACR,eAAe;IACf,KAAK,MAAM,SAAS,WAAW,KAAK,QAAQ,OAAO,CAAC,GAClD,MAAM,cAAc,MAAM,IAAI;IAEhC;GACF;GAEA,KAAK,MAAM,SAAS,WAAW,KAC7B,QAAQ,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC,CACxC,GACE,MAAM,cAAc,MAAM,IAAI;EAElC;EAEA,MAAM,WAAW,WAAW,MAAM;EAClC,IAAI,aAAa,MAAM,MAAM,cAAc,SAAS,IAAI;CAC1D,UAAU;EACR,IAAI;GACF,IAAI,cAAc,MAAM,OAAO,OAAO,CAAC,CAAC,YAAY,KAAA,CAAS;EAC/D,UAAU;GACR,OAAO,YAAY;EACrB;CACF;AACF"}
|
|
1
|
+
{"version":3,"file":"AdkClient.js","names":[],"sources":["../src/AdkClient.ts"],"sourcesContent":["import { SSEEventDecoder } from \"assistant-stream/utils\";\nimport { contentToParts } from \"./contentToParts\";\nimport { parseAdkEventValue } from \"./parseAdkEvent\";\nimport { toAdkFunctionResponse } from \"./toAdkFunctionResponse\";\nimport { trimTrailingSlashes } from \"./trimTrailingSlashes\";\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 if (options.appName === \"\") {\n throw new Error(\n 'createAdkStream direct mode requires a non-empty \"appName\".',\n );\n }\n\n const isDirect = options.appName != null;\n if (isDirect && (options.userId == null || options.userId === \"\")) {\n throw new Error(\n 'createAdkStream direct mode requires \"userId\" when \"appName\" is provided.',\n );\n }\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 = `${trimTrailingSlashes(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 validateEventStreamContentType(response);\n yield* parseSSEResponse(response);\n };\n}\n\n// ── Internal helpers ──\n\nfunction validateEventStreamContentType(response: Response): void {\n const contentType = response.headers.get(\"Content-Type\");\n const mediaType = contentType?.split(\";\", 1)[0]?.trim().toLowerCase();\n if (mediaType !== \"text/event-stream\") {\n const received = contentType\n ? `\"${contentType}\"`\n : \"no Content-Type header\";\n void response.body?.cancel().catch(() => undefined);\n throw new Error(\n `Expected ADK stream response Content-Type \"text/event-stream\", received ${received}`,\n );\n }\n}\n\nfunction parseAdkEvent(data: string): AdkEvent {\n let value: unknown;\n try {\n value = JSON.parse(data);\n } catch {\n throw new Error(\"Invalid ADK stream event: expected valid JSON.\");\n }\n\n return parseAdkEventValue(value, \"Invalid ADK stream event\");\n}\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: toAdkFunctionResponse(response, msg.status === \"error\"),\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 const sseDecoder = new SSEEventDecoder({ trailing: \"dispatch\" });\n\n let shouldCancel = true;\n try {\n while (true) {\n let result: ReadableStreamReadResult<Uint8Array>;\n try {\n result = await reader.read();\n } catch (error) {\n shouldCancel = false;\n throw error;\n }\n\n const { done, value } = result;\n if (done) {\n shouldCancel = false;\n for (const event of sseDecoder.push(decoder.decode())) {\n yield parseAdkEvent(event.data);\n }\n break;\n }\n\n for (const event of sseDecoder.push(\n decoder.decode(value, { stream: true }),\n )) {\n yield parseAdkEvent(event.data);\n }\n }\n\n const trailing = sseDecoder.flush();\n if (trailing !== null) yield parseAdkEvent(trailing.data);\n } finally {\n try {\n if (shouldCancel) await reader.cancel().catch(() => undefined);\n } finally {\n reader.releaseLock();\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -22,7 +22,7 @@ declare class AdkEventAccumulator {
|
|
|
22
22
|
private escalated;
|
|
23
23
|
private messageMetadataMap;
|
|
24
24
|
private aiMessageOrdinals;
|
|
25
|
-
constructor(initialMessages?: AdkMessage[]);
|
|
25
|
+
constructor(initialMessages?: AdkMessage[], initialLongRunningToolIds?: readonly string[]);
|
|
26
26
|
processEvent(rawEvent: AdkEvent): AdkMessage[];
|
|
27
27
|
private processPart;
|
|
28
28
|
private trackMessageMetadata;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdkEventAccumulator.d.ts","names":[],"sources":["../src/AdkEventAccumulator.ts"],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"AdkEventAccumulator.d.ts","names":[],"sources":["../src/AdkEventAccumulator.ts"],"mappings":";;;;;;cA0Ca,kBAAmB,OAAO;cAoK1B;UACH;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UAEA;UAIA;UACA;UACA;UACA;UACA;UACA;UAGA;EAEN,YAAA,kBAAkB,cAClB;EAYF,aAAa,UAAU,WAAW;UAwN1B;UA+JA;UAmBA;UAMA;UAyBA;UASA;UAYA;UAeA;EAMR,eAAe;EAIf,iBAAiB;EAIjB,oBAAoB;EAIpB;IAAkB;IAA2B;;EAI7C;EAIA;EAIA,wBAAwB;EAIxB,mBAAmB;EAInB;EAIA,sBAAsB,YAAY"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { isAdkFunctionError } from "./toAdkFunctionResponse.js";
|
|
2
|
+
import { isRecord } from "@assistant-ui/core/internal";
|
|
1
3
|
import { generateId } from "@assistant-ui/core";
|
|
2
4
|
//#region src/AdkEventAccumulator.ts
|
|
3
5
|
/**
|
|
@@ -81,6 +83,21 @@ const normalizeEventPart = (part) => {
|
|
|
81
83
|
if ("function_response" in p && !("functionResponse" in p)) result.functionResponse = p.function_response;
|
|
82
84
|
if ("inline_data" in p && !("inlineData" in p)) result.inlineData = p.inline_data;
|
|
83
85
|
if ("file_data" in p && !("fileData" in p)) result.fileData = p.file_data;
|
|
86
|
+
if (isRecord(result.inlineData)) {
|
|
87
|
+
const data = result.inlineData;
|
|
88
|
+
if ("mime_type" in data && !("mimeType" in data)) result.inlineData = {
|
|
89
|
+
...data,
|
|
90
|
+
mimeType: data.mime_type
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
if (isRecord(result.fileData)) {
|
|
94
|
+
const data = result.fileData;
|
|
95
|
+
result.fileData = {
|
|
96
|
+
...data,
|
|
97
|
+
..."mime_type" in data && !("mimeType" in data) && { mimeType: data.mime_type },
|
|
98
|
+
..."file_uri" in data && !("fileUri" in data) && { fileUri: data.file_uri }
|
|
99
|
+
};
|
|
100
|
+
}
|
|
84
101
|
if ("executable_code" in p && !("executableCode" in p)) result.executableCode = p.executable_code;
|
|
85
102
|
if ("code_execution_result" in p && !("codeExecutionResult" in p)) result.codeExecutionResult = p.code_execution_result;
|
|
86
103
|
return result;
|
|
@@ -126,8 +143,8 @@ var AdkEventAccumulator = class {
|
|
|
126
143
|
finalTextReplacedThisEvent = false;
|
|
127
144
|
finalReasoningReplacedThisEvent = false;
|
|
128
145
|
partialReasoningBuffer = "";
|
|
129
|
-
accumulatedStateDelta =
|
|
130
|
-
accumulatedArtifactDelta =
|
|
146
|
+
accumulatedStateDelta = Object.create(null);
|
|
147
|
+
accumulatedArtifactDelta = Object.create(null);
|
|
131
148
|
lastAgentInfo = {};
|
|
132
149
|
lastTransferToAgent;
|
|
133
150
|
pendingLongRunningToolIds = /* @__PURE__ */ new Set();
|
|
@@ -136,8 +153,9 @@ var AdkEventAccumulator = class {
|
|
|
136
153
|
escalated = false;
|
|
137
154
|
messageMetadataMap = /* @__PURE__ */ new Map();
|
|
138
155
|
aiMessageOrdinals = /* @__PURE__ */ new Map();
|
|
139
|
-
constructor(initialMessages) {
|
|
156
|
+
constructor(initialMessages, initialLongRunningToolIds) {
|
|
140
157
|
if (initialMessages) for (const msg of initialMessages) this.messagesMap.set(msg.id, msg);
|
|
158
|
+
if (initialLongRunningToolIds) this.pendingLongRunningToolIds = new Set(initialLongRunningToolIds);
|
|
141
159
|
}
|
|
142
160
|
processEvent(rawEvent) {
|
|
143
161
|
const event = normalizeEvent(rawEvent);
|
|
@@ -218,14 +236,17 @@ var AdkEventAccumulator = class {
|
|
|
218
236
|
});
|
|
219
237
|
else if (part.inlineData) humanParts.push(inlineDataToPart(part.inlineData.mimeType, part.inlineData.data));
|
|
220
238
|
else if (part.fileData) humanParts.push(fileDataToPart(part.fileData.fileUri, part.fileData.mimeType));
|
|
221
|
-
else if (part.functionResponse?.id)
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
239
|
+
else if (part.functionResponse?.id) {
|
|
240
|
+
toolMessages.push({
|
|
241
|
+
id: toolMessageId(event, index),
|
|
242
|
+
type: "tool",
|
|
243
|
+
tool_call_id: part.functionResponse.id,
|
|
244
|
+
name: part.functionResponse.name,
|
|
245
|
+
content: JSON.stringify(part.functionResponse.response),
|
|
246
|
+
status: isAdkFunctionError(part.functionResponse.response) ? "error" : "success"
|
|
247
|
+
});
|
|
248
|
+
this.pendingLongRunningToolIds.delete(part.functionResponse.id);
|
|
249
|
+
}
|
|
229
250
|
for (const toolMsg of toolMessages) this.messagesMap.set(toolMsg.id, toolMsg);
|
|
230
251
|
if (humanParts.length > 0) {
|
|
231
252
|
const id = event.id ?? generateId();
|
|
@@ -348,7 +369,7 @@ var AdkEventAccumulator = class {
|
|
|
348
369
|
tool_call_id: part.functionResponse.id ?? "",
|
|
349
370
|
name: part.functionResponse.name,
|
|
350
371
|
content: JSON.stringify(part.functionResponse.response),
|
|
351
|
-
status: "success"
|
|
372
|
+
status: isAdkFunctionError(part.functionResponse.response) ? "error" : "success"
|
|
352
373
|
};
|
|
353
374
|
this.messagesMap.set(toolMsg.id, toolMsg);
|
|
354
375
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdkEventAccumulator.js","names":[],"sources":["../src/AdkEventAccumulator.ts"],"sourcesContent":["import { generateId } from \"@assistant-ui/core\";\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\n/**\n * A session load replays the stored events through a fresh accumulator, so a\n * message needs an id derived from the event that carries it rather than one\n * minted per replay. An event with no id of its own has never been through the\n * session and has nothing stable to derive from, so it keeps a generated one.\n *\n * A human message keeps the bare event id it has always had. The other kinds\n * take a suffixed namespace, since one event can carry several of them: a tool\n * message by the index of its part, an assistant message by how many this\n * event has already opened.\n */\nconst toolMessageId = (event: AdkEvent, partIndex: number): string =>\n event.id ? `${event.id}:${partIndex}` : generateId();\n\nconst aiMessageId = (event: AdkEvent, ordinal: number): string =>\n event.id ? `${event.id}:ai${ordinal === 0 ? \"\" : ordinal}` : generateId();\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 finalTextReplacedThisEvent = false;\n private finalReasoningReplacedThisEvent = false;\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 // How many assistant messages each event has opened, so a replay of that\n // event opens them with the same ids.\n private aiMessageOrdinals = new Map<string, number>();\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 const toolMessages: AdkMessage[] = [];\n for (const [index, part] of parts.entries()) {\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 } else if (part.functionResponse?.id) {\n // ADK records tool confirmation and other client-supplied tool\n // results as user-authored function responses, and its request\n // confirmation processors search user events for them. Dropping\n // them here would replay a settled gate as pending. A response\n // carrying no id answers no call: core drops it as an orphan, and\n // keeping it would let it settle the batch it was grouped into.\n toolMessages.push({\n id: toolMessageId(event, index),\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 }\n }\n // The replies answer the preceding assistant turn, so they are emitted\n // before any user content in the same event. A human message between the\n // tool call and its reply splits them into separate converted messages,\n // orphaning the reply and leaving its gate unsettled.\n for (const toolMsg of toolMessages) {\n this.messagesMap.set(toolMsg.id, toolMsg);\n }\n if (humanParts.length > 0) {\n const id = event.id ?? generateId();\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 // Replace-semantics close out the streamed partial buffer, which only\n // the first final text/reasoning part of an event may do; later parts\n // of the same event are distinct content and append.\n this.finalTextReplacedThisEvent = false;\n this.finalReasoningReplacedThisEvent = false;\n for (const [index, part] of parts.entries()) {\n this.processPart(part, event, index);\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(\n part: AdkEventPart,\n event: AdkEvent,\n partIndex: number,\n ): 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 if (!this.finalReasoningReplacedThisEvent) {\n this.finalReasoningReplacedThisEvent = true;\n this.partialReasoningBuffer = \"\";\n this.replaceLastReasoningContent(msg, part.text);\n } else {\n this.appendContent(msg, { type: \"reasoning\", text: 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 if (!this.finalTextReplacedThisEvent) {\n this.finalTextReplacedThisEvent = true;\n this.partialTextBuffer = \"\";\n this.replaceLastTextContent(msg, part.text);\n } else {\n this.appendContent(msg, { type: \"text\", text: 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 ?? generateId(),\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: toolMessageId(event, partIndex),\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 ordinal = this.aiMessageOrdinals.get(event.id ?? \"\") ?? 0;\n this.aiMessageOrdinals.set(event.id ?? \"\", ordinal + 1);\n const id = aiMessageId(event, ordinal);\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":[],"sources":["../src/AdkEventAccumulator.ts"],"sourcesContent":["import { generateId } from \"@assistant-ui/core\";\nimport { isRecord } from \"@assistant-ui/core/internal\";\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\";\nimport { isAdkFunctionError } from \"./toAdkFunctionResponse\";\n\ntype InProgressMessage = AdkMessage & { type: \"ai\" };\n\n/**\n * A session load replays the stored events through a fresh accumulator, so a\n * message needs an id derived from the event that carries it rather than one\n * minted per replay. An event with no id of its own has never been through the\n * session and has nothing stable to derive from, so it keeps a generated one.\n *\n * A human message keeps the bare event id it has always had. The other kinds\n * take a suffixed namespace, since one event can carry several of them: a tool\n * message by the index of its part, an assistant message by how many this\n * event has already opened.\n */\nconst toolMessageId = (event: AdkEvent, partIndex: number): string =>\n event.id ? `${event.id}:${partIndex}` : generateId();\n\nconst aiMessageId = (event: AdkEvent, ordinal: number): string =>\n event.id ? `${event.id}:ai${ordinal === 0 ? \"\" : ordinal}` : generateId();\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 (isRecord(result.inlineData)) {\n const data = result.inlineData;\n if (\"mime_type\" in data && !(\"mimeType\" in data))\n result.inlineData = { ...data, mimeType: data.mime_type };\n }\n if (isRecord(result.fileData)) {\n const data = result.fileData;\n result.fileData = {\n ...data,\n ...(\"mime_type\" in data &&\n !(\"mimeType\" in data) && { mimeType: data.mime_type }),\n ...(\"file_uri\" in data &&\n !(\"fileUri\" in data) && { fileUri: data.file_uri }),\n };\n }\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 finalTextReplacedThisEvent = false;\n private finalReasoningReplacedThisEvent = false;\n private partialReasoningBuffer = \"\";\n private accumulatedStateDelta: Record<string, unknown> = Object.create(null);\n private accumulatedArtifactDelta: Record<string, number> =\n Object.create(null);\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 // How many assistant messages each event has opened, so a replay of that\n // event opens them with the same ids.\n private aiMessageOrdinals = new Map<string, number>();\n constructor(\n initialMessages?: AdkMessage[],\n initialLongRunningToolIds?: readonly string[],\n ) {\n if (initialMessages) {\n for (const msg of initialMessages) {\n this.messagesMap.set(msg.id, msg);\n }\n }\n if (initialLongRunningToolIds) {\n this.pendingLongRunningToolIds = new Set(initialLongRunningToolIds);\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 const toolMessages: AdkMessage[] = [];\n for (const [index, part] of parts.entries()) {\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 } else if (part.functionResponse?.id) {\n // ADK records tool confirmation and other client-supplied tool\n // results as user-authored function responses, and its request\n // confirmation processors search user events for them. Dropping\n // them here would replay a settled gate as pending. A response\n // carrying no id answers no call: core drops it as an orphan, and\n // keeping it would let it settle the batch it was grouped into.\n toolMessages.push({\n id: toolMessageId(event, index),\n type: \"tool\",\n tool_call_id: part.functionResponse.id,\n name: part.functionResponse.name,\n content: JSON.stringify(part.functionResponse.response),\n status: isAdkFunctionError(part.functionResponse.response)\n ? \"error\"\n : \"success\",\n });\n // Only a user-authored response settles a long-running call; the response ADK authors for one is the tool's interim result.\n this.pendingLongRunningToolIds.delete(part.functionResponse.id);\n }\n }\n // The replies answer the preceding assistant turn, so they are emitted\n // before any user content in the same event. A human message between the\n // tool call and its reply splits them into separate converted messages,\n // orphaning the reply and leaving its gate unsettled.\n for (const toolMsg of toolMessages) {\n this.messagesMap.set(toolMsg.id, toolMsg);\n }\n if (humanParts.length > 0) {\n const id = event.id ?? generateId();\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 // Replace-semantics close out the streamed partial buffer, which only\n // the first final text/reasoning part of an event may do; later parts\n // of the same event are distinct content and append.\n this.finalTextReplacedThisEvent = false;\n this.finalReasoningReplacedThisEvent = false;\n for (const [index, part] of parts.entries()) {\n this.processPart(part, event, index);\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(\n part: AdkEventPart,\n event: AdkEvent,\n partIndex: number,\n ): 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 if (!this.finalReasoningReplacedThisEvent) {\n this.finalReasoningReplacedThisEvent = true;\n this.partialReasoningBuffer = \"\";\n this.replaceLastReasoningContent(msg, part.text);\n } else {\n this.appendContent(msg, { type: \"reasoning\", text: 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 if (!this.finalTextReplacedThisEvent) {\n this.finalTextReplacedThisEvent = true;\n this.partialTextBuffer = \"\";\n this.replaceLastTextContent(msg, part.text);\n } else {\n this.appendContent(msg, { type: \"text\", text: 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 ?? generateId(),\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: toolMessageId(event, partIndex),\n type: \"tool\",\n tool_call_id: part.functionResponse.id ?? \"\",\n name: part.functionResponse.name,\n content: JSON.stringify(part.functionResponse.response),\n status: isAdkFunctionError(part.functionResponse.response)\n ? \"error\"\n : \"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 ordinal = this.aiMessageOrdinals.get(event.id ?? \"\") ?? 0;\n this.aiMessageOrdinals.set(event.id ?? \"\", ordinal + 1);\n const id = aiMessageId(event, ordinal);\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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"}
|
|
@@ -5,18 +5,27 @@ import { AppendMessage, ThreadMessage } from "@assistant-ui/core";
|
|
|
5
5
|
declare const getMessageContent: (msg: AppendMessage) => string | ({
|
|
6
6
|
type: "text";
|
|
7
7
|
text: string;
|
|
8
|
-
url?: never;
|
|
9
8
|
mimeType?: never;
|
|
9
|
+
data?: never;
|
|
10
|
+
url?: never;
|
|
11
|
+
} | {
|
|
12
|
+
type: "image";
|
|
13
|
+
mimeType: string;
|
|
14
|
+
data: string;
|
|
15
|
+
text?: never;
|
|
16
|
+
url?: never;
|
|
10
17
|
} | {
|
|
11
18
|
type: "image_url";
|
|
12
19
|
url: string;
|
|
13
20
|
text?: never;
|
|
14
21
|
mimeType?: never;
|
|
22
|
+
data?: never;
|
|
15
23
|
} | {
|
|
16
24
|
type: "file_url";
|
|
17
25
|
url: string;
|
|
18
26
|
mimeType: string;
|
|
19
27
|
text?: never;
|
|
28
|
+
data?: never;
|
|
20
29
|
} | {
|
|
21
30
|
filename?: string;
|
|
22
31
|
type: "file";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"convertToAdkMessages.d.ts","names":[],"sources":["../src/convertToAdkMessages.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"convertToAdkMessages.d.ts","names":[],"sources":["../src/convertToAdkMessages.ts"],"mappings":";;;;cAgBa,oBAAqB,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cA2E1B,sBAAuB,UAAU,iBAAA;;;;;;;;;;cAyBjC,0BACX,UAAU,cACV,0CACC,MAAM;EAAe;;cAaX,sBACX,yBAAyB,iBACzB,4BACC;cAWU,mBACX,KAAK,eACL,gBACC;EAAe;EAAe"}
|
|
@@ -1,19 +1,33 @@
|
|
|
1
|
+
import { createToolCallCancellationStub, parseDataUrl, resolveFilePartSource, resolveImageMediaType, scanPendingToolCalls } from "@assistant-ui/core/internal";
|
|
1
2
|
import { generateId, getExternalStoreMessages } from "@assistant-ui/core";
|
|
2
|
-
import { createToolCallCancellationStub, parseDataUrl, resolveFilePartSource, scanPendingToolCalls } from "@assistant-ui/core/internal";
|
|
3
3
|
//#region src/convertToAdkMessages.ts
|
|
4
4
|
/** Exported for unit tests. */
|
|
5
5
|
const getMessageContent = (msg) => {
|
|
6
|
-
const content = [...msg.content
|
|
6
|
+
const content = [...msg.content.map((part) => ({
|
|
7
|
+
part,
|
|
8
|
+
contentType: void 0
|
|
9
|
+
})), ...msg.attachments?.flatMap((attachment) => attachment.content.map((part) => ({
|
|
10
|
+
part,
|
|
11
|
+
contentType: attachment.contentType
|
|
12
|
+
}))) ?? []].flatMap(({ part, contentType }) => {
|
|
7
13
|
const type = part.type;
|
|
8
14
|
switch (type) {
|
|
9
15
|
case "text": return {
|
|
10
16
|
type: "text",
|
|
11
17
|
text: part.text
|
|
12
18
|
};
|
|
13
|
-
case "image":
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
19
|
+
case "image": {
|
|
20
|
+
const parsed = parseDataUrl(part.image);
|
|
21
|
+
if (parsed) return {
|
|
22
|
+
type: "image",
|
|
23
|
+
mimeType: resolveImageMediaType(part.image, contentType),
|
|
24
|
+
data: parsed.data
|
|
25
|
+
};
|
|
26
|
+
return {
|
|
27
|
+
type: "image_url",
|
|
28
|
+
url: part.image
|
|
29
|
+
};
|
|
30
|
+
}
|
|
17
31
|
case "file": {
|
|
18
32
|
const source = resolveFilePartSource(part);
|
|
19
33
|
if (source.kind === "url") return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"convertToAdkMessages.js","names":["_exhaustiveCheck"],"sources":["../src/convertToAdkMessages.ts"],"sourcesContent":["import {\n generateId,\n getExternalStoreMessages,\n type AppendMessage,\n type ThreadMessage,\n} from \"@assistant-ui/core\";\nimport {\n createToolCallCancellationStub,\n parseDataUrl,\n resolveFilePartSource,\n scanPendingToolCalls,\n} from \"@assistant-ui/core/internal\";\nimport type { AdkMessage } from \"./types\";\n\n/** Exported for unit tests. */\nexport const getMessageContent = (msg: AppendMessage) => {\n const allContent = [\n ...msg.content,\n ...(msg.attachments?.flatMap((
|
|
1
|
+
{"version":3,"file":"convertToAdkMessages.js","names":["_exhaustiveCheck"],"sources":["../src/convertToAdkMessages.ts"],"sourcesContent":["import {\n generateId,\n getExternalStoreMessages,\n type AppendMessage,\n type ThreadMessage,\n} from \"@assistant-ui/core\";\nimport {\n createToolCallCancellationStub,\n parseDataUrl,\n resolveFilePartSource,\n resolveImageMediaType,\n scanPendingToolCalls,\n} from \"@assistant-ui/core/internal\";\nimport type { AdkMessage } from \"./types\";\n\n/** Exported for unit tests. */\nexport const getMessageContent = (msg: AppendMessage) => {\n const allContent = [\n ...msg.content.map((part) => ({ part, contentType: undefined })),\n ...(msg.attachments?.flatMap((attachment) =>\n attachment.content.map((part) => ({\n part,\n contentType: attachment.contentType,\n })),\n ) ?? []),\n ];\n const content = allContent.flatMap(({ part, contentType }) => {\n const type = part.type;\n switch (type) {\n case \"text\":\n return { type: \"text\" as const, text: part.text };\n case \"image\": {\n const parsed = parseDataUrl(part.image);\n if (parsed) {\n return {\n type: \"image\" as const,\n mimeType: resolveImageMediaType(part.image, contentType),\n data: parsed.data,\n };\n }\n return { type: \"image_url\" as const, url: part.image };\n }\n case \"file\": {\n const source = resolveFilePartSource(part);\n if (source.kind === \"url\") {\n return {\n type: \"file_url\" as const,\n url: source.url,\n mimeType: part.mimeType,\n };\n }\n return {\n type: \"file\" as const,\n mimeType: part.mimeType,\n // Lands in Gemini `inlineData.data`, which takes bare base64, so a\n // data URL envelope is stripped rather than forwarded.\n data: source.data,\n ...(part.filename != null && { filename: part.filename }),\n };\n }\n case \"audio\": {\n const parsed = parseDataUrl(part.audio.data);\n return {\n type: \"file\" as const,\n mimeType: `audio/${part.audio.format}`,\n data: parsed?.data ?? part.audio.data,\n };\n }\n case \"data\":\n return [];\n\n case \"tool-call\":\n throw new Error(\"Tool call appends are not supported.\");\n\n default: {\n const _exhaustiveCheck: \"reasoning\" | \"source\" | \"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/** Exported for unit tests. */\nexport const getPendingToolCalls = (messages: AdkMessage[]) => {\n return scanPendingToolCalls(\n messages,\n (message) => {\n if (message.type === \"ai\") {\n return { toolCalls: message.tool_calls ?? [] };\n }\n if (message.type === \"tool\") {\n return { toolCallId: message.tool_call_id };\n }\n return undefined;\n },\n (toolCall) => toolCall.id,\n );\n};\n\n/**\n * 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: generateId(),\n ...createToolCallCancellationStub(t),\n }) satisfies AdkMessage & { type: \"tool\" },\n );\n};\n\nexport const 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 const toAdkUserMessage = (\n msg: AppendMessage,\n id = generateId(),\n): AdkMessage & { type: \"human\"; id: string } => ({\n id,\n type: \"human\",\n content: getMessageContent(msg),\n});\n"],"mappings":";;;;AAgBA,MAAa,qBAAqB,QAAuB;CAUvD,MAAM,UAAU,CARd,GAAG,IAAI,QAAQ,KAAK,UAAU;EAAE;EAAM,aAAa,KAAA;CAAU,EAAE,GAC/D,GAAI,IAAI,aAAa,SAAS,eAC5B,WAAW,QAAQ,KAAK,UAAU;EAChC;EACA,aAAa,WAAW;CAC1B,EAAE,CACJ,KAAK,CAAC,CAEiB,CAAC,CAAC,SAAS,EAAE,MAAM,kBAAkB;EAC5D,MAAM,OAAO,KAAK;EAClB,QAAQ,MAAR;GACE,KAAK,QACH,OAAO;IAAE,MAAM;IAAiB,MAAM,KAAK;GAAK;GAClD,KAAK,SAAS;IACZ,MAAM,SAAS,aAAa,KAAK,KAAK;IACtC,IAAI,QACF,OAAO;KACL,MAAM;KACN,UAAU,sBAAsB,KAAK,OAAO,WAAW;KACvD,MAAM,OAAO;IACf;IAEF,OAAO;KAAE,MAAM;KAAsB,KAAK,KAAK;IAAM;GACvD;GACA,KAAK,QAAQ;IACX,MAAM,SAAS,sBAAsB,IAAI;IACzC,IAAI,OAAO,SAAS,OAClB,OAAO;KACL,MAAM;KACN,KAAK,OAAO;KACZ,UAAU,KAAK;IACjB;IAEF,OAAO;KACL,MAAM;KACN,UAAU,KAAK;KAGf,MAAM,OAAO;KACb,GAAI,KAAK,YAAY,QAAQ,EAAE,UAAU,KAAK,SAAS;IACzD;GACF;GACA,KAAK,SAAS;IACZ,MAAM,SAAS,aAAa,KAAK,MAAM,IAAI;IAC3C,OAAO;KACL,MAAM;KACN,UAAU,SAAS,KAAK,MAAM;KAC9B,MAAM,QAAQ,QAAQ,KAAK,MAAM;IACnC;GACF;GACA,KAAK,QACH,OAAO,CAAC;GAEV,KAAK,aACH,MAAM,IAAI,MAAM,sCAAsC;GAExD,SAEE,MAAM,IAAI,MACR,yCAAyCA,MAC3C;EAEJ;CACF,CAAC;CAED,IAAI,QAAQ,WAAW,KAAK,QAAQ,EAAE,EAAE,SAAS,QAC/C,OAAO,QAAQ,EAAE,CAAC,QAAQ;CAG5B,OAAO;AACT;;AAGA,MAAa,uBAAuB,aAA2B;CAC7D,OAAO,qBACL,WACC,YAAY;EACX,IAAI,QAAQ,SAAS,MACnB,OAAO,EAAE,WAAW,QAAQ,cAAc,CAAC,EAAE;EAE/C,IAAI,QAAQ,SAAS,QACnB,OAAO,EAAE,YAAY,QAAQ,aAAa;CAG9C,IACC,aAAa,SAAS,EACzB;AACF;;;;;;;;;;AAWA,MAAa,2BACX,UACA,uBACyC;CACzC,MAAM,iBAAiB,IAAI,IAAI,kBAAkB;CACjD,OAAO,oBAAoB,QAAQ,CAAC,CACjC,QAAQ,MAAM,CAAC,eAAe,IAAI,EAAE,EAAE,CAAC,CAAC,CACxC,KACE,OACE;EACC,IAAI,WAAW;EACf,GAAG,+BAA+B,CAAC;CACrC,EACJ;AACJ;AAEA,MAAa,uBACX,gBACA,aACiB;CACjB,IAAI,aAAa,MAAM,OAAO,CAAC;CAC/B,MAAM,cAAc,eAAe,WAAW,MAAM,EAAE,OAAO,QAAQ;CACrE,IAAI,gBAAgB,IAAI,OAAO,CAAC;CAChC,MAAM,YAA0B,CAAC;CACjC,KAAK,IAAI,IAAI,GAAG,KAAK,eAAe,IAAI,eAAe,QAAQ,KAC7D,UAAU,KAAK,GAAG,yBAAqC,eAAe,EAAG,CAAC;CAE5E,OAAO;AACT;AAEA,MAAa,oBACX,KACA,KAAK,WAAW,OACgC;CAChD;CACA,MAAM;CACN,SAAS,kBAAkB,GAAG;AAChC"}
|
package/dist/hooks.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.d.ts","names":[],"sources":["../src/hooks.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","names":[],"sources":["../src/hooks.ts"],"mappings":";;;;cAwBa;EAAA;EAAA;;;cAIA,0BAAkB;;cAIlB,mBAEH,UAAU,cAAc,QAAQ,yBAAoB;;cAKjD;;cAIA,+BAAuB;;cAIvB,0BAAkB;;cAIlB,uBAAe;;cAIf;;cAGA,6BAAqB,YAAA;;cAMrB,0BAGT,oBACA,oBACA,UAAU,sBAAiB;;cAQlB,yBAEH,oBAAoB,YAAY,sBAAiB;;cAiB9C,0BAEH,oBAAoB,QAAQ,sBAAiB;;cAyC1C,sBAAc;;cAGd,uBAAe;;cAGf,uBAAe"}
|
package/dist/hooks.js
CHANGED
|
@@ -2,6 +2,7 @@ import { adkExtras } from "./adkExtras.js";
|
|
|
2
2
|
import { toAdkConfirmationReply } from "./adkToolApproval.js";
|
|
3
3
|
import { generateId } from "@assistant-ui/core";
|
|
4
4
|
import { useAui } from "@assistant-ui/store";
|
|
5
|
+
import { useShallowSelector } from "@assistant-ui/store/internal";
|
|
5
6
|
//#region src/hooks.ts
|
|
6
7
|
const EMPTY_STATE_DELTA = {};
|
|
7
8
|
const EMPTY_ARTIFACT_DELTA = {};
|
|
@@ -62,17 +63,14 @@ const useAdkSubmitInput = () => {
|
|
|
62
63
|
const APP_PREFIX = "app:";
|
|
63
64
|
const USER_PREFIX = "user:";
|
|
64
65
|
const TEMP_PREFIX = "temp:";
|
|
65
|
-
const filterByPrefix = (state, prefix) =>
|
|
66
|
-
|
|
67
|
-
for (const key of Object.keys(state)) if (key.startsWith(prefix)) result[key.slice(prefix.length)] = state[key];
|
|
68
|
-
return result;
|
|
69
|
-
};
|
|
66
|
+
const filterByPrefix = (state, prefix) => Object.fromEntries(Object.entries(state).filter(([key]) => key.startsWith(prefix)).map(([key, value]) => [key.slice(prefix.length), value]));
|
|
67
|
+
const useAdkStateByPrefix = (prefix) => adkExtras.use(useShallowSelector((e) => filterByPrefix(e.stateDelta, prefix)), EMPTY_STATE_DELTA);
|
|
70
68
|
/** Returns app-level state (keys prefixed with `app:`, prefix stripped). */
|
|
71
|
-
const useAdkAppState = () =>
|
|
69
|
+
const useAdkAppState = () => useAdkStateByPrefix(APP_PREFIX);
|
|
72
70
|
/** Returns user-level state (keys prefixed with `user:`, prefix stripped). */
|
|
73
|
-
const useAdkUserState = () =>
|
|
71
|
+
const useAdkUserState = () => useAdkStateByPrefix(USER_PREFIX);
|
|
74
72
|
/** Returns temp state (keys prefixed with `temp:`, prefix stripped). Not persisted. */
|
|
75
|
-
const useAdkTempState = () =>
|
|
73
|
+
const useAdkTempState = () => useAdkStateByPrefix(TEMP_PREFIX);
|
|
76
74
|
//#endregion
|
|
77
75
|
export { useAdkAgentInfo, useAdkAppState, useAdkArtifacts, useAdkAuthRequests, useAdkConfirmTool, useAdkEscalation, useAdkLongRunningToolIds, useAdkMessageMetadata, useAdkSend, useAdkSessionState, useAdkSubmitAuth, useAdkSubmitInput, useAdkTempState, useAdkToolConfirmations, useAdkUserState };
|
|
78
76
|
|
package/dist/hooks.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.js","names":[],"sources":["../src/hooks.ts"],"sourcesContent":["import { generateId } from \"@assistant-ui/core\";\nimport { useAui } from \"@assistant-ui/store\";\nimport type { ReadonlyJSONValue } from \"assistant-stream/utils\";\nimport { adkExtras } from \"./adkExtras\";\nimport { toAdkConfirmationReply } from \"./adkToolApproval\";\nimport type {\n AdkMessage,\n AdkSendMessageConfig,\n AdkToolConfirmation,\n AdkAuthCredential,\n AdkAuthRequest,\n AdkMessageMetadata,\n} from \"./types\";\n\nconst EMPTY_STATE_DELTA: Record<string, unknown> = {};\nconst EMPTY_ARTIFACT_DELTA: Record<string, number> = {};\nconst EMPTY_LONG_RUNNING_TOOL_IDS: string[] = [];\nconst EMPTY_TOOL_CONFIRMATIONS: AdkToolConfirmation[] = [];\nconst EMPTY_AUTH_REQUESTS: AdkAuthRequest[] = [];\nconst EMPTY_MESSAGE_METADATA = new Map<string, AdkMessageMetadata>();\n\n/** Returns the name and branch of the currently active ADK agent. */\nexport const useAdkAgentInfo = () =>\n adkExtras.use((e) => e.agentInfo, undefined);\n\n/** Returns the accumulated session state delta from ADK events. */\nexport const useAdkSessionState = () =>\n adkExtras.use((e) => e.stateDelta, EMPTY_STATE_DELTA);\n\n/** Returns a function to send raw ADK messages. */\nexport const useAdkSend = () => {\n const aui = useAui();\n return (messages: AdkMessage[], config: AdkSendMessageConfig) =>\n adkExtras.get(aui).send(messages, config);\n};\n\n/** Returns the IDs of long-running tools awaiting external input. */\nexport const useAdkLongRunningToolIds = () =>\n adkExtras.use((e) => e.longRunningToolIds, EMPTY_LONG_RUNNING_TOOL_IDS);\n\n/** Returns pending tool confirmation requests (from SecurityPlugin etc). */\nexport const useAdkToolConfirmations = () =>\n adkExtras.use((e) => e.toolConfirmations, EMPTY_TOOL_CONFIRMATIONS);\n\n/** Returns pending auth credential requests from tools. */\nexport const useAdkAuthRequests = () =>\n adkExtras.use((e) => e.authRequests, EMPTY_AUTH_REQUESTS);\n\n/** Returns the accumulated artifact delta (filename → version). */\nexport const useAdkArtifacts = () =>\n adkExtras.use((e) => e.artifactDelta, EMPTY_ARTIFACT_DELTA);\n\n/** Returns whether any agent has escalated (requested human handoff). */\nexport const useAdkEscalation = () => adkExtras.use((e) => e.escalated, false);\n\n/** Returns per-message metadata (grounding, citation, usage). Keyed by message ID. */\nexport const useAdkMessageMetadata = () =>\n adkExtras.use((e) => e.messageMetadata, EMPTY_MESSAGE_METADATA);\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 adkExtras\n .get(aui)\n .send([toAdkConfirmationReply(toolCallId, confirmed, payload)], {});\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 adkExtras.get(aui).send(\n [\n {\n id: generateId(),\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/** 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 adkExtras.get(aui).send(\n [\n {\n id: generateId(),\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// ── 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>
|
|
1
|
+
{"version":3,"file":"hooks.js","names":[],"sources":["../src/hooks.ts"],"sourcesContent":["import { generateId } from \"@assistant-ui/core\";\nimport { useAui } from \"@assistant-ui/store\";\nimport { useShallowSelector } from \"@assistant-ui/store/internal\";\nimport type { ReadonlyJSONValue } from \"assistant-stream/utils\";\nimport { adkExtras } from \"./adkExtras\";\nimport { toAdkConfirmationReply } from \"./adkToolApproval\";\nimport type {\n AdkMessage,\n AdkSendMessageConfig,\n AdkToolConfirmation,\n AdkAuthCredential,\n AdkAuthRequest,\n AdkMessageMetadata,\n AdkRuntimeExtras,\n} from \"./types\";\n\nconst EMPTY_STATE_DELTA: Record<string, unknown> = {};\nconst EMPTY_ARTIFACT_DELTA: Record<string, number> = {};\nconst EMPTY_LONG_RUNNING_TOOL_IDS: string[] = [];\nconst EMPTY_TOOL_CONFIRMATIONS: AdkToolConfirmation[] = [];\nconst EMPTY_AUTH_REQUESTS: AdkAuthRequest[] = [];\nconst EMPTY_MESSAGE_METADATA = new Map<string, AdkMessageMetadata>();\n\n/** Returns the name and branch of the currently active ADK agent. */\nexport const useAdkAgentInfo = () =>\n adkExtras.use((e) => e.agentInfo, undefined);\n\n/** Returns the accumulated session state delta from ADK events. */\nexport const useAdkSessionState = () =>\n adkExtras.use((e) => e.stateDelta, EMPTY_STATE_DELTA);\n\n/** Returns a function to send raw ADK messages. */\nexport const useAdkSend = () => {\n const aui = useAui();\n return (messages: AdkMessage[], config: AdkSendMessageConfig) =>\n adkExtras.get(aui).send(messages, config);\n};\n\n/** Returns the IDs of long-running tools awaiting external input. */\nexport const useAdkLongRunningToolIds = () =>\n adkExtras.use((e) => e.longRunningToolIds, EMPTY_LONG_RUNNING_TOOL_IDS);\n\n/** Returns pending tool confirmation requests (from SecurityPlugin etc). */\nexport const useAdkToolConfirmations = () =>\n adkExtras.use((e) => e.toolConfirmations, EMPTY_TOOL_CONFIRMATIONS);\n\n/** Returns pending auth credential requests from tools. */\nexport const useAdkAuthRequests = () =>\n adkExtras.use((e) => e.authRequests, EMPTY_AUTH_REQUESTS);\n\n/** Returns the accumulated artifact delta (filename → version). */\nexport const useAdkArtifacts = () =>\n adkExtras.use((e) => e.artifactDelta, EMPTY_ARTIFACT_DELTA);\n\n/** Returns whether any agent has escalated (requested human handoff). */\nexport const useAdkEscalation = () => adkExtras.use((e) => e.escalated, false);\n\n/** Returns per-message metadata (grounding, citation, usage). Keyed by message ID. */\nexport const useAdkMessageMetadata = () =>\n adkExtras.use((e) => e.messageMetadata, EMPTY_MESSAGE_METADATA);\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 adkExtras\n .get(aui)\n .send([toAdkConfirmationReply(toolCallId, confirmed, payload)], {});\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 adkExtras.get(aui).send(\n [\n {\n id: generateId(),\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/** 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 adkExtras.get(aui).send(\n [\n {\n id: generateId(),\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// ── 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 Object.fromEntries(\n Object.entries(state)\n .filter(([key]) => key.startsWith(prefix))\n .map(([key, value]) => [key.slice(prefix.length), value]),\n );\n\nconst useAdkStateByPrefix = (prefix: string) =>\n adkExtras.use(\n useShallowSelector((e: AdkRuntimeExtras) =>\n filterByPrefix(e.stateDelta, prefix),\n ),\n EMPTY_STATE_DELTA,\n );\n\n/** Returns app-level state (keys prefixed with `app:`, prefix stripped). */\nexport const useAdkAppState = () => useAdkStateByPrefix(APP_PREFIX);\n\n/** Returns user-level state (keys prefixed with `user:`, prefix stripped). */\nexport const useAdkUserState = () => useAdkStateByPrefix(USER_PREFIX);\n\n/** Returns temp state (keys prefixed with `temp:`, prefix stripped). Not persisted. */\nexport const useAdkTempState = () => useAdkStateByPrefix(TEMP_PREFIX);\n"],"mappings":";;;;;;AAgBA,MAAM,oBAA6C,CAAC;AACpD,MAAM,uBAA+C,CAAC;AACtD,MAAM,8BAAwC,CAAC;AAC/C,MAAM,2BAAkD,CAAC;AACzD,MAAM,sBAAwC,CAAC;AAC/C,MAAM,yCAAyB,IAAI,IAAgC;;AAGnE,MAAa,wBACX,UAAU,KAAK,MAAM,EAAE,WAAW,KAAA,CAAS;;AAG7C,MAAa,2BACX,UAAU,KAAK,MAAM,EAAE,YAAY,iBAAiB;;AAGtD,MAAa,mBAAmB;CAC9B,MAAM,MAAM,OAAO;CACnB,QAAQ,UAAwB,WAC9B,UAAU,IAAI,GAAG,CAAC,CAAC,KAAK,UAAU,MAAM;AAC5C;;AAGA,MAAa,iCACX,UAAU,KAAK,MAAM,EAAE,oBAAoB,2BAA2B;;AAGxE,MAAa,gCACX,UAAU,KAAK,MAAM,EAAE,mBAAmB,wBAAwB;;AAGpE,MAAa,2BACX,UAAU,KAAK,MAAM,EAAE,cAAc,mBAAmB;;AAG1D,MAAa,wBACX,UAAU,KAAK,MAAM,EAAE,eAAe,oBAAoB;;AAG5D,MAAa,yBAAyB,UAAU,KAAK,MAAM,EAAE,WAAW,KAAK;;AAG7E,MAAa,8BACX,UAAU,KAAK,MAAM,EAAE,iBAAiB,sBAAsB;;AAKhE,MAAa,0BAA0B;CACrC,MAAM,MAAM,OAAO;CACnB,QACE,YACA,WACA,YAEA,UACG,IAAI,GAAG,CAAC,CACR,KAAK,CAAC,uBAAuB,YAAY,WAAW,OAAO,CAAC,GAAG,CAAC,CAAC;AACxE;;AAGA,MAAa,yBAAyB;CACpC,MAAM,MAAM,OAAO;CACnB,QAAQ,YAAoB,eAC1B,UAAU,IAAI,GAAG,CAAC,CAAC,KACjB,CACE;EACE,IAAI,WAAW;EACf,MAAM;EACN,cAAc;EACd,MAAM;EACN,SAAS,KAAK,UAAU,UAAU;EAClC,QAAQ;CACV,CACF,GACA,CAAC,CACH;AACJ;;AAGA,MAAa,0BAA0B;CACrC,MAAM,MAAM,OAAO;CACnB,QAAQ,YAAoB,WAC1B,UAAU,IAAI,GAAG,CAAC,CAAC,KACjB,CACE;EACE,IAAI,WAAW;EACf,MAAM;EACN,cAAc;EACd,MAAM;EACN,SAAS,KAAK,UAAU,EAAE,OAAO,CAAC;EAClC,QAAQ;CACV,CACF,GACA,CAAC,CACH;AACJ;AAIA,MAAM,aAAa;AACnB,MAAM,cAAc;AACpB,MAAM,cAAc;AAEpB,MAAM,kBACJ,OACA,WAEA,OAAO,YACL,OAAO,QAAQ,KAAK,CAAC,CAClB,QAAQ,CAAC,SAAS,IAAI,WAAW,MAAM,CAAC,CAAC,CACzC,KAAK,CAAC,KAAK,WAAW,CAAC,IAAI,MAAM,OAAO,MAAM,GAAG,KAAK,CAAC,CAC5D;AAEF,MAAM,uBAAuB,WAC3B,UAAU,IACR,oBAAoB,MAClB,eAAe,EAAE,YAAY,MAAM,CACrC,GACA,iBACF;;AAGF,MAAa,uBAAuB,oBAAoB,UAAU;;AAGlE,MAAa,wBAAwB,oBAAoB,WAAW;;AAGpE,MAAa,wBAAwB,oBAAoB,WAAW"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parseAdkEvent.d.ts","names":[],"sources":["../src/parseAdkEvent.ts"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"parseAdkEvent.d.ts","names":[],"sources":["../src/parseAdkEvent.ts"],"mappings":";;iBAUgB,mBACd,gBACA,sBACC"}
|
package/dist/parseAdkEvent.js
CHANGED
|
@@ -1,11 +1,24 @@
|
|
|
1
|
+
import { isRecord } from "@assistant-ui/core/internal";
|
|
1
2
|
//#region src/parseAdkEvent.ts
|
|
3
|
+
const invalidField = (errorPrefix, field, expectation) => /* @__PURE__ */ new Error(`${errorPrefix}: expected "${field}" to be ${expectation}.`);
|
|
2
4
|
function parseAdkEventValue(value, errorPrefix) {
|
|
3
|
-
if (
|
|
4
|
-
const { id: rawId, ...event } = value;
|
|
5
|
+
if (!isRecord(value) || Object.keys(value).length === 0) throw new Error(`${errorPrefix}: expected a non-empty object.`);
|
|
6
|
+
const { id: rawId, content: rawContent, ...event } = value;
|
|
5
7
|
if (rawId != null && typeof rawId !== "string" && (typeof rawId !== "number" || !Number.isFinite(rawId))) throw new Error(`${errorPrefix}: expected "id" to be a string or finite number when present.`);
|
|
8
|
+
let content;
|
|
9
|
+
if (rawContent != null) {
|
|
10
|
+
if (!isRecord(rawContent)) throw invalidField(errorPrefix, "content", "an object when present");
|
|
11
|
+
const { parts, ...contentFields } = rawContent;
|
|
12
|
+
if (parts != null && (!Array.isArray(parts) || !parts.every(isRecord))) throw invalidField(errorPrefix, "content.parts", "an array of objects when present");
|
|
13
|
+
content = {
|
|
14
|
+
...contentFields,
|
|
15
|
+
...parts != null && { parts }
|
|
16
|
+
};
|
|
17
|
+
}
|
|
6
18
|
const errorMessage = "error" in event && typeof event.error === "string" ? event.error : void 0;
|
|
7
19
|
return {
|
|
8
20
|
...event,
|
|
21
|
+
...content !== void 0 && { content },
|
|
9
22
|
...rawId != null && { id: String(rawId) },
|
|
10
23
|
...errorMessage !== void 0 && !("errorMessage" in event) && !("error_message" in event) && { errorMessage }
|
|
11
24
|
};
|