@assistant-ui/react 0.9.1 → 0.9.3

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 (86) hide show
  1. package/dist/model-context/ModelContextTypes.d.ts +1 -24
  2. package/dist/model-context/ModelContextTypes.d.ts.map +1 -1
  3. package/dist/model-context/ModelContextTypes.js.map +1 -1
  4. package/dist/model-context/ModelContextTypes.mjs.map +1 -1
  5. package/dist/model-context/index.d.ts +2 -1
  6. package/dist/model-context/index.d.ts.map +1 -1
  7. package/dist/model-context/index.js.map +1 -1
  8. package/dist/model-context/index.mjs.map +1 -1
  9. package/dist/model-context/tool.d.ts +1 -1
  10. package/dist/model-context/tool.d.ts.map +1 -1
  11. package/dist/model-context/tool.js.map +1 -1
  12. package/dist/model-context/tool.mjs.map +1 -1
  13. package/dist/model-context/useAssistantTool.d.ts +1 -1
  14. package/dist/model-context/useAssistantTool.d.ts.map +1 -1
  15. package/dist/model-context/useAssistantTool.js.map +1 -1
  16. package/dist/model-context/useAssistantTool.mjs.map +1 -1
  17. package/dist/primitives/contentPart/useContentPartText.d.ts +5 -3
  18. package/dist/primitives/contentPart/useContentPartText.d.ts.map +1 -1
  19. package/dist/primitives/contentPart/useContentPartText.js +2 -2
  20. package/dist/primitives/contentPart/useContentPartText.js.map +1 -1
  21. package/dist/primitives/contentPart/useContentPartText.mjs +2 -2
  22. package/dist/primitives/contentPart/useContentPartText.mjs.map +1 -1
  23. package/dist/runtimes/external-store/ThreadMessageLike.d.ts.map +1 -1
  24. package/dist/runtimes/external-store/ThreadMessageLike.js +2 -2
  25. package/dist/runtimes/external-store/ThreadMessageLike.js.map +1 -1
  26. package/dist/runtimes/external-store/ThreadMessageLike.mjs +3 -3
  27. package/dist/runtimes/external-store/ThreadMessageLike.mjs.map +1 -1
  28. package/dist/runtimes/external-store/index.d.ts +1 -1
  29. package/dist/runtimes/external-store/index.d.ts.map +1 -1
  30. package/dist/runtimes/external-store/index.js.map +1 -1
  31. package/dist/runtimes/external-store/index.mjs.map +1 -1
  32. package/dist/runtimes/index.d.ts +0 -1
  33. package/dist/runtimes/index.d.ts.map +1 -1
  34. package/dist/runtimes/index.js +1 -6
  35. package/dist/runtimes/index.js.map +1 -1
  36. package/dist/runtimes/index.mjs +1 -7
  37. package/dist/runtimes/index.mjs.map +1 -1
  38. package/dist/runtimes/local/LocalThreadRuntimeCore.d.ts.map +1 -1
  39. package/dist/runtimes/local/LocalThreadRuntimeCore.js +9 -3
  40. package/dist/runtimes/local/LocalThreadRuntimeCore.js.map +1 -1
  41. package/dist/runtimes/local/LocalThreadRuntimeCore.mjs +9 -3
  42. package/dist/runtimes/local/LocalThreadRuntimeCore.mjs.map +1 -1
  43. package/dist/tests/setup.js +8 -8
  44. package/dist/tests/setup.js.map +1 -1
  45. package/dist/tests/setup.mjs +8 -8
  46. package/dist/tests/setup.mjs.map +1 -1
  47. package/dist/types/ContentPartComponentTypes.d.ts +1 -1
  48. package/dist/types/ContentPartComponentTypes.d.ts.map +1 -1
  49. package/dist/types/ContentPartComponentTypes.js.map +1 -1
  50. package/dist/utils/smooth/useSmooth.d.ts +2 -2
  51. package/dist/utils/smooth/useSmooth.d.ts.map +1 -1
  52. package/dist/utils/smooth/useSmooth.js.map +1 -1
  53. package/dist/utils/smooth/useSmooth.mjs.map +1 -1
  54. package/dist/utils/useToolArgsFieldStatus.d.ts +12 -0
  55. package/dist/utils/useToolArgsFieldStatus.d.ts.map +1 -0
  56. package/dist/utils/useToolArgsFieldStatus.js +45 -0
  57. package/dist/utils/useToolArgsFieldStatus.js.map +1 -0
  58. package/dist/utils/useToolArgsFieldStatus.mjs +20 -0
  59. package/dist/utils/useToolArgsFieldStatus.mjs.map +1 -0
  60. package/package.json +7 -7
  61. package/src/model-context/ModelContextTypes.ts +1 -40
  62. package/src/model-context/index.ts +2 -1
  63. package/src/model-context/tool.ts +1 -1
  64. package/src/model-context/useAssistantTool.tsx +1 -1
  65. package/src/primitives/contentPart/useContentPartText.tsx +4 -4
  66. package/src/runtimes/external-store/ThreadMessageLike.tsx +6 -3
  67. package/src/runtimes/external-store/index.ts +2 -0
  68. package/src/runtimes/index.ts +0 -4
  69. package/src/runtimes/local/LocalThreadRuntimeCore.tsx +11 -5
  70. package/src/types/ContentPartComponentTypes.tsx +1 -1
  71. package/src/utils/smooth/useSmooth.tsx +7 -3
  72. package/src/utils/useToolArgsFieldStatus.tsx +18 -0
  73. package/dist/runtimes/streams/toolResultStream.d.ts +0 -5
  74. package/dist/runtimes/streams/toolResultStream.d.ts.map +0 -1
  75. package/dist/runtimes/streams/toolResultStream.js +0 -94
  76. package/dist/runtimes/streams/toolResultStream.js.map +0 -1
  77. package/dist/runtimes/streams/toolResultStream.mjs +0 -68
  78. package/dist/runtimes/streams/toolResultStream.mjs.map +0 -1
  79. package/dist/utils/json/fix-json.d.ts +0 -2
  80. package/dist/utils/json/fix-json.d.ts.map +0 -1
  81. package/dist/utils/json/fix-json.js +0 -350
  82. package/dist/utils/json/fix-json.js.map +0 -1
  83. package/dist/utils/json/fix-json.mjs +0 -325
  84. package/dist/utils/json/fix-json.mjs.map +0 -1
  85. package/src/runtimes/streams/toolResultStream.ts +0 -88
  86. package/src/utils/json/fix-json.ts +0 -421
@@ -18,7 +18,7 @@ export type FileContentPartComponent = ComponentType<FileContentPartProps>;
18
18
  export type Unstable_AudioContentPartProps = ContentPartState & Unstable_AudioContentPart;
19
19
  export type Unstable_AudioContentPartComponent = ComponentType<Unstable_AudioContentPartProps>;
20
20
  export type ToolCallContentPartProps<TArgs = any, TResult = unknown> = ContentPartState & ToolCallContentPart<TArgs, TResult> & {
21
- addResult: (result: any) => void;
21
+ addResult: (result: TResult) => void;
22
22
  };
23
23
  export type ToolCallContentPartComponent<TArgs = any, TResult = any> = ComponentType<ToolCallContentPartProps<TArgs, TResult>>;
