@assistant-ui/core 0.2.9 → 0.2.10
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/tool.d.ts +1 -1
- package/dist/model-context/tool.js +1 -1
- package/dist/model-context/tool.js.map +1 -1
- package/dist/model-context/types.js +17 -2
- package/dist/model-context/types.js.map +1 -1
- package/dist/react/adapters/LocalStorageThreadListAdapter.d.ts.map +1 -1
- package/dist/react/adapters/LocalStorageThreadListAdapter.js +12 -2
- package/dist/react/adapters/LocalStorageThreadListAdapter.js.map +1 -1
- package/dist/react/client/Tools.d.ts.map +1 -1
- package/dist/react/client/Tools.js +9 -3
- package/dist/react/client/Tools.js.map +1 -1
- package/dist/react/index.d.ts +7 -3
- package/dist/react/index.js +6 -2
- package/dist/react/model-context/define-mcp-toolkit.d.ts +12 -0
- package/dist/react/model-context/define-mcp-toolkit.d.ts.map +1 -0
- package/dist/react/model-context/define-mcp-toolkit.js +14 -0
- package/dist/react/model-context/define-mcp-toolkit.js.map +1 -0
- package/dist/react/model-context/define-toolkit.d.ts +4 -3
- package/dist/react/model-context/define-toolkit.d.ts.map +1 -1
- package/dist/react/model-context/define-toolkit.js +1 -14
- package/dist/react/model-context/define-toolkit.js.map +1 -1
- package/dist/react/model-context/hitl.d.ts +8 -4
- package/dist/react/model-context/hitl.d.ts.map +1 -1
- package/dist/react/model-context/hitl.js +9 -5
- package/dist/react/model-context/hitl.js.map +1 -1
- package/dist/react/model-context/makeAssistantTool.d.ts +8 -0
- package/dist/react/model-context/makeAssistantTool.d.ts.map +1 -1
- package/dist/react/model-context/makeAssistantTool.js +4 -0
- package/dist/react/model-context/makeAssistantTool.js.map +1 -1
- package/dist/react/model-context/makeAssistantToolUI.d.ts +8 -0
- package/dist/react/model-context/makeAssistantToolUI.d.ts.map +1 -1
- package/dist/react/model-context/makeAssistantToolUI.js +4 -0
- package/dist/react/model-context/makeAssistantToolUI.js.map +1 -1
- package/dist/react/model-context/provider-tool.d.ts +15 -0
- package/dist/react/model-context/provider-tool.d.ts.map +1 -0
- package/dist/react/model-context/provider-tool.js +12 -0
- package/dist/react/model-context/provider-tool.js.map +1 -0
- package/dist/react/model-context/stub-tool.d.ts +12 -0
- package/dist/react/model-context/stub-tool.d.ts.map +1 -0
- package/dist/react/model-context/stub-tool.js +15 -0
- package/dist/react/model-context/stub-tool.js.map +1 -0
- package/dist/react/model-context/toolbox.d.ts +62 -15
- package/dist/react/model-context/toolbox.d.ts.map +1 -1
- package/dist/react/model-context/toolbox.js +19 -1
- package/dist/react/model-context/toolbox.js.map +1 -1
- package/dist/react/model-context/useAssistantTool.d.ts +11 -1
- package/dist/react/model-context/useAssistantTool.d.ts.map +1 -1
- package/dist/react/model-context/useAssistantTool.js +12 -6
- package/dist/react/model-context/useAssistantTool.js.map +1 -1
- package/dist/react/model-context/useAssistantToolUI.d.ts +13 -4
- package/dist/react/model-context/useAssistantToolUI.d.ts.map +1 -1
- package/dist/react/model-context/useAssistantToolUI.js +6 -3
- package/dist/react/model-context/useAssistantToolUI.js.map +1 -1
- package/dist/react/model-context/useAuiToolOverrides.d.ts +22 -0
- package/dist/react/model-context/useAuiToolOverrides.d.ts.map +1 -0
- package/dist/react/model-context/useAuiToolOverrides.js +31 -0
- package/dist/react/model-context/useAuiToolOverrides.js.map +1 -0
- package/dist/react/primitives/part/PartMessages.d.ts +13 -11
- package/dist/react/primitives/part/PartMessages.d.ts.map +1 -1
- package/dist/react/primitives/part/PartMessages.js +13 -11
- package/dist/react/primitives/part/PartMessages.js.map +1 -1
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts +1 -0
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js +28 -0
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js.map +1 -1
- package/dist/react/runtimes/cloud/useCloudThreadListAdapter.d.ts.map +1 -1
- package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js +9 -2
- package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js.map +1 -1
- package/dist/runtime/api/thread-list-item-runtime.d.ts +2 -0
- package/dist/runtime/api/thread-list-item-runtime.d.ts.map +1 -1
- package/dist/runtime/api/thread-list-item-runtime.js +6 -0
- package/dist/runtime/api/thread-list-item-runtime.js.map +1 -1
- package/dist/runtime/interfaces/thread-list-runtime-core.d.ts +1 -0
- package/dist/runtime/interfaces/thread-list-runtime-core.d.ts.map +1 -1
- package/dist/runtimes/external-store/external-store-adapter.d.ts +2 -0
- package/dist/runtimes/external-store/external-store-adapter.d.ts.map +1 -1
- package/dist/runtimes/external-store/external-store-thread-list-runtime-core.d.ts +1 -0
- package/dist/runtimes/external-store/external-store-thread-list-runtime-core.d.ts.map +1 -1
- package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js +5 -0
- package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js.map +1 -1
- package/dist/runtimes/remote-thread-list/adapter/in-memory.d.ts +1 -0
- package/dist/runtimes/remote-thread-list/adapter/in-memory.d.ts.map +1 -1
- package/dist/runtimes/remote-thread-list/adapter/in-memory.js +3 -0
- package/dist/runtimes/remote-thread-list/adapter/in-memory.js.map +1 -1
- package/dist/runtimes/remote-thread-list/types.d.ts +1 -0
- package/dist/runtimes/remote-thread-list/types.d.ts.map +1 -1
- package/dist/store/runtime-clients/thread-list-item-runtime-client.js +1 -0
- package/dist/store/runtime-clients/thread-list-item-runtime-client.js.map +1 -1
- package/dist/store/scopes/thread-list-item.d.ts +1 -0
- package/dist/store/scopes/thread-list-item.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/model-context/tool.ts +1 -1
- package/src/model-context/types.ts +21 -3
- package/src/react/adapters/LocalStorageThreadListAdapter.tsx +15 -2
- package/src/react/client/Tools.ts +22 -7
- package/src/react/index.ts +14 -3
- package/src/react/model-context/define-mcp-toolkit.ts +16 -0
- package/src/react/model-context/define-toolkit.test.ts +92 -4
- package/src/react/model-context/define-toolkit.ts +21 -3
- package/src/react/model-context/hitl.ts +10 -5
- package/src/react/model-context/makeAssistantTool.ts +8 -0
- package/src/react/model-context/makeAssistantToolUI.ts +8 -0
- package/src/react/model-context/provider-tool.ts +30 -0
- package/src/react/model-context/stub-tool.ts +14 -0
- package/src/react/model-context/toolbox.test.ts +182 -0
- package/src/react/model-context/toolbox.ts +189 -21
- package/src/react/model-context/useAssistantTool.ts +28 -8
- package/src/react/model-context/useAssistantToolUI.ts +13 -4
- package/src/react/model-context/useAuiToolOverrides.ts +38 -0
- package/src/react/primitives/part/PartMessages.tsx +13 -11
- package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.tsx +43 -0
- package/src/react/runtimes/cloud/useCloudThreadListAdapter.tsx +9 -0
- package/src/runtime/api/thread-list-item-runtime.ts +15 -0
- package/src/runtime/interfaces/thread-list-runtime-core.ts +4 -0
- package/src/runtimes/external-store/external-store-adapter.ts +7 -0
- package/src/runtimes/external-store/external-store-thread-list-runtime-core.ts +13 -0
- package/src/runtimes/remote-thread-list/adapter/in-memory.ts +4 -0
- package/src/runtimes/remote-thread-list/types.ts +4 -0
- package/src/store/clients/model-context-client.test.ts +87 -2
- package/src/store/runtime-clients/thread-list-item-runtime-client.ts +1 -0
- package/src/store/scopes/thread-list-item.ts +1 -0
- package/src/tests/RemoteThreadListThreadListRuntimeCore-custom-metadata.test.ts +69 -1
- package/src/tests/thread-list-runtime-getLoadThreadsPromise.test.ts +1 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"thread-list-item-runtime-client.js","names":[],"sources":["../../../src/store/runtime-clients/thread-list-item-runtime-client.ts"],"sourcesContent":["import type { Unsubscribe } from \"../../types/unsubscribe\";\nimport { resource, tapEffect } from \"@assistant-ui/tap\";\nimport { type ClientOutput, tapAssistantEmit } from \"@assistant-ui/store\";\nimport type {\n ThreadListItemEventType,\n ThreadListItemRuntime,\n} from \"../../runtime/api/thread-list-item-runtime\";\nimport { tapSubscribable } from \"./tap-subscribable\";\n\nexport const ThreadListItemClient = resource(\n ({\n runtime,\n }: {\n runtime: ThreadListItemRuntime;\n }): ClientOutput<\"threadListItem\"> => {\n const state = tapSubscribable(runtime);\n const emit = tapAssistantEmit();\n\n // Bind thread list item events to event manager\n tapEffect(() => {\n const unsubscribers: Unsubscribe[] = [];\n\n // Subscribe to thread list item events\n const threadListItemEvents: ThreadListItemEventType[] = [\n \"switchedTo\",\n \"switchedAway\",\n ];\n\n for (const event of threadListItemEvents) {\n const unsubscribe = runtime.unstable_on(event, () => {\n emit(`threadListItem.${event}`, {\n threadId: runtime.getState()!.id,\n });\n });\n unsubscribers.push(unsubscribe);\n }\n\n return () => {\n for (const unsub of unsubscribers) unsub();\n };\n }, [runtime, emit]);\n\n return {\n getState: () => state,\n switchTo: runtime.switchTo,\n rename: runtime.rename,\n archive: runtime.archive,\n unarchive: runtime.unarchive,\n delete: runtime.delete,\n generateTitle: runtime.generateTitle,\n initialize: runtime.initialize,\n detach: runtime.detach,\n __internal_getRuntime: () => runtime,\n };\n },\n);\n"],"mappings":";;;;AASA,MAAa,uBAAuB,UACjC,EACC,cAGoC;CACpC,MAAM,QAAQ,gBAAgB,OAAO;CACrC,MAAM,OAAO,iBAAiB;CAG9B,gBAAgB;EACd,MAAM,gBAA+B,CAAC;EAQtC,KAAK,MAAM,SAAS,CAJlB,cACA,cAGqC,GAAG;GACxC,MAAM,cAAc,QAAQ,YAAY,aAAa;IACnD,KAAK,kBAAkB,SAAS,EAC9B,UAAU,QAAQ,SAAS,EAAG,GAChC,CAAC;GACH,CAAC;GACD,cAAc,KAAK,WAAW;EAChC;EAEA,aAAa;GACX,KAAK,MAAM,SAAS,eAAe,MAAM;EAC3C;CACF,GAAG,CAAC,SAAS,IAAI,CAAC;CAElB,OAAO;EACL,gBAAgB;EAChB,UAAU,QAAQ;EAClB,QAAQ,QAAQ;EAChB,SAAS,QAAQ;EACjB,WAAW,QAAQ;EACnB,QAAQ,QAAQ;EAChB,eAAe,QAAQ;EACvB,YAAY,QAAQ;EACpB,QAAQ,QAAQ;EAChB,6BAA6B;CAC/B;AACF,CACF"}
|
|
1
|
+
{"version":3,"file":"thread-list-item-runtime-client.js","names":[],"sources":["../../../src/store/runtime-clients/thread-list-item-runtime-client.ts"],"sourcesContent":["import type { Unsubscribe } from \"../../types/unsubscribe\";\nimport { resource, tapEffect } from \"@assistant-ui/tap\";\nimport { type ClientOutput, tapAssistantEmit } from \"@assistant-ui/store\";\nimport type {\n ThreadListItemEventType,\n ThreadListItemRuntime,\n} from \"../../runtime/api/thread-list-item-runtime\";\nimport { tapSubscribable } from \"./tap-subscribable\";\n\nexport const ThreadListItemClient = resource(\n ({\n runtime,\n }: {\n runtime: ThreadListItemRuntime;\n }): ClientOutput<\"threadListItem\"> => {\n const state = tapSubscribable(runtime);\n const emit = tapAssistantEmit();\n\n // Bind thread list item events to event manager\n tapEffect(() => {\n const unsubscribers: Unsubscribe[] = [];\n\n // Subscribe to thread list item events\n const threadListItemEvents: ThreadListItemEventType[] = [\n \"switchedTo\",\n \"switchedAway\",\n ];\n\n for (const event of threadListItemEvents) {\n const unsubscribe = runtime.unstable_on(event, () => {\n emit(`threadListItem.${event}`, {\n threadId: runtime.getState()!.id,\n });\n });\n unsubscribers.push(unsubscribe);\n }\n\n return () => {\n for (const unsub of unsubscribers) unsub();\n };\n }, [runtime, emit]);\n\n return {\n getState: () => state,\n switchTo: runtime.switchTo,\n rename: runtime.rename,\n updateCustom: runtime.updateCustom,\n archive: runtime.archive,\n unarchive: runtime.unarchive,\n delete: runtime.delete,\n generateTitle: runtime.generateTitle,\n initialize: runtime.initialize,\n detach: runtime.detach,\n __internal_getRuntime: () => runtime,\n };\n },\n);\n"],"mappings":";;;;AASA,MAAa,uBAAuB,UACjC,EACC,cAGoC;CACpC,MAAM,QAAQ,gBAAgB,OAAO;CACrC,MAAM,OAAO,iBAAiB;CAG9B,gBAAgB;EACd,MAAM,gBAA+B,CAAC;EAQtC,KAAK,MAAM,SAAS,CAJlB,cACA,cAGqC,GAAG;GACxC,MAAM,cAAc,QAAQ,YAAY,aAAa;IACnD,KAAK,kBAAkB,SAAS,EAC9B,UAAU,QAAQ,SAAS,EAAG,GAChC,CAAC;GACH,CAAC;GACD,cAAc,KAAK,WAAW;EAChC;EAEA,aAAa;GACX,KAAK,MAAM,SAAS,eAAe,MAAM;EAC3C;CACF,GAAG,CAAC,SAAS,IAAI,CAAC;CAElB,OAAO;EACL,gBAAgB;EAChB,UAAU,QAAQ;EAClB,QAAQ,QAAQ;EAChB,cAAc,QAAQ;EACtB,SAAS,QAAQ;EACjB,WAAW,QAAQ;EACnB,QAAQ,QAAQ;EAChB,eAAe,QAAQ;EACvB,YAAY,QAAQ;EACpB,QAAQ,QAAQ;EAChB,6BAA6B;CAC/B;AACF,CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"thread-list-item.d.ts","names":[],"sources":["../../../src/store/scopes/thread-list-item.ts"],"mappings":";;;;KAGY,mBAAA;EAAA,SACD,EAAA;EAAA,SACA,QAAA;EAAA,SACA,UAAA;EAAA,SACA,KAAA;EAAA,SACA,MAAA,EAAQ,oBAAA;EAAA,SACR,MAAA,GAAS,MAAM;AAAA;AAAA,KAGd,qBAAA;EACV,QAAA,IAAY,mBAAA;EACZ,QAAA,CAAS,OAAA;IAAY,SAAA;EAAA;EACrB,MAAA,CAAO,QAAA;EACP,OAAA;EACA,SAAA;EACA,MAAA;EACA,aAAA;EACA,UAAA,IAAc,OAAA;IAAU,QAAA;IAAkB,UAAA;EAAA;EAC1C,MAAA;EACA,qBAAA,KAA0B,qBAAA;AAAA;AAAA,KAGhB,kBAAA;EACV,MAAA;EACA,KAAA;IACM,IAAA;EAAA;IACA,IAAA;IAAY,EAAA;EAAA;IACZ,IAAA;IAAe,KAAA;IAAe,QAAA;EAAA;AAAA;AAAA,KAG1B,oBAAA;
|
|
1
|
+
{"version":3,"file":"thread-list-item.d.ts","names":[],"sources":["../../../src/store/scopes/thread-list-item.ts"],"mappings":";;;;KAGY,mBAAA;EAAA,SACD,EAAA;EAAA,SACA,QAAA;EAAA,SACA,UAAA;EAAA,SACA,KAAA;EAAA,SACA,MAAA,EAAQ,oBAAA;EAAA,SACR,MAAA,GAAS,MAAM;AAAA;AAAA,KAGd,qBAAA;EACV,QAAA,IAAY,mBAAA;EACZ,QAAA,CAAS,OAAA;IAAY,SAAA;EAAA;EACrB,MAAA,CAAO,QAAA;EACP,YAAA,CAAa,MAAA,EAAQ,MAAA;EACrB,OAAA;EACA,SAAA;EACA,MAAA;EACA,aAAA;EACA,UAAA,IAAc,OAAA;IAAU,QAAA;IAAkB,UAAA;EAAA;EAC1C,MAAA;EACA,qBAAA,KAA0B,qBAAA;AAAA;AAAA,KAGhB,kBAAA;EACV,MAAA;EACA,KAAA;IACM,IAAA;EAAA;IACA,IAAA;IAAY,EAAA;EAAA;IACZ,IAAA;IAAe,KAAA;IAAe,QAAA;EAAA;AAAA;AAAA,KAG1B,oBAAA;EAbI;;;;;EAmBd,2BAAA;IAA+B,QAAA;EAAA;EAdrB;;;;;EAoBV,6BAAA;IAAiC,QAAA;EAAA;AAAA;AAAA,KAGvB,0BAAA;EACV,OAAA,EAAS,qBAAA;EACT,IAAA,EAAM,kBAAA;EACN,MAAA,EAAQ,oBAAA;AAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@assistant-ui/core",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.10",
|
|
4
4
|
"description": "Framework-agnostic core runtime for assistant-ui",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"assistant",
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
],
|
|
60
60
|
"sideEffects": false,
|
|
61
61
|
"dependencies": {
|
|
62
|
-
"assistant-stream": "^0.3.
|
|
62
|
+
"assistant-stream": "^0.3.20",
|
|
63
63
|
"nanoid": "^5.1.11"
|
|
64
64
|
},
|
|
65
65
|
"peerDependencies": {
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
"@assistant-ui/tap": "^0.5.14",
|
|
68
68
|
"@types/react": "*",
|
|
69
69
|
"react": "^18 || ^19",
|
|
70
|
-
"assistant-cloud": "^0.1.
|
|
70
|
+
"assistant-cloud": "^0.1.31",
|
|
71
71
|
"zustand": "^5.0.11"
|
|
72
72
|
},
|
|
73
73
|
"peerDependenciesMeta": {
|
|
@@ -91,8 +91,8 @@
|
|
|
91
91
|
"zustand": "^5.0.14",
|
|
92
92
|
"@assistant-ui/store": "0.2.13",
|
|
93
93
|
"@assistant-ui/tap": "0.5.14",
|
|
94
|
-
"@assistant-ui/x-buildutils": "0.0.
|
|
95
|
-
"assistant-cloud": "0.1.
|
|
94
|
+
"@assistant-ui/x-buildutils": "0.0.11",
|
|
95
|
+
"assistant-cloud": "0.1.31"
|
|
96
96
|
},
|
|
97
97
|
"publishConfig": {
|
|
98
98
|
"access": "public",
|
|
@@ -7,7 +7,7 @@ import type { Tool } from "assistant-stream";
|
|
|
7
7
|
* optional model-output conversion.
|
|
8
8
|
*
|
|
9
9
|
* This helper keeps reusable tool definitions type-checked and convenient to
|
|
10
|
-
* export for a {@link Toolkit}
|
|
10
|
+
* export for a {@link Toolkit} registered with {@link Tools}.
|
|
11
11
|
* Inference from parameter schemas is currently limited, so provide generic
|
|
12
12
|
* arguments when you need precise args or result types.
|
|
13
13
|
*
|
|
@@ -55,7 +55,10 @@ export const mergeModelContexts = (
|
|
|
55
55
|
.map((c) => c.getModelContext())
|
|
56
56
|
.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
|
|
57
57
|
|
|
58
|
+
const toolPriorities: Record<string, number> = {};
|
|
59
|
+
|
|
58
60
|
return configs.reduce((acc, config) => {
|
|
61
|
+
const priority = config.priority ?? 0;
|
|
59
62
|
if (config.system) {
|
|
60
63
|
if (acc.system) {
|
|
61
64
|
acc.system += `\n\n${config.system}`;
|
|
@@ -67,13 +70,28 @@ export const mergeModelContexts = (
|
|
|
67
70
|
for (const [name, tool] of Object.entries(config.tools)) {
|
|
68
71
|
const existing = acc.tools?.[name];
|
|
69
72
|
if (existing && existing !== tool) {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
+
const existingPriority = toolPriorities[name]!;
|
|
74
|
+
if (existingPriority === priority) {
|
|
75
|
+
throw new Error(
|
|
76
|
+
`You tried to define a tool with the name ${name}, but it already exists.`,
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const higherPriorityTool =
|
|
81
|
+
existingPriority > priority ? existing : tool;
|
|
82
|
+
const lowerPriorityTool =
|
|
83
|
+
existingPriority > priority ? tool : existing;
|
|
84
|
+
acc.tools![name] = {
|
|
85
|
+
...lowerPriorityTool,
|
|
86
|
+
...higherPriorityTool,
|
|
87
|
+
} as Tool<any, any>;
|
|
88
|
+
toolPriorities[name] = Math.max(existingPriority, priority);
|
|
89
|
+
continue;
|
|
73
90
|
}
|
|
74
91
|
|
|
75
92
|
if (!acc.tools) acc.tools = {};
|
|
76
93
|
acc.tools[name] = tool;
|
|
94
|
+
toolPriorities[name] ??= priority;
|
|
77
95
|
}
|
|
78
96
|
}
|
|
79
97
|
if (config.config) {
|
|
@@ -28,13 +28,12 @@ type LocalStorageAdapterOptions = {
|
|
|
28
28
|
titleGenerator?: TitleGenerationAdapter | undefined;
|
|
29
29
|
};
|
|
30
30
|
|
|
31
|
-
// `RemoteThreadMetadata.custom` is intentionally not persisted; consumers that
|
|
32
|
-
// need it across reloads should fork this adapter or use a remote backend.
|
|
33
31
|
type StoredThreadMetadata = {
|
|
34
32
|
remoteId: string;
|
|
35
33
|
externalId?: string;
|
|
36
34
|
status: "regular" | "archived";
|
|
37
35
|
title?: string;
|
|
36
|
+
custom?: Record<string, unknown> | undefined;
|
|
38
37
|
};
|
|
39
38
|
|
|
40
39
|
class AsyncStorageHistoryAdapter implements ThreadHistoryAdapter {
|
|
@@ -131,6 +130,7 @@ export const createLocalStorageAdapter = (
|
|
|
131
130
|
externalId: t.externalId,
|
|
132
131
|
status: t.status,
|
|
133
132
|
title: t.title,
|
|
133
|
+
custom: t.custom,
|
|
134
134
|
})),
|
|
135
135
|
};
|
|
136
136
|
},
|
|
@@ -162,6 +162,18 @@ export const createLocalStorageAdapter = (
|
|
|
162
162
|
}
|
|
163
163
|
},
|
|
164
164
|
|
|
165
|
+
async updateCustom(
|
|
166
|
+
remoteId: string,
|
|
167
|
+
custom: Record<string, unknown> | undefined,
|
|
168
|
+
): Promise<void> {
|
|
169
|
+
const threads = await loadThreadMetadata();
|
|
170
|
+
const thread = threads.find((t) => t.remoteId === remoteId);
|
|
171
|
+
if (thread) {
|
|
172
|
+
thread.custom = custom;
|
|
173
|
+
await saveThreadMetadata(threads);
|
|
174
|
+
}
|
|
175
|
+
},
|
|
176
|
+
|
|
165
177
|
async archive(remoteId: string): Promise<void> {
|
|
166
178
|
const threads = await loadThreadMetadata();
|
|
167
179
|
const thread = threads.find((t) => t.remoteId === remoteId);
|
|
@@ -196,6 +208,7 @@ export const createLocalStorageAdapter = (
|
|
|
196
208
|
externalId: thread.externalId,
|
|
197
209
|
status: thread.status,
|
|
198
210
|
title: thread.title,
|
|
211
|
+
custom: thread.custom,
|
|
199
212
|
};
|
|
200
213
|
},
|
|
201
214
|
|
|
@@ -17,6 +17,7 @@ import type { McpAppResourceOutput, ToolsState } from "../types/scopes/tools";
|
|
|
17
17
|
import type { Tool } from "assistant-stream";
|
|
18
18
|
import {
|
|
19
19
|
isStandaloneToolDisplay,
|
|
20
|
+
makeToolCallTextComponent,
|
|
20
21
|
type Toolkit,
|
|
21
22
|
} from "../model-context/toolbox";
|
|
22
23
|
import type { ToolCallMessagePartComponent } from "../types/MessagePartComponentTypes";
|
|
@@ -106,22 +107,36 @@ export const Tools = resource(
|
|
|
106
107
|
|
|
107
108
|
// Register tool UIs (exclude symbols)
|
|
108
109
|
for (const [toolName, tool] of Object.entries(toolkit)) {
|
|
109
|
-
|
|
110
|
+
const toolRender = "render" in tool ? tool.render : undefined;
|
|
111
|
+
const toolRenderText =
|
|
112
|
+
"renderText" in tool ? tool.renderText : undefined;
|
|
113
|
+
const render =
|
|
114
|
+
toolRender ??
|
|
115
|
+
(toolRenderText
|
|
116
|
+
? makeToolCallTextComponent(toolRenderText)
|
|
117
|
+
: undefined);
|
|
118
|
+
if (render) {
|
|
110
119
|
unsubscribes.push(
|
|
111
|
-
setToolUI(toolName,
|
|
120
|
+
setToolUI(toolName, render, {
|
|
112
121
|
standalone: isStandaloneToolDisplay(tool),
|
|
113
122
|
}),
|
|
114
123
|
);
|
|
115
124
|
}
|
|
116
125
|
}
|
|
117
126
|
|
|
118
|
-
// Register tools with model context (exclude symbols). `render
|
|
119
|
-
// `display` are client-only presentation concerns and
|
|
120
|
-
// model.
|
|
127
|
+
// Register tools with model context (exclude symbols). `render`,
|
|
128
|
+
// `renderText`, and `display` are client-only presentation concerns and
|
|
129
|
+
// never reach the model.
|
|
121
130
|
const toolsWithoutRender = Object.entries(toolkit).reduce(
|
|
122
131
|
(acc, [name, tool]) => {
|
|
123
|
-
|
|
124
|
-
|
|
132
|
+
if (tool.type === "mcp") return acc;
|
|
133
|
+
const {
|
|
134
|
+
display: _display,
|
|
135
|
+
render: _render,
|
|
136
|
+
renderText: _renderText,
|
|
137
|
+
...rest
|
|
138
|
+
} = tool as typeof tool & { renderText?: unknown };
|
|
139
|
+
acc[name] = rest as Tool<any, any>;
|
|
125
140
|
return acc;
|
|
126
141
|
},
|
|
127
142
|
{} as Record<string, Tool<any, any>>,
|
package/src/react/index.ts
CHANGED
|
@@ -35,11 +35,22 @@ export { useInlineRender } from "./model-context/useInlineRender";
|
|
|
35
35
|
export {
|
|
36
36
|
type Toolkit,
|
|
37
37
|
type ToolDefinition,
|
|
38
|
-
type
|
|
39
|
-
type
|
|
38
|
+
type ToolkitDefinition,
|
|
39
|
+
type ToolkitDefinitionEntry,
|
|
40
|
+
type ToolCallText,
|
|
40
41
|
} from "./model-context/toolbox";
|
|
41
42
|
export { defineToolkit } from "./model-context/define-toolkit";
|
|
42
|
-
export {
|
|
43
|
+
export { stubTool } from "./model-context/stub-tool";
|
|
44
|
+
export { useAuiToolOverrides } from "./model-context/useAuiToolOverrides";
|
|
45
|
+
export { hitl, hitlTool } from "./model-context/hitl";
|
|
46
|
+
export {
|
|
47
|
+
providerTool,
|
|
48
|
+
type ProviderToolConfig,
|
|
49
|
+
} from "./model-context/provider-tool";
|
|
50
|
+
export {
|
|
51
|
+
defineMcpToolkit,
|
|
52
|
+
type McpToolkitDefinition,
|
|
53
|
+
} from "./model-context/define-mcp-toolkit";
|
|
43
54
|
export {
|
|
44
55
|
useAssistantInteractable,
|
|
45
56
|
type AssistantInteractableProps,
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { McpServerConfig } from "assistant-stream";
|
|
2
|
+
import type { Toolkit } from "./toolbox";
|
|
3
|
+
|
|
4
|
+
export type McpToolkitDefinition = Record<string, McpServerConfig>;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Defines MCP server tools as a spreadable toolkit fragment.
|
|
8
|
+
*/
|
|
9
|
+
export function defineMcpToolkit(definition: McpToolkitDefinition): Toolkit {
|
|
10
|
+
return Object.fromEntries(
|
|
11
|
+
Object.entries(definition).map(([name, server]) => [
|
|
12
|
+
name,
|
|
13
|
+
{ type: "mcp", server },
|
|
14
|
+
]),
|
|
15
|
+
) as Toolkit;
|
|
16
|
+
}
|
|
@@ -1,13 +1,101 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
1
|
+
import { describe, it, expect, expectTypeOf } from "vitest";
|
|
2
|
+
import type { AsyncIterableStream } from "assistant-stream/utils";
|
|
2
3
|
import { defineToolkit } from "./define-toolkit";
|
|
3
|
-
import { hitl } from "./hitl";
|
|
4
|
+
import { hitl, hitlTool } from "./hitl";
|
|
5
|
+
import { providerTool } from "./provider-tool";
|
|
6
|
+
import { stubTool } from "./stub-tool";
|
|
7
|
+
import type { ToolkitDefinition } from "./toolbox";
|
|
8
|
+
|
|
9
|
+
type TestStandardSchema<T> = {
|
|
10
|
+
readonly "~standard": {
|
|
11
|
+
readonly version: 1;
|
|
12
|
+
readonly vendor: "test";
|
|
13
|
+
readonly types?: {
|
|
14
|
+
readonly input: T;
|
|
15
|
+
readonly output: T;
|
|
16
|
+
};
|
|
17
|
+
readonly validate: (value: unknown) => { readonly value: T };
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const checkDefineToolkitTypes = () => {
|
|
22
|
+
defineToolkit({
|
|
23
|
+
search: {
|
|
24
|
+
parameters: {} as TestStandardSchema<{
|
|
25
|
+
query: string;
|
|
26
|
+
limit?: number;
|
|
27
|
+
tags: string[];
|
|
28
|
+
}>,
|
|
29
|
+
execute: async ({
|
|
30
|
+
query,
|
|
31
|
+
limit,
|
|
32
|
+
}: {
|
|
33
|
+
query: string;
|
|
34
|
+
limit?: number;
|
|
35
|
+
tags: string[];
|
|
36
|
+
}) => ({
|
|
37
|
+
ids: [query],
|
|
38
|
+
count: limit ?? 0,
|
|
39
|
+
}),
|
|
40
|
+
streamCall: async (reader) => {
|
|
41
|
+
const query = await reader.args.get("query");
|
|
42
|
+
expectTypeOf(query).toEqualTypeOf<string>();
|
|
43
|
+
|
|
44
|
+
expectTypeOf(reader.args.streamValues("query")).toEqualTypeOf<
|
|
45
|
+
AsyncIterableStream<string>
|
|
46
|
+
>();
|
|
47
|
+
expectTypeOf(reader.args.streamText("query")).toEqualTypeOf<
|
|
48
|
+
AsyncIterableStream<unknown>
|
|
49
|
+
>();
|
|
50
|
+
expectTypeOf(reader.args.forEach("tags")).toEqualTypeOf<
|
|
51
|
+
AsyncIterableStream<string>
|
|
52
|
+
>();
|
|
53
|
+
|
|
54
|
+
const response = await reader.response.get();
|
|
55
|
+
expectTypeOf(response.result).toEqualTypeOf<unknown>();
|
|
56
|
+
|
|
57
|
+
// @ts-expect-error unknown argument paths should not be accepted
|
|
58
|
+
reader.args.get("missing");
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
};
|
|
63
|
+
expectTypeOf(checkDefineToolkitTypes).toEqualTypeOf<() => void>();
|
|
64
|
+
|
|
65
|
+
const checkToolkitDefinitionTypes = () => {
|
|
66
|
+
({
|
|
67
|
+
invalidMcp: {
|
|
68
|
+
// @ts-expect-error MCP-shaped tools cannot also declare an execute callback
|
|
69
|
+
server: { type: "http", url: "https://example.com/mcp" },
|
|
70
|
+
execute: async () => "invalid",
|
|
71
|
+
},
|
|
72
|
+
}) satisfies ToolkitDefinition;
|
|
73
|
+
};
|
|
74
|
+
expectTypeOf(checkToolkitDefinitionTypes).toEqualTypeOf<() => void>();
|
|
4
75
|
|
|
5
76
|
describe("use-generative markers", () => {
|
|
6
77
|
it("defineToolkit throws at runtime — it must be stripped by the compiler, never called", () => {
|
|
7
78
|
expect(() => defineToolkit({})).toThrow(/no runtime implementation/);
|
|
8
79
|
});
|
|
9
80
|
|
|
10
|
-
it("
|
|
11
|
-
expect(() =>
|
|
81
|
+
it("hitlTool throws at runtime — it must be stripped by the compiler, never called", () => {
|
|
82
|
+
expect(() => hitlTool()).toThrow(/no runtime implementation/);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it("hitl remains a compatibility alias", () => {
|
|
86
|
+
expect(hitl).toBe(hitlTool);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it("providerTool throws at runtime — it must be stripped by the compiler, never called", () => {
|
|
90
|
+
expect(() =>
|
|
91
|
+
providerTool({
|
|
92
|
+
providerId: "openai.web_search_preview",
|
|
93
|
+
args: {},
|
|
94
|
+
}),
|
|
95
|
+
).toThrow(/no runtime implementation/);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it("stubTool throws at runtime — it must be stripped by the compiler, never called", () => {
|
|
99
|
+
expect(() => stubTool()).toThrow(/no runtime implementation/);
|
|
12
100
|
});
|
|
13
101
|
});
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
Toolkit,
|
|
3
|
+
ToolkitDefinition,
|
|
4
|
+
ToolkitDefinitionEntryWithParameters,
|
|
5
|
+
} from "./toolbox";
|
|
2
6
|
|
|
3
7
|
/**
|
|
4
8
|
* Authoring helper for a `"use generative"` toolkit. Accepts the permissive
|
|
5
|
-
* {@link
|
|
9
|
+
* {@link ToolkitDefinition} (a `backend` tool may carry its server `execute`)
|
|
6
10
|
* and types the result as the canonical {@link Toolkit}.
|
|
7
11
|
*
|
|
8
12
|
* It has **no runtime implementation**. A `"use generative"` compiler (e.g.
|
|
@@ -13,7 +17,21 @@ import type { Toolkit, ToolkitDeclaration } from "./toolbox";
|
|
|
13
17
|
* outside a `"use generative"` file — which would ship a backend `execute` to the
|
|
14
18
|
* client. So it throws instead of silently leaking.
|
|
15
19
|
*/
|
|
16
|
-
export function defineToolkit
|
|
20
|
+
export function defineToolkit<
|
|
21
|
+
TArgsByName extends {
|
|
22
|
+
[K in keyof TArgsByName]: Record<string, unknown>;
|
|
23
|
+
},
|
|
24
|
+
TResultByName extends { [K in keyof TArgsByName]: unknown } = {
|
|
25
|
+
[K in keyof TArgsByName]: unknown;
|
|
26
|
+
},
|
|
27
|
+
>(_definition: {
|
|
28
|
+
[K in keyof TArgsByName]: ToolkitDefinitionEntryWithParameters<
|
|
29
|
+
TArgsByName[K],
|
|
30
|
+
TResultByName[K]
|
|
31
|
+
>;
|
|
32
|
+
}): Toolkit;
|
|
33
|
+
export function defineToolkit(_definition: ToolkitDefinition): Toolkit;
|
|
34
|
+
export function defineToolkit(_definition: ToolkitDefinition): Toolkit {
|
|
17
35
|
throw new Error(
|
|
18
36
|
"[assistant-ui] defineToolkit() has no runtime implementation — it is " +
|
|
19
37
|
"stripped at build time by the use-generative compiler. Reaching it means " +
|
|
@@ -3,20 +3,25 @@
|
|
|
3
3
|
* supplies the result instead of code. Use it as the tool's `execute`:
|
|
4
4
|
*
|
|
5
5
|
* ```tsx
|
|
6
|
-
* confirm: { execute:
|
|
6
|
+
* confirm: { execute: hitlTool(), render: (props) => <Confirm {...props} /> }
|
|
7
7
|
* ```
|
|
8
8
|
*
|
|
9
9
|
* Like {@link defineToolkit}, it has **no runtime implementation**: a
|
|
10
10
|
* `"use generative"` compiler (e.g. `@assistant-ui/next` or `@assistant-ui/vite`)
|
|
11
|
-
* detects `execute:
|
|
11
|
+
* detects `execute: hitlTool()`, drops it, and stamps the tool `type: "human"`.
|
|
12
12
|
* Reaching it at runtime means the module wasn't compiled (used outside a
|
|
13
13
|
* `"use generative"` file), so it throws.
|
|
14
14
|
*/
|
|
15
|
-
export function
|
|
15
|
+
export function hitlTool(): never {
|
|
16
16
|
throw new Error(
|
|
17
|
-
"[assistant-ui]
|
|
17
|
+
"[assistant-ui] hitlTool() has no runtime implementation — it marks a " +
|
|
18
18
|
"human-in-the-loop tool and is stripped at build time by the " +
|
|
19
19
|
"use-generative compiler. Reaching it means this module was not compiled " +
|
|
20
|
-
'(e.g.
|
|
20
|
+
'(e.g. hitlTool() used outside a "use generative" file).',
|
|
21
21
|
);
|
|
22
22
|
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @deprecated Use {@link hitlTool}.
|
|
26
|
+
*/
|
|
27
|
+
export const hitl = hitlTool;
|
|
@@ -6,6 +6,10 @@ import { type AssistantToolProps, useAssistantTool } from "./useAssistantTool";
|
|
|
6
6
|
*
|
|
7
7
|
* Rendering the component registers its tool for the lifetime of that render
|
|
8
8
|
* subtree.
|
|
9
|
+
*
|
|
10
|
+
* @deprecated Use a toolkit with `Tools({ toolkit })` and register it via
|
|
11
|
+
* `useAui({ tools: Tools({ toolkit }) })` instead. See
|
|
12
|
+
* https://assistant-ui.com/docs/migrations/toolkit-tools.
|
|
9
13
|
*/
|
|
10
14
|
export type AssistantTool = FC & {
|
|
11
15
|
/** Tool definition registered by this component. */
|
|
@@ -19,6 +23,10 @@ export type AssistantTool = FC & {
|
|
|
19
23
|
* rather than calling {@link useAssistantTool} directly.
|
|
20
24
|
*
|
|
21
25
|
* @param tool - Tool definition and name to register.
|
|
26
|
+
*
|
|
27
|
+
* @deprecated Use a toolkit with `Tools({ toolkit })` and register it via
|
|
28
|
+
* `useAui({ tools: Tools({ toolkit }) })` instead. See
|
|
29
|
+
* https://assistant-ui.com/docs/migrations/toolkit-tools.
|
|
22
30
|
*/
|
|
23
31
|
export const makeAssistantTool = <
|
|
24
32
|
TArgs extends Record<string, unknown>,
|
|
@@ -9,6 +9,10 @@ import {
|
|
|
9
9
|
*
|
|
10
10
|
* Rendering the component registers a renderer for matching tool-call message
|
|
11
11
|
* parts.
|
|
12
|
+
*
|
|
13
|
+
* @deprecated Put `render`/`renderText` on the matching toolkit entry, or use
|
|
14
|
+
* `MessagePrimitive.Parts` inline tool render overrides for per-message UI.
|
|
15
|
+
* See https://assistant-ui.com/docs/migrations/toolkit-tools.
|
|
12
16
|
*/
|
|
13
17
|
export type AssistantToolUI = FC & {
|
|
14
18
|
/** Tool renderer registered by this component. */
|
|
@@ -22,6 +26,10 @@ export type AssistantToolUI = FC & {
|
|
|
22
26
|
* are registered elsewhere.
|
|
23
27
|
*
|
|
24
28
|
* @param tool - Tool renderer registration.
|
|
29
|
+
*
|
|
30
|
+
* @deprecated Put `render`/`renderText` on the matching toolkit entry, or use
|
|
31
|
+
* `MessagePrimitive.Parts` inline tool render overrides for per-message UI.
|
|
32
|
+
* See https://assistant-ui.com/docs/migrations/toolkit-tools.
|
|
25
33
|
*/
|
|
26
34
|
export const makeAssistantToolUI = <TArgs, TResult>(
|
|
27
35
|
tool: AssistantToolUIProps<TArgs, TResult>,
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Tool } from "assistant-stream";
|
|
2
|
+
|
|
3
|
+
type ProviderToolDefinition<TArgs extends Record<string, unknown>> = Extract<
|
|
4
|
+
Tool<TArgs, unknown>,
|
|
5
|
+
{ type: "provider" }
|
|
6
|
+
>;
|
|
7
|
+
|
|
8
|
+
export type ProviderToolConfig<
|
|
9
|
+
TArgs extends Record<string, unknown> = Record<string, unknown>,
|
|
10
|
+
> = Pick<
|
|
11
|
+
ProviderToolDefinition<TArgs>,
|
|
12
|
+
| "providerId"
|
|
13
|
+
| "args"
|
|
14
|
+
| "parameters"
|
|
15
|
+
| "providerOptions"
|
|
16
|
+
| "supportsDeferredResults"
|
|
17
|
+
>;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Marks a tool as provider-executed. The use-generative compiler converts
|
|
21
|
+
* `execute: providerTool(...)` into a `type: "provider"` tool entry.
|
|
22
|
+
*/
|
|
23
|
+
export function providerTool(_config: ProviderToolConfig): never {
|
|
24
|
+
throw new Error(
|
|
25
|
+
"[assistant-ui] providerTool() has no runtime implementation — it marks a " +
|
|
26
|
+
"provider-executed tool and is stripped at build time by the " +
|
|
27
|
+
"use-generative compiler. Reaching it means this module was not compiled " +
|
|
28
|
+
'(e.g. providerTool() used outside a "use generative" file).',
|
|
29
|
+
);
|
|
30
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Marks a generative toolkit entry as a frontend tool whose executor will be
|
|
3
|
+
* supplied by `useAuiToolOverrides(...)`.
|
|
4
|
+
*
|
|
5
|
+
* `stubTool()` has no runtime implementation. It must be used inside a
|
|
6
|
+
* `"use generative"` toolkit file so the compiler can strip it.
|
|
7
|
+
*/
|
|
8
|
+
export function stubTool(): never {
|
|
9
|
+
throw new Error(
|
|
10
|
+
"[assistant-ui] stubTool() has no runtime implementation - it marks a " +
|
|
11
|
+
"tool executor that must be supplied via useAuiToolOverrides(...). Make " +
|
|
12
|
+
'sure this module is compiled as "use generative".',
|
|
13
|
+
);
|
|
14
|
+
}
|