gemi 0.59.0 → 0.61.0

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 (237) hide show
  1. package/dist/ai/Agent.d.ts +533 -25
  2. package/dist/ai/Agent.d.ts.map +1 -1
  3. package/dist/ai/Agent.test-d.d.ts +2 -0
  4. package/dist/ai/Agent.test-d.d.ts.map +1 -0
  5. package/dist/ai/AgentController.d.ts +275 -6
  6. package/dist/ai/AgentController.d.ts.map +1 -1
  7. package/dist/ai/AgentProvider.d.ts +255 -0
  8. package/dist/ai/AgentProvider.d.ts.map +1 -0
  9. package/dist/ai/Schema.d.ts +125 -0
  10. package/dist/ai/Schema.d.ts.map +1 -0
  11. package/dist/ai/Schema.test-d.d.ts +2 -0
  12. package/dist/ai/Schema.test-d.d.ts.map +1 -0
  13. package/dist/ai/client/index.d.ts +24 -0
  14. package/dist/ai/client/index.d.ts.map +1 -0
  15. package/dist/ai/client/index.js +1053 -0
  16. package/dist/ai/client/index.js.map +1 -0
  17. package/dist/ai/client/reducer.d.ts +127 -0
  18. package/dist/ai/client/reducer.d.ts.map +1 -0
  19. package/dist/ai/client/reducer.test-d.d.ts +2 -0
  20. package/dist/ai/client/reducer.test-d.d.ts.map +1 -0
  21. package/dist/ai/client/sse.d.ts +54 -0
  22. package/dist/ai/client/sse.d.ts.map +1 -0
  23. package/dist/ai/example.d.ts +129 -0
  24. package/dist/ai/example.d.ts.map +1 -0
  25. package/dist/ai/index.d.ts +35 -0
  26. package/dist/ai/index.d.ts.map +1 -0
  27. package/dist/ai/index.js +20 -0
  28. package/dist/ai/index.js.map +23 -0
  29. package/dist/ai/live/harness.d.ts +137 -0
  30. package/dist/ai/live/harness.d.ts.map +1 -0
  31. package/dist/ai/providers/call.d.ts +42 -0
  32. package/dist/ai/providers/call.d.ts.map +1 -0
  33. package/dist/ai/providers/capabilities.d.ts +50 -0
  34. package/dist/ai/providers/capabilities.d.ts.map +1 -0
  35. package/dist/ai/providers/errors.d.ts +37 -0
  36. package/dist/ai/providers/errors.d.ts.map +1 -0
  37. package/dist/ai/providers/fakeProvider.d.ts +35 -0
  38. package/dist/ai/providers/fakeProvider.d.ts.map +1 -0
  39. package/dist/ai/providers/http.d.ts +46 -0
  40. package/dist/ai/providers/http.d.ts.map +1 -0
  41. package/dist/ai/providers/request.d.ts +69 -0
  42. package/dist/ai/providers/request.d.ts.map +1 -0
  43. package/dist/ai/providers/stream.d.ts +42 -0
  44. package/dist/ai/providers/stream.d.ts.map +1 -0
  45. package/dist/ai/signing.d.ts +195 -0
  46. package/dist/ai/signing.d.ts.map +1 -0
  47. package/dist/ai/store/LiveRuns.d.ts +142 -0
  48. package/dist/ai/store/LiveRuns.d.ts.map +1 -0
  49. package/dist/ai/store/MemoryAgentStore.d.ts +61 -0
  50. package/dist/ai/store/MemoryAgentStore.d.ts.map +1 -0
  51. package/dist/ai/store/index.d.ts +4 -0
  52. package/dist/ai/store/index.d.ts.map +1 -0
  53. package/dist/ai/store/sse.d.ts +58 -0
  54. package/dist/ai/store/sse.d.ts.map +1 -0
  55. package/dist/ai/store/stubAgentRun.d.ts +56 -0
  56. package/dist/ai/store/stubAgentRun.d.ts.map +1 -0
  57. package/dist/ai/types.d.ts +443 -0
  58. package/dist/ai/types.d.ts.map +1 -0
  59. package/dist/ai/useChat.d.ts +253 -7
  60. package/dist/ai/useChat.d.ts.map +1 -1
  61. package/dist/bin/gemi.js +500 -16
  62. package/dist/bin/gemi.js.map +10 -5
  63. package/dist/chunk-1aqzcgfr.js +5 -0
  64. package/dist/chunk-1aqzcgfr.js.map +10 -0
  65. package/dist/{chunk-get4mkx8.js → chunk-1b7e9rj7.js} +2 -2
  66. package/dist/{chunk-get4mkx8.js.map → chunk-1b7e9rj7.js.map} +1 -1
  67. package/dist/{chunk-gfma8e03.js → chunk-3aemqfdr.js} +2 -2
  68. package/dist/{chunk-gfma8e03.js.map → chunk-3aemqfdr.js.map} +1 -1
  69. package/dist/{chunk-j06g4sqc.js → chunk-528n3vgy.js} +2 -2
  70. package/dist/{chunk-j06g4sqc.js.map → chunk-528n3vgy.js.map} +1 -1
  71. package/dist/{chunk-2khdxyjb.js → chunk-57a0nqfj.js} +1 -1
  72. package/dist/chunk-57a0nqfj.js.map +10 -0
  73. package/dist/{chunk-c40n5r4v.js → chunk-5mhcwnyd.js} +2 -2
  74. package/dist/{chunk-c40n5r4v.js.map → chunk-5mhcwnyd.js.map} +1 -1
  75. package/dist/{chunk-gwchvzdp.js → chunk-71pk1mxx.js} +2 -2
  76. package/dist/{chunk-gwchvzdp.js.map → chunk-71pk1mxx.js.map} +1 -1
  77. package/dist/{chunk-spbgpndn.js → chunk-7t1hjs9f.js} +2 -2
  78. package/dist/{chunk-spbgpndn.js.map → chunk-7t1hjs9f.js.map} +1 -1
  79. package/dist/{chunk-9gsdcjt7.js → chunk-7xvaace2.js} +3 -3
  80. package/dist/{chunk-9gsdcjt7.js.map → chunk-7xvaace2.js.map} +1 -1
  81. package/dist/{chunk-fxy42w6n.js → chunk-8ag0da2s.js} +2 -2
  82. package/dist/{chunk-fxy42w6n.js.map → chunk-8ag0da2s.js.map} +1 -1
  83. package/dist/chunk-8r8epsef.js +5 -0
  84. package/dist/chunk-8r8epsef.js.map +11 -0
  85. package/dist/chunk-91cj3nxk.js +6 -0
  86. package/dist/{chunk-txhcx69q.js.map → chunk-91cj3nxk.js.map} +2 -2
  87. package/dist/{chunk-0fm6jh9b.js → chunk-9nmvm20t.js} +2 -2
  88. package/dist/{chunk-0fm6jh9b.js.map → chunk-9nmvm20t.js.map} +1 -1
  89. package/dist/{chunk-98a3k7bp.js → chunk-9xpa7dpy.js} +2 -2
  90. package/dist/{chunk-98a3k7bp.js.map → chunk-9xpa7dpy.js.map} +1 -1
  91. package/dist/{chunk-qva4841r.js → chunk-a1exbqcq.js} +3 -3
  92. package/dist/{chunk-qva4841r.js.map → chunk-a1exbqcq.js.map} +1 -1
  93. package/dist/{chunk-cw9y6k15.js → chunk-bb19bwg6.js} +2 -2
  94. package/dist/{chunk-cw9y6k15.js.map → chunk-bb19bwg6.js.map} +1 -1
  95. package/dist/{chunk-3gvjn3q4.js → chunk-cf7bvd12.js} +1 -1
  96. package/dist/{chunk-rkbv3df7.js → chunk-djp2xeqe.js} +2 -2
  97. package/dist/{chunk-rkbv3df7.js.map → chunk-djp2xeqe.js.map} +1 -1
  98. package/dist/chunk-ds44bqr9.js +4 -0
  99. package/dist/{chunk-4mcyyh1v.js.map → chunk-ds44bqr9.js.map} +4 -9
  100. package/dist/{chunk-wzvs3sym.js → chunk-exndjhza.js} +3 -3
  101. package/dist/{chunk-wzvs3sym.js.map → chunk-exndjhza.js.map} +1 -1
  102. package/dist/{chunk-f6dd4gd8.js → chunk-f233yzxf.js} +2 -2
  103. package/dist/{chunk-f6dd4gd8.js.map → chunk-f233yzxf.js.map} +1 -1
  104. package/dist/chunk-fz5g2z6h.js +4 -0
  105. package/dist/{chunk-fbvvqf9b.js.map → chunk-fz5g2z6h.js.map} +2 -2
  106. package/dist/{chunk-vj9538yn.js → chunk-gcszdwcb.js} +2 -2
  107. package/dist/{chunk-vj9538yn.js.map → chunk-gcszdwcb.js.map} +1 -1
  108. package/dist/{chunk-pkjq9833.js → chunk-htesx7ym.js} +4 -4
  109. package/dist/{chunk-pkjq9833.js.map → chunk-htesx7ym.js.map} +1 -1
  110. package/dist/chunk-hyxmmj9b.js +5 -0
  111. package/dist/{chunk-n412aa9s.js.map → chunk-hyxmmj9b.js.map} +2 -2
  112. package/dist/{chunk-stq96kya.js → chunk-k2sjvt0c.js} +2 -2
  113. package/dist/{chunk-stq96kya.js.map → chunk-k2sjvt0c.js.map} +1 -1
  114. package/dist/{chunk-zhbrkpb3.js → chunk-k75phgj4.js} +4 -4
  115. package/dist/{chunk-zhbrkpb3.js.map → chunk-k75phgj4.js.map} +1 -1
  116. package/dist/{chunk-y64j80v9.js → chunk-m0tp7zjp.js} +2 -2
  117. package/dist/{chunk-y64j80v9.js.map → chunk-m0tp7zjp.js.map} +1 -1
  118. package/dist/{chunk-06j6rsew.js → chunk-m45j7p1y.js} +2 -2
  119. package/dist/{chunk-06j6rsew.js.map → chunk-m45j7p1y.js.map} +1 -1
  120. package/dist/chunk-mca9wsvs.js +5 -0
  121. package/dist/{chunk-z2tcxwyr.js.map → chunk-mca9wsvs.js.map} +3 -4
  122. package/dist/{chunk-tey1xayb.js → chunk-ms13evzp.js} +2 -2
  123. package/dist/{chunk-tey1xayb.js.map → chunk-ms13evzp.js.map} +1 -1
  124. package/dist/{chunk-bn1v4sfs.js → chunk-r962ae93.js} +2 -2
  125. package/dist/{chunk-bn1v4sfs.js.map → chunk-r962ae93.js.map} +1 -1
  126. package/dist/{chunk-23h0dmx2.js → chunk-s41ees18.js} +2 -2
  127. package/dist/{chunk-23h0dmx2.js.map → chunk-s41ees18.js.map} +1 -1
  128. package/dist/chunk-snb68dgr.js +4 -0
  129. package/dist/{chunk-hwhw98hc.js.map → chunk-snb68dgr.js.map} +1 -1
  130. package/dist/chunk-sz051605.js +5 -0
  131. package/dist/chunk-sz051605.js.map +14 -0
  132. package/dist/{chunk-2cwcfwg3.js → chunk-tr3cbx8k.js} +2 -2
  133. package/dist/{chunk-2cwcfwg3.js.map → chunk-tr3cbx8k.js.map} +2 -2
  134. package/dist/{chunk-dgasxgsm.js → chunk-vqcswg7h.js} +2 -2
  135. package/dist/{chunk-dgasxgsm.js.map → chunk-vqcswg7h.js.map} +2 -2
  136. package/dist/{chunk-zqsfanvk.js → chunk-wpb1xpdp.js} +2 -2
  137. package/dist/{chunk-zqsfanvk.js.map → chunk-wpb1xpdp.js.map} +1 -1
  138. package/dist/{chunk-z1e55w67.js → chunk-ybqss0jy.js} +2 -2
  139. package/dist/{chunk-z1e55w67.js.map → chunk-ybqss0jy.js.map} +1 -1
  140. package/dist/{chunk-cejf873g.js → chunk-yk5wqmyh.js} +2 -2
  141. package/dist/{chunk-cejf873g.js.map → chunk-yk5wqmyh.js.map} +1 -1
  142. package/dist/{chunk-8kj3zrm9.js → chunk-ywntv8yw.js} +4 -4
  143. package/dist/{chunk-8kj3zrm9.js.map → chunk-ywntv8yw.js.map} +1 -1
  144. package/dist/chunks/{ThemeProvider-ByU4BQdL.js → ThemeProvider-BZ2SsSZ3.js} +60 -39
  145. package/dist/chunks/ThemeProvider-BZ2SsSZ3.js.map +1 -0
  146. package/dist/chunks/useParams-BN3XXfmG.js +20 -0
  147. package/dist/chunks/useParams-BN3XXfmG.js.map +1 -0
  148. package/dist/client/index.js +3 -3
  149. package/dist/client/index.js.map +1 -1
  150. package/dist/client/useDictionary.d.ts.map +1 -1
  151. package/dist/config/index.d.ts +2 -0
  152. package/dist/config/index.d.ts.map +1 -1
  153. package/dist/config/index.js +2 -2
  154. package/dist/config/index.js.map +3 -3
  155. package/dist/database/index.js +1 -1
  156. package/dist/facades/index.js +2 -2
  157. package/dist/facades/index.js.map +1 -1
  158. package/dist/http/ApiRouter.d.ts +30 -2
  159. package/dist/http/ApiRouter.d.ts.map +1 -1
  160. package/dist/http/index.js +2 -2
  161. package/dist/http/index.js.map +1 -1
  162. package/dist/i18n/defineDictionary.d.ts +7 -4
  163. package/dist/i18n/defineDictionary.d.ts.map +1 -1
  164. package/dist/i18n/dictionaryRegistry.d.ts +38 -14
  165. package/dist/i18n/dictionaryRegistry.d.ts.map +1 -1
  166. package/dist/i18n/dictionaryRuntime.js +1 -1
  167. package/dist/i18n/index.js +2 -2
  168. package/dist/i18n/index.js.map +2 -2
  169. package/dist/kernel/index.js +2 -2
  170. package/dist/kernel/index.js.map +2 -2
  171. package/dist/orm/index.js +2 -2
  172. package/dist/orm/index.js.map +2 -2
  173. package/dist/server/index.js +1 -1
  174. package/dist/services/index.js +2 -2
  175. package/dist/services/index.js.map +2 -2
  176. package/dist/testing/index.js +2 -1
  177. package/dist/testing/index.js.map +1 -1
  178. package/package.json +5 -2
  179. package/skills/gemi-react-best-practices/SKILL.md +231 -0
  180. package/skills/gemi-react-best-practices/rules/_sections.md +56 -0
  181. package/skills/gemi-react-best-practices/rules/_template.md +28 -0
  182. package/skills/gemi-react-best-practices/rules/bundle-deep-imports.md +48 -0
  183. package/skills/gemi-react-best-practices/rules/bundle-mount-gate-heavy-panels.md +63 -0
  184. package/skills/gemi-react-best-practices/rules/client-form-vs-mutation-hooks.md +57 -0
  185. package/skills/gemi-react-best-practices/rules/client-loading-error-exports.md +54 -0
  186. package/skills/gemi-react-best-practices/rules/client-no-effect-data-flow.md +68 -0
  187. package/skills/gemi-react-best-practices/rules/client-typed-links.md +51 -0
  188. package/skills/gemi-react-best-practices/rules/controller-authorize-every-tenant-read.md +65 -0
  189. package/skills/gemi-react-best-practices/rules/controller-parse-request-at-the-boundary.md +54 -0
  190. package/skills/gemi-react-best-practices/rules/controller-redirect-facade-throws.md +68 -0
  191. package/skills/gemi-react-best-practices/rules/controller-request-schema.md +61 -0
  192. package/skills/gemi-react-best-practices/rules/controller-throw-framework-errors.md +57 -0
  193. package/skills/gemi-react-best-practices/rules/i18n-define-dictionary-inline.md +58 -0
  194. package/skills/gemi-react-best-practices/rules/orm-analytics-connection.md +53 -0
  195. package/skills/gemi-react-best-practices/rules/orm-include-not-n-plus-one.md +56 -0
  196. package/skills/gemi-react-best-practices/rules/orm-paginate-helper.md +69 -0
  197. package/skills/gemi-react-best-practices/rules/orm-plain-rows-by-default.md +55 -0
  198. package/skills/gemi-react-best-practices/rules/orm-select-narrow.md +58 -0
  199. package/skills/gemi-react-best-practices/rules/orm-transaction-no-io.md +54 -0
  200. package/skills/gemi-react-best-practices/rules/orm-transaction-sequential.md +64 -0
  201. package/skills/gemi-react-best-practices/rules/payload-dont-overprefetch.md +54 -0
  202. package/skills/gemi-react-best-practices/rules/payload-instant-vs-prefetch.md +58 -0
  203. package/skills/gemi-react-best-practices/rules/payload-minimal-view-props.md +51 -0
  204. package/skills/gemi-react-best-practices/rules/payload-parallel-controller-work.md +56 -0
  205. package/skills/gemi-react-best-practices/rules/payload-prefetch-late-queries.md +58 -0
  206. package/skills/gemi-react-best-practices/rules/payload-prefetch-mirrors-usequery.md +52 -0
  207. package/skills/gemi-react-best-practices/rules/query-debounce-search-variant.md +52 -0
  208. package/skills/gemi-react-best-practices/rules/query-keep-previous-data.md +40 -0
  209. package/skills/gemi-react-best-practices/rules/query-lazy-vs-mount-gate.md +54 -0
  210. package/skills/gemi-react-best-practices/rules/query-mutate-over-refetch.md +55 -0
  211. package/skills/gemi-react-best-practices/rules/query-no-hand-rolled-fetch.md +60 -0
  212. package/skills/gemi-react-best-practices/rules/query-revalidate-on-focus.md +44 -0
  213. package/skills/gemi-react-best-practices/rules/query-share-cache-key.md +51 -0
  214. package/skills/gemi-react-best-practices/rules/query-suspense-default.md +52 -0
  215. package/skills/gemi-react-best-practices/rules/routing-cache-policy-constants.md +53 -0
  216. package/skills/gemi-react-best-practices/rules/routing-middleware-dsl.md +60 -0
  217. package/skills/gemi-react-best-practices/rules/routing-resource-routes.md +59 -0
  218. package/skills/gemi-react-best-practices/rules/routing-routers-are-classes.md +55 -0
  219. package/skills/gemi-react-best-practices/rules/service-lazy-not-module-scope.md +63 -0
  220. package/skills/gemi-react-best-practices/rules/service-queue-is-in-memory.md +52 -0
  221. package/skills/gemi-react-best-practices/rules/service-static-token-and-name.md +52 -0
  222. package/skills/gemi-react-best-practices/rules/structure-discovered-vs-registered.md +71 -0
  223. package/skills/gemi-react-best-practices/rules/structure-do-not-reinvent-the-framework.md +58 -0
  224. package/skills/gemi-react-best-practices/rules/testing-assert-behaviour-over-markup.md +54 -0
  225. package/skills/gemi-react-best-practices/rules/testing-match-the-suite.md +57 -0
  226. package/skills/gemi-react-best-practices/rules/testing-page-seeds-real-inputs.md +65 -0
  227. package/dist/chunk-2khdxyjb.js.map +0 -10
  228. package/dist/chunk-4mcyyh1v.js +0 -4
  229. package/dist/chunk-fbvvqf9b.js +0 -4
  230. package/dist/chunk-hwhw98hc.js +0 -4
  231. package/dist/chunk-n412aa9s.js +0 -5
  232. package/dist/chunk-q0y0j3ne.js +0 -5
  233. package/dist/chunk-q0y0j3ne.js.map +0 -11
  234. package/dist/chunk-txhcx69q.js +0 -6
  235. package/dist/chunk-z2tcxwyr.js +0 -5
  236. package/dist/chunks/ThemeProvider-ByU4BQdL.js.map +0 -1
  237. /package/dist/{chunk-3gvjn3q4.js.map → chunk-cf7bvd12.js.map} +0 -0
