@algosuite/vo-mcp 0.2.0-beta.57 → 0.2.0-beta.58

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.
@@ -7649,8 +7649,17 @@ function messageExcerpt(output) {
7649
7649
  const s = String(output ?? "");
7650
7650
  return s.length > 1200 ? `...${s.slice(-1200)}` : s;
7651
7651
  }
7652
- async function enforceCompletionGateOrFail({ client, id, task, worktreeDir, log: log2 = () => {
7653
- }, execFileImpl = execFile } = {}) {
7652
+ async function enforceCompletionGateOrFail({
7653
+ client,
7654
+ id,
7655
+ task,
7656
+ worktreeDir,
7657
+ run = null,
7658
+ truncated = false,
7659
+ log: log2 = () => {
7660
+ },
7661
+ execFileImpl = execFile
7662
+ } = {}) {
7654
7663
  const resolved = resolveCompletionGate(task);
7655
7664
  if (resolved === null) return false;
7656
7665
  if (resolved.invalid) {
@@ -7674,6 +7683,12 @@ ${messageExcerpt(cached2.output)}`, "completion_gate_failed");
7674
7683
  return false;
7675
7684
  }
7676
7685
  const kind = outcome.timedOut ? `timed out after ${COMPLETION_GATE_TIMEOUT_MS}ms` : `exited ${outcome.exitCode}`;
7686
+ if (truncated) {
7687
+ log2(`task ${id}: completion gate FAILED (${kind}) after a budget/turn-truncated run \u2014 salvaging as PARTIAL draft, not terminal-failing`);
7688
+ if (run) run.gateFailureNote = `completion gate '${task.completion_gate}' ${kind} (gate ran against a budget/turn-truncated run):
7689
+ ${messageExcerpt(outcome.output)}`;
7690
+ return false;
7691
+ }
7677
7692
  log2(`task ${id}: completion gate FAILED (${kind}) \u2014 not publishing`);
7678
7693
  await postFailed2(client, id, `completion gate '${task.completion_gate}' ${kind} \u2014 task may not claim completion:
7679
7694
  ${messageExcerpt(outcome.output)}`, "completion_gate_failed");
@@ -11142,8 +11157,8 @@ var init_pr_watcher_github = __esm({
11142
11157
  "../../scripts/virtual-office/code-runner/pr-watcher-github.mjs"() {
11143
11158
  "use strict";
11144
11159
  init_process_runner2();
11145
- VIEW_FIELDS_WITH_CI = "state,statusCheckRollup,headRefName,headRefOid,url,isDraft,mergeStateStatus";
11146
- VIEW_FIELDS_WITHOUT_CI = "state,headRefName,headRefOid,url,isDraft,mergeStateStatus";
11160
+ VIEW_FIELDS_WITH_CI = "state,statusCheckRollup,headRefName,headRefOid,url,isDraft,mergeStateStatus,body";
11161
+ VIEW_FIELDS_WITHOUT_CI = "state,headRefName,headRefOid,url,isDraft,mergeStateStatus,body";
11147
11162
  CI_UNREADABLE_REASON = "app_token_missing_checks_read";
11148
11163
  DIAGNOSTIC_INTERVAL_MS = 30 * 60 * 1e3;
11149
11164
  lastDiagnosticAt = 0;
@@ -11885,7 +11900,7 @@ function startControlServer({ port, getStatus, requestStop, allowedOrigin, log:
11885
11900
  server.unref?.();
11886
11901
  return server;
11887
11902
  }
11888
- function startDaemonControl({ cfg, runnerInstanceId, requestStop, getActiveCount, isRunning, startedAt, log: log2 = () => {
11903
+ function startDaemonControl({ cfg, runnerInstanceId, requestStop, getActiveCount, getActiveTaskIds = () => [], isRunning, startedAt, log: log2 = () => {
11889
11904
  }, onDuplicate = null, getUpdateStatus = () => null, getClaimGate = () => null }) {
11890
11905
  if (!cfg.controlEnabled) return null;
11891
11906
  return startControlServer({
@@ -11902,6 +11917,9 @@ function startDaemonControl({ cfg, runnerInstanceId, requestStop, getActiveCount
11902
11917
  servedOperators: cfg.servedOperators,
11903
11918
  watchEnabled: cfg.watchEnabled,
11904
11919
  activeTasks: getActiveCount(),
11920
+ // The supervisor's update-drain gate reads THESE ids (not a guess) to mark
11921
+ // in-flight work before a capped staged-update restart kills it.
11922
+ activeTaskIds: getActiveTaskIds(),
11905
11923
  startedAt: new Date(startedAt).toISOString(),
11906
11924
  uptimeSec: Math.round((Date.now() - startedAt) / 1e3),
11907
11925
  // Host version awareness — the app + `runner --status` read drift from here.
@@ -13373,6 +13391,17 @@ var init_redact_tokens = __esm({
13373
13391
  }
13374
13392
  });
13375
13393
 
13394
+ // ../../scripts/ci/check-consensus-receipt-core.mjs
13395
+ var RECEIPT_MARKER_RE, UNAVAILABILITY_RE;
13396
+ var init_check_consensus_receipt_core = __esm({
13397
+ "../../scripts/ci/check-consensus-receipt-core.mjs"() {
13398
+ "use strict";
13399
+ init_methodology_composer();
13400
+ RECEIPT_MARKER_RE = /receipt id:\s*[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/iu;
13401
+ UNAVAILABILITY_RE = /consensus[^.\n]{0,80}(not available|unavailable|not permitted|could not be reached|no receipt_id)/iu;
13402
+ }
13403
+ });
13404
+
13376
13405
  // ../../scripts/virtual-office/code-runner/task-helpers.mjs
13377
13406
  function makeSafeProgress(log2) {
13378
13407
  return async (client, id, patch) => {
@@ -13397,6 +13426,17 @@ ${String(run?.lastAgentMessage || "")}`;
13397
13426
  const missing = found.filter((line) => !String(slicedBodyText || "").includes(line));
13398
13427
  return missing.length ? ["", "### Consensus evidence (preserved past truncation)", "", ...missing.map((line) => redactSecrets(line))] : [];
13399
13428
  }
13429
+ function consensusUnavailabilityLine(stakes) {
13430
+ const signal = String(stakes ?? "").replace(/\s+/gu, " ").trim().slice(0, 80) || "unspecified";
13431
+ return `Consensus judgment was not available in this headless session (no receipt_id) \u2014 automated declaration by the runner; stakes signal: ${signal}.`;
13432
+ }
13433
+ function withConsensusDeclaration(body, stakes) {
13434
+ const text = String(body ?? "");
13435
+ if (RECEIPT_MARKER_RE.test(text) || UNAVAILABILITY_RE.test(text)) return text;
13436
+ return `${text}
13437
+
13438
+ ${consensusUnavailabilityLine(stakes)}`;
13439
+ }
13400
13440
  function buildPrBody(task, run, files, { armAutoMerge = false } = {}) {
13401
13441
  const governedStakes = matchGovernedStakes({ prompt: String(task.prompt || "") });
13402
13442
  const slicedSections = [
@@ -13422,15 +13462,20 @@ function buildPrBody(task, run, files, { armAutoMerge = false } = {}) {
13422
13462
  "",
13423
13463
  // A budget/turn-capped run ends with no assistant text (summary = the bare
13424
13464
  // subtype); its LAST message is the honest report the operator needs.
13425
- ...run.lastAgentMessage ? ["### Last agent message before the cap", "", redactSecrets(String(run.lastAgentMessage)).slice(0, 2e3), ""] : []
13465
+ ...run.lastAgentMessage ? ["### Last agent message before the cap", "", redactSecrets(String(run.lastAgentMessage)).slice(0, 2e3), ""] : [],
13466
+ // Completion-gate failures salvaged against a budget/turn-truncated run
13467
+ // (D4, incident afc90342) — the gate output that would otherwise have
13468
+ // only lived in a terminal-failure message the runner never publishes.
13469
+ ...run.gateFailureNote ? ["### Completion gate output (not yet passing)", "", redactSecrets(String(run.gateFailureNote)).slice(0, 2e3), ""] : []
13426
13470
  ];
13427
- return [
13471
+ const composed = [
13428
13472
  ...slicedSections,
13429
13473
  // Receipt lines the slices dropped — the gate reads only this body.
13430
13474
  ...preservedReceiptLines(run, slicedSections.join("\n")),
13431
13475
  "---",
13432
13476
  armAutoMerge ? "_Opened by the AlgoHQ code-runner daemon. After CI passes, the watcher must obtain a durable consensus receipt and merge the exact verified SHA._" : "_Opened by the AlgoHQ code-runner daemon. This PR awaits the verify-before-act gate / operator review \u2014 it is NOT auto-merged._"
13433
13477
  ].filter((l) => l !== "").join("\n");
13478
+ return governedStakes ? withConsensusDeclaration(composed, governedStakes) : composed;
13434
13479
  }
13435
13480
  async function mintRunnerGithubTokens({ client, taskId, log: log2, repo = null, requirePublish = false }) {
13436
13481
  const publishToken = (await client.getInstallationToken({ required: requirePublish }))?.token ?? null;
@@ -13451,6 +13496,7 @@ var init_task_helpers = __esm({
13451
13496
  "use strict";
13452
13497
  init_redact_tokens();
13453
13498
  init_methodology_composer();
13499
+ init_check_consensus_receipt_core();
13454
13500
  RECEIPT_LINE_RE = /receipt id:\s*[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/giu;
13455
13501
  }
13456
13502
  });
@@ -15803,7 +15849,7 @@ async function processOneTask(client, task, cfg, runnerInstanceId, swarmAdmissio
15803
15849
  }
15804
15850
  if (await taskWasCancelled({ client, id, run, safeProgress, log })) return;
15805
15851
  if (await gateTestGenTaskOrFail({ client, id, task, files, worktreeDir: wt.worktreeDir, log })) return;
15806
- if (await enforceCompletionGateOrFail({ client, id, task, worktreeDir: wt.worktreeDir, log })) return;
15852
+ if (await enforceCompletionGateOrFail({ client, id, task, worktreeDir: wt.worktreeDir, run, truncated: partial, log })) return;
15807
15853
  const publicationTarget = await resolvePublicationTarget({ task, continuationRestore, worktreeDir: wt.worktreeDir, githubToken, allowAmbientGithubFallback: cfg.allowAmbientGithub });
15808
15854
  const localBranch = await resolveOrCreateBranchAsync(wt.worktreeDir, "vo/code-task");
15809
15855
  const publicationBranch = publicationTarget.targetBranch || localBranch;
@@ -15896,6 +15942,7 @@ async function main({ env: env2 = process.env, once: once2 = false } = {}) {
15896
15942
  let reconcileStale = true;
15897
15943
  let stopping = false;
15898
15944
  let active = 0;
15945
+ const activeTaskIds = /* @__PURE__ */ new Set();
15899
15946
  const stop = (sig) => {
15900
15947
  if (stopping) return;
15901
15948
  stopping = true;
@@ -15910,6 +15957,7 @@ async function main({ env: env2 = process.env, once: once2 = false } = {}) {
15910
15957
  runnerInstanceId,
15911
15958
  requestStop: () => stop("web-control"),
15912
15959
  getActiveCount: () => active,
15960
+ getActiveTaskIds: () => [...activeTaskIds],
15913
15961
  isRunning: () => !stopping,
15914
15962
  startedAt,
15915
15963
  log,
@@ -16000,6 +16048,7 @@ async function main({ env: env2 = process.env, once: once2 = false } = {}) {
16000
16048
  }
16001
16049
  log(`claimed task ${task.code_task_id} (${task.repo})`);
16002
16050
  active += 1;
16051
+ activeTaskIds.add(task.code_task_id);
16003
16052
  const runTask = task.kind === "inference" ? processInferenceTask(client, task, cfg, { safeProgress, runnerStagePatch, log }) : processOneTask(client, task, cfg, runnerInstanceId, { availableAgents: claimAgents.availableAgents, accountUsage: accountUsage.get() });
16004
16053
  const done = runTask.catch(async (error) => {
16005
16054
  log(`task ${task.code_task_id} unhandled runner error: ${error.message}`);
@@ -16019,6 +16068,7 @@ async function main({ env: env2 = process.env, once: once2 = false } = {}) {
16019
16068
  });
16020
16069
  }).finally(() => {
16021
16070
  active -= 1;
16071
+ activeTaskIds.delete(task.code_task_id);
16022
16072
  });
16023
16073
  if (once2) {
16024
16074
  await done;