gemi 0.60.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 (183) 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/chunk-1aqzcgfr.js +5 -0
  62. package/dist/chunk-1aqzcgfr.js.map +10 -0
  63. package/dist/{chunk-get4mkx8.js → chunk-1b7e9rj7.js} +2 -2
  64. package/dist/{chunk-get4mkx8.js.map → chunk-1b7e9rj7.js.map} +1 -1
  65. package/dist/{chunk-x8beq9c4.js → chunk-3aemqfdr.js} +2 -2
  66. package/dist/{chunk-x8beq9c4.js.map → chunk-3aemqfdr.js.map} +1 -1
  67. package/dist/{chunk-j06g4sqc.js → chunk-528n3vgy.js} +2 -2
  68. package/dist/{chunk-j06g4sqc.js.map → chunk-528n3vgy.js.map} +1 -1
  69. package/dist/{chunk-2khdxyjb.js → chunk-57a0nqfj.js} +1 -1
  70. package/dist/chunk-57a0nqfj.js.map +10 -0
  71. package/dist/{chunk-c40n5r4v.js → chunk-5mhcwnyd.js} +2 -2
  72. package/dist/{chunk-c40n5r4v.js.map → chunk-5mhcwnyd.js.map} +1 -1
  73. package/dist/{chunk-gwchvzdp.js → chunk-71pk1mxx.js} +2 -2
  74. package/dist/{chunk-gwchvzdp.js.map → chunk-71pk1mxx.js.map} +1 -1
  75. package/dist/{chunk-spbgpndn.js → chunk-7t1hjs9f.js} +2 -2
  76. package/dist/{chunk-spbgpndn.js.map → chunk-7t1hjs9f.js.map} +1 -1
  77. package/dist/{chunk-9gsdcjt7.js → chunk-7xvaace2.js} +3 -3
  78. package/dist/{chunk-9gsdcjt7.js.map → chunk-7xvaace2.js.map} +1 -1
  79. package/dist/{chunk-fxy42w6n.js → chunk-8ag0da2s.js} +2 -2
  80. package/dist/{chunk-fxy42w6n.js.map → chunk-8ag0da2s.js.map} +1 -1
  81. package/dist/chunk-8r8epsef.js +5 -0
  82. package/dist/chunk-8r8epsef.js.map +11 -0
  83. package/dist/chunk-91cj3nxk.js +6 -0
  84. package/dist/{chunk-y3zz410b.js.map → chunk-91cj3nxk.js.map} +2 -2
  85. package/dist/{chunk-0fm6jh9b.js → chunk-9nmvm20t.js} +2 -2
  86. package/dist/{chunk-0fm6jh9b.js.map → chunk-9nmvm20t.js.map} +1 -1
  87. package/dist/{chunk-98a3k7bp.js → chunk-9xpa7dpy.js} +2 -2
  88. package/dist/{chunk-98a3k7bp.js.map → chunk-9xpa7dpy.js.map} +1 -1
  89. package/dist/{chunk-qva4841r.js → chunk-a1exbqcq.js} +3 -3
  90. package/dist/{chunk-qva4841r.js.map → chunk-a1exbqcq.js.map} +1 -1
  91. package/dist/{chunk-cw9y6k15.js → chunk-bb19bwg6.js} +2 -2
  92. package/dist/{chunk-cw9y6k15.js.map → chunk-bb19bwg6.js.map} +1 -1
  93. package/dist/{chunk-3gvjn3q4.js → chunk-cf7bvd12.js} +1 -1
  94. package/dist/{chunk-rkbv3df7.js → chunk-djp2xeqe.js} +2 -2
  95. package/dist/{chunk-rkbv3df7.js.map → chunk-djp2xeqe.js.map} +1 -1
  96. package/dist/chunk-ds44bqr9.js +4 -0
  97. package/dist/{chunk-4mcyyh1v.js.map → chunk-ds44bqr9.js.map} +4 -9
  98. package/dist/{chunk-wzvs3sym.js → chunk-exndjhza.js} +3 -3
  99. package/dist/{chunk-wzvs3sym.js.map → chunk-exndjhza.js.map} +1 -1
  100. package/dist/{chunk-f6dd4gd8.js → chunk-f233yzxf.js} +2 -2
  101. package/dist/{chunk-f6dd4gd8.js.map → chunk-f233yzxf.js.map} +1 -1
  102. package/dist/chunk-fz5g2z6h.js +4 -0
  103. package/dist/{chunk-fbvvqf9b.js.map → chunk-fz5g2z6h.js.map} +2 -2
  104. package/dist/{chunk-vj9538yn.js → chunk-gcszdwcb.js} +2 -2
  105. package/dist/{chunk-vj9538yn.js.map → chunk-gcszdwcb.js.map} +1 -1
  106. package/dist/{chunk-pkjq9833.js → chunk-htesx7ym.js} +4 -4
  107. package/dist/{chunk-pkjq9833.js.map → chunk-htesx7ym.js.map} +1 -1
  108. package/dist/chunk-hyxmmj9b.js +5 -0
  109. package/dist/{chunk-khf9xda6.js.map → chunk-hyxmmj9b.js.map} +2 -2
  110. package/dist/{chunk-stq96kya.js → chunk-k2sjvt0c.js} +2 -2
  111. package/dist/{chunk-stq96kya.js.map → chunk-k2sjvt0c.js.map} +1 -1
  112. package/dist/{chunk-zhbrkpb3.js → chunk-k75phgj4.js} +4 -4
  113. package/dist/{chunk-zhbrkpb3.js.map → chunk-k75phgj4.js.map} +1 -1
  114. package/dist/{chunk-y64j80v9.js → chunk-m0tp7zjp.js} +2 -2
  115. package/dist/{chunk-y64j80v9.js.map → chunk-m0tp7zjp.js.map} +1 -1
  116. package/dist/{chunk-06j6rsew.js → chunk-m45j7p1y.js} +2 -2
  117. package/dist/{chunk-06j6rsew.js.map → chunk-m45j7p1y.js.map} +1 -1
  118. package/dist/chunk-mca9wsvs.js +5 -0
  119. package/dist/{chunk-z2tcxwyr.js.map → chunk-mca9wsvs.js.map} +3 -4
  120. package/dist/{chunk-tey1xayb.js → chunk-ms13evzp.js} +2 -2
  121. package/dist/{chunk-tey1xayb.js.map → chunk-ms13evzp.js.map} +1 -1
  122. package/dist/{chunk-bn1v4sfs.js → chunk-r962ae93.js} +2 -2
  123. package/dist/{chunk-bn1v4sfs.js.map → chunk-r962ae93.js.map} +1 -1
  124. package/dist/{chunk-23h0dmx2.js → chunk-s41ees18.js} +2 -2
  125. package/dist/{chunk-23h0dmx2.js.map → chunk-s41ees18.js.map} +1 -1
  126. package/dist/chunk-snb68dgr.js +4 -0
  127. package/dist/{chunk-hwhw98hc.js.map → chunk-snb68dgr.js.map} +1 -1
  128. package/dist/chunk-sz051605.js +5 -0
  129. package/dist/chunk-sz051605.js.map +14 -0
  130. package/dist/{chunk-2cwcfwg3.js → chunk-tr3cbx8k.js} +2 -2
  131. package/dist/{chunk-2cwcfwg3.js.map → chunk-tr3cbx8k.js.map} +2 -2
  132. package/dist/{chunk-dgasxgsm.js → chunk-vqcswg7h.js} +2 -2
  133. package/dist/{chunk-dgasxgsm.js.map → chunk-vqcswg7h.js.map} +2 -2
  134. package/dist/{chunk-zqsfanvk.js → chunk-wpb1xpdp.js} +2 -2
  135. package/dist/{chunk-zqsfanvk.js.map → chunk-wpb1xpdp.js.map} +1 -1
  136. package/dist/{chunk-z1e55w67.js → chunk-ybqss0jy.js} +2 -2
  137. package/dist/{chunk-z1e55w67.js.map → chunk-ybqss0jy.js.map} +1 -1
  138. package/dist/{chunk-cejf873g.js → chunk-yk5wqmyh.js} +2 -2
  139. package/dist/{chunk-cejf873g.js.map → chunk-yk5wqmyh.js.map} +1 -1
  140. package/dist/{chunk-8kj3zrm9.js → chunk-ywntv8yw.js} +4 -4
  141. package/dist/{chunk-8kj3zrm9.js.map → chunk-ywntv8yw.js.map} +1 -1
  142. package/dist/chunks/{ThemeProvider-ByU4BQdL.js → ThemeProvider-BZ2SsSZ3.js} +60 -39
  143. package/dist/chunks/ThemeProvider-BZ2SsSZ3.js.map +1 -0
  144. package/dist/chunks/useParams-BN3XXfmG.js +20 -0
  145. package/dist/chunks/useParams-BN3XXfmG.js.map +1 -0
  146. package/dist/client/index.js +3 -3
  147. package/dist/client/index.js.map +1 -1
  148. package/dist/client/useDictionary.d.ts.map +1 -1
  149. package/dist/database/index.js +1 -1
  150. package/dist/facades/index.js +2 -2
  151. package/dist/facades/index.js.map +1 -1
  152. package/dist/http/ApiRouter.d.ts +30 -2
  153. package/dist/http/ApiRouter.d.ts.map +1 -1
  154. package/dist/http/index.js +2 -2
  155. package/dist/http/index.js.map +1 -1
  156. package/dist/i18n/defineDictionary.d.ts +7 -4
  157. package/dist/i18n/defineDictionary.d.ts.map +1 -1
  158. package/dist/i18n/dictionaryRegistry.d.ts +38 -14
  159. package/dist/i18n/dictionaryRegistry.d.ts.map +1 -1
  160. package/dist/i18n/dictionaryRuntime.js +1 -1
  161. package/dist/i18n/index.js +2 -2
  162. package/dist/i18n/index.js.map +2 -2
  163. package/dist/kernel/index.js +2 -2
  164. package/dist/kernel/index.js.map +2 -2
  165. package/dist/orm/index.js +2 -2
  166. package/dist/orm/index.js.map +2 -2
  167. package/dist/server/index.js +1 -1
  168. package/dist/services/index.js +2 -2
  169. package/dist/services/index.js.map +2 -2
  170. package/dist/testing/index.js +2 -1
  171. package/dist/testing/index.js.map +1 -1
  172. package/package.json +3 -1
  173. package/dist/chunk-2khdxyjb.js.map +0 -10
  174. package/dist/chunk-4mcyyh1v.js +0 -4
  175. package/dist/chunk-fbvvqf9b.js +0 -4
  176. package/dist/chunk-hwhw98hc.js +0 -4
  177. package/dist/chunk-khf9xda6.js +0 -5
  178. package/dist/chunk-q0y0j3ne.js +0 -5
  179. package/dist/chunk-q0y0j3ne.js.map +0 -11
  180. package/dist/chunk-y3zz410b.js +0 -6
  181. package/dist/chunk-z2tcxwyr.js +0 -5
  182. package/dist/chunks/ThemeProvider-ByU4BQdL.js.map +0 -1
  183. /package/dist/{chunk-3gvjn3q4.js.map → chunk-cf7bvd12.js.map} +0 -0
