@data-club/ai-hub-server 0.0.1

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 (248) hide show
  1. package/dist/auth/argon2.d.ts +72 -0
  2. package/dist/auth/argon2.d.ts.map +1 -0
  3. package/dist/auth/argon2.js +145 -0
  4. package/dist/auth/argon2.js.map +1 -0
  5. package/dist/auth/encryption.d.ts +52 -0
  6. package/dist/auth/encryption.d.ts.map +1 -0
  7. package/dist/auth/encryption.js +98 -0
  8. package/dist/auth/encryption.js.map +1 -0
  9. package/dist/auth/jwt.d.ts +133 -0
  10. package/dist/auth/jwt.d.ts.map +1 -0
  11. package/dist/auth/jwt.js +147 -0
  12. package/dist/auth/jwt.js.map +1 -0
  13. package/dist/auth/middleware.d.ts +101 -0
  14. package/dist/auth/middleware.d.ts.map +1 -0
  15. package/dist/auth/middleware.js +161 -0
  16. package/dist/auth/middleware.js.map +1 -0
  17. package/dist/auth/passwordPolicy.d.ts +72 -0
  18. package/dist/auth/passwordPolicy.d.ts.map +1 -0
  19. package/dist/auth/passwordPolicy.js +88 -0
  20. package/dist/auth/passwordPolicy.js.map +1 -0
  21. package/dist/auth/roleRules.d.ts +200 -0
  22. package/dist/auth/roleRules.d.ts.map +1 -0
  23. package/dist/auth/roleRules.js +365 -0
  24. package/dist/auth/roleRules.js.map +1 -0
  25. package/dist/auth/userView.d.ts +55 -0
  26. package/dist/auth/userView.d.ts.map +1 -0
  27. package/dist/auth/userView.js +77 -0
  28. package/dist/auth/userView.js.map +1 -0
  29. package/dist/bootstrap.d.ts +104 -0
  30. package/dist/bootstrap.d.ts.map +1 -0
  31. package/dist/bootstrap.js +160 -0
  32. package/dist/bootstrap.js.map +1 -0
  33. package/dist/db/connection.d.ts +39 -0
  34. package/dist/db/connection.d.ts.map +1 -0
  35. package/dist/db/connection.js +62 -0
  36. package/dist/db/connection.js.map +1 -0
  37. package/dist/db/migrate.d.ts +31 -0
  38. package/dist/db/migrate.d.ts.map +1 -0
  39. package/dist/db/migrate.js +197 -0
  40. package/dist/db/migrate.js.map +1 -0
  41. package/dist/db/schema.d.ts +1902 -0
  42. package/dist/db/schema.d.ts.map +1 -0
  43. package/dist/db/schema.js +662 -0
  44. package/dist/db/schema.js.map +1 -0
  45. package/dist/db/seed.d.ts +92 -0
  46. package/dist/db/seed.d.ts.map +1 -0
  47. package/dist/db/seed.js +160 -0
  48. package/dist/db/seed.js.map +1 -0
  49. package/dist/handlers/fetch.d.ts +89 -0
  50. package/dist/handlers/fetch.d.ts.map +1 -0
  51. package/dist/handlers/fetch.js +173 -0
  52. package/dist/handlers/fetch.js.map +1 -0
  53. package/dist/handlers/nextjs.d.ts +40 -0
  54. package/dist/handlers/nextjs.d.ts.map +1 -0
  55. package/dist/handlers/nextjs.js +42 -0
  56. package/dist/handlers/nextjs.js.map +1 -0
  57. package/dist/handlers/responses.d.ts +46 -0
  58. package/dist/handlers/responses.d.ts.map +1 -0
  59. package/dist/handlers/responses.js +74 -0
  60. package/dist/handlers/responses.js.map +1 -0
  61. package/dist/handlers/routeTable.d.ts +21 -0
  62. package/dist/handlers/routeTable.d.ts.map +1 -0
  63. package/dist/handlers/routeTable.js +133 -0
  64. package/dist/handlers/routeTable.js.map +1 -0
  65. package/dist/handlers/router.d.ts +37 -0
  66. package/dist/handlers/router.d.ts.map +1 -0
  67. package/dist/handlers/router.js +82 -0
  68. package/dist/handlers/router.js.map +1 -0
  69. package/dist/handlers/sse.d.ts +38 -0
  70. package/dist/handlers/sse.d.ts.map +1 -0
  71. package/dist/handlers/sse.js +52 -0
  72. package/dist/handlers/sse.js.map +1 -0
  73. package/dist/handlers/types.d.ts +96 -0
  74. package/dist/handlers/types.d.ts.map +1 -0
  75. package/dist/handlers/types.js +14 -0
  76. package/dist/handlers/types.js.map +1 -0
  77. package/dist/index.d.ts +25 -0
  78. package/dist/index.d.ts.map +1 -0
  79. package/dist/index.js +24 -0
  80. package/dist/index.js.map +1 -0
  81. package/dist/letta/client.d.ts +355 -0
  82. package/dist/letta/client.d.ts.map +1 -0
  83. package/dist/letta/client.js +529 -0
  84. package/dist/letta/client.js.map +1 -0
  85. package/dist/letta/eventTranslator.d.ts +166 -0
  86. package/dist/letta/eventTranslator.d.ts.map +1 -0
  87. package/dist/letta/eventTranslator.js +532 -0
  88. package/dist/letta/eventTranslator.js.map +1 -0
  89. package/dist/letta/index.d.ts +13 -0
  90. package/dist/letta/index.d.ts.map +1 -0
  91. package/dist/letta/index.js +12 -0
  92. package/dist/letta/index.js.map +1 -0
  93. package/dist/letta/modelSettings.d.ts +176 -0
  94. package/dist/letta/modelSettings.d.ts.map +1 -0
  95. package/dist/letta/modelSettings.js +314 -0
  96. package/dist/letta/modelSettings.js.map +1 -0
  97. package/dist/letta/promptWrapping.d.ts +141 -0
  98. package/dist/letta/promptWrapping.d.ts.map +1 -0
  99. package/dist/letta/promptWrapping.js +213 -0
  100. package/dist/letta/promptWrapping.js.map +1 -0
  101. package/dist/letta/sandbox.d.ts +100 -0
  102. package/dist/letta/sandbox.d.ts.map +1 -0
  103. package/dist/letta/sandbox.js +151 -0
  104. package/dist/letta/sandbox.js.map +1 -0
  105. package/dist/letta/settingsFileSeed.d.ts +146 -0
  106. package/dist/letta/settingsFileSeed.d.ts.map +1 -0
  107. package/dist/letta/settingsFileSeed.js +177 -0
  108. package/dist/letta/settingsFileSeed.js.map +1 -0
  109. package/dist/letta/subprocessThrottle.d.ts +151 -0
  110. package/dist/letta/subprocessThrottle.d.ts.map +1 -0
  111. package/dist/letta/subprocessThrottle.js +195 -0
  112. package/dist/letta/subprocessThrottle.js.map +1 -0
  113. package/dist/letta/tpmRecovery.d.ts +202 -0
  114. package/dist/letta/tpmRecovery.d.ts.map +1 -0
  115. package/dist/letta/tpmRecovery.js +314 -0
  116. package/dist/letta/tpmRecovery.js.map +1 -0
  117. package/dist/letta/types.d.ts +54 -0
  118. package/dist/letta/types.d.ts.map +1 -0
  119. package/dist/letta/types.js +16 -0
  120. package/dist/letta/types.js.map +1 -0
  121. package/dist/observability/logger.d.ts +48 -0
  122. package/dist/observability/logger.d.ts.map +1 -0
  123. package/dist/observability/logger.js +81 -0
  124. package/dist/observability/logger.js.map +1 -0
  125. package/dist/observability/metrics.d.ts +53 -0
  126. package/dist/observability/metrics.d.ts.map +1 -0
  127. package/dist/observability/metrics.js +92 -0
  128. package/dist/observability/metrics.js.map +1 -0
  129. package/dist/routes/admin/agents.d.ts +63 -0
  130. package/dist/routes/admin/agents.d.ts.map +1 -0
  131. package/dist/routes/admin/agents.js +461 -0
  132. package/dist/routes/admin/agents.js.map +1 -0
  133. package/dist/routes/admin/rotatingMessages.d.ts +51 -0
  134. package/dist/routes/admin/rotatingMessages.d.ts.map +1 -0
  135. package/dist/routes/admin/rotatingMessages.js +292 -0
  136. package/dist/routes/admin/rotatingMessages.js.map +1 -0
  137. package/dist/routes/admin/sessions.d.ts +61 -0
  138. package/dist/routes/admin/sessions.d.ts.map +1 -0
  139. package/dist/routes/admin/sessions.js +232 -0
  140. package/dist/routes/admin/sessions.js.map +1 -0
  141. package/dist/routes/admin/settings.d.ts +110 -0
  142. package/dist/routes/admin/settings.d.ts.map +1 -0
  143. package/dist/routes/admin/settings.js +401 -0
  144. package/dist/routes/admin/settings.js.map +1 -0
  145. package/dist/routes/admin/users.d.ts +115 -0
  146. package/dist/routes/admin/users.d.ts.map +1 -0
  147. package/dist/routes/admin/users.js +374 -0
  148. package/dist/routes/admin/users.js.map +1 -0
  149. package/dist/routes/agents.d.ts +30 -0
  150. package/dist/routes/agents.d.ts.map +1 -0
  151. package/dist/routes/agents.js +55 -0
  152. package/dist/routes/agents.js.map +1 -0
  153. package/dist/routes/auth.d.ts +121 -0
  154. package/dist/routes/auth.d.ts.map +1 -0
  155. package/dist/routes/auth.js +422 -0
  156. package/dist/routes/auth.js.map +1 -0
  157. package/dist/routes/chat.d.ts +97 -0
  158. package/dist/routes/chat.d.ts.map +1 -0
  159. package/dist/routes/chat.js +484 -0
  160. package/dist/routes/chat.js.map +1 -0
  161. package/dist/routes/featureToggles.d.ts +34 -0
  162. package/dist/routes/featureToggles.d.ts.map +1 -0
  163. package/dist/routes/featureToggles.js +47 -0
  164. package/dist/routes/featureToggles.js.map +1 -0
  165. package/dist/routes/health.d.ts +24 -0
  166. package/dist/routes/health.d.ts.map +1 -0
  167. package/dist/routes/health.js +37 -0
  168. package/dist/routes/health.js.map +1 -0
  169. package/dist/routes/metrics.d.ts +35 -0
  170. package/dist/routes/metrics.d.ts.map +1 -0
  171. package/dist/routes/metrics.js +106 -0
  172. package/dist/routes/metrics.js.map +1 -0
  173. package/dist/routes/sessions.d.ts +161 -0
  174. package/dist/routes/sessions.d.ts.map +1 -0
  175. package/dist/routes/sessions.js +1501 -0
  176. package/dist/routes/sessions.js.map +1 -0
  177. package/dist/routes/stubs.d.ts +25 -0
  178. package/dist/routes/stubs.d.ts.map +1 -0
  179. package/dist/routes/stubs.js +25 -0
  180. package/dist/routes/stubs.js.map +1 -0
  181. package/dist/state/cron.d.ts +58 -0
  182. package/dist/state/cron.d.ts.map +1 -0
  183. package/dist/state/cron.js +160 -0
  184. package/dist/state/cron.js.map +1 -0
  185. package/dist/state/rotationRunner.d.ts +96 -0
  186. package/dist/state/rotationRunner.d.ts.map +1 -0
  187. package/dist/state/rotationRunner.js +246 -0
  188. package/dist/state/rotationRunner.js.map +1 -0
  189. package/dist/state/rotationScheduler.d.ts +76 -0
  190. package/dist/state/rotationScheduler.d.ts.map +1 -0
  191. package/dist/state/rotationScheduler.js +124 -0
  192. package/dist/state/rotationScheduler.js.map +1 -0
  193. package/dist/state/turnRegistry.d.ts +95 -0
  194. package/dist/state/turnRegistry.d.ts.map +1 -0
  195. package/dist/state/turnRegistry.js +149 -0
  196. package/dist/state/turnRegistry.js.map +1 -0
  197. package/dist/state/turnRunner.d.ts +134 -0
  198. package/dist/state/turnRunner.d.ts.map +1 -0
  199. package/dist/state/turnRunner.js +476 -0
  200. package/dist/state/turnRunner.js.map +1 -0
  201. package/package.json +47 -0
  202. package/src/auth/argon2.ts +152 -0
  203. package/src/auth/encryption.ts +110 -0
  204. package/src/auth/jwt.ts +217 -0
  205. package/src/auth/middleware.ts +250 -0
  206. package/src/auth/passwordPolicy.ts +99 -0
  207. package/src/auth/roleRules.ts +497 -0
  208. package/src/auth/userView.ts +88 -0
  209. package/src/bootstrap.ts +254 -0
  210. package/src/db/connection.ts +75 -0
  211. package/src/db/migrate.ts +212 -0
  212. package/src/db/schema.ts +750 -0
  213. package/src/db/seed.ts +236 -0
  214. package/src/handlers/fetch.ts +251 -0
  215. package/src/handlers/nextjs.ts +49 -0
  216. package/src/handlers/responses.ts +95 -0
  217. package/src/handlers/routeTable.ts +188 -0
  218. package/src/handlers/router.ts +96 -0
  219. package/src/handlers/sse.ts +55 -0
  220. package/src/handlers/types.ts +104 -0
  221. package/src/index.ts +60 -0
  222. package/src/letta/client.ts +860 -0
  223. package/src/letta/eventTranslator.ts +667 -0
  224. package/src/letta/index.ts +46 -0
  225. package/src/letta/lettaCliShim.mjs +40 -0
  226. package/src/letta/sandbox.ts +167 -0
  227. package/src/letta/settingsFileSeed.ts +254 -0
  228. package/src/letta/subprocessThrottle.ts +251 -0
  229. package/src/letta/types.ts +65 -0
  230. package/src/observability/logger.ts +103 -0
  231. package/src/observability/metrics.ts +114 -0
  232. package/src/routes/admin/agents.ts +574 -0
  233. package/src/routes/admin/rotatingMessages.ts +351 -0
  234. package/src/routes/admin/sessions.ts +283 -0
  235. package/src/routes/admin/settings.ts +463 -0
  236. package/src/routes/admin/users.ts +455 -0
  237. package/src/routes/agents.ts +66 -0
  238. package/src/routes/auth.ts +513 -0
  239. package/src/routes/chat.ts +534 -0
  240. package/src/routes/featureToggles.ts +52 -0
  241. package/src/routes/health.ts +44 -0
  242. package/src/routes/metrics.ts +111 -0
  243. package/src/routes/sessions.ts +1878 -0
  244. package/src/state/cron.ts +179 -0
  245. package/src/state/rotationRunner.ts +326 -0
  246. package/src/state/rotationScheduler.ts +164 -0
  247. package/src/state/turnRegistry.ts +210 -0
  248. package/src/state/turnRunner.ts +588 -0