@@ -1,12 +1,258 @@
1
- type Agent = {};
2
- interface UseChatParams {
3
- agent: Agent;
1
+ import type { RPC } from "../client/rpc";
2
+ import type { AgentError, AgentMessage, ClientTurn, PendingToolCall, ToolShapes } from "./types";
3
+ /**
4
+ * The agent routes, picked out of the same `RPC` interface `useQuery` and
5
+ * `useMutation` read. An agent is not a second kind of thing to register — it is
6
+ * a route, so its key is its path and its types arrive the way every other
7
+ * route's types do.
8
+ */
9
+ type AgentRoutes = {
10
+ [K in keyof RPC as RPC[K] extends {
11
+ __agent: true;
12
+ } ? K : never]: RPC[K];
13
+ };
14
+ type ToolsOf<P extends keyof AgentRoutes> = AgentRoutes[P] extends {
15
+ tools: infer T;
16
+ } ? T extends ToolShapes ? T : ToolShapes : ToolShapes;
17
+ type OutputOf<P extends keyof AgentRoutes> = AgentRoutes[P] extends {
18
+ output: infer O;
19
+ } ? O : unknown;
20
+ /**
21
+ * What the UI is waiting on.
22
+ *
23
+ * `awaiting-input` is its own state rather than a flavour of idle: the run is
24
+ * over, but the conversation is holding a question, and a UI that cannot tell
25
+ * the difference will either look hung or look finished.
26
+ */
27
+ export type ChatStatus = "idle" | "submitted" | "streaming" | "awaiting-input" | "error";
28
+ export interface UseChatParams<P extends keyof AgentRoutes> {
29
+ /** Continues a server-side thread. Omitted, the hook keeps history itself and
30
+ * sends it with each request — the stateless default.
31
+ *
32
+ * The id is the store's, not the client's: an app route calls
33
+ * `store.createThread` and hands the result to this hook, and an id the
34
+ * store never minted — or has since expired — is a `thread_not_found` error
35
+ * on the first turn. Only a store built with client-owned ids
36
+ * (`new MemoryAgentStore({ clientOwnedIds: true })`) takes one the client
37
+ * made up. */
38
+ threadId?: string;
39
+ /** Server-rendered or restored history. */
40
+ initialMessages?: AgentMessage<ToolsOf<P>, OutputOf<P>>[];
41
+ /**
42
+ * Where the client that produced `initialMessages` left off, so `/attach` can
43
+ * be asked for the tail rather than the whole run.
44
+ *
45
+ * Without it the hook has to say "I have seen nothing", and a run kept alive
46
+ * past `run-end` — which `LiveRuns` does on purpose, so a refresh a second
47
+ * late still sees the ending — replays from the top onto a transcript that
48
+ * already has it. Take it from `cursor` on the previous mount and persist it
49
+ * beside the messages; the two belong together, and restoring one without the
50
+ * other is what produces a doubled answer.
51
+ *
52
+ * `runId` is half of it rather than decoration: frames number from zero in
53
+ * every run, so a bare number cannot say whether it describes the run that is
54
+ * live now. Given both, the server resumes when they match and replays from
55
+ * the start when they do not.
56
+ */
57
+ cursor?: {
58
+ runId: string;
59
+ seq: number;
60
+ };
61
+ /**
62
+ * On mount, ask whether a run is still going on this thread and pick it back
63
+ * up from where this client left off. Needs a `threadId` — that is the handle
64
+ * that survives a refresh, which is why the client is never asked to stash a
65
+ * `runId` of its own. Defaults to true.
66
+ */
67
+ attach?: boolean;
68
+ /** Merged into the request body, for anything the agent's controller reads
69
+ * off the request that is not a message. */
70
+ body?: Record<string, unknown>;
71
+ headers?: Record<string, string>;
72
+ onFinish?: (message: AgentMessage<ToolsOf<P>, OutputOf<P>>) => void;
73
+ onError?: (error: AgentError) => void;
74
+ onAwaitingInput?: (pending: PendingToolCall<ToolsOf<P>>[]) => void;
75
+ /**
76
+ * The mount probe found no run to attach to.
77
+ *
78
+ * On one server this means what it says, and there is nothing to do. On more
79
+ * than one it is ambiguous in a way neither end can resolve: a run lives in
80
+ * the process that started it, `find` only ever searches that process, and a
81
+ * refresh routed to a different instance gets the same answer as a thread
82
+ * with nothing running. The server cannot tell the two apart, so it does not
83
+ * pretend to.
84
+ *
85
+ * What an app can do is re-read the thread — the run is still going wherever
86
+ * it is, and its messages land in the store when it finishes, so refetching
87
+ * shows the answer that the stream would have shown arriving. Without this
88
+ * the client simply sits on its own history, and the reply appears only when
89
+ * something else happens to reload it.
90
+ *
91
+ * The better fix is upstream: route a session to one instance (on Azure App
92
+ * Service that is ARR affinity, which is on by default) so the refresh lands
93
+ * where its run is. This is the fallback for when it does not — a scale-in,
94
+ * a new device, a cleared cookie.
95
+ */
96
+ onAttachMiss?: (params: {
97
+ threadId: string;
98
+ }) => void;
4
99
  }
5
- interface MessagePayload {
100
+ export interface UseChatResult<P extends keyof AgentRoutes> {
101
+ /**
102
+ * The transcript, tools and all.
103
+ *
104
+ * A `tool-call` part narrows on `name`, and with it `input`, `output` and
105
+ * `progress` — the tool's own yields, in order, typed by what its `execute`
106
+ * yields rather than as `unknown`. `nested` on that same part holds the
107
+ * sub-agent runs the tool drove, each an ordinary `AgentMessage[]` with a
108
+ * name and a label, so a component walks into it and renders it with whatever
109
+ * it already renders `messages` with:
110
+ *
111
+ * {part.type === "tool-call" && part.nested?.map((run) => (
112
+ * <Transcript key={run.runId} title={run.label ?? run.agent} messages={run.messages} />
113
+ * ))}
114
+ *
115
+ * Those inner messages are typed with the default `ToolShapes`, not this
116
+ * route's: a sub-agent's tools are its own, and typing its transcript with
117
+ * the parent's tool names would be a lie the compiler tells.
118
+ */
119
+ messages: AgentMessage<ToolsOf<P>, OutputOf<P>>[];
120
+ status: ChatStatus;
121
+ /** Cleared by the next successful send, so a retry does not have to clear it. */
122
+ error: AgentError | null;
123
+ /** Set once the server has assigned one. */
124
+ threadId?: string;
125
+ /** The run being streamed or attached to, if any. */
126
+ runId?: string;
127
+ /**
128
+ * How far this client has got, to hand back as `cursor` on the next mount.
129
+ *
130
+ * Persist it with `messages`: a restored transcript whose cursor was not
131
+ * restored asks `/attach` for a run it already has, and additive deltas
132
+ * arriving a second time are how an answer ends up printed twice. `runId` is
133
+ * undefined until a run has named itself, and the pair is meaningless until
134
+ * then — there is nothing to resume.
135
+ */
136
+ cursor: {
137
+ runId?: string;
138
+ seq: number;
139
+ };
140
+ /**
141
+ * The one way to advance the conversation. A string is shorthand for
142
+ * `{ text }`; answers to pending calls go in the same turn, and may travel
143
+ * with text.
144
+ */
145
+ sendMessage(turn: ClientTurn | string): Promise<void>;
146
+ /**
147
+ * Explicit cancel — a closed tab no longer stops a run, so this is what does.
148
+ *
149
+ * The UI stops immediately; the server call is what actually ends the
150
+ * generation and any tool mid-flight. `messages` keeps the interrupted turn
151
+ * with everything it had produced, marked `aborted`, so the transcript shows
152
+ * where it was cut rather than losing text the user already read.
153
+ */
154
+ stop(): Promise<void>;
155
+ /** Drops the last assistant turn and re-runs from the user turn before it. */
156
+ regenerate(): Promise<void>;
157
+ setMessages(messages: AgentMessage<ToolsOf<P>, OutputOf<P>>[]): void;
158
+ /**
159
+ * Non-empty exactly when `status === "awaiting-input"`.
160
+ *
161
+ * A call a *sub*-agent made arrives here too, with `path` naming the chain of
162
+ * tool calls it is nested under. Nothing else about it is different, and that
163
+ * is the point: it is answered by `approve`/`answer` like any other, and
164
+ * `path` is there only so a UI can say which agent is asking.
165
+ */
166
+ pending: PendingToolCall<ToolsOf<P>>[];
167
+ /**
168
+ * The deferred tools the model has pulled in during the run in flight.
169
+ *
170
+ * Somewhere for a UI to put "…looking for the right tool" instead of an
171
+ * unexplained pause. Run-scoped and not part of the transcript: it says what
172
+ * is happening now, and is empty again on the next `run-start`, so it is not
173
+ * something to persist beside `messages`.
174
+ */
175
+ loadedTools: string[];
176
+ /**
177
+ * Sugar over `sendMessage`. The hook carries each pending call's signature —
178
+ * and its `path`, if the question came from a sub-agent — and hands both back
179
+ * untouched, so an app answers with a boolean and never sees the mechanism
180
+ * that makes answering trustworthy. Answering a nested question is the same
181
+ * call as answering a top-level one.
182
+ */
183
+ approve(toolCallId: string, approve: boolean, reason?: string): Promise<void>;
184
+ /** The same, for a `question` or `client` tool: the value is checked against
185
+ * the tool's output schema server-side before the model sees it. */
186
+ answer(toolCallId: string, output: unknown): Promise<void>;
187
+ /** Uploads through the agent's own upload route and returns the id to put in
188
+ * `sendMessage({ files })`. Here rather than in app code because the route is
189
+ * derived from the same path. */
190
+ attach(file: File): Promise<{
191
+ fileId: string;
192
+ name: string;
193
+ mimeType: string;
194
+ }>;
6
195
  }
7
- export declare function useChat(params: UseChatParams): {
8
- messages: any[];
9
- sendMessage: (payload: MessagePayload) => Promise<void>;
196
+ /**
197
+ * What `POST /api<path>` receives.
198
+ *
199
+ * One route for every client turn, so the body has to say which mode it is in:
200
+ * with a `threadId` the server owns the history, without one the client carries
201
+ * it and sends the transcript *before* this turn — the turn itself is never in
202
+ * `messages`, or the server would see it twice.
203
+ */
204
+ export type AgentRequestBody = {
205
+ turn: ClientTurn;
206
+ threadId?: string;
207
+ messages?: AgentMessage[];
208
+ /**
209
+ * A handle on this run, minted before the run has one.
210
+ *
211
+ * `stop` needs something to name, and the server's own `runId` does not reach
212
+ * the client until `run-start` — a gap covering the network round trip and
213
+ * the provider's time to first token, which is precisely the window a user
214
+ * cancels in. A thread id would do it where there is one, but the stateless
215
+ * first turn has neither. So the client names the run it is starting, and the
216
+ * server is expected to remember the mapping for as long as the run lives.
217
+ */
218
+ clientRunId: string;
219
+ } & Record<string, unknown>;
220
+ /**
221
+ * What `POST /api<path>/attach` receives: which thread, and how far this client
222
+ * already got.
223
+ *
224
+ * `runId` says which run the cursor counts within. Absent, or naming a run that
225
+ * is not the live one, the cursor cannot be honoured and the run has to be
226
+ * replayed from the start.
227
+ */
228
+ export type AgentAttachBody = {
229
+ threadId: string;
230
+ cursor: number;
231
+ runId?: string;
232
+ };
233
+ /**
234
+ * What `POST /api<path>/stop` receives.
235
+ *
236
+ * Every field is optional because the client stops runs it cannot always name:
237
+ * before `run-start` there is no `runId`, and a stateless first turn has no
238
+ * `threadId` either. Whichever handle is present is enough — resolve by
239
+ * `runId`, else by `clientRunId`, else the live run on `threadId`.
240
+ */
241
+ export type AgentStopBody = {
242
+ runId?: string;
243
+ threadId?: string;
244
+ clientRunId?: string;
10
245
  };
246
+ /**
247
+ * The path is the agent's route, exactly as mounted:
248
+ *
249
+ * const { messages, sendMessage } = useChat("/chat")
250
+ *
251
+ * and a tool part inside `messages` narrows on `name`, giving `input` and
252
+ * `output` their real types — which is the whole reason the tool tuple is
253
+ * carried through `Agent`, `AgentRoute` and `RPC` instead of being erased at the
254
+ * first boundary.
255
+ */
256
+ export declare function useChat<P extends keyof AgentRoutes>(path: P, params?: UseChatParams<P>): UseChatResult<P>;
11
257
  export {};
12
258
  //# sourceMappingURL=useChat.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useChat.d.ts","sourceRoot":"","sources":["../../ai/useChat.tsx"],"names":[],"mappings":"AAOA,KAAK,KAAK,GAAG,EAAE,CAAC;AAMhB,UAAU,aAAa;IACrB,KAAK,EAAE,KAAK,CAAC;CACd;AAED,UAAU,cAAc;CAAG;AAE3B,wBAAgB,OAAO,CAAC,MAAM,EAAE,aAAa;;2BAGZ,cAAc;EAE9C"}
1
+ {"version":3,"file":"useChat.d.ts","sourceRoot":"","sources":["../../ai/useChat.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAIzC,OAAO,KAAK,EACV,UAAU,EACV,YAAY,EAEZ,UAAU,EACV,eAAe,EACf,UAAU,EACX,MAAM,SAAS,CAAC;AAEjB;;;;;GAKG;AACH,KAAK,WAAW,GAAG;KAChB,CAAC,IAAI,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,SAAS;QAAE,OAAO,EAAE,IAAI,CAAA;KAAE,GAAG,CAAC,GAAG,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC;CACzE,CAAC;AAEF,KAAK,OAAO,CAAC,CAAC,SAAS,MAAM,WAAW,IAAI,WAAW,CAAC,CAAC,CAAC,SAAS;IAAE,KAAK,EAAE,MAAM,CAAC,CAAA;CAAE,GACjF,CAAC,SAAS,UAAU,GAClB,CAAC,GACD,UAAU,GACZ,UAAU,CAAC;AAEf,KAAK,QAAQ,CAAC,CAAC,SAAS,MAAM,WAAW,IAAI,WAAW,CAAC,CAAC,CAAC,SAAS;IAAE,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GACnF,CAAC,GACD,OAAO,CAAC;AAEZ;;;;;;GAMG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,WAAW,GAAG,WAAW,GAAG,gBAAgB,GAAG,OAAO,CAAC;AAEzF,MAAM,WAAW,aAAa,CAAC,CAAC,SAAS,MAAM,WAAW;IACxD;;;;;;;;mBAQe;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2CAA2C;IAC3C,eAAe,CAAC,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1D;;;;;;;;;;;;;;;OAeG;IACH,MAAM,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IACxC;;;;;OAKG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;iDAC6C;IAC7C,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;IACpE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IACtC,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC;IACnE;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CACvD;AAED,MAAM,WAAW,aAAa,CAAC,CAAC,SAAS,MAAM,WAAW;IACxD;;;;;;;;;;;;;;;;;OAiBG;IACH,QAAQ,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAClD,MAAM,EAAE,UAAU,CAAC;IACnB,iFAAiF;IACjF,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IACzB,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qDAAqD;IACrD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;;;OAQG;IACH,MAAM,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IAExC;;;;OAIG;IACH,WAAW,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtD;;;;;;;OAOG;IACH,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,8EAA8E;IAC9E,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,WAAW,CAAC,QAAQ,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC;IAErE;;;;;;;OAOG;IACH,OAAO,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACvC;;;;;;;OAOG;IACH,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB;;;;;;OAMG;IACH,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9E;yEACqE;IACrE,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE3D;;sCAEkC;IAClC,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjF;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,YAAY,EAAE,CAAC;IAC1B;;;;;;;;;OASG;IACH,WAAW,EAAE,MAAM,CAAC;CACrB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE5B;;;;;;;GAOG;AACH,MAAM,MAAM,eAAe,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnF;;;;;;;GAOG;AACH,MAAM,MAAM,aAAa,GAAG;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAsHxF;;;;;;;;;GASG;AACH,wBAAgB,OAAO,CAAC,CAAC,SAAS,MAAM,WAAW,EACjD,IAAI,EAAE,CAAC,EACP,MAAM,GAAE,aAAa,CAAC,CAAC,CAAM,GAC5B,aAAa,CAAC,CAAC,CAAC,CAgkBlB"}