@coreplane/switchboard 1.260.5 → 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 +106 -4
- 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/budgets.ts +5 -0
- package/dist/assets/src/core/coordinator/driver.ts +43 -6
- package/dist/assets/src/core/pipelineStanding.ts +24 -0
- package/dist/assets/src/core/plane/decide.ts +25 -0
- package/dist/assets/src/core/refusal.ts +1 -1
- package/dist/assets/src/core/runEvents.ts +5 -0
- package/dist/assets/src/core/runFriction.ts +2 -0
- package/dist/assets/src/core/runLedger/decisions.ts +10 -1
- package/dist/assets/src/core/runLedger/types.ts +24 -0
- package/dist/assets/src/core/runLiveState.ts +205 -0
- package/dist/assets/src/core/runRecord.ts +4 -0
- package/dist/assets/src/core/ship/coordinator.ts +29 -6
- package/dist/assets/web/dist/.vite/manifest.json +67 -67
- package/dist/assets/web/dist/assets/{DeliveryPage-Cf1joUyA.js → DeliveryPage-BUJckSuW.js} +1 -1
- package/dist/assets/web/dist/assets/{HomePage-DZEAnCCv.js → HomePage-CBQpcnaW.js} +1 -1
- package/dist/assets/web/dist/assets/{PendingTurnRow-4B8JwETU.js → PendingTurnRow-DIC86uWA.js} +1 -1
- package/dist/assets/web/dist/assets/{PlanePage-CHU2szQs.js → PlanePage-CfrbMh8t.js} +1 -1
- package/dist/assets/web/dist/assets/{ResidentDetailPage-L5SRcN_O.js → ResidentDetailPage-C-SgOUTl.js} +1 -1
- package/dist/assets/web/dist/assets/{ResidentsIndexPage-BIFf8qyE.js → ResidentsIndexPage-CiDhvXok.js} +1 -1
- package/dist/assets/web/dist/assets/{RunFoldRow-DzPIshJx.js → RunFoldRow-DZ8huwUU.js} +1 -1
- package/dist/assets/web/dist/assets/{RunRoutePage-Cru5IVux.js → RunRoutePage-Cp6wicYc.js} +3 -3
- package/dist/assets/web/dist/assets/{RunsIndexPage-CBkdPAdj.js → RunsIndexPage-BPXtfwwx.js} +1 -1
- package/dist/assets/web/dist/assets/{ScheduledPage-D_R55BDk.js → ScheduledPage-DbvP48HI.js} +1 -1
- package/dist/assets/web/dist/assets/{SettingsPage-DlmZvAvf.js → SettingsPage-B87lZaiN.js} +1 -1
- package/dist/assets/web/dist/assets/{SilentTurn-PWMDMbMG.js → SilentTurn-CPED_XCV.js} +1 -1
- package/dist/assets/web/dist/assets/{StatusDot-Bq0mYMFo.js → StatusDot-CFLn-DZ2.js} +1 -1
- package/dist/assets/web/dist/assets/{Tooltip-Bs6zd7yE.js → Tooltip-Dx9YBVEx.js} +1 -1
- package/dist/assets/web/dist/assets/{UnitRoutePage-BMGEZCvn.js → UnitRoutePage-d4A2X_o7.js} +1 -1
- package/dist/assets/web/dist/assets/budgets-BQgcCyvb.js +1 -0
- package/dist/assets/web/dist/assets/{dist-EkKVbIM-.js → dist-Cn51vWpw.js} +1 -1
- package/dist/assets/web/dist/assets/{indexRow-5s3hNzZ9.js → indexRow-BsWcHHVh.js} +1 -1
- package/dist/assets/web/dist/assets/{main-Disot0n_.js → main-DYwRHh0F.js} +2 -2
- package/dist/assets/web/dist/assets/{sseReplay-9gcMpylx.js → sseReplay-DGRDRLua.js} +1 -1
- package/dist/cli.js +1673 -722
- package/package.json +1 -1
- package/dist/assets/web/dist/assets/budgets-0szUBIMv.js +0 -1
package/dist/cli.js
CHANGED
|
@@ -597,7 +597,7 @@ function fit(pipeline) {
|
|
|
597
597
|
const need = ALLOWANCES.provision + ASKS.coding + reserveMinutes({ kind: "coding", index: 0 }, pipeline);
|
|
598
598
|
return { ok: pipeline.maxMinutes >= need, need, have: pipeline.maxMinutes };
|
|
599
599
|
}
|
|
600
|
-
var SECOND_MS, secondsToMs, MINUTE_MS, minutesToMs, DAY_MS, WEEK_MS, CONFIRMATION_TTL_MS, QUESTION_TTL_MS, AUTHOR_BINDING_TTL_MS, FIRST_ATTACH_WAIT_MS, ATTACH_REQUEST_MIN_MS, HARNESS_PROBE_WAIT_MS, DRAIN, INTAKE_WINDOW_MAX_MS, INTAKE_RECOVERY_WINDOW_MS, INTAKE_DELIVERY_CLAIM_MS, LOOP_PRESETS, ASKS, PRESET_FLOORS, FLOORS, PULL_SWEEP, PROVIDER_RETRY_BACKOFFS_MS, MODEL_STREAM_HEARTBEAT_MS, HOSTED_DEADLINE_MARGIN_MINUTES, SHIP_WAIT, RESTART_CLAIM_GRACE_MS, PLANE, PACE_WINDOW_MINUTES, ALLOWANCES, POST_STEP_MINUTES, WRAP_UP_WARNING, SANDBOX_CREDENTIAL_WRITE_TIMEOUT_MS, BASH_COMMAND, RUNAWAY_TURNS_PER_MINUTE, DEFAULT_GRANT, GRANT_RENEWALS_MAX, STRUCTURED_RETRIES_MAX, IDLE_DAYS_DEFAULT, IDLE_DAYS_MAX, IDLE_WAKES_MAX;
|
|
600
|
+
var SECOND_MS, secondsToMs, MINUTE_MS, minutesToMs, DAY_MS, WEEK_MS, CONFIRMATION_TTL_MS, QUESTION_TTL_MS, AUTHOR_BINDING_TTL_MS, FIRST_ATTACH_WAIT_MS, ATTACH_REQUEST_MIN_MS, HARNESS_PROBE_WAIT_MS, DRAIN, INTAKE_WINDOW_MAX_MS, INTAKE_RECOVERY_WINDOW_MS, INTAKE_DELIVERY_CLAIM_MS, LOOP_PRESETS, ASKS, PRESET_FLOORS, FLOORS, PULL_SWEEP, PROVIDER_RETRY_BACKOFFS_MS, MODEL_STREAM_HEARTBEAT_MS, HOSTED_DEADLINE_MARGIN_MINUTES, SHIP_WAIT, SHIP_RECORD_VISIBILITY, RESTART_CLAIM_GRACE_MS, PLANE, PACE_WINDOW_MINUTES, ALLOWANCES, POST_STEP_MINUTES, WRAP_UP_WARNING, SANDBOX_CREDENTIAL_WRITE_TIMEOUT_MS, BASH_COMMAND, RUNAWAY_TURNS_PER_MINUTE, DEFAULT_GRANT, GRANT_RENEWALS_MAX, STRUCTURED_RETRIES_MAX, IDLE_DAYS_DEFAULT, IDLE_DAYS_MAX, IDLE_WAKES_MAX;
|
|
601
601
|
var init_budgets = __esm({
|
|
602
602
|
"../../src/core/budgets.ts"() {
|
|
603
603
|
"use strict";
|
|
@@ -676,6 +676,7 @@ var init_budgets = __esm({
|
|
|
676
676
|
MODEL_STREAM_HEARTBEAT_MS = 15e3;
|
|
677
677
|
HOSTED_DEADLINE_MARGIN_MINUTES = 60;
|
|
678
678
|
SHIP_WAIT = { marginMinutes: 5, chunkMinutes: 5, mergeChunkMinutes: 5, busyRetryMinutes: 2 };
|
|
679
|
+
SHIP_RECORD_VISIBILITY = { retries: 3, retryMs: secondsToMs(1) };
|
|
679
680
|
RESTART_CLAIM_GRACE_MS = minutesToMs(SHIP_WAIT.chunkMinutes);
|
|
680
681
|
PLANE = {
|
|
681
682
|
recentMinutes: 60,
|
|
@@ -4077,6 +4078,7 @@ function isHeadMaterial(event) {
|
|
|
4077
4078
|
case "context":
|
|
4078
4079
|
case "reference":
|
|
4079
4080
|
case "run_meta":
|
|
4081
|
+
case "run_state":
|
|
4080
4082
|
case "route":
|
|
4081
4083
|
return true;
|
|
4082
4084
|
case "run_note":
|
|
@@ -4846,7 +4848,7 @@ function analyzeRunFriction(events, opts = {}) {
|
|
|
4846
4848
|
return;
|
|
4847
4849
|
}
|
|
4848
4850
|
if (ev.type === "artifact" && ev.direction === "out") outboundArtifacts++;
|
|
4849
|
-
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") {
|
|
4850
4852
|
sideFactEvents++;
|
|
4851
4853
|
return;
|
|
4852
4854
|
}
|
|
@@ -4928,6 +4930,7 @@ function analyzeRunFriction(events, opts = {}) {
|
|
|
4928
4930
|
}
|
|
4929
4931
|
return;
|
|
4930
4932
|
}
|
|
4933
|
+
if (ev.type !== "run_note") return;
|
|
4931
4934
|
switch (ev.kind) {
|
|
4932
4935
|
case "wrap_up":
|
|
4933
4936
|
wrapUp = { index, at: ev.at };
|
|
@@ -5881,6 +5884,26 @@ var init_contract2 = __esm({
|
|
|
5881
5884
|
});
|
|
5882
5885
|
|
|
5883
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
|
+
}
|
|
5884
5907
|
function endingWordOf(kind) {
|
|
5885
5908
|
return ENDING_WORDS[kind] ?? kind;
|
|
5886
5909
|
}
|
|
@@ -6007,10 +6030,11 @@ function isPipelineSummaryShape(v) {
|
|
|
6007
6030
|
}
|
|
6008
6031
|
return true;
|
|
6009
6032
|
}
|
|
6010
|
-
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_;
|
|
6011
6034
|
var init_pipelineStanding = __esm({
|
|
6012
6035
|
"../../src/core/pipelineStanding.ts"() {
|
|
6013
6036
|
"use strict";
|
|
6037
|
+
HOSTED_PIPELINE_STARTING_DETAIL = "pipeline starting";
|
|
6014
6038
|
STAGES = [
|
|
6015
6039
|
"coding",
|
|
6016
6040
|
"review",
|
|
@@ -15400,7 +15424,7 @@ var init_refusal = __esm({
|
|
|
15400
15424
|
repo_not_onboarded: "request",
|
|
15401
15425
|
repo_access: "policy",
|
|
15402
15426
|
pr_head_unknown: "system",
|
|
15403
|
-
|
|
15427
|
+
workspace_head_mismatch: "system",
|
|
15404
15428
|
coordinator_thread_live: "system",
|
|
15405
15429
|
live_agent_allowlist: "policy",
|
|
15406
15430
|
follow_up_refused: "request",
|
|
@@ -16133,6 +16157,7 @@ var init_resident = __esm({
|
|
|
16133
16157
|
* here: its `runtime-replaced` is the typed restart (`opWithReattach`). */
|
|
16134
16158
|
runtimeReplacedStreak = 0;
|
|
16135
16159
|
lastBinding;
|
|
16160
|
+
attachAttempt = 0;
|
|
16136
16161
|
/** The thread's binding as the resident answered it on the most recent
|
|
16137
16162
|
* successful attach — including a mid-run re-attach after an eviction, which
|
|
16138
16163
|
* may land on a newer sha than the one the run started on. Undefined until
|
|
@@ -16299,6 +16324,7 @@ var init_resident = __esm({
|
|
|
16299
16324
|
* an operation's wall clock is the command's, and a recovery attach is not
|
|
16300
16325
|
* the command. */
|
|
16301
16326
|
async attach(span, opts = {}) {
|
|
16327
|
+
this.attachAttempt++;
|
|
16302
16328
|
const answer = await this.attachOnce(span, this.attachBoundMs("/attach"), opts.signal);
|
|
16303
16329
|
if (answer.ok) return answer.binding;
|
|
16304
16330
|
if (isDrainingRefusal(answer)) {
|
|
@@ -16347,14 +16373,16 @@ var init_resident = __esm({
|
|
|
16347
16373
|
t0 + (left === void 0 ? DRAIN_WAIT_MAX_MS : Math.max(0, left - DRAIN_LEASE_RESERVE_MS))
|
|
16348
16374
|
);
|
|
16349
16375
|
let answer = first;
|
|
16350
|
-
|
|
16351
|
-
|
|
16352
|
-
|
|
16376
|
+
await this.opts.onLiveStateObservation?.({
|
|
16377
|
+
state: "waiting_deploy",
|
|
16378
|
+
bound: deadline,
|
|
16379
|
+
reason: "deploy",
|
|
16380
|
+
attempt: this.attachAttempt
|
|
16381
|
+
});
|
|
16353
16382
|
const waitSpan = span?.start("dispatch.workspace.attach.drain-wait");
|
|
16354
16383
|
try {
|
|
16355
16384
|
for (; ; ) {
|
|
16356
16385
|
const now = systemClock();
|
|
16357
|
-
note(now);
|
|
16358
16386
|
if (now >= deadline)
|
|
16359
16387
|
throw new ResidentDrainingError(this.opts.resource, now - t0, drainingUntil(answer), refusalWords(answer));
|
|
16360
16388
|
await wakePause(Math.min(DRAIN_POLL_MS, deadline - now), opts.signal, "/attach");
|
|
@@ -16392,7 +16420,6 @@ var init_resident = __esm({
|
|
|
16392
16420
|
}
|
|
16393
16421
|
throw err2;
|
|
16394
16422
|
} finally {
|
|
16395
|
-
this.opts.onSetupNote?.(void 0);
|
|
16396
16423
|
}
|
|
16397
16424
|
}
|
|
16398
16425
|
/** One `/attach`, answered rather than thrown: the binding on a 200, else
|
|
@@ -16699,6 +16726,13 @@ var init_resident = __esm({
|
|
|
16699
16726
|
}
|
|
16700
16727
|
};
|
|
16701
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
|
+
});
|
|
16702
16736
|
let transient = opts.origin === "transient-refusal";
|
|
16703
16737
|
const definite = (why) => residentWakeStrike(route2, refusal, why, "refused", opts.origin);
|
|
16704
16738
|
const decide = (view) => transient && isUnansweredProbe(view) ? {
|
|
@@ -18412,7 +18446,7 @@ async function makeExecutor(opts, ctx, span) {
|
|
|
18412
18446
|
resolveEnvs: () => gitIdentityEnvs(ctx.profile.identity, authorSourceOf(opts, ctx)),
|
|
18413
18447
|
...ctx.ownPr !== void 0 ? { ownPr: ctx.ownPr } : {},
|
|
18414
18448
|
...ctx.remainingMs !== void 0 ? { remainingMs: ctx.remainingMs } : {},
|
|
18415
|
-
...ctx.
|
|
18449
|
+
...ctx.onLiveStateObservation !== void 0 ? { onLiveStateObservation: ctx.onLiveStateObservation } : {}
|
|
18416
18450
|
},
|
|
18417
18451
|
nonWarm,
|
|
18418
18452
|
span,
|
|
@@ -18594,7 +18628,7 @@ async function reattachWorkspace(opts, ctx, recorded, span) {
|
|
|
18594
18628
|
// resident holds its own credential, so the pairs alone ride.
|
|
18595
18629
|
resolveEnvs: () => gitIdentityEnvs(ctx.profile.identity, authorSourceOf(opts, ctx)),
|
|
18596
18630
|
...ctx.remainingMs !== void 0 ? { remainingMs: ctx.remainingMs } : {},
|
|
18597
|
-
...ctx.
|
|
18631
|
+
...ctx.onLiveStateObservation !== void 0 ? { onLiveStateObservation: ctx.onLiveStateObservation } : {}
|
|
18598
18632
|
});
|
|
18599
18633
|
let binding;
|
|
18600
18634
|
try {
|
|
@@ -25399,6 +25433,199 @@ var init_frictionProposals = __esm({
|
|
|
25399
25433
|
}
|
|
25400
25434
|
});
|
|
25401
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
|
+
|
|
25402
25629
|
// ../../src/core/runEventLines.ts
|
|
25403
25630
|
function parseRunEventLines(text) {
|
|
25404
25631
|
const events = [];
|
|
@@ -25464,6 +25691,8 @@ function isRunEvent(v) {
|
|
|
25464
25691
|
return typeof o.url === "string" && typeof o.number === "number" && typeof o.created === "boolean";
|
|
25465
25692
|
case "pushed_head":
|
|
25466
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");
|
|
25467
25696
|
case "review_posted":
|
|
25468
25697
|
return typeof o.repo === "string" && typeof o.number === "number" && typeof o.head === "string";
|
|
25469
25698
|
case "ship_round":
|
|
@@ -25486,12 +25715,16 @@ function isRunEvent(v) {
|
|
|
25486
25715
|
return false;
|
|
25487
25716
|
}
|
|
25488
25717
|
}
|
|
25489
|
-
var NOTE_KINDS;
|
|
25718
|
+
var NOTE_KINDS, LIVE_STATES, ENDING_CAUSES;
|
|
25490
25719
|
var init_runEventLines = __esm({
|
|
25491
25720
|
"../../src/core/runEventLines.ts"() {
|
|
25492
25721
|
"use strict";
|
|
25493
25722
|
init_runEvents();
|
|
25723
|
+
init_runLiveState();
|
|
25724
|
+
init_decide();
|
|
25494
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);
|
|
25495
25728
|
}
|
|
25496
25729
|
});
|
|
25497
25730
|
|
|
@@ -29134,6 +29367,505 @@ var init_llmOutput = __esm({
|
|
|
29134
29367
|
}
|
|
29135
29368
|
});
|
|
29136
29369
|
|
|
29370
|
+
// ../../src/core/dispatch/handBack.ts
|
|
29371
|
+
function renderHandBackLine(line4) {
|
|
29372
|
+
return `${HAND_BACK_PREFIX}
|
|
29373
|
+
\`${line4}\``;
|
|
29374
|
+
}
|
|
29375
|
+
var HAND_BACK_PREFIX;
|
|
29376
|
+
var init_handBack = __esm({
|
|
29377
|
+
"../../src/core/dispatch/handBack.ts"() {
|
|
29378
|
+
"use strict";
|
|
29379
|
+
HAND_BACK_PREFIX = "To run this:";
|
|
29380
|
+
}
|
|
29381
|
+
});
|
|
29382
|
+
|
|
29383
|
+
// ../../src/core/statusCardFrame.ts
|
|
29384
|
+
function activityText(activity) {
|
|
29385
|
+
if (!activity) return void 0;
|
|
29386
|
+
if (activity.kind === "line") return activity.text;
|
|
29387
|
+
return `\u2192 $ ${activity.command.replace(/\s+/g, " ").trim()}`;
|
|
29388
|
+
}
|
|
29389
|
+
function createCardShell(opts) {
|
|
29390
|
+
const verbosity2 = opts.verbosity ?? DEFAULT_VERBOSITY;
|
|
29391
|
+
const notes = [];
|
|
29392
|
+
let link = opts.link;
|
|
29393
|
+
let frame2 = 0;
|
|
29394
|
+
let finishedAt;
|
|
29395
|
+
let setupLabel;
|
|
29396
|
+
const lead = opts.lead ?? [];
|
|
29397
|
+
const base = () => opts.model !== void 0 && shows(verbosity2, "verbose") ? `${opts.label} on \`${opts.model}\`` : opts.label;
|
|
29398
|
+
const label = () => [base(), ...notes.filter((n2) => shows(verbosity2, n2.level)).map((n2) => n2.text)].join(" \xB7 ");
|
|
29399
|
+
const elapsed2 = () => formatDuration((finishedAt ?? opts.now()) - opts.startedAt, "clock");
|
|
29400
|
+
const headline = (icon) => `${icon} ${label()} \xB7 ${elapsed2()}`;
|
|
29401
|
+
const closeDetail = (close, own) => [...shows(verbosity2, "debug") ? [close.shape, close.queued] : [], own].filter(Boolean).join("\n") || void 0;
|
|
29402
|
+
return {
|
|
29403
|
+
get label() {
|
|
29404
|
+
return label();
|
|
29405
|
+
},
|
|
29406
|
+
note(level, text) {
|
|
29407
|
+
notes.push({ level, text });
|
|
29408
|
+
},
|
|
29409
|
+
setLink(next) {
|
|
29410
|
+
link = next;
|
|
29411
|
+
},
|
|
29412
|
+
freeze(at) {
|
|
29413
|
+
finishedAt = at;
|
|
29414
|
+
},
|
|
29415
|
+
setSetupLabel(next) {
|
|
29416
|
+
setupLabel = next;
|
|
29417
|
+
},
|
|
29418
|
+
ack() {
|
|
29419
|
+
const detail = lead.join("\n");
|
|
29420
|
+
return { title: `\u{1F440} ${label()} \xB7 preparing workspace\u2026`, ...detail ? { detail } : {} };
|
|
29421
|
+
},
|
|
29422
|
+
live(parts = {}) {
|
|
29423
|
+
const glyph = SPINNER_GLYPHS[frame2++ % SPINNER_GLYPHS.length];
|
|
29424
|
+
const detail = [...lead, ...parts.detail ?? []].filter(Boolean).join("\n");
|
|
29425
|
+
return {
|
|
29426
|
+
title: headline(glyph) + (setupLabel ? ` \u2014 ${setupLabel}` : "") + (parts.suffix ?? "") + (parts.notice ? ` \xB7 ${parts.notice}` : ""),
|
|
29427
|
+
detail: detail || void 0,
|
|
29428
|
+
...parts.activity ? { activity: parts.activity } : {},
|
|
29429
|
+
link
|
|
29430
|
+
};
|
|
29431
|
+
},
|
|
29432
|
+
close(close) {
|
|
29433
|
+
const detail = closeDetail(close, close.kind === "done" ? close.detail : void 0);
|
|
29434
|
+
switch (close.kind) {
|
|
29435
|
+
case "done":
|
|
29436
|
+
return { title: headline(close.icon), detail, link };
|
|
29437
|
+
case "not_started":
|
|
29438
|
+
return { title: `${close.icon} ${label()} \xB7 not started (${close.reason}) \xB7 ${elapsed2()}`, detail };
|
|
29439
|
+
case "refused":
|
|
29440
|
+
return { title: `${close.icon} ${label()} \xB7 ${close.reason} \xB7 ${elapsed2()}`, detail };
|
|
29441
|
+
case "setup_failed":
|
|
29442
|
+
return { title: `\u274C setup failed \xB7 ${close.reason} \xB7 ${elapsed2()}`, detail };
|
|
29443
|
+
}
|
|
29444
|
+
}
|
|
29445
|
+
};
|
|
29446
|
+
}
|
|
29447
|
+
var SPINNER_GLYPHS, LIVE_CARD_PREFIXES, ROUTE_REASON_PREFIX;
|
|
29448
|
+
var init_statusCardFrame = __esm({
|
|
29449
|
+
"../../src/core/statusCardFrame.ts"() {
|
|
29450
|
+
"use strict";
|
|
29451
|
+
init_formatDuration();
|
|
29452
|
+
init_verbosity();
|
|
29453
|
+
SPINNER_GLYPHS = ["\u25D0", "\u25D3", "\u25D1", "\u25D2"];
|
|
29454
|
+
LIVE_CARD_PREFIXES = [...SPINNER_GLYPHS, "\u{1F440}"];
|
|
29455
|
+
ROUTE_REASON_PREFIX = "route reason:";
|
|
29456
|
+
}
|
|
29457
|
+
});
|
|
29458
|
+
|
|
29459
|
+
// ../../src/core/confirmations.ts
|
|
29460
|
+
import { randomUUID } from "node:crypto";
|
|
29461
|
+
import { existsSync as existsSync12, mkdirSync as mkdirSync9, readFileSync as readFileSync14, writeFileSync as writeFileSync8 } from "node:fs";
|
|
29462
|
+
import { dirname as dirname10, resolve as resolve9 } from "node:path";
|
|
29463
|
+
function newConfirmationId() {
|
|
29464
|
+
return randomUUID();
|
|
29465
|
+
}
|
|
29466
|
+
function renderOffer(offer) {
|
|
29467
|
+
if (offer.question) return `${offer.question.text}
|
|
29468
|
+
Did you mean:
|
|
29469
|
+
\`${offer.line}\`
|
|
29470
|
+
|
|
29471
|
+
${offer.question.evidence}`;
|
|
29472
|
+
return [offer.line, ...offer.risk ? [offer.risk] : []].join("\n");
|
|
29473
|
+
}
|
|
29474
|
+
function confirmationMessageOf(msg) {
|
|
29475
|
+
const { images: _images, documents: _documents, staged: _staged, ...kept } = msg;
|
|
29476
|
+
return kept;
|
|
29477
|
+
}
|
|
29478
|
+
function isRecord3(v) {
|
|
29479
|
+
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
29480
|
+
}
|
|
29481
|
+
function isMessage(v) {
|
|
29482
|
+
return isRecord3(v) && typeof v.channelId === "string" && typeof v.userId === "string" && typeof v.threadKey === "string" && typeof v.text === "string";
|
|
29483
|
+
}
|
|
29484
|
+
function isRunShape(v) {
|
|
29485
|
+
return typeof v.id === "string" && isMessage(v.message) && typeof v.command === "string" && isRecord3(v.input) && typeof v.receipt === "string" && typeof v.risk === "string" && typeof v.model === "string";
|
|
29486
|
+
}
|
|
29487
|
+
function isRedispatchShape(v) {
|
|
29488
|
+
return typeof v.id === "string" && isMessage(v.message) && typeof v.line === "string" && typeof v.evidence === "string" && typeof v.code === "string";
|
|
29489
|
+
}
|
|
29490
|
+
function parsePendingConfirmation(v) {
|
|
29491
|
+
if (!isRecord3(v)) return void 0;
|
|
29492
|
+
if (v.kind === "redispatch")
|
|
29493
|
+
return isRedispatchShape(v) ? v : void 0;
|
|
29494
|
+
if (v.kind !== void 0 && v.kind !== "run") return void 0;
|
|
29495
|
+
return isRunShape(v) ? { ...v, kind: "run" } : void 0;
|
|
29496
|
+
}
|
|
29497
|
+
function parseConfirmation(v) {
|
|
29498
|
+
if (!isRecord3(v) || typeof v.expiresAt !== "number") return void 0;
|
|
29499
|
+
const pending2 = parsePendingConfirmation(v);
|
|
29500
|
+
return pending2 ? { ...pending2, expiresAt: v.expiresAt } : void 0;
|
|
29501
|
+
}
|
|
29502
|
+
function isRefusal(v) {
|
|
29503
|
+
return typeof v === "string" && CONFIRMATION_REFUSALS.includes(v);
|
|
29504
|
+
}
|
|
29505
|
+
function judge2(rows, id, actorIds, now, kind) {
|
|
29506
|
+
const row2 = rows.get(id);
|
|
29507
|
+
if (!row2) return { ok: false, refused: "used" };
|
|
29508
|
+
if (kind === "consume" && row2.expiresAt <= now) {
|
|
29509
|
+
rows.delete(id);
|
|
29510
|
+
return { ok: false, refused: "expired", row: row2 };
|
|
29511
|
+
}
|
|
29512
|
+
if (!actorIds.includes(row2.message.userId))
|
|
29513
|
+
return kind === "consume" ? { ok: false, refused: "foreign", row: row2 } : { ok: false, refused: "foreign" };
|
|
29514
|
+
rows.delete(id);
|
|
29515
|
+
return kind === "consume" ? { ok: true, row: row2 } : { ok: true };
|
|
29516
|
+
}
|
|
29517
|
+
function replaceThreadRow(rows, row2) {
|
|
29518
|
+
for (const [id, r] of rows) if (r.message.threadKey === row2.message.threadKey) rows.delete(id);
|
|
29519
|
+
rows.set(row2.id, row2);
|
|
29520
|
+
}
|
|
29521
|
+
function threadRowId(rows, threadKey) {
|
|
29522
|
+
for (const [id, r] of rows) if (r.message.threadKey === threadKey) return id;
|
|
29523
|
+
return void 0;
|
|
29524
|
+
}
|
|
29525
|
+
function buildConfirmationStore(config, secrets, opts) {
|
|
29526
|
+
const worker = config.config.runtimeOverrides?.worker;
|
|
29527
|
+
if (!worker) return new FileConfirmationStore(opts.path);
|
|
29528
|
+
const tokenEnv = worker.tokenEnv ?? "MEMORY_TOKEN";
|
|
29529
|
+
const token2 = secrets.named(tokenEnv);
|
|
29530
|
+
if (!token2) throw new Error(`runtimeOverrides.worker is configured but ${tokenEnv} is not set`);
|
|
29531
|
+
return new WorkerConfirmationStore({
|
|
29532
|
+
baseUrl: worker.baseUrl,
|
|
29533
|
+
token: token2.reveal(),
|
|
29534
|
+
...opts.fetch ? { fetch: opts.fetch } : {}
|
|
29535
|
+
});
|
|
29536
|
+
}
|
|
29537
|
+
var CONFIRMATION_REFUSALS, UNSHOWABLE_LINE, STORE_UNREACHABLE_LINE, FileConfirmationStore, CONFIRMATION_WORKER_TIMEOUT_MS, WorkerConfirmationStore;
|
|
29538
|
+
var init_confirmations = __esm({
|
|
29539
|
+
"../../src/core/confirmations.ts"() {
|
|
29540
|
+
"use strict";
|
|
29541
|
+
init_clock();
|
|
29542
|
+
CONFIRMATION_REFUSALS = ["used", "expired", "foreign"];
|
|
29543
|
+
UNSHOWABLE_LINE = "this command carries a value that cannot be shown, so no confirmation can be offered; nothing ran";
|
|
29544
|
+
STORE_UNREACHABLE_LINE = "this command needs a confirmation click, and the confirmation store could not be reached; nothing ran \u2014 ask again for the button";
|
|
29545
|
+
FileConfirmationStore = class {
|
|
29546
|
+
path;
|
|
29547
|
+
clock;
|
|
29548
|
+
constructor(path, opts = {}) {
|
|
29549
|
+
this.path = resolve9(path);
|
|
29550
|
+
this.clock = opts.clock ?? systemClock;
|
|
29551
|
+
}
|
|
29552
|
+
read() {
|
|
29553
|
+
const rows = /* @__PURE__ */ new Map();
|
|
29554
|
+
if (!existsSync12(this.path)) return rows;
|
|
29555
|
+
const raw = JSON.parse(readFileSync14(this.path, "utf8"));
|
|
29556
|
+
for (const v of Array.isArray(raw.confirmations) ? raw.confirmations : []) {
|
|
29557
|
+
const row2 = parseConfirmation(v);
|
|
29558
|
+
if (row2) rows.set(row2.id, row2);
|
|
29559
|
+
}
|
|
29560
|
+
return rows;
|
|
29561
|
+
}
|
|
29562
|
+
write(rows) {
|
|
29563
|
+
mkdirSync9(dirname10(this.path), { recursive: true });
|
|
29564
|
+
writeFileSync8(this.path, JSON.stringify({ confirmations: [...rows.values()] }, null, 2));
|
|
29565
|
+
}
|
|
29566
|
+
async put(row2, ttlMs) {
|
|
29567
|
+
const rows = this.read();
|
|
29568
|
+
const stored = { ...row2, expiresAt: this.clock() + ttlMs };
|
|
29569
|
+
replaceThreadRow(rows, stored);
|
|
29570
|
+
this.write(rows);
|
|
29571
|
+
return stored;
|
|
29572
|
+
}
|
|
29573
|
+
async consume(id, actorIds) {
|
|
29574
|
+
const rows = this.read();
|
|
29575
|
+
const out = judge2(rows, id, actorIds, this.clock(), "consume");
|
|
29576
|
+
this.write(rows);
|
|
29577
|
+
return out;
|
|
29578
|
+
}
|
|
29579
|
+
async cancel(id, actorIds) {
|
|
29580
|
+
const rows = this.read();
|
|
29581
|
+
const out = judge2(rows, id, actorIds, this.clock(), "cancel");
|
|
29582
|
+
this.write(rows);
|
|
29583
|
+
return out;
|
|
29584
|
+
}
|
|
29585
|
+
async cancelByThread(threadKey, actorIds) {
|
|
29586
|
+
const rows = this.read();
|
|
29587
|
+
const id = threadRowId(rows, threadKey);
|
|
29588
|
+
if (id === void 0) return { ok: false, refused: "used" };
|
|
29589
|
+
const out = judge2(rows, id, actorIds, this.clock(), "cancel");
|
|
29590
|
+
this.write(rows);
|
|
29591
|
+
return out;
|
|
29592
|
+
}
|
|
29593
|
+
async pendingByThread(threadKey) {
|
|
29594
|
+
const rows = this.read();
|
|
29595
|
+
const id = threadRowId(rows, threadKey);
|
|
29596
|
+
const row2 = id === void 0 ? void 0 : rows.get(id);
|
|
29597
|
+
if (!row2 || row2.expiresAt <= this.clock()) return void 0;
|
|
29598
|
+
return row2;
|
|
29599
|
+
}
|
|
29600
|
+
describe() {
|
|
29601
|
+
return `file ${this.path}`;
|
|
29602
|
+
}
|
|
29603
|
+
};
|
|
29604
|
+
CONFIRMATION_WORKER_TIMEOUT_MS = 8e3;
|
|
29605
|
+
WorkerConfirmationStore = class {
|
|
29606
|
+
constructor(opts) {
|
|
29607
|
+
this.opts = opts;
|
|
29608
|
+
this.baseUrl = opts.baseUrl.replace(/\/+$/, "");
|
|
29609
|
+
this.fetchImpl = opts.fetch ?? fetch;
|
|
29610
|
+
}
|
|
29611
|
+
opts;
|
|
29612
|
+
baseUrl;
|
|
29613
|
+
fetchImpl;
|
|
29614
|
+
async put(row2, ttlMs) {
|
|
29615
|
+
const body = await this.post("/config/confirmations/put", {
|
|
29616
|
+
id: row2.id,
|
|
29617
|
+
threadKey: row2.message.threadKey,
|
|
29618
|
+
requester: row2.message.userId,
|
|
29619
|
+
body: row2,
|
|
29620
|
+
ttlMs
|
|
29621
|
+
});
|
|
29622
|
+
if (typeof body.expiresAt !== "number")
|
|
29623
|
+
throw new Error("confirmation store answered a put without the expiry it stamped");
|
|
29624
|
+
return { ...row2, expiresAt: body.expiresAt };
|
|
29625
|
+
}
|
|
29626
|
+
async consume(id, actorIds) {
|
|
29627
|
+
const body = await this.post("/config/confirmations/consume", { id, actorIds });
|
|
29628
|
+
const stored = isRecord3(body.row) ? body.row : void 0;
|
|
29629
|
+
const row2 = parseConfirmation(
|
|
29630
|
+
stored && isRecord3(stored.body) ? { ...stored.body, expiresAt: stored.expiresAt } : void 0
|
|
29631
|
+
);
|
|
29632
|
+
if (isRefusal(body.refused))
|
|
29633
|
+
return { ok: false, refused: body.refused, ...row2 ? { row: row2 } : {} };
|
|
29634
|
+
if (!row2) throw new Error("confirmation store answered a consume outside its contract");
|
|
29635
|
+
return { ok: true, row: row2 };
|
|
29636
|
+
}
|
|
29637
|
+
async cancel(id, actorIds) {
|
|
29638
|
+
const body = await this.post("/config/confirmations/cancel", { id, actorIds });
|
|
29639
|
+
if (body.ok === true) return { ok: true };
|
|
29640
|
+
if (body.refused === "used" || body.refused === "foreign") return { ok: false, refused: body.refused };
|
|
29641
|
+
throw new Error("confirmation store answered a cancel outside its contract");
|
|
29642
|
+
}
|
|
29643
|
+
async cancelByThread(threadKey, actorIds) {
|
|
29644
|
+
const body = await this.post("/config/confirmations/cancel-by-thread", { threadKey, actorIds });
|
|
29645
|
+
if (body.ok === true) return { ok: true };
|
|
29646
|
+
if (body.refused === "used" || body.refused === "foreign") return { ok: false, refused: body.refused };
|
|
29647
|
+
throw new Error("confirmation store answered a cancel-by-thread outside its contract");
|
|
29648
|
+
}
|
|
29649
|
+
async pendingByThread(threadKey) {
|
|
29650
|
+
const body = await this.post("/config/confirmations/pending-by-thread", { threadKey });
|
|
29651
|
+
if (body.row === null) return void 0;
|
|
29652
|
+
const stored = isRecord3(body.row) ? body.row : void 0;
|
|
29653
|
+
const row2 = parseConfirmation(
|
|
29654
|
+
stored && isRecord3(stored.body) ? { ...stored.body, expiresAt: stored.expiresAt } : void 0
|
|
29655
|
+
);
|
|
29656
|
+
if (!row2) throw new Error("confirmation store answered a pending-by-thread outside its contract");
|
|
29657
|
+
return row2;
|
|
29658
|
+
}
|
|
29659
|
+
describe() {
|
|
29660
|
+
return `state Worker ${this.baseUrl} (ConfigDO confirmations)`;
|
|
29661
|
+
}
|
|
29662
|
+
async post(path, payload2) {
|
|
29663
|
+
let res;
|
|
29664
|
+
try {
|
|
29665
|
+
res = await this.fetchImpl(`${this.baseUrl}${path}`, {
|
|
29666
|
+
method: "POST",
|
|
29667
|
+
headers: { authorization: `Bearer ${this.opts.token}`, "content-type": "application/json" },
|
|
29668
|
+
body: JSON.stringify(payload2),
|
|
29669
|
+
signal: AbortSignal.timeout(CONFIRMATION_WORKER_TIMEOUT_MS)
|
|
29670
|
+
});
|
|
29671
|
+
} catch (err2) {
|
|
29672
|
+
throw new Error(`confirmation store unreachable: ${err2 instanceof Error ? err2.message : String(err2)}`, {
|
|
29673
|
+
cause: err2
|
|
29674
|
+
});
|
|
29675
|
+
}
|
|
29676
|
+
if (!res.ok) throw new Error(`confirmation store answered HTTP ${res.status} on ${path}`);
|
|
29677
|
+
const body = await res.json().catch(() => void 0);
|
|
29678
|
+
if (!isRecord3(body)) throw new Error(`confirmation store returned a non-JSON body on ${path}`);
|
|
29679
|
+
return body;
|
|
29680
|
+
}
|
|
29681
|
+
};
|
|
29682
|
+
}
|
|
29683
|
+
});
|
|
29684
|
+
|
|
29685
|
+
// ../../src/core/dispatch/route.ts
|
|
29686
|
+
function outputCapWithReasoning(visibleAnswerTokens, opts = {}) {
|
|
29687
|
+
return opts.capField !== void 0 && REASONING_COUNTING_CAP_FIELDS.has(opts.capField) ? visibleAnswerTokens + REASONING_OUTPUT_TOKEN_ALLOWANCE : visibleAnswerTokens;
|
|
29688
|
+
}
|
|
29689
|
+
function outputCapRetry(current) {
|
|
29690
|
+
return Math.max(current * 2, REASONING_OUTPUT_TOKEN_ALLOWANCE);
|
|
29691
|
+
}
|
|
29692
|
+
function routedRunsAtOnce(def, confirm, input) {
|
|
29693
|
+
const radius = input === void 0 ? blastRadius(def) : boundBlastRadius(def, input);
|
|
29694
|
+
return radius === "read" || CONFIRM_ORDER[radius] < CONFIRM_ORDER[confirm];
|
|
29695
|
+
}
|
|
29696
|
+
function routeReceipt(def, input) {
|
|
29697
|
+
return redactAndCap(chatInvocation(def, input), ROUTE_RECEIPT_CAP);
|
|
29698
|
+
}
|
|
29699
|
+
function routablePresets() {
|
|
29700
|
+
return Object.values(AGENTS).filter((a) => a.routable !== false).map(({ name, description, machine, identity: identity2, maxMinutes }) => ({
|
|
29701
|
+
name,
|
|
29702
|
+
description,
|
|
29703
|
+
machine,
|
|
29704
|
+
identity: identity2,
|
|
29705
|
+
maxMinutes
|
|
29706
|
+
}));
|
|
29707
|
+
}
|
|
29708
|
+
function routableCommands(commands) {
|
|
29709
|
+
return commands.list().filter((cmd) => CommandRegistry.exposedTo(cmd, "chat")).map((cmd) => ({
|
|
29710
|
+
id: cmd.id,
|
|
29711
|
+
effect: cmd.effect,
|
|
29712
|
+
def: cmd,
|
|
29713
|
+
tool: { name: mcpToolName(cmd.id), description: cmd.describe, inputSchema: jsonSchemaFor(cmd) }
|
|
29714
|
+
}));
|
|
29715
|
+
}
|
|
29716
|
+
function renderPresetTable(presets) {
|
|
29717
|
+
const rows = presets.map(
|
|
29718
|
+
(p) => `| \`${p.name}\` | ${oneLine(p.description)} | ${p.machine} | ${p.identity} | ${p.maxMinutes} min |`
|
|
29719
|
+
);
|
|
29720
|
+
return ["| name | what it does | machine | credential | budget |", "|---|---|---|---|---|", ...rows].join("\n");
|
|
29721
|
+
}
|
|
29722
|
+
function quoteRequest(text) {
|
|
29723
|
+
const cap = 2e3;
|
|
29724
|
+
const bent = text.replace(/<(\/?)request>/gi, "\u2039$1request\u203A");
|
|
29725
|
+
if (bent.length <= cap) return bent;
|
|
29726
|
+
return `${bent.slice(0, cap)}
|
|
29727
|
+
\u2026[truncated: ${bent.length - cap} more characters]`;
|
|
29728
|
+
}
|
|
29729
|
+
function providerStructuredModel(provider, model, opts = {}) {
|
|
29730
|
+
const forced = (opts.answer ?? "tool") === "tool";
|
|
29731
|
+
return async (prompt, call2) => {
|
|
29732
|
+
const tools = [prompt.tool, ...prompt.tools ?? []];
|
|
29733
|
+
const toolChoice = prompt.open ? void 0 : tools.length > 1 ? { type: "any" } : { type: "tool", name: prompt.tool.name };
|
|
29734
|
+
const messages = [
|
|
29735
|
+
{ role: "user", content: [{ type: "text", text: prompt.user }] },
|
|
29736
|
+
...(prompt.retries ?? []).flatMap((r) => [
|
|
29737
|
+
{ role: "assistant", content: [{ type: "text", text: r.answer }] },
|
|
29738
|
+
{ role: "user", content: [{ type: "text", text: r.violation }] }
|
|
29739
|
+
])
|
|
29740
|
+
];
|
|
29741
|
+
const result = await provider.complete({
|
|
29742
|
+
model,
|
|
29743
|
+
system: prompt.system,
|
|
29744
|
+
messages,
|
|
29745
|
+
maxTokens: call2.maxTokens,
|
|
29746
|
+
signal: call2.signal,
|
|
29747
|
+
// The caller's configured effort, card-decided (`turnEffort`): intake's
|
|
29748
|
+
// `intake.effort` or the operator's `defaults.efforts.general`. Absent →
|
|
29749
|
+
// the model's own default.
|
|
29750
|
+
...opts.effort ? { effort: opts.effort.effort, effortWord: opts.effort.effortWord } : {},
|
|
29751
|
+
...forced ? { tools, toolChoice } : {}
|
|
29752
|
+
});
|
|
29753
|
+
if (result.stopReason === "max_tokens") throw new OutputCapError(call2.maxTokens);
|
|
29754
|
+
const calls = result.content.filter(
|
|
29755
|
+
(p) => p.type === "tool_use"
|
|
29756
|
+
);
|
|
29757
|
+
if (calls.length > 1) throw new MultiToolCallError(calls.map((c) => ({ tool: c.name, input: c.input })));
|
|
29758
|
+
if (calls.length === 1) return { tool: calls[0].name, input: calls[0].input };
|
|
29759
|
+
return result.content.filter((p) => p.type === "text").map((p) => p.text).join("");
|
|
29760
|
+
};
|
|
29761
|
+
}
|
|
29762
|
+
async function mintConfirmationOffer(args) {
|
|
29763
|
+
const { io, store, msg, origin, def, input, receipt, model } = args;
|
|
29764
|
+
if (!io.offer || !store) return { kind: "no_click" };
|
|
29765
|
+
const line4 = chatInvocation(def, input);
|
|
29766
|
+
if (redactSecrets(line4) !== line4) return { kind: "unshowable" };
|
|
29767
|
+
const risk = def.annotations?.risk?.(input, origin) ?? "";
|
|
29768
|
+
let row2;
|
|
29769
|
+
try {
|
|
29770
|
+
row2 = await store.put(
|
|
29771
|
+
{
|
|
29772
|
+
kind: "run",
|
|
29773
|
+
id: newConfirmationId(),
|
|
29774
|
+
message: confirmationMessageOf(msg),
|
|
29775
|
+
command: def.id,
|
|
29776
|
+
input,
|
|
29777
|
+
receipt,
|
|
29778
|
+
risk,
|
|
29779
|
+
model
|
|
29780
|
+
},
|
|
29781
|
+
CONFIRMATION_TTL_MS
|
|
29782
|
+
);
|
|
29783
|
+
} catch (err2) {
|
|
29784
|
+
console.warn(
|
|
29785
|
+
`[route] ${msg.threadKey} confirmation store unreachable at mint, handing back: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
29786
|
+
);
|
|
29787
|
+
return { kind: "store_unreachable" };
|
|
29788
|
+
}
|
|
29789
|
+
return { kind: "offered", shown: { id: row2.id, line: line4, risk, expiresAt: row2.expiresAt } };
|
|
29790
|
+
}
|
|
29791
|
+
function redactedInput(input) {
|
|
29792
|
+
const text = (s) => redactAndCap(redactSecrets(s), 200);
|
|
29793
|
+
const leaf = (v) => {
|
|
29794
|
+
if (typeof v === "string") return text(v);
|
|
29795
|
+
if (typeof v === "number" || typeof v === "boolean" || v === null) return v;
|
|
29796
|
+
return v === void 0 ? null : text(JSON.stringify(v) ?? String(v));
|
|
29797
|
+
};
|
|
29798
|
+
const leafOrList = (v) => Array.isArray(v) ? v.map(leaf) : leaf(v);
|
|
29799
|
+
const isRecord11 = (v) => typeof v === "object" && v !== null && (Object.getPrototypeOf(v) === Object.prototype || Object.getPrototypeOf(v) === null);
|
|
29800
|
+
const entries = (v, of) => Object.fromEntries(
|
|
29801
|
+
Object.entries(v).filter(([, x]) => x !== void 0).map(([k, x]) => [k, of(x)])
|
|
29802
|
+
);
|
|
29803
|
+
const object1 = (v) => entries(v, leafOrList);
|
|
29804
|
+
const object2 = (v) => entries(v, (x) => isRecord11(x) ? object1(x) : leafOrList(x));
|
|
29805
|
+
const object3 = (v) => entries(v, (x) => isRecord11(x) ? object2(x) : leafOrList(x));
|
|
29806
|
+
return {
|
|
29807
|
+
...input.args ? { args: input.args.map(leaf) } : {},
|
|
29808
|
+
...input.options ? { options: object3(input.options) } : {}
|
|
29809
|
+
};
|
|
29810
|
+
}
|
|
29811
|
+
function routeReasonLabel(reason2, collapsed) {
|
|
29812
|
+
return `${ROUTE_REASON_PREFIX} ${reason2}${collapsed ? ` (compound collapsed: ${collapsed.presets.join("+")})` : ""}`;
|
|
29813
|
+
}
|
|
29814
|
+
function routedPartLines(parts) {
|
|
29815
|
+
return parts.map((p) => {
|
|
29816
|
+
const line4 = p.text.replace(/\s+/g, " ").trim();
|
|
29817
|
+
return `${p.preset}: ${line4.length > ROUTE_PART_LINE_CAP ? `${line4.slice(0, ROUTE_PART_LINE_CAP - 1)}\u2026` : line4}`;
|
|
29818
|
+
});
|
|
29819
|
+
}
|
|
29820
|
+
function compoundBrief(text, parts) {
|
|
29821
|
+
return [
|
|
29822
|
+
text,
|
|
29823
|
+
"",
|
|
29824
|
+
`${COMPOUND_BRIEF_HEADING}: ${parts.length} independent parts. Spawn exactly these children \u2014 one \`spawn_run\` per part, on the preset named, with the part's text as the child's whole prompt (add the repository where the preset needs one) \u2014 then \`await_runs\` them all and compile one answer. Do not merge, drop or add a part.`,
|
|
29825
|
+
...parts.map((p, i) => `${i + 1}. \`${p.preset}\`: ${p.text}`)
|
|
29826
|
+
].join("\n");
|
|
29827
|
+
}
|
|
29828
|
+
var REASONING_COUNTING_CAP_FIELDS, REASONING_OUTPUT_TOKEN_ALLOWANCE, OutputCapError, ROUTE_REASON_CAP, ROUTE_MIN_OUTPUT_TOKENS, ROUTE_TIMEOUT_MS, ROUTE_PART_LINE_CAP, ROUTE_RECEIPT_CAP, ROUTED_RECEIPT_PREFIX, COMPOUND_BRIEF_HEADING, MultiToolCallError;
|
|
29829
|
+
var init_route = __esm({
|
|
29830
|
+
"../../src/core/dispatch/route.ts"() {
|
|
29831
|
+
"use strict";
|
|
29832
|
+
init_registry();
|
|
29833
|
+
init_handBack();
|
|
29834
|
+
init_profile();
|
|
29835
|
+
init_redact();
|
|
29836
|
+
init_statusCardFrame();
|
|
29837
|
+
init_commandRegistry();
|
|
29838
|
+
init_commandSurface();
|
|
29839
|
+
init_budgets();
|
|
29840
|
+
init_confirmations();
|
|
29841
|
+
REASONING_COUNTING_CAP_FIELDS = /* @__PURE__ */ new Set(["max_tokens", "max_completion_tokens", "max_output_tokens"]);
|
|
29842
|
+
REASONING_OUTPUT_TOKEN_ALLOWANCE = 4096;
|
|
29843
|
+
OutputCapError = class extends Error {
|
|
29844
|
+
constructor(maxTokens) {
|
|
29845
|
+
super(`answer cut at the output cap (${maxTokens} tokens)`);
|
|
29846
|
+
this.maxTokens = maxTokens;
|
|
29847
|
+
this.name = "OutputCapError";
|
|
29848
|
+
}
|
|
29849
|
+
maxTokens;
|
|
29850
|
+
};
|
|
29851
|
+
ROUTE_REASON_CAP = 120;
|
|
29852
|
+
ROUTE_MIN_OUTPUT_TOKENS = 200;
|
|
29853
|
+
ROUTE_TIMEOUT_MS = 8e3;
|
|
29854
|
+
ROUTE_PART_LINE_CAP = 100;
|
|
29855
|
+
ROUTE_RECEIPT_CAP = 300;
|
|
29856
|
+
ROUTED_RECEIPT_PREFIX = "routed:";
|
|
29857
|
+
COMPOUND_BRIEF_HEADING = "Routed as a compound request";
|
|
29858
|
+
MultiToolCallError = class extends Error {
|
|
29859
|
+
constructor(calls) {
|
|
29860
|
+
super(`answer carried ${calls.length} tool calls; the route is one call`);
|
|
29861
|
+
this.calls = calls;
|
|
29862
|
+
this.name = "MultiToolCallError";
|
|
29863
|
+
}
|
|
29864
|
+
calls;
|
|
29865
|
+
};
|
|
29866
|
+
}
|
|
29867
|
+
});
|
|
29868
|
+
|
|
29137
29869
|
// ../../src/core/memory/reflection.ts
|
|
29138
29870
|
import { z as z15 } from "zod";
|
|
29139
29871
|
function shouldReflect(input) {
|
|
@@ -29288,13 +30020,14 @@ async function reflect(deps) {
|
|
|
29288
30020
|
const seen = /* @__PURE__ */ new Set();
|
|
29289
30021
|
const existing = [...await windowP, ...hits].filter((r) => !seen.has(r.id) && (seen.add(r.id), true));
|
|
29290
30022
|
const text = buildReflectionInput({ history: deps.history, request: deps.request, answer: deps.answer, existing });
|
|
30023
|
+
const maxTokens = outputCapWithReasoning(REFLECTION_MAX_TOKENS, { capField: deps.capField });
|
|
29291
30024
|
let result;
|
|
29292
30025
|
try {
|
|
29293
30026
|
result = await deps.provider.complete({
|
|
29294
30027
|
model: deps.model,
|
|
29295
30028
|
system: REFLECTION_SYSTEM,
|
|
29296
30029
|
messages: [{ role: "user", content: [{ type: "text", text }] }],
|
|
29297
|
-
maxTokens
|
|
30030
|
+
maxTokens,
|
|
29298
30031
|
...deps.effort !== void 0 ? { effort: deps.effort } : {},
|
|
29299
30032
|
...deps.effortWord !== void 0 ? { effortWord: deps.effortWord } : {}
|
|
29300
30033
|
});
|
|
@@ -29303,13 +30036,17 @@ async function reflect(deps) {
|
|
|
29303
30036
|
warn(`reflection skipped: ${renderProviderFailure(failure2.cause)}`);
|
|
29304
30037
|
return;
|
|
29305
30038
|
}
|
|
30039
|
+
const truncated = result.stopReason === "max_tokens" ? `truncated at ${maxTokens} max tokens` : void 0;
|
|
30040
|
+
if (truncated) {
|
|
30041
|
+
warn(`reflection output rejected (${truncated}); nothing written`);
|
|
30042
|
+
return;
|
|
30043
|
+
}
|
|
29306
30044
|
const reply = result.content.filter((p) => p.type === "text").map((p) => p.text).join("");
|
|
29307
30045
|
const prov = { sourceThreadKey: deps.sourceThreadKey, sourceRunId: deps.sourceRunId };
|
|
29308
30046
|
const parsed = parseReflection(reply, prov, new Set(existing.map((r) => r.id)));
|
|
29309
|
-
const
|
|
29310
|
-
const stopNote = truncated ?? (result.stopReason === "end_turn" ? void 0 : `stop: ${result.stopReason}`);
|
|
30047
|
+
const stopNote = result.stopReason === "end_turn" ? void 0 : `stop: ${result.stopReason}`;
|
|
29311
30048
|
if (!parsed.ok) {
|
|
29312
|
-
const why =
|
|
30049
|
+
const why = stopNote ? `${parsed.error}; ${stopNote}` : parsed.error;
|
|
29313
30050
|
warn(`reflection output rejected (${why}); nothing written`);
|
|
29314
30051
|
return;
|
|
29315
30052
|
}
|
|
@@ -29380,6 +30117,7 @@ var init_reflection = __esm({
|
|
|
29380
30117
|
init_authz();
|
|
29381
30118
|
init_runEvents();
|
|
29382
30119
|
init_llmOutput();
|
|
30120
|
+
init_route();
|
|
29383
30121
|
init_engine();
|
|
29384
30122
|
init_scorer();
|
|
29385
30123
|
init_scope2();
|
|
@@ -29622,10 +30360,13 @@ function scheduleReflection(input) {
|
|
|
29622
30360
|
const info = (m) => console.log(`[memory] ${input.threadKey} ${m}`);
|
|
29623
30361
|
let provider;
|
|
29624
30362
|
let model;
|
|
30363
|
+
let capField;
|
|
29625
30364
|
try {
|
|
29626
|
-
const
|
|
30365
|
+
const modelRef3 = input.cfg.model ?? input.runModelRef;
|
|
30366
|
+
const ref = parseModelRef(modelRef3);
|
|
29627
30367
|
provider = input.providers.get(ref.provider);
|
|
29628
30368
|
model = ref.model;
|
|
30369
|
+
capField = resolveModelCard(modelRef3, input.providerBlocks ?? {}, installedModelRegistry).capField;
|
|
29629
30370
|
} catch (err2) {
|
|
29630
30371
|
warn(`reflection skipped: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
29631
30372
|
return;
|
|
@@ -29637,6 +30378,7 @@ function scheduleReflection(input) {
|
|
|
29637
30378
|
provider,
|
|
29638
30379
|
model,
|
|
29639
30380
|
...effort2.request ? { effort: effort2.request.effort, effortWord: effort2.request.effortWord } : {},
|
|
30381
|
+
...capField !== void 0 ? { capField } : {},
|
|
29640
30382
|
store: selectMemoryStore(input.cfg, input.store),
|
|
29641
30383
|
scopeKeys: requestScopeKeys(input.organization, input.userId, { channelId: input.channelId, repo: input.repo }),
|
|
29642
30384
|
actor: reflectionActor(input.actor, { channelId: input.channelId, repo: input.repo }),
|
|
@@ -29693,6 +30435,8 @@ var init_memory = __esm({
|
|
|
29693
30435
|
"use strict";
|
|
29694
30436
|
init_provider();
|
|
29695
30437
|
init_turnEffort();
|
|
30438
|
+
init_installedModelRegistry();
|
|
30439
|
+
init_modelCard();
|
|
29696
30440
|
init_scorer();
|
|
29697
30441
|
init_scope2();
|
|
29698
30442
|
init_stores();
|
|
@@ -31208,7 +31952,7 @@ ${line4}` : ""}`
|
|
|
31208
31952
|
});
|
|
31209
31953
|
|
|
31210
31954
|
// ../../src/core/reviewAbridge.ts
|
|
31211
|
-
import { resolve as
|
|
31955
|
+
import { resolve as resolve10 } from "node:path";
|
|
31212
31956
|
function meatArtifactOf(record2) {
|
|
31213
31957
|
return record2.events.find((e) => isReadingDiff(e) && e.poweredBy === "meat");
|
|
31214
31958
|
}
|
|
@@ -31253,7 +31997,7 @@ function reviewAbridgerFromConfig(config, store, secrets, env, dataDir, warn) {
|
|
|
31253
31997
|
github: () => github,
|
|
31254
31998
|
meat: meatOnHost({
|
|
31255
31999
|
apiKey: () => anthropicApiKey(config().providers, secrets),
|
|
31256
|
-
cacheDir:
|
|
32000
|
+
cacheDir: resolve10(dataDir, "meat-cache"),
|
|
31257
32001
|
hostEnv: { PATH: env.PATH, HOME: env.HOME }
|
|
31258
32002
|
}),
|
|
31259
32003
|
defaultModel: () => {
|
|
@@ -31725,6 +32469,8 @@ function assembleRunRecord(input) {
|
|
|
31725
32469
|
...seal?.replyNote !== void 0 ? { replyNote: seal.replyNote } : {},
|
|
31726
32470
|
...snap !== null ? { stepCount: snap.stepCount } : {},
|
|
31727
32471
|
status: input.status,
|
|
32472
|
+
...snap?.liveState !== void 0 ? { liveState: snap.liveState } : {},
|
|
32473
|
+
...snap?.liveStateSeq !== void 0 ? { liveStateSeq: snap.liveStateSeq } : {},
|
|
31728
32474
|
eventCount: Math.max(snap?.eventCount ?? atFinish.length, seal?.eventCount ?? 0),
|
|
31729
32475
|
storedEventCount: events.length,
|
|
31730
32476
|
truncated: false,
|
|
@@ -31908,43 +32654,6 @@ var init_record = __esm({
|
|
|
31908
32654
|
}
|
|
31909
32655
|
});
|
|
31910
32656
|
|
|
31911
|
-
// ../../src/core/plane/decide.ts
|
|
31912
|
-
function endingCauseWords(cause) {
|
|
31913
|
-
switch (cause) {
|
|
31914
|
-
case "completed":
|
|
31915
|
-
return "it completed";
|
|
31916
|
-
case "failed":
|
|
31917
|
-
return "it failed";
|
|
31918
|
-
case "stopped":
|
|
31919
|
-
return "it was stopped";
|
|
31920
|
-
case "withdrawn":
|
|
31921
|
-
return "its wait was withdrawn";
|
|
31922
|
-
case "refused":
|
|
31923
|
-
return "its admission was refused";
|
|
31924
|
-
case "lease_lapsed":
|
|
31925
|
-
return "its lease lapsed with no heartbeat";
|
|
31926
|
-
case "resident_replaced":
|
|
31927
|
-
return "the resident container running it was replaced";
|
|
31928
|
-
case "runner_gone":
|
|
31929
|
-
return "the runner instance driving it is gone";
|
|
31930
|
-
}
|
|
31931
|
-
}
|
|
31932
|
-
function isReissueSteerText(text) {
|
|
31933
|
-
return /^the model provider .+ is answering again — re-issue the held turn and continue$/.test(text.trim());
|
|
31934
|
-
}
|
|
31935
|
-
function waitingWords(waiting2) {
|
|
31936
|
-
if (waiting2.length === 0) return "its turn";
|
|
31937
|
-
return waiting2.map(
|
|
31938
|
-
(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`
|
|
31939
|
-
).join(", then ");
|
|
31940
|
-
}
|
|
31941
|
-
var init_decide = __esm({
|
|
31942
|
-
"../../src/core/plane/decide.ts"() {
|
|
31943
|
-
"use strict";
|
|
31944
|
-
init_budgets();
|
|
31945
|
-
}
|
|
31946
|
-
});
|
|
31947
|
-
|
|
31948
32657
|
// ../../src/core/runsService.ts
|
|
31949
32658
|
function runResource(view) {
|
|
31950
32659
|
return {
|
|
@@ -31981,6 +32690,8 @@ function ledgerView(row2, events) {
|
|
|
31981
32690
|
...m.repo !== void 0 ? { repo: m.repo } : {},
|
|
31982
32691
|
startedAt: row2.startedAt,
|
|
31983
32692
|
finished: false,
|
|
32693
|
+
...row2.liveState !== void 0 ? { liveState: row2.liveState } : {},
|
|
32694
|
+
...row2.liveStateSeq !== void 0 ? { liveStateSeq: row2.liveStateSeq } : {},
|
|
31984
32695
|
eventCount: events.length,
|
|
31985
32696
|
...activity !== void 0 ? { activity } : {},
|
|
31986
32697
|
...m.sourceUrl !== void 0 ? { sourceUrl: m.sourceUrl } : {},
|
|
@@ -32019,6 +32730,8 @@ function liveView(s) {
|
|
|
32019
32730
|
...s.stepCount !== void 0 ? { stepCount: s.stepCount } : {},
|
|
32020
32731
|
...s.schema !== void 0 ? { schema: s.schema } : {},
|
|
32021
32732
|
...s.status !== void 0 ? { status: s.status } : {},
|
|
32733
|
+
...s.liveState !== void 0 ? { liveState: s.liveState } : {},
|
|
32734
|
+
...s.liveStateSeq !== void 0 ? { liveStateSeq: s.liveStateSeq } : {},
|
|
32022
32735
|
eventCount: s.eventCount,
|
|
32023
32736
|
...s.stop ? { stop: s.stop } : {},
|
|
32024
32737
|
...s.activity !== void 0 ? { activity: s.activity } : {},
|
|
@@ -32116,7 +32829,7 @@ function createRunsService(deps) {
|
|
|
32116
32829
|
const prices = deps.prices ?? NO_PRICES;
|
|
32117
32830
|
const clock4 = deps.clock ?? systemClock;
|
|
32118
32831
|
const warn = deps.warn ?? ((m) => console.warn(m));
|
|
32119
|
-
const
|
|
32832
|
+
const describe13 = (err2) => err2 instanceof Error ? err2.message : String(err2);
|
|
32120
32833
|
let listing;
|
|
32121
32834
|
const liveRows = () => {
|
|
32122
32835
|
if (!ledger) return null;
|
|
@@ -32136,7 +32849,7 @@ function createRunsService(deps) {
|
|
|
32136
32849
|
try {
|
|
32137
32850
|
rows = await pending2;
|
|
32138
32851
|
} catch (err2) {
|
|
32139
|
-
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)}`);
|
|
32140
32853
|
return [];
|
|
32141
32854
|
}
|
|
32142
32855
|
const foreign = rows.filter((row2) => !registry.getById(row2.runId));
|
|
@@ -32146,7 +32859,7 @@ function createRunsService(deps) {
|
|
|
32146
32859
|
try {
|
|
32147
32860
|
events = await ledger.readEvents(row2.runId);
|
|
32148
32861
|
} catch (err2) {
|
|
32149
|
-
warn(`[runs] run ledger events read failed for ${row2.runId}: ${
|
|
32862
|
+
warn(`[runs] run ledger events read failed for ${row2.runId}: ${describe13(err2)}`);
|
|
32150
32863
|
}
|
|
32151
32864
|
return ledgerView(row2, events);
|
|
32152
32865
|
})
|
|
@@ -32160,7 +32873,7 @@ function createRunsService(deps) {
|
|
|
32160
32873
|
if (!row2) return null;
|
|
32161
32874
|
return { row: row2, events: await ledger.readEvents(id) };
|
|
32162
32875
|
} catch (err2) {
|
|
32163
|
-
warn(`[runs] run ledger read failed for ${id}: ${
|
|
32876
|
+
warn(`[runs] run ledger read failed for ${id}: ${describe13(err2)}`);
|
|
32164
32877
|
return null;
|
|
32165
32878
|
}
|
|
32166
32879
|
};
|
|
@@ -32183,7 +32896,7 @@ function createRunsService(deps) {
|
|
|
32183
32896
|
activity: row2.state === "waiting" ? `queued at position ${row2.position} \u2014 waiting on ${waiting2}` : row2.state === "admitted" ? "admitted \u2014 starting" : "withdrawn"
|
|
32184
32897
|
};
|
|
32185
32898
|
} catch (err2) {
|
|
32186
|
-
warn(`[runs] plane queued read failed for ${id}: ${
|
|
32899
|
+
warn(`[runs] plane queued read failed for ${id}: ${describe13(err2)}`);
|
|
32187
32900
|
return null;
|
|
32188
32901
|
}
|
|
32189
32902
|
};
|
|
@@ -32201,7 +32914,7 @@ function createRunsService(deps) {
|
|
|
32201
32914
|
row2 = await storeSummary(id);
|
|
32202
32915
|
} catch (err2) {
|
|
32203
32916
|
warn(
|
|
32204
|
-
`[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)}`
|
|
32205
32918
|
);
|
|
32206
32919
|
return {};
|
|
32207
32920
|
}
|
|
@@ -32246,12 +32959,12 @@ function createRunsService(deps) {
|
|
|
32246
32959
|
if (marked.ok) runnerStopped = true;
|
|
32247
32960
|
else warn(`[runs] the runner's stop mark was refused for ${id} (${marked.reason})`);
|
|
32248
32961
|
} catch (err2) {
|
|
32249
|
-
warn(`[runs] the runner's stop mark failed for ${id}: ${
|
|
32962
|
+
warn(`[runs] the runner's stop mark failed for ${id}: ${describe13(err2)}`);
|
|
32250
32963
|
}
|
|
32251
32964
|
try {
|
|
32252
32965
|
unitRows = await units.listUnits(instanceId);
|
|
32253
32966
|
} catch (err2) {
|
|
32254
|
-
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)}`);
|
|
32255
32968
|
}
|
|
32256
32969
|
}
|
|
32257
32970
|
registry.publish(id, { type: "answer", text: hostedSealAnswer(unitRows, runnerStopped), at: clock4() });
|
|
@@ -32297,7 +33010,7 @@ function createRunsService(deps) {
|
|
|
32297
33010
|
if (!done.ok) warn(`[runs] run ledger finish refused for ${id} (${done.reason ?? "unknown"})`);
|
|
32298
33011
|
}
|
|
32299
33012
|
} catch (err2) {
|
|
32300
|
-
warn(`[runs] run ledger finish failed for ${id}: ${
|
|
33013
|
+
warn(`[runs] run ledger finish failed for ${id}: ${describe13(err2)}`);
|
|
32301
33014
|
}
|
|
32302
33015
|
}
|
|
32303
33016
|
return { ok: true, value: { id, mode: "hard", state: "stopping" } };
|
|
@@ -32476,7 +33189,7 @@ function createRunsService(deps) {
|
|
|
32476
33189
|
const r = await ledger.requestStop(id, mode);
|
|
32477
33190
|
if (r.ok) return { ok: true, value: { id, mode, state: "stopping" } };
|
|
32478
33191
|
} catch (err2) {
|
|
32479
|
-
warn(`[runs] run ledger stop failed for ${id}: ${
|
|
33192
|
+
warn(`[runs] run ledger stop failed for ${id}: ${describe13(err2)}`);
|
|
32480
33193
|
}
|
|
32481
33194
|
}
|
|
32482
33195
|
if (await storeSummary(id)) return conflict;
|
|
@@ -32486,7 +33199,7 @@ function createRunsService(deps) {
|
|
|
32486
33199
|
if (r.withdrawn) return { ok: true, value: { id, mode, state: "withdrawn" } };
|
|
32487
33200
|
if (await ledger.planeQueued(id) !== null) return conflict;
|
|
32488
33201
|
} catch (err2) {
|
|
32489
|
-
warn(`[runs] plane withdraw failed for ${id}: ${
|
|
33202
|
+
warn(`[runs] plane withdraw failed for ${id}: ${describe13(err2)}`);
|
|
32490
33203
|
}
|
|
32491
33204
|
}
|
|
32492
33205
|
return notFound;
|
|
@@ -34417,6 +35130,11 @@ var init_runLedgerWorker = __esm({
|
|
|
34417
35130
|
if (events.length === 0) return { ok: true };
|
|
34418
35131
|
return this.fenceResult(await this.post("/runs/append", { storeKey: this.opts.storeKey, runId: runId3, gen, events }));
|
|
34419
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
|
+
}
|
|
34420
35138
|
async setState(runId3, gen, state) {
|
|
34421
35139
|
this.checkIds(runId3, gen);
|
|
34422
35140
|
return this.fenceResult(await this.post("/runs/state", { storeKey: this.opts.storeKey, runId: runId3, gen, state }));
|
|
@@ -34611,7 +35329,7 @@ var init_githubRepoInspect = __esm({
|
|
|
34611
35329
|
});
|
|
34612
35330
|
|
|
34613
35331
|
// ../../src/core/commandCatalogue.ts
|
|
34614
|
-
import { existsSync as
|
|
35332
|
+
import { existsSync as existsSync13, readFileSync as readFileSync15 } from "node:fs";
|
|
34615
35333
|
import { readFile as readFile2 } from "node:fs/promises";
|
|
34616
35334
|
function unstampedStatus() {
|
|
34617
35335
|
let version2 = "unknown";
|
|
@@ -34636,10 +35354,10 @@ function defaultOperations(config, secrets, caller) {
|
|
|
34636
35354
|
return null;
|
|
34637
35355
|
}
|
|
34638
35356
|
function readSource(source2) {
|
|
34639
|
-
return Promise.resolve(
|
|
35357
|
+
return Promise.resolve(readFileSync15(source2 === "-" ? 0 : source2, "utf8"));
|
|
34640
35358
|
}
|
|
34641
35359
|
async function readOptionalFile(path) {
|
|
34642
|
-
return
|
|
35360
|
+
return existsSync13(path) ? readFile2(path, "utf8") : void 0;
|
|
34643
35361
|
}
|
|
34644
35362
|
function once(provided) {
|
|
34645
35363
|
if (typeof provided !== "function") {
|
|
@@ -35116,232 +35834,6 @@ var init_trace = __esm({
|
|
|
35116
35834
|
}
|
|
35117
35835
|
});
|
|
35118
35836
|
|
|
35119
|
-
// ../../src/core/confirmations.ts
|
|
35120
|
-
import { randomUUID } from "node:crypto";
|
|
35121
|
-
import { existsSync as existsSync13, mkdirSync as mkdirSync9, readFileSync as readFileSync15, writeFileSync as writeFileSync8 } from "node:fs";
|
|
35122
|
-
import { dirname as dirname10, resolve as resolve10 } from "node:path";
|
|
35123
|
-
function newConfirmationId() {
|
|
35124
|
-
return randomUUID();
|
|
35125
|
-
}
|
|
35126
|
-
function renderOffer(offer) {
|
|
35127
|
-
if (offer.question) return `${offer.question.text}
|
|
35128
|
-
Did you mean:
|
|
35129
|
-
\`${offer.line}\`
|
|
35130
|
-
|
|
35131
|
-
${offer.question.evidence}`;
|
|
35132
|
-
return [offer.line, ...offer.risk ? [offer.risk] : []].join("\n");
|
|
35133
|
-
}
|
|
35134
|
-
function confirmationMessageOf(msg) {
|
|
35135
|
-
const { images: _images, documents: _documents, staged: _staged, ...kept } = msg;
|
|
35136
|
-
return kept;
|
|
35137
|
-
}
|
|
35138
|
-
function isRecord3(v) {
|
|
35139
|
-
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
35140
|
-
}
|
|
35141
|
-
function isMessage(v) {
|
|
35142
|
-
return isRecord3(v) && typeof v.channelId === "string" && typeof v.userId === "string" && typeof v.threadKey === "string" && typeof v.text === "string";
|
|
35143
|
-
}
|
|
35144
|
-
function isRunShape(v) {
|
|
35145
|
-
return typeof v.id === "string" && isMessage(v.message) && typeof v.command === "string" && isRecord3(v.input) && typeof v.receipt === "string" && typeof v.risk === "string" && typeof v.model === "string";
|
|
35146
|
-
}
|
|
35147
|
-
function isRedispatchShape(v) {
|
|
35148
|
-
return typeof v.id === "string" && isMessage(v.message) && typeof v.line === "string" && typeof v.evidence === "string" && typeof v.code === "string";
|
|
35149
|
-
}
|
|
35150
|
-
function parsePendingConfirmation(v) {
|
|
35151
|
-
if (!isRecord3(v)) return void 0;
|
|
35152
|
-
if (v.kind === "redispatch")
|
|
35153
|
-
return isRedispatchShape(v) ? v : void 0;
|
|
35154
|
-
if (v.kind !== void 0 && v.kind !== "run") return void 0;
|
|
35155
|
-
return isRunShape(v) ? { ...v, kind: "run" } : void 0;
|
|
35156
|
-
}
|
|
35157
|
-
function parseConfirmation(v) {
|
|
35158
|
-
if (!isRecord3(v) || typeof v.expiresAt !== "number") return void 0;
|
|
35159
|
-
const pending2 = parsePendingConfirmation(v);
|
|
35160
|
-
return pending2 ? { ...pending2, expiresAt: v.expiresAt } : void 0;
|
|
35161
|
-
}
|
|
35162
|
-
function isRefusal(v) {
|
|
35163
|
-
return typeof v === "string" && CONFIRMATION_REFUSALS.includes(v);
|
|
35164
|
-
}
|
|
35165
|
-
function judge2(rows, id, actorIds, now, kind) {
|
|
35166
|
-
const row2 = rows.get(id);
|
|
35167
|
-
if (!row2) return { ok: false, refused: "used" };
|
|
35168
|
-
if (kind === "consume" && row2.expiresAt <= now) {
|
|
35169
|
-
rows.delete(id);
|
|
35170
|
-
return { ok: false, refused: "expired", row: row2 };
|
|
35171
|
-
}
|
|
35172
|
-
if (!actorIds.includes(row2.message.userId))
|
|
35173
|
-
return kind === "consume" ? { ok: false, refused: "foreign", row: row2 } : { ok: false, refused: "foreign" };
|
|
35174
|
-
rows.delete(id);
|
|
35175
|
-
return kind === "consume" ? { ok: true, row: row2 } : { ok: true };
|
|
35176
|
-
}
|
|
35177
|
-
function replaceThreadRow(rows, row2) {
|
|
35178
|
-
for (const [id, r] of rows) if (r.message.threadKey === row2.message.threadKey) rows.delete(id);
|
|
35179
|
-
rows.set(row2.id, row2);
|
|
35180
|
-
}
|
|
35181
|
-
function threadRowId(rows, threadKey) {
|
|
35182
|
-
for (const [id, r] of rows) if (r.message.threadKey === threadKey) return id;
|
|
35183
|
-
return void 0;
|
|
35184
|
-
}
|
|
35185
|
-
function buildConfirmationStore(config, secrets, opts) {
|
|
35186
|
-
const worker = config.config.runtimeOverrides?.worker;
|
|
35187
|
-
if (!worker) return new FileConfirmationStore(opts.path);
|
|
35188
|
-
const tokenEnv = worker.tokenEnv ?? "MEMORY_TOKEN";
|
|
35189
|
-
const token2 = secrets.named(tokenEnv);
|
|
35190
|
-
if (!token2) throw new Error(`runtimeOverrides.worker is configured but ${tokenEnv} is not set`);
|
|
35191
|
-
return new WorkerConfirmationStore({
|
|
35192
|
-
baseUrl: worker.baseUrl,
|
|
35193
|
-
token: token2.reveal(),
|
|
35194
|
-
...opts.fetch ? { fetch: opts.fetch } : {}
|
|
35195
|
-
});
|
|
35196
|
-
}
|
|
35197
|
-
var CONFIRMATION_REFUSALS, UNSHOWABLE_LINE, STORE_UNREACHABLE_LINE, FileConfirmationStore, CONFIRMATION_WORKER_TIMEOUT_MS, WorkerConfirmationStore;
|
|
35198
|
-
var init_confirmations = __esm({
|
|
35199
|
-
"../../src/core/confirmations.ts"() {
|
|
35200
|
-
"use strict";
|
|
35201
|
-
init_clock();
|
|
35202
|
-
CONFIRMATION_REFUSALS = ["used", "expired", "foreign"];
|
|
35203
|
-
UNSHOWABLE_LINE = "this command carries a value that cannot be shown, so no confirmation can be offered; nothing ran";
|
|
35204
|
-
STORE_UNREACHABLE_LINE = "this command needs a confirmation click, and the confirmation store could not be reached; nothing ran \u2014 ask again for the button";
|
|
35205
|
-
FileConfirmationStore = class {
|
|
35206
|
-
path;
|
|
35207
|
-
clock;
|
|
35208
|
-
constructor(path, opts = {}) {
|
|
35209
|
-
this.path = resolve10(path);
|
|
35210
|
-
this.clock = opts.clock ?? systemClock;
|
|
35211
|
-
}
|
|
35212
|
-
read() {
|
|
35213
|
-
const rows = /* @__PURE__ */ new Map();
|
|
35214
|
-
if (!existsSync13(this.path)) return rows;
|
|
35215
|
-
const raw = JSON.parse(readFileSync15(this.path, "utf8"));
|
|
35216
|
-
for (const v of Array.isArray(raw.confirmations) ? raw.confirmations : []) {
|
|
35217
|
-
const row2 = parseConfirmation(v);
|
|
35218
|
-
if (row2) rows.set(row2.id, row2);
|
|
35219
|
-
}
|
|
35220
|
-
return rows;
|
|
35221
|
-
}
|
|
35222
|
-
write(rows) {
|
|
35223
|
-
mkdirSync9(dirname10(this.path), { recursive: true });
|
|
35224
|
-
writeFileSync8(this.path, JSON.stringify({ confirmations: [...rows.values()] }, null, 2));
|
|
35225
|
-
}
|
|
35226
|
-
async put(row2, ttlMs) {
|
|
35227
|
-
const rows = this.read();
|
|
35228
|
-
const stored = { ...row2, expiresAt: this.clock() + ttlMs };
|
|
35229
|
-
replaceThreadRow(rows, stored);
|
|
35230
|
-
this.write(rows);
|
|
35231
|
-
return stored;
|
|
35232
|
-
}
|
|
35233
|
-
async consume(id, actorIds) {
|
|
35234
|
-
const rows = this.read();
|
|
35235
|
-
const out = judge2(rows, id, actorIds, this.clock(), "consume");
|
|
35236
|
-
this.write(rows);
|
|
35237
|
-
return out;
|
|
35238
|
-
}
|
|
35239
|
-
async cancel(id, actorIds) {
|
|
35240
|
-
const rows = this.read();
|
|
35241
|
-
const out = judge2(rows, id, actorIds, this.clock(), "cancel");
|
|
35242
|
-
this.write(rows);
|
|
35243
|
-
return out;
|
|
35244
|
-
}
|
|
35245
|
-
async cancelByThread(threadKey, actorIds) {
|
|
35246
|
-
const rows = this.read();
|
|
35247
|
-
const id = threadRowId(rows, threadKey);
|
|
35248
|
-
if (id === void 0) return { ok: false, refused: "used" };
|
|
35249
|
-
const out = judge2(rows, id, actorIds, this.clock(), "cancel");
|
|
35250
|
-
this.write(rows);
|
|
35251
|
-
return out;
|
|
35252
|
-
}
|
|
35253
|
-
async pendingByThread(threadKey) {
|
|
35254
|
-
const rows = this.read();
|
|
35255
|
-
const id = threadRowId(rows, threadKey);
|
|
35256
|
-
const row2 = id === void 0 ? void 0 : rows.get(id);
|
|
35257
|
-
if (!row2 || row2.expiresAt <= this.clock()) return void 0;
|
|
35258
|
-
return row2;
|
|
35259
|
-
}
|
|
35260
|
-
describe() {
|
|
35261
|
-
return `file ${this.path}`;
|
|
35262
|
-
}
|
|
35263
|
-
};
|
|
35264
|
-
CONFIRMATION_WORKER_TIMEOUT_MS = 8e3;
|
|
35265
|
-
WorkerConfirmationStore = class {
|
|
35266
|
-
constructor(opts) {
|
|
35267
|
-
this.opts = opts;
|
|
35268
|
-
this.baseUrl = opts.baseUrl.replace(/\/+$/, "");
|
|
35269
|
-
this.fetchImpl = opts.fetch ?? fetch;
|
|
35270
|
-
}
|
|
35271
|
-
opts;
|
|
35272
|
-
baseUrl;
|
|
35273
|
-
fetchImpl;
|
|
35274
|
-
async put(row2, ttlMs) {
|
|
35275
|
-
const body = await this.post("/config/confirmations/put", {
|
|
35276
|
-
id: row2.id,
|
|
35277
|
-
threadKey: row2.message.threadKey,
|
|
35278
|
-
requester: row2.message.userId,
|
|
35279
|
-
body: row2,
|
|
35280
|
-
ttlMs
|
|
35281
|
-
});
|
|
35282
|
-
if (typeof body.expiresAt !== "number")
|
|
35283
|
-
throw new Error("confirmation store answered a put without the expiry it stamped");
|
|
35284
|
-
return { ...row2, expiresAt: body.expiresAt };
|
|
35285
|
-
}
|
|
35286
|
-
async consume(id, actorIds) {
|
|
35287
|
-
const body = await this.post("/config/confirmations/consume", { id, actorIds });
|
|
35288
|
-
const stored = isRecord3(body.row) ? body.row : void 0;
|
|
35289
|
-
const row2 = parseConfirmation(
|
|
35290
|
-
stored && isRecord3(stored.body) ? { ...stored.body, expiresAt: stored.expiresAt } : void 0
|
|
35291
|
-
);
|
|
35292
|
-
if (isRefusal(body.refused))
|
|
35293
|
-
return { ok: false, refused: body.refused, ...row2 ? { row: row2 } : {} };
|
|
35294
|
-
if (!row2) throw new Error("confirmation store answered a consume outside its contract");
|
|
35295
|
-
return { ok: true, row: row2 };
|
|
35296
|
-
}
|
|
35297
|
-
async cancel(id, actorIds) {
|
|
35298
|
-
const body = await this.post("/config/confirmations/cancel", { id, actorIds });
|
|
35299
|
-
if (body.ok === true) return { ok: true };
|
|
35300
|
-
if (body.refused === "used" || body.refused === "foreign") return { ok: false, refused: body.refused };
|
|
35301
|
-
throw new Error("confirmation store answered a cancel outside its contract");
|
|
35302
|
-
}
|
|
35303
|
-
async cancelByThread(threadKey, actorIds) {
|
|
35304
|
-
const body = await this.post("/config/confirmations/cancel-by-thread", { threadKey, actorIds });
|
|
35305
|
-
if (body.ok === true) return { ok: true };
|
|
35306
|
-
if (body.refused === "used" || body.refused === "foreign") return { ok: false, refused: body.refused };
|
|
35307
|
-
throw new Error("confirmation store answered a cancel-by-thread outside its contract");
|
|
35308
|
-
}
|
|
35309
|
-
async pendingByThread(threadKey) {
|
|
35310
|
-
const body = await this.post("/config/confirmations/pending-by-thread", { threadKey });
|
|
35311
|
-
if (body.row === null) return void 0;
|
|
35312
|
-
const stored = isRecord3(body.row) ? body.row : void 0;
|
|
35313
|
-
const row2 = parseConfirmation(
|
|
35314
|
-
stored && isRecord3(stored.body) ? { ...stored.body, expiresAt: stored.expiresAt } : void 0
|
|
35315
|
-
);
|
|
35316
|
-
if (!row2) throw new Error("confirmation store answered a pending-by-thread outside its contract");
|
|
35317
|
-
return row2;
|
|
35318
|
-
}
|
|
35319
|
-
describe() {
|
|
35320
|
-
return `state Worker ${this.baseUrl} (ConfigDO confirmations)`;
|
|
35321
|
-
}
|
|
35322
|
-
async post(path, payload2) {
|
|
35323
|
-
let res;
|
|
35324
|
-
try {
|
|
35325
|
-
res = await this.fetchImpl(`${this.baseUrl}${path}`, {
|
|
35326
|
-
method: "POST",
|
|
35327
|
-
headers: { authorization: `Bearer ${this.opts.token}`, "content-type": "application/json" },
|
|
35328
|
-
body: JSON.stringify(payload2),
|
|
35329
|
-
signal: AbortSignal.timeout(CONFIRMATION_WORKER_TIMEOUT_MS)
|
|
35330
|
-
});
|
|
35331
|
-
} catch (err2) {
|
|
35332
|
-
throw new Error(`confirmation store unreachable: ${err2 instanceof Error ? err2.message : String(err2)}`, {
|
|
35333
|
-
cause: err2
|
|
35334
|
-
});
|
|
35335
|
-
}
|
|
35336
|
-
if (!res.ok) throw new Error(`confirmation store answered HTTP ${res.status} on ${path}`);
|
|
35337
|
-
const body = await res.json().catch(() => void 0);
|
|
35338
|
-
if (!isRecord3(body)) throw new Error(`confirmation store returned a non-JSON body on ${path}`);
|
|
35339
|
-
return body;
|
|
35340
|
-
}
|
|
35341
|
-
};
|
|
35342
|
-
}
|
|
35343
|
-
});
|
|
35344
|
-
|
|
35345
35837
|
// ../../src/core/markdownDocument.ts
|
|
35346
35838
|
function toMarkdownDocument(text) {
|
|
35347
35839
|
return text.replace(/[\uE000\uE001]/g, "").split(/(```[\s\S]*?```)/g).map((seg, i) => i % 2 === 1 ? seg : hardBreaks(convertProse(seg))).join("");
|
|
@@ -35471,6 +35963,9 @@ function activityLine(e) {
|
|
|
35471
35963
|
case "lease":
|
|
35472
35964
|
return "lease started";
|
|
35473
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.
|
|
35474
35969
|
case "skill_use":
|
|
35475
35970
|
return `\u{1F4DA} skill ${e.skill} loaded`;
|
|
35476
35971
|
case "artifact":
|
|
@@ -36414,7 +36909,7 @@ async function attachRoundWorkspace(input) {
|
|
|
36414
36909
|
...input.round.stopSignal !== void 0 ? { stopSignal: input.round.stopSignal } : {},
|
|
36415
36910
|
...input.round.remainingMs !== void 0 ? { remainingMs: input.round.remainingMs } : {},
|
|
36416
36911
|
...input.round.requester !== void 0 ? { requester: input.round.requester } : {},
|
|
36417
|
-
...input.round.
|
|
36912
|
+
...input.round.onLiveStateObservation !== void 0 ? { onLiveStateObservation: input.round.onLiveStateObservation } : {}
|
|
36418
36913
|
},
|
|
36419
36914
|
input.span
|
|
36420
36915
|
);
|
|
@@ -36463,30 +36958,62 @@ function checkPrHeadPreflight(input) {
|
|
|
36463
36958
|
async function guardAttachedHead(input) {
|
|
36464
36959
|
const expected = normalizeHead(input.expectedHeadSha);
|
|
36465
36960
|
if (!expected) return { outcome: "unverified" };
|
|
36466
|
-
const attached = normalizeHead(input.attached.sha);
|
|
36467
|
-
const source2 = input.attached.source ?? "workspace-observed";
|
|
36468
36961
|
const where = `${input.pr.repo}#${input.pr.number}`;
|
|
36469
|
-
const
|
|
36470
|
-
|
|
36471
|
-
|
|
36472
|
-
|
|
36962
|
+
const namedSource = (observed) => {
|
|
36963
|
+
const source3 = observed.source ?? "workspace-observed";
|
|
36964
|
+
const branch2 = observed.ref ?? input.fallbackRef;
|
|
36965
|
+
return source3 === "resident binding" ? branch2 ? `${source3} for ${branch2}` : source3 : branch2 ? `${source3} HEAD for ${branch2}` : `${source3} HEAD`;
|
|
36966
|
+
};
|
|
36967
|
+
const first = normalizeHead(input.attached.sha);
|
|
36968
|
+
if (first && sameCommit(expected, first)) return { outcome: "verified" };
|
|
36969
|
+
if (first) {
|
|
36970
|
+
const current = normalizeHead(await input.fetchPrHead(input.pr).catch(() => void 0));
|
|
36971
|
+
if (current && sameCommit(first, current)) {
|
|
36972
|
+
console.log(
|
|
36973
|
+
`[review] ${input.logKey} PR head moved since resolution: ${expected} \u2192 ${current}; the ${namedSource(input.attached)} is at the current head \u2014 reviewing it (${where})`
|
|
36974
|
+
);
|
|
36975
|
+
return { outcome: "adopted", headSha: current };
|
|
36976
|
+
}
|
|
36977
|
+
}
|
|
36978
|
+
let retried;
|
|
36979
|
+
let reprovisionFailed = false;
|
|
36980
|
+
try {
|
|
36981
|
+
retried = await input.reprovision(expected);
|
|
36982
|
+
} catch {
|
|
36983
|
+
reprovisionFailed = true;
|
|
36984
|
+
retried = { sha: void 0 };
|
|
36985
|
+
}
|
|
36986
|
+
const checked = normalizeHead(retried.sha);
|
|
36987
|
+
if (checked && sameCommit(expected, checked)) {
|
|
36988
|
+
console.log(`[review] ${input.logKey} workspace reprovisioned at reviewed head ${expected} (${where})`);
|
|
36989
|
+
return { outcome: "verified" };
|
|
36990
|
+
}
|
|
36991
|
+
const initial = first ? `the initial ${namedSource(input.attached)} was at ${first}` : `the initial ${namedSource(input.attached)} could not be read`;
|
|
36992
|
+
if (reprovisionFailed) {
|
|
36993
|
+
console.log(
|
|
36994
|
+
`[review] ${input.logKey} not started: ${initial}; reprovision failed before retry HEAD observation, expected reviewed head ${expected} (${where})`
|
|
36995
|
+
);
|
|
36473
36996
|
return {
|
|
36474
36997
|
outcome: "refused",
|
|
36475
|
-
reply: `\u{1F500} Review of ${where} not started: ${
|
|
36998
|
+
reply: `\u{1F500} Review of ${where} not started: ${initial}, and the automatic reprovision failed before a retry HEAD could be observed; the expected reviewed head is ${expected}. It is not a finding, and nothing was posted to GitHub.`
|
|
36476
36999
|
};
|
|
36477
37000
|
}
|
|
36478
|
-
|
|
36479
|
-
|
|
36480
|
-
if (current && sameCommit(attached, current)) {
|
|
37001
|
+
const source2 = namedSource(retried);
|
|
37002
|
+
if (!checked) {
|
|
36481
37003
|
console.log(
|
|
36482
|
-
`[review] ${input.logKey}
|
|
37004
|
+
`[review] ${input.logKey} not started: ${initial}; ${source2} unreadable after reprovision, expected reviewed head ${expected} (${where})`
|
|
36483
37005
|
);
|
|
36484
|
-
return {
|
|
37006
|
+
return {
|
|
37007
|
+
outcome: "refused",
|
|
37008
|
+
reply: `\u{1F500} Review of ${where} not started: ${initial}, and the ${source2} could not be read after one automatic reprovision, so it could not be verified; the expected reviewed head is ${expected}. It is not a finding, and nothing was posted to GitHub.`
|
|
37009
|
+
};
|
|
36485
37010
|
}
|
|
36486
|
-
console.log(
|
|
37011
|
+
console.log(
|
|
37012
|
+
`[review] ${input.logKey} not started: ${source2} ${checked} after reprovision, expected reviewed head ${expected} (${where})`
|
|
37013
|
+
);
|
|
36487
37014
|
return {
|
|
36488
37015
|
outcome: "refused",
|
|
36489
|
-
reply: `\u{1F500} Review of ${where} not started: the ${
|
|
37016
|
+
reply: `\u{1F500} Review of ${where} not started: after one automatic reprovision, the ${source2} is at ${checked}, but the expected reviewed head is ${expected}. It is not a finding, and nothing was posted to GitHub.`
|
|
36490
37017
|
};
|
|
36491
37018
|
}
|
|
36492
37019
|
function makeSystemComposer(input) {
|
|
@@ -36964,14 +37491,19 @@ async function authorizePrHead(ctx) {
|
|
|
36964
37491
|
}
|
|
36965
37492
|
return { kind: "allowed" };
|
|
36966
37493
|
}
|
|
37494
|
+
function reviewCheckoutFacts(repoCtx) {
|
|
37495
|
+
return {
|
|
37496
|
+
remote: `https://github.com/${repoCtx.repo}.git`,
|
|
37497
|
+
helper: `!f() { test -n "$GH_TOKEN" || exit 1; printf '%s\\n' 'username=x-access-token' "password=$GH_TOKEN"; }; f`,
|
|
37498
|
+
refspecs: [
|
|
37499
|
+
"+HEAD:refs/remotes/origin/HEAD",
|
|
37500
|
+
`+refs/pull/${repoCtx.pr}/head:refs/remotes/origin/pull/${repoCtx.pr}/head`,
|
|
37501
|
+
...repoCtx.baseRef ? [`+refs/heads/${repoCtx.baseRef}:refs/remotes/origin/${repoCtx.baseRef}`] : []
|
|
37502
|
+
]
|
|
37503
|
+
};
|
|
37504
|
+
}
|
|
36967
37505
|
function coldReviewCheckoutCommand(repoCtx) {
|
|
36968
|
-
const remote =
|
|
36969
|
-
const helper = `!f() { test -n "$GH_TOKEN" || exit 1; printf '%s\\n' 'username=x-access-token' "password=$GH_TOKEN"; }; f`;
|
|
36970
|
-
const refspecs = [
|
|
36971
|
-
"+HEAD:refs/remotes/origin/HEAD",
|
|
36972
|
-
`+refs/pull/${repoCtx.pr}/head:refs/remotes/origin/pull/${repoCtx.pr}/head`,
|
|
36973
|
-
...repoCtx.baseRef ? [`+refs/heads/${repoCtx.baseRef}:refs/remotes/origin/${repoCtx.baseRef}`] : []
|
|
36974
|
-
];
|
|
37506
|
+
const { remote, helper, refspecs } = reviewCheckoutFacts(repoCtx);
|
|
36975
37507
|
return [
|
|
36976
37508
|
"set -eu",
|
|
36977
37509
|
"find . -mindepth 1 -maxdepth 1 ! -name attachments -exec rm -rf -- {} +",
|
|
@@ -36981,6 +37513,15 @@ function coldReviewCheckoutCommand(repoCtx) {
|
|
|
36981
37513
|
`git checkout --detach --force ${shellQuote(repoCtx.headSha)}`
|
|
36982
37514
|
].join("\n");
|
|
36983
37515
|
}
|
|
37516
|
+
function seededReviewCheckoutCommand(repoCtx, workspace) {
|
|
37517
|
+
const { helper, refspecs } = reviewCheckoutFacts(repoCtx);
|
|
37518
|
+
const git2 = `git -C ${shellQuote(workspace)}`;
|
|
37519
|
+
return [
|
|
37520
|
+
"set -eu",
|
|
37521
|
+
`${git2} -c credential.helper= -c credential.helper=${shellQuote(helper)} fetch --force --no-tags origin ${refspecs.map(shellQuote).join(" ")}`,
|
|
37522
|
+
`${git2} checkout --detach --force ${shellQuote(repoCtx.headSha)}`
|
|
37523
|
+
].join("\n");
|
|
37524
|
+
}
|
|
36984
37525
|
async function authorizeAttachedHead(deps, ctx) {
|
|
36985
37526
|
const { msg, refuse: refuse3, card, shell, closeLines, clock: clock4, agent, resume, selection, root } = ctx;
|
|
36986
37527
|
const { executor, resident, binding } = selection;
|
|
@@ -36991,7 +37532,6 @@ async function authorizeAttachedHead(deps, ctx) {
|
|
|
36991
37532
|
const pr = { repo: repoCtx.repo, number: repoCtx.pr };
|
|
36992
37533
|
const expectedHeadSha = repoCtx.headSha;
|
|
36993
37534
|
const guard = await root.span("dispatch.gate.attached_head", async (span) => {
|
|
36994
|
-
const source2 = resident && binding?.sha !== void 0 ? "resident binding" : "workspace-observed";
|
|
36995
37535
|
const command2 = selection.seeded?.workspace ? `git -C ${shellQuote(selection.seeded.workspace)} rev-parse HEAD` : "git rev-parse HEAD";
|
|
36996
37536
|
if (!resident && selection.seeded === void 0 && expectedHeadSha !== void 0) {
|
|
36997
37537
|
await executor.exec(
|
|
@@ -36999,13 +37539,48 @@ async function authorizeAttachedHead(deps, ctx) {
|
|
|
36999
37539
|
{ timeoutMs: BASH_TIMEOUT_MAX_MS }
|
|
37000
37540
|
);
|
|
37001
37541
|
}
|
|
37002
|
-
const
|
|
37542
|
+
const observeHead = () => executor.exec(command2, { timeoutMs: 3e4, span }).then(parseRevParseOutput).catch(() => void 0);
|
|
37543
|
+
const sha = await observeHead();
|
|
37003
37544
|
const g = await guardAttachedHead({
|
|
37004
37545
|
pr,
|
|
37005
37546
|
expectedHeadSha,
|
|
37006
|
-
attached: { sha, ref: binding?.ref ?? repoCtx.ref, source:
|
|
37547
|
+
attached: { sha, ref: binding?.ref ?? repoCtx.ref, source: "workspace-observed" },
|
|
37007
37548
|
fallbackRef: repoCtx.ref,
|
|
37008
37549
|
fetchPrHead: deps.fetchPrHead ?? currentPrHeadSha,
|
|
37550
|
+
reprovision: async (headSha) => {
|
|
37551
|
+
if (executor.moveTo) {
|
|
37552
|
+
await executor.moveTo(headSha, { span });
|
|
37553
|
+
const observedSha = await observeHead();
|
|
37554
|
+
if (selection.binding && observedSha !== void 0) {
|
|
37555
|
+
selection.binding = {
|
|
37556
|
+
...selection.binding,
|
|
37557
|
+
ref: repoCtx.ref ?? selection.binding.ref,
|
|
37558
|
+
sha: observedSha
|
|
37559
|
+
};
|
|
37560
|
+
}
|
|
37561
|
+
return {
|
|
37562
|
+
sha: observedSha,
|
|
37563
|
+
ref: repoCtx.ref,
|
|
37564
|
+
source: "workspace-observed"
|
|
37565
|
+
};
|
|
37566
|
+
}
|
|
37567
|
+
if (selection.seeded?.workspace) {
|
|
37568
|
+
await executor.exec(
|
|
37569
|
+
seededReviewCheckoutCommand(
|
|
37570
|
+
{ ...repoCtx, repo: pr.repo, pr: pr.number, headSha },
|
|
37571
|
+
selection.seeded.workspace
|
|
37572
|
+
),
|
|
37573
|
+
{ timeoutMs: BASH_TIMEOUT_MAX_MS, span }
|
|
37574
|
+
);
|
|
37575
|
+
} else {
|
|
37576
|
+
await executor.exec(coldReviewCheckoutCommand({ ...repoCtx, repo: pr.repo, pr: pr.number, headSha }), {
|
|
37577
|
+
timeoutMs: BASH_TIMEOUT_MAX_MS,
|
|
37578
|
+
span
|
|
37579
|
+
});
|
|
37580
|
+
}
|
|
37581
|
+
const retried = await observeHead();
|
|
37582
|
+
return { sha: retried, ref: repoCtx.ref, source: "workspace-observed" };
|
|
37583
|
+
},
|
|
37009
37584
|
logKey: msg.threadKey
|
|
37010
37585
|
});
|
|
37011
37586
|
span.setAttrs({ outcome: g.outcome });
|
|
@@ -37018,14 +37593,19 @@ async function authorizeAttachedHead(deps, ctx) {
|
|
|
37018
37593
|
verifiedAtAttach = true;
|
|
37019
37594
|
headAdopted = true;
|
|
37020
37595
|
} else if (guard.outcome === "refused") {
|
|
37021
|
-
await refuse3(refusalOf("
|
|
37596
|
+
await refuse3(refusalOf("workspace_head_mismatch", guard.reply), async () => {
|
|
37022
37597
|
if (executor.release) await executor.release("always").catch(() => {
|
|
37023
37598
|
});
|
|
37024
37599
|
await card.done(
|
|
37025
|
-
shell.close({
|
|
37600
|
+
shell.close({
|
|
37601
|
+
kind: "not_started",
|
|
37602
|
+
icon: "\u{1F500}",
|
|
37603
|
+
reason: "workspace head mismatch",
|
|
37604
|
+
...closeLines(clock4(), false)
|
|
37605
|
+
})
|
|
37026
37606
|
);
|
|
37027
37607
|
});
|
|
37028
|
-
return { kind: "refused", reason: "
|
|
37608
|
+
return { kind: "refused", reason: "workspace_head_mismatch" };
|
|
37029
37609
|
}
|
|
37030
37610
|
}
|
|
37031
37611
|
return { kind: "allowed", repoCtx, verifiedAtAttach, headAdopted };
|
|
@@ -37418,6 +37998,10 @@ var init_threadAdmission = __esm({
|
|
|
37418
37998
|
get size() {
|
|
37419
37999
|
return this.pending.length;
|
|
37420
38000
|
}
|
|
38001
|
+
/** The ledger seqs of the follow-ups still pending, oldest first. */
|
|
38002
|
+
get pendingSeqs() {
|
|
38003
|
+
return this.pending.flatMap((input) => input.ledgerSeq !== void 0 ? [input.ledgerSeq] : []);
|
|
38004
|
+
}
|
|
37421
38005
|
};
|
|
37422
38006
|
ThreadAdmission = class {
|
|
37423
38007
|
live = /* @__PURE__ */ new Map();
|
|
@@ -38085,279 +38669,6 @@ var init_commandChat = __esm({
|
|
|
38085
38669
|
}
|
|
38086
38670
|
});
|
|
38087
38671
|
|
|
38088
|
-
// ../../src/core/dispatch/handBack.ts
|
|
38089
|
-
function renderHandBackLine(line4) {
|
|
38090
|
-
return `${HAND_BACK_PREFIX}
|
|
38091
|
-
\`${line4}\``;
|
|
38092
|
-
}
|
|
38093
|
-
var HAND_BACK_PREFIX;
|
|
38094
|
-
var init_handBack = __esm({
|
|
38095
|
-
"../../src/core/dispatch/handBack.ts"() {
|
|
38096
|
-
"use strict";
|
|
38097
|
-
HAND_BACK_PREFIX = "To run this:";
|
|
38098
|
-
}
|
|
38099
|
-
});
|
|
38100
|
-
|
|
38101
|
-
// ../../src/core/statusCardFrame.ts
|
|
38102
|
-
function activityText(activity) {
|
|
38103
|
-
if (!activity) return void 0;
|
|
38104
|
-
if (activity.kind === "line") return activity.text;
|
|
38105
|
-
return `\u2192 $ ${activity.command.replace(/\s+/g, " ").trim()}`;
|
|
38106
|
-
}
|
|
38107
|
-
function createCardShell(opts) {
|
|
38108
|
-
const verbosity2 = opts.verbosity ?? DEFAULT_VERBOSITY;
|
|
38109
|
-
const notes = [];
|
|
38110
|
-
let link = opts.link;
|
|
38111
|
-
let frame2 = 0;
|
|
38112
|
-
let finishedAt;
|
|
38113
|
-
let setupLabel;
|
|
38114
|
-
const lead = opts.lead ?? [];
|
|
38115
|
-
const base = () => opts.model !== void 0 && shows(verbosity2, "verbose") ? `${opts.label} on \`${opts.model}\`` : opts.label;
|
|
38116
|
-
const label = () => [base(), ...notes.filter((n2) => shows(verbosity2, n2.level)).map((n2) => n2.text)].join(" \xB7 ");
|
|
38117
|
-
const elapsed2 = () => formatDuration((finishedAt ?? opts.now()) - opts.startedAt, "clock");
|
|
38118
|
-
const headline = (icon) => `${icon} ${label()} \xB7 ${elapsed2()}`;
|
|
38119
|
-
const closeDetail = (close, own) => [...shows(verbosity2, "debug") ? [close.shape, close.queued] : [], own].filter(Boolean).join("\n") || void 0;
|
|
38120
|
-
return {
|
|
38121
|
-
get label() {
|
|
38122
|
-
return label();
|
|
38123
|
-
},
|
|
38124
|
-
note(level, text) {
|
|
38125
|
-
notes.push({ level, text });
|
|
38126
|
-
},
|
|
38127
|
-
setLink(next) {
|
|
38128
|
-
link = next;
|
|
38129
|
-
},
|
|
38130
|
-
freeze(at) {
|
|
38131
|
-
finishedAt = at;
|
|
38132
|
-
},
|
|
38133
|
-
setSetupLabel(next) {
|
|
38134
|
-
setupLabel = next;
|
|
38135
|
-
},
|
|
38136
|
-
ack() {
|
|
38137
|
-
const detail = lead.join("\n");
|
|
38138
|
-
return { title: `\u{1F440} ${label()} \xB7 preparing workspace\u2026`, ...detail ? { detail } : {} };
|
|
38139
|
-
},
|
|
38140
|
-
live(parts = {}) {
|
|
38141
|
-
const glyph = SPINNER_GLYPHS[frame2++ % SPINNER_GLYPHS.length];
|
|
38142
|
-
const detail = [...lead, ...parts.detail ?? []].filter(Boolean).join("\n");
|
|
38143
|
-
return {
|
|
38144
|
-
title: headline(glyph) + (setupLabel ? ` \u2014 ${setupLabel}` : "") + (parts.suffix ?? "") + (parts.notice ? ` \xB7 ${parts.notice}` : ""),
|
|
38145
|
-
detail: detail || void 0,
|
|
38146
|
-
...parts.activity ? { activity: parts.activity } : {},
|
|
38147
|
-
link
|
|
38148
|
-
};
|
|
38149
|
-
},
|
|
38150
|
-
close(close) {
|
|
38151
|
-
const detail = closeDetail(close, close.kind === "done" ? close.detail : void 0);
|
|
38152
|
-
switch (close.kind) {
|
|
38153
|
-
case "done":
|
|
38154
|
-
return { title: headline(close.icon), detail, link };
|
|
38155
|
-
case "not_started":
|
|
38156
|
-
return { title: `${close.icon} ${label()} \xB7 not started (${close.reason}) \xB7 ${elapsed2()}`, detail };
|
|
38157
|
-
case "refused":
|
|
38158
|
-
return { title: `${close.icon} ${label()} \xB7 ${close.reason} \xB7 ${elapsed2()}`, detail };
|
|
38159
|
-
case "setup_failed":
|
|
38160
|
-
return { title: `\u274C setup failed \xB7 ${close.reason} \xB7 ${elapsed2()}`, detail };
|
|
38161
|
-
}
|
|
38162
|
-
}
|
|
38163
|
-
};
|
|
38164
|
-
}
|
|
38165
|
-
var SPINNER_GLYPHS, LIVE_CARD_PREFIXES, ROUTE_REASON_PREFIX;
|
|
38166
|
-
var init_statusCardFrame = __esm({
|
|
38167
|
-
"../../src/core/statusCardFrame.ts"() {
|
|
38168
|
-
"use strict";
|
|
38169
|
-
init_formatDuration();
|
|
38170
|
-
init_verbosity();
|
|
38171
|
-
SPINNER_GLYPHS = ["\u25D0", "\u25D3", "\u25D1", "\u25D2"];
|
|
38172
|
-
LIVE_CARD_PREFIXES = [...SPINNER_GLYPHS, "\u{1F440}"];
|
|
38173
|
-
ROUTE_REASON_PREFIX = "route reason:";
|
|
38174
|
-
}
|
|
38175
|
-
});
|
|
38176
|
-
|
|
38177
|
-
// ../../src/core/dispatch/route.ts
|
|
38178
|
-
function outputCapWithReasoning(visibleAnswerTokens, opts = {}) {
|
|
38179
|
-
return opts.capField !== void 0 && REASONING_COUNTING_CAP_FIELDS.has(opts.capField) ? visibleAnswerTokens + REASONING_OUTPUT_TOKEN_ALLOWANCE : visibleAnswerTokens;
|
|
38180
|
-
}
|
|
38181
|
-
function outputCapRetry(current) {
|
|
38182
|
-
return Math.max(current * 2, REASONING_OUTPUT_TOKEN_ALLOWANCE);
|
|
38183
|
-
}
|
|
38184
|
-
function routedRunsAtOnce(def, confirm, input) {
|
|
38185
|
-
const radius = input === void 0 ? blastRadius(def) : boundBlastRadius(def, input);
|
|
38186
|
-
return radius === "read" || CONFIRM_ORDER[radius] < CONFIRM_ORDER[confirm];
|
|
38187
|
-
}
|
|
38188
|
-
function routeReceipt(def, input) {
|
|
38189
|
-
return redactAndCap(chatInvocation(def, input), ROUTE_RECEIPT_CAP);
|
|
38190
|
-
}
|
|
38191
|
-
function routablePresets() {
|
|
38192
|
-
return Object.values(AGENTS).filter((a) => a.routable !== false).map(({ name, description, machine, identity: identity2, maxMinutes }) => ({
|
|
38193
|
-
name,
|
|
38194
|
-
description,
|
|
38195
|
-
machine,
|
|
38196
|
-
identity: identity2,
|
|
38197
|
-
maxMinutes
|
|
38198
|
-
}));
|
|
38199
|
-
}
|
|
38200
|
-
function routableCommands(commands) {
|
|
38201
|
-
return commands.list().filter((cmd) => CommandRegistry.exposedTo(cmd, "chat")).map((cmd) => ({
|
|
38202
|
-
id: cmd.id,
|
|
38203
|
-
effect: cmd.effect,
|
|
38204
|
-
def: cmd,
|
|
38205
|
-
tool: { name: mcpToolName(cmd.id), description: cmd.describe, inputSchema: jsonSchemaFor(cmd) }
|
|
38206
|
-
}));
|
|
38207
|
-
}
|
|
38208
|
-
function renderPresetTable(presets) {
|
|
38209
|
-
const rows = presets.map(
|
|
38210
|
-
(p) => `| \`${p.name}\` | ${oneLine(p.description)} | ${p.machine} | ${p.identity} | ${p.maxMinutes} min |`
|
|
38211
|
-
);
|
|
38212
|
-
return ["| name | what it does | machine | credential | budget |", "|---|---|---|---|---|", ...rows].join("\n");
|
|
38213
|
-
}
|
|
38214
|
-
function quoteRequest(text) {
|
|
38215
|
-
const cap = 2e3;
|
|
38216
|
-
const bent = text.replace(/<(\/?)request>/gi, "\u2039$1request\u203A");
|
|
38217
|
-
if (bent.length <= cap) return bent;
|
|
38218
|
-
return `${bent.slice(0, cap)}
|
|
38219
|
-
\u2026[truncated: ${bent.length - cap} more characters]`;
|
|
38220
|
-
}
|
|
38221
|
-
function providerStructuredModel(provider, model, opts = {}) {
|
|
38222
|
-
const forced = (opts.answer ?? "tool") === "tool";
|
|
38223
|
-
return async (prompt, call2) => {
|
|
38224
|
-
const tools = [prompt.tool, ...prompt.tools ?? []];
|
|
38225
|
-
const toolChoice = prompt.open ? void 0 : tools.length > 1 ? { type: "any" } : { type: "tool", name: prompt.tool.name };
|
|
38226
|
-
const messages = [
|
|
38227
|
-
{ role: "user", content: [{ type: "text", text: prompt.user }] },
|
|
38228
|
-
...(prompt.retries ?? []).flatMap((r) => [
|
|
38229
|
-
{ role: "assistant", content: [{ type: "text", text: r.answer }] },
|
|
38230
|
-
{ role: "user", content: [{ type: "text", text: r.violation }] }
|
|
38231
|
-
])
|
|
38232
|
-
];
|
|
38233
|
-
const result = await provider.complete({
|
|
38234
|
-
model,
|
|
38235
|
-
system: prompt.system,
|
|
38236
|
-
messages,
|
|
38237
|
-
maxTokens: call2.maxTokens,
|
|
38238
|
-
signal: call2.signal,
|
|
38239
|
-
// The caller's configured effort, card-decided (`turnEffort`): intake's
|
|
38240
|
-
// `intake.effort` or the operator's `defaults.efforts.general`. Absent →
|
|
38241
|
-
// the model's own default.
|
|
38242
|
-
...opts.effort ? { effort: opts.effort.effort, effortWord: opts.effort.effortWord } : {},
|
|
38243
|
-
...forced ? { tools, toolChoice } : {}
|
|
38244
|
-
});
|
|
38245
|
-
if (result.stopReason === "max_tokens") throw new OutputCapError(call2.maxTokens);
|
|
38246
|
-
const calls = result.content.filter(
|
|
38247
|
-
(p) => p.type === "tool_use"
|
|
38248
|
-
);
|
|
38249
|
-
if (calls.length > 1) throw new MultiToolCallError(calls.map((c) => ({ tool: c.name, input: c.input })));
|
|
38250
|
-
if (calls.length === 1) return { tool: calls[0].name, input: calls[0].input };
|
|
38251
|
-
return result.content.filter((p) => p.type === "text").map((p) => p.text).join("");
|
|
38252
|
-
};
|
|
38253
|
-
}
|
|
38254
|
-
async function mintConfirmationOffer(args) {
|
|
38255
|
-
const { io, store, msg, origin, def, input, receipt, model } = args;
|
|
38256
|
-
if (!io.offer || !store) return { kind: "no_click" };
|
|
38257
|
-
const line4 = chatInvocation(def, input);
|
|
38258
|
-
if (redactSecrets(line4) !== line4) return { kind: "unshowable" };
|
|
38259
|
-
const risk = def.annotations?.risk?.(input, origin) ?? "";
|
|
38260
|
-
let row2;
|
|
38261
|
-
try {
|
|
38262
|
-
row2 = await store.put(
|
|
38263
|
-
{
|
|
38264
|
-
kind: "run",
|
|
38265
|
-
id: newConfirmationId(),
|
|
38266
|
-
message: confirmationMessageOf(msg),
|
|
38267
|
-
command: def.id,
|
|
38268
|
-
input,
|
|
38269
|
-
receipt,
|
|
38270
|
-
risk,
|
|
38271
|
-
model
|
|
38272
|
-
},
|
|
38273
|
-
CONFIRMATION_TTL_MS
|
|
38274
|
-
);
|
|
38275
|
-
} catch (err2) {
|
|
38276
|
-
console.warn(
|
|
38277
|
-
`[route] ${msg.threadKey} confirmation store unreachable at mint, handing back: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
38278
|
-
);
|
|
38279
|
-
return { kind: "store_unreachable" };
|
|
38280
|
-
}
|
|
38281
|
-
return { kind: "offered", shown: { id: row2.id, line: line4, risk, expiresAt: row2.expiresAt } };
|
|
38282
|
-
}
|
|
38283
|
-
function redactedInput(input) {
|
|
38284
|
-
const text = (s) => redactAndCap(redactSecrets(s), 200);
|
|
38285
|
-
const leaf = (v) => {
|
|
38286
|
-
if (typeof v === "string") return text(v);
|
|
38287
|
-
if (typeof v === "number" || typeof v === "boolean" || v === null) return v;
|
|
38288
|
-
return v === void 0 ? null : text(JSON.stringify(v) ?? String(v));
|
|
38289
|
-
};
|
|
38290
|
-
const leafOrList = (v) => Array.isArray(v) ? v.map(leaf) : leaf(v);
|
|
38291
|
-
const isRecord11 = (v) => typeof v === "object" && v !== null && (Object.getPrototypeOf(v) === Object.prototype || Object.getPrototypeOf(v) === null);
|
|
38292
|
-
const entries = (v, of) => Object.fromEntries(
|
|
38293
|
-
Object.entries(v).filter(([, x]) => x !== void 0).map(([k, x]) => [k, of(x)])
|
|
38294
|
-
);
|
|
38295
|
-
const object1 = (v) => entries(v, leafOrList);
|
|
38296
|
-
const object2 = (v) => entries(v, (x) => isRecord11(x) ? object1(x) : leafOrList(x));
|
|
38297
|
-
const object3 = (v) => entries(v, (x) => isRecord11(x) ? object2(x) : leafOrList(x));
|
|
38298
|
-
return {
|
|
38299
|
-
...input.args ? { args: input.args.map(leaf) } : {},
|
|
38300
|
-
...input.options ? { options: object3(input.options) } : {}
|
|
38301
|
-
};
|
|
38302
|
-
}
|
|
38303
|
-
function routeReasonLabel(reason2, collapsed) {
|
|
38304
|
-
return `${ROUTE_REASON_PREFIX} ${reason2}${collapsed ? ` (compound collapsed: ${collapsed.presets.join("+")})` : ""}`;
|
|
38305
|
-
}
|
|
38306
|
-
function routedPartLines(parts) {
|
|
38307
|
-
return parts.map((p) => {
|
|
38308
|
-
const line4 = p.text.replace(/\s+/g, " ").trim();
|
|
38309
|
-
return `${p.preset}: ${line4.length > ROUTE_PART_LINE_CAP ? `${line4.slice(0, ROUTE_PART_LINE_CAP - 1)}\u2026` : line4}`;
|
|
38310
|
-
});
|
|
38311
|
-
}
|
|
38312
|
-
function compoundBrief(text, parts) {
|
|
38313
|
-
return [
|
|
38314
|
-
text,
|
|
38315
|
-
"",
|
|
38316
|
-
`${COMPOUND_BRIEF_HEADING}: ${parts.length} independent parts. Spawn exactly these children \u2014 one \`spawn_run\` per part, on the preset named, with the part's text as the child's whole prompt (add the repository where the preset needs one) \u2014 then \`await_runs\` them all and compile one answer. Do not merge, drop or add a part.`,
|
|
38317
|
-
...parts.map((p, i) => `${i + 1}. \`${p.preset}\`: ${p.text}`)
|
|
38318
|
-
].join("\n");
|
|
38319
|
-
}
|
|
38320
|
-
var REASONING_COUNTING_CAP_FIELDS, REASONING_OUTPUT_TOKEN_ALLOWANCE, OutputCapError, ROUTE_REASON_CAP, ROUTE_MIN_OUTPUT_TOKENS, ROUTE_TIMEOUT_MS, ROUTE_PART_LINE_CAP, ROUTE_RECEIPT_CAP, ROUTED_RECEIPT_PREFIX, COMPOUND_BRIEF_HEADING, MultiToolCallError;
|
|
38321
|
-
var init_route = __esm({
|
|
38322
|
-
"../../src/core/dispatch/route.ts"() {
|
|
38323
|
-
"use strict";
|
|
38324
|
-
init_registry();
|
|
38325
|
-
init_handBack();
|
|
38326
|
-
init_profile();
|
|
38327
|
-
init_redact();
|
|
38328
|
-
init_statusCardFrame();
|
|
38329
|
-
init_commandRegistry();
|
|
38330
|
-
init_commandSurface();
|
|
38331
|
-
init_budgets();
|
|
38332
|
-
init_confirmations();
|
|
38333
|
-
REASONING_COUNTING_CAP_FIELDS = /* @__PURE__ */ new Set(["max_tokens", "max_completion_tokens", "max_output_tokens"]);
|
|
38334
|
-
REASONING_OUTPUT_TOKEN_ALLOWANCE = 4096;
|
|
38335
|
-
OutputCapError = class extends Error {
|
|
38336
|
-
constructor(maxTokens) {
|
|
38337
|
-
super(`answer cut at the output cap (${maxTokens} tokens)`);
|
|
38338
|
-
this.maxTokens = maxTokens;
|
|
38339
|
-
this.name = "OutputCapError";
|
|
38340
|
-
}
|
|
38341
|
-
maxTokens;
|
|
38342
|
-
};
|
|
38343
|
-
ROUTE_REASON_CAP = 120;
|
|
38344
|
-
ROUTE_MIN_OUTPUT_TOKENS = 200;
|
|
38345
|
-
ROUTE_TIMEOUT_MS = 8e3;
|
|
38346
|
-
ROUTE_PART_LINE_CAP = 100;
|
|
38347
|
-
ROUTE_RECEIPT_CAP = 300;
|
|
38348
|
-
ROUTED_RECEIPT_PREFIX = "routed:";
|
|
38349
|
-
COMPOUND_BRIEF_HEADING = "Routed as a compound request";
|
|
38350
|
-
MultiToolCallError = class extends Error {
|
|
38351
|
-
constructor(calls) {
|
|
38352
|
-
super(`answer carried ${calls.length} tool calls; the route is one call`);
|
|
38353
|
-
this.calls = calls;
|
|
38354
|
-
this.name = "MultiToolCallError";
|
|
38355
|
-
}
|
|
38356
|
-
calls;
|
|
38357
|
-
};
|
|
38358
|
-
}
|
|
38359
|
-
});
|
|
38360
|
-
|
|
38361
38672
|
// ../../src/core/runRegistry/runControl.ts
|
|
38362
38673
|
var RunControl;
|
|
38363
38674
|
var init_runControl = __esm({
|
|
@@ -38484,6 +38795,8 @@ function summaryOf(run2, now) {
|
|
|
38484
38795
|
...m?.hosted ? { hosted: true } : {},
|
|
38485
38796
|
...run2.instanceId !== void 0 ? { instanceId: run2.instanceId } : {},
|
|
38486
38797
|
...run2.pipeline !== void 0 ? { pipeline: run2.pipeline } : {},
|
|
38798
|
+
...run2.liveState !== void 0 ? { liveState: run2.liveState } : {},
|
|
38799
|
+
...run2.liveStateSeq !== void 0 ? { liveStateSeq: run2.liveStateSeq } : {},
|
|
38487
38800
|
finished: run2.finished,
|
|
38488
38801
|
startedAt: run2.startedAt,
|
|
38489
38802
|
...run2.finishedAt !== void 0 ? { finishedAt: run2.finishedAt } : {},
|
|
@@ -38519,7 +38832,9 @@ function snapshotOf(run2) {
|
|
|
38519
38832
|
...run2.meta?.receivedAt !== void 0 ? { receivedAt: run2.meta.receivedAt } : {},
|
|
38520
38833
|
eventCount: run2.eventCount,
|
|
38521
38834
|
stepCount: run2.stepCount,
|
|
38522
|
-
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 } : {}
|
|
38523
38838
|
};
|
|
38524
38839
|
}
|
|
38525
38840
|
function sealResultOf(run2) {
|
|
@@ -38603,6 +38918,7 @@ var init_runRegistry = __esm({
|
|
|
38603
38918
|
init_projections();
|
|
38604
38919
|
init_indexFeed();
|
|
38605
38920
|
init_runPace();
|
|
38921
|
+
init_runLiveState();
|
|
38606
38922
|
PACE_RING_CAP = 1200;
|
|
38607
38923
|
UNSEALED_HOLD_MS = 15 * 6e4;
|
|
38608
38924
|
RUN_LABEL_MAX2 = 200;
|
|
@@ -38676,6 +38992,10 @@ var init_runRegistry = __esm({
|
|
|
38676
38992
|
if (!isSpanRecord(event)) run2.stepCount++;
|
|
38677
38993
|
appendToBacklog(run2, this.bounds, { ...event, seq });
|
|
38678
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;
|
|
38679
38999
|
this.index.notify({ type: "upsert", run: summaryOf(run2, this.now()) });
|
|
38680
39000
|
return { id, token: token2, control: run2.control, ...stored !== void 0 ? { label: stored } : {} };
|
|
38681
39001
|
}
|
|
@@ -38764,6 +39084,32 @@ var init_runRegistry = __esm({
|
|
|
38764
39084
|
}
|
|
38765
39085
|
if (!span) this.index.notify({ type: "upsert", run: summaryOf(run2, this.now()) });
|
|
38766
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
|
+
}
|
|
38767
39113
|
/** Mark a run finished — the agent stopped: stamp `finishedAt`, send every
|
|
38768
39114
|
* attached subscriber the `finished` frame WITHOUT detaching it (span records
|
|
38769
39115
|
* still flow until the seal), and upsert the index. `status` is the terminal
|
|
@@ -41765,6 +42111,47 @@ var init_customInstructions = __esm({
|
|
|
41765
42111
|
}
|
|
41766
42112
|
});
|
|
41767
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
|
+
|
|
41768
42155
|
// ../../src/core/statusCoalescer.ts
|
|
41769
42156
|
function coalesceStatus(inner, minIntervalMs, now = Date.now, schedule = setTimeout) {
|
|
41770
42157
|
let lastSentAt = -Infinity;
|
|
@@ -41937,22 +42324,24 @@ async function registerRun(deps, ctx) {
|
|
|
41937
42324
|
{
|
|
41938
42325
|
id: runId3,
|
|
41939
42326
|
startedAt,
|
|
41940
|
-
...
|
|
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 } : {}
|
|
41941
42329
|
}
|
|
41942
42330
|
);
|
|
42331
|
+
const events = new RunEventLane((event) => registry.publish(run2.id, event));
|
|
41943
42332
|
if (ctx.restartCarried)
|
|
41944
|
-
|
|
42333
|
+
events.publish({ type: "run_note", kind: "resumed", summary: ctx.restartCarried.note, at: clock4() });
|
|
41945
42334
|
const liveUrl = liveViewLink(run2.id, run2.token);
|
|
41946
42335
|
shell.setLink(liveUrl ? { url: liveUrl, label: "Live run" } : void 0);
|
|
41947
42336
|
if (liveUrl) admitted.runLink = liveUrl;
|
|
41948
42337
|
io.runStarted?.({ id: run2.id });
|
|
41949
|
-
trace.bindRun(run2.id, (
|
|
42338
|
+
trace.bindRun(run2.id, (event) => events.publish(event));
|
|
41950
42339
|
const publishText = (type, text, source3, raw) => {
|
|
41951
42340
|
const redacted = redactSecrets(text);
|
|
41952
42341
|
const body = { text: redacted, ...source3 ? { source: source3 } : {}, at: clock4() };
|
|
41953
42342
|
const event = type === "input" ? { type, messageId: messageIdOf(msg, run2.id), ...body } : { type, ...body };
|
|
41954
42343
|
const withRaw = raw !== void 0 ? { ...event, raw: redactSecrets(raw) } : event;
|
|
41955
|
-
|
|
42344
|
+
events.publish(utf8ByteLength(JSON.stringify(withRaw)) <= MAX_EVENT_BYTES ? withRaw : event);
|
|
41956
42345
|
console.log(`[event] ${msg.threadKey} type=${type} bytes=${utf8ByteLength(redacted)}`);
|
|
41957
42346
|
};
|
|
41958
42347
|
const humanize = isMrkdwnChannel(msg.channelId);
|
|
@@ -41972,7 +42361,7 @@ async function registerRun(deps, ctx) {
|
|
|
41972
42361
|
if (!resume && ctx.references) {
|
|
41973
42362
|
const { conversations, blocks } = ctx.references;
|
|
41974
42363
|
conversations.forEach((rc, i) => {
|
|
41975
|
-
|
|
42364
|
+
events.publish({
|
|
41976
42365
|
type: "reference",
|
|
41977
42366
|
url: rc.permalink,
|
|
41978
42367
|
channelId: rc.ref.channelId,
|
|
@@ -41984,7 +42373,7 @@ async function registerRun(deps, ctx) {
|
|
|
41984
42373
|
console.log(`[event] ${msg.threadKey} type=reference channel=${rc.ref.channelId} messages=${rc.messages.length}`);
|
|
41985
42374
|
});
|
|
41986
42375
|
}
|
|
41987
|
-
const publishMeta = (repoCtx2) =>
|
|
42376
|
+
const publishMeta = (repoCtx2) => events.publish({
|
|
41988
42377
|
type: "run_meta",
|
|
41989
42378
|
agent: agent.name,
|
|
41990
42379
|
agentSource,
|
|
@@ -42016,7 +42405,7 @@ async function registerRun(deps, ctx) {
|
|
|
42016
42405
|
if (!resume)
|
|
42017
42406
|
for (const d of cardDecisions ?? []) {
|
|
42018
42407
|
if (d.outcome !== "degraded") continue;
|
|
42019
|
-
|
|
42408
|
+
events.publish({
|
|
42020
42409
|
type: "run_note",
|
|
42021
42410
|
kind: "control_degraded",
|
|
42022
42411
|
summary: oneLine(
|
|
@@ -42030,12 +42419,12 @@ async function registerRun(deps, ctx) {
|
|
|
42030
42419
|
at: clock4()
|
|
42031
42420
|
});
|
|
42032
42421
|
}
|
|
42033
|
-
if (!resume && route2)
|
|
42034
|
-
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() });
|
|
42035
42424
|
if (!resume && deps.config.config.runHistory?.includeContext !== false) {
|
|
42036
42425
|
for (const text of contextMessageTexts(seedTurns ?? history, humanize)) publishText("context", text);
|
|
42037
42426
|
}
|
|
42038
|
-
return { run: run2, runId: runId3, channelVisibility, liveUrl, publishText, publishMeta };
|
|
42427
|
+
return { run: run2, runId: runId3, channelVisibility, liveUrl, events, publishText, publishMeta };
|
|
42039
42428
|
}
|
|
42040
42429
|
async function reserveRun(deps, ctx) {
|
|
42041
42430
|
const {
|
|
@@ -42111,8 +42500,8 @@ async function reserveRun(deps, ctx) {
|
|
|
42111
42500
|
}
|
|
42112
42501
|
async function attachRound(deps, ctx) {
|
|
42113
42502
|
const { threadKey, agent, profile, repoCtx, root, clock: clock4, reattach, stopSignal, remainingMs, requester } = ctx;
|
|
42114
|
-
const {
|
|
42115
|
-
const ownPr = ownPrOf(repoCtx);
|
|
42503
|
+
const { onLiveStateObservation } = ctx;
|
|
42504
|
+
const ownPr = agent.name === "review" ? void 0 : ownPrOf(repoCtx);
|
|
42116
42505
|
return root.span("dispatch.workspace.attach", async (span) => {
|
|
42117
42506
|
const graft = (steps, residentTotalMs) => graftResidentSteps(steps, {
|
|
42118
42507
|
parent: span,
|
|
@@ -42147,7 +42536,7 @@ async function attachRound(deps, ctx) {
|
|
|
42147
42536
|
...stopSignal !== void 0 ? { stopSignal } : {},
|
|
42148
42537
|
...remainingMs !== void 0 ? { remainingMs } : {},
|
|
42149
42538
|
...requester !== void 0 ? { requester } : {},
|
|
42150
|
-
...
|
|
42539
|
+
...onLiveStateObservation !== void 0 ? { onLiveStateObservation } : {}
|
|
42151
42540
|
},
|
|
42152
42541
|
logKey: threadKey,
|
|
42153
42542
|
span
|
|
@@ -42204,10 +42593,10 @@ async function attachWorkspace(deps, ctx) {
|
|
|
42204
42593
|
clock: clock4,
|
|
42205
42594
|
// The requester whose binding names the author pair (record 0062).
|
|
42206
42595
|
requester: msg.userId,
|
|
42207
|
-
|
|
42208
|
-
|
|
42209
|
-
|
|
42210
|
-
|
|
42596
|
+
onLiveStateObservation: async (observation) => {
|
|
42597
|
+
await ctx.onLiveStateObservation?.(observation);
|
|
42598
|
+
shell.setSetupLabel(`${liveStateWords(observation.state)}\u2026`);
|
|
42599
|
+
},
|
|
42211
42600
|
...reattach !== void 0 ? { reattach } : {},
|
|
42212
42601
|
...stopSignal !== void 0 ? { stopSignal } : {},
|
|
42213
42602
|
...remainingMs !== void 0 ? { remainingMs } : {}
|
|
@@ -42374,7 +42763,6 @@ var init_provision = __esm({
|
|
|
42374
42763
|
init_factory();
|
|
42375
42764
|
init_executor();
|
|
42376
42765
|
init_residentTrace();
|
|
42377
|
-
init_displayNames();
|
|
42378
42766
|
init_resident();
|
|
42379
42767
|
init_memory();
|
|
42380
42768
|
init_budgets();
|
|
@@ -42387,12 +42775,14 @@ var init_provision = __esm({
|
|
|
42387
42775
|
init_reviewRound();
|
|
42388
42776
|
init_repoContext();
|
|
42389
42777
|
init_runEvents();
|
|
42778
|
+
init_runEventLane();
|
|
42390
42779
|
init_redact();
|
|
42391
42780
|
init_runRecord();
|
|
42392
42781
|
init_inboxMessage();
|
|
42393
42782
|
init_statusCardFrame();
|
|
42394
42783
|
init_statusCoalescer();
|
|
42395
42784
|
init_types5();
|
|
42785
|
+
init_decide();
|
|
42396
42786
|
init_record();
|
|
42397
42787
|
init_reply();
|
|
42398
42788
|
init_refusal();
|
|
@@ -45718,6 +46108,18 @@ function decisionRecordTaskKey(...parts) {
|
|
|
45718
46108
|
}
|
|
45719
46109
|
return hash.toString(16).padStart(16, "0");
|
|
45720
46110
|
}
|
|
46111
|
+
function durableDecisionRecordReservation(store) {
|
|
46112
|
+
return async (repo, taskKey, claimed2, existing) => {
|
|
46113
|
+
try {
|
|
46114
|
+
const reserved = await store.reserveDecisionRecord(repo, taskKey, claimed2, existing);
|
|
46115
|
+
if (!reserved.ok) throw new DecisionRecordReservationUnavailableError();
|
|
46116
|
+
return reserved.number;
|
|
46117
|
+
} catch (error) {
|
|
46118
|
+
if (error instanceof DecisionRecordReservationUnavailableError) throw error;
|
|
46119
|
+
throw new DecisionRecordReservationUnavailableError();
|
|
46120
|
+
}
|
|
46121
|
+
};
|
|
46122
|
+
}
|
|
45721
46123
|
var DECISION_RECORD_ENV, RECORD_MARKER, POSITIVE_RECORD_INSTRUCTION, NEGATED_INSTRUCTION, DECISION_RECORD_STORE_REFUSAL, DecisionRecordReservationUnavailableError, DecisionRecordAllocator;
|
|
45722
46124
|
var init_decisionRecordReservation = __esm({
|
|
45723
46125
|
"../../src/core/decisionRecordReservation.ts"() {
|
|
@@ -48601,6 +49003,11 @@ var init_mirror = __esm({
|
|
|
48601
49003
|
seedEchoPending = false;
|
|
48602
49004
|
mirroredTail;
|
|
48603
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;
|
|
48604
49011
|
/** The rows written since the mirror started, and the compaction entries
|
|
48605
49012
|
* among them by position — kept whether or not the ledger is wired, so
|
|
48606
49013
|
* the harness holds this generation's copy of the record it wrote
|
|
@@ -48614,6 +49021,11 @@ var init_mirror = __esm({
|
|
|
48614
49021
|
compactionRows = [];
|
|
48615
49022
|
/** The highest ledger inbox seq folded in so far (run-history item 40). */
|
|
48616
49023
|
inboxConsumedSeq = 0;
|
|
49024
|
+
/** The owed seqs the cursor has already passed, ascending; absent when none. */
|
|
49025
|
+
inboxDeferred() {
|
|
49026
|
+
const deferred = [...new Set(this.deps.owedInboxSeqs?.() ?? [])].filter((seq) => seq <= this.inboxConsumedSeq).sort((a, b) => a - b);
|
|
49027
|
+
return deferred.length > 0 ? { inboxDeferredSeqs: deferred } : {};
|
|
49028
|
+
}
|
|
48617
49029
|
/** Whether a report is owed: the mirror is wired and something happened. */
|
|
48618
49030
|
get wired() {
|
|
48619
49031
|
return this.deps.onStep !== void 0;
|
|
@@ -48702,8 +49114,11 @@ var init_mirror = __esm({
|
|
|
48702
49114
|
turn,
|
|
48703
49115
|
iteration: this.iteration++,
|
|
48704
49116
|
remainingMs: Math.max(0, this.deps.remainingMs()),
|
|
48705
|
-
inboxConsumedSeq: this.inboxConsumedSeq
|
|
49117
|
+
inboxConsumedSeq: this.inboxConsumedSeq,
|
|
49118
|
+
...this.inboxDeferred()
|
|
48706
49119
|
};
|
|
49120
|
+
this.lastTurn = report2.turn;
|
|
49121
|
+
this.lastIteration = report2.iteration;
|
|
48707
49122
|
this.idx += turns.length;
|
|
48708
49123
|
this.lastAssistantIdx = this.idx - 1;
|
|
48709
49124
|
this.rows.push(...turns);
|
|
@@ -48729,8 +49144,11 @@ var init_mirror = __esm({
|
|
|
48729
49144
|
turn,
|
|
48730
49145
|
iteration: this.iteration,
|
|
48731
49146
|
remainingMs: Math.max(0, this.deps.remainingMs()),
|
|
48732
|
-
inboxConsumedSeq: this.inboxConsumedSeq
|
|
49147
|
+
inboxConsumedSeq: this.inboxConsumedSeq,
|
|
49148
|
+
...this.inboxDeferred()
|
|
48733
49149
|
};
|
|
49150
|
+
this.lastTurn = report2.turn;
|
|
49151
|
+
this.lastIteration = report2.iteration;
|
|
48734
49152
|
this.idx += turns.length + 1;
|
|
48735
49153
|
this.rows.push(...turns);
|
|
48736
49154
|
this.compactionRows.push({ before: this.rows.length, entry });
|
|
@@ -48738,6 +49156,22 @@ var init_mirror = __esm({
|
|
|
48738
49156
|
await this.deps.onStep(report2);
|
|
48739
49157
|
return true;
|
|
48740
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
|
+
}
|
|
48741
49175
|
};
|
|
48742
49176
|
}
|
|
48743
49177
|
});
|
|
@@ -49813,6 +50247,7 @@ async function runPiHarnessOpen(deps, run2) {
|
|
|
49813
50247
|
let paths;
|
|
49814
50248
|
let requeueUnechoed = () => {
|
|
49815
50249
|
};
|
|
50250
|
+
let unechoedSeqs = () => [];
|
|
49816
50251
|
let dropHeld = () => {
|
|
49817
50252
|
};
|
|
49818
50253
|
let loopEnded = false;
|
|
@@ -49847,7 +50282,10 @@ async function runPiHarnessOpen(deps, run2) {
|
|
|
49847
50282
|
onStep: run2.onStep,
|
|
49848
50283
|
seedLength: run2.resume ? run2.resume.messages.length + (run2.resume.compactions?.length ?? 0) : run2.messages.length,
|
|
49849
50284
|
remainingMs: () => deadline - now(),
|
|
49850
|
-
...tail ? { mirroredTail: tail } : {}
|
|
50285
|
+
...tail ? { mirroredTail: tail } : {},
|
|
50286
|
+
// The rows pi has not read yet: the cursor can pass one when a later row
|
|
50287
|
+
// is consumed first (the plane's provider-up beside an ordinary steer).
|
|
50288
|
+
owedInboxSeqs: () => [...run2.inbox?.pendingSeqs ?? [], ...unechoedSeqs()]
|
|
49851
50289
|
});
|
|
49852
50290
|
mirror.inboxConsumedSeq = run2.resume?.inboxConsumedSeq ?? 0;
|
|
49853
50291
|
placed = (event) => {
|
|
@@ -50254,6 +50692,7 @@ async function runPiHarnessOpen(deps, run2) {
|
|
|
50254
50692
|
const [echoed] = unechoed.splice(at, 1);
|
|
50255
50693
|
if (echoed.seq > mirror.inboxConsumedSeq) mirror.inboxConsumedSeq = echoed.seq;
|
|
50256
50694
|
};
|
|
50695
|
+
unechoedSeqs = () => unechoed.flatMap((u) => u.inputs.flatMap((i) => i.ledgerSeq !== void 0 ? [i.ledgerSeq] : []));
|
|
50257
50696
|
requeueUnechoed = () => {
|
|
50258
50697
|
pendingReissue = [];
|
|
50259
50698
|
run2.inbox?.requeue(unechoed.splice(0).flatMap((u) => u.inputs));
|
|
@@ -50262,6 +50701,7 @@ async function runPiHarnessOpen(deps, run2) {
|
|
|
50262
50701
|
let parkSettled = false;
|
|
50263
50702
|
let pendingReissue = [];
|
|
50264
50703
|
let reissueInFlight;
|
|
50704
|
+
let reissueInFlightRows = [];
|
|
50265
50705
|
let reissues = 0;
|
|
50266
50706
|
let providerRetryReady = false;
|
|
50267
50707
|
let providerRetryWait;
|
|
@@ -50274,20 +50714,21 @@ async function runPiHarnessOpen(deps, run2) {
|
|
|
50274
50714
|
providerRetryWait = void 0;
|
|
50275
50715
|
providerRetryGeneration += 1;
|
|
50276
50716
|
pendingReissue = [];
|
|
50717
|
+
reissueInFlightRows = [];
|
|
50277
50718
|
};
|
|
50278
50719
|
const maybeReissue = () => {
|
|
50279
50720
|
if (heldTurn === void 0 || !parkSettled || reissueInFlight !== void 0 || retryInFlight !== void 0)
|
|
50280
50721
|
return;
|
|
50281
50722
|
if (pendingReissue.length === 0) return;
|
|
50282
50723
|
if (loopEnded || hardStopped || writeUp !== void 0 || finaleAborted) return;
|
|
50283
|
-
|
|
50724
|
+
reissueInFlightRows = pendingReissue.splice(0);
|
|
50284
50725
|
reissues += 1;
|
|
50285
50726
|
const id = reissues === 1 ? `${ids.prompt}:reissue` : `${ids.prompt}:reissue:${reissues}`;
|
|
50286
50727
|
reissueInFlight = id;
|
|
50287
50728
|
unechoed.push({
|
|
50288
50729
|
message: REISSUE_PROMPT,
|
|
50289
|
-
seq: Math.max(0, ...
|
|
50290
|
-
inputs:
|
|
50730
|
+
seq: Math.max(0, ...reissueInFlightRows.map((i) => i.ledgerSeq ?? 0)),
|
|
50731
|
+
inputs: reissueInFlightRows
|
|
50291
50732
|
});
|
|
50292
50733
|
sends.send({ id, type: "prompt", message: REISSUE_PROMPT });
|
|
50293
50734
|
};
|
|
@@ -50548,16 +50989,29 @@ ${stagedLine}` : prompt;
|
|
|
50548
50989
|
save();
|
|
50549
50990
|
}
|
|
50550
50991
|
if (reissueInFlight !== void 0 && r.id === reissueInFlight) {
|
|
50551
|
-
reissueInFlight = void 0;
|
|
50552
50992
|
if (r.success === false) {
|
|
50993
|
+
reissueInFlight = void 0;
|
|
50553
50994
|
parkSettled = false;
|
|
50554
50995
|
const at = unechoed.findIndex((u) => u.message === REISSUE_PROMPT);
|
|
50555
|
-
if (at >= 0)
|
|
50996
|
+
if (at >= 0) unechoed.splice(at, 1);
|
|
50997
|
+
pendingReissue.push(...reissueInFlightRows);
|
|
50998
|
+
reissueInFlightRows = [];
|
|
50556
50999
|
note(
|
|
50557
51000
|
"harness_error",
|
|
50558
51001
|
`the reissue prompt was refused (${String(r.error ?? "no reason")}); the turn stays held for the next settle`
|
|
50559
51002
|
);
|
|
50560
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;
|
|
50561
51015
|
clearProviderHold();
|
|
50562
51016
|
}
|
|
50563
51017
|
}
|
|
@@ -50566,7 +51020,16 @@ ${stagedLine}` : prompt;
|
|
|
50566
51020
|
if (r.success === false) {
|
|
50567
51021
|
parkSettled = false;
|
|
50568
51022
|
note("harness_error", "the model retry prompt was refused; the transport failure remains held");
|
|
50569
|
-
} 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
|
+
}
|
|
50570
51033
|
}
|
|
50571
51034
|
if (r.id === ids.prompt) {
|
|
50572
51035
|
catchingUp = false;
|
|
@@ -50923,10 +51386,13 @@ ${stagedLine}` : prompt;
|
|
|
50923
51386
|
`the follow-up turn's reissue prompt was refused (${String(obs.response.error ?? "no reason")}); the turn stays held for the next settle`
|
|
50924
51387
|
);
|
|
50925
51388
|
} else {
|
|
51389
|
+
drainTurnReissues();
|
|
50926
51390
|
mirror.inboxConsumedSeq = Math.max(
|
|
50927
51391
|
mirror.inboxConsumedSeq,
|
|
50928
|
-
...turnReissueInFlightRows.map((item) => item.ledgerSeq ?? 0)
|
|
51392
|
+
...turnReissueInFlightRows.map((item) => item.ledgerSeq ?? 0),
|
|
51393
|
+
...turnReissueRows.map((item) => item.ledgerSeq ?? 0)
|
|
50929
51394
|
);
|
|
51395
|
+
await mirror.checkpointInbox();
|
|
50930
51396
|
clearTurnProviderHold();
|
|
50931
51397
|
}
|
|
50932
51398
|
}
|
|
@@ -50935,7 +51401,15 @@ ${stagedLine}` : prompt;
|
|
|
50935
51401
|
if (obs.response.success === false) {
|
|
50936
51402
|
turnParkSettled = false;
|
|
50937
51403
|
note("harness_error", "the follow-up turn's model retry prompt was refused; the failure remains held");
|
|
50938
|
-
} else
|
|
51404
|
+
} else {
|
|
51405
|
+
drainTurnReissues();
|
|
51406
|
+
mirror.inboxConsumedSeq = Math.max(
|
|
51407
|
+
mirror.inboxConsumedSeq,
|
|
51408
|
+
...turnReissueRows.map((item) => item.ledgerSeq ?? 0)
|
|
51409
|
+
);
|
|
51410
|
+
await mirror.checkpointInbox();
|
|
51411
|
+
clearTurnProviderHold();
|
|
51412
|
+
}
|
|
50939
51413
|
}
|
|
50940
51414
|
}
|
|
50941
51415
|
if (obs.response?.id === id && obs.response.success === false)
|
|
@@ -52266,6 +52740,7 @@ async function runLoop(deps, ctx) {
|
|
|
52266
52740
|
coordinator,
|
|
52267
52741
|
seed
|
|
52268
52742
|
} = ctx;
|
|
52743
|
+
const events = ctx.events ?? new RunEventLane((event) => registry.publish(run2.id, event));
|
|
52269
52744
|
const agent = budgetedAgent(ctx.agent, profile);
|
|
52270
52745
|
const { round: round2 } = ctx;
|
|
52271
52746
|
let { executor } = round2.selection;
|
|
@@ -52339,13 +52814,11 @@ async function runLoop(deps, ctx) {
|
|
|
52339
52814
|
const pushes = trackPushedBranch(typeof restored.pushedBranch === "string" ? restored.pushedBranch : void 0);
|
|
52340
52815
|
let budgetEnded = false;
|
|
52341
52816
|
let recordedPushedBranch;
|
|
52342
|
-
|
|
52817
|
+
let modelBudgetEndsAt;
|
|
52818
|
+
const publishEvent = (e, startsRunBudget) => {
|
|
52343
52819
|
registry.publish(run2.id, e);
|
|
52344
52820
|
if (isSpanRecord(e)) return;
|
|
52345
|
-
if (
|
|
52346
|
-
run2.control.startLease(() => e.endsAt - clock4());
|
|
52347
|
-
return;
|
|
52348
|
-
}
|
|
52821
|
+
if (startsRunBudget) return;
|
|
52349
52822
|
if (e.type === "tool_call") toolCalls++;
|
|
52350
52823
|
if (e.type === "run_note" && e.kind === "time_budget_exhausted") budgetEnded = true;
|
|
52351
52824
|
if (isCodingPrRun) {
|
|
@@ -52365,6 +52838,47 @@ async function runLoop(deps, ctx) {
|
|
|
52365
52838
|
lastActivity = bookkeeping && !showBookkeeping ? void 0 : cardActivity(e);
|
|
52366
52839
|
card.update(currentFrame());
|
|
52367
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
|
+
};
|
|
52368
52882
|
for (const s of mcpForRun?.servers ?? []) {
|
|
52369
52883
|
if (s.unavailable !== void 0)
|
|
52370
52884
|
onEvent({
|
|
@@ -52387,14 +52901,14 @@ async function runLoop(deps, ctx) {
|
|
|
52387
52901
|
descriptionArtifact = startReviewDescription({
|
|
52388
52902
|
store: deps.runStore,
|
|
52389
52903
|
repoCtx,
|
|
52390
|
-
publish: (
|
|
52904
|
+
publish: (event) => events.publish(event)
|
|
52391
52905
|
});
|
|
52392
52906
|
readingDiffBaseline = startReviewReadingDiff({
|
|
52393
52907
|
executor,
|
|
52394
52908
|
cfg: deps.config.config.review?.readingDiff,
|
|
52395
52909
|
env: publicEnv(),
|
|
52396
52910
|
baseRef: repoCtx.baseRef,
|
|
52397
|
-
publish: (
|
|
52911
|
+
publish: (event) => events.publish(event),
|
|
52398
52912
|
parent: root
|
|
52399
52913
|
}).baseline.then((published) => {
|
|
52400
52914
|
console.log(`[reading-diff] ${msg.threadKey} baseline ${published ? "published" : "none"}`);
|
|
@@ -52466,10 +52980,11 @@ async function runLoop(deps, ctx) {
|
|
|
52466
52980
|
if (interrupted === void 0) runFailed = true;
|
|
52467
52981
|
throw err2;
|
|
52468
52982
|
} finally {
|
|
52983
|
+
await events.drain();
|
|
52469
52984
|
const calls = callsInFlight(recordEvents(), statusNow());
|
|
52470
52985
|
commandInFlight = calls.length > 0;
|
|
52471
52986
|
if (commandInFlight)
|
|
52472
|
-
|
|
52987
|
+
events.publish({
|
|
52473
52988
|
type: "run_note",
|
|
52474
52989
|
kind: "workspace_torn_down",
|
|
52475
52990
|
summary: redactAndCap(
|
|
@@ -52543,12 +53058,12 @@ async function runLoop(deps, ctx) {
|
|
|
52543
53058
|
let reviewStoppedBeforeStart = false;
|
|
52544
53059
|
const latchReviewStoppedBeforeStart = () => {
|
|
52545
53060
|
if (reviewStoppedBeforeStart || agent.name !== "review") return reviewStoppedBeforeStart;
|
|
52546
|
-
const
|
|
52547
|
-
const stopAt =
|
|
53061
|
+
const events2 = recordEvents();
|
|
53062
|
+
const stopAt = events2.findIndex(
|
|
52548
53063
|
(event) => event.type === "run_note" && (event.kind === "stop_requested" || event.kind === "stopped")
|
|
52549
53064
|
);
|
|
52550
53065
|
if (stopAt < 0) return false;
|
|
52551
|
-
reviewStoppedBeforeStart = !
|
|
53066
|
+
reviewStoppedBeforeStart = !events2.slice(0, stopAt).some((event) => event.type === "tool_call" && event.tool !== "update_status");
|
|
52552
53067
|
return reviewStoppedBeforeStart;
|
|
52553
53068
|
};
|
|
52554
53069
|
const clearStoppedReviewTail = () => {
|
|
@@ -52563,8 +53078,8 @@ async function runLoop(deps, ctx) {
|
|
|
52563
53078
|
};
|
|
52564
53079
|
const tailSkipped = () => run2.control.requested === "hard" || relaunchEndedRun || latchReviewStoppedBeforeStart();
|
|
52565
53080
|
const releaseWorkspace = (span) => {
|
|
52566
|
-
const
|
|
52567
|
-
const pushed = pushedBranchesOf(
|
|
53081
|
+
const events2 = recordEvents();
|
|
53082
|
+
const pushed = pushedBranchesOf(events2);
|
|
52568
53083
|
return round2.release({
|
|
52569
53084
|
hardStopped: run2.control.requested === "hard",
|
|
52570
53085
|
commandInFlight,
|
|
@@ -52582,7 +53097,7 @@ async function runLoop(deps, ctx) {
|
|
|
52582
53097
|
const staged = await stageIntoWorkspace(files, {
|
|
52583
53098
|
store: deps.artifacts,
|
|
52584
53099
|
threadKey: msg.threadKey,
|
|
52585
|
-
publish: (
|
|
53100
|
+
publish: (event) => events.publish(event),
|
|
52586
53101
|
nextIndex: nextStagedIndex,
|
|
52587
53102
|
executor,
|
|
52588
53103
|
resident: round2.selection.resident !== void 0
|
|
@@ -53028,7 +53543,7 @@ async function runLoop(deps, ctx) {
|
|
|
53028
53543
|
return { workspace, description: prDescription !== void 0 ? "submitted" : "not_submitted" };
|
|
53029
53544
|
};
|
|
53030
53545
|
if (leftBehind) {
|
|
53031
|
-
|
|
53546
|
+
events.publish({
|
|
53032
53547
|
type: "run_note",
|
|
53033
53548
|
kind: "work_left_behind",
|
|
53034
53549
|
summary: oneLine(workLeftBehindSummary(leftBehind)),
|
|
@@ -53037,7 +53552,7 @@ async function runLoop(deps, ctx) {
|
|
|
53037
53552
|
shell.note("quiet", workLeftBehindLabel(leftBehind));
|
|
53038
53553
|
}
|
|
53039
53554
|
if (prDescription) {
|
|
53040
|
-
|
|
53555
|
+
events.publish({
|
|
53041
53556
|
type: "pr_description",
|
|
53042
53557
|
description: redactPrDescription(prDescription),
|
|
53043
53558
|
at: clock4()
|
|
@@ -53073,7 +53588,7 @@ async function runLoop(deps, ctx) {
|
|
|
53073
53588
|
}
|
|
53074
53589
|
} : {},
|
|
53075
53590
|
descriptionTurnRan,
|
|
53076
|
-
publish: (
|
|
53591
|
+
publish: (event) => events.publish(event),
|
|
53077
53592
|
logKey: msg.threadKey
|
|
53078
53593
|
})
|
|
53079
53594
|
);
|
|
@@ -53111,7 +53626,7 @@ async function runLoop(deps, ctx) {
|
|
|
53111
53626
|
fetchPrHead: deps.fetchPrHead ?? currentPrHeadSha,
|
|
53112
53627
|
reply: (text) => io.reply(text),
|
|
53113
53628
|
ack: (text) => replyAck(io, resolved.verbosity, text),
|
|
53114
|
-
publish: (
|
|
53629
|
+
publish: (event) => events.publish(event),
|
|
53115
53630
|
logKey: msg.threadKey
|
|
53116
53631
|
})
|
|
53117
53632
|
);
|
|
@@ -53122,7 +53637,7 @@ async function runLoop(deps, ctx) {
|
|
|
53122
53637
|
gateBypassed = err2 instanceof HarnessGateBypassedError;
|
|
53123
53638
|
if (err2 instanceof ModelPolicyRefusedError) failure2 = { kind: "policy_refusal" };
|
|
53124
53639
|
else if (err2 instanceof ModelTransientFailureError) failure2 = { kind: "provider_transient" };
|
|
53125
|
-
|
|
53640
|
+
events.publish({
|
|
53126
53641
|
type: "run_note",
|
|
53127
53642
|
kind: "run_failed",
|
|
53128
53643
|
summary: redactAndCap(err2 instanceof Error ? err2.message : String(err2), ENDING_NOTE_MAX)
|
|
@@ -53131,7 +53646,7 @@ async function runLoop(deps, ctx) {
|
|
|
53131
53646
|
await endHarness().catch((endErr) => {
|
|
53132
53647
|
const detail = `the harness session's end failed after the loop's own error: ${endErr instanceof Error ? endErr.message : String(endErr)}`;
|
|
53133
53648
|
console.warn(`[run] ${msg.threadKey} ${detail}`);
|
|
53134
|
-
|
|
53649
|
+
events.publish({
|
|
53135
53650
|
type: "run_note",
|
|
53136
53651
|
kind: "harness_error",
|
|
53137
53652
|
summary: redactAndCap(detail, ENDING_NOTE_MAX),
|
|
@@ -53140,13 +53655,13 @@ async function runLoop(deps, ctx) {
|
|
|
53140
53655
|
});
|
|
53141
53656
|
await preserveCodingChildWork("ending").catch((salvageErr) => {
|
|
53142
53657
|
const summary = `the interrupted-work checkpoint failed before teardown: ${salvageErr instanceof Error ? salvageErr.message : String(salvageErr)}`;
|
|
53143
|
-
|
|
53658
|
+
events.publish({ type: "run_note", kind: "work_salvage", summary, at: clock4() });
|
|
53144
53659
|
shell.note("quiet", summary);
|
|
53145
53660
|
});
|
|
53146
53661
|
await root.span("post.workspace_release", (span) => releaseWorkspace(span));
|
|
53147
53662
|
if (!interrupted) throw err2;
|
|
53148
53663
|
if (coordinator !== void 0)
|
|
53149
|
-
|
|
53664
|
+
events.publish({
|
|
53150
53665
|
type: "child_interrupted",
|
|
53151
53666
|
parentInstanceId: coordinator.parentInstanceId,
|
|
53152
53667
|
reason: redactAndCap(interrupted.message, ENDING_NOTE_MAX),
|
|
@@ -53161,12 +53676,49 @@ async function runLoop(deps, ctx) {
|
|
|
53161
53676
|
};
|
|
53162
53677
|
} finally {
|
|
53163
53678
|
clearInterval(heartbeat);
|
|
53679
|
+
await events.drain();
|
|
53164
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
|
+
}
|
|
53165
53717
|
registry.finish(run2.id, status3);
|
|
53166
53718
|
const snap = registry.snapshot(run2.id, run2.token);
|
|
53167
|
-
const
|
|
53719
|
+
const recordEventList = snap?.events ?? [];
|
|
53168
53720
|
const finishedAt = snap?.finishedAt ?? clock4();
|
|
53169
|
-
const diagnosis = analyzeRunFriction(
|
|
53721
|
+
const diagnosis = analyzeRunFriction(recordEventList, {
|
|
53170
53722
|
finished: true,
|
|
53171
53723
|
truncated: snap?.truncated ?? false,
|
|
53172
53724
|
window: { start: snap?.receivedAt ?? startedAt, end: finishedAt }
|
|
@@ -53299,10 +53851,13 @@ var init_runLoop = __esm({
|
|
|
53299
53851
|
init_readingDiff();
|
|
53300
53852
|
init_reviewDescription();
|
|
53301
53853
|
init_runEvents();
|
|
53854
|
+
init_runEventLane();
|
|
53302
53855
|
init_redact();
|
|
53303
53856
|
init_runFriction();
|
|
53304
53857
|
init_llmOutput();
|
|
53305
53858
|
init_runRecord();
|
|
53859
|
+
init_runLiveState();
|
|
53860
|
+
init_decide();
|
|
53306
53861
|
init_statusCardLabel();
|
|
53307
53862
|
init_runPace();
|
|
53308
53863
|
init_statusCardFrame();
|
|
@@ -54254,6 +54809,34 @@ async function runShipBranch(deps, msg, io, ctx) {
|
|
|
54254
54809
|
...REPLAY_EVERYTHING
|
|
54255
54810
|
});
|
|
54256
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
|
+
}
|
|
54257
54840
|
const hostRefused = opened.kind === "untracked" && opened.why === "thread-live";
|
|
54258
54841
|
const liveUrl = liveViewLink(run2.id, run2.token);
|
|
54259
54842
|
ctx.live.runId = run2.id;
|
|
@@ -54324,7 +54907,23 @@ async function runShipBranch(deps, msg, io, ctx) {
|
|
|
54324
54907
|
instanceId: outcome.instanceId,
|
|
54325
54908
|
until: clock4() + minutesToMs(caps.maxMinutes + HOSTED_DEADLINE_MARGIN_MINUTES)
|
|
54326
54909
|
};
|
|
54327
|
-
|
|
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
|
+
);
|
|
54328
54927
|
registry.publish(run2.id, {
|
|
54329
54928
|
type: "run_meta",
|
|
54330
54929
|
agent: agent.name,
|
|
@@ -54432,6 +55031,8 @@ var init_ship = __esm({
|
|
|
54432
55031
|
init_runFriction();
|
|
54433
55032
|
init_run2();
|
|
54434
55033
|
init_runRegistry();
|
|
55034
|
+
init_runLiveState();
|
|
55035
|
+
init_pipelineStanding();
|
|
54435
55036
|
init_statusCardFrame();
|
|
54436
55037
|
init_types5();
|
|
54437
55038
|
init_refusal();
|
|
@@ -55611,12 +56212,12 @@ async function dispatch(deps, msg, io, opts = {}) {
|
|
|
55611
56212
|
...operatorEvent ? { operator: operatorEvent } : {},
|
|
55612
56213
|
...references.conversations.length > 0 ? { references } : {}
|
|
55613
56214
|
});
|
|
55614
|
-
const { run: run2, runId: runId3, channelVisibility, liveUrl, publishText, publishMeta } = registration;
|
|
56215
|
+
const { run: run2, runId: runId3, channelVisibility, liveUrl, events, publishText, publishMeta } = registration;
|
|
55615
56216
|
registered = run2;
|
|
55616
56217
|
for (const summary of seedNotes)
|
|
55617
|
-
|
|
56218
|
+
events.publish({ type: "run_note", kind: "seed", summary: oneLine(summary), at: clock4() });
|
|
55618
56219
|
if (opts.redispatch)
|
|
55619
|
-
|
|
56220
|
+
events.publish({
|
|
55620
56221
|
type: "run_note",
|
|
55621
56222
|
kind: "redispatch",
|
|
55622
56223
|
summary: `confirmed after question ${opts.redispatch.code}`,
|
|
@@ -55631,7 +56232,7 @@ async function dispatch(deps, msg, io, opts = {}) {
|
|
|
55631
56232
|
threadKey: msg.threadKey,
|
|
55632
56233
|
nextIndex: nextStagedIndex,
|
|
55633
56234
|
preserveWorkspaceIndexes: true,
|
|
55634
|
-
publish: (
|
|
56235
|
+
publish: (event) => events.publish(event)
|
|
55635
56236
|
}) : void 0;
|
|
55636
56237
|
const threadAssets = !resume && deps.artifacts && thread && thread.length > 0 ? readThreadAssets({ runs: runsService, store: deps.artifacts }, msg.threadKey).then(
|
|
55637
56238
|
(assets) => assets.filter((a) => a.runId !== runId3)
|
|
@@ -55642,7 +56243,7 @@ async function dispatch(deps, msg, io, opts = {}) {
|
|
|
55642
56243
|
{
|
|
55643
56244
|
nextIndex: nextStagedIndex,
|
|
55644
56245
|
messageId: messageIdOf(msg, runId3),
|
|
55645
|
-
publish: (
|
|
56246
|
+
publish: (event) => events.publish(event)
|
|
55646
56247
|
}
|
|
55647
56248
|
)
|
|
55648
56249
|
) : void 0;
|
|
@@ -55674,7 +56275,7 @@ async function dispatch(deps, msg, io, opts = {}) {
|
|
|
55674
56275
|
reserved = reservation.reserved;
|
|
55675
56276
|
requestRow = reservation.requestRow;
|
|
55676
56277
|
if (reservation.untrackedWhy !== void 0) {
|
|
55677
|
-
|
|
56278
|
+
events.publish({
|
|
55678
56279
|
type: "run_note",
|
|
55679
56280
|
kind: "ledger_untracked",
|
|
55680
56281
|
summary: redactAndCap(
|
|
@@ -55688,6 +56289,100 @@ async function dispatch(deps, msg, io, opts = {}) {
|
|
|
55688
56289
|
shell.note("debug", "untracked by the ledger");
|
|
55689
56290
|
}
|
|
55690
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
|
+
};
|
|
55691
56386
|
const reattach = resume ? carriedWorkspaceBinding(resume.row) : void 0;
|
|
55692
56387
|
const control = registered?.control;
|
|
55693
56388
|
const attach = await attachWorkspace(deps, {
|
|
@@ -55707,7 +56402,8 @@ async function dispatch(deps, msg, io, opts = {}) {
|
|
|
55707
56402
|
// during the attach ends its wake wait at once, and once the harness
|
|
55708
56403
|
// starts the lease every attach the executor opens is clipped to the
|
|
55709
56404
|
// run's remaining clock (execution.md item 9).
|
|
55710
|
-
...control ? { stopSignal: control.hardSignal, remainingMs: () => control.remainingMs() } : {}
|
|
56405
|
+
...control ? { stopSignal: control.hardSignal, remainingMs: () => control.remainingMs() } : {},
|
|
56406
|
+
onLiveStateObservation: observeResidentLiveState
|
|
55711
56407
|
});
|
|
55712
56408
|
if (attach.kind === "refused") return ended;
|
|
55713
56409
|
if (attach.kind === "stopped") {
|
|
@@ -55759,6 +56455,17 @@ async function dispatch(deps, msg, io, opts = {}) {
|
|
|
55759
56455
|
return ended;
|
|
55760
56456
|
}
|
|
55761
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
|
+
}
|
|
55762
56469
|
if (resume && ledgerRun) {
|
|
55763
56470
|
const rebound = workspaceBindingFor(round2.selection, profile.machine);
|
|
55764
56471
|
if (rebound !== void 0) ledgerRun.setState({ binding: rebound });
|
|
@@ -55940,6 +56647,12 @@ async function dispatch(deps, msg, io, opts = {}) {
|
|
|
55940
56647
|
markUntracked: () => shell.note("debug", "untracked by the ledger"),
|
|
55941
56648
|
...seedActors !== void 0 ? { seedActors } : {}
|
|
55942
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
|
+
}
|
|
55943
56656
|
const sessionTools = sessionCapabilityFor(
|
|
55944
56657
|
ledgerRun,
|
|
55945
56658
|
deps.runLedger,
|
|
@@ -55981,6 +56694,7 @@ async function dispatch(deps, msg, io, opts = {}) {
|
|
|
55981
56694
|
mcpForRun,
|
|
55982
56695
|
run: run2,
|
|
55983
56696
|
registry,
|
|
56697
|
+
events,
|
|
55984
56698
|
round: round2,
|
|
55985
56699
|
admitted,
|
|
55986
56700
|
ledgerRun,
|
|
@@ -56309,6 +57023,8 @@ var init_dispatcher = __esm({
|
|
|
56309
57023
|
init_registry();
|
|
56310
57024
|
init_budgets();
|
|
56311
57025
|
init_trace();
|
|
57026
|
+
init_runLiveState();
|
|
57027
|
+
init_decide();
|
|
56312
57028
|
init_requestTrace();
|
|
56313
57029
|
init_runShape();
|
|
56314
57030
|
init_runEvents();
|
|
@@ -56806,6 +57522,7 @@ function createLedgerWriteThrough(opts) {
|
|
|
56806
57522
|
turnIndex: report2.firstIdx + turns.length,
|
|
56807
57523
|
inFlight: report2.inFlight,
|
|
56808
57524
|
inboxConsumedSeq: report2.inboxConsumedSeq,
|
|
57525
|
+
...report2.inboxDeferredSeqs?.length ? { inboxDeferredSeqs: report2.inboxDeferredSeqs } : {},
|
|
56809
57526
|
remainingMs: report2.remainingMs,
|
|
56810
57527
|
turn: report2.turn,
|
|
56811
57528
|
iteration: report2.iteration
|
|
@@ -56839,7 +57556,7 @@ function createLedgerWriteThrough(opts) {
|
|
|
56839
57556
|
}
|
|
56840
57557
|
}
|
|
56841
57558
|
event(event, seq) {
|
|
56842
|
-
if (this.detached || this.finished) return;
|
|
57559
|
+
if (this.detached || this.finished || seq <= this.lastSeq) return;
|
|
56843
57560
|
this.lastSeq = seq;
|
|
56844
57561
|
const e = event;
|
|
56845
57562
|
if (typeof e.at === "number") this.factLastEventAt = e.at;
|
|
@@ -56860,6 +57577,30 @@ function createLedgerWriteThrough(opts) {
|
|
|
56860
57577
|
};
|
|
56861
57578
|
this.flusher.push({ ...event, seq });
|
|
56862
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
|
+
}
|
|
56863
57604
|
setState(patch) {
|
|
56864
57605
|
if (this.detached) return;
|
|
56865
57606
|
this.state = { ...this.state, ...patch };
|
|
@@ -57244,6 +57985,9 @@ var init_writeThrough = __esm({
|
|
|
57244
57985
|
}
|
|
57245
57986
|
event(_event, _seq) {
|
|
57246
57987
|
}
|
|
57988
|
+
async assignLiveState(_assignment) {
|
|
57989
|
+
return { ok: false, reason: "unknown-run" };
|
|
57990
|
+
}
|
|
57247
57991
|
setState(_patch) {
|
|
57248
57992
|
}
|
|
57249
57993
|
async finishing() {
|
|
@@ -63023,14 +63767,23 @@ var init_configBoot = __esm({
|
|
|
63023
63767
|
});
|
|
63024
63768
|
|
|
63025
63769
|
// ../../src/intakeModel.ts
|
|
63770
|
+
function intakeDecisionDeps(completion, deps) {
|
|
63771
|
+
return {
|
|
63772
|
+
model: completion.model,
|
|
63773
|
+
...completion.capField !== void 0 ? { capField: completion.capField } : {},
|
|
63774
|
+
...deps
|
|
63775
|
+
};
|
|
63776
|
+
}
|
|
63026
63777
|
function intakeCompletion(config, completions, log = console.log) {
|
|
63027
63778
|
const modelRef3 = intakeModelRef(config);
|
|
63028
63779
|
if (!modelRef3) return void 0;
|
|
63029
63780
|
const ref = parseModelRef(modelRef3);
|
|
63781
|
+
const card = resolveModelCard(modelRef3, config.providers, installedModelRegistry);
|
|
63030
63782
|
const effort2 = turnEffort(modelRef3, config.intake?.effort, config.providers);
|
|
63031
63783
|
if (effort2.note) log(`[intake] effort: ${effort2.note}`);
|
|
63032
63784
|
return {
|
|
63033
63785
|
modelRef: modelRef3,
|
|
63786
|
+
capField: card.capField,
|
|
63034
63787
|
model: providerStructuredModel(completions.get(ref.provider), ref.model, {
|
|
63035
63788
|
...effort2.request ? { effort: effort2.request } : {}
|
|
63036
63789
|
})
|
|
@@ -63042,6 +63795,8 @@ var init_intakeModel = __esm({
|
|
|
63042
63795
|
init_config2();
|
|
63043
63796
|
init_route();
|
|
63044
63797
|
init_turnEffort();
|
|
63798
|
+
init_installedModelRegistry();
|
|
63799
|
+
init_modelCard();
|
|
63045
63800
|
init_provider();
|
|
63046
63801
|
}
|
|
63047
63802
|
});
|
|
@@ -63164,7 +63919,10 @@ async function askModel(input, deps) {
|
|
|
63164
63919
|
floor: (violation) => ({ verdict: "silent", reason: violation, source: "error" })
|
|
63165
63920
|
},
|
|
63166
63921
|
deps.model,
|
|
63167
|
-
{
|
|
63922
|
+
{
|
|
63923
|
+
maxTokens: outputCapWithReasoning(ROUTE_MIN_OUTPUT_TOKENS, { capField: deps.capField }),
|
|
63924
|
+
signal: AbortSignal.timeout(deps.timeoutMs ?? ROUTE_TIMEOUT_MS)
|
|
63925
|
+
}
|
|
63168
63926
|
);
|
|
63169
63927
|
return { ...seam.value, attempts: seam.attempts };
|
|
63170
63928
|
} catch (err2) {
|
|
@@ -63173,8 +63931,18 @@ async function askModel(input, deps) {
|
|
|
63173
63931
|
if (timedOut) {
|
|
63174
63932
|
return {
|
|
63175
63933
|
verdict: "silent",
|
|
63176
|
-
reason:
|
|
63934
|
+
reason: renderProviderFailure("transient", "ended"),
|
|
63177
63935
|
source: "timeout",
|
|
63936
|
+
providerFailure: "transient",
|
|
63937
|
+
...attempts ? { attempts } : {}
|
|
63938
|
+
};
|
|
63939
|
+
}
|
|
63940
|
+
const outputCapError = err2 instanceof OutputCapError ? err2 : err2 instanceof StructuredAskError && err2.cause instanceof OutputCapError ? err2.cause : void 0;
|
|
63941
|
+
if (outputCapError) {
|
|
63942
|
+
return {
|
|
63943
|
+
verdict: "silent",
|
|
63944
|
+
reason: tidyReason(outputCapError.message),
|
|
63945
|
+
source: "error",
|
|
63178
63946
|
...attempts ? { attempts } : {}
|
|
63179
63947
|
};
|
|
63180
63948
|
}
|
|
@@ -70068,7 +70836,13 @@ async function launchResumes(deps, resumable, opts) {
|
|
|
70068
70836
|
const handle2 = registry.create(row2.meta.label, rehostMeta(row2), {
|
|
70069
70837
|
id: row2.runId,
|
|
70070
70838
|
startedAt: row2.startedAt,
|
|
70071
|
-
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
|
+
} : {}
|
|
70072
70846
|
});
|
|
70073
70847
|
const adopted = deps.runLedger.adopt({
|
|
70074
70848
|
runId: row2.runId,
|
|
@@ -70509,6 +71283,72 @@ var init_adminModelProxy = __esm({
|
|
|
70509
71283
|
}
|
|
70510
71284
|
});
|
|
70511
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
|
+
|
|
70512
71352
|
// ../../src/channels/adminTraceLog.ts
|
|
70513
71353
|
function parseTraceLogQuery(search) {
|
|
70514
71354
|
const query = {};
|
|
@@ -71018,7 +71858,7 @@ async function openThreadFromRequester(deps, instance, lead, at) {
|
|
|
71018
71858
|
}
|
|
71019
71859
|
};
|
|
71020
71860
|
} catch (err2) {
|
|
71021
|
-
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 }) };
|
|
71022
71862
|
}
|
|
71023
71863
|
}
|
|
71024
71864
|
function authorizeStep(headers, step, deps) {
|
|
@@ -71142,8 +71982,8 @@ async function spawn6(body, deps) {
|
|
|
71142
71982
|
try {
|
|
71143
71983
|
turn = await composeChild(req.brief, instance, row2, briefReaders(deps, instance));
|
|
71144
71984
|
} catch (err2) {
|
|
71145
|
-
log(`[coordinator] ${instance.id} ${req.step}: the brief could not be composed: ${
|
|
71146
|
-
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 });
|
|
71147
71987
|
}
|
|
71148
71988
|
} else {
|
|
71149
71989
|
turn = { prompt: req.prompt };
|
|
@@ -71213,7 +72053,7 @@ ${foldThreadEvents(folded)}` };
|
|
|
71213
72053
|
});
|
|
71214
72054
|
} catch (err2) {
|
|
71215
72055
|
releaseAdmission();
|
|
71216
|
-
return json3(502, { ok: false, error: "spawn_failed", message:
|
|
72056
|
+
return json3(502, { ok: false, error: "spawn_failed", message: describe12(err2), at });
|
|
71217
72057
|
}
|
|
71218
72058
|
const settled = dispatching.then(
|
|
71219
72059
|
(outcome) => ({ kind: "ended", outcome }),
|
|
@@ -71222,7 +72062,7 @@ ${foldThreadEvents(folded)}` };
|
|
|
71222
72062
|
void settled.then((end) => {
|
|
71223
72063
|
releaseAdmission();
|
|
71224
72064
|
if (end.kind === "threw")
|
|
71225
|
-
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)}`);
|
|
71226
72066
|
});
|
|
71227
72067
|
const first = await Promise.race([started.then((id) => ({ kind: "started", id })), settled]);
|
|
71228
72068
|
if (first.kind === "started" || startedId !== void 0) {
|
|
@@ -71232,7 +72072,7 @@ ${foldThreadEvents(folded)}` };
|
|
|
71232
72072
|
{ instanceId: instance.id, unit: row2.unit },
|
|
71233
72073
|
folded.map((e) => e.seq),
|
|
71234
72074
|
req.step
|
|
71235
|
-
).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)}`));
|
|
71236
72076
|
log(
|
|
71237
72077
|
`[coordinator] ${instance.id} ${req.step}: folded ${folded.length} thread event(s) into the ${req.preset} child`
|
|
71238
72078
|
);
|
|
@@ -71240,7 +72080,7 @@ ${foldThreadEvents(folded)}` };
|
|
|
71240
72080
|
log(`[coordinator] ${instance.id} ${req.step}: spawned ${req.preset} run ${runId3} in ${threadKey}`);
|
|
71241
72081
|
return json3(200, { ok: true, runId: runId3, threadKey, at });
|
|
71242
72082
|
}
|
|
71243
|
-
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 });
|
|
71244
72084
|
const refusal = first.outcome.refusal;
|
|
71245
72085
|
if (refusal === "coordinator_thread_live") {
|
|
71246
72086
|
const now = await liveOnThread(deps.runs, instance, threadKey);
|
|
@@ -71424,6 +72264,25 @@ async function childPullRequestState(deps, instance, unit) {
|
|
|
71424
72264
|
if (state === void 0) throw new Error(headBranchStateError(instance.repo, row2.pr.number));
|
|
71425
72265
|
return state;
|
|
71426
72266
|
}
|
|
72267
|
+
async function isEarlierAttemptRun(deps, current, view, unit) {
|
|
72268
|
+
if (current?.plan === void 0 || view.parentInstanceId === void 0 || unit === void 0) return false;
|
|
72269
|
+
if (unitOfIdempotencyKey(view.idempotencyKey ?? "") !== unit) return false;
|
|
72270
|
+
const prior = await deps.instances.get(view.parentInstanceId);
|
|
72271
|
+
if (prior?.plan === void 0) return false;
|
|
72272
|
+
const currentAttempt = current.attempt ?? 1;
|
|
72273
|
+
const priorAttempt = prior.attempt ?? 1;
|
|
72274
|
+
if (currentAttempt <= priorAttempt || current.plan.id !== prior.plan.id || current.plan.path !== prior.plan.path || current.repo !== prior.repo)
|
|
72275
|
+
return false;
|
|
72276
|
+
const [nextAttempt, currentUnits, priorUnits] = await Promise.all([
|
|
72277
|
+
deps.instances.get(planInstanceId(current.plan.id, currentAttempt + 1)),
|
|
72278
|
+
deps.instances.listUnits(current.id),
|
|
72279
|
+
deps.instances.listUnits(prior.id)
|
|
72280
|
+
]);
|
|
72281
|
+
if (nextAttempt !== null) return false;
|
|
72282
|
+
const currentUnit = currentUnits.find((row2) => row2.unit === unit);
|
|
72283
|
+
const priorUnit = priorUnits.find((row2) => row2.unit === unit);
|
|
72284
|
+
return currentUnit !== void 0 && priorUnit !== void 0 && currentUnit.branch === priorUnit.branch;
|
|
72285
|
+
}
|
|
71427
72286
|
async function readRecord(body, deps) {
|
|
71428
72287
|
const id = parseInstanceId(body.parentInstanceId);
|
|
71429
72288
|
if (!id.ok) return json3(400, { ok: false, error: id.error });
|
|
@@ -71432,15 +72291,16 @@ async function readRecord(body, deps) {
|
|
|
71432
72291
|
if (body.unit !== void 0 && (typeof body.unit !== "string" || !UNIT_ID.test(body.unit)))
|
|
71433
72292
|
return json3(400, { ok: false, error: "unit must be a unit id" });
|
|
71434
72293
|
const at = (deps.clock ?? systemClock)();
|
|
71435
|
-
const res = await deps.runs.getRun(body.runId);
|
|
71436
|
-
if (!res.ok
|
|
72294
|
+
const [res, instanceRow] = await Promise.all([deps.runs.getRun(body.runId), deps.instances.get(id.value)]);
|
|
72295
|
+
if (!res.ok) return json3(404, { ok: false, error: "not_found" });
|
|
71437
72296
|
const view = res.value;
|
|
71438
|
-
|
|
72297
|
+
if (view.parentInstanceId !== id.value && !await isEarlierAttemptRun(deps, instanceRow, view, typeof body.unit === "string" ? body.unit : void 0))
|
|
72298
|
+
return json3(404, { ok: false, error: "not_found" });
|
|
71439
72299
|
let pullRequest;
|
|
71440
72300
|
try {
|
|
71441
72301
|
pullRequest = await childPullRequestState(deps, instanceRow, typeof body.unit === "string" ? body.unit : void 0);
|
|
71442
72302
|
} catch (err2) {
|
|
71443
|
-
return json3(502, { ok: false, error: "github_unavailable", message:
|
|
72303
|
+
return json3(502, { ok: false, error: "github_unavailable", message: describe12(err2), at });
|
|
71444
72304
|
}
|
|
71445
72305
|
if (!view.finished)
|
|
71446
72306
|
return json3(200, {
|
|
@@ -71756,7 +72616,7 @@ async function prCheck(body, deps) {
|
|
|
71756
72616
|
if (recover === void 0) {
|
|
71757
72617
|
const ahead = instance.base === void 0 ? void 0 : await deps.commitsOverBase(instance.repo, instance.base, branch2).catch((err2) => {
|
|
71758
72618
|
(deps.log ?? console.log)(
|
|
71759
|
-
`[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)}`
|
|
71760
72620
|
);
|
|
71761
72621
|
return void 0;
|
|
71762
72622
|
});
|
|
@@ -71780,7 +72640,7 @@ async function prCheck(body, deps) {
|
|
|
71780
72640
|
if (state?.state !== "merged") throw new Error(`${instance.repo}#${merged.number} no longer reads merged`);
|
|
71781
72641
|
return json3(200, { ok: true, ...state, at });
|
|
71782
72642
|
} catch (err2) {
|
|
71783
|
-
return json3(502, { ok: false, error: "github_unavailable", message:
|
|
72643
|
+
return json3(502, { ok: false, error: "github_unavailable", message: describe12(err2), at });
|
|
71784
72644
|
}
|
|
71785
72645
|
}
|
|
71786
72646
|
async function hostRunOf(deps, instance) {
|
|
@@ -71793,14 +72653,68 @@ async function hostRunOf(deps, instance) {
|
|
|
71793
72653
|
return { kind: "not_host" };
|
|
71794
72654
|
return { kind: "untracked" };
|
|
71795
72655
|
}
|
|
71796
|
-
function hostPublish(deps, instance, runId3, events, at) {
|
|
71797
|
-
for (const event of events) deps.registry.publish(runId3, event);
|
|
72656
|
+
async function hostPublish(deps, instance, runId3, events, at) {
|
|
71798
72657
|
const caps = instance.caps ?? resolveShipCaps(void 0);
|
|
71799
72658
|
const hosting = {
|
|
71800
72659
|
instanceId: instance.id,
|
|
71801
72660
|
until: at + minutesToMs(caps.maxMinutes + HOSTED_DEADLINE_MARGIN_MINUTES)
|
|
71802
72661
|
};
|
|
71803
|
-
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);
|
|
71804
72718
|
}
|
|
71805
72719
|
function namesForeignRun(instance, body) {
|
|
71806
72720
|
return typeof body.runId === "string" && body.runId !== instance.runId;
|
|
@@ -71886,7 +72800,7 @@ async function unitStart(body, deps) {
|
|
|
71886
72800
|
row2 = { ...row2, startedAt: row2.startedAt ?? at };
|
|
71887
72801
|
await deps.instances.putUnits([row2]);
|
|
71888
72802
|
if (host.kind === "host")
|
|
71889
|
-
hostPublish(
|
|
72803
|
+
await hostPublish(
|
|
71890
72804
|
deps,
|
|
71891
72805
|
instance,
|
|
71892
72806
|
host.runId,
|
|
@@ -71935,7 +72849,7 @@ async function branch(body, deps) {
|
|
|
71935
72849
|
await deps.createBranchRef(instance.repo, name, base);
|
|
71936
72850
|
return json3(200, { ok: true, branch: name, base, at });
|
|
71937
72851
|
} catch (err2) {
|
|
71938
|
-
return json3(200, { ok: false, reason:
|
|
72852
|
+
return json3(200, { ok: false, reason: describe12(err2), at });
|
|
71939
72853
|
}
|
|
71940
72854
|
}
|
|
71941
72855
|
function unitLines(units, generated, severity) {
|
|
@@ -72016,7 +72930,7 @@ async function round(body, deps) {
|
|
|
72016
72930
|
await deps.instances.putUnits([updated]);
|
|
72017
72931
|
if (host.kind === "host") {
|
|
72018
72932
|
const thread = unitThread(instance, updated, units.length);
|
|
72019
|
-
hostPublish(
|
|
72933
|
+
await hostPublish(
|
|
72020
72934
|
deps,
|
|
72021
72935
|
instance,
|
|
72022
72936
|
host.runId,
|
|
@@ -72050,7 +72964,7 @@ async function round(body, deps) {
|
|
|
72050
72964
|
instance,
|
|
72051
72965
|
units.map((u) => u.unit === updated.unit ? updated : u)
|
|
72052
72966
|
).catch(
|
|
72053
|
-
(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)}`)
|
|
72054
72968
|
);
|
|
72055
72969
|
return json3(200, { ok: true, at });
|
|
72056
72970
|
}
|
|
@@ -72224,7 +73138,7 @@ async function unitWake(body, deps) {
|
|
|
72224
73138
|
instance,
|
|
72225
73139
|
units.map((u) => u.unit === visible.unit ? visible : u)
|
|
72226
73140
|
).catch(
|
|
72227
|
-
(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)}`)
|
|
72228
73142
|
);
|
|
72229
73143
|
return json3(200, { ok: true, answer, at });
|
|
72230
73144
|
}
|
|
@@ -72287,7 +73201,7 @@ async function unitEnd(body, deps) {
|
|
|
72287
73201
|
deps.runnerOwnership?.release(instance.repo, updated.pr.number);
|
|
72288
73202
|
const thread = unitThread(instance, updated, units.length);
|
|
72289
73203
|
if (host.kind === "host")
|
|
72290
|
-
hostPublish(
|
|
73204
|
+
await hostPublish(
|
|
72291
73205
|
deps,
|
|
72292
73206
|
instance,
|
|
72293
73207
|
host.runId,
|
|
@@ -72318,7 +73232,7 @@ async function unitEnd(body, deps) {
|
|
|
72318
73232
|
`unit-end:${row2.unit}`
|
|
72319
73233
|
).catch(
|
|
72320
73234
|
(err2) => (deps.log ?? console.warn)(
|
|
72321
|
-
`[coordinator] ${instance.id} ${row2.unit}: the leftover marks failed: ${
|
|
73235
|
+
`[coordinator] ${instance.id} ${row2.unit}: the leftover marks failed: ${describe12(err2)}`
|
|
72322
73236
|
)
|
|
72323
73237
|
);
|
|
72324
73238
|
const freshTurn = {
|
|
@@ -72336,7 +73250,7 @@ async function unitEnd(body, deps) {
|
|
|
72336
73250
|
};
|
|
72337
73251
|
void deps.dispatch(freshTurn, io).catch(
|
|
72338
73252
|
(err2) => (deps.log ?? console.warn)(
|
|
72339
|
-
`[coordinator] ${instance.id} ${row2.unit}: the leftovers' fresh turn threw: ${
|
|
73253
|
+
`[coordinator] ${instance.id} ${row2.unit}: the leftovers' fresh turn threw: ${describe12(err2)}`
|
|
72340
73254
|
)
|
|
72341
73255
|
);
|
|
72342
73256
|
(deps.log ?? console.log)(
|
|
@@ -72353,7 +73267,7 @@ async function unitEnd(body, deps) {
|
|
|
72353
73267
|
told = true;
|
|
72354
73268
|
} catch (err2) {
|
|
72355
73269
|
(deps.log ?? console.warn)(
|
|
72356
|
-
`[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)}`
|
|
72357
73271
|
);
|
|
72358
73272
|
}
|
|
72359
73273
|
}
|
|
@@ -72367,7 +73281,7 @@ ${ending.report}` + (rendered !== void 0 ? `
|
|
|
72367
73281
|
${rendered}` : "");
|
|
72368
73282
|
await deps.github.commentIssue(instance.repo, row2.issue, comment).catch(
|
|
72369
73283
|
(err2) => (deps.log ?? console.warn)(
|
|
72370
|
-
`[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)}`
|
|
72371
73285
|
)
|
|
72372
73286
|
);
|
|
72373
73287
|
}
|
|
@@ -72378,7 +73292,7 @@ ${rendered}` : "");
|
|
|
72378
73292
|
|
|
72379
73293
|
${ending.report}`).catch(
|
|
72380
73294
|
(err2) => (deps.log ?? console.warn)(
|
|
72381
|
-
`[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)}`
|
|
72382
73296
|
)
|
|
72383
73297
|
);
|
|
72384
73298
|
}
|
|
@@ -72440,7 +73354,7 @@ async function rebaseStep(body, deps) {
|
|
|
72440
73354
|
at
|
|
72441
73355
|
});
|
|
72442
73356
|
} catch (err2) {
|
|
72443
|
-
return json3(200, { ok: true, outcome: "refused", reason:
|
|
73357
|
+
return json3(200, { ok: true, outcome: "refused", reason: describe12(err2), at });
|
|
72444
73358
|
}
|
|
72445
73359
|
}
|
|
72446
73360
|
async function merge(body, deps, subject2) {
|
|
@@ -72478,7 +73392,7 @@ async function merge(body, deps, subject2) {
|
|
|
72478
73392
|
try {
|
|
72479
73393
|
facts2 = await deps.fetchPrFacts(pr);
|
|
72480
73394
|
} catch (err2) {
|
|
72481
|
-
return json3(502, { ok: false, error: "github_unavailable", message:
|
|
73395
|
+
return json3(502, { ok: false, error: "github_unavailable", message: describe12(err2), at });
|
|
72482
73396
|
}
|
|
72483
73397
|
if (facts2 === void 0)
|
|
72484
73398
|
return json3(502, { ok: false, error: "github_unavailable", message: `${where} could not be read`, at });
|
|
@@ -72604,7 +73518,7 @@ async function merge(body, deps, subject2) {
|
|
|
72604
73518
|
try {
|
|
72605
73519
|
queued = await deps.enqueuePullRequest(pr, { sha: headSha });
|
|
72606
73520
|
} catch (err2) {
|
|
72607
|
-
return json3(502, { ok: false, error: "github_unavailable", message:
|
|
73521
|
+
return json3(502, { ok: false, error: "github_unavailable", message: describe12(err2), at });
|
|
72608
73522
|
}
|
|
72609
73523
|
if (!queued.ok) return refused7(`GitHub refused to enqueue ${where}: ${queued.reason}`);
|
|
72610
73524
|
log(
|
|
@@ -72621,7 +73535,7 @@ async function merge(body, deps, subject2) {
|
|
|
72621
73535
|
title: facts2.title ?? `Merge pull request #${pr.number}`
|
|
72622
73536
|
});
|
|
72623
73537
|
} catch (err2) {
|
|
72624
|
-
return json3(502, { ok: false, error: "github_unavailable", message:
|
|
73538
|
+
return json3(502, { ok: false, error: "github_unavailable", message: describe12(err2), at });
|
|
72625
73539
|
}
|
|
72626
73540
|
if (!merged.ok) {
|
|
72627
73541
|
if (merged.status === 405 && MERGE_QUEUE_405.test(merged.reason)) return enqueue();
|
|
@@ -72732,13 +73646,54 @@ async function finish(body, deps) {
|
|
|
72732
73646
|
if (host.kind === "not_host") return json3(409, { ok: false, error: "not_host", at });
|
|
72733
73647
|
const units = await deps.instances.listUnits(instance.id);
|
|
72734
73648
|
if (host.kind === "host") {
|
|
72735
|
-
|
|
72736
|
-
|
|
72737
|
-
|
|
72738
|
-
|
|
72739
|
-
|
|
72740
|
-
|
|
72741
|
-
|
|
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
|
+
}
|
|
72742
73697
|
deps.registry.finish(host.runId, body.outcome);
|
|
72743
73698
|
}
|
|
72744
73699
|
await drawCard(deps, instance, units, { icon: body.outcome === "completed" ? "\u2705" : "\u26A0\uFE0F" }).catch(() => {
|
|
@@ -72900,13 +73855,13 @@ function createAdminCoordinatorHandler(deps) {
|
|
|
72900
73855
|
}
|
|
72901
73856
|
write(res, await answerCoordinatorStep(door, read.body, deps));
|
|
72902
73857
|
} catch (err2) {
|
|
72903
|
-
(deps.log ?? console.error)(`[coordinator] ${
|
|
73858
|
+
(deps.log ?? console.error)(`[coordinator] ${describe12(err2)}`);
|
|
72904
73859
|
write(res, json3(500, { ok: false, error: "internal error" }));
|
|
72905
73860
|
}
|
|
72906
73861
|
})();
|
|
72907
73862
|
};
|
|
72908
73863
|
}
|
|
72909
|
-
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;
|
|
72910
73865
|
var init_adminCoordinator = __esm({
|
|
72911
73866
|
"../../src/channels/adminCoordinator.ts"() {
|
|
72912
73867
|
"use strict";
|
|
@@ -72953,7 +73908,7 @@ var init_adminCoordinator = __esm({
|
|
|
72953
73908
|
};
|
|
72954
73909
|
invalid = (error) => ({ ok: false, error });
|
|
72955
73910
|
json3 = (status3, body) => ({ status: status3, body });
|
|
72956
|
-
|
|
73911
|
+
describe12 = (err2) => err2 instanceof Error ? err2.message : String(err2);
|
|
72957
73912
|
isGenerated2 = (instance) => instance.plan?.path === void 0;
|
|
72958
73913
|
EVERY_RUN = { kind: "all" };
|
|
72959
73914
|
REVIEW_POSTED_CHECKS = 3;
|
|
@@ -73824,11 +74779,7 @@ async function runBot() {
|
|
|
73824
74779
|
const coordinatorInstances = buildCoordinatorInstanceStore(runHistoryCfg, processSecrets);
|
|
73825
74780
|
const decisionRecordAllocator = new DecisionRecordAllocator(
|
|
73826
74781
|
fetchDecisionRecordClaims,
|
|
73827
|
-
|
|
73828
|
-
const reserved = await coordinatorInstances.reserveDecisionRecord(repo, taskKey, claimed2, existing);
|
|
73829
|
-
if (!reserved.ok) throw new DecisionRecordReservationUnavailableError();
|
|
73830
|
-
return reserved.number;
|
|
73831
|
-
}
|
|
74782
|
+
durableDecisionRecordReservation(coordinatorInstances)
|
|
73832
74783
|
);
|
|
73833
74784
|
let planeAdmitPass;
|
|
73834
74785
|
const planeEffectExecutor = {
|
|
@@ -74100,9 +75051,7 @@ async function runBot() {
|
|
|
74100
75051
|
slackIntake = wireIntakeGate({
|
|
74101
75052
|
intakeModeFor: (threadKey, userId, channelId) => config.intakeModeFor(threadKey, userId, channelId),
|
|
74102
75053
|
deps: {
|
|
74103
|
-
|
|
74104
|
-
ledger: intakeLedger,
|
|
74105
|
-
now: systemClock
|
|
75054
|
+
...intakeDecisionDeps(intake, { ledger: intakeLedger, now: systemClock })
|
|
74106
75055
|
},
|
|
74107
75056
|
modelRef: intake.modelRef,
|
|
74108
75057
|
gen: PROCESS_STARTED_AT,
|
|
@@ -74194,6 +75143,13 @@ async function runBot() {
|
|
|
74194
75143
|
if (process.env.PORT) {
|
|
74195
75144
|
const ingress = createIngressHandler(deps, { auth, publicBaseUrl: process.env.PUBLIC_BASE_URL, personByEmail });
|
|
74196
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
|
+
});
|
|
74197
75153
|
const modelProxy = createModelProxyHandler({
|
|
74198
75154
|
bearers: runBearers,
|
|
74199
75155
|
providers: () => config.config.providers,
|
|
@@ -74202,17 +75158,11 @@ async function runBot() {
|
|
|
74202
75158
|
...costsCfg?.prices ? { prices: () => costsCfg.prices } : {},
|
|
74203
75159
|
secrets: processSecrets,
|
|
74204
75160
|
clock: systemClock,
|
|
74205
|
-
// The plane's provider seam (model-proxy item 12a; record 0064):
|
|
74206
|
-
// and
|
|
74207
|
-
// 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.
|
|
74208
75163
|
plane: {
|
|
74209
|
-
level: (provider, side, cause) => void
|
|
74210
|
-
|
|
74211
|
-
name: "provider",
|
|
74212
|
-
side,
|
|
74213
|
-
...side === "down" && cause !== void 0 ? { cause } : {}
|
|
74214
|
-
}),
|
|
74215
|
-
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)
|
|
74216
75166
|
}
|
|
74217
75167
|
});
|
|
74218
75168
|
const harnessRoutes = createHarnessRoutesHandler({ bearers: runBearers, harnesses, takeover });
|
|
@@ -74956,6 +75906,7 @@ var init_index = __esm({
|
|
|
74956
75906
|
init_adminModelProxy();
|
|
74957
75907
|
init_modelProxy();
|
|
74958
75908
|
init_runBearers();
|
|
75909
|
+
init_providerLiveStateCoordinator();
|
|
74959
75910
|
init_piHarness();
|
|
74960
75911
|
init_harness2();
|
|
74961
75912
|
init_relay();
|