@assistant-ui/react 0.11.46 → 0.11.48
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/augmentations.d.ts.map +1 -1
- package/dist/client/ThreadMessageClient.js +2 -2
- package/dist/client/ThreadMessageClient.js.map +1 -1
- package/dist/client/types/ModelContext.d.ts.map +1 -1
- package/dist/client/types/Thread.d.ts +4 -0
- package/dist/client/types/Thread.d.ts.map +1 -1
- package/dist/context/react/AssistantApiContext.d.ts.map +1 -1
- package/dist/context/react/AssistantApiContext.js.map +1 -1
- package/dist/context/react/index.d.ts +1 -1
- package/dist/context/react/index.d.ts.map +1 -1
- package/dist/context/react/index.js.map +1 -1
- package/dist/context/react/utils/createStateHookForRuntime.d.ts.map +1 -1
- package/dist/context/react/utils/createStateHookForRuntime.js.map +1 -1
- package/dist/context/react/utils/ensureBinding.js.map +1 -1
- package/dist/context/stores/ThreadViewport.js +1 -1
- package/dist/context/stores/ThreadViewport.js.map +1 -1
- package/dist/legacy-runtime/AssistantRuntimeProvider.d.ts +3 -3
- package/dist/legacy-runtime/AssistantRuntimeProvider.d.ts.map +1 -1
- package/dist/legacy-runtime/AssistantRuntimeProvider.js +3 -6
- package/dist/legacy-runtime/AssistantRuntimeProvider.js.map +1 -1
- package/dist/legacy-runtime/client/MessagePartRuntimeClient.js +1 -1
- package/dist/legacy-runtime/client/MessagePartRuntimeClient.js.map +1 -1
- package/dist/legacy-runtime/client/MessageRuntimeClient.js +1 -1
- package/dist/legacy-runtime/client/MessageRuntimeClient.js.map +1 -1
- package/dist/legacy-runtime/client/ThreadRuntimeClient.d.ts.map +1 -1
- package/dist/legacy-runtime/client/ThreadRuntimeClient.js +1 -0
- package/dist/legacy-runtime/client/ThreadRuntimeClient.js.map +1 -1
- package/dist/legacy-runtime/cloud/auiV0.js +1 -1
- package/dist/legacy-runtime/cloud/auiV0.js.map +1 -1
- package/dist/legacy-runtime/runtime/AssistantRuntime.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime/AssistantRuntime.js.map +1 -1
- package/dist/legacy-runtime/runtime/ComposerRuntime.js +2 -2
- package/dist/legacy-runtime/runtime/ComposerRuntime.js.map +1 -1
- package/dist/legacy-runtime/runtime/MessageRuntime.js +3 -3
- package/dist/legacy-runtime/runtime/MessageRuntime.js.map +1 -1
- package/dist/legacy-runtime/runtime/ThreadListRuntime.js +1 -1
- package/dist/legacy-runtime/runtime/ThreadListRuntime.js.map +1 -1
- package/dist/legacy-runtime/runtime/ThreadRuntime.js +2 -2
- package/dist/legacy-runtime/runtime/ThreadRuntime.js.map +1 -1
- package/dist/legacy-runtime/runtime/subscribable/SKIP_UPDATE.js +1 -1
- package/dist/legacy-runtime/runtime/subscribable/SKIP_UPDATE.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/adapters/RuntimeAdapterProvider.d.ts +1 -2
- package/dist/legacy-runtime/runtime-cores/adapters/RuntimeAdapterProvider.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/adapters/RuntimeAdapterProvider.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/adapters/attachment/CompositeAttachmentAdapter.js +2 -2
- package/dist/legacy-runtime/runtime-cores/adapters/attachment/CompositeAttachmentAdapter.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/adapters/feedback/index.d.ts +1 -1
- package/dist/legacy-runtime/runtime-cores/adapters/feedback/index.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/adapters/suggestion/index.d.ts +1 -1
- package/dist/legacy-runtime/runtime-cores/adapters/suggestion/index.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.js +1 -1
- package/dist/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreAdapter.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/external-store/ThreadMessageLike.js +1 -1
- package/dist/legacy-runtime/runtime-cores/external-store/ThreadMessageLike.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/external-store/auto-status.js +1 -1
- package/dist/legacy-runtime/runtime-cores/external-store/auto-status.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/external-store/getExternalStoreMessage.js +2 -2
- package/dist/legacy-runtime/runtime-cores/external-store/getExternalStoreMessage.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListHookInstanceManager.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListHookInstanceManager.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListThreadListRuntimeCore.js.map +1 -1
- package/dist/model-context/registry/ModelContextRegistry.js +3 -3
- package/dist/model-context/registry/ModelContextRegistry.js.map +1 -1
- package/dist/primitives/actionBar/ActionBarCopy.d.ts.map +1 -1
- package/dist/primitives/actionBar/ActionBarCopy.js.map +1 -1
- package/dist/primitives/actionBar/ActionBarExportMarkdown.d.ts +17 -0
- package/dist/primitives/actionBar/ActionBarExportMarkdown.d.ts.map +1 -0
- package/dist/primitives/actionBar/ActionBarExportMarkdown.js +54 -0
- package/dist/primitives/actionBar/ActionBarExportMarkdown.js.map +1 -0
- package/dist/primitives/actionBar/index.d.ts +1 -0
- package/dist/primitives/actionBar/index.d.ts.map +1 -1
- package/dist/primitives/actionBar/index.js +2 -0
- package/dist/primitives/actionBar/index.js.map +1 -1
- package/dist/primitives/assistant/AssistantIf.d.ts +12 -0
- package/dist/primitives/assistant/AssistantIf.d.ts.map +1 -0
- package/dist/primitives/assistant/AssistantIf.js +16 -0
- package/dist/primitives/assistant/AssistantIf.js.map +1 -0
- package/dist/primitives/composer/ComposerIf.d.ts +3 -0
- package/dist/primitives/composer/ComposerIf.d.ts.map +1 -1
- package/dist/primitives/composer/ComposerIf.js.map +1 -1
- package/dist/primitives/composer/ComposerInput.d.ts.map +1 -1
- package/dist/primitives/composer/ComposerInput.js +1 -0
- package/dist/primitives/composer/ComposerInput.js.map +1 -1
- package/dist/primitives/index.d.ts +1 -0
- package/dist/primitives/index.d.ts.map +1 -1
- package/dist/primitives/index.js +2 -0
- package/dist/primitives/index.js.map +1 -1
- package/dist/primitives/message/MessageError.js +1 -2
- package/dist/primitives/message/MessageError.js.map +1 -1
- package/dist/primitives/message/MessageIf.d.ts +3 -0
- package/dist/primitives/message/MessageIf.d.ts.map +1 -1
- package/dist/primitives/message/MessageIf.js.map +1 -1
- package/dist/primitives/message/MessageParts.d.ts.map +1 -1
- package/dist/primitives/message/MessageParts.js +2 -2
- package/dist/primitives/message/MessageParts.js.map +1 -1
- package/dist/primitives/message/MessagePartsGrouped.d.ts.map +1 -1
- package/dist/primitives/message/MessagePartsGrouped.js.map +1 -1
- package/dist/primitives/messagePart/useMessagePartData.d.ts.map +1 -1
- package/dist/primitives/messagePart/useMessagePartData.js.map +1 -1
- package/dist/primitives/thread/ThreadIf.d.ts +3 -0
- package/dist/primitives/thread/ThreadIf.d.ts.map +1 -1
- package/dist/primitives/thread/ThreadIf.js +2 -3
- package/dist/primitives/thread/ThreadIf.js.map +1 -1
- package/dist/tests/setup.js +44 -42
- package/dist/tests/setup.js.map +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/smooth/useSmooth.js +2 -2
- package/dist/utils/smooth/useSmooth.js.map +1 -1
- package/package.json +8 -11
- package/src/augmentations.ts +0 -2
- package/src/client/ThreadMessageClient.tsx +2 -2
- package/src/client/types/ModelContext.ts +0 -1
- package/src/client/types/Thread.ts +5 -0
- package/src/context/react/AssistantApiContext.tsx +0 -2
- package/src/context/react/index.ts +1 -0
- package/src/context/react/utils/createStateHookForRuntime.ts +0 -1
- package/src/context/react/utils/ensureBinding.ts +1 -1
- package/src/legacy-runtime/AssistantRuntimeProvider.tsx +5 -6
- package/src/legacy-runtime/client/MessagePartRuntimeClient.ts +1 -1
- package/src/legacy-runtime/client/MessageRuntimeClient.ts +1 -1
- package/src/legacy-runtime/client/ThreadRuntimeClient.ts +1 -0
- package/src/legacy-runtime/cloud/auiV0.ts +1 -1
- package/src/legacy-runtime/runtime/AssistantRuntime.ts +3 -1
- package/src/legacy-runtime/runtime/ComposerRuntime.ts +2 -2
- package/src/legacy-runtime/runtime/MessageRuntime.ts +3 -3
- package/src/legacy-runtime/runtime/ThreadListRuntime.ts +1 -1
- package/src/legacy-runtime/runtime/ThreadRuntime.ts +2 -2
- package/src/legacy-runtime/runtime-cores/adapters/RuntimeAdapterProvider.tsx +1 -1
- package/src/legacy-runtime/runtime-cores/adapters/attachment/CompositeAttachmentAdapter.ts +2 -2
- package/src/legacy-runtime/runtime-cores/adapters/feedback/index.ts +1 -1
- package/src/legacy-runtime/runtime-cores/adapters/suggestion/index.ts +1 -1
- package/src/legacy-runtime/runtime-cores/external-store/ExternalStoreAdapter.tsx +1 -1
- package/src/legacy-runtime/runtime-cores/external-store/ThreadMessageLike.tsx +1 -1
- package/src/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListHookInstanceManager.tsx +0 -2
- package/src/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListThreadListRuntimeCore.tsx +0 -2
- package/src/primitives/actionBar/ActionBarCopy.tsx +3 -1
- package/src/primitives/actionBar/ActionBarExportMarkdown.tsx +70 -0
- package/src/primitives/actionBar/index.ts +1 -0
- package/src/primitives/assistant/AssistantIf.tsx +25 -0
- package/src/primitives/composer/ComposerIf.tsx +3 -0
- package/src/primitives/composer/ComposerInput.tsx +3 -0
- package/src/primitives/index.ts +2 -0
- package/src/primitives/message/MessageError.tsx +1 -1
- package/src/primitives/message/MessageIf.tsx +3 -0
- package/src/primitives/message/MessageParts.tsx +2 -3
- package/src/primitives/message/MessagePartsGrouped.tsx +0 -1
- package/src/primitives/messagePart/useMessagePartData.tsx +1 -1
- package/src/primitives/thread/ThreadIf.tsx +5 -3
- package/src/types/index.ts +0 -1
- package/src/utils/smooth/useSmooth.tsx +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,UAAU,EACV,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAE3B,YAAY,EACV,aAAa,EACb,eAAe,EACf,oBAAoB,EACpB,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,yBAAyB,EACzB,mBAAmB,EACnB,aAAa,EACb,iBAAiB,EACjB,yBAAyB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,UAAU,EACV,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAE3B,YAAY,EACV,aAAa,EACb,eAAe,EACf,oBAAoB,EACpB,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,yBAAyB,EACzB,mBAAmB,EACnB,aAAa,EACb,iBAAiB,EACjB,yBAAyB,EAEzB,qBAAqB,EACrB,0BAA0B,EAC1B,mBAAmB,EACnB,sBAAsB,EACtB,iBAAiB,EACjB,aAAa,GACd,MAAM,kBAAkB,CAAC;AAE1B,YAAY,EACV,yBAAyB,EACzB,qBAAqB,EACrB,wBAAwB,EACxB,oBAAoB,EACpB,6BAA6B,EAC7B,yBAAyB,EACzB,0BAA0B,EAC1B,sBAAsB,EACtB,yBAAyB,EACzB,qBAAqB,EACrB,wBAAwB,EACxB,oBAAoB,EACpB,kCAAkC,EAClC,8BAA8B,EAC9B,4BAA4B,EAC5B,wBAAwB,EACxB,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,6BAA6B,CAAC;AAGrC,YAAY,EAAE,oBAAoB,EAAE,MAAM,iDAAiD,CAAC;AAE5F,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,YAAY,EACV,mBAAmB,EACnB,sBAAsB,EACtB,cAAc,EACd,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,cAAc,CAAC"}
|
|
@@ -68,10 +68,10 @@ var useSmooth = (state, smooth = false) => {
|
|
|
68
68
|
});
|
|
69
69
|
useEffect(() => {
|
|
70
70
|
if (smoothStatusStore) {
|
|
71
|
-
const target = displayedText !== text || state.status.type === "running" ? SMOOTH_STATUS : state.status;
|
|
71
|
+
const target = smooth && (displayedText !== text || state.status.type === "running") ? SMOOTH_STATUS : state.status;
|
|
72
72
|
writableStore(smoothStatusStore).setState(target, true);
|
|
73
73
|
}
|
|
74
|
-
}, [smoothStatusStore, text, displayedText, state.status]);
|
|
74
|
+
}, [smoothStatusStore, smooth, text, displayedText, state.status]);
|
|
75
75
|
const [animatorRef] = useState(
|
|
76
76
|
new TextStreamAnimator(text, setText)
|
|
77
77
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/utils/smooth/useSmooth.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useMemo, useRef, useState } from \"react\";\nimport { useAssistantState } from \"../../context\";\nimport {\n MessagePartStatus,\n ReasoningMessagePart,\n TextMessagePart,\n} from \"../../types/AssistantTypes\";\nimport { useCallbackRef } from \"@radix-ui/react-use-callback-ref\";\nimport { useSmoothStatusStore } from \"./SmoothContext\";\nimport { writableStore } from \"../../context/ReadonlyStore\";\nimport { MessagePartState } from \"../../legacy-runtime/runtime/MessagePartRuntime\";\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: MessagePartStatus = Object.freeze({\n type: \"running\",\n});\n\nexport const useSmooth = (\n state: MessagePartState & (TextMessagePart | ReasoningMessagePart),\n smooth: boolean = false,\n): MessagePartState & (TextMessagePart | ReasoningMessagePart) => {\n const { text } = state;\n const id = useAssistantState(({ message }) => message.id);\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":";;;AAEA,SAAS,WAAW,SAAS,QAAQ,gBAAgB;AACrD,SAAS,yBAAyB;AAMlC,SAAS,sBAAsB;AAC/B,SAAS,4BAA4B;AACrC,SAAS,qBAAqB;AAG9B,IAAM,qBAAN,MAAyB;AAAA,EAMvB,YACS,aACC,SACR;AAFO;AACC;AAAA,EACP;AAAA,EARK,mBAAkC;AAAA,EAClC,iBAAyB,KAAK,IAAI;AAAA,EAEnC,aAAqB;AAAA,EAO5B,QAAQ;AACN,QAAI,KAAK,qBAAqB,KAAM;AACpC,SAAK,iBAAiB,KAAK,IAAI;AAC/B,SAAK,QAAQ;AAAA,EACf;AAAA,EAEA,OAAO;AACL,QAAI,KAAK,qBAAqB,MAAM;AAClC,2BAAqB,KAAK,gBAAgB;AAC1C,WAAK,mBAAmB;AAAA,IAC1B;AAAA,EACF;AAAA,EAEQ,UAAU,MAAM;AACtB,UAAM,cAAc,KAAK,IAAI;AAC7B,UAAM,YAAY,cAAc,KAAK;AACrC,QAAI,gBAAgB;AAEpB,UAAM,iBAAiB,KAAK,WAAW,SAAS,KAAK,YAAY;AACjE,UAAM,kBAAkB,KAAK,IAAI,GAAG,MAAM,cAAc;AAExD,QAAI,aAAa;AACjB,WAAO,iBAAiB,mBAAmB,aAAa,gBAAgB;AACtE;AACA,uBAAiB;AAAA,IACnB;AAEA,QAAI,eAAe,gBAAgB;AACjC,WAAK,mBAAmB,sBAAsB,KAAK,OAAO;AAAA,IAC5D,OAAO;AACL,WAAK,mBAAmB;AAAA,IAC1B;AACA,QAAI,eAAe,EAAG;AAEtB,SAAK,cAAc,KAAK,WAAW;AAAA,MACjC;AAAA,MACA,KAAK,YAAY,SAAS;AAAA,IAC5B;AACA,SAAK,iBAAiB,cAAc;AACpC,SAAK,QAAQ,KAAK,WAAW;AAAA,EAC/B;AACF;AAEA,IAAM,gBAAmC,OAAO,OAAO;AAAA,EACrD,MAAM;AACR,CAAC;AAEM,IAAM,YAAY,CACvB,OACA,SAAkB,UAC8C;AAChE,QAAM,EAAE,KAAK,IAAI;AACjB,QAAM,KAAK,kBAAkB,CAAC,EAAE,QAAQ,MAAM,QAAQ,EAAE;AAExD,QAAM,QAAQ,OAAO,EAAE;AACvB,QAAM,CAAC,eAAe,gBAAgB,IAAI,SAAS,IAAI;AAEvD,QAAM,oBAAoB,qBAAqB,EAAE,UAAU,KAAK,CAAC;AACjE,QAAM,UAAU,eAAe,CAACA,UAAiB;AAC/C,qBAAiBA,KAAI;AACrB,QAAI,mBAAmB;AACrB,YAAM,SACJ,kBAAkBA,SAAQ,MAAM,OAAO,SAAS,YAC5C,gBACA,MAAM;AACZ,oBAAc,iBAAiB,EAAE,SAAS,QAAQ,IAAI;AAAA,IACxD;AAAA,EACF,CAAC;AAGD,YAAU,MAAM;AACd,QAAI,mBAAmB;AACrB,YAAM,SACJ,kBAAkB,QAAQ,MAAM,OAAO,SAAS,
|
|
1
|
+
{"version":3,"sources":["../../../src/utils/smooth/useSmooth.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useMemo, useRef, useState } from \"react\";\nimport { useAssistantState } from \"../../context\";\nimport {\n MessagePartStatus,\n ReasoningMessagePart,\n TextMessagePart,\n} from \"../../types/AssistantTypes\";\nimport { useCallbackRef } from \"@radix-ui/react-use-callback-ref\";\nimport { useSmoothStatusStore } from \"./SmoothContext\";\nimport { writableStore } from \"../../context/ReadonlyStore\";\nimport { MessagePartState } from \"../../legacy-runtime/runtime/MessagePartRuntime\";\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: MessagePartStatus = Object.freeze({\n type: \"running\",\n});\n\nexport const useSmooth = (\n state: MessagePartState & (TextMessagePart | ReasoningMessagePart),\n smooth: boolean = false,\n): MessagePartState & (TextMessagePart | ReasoningMessagePart) => {\n const { text } = state;\n const id = useAssistantState(({ message }) => message.id);\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 smooth && (displayedText !== text || state.status.type === \"running\")\n ? SMOOTH_STATUS\n : state.status;\n writableStore(smoothStatusStore).setState(target, true);\n }\n }, [smoothStatusStore, smooth, 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"]}
|
package/package.json
CHANGED
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"conversational-ui",
|
|
29
29
|
"conversational-ai"
|
|
30
30
|
],
|
|
31
|
-
"version": "0.11.
|
|
31
|
+
"version": "0.11.48",
|
|
32
32
|
"license": "MIT",
|
|
33
33
|
"type": "module",
|
|
34
34
|
"exports": {
|
|
@@ -48,8 +48,8 @@
|
|
|
48
48
|
],
|
|
49
49
|
"sideEffects": false,
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"assistant-cloud": "^0.1.
|
|
52
|
-
"@assistant-ui/tap": "^0.3.
|
|
51
|
+
"assistant-cloud": "^0.1.10",
|
|
52
|
+
"@assistant-ui/tap": "^0.3.2",
|
|
53
53
|
"@radix-ui/primitive": "^1.1.3",
|
|
54
54
|
"@radix-ui/react-compose-refs": "^1.1.2",
|
|
55
55
|
"@radix-ui/react-context": "^1.1.3",
|
|
@@ -59,11 +59,11 @@
|
|
|
59
59
|
"@radix-ui/react-use-callback-ref": "^1.1.1",
|
|
60
60
|
"@radix-ui/react-use-escape-keydown": "^1.1.1",
|
|
61
61
|
"@standard-schema/spec": "^1.0.0",
|
|
62
|
-
"assistant-stream": "^0.2.
|
|
62
|
+
"assistant-stream": "^0.2.43",
|
|
63
63
|
"nanoid": "5.1.6",
|
|
64
64
|
"react-textarea-autosize": "^8.5.9",
|
|
65
65
|
"zod": "^4.1.13",
|
|
66
|
-
"zustand": "^5.0.
|
|
66
|
+
"zustand": "^5.0.9"
|
|
67
67
|
},
|
|
68
68
|
"peerDependencies": {
|
|
69
69
|
"@types/react": "*",
|
|
@@ -84,10 +84,8 @@
|
|
|
84
84
|
"@stryker-mutator/vitest-runner": "^9.4.0",
|
|
85
85
|
"@types/json-schema": "^7.0.15",
|
|
86
86
|
"@types/node": "^24.10.1",
|
|
87
|
-
"
|
|
88
|
-
"
|
|
89
|
-
"tsx": "^4.20.6",
|
|
90
|
-
"vitest": "^4.0.14",
|
|
87
|
+
"tsx": "^4.21.0",
|
|
88
|
+
"vitest": "^4.0.15",
|
|
91
89
|
"@assistant-ui/x-buildutils": "0.0.1"
|
|
92
90
|
},
|
|
93
91
|
"publishConfig": {
|
|
@@ -106,7 +104,6 @@
|
|
|
106
104
|
"build": "tsx scripts/build.mts",
|
|
107
105
|
"test": "vitest run",
|
|
108
106
|
"test:watch": "vitest",
|
|
109
|
-
"test:mutation": "stryker run"
|
|
110
|
-
"lint": "eslint ."
|
|
107
|
+
"test:mutation": "stryker run"
|
|
111
108
|
}
|
|
112
109
|
}
|
package/src/augmentations.ts
CHANGED
|
@@ -22,10 +22,8 @@
|
|
|
22
22
|
* ```
|
|
23
23
|
*/
|
|
24
24
|
export namespace Assistant {
|
|
25
|
-
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
26
25
|
export interface Commands {}
|
|
27
26
|
|
|
28
|
-
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
29
27
|
export interface ExternalState {}
|
|
30
28
|
}
|
|
31
29
|
|
|
@@ -40,7 +40,7 @@ const ThreadMessagePartClient = resource(
|
|
|
40
40
|
{
|
|
41
41
|
key:
|
|
42
42
|
state.type === "tool-call"
|
|
43
|
-
?
|
|
43
|
+
? `toolCallId-${state.toolCallId}`
|
|
44
44
|
: undefined,
|
|
45
45
|
},
|
|
46
46
|
);
|
|
@@ -122,7 +122,7 @@ export const ThreadMessageClient = resource(
|
|
|
122
122
|
if ("index" in selector) {
|
|
123
123
|
return parts.api({ index: selector.index });
|
|
124
124
|
} else {
|
|
125
|
-
return parts.api({ key:
|
|
125
|
+
return parts.api({ key: `toolCallId-${selector.toolCallId}` });
|
|
126
126
|
}
|
|
127
127
|
},
|
|
128
128
|
attachment: (selector) => {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { Unsubscribe } from "../../types";
|
|
2
2
|
import type { ModelContextProvider } from "../../model-context/ModelContextTypes";
|
|
3
3
|
|
|
4
|
-
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
5
4
|
export type ModelContextState = {};
|
|
6
5
|
|
|
7
6
|
export type ModelContextApi = ModelContextProvider & {
|
|
@@ -19,6 +19,11 @@ import { CreateResumeRunConfig } from "../../legacy-runtime/runtime/ThreadRuntim
|
|
|
19
19
|
import { ModelContext } from "../../model-context";
|
|
20
20
|
|
|
21
21
|
export type ThreadClientState = {
|
|
22
|
+
/**
|
|
23
|
+
* Whether the thread is empty. A thread is considered empty when it has no messages and is not loading.
|
|
24
|
+
*/
|
|
25
|
+
readonly isEmpty: boolean;
|
|
26
|
+
|
|
22
27
|
/**
|
|
23
28
|
* Whether the thread is disabled. Disabled threads cannot receive new messages.
|
|
24
29
|
*/
|
|
@@ -287,10 +287,8 @@ export function useAssistantApi(): AssistantApi;
|
|
|
287
287
|
export function useAssistantApi(config: AssistantClientProps): AssistantApi;
|
|
288
288
|
export function useAssistantApi(config?: AssistantClientProps): AssistantApi {
|
|
289
289
|
if (config) {
|
|
290
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
291
290
|
return useExtendedAssistantApiImpl(config);
|
|
292
291
|
} else {
|
|
293
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
294
292
|
return useAssistantApiImpl();
|
|
295
293
|
}
|
|
296
294
|
}
|
|
@@ -75,7 +75,6 @@ export function createStateHookForRuntime<TState>(
|
|
|
75
75
|
if (!store) return null;
|
|
76
76
|
|
|
77
77
|
// it is ok to call useRuntimeStateInternal conditionally because it will never become null if its available
|
|
78
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
79
78
|
return useRuntimeStateInternal(store, selector);
|
|
80
79
|
}
|
|
81
80
|
|
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
import { FC, memo, PropsWithChildren } from "react";
|
|
4
4
|
import {
|
|
5
|
-
AssistantProvider,
|
|
6
5
|
useAssistantApi,
|
|
6
|
+
AssistantProvider,
|
|
7
7
|
} from "../context/react/AssistantApiContext";
|
|
8
8
|
import { AssistantRuntime } from "./runtime/AssistantRuntime";
|
|
9
9
|
import { AssistantRuntimeCore } from "./runtime-cores/core/AssistantRuntimeCore";
|
|
10
10
|
import { RuntimeAdapter } from "./RuntimeAdapter";
|
|
11
11
|
import { ThreadPrimitiveViewportProvider } from "../context/providers/ThreadViewportProvider";
|
|
12
12
|
|
|
13
|
-
export namespace
|
|
13
|
+
export namespace AssistantRuntimeProvider {
|
|
14
14
|
export type Props = PropsWithChildren<{
|
|
15
15
|
/**
|
|
16
16
|
* The runtime to provide to the rest of your app.
|
|
@@ -23,10 +23,9 @@ const getRenderComponent = (runtime: AssistantRuntime) => {
|
|
|
23
23
|
return (runtime as { _core?: AssistantRuntimeCore })._core?.RenderComponent;
|
|
24
24
|
};
|
|
25
25
|
|
|
26
|
-
export const AssistantRuntimeProviderImpl: FC<
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}) => {
|
|
26
|
+
export const AssistantRuntimeProviderImpl: FC<
|
|
27
|
+
AssistantRuntimeProvider.Props
|
|
28
|
+
> = ({ children, runtime }) => {
|
|
30
29
|
const api = useAssistantApi({
|
|
31
30
|
threads: RuntimeAdapter(runtime),
|
|
32
31
|
});
|
|
@@ -116,7 +116,7 @@ export const MessageClient = resource(
|
|
|
116
116
|
if ("index" in selector) {
|
|
117
117
|
return parts.api({ index: selector.index });
|
|
118
118
|
} else {
|
|
119
|
-
return parts.api({ key:
|
|
119
|
+
return parts.api({ key: `toolCallId-${selector.toolCallId}` });
|
|
120
120
|
}
|
|
121
121
|
},
|
|
122
122
|
|
|
@@ -97,6 +97,7 @@ export const ThreadClient = resource(
|
|
|
97
97
|
|
|
98
98
|
const state = tapMemo<ThreadClientState>(() => {
|
|
99
99
|
return {
|
|
100
|
+
isEmpty: messages.state.length === 0 && !runtimeState.isLoading,
|
|
100
101
|
isDisabled: runtimeState.isDisabled,
|
|
101
102
|
isLoading: runtimeState.isLoading,
|
|
102
103
|
isRunning: runtimeState.isRunning,
|
|
@@ -92,7 +92,7 @@ export const auiV0Encode = (message: ThreadMessage): AuiV0Message => {
|
|
|
92
92
|
case "tool-call": {
|
|
93
93
|
if (!isJSONValue(part.result)) {
|
|
94
94
|
console.warn(
|
|
95
|
-
|
|
95
|
+
`tool-call result is not JSON! ${JSON.stringify(part)}`,
|
|
96
96
|
);
|
|
97
97
|
}
|
|
98
98
|
return {
|
|
@@ -101,7 +101,9 @@ export class AssistantRuntimeImpl implements AssistantRuntime {
|
|
|
101
101
|
|
|
102
102
|
public reset({
|
|
103
103
|
initialMessages,
|
|
104
|
-
}: {
|
|
104
|
+
}: {
|
|
105
|
+
initialMessages?: ThreadMessageLike[];
|
|
106
|
+
} = {}) {
|
|
105
107
|
return this._core.threads
|
|
106
108
|
.getMainThreadRuntimeCore()
|
|
107
109
|
.import(ExportedMessageRepository.fromArray(initialMessages ?? []));
|
|
@@ -335,7 +335,7 @@ export class ThreadComposerRuntimeImpl
|
|
|
335
335
|
...this.path,
|
|
336
336
|
attachmentSource: "thread-composer",
|
|
337
337
|
attachmentSelector: { type: "index", index: idx },
|
|
338
|
-
ref: this.path.ref
|
|
338
|
+
ref: `${this.path.ref}${this.path.ref}.attachments[${idx}]`,
|
|
339
339
|
},
|
|
340
340
|
getState: () => {
|
|
341
341
|
const attachments = this.getState().attachments;
|
|
@@ -423,7 +423,7 @@ export class EditComposerRuntimeImpl
|
|
|
423
423
|
...this.path,
|
|
424
424
|
attachmentSource: "edit-composer",
|
|
425
425
|
attachmentSelector: { type: "index", index: idx },
|
|
426
|
-
ref: this.path.ref
|
|
426
|
+
ref: `${this.path.ref}${this.path.ref}.attachments[${idx}]`,
|
|
427
427
|
},
|
|
428
428
|
getState: () => {
|
|
429
429
|
const attachments = this.getState().attachments;
|
|
@@ -149,7 +149,7 @@ export class MessageRuntimeImpl implements MessageRuntime {
|
|
|
149
149
|
new NestedSubscriptionSubject({
|
|
150
150
|
path: {
|
|
151
151
|
...this.path,
|
|
152
|
-
ref: this.path.ref
|
|
152
|
+
ref: `${this.path.ref}${this.path.ref}.composer`,
|
|
153
153
|
composerSource: "edit",
|
|
154
154
|
},
|
|
155
155
|
getState: this._getEditComposerRuntimeCore,
|
|
@@ -270,7 +270,7 @@ export class MessageRuntimeImpl implements MessageRuntime {
|
|
|
270
270
|
new ShallowMemoizeSubject({
|
|
271
271
|
path: {
|
|
272
272
|
...this.path,
|
|
273
|
-
ref: this.path.ref
|
|
273
|
+
ref: `${this.path.ref}${this.path.ref}.content[${idx}]`,
|
|
274
274
|
messagePartSelector: { type: "index", index: idx },
|
|
275
275
|
},
|
|
276
276
|
getState: () => {
|
|
@@ -314,7 +314,7 @@ export class MessageRuntimeImpl implements MessageRuntime {
|
|
|
314
314
|
new ShallowMemoizeSubject({
|
|
315
315
|
path: {
|
|
316
316
|
...this.path,
|
|
317
|
-
ref: this.path.ref
|
|
317
|
+
ref: `${this.path.ref}${this.path.ref}.attachments[${idx}]`,
|
|
318
318
|
attachmentSource: "message",
|
|
319
319
|
attachmentSelector: { type: "index", index: idx },
|
|
320
320
|
},
|
|
@@ -163,7 +163,7 @@ export class ThreadListRuntimeImpl implements ThreadListRuntime {
|
|
|
163
163
|
return new this._runtimeFactory(
|
|
164
164
|
new NestedSubscriptionSubject({
|
|
165
165
|
path: {
|
|
166
|
-
ref:
|
|
166
|
+
ref: `threads[threadId=${JSON.stringify(threadId)}]`,
|
|
167
167
|
threadSelector: { type: "threadId", threadId },
|
|
168
168
|
},
|
|
169
169
|
getState: () => this._core.getThreadRuntimeCore(threadId),
|
|
@@ -338,7 +338,7 @@ export class ThreadRuntimeImpl implements ThreadRuntime {
|
|
|
338
338
|
new NestedSubscriptionSubject({
|
|
339
339
|
path: {
|
|
340
340
|
...this.path,
|
|
341
|
-
ref: this.path.ref
|
|
341
|
+
ref: `${this.path.ref}${this.path.ref}.composer`,
|
|
342
342
|
composerSource: "thread",
|
|
343
343
|
},
|
|
344
344
|
getState: () => this._threadBinding.getState().composer,
|
|
@@ -437,7 +437,7 @@ export class ThreadRuntimeImpl implements ThreadRuntime {
|
|
|
437
437
|
return this._getMessageRuntime(
|
|
438
438
|
{
|
|
439
439
|
...this.path,
|
|
440
|
-
ref: this.path.ref
|
|
440
|
+
ref: `${this.path.ref}${this.path.ref}.messages[${idx}]`,
|
|
441
441
|
messageSelector: { type: "index", index: idx },
|
|
442
442
|
},
|
|
443
443
|
() => {
|
|
@@ -13,7 +13,7 @@ export type RuntimeAdapters = {
|
|
|
13
13
|
|
|
14
14
|
const RuntimeAdaptersContext = createContext<RuntimeAdapters | null>(null);
|
|
15
15
|
|
|
16
|
-
namespace RuntimeAdapterProvider {
|
|
16
|
+
export namespace RuntimeAdapterProvider {
|
|
17
17
|
export type Props = {
|
|
18
18
|
adapters: RuntimeAdapters;
|
|
19
19
|
children: ReactNode;
|
|
@@ -19,7 +19,7 @@ function fileMatchesAccept(
|
|
|
19
19
|
.map((type) => type.trim().toLowerCase());
|
|
20
20
|
|
|
21
21
|
// Get the file's extension and MIME type
|
|
22
|
-
const fileExtension =
|
|
22
|
+
const fileExtension = `.${file.name.split(".").pop()!.toLowerCase()}`;
|
|
23
23
|
const fileMimeType = file.type.toLowerCase();
|
|
24
24
|
|
|
25
25
|
for (const type of allowedTypes) {
|
|
@@ -37,7 +37,7 @@ function fileMatchesAccept(
|
|
|
37
37
|
// Check for wildcard MIME type match
|
|
38
38
|
if (type.endsWith("/*")) {
|
|
39
39
|
const generalType = type.split("/")[0]!;
|
|
40
|
-
if (fileMimeType.startsWith(generalType
|
|
40
|
+
if (fileMimeType.startsWith(`${generalType}/`)) {
|
|
41
41
|
return true;
|
|
42
42
|
}
|
|
43
43
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export type { FeedbackAdapter } from "./FeedbackAdapter";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export type { SuggestionAdapter } from "./SuggestionAdapter";
|
|
@@ -70,7 +70,7 @@ type ExternalStoreAdapterBase<T> = {
|
|
|
70
70
|
onNew: (message: AppendMessage) => Promise<void>;
|
|
71
71
|
onEdit?: ((message: AppendMessage) => Promise<void>) | undefined;
|
|
72
72
|
onReload?: // TODO: remove parentId in 0.12.0
|
|
73
|
-
|
|
73
|
+
| ((parentId: string | null, config: StartRunConfig) => Promise<void>)
|
|
74
74
|
| undefined;
|
|
75
75
|
onResume?: ((config: ResumeRunConfig) => Promise<void>) | undefined;
|
|
76
76
|
onCancel?: (() => Promise<void>) | undefined;
|
|
@@ -132,7 +132,7 @@ export const fromThreadMessageLike = (
|
|
|
132
132
|
const { parentId, messages, ...basePart } = part;
|
|
133
133
|
const commonProps = {
|
|
134
134
|
...basePart,
|
|
135
|
-
toolCallId: part.toolCallId ??
|
|
135
|
+
toolCallId: part.toolCallId ?? `tool-${generateId()}`,
|
|
136
136
|
...(parentId !== undefined && { parentId }),
|
|
137
137
|
...(messages !== undefined && { messages }),
|
|
138
138
|
};
|
package/src/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListHookInstanceManager.tsx
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/* eslint-disable react-hooks/rules-of-hooks */
|
|
2
1
|
"use client";
|
|
3
2
|
|
|
4
3
|
import {
|
|
@@ -128,7 +127,6 @@ export class RemoteThreadListHookInstanceManager extends BaseSubscribable {
|
|
|
128
127
|
private _OuterActiveThreadProvider: FC<{
|
|
129
128
|
threadId: string;
|
|
130
129
|
provider: ComponentType<PropsWithChildren>;
|
|
131
|
-
// eslint-disable-next-line react/display-name
|
|
132
130
|
}> = memo(({ threadId, provider: Provider }) => {
|
|
133
131
|
// Runtime is provided by ThreadListItemByIdProvider
|
|
134
132
|
|
|
@@ -605,9 +605,7 @@ export class RemoteThreadListThreadListRuntimeCore
|
|
|
605
605
|
private useBoundIds = create<string[]>(() => []);
|
|
606
606
|
|
|
607
607
|
public __internal_RenderComponent: FC = () => {
|
|
608
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
609
608
|
const id = useId();
|
|
610
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
611
609
|
useEffect(() => {
|
|
612
610
|
this.useBoundIds.setState((s) => [...s, id], true);
|
|
613
611
|
return () => {
|
|
@@ -33,7 +33,9 @@ import { useAssistantState, useAssistantApi } from "../../context";
|
|
|
33
33
|
*/
|
|
34
34
|
const useActionBarPrimitiveCopy = ({
|
|
35
35
|
copiedDuration = 3000,
|
|
36
|
-
}: {
|
|
36
|
+
}: {
|
|
37
|
+
copiedDuration?: number | undefined;
|
|
38
|
+
} = {}) => {
|
|
37
39
|
const api = useAssistantApi();
|
|
38
40
|
const hasCopyableContent = useAssistantState(({ message }) => {
|
|
39
41
|
return (
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { forwardRef, useCallback } from "react";
|
|
4
|
+
import { ActionButtonProps } from "../../utils/createActionButton";
|
|
5
|
+
import { composeEventHandlers } from "@radix-ui/primitive";
|
|
6
|
+
import { Primitive } from "@radix-ui/react-primitive";
|
|
7
|
+
import { useAssistantState, useAssistantApi } from "../../context";
|
|
8
|
+
|
|
9
|
+
const useActionBarExportMarkdown = ({
|
|
10
|
+
filename,
|
|
11
|
+
onExport,
|
|
12
|
+
}: {
|
|
13
|
+
filename?: string | undefined;
|
|
14
|
+
onExport?: ((content: string) => void | Promise<void>) | undefined;
|
|
15
|
+
} = {}) => {
|
|
16
|
+
const api = useAssistantApi();
|
|
17
|
+
const hasExportableContent = useAssistantState(({ message }) => {
|
|
18
|
+
return (
|
|
19
|
+
(message.role !== "assistant" || message.status?.type !== "running") &&
|
|
20
|
+
message.parts.some((c) => c.type === "text" && c.text.length > 0)
|
|
21
|
+
);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
const callback = useCallback(async () => {
|
|
25
|
+
const content = api.message().getCopyText();
|
|
26
|
+
if (!content) return;
|
|
27
|
+
|
|
28
|
+
if (onExport) {
|
|
29
|
+
await onExport(content);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const blob = new Blob([content], { type: "text/markdown" });
|
|
34
|
+
const url = URL.createObjectURL(blob);
|
|
35
|
+
const a = document.createElement("a");
|
|
36
|
+
a.href = url;
|
|
37
|
+
a.download = filename ?? `message-${Date.now()}.md`;
|
|
38
|
+
a.click();
|
|
39
|
+
URL.revokeObjectURL(url);
|
|
40
|
+
}, [api, filename, onExport]);
|
|
41
|
+
|
|
42
|
+
if (!hasExportableContent) return null;
|
|
43
|
+
return callback;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export namespace ActionBarPrimitiveExportMarkdown {
|
|
47
|
+
export type Element = HTMLButtonElement;
|
|
48
|
+
export type Props = ActionButtonProps<typeof useActionBarExportMarkdown>;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export const ActionBarPrimitiveExportMarkdown = forwardRef<
|
|
52
|
+
ActionBarPrimitiveExportMarkdown.Element,
|
|
53
|
+
ActionBarPrimitiveExportMarkdown.Props
|
|
54
|
+
>(({ filename, onExport, onClick, disabled, ...props }, forwardedRef) => {
|
|
55
|
+
const callback = useActionBarExportMarkdown({ filename, onExport });
|
|
56
|
+
return (
|
|
57
|
+
<Primitive.button
|
|
58
|
+
type="button"
|
|
59
|
+
{...props}
|
|
60
|
+
ref={forwardedRef}
|
|
61
|
+
disabled={disabled || !callback}
|
|
62
|
+
onClick={composeEventHandlers(onClick, () => {
|
|
63
|
+
callback?.();
|
|
64
|
+
})}
|
|
65
|
+
/>
|
|
66
|
+
);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
ActionBarPrimitiveExportMarkdown.displayName =
|
|
70
|
+
"ActionBarPrimitive.ExportMarkdown";
|
|
@@ -6,3 +6,4 @@ export { ActionBarPrimitiveSpeak as Speak } from "./ActionBarSpeak";
|
|
|
6
6
|
export { ActionBarPrimitiveStopSpeaking as StopSpeaking } from "./ActionBarStopSpeaking";
|
|
7
7
|
export { ActionBarPrimitiveFeedbackPositive as FeedbackPositive } from "./ActionBarFeedbackPositive";
|
|
8
8
|
export { ActionBarPrimitiveFeedbackNegative as FeedbackNegative } from "./ActionBarFeedbackNegative";
|
|
9
|
+
export { ActionBarPrimitiveExportMarkdown as ExportMarkdown } from "./ActionBarExportMarkdown";
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import type { FC, PropsWithChildren } from "react";
|
|
4
|
+
import { useAssistantState } from "../../context";
|
|
5
|
+
import type { AssistantState } from "../../context/react/AssistantApiContext";
|
|
6
|
+
|
|
7
|
+
type UseAssistantIfProps = {
|
|
8
|
+
condition: AssistantIf.Condition;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const useAssistantIf = (props: UseAssistantIfProps) => {
|
|
12
|
+
return useAssistantState(props.condition);
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export namespace AssistantIf {
|
|
16
|
+
export type Props = PropsWithChildren<UseAssistantIfProps>;
|
|
17
|
+
export type Condition = (state: AssistantState) => boolean;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export const AssistantIf: FC<AssistantIf.Props> = ({ children, condition }) => {
|
|
21
|
+
const result = useAssistantIf({ condition });
|
|
22
|
+
return result ? children : null;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
AssistantIf.displayName = "AssistantIf";
|
|
@@ -23,6 +23,9 @@ export namespace ComposerPrimitiveIf {
|
|
|
23
23
|
export type Props = PropsWithChildren<UseComposerIfProps>;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
/**
|
|
27
|
+
* @deprecated Use `<AssistantIf condition={({ composer }) => ...} />` instead.
|
|
28
|
+
*/
|
|
26
29
|
export const ComposerPrimitiveIf: FC<ComposerPrimitiveIf.Props> = ({
|
|
27
30
|
children,
|
|
28
31
|
...query
|
|
@@ -114,6 +114,9 @@ export const ComposerPrimitiveInput = forwardRef<
|
|
|
114
114
|
useEscapeKeydown((e) => {
|
|
115
115
|
if (!cancelOnEscape) return;
|
|
116
116
|
|
|
117
|
+
// Only handle ESC if it originated from within this input
|
|
118
|
+
if (!textareaRef.current?.contains(e.target as Node)) return;
|
|
119
|
+
|
|
117
120
|
const composer = api.composer();
|
|
118
121
|
if (composer.getState().canCancel) {
|
|
119
122
|
composer.cancel();
|
package/src/primitives/index.ts
CHANGED
|
@@ -10,6 +10,8 @@ export * as ThreadPrimitive from "./thread";
|
|
|
10
10
|
export * as ThreadListPrimitive from "./threadList";
|
|
11
11
|
export * as ThreadListItemPrimitive from "./threadListItem";
|
|
12
12
|
|
|
13
|
+
export { AssistantIf } from "./assistant/AssistantIf";
|
|
14
|
+
|
|
13
15
|
export { useMessagePartText } from "./messagePart/useMessagePartText";
|
|
14
16
|
export { useMessagePartReasoning } from "./messagePart/useMessagePartReasoning";
|
|
15
17
|
export { useMessagePartSource } from "./messagePart/useMessagePartSource";
|
|
@@ -9,7 +9,7 @@ export const MessagePrimitiveError: FC<PropsWithChildren> = ({ children }) => {
|
|
|
9
9
|
message.status?.type === "incomplete" &&
|
|
10
10
|
message.status.reason === "error",
|
|
11
11
|
);
|
|
12
|
-
return hasError ?
|
|
12
|
+
return hasError ? children : null;
|
|
13
13
|
};
|
|
14
14
|
|
|
15
15
|
MessagePrimitiveError.displayName = "MessagePrimitive.Error";
|
|
@@ -77,6 +77,9 @@ export namespace MessagePrimitiveIf {
|
|
|
77
77
|
export type Props = PropsWithChildren<UseMessageIfProps>;
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
+
/**
|
|
81
|
+
* @deprecated Use `<AssistantIf condition={({ message }) => ...} />` instead.
|
|
82
|
+
*/
|
|
80
83
|
export const MessagePrimitiveIf: FC<MessagePrimitiveIf.Props> = ({
|
|
81
84
|
children,
|
|
82
85
|
...query
|