@assistant-ui/core 0.2.5 → 0.2.7

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 (140) hide show
  1. package/dist/index.d.ts +4 -2
  2. package/dist/index.js +6 -0
  3. package/dist/index.js.map +1 -0
  4. package/dist/internal/duplicate-detection.d.ts +5 -0
  5. package/dist/internal/duplicate-detection.d.ts.map +1 -0
  6. package/dist/internal/duplicate-detection.js +11 -0
  7. package/dist/internal/duplicate-detection.js.map +1 -0
  8. package/dist/react/AssistantProvider.d.ts.map +1 -1
  9. package/dist/react/AssistantProvider.js.map +1 -1
  10. package/dist/react/index.d.ts +3 -2
  11. package/dist/react/index.js +2 -2
  12. package/dist/react/primitives/chainOfThought/ChainOfThoughtParts.js.map +1 -1
  13. package/dist/react/primitives/message/MessageGroupedParts.d.ts +25 -21
  14. package/dist/react/primitives/message/MessageGroupedParts.d.ts.map +1 -1
  15. package/dist/react/primitives/message/MessageGroupedParts.js +6 -7
  16. package/dist/react/primitives/message/MessageGroupedParts.js.map +1 -1
  17. package/dist/react/primitives/message/MessageParts.d.ts +2 -1
  18. package/dist/react/primitives/message/MessageParts.d.ts.map +1 -1
  19. package/dist/react/primitives/message/MessageParts.js +9 -4
  20. package/dist/react/primitives/message/MessageParts.js.map +1 -1
  21. package/dist/react/providers/TextMessagePartProvider.d.ts.map +1 -1
  22. package/dist/react/providers/TextMessagePartProvider.js +3 -0
  23. package/dist/react/providers/TextMessagePartProvider.js.map +1 -1
  24. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts +3 -1
  25. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts.map +1 -1
  26. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts +3 -1
  27. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
  28. package/dist/react/runtimes/external-message-converter.d.ts +1 -1
  29. package/dist/react/runtimes/external-message-converter.d.ts.map +1 -1
  30. package/dist/react/runtimes/external-message-converter.js +7 -3
  31. package/dist/react/runtimes/external-message-converter.js.map +1 -1
  32. package/dist/react/types/MessagePartComponentTypes.d.ts +8 -0
  33. package/dist/react/types/MessagePartComponentTypes.d.ts.map +1 -1
  34. package/dist/react/utils/groupParts.d.ts +40 -12
  35. package/dist/react/utils/groupParts.d.ts.map +1 -1
  36. package/dist/react/utils/groupParts.js +51 -9
  37. package/dist/react/utils/groupParts.js.map +1 -1
  38. package/dist/runtime/api/attachment-runtime.d.ts.map +1 -1
  39. package/dist/runtime/api/attachment-runtime.js.map +1 -1
  40. package/dist/runtime/api/message-part-runtime.d.ts +8 -0
  41. package/dist/runtime/api/message-part-runtime.d.ts.map +1 -1
  42. package/dist/runtime/api/message-part-runtime.js +13 -0
  43. package/dist/runtime/api/message-part-runtime.js.map +1 -1
  44. package/dist/runtime/api/thread-runtime.d.ts +2 -1
  45. package/dist/runtime/api/thread-runtime.d.ts.map +1 -1
  46. package/dist/runtime/base/base-thread-runtime-core.d.ts +2 -1
  47. package/dist/runtime/base/base-thread-runtime-core.d.ts.map +1 -1
  48. package/dist/runtime/base/base-thread-runtime-core.js.map +1 -1
  49. package/dist/runtime/interfaces/thread-runtime-core.d.ts +15 -1
  50. package/dist/runtime/interfaces/thread-runtime-core.d.ts.map +1 -1
  51. package/dist/runtime/utils/thread-message-like.d.ts +10 -0
  52. package/dist/runtime/utils/thread-message-like.d.ts.map +1 -1
  53. package/dist/runtime/utils/thread-message-like.js.map +1 -1
  54. package/dist/runtimes/external-store/external-store-adapter.d.ts +33 -1
  55. package/dist/runtimes/external-store/external-store-adapter.d.ts.map +1 -1
  56. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.d.ts.map +1 -1
  57. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js.map +1 -1
  58. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts +27 -1
  59. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts.map +1 -1
  60. package/dist/runtimes/external-store/external-store-thread-runtime-core.js +98 -3
  61. package/dist/runtimes/external-store/external-store-thread-runtime-core.js.map +1 -1
  62. package/dist/runtimes/local/local-thread-runtime-core.d.ts +2 -1
  63. package/dist/runtimes/local/local-thread-runtime-core.d.ts.map +1 -1
  64. package/dist/runtimes/local/local-thread-runtime-core.js +3 -0
  65. package/dist/runtimes/local/local-thread-runtime-core.js.map +1 -1
  66. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts +1 -0
  67. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts.map +1 -1
  68. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.js +3 -0
  69. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.js.map +1 -1
  70. package/dist/runtimes/remote-thread-list/empty-thread-core.d.ts.map +1 -1
  71. package/dist/runtimes/remote-thread-list/empty-thread-core.js +3 -0
  72. package/dist/runtimes/remote-thread-list/empty-thread-core.js.map +1 -1
  73. package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts +168 -0
  74. package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts.map +1 -0
  75. package/dist/runtimes/tool-invocations/ToolInvocationTracker.js +449 -0
  76. package/dist/runtimes/tool-invocations/ToolInvocationTracker.js.map +1 -0
  77. package/dist/store/clients/thread-message-client.d.ts.map +1 -1
  78. package/dist/store/clients/thread-message-client.js +3 -0
  79. package/dist/store/clients/thread-message-client.js.map +1 -1
  80. package/dist/store/runtime-clients/message-part-runtime-client.js +1 -0
  81. package/dist/store/runtime-clients/message-part-runtime-client.js.map +1 -1
  82. package/dist/store/scopes/part.d.ts +7 -0
  83. package/dist/store/scopes/part.d.ts.map +1 -1
  84. package/dist/subscribable/subscribable.d.ts.map +1 -1
  85. package/dist/subscribable/subscribable.js.map +1 -1
  86. package/dist/types/message.d.ts +6 -0
  87. package/dist/types/message.d.ts.map +1 -1
  88. package/dist/types/message.js.map +1 -1
  89. package/package.json +4 -4
  90. package/src/adapters/index.ts +1 -4
  91. package/src/index.ts +11 -0
  92. package/src/internal/duplicate-detection.ts +26 -0
  93. package/src/react/AssistantProvider.tsx +2 -3
  94. package/src/react/index.ts +2 -6
  95. package/src/react/primitives/chainOfThought/ChainOfThoughtParts.tsx +1 -2
  96. package/src/react/primitives/message/MessageAttachments.test.tsx +1 -1
  97. package/src/react/primitives/message/MessageGroupedParts.tsx +38 -31
  98. package/src/react/primitives/message/MessageParts.tsx +14 -1
  99. package/src/react/providers/TextMessagePartProvider.tsx +3 -0
  100. package/src/react/runtimes/external-message-converter.ts +26 -13
  101. package/src/react/types/MessagePartComponentTypes.ts +8 -0
  102. package/src/react/utils/groupParts.ts +67 -22
  103. package/src/runtime/api/attachment-runtime.ts +1 -2
  104. package/src/runtime/api/message-part-runtime.ts +26 -0
  105. package/src/runtime/base/base-thread-runtime-core.ts +4 -0
  106. package/src/runtime/interfaces/thread-runtime-core.ts +15 -0
  107. package/src/runtime/internal.ts +1 -4
  108. package/src/runtime/utils/thread-message-like.ts +7 -0
  109. package/src/runtimes/external-store/external-store-adapter.ts +37 -0
  110. package/src/runtimes/external-store/external-store-thread-list-runtime-core.ts +1 -3
  111. package/src/runtimes/external-store/external-store-thread-runtime-core.ts +168 -4
  112. package/src/runtimes/local/local-thread-runtime-core.ts +5 -0
  113. package/src/runtimes/readonly/ReadonlyThreadRuntimeCore.ts +4 -0
  114. package/src/runtimes/remote-thread-list/empty-thread-core.ts +4 -0
  115. package/src/runtimes/tool-invocations/EDGE_CASES.md +194 -0
  116. package/src/runtimes/tool-invocations/ToolInvocationTracker.test.ts +1054 -0
  117. package/src/runtimes/tool-invocations/ToolInvocationTracker.ts +783 -0
  118. package/src/store/clients/thread-message-client.ts +3 -0
  119. package/src/store/runtime-clients/message-part-runtime-client.ts +2 -0
  120. package/src/store/scopes/part.ts +4 -0
  121. package/src/subscribable/subscribable.ts +3 -3
  122. package/src/tests/OptimisticState-delete-crash.test.ts +2 -0
  123. package/src/tests/OptimisticState-list-race.test.ts +2 -0
  124. package/src/tests/RemoteThreadListThreadListRuntimeCore-loadMore.test.ts +5 -5
  125. package/src/tests/auiV0Encode.test.ts +1 -1
  126. package/src/tests/composer-can-send.test.ts +8 -4
  127. package/src/tests/duplicate-detection.test.ts +34 -0
  128. package/src/tests/external-store-thread-list-runtime-core.test.ts +1 -1
  129. package/src/tests/external-store-thread-runtime-core.test.ts +7 -6
  130. package/src/tests/groupParts.test.ts +118 -32
  131. package/src/tests/no-unsafe-process-env.test.ts +1 -0
  132. package/src/tests/remote-thread-list-isLoading.test.ts +2 -0
  133. package/src/tests/thread-message-like.test.ts +4 -1
  134. package/src/types/index.ts +1 -4
  135. package/src/types/message.ts +7 -0
  136. package/dist/react/runtimes/useToolInvocations.d.ts +0 -53
  137. package/dist/react/runtimes/useToolInvocations.d.ts.map +0 -1
  138. package/dist/react/runtimes/useToolInvocations.js +0 -380
  139. package/dist/react/runtimes/useToolInvocations.js.map +0 -1
  140. package/src/react/runtimes/useToolInvocations.ts +0 -694
@@ -1,14 +1,56 @@
1
+ import { isMcpAppUri } from "../../types/message.js";
1
2
  //#region src/react/utils/groupParts.ts
2
- const EMPTY_PATH = Object.freeze([]);
3
3
  /**
4
- * Normalize a `groupBy` return value to a path array.
5
- * `null`/`undefined`/`[]` → `[]` (ungrouped).
6
- * `"foo"` `["foo"]`. Arrays pass through.
4
+ * Hierarchical adjacent-coalescing grouping for message parts.
5
+ *
6
+ * Given a group path per part (from `groupBy`), builds a tree of group
7
+ * nodes wrapping individual parts. Adjacent parts sharing a path prefix
8
+ * coalesce into the same group; ungrouped parts are direct children of
9
+ * the root.
10
+ *
11
+ * Each node gets a structural `nodeKey` built from sibling indices
12
+ * (`"0.1.0"`), stable under append-only streaming.
7
13
  */
