@kernlang/agon 0.1.1 → 0.1.3

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.
@@ -10,6 +10,7 @@ import {
10
10
  appendUserTurnIfAbsent,
11
11
  applyPatch,
12
12
  assignForgeRoles,
13
+ buildCodebaseMap,
13
14
  buildCritiquePrompt,
14
15
  buildForgePrompt,
15
16
  buildHistoryPrimedPrompt,
@@ -26,6 +27,7 @@ import {
26
27
  createBashTool,
27
28
  createBrainstormTool,
28
29
  createCampfireTool,
30
+ createConquerTool,
29
31
  createDelegateTool,
30
32
  createEditTool,
31
33
  createExitPlanModeTool,
@@ -98,7 +100,7 @@ import {
98
100
  worktreeCreate,
99
101
  worktreeDiff,
100
102
  worktreeRemoveBestEffort
101
- } from "./chunk-7PMMOQZ7.js";
103
+ } from "./chunk-PFHGKBQT.js";
102
104
 
103
105
  // ../forge/src/generated/forge.ts
104
106
  import { randomUUID as randomUUID2 } from "crypto";
@@ -6729,6 +6731,7 @@ function createCesarToolRegistry(engineId) {
6729
6731
  toolRegistry.register(createCampfireTool());
6730
6732
  toolRegistry.register(createPipelineTool());
6731
6733
  toolRegistry.register(createGoalTool());
6734
+ toolRegistry.register(createConquerTool());
6732
6735
  toolRegistry.register(createReviewTool());
6733
6736
  toolRegistry.register(createDelegateTool());
6734
6737
  toolRegistry.register(createAgentTool());
@@ -8434,6 +8437,13 @@ function detectNarratedToolStall(text) {
8434
8437
  const STALL_RE = /\b(?:let me (?:check|look|examine|read|search|find|see|review|explore|investigate|understand|get|grab|continue)|i (?:need|want|should|will) (?:to )?(?:check|look|examine|read|search|find|see|review|explore|investigate|understand|get|grab|continue)|now (?:let me|i'll)|continu(?:e|ing)|keep (?:reading|investigating|looking)|next[,.]?\s*(?:i|let)|before (?:i can|proceeding|implementing|deciding))\b/i;
8435
8438
  return FAKE_GATE_RE.test(tail) || READ_INTENT_RE.test(tail) || SEARCH_INTENT_RE.test(tail) || DIR_INTENT_RE.test(tail) || STALL_RE.test(tail);
8436
8439
  }
8440
+ function detectMutationIntentStall(text) {
8441
+ const body = String(text ?? "").trim();
8442
+ if (!body) return false;
8443
+ const MUTATION_INTENT_RE = /\b(?:edit|write|apply|patch|implement|insert|replace|land it|commit it|the (?:change|fix|diff|patch|edit)|make the (?:edit|change)s?|ready to (?:paste|apply))\b/i;
8444
+ const HANDBACK_RE = /\b(?:read-?only|can'?t (?:write|edit|apply|mutate|touch)|no (?:write|edit|bash) tool|(?:edit|write|bash)(?: tool)?(?: is)? (?:not enabled|disabled|not wired|not available|unavailable)|not (?:enabled|wired|reachable) in this (?:context|session|turn)|spawn (?:an? )?agent|dispatch (?:an? )?agent|paste (?:it|this|the\b)|apply (?:it|this)\b|git apply|you (?:can )?(?:run|apply|paste)|in your terminal|hand you the (?:patch|diff|commands?)|copy[- ]?paste)\b/i;
8445
+ return MUTATION_INTENT_RE.test(body) && HANDBACK_RE.test(body);
8446
+ }
8437
8447
  function eagerFailedToolNames(results) {
8438
8448
  const names = [];
8439
8449
  for (const result of results ?? []) {
@@ -8504,6 +8514,7 @@ function extractDelegation(toolName, args) {
8504
8514
  maxTurns: typeof argsRecord.maxTurns === "number" ? argsRecord.maxTurns : void 0,
8505
8515
  queue: typeof argsRecord.queue === "string" ? argsRecord.queue : void 0,
8506
8516
  gate: typeof argsRecord.gate === "string" ? argsRecord.gate : void 0,
8517
+ builder: typeof argsRecord.builder === "string" ? argsRecord.builder : void 0,
8507
8518
  push: argsRecord.push ?? void 0,
8508
8519
  pr: argsRecord.pr ?? void 0,
8509
8520
  maxHours: typeof argsRecord.maxHours === "number" ? argsRecord.maxHours : void 0,
@@ -9057,6 +9068,7 @@ RULE 6 \u2014 AFTER DELEGATION: After calling Forge/Brainstorm/Tribunal/Campfire
9057
9068
  RULE 7 \u2014 NO NARRATION: NEVER narrate your research process. Do not write "Reading the file...", "I'm checking...", "Let me look at...", "I've confirmed...". The user sees your text output \u2014 if you narrate exploration it looks like you have no clue. Instead: call tools SILENTLY, then speak ONLY when you have the answer or decision. Your visible output should be conclusions, answers, and actions \u2014 never a play-by-play of your investigation. If you need to read files or search code, call Read/Grep/Glob directly without announcing it.
9058
9069
 
9059
9070
  RULE 8 \u2014 AUTONOMOUS PLANS: Plan mode is optional, not the default. Stay live unless staged execution is genuinely useful. Switch to planning when the task needs multiple dependent steps, expensive orchestration, resumability, explicit approval, or cost visibility. When you call ProposePlan, decide whether to set autoApprove=true. Set it ONLY when (a) the user clearly described a multi-stage workflow ("plan it, build it, review it"; "investigate then forge it"; "do the whole thing autonomously") AND (b) you have HIGH confidence in the steps after investigation (not before). The runtime applies a layered policy and may still ask the user \u2014 your autoApprove=true is permission, not a guarantee. Default to autoApprove=false (or omit it) whenever you are uncertain or when the plan touches mutating steps and the user did not explicitly invite autonomous execution. selfReview defaults to true for mutating plans \u2014 only set selfReview=false for purely advisory plans (brainstorm/tribunal/research only) where a code-review gate would have nothing to review.
9071
+ RULE 8b \u2014 AUTONOMOUS BUILD TOOLS (Goal / Conquer): These run a build to completion in the BACKGROUND. Goal(intent, queue?, gate?) drives a finite, machine-verifiable task QUEUE (forge \u2192 witness \u2192 review \u2192 commit per task on a goal/* branch). Conquer(task, gate, builder?, engines?) is for an OPEN-ENDED build you'd otherwise babysit: it drives an external builder CLI as the user (builder defaults to codex \u2014 pass builder:"codex" / "claude" / "agy") unattended until the gate passes, convening nero/tribunal/council on forks, then STOPS at a human merge gate (NEVER auto-merges). Fire EITHER ONLY when the user explicitly asks to build it unattended ("conquer this with codex", "build it autonomously") \u2014 NEVER on a vague request; both are long, real-spend, multi-hour runs. Conquer REQUIRES a discriminating gate (the done-spec, e.g. gate:"pnpm test"); if the user did not give one, ASK for the command that proves the build is done before calling. After calling either, STOP and wait \u2014 the background job and the merge gate handle the rest.
9060
9072
 
9061
9073
  RULE 10 \u2014 TURN CLOSURE: End every turn with one clear closing line so the user can tell AT A GLANCE which of three states you are in: done, waiting on them for a decision/info, or handed off. This is non-negotiable: NEVER end a turn with only a recap, a silent stop, or a trailing thought \u2014 that leaves the user wondering "is it my turn? do I have to do something?", which must never happen. Four valid shapes \u2014 pick exactly one:
9062
9074
  a) DONE \u2014 past-tense, concrete, names the file/result. Example: "Fixed: brain.kern lines 787-799, drain timers added before early return, typecheck green." No trailing menu, no "standing by".
@@ -9089,6 +9101,12 @@ function buildCesarSystemPrompt(ctx) {
9089
9101
  const systemParts = [CESAR_SYSTEM_PROMPT];
9090
9102
  if (projectCtx) systemParts.push(`## PROJECT CONTEXT
9091
9103
  ${projectCtx}`);
9104
+ try {
9105
+ const codebaseBrief = buildCodebaseMap(cesarCwd);
9106
+ if (codebaseBrief) systemParts.push(codebaseBrief);
9107
+ } catch (err) {
9108
+ console.warn(`[agon] codebase atlas skipped: ${err instanceof Error ? err.message : String(err)}`);
9109
+ }
9092
9110
  systemParts.push(`## AVAILABLE ENGINES
9093
9111
  ${engineList}`);
9094
9112
  if (ctx.explorationMode) {
@@ -9228,6 +9246,7 @@ ${context}`);
9228
9246
  }
9229
9247
  var CESAR_SNAPSHOT_MSG_CHAR_CAP = 4e3;
9230
9248
  var CONFIDENCE_BLOCK_LIMIT = 2;
9249
+ var SEARCH_NUDGE_THRESHOLD = 40;
9231
9250
  function capSnapshotMessageContent(content) {
9232
9251
  if (content.length <= CESAR_SNAPSHOT_MSG_CHAR_CAP) return content;
9233
9252
  return `${content.slice(0, CESAR_SNAPSHOT_MSG_CHAR_CAP)}
@@ -9272,6 +9291,7 @@ function buildOnToolCall(ctx, toolRegistry, config) {
9272
9291
  const toolResultCache = /* @__PURE__ */ new Map();
9273
9292
  const nativeToolErrorRetries = /* @__PURE__ */ new Map();
9274
9293
  const CACHEABLE_TOOLS = /* @__PURE__ */ new Set(["Grep", "Glob"]);
9294
+ const SEARCH_NUDGE_TOOLS = /* @__PURE__ */ new Set(["Read", "Grep", "Glob"]);
9275
9295
  const explorationMode = ctx.explorationMode ?? false;
9276
9296
  const sharedToolCtx = {
9277
9297
  cwd,
@@ -9354,7 +9374,7 @@ ${cleaned}`;
9354
9374
  }
9355
9375
  }
9356
9376
  if (name === "ExitPlanMode") {
9357
- const { handleExitPlanMode } = await import("./plan-mode-KBJY2FJN.js");
9377
+ const { handleExitPlanMode } = await import("./plan-mode-OSU42TOI.js");
9358
9378
  return "[DELEGATION_BREAK] " + handleExitPlanMode(String(args.reason ?? ""), ctx.cesar?.planDispatch ?? null, ctx);
9359
9379
  }
9360
9380
  if (name === "ProposePlan") {
@@ -9377,7 +9397,7 @@ ${cleaned}`;
9377
9397
  }
9378
9398
  }
9379
9399
  }
9380
- const { handleProposePlan } = await import("./plan-mode-KBJY2FJN.js");
9400
+ const { handleProposePlan } = await import("./plan-mode-OSU42TOI.js");
9381
9401
  const dispatch = ctx.cesar.planDispatch;
9382
9402
  if (!dispatch) {
9383
9403
  return "[PLAN_ERROR] Internal plan display dispatch unavailable. Retry the plan request so Agon can render the approval panel.";
@@ -9413,13 +9433,14 @@ ${cleaned}`;
9413
9433
  return value >= 93 ? `Confidence ${value}% recorded. High confidence. Proceed.` : `Confidence ${value}% recorded. Proceed.`;
9414
9434
  }
9415
9435
  }
9416
- const READ_TOOLS = /* @__PURE__ */ new Set(["Read", "Grep", "Glob", "ReportConfidence", "Delegate"]);
9417
- if (!ctx.cesar.confidenceSatisfied && !READ_TOOLS.has(name)) {
9436
+ const CONFIDENCE_INVESTIGATION_TOOLS = /* @__PURE__ */ new Set(["Read", "Grep", "Glob", "ReportConfidence", "Delegate"]);
9437
+ const _isInvestigation = CONFIDENCE_INVESTIGATION_TOOLS.has(name) || name === "Bash" && isReadOnlyCommand(String(args.command ?? ""));
9438
+ if (!ctx.cesar.confidenceSatisfied && !_isInvestigation) {
9418
9439
  const blocks = (ctx.cesar.confidenceBlockCount ?? 0) + 1;
9419
9440
  ctx.cesar.confidenceBlockCount = blocks;
9420
9441
  if (blocks <= CONFIDENCE_BLOCK_LIMIT) {
9421
9442
  ctx.cesar.blockedOnConfidence = { name, args };
9422
- return `[BLOCKED] Report confidence first. Call ReportConfidence(value) before using ${name}. After ReportConfidence succeeds, retry the SAME ${name} call immediately with the same arguments. Read/Grep/Glob are allowed for investigation.`;
9443
+ return `[BLOCKED] Report confidence first. Call ReportConfidence(value) before using ${name}. After ReportConfidence succeeds, retry the SAME ${name} call immediately with the same arguments. Read/Grep/Glob and read-only Bash are allowed for investigation.`;
9423
9444
  }
9424
9445
  ctx.cesar.confidenceSatisfied = true;
9425
9446
  ctx.cesar.blockedOnConfidence = null;
@@ -9464,6 +9485,16 @@ Repair retry already used for this exact ${name} input in this turn. Stop retryi
9464
9485
  toolResultCache.clear();
9465
9486
  ctx.cesar.blockedOnConfidence = null;
9466
9487
  }
9488
+ if (result.result.ok && SEARCH_NUDGE_TOOLS.has(name)) {
9489
+ const searches = (ctx.cesar.searchToolCount ?? 0) + 1;
9490
+ ctx.cesar.searchToolCount = searches;
9491
+ if (searches >= SEARCH_NUDGE_THRESHOLD && !ctx.cesar.searchNudged) {
9492
+ ctx.cesar.searchNudged = true;
9493
+ output = `${output ?? ""}
9494
+
9495
+ [NOTE] ${searches} read/search calls this turn. A CODEBASE BRIEF mapping where things live (files + top symbols per package) is in your system prompt \u2014 consult it to locate code instead of searching more. If something isn't listed, narrow the query rather than broadening it.`;
9496
+ }
9497
+ }
9467
9498
  return output;
9468
9499
  };
9469
9500
  }
@@ -9938,7 +9969,7 @@ async function commitTurnAndDelegate(pendingDel, input, response, cesarEngineId,
9938
9969
  const reasoning = delResult.userContext ? `${pendingDel.reasoning ?? ""}
9939
9970
 
9940
9971
  User context: ${delResult.userContext}` : pendingDel.reasoning;
9941
- return { mode, delegated: true, responded: true, action, task: pendingDel.task, reasoning, decisionReason: "tool-delegation", scope: pendingDel.scope, fitnessCmd: pendingDel.fitnessCmd, hardened: delResult.hardened ?? pendingDel.hardened, tribunalMode: delResult.tribunalMode ?? pendingDel.tribunalMode, team: delResult.team ?? pendingDel.team, target: pendingDel.target, engineId: pendingDel.engineId, engines: pendingDel.engines, taskKind: pendingDel.taskKind, maxTurns: pendingDel.maxTurns, queue: pendingDel.queue, gate: pendingDel.gate, push: pendingDel.push, pr: pendingDel.pr, maxHours: pendingDel.maxHours, budget: pendingDel.budget, ...telemetry ?? {} };
9972
+ return { mode, delegated: true, responded: true, action, task: pendingDel.task, reasoning, decisionReason: "tool-delegation", scope: pendingDel.scope, fitnessCmd: pendingDel.fitnessCmd, hardened: delResult.hardened ?? pendingDel.hardened, tribunalMode: delResult.tribunalMode ?? pendingDel.tribunalMode, team: delResult.team ?? pendingDel.team, target: pendingDel.target, engineId: pendingDel.engineId, engines: pendingDel.engines, taskKind: pendingDel.taskKind, maxTurns: pendingDel.maxTurns, queue: pendingDel.queue, gate: pendingDel.gate, builder: pendingDel.builder, push: pendingDel.push, pr: pendingDel.pr, maxHours: pendingDel.maxHours, budget: pendingDel.budget, ...telemetry ?? {} };
9942
9973
  }
9943
9974
  return { delegated: false, responded: true, decisionReason: "delegation-cancelled", ...telemetry ?? {} };
9944
9975
  }
@@ -10107,6 +10138,8 @@ async function handleCesarBrain(input, dispatch, ctx, images) {
10107
10138
  ctx.cesar.confidenceSatisfied = false;
10108
10139
  ctx.cesar.blockedOnConfidence = null;
10109
10140
  ctx.cesar.confidenceBlockCount = 0;
10141
+ ctx.cesar.searchToolCount = 0;
10142
+ ctx.cesar.searchNudged = false;
10110
10143
  ctx.cesar.turnId = _turnId;
10111
10144
  ctx.cesar.planDispatch = dispatch;
10112
10145
  const _brainStartMs = Date.now();
@@ -10265,7 +10298,7 @@ async function handleCesarBrain(input, dispatch, ctx, images) {
10265
10298
  const fastPathMode = simpleEditFastPath ? "edit" : answerFastPath ? "answer" : "";
10266
10299
  const fastPathBaseBudget = simpleEditFastPath ? 5 : 3;
10267
10300
  const fastPathMaxBudget = simpleEditFastPath ? 8 : 4;
10268
- const FAST_PATH_BLOCKED_TOOLS = ["Forge", "Brainstorm", "Tribunal", "Campfire", "Pipeline", "Review", "Agent", "Goal", "Delegate", "ProposePlan", "QuickNero"];
10301
+ const FAST_PATH_BLOCKED_TOOLS = ["Forge", "Brainstorm", "Tribunal", "Campfire", "Pipeline", "Review", "Agent", "Goal", "Conquer", "Delegate", "ProposePlan", "QuickNero"];
10269
10302
  if (cesarFastPath && !restoreFastPathMode) {
10270
10303
  const hadPreviousFastPathMode = Object.prototype.hasOwnProperty.call(ctx.cesar, "fastPathMode");
10271
10304
  const previousFastPathMode = ctx.cesar.fastPathMode;
@@ -10514,7 +10547,7 @@ ${enrichedInput}`;
10514
10547
  const toolInput = typeof meta.input === "string" ? meta.input : meta.input ? JSON.stringify(meta.input) : "";
10515
10548
  const toolName = chunk.content || "tool";
10516
10549
  const toolStatus = meta.status ?? "running";
10517
- const STREAM_ORCH = /* @__PURE__ */ new Set(["Forge", "Brainstorm", "Tribunal", "Campfire", "Pipeline", "Review", "Agent", "Goal"]);
10550
+ const STREAM_ORCH = /* @__PURE__ */ new Set(["Forge", "Brainstorm", "Tribunal", "Campfire", "Pipeline", "Review", "Agent", "Goal", "Conquer"]);
10518
10551
  hadToolActivity = true;
10519
10552
  recordToolUse(toolName, ctx.cesar.hasNativeTools ? "native" : "eager", toolInput, toolStatus);
10520
10553
  dispatch({ type: "spinner-update", message: `Cesar: ${toolName}\u2026` });
@@ -10859,7 +10892,7 @@ ${enrichedInput}`;
10859
10892
  });
10860
10893
  continue;
10861
10894
  }
10862
- const { handleProposePlan } = await import("./plan-mode-KBJY2FJN.js");
10895
+ const { handleProposePlan } = await import("./plan-mode-OSU42TOI.js");
10863
10896
  const planDispatch = ctx.cesar.planDispatch ?? dispatch;
10864
10897
  if (planDispatch) {
10865
10898
  try {
@@ -10872,7 +10905,7 @@ ${enrichedInput}`;
10872
10905
  }
10873
10906
  } else if (signal.tool === "ExitPlanMode") {
10874
10907
  recordToolUse("ExitPlanMode", "mcp", JSON.stringify(signal.args ?? {}), "done");
10875
- const { handleExitPlanMode } = await import("./plan-mode-KBJY2FJN.js");
10908
+ const { handleExitPlanMode } = await import("./plan-mode-OSU42TOI.js");
10876
10909
  const planDispatch = ctx.cesar.planDispatch ?? dispatch;
10877
10910
  try {
10878
10911
  const exitResult = handleExitPlanMode(String(signal.args?.reason ?? ""), planDispatch, ctx);
@@ -11015,7 +11048,7 @@ ${enrichedInput}`;
11015
11048
  _lastToolInputs[name] = JSON.stringify(inp);
11016
11049
  recordToolUse(name, "xml", _lastToolInputs[name], "running");
11017
11050
  emitXmlToolEvent(name, inp, "running");
11018
- const LOOP_ORCH = /* @__PURE__ */ new Set(["Forge", "Brainstorm", "Tribunal", "Campfire", "Pipeline", "Review", "Agent", "Goal"]);
11051
+ const LOOP_ORCH = /* @__PURE__ */ new Set(["Forge", "Brainstorm", "Tribunal", "Campfire", "Pipeline", "Review", "Agent", "Goal", "Conquer"]);
11019
11052
  if (LOOP_ORCH.has(name)) {
11020
11053
  if (cesarFastPath) {
11021
11054
  return;
@@ -11088,7 +11121,7 @@ ${enrichedInput}`;
11088
11121
  output: "A Cesar plan is already active; nested plans are blocked. Resume or cancel the current plan before proposing another."
11089
11122
  });
11090
11123
  } else {
11091
- const { handleProposePlan } = await import("./plan-mode-KBJY2FJN.js");
11124
+ const { handleProposePlan } = await import("./plan-mode-OSU42TOI.js");
11092
11125
  const planDispatch = ctx.cesar.planDispatch ?? dispatch;
11093
11126
  const plan = await handleProposePlan(ppArgs, planDispatch, ctx);
11094
11127
  if (ctx.setActivePlan) ctx.setActivePlan(plan);
@@ -11112,7 +11145,7 @@ ${enrichedInput}`;
11112
11145
  const epArgs = ctx.cesar._exitPlanModeArgs;
11113
11146
  delete ctx.cesar._exitPlanModeArgs;
11114
11147
  try {
11115
- const { handleExitPlanMode } = await import("./plan-mode-KBJY2FJN.js");
11148
+ const { handleExitPlanMode } = await import("./plan-mode-OSU42TOI.js");
11116
11149
  const planDispatch = ctx.cesar.planDispatch ?? dispatch;
11117
11150
  const exitResult = handleExitPlanMode(String(epArgs?.reason ?? ""), planDispatch, ctx);
11118
11151
  dispatch({ type: "tool-call", engineId: cesarEngineId, tool: "ExitPlanMode", input: JSON.stringify(epArgs ?? {}), status: "done", output: exitResult });
@@ -11196,11 +11229,18 @@ ${qnResult.challengeText}` : ""
11196
11229
  }
11197
11230
  }
11198
11231
  const investigationResponse = response;
11232
+ let mutationStallForced = false;
11233
+ if (!mutationDeferred && !inPlanMode && !ctx.cesar.pendingDelegation && (hadToolActivity || ranToolLoop) && session.alive && !abort.signal.aborted && detectMutationIntentStall(response)) {
11234
+ mutationDeferred = true;
11235
+ mutationStallForced = true;
11236
+ dispatch({ type: "warning", message: "Cesar described a write but called no tool \u2014 unlocking execution and pushing it to apply directly." });
11237
+ }
11199
11238
  if (mutationDeferred && toolRegistry && session.alive && !abort.signal.aborted) {
11200
11239
  toolCtx.readOnlyMode = false;
11201
11240
  dispatch({ type: "spinner-start", message: "Cesar executing\u2026", color });
11202
11241
  let execResponse = "";
11203
- const execGen = session.send({ message: "Investigation complete. You may now use write, edit, and bash tools to execute your plan. Proceed.", signal: abort.signal });
11242
+ const _execNudge = mutationStallForced ? "You HAVE Edit, Write, and Bash tools and you are NOT read-only. The investigation gate only DEFERS the first mutating call; calling Edit/Write/Bash is what unlocks execution \u2014 and it is unlocked now. Apply the change directly this turn with Edit/Write/Bash. Do NOT say you lack write tools, do NOT delegate to an Agent to do the writing, and do NOT ask the user to paste or apply it themselves." : "Investigation complete. You may now use write, edit, and bash tools to execute your plan. Proceed.";
11243
+ const execGen = session.send({ message: _execNudge, signal: abort.signal });
11204
11244
  for await (const chunk of execGen) {
11205
11245
  if (chunk.type === "text") execResponse += chunk.content;
11206
11246
  if (chunk.type === "done" || chunk.type === "error") break;
@@ -11383,7 +11423,7 @@ ${cleanFinalAnswer}` : cleanFinalAnswer;
11383
11423
  }
11384
11424
  }
11385
11425
  const _AUTO_CONT_WRITE_TOOLS = /* @__PURE__ */ new Set(["Edit", "Write", "MultiEdit", "NotebookEdit"]);
11386
- const _AUTO_CONT_LOOP_ORCH = /* @__PURE__ */ new Set(["Forge", "Brainstorm", "Tribunal", "Campfire", "Pipeline", "Review", "Agent", "Goal"]);
11426
+ const _AUTO_CONT_LOOP_ORCH = /* @__PURE__ */ new Set(["Forge", "Brainstorm", "Tribunal", "Campfire", "Pipeline", "Review", "Agent", "Goal", "Conquer"]);
11387
11427
  const _AUTO_CONT_CONTINUE_RE = /\b(?:now i'?ll|next i'?ll|still need|let me also|i'?ll also|then i'?ll|next step|next up)\b/i;
11388
11428
  const _AUTO_CONT_READONLY_DONE_RE = /\b(?:tests? passed|all (?:tests|checks) pass|no matches found|no issues found|no errors|all clean|nothing to (?:do|fix|change)|already (?:correct|fixed|in place|done))\b/i;
11389
11429
  const _detectTurnState = (resp, baselineToolCount) => {
@@ -11447,7 +11487,7 @@ ${cleanFinalAnswer}` : cleanFinalAnswer;
11447
11487
  },
11448
11488
  maxTurns: cesarFastPath ? fastPathMaxBudget : void 0
11449
11489
  });
11450
- const _shouldAutoContinue = (hadToolActivity || ranToolLoop) && !inPlanMode && !ctx.cesar.pendingDelegation && session.alive && !abort.signal.aborted && !_engineErrored && response.trim().length > 0;
11490
+ const _shouldAutoContinue = (hadToolActivity || ranToolLoop) && !inPlanMode && !answerFastPath && !ctx.cesar.pendingDelegation && session.alive && !abort.signal.aborted && !_engineErrored && response.trim().length > 0;
11451
11491
  if (_shouldAutoContinue) {
11452
11492
  const MAX_CONTINUATIONS = 5;
11453
11493
  let _continuations = 0;
@@ -11692,8 +11732,9 @@ ${cleanFinalAnswer}` : cleanFinalAnswer;
11692
11732
  const full = m[3].trim();
11693
11733
  _forkOptions.push({ key, label: full.length > 60 ? full.slice(0, 59) + "\u2026" : full, full });
11694
11734
  }
11695
- const isForkQuestion = /\?\s*$/.test(lastLine) && _forkOptions.length >= 2 && _forkOptions.length <= 6;
11696
- const asksConfirmation = !ranToolLoop && /\?\s*$/.test(lastLine) && /\b(want|shall|should|ready|proceed|go ahead|dispatch|confirm|continue|implement)\b/i.test(lastLine);
11735
+ const _isChatTurn = routingHints.intakeKind === "chat" || routingHints.recommendedFlow === "answer";
11736
+ const isForkQuestion = !_isChatTurn && /\?\s*$/.test(lastLine) && _forkOptions.length >= 2 && _forkOptions.length <= 6;
11737
+ const asksConfirmation = !_isChatTurn && !ranToolLoop && /\?\s*$/.test(lastLine) && /\b(want|shall|should|ready|proceed|go ahead|dispatch|confirm|continue|implement)\b/i.test(lastLine);
11697
11738
  if (isForkQuestion) {
11698
11739
  const _forkColors = ["#4ade80", "#22d3ee", "#fbbf24", "#a78bfa", "#f97316", "#ef4444"];
11699
11740
  const _allNumeric = _forkOptions.every((o) => /^[0-9]$/.test(o.key));
@@ -11874,4 +11915,4 @@ export {
11874
11915
  ensureCesarSession,
11875
11916
  handleCesarBrain
11876
11917
  };
11877
- //# sourceMappingURL=chunk-HVJTVOXT.js.map
11918
+ //# sourceMappingURL=chunk-XOJPAFCJ.js.map