@assistant-ui/react 0.11.34 → 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.
Files changed (216) hide show
  1. package/dist/augmentations.d.ts +9 -0
  2. package/dist/augmentations.d.ts.map +1 -1
  3. package/dist/client/AssistantClient.d.ts +13 -57
  4. package/dist/client/AssistantClient.d.ts.map +1 -1
  5. package/dist/client/AssistantClient.js +49 -26
  6. package/dist/client/AssistantClient.js.map +1 -1
  7. package/dist/client/ModelContext.d.ts +8 -0
  8. package/dist/client/ModelContext.d.ts.map +1 -0
  9. package/dist/client/ModelContext.js +21 -0
  10. package/dist/client/ModelContext.js.map +1 -0
  11. package/dist/client/ModelContextClient.d.ts +7 -0
  12. package/dist/client/ModelContextClient.d.ts.map +1 -0
  13. package/dist/client/ModelContextClient.js +18 -0
  14. package/dist/client/ModelContextClient.js.map +1 -0
  15. package/dist/client/ToolUIClient.d.ts.map +1 -1
  16. package/dist/client/ToolUIClient.js +45 -3
  17. package/dist/client/ToolUIClient.js.map +1 -1
  18. package/dist/client/ToolUIContext.d.ts +4 -0
  19. package/dist/client/ToolUIContext.d.ts.map +1 -0
  20. package/dist/client/ToolUIContext.js +20 -0
  21. package/dist/client/ToolUIContext.js.map +1 -0
  22. package/dist/client/Tools.d.ts +10 -0
  23. package/dist/client/Tools.d.ts.map +1 -0
  24. package/dist/client/Tools.js +55 -0
  25. package/dist/client/Tools.js.map +1 -0
  26. package/dist/client/types/ModelContext.d.ts +12 -0
  27. package/dist/client/types/ModelContext.d.ts.map +1 -0
  28. package/dist/client/types/ModelContext.js +1 -0
  29. package/dist/client/types/ModelContext.js.map +1 -0
  30. package/dist/client/types/ThreadList.d.ts.map +1 -1
  31. package/dist/client/types/ToolUI.d.ts +12 -1
  32. package/dist/client/types/ToolUI.d.ts.map +1 -1
  33. package/dist/client/types/Tools.d.ts +9 -0
  34. package/dist/client/types/Tools.d.ts.map +1 -0
  35. package/dist/client/types/Tools.js +1 -0
  36. package/dist/client/types/Tools.js.map +1 -0
  37. package/dist/context/providers/AttachmentByIndexProvider.d.ts.map +1 -1
  38. package/dist/context/providers/AttachmentByIndexProvider.js +20 -24
  39. package/dist/context/providers/AttachmentByIndexProvider.js.map +1 -1
  40. package/dist/context/providers/MessageByIndexProvider.d.ts.map +1 -1
  41. package/dist/context/providers/MessageByIndexProvider.js +27 -29
  42. package/dist/context/providers/MessageByIndexProvider.js.map +1 -1
  43. package/dist/context/providers/MessageProvider.d.ts.map +1 -1
  44. package/dist/context/providers/MessageProvider.js +11 -13
  45. package/dist/context/providers/MessageProvider.js.map +1 -1
  46. package/dist/context/providers/PartByIndexProvider.d.ts.map +1 -1
  47. package/dist/context/providers/PartByIndexProvider.js +11 -13
  48. package/dist/context/providers/PartByIndexProvider.js.map +1 -1
  49. package/dist/context/providers/TextMessagePartProvider.d.ts.map +1 -1
  50. package/dist/context/providers/TextMessagePartProvider.js +11 -13
  51. package/dist/context/providers/TextMessagePartProvider.js.map +1 -1
  52. package/dist/context/providers/ThreadListItemProvider.d.ts.map +1 -1
  53. package/dist/context/providers/ThreadListItemProvider.js +41 -45
  54. package/dist/context/providers/ThreadListItemProvider.js.map +1 -1
  55. package/dist/context/react/AssistantApiContext.d.ts +33 -4
  56. package/dist/context/react/AssistantApiContext.d.ts.map +1 -1
  57. package/dist/context/react/AssistantApiContext.js +35 -17
  58. package/dist/context/react/AssistantApiContext.js.map +1 -1
  59. package/dist/context/react/index.d.ts +1 -1
  60. package/dist/context/react/index.d.ts.map +1 -1
  61. package/dist/context/react/index.js +5 -1
  62. package/dist/context/react/index.js.map +1 -1
  63. package/dist/legacy-runtime/AssistantRuntimeProvider.d.ts.map +1 -1
  64. package/dist/legacy-runtime/AssistantRuntimeProvider.js +7 -9
  65. package/dist/legacy-runtime/AssistantRuntimeProvider.js.map +1 -1
  66. package/dist/legacy-runtime/RuntimeAdapter.d.ts +7 -0
  67. package/dist/legacy-runtime/RuntimeAdapter.d.ts.map +1 -0
  68. package/dist/legacy-runtime/RuntimeAdapter.js +20 -0
  69. package/dist/legacy-runtime/RuntimeAdapter.js.map +1 -0
  70. package/dist/legacy-runtime/client/ThreadListRuntimeClient.d.ts +2 -0
  71. package/dist/legacy-runtime/client/ThreadListRuntimeClient.d.ts.map +1 -1
  72. package/dist/legacy-runtime/client/ThreadListRuntimeClient.js +6 -2
  73. package/dist/legacy-runtime/client/ThreadListRuntimeClient.js.map +1 -1
  74. package/dist/legacy-runtime/hooks/AssistantContext.d.ts +14 -1
  75. package/dist/legacy-runtime/hooks/AssistantContext.d.ts.map +1 -1
  76. package/dist/legacy-runtime/hooks/AssistantContext.js +1 -1
  77. package/dist/legacy-runtime/hooks/AssistantContext.js.map +1 -1
  78. package/dist/legacy-runtime/hooks/AttachmentContext.d.ts +6 -0
  79. package/dist/legacy-runtime/hooks/AttachmentContext.d.ts.map +1 -1
  80. package/dist/legacy-runtime/hooks/AttachmentContext.js.map +1 -1
  81. package/dist/legacy-runtime/hooks/ComposerContext.d.ts +41 -2
  82. package/dist/legacy-runtime/hooks/ComposerContext.d.ts.map +1 -1
  83. package/dist/legacy-runtime/hooks/ComposerContext.js.map +1 -1
  84. package/dist/legacy-runtime/hooks/MessageContext.d.ts +36 -2
  85. package/dist/legacy-runtime/hooks/MessageContext.d.ts.map +1 -1
  86. package/dist/legacy-runtime/hooks/MessageContext.js.map +1 -1
  87. package/dist/legacy-runtime/hooks/MessagePartContext.d.ts +6 -0
  88. package/dist/legacy-runtime/hooks/MessagePartContext.d.ts.map +1 -1
  89. package/dist/legacy-runtime/hooks/MessagePartContext.js.map +1 -1
  90. package/dist/legacy-runtime/hooks/ThreadContext.d.ts +26 -1
  91. package/dist/legacy-runtime/hooks/ThreadContext.d.ts.map +1 -1
  92. package/dist/legacy-runtime/hooks/ThreadContext.js.map +1 -1
  93. package/dist/legacy-runtime/hooks/ThreadListItemContext.d.ts +6 -0
  94. package/dist/legacy-runtime/hooks/ThreadListItemContext.d.ts.map +1 -1
  95. package/dist/legacy-runtime/hooks/ThreadListItemContext.js.map +1 -1
  96. package/dist/legacy-runtime/runtime-cores/assistant-transport/index.d.ts +2 -2
  97. package/dist/legacy-runtime/runtime-cores/assistant-transport/index.d.ts.map +1 -1
  98. package/dist/legacy-runtime/runtime-cores/assistant-transport/index.js +4 -2
  99. package/dist/legacy-runtime/runtime-cores/assistant-transport/index.js.map +1 -1
  100. package/dist/legacy-runtime/runtime-cores/assistant-transport/types.d.ts +2 -0
  101. package/dist/legacy-runtime/runtime-cores/assistant-transport/types.d.ts.map +1 -1
  102. package/dist/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.d.ts +3 -0
  103. package/dist/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.d.ts.map +1 -1
  104. package/dist/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.js +14 -4
  105. package/dist/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.js.map +1 -1
  106. package/dist/legacy-runtime/runtime-cores/core/AssistantRuntimeCore.d.ts +1 -0
  107. package/dist/legacy-runtime/runtime-cores/core/AssistantRuntimeCore.d.ts.map +1 -1
  108. package/dist/legacy-runtime/runtime-cores/core/BaseAssistantRuntimeCore.d.ts +1 -0
  109. package/dist/legacy-runtime/runtime-cores/core/BaseAssistantRuntimeCore.d.ts.map +1 -1
  110. package/dist/legacy-runtime/runtime-cores/core/BaseAssistantRuntimeCore.js +3 -0
  111. package/dist/legacy-runtime/runtime-cores/core/BaseAssistantRuntimeCore.js.map +1 -1
  112. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadListRuntimeCore.d.ts +4 -1
  113. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadListRuntimeCore.d.ts.map +1 -1
  114. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadListRuntimeCore.js +2 -2
  115. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadListRuntimeCore.js.map +1 -1
  116. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadRuntimeCore.d.ts.map +1 -1
  117. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadRuntimeCore.js +7 -1
  118. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadRuntimeCore.js.map +1 -1
  119. package/dist/legacy-runtime/runtime-cores/external-store/auto-status.d.ts +2 -12
  120. package/dist/legacy-runtime/runtime-cores/external-store/auto-status.d.ts.map +1 -1
  121. package/dist/legacy-runtime/runtime-cores/external-store/auto-status.js +45 -15
  122. package/dist/legacy-runtime/runtime-cores/external-store/auto-status.js.map +1 -1
  123. package/dist/legacy-runtime/runtime-cores/external-store/external-message-converter.d.ts +2 -0
  124. package/dist/legacy-runtime/runtime-cores/external-store/external-message-converter.d.ts.map +1 -1
  125. package/dist/legacy-runtime/runtime-cores/external-store/external-message-converter.js +4 -2
  126. package/dist/legacy-runtime/runtime-cores/external-store/external-message-converter.js.map +1 -1
  127. package/dist/legacy-runtime/runtime-cores/local/LocalThreadListRuntimeCore.d.ts +4 -1
  128. package/dist/legacy-runtime/runtime-cores/local/LocalThreadListRuntimeCore.d.ts.map +1 -1
  129. package/dist/legacy-runtime/runtime-cores/local/LocalThreadListRuntimeCore.js +2 -2
  130. package/dist/legacy-runtime/runtime-cores/local/LocalThreadListRuntimeCore.js.map +1 -1
  131. package/dist/legacy-runtime/runtime-cores/utils/MessageRepository.js +1 -1
  132. package/dist/legacy-runtime/runtime-cores/utils/MessageRepository.js.map +1 -1
  133. package/dist/model-context/index.d.ts +2 -0
  134. package/dist/model-context/index.d.ts.map +1 -1
  135. package/dist/model-context/index.js +6 -0
  136. package/dist/model-context/index.js.map +1 -1
  137. package/dist/model-context/makeAssistantVisible.js +1 -1
  138. package/dist/model-context/makeAssistantVisible.js.map +1 -1
  139. package/dist/model-context/toolbox.d.ts +28 -0
  140. package/dist/model-context/toolbox.d.ts.map +1 -0
  141. package/dist/model-context/toolbox.js +15 -0
  142. package/dist/model-context/toolbox.js.map +1 -0
  143. package/dist/model-context/useAssistantInstructions.js +1 -1
  144. package/dist/model-context/useAssistantInstructions.js.map +1 -1
  145. package/dist/model-context/useAssistantTool.js +1 -1
  146. package/dist/model-context/useAssistantTool.js.map +1 -1
  147. package/dist/primitives/message/MessageParts.d.ts.map +1 -1
  148. package/dist/primitives/message/MessageParts.js +2 -2
  149. package/dist/primitives/message/MessageParts.js.map +1 -1
  150. package/dist/primitives/message/MessagePartsGrouped.d.ts.map +1 -1
  151. package/dist/primitives/message/MessagePartsGrouped.js +2 -2
  152. package/dist/primitives/message/MessagePartsGrouped.js.map +1 -1
  153. package/dist/tests/setup.js +8 -11
  154. package/dist/tests/setup.js.map +1 -1
  155. package/dist/utils/tap-store/derived-scopes.d.ts +81 -0
  156. package/dist/utils/tap-store/derived-scopes.d.ts.map +1 -0
  157. package/dist/utils/tap-store/derived-scopes.js +67 -0
  158. package/dist/utils/tap-store/derived-scopes.js.map +1 -0
  159. package/dist/utils/tap-store/index.d.ts +1 -0
  160. package/dist/utils/tap-store/index.d.ts.map +1 -1
  161. package/dist/utils/tap-store/index.js +4 -0
  162. package/dist/utils/tap-store/index.js.map +1 -1
  163. package/dist/utils/tap-store/tap-api.js +1 -1
  164. package/dist/utils/tap-store/tap-api.js.map +1 -1
  165. package/package.json +9 -9
  166. package/src/augmentations.ts +12 -0
  167. package/src/client/AssistantClient.ts +64 -38
  168. package/src/client/ModelContext.ts +28 -0
  169. package/src/client/ModelContextClient.ts +16 -0
  170. package/src/client/ToolUIClient.ts +50 -3
  171. package/src/client/ToolUIContext.ts +22 -0
  172. package/src/client/Tools.ts +68 -0
  173. package/src/client/types/ModelContext.ts +15 -0
  174. package/src/client/types/ThreadList.ts +4 -0
  175. package/src/client/types/ToolUI.ts +10 -1
  176. package/src/client/types/Tools.ts +11 -0
  177. package/src/context/providers/AttachmentByIndexProvider.tsx +21 -25
  178. package/src/context/providers/MessageByIndexProvider.tsx +31 -33
  179. package/src/context/providers/MessageProvider.tsx +12 -14
  180. package/src/context/providers/PartByIndexProvider.tsx +12 -14
  181. package/src/context/providers/TextMessagePartProvider.tsx +12 -14
  182. package/src/context/providers/ThreadListItemProvider.tsx +42 -46
  183. package/src/context/react/AssistantApiContext.tsx +69 -29
  184. package/src/context/react/index.ts +5 -1
  185. package/src/legacy-runtime/AssistantRuntimeProvider.tsx +7 -9
  186. package/src/legacy-runtime/RuntimeAdapter.ts +19 -0
  187. package/src/legacy-runtime/client/ThreadListRuntimeClient.ts +10 -1
  188. package/src/legacy-runtime/hooks/AssistantContext.ts +16 -2
  189. package/src/legacy-runtime/hooks/AttachmentContext.ts +6 -0
  190. package/src/legacy-runtime/hooks/ComposerContext.ts +41 -2
  191. package/src/legacy-runtime/hooks/MessageContext.ts +37 -2
  192. package/src/legacy-runtime/hooks/MessagePartContext.ts +6 -0
  193. package/src/legacy-runtime/hooks/ThreadContext.ts +27 -1
  194. package/src/legacy-runtime/hooks/ThreadListItemContext.ts +6 -0
  195. package/src/legacy-runtime/runtime-cores/assistant-transport/index.ts +2 -0
  196. package/src/legacy-runtime/runtime-cores/assistant-transport/types.ts +3 -0
  197. package/src/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.tsx +35 -14
  198. package/src/legacy-runtime/runtime-cores/core/AssistantRuntimeCore.tsx +1 -0
  199. package/src/legacy-runtime/runtime-cores/core/BaseAssistantRuntimeCore.tsx +4 -0
  200. package/src/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadListRuntimeCore.tsx +4 -2
  201. package/src/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadRuntimeCore.tsx +7 -1
  202. package/src/legacy-runtime/runtime-cores/external-store/auto-status.tsx +49 -16
  203. package/src/legacy-runtime/runtime-cores/external-store/external-message-converter.tsx +4 -0
  204. package/src/legacy-runtime/runtime-cores/local/LocalThreadListRuntimeCore.tsx +4 -2
  205. package/src/legacy-runtime/runtime-cores/utils/MessageRepository.tsx +1 -1
  206. package/src/model-context/index.ts +9 -0
  207. package/src/model-context/makeAssistantVisible.tsx +1 -1
  208. package/src/model-context/toolbox.tsx +37 -0
  209. package/src/model-context/useAssistantInstructions.tsx +1 -1
  210. package/src/model-context/useAssistantTool.tsx +1 -1
  211. package/src/primitives/message/MessageParts.tsx +3 -2
  212. package/src/primitives/message/MessagePartsGrouped.tsx +3 -2
  213. package/src/tests/setup.ts +2 -8
  214. package/src/utils/tap-store/derived-scopes.ts +185 -0
  215. package/src/utils/tap-store/index.ts +9 -0
  216. 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,7 +1,11 @@
