@assistant-ui/react 0.7.69 → 0.7.70

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. package/dist/api/MessageRuntime.d.ts +2 -1
  2. package/dist/api/MessageRuntime.d.ts.map +1 -1
  3. package/dist/api/MessageRuntime.js +9 -2
  4. package/dist/api/MessageRuntime.js.map +1 -1
  5. package/dist/api/MessageRuntime.mjs +9 -2
  6. package/dist/api/MessageRuntime.mjs.map +1 -1
  7. package/dist/context/providers/ThreadRuntimeProvider.d.ts.map +1 -1
  8. package/dist/context/providers/ThreadRuntimeProvider.js +3 -5
  9. package/dist/context/providers/ThreadRuntimeProvider.js.map +1 -1
  10. package/dist/context/providers/ThreadRuntimeProvider.mjs +3 -5
  11. package/dist/context/providers/ThreadRuntimeProvider.mjs.map +1 -1
  12. package/dist/context/providers/ThreadViewportProvider.d.ts +3 -0
  13. package/dist/context/providers/ThreadViewportProvider.d.ts.map +1 -0
  14. package/dist/context/providers/ThreadViewportProvider.js +63 -0
  15. package/dist/context/providers/ThreadViewportProvider.js.map +1 -0
  16. package/dist/context/providers/ThreadViewportProvider.mjs +42 -0
  17. package/dist/context/providers/ThreadViewportProvider.mjs.map +1 -0
  18. package/dist/context/react/ThreadContext.d.ts +0 -18
  19. package/dist/context/react/ThreadContext.d.ts.map +1 -1
  20. package/dist/context/react/ThreadContext.js +2 -11
  21. package/dist/context/react/ThreadContext.js.map +1 -1
  22. package/dist/context/react/ThreadContext.mjs +1 -8
  23. package/dist/context/react/ThreadContext.mjs.map +1 -1
  24. package/dist/context/react/ThreadViewportContext.d.ts +24 -0
  25. package/dist/context/react/ThreadViewportContext.d.ts.map +1 -0
  26. package/dist/context/react/ThreadViewportContext.js +44 -0
  27. package/dist/context/react/ThreadViewportContext.js.map +1 -0
  28. package/dist/context/react/ThreadViewportContext.mjs +18 -0
  29. package/dist/context/react/ThreadViewportContext.mjs.map +1 -0
  30. package/dist/context/react/index.d.ts +2 -1
  31. package/dist/context/react/index.d.ts.map +1 -1
  32. package/dist/context/react/index.js +3 -2
  33. package/dist/context/react/index.js.map +1 -1
  34. package/dist/context/react/index.mjs +4 -2
  35. package/dist/context/react/index.mjs.map +1 -1
  36. package/dist/context/stores/ThreadViewport.d.ts.map +1 -1
  37. package/dist/context/stores/ThreadViewport.js +1 -0
  38. package/dist/context/stores/ThreadViewport.js.map +1 -1
  39. package/dist/context/stores/ThreadViewport.mjs +2 -0
  40. package/dist/context/stores/ThreadViewport.mjs.map +1 -1
  41. package/dist/model-context/ModelContextTypes.d.ts +3 -0
  42. package/dist/model-context/ModelContextTypes.d.ts.map +1 -1
  43. package/dist/model-context/ModelContextTypes.js.map +1 -1
  44. package/dist/model-context/ModelContextTypes.mjs.map +1 -1
  45. package/dist/primitives/thread/ThreadScrollToBottom.d.ts.map +1 -1
  46. package/dist/primitives/thread/ThreadScrollToBottom.js +3 -4
  47. package/dist/primitives/thread/ThreadScrollToBottom.js.map +1 -1
  48. package/dist/primitives/thread/ThreadScrollToBottom.mjs +1 -2
  49. package/dist/primitives/thread/ThreadScrollToBottom.mjs.map +1 -1
  50. package/dist/primitives/thread/ThreadViewport.d.ts.map +1 -1
  51. package/dist/primitives/thread/ThreadViewport.js +5 -1
  52. package/dist/primitives/thread/ThreadViewport.js.map +1 -1
  53. package/dist/primitives/thread/ThreadViewport.mjs +5 -1
  54. package/dist/primitives/thread/ThreadViewport.mjs.map +1 -1
  55. package/dist/primitives/thread/useThreadViewportAutoScroll.d.ts.map +1 -1
  56. package/dist/primitives/thread/useThreadViewportAutoScroll.js +2 -1
  57. package/dist/primitives/thread/useThreadViewportAutoScroll.js.map +1 -1
  58. package/dist/primitives/thread/useThreadViewportAutoScroll.mjs +2 -4
  59. package/dist/primitives/thread/useThreadViewportAutoScroll.mjs.map +1 -1
  60. package/dist/runtimes/composer/DefaultEditComposerRuntimeCore.d.ts +1 -1
  61. package/dist/runtimes/composer/DefaultEditComposerRuntimeCore.d.ts.map +1 -1
  62. package/dist/runtimes/composer/DefaultEditComposerRuntimeCore.js +1 -0
  63. package/dist/runtimes/composer/DefaultEditComposerRuntimeCore.js.map +1 -1
  64. package/dist/runtimes/composer/DefaultEditComposerRuntimeCore.mjs +1 -0
  65. package/dist/runtimes/composer/DefaultEditComposerRuntimeCore.mjs.map +1 -1
  66. package/dist/runtimes/edge/streams/toolResultStream.d.ts.map +1 -1
  67. package/dist/runtimes/edge/streams/toolResultStream.js +13 -15
  68. package/dist/runtimes/edge/streams/toolResultStream.js.map +1 -1
  69. package/dist/runtimes/edge/streams/toolResultStream.mjs +13 -15
  70. package/dist/runtimes/edge/streams/toolResultStream.mjs.map +1 -1
  71. package/dist/utils/hooks/useOnScrollToBottom.js +2 -2
  72. package/dist/utils/hooks/useOnScrollToBottom.js.map +1 -1
  73. package/dist/utils/hooks/useOnScrollToBottom.mjs +1 -1
  74. package/dist/utils/hooks/useOnScrollToBottom.mjs.map +1 -1
  75. package/package.json +3 -3
  76. package/src/api/MessageRuntime.ts +14 -5
  77. package/src/context/providers/ThreadRuntimeProvider.tsx +4 -5
  78. package/src/context/providers/ThreadViewportProvider.tsx +49 -0
  79. package/src/context/react/ThreadContext.ts +0 -8
  80. package/src/context/react/ThreadViewportContext.ts +23 -0
  81. package/src/context/react/index.ts +4 -1
  82. package/src/context/stores/ThreadViewport.tsx +2 -0
  83. package/src/model-context/ModelContextTypes.ts +7 -0
  84. package/src/primitives/thread/ThreadScrollToBottom.tsx +1 -2
  85. package/src/primitives/thread/ThreadViewport.tsx +13 -1
  86. package/src/primitives/thread/useThreadViewportAutoScroll.tsx +2 -4
  87. package/src/runtimes/composer/DefaultEditComposerRuntimeCore.tsx +4 -1
  88. package/src/runtimes/edge/streams/toolResultStream.ts +20 -18
  89. package/src/utils/hooks/useOnScrollToBottom.tsx +1 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/runtimes/composer/DefaultEditComposerRuntimeCore.tsx"],"sourcesContent":["import { AppendMessage, ThreadMessage } from \"../../types\";\nimport { getThreadMessageText } from \"../../utils/getThreadMessageText\";\nimport { AttachmentAdapter } from \"../adapters/attachment\";\nimport { ThreadRuntimeCore } from \"../core/ThreadRuntimeCore\";\nimport { BaseComposerRuntimeCore } from \"./BaseComposerRuntimeCore\";\n\nexport class DefaultEditComposerRuntimeCore extends BaseComposerRuntimeCore {\n public get canCancel() {\n return true;\n }\n\n protected getAttachmentAdapter() {\n return this.runtime.adapters?.attachments;\n }\n\n private _nonTextParts;\n private _previousText;\n private _parentId;\n private _sourceId;\n constructor(\n private runtime: Omit<ThreadRuntimeCore, \"composer\"> & {\n adapters?: { attachments?: AttachmentAdapter | undefined } | undefined;\n },\n private endEditCallback: () => void,\n { parentId, message }: { parentId: string | null; message: ThreadMessage },\n ) {\n super();\n this._parentId = parentId;\n this._sourceId = message.id;\n this._previousText = getThreadMessageText(message);\n this.setText(this._previousText);\n\n this.setRole(message.role);\n this.setAttachments(message.attachments ?? []);\n\n this._nonTextParts = message.content.filter(\n (part) => part.type !== \"text\" && part.type !== \"ui\",\n );\n }\n\n public async handleSend(\n message: Omit<AppendMessage, \"parentId\" | \"sourceId\">,\n ) {\n const text = getThreadMessageText(message as AppendMessage);\n if (text !== this._previousText) {\n this.runtime.append({\n ...message,\n content: [...message.content, ...this._nonTextParts] as any,\n parentId: this._parentId,\n sourceId: this._sourceId,\n });\n }\n\n this.handleCancel();\n }\n\n public handleCancel() {\n this.endEditCallback();\n this._notifySubscribers();\n }\n}\n"],"mappings":";AACA,SAAS,4BAA4B;AAGrC,SAAS,+BAA+B;AAEjC,IAAM,iCAAN,cAA6C,wBAAwB;AAAA,EAa1E,YACU,SAGA,iBACR,EAAE,UAAU,QAAQ,GACpB;AACA,UAAM;AANE;AAGA;AAIR,SAAK,YAAY;AACjB,SAAK,YAAY,QAAQ;AACzB,SAAK,gBAAgB,qBAAqB,OAAO;AACjD,SAAK,QAAQ,KAAK,aAAa;AAE/B,SAAK,QAAQ,QAAQ,IAAI;AACzB,SAAK,eAAe,QAAQ,eAAe,CAAC,CAAC;AAE7C,SAAK,gBAAgB,QAAQ,QAAQ;AAAA,MACnC,CAAC,SAAS,KAAK,SAAS,UAAU,KAAK,SAAS;AAAA,IAClD;AAAA,EACF;AAAA,EA/BA,IAAW,YAAY;AACrB,WAAO;AAAA,EACT;AAAA,EAEU,uBAAuB;AAC/B,WAAO,KAAK,QAAQ,UAAU;AAAA,EAChC;AAAA,EAEQ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAsBR,MAAa,WACX,SACA;AACA,UAAM,OAAO,qBAAqB,OAAwB;AAC1D,QAAI,SAAS,KAAK,eAAe;AAC/B,WAAK,QAAQ,OAAO;AAAA,QAClB,GAAG;AAAA,QACH,SAAS,CAAC,GAAG,QAAQ,SAAS,GAAG,KAAK,aAAa;AAAA,QACnD,UAAU,KAAK;AAAA,QACf,UAAU,KAAK;AAAA,MACjB,CAAC;AAAA,IACH;AAEA,SAAK,aAAa;AAAA,EACpB;AAAA,EAEO,eAAe;AACpB,SAAK,gBAAgB;AACrB,SAAK,mBAAmB;AAAA,EAC1B;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../src/runtimes/composer/DefaultEditComposerRuntimeCore.tsx"],"sourcesContent":["import { AppendMessage, ThreadMessage } from \"../../types\";\nimport { getThreadMessageText } from \"../../utils/getThreadMessageText\";\nimport { AttachmentAdapter } from \"../adapters/attachment\";\nimport { ThreadRuntimeCore } from \"../core/ThreadRuntimeCore\";\nimport { BaseComposerRuntimeCore } from \"./BaseComposerRuntimeCore\";\n\nexport class DefaultEditComposerRuntimeCore extends BaseComposerRuntimeCore {\n public get canCancel() {\n return true;\n }\n\n protected getAttachmentAdapter() {\n return this.runtime.adapters?.attachments;\n }\n\n private _nonTextParts;\n private _previousText;\n private _parentId;\n private _sourceId;\n constructor(\n private runtime: ThreadRuntimeCore & {\n adapters?: { attachments?: AttachmentAdapter | undefined } | undefined;\n },\n private endEditCallback: () => void,\n { parentId, message }: { parentId: string | null; message: ThreadMessage },\n ) {\n super();\n this._parentId = parentId;\n this._sourceId = message.id;\n this._previousText = getThreadMessageText(message);\n this.setText(this._previousText);\n\n this.setRole(message.role);\n this.setAttachments(message.attachments ?? []);\n\n this._nonTextParts = message.content.filter(\n (part) => part.type !== \"text\" && part.type !== \"ui\",\n );\n\n // Use the runConfig from the regular (non-edit) composer as the initial runConfig for the edit composer\n this.setRunConfig({ ...runtime.composer.runConfig });\n }\n\n public async handleSend(\n message: Omit<AppendMessage, \"parentId\" | \"sourceId\">,\n ) {\n const text = getThreadMessageText(message as AppendMessage);\n if (text !== this._previousText) {\n this.runtime.append({\n ...message,\n content: [...message.content, ...this._nonTextParts] as any,\n parentId: this._parentId,\n sourceId: this._sourceId,\n });\n }\n\n this.handleCancel();\n }\n\n public handleCancel() {\n this.endEditCallback();\n this._notifySubscribers();\n }\n}\n"],"mappings":";AACA,SAAS,4BAA4B;AAGrC,SAAS,+BAA+B;AAEjC,IAAM,iCAAN,cAA6C,wBAAwB;AAAA,EAa1E,YACU,SAGA,iBACR,EAAE,UAAU,QAAQ,GACpB;AACA,UAAM;AANE;AAGA;AAIR,SAAK,YAAY;AACjB,SAAK,YAAY,QAAQ;AACzB,SAAK,gBAAgB,qBAAqB,OAAO;AACjD,SAAK,QAAQ,KAAK,aAAa;AAE/B,SAAK,QAAQ,QAAQ,IAAI;AACzB,SAAK,eAAe,QAAQ,eAAe,CAAC,CAAC;AAE7C,SAAK,gBAAgB,QAAQ,QAAQ;AAAA,MACnC,CAAC,SAAS,KAAK,SAAS,UAAU,KAAK,SAAS;AAAA,IAClD;AAGA,SAAK,aAAa,EAAE,GAAG,QAAQ,SAAS,UAAU,CAAC;AAAA,EACrD;AAAA,EAlCA,IAAW,YAAY;AACrB,WAAO;AAAA,EACT;AAAA,EAEU,uBAAuB;AAC/B,WAAO,KAAK,QAAQ,UAAU;AAAA,EAChC;AAAA,EAEQ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAyBR,MAAa,WACX,SACA;AACA,UAAM,OAAO,qBAAqB,OAAwB;AAC1D,QAAI,SAAS,KAAK,eAAe;AAC/B,WAAK,QAAQ,OAAO;AAAA,QAClB,GAAG;AAAA,QACH,SAAS,CAAC,GAAG,QAAQ,SAAS,GAAG,KAAK,aAAa;AAAA,QACnD,UAAU,KAAK;AAAA,QACf,UAAU,KAAK;AAAA,MACjB,CAAC;AAAA,IACH;AAEA,SAAK,aAAa;AAAA,EACpB;AAAA,EAEO,eAAe;AACpB,SAAK,gBAAgB;AACrB,SAAK,mBAAmB;AAAA,EAC1B;AACF;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"toolResultStream.d.ts","sourceRoot":"","sources":["../../../../src/runtimes/edge/streams/toolResultStream.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,0CAA0C,CAAC;AAChE,OAAO,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAG7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAEnE,MAAM,MAAM,oBAAoB,GAC5B,yBAAyB,GACzB;IACE,IAAI,EAAE,aAAa,CAAC;IACpB,WAAW,EAAE,iBAAiB,EAAE,CAAC;CAClC,GACD;IACE,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,iBAAiB,EAAE,CAAC;CAC3B,GACD;IACE,IAAI,EAAE,aAAa,CAAC;IACpB,YAAY,EAAE,UAAU,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,GACD;IACE,IAAI,EAAE,aAAa,CAAC;IACpB,YAAY,EACR,MAAM,GACN,QAAQ,GACR,gBAAgB,GAChB,YAAY,GACZ,OAAO,GACP,OAAO,GACP,SAAS,CAAC;IACd,KAAK,EAAE;QACL,YAAY,EAAE,MAAM,CAAC;QACrB,gBAAgB,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF,WAAW,EAAE,OAAO,CAAC;CACtB,CAAC;AAEN,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,SAAS,EACvC,WAAW,EAAE,WAAW,+DA0GzB"}
