@coreplane/switchboard 1.260.6 → 1.261.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/assets/deploy/cloudflare-memory/worker.ts +89 -1
- package/dist/assets/package-lock.json +3 -3
- package/dist/assets/package.json +1 -1
- package/dist/assets/source.json +3 -3
- package/dist/assets/src/core/pipelineStanding.ts +24 -0
- package/dist/assets/src/core/plane/decide.ts +25 -0
- package/dist/assets/src/core/runEvents.ts +5 -0
- package/dist/assets/src/core/runFriction.ts +2 -0
- package/dist/assets/src/core/runLedger/types.ts +21 -0
- package/dist/assets/src/core/runLiveState.ts +205 -0
- package/dist/assets/src/core/runRecord.ts +4 -0
- package/dist/cli.js +945 -166
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -4078,6 +4078,7 @@ function isHeadMaterial(event) {
|
|
|
4078
4078
|
case "context":
|
|
4079
4079
|
case "reference":
|
|
4080
4080
|
case "run_meta":
|
|
4081
|
+
case "run_state":
|
|
4081
4082
|
case "route":
|
|
4082
4083
|
return true;
|
|
4083
4084
|
case "run_note":
|
|
@@ -4847,7 +4848,7 @@ function analyzeRunFriction(events, opts = {}) {
|
|
|
4847
4848
|
return;
|
|
4848
4849
|
}
|
|
4849
4850
|
if (ev.type === "artifact" && ev.direction === "out") outboundArtifacts++;
|
|
4850
|
-
if (ev.type === "skill_use" || ev.type === "artifact" || ev.type === "review_artifact" || ev.type === "pr_description" || ev.type === "pr_opened" || ev.type === "coordinator_tag" || ev.type === "ship_handoff" || ev.type === "child_interrupted" || ev.type === "child_resumed" || ev.type === "review_posted" || ev.type === "ship_round" || ev.type === "ship_unit" || ev.type === "route" || ev.type === "operator" || ev.type === "refusal" || ev.type === "reference" || ev.type === "lease" || ev.type === "pushed_head") {
|
|
4851
|
+
if (ev.type === "skill_use" || ev.type === "artifact" || ev.type === "review_artifact" || ev.type === "pr_description" || ev.type === "pr_opened" || ev.type === "coordinator_tag" || ev.type === "ship_handoff" || ev.type === "child_interrupted" || ev.type === "child_resumed" || ev.type === "review_posted" || ev.type === "ship_round" || ev.type === "ship_unit" || ev.type === "route" || ev.type === "operator" || ev.type === "refusal" || ev.type === "reference" || ev.type === "run_state" || ev.type === "lease" || ev.type === "pushed_head") {
|
|
4851
4852
|
sideFactEvents++;
|
|
4852
4853
|
return;
|
|
4853
4854
|
}
|
|
@@ -4929,6 +4930,7 @@ function analyzeRunFriction(events, opts = {}) {
|
|
|
4929
4930
|
}
|
|
4930
4931
|
return;
|
|
4931
4932
|
}
|
|
4933
|
+
if (ev.type !== "run_note") return;
|
|
4932
4934
|
switch (ev.kind) {
|
|
4933
4935
|
case "wrap_up":
|
|
4934
4936
|
wrapUp = { index, at: ev.at };
|
|
@@ -5882,6 +5884,26 @@ var init_contract2 = __esm({
|
|
|
5882
5884
|
});
|
|
5883
5885
|
|
|
5884
5886
|
// ../../src/core/pipelineStanding.ts
|
|
5887
|
+
function hostedStageDetail(stage) {
|
|
5888
|
+
switch (stage) {
|
|
5889
|
+
case "coding":
|
|
5890
|
+
return "coding a unit";
|
|
5891
|
+
case "review":
|
|
5892
|
+
return "reviewing a unit";
|
|
5893
|
+
case "fix":
|
|
5894
|
+
return "fixing review findings";
|
|
5895
|
+
case "approved":
|
|
5896
|
+
return "waiting for checks and merge";
|
|
5897
|
+
case "merge-ready":
|
|
5898
|
+
return "ready for a person to merge";
|
|
5899
|
+
case "merged":
|
|
5900
|
+
return "a unit merged";
|
|
5901
|
+
case "idle":
|
|
5902
|
+
return "waiting for the next pipeline step";
|
|
5903
|
+
case "ended":
|
|
5904
|
+
return "finishing the pipeline";
|
|
5905
|
+
}
|
|
5906
|
+
}
|
|
5885
5907
|
function endingWordOf(kind) {
|
|
5886
5908
|
return ENDING_WORDS[kind] ?? kind;
|
|
5887
5909
|
}
|
|
@@ -6008,10 +6030,11 @@ function isPipelineSummaryShape(v) {
|
|
|
6008
6030
|
}
|
|
6009
6031
|
return true;
|
|
6010
6032
|
}
|
|
6011
|
-
var STAGES, OPEN_STAGES, ROUND_STAGE, ENDING_STAGE, ENDING_WORDS, ROUND_OUTCOME_WORDS, isFinite_;
|
|
6033
|
+
var HOSTED_PIPELINE_STARTING_DETAIL, STAGES, OPEN_STAGES, ROUND_STAGE, ENDING_STAGE, ENDING_WORDS, ROUND_OUTCOME_WORDS, isFinite_;
|
|
6012
6034
|
var init_pipelineStanding = __esm({
|
|
6013
6035
|
"../../src/core/pipelineStanding.ts"() {
|
|
6014
6036
|
"use strict";
|
|
6037
|
+
HOSTED_PIPELINE_STARTING_DETAIL = "pipeline starting";
|
|
6015
6038
|
STAGES = [
|
|
6016
6039
|
"coding",
|
|
6017
6040
|
"review",
|
|
@@ -16134,6 +16157,7 @@ var init_resident = __esm({
|
|
|
16134
16157
|
* here: its `runtime-replaced` is the typed restart (`opWithReattach`). */
|
|
16135
16158
|
runtimeReplacedStreak = 0;
|
|
16136
16159
|
lastBinding;
|
|
16160
|
+
attachAttempt = 0;
|
|
16137
16161
|
/** The thread's binding as the resident answered it on the most recent
|
|
16138
16162
|
* successful attach — including a mid-run re-attach after an eviction, which
|
|
16139
16163
|
* may land on a newer sha than the one the run started on. Undefined until
|
|
@@ -16300,6 +16324,7 @@ var init_resident = __esm({
|
|
|
16300
16324
|
* an operation's wall clock is the command's, and a recovery attach is not
|
|
16301
16325
|
* the command. */
|
|
16302
16326
|
async attach(span, opts = {}) {
|
|
16327
|
+
this.attachAttempt++;
|
|
16303
16328
|
const answer = await this.attachOnce(span, this.attachBoundMs("/attach"), opts.signal);
|
|
16304
16329
|
if (answer.ok) return answer.binding;
|
|
16305
16330
|
if (isDrainingRefusal(answer)) {
|
|
@@ -16348,14 +16373,16 @@ var init_resident = __esm({
|
|
|
16348
16373
|
t0 + (left === void 0 ? DRAIN_WAIT_MAX_MS : Math.max(0, left - DRAIN_LEASE_RESERVE_MS))
|
|
16349
16374
|
);
|
|
16350
16375
|
let answer = first;
|
|
16351
|
-
|
|
16352
|
-
|
|
16353
|
-
|
|
16376
|
+
await this.opts.onLiveStateObservation?.({
|
|
16377
|
+
state: "waiting_deploy",
|
|
16378
|
+
bound: deadline,
|
|
16379
|
+
reason: "deploy",
|
|
16380
|
+
attempt: this.attachAttempt
|
|
16381
|
+
});
|
|
16354
16382
|
const waitSpan = span?.start("dispatch.workspace.attach.drain-wait");
|
|
16355
16383
|
try {
|
|
16356
16384
|
for (; ; ) {
|
|
16357
16385
|
const now = systemClock();
|
|
16358
|
-
note(now);
|
|
16359
16386
|
if (now >= deadline)
|
|
16360
16387
|
throw new ResidentDrainingError(this.opts.resource, now - t0, drainingUntil(answer), refusalWords(answer));
|
|
16361
16388
|
await wakePause(Math.min(DRAIN_POLL_MS, deadline - now), opts.signal, "/attach");
|
|
@@ -16393,7 +16420,6 @@ var init_resident = __esm({
|
|
|
16393
16420
|
}
|
|
16394
16421
|
throw err2;
|
|
16395
16422
|
} finally {
|
|
16396
|
-
this.opts.onSetupNote?.(void 0);
|
|
16397
16423
|
}
|
|
16398
16424
|
}
|
|
16399
16425
|
/** One `/attach`, answered rather than thrown: the binding on a 200, else
|
|
@@ -16700,6 +16726,13 @@ var init_resident = __esm({
|
|
|
16700
16726
|
}
|
|
16701
16727
|
};
|
|
16702
16728
|
const t0 = systemClock();
|
|
16729
|
+
const wakeBound = t0 + wakeWaitBudget(opts.budgetMs);
|
|
16730
|
+
await this.opts.onLiveStateObservation?.({
|
|
16731
|
+
state: "waiting_repository",
|
|
16732
|
+
bound: wakeBound,
|
|
16733
|
+
reason: "repository_container",
|
|
16734
|
+
attempt: this.attachAttempt
|
|
16735
|
+
});
|
|
16703
16736
|
let transient = opts.origin === "transient-refusal";
|
|
16704
16737
|
const definite = (why) => residentWakeStrike(route2, refusal, why, "refused", opts.origin);
|
|
16705
16738
|
const decide = (view) => transient && isUnansweredProbe(view) ? {
|
|
@@ -18413,7 +18446,7 @@ async function makeExecutor(opts, ctx, span) {
|
|
|
18413
18446
|
resolveEnvs: () => gitIdentityEnvs(ctx.profile.identity, authorSourceOf(opts, ctx)),
|
|
18414
18447
|
...ctx.ownPr !== void 0 ? { ownPr: ctx.ownPr } : {},
|
|
18415
18448
|
...ctx.remainingMs !== void 0 ? { remainingMs: ctx.remainingMs } : {},
|
|
18416
|
-
...ctx.
|
|
18449
|
+
...ctx.onLiveStateObservation !== void 0 ? { onLiveStateObservation: ctx.onLiveStateObservation } : {}
|
|
18417
18450
|
},
|
|
18418
18451
|
nonWarm,
|
|
18419
18452
|
span,
|
|
@@ -18595,7 +18628,7 @@ async function reattachWorkspace(opts, ctx, recorded, span) {
|
|
|
18595
18628
|
// resident holds its own credential, so the pairs alone ride.
|
|
18596
18629
|
resolveEnvs: () => gitIdentityEnvs(ctx.profile.identity, authorSourceOf(opts, ctx)),
|
|
18597
18630
|
...ctx.remainingMs !== void 0 ? { remainingMs: ctx.remainingMs } : {},
|
|
18598
|
-
...ctx.
|
|
18631
|
+
...ctx.onLiveStateObservation !== void 0 ? { onLiveStateObservation: ctx.onLiveStateObservation } : {}
|
|
18599
18632
|
});
|
|
18600
18633
|
let binding;
|
|
18601
18634
|
try {
|
|
@@ -25400,6 +25433,199 @@ var init_frictionProposals = __esm({
|
|
|
25400
25433
|
}
|
|
25401
25434
|
});
|
|
25402
25435
|
|
|
25436
|
+
// ../../src/core/runLiveState.ts
|
|
25437
|
+
function safeLiveStateDetail(detail) {
|
|
25438
|
+
if (detail === void 0) return void 0;
|
|
25439
|
+
const line4 = oneLine(detail);
|
|
25440
|
+
if (line4 === "" || UNSAFE_DETAIL.test(line4)) return void 0;
|
|
25441
|
+
return redactAndCap(line4, LIVE_STATE_DETAIL_MAX - 1);
|
|
25442
|
+
}
|
|
25443
|
+
function assignRunLiveState(current, currentSeq, input) {
|
|
25444
|
+
if (input.expectedSeq !== currentSeq) return { ok: false, reason: "stale-sequence" };
|
|
25445
|
+
if (current === void 0 && input.state !== "admitted") return { ok: false, reason: "invalid-transition" };
|
|
25446
|
+
if (current?.state === "ended") return { ok: false, reason: "terminal" };
|
|
25447
|
+
if (input.state !== "ended") {
|
|
25448
|
+
if (input.bound === void 0) return { ok: false, reason: "bound-required" };
|
|
25449
|
+
if (!Number.isFinite(input.bound) || input.bound < input.at) return { ok: false, reason: "invalid-bound" };
|
|
25450
|
+
} else if (input.cause === void 0) return { ok: false, reason: "cause-required" };
|
|
25451
|
+
if (current !== void 0 && current.state !== input.state && !TRANSITIONS[current.state].includes(input.state))
|
|
25452
|
+
return { ok: false, reason: "invalid-transition" };
|
|
25453
|
+
const detail = safeLiveStateDetail(input.detail);
|
|
25454
|
+
const liveState = {
|
|
25455
|
+
state: input.state,
|
|
25456
|
+
since: current?.state === input.state ? current.since : input.at,
|
|
25457
|
+
...input.state !== "ended" ? { bound: input.bound } : {},
|
|
25458
|
+
...detail !== void 0 ? { detail } : {}
|
|
25459
|
+
};
|
|
25460
|
+
if (current?.state === input.state) return { ok: true, liveState };
|
|
25461
|
+
return {
|
|
25462
|
+
ok: true,
|
|
25463
|
+
liveState,
|
|
25464
|
+
event: {
|
|
25465
|
+
type: "run_state",
|
|
25466
|
+
...liveState,
|
|
25467
|
+
...input.state === "ended" ? { cause: input.cause } : {},
|
|
25468
|
+
at: input.at
|
|
25469
|
+
}
|
|
25470
|
+
};
|
|
25471
|
+
}
|
|
25472
|
+
function foldRunLiveState(events, materialized = {}) {
|
|
25473
|
+
let liveState = materialized.liveState;
|
|
25474
|
+
let liveStateSeq = materialized.liveStateSeq ?? 0;
|
|
25475
|
+
let leaseEndsAt;
|
|
25476
|
+
for (const event of [...events].sort((left, right) => (left.seq ?? 0) - (right.seq ?? 0))) {
|
|
25477
|
+
if (event.type === "lease" && event.endsAt !== void 0) leaseEndsAt = event.endsAt;
|
|
25478
|
+
const seq = event.seq ?? 0;
|
|
25479
|
+
if (seq <= liveStateSeq) continue;
|
|
25480
|
+
if (event.type === "run_state" && RUN_LIVE_STATE_NAMES.includes(event.state) && event.since !== void 0) {
|
|
25481
|
+
liveState = {
|
|
25482
|
+
state: event.state,
|
|
25483
|
+
since: event.since,
|
|
25484
|
+
...event.bound !== void 0 ? { bound: event.bound } : {},
|
|
25485
|
+
...event.detail !== void 0 ? { detail: event.detail } : {}
|
|
25486
|
+
};
|
|
25487
|
+
liveStateSeq = seq;
|
|
25488
|
+
continue;
|
|
25489
|
+
}
|
|
25490
|
+
if (event.type === "tool_call" && liveState?.state === "working" && event.at !== void 0 && event.boundMs !== void 0) {
|
|
25491
|
+
liveState = { ...liveState, bound: event.at + event.boundMs, detail: "running a tool" };
|
|
25492
|
+
liveStateSeq = seq;
|
|
25493
|
+
continue;
|
|
25494
|
+
}
|
|
25495
|
+
if (event.type === "tool_result" && liveState?.state === "working" && leaseEndsAt !== void 0) {
|
|
25496
|
+
liveState = { ...liveState, bound: leaseEndsAt, detail: "model turn" };
|
|
25497
|
+
liveStateSeq = seq;
|
|
25498
|
+
}
|
|
25499
|
+
}
|
|
25500
|
+
return {
|
|
25501
|
+
...liveState !== void 0 ? { liveState } : {},
|
|
25502
|
+
...liveStateSeq > 0 ? { liveStateSeq } : {}
|
|
25503
|
+
};
|
|
25504
|
+
}
|
|
25505
|
+
var RUN_LIVE_STATE_NAMES, LIVE_STATE_DETAIL_MAX, TRANSITIONS, UNSAFE_DETAIL;
|
|
25506
|
+
var init_runLiveState = __esm({
|
|
25507
|
+
"../../src/core/runLiveState.ts"() {
|
|
25508
|
+
"use strict";
|
|
25509
|
+
init_redact();
|
|
25510
|
+
RUN_LIVE_STATE_NAMES = [
|
|
25511
|
+
"admitted",
|
|
25512
|
+
"waiting_deploy",
|
|
25513
|
+
"waiting_repository",
|
|
25514
|
+
"falling_back",
|
|
25515
|
+
"preparing",
|
|
25516
|
+
"working",
|
|
25517
|
+
"waiting_provider",
|
|
25518
|
+
"wrapping_up",
|
|
25519
|
+
"ended"
|
|
25520
|
+
];
|
|
25521
|
+
LIVE_STATE_DETAIL_MAX = 160;
|
|
25522
|
+
TRANSITIONS = {
|
|
25523
|
+
admitted: ["waiting_deploy", "waiting_repository", "falling_back", "preparing", "working", "wrapping_up", "ended"],
|
|
25524
|
+
waiting_deploy: ["waiting_repository", "falling_back", "preparing", "working", "wrapping_up", "ended"],
|
|
25525
|
+
waiting_repository: ["waiting_deploy", "falling_back", "preparing", "working", "wrapping_up", "ended"],
|
|
25526
|
+
falling_back: ["preparing", "working", "wrapping_up", "ended"],
|
|
25527
|
+
preparing: ["waiting_deploy", "waiting_repository", "falling_back", "working", "wrapping_up", "ended"],
|
|
25528
|
+
working: [
|
|
25529
|
+
"waiting_deploy",
|
|
25530
|
+
"waiting_repository",
|
|
25531
|
+
"falling_back",
|
|
25532
|
+
"preparing",
|
|
25533
|
+
"waiting_provider",
|
|
25534
|
+
"wrapping_up",
|
|
25535
|
+
"ended"
|
|
25536
|
+
],
|
|
25537
|
+
waiting_provider: ["working", "wrapping_up", "ended"],
|
|
25538
|
+
wrapping_up: ["ended"],
|
|
25539
|
+
ended: []
|
|
25540
|
+
};
|
|
25541
|
+
UNSAFE_DETAIL = /(?:\bimage-stale\b|\battach-failed\b|\bparked-provider\b|<\/?(?:html|body|head)\b|\bbad gateway\b)/i;
|
|
25542
|
+
}
|
|
25543
|
+
});
|
|
25544
|
+
|
|
25545
|
+
// ../../src/core/plane/decide.ts
|
|
25546
|
+
function liveStateWords(state) {
|
|
25547
|
+
switch (state) {
|
|
25548
|
+
case "admitted":
|
|
25549
|
+
return "admitted";
|
|
25550
|
+
case "waiting_deploy":
|
|
25551
|
+
return "waiting for the current deploy";
|
|
25552
|
+
case "waiting_repository":
|
|
25553
|
+
return "waiting for the repository container";
|
|
25554
|
+
case "falling_back":
|
|
25555
|
+
return "switching to a fallback workspace";
|
|
25556
|
+
case "preparing":
|
|
25557
|
+
return "preparing the workspace";
|
|
25558
|
+
case "working":
|
|
25559
|
+
return "working";
|
|
25560
|
+
case "waiting_provider":
|
|
25561
|
+
return "waiting for the model provider";
|
|
25562
|
+
case "wrapping_up":
|
|
25563
|
+
return "wrapping up";
|
|
25564
|
+
case "ended":
|
|
25565
|
+
return "ended";
|
|
25566
|
+
}
|
|
25567
|
+
}
|
|
25568
|
+
function causeOfClose(status3, restarting) {
|
|
25569
|
+
switch (status3) {
|
|
25570
|
+
case "completed":
|
|
25571
|
+
return "completed";
|
|
25572
|
+
case "failed":
|
|
25573
|
+
return "failed";
|
|
25574
|
+
case "stopped_soft":
|
|
25575
|
+
case "stopped_hard":
|
|
25576
|
+
case "stopped":
|
|
25577
|
+
return "stopped";
|
|
25578
|
+
default:
|
|
25579
|
+
return restarting === true ? "resident_replaced" : "lease_lapsed";
|
|
25580
|
+
}
|
|
25581
|
+
}
|
|
25582
|
+
function endingCauseWords(cause) {
|
|
25583
|
+
switch (cause) {
|
|
25584
|
+
case "completed":
|
|
25585
|
+
return "it completed";
|
|
25586
|
+
case "failed":
|
|
25587
|
+
return "it failed";
|
|
25588
|
+
case "stopped":
|
|
25589
|
+
return "it was stopped";
|
|
25590
|
+
case "withdrawn":
|
|
25591
|
+
return "its wait was withdrawn";
|
|
25592
|
+
case "refused":
|
|
25593
|
+
return "its admission was refused";
|
|
25594
|
+
case "lease_lapsed":
|
|
25595
|
+
return "its lease lapsed with no heartbeat";
|
|
25596
|
+
case "resident_replaced":
|
|
25597
|
+
return "the resident container running it was replaced";
|
|
25598
|
+
case "runner_gone":
|
|
25599
|
+
return "the runner instance driving it is gone";
|
|
25600
|
+
}
|
|
25601
|
+
}
|
|
25602
|
+
function isReissueSteerText(text) {
|
|
25603
|
+
return /^the model provider .+ is answering again — re-issue the held turn and continue$/.test(text.trim());
|
|
25604
|
+
}
|
|
25605
|
+
function waitingWords(waiting2) {
|
|
25606
|
+
if (waiting2.length === 0) return "its turn";
|
|
25607
|
+
return waiting2.map(
|
|
25608
|
+
(c) => c.kind === "thread_free" ? "the thread's live run" : c.kind === "deploy_settled" ? "the pending deploy" : c.kind === "seat" ? `a seat on ${c.resident}` : c.kind === "memory" ? `memory on ${c.resident}` : c.kind === "provider_up" ? `the ${c.provider} provider` : `the ${c.window} window`
|
|
25609
|
+
).join(", then ");
|
|
25610
|
+
}
|
|
25611
|
+
var PLANE_ENDING_CAUSES;
|
|
25612
|
+
var init_decide = __esm({
|
|
25613
|
+
"../../src/core/plane/decide.ts"() {
|
|
25614
|
+
"use strict";
|
|
25615
|
+
init_budgets();
|
|
25616
|
+
PLANE_ENDING_CAUSES = [
|
|
25617
|
+
"completed",
|
|
25618
|
+
"failed",
|
|
25619
|
+
"stopped",
|
|
25620
|
+
"withdrawn",
|
|
25621
|
+
"refused",
|
|
25622
|
+
"lease_lapsed",
|
|
25623
|
+
"resident_replaced",
|
|
25624
|
+
"runner_gone"
|
|
25625
|
+
];
|
|
25626
|
+
}
|
|
25627
|
+
});
|
|
25628
|
+
|
|
25403
25629
|
// ../../src/core/runEventLines.ts
|
|
25404
25630
|
function parseRunEventLines(text) {
|
|
25405
25631
|
const events = [];
|
|
@@ -25465,6 +25691,8 @@ function isRunEvent(v) {
|
|
|
25465
25691
|
return typeof o.url === "string" && typeof o.number === "number" && typeof o.created === "boolean";
|
|
25466
25692
|
case "pushed_head":
|
|
25467
25693
|
return typeof o.ref === "string" && typeof o.sha === "string" && (o.by === "push" || o.by === "salvage");
|
|
25694
|
+
case "run_state":
|
|
25695
|
+
return typeof o.state === "string" && LIVE_STATES.has(o.state) && typeof o.since === "number" && (o.state === "ended" ? typeof o.cause === "string" && ENDING_CAUSES.has(o.cause) : typeof o.bound === "number");
|
|
25468
25696
|
case "review_posted":
|
|
25469
25697
|
return typeof o.repo === "string" && typeof o.number === "number" && typeof o.head === "string";
|
|
25470
25698
|
case "ship_round":
|
|
@@ -25487,12 +25715,16 @@ function isRunEvent(v) {
|
|
|
25487
25715
|
return false;
|
|
25488
25716
|
}
|
|
25489
25717
|
}
|
|
25490
|
-
var NOTE_KINDS;
|
|
25718
|
+
var NOTE_KINDS, LIVE_STATES, ENDING_CAUSES;
|
|
25491
25719
|
var init_runEventLines = __esm({
|
|
25492
25720
|
"../../src/core/runEventLines.ts"() {
|
|
25493
25721
|
"use strict";
|
|
25494
25722
|
init_runEvents();
|
|
25723
|
+
init_runLiveState();
|
|
25724
|
+
init_decide();
|
|
25495
25725
|
NOTE_KINDS = new Set(RUN_NOTE_KINDS);
|
|
25726
|
+
LIVE_STATES = new Set(RUN_LIVE_STATE_NAMES);
|
|
25727
|
+
ENDING_CAUSES = new Set(PLANE_ENDING_CAUSES);
|
|
25496
25728
|
}
|
|
25497
25729
|
});
|
|
25498
25730
|
|
|
@@ -32237,6 +32469,8 @@ function assembleRunRecord(input) {
|
|
|
32237
32469
|
...seal?.replyNote !== void 0 ? { replyNote: seal.replyNote } : {},
|
|
32238
32470
|
...snap !== null ? { stepCount: snap.stepCount } : {},
|
|
32239
32471
|
status: input.status,
|
|
32472
|
+
...snap?.liveState !== void 0 ? { liveState: snap.liveState } : {},
|
|
32473
|
+
...snap?.liveStateSeq !== void 0 ? { liveStateSeq: snap.liveStateSeq } : {},
|
|
32240
32474
|
eventCount: Math.max(snap?.eventCount ?? atFinish.length, seal?.eventCount ?? 0),
|
|
32241
32475
|
storedEventCount: events.length,
|
|
32242
32476
|
truncated: false,
|
|
@@ -32420,43 +32654,6 @@ var init_record = __esm({
|
|
|
32420
32654
|
}
|
|
32421
32655
|
});
|
|
32422
32656
|
|
|
32423
|
-
// ../../src/core/plane/decide.ts
|
|
32424
|
-
function endingCauseWords(cause) {
|
|
32425
|
-
switch (cause) {
|
|
32426
|
-
case "completed":
|
|
32427
|
-
return "it completed";
|
|
32428
|
-
case "failed":
|
|
32429
|
-
return "it failed";
|
|
32430
|
-
case "stopped":
|
|
32431
|
-
return "it was stopped";
|
|
32432
|
-
case "withdrawn":
|
|
32433
|
-
return "its wait was withdrawn";
|
|
32434
|
-
case "refused":
|
|
32435
|
-
return "its admission was refused";
|
|
32436
|
-
case "lease_lapsed":
|
|
32437
|
-
return "its lease lapsed with no heartbeat";
|
|
32438
|
-
case "resident_replaced":
|
|
32439
|
-
return "the resident container running it was replaced";
|
|
32440
|
-
case "runner_gone":
|
|
32441
|
-
return "the runner instance driving it is gone";
|
|
32442
|
-
}
|
|
32443
|
-
}
|
|
32444
|
-
function isReissueSteerText(text) {
|
|
32445
|
-
return /^the model provider .+ is answering again — re-issue the held turn and continue$/.test(text.trim());
|
|
32446
|
-
}
|
|
32447
|
-
function waitingWords(waiting2) {
|
|
32448
|
-
if (waiting2.length === 0) return "its turn";
|
|
32449
|
-
return waiting2.map(
|
|
32450
|
-
(c) => c.kind === "thread_free" ? "the thread's live run" : c.kind === "deploy_settled" ? "the pending deploy" : c.kind === "seat" ? `a seat on ${c.resident}` : c.kind === "memory" ? `memory on ${c.resident}` : c.kind === "provider_up" ? `the ${c.provider} provider` : `the ${c.window} window`
|
|
32451
|
-
).join(", then ");
|
|
32452
|
-
}
|
|
32453
|
-
var init_decide = __esm({
|
|
32454
|
-
"../../src/core/plane/decide.ts"() {
|
|
32455
|
-
"use strict";
|
|
32456
|
-
init_budgets();
|
|
32457
|
-
}
|
|
32458
|
-
});
|
|
32459
|
-
|
|
32460
32657
|
// ../../src/core/runsService.ts
|
|
32461
32658
|
function runResource(view) {
|
|
32462
32659
|
return {
|
|
@@ -32493,6 +32690,8 @@ function ledgerView(row2, events) {
|
|
|
32493
32690
|
...m.repo !== void 0 ? { repo: m.repo } : {},
|
|
32494
32691
|
startedAt: row2.startedAt,
|
|
32495
32692
|
finished: false,
|
|
32693
|
+
...row2.liveState !== void 0 ? { liveState: row2.liveState } : {},
|
|
32694
|
+
...row2.liveStateSeq !== void 0 ? { liveStateSeq: row2.liveStateSeq } : {},
|
|
32496
32695
|
eventCount: events.length,
|
|
32497
32696
|
...activity !== void 0 ? { activity } : {},
|
|
32498
32697
|
...m.sourceUrl !== void 0 ? { sourceUrl: m.sourceUrl } : {},
|
|
@@ -32531,6 +32730,8 @@ function liveView(s) {
|
|
|
32531
32730
|
...s.stepCount !== void 0 ? { stepCount: s.stepCount } : {},
|
|
32532
32731
|
...s.schema !== void 0 ? { schema: s.schema } : {},
|
|
32533
32732
|
...s.status !== void 0 ? { status: s.status } : {},
|
|
32733
|
+
...s.liveState !== void 0 ? { liveState: s.liveState } : {},
|
|
32734
|
+
...s.liveStateSeq !== void 0 ? { liveStateSeq: s.liveStateSeq } : {},
|
|
32534
32735
|
eventCount: s.eventCount,
|
|
32535
32736
|
...s.stop ? { stop: s.stop } : {},
|
|
32536
32737
|
...s.activity !== void 0 ? { activity: s.activity } : {},
|
|
@@ -32628,7 +32829,7 @@ function createRunsService(deps) {
|
|
|
32628
32829
|
const prices = deps.prices ?? NO_PRICES;
|
|
32629
32830
|
const clock4 = deps.clock ?? systemClock;
|
|
32630
32831
|
const warn = deps.warn ?? ((m) => console.warn(m));
|
|
32631
|
-
const
|
|
32832
|
+
const describe13 = (err2) => err2 instanceof Error ? err2.message : String(err2);
|
|
32632
32833
|
let listing;
|
|
32633
32834
|
const liveRows = () => {
|
|
32634
32835
|
if (!ledger) return null;
|
|
@@ -32648,7 +32849,7 @@ function createRunsService(deps) {
|
|
|
32648
32849
|
try {
|
|
32649
32850
|
rows = await pending2;
|
|
32650
32851
|
} catch (err2) {
|
|
32651
|
-
warn(`[runs] run ledger list failed \u2014 showing this process's runs only: ${
|
|
32852
|
+
warn(`[runs] run ledger list failed \u2014 showing this process's runs only: ${describe13(err2)}`);
|
|
32652
32853
|
return [];
|
|
32653
32854
|
}
|
|
32654
32855
|
const foreign = rows.filter((row2) => !registry.getById(row2.runId));
|
|
@@ -32658,7 +32859,7 @@ function createRunsService(deps) {
|
|
|
32658
32859
|
try {
|
|
32659
32860
|
events = await ledger.readEvents(row2.runId);
|
|
32660
32861
|
} catch (err2) {
|
|
32661
|
-
warn(`[runs] run ledger events read failed for ${row2.runId}: ${
|
|
32862
|
+
warn(`[runs] run ledger events read failed for ${row2.runId}: ${describe13(err2)}`);
|
|
32662
32863
|
}
|
|
32663
32864
|
return ledgerView(row2, events);
|
|
32664
32865
|
})
|
|
@@ -32672,7 +32873,7 @@ function createRunsService(deps) {
|
|
|
32672
32873
|
if (!row2) return null;
|
|
32673
32874
|
return { row: row2, events: await ledger.readEvents(id) };
|
|
32674
32875
|
} catch (err2) {
|
|
32675
|
-
warn(`[runs] run ledger read failed for ${id}: ${
|
|
32876
|
+
warn(`[runs] run ledger read failed for ${id}: ${describe13(err2)}`);
|
|
32676
32877
|
return null;
|
|
32677
32878
|
}
|
|
32678
32879
|
};
|
|
@@ -32695,7 +32896,7 @@ function createRunsService(deps) {
|
|
|
32695
32896
|
activity: row2.state === "waiting" ? `queued at position ${row2.position} \u2014 waiting on ${waiting2}` : row2.state === "admitted" ? "admitted \u2014 starting" : "withdrawn"
|
|
32696
32897
|
};
|
|
32697
32898
|
} catch (err2) {
|
|
32698
|
-
warn(`[runs] plane queued read failed for ${id}: ${
|
|
32899
|
+
warn(`[runs] plane queued read failed for ${id}: ${describe13(err2)}`);
|
|
32699
32900
|
return null;
|
|
32700
32901
|
}
|
|
32701
32902
|
};
|
|
@@ -32713,7 +32914,7 @@ function createRunsService(deps) {
|
|
|
32713
32914
|
row2 = await storeSummary(id);
|
|
32714
32915
|
} catch (err2) {
|
|
32715
32916
|
warn(
|
|
32716
|
-
`[runs] history store read failed for ${id} \u2014 serving the registry row without its record: ${
|
|
32917
|
+
`[runs] history store read failed for ${id} \u2014 serving the registry row without its record: ${describe13(err2)}`
|
|
32717
32918
|
);
|
|
32718
32919
|
return {};
|
|
32719
32920
|
}
|
|
@@ -32758,12 +32959,12 @@ function createRunsService(deps) {
|
|
|
32758
32959
|
if (marked.ok) runnerStopped = true;
|
|
32759
32960
|
else warn(`[runs] the runner's stop mark was refused for ${id} (${marked.reason})`);
|
|
32760
32961
|
} catch (err2) {
|
|
32761
|
-
warn(`[runs] the runner's stop mark failed for ${id}: ${
|
|
32962
|
+
warn(`[runs] the runner's stop mark failed for ${id}: ${describe13(err2)}`);
|
|
32762
32963
|
}
|
|
32763
32964
|
try {
|
|
32764
32965
|
unitRows = await units.listUnits(instanceId);
|
|
32765
32966
|
} catch (err2) {
|
|
32766
|
-
warn(`[runs] unit rows unavailable for the hard stop of ${id}: ${
|
|
32967
|
+
warn(`[runs] unit rows unavailable for the hard stop of ${id}: ${describe13(err2)}`);
|
|
32767
32968
|
}
|
|
32768
32969
|
}
|
|
32769
32970
|
registry.publish(id, { type: "answer", text: hostedSealAnswer(unitRows, runnerStopped), at: clock4() });
|
|
@@ -32809,7 +33010,7 @@ function createRunsService(deps) {
|
|
|
32809
33010
|
if (!done.ok) warn(`[runs] run ledger finish refused for ${id} (${done.reason ?? "unknown"})`);
|
|
32810
33011
|
}
|
|
32811
33012
|
} catch (err2) {
|
|
32812
|
-
warn(`[runs] run ledger finish failed for ${id}: ${
|
|
33013
|
+
warn(`[runs] run ledger finish failed for ${id}: ${describe13(err2)}`);
|
|
32813
33014
|
}
|
|
32814
33015
|
}
|
|
32815
33016
|
return { ok: true, value: { id, mode: "hard", state: "stopping" } };
|
|
@@ -32988,7 +33189,7 @@ function createRunsService(deps) {
|
|
|
32988
33189
|
const r = await ledger.requestStop(id, mode);
|
|
32989
33190
|
if (r.ok) return { ok: true, value: { id, mode, state: "stopping" } };
|
|
32990
33191
|
} catch (err2) {
|
|
32991
|
-
warn(`[runs] run ledger stop failed for ${id}: ${
|
|
33192
|
+
warn(`[runs] run ledger stop failed for ${id}: ${describe13(err2)}`);
|
|
32992
33193
|
}
|
|
32993
33194
|
}
|
|
32994
33195
|
if (await storeSummary(id)) return conflict;
|
|
@@ -32998,7 +33199,7 @@ function createRunsService(deps) {
|
|
|
32998
33199
|
if (r.withdrawn) return { ok: true, value: { id, mode, state: "withdrawn" } };
|
|
32999
33200
|
if (await ledger.planeQueued(id) !== null) return conflict;
|
|
33000
33201
|
} catch (err2) {
|
|
33001
|
-
warn(`[runs] plane withdraw failed for ${id}: ${
|
|
33202
|
+
warn(`[runs] plane withdraw failed for ${id}: ${describe13(err2)}`);
|
|
33002
33203
|
}
|
|
33003
33204
|
}
|
|
33004
33205
|
return notFound;
|
|
@@ -34929,6 +35130,11 @@ var init_runLedgerWorker = __esm({
|
|
|
34929
35130
|
if (events.length === 0) return { ok: true };
|
|
34930
35131
|
return this.fenceResult(await this.post("/runs/append", { storeKey: this.opts.storeKey, runId: runId3, gen, events }));
|
|
34931
35132
|
}
|
|
35133
|
+
async assignLiveState(runId3, gen, assignment) {
|
|
35134
|
+
this.checkIds(runId3, gen);
|
|
35135
|
+
const r = await this.post("/runs/live-state", { storeKey: this.opts.storeKey, runId: runId3, gen, assignment });
|
|
35136
|
+
return r.data;
|
|
35137
|
+
}
|
|
34932
35138
|
async setState(runId3, gen, state) {
|
|
34933
35139
|
this.checkIds(runId3, gen);
|
|
34934
35140
|
return this.fenceResult(await this.post("/runs/state", { storeKey: this.opts.storeKey, runId: runId3, gen, state }));
|
|
@@ -35757,6 +35963,9 @@ function activityLine(e) {
|
|
|
35757
35963
|
case "lease":
|
|
35758
35964
|
return "lease started";
|
|
35759
35965
|
// the harness's clocks: head material the run loop keeps off the card — never arrives here
|
|
35966
|
+
case "run_state":
|
|
35967
|
+
return "";
|
|
35968
|
+
// Existing renderers stay until the surface cutover to the shared wording table.
|
|
35760
35969
|
case "skill_use":
|
|
35761
35970
|
return `\u{1F4DA} skill ${e.skill} loaded`;
|
|
35762
35971
|
case "artifact":
|
|
@@ -36700,7 +36909,7 @@ async function attachRoundWorkspace(input) {
|
|
|
36700
36909
|
...input.round.stopSignal !== void 0 ? { stopSignal: input.round.stopSignal } : {},
|
|
36701
36910
|
...input.round.remainingMs !== void 0 ? { remainingMs: input.round.remainingMs } : {},
|
|
36702
36911
|
...input.round.requester !== void 0 ? { requester: input.round.requester } : {},
|
|
36703
|
-
...input.round.
|
|
36912
|
+
...input.round.onLiveStateObservation !== void 0 ? { onLiveStateObservation: input.round.onLiveStateObservation } : {}
|
|
36704
36913
|
},
|
|
36705
36914
|
input.span
|
|
36706
36915
|
);
|
|
@@ -38586,6 +38795,8 @@ function summaryOf(run2, now) {
|
|
|
38586
38795
|
...m?.hosted ? { hosted: true } : {},
|
|
38587
38796
|
...run2.instanceId !== void 0 ? { instanceId: run2.instanceId } : {},
|
|
38588
38797
|
...run2.pipeline !== void 0 ? { pipeline: run2.pipeline } : {},
|
|
38798
|
+
...run2.liveState !== void 0 ? { liveState: run2.liveState } : {},
|
|
38799
|
+
...run2.liveStateSeq !== void 0 ? { liveStateSeq: run2.liveStateSeq } : {},
|
|
38589
38800
|
finished: run2.finished,
|
|
38590
38801
|
startedAt: run2.startedAt,
|
|
38591
38802
|
...run2.finishedAt !== void 0 ? { finishedAt: run2.finishedAt } : {},
|
|
@@ -38621,7 +38832,9 @@ function snapshotOf(run2) {
|
|
|
38621
38832
|
...run2.meta?.receivedAt !== void 0 ? { receivedAt: run2.meta.receivedAt } : {},
|
|
38622
38833
|
eventCount: run2.eventCount,
|
|
38623
38834
|
stepCount: run2.stepCount,
|
|
38624
|
-
truncated: run2.eventCount > run2.backlog.length
|
|
38835
|
+
truncated: run2.eventCount > run2.backlog.length,
|
|
38836
|
+
...run2.liveState !== void 0 ? { liveState: run2.liveState } : {},
|
|
38837
|
+
...run2.liveStateSeq !== void 0 ? { liveStateSeq: run2.liveStateSeq } : {}
|
|
38625
38838
|
};
|
|
38626
38839
|
}
|
|
38627
38840
|
function sealResultOf(run2) {
|
|
@@ -38705,6 +38918,7 @@ var init_runRegistry = __esm({
|
|
|
38705
38918
|
init_projections();
|
|
38706
38919
|
init_indexFeed();
|
|
38707
38920
|
init_runPace();
|
|
38921
|
+
init_runLiveState();
|
|
38708
38922
|
PACE_RING_CAP = 1200;
|
|
38709
38923
|
UNSEALED_HOLD_MS = 15 * 6e4;
|
|
38710
38924
|
RUN_LABEL_MAX2 = 200;
|
|
@@ -38778,6 +38992,10 @@ var init_runRegistry = __esm({
|
|
|
38778
38992
|
if (!isSpanRecord(event)) run2.stepCount++;
|
|
38779
38993
|
appendToBacklog(run2, this.bounds, { ...event, seq });
|
|
38780
38994
|
}
|
|
38995
|
+
const replayedLiveState = foldRunLiveState(opts.replay ?? [], opts.liveState);
|
|
38996
|
+
const folded = opts.resetLiveState ? { liveStateSeq: replayedLiveState.liveStateSeq } : replayedLiveState;
|
|
38997
|
+
run2.liveState = folded.liveState;
|
|
38998
|
+
run2.liveStateSeq = folded.liveStateSeq;
|
|
38781
38999
|
this.index.notify({ type: "upsert", run: summaryOf(run2, this.now()) });
|
|
38782
39000
|
return { id, token: token2, control: run2.control, ...stored !== void 0 ? { label: stored } : {} };
|
|
38783
39001
|
}
|
|
@@ -38866,6 +39084,32 @@ var init_runRegistry = __esm({
|
|
|
38866
39084
|
}
|
|
38867
39085
|
if (!span) this.index.notify({ type: "upsert", run: summaryOf(run2, this.now()) });
|
|
38868
39086
|
}
|
|
39087
|
+
/** Apply an assignment only after its durable transaction acknowledged. The
|
|
39088
|
+
* boundary keeps the ledger-assigned stream sequence; subscribers cannot
|
|
39089
|
+
* observe either half before this call. */
|
|
39090
|
+
commitLiveState(id, committed) {
|
|
39091
|
+
const run2 = this.runs.get(id);
|
|
39092
|
+
if (!run2 || run2.finished || run2.sealedAt !== void 0) return false;
|
|
39093
|
+
const event = committed.event;
|
|
39094
|
+
if (event !== void 0) {
|
|
39095
|
+
const seq = event.seq;
|
|
39096
|
+
if (seq === void 0 || seq !== run2.eventCount + 1) return false;
|
|
39097
|
+
run2.eventCount = seq;
|
|
39098
|
+
run2.stepCount++;
|
|
39099
|
+
const stamped = { ...event, seq };
|
|
39100
|
+
appendToBacklog(run2, this.bounds, stamped);
|
|
39101
|
+
for (const sub of run2.subscribers) {
|
|
39102
|
+
try {
|
|
39103
|
+
sub.onEvent(stamped, seq);
|
|
39104
|
+
} catch {
|
|
39105
|
+
}
|
|
39106
|
+
}
|
|
39107
|
+
}
|
|
39108
|
+
run2.liveState = committed.liveState;
|
|
39109
|
+
run2.liveStateSeq = committed.liveStateSeq;
|
|
39110
|
+
this.index.notify({ type: "upsert", run: summaryOf(run2, this.now()) });
|
|
39111
|
+
return true;
|
|
39112
|
+
}
|
|
38869
39113
|
/** Mark a run finished — the agent stopped: stamp `finishedAt`, send every
|
|
38870
39114
|
* attached subscriber the `finished` frame WITHOUT detaching it (span records
|
|
38871
39115
|
* still flow until the seal), and upsert the index. `status` is the terminal
|
|
@@ -41867,6 +42111,47 @@ var init_customInstructions = __esm({
|
|
|
41867
42111
|
}
|
|
41868
42112
|
});
|
|
41869
42113
|
|
|
42114
|
+
// ../../src/core/runEventLane.ts
|
|
42115
|
+
var RunEventLane;
|
|
42116
|
+
var init_runEventLane = __esm({
|
|
42117
|
+
"../../src/core/runEventLane.ts"() {
|
|
42118
|
+
"use strict";
|
|
42119
|
+
RunEventLane = class {
|
|
42120
|
+
constructor(publishNow) {
|
|
42121
|
+
this.publishNow = publishNow;
|
|
42122
|
+
}
|
|
42123
|
+
publishNow;
|
|
42124
|
+
tail;
|
|
42125
|
+
/** Publish synchronously while idle; otherwise preserve order behind the active write. */
|
|
42126
|
+
publish(event) {
|
|
42127
|
+
if (!this.tail) {
|
|
42128
|
+
this.publishNow(event);
|
|
42129
|
+
return;
|
|
42130
|
+
}
|
|
42131
|
+
void this.write(() => this.publishNow(event));
|
|
42132
|
+
}
|
|
42133
|
+
/** Queue one operation after every event or operation already accepted. */
|
|
42134
|
+
write(work) {
|
|
42135
|
+
const previous = this.tail ?? Promise.resolve();
|
|
42136
|
+
const next = previous.then(work);
|
|
42137
|
+
const settled = next.then(
|
|
42138
|
+
() => void 0,
|
|
42139
|
+
() => void 0
|
|
42140
|
+
);
|
|
42141
|
+
this.tail = settled;
|
|
42142
|
+
void settled.then(() => {
|
|
42143
|
+
if (this.tail === settled) this.tail = void 0;
|
|
42144
|
+
});
|
|
42145
|
+
return next;
|
|
42146
|
+
}
|
|
42147
|
+
/** Wait until every operation accepted so far has settled. */
|
|
42148
|
+
async drain() {
|
|
42149
|
+
await this.tail;
|
|
42150
|
+
}
|
|
42151
|
+
};
|
|
42152
|
+
}
|
|
42153
|
+
});
|
|
42154
|
+
|
|
41870
42155
|
// ../../src/core/statusCoalescer.ts
|
|
41871
42156
|
function coalesceStatus(inner, minIntervalMs, now = Date.now, schedule = setTimeout) {
|
|
41872
42157
|
let lastSentAt = -Infinity;
|
|
@@ -42039,22 +42324,24 @@ async function registerRun(deps, ctx) {
|
|
|
42039
42324
|
{
|
|
42040
42325
|
id: runId3,
|
|
42041
42326
|
startedAt,
|
|
42042
|
-
...
|
|
42327
|
+
...carriedRow?.liveState !== void 0 ? { liveState: { liveState: carriedRow.liveState, liveStateSeq: carriedRow.liveStateSeq } } : {},
|
|
42328
|
+
...resume ? { replay: resume.events } : ctx.restartCarried ? { replay: ctx.restartCarried.events, token: ctx.restartCarried.token, resetLiveState: true } : {}
|
|
42043
42329
|
}
|
|
42044
42330
|
);
|
|
42331
|
+
const events = new RunEventLane((event) => registry.publish(run2.id, event));
|
|
42045
42332
|
if (ctx.restartCarried)
|
|
42046
|
-
|
|
42333
|
+
events.publish({ type: "run_note", kind: "resumed", summary: ctx.restartCarried.note, at: clock4() });
|
|
42047
42334
|
const liveUrl = liveViewLink(run2.id, run2.token);
|
|
42048
42335
|
shell.setLink(liveUrl ? { url: liveUrl, label: "Live run" } : void 0);
|
|
42049
42336
|
if (liveUrl) admitted.runLink = liveUrl;
|
|
42050
42337
|
io.runStarted?.({ id: run2.id });
|
|
42051
|
-
trace.bindRun(run2.id, (
|
|
42338
|
+
trace.bindRun(run2.id, (event) => events.publish(event));
|
|
42052
42339
|
const publishText = (type, text, source3, raw) => {
|
|
42053
42340
|
const redacted = redactSecrets(text);
|
|
42054
42341
|
const body = { text: redacted, ...source3 ? { source: source3 } : {}, at: clock4() };
|
|
42055
42342
|
const event = type === "input" ? { type, messageId: messageIdOf(msg, run2.id), ...body } : { type, ...body };
|
|
42056
42343
|
const withRaw = raw !== void 0 ? { ...event, raw: redactSecrets(raw) } : event;
|
|
42057
|
-
|
|
42344
|
+
events.publish(utf8ByteLength(JSON.stringify(withRaw)) <= MAX_EVENT_BYTES ? withRaw : event);
|
|
42058
42345
|
console.log(`[event] ${msg.threadKey} type=${type} bytes=${utf8ByteLength(redacted)}`);
|
|
42059
42346
|
};
|
|
42060
42347
|
const humanize = isMrkdwnChannel(msg.channelId);
|
|
@@ -42074,7 +42361,7 @@ async function registerRun(deps, ctx) {
|
|
|
42074
42361
|
if (!resume && ctx.references) {
|
|
42075
42362
|
const { conversations, blocks } = ctx.references;
|
|
42076
42363
|
conversations.forEach((rc, i) => {
|
|
42077
|
-
|
|
42364
|
+
events.publish({
|
|
42078
42365
|
type: "reference",
|
|
42079
42366
|
url: rc.permalink,
|
|
42080
42367
|
channelId: rc.ref.channelId,
|
|
@@ -42086,7 +42373,7 @@ async function registerRun(deps, ctx) {
|
|
|
42086
42373
|
console.log(`[event] ${msg.threadKey} type=reference channel=${rc.ref.channelId} messages=${rc.messages.length}`);
|
|
42087
42374
|
});
|
|
42088
42375
|
}
|
|
42089
|
-
const publishMeta = (repoCtx2) =>
|
|
42376
|
+
const publishMeta = (repoCtx2) => events.publish({
|
|
42090
42377
|
type: "run_meta",
|
|
42091
42378
|
agent: agent.name,
|
|
42092
42379
|
agentSource,
|
|
@@ -42118,7 +42405,7 @@ async function registerRun(deps, ctx) {
|
|
|
42118
42405
|
if (!resume)
|
|
42119
42406
|
for (const d of cardDecisions ?? []) {
|
|
42120
42407
|
if (d.outcome !== "degraded") continue;
|
|
42121
|
-
|
|
42408
|
+
events.publish({
|
|
42122
42409
|
type: "run_note",
|
|
42123
42410
|
kind: "control_degraded",
|
|
42124
42411
|
summary: oneLine(
|
|
@@ -42132,12 +42419,12 @@ async function registerRun(deps, ctx) {
|
|
|
42132
42419
|
at: clock4()
|
|
42133
42420
|
});
|
|
42134
42421
|
}
|
|
42135
|
-
if (!resume && route2)
|
|
42136
|
-
if (!resume && ctx.operator)
|
|
42422
|
+
if (!resume && route2) events.publish({ type: "route", ...route2, at: clock4() });
|
|
42423
|
+
if (!resume && ctx.operator) events.publish({ type: "operator", ...ctx.operator, at: clock4() });
|
|
42137
42424
|
if (!resume && deps.config.config.runHistory?.includeContext !== false) {
|
|
42138
42425
|
for (const text of contextMessageTexts(seedTurns ?? history, humanize)) publishText("context", text);
|
|
42139
42426
|
}
|
|
42140
|
-
return { run: run2, runId: runId3, channelVisibility, liveUrl, publishText, publishMeta };
|
|
42427
|
+
return { run: run2, runId: runId3, channelVisibility, liveUrl, events, publishText, publishMeta };
|
|
42141
42428
|
}
|
|
42142
42429
|
async function reserveRun(deps, ctx) {
|
|
42143
42430
|
const {
|
|
@@ -42213,7 +42500,7 @@ async function reserveRun(deps, ctx) {
|
|
|
42213
42500
|
}
|
|
42214
42501
|
async function attachRound(deps, ctx) {
|
|
42215
42502
|
const { threadKey, agent, profile, repoCtx, root, clock: clock4, reattach, stopSignal, remainingMs, requester } = ctx;
|
|
42216
|
-
const {
|
|
42503
|
+
const { onLiveStateObservation } = ctx;
|
|
42217
42504
|
const ownPr = agent.name === "review" ? void 0 : ownPrOf(repoCtx);
|
|
42218
42505
|
return root.span("dispatch.workspace.attach", async (span) => {
|
|
42219
42506
|
const graft = (steps, residentTotalMs) => graftResidentSteps(steps, {
|
|
@@ -42249,7 +42536,7 @@ async function attachRound(deps, ctx) {
|
|
|
42249
42536
|
...stopSignal !== void 0 ? { stopSignal } : {},
|
|
42250
42537
|
...remainingMs !== void 0 ? { remainingMs } : {},
|
|
42251
42538
|
...requester !== void 0 ? { requester } : {},
|
|
42252
|
-
...
|
|
42539
|
+
...onLiveStateObservation !== void 0 ? { onLiveStateObservation } : {}
|
|
42253
42540
|
},
|
|
42254
42541
|
logKey: threadKey,
|
|
42255
42542
|
span
|
|
@@ -42306,10 +42593,10 @@ async function attachWorkspace(deps, ctx) {
|
|
|
42306
42593
|
clock: clock4,
|
|
42307
42594
|
// The requester whose binding names the author pair (record 0062).
|
|
42308
42595
|
requester: msg.userId,
|
|
42309
|
-
|
|
42310
|
-
|
|
42311
|
-
|
|
42312
|
-
|
|
42596
|
+
onLiveStateObservation: async (observation) => {
|
|
42597
|
+
await ctx.onLiveStateObservation?.(observation);
|
|
42598
|
+
shell.setSetupLabel(`${liveStateWords(observation.state)}\u2026`);
|
|
42599
|
+
},
|
|
42313
42600
|
...reattach !== void 0 ? { reattach } : {},
|
|
42314
42601
|
...stopSignal !== void 0 ? { stopSignal } : {},
|
|
42315
42602
|
...remainingMs !== void 0 ? { remainingMs } : {}
|
|
@@ -42476,7 +42763,6 @@ var init_provision = __esm({
|
|
|
42476
42763
|
init_factory();
|
|
42477
42764
|
init_executor();
|
|
42478
42765
|
init_residentTrace();
|
|
42479
|
-
init_displayNames();
|
|
42480
42766
|
init_resident();
|
|
42481
42767
|
init_memory();
|
|
42482
42768
|
init_budgets();
|
|
@@ -42489,12 +42775,14 @@ var init_provision = __esm({
|
|
|
42489
42775
|
init_reviewRound();
|
|
42490
42776
|
init_repoContext();
|
|
42491
42777
|
init_runEvents();
|
|
42778
|
+
init_runEventLane();
|
|
42492
42779
|
init_redact();
|
|
42493
42780
|
init_runRecord();
|
|
42494
42781
|
init_inboxMessage();
|
|
42495
42782
|
init_statusCardFrame();
|
|
42496
42783
|
init_statusCoalescer();
|
|
42497
42784
|
init_types5();
|
|
42785
|
+
init_decide();
|
|
42498
42786
|
init_record();
|
|
42499
42787
|
init_reply();
|
|
42500
42788
|
init_refusal();
|
|
@@ -48715,6 +49003,11 @@ var init_mirror = __esm({
|
|
|
48715
49003
|
seedEchoPending = false;
|
|
48716
49004
|
mirroredTail;
|
|
48717
49005
|
iteration = 0;
|
|
49006
|
+
/** The loop counters on the last transcript-bearing step. A cursor-only
|
|
49007
|
+
* checkpoint repeats them so a post-loop turn cannot become part of the
|
|
49008
|
+
* resumable model loop merely by consuming a control row. */
|
|
49009
|
+
lastTurn = 0;
|
|
49010
|
+
lastIteration = 0;
|
|
48718
49011
|
/** The rows written since the mirror started, and the compaction entries
|
|
48719
49012
|
* among them by position — kept whether or not the ledger is wired, so
|
|
48720
49013
|
* the harness holds this generation's copy of the record it wrote
|
|
@@ -48824,6 +49117,8 @@ var init_mirror = __esm({
|
|
|
48824
49117
|
inboxConsumedSeq: this.inboxConsumedSeq,
|
|
48825
49118
|
...this.inboxDeferred()
|
|
48826
49119
|
};
|
|
49120
|
+
this.lastTurn = report2.turn;
|
|
49121
|
+
this.lastIteration = report2.iteration;
|
|
48827
49122
|
this.idx += turns.length;
|
|
48828
49123
|
this.lastAssistantIdx = this.idx - 1;
|
|
48829
49124
|
this.rows.push(...turns);
|
|
@@ -48852,6 +49147,8 @@ var init_mirror = __esm({
|
|
|
48852
49147
|
inboxConsumedSeq: this.inboxConsumedSeq,
|
|
48853
49148
|
...this.inboxDeferred()
|
|
48854
49149
|
};
|
|
49150
|
+
this.lastTurn = report2.turn;
|
|
49151
|
+
this.lastIteration = report2.iteration;
|
|
48855
49152
|
this.idx += turns.length + 1;
|
|
48856
49153
|
this.rows.push(...turns);
|
|
48857
49154
|
this.compactionRows.push({ before: this.rows.length, entry });
|
|
@@ -48859,6 +49156,22 @@ var init_mirror = __esm({
|
|
|
48859
49156
|
await this.deps.onStep(report2);
|
|
48860
49157
|
return true;
|
|
48861
49158
|
}
|
|
49159
|
+
/** Persist only the inbox cursor and its deferred exceptions. Post-loop
|
|
49160
|
+
* turns deliberately stay out of the resumable transcript, but a control
|
|
49161
|
+
* row they consume must survive a bot restart just as a loop step does. */
|
|
49162
|
+
async checkpointInbox() {
|
|
49163
|
+
if (!this.deps.onStep) return;
|
|
49164
|
+
await this.deps.onStep({
|
|
49165
|
+
turns: [],
|
|
49166
|
+
firstIdx: this.idx,
|
|
49167
|
+
inFlight: [],
|
|
49168
|
+
turn: this.lastTurn,
|
|
49169
|
+
iteration: this.lastIteration,
|
|
49170
|
+
remainingMs: Math.max(0, this.deps.remainingMs()),
|
|
49171
|
+
inboxConsumedSeq: this.inboxConsumedSeq,
|
|
49172
|
+
...this.inboxDeferred()
|
|
49173
|
+
});
|
|
49174
|
+
}
|
|
48862
49175
|
};
|
|
48863
49176
|
}
|
|
48864
49177
|
});
|
|
@@ -50388,6 +50701,7 @@ async function runPiHarnessOpen(deps, run2) {
|
|
|
50388
50701
|
let parkSettled = false;
|
|
50389
50702
|
let pendingReissue = [];
|
|
50390
50703
|
let reissueInFlight;
|
|
50704
|
+
let reissueInFlightRows = [];
|
|
50391
50705
|
let reissues = 0;
|
|
50392
50706
|
let providerRetryReady = false;
|
|
50393
50707
|
let providerRetryWait;
|
|
@@ -50400,20 +50714,21 @@ async function runPiHarnessOpen(deps, run2) {
|
|
|
50400
50714
|
providerRetryWait = void 0;
|
|
50401
50715
|
providerRetryGeneration += 1;
|
|
50402
50716
|
pendingReissue = [];
|
|
50717
|
+
reissueInFlightRows = [];
|
|
50403
50718
|
};
|
|
50404
50719
|
const maybeReissue = () => {
|
|
50405
50720
|
if (heldTurn === void 0 || !parkSettled || reissueInFlight !== void 0 || retryInFlight !== void 0)
|
|
50406
50721
|
return;
|
|
50407
50722
|
if (pendingReissue.length === 0) return;
|
|
50408
50723
|
if (loopEnded || hardStopped || writeUp !== void 0 || finaleAborted) return;
|
|
50409
|
-
|
|
50724
|
+
reissueInFlightRows = pendingReissue.splice(0);
|
|
50410
50725
|
reissues += 1;
|
|
50411
50726
|
const id = reissues === 1 ? `${ids.prompt}:reissue` : `${ids.prompt}:reissue:${reissues}`;
|
|
50412
50727
|
reissueInFlight = id;
|
|
50413
50728
|
unechoed.push({
|
|
50414
50729
|
message: REISSUE_PROMPT,
|
|
50415
|
-
seq: Math.max(0, ...
|
|
50416
|
-
inputs:
|
|
50730
|
+
seq: Math.max(0, ...reissueInFlightRows.map((i) => i.ledgerSeq ?? 0)),
|
|
50731
|
+
inputs: reissueInFlightRows
|
|
50417
50732
|
});
|
|
50418
50733
|
sends.send({ id, type: "prompt", message: REISSUE_PROMPT });
|
|
50419
50734
|
};
|
|
@@ -50674,16 +50989,29 @@ ${stagedLine}` : prompt;
|
|
|
50674
50989
|
save();
|
|
50675
50990
|
}
|
|
50676
50991
|
if (reissueInFlight !== void 0 && r.id === reissueInFlight) {
|
|
50677
|
-
reissueInFlight = void 0;
|
|
50678
50992
|
if (r.success === false) {
|
|
50993
|
+
reissueInFlight = void 0;
|
|
50679
50994
|
parkSettled = false;
|
|
50680
50995
|
const at = unechoed.findIndex((u) => u.message === REISSUE_PROMPT);
|
|
50681
|
-
if (at >= 0)
|
|
50996
|
+
if (at >= 0) unechoed.splice(at, 1);
|
|
50997
|
+
pendingReissue.push(...reissueInFlightRows);
|
|
50998
|
+
reissueInFlightRows = [];
|
|
50682
50999
|
note(
|
|
50683
51000
|
"harness_error",
|
|
50684
51001
|
`the reissue prompt was refused (${String(r.error ?? "no reason")}); the turn stays held for the next settle`
|
|
50685
51002
|
);
|
|
50686
51003
|
} else {
|
|
51004
|
+
drainFollowUps2();
|
|
51005
|
+
await steers;
|
|
51006
|
+
const at = unechoed.findIndex((u) => u.message === REISSUE_PROMPT);
|
|
51007
|
+
if (at >= 0) unechoed.splice(at, 1);
|
|
51008
|
+
mirror.inboxConsumedSeq = Math.max(
|
|
51009
|
+
mirror.inboxConsumedSeq,
|
|
51010
|
+
...reissueInFlightRows.map((item) => item.ledgerSeq ?? 0),
|
|
51011
|
+
...pendingReissue.map((item) => item.ledgerSeq ?? 0)
|
|
51012
|
+
);
|
|
51013
|
+
await mirror.checkpointInbox();
|
|
51014
|
+
reissueInFlight = void 0;
|
|
50687
51015
|
clearProviderHold();
|
|
50688
51016
|
}
|
|
50689
51017
|
}
|
|
@@ -50692,7 +51020,16 @@ ${stagedLine}` : prompt;
|
|
|
50692
51020
|
if (r.success === false) {
|
|
50693
51021
|
parkSettled = false;
|
|
50694
51022
|
note("harness_error", "the model retry prompt was refused; the transport failure remains held");
|
|
50695
|
-
} else
|
|
51023
|
+
} else {
|
|
51024
|
+
drainFollowUps2();
|
|
51025
|
+
await steers;
|
|
51026
|
+
mirror.inboxConsumedSeq = Math.max(
|
|
51027
|
+
mirror.inboxConsumedSeq,
|
|
51028
|
+
...pendingReissue.map((item) => item.ledgerSeq ?? 0)
|
|
51029
|
+
);
|
|
51030
|
+
await mirror.checkpointInbox();
|
|
51031
|
+
clearProviderHold();
|
|
51032
|
+
}
|
|
50696
51033
|
}
|
|
50697
51034
|
if (r.id === ids.prompt) {
|
|
50698
51035
|
catchingUp = false;
|
|
@@ -51049,10 +51386,13 @@ ${stagedLine}` : prompt;
|
|
|
51049
51386
|
`the follow-up turn's reissue prompt was refused (${String(obs.response.error ?? "no reason")}); the turn stays held for the next settle`
|
|
51050
51387
|
);
|
|
51051
51388
|
} else {
|
|
51389
|
+
drainTurnReissues();
|
|
51052
51390
|
mirror.inboxConsumedSeq = Math.max(
|
|
51053
51391
|
mirror.inboxConsumedSeq,
|
|
51054
|
-
...turnReissueInFlightRows.map((item) => item.ledgerSeq ?? 0)
|
|
51392
|
+
...turnReissueInFlightRows.map((item) => item.ledgerSeq ?? 0),
|
|
51393
|
+
...turnReissueRows.map((item) => item.ledgerSeq ?? 0)
|
|
51055
51394
|
);
|
|
51395
|
+
await mirror.checkpointInbox();
|
|
51056
51396
|
clearTurnProviderHold();
|
|
51057
51397
|
}
|
|
51058
51398
|
}
|
|
@@ -51067,6 +51407,7 @@ ${stagedLine}` : prompt;
|
|
|
51067
51407
|
mirror.inboxConsumedSeq,
|
|
51068
51408
|
...turnReissueRows.map((item) => item.ledgerSeq ?? 0)
|
|
51069
51409
|
);
|
|
51410
|
+
await mirror.checkpointInbox();
|
|
51070
51411
|
clearTurnProviderHold();
|
|
51071
51412
|
}
|
|
51072
51413
|
}
|
|
@@ -52399,6 +52740,7 @@ async function runLoop(deps, ctx) {
|
|
|
52399
52740
|
coordinator,
|
|
52400
52741
|
seed
|
|
52401
52742
|
} = ctx;
|
|
52743
|
+
const events = ctx.events ?? new RunEventLane((event) => registry.publish(run2.id, event));
|
|
52402
52744
|
const agent = budgetedAgent(ctx.agent, profile);
|
|
52403
52745
|
const { round: round2 } = ctx;
|
|
52404
52746
|
let { executor } = round2.selection;
|
|
@@ -52472,13 +52814,11 @@ async function runLoop(deps, ctx) {
|
|
|
52472
52814
|
const pushes = trackPushedBranch(typeof restored.pushedBranch === "string" ? restored.pushedBranch : void 0);
|
|
52473
52815
|
let budgetEnded = false;
|
|
52474
52816
|
let recordedPushedBranch;
|
|
52475
|
-
|
|
52817
|
+
let modelBudgetEndsAt;
|
|
52818
|
+
const publishEvent = (e, startsRunBudget) => {
|
|
52476
52819
|
registry.publish(run2.id, e);
|
|
52477
52820
|
if (isSpanRecord(e)) return;
|
|
52478
|
-
if (
|
|
52479
|
-
run2.control.startLease(() => e.endsAt - clock4());
|
|
52480
|
-
return;
|
|
52481
|
-
}
|
|
52821
|
+
if (startsRunBudget) return;
|
|
52482
52822
|
if (e.type === "tool_call") toolCalls++;
|
|
52483
52823
|
if (e.type === "run_note" && e.kind === "time_budget_exhausted") budgetEnded = true;
|
|
52484
52824
|
if (isCodingPrRun) {
|
|
@@ -52498,6 +52838,47 @@ async function runLoop(deps, ctx) {
|
|
|
52498
52838
|
lastActivity = bookkeeping && !showBookkeeping ? void 0 : cardActivity(e);
|
|
52499
52839
|
card.update(currentFrame());
|
|
52500
52840
|
};
|
|
52841
|
+
const onEvent = (e) => {
|
|
52842
|
+
const startsRunBudget = e.type === "lease";
|
|
52843
|
+
if (startsRunBudget) {
|
|
52844
|
+
modelBudgetEndsAt = e.endsAt;
|
|
52845
|
+
run2.control.startLease(() => e.endsAt - clock4());
|
|
52846
|
+
}
|
|
52847
|
+
void events.write(async () => {
|
|
52848
|
+
if ((e.type === "tool_call" || e.type === "tool_result") && typeof registry.commitLiveState === "function") {
|
|
52849
|
+
const summary = registry.getById(run2.id);
|
|
52850
|
+
if (summary?.liveState?.state === "working") {
|
|
52851
|
+
const at = e.at ?? clock4();
|
|
52852
|
+
const bound = e.type === "tool_call" && e.boundMs !== void 0 ? at + e.boundMs : modelBudgetEndsAt ?? summary.liveState.bound;
|
|
52853
|
+
if (bound !== void 0) {
|
|
52854
|
+
const sourceSeq = summary.eventCount + 1;
|
|
52855
|
+
const assignment = {
|
|
52856
|
+
expectedSeq: summary.liveStateSeq ?? 0,
|
|
52857
|
+
at,
|
|
52858
|
+
state: "working",
|
|
52859
|
+
bound,
|
|
52860
|
+
detail: e.type === "tool_call" ? "running a tool" : "model turn",
|
|
52861
|
+
sourceEvents: [{ ...e, seq: sourceSeq }]
|
|
52862
|
+
};
|
|
52863
|
+
try {
|
|
52864
|
+
if (ledgerRun?.tracked()) {
|
|
52865
|
+
const committed = await ledgerRun.assignLiveState(assignment);
|
|
52866
|
+
if (committed.ok) registry.commitLiveState(run2.id, committed);
|
|
52867
|
+
} else {
|
|
52868
|
+
const local = assignRunLiveState(summary.liveState, summary.liveStateSeq ?? 0, assignment);
|
|
52869
|
+
if (local.ok) registry.commitLiveState(run2.id, { ...local, liveStateSeq: sourceSeq });
|
|
52870
|
+
}
|
|
52871
|
+
} catch (err2) {
|
|
52872
|
+
console.warn(
|
|
52873
|
+
`[run] ${msg.threadKey} live-state projection failed: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
52874
|
+
);
|
|
52875
|
+
}
|
|
52876
|
+
}
|
|
52877
|
+
}
|
|
52878
|
+
}
|
|
52879
|
+
publishEvent(e, startsRunBudget);
|
|
52880
|
+
});
|
|
52881
|
+
};
|
|
52501
52882
|
for (const s of mcpForRun?.servers ?? []) {
|
|
52502
52883
|
if (s.unavailable !== void 0)
|
|
52503
52884
|
onEvent({
|
|
@@ -52520,14 +52901,14 @@ async function runLoop(deps, ctx) {
|
|
|
52520
52901
|
descriptionArtifact = startReviewDescription({
|
|
52521
52902
|
store: deps.runStore,
|
|
52522
52903
|
repoCtx,
|
|
52523
|
-
publish: (
|
|
52904
|
+
publish: (event) => events.publish(event)
|
|
52524
52905
|
});
|
|
52525
52906
|
readingDiffBaseline = startReviewReadingDiff({
|
|
52526
52907
|
executor,
|
|
52527
52908
|
cfg: deps.config.config.review?.readingDiff,
|
|
52528
52909
|
env: publicEnv(),
|
|
52529
52910
|
baseRef: repoCtx.baseRef,
|
|
52530
|
-
publish: (
|
|
52911
|
+
publish: (event) => events.publish(event),
|
|
52531
52912
|
parent: root
|
|
52532
52913
|
}).baseline.then((published) => {
|
|
52533
52914
|
console.log(`[reading-diff] ${msg.threadKey} baseline ${published ? "published" : "none"}`);
|
|
@@ -52599,10 +52980,11 @@ async function runLoop(deps, ctx) {
|
|
|
52599
52980
|
if (interrupted === void 0) runFailed = true;
|
|
52600
52981
|
throw err2;
|
|
52601
52982
|
} finally {
|
|
52983
|
+
await events.drain();
|
|
52602
52984
|
const calls = callsInFlight(recordEvents(), statusNow());
|
|
52603
52985
|
commandInFlight = calls.length > 0;
|
|
52604
52986
|
if (commandInFlight)
|
|
52605
|
-
|
|
52987
|
+
events.publish({
|
|
52606
52988
|
type: "run_note",
|
|
52607
52989
|
kind: "workspace_torn_down",
|
|
52608
52990
|
summary: redactAndCap(
|
|
@@ -52676,12 +53058,12 @@ async function runLoop(deps, ctx) {
|
|
|
52676
53058
|
let reviewStoppedBeforeStart = false;
|
|
52677
53059
|
const latchReviewStoppedBeforeStart = () => {
|
|
52678
53060
|
if (reviewStoppedBeforeStart || agent.name !== "review") return reviewStoppedBeforeStart;
|
|
52679
|
-
const
|
|
52680
|
-
const stopAt =
|
|
53061
|
+
const events2 = recordEvents();
|
|
53062
|
+
const stopAt = events2.findIndex(
|
|
52681
53063
|
(event) => event.type === "run_note" && (event.kind === "stop_requested" || event.kind === "stopped")
|
|
52682
53064
|
);
|
|
52683
53065
|
if (stopAt < 0) return false;
|
|
52684
|
-
reviewStoppedBeforeStart = !
|
|
53066
|
+
reviewStoppedBeforeStart = !events2.slice(0, stopAt).some((event) => event.type === "tool_call" && event.tool !== "update_status");
|
|
52685
53067
|
return reviewStoppedBeforeStart;
|
|
52686
53068
|
};
|
|
52687
53069
|
const clearStoppedReviewTail = () => {
|
|
@@ -52696,8 +53078,8 @@ async function runLoop(deps, ctx) {
|
|
|
52696
53078
|
};
|
|
52697
53079
|
const tailSkipped = () => run2.control.requested === "hard" || relaunchEndedRun || latchReviewStoppedBeforeStart();
|
|
52698
53080
|
const releaseWorkspace = (span) => {
|
|
52699
|
-
const
|
|
52700
|
-
const pushed = pushedBranchesOf(
|
|
53081
|
+
const events2 = recordEvents();
|
|
53082
|
+
const pushed = pushedBranchesOf(events2);
|
|
52701
53083
|
return round2.release({
|
|
52702
53084
|
hardStopped: run2.control.requested === "hard",
|
|
52703
53085
|
commandInFlight,
|
|
@@ -52715,7 +53097,7 @@ async function runLoop(deps, ctx) {
|
|
|
52715
53097
|
const staged = await stageIntoWorkspace(files, {
|
|
52716
53098
|
store: deps.artifacts,
|
|
52717
53099
|
threadKey: msg.threadKey,
|
|
52718
|
-
publish: (
|
|
53100
|
+
publish: (event) => events.publish(event),
|
|
52719
53101
|
nextIndex: nextStagedIndex,
|
|
52720
53102
|
executor,
|
|
52721
53103
|
resident: round2.selection.resident !== void 0
|
|
@@ -53161,7 +53543,7 @@ async function runLoop(deps, ctx) {
|
|
|
53161
53543
|
return { workspace, description: prDescription !== void 0 ? "submitted" : "not_submitted" };
|
|
53162
53544
|
};
|
|
53163
53545
|
if (leftBehind) {
|
|
53164
|
-
|
|
53546
|
+
events.publish({
|
|
53165
53547
|
type: "run_note",
|
|
53166
53548
|
kind: "work_left_behind",
|
|
53167
53549
|
summary: oneLine(workLeftBehindSummary(leftBehind)),
|
|
@@ -53170,7 +53552,7 @@ async function runLoop(deps, ctx) {
|
|
|
53170
53552
|
shell.note("quiet", workLeftBehindLabel(leftBehind));
|
|
53171
53553
|
}
|
|
53172
53554
|
if (prDescription) {
|
|
53173
|
-
|
|
53555
|
+
events.publish({
|
|
53174
53556
|
type: "pr_description",
|
|
53175
53557
|
description: redactPrDescription(prDescription),
|
|
53176
53558
|
at: clock4()
|
|
@@ -53206,7 +53588,7 @@ async function runLoop(deps, ctx) {
|
|
|
53206
53588
|
}
|
|
53207
53589
|
} : {},
|
|
53208
53590
|
descriptionTurnRan,
|
|
53209
|
-
publish: (
|
|
53591
|
+
publish: (event) => events.publish(event),
|
|
53210
53592
|
logKey: msg.threadKey
|
|
53211
53593
|
})
|
|
53212
53594
|
);
|
|
@@ -53244,7 +53626,7 @@ async function runLoop(deps, ctx) {
|
|
|
53244
53626
|
fetchPrHead: deps.fetchPrHead ?? currentPrHeadSha,
|
|
53245
53627
|
reply: (text) => io.reply(text),
|
|
53246
53628
|
ack: (text) => replyAck(io, resolved.verbosity, text),
|
|
53247
|
-
publish: (
|
|
53629
|
+
publish: (event) => events.publish(event),
|
|
53248
53630
|
logKey: msg.threadKey
|
|
53249
53631
|
})
|
|
53250
53632
|
);
|
|
@@ -53255,7 +53637,7 @@ async function runLoop(deps, ctx) {
|
|
|
53255
53637
|
gateBypassed = err2 instanceof HarnessGateBypassedError;
|
|
53256
53638
|
if (err2 instanceof ModelPolicyRefusedError) failure2 = { kind: "policy_refusal" };
|
|
53257
53639
|
else if (err2 instanceof ModelTransientFailureError) failure2 = { kind: "provider_transient" };
|
|
53258
|
-
|
|
53640
|
+
events.publish({
|
|
53259
53641
|
type: "run_note",
|
|
53260
53642
|
kind: "run_failed",
|
|
53261
53643
|
summary: redactAndCap(err2 instanceof Error ? err2.message : String(err2), ENDING_NOTE_MAX)
|
|
@@ -53264,7 +53646,7 @@ async function runLoop(deps, ctx) {
|
|
|
53264
53646
|
await endHarness().catch((endErr) => {
|
|
53265
53647
|
const detail = `the harness session's end failed after the loop's own error: ${endErr instanceof Error ? endErr.message : String(endErr)}`;
|
|
53266
53648
|
console.warn(`[run] ${msg.threadKey} ${detail}`);
|
|
53267
|
-
|
|
53649
|
+
events.publish({
|
|
53268
53650
|
type: "run_note",
|
|
53269
53651
|
kind: "harness_error",
|
|
53270
53652
|
summary: redactAndCap(detail, ENDING_NOTE_MAX),
|
|
@@ -53273,13 +53655,13 @@ async function runLoop(deps, ctx) {
|
|
|
53273
53655
|
});
|
|
53274
53656
|
await preserveCodingChildWork("ending").catch((salvageErr) => {
|
|
53275
53657
|
const summary = `the interrupted-work checkpoint failed before teardown: ${salvageErr instanceof Error ? salvageErr.message : String(salvageErr)}`;
|
|
53276
|
-
|
|
53658
|
+
events.publish({ type: "run_note", kind: "work_salvage", summary, at: clock4() });
|
|
53277
53659
|
shell.note("quiet", summary);
|
|
53278
53660
|
});
|
|
53279
53661
|
await root.span("post.workspace_release", (span) => releaseWorkspace(span));
|
|
53280
53662
|
if (!interrupted) throw err2;
|
|
53281
53663
|
if (coordinator !== void 0)
|
|
53282
|
-
|
|
53664
|
+
events.publish({
|
|
53283
53665
|
type: "child_interrupted",
|
|
53284
53666
|
parentInstanceId: coordinator.parentInstanceId,
|
|
53285
53667
|
reason: redactAndCap(interrupted.message, ENDING_NOTE_MAX),
|
|
@@ -53294,12 +53676,49 @@ async function runLoop(deps, ctx) {
|
|
|
53294
53676
|
};
|
|
53295
53677
|
} finally {
|
|
53296
53678
|
clearInterval(heartbeat);
|
|
53679
|
+
await events.drain();
|
|
53297
53680
|
const status3 = statusNow();
|
|
53681
|
+
if (typeof registry.commitLiveState === "function") {
|
|
53682
|
+
const commitBoundary = async (state, at2) => {
|
|
53683
|
+
const summary = registry.getById(run2.id);
|
|
53684
|
+
if (!summary) return;
|
|
53685
|
+
const eventSeq = summary.eventCount + 1;
|
|
53686
|
+
const assignment = state === "ended" ? {
|
|
53687
|
+
expectedSeq: summary.liveStateSeq ?? 0,
|
|
53688
|
+
eventSeq,
|
|
53689
|
+
at: at2,
|
|
53690
|
+
state,
|
|
53691
|
+
cause: causeOfClose(status3, interrupted !== void 0)
|
|
53692
|
+
} : {
|
|
53693
|
+
expectedSeq: summary.liveStateSeq ?? 0,
|
|
53694
|
+
eventSeq,
|
|
53695
|
+
at: at2,
|
|
53696
|
+
state,
|
|
53697
|
+
bound: summary.liveState?.bound ?? at2,
|
|
53698
|
+
detail: "writing the final answer"
|
|
53699
|
+
};
|
|
53700
|
+
if (ledgerRun?.tracked()) {
|
|
53701
|
+
const committed = await ledgerRun.assignLiveState(assignment);
|
|
53702
|
+
if (committed.ok) registry.commitLiveState(run2.id, committed);
|
|
53703
|
+
return;
|
|
53704
|
+
}
|
|
53705
|
+
const local = assignRunLiveState(summary.liveState, summary.liveStateSeq ?? 0, assignment);
|
|
53706
|
+
if (!local.ok || !local.event) return;
|
|
53707
|
+
registry.commitLiveState(run2.id, {
|
|
53708
|
+
...local,
|
|
53709
|
+
event: { ...local.event, seq: eventSeq },
|
|
53710
|
+
liveStateSeq: eventSeq
|
|
53711
|
+
});
|
|
53712
|
+
};
|
|
53713
|
+
const at = clock4();
|
|
53714
|
+
await commitBoundary("wrapping_up", at);
|
|
53715
|
+
await commitBoundary("ended", clock4());
|
|
53716
|
+
}
|
|
53298
53717
|
registry.finish(run2.id, status3);
|
|
53299
53718
|
const snap = registry.snapshot(run2.id, run2.token);
|
|
53300
|
-
const
|
|
53719
|
+
const recordEventList = snap?.events ?? [];
|
|
53301
53720
|
const finishedAt = snap?.finishedAt ?? clock4();
|
|
53302
|
-
const diagnosis = analyzeRunFriction(
|
|
53721
|
+
const diagnosis = analyzeRunFriction(recordEventList, {
|
|
53303
53722
|
finished: true,
|
|
53304
53723
|
truncated: snap?.truncated ?? false,
|
|
53305
53724
|
window: { start: snap?.receivedAt ?? startedAt, end: finishedAt }
|
|
@@ -53432,10 +53851,13 @@ var init_runLoop = __esm({
|
|
|
53432
53851
|
init_readingDiff();
|
|
53433
53852
|
init_reviewDescription();
|
|
53434
53853
|
init_runEvents();
|
|
53854
|
+
init_runEventLane();
|
|
53435
53855
|
init_redact();
|
|
53436
53856
|
init_runFriction();
|
|
53437
53857
|
init_llmOutput();
|
|
53438
53858
|
init_runRecord();
|
|
53859
|
+
init_runLiveState();
|
|
53860
|
+
init_decide();
|
|
53439
53861
|
init_statusCardLabel();
|
|
53440
53862
|
init_runPace();
|
|
53441
53863
|
init_statusCardFrame();
|
|
@@ -54387,6 +54809,34 @@ async function runShipBranch(deps, msg, io, ctx) {
|
|
|
54387
54809
|
...REPLAY_EVERYTHING
|
|
54388
54810
|
});
|
|
54389
54811
|
}
|
|
54812
|
+
const admittedAt = clock4();
|
|
54813
|
+
const admittedEventSeq = (registry.getById(run2.id)?.eventCount ?? 0) + 1;
|
|
54814
|
+
const admittedAssignment = {
|
|
54815
|
+
expectedSeq: 0,
|
|
54816
|
+
eventSeq: admittedEventSeq,
|
|
54817
|
+
at: admittedAt,
|
|
54818
|
+
state: "admitted",
|
|
54819
|
+
bound: admittedAt + minutesToMs(profile.minutes),
|
|
54820
|
+
detail: "waiting for the pipeline to start"
|
|
54821
|
+
};
|
|
54822
|
+
if (ledgerRun) {
|
|
54823
|
+
const committed = await ledgerRun.assignLiveState(admittedAssignment);
|
|
54824
|
+
if (!committed.ok || !registry.commitLiveState(run2.id, committed))
|
|
54825
|
+
throw new RefusalError(
|
|
54826
|
+
refusalOf(
|
|
54827
|
+
"setup_failed",
|
|
54828
|
+
`hosted live state start was not committed (${committed.ok ? "registry sequence" : committed.reason})`
|
|
54829
|
+
)
|
|
54830
|
+
);
|
|
54831
|
+
} else {
|
|
54832
|
+
const local = assignRunLiveState(void 0, 0, admittedAssignment);
|
|
54833
|
+
if (local.ok && local.event)
|
|
54834
|
+
registry.commitLiveState(run2.id, {
|
|
54835
|
+
...local,
|
|
54836
|
+
event: { ...local.event, seq: admittedEventSeq },
|
|
54837
|
+
liveStateSeq: admittedEventSeq
|
|
54838
|
+
});
|
|
54839
|
+
}
|
|
54390
54840
|
const hostRefused = opened.kind === "untracked" && opened.why === "thread-live";
|
|
54391
54841
|
const liveUrl = liveViewLink(run2.id, run2.token);
|
|
54392
54842
|
ctx.live.runId = run2.id;
|
|
@@ -54457,7 +54907,23 @@ async function runShipBranch(deps, msg, io, ctx) {
|
|
|
54457
54907
|
instanceId: outcome.instanceId,
|
|
54458
54908
|
until: clock4() + minutesToMs(caps.maxMinutes + HOSTED_DEADLINE_MARGIN_MINUTES)
|
|
54459
54909
|
};
|
|
54460
|
-
|
|
54910
|
+
const summary = registry.getById(run2.id);
|
|
54911
|
+
const committed = await ledgerRun.assignLiveState({
|
|
54912
|
+
expectedSeq: summary?.liveStateSeq ?? 0,
|
|
54913
|
+
eventSeq: (summary?.eventCount ?? 0) + 1,
|
|
54914
|
+
at: clock4(),
|
|
54915
|
+
state: "working",
|
|
54916
|
+
bound: hosting.until,
|
|
54917
|
+
detail: HOSTED_PIPELINE_STARTING_DETAIL,
|
|
54918
|
+
statePatch: { hosting }
|
|
54919
|
+
});
|
|
54920
|
+
if (!committed.ok || !registry.commitLiveState(run2.id, committed))
|
|
54921
|
+
throw new RefusalError(
|
|
54922
|
+
refusalOf(
|
|
54923
|
+
"setup_failed",
|
|
54924
|
+
`hosted live state transition was not committed (${committed.ok ? "registry sequence" : committed.reason})`
|
|
54925
|
+
)
|
|
54926
|
+
);
|
|
54461
54927
|
registry.publish(run2.id, {
|
|
54462
54928
|
type: "run_meta",
|
|
54463
54929
|
agent: agent.name,
|
|
@@ -54565,6 +55031,8 @@ var init_ship = __esm({
|
|
|
54565
55031
|
init_runFriction();
|
|
54566
55032
|
init_run2();
|
|
54567
55033
|
init_runRegistry();
|
|
55034
|
+
init_runLiveState();
|
|
55035
|
+
init_pipelineStanding();
|
|
54568
55036
|
init_statusCardFrame();
|
|
54569
55037
|
init_types5();
|
|
54570
55038
|
init_refusal();
|
|
@@ -55744,12 +56212,12 @@ async function dispatch(deps, msg, io, opts = {}) {
|
|
|
55744
56212
|
...operatorEvent ? { operator: operatorEvent } : {},
|
|
55745
56213
|
...references.conversations.length > 0 ? { references } : {}
|
|
55746
56214
|
});
|
|
55747
|
-
const { run: run2, runId: runId3, channelVisibility, liveUrl, publishText, publishMeta } = registration;
|
|
56215
|
+
const { run: run2, runId: runId3, channelVisibility, liveUrl, events, publishText, publishMeta } = registration;
|
|
55748
56216
|
registered = run2;
|
|
55749
56217
|
for (const summary of seedNotes)
|
|
55750
|
-
|
|
56218
|
+
events.publish({ type: "run_note", kind: "seed", summary: oneLine(summary), at: clock4() });
|
|
55751
56219
|
if (opts.redispatch)
|
|
55752
|
-
|
|
56220
|
+
events.publish({
|
|
55753
56221
|
type: "run_note",
|
|
55754
56222
|
kind: "redispatch",
|
|
55755
56223
|
summary: `confirmed after question ${opts.redispatch.code}`,
|
|
@@ -55764,7 +56232,7 @@ async function dispatch(deps, msg, io, opts = {}) {
|
|
|
55764
56232
|
threadKey: msg.threadKey,
|
|
55765
56233
|
nextIndex: nextStagedIndex,
|
|
55766
56234
|
preserveWorkspaceIndexes: true,
|
|
55767
|
-
publish: (
|
|
56235
|
+
publish: (event) => events.publish(event)
|
|
55768
56236
|
}) : void 0;
|
|
55769
56237
|
const threadAssets = !resume && deps.artifacts && thread && thread.length > 0 ? readThreadAssets({ runs: runsService, store: deps.artifacts }, msg.threadKey).then(
|
|
55770
56238
|
(assets) => assets.filter((a) => a.runId !== runId3)
|
|
@@ -55775,7 +56243,7 @@ async function dispatch(deps, msg, io, opts = {}) {
|
|
|
55775
56243
|
{
|
|
55776
56244
|
nextIndex: nextStagedIndex,
|
|
55777
56245
|
messageId: messageIdOf(msg, runId3),
|
|
55778
|
-
publish: (
|
|
56246
|
+
publish: (event) => events.publish(event)
|
|
55779
56247
|
}
|
|
55780
56248
|
)
|
|
55781
56249
|
) : void 0;
|
|
@@ -55807,7 +56275,7 @@ async function dispatch(deps, msg, io, opts = {}) {
|
|
|
55807
56275
|
reserved = reservation.reserved;
|
|
55808
56276
|
requestRow = reservation.requestRow;
|
|
55809
56277
|
if (reservation.untrackedWhy !== void 0) {
|
|
55810
|
-
|
|
56278
|
+
events.publish({
|
|
55811
56279
|
type: "run_note",
|
|
55812
56280
|
kind: "ledger_untracked",
|
|
55813
56281
|
summary: redactAndCap(
|
|
@@ -55821,6 +56289,100 @@ async function dispatch(deps, msg, io, opts = {}) {
|
|
|
55821
56289
|
shell.note("debug", "untracked by the ledger");
|
|
55822
56290
|
}
|
|
55823
56291
|
}
|
|
56292
|
+
if (typeof registry.commitLiveState === "function") {
|
|
56293
|
+
await events.write(async () => {
|
|
56294
|
+
const current = registry.getById(runId3);
|
|
56295
|
+
if (current && current.liveState === void 0) {
|
|
56296
|
+
const at = clock4();
|
|
56297
|
+
const eventSeq = current.eventCount + 1;
|
|
56298
|
+
const assignment = {
|
|
56299
|
+
expectedSeq: 0,
|
|
56300
|
+
eventSeq,
|
|
56301
|
+
at,
|
|
56302
|
+
state: "admitted",
|
|
56303
|
+
bound: resume ? at + resume.plan.remainingMs : Math.max(startedAt + minutesToMs(profile.minutes), at + minutesToMs(profile.minutes)),
|
|
56304
|
+
detail: "waiting to attach the workspace",
|
|
56305
|
+
// A reservation is not subscribed to the registry until promotion.
|
|
56306
|
+
// Commit the setup stream that already exists with admission, or
|
|
56307
|
+
// advancing its ledger cursor here would make promotion skip it.
|
|
56308
|
+
...reserved ? {
|
|
56309
|
+
sourceEvents: (registry.snapshotById(runId3)?.events ?? []).map((event) => ({
|
|
56310
|
+
...event,
|
|
56311
|
+
seq: event.seq
|
|
56312
|
+
}))
|
|
56313
|
+
} : {},
|
|
56314
|
+
...(current.liveStateSeq ?? 0) > 0 ? { restart: true } : {}
|
|
56315
|
+
};
|
|
56316
|
+
const tracked = reserved ?? ledgerRun;
|
|
56317
|
+
if (tracked?.tracked()) {
|
|
56318
|
+
let committed = await tracked.assignLiveState(assignment);
|
|
56319
|
+
if (!committed.ok && committed.reason === "stale-sequence" && (current.liveStateSeq ?? 0) > 0)
|
|
56320
|
+
committed = await tracked.assignLiveState({
|
|
56321
|
+
...assignment,
|
|
56322
|
+
expectedSeq: current.liveStateSeq ?? 0,
|
|
56323
|
+
sourceEvents: void 0,
|
|
56324
|
+
restart: true
|
|
56325
|
+
});
|
|
56326
|
+
if (!committed.ok || !registry.commitLiveState(runId3, committed))
|
|
56327
|
+
throw new Error(
|
|
56328
|
+
`live state admission was not committed (${committed.ok ? "registry sequence" : committed.reason})`
|
|
56329
|
+
);
|
|
56330
|
+
} else {
|
|
56331
|
+
const expectedSeq = current.liveStateSeq ?? 0;
|
|
56332
|
+
const local = assignRunLiveState(void 0, expectedSeq, { ...assignment, expectedSeq });
|
|
56333
|
+
if (!local.ok || !local.event) throw new Error("live state admission was invalid");
|
|
56334
|
+
registry.commitLiveState(runId3, {
|
|
56335
|
+
...local,
|
|
56336
|
+
event: { ...local.event, seq: eventSeq },
|
|
56337
|
+
liveStateSeq: eventSeq
|
|
56338
|
+
});
|
|
56339
|
+
}
|
|
56340
|
+
}
|
|
56341
|
+
});
|
|
56342
|
+
}
|
|
56343
|
+
const assignLive = async (next, at, detail) => {
|
|
56344
|
+
if (typeof registry.commitLiveState !== "function") return true;
|
|
56345
|
+
let accepted = false;
|
|
56346
|
+
await events.write(async () => {
|
|
56347
|
+
const summary = registry.getById(runId3);
|
|
56348
|
+
if (!summary) return;
|
|
56349
|
+
const eventSeq = summary.eventCount + 1;
|
|
56350
|
+
const assignment = {
|
|
56351
|
+
expectedSeq: summary.liveStateSeq ?? 0,
|
|
56352
|
+
eventSeq,
|
|
56353
|
+
at,
|
|
56354
|
+
state: next.state,
|
|
56355
|
+
bound: next.bound,
|
|
56356
|
+
...detail !== void 0 ? { detail } : {}
|
|
56357
|
+
};
|
|
56358
|
+
const tracked = ledgerRun ?? reserved;
|
|
56359
|
+
if (tracked) {
|
|
56360
|
+
const committed = await tracked.assignLiveState(assignment);
|
|
56361
|
+
accepted = committed.ok && (registry.commitLiveState?.(runId3, committed) ?? true);
|
|
56362
|
+
return;
|
|
56363
|
+
}
|
|
56364
|
+
const local = assignRunLiveState(summary.liveState, summary.liveStateSeq ?? 0, assignment);
|
|
56365
|
+
if (!local.ok) return;
|
|
56366
|
+
accepted = registry.commitLiveState?.(runId3, {
|
|
56367
|
+
...local,
|
|
56368
|
+
...local.event ? { event: { ...local.event, seq: eventSeq } } : {},
|
|
56369
|
+
liveStateSeq: local.event ? eventSeq : summary.liveStateSeq ?? 0
|
|
56370
|
+
}) ?? true;
|
|
56371
|
+
});
|
|
56372
|
+
return accepted;
|
|
56373
|
+
};
|
|
56374
|
+
let residentAttachAttempt = 0;
|
|
56375
|
+
const observeResidentLiveState = async (observation) => {
|
|
56376
|
+
if (observation.attempt < residentAttachAttempt) return;
|
|
56377
|
+
residentAttachAttempt = observation.attempt;
|
|
56378
|
+
const accepted = await assignLive(
|
|
56379
|
+
{ state: observation.state, bound: observation.bound },
|
|
56380
|
+
clock4(),
|
|
56381
|
+
liveStateWords(observation.state)
|
|
56382
|
+
);
|
|
56383
|
+
if (!accepted) throw new Error("resident live-state observation was stale or could not be committed");
|
|
56384
|
+
shell.setSetupLabel(`${liveStateWords(observation.state)}\u2026`);
|
|
56385
|
+
};
|
|
55824
56386
|
const reattach = resume ? carriedWorkspaceBinding(resume.row) : void 0;
|
|
55825
56387
|
const control = registered?.control;
|
|
55826
56388
|
const attach = await attachWorkspace(deps, {
|
|
@@ -55840,7 +56402,8 @@ async function dispatch(deps, msg, io, opts = {}) {
|
|
|
55840
56402
|
// during the attach ends its wake wait at once, and once the harness
|
|
55841
56403
|
// starts the lease every attach the executor opens is clipped to the
|
|
55842
56404
|
// run's remaining clock (execution.md item 9).
|
|
55843
|
-
...control ? { stopSignal: control.hardSignal, remainingMs: () => control.remainingMs() } : {}
|
|
56405
|
+
...control ? { stopSignal: control.hardSignal, remainingMs: () => control.remainingMs() } : {},
|
|
56406
|
+
onLiveStateObservation: observeResidentLiveState
|
|
55844
56407
|
});
|
|
55845
56408
|
if (attach.kind === "refused") return ended;
|
|
55846
56409
|
if (attach.kind === "stopped") {
|
|
@@ -55892,6 +56455,17 @@ async function dispatch(deps, msg, io, opts = {}) {
|
|
|
55892
56455
|
return ended;
|
|
55893
56456
|
}
|
|
55894
56457
|
const { round: round2 } = attach;
|
|
56458
|
+
if (typeof registry.commitLiveState === "function") {
|
|
56459
|
+
const summary = registry.getById(runId3);
|
|
56460
|
+
const bound2 = summary?.liveState?.bound ?? startedAt + minutesToMs(profile.minutes);
|
|
56461
|
+
if (summary?.liveState && (summary.liveState.state === "waiting_deploy" || summary.liveState.state === "waiting_repository") && round2.selection.backend !== "resident") {
|
|
56462
|
+
if (!await assignLive({ state: "falling_back", bound: bound2 }, clock4(), "switching to a fallback workspace"))
|
|
56463
|
+
throw new Error("fallback live state could not be committed");
|
|
56464
|
+
}
|
|
56465
|
+
if (!await assignLive({ state: "preparing", bound: bound2 }, clock4(), "preparing the workspace"))
|
|
56466
|
+
throw new Error("preparation live state could not be committed");
|
|
56467
|
+
shell.setSetupLabel(`${liveStateWords("preparing")}\u2026`);
|
|
56468
|
+
}
|
|
55895
56469
|
if (resume && ledgerRun) {
|
|
55896
56470
|
const rebound = workspaceBindingFor(round2.selection, profile.machine);
|
|
55897
56471
|
if (rebound !== void 0) ledgerRun.setState({ binding: rebound });
|
|
@@ -56073,6 +56647,12 @@ async function dispatch(deps, msg, io, opts = {}) {
|
|
|
56073
56647
|
markUntracked: () => shell.note("debug", "untracked by the ledger"),
|
|
56074
56648
|
...seedActors !== void 0 ? { seedActors } : {}
|
|
56075
56649
|
});
|
|
56650
|
+
if (typeof registry.commitLiveState === "function") {
|
|
56651
|
+
const summary = registry.getById(runId3);
|
|
56652
|
+
const bound2 = summary?.liveState?.bound ?? startedAt + minutesToMs(profile.minutes);
|
|
56653
|
+
if (!await assignLive({ state: "working", bound: bound2 }, clock4(), "model turn"))
|
|
56654
|
+
throw new Error("working live state could not be committed");
|
|
56655
|
+
}
|
|
56076
56656
|
const sessionTools = sessionCapabilityFor(
|
|
56077
56657
|
ledgerRun,
|
|
56078
56658
|
deps.runLedger,
|
|
@@ -56114,6 +56694,7 @@ async function dispatch(deps, msg, io, opts = {}) {
|
|
|
56114
56694
|
mcpForRun,
|
|
56115
56695
|
run: run2,
|
|
56116
56696
|
registry,
|
|
56697
|
+
events,
|
|
56117
56698
|
round: round2,
|
|
56118
56699
|
admitted,
|
|
56119
56700
|
ledgerRun,
|
|
@@ -56442,6 +57023,8 @@ var init_dispatcher = __esm({
|
|
|
56442
57023
|
init_registry();
|
|
56443
57024
|
init_budgets();
|
|
56444
57025
|
init_trace();
|
|
57026
|
+
init_runLiveState();
|
|
57027
|
+
init_decide();
|
|
56445
57028
|
init_requestTrace();
|
|
56446
57029
|
init_runShape();
|
|
56447
57030
|
init_runEvents();
|
|
@@ -56973,7 +57556,7 @@ function createLedgerWriteThrough(opts) {
|
|
|
56973
57556
|
}
|
|
56974
57557
|
}
|
|
56975
57558
|
event(event, seq) {
|
|
56976
|
-
if (this.detached || this.finished) return;
|
|
57559
|
+
if (this.detached || this.finished || seq <= this.lastSeq) return;
|
|
56977
57560
|
this.lastSeq = seq;
|
|
56978
57561
|
const e = event;
|
|
56979
57562
|
if (typeof e.at === "number") this.factLastEventAt = e.at;
|
|
@@ -56994,6 +57577,30 @@ function createLedgerWriteThrough(opts) {
|
|
|
56994
57577
|
};
|
|
56995
57578
|
this.flusher.push({ ...event, seq });
|
|
56996
57579
|
}
|
|
57580
|
+
async assignLiveState(assignment) {
|
|
57581
|
+
if (this.detached || this.finished) return { ok: false, reason: "unknown-run" };
|
|
57582
|
+
await this.flusher.flush();
|
|
57583
|
+
await this.stateSending;
|
|
57584
|
+
try {
|
|
57585
|
+
const result = await ledger.assignLiveState(this.runId, gen, assignment);
|
|
57586
|
+
if (!result.ok) {
|
|
57587
|
+
if (result.reason === "fenced" || result.reason === "unknown-run")
|
|
57588
|
+
this.detach(`live state refused (${result.reason})`);
|
|
57589
|
+
return result;
|
|
57590
|
+
}
|
|
57591
|
+
this.state = {
|
|
57592
|
+
...this.state,
|
|
57593
|
+
...assignment.statePatch,
|
|
57594
|
+
liveState: result.liveState,
|
|
57595
|
+
liveStateSeq: result.liveStateSeq
|
|
57596
|
+
};
|
|
57597
|
+
this.lastSeq = Math.max(this.lastSeq, result.liveStateSeq);
|
|
57598
|
+
return result;
|
|
57599
|
+
} catch (err2) {
|
|
57600
|
+
warn(`[ledger] ${this.threadKey} live state not written: ${describe9(err2)}`);
|
|
57601
|
+
return { ok: false, reason: "unknown-run" };
|
|
57602
|
+
}
|
|
57603
|
+
}
|
|
56997
57604
|
setState(patch) {
|
|
56998
57605
|
if (this.detached) return;
|
|
56999
57606
|
this.state = { ...this.state, ...patch };
|
|
@@ -57378,6 +57985,9 @@ var init_writeThrough = __esm({
|
|
|
57378
57985
|
}
|
|
57379
57986
|
event(_event, _seq) {
|
|
57380
57987
|
}
|
|
57988
|
+
async assignLiveState(_assignment) {
|
|
57989
|
+
return { ok: false, reason: "unknown-run" };
|
|
57990
|
+
}
|
|
57381
57991
|
setState(_patch) {
|
|
57382
57992
|
}
|
|
57383
57993
|
async finishing() {
|
|
@@ -70226,7 +70836,13 @@ async function launchResumes(deps, resumable, opts) {
|
|
|
70226
70836
|
const handle2 = registry.create(row2.meta.label, rehostMeta(row2), {
|
|
70227
70837
|
id: row2.runId,
|
|
70228
70838
|
startedAt: row2.startedAt,
|
|
70229
|
-
replay: run2.events
|
|
70839
|
+
replay: run2.events,
|
|
70840
|
+
...row2.liveState !== void 0 ? {
|
|
70841
|
+
liveState: {
|
|
70842
|
+
liveState: row2.liveState,
|
|
70843
|
+
...row2.liveStateSeq !== void 0 ? { liveStateSeq: row2.liveStateSeq } : {}
|
|
70844
|
+
}
|
|
70845
|
+
} : {}
|
|
70230
70846
|
});
|
|
70231
70847
|
const adopted = deps.runLedger.adopt({
|
|
70232
70848
|
runId: row2.runId,
|
|
@@ -70667,6 +71283,72 @@ var init_adminModelProxy = __esm({
|
|
|
70667
71283
|
}
|
|
70668
71284
|
});
|
|
70669
71285
|
|
|
71286
|
+
// ../../src/core/providerLiveStateCoordinator.ts
|
|
71287
|
+
function createProviderLiveStateCoordinator(deps) {
|
|
71288
|
+
let tail = Promise.resolve();
|
|
71289
|
+
const enqueue = (label, work) => {
|
|
71290
|
+
const next = tail.then(work).catch((error) => {
|
|
71291
|
+
deps.warn(`${label} failed: ${describe11(error)}`);
|
|
71292
|
+
});
|
|
71293
|
+
tail = next;
|
|
71294
|
+
return next;
|
|
71295
|
+
};
|
|
71296
|
+
return {
|
|
71297
|
+
level: (provider, side, cause) => enqueue(`provider ${side} report for ${provider}`, async () => {
|
|
71298
|
+
await deps.runLedger.planeLevel({
|
|
71299
|
+
provider,
|
|
71300
|
+
name: "provider",
|
|
71301
|
+
side,
|
|
71302
|
+
...side === "down" && cause !== void 0 ? { cause } : {}
|
|
71303
|
+
});
|
|
71304
|
+
if (side !== "up" || !deps.ledger) return;
|
|
71305
|
+
const rows = await deps.ledger.listLive();
|
|
71306
|
+
for (const row2 of rows) {
|
|
71307
|
+
if (row2.state.liveProvider !== provider || row2.liveState?.state !== "waiting_provider") continue;
|
|
71308
|
+
const tracked = deps.runLedger.liveRuns().find((run2) => run2.runId === row2.runId);
|
|
71309
|
+
const summary = deps.registry.getById(row2.runId);
|
|
71310
|
+
if (!tracked || !summary || row2.liveState.bound === void 0) continue;
|
|
71311
|
+
const committed = await tracked.assignLiveState({
|
|
71312
|
+
expectedSeq: summary.liveStateSeq ?? 0,
|
|
71313
|
+
eventSeq: summary.eventCount + 1,
|
|
71314
|
+
at: deps.clock(),
|
|
71315
|
+
state: "working",
|
|
71316
|
+
bound: row2.liveState.bound,
|
|
71317
|
+
detail: "model turn",
|
|
71318
|
+
statePatch: { liveProvider: void 0 }
|
|
71319
|
+
});
|
|
71320
|
+
if (committed.ok) deps.registry.commitLiveState(row2.runId, committed);
|
|
71321
|
+
}
|
|
71322
|
+
}),
|
|
71323
|
+
park: (runId3, provider) => enqueue(`provider park for ${runId3}`, async () => {
|
|
71324
|
+
await deps.runLedger.planePark(runId3, provider);
|
|
71325
|
+
const summary = deps.registry.getById(runId3);
|
|
71326
|
+
const tracked = deps.runLedger.liveRuns().find((run2) => run2.runId === runId3);
|
|
71327
|
+
const events = deps.registry.snapshotById(runId3)?.events ?? [];
|
|
71328
|
+
let leaseEndsAt;
|
|
71329
|
+
for (const event of events) if (event.type === "lease") leaseEndsAt = event.endsAt;
|
|
71330
|
+
if (!summary || !tracked || leaseEndsAt === void 0) return;
|
|
71331
|
+
const committed = await tracked.assignLiveState({
|
|
71332
|
+
expectedSeq: summary.liveStateSeq ?? 0,
|
|
71333
|
+
eventSeq: summary.eventCount + 1,
|
|
71334
|
+
at: deps.clock(),
|
|
71335
|
+
state: "waiting_provider",
|
|
71336
|
+
bound: leaseEndsAt,
|
|
71337
|
+
detail: "waiting for the model provider",
|
|
71338
|
+
statePatch: { liveProvider: provider }
|
|
71339
|
+
});
|
|
71340
|
+
if (committed.ok) deps.registry.commitLiveState(runId3, committed);
|
|
71341
|
+
})
|
|
71342
|
+
};
|
|
71343
|
+
}
|
|
71344
|
+
var describe11;
|
|
71345
|
+
var init_providerLiveStateCoordinator = __esm({
|
|
71346
|
+
"../../src/core/providerLiveStateCoordinator.ts"() {
|
|
71347
|
+
"use strict";
|
|
71348
|
+
describe11 = (error) => error instanceof Error ? error.message : String(error);
|
|
71349
|
+
}
|
|
71350
|
+
});
|
|
71351
|
+
|
|
70670
71352
|
// ../../src/channels/adminTraceLog.ts
|
|
70671
71353
|
function parseTraceLogQuery(search) {
|
|
70672
71354
|
const query = {};
|
|
@@ -71176,7 +71858,7 @@ async function openThreadFromRequester(deps, instance, lead, at) {
|
|
|
71176
71858
|
}
|
|
71177
71859
|
};
|
|
71178
71860
|
} catch (err2) {
|
|
71179
|
-
return { ok: false, response: json3(502, { ok: false, error: "thread_failed", message:
|
|
71861
|
+
return { ok: false, response: json3(502, { ok: false, error: "thread_failed", message: describe12(err2), at }) };
|
|
71180
71862
|
}
|
|
71181
71863
|
}
|
|
71182
71864
|
function authorizeStep(headers, step, deps) {
|
|
@@ -71300,8 +71982,8 @@ async function spawn6(body, deps) {
|
|
|
71300
71982
|
try {
|
|
71301
71983
|
turn = await composeChild(req.brief, instance, row2, briefReaders(deps, instance));
|
|
71302
71984
|
} catch (err2) {
|
|
71303
|
-
log(`[coordinator] ${instance.id} ${req.step}: the brief could not be composed: ${
|
|
71304
|
-
return json3(502, { ok: false, error: "brief_failed", message:
|
|
71985
|
+
log(`[coordinator] ${instance.id} ${req.step}: the brief could not be composed: ${describe12(err2)}`);
|
|
71986
|
+
return json3(502, { ok: false, error: "brief_failed", message: describe12(err2), at });
|
|
71305
71987
|
}
|
|
71306
71988
|
} else {
|
|
71307
71989
|
turn = { prompt: req.prompt };
|
|
@@ -71371,7 +72053,7 @@ ${foldThreadEvents(folded)}` };
|
|
|
71371
72053
|
});
|
|
71372
72054
|
} catch (err2) {
|
|
71373
72055
|
releaseAdmission();
|
|
71374
|
-
return json3(502, { ok: false, error: "spawn_failed", message:
|
|
72056
|
+
return json3(502, { ok: false, error: "spawn_failed", message: describe12(err2), at });
|
|
71375
72057
|
}
|
|
71376
72058
|
const settled = dispatching.then(
|
|
71377
72059
|
(outcome) => ({ kind: "ended", outcome }),
|
|
@@ -71380,7 +72062,7 @@ ${foldThreadEvents(folded)}` };
|
|
|
71380
72062
|
void settled.then((end) => {
|
|
71381
72063
|
releaseAdmission();
|
|
71382
72064
|
if (end.kind === "threw")
|
|
71383
|
-
log(`[coordinator] ${instance.id} ${req.step}: the child's dispatch threw: ${
|
|
72065
|
+
log(`[coordinator] ${instance.id} ${req.step}: the child's dispatch threw: ${describe12(end.err)}`);
|
|
71384
72066
|
});
|
|
71385
72067
|
const first = await Promise.race([started.then((id) => ({ kind: "started", id })), settled]);
|
|
71386
72068
|
if (first.kind === "started" || startedId !== void 0) {
|
|
@@ -71390,7 +72072,7 @@ ${foldThreadEvents(folded)}` };
|
|
|
71390
72072
|
{ instanceId: instance.id, unit: row2.unit },
|
|
71391
72073
|
folded.map((e) => e.seq),
|
|
71392
72074
|
req.step
|
|
71393
|
-
).catch((err2) => log(`[coordinator] ${instance.id} ${req.step}: the consumed marks failed: ${
|
|
72075
|
+
).catch((err2) => log(`[coordinator] ${instance.id} ${req.step}: the consumed marks failed: ${describe12(err2)}`));
|
|
71394
72076
|
log(
|
|
71395
72077
|
`[coordinator] ${instance.id} ${req.step}: folded ${folded.length} thread event(s) into the ${req.preset} child`
|
|
71396
72078
|
);
|
|
@@ -71398,7 +72080,7 @@ ${foldThreadEvents(folded)}` };
|
|
|
71398
72080
|
log(`[coordinator] ${instance.id} ${req.step}: spawned ${req.preset} run ${runId3} in ${threadKey}`);
|
|
71399
72081
|
return json3(200, { ok: true, runId: runId3, threadKey, at });
|
|
71400
72082
|
}
|
|
71401
|
-
if (first.kind === "threw") return json3(502, { ok: false, error: "spawn_failed", message:
|
|
72083
|
+
if (first.kind === "threw") return json3(502, { ok: false, error: "spawn_failed", message: describe12(first.err), at });
|
|
71402
72084
|
const refusal = first.outcome.refusal;
|
|
71403
72085
|
if (refusal === "coordinator_thread_live") {
|
|
71404
72086
|
const now = await liveOnThread(deps.runs, instance, threadKey);
|
|
@@ -71618,7 +72300,7 @@ async function readRecord(body, deps) {
|
|
|
71618
72300
|
try {
|
|
71619
72301
|
pullRequest = await childPullRequestState(deps, instanceRow, typeof body.unit === "string" ? body.unit : void 0);
|
|
71620
72302
|
} catch (err2) {
|
|
71621
|
-
return json3(502, { ok: false, error: "github_unavailable", message:
|
|
72303
|
+
return json3(502, { ok: false, error: "github_unavailable", message: describe12(err2), at });
|
|
71622
72304
|
}
|
|
71623
72305
|
if (!view.finished)
|
|
71624
72306
|
return json3(200, {
|
|
@@ -71934,7 +72616,7 @@ async function prCheck(body, deps) {
|
|
|
71934
72616
|
if (recover === void 0) {
|
|
71935
72617
|
const ahead = instance.base === void 0 ? void 0 : await deps.commitsOverBase(instance.repo, instance.base, branch2).catch((err2) => {
|
|
71936
72618
|
(deps.log ?? console.log)(
|
|
71937
|
-
`[coordinator] ${instance.id} pr-check: the compare of ${branch2} over ${instance.base} could not be read: ${
|
|
72619
|
+
`[coordinator] ${instance.id} pr-check: the compare of ${branch2} over ${instance.base} could not be read: ${describe12(err2)}`
|
|
71938
72620
|
);
|
|
71939
72621
|
return void 0;
|
|
71940
72622
|
});
|
|
@@ -71958,7 +72640,7 @@ async function prCheck(body, deps) {
|
|
|
71958
72640
|
if (state?.state !== "merged") throw new Error(`${instance.repo}#${merged.number} no longer reads merged`);
|
|
71959
72641
|
return json3(200, { ok: true, ...state, at });
|
|
71960
72642
|
} catch (err2) {
|
|
71961
|
-
return json3(502, { ok: false, error: "github_unavailable", message:
|
|
72643
|
+
return json3(502, { ok: false, error: "github_unavailable", message: describe12(err2), at });
|
|
71962
72644
|
}
|
|
71963
72645
|
}
|
|
71964
72646
|
async function hostRunOf(deps, instance) {
|
|
@@ -71971,14 +72653,68 @@ async function hostRunOf(deps, instance) {
|
|
|
71971
72653
|
return { kind: "not_host" };
|
|
71972
72654
|
return { kind: "untracked" };
|
|
71973
72655
|
}
|
|
71974
|
-
function hostPublish(deps, instance, runId3, events, at) {
|
|
71975
|
-
for (const event of events) deps.registry.publish(runId3, event);
|
|
72656
|
+
async function hostPublish(deps, instance, runId3, events, at) {
|
|
71976
72657
|
const caps = instance.caps ?? resolveShipCaps(void 0);
|
|
71977
72658
|
const hosting = {
|
|
71978
72659
|
instanceId: instance.id,
|
|
71979
72660
|
until: at + minutesToMs(caps.maxMinutes + HOSTED_DEADLINE_MARGIN_MINUTES)
|
|
71980
72661
|
};
|
|
71981
|
-
deps.ledgerRuns().find((run2) => run2.runId === runId3)
|
|
72662
|
+
const ledgerRun = deps.ledgerRuns().find((run2) => run2.runId === runId3);
|
|
72663
|
+
let summary = deps.registry.getById(runId3);
|
|
72664
|
+
if (ledgerRun && summary) {
|
|
72665
|
+
if (summary.liveState === void 0) {
|
|
72666
|
+
const admitted = await ledgerRun.assignLiveState({
|
|
72667
|
+
expectedSeq: 0,
|
|
72668
|
+
eventSeq: summary.eventCount + 1,
|
|
72669
|
+
at,
|
|
72670
|
+
state: "admitted",
|
|
72671
|
+
bound: hosting.until,
|
|
72672
|
+
detail: "waiting for the pipeline hand-off"
|
|
72673
|
+
});
|
|
72674
|
+
if (!admitted.ok || !deps.registry.commitLiveState(runId3, admitted))
|
|
72675
|
+
throw new Error(
|
|
72676
|
+
`hosted live state backfill was not committed (${admitted.ok ? "registry sequence" : admitted.reason})`
|
|
72677
|
+
);
|
|
72678
|
+
summary = deps.registry.getById(runId3);
|
|
72679
|
+
if (!summary) throw new Error("hosted run disappeared during live-state backfill");
|
|
72680
|
+
const working = await ledgerRun.assignLiveState({
|
|
72681
|
+
expectedSeq: summary.liveStateSeq ?? 0,
|
|
72682
|
+
eventSeq: summary.eventCount + 1,
|
|
72683
|
+
at,
|
|
72684
|
+
state: "working",
|
|
72685
|
+
bound: hosting.until,
|
|
72686
|
+
detail: "pipeline starting",
|
|
72687
|
+
statePatch: { hosting }
|
|
72688
|
+
});
|
|
72689
|
+
if (!working.ok || !deps.registry.commitLiveState(runId3, working))
|
|
72690
|
+
throw new Error(
|
|
72691
|
+
`hosted working backfill was not committed (${working.ok ? "registry sequence" : working.reason})`
|
|
72692
|
+
);
|
|
72693
|
+
summary = deps.registry.getById(runId3);
|
|
72694
|
+
if (!summary) throw new Error("hosted run disappeared after live-state backfill");
|
|
72695
|
+
}
|
|
72696
|
+
const firstSeq = summary.eventCount + 1;
|
|
72697
|
+
const sourceEvents = events.map((event, index) => ({ ...event, seq: firstSeq + index }));
|
|
72698
|
+
const prior = deps.registry.snapshotById(runId3)?.events.filter((event) => event.type === "ship_round" || event.type === "ship_unit") ?? [];
|
|
72699
|
+
const standing = pipelineStandingOf([...prior, ...events]);
|
|
72700
|
+
const stage = standing.changes.at(-1)?.stage ?? "idle";
|
|
72701
|
+
const committed = await ledgerRun.assignLiveState({
|
|
72702
|
+
expectedSeq: summary.liveStateSeq ?? 0,
|
|
72703
|
+
at,
|
|
72704
|
+
state: "working",
|
|
72705
|
+
bound: hosting.until,
|
|
72706
|
+
detail: hostedStageDetail(stage),
|
|
72707
|
+
statePatch: { hosting },
|
|
72708
|
+
sourceEvents
|
|
72709
|
+
});
|
|
72710
|
+
if (!committed.ok || !deps.registry.commitLiveState(runId3, committed))
|
|
72711
|
+
throw new Error(
|
|
72712
|
+
`hosted live state refresh was not committed (${committed.ok ? "registry sequence" : committed.reason})`
|
|
72713
|
+
);
|
|
72714
|
+
} else {
|
|
72715
|
+
ledgerRun?.setState({ hosting });
|
|
72716
|
+
}
|
|
72717
|
+
for (const event of events) deps.registry.publish(runId3, event);
|
|
71982
72718
|
}
|
|
71983
72719
|
function namesForeignRun(instance, body) {
|
|
71984
72720
|
return typeof body.runId === "string" && body.runId !== instance.runId;
|
|
@@ -72064,7 +72800,7 @@ async function unitStart(body, deps) {
|
|
|
72064
72800
|
row2 = { ...row2, startedAt: row2.startedAt ?? at };
|
|
72065
72801
|
await deps.instances.putUnits([row2]);
|
|
72066
72802
|
if (host.kind === "host")
|
|
72067
|
-
hostPublish(
|
|
72803
|
+
await hostPublish(
|
|
72068
72804
|
deps,
|
|
72069
72805
|
instance,
|
|
72070
72806
|
host.runId,
|
|
@@ -72113,7 +72849,7 @@ async function branch(body, deps) {
|
|
|
72113
72849
|
await deps.createBranchRef(instance.repo, name, base);
|
|
72114
72850
|
return json3(200, { ok: true, branch: name, base, at });
|
|
72115
72851
|
} catch (err2) {
|
|
72116
|
-
return json3(200, { ok: false, reason:
|
|
72852
|
+
return json3(200, { ok: false, reason: describe12(err2), at });
|
|
72117
72853
|
}
|
|
72118
72854
|
}
|
|
72119
72855
|
function unitLines(units, generated, severity) {
|
|
@@ -72194,7 +72930,7 @@ async function round(body, deps) {
|
|
|
72194
72930
|
await deps.instances.putUnits([updated]);
|
|
72195
72931
|
if (host.kind === "host") {
|
|
72196
72932
|
const thread = unitThread(instance, updated, units.length);
|
|
72197
|
-
hostPublish(
|
|
72933
|
+
await hostPublish(
|
|
72198
72934
|
deps,
|
|
72199
72935
|
instance,
|
|
72200
72936
|
host.runId,
|
|
@@ -72228,7 +72964,7 @@ async function round(body, deps) {
|
|
|
72228
72964
|
instance,
|
|
72229
72965
|
units.map((u) => u.unit === updated.unit ? updated : u)
|
|
72230
72966
|
).catch(
|
|
72231
|
-
(err2) => (deps.log ?? console.warn)(`[coordinator] ${instance.id}: the card could not be redrawn: ${
|
|
72967
|
+
(err2) => (deps.log ?? console.warn)(`[coordinator] ${instance.id}: the card could not be redrawn: ${describe12(err2)}`)
|
|
72232
72968
|
);
|
|
72233
72969
|
return json3(200, { ok: true, at });
|
|
72234
72970
|
}
|
|
@@ -72402,7 +73138,7 @@ async function unitWake(body, deps) {
|
|
|
72402
73138
|
instance,
|
|
72403
73139
|
units.map((u) => u.unit === visible.unit ? visible : u)
|
|
72404
73140
|
).catch(
|
|
72405
|
-
(err2) => (deps.log ?? console.warn)(`[coordinator] ${instance.id}: the card could not be redrawn: ${
|
|
73141
|
+
(err2) => (deps.log ?? console.warn)(`[coordinator] ${instance.id}: the card could not be redrawn: ${describe12(err2)}`)
|
|
72406
73142
|
);
|
|
72407
73143
|
return json3(200, { ok: true, answer, at });
|
|
72408
73144
|
}
|
|
@@ -72465,7 +73201,7 @@ async function unitEnd(body, deps) {
|
|
|
72465
73201
|
deps.runnerOwnership?.release(instance.repo, updated.pr.number);
|
|
72466
73202
|
const thread = unitThread(instance, updated, units.length);
|
|
72467
73203
|
if (host.kind === "host")
|
|
72468
|
-
hostPublish(
|
|
73204
|
+
await hostPublish(
|
|
72469
73205
|
deps,
|
|
72470
73206
|
instance,
|
|
72471
73207
|
host.runId,
|
|
@@ -72496,7 +73232,7 @@ async function unitEnd(body, deps) {
|
|
|
72496
73232
|
`unit-end:${row2.unit}`
|
|
72497
73233
|
).catch(
|
|
72498
73234
|
(err2) => (deps.log ?? console.warn)(
|
|
72499
|
-
`[coordinator] ${instance.id} ${row2.unit}: the leftover marks failed: ${
|
|
73235
|
+
`[coordinator] ${instance.id} ${row2.unit}: the leftover marks failed: ${describe12(err2)}`
|
|
72500
73236
|
)
|
|
72501
73237
|
);
|
|
72502
73238
|
const freshTurn = {
|
|
@@ -72514,7 +73250,7 @@ async function unitEnd(body, deps) {
|
|
|
72514
73250
|
};
|
|
72515
73251
|
void deps.dispatch(freshTurn, io).catch(
|
|
72516
73252
|
(err2) => (deps.log ?? console.warn)(
|
|
72517
|
-
`[coordinator] ${instance.id} ${row2.unit}: the leftovers' fresh turn threw: ${
|
|
73253
|
+
`[coordinator] ${instance.id} ${row2.unit}: the leftovers' fresh turn threw: ${describe12(err2)}`
|
|
72518
73254
|
)
|
|
72519
73255
|
);
|
|
72520
73256
|
(deps.log ?? console.log)(
|
|
@@ -72531,7 +73267,7 @@ async function unitEnd(body, deps) {
|
|
|
72531
73267
|
told = true;
|
|
72532
73268
|
} catch (err2) {
|
|
72533
73269
|
(deps.log ?? console.warn)(
|
|
72534
|
-
`[coordinator] ${instance.id} ${row2.unit}: the report could not be posted: ${
|
|
73270
|
+
`[coordinator] ${instance.id} ${row2.unit}: the report could not be posted: ${describe12(err2)}`
|
|
72535
73271
|
);
|
|
72536
73272
|
}
|
|
72537
73273
|
}
|
|
@@ -72545,7 +73281,7 @@ ${ending.report}` + (rendered !== void 0 ? `
|
|
|
72545
73281
|
${rendered}` : "");
|
|
72546
73282
|
await deps.github.commentIssue(instance.repo, row2.issue, comment).catch(
|
|
72547
73283
|
(err2) => (deps.log ?? console.warn)(
|
|
72548
|
-
`[coordinator] ${instance.id} ${row2.unit}: the board comment could not be posted: ${
|
|
73284
|
+
`[coordinator] ${instance.id} ${row2.unit}: the board comment could not be posted: ${describe12(err2)}`
|
|
72549
73285
|
)
|
|
72550
73286
|
);
|
|
72551
73287
|
}
|
|
@@ -72556,7 +73292,7 @@ ${rendered}` : "");
|
|
|
72556
73292
|
|
|
72557
73293
|
${ending.report}`).catch(
|
|
72558
73294
|
(err2) => (deps.log ?? console.warn)(
|
|
72559
|
-
`[coordinator] ${instance.id} ${row2.unit}: the human-gated report could not be posted on the pull request: ${
|
|
73295
|
+
`[coordinator] ${instance.id} ${row2.unit}: the human-gated report could not be posted on the pull request: ${describe12(err2)}`
|
|
72560
73296
|
)
|
|
72561
73297
|
);
|
|
72562
73298
|
}
|
|
@@ -72618,7 +73354,7 @@ async function rebaseStep(body, deps) {
|
|
|
72618
73354
|
at
|
|
72619
73355
|
});
|
|
72620
73356
|
} catch (err2) {
|
|
72621
|
-
return json3(200, { ok: true, outcome: "refused", reason:
|
|
73357
|
+
return json3(200, { ok: true, outcome: "refused", reason: describe12(err2), at });
|
|
72622
73358
|
}
|
|
72623
73359
|
}
|
|
72624
73360
|
async function merge(body, deps, subject2) {
|
|
@@ -72656,7 +73392,7 @@ async function merge(body, deps, subject2) {
|
|
|
72656
73392
|
try {
|
|
72657
73393
|
facts2 = await deps.fetchPrFacts(pr);
|
|
72658
73394
|
} catch (err2) {
|
|
72659
|
-
return json3(502, { ok: false, error: "github_unavailable", message:
|
|
73395
|
+
return json3(502, { ok: false, error: "github_unavailable", message: describe12(err2), at });
|
|
72660
73396
|
}
|
|
72661
73397
|
if (facts2 === void 0)
|
|
72662
73398
|
return json3(502, { ok: false, error: "github_unavailable", message: `${where} could not be read`, at });
|
|
@@ -72782,7 +73518,7 @@ async function merge(body, deps, subject2) {
|
|
|
72782
73518
|
try {
|
|
72783
73519
|
queued = await deps.enqueuePullRequest(pr, { sha: headSha });
|
|
72784
73520
|
} catch (err2) {
|
|
72785
|
-
return json3(502, { ok: false, error: "github_unavailable", message:
|
|
73521
|
+
return json3(502, { ok: false, error: "github_unavailable", message: describe12(err2), at });
|
|
72786
73522
|
}
|
|
72787
73523
|
if (!queued.ok) return refused7(`GitHub refused to enqueue ${where}: ${queued.reason}`);
|
|
72788
73524
|
log(
|
|
@@ -72799,7 +73535,7 @@ async function merge(body, deps, subject2) {
|
|
|
72799
73535
|
title: facts2.title ?? `Merge pull request #${pr.number}`
|
|
72800
73536
|
});
|
|
72801
73537
|
} catch (err2) {
|
|
72802
|
-
return json3(502, { ok: false, error: "github_unavailable", message:
|
|
73538
|
+
return json3(502, { ok: false, error: "github_unavailable", message: describe12(err2), at });
|
|
72803
73539
|
}
|
|
72804
73540
|
if (!merged.ok) {
|
|
72805
73541
|
if (merged.status === 405 && MERGE_QUEUE_405.test(merged.reason)) return enqueue();
|
|
@@ -72910,13 +73646,54 @@ async function finish(body, deps) {
|
|
|
72910
73646
|
if (host.kind === "not_host") return json3(409, { ok: false, error: "not_host", at });
|
|
72911
73647
|
const units = await deps.instances.listUnits(instance.id);
|
|
72912
73648
|
if (host.kind === "host") {
|
|
72913
|
-
|
|
72914
|
-
|
|
72915
|
-
|
|
72916
|
-
|
|
72917
|
-
|
|
72918
|
-
|
|
72919
|
-
|
|
73649
|
+
const ledgerRun = deps.ledgerRuns().find((run2) => run2.runId === host.runId);
|
|
73650
|
+
let summary = deps.registry.getById(host.runId);
|
|
73651
|
+
if (ledgerRun && summary) {
|
|
73652
|
+
if (summary.liveState === void 0) {
|
|
73653
|
+
await hostPublish(deps, instance, host.runId, [], at);
|
|
73654
|
+
summary = deps.registry.getById(host.runId);
|
|
73655
|
+
if (!summary) throw new Error("hosted run disappeared during finish backfill");
|
|
73656
|
+
}
|
|
73657
|
+
const bound = summary.liveState?.bound ?? at + minutesToMs(HOSTED_DEADLINE_MARGIN_MINUTES);
|
|
73658
|
+
const wrapping = await ledgerRun.assignLiveState({
|
|
73659
|
+
expectedSeq: summary.liveStateSeq ?? 0,
|
|
73660
|
+
eventSeq: summary.eventCount + 1,
|
|
73661
|
+
at,
|
|
73662
|
+
state: "wrapping_up",
|
|
73663
|
+
bound,
|
|
73664
|
+
detail: "writing the pipeline summary"
|
|
73665
|
+
});
|
|
73666
|
+
if (!wrapping.ok || !deps.registry.commitLiveState(host.runId, wrapping))
|
|
73667
|
+
throw new Error(`hosted wrap-up was not committed (${wrapping.ok ? "registry sequence" : wrapping.reason})`);
|
|
73668
|
+
summary = deps.registry.getById(host.runId);
|
|
73669
|
+
if (!summary) throw new Error("hosted run disappeared during wrap-up");
|
|
73670
|
+
const answer = { type: "answer", text: planSummary(units, isGenerated2(instance)), at };
|
|
73671
|
+
const answerSeq = summary.eventCount + 1;
|
|
73672
|
+
const refreshed = await ledgerRun.assignLiveState({
|
|
73673
|
+
expectedSeq: summary.liveStateSeq ?? 0,
|
|
73674
|
+
at,
|
|
73675
|
+
state: "wrapping_up",
|
|
73676
|
+
bound,
|
|
73677
|
+
detail: "writing the pipeline summary",
|
|
73678
|
+
sourceEvents: [{ ...answer, seq: answerSeq }]
|
|
73679
|
+
});
|
|
73680
|
+
if (!refreshed.ok || !deps.registry.commitLiveState(host.runId, refreshed))
|
|
73681
|
+
throw new Error(`hosted summary was not committed (${refreshed.ok ? "registry sequence" : refreshed.reason})`);
|
|
73682
|
+
deps.registry.publish(host.runId, answer);
|
|
73683
|
+
summary = deps.registry.getById(host.runId);
|
|
73684
|
+
if (!summary) throw new Error("hosted run disappeared before ending");
|
|
73685
|
+
const ended = await ledgerRun.assignLiveState({
|
|
73686
|
+
expectedSeq: summary.liveStateSeq ?? 0,
|
|
73687
|
+
eventSeq: summary.eventCount + 1,
|
|
73688
|
+
at,
|
|
73689
|
+
state: "ended",
|
|
73690
|
+
cause: body.outcome === "completed" ? "completed" : "failed"
|
|
73691
|
+
});
|
|
73692
|
+
if (!ended.ok || !deps.registry.commitLiveState(host.runId, ended))
|
|
73693
|
+
throw new Error(`hosted ending was not committed (${ended.ok ? "registry sequence" : ended.reason})`);
|
|
73694
|
+
} else {
|
|
73695
|
+
deps.registry.publish(host.runId, { type: "answer", text: planSummary(units, isGenerated2(instance)), at });
|
|
73696
|
+
}
|
|
72920
73697
|
deps.registry.finish(host.runId, body.outcome);
|
|
72921
73698
|
}
|
|
72922
73699
|
await drawCard(deps, instance, units, { icon: body.outcome === "completed" ? "\u2705" : "\u26A0\uFE0F" }).catch(() => {
|
|
@@ -73078,13 +73855,13 @@ function createAdminCoordinatorHandler(deps) {
|
|
|
73078
73855
|
}
|
|
73079
73856
|
write(res, await answerCoordinatorStep(door, read.body, deps));
|
|
73080
73857
|
} catch (err2) {
|
|
73081
|
-
(deps.log ?? console.error)(`[coordinator] ${
|
|
73858
|
+
(deps.log ?? console.error)(`[coordinator] ${describe12(err2)}`);
|
|
73082
73859
|
write(res, json3(500, { ok: false, error: "internal error" }));
|
|
73083
73860
|
}
|
|
73084
73861
|
})();
|
|
73085
73862
|
};
|
|
73086
73863
|
}
|
|
73087
|
-
var COORDINATOR_ADMIN_PREFIX, MAX_SPAWN_PROMPT_CHARS, FINISHED_LOOKBACK_PAGES, MAX_ADMIN_BODY_BYTES, UNIT_ID, PRESETS_OF_KIND, invalid, json3,
|
|
73864
|
+
var COORDINATOR_ADMIN_PREFIX, MAX_SPAWN_PROMPT_CHARS, FINISHED_LOOKBACK_PAGES, MAX_ADMIN_BODY_BYTES, UNIT_ID, PRESETS_OF_KIND, invalid, json3, describe12, isGenerated2, EVERY_RUN, REVIEW_POSTED_CHECKS, REVIEW_POSTED_RECHECK_MS, githubSecondStart, CHILD_SUPERSESSION_REASONS, ROUND_OUTCOMES, ENDING_ICON, STEPS;
|
|
73088
73865
|
var init_adminCoordinator = __esm({
|
|
73089
73866
|
"../../src/channels/adminCoordinator.ts"() {
|
|
73090
73867
|
"use strict";
|
|
@@ -73131,7 +73908,7 @@ var init_adminCoordinator = __esm({
|
|
|
73131
73908
|
};
|
|
73132
73909
|
invalid = (error) => ({ ok: false, error });
|
|
73133
73910
|
json3 = (status3, body) => ({ status: status3, body });
|
|
73134
|
-
|
|
73911
|
+
describe12 = (err2) => err2 instanceof Error ? err2.message : String(err2);
|
|
73135
73912
|
isGenerated2 = (instance) => instance.plan?.path === void 0;
|
|
73136
73913
|
EVERY_RUN = { kind: "all" };
|
|
73137
73914
|
REVIEW_POSTED_CHECKS = 3;
|
|
@@ -74366,6 +75143,13 @@ async function runBot() {
|
|
|
74366
75143
|
if (process.env.PORT) {
|
|
74367
75144
|
const ingress = createIngressHandler(deps, { auth, publicBaseUrl: process.env.PUBLIC_BASE_URL, personByEmail });
|
|
74368
75145
|
const mcp2 = createMcpHandler(deps, { auth, commands, grantsFor: (id) => config.grantsFor(id), personByEmail });
|
|
75146
|
+
const providerLiveState = createProviderLiveStateCoordinator({
|
|
75147
|
+
runLedger,
|
|
75148
|
+
ledger: ledgerClient,
|
|
75149
|
+
registry: defaultRunRegistry,
|
|
75150
|
+
clock: systemClock,
|
|
75151
|
+
warn: (message4) => console.warn(`[provider-state] ${message4}`)
|
|
75152
|
+
});
|
|
74369
75153
|
const modelProxy = createModelProxyHandler({
|
|
74370
75154
|
bearers: runBearers,
|
|
74371
75155
|
providers: () => config.config.providers,
|
|
@@ -74374,17 +75158,11 @@ async function runBot() {
|
|
|
74374
75158
|
...costsCfg?.prices ? { prices: () => costsCfg.prices } : {},
|
|
74375
75159
|
secrets: processSecrets,
|
|
74376
75160
|
clock: systemClock,
|
|
74377
|
-
// The plane's provider seam (model-proxy item 12a; record 0064):
|
|
74378
|
-
// and
|
|
74379
|
-
// the null write-through swallows both where no ledger is configured.
|
|
75161
|
+
// The plane's provider seam (model-proxy item 12a; record 0064): one
|
|
75162
|
+
// coordinator sequences level and park writes; the proxy never waits.
|
|
74380
75163
|
plane: {
|
|
74381
|
-
level: (provider, side, cause) => void
|
|
74382
|
-
|
|
74383
|
-
name: "provider",
|
|
74384
|
-
side,
|
|
74385
|
-
...side === "down" && cause !== void 0 ? { cause } : {}
|
|
74386
|
-
}),
|
|
74387
|
-
park: (runId3, provider) => void runLedger.planePark(runId3, provider)
|
|
75164
|
+
level: (provider, side, cause) => void providerLiveState.level(provider, side, cause),
|
|
75165
|
+
park: (runId3, provider) => void providerLiveState.park(runId3, provider)
|
|
74388
75166
|
}
|
|
74389
75167
|
});
|
|
74390
75168
|
const harnessRoutes = createHarnessRoutesHandler({ bearers: runBearers, harnesses, takeover });
|
|
@@ -75128,6 +75906,7 @@ var init_index = __esm({
|
|
|
75128
75906
|
init_adminModelProxy();
|
|
75129
75907
|
init_modelProxy();
|
|
75130
75908
|
init_runBearers();
|
|
75909
|
+
init_providerLiveStateCoordinator();
|
|
75131
75910
|
init_piHarness();
|
|
75132
75911
|
init_harness2();
|
|
75133
75912
|
init_relay();
|