24
24
  //# sourceMappingURL=ContentPartComponentTypes.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ContentPartComponentTypes.d.ts","sourceRoot":"","sources":["../../src/types/ContentPartComponentTypes.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAC3C,OAAO,KAAK,EACV,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EAChB,oBAAoB,EACpB,iBAAiB,EACjB,eAAe,EACf,mBAAmB,EACnB,yBAAyB,EAC1B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAE7D,MAAM,MAAM,qBAAqB,GAAG;IAClC,MAAM,EAAE,iBAAiB,CAAC;CAC3B,CAAC;AACF,MAAM,MAAM,yBAAyB,GAAG,aAAa,CAAC,qBAAqB,CAAC,CAAC;AAE7E,MAAM,MAAM,oBAAoB,GAAG,gBAAgB,GAAG,eAAe,CAAC;AACtE,MAAM,MAAM,wBAAwB,GAAG,aAAa,CAAC,oBAAoB,CAAC,CAAC;AAE3E,MAAM,MAAM,yBAAyB,GAAG,gBAAgB,GAAG,oBAAoB,CAAC;AAChF,MAAM,MAAM,6BAA6B,GACvC,aAAa,CAAC,yBAAyB,CAAC,CAAC;AAE3C,MAAM,MAAM,sBAAsB,GAAG,gBAAgB,GAAG,iBAAiB,CAAC;AAC1E,MAAM,MAAM,0BAA0B,GAAG,aAAa,CAAC,sBAAsB,CAAC,CAAC;AAE/E,MAAM,MAAM,qBAAqB,GAAG,gBAAgB,GAAG,gBAAgB,CAAC;AACxE,MAAM,MAAM,yBAAyB,GAAG,aAAa,CAAC,qBAAqB,CAAC,CAAC;AAE7E,MAAM,MAAM,oBAAoB,GAAG,gBAAgB,GAAG,eAAe,CAAC;AACtE,MAAM,MAAM,wBAAwB,GAAG,aAAa,CAAC,oBAAoB,CAAC,CAAC;AAE3E,MAAM,MAAM,8BAA8B,GAAG,gBAAgB,GAC3D,yBAAyB,CAAC;AAC5B,MAAM,MAAM,kCAAkC,GAC5C,aAAa,CAAC,8BAA8B,CAAC,CAAC;AAEhD,MAAM,MAAM,wBAAwB,CAClC,KAAK,GAAG,GAAG,EACX,OAAO,GAAG,OAAO,IACf,gBAAgB,GAClB,mBAAmB,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG;IACpC,SAAS,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,IAAI,CAAC;CAClC,CAAC;AAEJ,MAAM,MAAM,4BAA4B,CACtC,KAAK,GAAG,GAAG,EACX,OAAO,GAAG,GAAG,IACX,aAAa,CAAC,wBAAwB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"ContentPartComponentTypes.d.ts","sourceRoot":"","sources":["../../src/types/ContentPartComponentTypes.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAC3C,OAAO,KAAK,EACV,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EAChB,oBAAoB,EACpB,iBAAiB,EACjB,eAAe,EACf,mBAAmB,EACnB,yBAAyB,EAC1B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAE7D,MAAM,MAAM,qBAAqB,GAAG;IAClC,MAAM,EAAE,iBAAiB,CAAC;CAC3B,CAAC;AACF,MAAM,MAAM,yBAAyB,GAAG,aAAa,CAAC,qBAAqB,CAAC,CAAC;AAE7E,MAAM,MAAM,oBAAoB,GAAG,gBAAgB,GAAG,eAAe,CAAC;AACtE,MAAM,MAAM,wBAAwB,GAAG,aAAa,CAAC,oBAAoB,CAAC,CAAC;AAE3E,MAAM,MAAM,yBAAyB,GAAG,gBAAgB,GAAG,oBAAoB,CAAC;AAChF,MAAM,MAAM,6BAA6B,GACvC,aAAa,CAAC,yBAAyB,CAAC,CAAC;AAE3C,MAAM,MAAM,sBAAsB,GAAG,gBAAgB,GAAG,iBAAiB,CAAC;AAC1E,MAAM,MAAM,0BAA0B,GAAG,aAAa,CAAC,sBAAsB,CAAC,CAAC;AAE/E,MAAM,MAAM,qBAAqB,GAAG,gBAAgB,GAAG,gBAAgB,CAAC;AACxE,MAAM,MAAM,yBAAyB,GAAG,aAAa,CAAC,qBAAqB,CAAC,CAAC;AAE7E,MAAM,MAAM,oBAAoB,GAAG,gBAAgB,GAAG,eAAe,CAAC;AACtE,MAAM,MAAM,wBAAwB,GAAG,aAAa,CAAC,oBAAoB,CAAC,CAAC;AAE3E,MAAM,MAAM,8BAA8B,GAAG,gBAAgB,GAC3D,yBAAyB,CAAC;AAC5B,MAAM,MAAM,kCAAkC,GAC5C,aAAa,CAAC,8BAA8B,CAAC,CAAC;AAEhD,MAAM,MAAM,wBAAwB,CAClC,KAAK,GAAG,GAAG,EACX,OAAO,GAAG,OAAO,IACf,gBAAgB,GAClB,mBAAmB,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG;IACpC,SAAS,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;CACtC,CAAC;AAEJ,MAAM,MAAM,4BAA4B,CACtC,KAAK,GAAG,GAAG,EACX,OAAO,GAAG,GAAG,IACX,aAAa,CAAC,wBAAwB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/types/ContentPartComponentTypes.tsx"],"sourcesContent":["import type { ComponentType } from \"react\";\nimport type {\n ContentPartStatus,\n FileContentPart,\n ImageContentPart,\n ReasoningContentPart,\n SourceContentPart,\n TextContentPart,\n ToolCallContentPart,\n Unstable_AudioContentPart,\n} from \"./AssistantTypes\";\nimport { ContentPartState } from \"../api/ContentPartRuntime\";\n\nexport type EmptyContentPartProps = {\n status: ContentPartStatus;\n};\nexport type EmptyContentPartComponent = ComponentType<EmptyContentPartProps>;\n\nexport type TextContentPartProps = ContentPartState & TextContentPart;\nexport type TextContentPartComponent = ComponentType<TextContentPartProps>;\n\nexport type ReasoningContentPartProps = ContentPartState & ReasoningContentPart;\nexport type ReasoningContentPartComponent =\n ComponentType<ReasoningContentPartProps>;\n\nexport type SourceContentPartProps = ContentPartState & SourceContentPart;\nexport type SourceContentPartComponent = ComponentType<SourceContentPartProps>;\n\nexport type ImageContentPartProps = ContentPartState & ImageContentPart;\nexport type ImageContentPartComponent = ComponentType<ImageContentPartProps>;\n\nexport type FileContentPartProps = ContentPartState & FileContentPart;\nexport type FileContentPartComponent = ComponentType<FileContentPartProps>;\n\nexport type Unstable_AudioContentPartProps = ContentPartState &\n Unstable_AudioContentPart;\nexport type Unstable_AudioContentPartComponent =\n ComponentType<Unstable_AudioContentPartProps>;\n\nexport type ToolCallContentPartProps<\n TArgs = any,\n TResult = unknown,\n> = ContentPartState &\n ToolCallContentPart<TArgs, TResult> & {\n addResult: (result: any) => void;\n };\n\nexport type ToolCallContentPartComponent<\n TArgs = any,\n TResult = any,\n> = ComponentType<ToolCallContentPartProps<TArgs, TResult>>;\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
