@assistant-ui/core 0.1.2 → 0.1.5
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/frame/provider.d.ts.map +1 -1
- package/dist/model-context/frame/provider.js +2 -4
- package/dist/model-context/frame/provider.js.map +1 -1
- package/dist/react/AssistantRuntimeProvider.d.ts +10 -0
- package/dist/react/AssistantRuntimeProvider.d.ts.map +1 -0
- package/dist/react/AssistantRuntimeProvider.js +16 -0
- package/dist/react/AssistantRuntimeProvider.js.map +1 -0
- package/dist/react/adapters/LocalStorageThreadListAdapter.d.ts +15 -0
- package/dist/react/adapters/LocalStorageThreadListAdapter.d.ts.map +1 -0
- package/dist/react/adapters/LocalStorageThreadListAdapter.js +154 -0
- package/dist/react/adapters/LocalStorageThreadListAdapter.js.map +1 -0
- package/dist/react/adapters/TitleGenerationAdapter.d.ts +6 -0
- package/dist/react/adapters/TitleGenerationAdapter.d.ts.map +1 -0
- package/dist/react/adapters/TitleGenerationAdapter.js +15 -0
- package/dist/react/adapters/TitleGenerationAdapter.js.map +1 -0
- package/dist/react/index.d.ts +5 -1
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +8 -1
- package/dist/react/index.js.map +1 -1
- package/dist/react/primitive-hooks/index.d.ts +15 -0
- package/dist/react/primitive-hooks/index.d.ts.map +1 -0
- package/dist/react/primitive-hooks/index.js +15 -0
- package/dist/react/primitive-hooks/index.js.map +1 -0
- package/dist/react/primitive-hooks/useActionBarCopy.d.ts +10 -0
- package/dist/react/primitive-hooks/useActionBarCopy.d.ts.map +1 -0
- package/dist/react/primitive-hooks/useActionBarCopy.js +26 -0
- package/dist/react/primitive-hooks/useActionBarCopy.js.map +1 -0
- package/dist/react/primitive-hooks/useActionBarEdit.d.ts +5 -0
- package/dist/react/primitive-hooks/useActionBarEdit.d.ts.map +1 -0
- package/dist/react/primitive-hooks/useActionBarEdit.js +11 -0
- package/dist/react/primitive-hooks/useActionBarEdit.js.map +1 -0
- package/dist/react/primitive-hooks/useActionBarFeedback.d.ts +9 -0
- package/dist/react/primitive-hooks/useActionBarFeedback.d.ts.map +1 -0
- package/dist/react/primitive-hooks/useActionBarFeedback.js +19 -0
- package/dist/react/primitive-hooks/useActionBarFeedback.js.map +1 -0
- package/dist/react/primitive-hooks/useActionBarReload.d.ts +5 -0
- package/dist/react/primitive-hooks/useActionBarReload.d.ts.map +1 -0
- package/dist/react/primitive-hooks/useActionBarReload.js +13 -0
- package/dist/react/primitive-hooks/useActionBarReload.js.map +1 -0
- package/dist/react/primitive-hooks/useComposerAddAttachment.d.ts +6 -0
- package/dist/react/primitive-hooks/useComposerAddAttachment.d.ts.map +1 -0
- package/dist/react/primitive-hooks/useComposerAddAttachment.js +11 -0
- package/dist/react/primitive-hooks/useComposerAddAttachment.js.map +1 -0
- package/dist/react/primitive-hooks/useComposerCancel.d.ts +5 -0
- package/dist/react/primitive-hooks/useComposerCancel.d.ts.map +1 -0
- package/dist/react/primitive-hooks/useComposerCancel.js +11 -0
- package/dist/react/primitive-hooks/useComposerCancel.js.map +1 -0
- package/dist/react/primitive-hooks/useComposerSend.d.ts +5 -0
- package/dist/react/primitive-hooks/useComposerSend.d.ts.map +1 -0
- package/dist/react/primitive-hooks/useComposerSend.js +11 -0
- package/dist/react/primitive-hooks/useComposerSend.js.map +1 -0
- package/dist/react/primitive-hooks/useEditComposerCancel.d.ts +4 -0
- package/dist/react/primitive-hooks/useEditComposerCancel.d.ts.map +1 -0
- package/dist/react/primitive-hooks/useEditComposerCancel.js +10 -0
- package/dist/react/primitive-hooks/useEditComposerCancel.js.map +1 -0
- package/dist/react/primitive-hooks/useEditComposerSend.d.ts +5 -0
- package/dist/react/primitive-hooks/useEditComposerSend.d.ts.map +1 -0
- package/dist/react/primitive-hooks/useEditComposerSend.js +11 -0
- package/dist/react/primitive-hooks/useEditComposerSend.js.map +1 -0
- package/dist/react/primitive-hooks/useMessageBranching.d.ts +7 -0
- package/dist/react/primitive-hooks/useMessageBranching.d.ts.map +1 -0
- package/dist/react/primitive-hooks/useMessageBranching.js +15 -0
- package/dist/react/primitive-hooks/useMessageBranching.js.map +1 -0
- package/dist/react/primitive-hooks/useMessageReload.d.ts +5 -0
- package/dist/react/primitive-hooks/useMessageReload.d.ts.map +1 -0
- package/dist/react/primitive-hooks/useMessageReload.js +11 -0
- package/dist/react/primitive-hooks/useMessageReload.js.map +1 -0
- package/dist/react/primitive-hooks/useThreadIsEmpty.d.ts +2 -0
- package/dist/react/primitive-hooks/useThreadIsEmpty.d.ts.map +1 -0
- package/dist/react/primitive-hooks/useThreadIsEmpty.js +5 -0
- package/dist/react/primitive-hooks/useThreadIsEmpty.js.map +1 -0
- package/dist/react/primitive-hooks/useThreadIsRunning.d.ts +2 -0
- package/dist/react/primitive-hooks/useThreadIsRunning.d.ts.map +1 -0
- package/dist/react/primitive-hooks/useThreadIsRunning.js +5 -0
- package/dist/react/primitive-hooks/useThreadIsRunning.js.map +1 -0
- package/dist/react/primitive-hooks/useThreadMessages.d.ts +3 -0
- package/dist/react/primitive-hooks/useThreadMessages.d.ts.map +1 -0
- package/dist/react/primitive-hooks/useThreadMessages.js +5 -0
- package/dist/react/primitive-hooks/useThreadMessages.js.map +1 -0
- package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts +97 -0
- package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts.map +1 -0
- package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js +111 -0
- package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js.map +1 -0
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts +115 -0
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -0
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js +444 -0
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js.map +1 -0
- package/dist/react/runtimes/RuntimeAdapterProvider.d.ts +18 -0
- package/dist/react/runtimes/RuntimeAdapterProvider.d.ts.map +1 -0
- package/dist/react/runtimes/RuntimeAdapterProvider.js +14 -0
- package/dist/react/runtimes/RuntimeAdapterProvider.js.map +1 -0
- package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts +5 -0
- package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts.map +1 -0
- package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js +528 -0
- package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js.map +1 -0
- package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.d.ts +15 -0
- package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.d.ts.map +1 -0
- package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.js +83 -0
- package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.js.map +1 -0
- package/dist/react/runtimes/cloud/auiV0.d.ts +62 -0
- package/dist/react/runtimes/cloud/auiV0.d.ts.map +1 -0
- package/dist/react/runtimes/cloud/auiV0.js +74 -0
- package/dist/react/runtimes/cloud/auiV0.js.map +1 -0
- package/dist/react/runtimes/cloud/index.d.ts +4 -0
- package/dist/react/runtimes/cloud/index.d.ts.map +1 -0
- package/dist/react/runtimes/cloud/index.js +4 -0
- package/dist/react/runtimes/cloud/index.js.map +1 -0
- package/dist/react/runtimes/cloud/useCloudThreadListAdapter.d.ts +13 -0
- package/dist/react/runtimes/cloud/useCloudThreadListAdapter.d.ts.map +1 -0
- package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js +103 -0
- package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js.map +1 -0
- package/dist/react/runtimes/createMessageConverter.d.ts +17 -0
- package/dist/react/runtimes/createMessageConverter.d.ts.map +1 -0
- package/dist/react/runtimes/createMessageConverter.js +50 -0
- package/dist/react/runtimes/createMessageConverter.js.map +1 -0
- package/dist/react/runtimes/external-message-converter.d.ts +34 -0
- package/dist/react/runtimes/external-message-converter.d.ts.map +1 -0
- package/dist/react/runtimes/external-message-converter.js +309 -0
- package/dist/react/runtimes/external-message-converter.js.map +1 -0
- package/dist/react/runtimes/index.d.ts +11 -0
- package/dist/react/runtimes/index.d.ts.map +1 -0
- package/dist/react/runtimes/index.js +11 -0
- package/dist/react/runtimes/index.js.map +1 -0
- package/dist/react/runtimes/useExternalStoreRuntime.d.ts +4 -0
- package/dist/react/runtimes/useExternalStoreRuntime.d.ts.map +1 -0
- package/dist/react/runtimes/useExternalStoreRuntime.js +19 -0
- package/dist/react/runtimes/useExternalStoreRuntime.js.map +1 -0
- package/dist/react/runtimes/useLocalRuntime.d.ts +28 -0
- package/dist/react/runtimes/useLocalRuntime.d.ts.map +1 -0
- package/dist/react/runtimes/useLocalRuntime.js +64 -0
- package/dist/react/runtimes/useLocalRuntime.js.map +1 -0
- package/dist/react/runtimes/useRemoteThreadListRuntime.d.ts +4 -0
- package/dist/react/runtimes/useRemoteThreadListRuntime.d.ts.map +1 -0
- package/dist/react/runtimes/useRemoteThreadListRuntime.js +48 -0
- package/dist/react/runtimes/useRemoteThreadListRuntime.js.map +1 -0
- package/dist/react/runtimes/useToolInvocations.d.ts +38 -0
- package/dist/react/runtimes/useToolInvocations.d.ts.map +1 -0
- package/dist/react/runtimes/useToolInvocations.js +411 -0
- package/dist/react/runtimes/useToolInvocations.js.map +1 -0
- package/dist/react/types/store-augmentation.d.ts +0 -1
- package/dist/react/types/store-augmentation.d.ts.map +1 -1
- package/dist/react/types/store-augmentation.js +1 -1
- package/dist/react/types/store-augmentation.js.map +1 -1
- package/dist/runtime/base/base-composer-runtime-core.d.ts.map +1 -1
- package/dist/runtime/base/base-composer-runtime-core.js +2 -0
- package/dist/runtime/base/base-composer-runtime-core.js.map +1 -1
- package/dist/store/index.d.ts +1 -1
- package/dist/store/index.d.ts.map +1 -1
- package/dist/store/index.js +1 -2
- package/dist/store/index.js.map +1 -1
- package/dist/utils/json/is-json-equal.d.ts +2 -0
- package/dist/utils/json/is-json-equal.d.ts.map +1 -0
- package/dist/utils/json/is-json-equal.js +31 -0
- package/dist/utils/json/is-json-equal.js.map +1 -0
- package/dist/utils/json/is-json.d.ts +6 -0
- package/dist/utils/json/is-json.d.ts.map +1 -0
- package/dist/utils/json/is-json.js +33 -0
- package/dist/utils/json/is-json.js.map +1 -0
- package/package.json +11 -10
- package/src/model-context/frame/provider.ts +2 -6
- package/src/react/AssistantRuntimeProvider.tsx +33 -0
- package/src/react/adapters/LocalStorageThreadListAdapter.tsx +227 -0
- package/src/react/adapters/TitleGenerationAdapter.ts +20 -0
- package/src/react/index.ts +17 -1
- package/src/react/primitive-hooks/index.ts +20 -0
- package/src/react/primitive-hooks/useActionBarCopy.ts +38 -0
- package/src/react/primitive-hooks/useActionBarEdit.ts +13 -0
- package/src/react/primitive-hooks/useActionBarFeedback.ts +28 -0
- package/src/react/primitive-hooks/useActionBarReload.ts +18 -0
- package/src/react/primitive-hooks/useComposerAddAttachment.ts +17 -0
- package/src/react/primitive-hooks/useComposerCancel.ts +13 -0
- package/src/react/primitive-hooks/useComposerSend.ts +15 -0
- package/src/react/primitive-hooks/useEditComposerCancel.ts +12 -0
- package/src/react/primitive-hooks/useEditComposerSend.ts +13 -0
- package/src/react/primitive-hooks/useMessageBranching.ts +18 -0
- package/src/react/primitive-hooks/useMessageReload.ts +13 -0
- package/src/react/primitive-hooks/useThreadIsEmpty.ts +5 -0
- package/src/react/primitive-hooks/useThreadIsRunning.ts +5 -0
- package/src/react/primitive-hooks/useThreadMessages.ts +6 -0
- package/src/react/runtimes/RemoteThreadListHookInstanceManager.tsx +176 -0
- package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.tsx +534 -0
- package/src/react/runtimes/RuntimeAdapterProvider.tsx +40 -0
- package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.ts +785 -0
- package/src/react/runtimes/cloud/CloudFileAttachmentAdapter.ts +101 -0
- package/src/react/runtimes/cloud/auiV0.ts +160 -0
- package/src/react/runtimes/cloud/index.ts +3 -0
- package/src/react/runtimes/cloud/useCloudThreadListAdapter.tsx +154 -0
- package/src/react/runtimes/createMessageConverter.ts +77 -0
- package/src/react/runtimes/external-message-converter.ts +487 -0
- package/src/react/runtimes/index.ts +36 -0
- package/src/react/runtimes/useExternalStoreRuntime.ts +27 -0
- package/src/react/runtimes/useLocalRuntime.ts +101 -0
- package/src/react/runtimes/useRemoteThreadListRuntime.ts +76 -0
- package/src/react/runtimes/useToolInvocations.ts +594 -0
- package/src/react/types/store-augmentation.ts +0 -2
- package/src/runtime/base/base-composer-runtime-core.ts +2 -0
- package/src/store/index.ts +1 -2
- package/src/tests/no-unsafe-process-env.test.ts +58 -0
- package/src/utils/json/is-json-equal.ts +48 -0
- package/src/utils/json/is-json.ts +58 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export function isRecord(value) {
|
|
2
|
+
return value != null && typeof value === "object" && !Array.isArray(value);
|
|
3
|
+
}
|
|
4
|
+
export function isJSONValue(value, currentDepth = 0) {
|
|
5
|
+
// Protect against too deep recursion
|
|
6
|
+
if (currentDepth > 100) {
|
|
7
|
+
return false;
|
|
8
|
+
}
|
|
9
|
+
if (value === null ||
|
|
10
|
+
typeof value === "string" ||
|
|
11
|
+
typeof value === "boolean") {
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
// Handle special number cases
|
|
15
|
+
if (typeof value === "number") {
|
|
16
|
+
return !Number.isNaN(value) && Number.isFinite(value);
|
|
17
|
+
}
|
|
18
|
+
if (Array.isArray(value)) {
|
|
19
|
+
return value.every((item) => isJSONValue(item, currentDepth + 1));
|
|
20
|
+
}
|
|
21
|
+
if (isRecord(value)) {
|
|
22
|
+
return Object.entries(value).every(([key, val]) => typeof key === "string" && isJSONValue(val, currentDepth + 1));
|
|
23
|
+
}
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
export function isJSONArray(value) {
|
|
27
|
+
return Array.isArray(value) && value.every(isJSONValue);
|
|
28
|
+
}
|
|
29
|
+
export function isJSONObject(value) {
|
|
30
|
+
return (isRecord(value) &&
|
|
31
|
+
Object.entries(value).every(([key, val]) => typeof key === "string" && isJSONValue(val)));
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=is-json.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"is-json.js","sourceRoot":"","sources":["../../../src/utils/json/is-json.ts"],"names":[],"mappings":"AAMA,MAAM,UAAU,QAAQ,CAAC,KAAc;IACrC,OAAO,KAAK,IAAI,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC7E,CAAC;AAED,MAAM,UAAU,WAAW,CACzB,KAAc,EACd,eAAuB,CAAC;IAExB,qCAAqC;IACrC,IAAI,YAAY,GAAG,GAAG,EAAE,CAAC;QACvB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IACE,KAAK,KAAK,IAAI;QACd,OAAO,KAAK,KAAK,QAAQ;QACzB,OAAO,KAAK,KAAK,SAAS,EAC1B,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,8BAA8B;IAC9B,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACxD,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,EAAE,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC;IACpE,CAAC;IAED,IAAI,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACpB,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,KAAK,CAChC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,EAAE,CACb,OAAO,GAAG,KAAK,QAAQ,IAAI,WAAW,CAAC,GAAG,EAAE,YAAY,GAAG,CAAC,CAAC,CAChE,CAAC;IACJ,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAc;IACxC,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;AAC1D,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAc;IACzC,OAAO,CACL,QAAQ,CAAC,KAAK,CAAC;QACf,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,KAAK,CACzB,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,OAAO,GAAG,KAAK,QAAQ,IAAI,WAAW,CAAC,GAAG,CAAC,CAC5D,CACF,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@assistant-ui/core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "Framework-agnostic core runtime for assistant-ui",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"assistant",
|
|
@@ -53,25 +53,25 @@
|
|
|
53
53
|
],
|
|
54
54
|
"sideEffects": false,
|
|
55
55
|
"dependencies": {
|
|
56
|
-
"assistant-stream": "^0.3.
|
|
56
|
+
"assistant-stream": "^0.3.5",
|
|
57
57
|
"nanoid": "^5.1.6"
|
|
58
58
|
},
|
|
59
59
|
"peerDependencies": {
|
|
60
|
-
"@assistant-ui/store": "^0.2.
|
|
61
|
-
"@assistant-ui/tap": "^0.5.
|
|
60
|
+
"@assistant-ui/store": "^0.2.2",
|
|
61
|
+
"@assistant-ui/tap": "^0.5.2",
|
|
62
62
|
"@types/react": "*",
|
|
63
63
|
"react": "^18 || ^19",
|
|
64
|
-
"
|
|
64
|
+
"assistant-cloud": "^0.1.21",
|
|
65
65
|
"zustand": "^5.0.11"
|
|
66
66
|
},
|
|
67
67
|
"peerDependenciesMeta": {
|
|
68
68
|
"@types/react": {
|
|
69
69
|
"optional": true
|
|
70
70
|
},
|
|
71
|
-
"
|
|
71
|
+
"assistant-cloud": {
|
|
72
72
|
"optional": true
|
|
73
73
|
},
|
|
74
|
-
"
|
|
74
|
+
"react": {
|
|
75
75
|
"optional": true
|
|
76
76
|
},
|
|
77
77
|
"zustand": {
|
|
@@ -83,9 +83,10 @@
|
|
|
83
83
|
"react": "^19.2.4",
|
|
84
84
|
"vitest": "^4.0.18",
|
|
85
85
|
"zustand": "^5.0.11",
|
|
86
|
-
"
|
|
87
|
-
"@assistant-ui/
|
|
88
|
-
"@assistant-ui/
|
|
86
|
+
"assistant-cloud": "0.1.21",
|
|
87
|
+
"@assistant-ui/store": "0.2.2",
|
|
88
|
+
"@assistant-ui/tap": "0.5.2",
|
|
89
|
+
"@assistant-ui/x-buildutils": "0.0.2"
|
|
89
90
|
},
|
|
90
91
|
"publishConfig": {
|
|
91
92
|
"access": "public",
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { ModelContextProvider, ModelContext } from "../types";
|
|
2
2
|
import type { Unsubscribe } from "../../types";
|
|
3
|
-
import { Tool } from "assistant-stream";
|
|
4
|
-
import { z } from "zod";
|
|
3
|
+
import { Tool, toJSONSchema } from "assistant-stream";
|
|
5
4
|
import {
|
|
6
5
|
FrameMessage,
|
|
7
6
|
FRAME_MESSAGE_CHANNEL,
|
|
@@ -11,10 +10,7 @@ import {
|
|
|
11
10
|
|
|
12
11
|
const serializeTool = (tool: Tool<any, any>): SerializedTool => ({
|
|
13
12
|
...(tool.description && { description: tool.description }),
|
|
14
|
-
parameters:
|
|
15
|
-
tool.parameters instanceof z.ZodType
|
|
16
|
-
? ((z as any).toJSONSchema?.(tool.parameters) ?? tool.parameters)
|
|
17
|
-
: tool.parameters,
|
|
13
|
+
parameters: tool.parameters ? toJSONSchema(tool.parameters) : undefined,
|
|
18
14
|
...(tool.disabled !== undefined && { disabled: tool.disabled }),
|
|
19
15
|
...(tool.type && { type: tool.type }),
|
|
20
16
|
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { type ReactNode, memo } from "react";
|
|
2
|
+
import { useAui, type AssistantClient } from "@assistant-ui/store";
|
|
3
|
+
import type { AssistantRuntime } from "../runtime/api/assistant-runtime";
|
|
4
|
+
import { AssistantProviderBase } from "./AssistantProvider";
|
|
5
|
+
|
|
6
|
+
export const useAssistantRuntime = (): AssistantRuntime => {
|
|
7
|
+
const aui = useAui();
|
|
8
|
+
const runtime = aui.threads().__internal_getAssistantRuntime?.();
|
|
9
|
+
if (!runtime) {
|
|
10
|
+
throw new Error(
|
|
11
|
+
"useAssistantRuntime must be used within an AssistantRuntimeProvider",
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
return runtime;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const AssistantRuntimeProvider = memo(
|
|
18
|
+
({
|
|
19
|
+
runtime,
|
|
20
|
+
aui,
|
|
21
|
+
children,
|
|
22
|
+
}: {
|
|
23
|
+
runtime: AssistantRuntime;
|
|
24
|
+
aui?: AssistantClient | null;
|
|
25
|
+
children: ReactNode;
|
|
26
|
+
}) => {
|
|
27
|
+
return (
|
|
28
|
+
<AssistantProviderBase runtime={runtime} aui={aui ?? null}>
|
|
29
|
+
{children}
|
|
30
|
+
</AssistantProviderBase>
|
|
31
|
+
);
|
|
32
|
+
},
|
|
33
|
+
);
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import { type AssistantStream, createAssistantStream } from "assistant-stream";
|
|
2
|
+
import { FC, PropsWithChildren, useMemo } from "react";
|
|
3
|
+
import { useAui } from "@assistant-ui/store";
|
|
4
|
+
import type {
|
|
5
|
+
RemoteThreadInitializeResponse,
|
|
6
|
+
RemoteThreadListAdapter,
|
|
7
|
+
RemoteThreadListResponse,
|
|
8
|
+
RemoteThreadMetadata,
|
|
9
|
+
ThreadHistoryAdapter,
|
|
10
|
+
ThreadMessage,
|
|
11
|
+
} from "../../index";
|
|
12
|
+
import type {
|
|
13
|
+
ExportedMessageRepository,
|
|
14
|
+
ExportedMessageRepositoryItem,
|
|
15
|
+
} from "../../internal";
|
|
16
|
+
import { RuntimeAdapterProvider } from "../runtimes/RuntimeAdapterProvider";
|
|
17
|
+
import type { TitleGenerationAdapter } from "./TitleGenerationAdapter";
|
|
18
|
+
|
|
19
|
+
export type AsyncStorageLike = {
|
|
20
|
+
getItem(key: string): Promise<string | null>;
|
|
21
|
+
setItem(key: string, value: string): Promise<void>;
|
|
22
|
+
removeItem(key: string): Promise<void>;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
type LocalStorageAdapterOptions = {
|
|
26
|
+
storage: AsyncStorageLike;
|
|
27
|
+
prefix?: string | undefined;
|
|
28
|
+
titleGenerator?: TitleGenerationAdapter | undefined;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
type StoredThreadMetadata = {
|
|
32
|
+
remoteId: string;
|
|
33
|
+
externalId?: string;
|
|
34
|
+
status: "regular" | "archived";
|
|
35
|
+
title?: string;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
class AsyncStorageHistoryAdapter implements ThreadHistoryAdapter {
|
|
39
|
+
constructor(
|
|
40
|
+
private storage: AsyncStorageLike,
|
|
41
|
+
private aui: ReturnType<typeof useAui>,
|
|
42
|
+
private prefix: string,
|
|
43
|
+
) {}
|
|
44
|
+
|
|
45
|
+
private _messagesKey(remoteId: string) {
|
|
46
|
+
return `${this.prefix}messages:${remoteId}`;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
async load(): Promise<ExportedMessageRepository> {
|
|
50
|
+
const remoteId = this.aui.threadListItem().getState().remoteId;
|
|
51
|
+
if (!remoteId) return { messages: [] };
|
|
52
|
+
|
|
53
|
+
const raw = await this.storage.getItem(this._messagesKey(remoteId));
|
|
54
|
+
if (!raw) return { messages: [] };
|
|
55
|
+
return JSON.parse(raw) as ExportedMessageRepository;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async append(item: ExportedMessageRepositoryItem): Promise<void> {
|
|
59
|
+
const { remoteId } = await this.aui.threadListItem().initialize();
|
|
60
|
+
|
|
61
|
+
const key = this._messagesKey(remoteId);
|
|
62
|
+
const raw = await this.storage.getItem(key);
|
|
63
|
+
const repo: ExportedMessageRepository = raw
|
|
64
|
+
? (JSON.parse(raw) as ExportedMessageRepository)
|
|
65
|
+
: { messages: [] };
|
|
66
|
+
|
|
67
|
+
const idx = repo.messages.findIndex(
|
|
68
|
+
(m) => m.message.id === item.message.id,
|
|
69
|
+
);
|
|
70
|
+
if (idx >= 0) {
|
|
71
|
+
repo.messages[idx] = item;
|
|
72
|
+
} else {
|
|
73
|
+
repo.messages.push(item);
|
|
74
|
+
}
|
|
75
|
+
repo.headId = item.message.id;
|
|
76
|
+
|
|
77
|
+
await this.storage.setItem(key, JSON.stringify(repo));
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const createHistoryProvider = (
|
|
82
|
+
storage: AsyncStorageLike,
|
|
83
|
+
prefix: string,
|
|
84
|
+
): FC<PropsWithChildren> => {
|
|
85
|
+
const Provider: FC<PropsWithChildren> = ({ children }) => {
|
|
86
|
+
const aui = useAui();
|
|
87
|
+
const history = useMemo(
|
|
88
|
+
() => new AsyncStorageHistoryAdapter(storage, aui, prefix),
|
|
89
|
+
[aui],
|
|
90
|
+
);
|
|
91
|
+
const adapters = useMemo(() => ({ history }), [history]);
|
|
92
|
+
|
|
93
|
+
return (
|
|
94
|
+
<RuntimeAdapterProvider adapters={adapters}>
|
|
95
|
+
{children}
|
|
96
|
+
</RuntimeAdapterProvider>
|
|
97
|
+
);
|
|
98
|
+
};
|
|
99
|
+
return Provider;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
export const createLocalStorageAdapter = (
|
|
103
|
+
options: LocalStorageAdapterOptions,
|
|
104
|
+
): RemoteThreadListAdapter => {
|
|
105
|
+
const { storage, prefix = "@assistant-ui:", titleGenerator } = options;
|
|
106
|
+
|
|
107
|
+
const threadsKey = `${prefix}threads`;
|
|
108
|
+
const messagesKey = (threadId: string) => `${prefix}messages:${threadId}`;
|
|
109
|
+
|
|
110
|
+
const loadThreadMetadata = async (): Promise<StoredThreadMetadata[]> => {
|
|
111
|
+
const raw = await storage.getItem(threadsKey);
|
|
112
|
+
return raw ? (JSON.parse(raw) as StoredThreadMetadata[]) : [];
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
const saveThreadMetadata = async (
|
|
116
|
+
threads: StoredThreadMetadata[],
|
|
117
|
+
): Promise<void> => {
|
|
118
|
+
await storage.setItem(threadsKey, JSON.stringify(threads));
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
const adapter: RemoteThreadListAdapter = {
|
|
122
|
+
unstable_Provider: createHistoryProvider(storage, prefix),
|
|
123
|
+
|
|
124
|
+
async list(): Promise<RemoteThreadListResponse> {
|
|
125
|
+
const threads = await loadThreadMetadata();
|
|
126
|
+
return {
|
|
127
|
+
threads: threads.map((t) => ({
|
|
128
|
+
remoteId: t.remoteId,
|
|
129
|
+
externalId: t.externalId,
|
|
130
|
+
status: t.status,
|
|
131
|
+
title: t.title,
|
|
132
|
+
})),
|
|
133
|
+
};
|
|
134
|
+
},
|
|
135
|
+
|
|
136
|
+
async initialize(
|
|
137
|
+
threadId: string,
|
|
138
|
+
): Promise<RemoteThreadInitializeResponse> {
|
|
139
|
+
const remoteId = threadId;
|
|
140
|
+
const threads = await loadThreadMetadata();
|
|
141
|
+
|
|
142
|
+
// Only add if not already present
|
|
143
|
+
if (!threads.some((t) => t.remoteId === remoteId)) {
|
|
144
|
+
threads.unshift({
|
|
145
|
+
remoteId,
|
|
146
|
+
status: "regular",
|
|
147
|
+
});
|
|
148
|
+
await saveThreadMetadata(threads);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return { remoteId, externalId: undefined };
|
|
152
|
+
},
|
|
153
|
+
|
|
154
|
+
async rename(remoteId: string, newTitle: string): Promise<void> {
|
|
155
|
+
const threads = await loadThreadMetadata();
|
|
156
|
+
const thread = threads.find((t) => t.remoteId === remoteId);
|
|
157
|
+
if (thread) {
|
|
158
|
+
thread.title = newTitle;
|
|
159
|
+
await saveThreadMetadata(threads);
|
|
160
|
+
}
|
|
161
|
+
},
|
|
162
|
+
|
|
163
|
+
async archive(remoteId: string): Promise<void> {
|
|
164
|
+
const threads = await loadThreadMetadata();
|
|
165
|
+
const thread = threads.find((t) => t.remoteId === remoteId);
|
|
166
|
+
if (thread) {
|
|
167
|
+
thread.status = "archived";
|
|
168
|
+
await saveThreadMetadata(threads);
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
|
|
172
|
+
async unarchive(remoteId: string): Promise<void> {
|
|
173
|
+
const threads = await loadThreadMetadata();
|
|
174
|
+
const thread = threads.find((t) => t.remoteId === remoteId);
|
|
175
|
+
if (thread) {
|
|
176
|
+
thread.status = "regular";
|
|
177
|
+
await saveThreadMetadata(threads);
|
|
178
|
+
}
|
|
179
|
+
},
|
|
180
|
+
|
|
181
|
+
async delete(remoteId: string): Promise<void> {
|
|
182
|
+
const threads = await loadThreadMetadata();
|
|
183
|
+
const filtered = threads.filter((t) => t.remoteId !== remoteId);
|
|
184
|
+
await saveThreadMetadata(filtered);
|
|
185
|
+
await storage.removeItem(messagesKey(remoteId));
|
|
186
|
+
},
|
|
187
|
+
|
|
188
|
+
async fetch(threadId: string): Promise<RemoteThreadMetadata> {
|
|
189
|
+
const threads = await loadThreadMetadata();
|
|
190
|
+
const thread = threads.find((t) => t.remoteId === threadId);
|
|
191
|
+
if (!thread) throw new Error("Thread not found");
|
|
192
|
+
return {
|
|
193
|
+
remoteId: thread.remoteId,
|
|
194
|
+
externalId: thread.externalId,
|
|
195
|
+
status: thread.status,
|
|
196
|
+
title: thread.title,
|
|
197
|
+
};
|
|
198
|
+
},
|
|
199
|
+
|
|
200
|
+
async generateTitle(
|
|
201
|
+
remoteId: string,
|
|
202
|
+
messages: readonly ThreadMessage[],
|
|
203
|
+
): Promise<AssistantStream> {
|
|
204
|
+
if (titleGenerator) {
|
|
205
|
+
const title = await titleGenerator.generateTitle(messages);
|
|
206
|
+
|
|
207
|
+
// Update the stored title
|
|
208
|
+
const threads = await loadThreadMetadata();
|
|
209
|
+
const thread = threads.find((t) => t.remoteId === remoteId);
|
|
210
|
+
if (thread) {
|
|
211
|
+
thread.title = title;
|
|
212
|
+
await saveThreadMetadata(threads);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// Return a stream with a single text part
|
|
216
|
+
return createAssistantStream((controller) => {
|
|
217
|
+
controller.appendText(title);
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// No title generator — return empty stream
|
|
222
|
+
return createAssistantStream(() => {});
|
|
223
|
+
},
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
return adapter;
|
|
227
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ThreadMessage } from "../../types/message";
|
|
2
|
+
|
|
3
|
+
export type TitleGenerationAdapter = {
|
|
4
|
+
generateTitle(messages: readonly ThreadMessage[]): Promise<string>;
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
export const createSimpleTitleAdapter = (): TitleGenerationAdapter => {
|
|
8
|
+
return {
|
|
9
|
+
async generateTitle(messages) {
|
|
10
|
+
const firstUserMessage = messages.find((m) => m.role === "user");
|
|
11
|
+
if (!firstUserMessage) return "New Thread";
|
|
12
|
+
|
|
13
|
+
const textPart = firstUserMessage.content.find((p) => p.type === "text");
|
|
14
|
+
if (!textPart || textPart.type !== "text") return "New Thread";
|
|
15
|
+
|
|
16
|
+
const text = textPart.text.trim();
|
|
17
|
+
return text.length > 50 ? `${text.slice(0, 47)}...` : text;
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
};
|
package/src/react/index.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
/// <reference path="./types/store-augmentation.ts" />
|
|
2
2
|
|
|
3
3
|
export * from "./model-context";
|
|
4
4
|
export * from "./client";
|
|
5
5
|
export * from "./types";
|
|
6
6
|
export * from "./providers";
|
|
7
7
|
export { RuntimeAdapter } from "./RuntimeAdapter";
|
|
8
|
+
export * from "./runtimes";
|
|
8
9
|
|
|
9
10
|
// AssistantProvider base
|
|
10
11
|
export {
|
|
@@ -48,3 +49,18 @@ export {
|
|
|
48
49
|
ComposerPrimitiveIf,
|
|
49
50
|
type UseComposerIfProps,
|
|
50
51
|
} from "./primitives/composer/ComposerIf";
|
|
52
|
+
|
|
53
|
+
// Primitive hooks (shared behavior logic)
|
|
54
|
+
export * from "./primitive-hooks";
|
|
55
|
+
|
|
56
|
+
// Shared AssistantRuntimeProvider
|
|
57
|
+
export {
|
|
58
|
+
AssistantRuntimeProvider,
|
|
59
|
+
useAssistantRuntime,
|
|
60
|
+
} from "./AssistantRuntimeProvider";
|
|
61
|
+
|
|
62
|
+
// Shared runtimes
|
|
63
|
+
export {
|
|
64
|
+
useLocalRuntime,
|
|
65
|
+
type LocalRuntimeOptions,
|
|
66
|
+
} from "./runtimes/useLocalRuntime";
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export { useThreadMessages } from "./useThreadMessages";
|
|
2
|
+
export { useThreadIsRunning } from "./useThreadIsRunning";
|
|
3
|
+
export { useThreadIsEmpty } from "./useThreadIsEmpty";
|
|
4
|
+
export { useComposerSend } from "./useComposerSend";
|
|
5
|
+
export { useComposerCancel } from "./useComposerCancel";
|
|
6
|
+
export { useMessageReload } from "./useMessageReload";
|
|
7
|
+
export { useMessageBranching } from "./useMessageBranching";
|
|
8
|
+
export {
|
|
9
|
+
useActionBarCopy,
|
|
10
|
+
type UseActionBarCopyOptions,
|
|
11
|
+
} from "./useActionBarCopy";
|
|
12
|
+
export { useActionBarEdit } from "./useActionBarEdit";
|
|
13
|
+
export { useActionBarReload } from "./useActionBarReload";
|
|
14
|
+
export {
|
|
15
|
+
useActionBarFeedbackPositive,
|
|
16
|
+
useActionBarFeedbackNegative,
|
|
17
|
+
} from "./useActionBarFeedback";
|
|
18
|
+
export { useComposerAddAttachment } from "./useComposerAddAttachment";
|
|
19
|
+
export { useEditComposerCancel } from "./useEditComposerCancel";
|
|
20
|
+
export { useEditComposerSend } from "./useEditComposerSend";
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { useCallback } from "react";
|
|
2
|
+
import { useAui, useAuiState } from "@assistant-ui/store";
|
|
3
|
+
|
|
4
|
+
export type UseActionBarCopyOptions = {
|
|
5
|
+
copiedDuration?: number | undefined;
|
|
6
|
+
copyToClipboard?: ((text: string) => void | Promise<void>) | undefined;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const useActionBarCopy = ({
|
|
10
|
+
copiedDuration = 3000,
|
|
11
|
+
copyToClipboard,
|
|
12
|
+
}: UseActionBarCopyOptions = {}) => {
|
|
13
|
+
const aui = useAui();
|
|
14
|
+
const disabled = useAuiState((s) => {
|
|
15
|
+
return !(
|
|
16
|
+
(s.message.role !== "assistant" ||
|
|
17
|
+
s.message.status?.type !== "running") &&
|
|
18
|
+
s.message.parts.some((c) => c.type === "text" && c.text.length > 0)
|
|
19
|
+
);
|
|
20
|
+
});
|
|
21
|
+
const isCopied = useAuiState((s) => s.message.isCopied);
|
|
22
|
+
const isEditing = useAuiState((s) => s.composer.isEditing);
|
|
23
|
+
const composerValue = useAuiState((s) => s.composer.text);
|
|
24
|
+
|
|
25
|
+
const copy = useCallback(() => {
|
|
26
|
+
const valueToCopy = isEditing ? composerValue : aui.message().getCopyText();
|
|
27
|
+
if (!valueToCopy) return;
|
|
28
|
+
|
|
29
|
+
const write = copyToClipboard ?? (() => {});
|
|
30
|
+
const result = write(valueToCopy);
|
|
31
|
+
Promise.resolve(result).then(() => {
|
|
32
|
+
aui.message().setIsCopied(true);
|
|
33
|
+
setTimeout(() => aui.message().setIsCopied(false), copiedDuration);
|
|
34
|
+
});
|
|
35
|
+
}, [aui, isEditing, composerValue, copiedDuration, copyToClipboard]);
|
|
36
|
+
|
|
37
|
+
return { copy, disabled, isCopied };
|
|
38
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { useCallback } from "react";
|
|
2
|
+
import { useAui, useAuiState } from "@assistant-ui/store";
|
|
3
|
+
|
|
4
|
+
export const useActionBarEdit = () => {
|
|
5
|
+
const aui = useAui();
|
|
6
|
+
const disabled = useAuiState((s) => s.composer.isEditing);
|
|
7
|
+
|
|
8
|
+
const edit = useCallback(() => {
|
|
9
|
+
aui.composer().beginEdit();
|
|
10
|
+
}, [aui]);
|
|
11
|
+
|
|
12
|
+
return { edit, disabled };
|
|
13
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { useCallback } from "react";
|
|
2
|
+
import { useAui, useAuiState } from "@assistant-ui/store";
|
|
3
|
+
|
|
4
|
+
export const useActionBarFeedbackPositive = () => {
|
|
5
|
+
const aui = useAui();
|
|
6
|
+
const isSubmitted = useAuiState(
|
|
7
|
+
(s) => s.message.metadata.submittedFeedback?.type === "positive",
|
|
8
|
+
);
|
|
9
|
+
|
|
10
|
+
const submit = useCallback(() => {
|
|
11
|
+
aui.message().submitFeedback({ type: "positive" });
|
|
12
|
+
}, [aui]);
|
|
13
|
+
|
|
14
|
+
return { submit, isSubmitted };
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const useActionBarFeedbackNegative = () => {
|
|
18
|
+
const aui = useAui();
|
|
19
|
+
const isSubmitted = useAuiState(
|
|
20
|
+
(s) => s.message.metadata.submittedFeedback?.type === "negative",
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
const submit = useCallback(() => {
|
|
24
|
+
aui.message().submitFeedback({ type: "negative" });
|
|
25
|
+
}, [aui]);
|
|
26
|
+
|
|
27
|
+
return { submit, isSubmitted };
|
|
28
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { useCallback } from "react";
|
|
2
|
+
import { useAui, useAuiState } from "@assistant-ui/store";
|
|
3
|
+
|
|
4
|
+
export const useActionBarReload = () => {
|
|
5
|
+
const aui = useAui();
|
|
6
|
+
const disabled = useAuiState(
|
|
7
|
+
(s) =>
|
|
8
|
+
s.thread.isRunning ||
|
|
9
|
+
s.thread.isDisabled ||
|
|
10
|
+
s.message.role !== "assistant",
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
const reload = useCallback(() => {
|
|
14
|
+
aui.message().reload();
|
|
15
|
+
}, [aui]);
|
|
16
|
+
|
|
17
|
+
return { reload, disabled };
|
|
18
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { useCallback } from "react";
|
|
2
|
+
import { useAui, useAuiState } from "@assistant-ui/store";
|
|
3
|
+
import type { CreateAttachment } from "../../types/attachment";
|
|
4
|
+
|
|
5
|
+
export const useComposerAddAttachment = () => {
|
|
6
|
+
const aui = useAui();
|
|
7
|
+
const disabled = useAuiState((s) => !s.composer.isEditing);
|
|
8
|
+
|
|
9
|
+
const addAttachment = useCallback(
|
|
10
|
+
(file: File | CreateAttachment) => {
|
|
11
|
+
return aui.composer().addAttachment(file);
|
|
12
|
+
},
|
|
13
|
+
[aui],
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
return { addAttachment, disabled };
|
|
17
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { useCallback } from "react";
|
|
2
|
+
import { useAui, useAuiState } from "@assistant-ui/store";
|
|
3
|
+
|
|
4
|
+
export const useComposerCancel = () => {
|
|
5
|
+
const aui = useAui();
|
|
6
|
+
const disabled = useAuiState((s) => !s.composer.canCancel);
|
|
7
|
+
|
|
8
|
+
const cancel = useCallback(() => {
|
|
9
|
+
aui.composer().cancel();
|
|
10
|
+
}, [aui]);
|
|
11
|
+
|
|
12
|
+
return { cancel, disabled };
|
|
13
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { useCallback } from "react";
|
|
2
|
+
import { useAui, useAuiState } from "@assistant-ui/store";
|
|
3
|
+
|
|
4
|
+
export const useComposerSend = () => {
|
|
5
|
+
const aui = useAui();
|
|
6
|
+
const disabled = useAuiState(
|
|
7
|
+
(s) => s.thread.isRunning || !s.composer.isEditing || s.composer.isEmpty,
|
|
8
|
+
);
|
|
9
|
+
|
|
10
|
+
const send = useCallback(() => {
|
|
11
|
+
aui.composer().send();
|
|
12
|
+
}, [aui]);
|
|
13
|
+
|
|
14
|
+
return { send, disabled };
|
|
15
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { useCallback } from "react";
|
|
2
|
+
import { useAui } from "@assistant-ui/store";
|
|
3
|
+
|
|
4
|
+
export const useEditComposerCancel = () => {
|
|
5
|
+
const aui = useAui();
|
|
6
|
+
|
|
7
|
+
const cancel = useCallback(() => {
|
|
8
|
+
aui.composer().cancel();
|
|
9
|
+
}, [aui]);
|
|
10
|
+
|
|
11
|
+
return { cancel };
|
|
12
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { useCallback } from "react";
|
|
2
|
+
import { useAui, useAuiState } from "@assistant-ui/store";
|
|
3
|
+
|
|
4
|
+
export const useEditComposerSend = () => {
|
|
5
|
+
const aui = useAui();
|
|
6
|
+
const disabled = useAuiState((s) => s.composer.isEmpty);
|
|
7
|
+
|
|
8
|
+
const send = useCallback(() => {
|
|
9
|
+
aui.composer().send();
|
|
10
|
+
}, [aui]);
|
|
11
|
+
|
|
12
|
+
return { send, disabled };
|
|
13
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { useCallback } from "react";
|
|
2
|
+
import { useAui, useAuiState } from "@assistant-ui/store";
|
|
3
|
+
|
|
4
|
+
export const useMessageBranching = () => {
|
|
5
|
+
const aui = useAui();
|
|
6
|
+
const branchNumber = useAuiState((s) => s.message.branchNumber);
|
|
7
|
+
const branchCount = useAuiState((s) => s.message.branchCount);
|
|
8
|
+
|
|
9
|
+
const goToPrev = useCallback(() => {
|
|
10
|
+
aui.message().switchToBranch({ position: "previous" });
|
|
11
|
+
}, [aui]);
|
|
12
|
+
|
|
13
|
+
const goToNext = useCallback(() => {
|
|
14
|
+
aui.message().switchToBranch({ position: "next" });
|
|
15
|
+
}, [aui]);
|
|
16
|
+
|
|
17
|
+
return { branchNumber, branchCount, goToPrev, goToNext };
|
|
18
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { useCallback } from "react";
|
|
2
|
+
import { useAui, useAuiState } from "@assistant-ui/store";
|
|
3
|
+
|
|
4
|
+
export const useMessageReload = () => {
|
|
5
|
+
const aui = useAui();
|
|
6
|
+
const canReload = useAuiState((s) => s.message.role === "assistant");
|
|
7
|
+
|
|
8
|
+
const reload = useCallback(() => {
|
|
9
|
+
aui.message().reload();
|
|
10
|
+
}, [aui]);
|
|
11
|
+
|
|
12
|
+
return { reload, canReload };
|
|
13
|
+
};
|