@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,66 @@
|
|
|
1
|
+
import type { ClaudeExitClass } from "../failure-classifier.js";
|
|
2
|
+
/**
|
|
3
|
+
* Failure classes that OPEN the chat circuit. These mirror the batch lane's
|
|
4
|
+
* "machine-level, not task-level" split: a spent/broken CREDENTIAL or a broken
|
|
5
|
+
* HOST is a `claude_exit_1`-class fault the runner cannot serve chat through, so
|
|
6
|
+
* it stops claiming chat turns. Recoverable-capacity classes
|
|
7
|
+
* (`capacity_exhausted`, `subscription_exhausted`, transient `claude_unavailable`)
|
|
8
|
+
* are NOT here — those merely requeue the turn; capacity is a resource, not a
|
|
9
|
+
* fault, and quarantining chat on a resettable window would needlessly bench it.
|
|
10
|
+
*/
|
|
11
|
+
export declare const CHAT_CIRCUIT_TRIP_CLASSES: readonly ClaudeExitClass[];
|
|
12
|
+
/** True when `cls` is a chat-circuit-opening (`claude_exit_1`-class) failure. */
|
|
13
|
+
export declare function isChatCircuitTripClass(cls: ClaudeExitClass): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Persisted chat-circuit sentinel. Shape mirrors QuarantineState but is a
|
|
16
|
+
* DISTINCT file so the two fault domains stay independent; `turnId` /
|
|
17
|
+
* `conversationId` replace the batch `taskId` so `doctor` can show which chat
|
|
18
|
+
* turn tripped the breaker.
|
|
19
|
+
*/
|
|
20
|
+
export interface ChatCircuitState {
|
|
21
|
+
cause: ClaudeExitClass;
|
|
22
|
+
trippedAt: string;
|
|
23
|
+
turnId: string;
|
|
24
|
+
conversationId: string;
|
|
25
|
+
detail: string;
|
|
26
|
+
}
|
|
27
|
+
/** Path to the chat-circuit sentinel (per-runner via the shared cacheDir()). */
|
|
28
|
+
export declare function chatCircuitFile(): string;
|
|
29
|
+
/** Current tripped state, or null when the chat circuit is closed. */
|
|
30
|
+
export declare function getChatCircuit(): Promise<ChatCircuitState | null>;
|
|
31
|
+
/** Write the chat-circuit sentinel (opens the circuit). Creates parent dirs. */
|
|
32
|
+
export declare function setChatCircuit(state: ChatCircuitState): Promise<void>;
|
|
33
|
+
/** Remove the chat-circuit sentinel (closes the circuit). Safe when closed. */
|
|
34
|
+
export declare function clearChatCircuit(): Promise<void>;
|
|
35
|
+
/**
|
|
36
|
+
* In-memory chat circuit breaker. Loaded from the sentinel at boot so a runner
|
|
37
|
+
* that restarts while its chat credential is still broken stays open until an
|
|
38
|
+
* operator clears it. `trip()` is idempotent — a second concurrent chat-turn
|
|
39
|
+
* failure never overwrites the first cause or re-persists — so racing failures
|
|
40
|
+
* on two in-flight turns open the circuit exactly once.
|
|
41
|
+
*/
|
|
42
|
+
export declare class ChatCircuitBreaker {
|
|
43
|
+
private open;
|
|
44
|
+
private state;
|
|
45
|
+
/** Hydrate the in-memory flag from the on-disk sentinel (call once at boot). */
|
|
46
|
+
load(): Promise<void>;
|
|
47
|
+
/** True while the chat circuit is open (runner must not claim chat turns). */
|
|
48
|
+
isOpen(): boolean;
|
|
49
|
+
/** The cause + provenance of the open circuit, or null when closed. */
|
|
50
|
+
current(): ChatCircuitState | null;
|
|
51
|
+
/**
|
|
52
|
+
* Open the circuit for a `claude_exit_1`-class chat failure. Idempotent: a
|
|
53
|
+
* no-op (returns false) when already open, so two concurrent turn failures
|
|
54
|
+
* trip it once. Returns true when this call opened it.
|
|
55
|
+
*/
|
|
56
|
+
trip(args: {
|
|
57
|
+
cause: ClaudeExitClass;
|
|
58
|
+
turnId: string;
|
|
59
|
+
conversationId: string;
|
|
60
|
+
detail: string;
|
|
61
|
+
now?: () => number;
|
|
62
|
+
}): Promise<boolean>;
|
|
63
|
+
/** Close the circuit (operator resolved the underlying issue). */
|
|
64
|
+
reset(): Promise<void>;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=chat-circuit-breaker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chat-circuit-breaker.d.ts","sourceRoot":"","sources":["../../src/runtime/chat-circuit-breaker.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAEhE;;;;;;;;GAQG;AACH,eAAO,MAAM,yBAAyB,EAAE,SAAS,eAAe,EAI/D,CAAC;AAEF,iFAAiF;AACjF,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAEpE;AAED;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,eAAe,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,gFAAgF;AAChF,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,sEAAsE;AACtE,wBAAsB,cAAc,IAAI,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAQvE;AAED,gFAAgF;AAChF,wBAAsB,cAAc,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAI3E;AAED,+EAA+E;AAC/E,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAMtD;AAED;;;;;;GAMG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,KAAK,CAAiC;IAE9C,gFAAgF;IAC1E,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAK3B,8EAA8E;IAC9E,MAAM,IAAI,OAAO;IAIjB,uEAAuE;IACvE,OAAO,IAAI,gBAAgB,GAAG,IAAI;IAIlC;;;;OAIG;IACG,IAAI,CAAC,IAAI,EAAE;QACf,KAAK,EAAE,eAAe,CAAC;QACvB,MAAM,EAAE,MAAM,CAAC;QACf,cAAc,EAAE,MAAM,CAAC;QACvB,MAAM,EAAE,MAAM,CAAC;QACf,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;KACpB,GAAG,OAAO,CAAC,OAAO,CAAC;IAgBpB,kEAAkE;IAC5D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAK7B"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CC-1B (TURN-LANE): the runner's CHAT-CAPABILITY circuit breaker.
|
|
3
|
+
*
|
|
4
|
+
* The batch lane's whole-runner quarantine (runtime/quarantine.ts) benches the
|
|
5
|
+
* ENTIRE runner — no task, no review, no chat — when the host/binary is broken.
|
|
6
|
+
* The chat lane needs a NARROWER fault domain: a `claude_exit_1`-class failure
|
|
7
|
+
* that surfaces while serving a chat turn must stop the runner claiming further
|
|
8
|
+
* CHAT turns (and requeue the in-flight one so another companion can finish it),
|
|
9
|
+
* WITHOUT benching the code/review lanes — a flaky chat credential should never
|
|
10
|
+
* starve the fleet's build throughput. This module is that scoped breaker.
|
|
11
|
+
*
|
|
12
|
+
* It deliberately REUSES the quarantine.ts recipe (a JSON sentinel under the
|
|
13
|
+
* shared cacheDir, an in-memory flag loaded from it at boot, a `ClaudeExitClass`
|
|
14
|
+
* cause) rather than inventing a new persistence shape — the two are siblings,
|
|
15
|
+
* one per fault domain. The sentinel filename differs (`chat-quarantine.json`)
|
|
16
|
+
* so the chat breaker and the whole-runner quarantine never clobber each other.
|
|
17
|
+
*
|
|
18
|
+
* Tripping the breaker is a CIRCUIT-OPEN, not a task failure: the turn that
|
|
19
|
+
* tripped it is REQUEUED (not burned) so it survives on another companion, and
|
|
20
|
+
* an operator clears the breaker (`acc-runner chat-circuit clear`, or deleting
|
|
21
|
+
* the file) once the underlying credential/host issue is fixed. `acc-runner
|
|
22
|
+
* doctor` surfaces the tripped state and its cause alongside the quarantine.
|
|
23
|
+
*/
|
|
24
|
+
import fs from "node:fs/promises";
|
|
25
|
+
import path from "node:path";
|
|
26
|
+
import { cacheDir } from "./cache-dir.js";
|
|
27
|
+
/**
|
|
28
|
+
* Failure classes that OPEN the chat circuit. These mirror the batch lane's
|
|
29
|
+
* "machine-level, not task-level" split: a spent/broken CREDENTIAL or a broken
|
|
30
|
+
* HOST is a `claude_exit_1`-class fault the runner cannot serve chat through, so
|
|
31
|
+
* it stops claiming chat turns. Recoverable-capacity classes
|
|
32
|
+
* (`capacity_exhausted`, `subscription_exhausted`, transient `claude_unavailable`)
|
|
33
|
+
* are NOT here — those merely requeue the turn; capacity is a resource, not a
|
|
34
|
+
* fault, and quarantining chat on a resettable window would needlessly bench it.
|
|
35
|
+
*/
|
|
36
|
+
export const CHAT_CIRCUIT_TRIP_CLASSES = [
|
|
37
|
+
"auth_expired",
|
|
38
|
+
"env_broken",
|
|
39
|
+
"usage_limit",
|
|
40
|
+
];
|
|
41
|
+
/** True when `cls` is a chat-circuit-opening (`claude_exit_1`-class) failure. */
|
|
42
|
+
export function isChatCircuitTripClass(cls) {
|
|
43
|
+
return CHAT_CIRCUIT_TRIP_CLASSES.includes(cls);
|
|
44
|
+
}
|
|
45
|
+
/** Path to the chat-circuit sentinel (per-runner via the shared cacheDir()). */
|
|
46
|
+
export function chatCircuitFile() {
|
|
47
|
+
return path.join(cacheDir(), "chat-quarantine.json");
|
|
48
|
+
}
|
|
49
|
+
/** Current tripped state, or null when the chat circuit is closed. */
|
|
50
|
+
export async function getChatCircuit() {
|
|
51
|
+
try {
|
|
52
|
+
const raw = await fs.readFile(chatCircuitFile(), "utf8");
|
|
53
|
+
return JSON.parse(raw);
|
|
54
|
+
}
|
|
55
|
+
catch (err) {
|
|
56
|
+
if (err.code === "ENOENT")
|
|
57
|
+
return null;
|
|
58
|
+
throw err;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/** Write the chat-circuit sentinel (opens the circuit). Creates parent dirs. */
|
|
62
|
+
export async function setChatCircuit(state) {
|
|
63
|
+
const file = chatCircuitFile();
|
|
64
|
+
await fs.mkdir(path.dirname(file), { recursive: true });
|
|
65
|
+
await fs.writeFile(file, JSON.stringify(state, null, 2), "utf8");
|
|
66
|
+
}
|
|
67
|
+
/** Remove the chat-circuit sentinel (closes the circuit). Safe when closed. */
|
|
68
|
+
export async function clearChatCircuit() {
|
|
69
|
+
try {
|
|
70
|
+
await fs.unlink(chatCircuitFile());
|
|
71
|
+
}
|
|
72
|
+
catch (err) {
|
|
73
|
+
if (err.code !== "ENOENT")
|
|
74
|
+
throw err;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* In-memory chat circuit breaker. Loaded from the sentinel at boot so a runner
|
|
79
|
+
* that restarts while its chat credential is still broken stays open until an
|
|
80
|
+
* operator clears it. `trip()` is idempotent — a second concurrent chat-turn
|
|
81
|
+
* failure never overwrites the first cause or re-persists — so racing failures
|
|
82
|
+
* on two in-flight turns open the circuit exactly once.
|
|
83
|
+
*/
|
|
84
|
+
export class ChatCircuitBreaker {
|
|
85
|
+
open = false;
|
|
86
|
+
state = null;
|
|
87
|
+
/** Hydrate the in-memory flag from the on-disk sentinel (call once at boot). */
|
|
88
|
+
async load() {
|
|
89
|
+
this.state = await getChatCircuit();
|
|
90
|
+
this.open = this.state !== null;
|
|
91
|
+
}
|
|
92
|
+
/** True while the chat circuit is open (runner must not claim chat turns). */
|
|
93
|
+
isOpen() {
|
|
94
|
+
return this.open;
|
|
95
|
+
}
|
|
96
|
+
/** The cause + provenance of the open circuit, or null when closed. */
|
|
97
|
+
current() {
|
|
98
|
+
return this.state;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Open the circuit for a `claude_exit_1`-class chat failure. Idempotent: a
|
|
102
|
+
* no-op (returns false) when already open, so two concurrent turn failures
|
|
103
|
+
* trip it once. Returns true when this call opened it.
|
|
104
|
+
*/
|
|
105
|
+
async trip(args) {
|
|
106
|
+
if (this.open)
|
|
107
|
+
return false;
|
|
108
|
+
const now = args.now ?? Date.now;
|
|
109
|
+
const state = {
|
|
110
|
+
cause: args.cause,
|
|
111
|
+
trippedAt: new Date(now()).toISOString(),
|
|
112
|
+
turnId: args.turnId,
|
|
113
|
+
conversationId: args.conversationId,
|
|
114
|
+
detail: args.detail,
|
|
115
|
+
};
|
|
116
|
+
this.open = true;
|
|
117
|
+
this.state = state;
|
|
118
|
+
await setChatCircuit(state);
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
/** Close the circuit (operator resolved the underlying issue). */
|
|
122
|
+
async reset() {
|
|
123
|
+
this.open = false;
|
|
124
|
+
this.state = null;
|
|
125
|
+
await clearChatCircuit();
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=chat-circuit-breaker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chat-circuit-breaker.js","sourceRoot":"","sources":["../../src/runtime/chat-circuit-breaker.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
export { PROTOCOL_VERSION } from "./pkg-version.js";
|
|
9
9
|
export declare const RUNNER_KEYCHAIN_SERVICE: "acc-runner";
|
|
10
10
|
export type { MessagingState, RunnerProtocol } from "./messaging.js";
|
|
11
|
+
import type { ConcurrencySource } from "./config.js";
|
|
11
12
|
export interface DeviceCodeResponse {
|
|
12
13
|
device_code: string;
|
|
13
14
|
user_code: string;
|
|
@@ -148,6 +149,13 @@ export interface RunnerCaps {
|
|
|
148
149
|
* can compute executor slots = concurrency − reserve without guessing.
|
|
149
150
|
*/
|
|
150
151
|
reserved_review_slots?: number;
|
|
152
|
+
/**
|
|
153
|
+
* RUNCFG-1: where the advertised `concurrency` came from — "server" (operator
|
|
154
|
+
* set acc.runners.desired_concurrency), "env" (ACC_RUNNER_CONCURRENCY), or
|
|
155
|
+
* "default" (compiled). Published so a misconfig ("advertised 5, operator set
|
|
156
|
+
* 50") is visible in the caps and the Runners UI. Additive/optional.
|
|
157
|
+
*/
|
|
158
|
+
concurrency_source?: ConcurrencySource;
|
|
151
159
|
}
|
|
152
160
|
export interface StoredSession {
|
|
153
161
|
access_token: string;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAQH,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,eAAO,MAAM,uBAAuB,EAAG,YAAqB,CAAC;AAK7D,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/watch.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { RealtimeChannel } from "@supabase/supabase-js";
|
|
2
|
-
import { type RunnerConfig } from "./config.js";
|
|
2
|
+
import { type ConcurrencySource, type RunnerConfig } from "./config.js";
|
|
3
3
|
export { resolveConcurrencyLimit, resolveReservedReviewSlots } from "./config.js";
|
|
4
4
|
import { type TokenProvider } from "./token-provider.js";
|
|
5
5
|
import { type RunnerSupabaseClient } from "./supabase.js";
|
|
@@ -288,6 +288,32 @@ interface WatchState {
|
|
|
288
288
|
* 1). Clamped away on a single-slot runner — see computeTaskClaimLimit.
|
|
289
289
|
*/
|
|
290
290
|
reservedReviewSlots: number;
|
|
291
|
+
/**
|
|
292
|
+
* RUNCFG-1: the env-or-default concurrency base (before any server override).
|
|
293
|
+
* `concurrencyLimit` above is the LIVE effective ceiling and may be raised or
|
|
294
|
+
* lowered by an operator's acc.runners.desired_concurrency on any heartbeat;
|
|
295
|
+
* this base is what the runner falls back to when the server override is
|
|
296
|
+
* cleared (set back to NULL). Captured once at startup.
|
|
297
|
+
*/
|
|
298
|
+
baseConcurrency: number;
|
|
299
|
+
baseReservedReviewSlots: number;
|
|
300
|
+
/** RUNCFG-1: whether ACC_RUNNER_CONCURRENCY was explicitly set (env vs default). */
|
|
301
|
+
concurrencyEnvExplicit: boolean;
|
|
302
|
+
/**
|
|
303
|
+
* RUNCFG-1: where the LIVE `concurrencyLimit` currently comes from
|
|
304
|
+
* (server|env|default). Published into caps.concurrency_source via
|
|
305
|
+
* runner_pull_concurrency and logged on every change so a "runner advertised
|
|
306
|
+
* 5 while operator set 50" misconfig is visible.
|
|
307
|
+
*/
|
|
308
|
+
concurrencySource: ConcurrencySource;
|
|
309
|
+
/**
|
|
310
|
+
* RUNCFG-1: single-flight + change tracking for the caps republish. The
|
|
311
|
+
* runner only writes caps.concurrency* when its effective value actually
|
|
312
|
+
* changes (or on the first heartbeat) — steady-state pulls pass NULL so the
|
|
313
|
+
* heartbeat path is a read, not a per-tick caps UPDATE. `false` until the
|
|
314
|
+
* first successful publish.
|
|
315
|
+
*/
|
|
316
|
+
concurrencyCapsPublished: boolean;
|
|
291
317
|
/**
|
|
292
318
|
* RVU-2 (FU-RVU2R): claim-pause-before-review-pause. Set true when a review
|
|
293
319
|
* signals capacity pressure (ReviewerOutcome.capacity_degraded) so pump()
|
package/dist/watch.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../src/watch.ts"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,
|
|
1
|
+
{"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../src/watch.ts"],"names":[],"mappings":"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"}
|
package/dist/watch.js
CHANGED
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
* arms a clean self-termination after n minutes without work.
|
|
27
27
|
*/
|
|
28
28
|
import chalk from "chalk";
|
|
29
|
-
import { applyBootstrapConfig, loadConfig, supabaseConfigSource, resolveRunnerConcurrency, } from "./config.js";
|
|
29
|
+
import { applyBootstrapConfig, concurrencyEnvExplicit, loadConfig, resolveEffectiveConcurrency, supabaseConfigSource, resolveRunnerConcurrency, } from "./config.js";
|
|
30
30
|
// CONC-1: these resolvers moved to config.ts so login.ts
|
|
31
31
|
// can share them without a login→watch import cycle. Re-exported here so
|
|
32
32
|
// existing tests that import them from `../src/watch.js` keep resolving.
|
|
@@ -1186,6 +1186,14 @@ export async function watchCommand(options = {}) {
|
|
|
1186
1186
|
// them once guarantees no drift between what the runner runs and advertises.
|
|
1187
1187
|
concurrencyLimit,
|
|
1188
1188
|
reservedReviewSlots,
|
|
1189
|
+
// RUNCFG-1: the env/default base the live ceiling falls back to when the
|
|
1190
|
+
// server override is cleared, plus the initial source label. An operator's
|
|
1191
|
+
// desired_concurrency overrides `concurrencyLimit` live (applyServerConcurrency).
|
|
1192
|
+
baseConcurrency: concurrencyLimit,
|
|
1193
|
+
baseReservedReviewSlots: reservedReviewSlots,
|
|
1194
|
+
concurrencyEnvExplicit: concurrencyEnvExplicit(),
|
|
1195
|
+
concurrencySource: concurrencyEnvExplicit() ? "env" : "default",
|
|
1196
|
+
concurrencyCapsPublished: false,
|
|
1189
1197
|
// RVU-2 (FU-RVU2R): claim-pause starts off; set under review capacity pressure.
|
|
1190
1198
|
capacityClaimPaused: false,
|
|
1191
1199
|
queue: [],
|
|
@@ -1353,6 +1361,11 @@ export async function watchCommand(options = {}) {
|
|
|
1353
1361
|
p_id: state.session.runner_id,
|
|
1354
1362
|
p_version: PACKAGE_VERSION,
|
|
1355
1363
|
});
|
|
1364
|
+
// RUNCFG-1: pull + apply any server-set concurrency at startup (and publish
|
|
1365
|
+
// the effective ceiling + source into caps) so a runner that boots with an
|
|
1366
|
+
// operator override already in place honours it from the first tick, not only
|
|
1367
|
+
// after the first scheduled heartbeat.
|
|
1368
|
+
await syncConcurrency(state, taskRunnerFactory);
|
|
1356
1369
|
console.log(chalk.gray(`Runner ${state.session.runner_id} is online. Ctrl-C to stop.`));
|
|
1357
1370
|
const stop = async () => {
|
|
1358
1371
|
if (state.stopped)
|
|
@@ -1469,6 +1482,88 @@ export async function watchCommand(options = {}) {
|
|
|
1469
1482
|
runningCount: () => state.running.size,
|
|
1470
1483
|
};
|
|
1471
1484
|
}
|
|
1485
|
+
/**
|
|
1486
|
+
* RUNCFG-1: apply the operator's server-set concurrency to the LIVE watch-loop
|
|
1487
|
+
* ceiling, precedence server-set > env > default. Idempotent: a no-change row
|
|
1488
|
+
* is a no-op. On a real change it updates the ceiling in place (no restart), so
|
|
1489
|
+
* pump() picks up the new limit on its next pass — a GROW immediately fills the
|
|
1490
|
+
* freed slots; a SHRINK applies as in-flight tasks free their slots (running
|
|
1491
|
+
* tasks are never interrupted). Marks caps for republish so the server-side
|
|
1492
|
+
* runnerReviewSlots() and the UI see the new effective value + source.
|
|
1493
|
+
*/
|
|
1494
|
+
function applyServerConcurrency(state, row, factory) {
|
|
1495
|
+
const eff = resolveEffectiveConcurrency({
|
|
1496
|
+
serverConcurrency: row?.desired_concurrency ?? null,
|
|
1497
|
+
serverReserve: row?.desired_reserved_review_slots ?? null,
|
|
1498
|
+
envConcurrency: state.baseConcurrency,
|
|
1499
|
+
envReserve: state.baseReservedReviewSlots,
|
|
1500
|
+
envExplicit: state.concurrencyEnvExplicit,
|
|
1501
|
+
});
|
|
1502
|
+
if (eff.concurrency === state.concurrencyLimit &&
|
|
1503
|
+
eff.reservedReviewSlots === state.reservedReviewSlots &&
|
|
1504
|
+
eff.source === state.concurrencySource) {
|
|
1505
|
+
return false;
|
|
1506
|
+
}
|
|
1507
|
+
const prevLimit = state.concurrencyLimit;
|
|
1508
|
+
const prevSource = state.concurrencySource;
|
|
1509
|
+
console.log(chalk.cyan(`[acc-runner] concurrency ${prevLimit}→${eff.concurrency} ` +
|
|
1510
|
+
`(reserve ${state.reservedReviewSlots}→${eff.reservedReviewSlots}, ` +
|
|
1511
|
+
`source ${prevSource}→${eff.source}) — applied live, no restart`));
|
|
1512
|
+
state.concurrencyLimit = eff.concurrency;
|
|
1513
|
+
state.reservedReviewSlots = eff.reservedReviewSlots;
|
|
1514
|
+
state.concurrencySource = eff.source;
|
|
1515
|
+
// Republish the new effective value + source into caps on the next heartbeat.
|
|
1516
|
+
state.concurrencyCapsPublished = false;
|
|
1517
|
+
void (async () => {
|
|
1518
|
+
try {
|
|
1519
|
+
await state.supabase.rpc("log_activity", {
|
|
1520
|
+
p_verb: "runner.concurrency_applied",
|
|
1521
|
+
p_target_id: state.session.runner_id,
|
|
1522
|
+
p_payload: {
|
|
1523
|
+
concurrency: eff.concurrency,
|
|
1524
|
+
reserved_review_slots: eff.reservedReviewSlots,
|
|
1525
|
+
source: eff.source,
|
|
1526
|
+
version: PACKAGE_VERSION,
|
|
1527
|
+
},
|
|
1528
|
+
p_target_type: "runner",
|
|
1529
|
+
});
|
|
1530
|
+
}
|
|
1531
|
+
catch { /* best-effort breadcrumb */ }
|
|
1532
|
+
})();
|
|
1533
|
+
// GROW: new slots are available now — pump to fill them. SHRINK needs no
|
|
1534
|
+
// action; pump already stops launching once running.size >= the new limit.
|
|
1535
|
+
if (eff.concurrency > prevLimit)
|
|
1536
|
+
void pump(state, factory);
|
|
1537
|
+
return true;
|
|
1538
|
+
}
|
|
1539
|
+
/**
|
|
1540
|
+
* RUNCFG-1: one concurrency sync round-trip, folded into the heartbeat cadence.
|
|
1541
|
+
* Reads acc.runners.desired_* (so applyServerConcurrency can retune the live
|
|
1542
|
+
* ceiling within one heartbeat) and — only when the effective value is stale in
|
|
1543
|
+
* caps (first sync or after a change) — publishes the runner's effective
|
|
1544
|
+
* ceiling + source so the server never writes a per-tick caps UPDATE in steady
|
|
1545
|
+
* state. Best-effort: an error just skips this round (the next heartbeat retries)
|
|
1546
|
+
* and never disturbs the heartbeat-failure ladder.
|
|
1547
|
+
*/
|
|
1548
|
+
async function syncConcurrency(state, factory) {
|
|
1549
|
+
const publish = !state.concurrencyCapsPublished;
|
|
1550
|
+
const { data, error } = await state.supabase.rpc("runner_pull_concurrency", {
|
|
1551
|
+
p_id: state.session.runner_id,
|
|
1552
|
+
p_effective: publish ? state.concurrencyLimit : null,
|
|
1553
|
+
p_reserve: publish ? state.reservedReviewSlots : null,
|
|
1554
|
+
p_source: publish ? state.concurrencySource : null,
|
|
1555
|
+
});
|
|
1556
|
+
if (error) {
|
|
1557
|
+
// A pre-0260 server 404s this RPC — non-fatal, exactly like
|
|
1558
|
+
// set_runner_capabilities / set_runner_repos on an older deploy. The runner
|
|
1559
|
+
// keeps its env/default ceiling.
|
|
1560
|
+
return;
|
|
1561
|
+
}
|
|
1562
|
+
if (publish)
|
|
1563
|
+
state.concurrencyCapsPublished = true;
|
|
1564
|
+
const row = (Array.isArray(data) ? data[0] : data);
|
|
1565
|
+
applyServerConcurrency(state, row, factory);
|
|
1566
|
+
}
|
|
1472
1567
|
function scheduleHeartbeat(state, taskRunnerFactory, baseMs) {
|
|
1473
1568
|
if (state.stopped)
|
|
1474
1569
|
return;
|
|
@@ -1481,6 +1576,11 @@ function scheduleHeartbeat(state, taskRunnerFactory, baseMs) {
|
|
|
1481
1576
|
});
|
|
1482
1577
|
if (!error) {
|
|
1483
1578
|
state.heartbeatFailures = 0;
|
|
1579
|
+
// RUNCFG-1: pull the operator's server-set concurrency and apply it to
|
|
1580
|
+
// the live ceiling within this heartbeat. Runs only on a healthy
|
|
1581
|
+
// heartbeat (a network/auth failure would fail this RPC too). Awaited so
|
|
1582
|
+
// a test's forced heartbeat sees the ceiling settled before it asserts.
|
|
1583
|
+
await syncConcurrency(state, taskRunnerFactory);
|
|
1484
1584
|
}
|
|
1485
1585
|
else {
|
|
1486
1586
|
state.heartbeatFailures += 1;
|