@tokenfactory/acc-runner 0.38.3 → 0.40.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.
- package/dist/chat-companion.d.ts +101 -0
- package/dist/chat-companion.d.ts.map +1 -0
- package/dist/chat-companion.js +183 -0
- package/dist/chat-companion.js.map +1 -0
- package/dist/chat-lane.d.ts +286 -0
- package/dist/chat-lane.d.ts.map +1 -0
- package/dist/chat-lane.js +328 -0
- package/dist/chat-lane.js.map +1 -0
- package/dist/chat-transport.d.ts +51 -0
- package/dist/chat-transport.d.ts.map +1 -0
- package/dist/chat-transport.js +105 -0
- package/dist/chat-transport.js.map +1 -0
- package/dist/cli.js +45 -0
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +38 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +39 -0
- package/dist/config.js.map +1 -1
- package/dist/doctor.d.ts +1 -0
- package/dist/doctor.d.ts.map +1 -1
- package/dist/doctor.js +122 -1
- package/dist/doctor.js.map +1 -1
- package/dist/login.d.ts +3 -2
- package/dist/login.d.ts.map +1 -1
- package/dist/login.js +8 -2
- package/dist/login.js.map +1 -1
- package/dist/runtime/chat-circuit-breaker.d.ts +66 -0
- package/dist/runtime/chat-circuit-breaker.d.ts.map +1 -0
- package/dist/runtime/chat-circuit-breaker.js +128 -0
- package/dist/runtime/chat-circuit-breaker.js.map +1 -0
- package/dist/types.d.ts +8 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/watch.d.ts +27 -1
- package/dist/watch.d.ts.map +1 -1
- package/dist/watch.js +101 -1
- package/dist/watch.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CC-1B (TURN-LANE): the runner-side chat claim lane + turn lifecycle.
|
|
3
|
+
*
|
|
4
|
+
* The chat lane is a SECOND lane beside the batch task/review lanes
|
|
5
|
+
* (docs/acc/WORKSPACE_COMMAND_CHAT_CONTRACTS.md §1). A *turn* is one operator
|
|
6
|
+
* prompt → one streamed agent reply. Turns are queued server-side; a companion
|
|
7
|
+
* runner CLAIMS a queued turn under a time-boxed lease (acc.claim_chat_turn,
|
|
8
|
+
* advisory-lock per conversation — migration 0254), STREAMS the reply as deltas,
|
|
9
|
+
* and COMPLETES it — or REQUEUES it when it loses the lease/capacity, so another
|
|
10
|
+
* companion finishes the turn without burning an operator turn.
|
|
11
|
+
*
|
|
12
|
+
* This module owns:
|
|
13
|
+
* 1. The turn LIFECYCLE state machine (queued → claimed → streaming →
|
|
14
|
+
* awaiting_confirmation → done | capacity_paused | failed | cancelled),
|
|
15
|
+
* with a transition validator.
|
|
16
|
+
* 2. The failure → disposition mapping: infra failures REQUEUE (never burn a
|
|
17
|
+
* turn); `claude_exit_1`-class failures open the chat circuit breaker AND
|
|
18
|
+
* requeue; a genuine agent error COMPLETES the turn as `error`.
|
|
19
|
+
* 3. `driveChatTurn` — the per-turn driver, an engine-agnostic loop over a
|
|
20
|
+
* `ConformantAgentEngine.streamTurn` that emits exactly ONE terminal
|
|
21
|
+
* transport call (complete OR requeue) so an abort mid-stream produces a
|
|
22
|
+
* clean requeue with no duplicate side effects.
|
|
23
|
+
* 4. `computeChatClaimBudget` — the chat-lane max-share knob so chat turns can
|
|
24
|
+
* never starve the code/review lanes of concurrency slots.
|
|
25
|
+
*
|
|
26
|
+
* Every side effect is behind the injectable `ChatLaneTransport` + the engine +
|
|
27
|
+
* an optional abort signal, so the whole lifecycle is exercised deterministically
|
|
28
|
+
* (tests/unit/chat-lane*.test.ts) with no `claude` binary and no network.
|
|
29
|
+
*/
|
|
30
|
+
import { classifyClaudeExit } from "./failure-classifier.js";
|
|
31
|
+
import { isChatCircuitTripClass } from "./runtime/chat-circuit-breaker.js";
|
|
32
|
+
/* ------------------------------------------------------------------ *
|
|
33
|
+
* 1. Wire shapes (runner-side mirror of the frozen chat-lane contract)
|
|
34
|
+
*
|
|
35
|
+
* The tier/capacity/capability types are pinned in engines/types.ts; the turn
|
|
36
|
+
* message payloads below mirror src/lib/workspace-command-chat.ts (the acc-runner
|
|
37
|
+
* package does not import from the web-app tree). Additive fields do not bump
|
|
38
|
+
* CHAT_LANE_PROTOCOL_VERSION — a peer on an older minor ignores unknown fields.
|
|
39
|
+
* ------------------------------------------------------------------ */
|
|
40
|
+
/** Chat-lane protocol version (mirrors the web-app constant of the same name). */
|
|
41
|
+
export const CHAT_LANE_PROTOCOL_VERSION = 1;
|
|
42
|
+
/** Terminal lifecycle states — no further transition is valid from these. */
|
|
43
|
+
export const TERMINAL_CHAT_LIFECYCLE = [
|
|
44
|
+
"done",
|
|
45
|
+
"capacity_paused",
|
|
46
|
+
"failed",
|
|
47
|
+
"cancelled",
|
|
48
|
+
"requeued",
|
|
49
|
+
];
|
|
50
|
+
const CHAT_LIFECYCLE_TRANSITIONS = {
|
|
51
|
+
queued: ["claimed", "cancelled"],
|
|
52
|
+
claimed: ["streaming", "requeued", "failed", "cancelled", "capacity_paused"],
|
|
53
|
+
streaming: [
|
|
54
|
+
"awaiting_confirmation",
|
|
55
|
+
"done",
|
|
56
|
+
"failed",
|
|
57
|
+
"cancelled",
|
|
58
|
+
"requeued",
|
|
59
|
+
"capacity_paused",
|
|
60
|
+
],
|
|
61
|
+
awaiting_confirmation: ["done", "cancelled"],
|
|
62
|
+
done: [],
|
|
63
|
+
capacity_paused: [],
|
|
64
|
+
failed: [],
|
|
65
|
+
cancelled: [],
|
|
66
|
+
requeued: [],
|
|
67
|
+
};
|
|
68
|
+
/** True when `to` is a legal next lifecycle state from `from`. */
|
|
69
|
+
export function isValidChatTransition(from, to) {
|
|
70
|
+
return CHAT_LIFECYCLE_TRANSITIONS[from]?.includes(to) ?? false;
|
|
71
|
+
}
|
|
72
|
+
/** True when the lifecycle state is terminal (the turn is settled). */
|
|
73
|
+
export function isTerminalChatLifecycle(state) {
|
|
74
|
+
return TERMINAL_CHAT_LIFECYCLE.includes(state);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Map a shared-taxonomy `ClassifiedExit` onto a chat-lane disposition. The split
|
|
78
|
+
* mirrors the batch lane's machine-vs-task rule but reroutes the terminal action
|
|
79
|
+
* to the chat lane's requeue/circuit model:
|
|
80
|
+
*
|
|
81
|
+
* capacity_exhausted | subscription_exhausted → requeue (capacity_lost) [infra]
|
|
82
|
+
* claude_unavailable (transient) → requeue (engine_unavailable) [infra]
|
|
83
|
+
* auth_expired → quarantine_requeue (credential_lost)
|
|
84
|
+
* env_broken → quarantine_requeue (engine_unavailable)
|
|
85
|
+
* usage_limit (hard wall) → quarantine_requeue (capacity_lost)
|
|
86
|
+
* task_error → error (turn completes 'error')
|
|
87
|
+
*/
|
|
88
|
+
export function classifyChatDisposition(classified) {
|
|
89
|
+
const cls = classified.class;
|
|
90
|
+
const detail = classified.detail;
|
|
91
|
+
if (cls === "task_error") {
|
|
92
|
+
return { action: "error", detail };
|
|
93
|
+
}
|
|
94
|
+
if (isChatCircuitTripClass(cls)) {
|
|
95
|
+
const reason = cls === "auth_expired"
|
|
96
|
+
? "credential_lost"
|
|
97
|
+
: cls === "usage_limit"
|
|
98
|
+
? "capacity_lost"
|
|
99
|
+
: "engine_unavailable";
|
|
100
|
+
return { action: "quarantine_requeue", reason, cause: cls, detail };
|
|
101
|
+
}
|
|
102
|
+
// Everything else (capacity_exhausted, subscription_exhausted, transient
|
|
103
|
+
// claude_unavailable) is recoverable infra → requeue, no circuit trip.
|
|
104
|
+
const reason = cls === "claude_unavailable" ? "engine_unavailable" : "capacity_lost";
|
|
105
|
+
return { action: "requeue", reason, quarantine: false, detail };
|
|
106
|
+
}
|
|
107
|
+
/** Coerce an arbitrary thrown value into a `ClassifiedExit` via the shared mapper. */
|
|
108
|
+
function classifyThrown(err, engine) {
|
|
109
|
+
const anyErr = err;
|
|
110
|
+
const exitCode = typeof anyErr?.exitCode === "number" ? anyErr.exitCode : 1;
|
|
111
|
+
const stderr = anyErr?.stderr ?? anyErr?.message ?? String(err ?? "");
|
|
112
|
+
const stdout = anyErr?.stdout ?? "";
|
|
113
|
+
// Prefer the engine's own classifier (delegates to failure-classifier) so a
|
|
114
|
+
// future engine can override, falling back to the shared mapper directly.
|
|
115
|
+
try {
|
|
116
|
+
return engine.classifyFailure(exitCode, stderr, stdout);
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
return classifyClaudeExit(exitCode, stderr, stdout);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/** True when the abort was requested (signal seam + AbortError name). */
|
|
123
|
+
function wasAborted(signal, err) {
|
|
124
|
+
if (signal?.aborted)
|
|
125
|
+
return true;
|
|
126
|
+
const name = err?.name;
|
|
127
|
+
return name === "AbortError";
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Drive one claimed turn to a terminal state. Emits EXACTLY ONE terminal
|
|
131
|
+
* transport call (complete OR requeue), guarded by `settled`, so a mid-stream
|
|
132
|
+
* abort/failure can never both requeue AND complete the same turn — the
|
|
133
|
+
* "kill mid-stream ⇒ clean requeue, no dup side effects" invariant.
|
|
134
|
+
*/
|
|
135
|
+
export async function driveChatTurn(turn, deps) {
|
|
136
|
+
const emit = (lifecycle, detail) => deps.onEvent?.({ turnId: turn.id, conversationId: turn.conversation_id, lifecycle, detail });
|
|
137
|
+
let seq = 0;
|
|
138
|
+
let sawText = false;
|
|
139
|
+
let fullText = "";
|
|
140
|
+
const base = {
|
|
141
|
+
turnId: turn.id,
|
|
142
|
+
conversationId: turn.conversation_id,
|
|
143
|
+
totalSeq: 0,
|
|
144
|
+
quarantined: false,
|
|
145
|
+
};
|
|
146
|
+
const requeue = async (reason, detail, opts = {}) => {
|
|
147
|
+
if (opts.quarantine) {
|
|
148
|
+
await deps.onCircuitTrip?.({ cause: opts.quarantine.cause, detail });
|
|
149
|
+
}
|
|
150
|
+
await deps.transport.requeue(turn, { reason, requeue_count: turn.requeue_count + 1 });
|
|
151
|
+
const lifecycle = reason === "capacity_lost" && !opts.quarantine ? "capacity_paused" : "requeued";
|
|
152
|
+
emit(lifecycle, detail);
|
|
153
|
+
return { ...base, totalSeq: seq, lifecycle, requeueReason: reason, quarantined: !!opts.quarantine, detail };
|
|
154
|
+
};
|
|
155
|
+
const complete = async (outcome, lifecycle, detail) => {
|
|
156
|
+
await deps.transport.complete(turn, {
|
|
157
|
+
outcome,
|
|
158
|
+
total_seq: seq,
|
|
159
|
+
...(detail && outcome === "error" ? { error: detail } : {}),
|
|
160
|
+
...(lifecycle === "awaiting_confirmation" ? { awaiting_confirmation: true } : {}),
|
|
161
|
+
});
|
|
162
|
+
emit(lifecycle, detail);
|
|
163
|
+
return { ...base, totalSeq: seq, lifecycle, outcome, detail };
|
|
164
|
+
};
|
|
165
|
+
// claimed → streaming
|
|
166
|
+
await deps.transport.markStreaming?.(turn);
|
|
167
|
+
emit("streaming");
|
|
168
|
+
try {
|
|
169
|
+
const iter = deps.engine.streamTurn({
|
|
170
|
+
prompt: turn.prompt,
|
|
171
|
+
conversationId: turn.conversation_id,
|
|
172
|
+
turnId: turn.id,
|
|
173
|
+
...(deps.cwd !== undefined ? { cwd: deps.cwd } : {}),
|
|
174
|
+
...(deps.delegationToken !== undefined ? { delegationToken: deps.delegationToken } : {}),
|
|
175
|
+
...(deps.signal ? { signal: deps.signal } : {}),
|
|
176
|
+
});
|
|
177
|
+
for await (const chunk of iter) {
|
|
178
|
+
if (deps.signal?.aborted) {
|
|
179
|
+
// Abort observed mid-stream: stop streaming and requeue cleanly. We do
|
|
180
|
+
// NOT emit further deltas or a complete — the turn survives untouched.
|
|
181
|
+
return await requeue(deps.abortReason ?? "operator_cancelled", "aborted mid-stream");
|
|
182
|
+
}
|
|
183
|
+
await deps.transport.stream(turn, { seq: chunk.seq, delta: chunk.delta, done: chunk.done });
|
|
184
|
+
seq = chunk.seq + 1;
|
|
185
|
+
if (chunk.delta) {
|
|
186
|
+
sawText = true;
|
|
187
|
+
fullText += chunk.delta;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
catch (err) {
|
|
192
|
+
if (wasAborted(deps.signal, err)) {
|
|
193
|
+
return await requeue(deps.abortReason ?? "operator_cancelled", "aborted mid-stream");
|
|
194
|
+
}
|
|
195
|
+
const disposition = classifyChatDisposition(classifyThrown(err, deps.engine));
|
|
196
|
+
if (disposition.action === "error") {
|
|
197
|
+
return await complete("error", "failed", disposition.detail);
|
|
198
|
+
}
|
|
199
|
+
if (disposition.action === "quarantine_requeue") {
|
|
200
|
+
return await requeue(disposition.reason, disposition.detail, {
|
|
201
|
+
quarantine: { cause: disposition.cause },
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
return await requeue(disposition.reason, disposition.detail);
|
|
205
|
+
}
|
|
206
|
+
// Stream ended cleanly. A late abort (signalled after the last chunk) still
|
|
207
|
+
// requeues rather than completing.
|
|
208
|
+
if (deps.signal?.aborted) {
|
|
209
|
+
return await requeue(deps.abortReason ?? "operator_cancelled", "aborted after stream end");
|
|
210
|
+
}
|
|
211
|
+
// A clean stream with zero visible text may be a SILENT engine failure. Probe
|
|
212
|
+
// it (batch-lane parity): an unhealthy probe means the empty turn was really a
|
|
213
|
+
// machine fault, not a genuine empty reply.
|
|
214
|
+
if (!sawText && deps.silentFailureProbe) {
|
|
215
|
+
const probe = await deps.silentFailureProbe();
|
|
216
|
+
if (probe) {
|
|
217
|
+
const disposition = classifyChatDisposition(probe);
|
|
218
|
+
if (disposition.action === "error") {
|
|
219
|
+
return await complete("error", "failed", disposition.detail);
|
|
220
|
+
}
|
|
221
|
+
if (disposition.action === "quarantine_requeue") {
|
|
222
|
+
return await requeue(disposition.reason, disposition.detail, {
|
|
223
|
+
quarantine: { cause: disposition.cause },
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
return await requeue(disposition.reason, disposition.detail);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
if (deps.requiresConfirmation?.(fullText, turn)) {
|
|
230
|
+
return await complete("ok", "awaiting_confirmation");
|
|
231
|
+
}
|
|
232
|
+
return await complete("ok", "done");
|
|
233
|
+
}
|
|
234
|
+
/* ------------------------------------------------------------------ *
|
|
235
|
+
* 6. Max-share — the chat-lane concurrency knob
|
|
236
|
+
* ------------------------------------------------------------------ */
|
|
237
|
+
/** Env var carrying the chat-lane max-share fraction (0..1). */
|
|
238
|
+
export const CHAT_MAX_SHARE_ENV = "ACC_RUNNER_CHAT_MAX_SHARE";
|
|
239
|
+
/** Default chat-lane max share of runner concurrency. */
|
|
240
|
+
export const DEFAULT_CHAT_MAX_SHARE = 0.5;
|
|
241
|
+
/**
|
|
242
|
+
* Resolve the chat-lane max-share fraction from a raw env value. Blank/absent ⇒
|
|
243
|
+
* default; a value ≤0 disables chat claiming; a value ≥1 is clamped so at least
|
|
244
|
+
* one slot always remains for the code/review lanes (chat can never take the
|
|
245
|
+
* whole runner). Non-numeric ⇒ default (a typo must not starve either lane).
|
|
246
|
+
*/
|
|
247
|
+
export function resolveChatMaxShare(raw) {
|
|
248
|
+
const trimmed = (raw ?? "").trim();
|
|
249
|
+
if (!trimmed)
|
|
250
|
+
return DEFAULT_CHAT_MAX_SHARE;
|
|
251
|
+
const n = Number.parseFloat(trimmed);
|
|
252
|
+
if (!Number.isFinite(n))
|
|
253
|
+
return DEFAULT_CHAT_MAX_SHARE;
|
|
254
|
+
if (n <= 0)
|
|
255
|
+
return 0;
|
|
256
|
+
if (n >= 1)
|
|
257
|
+
return 1;
|
|
258
|
+
return n;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Compute how many NEW chat turns the runner may claim right now, given its
|
|
262
|
+
* concurrency ceiling and current mixed load. The max-share invariant guarantees
|
|
263
|
+
* the code/review lanes never starve:
|
|
264
|
+
*
|
|
265
|
+
* chatCeiling = clamp(floor(concurrency * maxShare), 0, concurrency - 1)
|
|
266
|
+
*
|
|
267
|
+
* i.e. chat may occupy at most `chatCeiling` slots, and that ceiling is capped at
|
|
268
|
+
* `concurrency - 1` so at least one slot is ALWAYS reservable for a code/review
|
|
269
|
+
* task even at maxShare = 1. The live budget then subtracts the chat turns
|
|
270
|
+
* already in flight and is further bounded by the runner's actual free capacity
|
|
271
|
+
* (concurrency − everything running). Returns 0 while the chat circuit is open or
|
|
272
|
+
* chat is disabled (maxShare ≤ 0).
|
|
273
|
+
*/
|
|
274
|
+
export function computeChatClaimBudget(opts) {
|
|
275
|
+
const concurrency = Math.max(1, Math.floor(opts.concurrencyLimit));
|
|
276
|
+
if (opts.circuitOpen)
|
|
277
|
+
return 0;
|
|
278
|
+
const share = opts.maxShare <= 0 ? 0 : opts.maxShare >= 1 ? 1 : opts.maxShare;
|
|
279
|
+
if (share <= 0)
|
|
280
|
+
return 0;
|
|
281
|
+
// Reserve ≥1 slot for code/review: chat ceiling never reaches full concurrency.
|
|
282
|
+
const chatCeiling = Math.min(Math.max(0, Math.floor(concurrency * share)), concurrency - 1);
|
|
283
|
+
const active = Math.max(0, Math.floor(opts.activeChatTurns));
|
|
284
|
+
const codeActive = Math.max(0, Math.floor(opts.activeCodeTasks));
|
|
285
|
+
const shareHeadroom = chatCeiling - active;
|
|
286
|
+
const freeSlots = concurrency - active - codeActive;
|
|
287
|
+
return Math.max(0, Math.min(shareHeadroom, freeSlots));
|
|
288
|
+
}
|
|
289
|
+
/* ------------------------------------------------------------------ *
|
|
290
|
+
* 7. Chat-lane runner config (env resolution)
|
|
291
|
+
* ------------------------------------------------------------------ */
|
|
292
|
+
/** Env var that opts the runner into the chat lane (a companion). */
|
|
293
|
+
export const CHAT_LANE_ENABLED_ENV = "ACC_RUNNER_CHAT_LANE";
|
|
294
|
+
/** Env var carrying the requested per-turn lease (ms). */
|
|
295
|
+
export const CHAT_LEASE_MS_ENV = "ACC_RUNNER_CHAT_LEASE_MS";
|
|
296
|
+
/** Default per-turn lease; mirrors acc.claim_chat_turn's default (60s). */
|
|
297
|
+
export const DEFAULT_CHAT_LEASE_MS = 60_000;
|
|
298
|
+
/** True when the value is a recognised truthy flag ("1"/"true"/"yes"/"on"). */
|
|
299
|
+
function isTruthyFlag(raw) {
|
|
300
|
+
const v = (raw ?? "").trim().toLowerCase();
|
|
301
|
+
return v === "1" || v === "true" || v === "yes" || v === "on";
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Resolve the requested per-turn lease. Blank/absent/non-numeric ⇒ default;
|
|
305
|
+
* numeric values clamp to the RPC's own accepted window (1s..10m) so the runner
|
|
306
|
+
* never asks for a lease the server would silently clamp anyway.
|
|
307
|
+
*/
|
|
308
|
+
export function resolveChatLeaseMs(raw) {
|
|
309
|
+
const n = Number.parseInt((raw ?? "").trim(), 10);
|
|
310
|
+
if (!Number.isFinite(n))
|
|
311
|
+
return DEFAULT_CHAT_LEASE_MS;
|
|
312
|
+
return Math.min(600_000, Math.max(1_000, n));
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Resolve the chat-lane knobs from the environment in ONE place so the companion
|
|
316
|
+
* loop and any caps/telemetry read the same values. A share of 0 (or the flag
|
|
317
|
+
* absent) means the runner does not claim chat turns even when enabled — the
|
|
318
|
+
* code/review lanes keep the whole runner.
|
|
319
|
+
*/
|
|
320
|
+
export function resolveChatLaneConfig(env = process.env) {
|
|
321
|
+
const maxShare = resolveChatMaxShare(env[CHAT_MAX_SHARE_ENV]);
|
|
322
|
+
return {
|
|
323
|
+
enabled: isTruthyFlag(env[CHAT_LANE_ENABLED_ENV]) && maxShare > 0,
|
|
324
|
+
maxShare,
|
|
325
|
+
leaseMs: resolveChatLeaseMs(env[CHAT_LEASE_MS_ENV]),
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
//# sourceMappingURL=chat-lane.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chat-lane.js","sourceRoot":"","sources":["../src/chat-lane.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,OAAO,EAAE,kBAAkB,EAA6C,MAAM,yBAAyB,CAAC;AACxG,OAAO,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAC;AAO3E;;;;;;;wEAOwE;AAExE,kFAAkF;AAClF,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAU,CAAC;AAiFrD,6EAA6E;AAC7E,MAAM,CAAC,MAAM,uBAAuB,GAAiC;IACnE,MAAM;IACN,iBAAiB;IACjB,QAAQ;IACR,WAAW;IACX,UAAU;CACX,CAAC;AAEF,MAAM,0BAA0B,GAA4D;IAC1F,MAAM,EAAE,CAAC,SAAS,EAAE,WAAW,CAAC;IAChC,OAAO,EAAE,CAAC,WAAW,EAAE,UAAU,EAAE,QAAQ,EAAE,WAAW,EAAE,iBAAiB,CAAC;IAC5E,SAAS,EAAE;QACT,uBAAuB;QACvB,MAAM;QACN,QAAQ;QACR,WAAW;QACX,UAAU;QACV,iBAAiB;KAClB;IACD,qBAAqB,EAAE,CAAC,MAAM,EAAE,WAAW,CAAC;IAC5C,IAAI,EAAE,EAAE;IACR,eAAe,EAAE,EAAE;IACnB,MAAM,EAAE,EAAE;IACV,SAAS,EAAE,EAAE;IACb,QAAQ,EAAE,EAAE;CACb,CAAC;AAEF,kEAAkE;AAClE,MAAM,UAAU,qBAAqB,CAAC,IAAuB,EAAE,EAAqB;IAClF,OAAO,0BAA0B,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,EAAE,CAAC,IAAI,KAAK,CAAC;AACjE,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,uBAAuB,CAAC,KAAwB;IAC9D,OAAO,uBAAuB,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AACjD,CAAC;AAyBD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,uBAAuB,CAAC,UAA0B;IAChE,MAAM,GAAG,GAAG,UAAU,CAAC,KAAK,CAAC;IAC7B,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC;IACjC,IAAI,GAAG,KAAK,YAAY,EAAE,CAAC;QACzB,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IACrC,CAAC;IACD,IAAI,sBAAsB,CAAC,GAAG,CAAC,EAAE,CAAC;QAChC,MAAM,MAAM,GACV,GAAG,KAAK,cAAc;YACpB,CAAC,CAAC,iBAAiB;YACnB,CAAC,CAAC,GAAG,KAAK,aAAa;gBACrB,CAAC,CAAC,eAAe;gBACjB,CAAC,CAAC,oBAAoB,CAAC;QAC7B,OAAO,EAAE,MAAM,EAAE,oBAAoB,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;IACtE,CAAC;IACD,yEAAyE;IACzE,uEAAuE;IACvE,MAAM,MAAM,GACV,GAAG,KAAK,oBAAoB,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,eAAe,CAAC;IACxE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AAClE,CAAC;AAuGD,sFAAsF;AACtF,SAAS,cAAc,CAAC,GAAY,EAAE,MAA6B;IACjE,MAAM,MAAM,GAAG,GAAuF,CAAC;IACvG,MAAM,QAAQ,GAAG,OAAO,MAAM,EAAE,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5E,MAAM,MAAM,GAAG,MAAM,EAAE,MAAM,IAAI,MAAM,EAAE,OAAO,IAAI,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC;IACtE,MAAM,MAAM,GAAG,MAAM,EAAE,MAAM,IAAI,EAAE,CAAC;IACpC,4EAA4E;IAC5E,0EAA0E;IAC1E,IAAI,CAAC;QACH,OAAO,MAAM,CAAC,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACtD,CAAC;AACH,CAAC;AAED,yEAAyE;AACzE,SAAS,UAAU,CAAC,MAA+B,EAAE,GAAa;IAChE,IAAI,MAAM,EAAE,OAAO;QAAE,OAAO,IAAI,CAAC;IACjC,MAAM,IAAI,GAAI,GAAyB,EAAE,IAAI,CAAC;IAC9C,OAAO,IAAI,KAAK,YAAY,CAAC;AAC/B,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,IAAqB,EACrB,IAAuB;IAEvB,MAAM,IAAI,GAAG,CAAC,SAA4B,EAAE,MAAe,EAAE,EAAE,CAC7D,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,cAAc,EAAE,IAAI,CAAC,eAAe,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;IAE/F,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,IAAI,QAAQ,GAAG,EAAE,CAAC;IAElB,MAAM,IAAI,GAAG;QACX,MAAM,EAAE,IAAI,CAAC,EAAE;QACf,cAAc,EAAE,IAAI,CAAC,eAAe;QACpC,QAAQ,EAAE,CAAC;QACX,WAAW,EAAE,KAAK;KACV,CAAC;IAEX,MAAM,OAAO,GAAG,KAAK,EACnB,MAA6B,EAC7B,MAAc,EACd,OAAoD,EAAE,EACxB,EAAE;QAChC,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QACvE,CAAC;QACD,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,aAAa,EAAE,IAAI,CAAC,aAAa,GAAG,CAAC,EAAE,CAAC,CAAC;QACtF,MAAM,SAAS,GACb,MAAM,KAAK,eAAe,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,UAAU,CAAC;QAClF,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QACxB,OAAO,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,CAAC;IAC9G,CAAC,CAAC;IAEF,MAAM,QAAQ,GAAG,KAAK,EACpB,OAAwB,EACxB,SAAiG,EACjG,MAAe,EACe,EAAE;QAChC,MAAM,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE;YAClC,OAAO;YACP,SAAS,EAAE,GAAG;YACd,GAAG,CAAC,MAAM,IAAI,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3D,GAAG,CAAC,SAAS,KAAK,uBAAuB,CAAC,CAAC,CAAC,EAAE,qBAAqB,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAClF,CAAC,CAAC;QACH,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QACxB,OAAO,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAChE,CAAC,CAAC;IAEF,sBAAsB;IACtB,MAAM,IAAI,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,IAAI,CAAC,CAAC;IAC3C,IAAI,CAAC,WAAW,CAAC,CAAC;IAElB,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC;YAClC,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,cAAc,EAAE,IAAI,CAAC,eAAe;YACpC,MAAM,EAAE,IAAI,CAAC,EAAE;YACf,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACpD,GAAG,CAAC,IAAI,CAAC,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACxF,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAChD,CAAC,CAAC;QAEH,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,IAAwC,EAAE,CAAC;YACnE,IAAI,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;gBACzB,uEAAuE;gBACvE,uEAAuE;gBACvE,OAAO,MAAM,OAAO,CAAC,IAAI,CAAC,WAAW,IAAI,oBAAoB,EAAE,oBAAoB,CAAC,CAAC;YACvF,CAAC;YACD,MAAM,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;YAC5F,GAAG,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC;YACpB,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;gBAChB,OAAO,GAAG,IAAI,CAAC;gBACf,QAAQ,IAAI,KAAK,CAAC,KAAK,CAAC;YAC1B,CAAC;QACH,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC;YACjC,OAAO,MAAM,OAAO,CAAC,IAAI,CAAC,WAAW,IAAI,oBAAoB,EAAE,oBAAoB,CAAC,CAAC;QACvF,CAAC;QACD,MAAM,WAAW,GAAG,uBAAuB,CAAC,cAAc,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;QAC9E,IAAI,WAAW,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;YACnC,OAAO,MAAM,QAAQ,CAAC,OAAO,EAAE,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;QAC/D,CAAC;QACD,IAAI,WAAW,CAAC,MAAM,KAAK,oBAAoB,EAAE,CAAC;YAChD,OAAO,MAAM,OAAO,CAAC,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE;gBAC3D,UAAU,EAAE,EAAE,KAAK,EAAE,WAAW,CAAC,KAAK,EAAE;aACzC,CAAC,CAAC;QACL,CAAC;QACD,OAAO,MAAM,OAAO,CAAC,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC/D,CAAC;IAED,4EAA4E;IAC5E,mCAAmC;IACnC,IAAI,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;QACzB,OAAO,MAAM,OAAO,CAAC,IAAI,CAAC,WAAW,IAAI,oBAAoB,EAAE,0BAA0B,CAAC,CAAC;IAC7F,CAAC;IAED,8EAA8E;IAC9E,+EAA+E;IAC/E,4CAA4C;IAC5C,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;QACxC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC9C,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,WAAW,GAAG,uBAAuB,CAAC,KAAK,CAAC,CAAC;YACnD,IAAI,WAAW,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;gBACnC,OAAO,MAAM,QAAQ,CAAC,OAAO,EAAE,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;YAC/D,CAAC;YACD,IAAI,WAAW,CAAC,MAAM,KAAK,oBAAoB,EAAE,CAAC;gBAChD,OAAO,MAAM,OAAO,CAAC,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE;oBAC3D,UAAU,EAAE,EAAE,KAAK,EAAE,WAAW,CAAC,KAAK,EAAE;iBACzC,CAAC,CAAC;YACL,CAAC;YACD,OAAO,MAAM,OAAO,CAAC,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;IAED,IAAI,IAAI,CAAC,oBAAoB,EAAE,CAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,CAAC;QAChD,OAAO,MAAM,QAAQ,CAAC,IAAI,EAAE,uBAAuB,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AACtC,CAAC;AAED;;wEAEwE;AAExE,gEAAgE;AAChE,MAAM,CAAC,MAAM,kBAAkB,GAAG,2BAA2B,CAAC;AAC9D,yDAAyD;AACzD,MAAM,CAAC,MAAM,sBAAsB,GAAG,GAAG,CAAC;AAE1C;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAA8B;IAChE,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACnC,IAAI,CAAC,OAAO;QAAE,OAAO,sBAAsB,CAAC;IAC5C,MAAM,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IACrC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;QAAE,OAAO,sBAAsB,CAAC;IACvD,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IACrB,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IACrB,OAAO,CAAC,CAAC;AACX,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,sBAAsB,CAAC,IAMtC;IACC,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;IACnE,IAAI,IAAI,CAAC,WAAW;QAAE,OAAO,CAAC,CAAC;IAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC;IAC9E,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IACzB,gFAAgF;IAChF,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAC1B,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,KAAK,CAAC,CAAC,EAC5C,WAAW,GAAG,CAAC,CAChB,CAAC;IACF,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC;IAC7D,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC;IACjE,MAAM,aAAa,GAAG,WAAW,GAAG,MAAM,CAAC;IAC3C,MAAM,SAAS,GAAG,WAAW,GAAG,MAAM,GAAG,UAAU,CAAC;IACpD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC,CAAC;AACzD,CAAC;AAED;;wEAEwE;AAExE,qEAAqE;AACrE,MAAM,CAAC,MAAM,qBAAqB,GAAG,sBAAsB,CAAC;AAC5D,0DAA0D;AAC1D,MAAM,CAAC,MAAM,iBAAiB,GAAG,0BAA0B,CAAC;AAC5D,2EAA2E;AAC3E,MAAM,CAAC,MAAM,qBAAqB,GAAG,MAAM,CAAC;AAE5C,+EAA+E;AAC/E,SAAS,YAAY,CAAC,GAA8B;IAClD,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC3C,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,IAAI,CAAC;AAChE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAA8B;IAC/D,MAAM,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IAClD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;QAAE,OAAO,qBAAqB,CAAC;IACtD,OAAO,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;AAC/C,CAAC;AAYD;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,MAAyB,OAAO,CAAC,GAAG;IACxE,MAAM,QAAQ,GAAG,mBAAmB,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC;IAC9D,OAAO;QACL,OAAO,EAAE,YAAY,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC,IAAI,QAAQ,GAAG,CAAC;QACjE,QAAQ;QACR,OAAO,EAAE,kBAAkB,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;KACpD,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CC-1B (TURN-LANE): the production `ChatLaneTransport` adapter.
|
|
3
|
+
*
|
|
4
|
+
* Wires the abstract lane seam (chat-lane.ts) onto real infrastructure per the
|
|
5
|
+
* frozen contract (WORKSPACE_COMMAND_CHAT_CONTRACTS §1/§3):
|
|
6
|
+
*
|
|
7
|
+
* - CLAIM → the `acc.claim_chat_turn` RPC (advisory-lock per conversation,
|
|
8
|
+
* migration 0254). Returns the claimed acc.chat_turns row mapped to
|
|
9
|
+
* a `ClaimedChatTurn`, or null when the queue is empty.
|
|
10
|
+
* - STREAM / COMPLETE / REQUEUE → a `broadcast` on the conversation's
|
|
11
|
+
* `chat:<conversation_id>` Realtime topic (§3), carrying the frozen
|
|
12
|
+
* envelope header + the lifecycle payload. The topic's server-side
|
|
13
|
+
* consumer persists deltas into acc.chat_turn_deltas and advances
|
|
14
|
+
* acc.chat_turns (service-role writer) — the runner never writes
|
|
15
|
+
* those tables directly (RLS: service-role only).
|
|
16
|
+
*
|
|
17
|
+
* A per-conversation channel is subscribed lazily and reused across a turn's
|
|
18
|
+
* many stream frames; `close()` tears them all down on shutdown. The driver only
|
|
19
|
+
* sees the `ChatLaneTransport` interface, so nothing here changes turn logic.
|
|
20
|
+
*/
|
|
21
|
+
import type { RunnerSupabaseClient } from "./supabase.js";
|
|
22
|
+
import { type ChatLaneTransport, type ClaimedChatTurn } from "./chat-lane.js";
|
|
23
|
+
/** Shape of one acc.chat_turns row as returned by acc.claim_chat_turn. */
|
|
24
|
+
interface ChatTurnRow {
|
|
25
|
+
id: string;
|
|
26
|
+
conversation_id: string;
|
|
27
|
+
org_id: string;
|
|
28
|
+
turn_ordinal: number | null;
|
|
29
|
+
prompt: string | null;
|
|
30
|
+
tier: string | null;
|
|
31
|
+
engine_id: string | null;
|
|
32
|
+
runner_id: string | null;
|
|
33
|
+
requeue_count: number | null;
|
|
34
|
+
lease_expires_at: string | null;
|
|
35
|
+
}
|
|
36
|
+
/** Map a raw claimed row onto the driver's `ClaimedChatTurn` (defensive defaults). */
|
|
37
|
+
export declare function mapClaimedTurn(row: ChatTurnRow): ClaimedChatTurn;
|
|
38
|
+
export interface SupabaseChatTransportOptions {
|
|
39
|
+
now?: () => number;
|
|
40
|
+
onLog?: (line: string) => void;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Build the production chat-lane transport bound to a runner's Supabase client.
|
|
44
|
+
* Claim uses the DB RPC; the lifecycle messages broadcast on the per-conversation
|
|
45
|
+
* chat topic.
|
|
46
|
+
*/
|
|
47
|
+
export declare function createSupabaseChatTransport(client: RunnerSupabaseClient, opts?: SupabaseChatTransportOptions): ChatLaneTransport & {
|
|
48
|
+
close: () => Promise<void>;
|
|
49
|
+
};
|
|
50
|
+
export {};
|
|
51
|
+
//# sourceMappingURL=chat-transport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chat-transport.d.ts","sourceRoot":"","sources":["../src/chat-transport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,EAEL,KAAK,iBAAiB,EAItB,KAAK,eAAe,EACrB,MAAM,gBAAgB,CAAC;AAgBxB,0EAA0E;AAC1E,UAAU,WAAW;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED,sFAAsF;AACtF,wBAAgB,cAAc,CAAC,GAAG,EAAE,WAAW,GAAG,eAAe,CAahE;AAED,MAAM,WAAW,4BAA4B;IAC3C,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,oBAAoB,EAC5B,IAAI,GAAE,4BAAiC,GACtC,iBAAiB,GAAG;IAAE,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAgGpD"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { CHAT_LANE_PROTOCOL_VERSION, } from "./chat-lane.js";
|
|
2
|
+
/** Map a raw claimed row onto the driver's `ClaimedChatTurn` (defensive defaults). */
|
|
3
|
+
export function mapClaimedTurn(row) {
|
|
4
|
+
return {
|
|
5
|
+
id: row.id,
|
|
6
|
+
conversation_id: row.conversation_id,
|
|
7
|
+
org_id: row.org_id,
|
|
8
|
+
turn_ordinal: row.turn_ordinal,
|
|
9
|
+
prompt: row.prompt ?? "",
|
|
10
|
+
tier: (row.tier ?? "full"),
|
|
11
|
+
engine_id: row.engine_id ?? "",
|
|
12
|
+
runner_id: row.runner_id ?? "",
|
|
13
|
+
requeue_count: row.requeue_count ?? 0,
|
|
14
|
+
lease_expires_at: row.lease_expires_at,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Build the production chat-lane transport bound to a runner's Supabase client.
|
|
19
|
+
* Claim uses the DB RPC; the lifecycle messages broadcast on the per-conversation
|
|
20
|
+
* chat topic.
|
|
21
|
+
*/
|
|
22
|
+
export function createSupabaseChatTransport(client, opts = {}) {
|
|
23
|
+
const now = opts.now ?? Date.now;
|
|
24
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
25
|
+
const channels = new Map(); // any-allowed: supabase RealtimeChannel type is not re-exported by the schema-scoped client
|
|
26
|
+
async function channelFor(conversationId) {
|
|
27
|
+
const topic = `chat:${conversationId}`;
|
|
28
|
+
const existing = channels.get(conversationId);
|
|
29
|
+
if (existing)
|
|
30
|
+
return existing;
|
|
31
|
+
const ch = client.channel(topic);
|
|
32
|
+
channels.set(conversationId, ch);
|
|
33
|
+
await new Promise((resolve) => {
|
|
34
|
+
ch.subscribe((status) => {
|
|
35
|
+
if (status === "SUBSCRIBED")
|
|
36
|
+
resolve();
|
|
37
|
+
});
|
|
38
|
+
// Never hang the turn on a slow subscribe — proceed after a short grace.
|
|
39
|
+
setTimeout(resolve, 2_000).unref?.();
|
|
40
|
+
});
|
|
41
|
+
return ch;
|
|
42
|
+
}
|
|
43
|
+
function header(kind, conversationId, turnId, runnerId) {
|
|
44
|
+
return {
|
|
45
|
+
protocol_version: CHAT_LANE_PROTOCOL_VERSION,
|
|
46
|
+
kind,
|
|
47
|
+
conversation_id: conversationId,
|
|
48
|
+
turn_id: turnId,
|
|
49
|
+
runner_id: runnerId,
|
|
50
|
+
ts: new Date(now()).toISOString(),
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
async function broadcast(turn, event, kind, payload) {
|
|
54
|
+
try {
|
|
55
|
+
const ch = await channelFor(turn.conversation_id);
|
|
56
|
+
await ch.send({
|
|
57
|
+
type: "broadcast",
|
|
58
|
+
event,
|
|
59
|
+
payload: { ...header(kind, turn.conversation_id, turn.id, turn.runner_id), payload },
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
opts.onLog?.(`[acc-runner] chat broadcast(${event}, ${turn.id}) failed: ${err.message}`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return {
|
|
67
|
+
async claim(args) {
|
|
68
|
+
const { data, error } = await client.rpc("claim_chat_turn", {
|
|
69
|
+
p_conversation_id: args.conversationId,
|
|
70
|
+
p_runner_id: args.runnerId,
|
|
71
|
+
p_engine_id: args.engineId,
|
|
72
|
+
p_tier: args.tier,
|
|
73
|
+
p_lease_ms: args.leaseMs,
|
|
74
|
+
});
|
|
75
|
+
if (error) {
|
|
76
|
+
opts.onLog?.(`[acc-runner] claim_chat_turn(${args.conversationId}) failed: ${error.message}`);
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
// The RPC returns the single claimed row (SETOF one) or null when empty.
|
|
80
|
+
const row = (Array.isArray(data) ? data[0] : data);
|
|
81
|
+
return row && row.id ? mapClaimedTurn(row) : null;
|
|
82
|
+
},
|
|
83
|
+
async stream(turn, payload) {
|
|
84
|
+
await broadcast(turn, "turn_stream", "chat.turn.stream", payload);
|
|
85
|
+
},
|
|
86
|
+
async complete(turn, payload) {
|
|
87
|
+
await broadcast(turn, "turn_complete", "chat.turn.complete", payload);
|
|
88
|
+
},
|
|
89
|
+
async requeue(turn, payload) {
|
|
90
|
+
await broadcast(turn, "turn_requeued", "chat.turn.requeue", payload);
|
|
91
|
+
},
|
|
92
|
+
async close() {
|
|
93
|
+
for (const ch of channels.values()) {
|
|
94
|
+
try {
|
|
95
|
+
await client.removeChannel(ch);
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
/* best-effort teardown */
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
channels.clear();
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=chat-transport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chat-transport.js","sourceRoot":"","sources":["../src/chat-transport.ts"],"names":[],"mappings":"AAqBA,OAAO,EACL,0BAA0B,GAM3B,MAAM,gBAAgB,CAAC;AA8BxB,sFAAsF;AACtF,MAAM,UAAU,cAAc,CAAC,GAAgB;IAC7C,OAAO;QACL,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,eAAe,EAAE,GAAG,CAAC,eAAe;QACpC,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,YAAY,EAAE,GAAG,CAAC,YAAY;QAC9B,MAAM,EAAE,GAAG,CAAC,MAAM,IAAI,EAAE;QACxB,IAAI,EAAE,CAAC,GAAG,CAAC,IAAI,IAAI,MAAM,CAAyB;QAClD,SAAS,EAAE,GAAG,CAAC,SAAS,IAAI,EAAE;QAC9B,SAAS,EAAE,GAAG,CAAC,SAAS,IAAI,EAAE;QAC9B,aAAa,EAAE,GAAG,CAAC,aAAa,IAAI,CAAC;QACrC,gBAAgB,EAAE,GAAG,CAAC,gBAAgB;KACvC,CAAC;AACJ,CAAC;AAOD;;;;GAIG;AACH,MAAM,UAAU,2BAA2B,CACzC,MAA4B,EAC5B,OAAqC,EAAE;IAEvC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IACjC,8DAA8D;IAC9D,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAe,CAAC,CAAC,4FAA4F;IAErI,KAAK,UAAU,UAAU,CAAC,cAAsB;QAC9C,MAAM,KAAK,GAAG,QAAQ,cAAc,EAAE,CAAC;QACvC,MAAM,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QAC9C,IAAI,QAAQ;YAAE,OAAO,QAAQ,CAAC;QAC9B,MAAM,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACjC,QAAQ,CAAC,GAAG,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;QACjC,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;YAClC,EAAE,CAAC,SAAS,CAAC,CAAC,MAAc,EAAE,EAAE;gBAC9B,IAAI,MAAM,KAAK,YAAY;oBAAE,OAAO,EAAE,CAAC;YACzC,CAAC,CAAC,CAAC;YACH,yEAAyE;YACzE,UAAU,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC;QACvC,CAAC,CAAC,CAAC;QACH,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,SAAS,MAAM,CACb,IAAoC,EACpC,cAAsB,EACtB,MAAc,EACd,QAAgB;QAEhB,OAAO;YACL,gBAAgB,EAAE,0BAA0B;YAC5C,IAAI;YACJ,eAAe,EAAE,cAAc;YAC/B,OAAO,EAAE,MAAM;YACf,SAAS,EAAE,QAAQ;YACnB,EAAE,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,WAAW,EAAE;SAClC,CAAC;IACJ,CAAC;IAED,KAAK,UAAU,SAAS,CACtB,IAAqB,EACrB,KAAqB,EACrB,IAAoC,EACpC,OAAgB;QAEhB,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;YAClD,MAAM,EAAE,CAAC,IAAI,CAAC;gBACZ,IAAI,EAAE,WAAW;gBACjB,KAAK;gBACL,OAAO,EAAE,EAAE,GAAG,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,eAAe,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE;aACrF,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,KAAK,EAAE,CAAC,+BAA+B,KAAK,KAAK,IAAI,CAAC,EAAE,aAAc,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QACtG,CAAC;IACH,CAAC;IAED,OAAO;QACL,KAAK,CAAC,KAAK,CAAC,IAAI;YACd,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,iBAAiB,EAAE;gBAC1D,iBAAiB,EAAE,IAAI,CAAC,cAAc;gBACtC,WAAW,EAAE,IAAI,CAAC,QAAQ;gBAC1B,WAAW,EAAE,IAAI,CAAC,QAAQ;gBAC1B,MAAM,EAAE,IAAI,CAAC,IAAI;gBACjB,UAAU,EAAE,IAAI,CAAC,OAAO;aACzB,CAAC,CAAC;YACH,IAAI,KAAK,EAAE,CAAC;gBACV,IAAI,CAAC,KAAK,EAAE,CAAC,gCAAgC,IAAI,CAAC,cAAc,aAAa,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;gBAC9F,OAAO,IAAI,CAAC;YACd,CAAC;YACD,yEAAyE;YACzE,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAmC,CAAC;YACrF,OAAO,GAAG,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACpD,CAAC;QAED,KAAK,CAAC,MAAM,CAAC,IAAqB,EAAE,OAA8B;YAChE,MAAM,SAAS,CAAC,IAAI,EAAE,aAAa,EAAE,kBAAkB,EAAE,OAAO,CAAC,CAAC;QACpE,CAAC;QAED,KAAK,CAAC,QAAQ,CAAC,IAAqB,EAAE,OAAgC;YACpE,MAAM,SAAS,CAAC,IAAI,EAAE,eAAe,EAAE,oBAAoB,EAAE,OAAO,CAAC,CAAC;QACxE,CAAC;QAED,KAAK,CAAC,OAAO,CAAC,IAAqB,EAAE,OAA+B;YAClE,MAAM,SAAS,CAAC,IAAI,EAAE,eAAe,EAAE,mBAAmB,EAAE,OAAO,CAAC,CAAC;QACvE,CAAC;QAED,KAAK,CAAC,KAAK;YACT,KAAK,MAAM,EAAE,IAAI,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;gBACnC,IAAI,CAAC;oBACH,MAAM,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;gBACjC,CAAC;gBAAC,MAAM,CAAC;oBACP,0BAA0B;gBAC5B,CAAC;YACH,CAAC;YACD,QAAQ,CAAC,KAAK,EAAE,CAAC;QACnB,CAAC;KACF,CAAC;AACJ,CAAC"}
|
package/dist/cli.js
CHANGED
|
@@ -12,6 +12,7 @@ import { logoutCommand } from "./logout.js";
|
|
|
12
12
|
import { watchCommand } from "./watch.js";
|
|
13
13
|
import { doctorCommand } from "./doctor.js";
|
|
14
14
|
import { clearQuarantine, getQuarantine } from "./runtime/quarantine.js";
|
|
15
|
+
import { clearChatCircuit, getChatCircuit } from "./runtime/chat-circuit-breaker.js";
|
|
15
16
|
import { runCommitGuardHook } from "./commit-guard.js";
|
|
16
17
|
import { PROTOCOL_VERSION } from "./types.js";
|
|
17
18
|
import { PACKAGE_VERSION } from "./pkg-version.js";
|
|
@@ -116,6 +117,50 @@ quarantineCmd
|
|
|
116
117
|
process.exitCode = 1;
|
|
117
118
|
}
|
|
118
119
|
});
|
|
120
|
+
// CC-1B (TURN-LANE): chat-circuit management. The runner opens the chat circuit
|
|
121
|
+
// automatically when a `claude_exit_1`-class fault surfaces while serving a chat
|
|
122
|
+
// turn — benching ONLY the chat lane (code/review keep running). An operator
|
|
123
|
+
// resolves the credential/host issue then clears the circuit to resume chat.
|
|
124
|
+
const chatCircuitCmd = program
|
|
125
|
+
.command("chat-circuit")
|
|
126
|
+
.description("Inspect or clear the chat-capability circuit breaker (chat lane only).");
|
|
127
|
+
chatCircuitCmd
|
|
128
|
+
.command("status")
|
|
129
|
+
.description("Show chat circuit state.")
|
|
130
|
+
.action(async () => {
|
|
131
|
+
try {
|
|
132
|
+
const c = await getChatCircuit();
|
|
133
|
+
if (!c) {
|
|
134
|
+
console.log("Chat circuit is closed (chat lane serving).");
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
console.log(chalk.red.bold(`CHAT CIRCUIT OPEN (${c.cause})`));
|
|
138
|
+
console.log(` Detail: ${c.detail}`);
|
|
139
|
+
console.log(` Turn: ${c.turnId}`);
|
|
140
|
+
console.log(` Conversation: ${c.conversationId}`);
|
|
141
|
+
console.log(` Since: ${c.trippedAt}`);
|
|
142
|
+
console.log(chalk.gray(`\nResolve the underlying ${c.cause} issue, then run \`acc-runner chat-circuit clear\`. ` +
|
|
143
|
+
`Code/review lanes are unaffected.`));
|
|
144
|
+
process.exitCode = 1;
|
|
145
|
+
}
|
|
146
|
+
catch (err) {
|
|
147
|
+
console.error(chalk.red(`✗ ${err.message}`));
|
|
148
|
+
process.exitCode = 1;
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
chatCircuitCmd
|
|
152
|
+
.command("clear")
|
|
153
|
+
.description("Close the chat circuit and allow the runner to resume claiming chat turns.")
|
|
154
|
+
.action(async () => {
|
|
155
|
+
try {
|
|
156
|
+
await clearChatCircuit();
|
|
157
|
+
console.log(chalk.green("✓ Chat circuit closed. Runner will resume claiming chat turns."));
|
|
158
|
+
}
|
|
159
|
+
catch (err) {
|
|
160
|
+
console.error(chalk.red(`✗ ${err.message}`));
|
|
161
|
+
process.exitCode = 1;
|
|
162
|
+
}
|
|
163
|
+
});
|
|
119
164
|
// RR-4: the git pre-commit hook the runner installs into a
|
|
120
165
|
// task worktree (see commit-guard.ts) re-invokes this hidden subcommand. It
|
|
121
166
|
// scans the STAGED text files and exits non-zero (with an actionable message on
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
CHANGED
|
@@ -141,6 +141,44 @@ export interface RunnerConcurrency {
|
|
|
141
141
|
concurrency: number;
|
|
142
142
|
reservedReviewSlots: number;
|
|
143
143
|
}
|
|
144
|
+
/**
|
|
145
|
+
* RUNCFG-1: where the runner's EFFECTIVE concurrency ceiling came from.
|
|
146
|
+
* - server: an operator set acc.runners.desired_concurrency (highest priority)
|
|
147
|
+
* - env: ACC_RUNNER_CONCURRENCY was set in the process env
|
|
148
|
+
* - default: neither — the compiled DEFAULT_CONCURRENCY_LIMIT
|
|
149
|
+
* Advertised in caps.concurrency_source and printed by `acc-runner doctor` so a
|
|
150
|
+
* "runner advertised 5 while operator set 50" misconfig is visible at a glance.
|
|
151
|
+
*/
|
|
152
|
+
export type ConcurrencySource = "server" | "env" | "default";
|
|
153
|
+
/**
|
|
154
|
+
* RUNCFG-1: is ACC_RUNNER_CONCURRENCY explicitly set? Distinguishes the `env`
|
|
155
|
+
* source (operator exported a value) from `default` (compiled fallback) when no
|
|
156
|
+
* server override is present.
|
|
157
|
+
*/
|
|
158
|
+
export declare function concurrencyEnvExplicit(env?: NodeJS.ProcessEnv): boolean;
|
|
159
|
+
/**
|
|
160
|
+
* RUNCFG-1: resolve the runner's EFFECTIVE concurrency from all three layers,
|
|
161
|
+
* precedence server-set > env > default. This is the single source of truth the
|
|
162
|
+
* watch loop applies to its live ceiling and doctor reports; it never reads the
|
|
163
|
+
* environment itself (callers pass the already-resolved env/default base) so it
|
|
164
|
+
* stays a pure function and is exhaustively unit-testable.
|
|
165
|
+
*/
|
|
166
|
+
export declare function resolveEffectiveConcurrency(input: {
|
|
167
|
+
/** acc.runners.desired_concurrency (null when no operator override). */
|
|
168
|
+
serverConcurrency: number | null | undefined;
|
|
169
|
+
/** acc.runners.desired_reserved_review_slots (null when no override). */
|
|
170
|
+
serverReserve: number | null | undefined;
|
|
171
|
+
/** The env-or-default concurrency (resolveConcurrencyLimit output). */
|
|
172
|
+
envConcurrency: number;
|
|
173
|
+
/** The env-or-default reserved-review-slot count. */
|
|
174
|
+
envReserve: number;
|
|
175
|
+
/** Whether ACC_RUNNER_CONCURRENCY was explicitly set (env vs default). */
|
|
176
|
+
envExplicit: boolean;
|
|
177
|
+
}): {
|
|
178
|
+
concurrency: number;
|
|
179
|
+
reservedReviewSlots: number;
|
|
180
|
+
source: ConcurrencySource;
|
|
181
|
+
};
|
|
144
182
|
/**
|
|
145
183
|
* CONC-1: resolve the runner's effective concurrency ONCE from the environment.
|
|
146
184
|
* Both the register caps payload and the watch loop consume the SAME result so
|