@assistant-ui/react 0.9.0 → 0.9.2
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.
- package/dist/model-context/ModelContextTypes.d.ts +11 -9
- package/dist/model-context/ModelContextTypes.d.ts.map +1 -1
- package/dist/model-context/ModelContextTypes.js.map +1 -1
- package/dist/model-context/ModelContextTypes.mjs.map +1 -1
- package/dist/model-context/type-path-utils.d.ts +19 -0
- package/dist/model-context/type-path-utils.d.ts.map +1 -0
- package/dist/model-context/type-path-utils.js +19 -0
- package/dist/model-context/type-path-utils.js.map +1 -0
- package/dist/model-context/type-path-utils.mjs +1 -0
- package/dist/model-context/type-path-utils.mjs.map +1 -0
- package/dist/primitives/assistantModal/AssistantModalRoot.d.ts.map +1 -1
- package/dist/primitives/assistantModal/AssistantModalRoot.js +5 -2
- package/dist/primitives/assistantModal/AssistantModalRoot.js.map +1 -1
- package/dist/primitives/assistantModal/AssistantModalRoot.mjs +5 -2
- package/dist/primitives/assistantModal/AssistantModalRoot.mjs.map +1 -1
- package/dist/primitives/contentPart/useContentPartText.d.ts +5 -3
- package/dist/primitives/contentPart/useContentPartText.d.ts.map +1 -1
- package/dist/primitives/contentPart/useContentPartText.js +2 -2
- package/dist/primitives/contentPart/useContentPartText.js.map +1 -1
- package/dist/primitives/contentPart/useContentPartText.mjs +2 -2
- package/dist/primitives/contentPart/useContentPartText.mjs.map +1 -1
- package/dist/runtimes/external-store/ThreadMessageLike.d.ts.map +1 -1
- package/dist/runtimes/external-store/ThreadMessageLike.js +2 -2
- package/dist/runtimes/external-store/ThreadMessageLike.js.map +1 -1
- package/dist/runtimes/external-store/ThreadMessageLike.mjs +3 -3
- package/dist/runtimes/external-store/ThreadMessageLike.mjs.map +1 -1
- package/dist/runtimes/external-store/index.d.ts +1 -1
- package/dist/runtimes/external-store/index.d.ts.map +1 -1
- package/dist/runtimes/external-store/index.js.map +1 -1
- package/dist/runtimes/external-store/index.mjs.map +1 -1
- package/dist/runtimes/local/LocalThreadRuntimeCore.d.ts.map +1 -1
- package/dist/runtimes/local/LocalThreadRuntimeCore.js +9 -3
- package/dist/runtimes/local/LocalThreadRuntimeCore.js.map +1 -1
- package/dist/runtimes/local/LocalThreadRuntimeCore.mjs +9 -3
- package/dist/runtimes/local/LocalThreadRuntimeCore.mjs.map +1 -1
- package/dist/tests/setup.js +8 -8
- package/dist/tests/setup.js.map +1 -1
- package/dist/tests/setup.mjs +8 -8
- package/dist/tests/setup.mjs.map +1 -1
- package/dist/types/ContentPartComponentTypes.d.ts +1 -1
- package/dist/types/ContentPartComponentTypes.d.ts.map +1 -1
- package/dist/types/ContentPartComponentTypes.js.map +1 -1
- package/dist/utils/smooth/useSmooth.d.ts +2 -2
- package/dist/utils/smooth/useSmooth.d.ts.map +1 -1
- package/dist/utils/smooth/useSmooth.js.map +1 -1
- package/dist/utils/smooth/useSmooth.mjs.map +1 -1
- package/dist/utils/useToolArgsFieldStatus.d.ts +12 -0
- package/dist/utils/useToolArgsFieldStatus.d.ts.map +1 -0
- package/dist/utils/useToolArgsFieldStatus.js +45 -0
- package/dist/utils/useToolArgsFieldStatus.js.map +1 -0
- package/dist/utils/useToolArgsFieldStatus.mjs +20 -0
- package/dist/utils/useToolArgsFieldStatus.mjs.map +1 -0
- package/package.json +14 -14
- package/src/model-context/ModelContextTypes.ts +28 -16
- package/src/model-context/type-path-utils.ts +32 -0
- package/src/primitives/assistantModal/AssistantModalRoot.tsx +6 -2
- package/src/primitives/contentPart/useContentPartText.tsx +4 -4
- package/src/runtimes/external-store/ThreadMessageLike.tsx +6 -3
- package/src/runtimes/external-store/index.ts +2 -0
- package/src/runtimes/local/LocalThreadRuntimeCore.tsx +11 -5
- package/src/types/ContentPartComponentTypes.tsx +1 -1
- package/src/utils/smooth/useSmooth.tsx +7 -3
- package/src/utils/useToolArgsFieldStatus.tsx +18 -0
- package/dist/utils/json/fix-json.d.ts +0 -2
- package/dist/utils/json/fix-json.d.ts.map +0 -1
- package/dist/utils/json/fix-json.js +0 -350
- package/dist/utils/json/fix-json.js.map +0 -1
- package/dist/utils/json/fix-json.mjs +0 -325
- package/dist/utils/json/fix-json.mjs.map +0 -1
- 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:
|
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,
|
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:
|
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,
|
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 {
|
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 {
|
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.
|
31
|
+
"version": "0.9.2",
|
32
32
|
"license": "MIT",
|
33
33
|
"exports": {
|
34
34
|
".": {
|
@@ -54,15 +54,15 @@
|
|
54
54
|
],
|
55
55
|
"sideEffects": false,
|
56
56
|
"dependencies": {
|
57
|
-
"@radix-ui/primitive": "^1.1.
|
58
|
-
"@radix-ui/react-compose-refs": "^1.1.
|
59
|
-
"@radix-ui/react-context": "^1.1.
|
60
|
-
"@radix-ui/react-popover": "^1.1.
|
61
|
-
"@radix-ui/react-primitive": "^2.0.
|
62
|
-
"@radix-ui/react-slot": "^1.
|
63
|
-
"@radix-ui/react-use-callback-ref": "^1.1.
|
64
|
-
"@radix-ui/react-use-escape-keydown": "^1.1.
|
65
|
-
"assistant-stream": "^0.1.
|
57
|
+
"@radix-ui/primitive": "^1.1.2",
|
58
|
+
"@radix-ui/react-compose-refs": "^1.1.2",
|
59
|
+
"@radix-ui/react-context": "^1.1.2",
|
60
|
+
"@radix-ui/react-popover": "^1.1.7",
|
61
|
+
"@radix-ui/react-primitive": "^2.0.3",
|
62
|
+
"@radix-ui/react-slot": "^1.2.0",
|
63
|
+
"@radix-ui/react-use-callback-ref": "^1.1.1",
|
64
|
+
"@radix-ui/react-use-escape-keydown": "^1.1.1",
|
65
|
+
"assistant-stream": "^0.1.2",
|
66
66
|
"nanoid": "5.1.5",
|
67
67
|
"react-textarea-autosize": "^8.5.9",
|
68
68
|
"zod": "^3.24.2",
|
@@ -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.
|
89
|
+
"@types/node": "^22.14.1",
|
90
90
|
"eslint": "^9",
|
91
|
-
"eslint-config-next": "15.
|
91
|
+
"eslint-config-next": "15.3.0",
|
92
92
|
"tsx": "^4.19.3",
|
93
93
|
"vitest": "^3.1.1",
|
94
|
-
"@assistant-ui/tsbuildutils": "
|
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.
|
110
|
+
"node": ">=20.0.0"
|
111
111
|
},
|
112
112
|
"scripts": {
|
113
113
|
"build": "tsx scripts/build.mts",
|
@@ -1,6 +1,7 @@
|
|
1
1
|
import { z } from "zod";
|
2
2
|
import type { JSONSchema7 } from "json-schema";
|
3
3
|
import { Unsubscribe } from "../types/Unsubscribe";
|
4
|
+
import { TypePath, TypeAtPath, DeepPartial } from "./type-path-utils";
|
4
5
|
|
5
6
|
export const LanguageModelV1CallSettingsSchema = z.object({
|
6
7
|
maxTokens: z.number().int().positive().optional(),
|
@@ -24,27 +25,38 @@ export const LanguageModelConfigSchema = z.object({
|
|
24
25
|
|
25
26
|
export type LanguageModelConfig = z.infer<typeof LanguageModelConfigSchema>;
|
26
27
|
|
28
|
+
type ToolExecutionContext = {
|
29
|
+
toolCallId: string;
|
30
|
+
abortSignal: AbortSignal;
|
31
|
+
};
|
32
|
+
|
33
|
+
type ReadableStreamIterator<T> = ReadableStream<T> &
|
34
|
+
AsyncGenerator<T, void, unknown>;
|
35
|
+
|
36
|
+
interface ToolCallReader<TArgs> {
|
37
|
+
get<PathT extends TypePath<TArgs>>(
|
38
|
+
...fieldPath: PathT
|
39
|
+
): Promise<TypeAtPath<TArgs, PathT>>;
|
40
|
+
|
41
|
+
stream<PathT extends TypePath<TArgs>>(
|
42
|
+
...fieldPath: PathT
|
43
|
+
): ReadableStreamIterator<DeepPartial<TypeAtPath<TArgs, PathT>>>;
|
44
|
+
|
45
|
+
forEach<PathT extends TypePath<TArgs>>(
|
46
|
+
...fieldPath: PathT
|
47
|
+
): TypeAtPath<TArgs, PathT> extends Array<infer U>
|
48
|
+
? ReadableStreamIterator<U>
|
49
|
+
: never;
|
50
|
+
}
|
51
|
+
|
27
52
|
export type ToolExecuteFunction<TArgs, TResult> = (
|
28
53
|
args: TArgs,
|
29
|
-
context:
|
30
|
-
toolCallId: string;
|
31
|
-
abortSignal: AbortSignal;
|
32
|
-
},
|
54
|
+
context: ToolExecutionContext,
|
33
55
|
) => TResult | Promise<TResult>;
|
34
56
|
|
35
57
|
export type ToolStreamCallFunction<TArgs, TResult> = (
|
36
|
-
|
37
|
-
|
38
|
-
args: TArgs;
|
39
|
-
argsTextDelta: string;
|
40
|
-
},
|
41
|
-
void,
|
42
|
-
unknown
|
43
|
-
>,
|
44
|
-
context: {
|
45
|
-
toolCallId: string;
|
46
|
-
abortSignal: AbortSignal;
|
47
|
-
},
|
58
|
+
controller: ToolCallReader<TArgs>,
|
59
|
+
context: ToolExecutionContext,
|
48
60
|
) => TResult | Promise<TResult>;
|
49
61
|
|
50
62
|
type OnSchemaValidationErrorFunction<TResult> = ToolExecuteFunction<
|
@@ -0,0 +1,32 @@
|
|
1
|
+
type AsNumber<K> = K extends `${infer N extends number}` ? N | K : K;
|
2
|
+
type TupleIndex<T extends readonly any[]> = Exclude<keyof T, keyof any[]>;
|
3
|
+
type IsTuple<T extends readonly any[]> = number extends T["length"]
|
4
|
+
? false
|
5
|
+
: true;
|
6
|
+
|
7
|
+
export type TypePath<T> =
|
8
|
+
| []
|
9
|
+
| (T extends object
|
10
|
+
? T extends readonly any[]
|
11
|
+
? IsTuple<T> extends true
|
12
|
+
? {
|
13
|
+
[K in TupleIndex<T>]: [AsNumber<K>, ...TypePath<T[K]>];
|
14
|
+
}[TupleIndex<T>]
|
15
|
+
: [number, ...TypePath<T[number]>]
|
16
|
+
: { [K in keyof T]: [K, ...TypePath<T[K]>] }[keyof T]
|
17
|
+
: []);
|
18
|
+
|
19
|
+
export type TypeAtPath<T, P extends readonly any[]> = P extends [
|
20
|
+
infer Head,
|
21
|
+
...infer Rest,
|
22
|
+
]
|
23
|
+
? Head extends keyof T
|
24
|
+
? TypeAtPath<T[Head], Rest>
|
25
|
+
: never
|
26
|
+
: T;
|
27
|
+
|
28
|
+
export type DeepPartial<T> = T extends readonly any[]
|
29
|
+
? readonly DeepPartial<T[number]>[]
|
30
|
+
: T extends { [key: string]: any }
|
31
|
+
? { readonly [K in keyof T]?: DeepPartial<T[K]> }
|
32
|
+
: T;
|
@@ -2,7 +2,6 @@
|
|
2
2
|
|
3
3
|
import { FC, useEffect, useState } from "react";
|
4
4
|
import * as PopoverPrimitive from "@radix-ui/react-popover";
|
5
|
-
import { composeEventHandlers } from "@radix-ui/primitive";
|
6
5
|
import { ScopedProps, usePopoverScope } from "./scope";
|
7
6
|
import { useThreadRuntime } from "../../context";
|
8
7
|
|
@@ -56,11 +55,16 @@ export const AssistantModalPrimitiveRoot: FC<
|
|
56
55
|
unstable_openOnRunStart,
|
57
56
|
});
|
58
57
|
|
58
|
+
const openChangeHandler = (open: boolean) => {
|
59
|
+
onOpenChange?.(open);
|
60
|
+
setOpen(open);
|
61
|
+
};
|
62
|
+
|
59
63
|
return (
|
60
64
|
<PopoverPrimitive.Root
|
61
65
|
{...scope}
|
62
66
|
open={open === undefined ? modalOpen : open}
|
63
|
-
onOpenChange={
|
67
|
+
onOpenChange={openChangeHandler}
|
64
68
|
{...rest}
|
65
69
|
/>
|
66
70
|
);
|
@@ -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 {
|
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:
|
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";
|
@@ -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
|
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:
|
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 {
|
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 +0,0 @@
|
|
1
|
-
{"version":3,"file":"fix-json.d.ts","sourceRoot":"","sources":["../../../src/utils/json/fix-json.ts"],"names":[],"mappings":"AA0CA,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CA0XvD"}
|