8
- const normalizeGroupKey = (key) => {
9
- if (key == null) return EMPTY_PATH;
10
- if (typeof key === "string") return [key];
11
- return key;
14
+ /**
15
+ * Symbol attached to memoizable `groupBy` functions (e.g. those returned
16
+ * by {@link groupPartByType}). Carries a string fingerprint of the config
17
+ * so `MessagePrimitive.GroupedParts` can memo the tree on
18
+ * `[parts, memoKey]` across renders — even when the helper call site
19
+ * reconstructs the function each render.
20
+ */
21
+ const GROUPBY_MEMO_KEY = Symbol.for("@assistant-ui/groupBy.memoKey");
22
+ /**
23
+ * Build a `groupBy` from a `part.type → group-key path` lookup.
24
+ * Parts whose type isn't in the map are left ungrouped. The returned
25
+ * function carries a stable {@link GROUPBY_MEMO_KEY} fingerprint so
26
+ * `<MessagePrimitive.GroupedParts>` can memoize its tree across renders.
27
+ *
28
+ * Special key `"mcp-app"` matches tool-call parts that point at an
29
+ * assistant-ui MCP app resource (`ui://...`) and takes precedence over
30
+ * the `"tool-call"` entry for those parts.
31
+ *
32
+ * @example
33
+ * ```tsx
34
+ * <MessagePrimitive.GroupedParts
35
+ * groupBy={groupPartByType({
36
+ * reasoning: ["group-thought", "group-reasoning"],
37
+ * "tool-call": ["group-thought", "group-tool"],
38
+ * "mcp-app": [],
39
+ * })}
40
+ * >
41
+ * {({ part, children }) => { ... }}
42
+ * </MessagePrimitive.GroupedParts>
43
+ * ```
44
+ */
45
+ const groupPartByType = (map) => {
46
+ const lookup = map;
47
+ const fn = ((part) => {
48
+ if (part.type === "tool-call" && lookup["mcp-app"] !== void 0 && isMcpAppUri(part.mcp?.app?.resourceUri)) return lookup["mcp-app"];
49
+ return lookup[part.type] ?? [];
50
+ });
51
+ const sortedEntries = Object.keys(map).sort().map((k) => [k, map[k]]);
52
+ fn[GROUPBY_MEMO_KEY] = `groupPartByType:${JSON.stringify(sortedEntries)}`;
53
+ return fn;
12
54
  };
13
55
  const makeChildNodeKey = (parent) => {
14
56
  const idx = parent.nextChildIdx++;
@@ -65,6 +107,6 @@ const buildGroupTree = (paths) => {
65
107
  return root.children;
66
108
  };
67
109
  //#endregion
68
- export { buildGroupTree, normalizeGroupKey };
110
+ export { GROUPBY_MEMO_KEY, buildGroupTree, groupPartByType };
69
111
 
70
112
  //# sourceMappingURL=groupParts.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"groupParts.js","names":[],"sources":["../../../src/react/utils/groupParts.ts"],"sourcesContent":["/**\n * Hierarchical adjacent-coalescing grouping for message parts.\n *\n * Given a group path per part (from `groupBy`), builds a tree of group\n * nodes wrapping individual parts. Adjacent parts sharing a path prefix\n * coalesce into the same group; ungrouped parts are direct children of\n * the root.\n *\n * Each node gets a structural `nodeKey` built from sibling indices\n * (`\"0.1.0\"`), stable under append-only streaming.\n */\n\n/**\n * Public group key type. Group keys must be prefixed with `group-` so\n * that a unified `switch (part.type)` in the renderer can distinguish\n * a group key (e.g. `\"group-thought\"`) from a real part type\n * (`\"text\"`, `\"tool-call\"`).\n */\nexport type GroupKey<TKey extends `group-${string}` = `group-${string}`> =\n | TKey\n | readonly TKey[]\n | null\n | undefined;\n\nexport type GroupNode = GroupNodeGroup | GroupNodePart;\n\nexport interface GroupNodeGroup {\n readonly type: \"group\";\n /** Current-level group key (last segment of the path). */\n readonly key: string;\n /** Structural React key: sibling-index path, e.g. `\"0.1.0\"`. */\n readonly nodeKey: string;\n /** Indices of parts in this subtree, in order. */\n readonly indices: readonly number[];\n readonly children: readonly GroupNode[];\n}\n\nexport interface GroupNodePart {\n readonly type: \"part\";\n /** Index of the part in the message. */\n readonly index: number;\n /** Structural React key: sibling-index path within parent. */\n readonly nodeKey: string;\n}\n\nconst EMPTY_PATH: readonly string[] = Object.freeze([]);\n\n/**\n * Normalize a `groupBy` return value to a path array.\n * `null`/`undefined`/`[]` → `[]` (ungrouped).\n * `\"foo\"` → `[\"foo\"]`. Arrays pass through.\n */\nexport const normalizeGroupKey = (key: GroupKey): readonly string[] => {\n if (key == null) return EMPTY_PATH;\n if (typeof key === \"string\") return [key];\n return key;\n};\n\ninterface BuildFrame {\n key: string;\n nodeKey: string;\n indices: number[];\n children: GroupNode[];\n nextChildIdx: number;\n}\n\nconst makeChildNodeKey = (parent: BuildFrame): string => {\n const idx = parent.nextChildIdx++;\n return parent.nodeKey === \"\" ? String(idx) : `${parent.nodeKey}.${idx}`;\n};\n\n/**\n * Build the group tree from an array of normalized group paths.\n * `paths[i]` is the path for part `i`. The output tree contains one\n * `part` node per part and one `group` node per coalesced run.\n */\nexport const buildGroupTree = (\n paths: readonly (readonly string[])[],\n): readonly GroupNode[] => {\n const root: BuildFrame = {\n key: \"\",\n nodeKey: \"\",\n indices: [],\n children: [],\n nextChildIdx: 0,\n };\n const stack: BuildFrame[] = [root];\n\n const closeTop = (): void => {\n const closing = stack.pop()!;\n const parent = stack[stack.length - 1]!;\n parent.children.push({\n type: \"group\",\n key: closing.key,\n nodeKey: closing.nodeKey,\n indices: closing.indices,\n children: closing.children,\n });\n };\n\n for (let i = 0; i < paths.length; i++) {\n const path = paths[i]!;\n\n // Find the longest prefix shared between currently-open groups\n // (excluding root) and this part's path.\n let common = 0;\n while (\n common < stack.length - 1 &&\n common < path.length &&\n stack[common + 1]!.key === path[common]\n ) {\n common++;\n }\n\n // Close groups not on this path.\n while (stack.length - 1 > common) {\n closeTop();\n }\n\n // Open new groups down to the part's depth.\n while (stack.length - 1 < path.length) {\n const parent = stack[stack.length - 1]!;\n stack.push({\n key: path[stack.length - 1]!,\n nodeKey: makeChildNodeKey(parent),\n indices: [],\n children: [],\n nextChildIdx: 0,\n });\n }\n\n // Push this part as a leaf in the deepest open group (or root).\n const top = stack[stack.length - 1]!;\n top.children.push({\n type: \"part\",\n index: i,\n nodeKey: makeChildNodeKey(top),\n });\n\n // Record the part index in every open ancestor group.\n for (let s = 1; s < stack.length; s++) {\n stack[s]!.indices.push(i);\n }\n }\n\n // Close any still-open groups.\n while (stack.length > 1) {\n closeTop();\n }\n\n return root.children;\n};\n"],"mappings":";AA6CA,MAAM,aAAgC,OAAO,OAAO,CAAC,CAAC;;;;;;AAOtD,MAAa,qBAAqB,QAAqC;CACrE,IAAI,OAAO,MAAM,OAAO;CACxB,IAAI,OAAO,QAAQ,UAAU,OAAO,CAAC,GAAG;CACxC,OAAO;AACT;AAUA,MAAM,oBAAoB,WAA+B;CACvD,MAAM,MAAM,OAAO;CACnB,OAAO,OAAO,YAAY,KAAK,OAAO,GAAG,IAAI,GAAG,OAAO,QAAQ,GAAG;AACpE;;;;;;AAOA,MAAa,kBACX,UACyB;CACzB,MAAM,OAAmB;EACvB,KAAK;EACL,SAAS;EACT,SAAS,CAAC;EACV,UAAU,CAAC;EACX,cAAc;CAChB;CACA,MAAM,QAAsB,CAAC,IAAI;CAEjC,MAAM,iBAAuB;EAC3B,MAAM,UAAU,MAAM,IAAI;EAE1B,MADqB,MAAM,SAAS,GAC7B,SAAS,KAAK;GACnB,MAAM;GACN,KAAK,QAAQ;GACb,SAAS,QAAQ;GACjB,SAAS,QAAQ;GACjB,UAAU,QAAQ;EACpB,CAAC;CACH;CAEA,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;EACrC,MAAM,OAAO,MAAM;EAInB,IAAI,SAAS;EACb,OACE,SAAS,MAAM,SAAS,KACxB,SAAS,KAAK,UACd,MAAM,SAAS,GAAI,QAAQ,KAAK,SAEhC;EAIF,OAAO,MAAM,SAAS,IAAI,QACxB,SAAS;EAIX,OAAO,MAAM,SAAS,IAAI,KAAK,QAAQ;GACrC,MAAM,SAAS,MAAM,MAAM,SAAS;GACpC,MAAM,KAAK;IACT,KAAK,KAAK,MAAM,SAAS;IACzB,SAAS,iBAAiB,MAAM;IAChC,SAAS,CAAC;IACV,UAAU,CAAC;IACX,cAAc;GAChB,CAAC;EACH;EAGA,MAAM,MAAM,MAAM,MAAM,SAAS;EACjC,IAAI,SAAS,KAAK;GAChB,MAAM;GACN,OAAO;GACP,SAAS,iBAAiB,GAAG;EAC/B,CAAC;EAGD,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAChC,MAAM,GAAI,QAAQ,KAAK,CAAC;CAE5B;CAGA,OAAO,MAAM,SAAS,GACpB,SAAS;CAGX,OAAO,KAAK;AACd"}
1
+ {"version":3,"file":"groupParts.js","names":[],"sources":["../../../src/react/utils/groupParts.ts"],"sourcesContent":["import { isMcpAppUri } from \"../../types/message\";\nimport type { PartState } from \"../../store/scopes/part\";\n\n/**\n * Hierarchical adjacent-coalescing grouping for message parts.\n *\n * Given a group path per part (from `groupBy`), builds a tree of group\n * nodes wrapping individual parts. Adjacent parts sharing a path prefix\n * coalesce into the same group; ungrouped parts are direct children of\n * the root.\n *\n * Each node gets a structural `nodeKey` built from sibling indices\n * (`\"0.1.0\"`), stable under append-only streaming.\n */\n\n/**\n * Symbol attached to memoizable `groupBy` functions (e.g. those returned\n * by {@link groupPartByType}). Carries a string fingerprint of the config\n * so `MessagePrimitive.GroupedParts` can memo the tree on\n * `[parts, memoKey]` across renders — even when the helper call site\n * reconstructs the function each render.\n */\nexport const GROUPBY_MEMO_KEY: unique symbol = Symbol.for(\n \"@assistant-ui/groupBy.memoKey\",\n);\n\n/**\n * Synthetic part-type key recognized by {@link groupPartByType}: a\n * tool-call whose `mcp.app.resourceUri` points at an assistant-ui MCP\n * app. Map this key to control how MCP-app tool calls are grouped —\n * separately from regular `\"tool-call\"` parts.\n */\ntype GroupPartType = PartState[\"type\"] | \"mcp-app\";\n\n/**\n * Build a `groupBy` from a `part.type → group-key path` lookup.\n * Parts whose type isn't in the map are left ungrouped. The returned\n * function carries a stable {@link GROUPBY_MEMO_KEY} fingerprint so\n * `<MessagePrimitive.GroupedParts>` can memoize its tree across renders.\n *\n * Special key `\"mcp-app\"` matches tool-call parts that point at an\n * assistant-ui MCP app resource (`ui://...`) and takes precedence over\n * the `\"tool-call\"` entry for those parts.\n *\n * @example\n * ```tsx\n * <MessagePrimitive.GroupedParts\n * groupBy={groupPartByType({\n * reasoning: [\"group-thought\", \"group-reasoning\"],\n * \"tool-call\": [\"group-thought\", \"group-tool\"],\n * \"mcp-app\": [],\n * })}\n * >\n * {({ part, children }) => { ... }}\n * </MessagePrimitive.GroupedParts>\n * ```\n */\nexport const groupPartByType = <TKey extends `group-${string}`>(\n map: Partial<Readonly<Record<GroupPartType, readonly TKey[]>>>,\n): ((part: PartState) => readonly TKey[]) => {\n const lookup = map as Readonly<Record<string, readonly TKey[] | undefined>>;\n const fn = ((part) => {\n if (\n part.type === \"tool-call\" &&\n lookup[\"mcp-app\"] !== undefined &&\n isMcpAppUri(part.mcp?.app?.resourceUri)\n ) {\n return lookup[\"mcp-app\"]!;\n }\n return lookup[part.type] ?? [];\n }) as ((part: PartState) => readonly TKey[]) & {\n [GROUPBY_MEMO_KEY]?: string;\n };\n // Sort keys so the fingerprint is insensitive to map insertion order —\n // two maps with the same key/value pairs but different declaration order\n // would otherwise hash differently and invalidate the memo unnecessarily.\n const sortedKeys = Object.keys(map).sort();\n const sortedEntries = sortedKeys.map((k) => [k, map[k as keyof typeof map]]);\n fn[GROUPBY_MEMO_KEY] = `groupPartByType:${JSON.stringify(sortedEntries)}`;\n return fn;\n};\n\nexport type GroupNode = GroupNodeGroup | GroupNodePart;\n\nexport interface GroupNodeGroup {\n readonly type: \"group\";\n /** Current-level group key (last segment of the path). */\n readonly key: string;\n /** Structural React key: sibling-index path, e.g. `\"0.1.0\"`. */\n readonly nodeKey: string;\n /** Indices of parts in this subtree, in order. */\n readonly indices: readonly number[];\n readonly children: readonly GroupNode[];\n}\n\nexport interface GroupNodePart {\n readonly type: \"part\";\n /** Index of the part in the message. */\n readonly index: number;\n /** Structural React key: sibling-index path within parent. */\n readonly nodeKey: string;\n}\n\ninterface BuildFrame {\n key: string;\n nodeKey: string;\n indices: number[];\n children: GroupNode[];\n nextChildIdx: number;\n}\n\nconst makeChildNodeKey = (parent: BuildFrame): string => {\n const idx = parent.nextChildIdx++;\n return parent.nodeKey === \"\" ? String(idx) : `${parent.nodeKey}.${idx}`;\n};\n\n/**\n * Build the group tree from an array of normalized group paths.\n * `paths[i]` is the path for part `i`. The output tree contains one\n * `part` node per part and one `group` node per coalesced run.\n */\nexport const buildGroupTree = (\n paths: readonly (readonly string[])[],\n): readonly GroupNode[] => {\n const root: BuildFrame = {\n key: \"\",\n nodeKey: \"\",\n indices: [],\n children: [],\n nextChildIdx: 0,\n };\n const stack: BuildFrame[] = [root];\n\n const closeTop = (): void => {\n const closing = stack.pop()!;\n const parent = stack[stack.length - 1]!;\n parent.children.push({\n type: \"group\",\n key: closing.key,\n nodeKey: closing.nodeKey,\n indices: closing.indices,\n children: closing.children,\n });\n };\n\n for (let i = 0; i < paths.length; i++) {\n const path = paths[i]!;\n\n // Find the longest prefix shared between currently-open groups\n // (excluding root) and this part's path.\n let common = 0;\n while (\n common < stack.length - 1 &&\n common < path.length &&\n stack[common + 1]!.key === path[common]\n ) {\n common++;\n }\n\n // Close groups not on this path.\n while (stack.length - 1 > common) {\n closeTop();\n }\n\n // Open new groups down to the part's depth.\n while (stack.length - 1 < path.length) {\n const parent = stack[stack.length - 1]!;\n stack.push({\n key: path[stack.length - 1]!,\n nodeKey: makeChildNodeKey(parent),\n indices: [],\n children: [],\n nextChildIdx: 0,\n });\n }\n\n // Push this part as a leaf in the deepest open group (or root).\n const top = stack[stack.length - 1]!;\n top.children.push({\n type: \"part\",\n index: i,\n nodeKey: makeChildNodeKey(top),\n });\n\n // Record the part index in every open ancestor group.\n for (let s = 1; s < stack.length; s++) {\n stack[s]!.indices.push(i);\n }\n }\n\n // Close any still-open groups.\n while (stack.length > 1) {\n closeTop();\n }\n\n return root.children;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAsBA,MAAa,mBAAkC,OAAO,IACpD,+BACF;;;;;;;;;;;;;;;;;;;;;;;;AAiCA,MAAa,mBACX,QAC2C;CAC3C,MAAM,SAAS;CACf,MAAM,OAAO,SAAS;EACpB,IACE,KAAK,SAAS,eACd,OAAO,eAAe,KAAA,KACtB,YAAY,KAAK,KAAK,KAAK,WAAW,GAEtC,OAAO,OAAO;EAEhB,OAAO,OAAO,KAAK,SAAS,CAAC;CAC/B;CAOA,MAAM,gBADa,OAAO,KAAK,GAAG,EAAE,KACL,EAAE,KAAK,MAAM,CAAC,GAAG,IAAI,EAAsB,CAAC;CAC3E,GAAG,oBAAoB,mBAAmB,KAAK,UAAU,aAAa;CACtE,OAAO;AACT;AA+BA,MAAM,oBAAoB,WAA+B;CACvD,MAAM,MAAM,OAAO;CACnB,OAAO,OAAO,YAAY,KAAK,OAAO,GAAG,IAAI,GAAG,OAAO,QAAQ,GAAG;AACpE;;;;;;AAOA,MAAa,kBACX,UACyB;CACzB,MAAM,OAAmB;EACvB,KAAK;EACL,SAAS;EACT,SAAS,CAAC;EACV,UAAU,CAAC;EACX,cAAc;CAChB;CACA,MAAM,QAAsB,CAAC,IAAI;CAEjC,MAAM,iBAAuB;EAC3B,MAAM,UAAU,MAAM,IAAI;EAE1B,MADqB,MAAM,SAAS,GAC7B,SAAS,KAAK;GACnB,MAAM;GACN,KAAK,QAAQ;GACb,SAAS,QAAQ;GACjB,SAAS,QAAQ;GACjB,UAAU,QAAQ;EACpB,CAAC;CACH;CAEA,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;EACrC,MAAM,OAAO,MAAM;EAInB,IAAI,SAAS;EACb,OACE,SAAS,MAAM,SAAS,KACxB,SAAS,KAAK,UACd,MAAM,SAAS,GAAI,QAAQ,KAAK,SAEhC;EAIF,OAAO,MAAM,SAAS,IAAI,QACxB,SAAS;EAIX,OAAO,MAAM,SAAS,IAAI,KAAK,QAAQ;GACrC,MAAM,SAAS,MAAM,MAAM,SAAS;GACpC,MAAM,KAAK;IACT,KAAK,KAAK,MAAM,SAAS;IACzB,SAAS,iBAAiB,MAAM;IAChC,SAAS,CAAC;IACV,UAAU,CAAC;IACX,cAAc;GAChB,CAAC;EACH;EAGA,MAAM,MAAM,MAAM,MAAM,SAAS;EACjC,IAAI,SAAS,KAAK;GAChB,MAAM;GACN,OAAO;GACP,SAAS,iBAAiB,GAAG;EAC/B,CAAC;EAGD,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAChC,MAAM,GAAI,QAAQ,KAAK,CAAC;CAE5B;CAGA,OAAO,MAAM,SAAS,GACpB,SAAS;CAGX,OAAO,KAAK;AACd"}
@@ -1 +1 @@
1
- {"version":3,"file":"attachment-runtime.d.ts","names":[],"sources":["../../../src/runtime/api/attachment-runtime.ts"],"mappings":";;;;;;;KAOK,sBAAA,GAAyB,kBAAkB;EAAA,SACrC,MAAM;AAAA;AAAA,KAGZ,6BAAA,GAAgC,UAAU;EAAA,SACpC,MAAM;AAAA;AAAA,KAGZ,2BAAA,GAA8B,UAAU;EAAA,SAClC,MAAM;AAAA;AAAA,KAGL,eAAA,GACR,6BAAA,GACA,2BAAA,GACA,sBAAA;AAAA,KAEC,yBAAA,gBAAyC,uBAAA,IAC5C,qBAAA,CACE,eAAA;EAAoB,MAAA,EAAQ,MAAA;AAAA,GAC5B,qBAAA;EAA0B,gBAAA,EAAkB,MAAA;AAAA;AAAA,KAG3C,uBAAA,GAA0B,eAAe;AAAA,KAElC,iBAAA,iBACM,uBAAA,GAA0B,uBAAA;EAAA,SAEjC,IAAA,EAAM,qBAAA;IAA0B,gBAAA,EAAkB,OAAA;EAAA;EAAA,SAClD,MAAA,EAAQ,OAAA;EACjB,QAAA,IAAY,eAAA;IAAoB,MAAA,EAAQ,OAAA;EAAA;EACxC,MAAA,IAAU,OAAA;EACV,SAAA,CAAU,QAAA,eAAuB,WAAA;AAAA;AAAA,uBAGb,qBAAA,gBACL,uBAAA,GAA0B,uBAAA,aAC9B,iBAAA;EAAA,QAQS,KAAA;EAAA,IANT,IAAA,CAAA,GAAI,qBAAA;;;eAIK,MAAA,CAAA,GAAU,MAAA;cAEV,KAAA,EAAO,yBAAA,CAA0B,MAAA;EAAA,UAI3C,sBAAA,CAAA;EAMH,QAAA,CAAA,GAAY,eAAA;IAAoB,MAAA,EAAQ,MAAA;EAAA;EAAA,SAI/B,MAAA,CAAA,GAAU,OAAA;EAEnB,SAAA,CAAU,QAAA,eAAoB,WAAA;AAAA;AAAA,uBAKxB,yBAAA,6DAEL,qBAAA,CAAsB,MAAA;EAAA,QAGpB,YAAA;cADR,IAAA,EAAM,yBAAA,CAA0B,MAAA,GACxB,YAAA,EAAc,0BAAA;EAKjB,MAAA,CAAA,GAAM,OAAA;AAAA;AAAA,cAOF,mCAAA,SAA4C,yBAAyB;EAAA,IACrE,MAAM,CAAA;AAAA;AAAA,cAKN,iCAAA,SAA0C,yBAAyB;EAAA,IACnE,MAAM,CAAA;AAAA;AAAA,cAKN,4BAAA,SAAqC,qBAAqB;EAAA,IAC1D,MAAA,CAAA;EAIJ,MAAA,CAAA;AAAA"}
1
+ {"version":3,"file":"attachment-runtime.d.ts","names":[],"sources":["../../../src/runtime/api/attachment-runtime.ts"],"mappings":";;;;;;;KAOK,sBAAA,GAAyB,kBAAkB;EAAA,SACrC,MAAM;AAAA;AAAA,KAGZ,6BAAA,GAAgC,UAAU;EAAA,SACpC,MAAM;AAAA;AAAA,KAGZ,2BAAA,GAA8B,UAAU;EAAA,SAClC,MAAM;AAAA;AAAA,KAGL,eAAA,GACR,6BAAA,GACA,2BAAA,GACA,sBAAA;AAAA,KAEC,yBAAA,gBAAyC,uBAAA,IAC5C,qBAAA,CACE,eAAA;EAAoB,MAAA,EAAQ,MAAA;AAAA,GAC5B,qBAAA;EAA0B,gBAAA,EAAkB,MAAA;AAAA;AAAA,KAG3C,uBAAA,GAA0B,eAAe;AAAA,KAElC,iBAAA,iBACM,uBAAA,GAA0B,uBAAA;EAAA,SAEjC,IAAA,EAAM,qBAAA;IAA0B,gBAAA,EAAkB,OAAA;EAAA;EAAA,SAClD,MAAA,EAAQ,OAAA;EACjB,QAAA,IAAY,eAAA;IAAoB,MAAA,EAAQ,OAAA;EAAA;EACxC,MAAA,IAAU,OAAA;EACV,SAAA,CAAU,QAAA,eAAuB,WAAA;AAAA;AAAA,uBAGb,qBAAA,gBACL,uBAAA,GAA0B,uBAAA,aAC9B,iBAAA;EAAA,QAOS,KAAA;EAAA,IANT,IAAA,CAAA,GAAI,qBAAA;;;eAIK,MAAA,CAAA,GAAU,MAAA;cAEV,KAAA,EAAO,yBAAA,CAA0B,MAAA;EAAA,UAI3C,sBAAA,CAAA;EAMH,QAAA,CAAA,GAAY,eAAA;IAAoB,MAAA,EAAQ,MAAA;EAAA;EAAA,SAI/B,MAAA,CAAA,GAAU,OAAA;EAEnB,SAAA,CAAU,QAAA,eAAoB,WAAA;AAAA;AAAA,uBAKxB,yBAAA,6DAEL,qBAAA,CAAsB,MAAA;EAAA,QAGpB,YAAA;cADR,IAAA,EAAM,yBAAA,CAA0B,MAAA,GACxB,YAAA,EAAc,0BAAA;EAKjB,MAAA,CAAA,GAAM,OAAA;AAAA;AAAA,cAOF,mCAAA,SAA4C,yBAAyB;EAAA,IACrE,MAAM,CAAA;AAAA;AAAA,cAKN,iCAAA,SAA0C,yBAAyB;EAAA,IACnE,MAAM,CAAA;AAAA;AAAA,cAKN,4BAAA,SAAqC,qBAAqB;EAAA,IAC1D,MAAA,CAAA;EAIJ,MAAA,CAAA;AAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"attachment-runtime.js","names":[],"sources":["../../../src/runtime/api/attachment-runtime.ts"],"sourcesContent":["import type { Attachment, CompleteAttachment } from \"../../types/attachment\";\nimport type { Unsubscribe } from \"../../types/unsubscribe\";\nimport type { SubscribableWithState } from \"../../subscribable/subscribable\";\n\nimport type { ComposerRuntimeCoreBinding } from \"./bindings\";\nimport type { AttachmentRuntimePath } from \"./paths\";\n\ntype MessageAttachmentState = CompleteAttachment & {\n readonly source: \"message\";\n};\n\ntype ThreadComposerAttachmentState = Attachment & {\n readonly source: \"thread-composer\";\n};\n\ntype EditComposerAttachmentState = Attachment & {\n readonly source: \"edit-composer\";\n};\n\nexport type AttachmentState =\n | ThreadComposerAttachmentState\n | EditComposerAttachmentState\n | MessageAttachmentState;\n\ntype AttachmentSnapshotBinding<Source extends AttachmentRuntimeSource> =\n SubscribableWithState<\n AttachmentState & { source: Source },\n AttachmentRuntimePath & { attachmentSource: Source }\n >;\n\ntype AttachmentRuntimeSource = AttachmentState[\"source\"];\n\nexport type AttachmentRuntime<\n TSource extends AttachmentRuntimeSource = AttachmentRuntimeSource,\n> = {\n readonly path: AttachmentRuntimePath & { attachmentSource: TSource };\n readonly source: TSource;\n getState(): AttachmentState & { source: TSource };\n remove(): Promise<void>;\n subscribe(callback: () => void): Unsubscribe;\n};\n\nexport abstract class AttachmentRuntimeImpl<\n Source extends AttachmentRuntimeSource = AttachmentRuntimeSource,\n> implements AttachmentRuntime\n{\n public get path() {\n return this._core.path;\n }\n\n public abstract get source(): Source;\n\n constructor(private _core: AttachmentSnapshotBinding<Source>) {\n this.__internal_bindMethods();\n }\n\n protected __internal_bindMethods() {\n this.getState = this.getState.bind(this);\n this.remove = this.remove.bind(this);\n this.subscribe = this.subscribe.bind(this);\n }\n\n public getState(): AttachmentState & { source: Source } {\n return this._core.getState();\n }\n\n public abstract remove(): Promise<void>;\n\n public subscribe(callback: () => void) {\n return this._core.subscribe(callback);\n }\n}\n\nabstract class ComposerAttachmentRuntime<\n Source extends \"thread-composer\" | \"edit-composer\",\n> extends AttachmentRuntimeImpl<Source> {\n constructor(\n core: AttachmentSnapshotBinding<Source>,\n private _composerApi: ComposerRuntimeCoreBinding,\n ) {\n super(core);\n }\n\n public remove() {\n const core = this._composerApi.getState();\n if (!core) throw new Error(\"Composer is not available\");\n return core.removeAttachment(this.getState().id);\n }\n}\n\nexport class ThreadComposerAttachmentRuntimeImpl extends ComposerAttachmentRuntime<\"thread-composer\"> {\n public get source(): \"thread-composer\" {\n return \"thread-composer\";\n }\n}\n\nexport class EditComposerAttachmentRuntimeImpl extends ComposerAttachmentRuntime<\"edit-composer\"> {\n public get source(): \"edit-composer\" {\n return \"edit-composer\";\n }\n}\n\nexport class MessageAttachmentRuntimeImpl extends AttachmentRuntimeImpl<\"message\"> {\n public get source(): \"message\" {\n return \"message\";\n }\n\n public remove(): never {\n throw new Error(\"Message attachments cannot be removed\");\n }\n}\n"],"mappings":";AA0CA,IAAsB,wBAAtB,MAGA;CAOsB;CANpB,IAAW,OAAO;EAChB,OAAO,KAAK,MAAM;CACpB;CAIA,YAAY,OAAkD;EAA1C,KAAA,QAAA;EAClB,KAAK,uBAAuB;CAC9B;CAEA,yBAAmC;EACjC,KAAK,WAAW,KAAK,SAAS,KAAK,IAAI;EACvC,KAAK,SAAS,KAAK,OAAO,KAAK,IAAI;EACnC,KAAK,YAAY,KAAK,UAAU,KAAK,IAAI;CAC3C;CAEA,WAAwD;EACtD,OAAO,KAAK,MAAM,SAAS;CAC7B;CAIA,UAAiB,UAAsB;EACrC,OAAO,KAAK,MAAM,UAAU,QAAQ;CACtC;AACF;AAEA,IAAe,4BAAf,cAEU,sBAA8B;CAG5B;CAFV,YACE,MACA,cACA;EACA,MAAM,IAAI;EAFF,KAAA,eAAA;CAGV;CAEA,SAAgB;EACd,MAAM,OAAO,KAAK,aAAa,SAAS;EACxC,IAAI,CAAC,MAAM,MAAM,IAAI,MAAM,2BAA2B;EACtD,OAAO,KAAK,iBAAiB,KAAK,SAAS,EAAE,EAAE;CACjD;AACF;AAEA,IAAa,sCAAb,cAAyD,0BAA6C;CACpG,IAAW,SAA4B;EACrC,OAAO;CACT;AACF;AAEA,IAAa,oCAAb,cAAuD,0BAA2C;CAChG,IAAW,SAA0B;EACnC,OAAO;CACT;AACF;AAEA,IAAa,+BAAb,cAAkD,sBAAiC;CACjF,IAAW,SAAoB;EAC7B,OAAO;CACT;CAEA,SAAuB;EACrB,MAAM,IAAI,MAAM,uCAAuC;CACzD;AACF"}
1
+ {"version":3,"file":"attachment-runtime.js","names":[],"sources":["../../../src/runtime/api/attachment-runtime.ts"],"sourcesContent":["import type { Attachment, CompleteAttachment } from \"../../types/attachment\";\nimport type { Unsubscribe } from \"../../types/unsubscribe\";\nimport type { SubscribableWithState } from \"../../subscribable/subscribable\";\n\nimport type { ComposerRuntimeCoreBinding } from \"./bindings\";\nimport type { AttachmentRuntimePath } from \"./paths\";\n\ntype MessageAttachmentState = CompleteAttachment & {\n readonly source: \"message\";\n};\n\ntype ThreadComposerAttachmentState = Attachment & {\n readonly source: \"thread-composer\";\n};\n\ntype EditComposerAttachmentState = Attachment & {\n readonly source: \"edit-composer\";\n};\n\nexport type AttachmentState =\n | ThreadComposerAttachmentState\n | EditComposerAttachmentState\n | MessageAttachmentState;\n\ntype AttachmentSnapshotBinding<Source extends AttachmentRuntimeSource> =\n SubscribableWithState<\n AttachmentState & { source: Source },\n AttachmentRuntimePath & { attachmentSource: Source }\n >;\n\ntype AttachmentRuntimeSource = AttachmentState[\"source\"];\n\nexport type AttachmentRuntime<\n TSource extends AttachmentRuntimeSource = AttachmentRuntimeSource,\n> = {\n readonly path: AttachmentRuntimePath & { attachmentSource: TSource };\n readonly source: TSource;\n getState(): AttachmentState & { source: TSource };\n remove(): Promise<void>;\n subscribe(callback: () => void): Unsubscribe;\n};\n\nexport abstract class AttachmentRuntimeImpl<\n Source extends AttachmentRuntimeSource = AttachmentRuntimeSource,\n> implements AttachmentRuntime {\n public get path() {\n return this._core.path;\n }\n\n public abstract get source(): Source;\n\n constructor(private _core: AttachmentSnapshotBinding<Source>) {\n this.__internal_bindMethods();\n }\n\n protected __internal_bindMethods() {\n this.getState = this.getState.bind(this);\n this.remove = this.remove.bind(this);\n this.subscribe = this.subscribe.bind(this);\n }\n\n public getState(): AttachmentState & { source: Source } {\n return this._core.getState();\n }\n\n public abstract remove(): Promise<void>;\n\n public subscribe(callback: () => void) {\n return this._core.subscribe(callback);\n }\n}\n\nabstract class ComposerAttachmentRuntime<\n Source extends \"thread-composer\" | \"edit-composer\",\n> extends AttachmentRuntimeImpl<Source> {\n constructor(\n core: AttachmentSnapshotBinding<Source>,\n private _composerApi: ComposerRuntimeCoreBinding,\n ) {\n super(core);\n }\n\n public remove() {\n const core = this._composerApi.getState();\n if (!core) throw new Error(\"Composer is not available\");\n return core.removeAttachment(this.getState().id);\n }\n}\n\nexport class ThreadComposerAttachmentRuntimeImpl extends ComposerAttachmentRuntime<\"thread-composer\"> {\n public get source(): \"thread-composer\" {\n return \"thread-composer\";\n }\n}\n\nexport class EditComposerAttachmentRuntimeImpl extends ComposerAttachmentRuntime<\"edit-composer\"> {\n public get source(): \"edit-composer\" {\n return \"edit-composer\";\n }\n}\n\nexport class MessageAttachmentRuntimeImpl extends AttachmentRuntimeImpl<\"message\"> {\n public get source(): \"message\" {\n return \"message\";\n }\n\n public remove(): never {\n throw new Error(\"Message attachments cannot be removed\");\n }\n}\n"],"mappings":";AA0CA,IAAsB,wBAAtB,MAE+B;CAOT;CANpB,IAAW,OAAO;EAChB,OAAO,KAAK,MAAM;CACpB;CAIA,YAAY,OAAkD;EAA1C,KAAA,QAAA;EAClB,KAAK,uBAAuB;CAC9B;CAEA,yBAAmC;EACjC,KAAK,WAAW,KAAK,SAAS,KAAK,IAAI;EACvC,KAAK,SAAS,KAAK,OAAO,KAAK,IAAI;EACnC,KAAK,YAAY,KAAK,UAAU,KAAK,IAAI;CAC3C;CAEA,WAAwD;EACtD,OAAO,KAAK,MAAM,SAAS;CAC7B;CAIA,UAAiB,UAAsB;EACrC,OAAO,KAAK,MAAM,UAAU,QAAQ;CACtC;AACF;AAEA,IAAe,4BAAf,cAEU,sBAA8B;CAG5B;CAFV,YACE,MACA,cACA;EACA,MAAM,IAAI;EAFF,KAAA,eAAA;CAGV;CAEA,SAAgB;EACd,MAAM,OAAO,KAAK,aAAa,SAAS;EACxC,IAAI,CAAC,MAAM,MAAM,IAAI,MAAM,2BAA2B;EACtD,OAAO,KAAK,iBAAiB,KAAK,SAAS,EAAE,EAAE;CACjD;AACF;AAEA,IAAa,sCAAb,cAAyD,0BAA6C;CACpG,IAAW,SAA4B;EACrC,OAAO;CACT;AACF;AAEA,IAAa,oCAAb,cAAuD,0BAA2C;CAChG,IAAW,SAA0B;EACnC,OAAO;CACT;AACF;AAEA,IAAa,+BAAb,cAAkD,sBAAiC;CACjF,IAAW,SAAoB;EAC7B,OAAO;CACT;CAEA,SAAuB;EACrB,MAAM,IAAI,MAAM,uCAAuC;CACzD;AACF"}
@@ -14,6 +14,10 @@ type MessagePartSnapshotBinding = SubscribableWithState<MessagePartState, Messag
14
14
  type MessagePartRuntime = {
15
15
  addToolResult(result: any | ToolResponse<any>): void;
16
16
  resumeToolCall(payload: unknown): void;
17
+ respondToToolApproval(response: {
18
+ approved: boolean;
19
+ reason?: string;
20
+ }): void;
17
21
  readonly path: MessagePartRuntimePath;
18
22
  getState(): MessagePartState;
19
23
  subscribe(callback: () => void): Unsubscribe;
@@ -28,6 +32,10 @@ declare class MessagePartRuntimeImpl implements MessagePartRuntime {
28
32
  getState(): MessagePartState;
29
33
  addToolResult(result: any | ToolResponse<any>): void;
30
34
  resumeToolCall(payload: unknown): void;
35
+ respondToToolApproval(response: {
36
+ approved: boolean;
37
+ reason?: string;
38
+ }): void;
31
39
  subscribe(callback: () => void): Unsubscribe;
32
40
  }
33
41
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"message-part-runtime.d.ts","names":[],"sources":["../../../src/runtime/api/message-part-runtime.ts"],"mappings":";;;;;;;;;KAaY,gBAAA,IACR,qBAAA,GACA,0BAAA;EAAA,SAEO,MAAA,EAAQ,iBAAA,GAAoB,yBAAA;AAAA;AAAA,KAGlC,0BAAA,GAA6B,qBAAA,CAChC,gBAAA,EACA,sBAAA;AAAA,KAGU,kBAAA;EACV,aAAA,CAAc,MAAA,QAAc,YAAA;EAC5B,cAAA,CAAe,OAAA;EAAA,SAEN,IAAA,EAAM,sBAAA;EACf,QAAA,IAAY,gBAAA;EACZ,SAAA,CAAU,QAAA,eAAuB,WAAA;AAAA;AAAA,cAGtB,sBAAA,YAAkC,kBAAA;EAAA,QAMnC,cAAA;EAAA,QACA,UAAA;EAAA,QACA,SAAA;EAAA,IAPC,IAAA,CAAA,GAAI,sBAAA;cAKL,cAAA,EAAgB,0BAAA,EAChB,UAAA,GAAa,mBAAA,cACb,SAAA,GAAY,wBAAA;EAAA,UAKZ,sBAAA,CAAA;EAOH,QAAA,CAAA,GAAQ,gBAAA;EAIR,aAAA,CAAc,MAAA,QAAc,YAAA;EA8B5B,cAAA,CAAe,OAAA;EAgBf,SAAA,CAAU,QAAA,eAAoB,WAAA;AAAA"}
1
+ {"version":3,"file":"message-part-runtime.d.ts","names":[],"sources":["../../../src/runtime/api/message-part-runtime.ts"],"mappings":";;;;;;;;;KAaY,gBAAA,IACR,qBAAA,GACA,0BAAA;EAAA,SAEO,MAAA,EAAQ,iBAAA,GAAoB,yBAAA;AAAA;AAAA,KAGlC,0BAAA,GAA6B,qBAAA,CAChC,gBAAA,EACA,sBAAA;AAAA,KAGU,kBAAA;EACV,aAAA,CAAc,MAAA,QAAc,YAAA;EAC5B,cAAA,CAAe,OAAA;EACf,qBAAA,CAAsB,QAAA;IAAY,QAAA;IAAmB,MAAA;EAAA;EAAA,SAE5C,IAAA,EAAM,sBAAA;EACf,QAAA,IAAY,gBAAA;EACZ,SAAA,CAAU,QAAA,eAAuB,WAAA;AAAA;AAAA,cAGtB,sBAAA,YAAkC,kBAAA;EAAA,QAMnC,cAAA;EAAA,QACA,UAAA;EAAA,QACA,SAAA;EAAA,IAPC,IAAA,CAAA,GAAI,sBAAA;cAKL,cAAA,EAAgB,0BAAA,EAChB,UAAA,GAAa,mBAAA,cACb,SAAA,GAAY,wBAAA;EAAA,UAKZ,sBAAA,CAAA;EAQH,QAAA,CAAA,GAAQ,gBAAA;EAIR,aAAA,CAAc,MAAA,QAAc,YAAA;EA8B5B,cAAA,CAAe,OAAA;EAgBf,qBAAA,CAAsB,QAAA;IAC3B,QAAA;IACA,MAAA;EAAA;EAsBK,SAAA,CAAU,QAAA,eAAoB,WAAA;AAAA"}
@@ -16,6 +16,7 @@ var MessagePartRuntimeImpl = class {
16
16
  __internal_bindMethods() {
17
17
  this.addToolResult = this.addToolResult.bind(this);
18
18
  this.resumeToolCall = this.resumeToolCall.bind(this);
19
+ this.respondToToolApproval = this.respondToToolApproval.bind(this);
19
20
  this.getState = this.getState.bind(this);
20
21
  this.subscribe = this.subscribe.bind(this);
21
22
  }
@@ -53,6 +54,18 @@ var MessagePartRuntimeImpl = class {
53
54
  payload
54
55
  });
55
56
  }
57
+ respondToToolApproval(response) {
58
+ const state = this.contentBinding.getState();
59
+ if (!state) throw new Error("Message part is not available");
60
+ if (state.type !== "tool-call") throw new Error("Tried to respond to tool approval on non-tool message part");
61
+ if (!state.approval || state.approval.approved !== void 0) throw new Error("Tool call has no pending approval");
62
+ if (!this.threadApi) throw new Error("Thread API is not available");
63
+ this.threadApi.getState().respondToToolApproval({
64
+ approvalId: state.approval.id,
65
+ approved: response.approved,
66
+ ...response.reason != null && { reason: response.reason }
67
+ });
68
+ }
56
69
  subscribe(callback) {
57
70
  return this.contentBinding.subscribe(callback);
58
71
  }
@@ -1 +1 @@
1
- {"version":3,"file":"message-part-runtime.js","names":[],"sources":["../../../src/runtime/api/message-part-runtime.ts"],"sourcesContent":["import type {\n ThreadAssistantMessagePart,\n ThreadUserMessagePart,\n ToolCallMessagePartStatus,\n} from \"../../types/message\";\nimport type { Unsubscribe } from \"../../types/unsubscribe\";\nimport type { MessagePartStatus } from \"../../types/message\";\nimport type { SubscribableWithState } from \"../../subscribable/subscribable\";\nimport type { ThreadRuntimeCoreBinding } from \"./thread-runtime\";\nimport type { MessageStateBinding } from \"./bindings\";\nimport type { MessagePartRuntimePath } from \"./paths\";\nimport { ToolResponse } from \"assistant-stream\";\n\nexport type MessagePartState = (\n | ThreadUserMessagePart\n | ThreadAssistantMessagePart\n) & {\n readonly status: MessagePartStatus | ToolCallMessagePartStatus;\n};\n\ntype MessagePartSnapshotBinding = SubscribableWithState<\n MessagePartState,\n MessagePartRuntimePath\n>;\n\nexport type MessagePartRuntime = {\n addToolResult(result: any | ToolResponse<any>): void;\n resumeToolCall(payload: unknown): void;\n\n readonly path: MessagePartRuntimePath;\n getState(): MessagePartState;\n subscribe(callback: () => void): Unsubscribe;\n};\n\nexport class MessagePartRuntimeImpl implements MessagePartRuntime {\n public get path() {\n return this.contentBinding.path;\n }\n\n constructor(\n private contentBinding: MessagePartSnapshotBinding,\n private messageApi?: MessageStateBinding,\n private threadApi?: ThreadRuntimeCoreBinding,\n ) {\n this.__internal_bindMethods();\n }\n\n protected __internal_bindMethods() {\n this.addToolResult = this.addToolResult.bind(this);\n this.resumeToolCall = this.resumeToolCall.bind(this);\n this.getState = this.getState.bind(this);\n this.subscribe = this.subscribe.bind(this);\n }\n\n public getState() {\n return this.contentBinding.getState();\n }\n\n public addToolResult(result: any | ToolResponse<any>) {\n const state = this.contentBinding.getState();\n if (!state) throw new Error(\"Message part is not available\");\n\n if (state.type !== \"tool-call\")\n throw new Error(\"Tried to add tool result to non-tool message part\");\n\n if (!this.messageApi)\n throw new Error(\n \"Message API is not available. This is likely a bug in assistant-ui.\",\n );\n if (!this.threadApi) throw new Error(\"Thread API is not available\");\n\n const message = this.messageApi.getState();\n if (!message) throw new Error(\"Message is not available\");\n\n const toolName = state.toolName;\n const toolCallId = state.toolCallId;\n\n const response = ToolResponse.toResponse(result);\n this.threadApi.getState().addToolResult({\n messageId: message.id,\n toolName,\n toolCallId,\n result: response.result,\n artifact: response.artifact,\n isError: response.isError,\n });\n }\n\n public resumeToolCall(payload: unknown) {\n const state = this.contentBinding.getState();\n if (!state) throw new Error(\"Message part is not available\");\n\n if (state.type !== \"tool-call\")\n throw new Error(\"Tried to resume tool call on non-tool message part\");\n\n if (!this.threadApi) throw new Error(\"Thread API is not available\");\n\n const toolCallId = state.toolCallId;\n this.threadApi.getState().resumeToolCall({\n toolCallId,\n payload,\n });\n }\n\n public subscribe(callback: () => void) {\n return this.contentBinding.subscribe(callback);\n }\n}\n"],"mappings":";;AAkCA,IAAa,yBAAb,MAAkE;CAMtD;CACA;CACA;CAPV,IAAW,OAAO;EAChB,OAAO,KAAK,eAAe;CAC7B;CAEA,YACE,gBACA,YACA,WACA;EAHQ,KAAA,iBAAA;EACA,KAAA,aAAA;EACA,KAAA,YAAA;EAER,KAAK,uBAAuB;CAC9B;CAEA,yBAAmC;EACjC,KAAK,gBAAgB,KAAK,cAAc,KAAK,IAAI;EACjD,KAAK,iBAAiB,KAAK,eAAe,KAAK,IAAI;EACnD,KAAK,WAAW,KAAK,SAAS,KAAK,IAAI;EACvC,KAAK,YAAY,KAAK,UAAU,KAAK,IAAI;CAC3C;CAEA,WAAkB;EAChB,OAAO,KAAK,eAAe,SAAS;CACtC;CAEA,cAAqB,QAAiC;EACpD,MAAM,QAAQ,KAAK,eAAe,SAAS;EAC3C,IAAI,CAAC,OAAO,MAAM,IAAI,MAAM,+BAA+B;EAE3D,IAAI,MAAM,SAAS,aACjB,MAAM,IAAI,MAAM,mDAAmD;EAErE,IAAI,CAAC,KAAK,YACR,MAAM,IAAI,MACR,qEACF;EACF,IAAI,CAAC,KAAK,WAAW,MAAM,IAAI,MAAM,6BAA6B;EAElE,MAAM,UAAU,KAAK,WAAW,SAAS;EACzC,IAAI,CAAC,SAAS,MAAM,IAAI,MAAM,0BAA0B;EAExD,MAAM,WAAW,MAAM;EACvB,MAAM,aAAa,MAAM;EAEzB,MAAM,WAAW,aAAa,WAAW,MAAM;EAC/C,KAAK,UAAU,SAAS,EAAE,cAAc;GACtC,WAAW,QAAQ;GACnB;GACA;GACA,QAAQ,SAAS;GACjB,UAAU,SAAS;GACnB,SAAS,SAAS;EACpB,CAAC;CACH;CAEA,eAAsB,SAAkB;EACtC,MAAM,QAAQ,KAAK,eAAe,SAAS;EAC3C,IAAI,CAAC,OAAO,MAAM,IAAI,MAAM,+BAA+B;EAE3D,IAAI,MAAM,SAAS,aACjB,MAAM,IAAI,MAAM,oDAAoD;EAEtE,IAAI,CAAC,KAAK,WAAW,MAAM,IAAI,MAAM,6BAA6B;EAElE,MAAM,aAAa,MAAM;EACzB,KAAK,UAAU,SAAS,EAAE,eAAe;GACvC;GACA;EACF,CAAC;CACH;CAEA,UAAiB,UAAsB;EACrC,OAAO,KAAK,eAAe,UAAU,QAAQ;CAC/C;AACF"}
1
+ {"version":3,"file":"message-part-runtime.js","names":[],"sources":["../../../src/runtime/api/message-part-runtime.ts"],"sourcesContent":["import type {\n ThreadAssistantMessagePart,\n ThreadUserMessagePart,\n ToolCallMessagePartStatus,\n} from \"../../types/message\";\nimport type { Unsubscribe } from \"../../types/unsubscribe\";\nimport type { MessagePartStatus } from \"../../types/message\";\nimport type { SubscribableWithState } from \"../../subscribable/subscribable\";\nimport type { ThreadRuntimeCoreBinding } from \"./thread-runtime\";\nimport type { MessageStateBinding } from \"./bindings\";\nimport type { MessagePartRuntimePath } from \"./paths\";\nimport { ToolResponse } from \"assistant-stream\";\n\nexport type MessagePartState = (\n | ThreadUserMessagePart\n | ThreadAssistantMessagePart\n) & {\n readonly status: MessagePartStatus | ToolCallMessagePartStatus;\n};\n\ntype MessagePartSnapshotBinding = SubscribableWithState<\n MessagePartState,\n MessagePartRuntimePath\n>;\n\nexport type MessagePartRuntime = {\n addToolResult(result: any | ToolResponse<any>): void;\n resumeToolCall(payload: unknown): void;\n respondToToolApproval(response: { approved: boolean; reason?: string }): void;\n\n readonly path: MessagePartRuntimePath;\n getState(): MessagePartState;\n subscribe(callback: () => void): Unsubscribe;\n};\n\nexport class MessagePartRuntimeImpl implements MessagePartRuntime {\n public get path() {\n return this.contentBinding.path;\n }\n\n constructor(\n private contentBinding: MessagePartSnapshotBinding,\n private messageApi?: MessageStateBinding,\n private threadApi?: ThreadRuntimeCoreBinding,\n ) {\n this.__internal_bindMethods();\n }\n\n protected __internal_bindMethods() {\n this.addToolResult = this.addToolResult.bind(this);\n this.resumeToolCall = this.resumeToolCall.bind(this);\n this.respondToToolApproval = this.respondToToolApproval.bind(this);\n this.getState = this.getState.bind(this);\n this.subscribe = this.subscribe.bind(this);\n }\n\n public getState() {\n return this.contentBinding.getState();\n }\n\n public addToolResult(result: any | ToolResponse<any>) {\n const state = this.contentBinding.getState();\n if (!state) throw new Error(\"Message part is not available\");\n\n if (state.type !== \"tool-call\")\n throw new Error(\"Tried to add tool result to non-tool message part\");\n\n if (!this.messageApi)\n throw new Error(\n \"Message API is not available. This is likely a bug in assistant-ui.\",\n );\n if (!this.threadApi) throw new Error(\"Thread API is not available\");\n\n const message = this.messageApi.getState();\n if (!message) throw new Error(\"Message is not available\");\n\n const toolName = state.toolName;\n const toolCallId = state.toolCallId;\n\n const response = ToolResponse.toResponse(result);\n this.threadApi.getState().addToolResult({\n messageId: message.id,\n toolName,\n toolCallId,\n result: response.result,\n artifact: response.artifact,\n isError: response.isError,\n });\n }\n\n public resumeToolCall(payload: unknown) {\n const state = this.contentBinding.getState();\n if (!state) throw new Error(\"Message part is not available\");\n\n if (state.type !== \"tool-call\")\n throw new Error(\"Tried to resume tool call on non-tool message part\");\n\n if (!this.threadApi) throw new Error(\"Thread API is not available\");\n\n const toolCallId = state.toolCallId;\n this.threadApi.getState().resumeToolCall({\n toolCallId,\n payload,\n });\n }\n\n public respondToToolApproval(response: {\n approved: boolean;\n reason?: string;\n }) {\n const state = this.contentBinding.getState();\n if (!state) throw new Error(\"Message part is not available\");\n\n if (state.type !== \"tool-call\")\n throw new Error(\n \"Tried to respond to tool approval on non-tool message part\",\n );\n\n if (!state.approval || state.approval.approved !== undefined)\n throw new Error(\"Tool call has no pending approval\");\n\n if (!this.threadApi) throw new Error(\"Thread API is not available\");\n\n this.threadApi.getState().respondToToolApproval({\n approvalId: state.approval.id,\n approved: response.approved,\n ...(response.reason != null && { reason: response.reason }),\n });\n }\n\n public subscribe(callback: () => void) {\n return this.contentBinding.subscribe(callback);\n }\n}\n"],"mappings":";;AAmCA,IAAa,yBAAb,MAAkE;CAMtD;CACA;CACA;CAPV,IAAW,OAAO;EAChB,OAAO,KAAK,eAAe;CAC7B;CAEA,YACE,gBACA,YACA,WACA;EAHQ,KAAA,iBAAA;EACA,KAAA,aAAA;EACA,KAAA,YAAA;EAER,KAAK,uBAAuB;CAC9B;CAEA,yBAAmC;EACjC,KAAK,gBAAgB,KAAK,cAAc,KAAK,IAAI;EACjD,KAAK,iBAAiB,KAAK,eAAe,KAAK,IAAI;EACnD,KAAK,wBAAwB,KAAK,sBAAsB,KAAK,IAAI;EACjE,KAAK,WAAW,KAAK,SAAS,KAAK,IAAI;EACvC,KAAK,YAAY,KAAK,UAAU,KAAK,IAAI;CAC3C;CAEA,WAAkB;EAChB,OAAO,KAAK,eAAe,SAAS;CACtC;CAEA,cAAqB,QAAiC;EACpD,MAAM,QAAQ,KAAK,eAAe,SAAS;EAC3C,IAAI,CAAC,OAAO,MAAM,IAAI,MAAM,+BAA+B;EAE3D,IAAI,MAAM,SAAS,aACjB,MAAM,IAAI,MAAM,mDAAmD;EAErE,IAAI,CAAC,KAAK,YACR,MAAM,IAAI,MACR,qEACF;EACF,IAAI,CAAC,KAAK,WAAW,MAAM,IAAI,MAAM,6BAA6B;EAElE,MAAM,UAAU,KAAK,WAAW,SAAS;EACzC,IAAI,CAAC,SAAS,MAAM,IAAI,MAAM,0BAA0B;EAExD,MAAM,WAAW,MAAM;EACvB,MAAM,aAAa,MAAM;EAEzB,MAAM,WAAW,aAAa,WAAW,MAAM;EAC/C,KAAK,UAAU,SAAS,EAAE,cAAc;GACtC,WAAW,QAAQ;GACnB;GACA;GACA,QAAQ,SAAS;GACjB,UAAU,SAAS;GACnB,SAAS,SAAS;EACpB,CAAC;CACH;CAEA,eAAsB,SAAkB;EACtC,MAAM,QAAQ,KAAK,eAAe,SAAS;EAC3C,IAAI,CAAC,OAAO,MAAM,IAAI,MAAM,+BAA+B;EAE3D,IAAI,MAAM,SAAS,aACjB,MAAM,IAAI,MAAM,oDAAoD;EAEtE,IAAI,CAAC,KAAK,WAAW,MAAM,IAAI,MAAM,6BAA6B;EAElE,MAAM,aAAa,MAAM;EACzB,KAAK,UAAU,SAAS,EAAE,eAAe;GACvC;GACA;EACF,CAAC;CACH;CAEA,sBAA6B,UAG1B;EACD,MAAM,QAAQ,KAAK,eAAe,SAAS;EAC3C,IAAI,CAAC,OAAO,MAAM,IAAI,MAAM,+BAA+B;EAE3D,IAAI,MAAM,SAAS,aACjB,MAAM,IAAI,MACR,4DACF;EAEF,IAAI,CAAC,MAAM,YAAY,MAAM,SAAS,aAAa,KAAA,GACjD,MAAM,IAAI,MAAM,mCAAmC;EAErD,IAAI,CAAC,KAAK,WAAW,MAAM,IAAI,MAAM,6BAA6B;EAElE,KAAK,UAAU,SAAS,EAAE,sBAAsB;GAC9C,YAAY,MAAM,SAAS;GAC3B,UAAU,SAAS;GACnB,GAAI,SAAS,UAAU,QAAQ,EAAE,QAAQ,SAAS,OAAO;EAC3D,CAAC;CACH;CAEA,UAAiB,UAAsB;EACrC,OAAO,KAAK,eAAe,UAAU,QAAQ;CAC/C;AACF"}
@@ -7,7 +7,7 @@ import { ThreadMessageLike } from "../utils/thread-message-like.js";
7
7
  import { ExportedMessageRepository } from "../utils/message-repository.js";
8
8
  import { QuoteInfo } from "../../types/quote.js";
9
9
  import { ComposerRuntimeEventCallback, ComposerRuntimeEventType, DictationState, EditComposerRuntimeCore, SendOptions } from "../interfaces/composer-runtime-core.js";
10
- import { AddToolResultOptions, ResumeRunConfig, ResumeToolCallOptions, RuntimeCapabilities, SpeechState, StartRunConfig, SubmitFeedbackOptions, ThreadRuntimeCore, ThreadRuntimeEventCallback, ThreadRuntimeEventType, ThreadSuggestion, VoiceSessionState } from "../interfaces/thread-runtime-core.js";
10
+ import { AddToolResultOptions, RespondToToolApprovalOptions, ResumeRunConfig, ResumeToolCallOptions, RuntimeCapabilities, SpeechState, StartRunConfig, SubmitFeedbackOptions, ThreadRuntimeCore, ThreadRuntimeEventCallback, ThreadRuntimeEventType, ThreadSuggestion, VoiceSessionState } from "../interfaces/thread-runtime-core.js";
11
11
  import { ThreadListItemRuntimePath, ThreadRuntimePath } from "./paths.js";
12
12
  import { Subscribable, SubscribableWithState } from "../../subscribable/subscribable.js";
13
13
  import { ThreadListItemState } from "./bindings.js";
@@ -189,6 +189,7 @@ declare class ThreadRuntimeImpl implements ThreadRuntime {
189
189
  cancelRun: () => void;
190
190
  addToolResult: (options: AddToolResultOptions) => void;
191
191
  resumeToolCall: (options: ResumeToolCallOptions) => void;
192
+ respondToToolApproval: (options: RespondToToolApprovalOptions) => void;
192
193
  speak: (messageId: string) => void;
193
194
  stopSpeaking: () => void;
194
195
  connectVoice: () => void;
@@ -1 +1 @@
1
- {"version":3,"file":"thread-runtime.d.ts","names":[],"sources":["../../../src/runtime/api/thread-runtime.ts"],"mappings":"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"}
1
+ {"version":3,"file":"thread-runtime.d.ts","names":[],"sources":["../../../src/runtime/api/thread-runtime.ts"],"mappings":"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"}
@@ -7,7 +7,7 @@ import { RealtimeVoiceAdapter } from "../../adapters/voice.js";
7
7
  import { ModelContext, ModelContextProvider } from "../../model-context/types.js";
8
8
  import { ThreadMessageLike } from "../utils/thread-message-like.js";
9
9
  import { ExportedMessageRepository, MessageRepository } from "../utils/message-repository.js";
10
- import { AddToolResultOptions, ResumeRunConfig, ResumeToolCallOptions, RuntimeCapabilities, SpeechState, StartRunConfig, SubmitFeedbackOptions, ThreadRuntimeCore, ThreadRuntimeEventCallback, ThreadRuntimeEventPayload, ThreadRuntimeEventType, ThreadSuggestion, VoiceSessionState } from "../interfaces/thread-runtime-core.js";
10
+ import { AddToolResultOptions, RespondToToolApprovalOptions, ResumeRunConfig, ResumeToolCallOptions, RuntimeCapabilities, SpeechState, StartRunConfig, SubmitFeedbackOptions, ThreadRuntimeCore, ThreadRuntimeEventCallback, ThreadRuntimeEventPayload, ThreadRuntimeEventType, ThreadSuggestion, VoiceSessionState } from "../interfaces/thread-runtime-core.js";
11
11
  import { DefaultThreadComposerRuntimeCore } from "./default-thread-composer-runtime-core.js";
12
12
  import { DefaultEditComposerRuntimeCore } from "./default-edit-composer-runtime-core.js";
13
13
  //#region src/runtime/base/base-thread-runtime-core.d.ts
@@ -34,6 +34,7 @@ declare abstract class BaseThreadRuntimeCore implements ThreadRuntimeCore {
34
34
  abstract resumeRun(config: ResumeRunConfig): void;
35
35
  abstract addToolResult(options: AddToolResultOptions): void;
36
36
  abstract resumeToolCall(options: ResumeToolCallOptions): void;
37
+ abstract respondToToolApproval(options: RespondToToolApprovalOptions): void;
37
38
  abstract cancelRun(): void;
38
39
  abstract exportExternalState(): any;
39
40
  abstract importExternalState(state: any): void;
@@ -1 +1 @@
1
- {"version":3,"file":"base-thread-runtime-core.d.ts","names":[],"sources":["../../../src/runtime/base/base-thread-runtime-core.ts"],"mappings":";;;;;;;;;;;;;KAoCK,kBAAA;EACH,MAAA,GAAS,sBAAA;EACT,QAAA,GAAW,eAAA;EACX,WAAA,GAAc,iBAAA;EACd,KAAA,GAAQ,oBAAA;AAAA;AAAA,uBAGY,qBAAA,YAAiC,iBAAA;EAAA,iBAkExB,gBAAA;EAAA,QAjErB,cAAA;EAAA,QACA,cAAA;EAAA,mBAEW,UAAA,EAAU,iBAAA;EAAA,aACT,QAAA,CAAA,GAAY,kBAAA;EAAA,aACZ,UAAA,CAAA;EAAA,aACA,cAAA,CAAA;EAAA,aACA,SAAA,CAAA;EAAA,aACA,WAAA,CAAA,YAAwB,gBAAA;EAAA,aACxB,MAAA,CAAA;EAAA,aAEA,YAAA,CAAA,GAAgB,mBAAA;EAAA,SACpB,MAAA,CAAO,OAAA,EAAS,aAAA;EAAA,SAChB,QAAA,CAAS,MAAA,EAAQ,cAAA;EAAA,SACjB,SAAA,CAAU,MAAA,EAAQ,eAAA;EAAA,SAClB,aAAA,CAAc,OAAA,EAAS,oBAAA;EAAA,SACvB,cAAA,CAAe,OAAA,EAAS,qBAAA;EAAA,SACxB,SAAA,CAAA;EAAA,SACA,mBAAA,CAAA;EAAA,SACA,mBAAA,CAAoB,KAAA;EAAA,UAE1B,cAAA,EAAgB,aAAA;EAAA,UAChB,gBAAA;EAAA,QACF,qBAAA;EAAA,QACA,sBAAA;EAAA,QACA,iBAAA;EAAA,UAEE,uBAAA,CAAA;EAAA,UAKA,gBAAA,CAAA,YAA6B,aAAA;EAAA,IAI5B,QAAA,CAAA,YAAqB,aAAA;EAAA,IAgBrB,KAAA,CAAA,gEAAK,kBAAA,oCAAA,iBAAA;EAAA,SAWA,QAAA,EAAQ,gCAAA;cAEK,gBAAA,EAAkB,oBAAA;EAExC,eAAA,CAAA,GAF4D,YAAA;EAAA,QAM3D,cAAA;EACD,eAAA,CAAgB,SAAA,WAAiB,8BAAA;EAGjC,SAAA,CAAU,SAAA;EAeV,cAAA,CAAe,SAAA;;;;;EAsBf,WAAA,CAAY,SAAA;EAOZ,cAAA,CAAe,QAAA;EAAA,UAKZ,kBAAA,CAAA;EAIH,uBAAA,WAAkC,sBAAA,CAAA,CACvC,KAAA,EAAO,CAAA,EACP,OAAA,EAAS,yBAAA,CAA0B,CAAA;EAQ9B,SAAA,CAAU,QAAA,eAAuB,WAAA;EAKjC,cAAA,CAAA;IAAiB,SAAA;IAAW;EAAA,GAAQ,qBAAA;EAAA,QAqBnC,aAAA;EACD,MAAA,EAAQ,WAAA;EAER,KAAA,CAAM,SAAA;EA8BN,YAAA,CAAA;EAAA,QAMC,aAAA;EAAA,QACA,YAAA;EACD,KAAA,EAAO,iBAAA;EAAA,QAEN,YAAA;EAAA,QACA,uBAAA;EAED,cAAA;EAEA,oBAAA,GAAwB,QAAA,iBAAuB,WAAA;EAK/C,YAAA,CAAA;EAAA,QA+DC,oBAAA;EAAA,QAEA,sBAAA;EAAA,QA8DA,4BAAA;EAaD,eAAA,CAAA;EAeA,SAAA,CAAA;EAUA,WAAA,CAAA;EAAA,UAUG,iBAAA,CAAA;EAOH,MAAA,CAAA,GAAM,yBAAA;EAIN,MAAA,CAAO,IAAA,EAAM,yBAAA;EAOb,KAAA,CAAM,eAAA,YAA2B,iBAAA;EAAA,QAIhC,iBAAA;EAKD,WAAA,WAAsB,sBAAA,CAAA,CAC3B,KAAA,EAAO,CAAA,EACP,QAAA,EAAU,0BAAA,CAA2B,CAAA,IAAE,WAAA;AAAA"}
1
+ {"version":3,"file":"base-thread-runtime-core.d.ts","names":[],"sources":["../../../src/runtime/base/base-thread-runtime-core.ts"],"mappings":";;;;;;;;;;;;;KAqCK,kBAAA;EACH,MAAA,GAAS,sBAAA;EACT,QAAA,GAAW,eAAA;EACX,WAAA,GAAc,iBAAA;EACd,KAAA,GAAQ,oBAAA;AAAA;AAAA,uBAGY,qBAAA,YAAiC,iBAAA;EAAA,iBAqExB,gBAAA;EAAA,QApErB,cAAA;EAAA,QACA,cAAA;EAAA,mBAEW,UAAA,EAAU,iBAAA;EAAA,aACT,QAAA,CAAA,GAAY,kBAAA;EAAA,aACZ,UAAA,CAAA;EAAA,aACA,cAAA,CAAA;EAAA,aACA,SAAA,CAAA;EAAA,aACA,WAAA,CAAA,YAAwB,gBAAA;EAAA,aACxB,MAAA,CAAA;EAAA,aAEA,YAAA,CAAA,GAAgB,mBAAA;EAAA,SACpB,MAAA,CAAO,OAAA,EAAS,aAAA;EAAA,SAChB,QAAA,CAAS,MAAA,EAAQ,cAAA;EAAA,SACjB,SAAA,CAAU,MAAA,EAAQ,eAAA;EAAA,SAClB,aAAA,CAAc,OAAA,EAAS,oBAAA;EAAA,SACvB,cAAA,CAAe,OAAA,EAAS,qBAAA;EAAA,SACxB,qBAAA,CACd,OAAA,EAAS,4BAAA;EAAA,SAEK,SAAA,CAAA;EAAA,SACA,mBAAA,CAAA;EAAA,SACA,mBAAA,CAAoB,KAAA;EAAA,UAE1B,cAAA,EAAgB,aAAA;EAAA,UAChB,gBAAA;EAAA,QACF,qBAAA;EAAA,QACA,sBAAA;EAAA,QACA,iBAAA;EAAA,UAEE,uBAAA,CAAA;EAAA,UAKA,gBAAA,CAAA,YAA6B,aAAA;EAAA,IAI5B,QAAA,CAAA,YAAqB,aAAA;EAAA,IAgBrB,KAAA,CAAA,gEAAK,kBAAA,oCAAA,iBAAA;EAAA,SAWA,QAAA,EAAQ,gCAAA;cAEK,gBAAA,EAAkB,oBAAA;EAExC,eAAA,CAAA,GAF4D,YAAA;EAAA,QAM3D,cAAA;EACD,eAAA,CAAgB,SAAA,WAAiB,8BAAA;EAGjC,SAAA,CAAU,SAAA;EAeV,cAAA,CAAe,SAAA;;;;;EAsBf,WAAA,CAAY,SAAA;EAOZ,cAAA,CAAe,QAAA;EAAA,UAKZ,kBAAA,CAAA;EAIH,uBAAA,WAAkC,sBAAA,CAAA,CACvC,KAAA,EAAO,CAAA,EACP,OAAA,EAAS,yBAAA,CAA0B,CAAA;EAQ9B,SAAA,CAAU,QAAA,eAAuB,WAAA;EAKjC,cAAA,CAAA;IAAiB,SAAA;IAAW;EAAA,GAAQ,qBAAA;EAAA,QAqBnC,aAAA;EACD,MAAA,EAAQ,WAAA;EAER,KAAA,CAAM,SAAA;EA8BN,YAAA,CAAA;EAAA,QAMC,aAAA;EAAA,QACA,YAAA;EACD,KAAA,EAAO,iBAAA;EAAA,QAEN,YAAA;EAAA,QACA,uBAAA;EAED,cAAA;EAEA,oBAAA,GAAwB,QAAA,iBAAuB,WAAA;EAK/C,YAAA,CAAA;EAAA,QA+DC,oBAAA;EAAA,QAEA,sBAAA;EAAA,QA8DA,4BAAA;EAaD,eAAA,CAAA;EAeA,SAAA,CAAA;EAUA,WAAA,CAAA;EAAA,UAUG,iBAAA,CAAA;EAOH,MAAA,CAAA,GAAM,yBAAA;EAIN,MAAA,CAAO,IAAA,EAAM,yBAAA;EAOb,KAAA,CAAM,eAAA,YAA2B,iBAAA;EAAA,QAIhC,iBAAA;EAKD,WAAA,WAAsB,sBAAA,CAAA,CAC3B,KAAA,EAAO,CAAA,EACP,QAAA,EAAU,0BAAA,CAA2B,CAAA,IAAE,WAAA;AAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"base-thread-runtime-core.js","names":[],"sources":["../../../src/runtime/base/base-thread-runtime-core.ts"],"sourcesContent":["import type {\n AppendMessage,\n ThreadAssistantMessage,\n ThreadMessage,\n} from \"../../types/message\";\nimport type { Unsubscribe } from \"../../types/unsubscribe\";\nimport type { ModelContextProvider } from \"../../model-context/types\";\nimport { getThreadMessageText } from \"../../utils/text\";\nimport { generateId } from \"../../utils/id\";\nimport {\n ExportedMessageRepository,\n MessageRepository,\n} from \"../utils/message-repository\";\nimport { DefaultThreadComposerRuntimeCore } from \"./default-thread-composer-runtime-core\";\nimport type {\n AddToolResultOptions,\n ResumeToolCallOptions,\n ThreadSuggestion,\n SubmitFeedbackOptions,\n ThreadRuntimeCore,\n SpeechState,\n VoiceSessionState,\n RuntimeCapabilities,\n ThreadRuntimeEventCallback,\n ThreadRuntimeEventPayload,\n ThreadRuntimeEventType,\n StartRunConfig,\n ResumeRunConfig,\n} from \"../interfaces/thread-runtime-core\";\nimport { DefaultEditComposerRuntimeCore } from \"./default-edit-composer-runtime-core\";\nimport type { SpeechSynthesisAdapter } from \"../../adapters/speech\";\nimport type { FeedbackAdapter } from \"../../adapters/feedback\";\nimport type { AttachmentAdapter } from \"../../adapters/attachment\";\nimport type { RealtimeVoiceAdapter } from \"../../adapters/voice\";\nimport type { ThreadMessageLike } from \"../utils/thread-message-like\";\n\ntype BaseThreadAdapters = {\n speech?: SpeechSynthesisAdapter | undefined;\n feedback?: FeedbackAdapter | undefined;\n attachments?: AttachmentAdapter | undefined;\n voice?: RealtimeVoiceAdapter | undefined;\n};\n\nexport abstract class BaseThreadRuntimeCore implements ThreadRuntimeCore {\n private _subscriptions = new Set<() => void>();\n private _isInitialized = false;\n\n protected readonly repository = new MessageRepository();\n public abstract get adapters(): BaseThreadAdapters | undefined;\n public abstract get isDisabled(): boolean;\n public abstract get isSendDisabled(): boolean;\n public abstract get isLoading(): boolean;\n public abstract get suggestions(): readonly ThreadSuggestion[];\n public abstract get extras(): unknown;\n\n public abstract get capabilities(): RuntimeCapabilities;\n public abstract append(message: AppendMessage): void;\n public abstract startRun(config: StartRunConfig): void;\n public abstract resumeRun(config: ResumeRunConfig): void;\n public abstract addToolResult(options: AddToolResultOptions): void;\n public abstract resumeToolCall(options: ResumeToolCallOptions): void;\n public abstract cancelRun(): void;\n public abstract exportExternalState(): any;\n public abstract importExternalState(state: any): void;\n\n protected _voiceMessages: ThreadMessage[] = [];\n protected _voiceGeneration = 0;\n private _cachedMergedMessages: readonly ThreadMessage[] | null = null;\n private _cachedVoiceGeneration = -1;\n private _cachedMergedBase: readonly ThreadMessage[] | null = null;\n\n protected _markVoiceMessagesDirty() {\n this._voiceGeneration++;\n this._cachedMergedMessages = null;\n }\n\n protected _getBaseMessages(): readonly ThreadMessage[] {\n return this.repository.getMessages();\n }\n\n public get messages(): readonly ThreadMessage[] {\n if (this._voiceMessages.length === 0) {\n return this._getBaseMessages();\n }\n const base = this._getBaseMessages();\n if (\n this._cachedVoiceGeneration !== this._voiceGeneration ||\n this._cachedMergedBase !== base\n ) {\n this._cachedMergedMessages = [...base, ...this._voiceMessages];\n this._cachedVoiceGeneration = this._voiceGeneration;\n this._cachedMergedBase = base;\n }\n return this._cachedMergedMessages!;\n }\n\n public get state() {\n let mostRecentAssistantMessage: (typeof this.messages)[number] | undefined;\n for (const message of this.messages) {\n if (message.role === \"assistant\") {\n mostRecentAssistantMessage = message;\n }\n }\n\n return mostRecentAssistantMessage?.metadata.unstable_state ?? null;\n }\n\n public readonly composer = new DefaultThreadComposerRuntimeCore(this);\n\n constructor(private readonly _contextProvider: ModelContextProvider) {}\n\n public getModelContext() {\n return this._contextProvider.getModelContext();\n }\n\n private _editComposers = new Map<string, DefaultEditComposerRuntimeCore>();\n public getEditComposer(messageId: string) {\n return this._editComposers.get(messageId);\n }\n public beginEdit(messageId: string) {\n if (this._editComposers.has(messageId))\n throw new Error(\"Edit already in progress\");\n\n this._editComposers.set(\n messageId,\n new DefaultEditComposerRuntimeCore(\n this,\n () => this._editComposers.delete(messageId),\n this.repository.getMessage(messageId),\n ),\n );\n this._notifySubscribers();\n }\n\n public getMessageById(messageId: string) {\n try {\n return this.repository.getMessage(messageId);\n } catch {\n // Check voice messages\n const baseMessages = this.repository.getMessages();\n const voiceIdx = this._voiceMessages.findIndex((m) => m.id === messageId);\n if (voiceIdx !== -1) {\n const parentId =\n voiceIdx > 0\n ? this._voiceMessages[voiceIdx - 1]!.id\n : (baseMessages.at(-1)?.id ?? null);\n return {\n parentId,\n message: this._voiceMessages[voiceIdx]!,\n index: baseMessages.length + voiceIdx,\n };\n }\n return undefined;\n }\n }\n\n public getBranches(messageId: string): string[] {\n if (this._voiceMessages.some((m) => m.id === messageId)) {\n return [];\n }\n return this.repository.getBranches(messageId);\n }\n\n public switchToBranch(branchId: string): void {\n this.repository.switchToBranch(branchId);\n this._notifySubscribers();\n }\n\n protected _notifySubscribers() {\n for (const callback of this._subscriptions) callback();\n }\n\n public _notifyEventSubscribers<E extends ThreadRuntimeEventType>(\n event: E,\n payload: ThreadRuntimeEventPayload[E],\n ) {\n const subscribers = this._eventSubscribers.get(event);\n if (!subscribers) return;\n\n for (const callback of subscribers) callback(payload);\n }\n\n public subscribe(callback: () => void): Unsubscribe {\n this._subscriptions.add(callback);\n return () => this._subscriptions.delete(callback);\n }\n\n public submitFeedback({ messageId, type }: SubmitFeedbackOptions) {\n const adapter = this.adapters?.feedback;\n if (!adapter) throw new Error(\"Feedback adapter not configured\");\n\n const { message, parentId } = this.repository.getMessage(messageId);\n adapter.submit({ message, type });\n\n if (message.role === \"assistant\") {\n const updatedMessage: ThreadMessage = {\n ...message,\n metadata: {\n ...message.metadata,\n submittedFeedback: { type },\n },\n };\n this.repository.addOrUpdateMessage(parentId, updatedMessage);\n }\n\n this._notifySubscribers();\n }\n\n private _stopSpeaking: Unsubscribe | undefined;\n public speech: SpeechState | undefined;\n\n public speak(messageId: string) {\n const adapter = this.adapters?.speech;\n if (!adapter) throw new Error(\"Speech adapter not configured\");\n\n const { message } = this.repository.getMessage(messageId);\n\n this._stopSpeaking?.();\n\n const utterance = adapter.speak(getThreadMessageText(message));\n const unsub = utterance.subscribe(() => {\n if (utterance.status.type === \"ended\") {\n this._stopSpeaking = undefined;\n this.speech = undefined;\n } else {\n this.speech = { messageId, status: utterance.status };\n }\n this._notifySubscribers();\n });\n\n this.speech = { messageId, status: utterance.status };\n this._notifySubscribers();\n\n this._stopSpeaking = () => {\n utterance.cancel();\n unsub();\n this.speech = undefined;\n this._stopSpeaking = undefined;\n };\n }\n\n public stopSpeaking() {\n if (!this._stopSpeaking) throw new Error(\"No message is being spoken\");\n this._stopSpeaking();\n this._notifySubscribers();\n }\n\n private _voiceSession: RealtimeVoiceAdapter.Session | undefined;\n private _voiceUnsubs: Array<() => void> = [];\n public voice: VoiceSessionState | undefined;\n\n private _voiceVolume = 0;\n private _voiceVolumeSubscribers = new Set<() => void>();\n\n public getVoiceVolume = () => this._voiceVolume;\n\n public subscribeVoiceVolume = (callback: () => void): Unsubscribe => {\n this._voiceVolumeSubscribers.add(callback);\n return () => this._voiceVolumeSubscribers.delete(callback);\n };\n\n public connectVoice() {\n const adapter = this.adapters?.voice;\n if (!adapter) throw new Error(\"Voice adapter not configured\");\n\n this.disconnectVoice();\n\n const session = adapter.connect({});\n this._voiceSession = session;\n const unsubs: Array<() => void> = [];\n\n let currentMode: RealtimeVoiceAdapter.Mode = \"listening\";\n\n this.voice = {\n status: session.status,\n isMuted: session.isMuted,\n mode: currentMode,\n };\n this._voiceVolume = 0;\n this._notifySubscribers();\n\n unsubs.push(\n session.onStatusChange((status) => {\n if (status.type === \"ended\") {\n this._finishVoiceAssistantMessage();\n this._voiceSession = undefined;\n this.voice = undefined;\n } else {\n this.voice = {\n status,\n isMuted: session.isMuted,\n mode: currentMode,\n };\n }\n this._notifySubscribers();\n }),\n );\n\n unsubs.push(\n session.onModeChange((mode) => {\n currentMode = mode;\n if (this.voice) {\n this.voice = { ...this.voice, mode };\n this._notifySubscribers();\n }\n }),\n );\n\n unsubs.push(\n session.onVolumeChange((volume) => {\n this._voiceVolume = volume;\n for (const cb of this._voiceVolumeSubscribers) cb();\n }),\n );\n\n unsubs.push(\n session.onTranscript((transcript) => {\n this._handleVoiceTranscript(transcript);\n }),\n );\n\n this._voiceUnsubs = unsubs;\n }\n\n private _currentAssistantMsg: ThreadAssistantMessage | null = null;\n\n private _handleVoiceTranscript(\n transcript: RealtimeVoiceAdapter.TranscriptItem,\n ) {\n this.ensureInitialized();\n\n if (transcript.role === \"user\") {\n this._finishVoiceAssistantMessage();\n this._currentAssistantMsg = null;\n\n if (transcript.isFinal) {\n this._voiceMessages.push({\n id: generateId(),\n role: \"user\",\n content: [{ type: \"text\", text: transcript.text }],\n metadata: { custom: {} },\n createdAt: new Date(),\n status: { type: \"complete\", reason: \"unknown\" },\n attachments: [],\n });\n this._markVoiceMessagesDirty();\n this._notifySubscribers();\n }\n } else {\n if (!this._currentAssistantMsg) {\n this._currentAssistantMsg = {\n id: generateId(),\n role: \"assistant\",\n content: [{ type: \"text\", text: transcript.text }],\n metadata: {\n unstable_state: this.state,\n unstable_annotations: [],\n unstable_data: [],\n steps: [],\n custom: {},\n },\n status: { type: \"running\" },\n createdAt: new Date(),\n };\n this._voiceMessages.push(this._currentAssistantMsg);\n } else {\n const idx = this._voiceMessages.indexOf(this._currentAssistantMsg);\n if (idx === -1) return;\n const updated: ThreadAssistantMessage = {\n ...this._currentAssistantMsg,\n content: [{ type: \"text\", text: transcript.text }],\n ...(transcript.isFinal\n ? { status: { type: \"complete\", reason: \"stop\" } }\n : {}),\n };\n this._voiceMessages[idx] = updated;\n this._currentAssistantMsg = updated;\n }\n\n if (transcript.isFinal) {\n this._currentAssistantMsg = null;\n }\n\n this._markVoiceMessagesDirty();\n this._notifySubscribers();\n }\n }\n\n private _finishVoiceAssistantMessage() {\n const last = this._voiceMessages.at(-1);\n if (last?.role === \"assistant\" && last.status.type === \"running\") {\n const idx = this._voiceMessages.length - 1;\n this._voiceMessages[idx] = {\n ...(last as ThreadAssistantMessage),\n status: { type: \"complete\", reason: \"stop\" },\n };\n this._markVoiceMessagesDirty();\n this._notifySubscribers();\n }\n }\n\n public disconnectVoice() {\n this._finishVoiceAssistantMessage();\n this._currentAssistantMsg = null;\n for (const unsub of this._voiceUnsubs) unsub();\n this._voiceUnsubs = [];\n this._voiceSession?.disconnect();\n this._voiceSession = undefined;\n this.voice = undefined;\n this._voiceVolume = 0;\n for (const cb of this._voiceVolumeSubscribers) cb();\n this._voiceMessages = [];\n this._markVoiceMessagesDirty();\n this._notifySubscribers();\n }\n\n public muteVoice() {\n if (!this._voiceSession) throw new Error(\"No active voice session\");\n this._voiceSession.mute();\n this.voice = {\n ...this.voice!,\n isMuted: true,\n };\n this._notifySubscribers();\n }\n\n public unmuteVoice() {\n if (!this._voiceSession) throw new Error(\"No active voice session\");\n this._voiceSession.unmute();\n this.voice = {\n ...this.voice!,\n isMuted: false,\n };\n this._notifySubscribers();\n }\n\n protected ensureInitialized() {\n if (!this._isInitialized) {\n this._isInitialized = true;\n this._notifyEventSubscribers(\"initialize\", {});\n }\n }\n\n public export() {\n return this.repository.export();\n }\n\n public import(data: ExportedMessageRepository) {\n this.ensureInitialized();\n this.repository.clear();\n this.repository.import(data);\n this._notifySubscribers();\n }\n\n public reset(initialMessages?: readonly ThreadMessageLike[]) {\n this.import(ExportedMessageRepository.fromArray(initialMessages ?? []));\n }\n\n private _eventSubscribers = new Map<\n ThreadRuntimeEventType,\n Set<(payload?: unknown) => void>\n >();\n\n public unstable_on<E extends ThreadRuntimeEventType>(\n event: E,\n callback: ThreadRuntimeEventCallback<E>,\n ) {\n const wrapped = callback as (payload?: unknown) => void;\n if (event === \"modelContextUpdate\") {\n // provider.subscribe is `() => void`; pump the typed empty payload to the user callback.\n return this._contextProvider.subscribe?.(() => wrapped({})) ?? (() => {});\n }\n\n let subscribers = this._eventSubscribers.get(event);\n if (!subscribers) {\n subscribers = new Set();\n this._eventSubscribers.set(event, subscribers);\n }\n subscribers.add(wrapped);\n\n // `initialize` latches: replay it (deferred) to subscribers that attach\n // after the thread already initialized, mirroring a BehaviorSubject.\n if (event === \"initialize\" && this._isInitialized) {\n queueMicrotask(() => {\n if (subscribers.has(wrapped)) wrapped({});\n });\n }\n\n return () => {\n this._eventSubscribers.get(event)?.delete(wrapped);\n };\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"base-thread-runtime-core.js","names":[],"sources":["../../../src/runtime/base/base-thread-runtime-core.ts"],"sourcesContent":["import type {\n AppendMessage,\n ThreadAssistantMessage,\n ThreadMessage,\n} from \"../../types/message\";\nimport type { Unsubscribe } from \"../../types/unsubscribe\";\nimport type { ModelContextProvider } from \"../../model-context/types\";\nimport { getThreadMessageText } from \"../../utils/text\";\nimport { generateId } from \"../../utils/id\";\nimport {\n ExportedMessageRepository,\n MessageRepository,\n} from \"../utils/message-repository\";\nimport { DefaultThreadComposerRuntimeCore } from \"./default-thread-composer-runtime-core\";\nimport type {\n AddToolResultOptions,\n ResumeToolCallOptions,\n RespondToToolApprovalOptions,\n ThreadSuggestion,\n SubmitFeedbackOptions,\n ThreadRuntimeCore,\n SpeechState,\n VoiceSessionState,\n RuntimeCapabilities,\n ThreadRuntimeEventCallback,\n ThreadRuntimeEventPayload,\n ThreadRuntimeEventType,\n StartRunConfig,\n ResumeRunConfig,\n} from \"../interfaces/thread-runtime-core\";\nimport { DefaultEditComposerRuntimeCore } from \"./default-edit-composer-runtime-core\";\nimport type { SpeechSynthesisAdapter } from \"../../adapters/speech\";\nimport type { FeedbackAdapter } from \"../../adapters/feedback\";\nimport type { AttachmentAdapter } from \"../../adapters/attachment\";\nimport type { RealtimeVoiceAdapter } from \"../../adapters/voice\";\nimport type { ThreadMessageLike } from \"../utils/thread-message-like\";\n\ntype BaseThreadAdapters = {\n speech?: SpeechSynthesisAdapter | undefined;\n feedback?: FeedbackAdapter | undefined;\n attachments?: AttachmentAdapter | undefined;\n voice?: RealtimeVoiceAdapter | undefined;\n};\n\nexport abstract class BaseThreadRuntimeCore implements ThreadRuntimeCore {\n private _subscriptions = new Set<() => void>();\n private _isInitialized = false;\n\n protected readonly repository = new MessageRepository();\n public abstract get adapters(): BaseThreadAdapters | undefined;\n public abstract get isDisabled(): boolean;\n public abstract get isSendDisabled(): boolean;\n public abstract get isLoading(): boolean;\n public abstract get suggestions(): readonly ThreadSuggestion[];\n public abstract get extras(): unknown;\n\n public abstract get capabilities(): RuntimeCapabilities;\n public abstract append(message: AppendMessage): void;\n public abstract startRun(config: StartRunConfig): void;\n public abstract resumeRun(config: ResumeRunConfig): void;\n public abstract addToolResult(options: AddToolResultOptions): void;\n public abstract resumeToolCall(options: ResumeToolCallOptions): void;\n public abstract respondToToolApproval(\n options: RespondToToolApprovalOptions,\n ): void;\n public abstract cancelRun(): void;\n public abstract exportExternalState(): any;\n public abstract importExternalState(state: any): void;\n\n protected _voiceMessages: ThreadMessage[] = [];\n protected _voiceGeneration = 0;\n private _cachedMergedMessages: readonly ThreadMessage[] | null = null;\n private _cachedVoiceGeneration = -1;\n private _cachedMergedBase: readonly ThreadMessage[] | null = null;\n\n protected _markVoiceMessagesDirty() {\n this._voiceGeneration++;\n this._cachedMergedMessages = null;\n }\n\n protected _getBaseMessages(): readonly ThreadMessage[] {\n return this.repository.getMessages();\n }\n\n public get messages(): readonly ThreadMessage[] {\n if (this._voiceMessages.length === 0) {\n return this._getBaseMessages();\n }\n const base = this._getBaseMessages();\n if (\n this._cachedVoiceGeneration !== this._voiceGeneration ||\n this._cachedMergedBase !== base\n ) {\n this._cachedMergedMessages = [...base, ...this._voiceMessages];\n this._cachedVoiceGeneration = this._voiceGeneration;\n this._cachedMergedBase = base;\n }\n return this._cachedMergedMessages!;\n }\n\n public get state() {\n let mostRecentAssistantMessage: (typeof this.messages)[number] | undefined;\n for (const message of this.messages) {\n if (message.role === \"assistant\") {\n mostRecentAssistantMessage = message;\n }\n }\n\n return mostRecentAssistantMessage?.metadata.unstable_state ?? null;\n }\n\n public readonly composer = new DefaultThreadComposerRuntimeCore(this);\n\n constructor(private readonly _contextProvider: ModelContextProvider) {}\n\n public getModelContext() {\n return this._contextProvider.getModelContext();\n }\n\n private _editComposers = new Map<string, DefaultEditComposerRuntimeCore>();\n public getEditComposer(messageId: string) {\n return this._editComposers.get(messageId);\n }\n public beginEdit(messageId: string) {\n if (this._editComposers.has(messageId))\n throw new Error(\"Edit already in progress\");\n\n this._editComposers.set(\n messageId,\n new DefaultEditComposerRuntimeCore(\n this,\n () => this._editComposers.delete(messageId),\n this.repository.getMessage(messageId),\n ),\n );\n this._notifySubscribers();\n }\n\n public getMessageById(messageId: string) {\n try {\n return this.repository.getMessage(messageId);\n } catch {\n // Check voice messages\n const baseMessages = this.repository.getMessages();\n const voiceIdx = this._voiceMessages.findIndex((m) => m.id === messageId);\n if (voiceIdx !== -1) {\n const parentId =\n voiceIdx > 0\n ? this._voiceMessages[voiceIdx - 1]!.id\n : (baseMessages.at(-1)?.id ?? null);\n return {\n parentId,\n message: this._voiceMessages[voiceIdx]!,\n index: baseMessages.length + voiceIdx,\n };\n }\n return undefined;\n }\n }\n\n public getBranches(messageId: string): string[] {\n if (this._voiceMessages.some((m) => m.id === messageId)) {\n return [];\n }\n return this.repository.getBranches(messageId);\n }\n\n public switchToBranch(branchId: string): void {\n this.repository.switchToBranch(branchId);\n this._notifySubscribers();\n }\n\n protected _notifySubscribers() {\n for (const callback of this._subscriptions) callback();\n }\n\n public _notifyEventSubscribers<E extends ThreadRuntimeEventType>(\n event: E,\n payload: ThreadRuntimeEventPayload[E],\n ) {\n const subscribers = this._eventSubscribers.get(event);\n if (!subscribers) return;\n\n for (const callback of subscribers) callback(payload);\n }\n\n public subscribe(callback: () => void): Unsubscribe {\n this._subscriptions.add(callback);\n return () => this._subscriptions.delete(callback);\n }\n\n public submitFeedback({ messageId, type }: SubmitFeedbackOptions) {\n const adapter = this.adapters?.feedback;\n if (!adapter) throw new Error(\"Feedback adapter not configured\");\n\n const { message, parentId } = this.repository.getMessage(messageId);\n adapter.submit({ message, type });\n\n if (message.role === \"assistant\") {\n const updatedMessage: ThreadMessage = {\n ...message,\n metadata: {\n ...message.metadata,\n submittedFeedback: { type },\n },\n };\n this.repository.addOrUpdateMessage(parentId, updatedMessage);\n }\n\n this._notifySubscribers();\n }\n\n private _stopSpeaking: Unsubscribe | undefined;\n public speech: SpeechState | undefined;\n\n public speak(messageId: string) {\n const adapter = this.adapters?.speech;\n if (!adapter) throw new Error(\"Speech adapter not configured\");\n\n const { message } = this.repository.getMessage(messageId);\n\n this._stopSpeaking?.();\n\n const utterance = adapter.speak(getThreadMessageText(message));\n const unsub = utterance.subscribe(() => {\n if (utterance.status.type === \"ended\") {\n this._stopSpeaking = undefined;\n this.speech = undefined;\n } else {\n this.speech = { messageId, status: utterance.status };\n }\n this._notifySubscribers();\n });\n\n this.speech = { messageId, status: utterance.status };\n this._notifySubscribers();\n\n this._stopSpeaking = () => {\n utterance.cancel();\n unsub();\n this.speech = undefined;\n this._stopSpeaking = undefined;\n };\n }\n\n public stopSpeaking() {\n if (!this._stopSpeaking) throw new Error(\"No message is being spoken\");\n this._stopSpeaking();\n this._notifySubscribers();\n }\n\n private _voiceSession: RealtimeVoiceAdapter.Session | undefined;\n private _voiceUnsubs: Array<() => void> = [];\n public voice: VoiceSessionState | undefined;\n\n private _voiceVolume = 0;\n private _voiceVolumeSubscribers = new Set<() => void>();\n\n public getVoiceVolume = () => this._voiceVolume;\n\n public subscribeVoiceVolume = (callback: () => void): Unsubscribe => {\n this._voiceVolumeSubscribers.add(callback);\n return () => this._voiceVolumeSubscribers.delete(callback);\n };\n\n public connectVoice() {\n const adapter = this.adapters?.voice;\n if (!adapter) throw new Error(\"Voice adapter not configured\");\n\n this.disconnectVoice();\n\n const session = adapter.connect({});\n this._voiceSession = session;\n const unsubs: Array<() => void> = [];\n\n let currentMode: RealtimeVoiceAdapter.Mode = \"listening\";\n\n this.voice = {\n status: session.status,\n isMuted: session.isMuted,\n mode: currentMode,\n };\n this._voiceVolume = 0;\n this._notifySubscribers();\n\n unsubs.push(\n session.onStatusChange((status) => {\n if (status.type === \"ended\") {\n this._finishVoiceAssistantMessage();\n this._voiceSession = undefined;\n this.voice = undefined;\n } else {\n this.voice = {\n status,\n isMuted: session.isMuted,\n mode: currentMode,\n };\n }\n this._notifySubscribers();\n }),\n );\n\n unsubs.push(\n session.onModeChange((mode) => {\n currentMode = mode;\n if (this.voice) {\n this.voice = { ...this.voice, mode };\n this._notifySubscribers();\n }\n }),\n );\n\n unsubs.push(\n session.onVolumeChange((volume) => {\n this._voiceVolume = volume;\n for (const cb of this._voiceVolumeSubscribers) cb();\n }),\n );\n\n unsubs.push(\n session.onTranscript((transcript) => {\n this._handleVoiceTranscript(transcript);\n }),\n );\n\n this._voiceUnsubs = unsubs;\n }\n\n private _currentAssistantMsg: ThreadAssistantMessage | null = null;\n\n private _handleVoiceTranscript(\n transcript: RealtimeVoiceAdapter.TranscriptItem,\n ) {\n this.ensureInitialized();\n\n if (transcript.role === \"user\") {\n this._finishVoiceAssistantMessage();\n this._currentAssistantMsg = null;\n\n if (transcript.isFinal) {\n this._voiceMessages.push({\n id: generateId(),\n role: \"user\",\n content: [{ type: \"text\", text: transcript.text }],\n metadata: { custom: {} },\n createdAt: new Date(),\n status: { type: \"complete\", reason: \"unknown\" },\n attachments: [],\n });\n this._markVoiceMessagesDirty();\n this._notifySubscribers();\n }\n } else {\n if (!this._currentAssistantMsg) {\n this._currentAssistantMsg = {\n id: generateId(),\n role: \"assistant\",\n content: [{ type: \"text\", text: transcript.text }],\n metadata: {\n unstable_state: this.state,\n unstable_annotations: [],\n unstable_data: [],\n steps: [],\n custom: {},\n },\n status: { type: \"running\" },\n createdAt: new Date(),\n };\n this._voiceMessages.push(this._currentAssistantMsg);\n } else {\n const idx = this._voiceMessages.indexOf(this._currentAssistantMsg);\n if (idx === -1) return;\n const updated: ThreadAssistantMessage = {\n ...this._currentAssistantMsg,\n content: [{ type: \"text\", text: transcript.text }],\n ...(transcript.isFinal\n ? { status: { type: \"complete\", reason: \"stop\" } }\n : {}),\n };\n this._voiceMessages[idx] = updated;\n this._currentAssistantMsg = updated;\n }\n\n if (transcript.isFinal) {\n this._currentAssistantMsg = null;\n }\n\n this._markVoiceMessagesDirty();\n this._notifySubscribers();\n }\n }\n\n private _finishVoiceAssistantMessage() {\n const last = this._voiceMessages.at(-1);\n if (last?.role === \"assistant\" && last.status.type === \"running\") {\n const idx = this._voiceMessages.length - 1;\n this._voiceMessages[idx] = {\n ...(last as ThreadAssistantMessage),\n status: { type: \"complete\", reason: \"stop\" },\n };\n this._markVoiceMessagesDirty();\n this._notifySubscribers();\n }\n }\n\n public disconnectVoice() {\n this._finishVoiceAssistantMessage();\n this._currentAssistantMsg = null;\n for (const unsub of this._voiceUnsubs) unsub();\n this._voiceUnsubs = [];\n this._voiceSession?.disconnect();\n this._voiceSession = undefined;\n this.voice = undefined;\n this._voiceVolume = 0;\n for (const cb of this._voiceVolumeSubscribers) cb();\n this._voiceMessages = [];\n this._markVoiceMessagesDirty();\n this._notifySubscribers();\n }\n\n public muteVoice() {\n if (!this._voiceSession) throw new Error(\"No active voice session\");\n this._voiceSession.mute();\n this.voice = {\n ...this.voice!,\n isMuted: true,\n };\n this._notifySubscribers();\n }\n\n public unmuteVoice() {\n if (!this._voiceSession) throw new Error(\"No active voice session\");\n this._voiceSession.unmute();\n this.voice = {\n ...this.voice!,\n isMuted: false,\n };\n this._notifySubscribers();\n }\n\n protected ensureInitialized() {\n if (!this._isInitialized) {\n this._isInitialized = true;\n this._notifyEventSubscribers(\"initialize\", {});\n }\n }\n\n public export() {\n return this.repository.export();\n }\n\n public import(data: ExportedMessageRepository) {\n this.ensureInitialized();\n this.repository.clear();\n this.repository.import(data);\n this._notifySubscribers();\n }\n\n public reset(initialMessages?: readonly ThreadMessageLike[]) {\n this.import(ExportedMessageRepository.fromArray(initialMessages ?? []));\n }\n\n private _eventSubscribers = new Map<\n ThreadRuntimeEventType,\n Set<(payload?: unknown) => void>\n >();\n\n public unstable_on<E extends ThreadRuntimeEventType>(\n event: E,\n callback: ThreadRuntimeEventCallback<E>,\n ) {\n const wrapped = callback as (payload?: unknown) => void;\n if (event === \"modelContextUpdate\") {\n // provider.subscribe is `() => void`; pump the typed empty payload to the user callback.\n return this._contextProvider.subscribe?.(() => wrapped({})) ?? (() => {});\n }\n\n let subscribers = this._eventSubscribers.get(event);\n if (!subscribers) {\n subscribers = new Set();\n this._eventSubscribers.set(event, subscribers);\n }\n subscribers.add(wrapped);\n\n // `initialize` latches: replay it (deferred) to subscribers that attach\n // after the thread already initialized, mirroring a BehaviorSubject.\n if (event === \"initialize\" && this._isInitialized) {\n queueMicrotask(() => {\n if (subscribers.has(wrapped)) wrapped({});\n });\n }\n\n return () => {\n this._eventSubscribers.get(event)?.delete(wrapped);\n };\n }\n}\n"],"mappings":"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"}
@@ -7,6 +7,7 @@ import { ChatModelRunOptions, ChatModelRunResult } from "../utils/chat-model-ada
7
7
  import { ThreadMessageLike } from "../utils/thread-message-like.js";
8
8
  import { ExportedMessageRepository } from "../utils/message-repository.js";
9
9
  import { EditComposerRuntimeCore, ThreadComposerRuntimeCore } from "./composer-runtime-core.js";
10
+ import { ToolModelContentPart } from "assistant-stream";
10
11
  import { ReadonlyJSONValue } from "assistant-stream/utils";
11
12
 
12
13
  //#region src/runtime/interfaces/thread-runtime-core.d.ts
@@ -31,11 +32,23 @@ type AddToolResultOptions = {
31
32
  result: ReadonlyJSONValue;
32
33
  isError: boolean;
33
34
  artifact?: ReadonlyJSONValue | undefined;
35
+ /**
36
+ * Optional model-content payload produced by the tool. Populated when a
37
+ * client-side `execute()` or `streamCall` returns a `ToolResponse` with
38
+ * `modelContent`. Forwarded through `adapter.onAddToolResult` so the
39
+ * adapter can include it when sending the result back to its backend.
40
+ */
41
+ modelContent?: readonly ToolModelContentPart[] | undefined;
34
42
  };
35
43
  type ResumeToolCallOptions = {
36
44
  toolCallId: string;
37
45
  payload: unknown;
38
46
  };
47
+ type RespondToToolApprovalOptions = {
48
+ approvalId: string;
49
+ approved: boolean;
50
+ reason?: string;
51
+ };
39
52
  type SubmitFeedbackOptions = {
40
53
  messageId: string;
41
54
  type: "negative" | "positive";
@@ -109,6 +122,7 @@ type ThreadRuntimeCore = Readonly<{
109
122
  cancelRun: () => void;
110
123
  addToolResult: (options: AddToolResultOptions) => void;
111
124
  resumeToolCall: (options: ResumeToolCallOptions) => void;
125
+ respondToToolApproval: (options: RespondToToolApprovalOptions) => void;
112
126
  speak: (messageId: string) => void;
113
127
  stopSpeaking: () => void;
114
128
  connectVoice: () => void;
@@ -158,5 +172,5 @@ type ThreadRuntimeCore = Readonly<{
158
172
  unstable_on<E extends ThreadRuntimeEventType>(event: E, callback: ThreadRuntimeEventCallback<E>): Unsubscribe;
159
173
  }>;
160
174
  //#endregion
161
- export { AddToolResultOptions, ResumeRunConfig, ResumeToolCallOptions, RuntimeCapabilities, SpeechState, StartRunConfig, SubmitFeedbackOptions, SubmittedFeedback, ThreadRuntimeCore, ThreadRuntimeEventCallback, ThreadRuntimeEventPayload, ThreadRuntimeEventType, ThreadSuggestion, VoiceSessionState };
175
+ export { AddToolResultOptions, RespondToToolApprovalOptions, ResumeRunConfig, ResumeToolCallOptions, RuntimeCapabilities, SpeechState, StartRunConfig, SubmitFeedbackOptions, SubmittedFeedback, ThreadRuntimeCore, ThreadRuntimeEventCallback, ThreadRuntimeEventPayload, ThreadRuntimeEventType, ThreadSuggestion, VoiceSessionState };
162
176
  //# sourceMappingURL=thread-runtime-core.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"thread-runtime-core.d.ts","names":[],"sources":["../../../src/runtime/interfaces/thread-runtime-core.ts"],"mappings":"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"}
1
+ {"version":3,"file":"thread-runtime-core.d.ts","names":[],"sources":["../../../src/runtime/interfaces/thread-runtime-core.ts"],"mappings":"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"}
@@ -20,6 +20,16 @@ type ThreadMessageLike = {
20
20
  readonly isError?: boolean | undefined;
21
21
  readonly parentId?: string | undefined;
22
22
  readonly messages?: readonly ThreadMessage[] | undefined;
23
+ readonly interrupt?: {
24
+ type: "human";
25
+ payload: unknown;
26
+ };
27
+ readonly approval?: {
28
+ readonly id: string;
29
+ readonly approved?: boolean;
30
+ readonly reason?: string;
31
+ readonly isAutomatic?: boolean;
32
+ };
23
33
  })[];
24
34
  readonly id?: string | undefined;
25
35
  readonly createdAt?: Date | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"thread-message-like.d.ts","names":[],"sources":["../../../src/runtime/utils/thread-message-like.ts"],"mappings":";;;;;KA0BK,gBAAA;EAAA,SACM,IAAA;EAAA,SACA,IAAI;AAAA;AAAA,KAGH,iBAAA;EAAA,SACD,IAAA;EAAA,SACA,OAAA,qBAGD,eAAA,GACA,oBAAA,GACA,iBAAA,GACA,gBAAA,GACA,eAAA,GACA,eAAA,GACA,uBAAA,GACA,yBAAA,GACA,gBAAA;IAAA,SAEW,IAAA;IAAA,SACA,UAAA;IAAA,SACA,QAAA;IAAA,SACA,IAAA,GAAO,kBAAA;IAAA,SACP,QAAA;IAAA,SACA,QAAA;IAAA,SACA,MAAA;IAAA,SACA,OAAA;IAAA,SACA,QAAA;IAAA,SACA,QAAA,YAAoB,aAAA;EAAA;EAAA,SAG9B,EAAA;EAAA,SACA,SAAA,GAAY,IAAA;EAAA,SACZ,MAAA,GAAS,aAAA;EAAA,SACT,WAAA,aACK,IAAA,CAAK,kBAAA;IAAA,SACJ,OAAA,YAAmB,qBAAA,GAAwB,gBAAA;EAAA;EAAA,SAGjD,QAAA;IAAA,SAEM,cAAA,GAAiB,iBAAA;IAAA,SACjB,oBAAA,YACI,iBAAA;IAAA,SAEJ,aAAA,YAAyB,iBAAA;IAAA,SACzB,KAAA,YAAiB,UAAA;IAAA,SACjB,MAAA,GAAS,aAAA;IAAA,SACT,iBAAA;MAAA,SAA+B,IAAA;IAAA;IAAA,SAC/B,MAAA,GAAS,MAAA;EAAA;AAAA;AAAA,cAab,qBAAA,GACX,IAAA,EAAM,iBAAA,EACN,UAAA,UACA,cAAA,EAAgB,aAAA,KACf,aAAA"}
1
+ {"version":3,"file":"thread-message-like.d.ts","names":[],"sources":["../../../src/runtime/utils/thread-message-like.ts"],"mappings":";;;;;KA0BK,gBAAA;EAAA,SACM,IAAA;EAAA,SACA,IAAI;AAAA;AAAA,KAGH,iBAAA;EAAA,SACD,IAAA;EAAA,SACA,OAAA,qBAGD,eAAA,GACA,oBAAA,GACA,iBAAA,GACA,gBAAA,GACA,eAAA,GACA,eAAA,GACA,uBAAA,GACA,yBAAA,GACA,gBAAA;IAAA,SAEW,IAAA;IAAA,SACA,UAAA;IAAA,SACA,QAAA;IAAA,SACA,IAAA,GAAO,kBAAA;IAAA,SACP,QAAA;IAAA,SACA,QAAA;IAAA,SACA,MAAA;IAAA,SACA,OAAA;IAAA,SACA,QAAA;IAAA,SACA,QAAA,YAAoB,aAAA;IAAA,SACpB,SAAA;MAAc,IAAA;MAAe,OAAA;IAAA;IAAA,SAC7B,QAAA;MAAA,SACE,EAAA;MAAA,SACA,QAAA;MAAA,SACA,MAAA;MAAA,SACA,WAAA;IAAA;EAAA;EAAA,SAIZ,EAAA;EAAA,SACA,SAAA,GAAY,IAAA;EAAA,SACZ,MAAA,GAAS,aAAA;EAAA,SACT,WAAA,aACK,IAAA,CAAK,kBAAA;IAAA,SACJ,OAAA,YAAmB,qBAAA,GAAwB,gBAAA;EAAA;EAAA,SAGjD,QAAA;IAAA,SAEM,cAAA,GAAiB,iBAAA;IAAA,SACjB,oBAAA,YACI,iBAAA;IAAA,SAEJ,aAAA,YAAyB,iBAAA;IAAA,SACzB,KAAA,YAAiB,UAAA;IAAA,SACjB,MAAA,GAAS,aAAA;IAAA,SACT,iBAAA;MAAA,SAA+B,IAAA;IAAA;IAAA,SAC/B,MAAA,GAAS,MAAA;EAAA;AAAA;AAAA,cAab,qBAAA,GACX,IAAA,EAAM,iBAAA,EACN,UAAA,UACA,cAAA,EAAgB,aAAA,KACf,aAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"thread-message-like.js","names":["unsupportedRole"],"sources":["../../../src/runtime/utils/thread-message-like.ts"],"sourcesContent":["import { parsePartialJsonObject } from \"assistant-stream/utils\";\nimport { generateId } from \"../../utils/id\";\nimport type {\n ReasoningMessagePart,\n SourceMessagePart,\n ThreadStep,\n MessageStatus,\n ImageMessagePart,\n ThreadMessage,\n ThreadAssistantMessagePart,\n ThreadAssistantMessage,\n ThreadUserMessagePart,\n ThreadUserMessage,\n ThreadSystemMessage,\n FileMessagePart,\n DataMessagePart,\n GenerativeUIMessagePart,\n Unstable_AudioMessagePart,\n} from \"../../types/message\";\nimport type { CompleteAttachment } from \"../../types/attachment\";\nimport type { MessageTiming, TextMessagePart } from \"../../types/message\";\nimport type {\n ReadonlyJSONObject,\n ReadonlyJSONValue,\n} from \"assistant-stream/utils\";\n\ntype DataPrefixedPart = {\n readonly type: `data-${string}`;\n readonly data: any;\n};\n\nexport type ThreadMessageLike = {\n readonly role: \"assistant\" | \"user\" | \"system\";\n readonly content:\n | string\n | readonly (\n | TextMessagePart\n | ReasoningMessagePart\n | SourceMessagePart\n | ImageMessagePart\n | FileMessagePart\n | DataMessagePart\n | GenerativeUIMessagePart\n | Unstable_AudioMessagePart\n | DataPrefixedPart\n | {\n readonly type: \"tool-call\";\n readonly toolCallId?: string;\n readonly toolName: string;\n readonly args?: ReadonlyJSONObject;\n readonly argsText?: string;\n readonly artifact?: any;\n readonly result?: any | undefined;\n readonly isError?: boolean | undefined;\n readonly parentId?: string | undefined;\n readonly messages?: readonly ThreadMessage[] | undefined;\n }\n )[];\n readonly id?: string | undefined;\n readonly createdAt?: Date | undefined;\n readonly status?: MessageStatus | undefined;\n readonly attachments?:\n | readonly (Omit<CompleteAttachment, \"content\"> & {\n readonly content: readonly (ThreadUserMessagePart | DataPrefixedPart)[];\n })[]\n | undefined;\n readonly metadata?:\n | {\n readonly unstable_state?: ReadonlyJSONValue;\n readonly unstable_annotations?:\n | readonly ReadonlyJSONValue[]\n | undefined;\n readonly unstable_data?: readonly ReadonlyJSONValue[] | undefined;\n readonly steps?: readonly ThreadStep[] | undefined;\n readonly timing?: MessageTiming | undefined;\n readonly submittedFeedback?: { readonly type: \"positive\" | \"negative\" };\n readonly custom?: Record<string, unknown> | undefined;\n }\n | undefined;\n};\n\nconst convertDataPrefixedPart = (\n type: string,\n data: unknown,\n): DataMessagePart | undefined => {\n if (!type.startsWith(\"data-\")) return undefined;\n return { type: \"data\", name: type.substring(5), data };\n};\n\nexport const fromThreadMessageLike = (\n like: ThreadMessageLike,\n fallbackId: string,\n fallbackStatus: MessageStatus,\n): ThreadMessage => {\n const { role, id, createdAt, attachments, status, metadata } = like;\n const common = {\n id: id ?? fallbackId,\n createdAt: createdAt ?? new Date(),\n };\n\n const content =\n typeof like.content === \"string\"\n ? [{ type: \"text\" as const, text: like.content }]\n : like.content;\n\n const sanitizeImageContent = ({\n image,\n ...rest\n }: ImageMessagePart): ImageMessagePart | null => {\n const dataUri = image.match(\n /^data:image\\/(png|jpeg|jpg|gif|webp|svg\\+xml);base64,(.*)$/,\n );\n if (dataUri) {\n return { ...rest, image };\n }\n if (/^(https:\\/\\/|blob:)/.test(image)) {\n return { ...rest, image };\n }\n console.warn(`Invalid image data format detected`);\n return null;\n };\n\n if (role !== \"user\" && attachments?.length)\n throw new Error(\"attachments are only supported for user messages\");\n\n if (role !== \"assistant\" && status)\n throw new Error(\"status is only supported for assistant messages\");\n\n if (role !== \"assistant\" && metadata?.steps)\n throw new Error(\"metadata.steps is only supported for assistant messages\");\n\n switch (role) {\n case \"assistant\":\n return {\n ...common,\n role,\n content: content\n .map((part): ThreadAssistantMessagePart | null => {\n const type = part.type;\n switch (type) {\n case \"text\":\n case \"reasoning\":\n if (part.text.trim().length === 0) return null;\n return part;\n\n case \"file\":\n case \"source\":\n return part;\n\n case \"image\":\n return sanitizeImageContent(part);\n\n case \"data\":\n return part;\n\n case \"generative-ui\":\n return part;\n\n case \"tool-call\": {\n const { parentId, messages, ...basePart } = part;\n const commonProps = {\n ...basePart,\n toolCallId: part.toolCallId ?? `tool-${generateId()}`,\n ...(parentId !== undefined && { parentId }),\n ...(messages !== undefined && { messages }),\n };\n\n if (part.args) {\n return {\n ...commonProps,\n args: part.args,\n argsText: part.argsText ?? JSON.stringify(part.args),\n };\n }\n return {\n ...commonProps,\n args: parsePartialJsonObject(part.argsText ?? \"\") ?? {},\n argsText: part.argsText ?? \"\",\n };\n }\n\n default: {\n const converted = convertDataPrefixedPart(\n type,\n (part as DataPrefixedPart).data,\n );\n if (converted) return converted;\n throw new Error(\n `Unsupported assistant message part type: ${type}`,\n );\n }\n }\n })\n .filter((c) => !!c),\n status: status ?? fallbackStatus,\n metadata: {\n unstable_state: metadata?.unstable_state ?? null,\n unstable_annotations: metadata?.unstable_annotations ?? [],\n unstable_data: metadata?.unstable_data ?? [],\n custom: metadata?.custom ?? {},\n steps: metadata?.steps ?? [],\n ...(metadata?.timing && { timing: metadata.timing }),\n ...(metadata?.submittedFeedback && {\n submittedFeedback: metadata.submittedFeedback,\n }),\n },\n } satisfies ThreadAssistantMessage;\n\n case \"user\":\n return {\n ...common,\n role,\n content: content.map((part): ThreadUserMessagePart => {\n const type = part.type;\n switch (type) {\n case \"text\":\n case \"image\":\n case \"audio\":\n case \"file\":\n case \"data\":\n return part;\n\n default: {\n const converted = convertDataPrefixedPart(\n type,\n (part as DataPrefixedPart).data,\n );\n if (converted) return converted;\n throw new Error(`Unsupported user message part type: ${type}`);\n }\n }\n }),\n attachments: (attachments ?? []).map((att) => ({\n ...att,\n content: att.content.map((part): ThreadUserMessagePart => {\n const converted = convertDataPrefixedPart(\n part.type,\n (part as DataPrefixedPart).data,\n );\n return converted ?? (part as ThreadUserMessagePart);\n }),\n })),\n metadata: {\n custom: metadata?.custom ?? {},\n },\n } satisfies ThreadUserMessage;\n\n case \"system\":\n if (content.length !== 1 || content[0]!.type !== \"text\")\n throw new Error(\n \"System messages must have exactly one text message part.\",\n );\n\n return {\n ...common,\n role,\n content: content as [TextMessagePart],\n metadata: {\n custom: metadata?.custom ?? {},\n },\n } satisfies ThreadSystemMessage;\n\n default: {\n const unsupportedRole: never = role;\n throw new Error(`Unknown message role: ${unsupportedRole}`);\n }\n }\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"thread-message-like.js","names":["unsupportedRole"],"sources":["../../../src/runtime/utils/thread-message-like.ts"],"sourcesContent":["import { parsePartialJsonObject } from \"assistant-stream/utils\";\nimport { generateId } from \"../../utils/id\";\nimport type {\n ReasoningMessagePart,\n SourceMessagePart,\n ThreadStep,\n MessageStatus,\n ImageMessagePart,\n ThreadMessage,\n ThreadAssistantMessagePart,\n ThreadAssistantMessage,\n ThreadUserMessagePart,\n ThreadUserMessage,\n ThreadSystemMessage,\n FileMessagePart,\n DataMessagePart,\n GenerativeUIMessagePart,\n Unstable_AudioMessagePart,\n} from \"../../types/message\";\nimport type { CompleteAttachment } from \"../../types/attachment\";\nimport type { MessageTiming, TextMessagePart } from \"../../types/message\";\nimport type {\n ReadonlyJSONObject,\n ReadonlyJSONValue,\n} from \"assistant-stream/utils\";\n\ntype DataPrefixedPart = {\n readonly type: `data-${string}`;\n readonly data: any;\n};\n\nexport type ThreadMessageLike = {\n readonly role: \"assistant\" | \"user\" | \"system\";\n readonly content:\n | string\n | readonly (\n | TextMessagePart\n | ReasoningMessagePart\n | SourceMessagePart\n | ImageMessagePart\n | FileMessagePart\n | DataMessagePart\n | GenerativeUIMessagePart\n | Unstable_AudioMessagePart\n | DataPrefixedPart\n | {\n readonly type: \"tool-call\";\n readonly toolCallId?: string;\n readonly toolName: string;\n readonly args?: ReadonlyJSONObject;\n readonly argsText?: string;\n readonly artifact?: any;\n readonly result?: any | undefined;\n readonly isError?: boolean | undefined;\n readonly parentId?: string | undefined;\n readonly messages?: readonly ThreadMessage[] | undefined;\n readonly interrupt?: { type: \"human\"; payload: unknown };\n readonly approval?: {\n readonly id: string;\n readonly approved?: boolean;\n readonly reason?: string;\n readonly isAutomatic?: boolean;\n };\n }\n )[];\n readonly id?: string | undefined;\n readonly createdAt?: Date | undefined;\n readonly status?: MessageStatus | undefined;\n readonly attachments?:\n | readonly (Omit<CompleteAttachment, \"content\"> & {\n readonly content: readonly (ThreadUserMessagePart | DataPrefixedPart)[];\n })[]\n | undefined;\n readonly metadata?:\n | {\n readonly unstable_state?: ReadonlyJSONValue;\n readonly unstable_annotations?:\n | readonly ReadonlyJSONValue[]\n | undefined;\n readonly unstable_data?: readonly ReadonlyJSONValue[] | undefined;\n readonly steps?: readonly ThreadStep[] | undefined;\n readonly timing?: MessageTiming | undefined;\n readonly submittedFeedback?: { readonly type: \"positive\" | \"negative\" };\n readonly custom?: Record<string, unknown> | undefined;\n }\n | undefined;\n};\n\nconst convertDataPrefixedPart = (\n type: string,\n data: unknown,\n): DataMessagePart | undefined => {\n if (!type.startsWith(\"data-\")) return undefined;\n return { type: \"data\", name: type.substring(5), data };\n};\n\nexport const fromThreadMessageLike = (\n like: ThreadMessageLike,\n fallbackId: string,\n fallbackStatus: MessageStatus,\n): ThreadMessage => {\n const { role, id, createdAt, attachments, status, metadata } = like;\n const common = {\n id: id ?? fallbackId,\n createdAt: createdAt ?? new Date(),\n };\n\n const content =\n typeof like.content === \"string\"\n ? [{ type: \"text\" as const, text: like.content }]\n : like.content;\n\n const sanitizeImageContent = ({\n image,\n ...rest\n }: ImageMessagePart): ImageMessagePart | null => {\n const dataUri = image.match(\n /^data:image\\/(png|jpeg|jpg|gif|webp|svg\\+xml);base64,(.*)$/,\n );\n if (dataUri) {\n return { ...rest, image };\n }\n if (/^(https:\\/\\/|blob:)/.test(image)) {\n return { ...rest, image };\n }\n console.warn(`Invalid image data format detected`);\n return null;\n };\n\n if (role !== \"user\" && attachments?.length)\n throw new Error(\"attachments are only supported for user messages\");\n\n if (role !== \"assistant\" && status)\n throw new Error(\"status is only supported for assistant messages\");\n\n if (role !== \"assistant\" && metadata?.steps)\n throw new Error(\"metadata.steps is only supported for assistant messages\");\n\n switch (role) {\n case \"assistant\":\n return {\n ...common,\n role,\n content: content\n .map((part): ThreadAssistantMessagePart | null => {\n const type = part.type;\n switch (type) {\n case \"text\":\n case \"reasoning\":\n if (part.text.trim().length === 0) return null;\n return part;\n\n case \"file\":\n case \"source\":\n return part;\n\n case \"image\":\n return sanitizeImageContent(part);\n\n case \"data\":\n return part;\n\n case \"generative-ui\":\n return part;\n\n case \"tool-call\": {\n const { parentId, messages, ...basePart } = part;\n const commonProps = {\n ...basePart,\n toolCallId: part.toolCallId ?? `tool-${generateId()}`,\n ...(parentId !== undefined && { parentId }),\n ...(messages !== undefined && { messages }),\n };\n\n if (part.args) {\n return {\n ...commonProps,\n args: part.args,\n argsText: part.argsText ?? JSON.stringify(part.args),\n };\n }\n return {\n ...commonProps,\n args: parsePartialJsonObject(part.argsText ?? \"\") ?? {},\n argsText: part.argsText ?? \"\",\n };\n }\n\n default: {\n const converted = convertDataPrefixedPart(\n type,\n (part as DataPrefixedPart).data,\n );\n if (converted) return converted;\n throw new Error(\n `Unsupported assistant message part type: ${type}`,\n );\n }\n }\n })\n .filter((c) => !!c),\n status: status ?? fallbackStatus,\n metadata: {\n unstable_state: metadata?.unstable_state ?? null,\n unstable_annotations: metadata?.unstable_annotations ?? [],\n unstable_data: metadata?.unstable_data ?? [],\n custom: metadata?.custom ?? {},\n steps: metadata?.steps ?? [],\n ...(metadata?.timing && { timing: metadata.timing }),\n ...(metadata?.submittedFeedback && {\n submittedFeedback: metadata.submittedFeedback,\n }),\n },\n } satisfies ThreadAssistantMessage;\n\n case \"user\":\n return {\n ...common,\n role,\n content: content.map((part): ThreadUserMessagePart => {\n const type = part.type;\n switch (type) {\n case \"text\":\n case \"image\":\n case \"audio\":\n case \"file\":\n case \"data\":\n return part;\n\n default: {\n const converted = convertDataPrefixedPart(\n type,\n (part as DataPrefixedPart).data,\n );\n if (converted) return converted;\n throw new Error(`Unsupported user message part type: ${type}`);\n }\n }\n }),\n attachments: (attachments ?? []).map((att) => ({\n ...att,\n content: att.content.map((part): ThreadUserMessagePart => {\n const converted = convertDataPrefixedPart(\n part.type,\n (part as DataPrefixedPart).data,\n );\n return converted ?? (part as ThreadUserMessagePart);\n }),\n })),\n metadata: {\n custom: metadata?.custom ?? {},\n },\n } satisfies ThreadUserMessage;\n\n case \"system\":\n if (content.length !== 1 || content[0]!.type !== \"text\")\n throw new Error(\n \"System messages must have exactly one text message part.\",\n );\n\n return {\n ...common,\n role,\n content: content as [TextMessagePart],\n metadata: {\n custom: metadata?.custom ?? {},\n },\n } satisfies ThreadSystemMessage;\n\n default: {\n const unsupportedRole: never = role;\n throw new Error(`Unknown message role: ${unsupportedRole}`);\n }\n }\n};\n"],"mappings":"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"}