1
1
  // src/utils/tap-store/index.ts
2
2
  import { asStore } from "./store.js";
3
3
  import { tapApi } from "./tap-api.js";
4
+ import {
5
+ DerivedScope
6
+ } from "./derived-scopes.js";
4
7
  export {
8
+ DerivedScope,
5
9
  asStore,
6
10
  tapApi
7
11
  };
@@ -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":[]}
@@ -27,7 +27,7 @@ var ReadonlyApiHandler = class {
27
27
  }
28
28
  };
29
29
  var tapApi = (api, options) => {
30
- const ref = tapRef(() => api);
30
+ const ref = tapRef(api);
31
31
  tapEffect(() => {
32
32
  ref.current = api;
33
33
  });
@@ -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(() => 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,MAAM,GAAG;AAC5B,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":[]}
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.34",
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.5",
52
- "@assistant-ui/tap": "^0.1.4",
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.37",
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.2.0",
85
- "@stryker-mutator/vitest-runner": "^9.2.0",
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.9.1",
87
+ "@types/node": "^24.10.0",
88
88
  "eslint": "^9",
89
- "eslint-config-next": "16.0.0",
89
+ "eslint-config-next": "16.0.1",
90
90
  "tsx": "^4.20.6",
91
- "vitest": "^4.0.1",
91
+ "vitest": "^4.0.6",
92
92
  "@assistant-ui/x-buildutils": "0.0.1"
93
93
  },
94
94
  "publishConfig": {
@@ -11,6 +11,12 @@
11
11
  * data: string;
12
12
  * };
13
13
  * }
