@tanstack/ai 0.58.0 → 0.59.0

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.
Files changed (85) hide show
  1. package/dist/esm/activities/chat/agents/define-agent.d.ts +81 -0
  2. package/dist/esm/activities/chat/agents/define-agent.js +34 -0
  3. package/dist/esm/activities/chat/agents/define-agent.js.map +1 -0
  4. package/dist/esm/activities/chat/agents/route.d.ts +53 -0
  5. package/dist/esm/activities/chat/agents/route.js +59 -0
  6. package/dist/esm/activities/chat/agents/route.js.map +1 -0
  7. package/dist/esm/activities/chat/agents/spawn.d.ts +124 -0
  8. package/dist/esm/activities/chat/agents/spawn.js +490 -0
  9. package/dist/esm/activities/chat/agents/spawn.js.map +1 -0
  10. package/dist/esm/activities/chat/agents/turn.d.ts +36 -0
  11. package/dist/esm/activities/chat/agents/turn.js +78 -0
  12. package/dist/esm/activities/chat/agents/turn.js.map +1 -0
  13. package/dist/esm/activities/chat/index.d.ts +13 -3
  14. package/dist/esm/activities/chat/index.js +337 -13
  15. package/dist/esm/activities/chat/index.js.map +1 -1
  16. package/dist/esm/activities/chat/messages.d.ts +7 -1
  17. package/dist/esm/activities/chat/messages.js +94 -18
  18. package/dist/esm/activities/chat/messages.js.map +1 -1
  19. package/dist/esm/activities/chat/middleware/run-store.d.ts +43 -7
  20. package/dist/esm/activities/chat/middleware/run-store.js +8 -1
  21. package/dist/esm/activities/chat/middleware/run-store.js.map +1 -1
  22. package/dist/esm/activities/chat/middleware/types.d.ts +47 -1
  23. package/dist/esm/activities/chat/middleware/types.js.map +1 -1
  24. package/dist/esm/activities/chat/stream/processor.d.ts +46 -0
  25. package/dist/esm/activities/chat/stream/processor.js +280 -7
  26. package/dist/esm/activities/chat/stream/processor.js.map +1 -1
  27. package/dist/esm/activities/chat/tools/tool-calls.d.ts +17 -3
  28. package/dist/esm/activities/chat/tools/tool-calls.js +54 -5
  29. package/dist/esm/activities/chat/tools/tool-calls.js.map +1 -1
  30. package/dist/esm/activities/generateAudio/index.js +1 -1
  31. package/dist/esm/activities/generateImage/index.js +1 -1
  32. package/dist/esm/activities/generateLiveVideo/index.js +1 -1
  33. package/dist/esm/activities/generateSpeech/index.js +1 -1
  34. package/dist/esm/activities/generateTranscription/index.js +1 -1
  35. package/dist/esm/activities/generateVoice/index.js +1 -1
  36. package/dist/esm/activities/generateWorld/index.js +1 -1
  37. package/dist/esm/activities/index.d.ts +3 -0
  38. package/dist/esm/activities/index.js +5 -3
  39. package/dist/esm/activities/summarize/index.js +1 -1
  40. package/dist/esm/client.d.ts +5 -36
  41. package/dist/esm/client.js +4 -37
  42. package/dist/esm/client.js.map +1 -1
  43. package/dist/esm/index.d.ts +5 -0
  44. package/dist/esm/index.js +6 -3
  45. package/dist/esm/middlewares/content-guard.js.map +1 -1
  46. package/dist/esm/types.d.ts +110 -88
  47. package/dist/esm/utilities/adapter-yield-chunk.d.ts +5 -1
  48. package/dist/esm/utilities/ag-ui-usage.d.ts +9 -9
  49. package/dist/esm/utilities/ag-ui-usage.js +66 -3
  50. package/dist/esm/utilities/ag-ui-usage.js.map +1 -1
  51. package/dist/esm/utilities/ag-ui-wire.js +56 -0
  52. package/dist/esm/utilities/ag-ui-wire.js.map +1 -1
  53. package/dist/esm/utilities/normalize-stream-chunk.js +7 -2
  54. package/dist/esm/utilities/normalize-stream-chunk.js.map +1 -1
  55. package/dist/esm/utilities/spec-event-keys.js +13 -8
  56. package/dist/esm/utilities/spec-event-keys.js.map +1 -1
  57. package/dist/esm/utilities/subagent-wire.d.ts +36 -0
  58. package/dist/esm/utilities/subagent-wire.js +131 -0
  59. package/dist/esm/utilities/subagent-wire.js.map +1 -0
  60. package/package.json +2 -2
  61. package/skills/ai-core/adapter-configuration/references/grok-adapter.md +1 -1
  62. package/skills/ai-core/media-generation/SKILL.md +2 -2
  63. package/skills/ai-core/middleware/SKILL.md +7 -4
  64. package/src/activities/chat/agents/define-agent.ts +121 -0
  65. package/src/activities/chat/agents/route.ts +115 -0
  66. package/src/activities/chat/agents/spawn.ts +806 -0
  67. package/src/activities/chat/agents/turn.ts +151 -0
  68. package/src/activities/chat/index.ts +529 -11
  69. package/src/activities/chat/messages.ts +125 -15
  70. package/src/activities/chat/middleware/run-store.ts +56 -7
  71. package/src/activities/chat/middleware/types.ts +47 -0
  72. package/src/activities/chat/stream/processor.ts +428 -8
  73. package/src/activities/chat/tools/tool-calls.ts +77 -11
  74. package/src/activities/index.ts +15 -0
  75. package/src/client.ts +22 -35
  76. package/src/index.ts +23 -0
  77. package/src/middlewares/content-guard.ts +7 -5
  78. package/src/types.ts +154 -94
  79. package/src/utilities/adapter-yield-chunk.ts +10 -2
  80. package/src/utilities/ag-ui-usage.test.ts +38 -0
  81. package/src/utilities/ag-ui-usage.ts +98 -11
  82. package/src/utilities/ag-ui-wire.ts +74 -0
  83. package/src/utilities/normalize-stream-chunk.ts +10 -2
  84. package/src/utilities/spec-event-keys.ts +34 -7
  85. package/src/utilities/subagent-wire.ts +184 -0
@@ -21,6 +21,7 @@ function toSpecTokenUsage(usage, options) {
21
21
  };
22
22
  const cachedInputTokens = promptTokensDetails?.cachedTokens;
23
23
  if (cachedInputTokens !== void 0) spec.cachedInputTokens = cachedInputTokens;
24
+ if (promptTokensDetails?.cacheWriteTokens !== void 0) spec.cacheWriteInputTokens = promptTokensDetails.cacheWriteTokens;
24
25
  const reasoningTokens = completionTokensDetails?.reasoningTokens;
25
26
  if (reasoningTokens !== void 0) spec.reasoningTokens = reasoningTokens;
26
27
  const leftoverPrompt = promptTokensDetails ? definedDetails(withoutKey(promptTokensDetails, "cachedTokens")) : void 0;
@@ -34,17 +35,79 @@ function toSpecTokenUsage(usage, options) {
34
35
  })
35
36
  };
36
37
  }
38
+ function sumNumbers(current, next) {
39
+ if (!current) return next;
40
+ if (!next) return current;
41
+ const result = { ...current };
42
+ for (const key of Object.keys(next)) {
43
+ const value = next[key];
44
+ if (typeof value !== "number") continue;
45
+ const previous = current[key];
46
+ result[key] = (typeof previous === "number" ? previous : 0) + value;
47
+ }
48
+ return result;
49
+ }
50
+ function sumOptional(current, next) {
51
+ if (current === void 0) return next;
52
+ if (next === void 0) return current;
53
+ return current + next;
54
+ }
55
+ /**
56
+ * Add two usage totals, as for a parent run and its children. Numbers add
57
+ * up. `billed` adds up only in the same unit. `providerUsageDetails` is
58
+ * opaque, so the latest one stays. `@tanstack/ai-persistence` sums per-run
59
+ * usage with the same rules.
60
+ */
61
+ function addTokenUsage(current, next) {
62
+ const promptTokensDetails = sumNumbers(current.promptTokensDetails, next.promptTokensDetails);
63
+ const completionTokensDetails = sumNumbers(current.completionTokensDetails, next.completionTokensDetails);
64
+ const costDetails = sumNumbers(current.costDetails, next.costDetails);
65
+ const cost = sumOptional(current.cost, next.cost);
66
+ const durationSeconds = sumOptional(current.durationSeconds, next.durationSeconds);
67
+ const unitsBilled = sumOptional(current.unitsBilled, next.unitsBilled);
68
+ const billed = current.billed && next.billed && current.billed.unit === next.billed.unit ? {
69
+ quantity: current.billed.quantity + next.billed.quantity,
70
+ unit: current.billed.unit
71
+ } : next.billed ?? current.billed;
72
+ const providerUsageDetails = next.providerUsageDetails ?? current.providerUsageDetails;
73
+ return {
74
+ ...current,
75
+ ...next,
76
+ promptTokens: current.promptTokens + next.promptTokens,
77
+ completionTokens: current.completionTokens + next.completionTokens,
78
+ totalTokens: current.totalTokens + next.totalTokens,
79
+ ...promptTokensDetails && { promptTokensDetails },
80
+ ...completionTokensDetails && { completionTokensDetails },
81
+ ...cost !== void 0 && { cost },
82
+ ...costDetails && { costDetails },
83
+ ...durationSeconds !== void 0 && { durationSeconds },
84
+ ...unitsBilled !== void 0 && { unitsBilled },
85
+ ...billed && { billed },
86
+ ...providerUsageDetails && { providerUsageDetails }
87
+ };
88
+ }
37
89
  function rebuildTokenUsage(usage, leftover) {
38
90
  if (isTanstackUsage(usage)) return usage;
39
91
  if (Array.isArray(usage)) return fromSpecTokenUsage(usage, leftover);
40
92
  return fromSpecTokenUsage(void 0, leftover);
41
93
  }