@@ -0,0 +1,195 @@
1
+ /**
2
+ * Signing for pending tool calls.
3
+ *
4
+ * A pending call travels through the browser and comes back — in stateless mode
5
+ * the whole history does — so the server cannot trust that what it gets back is
6
+ * what it sent. Without a signature the client asserts not just *that* a call
7
+ * was approved but *what* was approved, and nothing would stop it from
8
+ * returning `approve: true` against an input it rewrote on the way. Signing is
9
+ * what makes the round trip safe, and it is why approvals need no server-side
10
+ * storage at all.
11
+ *
12
+ * What is signed, and what deliberately is not:
13
+ *
14
+ * signed — `runId`, `toolCallId`, the tool `name`, the `kind` of pending call
15
+ * and a canonical serialization of the input, plus a nonce, an
16
+ * expiry, and — for a call a sub-agent asked — the `path` of
17
+ * tool-call ids it is nested under.
18
+ * not — the client's answer. `approve: true` / `approve: false` and a
19
+ * question's output are the *point* of asking; a client that flips
20
+ * its own answer has refused, not forged. What the signature buys is
21
+ * that the answer is bound to the call the server actually made,
22
+ * with the input the server actually saw.
23
+ *
24
+ * A verified token is not yet an answer the server may act on: it says the
25
+ * question was asked, not that it is still open. `consumePendingCall` at the
26
+ * bottom of this file spends the nonce, which is what makes an approval
27
+ * single-use — see the note there for what that guarantee is worth.
28
+ *
29
+ * `kind` is in there for a specific attack: an `approval`-kind call is one the
30
+ * *server* runs, so a client that reused its signature on the "here is the
31
+ * output" arm of `ClientToolResult` would be fabricating a server tool's result
32
+ * rather than approving it. Binding the kind makes that a forgery instead of a
33
+ * shape the caller has to remember to check.
34
+ */
35
+ /** Everything the signature commits to. */
36
+ export type PendingCallClaims = {
37
+ runId: string;
38
+ toolCallId: string;
39
+ name: string;
40
+ kind: "approval" | "question" | "client";
41
+ input: unknown;
42
+ /**
43
+ * The chain of tool-call ids the call is nested under, outermost first.
44
+ * Absent — or empty, which means the same thing — for a top-level call.
45
+ *
46
+ * A sub-agent's question reaches the user through its parent's pending list,
47
+ * so `toolCallId` stops being an address on its own: two sub-runs under two
48
+ * different tools can each hold a call the outer run never made. Binding the
49
+ * path is what stops a token minted for a call nested under tool call X from
50
+ * being replayed as a top-level call, or as one nested under Y.
51
+ */
52
+ path?: string[];
53
+ };
54
+ export type SignOptions = {
55
+ /** Overrides `process.env.SECRET`. Exists for tests; apps use the app key. */
56
+ secret?: string;
57
+ /**
58
+ * Default 24 hours. An approval waits on a human, and humans go to lunch —
59
+ * a short expiry turns "I approved it after standup" into an unexplained
60
+ * failure. Long enough to survive a working day, short enough that a token
61
+ * lifted from a log is not useful next month.
62
+ */
63
+ ttlMs?: number;
64
+ /** Injected clock, so the expiry path is testable without waiting. */
65
+ now?: number;
66
+ };
67
+ export type VerifyOptions = {
68
+ secret?: string;
69
+ now?: number;
70
+ };
71
+ /**
72
+ * A discriminated result rather than a boolean, because the two failures are
73
+ * different events: `expired` is a sentence to show the user, `forged` is worth
74
+ * logging and possibly alerting on. Collapsing them loses the only signal that
75
+ * says someone is probing.
76
+ */
77
+ export type VerifyResult = {
78
+ ok: true;
79
+ runId: string;
80
+ nonce: string;
81
+ expiresAt: number;
82
+ } | {
83
+ ok: false;
84
+ reason: "malformed" | "expired" | "forged";
85
+ };
86
+ /**
87
+ * Serializes a value so that the same value always produces the same string.
88
+ *
89
+ * `JSON.stringify` is not enough: it preserves insertion order, so an input
90
+ * that made a round trip through a client — parsed and re-serialized, with the
91
+ * keys in whatever order the parser produced — would hash differently and a
92
+ * legitimate approval would come back looking forged. Keys are sorted,
93
+ * `undefined` members are dropped (they do not survive JSON anyway), and arrays
94
+ * keep their order because in an array order *is* the value.
95
+ */
96
+ export declare function canonicalize(value: unknown): string;
97
+ /** `agt1.<runId>.<nonce>.<expiry>.<mac>`, all base64url or base36. */
98
+ export declare function signPendingCall(claims: PendingCallClaims, options?: SignOptions): string;
99
+ /**
100
+ * The metadata a signature carries in the clear.
101
+ *
102
+ * `Agent` needs the issuing `runId` before it can verify anything: the call was
103
+ * signed under the run that made it, and the turn answering it is a *new* run
104
+ * with a new id. Reading it out of the token is safe because the token's own
105
+ * MAC covers it — a client that edits the runId here fails verification, so
106
+ * this is "which run does this claim to belong to", not "which run does the
107
+ * client say it belongs to".
108
+ */
109
+ export declare function readSignature(signature: string): {
110
+ runId: string;
111
+ nonce: string;
112
+ expiresAt: number;
113
+ } | null;
114
+ export declare function verifyPendingCall(signature: string, claims: PendingCallClaims, options?: VerifyOptions): VerifyResult;
115
+ /**
116
+ * What a parked sub-run's record is signed over.
117
+ *
118
+ * `ToolCallPart.nested` is the parent's own record of where a sub-run stopped,
119
+ * and in stateless mode it makes the same trip through the browser a pending
120
+ * call does. The next turn *runs a tool* on the strength of that record — the
121
+ * tool is re-entered because the record says a sub-run under it is waiting on
122
+ * the question being answered — so an unsigned record lets the client choose
123
+ * which tools run, with what input, before any answer is verified. A MAC over
124
+ * what the server actually recorded is what makes the record safe to carry.
125
+ *
126
+ * Only a parked record is signed, because only a parked record executes
127
+ * anything: a finished sub-run is replayed out of its transcript and spends
128
+ * nothing, and a client that forges one has fed its own tool a made-up answer,
129
+ * which a client-carried history already allows everywhere.
130
+ *
131
+ * Deliberately not signed: the transcript. The sub-run resumes from messages
132
+ * the client carried, exactly as the parent does in stateless mode, and the
133
+ * same argument applies — what the signature pins is that the server parked
134
+ * *here*, on *these* calls, with *this* input, and not what was said on the
135
+ * way.
136
+ */
137
+ export type NestedRunClaims = {
138
+ /** The root run's id, the one every pending call of the tree is minted under. */
139
+ runId: string;
140
+ /**
141
+ * Tool-call ids from the root down to and including the call the record
142
+ * hangs off. A sub-run's id is not an address on its own for the same reason
143
+ * a nested call's is not: two sub-runs under two different tools can carry
144
+ * the same one.
145
+ */
146
+ path: string[];
147
+ /** The sub-run's own id, so a record cannot be moved between sub-runs. */
148
+ nestedRunId: string;
149
+ /** The tool calls the sub-run is waiting on: every call left open in its transcript. */
150
+ open: string[];
151
+ /**
152
+ * The input the tool that parked was running on, as the transcript carries
153
+ * it. Re-entry runs the tool body with the input the history holds, and the
154
+ * history is the client's — so a record that pinned where the sub-run parked
155
+ * but not what its tool was given would let the client keep the run and
156
+ * rewrite the arguments to anything the schema accepts. The same bargain a
157
+ * pending call makes: the input executed is the input signed.
158
+ */
159
+ input: unknown;
160
+ };
161
+ /**
162
+ * Same shape as a pending call's token, so the same reader serves both — nonce
163
+ * included, and the nonce is spent, by `consumeNestedRun` below. A verified
164
+ * record is permission to run the tool it hangs off, and the tool body runs
165
+ * before the sub-run gets to look at the answer's own nonce; a record that
166
+ * could be presented twice would run the body twice before anything refused
167
+ * the replay. Every park mints a fresh record, so spending one costs a
168
+ * legitimate re-park nothing.
169
+ */
170
+ export declare function signNestedRun(claims: NestedRunClaims, options?: SignOptions): string;
171
+ /**
172
+ * The run that verifies a record is never the run that minted it — the turn
173
+ * answering a question is a new run with a new id — so the minting run's id is
174
+ * read out of the token rather than asked of the caller, which has no other
175
+ * source for it. The MAC covers it, so a client that edits the id in the clear
176
+ * fails here rather than being believed.
177
+ */
178
+ export declare function verifyNestedRun(signature: string, claims: Omit<NestedRunClaims, "runId">, options?: VerifyOptions): VerifyResult;
179
+ /**
180
+ * Spends a signature's nonce. `false` means it was already spent — the answer
181
+ * is a replay and must not be acted on.
182
+ *
183
+ * Separate from `verifyPendingCall` rather than folded into it, because verify
184
+ * is a pure question a caller may want to ask twice (logging a forgery, say)
185
+ * and this one is a state change that must happen exactly once per answer.
186
+ */
187
+ export declare function consumePendingCall(signature: string, options?: VerifyOptions): boolean;
188
+ /**
189
+ * Spends a parked-run record's nonce, on the same registry and the same terms.
190
+ * `false` means the record has already re-entered its tool once — the turn is
191
+ * a replay of a history from before the answer was delivered, and the body
192
+ * must not run again on it.
193
+ */
194
+ export declare function consumeNestedRun(signature: string, options?: VerifyOptions): boolean;
195
+ //# sourceMappingURL=signing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signing.d.ts","sourceRoot":"","sources":["../../ai/signing.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,2CAA2C;AAC3C,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,UAAU,GAAG,UAAU,GAAG,QAAQ,CAAC;IACzC,KAAK,EAAE,OAAO,CAAC;IACf;;;;;;;;;OASG;IACH,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,8EAA8E;IAC9E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sEAAsE;IACtE,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GACpB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAC7D;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,QAAQ,CAAA;CAAE,CAAC;AAkB9D;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAYnD;AAkDD,sEAAsE;AACtE,wBAAgB,eAAe,CAAC,MAAM,EAAE,iBAAiB,EAAE,OAAO,GAAE,WAAgB,GAAG,MAAM,CAO5F;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,MAAM,GAChB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAE5D;AA6BD,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,iBAAiB,EACzB,OAAO,GAAE,aAAkB,GAC1B,YAAY,CAwBd;AAID;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,iFAAiF;IACjF,KAAK,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,0EAA0E;IAC1E,WAAW,EAAE,MAAM,CAAC;IACpB,wFAAwF;IACxF,IAAI,EAAE,MAAM,EAAE,CAAC;IACf;;;;;;;OAOG;IACH,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AAmBF;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,eAAe,EAAE,OAAO,GAAE,WAAgB,GAAG,MAAM,CAOxF;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,IAAI,CAAC,eAAe,EAAE,OAAO,CAAC,EACtC,OAAO,GAAE,aAAkB,GAC1B,YAAY,CAwBd;AA2CD;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,OAAO,CAE1F;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,OAAO,CAExF"}
@@ -0,0 +1,142 @@
1
+ import type { AgentRun } from "../Agent";
2
+ import type { LiveRuns } from "../AgentController";
3
+ import type { AgentStreamEvent, AgentStreamFrame } from "../types";
4
+ /**
5
+ * A cursor older than anything still buffered.
6
+ *
7
+ * Deliberately an error rather than "here is the tail I still have". A client
8
+ * that asked for frame 12 and silently got frame 300 onwards has a transcript
9
+ * with a hole in it and no way to know — it will render a half-message, or an
10
+ * `awaiting-input` for a tool call it never saw. Saying so lets the client do
11
+ * the only correct thing, which is to reload the thread from the store.
12
+ */
13
+ export declare class FrameCursorEvictedError extends Error {
14
+ readonly runId: string;
15
+ readonly requested: number;
16
+ readonly oldest: number;
17
+ readonly code = "frame_cursor_evicted";
18
+ constructor(runId: string, requested: number, oldest: number);
19
+ }
20
+ /**
21
+ * No run under that id in *this* process.
22
+ *
23
+ * Which is the honest answer, and the one worth being loud about: the run may
24
+ * well be alive on the box next door. See the note on `MemoryLiveRuns` — behind
25
+ * a round-robin load balancer this is what a refresh hits roughly (n-1)/n of
26
+ * the time, and an explicit miss is the difference between a bug someone finds
27
+ * in an hour and one that presents as "reattach sometimes does nothing".
28
+ */
29
+ export declare class LiveRunNotFoundError extends Error {
30
+ readonly runId: string;
31
+ readonly code = "live_run_not_found";
32
+ constructor(runId: string);
33
+ }
34
+ export type RegisterParams = {
35
+ threadId?: string;
36
+ /**
37
+ * The client's own name for this run, minted before the run had one.
38
+ *
39
+ * `runId` does not reach the client until `run-start`, and a stateless first
40
+ * turn has no `threadId` either, so for the length of a network round trip
41
+ * plus the provider's time to first token there is nothing for `/stop` to
42
+ * name — which is exactly the window a user cancels in. `useChat` sends a
43
+ * `clientRunId` with every turn it starts; recording it here is what makes
44
+ * that window stoppable.
45
+ */
46
+ clientRunId?: string;
47
+ /**
48
+ * Called once per frame, in order, off the buffering path.
49
+ *
50
+ * The controller's `on*` hooks hang off this. It is a callback rather than a
51
+ * second `run.frames()` subscription because every extra subscriber is
52
+ * another consumer of a generator whose multi-subscriber behaviour we do not
53
+ * own, and one pump is one thing to reason about.
54
+ */
55
+ onEvent?: (event: AgentStreamEvent) => void | Promise<void>;
56
+ /** Reported failures: a hook that threw, or a run whose frame iterator did.
57
+ * Injectable so tests can assert on it instead of reading stderr. */
58
+ onInternalError?: (error: unknown) => void;
59
+ };
60
+ /**
61
+ * The runs currently in flight in this process, and their recent frames.
62
+ *
63
+ * PER-PROCESS IS NOT AN IMPLEMENTATION SHORTCUT THAT A BETTER STORE FIXES. A
64
+ * running generator lives in one process, and a second server cannot attach to
65
+ * it — no amount of Redis moves an in-flight async iterator across a socket.
66
+ * Reattachment therefore needs the request to land where the run is: one
67
+ * server, sticky routing, or a proxy that forwards by `runId`. Worth saying out
68
+ * loud, because the failure mode behind a round-robin load balancer is a
69
+ * refresh that usually works.
70
+ *
71
+ * `find` and `replay` are built so that failure is an explicit miss — a 404
72
+ * naming the run, a 410 naming the cursor — and never an SSE stream that opens,
73
+ * says nothing and closes. An empty stream is indistinguishable from a run that
74
+ * finished quietly, which is exactly the confusion this is supposed to avoid.
75
+ */
76
+ export declare class MemoryLiveRuns implements LiveRuns {
77
+ ttlMs: number;
78
+ readonly maxFrames: number;
79
+ private runs;
80
+ /** Thread to the most recently registered run for it. */
81
+ private byThread;
82
+ /** The client's pre-`run-start` name for a run, to the run. */
83
+ private byClientRun;
84
+ constructor(params?: {
85
+ ttlMs?: number;
86
+ maxFrames?: number;
87
+ });
88
+ /**
89
+ * Takes ownership of a run: starts buffering its frames and holds it until
90
+ * `ttlMs` past the end.
91
+ */
92
+ register(run: AgentRun, params?: RegisterParams): void;
93
+ /**
94
+ * The run a client named before the server had named it.
95
+ *
96
+ * Deliberately not folded into `find`, whose parameter is part of the
97
+ * read-side `LiveRuns` interface an app may already implement — widening that
98
+ * parameter would break every such implementation, and this lookup is only
99
+ * ever asked by `/stop`.
100
+ */
101
+ findByClientRunId(clientRunId: string): string | null;
102
+ /** What the client asks after a refresh: is anything still going here? */
103
+ find(params: {
104
+ threadId: string;
105
+ }): Promise<{
106
+ runId: string;
107
+ seq: number;
108
+ } | null>;
109
+ get(runId: string): AgentRun | null;
110
+ /**
111
+ * The buffered frames from `from` onwards, followed by live ones until the
112
+ * run ends.
113
+ *
114
+ * Throws before returning anything, so an evicted cursor and an unknown run
115
+ * are still HTTP statuses rather than events on a stream that already
116
+ * committed to a 200.
117
+ *
118
+ * `from` omitted means "start wherever you still can", not "start at 0".
119
+ * These are genuinely different requests: a client that names a cursor is
120
+ * telling us where its transcript ends, and handing it a later frame leaves
121
+ * an invisible hole — that is the 410. A client with no cursor at all — the
122
+ * browser reattaching on mount, which is the case `/attach` exists for — has
123
+ * no transcript to put a hole in, and refusing it the tail because the run is
124
+ * older than the buffer would 410 every run past `maxFrames`, i.e. every run
125
+ * long enough to be worth reattaching to.
126
+ */
127
+ replay(runId: string, from?: number): AsyncIterable<AgentStreamFrame>;
128
+ /** Test seam: drops everything and cancels the pending eviction timers. */
129
+ clear(): void;
130
+ get size(): number;
131
+ private pump;
132
+ private drain;
133
+ private wait;
134
+ private notify;
135
+ private scheduleEviction;
136
+ }
137
+ /**
138
+ * The process-wide default, shared by every `AgentController` that does not
139
+ * bring its own. One map per process is the whole point — see the class note.
140
+ */
141
+ export declare const liveRuns: MemoryLiveRuns;
142
+ //# sourceMappingURL=LiveRuns.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LiveRuns.d.ts","sourceRoot":"","sources":["../../../ai/store/LiveRuns.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAqCnE;;;;;;;;GAQG;AACH,qBAAa,uBAAwB,SAAQ,KAAK;IAI9C,QAAQ,CAAC,KAAK,EAAE,MAAM;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM;IALzB,QAAQ,CAAC,IAAI,0BAA0B;gBAG5B,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM;CAO1B;AAED;;;;;;;;GAQG;AACH,qBAAa,oBAAqB,SAAQ,KAAK;IAGjC,QAAQ,CAAC,KAAK,EAAE,MAAM;IAFlC,QAAQ,CAAC,IAAI,wBAAwB;gBAEhB,KAAK,EAAE,MAAM;CAGnC;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;;;;;OASG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5D;0EACsE;IACtE,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CAC5C,CAAC;AAqCF;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,cAAe,YAAW,QAAQ;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAE3B,OAAO,CAAC,IAAI,CAA4B;IACxC,yDAAyD;IACzD,OAAO,CAAC,QAAQ,CAA6B;IAC7C,+DAA+D;IAC/D,OAAO,CAAC,WAAW,CAA6B;gBAEpC,MAAM,GAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO;IAK/D;;;OAGG;IACH,QAAQ,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,GAAE,cAAmB,GAAG,IAAI;IAuB1D;;;;;;;OAOG;IACH,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAKrD,0EAA0E;IACpE,IAAI,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAexF,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI;IAInC;;;;;;;;;;;;;;;;OAgBG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,aAAa,CAAC,gBAAgB,CAAC;IAcrE,2EAA2E;IAC3E,KAAK,IAAI,IAAI;IAeb,IAAI,IAAI,IAAI,MAAM,CAEjB;YAEa,IAAI;YA4CH,KAAK;IA4CpB,OAAO,CAAC,IAAI;IAOZ,OAAO,CAAC,MAAM;IASd,OAAO,CAAC,gBAAgB;CAqBzB;AAED;;;GAGG;AACH,eAAO,MAAM,QAAQ,gBAAuB,CAAC"}
@@ -0,0 +1,61 @@
1
+ import type { AgentStore } from "../AgentController";
2
+ import type { AgentMessage } from "../types";
3
+ /**
4
+ * The default store: conversations last as long as the process.
5
+ *
6
+ * It exists so that `threadId` works out of the box, not so that anything is
7
+ * durable — a restart loses every thread, and a second server never had them.
8
+ * That is the honest default for a framework store, and it is why stateless is
9
+ * still the mode an app gets without asking: the client carrying its own
10
+ * history survives a deploy, and this does not.
11
+ *
12
+ * Expiry is swept lazily rather than on a timer. A `setTimeout` per thread is a
13
+ * timer per conversation and a reference the GC cannot collect, and an interval
14
+ * running forever keeps a process alive that has nothing else to do — so the
15
+ * sweep happens on access, at most once a minute, and an untouched process
16
+ * simply stops sweeping.
17
+ *
18
+ * A thread the store does not have is `null` from `loadThread` and an error
19
+ * from `appendMessages`, never an empty conversation. It used to be the other
20
+ * way, and the three ways a thread goes missing — it expired, the id was
21
+ * mistyped, it lived on an instance that was scaled in — all read as a fresh
22
+ * chat: the history was gone with no signal, and the next turn was persisted
23
+ * under the dead id as though it were the first. `clientOwnedIds` is the one
24
+ * setup where an unknown id is not a lost thread, because the client minted it.
25
+ */
26
+ export declare class MemoryAgentStore implements AgentStore {
27
+ readonly ttlMs: number;
28
+ /** The ids come from the client, not from `createThread`, so an id this
29
+ * store has never seen is a conversation starting rather than one lost. */
30
+ readonly clientOwnedIds: boolean;
31
+ private threads;
32
+ private lastSweep;
33
+ constructor(params?: {
34
+ ttlMs?: number;
35
+ clientOwnedIds?: boolean;
36
+ });
37
+ createThread(params: {
38
+ userId?: string | number;
39
+ }): Promise<{
40
+ threadId: string;
41
+ }>;
42
+ loadThread(threadId: string): Promise<AgentMessage[] | null>;
43
+ appendMessages(threadId: string, messages: AgentMessage[]): Promise<void>;
44
+ /** Test seam, and a way for an app to drop a conversation on request. */
45
+ delete(threadId: string): void;
46
+ get size(): number;
47
+ sweep(now?: number): void;
48
+ }
49
+ /**
50
+ * The process-wide default every `AgentController` uses unless it is given
51
+ * another.
52
+ *
53
+ * It has to be a shared instance, not a field initializer. A gemi controller is
54
+ * constructed per request — `RouteHandler.run()` does `new Controller()` every
55
+ * time — so `store = new MemoryAgentStore()` written in a controller field is a
56
+ * brand new, empty store on every turn, and a threaded conversation would read
57
+ * back nothing while looking like it was configured correctly. Anything
58
+ * process-lived that a controller holds has to be created outside it.
59
+ */
60
+ export declare const defaultAgentStore: MemoryAgentStore;
61
+ //# sourceMappingURL=MemoryAgentStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MemoryAgentStore.d.ts","sourceRoot":"","sources":["../../../ai/store/MemoryAgentStore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAgB7C;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,gBAAiB,YAAW,UAAU;IACjD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB;gFAC4E;IAC5E,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IAEjC,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,SAAS,CAAK;gBAEV,MAAM,GAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,cAAc,CAAC,EAAE,OAAO,CAAA;KAAO;IAK/D,YAAY,CAAC,MAAM,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAWjF,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,GAAG,IAAI,CAAC;IAiB5D,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAiC/E,yEAAyE;IACzE,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAI9B,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,KAAK,CAAC,GAAG,SAAa,GAAG,IAAI;CAW9B;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,iBAAiB,kBAAyB,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { defaultAgentStore, MemoryAgentStore } from "./MemoryAgentStore";
2
+ export { FrameCursorEvictedError, LiveRunNotFoundError, liveRuns, MemoryLiveRuns, type RegisterParams, } from "./LiveRuns";
3
+ export { encodeFrame, sseHeaders, sseResponse } from "./sse";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../ai/store/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACzE,OAAO,EACL,uBAAuB,EACvB,oBAAoB,EACpB,QAAQ,EACR,cAAc,EACd,KAAK,cAAc,GACpB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC"}
@@ -0,0 +1,58 @@
1
+ import type { AgentStreamFrame } from "../types";
2
+ /**
3
+ * One frame, one SSE event.
4
+ *
5
+ * `id:` carries the frame's `seq`, which is what makes the browser's own
6
+ * `Last-Event-ID` the right cursor on reconnect — the transport asks the
7
+ * question the run already knows how to answer, and the client never has to
8
+ * track a position of its own.
9
+ */
10
+ export declare function encodeFrame(frame: AgentStreamFrame): string;
11
+ /**
12
+ * How long a connection may sit idle before a comment line goes out.
13
+ *
14
+ * The nearest ceiling is not a proxy but our own server: Bun's `idleTimeout`
15
+ * counts socket silence, a streaming body included, and gemi runs at its
16
+ * 10-second default unless `SERVER_IDLE_TIMEOUT` says otherwise. A comment
17
+ * line every 25 seconds was measured to lose the connection at 12; every 5
18
+ * keeps it open, with room for a write that lands late. Azure App Service's
19
+ * front end, at about 230 seconds, is the far ceiling, and 5 clears it by the
20
+ * same margin. A thousand quiet streams cost two hundred thirteen-byte writes
21
+ * a second, which is nothing. Both encoders read this one value, so the two
22
+ * cannot drift apart.
23
+ */
24
+ export declare const SSE_KEEPALIVE_INTERVAL_MS = 5000;
25
+ /**
26
+ * The comment line itself. A line starting with `:` is a comment under the SSE
27
+ * spec: every parser on our side skips it, and so does the browser's own
28
+ * `EventSource`.
29
+ */
30
+ export declare const SSE_KEEPALIVE = ": keepalive\n\n";
31
+ /**
32
+ * Writes a keepalive whenever the stream has been silent for the interval.
33
+ *
34
+ * Armed on creation because the silence before the first frame is real
35
+ * silence too — a model thinking is the common case. `touch()` after every
36
+ * frame is what makes it measure silence rather than elapsed time; `stop()`
37
+ * on close or cancel is what keeps a finished stream from holding a timer.
38
+ *
39
+ * The write is guarded because a cancel can land between the timer firing and
40
+ * the enqueue, and a closed controller throws. There is nothing to do about
41
+ * that except stop. `arm` checks `stopped` too, so a `touch()` that arrives
42
+ * after `stop()` cannot hand a finished stream a timer for one more interval.
43
+ */
44
+ export declare function sseKeepalive(controller: ReadableStreamDefaultController<Uint8Array>, intervalMs?: number): {
45
+ touch(): void;
46
+ stop(): void;
47
+ };
48
+ export declare function sseHeaders(): Record<string, string>;
49
+ /**
50
+ * Encodes an async iterable of frames as an SSE response.
51
+ *
52
+ * Pulls one frame per `pull` rather than looping inside `start`: a `start` that
53
+ * awaits the whole run does not resolve until the run is over, and the stream
54
+ * is not readable until it does — which would turn every streamed answer into a
55
+ * single delivery at the end.
56
+ */
57
+ export declare function sseResponse(frames: AsyncIterable<AgentStreamFrame>, status?: number): Response;
58
+ //# sourceMappingURL=sse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../../../ai/store/sse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAc,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAI7D;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,MAAM,CAE3D;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,yBAAyB,OAAQ,CAAC;AAE/C;;;;GAIG;AACH,eAAO,MAAM,aAAa,oBAAoB,CAAC;AAE/C;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,CAC1B,UAAU,EAAE,+BAA+B,CAAC,UAAU,CAAC,EACvD,UAAU,SAA4B,GACrC;IAAE,KAAK,IAAI,IAAI,CAAC;IAAC,IAAI,IAAI,IAAI,CAAA;CAAE,CA4BjC;AAED,wBAAgB,UAAU,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAWnD;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,aAAa,CAAC,gBAAgB,CAAC,EAAE,MAAM,SAAM,GAAG,QAAQ,CAwC3F"}
@@ -0,0 +1,56 @@
1
+ import type { AgentRun, AgentRunResult } from "../Agent";
2
+ import type { AgentStreamEvent, AgentStreamFrame, ToolShapes } from "../types";
3
+ /**
4
+ * A hand-driven `AgentRun`, for tests of everything that consumes one.
5
+ *
6
+ * It lives in source rather than in a test file because both the `LiveRuns`
7
+ * tests and the controller tests need the same fake, and a test file that
8
+ * imports another test file gets that file's suites collected twice.
9
+ *
10
+ * It is deliberately a *stub satisfying the interface*, not a shrunken `Agent`:
11
+ * the real agent is a separate slice, and a test that imported it would be
12
+ * testing whichever half of the module was written last.
13
+ */
14
+ export declare class StubAgentRun implements AgentRun<ToolShapes, unknown> {
15
+ readonly runId: string;
16
+ stopped: boolean;
17
+ stopReason: string | undefined;
18
+ /** Every `frames()` call ever made, so a test can assert on subscribers. */
19
+ subscriptions: number;
20
+ private buffer;
21
+ /**
22
+ * Frames are numbered from 1, because `AgentRunImpl` numbers them from 1.
23
+ *
24
+ * This used to start at 0, and the difference was not cosmetic: `LiveRuns`
25
+ * decided whether a cursor had been evicted by comparing it against the
26
+ * oldest buffered `seq`, which is 1 on a real run that has evicted nothing
27
+ * and 0 on this one. Every test here passed against a stub that could not
28
+ * express the case, and a ten-frame run answered a refresh with 410.
29
+ */
30
+ private nextSeq;
31
+ private done;
32
+ private wake;
33
+ /** See the note on `Entry.version` in `LiveRuns`: same missed-wakeup window,
34
+ * same fix. */
35
+ private version;
36
+ private outcome;
37
+ private settle;
38
+ private settled;
39
+ constructor(runId?: string);
40
+ /** Pushes one event onto the run, numbering it the way a real run would. */
41
+ emit(event: AgentStreamEvent): AgentStreamFrame;
42
+ /** Ends the run. Everything parked on `frames()` or `result()` unblocks. */
43
+ finish(result?: Partial<AgentRunResult<ToolShapes, unknown>>): void;
44
+ frames(from?: number): AsyncIterable<AgentStreamFrame>;
45
+ [Symbol.asyncIterator](): AsyncGenerator<AgentStreamEvent, void, void>;
46
+ toResponse(params?: {
47
+ from?: number;
48
+ }): Response;
49
+ result(): Promise<AgentRunResult<ToolShapes, unknown>>;
50
+ stop(params?: {
51
+ reason?: string;
52
+ }): void;
53
+ private replay;
54
+ private notify;
55
+ }
56
+ //# sourceMappingURL=stubAgentRun.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stubAgentRun.d.ts","sourceRoot":"","sources":["../../../ai/store/stubAgentRun.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AACzD,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE/E;;;;;;;;;;GAUG;AACH,qBAAa,YAAa,YAAW,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAChE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAEvB,OAAO,UAAS;IAChB,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,4EAA4E;IAC5E,aAAa,SAAK;IAElB,OAAO,CAAC,MAAM,CAA0B;IACxC;;;;;;;;OAQG;IACH,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,IAAI,CAAyB;IACrC;oBACgB;IAChB,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,OAAO,CAAoD;IACnE,OAAO,CAAC,MAAM,CAAwE;IACtF,OAAO,CAAC,OAAO,CAA+C;gBAElD,KAAK,SAAa;IAO9B,4EAA4E;IAC5E,IAAI,CAAC,KAAK,EAAE,gBAAgB,GAAG,gBAAgB;IAO/C,4EAA4E;IAC5E,MAAM,CAAC,MAAM,GAAE,OAAO,CAAC,cAAc,CAAC,UAAU,EAAE,OAAO,CAAC,CAAM,GAAG,IAAI;IAavE,MAAM,CAAC,IAAI,SAAI,GAAG,aAAa,CAAC,gBAAgB,CAAC;IAK1C,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,cAAc,CAAC,gBAAgB,EAAE,IAAI,EAAE,IAAI,CAAC;IAM7E,UAAU,CAAC,MAAM,GAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,QAAQ;IAWpD,MAAM,IAAI,OAAO,CAAC,cAAc,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IAItD,IAAI,CAAC,MAAM,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,IAAI;YAK7B,MAAM;IAmBrB,OAAO,CAAC,MAAM;CAQf"}