@assistant-ui/react-ai-sdk 1.3.30 → 1.3.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/dist/assistant-stream/dist/core/tool/schema-utils.d.ts +15 -0
  2. package/dist/assistant-stream/dist/core/tool/schema-utils.d.ts.map +1 -0
  3. package/dist/{packages/assistant-stream → assistant-stream}/dist/core/tool/schema-utils.js +9 -3
  4. package/dist/assistant-stream/dist/core/tool/schema-utils.js.map +1 -0
  5. package/dist/{packages/assistant-stream → assistant-stream}/dist/core/tool/tool-types.d.ts +27 -1
  6. package/dist/assistant-stream/dist/core/tool/tool-types.d.ts.map +1 -0
  7. package/dist/assistant-stream/dist/index.d.ts +2 -0
  8. package/dist/{node_modules → assistant-stream/dist/node_modules}/.pnpm/@types_json-schema@7.0.15/node_modules/@types/json-schema/index.d.ts +4 -5
  9. package/dist/assistant-stream/dist/node_modules/.pnpm/@types_json-schema@7.0.15/node_modules/@types/json-schema/index.d.ts.map +1 -0
  10. package/dist/assistant-stream/dist/resumable/createResumableAssistantStreamResponse.d.ts.map +1 -0
  11. package/dist/assistant-stream/dist/resumable/createResumableAssistantStreamResponse.js.map +1 -0
  12. package/dist/assistant-stream/dist/utils/json/json-value.d.ts.map +1 -0
  13. package/dist/frontendTools.d.ts +33 -6
  14. package/dist/frontendTools.d.ts.map +1 -1
  15. package/dist/frontendTools.js +3 -2
  16. package/dist/frontendTools.js.map +1 -1
  17. package/dist/generativeTools.d.ts +44 -0
  18. package/dist/generativeTools.d.ts.map +1 -0
  19. package/dist/generativeTools.js +55 -0
  20. package/dist/generativeTools.js.map +1 -0
  21. package/dist/index.d.ts +3 -2
  22. package/dist/index.js +3 -2
  23. package/dist/modelContentEnvelope.d.ts +1 -1
  24. package/dist/modelContentEnvelope.d.ts.map +1 -1
  25. package/dist/ui/resumable.d.ts +1 -1
  26. package/dist/ui/resumable.js +1 -1
  27. package/dist/ui/use-chat/AssistantChatTransport.d.ts.map +1 -1
  28. package/dist/ui/use-chat/AssistantChatTransport.js +2 -2
  29. package/dist/ui/use-chat/useAISDKRuntime.d.ts +3 -16
  30. package/dist/ui/use-chat/useAISDKRuntime.d.ts.map +1 -1
  31. package/dist/ui/use-chat/useAISDKRuntime.js +8 -3
  32. package/dist/ui/use-chat/useAISDKRuntime.js.map +1 -1
  33. package/dist/ui/use-chat/useChatRuntime.d.ts +2 -3
  34. package/dist/ui/use-chat/useChatRuntime.d.ts.map +1 -1
  35. package/dist/ui/use-chat/useChatRuntime.js +4 -3
  36. package/dist/ui/use-chat/useChatRuntime.js.map +1 -1
  37. package/dist/ui/use-chat/useExternalHistory.d.ts.map +1 -1
  38. package/dist/ui/use-chat/useExternalHistory.js +16 -8
  39. package/dist/ui/use-chat/useExternalHistory.js.map +1 -1
  40. package/dist/ui/utils/convertMessage.d.ts +3 -2
  41. package/dist/ui/utils/convertMessage.d.ts.map +1 -1
  42. package/dist/ui/utils/convertMessage.js +3 -1
  43. package/dist/ui/utils/convertMessage.js.map +1 -1
  44. package/dist/usage.d.ts.map +1 -1
  45. package/package.json +7 -7
  46. package/src/frontendTools.test.ts +24 -0
  47. package/src/frontendTools.ts +4 -6
  48. package/src/generativeTools.ts +90 -0
  49. package/src/index.ts +4 -0
  50. package/src/ui/use-chat/useAISDKRuntime.test.ts +36 -0
  51. package/src/ui/use-chat/useAISDKRuntime.ts +19 -16
  52. package/src/ui/use-chat/useChatRuntime.ts +22 -21
  53. package/src/ui/use-chat/useExternalHistory.test.ts +60 -1
  54. package/src/ui/use-chat/useExternalHistory.ts +17 -8
  55. package/src/ui/utils/convertMessage.test.ts +25 -0
  56. package/src/ui/utils/convertMessage.ts +6 -0
  57. package/dist/node_modules/.pnpm/@types_json-schema@7.0.15/node_modules/@types/json-schema/index.d.ts.map +0 -1
  58. package/dist/packages/assistant-stream/dist/core/tool/schema-utils.d.ts +0 -1
  59. package/dist/packages/assistant-stream/dist/core/tool/schema-utils.js.map +0 -1
  60. package/dist/packages/assistant-stream/dist/core/tool/tool-types.d.ts.map +0 -1
  61. package/dist/packages/assistant-stream/dist/index.d.ts +0 -1
  62. package/dist/packages/assistant-stream/dist/resumable/createResumableAssistantStreamResponse.d.ts.map +0 -1
  63. package/dist/packages/assistant-stream/dist/resumable/createResumableAssistantStreamResponse.js.map +0 -1
  64. package/dist/packages/assistant-stream/dist/utils/json/json-value.d.ts.map +0 -1
  65. /package/dist/{packages/assistant-stream → assistant-stream}/dist/core/AssistantStream.d.ts +0 -0
  66. /package/dist/{packages/assistant-stream → assistant-stream}/dist/core/AssistantStreamChunk.d.ts +0 -0
  67. /package/dist/{packages/assistant-stream → assistant-stream}/dist/core/accumulators/AssistantMessageStream.d.ts +0 -0
  68. /package/dist/{packages/assistant-stream → assistant-stream}/dist/core/accumulators/assistant-message-accumulator.d.ts +0 -0
  69. /package/dist/{packages/assistant-stream → assistant-stream}/dist/core/modules/assistant-stream.d.ts +0 -0
  70. /package/dist/{packages/assistant-stream → assistant-stream}/dist/core/modules/text.d.ts +0 -0
  71. /package/dist/{packages/assistant-stream → assistant-stream}/dist/core/modules/tool-call.d.ts +0 -0
  72. /package/dist/{packages/assistant-stream → assistant-stream}/dist/core/serialization/PlainText.d.ts +0 -0
  73. /package/dist/{packages/assistant-stream → assistant-stream}/dist/core/serialization/assistant-transport/AssistantTransport.d.ts +0 -0
  74. /package/dist/{packages/assistant-stream → assistant-stream}/dist/core/serialization/data-stream/DataStream.d.ts +0 -0
  75. /package/dist/{packages/assistant-stream → assistant-stream}/dist/core/serialization/ui-message-stream/UIMessageStream.d.ts +0 -0
  76. /package/dist/{packages/assistant-stream → assistant-stream}/dist/core/tool/ToolExecutionStream.d.ts +0 -0
  77. /package/dist/{packages/assistant-stream → assistant-stream}/dist/core/tool/toolResultStream.d.ts +0 -0
  78. /package/dist/{packages/assistant-stream → assistant-stream}/dist/core/utils/stream/AssistantMetaTransformStream.d.ts +0 -0
  79. /package/dist/{packages/assistant-stream → assistant-stream}/dist/core/utils/stream/AssistantTransformStream.d.ts +0 -0
  80. /package/dist/{packages/assistant-stream → assistant-stream}/dist/core/utils/types.d.ts +0 -0
  81. /package/dist/{packages/assistant-stream → assistant-stream}/dist/resumable/createResumableAssistantStreamResponse.d.ts +0 -0
  82. /package/dist/{packages/assistant-stream → assistant-stream}/dist/resumable/createResumableAssistantStreamResponse.js +0 -0
  83. /package/dist/{packages/assistant-stream → assistant-stream}/dist/resumable/index.d.ts +0 -0
  84. /package/dist/{packages/assistant-stream → assistant-stream}/dist/utils/json/json-value.d.ts +0 -0
  85. /package/dist/{packages/assistant-stream → assistant-stream}/dist/utils.d.ts +0 -0