1
+ {"version":3,"sources":["../../src/types/ContentPartComponentTypes.tsx"],"sourcesContent":["import type { ComponentType } from \"react\";\nimport type {\n ContentPartStatus,\n FileContentPart,\n ImageContentPart,\n ReasoningContentPart,\n SourceContentPart,\n TextContentPart,\n ToolCallContentPart,\n Unstable_AudioContentPart,\n} from \"./AssistantTypes\";\nimport { ContentPartState } from \"../api/ContentPartRuntime\";\n\nexport type EmptyContentPartProps = {\n status: ContentPartStatus;\n};\nexport type EmptyContentPartComponent = ComponentType<EmptyContentPartProps>;\n\nexport type TextContentPartProps = ContentPartState & TextContentPart;\nexport type TextContentPartComponent = ComponentType<TextContentPartProps>;\n\nexport type ReasoningContentPartProps = ContentPartState & ReasoningContentPart;\nexport type ReasoningContentPartComponent =\n ComponentType<ReasoningContentPartProps>;\n\nexport type SourceContentPartProps = ContentPartState & SourceContentPart;\nexport type SourceContentPartComponent = ComponentType<SourceContentPartProps>;\n\nexport type ImageContentPartProps = ContentPartState & ImageContentPart;\nexport type ImageContentPartComponent = ComponentType<ImageContentPartProps>;\n\nexport type FileContentPartProps = ContentPartState & FileContentPart;\nexport type FileContentPartComponent = ComponentType<FileContentPartProps>;\n\nexport type Unstable_AudioContentPartProps = ContentPartState &\n Unstable_AudioContentPart;\nexport type Unstable_AudioContentPartComponent =\n ComponentType<Unstable_AudioContentPartProps>;\n\nexport type ToolCallContentPartProps<\n TArgs = any,\n TResult = unknown,\n> = ContentPartState &\n ToolCallContentPart<TArgs, TResult> & {\n addResult: (result: TResult) => void;\n };\n\nexport type ToolCallContentPartComponent<\n TArgs = any,\n TResult = any,\n> = ComponentType<ToolCallContentPartProps<TArgs, TResult>>;\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
@@ -1,4 +1,4 @@
1
- import { TextContentPart } from "../../types/AssistantTypes";
1
+ import { ReasoningContentPart, TextContentPart } from "../../types/AssistantTypes";
2
2
  import { ContentPartState } from "../../api/ContentPartRuntime";
3
- export declare const useSmooth: (state: ContentPartState & TextContentPart, smooth?: boolean) => ContentPartState & TextContentPart;
3
+ export declare const useSmooth: (state: ContentPartState & (TextContentPart | ReasoningContentPart), smooth?: boolean) => ContentPartState & (TextContentPart | ReasoningContentPart);
4
4
  //# sourceMappingURL=useSmooth.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useSmooth.d.ts","sourceRoot":"","sources":["../../../src/utils/smooth/useSmooth.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAqB,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAIhF,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AA4DhE,eAAO,MAAM,SAAS,GACpB,OAAO,gBAAgB,GAAG,eAAe,EACzC,SAAQ,OAAe,KACtB,gBAAgB,GAAG,eA2ErB,CAAC"}
1
+ {"version":3,"file":"useSmooth.d.ts","sourceRoot":"","sources":["../../../src/utils/smooth/useSmooth.tsx"],"names":[],"mappings":"AAIA,OAAO,EAEL,oBAAoB,EACpB,eAAe,EAChB,MAAM,4BAA4B,CAAC;AAIpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AA4DhE,eAAO,MAAM,SAAS,GACpB,OAAO,gBAAgB,GAAG,CAAC,eAAe,GAAG,oBAAoB,CAAC,EAClE,SAAQ,OAAe,KACtB,gBAAgB,GAAG,CAAC,eAAe,GAAG,oBAAoB,CA2E5D,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/smooth/useSmooth.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useMemo, useRef, useState } from \"react\";\nimport { useMessage } from \"../../context\";\nimport { ContentPartStatus, TextContentPart } from \"../../types/AssistantTypes\";\nimport { useCallbackRef } from \"@radix-ui/react-use-callback-ref\";\nimport { useSmoothStatusStore } from \"./SmoothContext\";\nimport { writableStore } from \"../../context/ReadonlyStore\";\nimport { ContentPartState } from \"../../api/ContentPartRuntime\";\n\nclass TextStreamAnimator {\n private animationFrameId: number | null = null;\n private lastUpdateTime: number = Date.now();\n\n public targetText: string = \"\";\n\n constructor(\n public currentText: string,\n private setText: (newText: string) => void,\n ) {}\n\n start() {\n if (this.animationFrameId !== null) return;\n this.lastUpdateTime = Date.now();\n this.animate();\n }\n\n stop() {\n if (this.animationFrameId !== null) {\n cancelAnimationFrame(this.animationFrameId);\n this.animationFrameId = null;\n }\n }\n\n private animate = () => {\n const currentTime = Date.now();\n const deltaTime = currentTime - this.lastUpdateTime;\n let timeToConsume = deltaTime;\n\n const remainingChars = this.targetText.length - this.currentText.length;\n const baseTimePerChar = Math.min(5, 250 / remainingChars);\n\n let charsToAdd = 0;\n while (timeToConsume >= baseTimePerChar && charsToAdd < remainingChars) {\n charsToAdd++;\n timeToConsume -= baseTimePerChar;\n }\n\n if (charsToAdd !== remainingChars) {\n this.animationFrameId = requestAnimationFrame(this.animate);\n } else {\n this.animationFrameId = null;\n }\n if (charsToAdd === 0) return;\n\n this.currentText = this.targetText.slice(\n 0,\n this.currentText.length + charsToAdd,\n );\n this.lastUpdateTime = currentTime - timeToConsume;\n this.setText(this.currentText);\n };\n}\n\nconst SMOOTH_STATUS: ContentPartStatus = Object.freeze({\n type: \"running\",\n});\n\nexport const useSmooth = (\n state: ContentPartState & TextContentPart,\n smooth: boolean = false,\n): ContentPartState & TextContentPart => {\n const { text } = state;\n const id = useMessage({\n optional: true,\n selector: (m: { id: string }) => m.id,\n });\n\n const idRef = useRef(id);\n const [displayedText, setDisplayedText] = useState(text);\n\n const smoothStatusStore = useSmoothStatusStore({ optional: true });\n const setText = useCallbackRef((text: string) => {\n setDisplayedText(text);\n if (smoothStatusStore) {\n const target =\n displayedText !== text || state.status.type === \"running\"\n ? SMOOTH_STATUS\n : state.status;\n writableStore(smoothStatusStore).setState(target, true);\n }\n });\n\n // TODO this is hacky\n useEffect(() => {\n if (smoothStatusStore) {\n const target =\n displayedText !== text || state.status.type === \"running\"\n ? SMOOTH_STATUS\n : state.status;\n writableStore(smoothStatusStore).setState(target, true);\n }\n }, [smoothStatusStore, text, displayedText, state.status]);\n\n const [animatorRef] = useState<TextStreamAnimator>(\n new TextStreamAnimator(text, setText),\n );\n\n useEffect(() => {\n if (!smooth) {\n animatorRef.stop();\n return;\n }\n\n if (idRef.current !== id || !text.startsWith(animatorRef.targetText)) {\n idRef.current = id;\n setText(text);\n\n animatorRef.currentText = text;\n animatorRef.targetText = text;\n animatorRef.stop();\n\n return;\n }\n\n animatorRef.targetText = text;\n animatorRef.start();\n }, [setText, animatorRef, id, smooth, text]);\n\n useEffect(() => {\n return () => {\n animatorRef.stop();\n };\n }, [animatorRef]);\n\n return useMemo(\n () =>\n smooth\n ? {\n type: \"text\",\n text: displayedText,\n status: text === displayedText ? state.status : SMOOTH_STATUS,\n }\n : state,\n [smooth, displayedText, state, text],\n );\n};\n"],"mappings":"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","names":["text"]}
1
+ {"version":3,"sources":["../../../src/utils/smooth/useSmooth.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useMemo, useRef, useState } from \"react\";\nimport { useMessage } from \"../../context\";\nimport {\n ContentPartStatus,\n ReasoningContentPart,\n TextContentPart,\n} from \"../../types/AssistantTypes\";\nimport { useCallbackRef } from \"@radix-ui/react-use-callback-ref\";\nimport { useSmoothStatusStore } from \"./SmoothContext\";\nimport { writableStore } from \"../../context/ReadonlyStore\";\nimport { ContentPartState } from \"../../api/ContentPartRuntime\";\n\nclass TextStreamAnimator {\n private animationFrameId: number | null = null;\n private lastUpdateTime: number = Date.now();\n\n public targetText: string = \"\";\n\n constructor(\n public currentText: string,\n private setText: (newText: string) => void,\n ) {}\n\n start() {\n if (this.animationFrameId !== null) return;\n this.lastUpdateTime = Date.now();\n this.animate();\n }\n\n stop() {\n if (this.animationFrameId !== null) {\n cancelAnimationFrame(this.animationFrameId);\n this.animationFrameId = null;\n }\n }\n\n private animate = () => {\n const currentTime = Date.now();\n const deltaTime = currentTime - this.lastUpdateTime;\n let timeToConsume = deltaTime;\n\n const remainingChars = this.targetText.length - this.currentText.length;\n const baseTimePerChar = Math.min(5, 250 / remainingChars);\n\n let charsToAdd = 0;\n while (timeToConsume >= baseTimePerChar && charsToAdd < remainingChars) {\n charsToAdd++;\n timeToConsume -= baseTimePerChar;\n }\n\n if (charsToAdd !== remainingChars) {\n this.animationFrameId = requestAnimationFrame(this.animate);\n } else {\n this.animationFrameId = null;\n }\n if (charsToAdd === 0) return;\n\n this.currentText = this.targetText.slice(\n 0,\n this.currentText.length + charsToAdd,\n );\n this.lastUpdateTime = currentTime - timeToConsume;\n this.setText(this.currentText);\n };\n}\n\nconst SMOOTH_STATUS: ContentPartStatus = Object.freeze({\n type: \"running\",\n});\n\nexport const useSmooth = (\n state: ContentPartState & (TextContentPart | ReasoningContentPart),\n smooth: boolean = false,\n): ContentPartState & (TextContentPart | ReasoningContentPart) => {\n const { text } = state;\n const id = useMessage({\n optional: true,\n selector: (m: { id: string }) => m.id,\n });\n\n const idRef = useRef(id);\n const [displayedText, setDisplayedText] = useState(text);\n\n const smoothStatusStore = useSmoothStatusStore({ optional: true });\n const setText = useCallbackRef((text: string) => {\n setDisplayedText(text);\n if (smoothStatusStore) {\n const target =\n displayedText !== text || state.status.type === \"running\"\n ? SMOOTH_STATUS\n : state.status;\n writableStore(smoothStatusStore).setState(target, true);\n }\n });\n\n // TODO this is hacky\n useEffect(() => {\n if (smoothStatusStore) {\n const target =\n displayedText !== text || state.status.type === \"running\"\n ? SMOOTH_STATUS\n : state.status;\n writableStore(smoothStatusStore).setState(target, true);\n }\n }, [smoothStatusStore, text, displayedText, state.status]);\n\n const [animatorRef] = useState<TextStreamAnimator>(\n new TextStreamAnimator(text, setText),\n );\n\n useEffect(() => {\n if (!smooth) {\n animatorRef.stop();\n return;\n }\n\n if (idRef.current !== id || !text.startsWith(animatorRef.targetText)) {\n idRef.current = id;\n setText(text);\n\n animatorRef.currentText = text;\n animatorRef.targetText = text;\n animatorRef.stop();\n\n return;\n }\n\n animatorRef.targetText = text;\n animatorRef.start();\n }, [setText, animatorRef, id, smooth, text]);\n\n useEffect(() => {\n return () => {\n animatorRef.stop();\n };\n }, [animatorRef]);\n\n return useMemo(\n () =>\n smooth\n ? {\n type: \"text\",\n text: displayedText,\n status: text === displayedText ? state.status : SMOOTH_STATUS,\n }\n : state,\n [smooth, displayedText, state, text],\n );\n};\n"],"mappings":"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","names":["text"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/smooth/useSmooth.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useMemo, useRef, useState } from \"react\";\nimport { useMessage } from \"../../context\";\nimport { ContentPartStatus, TextContentPart } from \"../../types/AssistantTypes\";\nimport { useCallbackRef } from \"@radix-ui/react-use-callback-ref\";\nimport { useSmoothStatusStore } from \"./SmoothContext\";\nimport { writableStore } from \"../../context/ReadonlyStore\";\nimport { ContentPartState } from \"../../api/ContentPartRuntime\";\n\nclass TextStreamAnimator {\n private animationFrameId: number | null = null;\n private lastUpdateTime: number = Date.now();\n\n public targetText: string = \"\";\n\n constructor(\n public currentText: string,\n private setText: (newText: string) => void,\n ) {}\n\n start() {\n if (this.animationFrameId !== null) return;\n this.lastUpdateTime = Date.now();\n this.animate();\n }\n\n stop() {\n if (this.animationFrameId !== null) {\n cancelAnimationFrame(this.animationFrameId);\n this.animationFrameId = null;\n }\n }\n\n private animate = () => {\n const currentTime = Date.now();\n const deltaTime = currentTime - this.lastUpdateTime;\n let timeToConsume = deltaTime;\n\n const remainingChars = this.targetText.length - this.currentText.length;\n const baseTimePerChar = Math.min(5, 250 / remainingChars);\n\n let charsToAdd = 0;\n while (timeToConsume >= baseTimePerChar && charsToAdd < remainingChars) {\n charsToAdd++;\n timeToConsume -= baseTimePerChar;\n }\n\n if (charsToAdd !== remainingChars) {\n this.animationFrameId = requestAnimationFrame(this.animate);\n } else {\n this.animationFrameId = null;\n }\n if (charsToAdd === 0) return;\n\n this.currentText = this.targetText.slice(\n 0,\n this.currentText.length + charsToAdd,\n );\n this.lastUpdateTime = currentTime - timeToConsume;\n this.setText(this.currentText);\n };\n}\n\nconst SMOOTH_STATUS: ContentPartStatus = Object.freeze({\n type: \"running\",\n});\n\nexport const useSmooth = (\n state: ContentPartState & TextContentPart,\n smooth: boolean = false,\n): ContentPartState & TextContentPart => {\n const { text } = state;\n const id = useMessage({\n optional: true,\n selector: (m: { id: string }) => m.id,\n });\n\n const idRef = useRef(id);\n const [displayedText, setDisplayedText] = useState(text);\n\n const smoothStatusStore = useSmoothStatusStore({ optional: true });\n const setText = useCallbackRef((text: string) => {\n setDisplayedText(text);\n if (smoothStatusStore) {\n const target =\n displayedText !== text || state.status.type === \"running\"\n ? SMOOTH_STATUS\n : state.status;\n writableStore(smoothStatusStore).setState(target, true);\n }\n });\n\n // TODO this is hacky\n useEffect(() => {\n if (smoothStatusStore) {\n const target =\n displayedText !== text || state.status.type === \"running\"\n ? SMOOTH_STATUS\n : state.status;\n writableStore(smoothStatusStore).setState(target, true);\n }\n }, [smoothStatusStore, text, displayedText, state.status]);\n\n const [animatorRef] = useState<TextStreamAnimator>(\n new TextStreamAnimator(text, setText),\n );\n\n useEffect(() => {\n if (!smooth) {\n animatorRef.stop();\n return;\n }\n\n if (idRef.current !== id || !text.startsWith(animatorRef.targetText)) {\n idRef.current = id;\n setText(text);\n\n animatorRef.currentText = text;\n animatorRef.targetText = text;\n animatorRef.stop();\n\n return;\n }\n\n animatorRef.targetText = text;\n animatorRef.start();\n }, [setText, animatorRef, id, smooth, text]);\n\n useEffect(() => {\n return () => {\n animatorRef.stop();\n };\n }, [animatorRef]);\n\n return useMemo(\n () =>\n smooth\n ? {\n type: \"text\",\n text: displayedText,\n status: text === displayedText ? state.status : SMOOTH_STATUS,\n }\n : state,\n [smooth, displayedText, state, text],\n );\n};\n"],"mappings":"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","names":["text"]}
1
+ {"version":3,"sources":["../../../src/utils/smooth/useSmooth.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useMemo, useRef, useState } from \"react\";\nimport { useMessage } from \"../../context\";\nimport {\n ContentPartStatus,\n ReasoningContentPart,\n TextContentPart,\n} from \"../../types/AssistantTypes\";\nimport { useCallbackRef } from \"@radix-ui/react-use-callback-ref\";\nimport { useSmoothStatusStore } from \"./SmoothContext\";\nimport { writableStore } from \"../../context/ReadonlyStore\";\nimport { ContentPartState } from \"../../api/ContentPartRuntime\";\n\nclass TextStreamAnimator {\n private animationFrameId: number | null = null;\n private lastUpdateTime: number = Date.now();\n\n public targetText: string = \"\";\n\n constructor(\n public currentText: string,\n private setText: (newText: string) => void,\n ) {}\n\n start() {\n if (this.animationFrameId !== null) return;\n this.lastUpdateTime = Date.now();\n this.animate();\n }\n\n stop() {\n if (this.animationFrameId !== null) {\n cancelAnimationFrame(this.animationFrameId);\n this.animationFrameId = null;\n }\n }\n\n private animate = () => {\n const currentTime = Date.now();\n const deltaTime = currentTime - this.lastUpdateTime;\n let timeToConsume = deltaTime;\n\n const remainingChars = this.targetText.length - this.currentText.length;\n const baseTimePerChar = Math.min(5, 250 / remainingChars);\n\n let charsToAdd = 0;\n while (timeToConsume >= baseTimePerChar && charsToAdd < remainingChars) {\n charsToAdd++;\n timeToConsume -= baseTimePerChar;\n }\n\n if (charsToAdd !== remainingChars) {\n this.animationFrameId = requestAnimationFrame(this.animate);\n } else {\n this.animationFrameId = null;\n }\n if (charsToAdd === 0) return;\n\n this.currentText = this.targetText.slice(\n 0,\n this.currentText.length + charsToAdd,\n );\n this.lastUpdateTime = currentTime - timeToConsume;\n this.setText(this.currentText);\n };\n}\n\nconst SMOOTH_STATUS: ContentPartStatus = Object.freeze({\n type: \"running\",\n});\n\nexport const useSmooth = (\n state: ContentPartState & (TextContentPart | ReasoningContentPart),\n smooth: boolean = false,\n): ContentPartState & (TextContentPart | ReasoningContentPart) => {\n const { text } = state;\n const id = useMessage({\n optional: true,\n selector: (m: { id: string }) => m.id,\n });\n\n const idRef = useRef(id);\n const [displayedText, setDisplayedText] = useState(text);\n\n const smoothStatusStore = useSmoothStatusStore({ optional: true });\n const setText = useCallbackRef((text: string) => {\n setDisplayedText(text);\n if (smoothStatusStore) {\n const target =\n displayedText !== text || state.status.type === \"running\"\n ? SMOOTH_STATUS\n : state.status;\n writableStore(smoothStatusStore).setState(target, true);\n }\n });\n\n // TODO this is hacky\n useEffect(() => {\n if (smoothStatusStore) {\n const target =\n displayedText !== text || state.status.type === \"running\"\n ? SMOOTH_STATUS\n : state.status;\n writableStore(smoothStatusStore).setState(target, true);\n }\n }, [smoothStatusStore, text, displayedText, state.status]);\n\n const [animatorRef] = useState<TextStreamAnimator>(\n new TextStreamAnimator(text, setText),\n );\n\n useEffect(() => {\n if (!smooth) {\n animatorRef.stop();\n return;\n }\n\n if (idRef.current !== id || !text.startsWith(animatorRef.targetText)) {\n idRef.current = id;\n setText(text);\n\n animatorRef.currentText = text;\n animatorRef.targetText = text;\n animatorRef.stop();\n\n return;\n }\n\n animatorRef.targetText = text;\n animatorRef.start();\n }, [setText, animatorRef, id, smooth, text]);\n\n useEffect(() => {\n return () => {\n animatorRef.stop();\n };\n }, [animatorRef]);\n\n return useMemo(\n () =>\n smooth\n ? {\n type: \"text\",\n text: displayedText,\n status: text === displayedText ? state.status : SMOOTH_STATUS,\n }\n : state,\n [smooth, displayedText, state, text],\n );\n};\n"],"mappings":"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","names":["text"]}
@@ -0,0 +1,12 @@
1
+ export declare const useToolArgsFieldStatus: (fieldPath: (string | number)[]) => {
2
+ readonly type: "running";
3
+ } | {
4
+ readonly type: "complete";
5
+ } | {
6
+ readonly type: "incomplete";
7
+ readonly reason: "cancelled" | "length" | "content-filter" | "other" | "error";
8
+ readonly error?: unknown;
9
+ } | {
10
+ type: string;
11
+ };
12
+ //# sourceMappingURL=useToolArgsFieldStatus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useToolArgsFieldStatus.d.ts","sourceRoot":"","sources":["../../src/utils/useToolArgsFieldStatus.tsx"],"names":[],"mappings":"AAKA,eAAO,MAAM,sBAAsB,GAAI,WAAW,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE;;;;;;;;;;CAYpE,CAAC"}
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/utils/useToolArgsFieldStatus.tsx
21
+ var useToolArgsFieldStatus_exports = {};
22
+ __export(useToolArgsFieldStatus_exports, {
23
+ useToolArgsFieldStatus: () => useToolArgsFieldStatus
24
+ });
25
+ module.exports = __toCommonJS(useToolArgsFieldStatus_exports);
26
+ var import_utils = require("assistant-stream/utils");
27
+ var import_context = require("../context/index.js");
28
+ var COMPLETE_STATUS = { type: "complete" };
29
+ var useToolArgsFieldStatus = (fieldPath) => {
30
+ return (0, import_context.useContentPart)((t) => {
31
+ if (t.type !== "tool-call")
32
+ throw new Error(
33
+ "useToolArgsFieldStatus can only be used inside tool-call content parts"
34
+ );
35
+ const state = (0, import_utils.getPartialJsonObjectFieldState)(t.args, fieldPath);
36
+ if (state === "complete" || t.status.type === "requires-action")
37
+ return COMPLETE_STATUS;
38
+ return t.status;
39
+ });
40
+ };
41
+ // Annotate the CommonJS export names for ESM import in node:
42
+ 0 && (module.exports = {
43
+ useToolArgsFieldStatus
44
+ });
45
+ //# sourceMappingURL=useToolArgsFieldStatus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/useToolArgsFieldStatus.tsx"],"sourcesContent":["import { getPartialJsonObjectFieldState } from \"assistant-stream/utils\";\nimport { useContentPart } from \"../context\";\n\nconst COMPLETE_STATUS = { type: \"complete\" };\n\nexport const useToolArgsFieldStatus = (fieldPath: (string | number)[]) => {\n return useContentPart((t) => {\n if (t.type !== \"tool-call\")\n throw new Error(\n \"useToolArgsFieldStatus can only be used inside tool-call content parts\",\n );\n\n const state = getPartialJsonObjectFieldState(t.args, fieldPath);\n if (state === \"complete\" || t.status.type === \"requires-action\")\n return COMPLETE_STATUS;\n return t.status;\n });\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA+C;AAC/C,qBAA+B;AAE/B,IAAM,kBAAkB,EAAE,MAAM,WAAW;AAEpC,IAAM,yBAAyB,CAAC,cAAmC;AACxE,aAAO,+BAAe,CAAC,MAAM;AAC3B,QAAI,EAAE,SAAS;AACb,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAEF,UAAM,YAAQ,6CAA+B,EAAE,MAAM,SAAS;AAC9D,QAAI,UAAU,cAAc,EAAE,OAAO,SAAS;AAC5C,aAAO;AACT,WAAO,EAAE;AAAA,EACX,CAAC;AACH;","names":[]}
@@ -0,0 +1,20 @@
1
+ // src/utils/useToolArgsFieldStatus.tsx
2
+ import { getPartialJsonObjectFieldState } from "assistant-stream/utils";
3
+ import { useContentPart } from "../context/index.mjs";
4
+ var COMPLETE_STATUS = { type: "complete" };
5
+ var useToolArgsFieldStatus = (fieldPath) => {
6
+ return useContentPart((t) => {
7
+ if (t.type !== "tool-call")
8
+ throw new Error(
9
+ "useToolArgsFieldStatus can only be used inside tool-call content parts"
10
+ );
11
+ const state = getPartialJsonObjectFieldState(t.args, fieldPath);
12
+ if (state === "complete" || t.status.type === "requires-action")
13
+ return COMPLETE_STATUS;
14
+ return t.status;
15
+ });
16
+ };
17
+ export {
18
+ useToolArgsFieldStatus
19
+ };
20
+ //# sourceMappingURL=useToolArgsFieldStatus.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/useToolArgsFieldStatus.tsx"],"sourcesContent":["import { getPartialJsonObjectFieldState } from \"assistant-stream/utils\";\nimport { useContentPart } from \"../context\";\n\nconst COMPLETE_STATUS = { type: \"complete\" };\n\nexport const useToolArgsFieldStatus = (fieldPath: (string | number)[]) => {\n return useContentPart((t) => {\n if (t.type !== \"tool-call\")\n throw new Error(\n \"useToolArgsFieldStatus can only be used inside tool-call content parts\",\n );\n\n const state = getPartialJsonObjectFieldState(t.args, fieldPath);\n if (state === \"complete\" || t.status.type === \"requires-action\")\n return COMPLETE_STATUS;\n return t.status;\n });\n};\n"],"mappings":";AAAA,SAAS,sCAAsC;AAC/C,SAAS,sBAAsB;AAE/B,IAAM,kBAAkB,EAAE,MAAM,WAAW;AAEpC,IAAM,yBAAyB,CAAC,cAAmC;AACxE,SAAO,eAAe,CAAC,MAAM;AAC3B,QAAI,EAAE,SAAS;AACb,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAEF,UAAM,QAAQ,+BAA+B,EAAE,MAAM,SAAS;AAC9D,QAAI,UAAU,cAAc,EAAE,OAAO,SAAS;AAC5C,aAAO;AACT,WAAO,EAAE;AAAA,EACX,CAAC;AACH;","names":[]}
package/package.json CHANGED
@@ -28,7 +28,7 @@
28
28
  "conversational-ui",