14
+ *
15
+ * interface ExternalState {
16
+ * myCustomState: {
17
+ * foo: string;
18
+ * };
19
+ * }
14
20
  * }
15
21
  * }
16
22
  * ```
@@ -18,6 +24,12 @@
18
24
  export namespace Assistant {
19
25
  // eslint-disable-next-line @typescript-eslint/no-empty-object-type
20
26
  export interface Commands {}
27
+
28
+ // eslint-disable-next-line @typescript-eslint/no-empty-object-type
29
+ export interface ExternalState {}
21
30
  }
22
31
 
23
32
  export type UserCommands = Assistant.Commands[keyof Assistant.Commands];
33
+ export type UserExternalState = keyof Assistant.ExternalState extends never
34
+ ? Record<string, unknown>
35
+ : Assistant.ExternalState[keyof Assistant.ExternalState];
@@ -7,8 +7,7 @@ import {
7
7
  tapResource,
8
8
  } from "@assistant-ui/tap";
9
9
  import { ThreadListClientApi, ThreadListClientState } from "./types/ThreadList";
10
- import { AssistantRuntime } from "../legacy-runtime/runtime/AssistantRuntime";
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
- registerModelContextProvider,
56
- __internal_runtime,
60
+ modelContext: modelContextEl,
61
+ tools: toolsEl,
57
62
  }: AssistantClientProps) => {
58
63
  const events = tapInlineResource(EventManager());
59
-
60
- const { threads, toolUIs } = withEventsProvider(events, () => {
61
- return {
62
- toolUIs: tapInlineResource(ToolUIClient()),
63
- threads: tapResource(threadsEl, [threadsEl]),
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
- registerModelContextProvider?: (
159
- provider: ModelContextProvider,
160
- ) => Unsubscribe;
161
-
162
- /** @internal */
163
- __internal_runtime?: AssistantRuntime;
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
- return useMemo(() => getClientFromStore(client), [client]);
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
- [toolName]: [...(prev[toolName] ?? []), render],
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
- [toolName]: prev[toolName]?.filter((r) => r !== render) ?? [],
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
+ };