mythos-router 1.0.0 → 1.1.1

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/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 thewaltero
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2026 thewaltero
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,220 +1,213 @@
1
1
  <div align="center">
2
2
 
3
- # MYTHOS
4
-
5
- ### Capybara Tier · Claude Opus 4.6 · Strict Write Discipline
6
-
7
- **The leaked Anthropic reasoning protocol. Running locally.**
8
-
9
- [![npm](https://img.shields.io/npm/v/mythos-router?style=flat-square&color=cc785c)](https://www.npmjs.com/package/mythos-router)
3
+ <pre>
4
+ ███╗ ███╗██╗ ██╗████████╗██╗ ██╗ ██████╗ ███████╗
5
+ ████╗ ████║╚██╗ ██╔╝╚══██╔══╝██║ ██║██╔═══██╗██╔════╝
6
+ ██╔████╔██║ ╚████╔╝ ██║ ███████║██║ ██║███████╗
7
+ ██║╚██╔╝██║ ╚██╔╝ ██║ ██╔══██║██║ ██║╚════██║
8
+ ██║ ╚═╝ ██║ ██║ ██║ ██║ ██║╚██████╔╝███████║
9
+ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚══════╝
10
+ </pre>
11
+
12
+ ### Claude-powered CLI agent framework for structured execution, memory, and verification
13
+
14
+ [![npm](https://img.shields.io/npm/v/mythos-router?style=flat-square)](https://www.npmjs.com/package/mythos-router)
10
15
  [![Node.js](https://img.shields.io/badge/Node.js-20+-339933?style=flat-square&logo=node.js&logoColor=white)](https://nodejs.org)
11
16
  [![TypeScript](https://img.shields.io/badge/TypeScript-5.7-3178C6?style=flat-square&logo=typescript&logoColor=white)](https://typescriptlang.org)
12
- [![Claude](https://img.shields.io/badge/Claude-Opus_4.6-cc785c?style=flat-square)](https://anthropic.com)
13
17
  [![License](https://img.shields.io/badge/License-MIT-green?style=flat-square)](./LICENSE)
14
- [![GitHub stars](https://img.shields.io/github/stars/thewaltero/mythos-router?style=social)](https://github.com/thewaltero/mythos-router)
15
-
16
- <p align="center">
17
- <img src="assets/demo.png" alt="mythos-router terminal demo" width="700" />
18
- </p>
19
-
20
- ```bash
21
- # Try it now
22
- npx mythos-router chat
23
- ```
24
18
 
25
19
  </div>
26
20
 
27
21
  ---
28
22
 
29
- ## What is this?
23
+ ## Overview
30
24
 
31
- **mythos-router** is a local CLI power tool that implements the *leaked Anthropic "Capybara" reasoning protocol* — the specialized tier designed for PhD-level reasoning and cybersecurity analysis.
25
+ **mythos-router** is a local CLI framework for building structured AI agent workflows using the Anthropic API.
32
26
 
33
- Unlike standard Claude wrappers, mythos-router enforces **Strict Write Discipline (SWD)**: every file operation the AI claims to perform is *verified against the actual filesystem*. If the model hallucinates a write, it gets a Correction Turn. If it fails twice, it yields to the human.
27
+ It extends standard LLM interactions with:
28
+ - deterministic file operation verification
29
+ - session-based memory logging
30
+ - token budgeting and cost tracking
31
+ - optional execution tracing and dry-run mode
34
32
 
35
- Zero slop. Zero hallucinated state. Full adaptive thinking.
33
+ The goal is to make LLM-assisted development more **traceable, controllable, and reproducible**.
36
34
 
37
35
  ---
38
36
 
39
- ## Features
37
+ ## Key Features
40
38
 
41
39
  | Feature | Description |
42
- |---------|-------------|
43
- | 🧠 **Adaptive Thinking** | Opus 4.6 with configurable effort levels (high/medium/low) |
44
- | 🔒 **Strict Write Discipline** | Pre/post filesystem snapshots verify every model claim |
45
- | 💤 **Self-Healing Memory** | `MEMORY.md` logs every action; auto-compresses via "Dream" |
46
- | **Correction Turns** | Model gets 2 retries to match filesystem reality, then yields |
47
- | 📋 **Drift Detection** | `verify` command syncs codebase state with memory |
48
- | 🚀 **Zero Build** | Runs directly via `tsx` no compile step in dev |
40
+ |--------|-------------|
41
+ | 🧠 Agentic chat runtime | Interactive CLI powered by Claude models |
42
+ | 📁 Execution verification | File operations are validated against filesystem state |
43
+ | 🧾 Session memory | Persistent `MEMORY.md` logs all actions |
44
+ | 💰 Token budgeting | Track and limit usage per session |
45
+ | 🔍 Dry-run mode | Preview file changes before execution |
46
+ | 📊 Verbose tracing | Inspect internal reasoning and execution steps |
47
+ | 🔁 Drift detection | Compare memory state with actual filesystem |
48
+ | ⚡ Zero build runtime | Runs directly via `tsx` in development |
49
49
 
50
50
  ---
51
51
 
52
52
  ## Installation
53
53
 
54
- ### Quick Start (npm)
55
-
54
+ ### Global install
56
55
  ```bash
57
- # Install globally
58
56
  npm install -g mythos-router
59
-
60
- # Set your API key
61
- export ANTHROPIC_API_KEY="sk-ant-..."
62
- # Windows: $env:ANTHROPIC_API_KEY = "sk-ant-..."
63
-
64
- # Go
65
- mythos chat
66
57
  ```
67
58
 
68
- ### Or try without installing
69
-
59
+ ### Run without installation
70
60
  ```bash
71
61
  npx mythos-router chat
72
62
  ```
73
63
 
74
- ### From Source
75
-
64
+ ### From source
76
65
  ```bash
77
66
  git clone https://github.com/thewaltero/mythos-router.git
78
67
  cd mythos-router
79
- npm install
80
- npm run chat
68
+ npm install --ignore-scripts
81
69
  ```
82
70
 
83
71
  ---
84
72
 
85
- ## Usage
73
+ ## Setup
86
74
 
87
- ### `mythos chat` Interactive Capybara Session
75
+ Set your Anthropic API key:
88
76
 
89
- ```bash
90
- mythos chat # Full power (high effort)
91
- mythos chat --effort low # Budget mode
92
- mythos chat --effort medium # Balanced
77
+ **Windows (PowerShell)**
78
+ ```powershell
79
+ $env:ANTHROPIC_API_KEY="sk-ant-..."
93
80
  ```
94
81
 
95
- In-session commands:
96
- - `/exit` — End session
97
- - `/memory` — Show memory status
98
- - `/clear` — Clear conversation (memory persists)
99
-
100
- ### `mythos verify` — Zero-Drift Codebase Scan
101
-
82
+ **macOS / Linux**
102
83
  ```bash
103
- mythos verify
84
+ export ANTHROPIC_API_KEY="sk-ant-..."
104
85
  ```
105
86
 
106
- Scans every file in your project and cross-references against `MEMORY.md`:
107
- - ✅ **Verified** — File state matches memory
108
- - ⚠️ **Drift** — File changed but memory doesn't reflect it
109
- - ❌ **Missing** — Memory references a file that doesn't exist
87
+ ---
110
88
 
111
- ### `mythos dream` — Memory Compression
89
+ ## Usage
112
90
 
91
+ ### Start interactive chat
113
92
  ```bash
114
- mythos dream # Auto-compress when needed
115
- mythos dream --force # Force compression
93
+ mythos chat
116
94
  ```
117
95
 
118
- When `MEMORY.md` exceeds 100 entries, older logs are compressed into a summary block using Claude (low effort, minimal token burn). Recent entries are preserved intact.
96
+ ### Modes
97
+ ```bash
98
+ mythos chat --effort high # deeper reasoning
99
+ mythos chat --effort medium # balanced
100
+ mythos chat --effort low # faster responses
101
+ ```
119
102
 
120
103
  ---
121
104
 
122
- ## Architecture
105
+ ## Safety & Execution Control
123
106
 
124
- ```
125
- mythos-router/
126
- ├── src/
127
- │ ├── cli.ts # Commander.js entry point
128
- │ ├── config.ts # Capybara system prompt + constants
129
- │ ├── client.ts # Anthropic SDK (adaptive thinking)
130
- │ ├── swd.ts # Strict Write Discipline engine
131
- │ ├── memory.ts # MEMORY.md self-healing manager
132
- │ ├── utils.ts # Terminal formatting (zero-dep)
133
- │ └── commands/
134
- │ ├── chat.ts # Interactive REPL
135
- │ ├── verify.ts # Codebase ↔ Memory scanner
136
- │ └── dream.ts # Memory compression
137
- ├── .mythosignore # SWD scan exclusions
138
- ├── MEMORY.md # Auto-generated agentic memory
139
- └── AGENTS.md # Project conventions
107
+ ### Dry-run mode
108
+ Preview file operations before applying changes:
109
+ ```bash
110
+ mythos chat --dry-run
140
111
  ```
141
112
 
142
- ### The SWD Protocol
143
-
113
+ ### Verbose mode
114
+ Inspect execution steps and verification logic:
115
+ ```bash
116
+ mythos chat --verbose
144
117
  ```
145
- User Input
146
-
147
-
148
- [Pre-Snapshot] ── filesystem state captured
149
-
150
-
151
- [Claude Opus 4.6] ── adaptive thinking (high effort)
152
-
153
-
154
- [Parse FILE_ACTION blocks] ── extract claimed operations
155
-
156
-
157
- [Post-Snapshot] ── filesystem state re-captured
158
-
159
-
160
- [Verify] ── before vs. after vs. model claims
161
-
162
- ├── ✅ All verified → Log to MEMORY.md
163
-
164
- └── ❌ Mismatch → Correction Turn (max 2 retries)
165
-
166
- └── Still failing → Yield to human
118
+
119
+ ### Combined
120
+ ```bash
121
+ mythos chat --dry-run --verbose
167
122
  ```
168
123
 
169
124
  ---
170
125
 
171
- ## MEMORY.md — Should You Commit It?
126
+ ## Token Budgeting
172
127
 
173
- **Yes.** `MEMORY.md` is designed to be committed to your repository. It becomes a "collaborative brain" where:
174
- - Multiple developers can see what the AI did in previous sessions
175
- - Different AI agents can reference past context
176
- - You get a full audit trail of every AI-assisted file operation
128
+ `mythos-router` includes a built-in usage tracker for session cost control.
177
129
 
178
- If you prefer to keep it private, add `MEMORY.md` to your `.gitignore`.
130
+ ```bash
131
+ mythos chat --max-tokens 100000
132
+ mythos chat --max-turns 10
133
+ mythos chat --no-budget
134
+ ```
135
+
136
+ When limits are reached, the session performs a graceful save of state into `MEMORY.md`.
179
137
 
180
138
  ---
181
139
 
182
- ## The Capybara System Prompt
140
+ ## Commands
183
141
 
184
- The system prompt implements the leaked Anthropic protocol:
142
+ ### Chat session
143
+ ```bash
144
+ mythos chat
145
+ ```
185
146
 
186
- > **Tier: Capybara** (Specialized in Cybersecurity & PhD Reasoning)
187
- >
188
- > Follow 'Strict Write Discipline' and never hallucinate filesystem state.
189
- > Every file operation must be wrapped in `[FILE_ACTION]` blocks for verification.
147
+ ### Codebase verification
148
+ Scans filesystem state and compares it with recorded memory:
149
+ ```bash
150
+ mythos verify
151
+ mythos verify --dry-run
152
+ ```
190
153
 
191
- The model is instructed to emit machine-readable delimiters around every file operation, making SWD verification 100% reliable.
154
+ ### Memory compression
155
+ Reduces size of `MEMORY.md` while preserving recent context:
156
+ ```bash
157
+ mythos dream
158
+ mythos dream --dry-run
159
+ ```
192
160
 
193
161
  ---
194
162
 
195
- ## Configuration
163
+ ## Architecture
164
+
165
+ ```text
166
+ src/
167
+ ├── cli.ts # CLI entry (Commander.js)
168
+ ├── client.ts # Anthropic API client
169
+ ├── config.ts # Model + runtime configuration
170
+ ├── budget.ts # Token and turn tracking
171
+ ├── swd.ts # File operation verification layer
172
+ ├── memory.ts # MEMORY.md system
173
+ ├── utils.ts # CLI utilities
174
+ └── commands/
175
+ ├── chat.ts
176
+ ├── verify.ts
177
+ └── dream.ts
178
+ ```
196
179
 
197
- | Env Variable | Required | Description |
198
- |-------------|----------|-------------|
199
- | `ANTHROPIC_API_KEY` | ✅ | Your Anthropic API key |
180
+ ---
200
181
 
201
- | File | Purpose |
202
- |------|---------|
203
- | `.mythosignore` | Patterns to exclude from SWD scanning |
204
- | `MEMORY.md` | Auto-generated agentic memory log |
182
+ ## Execution Model
183
+
184
+ 1. User input is received in CLI
185
+ 2. LLM generates response with structured file operations
186
+ 3. File system snapshot is captured
187
+ 4. Proposed changes are validated against actual filesystem state
188
+ 5. Verified actions are applied and logged to `MEMORY.md`
189
+ 6. Drift or mismatches trigger correction handling
205
190
 
206
191
  ---
207
192
 
208
- ## Token Usage
193
+ ## MEMORY.md
194
+
195
+ `MEMORY.md` acts as a persistent execution log of the agent system.
196
+
197
+ It records:
198
+ - executed file operations
199
+ - session summaries
200
+ - verification results
209
201
 
210
- | Mode | Typical Cost Per Turn |
211
- |------|----------------------|
212
- | `--effort high` | Full Opus 4.6 pricing (deep reasoning) |
213
- | `--effort medium` | Balanced — good for most tasks |
214
- | `--effort low` | Minimal thinking — quick answers |
215
- | `dream` | Low effort summarization (~500 tokens) |
202
+ It can optionally be committed to version control for collaborative AI-assisted development.
216
203
 
217
- Token counts are displayed after every chat response.
204
+ ---
205
+
206
+ ## Environment Variables
207
+
208
+ | Variable | Required | Description |
209
+ |----------|----------|-------------|
210
+ | `ANTHROPIC_API_KEY` | Yes | API key for Anthropic models |
218
211
 
219
212
  ---
220
213
 
@@ -224,6 +217,8 @@ MIT
224
217
 
225
218
  ---
226
219
 
227
- <div align="center">
228
- <sub>Built with the leaked Capybara protocol. No affiliation with Anthropic. Use responsibly.</sub>
229
- </div>
220
+ ## Disclaimer
221
+
222
+ This project is an independent open-source tool built on top of the Anthropic API. It is not affiliated with or endorsed by Anthropic.
223
+
224
+ <div align="center"><sub>Built for structured AI agent workflows with verifiable execution.</sub></div>
@@ -0,0 +1,47 @@
1
+ export interface BudgetConfig {
2
+ maxTokens: number;
3
+ maxTurns: number;
4
+ warnAtPercent: number;
5
+ /** Cost per input token in USD (update when Anthropic changes pricing) */
6
+ costPerInputToken: number;
7
+ /** Cost per output token in USD (update when Anthropic changes pricing) */
8
+ costPerOutputToken: number;
9
+ }
10
+ export interface BudgetCheck {
11
+ ok: boolean;
12
+ reason?: string;
13
+ tokensPercent: number;
14
+ turnsPercent: number;
15
+ warning: boolean;
16
+ /** True when budget is exhausted — signals the caller to perform a graceful save */
17
+ exhausted: boolean;
18
+ }
19
+ export interface BudgetSnapshot {
20
+ totalTokens: number;
21
+ inputTokens: number;
22
+ outputTokens: number;
23
+ turns: number;
24
+ maxTokens: number;
25
+ maxTurns: number;
26
+ startedAt: number;
27
+ elapsedMs: number;
28
+ /** Estimated cost in USD based on configured token pricing */
29
+ estimatedCostUSD: number;
30
+ }
31
+ export declare class SessionBudget {
32
+ private config;
33
+ private totalInput;
34
+ private totalOutput;
35
+ private turnCount;
36
+ private startedAt;
37
+ private enabled;
38
+ constructor(config?: Partial<BudgetConfig>, enabled?: boolean);
39
+ record(inputTokens: number, outputTokens: number): void;
40
+ check(): BudgetCheck;
41
+ status(): BudgetSnapshot;
42
+ isEnabled(): boolean;
43
+ formatBar(width?: number): string;
44
+ formatWarning(): string | null;
45
+ formatSessionSummary(): string;
46
+ }
47
+ //# sourceMappingURL=budget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"budget.d.ts","sourceRoot":"","sources":["../src/budget.ts"],"names":[],"mappings":"AAeA,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,0EAA0E;IAC1E,iBAAiB,EAAE,MAAM,CAAC;IAC1B,2EAA2E;IAC3E,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,oFAAoF;IACpF,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,8DAA8D;IAC9D,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAGD,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,OAAO,CAAU;gBAEb,MAAM,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,EAAE,OAAO,UAAO;IAa1D,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI;IAOvD,KAAK,IAAI,WAAW;IA6CpB,MAAM,IAAI,cAAc;IAkBxB,SAAS,IAAI,OAAO;IAKpB,SAAS,CAAC,KAAK,SAAK,GAAG,MAAM;IAkC7B,aAAa,IAAI,MAAM,GAAG,IAAI;IA6B9B,oBAAoB,IAAI,MAAM;CAQ/B"}
package/dist/budget.js ADDED
@@ -0,0 +1,157 @@
1
+ // ─────────────────────────────────────────────────────────────
2
+ // mythos-router :: budget.ts
3
+ // Session Budget Limiter — Financial safety switch
4
+ // ─────────────────────────────────────────────────────────────
5
+ import { DEFAULT_MAX_TOKENS_PER_SESSION, DEFAULT_MAX_TURNS, BUDGET_WARN_PERCENT, COST_PER_INPUT_TOKEN, COST_PER_OUTPUT_TOKEN, } from './config.js';
6
+ import { c } from './utils.js';
7
+ // ── Session Budget Class ─────────────────────────────────────
8
+ export class SessionBudget {
9
+ config;
10
+ totalInput = 0;
11
+ totalOutput = 0;
12
+ turnCount = 0;
13
+ startedAt;
14
+ enabled;
15
+ constructor(config, enabled = true) {
16
+ this.config = {
17
+ maxTokens: config?.maxTokens ?? DEFAULT_MAX_TOKENS_PER_SESSION,
18
+ maxTurns: config?.maxTurns ?? DEFAULT_MAX_TURNS,
19
+ warnAtPercent: config?.warnAtPercent ?? BUDGET_WARN_PERCENT,
20
+ costPerInputToken: config?.costPerInputToken ?? COST_PER_INPUT_TOKEN,
21
+ costPerOutputToken: config?.costPerOutputToken ?? COST_PER_OUTPUT_TOKEN,
22
+ };
23
+ this.startedAt = Date.now();
24
+ this.enabled = enabled;
25
+ }
26
+ // ── Record token usage after an API call ─────────────────
27
+ record(inputTokens, outputTokens) {
28
+ this.totalInput += inputTokens;
29
+ this.totalOutput += outputTokens;
30
+ this.turnCount++;
31
+ }
32
+ // ── Check if budget is still ok ──────────────────────────
33
+ check() {
34
+ if (!this.enabled) {
35
+ return { ok: true, tokensPercent: 0, turnsPercent: 0, warning: false, exhausted: false };
36
+ }
37
+ const totalTokens = this.totalInput + this.totalOutput;
38
+ const tokensPercent = (totalTokens / this.config.maxTokens) * 100;
39
+ const turnsPercent = (this.turnCount / this.config.maxTurns) * 100;
40
+ const warning = tokensPercent >= this.config.warnAtPercent ||
41
+ turnsPercent >= this.config.warnAtPercent;
42
+ // Token limit exceeded
43
+ if (totalTokens >= this.config.maxTokens) {
44
+ return {
45
+ ok: false,
46
+ exhausted: true,
47
+ reason: `Session budget exhausted: ${totalTokens.toLocaleString()}/${this.config.maxTokens.toLocaleString()} tokens ` +
48
+ `used across ${this.turnCount} turns. ` +
49
+ `Use --max-tokens <n> to increase or --no-budget to disable.`,
50
+ tokensPercent: Math.min(tokensPercent, 100),
51
+ turnsPercent,
52
+ warning: true,
53
+ };
54
+ }
55
+ // Turn limit exceeded
56
+ if (this.turnCount >= this.config.maxTurns) {
57
+ return {
58
+ ok: false,
59
+ exhausted: true,
60
+ reason: `Session turn limit reached: ${this.turnCount}/${this.config.maxTurns} turns. ` +
61
+ `Use --max-turns <n> to increase or --no-budget to disable.`,
62
+ tokensPercent,
63
+ turnsPercent: Math.min(turnsPercent, 100),
64
+ warning: true,
65
+ };
66
+ }
67
+ return { ok: true, tokensPercent, turnsPercent, warning, exhausted: false };
68
+ }
69
+ // ── Get current snapshot ─────────────────────────────────
70
+ status() {
71
+ const estimatedCostUSD = this.totalInput * this.config.costPerInputToken +
72
+ this.totalOutput * this.config.costPerOutputToken;
73
+ return {
74
+ totalTokens: this.totalInput + this.totalOutput,
75
+ inputTokens: this.totalInput,
76
+ outputTokens: this.totalOutput,
77
+ turns: this.turnCount,
78
+ maxTokens: this.config.maxTokens,
79
+ maxTurns: this.config.maxTurns,
80
+ startedAt: this.startedAt,
81
+ elapsedMs: Date.now() - this.startedAt,
82
+ estimatedCostUSD,
83
+ };
84
+ }
85
+ // ── Is budget enforcement enabled? ───────────────────────
86
+ isEnabled() {
87
+ return this.enabled;
88
+ }
89
+ // ── Format a visual budget bar for the terminal ──────────
90
+ formatBar(width = 20) {
91
+ if (!this.enabled) {
92
+ return `${c.dim}budget: ${c.yellow}disabled${c.dim} (expert mode)${c.reset}`;
93
+ }
94
+ const snap = this.status();
95
+ const tokPct = Math.min((snap.totalTokens / snap.maxTokens) * 100, 100);
96
+ const turnPct = Math.min((snap.turns / snap.maxTurns) * 100, 100);
97
+ const tokBar = progressBar(tokPct, width);
98
+ const turnBar = progressBar(turnPct, Math.floor(width / 2));
99
+ const tokColor = tokPct >= 90 ? c.red : tokPct >= this.config.warnAtPercent ? c.yellow : c.green;
100
+ const turnColor = turnPct >= 90 ? c.red : turnPct >= this.config.warnAtPercent ? c.yellow : c.green;
101
+ const elapsed = formatElapsed(snap.elapsedMs);
102
+ return (`${c.dim}budget:${c.reset} ` +
103
+ `${tokColor}${tokBar}${c.reset} ` +
104
+ `${tokColor}${snap.totalTokens.toLocaleString()}${c.dim}/${snap.maxTokens.toLocaleString()} tokens${c.reset} · ` +
105
+ `${turnColor}${turnBar}${c.reset} ` +
106
+ `${turnColor}${snap.turns}${c.dim}/${snap.maxTurns} turns${c.reset} · ` +
107
+ `${c.dim}~$${snap.estimatedCostUSD.toFixed(4)} · ${elapsed}${c.reset}`);
108
+ }
109
+ // ── Format warning message if at threshold ───────────────
110
+ formatWarning() {
111
+ if (!this.enabled)
112
+ return null;
113
+ const { warning, ok, tokensPercent, turnsPercent } = this.check();
114
+ if (!ok) {
115
+ const snap = this.status();
116
+ return (`${c.yellow}${c.bold}⏸ BUDGET REACHED — Graceful Save${c.reset}\n` +
117
+ `${c.dim} ${snap.totalTokens.toLocaleString()} tokens consumed across ${snap.turns} turns (~$${snap.estimatedCostUSD.toFixed(4)}).${c.reset}\n` +
118
+ `${c.green} Progress saved to MEMORY.md. Resume with ${c.cyan}mythos chat${c.green} to continue.${c.reset}\n` +
119
+ `${c.dim} Increase limits: ${c.cyan}mythos chat --max-tokens 1000000 --max-turns 50${c.reset}\n` +
120
+ `${c.dim} Disable limits: ${c.cyan}mythos chat --no-budget${c.reset}`);
121
+ }
122
+ if (warning) {
123
+ const higher = Math.max(tokensPercent, turnsPercent);
124
+ const snap = this.status();
125
+ return (`${c.yellow}⚠ Budget ${Math.round(higher)}% consumed${c.reset} — ` +
126
+ `${c.dim}${snap.totalTokens.toLocaleString()} tokens · ${snap.turns} turns${c.reset}`);
127
+ }
128
+ return null;
129
+ }
130
+ // ── Graceful session summary for MEMORY.md ────────────────
131
+ formatSessionSummary() {
132
+ const snap = this.status();
133
+ const elapsed = formatElapsed(snap.elapsedMs);
134
+ return (`budget-save: ${snap.totalTokens.toLocaleString()} tokens · ` +
135
+ `${snap.turns} turns · ~$${snap.estimatedCostUSD.toFixed(4)} · ${elapsed}`);
136
+ }
137
+ }
138
+ // ── Progress Bar Helper ──────────────────────────────────────
139
+ function progressBar(percent, width) {
140
+ const filled = Math.round((percent / 100) * width);
141
+ const empty = width - filled;
142
+ return `[${`█`.repeat(filled)}${`░`.repeat(empty)}]`;
143
+ }
144
+ // ── Elapsed Time Formatter ───────────────────────────────────
145
+ function formatElapsed(ms) {
146
+ const seconds = Math.floor(ms / 1000);
147
+ if (seconds < 60)
148
+ return `${seconds}s`;
149
+ const minutes = Math.floor(seconds / 60);
150
+ const secs = seconds % 60;
151
+ if (minutes < 60)
152
+ return `${minutes}m ${secs}s`;
153
+ const hours = Math.floor(minutes / 60);
154
+ const mins = minutes % 60;
155
+ return `${hours}h ${mins}m`;
156
+ }
157
+ //# sourceMappingURL=budget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"budget.js","sourceRoot":"","sources":["../src/budget.ts"],"names":[],"mappings":"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"}