1
+ {"version":3,"file":"toolResultStream.d.ts","sourceRoot":"","sources":["../../../../src/runtimes/edge/streams/toolResultStream.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,0CAA0C,CAAC;AAChE,OAAO,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAG7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAEnE,MAAM,MAAM,oBAAoB,GAC5B,yBAAyB,GACzB;IACE,IAAI,EAAE,aAAa,CAAC;IACpB,WAAW,EAAE,iBAAiB,EAAE,CAAC;CAClC,GACD;IACE,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,iBAAiB,EAAE,CAAC;CAC3B,GACD;IACE,IAAI,EAAE,aAAa,CAAC;IACpB,YAAY,EAAE,UAAU,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,GACD;IACE,IAAI,EAAE,aAAa,CAAC;IACpB,YAAY,EACR,MAAM,GACN,QAAQ,GACR,gBAAgB,GAChB,YAAY,GACZ,OAAO,GACP,OAAO,GACP,SAAS,CAAC;IACd,KAAK,EAAE;QACL,YAAY,EAAE,MAAM,CAAC;QACrB,gBAAgB,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF,WAAW,EAAE,OAAO,CAAC;CACtB,CAAC;AAEN,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,SAAS,EACvC,WAAW,EAAE,WAAW,+DA4GzB"}
@@ -60,26 +60,24 @@ function toolResultStream(tools, abortSignal) {
60
60
  });
61
61
  return;
62
62
  }