42
94
  function fromSpecTokenUsage(usage, leftover) {
43
- const spec = usage?.[0];
44
- if (spec == null && leftover == null) return;
95
+ const spec = usage?.reduce((total, entry) => {
96
+ for (const key of [
97
+ "inputTokens",
98
+ "outputTokens",
99
+ "totalTokens",
100
+ "cachedInputTokens",
101
+ "cacheWriteInputTokens",
102
+ "reasoningTokens"
103
+ ]) if (entry[key] !== void 0) total[key] = (total[key] ?? 0) + entry[key];
104
+ return total;
105
+ }, {});
106
+ if ((usage === void 0 || usage.length === 0) && leftover == null) return;
45
107
  const { promptTokensDetails: leftoverPromptDetails, completionTokensDetails: leftoverCompletionDetails, ...leftoverRest } = leftover ?? {};
46
108
  const promptTokensDetails = definedDetails({
47
109
  ...spec?.cachedInputTokens !== void 0 ? { cachedTokens: spec.cachedInputTokens } : {},
110
+ ...spec?.cacheWriteInputTokens !== void 0 ? { cacheWriteTokens: spec.cacheWriteInputTokens } : {},
48
111
  ...leftoverPromptDetails
49
112
  });
50
113
  const completionTokensDetails = definedDetails({
@@ -61,6 +124,6 @@ function fromSpecTokenUsage(usage, leftover) {
61
124
  };
62
125
  }
63
126
  //#endregion
64
- export { fromSpecTokenUsage, isTanstackUsage, rebuildTokenUsage, toSpecTokenUsage };
127
+ export { addTokenUsage, fromSpecTokenUsage, isTanstackUsage, rebuildTokenUsage, toSpecTokenUsage };
65
128
 
66
129
  //# sourceMappingURL=ag-ui-usage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ag-ui-usage.js","names":[],"sources":["../../../src/utilities/ag-ui-usage.ts"],"sourcesContent":["import type { TokenUsage } from '../types'\n\n/** AG-UI spec `usage[]` item (provider/model labels + token counts only). */\nexport interface SpecTokenUsage {\n provider?: string\n model?: string\n inputTokens?: number\n outputTokens?: number\n totalTokens?: number\n reasoningTokens?: number\n cachedInputTokens?: number\n}\n\nexport interface ToSpecTokenUsageOptions {\n provider?: string\n model?: string\n}\n\n/** TokenUsage fields that have no AG-UI `usage[]` equivalent. */\nexport type TokenUsageLeftover = Omit<\n TokenUsage,\n 'promptTokens' | 'completionTokens' | 'totalTokens'\n>\n\nfunction definedDetails<T extends object>(value: T): T | undefined {\n return Object.keys(value).length > 0 ? value : undefined\n}\n\nfunction withoutKey<T extends object, K extends keyof T>(\n value: T,\n key: K,\n): Omit<T, K> {\n const next = { ...value }\n delete next[key]\n return next\n}\n\nexport function isTanstackUsage(usage: unknown): usage is TokenUsage {\n return (\n typeof usage === 'object' &&\n usage != null &&\n !Array.isArray(usage) &&\n 'promptTokens' in usage\n )\n}\n\nexport function toSpecTokenUsage(\n usage: TokenUsage,\n options?: ToSpecTokenUsageOptions,\n): { usage: Array<SpecTokenUsage>; leftover?: TokenUsageLeftover } {\n const {\n promptTokens,\n completionTokens,\n totalTokens,\n promptTokensDetails,\n completionTokensDetails,\n ...rest\n } = usage\n\n const spec: SpecTokenUsage = {\n ...(options?.provider !== undefined ? { provider: options.provider } : {}),\n ...(options?.model !== undefined ? { model: options.model } : {}),\n inputTokens: promptTokens,\n outputTokens: completionTokens,\n totalTokens,\n }\n const cachedInputTokens = promptTokensDetails?.cachedTokens\n if (cachedInputTokens !== undefined) {\n spec.cachedInputTokens = cachedInputTokens\n }\n const reasoningTokens = completionTokensDetails?.reasoningTokens\n if (reasoningTokens !== undefined) {\n spec.reasoningTokens = reasoningTokens\n }\n\n const leftoverPrompt = promptTokensDetails\n ? definedDetails(withoutKey(promptTokensDetails, 'cachedTokens'))\n : undefined\n const leftoverCompletion = completionTokensDetails\n ? definedDetails(withoutKey(completionTokensDetails, 'reasoningTokens'))\n : undefined\n\n return {\n usage: [spec],\n leftover: definedDetails({\n ...rest,\n ...(leftoverPrompt !== undefined\n ? { promptTokensDetails: leftoverPrompt }\n : {}),\n ...(leftoverCompletion !== undefined\n ? { completionTokensDetails: leftoverCompletion }\n : {}),\n }),\n }\n}\n\nexport function rebuildTokenUsage(\n usage: unknown,\n leftover?: TokenUsageLeftover,\n): TokenUsage | undefined {\n if (isTanstackUsage(usage)) {\n return usage\n }\n if (Array.isArray(usage)) {\n return fromSpecTokenUsage(usage, leftover)\n }\n return fromSpecTokenUsage(undefined, leftover)\n}\n\nexport function fromSpecTokenUsage(\n usage: ReadonlyArray<SpecTokenUsage> | undefined,\n leftover?: TokenUsageLeftover,\n): TokenUsage | undefined {\n const spec = usage?.[0]\n if (spec == null && leftover == null) {\n return undefined\n }\n\n const {\n promptTokensDetails: leftoverPromptDetails,\n completionTokensDetails: leftoverCompletionDetails,\n ...leftoverRest\n } = leftover ?? {}\n\n const promptTokensDetails = definedDetails({\n ...(spec?.cachedInputTokens !== undefined\n ? { cachedTokens: spec.cachedInputTokens }\n : {}),\n ...leftoverPromptDetails,\n })\n const completionTokensDetails = definedDetails({\n ...(spec?.reasoningTokens !== undefined\n ? { reasoningTokens: spec.reasoningTokens }\n : {}),\n ...leftoverCompletionDetails,\n })\n\n return {\n promptTokens: spec?.inputTokens ?? 0,\n completionTokens: spec?.outputTokens ?? 0,\n totalTokens: spec?.totalTokens ?? 0,\n ...leftoverRest,\n ...(promptTokensDetails !== undefined ? { promptTokensDetails } : {}),\n ...(completionTokensDetails !== undefined\n ? { completionTokensDetails }\n : {}),\n }\n}\n"],"mappings":";AAwBA,SAAS,eAAiC,OAAyB;CACjE,OAAO,OAAO,KAAK,KAAK,CAAC,CAAC,SAAS,IAAI,QAAQ,KAAA;AACjD;AAEA,SAAS,WACP,OACA,KACY;CACZ,MAAM,OAAO,EAAE,GAAG,MAAM;CACxB,OAAO,KAAK;CACZ,OAAO;AACT;AAEA,SAAgB,gBAAgB,OAAqC;CACnE,OACE,OAAO,UAAU,YACjB,SAAS,QACT,CAAC,MAAM,QAAQ,KAAK,KACpB,kBAAkB;AAEtB;AAEA,SAAgB,iBACd,OACA,SACiE;CACjE,MAAM,EACJ,cACA,kBACA,aACA,qBACA,yBACA,GAAG,SACD;CAEJ,MAAM,OAAuB;EAC3B,GAAI,SAAS,aAAa,KAAA,IAAY,EAAE,UAAU,QAAQ,SAAS,IAAI,CAAC;EACxE,GAAI,SAAS,UAAU,KAAA,IAAY,EAAE,OAAO,QAAQ,MAAM,IAAI,CAAC;EAC/D,aAAa;EACb,cAAc;EACd;CACF;CACA,MAAM,oBAAoB,qBAAqB;CAC/C,IAAI,sBAAsB,KAAA,GACxB,KAAK,oBAAoB;CAE3B,MAAM,kBAAkB,yBAAyB;CACjD,IAAI,oBAAoB,KAAA,GACtB,KAAK,kBAAkB;CAGzB,MAAM,iBAAiB,sBACnB,eAAe,WAAW,qBAAqB,cAAc,CAAC,IAC9D,KAAA;CACJ,MAAM,qBAAqB,0BACvB,eAAe,WAAW,yBAAyB,iBAAiB,CAAC,IACrE,KAAA;CAEJ,OAAO;EACL,OAAO,CAAC,IAAI;EACZ,UAAU,eAAe;GACvB,GAAG;GACH,GAAI,mBAAmB,KAAA,IACnB,EAAE,qBAAqB,eAAe,IACtC,CAAC;GACL,GAAI,uBAAuB,KAAA,IACvB,EAAE,yBAAyB,mBAAmB,IAC9C,CAAC;EACP,CAAC;CACH;AACF;AAEA,SAAgB,kBACd,OACA,UACwB;CACxB,IAAI,gBAAgB,KAAK,GACvB,OAAO;CAET,IAAI,MAAM,QAAQ,KAAK,GACrB,OAAO,mBAAmB,OAAO,QAAQ;CAE3C,OAAO,mBAAmB,KAAA,GAAW,QAAQ;AAC/C;AAEA,SAAgB,mBACd,OACA,UACwB;CACxB,MAAM,OAAO,QAAQ;CACrB,IAAI,QAAQ,QAAQ,YAAY,MAC9B;CAGF,MAAM,EACJ,qBAAqB,uBACrB,yBAAyB,2BACzB,GAAG,iBACD,YAAY,CAAC;CAEjB,MAAM,sBAAsB,eAAe;EACzC,GAAI,MAAM,sBAAsB,KAAA,IAC5B,EAAE,cAAc,KAAK,kBAAkB,IACvC,CAAC;EACL,GAAG;CACL,CAAC;CACD,MAAM,0BAA0B,eAAe;EAC7C,GAAI,MAAM,oBAAoB,KAAA,IAC1B,EAAE,iBAAiB,KAAK,gBAAgB,IACxC,CAAC;EACL,GAAG;CACL,CAAC;CAED,OAAO;EACL,cAAc,MAAM,eAAe;EACnC,kBAAkB,MAAM,gBAAgB;EACxC,aAAa,MAAM,eAAe;EAClC,GAAG;EACH,GAAI,wBAAwB,KAAA,IAAY,EAAE,oBAAoB,IAAI,CAAC;EACnE,GAAI,4BAA4B,KAAA,IAC5B,EAAE,wBAAwB,IAC1B,CAAC;CACP;AACF"}
1
+ {"version":3,"file":"ag-ui-usage.js","names":[],"sources":["../../../src/utilities/ag-ui-usage.ts"],"sourcesContent":["import type { TokenUsage as SpecTokenUsage } from '@ag-ui/core'\nimport type { TokenUsage } from '../types'\n\n/** AG-UI spec `usage[]` item (provider/model labels + token counts only). */\nexport type { TokenUsage as SpecTokenUsage } from '@ag-ui/core'\n\nexport interface ToSpecTokenUsageOptions {\n provider?: string\n model?: string\n}\n\n/** TokenUsage fields that have no AG-UI `usage[]` equivalent. */\nexport type TokenUsageLeftover = Omit<\n TokenUsage,\n 'promptTokens' | 'completionTokens' | 'totalTokens'\n>\n\nfunction definedDetails<T extends object>(value: T): T | undefined {\n return Object.keys(value).length > 0 ? value : undefined\n}\n\nfunction withoutKey<T extends object, K extends keyof T>(\n value: T,\n key: K,\n): Omit<T, K> {\n const next = { ...value }\n delete next[key]\n return next\n}\n\nexport function isTanstackUsage(usage: unknown): usage is TokenUsage {\n return (\n typeof usage === 'object' &&\n usage != null &&\n !Array.isArray(usage) &&\n 'promptTokens' in usage\n )\n}\n\nexport function toSpecTokenUsage(\n usage: TokenUsage,\n options?: ToSpecTokenUsageOptions,\n): { usage: Array<SpecTokenUsage>; leftover?: TokenUsageLeftover } {\n const {\n promptTokens,\n completionTokens,\n totalTokens,\n promptTokensDetails,\n completionTokensDetails,\n ...rest\n } = usage\n\n const spec: SpecTokenUsage = {\n ...(options?.provider !== undefined ? { provider: options.provider } : {}),\n ...(options?.model !== undefined ? { model: options.model } : {}),\n inputTokens: promptTokens,\n outputTokens: completionTokens,\n totalTokens,\n }\n const cachedInputTokens = promptTokensDetails?.cachedTokens\n if (cachedInputTokens !== undefined) {\n spec.cachedInputTokens = cachedInputTokens\n }\n if (promptTokensDetails?.cacheWriteTokens !== undefined) {\n spec.cacheWriteInputTokens = promptTokensDetails.cacheWriteTokens\n }\n const reasoningTokens = completionTokensDetails?.reasoningTokens\n if (reasoningTokens !== undefined) {\n spec.reasoningTokens = reasoningTokens\n }\n\n // cacheWriteTokens stays in the leftover too, so clients built before\n // cacheWriteInputTokens existed still rebuild it.\n const leftoverPrompt = promptTokensDetails\n ? definedDetails(withoutKey(promptTokensDetails, 'cachedTokens'))\n : undefined\n const leftoverCompletion = completionTokensDetails\n ? definedDetails(withoutKey(completionTokensDetails, 'reasoningTokens'))\n : undefined\n\n return {\n usage: [spec],\n leftover: definedDetails({\n ...rest,\n ...(leftoverPrompt !== undefined\n ? { promptTokensDetails: leftoverPrompt }\n : {}),\n ...(leftoverCompletion !== undefined\n ? { completionTokensDetails: leftoverCompletion }\n : {}),\n }),\n }\n}\n\nfunction sumNumbers<T extends object>(\n current: T | undefined,\n next: T | undefined,\n): T | undefined {\n if (!current) return next\n if (!next) return current\n const result = { ...current }\n for (const key of Object.keys(next) as Array<keyof T>) {\n const value = next[key]\n if (typeof value !== 'number') continue\n const previous = current[key]\n result[key] = ((typeof previous === 'number' ? previous : 0) +\n value) as T[keyof T]\n }\n return result\n}\n\nfunction sumOptional(current?: number, next?: number): number | undefined {\n if (current === undefined) return next\n if (next === undefined) return current\n return current + next\n}\n\n/**\n * Add two usage totals, as for a parent run and its children. Numbers add\n * up. `billed` adds up only in the same unit. `providerUsageDetails` is\n * opaque, so the latest one stays. `@tanstack/ai-persistence` sums per-run\n * usage with the same rules.\n */\nexport function addTokenUsage(\n current: TokenUsage,\n next: TokenUsage,\n): TokenUsage {\n const promptTokensDetails = sumNumbers(\n current.promptTokensDetails,\n next.promptTokensDetails,\n )\n const completionTokensDetails = sumNumbers(\n current.completionTokensDetails,\n next.completionTokensDetails,\n )\n const costDetails = sumNumbers(current.costDetails, next.costDetails)\n const cost = sumOptional(current.cost, next.cost)\n const durationSeconds = sumOptional(\n current.durationSeconds,\n next.durationSeconds,\n )\n const unitsBilled = sumOptional(current.unitsBilled, next.unitsBilled)\n const billed =\n current.billed && next.billed && current.billed.unit === next.billed.unit\n ? {\n quantity: current.billed.quantity + next.billed.quantity,\n unit: current.billed.unit,\n }\n : (next.billed ?? current.billed)\n const providerUsageDetails =\n next.providerUsageDetails ?? current.providerUsageDetails\n return {\n ...current,\n ...next,\n promptTokens: current.promptTokens + next.promptTokens,\n completionTokens: current.completionTokens + next.completionTokens,\n totalTokens: current.totalTokens + next.totalTokens,\n ...(promptTokensDetails && { promptTokensDetails }),\n ...(completionTokensDetails && { completionTokensDetails }),\n ...(cost !== undefined && { cost }),\n ...(costDetails && { costDetails }),\n ...(durationSeconds !== undefined && { durationSeconds }),\n ...(unitsBilled !== undefined && { unitsBilled }),\n ...(billed && { billed }),\n ...(providerUsageDetails && { providerUsageDetails }),\n }\n}\n\nexport function rebuildTokenUsage(\n usage: unknown,\n leftover?: TokenUsageLeftover,\n): TokenUsage | undefined {\n if (isTanstackUsage(usage)) {\n return usage\n }\n if (Array.isArray(usage)) {\n return fromSpecTokenUsage(usage, leftover)\n }\n return fromSpecTokenUsage(undefined, leftover)\n}\n\nexport function fromSpecTokenUsage(\n usage: ReadonlyArray<SpecTokenUsage> | undefined,\n leftover?: TokenUsageLeftover,\n): TokenUsage | undefined {\n const spec = usage?.reduce<SpecTokenUsage>((total, entry) => {\n for (const key of [\n 'inputTokens',\n 'outputTokens',\n 'totalTokens',\n 'cachedInputTokens',\n 'cacheWriteInputTokens',\n 'reasoningTokens',\n ] as const) {\n if (entry[key] !== undefined) total[key] = (total[key] ?? 0) + entry[key]\n }\n return total\n }, {})\n if ((usage === undefined || usage.length === 0) && leftover == null) {\n return undefined\n }\n\n const {\n promptTokensDetails: leftoverPromptDetails,\n completionTokensDetails: leftoverCompletionDetails,\n ...leftoverRest\n } = leftover ?? {}\n\n const promptTokensDetails = definedDetails({\n ...(spec?.cachedInputTokens !== undefined\n ? { cachedTokens: spec.cachedInputTokens }\n : {}),\n ...(spec?.cacheWriteInputTokens !== undefined\n ? { cacheWriteTokens: spec.cacheWriteInputTokens }\n : {}),\n ...leftoverPromptDetails,\n })\n const completionTokensDetails = definedDetails({\n ...(spec?.reasoningTokens !== undefined\n ? { reasoningTokens: spec.reasoningTokens }\n : {}),\n ...leftoverCompletionDetails,\n })\n\n return {\n promptTokens: spec?.inputTokens ?? 0,\n completionTokens: spec?.outputTokens ?? 0,\n totalTokens: spec?.totalTokens ?? 0,\n ...leftoverRest,\n ...(promptTokensDetails !== undefined ? { promptTokensDetails } : {}),\n ...(completionTokensDetails !== undefined\n ? { completionTokensDetails }\n : {}),\n }\n}\n"],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { tanstackMetadata } from "./merge-metadata.js";
2
2
  import { normalizeToolResult } from "./tool-result.js";
3
+ import { wireSubagentInfo, wireSubagentRunId } from "./subagent-wire.js";
3
4
  import { coerceCreatedAt, modelMessageToUIMessage } from "../activities/chat/messages.js";
4
5
  //#region src/utilities/ag-ui-wire.ts
5
6
  function isRecord(value) {
@@ -110,6 +111,7 @@ function uiMessagesToWire(messages, options) {
110
111
  metadata: rebuiltToolMetadata(void 0, void 0, void 0, result)
111
112
  });
112
113
  }
114
+ for (const part of parts) if (part.type === "subagent") wire.push(...subagentToWire(part, options));
113
115
  }
114
116
  return wire;
115
117
  }