29
29
  "conversational-ai"
30
30
  ],
31
- "version": "0.9.1",
31
+ "version": "0.9.3",
32
32
  "license": "MIT",
33
33
  "exports": {
34
34
  ".": {
@@ -62,10 +62,10 @@
62
62
  "@radix-ui/react-slot": "^1.2.0",
63
63
  "@radix-ui/react-use-callback-ref": "^1.1.1",
64
64
  "@radix-ui/react-use-escape-keydown": "^1.1.1",
65
- "assistant-stream": "^0.1.1",
65
+ "assistant-stream": "^0.1.3",
66
66
  "nanoid": "5.1.5",
67
67
  "react-textarea-autosize": "^8.5.9",
68
- "zod": "^3.24.2",
68
+ "zod": "^3.24.3",
69
69
  "zustand": "^5.0.3"
70
70
  },
71
71
  "peerDependencies": {
@@ -86,12 +86,12 @@
86
86
  "@stryker-mutator/core": "^8.7.1",
87
87
  "@stryker-mutator/vitest-runner": "^8.7.1",
88
88
  "@types/json-schema": "^7.0.15",
89
- "@types/node": "^22.14.0",
89
+ "@types/node": "^22.14.1",
90
90
  "eslint": "^9",
91
- "eslint-config-next": "15.3.0",
91
+ "eslint-config-next": "15.3.1",
92
92
  "tsx": "^4.19.3",
93
93
  "vitest": "^3.1.1",
94
- "@assistant-ui/tsbuildutils": "^0.0.1",
94
+ "@assistant-ui/tsbuildutils": "0.0.1",
95
95
  "@assistant-ui/tsconfig": "0.0.0"
96
96
  },
97
97
  "publishConfig": {
@@ -107,7 +107,7 @@
107
107
  "url": "https://github.com/assistant-ui/assistant-ui/issues"
108
108
  },
109
109
  "engines": {
110
- "node": ">=20.10.0"
110
+ "node": ">=20.0.0"
111
111
  },
112
112
  "scripts": {
113
113
  "build": "tsx scripts/build.mts",
@@ -1,6 +1,6 @@
1
1
  import { z } from "zod";
2
- import type { JSONSchema7 } from "json-schema";
3
2
  import { Unsubscribe } from "../types/Unsubscribe";
3
+ import { Tool } from "assistant-stream";
4
4
 
5
5
  export const LanguageModelV1CallSettingsSchema = z.object({
6
6
  maxTokens: z.number().int().positive().optional(),
@@ -24,45 +24,6 @@ export const LanguageModelConfigSchema = z.object({
24
24
 
25
25
  export type LanguageModelConfig = z.infer<typeof LanguageModelConfigSchema>;
26
26
 
27
- export type ToolExecuteFunction<TArgs, TResult> = (
28
- args: TArgs,
29
- context: {
30
- toolCallId: string;
31
- abortSignal: AbortSignal;
32
- },
33
- ) => TResult | Promise<TResult>;
34
-
35
- export type ToolStreamCallFunction<TArgs, TResult> = (
36
- iterator: AsyncGenerator<
37
- {
38
- args: TArgs;
39
- argsTextDelta: string;
40
- },
41
- void,
42
- unknown
43
- >,
44
- context: {
45
- toolCallId: string;
46
- abortSignal: AbortSignal;
47
- },
48
- ) => TResult | Promise<TResult>;
49
-
50
- type OnSchemaValidationErrorFunction<TResult> = ToolExecuteFunction<
51
- unknown,
52
- TResult
53
- >;
54
-
55
- export type Tool<TArgs = unknown, TResult = unknown> = {
56
- description?: string | undefined;
57
- parameters: z.ZodSchema<TArgs> | JSONSchema7;
58
- execute?: ToolExecuteFunction<TArgs, TResult>;
59
- /**
60
- * @deprecated TODO not yet implemented
61
- */
62
- experimental_streamCall?: ToolStreamCallFunction<TArgs, TResult>;
63
- experimental_onSchemaValidationError?: OnSchemaValidationErrorFunction<TResult>;
64
- };
65
-
66
27
  export type ModelContext = {
67
28
  priority?: number | undefined;
68
29
  system?: string | undefined;
@@ -22,9 +22,10 @@ export type {
22
22
  ModelContextProvider as AssistantConfigProvider,
23
23
  ModelContext,
24
24
  ModelContextProvider,
25
- Tool,
26
25
  } from "./ModelContextTypes";
27
26
 
27
+ export type { Tool } from "assistant-stream";
28
+
28
29
  export { tool } from "./tool";
29
30
 
30
31
  /**
@@ -1,5 +1,5 @@
1
1
  import { Schema, z } from "zod";
2
- import { Tool } from "./ModelContextTypes";
2
+ import { Tool } from "assistant-stream";
3
3
 
4
4
  export type inferParameters<PARAMETERS extends Tool<any, any>["parameters"]> =
5
5
  PARAMETERS extends Schema<any>
@@ -6,7 +6,7 @@ import {
6
6
  useToolUIsStore,
7
7
  } from "../context/react/AssistantContext";
8
8
  import type { ToolCallContentPartComponent } from "../types/ContentPartComponentTypes";
9
- import type { Tool } from "./ModelContextTypes";
9
+ import type { Tool } from "assistant-stream";
10
10
 
11
11
  export type AssistantToolProps<TArgs, TResult> = Tool<TArgs, TResult> & {
12
12
  toolName: string;
@@ -2,16 +2,16 @@
2
2
 
3
3
  import { ContentPartState } from "../../api/ContentPartRuntime";
4
4
  import { useContentPart } from "../../context/react/ContentPartContext";
5
- import { TextContentPart } from "../../types";
5
+ import { TextContentPart, ReasoningContentPart } from "../../types";
6
6
 
7
7
  export const useContentPartText = () => {
8
8
  const text = useContentPart((c) => {
9
- if (c.type !== "text")
9
+ if (c.type !== "text" && c.type !== "reasoning")
10
10
  throw new Error(
11
- "ContentPartText can only be used inside text content parts.",
11
+ "ContentPartText can only be used inside text or reasoning content parts.",
12
12
  );
13
13
 
14
- return c as ContentPartState & TextContentPart;
14
+ return c as ContentPartState & (TextContentPart | ReasoningContentPart);
15
15
  });
16
16
 
17
17
  return text;
@@ -1,4 +1,4 @@
1
- import { parsePartialJson } from "assistant-stream/utils";
1
+ import { parsePartialJsonObject } from "assistant-stream/utils";
2
2
  import { generateId } from "../../internal";
3
3
  import {
4
4
  MessageStatus,
@@ -78,7 +78,7 @@ export const fromThreadMessageLike = (
78
78
  ? [{ type: "text" as const, text: like.content }]
79
79
  : like.content;
80
80
 
81
- if (role !== "user" && attachments)
81
+ if (role !== "user" && attachments?.length)
82
82
  throw new Error("attachments are only supported for user messages");
83
83
 
84
84
  if (role !== "assistant" && status)
@@ -117,7 +117,10 @@ export const fromThreadMessageLike = (
117
117
  return {
118
118
  ...part,
119
119
  toolCallId: part.toolCallId ?? "tool-" + generateId(),
120
- args: part.args ?? parsePartialJson(part.argsText ?? "{}"),
120
+ args:
121
+ part.args ??
122
+ parsePartialJsonObject(part.argsText ?? "") ??
123
+ {},
121
124
  argsText: part.argsText ?? "",
122
125
  };
123
126
  }
@@ -1,6 +1,8 @@
1
1
  export type {
2
2
  ExternalStoreAdapter,
3
3
  ExternalStoreMessageConverter,
4
+ ExternalStoreThreadListAdapter,
5
+ ExternalStoreThreadData,
4
6
  } from "./ExternalStoreAdapter";
5
7
  export type { ThreadMessageLike } from "./ThreadMessageLike";
6
8
  export { useExternalStoreRuntime } from "./useExternalStoreRuntime";
@@ -4,8 +4,4 @@ export * from "./external-store";
4
4
  export * from "./local";
5
5
  export * from "./remote-thread-list";
6
6
 
7
- export {
8
- toolResultStream as unstable_toolResultStream,
9
- unstable_runPendingTools,
10
- } from "./streams/toolResultStream";
11
7
  export { ExportedMessageRepository } from "./utils/MessageRepository";
@@ -297,10 +297,11 @@ export class LocalThreadRuntimeCore
297
297
  runCallback ??
298
298
  this.adapters.chatModel.run.bind(this.adapters.chatModel);
299
299
 
300
+ const abortSignal = this.abortController.signal;
300
301
  const promiseOrGenerator = runCallback({
301
302
  messages,
302
303
  runConfig: this._lastRunConfig,
303
- abortSignal: this.abortController.signal,
304
+ abortSignal,
304
305
  context,
305
306
  config: context,
306
307
  unstable_assistantMessageId: message.id,
@@ -312,22 +313,25 @@ export class LocalThreadRuntimeCore
312
313
  // handle async iterator for streaming results
313
314
  if (Symbol.asyncIterator in promiseOrGenerator) {
314
315
  for await (const r of promiseOrGenerator) {
316
+ if (abortSignal.aborted) {
317
+ updateMessage({
318
+ status: { type: "incomplete", reason: "cancelled" },
319
+ });
320
+ break;
321
+ }
322
+
315
323
  updateMessage(r);
316
324
  }
317
325
  } else {
318
326
  updateMessage(await promiseOrGenerator);
319
327
  }
320
328
 
321
- this.abortController = null;
322
-
323
329
  if (message.status.type === "running") {
324
330
  updateMessage({
325
331
  status: { type: "complete", reason: "unknown" },
326
332
  });
327
333
  }
328
334
  } catch (e) {
329
- this.abortController = null;
330
-
331
335
  // TODO this should be handled by the run result stream
332
336
  if (e instanceof Error && e.name === "AbortError") {
333
337
  updateMessage({
@@ -348,6 +352,8 @@ export class LocalThreadRuntimeCore
348
352
  throw e;
349
353
  }
350
354
  } finally {
355
+ this.abortController = null;
356
+
351
357
  if (
352
358
  message.status.type === "complete" ||
353
359
  message.status.type === "incomplete"
@@ -42,7 +42,7 @@ export type ToolCallContentPartProps<
42
42
  TResult = unknown,
43
43
  > = ContentPartState &
44
44
  ToolCallContentPart<TArgs, TResult> & {
45
- addResult: (result: any) => void;
45
+ addResult: (result: TResult) => void;
46
46
  };
47
47
 
48
48
  export type ToolCallContentPartComponent<
@@ -2,7 +2,11 @@
2
2
 
3
3
  import { useEffect, useMemo, useRef, useState } from "react";
4
4
  import { useMessage } from "../../context";
5
- import { ContentPartStatus, TextContentPart } from "../../types/AssistantTypes";
5
+ import {
6
+ ContentPartStatus,
7
+ ReasoningContentPart,
8
+ TextContentPart,
9
+ } from "../../types/AssistantTypes";
6
10
  import { useCallbackRef } from "@radix-ui/react-use-callback-ref";
7
11
  import { useSmoothStatusStore } from "./SmoothContext";
8
12
  import { writableStore } from "../../context/ReadonlyStore";
@@ -67,9 +71,9 @@ const SMOOTH_STATUS: ContentPartStatus = Object.freeze({
67
71
  });
68
72
 
69
73
  export const useSmooth = (
70
- state: ContentPartState & TextContentPart,
74
+ state: ContentPartState & (TextContentPart | ReasoningContentPart),
71
75
  smooth: boolean = false,
72
- ): ContentPartState & TextContentPart => {
76
+ ): ContentPartState & (TextContentPart | ReasoningContentPart) => {
73
77
  const { text } = state;
74
78
  const id = useMessage({
75
79
  optional: true,
@@ -0,0 +1,18 @@
1
+ import { getPartialJsonObjectFieldState } from "assistant-stream/utils";
2
+ import { useContentPart } from "../context";
3
+
4
+ const COMPLETE_STATUS = { type: "complete" };
5
+
6
+ export const useToolArgsFieldStatus = (fieldPath: (string | number)[]) => {
7
+ return useContentPart((t) => {
8
+ if (t.type !== "tool-call")
9
+ throw new Error(
10
+ "useToolArgsFieldStatus can only be used inside tool-call content parts",
11
+ );
12
+
13
+ const state = getPartialJsonObjectFieldState(t.args, fieldPath);
14
+ if (state === "complete" || t.status.type === "requires-action")
15
+ return COMPLETE_STATUS;
16
+ return t.status;
17
+ });
18
+ };
@@ -1,5 +0,0 @@
1
- import { Tool } from "../../model-context/ModelContextTypes";
2
- import { AssistantMessage, ToolExecutionStream } from "assistant-stream";
3
- export declare function unstable_runPendingTools(message: AssistantMessage, tools: Record<string, Tool<any, any>> | undefined, abortSignal: AbortSignal): Promise<AssistantMessage>;
4
- export declare function toolResultStream(tools: Record<string, Tool<any, any>> | undefined, abortSignal: AbortSignal): ToolExecutionStream;
5
- //# sourceMappingURL=toolResultStream.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"toolResultStream.d.ts","sourceRoot":"","sources":["../../../src/runtimes/streams/toolResultStream.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,uCAAuC,CAAC;AAE7D,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AA4CzE,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,gBAAgB,EACzB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,GAAG,SAAS,EACjD,WAAW,EAAE,WAAW,6BA6BzB;AAED,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,GAAG,SAAS,EACjD,WAAW,EAAE,WAAW,uBAKzB"}
@@ -1,94 +0,0 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // src/runtimes/streams/toolResultStream.ts
21
- var toolResultStream_exports = {};
22
- __export(toolResultStream_exports, {
23
- toolResultStream: () => toolResultStream,
24
- unstable_runPendingTools: () => unstable_runPendingTools
25
- });
26
- module.exports = __toCommonJS(toolResultStream_exports);
27
- var import_zod = require("zod");
28
- var import_assistant_stream = require("assistant-stream");
29
- var import_assistant_stream2 = require("assistant-stream");
30
- function getToolResponse(tools, abortSignal, toolCall) {
31
- const tool = tools?.[toolCall.toolName];
32
- if (!tool || !tool.execute) return void 0;
33
- let executeFn = tool.execute;
34
- if (tool.parameters instanceof import_zod.z.ZodType) {
35
- const result = tool.parameters.safeParse(toolCall.args);
36
- if (!result.success) {
37
- executeFn = tool.experimental_onSchemaValidationError ?? (() => {
38
- throw new Error(
39
- `Function parameter validation failed. ${JSON.stringify(result.error.issues)}`
40
- );
41
- });
42
- }
43
- }
44
- const getResult = async () => {
45
- const result = await executeFn(toolCall.args, {
46
- toolCallId: toolCall.toolCallId,
47
- abortSignal
48
- });
49
- if (result instanceof import_assistant_stream2.ToolResponse) return result;
50
- return new import_assistant_stream2.ToolResponse({
51
- result: result === void 0 ? "<no result>" : result
52
- });
53
- };
54
- return getResult();
55
- }
56
- async function unstable_runPendingTools(message, tools, abortSignal) {
57
- for (const part of message.parts) {
58
- if (part.type === "tool-call") {
59
- const promiseOrUndefined = getToolResponse(tools, abortSignal, part);
60
- if (promiseOrUndefined) {
61
- const result = await promiseOrUndefined;
62
- const updatedParts = message.parts.map((p) => {
63
- if (p.type === "tool-call" && p.toolCallId === part.toolCallId) {
64
- return {
65
- ...p,
66
- state: "result",
67
- artifact: result.artifact,
68
- result: result.result,
69
- isError: result.isError
70
- };
71
- }
72
- return p;
73
- });
74
- message = {
75
- ...message,
76
- parts: updatedParts,
77
- content: updatedParts
78
- };
79
- }
80
- }
81
- }
82
- return message;
83
- }
84
- function toolResultStream(tools, abortSignal) {
85
- return new import_assistant_stream.ToolExecutionStream(
86
- (toolCall) => getToolResponse(tools, abortSignal, toolCall)
87
- );
88
- }
89
- // Annotate the CommonJS export names for ESM import in node:
90
- 0 && (module.exports = {
91
- toolResultStream,
92
- unstable_runPendingTools
93
- });
94
- //# sourceMappingURL=toolResultStream.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../src/runtimes/streams/toolResultStream.ts"],"sourcesContent":["import { Tool } from \"../../model-context/ModelContextTypes\";\nimport { z } from \"zod\";\nimport { AssistantMessage, ToolExecutionStream } from \"assistant-stream\";\nimport { ToolResponse } from \"assistant-stream\";\n\nfunction getToolResponse(\n tools: Record<string, Tool<any, any>> | undefined,\n abortSignal: AbortSignal,\n toolCall: {\n toolCallId: string;\n toolName: string;\n args: unknown;\n },\n) {\n const tool = tools?.[toolCall.toolName];\n if (!tool || !tool.execute) return undefined;\n\n let executeFn = tool.execute;\n\n if (tool.parameters instanceof z.ZodType) {\n const result = tool.parameters.safeParse(toolCall.args);\n if (!result.success) {\n executeFn =\n tool.experimental_onSchemaValidationError ??\n (() => {\n throw new Error(\n `Function parameter validation failed. ${JSON.stringify(result.error.issues)}`,\n );\n });\n }\n }\n\n const getResult = async () => {\n const result = await executeFn(toolCall.args, {\n toolCallId: toolCall.toolCallId,\n abortSignal,\n });\n if (result instanceof ToolResponse) return result;\n return new ToolResponse({\n result: result === undefined ? \"<no result>\" : result,\n });\n };\n\n return getResult();\n}\n\nexport async function unstable_runPendingTools(\n message: AssistantMessage,\n tools: Record<string, Tool<any, any>> | undefined,\n abortSignal: AbortSignal,\n) {\n // TODO parallel tool calling\n for (const part of message.parts) {\n if (part.type === \"tool-call\") {\n const promiseOrUndefined = getToolResponse(tools, abortSignal, part);\n if (promiseOrUndefined) {\n const result = await promiseOrUndefined;\n const updatedParts = message.parts.map((p) => {\n if (p.type === \"tool-call\" && p.toolCallId === part.toolCallId) {\n return {\n ...p,\n state: \"result\" as const,\n artifact: result.artifact,\n result: result.result,\n isError: result.isError,\n };\n }\n return p;\n });\n message = {\n ...message,\n parts: updatedParts,\n content: updatedParts,\n };\n }\n }\n }\n return message;\n}\n\nexport function toolResultStream(\n tools: Record<string, Tool<any, any>> | undefined,\n abortSignal: AbortSignal,\n) {\n return new ToolExecutionStream((toolCall) =>\n getToolResponse(tools, abortSignal, toolCall),\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,iBAAkB;AAClB,8BAAsD;AACtD,IAAAA,2BAA6B;AAE7B,SAAS,gBACP,OACA,aACA,UAKA;AACA,QAAM,OAAO,QAAQ,SAAS,QAAQ;AACtC,MAAI,CAAC,QAAQ,CAAC,KAAK,QAAS,QAAO;AAEnC,MAAI,YAAY,KAAK;AAErB,MAAI,KAAK,sBAAsB,aAAE,SAAS;AACxC,UAAM,SAAS,KAAK,WAAW,UAAU,SAAS,IAAI;AACtD,QAAI,CAAC,OAAO,SAAS;AACnB,kBACE,KAAK,yCACJ,MAAM;AACL,cAAM,IAAI;AAAA,UACR,yCAAyC,KAAK,UAAU,OAAO,MAAM,MAAM,CAAC;AAAA,QAC9E;AAAA,MACF;AAAA,IACJ;AAAA,EACF;AAEA,QAAM,YAAY,YAAY;AAC5B,UAAM,SAAS,MAAM,UAAU,SAAS,MAAM;AAAA,MAC5C,YAAY,SAAS;AAAA,MACrB;AAAA,IACF,CAAC;AACD,QAAI,kBAAkB,sCAAc,QAAO;AAC3C,WAAO,IAAI,sCAAa;AAAA,MACtB,QAAQ,WAAW,SAAY,gBAAgB;AAAA,IACjD,CAAC;AAAA,EACH;AAEA,SAAO,UAAU;AACnB;AAEA,eAAsB,yBACpB,SACA,OACA,aACA;AAEA,aAAW,QAAQ,QAAQ,OAAO;AAChC,QAAI,KAAK,SAAS,aAAa;AAC7B,YAAM,qBAAqB,gBAAgB,OAAO,aAAa,IAAI;AACnE,UAAI,oBAAoB;AACtB,cAAM,SAAS,MAAM;AACrB,cAAM,eAAe,QAAQ,MAAM,IAAI,CAAC,MAAM;AAC5C,cAAI,EAAE,SAAS,eAAe,EAAE,eAAe,KAAK,YAAY;AAC9D,mBAAO;AAAA,cACL,GAAG;AAAA,cACH,OAAO;AAAA,cACP,UAAU,OAAO;AAAA,cACjB,QAAQ,OAAO;AAAA,cACf,SAAS,OAAO;AAAA,YAClB;AAAA,UACF;AACA,iBAAO;AAAA,QACT,CAAC;AACD,kBAAU;AAAA,UACR,GAAG;AAAA,UACH,OAAO;AAAA,UACP,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,iBACd,OACA,aACA;AACA,SAAO,IAAI;AAAA,IAAoB,CAAC,aAC9B,gBAAgB,OAAO,aAAa,QAAQ;AAAA,EAC9C;AACF;","names":["import_assistant_stream"]}