@@ -0,0 +1,15 @@
1
+ import { JSONSchema7 } from "../../node_modules/.pnpm/@types_json-schema@7.0.15/node_modules/@types/json-schema/index.js";
2
+ import { ProviderOptions } from "./tool-types.js";
3
+ //#region ../assistant-stream/dist/core/tool/schema-utils.d.ts
4
+ //#region src/core/tool/schema-utils.d.ts
5
+ /**
6
+ * Type for a tool definition with JSON Schema parameters.
7
+ */
8
+ type ToolJSONSchema = {
9
+ description?: string;
10
+ parameters: JSONSchema7;
11
+ providerOptions?: ProviderOptions;
12
+ };
13
+ //#endregion
14
+ export { ToolJSONSchema };
15
+ //# sourceMappingURL=schema-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-utils.d.ts","names":["description","parameters","JSONSchema7","providerOptions","ProviderOptions","filter","name","Tool","tool","StandardSchemaV1","schema","Record","tools","ToToolsJSONSchemaOptions","options","ToolJSONSchema"],"sources":["../../../../../../assistant-stream/dist/core/tool/schema-utils.d.ts"],"mappings":";;;;AAEyD;;;AAAA,KAMpD,cAAA;EACHA,WAAAA;EACAC,UAAAA,EAAY,WAAA;EACZE,eAAAA,GAAkB,eAAe;AAAA"}
@@ -35,16 +35,22 @@ function defaultToolFilter(_name, tool) {
35
35
  /**
36
36
  * Converts a record of tools to a record of tool definitions with JSON Schema parameters.
37
37
  * By default, filters out disabled tools and backend tools.
38
+ *
39
+ * Entries are emitted in alphabetical order so the resulting request body is
40
+ * byte-identical regardless of the order in which tools were registered. This
41
+ * keeps provider prompt caches stable across renders that mount tools in
42
+ * different orders.
38
43
  */
39
44
  function toToolsJSONSchema(tools, options = {}) {
40
45
  if (!tools) return {};
41
46
  const filter = options.filter ?? defaultToolFilter;
42
- return Object.fromEntries(Object.entries(tools).filter(([name, tool]) => filter(name, tool) && tool.parameters).map(([name, tool]) => [name, {
47
+ return Object.fromEntries(Object.entries(tools).filter(([name, tool]) => filter(name, tool) && tool.parameters).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([name, tool]) => [name, {
43
48
  ...tool.description && { description: tool.description },
44
- parameters: toJSONSchema(tool.parameters)
49
+ parameters: toJSONSchema(tool.parameters),
50
+ ...tool.providerOptions && { providerOptions: tool.providerOptions }
45
51
  }]));
46
52
  }
47
53
  //#endregion
48
- export { toToolsJSONSchema };
54
+ export { toJSONSchema, toToolsJSONSchema };
49
55
 
50
56
  //# sourceMappingURL=schema-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-utils.js","names":[],"sources":["../../../../../../assistant-stream/dist/core/tool/schema-utils.js"],"sourcesContent":["//#region src/core/tool/schema-utils.ts\nfunction isStandardSchema(schema) {\n\treturn typeof schema === \"object\" && schema !== null && \"~standard\" in schema && typeof schema[\"~standard\"] === \"object\";\n}\nfunction hasToJSONSchemaMethod(schema) {\n\treturn typeof schema === \"object\" && schema !== null && \"toJSONSchema\" in schema && typeof schema.toJSONSchema === \"function\";\n}\nfunction hasToJSONMethod(schema) {\n\treturn typeof schema === \"object\" && schema !== null && \"toJSON\" in schema && typeof schema.toJSON === \"function\";\n}\n/**\n* Converts a schema to JSONSchema7.\n* Supports:\n* - StandardSchemaV1 with ~standard.toJSONSchema (e.g., Zod v4)\n* - StandardSchemaV1 with ~standard.jsonSchema.input() (e.g., Zod v4)\n* - Objects with toJSONSchema() method (e.g., Zod v4)\n* - Objects with toJSON() method\n* - Plain JSONSchema7 objects (must have a \"type\" property)\n*/\nfunction toJSONSchema(schema) {\n\tif (isStandardSchema(schema)) {\n\t\tconst toJSONSchemaMethod = schema[\"~standard\"].toJSONSchema;\n\t\tif (typeof toJSONSchemaMethod === \"function\") return toJSONSchemaMethod();\n\t\tconst jsonSchema = schema[\"~standard\"].jsonSchema;\n\t\tif (typeof jsonSchema === \"object\" && jsonSchema !== null && typeof jsonSchema.input === \"function\") return jsonSchema.input();\n\t}\n\tif (hasToJSONSchemaMethod(schema)) return schema.toJSONSchema();\n\tif (hasToJSONMethod(schema)) return schema.toJSON();\n\tif (isStandardSchema(schema)) throw new Error(\"Could not convert schema to JSON Schema. The schema implements Standard Schema but does not support JSON Schema conversion. If you are using Zod, please upgrade to Zod v4 (npm install zod@latest). Alternatively, pass a plain JSON Schema object instead.\");\n\treturn schema;\n}\n/**\n* Returns a copy of the JSON Schema with `required` removed recursively,\n* making every property optional. Array item schemas are left unchanged.\n*/\nfunction toPartialJSONSchema(schema) {\n\tconst { required: _, ...result } = schema;\n\tif (result.properties) result.properties = Object.fromEntries(Object.entries(result.properties).map(([key, prop]) => {\n\t\tif (typeof prop === \"object\" && prop !== null && !Array.isArray(prop)) {\n\t\t\tconst p = prop;\n\t\t\treturn [key, p.properties != null ? toPartialJSONSchema(p) : prop];\n\t\t}\n\t\treturn [key, prop];\n\t}));\n\treturn result;\n}\nfunction defaultToolFilter(_name, tool) {\n\treturn !tool.disabled && tool.type !== \"backend\";\n}\n/**\n* Converts a record of tools to a record of tool definitions with JSON Schema parameters.\n* By default, filters out disabled tools and backend tools.\n*\n* Entries are emitted in alphabetical order so the resulting request body is\n* byte-identical regardless of the order in which tools were registered. This\n* keeps provider prompt caches stable across renders that mount tools in\n* different orders.\n*/\nfunction toToolsJSONSchema(tools, options = {}) {\n\tif (!tools) return {};\n\tconst filter = options.filter ?? defaultToolFilter;\n\treturn Object.fromEntries(Object.entries(tools).filter(([name, tool]) => filter(name, tool) && tool.parameters).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([name, tool]) => [name, {\n\t\t...tool.description && { description: tool.description },\n\t\tparameters: toJSONSchema(tool.parameters),\n\t\t...tool.providerOptions && { providerOptions: tool.providerOptions }\n\t}]));\n}\n//#endregion\nexport { toJSONSchema, toPartialJSONSchema, toToolsJSONSchema };\n\n//# sourceMappingURL=schema-utils.js.map"],"mappings":";AACA,SAAS,iBAAiB,QAAQ;CACjC,OAAO,OAAO,WAAW,YAAY,WAAW,QAAQ,eAAe,UAAU,OAAO,OAAO,iBAAiB;AACjH;AACA,SAAS,sBAAsB,QAAQ;CACtC,OAAO,OAAO,WAAW,YAAY,WAAW,QAAQ,kBAAkB,UAAU,OAAO,OAAO,iBAAiB;AACpH;AACA,SAAS,gBAAgB,QAAQ;CAChC,OAAO,OAAO,WAAW,YAAY,WAAW,QAAQ,YAAY,UAAU,OAAO,OAAO,WAAW;AACxG;;;;;;;;;;AAUA,SAAS,aAAa,QAAQ;CAC7B,IAAI,iBAAiB,MAAM,GAAG;EAC7B,MAAM,qBAAqB,OAAO,aAAa;EAC/C,IAAI,OAAO,uBAAuB,YAAY,OAAO,mBAAmB;EACxE,MAAM,aAAa,OAAO,aAAa;EACvC,IAAI,OAAO,eAAe,YAAY,eAAe,QAAQ,OAAO,WAAW,UAAU,YAAY,OAAO,WAAW,MAAM;CAC9H;CACA,IAAI,sBAAsB,MAAM,GAAG,OAAO,OAAO,aAAa;CAC9D,IAAI,gBAAgB,MAAM,GAAG,OAAO,OAAO,OAAO;CAClD,IAAI,iBAAiB,MAAM,GAAG,MAAM,IAAI,MAAM,8PAA8P;CAC5S,OAAO;AACR;AAgBA,SAAS,kBAAkB,OAAO,MAAM;CACvC,OAAO,CAAC,KAAK,YAAY,KAAK,SAAS;AACxC;;;;;;;;;;AAUA,SAAS,kBAAkB,OAAO,UAAU,CAAC,GAAG;CAC/C,IAAI,CAAC,OAAO,OAAO,CAAC;CACpB,MAAM,SAAS,QAAQ,UAAU;CACjC,OAAO,OAAO,YAAY,OAAO,QAAQ,KAAK,EAAE,QAAQ,CAAC,MAAM,UAAU,OAAO,MAAM,IAAI,KAAK,KAAK,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,CAAC,EAAE,KAAK,CAAC,MAAM,UAAU,CAAC,MAAM;EAC3L,GAAG,KAAK,eAAe,EAAE,aAAa,KAAK,YAAY;EACvD,YAAY,aAAa,KAAK,UAAU;EACxC,GAAG,KAAK,mBAAmB,EAAE,iBAAiB,KAAK,gBAAgB;CACpE,CAAC,CAAC,CAAC;AACJ"}
@@ -38,6 +38,32 @@ type ToolModelContentPart = {
38
38
  * ];
39
39
  * ```
40
40
  */
41
+ /**
42
+ * Per-provider metadata forwarded into the wire request body verbatim.
43
+ * assistant-ui does not interpret these values; downstream adapters (AI SDK,
44
+ * custom routes) pass them to the model provider as-is.
45
+ *
46
+ * The outer key is the provider name (`anthropic`, `openai`, ...); the inner
47
+ * object is whatever shape that provider's SDK expects under
48
+ * `tool.providerOptions[providerName]`. Use this to enable provider-specific
49
+ * tool behaviors such as Anthropic's `defer_loading`
50
+ * (`{ anthropic: { deferLoading: true } }`) without adding provider-aware
51
+ * code in assistant-ui.
52
+ */
53
+ type ProviderOptions = Record<string, Record<string, unknown>>;
54
+ /**
55
+ * Controls how a tool call's UI is presented relative to the assistant's
56
+ * chain-of-thought trace.
57
+ *
58
+ * - `"inline"` — the tool call is part of the reasoning trace and is folded
59
+ * into the chain-of-thought grouping alongside other routine tool calls.
60
+ * - `"standalone"` — the tool call is surfaced on its own, outside the
61
+ * chain-of-thought grouping (e.g. a human-in-the-loop prompt, a generative
62
+ * UI surface, or an important action UI worth showing prominently).
63
+ *
64
+ * This is a client-side presentation hint only; it does not affect how the
65
+ * tool is exposed to or executed by the model.
66
+ */
41
67
  //#endregion
42
- export { ToolModelContentPart };
68
+ export { ProviderOptions, ToolModelContentPart };
43
69
  //# sourceMappingURL=tool-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-types.d.ts","names":["type","text","data","mediaType","filename","TArgs","TResult","toolCallId","input","output","options","ToolModelContentPart","Promise","Record","get","PathT","TypePath","fieldPath","TypeAtPath","streamValues","AsyncIterableStream","DeepPartial","streamText","U","forEach","Array","ToolResponse","args","ToolCallArgsReader","response","ToolCallResponseReader","result","abortSignal","AbortSignal","human","payload","ToolExecutionContext","context","ToolCallReader","reader","ToolExecuteFunction","streamCall","ToolStreamCallFunction","display","ToolDisplay","ToolBase","description","parameters","disabled","execute","toModelOutput","experimental_onSchemaValidationError","providerOptions","StandardSchemaV1","JSONSchema7","ToolModelOutputFunction","OnSchemaValidationErrorFunction","ProviderOptions","FrontendTool","BackendTool","HumanTool","ToolWithoutType","BackendToolDeclaration","Omit"],"sources":["../../../../../../assistant-stream/dist/core/tool/tool-types.d.ts"],"mappings":";;KAOK,oBAAA;EAEMC,4EADmED,IAAAA,UACnEC;EAAAA,SAAAA,IAAAA;AAAAA;EAQAE,4EANmEH,IAAAA;EAOnEI;;AAAQ;AAkGiE;EAlGzEA,SAFAF,IAAAA,UAiHS;EAAA,SAhHTC,SAAAA,UAgHkB;EAAA,SA/GlBC,QAAAA;AAAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA+GN,eAAA,GAAkB,MAAM,SAAS,MAAA"}
@@ -0,0 +1,2 @@
1
+ import { ProviderOptions, ToolModelContentPart } from "./core/tool/tool-types.js";
2
+ import { ToolJSONSchema } from "./core/tool/schema-utils.js";
@@ -1,3 +1,4 @@
1
+ //#region ../assistant-stream/dist/node_modules/.pnpm/@types_json-schema@7.0.15/node_modules/@types/json-schema/index.d.ts
1
2
  //#region ../../node_modules/.pnpm/@types+json-schema@7.0.15/node_modules/@types/json-schema/index.d.ts
2
3
  // ==================================================================================================
3
4
  // JSON Schema Draft 07
@@ -15,12 +16,10 @@ type JSONSchema7TypeName = "string" //
15
16
  * @see https://tools.ietf.org/html/draft-handrews-json-schema-validation-01#section-6.1.1
16
17
  */
17
18
  type JSONSchema7Type = string //
18
- | number | boolean | JSONSchema7Object | JSONSchema7Array | null;
19
- // Workaround for infinite type recursion
19
+ | number | boolean | JSONSchema7Object | JSONSchema7Array | null; // Workaround for infinite type recursion
20
20
  interface JSONSchema7Object {
21
21
  [key: string]: JSONSchema7Type;
22
- }
23
- // Workaround for infinite type recursion
22
+ } // Workaround for infinite type recursion
24
23
  // https://github.com/Microsoft/TypeScript/issues/3496#issuecomment-128553540
25
24
  interface JSONSchema7Array extends Array<JSONSchema7Type> {}
26
25
  /**
@@ -135,7 +134,7 @@ interface JSONSchema7 {
135
134
  readOnly?: boolean | undefined;
136
135
  writeOnly?: boolean | undefined;
137
136
  examples?: JSONSchema7Type | undefined;
138
- }
137
+ } //#endregion
139
138
  //#endregion
140
139
  export { JSONSchema7 };
141
140
  //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","names":["JSONSchema7Object","JSONSchema7Array","key","JSONSchema7Type","Array","JSONSchema7","$id","$ref","$schema","JSONSchema7Version","$comment","$defs","JSONSchema7Definition","type","JSONSchema7TypeName","enum","const","multipleOf","maximum","exclusiveMaximum","minimum","exclusiveMinimum","maxLength","minLength","pattern","items","additionalItems","maxItems","minItems","uniqueItems","contains","maxProperties","minProperties","required","properties","patternProperties","additionalProperties","dependencies","propertyNames","if","then","else","allOf","anyOf","oneOf","not","format","contentMediaType","contentEncoding","definitions","title","description","default","readOnly","writeOnly","examples"],"sources":["../../../../../../../../../../assistant-stream/dist/node_modules/.pnpm/@types_json-schema@7.0.15/node_modules/@types/json-schema/index.d.ts"],"x_google_ignoreList":[0],"mappings":";;;;;;;AAUwB;;;;AAAA,KAAnB,mBAAA;AAAA;;;;AAU2B;KAJ3B,eAAA;AAAA,qBACgB,iBAAA,GAAoB,gBAAgB;AAAA,UAE/C,iBAAA;EAAA,CACPE,GAAAA,WAAc,eAAe;AAAA;AAAA;AAAA,UAItB,gBAAA,SAAyB,KAAK,CAAC,eAAA;AAYlB;AAAA;;;;AAKiB;AAAA;;;;;AALjB,KAAlB,kBAAA;;;;;KAKA,qBAAA,GAAwB,WAAW;AAAA,UAC9B,WAAA;EACRI,GAAAA;EACAC,IAAAA;EACAC,OAAAA,GAAU,kBAAA;EACVE,QAAAA;EAmDiB;;;;EA9CjBC,KAAAA;IAAAA,CACGT,GAAAA,WAAc,qBAAA;EAAA;EA2DT;;;EAtDRW,IAAAA,GAAO,mBAAA,GAAsB,mBAAA;EAC7BE,IAAAA,GAAO,eAAA;EACPC,KAAAA,GAAQ,eAAA;EA6EkB;;;EAzE1BC,UAAAA;EACAC,OAAAA;EACAC,gBAAAA;EACAC,OAAAA;EACAC,gBAAAA;EAfiBT;;;EAmBjBU,SAAAA;EACAC,SAAAA;EACAC,OAAAA;EAdAR;;;EAkBAS,KAAAA,GAAQ,qBAAA,GAAwB,qBAAA;EAChCC,eAAAA,GAAkB,qBAAA;EAClBC,QAAAA;EACAC,QAAAA;EACAC,WAAAA;EACAC,QAAAA,GAAW,qBAAA;EATXN;;;EAaAO,aAAAA;EACAC,aAAAA;EACAC,QAAAA;EACAC,UAAAA;IAAAA,CACGhC,GAAAA,WAAc,qBAAA;EAAA;EAEjBiC,iBAAAA;IAAAA,CACGjC,GAAAA,WAAc,qBAAA;EAAA;EAEjBkC,oBAAAA,GAAuB,qBAAA;EACvBC,YAAAA;IAAAA,CACGnC,GAAAA,WAAc,qBAAA;EAAA;EAEjBoC,aAAAA,GAAgB,qBAAA;EAPhBH;;;EAWAI,EAAAA,GAAK,qBAAA;EACLC,IAAAA,GAAO,qBAAA;EACPC,IAAAA,GAAO,qBAAA;EARJvC;;;EAYHwC,KAAAA,GAAQ,qBAAA;EACRC,KAAAA,GAAQ,qBAAA;EACRC,KAAAA,GAAQ,qBAAA;EACRC,GAAAA,GAAM,qBAAA;EARCjC;;;EAYPkC,MAAAA;EAPQlC;;;EAWRmC,gBAAAA;EACAC,eAAAA;EATAH;;;EAaAI,WAAAA;IAAAA,CACG/C,GAAAA,WAAc,qBAAA;EAAA;EAAdA;;;EAKHgD,KAAAA;EACAC,WAAAA;EACAC,OAAAA,GAAU,eAAA;EACVC,QAAAA;EACAC,SAAAA;EACAC,QAAAA,GAAW,eAAA;AAAA"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createResumableAssistantStreamResponse.d.ts","names":["context","ResumableStreamContext","streamId","callback","AssistantStreamController","controller","PromiseLike","encoder","AssistantStreamEncoder","headers","HeadersInit","CreateResumableAssistantStreamResponseOptions","options","Promise","Response","missingResponse","CreateResumeAssistantStreamResponseOptions"],"sources":["../../../../../assistant-stream/dist/resumable/createResumableAssistantStreamResponse.d.ts"],"mappings":";;cAKc,0BAAA"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createResumableAssistantStreamResponse.js","names":[],"sources":["../../../../../assistant-stream/dist/resumable/createResumableAssistantStreamResponse.js"],"sourcesContent":["import { DataStreamEncoder } from \"../core/serialization/data-stream/DataStream.js\";\nimport { createAssistantStream } from \"../core/modules/assistant-stream.js\";\n//#region src/resumable/createResumableAssistantStreamResponse.ts\nconst RESUMABLE_STREAM_ID_HEADER = \"x-resumable-stream-id\";\nasync function createResumableAssistantStreamResponse(options) {\n\tconst encoder = (options.encoder ?? (() => new DataStreamEncoder()))();\n\tconst stream = await options.context.run(options.streamId, () => {\n\t\treturn createAssistantStream(options.callback).pipeThrough(encoder);\n\t});\n\treturn new Response(stream, { headers: mergeHeaders(encoder.headers, options.headers, options.streamId) });\n}\nasync function createResumeAssistantStreamResponse(options) {\n\tconst stream = await options.context.resume(options.streamId);\n\tif (!stream) return options.missingResponse?.() ?? defaultMissingResponse();\n\tconst encoder = (options.encoder ?? (() => new DataStreamEncoder()))();\n\treturn new Response(stream, { headers: mergeHeaders(encoder.headers, options.headers, options.streamId) });\n}\nfunction defaultMissingResponse() {\n\treturn new Response(JSON.stringify({ error: \"stream not found\" }), {\n\t\tstatus: 404,\n\t\theaders: { \"Content-Type\": \"application/json\" }\n\t});\n}\nfunction mergeHeaders(encoderHeaders, extra, streamId) {\n\tconst merged = new Headers(encoderHeaders ?? {});\n\tif (extra) for (const [key, value] of new Headers(extra)) merged.set(key, value);\n\tmerged.set(RESUMABLE_STREAM_ID_HEADER, streamId);\n\treturn merged;\n}\n//#endregion\nexport { RESUMABLE_STREAM_ID_HEADER, createResumableAssistantStreamResponse, createResumeAssistantStreamResponse };\n\n//# sourceMappingURL=createResumableAssistantStreamResponse.js.map"],"mappings":";AAGA,MAAM,6BAA6B"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json-value.d.ts","names":["ReadonlyJSONObject","ReadonlyJSONArray","key","ReadonlyJSONValue"],"sources":["../../../../../../assistant-stream/dist/utils/json/json-value.d.ts"],"mappings":";;KACK,iBAAA,sCAAuD,kBAAA,GAAqB,iBAAiB;AAAA,KAC7F,kBAAA;EAAA,UACOE,GAAAA,WAAc,iBAAiB;AAAA;AAAA,KAEtC,iBAAA,YAA6B,iBAAiB"}
@@ -1,11 +1,38 @@
1
- import { JSONSchema7 } from "./node_modules/.pnpm/@types_json-schema@7.0.15/node_modules/@types/json-schema/index.js";
1
+ import { ToolJSONSchema } from "./assistant-stream/dist/core/tool/schema-utils.js";
2
2
  import { ToolSet } from "ai";
3
3
 
4
4
  //#region src/frontendTools.d.ts
5
- declare const frontendTools: (tools: Record<string, {
6
- description?: string;
7
- parameters: JSONSchema7;
8
- }>) => ToolSet;
5
+ declare const defaultToModelOutput: ({
6
+ output
7
+ }: {
8
+ output: unknown;
9
+ }) => {
10
+ type: "content";
11
+ value: ({
12
+ type: "text";
13
+ text: string;
14
+ data?: never;
15
+ mediaType?: never;
16
+ } | {
17
+ type: "image-data";
18
+ data: string;
19
+ mediaType: string;
20
+ text?: never;
21
+ } | {
22
+ filename?: string;
23
+ type: "file-data";
24
+ data: string;
25
+ mediaType: string;
26
+ text?: never;
27
+ })[];
28
+ } | {
29
+ type: "text";
30
+ value: string;
31
+ } | {
32
+ type: "json";
33
+ value: any;
34
+ };
35
+ declare const frontendTools: (tools: Record<string, ToolJSONSchema>) => ToolSet;
9
36
  //#endregion
10
- export { frontendTools };
37
+ export { defaultToModelOutput, frontendTools };
11
38
  //# sourceMappingURL=frontendTools.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"frontendTools.d.ts","names":[],"sources":["../src/frontendTools.ts"],"mappings":";;;;cAqCa,aAAA,GACX,KAAA,EAAO,MAAA;EAAiB,WAAA;EAAsB,UAAA,EAAY,WAAA;AAAA,OACzD,OAAA"}
1
+ {"version":3,"file":"frontendTools.d.ts","names":[],"sources":["../src/frontendTools.ts"],"mappings":";;;;cA0Ba,oBAAA;EAAwB;AAAA;EAAc,MAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;cAUtC,aAAA,GAAiB,KAAA,EAAO,MAAA,SAAe,cAAA,MAAkB,OAAA"}
@@ -34,9 +34,10 @@ const defaultToModelOutput = ({ output }) => {
34
34
  const frontendTools = (tools) => Object.fromEntries(Object.entries(tools).map(([name, t]) => [name, {
35
35
  ...t.description !== void 0 && { description: t.description },
36
36
  inputSchema: jsonSchema(t.parameters),
37
- toModelOutput: defaultToModelOutput
37
+ toModelOutput: defaultToModelOutput,
38
+ ...t.providerOptions && { providerOptions: t.providerOptions }
38
39
  }]));
39
40
  //#endregion
40
- export { frontendTools };
41
+ export { defaultToModelOutput, frontendTools };
41
42
 
42
43
  //# sourceMappingURL=frontendTools.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"frontendTools.js","names":[],"sources":["../src/frontendTools.ts"],"sourcesContent":["import { jsonSchema, type ToolSet } from \"ai\";\nimport type { JSONSchema7 } from \"json-schema\";\nimport type { ToolModelContentPart } from \"assistant-stream\";\nimport { unwrapModelContentEnvelope } from \"./modelContentEnvelope\";\n\nconst toAISDKContent = (parts: readonly ToolModelContentPart[]) => ({\n type: \"content\" as const,\n value: parts.map((part) => {\n if (part.type === \"text\") {\n return { type: \"text\" as const, text: part.text };\n }\n const isImage = part.mediaType.startsWith(\"image/\");\n return isImage\n ? {\n type: \"image-data\" as const,\n data: part.data,\n mediaType: part.mediaType,\n }\n : {\n type: \"file-data\" as const,\n data: part.data,\n mediaType: part.mediaType,\n ...(part.filename !== undefined && { filename: part.filename }),\n };\n }),\n});\n\nconst defaultToModelOutput = ({ output }: { output: unknown }) => {\n const { modelContent } = unwrapModelContentEnvelope(output);\n if (modelContent !== undefined) {\n return toAISDKContent(modelContent);\n }\n return typeof output === \"string\"\n ? { type: \"text\" as const, value: output }\n : { type: \"json\" as const, value: (output ?? null) as any };\n};\n\nexport const frontendTools = (\n tools: Record<string, { description?: string; parameters: JSONSchema7 }>,\n): ToolSet =>\n Object.fromEntries(\n Object.entries(tools).map(([name, t]) => [\n name,\n {\n ...(t.description !== undefined && { description: t.description }),\n inputSchema: jsonSchema(t.parameters),\n toModelOutput: defaultToModelOutput,\n },\n ]),\n ) as ToolSet;\n"],"mappings":";;;AAKA,MAAM,kBAAkB,WAA4C;CAClE,MAAM;CACN,OAAO,MAAM,KAAK,SAAS;EACzB,IAAI,KAAK,SAAS,QAChB,OAAO;GAAE,MAAM;GAAiB,MAAM,KAAK;EAAK;EAGlD,OADgB,KAAK,UAAU,WAAW,QAC7B,IACT;GACE,MAAM;GACN,MAAM,KAAK;GACX,WAAW,KAAK;EAClB,IACA;GACE,MAAM;GACN,MAAM,KAAK;GACX,WAAW,KAAK;GAChB,GAAI,KAAK,aAAa,KAAA,KAAa,EAAE,UAAU,KAAK,SAAS;EAC/D;CACN,CAAC;AACH;AAEA,MAAM,wBAAwB,EAAE,aAAkC;CAChE,MAAM,EAAE,iBAAiB,2BAA2B,MAAM;CAC1D,IAAI,iBAAiB,KAAA,GACnB,OAAO,eAAe,YAAY;CAEpC,OAAO,OAAO,WAAW,WACrB;EAAE,MAAM;EAAiB,OAAO;CAAO,IACvC;EAAE,MAAM;EAAiB,OAAQ,UAAU;CAAa;AAC9D;AAEA,MAAa,iBACX,UAEA,OAAO,YACL,OAAO,QAAQ,KAAK,EAAE,KAAK,CAAC,MAAM,OAAO,CACvC,MACA;CACE,GAAI,EAAE,gBAAgB,KAAA,KAAa,EAAE,aAAa,EAAE,YAAY;CAChE,aAAa,WAAW,EAAE,UAAU;CACpC,eAAe;AACjB,CACF,CAAC,CACH"}
1
+ {"version":3,"file":"frontendTools.js","names":[],"sources":["../src/frontendTools.ts"],"sourcesContent":["import { jsonSchema, type ToolSet } from \"ai\";\nimport type { ToolJSONSchema, ToolModelContentPart } from \"assistant-stream\";\nimport { unwrapModelContentEnvelope } from \"./modelContentEnvelope\";\n\nconst toAISDKContent = (parts: readonly ToolModelContentPart[]) => ({\n type: \"content\" as const,\n value: parts.map((part) => {\n if (part.type === \"text\") {\n return { type: \"text\" as const, text: part.text };\n }\n const isImage = part.mediaType.startsWith(\"image/\");\n return isImage\n ? {\n type: \"image-data\" as const,\n data: part.data,\n mediaType: part.mediaType,\n }\n : {\n type: \"file-data\" as const,\n data: part.data,\n mediaType: part.mediaType,\n ...(part.filename !== undefined && { filename: part.filename }),\n };\n }),\n});\n\nexport const defaultToModelOutput = ({ output }: { output: unknown }) => {\n const { modelContent } = unwrapModelContentEnvelope(output);\n if (modelContent !== undefined) {\n return toAISDKContent(modelContent);\n }\n return typeof output === \"string\"\n ? { type: \"text\" as const, value: output }\n : { type: \"json\" as const, value: (output ?? null) as any };\n};\n\nexport const frontendTools = (tools: Record<string, ToolJSONSchema>): ToolSet =>\n Object.fromEntries(\n Object.entries(tools).map(([name, t]) => [\n name,\n {\n ...(t.description !== undefined && { description: t.description }),\n inputSchema: jsonSchema(t.parameters),\n toModelOutput: defaultToModelOutput,\n ...(t.providerOptions && { providerOptions: t.providerOptions }),\n },\n ]),\n ) as ToolSet;\n"],"mappings":";;;AAIA,MAAM,kBAAkB,WAA4C;CAClE,MAAM;CACN,OAAO,MAAM,KAAK,SAAS;EACzB,IAAI,KAAK,SAAS,QAChB,OAAO;GAAE,MAAM;GAAiB,MAAM,KAAK;EAAK;EAGlD,OADgB,KAAK,UAAU,WAAW,QAC7B,IACT;GACE,MAAM;GACN,MAAM,KAAK;GACX,WAAW,KAAK;EAClB,IACA;GACE,MAAM;GACN,MAAM,KAAK;GACX,WAAW,KAAK;GAChB,GAAI,KAAK,aAAa,KAAA,KAAa,EAAE,UAAU,KAAK,SAAS;EAC/D;CACN,CAAC;AACH;AAEA,MAAa,wBAAwB,EAAE,aAAkC;CACvE,MAAM,EAAE,iBAAiB,2BAA2B,MAAM;CAC1D,IAAI,iBAAiB,KAAA,GACnB,OAAO,eAAe,YAAY;CAEpC,OAAO,OAAO,WAAW,WACrB;EAAE,MAAM;EAAiB,OAAO;CAAO,IACvC;EAAE,MAAM;EAAiB,OAAQ,UAAU;CAAa;AAC9D;AAEA,MAAa,iBAAiB,UAC5B,OAAO,YACL,OAAO,QAAQ,KAAK,EAAE,KAAK,CAAC,MAAM,OAAO,CACvC,MACA;CACE,GAAI,EAAE,gBAAgB,KAAA,KAAa,EAAE,aAAa,EAAE,YAAY;CAChE,aAAa,WAAW,EAAE,UAAU;CACpC,eAAe;CACf,GAAI,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,gBAAgB;AAChE,CACF,CAAC,CACH"}
@@ -0,0 +1,44 @@
1
+ import { ToolJSONSchema } from "./assistant-stream/dist/core/tool/schema-utils.js";
2
+ import { ToolSet } from "ai";
3
+ import { Toolkit } from "@assistant-ui/core/react";
4
+
5
+ //#region src/generativeTools.d.ts
6
+ interface GenerativeToolsOptions {
7
+ /**
8
+ * The server build of a generative toolkit (schema + server `execute`). Typed
9
+ * as the canonical {@link Toolkit} so callers don't need to cast; the server
10
+ * build carries `execute`, recovered internally as {@link ToolkitDeclaration}.
11
+ */
12
+ toolkit: Toolkit;
13
+ /**
14
+ * Tools uploaded by the frontend (the request body's `tools`). Merged in
15
+ * alongside the `toolkit`; a server `execute` from `toolkit` takes precedence
16
+ * over an uploaded entry of the same name.
17
+ */
18
+ frontendTools?: Record<string, ToolJSONSchema>;
19
+ }
20
+ /**
21
+ * Builds an AI SDK `ToolSet` for server-side use with `streamText` /
22
+ * `generateText` from a generative `toolkit` and the frontend-uploaded tools.
23
+ *
24
+ * Each toolkit tool's `execute` runs on the server. Pair this with the
25
+ * `"use generative"` compiler: import the toolkit in a server route (where it
26
+ * resolves to the server build — schema + `execute`, with `render` stripped) and
27
+ * pass it here. Tools without an `execute` are still exposed to the model but
28
+ * left for the client to fulfill. `frontendTools` lets the client contribute
29
+ * tools that aren't in the static toolkit.
30
+ *
31
+ * @example
32
+ * ```ts
33
+ * const { tools } = await req.json();
34
+ * streamText({
35
+ * model,
36
+ * messages,
37
+ * tools: generativeTools({ toolkit: docsToolkit, frontendTools: tools }),
38
+ * });
39
+ * ```
40
+ */
41
+ declare const generativeTools: (options: GenerativeToolsOptions) => ToolSet;
42
+ //#endregion
43
+ export { GenerativeToolsOptions, generativeTools };
44
+ //# sourceMappingURL=generativeTools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generativeTools.d.ts","names":[],"sources":["../src/generativeTools.ts"],"mappings":";;;;;UAgBiB,sBAAA;;;AAAjB;;;EAME,OAAA,EAAS,OAAA;EAMsB;;;;;EAA/B,aAAA,GAAgB,MAAA,SAAe,cAAA;AAAA;;;;AAAc;AAwB/C;;;;;;;;AAME;;;;;;;;;cANW,eAAA,GAAmB,OAAA,EAAS,sBAAA,KAAyB,OAMhE"}
@@ -0,0 +1,55 @@
1
+ import { defaultToModelOutput, frontendTools } from "./frontendTools.js";
2
+ import { toJSONSchema } from "./assistant-stream/dist/core/tool/schema-utils.js";
3
+ import { jsonSchema } from "ai";
4
+ //#region src/generativeTools.ts
5
+ const EMPTY_SCHEMA = {
6
+ type: "object",
7
+ properties: {}
8
+ };
9
+ const humanNotSupported = () => {
10
+ throw new Error("`human()` is not available during server-side tool execution.");
11
+ };
12
+ const neverAbort = new AbortController().signal;
13
+ /**
14
+ * Builds an AI SDK `ToolSet` for server-side use with `streamText` /
15
+ * `generateText` from a generative `toolkit` and the frontend-uploaded tools.
16
+ *
17
+ * Each toolkit tool's `execute` runs on the server. Pair this with the
18
+ * `"use generative"` compiler: import the toolkit in a server route (where it
19
+ * resolves to the server build — schema + `execute`, with `render` stripped) and
20
+ * pass it here. Tools without an `execute` are still exposed to the model but
21
+ * left for the client to fulfill. `frontendTools` lets the client contribute
22
+ * tools that aren't in the static toolkit.
23
+ *
24
+ * @example
25
+ * ```ts
26
+ * const { tools } = await req.json();
27
+ * streamText({
28
+ * model,
29
+ * messages,
30
+ * tools: generativeTools({ toolkit: docsToolkit, frontendTools: tools }),
31
+ * });
32
+ * ```
33
+ */
34
+ const generativeTools = (options) => ({
35
+ ...options.frontendTools ? frontendTools(options.frontendTools) : {},
36
+ ...toServerToolSet(options.toolkit)
37
+ });
38
+ const toServerToolSet = (toolkit) => Object.fromEntries(Object.entries(toolkit).filter(([, t]) => !t.disabled).map(([name, t]) => {
39
+ const execute = t.execute;
40
+ return [name, {
41
+ ...t.description !== void 0 && { description: t.description },
42
+ inputSchema: jsonSchema(t.parameters ? toJSONSchema(t.parameters) : EMPTY_SCHEMA),
43
+ toModelOutput: t.toModelOutput ?? defaultToModelOutput,
44
+ ...t.providerOptions && { providerOptions: t.providerOptions },
45
+ ...execute && { execute: (args, callOptions) => execute(args, {
46
+ toolCallId: callOptions.toolCallId,
47
+ abortSignal: callOptions.abortSignal ?? neverAbort,
48
+ human: humanNotSupported
49
+ }) }
50
+ }];
51
+ }));
52
+ //#endregion
53
+ export { generativeTools };
54
+
55
+ //# sourceMappingURL=generativeTools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generativeTools.js","names":[],"sources":["../src/generativeTools.ts"],"sourcesContent":["import { jsonSchema, type ToolSet } from \"ai\";\nimport { toJSONSchema, type ToolJSONSchema } from \"assistant-stream\";\nimport type { Toolkit, ToolkitDeclaration } from \"@assistant-ui/core/react\";\nimport { defaultToModelOutput, frontendTools } from \"./frontendTools\";\n\nconst EMPTY_SCHEMA = { type: \"object\" as const, properties: {} };\n\nconst humanNotSupported = (): never => {\n throw new Error(\n \"`human()` is not available during server-side tool execution.\",\n );\n};\n\n// AI SDK leaves `abortSignal` optional; assistant-ui's execute requires one.\nconst neverAbort = new AbortController().signal;\n\nexport interface GenerativeToolsOptions {\n /**\n * The server build of a generative toolkit (schema + server `execute`). Typed\n * as the canonical {@link Toolkit} so callers don't need to cast; the server\n * build carries `execute`, recovered internally as {@link ToolkitDeclaration}.\n */\n toolkit: Toolkit;\n /**\n * Tools uploaded by the frontend (the request body's `tools`). Merged in\n * alongside the `toolkit`; a server `execute` from `toolkit` takes precedence\n * over an uploaded entry of the same name.\n */\n frontendTools?: Record<string, ToolJSONSchema>;\n}\n\n/**\n * Builds an AI SDK `ToolSet` for server-side use with `streamText` /\n * `generateText` from a generative `toolkit` and the frontend-uploaded tools.\n *\n * Each toolkit tool's `execute` runs on the server. Pair this with the\n * `\"use generative\"` compiler: import the toolkit in a server route (where it\n * resolves to the server build — schema + `execute`, with `render` stripped) and\n * pass it here. Tools without an `execute` are still exposed to the model but\n * left for the client to fulfill. `frontendTools` lets the client contribute\n * tools that aren't in the static toolkit.\n *\n * @example\n * ```ts\n * const { tools } = await req.json();\n * streamText({\n * model,\n * messages,\n * tools: generativeTools({ toolkit: docsToolkit, frontendTools: tools }),\n * });\n * ```\n */\nexport const generativeTools = (options: GenerativeToolsOptions): ToolSet => ({\n ...(options.frontendTools ? frontendTools(options.frontendTools) : {}),\n // `toolkit` last so its server-side `execute` wins over an uploaded entry of\n // the same name. The cast recovers the declaration shape — the server build\n // carries `execute`, which the canonical `Toolkit` type erases.\n ...toServerToolSet(options.toolkit as ToolkitDeclaration),\n});\n\nconst toServerToolSet = (toolkit: ToolkitDeclaration): ToolSet =>\n Object.fromEntries(\n Object.entries(toolkit)\n .filter(([, t]) => !t.disabled)\n .map(([name, t]) => {\n const execute = t.execute;\n return [\n name,\n {\n ...(t.description !== undefined && { description: t.description }),\n inputSchema: jsonSchema(\n t.parameters ? toJSONSchema(t.parameters) : EMPTY_SCHEMA,\n ),\n toModelOutput: t.toModelOutput ?? defaultToModelOutput,\n ...(t.providerOptions && { providerOptions: t.providerOptions }),\n ...(execute && {\n execute: (\n args: unknown,\n callOptions: { toolCallId: string; abortSignal?: AbortSignal },\n ) =>\n execute(args as never, {\n toolCallId: callOptions.toolCallId,\n abortSignal: callOptions.abortSignal ?? neverAbort,\n human: humanNotSupported,\n }),\n }),\n },\n ];\n }),\n ) as ToolSet;\n"],"mappings":";;;;AAKA,MAAM,eAAe;CAAE,MAAM;CAAmB,YAAY,CAAC;AAAE;AAE/D,MAAM,0BAAiC;CACrC,MAAM,IAAI,MACR,+DACF;AACF;AAGA,MAAM,aAAa,IAAI,gBAAgB,EAAE;;;;;;;;;;;;;;;;;;;;;;AAsCzC,MAAa,mBAAmB,aAA8C;CAC5E,GAAI,QAAQ,gBAAgB,cAAc,QAAQ,aAAa,IAAI,CAAC;CAIpE,GAAG,gBAAgB,QAAQ,OAA6B;AAC1D;AAEA,MAAM,mBAAmB,YACvB,OAAO,YACL,OAAO,QAAQ,OAAO,EACnB,QAAQ,GAAG,OAAO,CAAC,EAAE,QAAQ,EAC7B,KAAK,CAAC,MAAM,OAAO;CAClB,MAAM,UAAU,EAAE;CAClB,OAAO,CACL,MACA;EACE,GAAI,EAAE,gBAAgB,KAAA,KAAa,EAAE,aAAa,EAAE,YAAY;EAChE,aAAa,WACX,EAAE,aAAa,aAAa,EAAE,UAAU,IAAI,YAC9C;EACA,eAAe,EAAE,iBAAiB;EAClC,GAAI,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,gBAAgB;EAC9D,GAAI,WAAW,EACb,UACE,MACA,gBAEA,QAAQ,MAAe;GACrB,YAAY,YAAY;GACxB,aAAa,YAAY,eAAe;GACxC,OAAO;EACT,CAAC,EACL;CACF,CACF;AACF,CAAC,CACL"}
package/dist/index.d.ts CHANGED
@@ -1,10 +1,11 @@
1
1
  /// <reference types="@assistant-ui/core/react" />
2
2
  import { frontendTools } from "./frontendTools.js";
3
+ import { GenerativeToolsOptions, generativeTools } from "./generativeTools.js";
3
4
  import { useAISDKRuntime } from "./ui/use-chat/useAISDKRuntime.js";
4
5
  import { UseChatRuntimeOptions, useChatRuntime } from "./ui/use-chat/useChatRuntime.js";
5
- import { RESUMABLE_STREAM_ID_HEADER } from "./packages/assistant-stream/dist/resumable/createResumableAssistantStreamResponse.js";
6
+ import { RESUMABLE_STREAM_ID_HEADER } from "./assistant-stream/dist/resumable/createResumableAssistantStreamResponse.js";
6
7
  import { AssistantChatResumableOptions, ResumableClientStorage, createResumableSessionStorage } from "./ui/resumable.js";
7
8
  import { AssistantChatTransport } from "./ui/use-chat/AssistantChatTransport.js";
8
9
  import { injectQuoteContext } from "./injectQuoteContext.js";
9
10
  import { ThreadTokenUsage, TokenUsageExtractableMessage, getThreadMessageTokenUsage, useThreadTokenUsage } from "./usage.js";
10
- export { type AssistantChatResumableOptions, AssistantChatTransport, RESUMABLE_STREAM_ID_HEADER, type ResumableClientStorage, type ThreadTokenUsage, type TokenUsageExtractableMessage, type UseChatRuntimeOptions, createResumableSessionStorage, frontendTools, getThreadMessageTokenUsage, injectQuoteContext, useAISDKRuntime, useChatRuntime, useThreadTokenUsage };
11
+ export { type AssistantChatResumableOptions, AssistantChatTransport, type GenerativeToolsOptions, RESUMABLE_STREAM_ID_HEADER, type ResumableClientStorage, type ThreadTokenUsage, type TokenUsageExtractableMessage, type UseChatRuntimeOptions, createResumableSessionStorage, frontendTools, generativeTools, getThreadMessageTokenUsage, injectQuoteContext, useAISDKRuntime, useChatRuntime, useThreadTokenUsage };
package/dist/index.js CHANGED
@@ -1,9 +1,10 @@
1
1
  import { frontendTools } from "./frontendTools.js";
2
+ import { generativeTools } from "./generativeTools.js";
2
3
  import { useAISDKRuntime } from "./ui/use-chat/useAISDKRuntime.js";
3
- import { RESUMABLE_STREAM_ID_HEADER } from "./packages/assistant-stream/dist/resumable/createResumableAssistantStreamResponse.js";
4
+ import { RESUMABLE_STREAM_ID_HEADER } from "./assistant-stream/dist/resumable/createResumableAssistantStreamResponse.js";
4
5
  import { createResumableSessionStorage } from "./ui/resumable.js";
5
6
  import { AssistantChatTransport } from "./ui/use-chat/AssistantChatTransport.js";
6
7
  import { useChatRuntime } from "./ui/use-chat/useChatRuntime.js";
7
8
  import { injectQuoteContext } from "./injectQuoteContext.js";
8
9
  import { getThreadMessageTokenUsage, useThreadTokenUsage } from "./usage.js";
9
- export { AssistantChatTransport, RESUMABLE_STREAM_ID_HEADER, createResumableSessionStorage, frontendTools, getThreadMessageTokenUsage, injectQuoteContext, useAISDKRuntime, useChatRuntime, useThreadTokenUsage };
10
+ export { AssistantChatTransport, RESUMABLE_STREAM_ID_HEADER, createResumableSessionStorage, frontendTools, generativeTools, getThreadMessageTokenUsage, injectQuoteContext, useAISDKRuntime, useChatRuntime, useThreadTokenUsage };
@@ -1,4 +1,4 @@
1
- import { ToolModelContentPart } from "./packages/assistant-stream/dist/core/tool/tool-types.js";
1
+ import { ToolModelContentPart } from "./assistant-stream/dist/core/tool/tool-types.js";
2
2
  //#region src/modelContentEnvelope.d.ts
3
3
  declare const ENVELOPE_KEY = "__aui_modelContent";
4
4
  type ModelContentEnvelope<TResult = unknown> = {
@@ -1 +1 @@
1
- {"version":3,"file":"modelContentEnvelope.d.ts","names":[],"sources":["../src/modelContentEnvelope.ts"],"mappings":";;cAEM,YAAA;AAAA,KAEM,oBAAA;EAAA,UACA,YAAA,YAAwB,oBAAA;EAAA,SACzB,KAAA,EAAO,OAAA;AAAA;AAAA,iBAGF,sBAAA,CACd,KAAA,YACC,KAAA,IAAS,oBAAoB;AAAA,iBAShB,wBAAA,SAAA,CACd,MAAA,EAAQ,OAAA,EACR,YAAA,WAAuB,oBAAA,KACtB,oBAAA,CAAqB,OAAA;AAAA,iBAIR,0BAAA,CAA2B,MAAA;EACzC,MAAA;EACA,YAAA,YAAwB,oBAAoB;AAAA"}
1
+ {"version":3,"file":"modelContentEnvelope.d.ts","names":[],"sources":["../src/modelContentEnvelope.ts"],"mappings":";;cAEM,YAAA;AAAA,KAEM,oBAAA;EAAA,UACA,YAAA,YAAwB,oBAAA;EAAA,SACzB,KAAA,EAAO,OAAA;AAAA;AAAA,iBAGF,sBAAA,CACd,KAAA,YACC,KAAA,IAAS,oBAAoB;AAAA,iBAShB,wBAAA,UACd,MAAA,EAAQ,OAAA,EACR,YAAA,WAAuB,oBAAA,KACtB,oBAAA,CAAqB,OAAA;AAAA,iBAIR,0BAAA,CAA2B,MAAA;EACzC,MAAA;EACA,YAAA,YAAwB,oBAAoB;AAAA"}
@@ -1,4 +1,4 @@
1
- import { RESUMABLE_STREAM_ID_HEADER } from "../packages/assistant-stream/dist/resumable/createResumableAssistantStreamResponse.js";
1
+ import { RESUMABLE_STREAM_ID_HEADER } from "../assistant-stream/dist/resumable/createResumableAssistantStreamResponse.js";
2
2
  //#region src/ui/resumable.d.ts
3
3
  type ResumableClientStorage = {
4
4
  getStreamId(): string | null;
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { RESUMABLE_STREAM_ID_HEADER } from "../packages/assistant-stream/dist/resumable/createResumableAssistantStreamResponse.js";
2
+ import { RESUMABLE_STREAM_ID_HEADER } from "../assistant-stream/dist/resumable/createResumableAssistantStreamResponse.js";
3
3
  //#region src/ui/resumable.ts
4
4
  const DEFAULT_STORAGE_KEY = "aui-resumable-stream-id";
5
5
  /** `sessionStorage`-backed storage for the pending resumable stream id. */
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantChatTransport.d.ts","names":[],"sources":["../../../src/ui/use-chat/AssistantChatTransport.ts"],"mappings":";;;;;KAeK,2BAAA,GAA8B,IAAI,CAAC,qBAAA;AAAA,KAM5B,iCAAA,oBAAqD,SAAA,IAC/D,4BAAA,CAA6B,UAAA;EAC3B,SAAA,GAAY,6BAAA;AAAA;AAAA,cAGH,sBAAA,oBACQ,SAAA,UACX,oBAAA,CAAqB,UAAA;EAAA,QACrB,OAAA;EAAA,QACA,iBAAA;EAAA,iBAGS,SAAA;cAEL,WAAA,GAAc,iCAAA,CAAkC,UAAA;EAkD5D,UAAA,CAAW,OAAA,EAAS,gBAAA;EAIpB,mBAAA,CAAA,GAAuB,6BAAA;EAIvB,+BAAA,CACE,MAAA,QAAc,2BAAA;AAAA"}
1
+ {"version":3,"file":"AssistantChatTransport.d.ts","names":[],"sources":["../../../src/ui/use-chat/AssistantChatTransport.ts"],"mappings":";;;;;KAeK,2BAAA,GAA8B,IAAI,CAAC,qBAAA;AAAA,KAM5B,iCAAA,oBAAqD,SAAA,IAC/D,4BAAA,CAA6B,UAAA;EAC3B,SAAA,GAAY,6BAAA;AAAA;AAAA,cAGH,sBAAA,oBACQ,SAAA,UACX,oBAAA,CAAqB,UAAA;EAAA,QACrB,OAAA;EAAA,QACA,iBAAA;EAAA,iBAGS,SAAA;cAEL,WAAA,GAAc,iCAAA,CAAkC,UAAA;EAkD5D,UAAA,CAAW,OAAA,EAAS,gBAAA;EAIpB,mBAAA,IAAuB,6BAAA;EAIvB,+BAAA,CACE,MAAA,QAAc,2BAAA;AAAA"}
@@ -1,5 +1,5 @@
1
- import { toToolsJSONSchema } from "../../packages/assistant-stream/dist/core/tool/schema-utils.js";
2
- import { RESUMABLE_STREAM_ID_HEADER } from "../../packages/assistant-stream/dist/resumable/createResumableAssistantStreamResponse.js";
1
+ import { toToolsJSONSchema } from "../../assistant-stream/dist/core/tool/schema-utils.js";
2
+ import { RESUMABLE_STREAM_ID_HEADER } from "../../assistant-stream/dist/resumable/createResumableAssistantStreamResponse.js";
3
3
  import { DefaultChatTransport } from "ai";
4
4
  //#region src/ui/use-chat/AssistantChatTransport.ts
5
5
  const FINISH_MARKER = "\"type\":\"finish\"";
@@ -1,9 +1,9 @@
1
- import { AppendMessage, AssistantRuntime, ExternalStoreAdapter, ThreadHistoryAdapter, ThreadSuggestion } from "@assistant-ui/core";
1
+ import { AppendMessage, AssistantRuntime, ExternalStoreAdapter, ExternalStoreSharedOptions, ThreadHistoryAdapter } from "@assistant-ui/core";
2
2
  import { CreateUIMessage, UIMessage, useChat } from "@ai-sdk/react";
3
3
 
4
4
  //#region src/ui/use-chat/useAISDKRuntime.d.ts
5
5
  type CustomToCreateMessageFunction = <UI_MESSAGE extends UIMessage = UIMessage>(message: AppendMessage) => CreateUIMessage<UI_MESSAGE>;
6
- type AISDKRuntimeAdapter = {
6
+ type AISDKRuntimeAdapter = ExternalStoreSharedOptions & {
7
7
  adapters?: (NonNullable<ExternalStoreAdapter["adapters"]> & {
8
8
  history?: ThreadHistoryAdapter | undefined;
9
9
  }) | undefined;
@@ -25,21 +25,8 @@ type AISDKRuntimeAdapter = {
25
25
  * (for example, an SSE reconnect endpoint keyed by turn id).
26
26
  */
27
27
  onResume?: ExternalStoreAdapter["onResume"];
28
- /**
29
- * Follow up suggestions to surface on the thread. Use this to drive
30
- * dynamic suggestions from application state, tool results, or backend
31
- * responses; flows into `thread.suggestions` and is rendered by
32
- * components that read it (such as the shadcn `ThreadFollowupSuggestions`).
33
- */
34
- suggestions?: readonly ThreadSuggestion[] | undefined;
35
28
  };
36
- declare const useAISDKRuntime: <UI_MESSAGE extends UIMessage = UIMessage>(chatHelpers: ReturnType<typeof useChat<UI_MESSAGE>>, {
37
- adapters,
38
- toCreateMessage: customToCreateMessage,
39
- cancelPendingToolCallsOnSend,
40
- onResume,
41
- suggestions
42
- }?: AISDKRuntimeAdapter) => AssistantRuntime;
29
+ declare const useAISDKRuntime: <UI_MESSAGE extends UIMessage = UIMessage>(chatHelpers: ReturnType<typeof useChat<UI_MESSAGE>>, adapter?: AISDKRuntimeAdapter) => AssistantRuntime;
43
30
  //#endregion
44
31
  export { AISDKRuntimeAdapter, CustomToCreateMessageFunction, useAISDKRuntime };
45
32
  //# sourceMappingURL=useAISDKRuntime.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useAISDKRuntime.d.ts","names":[],"sources":["../../../src/ui/use-chat/useAISDKRuntime.ts"],"mappings":";;;;KAyCY,6BAAA,uBACS,SAAA,GAAY,SAAA,EAE/B,OAAA,EAAS,aAAA,KACN,eAAA,CAAgB,UAAA;AAAA,KAYT,mBAAA;EACV,QAAA,IACK,WAAA,CAAY,oBAAA;IACX,OAAA,GAAU,oBAAA;EAAA;EAGhB,eAAA,GAAkB,6BAAA;EArBa;;;;;;;;EA8B/B,4BAAA;EA5BS;;;;;AACoB;AAY/B;EAuBE,QAAA,GAAW,oBAAA;;;;;;;EAOX,WAAA,YAAuB,gBAAA;AAAA;AAAA,cAGZ,eAAA,sBAAsC,SAAA,GAAY,SAAA,EAC7D,WAAA,EAAa,UAAA,QAAkB,OAAA,CAAQ,UAAA;EACvC,QAAA;EAAA,eAAA,EAAA,qBAAA;EAAA,4BAAA;EAAA,QAAA;EAAA;AAAA,IAMG,mBAAA,KAAwB,gBAAA"}
1
+ {"version":3,"file":"useAISDKRuntime.d.ts","names":[],"sources":["../../../src/ui/use-chat/useAISDKRuntime.ts"],"mappings":";;;;KA4CY,6BAAA,uBACS,SAAA,GAAY,SAAA,EAE/B,OAAA,EAAS,aAAA,KACN,eAAA,CAAgB,UAAA;AAAA,KAYT,mBAAA,GAAsB,0BAAA;EAChC,QAAA,IACK,WAAA,CAAY,oBAAA;IACX,OAAA,GAAU,oBAAA;EAAA;EAGhB,eAAA,GAAkB,6BAAA;EArBa;;;;;;;;EA8B/B,4BAAA;EA5BS;;;;;AACoB;AAY/B;EAuBE,QAAA,GAAW,oBAAA;AAAA;AAAA,cAGA,eAAA,sBAAsC,SAAA,GAAY,SAAA,EAC7D,WAAA,EAAa,UAAA,QAAkB,OAAA,CAAQ,UAAA,IACvC,OAAA,GAAS,mBAAA,KAAwB,gBAAA"}
@@ -11,14 +11,15 @@ import { useStreamingTiming } from "./useStreamingTiming.js";
11
11
  import { generateId, isToolUIPart } from "ai";
12
12
  import { useMemo, useRef, useState } from "react";
13
13
  import { useExternalStoreRuntime, useRuntimeAdapters } from "@assistant-ui/core/react";
14
- import { getExternalStoreMessages } from "@assistant-ui/core";
14
+ import { getExternalStoreMessages, pickExternalStoreSharedOptions } from "@assistant-ui/core";
15
15
  //#region src/ui/use-chat/useAISDKRuntime.ts
16
16
  const toUIMessage = (createMessage, fallbackRole) => ({
17
17
  ...createMessage,
18
18
  id: createMessage.id ?? generateId(),
19
19
  role: createMessage.role ?? fallbackRole
20
20
  });
21
- const useAISDKRuntime = (chatHelpers, { adapters, toCreateMessage: customToCreateMessage, cancelPendingToolCallsOnSend = true, onResume, suggestions } = {}) => {
21
+ const useAISDKRuntime = (chatHelpers, adapter = {}) => {
22
+ const { adapters, toCreateMessage: customToCreateMessage, cancelPendingToolCallsOnSend = true, onResume } = adapter;
22
23
  const contextAdapters = useRuntimeAdapters();
23
24
  const [toolStatuses, setToolStatuses] = useState({});
24
25
  const toolArgsKeyOrderCacheRef = useRef(/* @__PURE__ */ new Map());
@@ -28,6 +29,8 @@ const useAISDKRuntime = (chatHelpers, { adapters, toCreateMessage: customToCreat
28
29
  const hasExecutingTools = Object.values(toolStatuses).some((s) => s?.type === "executing");
29
30
  const isRunning = chatHelpers.status === "submitted" || chatHelpers.status === "streaming" || hasExecutingTools;
30
31
  const messageTiming = useStreamingTiming(chatHelpers.messages, isRunning);
32
+ const lastMessage = chatHelpers.messages.at(-1);
33
+ const optimisticMessageId = isRunning && lastMessage?.role === "assistant" ? lastMessage.id : void 0;
31
34
  const messages = AISDKMessageConverter.useThreadMessages({
32
35
  isRunning,
33
36
  messages: chatHelpers.messages,
@@ -37,10 +40,12 @@ const useAISDKRuntime = (chatHelpers, { adapters, toCreateMessage: customToCreat
37
40
  toolArgsKeyOrderCache: toolArgsKeyOrderCacheRef.current,
38
41
  toolLastInputCache: toolLastInputCacheRef.current,
39
42
  mcpAppMetadataCache: mcpAppMetadataCacheRef.current,
43
+ ...optimisticMessageId && { optimisticMessageId },
40
44
  ...chatHelpers.error && { error: chatHelpers.error.message }
41
45
  }), [
42
46
  toolStatuses,
43
47
  messageTiming,
48
+ optimisticMessageId,
44
49
  chatHelpers.error
45
50
  ])
46
51
  });
@@ -160,8 +165,8 @@ const useAISDKRuntime = (chatHelpers, { adapters, toCreateMessage: customToCreat
160
165
  options: { metadata: lastRunConfigRef.current }
161
166
  });
162
167
  },
168
+ ...pickExternalStoreSharedOptions(adapter),
163
169
  ...onResume && { onResume },
164
- ...suggestions && { suggestions },
165
170
  adapters: {
166
171
  attachments: vercelAttachmentAdapter,
167
172
  ...contextAdapters,
@@ -1 +1 @@
1
- {"version":3,"file":"useAISDKRuntime.js","names":[],"sources":["../../../src/ui/use-chat/useAISDKRuntime.ts"],"sourcesContent":["\"use client\";\n\nimport { useMemo, useRef, useState } from \"react\";\nimport type { UIMessage, useChat, CreateUIMessage } from \"@ai-sdk/react\";\nimport { isToolUIPart, generateId } from \"ai\";\nimport {\n useExternalStoreRuntime,\n useRuntimeAdapters,\n} from \"@assistant-ui/core/react\";\nimport type { ToolExecutionStatus } from \"@assistant-ui/core\";\nimport type {\n ExternalStoreAdapter,\n ThreadHistoryAdapter,\n AssistantRuntime,\n ThreadMessage,\n ThreadSuggestion,\n MessageFormatAdapter,\n MessageFormatItem,\n MessageFormatRepository,\n AppendMessage,\n RunConfig,\n McpAppMetadata,\n} from \"@assistant-ui/core\";\nimport { getExternalStoreMessages } from \"@assistant-ui/core\";\nimport type { ReadonlyJSONObject } from \"assistant-stream/utils\";\nimport { sliceMessagesUntil } from \"../utils/sliceMessagesUntil\";\nimport { toCreateMessage } from \"../utils/toCreateMessage\";\nimport { vercelAttachmentAdapter } from \"../utils/vercelAttachmentAdapter\";\nimport { getVercelAIMessages } from \"../getVercelAIMessages\";\nimport { AISDKMessageConverter } from \"../utils/convertMessage\";\nimport { wrapModelContentEnvelope } from \"../../modelContentEnvelope\";\nimport {\n type AISDKStorageFormat,\n aiSDKV6FormatAdapter,\n} from \"../adapters/aiSDKFormatAdapter\";\nimport {\n useExternalHistory,\n toExportedMessageRepository,\n} from \"./useExternalHistory\";\nimport { useStreamingTiming } from \"./useStreamingTiming\";\n\nexport type CustomToCreateMessageFunction = <\n UI_MESSAGE extends UIMessage = UIMessage,\n>(\n message: AppendMessage,\n) => CreateUIMessage<UI_MESSAGE>;\n\nconst toUIMessage = <UI_MESSAGE extends UIMessage>(\n createMessage: CreateUIMessage<UI_MESSAGE>,\n fallbackRole: UI_MESSAGE[\"role\"],\n): UI_MESSAGE =>\n ({\n ...createMessage,\n id: createMessage.id ?? generateId(),\n role: createMessage.role ?? fallbackRole,\n }) as UI_MESSAGE;\n\nexport type AISDKRuntimeAdapter = {\n adapters?:\n | (NonNullable<ExternalStoreAdapter[\"adapters\"]> & {\n history?: ThreadHistoryAdapter | undefined;\n })\n | undefined;\n toCreateMessage?: CustomToCreateMessageFunction;\n /**\n * Whether to automatically cancel pending interactive tool calls when the user sends a new message.\n *\n * When enabled (default), the pending tool calls will be marked as failed with an error message\n * indicating the user cancelled the tool call by sending a new message.\n *\n * @default true\n */\n cancelPendingToolCallsOnSend?: boolean | undefined;\n /**\n * Called when `runtime.thread.resumeRun(config)` is invoked.\n *\n * When omitted, `resumeRun` throws `\"Runtime does not support resuming runs.\"`.\n * Provide this to bridge resume invocations into a custom replay channel\n * (for example, an SSE reconnect endpoint keyed by turn id).\n */\n onResume?: ExternalStoreAdapter[\"onResume\"];\n /**\n * Follow up suggestions to surface on the thread. Use this to drive\n * dynamic suggestions from application state, tool results, or backend\n * responses; flows into `thread.suggestions` and is rendered by\n * components that read it (such as the shadcn `ThreadFollowupSuggestions`).\n */\n suggestions?: readonly ThreadSuggestion[] | undefined;\n};\n\nexport const useAISDKRuntime = <UI_MESSAGE extends UIMessage = UIMessage>(\n chatHelpers: ReturnType<typeof useChat<UI_MESSAGE>>,\n {\n adapters,\n toCreateMessage: customToCreateMessage,\n cancelPendingToolCallsOnSend = true,\n onResume,\n suggestions,\n }: AISDKRuntimeAdapter = {},\n) => {\n const contextAdapters = useRuntimeAdapters();\n const [toolStatuses, setToolStatuses] = useState<\n Record<string, ToolExecutionStatus>\n >({});\n const toolArgsKeyOrderCacheRef = useRef<Map<string, Map<string, string[]>>>(\n new Map(),\n );\n const toolLastInputCacheRef = useRef<Map<string, ReadonlyJSONObject>>(\n new Map(),\n );\n const mcpAppMetadataCacheRef = useRef<Map<string, McpAppMetadata>>(new Map());\n const lastRunConfigRef = useRef<RunConfig | undefined>(undefined);\n\n const hasExecutingTools = Object.values(toolStatuses).some(\n (s) => s?.type === \"executing\",\n );\n const isRunning =\n chatHelpers.status === \"submitted\" ||\n chatHelpers.status === \"streaming\" ||\n hasExecutingTools;\n\n const messageTiming = useStreamingTiming(chatHelpers.messages, isRunning);\n\n const messages = AISDKMessageConverter.useThreadMessages({\n isRunning,\n messages: chatHelpers.messages,\n metadata: useMemo(\n () => ({\n toolStatuses,\n messageTiming,\n toolArgsKeyOrderCache: toolArgsKeyOrderCacheRef.current,\n toolLastInputCache: toolLastInputCacheRef.current,\n mcpAppMetadataCache: mcpAppMetadataCacheRef.current,\n ...(chatHelpers.error && { error: chatHelpers.error.message }),\n }),\n [toolStatuses, messageTiming, chatHelpers.error],\n ),\n });\n\n const [runtimeRef] = useState(() => ({\n get current(): AssistantRuntime {\n return runtime;\n },\n }));\n\n const isLoading = useExternalHistory(\n runtimeRef,\n adapters?.history ?? contextAdapters?.history,\n AISDKMessageConverter.toThreadMessages as (\n messages: UI_MESSAGE[],\n ) => ThreadMessage[],\n aiSDKV6FormatAdapter as MessageFormatAdapter<\n UI_MESSAGE,\n AISDKStorageFormat\n >,\n (messages) => {\n chatHelpers.setMessages(messages);\n },\n );\n\n const completePendingToolCalls = async () => {\n if (!cancelPendingToolCallsOnSend) return;\n\n // The runtime auto-aborts in-flight tool invocations when a new run\n // is dispatched (append() / startRun()). All we need to do here is\n // mark any tool without a result as cancelled in the UI message list.\n\n // Mark any tool without a result as cancelled (uses setMessages to avoid triggering sendAutomaticallyWhen)\n chatHelpers.setMessages((messages) => {\n const lastMessage = messages.at(-1);\n if (lastMessage?.role !== \"assistant\") return messages;\n\n let hasChanges = false;\n const parts = lastMessage.parts?.map((part) => {\n if (!isToolUIPart(part)) return part;\n if (part.state === \"output-available\" || part.state === \"output-error\")\n return part;\n\n hasChanges = true;\n return {\n ...part,\n state: \"output-error\" as const,\n errorText: \"User cancelled tool call by sending a new message.\",\n };\n });\n\n if (!hasChanges) return messages;\n return [...messages.slice(0, -1), { ...lastMessage, parts }];\n });\n };\n\n const runtime = useExternalStoreRuntime({\n isRunning,\n messages,\n unstable_enableToolInvocations: true,\n setToolStatuses,\n setMessages: (messages) =>\n chatHelpers.setMessages(\n messages\n .map(getVercelAIMessages<UI_MESSAGE>)\n .filter(Boolean)\n .flat(),\n ),\n onImport: (messages) =>\n chatHelpers.setMessages(\n messages\n .map(getVercelAIMessages<UI_MESSAGE>)\n .filter(Boolean)\n .flat(),\n ),\n onExportExternalState: (): MessageFormatRepository<UI_MESSAGE> => {\n const exported = runtimeRef.current.thread.export();\n\n const expandedMessages: MessageFormatItem<UI_MESSAGE>[] = [];\n const lastInnerIdMap = new Map<string, string>();\n\n for (const item of exported.messages) {\n const innerMessages = getExternalStoreMessages<UI_MESSAGE>(\n item.message,\n );\n let parentId =\n item.parentId != null\n ? (lastInnerIdMap.get(item.parentId) ?? item.parentId)\n : null;\n for (const innerMessage of innerMessages) {\n expandedMessages.push({ parentId, message: innerMessage });\n parentId = aiSDKV6FormatAdapter.getId(innerMessage as UIMessage);\n }\n if (innerMessages.length > 0) {\n lastInnerIdMap.set(\n item.message.id,\n aiSDKV6FormatAdapter.getId(\n innerMessages[innerMessages.length - 1]! as UIMessage,\n ),\n );\n }\n }\n\n const result: MessageFormatRepository<UI_MESSAGE> = {\n messages: expandedMessages,\n };\n\n if (exported.headId != null) {\n result.headId = lastInnerIdMap.get(exported.headId) ?? exported.headId;\n }\n\n return result;\n },\n onLoadExternalState: (repo: MessageFormatRepository<UI_MESSAGE>) => {\n // Convert MessageFormatRepository to ExportedMessageRepository\n const exportedRepo = toExportedMessageRepository(\n AISDKMessageConverter.toThreadMessages,\n repo,\n );\n\n // Import into the thread's MessageRepository\n runtimeRef.current.thread.import(exportedRepo);\n },\n onCancel: async () => {\n chatHelpers.stop();\n },\n onNew: async (message) => {\n const createMessage = (\n customToCreateMessage ?? toCreateMessage\n )<UI_MESSAGE>(message);\n\n if (!(message.startRun ?? message.role === \"user\")) {\n chatHelpers.setMessages((current) => [\n ...current,\n toUIMessage<UI_MESSAGE>(createMessage, message.role),\n ]);\n return;\n }\n\n lastRunConfigRef.current = message.runConfig;\n await completePendingToolCalls();\n await chatHelpers.sendMessage(createMessage, {\n metadata: message.runConfig,\n });\n },\n onEdit: async (message) => {\n const createMessage = (\n customToCreateMessage ?? toCreateMessage\n )<UI_MESSAGE>(message);\n\n if (!(message.startRun ?? message.role === \"user\")) {\n chatHelpers.setMessages((current) => [\n ...sliceMessagesUntil(current, message.parentId),\n toUIMessage<UI_MESSAGE>(createMessage, message.role),\n ]);\n return;\n }\n\n lastRunConfigRef.current = message.runConfig;\n chatHelpers.setMessages((current) =>\n sliceMessagesUntil(current, message.parentId),\n );\n await chatHelpers.sendMessage(createMessage, {\n metadata: message.runConfig,\n });\n },\n onReload: async (parentId: string | null, config) => {\n lastRunConfigRef.current = config.runConfig;\n const newMessages = sliceMessagesUntil(chatHelpers.messages, parentId);\n chatHelpers.setMessages(newMessages);\n\n await chatHelpers.regenerate({ metadata: config.runConfig });\n },\n onAddToolResult: ({\n toolCallId,\n toolName,\n result,\n isError,\n modelContent,\n }) => {\n const options = { metadata: lastRunConfigRef.current };\n if (isError) {\n chatHelpers.addToolOutput({\n state: \"output-error\",\n tool: toolName ?? toolCallId,\n toolCallId,\n errorText:\n typeof result === \"string\" ? result : JSON.stringify(result),\n options,\n });\n } else {\n const output =\n modelContent !== undefined\n ? wrapModelContentEnvelope(result, modelContent)\n : result;\n chatHelpers.addToolResult({\n tool: toolName,\n toolCallId,\n output,\n options,\n });\n }\n },\n onRespondToToolApproval: ({ approvalId, approved, reason }) => {\n void chatHelpers.addToolApprovalResponse({\n id: approvalId,\n approved,\n ...(reason != null && { reason }),\n options: { metadata: lastRunConfigRef.current },\n });\n },\n ...(onResume && { onResume }),\n ...(suggestions && { suggestions }),\n adapters: {\n attachments: vercelAttachmentAdapter,\n ...contextAdapters,\n ...adapters,\n },\n isLoading,\n });\n\n return runtime;\n};\n"],"mappings":";;;;;;;;;;;;;;;AA+CA,MAAM,eACJ,eACA,kBAEC;CACC,GAAG;CACH,IAAI,cAAc,MAAM,WAAW;CACnC,MAAM,cAAc,QAAQ;AAC9B;AAmCF,MAAa,mBACX,aACA,EACE,UACA,iBAAiB,uBACjB,+BAA+B,MAC/B,UACA,gBACuB,CAAC,MACvB;CACH,MAAM,kBAAkB,mBAAmB;CAC3C,MAAM,CAAC,cAAc,mBAAmB,SAEtC,CAAC,CAAC;CACJ,MAAM,2BAA2B,uBAC/B,IAAI,IAAI,CACV;CACA,MAAM,wBAAwB,uBAC5B,IAAI,IAAI,CACV;CACA,MAAM,yBAAyB,uBAAoC,IAAI,IAAI,CAAC;CAC5E,MAAM,mBAAmB,OAA8B,KAAA,CAAS;CAEhE,MAAM,oBAAoB,OAAO,OAAO,YAAY,EAAE,MACnD,MAAM,GAAG,SAAS,WACrB;CACA,MAAM,YACJ,YAAY,WAAW,eACvB,YAAY,WAAW,eACvB;CAEF,MAAM,gBAAgB,mBAAmB,YAAY,UAAU,SAAS;CAExE,MAAM,WAAW,sBAAsB,kBAAkB;EACvD;EACA,UAAU,YAAY;EACtB,UAAU,eACD;GACL;GACA;GACA,uBAAuB,yBAAyB;GAChD,oBAAoB,sBAAsB;GAC1C,qBAAqB,uBAAuB;GAC5C,GAAI,YAAY,SAAS,EAAE,OAAO,YAAY,MAAM,QAAQ;EAC9D,IACA;GAAC;GAAc;GAAe,YAAY;EAAK,CACjD;CACF,CAAC;CAED,MAAM,CAAC,cAAc,gBAAgB,EACnC,IAAI,UAA4B;EAC9B,OAAO;CACT,EACF,EAAE;CAEF,MAAM,YAAY,mBAChB,YACA,UAAU,WAAW,iBAAiB,SACtC,sBAAsB,kBAGtB,uBAIC,aAAa;EACZ,YAAY,YAAY,QAAQ;CAClC,CACF;CAEA,MAAM,2BAA2B,YAAY;EAC3C,IAAI,CAAC,8BAA8B;EAOnC,YAAY,aAAa,aAAa;GACpC,MAAM,cAAc,SAAS,GAAG,EAAE;GAClC,IAAI,aAAa,SAAS,aAAa,OAAO;GAE9C,IAAI,aAAa;GACjB,MAAM,QAAQ,YAAY,OAAO,KAAK,SAAS;IAC7C,IAAI,CAAC,aAAa,IAAI,GAAG,OAAO;IAChC,IAAI,KAAK,UAAU,sBAAsB,KAAK,UAAU,gBACtD,OAAO;IAET,aAAa;IACb,OAAO;KACL,GAAG;KACH,OAAO;KACP,WAAW;IACb;GACF,CAAC;GAED,IAAI,CAAC,YAAY,OAAO;GACxB,OAAO,CAAC,GAAG,SAAS,MAAM,GAAG,EAAE,GAAG;IAAE,GAAG;IAAa;GAAM,CAAC;EAC7D,CAAC;CACH;CAEA,MAAM,UAAU,wBAAwB;EACtC;EACA;EACA,gCAAgC;EAChC;EACA,cAAc,aACZ,YAAY,YACV,SACG,IAAI,mBAA+B,EACnC,OAAO,OAAO,EACd,KAAK,CACV;EACF,WAAW,aACT,YAAY,YACV,SACG,IAAI,mBAA+B,EACnC,OAAO,OAAO,EACd,KAAK,CACV;EACF,6BAAkE;GAChE,MAAM,WAAW,WAAW,QAAQ,OAAO,OAAO;GAElD,MAAM,mBAAoD,CAAC;GAC3D,MAAM,iCAAiB,IAAI,IAAoB;GAE/C,KAAK,MAAM,QAAQ,SAAS,UAAU;IACpC,MAAM,gBAAgB,yBACpB,KAAK,OACP;IACA,IAAI,WACF,KAAK,YAAY,OACZ,eAAe,IAAI,KAAK,QAAQ,KAAK,KAAK,WAC3C;IACN,KAAK,MAAM,gBAAgB,eAAe;KACxC,iBAAiB,KAAK;MAAE;MAAU,SAAS;KAAa,CAAC;KACzD,WAAW,qBAAqB,MAAM,YAAyB;IACjE;IACA,IAAI,cAAc,SAAS,GACzB,eAAe,IACb,KAAK,QAAQ,IACb,qBAAqB,MACnB,cAAc,cAAc,SAAS,EACvC,CACF;GAEJ;GAEA,MAAM,SAA8C,EAClD,UAAU,iBACZ;GAEA,IAAI,SAAS,UAAU,MACrB,OAAO,SAAS,eAAe,IAAI,SAAS,MAAM,KAAK,SAAS;GAGlE,OAAO;EACT;EACA,sBAAsB,SAA8C;GAElE,MAAM,eAAe,4BACnB,sBAAsB,kBACtB,IACF;GAGA,WAAW,QAAQ,OAAO,OAAO,YAAY;EAC/C;EACA,UAAU,YAAY;GACpB,YAAY,KAAK;EACnB;EACA,OAAO,OAAO,YAAY;GACxB,MAAM,iBACJ,yBAAyB,iBACb,OAAO;GAErB,IAAI,EAAE,QAAQ,YAAY,QAAQ,SAAS,SAAS;IAClD,YAAY,aAAa,YAAY,CACnC,GAAG,SACH,YAAwB,eAAe,QAAQ,IAAI,CACrD,CAAC;IACD;GACF;GAEA,iBAAiB,UAAU,QAAQ;GACnC,MAAM,yBAAyB;GAC/B,MAAM,YAAY,YAAY,eAAe,EAC3C,UAAU,QAAQ,UACpB,CAAC;EACH;EACA,QAAQ,OAAO,YAAY;GACzB,MAAM,iBACJ,yBAAyB,iBACb,OAAO;GAErB,IAAI,EAAE,QAAQ,YAAY,QAAQ,SAAS,SAAS;IAClD,YAAY,aAAa,YAAY,CACnC,GAAG,mBAAmB,SAAS,QAAQ,QAAQ,GAC/C,YAAwB,eAAe,QAAQ,IAAI,CACrD,CAAC;IACD;GACF;GAEA,iBAAiB,UAAU,QAAQ;GACnC,YAAY,aAAa,YACvB,mBAAmB,SAAS,QAAQ,QAAQ,CAC9C;GACA,MAAM,YAAY,YAAY,eAAe,EAC3C,UAAU,QAAQ,UACpB,CAAC;EACH;EACA,UAAU,OAAO,UAAyB,WAAW;GACnD,iBAAiB,UAAU,OAAO;GAClC,MAAM,cAAc,mBAAmB,YAAY,UAAU,QAAQ;GACrE,YAAY,YAAY,WAAW;GAEnC,MAAM,YAAY,WAAW,EAAE,UAAU,OAAO,UAAU,CAAC;EAC7D;EACA,kBAAkB,EAChB,YACA,UACA,QACA,SACA,mBACI;GACJ,MAAM,UAAU,EAAE,UAAU,iBAAiB,QAAQ;GACrD,IAAI,SACF,YAAY,cAAc;IACxB,OAAO;IACP,MAAM,YAAY;IAClB;IACA,WACE,OAAO,WAAW,WAAW,SAAS,KAAK,UAAU,MAAM;IAC7D;GACF,CAAC;QACI;IACL,MAAM,SACJ,iBAAiB,KAAA,IACb,yBAAyB,QAAQ,YAAY,IAC7C;IACN,YAAY,cAAc;KACxB,MAAM;KACN;KACA;KACA;IACF,CAAC;GACH;EACF;EACA,0BAA0B,EAAE,YAAY,UAAU,aAAa;GAC7D,YAAiB,wBAAwB;IACvC,IAAI;IACJ;IACA,GAAI,UAAU,QAAQ,EAAE,OAAO;IAC/B,SAAS,EAAE,UAAU,iBAAiB,QAAQ;GAChD,CAAC;EACH;EACA,GAAI,YAAY,EAAE,SAAS;EAC3B,GAAI,eAAe,EAAE,YAAY;EACjC,UAAU;GACR,aAAa;GACb,GAAG;GACH,GAAG;EACL;EACA;CACF,CAAC;CAED,OAAO;AACT"}
1
+ {"version":3,"file":"useAISDKRuntime.js","names":[],"sources":["../../../src/ui/use-chat/useAISDKRuntime.ts"],"sourcesContent":["\"use client\";\n\nimport { useMemo, useRef, useState } from \"react\";\nimport type { UIMessage, useChat, CreateUIMessage } from \"@ai-sdk/react\";\nimport { isToolUIPart, generateId } from \"ai\";\nimport {\n useExternalStoreRuntime,\n useRuntimeAdapters,\n} from \"@assistant-ui/core/react\";\nimport type { ToolExecutionStatus } from \"@assistant-ui/core\";\nimport type {\n ExternalStoreAdapter,\n ExternalStoreSharedOptions,\n ThreadHistoryAdapter,\n AssistantRuntime,\n ThreadMessage,\n MessageFormatAdapter,\n MessageFormatItem,\n MessageFormatRepository,\n AppendMessage,\n RunConfig,\n McpAppMetadata,\n} from \"@assistant-ui/core\";\nimport {\n getExternalStoreMessages,\n pickExternalStoreSharedOptions,\n} from \"@assistant-ui/core\";\nimport type { ReadonlyJSONObject } from \"assistant-stream/utils\";\nimport { sliceMessagesUntil } from \"../utils/sliceMessagesUntil\";\nimport { toCreateMessage } from \"../utils/toCreateMessage\";\nimport { vercelAttachmentAdapter } from \"../utils/vercelAttachmentAdapter\";\nimport { getVercelAIMessages } from \"../getVercelAIMessages\";\nimport { AISDKMessageConverter } from \"../utils/convertMessage\";\nimport { wrapModelContentEnvelope } from \"../../modelContentEnvelope\";\nimport {\n type AISDKStorageFormat,\n aiSDKV6FormatAdapter,\n} from \"../adapters/aiSDKFormatAdapter\";\nimport {\n useExternalHistory,\n toExportedMessageRepository,\n} from \"./useExternalHistory\";\nimport { useStreamingTiming } from \"./useStreamingTiming\";\n\nexport type CustomToCreateMessageFunction = <\n UI_MESSAGE extends UIMessage = UIMessage,\n>(\n message: AppendMessage,\n) => CreateUIMessage<UI_MESSAGE>;\n\nconst toUIMessage = <UI_MESSAGE extends UIMessage>(\n createMessage: CreateUIMessage<UI_MESSAGE>,\n fallbackRole: UI_MESSAGE[\"role\"],\n): UI_MESSAGE =>\n ({\n ...createMessage,\n id: createMessage.id ?? generateId(),\n role: createMessage.role ?? fallbackRole,\n }) as UI_MESSAGE;\n\nexport type AISDKRuntimeAdapter = ExternalStoreSharedOptions & {\n adapters?:\n | (NonNullable<ExternalStoreAdapter[\"adapters\"]> & {\n history?: ThreadHistoryAdapter | undefined;\n })\n | undefined;\n toCreateMessage?: CustomToCreateMessageFunction;\n /**\n * Whether to automatically cancel pending interactive tool calls when the user sends a new message.\n *\n * When enabled (default), the pending tool calls will be marked as failed with an error message\n * indicating the user cancelled the tool call by sending a new message.\n *\n * @default true\n */\n cancelPendingToolCallsOnSend?: boolean | undefined;\n /**\n * Called when `runtime.thread.resumeRun(config)` is invoked.\n *\n * When omitted, `resumeRun` throws `\"Runtime does not support resuming runs.\"`.\n * Provide this to bridge resume invocations into a custom replay channel\n * (for example, an SSE reconnect endpoint keyed by turn id).\n */\n onResume?: ExternalStoreAdapter[\"onResume\"];\n};\n\nexport const useAISDKRuntime = <UI_MESSAGE extends UIMessage = UIMessage>(\n chatHelpers: ReturnType<typeof useChat<UI_MESSAGE>>,\n adapter: AISDKRuntimeAdapter = {},\n) => {\n const {\n adapters,\n toCreateMessage: customToCreateMessage,\n cancelPendingToolCallsOnSend = true,\n onResume,\n } = adapter;\n const contextAdapters = useRuntimeAdapters();\n const [toolStatuses, setToolStatuses] = useState<\n Record<string, ToolExecutionStatus>\n >({});\n const toolArgsKeyOrderCacheRef = useRef<Map<string, Map<string, string[]>>>(\n new Map(),\n );\n const toolLastInputCacheRef = useRef<Map<string, ReadonlyJSONObject>>(\n new Map(),\n );\n const mcpAppMetadataCacheRef = useRef<Map<string, McpAppMetadata>>(new Map());\n const lastRunConfigRef = useRef<RunConfig | undefined>(undefined);\n\n const hasExecutingTools = Object.values(toolStatuses).some(\n (s) => s?.type === \"executing\",\n );\n const isRunning =\n chatHelpers.status === \"submitted\" ||\n chatHelpers.status === \"streaming\" ||\n hasExecutingTools;\n\n const messageTiming = useStreamingTiming(chatHelpers.messages, isRunning);\n\n // Flag the streaming message optimistic: its id can be swapped for a server\n // id mid-run, and the repository then drops the orphaned pre-swap id (#4037).\n const lastMessage = chatHelpers.messages.at(-1);\n const optimisticMessageId =\n isRunning && lastMessage?.role === \"assistant\" ? lastMessage.id : undefined;\n\n const messages = AISDKMessageConverter.useThreadMessages({\n isRunning,\n messages: chatHelpers.messages,\n metadata: useMemo(\n () => ({\n toolStatuses,\n messageTiming,\n toolArgsKeyOrderCache: toolArgsKeyOrderCacheRef.current,\n toolLastInputCache: toolLastInputCacheRef.current,\n mcpAppMetadataCache: mcpAppMetadataCacheRef.current,\n ...(optimisticMessageId && { optimisticMessageId }),\n ...(chatHelpers.error && { error: chatHelpers.error.message }),\n }),\n [toolStatuses, messageTiming, optimisticMessageId, chatHelpers.error],\n ),\n });\n\n const [runtimeRef] = useState(() => ({\n get current(): AssistantRuntime {\n return runtime;\n },\n }));\n\n const isLoading = useExternalHistory(\n runtimeRef,\n adapters?.history ?? contextAdapters?.history,\n AISDKMessageConverter.toThreadMessages as (\n messages: UI_MESSAGE[],\n ) => ThreadMessage[],\n aiSDKV6FormatAdapter as MessageFormatAdapter<\n UI_MESSAGE,\n AISDKStorageFormat\n >,\n (messages) => {\n chatHelpers.setMessages(messages);\n },\n );\n\n const completePendingToolCalls = async () => {\n if (!cancelPendingToolCallsOnSend) return;\n\n // The runtime auto-aborts in-flight tool invocations when a new run\n // is dispatched (append() / startRun()). All we need to do here is\n // mark any tool without a result as cancelled in the UI message list.\n\n // Mark any tool without a result as cancelled (uses setMessages to avoid triggering sendAutomaticallyWhen)\n chatHelpers.setMessages((messages) => {\n const lastMessage = messages.at(-1);\n if (lastMessage?.role !== \"assistant\") return messages;\n\n let hasChanges = false;\n const parts = lastMessage.parts?.map((part) => {\n if (!isToolUIPart(part)) return part;\n if (part.state === \"output-available\" || part.state === \"output-error\")\n return part;\n\n hasChanges = true;\n return {\n ...part,\n state: \"output-error\" as const,\n errorText: \"User cancelled tool call by sending a new message.\",\n };\n });\n\n if (!hasChanges) return messages;\n return [...messages.slice(0, -1), { ...lastMessage, parts }];\n });\n };\n\n const runtime = useExternalStoreRuntime({\n isRunning,\n messages,\n unstable_enableToolInvocations: true,\n setToolStatuses,\n setMessages: (messages) =>\n chatHelpers.setMessages(\n messages\n .map(getVercelAIMessages<UI_MESSAGE>)\n .filter(Boolean)\n .flat(),\n ),\n onImport: (messages) =>\n chatHelpers.setMessages(\n messages\n .map(getVercelAIMessages<UI_MESSAGE>)\n .filter(Boolean)\n .flat(),\n ),\n onExportExternalState: (): MessageFormatRepository<UI_MESSAGE> => {\n const exported = runtimeRef.current.thread.export();\n\n const expandedMessages: MessageFormatItem<UI_MESSAGE>[] = [];\n const lastInnerIdMap = new Map<string, string>();\n\n for (const item of exported.messages) {\n const innerMessages = getExternalStoreMessages<UI_MESSAGE>(\n item.message,\n );\n let parentId =\n item.parentId != null\n ? (lastInnerIdMap.get(item.parentId) ?? item.parentId)\n : null;\n for (const innerMessage of innerMessages) {\n expandedMessages.push({ parentId, message: innerMessage });\n parentId = aiSDKV6FormatAdapter.getId(innerMessage as UIMessage);\n }\n if (innerMessages.length > 0) {\n lastInnerIdMap.set(\n item.message.id,\n aiSDKV6FormatAdapter.getId(\n innerMessages[innerMessages.length - 1]! as UIMessage,\n ),\n );\n }\n }\n\n const result: MessageFormatRepository<UI_MESSAGE> = {\n messages: expandedMessages,\n };\n\n if (exported.headId != null) {\n result.headId = lastInnerIdMap.get(exported.headId) ?? exported.headId;\n }\n\n return result;\n },\n onLoadExternalState: (repo: MessageFormatRepository<UI_MESSAGE>) => {\n // Convert MessageFormatRepository to ExportedMessageRepository\n const exportedRepo = toExportedMessageRepository(\n AISDKMessageConverter.toThreadMessages,\n repo,\n );\n\n // Import into the thread's MessageRepository\n runtimeRef.current.thread.import(exportedRepo);\n },\n onCancel: async () => {\n chatHelpers.stop();\n },\n onNew: async (message) => {\n const createMessage = (\n customToCreateMessage ?? toCreateMessage\n )<UI_MESSAGE>(message);\n\n if (!(message.startRun ?? message.role === \"user\")) {\n chatHelpers.setMessages((current) => [\n ...current,\n toUIMessage<UI_MESSAGE>(createMessage, message.role),\n ]);\n return;\n }\n\n lastRunConfigRef.current = message.runConfig;\n await completePendingToolCalls();\n await chatHelpers.sendMessage(createMessage, {\n metadata: message.runConfig,\n });\n },\n onEdit: async (message) => {\n const createMessage = (\n customToCreateMessage ?? toCreateMessage\n )<UI_MESSAGE>(message);\n\n if (!(message.startRun ?? message.role === \"user\")) {\n chatHelpers.setMessages((current) => [\n ...sliceMessagesUntil(current, message.parentId),\n toUIMessage<UI_MESSAGE>(createMessage, message.role),\n ]);\n return;\n }\n\n lastRunConfigRef.current = message.runConfig;\n chatHelpers.setMessages((current) =>\n sliceMessagesUntil(current, message.parentId),\n );\n await chatHelpers.sendMessage(createMessage, {\n metadata: message.runConfig,\n });\n },\n onReload: async (parentId: string | null, config) => {\n lastRunConfigRef.current = config.runConfig;\n const newMessages = sliceMessagesUntil(chatHelpers.messages, parentId);\n chatHelpers.setMessages(newMessages);\n\n await chatHelpers.regenerate({ metadata: config.runConfig });\n },\n onAddToolResult: ({\n toolCallId,\n toolName,\n result,\n isError,\n modelContent,\n }) => {\n const options = { metadata: lastRunConfigRef.current };\n if (isError) {\n chatHelpers.addToolOutput({\n state: \"output-error\",\n tool: toolName ?? toolCallId,\n toolCallId,\n errorText:\n typeof result === \"string\" ? result : JSON.stringify(result),\n options,\n });\n } else {\n const output =\n modelContent !== undefined\n ? wrapModelContentEnvelope(result, modelContent)\n : result;\n chatHelpers.addToolResult({\n tool: toolName,\n toolCallId,\n output,\n options,\n });\n }\n },\n onRespondToToolApproval: ({ approvalId, approved, reason }) => {\n void chatHelpers.addToolApprovalResponse({\n id: approvalId,\n approved,\n ...(reason != null && { reason }),\n options: { metadata: lastRunConfigRef.current },\n });\n },\n ...pickExternalStoreSharedOptions(adapter),\n ...(onResume && { onResume }),\n adapters: {\n attachments: vercelAttachmentAdapter,\n ...contextAdapters,\n ...adapters,\n },\n isLoading,\n });\n\n return runtime;\n};\n"],"mappings":"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"}