@kernlang/agon 0.1.3 → 0.1.4

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.
@@ -1,5 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
+ ENGINE_COLORS,
4
+ cleanEngineOutput,
5
+ icons,
6
+ parseMarkdownBlocks
7
+ } from "./chunk-WE32YJKT.js";
8
+ import {
9
+ AGON_MODE_NAMES,
3
10
  CORPUS_PATH,
4
11
  FitnessError,
5
12
  RUNS_DIR,
@@ -68,6 +75,7 @@ import {
68
75
  getProjectFileStateCache,
69
76
  getRatings,
70
77
  gitChangedFiles,
78
+ hasProjectBrief,
71
79
  isReadOnlyCommand,
72
80
  listCesarPlans,
73
81
  loadConfig,
@@ -100,7 +108,7 @@ import {
100
108
  worktreeCreate,
101
109
  worktreeDiff,
102
110
  worktreeRemoveBestEffort
103
- } from "./chunk-PFHGKBQT.js";
111
+ } from "./chunk-C22VTCS6.js";
104
112
 
105
113
  // ../forge/src/generated/forge.ts
106
114
  import { randomUUID as randomUUID2 } from "crypto";
@@ -112,7 +120,7 @@ import { join } from "path";
112
120
  import { mkdirSync, rmSync } from "fs";
113
121
  var HEALTH_CHECK_DISABLE_ENV = "AGON_DISABLE_FORGE_HEALTH_CHECK";
114
122
  var HEALTH_CHECK_DEFAULT_PROMPT = "Reply with just: ok";
115
- async function healthCheckEngine(engineId, registry, adapter, _cwd, timeoutSec, prompt) {
123
+ async function healthCheckEngine(engineId, registry, adapter, _cwd, timeoutSec, prompt, signal) {
116
124
  const start = Date.now();
117
125
  let engine;
118
126
  try {
@@ -145,7 +153,8 @@ async function healthCheckEngine(engineId, registry, adapter, _cwd, timeoutSec,
145
153
  cwd: scratchDir,
146
154
  mode: useAgent ? "agent" : "exec",
147
155
  timeout: Math.max(1, Math.ceil(timeoutSec)),
148
- outputDir: scratchDir
156
+ outputDir: scratchDir,
157
+ signal
149
158
  };
150
159
  dispatchResult = useAgent ? await adapter.dispatchAgent(opts) : await adapter.dispatch(opts);
151
160
  } catch (err) {
@@ -203,7 +212,7 @@ function isApiBackedEngine(engineId, registry) {
203
212
  return false;
204
213
  }
205
214
  }
206
- async function healthCheckEngines(engineIds, registry, adapter, cwd, timeoutSec, prompt, apiTimeoutSec, maxParallelApi) {
215
+ async function healthCheckEngines(engineIds, registry, adapter, cwd, timeoutSec, prompt, apiTimeoutSec, maxParallelApi, signal) {
207
216
  const start = Date.now();
208
217
  if (process.env[HEALTH_CHECK_DISABLE_ENV]) {
209
218
  return { healthy: engineIds.slice(), unhealthy: [], totalMs: Date.now() - start };
@@ -215,10 +224,10 @@ async function healthCheckEngines(engineIds, registry, adapter, cwd, timeoutSec,
215
224
  engineIds.map((id) => {
216
225
  if (isApiBackedEngine(id, registry)) {
217
226
  return apiSem.runWith(
218
- () => healthCheckEngine(id, registry, adapter, cwd, apiTimeout, prompt)
227
+ () => healthCheckEngine(id, registry, adapter, cwd, apiTimeout, prompt, signal)
219
228
  );
220
229
  }
221
- return healthCheckEngine(id, registry, adapter, cwd, timeoutSec, prompt);
230
+ return healthCheckEngine(id, registry, adapter, cwd, timeoutSec, prompt, signal);
222
231
  })
223
232
  );
224
233
  const healthy = [];
@@ -243,6 +252,46 @@ async function healthCheckEngines(engineIds, registry, adapter, cwd, timeoutSec,
243
252
  });
244
253
  return { healthy, unhealthy, totalMs: Date.now() - start };
245
254
  }
255
+ async function preflightHealthFilter(opts) {
256
+ const { engineIds, registry, adapter } = opts;
257
+ const skipped = [];
258
+ const afterQuarantine = [];
259
+ for (const id of engineIds) {
260
+ const health = engineHealth.get(id);
261
+ if (health && (health.status === "auth-failed" || health.status === "unreachable")) {
262
+ skipped.push({ engineId: id, status: health.status, reason: health.reason || "quarantined this session" });
263
+ } else {
264
+ afterQuarantine.push(id);
265
+ }
266
+ }
267
+ const wantProbe = opts.probe === true || !!process.env.AGON_FORCE_HEALTH_PROBE;
268
+ if (!wantProbe || afterQuarantine.length === 0) {
269
+ return { healthy: afterQuarantine, skipped };
270
+ }
271
+ let apiTimeoutSec;
272
+ let maxParallelApi;
273
+ try {
274
+ const cfg = loadConfig(opts.cwd ?? process.cwd());
275
+ apiTimeoutSec = cfg?.forgeHealthCheckApiTimeoutSec;
276
+ maxParallelApi = cfg?.forgeMaxParallelApi;
277
+ } catch {
278
+ }
279
+ const summary = await healthCheckEngines(
280
+ afterQuarantine.slice(),
281
+ registry,
282
+ adapter,
283
+ opts.cwd ?? process.cwd(),
284
+ opts.timeoutSec ?? 5,
285
+ HEALTH_CHECK_DEFAULT_PROMPT,
286
+ apiTimeoutSec,
287
+ maxParallelApi,
288
+ opts.signal
289
+ );
290
+ for (const u of summary.unhealthy) {
291
+ skipped.push({ engineId: u.engineId, status: "health-check-failed", reason: u.reason ?? "probe failed" });
292
+ }
293
+ return { healthy: summary.healthy, skipped };
294
+ }
246
295
 
247
296
  // ../forge/src/generated/stages.ts
248
297
  import { join as join4 } from "path";
@@ -1648,7 +1697,11 @@ async function runForge(options, registry, adapter, onEvent) {
1648
1697
  onEvent?.({ type: "forge:fatal", data: { phase: "preflight", error } });
1649
1698
  return manifest2;
1650
1699
  }
1651
- const enabledEngines = options.engines ?? registry.activeIds(config);
1700
+ const __roster = registry.partitionRoster(options.engines ?? null, config);
1701
+ if (__roster.removed.length > 0) {
1702
+ throw new Error(`Removed engine(s) cannot run: ${__roster.removed.join(", ")}. They were hard-removed via 'agon engine remove'; restore with 'agon engine add <id>' (or /engines restore <id>).`);
1703
+ }
1704
+ const enabledEngines = __roster.active;
1652
1705
  const explicitlyRequested = options.engines != null && options.engines.length > 0;
1653
1706
  const skippedQuarantine = [];
1654
1707
  const droppedEngines = [];
@@ -2397,16 +2450,22 @@ function fallbackParse(output) {
2397
2450
  async function runBrainstorm(opts) {
2398
2451
  const brainstormId = randomUUID3().slice(0, 8);
2399
2452
  seedNewEnginesFromRegistry(opts.registry);
2453
+ const __hc = await preflightHealthFilter({ engineIds: opts.engines, registry: opts.registry, adapter: opts.adapter, signal: opts.signal });
2454
+ for (const s of __hc.skipped) console.warn(`[agon] brainstorm: skipping ${s.engineId} \u2014 ${s.status} (${s.reason})`);
2455
+ const __engines = __hc.healthy;
2456
+ if (__engines.length === 0) {
2457
+ throw new Error(`No healthy engines for brainstorm; all ${__hc.skipped.length} were quarantined this session (${__hc.skipped.map((s) => s.engineId).join(", ")}). Restore with 'agon engine add <id>'.`);
2458
+ }
2400
2459
  const sidechain = createSidechainLogger({
2401
2460
  sessionId: brainstormId,
2402
2461
  sessionType: "brainstorm",
2403
2462
  outputDir: opts.outputDir
2404
2463
  });
2405
- sidechain.log("brainstorm:init", void 0, { question: opts.question, engines: opts.engines });
2464
+ sidechain.log("brainstorm:init", void 0, { question: opts.question, engines: __engines });
2406
2465
  const ranked = await collectRankedDrafts({
2407
2466
  question: opts.question,
2408
2467
  context: opts.context,
2409
- engines: opts.engines,
2468
+ engines: __engines,
2410
2469
  registry: opts.registry,
2411
2470
  adapter: opts.adapter,
2412
2471
  timeout: opts.timeout,
@@ -2751,9 +2810,18 @@ ${snippet}${thinking.length > 800 ? "\u2026" : ""}`;
2751
2810
  });
2752
2811
  }
2753
2812
  async function runTribunal(opts) {
2754
- const { question, engines, rounds, registry, adapter, timeout, outputDir } = opts;
2813
+ const { question, rounds, registry, adapter, timeout, outputDir } = opts;
2755
2814
  const signal = opts.signal;
2756
2815
  const mode = opts.mode ?? "adversarial";
2816
+ const __hc = await preflightHealthFilter({ engineIds: opts.engines, registry, adapter, signal });
2817
+ for (const s of __hc.skipped) console.warn(`[agon] tribunal: skipping ${s.engineId} \u2014 ${s.status} (${s.reason})`);
2818
+ const engines = __hc.healthy;
2819
+ if (engines.length < 2) {
2820
+ if (__hc.skipped.length === 0) {
2821
+ throw new Error(`Tribunal needs at least 2 engines; only ${opts.engines.length} provided. Widen --engines or add one with 'agon engine add <id>'.`);
2822
+ }
2823
+ throw new Error(`Tribunal needs at least 2 healthy engines; ${__hc.skipped.length} were quarantined this session (${__hc.skipped.map((s) => s.engineId).join(", ")}). Restore with 'agon engine add <id>' or widen --engines.`);
2824
+ }
2757
2825
  seedNewEnginesFromRegistry(registry);
2758
2826
  const modeConfig = getModeConfig(mode, engines.length);
2759
2827
  const roles = modeConfig.roles.slice(0, engines.length);
@@ -2900,8 +2968,14 @@ ${p.arguments[p.arguments.length - 1]}`).join("\n\n---\n\n") : void 0;
2900
2968
 
2901
2969
  // ../forge/src/generated/campfire.ts
2902
2970
  async function runCampfire(opts) {
2903
- const { topic, engines, registry, adapter, strategy, timeout, outputDir } = opts;
2971
+ const { topic, registry, adapter, strategy, timeout, outputDir } = opts;
2904
2972
  const cwd = resolveWorkingDir();
2973
+ const __hc = await preflightHealthFilter({ engineIds: opts.engines, registry, adapter, signal: opts.signal });
2974
+ for (const s of __hc.skipped) console.warn(`[agon] campfire: skipping ${s.engineId} \u2014 ${s.status} (${s.reason})`);
2975
+ const engines = __hc.healthy;
2976
+ if (engines.length === 0) {
2977
+ throw new Error(`No healthy engines for campfire; all ${__hc.skipped.length} were quarantined this session (${__hc.skipped.map((s) => s.engineId).join(", ")}). Restore with 'agon engine add <id>'.`);
2978
+ }
2905
2979
  const basePrompt = [
2906
2980
  `## CAMPFIRE`,
2907
2981
  `Topic: ${topic || "open discussion"}`,
@@ -3081,12 +3155,18 @@ async function runNero(opts) {
3081
3155
  const ratings = opts.ratings ?? getRatings();
3082
3156
  const MAX_ATTEMPTS = 2;
3083
3157
  const backoffMs = opts.retryBackoffMs ?? 1200;
3158
+ const __hc = await preflightHealthFilter({ engineIds: opts.engines, registry: opts.registry, adapter: opts.adapter, signal: opts.signal });
3159
+ for (const s of __hc.skipped) opts.onStatus?.(`Nero: skipping ${s.engineId} \u2014 ${s.status} (${s.reason})`);
3160
+ const __engines = __hc.healthy;
3084
3161
  const forced = opts.engine?.trim();
3162
+ if (forced && opts.engines.includes(forced) && !__engines.includes(forced)) {
3163
+ return { ok: false, engineId: forced, reason: "none", scope: null, verdict: "unknown", challengeConfidence: null, challengeText: `Requested Nero critic '${forced}' is quarantined this session (auth-failed/unreachable). Restore with 'agon engine add <id>' or pick another --engine.`, outputDir: opts.outputDir };
3164
+ }
3085
3165
  let ranked;
3086
- if (forced && opts.engines.includes(forced)) {
3166
+ if (forced && __engines.includes(forced)) {
3087
3167
  ranked = [{ engineId: forced, reason: "forced", scope: null }];
3088
3168
  } else {
3089
- ranked = rankNeroCritics(opts.engines, ratings, { exclude: opts.exclude });
3169
+ ranked = rankNeroCritics(__engines, ratings, { exclude: opts.exclude });
3090
3170
  }
3091
3171
  if (ranked.length === 0) {
3092
3172
  return { ok: false, engineId: "", reason: "none", scope: null, verdict: "unknown", challengeConfidence: null, challengeText: "No engine available to play Nero (every candidate is the author under review).", outputDir: opts.outputDir };
@@ -3283,10 +3363,33 @@ function parseCouncilConfidence(text) {
3283
3363
  return n;
3284
3364
  }
3285
3365
  async function runCouncil(opts) {
3286
- const { question, engines, registry, adapter, timeout, outputDir } = opts;
3366
+ const { question, registry, adapter, timeout, outputDir } = opts;
3287
3367
  const signal = opts.signal;
3288
3368
  const cwd = opts.cwd ?? resolveWorkingDir();
3289
3369
  const warnings = [];
3370
+ const __hc = await preflightHealthFilter({ engineIds: opts.engines, registry, adapter, signal });
3371
+ for (const s of __hc.skipped) {
3372
+ warnings.push(`${s.engineId} skipped \u2014 ${s.status} (${s.reason})`);
3373
+ console.warn(`[agon] council: skipping ${s.engineId} \u2014 ${s.status} (${s.reason})`);
3374
+ }
3375
+ const engines = __hc.healthy;
3376
+ const __forcedChair = opts.chairman?.trim();
3377
+ if (__forcedChair && __hc.skipped.some((s) => s.engineId === __forcedChair)) {
3378
+ return {
3379
+ ok: false,
3380
+ question,
3381
+ brief: "",
3382
+ chairmanId: __forcedChair,
3383
+ chairmanReason: "forced",
3384
+ actingChairmanId: "",
3385
+ seats: [],
3386
+ verdict: `Requested chairman '${__forcedChair}' is quarantined this session (auth-failed/unreachable) and cannot chair. Restore with 'agon engine add <id>' or pick another chair.`,
3387
+ confidence: null,
3388
+ degraded: true,
3389
+ warnings: [`Chairman ${__forcedChair} quarantined this session.`],
3390
+ outputDir
3391
+ };
3392
+ }
3290
3393
  if (engines.length < 2) {
3291
3394
  return {
3292
3395
  ok: false,
@@ -3322,6 +3425,13 @@ async function runCouncil(opts) {
3322
3425
  } catch {
3323
3426
  cesarId = "";
3324
3427
  }
3428
+ if (cesarId && !engines.includes(cesarId)) {
3429
+ const __ch = engineHealth.get(cesarId);
3430
+ if (__ch && (__ch.status === "auth-failed" || __ch.status === "unreachable")) {
3431
+ warnings.push(`Configured Cesar chair '${cesarId}' is quarantined this session (${__ch.status}); falling back to ${engines[0]} as chair.`);
3432
+ cesarId = "";
3433
+ }
3434
+ }
3325
3435
  chairmanId = cesarId || engines[0];
3326
3436
  chairmanReason = "cesar";
3327
3437
  degraded = true;
@@ -3582,9 +3692,15 @@ function synthesisRoutingAdvice(prompt) {
3582
3692
  ].join(" ");
3583
3693
  }
3584
3694
  async function runSynthesisModus(opts) {
3585
- const { prompt, engines, registry, adapter, timeout, outputDir } = opts;
3695
+ const { prompt, registry, adapter, timeout, outputDir } = opts;
3586
3696
  const swapRounds = Math.max(0, opts.swaps ?? 1);
3587
3697
  const cwd = resolveWorkingDir();
3698
+ const __hc = await preflightHealthFilter({ engineIds: opts.engines, registry, adapter, signal: opts.signal });
3699
+ for (const s of __hc.skipped) console.warn(`[agon] synthesis: skipping ${s.engineId} \u2014 ${s.status} (${s.reason})`);
3700
+ const engines = __hc.healthy;
3701
+ if (engines.length === 0) {
3702
+ throw new Error(`No healthy engines for synthesis; all ${__hc.skipped.length} were quarantined this session (${__hc.skipped.map((s) => s.engineId).join(", ")}). Restore with 'agon engine add <id>'.`);
3703
+ }
3588
3704
  const drafts = [];
3589
3705
  const draftPromises = engines.map(async (engineId) => {
3590
3706
  const engine = registry.get(engineId);
@@ -4058,7 +4174,11 @@ async function runTeamForge(options, registry, adapter, onEvent) {
4058
4174
  sessionType: "team-forge",
4059
4175
  outputDir: forgeDir
4060
4176
  });
4061
- const enabledEngines = options.engines ?? registry.activeIds(config);
4177
+ const __roster = registry.partitionRoster(options.engines ?? null, config);
4178
+ if (__roster.removed.length > 0) {
4179
+ throw new Error(`Removed engine(s) cannot run: ${__roster.removed.join(", ")}. Restore with 'agon engine add <id>' (or /engines restore <id>).`);
4180
+ }
4181
+ const enabledEngines = __roster.active;
4062
4182
  const available = enabledEngines.filter((id) => {
4063
4183
  try {
4064
4184
  const engine = registry.get(id);
@@ -4313,7 +4433,11 @@ async function runTeamTribunal(options) {
4313
4433
  sessionType: "team-tribunal",
4314
4434
  outputDir: options.outputDir
4315
4435
  });
4316
- const enabledEngines = options.engines ?? options.registry.activeIds(config);
4436
+ const __roster = options.registry.partitionRoster(options.engines ?? null, config);
4437
+ if (__roster.removed.length > 0) {
4438
+ throw new Error(`Removed engine(s) cannot run: ${__roster.removed.join(", ")}. Restore with 'agon engine add <id>' (or /engines restore <id>).`);
4439
+ }
4440
+ const enabledEngines = __roster.active;
4317
4441
  const available = enabledEngines.filter((id) => {
4318
4442
  try {
4319
4443
  const engine = options.registry.get(id);
@@ -4574,7 +4698,11 @@ async function runTeamBrainstorm(options) {
4574
4698
  sessionType: "team-brainstorm",
4575
4699
  outputDir: options.outputDir
4576
4700
  });
4577
- const enabledEngines = options.engines ?? options.registry.activeIds(config);
4701
+ const __roster = options.registry.partitionRoster(options.engines ?? null, config);
4702
+ if (__roster.removed.length > 0) {
4703
+ throw new Error(`Removed engine(s) cannot run: ${__roster.removed.join(", ")}. Restore with 'agon engine add <id>' (or /engines restore <id>).`);
4704
+ }
4705
+ const enabledEngines = __roster.active;
4578
4706
  const available = enabledEngines.filter((id) => {
4579
4707
  try {
4580
4708
  const engine = options.registry.get(id);
@@ -6510,113 +6638,6 @@ Continue. Emit CONQUER_ASK only for a real fork, CONQUER_DONE when finished.`;
6510
6638
  };
6511
6639
  }
6512
6640
 
6513
- // src/generated/signals/icons.ts
6514
- var ROMAN_ICONS = { read: "\u039E", edit: "\u270E", write: "\u2712", bash: "\u03DF", search: "\u2609", find: "\u2295", tool: "\u2692", campfire: "\u2632", brainstorm: "\u2609", tribunal: "\u2696", image: "\u229E", queue: "\u231B", prompt: "\u25BB", winner: "\u2605", success: "\u2714", fail: "\u2718", warning: "\u26A0", header: "\u25B8", nero: "\u2020", dotOn: "\u25C6", dotOff: "\u25C7", play: "\u25B6", refresh: "\u21BB", flag: "\u2691", check: "\u2714", cross: "\u2718", spinner: "\u25D0" };
6515
- var CLASSIC_ICONS = { read: "\u{1F4C4}", edit: "\u270F\uFE0F", write: "\u{1F4DD}", bash: "\u26A1", search: "\u{1F50D}", find: "\u{1F4C2}", tool: "\u{1F527}", campfire: "\u{1F525}", brainstorm: "\u{1F4A1}", tribunal: "\u2696", image: "\u{1F4CE}", queue: "\u23F3", prompt: "\u276F", winner: "\u2605", success: "\u2714", fail: "\u2718", warning: "\u26A0", header: "\u25B8", nero: "\u2694", dotOn: "\u25CF", dotOff: "\u25CB", play: "\u25B6", refresh: "\u21BB", flag: "\u2691", check: "\u2714", cross: "\u2718", spinner: "\u25D0" };
6516
- function icons() {
6517
- const theme = loadConfig().iconTheme ?? "roman";
6518
- return theme === "classic" ? CLASSIC_ICONS : ROMAN_ICONS;
6519
- }
6520
-
6521
- // src/generated/blocks/output-format.ts
6522
- var BOLD = "\x1B[1m";
6523
- var DIM = "\x1B[2m";
6524
- var GREEN = "\x1B[32m";
6525
- var RED = "\x1B[31m";
6526
- var YELLOW = "\x1B[33m";
6527
- var CYAN = "\x1B[36m";
6528
- var RESET = "\x1B[0m";
6529
- var ENGINE_COLORS = { claude: 208, codex: 34, agy: 33, ollama: 255, aider: 141, openrouter: 197, qwen: 45, mistral: 75, opencode: 156, minimax: 124, zai: 124 };
6530
- function bold(text) {
6531
- return `${BOLD}${text}${RESET}`;
6532
- }
6533
- function dim(text) {
6534
- return `${DIM}${text}${RESET}`;
6535
- }
6536
- function green(text) {
6537
- return `${GREEN}${text}${RESET}`;
6538
- }
6539
- function red(text) {
6540
- return `${RED}${text}${RESET}`;
6541
- }
6542
- function yellow(text) {
6543
- return `${YELLOW}${text}${RESET}`;
6544
- }
6545
- function cyan(text) {
6546
- return `${CYAN}${text}${RESET}`;
6547
- }
6548
- function stripAnsi(str) {
6549
- return str.replace(/\x1b\[[0-9;]*m/g, "");
6550
- }
6551
- function visibleLength(str) {
6552
- return stripAnsi(str).length;
6553
- }
6554
- function header(text) {
6555
- const { header: h } = icons();
6556
- console.log(`
6557
- ${BOLD}${CYAN}${h} ${text}${RESET}`);
6558
- }
6559
- function success(text) {
6560
- const { success: s } = icons();
6561
- console.log(`${GREEN}${s}${RESET} ${text}`);
6562
- }
6563
- function fail(text) {
6564
- const { fail: f } = icons();
6565
- console.log(`${RED}${f}${RESET} ${text}`);
6566
- }
6567
- function warn(text) {
6568
- const { warning: w } = icons();
6569
- console.log(`${YELLOW}${w}${RESET} ${text}`);
6570
- }
6571
- function info(text) {
6572
- console.log(`${DIM}${text}${RESET}`);
6573
- }
6574
- function table(headers, rows) {
6575
- const widths = headers.map(
6576
- (h, i) => Math.max(visibleLength(h), ...rows.map((r) => visibleLength(r[i] ?? "")))
6577
- );
6578
- const headerLine = headers.map((h, i) => h.padEnd(widths[i])).join(" ");
6579
- const separator = widths.map((w) => "\u2500".repeat(w)).join("\u2500\u2500");
6580
- console.log(` ${bold(headerLine)}`);
6581
- console.log(` ${dim(separator)}`);
6582
- for (const row of rows) {
6583
- const line = row.map((cell, i) => {
6584
- const pad = widths[i] - visibleLength(cell);
6585
- return cell + " ".repeat(Math.max(0, pad));
6586
- }).join(" ");
6587
- console.log(` ${line}`);
6588
- }
6589
- }
6590
- function shortToolPath(filePath) {
6591
- const home = process.env.HOME;
6592
- const stripped = String(filePath ?? "").replace(`${process.cwd()}/`, "");
6593
- return home ? stripped.replace(home, "~") : stripped;
6594
- }
6595
- function isCesarTelemetryLine(message) {
6596
- const text = String(message ?? "").trim();
6597
- return text.startsWith("Cesar route:") || text.startsWith("What happened:");
6598
- }
6599
- function formatConfidenceToolLabel(parsed, rawInput) {
6600
- const rawValue = parsed?.value ?? parsed?.confidence ?? parsed?.score;
6601
- let value = Number(rawValue);
6602
- if (!Number.isFinite(value)) {
6603
- const text = String(rawInput ?? "");
6604
- const match = text.match(/"value"\s*:\s*(\d{1,3}(?:\.\d+)?)/) || text.match(/(\d{1,3})\s*%/);
6605
- if (match) {
6606
- value = Number(match[1]);
6607
- }
6608
- }
6609
- if (Number.isFinite(value)) {
6610
- const pct = value <= 1 && value > 0 ? Math.round(value * 100) : Math.round(value);
6611
- if (pct >= 0 && pct <= 100) {
6612
- const reasoning = String(parsed?.reasoning ?? parsed?.reason ?? parsed?.thought ?? "").replace(/\s+/g, " ").trim();
6613
- const shortReasoning = reasoning.length > 180 ? `${reasoning.slice(0, 177)}\u2026` : reasoning;
6614
- return shortReasoning ? `${pct}% confidence \xB7 ${shortReasoning}` : `${pct}% confidence`;
6615
- }
6616
- }
6617
- return "confidence";
6618
- }
6619
-
6620
6641
  // src/generated/handlers/engine-filter.ts
6621
6642
  var DEFAULT_EXCLUDED_ORCHESTRATION_ENGINE_PREFIXES = ["qwen", "ollama", "opencode", "open-code"];
6622
6643
  var DEFAULT_EXCLUDED_ORCHESTRATION_ENGINE_EXACT = ["kimi", "minimax", "mistral"];
@@ -6844,360 +6865,6 @@ async function executeEagerTool(toolName, meta, toolRegistry, toolCtx, dispatch,
6844
6865
  return result;
6845
6866
  }
6846
6867
 
6847
- // src/generated/blocks/markdown.ts
6848
- var FENCE_OPEN = /^```(\w*)\s*$/;
6849
- var FENCE_CLOSE = /^```\s*$/;
6850
- function isTableSeparator(line) {
6851
- return /^\|[\s:_-]+(\|[\s:_-]+)*\|?\s*$/.test(line.trim());
6852
- }
6853
- function isTableRow(line) {
6854
- const t = line.trim();
6855
- return t.startsWith("|") && t.includes("|", 1);
6856
- }
6857
- function parseTableAlignment(sepLine) {
6858
- const cells = sepLine.trim().replace(/^\||\|$/g, "").split("|");
6859
- return cells.map((c) => {
6860
- const t = c.trim();
6861
- if (t.startsWith(":") && t.endsWith(":")) return "center";
6862
- if (t.endsWith(":")) return "right";
6863
- return "left";
6864
- });
6865
- }
6866
- function parseTableCells(line) {
6867
- return line.trim().replace(/^\||\|$/g, "").split("|").map((c) => c.trim());
6868
- }
6869
- function emitProseWithTables(proseLines, segments) {
6870
- let i = 0;
6871
- let buffered = [];
6872
- function flushProse() {
6873
- const text = buffered.join("\n");
6874
- if (text.trim()) {
6875
- segments.push({ type: "prose", text, language: void 0, code: void 0, index: void 0, headers: void 0, rows: void 0, alignments: void 0 });
6876
- }
6877
- buffered = [];
6878
- }
6879
- while (i < proseLines.length) {
6880
- if (isTableRow(proseLines[i]) && i + 1 < proseLines.length && isTableSeparator(proseLines[i + 1])) {
6881
- flushProse();
6882
- const headers = parseTableCells(proseLines[i]);
6883
- const alignments = parseTableAlignment(proseLines[i + 1]);
6884
- const rows = [];
6885
- i += 2;
6886
- while (i < proseLines.length && isTableRow(proseLines[i]) && !isTableSeparator(proseLines[i])) {
6887
- rows.push(parseTableCells(proseLines[i]));
6888
- i++;
6889
- }
6890
- segments.push({ type: "table", text: void 0, language: void 0, code: void 0, index: void 0, headers, rows, alignments });
6891
- continue;
6892
- }
6893
- buffered.push(proseLines[i]);
6894
- i++;
6895
- }
6896
- flushProse();
6897
- }
6898
- var _mdCache = /* @__PURE__ */ new Map();
6899
- var _MD_CACHE_MAX = 500;
6900
- function parseMarkdownBlocks(text) {
6901
- let key;
6902
- if (text.length < 500) {
6903
- key = text;
6904
- } else {
6905
- let hash = 5381;
6906
- for (let i = 0; i < text.length; i++) {
6907
- hash = (hash << 5) + hash + text.charCodeAt(i) | 0;
6908
- }
6909
- key = `h:${hash}:${text.length}`;
6910
- }
6911
- const cached = _mdCache.get(key);
6912
- if (cached) return cached;
6913
- const lines = text.split("\n");
6914
- const segments = [];
6915
- let inCode = false;
6916
- let codeLang = "";
6917
- let codeLines = [];
6918
- let proseLines = [];
6919
- let codeIndex = 0;
6920
- for (const line of lines) {
6921
- const trimmed = line.trimStart();
6922
- if (!inCode) {
6923
- const openMatch = trimmed.match(FENCE_OPEN);
6924
- if (openMatch) {
6925
- emitProseWithTables(proseLines, segments);
6926
- proseLines = [];
6927
- inCode = true;
6928
- codeLang = openMatch[1] ?? "";
6929
- codeLines = [];
6930
- continue;
6931
- }
6932
- proseLines.push(line);
6933
- } else {
6934
- if (FENCE_CLOSE.test(trimmed)) {
6935
- if (codeLines.length > 0) {
6936
- codeIndex++;
6937
- segments.push({ type: "code", language: codeLang, code: codeLines.join("\n"), text: void 0, index: codeIndex, headers: void 0, rows: void 0, alignments: void 0 });
6938
- }
6939
- inCode = false;
6940
- codeLang = "";
6941
- codeLines = [];
6942
- continue;
6943
- }
6944
- codeLines.push(line);
6945
- }
6946
- }
6947
- if (inCode && codeLines.length > 0) {
6948
- codeIndex++;
6949
- segments.push({ type: "code", language: codeLang, code: codeLines.join("\n"), text: void 0, index: codeIndex, headers: void 0, rows: void 0, alignments: void 0 });
6950
- } else if (proseLines.length > 0) {
6951
- emitProseWithTables(proseLines, segments);
6952
- }
6953
- if (_mdCache.size >= _MD_CACHE_MAX) {
6954
- const firstKey = _mdCache.keys().next().value;
6955
- if (firstKey !== void 0) _mdCache.delete(firstKey);
6956
- }
6957
- _mdCache.set(key, segments);
6958
- return segments;
6959
- }
6960
- function truncateCodeLine(line, maxWidth) {
6961
- if (line.length <= maxWidth) {
6962
- return line;
6963
- }
6964
- const overflow = line.length - maxWidth + 1;
6965
- return line.slice(0, maxWidth - 1) + `\u2026+${overflow}`;
6966
- }
6967
- function extractCodexStructured(text) {
6968
- const summaryMatch = text.match(/summary:\s*"([\s\S]*?)"\s*(?:sections\s*\{|$)/);
6969
- const contentMatches = [...text.matchAll(/content:\s*"([\s\S]*?)"\s*\}/g)];
6970
- if (!summaryMatch || contentMatches.length === 0) {
6971
- return null;
6972
- }
6973
- const parts = [summaryMatch[1]];
6974
- const sectionMatches = [...text.matchAll(/\d+:\s*"([^"]+)"\s*\{\s*content:\s*"([\s\S]*?)"\s*\}/g)];
6975
- for (const m of sectionMatches) {
6976
- parts.push(`
6977
- ## ${m[1]}
6978
- ${m[2]}`);
6979
- }
6980
- return parts.join("\n").replace(/\\n/g, "\n").trim();
6981
- }
6982
- function parseStreamJsonLine(trimmed) {
6983
- try {
6984
- const parsed = JSON.parse(trimmed);
6985
- if (!parsed.type) return { action: "keep" };
6986
- if (parsed.type === "assistant" && parsed.message?.content) {
6987
- const content = typeof parsed.message.content === "string" ? parsed.message.content : Array.isArray(parsed.message.content) ? parsed.message.content.filter((b) => b.type === "text").map((b) => b.text).join("\n") : "";
6988
- return content ? { action: "use", content } : { action: "skip" };
6989
- }
6990
- if (parsed.type === "text" && parsed.part?.text) {
6991
- return { action: "use", content: parsed.part.text };
6992
- }
6993
- if (parsed.type === "result") {
6994
- if (parsed.subtype === "error_max_turns" || parsed.is_error) return { action: "skip" };
6995
- if (parsed.result && typeof parsed.result === "string") return { action: "use", content: parsed.result };
6996
- return { action: "skip" };
6997
- }
6998
- const skipTypes = [
6999
- "system",
7000
- "hook_started",
7001
- "hook_response",
7002
- "tool_use",
7003
- "tool_result",
7004
- "user",
7005
- "rate_limit_event",
7006
- "message_start",
7007
- "message_stop",
7008
- "message_delta",
7009
- "content_block_start",
7010
- "content_block_stop",
7011
- "content_block_delta",
7012
- "step_start",
7013
- "step_finish",
7014
- "step-start",
7015
- "step-finish",
7016
- "ping",
7017
- "error",
7018
- "init",
7019
- "session_start",
7020
- "session_end"
7021
- ];
7022
- if (skipTypes.includes(parsed.type)) return { action: "skip" };
7023
- if (parsed.type?.startsWith("hook_")) return { action: "skip" };
7024
- if (parsed.type?.startsWith("step_")) return { action: "skip" };
7025
- if (parsed.subtype === "system") return { action: "skip" };
7026
- if (parsed.sessionID || parsed.session_id || parsed.uuid) return { action: "skip" };
7027
- } catch {
7028
- }
7029
- return { action: "keep" };
7030
- }
7031
- function deduplicateInline(line) {
7032
- const len = line.length;
7033
- if (len < 10) return line;
7034
- for (let half = Math.floor(len / 2); half >= 5; half--) {
7035
- const candidate = line.slice(0, half);
7036
- if (line.slice(half).startsWith(candidate)) {
7037
- return candidate + line.slice(half + candidate.length);
7038
- }
7039
- }
7040
- return line;
7041
- }
7042
- function deduplicateParagraphs(text) {
7043
- const lines = text.split("\n");
7044
- const dedupedLines = lines.map((l) => deduplicateInline(l));
7045
- const joined = dedupedLines.join("\n");
7046
- const paragraphs = joined.split(/\n{2,}/);
7047
- const seen = /* @__PURE__ */ new Set();
7048
- const deduped = [];
7049
- for (const para of paragraphs) {
7050
- const normalized = para.trim().replace(/\s+/g, " ");
7051
- if (!normalized) {
7052
- continue;
7053
- }
7054
- if (seen.has(normalized)) {
7055
- continue;
7056
- }
7057
- seen.add(normalized);
7058
- deduped.push(para.trim());
7059
- }
7060
- return deduped.join("\n\n");
7061
- }
7062
- function stripBuddyThinkingNoise(text) {
7063
- const lines = text.split("\n");
7064
- const result = [];
7065
- for (let i = 0; i < lines.length; i++) {
7066
- const line = lines[i];
7067
- const trimmed = line.trim();
7068
- if (trimmed.startsWith("Command:") && trimmed.includes("/bin/")) continue;
7069
- if (trimmed.startsWith("Chunk ID:")) continue;
7070
- if (trimmed.startsWith("Wall time:")) continue;
7071
- if (trimmed.startsWith("Process exited with code")) continue;
7072
- if (trimmed.startsWith("Original token count:")) continue;
7073
- if (trimmed === "Output:") continue;
7074
- if (i + 1 < lines.length) {
7075
- const next = lines[i + 1].trim();
7076
- if (trimmed.length > 20 && next.startsWith(trimmed)) continue;
7077
- }
7078
- result.push(line);
7079
- }
7080
- return result.join("\n");
7081
- }
7082
- function shortenFilePaths(text) {
7083
- const fenceRe = /^```[\s\S]*?^```/gm;
7084
- const fences = [];
7085
- let fm;
7086
- while ((fm = fenceRe.exec(text)) !== null) {
7087
- fences.push({ start: fm.index, end: fm.index + fm[0].length });
7088
- }
7089
- function insideFence(pos) {
7090
- return fences.some((f) => pos >= f.start && pos < f.end);
7091
- }
7092
- const cwd = process.cwd();
7093
- const home = process.env.HOME ?? "";
7094
- const exts = "tsx|jsx|ts|js|json|kern|md|py|rs|go|yaml|yml|toml|sh|css|html|svelte|vue|rb|java|cpp|c|h";
7095
- const pathRe = new RegExp("(?<!`)(?:~/|/)[A-Za-z0-9._\\-/]+\\.(?:" + exts + ")(?::[0-9]+(?::[0-9]+)?|#L[0-9]+)?(?!`)", "g");
7096
- return text.replace(pathRe, (match, offset) => {
7097
- if (insideFence(offset)) return match;
7098
- if (match.length < 10) return match;
7099
- if (!match.includes("/")) return match;
7100
- let shortened = match;
7101
- if (shortened.startsWith("~/") && home) {
7102
- shortened = home + shortened.slice(1);
7103
- }
7104
- if (shortened.startsWith(cwd + "/")) {
7105
- shortened = shortened.slice(cwd.length + 1);
7106
- } else if (home && shortened.startsWith(home + "/")) {
7107
- shortened = "~/" + shortened.slice(home.length + 1);
7108
- }
7109
- const parts = shortened.split("/");
7110
- if (parts.length > 2) {
7111
- shortened = parts[parts.length - 1];
7112
- }
7113
- return "`" + shortened + "`";
7114
- });
7115
- }
7116
- function addParagraphBreaks(text) {
7117
- const paragraphs = text.split(/\n{2,}/);
7118
- const result = [];
7119
- for (const para of paragraphs) {
7120
- const lines = para.split("\n");
7121
- const isStructured = lines.some((l) => /^(#{1,3}\s|[-*]\s+\w|\d+\.\s+\w|>\s)/.test(l.trimStart()));
7122
- const totalLen = lines.reduce((sum, l) => sum + l.length, 0);
7123
- if (isStructured || totalLen < 250) {
7124
- result.push(para);
7125
- continue;
7126
- }
7127
- const joined = lines.join(" ");
7128
- const sentences = joined.split(/(?<=\.\s)(?=[A-Z])/);
7129
- if (sentences.length <= 2) {
7130
- result.push(para);
7131
- continue;
7132
- }
7133
- const chunks = [];
7134
- let current = "";
7135
- let count = 0;
7136
- for (const sentence of sentences) {
7137
- current += sentence;
7138
- count++;
7139
- if (count >= 3 || current.length > 250) {
7140
- chunks.push(current.trim());
7141
- current = "";
7142
- count = 0;
7143
- }
7144
- }
7145
- if (current.trim()) chunks.push(current.trim());
7146
- result.push(chunks.join("\n\n"));
7147
- }
7148
- return result.join("\n\n");
7149
- }
7150
- var _cleanCache = /* @__PURE__ */ new Map();
7151
- function cleanEngineOutput(raw) {
7152
- const cached = _cleanCache.get(raw);
7153
- if (cached !== void 0) {
7154
- return cached;
7155
- }
7156
- const lines = raw.split("\n");
7157
- const cleaned = [];
7158
- for (const line of lines) {
7159
- const trimmed = line.trim();
7160
- if (cleaned.length === 0 && !trimmed) {
7161
- continue;
7162
- }
7163
- if (trimmed.startsWith("{") && trimmed.includes('"type"')) {
7164
- const result2 = parseStreamJsonLine(trimmed);
7165
- if (result2.action === "skip") {
7166
- continue;
7167
- }
7168
- if (result2.action === "use") {
7169
- cleaned.push(result2.content);
7170
- continue;
7171
- }
7172
- }
7173
- cleaned.push(line);
7174
- }
7175
- let result = cleaned.join("\n").trim();
7176
- const codexResult = extractCodexStructured(result);
7177
- if (codexResult) {
7178
- result = codexResult;
7179
- }
7180
- result = result.replace(/<tool\s+name="[^"]*">[\s\S]*?<\/tool>/g, "");
7181
- result = result.replace(/<tool\s+name="[^"]*">[\s\S]*?<\/invoke>(\s*<\/[a-zA-Z_:]+>)*/g, "");
7182
- result = result.replace(/<tool_result[\s\S]*?<\/tool_result>/g, "");
7183
- result = result.replace(/<\/minimax:tool_call>/g, "");
7184
- result = result.replace(/<parameter\s+name="[^"]*">[^<]*<\/parameter>/g, "");
7185
- result = result.replace(/<tool_calls>[\s\S]*?<\/tool_calls>/gi, "");
7186
- result = result.replace(/<(Read|Write|Edit|Bash|Grep|Glob|LS|ListPlans|Retrieve)\b[\s\S]*?<\/\1>/g, "");
7187
- result = result.replace(/<\/?(file_path|path|pattern|command|query|content|old_string|new_string|start_line|end_line|id)>\s*/g, "");
7188
- result = result.replace(/<think>[\s\S]*?<\/think>\s*/gi, "");
7189
- result = result.replace(/^(I'm checking|I'm looking|I'm reading|I'm searching|I'm inspecting|Let me check|Let me look|Let me read|Let me search|Let me inspect|I've confirmed|I've verified|I've checked|I'll now|I will now|Now I'm|Now let me|First,? I'll|First,? let me|Next,? I'll|Next,? let me)\b[^.\n]*[.\n]\s*/gim, "");
7190
- result = stripBuddyThinkingNoise(result);
7191
- result = deduplicateParagraphs(result);
7192
- result = addParagraphBreaks(result);
7193
- result = shortenFilePaths(result);
7194
- if (_cleanCache.size > 200) {
7195
- _cleanCache.clear();
7196
- }
7197
- _cleanCache.set(raw, result);
7198
- return result;
7199
- }
7200
-
7201
6868
  // src/generated/blocks/code-buffer.ts
7202
6869
  var CodeBlockBuffer = class {
7203
6870
  blocks = [];
@@ -7324,7 +6991,8 @@ function _showNextPermission(actions) {
7324
6991
  choices: [
7325
6992
  { key: "y", label: "Yes", color: "#4ade80" },
7326
6993
  { key: "n", label: "No", color: "#ef4444" },
7327
- { key: "a", label: "Always", color: "#60a5fa" }
6994
+ { key: "a", label: "Always", color: "#60a5fa" },
6995
+ { key: "__other", label: "No, tell Cesar what to do instead", color: "#9ca3af" }
7328
6996
  ],
7329
6997
  resolve: (answer) => {
7330
6998
  _permissionQueue.shift();
@@ -7509,14 +7177,17 @@ function handleOutputEvent(event, state, actions, mode, chatStartTime) {
7509
7177
  case "patch-review":
7510
7178
  actions.setReviewEvent({ winnerId: event.winnerId, patchPath: event.patchPath, patchContent: event.patchContent });
7511
7179
  return;
7512
- case "question":
7180
+ case "question": {
7513
7181
  if (_permissionQueue.length > 0) {
7514
7182
  const qResolve = event.resolve;
7515
7183
  if (qResolve) qResolve("");
7516
7184
  return;
7517
7185
  }
7518
- actions.setQuestionState({ prompt: event.prompt, resolve: event.resolve, choices: event.choices });
7186
+ const _qChoices = event.choices;
7187
+ const _withOther = Array.isArray(_qChoices) && _qChoices.length > 0 && !_qChoices.some((c) => c && c.key === "__other") ? [..._qChoices, { key: "__other", label: "Other", color: "#9ca3af" }] : _qChoices;
7188
+ actions.setQuestionState({ prompt: event.prompt, resolve: event.resolve, choices: _withOther, defaultChoiceKey: event.defaultChoiceKey });
7519
7189
  return;
7190
+ }
7520
7191
  case "permission-ask": {
7521
7192
  if (state.streamingText) {
7522
7193
  actions.flushStream();
@@ -8790,6 +8461,25 @@ function summarizeToolPayload(payload) {
8790
8461
  }
8791
8462
  return out;
8792
8463
  }
8464
+ function buildToolErrorDiagnostic(name, args, error) {
8465
+ let inputSnippet;
8466
+ try {
8467
+ const safe = summarizeToolPayload(args);
8468
+ if (safe === void 0) {
8469
+ inputSnippet = "(no input)";
8470
+ } else {
8471
+ const s = JSON.stringify(safe);
8472
+ inputSnippet = s.length > 800 ? s.slice(0, 800) + "\u2026 (truncated)" : s;
8473
+ }
8474
+ } catch {
8475
+ inputSnippet = "(input could not be inspected)";
8476
+ }
8477
+ const rawErr = typeof error === "string" ? error : String(error ?? "Tool execution failed");
8478
+ const errMsg = rawErr.length > 500 ? rawErr.slice(0, 500) + "\u2026 (truncated)" : rawErr;
8479
+ return `Tool ${name} failed.
8480
+ Input (redacted): ${inputSnippet}
8481
+ Error: ${errMsg}`;
8482
+ }
8793
8483
  function appendCesarJsonl(fileName, record, runsDir) {
8794
8484
  const dir = runsDir ?? RUNS_DIR;
8795
8485
  mkdirSync10(dir, { recursive: true });
@@ -8833,6 +8523,27 @@ function recordCesarToolTimeline(record, runsDir) {
8833
8523
  } catch {
8834
8524
  }
8835
8525
  }
8526
+ function recordCesarConfidence(record) {
8527
+ try {
8528
+ const sessionId = typeof record.sessionId === "string" && /^[A-Za-z0-9_-][A-Za-z0-9._-]{0,127}$/.test(record.sessionId) ? record.sessionId : "unknown-session";
8529
+ const value = Number.isFinite(record.value) && record.value >= 0 && record.value <= 100 ? record.value : null;
8530
+ if (value === null) return;
8531
+ let reasoning = typeof record.reasoning === "string" ? record.reasoning.replace(/\s+/g, " ").trim() : void 0;
8532
+ if (reasoning) {
8533
+ if (looksSensitiveString(reasoning)) reasoning = "[redacted]";
8534
+ else if (reasoning.length > 500) reasoning = reasoning.slice(0, 500) + "\u2026 (truncated)";
8535
+ }
8536
+ appendCesarJsonl(`${sessionId}.jsonl`, {
8537
+ kind: "confidence",
8538
+ sessionId,
8539
+ turnId: record.turnId,
8540
+ engineId: record.engineId,
8541
+ value,
8542
+ reasoning
8543
+ }, agonPath("calibration"));
8544
+ } catch {
8545
+ }
8546
+ }
8836
8547
  function readJsonlRecords(filePath) {
8837
8548
  if (!existsSync11(filePath)) {
8838
8549
  return [];
@@ -9108,7 +8819,9 @@ ${projectCtx}`);
9108
8819
  console.warn(`[agon] codebase atlas skipped: ${err instanceof Error ? err.message : String(err)}`);
9109
8820
  }
9110
8821
  systemParts.push(`## AVAILABLE ENGINES
9111
- ${engineList}`);
8822
+ ${engineList}
8823
+
8824
+ MODES vs ENGINES: the names above are ENGINES \u2014 runnable backends you delegate to (codex, claude, agy, \u2026). MODES are commands/workflows you invoke (run /<name>): ${AGON_MODE_NAMES.join(", ")}. A mode runs ON engines \u2014 never treat a mode name (e.g. "conquer") as an engine id.`);
9112
8825
  if (ctx.explorationMode) {
9113
8826
  systemParts.push(`## OPERATING MODE
9114
8827
  Exploration mode is ON. Stay read-only: inspect files, search, and use read-only shell commands only. Do not call Edit or Write. Do not run non-read-only Bash commands.`);
@@ -9374,7 +9087,7 @@ ${cleaned}`;
9374
9087
  }
9375
9088
  }
9376
9089
  if (name === "ExitPlanMode") {
9377
- const { handleExitPlanMode } = await import("./plan-mode-OSU42TOI.js");
9090
+ const { handleExitPlanMode } = await import("./plan-mode-4XRC2ZC7.js");
9378
9091
  return "[DELEGATION_BREAK] " + handleExitPlanMode(String(args.reason ?? ""), ctx.cesar?.planDispatch ?? null, ctx);
9379
9092
  }
9380
9093
  if (name === "ProposePlan") {
@@ -9397,7 +9110,7 @@ ${cleaned}`;
9397
9110
  }
9398
9111
  }
9399
9112
  }
9400
- const { handleProposePlan } = await import("./plan-mode-OSU42TOI.js");
9113
+ const { handleProposePlan } = await import("./plan-mode-4XRC2ZC7.js");
9401
9114
  const dispatch = ctx.cesar.planDispatch;
9402
9115
  if (!dispatch) {
9403
9116
  return "[PLAN_ERROR] Internal plan display dispatch unavailable. Retry the plan request so Agon can render the approval panel.";
@@ -9425,6 +9138,13 @@ ${cleaned}`;
9425
9138
  ctx.cesar.reportedConfidenceReasoning = reasoning || void 0;
9426
9139
  ctx.cesar.confidenceSatisfied = true;
9427
9140
  ctx.cesar.confidenceBlockCount = 0;
9141
+ recordCesarConfidence({
9142
+ sessionId: String(ctx.chatSession?.id ?? "unknown-session"),
9143
+ turnId: ctx.cesar.turnId,
9144
+ engineId: ctx.cesarSession?.engineId ?? config?.cesarEngine,
9145
+ value,
9146
+ reasoning: reasoning || void 0
9147
+ });
9428
9148
  const blocked = ctx.cesar.blockedOnConfidence;
9429
9149
  ctx.cesar.blockedOnConfidence = null;
9430
9150
  if (blocked) {
@@ -9466,14 +9186,15 @@ ${cleaned}`;
9466
9186
  );
9467
9187
  let output = result.result.ok ? result.result.content : result.result.error ?? "Tool execution failed";
9468
9188
  if (!result.result.ok) {
9189
+ const diag = buildToolErrorDiagnostic(name, args, result.result.error);
9469
9190
  const retryKey = `${name}:${JSON.stringify(args)}`;
9470
9191
  const used = nativeToolErrorRetries.get(retryKey) ?? 0;
9471
9192
  if (used <= 0) {
9472
9193
  nativeToolErrorRetries.set(retryKey, 1);
9473
- output = `[RETRYABLE_TOOL_ERROR] ${output}
9474
- Retry this ${name} call once with corrected input. Do not narrate before retrying.`;
9194
+ output = `[RETRYABLE_TOOL_ERROR] ${diag}
9195
+ Retry this ${name} call ONCE with corrected input that matches the tool's schema. Do not narrate before retrying.`;
9475
9196
  } else {
9476
- output = `[TOOL_ERROR_FINAL] ${output}
9197
+ output = `[TOOL_ERROR_FINAL] ${diag}
9477
9198
  Repair retry already used for this exact ${name} input in this turn. Stop retrying this call and explain the blocker.`;
9478
9199
  }
9479
9200
  } else {
@@ -10001,11 +9722,23 @@ User context: ${delResult.userContext}` : suggestion.rest;
10001
9722
  }
10002
9723
  return { delegated: false, responded: true, decisionReason: "suggestion-cancelled", ...telemetry ?? {} };
10003
9724
  }
9725
+ var _noBriefNudged = /* @__PURE__ */ new Set();
10004
9726
  async function handleCesarBrain(input, dispatch, ctx, images) {
10005
9727
  const abort = new AbortController();
10006
9728
  const _turnStart = Date.now();
10007
9729
  const _turnId = createCesarTurnId();
10008
9730
  const _turnCwd = resolveWorkingDir();
9731
+ try {
9732
+ const _sid = String(ctx.chatSession?.id ?? "");
9733
+ if (_sid && !_noBriefNudged.has(_sid)) {
9734
+ if (_noBriefNudged.size > 5e3) _noBriefNudged.clear();
9735
+ _noBriefNudged.add(_sid);
9736
+ if (!hasProjectBrief(_turnCwd)) {
9737
+ dispatch({ type: "warning", message: "No project brief found in this repo. Create AGON.md or .agon/project.md so Cesar has project context from turn 1." });
9738
+ }
9739
+ }
9740
+ } catch {
9741
+ }
10009
9742
  const _toolsUsed = [];
10010
9743
  const _toolUseKeys = /* @__PURE__ */ new Set();
10011
9744
  let _toolEventCount = 0;
@@ -10113,6 +9846,7 @@ async function handleCesarBrain(input, dispatch, ctx, images) {
10113
9846
  console.warn("[cesar:brain] force-clearing stuck busy flag");
10114
9847
  ctx.cesar.busy = false;
10115
9848
  ctx.cesar.queue = null;
9849
+ ctx.cesar.abortSignal = null;
10116
9850
  } else {
10117
9851
  if (_isFollowUp) {
10118
9852
  const elapsed = Math.round((Date.now() - busySince) / 1e3);
@@ -10126,7 +9860,8 @@ async function handleCesarBrain(input, dispatch, ctx, images) {
10126
9860
  } else {
10127
9861
  ctx.cesar.queue = { input, dispatch, images };
10128
9862
  }
10129
- dispatch({ type: "info", message: "Queued \u2014 will send when Cesar finishes." });
9863
+ const _interrupting = ctx.cesar.abortSignal?.aborted === true;
9864
+ dispatch({ type: "info", message: _interrupting ? "Interrupting \u2014 your message is up next\u2026" : "Queued \u2014 will send when Cesar finishes." });
10130
9865
  return { delegated: false, responded: true };
10131
9866
  }
10132
9867
  }
@@ -10172,6 +9907,7 @@ async function handleCesarBrain(input, dispatch, ctx, images) {
10172
9907
  }
10173
9908
  const color = ENGINE_COLORS[cesarEngineId] ?? 124;
10174
9909
  ctx.setActiveAbort(abort);
9910
+ ctx.cesar.abortSignal = abort.signal;
10175
9911
  ctx.cesar.lastDispatch = dispatch;
10176
9912
  dispatch({ type: "confidence-update", value: null });
10177
9913
  dispatch({ type: "spinner-start", message: "Cesar thinking\u2026", color });
@@ -10870,6 +10606,13 @@ ${enrichedInput}`;
10870
10606
  ctx.cesar.reportedConfidence = value;
10871
10607
  ctx.cesar.reportedConfidenceReasoning = reasoning || void 0;
10872
10608
  ctx.cesar.confidenceSatisfied = true;
10609
+ recordCesarConfidence({
10610
+ sessionId: String(ctx.chatSession?.id ?? "unknown-session"),
10611
+ turnId: ctx.cesar.turnId ?? _turnId,
10612
+ engineId: cesarEngineId,
10613
+ value,
10614
+ reasoning: reasoning || void 0
10615
+ });
10873
10616
  parsedConfidence = value;
10874
10617
  dispatch({ type: "info", message: confidenceBadge(value) + ` Cesar (via MCP)` });
10875
10618
  dispatch({ type: "confidence-update", value });
@@ -10892,7 +10635,7 @@ ${enrichedInput}`;
10892
10635
  });
10893
10636
  continue;
10894
10637
  }
10895
- const { handleProposePlan } = await import("./plan-mode-OSU42TOI.js");
10638
+ const { handleProposePlan } = await import("./plan-mode-4XRC2ZC7.js");
10896
10639
  const planDispatch = ctx.cesar.planDispatch ?? dispatch;
10897
10640
  if (planDispatch) {
10898
10641
  try {
@@ -10905,7 +10648,7 @@ ${enrichedInput}`;
10905
10648
  }
10906
10649
  } else if (signal.tool === "ExitPlanMode") {
10907
10650
  recordToolUse("ExitPlanMode", "mcp", JSON.stringify(signal.args ?? {}), "done");
10908
- const { handleExitPlanMode } = await import("./plan-mode-OSU42TOI.js");
10651
+ const { handleExitPlanMode } = await import("./plan-mode-4XRC2ZC7.js");
10909
10652
  const planDispatch = ctx.cesar.planDispatch ?? dispatch;
10910
10653
  try {
10911
10654
  const exitResult = handleExitPlanMode(String(signal.args?.reason ?? ""), planDispatch, ctx);
@@ -11121,7 +10864,7 @@ ${enrichedInput}`;
11121
10864
  output: "A Cesar plan is already active; nested plans are blocked. Resume or cancel the current plan before proposing another."
11122
10865
  });
11123
10866
  } else {
11124
- const { handleProposePlan } = await import("./plan-mode-OSU42TOI.js");
10867
+ const { handleProposePlan } = await import("./plan-mode-4XRC2ZC7.js");
11125
10868
  const planDispatch = ctx.cesar.planDispatch ?? dispatch;
11126
10869
  const plan = await handleProposePlan(ppArgs, planDispatch, ctx);
11127
10870
  if (ctx.setActivePlan) ctx.setActivePlan(plan);
@@ -11145,7 +10888,7 @@ ${enrichedInput}`;
11145
10888
  const epArgs = ctx.cesar._exitPlanModeArgs;
11146
10889
  delete ctx.cesar._exitPlanModeArgs;
11147
10890
  try {
11148
- const { handleExitPlanMode } = await import("./plan-mode-OSU42TOI.js");
10891
+ const { handleExitPlanMode } = await import("./plan-mode-4XRC2ZC7.js");
11149
10892
  const planDispatch = ctx.cesar.planDispatch ?? dispatch;
11150
10893
  const exitResult = handleExitPlanMode(String(epArgs?.reason ?? ""), planDispatch, ctx);
11151
10894
  dispatch({ type: "tool-call", engineId: cesarEngineId, tool: "ExitPlanMode", input: JSON.stringify(epArgs ?? {}), status: "done", output: exitResult });
@@ -11737,20 +11480,12 @@ ${cleanFinalAnswer}` : cleanFinalAnswer;
11737
11480
  const asksConfirmation = !_isChatTurn && !ranToolLoop && /\?\s*$/.test(lastLine) && /\b(want|shall|should|ready|proceed|go ahead|dispatch|confirm|continue|implement)\b/i.test(lastLine);
11738
11481
  if (isForkQuestion) {
11739
11482
  const _forkColors = ["#4ade80", "#22d3ee", "#fbbf24", "#a78bfa", "#f97316", "#ef4444"];
11740
- const _allNumeric = _forkOptions.every((o) => /^[0-9]$/.test(o.key));
11741
- let _ownKey = _allNumeric ? String(_forkOptions.length + 1) : String.fromCharCode(97 + _forkOptions.length);
11742
- if (_seenForkKeys.has(_ownKey)) _ownKey = "o";
11743
- const _choices = [
11744
- ..._forkOptions.map((o, i) => ({ key: o.key, label: o.label, color: _forkColors[i % _forkColors.length] })),
11745
- { key: _ownKey, label: "\u270E my own idea (type it)", color: "#9ca3af" }
11746
- ];
11483
+ const _choices = _forkOptions.map((o, i) => ({ key: o.key, label: o.label, color: _forkColors[i % _forkColors.length] }));
11747
11484
  const picked = String(await new Promise((resolve4) => {
11748
- dispatch({ type: "question", prompt: `${cesarEngineId} \u2014 pick one, or ${_ownKey.toUpperCase()} to type your own (Esc to decide later):`, choices: _choices, resolve: resolve4 });
11485
+ dispatch({ type: "question", prompt: `${cesarEngineId} \u2014 pick one (Esc to decide later):`, choices: _choices, resolve: resolve4 });
11749
11486
  })).toLowerCase();
11750
11487
  const chosen = _forkOptions.find((o) => o.key === picked);
11751
- if (picked === _ownKey) {
11752
- dispatch({ type: "info", message: "Type your idea below and press Enter \u2014 Cesar has the options in context." });
11753
- } else if (chosen && session.alive && !abort.signal.aborted) {
11488
+ if (chosen && session.alive && !abort.signal.aborted) {
11754
11489
  dispatch({ type: "spinner-start", message: `${cesarEngineId} continuing\u2026`, color });
11755
11490
  let followUp = "";
11756
11491
  const gen = session.send({ message: `Go with option ${chosen.key.toUpperCase()}: ${chosen.full}. Proceed and finish it.`, signal: abort.signal });
@@ -11766,13 +11501,10 @@ ${cleanFinalAnswer}` : cleanFinalAnswer;
11766
11501
  const answer = await new Promise((resolve4) => {
11767
11502
  dispatch({ type: "question", prompt: `${cesarEngineId}: ${lastLine.length > 80 ? lastLine.slice(0, 80) + "\u2026" : lastLine}`, choices: [
11768
11503
  { key: "y", label: "Yes", color: "#4ade80" },
11769
- { key: "n", label: "No", color: "#ef4444" },
11770
- { key: "3", label: "\u270E tell Cesar what to do (type it)", color: "#9ca3af" }
11504
+ { key: "n", label: "No", color: "#ef4444" }
11771
11505
  ], resolve: resolve4 });
11772
11506
  });
11773
- if (answer === "3") {
11774
- dispatch({ type: "info", message: "Type your instruction below and press Enter \u2014 Cesar has the question in context." });
11775
- } else if (answer === "y" && session.alive && !abort.signal.aborted) {
11507
+ if (answer === "y" && session.alive && !abort.signal.aborted) {
11776
11508
  dispatch({ type: "spinner-start", message: `${cesarEngineId} continuing\u2026`, color });
11777
11509
  let followUp = "";
11778
11510
  const gen = session.send({ message: "yes", signal: abort.signal });
@@ -11823,20 +11555,25 @@ ${cleanFinalAnswer}` : cleanFinalAnswer;
11823
11555
  }
11824
11556
  });
11825
11557
  }
11826
- ctx.cesar.busy = false;
11827
- ctx.cesar.busySince = null;
11828
- if (ctx.cesar.turnId === _turnId) ctx.cesar.turnId = void 0;
11558
+ const _ownsTurn = ctx.cesar.turnId === _turnId;
11559
+ const _wasInterrupted = _ownsTurn && ctx.cesar.abortSignal?.aborted === true;
11829
11560
  dispatch({ type: "spinner-stop" });
11830
- ctx.setActiveAbort(null);
11831
- const queued = ctx.cesar.queue;
11832
- if (queued) {
11833
- ctx.cesar.queue = null;
11834
- setTimeout(() => {
11835
- handleCesarBrain(queued.input, queued.dispatch, ctx, queued.images).catch((err) => {
11836
- console.error(`[cesar:queue] drain failed: ${err.message ?? err}`);
11837
- ctx.cesar.busy = false;
11838
- });
11839
- }, 100);
11561
+ if (_ownsTurn) {
11562
+ ctx.cesar.busy = false;
11563
+ ctx.cesar.busySince = null;
11564
+ ctx.cesar.abortSignal = null;
11565
+ ctx.cesar.turnId = void 0;
11566
+ ctx.setActiveAbort(null);
11567
+ const queued = ctx.cesar.queue;
11568
+ if (queued) {
11569
+ ctx.cesar.queue = null;
11570
+ setTimeout(() => {
11571
+ handleCesarBrain(queued.input, queued.dispatch, ctx, queued.images).catch((err) => {
11572
+ console.error(`[cesar:queue] drain failed: ${err.message ?? err}`);
11573
+ ctx.cesar.busy = false;
11574
+ });
11575
+ }, _wasInterrupted ? 0 : 100);
11576
+ }
11840
11577
  }
11841
11578
  }
11842
11579
  }
@@ -11869,23 +11606,6 @@ export {
11869
11606
  runGoalController,
11870
11607
  runSupervisor,
11871
11608
  runConquer,
11872
- icons,
11873
- ENGINE_COLORS,
11874
- bold,
11875
- dim,
11876
- green,
11877
- red,
11878
- yellow,
11879
- cyan,
11880
- header,
11881
- success,
11882
- fail,
11883
- warn,
11884
- info,
11885
- table,
11886
- shortToolPath,
11887
- isCesarTelemetryLine,
11888
- formatConfidenceToolLabel,
11889
11609
  filterDefaultOrchestrationEngines,
11890
11610
  readCesarToolReliability,
11891
11611
  summarizeAllCesarToolReliability,
@@ -11895,9 +11615,6 @@ export {
11895
11615
  deriveRoutingHints,
11896
11616
  buildRoutingContext,
11897
11617
  shouldUseAgentTeam,
11898
- parseMarkdownBlocks,
11899
- truncateCodeLine,
11900
- cleanEngineOutput,
11901
11618
  codeBlockBuffer,
11902
11619
  todosFromPlanSteps,
11903
11620
  getSessionAllowList,
@@ -11915,4 +11632,4 @@ export {
11915
11632
  ensureCesarSession,
11916
11633
  handleCesarBrain
11917
11634
  };
11918
- //# sourceMappingURL=chunk-XOJPAFCJ.js.map
11635
+ //# sourceMappingURL=chunk-FCCH7IPJ.js.map