@assistant-ui/react 0.11.35 → 0.11.36
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/client/AssistantClient.d.ts +13 -57
- package/dist/client/AssistantClient.d.ts.map +1 -1
- package/dist/client/AssistantClient.js +49 -26
- package/dist/client/AssistantClient.js.map +1 -1
- package/dist/client/ModelContext.d.ts +8 -0
- package/dist/client/ModelContext.d.ts.map +1 -0
- package/dist/client/ModelContext.js +21 -0
- package/dist/client/ModelContext.js.map +1 -0
- package/dist/client/ModelContextClient.d.ts +7 -0
- package/dist/client/ModelContextClient.d.ts.map +1 -0
- package/dist/client/ModelContextClient.js +18 -0
- package/dist/client/ModelContextClient.js.map +1 -0
- package/dist/client/ToolUIClient.d.ts.map +1 -1
- package/dist/client/ToolUIClient.js +45 -3
- package/dist/client/ToolUIClient.js.map +1 -1
- package/dist/client/ToolUIContext.d.ts +4 -0
- package/dist/client/ToolUIContext.d.ts.map +1 -0
- package/dist/client/ToolUIContext.js +20 -0
- package/dist/client/ToolUIContext.js.map +1 -0
- package/dist/client/Tools.d.ts +10 -0
- package/dist/client/Tools.d.ts.map +1 -0
- package/dist/client/Tools.js +55 -0
- package/dist/client/Tools.js.map +1 -0
- package/dist/client/types/ModelContext.d.ts +12 -0
- package/dist/client/types/ModelContext.d.ts.map +1 -0
- package/dist/client/types/ModelContext.js +1 -0
- package/dist/client/types/ModelContext.js.map +1 -0
- package/dist/client/types/ThreadList.d.ts.map +1 -1
- package/dist/client/types/ToolUI.d.ts +12 -1
- package/dist/client/types/ToolUI.d.ts.map +1 -1
- package/dist/client/types/Tools.d.ts +9 -0
- package/dist/client/types/Tools.d.ts.map +1 -0
- package/dist/client/types/Tools.js +1 -0
- package/dist/client/types/Tools.js.map +1 -0
- package/dist/context/providers/AttachmentByIndexProvider.d.ts.map +1 -1
- package/dist/context/providers/AttachmentByIndexProvider.js +20 -24
- package/dist/context/providers/AttachmentByIndexProvider.js.map +1 -1
- package/dist/context/providers/MessageByIndexProvider.d.ts.map +1 -1
- package/dist/context/providers/MessageByIndexProvider.js +27 -29
- package/dist/context/providers/MessageByIndexProvider.js.map +1 -1
- package/dist/context/providers/MessageProvider.d.ts.map +1 -1
- package/dist/context/providers/MessageProvider.js +11 -13
- package/dist/context/providers/MessageProvider.js.map +1 -1
- package/dist/context/providers/PartByIndexProvider.d.ts.map +1 -1
- package/dist/context/providers/PartByIndexProvider.js +11 -13
- package/dist/context/providers/PartByIndexProvider.js.map +1 -1
- package/dist/context/providers/TextMessagePartProvider.d.ts.map +1 -1
- package/dist/context/providers/TextMessagePartProvider.js +11 -13
- package/dist/context/providers/TextMessagePartProvider.js.map +1 -1
- package/dist/context/providers/ThreadListItemProvider.d.ts.map +1 -1
- package/dist/context/providers/ThreadListItemProvider.js +41 -45
- package/dist/context/providers/ThreadListItemProvider.js.map +1 -1
- package/dist/context/react/AssistantApiContext.d.ts +33 -4
- package/dist/context/react/AssistantApiContext.d.ts.map +1 -1
- package/dist/context/react/AssistantApiContext.js +35 -17
- 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 +5 -1
- package/dist/context/react/index.js.map +1 -1
- package/dist/legacy-runtime/AssistantRuntimeProvider.d.ts.map +1 -1
- package/dist/legacy-runtime/AssistantRuntimeProvider.js +7 -9
- package/dist/legacy-runtime/AssistantRuntimeProvider.js.map +1 -1
- package/dist/legacy-runtime/RuntimeAdapter.d.ts +7 -0
- package/dist/legacy-runtime/RuntimeAdapter.d.ts.map +1 -0
- package/dist/legacy-runtime/RuntimeAdapter.js +20 -0
- package/dist/legacy-runtime/RuntimeAdapter.js.map +1 -0
- package/dist/legacy-runtime/client/ThreadListRuntimeClient.d.ts +2 -0
- package/dist/legacy-runtime/client/ThreadListRuntimeClient.d.ts.map +1 -1
- package/dist/legacy-runtime/client/ThreadListRuntimeClient.js +6 -2
- package/dist/legacy-runtime/client/ThreadListRuntimeClient.js.map +1 -1
- package/dist/legacy-runtime/hooks/AssistantContext.d.ts +14 -1
- package/dist/legacy-runtime/hooks/AssistantContext.d.ts.map +1 -1
- package/dist/legacy-runtime/hooks/AssistantContext.js +1 -1
- package/dist/legacy-runtime/hooks/AssistantContext.js.map +1 -1
- package/dist/legacy-runtime/hooks/AttachmentContext.d.ts +6 -0
- package/dist/legacy-runtime/hooks/AttachmentContext.d.ts.map +1 -1
- package/dist/legacy-runtime/hooks/AttachmentContext.js.map +1 -1
- package/dist/legacy-runtime/hooks/ComposerContext.d.ts +41 -2
- package/dist/legacy-runtime/hooks/ComposerContext.d.ts.map +1 -1
- package/dist/legacy-runtime/hooks/ComposerContext.js.map +1 -1
- package/dist/legacy-runtime/hooks/MessageContext.d.ts +36 -2
- package/dist/legacy-runtime/hooks/MessageContext.d.ts.map +1 -1
- package/dist/legacy-runtime/hooks/MessageContext.js.map +1 -1
- package/dist/legacy-runtime/hooks/MessagePartContext.d.ts +6 -0
- package/dist/legacy-runtime/hooks/MessagePartContext.d.ts.map +1 -1
- package/dist/legacy-runtime/hooks/MessagePartContext.js.map +1 -1
- package/dist/legacy-runtime/hooks/ThreadContext.d.ts +26 -1
- package/dist/legacy-runtime/hooks/ThreadContext.d.ts.map +1 -1
- package/dist/legacy-runtime/hooks/ThreadContext.js.map +1 -1
- package/dist/legacy-runtime/hooks/ThreadListItemContext.d.ts +6 -0
- package/dist/legacy-runtime/hooks/ThreadListItemContext.d.ts.map +1 -1
- package/dist/legacy-runtime/hooks/ThreadListItemContext.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/core/AssistantRuntimeCore.d.ts +1 -0
- package/dist/legacy-runtime/runtime-cores/core/AssistantRuntimeCore.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/core/BaseAssistantRuntimeCore.d.ts +1 -0
- package/dist/legacy-runtime/runtime-cores/core/BaseAssistantRuntimeCore.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/core/BaseAssistantRuntimeCore.js +3 -0
- package/dist/legacy-runtime/runtime-cores/core/BaseAssistantRuntimeCore.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadListRuntimeCore.d.ts +4 -1
- package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadListRuntimeCore.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadListRuntimeCore.js +2 -2
- package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadListRuntimeCore.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadRuntimeCore.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadRuntimeCore.js +7 -1
- package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadRuntimeCore.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/external-store/auto-status.d.ts +2 -12
- package/dist/legacy-runtime/runtime-cores/external-store/auto-status.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/external-store/auto-status.js +45 -15
- package/dist/legacy-runtime/runtime-cores/external-store/auto-status.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/external-store/external-message-converter.d.ts +2 -0
- package/dist/legacy-runtime/runtime-cores/external-store/external-message-converter.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/external-store/external-message-converter.js +4 -2
- package/dist/legacy-runtime/runtime-cores/external-store/external-message-converter.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/local/LocalThreadListRuntimeCore.d.ts +4 -1
- package/dist/legacy-runtime/runtime-cores/local/LocalThreadListRuntimeCore.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/local/LocalThreadListRuntimeCore.js +2 -2
- package/dist/legacy-runtime/runtime-cores/local/LocalThreadListRuntimeCore.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/utils/MessageRepository.js +1 -1
- package/dist/legacy-runtime/runtime-cores/utils/MessageRepository.js.map +1 -1
- package/dist/model-context/index.d.ts +2 -0
- package/dist/model-context/index.d.ts.map +1 -1
- package/dist/model-context/index.js +6 -0
- package/dist/model-context/index.js.map +1 -1
- package/dist/model-context/makeAssistantVisible.js +1 -1
- package/dist/model-context/makeAssistantVisible.js.map +1 -1
- package/dist/model-context/toolbox.d.ts +28 -0
- package/dist/model-context/toolbox.d.ts.map +1 -0
- package/dist/model-context/toolbox.js +15 -0
- package/dist/model-context/toolbox.js.map +1 -0
- package/dist/model-context/useAssistantInstructions.js +1 -1
- package/dist/model-context/useAssistantInstructions.js.map +1 -1
- package/dist/model-context/useAssistantTool.js +1 -1
- package/dist/model-context/useAssistantTool.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 +2 -2
- package/dist/primitives/message/MessagePartsGrouped.js.map +1 -1
- package/dist/tests/setup.js +7 -7
- package/dist/tests/setup.js.map +1 -1
- package/dist/utils/tap-store/derived-scopes.d.ts +81 -0
- package/dist/utils/tap-store/derived-scopes.d.ts.map +1 -0
- package/dist/utils/tap-store/derived-scopes.js +67 -0
- package/dist/utils/tap-store/derived-scopes.js.map +1 -0
- package/dist/utils/tap-store/index.d.ts +1 -0
- package/dist/utils/tap-store/index.d.ts.map +1 -1
- package/dist/utils/tap-store/index.js +4 -0
- package/dist/utils/tap-store/index.js.map +1 -1
- package/dist/utils/tap-store/tap-api.js +1 -1
- package/dist/utils/tap-store/tap-api.js.map +1 -1
- package/package.json +9 -9
- package/src/client/AssistantClient.ts +64 -38
- package/src/client/ModelContext.ts +28 -0
- package/src/client/ModelContextClient.ts +16 -0
- package/src/client/ToolUIClient.ts +50 -3
- package/src/client/ToolUIContext.ts +22 -0
- package/src/client/Tools.ts +68 -0
- package/src/client/types/ModelContext.ts +15 -0
- package/src/client/types/ThreadList.ts +4 -0
- package/src/client/types/ToolUI.ts +10 -1
- package/src/client/types/Tools.ts +11 -0
- package/src/context/providers/AttachmentByIndexProvider.tsx +21 -25
- package/src/context/providers/MessageByIndexProvider.tsx +31 -33
- package/src/context/providers/MessageProvider.tsx +12 -14
- package/src/context/providers/PartByIndexProvider.tsx +12 -14
- package/src/context/providers/TextMessagePartProvider.tsx +12 -14
- package/src/context/providers/ThreadListItemProvider.tsx +42 -46
- package/src/context/react/AssistantApiContext.tsx +69 -29
- package/src/context/react/index.ts +5 -1
- package/src/legacy-runtime/AssistantRuntimeProvider.tsx +7 -9
- package/src/legacy-runtime/RuntimeAdapter.ts +19 -0
- package/src/legacy-runtime/client/ThreadListRuntimeClient.ts +10 -1
- package/src/legacy-runtime/hooks/AssistantContext.ts +16 -2
- package/src/legacy-runtime/hooks/AttachmentContext.ts +6 -0
- package/src/legacy-runtime/hooks/ComposerContext.ts +41 -2
- package/src/legacy-runtime/hooks/MessageContext.ts +37 -2
- package/src/legacy-runtime/hooks/MessagePartContext.ts +6 -0
- package/src/legacy-runtime/hooks/ThreadContext.ts +27 -1
- package/src/legacy-runtime/hooks/ThreadListItemContext.ts +6 -0
- package/src/legacy-runtime/runtime-cores/core/AssistantRuntimeCore.tsx +1 -0
- package/src/legacy-runtime/runtime-cores/core/BaseAssistantRuntimeCore.tsx +4 -0
- package/src/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadListRuntimeCore.tsx +4 -2
- package/src/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadRuntimeCore.tsx +7 -1
- package/src/legacy-runtime/runtime-cores/external-store/auto-status.tsx +49 -16
- package/src/legacy-runtime/runtime-cores/external-store/external-message-converter.tsx +4 -0
- package/src/legacy-runtime/runtime-cores/local/LocalThreadListRuntimeCore.tsx +4 -2
- package/src/legacy-runtime/runtime-cores/utils/MessageRepository.tsx +1 -1
- package/src/model-context/index.ts +9 -0
- package/src/model-context/makeAssistantVisible.tsx +1 -1
- package/src/model-context/toolbox.tsx +37 -0
- package/src/model-context/useAssistantInstructions.tsx +1 -1
- package/src/model-context/useAssistantTool.tsx +1 -1
- package/src/primitives/message/MessageParts.tsx +3 -2
- package/src/primitives/message/MessagePartsGrouped.tsx +3 -2
- package/src/utils/tap-store/derived-scopes.ts +185 -0
- package/src/utils/tap-store/index.ts +9 -0
- package/src/utils/tap-store/tap-api.ts +1 -1
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type { AssistantApi, AssistantApiField } from "../../context/react/AssistantApiContext";
|
|
2
|
+
import type { AssistantEvent, AssistantEventCallback, AssistantEventSelector } from "../../types/EventTypes";
|
|
3
|
+
import type { ResourceElement, Unsubscribe } from "@assistant-ui/tap";
|
|
4
|
+
/**
|
|
5
|
+
* Extract the API return type from an AssistantApiField
|
|
6
|
+
*/
|
|
7
|
+
type ExtractApiType<T> = T extends AssistantApiField<infer TApi, any> ? TApi : never;
|
|
8
|
+
/**
|
|
9
|
+
* Extract the metadata type from an AssistantApiField
|
|
10
|
+
*
|
|
11
|
+
* Used in DerivedScopesInput to validate that each field's source/query types match
|
|
12
|
+
* the expected types from AssistantApi.
|
|
13
|
+
*/
|
|
14
|
+
type ExtractMeta<T> = T extends AssistantApiField<any, infer TMeta> ? TMeta : never;
|
|
15
|
+
/**
|
|
16
|
+
* Get only the field names from AssistantApi (exclude method names)
|
|
17
|
+
*/
|
|
18
|
+
type AssistantApiFieldNames = {
|
|
19
|
+
[K in keyof AssistantApi]: AssistantApi[K] extends {
|
|
20
|
+
source: any;
|
|
21
|
+
query: any;
|
|
22
|
+
} ? K : never;
|
|
23
|
+
}[keyof AssistantApi];
|
|
24
|
+
/**
|
|
25
|
+
* Configuration for a derived scope field - infers types from the actual values provided
|
|
26
|
+
*/
|
|
27
|
+
export type DerivedScopeConfig<TSource extends string | null, TQuery, TApi> = {
|
|
28
|
+
source: TSource;
|
|
29
|
+
query: TQuery;
|
|
30
|
+
get: () => TApi;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Type for the special `on` callback function
|
|
34
|
+
*/
|
|
35
|
+
export type OnCallbackFn = <TEvent extends AssistantEvent>(selector: AssistantEventSelector<TEvent>, callback: AssistantEventCallback<TEvent>) => Unsubscribe;
|
|
36
|
+
/**
|
|
37
|
+
* Type for the special `subscribe` callback function
|
|
38
|
+
*/
|
|
39
|
+
export type SubscribeCallbackFn = (listener: () => void) => Unsubscribe;
|
|
40
|
+
/**
|
|
41
|
+
* Type for the special `flushSync` callback function
|
|
42
|
+
*/
|
|
43
|
+
export type FlushSyncCallbackFn = () => void;
|
|
44
|
+
/**
|
|
45
|
+
* Type for special non-field functions in AssistantApi
|
|
46
|
+
*/
|
|
47
|
+
export type SpecialCallbacks = {
|
|
48
|
+
on?: OnCallbackFn;
|
|
49
|
+
subscribe?: SubscribeCallbackFn;
|
|
50
|
+
flushSync?: FlushSyncCallbackFn;
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Type for the scopes parameter - allows both DerivedScope elements and special callbacks.
|
|
54
|
+
* Field names are restricted to valid AssistantApi field names.
|
|
55
|
+
* TypeScript validates that the source/query/get types match the expected field type.
|
|
56
|
+
*/
|
|
57
|
+
export type DerivedScopesInput = {
|
|
58
|
+
[K in AssistantApiFieldNames]?: ResourceElement<AssistantApiField<ExtractApiType<AssistantApi[K]>, {
|
|
59
|
+
source: ExtractMeta<AssistantApi[K]>["source"];
|
|
60
|
+
query: ExtractMeta<AssistantApi[K]>["query"];
|
|
61
|
+
}>>;
|
|
62
|
+
} & SpecialCallbacks;
|
|
63
|
+
/**
|
|
64
|
+
* DerivedScope resource - memoizes an AssistantApiField based on source and query.
|
|
65
|
+
* The get callback always calls the most recent version (useEffectEvent pattern).
|
|
66
|
+
* TypeScript infers TSource, TQuery, and TApi from the config object.
|
|
67
|
+
* Validation happens at the DerivedScopesInput level.
|
|
68
|
+
*/
|
|
69
|
+
export declare const DerivedScope: <TSource extends string | null, TQuery, TApi>(props: DerivedScopeConfig<TSource, TQuery, TApi>, options?: {
|
|
70
|
+
key?: string | number;
|
|
71
|
+
} | undefined) => ResourceElement<AssistantApiField<TApi, {
|
|
72
|
+
source: TSource;
|
|
73
|
+
query: TQuery;
|
|
74
|
+
}>, DerivedScopeConfig<TSource, TQuery, TApi>>;
|
|
75
|
+
/**
|
|
76
|
+
* DerivedScopes resource - takes an object of DerivedScope resource elements and special callbacks,
|
|
77
|
+
* and returns a Partial<AssistantApi> with all the derived fields.
|
|
78
|
+
*/
|
|
79
|
+
export declare const DerivedScopes: import("@assistant-ui/tap").ResourceElementConstructor<Partial<AssistantApi>, DerivedScopesInput>;
|
|
80
|
+
export {};
|
|
81
|
+
//# sourceMappingURL=derived-scopes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"derived-scopes.d.ts","sourceRoot":"","sources":["../../../src/utils/tap-store/derived-scopes.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,YAAY,EACZ,iBAAiB,EAClB,MAAM,yCAAyC,CAAC;AACjD,OAAO,KAAK,EACV,cAAc,EACd,sBAAsB,EACtB,sBAAsB,EACvB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEtE;;GAEG;AACH,KAAK,cAAc,CAAC,CAAC,IACnB,CAAC,SAAS,iBAAiB,CAAC,MAAM,IAAI,EAAE,GAAG,CAAC,GAAG,IAAI,GAAG,KAAK,CAAC;AAE9D;;;;;GAKG;AACH,KAAK,WAAW,CAAC,CAAC,IAChB,CAAC,SAAS,iBAAiB,CAAC,GAAG,EAAE,MAAM,KAAK,CAAC,GAAG,KAAK,GAAG,KAAK,CAAC;AAEhE;;GAEG;AACH,KAAK,sBAAsB,GAAG;KAC3B,CAAC,IAAI,MAAM,YAAY,GAAG,YAAY,CAAC,CAAC,CAAC,SAAS;QAAE,MAAM,EAAE,GAAG,CAAC;QAAC,KAAK,EAAE,GAAG,CAAA;KAAE,GAC1E,CAAC,GACD,KAAK;CACV,CAAC,MAAM,YAAY,CAAC,CAAC;AAEtB;;GAEG;AACH,MAAM,MAAM,kBAAkB,CAAC,OAAO,SAAS,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,IAAI,IAAI;IAC5E,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,IAAI,CAAC;CACjB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,MAAM,SAAS,cAAc,EACvD,QAAQ,EAAE,sBAAsB,CAAC,MAAM,CAAC,EACxC,QAAQ,EAAE,sBAAsB,CAAC,MAAM,CAAC,KACrC,WAAW,CAAC;AAEjB;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,WAAW,CAAC;AAExE;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,MAAM,IAAI,CAAC;AAE7C;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,EAAE,CAAC,EAAE,YAAY,CAAC;IAClB,SAAS,CAAC,EAAE,mBAAmB,CAAC;IAChC,SAAS,CAAC,EAAE,mBAAmB,CAAC;CACjC,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAAG;KAC9B,CAAC,IAAI,sBAAsB,CAAC,CAAC,EAAE,eAAe,CAC7C,iBAAiB,CACf,cAAc,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAC/B;QACE,MAAM,EAAE,WAAW,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QAC/C,KAAK,EAAE,WAAW,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;KAC9C,CACF,CACF;CACF,GAAG,gBAAgB,CAAC;AAErB;;;;;GAKG;AACH,eAAO,MAAM,YAAY,GACtB,OAAO,SAAS,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,IAAI;;;YAKhC,OAAO;WACR,MAAM;8CAgBlB,CAAC;AAmBF;;;GAGG;AACH,eAAO,MAAM,aAAa,mGAyCzB,CAAC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// src/utils/tap-store/derived-scopes.ts
|
|
2
|
+
import { resource, tapEffect } from "@assistant-ui/tap";
|
|
3
|
+
import { tapMemo, tapRef, tapResource, tapResources } from "@assistant-ui/tap";
|
|
4
|
+
import { createAssistantApiField } from "../../context/react/AssistantApiContext.js";
|
|
5
|
+
var DerivedScope = resource(
|
|
6
|
+
(config) => {
|
|
7
|
+
const getRef = tapRef(config.get);
|
|
8
|
+
tapEffect(() => {
|
|
9
|
+
getRef.current = config.get;
|
|
10
|
+
});
|
|
11
|
+
return tapMemo(() => {
|
|
12
|
+
return createAssistantApiField({
|
|
13
|
+
source: config.source,
|
|
14
|
+
query: config.query,
|
|
15
|
+
get: () => getRef.current()
|
|
16
|
+
});
|
|
17
|
+
}, [config.source, JSON.stringify(config.query)]);
|
|
18
|
+
}
|
|
19
|
+
);
|
|
20
|
+
var ScopeFieldWithNameResource = resource(
|
|
21
|
+
(config) => {
|
|
22
|
+
const field = tapResource(config.scopeElement);
|
|
23
|
+
return tapMemo(
|
|
24
|
+
() => [config.fieldName, field],
|
|
25
|
+
[config.fieldName, field]
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
);
|
|
29
|
+
var DerivedScopes = resource(
|
|
30
|
+
(scopes) => {
|
|
31
|
+
const { on, subscribe, flushSync, ...scopeFields } = scopes;
|
|
32
|
+
const callbacksRef = tapRef({ on, subscribe, flushSync });
|
|
33
|
+
tapEffect(() => {
|
|
34
|
+
callbacksRef.current = { on, subscribe, flushSync };
|
|
35
|
+
});
|
|
36
|
+
const results = tapResources(
|
|
37
|
+
Object.entries(scopeFields).map(
|
|
38
|
+
([fieldName, scopeElement]) => ScopeFieldWithNameResource(
|
|
39
|
+
{
|
|
40
|
+
fieldName,
|
|
41
|
+
scopeElement
|
|
42
|
+
},
|
|
43
|
+
{ key: fieldName }
|
|
44
|
+
)
|
|
45
|
+
)
|
|
46
|
+
);
|
|
47
|
+
return tapMemo(() => {
|
|
48
|
+
const result = Object.fromEntries(results);
|
|
49
|
+
const {
|
|
50
|
+
on: onCb,
|
|
51
|
+
subscribe: subCb,
|
|
52
|
+
flushSync: flushCb
|
|
53
|
+
} = callbacksRef.current;
|
|
54
|
+
if (onCb) {
|
|
55
|
+
result.on = (selector, callback) => onCb(selector, callback);
|
|
56
|
+
}
|
|
57
|
+
if (subCb) result.subscribe = (listener) => subCb(listener);
|
|
58
|
+
if (flushCb) result.flushSync = () => flushCb();
|
|
59
|
+
return result;
|
|
60
|
+
}, [...results]);
|
|
61
|
+
}
|
|
62
|
+
);
|
|
63
|
+
export {
|
|
64
|
+
DerivedScope,
|
|
65
|
+
DerivedScopes
|
|
66
|
+
};
|
|
67
|
+
//# sourceMappingURL=derived-scopes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/utils/tap-store/derived-scopes.ts"],"sourcesContent":["import { resource, tapEffect } from \"@assistant-ui/tap\";\nimport { tapMemo, tapRef, tapResource, tapResources } from \"@assistant-ui/tap\";\nimport { createAssistantApiField } from \"../../context/react/AssistantApiContext\";\nimport type {\n AssistantApi,\n AssistantApiField,\n} from \"../../context/react/AssistantApiContext\";\nimport type {\n AssistantEvent,\n AssistantEventCallback,\n AssistantEventSelector,\n} from \"../../types/EventTypes\";\nimport type { ResourceElement, Unsubscribe } from \"@assistant-ui/tap\";\n\n/**\n * Extract the API return type from an AssistantApiField\n */\ntype ExtractApiType<T> =\n T extends AssistantApiField<infer TApi, any> ? TApi : never;\n\n/**\n * Extract the metadata type from an AssistantApiField\n *\n * Used in DerivedScopesInput to validate that each field's source/query types match\n * the expected types from AssistantApi.\n */\ntype ExtractMeta<T> =\n T extends AssistantApiField<any, infer TMeta> ? TMeta : never;\n\n/**\n * Get only the field names from AssistantApi (exclude method names)\n */\ntype AssistantApiFieldNames = {\n [K in keyof AssistantApi]: AssistantApi[K] extends { source: any; query: any }\n ? K\n : never;\n}[keyof AssistantApi];\n\n/**\n * Configuration for a derived scope field - infers types from the actual values provided\n */\nexport type DerivedScopeConfig<TSource extends string | null, TQuery, TApi> = {\n source: TSource;\n query: TQuery;\n get: () => TApi;\n};\n\n/**\n * Type for the special `on` callback function\n */\nexport type OnCallbackFn = <TEvent extends AssistantEvent>(\n selector: AssistantEventSelector<TEvent>,\n callback: AssistantEventCallback<TEvent>,\n) => Unsubscribe;\n\n/**\n * Type for the special `subscribe` callback function\n */\nexport type SubscribeCallbackFn = (listener: () => void) => Unsubscribe;\n\n/**\n * Type for the special `flushSync` callback function\n */\nexport type FlushSyncCallbackFn = () => void;\n\n/**\n * Type for special non-field functions in AssistantApi\n */\nexport type SpecialCallbacks = {\n on?: OnCallbackFn;\n subscribe?: SubscribeCallbackFn;\n flushSync?: FlushSyncCallbackFn;\n};\n\n/**\n * Type for the scopes parameter - allows both DerivedScope elements and special callbacks.\n * Field names are restricted to valid AssistantApi field names.\n * TypeScript validates that the source/query/get types match the expected field type.\n */\nexport type DerivedScopesInput = {\n [K in AssistantApiFieldNames]?: ResourceElement<\n AssistantApiField<\n ExtractApiType<AssistantApi[K]>,\n {\n source: ExtractMeta<AssistantApi[K]>[\"source\"];\n query: ExtractMeta<AssistantApi[K]>[\"query\"];\n }\n >\n >;\n} & SpecialCallbacks;\n\n/**\n * DerivedScope resource - memoizes an AssistantApiField based on source and query.\n * The get callback always calls the most recent version (useEffectEvent pattern).\n * TypeScript infers TSource, TQuery, and TApi from the config object.\n * Validation happens at the DerivedScopesInput level.\n */\nexport const DerivedScope = resource(\n <TSource extends string | null, TQuery, TApi>(\n config: DerivedScopeConfig<TSource, TQuery, TApi>,\n ): AssistantApiField<\n TApi,\n {\n source: TSource;\n query: TQuery;\n }\n > => {\n const getRef = tapRef(config.get);\n tapEffect(() => {\n getRef.current = config.get;\n });\n\n return tapMemo(() => {\n return createAssistantApiField({\n source: config.source,\n query: config.query,\n get: () => getRef.current(),\n });\n }, [config.source, JSON.stringify(config.query)]);\n },\n);\n\n/**\n * Helper resource to wrap each scope field - stable resource identity for proper memoization.\n * Creating this outside the map ensures tapResources can properly track and memoize each field.\n */\nconst ScopeFieldWithNameResource = resource(\n (config: {\n fieldName: string;\n scopeElement: ReturnType<typeof DerivedScope>;\n }) => {\n const field = tapResource(config.scopeElement);\n return tapMemo(\n () => [config.fieldName, field] as const,\n [config.fieldName, field],\n );\n },\n);\n\n/**\n * DerivedScopes resource - takes an object of DerivedScope resource elements and special callbacks,\n * and returns a Partial<AssistantApi> with all the derived fields.\n */\nexport const DerivedScopes = resource(\n (scopes: DerivedScopesInput): Partial<AssistantApi> => {\n const { on, subscribe, flushSync, ...scopeFields } = scopes;\n const callbacksRef = tapRef({ on, subscribe, flushSync });\n tapEffect(() => {\n callbacksRef.current = { on, subscribe, flushSync };\n });\n\n const results = tapResources(\n Object.entries(scopeFields).map(([fieldName, scopeElement]) =>\n ScopeFieldWithNameResource(\n {\n fieldName,\n scopeElement: scopeElement as ReturnType<typeof DerivedScope>,\n },\n { key: fieldName },\n ),\n ),\n );\n\n return tapMemo(() => {\n const result = Object.fromEntries(results) as Partial<AssistantApi>;\n\n const {\n on: onCb,\n subscribe: subCb,\n flushSync: flushCb,\n } = callbacksRef.current;\n\n if (onCb) {\n result.on = <TEvent extends AssistantEvent>(\n selector: AssistantEventSelector<TEvent>,\n callback: AssistantEventCallback<TEvent>,\n ) => onCb(selector, callback);\n }\n if (subCb) result.subscribe = (listener) => subCb(listener);\n if (flushCb) result.flushSync = () => flushCb();\n\n return result;\n }, [...results]);\n },\n);\n"],"mappings":";AAAA,SAAS,UAAU,iBAAiB;AACpC,SAAS,SAAS,QAAQ,aAAa,oBAAoB;AAC3D,SAAS,+BAA+B;AA+FjC,IAAM,eAAe;AAAA,EAC1B,CACE,WAOG;AACH,UAAM,SAAS,OAAO,OAAO,GAAG;AAChC,cAAU,MAAM;AACd,aAAO,UAAU,OAAO;AAAA,IAC1B,CAAC;AAED,WAAO,QAAQ,MAAM;AACnB,aAAO,wBAAwB;AAAA,QAC7B,QAAQ,OAAO;AAAA,QACf,OAAO,OAAO;AAAA,QACd,KAAK,MAAM,OAAO,QAAQ;AAAA,MAC5B,CAAC;AAAA,IACH,GAAG,CAAC,OAAO,QAAQ,KAAK,UAAU,OAAO,KAAK,CAAC,CAAC;AAAA,EAClD;AACF;AAMA,IAAM,6BAA6B;AAAA,EACjC,CAAC,WAGK;AACJ,UAAM,QAAQ,YAAY,OAAO,YAAY;AAC7C,WAAO;AAAA,MACL,MAAM,CAAC,OAAO,WAAW,KAAK;AAAA,MAC9B,CAAC,OAAO,WAAW,KAAK;AAAA,IAC1B;AAAA,EACF;AACF;AAMO,IAAM,gBAAgB;AAAA,EAC3B,CAAC,WAAsD;AACrD,UAAM,EAAE,IAAI,WAAW,WAAW,GAAG,YAAY,IAAI;AACrD,UAAM,eAAe,OAAO,EAAE,IAAI,WAAW,UAAU,CAAC;AACxD,cAAU,MAAM;AACd,mBAAa,UAAU,EAAE,IAAI,WAAW,UAAU;AAAA,IACpD,CAAC;AAED,UAAM,UAAU;AAAA,MACd,OAAO,QAAQ,WAAW,EAAE;AAAA,QAAI,CAAC,CAAC,WAAW,YAAY,MACvD;AAAA,UACE;AAAA,YACE;AAAA,YACA;AAAA,UACF;AAAA,UACA,EAAE,KAAK,UAAU;AAAA,QACnB;AAAA,MACF;AAAA,IACF;AAEA,WAAO,QAAQ,MAAM;AACnB,YAAM,SAAS,OAAO,YAAY,OAAO;AAEzC,YAAM;AAAA,QACJ,IAAI;AAAA,QACJ,WAAW;AAAA,QACX,WAAW;AAAA,MACb,IAAI,aAAa;AAEjB,UAAI,MAAM;AACR,eAAO,KAAK,CACV,UACA,aACG,KAAK,UAAU,QAAQ;AAAA,MAC9B;AACA,UAAI,MAAO,QAAO,YAAY,CAAC,aAAa,MAAM,QAAQ;AAC1D,UAAI,QAAS,QAAO,YAAY,MAAM,QAAQ;AAE9C,aAAO;AAAA,IACT,GAAG,CAAC,GAAG,OAAO,CAAC;AAAA,EACjB;AACF;","names":[]}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export { type Store, asStore } from "./store";
|
|
2
2
|
export { tapApi, type ApiObject } from "./tap-api";
|
|
3
|
+
export { DerivedScope, type DerivedScopeConfig, type OnCallbackFn, type SubscribeCallbackFn, type FlushSyncCallbackFn, type SpecialCallbacks, type DerivedScopesInput, } from "./derived-scopes";
|
|
3
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/tap-store/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/tap-store/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EACL,YAAY,EACZ,KAAK,kBAAkB,EACvB,KAAK,YAAY,EACjB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,GACxB,MAAM,kBAAkB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/utils/tap-store/index.ts"],"sourcesContent":["export { type Store, asStore } from \"./store\";\nexport { tapApi, type ApiObject } from \"./tap-api\";\n"],"mappings":";AAAA,SAAqB,eAAe;AACpC,SAAS,cAA8B;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/utils/tap-store/index.ts"],"sourcesContent":["export { type Store, asStore } from \"./store\";\nexport { tapApi, type ApiObject } from \"./tap-api\";\nexport {\n DerivedScope,\n type DerivedScopeConfig,\n type OnCallbackFn,\n type SubscribeCallbackFn,\n type FlushSyncCallbackFn,\n type SpecialCallbacks,\n type DerivedScopesInput,\n} from \"./derived-scopes\";\n"],"mappings":";AAAA,SAAqB,eAAe;AACpC,SAAS,cAA8B;AACvC;AAAA,EACE;AAAA,OAOK;","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/utils/tap-store/tap-api.ts"],"sourcesContent":["import { tapEffect, tapMemo, tapRef } from \"@assistant-ui/tap\";\n\nexport interface ApiObject {\n [key: string]: ((...args: any[]) => any) | ApiObject;\n}\n\nclass ReadonlyApiHandler<TApi extends ApiObject> implements ProxyHandler<TApi> {\n constructor(private readonly getApi: () => TApi) {}\n\n get(_: unknown, prop: string | symbol) {\n return this.getApi()[prop as keyof TApi];\n }\n\n ownKeys(): ArrayLike<string | symbol> {\n return Object.keys(this.getApi() as object);\n }\n\n has(_: unknown, prop: string | symbol) {\n return prop in (this.getApi() as object);\n }\n\n getOwnPropertyDescriptor(_: unknown, prop: string | symbol) {\n return Object.getOwnPropertyDescriptor(this.getApi(), prop);\n }\n\n set() {\n return false;\n }\n defineProperty() {\n return false;\n }\n deleteProperty() {\n return false;\n }\n}\n\nexport const tapApi = <TApi extends ApiObject & { getState: () => any }>(\n api: TApi,\n options?: {\n key?: string | undefined;\n },\n) => {\n const ref = tapRef(
|
|
1
|
+
{"version":3,"sources":["../../../src/utils/tap-store/tap-api.ts"],"sourcesContent":["import { tapEffect, tapMemo, tapRef } from \"@assistant-ui/tap\";\n\nexport interface ApiObject {\n [key: string]: ((...args: any[]) => any) | ApiObject;\n}\n\nclass ReadonlyApiHandler<TApi extends ApiObject> implements ProxyHandler<TApi> {\n constructor(private readonly getApi: () => TApi) {}\n\n get(_: unknown, prop: string | symbol) {\n return this.getApi()[prop as keyof TApi];\n }\n\n ownKeys(): ArrayLike<string | symbol> {\n return Object.keys(this.getApi() as object);\n }\n\n has(_: unknown, prop: string | symbol) {\n return prop in (this.getApi() as object);\n }\n\n getOwnPropertyDescriptor(_: unknown, prop: string | symbol) {\n return Object.getOwnPropertyDescriptor(this.getApi(), prop);\n }\n\n set() {\n return false;\n }\n defineProperty() {\n return false;\n }\n deleteProperty() {\n return false;\n }\n}\n\nexport const tapApi = <TApi extends ApiObject & { getState: () => any }>(\n api: TApi,\n options?: {\n key?: string | undefined;\n },\n) => {\n const ref = tapRef(api);\n tapEffect(() => {\n ref.current = api;\n });\n\n const apiProxy = tapMemo(\n () =>\n new Proxy<TApi>({} as TApi, new ReadonlyApiHandler(() => ref.current)),\n [],\n );\n\n const key = options?.key;\n const state = api.getState();\n\n return tapMemo(\n () => ({\n key,\n state,\n api: apiProxy,\n }),\n [state, key],\n );\n};\n"],"mappings":";AAAA,SAAS,WAAW,SAAS,cAAc;AAM3C,IAAM,qBAAN,MAA+E;AAAA,EAC7E,YAA6B,QAAoB;AAApB;AAAA,EAAqB;AAAA,EAElD,IAAI,GAAY,MAAuB;AACrC,WAAO,KAAK,OAAO,EAAE,IAAkB;AAAA,EACzC;AAAA,EAEA,UAAsC;AACpC,WAAO,OAAO,KAAK,KAAK,OAAO,CAAW;AAAA,EAC5C;AAAA,EAEA,IAAI,GAAY,MAAuB;AACrC,WAAO,QAAS,KAAK,OAAO;AAAA,EAC9B;AAAA,EAEA,yBAAyB,GAAY,MAAuB;AAC1D,WAAO,OAAO,yBAAyB,KAAK,OAAO,GAAG,IAAI;AAAA,EAC5D;AAAA,EAEA,MAAM;AACJ,WAAO;AAAA,EACT;AAAA,EACA,iBAAiB;AACf,WAAO;AAAA,EACT;AAAA,EACA,iBAAiB;AACf,WAAO;AAAA,EACT;AACF;AAEO,IAAM,SAAS,CACpB,KACA,YAGG;AACH,QAAM,MAAM,OAAO,GAAG;AACtB,YAAU,MAAM;AACd,QAAI,UAAU;AAAA,EAChB,CAAC;AAED,QAAM,WAAW;AAAA,IACf,MACE,IAAI,MAAY,CAAC,GAAW,IAAI,mBAAmB,MAAM,IAAI,OAAO,CAAC;AAAA,IACvE,CAAC;AAAA,EACH;AAEA,QAAM,MAAM,SAAS;AACrB,QAAM,QAAQ,IAAI,SAAS;AAE3B,SAAO;AAAA,IACL,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,CAAC,OAAO,GAAG;AAAA,EACb;AACF;","names":[]}
|
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.36",
|
|
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.1.
|
|
51
|
+
"assistant-cloud": "^0.1.6",
|
|
52
|
+
"@assistant-ui/tap": "^0.1.5",
|
|
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.2",
|
|
@@ -59,7 +59,7 @@
|
|
|
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.39",
|
|
63
63
|
"json-schema": "^0.4.0",
|
|
64
64
|
"nanoid": "5.1.6",
|
|
65
65
|
"react-textarea-autosize": "^8.5.9",
|
|
@@ -81,14 +81,14 @@
|
|
|
81
81
|
}
|
|
82
82
|
},
|
|
83
83
|
"devDependencies": {
|
|
84
|
-
"@stryker-mutator/core": "^9.
|
|
85
|
-
"@stryker-mutator/vitest-runner": "^9.
|
|
84
|
+
"@stryker-mutator/core": "^9.3.0",
|
|
85
|
+
"@stryker-mutator/vitest-runner": "^9.3.0",
|
|
86
86
|
"@types/json-schema": "^7.0.15",
|
|
87
|
-
"@types/node": "^24.
|
|
87
|
+
"@types/node": "^24.10.0",
|
|
88
88
|
"eslint": "^9",
|
|
89
|
-
"eslint-config-next": "16.0.
|
|
89
|
+
"eslint-config-next": "16.0.1",
|
|
90
90
|
"tsx": "^4.20.6",
|
|
91
|
-
"vitest": "^4.0.
|
|
91
|
+
"vitest": "^4.0.6",
|
|
92
92
|
"@assistant-ui/x-buildutils": "0.0.1"
|
|
93
93
|
},
|
|
94
94
|
"publishConfig": {
|
|
@@ -7,8 +7,7 @@ import {
|
|
|
7
7
|
tapResource,
|
|
8
8
|
} from "@assistant-ui/tap";
|
|
9
9
|
import { ThreadListClientApi, ThreadListClientState } from "./types/ThreadList";
|
|
10
|
-
import {
|
|
11
|
-
import { ModelContextProvider } from "../model-context";
|
|
10
|
+
import { Tools } from "../model-context";
|
|
12
11
|
import { asStore, Store, tapApi } from "../utils/tap-store";
|
|
13
12
|
import { useResource } from "@assistant-ui/tap/react";
|
|
14
13
|
import { useMemo } from "react";
|
|
@@ -22,14 +21,23 @@ import { EventManager } from "../legacy-runtime/client/EventManagerRuntimeClient
|
|
|
22
21
|
import {
|
|
23
22
|
AssistantApi,
|
|
24
23
|
createAssistantApiField,
|
|
24
|
+
useAssistantApiImpl,
|
|
25
|
+
extendApi,
|
|
25
26
|
} from "../context/react/AssistantApiContext";
|
|
26
27
|
import { ToolUIClient } from "./ToolUIClient";
|
|
27
28
|
import { withEventsProvider } from "./EventContext";
|
|
29
|
+
import { withModelContextProvider } from "./ModelContext";
|
|
30
|
+
import { withToolUIProvider } from "./ToolUIContext";
|
|
28
31
|
import { ToolUIApi, ToolUIState } from "./types/ToolUI";
|
|
32
|
+
import { ToolsApi, ToolsState } from "./types/Tools";
|
|
33
|
+
import { ModelContextApi, ModelContextState } from "./types/ModelContext";
|
|
34
|
+
import { ModelContext as ModelContextResource } from "./ModelContextClient";
|
|
29
35
|
|
|
30
36
|
type AssistantClientState = {
|
|
31
37
|
readonly threads: ThreadListClientState;
|
|
32
38
|
readonly toolUIs: ToolUIState;
|
|
39
|
+
readonly tools: ToolsState;
|
|
40
|
+
readonly modelContext: ModelContextState;
|
|
33
41
|
};
|
|
34
42
|
|
|
35
43
|
type AssistantClientApi = {
|
|
@@ -37,39 +45,53 @@ type AssistantClientApi = {
|
|
|
37
45
|
|
|
38
46
|
readonly threads: ThreadListClientApi;
|
|
39
47
|
readonly toolUIs: ToolUIApi;
|
|
48
|
+
readonly tools: ToolsApi;
|
|
49
|
+
readonly modelContext: ModelContextApi;
|
|
40
50
|
|
|
41
51
|
on<TEvent extends AssistantEvent>(
|
|
42
52
|
event: TEvent,
|
|
43
53
|
callback: AssistantEventCallback<TEvent>,
|
|
44
54
|
): Unsubscribe;
|
|
45
|
-
|
|
46
|
-
registerModelContextProvider(provider: ModelContextProvider): Unsubscribe;
|
|
47
|
-
|
|
48
|
-
/** @internal */
|
|
49
|
-
__internal_getRuntime?(): AssistantRuntime;
|
|
50
55
|
};
|
|
51
56
|
|
|
52
57
|
const AssistantStore = resource(
|
|
53
58
|
({
|
|
54
59
|
threads: threadsEl,
|
|
55
|
-
|
|
56
|
-
|
|
60
|
+
modelContext: modelContextEl,
|
|
61
|
+
tools: toolsEl,
|
|
57
62
|
}: AssistantClientProps) => {
|
|
58
63
|
const events = tapInlineResource(EventManager());
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
const toolUIsResource = tapInlineResource(ToolUIClient());
|
|
65
|
+
|
|
66
|
+
const { threads, toolUIs, tools, modelContext } = withEventsProvider(
|
|
67
|
+
events,
|
|
68
|
+
() => {
|
|
69
|
+
const modelContextResource = tapResource(
|
|
70
|
+
modelContextEl ?? ModelContextResource(),
|
|
71
|
+
[modelContextEl],
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
return withModelContextProvider(modelContextResource.api, () => {
|
|
75
|
+
return withToolUIProvider(toolUIsResource.api, () => {
|
|
76
|
+
return {
|
|
77
|
+
toolUIs: toolUIsResource,
|
|
78
|
+
modelContext: modelContextResource,
|
|
79
|
+
tools: tapResource(toolsEl ?? Tools({}), [toolsEl]),
|
|
80
|
+
threads: tapResource(threadsEl, [threadsEl]),
|
|
81
|
+
};
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
},
|
|
85
|
+
);
|
|
66
86
|
|
|
67
87
|
const state = tapMemo<AssistantClientState>(
|
|
68
88
|
() => ({
|
|
69
89
|
threads: threads.state,
|
|
70
90
|
toolUIs: toolUIs.state,
|
|
91
|
+
tools: tools.state,
|
|
92
|
+
modelContext: modelContext.state,
|
|
71
93
|
}),
|
|
72
|
-
[threads.state, toolUIs.state],
|
|
94
|
+
[threads.state, toolUIs.state, tools.state, modelContext.state],
|
|
73
95
|
);
|
|
74
96
|
|
|
75
97
|
return tapApi<AssistantClientApi>({
|
|
@@ -77,13 +99,9 @@ const AssistantStore = resource(
|
|
|
77
99
|
|
|
78
100
|
threads: threads.api,
|
|
79
101
|
toolUIs: toolUIs.api,
|
|
102
|
+
tools: tools.api,
|
|
103
|
+
modelContext: modelContext.api,
|
|
80
104
|
on: events.on,
|
|
81
|
-
|
|
82
|
-
registerModelContextProvider:
|
|
83
|
-
registerModelContextProvider ?? (() => () => {}),
|
|
84
|
-
...(__internal_runtime && {
|
|
85
|
-
__internal_getRuntime: () => __internal_runtime,
|
|
86
|
-
}),
|
|
87
105
|
});
|
|
88
106
|
},
|
|
89
107
|
);
|
|
@@ -103,6 +121,16 @@ const getClientFromStore = (client: Store<{ api: AssistantClientApi }>) => {
|
|
|
103
121
|
query: {},
|
|
104
122
|
get: () => client.getState().api.toolUIs,
|
|
105
123
|
}),
|
|
124
|
+
tools: createAssistantApiField({
|
|
125
|
+
source: "root",
|
|
126
|
+
query: {},
|
|
127
|
+
get: () => client.getState().api.tools,
|
|
128
|
+
}),
|
|
129
|
+
modelContext: createAssistantApiField({
|
|
130
|
+
source: "root",
|
|
131
|
+
query: {},
|
|
132
|
+
get: () => client.getState().api.modelContext,
|
|
133
|
+
}),
|
|
106
134
|
thread: createAssistantApiField({
|
|
107
135
|
source: "threads",
|
|
108
136
|
query: { type: "main" },
|
|
@@ -118,14 +146,6 @@ const getClientFromStore = (client: Store<{ api: AssistantClientApi }>) => {
|
|
|
118
146
|
query: {},
|
|
119
147
|
get: () => client.getState().api.threads.thread("main").composer,
|
|
120
148
|
}),
|
|
121
|
-
registerModelContextProvider(provider: ModelContextProvider) {
|
|
122
|
-
return client.getState().api.registerModelContextProvider(provider);
|
|
123
|
-
},
|
|
124
|
-
...(client.getState().api.__internal_getRuntime && {
|
|
125
|
-
__internal_getRuntime() {
|
|
126
|
-
return client.getState().api.__internal_getRuntime!();
|
|
127
|
-
},
|
|
128
|
-
}),
|
|
129
149
|
on(selector, callback) {
|
|
130
150
|
const { event, scope } = normalizeEventSelector(selector);
|
|
131
151
|
if (scope === "*") return client.getState().api.on(event, callback);
|
|
@@ -155,15 +175,21 @@ export type AssistantClientProps = {
|
|
|
155
175
|
state: ThreadListClientState;
|
|
156
176
|
api: ThreadListClientApi;
|
|
157
177
|
}>;
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
178
|
+
modelContext?: ResourceElement<{
|
|
179
|
+
state: ModelContextState;
|
|
180
|
+
api: ModelContextApi;
|
|
181
|
+
}>;
|
|
182
|
+
tools?:
|
|
183
|
+
| ResourceElement<{
|
|
184
|
+
state: ToolsState;
|
|
185
|
+
api: ToolsApi;
|
|
186
|
+
}>
|
|
187
|
+
| undefined;
|
|
164
188
|
};
|
|
165
189
|
|
|
166
190
|
export const useAssistantClient = (props: AssistantClientProps) => {
|
|
191
|
+
const api = useAssistantApiImpl();
|
|
167
192
|
const client = useResource(asStore(AssistantStore(props)));
|
|
168
|
-
|
|
193
|
+
const clientApi = useMemo(() => getClientFromStore(client), [client]);
|
|
194
|
+
return useMemo(() => extendApi(api, clientApi), [api, clientApi]);
|
|
169
195
|
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createContext,
|
|
3
|
+
tapContext,
|
|
4
|
+
withContextProvider,
|
|
5
|
+
Unsubscribe,
|
|
6
|
+
} from "@assistant-ui/tap";
|
|
7
|
+
import { ModelContextProvider } from "../model-context/ModelContextTypes";
|
|
8
|
+
|
|
9
|
+
export type ModelContextRegistrar = ModelContextProvider & {
|
|
10
|
+
register: (provider: ModelContextProvider) => Unsubscribe;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const ModelContextContext = createContext<ModelContextRegistrar | null>(null);
|
|
14
|
+
|
|
15
|
+
export const withModelContextProvider = <TResult>(
|
|
16
|
+
modelContext: ModelContextRegistrar,
|
|
17
|
+
fn: () => TResult,
|
|
18
|
+
) => {
|
|
19
|
+
return withContextProvider(ModelContextContext, modelContext, fn);
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export const tapModelContext = () => {
|
|
23
|
+
const modelContext = tapContext(ModelContextContext);
|
|
24
|
+
if (!modelContext)
|
|
25
|
+
throw new Error("Model context is not available in this context");
|
|
26
|
+
|
|
27
|
+
return modelContext;
|
|
28
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { resource, tapState } from "@assistant-ui/tap";
|
|
2
|
+
import { tapApi } from "../utils/tap-store";
|
|
3
|
+
import { CompositeContextProvider } from "../utils/CompositeContextProvider";
|
|
4
|
+
import type { ModelContextState, ModelContextApi } from "./types/ModelContext";
|
|
5
|
+
|
|
6
|
+
export const ModelContext = resource(() => {
|
|
7
|
+
const [state] = tapState<ModelContextState>(() => ({}));
|
|
8
|
+
const composite = new CompositeContextProvider();
|
|
9
|
+
|
|
10
|
+
return tapApi<ModelContextApi>({
|
|
11
|
+
getState: () => state,
|
|
12
|
+
getModelContext: () => composite.getModelContext(),
|
|
13
|
+
subscribe: (callback) => composite.subscribe(callback),
|
|
14
|
+
register: (provider) => composite.registerModelContextProvider(provider),
|
|
15
|
+
});
|
|
16
|
+
});
|
|
@@ -3,7 +3,11 @@ import { tapApi } from "../utils/tap-store";
|
|
|
3
3
|
import { ToolUIState, ToolUIApi } from "./types/ToolUI";
|
|
4
4
|
|
|
5
5
|
export const ToolUIClient = resource(() => {
|
|
6
|
-
const [state, setState] = tapState<ToolUIState>(() => ({
|
|
6
|
+
const [state, setState] = tapState<ToolUIState>(() => ({
|
|
7
|
+
tools: {},
|
|
8
|
+
fallback: [],
|
|
9
|
+
layout: [],
|
|
10
|
+
}));
|
|
7
11
|
|
|
8
12
|
return tapApi<ToolUIApi>({
|
|
9
13
|
getState: () => state,
|
|
@@ -12,7 +16,10 @@ export const ToolUIClient = resource(() => {
|
|
|
12
16
|
setState((prev) => {
|
|
13
17
|
return {
|
|
14
18
|
...prev,
|
|
15
|
-
|
|
19
|
+
tools: {
|
|
20
|
+
...prev.tools,
|
|
21
|
+
[toolName]: [...(prev.tools[toolName] ?? []), render],
|
|
22
|
+
},
|
|
16
23
|
};
|
|
17
24
|
});
|
|
18
25
|
|
|
@@ -20,7 +27,47 @@ export const ToolUIClient = resource(() => {
|
|
|
20
27
|
setState((prev) => {
|
|
21
28
|
return {
|
|
22
29
|
...prev,
|
|
23
|
-
|
|
30
|
+
tools: {
|
|
31
|
+
...prev.tools,
|
|
32
|
+
[toolName]:
|
|
33
|
+
prev.tools[toolName]?.filter((r) => r !== render) ?? [],
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
setFallbackToolUI: (render) => {
|
|
41
|
+
setState((prev) => {
|
|
42
|
+
return {
|
|
43
|
+
...prev,
|
|
44
|
+
fallback: [...prev.fallback, render],
|
|
45
|
+
};
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
return () => {
|
|
49
|
+
setState((prev) => {
|
|
50
|
+
return {
|
|
51
|
+
...prev,
|
|
52
|
+
fallback: prev.fallback.filter((r) => r !== render),
|
|
53
|
+
};
|
|
54
|
+
});
|
|
55
|
+
};
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
setToolUILayout: (render) => {
|
|
59
|
+
setState((prev) => {
|
|
60
|
+
return {
|
|
61
|
+
...prev,
|
|
62
|
+
layout: [...prev.layout, render],
|
|
63
|
+
};
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
return () => {
|
|
67
|
+
setState((prev) => {
|
|
68
|
+
return {
|
|
69
|
+
...prev,
|
|
70
|
+
layout: prev.layout.filter((r) => r !== render),
|
|
24
71
|
};
|
|
25
72
|
});
|
|
26
73
|
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createContext,
|
|
3
|
+
tapContext,
|
|
4
|
+
withContextProvider,
|
|
5
|
+
} from "@assistant-ui/tap";
|
|
6
|
+
import type { ToolUIApi } from "./types/ToolUI";
|
|
7
|
+
|
|
8
|
+
const ToolUIContext = createContext<ToolUIApi | null>(null);
|
|
9
|
+
|
|
10
|
+
export const withToolUIProvider = <TResult>(
|
|
11
|
+
toolUIs: ToolUIApi,
|
|
12
|
+
fn: () => TResult,
|
|
13
|
+
) => {
|
|
14
|
+
return withContextProvider(ToolUIContext, toolUIs, fn);
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const tapToolUI = () => {
|
|
18
|
+
const toolUIs = tapContext(ToolUIContext);
|
|
19
|
+
if (!toolUIs) throw new Error("ToolUI context is not available");
|
|
20
|
+
|
|
21
|
+
return toolUIs;
|
|
22
|
+
};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { resource, tapState, tapEffect } from "@assistant-ui/tap";
|
|
2
|
+
import { tapApi } from "../utils/tap-store";
|
|
3
|
+
import { tapModelContext } from "./ModelContext";
|
|
4
|
+
import { tapToolUI } from "./ToolUIContext";
|
|
5
|
+
import { ToolsState, ToolsApi } from "./types/Tools";
|
|
6
|
+
import type { Tool } from "assistant-stream";
|
|
7
|
+
import {
|
|
8
|
+
type Toolkit,
|
|
9
|
+
FallbackSymbol,
|
|
10
|
+
LayoutSymbol,
|
|
11
|
+
} from "../model-context/toolbox";
|
|
12
|
+
|
|
13
|
+
export const Tools = resource(({ toolkit }: { toolkit?: Toolkit }) => {
|
|
14
|
+
const [state] = tapState<ToolsState>(() => ({}));
|
|
15
|
+
|
|
16
|
+
const modelContext = tapModelContext();
|
|
17
|
+
const toolUI = tapToolUI();
|
|
18
|
+
|
|
19
|
+
tapEffect(() => {
|
|
20
|
+
if (!toolkit) return;
|
|
21
|
+
const unsubscribes: (() => void)[] = [];
|
|
22
|
+
|
|
23
|
+
// Register fallback UI
|
|
24
|
+
const fallback = toolkit[FallbackSymbol];
|
|
25
|
+
if (fallback?.render) {
|
|
26
|
+
unsubscribes.push(toolUI.setFallbackToolUI(fallback.render));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Register layout
|
|
30
|
+
const layout = toolkit[LayoutSymbol];
|
|
31
|
+
if (layout?.render) {
|
|
32
|
+
unsubscribes.push(toolUI.setToolUILayout(layout.render));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Register tool UIs (exclude symbols)
|
|
36
|
+
for (const [toolName, tool] of Object.entries(toolkit)) {
|
|
37
|
+
if (tool.render) {
|
|
38
|
+
unsubscribes.push(toolUI.setToolUI(toolName, tool.render));
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Register tools with model context (exclude symbols)
|
|
43
|
+
const toolsWithoutRender = Object.entries(toolkit).reduce(
|
|
44
|
+
(acc, [name, tool]) => {
|
|
45
|
+
const { render, ...rest } = tool;
|
|
46
|
+
acc[name] = rest;
|
|
47
|
+
return acc;
|
|
48
|
+
},
|
|
49
|
+
{} as Record<string, Tool<any, any>>,
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
const modelContextProvider = {
|
|
53
|
+
getModelContext: () => ({
|
|
54
|
+
tools: toolsWithoutRender,
|
|
55
|
+
}),
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
unsubscribes.push(modelContext.register(modelContextProvider));
|
|
59
|
+
|
|
60
|
+
return () => {
|
|
61
|
+
unsubscribes.forEach((fn) => fn());
|
|
62
|
+
};
|
|
63
|
+
}, [toolkit, modelContext, toolUI]);
|
|
64
|
+
|
|
65
|
+
return tapApi<ToolsApi>({
|
|
66
|
+
getState: () => state,
|
|
67
|
+
});
|
|
68
|
+
});
|