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 +21 -21
- package/README.md +136 -141
- package/dist/budget.d.ts +47 -0
- package/dist/budget.d.ts.map +1 -0
- package/dist/budget.js +157 -0
- package/dist/budget.js.map +1 -0
- package/dist/cli.js +11 -3
- package/dist/cli.js.map +1 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +63 -35
- package/dist/client.js.map +1 -1
- package/dist/commands/chat.d.ts +9 -2
- package/dist/commands/chat.d.ts.map +1 -1
- package/dist/commands/chat.js +149 -39
- package/dist/commands/chat.js.map +1 -1
- package/dist/commands/dream.d.ts +1 -0
- package/dist/commands/dream.d.ts.map +1 -1
- package/dist/commands/dream.js +7 -3
- package/dist/commands/dream.js.map +1 -1
- package/dist/commands/verify.d.ts +3 -1
- package/dist/commands/verify.d.ts.map +1 -1
- package/dist/commands/verify.js +7 -14
- package/dist/commands/verify.js.map +1 -1
- package/dist/config.d.ts +6 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +65 -50
- package/dist/config.js.map +1 -1
- package/dist/memory.d.ts +3 -3
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +22 -8
- package/dist/memory.js.map +1 -1
- package/dist/swd.d.ts +8 -1
- package/dist/swd.d.ts.map +1 -1
- package/dist/swd.js +74 -11
- package/dist/swd.js.map +1 -1
- package/dist/utils.d.ts +4 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +41 -12
- package/dist/utils.js.map +1 -1
- package/package.json +63 -63
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
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
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
|
+
[](https://www.npmjs.com/package/mythos-router)
|
|
10
15
|
[](https://nodejs.org)
|
|
11
16
|
[](https://typescriptlang.org)
|
|
12
|
-
[](https://anthropic.com)
|
|
13
17
|
[](./LICENSE)
|
|
14
|
-
[](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
|
-
##
|
|
23
|
+
## Overview
|
|
30
24
|
|
|
31
|
-
**mythos-router** is a local CLI
|
|
25
|
+
**mythos-router** is a local CLI framework for building structured AI agent workflows using the Anthropic API.
|
|
32
26
|
|
|
33
|
-
|
|
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
|
-
|
|
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
|
-
| 🧠
|
|
44
|
-
|
|
|
45
|
-
|
|
|
46
|
-
|
|
|
47
|
-
|
|
|
48
|
-
|
|
|
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
|
-
###
|
|
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
|
-
###
|
|
69
|
-
|
|
59
|
+
### Run without installation
|
|
70
60
|
```bash
|
|
71
61
|
npx mythos-router chat
|
|
72
62
|
```
|
|
73
63
|
|
|
74
|
-
### From
|
|
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
|
-
##
|
|
73
|
+
## Setup
|
|
86
74
|
|
|
87
|
-
|
|
75
|
+
Set your Anthropic API key:
|
|
88
76
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
mythos chat --effort medium # Balanced
|
|
77
|
+
**Windows (PowerShell)**
|
|
78
|
+
```powershell
|
|
79
|
+
$env:ANTHROPIC_API_KEY="sk-ant-..."
|
|
93
80
|
```
|
|
94
81
|
|
|
95
|
-
|
|
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
|
-
|
|
84
|
+
export ANTHROPIC_API_KEY="sk-ant-..."
|
|
104
85
|
```
|
|
105
86
|
|
|
106
|
-
|
|
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
|
-
|
|
89
|
+
## Usage
|
|
112
90
|
|
|
91
|
+
### Start interactive chat
|
|
113
92
|
```bash
|
|
114
|
-
mythos
|
|
115
|
-
mythos dream --force # Force compression
|
|
93
|
+
mythos chat
|
|
116
94
|
```
|
|
117
95
|
|
|
118
|
-
|
|
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
|
-
##
|
|
105
|
+
## Safety & Execution Control
|
|
123
106
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
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
|
-
###
|
|
143
|
-
|
|
113
|
+
### Verbose mode
|
|
114
|
+
Inspect execution steps and verification logic:
|
|
115
|
+
```bash
|
|
116
|
+
mythos chat --verbose
|
|
144
117
|
```
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
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
|
-
##
|
|
126
|
+
## Token Budgeting
|
|
172
127
|
|
|
173
|
-
|
|
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
|
-
|
|
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
|
-
##
|
|
140
|
+
## Commands
|
|
183
141
|
|
|
184
|
-
|
|
142
|
+
### Chat session
|
|
143
|
+
```bash
|
|
144
|
+
mythos chat
|
|
145
|
+
```
|
|
185
146
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
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
|
-
|
|
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
|
-
##
|
|
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
|
-
|
|
198
|
-
|-------------|----------|-------------|
|
|
199
|
-
| `ANTHROPIC_API_KEY` | ✅ | Your Anthropic API key |
|
|
180
|
+
---
|
|
200
181
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
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
|
-
##
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
228
|
-
|
|
229
|
-
|
|
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>
|
package/dist/budget.d.ts
ADDED
|
@@ -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":"AAAA,gEAAgE;AAChE,8BAA8B;AAC9B,oDAAoD;AACpD,gEAAgE;AAEhE,OAAO,EACL,8BAA8B,EAC9B,iBAAiB,EACjB,mBAAmB,EACnB,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,CAAC,EAAE,MAAM,YAAY,CAAC;AAoC/B,gEAAgE;AAChE,MAAM,OAAO,aAAa;IAChB,MAAM,CAAe;IACrB,UAAU,GAAG,CAAC,CAAC;IACf,WAAW,GAAG,CAAC,CAAC;IAChB,SAAS,GAAG,CAAC,CAAC;IACd,SAAS,CAAS;IAClB,OAAO,CAAU;IAEzB,YAAY,MAA8B,EAAE,OAAO,GAAG,IAAI;QACxD,IAAI,CAAC,MAAM,GAAG;YACZ,SAAS,EAAE,MAAM,EAAE,SAAS,IAAI,8BAA8B;YAC9D,QAAQ,EAAE,MAAM,EAAE,QAAQ,IAAI,iBAAiB;YAC/C,aAAa,EAAE,MAAM,EAAE,aAAa,IAAI,mBAAmB;YAC3D,iBAAiB,EAAE,MAAM,EAAE,iBAAiB,IAAI,oBAAoB;YACpE,kBAAkB,EAAE,MAAM,EAAE,kBAAkB,IAAI,qBAAqB;SACxE,CAAC;QACF,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC5B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED,4DAA4D;IAC5D,MAAM,CAAC,WAAmB,EAAE,YAAoB;QAC9C,IAAI,CAAC,UAAU,IAAI,WAAW,CAAC;QAC/B,IAAI,CAAC,WAAW,IAAI,YAAY,CAAC;QACjC,IAAI,CAAC,SAAS,EAAE,CAAC;IACnB,CAAC;IAED,4DAA4D;IAC5D,KAAK;QACH,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAClB,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;QAC3F,CAAC;QAED,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC;QACvD,MAAM,aAAa,GAAG,CAAC,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,GAAG,CAAC;QAClE,MAAM,YAAY,GAAG,CAAC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,GAAG,CAAC;QACnE,MAAM,OAAO,GACX,aAAa,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa;YAC1C,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC;QAE5C,uBAAuB;QACvB,IAAI,WAAW,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;YACzC,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,SAAS,EAAE,IAAI;gBACf,MAAM,EACJ,6BAA6B,WAAW,CAAC,cAAc,EAAE,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,EAAE,UAAU;oBAC7G,eAAe,IAAI,CAAC,SAAS,UAAU;oBACvC,6DAA6D;gBAC/D,aAAa,EAAE,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,GAAG,CAAC;gBAC3C,YAAY;gBACZ,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;QAED,sBAAsB;QACtB,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;YAC3C,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,SAAS,EAAE,IAAI;gBACf,MAAM,EACJ,+BAA+B,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,UAAU;oBAC/E,4DAA4D;gBAC9D,aAAa;gBACb,YAAY,EAAE,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,GAAG,CAAC;gBACzC,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;QAED,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IAC9E,CAAC;IAED,4DAA4D;IAC5D,MAAM;QACJ,MAAM,gBAAgB,GACpB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,iBAAiB;YAC/C,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC;QACpD,OAAO;YACL,WAAW,EAAE,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,WAAW;YAC/C,WAAW,EAAE,IAAI,CAAC,UAAU;YAC5B,YAAY,EAAE,IAAI,CAAC,WAAW;YAC9B,KAAK,EAAE,IAAI,CAAC,SAAS;YACrB,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS;YAChC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ;YAC9B,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS;YACtC,gBAAgB;SACjB,CAAC;IACJ,CAAC;IAED,4DAA4D;IAC5D,SAAS;QACP,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED,4DAA4D;IAC5D,SAAS,CAAC,KAAK,GAAG,EAAE;QAClB,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAClB,OAAO,GAAG,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,MAAM,WAAW,CAAC,CAAC,GAAG,iBAAiB,CAAC,CAAC,KAAK,EAAE,CAAC;QAC/E,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CACrB,CAAC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,GAAG,EACzC,GAAG,CACJ,CAAC;QACF,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CACtB,CAAC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,GAAG,EAClC,GAAG,CACJ,CAAC;QAEF,MAAM,MAAM,GAAG,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAC1C,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;QAE5D,MAAM,QAAQ,GAAG,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QACjG,MAAM,SAAS,GAAG,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QAEpG,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAE9C,OAAO,CACL,GAAG,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,KAAK,GAAG;YAC5B,GAAG,QAAQ,GAAG,MAAM,GAAG,CAAC,CAAC,KAAK,GAAG;YACjC,GAAG,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC,KAAK,KAAK;YAChH,GAAG,SAAS,GAAG,OAAO,GAAG,CAAC,CAAC,KAAK,GAAG;YACnC,GAAG,SAAS,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC,QAAQ,SAAS,CAAC,CAAC,KAAK,KAAK;YACvE,GAAG,CAAC,CAAC,GAAG,KAAK,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,EAAE,CACvE,CAAC;IACJ,CAAC;IAED,4DAA4D;IAC5D,aAAa;QACX,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC;QAE/B,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,aAAa,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;QAElE,IAAI,CAAC,EAAE,EAAE,CAAC;YACR,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;YAC3B,OAAO,CACL,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,mCAAmC,CAAC,CAAC,KAAK,IAAI;gBAClE,GAAG,CAAC,CAAC,GAAG,KAAK,IAAI,CAAC,WAAW,CAAC,cAAc,EAAE,2BAA2B,IAAI,CAAC,KAAK,aAAa,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,IAAI;gBAChJ,GAAG,CAAC,CAAC,KAAK,8CAA8C,CAAC,CAAC,IAAI,cAAc,CAAC,CAAC,KAAK,gBAAgB,CAAC,CAAC,KAAK,IAAI;gBAC9G,GAAG,CAAC,CAAC,GAAG,sBAAsB,CAAC,CAAC,IAAI,kDAAkD,CAAC,CAAC,KAAK,IAAI;gBACjG,GAAG,CAAC,CAAC,GAAG,sBAAsB,CAAC,CAAC,IAAI,0BAA0B,CAAC,CAAC,KAAK,EAAE,CACxE,CAAC;QACJ,CAAC;QAED,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;YACrD,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;YAC3B,OAAO,CACL,GAAG,CAAC,CAAC,MAAM,YAAY,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,KAAK,KAAK;gBAClE,GAAG,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,cAAc,EAAE,aAAa,IAAI,CAAC,KAAK,SAAS,CAAC,CAAC,KAAK,EAAE,CACtF,CAAC;QACJ,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED,6DAA6D;IAC7D,oBAAoB;QAClB,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC3B,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC9C,OAAO,CACL,gBAAgB,IAAI,CAAC,WAAW,CAAC,cAAc,EAAE,YAAY;YAC7D,GAAG,IAAI,CAAC,KAAK,cAAc,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,OAAO,EAAE,CAC3E,CAAC;IACJ,CAAC;CACF;AAED,gEAAgE;AAChE,SAAS,WAAW,CAAC,OAAe,EAAE,KAAa;IACjD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,GAAG,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC;IACnD,MAAM,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;IAC7B,OAAO,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC;AACvD,CAAC;AAED,gEAAgE;AAChE,SAAS,aAAa,CAAC,EAAU;IAC/B,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;IACtC,IAAI,OAAO,GAAG,EAAE;QAAE,OAAO,GAAG,OAAO,GAAG,CAAC;IACvC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;IACzC,MAAM,IAAI,GAAG,OAAO,GAAG,EAAE,CAAC;IAC1B,IAAI,OAAO,GAAG,EAAE;QAAE,OAAO,GAAG,OAAO,KAAK,IAAI,GAAG,CAAC;IAChD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;IACvC,MAAM,IAAI,GAAG,OAAO,GAAG,EAAE,CAAC;IAC1B,OAAO,GAAG,KAAK,KAAK,IAAI,GAAG,CAAC;AAC9B,CAAC"}
|