@wrongstack/core 0.265.1 → 0.268.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{agent-bridge-DrkBxszZ.d.ts → agent-bridge-UhojbpWx.d.ts} +1 -1
- package/dist/{agent-subagent-runner-DM2pP-B6.d.ts → agent-subagent-runner-Bvtf1o9K.d.ts} +25 -7
- package/dist/{brain-BXd_61kQ.d.ts → brain-69wzMKp1.d.ts} +73 -1
- package/dist/{compactor-B8pOf45Y.d.ts → compactor-CBQAJoDc.d.ts} +19 -1
- package/dist/{config-BMCj_XDs.d.ts → config-VKfOZ-6X.d.ts} +122 -3
- package/dist/{context-MRk5PhNv.d.ts → context-C0U8B9NF.d.ts} +88 -1
- package/dist/coordination/index.d.ts +57 -161
- package/dist/coordination/index.js +471 -177
- package/dist/coordination/index.js.map +1 -1
- package/dist/defaults/index.d.ts +26 -25
- package/dist/defaults/index.js +1818 -844
- package/dist/defaults/index.js.map +1 -1
- package/dist/execution/index.d.ts +72 -16
- package/dist/execution/index.js +1270 -265
- package/dist/execution/index.js.map +1 -1
- package/dist/execution/prompt-enhancer.d.ts +1 -1
- package/dist/extension/index.d.ts +7 -6
- package/dist/global-mailbox-KByEFFBa.d.ts +663 -0
- package/dist/{goal-preamble-DvHDSKSe.d.ts → goal-preamble-CrYjmdw4.d.ts} +28 -11
- package/dist/{goal-store-DtLMySNb.d.ts → goal-store-Y_zdLZ3q.d.ts} +1 -1
- package/dist/hq/index.d.ts +195 -0
- package/dist/hq/index.js +1884 -0
- package/dist/hq/index.js.map +1 -0
- package/dist/index-BfaS-f_m.d.ts +82 -0
- package/dist/{index-B-ch8K9C.d.ts → index-CtQnmkaS.d.ts} +8 -8
- package/dist/{index-CEDeNodM.d.ts → index-gCv830d7.d.ts} +5 -5
- package/dist/index.d.ts +124 -47
- package/dist/index.js +5600 -2662
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/index.d.ts +6 -6
- package/dist/infrastructure/index.js +117 -19
- package/dist/infrastructure/index.js.map +1 -1
- package/dist/kernel/index.d.ts +10 -9
- package/dist/kernel/index.js.map +1 -1
- package/dist/{pipeline-DPDxH_7m.d.ts → mailbox-types-Ct2hJq0P.d.ts} +1 -244
- package/dist/{mcp-servers-2x4w6Jn9.d.ts → mcp-servers-HT3Fi7Bl.d.ts} +10 -4
- package/dist/models/index.d.ts +5 -5
- package/dist/models/index.js +33 -3
- package/dist/models/index.js.map +1 -1
- package/dist/{models-registry-DmJlKuNp.d.ts → models-registry-Bvcl3Vaa.d.ts} +1 -1
- package/dist/{multi-agent-coordinator-DyCkCZnU.d.ts → multi-agent-coordinator-BACjsmkC.d.ts} +1 -1
- package/dist/{null-fleet-bus-CG9QY2aP.d.ts → null-fleet-bus-DA7fvhUg.d.ts} +14 -9
- package/dist/observability/index.d.ts +2 -2
- package/dist/{parallel-eternal-engine-Jw9uhEoT.d.ts → parallel-eternal-engine-Ci71gYu_.d.ts} +11 -15
- package/dist/{path-resolver-Dy2ej-gE.d.ts → path-resolver-O1IJnmKE.d.ts} +4 -3
- package/dist/{permission-B9SB45lp.d.ts → permission-Bd-57Lbl.d.ts} +1 -1
- package/dist/{permission-policy-CkjSXabK.d.ts → permission-policy-uNXC6Kge.d.ts} +2 -3
- package/dist/pipeline-BDNvENyV.d.ts +245 -0
- package/dist/{plan-templates-CzD9GnAU.d.ts → plan-templates-EMsalEtN.d.ts} +5 -5
- package/dist/{llm-selector-C0tfTCUe.d.ts → provider-model-resolve-CEb9x886.d.ts} +40 -3
- package/dist/{provider-runner-DMa70ODu.d.ts → provider-runner-DWJbpo70.d.ts} +3 -3
- package/dist/{retry-policy-CN0khdlj.d.ts → retry-policy-C3s_lvdK.d.ts} +1 -1
- package/dist/sdd/index.d.ts +9 -8
- package/dist/sdd/index.js +44 -14
- package/dist/sdd/index.js.map +1 -1
- package/dist/{secret-vault-B2yw84VT.d.ts → secret-vault-Cgduf5xL.d.ts} +2 -2
- package/dist/security/index.d.ts +5 -67
- package/dist/security/index.js +129 -99
- package/dist/security/index.js.map +1 -1
- package/dist/{selector-CzHh_igB.d.ts → selector-47LBnBVk.d.ts} +1 -1
- package/dist/{session-event-bridge-BUI6Jf-4.d.ts → session-event-bridge-Cw7oqmW2.d.ts} +1 -1
- package/dist/{session-reader-CMgdMSRP.d.ts → session-reader-DD4v2Obw.d.ts} +1 -1
- package/dist/storage/index.d.ts +14 -12
- package/dist/storage/index.js +144 -120
- package/dist/storage/index.js.map +1 -1
- package/dist/tools/index.d.ts +4 -2
- package/dist/tools/index.js +166 -31
- package/dist/tools/index.js.map +1 -1
- package/dist/types/index.d.ts +20 -19
- package/dist/types/index.js +1358 -476
- package/dist/types/index.js.map +1 -1
- package/dist/utils/index.d.ts +472 -405
- package/dist/utils/index.js +2321 -1193
- package/dist/utils/index.js.map +1 -1
- package/package.json +5 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/term.ts","../../src/utils/color.ts","../../src/infrastructure/logger.ts","../../src/infrastructure/path-resolver.ts","../../src/infrastructure/token-counter.ts","../../src/infrastructure/mcp-servers.ts","../../src/utils/expect-defined.ts","../../src/utils/message-invariants.ts","../../src/utils/token-estimate.ts","../../src/infrastructure/context-manager.ts"],"names":["path","fs2"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * TTY detection helpers — the single source of truth for \"is this process\n * running against a real terminal?\". Replaces ad-hoc `process.stdin.isTTY`\n * / `process.stdout.isTTY` checks scattered across the codebase so that:\n *\n * 1. test code can mock a single module instead of stubbing `isTTY` on\n * every ReadStream/WriteStream the test happens to touch;\n * 2. a future TTY-detection source (an env var override, a Windows\n * ConPTY workaround, …) lands in one place;\n * 3. `isInteractive()` encodes the rule the project already used inline\n * (\"both streams are TTYs AND we're not running under CI\") in one\n * testable helper instead of the same 3-condition check in two\n * different files.\n *\n * Scope: detection only. Raw-mode control (`setRawMode`), resize\n * subscriptions, and write-injection belong to a future, larger TTY\n * abstraction; this module is the smallest pull that gives us a\n * testable seam and dedups 20+ call sites.\n */\n\nconst hasStdout = (): boolean => typeof process !== 'undefined' && !!process.stdout;\nconst hasStdin = (): boolean => typeof process !== 'undefined' && !!process.stdin;\n\n/** True when `process.stdout` is attached to a terminal (not a pipe/file). */\nexport function isStdoutTTY(): boolean {\n return hasStdout() && Boolean(process.stdout.isTTY);\n}\n\n/** True when `process.stdin` is attached to a terminal (not a pipe/file). */\nexport function isStdinTTY(): boolean {\n return hasStdin() && Boolean(process.stdin.isTTY);\n}\n\n/**\n * True when the current process is an interactive session: both stdin and\n * stdout are TTYs. Callers that also need a \"not a single-shot invocation\"\n * or \"not under CI\" check should layer that on top — keeping this helper\n * minimal preserves the original inline checks it replaces.\n */\nexport function isInteractive(): boolean {\n return isStdinTTY() && isStdoutTTY();\n}\n\n/** Current terminal size in characters, with a 24×80 fallback for non-TTYs. */\nexport function getTermSize(): { rows: number; cols: number } {\n if (!hasStdout()) return { rows: 24, cols: 80 };\n return {\n rows: process.stdout.rows ?? 24,\n cols: process.stdout.columns ?? 80,\n };\n}\n\n/**\n * Subscribe to terminal resize events. `cb` is called with the new size each\n * time the underlying stream emits `resize`. Returns a cleanup function the\n * caller MUST call on dispose to remove the listener — leaving a stale\n * `resize` listener on a disposed component leaks the closure (and the\n * component itself, transitively) until the process exits.\n *\n * The stream argument defaults to `process.stdout`. Pass an explicit\n * `NodeJS.WriteStream` when the caller already owns one (e.g. a status line\n * that targets an injected `out` for testability). For non-TTY streams no\n * listener is registered and the returned cleanup is a no-op.\n */\nexport function onResize(\n cb: (size: { rows: number; cols: number }) => void,\n stream: NodeJS.WriteStream = process.stdout,\n): () => void {\n if (!stream || typeof stream.on !== 'function') return () => {};\n const handler = (): void => {\n cb({\n rows: stream.rows ?? 24,\n cols: stream.columns ?? 80,\n });\n };\n stream.on('resize', handler);\n return () => {\n stream.off('resize', handler);\n };\n}\n\n/**\n * Toggle raw mode on a TTY stdin stream. Returns `true` when the toggle was\n * applied, `false` when the stream is null, not a TTY, or doesn't expose\n * `setRawMode` (pipes, file descriptors, Windows ConPTY edge cases). Callers\n * that need to restore the previous mode should snapshot `input.isRaw`\n * BEFORE the call and pass the value to a second call to flip back.\n *\n * Use this helper to drop the now-redundant\n * `if (input.isTTY) input.setRawMode(...)` ceremony at every call site.\n */\nexport function setRawMode(input: NodeJS.ReadStream, mode: boolean): boolean {\n if (!input || input.isTTY !== true) return false;\n if (typeof input.setRawMode !== 'function') return false;\n input.setRawMode(mode);\n return true;\n}\n\n/**\n * Bracket installed by the interactive input reader while a `readline`\n * prompt is on screen. Out-of-band terminal writes — logger WARN/INFO\n * lines, async activity from the Telegram bridge, etc. — go to the same\n * physical terminal as the half-typed prompt but readline has no idea they\n * happened, so it never repaints. The result is the classic corruption the\n * user sees: every async line strands the in-progress draft as a fresh\n * scrollback row (sometimes with its cursor underline).\n *\n * The guard closes that gap. `suspend()` wipes the draft row so the message\n * prints clean; `resume()` repaints the prompt + draft (cursor preserved).\n * When no prompt is active the guard is `null` and writes pass straight\n * through — so agent-turn output (spinner, renderer) is untouched.\n */\nexport interface OutputLineGuard {\n /** Clear the current input row right before an out-of-band write. */\n suspend(): void;\n /** Repaint the prompt + in-progress draft right after the write. */\n resume(): void;\n}\n\nlet activeOutputGuard: OutputLineGuard | null = null;\n\n/**\n * Register (or clear, with `null`) the guard that brackets out-of-band\n * writes. Installed by {@link writeOut}/{@link writeErr} consumers — in\n * practice the CLI's readline input reader — only while a prompt is live.\n * Idempotent; the most recent caller wins.\n */\nexport function setOutputLineGuard(guard: OutputLineGuard | null): void {\n activeOutputGuard = guard;\n}\n\n/**\n * Stream-agnostic write primitive. Returns `false` when the stream is\n * missing or doesn't expose `write` so callers can degrade silently under\n * hostile host environments (closed pipe, mock injects `null`, test\n * replaces the stream with a stub).\n *\n * When an {@link OutputLineGuard} is installed (a readline prompt is on\n * screen) the write is bracketed by `suspend()`/`resume()` so the user's\n * half-typed input survives the interruption instead of being stranded in\n * scrollback. The guard's own redraw uses raw stream writes — never\n * `writeOut`/`writeErr` — so there is no re-entrancy here.\n *\n * **Not exported in the public API.** Exposed only inside `term.ts` for\n * `writeOut` / `writeErr` to share a single implementation. If a caller\n * needs to write to an arbitrary stream, they should call `writeOut` (or\n * `writeErr`) with an explicit `stream` argument — the named functions\n * are the public surface so the \"this is the standard error stream\"\n * intent stays visible at every call site.\n */\nfunction writeTo(\n s: string,\n stream: NodeJS.WriteStream | undefined,\n): boolean {\n if (!stream || typeof stream.write !== 'function') return false;\n const guard = activeOutputGuard;\n if (!guard) {\n stream.write(s);\n return true;\n }\n // A prompt is live — wipe the draft row, emit the message, repaint.\n guard.suspend();\n stream.write(s);\n guard.resume();\n return true;\n}\n\n/**\n * Write `s` to `stream` (defaults to `process.stdout`). Returns `false`\n * when the stream is missing or doesn't expose `write` so callers can\n * degrade silently under hostile host environments (closed pipe, mock\n * injects `null`, test replaces the stream with a stub).\n *\n * Why a helper:\n * 1. **Single seam for output capture in tests** — stub `writeOut` once\n * and assert on what the rest of the codebase intended to print,\n * without spying on `process.stdout.write` (which is brittle and\n * leaks across parallel test files).\n * 2. **Stream swap without grep** — routing the CLI's output to a\n * logger or `out.log` becomes a one-line change at process boot.\n * 3. **Defensive default** — closes the \"what if `process.stdout` is\n * `null`\" gap that currently exists at ~50 call sites that just\n * call `process.stdout.write(s)` and crash on certain Windows\n * redirect invocations.\n *\n * Call-site migration is staged: this commit introduces the helper, a\n * follow-up commit replaces the 50+ `process.stdout.write(...)` sites\n * with `writeOut(...)`. Until that migration lands, both forms coexist\n * and `writeOut` is the preferred form for new code.\n */\nexport function writeOut(\n s: string,\n stream: NodeJS.WriteStream = process.stdout,\n): boolean {\n return writeTo(s, stream);\n}\n\n/**\n * Symmetric partner of `writeOut` for the standard error stream. Same shape,\n * same defensive contract, same single-seam-for-tests story — just defaults to\n * `process.stderr` instead of `process.stdout`.\n *\n * Use this in code paths that emit error/diagnostic/warning text. Keeping\n * these two helpers split (rather than a single `writeTo(s, stream)`) means\n * the call site reads as a clear intent signal: \"I am writing an error\" vs.\n * \"I am writing a result\" — which matters for callers that decide between\n * stdout/stderr routing (e.g. `--quiet` flags, log-level filtering,\n * structured-log rewriters that fork on stream).\n *\n * Stderr writes from the core logger (see `infrastructure/logger.ts`) and from\n * the TUI guard (see `tui/run-tui.ts`) used to call `process.stderr.write`\n * directly. Routing them through this helper lets tests stub the stream at\n * one boundary and lets future logging middleware (e.g. a JSON-line rewriter)\n * swap the destination for the entire process in one place.\n */\nexport function writeErr(\n s: string,\n stream: NodeJS.WriteStream = process.stderr,\n): boolean {\n return writeTo(s, stream);\n}\n","import { isStdoutTTY } from './term.js';\n\nconst isColorTty = (): boolean => {\n if (envFlag(process.env.NO_COLOR)) return false;\n if (envFlag(process.env.FORCE_COLOR)) return true;\n return isStdoutTTY();\n};\n\nfunction envFlag(value: string | undefined): boolean {\n if (value === undefined) return false;\n if (value.trim() === '') return false;\n return !/^(0|false|no|off)$/i.test(value.trim());\n}\n\nconst COLOR = isColorTty();\n\nconst wrap =\n (open: string, close: string) =>\n (s: string): string =>\n COLOR ? `\\x1b[${open}m${s}\\x1b[${close}m` : s;\n\nexport const color = {\n reset: wrap('0', '0'),\n bold: wrap('1', '22'),\n dim: wrap('2', '22'),\n italic: wrap('3', '23'),\n underline: wrap('4', '24'),\n red: wrap('31', '39'),\n green: wrap('32', '39'),\n yellow: wrap('33', '39'),\n blue: wrap('34', '39'),\n magenta: wrap('35', '39'),\n cyan: wrap('36', '39'),\n gray: wrap('90', '39'),\n amber: wrap('38;5;214', '39'),\n pink: wrap('38;5;205', '39'),\n bgRed: wrap('41', '49'),\n bgGreen: wrap('42', '49'),\n};\n\nexport function stripAnsi(s: string): string {\n return s.replace(\n // biome-ignore lint/suspicious/noControlCharactersInRegex: ANSI escape regex\n /\\x1b\\[[0-9;]*[A-Za-z]/g,\n '',\n );\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport type { LogLevel, Logger } from '../types/logger.js';\nimport { color } from '../utils/color.js';\nimport { writeErr } from '../utils/term.js';\n\nconst LEVEL_RANK: Record<LogLevel, number> = {\n error: 0,\n warn: 1,\n info: 2,\n debug: 3,\n trace: 4,\n};\n\nconst COLORS: Record<LogLevel, (s: string) => string> = {\n error: color.red,\n warn: color.yellow,\n info: color.cyan,\n debug: color.gray,\n trace: color.dim,\n};\n\nconst LOG_LEVELS = new Set<LogLevel>(['error', 'warn', 'info', 'debug', 'trace']);\nconst LOG_FORMATS = new Set<string>(['pretty', 'json']);\n\nexport type LogFormat = 'pretty' | 'json';\n\nexport interface DefaultLoggerOptions {\n level?: LogLevel | undefined;\n file?: string | undefined;\n /**\n * @deprecated Use `format: 'json'` instead. Kept for backward compat\n * with existing callers but has no effect on output — the `format`\n * option controls whether stderr receives pretty-printed or JSON lines.\n */\n pretty?: boolean | undefined;\n /** Output format for stderr. `pretty` (colored, human-readable) or `json` (machine-parseable). Defaults to `WRONGSTACK_LOG_FORMAT` env var, falling back to `pretty`. */\n format?: LogFormat | undefined;\n bindings?: Record<string, unknown>;\n /**\n * When false, suppress stderr output entirely — only write to the log\n * file (if configured). Use this in TUI mode so plugin/library log\n * messages don't interleave with Ink's terminal rendering.\n * Default: true (stderr output is enabled).\n */\n stderr?: boolean | undefined;\n /**\n * Rotate the log file once it exceeds this many bytes: the current file is\n * renamed to `<file>.1` (replacing any previous one) and a fresh file\n * starts. Bounds total disk to ~2× this value. Default 10 MB.\n */\n maxFileBytes?: number | undefined;\n}\n\nexport class DefaultLogger implements Logger {\n /** How many file writes between rotation size checks (statSync is not free). */\n private static readonly ROTATE_CHECK_EVERY = 100;\n\n level: LogLevel;\n private readonly file?: string | undefined;\n private readonly bindings: Record<string, unknown>;\n private readonly format: LogFormat;\n private readonly stderr: boolean;\n private readonly maxFileBytes: number;\n private writesSinceRotateCheck = 0;\n\n constructor(opts: DefaultLoggerOptions = {}) {\n this.level = opts.level ?? parseLogLevel(process.env.WRONGSTACK_LOG_LEVEL);\n this.file = opts.file;\n this.bindings = opts.bindings ?? {};\n this.format = opts.format ?? parseLogFormat(process.env.WRONGSTACK_LOG_FORMAT);\n this.stderr = opts.stderr !== false; // default true\n this.maxFileBytes = opts.maxFileBytes ?? 10 * 1024 * 1024;\n if (this.file) {\n try {\n fs.mkdirSync(path.dirname(this.file), { recursive: true });\n } catch {\n // best-effort\n }\n }\n }\n\n error(msg: string, ctx?: unknown): void {\n this.log('error', msg, ctx);\n }\n warn(msg: string, ctx?: unknown): void {\n this.log('warn', msg, ctx);\n }\n info(msg: string, ctx?: unknown): void {\n this.log('info', msg, ctx);\n }\n debug(msg: string, ctx?: unknown): void {\n this.log('debug', msg, ctx);\n }\n trace(msg: string, ctx?: unknown): void {\n this.log('trace', msg, ctx);\n }\n\n child(bindings: Record<string, unknown>): Logger {\n return new DefaultLogger({\n level: this.level,\n file: this.file,\n format: this.format,\n stderr: this.stderr,\n maxFileBytes: this.maxFileBytes,\n bindings: { ...this.bindings, ...bindings },\n });\n }\n\n /**\n * Size-based rotation: when the file outgrows `maxFileBytes`, rename it to\n * `<file>.1` (dropping the previous `.1`) so the live file restarts empty.\n * Checked on the first write and every ROTATE_CHECK_EVERY writes after.\n * Best-effort: a rename can fail on Windows while another process holds\n * the file — the next check retries. Multiple processes appending to the\n * same log all run this check; whoever crosses the threshold first wins.\n */\n private maybeRotate(file: string): void {\n if (this.writesSinceRotateCheck++ % DefaultLogger.ROTATE_CHECK_EVERY !== 0) return;\n try {\n const st = fs.statSync(file);\n if (st.size < this.maxFileBytes) return;\n fs.rmSync(`${file}.1`, { force: true });\n fs.renameSync(file, `${file}.1`);\n } catch {\n // file missing, locked, or raced by another process — ignore\n }\n }\n\n private log(level: LogLevel, msg: string, ctx?: unknown): void {\n const r = LEVEL_RANK[level];\n const allowed = LEVEL_RANK[this.level];\n if (r > allowed) return;\n const ts = new Date().toISOString();\n const entry: Record<string, unknown> = { ts, level, msg, ...this.bindings };\n if (ctx !== undefined) {\n entry.ctx = ctx instanceof Error ? { message: ctx.message, stack: ctx.stack } : ctx;\n }\n // Disk: JSON line\n if (this.file) {\n try {\n this.maybeRotate(this.file);\n fs.appendFileSync(this.file, `${JSON.stringify(entry)}\\n`);\n } catch {\n // ignore\n }\n }\n // Stderr: pretty or json. Suppressed when this.stderr is false (TUI mode)\n // so plugin/library log messages don't interleave with Ink's rendering.\n if (!this.stderr) return;\n if (this.format === 'json') {\n writeErr(`${JSON.stringify(entry)}\\n`);\n } else {\n const head = `${color.dim(ts)} ${COLORS[level](level.toUpperCase().padEnd(5))} ${msg}`;\n if (ctx !== undefined) {\n writeErr(`${head} ${formatCtx(ctx)}\\n`);\n } else {\n writeErr(`${head}\\n`);\n }\n }\n }\n}\n\nfunction parseLogLevel(raw: string | undefined): LogLevel {\n return raw && LOG_LEVELS.has(raw as LogLevel) ? (raw as LogLevel) : 'info';\n}\n\nfunction parseLogFormat(raw: string | undefined): LogFormat {\n return raw && LOG_FORMATS.has(raw) ? (raw as LogFormat) : 'pretty';\n}\n\nfunction formatCtx(ctx: unknown): string {\n if (ctx instanceof Error) return color.dim(ctx.message);\n if (typeof ctx === 'string') return color.dim(ctx);\n try {\n return color.dim(JSON.stringify(ctx));\n } catch {\n return color.dim(String(ctx));\n }\n}\n\n/**\n * A logger that silently discards all messages. Used during boot before\n * the real logger is configured, and in test contexts where logging\n * would be noise.\n */\nexport const noOpLogger: Logger = {\n // 'error' is the quietest level the Logger contract offers; the methods\n // discard everything regardless, this only matters to level checks.\n level: 'error',\n error: () => {},\n warn: () => {},\n info: () => {},\n debug: () => {},\n trace: () => {},\n child: () => noOpLogger,\n};\n","import * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport type { PathResolver } from '../types/path-resolver.js';\n\nconst PROJECT_MARKERS = [\n '.git',\n 'package.json',\n 'pnpm-workspace.yaml',\n 'go.mod',\n 'Cargo.toml',\n 'pyproject.toml',\n // Use AGENTS.md, not the bare .wrongstack directory. A bare .wrongstack/\n // directory can be the global config directory (~/.wrongstack), which is\n // NOT a project marker. Only .wrongstack/AGENTS.md signals a real\n // WrongStack project.\n '.wrongstack/AGENTS.md',\n];\n\nexport class DefaultPathResolver implements PathResolver {\n readonly projectRoot: string;\n readonly cwd: string;\n\n constructor(cwd: string = process.cwd()) {\n this.cwd = path.resolve(cwd);\n this.projectRoot = this.detectProjectRoot(this.cwd);\n }\n\n detectProjectRoot(start: string): string {\n let dir = path.resolve(start);\n const root = path.parse(dir).root;\n const home = path.resolve(os.homedir());\n const startPath = path.resolve(start);\n while (dir !== root) {\n // Don't walk past the user home directory. Home often has stray\n // markers (.git for dotfile tracking, package.json from global\n // tooling) that are unrelated to the actual working directory.\n // When cwd IS home we still check markers there — this guard\n // only fires during the upward walk from a subdirectory.\n if (dir === home && dir !== startPath) {\n break;\n }\n for (const marker of PROJECT_MARKERS) {\n try {\n fs.accessSync(path.join(dir, marker));\n return dir;\n } catch {\n // continue\n }\n }\n const parent = path.dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n return startPath;\n }\n\n resolve(input: string): string {\n const abs = path.isAbsolute(input) ? input : path.resolve(this.cwd, input);\n let real: string;\n try {\n real = fs.realpathSync(abs);\n } catch {\n // path doesn't exist yet; normalize without resolving symlinks\n real = path.normalize(abs);\n }\n return real;\n }\n\n isInsideRoot(absPath: string): boolean {\n const normalized = path.normalize(absPath);\n const root = path.normalize(this.projectRoot);\n if (normalized === root) return true;\n const rel = path.relative(root, normalized);\n return !rel.startsWith('..') && !path.isAbsolute(rel);\n }\n\n ensureInsideRoot(absPath: string): string {\n const resolved = this.resolve(absPath);\n if (!this.isInsideRoot(resolved)) {\n // Render the input as a project-relative-looking string when possible\n // so the error message can flow through telemetry / LLM transcripts\n // without leaking the absolute project root layout.\n const display = path.isAbsolute(absPath) ? path.basename(absPath) : absPath;\n const err = new Error(`Path \"${display}\" resolves outside the project root`);\n // Keep the full information available to programmatic callers; only\n // the user-facing `message` is sanitized.\n (err as Error & { fullPath?: string | undefined; projectRoot?: string | undefined }).fullPath = absPath;\n (err as Error & { fullPath?: string | undefined; projectRoot?: string | undefined }).projectRoot = this.projectRoot;\n throw err;\n }\n return resolved;\n }\n}\n","import type { EventBus } from '../kernel/events.js';\nimport type { ModelsRegistry, ResolvedModel } from '../types/models-registry.js';\nimport type { Usage } from '../types/provider.js';\nimport type { CacheStats, TokenCounter } from '../types/token-counter.js';\n\ninterface PriceEntry {\n input?: number | undefined;\n output?: number | undefined;\n cacheRead?: number | undefined;\n cacheWrite?: number | undefined;\n}\n\nconst PRICE_CACHE_MAX_SIZE = 100;\n\n/**\n * Token counter that derives pricing from the ModelsRegistry instead of a\n * hardcoded table. If a model is unknown to the registry (or the registry is\n * unavailable) the counter still tracks token totals but reports zero cost.\n */\nexport class DefaultTokenCounter implements TokenCounter {\n private input = 0;\n private output = 0;\n private cacheRead = 0;\n private cacheWrite = 0;\n private costInput = 0;\n private costOutput = 0;\n private readonly registry?: ModelsRegistry | undefined;\n private readonly providerId?: string | undefined;\n private readonly events?: EventBus | undefined;\n private priceCache = new Map<string, PriceEntry>();\n /** Most recently accounted request's tokens. Used for per-request context pressure. */\n private lastInput = 0;\n private lastCacheRead = 0;\n\n constructor(opts: { registry?: ModelsRegistry | undefined; providerId?: string | undefined; events?: EventBus | undefined } = {}) {\n this.registry = opts.registry;\n this.providerId = opts.providerId;\n this.events = opts.events;\n }\n\n account(usage: Usage, model?: string): void {\n this.input += usage.input;\n this.output += usage.output;\n this.cacheRead += usage.cacheRead ?? 0;\n this.cacheWrite += usage.cacheWrite ?? 0;\n // Snapshot per-request tokens for context pressure tracking.\n this.lastInput = usage.input;\n this.lastCacheRead = usage.cacheRead ?? 0;\n\n const price = model ? this.priceCache.get(model) : undefined;\n if (price) {\n this.applyPrice(usage, price);\n this.events?.emit('token.accounted', {\n usage: this.total(),\n cost: { input: this.costInput, output: this.costOutput, total: this.costInput + this.costOutput },\n });\n } else if (this.registry && this.providerId && model) {\n // Evict oldest entry when cache is full before async lookup.\n if (this.priceCache.size >= PRICE_CACHE_MAX_SIZE) {\n const keys = [...this.priceCache.keys()];\n this.priceCache.delete(keys[0] ?? '');\n }\n // Async lookup — populate cache, but don't block this call.\n void this.registry\n .getModel(this.providerId, model)\n .then((m) => {\n if (m) {\n const p = priceFromModel(m);\n this.priceCache.set(model, p);\n this.applyPrice(usage, p);\n this.events?.emit('token.accounted', {\n usage: this.total(),\n cost: { input: this.costInput, output: this.costOutput, total: this.costInput + this.costOutput },\n });\n }\n })\n .catch(() => {\n // Emit so observability tooling can detect unknown models.\n this.events?.emit('token.cost_estimate_unavailable', { model: model ?? '<unknown>' });\n return undefined;\n });\n }\n }\n\n /** Synchronous variant for code paths that have already resolved the model. */\n accountWithModel(usage: Usage, resolved: ResolvedModel): void {\n this.input += usage.input;\n this.output += usage.output;\n this.cacheRead += usage.cacheRead ?? 0;\n this.cacheWrite += usage.cacheWrite ?? 0;\n // Snapshot per-request tokens for context pressure tracking.\n this.lastInput = usage.input;\n this.lastCacheRead = usage.cacheRead ?? 0;\n const price = priceFromModel(resolved);\n if (this.priceCache.size >= PRICE_CACHE_MAX_SIZE) {\n const keys = [...this.priceCache.keys()];\n this.priceCache.delete(keys[0] ?? '');\n }\n this.priceCache.set(resolved.modelId, price);\n this.applyPrice(usage, price);\n this.events?.emit('token.accounted', {\n usage: this.total(),\n cost: { input: this.costInput, output: this.costOutput, total: this.costInput + this.costOutput },\n });\n }\n\n total(): Usage {\n return {\n input: this.input,\n output: this.output,\n cacheRead: this.cacheRead,\n cacheWrite: this.cacheWrite,\n };\n }\n\n currentRequestTokens(): { input: number; cacheRead: number } {\n return { input: this.lastInput, cacheRead: this.lastCacheRead };\n }\n\n estimateCost(): { input: number; output: number; total: number; currency: 'USD' } {\n return {\n input: round4(this.costInput),\n output: round4(this.costOutput),\n total: round4(this.costInput + this.costOutput),\n currency: 'USD',\n };\n }\n\n cacheStats(): CacheStats {\n // Hit ratio: cacheRead / (cacheRead + input). `input` from the provider\n // is the count of fresh-token reads, so this answers \"what fraction of\n // the prompt did we get for the cache price?\"\n const denom = this.cacheRead + this.input;\n return {\n readTokens: this.cacheRead,\n writeTokens: this.cacheWrite,\n hitRatio: denom === 0 ? 0 : this.cacheRead / denom,\n };\n }\n\n /** Invalidate cached prices so the next account() call fetches fresh data. */\n invalidateCache(): void {\n this.priceCache.clear();\n }\n\n reset(): void {\n this.input = 0;\n this.output = 0;\n this.cacheRead = 0;\n this.cacheWrite = 0;\n this.costInput = 0;\n this.costOutput = 0;\n }\n\n private applyPrice(usage: Usage, price: PriceEntry): void {\n if (price.input) this.costInput += (usage.input / 1_000_000) * price.input;\n if (price.output) this.costOutput += (usage.output / 1_000_000) * price.output;\n if (usage.cacheRead && price.cacheRead) {\n this.costInput += (usage.cacheRead / 1_000_000) * price.cacheRead;\n }\n if (usage.cacheWrite && price.cacheWrite) {\n this.costInput += (usage.cacheWrite / 1_000_000) * price.cacheWrite;\n }\n }\n}\n\nfunction priceFromModel(m: ResolvedModel): PriceEntry {\n return {\n input: m.cost?.input,\n output: m.cost?.output,\n cacheRead: m.cost?.cache_read,\n cacheWrite: m.cost?.cache_write,\n };\n}\n\nfunction round4(n: number): number {\n return Math.round(n * 10_000) / 10_000;\n}\n","import type { MCPServerConfig } from '../types/config.js';\n\n/**\n * Built-in MCP server presets available to all WrongStack users out of the box.\n * These servers must be explicitly enabled in config (disabled by default).\n *\n * To enable: set `mcpServers: { serverName: { enabled: true } }` in your config.\n *\n * Some servers require environment variables or additional config — see notes below.\n *\n * Transport types:\n * stdio — spawns a local npm package binary via child_process\n * sse — HTTP SSE endpoint (client POSTs requests)\n * streamable-http — session-based HTTP with NDJSON responses\n */\n\n/** Filesystem access: read, write, list, search, tree. Good for exploring projects. */\nexport const filesystemServer = (): MCPServerConfig => ({\n name: 'filesystem',\n description: 'Read, write, and navigate the local filesystem (read-heavy tools)',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-filesystem', '.'],\n permission: 'confirm',\n});\n\n/** GitHub API: issues, PRs, repos, search, file operations. Requires GITHUB_PERSONAL_ACCESS_TOKEN. */\nexport const githubServer = (): MCPServerConfig => ({\n name: 'github',\n description:\n 'GitHub API — issues, PRs, repos, search, file ops (requires GITHUB_PERSONAL_ACCESS_TOKEN)',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-github'],\n permission: 'confirm',\n});\n\n/**\n * Context7 — codebase-aware documentation and Q&A using context from your code.\n * Live documentation for any library, grounded in your actual versions.\n */\nexport const context7Server = (): MCPServerConfig => ({\n name: 'context7',\n description: 'Codebase-aware documentation and Q&A (context7.ai)',\n transport: 'streamable-http',\n url: 'https://mcp.context7.com/mcp',\n permission: 'confirm',\n});\n\n/**\n * Brave Search — web search via Brave Browser's API.\n * Requires BRAVE_SEARCH_API_KEY. Free tier: 2,000 queries/month.\n * Sign up at https://api.search.brave.com/\n */\nexport const braveSearchServer = (): MCPServerConfig => ({\n name: 'brave-search',\n description: 'Web search (Brave). Requires BRAVE_SEARCH_API_KEY — free tier 2k queries/month',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-brave-search'],\n permission: 'confirm',\n});\n\n/**\n * Block (Block, Inc.) — Postgres database access via SQL.\n * Useful for running queries against a connected database during development.\n */\nexport const blockServer = (): MCPServerConfig => ({\n name: 'block',\n description: 'Postgres database access via SQL (Block MCP server)',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-block'],\n permission: 'confirm',\n});\n\n/**\n * EverArt — AI image generation via various providers.\n * Requires EVERART_API_KEY.\n */\nexport const everArtServer = (): MCPServerConfig => ({\n name: 'everart',\n description: 'AI image generation (EverArt). Requires EVERART_API_KEY',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-everart'],\n permission: 'confirm',\n});\n\n/**\n * Slack — messaging, channels, search.\n * Requires SLACK_BOT_TOKEN and either SLACK_TEAM_ID or SLACK_USER_TOKEN.\n */\nexport const slackServer = (): MCPServerConfig => ({\n name: 'slack',\n description: 'Slack — messaging, channels, search. Requires SLACK_BOT_TOKEN + SLACK_TEAM_ID',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-slack'],\n permission: 'confirm',\n});\n\n/**\n * AWS knowledge base — EC2, S3, Lambda, IAM, CloudFormation, cost management.\n * Requires AWS access key + secret in environment.\n */\nexport const awsServer = (): MCPServerConfig => ({\n name: 'aws',\n description: 'AWS — EC2, S3, Lambda, IAM, CloudFormation, costs. Requires AWS credentials',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-aws'],\n permission: 'confirm',\n});\n\n/**\n * Google Maps — directions, distance matrix, geocoding, places.\n * Requires GOOGLE_MAPS_API_KEY.\n */\nexport const googleMapsServer = (): MCPServerConfig => ({\n name: 'google-maps',\n description: 'Google Maps — directions, geocoding, places. Requires GOOGLE_MAPS_API_KEY',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-google-maps'],\n permission: 'confirm',\n});\n\n/** Sentinel — security vulnerability scanning (sentinel-labs). */\nexport const sentinelServer = (): MCPServerConfig => ({\n name: 'sentinel',\n description: 'Security vulnerability scanning (Sentinel)',\n transport: 'streamable-http',\n url: 'https://mcp.sentinel.ai',\n permission: 'deny', // security tool — require explicit confirmation\n});\n\n/**\n * Z.AI Vision MCP — image understanding fallback for text-only models.\n * Requires Z_AI_API_KEY. Tools are read-only and safe to run automatically.\n */\nexport const zaiVisionServer = (): MCPServerConfig => ({\n name: 'zai-vision',\n description: 'Z.AI Vision MCP — image analysis and screenshot understanding',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@z_ai/mcp-server@latest'],\n env: { Z_AI_MODE: 'ZAI' },\n allowedTools: [\n 'image_analysis',\n 'extract_text_from_screenshot',\n 'diagnose_error_screenshot',\n 'understand_technical_diagram',\n 'analyze_data_visualization',\n 'ui_diff_check',\n ],\n permission: 'auto',\n});\n\n/**\n * Playwright — browser automation: navigate, click, type, screenshot, evaluate JS.\n * Spawns a headless Chromium browser via @modelcontextprotocol/server-playwright.\n * Tools can read and interact with live web pages — permission defaults to\n * `confirm` because form submission / DOM mutation is possible.\n */\nexport const playwrightServer = (): MCPServerConfig => ({\n name: 'playwright',\n description:\n 'Browser automation — navigate, screenshot, click, type, evaluate JS (headless Chromium)',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-playwright'],\n permission: 'confirm',\n});\n\n/**\n * MiniMax Token Plan MCP — web_search + understand_image.\n * This preset exposes only the read-only image understanding tool by default.\n * Requires MINIMAX_API_KEY and uvx on PATH.\n */\nexport const miniMaxVisionServer = (): MCPServerConfig => ({\n name: 'minimax-vision',\n description: 'MiniMax MCP — image understanding via understand_image',\n transport: 'stdio',\n command: 'uvx',\n args: ['minimax-coding-plan-mcp', '-y'],\n env: {\n MINIMAX_MCP_BASE_PATH: './.wrongstack/minimax-output',\n MINIMAX_API_HOST: 'https://api.minimax.io',\n MINIMAX_API_RESOURCE_MODE: 'url',\n },\n allowedTools: ['understand_image'],\n permission: 'auto',\n});\n\n/** Everything bundled — full set of built-in servers. Useful for `wstack mcp add --all`. */\nexport const allServers = (): Record<string, MCPServerConfig> => ({\n filesystem: { ...filesystemServer(), enabled: false },\n github: { ...githubServer(), enabled: false },\n context7: { ...context7Server(), enabled: false },\n 'brave-search': { ...braveSearchServer(), enabled: false },\n block: { ...blockServer(), enabled: false },\n everart: { ...everArtServer(), enabled: false },\n slack: { ...slackServer(), enabled: false },\n aws: { ...awsServer(), enabled: false },\n 'google-maps': { ...googleMapsServer(), enabled: false },\n sentinel: { ...sentinelServer(), enabled: false },\n 'zai-vision': { ...zaiVisionServer(), enabled: false },\n 'minimax-vision': { ...miniMaxVisionServer(), enabled: false },\n playwright: { ...playwrightServer(), enabled: false },\n});\n","/** Assert a value is neither null nor undefined. Throws if it is.\n * Useful after optional chaining and indexed access when the\n * control flow guarantees the value exists but TypeScript can't\n * prove it (e.g. after a check on a related field). */\nexport function expectDefined<T>(value: T | null | undefined, label?: string): T {\n if (value === null || value === undefined) {\n const err = new Error(label ? `Expected ${label} to be defined` : 'Expected value to be defined');\n err.name = 'ExpectDefinedError';\n throw err;\n }\n return value;\n}\n","import { expectDefined } from './expect-defined.js';\nimport type { ContentBlock, ToolResultBlock, ToolUseBlock } from '../types/blocks.js';\nimport type { Message } from '../types/messages.js';\nexport interface MessageRepairReport {\n changed: boolean;\n removedToolUses: string[];\n removedToolResults: string[];\n removedMessages: number;\n}\n\nexport interface MessageRepairResult {\n messages: Message[];\n report: MessageRepairReport;\n}\n\n/**\n * Repair provider-level tool-call adjacency invariants.\n *\n * Anthropic requires every assistant `tool_use` block to have a matching\n * `tool_result` block in the immediately following user message. Manual\n * context surgery (summary/prune) can cut through the middle of such an\n * exchange. This function removes only the now-orphaned protocol blocks,\n * preserving surrounding text/images/thinking blocks where possible.\n */\nexport function repairToolUseAdjacency(messages: Message[]): MessageRepairResult {\n const removedToolUses: string[] = [];\n const removedToolResults: string[] = [];\n let removedMessages = 0;\n let changed = false;\n const out: Message[] = [];\n\n for (let i = 0; i < messages.length; i++) {\n const original = expectDefined(messages[i]);\n let msg = original;\n\n if (hasToolUse(msg)) {\n const nextIds = toolResultIds(messages[i + 1]);\n const filtered = mapContent(msg, (blocks) => {\n const next: ContentBlock[] = [];\n for (const block of blocks) {\n if (block.type === 'tool_use' && !nextIds.has(block.id)) {\n removedToolUses.push(block.id);\n changed = true;\n continue;\n }\n next.push(block);\n }\n return next;\n });\n msg = filtered ?? msg;\n }\n\n if (hasToolResult(msg)) {\n const allowed = toolUseIds(out[out.length - 1]);\n const filtered = mapContent(msg, (blocks) => {\n const next: ContentBlock[] = [];\n for (const block of blocks) {\n if (block.type === 'tool_result' && !allowed.has(block.tool_use_id)) {\n removedToolResults.push(block.tool_use_id);\n changed = true;\n continue;\n }\n next.push(block);\n }\n return next;\n });\n msg = filtered ?? msg;\n }\n\n if (isEmptyMessage(msg)) {\n removedMessages++;\n changed = true;\n continue;\n }\n out.push(msg);\n }\n\n return {\n messages: changed ? out : messages,\n report: { changed, removedToolUses, removedToolResults, removedMessages },\n };\n}\n\nfunction hasToolUse(msg: Message | undefined): boolean {\n return contentBlocks(msg).some((b): b is ToolUseBlock => b.type === 'tool_use');\n}\n\nfunction hasToolResult(msg: Message | undefined): boolean {\n return contentBlocks(msg).some((b): b is ToolResultBlock => b.type === 'tool_result');\n}\n\nfunction toolUseIds(msg: Message | undefined): Set<string> {\n const ids = new Set<string>();\n if (!msg || msg.role !== 'assistant') return ids;\n for (const block of contentBlocks(msg)) {\n if (block.type === 'tool_use') ids.add(block.id);\n }\n return ids;\n}\n\nfunction toolResultIds(msg: Message | undefined): Set<string> {\n const ids = new Set<string>();\n if (!msg || msg.role !== 'user') return ids;\n for (const block of contentBlocks(msg)) {\n if (block.type === 'tool_result') ids.add(block.tool_use_id);\n }\n return ids;\n}\n\nfunction contentBlocks(msg: Message | undefined): ContentBlock[] {\n return msg && Array.isArray(msg.content) ? msg.content : [];\n}\n\nfunction mapContent(\n msg: Message,\n fn: (blocks: ContentBlock[]) => ContentBlock[],\n): Message | null {\n if (!Array.isArray(msg.content)) return msg;\n const next = fn(msg.content);\n if (next.length === msg.content.length && next.every((b, idx) => b === msg.content[idx])) {\n return msg;\n }\n return { ...msg, content: next };\n}\n\nfunction isEmptyMessage(msg: Message): boolean {\n if (typeof msg.content === 'string') return msg.content.trim().length === 0;\n return msg.content.length === 0;\n}\n","import type { Message } from '../types/messages.js';\n/**\n * Shared token estimation with JSON.stringify caching.\n * Avoids repeated stringification of tool input objects.\n *\n * ## Calibration\n *\n * `estimateRequestTokens` uses a fixed 3.5 chars/token heuristic — a\n * conservative overestimate that prevents underestimation but reduces\n * accuracy. After each API call, call `recordActualUsage()` with the\n * real `usage.input` from the provider response. The module maintains a\n * rolling average of `actual / estimated` ratio (EWM, α=0.3) and\n * applies it to subsequent calls via `estimateRequestTokensCalibrated`.\n *\n * Calibration is per-module (shared across all callers), which is\n * sufficient: the chars/token ratio is a property of the tokenizer,\n * not the model. Uncalibrated calls (before any samples, or when\n * `recordActualUsage` is not called) fall back to the uncalibrated\n * estimate so nothing breaks.\n */\n\nconst RoughTokenEstimate = (text: string, charsPerToken = 3.5): number =>\n Math.max(1, Math.ceil(text.length / charsPerToken));\n\n/** Calibration state: actual/estimated ratio via exponential weighted moving average. */\ninterface CalState {\n ratio: number; // current calibration multiplier (actual / estimated)\n count: number; // number of samples recorded\n prevEst: number; // estimated tokens from the most recent estimateRequestTokens call\n}\n\n/** EWM α — higher = faster adaptation, more volatile. */\nconst CAL_ALPHA = 0.3;\n\n/**\n * Calibration is keyed so that, in a multi-agent / model-switching process,\n * each (provider, model) tokenizer gets its own ratio instead of all of them\n * collapsing onto one shared number. Callers that don't pass a key use the\n * shared `__global__` bucket — that preserves the original single-session\n * behavior and keeps all existing call sites working unchanged.\n */\nconst CALIBRATION_GLOBAL_KEY = '__global__';\nconst _cals = new Map<string, CalState>();\n\nfunction calState(key: string): CalState {\n let state = _cals.get(key);\n if (!state) {\n state = { ratio: 1.0, count: 0, prevEst: 0 };\n _cals.set(key, state);\n }\n return state;\n}\n\nconst MIN_SAMPLES_FOR_CALIBRATION = 3;\n\n/**\n * Cache of computed estimates keyed by the stringified input — not the\n * input object itself. Previously the cache was keyed by the input object\n * via WeakMap, but JSON.stringify() produces a new object reference each\n * call so the cache never hit. Now we use a Map with string keys so that\n * repeated stringifications of the same structure share a single entry.\n */\nconst ESTIMATE_CACHE = new Map<string, number>();\n\nconst ESTIMATE_CACHE_MAX_SIZE = 10_000;\n\nfunction getCachedEstimate(key: string, compute: (key: string) => number): number {\n const existing = ESTIMATE_CACHE.get(key);\n if (existing !== undefined) return existing;\n if (ESTIMATE_CACHE.size >= ESTIMATE_CACHE_MAX_SIZE) {\n // Evict oldest half when at capacity — O(1) instead of O(n) iteration.\n // 5 000 surviving entries still give a high cache hit rate for the\n // common case of repeated context-window checks on the same messages.\n for (const k of ESTIMATE_CACHE.keys()) {\n if (ESTIMATE_CACHE.size <= Math.floor(ESTIMATE_CACHE_MAX_SIZE / 2)) break;\n ESTIMATE_CACHE.delete(k);\n }\n }\n const estimate = compute(key);\n ESTIMATE_CACHE.set(key, estimate);\n return estimate;\n}\n\n/**\n * Estimate tokens for a tool_use block input.\n * Caches the stringified result keyed by the stable string representation\n * to avoid repeated JSON.stringify calls during context window checks.\n */\nexport function estimateToolInputTokens(input: unknown): number {\n if (typeof input === 'string') return RoughTokenEstimate(input);\n if (input === null || typeof input !== 'object') {\n return RoughTokenEstimate(String(input));\n }\n // JSON.stringify is called once to form the cache key; RoughTokenEstimate\n // is deferred only on cache miss (compute callback), not wrapped unnecessarily.\n return getCachedEstimate(JSON.stringify(input), (key) => RoughTokenEstimate(key));\n}\n\n/**\n * Estimate tokens for a tool_result content.\n */\nexport function estimateToolResultTokens(content: string | unknown): number {\n if (typeof content === 'string') return RoughTokenEstimate(content);\n return getCachedEstimate(JSON.stringify(content), (key) => RoughTokenEstimate(key));\n}\n\n/**\n * Estimate tokens for a text block.\n */\nexport function estimateTextTokens(text: string): number {\n return RoughTokenEstimate(text);\n}\n\n/**\n * Compute and cache the token estimate for a single message. This is the\n * canonical per-message estimator — called once by ConversationState on\n * append/replace so the O(n·m) content-block walk happens at mutation time,\n * not on every context-pressure check.\n */\nexport function computeMessageTokens(msg: Message): number {\n if (typeof msg.content === 'string') return estimateTextTokens(msg.content);\n let total = 0;\n for (const b of msg.content) {\n if (b.type === 'text') total += estimateTextTokens(b.text);\n else if (b.type === 'tool_use') total += estimateToolInputTokens(b.input);\n else if (b.type === 'tool_result') total += estimateToolResultTokens(b.content);\n else total += RoughTokenEstimate(JSON.stringify(b));\n }\n return total;\n}\n\n/**\n * Estimate tokens for an array of messages (text + tool I/O), using the shared\n * 3.5 chars/token basis. This is the single canonical message-array estimator —\n * compactors, the context_manager tool, and the `/context` display all route\n * through it so the number a user sees matches the number compaction decides on.\n *\n * When a message carries a pre-computed `_estTokens` field (set by\n * ConversationState on append/replace), it is used directly instead of\n * re-walking the content blocks — turning the O(n·m) scan into an O(n)\n * sum for fully-cached arrays.\n */\nexport function estimateMessageTokens(messages: readonly Message[]): number {\n let total = 0;\n for (const m of messages) {\n if (typeof m._estTokens === 'number' && m._estTokens > 0) {\n total += m._estTokens;\n continue;\n }\n total += computeMessageTokens(m);\n }\n return total;\n}\n\n/**\n * Rough estimate of tokens in a tool definition (name + description + schema).\n * Accounts for the JSON-serialized inputSchema which is sent to the API\n * but NOT included in roughEstimate(content).\n */\nexport function estimateToolDefTokens(tool: { name: string; description?: string | undefined; inputSchema: unknown }): number {\n // Fast path: pre-computed by ToolRegistry at registration time.\n const cached = (tool as { _estDefTokens?: number | undefined })._estDefTokens;\n if (typeof cached === 'number' && cached > 0) return cached;\n\n return RoughTokenEstimate(tool.name) +\n RoughTokenEstimate(tool.description ?? '') +\n RoughTokenEstimate(JSON.stringify(tool.inputSchema));\n}\n\n/**\n * Estimate the total API request token count: system prompt + tool definitions\n * + conversation messages. Use this for context-window bar calculations\n * instead of roughEstimate (which only counts messages).\n *\n * The overhead ratio (overhead / messages) varies by conversation length:\n * - Short conversations (< 10 messages): ~30-50% overhead (large system+tools)\n * - Medium (10-50 messages): ~15-30%\n * - Long (> 50 messages): ~5-15%\n *\n * Returns { messages, systemPrompt, tools, total } for debugging display.\n */\nexport interface RequestTokenBreakdown {\n messages: number;\n systemPrompt: number;\n tools: number;\n total: number;\n}\n\nexport function estimateRequestTokens(\n messages: unknown,\n systemPrompt: unknown,\n tools: { name: string; description?: string | undefined; inputSchema: unknown }[],\n calibrationKey: string = CALIBRATION_GLOBAL_KEY,\n): RequestTokenBreakdown {\n // Messages: apply the same logic as roughEstimate\n let messagesTokens = 0;\n if (typeof messages === 'string') {\n messagesTokens = RoughTokenEstimate(messages);\n } else if (Array.isArray(messages)) {\n for (const m of messages) {\n if (typeof m === 'object' && m !== null && 'content' in m) {\n // Fast path: pre-computed per-message token estimate (set by\n // ConversationState on append/replace). Skips the O(m) content-block\n // walk entirely for cached messages.\n const cached = (m as { _estTokens?: number | undefined })._estTokens;\n if (typeof cached === 'number' && cached > 0) {\n messagesTokens += cached;\n continue;\n }\n const content = (m as { content: unknown }).content;\n if (typeof content === 'string') {\n messagesTokens += RoughTokenEstimate(content);\n } else if (Array.isArray(content)) {\n for (const b of content) {\n if (typeof b === 'object' && b !== null) {\n if ((b as { type?: string | undefined }).type === 'text') {\n messagesTokens += RoughTokenEstimate((b as { text: string }).text);\n } else {\n messagesTokens += RoughTokenEstimate(JSON.stringify(b));\n }\n }\n }\n }\n }\n }\n }\n\n // System prompt\n let systemTokens = 0;\n if (typeof systemPrompt === 'string') {\n systemTokens = RoughTokenEstimate(systemPrompt);\n } else if (Array.isArray(systemPrompt)) {\n for (const b of systemPrompt) {\n if (typeof b === 'object' && b !== null && (b as { type?: string | undefined }).type === 'text') {\n systemTokens += RoughTokenEstimate((b as { text: string }).text);\n }\n }\n }\n\n // Tool definitions\n let toolsTokens = 0;\n for (const t of tools) {\n toolsTokens += estimateToolDefTokens(t);\n }\n\n const total = messagesTokens + systemTokens + toolsTokens;\n\n // Record the raw estimate for calibration: the next recordActualUsage()\n // call will pair this against the actual API usage so the rolling ratio\n // stays in sync with the real chars/token ratio of the content.\n calState(calibrationKey).prevEst = total;\n\n return {\n messages: messagesTokens,\n systemPrompt: systemTokens,\n tools: toolsTokens,\n total,\n };\n}\n\n/**\n * Record the actual API input token count after a provider call so\n * `estimateRequestTokensCalibrated` can self-correct on subsequent calls.\n *\n * Prefer passing `estimatedInputTokens` explicitly (the calibrated pre-flight\n * estimate from the middleware) — this avoids race conditions when other code\n * also calls `estimateRequestTokens` between the pre-flight and this call\n * (e.g. audit logging in agent.ts).\n *\n * When `estimatedInputTokens` is omitted, falls back to the keyed bucket's\n * `prevEst` for backward compatibility with callers that don't have the\n * pre-flight value. `calibrationKey` selects the per-(provider,model) bucket\n * (defaults to the shared global bucket).\n */\nexport function recordActualUsage(\n actualInputTokens: number,\n estimatedInputTokens?: number,\n calibrationKey: string = CALIBRATION_GLOBAL_KEY,\n): void {\n if (actualInputTokens <= 0) return;\n const cal = calState(calibrationKey);\n const est = estimatedInputTokens ?? cal.prevEst;\n if (est <= 0) return;\n\n const sampleRatio = actualInputTokens / est;\n if (cal.count === 0) {\n cal.ratio = sampleRatio;\n } else {\n // EWM: new = α * sample + (1-α) * old → α=0.3 = fast initial converge\n cal.ratio = CAL_ALPHA * sampleRatio + (1 - CAL_ALPHA) * cal.ratio;\n }\n // Sanity bound: keep the rolling ratio within [0.5, 1.5] so a sequence\n // of bad samples can't blow up the calibration for everyone.\n cal.ratio = Math.min(1.5, Math.max(0.5, cal.ratio));\n cal.count++;\n}\n\n/**\n * Returns the current calibration state for a bucket. Exposed for debugging\n * and tests — not needed by normal callers.\n */\nexport function getCalibrationState(\n calibrationKey: string = CALIBRATION_GLOBAL_KEY,\n): { ratio: number; count: number; calibrated: boolean } {\n const cal = calState(calibrationKey);\n return {\n ratio: cal.ratio,\n count: cal.count,\n calibrated: cal.count >= MIN_SAMPLES_FOR_CALIBRATION,\n };\n}\n\n/**\n * Like `estimateRequestTokens` but applies the rolling calibration factor\n * so context pressure readings converge on reality within a few iterations.\n *\n * Before any `recordActualUsage` samples are collected, returns the same\n * result as `estimateRequestTokens` (ratio = 1.0, no distortion).\n * After `MIN_SAMPLES_FOR_CALIBRATION` samples, applies the calibrated\n * multiplier capped to the range [0.5, 1.5] as a sanity bound.\n */\nexport function estimateRequestTokensCalibrated(\n messages: unknown,\n systemPrompt: unknown,\n tools: { name: string; description?: string | undefined; inputSchema: unknown }[],\n calibrationKey: string = CALIBRATION_GLOBAL_KEY,\n): RequestTokenBreakdown {\n const result = estimateRequestTokens(messages, systemPrompt, tools, calibrationKey);\n const cal = calState(calibrationKey);\n\n if (cal.count >= MIN_SAMPLES_FOR_CALIBRATION) {\n const safeRatio = Math.min(1.5, Math.max(0.5, cal.ratio));\n return {\n messages: Math.round(result.messages * safeRatio),\n systemPrompt: Math.round(result.systemPrompt * safeRatio),\n tools: Math.round(result.tools * safeRatio),\n total: Math.round(result.total * safeRatio),\n };\n }\n\n return result;\n}\n\n/**\n * Resets calibration state. Primarily for tests that run in the same\n * process and need a clean slate between suites. With no argument it clears\n * every bucket (including the global one); pass a key to reset just that bucket.\n */\nexport function resetCalibration(calibrationKey?: string): void {\n if (calibrationKey === undefined) {\n _cals.clear();\n return;\n }\n _cals.delete(calibrationKey);\n}\n","import type { Context } from '../core/context.js';\nimport type { Compactor } from '../types/compactor.js';\nimport type { Message } from '../types/messages.js';\nimport type { Tool } from '../types/tool.js';\nimport { repairToolUseAdjacency } from '../utils/message-invariants.js';\nimport { estimateMessageTokens, estimateRequestTokens } from '../utils/token-estimate.js';\n\n/**\n * Context introspection and management tool.\n * Allows the model to:\n * - \"check\" → see token budget and message counts\n * - \"summary\" → summarize and replace a range of messages\n * - \"prune\" → remove specific message indices\n * - \"add_note\" → inject a summary note at a specific point\n * - \"compact\" → run compaction via the injected compactor\n */\nexport const CONTEXT_MANAGER_TOOL_NAME = 'context_manager';\n\nexport type ContextManagerAction =\n | 'check'\n | 'summary'\n | 'prune'\n | 'add_note'\n | 'compact'\n | 'repair';\n\nexport interface ContextManagerInput {\n action: ContextManagerAction;\n /** 0-based message indices for prune/summary (inclusive). */\n from?: number | undefined;\n to?: number | undefined;\n /** Text for add_note / summary actions. For summary, this is the LLM-provided summary text. */\n text?: string | undefined;\n /** Inject after which index (for add_note). Defaults to prepend (0). */\n afterIndex?: number | undefined;\n /**\n * System prompt blocks for accurate total token estimation in check action.\n * When provided, check returns the full API request estimate\n * (messages + system + tools) instead of just message tokens.\n */\n systemPrompt?: unknown | undefined;\n /**\n * Registered tools for accurate total token estimation in check action.\n * Each tool's name + description + inputSchema is counted.\n */\n tools?: { name: string; description?: string | undefined; inputSchema: unknown }[];\n}\n\nexport interface ContextManagerResult {\n action: ContextManagerAction;\n beforeTokens: number;\n afterTokens?: number | undefined;\n removedCount?: number | undefined;\n messageCount: number;\n summary?: string | undefined;\n notes?: string | undefined;\n repaired?: {\n removedToolUses: string[];\n removedToolResults: string[];\n removedMessages: number;\n } | undefined;\n}\n\n/**\n * Options for creating a context manager tool.\n * `compactor` is required for the \"compact\" action; without it the action returns an error.\n */\nexport interface ContextManagerToolOptions {\n compactor?: Compactor | undefined;\n /**\n * Optional sub-LLM summarizer. When provided, the \"summary\" action calls this\n * to produce real summaries of message ranges instead of placeholder text.\n * (signature matches Provider.complete — return the summary text in result.content[0].text)\n */\n summarizer?: (((messages: Message[]) => Promise<string>)) | undefined;\n /**\n * Minimum full-request token count before the compact action is allowed to run.\n * Prevents unnecessary compaction calls when context is small.\n * Default: 0 (always allow). Set to ~5000 for meaningful compaction targets.\n */\n minCompactThreshold?: number | undefined;\n /**\n * Minimum token growth required before retrying after a NOOP compaction.\n * A NOOP is when compaction saved nothing (preserveK protects everything,\n * no oversized tool_results). Default: 2000.\n */\n noopRetryDeltaTokens?: number | undefined;\n /**\n * Provider's max context window in tokens. Used to compute a relative\n * threshold when `minCompactThreshold` is not set. Default: 128_000.\n */\n maxContext?: number | undefined;\n /**\n * Fraction of maxContext that triggers compaction. Only used when\n * `minCompactThreshold` is not set. Default: 0.5 (50% of maxContext).\n */\n compactThresholdFraction?: number | undefined;\n}\n\n/** Messages-only token estimate. Delegates to the canonical shared estimator\n * so the context_manager tool agrees with compaction and the `/context` bar. */\nfunction roughEstimate(messages: Message[]): number {\n return estimateMessageTokens(messages);\n}\n\nexport function createContextManagerTool(\n opts: ContextManagerToolOptions = {},\n): Tool<ContextManagerInput, ContextManagerResult> {\n const minCompactThreshold = opts.minCompactThreshold ?? 0;\n const noopRetryDeltaTokens = opts.noopRetryDeltaTokens ?? 2_000;\n /** Hard override for maxContext. When absent, the runtime value from ctx.provider is used. */\n const configuredMaxContext = opts.maxContext;\n const compactThresholdFraction = opts.compactThresholdFraction ?? 0.5;\n\n // Tracks the most recent NOOP attempt so we can skip retry until context grows.\n let lastNoopTokens = 0;\n\n return {\n name: CONTEXT_MANAGER_TOOL_NAME,\n description:\n 'Inspect or reorganize the conversation context window. ' +\n 'Use \"check\" to see token budget. ' +\n 'Use \"summary\" to collapse a message range into a concise note (provide \"text\" for custom summary). ' +\n 'Use \"prune\" to remove specific messages by index. ' +\n 'Use \"add_note\" to inject a summary note. ' +\n 'Use \"compact\" to run aggressive compaction. ' +\n 'Use \"repair\" to remove orphan tool_use/tool_result blocks after manual context surgery.',\n inputSchema: {\n type: 'object',\n properties: {\n action: {\n type: 'string',\n enum: ['check', 'summary', 'prune', 'add_note', 'compact', 'repair'],\n description: 'The context operation to perform.',\n },\n from: {\n type: 'number',\n description: 'Start index (inclusive) for summary/prune operations.',\n },\n to: {\n type: 'number',\n description: 'End index (inclusive) for summary/prune operations.',\n },\n text: {\n type: 'string',\n description:\n 'Summary or note text. For \"summary\": the model-provided summary of the removed range. ' +\n 'For \"add_note\": the note to inject.',\n },\n afterIndex: {\n type: 'number',\n description: 'Insert after this index (for add_note). Defaults to prepend (0).',\n },\n },\n required: ['action'],\n },\n permission: 'auto',\n mutating: true,\n\n async execute(input: ContextManagerInput, ctx: Context): Promise<ContextManagerResult> {\n const messages = ctx.messages;\n const beforeTokens = roughEstimate(messages);\n\n // When ctx.state is available, route mutations through the observer\n // layer so subscribers stay in sync. Fall back to direct mutation for\n // tests and environments that haven't wired ConversationState.\n const applyMessages = (next: Message[]) => {\n const repaired = repairToolUseAdjacency(next);\n const finalMessages = repaired.messages;\n // Skip if finalMessages === messages (no-op: repair returned the same array).\n // This also prevents the self-spread bug where spreading an array into\n // splice(0, 0, ...arr) on the same array reference empties it.\n if (finalMessages === messages) return repaired.report;\n if (ctx.state) {\n ctx.state.replaceMessages(finalMessages);\n } else {\n // push(...) is O(k) with no element shift, unlike splice(0, 0, ...) which\n // shifts all existing elements before inserting at position 0.\n messages.length = 0;\n messages.push(...finalMessages);\n }\n return repaired.report;\n };\n\n switch (input.action) {\n case 'check': {\n // Prefer the full API request estimate when systemPrompt + tools are available.\n // This is the accurate number for context-window bar display.\n // Falls back to roughEstimate (messages-only) for backward compat and test environments.\n const estimate = (input.systemPrompt != null && Array.isArray(input.tools))\n ? estimateRequestTokens(messages, input.systemPrompt, input.tools)\n : { total: beforeTokens, messages: beforeTokens, systemPrompt: 0, tools: 0 };\n return {\n action: 'check',\n beforeTokens: estimate.total,\n messageCount: messages.length,\n notes: JSON.stringify({\n messages: messages.length,\n tokens: estimate.total,\n msgTokens: estimate.messages,\n sysTokens: estimate.systemPrompt,\n toolTokens: estimate.tools,\n readFiles: ctx.readFiles.size,\n todos: ctx.todos.length,\n inProgress: ctx.todos.filter((t) => t.status === 'in_progress').length,\n }),\n };\n }\n\n case 'repair': {\n const repair = applyMessages([...messages]);\n const afterTokens = roughEstimate(ctx.messages);\n return {\n action: 'repair',\n beforeTokens,\n afterTokens,\n messageCount: ctx.messages.length,\n repaired: repair.changed\n ? {\n removedToolUses: repair.removedToolUses,\n removedToolResults: repair.removedToolResults,\n removedMessages: repair.removedMessages,\n }\n : undefined,\n notes: repair.changed\n ? 'Context tool-call adjacency repaired.'\n : 'Context tool-call adjacency already valid.',\n };\n }\n\n case 'compact': {\n if (!opts.compactor) {\n return {\n action: 'compact',\n beforeTokens,\n messageCount: messages.length,\n notes: 'No compactor registered. Use /compact aggressive via slash command instead.',\n };\n }\n // Compute full request tokens for threshold check.\n const fullEstimate = (input.systemPrompt != null && Array.isArray(input.tools))\n ? estimateRequestTokens(messages, input.systemPrompt, input.tools)\n : { total: beforeTokens, messages: beforeTokens, systemPrompt: 0, tools: 0 };\n const currentTokens = fullEstimate.total;\n\n // Resolve maxContext at execution time from the live provider capabilities.\n // This is the actual model limit — from models.dev catalog, provider config,\n // or explicit effectiveMaxContext override. Falls back to the creation-time\n // value only when no runtime value is available (e.g. in test environments).\n const runtimeMaxContext =\n configuredMaxContext ?? ctx.provider?.capabilities?.maxContext ?? 128_000;\n const runtimeThreshold = minCompactThreshold > 0\n ? minCompactThreshold\n : Math.floor(runtimeMaxContext * compactThresholdFraction);\n\n // NOOP retry prevention: skip if the previous compaction saved nothing\n // and context hasn't grown enough to make another attempt worthwhile.\n if (lastNoopTokens > 0) {\n const delta = currentTokens - lastNoopTokens;\n if (delta < noopRetryDeltaTokens) {\n return {\n action: 'compact',\n beforeTokens,\n afterTokens: beforeTokens,\n messageCount: messages.length,\n notes: `Compact is a NOOP retry: context grew only ${delta} tokens since the last no-op attempt (threshold: ${noopRetryDeltaTokens}). Skip until more content accumulates.`,\n };\n }\n }\n\n // Minimum threshold check: skip if context is too small to benefit.\n if (runtimeThreshold > 0 && currentTokens < runtimeThreshold) {\n return {\n action: 'compact',\n beforeTokens,\n afterTokens: beforeTokens,\n messageCount: messages.length,\n notes: `Context tokens (${currentTokens}) below compact threshold (${runtimeThreshold}, based on provider maxContext ${runtimeMaxContext}). Skipping.`,\n };\n }\n\n const report = await opts.compactor.compact(ctx);\n ctx.clearFileTracking();\n\n // When ctx.state is not wired, the compactor's replaceMessages calls are\n // no-ops — repairToolUseAdjacency was still called inside the compactor but\n // the result was never committed. Run repair once to commit via the fallback.\n // When ctx.state IS wired, the compactor already committed the repair.\n let repaired = report.repaired;\n let afterTokens: number;\n if (!ctx.state) {\n const repair = applyMessages([...ctx.messages]);\n repaired = report.repaired ?? (repair.changed ? repair : undefined);\n afterTokens = repair.changed ? roughEstimate(ctx.messages) : report.after;\n } else {\n afterTokens = report.after;\n }\n\n // Record NOOP state: did compaction actually reduce tokens?\n const reduced = report.fullRequestTokensBefore > report.fullRequestTokensAfter;\n const repairedSomething = !!report.repaired;\n if (reduced || repairedSomething) {\n lastNoopTokens = 0;\n } else {\n lastNoopTokens = currentTokens;\n }\n\n return {\n action: 'compact',\n beforeTokens,\n afterTokens,\n messageCount: ctx.messages.length,\n repaired: repaired\n ? {\n removedToolUses: repaired.removedToolUses,\n removedToolResults: repaired.removedToolResults,\n removedMessages: repaired.removedMessages,\n }\n : undefined,\n };\n }\n\n case 'prune': {\n const from = input.from ?? 0;\n const to = input.to ?? messages.length - 1;\n if (from < 0 || to >= messages.length || from > to) {\n return {\n action: 'prune',\n beforeTokens,\n messageCount: messages.length,\n notes: `Invalid range [${from}, ${to}] for ${messages.length} messages.`,\n };\n }\n const copy = [...messages];\n const removed = copy.splice(from, to - from + 1);\n ctx.clearFileTracking();\n const repair = applyMessages(copy);\n const afterTokens = roughEstimate(ctx.messages);\n return {\n action: 'prune',\n beforeTokens,\n afterTokens,\n messageCount: ctx.messages.length,\n removedCount: removed.length,\n repaired: repair.changed\n ? {\n removedToolUses: repair.removedToolUses,\n removedToolResults: repair.removedToolResults,\n removedMessages: repair.removedMessages,\n }\n : undefined,\n };\n }\n\n case 'add_note': {\n const noteText = input.text ?? '(no summary)';\n const afterIdx = Math.min(input.afterIndex ?? 0, messages.length);\n const noteMsg: Message = {\n role: 'system',\n content: `[note: ${noteText}]`,\n };\n const copy = [...messages];\n copy.splice(afterIdx, 0, noteMsg);\n const repair = applyMessages(copy);\n const afterTokens = roughEstimate(ctx.messages);\n return {\n action: 'add_note',\n beforeTokens,\n afterTokens,\n messageCount: ctx.messages.length,\n summary: noteText,\n repaired: repair.changed\n ? {\n removedToolUses: repair.removedToolUses,\n removedToolResults: repair.removedToolResults,\n removedMessages: repair.removedMessages,\n }\n : undefined,\n };\n }\n\n case 'summary': {\n const from = input.from ?? 0;\n const to = input.to ?? messages.length - 1;\n if (from < 0 || to >= messages.length || from > to) {\n return {\n action: 'summary',\n beforeTokens,\n messageCount: messages.length,\n notes: `Invalid range [${from}, ${to}] for ${messages.length} messages.`,\n };\n }\n const summaryText =\n input.text ?? '[summary placeholder — provide \"text\" to record the summary]';\n const summaryMsg: Message = {\n role: 'system',\n content: `[summary of messages ${from}–${to}]: ${summaryText}`,\n };\n const copy = [...messages];\n copy.splice(from, to - from + 1, summaryMsg);\n ctx.clearFileTracking();\n const repair = applyMessages(copy);\n const afterTokens = roughEstimate(ctx.messages);\n return {\n action: 'summary',\n beforeTokens,\n afterTokens,\n messageCount: ctx.messages.length,\n summary: summaryText,\n repaired: repair.changed\n ? {\n removedToolUses: repair.removedToolUses,\n removedToolResults: repair.removedToolResults,\n removedMessages: repair.removedMessages,\n }\n : undefined,\n };\n }\n\n default:\n return {\n action: input.action,\n beforeTokens,\n messageCount: messages.length,\n notes: `Unknown action: ${input.action}`,\n };\n }\n },\n };\n}\n\n/** Pre-built instance with no compactor — compact action will return an error. */\nexport const contextManagerTool: Tool<ContextManagerInput, ContextManagerResult> =\n createContextManagerTool();\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/utils/term.ts","../../src/utils/color.ts","../../src/infrastructure/logger.ts","../../src/infrastructure/path-resolver.ts","../../src/infrastructure/token-counter.ts","../../src/infrastructure/mcp-servers.ts","../../src/utils/expect-defined.ts","../../src/utils/message-invariants.ts","../../src/utils/tool-wire-compact.ts","../../src/utils/token-estimate.ts","../../src/infrastructure/context-manager.ts"],"names":["path","fs2"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * TTY detection helpers — the single source of truth for \"is this process\n * running against a real terminal?\". Replaces ad-hoc `process.stdin.isTTY`\n * / `process.stdout.isTTY` checks scattered across the codebase so that:\n *\n * 1. test code can mock a single module instead of stubbing `isTTY` on\n * every ReadStream/WriteStream the test happens to touch;\n * 2. a future TTY-detection source (an env var override, a Windows\n * ConPTY workaround, …) lands in one place;\n * 3. `isInteractive()` encodes the rule the project already used inline\n * (\"both streams are TTYs AND we're not running under CI\") in one\n * testable helper instead of the same 3-condition check in two\n * different files.\n *\n * Scope: detection only. Raw-mode control (`setRawMode`), resize\n * subscriptions, and write-injection belong to a future, larger TTY\n * abstraction; this module is the smallest pull that gives us a\n * testable seam and dedups 20+ call sites.\n */\n\nconst hasStdout = (): boolean => typeof process !== 'undefined' && !!process.stdout;\nconst hasStdin = (): boolean => typeof process !== 'undefined' && !!process.stdin;\n\n/** True when `process.stdout` is attached to a terminal (not a pipe/file). */\nexport function isStdoutTTY(): boolean {\n return hasStdout() && Boolean(process.stdout.isTTY);\n}\n\n/** True when `process.stdin` is attached to a terminal (not a pipe/file). */\nexport function isStdinTTY(): boolean {\n return hasStdin() && Boolean(process.stdin.isTTY);\n}\n\n/**\n * True when the current process is an interactive session: both stdin and\n * stdout are TTYs. Callers that also need a \"not a single-shot invocation\"\n * or \"not under CI\" check should layer that on top — keeping this helper\n * minimal preserves the original inline checks it replaces.\n */\nexport function isInteractive(): boolean {\n return isStdinTTY() && isStdoutTTY();\n}\n\n/** Current terminal size in characters, with a 24×80 fallback for non-TTYs. */\nexport function getTermSize(): { rows: number; cols: number } {\n if (!hasStdout()) return { rows: 24, cols: 80 };\n return {\n rows: process.stdout.rows ?? 24,\n cols: process.stdout.columns ?? 80,\n };\n}\n\n/**\n * Subscribe to terminal resize events. `cb` is called with the new size each\n * time the underlying stream emits `resize`. Returns a cleanup function the\n * caller MUST call on dispose to remove the listener — leaving a stale\n * `resize` listener on a disposed component leaks the closure (and the\n * component itself, transitively) until the process exits.\n *\n * The stream argument defaults to `process.stdout`. Pass an explicit\n * `NodeJS.WriteStream` when the caller already owns one (e.g. a status line\n * that targets an injected `out` for testability). For non-TTY streams no\n * listener is registered and the returned cleanup is a no-op.\n */\nexport function onResize(\n cb: (size: { rows: number; cols: number }) => void,\n stream: NodeJS.WriteStream = process.stdout,\n): () => void {\n if (!stream || typeof stream.on !== 'function') return () => {};\n const handler = (): void => {\n cb({\n rows: stream.rows ?? 24,\n cols: stream.columns ?? 80,\n });\n };\n stream.on('resize', handler);\n return () => {\n stream.off('resize', handler);\n };\n}\n\n/**\n * Toggle raw mode on a TTY stdin stream. Returns `true` when the toggle was\n * applied, `false` when the stream is null, not a TTY, or doesn't expose\n * `setRawMode` (pipes, file descriptors, Windows ConPTY edge cases). Callers\n * that need to restore the previous mode should snapshot `input.isRaw`\n * BEFORE the call and pass the value to a second call to flip back.\n *\n * Use this helper to drop the now-redundant\n * `if (input.isTTY) input.setRawMode(...)` ceremony at every call site.\n */\nexport function setRawMode(input: NodeJS.ReadStream, mode: boolean): boolean {\n if (!input || input.isTTY !== true) return false;\n if (typeof input.setRawMode !== 'function') return false;\n input.setRawMode(mode);\n return true;\n}\n\n/**\n * Bracket installed by the interactive input reader while a `readline`\n * prompt is on screen. Out-of-band terminal writes — logger WARN/INFO\n * lines, async activity from the Telegram bridge, etc. — go to the same\n * physical terminal as the half-typed prompt but readline has no idea they\n * happened, so it never repaints. The result is the classic corruption the\n * user sees: every async line strands the in-progress draft as a fresh\n * scrollback row (sometimes with its cursor underline).\n *\n * The guard closes that gap. `suspend()` wipes the draft row so the message\n * prints clean; `resume()` repaints the prompt + draft (cursor preserved).\n * When no prompt is active the guard is `null` and writes pass straight\n * through — so agent-turn output (spinner, renderer) is untouched.\n */\nexport interface OutputLineGuard {\n /** Clear the current input row right before an out-of-band write. */\n suspend(): void;\n /** Repaint the prompt + in-progress draft right after the write. */\n resume(): void;\n}\n\nlet activeOutputGuard: OutputLineGuard | null = null;\n\n/**\n * Register (or clear, with `null`) the guard that brackets out-of-band\n * writes. Installed by {@link writeOut}/{@link writeErr} consumers — in\n * practice the CLI's readline input reader — only while a prompt is live.\n * Idempotent; the most recent caller wins.\n */\nexport function setOutputLineGuard(guard: OutputLineGuard | null): void {\n activeOutputGuard = guard;\n}\n\n/**\n * Stream-agnostic write primitive. Returns `false` when the stream is\n * missing or doesn't expose `write` so callers can degrade silently under\n * hostile host environments (closed pipe, mock injects `null`, test\n * replaces the stream with a stub).\n *\n * When an {@link OutputLineGuard} is installed (a readline prompt is on\n * screen) the write is bracketed by `suspend()`/`resume()` so the user's\n * half-typed input survives the interruption instead of being stranded in\n * scrollback. The guard's own redraw uses raw stream writes — never\n * `writeOut`/`writeErr` — so there is no re-entrancy here.\n *\n * **Not exported in the public API.** Exposed only inside `term.ts` for\n * `writeOut` / `writeErr` to share a single implementation. If a caller\n * needs to write to an arbitrary stream, they should call `writeOut` (or\n * `writeErr`) with an explicit `stream` argument — the named functions\n * are the public surface so the \"this is the standard error stream\"\n * intent stays visible at every call site.\n */\nfunction writeTo(\n s: string,\n stream: NodeJS.WriteStream | undefined,\n): boolean {\n if (!stream || typeof stream.write !== 'function') return false;\n const guard = activeOutputGuard;\n if (!guard) {\n stream.write(s);\n return true;\n }\n // A prompt is live — wipe the draft row, emit the message, repaint.\n guard.suspend();\n stream.write(s);\n guard.resume();\n return true;\n}\n\n/**\n * Write `s` to `stream` (defaults to `process.stdout`). Returns `false`\n * when the stream is missing or doesn't expose `write` so callers can\n * degrade silently under hostile host environments (closed pipe, mock\n * injects `null`, test replaces the stream with a stub).\n *\n * Why a helper:\n * 1. **Single seam for output capture in tests** — stub `writeOut` once\n * and assert on what the rest of the codebase intended to print,\n * without spying on `process.stdout.write` (which is brittle and\n * leaks across parallel test files).\n * 2. **Stream swap without grep** — routing the CLI's output to a\n * logger or `out.log` becomes a one-line change at process boot.\n * 3. **Defensive default** — closes the \"what if `process.stdout` is\n * `null`\" gap that currently exists at ~50 call sites that just\n * call `process.stdout.write(s)` and crash on certain Windows\n * redirect invocations.\n *\n * Call-site migration is staged: this commit introduces the helper, a\n * follow-up commit replaces the 50+ `process.stdout.write(...)` sites\n * with `writeOut(...)`. Until that migration lands, both forms coexist\n * and `writeOut` is the preferred form for new code.\n */\nexport function writeOut(\n s: string,\n stream: NodeJS.WriteStream = process.stdout,\n): boolean {\n return writeTo(s, stream);\n}\n\n/**\n * Symmetric partner of `writeOut` for the standard error stream. Same shape,\n * same defensive contract, same single-seam-for-tests story — just defaults to\n * `process.stderr` instead of `process.stdout`.\n *\n * Use this in code paths that emit error/diagnostic/warning text. Keeping\n * these two helpers split (rather than a single `writeTo(s, stream)`) means\n * the call site reads as a clear intent signal: \"I am writing an error\" vs.\n * \"I am writing a result\" — which matters for callers that decide between\n * stdout/stderr routing (e.g. `--quiet` flags, log-level filtering,\n * structured-log rewriters that fork on stream).\n *\n * Stderr writes from the core logger (see `infrastructure/logger.ts`) and from\n * the TUI guard (see `tui/run-tui.ts`) used to call `process.stderr.write`\n * directly. Routing them through this helper lets tests stub the stream at\n * one boundary and lets future logging middleware (e.g. a JSON-line rewriter)\n * swap the destination for the entire process in one place.\n */\nexport function writeErr(\n s: string,\n stream: NodeJS.WriteStream = process.stderr,\n): boolean {\n return writeTo(s, stream);\n}\n","import { isStdoutTTY } from './term.js';\n\nconst isColorTty = (): boolean => {\n if (envFlag(process.env.NO_COLOR)) return false;\n if (envFlag(process.env.FORCE_COLOR)) return true;\n return isStdoutTTY();\n};\n\nfunction envFlag(value: string | undefined): boolean {\n if (value === undefined) return false;\n if (value.trim() === '') return false;\n return !/^(0|false|no|off)$/i.test(value.trim());\n}\n\nconst COLOR = isColorTty();\n\nconst wrap =\n (open: string, close: string) =>\n (s: string): string =>\n COLOR ? `\\x1b[${open}m${s}\\x1b[${close}m` : s;\n\nexport const color = {\n reset: wrap('0', '0'),\n bold: wrap('1', '22'),\n dim: wrap('2', '22'),\n italic: wrap('3', '23'),\n underline: wrap('4', '24'),\n red: wrap('31', '39'),\n green: wrap('32', '39'),\n yellow: wrap('33', '39'),\n blue: wrap('34', '39'),\n magenta: wrap('35', '39'),\n cyan: wrap('36', '39'),\n gray: wrap('90', '39'),\n amber: wrap('38;5;214', '39'),\n pink: wrap('38;5;205', '39'),\n bgRed: wrap('41', '49'),\n bgGreen: wrap('42', '49'),\n};\n\nexport function stripAnsi(s: string): string {\n return s.replace(\n // biome-ignore lint/suspicious/noControlCharactersInRegex: ANSI escape regex\n /\\x1b\\[[0-9;]*[A-Za-z]/g,\n '',\n );\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport type { LogLevel, Logger } from '../types/logger.js';\nimport { color } from '../utils/color.js';\nimport { writeErr } from '../utils/term.js';\n\nconst LEVEL_RANK: Record<LogLevel, number> = {\n error: 0,\n warn: 1,\n info: 2,\n debug: 3,\n trace: 4,\n};\n\nconst COLORS: Record<LogLevel, (s: string) => string> = {\n error: color.red,\n warn: color.yellow,\n info: color.cyan,\n debug: color.gray,\n trace: color.dim,\n};\n\nconst LOG_LEVELS = new Set<LogLevel>(['error', 'warn', 'info', 'debug', 'trace']);\nconst LOG_FORMATS = new Set<string>(['pretty', 'json']);\n\nexport type LogFormat = 'pretty' | 'json';\n\nexport interface DefaultLoggerOptions {\n level?: LogLevel | undefined;\n file?: string | undefined;\n /**\n * @deprecated Use `format: 'json'` instead. Kept for backward compat\n * with existing callers but has no effect on output — the `format`\n * option controls whether stderr receives pretty-printed or JSON lines.\n */\n pretty?: boolean | undefined;\n /** Output format for stderr. `pretty` (colored, human-readable) or `json` (machine-parseable). Defaults to `WRONGSTACK_LOG_FORMAT` env var, falling back to `pretty`. */\n format?: LogFormat | undefined;\n bindings?: Record<string, unknown>;\n /**\n * When false, suppress stderr output entirely — only write to the log\n * file (if configured). Use this in TUI mode so plugin/library log\n * messages don't interleave with Ink's terminal rendering.\n * Default: true (stderr output is enabled).\n */\n stderr?: boolean | undefined;\n /**\n * Rotate the log file once it exceeds this many bytes: the current file is\n * renamed to `<file>.1` (replacing any previous one) and a fresh file\n * starts. Bounds total disk to ~2× this value. Default 10 MB.\n */\n maxFileBytes?: number | undefined;\n}\n\nexport class DefaultLogger implements Logger {\n /** How many file writes between rotation size checks (statSync is not free). */\n private static readonly ROTATE_CHECK_EVERY = 100;\n\n level: LogLevel;\n private readonly file?: string | undefined;\n private readonly bindings: Record<string, unknown>;\n private readonly format: LogFormat;\n private readonly stderr: boolean;\n private readonly maxFileBytes: number;\n private writesSinceRotateCheck = 0;\n\n constructor(opts: DefaultLoggerOptions = {}) {\n this.level = opts.level ?? parseLogLevel(process.env.WRONGSTACK_LOG_LEVEL);\n this.file = opts.file;\n this.bindings = opts.bindings ?? {};\n this.format = opts.format ?? parseLogFormat(process.env.WRONGSTACK_LOG_FORMAT);\n this.stderr = opts.stderr !== false; // default true\n this.maxFileBytes = opts.maxFileBytes ?? 10 * 1024 * 1024;\n if (this.file) {\n try {\n fs.mkdirSync(path.dirname(this.file), { recursive: true });\n } catch {\n // best-effort\n }\n }\n }\n\n error(msg: string, ctx?: unknown): void {\n this.log('error', msg, ctx);\n }\n warn(msg: string, ctx?: unknown): void {\n this.log('warn', msg, ctx);\n }\n info(msg: string, ctx?: unknown): void {\n this.log('info', msg, ctx);\n }\n debug(msg: string, ctx?: unknown): void {\n this.log('debug', msg, ctx);\n }\n trace(msg: string, ctx?: unknown): void {\n this.log('trace', msg, ctx);\n }\n\n child(bindings: Record<string, unknown>): Logger {\n return new DefaultLogger({\n level: this.level,\n file: this.file,\n format: this.format,\n stderr: this.stderr,\n maxFileBytes: this.maxFileBytes,\n bindings: { ...this.bindings, ...bindings },\n });\n }\n\n /**\n * Size-based rotation: when the file outgrows `maxFileBytes`, rename it to\n * `<file>.1` (dropping the previous `.1`) so the live file restarts empty.\n * Checked on the first write and every ROTATE_CHECK_EVERY writes after.\n * Best-effort: a rename can fail on Windows while another process holds\n * the file — the next check retries. Multiple processes appending to the\n * same log all run this check; whoever crosses the threshold first wins.\n */\n private maybeRotate(file: string): void {\n if (this.writesSinceRotateCheck++ % DefaultLogger.ROTATE_CHECK_EVERY !== 0) return;\n try {\n const st = fs.statSync(file);\n if (st.size < this.maxFileBytes) return;\n fs.rmSync(`${file}.1`, { force: true });\n fs.renameSync(file, `${file}.1`);\n } catch {\n // file missing, locked, or raced by another process — ignore\n }\n }\n\n private log(level: LogLevel, msg: string, ctx?: unknown): void {\n const r = LEVEL_RANK[level];\n const allowed = LEVEL_RANK[this.level];\n if (r > allowed) return;\n const ts = new Date().toISOString();\n const entry: Record<string, unknown> = { ts, level, msg, ...this.bindings };\n if (ctx !== undefined) {\n entry.ctx = ctx instanceof Error ? { message: ctx.message, stack: ctx.stack } : ctx;\n }\n // Disk: JSON line\n if (this.file) {\n try {\n this.maybeRotate(this.file);\n fs.appendFileSync(this.file, `${JSON.stringify(entry)}\\n`);\n } catch {\n // ignore\n }\n }\n // Stderr: pretty or json. Suppressed when this.stderr is false (TUI mode)\n // so plugin/library log messages don't interleave with Ink's rendering.\n if (!this.stderr) return;\n if (this.format === 'json') {\n writeErr(`${JSON.stringify(entry)}\\n`);\n } else {\n const head = `${color.dim(ts)} ${COLORS[level](level.toUpperCase().padEnd(5))} ${msg}`;\n if (ctx !== undefined) {\n writeErr(`${head} ${formatCtx(ctx)}\\n`);\n } else {\n writeErr(`${head}\\n`);\n }\n }\n }\n}\n\nfunction parseLogLevel(raw: string | undefined): LogLevel {\n return raw && LOG_LEVELS.has(raw as LogLevel) ? (raw as LogLevel) : 'info';\n}\n\nfunction parseLogFormat(raw: string | undefined): LogFormat {\n return raw && LOG_FORMATS.has(raw) ? (raw as LogFormat) : 'pretty';\n}\n\nfunction formatCtx(ctx: unknown): string {\n if (ctx instanceof Error) return color.dim(ctx.message);\n if (typeof ctx === 'string') return color.dim(ctx);\n try {\n return color.dim(JSON.stringify(ctx));\n } catch {\n return color.dim(String(ctx));\n }\n}\n\n/**\n * A logger that silently discards all messages. Used during boot before\n * the real logger is configured, and in test contexts where logging\n * would be noise.\n */\nexport const noOpLogger: Logger = {\n // 'error' is the quietest level the Logger contract offers; the methods\n // discard everything regardless, this only matters to level checks.\n level: 'error',\n error: () => {},\n warn: () => {},\n info: () => {},\n debug: () => {},\n trace: () => {},\n child: () => noOpLogger,\n};\n","import * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport type { PathResolver } from '../types/path-resolver.js';\n\nconst PROJECT_MARKERS = [\n '.git',\n 'package.json',\n 'pnpm-workspace.yaml',\n 'go.mod',\n 'Cargo.toml',\n 'pyproject.toml',\n // Use AGENTS.md, not the bare .wrongstack directory. A bare .wrongstack/\n // directory can be the global config directory (~/.wrongstack), which is\n // NOT a project marker. Only .wrongstack/AGENTS.md signals a real\n // WrongStack project.\n '.wrongstack/AGENTS.md',\n];\n\nexport class DefaultPathResolver implements PathResolver {\n readonly projectRoot: string;\n readonly cwd: string;\n\n constructor(cwd: string = process.cwd()) {\n this.cwd = path.resolve(cwd);\n this.projectRoot = this.detectProjectRoot(this.cwd);\n }\n\n detectProjectRoot(start: string): string {\n let dir = path.resolve(start);\n const root = path.parse(dir).root;\n const home = path.resolve(os.homedir());\n const startPath = path.resolve(start);\n while (dir !== root) {\n // Don't walk past the user home directory. Home often has stray\n // markers (.git for dotfile tracking, package.json from global\n // tooling) that are unrelated to the actual working directory.\n // When cwd IS home we still check markers there — this guard\n // only fires during the upward walk from a subdirectory.\n if (dir === home && dir !== startPath) {\n break;\n }\n for (const marker of PROJECT_MARKERS) {\n try {\n fs.accessSync(path.join(dir, marker));\n return dir;\n } catch {\n // continue\n }\n }\n const parent = path.dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n return startPath;\n }\n\n resolve(input: string): string {\n const abs = path.isAbsolute(input) ? input : path.resolve(this.cwd, input);\n let real: string;\n try {\n real = fs.realpathSync(abs);\n } catch {\n // path doesn't exist yet; normalize without resolving symlinks\n real = path.normalize(abs);\n }\n return real;\n }\n\n isInsideRoot(absPath: string): boolean {\n const normalized = path.normalize(absPath);\n const root = path.normalize(this.projectRoot);\n if (normalized === root) return true;\n const rel = path.relative(root, normalized);\n return !rel.startsWith('..') && !path.isAbsolute(rel);\n }\n\n ensureInsideRoot(absPath: string): string {\n const resolved = this.resolve(absPath);\n if (!this.isInsideRoot(resolved)) {\n // Render the input as a project-relative-looking string when possible\n // so the error message can flow through telemetry / LLM transcripts\n // without leaking the absolute project root layout.\n const display = path.isAbsolute(absPath) ? path.basename(absPath) : absPath;\n const err = new Error(`Path \"${display}\" resolves outside the project root`);\n // Keep the full information available to programmatic callers; only\n // the user-facing `message` is sanitized.\n (err as Error & { fullPath?: string | undefined; projectRoot?: string | undefined }).fullPath = absPath;\n (err as Error & { fullPath?: string | undefined; projectRoot?: string | undefined }).projectRoot = this.projectRoot;\n throw err;\n }\n return resolved;\n }\n}\n","import type { EventBus } from '../kernel/events.js';\nimport type { ModelsRegistry, ResolvedModel } from '../types/models-registry.js';\nimport type { Usage } from '../types/provider.js';\nimport type { CacheStats, TokenCounter } from '../types/token-counter.js';\n\ninterface PriceEntry {\n input?: number | undefined;\n output?: number | undefined;\n cacheRead?: number | undefined;\n cacheWrite?: number | undefined;\n cacheWrite5m?: number | undefined;\n cacheWrite1h?: number | undefined;\n}\n\nconst PRICE_CACHE_MAX_SIZE = 100;\n\n/**\n * Token counter that derives pricing from the ModelsRegistry instead of a\n * hardcoded table. If a model is unknown to the registry (or the registry is\n * unavailable) the counter still tracks token totals but reports zero cost.\n */\nexport class DefaultTokenCounter implements TokenCounter {\n private input = 0;\n private output = 0;\n private cacheRead = 0;\n private cacheWrite = 0;\n private costInput = 0;\n private costOutput = 0;\n private readonly registry?: ModelsRegistry | undefined;\n private readonly providerId?: string | undefined;\n private readonly events?: EventBus | undefined;\n private priceCache = new Map<string, PriceEntry>();\n /** Most recently accounted request's tokens. Used for per-request context pressure. */\n private lastInput = 0;\n private lastCacheRead = 0;\n\n constructor(opts: { registry?: ModelsRegistry | undefined; providerId?: string | undefined; events?: EventBus | undefined } = {}) {\n this.registry = opts.registry;\n this.providerId = opts.providerId;\n this.events = opts.events;\n }\n\n account(usage: Usage, model?: string): void {\n this.input += usage.input;\n this.output += usage.output;\n this.cacheRead += usage.cacheRead ?? 0;\n this.cacheWrite += usage.cacheWrite ?? 0;\n // Snapshot per-request tokens for context pressure tracking.\n this.lastInput = usage.input;\n this.lastCacheRead = usage.cacheRead ?? 0;\n\n const price = model ? this.priceCache.get(model) : undefined;\n if (price) {\n this.applyPrice(usage, price);\n this.emitAccounted();\n return;\n }\n\n if (this.registry && this.providerId && model) {\n // Evict oldest entry when cache is full before async lookup.\n if (this.priceCache.size >= PRICE_CACHE_MAX_SIZE) {\n const keys = [...this.priceCache.keys()];\n this.priceCache.delete(keys[0] ?? '');\n }\n // Async lookup — populate cache, but don't block this call.\n void this.registry\n .getModel(this.providerId, model)\n .then((m) => {\n if (m) {\n const p = priceFromModel(m);\n this.priceCache.set(model, p);\n this.applyPrice(usage, p);\n }\n // Token totals are authoritative even when pricing is unresolved.\n // Emit after the lookup settles so live UIs update for unknown models\n // without double-emitting when pricing is resolved.\n this.emitAccounted();\n })\n .catch(() => {\n // Emit so observability tooling can detect unknown models.\n this.events?.emit('token.cost_estimate_unavailable', { model: model ?? '<unknown>' });\n this.emitAccounted();\n return undefined;\n });\n return;\n }\n\n // No pricing source exists. Still emit token totals so live UIs do not stay\n // at 0 just because cost cannot be estimated.\n this.emitAccounted();\n }\n\n /** Synchronous variant for code paths that have already resolved the model. */\n accountWithModel(usage: Usage, resolved: ResolvedModel): void {\n this.input += usage.input;\n this.output += usage.output;\n this.cacheRead += usage.cacheRead ?? 0;\n this.cacheWrite += usage.cacheWrite ?? 0;\n // Snapshot per-request tokens for context pressure tracking.\n this.lastInput = usage.input;\n this.lastCacheRead = usage.cacheRead ?? 0;\n const price = priceFromModel(resolved);\n if (this.priceCache.size >= PRICE_CACHE_MAX_SIZE) {\n const keys = [...this.priceCache.keys()];\n this.priceCache.delete(keys[0] ?? '');\n }\n this.priceCache.set(resolved.modelId, price);\n this.applyPrice(usage, price);\n this.emitAccounted();\n }\n\n total(): Usage {\n return {\n input: this.input,\n output: this.output,\n cacheRead: this.cacheRead,\n cacheWrite: this.cacheWrite,\n };\n }\n\n currentRequestTokens(): { input: number; cacheRead: number } {\n return { input: this.lastInput, cacheRead: this.lastCacheRead };\n }\n\n estimateCost(): { input: number; output: number; total: number; currency: 'USD' } {\n return {\n input: round4(this.costInput),\n output: round4(this.costOutput),\n total: round4(this.costInput + this.costOutput),\n currency: 'USD',\n };\n }\n\n cacheStats(): CacheStats {\n // Hit ratio: cacheRead / (cacheRead + input). `input` from the provider\n // is the count of fresh-token reads, so this answers \"what fraction of\n // the prompt did we get for the cache price?\"\n const denom = this.cacheRead + this.input;\n return {\n readTokens: this.cacheRead,\n writeTokens: this.cacheWrite,\n hitRatio: denom === 0 ? 0 : this.cacheRead / denom,\n };\n }\n\n /** Invalidate cached prices so the next account() call fetches fresh data. */\n invalidateCache(): void {\n this.priceCache.clear();\n }\n\n private emitAccounted(): void {\n this.events?.emit('token.accounted', {\n usage: this.total(),\n cost: { input: this.costInput, output: this.costOutput, total: this.costInput + this.costOutput },\n });\n }\n\n reset(): void {\n this.input = 0;\n this.output = 0;\n this.cacheRead = 0;\n this.cacheWrite = 0;\n this.costInput = 0;\n this.costOutput = 0;\n this.lastInput = 0;\n this.lastCacheRead = 0;\n this.emitAccounted();\n }\n\n private applyPrice(usage: Usage, price: PriceEntry): void {\n if (price.input) this.costInput += (usage.input / 1_000_000) * price.input;\n if (price.output) this.costOutput += (usage.output / 1_000_000) * price.output;\n if (usage.cacheRead && price.cacheRead) {\n this.costInput += (usage.cacheRead / 1_000_000) * price.cacheRead;\n }\n const hasCacheWriteSplit = usage.cacheWrite5m !== undefined || usage.cacheWrite1h !== undefined;\n const cacheWrite5m = usage.cacheWrite5m ?? (hasCacheWriteSplit ? 0 : usage.cacheWrite);\n const cacheWrite1h = usage.cacheWrite1h ?? 0;\n if (cacheWrite5m && (price.cacheWrite5m ?? price.cacheWrite)) {\n this.costInput += (cacheWrite5m / 1_000_000) * (price.cacheWrite5m ?? price.cacheWrite ?? 0);\n }\n if (cacheWrite1h && (price.cacheWrite1h ?? price.cacheWrite)) {\n this.costInput += (cacheWrite1h / 1_000_000) * (price.cacheWrite1h ?? price.cacheWrite ?? 0);\n }\n }\n}\n\nfunction priceFromModel(m: ResolvedModel): PriceEntry {\n return {\n input: m.cost?.input,\n output: m.cost?.output,\n cacheRead: m.cost?.cache_read,\n cacheWrite: m.cost?.cache_write,\n cacheWrite5m: m.cost?.cache_write_5m ?? m.cost?.cache_write,\n cacheWrite1h: m.cost?.cache_write_1h ?? (m.cost?.input !== undefined ? m.cost.input * 2 : undefined),\n };\n}\n\nfunction round4(n: number): number {\n return Math.round(n * 10_000) / 10_000;\n}\n","import type { MCPServerConfig } from '../types/config.js';\n\n/**\n * Built-in MCP server presets available to all WrongStack users out of the box.\n * These servers must be explicitly enabled in config (disabled by default).\n *\n * To enable: set `mcpServers: { serverName: { enabled: true } }` in your config.\n *\n * Some servers require environment variables or additional config — see notes below.\n *\n * Transport types:\n * stdio — spawns a local npm package binary via child_process\n * sse — HTTP SSE endpoint (client POSTs requests)\n * streamable-http — session-based HTTP with NDJSON responses\n */\n\n/** Filesystem access: read, write, list, search, tree. Good for exploring projects. */\nexport const filesystemServer = (): MCPServerConfig => ({\n name: 'filesystem',\n description: 'Read, write, and navigate the local filesystem (read-heavy tools)',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-filesystem', '.'],\n permission: 'confirm',\n});\n\n/** GitHub API: issues, PRs, repos, search, file operations. Requires GITHUB_PERSONAL_ACCESS_TOKEN. */\nexport const githubServer = (): MCPServerConfig => ({\n name: 'github',\n description:\n 'GitHub API — issues, PRs, repos, search, file ops (requires GITHUB_PERSONAL_ACCESS_TOKEN)',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-github'],\n permission: 'confirm',\n});\n\n/**\n * Context7 — codebase-aware documentation and Q&A using context from your code.\n * Live documentation for any library, grounded in your actual versions.\n */\nexport const context7Server = (): MCPServerConfig => ({\n name: 'context7',\n description: 'Codebase-aware documentation and Q&A (context7.ai)',\n transport: 'streamable-http',\n url: 'https://mcp.context7.com/mcp',\n permission: 'confirm',\n});\n\n/**\n * Brave Search — web search via Brave Browser's API.\n * Requires BRAVE_SEARCH_API_KEY. Free tier: 2,000 queries/month.\n * Sign up at https://api.search.brave.com/\n */\nexport const braveSearchServer = (): MCPServerConfig => ({\n name: 'brave-search',\n description: 'Web search (Brave). Requires BRAVE_SEARCH_API_KEY — free tier 2k queries/month',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-brave-search'],\n permission: 'confirm',\n});\n\n/**\n * Block (Block, Inc.) — Postgres database access via SQL.\n * Useful for running queries against a connected database during development.\n */\nexport const blockServer = (): MCPServerConfig => ({\n name: 'block',\n description: 'Postgres database access via SQL (Block MCP server)',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-block'],\n permission: 'confirm',\n});\n\n/**\n * EverArt — AI image generation via various providers.\n * Requires EVERART_API_KEY.\n */\nexport const everArtServer = (): MCPServerConfig => ({\n name: 'everart',\n description: 'AI image generation (EverArt). Requires EVERART_API_KEY',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-everart'],\n permission: 'confirm',\n});\n\n/**\n * Slack — messaging, channels, search.\n * Requires SLACK_BOT_TOKEN and either SLACK_TEAM_ID or SLACK_USER_TOKEN.\n */\nexport const slackServer = (): MCPServerConfig => ({\n name: 'slack',\n description: 'Slack — messaging, channels, search. Requires SLACK_BOT_TOKEN + SLACK_TEAM_ID',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-slack'],\n permission: 'confirm',\n});\n\n/**\n * AWS knowledge base — EC2, S3, Lambda, IAM, CloudFormation, cost management.\n * Requires AWS access key + secret in environment.\n */\nexport const awsServer = (): MCPServerConfig => ({\n name: 'aws',\n description: 'AWS — EC2, S3, Lambda, IAM, CloudFormation, costs. Requires AWS credentials',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-aws'],\n permission: 'confirm',\n});\n\n/**\n * Google Maps — directions, distance matrix, geocoding, places.\n * Requires GOOGLE_MAPS_API_KEY.\n */\nexport const googleMapsServer = (): MCPServerConfig => ({\n name: 'google-maps',\n description: 'Google Maps — directions, geocoding, places. Requires GOOGLE_MAPS_API_KEY',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-google-maps'],\n permission: 'confirm',\n});\n\n/** Sentinel — security vulnerability scanning (sentinel-labs). */\nexport const sentinelServer = (): MCPServerConfig => ({\n name: 'sentinel',\n description: 'Security vulnerability scanning (Sentinel)',\n transport: 'streamable-http',\n url: 'https://mcp.sentinel.ai',\n permission: 'deny', // security tool — require explicit confirmation\n});\n\n/**\n * Z.AI Vision MCP — image understanding fallback for text-only models.\n * Requires Z_AI_API_KEY. Tools are read-only and safe to run automatically.\n */\nexport const zaiVisionServer = (): MCPServerConfig => ({\n name: 'zai-vision',\n description: 'Z.AI Vision MCP — image analysis and screenshot understanding',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@z_ai/mcp-server@latest'],\n env: { Z_AI_MODE: 'ZAI' },\n allowedTools: [\n 'image_analysis',\n 'extract_text_from_screenshot',\n 'diagnose_error_screenshot',\n 'understand_technical_diagram',\n 'analyze_data_visualization',\n 'ui_diff_check',\n ],\n permission: 'auto',\n});\n\n/**\n * Playwright — browser automation: navigate, click, type, screenshot, evaluate JS.\n * Spawns a headless Chromium browser via @modelcontextprotocol/server-playwright.\n * Tools can read and interact with live web pages — permission defaults to\n * `confirm` because form submission / DOM mutation is possible.\n */\nexport const playwrightServer = (): MCPServerConfig => ({\n name: 'playwright',\n description:\n 'Browser automation — navigate, screenshot, click, type, evaluate JS (headless Chromium)',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-playwright'],\n permission: 'confirm',\n});\n\n/**\n * MiniMax Token Plan MCP — web_search + understand_image.\n * This preset exposes only the read-only image understanding tool by default.\n * Requires MINIMAX_API_KEY and uvx on PATH.\n */\nexport const miniMaxVisionServer = (): MCPServerConfig => ({\n name: 'minimax-vision',\n description: 'MiniMax MCP — image understanding via understand_image',\n transport: 'stdio',\n command: 'uvx',\n args: ['minimax-coding-plan-mcp', '-y'],\n env: {\n MINIMAX_MCP_BASE_PATH: './.wrongstack/minimax-output',\n MINIMAX_API_HOST: 'https://api.minimax.io',\n MINIMAX_API_RESOURCE_MODE: 'url',\n },\n allowedTools: ['understand_image'],\n permission: 'auto',\n});\n\n/**\n * SSH Manager — remote SSH execution, file transfer, tunnels, health checks, and deployment ops.\n * Server credentials are intentionally NOT embedded here. Configure hosts via mcp-ssh-manager's\n * env/TOML config (for example SSH_SERVER_<NAME>_HOST, USER, KEYPATH/PASSWORD) or ssh-agent.\n */\nexport const sshManagerServer = (): MCPServerConfig => ({\n name: 'ssh',\n description:\n 'Remote SSH management — execute commands, transfer files, tunnels, health checks (mcp-ssh-manager)',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', 'mcp-ssh-manager'],\n env: {\n MCP_SSH_COMPACT_JSON: 'true',\n MCP_SSH_DEFAULT_TIMEOUT: '120000',\n },\n permission: 'confirm',\n requestTimeoutMs: 180_000,\n});\n\n/** Everything bundled — full set of built-in servers. Useful for `wstack mcp add --all`. */\nexport const allServers = (): Record<string, MCPServerConfig> => ({\n filesystem: { ...filesystemServer(), enabled: false },\n github: { ...githubServer(), enabled: false },\n context7: { ...context7Server(), enabled: false },\n 'brave-search': { ...braveSearchServer(), enabled: false },\n block: { ...blockServer(), enabled: false },\n everart: { ...everArtServer(), enabled: false },\n slack: { ...slackServer(), enabled: false },\n aws: { ...awsServer(), enabled: false },\n 'google-maps': { ...googleMapsServer(), enabled: false },\n sentinel: { ...sentinelServer(), enabled: false },\n 'zai-vision': { ...zaiVisionServer(), enabled: false },\n 'minimax-vision': { ...miniMaxVisionServer(), enabled: false },\n playwright: { ...playwrightServer(), enabled: false },\n ssh: { ...sshManagerServer(), enabled: false },\n});\n","/** Assert a value is neither null nor undefined. Throws if it is.\n * Useful after optional chaining and indexed access when the\n * control flow guarantees the value exists but TypeScript can't\n * prove it (e.g. after a check on a related field). */\nexport function expectDefined<T>(value: T | null | undefined, label?: string): T {\n if (value === null || value === undefined) {\n const err = new Error(label ? `Expected ${label} to be defined` : 'Expected value to be defined');\n err.name = 'ExpectDefinedError';\n throw err;\n }\n return value;\n}\n","import { expectDefined } from './expect-defined.js';\nimport type { ContentBlock, ToolResultBlock, ToolUseBlock } from '../types/blocks.js';\nimport type { Message } from '../types/messages.js';\nexport interface MessageRepairReport {\n changed: boolean;\n removedToolUses: string[];\n removedToolResults: string[];\n removedMessages: number;\n}\n\nexport interface MessageRepairResult {\n messages: Message[];\n report: MessageRepairReport;\n}\n\n/**\n * Repair provider-level tool-call adjacency invariants.\n *\n * Anthropic requires every assistant `tool_use` block to have a matching\n * `tool_result` block in the immediately following user message. Manual\n * context surgery (summary/prune) can cut through the middle of such an\n * exchange. This function removes only the now-orphaned protocol blocks,\n * preserving surrounding text/images/thinking blocks where possible.\n */\nexport function repairToolUseAdjacency(messages: Message[]): MessageRepairResult {\n const removedToolUses: string[] = [];\n const removedToolResults: string[] = [];\n let removedMessages = 0;\n let changed = false;\n const out: Message[] = [];\n\n for (let i = 0; i < messages.length; i++) {\n const original = expectDefined(messages[i]);\n let msg = original;\n\n if (hasToolUse(msg)) {\n const nextIds = toolResultIds(messages[i + 1]);\n const filtered = mapContent(msg, (blocks) => {\n const next: ContentBlock[] = [];\n for (const block of blocks) {\n if (block.type === 'tool_use' && !nextIds.has(block.id)) {\n removedToolUses.push(block.id);\n changed = true;\n continue;\n }\n next.push(block);\n }\n return next;\n });\n msg = filtered ?? msg;\n }\n\n if (hasToolResult(msg)) {\n const allowed = toolUseIds(out[out.length - 1]);\n const filtered = mapContent(msg, (blocks) => {\n const next: ContentBlock[] = [];\n for (const block of blocks) {\n if (block.type === 'tool_result' && !allowed.has(block.tool_use_id)) {\n removedToolResults.push(block.tool_use_id);\n changed = true;\n continue;\n }\n next.push(block);\n }\n return next;\n });\n msg = filtered ?? msg;\n }\n\n if (isEmptyMessage(msg)) {\n removedMessages++;\n changed = true;\n continue;\n }\n out.push(msg);\n }\n\n return {\n messages: changed ? out : messages,\n report: { changed, removedToolUses, removedToolResults, removedMessages },\n };\n}\n\nfunction hasToolUse(msg: Message | undefined): boolean {\n return contentBlocks(msg).some((b): b is ToolUseBlock => b.type === 'tool_use');\n}\n\nfunction hasToolResult(msg: Message | undefined): boolean {\n return contentBlocks(msg).some((b): b is ToolResultBlock => b.type === 'tool_result');\n}\n\nfunction toolUseIds(msg: Message | undefined): Set<string> {\n const ids = new Set<string>();\n if (!msg || msg.role !== 'assistant') return ids;\n for (const block of contentBlocks(msg)) {\n if (block.type === 'tool_use') ids.add(block.id);\n }\n return ids;\n}\n\nfunction toolResultIds(msg: Message | undefined): Set<string> {\n const ids = new Set<string>();\n if (!msg || msg.role !== 'user') return ids;\n for (const block of contentBlocks(msg)) {\n if (block.type === 'tool_result') ids.add(block.tool_use_id);\n }\n return ids;\n}\n\nfunction contentBlocks(msg: Message | undefined): ContentBlock[] {\n return msg && Array.isArray(msg.content) ? msg.content : [];\n}\n\nfunction mapContent(\n msg: Message,\n fn: (blocks: ContentBlock[]) => ContentBlock[],\n): Message | null {\n if (!Array.isArray(msg.content)) return msg;\n const next = fn(msg.content);\n if (next.length === msg.content.length && next.every((b, idx) => b === msg.content[idx])) {\n return msg;\n }\n return { ...msg, content: next };\n}\n\nfunction isEmptyMessage(msg: Message): boolean {\n if (typeof msg.content === 'string') return msg.content.trim().length === 0;\n return msg.content.length === 0;\n}\n","import type { JSONSchema } from '../types/tool.js';\n\nexport interface ToolWireDefinitionLike {\n name: string;\n description?: string | undefined;\n inputSchema: unknown;\n}\n\nexport interface CompactToolDefinitionForWireOptions {\n /** Top-level tool description budget. */\n descriptionMaxChars?: number | undefined;\n /** Per-JSON-Schema `description` annotation budget. */\n schemaDescriptionMaxChars?: number | undefined;\n}\n\nexport interface CompactWireToolDefinition {\n name: string;\n description: string;\n inputSchema: Record<string, unknown>;\n}\n\nconst TOOL_DESCRIPTION_MAX_CHARS = 640;\nconst SCHEMA_DESCRIPTION_MAX_CHARS = 180;\n\nconst compactCache = new WeakMap<object, CompactWireToolDefinition>();\n\n/**\n * Return the provider-wire version of a tool definition.\n *\n * Tool schemas remain structurally intact: validation keywords, property\n * names, required fields, enum values, and nested shapes are preserved. The\n * only reduction is on human prose annotations (`description`), which are the\n * largest repeated cost in provider tool declarations.\n */\nexport function compactToolDefinitionForWire(\n tool: ToolWireDefinitionLike,\n opts: CompactToolDefinitionForWireOptions = {},\n): CompactWireToolDefinition {\n const useDefaultOptions =\n opts.descriptionMaxChars === undefined && opts.schemaDescriptionMaxChars === undefined;\n if (useDefaultOptions && typeof tool === 'object' && tool !== null) {\n const cached = compactCache.get(tool);\n if (cached) return cached;\n }\n\n const compact: CompactWireToolDefinition = {\n name: tool.name,\n description: compactDescription(\n tool.description ?? '',\n opts.descriptionMaxChars ?? TOOL_DESCRIPTION_MAX_CHARS,\n ),\n inputSchema: compactSchemaDescriptions(\n tool.inputSchema,\n opts.schemaDescriptionMaxChars ?? SCHEMA_DESCRIPTION_MAX_CHARS,\n ),\n };\n\n if (useDefaultOptions && typeof tool === 'object' && tool !== null) {\n compactCache.set(tool, compact);\n }\n return compact;\n}\n\nexport function compactSchemaDescriptions(\n schema: unknown,\n maxDescriptionChars = SCHEMA_DESCRIPTION_MAX_CHARS,\n): Record<string, unknown> {\n const compact = compactSchemaNode(schema, maxDescriptionChars);\n return isRecord(compact) ? compact : { type: 'object', properties: {} };\n}\n\nfunction compactSchemaNode(node: unknown, maxDescriptionChars: number): unknown {\n if (Array.isArray(node)) {\n return node.map((item) => compactSchemaNode(item, maxDescriptionChars));\n }\n if (!isRecord(node)) return node;\n\n const out: JSONSchema = {};\n for (const [key, value] of Object.entries(node)) {\n if (key === 'description' && typeof value === 'string') {\n out[key] = compactDescription(value, maxDescriptionChars);\n } else {\n out[key] = compactSchemaNode(value, maxDescriptionChars);\n }\n }\n return out;\n}\n\nfunction compactDescription(text: string, maxChars: number): string {\n const normalized = text.replace(/\\s+/g, ' ').trim();\n if (normalized.length <= maxChars) return normalized;\n if (maxChars <= 20) return normalized.slice(0, maxChars);\n\n const hardLimit = maxChars - 12;\n const boundary = findSemanticBoundary(normalized, hardLimit);\n const head = normalized.slice(0, boundary > 0 ? boundary : hardLimit).trimEnd();\n return `${head} ...`;\n}\n\nfunction findSemanticBoundary(text: string, limit: number): number {\n const punctuation = Math.max(\n text.lastIndexOf('. ', limit),\n text.lastIndexOf('; ', limit),\n text.lastIndexOf(': ', limit),\n );\n if (punctuation >= Math.floor(limit * 0.45)) return punctuation + 1;\n\n const comma = text.lastIndexOf(', ', limit);\n if (comma >= Math.floor(limit * 0.6)) return comma + 1;\n\n const space = text.lastIndexOf(' ', limit);\n return space >= Math.floor(limit * 0.6) ? space : limit;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return !!value && typeof value === 'object' && !Array.isArray(value);\n}\n","import type { Message } from '../types/messages.js';\nimport { compactToolDefinitionForWire } from './tool-wire-compact.js';\n\n/**\n * Shared token estimation with JSON.stringify caching.\n * Avoids repeated stringification of tool input objects.\n *\n * ## Calibration\n *\n * `estimateRequestTokens` uses a fixed 3.5 chars/token heuristic — a\n * conservative overestimate that prevents underestimation but reduces\n * accuracy. After each API call, call `recordActualUsage()` with the\n * real `usage.input` from the provider response. The module maintains a\n * rolling average of `actual / estimated` ratio (EWM, α=0.3) and\n * applies it to subsequent calls via `estimateRequestTokensCalibrated`.\n *\n * Calibration is per-module (shared across all callers), which is\n * sufficient: the chars/token ratio is a property of the tokenizer,\n * not the model. Uncalibrated calls (before any samples, or when\n * `recordActualUsage` is not called) fall back to the uncalibrated\n * estimate so nothing breaks.\n */\n\nconst RoughTokenEstimate = (text: string, charsPerToken = 3.5): number =>\n Math.max(1, Math.ceil(text.length / charsPerToken));\n\n/** Calibration state: actual/estimated ratio via exponential weighted moving average. */\ninterface CalState {\n ratio: number; // current calibration multiplier (actual / estimated)\n count: number; // number of samples recorded\n prevEst: number; // estimated tokens from the most recent estimateRequestTokens call\n}\n\n/** EWM α — higher = faster adaptation, more volatile. */\nconst CAL_ALPHA = 0.3;\n\n/**\n * Calibration is keyed so that, in a multi-agent / model-switching process,\n * each (provider, model) tokenizer gets its own ratio instead of all of them\n * collapsing onto one shared number. Callers that don't pass a key use the\n * shared `__global__` bucket — that preserves the original single-session\n * behavior and keeps all existing call sites working unchanged.\n */\nconst CALIBRATION_GLOBAL_KEY = '__global__';\nconst _cals = new Map<string, CalState>();\n\nfunction calState(key: string): CalState {\n let state = _cals.get(key);\n if (!state) {\n state = { ratio: 1.0, count: 0, prevEst: 0 };\n _cals.set(key, state);\n }\n return state;\n}\n\nconst MIN_SAMPLES_FOR_CALIBRATION = 3;\n\n/**\n * Cache of computed estimates keyed by the stringified input — not the\n * input object itself. Previously the cache was keyed by the input object\n * via WeakMap, but JSON.stringify() produces a new object reference each\n * call so the cache never hit. Now we use a Map with string keys so that\n * repeated stringifications of the same structure share a single entry.\n */\nconst ESTIMATE_CACHE = new Map<string, number>();\n\nconst ESTIMATE_CACHE_MAX_SIZE = 10_000;\n\nfunction getCachedEstimate(key: string, compute: (key: string) => number): number {\n const existing = ESTIMATE_CACHE.get(key);\n if (existing !== undefined) return existing;\n if (ESTIMATE_CACHE.size >= ESTIMATE_CACHE_MAX_SIZE) {\n // Evict oldest half when at capacity — O(1) instead of O(n) iteration.\n // 5 000 surviving entries still give a high cache hit rate for the\n // common case of repeated context-window checks on the same messages.\n for (const k of ESTIMATE_CACHE.keys()) {\n if (ESTIMATE_CACHE.size <= Math.floor(ESTIMATE_CACHE_MAX_SIZE / 2)) break;\n ESTIMATE_CACHE.delete(k);\n }\n }\n const estimate = compute(key);\n ESTIMATE_CACHE.set(key, estimate);\n return estimate;\n}\n\n/**\n * Estimate tokens for a tool_use block input.\n * Caches the stringified result keyed by the stable string representation\n * to avoid repeated JSON.stringify calls during context window checks.\n */\nexport function estimateToolInputTokens(input: unknown): number {\n if (typeof input === 'string') return RoughTokenEstimate(input);\n if (input === null || typeof input !== 'object') {\n return RoughTokenEstimate(String(input));\n }\n // JSON.stringify is called once to form the cache key; RoughTokenEstimate\n // is deferred only on cache miss (compute callback), not wrapped unnecessarily.\n return getCachedEstimate(JSON.stringify(input), (key) => RoughTokenEstimate(key));\n}\n\n/**\n * Estimate tokens for a tool_result content.\n */\nexport function estimateToolResultTokens(content: string | unknown): number {\n if (typeof content === 'string') return RoughTokenEstimate(content);\n return getCachedEstimate(JSON.stringify(content), (key) => RoughTokenEstimate(key));\n}\n\n/**\n * Estimate tokens for a text block.\n */\nexport function estimateTextTokens(text: string): number {\n return RoughTokenEstimate(text);\n}\n\n/**\n * Compute and cache the token estimate for a single message. This is the\n * canonical per-message estimator — called once by ConversationState on\n * append/replace so the O(n·m) content-block walk happens at mutation time,\n * not on every context-pressure check.\n */\nexport function computeMessageTokens(msg: Message): number {\n if (typeof msg.content === 'string') return estimateTextTokens(msg.content);\n let total = 0;\n for (const b of msg.content) {\n if (b.type === 'text') total += estimateTextTokens(b.text);\n else if (b.type === 'tool_use') total += estimateToolInputTokens(b.input);\n else if (b.type === 'tool_result') total += estimateToolResultTokens(b.content);\n else total += RoughTokenEstimate(JSON.stringify(b));\n }\n return total;\n}\n\n/**\n * Estimate tokens for an array of messages (text + tool I/O), using the shared\n * 3.5 chars/token basis. This is the single canonical message-array estimator —\n * compactors, the context_manager tool, and the `/context` display all route\n * through it so the number a user sees matches the number compaction decides on.\n *\n * When a message carries a pre-computed `_estTokens` field (set by\n * ConversationState on append/replace), it is used directly instead of\n * re-walking the content blocks — turning the O(n·m) scan into an O(n)\n * sum for fully-cached arrays.\n */\nexport function estimateMessageTokens(messages: readonly Message[]): number {\n let total = 0;\n for (const m of messages) {\n if (typeof m._estTokens === 'number' && m._estTokens > 0) {\n total += m._estTokens;\n continue;\n }\n total += computeMessageTokens(m);\n }\n return total;\n}\n\n/**\n * Rough estimate of tokens in a tool definition (name + description + schema).\n * Accounts for the JSON-serialized inputSchema which is sent to the API\n * but NOT included in roughEstimate(content).\n */\nexport function estimateToolDefTokens(tool: {\n name: string;\n description?: string | undefined;\n inputSchema: unknown;\n}): number {\n // Fast path: pre-computed by ToolRegistry at registration time.\n const cached = (tool as { _estDefTokens?: number | undefined })._estDefTokens;\n if (typeof cached === 'number' && cached > 0) return cached;\n\n const compact = compactToolDefinitionForWire(tool);\n return (\n RoughTokenEstimate(tool.name) +\n RoughTokenEstimate(compact.description) +\n RoughTokenEstimate(JSON.stringify(compact.inputSchema))\n );\n}\n\n/**\n * Estimate the total API request token count: system prompt + tool definitions\n * + conversation messages. Use this for context-window bar calculations\n * instead of roughEstimate (which only counts messages).\n *\n * The overhead ratio (overhead / messages) varies by conversation length:\n * - Short conversations (< 10 messages): ~30-50% overhead (large system+tools)\n * - Medium (10-50 messages): ~15-30%\n * - Long (> 50 messages): ~5-15%\n *\n * Returns { messages, systemPrompt, tools, total } for debugging display.\n */\nexport interface RequestTokenBreakdown {\n messages: number;\n systemPrompt: number;\n tools: number;\n total: number;\n}\n\nexport function estimateRequestTokens(\n messages: unknown,\n systemPrompt: unknown,\n tools: { name: string; description?: string | undefined; inputSchema: unknown }[],\n calibrationKey: string = CALIBRATION_GLOBAL_KEY,\n): RequestTokenBreakdown {\n // Messages: apply the same logic as roughEstimate\n let messagesTokens = 0;\n if (typeof messages === 'string') {\n messagesTokens = RoughTokenEstimate(messages);\n } else if (Array.isArray(messages)) {\n for (const m of messages) {\n if (typeof m === 'object' && m !== null && 'content' in m) {\n // Fast path: pre-computed per-message token estimate (set by\n // ConversationState on append/replace). Skips the O(m) content-block\n // walk entirely for cached messages.\n const cached = (m as { _estTokens?: number | undefined })._estTokens;\n if (typeof cached === 'number' && cached > 0) {\n messagesTokens += cached;\n continue;\n }\n const content = (m as { content: unknown }).content;\n if (typeof content === 'string') {\n messagesTokens += RoughTokenEstimate(content);\n } else if (Array.isArray(content)) {\n for (const b of content) {\n if (typeof b === 'object' && b !== null) {\n if ((b as { type?: string | undefined }).type === 'text') {\n messagesTokens += RoughTokenEstimate((b as { text: string }).text);\n } else {\n messagesTokens += RoughTokenEstimate(JSON.stringify(b));\n }\n }\n }\n }\n }\n }\n }\n\n // System prompt\n let systemTokens = 0;\n if (typeof systemPrompt === 'string') {\n systemTokens = RoughTokenEstimate(systemPrompt);\n } else if (Array.isArray(systemPrompt)) {\n for (const b of systemPrompt) {\n if (\n typeof b === 'object' &&\n b !== null &&\n (b as { type?: string | undefined }).type === 'text'\n ) {\n systemTokens += RoughTokenEstimate((b as { text: string }).text);\n }\n }\n }\n\n // Tool definitions\n let toolsTokens = 0;\n for (const t of tools) {\n toolsTokens += estimateToolDefTokens(t);\n }\n\n const total = messagesTokens + systemTokens + toolsTokens;\n\n // Record the raw estimate for calibration: the next recordActualUsage()\n // call will pair this against the actual API usage so the rolling ratio\n // stays in sync with the real chars/token ratio of the content.\n calState(calibrationKey).prevEst = total;\n\n return {\n messages: messagesTokens,\n systemPrompt: systemTokens,\n tools: toolsTokens,\n total,\n };\n}\n\n/**\n * Record the actual API input token count after a provider call so\n * `estimateRequestTokensCalibrated` can self-correct on subsequent calls.\n *\n * Prefer passing `estimatedInputTokens` explicitly (the calibrated pre-flight\n * estimate from the middleware) — this avoids race conditions when other code\n * also calls `estimateRequestTokens` between the pre-flight and this call\n * (e.g. audit logging in agent.ts).\n *\n * When `estimatedInputTokens` is omitted, falls back to the keyed bucket's\n * `prevEst` for backward compatibility with callers that don't have the\n * pre-flight value. `calibrationKey` selects the per-(provider,model) bucket\n * (defaults to the shared global bucket).\n */\nexport function recordActualUsage(\n actualInputTokens: number,\n estimatedInputTokens?: number,\n calibrationKey: string = CALIBRATION_GLOBAL_KEY,\n): void {\n if (actualInputTokens <= 0) return;\n const cal = calState(calibrationKey);\n const est = estimatedInputTokens ?? cal.prevEst;\n if (est <= 0) return;\n\n const sampleRatio = actualInputTokens / est;\n if (cal.count === 0) {\n cal.ratio = sampleRatio;\n } else {\n // EWM: new = α * sample + (1-α) * old → α=0.3 = fast initial converge\n cal.ratio = CAL_ALPHA * sampleRatio + (1 - CAL_ALPHA) * cal.ratio;\n }\n // Sanity bound: keep the rolling ratio within [0.5, 1.5] so a sequence\n // of bad samples can't blow up the calibration for everyone.\n cal.ratio = Math.min(1.5, Math.max(0.5, cal.ratio));\n cal.count++;\n}\n\n/**\n * Returns the current calibration state for a bucket. Exposed for debugging\n * and tests — not needed by normal callers.\n */\nexport function getCalibrationState(calibrationKey: string = CALIBRATION_GLOBAL_KEY): {\n ratio: number;\n count: number;\n calibrated: boolean;\n} {\n const cal = calState(calibrationKey);\n return {\n ratio: cal.ratio,\n count: cal.count,\n calibrated: cal.count >= MIN_SAMPLES_FOR_CALIBRATION,\n };\n}\n\n/**\n * Like `estimateRequestTokens` but applies the rolling calibration factor\n * so context pressure readings converge on reality within a few iterations.\n *\n * Before any `recordActualUsage` samples are collected, returns the same\n * result as `estimateRequestTokens` (ratio = 1.0, no distortion).\n * After `MIN_SAMPLES_FOR_CALIBRATION` samples, applies the calibrated\n * multiplier capped to the range [0.5, 1.5] as a sanity bound.\n */\nexport function estimateRequestTokensCalibrated(\n messages: unknown,\n systemPrompt: unknown,\n tools: { name: string; description?: string | undefined; inputSchema: unknown }[],\n calibrationKey: string = CALIBRATION_GLOBAL_KEY,\n): RequestTokenBreakdown {\n const result = estimateRequestTokens(messages, systemPrompt, tools, calibrationKey);\n const cal = calState(calibrationKey);\n\n if (cal.count >= MIN_SAMPLES_FOR_CALIBRATION) {\n const safeRatio = Math.min(1.5, Math.max(0.5, cal.ratio));\n return {\n messages: Math.round(result.messages * safeRatio),\n systemPrompt: Math.round(result.systemPrompt * safeRatio),\n tools: Math.round(result.tools * safeRatio),\n total: Math.round(result.total * safeRatio),\n };\n }\n\n return result;\n}\n\n/**\n * Resets calibration state. Primarily for tests that run in the same\n * process and need a clean slate between suites. With no argument it clears\n * every bucket (including the global one); pass a key to reset just that bucket.\n */\nexport function resetCalibration(calibrationKey?: string): void {\n if (calibrationKey === undefined) {\n _cals.clear();\n return;\n }\n _cals.delete(calibrationKey);\n}\n","import type { Context } from '../core/context.js';\nimport type { Compactor } from '../types/compactor.js';\nimport type { Message } from '../types/messages.js';\nimport type { Tool } from '../types/tool.js';\nimport { repairToolUseAdjacency } from '../utils/message-invariants.js';\nimport { estimateMessageTokens, estimateRequestTokens } from '../utils/token-estimate.js';\n\n/**\n * Context introspection and management tool.\n * Allows the model to:\n * - \"check\" → see token budget and message counts\n * - \"summary\" → summarize and replace a range of messages\n * - \"prune\" → remove specific message indices\n * - \"add_note\" → inject a summary note at a specific point\n * - \"compact\" → run compaction via the injected compactor\n */\nexport const CONTEXT_MANAGER_TOOL_NAME = 'context_manager';\n\nexport type ContextManagerAction =\n | 'check'\n | 'summary'\n | 'prune'\n | 'add_note'\n | 'compact'\n | 'repair';\n\nexport interface ContextManagerInput {\n action: ContextManagerAction;\n /** 0-based message indices for prune/summary (inclusive). */\n from?: number | undefined;\n to?: number | undefined;\n /** Text for add_note / summary actions. For summary, this is the LLM-provided summary text. */\n text?: string | undefined;\n /** Inject after which index (for add_note). Defaults to prepend (0). */\n afterIndex?: number | undefined;\n /**\n * System prompt blocks for accurate total token estimation in check action.\n * When provided, check returns the full API request estimate\n * (messages + system + tools) instead of just message tokens.\n */\n systemPrompt?: unknown | undefined;\n /**\n * Registered tools for accurate total token estimation in check action.\n * Each tool's name + description + inputSchema is counted.\n */\n tools?: { name: string; description?: string | undefined; inputSchema: unknown }[];\n}\n\nexport interface ContextManagerResult {\n action: ContextManagerAction;\n beforeTokens: number;\n afterTokens?: number | undefined;\n removedCount?: number | undefined;\n messageCount: number;\n summary?: string | undefined;\n notes?: string | undefined;\n repaired?: {\n removedToolUses: string[];\n removedToolResults: string[];\n removedMessages: number;\n } | undefined;\n}\n\n/**\n * Options for creating a context manager tool.\n * `compactor` is required for the \"compact\" action; without it the action returns an error.\n */\nexport interface ContextManagerToolOptions {\n compactor?: Compactor | undefined;\n /**\n * Optional sub-LLM summarizer. When provided, the \"summary\" action calls this\n * to produce real summaries of message ranges instead of placeholder text.\n * (signature matches Provider.complete — return the summary text in result.content[0].text)\n */\n summarizer?: (((messages: Message[]) => Promise<string>)) | undefined;\n /**\n * Minimum full-request token count before the compact action is allowed to run.\n * Prevents unnecessary compaction calls when context is small.\n * Default: 0 (always allow). Set to ~5000 for meaningful compaction targets.\n */\n minCompactThreshold?: number | undefined;\n /**\n * Minimum token growth required before retrying after a NOOP compaction.\n * A NOOP is when compaction saved nothing (preserveK protects everything,\n * no oversized tool_results). Default: 2000.\n */\n noopRetryDeltaTokens?: number | undefined;\n /**\n * Provider's max context window in tokens. Used to compute a relative\n * threshold when `minCompactThreshold` is not set. Default: 128_000.\n */\n maxContext?: number | undefined;\n /**\n * Fraction of maxContext that triggers compaction. Only used when\n * `minCompactThreshold` is not set. Default: 0.5 (50% of maxContext).\n */\n compactThresholdFraction?: number | undefined;\n}\n\n/** Messages-only token estimate. Delegates to the canonical shared estimator\n * so the context_manager tool agrees with compaction and the `/context` bar. */\nfunction roughEstimate(messages: Message[]): number {\n return estimateMessageTokens(messages);\n}\n\nexport function createContextManagerTool(\n opts: ContextManagerToolOptions = {},\n): Tool<ContextManagerInput, ContextManagerResult> {\n const minCompactThreshold = opts.minCompactThreshold ?? 0;\n const noopRetryDeltaTokens = opts.noopRetryDeltaTokens ?? 2_000;\n /** Hard override for maxContext. When absent, the runtime value from ctx.provider is used. */\n const configuredMaxContext = opts.maxContext;\n const compactThresholdFraction = opts.compactThresholdFraction ?? 0.5;\n\n // Tracks the most recent NOOP attempt so we can skip retry until context grows.\n let lastNoopTokens = 0;\n\n return {\n name: CONTEXT_MANAGER_TOOL_NAME,\n description:\n 'Inspect or reorganize the conversation context window. ' +\n 'Use \"check\" to see token budget. ' +\n 'Use \"summary\" to collapse a message range into a concise note (provide \"text\" for custom summary). ' +\n 'Use \"prune\" to remove specific messages by index. ' +\n 'Use \"add_note\" to inject a summary note. ' +\n 'Use \"compact\" to run aggressive compaction. ' +\n 'Use \"repair\" to remove orphan tool_use/tool_result blocks after manual context surgery.',\n inputSchema: {\n type: 'object',\n properties: {\n action: {\n type: 'string',\n enum: ['check', 'summary', 'prune', 'add_note', 'compact', 'repair'],\n description: 'The context operation to perform.',\n },\n from: {\n type: 'number',\n description: 'Start index (inclusive) for summary/prune operations.',\n },\n to: {\n type: 'number',\n description: 'End index (inclusive) for summary/prune operations.',\n },\n text: {\n type: 'string',\n description:\n 'Summary or note text. For \"summary\": the model-provided summary of the removed range. ' +\n 'For \"add_note\": the note to inject.',\n },\n afterIndex: {\n type: 'number',\n description: 'Insert after this index (for add_note). Defaults to prepend (0).',\n },\n },\n required: ['action'],\n },\n permission: 'auto',\n mutating: true,\n\n async execute(input: ContextManagerInput, ctx: Context): Promise<ContextManagerResult> {\n const messages = ctx.messages;\n const beforeTokens = roughEstimate(messages);\n\n // When ctx.state is available, route mutations through the observer\n // layer so subscribers stay in sync. Fall back to direct mutation for\n // tests and environments that haven't wired ConversationState.\n const applyMessages = (next: Message[]) => {\n const repaired = repairToolUseAdjacency(next);\n const finalMessages = repaired.messages;\n // Skip if finalMessages === messages (no-op: repair returned the same array).\n // This also prevents the self-spread bug where spreading an array into\n // splice(0, 0, ...arr) on the same array reference empties it.\n if (finalMessages === messages) return repaired.report;\n if (ctx.state) {\n ctx.state.replaceMessages(finalMessages);\n } else {\n // push(...) is O(k) with no element shift, unlike splice(0, 0, ...) which\n // shifts all existing elements before inserting at position 0.\n messages.length = 0;\n messages.push(...finalMessages);\n }\n return repaired.report;\n };\n\n switch (input.action) {\n case 'check': {\n // Prefer the full API request estimate when systemPrompt + tools are available.\n // This is the accurate number for context-window bar display.\n // Falls back to roughEstimate (messages-only) for backward compat and test environments.\n const estimate = (input.systemPrompt != null && Array.isArray(input.tools))\n ? estimateRequestTokens(messages, input.systemPrompt, input.tools)\n : { total: beforeTokens, messages: beforeTokens, systemPrompt: 0, tools: 0 };\n return {\n action: 'check',\n beforeTokens: estimate.total,\n messageCount: messages.length,\n notes: JSON.stringify({\n messages: messages.length,\n tokens: estimate.total,\n msgTokens: estimate.messages,\n sysTokens: estimate.systemPrompt,\n toolTokens: estimate.tools,\n readFiles: ctx.readFiles.size,\n todos: ctx.todos.length,\n inProgress: ctx.todos.filter((t) => t.status === 'in_progress').length,\n }),\n };\n }\n\n case 'repair': {\n const repair = applyMessages([...messages]);\n const afterTokens = roughEstimate(ctx.messages);\n return {\n action: 'repair',\n beforeTokens,\n afterTokens,\n messageCount: ctx.messages.length,\n repaired: repair.changed\n ? {\n removedToolUses: repair.removedToolUses,\n removedToolResults: repair.removedToolResults,\n removedMessages: repair.removedMessages,\n }\n : undefined,\n notes: repair.changed\n ? 'Context tool-call adjacency repaired.'\n : 'Context tool-call adjacency already valid.',\n };\n }\n\n case 'compact': {\n if (!opts.compactor) {\n return {\n action: 'compact',\n beforeTokens,\n messageCount: messages.length,\n notes: 'No compactor registered. Use /compact aggressive via slash command instead.',\n };\n }\n // Compute full request tokens for threshold check.\n const fullEstimate = (input.systemPrompt != null && Array.isArray(input.tools))\n ? estimateRequestTokens(messages, input.systemPrompt, input.tools)\n : { total: beforeTokens, messages: beforeTokens, systemPrompt: 0, tools: 0 };\n const currentTokens = fullEstimate.total;\n\n // Resolve maxContext at execution time from the live provider capabilities.\n // This is the actual model limit — from models.dev catalog, provider config,\n // or explicit effectiveMaxContext override. Falls back to the creation-time\n // value only when no runtime value is available (e.g. in test environments).\n const runtimeMaxContext =\n configuredMaxContext ?? ctx.provider?.capabilities?.maxContext ?? 128_000;\n const runtimeThreshold = minCompactThreshold > 0\n ? minCompactThreshold\n : Math.floor(runtimeMaxContext * compactThresholdFraction);\n\n // NOOP retry prevention: skip if the previous compaction saved nothing\n // and context hasn't grown enough to make another attempt worthwhile.\n if (lastNoopTokens > 0) {\n const delta = currentTokens - lastNoopTokens;\n if (delta < noopRetryDeltaTokens) {\n return {\n action: 'compact',\n beforeTokens,\n afterTokens: beforeTokens,\n messageCount: messages.length,\n notes: `Compact is a NOOP retry: context grew only ${delta} tokens since the last no-op attempt (threshold: ${noopRetryDeltaTokens}). Skip until more content accumulates.`,\n };\n }\n }\n\n // Minimum threshold check: skip if context is too small to benefit.\n if (runtimeThreshold > 0 && currentTokens < runtimeThreshold) {\n return {\n action: 'compact',\n beforeTokens,\n afterTokens: beforeTokens,\n messageCount: messages.length,\n notes: `Context tokens (${currentTokens}) below compact threshold (${runtimeThreshold}, based on provider maxContext ${runtimeMaxContext}). Skipping.`,\n };\n }\n\n const report = await opts.compactor.compact(ctx);\n ctx.clearFileTracking();\n\n // When ctx.state is not wired, the compactor's replaceMessages calls are\n // no-ops — repairToolUseAdjacency was still called inside the compactor but\n // the result was never committed. Run repair once to commit via the fallback.\n // When ctx.state IS wired, the compactor already committed the repair.\n let repaired = report.repaired;\n let afterTokens: number;\n if (!ctx.state) {\n const repair = applyMessages([...ctx.messages]);\n repaired = report.repaired ?? (repair.changed ? repair : undefined);\n afterTokens = repair.changed ? roughEstimate(ctx.messages) : report.after;\n } else {\n afterTokens = report.after;\n }\n\n // Record NOOP state: did compaction actually reduce tokens?\n const reduced = report.fullRequestTokensBefore > report.fullRequestTokensAfter;\n const repairedSomething = !!report.repaired;\n if (reduced || repairedSomething) {\n lastNoopTokens = 0;\n } else {\n lastNoopTokens = currentTokens;\n }\n\n return {\n action: 'compact',\n beforeTokens,\n afterTokens,\n messageCount: ctx.messages.length,\n repaired: repaired\n ? {\n removedToolUses: repaired.removedToolUses,\n removedToolResults: repaired.removedToolResults,\n removedMessages: repaired.removedMessages,\n }\n : undefined,\n };\n }\n\n case 'prune': {\n const from = input.from ?? 0;\n const to = input.to ?? messages.length - 1;\n if (from < 0 || to >= messages.length || from > to) {\n return {\n action: 'prune',\n beforeTokens,\n messageCount: messages.length,\n notes: `Invalid range [${from}, ${to}] for ${messages.length} messages.`,\n };\n }\n const copy = [...messages];\n const removed = copy.splice(from, to - from + 1);\n ctx.clearFileTracking();\n const repair = applyMessages(copy);\n const afterTokens = roughEstimate(ctx.messages);\n return {\n action: 'prune',\n beforeTokens,\n afterTokens,\n messageCount: ctx.messages.length,\n removedCount: removed.length,\n repaired: repair.changed\n ? {\n removedToolUses: repair.removedToolUses,\n removedToolResults: repair.removedToolResults,\n removedMessages: repair.removedMessages,\n }\n : undefined,\n };\n }\n\n case 'add_note': {\n const noteText = input.text ?? '(no summary)';\n const afterIdx = Math.min(input.afterIndex ?? 0, messages.length);\n const noteMsg: Message = {\n role: 'system',\n content: `[note: ${noteText}]`,\n };\n const copy = [...messages];\n copy.splice(afterIdx, 0, noteMsg);\n const repair = applyMessages(copy);\n const afterTokens = roughEstimate(ctx.messages);\n return {\n action: 'add_note',\n beforeTokens,\n afterTokens,\n messageCount: ctx.messages.length,\n summary: noteText,\n repaired: repair.changed\n ? {\n removedToolUses: repair.removedToolUses,\n removedToolResults: repair.removedToolResults,\n removedMessages: repair.removedMessages,\n }\n : undefined,\n };\n }\n\n case 'summary': {\n const from = input.from ?? 0;\n const to = input.to ?? messages.length - 1;\n if (from < 0 || to >= messages.length || from > to) {\n return {\n action: 'summary',\n beforeTokens,\n messageCount: messages.length,\n notes: `Invalid range [${from}, ${to}] for ${messages.length} messages.`,\n };\n }\n const summaryText =\n input.text ?? '[summary placeholder — provide \"text\" to record the summary]';\n const summaryMsg: Message = {\n role: 'system',\n content: `[summary of messages ${from}–${to}]: ${summaryText}`,\n };\n const copy = [...messages];\n copy.splice(from, to - from + 1, summaryMsg);\n ctx.clearFileTracking();\n const repair = applyMessages(copy);\n const afterTokens = roughEstimate(ctx.messages);\n return {\n action: 'summary',\n beforeTokens,\n afterTokens,\n messageCount: ctx.messages.length,\n summary: summaryText,\n repaired: repair.changed\n ? {\n removedToolUses: repair.removedToolUses,\n removedToolResults: repair.removedToolResults,\n removedMessages: repair.removedMessages,\n }\n : undefined,\n };\n }\n\n default:\n return {\n action: input.action,\n beforeTokens,\n messageCount: messages.length,\n notes: `Unknown action: ${input.action}`,\n };\n }\n },\n };\n}\n\n/** Pre-built instance with no compactor — compact action will return an error. */\nexport const contextManagerTool: Tool<ContextManagerInput, ContextManagerResult> =\n createContextManagerTool();\n"]}
|
package/dist/kernel/index.d.ts
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export { E as EventBus, m as EventLogger, n as EventMap, a as EventName, L as Listener, v as ScopedEventBus } from '../brain-
|
|
3
|
-
export { R as RunController, b as RunControllerOptions, T as TOKENS } from '../index-
|
|
4
|
-
import '../context-
|
|
5
|
-
import '../
|
|
6
|
-
import '../
|
|
7
|
-
import '../
|
|
1
|
+
export { c as BindOptions, C as Container, D as Decorator, F as Factory, d as Middleware, M as MiddlewareHandler, N as NextFn, P as Pipeline, e as PipelineOptions, T as Token } from '../pipeline-BDNvENyV.js';
|
|
2
|
+
export { E as EventBus, m as EventLogger, n as EventMap, a as EventName, L as Listener, v as ScopedEventBus } from '../brain-69wzMKp1.js';
|
|
3
|
+
export { R as RunController, b as RunControllerOptions, T as TOKENS } from '../index-CtQnmkaS.js';
|
|
4
|
+
import '../context-C0U8B9NF.js';
|
|
5
|
+
import '../mailbox-types-Ct2hJq0P.js';
|
|
6
|
+
import '../config-VKfOZ-6X.js';
|
|
7
|
+
import '../compactor-CBQAJoDc.js';
|
|
8
|
+
import '../retry-policy-C3s_lvdK.js';
|
|
8
9
|
import '../input-reader-E-ffP2ee.js';
|
|
9
10
|
import '../logger-B63L5bTg.js';
|
|
10
11
|
import '../mode-CZlO9iU1.js';
|
|
11
12
|
import '../path-resolver-CPRj4bFY.js';
|
|
12
|
-
import '../permission-
|
|
13
|
-
import '../provider-runner-
|
|
13
|
+
import '../permission-Bd-57Lbl.js';
|
|
14
|
+
import '../provider-runner-DWJbpo70.js';
|
|
14
15
|
import '../observability-D-HZN_mF.js';
|
|
15
16
|
import '../skill-DGIXCtdv.js';
|