@tokenfactory/acc-runner 0.40.12 → 0.40.14
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/capacity/account-window.d.ts +64 -0
- package/dist/capacity/account-window.d.ts.map +1 -0
- package/dist/capacity/account-window.js +66 -0
- package/dist/capacity/account-window.js.map +1 -0
- package/dist/capacity/fleet-pause-verbs.d.ts +38 -0
- package/dist/capacity/fleet-pause-verbs.d.ts.map +1 -0
- package/dist/capacity/fleet-pause-verbs.js +26 -0
- package/dist/capacity/fleet-pause-verbs.js.map +1 -0
- package/dist/capacity/index.d.ts +15 -0
- package/dist/capacity/index.d.ts.map +1 -0
- package/dist/capacity/index.js +15 -0
- package/dist/capacity/index.js.map +1 -0
- package/dist/capacity/resume-controller.d.ts +150 -0
- package/dist/capacity/resume-controller.d.ts.map +1 -0
- package/dist/capacity/resume-controller.js +229 -0
- package/dist/capacity/resume-controller.js.map +1 -0
- package/dist/capacity/resume-policy.d.ts +101 -0
- package/dist/capacity/resume-policy.d.ts.map +1 -0
- package/dist/capacity/resume-policy.js +80 -0
- package/dist/capacity/resume-policy.js.map +1 -0
- package/dist/companion-run.d.ts.map +1 -1
- package/dist/companion-run.js +38 -0
- package/dist/companion-run.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AS-3 (RESUME): runner-side per-account capacity WINDOW MEMORY.
|
|
3
|
+
*
|
|
4
|
+
* A durable, account-keyed memory of "is this login's subscription window
|
|
5
|
+
* capped, and until when?" keyed on the engine's `synthetic_account`. It is the
|
|
6
|
+
* piece that lets the resume policy RE-PAUSE a returning capped account FROM
|
|
7
|
+
* MEMORY without burning a request (operator scenario: swap back to a
|
|
8
|
+
* still-capped `ajay` → re-pause immediately rather than claim a task just to
|
|
9
|
+
* watch it 429 again).
|
|
10
|
+
*
|
|
11
|
+
* Two states only — `open | capped` — mirroring the server account-window fold
|
|
12
|
+
* (api/_lib/account-capacity/account-window.ts). The shape is DUPLICATED on
|
|
13
|
+
* purpose: the runner is a standalone published package and MUST NOT import from
|
|
14
|
+
* api/_lib (the cost-pricing.ts / capacity-plugin.ts precedent). Kept in sync by
|
|
15
|
+
* hand. // keep in sync
|
|
16
|
+
*
|
|
17
|
+
* The fold applies the CC-3A hysteresis rule verbatim: a capped window reopens
|
|
18
|
+
* ONLY on a tick whose clock has passed a KNOWN reset instant — never on a
|
|
19
|
+
* null-reset guess (an indefinite cap stays capped until a probe/account-change
|
|
20
|
+
* says otherwise), so a window can't flap open on a missing reset time.
|
|
21
|
+
*/
|
|
22
|
+
/** Whether an account's subscription window is serving or capped. */
|
|
23
|
+
export type AccountWindowState = "open" | "capped";
|
|
24
|
+
/** One account's remembered capacity window. */
|
|
25
|
+
export interface AccountWindow {
|
|
26
|
+
state: AccountWindowState;
|
|
27
|
+
/**
|
|
28
|
+
* Absolute reset instant (epoch ms) for a capped window with a KNOWN reset;
|
|
29
|
+
* `null` means capped indefinitely (no parseable reset) — treated as the
|
|
30
|
+
* longest possible wait, so extend-only never shortens it and a tick never
|
|
31
|
+
* reopens it on a guess.
|
|
32
|
+
*/
|
|
33
|
+
resetAtMs: number | null;
|
|
34
|
+
/** Epoch ms this window was last folded (audit / staleness). */
|
|
35
|
+
updatedAtMs: number;
|
|
36
|
+
}
|
|
37
|
+
/** An event folded into a window. */
|
|
38
|
+
export type AccountWindowEvent =
|
|
39
|
+
/** The account hit a subscription/usage cap; `resetAtMs` is its stated reset (null = indefinite). */
|
|
40
|
+
{
|
|
41
|
+
kind: "cap_hit";
|
|
42
|
+
resetAtMs: number | null;
|
|
43
|
+
atMs: number;
|
|
44
|
+
}
|
|
45
|
+
/** A clock tick — reopens a capped window iff its known reset has elapsed. */
|
|
46
|
+
| {
|
|
47
|
+
kind: "tick";
|
|
48
|
+
atMs: number;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Fold an event into a window. Pure. Returns a fresh window (never mutates).
|
|
52
|
+
* - cap_hit: caps the window; extend-only on the reset instant.
|
|
53
|
+
* - tick: reopens a capped window ONLY when a known reset has elapsed.
|
|
54
|
+
*/
|
|
55
|
+
export declare function foldAccountWindow(prev: AccountWindow | null, event: AccountWindowEvent): AccountWindow;
|
|
56
|
+
/**
|
|
57
|
+
* True when a window is capped AND that cap has NOT yet elapsed — the condition
|
|
58
|
+
* for re-pausing a returning account from memory. An indefinite cap (null reset)
|
|
59
|
+
* is always still-capped; a finite cap is still-capped until `nowMs` reaches it.
|
|
60
|
+
* A missing window (never seen) is NOT still-capped (honest unknown → let the
|
|
61
|
+
* probe decide).
|
|
62
|
+
*/
|
|
63
|
+
export declare function isStillCapped(window: AccountWindow | null, nowMs: number): boolean;
|
|
64
|
+
//# sourceMappingURL=account-window.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account-window.d.ts","sourceRoot":"","sources":["../../src/capacity/account-window.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,qEAAqE;AACrE,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEnD,gDAAgD;AAChD,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,kBAAkB,CAAC;IAC1B;;;;;OAKG;IACH,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,gEAAgE;IAChE,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,qCAAqC;AACrC,MAAM,MAAM,kBAAkB;AAC5B,qGAAqG;AACnG;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE;AAC7D,8EAA8E;GAC5E;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAYnC;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,aAAa,GAAG,IAAI,EAC1B,KAAK,EAAE,kBAAkB,GACxB,aAAa,CAiBf;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAGlF"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AS-3 (RESUME): runner-side per-account capacity WINDOW MEMORY.
|
|
3
|
+
*
|
|
4
|
+
* A durable, account-keyed memory of "is this login's subscription window
|
|
5
|
+
* capped, and until when?" keyed on the engine's `synthetic_account`. It is the
|
|
6
|
+
* piece that lets the resume policy RE-PAUSE a returning capped account FROM
|
|
7
|
+
* MEMORY without burning a request (operator scenario: swap back to a
|
|
8
|
+
* still-capped `ajay` → re-pause immediately rather than claim a task just to
|
|
9
|
+
* watch it 429 again).
|
|
10
|
+
*
|
|
11
|
+
* Two states only — `open | capped` — mirroring the server account-window fold
|
|
12
|
+
* (api/_lib/account-capacity/account-window.ts). The shape is DUPLICATED on
|
|
13
|
+
* purpose: the runner is a standalone published package and MUST NOT import from
|
|
14
|
+
* api/_lib (the cost-pricing.ts / capacity-plugin.ts precedent). Kept in sync by
|
|
15
|
+
* hand. // keep in sync
|
|
16
|
+
*
|
|
17
|
+
* The fold applies the CC-3A hysteresis rule verbatim: a capped window reopens
|
|
18
|
+
* ONLY on a tick whose clock has passed a KNOWN reset instant — never on a
|
|
19
|
+
* null-reset guess (an indefinite cap stays capped until a probe/account-change
|
|
20
|
+
* says otherwise), so a window can't flap open on a missing reset time.
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* Extend-only reset merge: a straggler cap can only push a window's reset LATER,
|
|
24
|
+
* never earlier (mirrors watch.ts enterCapacityPause's extend-only rule). `null`
|
|
25
|
+
* (indefinite) is the longest wait, so it dominates any finite reset.
|
|
26
|
+
*/
|
|
27
|
+
function mergeResetLater(prev, next) {
|
|
28
|
+
if (prev === null || next === null)
|
|
29
|
+
return null;
|
|
30
|
+
return Math.max(prev, next);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Fold an event into a window. Pure. Returns a fresh window (never mutates).
|
|
34
|
+
* - cap_hit: caps the window; extend-only on the reset instant.
|
|
35
|
+
* - tick: reopens a capped window ONLY when a known reset has elapsed.
|
|
36
|
+
*/
|
|
37
|
+
export function foldAccountWindow(prev, event) {
|
|
38
|
+
if (event.kind === "cap_hit") {
|
|
39
|
+
const resetAtMs = prev && prev.state === "capped"
|
|
40
|
+
? mergeResetLater(prev.resetAtMs, event.resetAtMs)
|
|
41
|
+
: event.resetAtMs;
|
|
42
|
+
return { state: "capped", resetAtMs, updatedAtMs: event.atMs };
|
|
43
|
+
}
|
|
44
|
+
// tick
|
|
45
|
+
if (!prev || prev.state !== "capped") {
|
|
46
|
+
return prev ?? { state: "open", resetAtMs: null, updatedAtMs: event.atMs };
|
|
47
|
+
}
|
|
48
|
+
// Reopen only on a KNOWN, elapsed reset — never on a null-reset guess.
|
|
49
|
+
if (prev.resetAtMs !== null && event.atMs >= prev.resetAtMs) {
|
|
50
|
+
return { state: "open", resetAtMs: null, updatedAtMs: event.atMs };
|
|
51
|
+
}
|
|
52
|
+
return { ...prev, updatedAtMs: event.atMs };
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* True when a window is capped AND that cap has NOT yet elapsed — the condition
|
|
56
|
+
* for re-pausing a returning account from memory. An indefinite cap (null reset)
|
|
57
|
+
* is always still-capped; a finite cap is still-capped until `nowMs` reaches it.
|
|
58
|
+
* A missing window (never seen) is NOT still-capped (honest unknown → let the
|
|
59
|
+
* probe decide).
|
|
60
|
+
*/
|
|
61
|
+
export function isStillCapped(window, nowMs) {
|
|
62
|
+
if (!window || window.state !== "capped")
|
|
63
|
+
return false;
|
|
64
|
+
return window.resetAtMs === null || nowMs < window.resetAtMs;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=account-window.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account-window.js","sourceRoot":"","sources":["../../src/capacity/account-window.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AA0BH;;;;GAIG;AACH,SAAS,eAAe,CAAC,IAAmB,EAAE,IAAmB;IAC/D,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAChD,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AAC9B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAC/B,IAA0B,EAC1B,KAAyB;IAEzB,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC7B,MAAM,SAAS,GACb,IAAI,IAAI,IAAI,CAAC,KAAK,KAAK,QAAQ;YAC7B,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC;YAClD,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC;QACtB,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;IACjE,CAAC;IACD,OAAO;IACP,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;QACrC,OAAO,IAAI,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7E,CAAC;IACD,uEAAuE;IACvE,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,IAAI,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;QAC5D,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;IACrE,CAAC;IACD,OAAO,EAAE,GAAG,IAAI,EAAE,WAAW,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;AAC9C,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,MAA4B,EAAE,KAAa;IACvE,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IACvD,OAAO,MAAM,CAAC,SAAS,KAAK,IAAI,IAAI,KAAK,GAAG,MAAM,CAAC,SAAS,CAAC;AAC/D,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AS-3 (RESUME): the activity-event verbs that drive the server-side FLEET
|
|
3
|
+
* PAUSE picture.
|
|
4
|
+
*
|
|
5
|
+
* "fleet_pause" is NOT a table — the server DERIVES the live paused-fleet set
|
|
6
|
+
* from `activity_events` (api/_lib/fleet-pause.ts): a runner counts as paused
|
|
7
|
+
* while its LATEST capacity event is a `runner.capacity_paused` whose
|
|
8
|
+
* `resume_at` is absent or still future, and it CLEARS the moment a
|
|
9
|
+
* `runner.capacity_resume` lands. So the resume path "clears the server-side
|
|
10
|
+
* fleet_pause row" by emitting `runner.capacity_resume` for this runner.
|
|
11
|
+
*
|
|
12
|
+
* These strings are DUPLICATED from api/_lib/fleet-pause.ts on purpose (the
|
|
13
|
+
* runner is a standalone published package and must not import from api/_lib —
|
|
14
|
+
* the capacity-plugin.ts precedent). Kept in sync by hand. // keep in sync
|
|
15
|
+
*
|
|
16
|
+
* NOTE (drift the wiring must fix): watch.ts today emits `runner.paused_capacity`
|
|
17
|
+
* / `runner.resume_capacity`, which the loader does NOT read — so the current
|
|
18
|
+
* fixed-timer pause is invisible to fleet_pause. The AS-3 controller emits these
|
|
19
|
+
* canonical verbs through its `setServerPause` / `clearServerPause` seams so the
|
|
20
|
+
* server sees the pause AND its clear.
|
|
21
|
+
*/
|
|
22
|
+
/** Verb a runner emits when it enters a capacity pause. Payload: `{ runner_id, resume_at?: ISO|null, reason?: string }`. */
|
|
23
|
+
export declare const RUNNER_CAPACITY_PAUSED_VERB = "runner.capacity_paused";
|
|
24
|
+
/** Verb a runner emits to clear its server-side fleet pause. Payload: `{ runner_id }`. */
|
|
25
|
+
export declare const RUNNER_CAPACITY_RESUME_VERB = "runner.capacity_resume";
|
|
26
|
+
/** Shape of the `runner.capacity_paused` payload the wiring should emit. */
|
|
27
|
+
export interface FleetPausePayload {
|
|
28
|
+
runner_id: string;
|
|
29
|
+
/** ISO reset instant, or null for an indefinite pause. */
|
|
30
|
+
resume_at: string | null;
|
|
31
|
+
/** Non-secret cause. */
|
|
32
|
+
reason?: string;
|
|
33
|
+
}
|
|
34
|
+
/** Shape of the `runner.capacity_resume` payload the wiring should emit. */
|
|
35
|
+
export interface FleetResumePayload {
|
|
36
|
+
runner_id: string;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=fleet-pause-verbs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fleet-pause-verbs.d.ts","sourceRoot":"","sources":["../../src/capacity/fleet-pause-verbs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,4HAA4H;AAC5H,eAAO,MAAM,2BAA2B,2BAA2B,CAAC;AAEpE,0FAA0F;AAC1F,eAAO,MAAM,2BAA2B,2BAA2B,CAAC;AAEpE,4EAA4E;AAC5E,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,0DAA0D;IAC1D,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,wBAAwB;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,4EAA4E;AAC5E,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;CACnB"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AS-3 (RESUME): the activity-event verbs that drive the server-side FLEET
|
|
3
|
+
* PAUSE picture.
|
|
4
|
+
*
|
|
5
|
+
* "fleet_pause" is NOT a table — the server DERIVES the live paused-fleet set
|
|
6
|
+
* from `activity_events` (api/_lib/fleet-pause.ts): a runner counts as paused
|
|
7
|
+
* while its LATEST capacity event is a `runner.capacity_paused` whose
|
|
8
|
+
* `resume_at` is absent or still future, and it CLEARS the moment a
|
|
9
|
+
* `runner.capacity_resume` lands. So the resume path "clears the server-side
|
|
10
|
+
* fleet_pause row" by emitting `runner.capacity_resume` for this runner.
|
|
11
|
+
*
|
|
12
|
+
* These strings are DUPLICATED from api/_lib/fleet-pause.ts on purpose (the
|
|
13
|
+
* runner is a standalone published package and must not import from api/_lib —
|
|
14
|
+
* the capacity-plugin.ts precedent). Kept in sync by hand. // keep in sync
|
|
15
|
+
*
|
|
16
|
+
* NOTE (drift the wiring must fix): watch.ts today emits `runner.paused_capacity`
|
|
17
|
+
* / `runner.resume_capacity`, which the loader does NOT read — so the current
|
|
18
|
+
* fixed-timer pause is invisible to fleet_pause. The AS-3 controller emits these
|
|
19
|
+
* canonical verbs through its `setServerPause` / `clearServerPause` seams so the
|
|
20
|
+
* server sees the pause AND its clear.
|
|
21
|
+
*/
|
|
22
|
+
/** Verb a runner emits when it enters a capacity pause. Payload: `{ runner_id, resume_at?: ISO|null, reason?: string }`. */
|
|
23
|
+
export const RUNNER_CAPACITY_PAUSED_VERB = "runner.capacity_paused";
|
|
24
|
+
/** Verb a runner emits to clear its server-side fleet pause. Payload: `{ runner_id }`. */
|
|
25
|
+
export const RUNNER_CAPACITY_RESUME_VERB = "runner.capacity_resume";
|
|
26
|
+
//# sourceMappingURL=fleet-pause-verbs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fleet-pause-verbs.js","sourceRoot":"","sources":["../../src/capacity/fleet-pause-verbs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,4HAA4H;AAC5H,MAAM,CAAC,MAAM,2BAA2B,GAAG,wBAAwB,CAAC;AAEpE,0FAA0F;AAC1F,MAAM,CAAC,MAAM,2BAA2B,GAAG,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AS-3 (RESUME): the runner capacity RESUME surface.
|
|
3
|
+
*
|
|
4
|
+
* Public entry point for the pause-until-(reset OR account-change OR ping-ok)
|
|
5
|
+
* engine: the stateful `ResumeController`, the pure `evaluateResume` decision
|
|
6
|
+
* core, the per-account window memory, and the fleet-pause verbs the wiring
|
|
7
|
+
* emits to set/clear the server-side pause. Wiring these onto watch.ts's pause
|
|
8
|
+
* path and the companion turn loop is a follow-up (those files are outside this
|
|
9
|
+
* track's scope); this barrel is what that follow-up imports.
|
|
10
|
+
*/
|
|
11
|
+
export { ResumeController, type ResumeControllerDeps, type ResumeTransition, } from "./resume-controller.js";
|
|
12
|
+
export { evaluateResume, type CapacityMode, type ResumeDecision, type ResumeEvalInput, type ResumeReason, } from "./resume-policy.js";
|
|
13
|
+
export { foldAccountWindow, isStillCapped, type AccountWindow, type AccountWindowEvent, type AccountWindowState, } from "./account-window.js";
|
|
14
|
+
export { RUNNER_CAPACITY_PAUSED_VERB, RUNNER_CAPACITY_RESUME_VERB, type FleetPausePayload, type FleetResumePayload, } from "./fleet-pause-verbs.js";
|
|
15
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/capacity/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EACL,gBAAgB,EAChB,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,GACtB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,cAAc,EACd,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,YAAY,GAClB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,GACxB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,2BAA2B,EAC3B,2BAA2B,EAC3B,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,GACxB,MAAM,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AS-3 (RESUME): the runner capacity RESUME surface.
|
|
3
|
+
*
|
|
4
|
+
* Public entry point for the pause-until-(reset OR account-change OR ping-ok)
|
|
5
|
+
* engine: the stateful `ResumeController`, the pure `evaluateResume` decision
|
|
6
|
+
* core, the per-account window memory, and the fleet-pause verbs the wiring
|
|
7
|
+
* emits to set/clear the server-side pause. Wiring these onto watch.ts's pause
|
|
8
|
+
* path and the companion turn loop is a follow-up (those files are outside this
|
|
9
|
+
* track's scope); this barrel is what that follow-up imports.
|
|
10
|
+
*/
|
|
11
|
+
export { ResumeController, } from "./resume-controller.js";
|
|
12
|
+
export { evaluateResume, } from "./resume-policy.js";
|
|
13
|
+
export { foldAccountWindow, isStillCapped, } from "./account-window.js";
|
|
14
|
+
export { RUNNER_CAPACITY_PAUSED_VERB, RUNNER_CAPACITY_RESUME_VERB, } from "./fleet-pause-verbs.js";
|
|
15
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/capacity/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EACL,gBAAgB,GAGjB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,cAAc,GAKf,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,iBAAiB,EACjB,aAAa,GAId,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,2BAA2B,EAC3B,2BAA2B,GAG5B,MAAM,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AS-3 (RESUME): the capacity RESUME CONTROLLER.
|
|
3
|
+
*
|
|
4
|
+
* The stateful governor that replaces watch.ts's fixed pause-until-reset
|
|
5
|
+
* `setTimeout` with pause-until-(reset OR account-change OR ping-ok), and adds
|
|
6
|
+
* the symmetric re-pause-from-memory for a returning still-capped account.
|
|
7
|
+
* It owns the per-account window memory + the pure resume policy
|
|
8
|
+
* (resume-policy.ts) and drives them off:
|
|
9
|
+
*
|
|
10
|
+
* - `reportCapacity()` — a task/review hit a subscription cap (watch.ts's
|
|
11
|
+
* `enterCapacityPause` trigger). Folds a cap onto the account and, if it is
|
|
12
|
+
* the current account, ENTERS the pause.
|
|
13
|
+
* - `observeAccount()` — the account probe (AS-1 `AccountProbeScheduler` →
|
|
14
|
+
* AS-2 broadcaster) saw the logged-in account. The fast path for a login
|
|
15
|
+
* swap: fires an immediate re-evaluation so a swap converges within one
|
|
16
|
+
* probe cycle rather than waiting on the stale account's reset.
|
|
17
|
+
* - an internal POLL (armed only while paused, at `pollIntervalMs`) that
|
|
18
|
+
* re-checks the reset instant + fires the cheap probe ping.
|
|
19
|
+
*
|
|
20
|
+
* On RESUME it does the three things the plan pins to the SAME TICK: clears the
|
|
21
|
+
* server-side fleet pause (`clearServerPause`), restarts task+review claim
|
|
22
|
+
* scans (`restartClaims`), and kicks the companion turn loop (`kickCompanion`)
|
|
23
|
+
* so queued chat turns drain — then leaves the pause. In-flight sessions are
|
|
24
|
+
* never touched: the controller only gates CLAIMING, it has no abort seam.
|
|
25
|
+
*
|
|
26
|
+
* FULLY injectable (clock / timer / probe / every side-effect seam) and every
|
|
27
|
+
* action is serialized onto one tail promise so overlapping triggers can't race
|
|
28
|
+
* — so the whole lifecycle is exercised with a fake clock, no wall-clock sleep,
|
|
29
|
+
* no real binary, no network.
|
|
30
|
+
*/
|
|
31
|
+
import type { ProbeTimer } from "../engines/account-probe.js";
|
|
32
|
+
import { type AccountWindow } from "./account-window.js";
|
|
33
|
+
import { type CapacityMode, type ResumeReason } from "./resume-policy.js";
|
|
34
|
+
/** A pause/resume transition, handed to the audit sink. */
|
|
35
|
+
export interface ResumeTransition {
|
|
36
|
+
from: CapacityMode;
|
|
37
|
+
to: CapacityMode;
|
|
38
|
+
/** Why the transition fired. */
|
|
39
|
+
reason: ResumeReason | "cap-hit" | "returning-capped-account";
|
|
40
|
+
/** The account the runner is anchored to after the transition. */
|
|
41
|
+
account: string | null;
|
|
42
|
+
/** Which driver produced it. */
|
|
43
|
+
trigger: "cap-report" | "observe-account" | "poll";
|
|
44
|
+
at: number;
|
|
45
|
+
}
|
|
46
|
+
export interface ResumeControllerDeps {
|
|
47
|
+
/** Clock (test seam). Default `Date.now`. */
|
|
48
|
+
now?: () => number;
|
|
49
|
+
/** Timer seam (test seam). Default `setTimeout`/`clearTimeout`. */
|
|
50
|
+
timer?: ProbeTimer;
|
|
51
|
+
/** While-paused re-check cadence (ms). Default 60s. */
|
|
52
|
+
pollIntervalMs?: number;
|
|
53
|
+
/** Min gap between account-change adoptions (flap protection). Default 60s. */
|
|
54
|
+
adoptionDebounceMs?: number;
|
|
55
|
+
/**
|
|
56
|
+
* Cheap serve-check for the observed account while paused:
|
|
57
|
+
* true = can serve now, false = still capped, null = can't tell.
|
|
58
|
+
* Omit to disable ping-based resume (reset + account-change still apply).
|
|
59
|
+
*/
|
|
60
|
+
probePing?: () => Promise<boolean | null>;
|
|
61
|
+
/** Clear the server-side fleet pause (emit `runner.capacity_resume`). */
|
|
62
|
+
clearServerPause: () => void | Promise<void>;
|
|
63
|
+
/** Set the server-side fleet pause (emit `runner.capacity_paused`). Optional. */
|
|
64
|
+
setServerPause?: (ctx: {
|
|
65
|
+
account: string;
|
|
66
|
+
resetAtMs: number | null;
|
|
67
|
+
}) => void | Promise<void>;
|
|
68
|
+
/** Restart task + review claim scans (watch.ts: pollOnce + pump + pumpReviews). */
|
|
69
|
+
restartClaims: () => void | Promise<void>;
|
|
70
|
+
/** Stop claiming tasks + reviews (watch.ts: pausedCapacity = true). Optional. */
|
|
71
|
+
stopClaims?: () => void | Promise<void>;
|
|
72
|
+
/** Kick the companion turn loop so queued chat turns drain. Optional. */
|
|
73
|
+
kickCompanion?: () => void | Promise<void>;
|
|
74
|
+
/** Freeze the companion turn loop on (re-)pause. Optional. */
|
|
75
|
+
freezeCompanion?: () => void | Promise<void>;
|
|
76
|
+
/** Best-effort audit/log sink. */
|
|
77
|
+
onLog?: (line: string) => void;
|
|
78
|
+
/** Transition audit hook. */
|
|
79
|
+
onTransition?: (t: ResumeTransition) => void;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Drives the pause-until-(reset OR account-change OR ping-ok) lifecycle. Start
|
|
83
|
+
* it once the runner knows its account (`start`), feed it cap reports and
|
|
84
|
+
* account observations, and it clears/sets the server pause and restarts claims
|
|
85
|
+
* through the injected seams at the right moment.
|
|
86
|
+
*/
|
|
87
|
+
export declare class ResumeController {
|
|
88
|
+
private readonly deps;
|
|
89
|
+
private readonly now;
|
|
90
|
+
private readonly timer;
|
|
91
|
+
private readonly pollIntervalMs;
|
|
92
|
+
private readonly adoptionDebounceMs;
|
|
93
|
+
private started;
|
|
94
|
+
private stopped;
|
|
95
|
+
private mode;
|
|
96
|
+
/** The account the current state is anchored to (capped account while paused). */
|
|
97
|
+
private anchorAccountKey;
|
|
98
|
+
/** The account the probe last observed. */
|
|
99
|
+
private observedAccountKey;
|
|
100
|
+
/** Per-account remembered capacity windows. */
|
|
101
|
+
private readonly windows;
|
|
102
|
+
/** Epoch ms of the last account-change adoption (null = none yet). */
|
|
103
|
+
private lastAdoptionAtMs;
|
|
104
|
+
private pollHandle;
|
|
105
|
+
/** Serial action chain so overlapping triggers never race. */
|
|
106
|
+
private tail;
|
|
107
|
+
constructor(deps: ResumeControllerDeps);
|
|
108
|
+
/** Current mode. */
|
|
109
|
+
currentMode(): CapacityMode;
|
|
110
|
+
/** The remembered window for an account (test/inspection seam). */
|
|
111
|
+
windowFor(accountKey: string): AccountWindow | null;
|
|
112
|
+
/** Note the runner's starting account. Idempotent. */
|
|
113
|
+
start(accountKey: string | null): void;
|
|
114
|
+
/**
|
|
115
|
+
* A task/review reported a subscription cap on `accountKey`. Folds the cap
|
|
116
|
+
* into that account's window and, when it is the current account and we are
|
|
117
|
+
* still claiming, enters the pause. Extend-only: a straggler cap on the
|
|
118
|
+
* already-paused account only pushes its reset later.
|
|
119
|
+
*/
|
|
120
|
+
reportCapacity(input: {
|
|
121
|
+
accountKey: string;
|
|
122
|
+
resetAtMs: number | null;
|
|
123
|
+
detail?: string;
|
|
124
|
+
}): void;
|
|
125
|
+
/**
|
|
126
|
+
* The account probe observed the logged-in account. The fast path for a login
|
|
127
|
+
* swap — fires an immediate re-evaluation so a swap converges within one probe
|
|
128
|
+
* cycle. A same-account observation is a cheap no-op re-check.
|
|
129
|
+
*/
|
|
130
|
+
observeAccount(accountKey: string | null): void;
|
|
131
|
+
/** Cancel the poll timer; in-flight actions still settle. */
|
|
132
|
+
stop(): void;
|
|
133
|
+
/** Resolve once every queued action has settled (test seam). */
|
|
134
|
+
settle(): Promise<void>;
|
|
135
|
+
private enqueue;
|
|
136
|
+
private armPoll;
|
|
137
|
+
private disarmPoll;
|
|
138
|
+
private onPollFire;
|
|
139
|
+
/** Evaluate the resume policy and act on it. */
|
|
140
|
+
private evaluate;
|
|
141
|
+
/** Enter (or re-enter) the capacity pause on `account`. */
|
|
142
|
+
private enterPause;
|
|
143
|
+
/**
|
|
144
|
+
* Leave the pause: clear the server fleet pause, restart claim scans, and kick
|
|
145
|
+
* the companion turn loop — all in this one tick (queued chat turns then drain
|
|
146
|
+
* on their own). In-flight sessions are never touched.
|
|
147
|
+
*/
|
|
148
|
+
private doResume;
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=resume-controller.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resume-controller.d.ts","sourceRoot":"","sources":["../../src/capacity/resume-controller.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { foldAccountWindow } from "./account-window.js";
|
|
2
|
+
import { evaluateResume, } from "./resume-policy.js";
|
|
3
|
+
const DEFAULT_POLL_INTERVAL_MS = 60_000; // one probe cycle
|
|
4
|
+
const DEFAULT_ADOPTION_DEBOUNCE_MS = 60_000; // CC-3A cooldownMinDwellMs
|
|
5
|
+
const DEFAULT_TIMER = {
|
|
6
|
+
setTimer: (fn, ms) => setTimeout(fn, ms),
|
|
7
|
+
clearTimer: (h) => clearTimeout(h),
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Drives the pause-until-(reset OR account-change OR ping-ok) lifecycle. Start
|
|
11
|
+
* it once the runner knows its account (`start`), feed it cap reports and
|
|
12
|
+
* account observations, and it clears/sets the server pause and restarts claims
|
|
13
|
+
* through the injected seams at the right moment.
|
|
14
|
+
*/
|
|
15
|
+
export class ResumeController {
|
|
16
|
+
deps;
|
|
17
|
+
now;
|
|
18
|
+
timer;
|
|
19
|
+
pollIntervalMs;
|
|
20
|
+
adoptionDebounceMs;
|
|
21
|
+
started = false;
|
|
22
|
+
stopped = false;
|
|
23
|
+
mode = "active";
|
|
24
|
+
/** The account the current state is anchored to (capped account while paused). */
|
|
25
|
+
anchorAccountKey = null;
|
|
26
|
+
/** The account the probe last observed. */
|
|
27
|
+
observedAccountKey = null;
|
|
28
|
+
/** Per-account remembered capacity windows. */
|
|
29
|
+
windows = new Map();
|
|
30
|
+
/** Epoch ms of the last account-change adoption (null = none yet). */
|
|
31
|
+
lastAdoptionAtMs = null;
|
|
32
|
+
pollHandle = null;
|
|
33
|
+
/** Serial action chain so overlapping triggers never race. */
|
|
34
|
+
tail = Promise.resolve();
|
|
35
|
+
constructor(deps) {
|
|
36
|
+
this.deps = deps;
|
|
37
|
+
this.now = deps.now ?? Date.now;
|
|
38
|
+
this.timer = deps.timer ?? DEFAULT_TIMER;
|
|
39
|
+
this.pollIntervalMs = Math.max(1, deps.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS);
|
|
40
|
+
this.adoptionDebounceMs = Math.max(0, deps.adoptionDebounceMs ?? DEFAULT_ADOPTION_DEBOUNCE_MS);
|
|
41
|
+
}
|
|
42
|
+
/** Current mode. */
|
|
43
|
+
currentMode() {
|
|
44
|
+
return this.mode;
|
|
45
|
+
}
|
|
46
|
+
/** The remembered window for an account (test/inspection seam). */
|
|
47
|
+
windowFor(accountKey) {
|
|
48
|
+
return this.windows.get(accountKey) ?? null;
|
|
49
|
+
}
|
|
50
|
+
/** Note the runner's starting account. Idempotent. */
|
|
51
|
+
start(accountKey) {
|
|
52
|
+
if (this.started || this.stopped)
|
|
53
|
+
return;
|
|
54
|
+
this.started = true;
|
|
55
|
+
this.anchorAccountKey = accountKey;
|
|
56
|
+
this.observedAccountKey = accountKey;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* A task/review reported a subscription cap on `accountKey`. Folds the cap
|
|
60
|
+
* into that account's window and, when it is the current account and we are
|
|
61
|
+
* still claiming, enters the pause. Extend-only: a straggler cap on the
|
|
62
|
+
* already-paused account only pushes its reset later.
|
|
63
|
+
*/
|
|
64
|
+
reportCapacity(input) {
|
|
65
|
+
if (this.stopped)
|
|
66
|
+
return;
|
|
67
|
+
if (!this.started)
|
|
68
|
+
this.start(input.accountKey);
|
|
69
|
+
const at = this.now();
|
|
70
|
+
this.windows.set(input.accountKey, foldAccountWindow(this.windows.get(input.accountKey) ?? null, {
|
|
71
|
+
kind: "cap_hit",
|
|
72
|
+
resetAtMs: input.resetAtMs,
|
|
73
|
+
atMs: at,
|
|
74
|
+
}));
|
|
75
|
+
// Only the CURRENT account's cap pauses the runner.
|
|
76
|
+
if (input.accountKey !== (this.observedAccountKey ?? this.anchorAccountKey))
|
|
77
|
+
return;
|
|
78
|
+
if (this.mode === "paused") {
|
|
79
|
+
// Already paused: the window was extended above; nothing else to do.
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
this.enqueue(() => this.enterPause(input.accountKey, input.resetAtMs, "cap-hit", "cap-report"));
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* The account probe observed the logged-in account. The fast path for a login
|
|
86
|
+
* swap — fires an immediate re-evaluation so a swap converges within one probe
|
|
87
|
+
* cycle. A same-account observation is a cheap no-op re-check.
|
|
88
|
+
*/
|
|
89
|
+
observeAccount(accountKey) {
|
|
90
|
+
if (this.stopped || !this.started)
|
|
91
|
+
return;
|
|
92
|
+
this.observedAccountKey = accountKey;
|
|
93
|
+
this.enqueue(() => this.evaluate("observe-account"));
|
|
94
|
+
}
|
|
95
|
+
/** Cancel the poll timer; in-flight actions still settle. */
|
|
96
|
+
stop() {
|
|
97
|
+
this.stopped = true;
|
|
98
|
+
this.disarmPoll();
|
|
99
|
+
}
|
|
100
|
+
/** Resolve once every queued action has settled (test seam). */
|
|
101
|
+
async settle() {
|
|
102
|
+
await this.tail;
|
|
103
|
+
}
|
|
104
|
+
enqueue(fn) {
|
|
105
|
+
this.tail = this.tail.then(fn).catch((err) => {
|
|
106
|
+
this.deps.onLog?.(`[acc-runner] resume-controller action failed: ${err?.message ?? String(err)}`);
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
armPoll() {
|
|
110
|
+
this.disarmPoll();
|
|
111
|
+
if (this.stopped)
|
|
112
|
+
return;
|
|
113
|
+
this.pollHandle = this.timer.setTimer(() => this.onPollFire(), this.pollIntervalMs);
|
|
114
|
+
}
|
|
115
|
+
disarmPoll() {
|
|
116
|
+
if (this.pollHandle !== null) {
|
|
117
|
+
this.timer.clearTimer(this.pollHandle);
|
|
118
|
+
this.pollHandle = null;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
onPollFire() {
|
|
122
|
+
if (this.stopped || this.mode !== "paused")
|
|
123
|
+
return;
|
|
124
|
+
// Re-arm BEFORE the async evaluation so the cadence is decoupled from probe
|
|
125
|
+
// latency and stays deterministic under a fake clock.
|
|
126
|
+
this.armPoll();
|
|
127
|
+
this.enqueue(() => this.evaluate("poll"));
|
|
128
|
+
}
|
|
129
|
+
/** Evaluate the resume policy and act on it. */
|
|
130
|
+
async evaluate(trigger) {
|
|
131
|
+
if (this.stopped)
|
|
132
|
+
return;
|
|
133
|
+
let pingOk = null;
|
|
134
|
+
if (this.mode === "paused" && this.deps.probePing) {
|
|
135
|
+
// Only ping when the same account is still observed — a swap resolves via
|
|
136
|
+
// the account-change branch and needs no request.
|
|
137
|
+
const swapped = this.observedAccountKey !== null && this.observedAccountKey !== this.anchorAccountKey;
|
|
138
|
+
if (!swapped) {
|
|
139
|
+
try {
|
|
140
|
+
pingOk = await this.deps.probePing();
|
|
141
|
+
}
|
|
142
|
+
catch (err) {
|
|
143
|
+
this.deps.onLog?.(`[acc-runner] resume probe ping failed: ${err?.message ?? String(err)}`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
if (this.stopped)
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
const decision = evaluateResume({
|
|
150
|
+
mode: this.mode,
|
|
151
|
+
nowMs: this.now(),
|
|
152
|
+
observedAccountKey: this.observedAccountKey,
|
|
153
|
+
anchorAccountKey: this.anchorAccountKey,
|
|
154
|
+
windows: this.windows,
|
|
155
|
+
pingOk,
|
|
156
|
+
lastAdoptionAtMs: this.lastAdoptionAtMs,
|
|
157
|
+
adoptionDebounceMs: this.adoptionDebounceMs,
|
|
158
|
+
});
|
|
159
|
+
switch (decision.action) {
|
|
160
|
+
case "stay":
|
|
161
|
+
return;
|
|
162
|
+
case "defer":
|
|
163
|
+
this.deps.onLog?.(`[acc-runner] account change to ${decision.account} deferred (adoption debounce)`);
|
|
164
|
+
return;
|
|
165
|
+
case "resume":
|
|
166
|
+
await this.doResume(decision.reason, decision.account, trigger);
|
|
167
|
+
return;
|
|
168
|
+
case "pause":
|
|
169
|
+
await this.enterPause(decision.account, decision.resetAtMs, "returning-capped-account", trigger);
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
/** Enter (or re-enter) the capacity pause on `account`. */
|
|
174
|
+
async enterPause(account, resetAtMs, reason, trigger) {
|
|
175
|
+
if (this.stopped)
|
|
176
|
+
return;
|
|
177
|
+
const from = this.mode;
|
|
178
|
+
const at = this.now();
|
|
179
|
+
// Ensure the account's window reflects this cap.
|
|
180
|
+
this.windows.set(account, foldAccountWindow(this.windows.get(account) ?? null, {
|
|
181
|
+
kind: "cap_hit",
|
|
182
|
+
resetAtMs,
|
|
183
|
+
atMs: at,
|
|
184
|
+
}));
|
|
185
|
+
this.mode = "paused";
|
|
186
|
+
this.anchorAccountKey = account;
|
|
187
|
+
// An account-change re-pause counts as an adoption (flap protection); a
|
|
188
|
+
// plain cap-hit does not, so the first swap after it is never debounced.
|
|
189
|
+
if (reason === "returning-capped-account")
|
|
190
|
+
this.lastAdoptionAtMs = at;
|
|
191
|
+
this.armPoll();
|
|
192
|
+
if (this.deps.setServerPause) {
|
|
193
|
+
await this.deps.setServerPause({ account, resetAtMs });
|
|
194
|
+
}
|
|
195
|
+
if (this.deps.stopClaims)
|
|
196
|
+
await this.deps.stopClaims();
|
|
197
|
+
if (this.deps.freezeCompanion)
|
|
198
|
+
await this.deps.freezeCompanion();
|
|
199
|
+
this.deps.onTransition?.({ from, to: "paused", reason, account, trigger, at });
|
|
200
|
+
this.deps.onLog?.(`[acc-runner] capacity PAUSE (${reason}) on ${account}` +
|
|
201
|
+
(resetAtMs !== null ? ` until ${new Date(resetAtMs).toISOString()}` : " (indefinite)"));
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Leave the pause: clear the server fleet pause, restart claim scans, and kick
|
|
205
|
+
* the companion turn loop — all in this one tick (queued chat turns then drain
|
|
206
|
+
* on their own). In-flight sessions are never touched.
|
|
207
|
+
*/
|
|
208
|
+
async doResume(reason, account, trigger) {
|
|
209
|
+
if (this.stopped)
|
|
210
|
+
return;
|
|
211
|
+
const from = this.mode;
|
|
212
|
+
const at = this.now();
|
|
213
|
+
this.mode = "active";
|
|
214
|
+
this.anchorAccountKey = account;
|
|
215
|
+
this.lastAdoptionAtMs = at;
|
|
216
|
+
// We are now serving on this account, so its window is open in memory — a
|
|
217
|
+
// later swap back to it resumes (not re-pauses) until it caps again.
|
|
218
|
+
this.windows.set(account, { state: "open", resetAtMs: null, updatedAtMs: at });
|
|
219
|
+
this.disarmPoll();
|
|
220
|
+
// Same tick: clear server pause → restart task+review claims → drain companion.
|
|
221
|
+
await this.deps.clearServerPause();
|
|
222
|
+
await this.deps.restartClaims();
|
|
223
|
+
if (this.deps.kickCompanion)
|
|
224
|
+
await this.deps.kickCompanion();
|
|
225
|
+
this.deps.onTransition?.({ from, to: "active", reason, account, trigger, at });
|
|
226
|
+
this.deps.onLog?.(`[acc-runner] capacity RESUME (${reason}) on ${account}`);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
//# sourceMappingURL=resume-controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resume-controller.js","sourceRoot":"","sources":["../../src/capacity/resume-controller.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AS-3 (RESUME): the PURE pause-until decision core.
|
|
3
|
+
*
|
|
4
|
+
* Replaces the fixed pause-until-reset timer (watch.ts's single `setTimeout`
|
|
5
|
+
* keyed to the capped account's stated reset) with
|
|
6
|
+
*
|
|
7
|
+
* pause-until ( current account's reset elapsed
|
|
8
|
+
* OR the logged-in account CHANGED
|
|
9
|
+
* OR a cheap probe ping says we can serve )
|
|
10
|
+
*
|
|
11
|
+
* plus the operator's symmetric requirement: swapping to a DIFFERENT account
|
|
12
|
+
* that is itself still-capped in memory RE-PAUSES from memory (no request
|
|
13
|
+
* burned) rather than resuming into an account that will just 429 again.
|
|
14
|
+
*
|
|
15
|
+
* Flap protection (reuse of the CC-3A pattern — api/_lib/capacity/
|
|
16
|
+
* identity-capacity.ts `cooldownMinDwellMs: 60_000`): an account-change
|
|
17
|
+
* adoption (resume or re-pause) is DEBOUNCED — a second account-change within
|
|
18
|
+
* `adoptionDebounceMs` of the last adoption is DEFERRED, so a keychain that
|
|
19
|
+
* flaps A→B→A→B faster than the debounce collapses to a single adoption instead
|
|
20
|
+
* of thrashing resume/pause. The capacity-window hysteresis (never reopen a
|
|
21
|
+
* capped window on a null-reset guess) lives in the fold (account-window.ts).
|
|
22
|
+
*
|
|
23
|
+
* PURE by construction: no clock, no timer, no I/O — every input is passed in,
|
|
24
|
+
* so the whole decision surface is exercised with a fake clock in unit tests.
|
|
25
|
+
*/
|
|
26
|
+
import { type AccountWindow } from "./account-window.js";
|
|
27
|
+
/** Whether the runner is currently claiming (`active`) or capacity-paused (`paused`). */
|
|
28
|
+
export type CapacityMode = "active" | "paused";
|
|
29
|
+
/** Inputs for one resume/re-pause decision. */
|
|
30
|
+
export interface ResumeEvalInput {
|
|
31
|
+
/** Current runner mode. */
|
|
32
|
+
mode: CapacityMode;
|
|
33
|
+
/** Wall-clock now (epoch ms) from the injected clock. */
|
|
34
|
+
nowMs: number;
|
|
35
|
+
/**
|
|
36
|
+
* The account the probe currently observes (its `synthetic_account`), or
|
|
37
|
+
* `null` when the probe cannot introspect one this tick.
|
|
38
|
+
*/
|
|
39
|
+
observedAccountKey: string | null;
|
|
40
|
+
/**
|
|
41
|
+
* The account the current state is anchored to: the capped account while
|
|
42
|
+
* paused, or the last-known serving account while active. `null` before the
|
|
43
|
+
* first observation.
|
|
44
|
+
*/
|
|
45
|
+
anchorAccountKey: string | null;
|
|
46
|
+
/** Per-account remembered capacity windows (keyed on `synthetic_account`). */
|
|
47
|
+
windows: ReadonlyMap<string, AccountWindow>;
|
|
48
|
+
/**
|
|
49
|
+
* Result of a cheap probe ping for the observed account THIS tick:
|
|
50
|
+
* true = the account can serve now (resume),
|
|
51
|
+
* false = still capped,
|
|
52
|
+
* null = not probed / can't tell.
|
|
53
|
+
* Only consulted while paused on the same account.
|
|
54
|
+
*/
|
|
55
|
+
pingOk: boolean | null;
|
|
56
|
+
/**
|
|
57
|
+
* Epoch ms of the last account-change adoption (resume or re-pause), or
|
|
58
|
+
* `null` if none yet — the initial cap-pause is NOT an adoption, so the first
|
|
59
|
+
* swap after a pause is never debounced.
|
|
60
|
+
*/
|
|
61
|
+
lastAdoptionAtMs: number | null;
|
|
62
|
+
/** Minimum gap between account-change adoptions (flap protection). */
|
|
63
|
+
adoptionDebounceMs: number;
|
|
64
|
+
}
|
|
65
|
+
/** Why a resume fired. */
|
|
66
|
+
export type ResumeReason = "reset" | "account-change" | "ping-ok";
|
|
67
|
+
/** The decision the controller acts on. */
|
|
68
|
+
export type ResumeDecision =
|
|
69
|
+
/** Stay in the current mode. */
|
|
70
|
+
{
|
|
71
|
+
action: "stay";
|
|
72
|
+
}
|
|
73
|
+
/** Leave the pause and resume claiming, on `account`. */
|
|
74
|
+
| {
|
|
75
|
+
action: "resume";
|
|
76
|
+
reason: ResumeReason;
|
|
77
|
+
account: string;
|
|
78
|
+
}
|
|
79
|
+
/** Re-pause: the observed account is a KNOWN still-capped account (from memory). */
|
|
80
|
+
| {
|
|
81
|
+
action: "pause";
|
|
82
|
+
reason: "returning-capped-account";
|
|
83
|
+
account: string;
|
|
84
|
+
resetAtMs: number | null;
|
|
85
|
+
}
|
|
86
|
+
/** An account change is held back by the adoption debounce; retry after the hold. */
|
|
87
|
+
| {
|
|
88
|
+
action: "defer";
|
|
89
|
+
reason: "adoption-debounce";
|
|
90
|
+
account: string;
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* Decide the next action. Pure — the controller supplies every input and
|
|
94
|
+
* executes the returned action (arming timers, calling seams). Ordering:
|
|
95
|
+
* 1. account swap (highest signal) — debounced, then resume-or-re-pause by
|
|
96
|
+
* the new account's remembered window;
|
|
97
|
+
* 2. same account while paused — reset elapsed, else a positive ping;
|
|
98
|
+
* 3. otherwise stay.
|
|
99
|
+
*/
|
|
100
|
+
export declare function evaluateResume(input: ResumeEvalInput): ResumeDecision;
|
|
101
|
+
//# sourceMappingURL=resume-policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resume-policy.d.ts","sourceRoot":"","sources":["../../src/capacity/resume-policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,EAAiB,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAExE,yFAAyF;AACzF,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE/C,+CAA+C;AAC/C,MAAM,WAAW,eAAe;IAC9B,2BAA2B;IAC3B,IAAI,EAAE,YAAY,CAAC;IACnB,yDAAyD;IACzD,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC;;;;OAIG;IACH,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,8EAA8E;IAC9E,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAC5C;;;;;;OAMG;IACH,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;IACvB;;;;OAIG;IACH,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,sEAAsE;IACtE,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,0BAA0B;AAC1B,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,gBAAgB,GAAG,SAAS,CAAC;AAElE,2CAA2C;AAC3C,MAAM,MAAM,cAAc;AACxB,gCAAgC;AAC9B;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE;AACpB,yDAAyD;GACvD;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,YAAY,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE;AAC7D,oFAAoF;GAClF;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,0BAA0B,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE;AACpG,qFAAqF;GACnF;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,mBAAmB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAOtE;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,eAAe,GAAG,cAAc,CA4CrE"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AS-3 (RESUME): the PURE pause-until decision core.
|
|
3
|
+
*
|
|
4
|
+
* Replaces the fixed pause-until-reset timer (watch.ts's single `setTimeout`
|
|
5
|
+
* keyed to the capped account's stated reset) with
|
|
6
|
+
*
|
|
7
|
+
* pause-until ( current account's reset elapsed
|
|
8
|
+
* OR the logged-in account CHANGED
|
|
9
|
+
* OR a cheap probe ping says we can serve )
|
|
10
|
+
*
|
|
11
|
+
* plus the operator's symmetric requirement: swapping to a DIFFERENT account
|
|
12
|
+
* that is itself still-capped in memory RE-PAUSES from memory (no request
|
|
13
|
+
* burned) rather than resuming into an account that will just 429 again.
|
|
14
|
+
*
|
|
15
|
+
* Flap protection (reuse of the CC-3A pattern — api/_lib/capacity/
|
|
16
|
+
* identity-capacity.ts `cooldownMinDwellMs: 60_000`): an account-change
|
|
17
|
+
* adoption (resume or re-pause) is DEBOUNCED — a second account-change within
|
|
18
|
+
* `adoptionDebounceMs` of the last adoption is DEFERRED, so a keychain that
|
|
19
|
+
* flaps A→B→A→B faster than the debounce collapses to a single adoption instead
|
|
20
|
+
* of thrashing resume/pause. The capacity-window hysteresis (never reopen a
|
|
21
|
+
* capped window on a null-reset guess) lives in the fold (account-window.ts).
|
|
22
|
+
*
|
|
23
|
+
* PURE by construction: no clock, no timer, no I/O — every input is passed in,
|
|
24
|
+
* so the whole decision surface is exercised with a fake clock in unit tests.
|
|
25
|
+
*/
|
|
26
|
+
import { isStillCapped } from "./account-window.js";
|
|
27
|
+
/** True when the observed account differs from the anchor (a login swap). */
|
|
28
|
+
function accountSwapped(input) {
|
|
29
|
+
return input.observedAccountKey !== null && input.observedAccountKey !== input.anchorAccountKey;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Decide the next action. Pure — the controller supplies every input and
|
|
33
|
+
* executes the returned action (arming timers, calling seams). Ordering:
|
|
34
|
+
* 1. account swap (highest signal) — debounced, then resume-or-re-pause by
|
|
35
|
+
* the new account's remembered window;
|
|
36
|
+
* 2. same account while paused — reset elapsed, else a positive ping;
|
|
37
|
+
* 3. otherwise stay.
|
|
38
|
+
*/
|
|
39
|
+
export function evaluateResume(input) {
|
|
40
|
+
if (accountSwapped(input)) {
|
|
41
|
+
const account = input.observedAccountKey;
|
|
42
|
+
// Flap protection: coalesce rapid account-change adoptions.
|
|
43
|
+
if (input.lastAdoptionAtMs !== null &&
|
|
44
|
+
input.nowMs - input.lastAdoptionAtMs < input.adoptionDebounceMs) {
|
|
45
|
+
return { action: "defer", reason: "adoption-debounce", account };
|
|
46
|
+
}
|
|
47
|
+
const window = input.windows.get(account) ?? null;
|
|
48
|
+
if (isStillCapped(window, input.nowMs)) {
|
|
49
|
+
// Swapped to a known still-capped account → re-pause from memory.
|
|
50
|
+
if (input.mode === "paused" && input.anchorAccountKey === account) {
|
|
51
|
+
return { action: "stay" };
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
action: "pause",
|
|
55
|
+
reason: "returning-capped-account",
|
|
56
|
+
account,
|
|
57
|
+
resetAtMs: window ? window.resetAtMs : null,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
// Fresh / unknown account → its quota is available; resume when paused.
|
|
61
|
+
if (input.mode === "paused") {
|
|
62
|
+
return { action: "resume", reason: "account-change", account };
|
|
63
|
+
}
|
|
64
|
+
return { action: "stay" };
|
|
65
|
+
}
|
|
66
|
+
if (input.mode === "paused") {
|
|
67
|
+
const key = input.observedAccountKey ?? input.anchorAccountKey;
|
|
68
|
+
const window = key ? input.windows.get(key) ?? null : null;
|
|
69
|
+
// Reset elapsed on the capped account's known window.
|
|
70
|
+
if (window && window.state === "capped" && window.resetAtMs !== null && input.nowMs >= window.resetAtMs) {
|
|
71
|
+
return { action: "resume", reason: "reset", account: key };
|
|
72
|
+
}
|
|
73
|
+
// Cheap probe ping says the window reopened early.
|
|
74
|
+
if (input.pingOk === true && key !== null) {
|
|
75
|
+
return { action: "resume", reason: "ping-ok", account: key };
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return { action: "stay" };
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=resume-policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resume-policy.js","sourceRoot":"","sources":["../../src/capacity/resume-policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,EAAE,aAAa,EAAsB,MAAM,qBAAqB,CAAC;AAwDxE,6EAA6E;AAC7E,SAAS,cAAc,CAAC,KAAsB;IAC5C,OAAO,KAAK,CAAC,kBAAkB,KAAK,IAAI,IAAI,KAAK,CAAC,kBAAkB,KAAK,KAAK,CAAC,gBAAgB,CAAC;AAClG,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAAC,KAAsB;IACnD,IAAI,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,OAAO,GAAG,KAAK,CAAC,kBAA4B,CAAC;QACnD,4DAA4D;QAC5D,IACE,KAAK,CAAC,gBAAgB,KAAK,IAAI;YAC/B,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,gBAAgB,GAAG,KAAK,CAAC,kBAAkB,EAC/D,CAAC;YACD,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,mBAAmB,EAAE,OAAO,EAAE,CAAC;QACnE,CAAC;QACD,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC;QAClD,IAAI,aAAa,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YACvC,kEAAkE;YAClE,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,gBAAgB,KAAK,OAAO,EAAE,CAAC;gBAClE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;YAC5B,CAAC;YACD,OAAO;gBACL,MAAM,EAAE,OAAO;gBACf,MAAM,EAAE,0BAA0B;gBAClC,OAAO;gBACP,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI;aAC5C,CAAC;QACJ,CAAC;QACD,wEAAwE;QACxE,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC5B,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,gBAAgB,EAAE,OAAO,EAAE,CAAC;QACjE,CAAC;QACD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IAC5B,CAAC;IAED,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC5B,MAAM,GAAG,GAAG,KAAK,CAAC,kBAAkB,IAAI,KAAK,CAAC,gBAAgB,CAAC;QAC/D,MAAM,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;QAC3D,sDAAsD;QACtD,IAAI,MAAM,IAAI,MAAM,CAAC,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,SAAS,KAAK,IAAI,IAAI,KAAK,CAAC,KAAK,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;YACxG,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAG,GAAc,EAAE,CAAC;QACzE,CAAC;QACD,mDAAmD;QACnD,IAAI,KAAK,CAAC,MAAM,KAAK,IAAI,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YAC1C,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC;QAC/D,CAAC;IACH,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAC5B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"companion-run.d.ts","sourceRoot":"","sources":["../src/companion-run.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"companion-run.d.ts","sourceRoot":"","sources":["../src/companion-run.ts"],"names":[],"mappings":"AA8CA,gFAAgF;AAChF,MAAM,WAAW,eAAe;IAC9B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB;AAED,oFAAoF;AACpF,eAAO,MAAM,2BAA2B,uCAAuC,CAAC;AAChF;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,kCAAkC,CAAC;AAEtE;;;;GAIG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,eAAe,CAAC,CA0OjE;AAED,+DAA+D;AAC/D,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC,CAmB5D;AAED,8DAA8D;AAC9D,wBAAsB,uBAAuB,IAAI,OAAO,CAAC,IAAI,CAAC,CAK7D;AAED,wCAAwC;AACxC,wBAAsB,yBAAyB,IAAI,OAAO,CAAC,IAAI,CAAC,CAK/D"}
|
package/dist/companion-run.js
CHANGED
|
@@ -14,6 +14,7 @@ import { createRunnerClient } from "./supabase.js";
|
|
|
14
14
|
import { RefreshReuseDetectedError, expiresSoon, refreshAccessToken, } from "./runtime/auth-lifecycle.js";
|
|
15
15
|
import { createSupabaseChatTransport } from "./chat-transport.js";
|
|
16
16
|
import { getChatEngine } from "./engines/registry.js";
|
|
17
|
+
import { writeMcpConfig } from "./mcp-spawn.js";
|
|
17
18
|
import { ChatCircuitBreaker, getChatCircuit } from "./runtime/chat-circuit-breaker.js";
|
|
18
19
|
import { CompanionMirrorSocket } from "./companion-mirror-socket.js";
|
|
19
20
|
import { CompanionRunner, OwnerConversationSource, createIdentityBroadcaster, deriveMirrorToken, resolveCompanionConfig, } from "./companion.js";
|
|
@@ -123,6 +124,34 @@ export async function companionCommand() {
|
|
|
123
124
|
// is reflected if the registration is retried on the fresh JWT.
|
|
124
125
|
reportIdentityProbe({ publicUrl: cfg.publicUrl, accessToken: session.access_token }, payload)
|
|
125
126
|
: undefined;
|
|
127
|
+
// CHAT-MCP-PROVISION: the chat engine spawns claude with
|
|
128
|
+
// `--strict-mcp-config --mcp-config <repoPath>/.mcp.json` and disables every
|
|
129
|
+
// native tool (acc-mcp is the only tool bus). Without that file claude
|
|
130
|
+
// hard-errors ("MCP config file not found") and the turn streams NO text — the
|
|
131
|
+
// operator sees an empty reply. The task lane provisions it via writeMcpConfig;
|
|
132
|
+
// the chat lane must too. One config covers the whole companion session (cwd is
|
|
133
|
+
// the stable repoPath); acc-mcp-server authorizes via the runner access token
|
|
134
|
+
// (task-id is optional for the chat lane). Re-provisioned on every token
|
|
135
|
+
// refresh so the baked JWT never goes stale. Reads session/cfg at CALL time.
|
|
136
|
+
let mcpCleanup = null;
|
|
137
|
+
const provisionChatMcp = async () => {
|
|
138
|
+
try {
|
|
139
|
+
mcpCleanup = await writeMcpConfig({
|
|
140
|
+
cwd: cfg.repoPath,
|
|
141
|
+
taskId: "", // no task in the chat lane — acc-mcp-server treats it as null
|
|
142
|
+
runnerId: session.runner_id,
|
|
143
|
+
accessToken: session.access_token,
|
|
144
|
+
publicUrl: cfg.publicUrl,
|
|
145
|
+
supabaseUrl: cfg.supabaseUrl,
|
|
146
|
+
supabaseAnonKey: cfg.supabaseAnonKey,
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
catch (err) {
|
|
150
|
+
// Non-fatal: a turn will still error visibly rather than the companion
|
|
151
|
+
// failing to come online. Surfaced so `doctor` / logs show the cause.
|
|
152
|
+
console.log(chalk.yellow(`[acc-runner] chat acc-mcp provisioning failed: ${err.message}`));
|
|
153
|
+
}
|
|
154
|
+
};
|
|
126
155
|
// AUTH-REFRESH: rotate the ACC session in place. Called proactively (token
|
|
127
156
|
// near expiry) and reactively (ONE per auth-failure streak) by CompanionRunner.
|
|
128
157
|
// Rebuilds the Supabase client so the next heartbeat bears the fresh JWT, and
|
|
@@ -153,6 +182,9 @@ export async function companionCommand() {
|
|
|
153
182
|
await transport.refreshClient(supabase, session.access_token).catch(() => {
|
|
154
183
|
/* channel teardown is best-effort; the next frame re-subscribes */
|
|
155
184
|
});
|
|
185
|
+
// Re-bake the fresh JWT into .mcp.json so the acc-mcp bus keeps authorizing
|
|
186
|
+
// across the rotation (the old token would 401 the tool calls otherwise).
|
|
187
|
+
await provisionChatMcp();
|
|
156
188
|
return true;
|
|
157
189
|
};
|
|
158
190
|
const runner = new CompanionRunner({
|
|
@@ -188,6 +220,8 @@ export async function companionCommand() {
|
|
|
188
220
|
cwd: cfg.repoPath,
|
|
189
221
|
onLog: (line) => console.log(chalk.gray(line)),
|
|
190
222
|
});
|
|
223
|
+
// Provision the acc-mcp tool bus before any turn can be claimed/driven.
|
|
224
|
+
await provisionChatMcp();
|
|
191
225
|
await runner.start();
|
|
192
226
|
// HONESTY: the banner states the bound identity (green) or "UNBOUND — not
|
|
193
227
|
// serving provider status" (yellow) with the reason + how to fix. `tone==="ok"`
|
|
@@ -202,6 +236,10 @@ export async function companionCommand() {
|
|
|
202
236
|
async stop() {
|
|
203
237
|
await runner.stop();
|
|
204
238
|
await broadcaster.close();
|
|
239
|
+
// Remove our JWT-bearing .mcp.json (or restore the operator's original).
|
|
240
|
+
await mcpCleanup?.restore().catch(() => {
|
|
241
|
+
/* best-effort; never block shutdown on config cleanup */
|
|
242
|
+
});
|
|
205
243
|
},
|
|
206
244
|
};
|
|
207
245
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"companion-run.js","sourceRoot":"","sources":["../src/companion-run.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"companion-run.js","sourceRoot":"","sources":["../src/companion-run.ts"],"names":[],"mappings":"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"}
|