@@ -142,6 +144,7 @@ function messageMetadata(msg, parts, includeSnapshotStructuredOutput) {
142
144
  const previousTanstack = tanstackMetadata(msg);
143
145
  const tanstack = {};
144
146
  if (previousTanstack?.model !== void 0) tanstack.model = previousTanstack.model;
147
+ if (previousTanstack?.runId !== void 0) tanstack.runId = previousTanstack.runId;
145
148
  if (previousTanstack?.signature !== void 0) tanstack.signature = previousTanstack.signature;
146
149
  const createdAt = coerceCreatedAt(msg.createdAt);
147
150
  if (createdAt !== void 0) tanstack.createdAt = createdAt.toISOString();
@@ -175,6 +178,59 @@ function collectText(parts) {
175
178
  else if (p.type === "structured-output" && p.status === "complete" && p.raw !== "") out.push(p.raw);
176
179
  return out.join("");
177
180
  }
181
+ /**
182
+ * A child's messages, tagged with its AG-UI `subagentRunId`. The card data
183
+ * rides in `metadata.tanstack.subagent`, so the other side can rebuild the
184
+ * card and continue a suspended child.
185
+ */
186
+ function subagentToWire(part, options) {
187
+ const { subagent } = part;
188
+ const info = {
189
+ name: subagent.name,
190
+ status: subagent.status,
191
+ ...subagent.description !== void 0 && { description: subagent.description },
192
+ ...subagent.error !== void 0 && { error: subagent.error },
193
+ ...subagent.interruptIds !== void 0 && { interruptIds: subagent.interruptIds },
194
+ ...subagent.parentSubagentRunId !== void 0 && { parentSubagentRunId: subagent.parentSubagentRunId },
195
+ ...subagent.parentToolCallId !== void 0 && { parentToolCallId: subagent.parentToolCallId },
196
+ ...subagent.metadata !== void 0 && { metadata: subagent.metadata }
197
+ };
198
+ const child = uiMessagesToWire(subagent.messages, options);
199
+ const own = child.some((message) => wireSubagentRunId(message) === void 0);
200
+ return (own ? child : [{
201
+ id: `subagent:${subagent.id}`,
202
+ role: "assistant"
203
+ }, ...child]).map((message, index) => {
204
+ const nestedId = wireSubagentRunId(message);
205
+ if (nestedId !== void 0) {
206
+ const nested = wireSubagentInfo(message);
207
+ if (!nested || nested.parentSubagentRunId !== void 0) return message;
208
+ return withSubagentInfo(message, nestedId, {
209
+ ...nested,
210
+ parentSubagentRunId: subagent.id
211
+ });
212
+ }
213
+ return withSubagentInfo(message, subagent.id, !own && index === 0 ? {
214
+ ...info,
215
+ placeholder: true
216
+ } : info);
217
+ });
218
+ }
219
+ function withSubagentInfo(message, subagentRunId, info) {
220
+ const metadata = isRecord(message.metadata) ? message.metadata : {};
221
+ const tanstack = isRecord(metadata.tanstack) ? metadata.tanstack : {};
222
+ return {
223
+ ...message,
224
+ subagentRunId,
225
+ metadata: {
226
+ ...metadata,
227
+ tanstack: {
228
+ ...tanstack,
229
+ subagent: info
230
+ }
231
+ }
232
+ };
233
+ }
178
234
  function collectUserContent(parts) {
179
235
  if (!parts.some((p) => p.type === "image" || p.type === "audio" || p.type === "video" || p.type === "document")) return collectText(parts);
180
236
  const out = [];
@@ -1 +1 @@
1
- {"version":3,"file":"ag-ui-wire.js","names":[],"sources":["../../../src/utilities/ag-ui-wire.ts"],"sourcesContent":["import type {\n AssistantMessage,\n InputContent,\n ReasoningMessage,\n SystemMessage,\n ToolCall,\n ToolMessage,\n UserMessage,\n} from '@ag-ui/core'\nimport type {\n ContentPart,\n MessagePart,\n ModelMessage,\n StructuredOutputPart,\n TanStackMessageMetadata,\n UIMessage,\n UIResourcePart,\n} from '../types'\nimport type { MetadataRecord } from './merge-metadata'\nimport { tanstackMetadata } from './merge-metadata'\nimport { normalizeToolResult } from './tool-result'\nimport {\n coerceCreatedAt,\n modelMessageToUIMessage,\n} from '../activities/chat/messages'\n\ntype WithMetadata<T> = T & { metadata?: MetadataRecord }\ntype WireSystemMessage = WithMetadata<SystemMessage>\ntype WireUserMessage = WithMetadata<UserMessage>\ntype WireAssistantMessage = WithMetadata<AssistantMessage>\ntype WireToolMessage = WithMetadata<\n ToolMessage & {\n name?: string\n }\n>\ntype WireReasoningMessage = WithMetadata<ReasoningMessage>\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction rebuiltToolMetadata(\n metadata: unknown,\n createdAt: unknown,\n id: string | undefined,\n content: string | null | Array<ContentPart>,\n anchorOwnsUiResources = false,\n): MetadataRecord | undefined {\n const source: MetadataRecord = isRecord(metadata) ? metadata : {}\n const tanstack = isRecord(source.tanstack) ? { ...source.tanstack } : {}\n if (anchorOwnsUiResources) delete tanstack.uiResources\n const date = coerceCreatedAt(createdAt)\n const toolResult: NonNullable<TanStackMessageMetadata['toolResult']> = {\n ...(id !== undefined ? { id } : {}),\n ...(date && { createdAt: date.toISOString() }),\n ...(Array.isArray(content) && { content }),\n }\n const result = {\n ...source,\n tanstack: { ...tanstack, toolResult },\n }\n return Object.keys(result).length ? result : undefined\n}\n\nexport type WireMessage =\n | WireSystemMessage\n | WireUserMessage\n | WireAssistantMessage\n | WireToolMessage\n | WireReasoningMessage\n\n/**\n * Serialize TanStack `UIMessage`s and `ModelMessage`s into the AG-UI\n * `RunAgentInput.messages` wire shape. Anchors are spec-only (`id`, `role`,\n * `name`, `content`, `toolCalls`, `metadata`). Tool results and thinking parts\n * on assistant messages are additionally emitted as fan-out\n * `{role:'tool',...}` and `{role:'reasoning',...}` entries for strict AG-UI\n * server consumers. Set `includeSnapshotStructuredOutput` to retain complete\n * structured-output metadata for UI snapshots.\n */\nexport function uiMessagesToWire(\n messages: Array<UIMessage | ModelMessage>,\n options?: { includeSnapshotStructuredOutput: boolean },\n): Array<WireMessage> {\n const wire: Array<WireMessage> = []\n const usedWireIds = new Set<string>(\n messages.flatMap((message) =>\n 'id' in message && message.id && message.role !== 'tool'\n ? [message.id]\n : [],\n ),\n )\n const includeSnapshotStructuredOutput =\n options?.includeSnapshotStructuredOutput ?? false\n\n const assistantIds = new Set<string>()\n for (const msg of messages) {\n if (msg.role === 'assistant' && msg.id !== undefined) {\n assistantIds.add(msg.id)\n }\n }\n\n for (const msg of messages) {\n if (!('parts' in msg) && msg.role === 'tool' && msg.toolCallId) {\n const id = uniqueToolWireId(\n toolWireId(msg.id, msg.toolCallId, assistantIds),\n usedWireIds,\n )\n const metadata = rebuiltToolMetadata(\n msg.metadata,\n msg.createdAt,\n msg.id,\n msg.content,\n )\n wire.push({\n role: 'tool',\n id,\n ...(msg.name !== undefined && { name: msg.name }),\n toolCallId: msg.toolCallId,\n content:\n typeof msg.content === 'string'\n ? msg.content\n : JSON.stringify(msg.content),\n ...(msg.error !== undefined && { error: msg.error }),\n ...(metadata !== undefined && { metadata }),\n })\n continue\n }\n\n const uiMessage: UIMessage =\n 'parts' in msg ? msg : modelMessageToUIMessage(msg, msg.id)\n const parts: ReadonlyArray<MessagePart> = uiMessage.parts\n usedWireIds.add(uiMessage.id)\n\n if (msg.role === 'system') {\n wire.push(\n toAnchor(\n uiMessage,\n 'system',\n {\n content:\n parts.length > 0\n ? collectText(parts)\n : ((msg as { content?: string }).content ?? ''),\n },\n parts,\n includeSnapshotStructuredOutput,\n ),\n )\n continue\n }\n\n if (msg.role === 'user') {\n wire.push(\n toAnchor(\n uiMessage,\n 'user',\n {\n content:\n parts.length > 0\n ? collectUserContent(parts)\n : ((msg as { content?: string }).content ?? ''),\n },\n parts,\n includeSnapshotStructuredOutput,\n ),\n )\n continue\n }\n\n // assistant: emit reasoning fan-outs first, then anchor, then tool fan-outs\n for (const part of parts) {\n if (part.type === 'thinking') {\n const reasoning: WireReasoningMessage = {\n role: 'reasoning',\n id: uniqueWireId(deriveReasoningId(uiMessage.id, part), usedWireIds),\n content: part.content,\n }\n if (part.signature) {\n reasoning.encryptedValue = part.signature\n }\n wire.push(reasoning)\n }\n }\n\n const text = collectText(parts)\n const toolCalls = collectToolCalls(parts)\n wire.push(\n toAnchor(\n uiMessage,\n 'assistant',\n {\n ...(text !== '' && { content: text }),\n ...(toolCalls && { toolCalls }),\n },\n parts,\n includeSnapshotStructuredOutput,\n ),\n )\n\n const explicitToolResults = new Set(\n parts.flatMap((part) =>\n part.type === 'tool-result' ? [part.toolCallId] : [],\n ),\n )\n for (const part of parts) {\n if (part.type === 'tool-result') {\n const id = uniqueToolWireId(\n part.id ?? deriveToolMessageId(part.toolCallId),\n usedWireIds,\n )\n const metadata = rebuiltToolMetadata(\n part.metadata,\n part.createdAt,\n part.id,\n part.content,\n true,\n )\n wire.push({\n role: 'tool',\n id,\n toolCallId: part.toolCallId,\n ...(part.name !== undefined && { name: part.name }),\n content:\n typeof part.content === 'string'\n ? part.content\n : JSON.stringify(part.content),\n ...(part.error !== undefined && { error: part.error }),\n ...(metadata !== undefined && { metadata }),\n })\n } else if (part.type === 'tool-call') {\n const approved = part.approval?.approved\n if (\n explicitToolResults.has(part.id) ||\n (part.output === undefined &&\n (part.state !== 'approval-responded' || approved === undefined))\n ) {\n continue\n }\n const result =\n part.output !== undefined\n ? normalizeToolResult(part.output)\n : JSON.stringify({\n approved,\n ...(approved && { pendingExecution: true }),\n message: approved\n ? 'User approved this action'\n : 'User denied this action',\n })\n const content =\n typeof result === 'string' ? result : JSON.stringify(result)\n wire.push({\n role: 'tool',\n id: uniqueToolWireId(deriveToolMessageId(part.id), usedWireIds),\n toolCallId: part.id,\n content,\n metadata: rebuiltToolMetadata(\n undefined,\n undefined,\n undefined,\n result,\n ),\n })\n }\n }\n }\n\n return wire\n}\n\nfunction toAnchor(\n msg: UIMessage,\n role: 'system',\n extras: { content: string },\n parts: ReadonlyArray<MessagePart>,\n includeSnapshotStructuredOutput: boolean,\n): WireSystemMessage\nfunction toAnchor(\n msg: UIMessage,\n role: 'user',\n extras: { content: string | Array<InputContent> },\n parts: ReadonlyArray<MessagePart>,\n includeSnapshotStructuredOutput: boolean,\n): WireUserMessage\nfunction toAnchor(\n msg: UIMessage,\n role: 'assistant',\n extras: {\n content?: string\n toolCalls?: Array<ToolCall>\n },\n parts: ReadonlyArray<MessagePart>,\n includeSnapshotStructuredOutput: boolean,\n): WireAssistantMessage\nfunction toAnchor(\n msg: UIMessage,\n role: UIMessage['role'],\n extras: {\n content?: string | Array<InputContent>\n toolCalls?: Array<ToolCall>\n },\n parts: ReadonlyArray<MessagePart>,\n includeSnapshotStructuredOutput: boolean,\n): WireSystemMessage | WireUserMessage | WireAssistantMessage {\n const metadata = messageMetadata(msg, parts, includeSnapshotStructuredOutput)\n const base = {\n id: msg.id,\n ...(msg.name !== undefined && { name: msg.name }),\n ...(metadata !== undefined && { metadata }),\n }\n if (role === 'system') {\n return { ...base, role, content: String(extras.content ?? '') }\n }\n if (role === 'user') {\n return { ...base, role, content: extras.content ?? '' }\n }\n return {\n ...base,\n role,\n ...(typeof extras.content === 'string' && { content: extras.content }),\n ...(extras.toolCalls !== undefined && { toolCalls: extras.toolCalls }),\n }\n}\n\nfunction messageMetadata(\n msg: UIMessage,\n parts: ReadonlyArray<MessagePart>,\n includeSnapshotStructuredOutput: boolean,\n): MetadataRecord | undefined {\n const base: MetadataRecord = { ...(msg.metadata ?? {}) }\n const previousTanstack = tanstackMetadata(msg)\n const tanstack: TanStackMessageMetadata = {}\n if (previousTanstack?.model !== undefined)\n tanstack.model = previousTanstack.model\n if (previousTanstack?.signature !== undefined)\n tanstack.signature = previousTanstack.signature\n const createdAt = coerceCreatedAt(msg.createdAt)\n if (createdAt !== undefined) tanstack.createdAt = createdAt.toISOString()\n\n const structuredOutput = serializedStructuredOutput(\n parts,\n includeSnapshotStructuredOutput,\n )\n if (structuredOutput) tanstack.structuredOutput = structuredOutput\n\n const toolCallMetadata: Record<string, unknown> = {}\n for (const part of parts) {\n if (part.type === 'tool-call' && part.metadata !== undefined) {\n toolCallMetadata[part.id] = part.metadata\n }\n }\n if (Object.keys(toolCallMetadata).length > 0) {\n tanstack.toolCallMetadata = toolCallMetadata\n }\n\n const uiResources = parts.filter(\n (p): p is UIResourcePart => p.type === 'ui-resource',\n )\n if (uiResources.length > 0) tanstack.uiResources = uiResources\n\n if (Object.keys(tanstack).length > 0) base.tanstack = tanstack\n else delete base.tanstack\n return Object.keys(base).length > 0 ? base : undefined\n}\n\nfunction serializedStructuredOutput(\n parts: ReadonlyArray<MessagePart>,\n includeSnapshotStructuredOutput: boolean,\n): TanStackMessageMetadata['structuredOutput'] | undefined {\n for (const p of parts) {\n if (\n p.type === 'structured-output' &&\n (includeSnapshotStructuredOutput || p.status !== 'complete')\n ) {\n return structuredOutputMetadata(p, includeSnapshotStructuredOutput)\n }\n }\n return undefined\n}\n\nfunction structuredOutputMetadata(\n part: StructuredOutputPart,\n includeSnapshotStructuredOutput: boolean,\n): NonNullable<TanStackMessageMetadata['structuredOutput']> {\n return {\n status: part.status,\n raw: part.raw,\n ...(includeSnapshotStructuredOutput && part.partial !== undefined\n ? { partial: part.partial }\n : {}),\n ...(includeSnapshotStructuredOutput && part.data !== undefined\n ? { data: part.data }\n : {}),\n ...(includeSnapshotStructuredOutput && part.reasoning\n ? { reasoning: part.reasoning }\n : {}),\n ...(part.errorMessage !== undefined && { errorMessage: part.errorMessage }),\n }\n}\n\nfunction collectText(parts: ReadonlyArray<MessagePart>): string {\n // The streamed JSON of a completed structured-output part is the source of\n // truth for multi-turn coherence — emitting it back as assistant content\n // lets the LLM see its own prior structured response. Streaming/errored\n // parts are skipped: they'd ship malformed JSON fragments and confuse the\n // model. `completeStructuredOutputPart` tries hard to populate `raw`\n // (caller → existing buffer → `JSON.stringify(data)`), but the stringify\n // fallback can leave it empty when `data` is unserializable (BigInt,\n // circular). The `p.raw !== ''` guard below is what enforces \"no malformed\n // round-trip\" in that case — without it we'd ship `''` and the model would\n // see an empty assistant turn.\n const out: Array<string> = []\n for (const p of parts) {\n if (p.type === 'text') {\n out.push(p.content)\n } else if (\n p.type === 'structured-output' &&\n p.status === 'complete' &&\n p.raw !== ''\n ) {\n out.push(p.raw)\n }\n }\n return out.join('')\n}\n\nfunction collectUserContent(\n parts: ReadonlyArray<MessagePart>,\n): string | Array<InputContent> {\n const hasMultimodal = parts.some(\n (p) =>\n p.type === 'image' ||\n p.type === 'audio' ||\n p.type === 'video' ||\n p.type === 'document',\n )\n if (!hasMultimodal) {\n return collectText(parts)\n }\n const out: Array<InputContent> = []\n for (const p of parts) {\n if (p.type === 'text') {\n out.push({ type: 'text', text: p.content })\n } else if (\n p.type === 'image' ||\n p.type === 'audio' ||\n p.type === 'video' ||\n p.type === 'document'\n ) {\n out.push(p)\n }\n }\n return out\n}\n\nfunction thoughtSignatureFromMetadata(metadata: unknown): string | undefined {\n if (\n metadata == null ||\n typeof metadata !== 'object' ||\n Array.isArray(metadata)\n ) {\n return undefined\n }\n if (!('thoughtSignature' in metadata)) return undefined\n const value = metadata.thoughtSignature\n return typeof value === 'string' && value !== '' ? value : undefined\n}\n\nfunction collectToolCalls(\n parts: ReadonlyArray<MessagePart>,\n): Array<ToolCall> | undefined {\n const calls: Array<ToolCall> = []\n for (const p of parts) {\n if (p.type === 'tool-call') {\n const encryptedValue = thoughtSignatureFromMetadata(p.metadata)\n calls.push({\n id: p.id,\n type: 'function',\n function: { name: p.name, arguments: p.arguments },\n ...(encryptedValue !== undefined ? { encryptedValue } : {}),\n })\n }\n }\n return calls.length > 0 ? calls : undefined\n}\n\nfunction deriveReasoningId(messageId: string, part: MessagePart): string {\n return `${messageId}-reasoning-${(part as { id?: string }).id ?? hashContent((part as { content: string }).content)}`\n}\n\nfunction deriveToolMessageId(toolCallId: string): string {\n return `tool-${toolCallId}`\n}\n\nfunction uniqueToolWireId(id: string, used: Set<string>): string {\n return uniqueWireId(id, used)\n}\n\nfunction uniqueWireId(id: string, used: Set<string>): string {\n if (!used.has(id)) {\n used.add(id)\n return id\n }\n let suffix = 2\n while (used.has(`${id}-${suffix}`)) suffix++\n const unique = `${id}-${suffix}`\n used.add(unique)\n return unique\n}\n\nfunction toolWireId(\n id: string | undefined,\n toolCallId: string,\n assistantIds: ReadonlySet<string>,\n): string {\n const derived = deriveToolMessageId(toolCallId)\n if (id === undefined || assistantIds.has(id)) return derived\n return id\n}\n\nfunction hashContent(s: string): string {\n // Cheap deterministic id suffix; collisions are tolerable since\n // reasoning ids only matter for AG-UI server consumers, not for our\n // own server's dedup logic (which keys on toolCallId, not reasoning id).\n let h = 0\n for (let i = 0; i < s.length; i++) h = (h * 31 + s.charCodeAt(i)) | 0\n return Math.abs(h).toString(36)\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ag-ui-wire.js","names":[],"sources":["../../../src/utilities/ag-ui-wire.ts"],"sourcesContent":["import type {\n AssistantMessage,\n InputContent,\n ReasoningMessage,\n SystemMessage,\n ToolCall,\n ToolMessage,\n UserMessage,\n} from '@ag-ui/core'\nimport type {\n ContentPart,\n MessagePart,\n ModelMessage,\n StructuredOutputPart,\n SubagentPart,\n TanStackMessageMetadata,\n UIMessage,\n UIResourcePart,\n} from '../types'\nimport type { MetadataRecord } from './merge-metadata'\nimport { tanstackMetadata } from './merge-metadata'\nimport { normalizeToolResult } from './tool-result'\nimport { wireSubagentInfo, wireSubagentRunId } from './subagent-wire'\nimport type { SubagentWireInfo } from './subagent-wire'\nimport {\n coerceCreatedAt,\n modelMessageToUIMessage,\n} from '../activities/chat/messages'\n\ntype WithMetadata<T> = T & { metadata?: MetadataRecord }\ntype WireSystemMessage = WithMetadata<SystemMessage>\ntype WireUserMessage = WithMetadata<UserMessage>\ntype WireAssistantMessage = WithMetadata<AssistantMessage>\ntype WireToolMessage = WithMetadata<\n ToolMessage & {\n name?: string\n }\n>\ntype WireReasoningMessage = WithMetadata<ReasoningMessage>\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction rebuiltToolMetadata(\n metadata: unknown,\n createdAt: unknown,\n id: string | undefined,\n content: string | null | Array<ContentPart>,\n anchorOwnsUiResources = false,\n): MetadataRecord | undefined {\n const source: MetadataRecord = isRecord(metadata) ? metadata : {}\n const tanstack = isRecord(source.tanstack) ? { ...source.tanstack } : {}\n if (anchorOwnsUiResources) delete tanstack.uiResources\n const date = coerceCreatedAt(createdAt)\n const toolResult: NonNullable<TanStackMessageMetadata['toolResult']> = {\n ...(id !== undefined ? { id } : {}),\n ...(date && { createdAt: date.toISOString() }),\n ...(Array.isArray(content) && { content }),\n }\n const result = {\n ...source,\n tanstack: { ...tanstack, toolResult },\n }\n return Object.keys(result).length ? result : undefined\n}\n\nexport type WireMessage =\n | WireSystemMessage\n | WireUserMessage\n | WireAssistantMessage\n | WireToolMessage\n | WireReasoningMessage\n\n/**\n * Serialize TanStack `UIMessage`s and `ModelMessage`s into the AG-UI\n * `RunAgentInput.messages` wire shape. Anchors are spec-only (`id`, `role`,\n * `name`, `content`, `toolCalls`, `metadata`). Tool results and thinking parts\n * on assistant messages are additionally emitted as fan-out\n * `{role:'tool',...}` and `{role:'reasoning',...}` entries for strict AG-UI\n * server consumers. Set `includeSnapshotStructuredOutput` to retain complete\n * structured-output metadata for UI snapshots.\n */\nexport function uiMessagesToWire(\n messages: Array<UIMessage | ModelMessage>,\n options?: { includeSnapshotStructuredOutput: boolean },\n): Array<WireMessage> {\n const wire: Array<WireMessage> = []\n const usedWireIds = new Set<string>(\n messages.flatMap((message) =>\n 'id' in message && message.id && message.role !== 'tool'\n ? [message.id]\n : [],\n ),\n )\n const includeSnapshotStructuredOutput =\n options?.includeSnapshotStructuredOutput ?? false\n\n const assistantIds = new Set<string>()\n for (const msg of messages) {\n if (msg.role === 'assistant' && msg.id !== undefined) {\n assistantIds.add(msg.id)\n }\n }\n\n for (const msg of messages) {\n if (!('parts' in msg) && msg.role === 'tool' && msg.toolCallId) {\n const id = uniqueToolWireId(\n toolWireId(msg.id, msg.toolCallId, assistantIds),\n usedWireIds,\n )\n const metadata = rebuiltToolMetadata(\n msg.metadata,\n msg.createdAt,\n msg.id,\n msg.content,\n )\n wire.push({\n role: 'tool',\n id,\n ...(msg.name !== undefined && { name: msg.name }),\n toolCallId: msg.toolCallId,\n content:\n typeof msg.content === 'string'\n ? msg.content\n : JSON.stringify(msg.content),\n ...(msg.error !== undefined && { error: msg.error }),\n ...(metadata !== undefined && { metadata }),\n })\n continue\n }\n\n const uiMessage: UIMessage =\n 'parts' in msg ? msg : modelMessageToUIMessage(msg, msg.id)\n const parts: ReadonlyArray<MessagePart> = uiMessage.parts\n usedWireIds.add(uiMessage.id)\n\n if (msg.role === 'system') {\n wire.push(\n toAnchor(\n uiMessage,\n 'system',\n {\n content:\n parts.length > 0\n ? collectText(parts)\n : ((msg as { content?: string }).content ?? ''),\n },\n parts,\n includeSnapshotStructuredOutput,\n ),\n )\n continue\n }\n\n if (msg.role === 'user') {\n wire.push(\n toAnchor(\n uiMessage,\n 'user',\n {\n content:\n parts.length > 0\n ? collectUserContent(parts)\n : ((msg as { content?: string }).content ?? ''),\n },\n parts,\n includeSnapshotStructuredOutput,\n ),\n )\n continue\n }\n\n // assistant: emit reasoning fan-outs first, then anchor, then tool fan-outs\n for (const part of parts) {\n if (part.type === 'thinking') {\n const reasoning: WireReasoningMessage = {\n role: 'reasoning',\n id: uniqueWireId(deriveReasoningId(uiMessage.id, part), usedWireIds),\n content: part.content,\n }\n if (part.signature) {\n reasoning.encryptedValue = part.signature\n }\n wire.push(reasoning)\n }\n }\n\n const text = collectText(parts)\n const toolCalls = collectToolCalls(parts)\n wire.push(\n toAnchor(\n uiMessage,\n 'assistant',\n {\n ...(text !== '' && { content: text }),\n ...(toolCalls && { toolCalls }),\n },\n parts,\n includeSnapshotStructuredOutput,\n ),\n )\n\n const explicitToolResults = new Set(\n parts.flatMap((part) =>\n part.type === 'tool-result' ? [part.toolCallId] : [],\n ),\n )\n for (const part of parts) {\n if (part.type === 'tool-result') {\n const id = uniqueToolWireId(\n part.id ?? deriveToolMessageId(part.toolCallId),\n usedWireIds,\n )\n const metadata = rebuiltToolMetadata(\n part.metadata,\n part.createdAt,\n part.id,\n part.content,\n true,\n )\n wire.push({\n role: 'tool',\n id,\n toolCallId: part.toolCallId,\n ...(part.name !== undefined && { name: part.name }),\n content:\n typeof part.content === 'string'\n ? part.content\n : JSON.stringify(part.content),\n ...(part.error !== undefined && { error: part.error }),\n ...(metadata !== undefined && { metadata }),\n })\n } else if (part.type === 'tool-call') {\n const approved = part.approval?.approved\n if (\n explicitToolResults.has(part.id) ||\n (part.output === undefined &&\n (part.state !== 'approval-responded' || approved === undefined))\n ) {\n continue\n }\n const result =\n part.output !== undefined\n ? normalizeToolResult(part.output)\n : JSON.stringify({\n approved,\n ...(approved && { pendingExecution: true }),\n message: approved\n ? 'User approved this action'\n : 'User denied this action',\n })\n const content =\n typeof result === 'string' ? result : JSON.stringify(result)\n wire.push({\n role: 'tool',\n id: uniqueToolWireId(deriveToolMessageId(part.id), usedWireIds),\n toolCallId: part.id,\n content,\n metadata: rebuiltToolMetadata(\n undefined,\n undefined,\n undefined,\n result,\n ),\n })\n }\n }\n\n for (const part of parts) {\n if (part.type === 'subagent') wire.push(...subagentToWire(part, options))\n }\n }\n\n return wire\n}\n\nfunction toAnchor(\n msg: UIMessage,\n role: 'system',\n extras: { content: string },\n parts: ReadonlyArray<MessagePart>,\n includeSnapshotStructuredOutput: boolean,\n): WireSystemMessage\nfunction toAnchor(\n msg: UIMessage,\n role: 'user',\n extras: { content: string | Array<InputContent> },\n parts: ReadonlyArray<MessagePart>,\n includeSnapshotStructuredOutput: boolean,\n): WireUserMessage\nfunction toAnchor(\n msg: UIMessage,\n role: 'assistant',\n extras: {\n content?: string\n toolCalls?: Array<ToolCall>\n },\n parts: ReadonlyArray<MessagePart>,\n includeSnapshotStructuredOutput: boolean,\n): WireAssistantMessage\nfunction toAnchor(\n msg: UIMessage,\n role: UIMessage['role'],\n extras: {\n content?: string | Array<InputContent>\n toolCalls?: Array<ToolCall>\n },\n parts: ReadonlyArray<MessagePart>,\n includeSnapshotStructuredOutput: boolean,\n): WireSystemMessage | WireUserMessage | WireAssistantMessage {\n const metadata = messageMetadata(msg, parts, includeSnapshotStructuredOutput)\n const base = {\n id: msg.id,\n ...(msg.name !== undefined && { name: msg.name }),\n ...(metadata !== undefined && { metadata }),\n }\n if (role === 'system') {\n return { ...base, role, content: String(extras.content ?? '') }\n }\n if (role === 'user') {\n return { ...base, role, content: extras.content ?? '' }\n }\n return {\n ...base,\n role,\n ...(typeof extras.content === 'string' && { content: extras.content }),\n ...(extras.toolCalls !== undefined && { toolCalls: extras.toolCalls }),\n }\n}\n\nfunction messageMetadata(\n msg: UIMessage,\n parts: ReadonlyArray<MessagePart>,\n includeSnapshotStructuredOutput: boolean,\n): MetadataRecord | undefined {\n const base: MetadataRecord = { ...(msg.metadata ?? {}) }\n const previousTanstack = tanstackMetadata(msg)\n const tanstack: TanStackMessageMetadata = {}\n if (previousTanstack?.model !== undefined)\n tanstack.model = previousTanstack.model\n if (previousTanstack?.runId !== undefined)\n tanstack.runId = previousTanstack.runId\n if (previousTanstack?.signature !== undefined)\n tanstack.signature = previousTanstack.signature\n const createdAt = coerceCreatedAt(msg.createdAt)\n if (createdAt !== undefined) tanstack.createdAt = createdAt.toISOString()\n\n const structuredOutput = serializedStructuredOutput(\n parts,\n includeSnapshotStructuredOutput,\n )\n if (structuredOutput) tanstack.structuredOutput = structuredOutput\n\n const toolCallMetadata: Record<string, unknown> = {}\n for (const part of parts) {\n if (part.type === 'tool-call' && part.metadata !== undefined) {\n toolCallMetadata[part.id] = part.metadata\n }\n }\n if (Object.keys(toolCallMetadata).length > 0) {\n tanstack.toolCallMetadata = toolCallMetadata\n }\n\n const uiResources = parts.filter(\n (p): p is UIResourcePart => p.type === 'ui-resource',\n )\n if (uiResources.length > 0) tanstack.uiResources = uiResources\n\n if (Object.keys(tanstack).length > 0) base.tanstack = tanstack\n else delete base.tanstack\n return Object.keys(base).length > 0 ? base : undefined\n}\n\nfunction serializedStructuredOutput(\n parts: ReadonlyArray<MessagePart>,\n includeSnapshotStructuredOutput: boolean,\n): TanStackMessageMetadata['structuredOutput'] | undefined {\n for (const p of parts) {\n if (\n p.type === 'structured-output' &&\n (includeSnapshotStructuredOutput || p.status !== 'complete')\n ) {\n return structuredOutputMetadata(p, includeSnapshotStructuredOutput)\n }\n }\n return undefined\n}\n\nfunction structuredOutputMetadata(\n part: StructuredOutputPart,\n includeSnapshotStructuredOutput: boolean,\n): NonNullable<TanStackMessageMetadata['structuredOutput']> {\n return {\n status: part.status,\n raw: part.raw,\n ...(includeSnapshotStructuredOutput && part.partial !== undefined\n ? { partial: part.partial }\n : {}),\n ...(includeSnapshotStructuredOutput && part.data !== undefined\n ? { data: part.data }\n : {}),\n ...(includeSnapshotStructuredOutput && part.reasoning\n ? { reasoning: part.reasoning }\n : {}),\n ...(part.errorMessage !== undefined && { errorMessage: part.errorMessage }),\n }\n}\n\nfunction collectText(parts: ReadonlyArray<MessagePart>): string {\n // The streamed JSON of a completed structured-output part is the source of\n // truth for multi-turn coherence — emitting it back as assistant content\n // lets the LLM see its own prior structured response. Streaming/errored\n // parts are skipped: they'd ship malformed JSON fragments and confuse the\n // model. `completeStructuredOutputPart` tries hard to populate `raw`\n // (caller → existing buffer → `JSON.stringify(data)`), but the stringify\n // fallback can leave it empty when `data` is unserializable (BigInt,\n // circular). The `p.raw !== ''` guard below is what enforces \"no malformed\n // round-trip\" in that case — without it we'd ship `''` and the model would\n // see an empty assistant turn.\n const out: Array<string> = []\n for (const p of parts) {\n if (p.type === 'text') {\n out.push(p.content)\n } else if (\n p.type === 'structured-output' &&\n p.status === 'complete' &&\n p.raw !== ''\n ) {\n out.push(p.raw)\n }\n }\n return out.join('')\n}\n\n/**\n * A child's messages, tagged with its AG-UI `subagentRunId`. The card data\n * rides in `metadata.tanstack.subagent`, so the other side can rebuild the\n * card and continue a suspended child.\n */\nfunction subagentToWire(\n part: SubagentPart,\n options?: { includeSnapshotStructuredOutput: boolean },\n): Array<WireMessage> {\n const { subagent } = part\n const info: SubagentWireInfo = {\n name: subagent.name,\n status: subagent.status,\n ...(subagent.description !== undefined && {\n description: subagent.description,\n }),\n ...(subagent.error !== undefined && { error: subagent.error }),\n ...(subagent.interruptIds !== undefined && {\n interruptIds: subagent.interruptIds,\n }),\n ...(subagent.parentSubagentRunId !== undefined && {\n parentSubagentRunId: subagent.parentSubagentRunId,\n }),\n ...(subagent.parentToolCallId !== undefined && {\n parentToolCallId: subagent.parentToolCallId,\n }),\n ...(subagent.metadata !== undefined && { metadata: subagent.metadata }),\n }\n const child = uiMessagesToWire(subagent.messages, options)\n const own = child.some((message) => wireSubagentRunId(message) === undefined)\n const messages: Array<WireMessage> = own\n ? child\n : [{ id: `subagent:${subagent.id}`, role: 'assistant' }, ...child]\n return messages.map((message, index) => {\n const nestedId = wireSubagentRunId(message)\n if (nestedId !== undefined) {\n const nested = wireSubagentInfo(message)\n if (!nested || nested.parentSubagentRunId !== undefined) return message\n return withSubagentInfo(message, nestedId, {\n ...nested,\n parentSubagentRunId: subagent.id,\n })\n }\n return withSubagentInfo(\n message,\n subagent.id,\n !own && index === 0 ? { ...info, placeholder: true } : info,\n )\n })\n}\n\nfunction withSubagentInfo(\n message: WireMessage,\n subagentRunId: string,\n info: SubagentWireInfo,\n): WireMessage {\n const metadata = isRecord(message.metadata) ? message.metadata : {}\n const tanstack = isRecord(metadata.tanstack) ? metadata.tanstack : {}\n return {\n ...message,\n subagentRunId,\n metadata: { ...metadata, tanstack: { ...tanstack, subagent: info } },\n }\n}\n\nfunction collectUserContent(\n parts: ReadonlyArray<MessagePart>,\n): string | Array<InputContent> {\n const hasMultimodal = parts.some(\n (p) =>\n p.type === 'image' ||\n p.type === 'audio' ||\n p.type === 'video' ||\n p.type === 'document',\n )\n if (!hasMultimodal) {\n return collectText(parts)\n }\n const out: Array<InputContent> = []\n for (const p of parts) {\n if (p.type === 'text') {\n out.push({ type: 'text', text: p.content })\n } else if (\n p.type === 'image' ||\n p.type === 'audio' ||\n p.type === 'video' ||\n p.type === 'document'\n ) {\n out.push(p)\n }\n }\n return out\n}\n\nfunction thoughtSignatureFromMetadata(metadata: unknown): string | undefined {\n if (\n metadata == null ||\n typeof metadata !== 'object' ||\n Array.isArray(metadata)\n ) {\n return undefined\n }\n if (!('thoughtSignature' in metadata)) return undefined\n const value = metadata.thoughtSignature\n return typeof value === 'string' && value !== '' ? value : undefined\n}\n\nfunction collectToolCalls(\n parts: ReadonlyArray<MessagePart>,\n): Array<ToolCall> | undefined {\n const calls: Array<ToolCall> = []\n for (const p of parts) {\n if (p.type === 'tool-call') {\n const encryptedValue = thoughtSignatureFromMetadata(p.metadata)\n calls.push({\n id: p.id,\n type: 'function',\n function: { name: p.name, arguments: p.arguments },\n ...(encryptedValue !== undefined ? { encryptedValue } : {}),\n })\n }\n }\n return calls.length > 0 ? calls : undefined\n}\n\nfunction deriveReasoningId(messageId: string, part: MessagePart): string {\n return `${messageId}-reasoning-${(part as { id?: string }).id ?? hashContent((part as { content: string }).content)}`\n}\n\nfunction deriveToolMessageId(toolCallId: string): string {\n return `tool-${toolCallId}`\n}\n\nfunction uniqueToolWireId(id: string, used: Set<string>): string {\n return uniqueWireId(id, used)\n}\n\nfunction uniqueWireId(id: string, used: Set<string>): string {\n if (!used.has(id)) {\n used.add(id)\n return id\n }\n let suffix = 2\n while (used.has(`${id}-${suffix}`)) suffix++\n const unique = `${id}-${suffix}`\n used.add(unique)\n return unique\n}\n\nfunction toolWireId(\n id: string | undefined,\n toolCallId: string,\n assistantIds: ReadonlySet<string>,\n): string {\n const derived = deriveToolMessageId(toolCallId)\n if (id === undefined || assistantIds.has(id)) return derived\n return id\n}\n\nfunction hashContent(s: string): string {\n // Cheap deterministic id suffix; collisions are tolerable since\n // reasoning ids only matter for AG-UI server consumers, not for our\n // own server's dedup logic (which keys on toolCallId, not reasoning id).\n let h = 0\n for (let i = 0; i < s.length; i++) h = (h * 31 + s.charCodeAt(i)) | 0\n return Math.abs(h).toString(36)\n}\n"],"mappings":"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"}
@@ -7,11 +7,16 @@ import { specKeysFor } from "./spec-event-keys.js";
7
7
  function stringField(value) {
8
8
  return typeof value === "string" && value !== "" ? value : void 0;
9
9
  }
10
+ function chunkFields(chunk) {
11
+ const fields = {};
12
+ for (const key of Object.keys(chunk)) fields[key] = Reflect.get(chunk, key);
13
+ return fields;
14
+ }
10
15
  function encryptedValueExtras(chunk) {
11
16
  const extras = [];
12
17
  const timestamp = "timestamp" in chunk && typeof chunk.timestamp === "number" ? chunk.timestamp : void 0;
13
18
  if (typeof chunk.signature === "string" && chunk.signature !== "") {
14
- const source = chunk;
19
+ const source = chunkFields(chunk);
15
20
  const toolCallId = stringField(source.toolCallId);
16
21
  const entityId = stringField(chunk.stepId) ?? stringField(source.stepName) ?? stringField(source.messageId) ?? toolCallId;
17
22
  if (entityId !== void 0) extras.push(reasoningEncryptedValue({
@@ -34,7 +39,7 @@ function encryptedValueExtras(chunk) {
34
39
  }
35
40
  function normalizeStreamChunk(chunk) {
36
41
  const specKeys = specKeysFor(chunk.type);
37
- const source = chunk;
42
+ const source = chunkFields(chunk);
38
43
  const specChunk = {};
39
44
  for (const key of Object.keys(chunk)) if (specKeys.has(key)) specChunk[key] = source[key];
40
45
  if (chunk.type === EventType.TOOL_CALL_START) {
@@ -1 +1 @@
1
- {"version":3,"file":"normalize-stream-chunk.js","names":[],"sources":["../../../src/utilities/normalize-stream-chunk.ts"],"sourcesContent":["import { EventType } from '../types'\nimport type { StreamChunk, ToolCallResultEvent } from '../types'\nimport type { AdapterYieldChunk } from './adapter-yield-chunk'\nimport { isTanstackUsage, toSpecTokenUsage } from './ag-ui-usage'\nimport type { MetadataRecord } from './merge-metadata'\nimport { withTanstackMetadata } from './merge-metadata'\nimport { reasoningEncryptedValue } from './reasoning-encrypted-value'\nimport { specKeysFor } from './spec-event-keys'\n\nfunction stringField(value: unknown): string | undefined {\n return typeof value === 'string' && value !== '' ? value : undefined\n}\n\nfunction encryptedValueExtras(chunk: AdapterYieldChunk): Array<StreamChunk> {\n const extras: Array<StreamChunk> = []\n const timestamp =\n 'timestamp' in chunk && typeof chunk.timestamp === 'number'\n ? chunk.timestamp\n : undefined\n\n if (typeof chunk.signature === 'string' && chunk.signature !== '') {\n const source = chunk as Record<string, unknown>\n const toolCallId = stringField(source.toolCallId)\n const entityId =\n stringField(chunk.stepId) ??\n stringField(source.stepName) ??\n stringField(source.messageId) ??\n toolCallId\n if (entityId !== undefined) {\n extras.push(\n reasoningEncryptedValue({\n subtype: toolCallId && !chunk.stepId ? 'tool-call' : 'message',\n entityId,\n encryptedValue: chunk.signature,\n timestamp,\n }),\n )\n }\n }\n\n if (chunk.type === EventType.TOOL_CALL_START) {\n const thoughtSignature = stringField(\n (chunk.metadata as { thoughtSignature?: unknown } | undefined)\n ?.thoughtSignature,\n )\n if (thoughtSignature !== undefined && chunk.toolCallId) {\n extras.push(\n reasoningEncryptedValue({\n subtype: 'tool-call',\n entityId: chunk.toolCallId,\n encryptedValue: thoughtSignature,\n timestamp,\n }),\n )\n }\n }\n\n return extras\n}\n\nexport function normalizeStreamChunk(\n chunk: AdapterYieldChunk,\n): Array<StreamChunk> {\n const specKeys = specKeysFor(chunk.type)\n const source = chunk as Record<string, unknown>\n const specChunk: Record<string, unknown> & {\n metadata?: MetadataRecord | null\n } = {}\n\n for (const key of Object.keys(chunk)) {\n if (specKeys.has(key)) {\n specChunk[key] = source[key]\n }\n }\n\n if (chunk.type === EventType.TOOL_CALL_START) {\n if (specChunk.toolCallName === undefined && chunk.toolName) {\n specChunk.toolCallName = chunk.toolName\n }\n }\n\n if (chunk.type === EventType.RUN_ERROR && chunk.error != null) {\n if (specChunk.message === undefined && chunk.error.message) {\n specChunk.message = chunk.error.message\n }\n if (specChunk.code === undefined && chunk.error.code !== undefined) {\n specChunk.code = chunk.error.code\n }\n }\n\n const tanstack: MetadataRecord = {}\n\n if (\n chunk.model !== undefined &&\n chunk.type !== EventType.TEXT_MESSAGE_CONTENT &&\n chunk.type !== EventType.TOOL_CALL_ARGS\n ) {\n tanstack.model = chunk.model\n }\n\n if (chunk.finishReason !== undefined) {\n tanstack.finishReason = chunk.finishReason\n }\n\n const interruptErrors = chunk['tanstack:interruptErrors']\n if (interruptErrors !== undefined) {\n tanstack.interruptErrors = interruptErrors\n }\n\n if (chunk.type === EventType.CUSTOM || chunk.type === EventType.RUN_ERROR) {\n if (chunk.threadId !== undefined) {\n tanstack.threadId = chunk.threadId\n }\n if (chunk.runId !== undefined) {\n tanstack.runId = chunk.runId\n }\n }\n\n const skipLeftover = new Set(['result', 'error', 'tanstack:interruptErrors'])\n if (\n chunk.type === EventType.TEXT_MESSAGE_CONTENT ||\n chunk.type === EventType.TOOL_CALL_ARGS\n ) {\n skipLeftover.add('model')\n skipLeftover.add('content')\n skipLeftover.add('args')\n }\n if (chunk.type === EventType.TOOL_CALL_START) {\n skipLeftover.add('toolName')\n }\n for (const key of Object.keys(chunk)) {\n if (specKeys.has(key) || skipLeftover.has(key)) continue\n if (tanstack[key] !== undefined) continue\n const value = source[key]\n if (value !== undefined) {\n tanstack[key] = value\n }\n }\n\n if (\n (chunk.type === EventType.RUN_FINISHED ||\n chunk.type === EventType.RUN_ERROR) &&\n isTanstackUsage(specChunk.usage)\n ) {\n const { usage, leftover } = toSpecTokenUsage(specChunk.usage, {\n model: typeof chunk.model === 'string' ? chunk.model : undefined,\n })\n specChunk.usage = usage\n if (leftover !== undefined) {\n tanstack.usage = leftover\n }\n }\n\n const normalized =\n Object.keys(tanstack).length === 0\n ? specChunk\n : withTanstackMetadata(specChunk, tanstack)\n\n const extras = encryptedValueExtras(chunk)\n const main: Array<StreamChunk> = [normalized as StreamChunk]\n\n if (chunk.type === EventType.TOOL_CALL_END && chunk.result !== undefined) {\n const parentMessageId = source.parentMessageId\n const resultChunk: ToolCallResultEvent = {\n type: EventType.TOOL_CALL_RESULT,\n toolCallId: chunk.toolCallId,\n content: Array.isArray(chunk.result)\n ? JSON.stringify(chunk.result)\n : chunk.result,\n messageId:\n typeof parentMessageId === 'string' && parentMessageId !== ''\n ? parentMessageId\n : chunk.toolCallId,\n }\n if (chunk.state === 'output-error') {\n main.push({\n ...resultChunk,\n metadata: { tanstack: { state: chunk.state } },\n })\n } else {\n main.push(resultChunk)\n }\n }\n\n return [...main, ...extras]\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"normalize-stream-chunk.js","names":[],"sources":["../../../src/utilities/normalize-stream-chunk.ts"],"sourcesContent":["import { EventType } from '../types'\nimport type { StreamChunk, ToolCallResultEvent } from '../types'\nimport type { AdapterYieldChunk } from './adapter-yield-chunk'\nimport { isTanstackUsage, toSpecTokenUsage } from './ag-ui-usage'\nimport type { MetadataRecord } from './merge-metadata'\nimport { withTanstackMetadata } from './merge-metadata'\nimport { reasoningEncryptedValue } from './reasoning-encrypted-value'\nimport { specKeysFor } from './spec-event-keys'\n\nfunction stringField(value: unknown): string | undefined {\n return typeof value === 'string' && value !== '' ? value : undefined\n}\n\nfunction chunkFields(chunk: object) {\n const fields: Record<string, unknown> = {}\n for (const key of Object.keys(chunk)) {\n fields[key] = Reflect.get(chunk, key)\n }\n return fields\n}\n\nfunction encryptedValueExtras(chunk: AdapterYieldChunk): Array<StreamChunk> {\n const extras: Array<StreamChunk> = []\n const timestamp =\n 'timestamp' in chunk && typeof chunk.timestamp === 'number'\n ? chunk.timestamp\n : undefined\n\n if (typeof chunk.signature === 'string' && chunk.signature !== '') {\n const source = chunkFields(chunk)\n const toolCallId = stringField(source.toolCallId)\n const entityId =\n stringField(chunk.stepId) ??\n stringField(source.stepName) ??\n stringField(source.messageId) ??\n toolCallId\n if (entityId !== undefined) {\n extras.push(\n reasoningEncryptedValue({\n subtype: toolCallId && !chunk.stepId ? 'tool-call' : 'message',\n entityId,\n encryptedValue: chunk.signature,\n timestamp,\n }),\n )\n }\n }\n\n if (chunk.type === EventType.TOOL_CALL_START) {\n const thoughtSignature = stringField(\n (chunk.metadata as { thoughtSignature?: unknown } | undefined)\n ?.thoughtSignature,\n )\n if (thoughtSignature !== undefined && chunk.toolCallId) {\n extras.push(\n reasoningEncryptedValue({\n subtype: 'tool-call',\n entityId: chunk.toolCallId,\n encryptedValue: thoughtSignature,\n timestamp,\n }),\n )\n }\n }\n\n return extras\n}\n\nexport function normalizeStreamChunk(\n chunk: AdapterYieldChunk,\n): Array<StreamChunk> {\n const specKeys = specKeysFor(chunk.type)\n const source = chunkFields(chunk)\n const specChunk: Record<string, unknown> & {\n metadata?: MetadataRecord | null\n } = {}\n\n for (const key of Object.keys(chunk)) {\n if (specKeys.has(key)) {\n specChunk[key] = source[key]\n }\n }\n\n if (chunk.type === EventType.TOOL_CALL_START) {\n if (specChunk.toolCallName === undefined && chunk.toolName) {\n specChunk.toolCallName = chunk.toolName\n }\n }\n\n if (chunk.type === EventType.RUN_ERROR && chunk.error != null) {\n if (specChunk.message === undefined && chunk.error.message) {\n specChunk.message = chunk.error.message\n }\n if (specChunk.code === undefined && chunk.error.code !== undefined) {\n specChunk.code = chunk.error.code\n }\n }\n\n const tanstack: MetadataRecord = {}\n\n if (\n chunk.model !== undefined &&\n chunk.type !== EventType.TEXT_MESSAGE_CONTENT &&\n chunk.type !== EventType.TOOL_CALL_ARGS\n ) {\n tanstack.model = chunk.model\n }\n\n if (chunk.finishReason !== undefined) {\n tanstack.finishReason = chunk.finishReason\n }\n\n const interruptErrors = chunk['tanstack:interruptErrors']\n if (interruptErrors !== undefined) {\n tanstack.interruptErrors = interruptErrors\n }\n\n if (chunk.type === EventType.CUSTOM || chunk.type === EventType.RUN_ERROR) {\n if (chunk.threadId !== undefined) {\n tanstack.threadId = chunk.threadId\n }\n if (chunk.runId !== undefined) {\n tanstack.runId = chunk.runId\n }\n }\n\n const skipLeftover = new Set(['result', 'error', 'tanstack:interruptErrors'])\n if (\n chunk.type === EventType.TEXT_MESSAGE_CONTENT ||\n chunk.type === EventType.TOOL_CALL_ARGS\n ) {\n skipLeftover.add('model')\n skipLeftover.add('content')\n skipLeftover.add('args')\n }\n if (chunk.type === EventType.TOOL_CALL_START) {\n skipLeftover.add('toolName')\n }\n for (const key of Object.keys(chunk)) {\n if (specKeys.has(key) || skipLeftover.has(key)) continue\n if (tanstack[key] !== undefined) continue\n const value = source[key]\n if (value !== undefined) {\n tanstack[key] = value\n }\n }\n\n if (\n (chunk.type === EventType.RUN_FINISHED ||\n chunk.type === EventType.RUN_ERROR) &&\n isTanstackUsage(specChunk.usage)\n ) {\n const { usage, leftover } = toSpecTokenUsage(specChunk.usage, {\n model: typeof chunk.model === 'string' ? chunk.model : undefined,\n })\n specChunk.usage = usage\n if (leftover !== undefined) {\n tanstack.usage = leftover\n }\n }\n\n const normalized =\n Object.keys(tanstack).length === 0\n ? specChunk\n : withTanstackMetadata(specChunk, tanstack)\n\n const extras = encryptedValueExtras(chunk)\n const main: Array<StreamChunk> = [normalized as StreamChunk]\n\n if (chunk.type === EventType.TOOL_CALL_END && chunk.result !== undefined) {\n const parentMessageId = source.parentMessageId\n const resultChunk: ToolCallResultEvent = {\n type: EventType.TOOL_CALL_RESULT,\n toolCallId: chunk.toolCallId,\n content: Array.isArray(chunk.result)\n ? JSON.stringify(chunk.result)\n : chunk.result,\n messageId:\n typeof parentMessageId === 'string' && parentMessageId !== ''\n ? parentMessageId\n : chunk.toolCallId,\n }\n if (chunk.state === 'output-error') {\n main.push({\n ...resultChunk,\n metadata: { tanstack: { state: chunk.state } },\n })\n } else {\n main.push(resultChunk)\n }\n }\n\n return [...main, ...extras]\n}\n"],"mappings":"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"}
@@ -19,11 +19,6 @@ var SPEC_KEYS = /* @__PURE__ */ new Map([
19
19
  [EventType.TOOL_CALL_END, keys("toolCallId")],
20
20
  [EventType.TOOL_CALL_CHUNK, keys("toolCallId", "toolCallName", "parentMessageId", "delta")],
21
21
  [EventType.TOOL_CALL_RESULT, keys("messageId", "toolCallId", "content", "role")],
22
- [EventType.THINKING_START, keys("title")],
23
- [EventType.THINKING_END, SHARED],
24
- [EventType.THINKING_TEXT_MESSAGE_START, SHARED],
25
- [EventType.THINKING_TEXT_MESSAGE_CONTENT, keys("delta")],
26
- [EventType.THINKING_TEXT_MESSAGE_END, SHARED],
27
22
  [EventType.STATE_SNAPSHOT, keys("snapshot")],
28
23
  [EventType.STATE_DELTA, keys("delta")],
29
24
  [EventType.MESSAGES_SNAPSHOT, keys("messages")],
@@ -31,7 +26,7 @@ var SPEC_KEYS = /* @__PURE__ */ new Map([
31
26
  [EventType.ACTIVITY_DELTA, keys("messageId", "activityType", "patch")],
32
27
  [EventType.RAW, keys("event", "source")],
33
28
  [EventType.CUSTOM, keys("name", "value")],
34
- [EventType.RUN_STARTED, keys("threadId", "runId", "parentRunId", "input")],
29
+ [EventType.RUN_STARTED, keys("threadId", "runId", "protocolVersion", "parentRunId", "input")],
35
30
  [EventType.RUN_FINISHED, keys("threadId", "runId", "result", "outcome", "usage")],
36
31
  [EventType.RUN_ERROR, keys("message", "code", "usage")],
37
32
  [EventType.STEP_STARTED, keys("stepName")],
@@ -42,10 +37,20 @@ var SPEC_KEYS = /* @__PURE__ */ new Map([
42
37
  [EventType.REASONING_MESSAGE_END, keys("messageId")],
43
38
  [EventType.REASONING_MESSAGE_CHUNK, keys("messageId", "delta")],
44
39
  [EventType.REASONING_END, keys("messageId")],
45
- [EventType.REASONING_ENCRYPTED_VALUE, keys("subtype", "entityId", "encryptedValue")]
40
+ [EventType.REASONING_ENCRYPTED_VALUE, keys("subtype", "entityId", "encryptedValue")],
41
+ [EventType.SUBAGENT_STARTED, keys("subagentRunId", "name", "description", "parentSubagentRunId", "parentToolCallId", "parentMessageId")],
42
+ [EventType.SUBAGENT_FINISHED, keys("subagentRunId", "result", "outcome")],
43
+ [EventType.SUBAGENT_ERROR, keys("subagentRunId", "message", "code")]
46
44
  ]);
45
+ var RUN_SCOPED = /* @__PURE__ */ new Set([
46
+ EventType.RUN_STARTED,
47
+ EventType.RUN_FINISHED,
48
+ EventType.RUN_ERROR,
49
+ EventType.MESSAGES_SNAPSHOT
50
+ ]);
51
+ var ATTRIBUTABLE_KEYS = new Map([...SPEC_KEYS].filter(([type]) => !RUN_SCOPED.has(type)).map(([type, fields]) => [type, /* @__PURE__ */ new Set([...fields, "subagentRunId"])]));
47
52
  function specKeysFor(type) {
48
- return SPEC_KEYS.get(type) ?? SHARED;
53
+ return ATTRIBUTABLE_KEYS.get(type) ?? SPEC_KEYS.get(type) ?? SHARED;
49
54
  }
50
55
  function isSpecTopLevelKey(type, key) {
51
56
  return specKeysFor(type).has(key);
@@ -1 +1 @@
1
- {"version":3,"file":"spec-event-keys.js","names":[],"sources":["../../../src/utilities/spec-event-keys.ts"],"sourcesContent":["import { EventType } from '../types'\n\nconst SHARED: ReadonlySet<string> = new Set([\n 'type',\n 'timestamp',\n 'rawEvent',\n 'metadata',\n])\n\nfunction keys(...fields: Array<string>): ReadonlySet<string> {\n return new Set([...SHARED, ...fields])\n}\n\nconst SPEC_KEYS: ReadonlyMap<string, ReadonlySet<string>> = new Map([\n [EventType.TEXT_MESSAGE_START, keys('messageId', 'role', 'name')],\n [EventType.TEXT_MESSAGE_CONTENT, keys('messageId', 'delta')],\n [EventType.TEXT_MESSAGE_END, keys('messageId')],\n [EventType.TEXT_MESSAGE_CHUNK, keys('messageId', 'role', 'delta', 'name')],\n [\n EventType.TOOL_CALL_START,\n keys('toolCallId', 'toolCallName', 'parentMessageId'),\n ],\n [EventType.TOOL_CALL_ARGS, keys('toolCallId', 'delta')],\n [EventType.TOOL_CALL_END, keys('toolCallId')],\n [\n EventType.TOOL_CALL_CHUNK,\n keys('toolCallId', 'toolCallName', 'parentMessageId', 'delta'),\n ],\n [\n EventType.TOOL_CALL_RESULT,\n keys('messageId', 'toolCallId', 'content', 'role'),\n ],\n [EventType.THINKING_START, keys('title')],\n [EventType.THINKING_END, SHARED],\n [EventType.THINKING_TEXT_MESSAGE_START, SHARED],\n [EventType.THINKING_TEXT_MESSAGE_CONTENT, keys('delta')],\n [EventType.THINKING_TEXT_MESSAGE_END, SHARED],\n [EventType.STATE_SNAPSHOT, keys('snapshot')],\n [EventType.STATE_DELTA, keys('delta')],\n [EventType.MESSAGES_SNAPSHOT, keys('messages')],\n [\n EventType.ACTIVITY_SNAPSHOT,\n keys('messageId', 'activityType', 'content', 'replace'),\n ],\n [EventType.ACTIVITY_DELTA, keys('messageId', 'activityType', 'patch')],\n [EventType.RAW, keys('event', 'source')],\n [EventType.CUSTOM, keys('name', 'value')],\n [EventType.RUN_STARTED, keys('threadId', 'runId', 'parentRunId', 'input')],\n [\n EventType.RUN_FINISHED,\n keys('threadId', 'runId', 'result', 'outcome', 'usage'),\n ],\n [EventType.RUN_ERROR, keys('message', 'code', 'usage')],\n [EventType.STEP_STARTED, keys('stepName')],\n [EventType.STEP_FINISHED, keys('stepName')],\n [EventType.REASONING_START, keys('messageId')],\n [EventType.REASONING_MESSAGE_START, keys('messageId', 'role')],\n [EventType.REASONING_MESSAGE_CONTENT, keys('messageId', 'delta')],\n [EventType.REASONING_MESSAGE_END, keys('messageId')],\n [EventType.REASONING_MESSAGE_CHUNK, keys('messageId', 'delta')],\n [EventType.REASONING_END, keys('messageId')],\n [\n EventType.REASONING_ENCRYPTED_VALUE,\n keys('subtype', 'entityId', 'encryptedValue'),\n ],\n])\n\nexport function specKeysFor(type: string): ReadonlySet<string> {\n return SPEC_KEYS.get(type) ?? SHARED\n}\n\nexport function isSpecTopLevelKey(type: string, key: string): boolean {\n return specKeysFor(type).has(key)\n}\n"],"mappings":";;AAEA,IAAM,yBAA8B,IAAI,IAAI;CAC1C;CACA;CACA;CACA;AACF,CAAC;AAED,SAAS,KAAK,GAAG,QAA4C;CAC3D,uBAAO,IAAI,IAAI,CAAC,GAAG,QAAQ,GAAG,MAAM,CAAC;AACvC;AAEA,IAAM,4BAAsD,IAAI,IAAI;CAClE,CAAC,UAAU,oBAAoB,KAAK,aAAa,QAAQ,MAAM,CAAC;CAChE,CAAC,UAAU,sBAAsB,KAAK,aAAa,OAAO,CAAC;CAC3D,CAAC,UAAU,kBAAkB,KAAK,WAAW,CAAC;CAC9C,CAAC,UAAU,oBAAoB,KAAK,aAAa,QAAQ,SAAS,MAAM,CAAC;CACzE,CACE,UAAU,iBACV,KAAK,cAAc,gBAAgB,iBAAiB,CACtD;CACA,CAAC,UAAU,gBAAgB,KAAK,cAAc,OAAO,CAAC;CACtD,CAAC,UAAU,eAAe,KAAK,YAAY,CAAC;CAC5C,CACE,UAAU,iBACV,KAAK,cAAc,gBAAgB,mBAAmB,OAAO,CAC/D;CACA,CACE,UAAU,kBACV,KAAK,aAAa,cAAc,WAAW,MAAM,CACnD;CACA,CAAC,UAAU,gBAAgB,KAAK,OAAO,CAAC;CACxC,CAAC,UAAU,cAAc,MAAM;CAC/B,CAAC,UAAU,6BAA6B,MAAM;CAC9C,CAAC,UAAU,+BAA+B,KAAK,OAAO,CAAC;CACvD,CAAC,UAAU,2BAA2B,MAAM;CAC5C,CAAC,UAAU,gBAAgB,KAAK,UAAU,CAAC;CAC3C,CAAC,UAAU,aAAa,KAAK,OAAO,CAAC;CACrC,CAAC,UAAU,mBAAmB,KAAK,UAAU,CAAC;CAC9C,CACE,UAAU,mBACV,KAAK,aAAa,gBAAgB,WAAW,SAAS,CACxD;CACA,CAAC,UAAU,gBAAgB,KAAK,aAAa,gBAAgB,OAAO,CAAC;CACrE,CAAC,UAAU,KAAK,KAAK,SAAS,QAAQ,CAAC;CACvC,CAAC,UAAU,QAAQ,KAAK,QAAQ,OAAO,CAAC;CACxC,CAAC,UAAU,aAAa,KAAK,YAAY,SAAS,eAAe,OAAO,CAAC;CACzE,CACE,UAAU,cACV,KAAK,YAAY,SAAS,UAAU,WAAW,OAAO,CACxD;CACA,CAAC,UAAU,WAAW,KAAK,WAAW,QAAQ,OAAO,CAAC;CACtD,CAAC,UAAU,cAAc,KAAK,UAAU,CAAC;CACzC,CAAC,UAAU,eAAe,KAAK,UAAU,CAAC;CAC1C,CAAC,UAAU,iBAAiB,KAAK,WAAW,CAAC;CAC7C,CAAC,UAAU,yBAAyB,KAAK,aAAa,MAAM,CAAC;CAC7D,CAAC,UAAU,2BAA2B,KAAK,aAAa,OAAO,CAAC;CAChE,CAAC,UAAU,uBAAuB,KAAK,WAAW,CAAC;CACnD,CAAC,UAAU,yBAAyB,KAAK,aAAa,OAAO,CAAC;CAC9D,CAAC,UAAU,eAAe,KAAK,WAAW,CAAC;CAC3C,CACE,UAAU,2BACV,KAAK,WAAW,YAAY,gBAAgB,CAC9C;AACF,CAAC;AAED,SAAgB,YAAY,MAAmC;CAC7D,OAAO,UAAU,IAAI,IAAI,KAAK;AAChC;AAEA,SAAgB,kBAAkB,MAAc,KAAsB;CACpE,OAAO,YAAY,IAAI,CAAC,CAAC,IAAI,GAAG;AAClC"}
1
+ {"version":3,"file":"spec-event-keys.js","names":[],"sources":["../../../src/utilities/spec-event-keys.ts"],"sourcesContent":["import { EventType } from '../types'\n\nconst SHARED: ReadonlySet<string> = new Set([\n 'type',\n 'timestamp',\n 'rawEvent',\n 'metadata',\n])\n\nfunction keys(...fields: Array<string>): ReadonlySet<string> {\n return new Set([...SHARED, ...fields])\n}\n\nconst SPEC_KEYS: ReadonlyMap<string, ReadonlySet<string>> = new Map([\n [EventType.TEXT_MESSAGE_START, keys('messageId', 'role', 'name')],\n [EventType.TEXT_MESSAGE_CONTENT, keys('messageId', 'delta')],\n [EventType.TEXT_MESSAGE_END, keys('messageId')],\n [EventType.TEXT_MESSAGE_CHUNK, keys('messageId', 'role', 'delta', 'name')],\n [\n EventType.TOOL_CALL_START,\n keys('toolCallId', 'toolCallName', 'parentMessageId'),\n ],\n [EventType.TOOL_CALL_ARGS, keys('toolCallId', 'delta')],\n [EventType.TOOL_CALL_END, keys('toolCallId')],\n [\n EventType.TOOL_CALL_CHUNK,\n keys('toolCallId', 'toolCallName', 'parentMessageId', 'delta'),\n ],\n [\n EventType.TOOL_CALL_RESULT,\n keys('messageId', 'toolCallId', 'content', 'role'),\n ],\n [EventType.STATE_SNAPSHOT, keys('snapshot')],\n [EventType.STATE_DELTA, keys('delta')],\n [EventType.MESSAGES_SNAPSHOT, keys('messages')],\n [\n EventType.ACTIVITY_SNAPSHOT,\n keys('messageId', 'activityType', 'content', 'replace'),\n ],\n [EventType.ACTIVITY_DELTA, keys('messageId', 'activityType', 'patch')],\n [EventType.RAW, keys('event', 'source')],\n [EventType.CUSTOM, keys('name', 'value')],\n [\n EventType.RUN_STARTED,\n keys('threadId', 'runId', 'protocolVersion', 'parentRunId', 'input'),\n ],\n [\n EventType.RUN_FINISHED,\n keys('threadId', 'runId', 'result', 'outcome', 'usage'),\n ],\n [EventType.RUN_ERROR, keys('message', 'code', 'usage')],\n [EventType.STEP_STARTED, keys('stepName')],\n [EventType.STEP_FINISHED, keys('stepName')],\n [EventType.REASONING_START, keys('messageId')],\n [EventType.REASONING_MESSAGE_START, keys('messageId', 'role')],\n [EventType.REASONING_MESSAGE_CONTENT, keys('messageId', 'delta')],\n [EventType.REASONING_MESSAGE_END, keys('messageId')],\n [EventType.REASONING_MESSAGE_CHUNK, keys('messageId', 'delta')],\n [EventType.REASONING_END, keys('messageId')],\n [\n EventType.REASONING_ENCRYPTED_VALUE,\n keys('subtype', 'entityId', 'encryptedValue'),\n ],\n [\n EventType.SUBAGENT_STARTED,\n keys(\n 'subagentRunId',\n 'name',\n 'description',\n 'parentSubagentRunId',\n 'parentToolCallId',\n 'parentMessageId',\n ),\n ],\n [EventType.SUBAGENT_FINISHED, keys('subagentRunId', 'result', 'outcome')],\n [EventType.SUBAGENT_ERROR, keys('subagentRunId', 'message', 'code')],\n])\n\nconst RUN_SCOPED = new Set<string>([\n EventType.RUN_STARTED,\n EventType.RUN_FINISHED,\n EventType.RUN_ERROR,\n EventType.MESSAGES_SNAPSHOT,\n])\n\nconst ATTRIBUTABLE_KEYS = new Map(\n [...SPEC_KEYS]\n .filter(([type]) => !RUN_SCOPED.has(type))\n .map(\n ([type, fields]) =>\n [type, new Set([...fields, 'subagentRunId'])] as const,\n ),\n)\n\nexport function specKeysFor(type: string): ReadonlySet<string> {\n return ATTRIBUTABLE_KEYS.get(type) ?? SPEC_KEYS.get(type) ?? SHARED\n}\n\nexport function isSpecTopLevelKey(type: string, key: string): boolean {\n return specKeysFor(type).has(key)\n}\n"],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import { SubagentInfo as AGUISubagentInfo } from '@ag-ui/core';
2
+ import { SubagentHandleData } from '../types.js';
3
+ /**
4
+ * Card data that travels on each child wire message, in
5
+ * `metadata.tanstack.subagent`. The messages carry the AG-UI `subagentRunId`.
6
+ */
7
+ export interface SubagentWireInfo extends AGUISubagentInfo, Pick<SubagentHandleData, 'status' | 'error' | 'interruptIds' | 'parentSubagentRunId' | 'parentToolCallId' | 'metadata'> {
8
+ /** The child has no messages yet. This wire message only holds the card. */
9
+ placeholder?: true;
10
+ }
11
+ export interface SubagentWireGroup<T> {
12
+ id: string;
13
+ info: SubagentWireInfo;
14
+ /** The child's messages without its own tag. Nested children keep theirs. */
15
+ messages: Array<T>;
16
+ /** Index in `top` of the last message before this child, or -1. */
17
+ hostIndex: number;
18
+ }
19
+ export declare function wireSubagentRunId(message: unknown): string | undefined;
20
+ export declare function wireSubagentInfo(message: unknown): SubagentWireInfo | undefined;
21
+ /**
22
+ * Split wire messages into the parent's own messages and one group per direct
23
+ * child. A nested child's messages stay inside its parent's group.
24
+ */
25
+ export declare function splitSubagentWire<T>(messages: ReadonlyArray<T>): {
26
+ top: Array<T>;
27
+ groups: Array<SubagentWireGroup<T>>;
28
+ };
29
+ /** Text a child wrote, for the parent model and for a later child. */
30
+ export declare function subagentWireText(messages: ReadonlyArray<unknown>): string;
31
+ /**
32
+ * The id of the parent assistant message that hosts a routed turn's cards.
33
+ * The persistence recorder writes that message, and a handoff run passes the
34
+ * same id so the stored thread keeps one copy.
35
+ */
36
+ export declare function subagentHostMessageId(runId: string): string;