63
- if (tool.parameters instanceof import_zod.z.ZodType) {
64
- const result = tool.parameters.safeParse(args);
65
- if (!result.success) {
66
- controller.enqueue({
67
- type: "tool-result",
68
- toolCallType,
69
- toolCallId,
70
- toolName,
71
- result: "Function parameter validation failed. " + JSON.stringify(result.error.issues),
72
- isError: true
73
- });
74
- return;
75
- }
76
- }
77
63
  toolCallExecutions.set(
78
64
  toolCallId,
79
65
  (async () => {
80
66
  if (!tool.execute) return;
67
+ let executeFn = tool.execute;
68
+ if (tool.parameters instanceof import_zod.z.ZodType) {
69
+ const result = tool.parameters.safeParse(args);
70
+ if (!result.success) {
71
+ executeFn = tool.experimental_onSchemaValidationError ?? (() => {
72
+ throw "Function parameter validation failed. " + JSON.stringify(result.error.issues);
73
+ });
74
+ }
75
+ }
81
76
  try {
82
- const result = await tool.execute(args, { abortSignal });
77
+ const result = await executeFn(args, {
78
+ toolCallId,
79
+ abortSignal
80
+ });
83
81
  controller.enqueue({
84
82
  type: "tool-result",
85
83
  toolCallType,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/runtimes/edge/streams/toolResultStream.ts"],"sourcesContent":["import { Tool } from \"../../../model-context/ModelContextTypes\";\nimport { LanguageModelV1StreamPart } from \"@ai-sdk/provider\";\nimport { z } from \"zod\";\nimport sjson from \"secure-json-parse\";\nimport { ReadonlyJSONValue } from \"../../../utils/json/json-value\";\n\nexport type ToolResultStreamPart =\n | LanguageModelV1StreamPart\n | {\n type: \"annotations\";\n annotations: ReadonlyJSONValue[];\n }\n | {\n type: \"data\";\n data: ReadonlyJSONValue[];\n }\n | {\n type: \"tool-result\";\n toolCallType: \"function\";\n toolCallId: string;\n toolName: string;\n result: unknown;\n isError?: boolean;\n }\n | {\n type: \"step-finish\";\n finishReason:\n | \"stop\"\n | \"length\"\n | \"content-filter\"\n | \"tool-calls\"\n | \"error\"\n | \"other\"\n | \"unknown\";\n usage: {\n promptTokens: number;\n completionTokens: number;\n };\n isContinued: boolean;\n };\n\nexport function toolResultStream(\n tools: Record<string, Tool> | undefined,\n abortSignal: AbortSignal,\n) {\n const toolCallExecutions = new Map<string, Promise<any>>();\n\n return new TransformStream<ToolResultStreamPart, ToolResultStreamPart>({\n transform(chunk, controller) {\n // forward everything\n controller.enqueue(chunk);\n\n // handle tool calls\n const chunkType = chunk.type;\n switch (chunkType) {\n case \"tool-call\": {\n const { toolCallId, toolCallType, toolName, args: argsText } = chunk;\n const tool = tools?.[toolName];\n if (!tool || !tool.execute) return;\n\n let args;\n try {\n args = sjson.parse(argsText);\n } catch (e) {\n controller.enqueue({\n type: \"tool-result\",\n toolCallType,\n toolCallId,\n toolName,\n result:\n \"Function parameter parsing failed. \" +\n JSON.stringify((e as Error).message),\n isError: true,\n });\n return;\n }\n\n if (tool.parameters instanceof z.ZodType) {\n const result = tool.parameters.safeParse(args);\n if (!result.success) {\n controller.enqueue({\n type: \"tool-result\",\n toolCallType,\n toolCallId,\n toolName,\n result:\n \"Function parameter validation failed. \" +\n JSON.stringify(result.error.issues),\n isError: true,\n });\n return;\n }\n }\n\n toolCallExecutions.set(\n toolCallId,\n (async () => {\n if (!tool.execute) return;\n\n try {\n const result = await tool.execute(args, { abortSignal });\n\n controller.enqueue({\n type: \"tool-result\",\n toolCallType,\n toolCallId,\n toolName,\n result,\n });\n } catch (error) {\n controller.enqueue({\n type: \"tool-result\",\n toolCallType,\n toolCallId,\n toolName,\n result: \"Error: \" + error,\n isError: true,\n });\n } finally {\n toolCallExecutions.delete(toolCallId);\n }\n })(),\n );\n break;\n }\n\n // ignore other parts\n case \"text-delta\":\n case \"tool-call-delta\":\n case \"tool-result\":\n case \"step-finish\":\n case \"finish\":\n case \"error\":\n case \"response-metadata\":\n case \"annotations\":\n case \"data\":\n break;\n\n default: {\n const unhandledType: never = chunkType;\n throw new Error(`Unhandled chunk type: ${unhandledType}`);\n }\n }\n },\n\n async flush() {\n await Promise.all(toolCallExecutions.values());\n },\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,iBAAkB;AAClB,+BAAkB;AAsCX,SAAS,iBACd,OACA,aACA;AACA,QAAM,qBAAqB,oBAAI,IAA0B;AAEzD,SAAO,IAAI,gBAA4D;AAAA,IACrE,UAAU,OAAO,YAAY;AAE3B,iBAAW,QAAQ,KAAK;AAGxB,YAAM,YAAY,MAAM;AACxB,cAAQ,WAAW;AAAA,QACjB,KAAK,aAAa;AAChB,gBAAM,EAAE,YAAY,cAAc,UAAU,MAAM,SAAS,IAAI;AAC/D,gBAAM,OAAO,QAAQ,QAAQ;AAC7B,cAAI,CAAC,QAAQ,CAAC,KAAK,QAAS;AAE5B,cAAI;AACJ,cAAI;AACF,mBAAO,yBAAAA,QAAM,MAAM,QAAQ;AAAA,UAC7B,SAAS,GAAG;AACV,uBAAW,QAAQ;AAAA,cACjB,MAAM;AAAA,cACN;AAAA,cACA;AAAA,cACA;AAAA,cACA,QACE,wCACA,KAAK,UAAW,EAAY,OAAO;AAAA,cACrC,SAAS;AAAA,YACX,CAAC;AACD;AAAA,UACF;AAEA,cAAI,KAAK,sBAAsB,aAAE,SAAS;AACxC,kBAAM,SAAS,KAAK,WAAW,UAAU,IAAI;AAC7C,gBAAI,CAAC,OAAO,SAAS;AACnB,yBAAW,QAAQ;AAAA,gBACjB,MAAM;AAAA,gBACN;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA,QACE,2CACA,KAAK,UAAU,OAAO,MAAM,MAAM;AAAA,gBACpC,SAAS;AAAA,cACX,CAAC;AACD;AAAA,YACF;AAAA,UACF;AAEA,6BAAmB;AAAA,YACjB;AAAA,aACC,YAAY;AACX,kBAAI,CAAC,KAAK,QAAS;AAEnB,kBAAI;AACF,sBAAM,SAAS,MAAM,KAAK,QAAQ,MAAM,EAAE,YAAY,CAAC;AAEvD,2BAAW,QAAQ;AAAA,kBACjB,MAAM;AAAA,kBACN;AAAA,kBACA;AAAA,kBACA;AAAA,kBACA;AAAA,gBACF,CAAC;AAAA,cACH,SAAS,OAAO;AACd,2BAAW,QAAQ;AAAA,kBACjB,MAAM;AAAA,kBACN;AAAA,kBACA;AAAA,kBACA;AAAA,kBACA,QAAQ,YAAY;AAAA,kBACpB,SAAS;AAAA,gBACX,CAAC;AAAA,cACH,UAAE;AACA,mCAAmB,OAAO,UAAU;AAAA,cACtC;AAAA,YACF,GAAG;AAAA,UACL;AACA;AAAA,QACF;AAAA;AAAA,QAGA,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AACH;AAAA,QAEF,SAAS;AACP,gBAAM,gBAAuB;AAC7B,gBAAM,IAAI,MAAM,yBAAyB,aAAa,EAAE;AAAA,QAC1D;AAAA,MACF;AAAA,IACF;AAAA,IAEA,MAAM,QAAQ;AACZ,YAAM,QAAQ,IAAI,mBAAmB,OAAO,CAAC;AAAA,IAC/C;AAAA,EACF,CAAC;AACH;","names":["sjson"]}
1
+ {"version":3,"sources":["../../../../src/runtimes/edge/streams/toolResultStream.ts"],"sourcesContent":["import { Tool } from \"../../../model-context/ModelContextTypes\";\nimport { LanguageModelV1StreamPart } from \"@ai-sdk/provider\";\nimport { z } from \"zod\";\nimport sjson from \"secure-json-parse\";\nimport { ReadonlyJSONValue } from \"../../../utils/json/json-value\";\n\nexport type ToolResultStreamPart =\n | LanguageModelV1StreamPart\n | {\n type: \"annotations\";\n annotations: ReadonlyJSONValue[];\n }\n | {\n type: \"data\";\n data: ReadonlyJSONValue[];\n }\n | {\n type: \"tool-result\";\n toolCallType: \"function\";\n toolCallId: string;\n toolName: string;\n result: unknown;\n isError?: boolean;\n }\n | {\n type: \"step-finish\";\n finishReason:\n | \"stop\"\n | \"length\"\n | \"content-filter\"\n | \"tool-calls\"\n | \"error\"\n | \"other\"\n | \"unknown\";\n usage: {\n promptTokens: number;\n completionTokens: number;\n };\n isContinued: boolean;\n };\n\nexport function toolResultStream(\n tools: Record<string, Tool> | undefined,\n abortSignal: AbortSignal,\n) {\n const toolCallExecutions = new Map<string, Promise<any>>();\n\n return new TransformStream<ToolResultStreamPart, ToolResultStreamPart>({\n transform(chunk, controller) {\n // forward everything\n controller.enqueue(chunk);\n\n // handle tool calls\n const chunkType = chunk.type;\n switch (chunkType) {\n case \"tool-call\": {\n const { toolCallId, toolCallType, toolName, args: argsText } = chunk;\n const tool = tools?.[toolName];\n if (!tool || !tool.execute) return;\n\n let args;\n try {\n args = sjson.parse(argsText);\n } catch (e) {\n controller.enqueue({\n type: \"tool-result\",\n toolCallType,\n toolCallId,\n toolName,\n result:\n \"Function parameter parsing failed. \" +\n JSON.stringify((e as Error).message),\n isError: true,\n });\n return;\n }\n\n toolCallExecutions.set(\n toolCallId,\n (async () => {\n if (!tool.execute) return;\n\n let executeFn = tool.execute;\n\n if (tool.parameters instanceof z.ZodType) {\n const result = tool.parameters.safeParse(args);\n if (!result.success) {\n executeFn =\n tool.experimental_onSchemaValidationError ??\n (() => {\n throw (\n \"Function parameter validation failed. \" +\n JSON.stringify(result.error.issues)\n );\n });\n }\n }\n\n try {\n const result = await executeFn(args, {\n toolCallId,\n abortSignal,\n });\n\n controller.enqueue({\n type: \"tool-result\",\n toolCallType,\n toolCallId,\n toolName,\n result,\n });\n } catch (error) {\n controller.enqueue({\n type: \"tool-result\",\n toolCallType,\n toolCallId,\n toolName,\n result: \"Error: \" + error,\n isError: true,\n });\n } finally {\n toolCallExecutions.delete(toolCallId);\n }\n })(),\n );\n break;\n }\n\n // ignore other parts\n case \"text-delta\":\n case \"tool-call-delta\":\n case \"tool-result\":\n case \"step-finish\":\n case \"finish\":\n case \"error\":\n case \"response-metadata\":\n case \"annotations\":\n case \"data\":\n break;\n\n default: {\n const unhandledType: never = chunkType;\n throw new Error(`Unhandled chunk type: ${unhandledType}`);\n }\n }\n },\n\n async flush() {\n await Promise.all(toolCallExecutions.values());\n },\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,iBAAkB;AAClB,+BAAkB;AAsCX,SAAS,iBACd,OACA,aACA;AACA,QAAM,qBAAqB,oBAAI,IAA0B;AAEzD,SAAO,IAAI,gBAA4D;AAAA,IACrE,UAAU,OAAO,YAAY;AAE3B,iBAAW,QAAQ,KAAK;AAGxB,YAAM,YAAY,MAAM;AACxB,cAAQ,WAAW;AAAA,QACjB,KAAK,aAAa;AAChB,gBAAM,EAAE,YAAY,cAAc,UAAU,MAAM,SAAS,IAAI;AAC/D,gBAAM,OAAO,QAAQ,QAAQ;AAC7B,cAAI,CAAC,QAAQ,CAAC,KAAK,QAAS;AAE5B,cAAI;AACJ,cAAI;AACF,mBAAO,yBAAAA,QAAM,MAAM,QAAQ;AAAA,UAC7B,SAAS,GAAG;AACV,uBAAW,QAAQ;AAAA,cACjB,MAAM;AAAA,cACN;AAAA,cACA;AAAA,cACA;AAAA,cACA,QACE,wCACA,KAAK,UAAW,EAAY,OAAO;AAAA,cACrC,SAAS;AAAA,YACX,CAAC;AACD;AAAA,UACF;AAEA,6BAAmB;AAAA,YACjB;AAAA,aACC,YAAY;AACX,kBAAI,CAAC,KAAK,QAAS;AAEnB,kBAAI,YAAY,KAAK;AAErB,kBAAI,KAAK,sBAAsB,aAAE,SAAS;AACxC,sBAAM,SAAS,KAAK,WAAW,UAAU,IAAI;AAC7C,oBAAI,CAAC,OAAO,SAAS;AACnB,8BACE,KAAK,yCACJ,MAAM;AACL,0BACE,2CACA,KAAK,UAAU,OAAO,MAAM,MAAM;AAAA,kBAEtC;AAAA,gBACJ;AAAA,cACF;AAEA,kBAAI;AACF,sBAAM,SAAS,MAAM,UAAU,MAAM;AAAA,kBACnC;AAAA,kBACA;AAAA,gBACF,CAAC;AAED,2BAAW,QAAQ;AAAA,kBACjB,MAAM;AAAA,kBACN;AAAA,kBACA;AAAA,kBACA;AAAA,kBACA;AAAA,gBACF,CAAC;AAAA,cACH,SAAS,OAAO;AACd,2BAAW,QAAQ;AAAA,kBACjB,MAAM;AAAA,kBACN;AAAA,kBACA;AAAA,kBACA;AAAA,kBACA,QAAQ,YAAY;AAAA,kBACpB,SAAS;AAAA,gBACX,CAAC;AAAA,cACH,UAAE;AACA,mCAAmB,OAAO,UAAU;AAAA,cACtC;AAAA,YACF,GAAG;AAAA,UACL;AACA;AAAA,QACF;AAAA;AAAA,QAGA,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AACH;AAAA,QAEF,SAAS;AACP,gBAAM,gBAAuB;AAC7B,gBAAM,IAAI,MAAM,yBAAyB,aAAa,EAAE;AAAA,QAC1D;AAAA,MACF;AAAA,IACF;AAAA,IAEA,MAAM,QAAQ;AACZ,YAAM,QAAQ,IAAI,mBAAmB,OAAO,CAAC;AAAA,IAC/C;AAAA,EACF,CAAC;AACH;","names":["sjson"]}
@@ -26,26 +26,24 @@ function toolResultStream(tools, abortSignal) {
26
26
  });
27
27
  return;
28
28
  }
29
- if (tool.parameters instanceof z.ZodType) {
30
- const result = tool.parameters.safeParse(args);
31
- if (!result.success) {
32
- controller.enqueue({
33
- type: "tool-result",
34
- toolCallType,
35
- toolCallId,
36
- toolName,
37
- result: "Function parameter validation failed. " + JSON.stringify(result.error.issues),
38
- isError: true
39
- });
40
- return;
41
- }
42
- }
43
29
  toolCallExecutions.set(
44
30
  toolCallId,
45
31
  (async () => {
46
32
  if (!tool.execute) return;
33
+ let executeFn = tool.execute;
34
+ if (tool.parameters instanceof z.ZodType) {
35
+ const result = tool.parameters.safeParse(args);
36
+ if (!result.success) {
37
+ executeFn = tool.experimental_onSchemaValidationError ?? (() => {
38
+ throw "Function parameter validation failed. " + JSON.stringify(result.error.issues);
39
+ });
40
+ }
41
+ }
47
42
  try {
48
- const result = await tool.execute(args, { abortSignal });
43
+ const result = await executeFn(args, {
44
+ toolCallId,
45
+ abortSignal
46
+ });
49
47
  controller.enqueue({
50
48
  type: "tool-result",
51
49
  toolCallType,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/runtimes/edge/streams/toolResultStream.ts"],"sourcesContent":["import { Tool } from \"../../../model-context/ModelContextTypes\";\nimport { LanguageModelV1StreamPart } from \"@ai-sdk/provider\";\nimport { z } from \"zod\";\nimport sjson from \"secure-json-parse\";\nimport { ReadonlyJSONValue } from \"../../../utils/json/json-value\";\n\nexport type ToolResultStreamPart =\n | LanguageModelV1StreamPart\n | {\n type: \"annotations\";\n annotations: ReadonlyJSONValue[];\n }\n | {\n type: \"data\";\n data: ReadonlyJSONValue[];\n }\n | {\n type: \"tool-result\";\n toolCallType: \"function\";\n toolCallId: string;\n toolName: string;\n result: unknown;\n isError?: boolean;\n }\n | {\n type: \"step-finish\";\n finishReason:\n | \"stop\"\n | \"length\"\n | \"content-filter\"\n | \"tool-calls\"\n | \"error\"\n | \"other\"\n | \"unknown\";\n usage: {\n promptTokens: number;\n completionTokens: number;\n };\n isContinued: boolean;\n };\n\nexport function toolResultStream(\n tools: Record<string, Tool> | undefined,\n abortSignal: AbortSignal,\n) {\n const toolCallExecutions = new Map<string, Promise<any>>();\n\n return new TransformStream<ToolResultStreamPart, ToolResultStreamPart>({\n transform(chunk, controller) {\n // forward everything\n controller.enqueue(chunk);\n\n // handle tool calls\n const chunkType = chunk.type;\n switch (chunkType) {\n case \"tool-call\": {\n const { toolCallId, toolCallType, toolName, args: argsText } = chunk;\n const tool = tools?.[toolName];\n if (!tool || !tool.execute) return;\n\n let args;\n try {\n args = sjson.parse(argsText);\n } catch (e) {\n controller.enqueue({\n type: \"tool-result\",\n toolCallType,\n toolCallId,\n toolName,\n result:\n \"Function parameter parsing failed. \" +\n JSON.stringify((e as Error).message),\n isError: true,\n });\n return;\n }\n\n if (tool.parameters instanceof z.ZodType) {\n const result = tool.parameters.safeParse(args);\n if (!result.success) {\n controller.enqueue({\n type: \"tool-result\",\n toolCallType,\n toolCallId,\n toolName,\n result:\n \"Function parameter validation failed. \" +\n JSON.stringify(result.error.issues),\n isError: true,\n });\n return;\n }\n }\n\n toolCallExecutions.set(\n toolCallId,\n (async () => {\n if (!tool.execute) return;\n\n try {\n const result = await tool.execute(args, { abortSignal });\n\n controller.enqueue({\n type: \"tool-result\",\n toolCallType,\n toolCallId,\n toolName,\n result,\n });\n } catch (error) {\n controller.enqueue({\n type: \"tool-result\",\n toolCallType,\n toolCallId,\n toolName,\n result: \"Error: \" + error,\n isError: true,\n });\n } finally {\n toolCallExecutions.delete(toolCallId);\n }\n })(),\n );\n break;\n }\n\n // ignore other parts\n case \"text-delta\":\n case \"tool-call-delta\":\n case \"tool-result\":\n case \"step-finish\":\n case \"finish\":\n case \"error\":\n case \"response-metadata\":\n case \"annotations\":\n case \"data\":\n break;\n\n default: {\n const unhandledType: never = chunkType;\n throw new Error(`Unhandled chunk type: ${unhandledType}`);\n }\n }\n },\n\n async flush() {\n await Promise.all(toolCallExecutions.values());\n },\n });\n}\n"],"mappings":";AAEA,SAAS,SAAS;AAClB,OAAO,WAAW;AAsCX,SAAS,iBACd,OACA,aACA;AACA,QAAM,qBAAqB,oBAAI,IAA0B;AAEzD,SAAO,IAAI,gBAA4D;AAAA,IACrE,UAAU,OAAO,YAAY;AAE3B,iBAAW,QAAQ,KAAK;AAGxB,YAAM,YAAY,MAAM;AACxB,cAAQ,WAAW;AAAA,QACjB,KAAK,aAAa;AAChB,gBAAM,EAAE,YAAY,cAAc,UAAU,MAAM,SAAS,IAAI;AAC/D,gBAAM,OAAO,QAAQ,QAAQ;AAC7B,cAAI,CAAC,QAAQ,CAAC,KAAK,QAAS;AAE5B,cAAI;AACJ,cAAI;AACF,mBAAO,MAAM,MAAM,QAAQ;AAAA,UAC7B,SAAS,GAAG;AACV,uBAAW,QAAQ;AAAA,cACjB,MAAM;AAAA,cACN;AAAA,cACA;AAAA,cACA;AAAA,cACA,QACE,wCACA,KAAK,UAAW,EAAY,OAAO;AAAA,cACrC,SAAS;AAAA,YACX,CAAC;AACD;AAAA,UACF;AAEA,cAAI,KAAK,sBAAsB,EAAE,SAAS;AACxC,kBAAM,SAAS,KAAK,WAAW,UAAU,IAAI;AAC7C,gBAAI,CAAC,OAAO,SAAS;AACnB,yBAAW,QAAQ;AAAA,gBACjB,MAAM;AAAA,gBACN;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA,QACE,2CACA,KAAK,UAAU,OAAO,MAAM,MAAM;AAAA,gBACpC,SAAS;AAAA,cACX,CAAC;AACD;AAAA,YACF;AAAA,UACF;AAEA,6BAAmB;AAAA,YACjB;AAAA,aACC,YAAY;AACX,kBAAI,CAAC,KAAK,QAAS;AAEnB,kBAAI;AACF,sBAAM,SAAS,MAAM,KAAK,QAAQ,MAAM,EAAE,YAAY,CAAC;AAEvD,2BAAW,QAAQ;AAAA,kBACjB,MAAM;AAAA,kBACN;AAAA,kBACA;AAAA,kBACA;AAAA,kBACA;AAAA,gBACF,CAAC;AAAA,cACH,SAAS,OAAO;AACd,2BAAW,QAAQ;AAAA,kBACjB,MAAM;AAAA,kBACN;AAAA,kBACA;AAAA,kBACA;AAAA,kBACA,QAAQ,YAAY;AAAA,kBACpB,SAAS;AAAA,gBACX,CAAC;AAAA,cACH,UAAE;AACA,mCAAmB,OAAO,UAAU;AAAA,cACtC;AAAA,YACF,GAAG;AAAA,UACL;AACA;AAAA,QACF;AAAA;AAAA,QAGA,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AACH;AAAA,QAEF,SAAS;AACP,gBAAM,gBAAuB;AAC7B,gBAAM,IAAI,MAAM,yBAAyB,aAAa,EAAE;AAAA,QAC1D;AAAA,MACF;AAAA,IACF;AAAA,IAEA,MAAM,QAAQ;AACZ,YAAM,QAAQ,IAAI,mBAAmB,OAAO,CAAC;AAAA,IAC/C;AAAA,EACF,CAAC;AACH;","names":[]}
1
+ {"version":3,"sources":["../../../../src/runtimes/edge/streams/toolResultStream.ts"],"sourcesContent":["import { Tool } from \"../../../model-context/ModelContextTypes\";\nimport { LanguageModelV1StreamPart } from \"@ai-sdk/provider\";\nimport { z } from \"zod\";\nimport sjson from \"secure-json-parse\";\nimport { ReadonlyJSONValue } from \"../../../utils/json/json-value\";\n\nexport type ToolResultStreamPart =\n | LanguageModelV1StreamPart\n | {\n type: \"annotations\";\n annotations: ReadonlyJSONValue[];\n }\n | {\n type: \"data\";\n data: ReadonlyJSONValue[];\n }\n | {\n type: \"tool-result\";\n toolCallType: \"function\";\n toolCallId: string;\n toolName: string;\n result: unknown;\n isError?: boolean;\n }\n | {\n type: \"step-finish\";\n finishReason:\n | \"stop\"\n | \"length\"\n | \"content-filter\"\n | \"tool-calls\"\n | \"error\"\n | \"other\"\n | \"unknown\";\n usage: {\n promptTokens: number;\n completionTokens: number;\n };\n isContinued: boolean;\n };\n\nexport function toolResultStream(\n tools: Record<string, Tool> | undefined,\n abortSignal: AbortSignal,\n) {\n const toolCallExecutions = new Map<string, Promise<any>>();\n\n return new TransformStream<ToolResultStreamPart, ToolResultStreamPart>({\n transform(chunk, controller) {\n // forward everything\n controller.enqueue(chunk);\n\n // handle tool calls\n const chunkType = chunk.type;\n switch (chunkType) {\n case \"tool-call\": {\n const { toolCallId, toolCallType, toolName, args: argsText } = chunk;\n const tool = tools?.[toolName];\n if (!tool || !tool.execute) return;\n\n let args;\n try {\n args = sjson.parse(argsText);\n } catch (e) {\n controller.enqueue({\n type: \"tool-result\",\n toolCallType,\n toolCallId,\n toolName,\n result:\n \"Function parameter parsing failed. \" +\n JSON.stringify((e as Error).message),\n isError: true,\n });\n return;\n }\n\n toolCallExecutions.set(\n toolCallId,\n (async () => {\n if (!tool.execute) return;\n\n let executeFn = tool.execute;\n\n if (tool.parameters instanceof z.ZodType) {\n const result = tool.parameters.safeParse(args);\n if (!result.success) {\n executeFn =\n tool.experimental_onSchemaValidationError ??\n (() => {\n throw (\n \"Function parameter validation failed. \" +\n JSON.stringify(result.error.issues)\n );\n });\n }\n }\n\n try {\n const result = await executeFn(args, {\n toolCallId,\n abortSignal,\n });\n\n controller.enqueue({\n type: \"tool-result\",\n toolCallType,\n toolCallId,\n toolName,\n result,\n });\n } catch (error) {\n controller.enqueue({\n type: \"tool-result\",\n toolCallType,\n toolCallId,\n toolName,\n result: \"Error: \" + error,\n isError: true,\n });\n } finally {\n toolCallExecutions.delete(toolCallId);\n }\n })(),\n );\n break;\n }\n\n // ignore other parts\n case \"text-delta\":\n case \"tool-call-delta\":\n case \"tool-result\":\n case \"step-finish\":\n case \"finish\":\n case \"error\":\n case \"response-metadata\":\n case \"annotations\":\n case \"data\":\n break;\n\n default: {\n const unhandledType: never = chunkType;\n throw new Error(`Unhandled chunk type: ${unhandledType}`);\n }\n }\n },\n\n async flush() {\n await Promise.all(toolCallExecutions.values());\n },\n });\n}\n"],"mappings":";AAEA,SAAS,SAAS;AAClB,OAAO,WAAW;AAsCX,SAAS,iBACd,OACA,aACA;AACA,QAAM,qBAAqB,oBAAI,IAA0B;AAEzD,SAAO,IAAI,gBAA4D;AAAA,IACrE,UAAU,OAAO,YAAY;AAE3B,iBAAW,QAAQ,KAAK;AAGxB,YAAM,YAAY,MAAM;AACxB,cAAQ,WAAW;AAAA,QACjB,KAAK,aAAa;AAChB,gBAAM,EAAE,YAAY,cAAc,UAAU,MAAM,SAAS,IAAI;AAC/D,gBAAM,OAAO,QAAQ,QAAQ;AAC7B,cAAI,CAAC,QAAQ,CAAC,KAAK,QAAS;AAE5B,cAAI;AACJ,cAAI;AACF,mBAAO,MAAM,MAAM,QAAQ;AAAA,UAC7B,SAAS,GAAG;AACV,uBAAW,QAAQ;AAAA,cACjB,MAAM;AAAA,cACN;AAAA,cACA;AAAA,cACA;AAAA,cACA,QACE,wCACA,KAAK,UAAW,EAAY,OAAO;AAAA,cACrC,SAAS;AAAA,YACX,CAAC;AACD;AAAA,UACF;AAEA,6BAAmB;AAAA,YACjB;AAAA,aACC,YAAY;AACX,kBAAI,CAAC,KAAK,QAAS;AAEnB,kBAAI,YAAY,KAAK;AAErB,kBAAI,KAAK,sBAAsB,EAAE,SAAS;AACxC,sBAAM,SAAS,KAAK,WAAW,UAAU,IAAI;AAC7C,oBAAI,CAAC,OAAO,SAAS;AACnB,8BACE,KAAK,yCACJ,MAAM;AACL,0BACE,2CACA,KAAK,UAAU,OAAO,MAAM,MAAM;AAAA,kBAEtC;AAAA,gBACJ;AAAA,cACF;AAEA,kBAAI;AACF,sBAAM,SAAS,MAAM,UAAU,MAAM;AAAA,kBACnC;AAAA,kBACA;AAAA,gBACF,CAAC;AAED,2BAAW,QAAQ;AAAA,kBACjB,MAAM;AAAA,kBACN;AAAA,kBACA;AAAA,kBACA;AAAA,kBACA;AAAA,gBACF,CAAC;AAAA,cACH,SAAS,OAAO;AACd,2BAAW,QAAQ;AAAA,kBACjB,MAAM;AAAA,kBACN;AAAA,kBACA;AAAA,kBACA;AAAA,kBACA,QAAQ,YAAY;AAAA,kBACpB,SAAS;AAAA,gBACX,CAAC;AAAA,cACH,UAAE;AACA,mCAAmB,OAAO,UAAU;AAAA,cACtC;AAAA,YACF,GAAG;AAAA,UACL;AACA;AAAA,QACF;AAAA;AAAA,QAGA,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AACH;AAAA,QAEF,SAAS;AACP,gBAAM,gBAAuB;AAC7B,gBAAM,IAAI,MAAM,yBAAyB,aAAa,EAAE;AAAA,QAC1D;AAAA,MACF;AAAA,IACF;AAAA,IAEA,MAAM,QAAQ;AACZ,YAAM,QAAQ,IAAI,mBAAmB,OAAO,CAAC;AAAA,IAC/C;AAAA,EACF,CAAC;AACH;","names":[]}
@@ -26,10 +26,10 @@ __export(useOnScrollToBottom_exports, {
26
26
  module.exports = __toCommonJS(useOnScrollToBottom_exports);
27
27
  var import_react_use_callback_ref = require("@radix-ui/react-use-callback-ref");
28
28
  var import_react = require("react");
29
- var import_ThreadContext = require("../../context/react/ThreadContext.js");
29
+ var import_ThreadViewportContext = require("../../context/react/ThreadViewportContext.js");
30
30
  var useOnScrollToBottom = (callback) => {
31
31
  const callbackRef = (0, import_react_use_callback_ref.useCallbackRef)(callback);
32
- const onScrollToBottom = (0, import_ThreadContext.useThreadViewport)((vp) => vp.onScrollToBottom);
32
+ const onScrollToBottom = (0, import_ThreadViewportContext.useThreadViewport)((vp) => vp.onScrollToBottom);
33
33
  (0, import_react.useEffect)(() => {
34
34
  return onScrollToBottom(callbackRef);
35
35
  }, [onScrollToBottom, callbackRef]);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/hooks/useOnScrollToBottom.tsx"],"sourcesContent":["\"use client\";\n\nimport { useCallbackRef } from \"@radix-ui/react-use-callback-ref\";\nimport { useEffect } from \"react\";\nimport { useThreadViewport } from \"../../context/react/ThreadContext\";\n\nexport const useOnScrollToBottom = (callback: () => void) => {\n const callbackRef = useCallbackRef(callback);\n const onScrollToBottom = useThreadViewport((vp) => vp.onScrollToBottom);\n\n useEffect(() => {\n return onScrollToBottom(callbackRef);\n }, [onScrollToBottom, callbackRef]);\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,oCAA+B;AAC/B,mBAA0B;AAC1B,2BAAkC;AAE3B,IAAM,sBAAsB,CAAC,aAAyB;AAC3D,QAAM,kBAAc,8CAAe,QAAQ;AAC3C,QAAM,uBAAmB,wCAAkB,CAAC,OAAO,GAAG,gBAAgB;AAEtE,8BAAU,MAAM;AACd,WAAO,iBAAiB,WAAW;AAAA,EACrC,GAAG,CAAC,kBAAkB,WAAW,CAAC;AACpC;","names":[]}
1
+ {"version":3,"sources":["../../../src/utils/hooks/useOnScrollToBottom.tsx"],"sourcesContent":["\"use client\";\n\nimport { useCallbackRef } from \"@radix-ui/react-use-callback-ref\";\nimport { useEffect } from \"react\";\nimport { useThreadViewport } from \"../../context/react/ThreadViewportContext\";\n\nexport const useOnScrollToBottom = (callback: () => void) => {\n const callbackRef = useCallbackRef(callback);\n const onScrollToBottom = useThreadViewport((vp) => vp.onScrollToBottom);\n\n useEffect(() => {\n return onScrollToBottom(callbackRef);\n }, [onScrollToBottom, callbackRef]);\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,oCAA+B;AAC/B,mBAA0B;AAC1B,mCAAkC;AAE3B,IAAM,sBAAsB,CAAC,aAAyB;AAC3D,QAAM,kBAAc,8CAAe,QAAQ;AAC3C,QAAM,uBAAmB,gDAAkB,CAAC,OAAO,GAAG,gBAAgB;AAEtE,8BAAU,MAAM;AACd,WAAO,iBAAiB,WAAW;AAAA,EACrC,GAAG,CAAC,kBAAkB,WAAW,CAAC;AACpC;","names":[]}
@@ -3,7 +3,7 @@
3
3
  // src/utils/hooks/useOnScrollToBottom.tsx
4
4
  import { useCallbackRef } from "@radix-ui/react-use-callback-ref";
5
5
  import { useEffect } from "react";
6
- import { useThreadViewport } from "../../context/react/ThreadContext.mjs";
6
+ import { useThreadViewport } from "../../context/react/ThreadViewportContext.mjs";
7
7
  var useOnScrollToBottom = (callback) => {
8
8
  const callbackRef = useCallbackRef(callback);
9
9
  const onScrollToBottom = useThreadViewport((vp) => vp.onScrollToBottom);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/hooks/useOnScrollToBottom.tsx"],"sourcesContent":["\"use client\";\n\nimport { useCallbackRef } from \"@radix-ui/react-use-callback-ref\";\nimport { useEffect } from \"react\";\nimport { useThreadViewport } from \"../../context/react/ThreadContext\";\n\nexport const useOnScrollToBottom = (callback: () => void) => {\n const callbackRef = useCallbackRef(callback);\n const onScrollToBottom = useThreadViewport((vp) => vp.onScrollToBottom);\n\n useEffect(() => {\n return onScrollToBottom(callbackRef);\n }, [onScrollToBottom, callbackRef]);\n};\n"],"mappings":";;;AAEA,SAAS,sBAAsB;AAC/B,SAAS,iBAAiB;AAC1B,SAAS,yBAAyB;AAE3B,IAAM,sBAAsB,CAAC,aAAyB;AAC3D,QAAM,cAAc,eAAe,QAAQ;AAC3C,QAAM,mBAAmB,kBAAkB,CAAC,OAAO,GAAG,gBAAgB;AAEtE,YAAU,MAAM;AACd,WAAO,iBAAiB,WAAW;AAAA,EACrC,GAAG,CAAC,kBAAkB,WAAW,CAAC;AACpC;","names":[]}
1
+ {"version":3,"sources":["../../../src/utils/hooks/useOnScrollToBottom.tsx"],"sourcesContent":["\"use client\";\n\nimport { useCallbackRef } from \"@radix-ui/react-use-callback-ref\";\nimport { useEffect } from \"react\";\nimport { useThreadViewport } from \"../../context/react/ThreadViewportContext\";\n\nexport const useOnScrollToBottom = (callback: () => void) => {\n const callbackRef = useCallbackRef(callback);\n const onScrollToBottom = useThreadViewport((vp) => vp.onScrollToBottom);\n\n useEffect(() => {\n return onScrollToBottom(callbackRef);\n }, [onScrollToBottom, callbackRef]);\n};\n"],"mappings":";;;AAEA,SAAS,sBAAsB;AAC/B,SAAS,iBAAiB;AAC1B,SAAS,yBAAyB;AAE3B,IAAM,sBAAsB,CAAC,aAAyB;AAC3D,QAAM,cAAc,eAAe,QAAQ;AAC3C,QAAM,mBAAmB,kBAAkB,CAAC,OAAO,GAAG,gBAAgB;AAEtE,YAAU,MAAM;AACd,WAAO,iBAAiB,WAAW;AAAA,EACrC,GAAG,CAAC,kBAAkB,WAAW,CAAC;AACpC;","names":[]}
package/package.json CHANGED
@@ -29,7 +29,7 @@
29
29
  "conversational-ui",
30
30
  "conversational-ai"
31
31
  ],
32
- "version": "0.7.69",
32
+ "version": "0.7.70",
33
33
  "license": "MIT",
34
34
  "exports": {
35
35
  ".": {
@@ -117,9 +117,9 @@
117
117
  "tailwindcss": "^3.4.17",
118
118
  "tailwindcss-animate": "^1.0.7",
119
119
  "tsx": "^4.19.2",
120
- "@assistant-ui/tailwindcss-transformer": "0.1.0",
120
+ "@assistant-ui/tsbuildutils": "^0.0.1",
121
121
  "@assistant-ui/tsconfig": "0.0.0",
122
- "@assistant-ui/tsbuildutils": "^0.0.1"
122
+ "@assistant-ui/tailwindcss-transformer": "0.1.0"
123
123
  },
124
124
  "publishConfig": {
125
125
  "access": "public",
@@ -150,10 +150,7 @@ export class MessageRuntimeImpl implements MessageRuntime {
150
150
  ref: this.path.ref + `${this.path.ref}.composer`,
151
151
  composerSource: "edit",
152
152
  },
153
- getState: () =>
154
- this._threadBinding
155
- .getState()
156
- .getEditComposer(this._core.getState().id),
153
+ getState: this._getEditComposerRuntimeCore,
157
154
  subscribe: (callback) => this._threadBinding.subscribe(callback),
158
155
  }),
159
156
  () => this._threadBinding.getState().beginEdit(this._core.getState().id),
@@ -177,11 +174,23 @@ export class MessageRuntimeImpl implements MessageRuntime {
177
174
 
178
175
  public readonly composer;
179
176
 
177
+ private _getEditComposerRuntimeCore = () => {
178
+ return this._threadBinding
179
+ .getState()
180
+ .getEditComposer(this._core.getState().id);
181
+ };
182
+
180
183
  public getState() {
181
184
  return this._core.getState();
182
185
  }
183
186
 
184
- public reload({ runConfig = {} }: ReloadConfig = {}) {
187
+ public reload(reloadConfig: ReloadConfig = {}) {
188
+ const editComposerRuntimeCore = this._getEditComposerRuntimeCore();
189
+ const composerRuntimeCore =
190
+ editComposerRuntimeCore ?? this._threadBinding.getState().composer;
191
+ const composer = editComposerRuntimeCore ?? composerRuntimeCore;
192
+
193
+ const { runConfig = composer.runConfig } = reloadConfig;
185
194
  const state = this._core.getState();
186
195
  if (state.role !== "assistant")
187
196
  throw new Error("Can only reload assistant messages");
@@ -4,13 +4,13 @@ import type { FC, PropsWithChildren } from "react";
4
4
  import { useEffect, useState } from "react";
5
5
  import type { ThreadContextValue } from "../react/ThreadContext";
6
6
  import { ThreadContext } from "../react/ThreadContext";
7
- import { makeThreadViewportStore } from "../stores/ThreadViewport";
8
7
  import { writableStore } from "../ReadonlyStore";
9
8
  import { ThreadRuntime } from "../../api/ThreadRuntime";
10
9
  import { create } from "zustand";
11
10
  import { ThreadListItemRuntime } from "../../api/ThreadListItemRuntime";
12
11
  import { ThreadListItemRuntimeProvider } from "./ThreadListItemRuntimeProvider";
13
12
  import { ensureBinding } from "../react/utils/ensureBinding";
13
+ import { ThreadViewportProvider } from "./ThreadViewportProvider";
14
14
 
15
15
  type ThreadProviderProps = {
16
16
  listItemRuntime: ThreadListItemRuntime;
@@ -36,18 +36,17 @@ export const ThreadRuntimeProvider: FC<
36
36
  const useThreadRuntime = useThreadRuntimeStore(runtime);
37
37
 
38
38
  const [context] = useState<ThreadContextValue>(() => {
39
- const useViewport = makeThreadViewportStore();
40
-
41
39
  return {
42
40
  useThreadRuntime,
43
- useViewport,
44
41
  };
45
42
  });
46
43
 
47
44
  return (
48
45
  <ThreadListItemRuntimeProvider runtime={threadListItemRuntime}>
49
46
  <ThreadContext.Provider value={context}>
50
- {children}
47
+ {/* TODO temporarily allow accessing viewport state from outside the viewport */}
48
+ {/* TODO figure out if this behavior should be deprecated, since it is quite hacky */}
49
+ <ThreadViewportProvider>{children}</ThreadViewportProvider>
51
50
  </ThreadContext.Provider>
52
51
  </ThreadListItemRuntimeProvider>
53
52
  );
@@ -0,0 +1,49 @@
1
+ "use client";
2
+
3
+ import type { FC, PropsWithChildren } from "react";
4
+ import { useEffect, useState } from "react";
5
+ import { makeThreadViewportStore } from "../stores/ThreadViewport";
6
+ import {
7
+ ThreadViewportContext,
8
+ ThreadViewportContextValue,
9
+ useThreadViewportStore,
10
+ } from "../react/ThreadViewportContext";
11
+ import { writableStore } from "../ReadonlyStore";
12
+
13
+ const useThreadViewportStoreValue = () => {
14
+ const outerViewport = useThreadViewportStore({ optional: true });
15
+ const [store] = useState(() => makeThreadViewportStore());
16
+
17
+ useEffect(() => {
18
+ return outerViewport?.getState().onScrollToBottom(() => {
19
+ store.getState().scrollToBottom();
20
+ });
21
+ }, [outerViewport, store]);
22
+
23
+ useEffect(() => {
24
+ if (!outerViewport) return;
25
+ return store.subscribe((state) => {
26
+ if (outerViewport.getState().isAtBottom !== state.isAtBottom) {
27
+ writableStore(outerViewport).setState({ isAtBottom: state.isAtBottom });
28
+ }
29
+ });
30
+ }, [store, outerViewport]);
31
+
32
+ return store;
33
+ };
34
+
35
+ export const ThreadViewportProvider: FC<PropsWithChildren> = ({ children }) => {
36
+ const useThreadViewport = useThreadViewportStoreValue();
37
+
38
+ const [context] = useState<ThreadViewportContextValue>(() => {
39
+ return {
40
+ useThreadViewport,
41
+ };
42
+ });
43
+
44
+ return (
45
+ <ThreadViewportContext.Provider value={context}>
46
+ {children}
47
+ </ThreadViewportContext.Provider>
48
+ );
49
+ };
@@ -1,11 +1,9 @@
1
1
  "use client";
2
2
 
3
3
  import { createContext, useEffect, useState } from "react";
4
- import type { ThreadViewportState } from "../stores/ThreadViewport";
5
4
  import { ReadonlyStore } from "../ReadonlyStore";
6
5
  import { UseBoundStore } from "zustand";
7
6
  import { createContextHook } from "./utils/createContextHook";
8
- import { createContextStoreHook } from "./utils/createContextStoreHook";
9
7
  import { ThreadRuntime } from "../../api/ThreadRuntime";
10
8
  import { ModelContext } from "../../model-context";
11
9
  import { createStateHookForRuntime } from "./utils/createStateHookForRuntime";
@@ -13,7 +11,6 @@ import { ThreadComposerRuntime } from "../../api";
13
11
 
14
12
  export type ThreadContextValue = {
15
13
  useThreadRuntime: UseBoundStore<ReadonlyStore<ThreadRuntime>>;
16
- useViewport: UseBoundStore<ReadonlyStore<ThreadViewportState>>;
17
14
  };
18
15
 
19
16
  export const ThreadContext = createContext<ThreadContextValue | null>(null);
@@ -44,11 +41,6 @@ export const useThreadComposer = createStateHookForRuntime(
44
41
  useThreadComposerRuntime,
45
42
  );
46
43
 
47
- export const {
48
- useViewport: useThreadViewport,
49
- useViewportStore: useThreadViewportStore,
50
- } = createContextStoreHook(useThreadContext, "useViewport");
51
-
52
44
  export function useThreadModelContext(options?: {
53
45
  optional?: false | undefined;
54
46
  }): ModelContext;
@@ -0,0 +1,23 @@
1
+ "use client";
2
+
3
+ import { createContext } from "react";
4
+ import { ReadonlyStore } from "../ReadonlyStore";
5
+ import { UseBoundStore } from "zustand";
6
+ import { createContextHook } from "./utils/createContextHook";
7
+ import { createContextStoreHook } from "./utils/createContextStoreHook";
8
+ import { ThreadViewportState } from "../stores";
9
+
10
+ export type ThreadViewportContextValue = {
11
+ useThreadViewport: UseBoundStore<ReadonlyStore<ThreadViewportState>>;
12
+ };
13
+
14
+ export const ThreadViewportContext =
15
+ createContext<ThreadViewportContextValue | null>(null);
16
+
17
+ const useThreadViewportContext = createContextHook(
18
+ ThreadViewportContext,
19
+ "ThreadPrimitive.Viewport",
20
+ );
21
+
22
+ export const { useThreadViewport, useThreadViewportStore } =
23
+ createContextStoreHook(useThreadViewportContext, "useThreadViewport");
@@ -18,9 +18,12 @@ export {
18
18
  * @deprecated This method was renamed to `useThreadModelContext`.
19
19
  */
20
20
  useThreadModelContext as useThreadModelConfig,
21
+ } from "./ThreadContext";
22
+
23
+ export {
21
24
  useThreadViewport,
22
25
  useThreadViewportStore,
23
- } from "./ThreadContext";
26
+ } from "./ThreadViewportContext";
24
27
 
25
28
  export {
26
29
  useThreadListItemRuntime,
@@ -1,3 +1,5 @@
1
+ "use client";
2
+
1
3
  import { create } from "zustand";
2
4
  import type { Unsubscribe } from "../../types/Unsubscribe";
3
5
 
@@ -27,10 +27,16 @@ export type LanguageModelConfig = z.infer<typeof LanguageModelConfigSchema>;
27
27
  type ToolExecuteFunction<TArgs, TResult> = (
28
28
  args: TArgs,
29
29
  context: {
30
+ toolCallId: string;
30
31
  abortSignal: AbortSignal;
31
32
  },
32
33
  ) => TResult | Promise<TResult>;
33
34
 
35
+ type OnSchemaValidationErrorFunction<TResult> = ToolExecuteFunction<
36
+ unknown,
37
+ TResult
38
+ >;
39
+
34
40
  export type Tool<
35
41
  TArgs extends Record<string, unknown> = Record<string | number, unknown>,
36
42
  TResult = unknown,
@@ -38,6 +44,7 @@ export type Tool<
38
44
  description?: string | undefined;
39
45
  parameters: z.ZodSchema<TArgs> | JSONSchema7;
40
46
  execute?: ToolExecuteFunction<TArgs, TResult>;
47
+ experimental_onSchemaValidationError?: OnSchemaValidationErrorFunction<TResult>;
41
48
  };
42
49
 
43
50
  export type ModelContext = {
@@ -6,8 +6,7 @@ import {
6
6
  createActionButton,
7
7
  } from "../../utils/createActionButton";
8
8
  import { useCallback } from "react";
9
- import { useThreadViewport } from "../../context";
10
- import { useThreadViewportStore } from "../../context/react/ThreadContext";
9
+ import { useThreadViewport, useThreadViewportStore } from "../../context/react/ThreadViewportContext";
11
10
 
12
11
  const useThreadScrollToBottom = () => {
13
12
  const isAtBottom = useThreadViewport((s) => s.isAtBottom);
@@ -4,6 +4,7 @@ import { useComposedRefs } from "@radix-ui/react-compose-refs";
4
4
  import { Primitive } from "@radix-ui/react-primitive";
5
5
  import { type ComponentRef, forwardRef, ComponentPropsWithoutRef } from "react";
6
6
  import { useThreadViewportAutoScroll } from "./useThreadViewportAutoScroll";
7
+ import { ThreadViewportProvider } from "../../context/providers/ThreadViewportProvider";
7
8
 
8
9
  export namespace ThreadPrimitiveViewport {
9
10
  export type Element = ComponentRef<typeof Primitive.div>;
@@ -12,7 +13,7 @@ export namespace ThreadPrimitiveViewport {
12
13
  };
13
14
  }
14
15
 
15
- export const ThreadPrimitiveViewport = forwardRef<
16
+ const ThreadPrimitiveViewportScrollable = forwardRef<
16
17
  ThreadPrimitiveViewport.Element,
17
18
  ThreadPrimitiveViewport.Props
18
19
  >(({ autoScroll, children, ...rest }, forwardedRef) => {
@@ -29,4 +30,15 @@ export const ThreadPrimitiveViewport = forwardRef<
29
30
  );
30
31
  });
31
32
 
33
+ export const ThreadPrimitiveViewport = forwardRef<
34
+ ThreadPrimitiveViewport.Element,
35
+ ThreadPrimitiveViewport.Props
36
+ >((props, ref) => {
37
+ return (
38
+ <ThreadViewportProvider>
39
+ <ThreadPrimitiveViewportScrollable {...props} ref={ref} />
40
+ </ThreadViewportProvider>
41
+ );
42
+ });
43
+
32
44
  ThreadPrimitiveViewport.displayName = "ThreadPrimitive.Viewport";
@@ -2,14 +2,12 @@
2
2
 
3
3
  import { useComposedRefs } from "@radix-ui/react-compose-refs";
4
4
  import { RefCallback, useEffect, useRef } from "react";
5
- import {
6
- useThreadRuntime,
7
- useThreadViewportStore,
8
- } from "../../context/react/ThreadContext";
5
+ import { useThreadRuntime } from "../../context/react/ThreadContext";
9
6
  import { useOnResizeContent } from "../../utils/hooks/useOnResizeContent";
10
7
  import { useOnScrollToBottom } from "../../utils/hooks/useOnScrollToBottom";
11
8
  import { useManagedRef } from "../../utils/hooks/useManagedRef";
12
9
  import { writableStore } from "../../context/ReadonlyStore";
10
+ import { useThreadViewportStore } from "../../context/react/ThreadViewportContext";
13
11
 
14
12
  export namespace useThreadViewportAutoScroll {
15
13
  export type Options = {
@@ -18,7 +18,7 @@ export class DefaultEditComposerRuntimeCore extends BaseComposerRuntimeCore {
18
18
  private _parentId;
19
19
  private _sourceId;
20
20
  constructor(
21
- private runtime: Omit<ThreadRuntimeCore, "composer"> & {
21
+ private runtime: ThreadRuntimeCore & {
22
22
  adapters?: { attachments?: AttachmentAdapter | undefined } | undefined;
23
23
  },
24
24
  private endEditCallback: () => void,
@@ -36,6 +36,9 @@ export class DefaultEditComposerRuntimeCore extends BaseComposerRuntimeCore {
36
36
  this._nonTextParts = message.content.filter(
37
37
  (part) => part.type !== "text" && part.type !== "ui",
38
38
  );
39
+
40
+ // Use the runConfig from the regular (non-edit) composer as the initial runConfig for the edit composer
41
+ this.setRunConfig({ ...runtime.composer.runConfig });
39
42
  }
40
43
 
41
44
  public async handleSend(
@@ -75,30 +75,32 @@ export function toolResultStream(
75
75
  return;
76
76
  }
77
77
 
78
- if (tool.parameters instanceof z.ZodType) {
79
- const result = tool.parameters.safeParse(args);
80
- if (!result.success) {
81
- controller.enqueue({
82
- type: "tool-result",
83
- toolCallType,
84
- toolCallId,
85
- toolName,
86
- result:
87
- "Function parameter validation failed. " +
88
- JSON.stringify(result.error.issues),
89
- isError: true,
90
- });
91
- return;
92
- }
93
- }
94
-
95
78
  toolCallExecutions.set(
96
79
  toolCallId,
97
80
  (async () => {
98
81
  if (!tool.execute) return;
99
82
 
83
+ let executeFn = tool.execute;
84
+
85
+ if (tool.parameters instanceof z.ZodType) {
86
+ const result = tool.parameters.safeParse(args);
87
+ if (!result.success) {
88
+ executeFn =
89
+ tool.experimental_onSchemaValidationError ??
90
+ (() => {
91
+ throw (
92
+ "Function parameter validation failed. " +
93
+ JSON.stringify(result.error.issues)
94
+ );
95
+ });
96
+ }
97
+ }
98
+
100
99
  try {
101
- const result = await tool.execute(args, { abortSignal });
100
+ const result = await executeFn(args, {
101
+ toolCallId,
102
+ abortSignal,
103
+ });
102
104
 
103
105
  controller.enqueue({
104
106
  type: "tool-result",
@@ -2,7 +2,7 @@
2
2
 
3
3
  import { useCallbackRef } from "@radix-ui/react-use-callback-ref";
4
4
  import { useEffect } from "react";
5
- import { useThreadViewport } from "../../context/react/ThreadContext";
5
+ import { useThreadViewport } from "../../context/react/ThreadViewportContext";
6
6
 
7
7
  export const useOnScrollToBottom = (callback: () => void) => {
8
8
  const callbackRef = useCallbackRef(callback);