@algosuite/vo-mcp 0.2.0-beta.36 → 0.2.0-beta.37

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.
@@ -2922,7 +2922,7 @@ function createControlPlaneClient({
2922
2922
  },
2923
2923
  /**
2924
2924
  * Read the operator's dispatch-mode config (Fast→Ultracode effort setting).
2925
- * Returns the mode string ('fast'|'standard'|'deep'|'ultra'|'ultracode'),
2925
+ * Returns the mode string ('fast'|'standard'|'deep'|'ultra'|'marathon'; 'ultracode' legacy),
2926
2926
  * defaulting to 'standard' on any error. Never throws — best-effort.
2927
2927
  */
2928
2928
  async getDispatchMode() {
@@ -3284,6 +3284,22 @@ function flushAgentStreamBuffer({
3284
3284
  if (trailing) deliverAgentEvent(parseEvent(trailing), { onProgress, onResult });
3285
3285
  return "";
3286
3286
  }
3287
+ function nextDeadlineDecision({
3288
+ nowMs,
3289
+ startMs,
3290
+ lastActivityMs,
3291
+ maxWallClockMs = 0,
3292
+ stallWindowMs = 6e5,
3293
+ legacy = false
3294
+ } = {}) {
3295
+ if (!(maxWallClockMs > 0)) return { action: "wait", delayMs: null };
3296
+ const elapsed = nowMs - startMs;
3297
+ if (elapsed < maxWallClockMs) return { action: "wait", delayMs: maxWallClockMs - elapsed };
3298
+ if (legacy) return { action: "kill", stalledForMs: null };
3299
+ const idle = nowMs - lastActivityMs;
3300
+ if (idle >= stallWindowMs) return { action: "kill", stalledForMs: idle };
3301
+ return { action: "wait", delayMs: stallWindowMs - idle };
3302
+ }
3287
3303
  function finalizeAgentTaskResult({
3288
3304
  result,
3289
3305
  bin,
@@ -3292,6 +3308,7 @@ function finalizeAgentTaskResult({
3292
3308
  killed,
3293
3309
  cancelReason,
3294
3310
  maxWallClockMs,
3311
+ stalledForMs = null,
3295
3312
  forcedAfterResult,
3296
3313
  code,
3297
3314
  signal,
@@ -3302,7 +3319,8 @@ function finalizeAgentTaskResult({
3302
3319
  ...result,
3303
3320
  ok: false,
3304
3321
  timedOut: true,
3305
- summary: `wall-clock timeout (${maxWallClockMs}ms)`
3322
+ stalledForMs,
3323
+ summary: stalledForMs != null ? `stalled: no stream activity for ${stalledForMs}ms after the wall-clock deadline (${maxWallClockMs}ms)` : `wall-clock timeout (${maxWallClockMs}ms)`
3306
3324
  };
3307
3325
  }
3308
3326
  if (killed) {
@@ -4123,6 +4141,8 @@ function runAgentTask({
4123
4141
  shouldCancel = async () => false,
4124
4142
  cancelPollMs = 5e3,
4125
4143
  maxWallClockMs = 0,
4144
+ stallWindowMs = Number(env2?.VO_CODE_RUNNER_STALL_WINDOW_MS) > 0 ? Number(env2.VO_CODE_RUNNER_STALL_WINDOW_MS) : 6e5,
4145
+ legacyWallClock = env2?.VO_CODE_RUNNER_LEGACY_WALLCLOCK === "1",
4126
4146
  postResultExitGraceMs = 1e4,
4127
4147
  exitDrainGraceMs = 300,
4128
4148
  armTerminalCleanup = armTerminalProcessCleanup,
@@ -4250,6 +4270,7 @@ function runAgentTask({
4250
4270
  killed,
4251
4271
  cancelReason,
4252
4272
  maxWallClockMs,
4273
+ stalledForMs,
4253
4274
  forcedAfterResult,
4254
4275
  code,
4255
4276
  signal,
@@ -4268,12 +4289,31 @@ function runAgentTask({
4268
4289
  }
4269
4290
  }, 5e3);
4270
4291
  };
4271
- const wallTimer = maxWallClockMs > 0 ? setTimeout(() => {
4272
- timedOut = true;
4273
- clearInterval(poll);
4274
- hardKill();
4275
- }, maxWallClockMs) : null;
4292
+ const deadlineStartMs = Date.now();
4293
+ let lastActivityMs = deadlineStartMs;
4294
+ let stalledForMs = null;
4295
+ let wallTimer = null;
4296
+ const armDeadline = () => {
4297
+ const decision = nextDeadlineDecision({
4298
+ nowMs: Date.now(),
4299
+ startMs: deadlineStartMs,
4300
+ lastActivityMs,
4301
+ maxWallClockMs,
4302
+ stallWindowMs,
4303
+ legacy: legacyWallClock
4304
+ });
4305
+ if (decision.action === "kill") {
4306
+ timedOut = true;
4307
+ stalledForMs = decision.stalledForMs;
4308
+ clearInterval(poll);
4309
+ hardKill();
4310
+ return;
4311
+ }
4312
+ if (decision.delayMs != null) wallTimer = setTimeout(armDeadline, decision.delayMs);
4313
+ };
4314
+ armDeadline();
4276
4315
  child.stdout.on("data", (chunk) => {
4316
+ lastActivityMs = Date.now();
4277
4317
  buffer = consumeAgentStreamChunk({
4278
4318
  chunk,
4279
4319
  buffer,
@@ -4283,6 +4323,7 @@ function runAgentTask({
4283
4323
  });
4284
4324
  });
4285
4325
  child.stderr.on("data", (c) => {
4326
+ lastActivityMs = Date.now();
4286
4327
  stderrTail = (stderrTail + c.toString()).slice(-4e3);
4287
4328
  });
4288
4329
  child.on("error", (err) => {
@@ -6007,6 +6048,7 @@ function isMaxTurnsResult(summary) {
6007
6048
  }
6008
6049
  function partialPrTitlePrefix(run = {}) {
6009
6050
  if (isMaxTurnsResult(run.summary)) return "\u26A0 PARTIAL (max turns reached)";
6051
+ if (run.timedOut && run.stalledForMs != null) return "\u26A0 PARTIAL (stalled \u2014 no progress after wall clock)";
6010
6052
  if (run.timedOut) return "\u26A0 PARTIAL (wall-clock timeout)";
6011
6053
  return "\u26A0 PARTIAL (needs continuation)";
6012
6054
  }
@@ -7119,6 +7161,98 @@ var init_dispatch_onboarding = __esm({
7119
7161
  }
7120
7162
  });
7121
7163
 
7164
+ // ../../scripts/virtual-office/code-runner/methodology-composer.mjs
7165
+ function classifyTaskShape(task) {
7166
+ const prompt = String(task?.prompt || "");
7167
+ for (const rule of SHAPE_RULES) {
7168
+ if (rule.matches(task, prompt)) return rule.shape;
7169
+ }
7170
+ return "feature";
7171
+ }
7172
+ function composeMethodologyBlock(task) {
7173
+ const shape = classifyTaskShape(task);
7174
+ const lines = [
7175
+ `## Methodology (auto-composed: ${shape})`,
7176
+ ...UNIVERSAL_DIRECTIVES.map((d) => `- ${d}`),
7177
+ ...(SHAPE_DIRECTIVES[shape] || []).map((d) => `- ${d}`)
7178
+ ];
7179
+ return { shape, block: lines.join("\n") };
7180
+ }
7181
+ function withMethodology(prompt, task) {
7182
+ const { shape, block } = composeMethodologyBlock(task);
7183
+ return { shape, prompt: `${prompt ?? ""}
7184
+
7185
+ ${block}` };
7186
+ }
7187
+ var SHAPE_RULES, UNIVERSAL_DIRECTIVES, SHAPE_DIRECTIVES;
7188
+ var init_methodology_composer = __esm({
7189
+ "../../scripts/virtual-office/code-runner/methodology-composer.mjs"() {
7190
+ "use strict";
7191
+ SHAPE_RULES = [
7192
+ {
7193
+ shape: "recovery",
7194
+ matches: (task, prompt) => Boolean(task?.resumed_from) || /VO_RECOVERY_FROM_CODE_TASK/u.test(prompt) || /previous run stopped before completion/iu.test(prompt)
7195
+ },
7196
+ {
7197
+ shape: "pr-repair",
7198
+ matches: (task) => typeof task?.repair_pr_number === "number"
7199
+ },
7200
+ {
7201
+ shape: "bug-fix",
7202
+ matches: (task, prompt) => Boolean(task?.bug_id) || /^reproduce and fix\b/iu.test(prompt) || /captured by: qa sweep/iu.test(prompt)
7203
+ },
7204
+ {
7205
+ shape: "roadmap-advance",
7206
+ matches: (task, prompt) => Boolean(task?.roadmap_app || task?.roadmap_item_id || typeof task?.roadmap_phase_index === "number") || /^roadmap:/iu.test(prompt)
7207
+ },
7208
+ {
7209
+ shape: "research",
7210
+ matches: (_task, prompt) => /\b(investigate|research|root[- ]cause|audit|diagnose|find out why|explain why)\b/iu.test(prompt)
7211
+ },
7212
+ {
7213
+ shape: "design",
7214
+ matches: (_task, prompt) => /\b(design doc|architecture|architect|adr\b|lane brief|write a plan|propose (a|the) (design|plan|approach))\b/iu.test(prompt)
7215
+ },
7216
+ {
7217
+ shape: "chore",
7218
+ matches: (_task, prompt) => prompt.length < 400 && /\b(typo|rename|bump|readme|changelog|comment|reword|lint fix|formatting)\b/iu.test(prompt)
7219
+ }
7220
+ ];
7221
+ UNIVERSAL_DIRECTIVES = [
7222
+ "Verification is a stage, not a vibe: before publishing, run the tests/build your change touches and cite their actual output. A claim without execution evidence is not done.",
7223
+ "Work to completion or end with an explicit failure reason. Do not stop because time has passed; stop when the evidence says the work is done \u2014 or state exactly what is blocking.",
7224
+ "Default to doing the work yourself in this session. Spawn parallel subagents ONLY for pieces that are genuinely independent and independently verifiable \u2014 and verify their results yourself before integrating; never let unreviewed parallel output merge into shared files."
7225
+ ];
7226
+ SHAPE_DIRECTIVES = {
7227
+ "bug-fix": [
7228
+ "Reproduce first: write the check that fails because of this bug, prove it fails, then fix, then prove the same check passes. A fix without a failing-then-passing check is not a fix."
7229
+ ],
7230
+ research: [
7231
+ "Every claim needs its source AND exact attribution \u2014 which file:line, which benchmark, which baseline, which version. Verify attribution, not just that a source exists; misattributed real facts are the dominant research failure mode.",
7232
+ "Deliver findings as a repo artifact (docs/) with the evidence inline, not only as chat output."
7233
+ ],
7234
+ "roadmap-advance": [
7235
+ "Update the roadmap doc status, regenerate the roadmap board if the doc changed, and add the roadmap-log fragment IN THIS SAME PR \u2014 a roadmap task that does not move the roadmap did not happen."
7236
+ ],
7237
+ design: [
7238
+ "Produce the plan artifact (docs/lanes/ or docs/adr/ with a Related section) BEFORE writing code. State the requirements you are designing to at the top; ambiguity resolved now is rework avoided later."
7239
+ ],
7240
+ recovery: [
7241
+ "Restore the preserved context first (draft PR, branch, checkpoint notes) and finish the ORIGINAL spec. Do not redo work that is already committed; verify what exists, then close the gap."
7242
+ ],
7243
+ "pr-repair": [
7244
+ "Work from the exact materialized PR source. Never force-push or rebase the existing branch; publish the replacement and let the host close the original."
7245
+ ],
7246
+ chore: [
7247
+ "Keep the diff minimal and mechanical. No fan-out, no speculative refactors; the verification stage is still required."
7248
+ ],
7249
+ feature: [
7250
+ "Ship the tests that prove the feature works in the same change, to the output-verified standard (assert the correct answer, not that something rendered)."
7251
+ ]
7252
+ };
7253
+ }
7254
+ });
7255
+
7122
7256
  // ../../scripts/virtual-office/code-runner/task-prompt.mjs
7123
7257
  function buildMissingKnowledgeMessage(taskId, reason) {
7124
7258
  const id = taskId || "unknown-task";
@@ -7162,11 +7296,16 @@ function withAttachmentManifest(prompt, markdown) {
7162
7296
 
7163
7297
  ${manifest}` : prompt;
7164
7298
  }
7299
+ function withComposedMethodology(prompt, task, log2, taskId) {
7300
+ const { shape, prompt: composed } = withMethodology(prompt, task);
7301
+ log2(`task ${taskId || "unknown-task"}: methodology shape=${shape}`);
7302
+ return composed;
7303
+ }
7165
7304
  async function composeCodeTaskPrompt(client, task, { log: log2 = () => {
7166
7305
  }, allowMissingKnowledgeContext = false, attachmentManifestMarkdown = "" } = {}) {
7167
7306
  const taskId = task?.code_task_id;
7168
7307
  if (!taskId) {
7169
- return composeDispatchPrompt(withAttachmentManifest(task?.prompt, attachmentManifestMarkdown), {
7308
+ return composeDispatchPrompt(withComposedMethodology(withAttachmentManifest(task?.prompt, attachmentManifestMarkdown), task, log2, taskId), {
7170
7309
  repo: task?.repo,
7171
7310
  knowledgeContextMarkdown: handleMissingKnowledgeContext(taskId, "missing code_task_id on the claimed task", {
7172
7311
  allowMissingKnowledgeContext,
@@ -7175,7 +7314,7 @@ async function composeCodeTaskPrompt(client, task, { log: log2 = () => {
7175
7314
  });
7176
7315
  }
7177
7316
  if (typeof client?.getTaskKnowledgeContext !== "function") {
7178
- return composeDispatchPrompt(withAttachmentManifest(task?.prompt, attachmentManifestMarkdown), {
7317
+ return composeDispatchPrompt(withComposedMethodology(withAttachmentManifest(task?.prompt, attachmentManifestMarkdown), task, log2, taskId), {
7179
7318
  repo: task?.repo,
7180
7319
  knowledgeContextMarkdown: handleMissingKnowledgeContext(taskId, "control-plane client cannot fetch knowledge context", {
7181
7320
  allowMissingKnowledgeContext,
@@ -7204,7 +7343,7 @@ async function composeCodeTaskPrompt(client, task, { log: log2 = () => {
7204
7343
  const prompt = operatorInstructions ? `${task?.prompt ?? ""}
7205
7344
 
7206
7345
  ${operatorInstructions}` : task?.prompt;
7207
- return composeDispatchPrompt(withAttachmentManifest(prompt, attachmentManifestMarkdown), {
7346
+ return composeDispatchPrompt(withComposedMethodology(withAttachmentManifest(prompt, attachmentManifestMarkdown), task, log2, taskId), {
7208
7347
  repo: task?.repo,
7209
7348
  knowledgeContextMarkdown
7210
7349
  });
@@ -7214,6 +7353,7 @@ var init_task_prompt = __esm({
7214
7353
  "../../scripts/virtual-office/code-runner/task-prompt.mjs"() {
7215
7354
  "use strict";
7216
7355
  init_dispatch_onboarding();
7356
+ init_methodology_composer();
7217
7357
  ALLOW_MISSING_KNOWLEDGE_CONTEXT_ENV = "VO_CODE_RUNNER_ALLOW_MISSING_KNOWLEDGE_CONTEXT";
7218
7358
  }
7219
7359
  });
@@ -9763,7 +9903,8 @@ var init_control_server = __esm({
9763
9903
  // ../../scripts/virtual-office/code-runner/effort-mode-config.mjs
9764
9904
  function resolveEffortMode(mode) {
9765
9905
  const normalized = String(mode || "").trim().toLowerCase();
9766
- return EFFORT_MODE_CONFIG[normalized] || EFFORT_MODE_CONFIG[DEFAULT_MODE];
9906
+ const canonical = LEGACY_MODE_ALIASES[normalized] || normalized;
9907
+ return EFFORT_MODE_CONFIG[canonical] || EFFORT_MODE_CONFIG[DEFAULT_MODE];
9767
9908
  }
9768
9909
  function resolveDefaultBudgetUsd(env2 = {}) {
9769
9910
  const raw = env2?.[DEFAULT_BUDGET_USD_ENV];
@@ -9793,7 +9934,7 @@ ${effortConfig.multiAgentInstruction}
9793
9934
  parts.push(String(basePrompt || "").trim());
9794
9935
  return parts.join("\n");
9795
9936
  }
9796
- var RED_TEAM_DIRECTIVE, DEFAULT_BUDGET_USD_ENV, EFFORT_MODE_CONFIG, DEFAULT_MODE;
9937
+ var RED_TEAM_DIRECTIVE, DEFAULT_BUDGET_USD_ENV, EFFORT_MODE_CONFIG, DEFAULT_MODE, LEGACY_MODE_ALIASES;
9797
9938
  var init_effort_mode_config = __esm({
9798
9939
  "../../scripts/virtual-office/code-runner/effort-mode-config.mjs"() {
9799
9940
  "use strict";
@@ -9832,7 +9973,7 @@ var init_effort_mode_config = __esm({
9832
9973
  thinkingDirective: `Think step-by-step. Exhaustively verify every assumption against source code and documentation. ${RED_TEAM_DIRECTIVE}`,
9833
9974
  multiAgentInstruction: "If this task needs multiple phases (research, build, verify), propose a plan first."
9834
9975
  },
9835
- ultracode: {
9976
+ marathon: {
9836
9977
  tier: "best",
9837
9978
  maxBudgetUsd: null,
9838
9979
  permissionMode: "acceptEdits",
@@ -9842,6 +9983,7 @@ var init_effort_mode_config = __esm({
9842
9983
  }
9843
9984
  };
9844
9985
  DEFAULT_MODE = "standard";
9986
+ LEGACY_MODE_ALIASES = { ultracode: "marathon" };
9845
9987
  }
9846
9988
  });
9847
9989