@coreplane/switchboard 1.260.5 → 1.260.6
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 +17 -3
- 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/refusal.ts +1 -1
- package/dist/assets/src/core/runLedger/decisions.ts +10 -1
- package/dist/assets/src/core/runLedger/types.ts +3 -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 +728 -556
- 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,
|
|
@@ -15400,7 +15401,7 @@ var init_refusal = __esm({
|
|
|
15400
15401
|
repo_not_onboarded: "request",
|
|
15401
15402
|
repo_access: "policy",
|
|
15402
15403
|
pr_head_unknown: "system",
|
|
15403
|
-
|
|
15404
|
+
workspace_head_mismatch: "system",
|
|
15404
15405
|
coordinator_thread_live: "system",
|
|
15405
15406
|
live_agent_allowlist: "policy",
|
|
15406
15407
|
follow_up_refused: "request",
|
|
@@ -29134,6 +29135,505 @@ var init_llmOutput = __esm({
|
|
|
29134
29135
|
}
|
|
29135
29136
|
});
|
|
29136
29137
|
|
|
29138
|
+
// ../../src/core/dispatch/handBack.ts
|
|
29139
|
+
function renderHandBackLine(line4) {
|
|
29140
|
+
return `${HAND_BACK_PREFIX}
|
|
29141
|
+
\`${line4}\``;
|
|
29142
|
+
}
|
|
29143
|
+
var HAND_BACK_PREFIX;
|
|
29144
|
+
var init_handBack = __esm({
|
|
29145
|
+
"../../src/core/dispatch/handBack.ts"() {
|
|
29146
|
+
"use strict";
|
|
29147
|
+
HAND_BACK_PREFIX = "To run this:";
|
|
29148
|
+
}
|
|
29149
|
+
});
|
|
29150
|
+
|
|
29151
|
+
// ../../src/core/statusCardFrame.ts
|
|
29152
|
+
function activityText(activity) {
|
|
29153
|
+
if (!activity) return void 0;
|
|
29154
|
+
if (activity.kind === "line") return activity.text;
|
|
29155
|
+
return `\u2192 $ ${activity.command.replace(/\s+/g, " ").trim()}`;
|
|
29156
|
+
}
|
|
29157
|
+
function createCardShell(opts) {
|
|
29158
|
+
const verbosity2 = opts.verbosity ?? DEFAULT_VERBOSITY;
|
|
29159
|
+
const notes = [];
|
|
29160
|
+
let link = opts.link;
|
|
29161
|
+
let frame2 = 0;
|
|
29162
|
+
let finishedAt;
|
|
29163
|
+
let setupLabel;
|
|
29164
|
+
const lead = opts.lead ?? [];
|
|
29165
|
+
const base = () => opts.model !== void 0 && shows(verbosity2, "verbose") ? `${opts.label} on \`${opts.model}\`` : opts.label;
|
|
29166
|
+
const label = () => [base(), ...notes.filter((n2) => shows(verbosity2, n2.level)).map((n2) => n2.text)].join(" \xB7 ");
|
|
29167
|
+
const elapsed2 = () => formatDuration((finishedAt ?? opts.now()) - opts.startedAt, "clock");
|
|
29168
|
+
const headline = (icon) => `${icon} ${label()} \xB7 ${elapsed2()}`;
|
|
29169
|
+
const closeDetail = (close, own) => [...shows(verbosity2, "debug") ? [close.shape, close.queued] : [], own].filter(Boolean).join("\n") || void 0;
|
|
29170
|
+
return {
|
|
29171
|
+
get label() {
|
|
29172
|
+
return label();
|
|
29173
|
+
},
|
|
29174
|
+
note(level, text) {
|
|
29175
|
+
notes.push({ level, text });
|
|
29176
|
+
},
|
|
29177
|
+
setLink(next) {
|
|
29178
|
+
link = next;
|
|
29179
|
+
},
|
|
29180
|
+
freeze(at) {
|
|
29181
|
+
finishedAt = at;
|
|
29182
|
+
},
|
|
29183
|
+
setSetupLabel(next) {
|
|
29184
|
+
setupLabel = next;
|
|
29185
|
+
},
|
|
29186
|
+
ack() {
|
|
29187
|
+
const detail = lead.join("\n");
|
|
29188
|
+
return { title: `\u{1F440} ${label()} \xB7 preparing workspace\u2026`, ...detail ? { detail } : {} };
|
|
29189
|
+
},
|
|
29190
|
+
live(parts = {}) {
|
|
29191
|
+
const glyph = SPINNER_GLYPHS[frame2++ % SPINNER_GLYPHS.length];
|
|
29192
|
+
const detail = [...lead, ...parts.detail ?? []].filter(Boolean).join("\n");
|
|
29193
|
+
return {
|
|
29194
|
+
title: headline(glyph) + (setupLabel ? ` \u2014 ${setupLabel}` : "") + (parts.suffix ?? "") + (parts.notice ? ` \xB7 ${parts.notice}` : ""),
|
|
29195
|
+
detail: detail || void 0,
|
|
29196
|
+
...parts.activity ? { activity: parts.activity } : {},
|
|
29197
|
+
link
|
|
29198
|
+
};
|
|
29199
|
+
},
|
|
29200
|
+
close(close) {
|
|
29201
|
+
const detail = closeDetail(close, close.kind === "done" ? close.detail : void 0);
|
|
29202
|
+
switch (close.kind) {
|
|
29203
|
+
case "done":
|
|
29204
|
+
return { title: headline(close.icon), detail, link };
|
|
29205
|
+
case "not_started":
|
|
29206
|
+
return { title: `${close.icon} ${label()} \xB7 not started (${close.reason}) \xB7 ${elapsed2()}`, detail };
|
|
29207
|
+
case "refused":
|
|
29208
|
+
return { title: `${close.icon} ${label()} \xB7 ${close.reason} \xB7 ${elapsed2()}`, detail };
|
|
29209
|
+
case "setup_failed":
|
|
29210
|
+
return { title: `\u274C setup failed \xB7 ${close.reason} \xB7 ${elapsed2()}`, detail };
|
|
29211
|
+
}
|
|
29212
|
+
}
|
|
29213
|
+
};
|
|
29214
|
+
}
|
|
29215
|
+
var SPINNER_GLYPHS, LIVE_CARD_PREFIXES, ROUTE_REASON_PREFIX;
|
|
29216
|
+
var init_statusCardFrame = __esm({
|
|
29217
|
+
"../../src/core/statusCardFrame.ts"() {
|
|
29218
|
+
"use strict";
|
|
29219
|
+
init_formatDuration();
|
|
29220
|
+
init_verbosity();
|
|
29221
|
+
SPINNER_GLYPHS = ["\u25D0", "\u25D3", "\u25D1", "\u25D2"];
|
|
29222
|
+
LIVE_CARD_PREFIXES = [...SPINNER_GLYPHS, "\u{1F440}"];
|
|
29223
|
+
ROUTE_REASON_PREFIX = "route reason:";
|
|
29224
|
+
}
|
|
29225
|
+
});
|
|
29226
|
+
|
|
29227
|
+
// ../../src/core/confirmations.ts
|
|
29228
|
+
import { randomUUID } from "node:crypto";
|
|
29229
|
+
import { existsSync as existsSync12, mkdirSync as mkdirSync9, readFileSync as readFileSync14, writeFileSync as writeFileSync8 } from "node:fs";
|
|
29230
|
+
import { dirname as dirname10, resolve as resolve9 } from "node:path";
|
|
29231
|
+
function newConfirmationId() {
|
|
29232
|
+
return randomUUID();
|
|
29233
|
+
}
|
|
29234
|
+
function renderOffer(offer) {
|
|
29235
|
+
if (offer.question) return `${offer.question.text}
|
|
29236
|
+
Did you mean:
|
|
29237
|
+
\`${offer.line}\`
|
|
29238
|
+
|
|
29239
|
+
${offer.question.evidence}`;
|
|
29240
|
+
return [offer.line, ...offer.risk ? [offer.risk] : []].join("\n");
|
|
29241
|
+
}
|
|
29242
|
+
function confirmationMessageOf(msg) {
|
|
29243
|
+
const { images: _images, documents: _documents, staged: _staged, ...kept } = msg;
|
|
29244
|
+
return kept;
|
|
29245
|
+
}
|
|
29246
|
+
function isRecord3(v) {
|
|
29247
|
+
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
29248
|
+
}
|
|
29249
|
+
function isMessage(v) {
|
|
29250
|
+
return isRecord3(v) && typeof v.channelId === "string" && typeof v.userId === "string" && typeof v.threadKey === "string" && typeof v.text === "string";
|
|
29251
|
+
}
|
|
29252
|
+
function isRunShape(v) {
|
|
29253
|
+
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";
|
|
29254
|
+
}
|
|
29255
|
+
function isRedispatchShape(v) {
|
|
29256
|
+
return typeof v.id === "string" && isMessage(v.message) && typeof v.line === "string" && typeof v.evidence === "string" && typeof v.code === "string";
|
|
29257
|
+
}
|
|
29258
|
+
function parsePendingConfirmation(v) {
|
|
29259
|
+
if (!isRecord3(v)) return void 0;
|
|
29260
|
+
if (v.kind === "redispatch")
|
|
29261
|
+
return isRedispatchShape(v) ? v : void 0;
|
|
29262
|
+
if (v.kind !== void 0 && v.kind !== "run") return void 0;
|
|
29263
|
+
return isRunShape(v) ? { ...v, kind: "run" } : void 0;
|
|
29264
|
+
}
|
|
29265
|
+
function parseConfirmation(v) {
|
|
29266
|
+
if (!isRecord3(v) || typeof v.expiresAt !== "number") return void 0;
|
|
29267
|
+
const pending2 = parsePendingConfirmation(v);
|
|
29268
|
+
return pending2 ? { ...pending2, expiresAt: v.expiresAt } : void 0;
|
|
29269
|
+
}
|
|
29270
|
+
function isRefusal(v) {
|
|
29271
|
+
return typeof v === "string" && CONFIRMATION_REFUSALS.includes(v);
|
|
29272
|
+
}
|
|
29273
|
+
function judge2(rows, id, actorIds, now, kind) {
|
|
29274
|
+
const row2 = rows.get(id);
|
|
29275
|
+
if (!row2) return { ok: false, refused: "used" };
|
|
29276
|
+
if (kind === "consume" && row2.expiresAt <= now) {
|
|
29277
|
+
rows.delete(id);
|
|
29278
|
+
return { ok: false, refused: "expired", row: row2 };
|
|
29279
|
+
}
|
|
29280
|
+
if (!actorIds.includes(row2.message.userId))
|
|
29281
|
+
return kind === "consume" ? { ok: false, refused: "foreign", row: row2 } : { ok: false, refused: "foreign" };
|
|
29282
|
+
rows.delete(id);
|
|
29283
|
+
return kind === "consume" ? { ok: true, row: row2 } : { ok: true };
|
|
29284
|
+
}
|
|
29285
|
+
function replaceThreadRow(rows, row2) {
|
|
29286
|
+
for (const [id, r] of rows) if (r.message.threadKey === row2.message.threadKey) rows.delete(id);
|
|
29287
|
+
rows.set(row2.id, row2);
|
|
29288
|
+
}
|
|
29289
|
+
function threadRowId(rows, threadKey) {
|
|
29290
|
+
for (const [id, r] of rows) if (r.message.threadKey === threadKey) return id;
|
|
29291
|
+
return void 0;
|
|
29292
|
+
}
|
|
29293
|
+
function buildConfirmationStore(config, secrets, opts) {
|
|
29294
|
+
const worker = config.config.runtimeOverrides?.worker;
|
|
29295
|
+
if (!worker) return new FileConfirmationStore(opts.path);
|
|
29296
|
+
const tokenEnv = worker.tokenEnv ?? "MEMORY_TOKEN";
|
|
29297
|
+
const token2 = secrets.named(tokenEnv);
|
|
29298
|
+
if (!token2) throw new Error(`runtimeOverrides.worker is configured but ${tokenEnv} is not set`);
|
|
29299
|
+
return new WorkerConfirmationStore({
|
|
29300
|
+
baseUrl: worker.baseUrl,
|
|
29301
|
+
token: token2.reveal(),
|
|
29302
|
+
...opts.fetch ? { fetch: opts.fetch } : {}
|
|
29303
|
+
});
|
|
29304
|
+
}
|
|
29305
|
+
var CONFIRMATION_REFUSALS, UNSHOWABLE_LINE, STORE_UNREACHABLE_LINE, FileConfirmationStore, CONFIRMATION_WORKER_TIMEOUT_MS, WorkerConfirmationStore;
|
|
29306
|
+
var init_confirmations = __esm({
|
|
29307
|
+
"../../src/core/confirmations.ts"() {
|
|
29308
|
+
"use strict";
|
|
29309
|
+
init_clock();
|
|
29310
|
+
CONFIRMATION_REFUSALS = ["used", "expired", "foreign"];
|
|
29311
|
+
UNSHOWABLE_LINE = "this command carries a value that cannot be shown, so no confirmation can be offered; nothing ran";
|
|
29312
|
+
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";
|
|
29313
|
+
FileConfirmationStore = class {
|
|
29314
|
+
path;
|
|
29315
|
+
clock;
|
|
29316
|
+
constructor(path, opts = {}) {
|
|
29317
|
+
this.path = resolve9(path);
|
|
29318
|
+
this.clock = opts.clock ?? systemClock;
|
|
29319
|
+
}
|
|
29320
|
+
read() {
|
|
29321
|
+
const rows = /* @__PURE__ */ new Map();
|
|
29322
|
+
if (!existsSync12(this.path)) return rows;
|
|
29323
|
+
const raw = JSON.parse(readFileSync14(this.path, "utf8"));
|
|
29324
|
+
for (const v of Array.isArray(raw.confirmations) ? raw.confirmations : []) {
|
|
29325
|
+
const row2 = parseConfirmation(v);
|
|
29326
|
+
if (row2) rows.set(row2.id, row2);
|
|
29327
|
+
}
|
|
29328
|
+
return rows;
|
|
29329
|
+
}
|
|
29330
|
+
write(rows) {
|
|
29331
|
+
mkdirSync9(dirname10(this.path), { recursive: true });
|
|
29332
|
+
writeFileSync8(this.path, JSON.stringify({ confirmations: [...rows.values()] }, null, 2));
|
|
29333
|
+
}
|
|
29334
|
+
async put(row2, ttlMs) {
|
|
29335
|
+
const rows = this.read();
|
|
29336
|
+
const stored = { ...row2, expiresAt: this.clock() + ttlMs };
|
|
29337
|
+
replaceThreadRow(rows, stored);
|
|
29338
|
+
this.write(rows);
|
|
29339
|
+
return stored;
|
|
29340
|
+
}
|
|
29341
|
+
async consume(id, actorIds) {
|
|
29342
|
+
const rows = this.read();
|
|
29343
|
+
const out = judge2(rows, id, actorIds, this.clock(), "consume");
|
|
29344
|
+
this.write(rows);
|
|
29345
|
+
return out;
|
|
29346
|
+
}
|
|
29347
|
+
async cancel(id, actorIds) {
|
|
29348
|
+
const rows = this.read();
|
|
29349
|
+
const out = judge2(rows, id, actorIds, this.clock(), "cancel");
|
|
29350
|
+
this.write(rows);
|
|
29351
|
+
return out;
|
|
29352
|
+
}
|
|
29353
|
+
async cancelByThread(threadKey, actorIds) {
|
|
29354
|
+
const rows = this.read();
|
|
29355
|
+
const id = threadRowId(rows, threadKey);
|
|
29356
|
+
if (id === void 0) return { ok: false, refused: "used" };
|
|
29357
|
+
const out = judge2(rows, id, actorIds, this.clock(), "cancel");
|
|
29358
|
+
this.write(rows);
|
|
29359
|
+
return out;
|
|
29360
|
+
}
|
|
29361
|
+
async pendingByThread(threadKey) {
|
|
29362
|
+
const rows = this.read();
|
|
29363
|
+
const id = threadRowId(rows, threadKey);
|
|
29364
|
+
const row2 = id === void 0 ? void 0 : rows.get(id);
|
|
29365
|
+
if (!row2 || row2.expiresAt <= this.clock()) return void 0;
|
|
29366
|
+
return row2;
|
|
29367
|
+
}
|
|
29368
|
+
describe() {
|
|
29369
|
+
return `file ${this.path}`;
|
|
29370
|
+
}
|
|
29371
|
+
};
|
|
29372
|
+
CONFIRMATION_WORKER_TIMEOUT_MS = 8e3;
|
|
29373
|
+
WorkerConfirmationStore = class {
|
|
29374
|
+
constructor(opts) {
|
|
29375
|
+
this.opts = opts;
|
|
29376
|
+
this.baseUrl = opts.baseUrl.replace(/\/+$/, "");
|
|
29377
|
+
this.fetchImpl = opts.fetch ?? fetch;
|
|
29378
|
+
}
|
|
29379
|
+
opts;
|
|
29380
|
+
baseUrl;
|
|
29381
|
+
fetchImpl;
|
|
29382
|
+
async put(row2, ttlMs) {
|
|
29383
|
+
const body = await this.post("/config/confirmations/put", {
|
|
29384
|
+
id: row2.id,
|
|
29385
|
+
threadKey: row2.message.threadKey,
|
|
29386
|
+
requester: row2.message.userId,
|
|
29387
|
+
body: row2,
|
|
29388
|
+
ttlMs
|
|
29389
|
+
});
|
|
29390
|
+
if (typeof body.expiresAt !== "number")
|
|
29391
|
+
throw new Error("confirmation store answered a put without the expiry it stamped");
|
|
29392
|
+
return { ...row2, expiresAt: body.expiresAt };
|
|
29393
|
+
}
|
|
29394
|
+
async consume(id, actorIds) {
|
|
29395
|
+
const body = await this.post("/config/confirmations/consume", { id, actorIds });
|
|
29396
|
+
const stored = isRecord3(body.row) ? body.row : void 0;
|
|
29397
|
+
const row2 = parseConfirmation(
|
|
29398
|
+
stored && isRecord3(stored.body) ? { ...stored.body, expiresAt: stored.expiresAt } : void 0
|
|
29399
|
+
);
|
|
29400
|
+
if (isRefusal(body.refused))
|
|
29401
|
+
return { ok: false, refused: body.refused, ...row2 ? { row: row2 } : {} };
|
|
29402
|
+
if (!row2) throw new Error("confirmation store answered a consume outside its contract");
|
|
29403
|
+
return { ok: true, row: row2 };
|
|
29404
|
+
}
|
|
29405
|
+
async cancel(id, actorIds) {
|
|
29406
|
+
const body = await this.post("/config/confirmations/cancel", { id, actorIds });
|
|
29407
|
+
if (body.ok === true) return { ok: true };
|
|
29408
|
+
if (body.refused === "used" || body.refused === "foreign") return { ok: false, refused: body.refused };
|
|
29409
|
+
throw new Error("confirmation store answered a cancel outside its contract");
|
|
29410
|
+
}
|
|
29411
|
+
async cancelByThread(threadKey, actorIds) {
|
|
29412
|
+
const body = await this.post("/config/confirmations/cancel-by-thread", { threadKey, actorIds });
|
|
29413
|
+
if (body.ok === true) return { ok: true };
|
|
29414
|
+
if (body.refused === "used" || body.refused === "foreign") return { ok: false, refused: body.refused };
|
|
29415
|
+
throw new Error("confirmation store answered a cancel-by-thread outside its contract");
|
|
29416
|
+
}
|
|
29417
|
+
async pendingByThread(threadKey) {
|
|
29418
|
+
const body = await this.post("/config/confirmations/pending-by-thread", { threadKey });
|
|
29419
|
+
if (body.row === null) return void 0;
|
|
29420
|
+
const stored = isRecord3(body.row) ? body.row : void 0;
|
|
29421
|
+
const row2 = parseConfirmation(
|
|
29422
|
+
stored && isRecord3(stored.body) ? { ...stored.body, expiresAt: stored.expiresAt } : void 0
|
|
29423
|
+
);
|
|
29424
|
+
if (!row2) throw new Error("confirmation store answered a pending-by-thread outside its contract");
|
|
29425
|
+
return row2;
|
|
29426
|
+
}
|
|
29427
|
+
describe() {
|
|
29428
|
+
return `state Worker ${this.baseUrl} (ConfigDO confirmations)`;
|
|
29429
|
+
}
|
|
29430
|
+
async post(path, payload2) {
|
|
29431
|
+
let res;
|
|
29432
|
+
try {
|
|
29433
|
+
res = await this.fetchImpl(`${this.baseUrl}${path}`, {
|
|
29434
|
+
method: "POST",
|
|
29435
|
+
headers: { authorization: `Bearer ${this.opts.token}`, "content-type": "application/json" },
|
|
29436
|
+
body: JSON.stringify(payload2),
|
|
29437
|
+
signal: AbortSignal.timeout(CONFIRMATION_WORKER_TIMEOUT_MS)
|
|
29438
|
+
});
|
|
29439
|
+
} catch (err2) {
|
|
29440
|
+
throw new Error(`confirmation store unreachable: ${err2 instanceof Error ? err2.message : String(err2)}`, {
|
|
29441
|
+
cause: err2
|
|
29442
|
+
});
|
|
29443
|
+
}
|
|
29444
|
+
if (!res.ok) throw new Error(`confirmation store answered HTTP ${res.status} on ${path}`);
|
|
29445
|
+
const body = await res.json().catch(() => void 0);
|
|
29446
|
+
if (!isRecord3(body)) throw new Error(`confirmation store returned a non-JSON body on ${path}`);
|
|
29447
|
+
return body;
|
|
29448
|
+
}
|
|
29449
|
+
};
|
|
29450
|
+
}
|
|
29451
|
+
});
|
|
29452
|
+
|
|
29453
|
+
// ../../src/core/dispatch/route.ts
|
|
29454
|
+
function outputCapWithReasoning(visibleAnswerTokens, opts = {}) {
|
|
29455
|
+
return opts.capField !== void 0 && REASONING_COUNTING_CAP_FIELDS.has(opts.capField) ? visibleAnswerTokens + REASONING_OUTPUT_TOKEN_ALLOWANCE : visibleAnswerTokens;
|
|
29456
|
+
}
|
|
29457
|
+
function outputCapRetry(current) {
|
|
29458
|
+
return Math.max(current * 2, REASONING_OUTPUT_TOKEN_ALLOWANCE);
|
|
29459
|
+
}
|
|
29460
|
+
function routedRunsAtOnce(def, confirm, input) {
|
|
29461
|
+
const radius = input === void 0 ? blastRadius(def) : boundBlastRadius(def, input);
|
|
29462
|
+
return radius === "read" || CONFIRM_ORDER[radius] < CONFIRM_ORDER[confirm];
|
|
29463
|
+
}
|
|
29464
|
+
function routeReceipt(def, input) {
|
|
29465
|
+
return redactAndCap(chatInvocation(def, input), ROUTE_RECEIPT_CAP);
|
|
29466
|
+
}
|
|
29467
|
+
function routablePresets() {
|
|
29468
|
+
return Object.values(AGENTS).filter((a) => a.routable !== false).map(({ name, description, machine, identity: identity2, maxMinutes }) => ({
|
|
29469
|
+
name,
|
|
29470
|
+
description,
|
|
29471
|
+
machine,
|
|
29472
|
+
identity: identity2,
|
|
29473
|
+
maxMinutes
|
|
29474
|
+
}));
|
|
29475
|
+
}
|
|
29476
|
+
function routableCommands(commands) {
|
|
29477
|
+
return commands.list().filter((cmd) => CommandRegistry.exposedTo(cmd, "chat")).map((cmd) => ({
|
|
29478
|
+
id: cmd.id,
|
|
29479
|
+
effect: cmd.effect,
|
|
29480
|
+
def: cmd,
|
|
29481
|
+
tool: { name: mcpToolName(cmd.id), description: cmd.describe, inputSchema: jsonSchemaFor(cmd) }
|
|
29482
|
+
}));
|
|
29483
|
+
}
|
|
29484
|
+
function renderPresetTable(presets) {
|
|
29485
|
+
const rows = presets.map(
|
|
29486
|
+
(p) => `| \`${p.name}\` | ${oneLine(p.description)} | ${p.machine} | ${p.identity} | ${p.maxMinutes} min |`
|
|
29487
|
+
);
|
|
29488
|
+
return ["| name | what it does | machine | credential | budget |", "|---|---|---|---|---|", ...rows].join("\n");
|
|
29489
|
+
}
|
|
29490
|
+
function quoteRequest(text) {
|
|
29491
|
+
const cap = 2e3;
|
|
29492
|
+
const bent = text.replace(/<(\/?)request>/gi, "\u2039$1request\u203A");
|
|
29493
|
+
if (bent.length <= cap) return bent;
|
|
29494
|
+
return `${bent.slice(0, cap)}
|
|
29495
|
+
\u2026[truncated: ${bent.length - cap} more characters]`;
|
|
29496
|
+
}
|
|
29497
|
+
function providerStructuredModel(provider, model, opts = {}) {
|
|
29498
|
+
const forced = (opts.answer ?? "tool") === "tool";
|
|
29499
|
+
return async (prompt, call2) => {
|
|
29500
|
+
const tools = [prompt.tool, ...prompt.tools ?? []];
|
|
29501
|
+
const toolChoice = prompt.open ? void 0 : tools.length > 1 ? { type: "any" } : { type: "tool", name: prompt.tool.name };
|
|
29502
|
+
const messages = [
|
|
29503
|
+
{ role: "user", content: [{ type: "text", text: prompt.user }] },
|
|
29504
|
+
...(prompt.retries ?? []).flatMap((r) => [
|
|
29505
|
+
{ role: "assistant", content: [{ type: "text", text: r.answer }] },
|
|
29506
|
+
{ role: "user", content: [{ type: "text", text: r.violation }] }
|
|
29507
|
+
])
|
|
29508
|
+
];
|
|
29509
|
+
const result = await provider.complete({
|
|
29510
|
+
model,
|
|
29511
|
+
system: prompt.system,
|
|
29512
|
+
messages,
|
|
29513
|
+
maxTokens: call2.maxTokens,
|
|
29514
|
+
signal: call2.signal,
|
|
29515
|
+
// The caller's configured effort, card-decided (`turnEffort`): intake's
|
|
29516
|
+
// `intake.effort` or the operator's `defaults.efforts.general`. Absent →
|
|
29517
|
+
// the model's own default.
|
|
29518
|
+
...opts.effort ? { effort: opts.effort.effort, effortWord: opts.effort.effortWord } : {},
|
|
29519
|
+
...forced ? { tools, toolChoice } : {}
|
|
29520
|
+
});
|
|
29521
|
+
if (result.stopReason === "max_tokens") throw new OutputCapError(call2.maxTokens);
|
|
29522
|
+
const calls = result.content.filter(
|
|
29523
|
+
(p) => p.type === "tool_use"
|
|
29524
|
+
);
|
|
29525
|
+
if (calls.length > 1) throw new MultiToolCallError(calls.map((c) => ({ tool: c.name, input: c.input })));
|
|
29526
|
+
if (calls.length === 1) return { tool: calls[0].name, input: calls[0].input };
|
|
29527
|
+
return result.content.filter((p) => p.type === "text").map((p) => p.text).join("");
|
|
29528
|
+
};
|
|
29529
|
+
}
|
|
29530
|
+
async function mintConfirmationOffer(args) {
|
|
29531
|
+
const { io, store, msg, origin, def, input, receipt, model } = args;
|
|
29532
|
+
if (!io.offer || !store) return { kind: "no_click" };
|
|
29533
|
+
const line4 = chatInvocation(def, input);
|
|
29534
|
+
if (redactSecrets(line4) !== line4) return { kind: "unshowable" };
|
|
29535
|
+
const risk = def.annotations?.risk?.(input, origin) ?? "";
|
|
29536
|
+
let row2;
|
|
29537
|
+
try {
|
|
29538
|
+
row2 = await store.put(
|
|
29539
|
+
{
|
|
29540
|
+
kind: "run",
|
|
29541
|
+
id: newConfirmationId(),
|
|
29542
|
+
message: confirmationMessageOf(msg),
|
|
29543
|
+
command: def.id,
|
|
29544
|
+
input,
|
|
29545
|
+
receipt,
|
|
29546
|
+
risk,
|
|
29547
|
+
model
|
|
29548
|
+
},
|
|
29549
|
+
CONFIRMATION_TTL_MS
|
|
29550
|
+
);
|
|
29551
|
+
} catch (err2) {
|
|
29552
|
+
console.warn(
|
|
29553
|
+
`[route] ${msg.threadKey} confirmation store unreachable at mint, handing back: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
29554
|
+
);
|
|
29555
|
+
return { kind: "store_unreachable" };
|
|
29556
|
+
}
|
|
29557
|
+
return { kind: "offered", shown: { id: row2.id, line: line4, risk, expiresAt: row2.expiresAt } };
|
|
29558
|
+
}
|
|
29559
|
+
function redactedInput(input) {
|
|
29560
|
+
const text = (s) => redactAndCap(redactSecrets(s), 200);
|
|
29561
|
+
const leaf = (v) => {
|
|
29562
|
+
if (typeof v === "string") return text(v);
|
|
29563
|
+
if (typeof v === "number" || typeof v === "boolean" || v === null) return v;
|
|
29564
|
+
return v === void 0 ? null : text(JSON.stringify(v) ?? String(v));
|
|
29565
|
+
};
|
|
29566
|
+
const leafOrList = (v) => Array.isArray(v) ? v.map(leaf) : leaf(v);
|
|
29567
|
+
const isRecord11 = (v) => typeof v === "object" && v !== null && (Object.getPrototypeOf(v) === Object.prototype || Object.getPrototypeOf(v) === null);
|
|
29568
|
+
const entries = (v, of) => Object.fromEntries(
|
|
29569
|
+
Object.entries(v).filter(([, x]) => x !== void 0).map(([k, x]) => [k, of(x)])
|
|
29570
|
+
);
|
|
29571
|
+
const object1 = (v) => entries(v, leafOrList);
|
|
29572
|
+
const object2 = (v) => entries(v, (x) => isRecord11(x) ? object1(x) : leafOrList(x));
|
|
29573
|
+
const object3 = (v) => entries(v, (x) => isRecord11(x) ? object2(x) : leafOrList(x));
|
|
29574
|
+
return {
|
|
29575
|
+
...input.args ? { args: input.args.map(leaf) } : {},
|
|
29576
|
+
...input.options ? { options: object3(input.options) } : {}
|
|
29577
|
+
};
|
|
29578
|
+
}
|
|
29579
|
+
function routeReasonLabel(reason2, collapsed) {
|
|
29580
|
+
return `${ROUTE_REASON_PREFIX} ${reason2}${collapsed ? ` (compound collapsed: ${collapsed.presets.join("+")})` : ""}`;
|
|
29581
|
+
}
|
|
29582
|
+
function routedPartLines(parts) {
|
|
29583
|
+
return parts.map((p) => {
|
|
29584
|
+
const line4 = p.text.replace(/\s+/g, " ").trim();
|
|
29585
|
+
return `${p.preset}: ${line4.length > ROUTE_PART_LINE_CAP ? `${line4.slice(0, ROUTE_PART_LINE_CAP - 1)}\u2026` : line4}`;
|
|
29586
|
+
});
|
|
29587
|
+
}
|
|
29588
|
+
function compoundBrief(text, parts) {
|
|
29589
|
+
return [
|
|
29590
|
+
text,
|
|
29591
|
+
"",
|
|
29592
|
+
`${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.`,
|
|
29593
|
+
...parts.map((p, i) => `${i + 1}. \`${p.preset}\`: ${p.text}`)
|
|
29594
|
+
].join("\n");
|
|
29595
|
+
}
|
|
29596
|
+
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;
|
|
29597
|
+
var init_route = __esm({
|
|
29598
|
+
"../../src/core/dispatch/route.ts"() {
|
|
29599
|
+
"use strict";
|
|
29600
|
+
init_registry();
|
|
29601
|
+
init_handBack();
|
|
29602
|
+
init_profile();
|
|
29603
|
+
init_redact();
|
|
29604
|
+
init_statusCardFrame();
|
|
29605
|
+
init_commandRegistry();
|
|
29606
|
+
init_commandSurface();
|
|
29607
|
+
init_budgets();
|
|
29608
|
+
init_confirmations();
|
|
29609
|
+
REASONING_COUNTING_CAP_FIELDS = /* @__PURE__ */ new Set(["max_tokens", "max_completion_tokens", "max_output_tokens"]);
|
|
29610
|
+
REASONING_OUTPUT_TOKEN_ALLOWANCE = 4096;
|
|
29611
|
+
OutputCapError = class extends Error {
|
|
29612
|
+
constructor(maxTokens) {
|
|
29613
|
+
super(`answer cut at the output cap (${maxTokens} tokens)`);
|
|
29614
|
+
this.maxTokens = maxTokens;
|
|
29615
|
+
this.name = "OutputCapError";
|
|
29616
|
+
}
|
|
29617
|
+
maxTokens;
|
|
29618
|
+
};
|
|
29619
|
+
ROUTE_REASON_CAP = 120;
|
|
29620
|
+
ROUTE_MIN_OUTPUT_TOKENS = 200;
|
|
29621
|
+
ROUTE_TIMEOUT_MS = 8e3;
|
|
29622
|
+
ROUTE_PART_LINE_CAP = 100;
|
|
29623
|
+
ROUTE_RECEIPT_CAP = 300;
|
|
29624
|
+
ROUTED_RECEIPT_PREFIX = "routed:";
|
|
29625
|
+
COMPOUND_BRIEF_HEADING = "Routed as a compound request";
|
|
29626
|
+
MultiToolCallError = class extends Error {
|
|
29627
|
+
constructor(calls) {
|
|
29628
|
+
super(`answer carried ${calls.length} tool calls; the route is one call`);
|
|
29629
|
+
this.calls = calls;
|
|
29630
|
+
this.name = "MultiToolCallError";
|
|
29631
|
+
}
|
|
29632
|
+
calls;
|
|
29633
|
+
};
|
|
29634
|
+
}
|
|
29635
|
+
});
|
|
29636
|
+
|
|
29137
29637
|
// ../../src/core/memory/reflection.ts
|
|
29138
29638
|
import { z as z15 } from "zod";
|
|
29139
29639
|
function shouldReflect(input) {
|
|
@@ -29288,13 +29788,14 @@ async function reflect(deps) {
|
|
|
29288
29788
|
const seen = /* @__PURE__ */ new Set();
|
|
29289
29789
|
const existing = [...await windowP, ...hits].filter((r) => !seen.has(r.id) && (seen.add(r.id), true));
|
|
29290
29790
|
const text = buildReflectionInput({ history: deps.history, request: deps.request, answer: deps.answer, existing });
|
|
29791
|
+
const maxTokens = outputCapWithReasoning(REFLECTION_MAX_TOKENS, { capField: deps.capField });
|
|
29291
29792
|
let result;
|
|
29292
29793
|
try {
|
|
29293
29794
|
result = await deps.provider.complete({
|
|
29294
29795
|
model: deps.model,
|
|
29295
29796
|
system: REFLECTION_SYSTEM,
|
|
29296
29797
|
messages: [{ role: "user", content: [{ type: "text", text }] }],
|
|
29297
|
-
maxTokens
|
|
29798
|
+
maxTokens,
|
|
29298
29799
|
...deps.effort !== void 0 ? { effort: deps.effort } : {},
|
|
29299
29800
|
...deps.effortWord !== void 0 ? { effortWord: deps.effortWord } : {}
|
|
29300
29801
|
});
|
|
@@ -29303,13 +29804,17 @@ async function reflect(deps) {
|
|
|
29303
29804
|
warn(`reflection skipped: ${renderProviderFailure(failure2.cause)}`);
|
|
29304
29805
|
return;
|
|
29305
29806
|
}
|
|
29807
|
+
const truncated = result.stopReason === "max_tokens" ? `truncated at ${maxTokens} max tokens` : void 0;
|
|
29808
|
+
if (truncated) {
|
|
29809
|
+
warn(`reflection output rejected (${truncated}); nothing written`);
|
|
29810
|
+
return;
|
|
29811
|
+
}
|
|
29306
29812
|
const reply = result.content.filter((p) => p.type === "text").map((p) => p.text).join("");
|
|
29307
29813
|
const prov = { sourceThreadKey: deps.sourceThreadKey, sourceRunId: deps.sourceRunId };
|
|
29308
29814
|
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}`);
|
|
29815
|
+
const stopNote = result.stopReason === "end_turn" ? void 0 : `stop: ${result.stopReason}`;
|
|
29311
29816
|
if (!parsed.ok) {
|
|
29312
|
-
const why =
|
|
29817
|
+
const why = stopNote ? `${parsed.error}; ${stopNote}` : parsed.error;
|
|
29313
29818
|
warn(`reflection output rejected (${why}); nothing written`);
|
|
29314
29819
|
return;
|
|
29315
29820
|
}
|
|
@@ -29380,6 +29885,7 @@ var init_reflection = __esm({
|
|
|
29380
29885
|
init_authz();
|
|
29381
29886
|
init_runEvents();
|
|
29382
29887
|
init_llmOutput();
|
|
29888
|
+
init_route();
|
|
29383
29889
|
init_engine();
|
|
29384
29890
|
init_scorer();
|
|
29385
29891
|
init_scope2();
|
|
@@ -29622,10 +30128,13 @@ function scheduleReflection(input) {
|
|
|
29622
30128
|
const info = (m) => console.log(`[memory] ${input.threadKey} ${m}`);
|
|
29623
30129
|
let provider;
|
|
29624
30130
|
let model;
|
|
30131
|
+
let capField;
|
|
29625
30132
|
try {
|
|
29626
|
-
const
|
|
30133
|
+
const modelRef3 = input.cfg.model ?? input.runModelRef;
|
|
30134
|
+
const ref = parseModelRef(modelRef3);
|
|
29627
30135
|
provider = input.providers.get(ref.provider);
|
|
29628
30136
|
model = ref.model;
|
|
30137
|
+
capField = resolveModelCard(modelRef3, input.providerBlocks ?? {}, installedModelRegistry).capField;
|
|
29629
30138
|
} catch (err2) {
|
|
29630
30139
|
warn(`reflection skipped: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
29631
30140
|
return;
|
|
@@ -29637,6 +30146,7 @@ function scheduleReflection(input) {
|
|
|
29637
30146
|
provider,
|
|
29638
30147
|
model,
|
|
29639
30148
|
...effort2.request ? { effort: effort2.request.effort, effortWord: effort2.request.effortWord } : {},
|
|
30149
|
+
...capField !== void 0 ? { capField } : {},
|
|
29640
30150
|
store: selectMemoryStore(input.cfg, input.store),
|
|
29641
30151
|
scopeKeys: requestScopeKeys(input.organization, input.userId, { channelId: input.channelId, repo: input.repo }),
|
|
29642
30152
|
actor: reflectionActor(input.actor, { channelId: input.channelId, repo: input.repo }),
|
|
@@ -29693,6 +30203,8 @@ var init_memory = __esm({
|
|
|
29693
30203
|
"use strict";
|
|
29694
30204
|
init_provider();
|
|
29695
30205
|
init_turnEffort();
|
|
30206
|
+
init_installedModelRegistry();
|
|
30207
|
+
init_modelCard();
|
|
29696
30208
|
init_scorer();
|
|
29697
30209
|
init_scope2();
|
|
29698
30210
|
init_stores();
|
|
@@ -31208,7 +31720,7 @@ ${line4}` : ""}`
|
|
|
31208
31720
|
});
|
|
31209
31721
|
|
|
31210
31722
|
// ../../src/core/reviewAbridge.ts
|
|
31211
|
-
import { resolve as
|
|
31723
|
+
import { resolve as resolve10 } from "node:path";
|
|
31212
31724
|
function meatArtifactOf(record2) {
|
|
31213
31725
|
return record2.events.find((e) => isReadingDiff(e) && e.poweredBy === "meat");
|
|
31214
31726
|
}
|
|
@@ -31253,7 +31765,7 @@ function reviewAbridgerFromConfig(config, store, secrets, env, dataDir, warn) {
|
|
|
31253
31765
|
github: () => github,
|
|
31254
31766
|
meat: meatOnHost({
|
|
31255
31767
|
apiKey: () => anthropicApiKey(config().providers, secrets),
|
|
31256
|
-
cacheDir:
|
|
31768
|
+
cacheDir: resolve10(dataDir, "meat-cache"),
|
|
31257
31769
|
hostEnv: { PATH: env.PATH, HOME: env.HOME }
|
|
31258
31770
|
}),
|
|
31259
31771
|
defaultModel: () => {
|
|
@@ -34611,7 +35123,7 @@ var init_githubRepoInspect = __esm({
|
|
|
34611
35123
|
});
|
|
34612
35124
|
|
|
34613
35125
|
// ../../src/core/commandCatalogue.ts
|
|
34614
|
-
import { existsSync as
|
|
35126
|
+
import { existsSync as existsSync13, readFileSync as readFileSync15 } from "node:fs";
|
|
34615
35127
|
import { readFile as readFile2 } from "node:fs/promises";
|
|
34616
35128
|
function unstampedStatus() {
|
|
34617
35129
|
let version2 = "unknown";
|
|
@@ -34636,10 +35148,10 @@ function defaultOperations(config, secrets, caller) {
|
|
|
34636
35148
|
return null;
|
|
34637
35149
|
}
|
|
34638
35150
|
function readSource(source2) {
|
|
34639
|
-
return Promise.resolve(
|
|
35151
|
+
return Promise.resolve(readFileSync15(source2 === "-" ? 0 : source2, "utf8"));
|
|
34640
35152
|
}
|
|
34641
35153
|
async function readOptionalFile(path) {
|
|
34642
|
-
return
|
|
35154
|
+
return existsSync13(path) ? readFile2(path, "utf8") : void 0;
|
|
34643
35155
|
}
|
|
34644
35156
|
function once(provided) {
|
|
34645
35157
|
if (typeof provided !== "function") {
|
|
@@ -35116,232 +35628,6 @@ var init_trace = __esm({
|
|
|
35116
35628
|
}
|
|
35117
35629
|
});
|
|
35118
35630
|
|
|
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
35631
|
// ../../src/core/markdownDocument.ts
|
|
35346
35632
|
function toMarkdownDocument(text) {
|
|
35347
35633
|
return text.replace(/[\uE000\uE001]/g, "").split(/(```[\s\S]*?```)/g).map((seg, i) => i % 2 === 1 ? seg : hardBreaks(convertProse(seg))).join("");
|
|
@@ -36463,30 +36749,62 @@ function checkPrHeadPreflight(input) {
|
|
|
36463
36749
|
async function guardAttachedHead(input) {
|
|
36464
36750
|
const expected = normalizeHead(input.expectedHeadSha);
|
|
36465
36751
|
if (!expected) return { outcome: "unverified" };
|
|
36466
|
-
const attached = normalizeHead(input.attached.sha);
|
|
36467
|
-
const source2 = input.attached.source ?? "workspace-observed";
|
|
36468
36752
|
const where = `${input.pr.repo}#${input.pr.number}`;
|
|
36469
|
-
const
|
|
36470
|
-
|
|
36471
|
-
|
|
36472
|
-
|
|
36753
|
+
const namedSource = (observed) => {
|
|
36754
|
+
const source3 = observed.source ?? "workspace-observed";
|
|
36755
|
+
const branch2 = observed.ref ?? input.fallbackRef;
|
|
36756
|
+
return source3 === "resident binding" ? branch2 ? `${source3} for ${branch2}` : source3 : branch2 ? `${source3} HEAD for ${branch2}` : `${source3} HEAD`;
|
|
36757
|
+
};
|
|
36758
|
+
const first = normalizeHead(input.attached.sha);
|
|
36759
|
+
if (first && sameCommit(expected, first)) return { outcome: "verified" };
|
|
36760
|
+
if (first) {
|
|
36761
|
+
const current = normalizeHead(await input.fetchPrHead(input.pr).catch(() => void 0));
|
|
36762
|
+
if (current && sameCommit(first, current)) {
|
|
36763
|
+
console.log(
|
|
36764
|
+
`[review] ${input.logKey} PR head moved since resolution: ${expected} \u2192 ${current}; the ${namedSource(input.attached)} is at the current head \u2014 reviewing it (${where})`
|
|
36765
|
+
);
|
|
36766
|
+
return { outcome: "adopted", headSha: current };
|
|
36767
|
+
}
|
|
36768
|
+
}
|
|
36769
|
+
let retried;
|
|
36770
|
+
let reprovisionFailed = false;
|
|
36771
|
+
try {
|
|
36772
|
+
retried = await input.reprovision(expected);
|
|
36773
|
+
} catch {
|
|
36774
|
+
reprovisionFailed = true;
|
|
36775
|
+
retried = { sha: void 0 };
|
|
36776
|
+
}
|
|
36777
|
+
const checked = normalizeHead(retried.sha);
|
|
36778
|
+
if (checked && sameCommit(expected, checked)) {
|
|
36779
|
+
console.log(`[review] ${input.logKey} workspace reprovisioned at reviewed head ${expected} (${where})`);
|
|
36780
|
+
return { outcome: "verified" };
|
|
36781
|
+
}
|
|
36782
|
+
const initial = first ? `the initial ${namedSource(input.attached)} was at ${first}` : `the initial ${namedSource(input.attached)} could not be read`;
|
|
36783
|
+
if (reprovisionFailed) {
|
|
36784
|
+
console.log(
|
|
36785
|
+
`[review] ${input.logKey} not started: ${initial}; reprovision failed before retry HEAD observation, expected reviewed head ${expected} (${where})`
|
|
36786
|
+
);
|
|
36473
36787
|
return {
|
|
36474
36788
|
outcome: "refused",
|
|
36475
|
-
reply: `\u{1F500} Review of ${where} not started: ${
|
|
36789
|
+
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
36790
|
};
|
|
36477
36791
|
}
|
|
36478
|
-
|
|
36479
|
-
|
|
36480
|
-
if (current && sameCommit(attached, current)) {
|
|
36792
|
+
const source2 = namedSource(retried);
|
|
36793
|
+
if (!checked) {
|
|
36481
36794
|
console.log(
|
|
36482
|
-
`[review] ${input.logKey}
|
|
36795
|
+
`[review] ${input.logKey} not started: ${initial}; ${source2} unreadable after reprovision, expected reviewed head ${expected} (${where})`
|
|
36483
36796
|
);
|
|
36484
|
-
return {
|
|
36797
|
+
return {
|
|
36798
|
+
outcome: "refused",
|
|
36799
|
+
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.`
|
|
36800
|
+
};
|
|
36485
36801
|
}
|
|
36486
|
-
console.log(
|
|
36802
|
+
console.log(
|
|
36803
|
+
`[review] ${input.logKey} not started: ${source2} ${checked} after reprovision, expected reviewed head ${expected} (${where})`
|
|
36804
|
+
);
|
|
36487
36805
|
return {
|
|
36488
36806
|
outcome: "refused",
|
|
36489
|
-
reply: `\u{1F500} Review of ${where} not started: the ${
|
|
36807
|
+
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
36808
|
};
|
|
36491
36809
|
}
|
|
36492
36810
|
function makeSystemComposer(input) {
|
|
@@ -36964,14 +37282,19 @@ async function authorizePrHead(ctx) {
|
|
|
36964
37282
|
}
|
|
36965
37283
|
return { kind: "allowed" };
|
|
36966
37284
|
}
|
|
37285
|
+
function reviewCheckoutFacts(repoCtx) {
|
|
37286
|
+
return {
|
|
37287
|
+
remote: `https://github.com/${repoCtx.repo}.git`,
|
|
37288
|
+
helper: `!f() { test -n "$GH_TOKEN" || exit 1; printf '%s\\n' 'username=x-access-token' "password=$GH_TOKEN"; }; f`,
|
|
37289
|
+
refspecs: [
|
|
37290
|
+
"+HEAD:refs/remotes/origin/HEAD",
|
|
37291
|
+
`+refs/pull/${repoCtx.pr}/head:refs/remotes/origin/pull/${repoCtx.pr}/head`,
|
|
37292
|
+
...repoCtx.baseRef ? [`+refs/heads/${repoCtx.baseRef}:refs/remotes/origin/${repoCtx.baseRef}`] : []
|
|
37293
|
+
]
|
|
37294
|
+
};
|
|
37295
|
+
}
|
|
36967
37296
|
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
|
-
];
|
|
37297
|
+
const { remote, helper, refspecs } = reviewCheckoutFacts(repoCtx);
|
|
36975
37298
|
return [
|
|
36976
37299
|
"set -eu",
|
|
36977
37300
|
"find . -mindepth 1 -maxdepth 1 ! -name attachments -exec rm -rf -- {} +",
|
|
@@ -36981,6 +37304,15 @@ function coldReviewCheckoutCommand(repoCtx) {
|
|
|
36981
37304
|
`git checkout --detach --force ${shellQuote(repoCtx.headSha)}`
|
|
36982
37305
|
].join("\n");
|
|
36983
37306
|
}
|
|
37307
|
+
function seededReviewCheckoutCommand(repoCtx, workspace) {
|
|
37308
|
+
const { helper, refspecs } = reviewCheckoutFacts(repoCtx);
|
|
37309
|
+
const git2 = `git -C ${shellQuote(workspace)}`;
|
|
37310
|
+
return [
|
|
37311
|
+
"set -eu",
|
|
37312
|
+
`${git2} -c credential.helper= -c credential.helper=${shellQuote(helper)} fetch --force --no-tags origin ${refspecs.map(shellQuote).join(" ")}`,
|
|
37313
|
+
`${git2} checkout --detach --force ${shellQuote(repoCtx.headSha)}`
|
|
37314
|
+
].join("\n");
|
|
37315
|
+
}
|
|
36984
37316
|
async function authorizeAttachedHead(deps, ctx) {
|
|
36985
37317
|
const { msg, refuse: refuse3, card, shell, closeLines, clock: clock4, agent, resume, selection, root } = ctx;
|
|
36986
37318
|
const { executor, resident, binding } = selection;
|
|
@@ -36991,7 +37323,6 @@ async function authorizeAttachedHead(deps, ctx) {
|
|
|
36991
37323
|
const pr = { repo: repoCtx.repo, number: repoCtx.pr };
|
|
36992
37324
|
const expectedHeadSha = repoCtx.headSha;
|
|
36993
37325
|
const guard = await root.span("dispatch.gate.attached_head", async (span) => {
|
|
36994
|
-
const source2 = resident && binding?.sha !== void 0 ? "resident binding" : "workspace-observed";
|
|
36995
37326
|
const command2 = selection.seeded?.workspace ? `git -C ${shellQuote(selection.seeded.workspace)} rev-parse HEAD` : "git rev-parse HEAD";
|
|
36996
37327
|
if (!resident && selection.seeded === void 0 && expectedHeadSha !== void 0) {
|
|
36997
37328
|
await executor.exec(
|
|
@@ -36999,13 +37330,48 @@ async function authorizeAttachedHead(deps, ctx) {
|
|
|
36999
37330
|
{ timeoutMs: BASH_TIMEOUT_MAX_MS }
|
|
37000
37331
|
);
|
|
37001
37332
|
}
|
|
37002
|
-
const
|
|
37333
|
+
const observeHead = () => executor.exec(command2, { timeoutMs: 3e4, span }).then(parseRevParseOutput).catch(() => void 0);
|
|
37334
|
+
const sha = await observeHead();
|
|
37003
37335
|
const g = await guardAttachedHead({
|
|
37004
37336
|
pr,
|
|
37005
37337
|
expectedHeadSha,
|
|
37006
|
-
attached: { sha, ref: binding?.ref ?? repoCtx.ref, source:
|
|
37338
|
+
attached: { sha, ref: binding?.ref ?? repoCtx.ref, source: "workspace-observed" },
|
|
37007
37339
|
fallbackRef: repoCtx.ref,
|
|
37008
37340
|
fetchPrHead: deps.fetchPrHead ?? currentPrHeadSha,
|
|
37341
|
+
reprovision: async (headSha) => {
|
|
37342
|
+
if (executor.moveTo) {
|
|
37343
|
+
await executor.moveTo(headSha, { span });
|
|
37344
|
+
const observedSha = await observeHead();
|
|
37345
|
+
if (selection.binding && observedSha !== void 0) {
|
|
37346
|
+
selection.binding = {
|
|
37347
|
+
...selection.binding,
|
|
37348
|
+
ref: repoCtx.ref ?? selection.binding.ref,
|
|
37349
|
+
sha: observedSha
|
|
37350
|
+
};
|
|
37351
|
+
}
|
|
37352
|
+
return {
|
|
37353
|
+
sha: observedSha,
|
|
37354
|
+
ref: repoCtx.ref,
|
|
37355
|
+
source: "workspace-observed"
|
|
37356
|
+
};
|
|
37357
|
+
}
|
|
37358
|
+
if (selection.seeded?.workspace) {
|
|
37359
|
+
await executor.exec(
|
|
37360
|
+
seededReviewCheckoutCommand(
|
|
37361
|
+
{ ...repoCtx, repo: pr.repo, pr: pr.number, headSha },
|
|
37362
|
+
selection.seeded.workspace
|
|
37363
|
+
),
|
|
37364
|
+
{ timeoutMs: BASH_TIMEOUT_MAX_MS, span }
|
|
37365
|
+
);
|
|
37366
|
+
} else {
|
|
37367
|
+
await executor.exec(coldReviewCheckoutCommand({ ...repoCtx, repo: pr.repo, pr: pr.number, headSha }), {
|
|
37368
|
+
timeoutMs: BASH_TIMEOUT_MAX_MS,
|
|
37369
|
+
span
|
|
37370
|
+
});
|
|
37371
|
+
}
|
|
37372
|
+
const retried = await observeHead();
|
|
37373
|
+
return { sha: retried, ref: repoCtx.ref, source: "workspace-observed" };
|
|
37374
|
+
},
|
|
37009
37375
|
logKey: msg.threadKey
|
|
37010
37376
|
});
|
|
37011
37377
|
span.setAttrs({ outcome: g.outcome });
|
|
@@ -37018,14 +37384,19 @@ async function authorizeAttachedHead(deps, ctx) {
|
|
|
37018
37384
|
verifiedAtAttach = true;
|
|
37019
37385
|
headAdopted = true;
|
|
37020
37386
|
} else if (guard.outcome === "refused") {
|
|
37021
|
-
await refuse3(refusalOf("
|
|
37387
|
+
await refuse3(refusalOf("workspace_head_mismatch", guard.reply), async () => {
|
|
37022
37388
|
if (executor.release) await executor.release("always").catch(() => {
|
|
37023
37389
|
});
|
|
37024
37390
|
await card.done(
|
|
37025
|
-
shell.close({
|
|
37391
|
+
shell.close({
|
|
37392
|
+
kind: "not_started",
|
|
37393
|
+
icon: "\u{1F500}",
|
|
37394
|
+
reason: "workspace head mismatch",
|
|
37395
|
+
...closeLines(clock4(), false)
|
|
37396
|
+
})
|
|
37026
37397
|
);
|
|
37027
37398
|
});
|
|
37028
|
-
return { kind: "refused", reason: "
|
|
37399
|
+
return { kind: "refused", reason: "workspace_head_mismatch" };
|
|
37029
37400
|
}
|
|
37030
37401
|
}
|
|
37031
37402
|
return { kind: "allowed", repoCtx, verifiedAtAttach, headAdopted };
|
|
@@ -37418,6 +37789,10 @@ var init_threadAdmission = __esm({
|
|
|
37418
37789
|
get size() {
|
|
37419
37790
|
return this.pending.length;
|
|
37420
37791
|
}
|
|
37792
|
+
/** The ledger seqs of the follow-ups still pending, oldest first. */
|
|
37793
|
+
get pendingSeqs() {
|
|
37794
|
+
return this.pending.flatMap((input) => input.ledgerSeq !== void 0 ? [input.ledgerSeq] : []);
|
|
37795
|
+
}
|
|
37421
37796
|
};
|
|
37422
37797
|
ThreadAdmission = class {
|
|
37423
37798
|
live = /* @__PURE__ */ new Map();
|
|
@@ -38085,279 +38460,6 @@ var init_commandChat = __esm({
|
|
|
38085
38460
|
}
|
|
38086
38461
|
});
|
|
38087
38462
|
|
|
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
38463
|
// ../../src/core/runRegistry/runControl.ts
|
|
38362
38464
|
var RunControl;
|
|
38363
38465
|
var init_runControl = __esm({
|
|
@@ -42112,7 +42214,7 @@ async function reserveRun(deps, ctx) {
|
|
|
42112
42214
|
async function attachRound(deps, ctx) {
|
|
42113
42215
|
const { threadKey, agent, profile, repoCtx, root, clock: clock4, reattach, stopSignal, remainingMs, requester } = ctx;
|
|
42114
42216
|
const { onSetupNote } = ctx;
|
|
42115
|
-
const ownPr = ownPrOf(repoCtx);
|
|
42217
|
+
const ownPr = agent.name === "review" ? void 0 : ownPrOf(repoCtx);
|
|
42116
42218
|
return root.span("dispatch.workspace.attach", async (span) => {
|
|
42117
42219
|
const graft = (steps, residentTotalMs) => graftResidentSteps(steps, {
|
|
42118
42220
|
parent: span,
|
|
@@ -45718,6 +45820,18 @@ function decisionRecordTaskKey(...parts) {
|
|
|
45718
45820
|
}
|
|
45719
45821
|
return hash.toString(16).padStart(16, "0");
|
|
45720
45822
|
}
|
|
45823
|
+
function durableDecisionRecordReservation(store) {
|
|
45824
|
+
return async (repo, taskKey, claimed2, existing) => {
|
|
45825
|
+
try {
|
|
45826
|
+
const reserved = await store.reserveDecisionRecord(repo, taskKey, claimed2, existing);
|
|
45827
|
+
if (!reserved.ok) throw new DecisionRecordReservationUnavailableError();
|
|
45828
|
+
return reserved.number;
|
|
45829
|
+
} catch (error) {
|
|
45830
|
+
if (error instanceof DecisionRecordReservationUnavailableError) throw error;
|
|
45831
|
+
throw new DecisionRecordReservationUnavailableError();
|
|
45832
|
+
}
|
|
45833
|
+
};
|
|
45834
|
+
}
|
|
45721
45835
|
var DECISION_RECORD_ENV, RECORD_MARKER, POSITIVE_RECORD_INSTRUCTION, NEGATED_INSTRUCTION, DECISION_RECORD_STORE_REFUSAL, DecisionRecordReservationUnavailableError, DecisionRecordAllocator;
|
|
45722
45836
|
var init_decisionRecordReservation = __esm({
|
|
45723
45837
|
"../../src/core/decisionRecordReservation.ts"() {
|
|
@@ -48614,6 +48728,11 @@ var init_mirror = __esm({
|
|
|
48614
48728
|
compactionRows = [];
|
|
48615
48729
|
/** The highest ledger inbox seq folded in so far (run-history item 40). */
|
|
48616
48730
|
inboxConsumedSeq = 0;
|
|
48731
|
+
/** The owed seqs the cursor has already passed, ascending; absent when none. */
|
|
48732
|
+
inboxDeferred() {
|
|
48733
|
+
const deferred = [...new Set(this.deps.owedInboxSeqs?.() ?? [])].filter((seq) => seq <= this.inboxConsumedSeq).sort((a, b) => a - b);
|
|
48734
|
+
return deferred.length > 0 ? { inboxDeferredSeqs: deferred } : {};
|
|
48735
|
+
}
|
|
48617
48736
|
/** Whether a report is owed: the mirror is wired and something happened. */
|
|
48618
48737
|
get wired() {
|
|
48619
48738
|
return this.deps.onStep !== void 0;
|
|
@@ -48702,7 +48821,8 @@ var init_mirror = __esm({
|
|
|
48702
48821
|
turn,
|
|
48703
48822
|
iteration: this.iteration++,
|
|
48704
48823
|
remainingMs: Math.max(0, this.deps.remainingMs()),
|
|
48705
|
-
inboxConsumedSeq: this.inboxConsumedSeq
|
|
48824
|
+
inboxConsumedSeq: this.inboxConsumedSeq,
|
|
48825
|
+
...this.inboxDeferred()
|
|
48706
48826
|
};
|
|
48707
48827
|
this.idx += turns.length;
|
|
48708
48828
|
this.lastAssistantIdx = this.idx - 1;
|
|
@@ -48729,7 +48849,8 @@ var init_mirror = __esm({
|
|
|
48729
48849
|
turn,
|
|
48730
48850
|
iteration: this.iteration,
|
|
48731
48851
|
remainingMs: Math.max(0, this.deps.remainingMs()),
|
|
48732
|
-
inboxConsumedSeq: this.inboxConsumedSeq
|
|
48852
|
+
inboxConsumedSeq: this.inboxConsumedSeq,
|
|
48853
|
+
...this.inboxDeferred()
|
|
48733
48854
|
};
|
|
48734
48855
|
this.idx += turns.length + 1;
|
|
48735
48856
|
this.rows.push(...turns);
|
|
@@ -49813,6 +49934,7 @@ async function runPiHarnessOpen(deps, run2) {
|
|
|
49813
49934
|
let paths;
|
|
49814
49935
|
let requeueUnechoed = () => {
|
|
49815
49936
|
};
|
|
49937
|
+
let unechoedSeqs = () => [];
|
|
49816
49938
|
let dropHeld = () => {
|
|
49817
49939
|
};
|
|
49818
49940
|
let loopEnded = false;
|
|
@@ -49847,7 +49969,10 @@ async function runPiHarnessOpen(deps, run2) {
|
|
|
49847
49969
|
onStep: run2.onStep,
|
|
49848
49970
|
seedLength: run2.resume ? run2.resume.messages.length + (run2.resume.compactions?.length ?? 0) : run2.messages.length,
|
|
49849
49971
|
remainingMs: () => deadline - now(),
|
|
49850
|
-
...tail ? { mirroredTail: tail } : {}
|
|
49972
|
+
...tail ? { mirroredTail: tail } : {},
|
|
49973
|
+
// The rows pi has not read yet: the cursor can pass one when a later row
|
|
49974
|
+
// is consumed first (the plane's provider-up beside an ordinary steer).
|
|
49975
|
+
owedInboxSeqs: () => [...run2.inbox?.pendingSeqs ?? [], ...unechoedSeqs()]
|
|
49851
49976
|
});
|
|
49852
49977
|
mirror.inboxConsumedSeq = run2.resume?.inboxConsumedSeq ?? 0;
|
|
49853
49978
|
placed = (event) => {
|
|
@@ -50254,6 +50379,7 @@ async function runPiHarnessOpen(deps, run2) {
|
|
|
50254
50379
|
const [echoed] = unechoed.splice(at, 1);
|
|
50255
50380
|
if (echoed.seq > mirror.inboxConsumedSeq) mirror.inboxConsumedSeq = echoed.seq;
|
|
50256
50381
|
};
|
|
50382
|
+
unechoedSeqs = () => unechoed.flatMap((u) => u.inputs.flatMap((i) => i.ledgerSeq !== void 0 ? [i.ledgerSeq] : []));
|
|
50257
50383
|
requeueUnechoed = () => {
|
|
50258
50384
|
pendingReissue = [];
|
|
50259
50385
|
run2.inbox?.requeue(unechoed.splice(0).flatMap((u) => u.inputs));
|
|
@@ -50935,7 +51061,14 @@ ${stagedLine}` : prompt;
|
|
|
50935
51061
|
if (obs.response.success === false) {
|
|
50936
51062
|
turnParkSettled = false;
|
|
50937
51063
|
note("harness_error", "the follow-up turn's model retry prompt was refused; the failure remains held");
|
|
50938
|
-
} else
|
|
51064
|
+
} else {
|
|
51065
|
+
drainTurnReissues();
|
|
51066
|
+
mirror.inboxConsumedSeq = Math.max(
|
|
51067
|
+
mirror.inboxConsumedSeq,
|
|
51068
|
+
...turnReissueRows.map((item) => item.ledgerSeq ?? 0)
|
|
51069
|
+
);
|
|
51070
|
+
clearTurnProviderHold();
|
|
51071
|
+
}
|
|
50939
51072
|
}
|
|
50940
51073
|
}
|
|
50941
51074
|
if (obs.response?.id === id && obs.response.success === false)
|
|
@@ -56806,6 +56939,7 @@ function createLedgerWriteThrough(opts) {
|
|
|
56806
56939
|
turnIndex: report2.firstIdx + turns.length,
|
|
56807
56940
|
inFlight: report2.inFlight,
|
|
56808
56941
|
inboxConsumedSeq: report2.inboxConsumedSeq,
|
|
56942
|
+
...report2.inboxDeferredSeqs?.length ? { inboxDeferredSeqs: report2.inboxDeferredSeqs } : {},
|
|
56809
56943
|
remainingMs: report2.remainingMs,
|
|
56810
56944
|
turn: report2.turn,
|
|
56811
56945
|
iteration: report2.iteration
|
|
@@ -63023,14 +63157,23 @@ var init_configBoot = __esm({
|
|
|
63023
63157
|
});
|
|
63024
63158
|
|
|
63025
63159
|
// ../../src/intakeModel.ts
|
|
63160
|
+
function intakeDecisionDeps(completion, deps) {
|
|
63161
|
+
return {
|
|
63162
|
+
model: completion.model,
|
|
63163
|
+
...completion.capField !== void 0 ? { capField: completion.capField } : {},
|
|
63164
|
+
...deps
|
|
63165
|
+
};
|
|
63166
|
+
}
|
|
63026
63167
|
function intakeCompletion(config, completions, log = console.log) {
|
|
63027
63168
|
const modelRef3 = intakeModelRef(config);
|
|
63028
63169
|
if (!modelRef3) return void 0;
|
|
63029
63170
|
const ref = parseModelRef(modelRef3);
|
|
63171
|
+
const card = resolveModelCard(modelRef3, config.providers, installedModelRegistry);
|
|
63030
63172
|
const effort2 = turnEffort(modelRef3, config.intake?.effort, config.providers);
|
|
63031
63173
|
if (effort2.note) log(`[intake] effort: ${effort2.note}`);
|
|
63032
63174
|
return {
|
|
63033
63175
|
modelRef: modelRef3,
|
|
63176
|
+
capField: card.capField,
|
|
63034
63177
|
model: providerStructuredModel(completions.get(ref.provider), ref.model, {
|
|
63035
63178
|
...effort2.request ? { effort: effort2.request } : {}
|
|
63036
63179
|
})
|
|
@@ -63042,6 +63185,8 @@ var init_intakeModel = __esm({
|
|
|
63042
63185
|
init_config2();
|
|
63043
63186
|
init_route();
|
|
63044
63187
|
init_turnEffort();
|
|
63188
|
+
init_installedModelRegistry();
|
|
63189
|
+
init_modelCard();
|
|
63045
63190
|
init_provider();
|
|
63046
63191
|
}
|
|
63047
63192
|
});
|
|
@@ -63164,7 +63309,10 @@ async function askModel(input, deps) {
|
|
|
63164
63309
|
floor: (violation) => ({ verdict: "silent", reason: violation, source: "error" })
|
|
63165
63310
|
},
|
|
63166
63311
|
deps.model,
|
|
63167
|
-
{
|
|
63312
|
+
{
|
|
63313
|
+
maxTokens: outputCapWithReasoning(ROUTE_MIN_OUTPUT_TOKENS, { capField: deps.capField }),
|
|
63314
|
+
signal: AbortSignal.timeout(deps.timeoutMs ?? ROUTE_TIMEOUT_MS)
|
|
63315
|
+
}
|
|
63168
63316
|
);
|
|
63169
63317
|
return { ...seam.value, attempts: seam.attempts };
|
|
63170
63318
|
} catch (err2) {
|
|
@@ -63173,8 +63321,18 @@ async function askModel(input, deps) {
|
|
|
63173
63321
|
if (timedOut) {
|
|
63174
63322
|
return {
|
|
63175
63323
|
verdict: "silent",
|
|
63176
|
-
reason:
|
|
63324
|
+
reason: renderProviderFailure("transient", "ended"),
|
|
63177
63325
|
source: "timeout",
|
|
63326
|
+
providerFailure: "transient",
|
|
63327
|
+
...attempts ? { attempts } : {}
|
|
63328
|
+
};
|
|
63329
|
+
}
|
|
63330
|
+
const outputCapError = err2 instanceof OutputCapError ? err2 : err2 instanceof StructuredAskError && err2.cause instanceof OutputCapError ? err2.cause : void 0;
|
|
63331
|
+
if (outputCapError) {
|
|
63332
|
+
return {
|
|
63333
|
+
verdict: "silent",
|
|
63334
|
+
reason: tidyReason(outputCapError.message),
|
|
63335
|
+
source: "error",
|
|
63178
63336
|
...attempts ? { attempts } : {}
|
|
63179
63337
|
};
|
|
63180
63338
|
}
|
|
@@ -71424,6 +71582,25 @@ async function childPullRequestState(deps, instance, unit) {
|
|
|
71424
71582
|
if (state === void 0) throw new Error(headBranchStateError(instance.repo, row2.pr.number));
|
|
71425
71583
|
return state;
|
|
71426
71584
|
}
|
|
71585
|
+
async function isEarlierAttemptRun(deps, current, view, unit) {
|
|
71586
|
+
if (current?.plan === void 0 || view.parentInstanceId === void 0 || unit === void 0) return false;
|
|
71587
|
+
if (unitOfIdempotencyKey(view.idempotencyKey ?? "") !== unit) return false;
|
|
71588
|
+
const prior = await deps.instances.get(view.parentInstanceId);
|
|
71589
|
+
if (prior?.plan === void 0) return false;
|
|
71590
|
+
const currentAttempt = current.attempt ?? 1;
|
|
71591
|
+
const priorAttempt = prior.attempt ?? 1;
|
|
71592
|
+
if (currentAttempt <= priorAttempt || current.plan.id !== prior.plan.id || current.plan.path !== prior.plan.path || current.repo !== prior.repo)
|
|
71593
|
+
return false;
|
|
71594
|
+
const [nextAttempt, currentUnits, priorUnits] = await Promise.all([
|
|
71595
|
+
deps.instances.get(planInstanceId(current.plan.id, currentAttempt + 1)),
|
|
71596
|
+
deps.instances.listUnits(current.id),
|
|
71597
|
+
deps.instances.listUnits(prior.id)
|
|
71598
|
+
]);
|
|
71599
|
+
if (nextAttempt !== null) return false;
|
|
71600
|
+
const currentUnit = currentUnits.find((row2) => row2.unit === unit);
|
|
71601
|
+
const priorUnit = priorUnits.find((row2) => row2.unit === unit);
|
|
71602
|
+
return currentUnit !== void 0 && priorUnit !== void 0 && currentUnit.branch === priorUnit.branch;
|
|
71603
|
+
}
|
|
71427
71604
|
async function readRecord(body, deps) {
|
|
71428
71605
|
const id = parseInstanceId(body.parentInstanceId);
|
|
71429
71606
|
if (!id.ok) return json3(400, { ok: false, error: id.error });
|
|
@@ -71432,10 +71609,11 @@ async function readRecord(body, deps) {
|
|
|
71432
71609
|
if (body.unit !== void 0 && (typeof body.unit !== "string" || !UNIT_ID.test(body.unit)))
|
|
71433
71610
|
return json3(400, { ok: false, error: "unit must be a unit id" });
|
|
71434
71611
|
const at = (deps.clock ?? systemClock)();
|
|
71435
|
-
const res = await deps.runs.getRun(body.runId);
|
|
71436
|
-
if (!res.ok
|
|
71612
|
+
const [res, instanceRow] = await Promise.all([deps.runs.getRun(body.runId), deps.instances.get(id.value)]);
|
|
71613
|
+
if (!res.ok) return json3(404, { ok: false, error: "not_found" });
|
|
71437
71614
|
const view = res.value;
|
|
71438
|
-
|
|
71615
|
+
if (view.parentInstanceId !== id.value && !await isEarlierAttemptRun(deps, instanceRow, view, typeof body.unit === "string" ? body.unit : void 0))
|
|
71616
|
+
return json3(404, { ok: false, error: "not_found" });
|
|
71439
71617
|
let pullRequest;
|
|
71440
71618
|
try {
|
|
71441
71619
|
pullRequest = await childPullRequestState(deps, instanceRow, typeof body.unit === "string" ? body.unit : void 0);
|
|
@@ -73824,11 +74002,7 @@ async function runBot() {
|
|
|
73824
74002
|
const coordinatorInstances = buildCoordinatorInstanceStore(runHistoryCfg, processSecrets);
|
|
73825
74003
|
const decisionRecordAllocator = new DecisionRecordAllocator(
|
|
73826
74004
|
fetchDecisionRecordClaims,
|
|
73827
|
-
|
|
73828
|
-
const reserved = await coordinatorInstances.reserveDecisionRecord(repo, taskKey, claimed2, existing);
|
|
73829
|
-
if (!reserved.ok) throw new DecisionRecordReservationUnavailableError();
|
|
73830
|
-
return reserved.number;
|
|
73831
|
-
}
|
|
74005
|
+
durableDecisionRecordReservation(coordinatorInstances)
|
|
73832
74006
|
);
|
|
73833
74007
|
let planeAdmitPass;
|
|
73834
74008
|
const planeEffectExecutor = {
|
|
@@ -74100,9 +74274,7 @@ async function runBot() {
|
|
|
74100
74274
|
slackIntake = wireIntakeGate({
|
|
74101
74275
|
intakeModeFor: (threadKey, userId, channelId) => config.intakeModeFor(threadKey, userId, channelId),
|
|
74102
74276
|
deps: {
|
|
74103
|
-
|
|
74104
|
-
ledger: intakeLedger,
|
|
74105
|
-
now: systemClock
|
|
74277
|
+
...intakeDecisionDeps(intake, { ledger: intakeLedger, now: systemClock })
|
|
74106
74278
|
},
|
|
74107
74279
|
modelRef: intake.modelRef,
|
|
74108
74280
|
gen: PROCESS_STARTED_AT,
|