@@ -0,0 +1,149 @@
1
+ /**
2
+ * In-memory broadcaster for live turn streams.
3
+ *
4
+ * Every active turn has at most one writer (the runner) and zero-or-more
5
+ * subscribers (the original `POST /chat` connection + every
6
+ * `GET /chat/:turn_id/events?from_seq=N` resumption connection still
7
+ * running while the turn is live).
8
+ *
9
+ * Persistence lives in `turn_events` (§11) — the registry only handles the
10
+ * **live attach** part of resumption. The first half of a resumption read
11
+ * (replay from `from_seq`) is a plain DB query.
12
+ *
13
+ * The registry is process-local — this matches the single-customer
14
+ * deployment model (§1). When ai-hub scales to multiple replicas in a
15
+ * v1.x release, this gets a Redis-backed implementation behind the same
16
+ * interface; the wire protocol (§9) and the resumption contract (§6.3.2)
17
+ * stay unchanged.
18
+ *
19
+ * @see SPECIFICATIONS.md §6.3.2 — resumption endpoint
20
+ * @see SPECIFICATIONS.md §6.6 — server-authoritative state machine
21
+ * @see SPECIFICATIONS.md §11 — `turn_events` table
22
+ */
23
+ /**
24
+ * Process-local map of live turn channels. The map prunes a channel on
25
+ * close as soon as every subscriber has unsubscribed (or immediately if
26
+ * no subscribers are attached).
27
+ */
28
+ const channels = new Map();
29
+ /**
30
+ * Begins a new live turn channel.
31
+ *
32
+ * The runner calls this when it inserts the `turn` row, before it starts
33
+ * pumping events. Returns an opaque `TurnPublisher` the runner uses to
34
+ * publish + close.
35
+ *
36
+ * @param turnId - the freshly-created turn id.
37
+ * @returns the publisher handle.
38
+ */
39
+ export function openTurnChannel(turnId) {
40
+ if (channels.has(turnId)) {
41
+ throw new Error(`Turn ${turnId} already has an open channel.`);
42
+ }
43
+ const channel = {
44
+ lastSeq: -1,
45
+ closed: false,
46
+ listeners: new Set(),
47
+ closeListeners: new Set(),
48
+ cancelController: new AbortController(),
49
+ };
50
+ channels.set(turnId, channel);
51
+ return {
52
+ cancelSignal: channel.cancelController.signal,
53
+ publish(event) {
54
+ channel.lastSeq = event.seq;
55
+ for (const listener of channel.listeners) {
56
+ try {
57
+ listener(event);
58
+ }
59
+ catch {
60
+ /* swallow — a misbehaving listener cannot break the channel */
61
+ }
62
+ }
63
+ },
64
+ close() {
65
+ if (channel.closed)
66
+ return;
67
+ channel.closed = true;
68
+ for (const cb of channel.closeListeners) {
69
+ try {
70
+ cb();
71
+ }
72
+ catch {
73
+ /* ignored */
74
+ }
75
+ }
76
+ channel.closeListeners.clear();
77
+ // Drop the channel once every subscriber unsubscribed. If nobody is
78
+ // listening at close time, prune immediately.
79
+ if (channel.listeners.size === 0) {
80
+ channels.delete(turnId);
81
+ }
82
+ },
83
+ };
84
+ }
85
+ /**
86
+ * Subscribes to a live turn channel.
87
+ *
88
+ * Returns `null` when the turn is not active (either never opened or
89
+ * already closed) — the caller should fall back to replaying persisted
90
+ * events from `turn_events` instead.
91
+ *
92
+ * @param turnId - the turn id to attach to.
93
+ * @param listener - called once per event (with `seq` already assigned).
94
+ * @param onClose - called once when the channel closes (after final event).
95
+ * @returns an unsubscribe function, or `null` when the channel is closed.
96
+ */
97
+ export function subscribeToTurn(turnId, listener, onClose) {
98
+ const channel = channels.get(turnId);
99
+ if (!channel || channel.closed)
100
+ return null;
101
+ channel.listeners.add(listener);
102
+ channel.closeListeners.add(onClose);
103
+ return () => {
104
+ channel.listeners.delete(listener);
105
+ channel.closeListeners.delete(onClose);
106
+ if (channel.closed && channel.listeners.size === 0) {
107
+ channels.delete(turnId);
108
+ }
109
+ };
110
+ }
111
+ /**
112
+ * Returns `true` when the turn has an open channel right now.
113
+ *
114
+ * The chat handler uses this to disambiguate "turn is in flight" from
115
+ * "turn completed long ago" without having to query the DB twice.
116
+ */
117
+ export function isTurnLive(turnId) {
118
+ const channel = channels.get(turnId);
119
+ return !!channel && !channel.closed;
120
+ }
121
+ /**
122
+ * Test-only utility — wipes the registry so tests can isolate from each
123
+ * other. Production code never calls this.
124
+ */
125
+ export function _resetTurnRegistryForTests() {
126
+ channels.clear();
127
+ }
128
+ /**
129
+ * Triggers cancellation of the named turn. The runner is expected to
130
+ * have wired its run to the publisher's `cancelSignal`; firing it from
131
+ * here aborts the upstream Letta call and short-circuits the loop.
132
+ *
133
+ * Idempotent: calling on a closed / unknown turn is a no-op. The
134
+ * `POST /chat/:id/cancel` route's user-facing 200 response covers
135
+ * race-conditions where the turn terminated between the request and
136
+ * this call.
137
+ *
138
+ * @param turnId - the turn to cancel.
139
+ * @returns `true` if the signal was fired, `false` if the channel is
140
+ * closed or unknown.
141
+ */
142
+ export function requestTurnCancellation(turnId) {
143
+ const channel = channels.get(turnId);
144
+ if (!channel || channel.closed)
145
+ return false;
146
+ channel.cancelController.abort();
147
+ return true;
148
+ }
149
+ //# sourceMappingURL=turnRegistry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"turnRegistry.js","sourceRoot":"","sources":["../../src/state/turnRegistry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,134 @@
1
+ /**
2
+ * Server-authoritative turn lifecycle (§6.6, §10).
3
+ *
4
+ * `runTurn(...)` is the one entry point that:
5
+ *
6
+ * 1. Inserts the `turn` row in status=running, phase=model_text.
7
+ * 2. Opens a live channel (`turnRegistry.openTurnChannel`) so concurrent
8
+ * resumption attempts can attach.
9
+ * 3. Emits `stream_start` (seq 0).
10
+ * 4. Calls `LettaClient.streamUserMessage(...)` which spawns a Letta
11
+ * Code subprocess, acquires the throttle lease, sends the user
12
+ * message. Returns a `ChatTurnHandle`.
13
+ * 5. Iterates the handle's `events` stream:
14
+ * - Non-terminal SDK messages → `translateSdkMessage(...)` →
15
+ * stamps + persists + broadcasts each emitted ai-hub event.
16
+ * - Terminal `result` SDK message → `finalizeTerminal(...)` →
17
+ * emits the closing `assistant_message_complete` + `stream_end`
18
+ * with the correct reason (`done` / `cancelled` / `error`).
19
+ * 6. On cancellation (caller signal OR `requestTurnCancellation`):
20
+ * calls `handle.abort()` to send `interrupt` to the CLI, keeps
21
+ * draining until terminal, then closes.
22
+ * 7. On throttle rejection (`ServerOverloadedError`): emits
23
+ * `error{code:"server_overloaded"}` + `stream_end{error}`.
24
+ * Transitions turn → failed.
25
+ * 8. On unhandled error: emits `error` + `stream_end{error}`,
26
+ * `turn.status = "failed"`.
27
+ * 9. Always calls `handle.close()` in finally (releases subprocess +
28
+ * throttle lease).
29
+ *
30
+ * @see SPECIFICATIONS.md §6.3.2 — chat / SSE
31
+ * @see SPECIFICATIONS.md §6.6 — state-machine ownership
32
+ * @see SPECIFICATIONS.md §6.9 — cancellation
33
+ * @see SPECIFICATIONS.md §9 — wire protocol
34
+ * @see SPECIFICATIONS.md §10 — state machine
35
+ */
36
+ import type { AIHubEvent, TurnStatus } from "@data-club/ai-hub";
37
+ import type { DrizzleDB } from "../db/connection.js";
38
+ import { type LettaClient } from "../letta/client.js";
39
+ import type { Logger } from "../observability/logger.js";
40
+ /** The ai-hub SSE wire-protocol version this server speaks (§9.1). */
41
+ export declare const WIRE_PROTOCOL_VERSION = "1.0";
42
+ /** Parameters for `runTurn`. */
43
+ export interface RunTurnOpts {
44
+ /** Drizzle handle. */
45
+ db: DrizzleDB;
46
+ /** Letta client wrapper (production wraps the SDKs; tests mock). */
47
+ lettaClient: LettaClient;
48
+ /** Pino logger for this request. */
49
+ logger: Logger;
50
+ /** Per-request id for log correlation (stamped on `error` events). */
51
+ requestId: string;
52
+ /** Owner of the session. */
53
+ userId: string;
54
+ /** ai-hub session id this turn belongs to. */
55
+ sessionId: string;
56
+ /** The Letta conversation id stored on the session row. */
57
+ lettaConversationId: string;
58
+ /** The Letta agent id stored on the session row. */
59
+ lettaAgentId: string;
60
+ /**
61
+ * Step-12.5 — absolute path of the per-session sandbox folder, or
62
+ * `null` when the session has no sandbox (today's stateless shape).
63
+ * Threaded as `cwd` into the Letta Code subprocess spawn so the
64
+ * agent's filesystem tools operate inside the seeded folder. When
65
+ * non-null, also flips the disallowed-tools list to re-enable
66
+ * `Read` / `Write` / `Bash` / etc.
67
+ */
68
+ sandboxDir: string | null;
69
+ /** The user's typed message. */
70
+ userMessage: string;
71
+ /** Optional idempotency key from the request body. */
72
+ idempotencyKey?: string;
73
+ /**
74
+ * Listener that receives every event the runner emits. The chat
75
+ * handler subscribes its SSE writer here. `null` events signal
76
+ * "channel closed; no more events coming."
77
+ */
78
+ onEvent: (event: AIHubEvent | null) => void;
79
+ /**
80
+ * Caller-supplied AbortSignal. When aborted, the runner calls
81
+ * `handle.abort()` on the spawned Letta Code subprocess and emits
82
+ * `stream_end{reason:"cancelled"}` after the upstream terminal
83
+ * `result` arrives.
84
+ */
85
+ signal?: AbortSignal;
86
+ }
87
+ /** Returned by `runTurn`. The runner returns after `turn_event`s are committed. */
88
+ export interface RunTurnResult {
89
+ /** The new turn id (the `turn_id` carried in `stream_start`). */
90
+ turnId: string;
91
+ /** Terminal status (`done` / `cancelled` / `failed`). */
92
+ status: Exclude<TurnStatus, "idle" | "running">;
93
+ }
94
+ /**
95
+ * Runs one turn from "user pressed Send" to terminal status. Returns a
96
+ * promise that resolves when the runner has persisted the terminal
97
+ * event(s), closed the live channel, and torn down the Letta Code
98
+ * subprocess.
99
+ *
100
+ * The caller is expected to keep `onEvent` alive for the entire run.
101
+ *
102
+ * @param opts - see `RunTurnOpts`.
103
+ * @returns the turn id and terminal status.
104
+ */
105
+ export declare function runTurn(opts: RunTurnOpts): Promise<RunTurnResult>;
106
+ /**
107
+ * Replays persisted `turn_event` rows newer than `fromSeq`, returned as
108
+ * ai-hub-shaped events. Used by `GET /chat/:turn_id/events?from_seq=N`
109
+ * for the replay half of resumption.
110
+ *
111
+ * @param db - Drizzle handle.
112
+ * @param turnId - the turn id.
113
+ * @param fromSeq - replays events with `seq > fromSeq`.
114
+ * @returns the persisted events.
115
+ *
116
+ * @see SPECIFICATIONS.md §6.3.2 — resumption
117
+ */
118
+ export declare function replayPersistedEvents(db: DrizzleDB, turnId: string, fromSeq: number): ReadonlyArray<AIHubEvent>;
119
+ /**
120
+ * Idempotently marks a turn as cancelled in the DB. Returns the row's
121
+ * resulting status. Called by `POST /chat/:turn_id/cancel` after firing
122
+ * `requestTurnCancellation`. The runner's catch arm also persists
123
+ * `cancelled` via `syncTurnRow`; this helper just guarantees the row
124
+ * is updated when the runner has already exited (terminal-after-cancel
125
+ * race).
126
+ *
127
+ * Does not overwrite `done` / `failed` — those are terminal states.
128
+ *
129
+ * @param db - Drizzle handle.
130
+ * @param turnId - the turn to cancel.
131
+ * @returns the row's resulting status, or `null` if no such row.
132
+ */
133
+ export declare function markCancelled(db: DrizzleDB, turnId: string): TurnStatus | null;
134
+ //# sourceMappingURL=turnRunner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"turnRunner.d.ts","sourceRoot":"","sources":["../../src/state/turnRunner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAMH,OAAO,KAAK,EACV,UAAU,EAGV,UAAU,EACX,MAAM,mBAAmB,CAAC;AAG3B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAA8C,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AASlG,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAGzD,sEAAsE;AACtE,eAAO,MAAM,qBAAqB,QAAQ,CAAC;AAM3C,gCAAgC;AAChC,MAAM,WAAW,WAAW;IAC1B,sBAAsB;IACtB,EAAE,EAAE,SAAS,CAAC;IACd,oEAAoE;IACpE,WAAW,EAAE,WAAW,CAAC;IACzB,oCAAoC;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,sEAAsE;IACtE,SAAS,EAAE,MAAM,CAAC;IAClB,4BAA4B;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,SAAS,EAAE,MAAM,CAAC;IAClB,2DAA2D;IAC3D,mBAAmB,EAAE,MAAM,CAAC;IAC5B,oDAAoD;IACpD,YAAY,EAAE,MAAM,CAAC;IACrB;;;;;;;OAOG;IACH,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,gCAAgC;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,sDAAsD;IACtD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;OAIG;IACH,OAAO,EAAE,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,KAAK,IAAI,CAAC;IAC5C;;;;;OAKG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,mFAAmF;AACnF,MAAM,WAAW,aAAa;IAC5B,iEAAiE;IACjE,MAAM,EAAE,MAAM,CAAC;IACf,yDAAyD;IACzD,MAAM,EAAE,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;CACjD;AAMD;;;;;;;;;;GAUG;AACH,wBAAsB,OAAO,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC,CA4VvE;AAuCD;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CACnC,EAAE,EAAE,SAAS,EACb,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GACd,aAAa,CAAC,UAAU,CAAC,CAa3B;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAC3B,EAAE,EAAE,SAAS,EACb,MAAM,EAAE,MAAM,GACb,UAAU,GAAG,IAAI,CAenB"}