dino-spec 13.6.0 → 14.0.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/bin/dino-hud.js +1 -1
- package/bin/dino.js +1 -1
- package/dist/core/agents/context-isolation.js +26 -26
- package/dist/core/context/__tests__/budget-thresholds.test.d.ts +5 -0
- package/dist/core/context/__tests__/budget-thresholds.test.d.ts.map +1 -0
- package/dist/core/context/__tests__/budget-thresholds.test.js +223 -0
- package/dist/core/context/__tests__/budget-thresholds.test.js.map +1 -0
- package/dist/core/context/__tests__/compaction-engine.test.d.ts +5 -0
- package/dist/core/context/__tests__/compaction-engine.test.d.ts.map +1 -0
- package/dist/core/context/__tests__/compaction-engine.test.js +474 -0
- package/dist/core/context/__tests__/compaction-engine.test.js.map +1 -0
- package/dist/core/context/__tests__/output-persistence.test.d.ts +5 -0
- package/dist/core/context/__tests__/output-persistence.test.d.ts.map +1 -0
- package/dist/core/context/__tests__/output-persistence.test.js +246 -0
- package/dist/core/context/__tests__/output-persistence.test.js.map +1 -0
- package/dist/core/context/budget-thresholds.d.ts +167 -0
- package/dist/core/context/budget-thresholds.d.ts.map +1 -0
- package/dist/core/context/budget-thresholds.js +234 -0
- package/dist/core/context/budget-thresholds.js.map +1 -0
- package/dist/core/context/compaction-engine.d.ts +193 -0
- package/dist/core/context/compaction-engine.d.ts.map +1 -0
- package/dist/core/context/compaction-engine.js +376 -0
- package/dist/core/context/compaction-engine.js.map +1 -0
- package/dist/core/context/index.d.ts +7 -3
- package/dist/core/context/index.d.ts.map +1 -1
- package/dist/core/context/index.js +22 -3
- package/dist/core/context/index.js.map +1 -1
- package/dist/core/context/output-persistence.d.ts +142 -0
- package/dist/core/context/output-persistence.d.ts.map +1 -0
- package/dist/core/context/output-persistence.js +242 -0
- package/dist/core/context/output-persistence.js.map +1 -0
- package/dist/core/environment/__tests__/pre-verify.test.d.ts +5 -0
- package/dist/core/environment/__tests__/pre-verify.test.d.ts.map +1 -0
- package/dist/core/environment/__tests__/pre-verify.test.js +343 -0
- package/dist/core/environment/__tests__/pre-verify.test.js.map +1 -0
- package/dist/core/environment/index.d.ts +8 -0
- package/dist/core/environment/index.d.ts.map +1 -0
- package/dist/core/environment/index.js +7 -0
- package/dist/core/environment/index.js.map +1 -0
- package/dist/core/environment/pre-verify.d.ts +63 -0
- package/dist/core/environment/pre-verify.d.ts.map +1 -0
- package/dist/core/environment/pre-verify.js +221 -0
- package/dist/core/environment/pre-verify.js.map +1 -0
- package/dist/core/environment/types.d.ts +37 -0
- package/dist/core/environment/types.d.ts.map +1 -0
- package/dist/core/environment/types.js +5 -0
- package/dist/core/environment/types.js.map +1 -0
- package/dist/core/intelligence/context-budget.d.ts +10 -5
- package/dist/core/intelligence/context-budget.d.ts.map +1 -1
- package/dist/core/intelligence/context-budget.js +12 -5
- package/dist/core/intelligence/context-budget.js.map +1 -1
- package/dist/mcp/__tests__/dynamic-updates.test.d.ts +5 -0
- package/dist/mcp/__tests__/dynamic-updates.test.d.ts.map +1 -0
- package/dist/mcp/__tests__/dynamic-updates.test.js +314 -0
- package/dist/mcp/__tests__/dynamic-updates.test.js.map +1 -0
- package/dist/mcp/dynamic-updates.d.ts +167 -0
- package/dist/mcp/dynamic-updates.d.ts.map +1 -0
- package/dist/mcp/dynamic-updates.js +313 -0
- package/dist/mcp/dynamic-updates.js.map +1 -0
- package/dist/mcp/index.d.ts +4 -2
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +5 -2
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/registry.d.ts +4 -4
- package/dist/mcp/registry.d.ts.map +1 -1
- package/dist/mcp/registry.js +16 -16
- package/dist/mcp/registry.js.map +1 -1
- package/dist/mcp/tools/__tests__/environment.test.d.ts +5 -0
- package/dist/mcp/tools/__tests__/environment.test.d.ts.map +1 -0
- package/dist/mcp/tools/__tests__/environment.test.js +219 -0
- package/dist/mcp/tools/__tests__/environment.test.js.map +1 -0
- package/dist/mcp/tools/environment.d.ts +27 -0
- package/dist/mcp/tools/environment.d.ts.map +1 -0
- package/dist/mcp/tools/environment.js +97 -0
- package/dist/mcp/tools/environment.js.map +1 -0
- package/dist/mcp/tools/index.d.ts +3 -1
- package/dist/mcp/tools/index.d.ts.map +1 -1
- package/dist/mcp/tools/index.js +13 -1
- package/dist/mcp/tools/index.js.map +1 -1
- package/dist/mcp/tools/output-persistence.d.ts +44 -0
- package/dist/mcp/tools/output-persistence.d.ts.map +1 -0
- package/dist/mcp/tools/output-persistence.js +208 -0
- package/dist/mcp/tools/output-persistence.js.map +1 -0
- package/dist/mcp-server.d.ts +2 -1
- package/dist/mcp-server.d.ts.map +1 -1
- package/dist/mcp-server.js +27 -2
- package/dist/mcp-server.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Output Persistence Tests - v14.0.0
|
|
3
|
+
*/
|
|
4
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
5
|
+
import { join } from 'path';
|
|
6
|
+
import { mkdir, rm, writeFile } from 'fs/promises';
|
|
7
|
+
import { OUTPUT_SIZE_THRESHOLD, OUTPUT_DIR, OUTPUT_RETENTION_DAYS, shouldPersist, persistOutput, readPersistedOutput, listPersistedOutputs, cleanupExpiredOutputs, getPersistedOutputsStats, generateContentHash, generateOutputFilename, createFileReference, parseFileReference, formatPersistenceResult, } from '../output-persistence.js';
|
|
8
|
+
describe('Output Persistence', () => {
|
|
9
|
+
const testDir = join(process.cwd(), 'test-output-persistence-temp');
|
|
10
|
+
beforeEach(async () => {
|
|
11
|
+
// Create fresh test directory
|
|
12
|
+
await mkdir(testDir, { recursive: true });
|
|
13
|
+
});
|
|
14
|
+
afterEach(async () => {
|
|
15
|
+
// Clean up test directory
|
|
16
|
+
try {
|
|
17
|
+
await rm(testDir, { recursive: true, force: true });
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
// Ignore errors
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
describe('Constants', () => {
|
|
24
|
+
it('should have correct size threshold', () => {
|
|
25
|
+
expect(OUTPUT_SIZE_THRESHOLD).toBe(30_000);
|
|
26
|
+
});
|
|
27
|
+
it('should have correct output directory', () => {
|
|
28
|
+
expect(OUTPUT_DIR).toBe('.dino/outputs');
|
|
29
|
+
});
|
|
30
|
+
it('should have correct retention days', () => {
|
|
31
|
+
expect(OUTPUT_RETENTION_DAYS).toBe(7);
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
describe('generateContentHash', () => {
|
|
35
|
+
it('should generate 8-character hash', () => {
|
|
36
|
+
const hash = generateContentHash('test content');
|
|
37
|
+
expect(hash.length).toBe(8);
|
|
38
|
+
});
|
|
39
|
+
it('should generate consistent hash for same content', () => {
|
|
40
|
+
const hash1 = generateContentHash('test content');
|
|
41
|
+
const hash2 = generateContentHash('test content');
|
|
42
|
+
expect(hash1).toBe(hash2);
|
|
43
|
+
});
|
|
44
|
+
it('should generate different hash for different content', () => {
|
|
45
|
+
const hash1 = generateContentHash('content 1');
|
|
46
|
+
const hash2 = generateContentHash('content 2');
|
|
47
|
+
expect(hash1).not.toBe(hash2);
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
describe('generateOutputFilename', () => {
|
|
51
|
+
it('should generate filename with timestamp and hash', () => {
|
|
52
|
+
const filename = generateOutputFilename('test content');
|
|
53
|
+
expect(filename).toMatch(/^\d{4}-\d{2}-\d{2}T.*-[a-f0-9]{8}\.txt$/);
|
|
54
|
+
});
|
|
55
|
+
it('should generate unique filenames', () => {
|
|
56
|
+
const filename1 = generateOutputFilename('content 1');
|
|
57
|
+
const filename2 = generateOutputFilename('content 2');
|
|
58
|
+
expect(filename1).not.toBe(filename2);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
describe('shouldPersist', () => {
|
|
62
|
+
it('should return false for small content', () => {
|
|
63
|
+
const smallContent = 'a'.repeat(1000);
|
|
64
|
+
expect(shouldPersist(smallContent)).toBe(false);
|
|
65
|
+
});
|
|
66
|
+
it('should return true for large content', () => {
|
|
67
|
+
const largeContent = 'a'.repeat(OUTPUT_SIZE_THRESHOLD + 1);
|
|
68
|
+
expect(shouldPersist(largeContent)).toBe(true);
|
|
69
|
+
});
|
|
70
|
+
it('should return false for content exactly at threshold', () => {
|
|
71
|
+
const exactContent = 'a'.repeat(OUTPUT_SIZE_THRESHOLD);
|
|
72
|
+
expect(shouldPersist(exactContent)).toBe(false);
|
|
73
|
+
});
|
|
74
|
+
it('should respect custom threshold', () => {
|
|
75
|
+
const content = 'a'.repeat(500);
|
|
76
|
+
expect(shouldPersist(content, { threshold: 100 })).toBe(true);
|
|
77
|
+
});
|
|
78
|
+
it('should persist when forced', () => {
|
|
79
|
+
const smallContent = 'a'.repeat(100);
|
|
80
|
+
expect(shouldPersist(smallContent, { force: true })).toBe(true);
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
describe('createFileReference', () => {
|
|
84
|
+
it('should create properly formatted reference', () => {
|
|
85
|
+
const ref = createFileReference('.dino/outputs/test.txt', 50000);
|
|
86
|
+
expect(ref).toContain('[Output persisted to:');
|
|
87
|
+
expect(ref).toContain('.dino/outputs/test.txt');
|
|
88
|
+
expect(ref).toContain('50,000 chars');
|
|
89
|
+
expect(ref).toContain('tokens');
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
describe('parseFileReference', () => {
|
|
93
|
+
it('should parse valid file reference', () => {
|
|
94
|
+
const ref = '[Output persisted to: .dino/outputs/test.txt (50,000 chars, ~12,500 tokens)]';
|
|
95
|
+
expect(parseFileReference(ref)).toBe('.dino/outputs/test.txt');
|
|
96
|
+
});
|
|
97
|
+
it('should return null for invalid reference', () => {
|
|
98
|
+
expect(parseFileReference('not a reference')).toBeNull();
|
|
99
|
+
});
|
|
100
|
+
it('should return null for empty string', () => {
|
|
101
|
+
expect(parseFileReference('')).toBeNull();
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
describe('persistOutput', () => {
|
|
105
|
+
it('should not persist small content', async () => {
|
|
106
|
+
const smallContent = 'small content';
|
|
107
|
+
const result = await persistOutput(smallContent, testDir);
|
|
108
|
+
expect(result.persisted).toBe(false);
|
|
109
|
+
expect(result.reference).toBe(smallContent);
|
|
110
|
+
expect(result.tokensSaved).toBe(0);
|
|
111
|
+
});
|
|
112
|
+
it('should persist large content', async () => {
|
|
113
|
+
const largeContent = 'a'.repeat(OUTPUT_SIZE_THRESHOLD + 1000);
|
|
114
|
+
const result = await persistOutput(largeContent, testDir);
|
|
115
|
+
expect(result.persisted).toBe(true);
|
|
116
|
+
expect(result.reference).toContain('[Output persisted to:');
|
|
117
|
+
expect(result.originalSize).toBe(largeContent.length);
|
|
118
|
+
expect(result.tokensSaved).toBeGreaterThan(0);
|
|
119
|
+
});
|
|
120
|
+
it('should create output file', async () => {
|
|
121
|
+
const largeContent = 'a'.repeat(OUTPUT_SIZE_THRESHOLD + 1000);
|
|
122
|
+
const result = await persistOutput(largeContent, testDir);
|
|
123
|
+
// Extract path from reference
|
|
124
|
+
const path = parseFileReference(result.reference);
|
|
125
|
+
expect(path).not.toBeNull();
|
|
126
|
+
// Verify file exists
|
|
127
|
+
const content = await readPersistedOutput(path, testDir);
|
|
128
|
+
expect(content).toBe(largeContent);
|
|
129
|
+
});
|
|
130
|
+
it('should create metadata file', async () => {
|
|
131
|
+
const largeContent = 'a'.repeat(OUTPUT_SIZE_THRESHOLD + 1000);
|
|
132
|
+
await persistOutput(largeContent, testDir, { source: 'test-tool' });
|
|
133
|
+
const outputs = await listPersistedOutputs(testDir);
|
|
134
|
+
expect(outputs.length).toBe(1);
|
|
135
|
+
expect(outputs[0].source).toBe('test-tool');
|
|
136
|
+
expect(outputs[0].sizeChars).toBe(largeContent.length);
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
describe('readPersistedOutput', () => {
|
|
140
|
+
it('should read existing output', async () => {
|
|
141
|
+
const content = 'test content for reading';
|
|
142
|
+
const outputDir = join(testDir, OUTPUT_DIR);
|
|
143
|
+
await mkdir(outputDir, { recursive: true });
|
|
144
|
+
const filePath = join(outputDir, 'test-read.txt');
|
|
145
|
+
await writeFile(filePath, content);
|
|
146
|
+
const result = await readPersistedOutput(join(OUTPUT_DIR, 'test-read.txt'), testDir);
|
|
147
|
+
expect(result).toBe(content);
|
|
148
|
+
});
|
|
149
|
+
it('should return null for non-existent file', async () => {
|
|
150
|
+
const result = await readPersistedOutput('.dino/outputs/nonexistent.txt', testDir);
|
|
151
|
+
expect(result).toBeNull();
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
describe('listPersistedOutputs', () => {
|
|
155
|
+
it('should return empty array when no outputs', async () => {
|
|
156
|
+
const outputs = await listPersistedOutputs(testDir);
|
|
157
|
+
expect(outputs).toEqual([]);
|
|
158
|
+
});
|
|
159
|
+
it('should list all outputs', async () => {
|
|
160
|
+
// Create multiple outputs
|
|
161
|
+
const content1 = 'a'.repeat(OUTPUT_SIZE_THRESHOLD + 100);
|
|
162
|
+
const content2 = 'b'.repeat(OUTPUT_SIZE_THRESHOLD + 200);
|
|
163
|
+
await persistOutput(content1, testDir, { source: 'tool1' });
|
|
164
|
+
await persistOutput(content2, testDir, { source: 'tool2' });
|
|
165
|
+
const outputs = await listPersistedOutputs(testDir);
|
|
166
|
+
expect(outputs.length).toBe(2);
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
describe('cleanupExpiredOutputs', () => {
|
|
170
|
+
it('should clean up expired outputs', async () => {
|
|
171
|
+
// Create an expired output manually
|
|
172
|
+
const outputDir = join(testDir, OUTPUT_DIR);
|
|
173
|
+
await mkdir(outputDir, { recursive: true });
|
|
174
|
+
const expiredMeta = {
|
|
175
|
+
path: join(OUTPUT_DIR, 'expired.txt'),
|
|
176
|
+
hash: 'abc12345',
|
|
177
|
+
sizeChars: 1000,
|
|
178
|
+
createdAt: new Date(Date.now() - 10 * 24 * 60 * 60 * 1000).toISOString(), // 10 days ago
|
|
179
|
+
expiresAt: new Date(Date.now() - 3 * 24 * 60 * 60 * 1000).toISOString(), // 3 days ago (expired)
|
|
180
|
+
};
|
|
181
|
+
await writeFile(join(outputDir, 'expired.txt'), 'expired content');
|
|
182
|
+
await writeFile(join(outputDir, 'expired.meta.json'), JSON.stringify(expiredMeta));
|
|
183
|
+
const cleaned = await cleanupExpiredOutputs(testDir);
|
|
184
|
+
expect(cleaned).toBe(1);
|
|
185
|
+
// Verify file is gone
|
|
186
|
+
const outputs = await listPersistedOutputs(testDir);
|
|
187
|
+
expect(outputs.length).toBe(0);
|
|
188
|
+
});
|
|
189
|
+
it('should not clean up non-expired outputs', async () => {
|
|
190
|
+
const content = 'a'.repeat(OUTPUT_SIZE_THRESHOLD + 100);
|
|
191
|
+
await persistOutput(content, testDir);
|
|
192
|
+
const cleaned = await cleanupExpiredOutputs(testDir);
|
|
193
|
+
expect(cleaned).toBe(0);
|
|
194
|
+
const outputs = await listPersistedOutputs(testDir);
|
|
195
|
+
expect(outputs.length).toBe(1);
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
describe('getPersistedOutputsStats', () => {
|
|
199
|
+
it('should return empty stats when no outputs', async () => {
|
|
200
|
+
const stats = await getPersistedOutputsStats(testDir);
|
|
201
|
+
expect(stats.count).toBe(0);
|
|
202
|
+
expect(stats.totalChars).toBe(0);
|
|
203
|
+
expect(stats.estimatedTokensSaved).toBe(0);
|
|
204
|
+
});
|
|
205
|
+
it('should calculate correct stats', async () => {
|
|
206
|
+
const content1 = 'a'.repeat(OUTPUT_SIZE_THRESHOLD + 100);
|
|
207
|
+
const content2 = 'b'.repeat(OUTPUT_SIZE_THRESHOLD + 200);
|
|
208
|
+
await persistOutput(content1, testDir);
|
|
209
|
+
await persistOutput(content2, testDir);
|
|
210
|
+
const stats = await getPersistedOutputsStats(testDir);
|
|
211
|
+
expect(stats.count).toBe(2);
|
|
212
|
+
expect(stats.totalChars).toBe(content1.length + content2.length);
|
|
213
|
+
expect(stats.estimatedTokensSaved).toBeGreaterThan(0);
|
|
214
|
+
expect(stats.oldestOutput).not.toBeNull();
|
|
215
|
+
expect(stats.newestOutput).not.toBeNull();
|
|
216
|
+
});
|
|
217
|
+
});
|
|
218
|
+
describe('formatPersistenceResult', () => {
|
|
219
|
+
it('should format non-persisted result', () => {
|
|
220
|
+
const result = {
|
|
221
|
+
persisted: false,
|
|
222
|
+
reference: 'original content',
|
|
223
|
+
originalSize: 15,
|
|
224
|
+
estimatedTokens: 4,
|
|
225
|
+
tokensSaved: 0,
|
|
226
|
+
};
|
|
227
|
+
const formatted = formatPersistenceResult(result);
|
|
228
|
+
expect(formatted).toContain('not persisted');
|
|
229
|
+
expect(formatted).toContain('below threshold');
|
|
230
|
+
});
|
|
231
|
+
it('should format persisted result', () => {
|
|
232
|
+
const result = {
|
|
233
|
+
persisted: true,
|
|
234
|
+
reference: '[Output persisted to: .dino/outputs/test.txt (50,000 chars, ~12,500 tokens)]',
|
|
235
|
+
originalSize: 50000,
|
|
236
|
+
estimatedTokens: 12500,
|
|
237
|
+
tokensSaved: 12450,
|
|
238
|
+
};
|
|
239
|
+
const formatted = formatPersistenceResult(result);
|
|
240
|
+
expect(formatted).toContain('successfully');
|
|
241
|
+
expect(formatted).toContain('50,000 chars');
|
|
242
|
+
expect(formatted).toContain('Tokens saved');
|
|
243
|
+
});
|
|
244
|
+
});
|
|
245
|
+
});
|
|
246
|
+
//# sourceMappingURL=output-persistence.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output-persistence.test.js","sourceRoot":"","sources":["../../../../src/core/context/__tests__/output-persistence.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Budget Thresholds - v14.0.0
|
|
3
|
+
*
|
|
4
|
+
* Configurable context budget thresholds with safety margins.
|
|
5
|
+
* Optimized for Claude 4.5's extended context window (200K tokens).
|
|
6
|
+
*
|
|
7
|
+
* Key improvements over v13.x:
|
|
8
|
+
* - Raised thresholds from 80/90/95% to 85/95/98%
|
|
9
|
+
* - Safety margin calculation for reliable headroom
|
|
10
|
+
* - Config-driven thresholds via .dino/config.json
|
|
11
|
+
* - Backwards compatible with existing budget tracking
|
|
12
|
+
*
|
|
13
|
+
* Reference: Anthropic context engineering best practices
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Default budget thresholds (v14.0.0)
|
|
17
|
+
*
|
|
18
|
+
* These thresholds are optimized for safe context utilization
|
|
19
|
+
* while maximizing available token budget.
|
|
20
|
+
*/
|
|
21
|
+
export declare const OPTIMIZED_BUDGET_THRESHOLDS: {
|
|
22
|
+
/** Start monitoring - context filling up */
|
|
23
|
+
readonly WARNING: 0.85;
|
|
24
|
+
/** High usage - recommend compaction */
|
|
25
|
+
readonly HIGH: 0.95;
|
|
26
|
+
/** Critical - force compaction recommendation */
|
|
27
|
+
readonly CRITICAL: 0.98;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Legacy thresholds for backwards compatibility
|
|
31
|
+
*/
|
|
32
|
+
export declare const LEGACY_BUDGET_THRESHOLDS: {
|
|
33
|
+
readonly WARNING: 0.8;
|
|
34
|
+
readonly HIGH: 0.9;
|
|
35
|
+
readonly CRITICAL: 0.95;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Default safety margin in tokens
|
|
39
|
+
*
|
|
40
|
+
* Reserved buffer to prevent context overflow.
|
|
41
|
+
* Provides headroom for system messages and unexpected content.
|
|
42
|
+
*/
|
|
43
|
+
export declare const DEFAULT_SAFETY_MARGIN = 2000;
|
|
44
|
+
/**
|
|
45
|
+
* Threshold configuration interface
|
|
46
|
+
*/
|
|
47
|
+
export interface ThresholdConfig {
|
|
48
|
+
/** Warning threshold (0-1) */
|
|
49
|
+
warning: number;
|
|
50
|
+
/** High threshold (0-1) */
|
|
51
|
+
high: number;
|
|
52
|
+
/** Critical threshold (0-1) */
|
|
53
|
+
critical: number;
|
|
54
|
+
/** Safety margin in tokens */
|
|
55
|
+
safetyMargin: number;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Threshold level type
|
|
59
|
+
*/
|
|
60
|
+
export type ThresholdLevel = 'safe' | 'warning' | 'high' | 'critical';
|
|
61
|
+
/**
|
|
62
|
+
* Threshold result with remaining capacity
|
|
63
|
+
*/
|
|
64
|
+
export interface ThresholdResult {
|
|
65
|
+
/** Current threshold level */
|
|
66
|
+
level: ThresholdLevel;
|
|
67
|
+
/** Remaining tokens before limit */
|
|
68
|
+
remaining: number;
|
|
69
|
+
/** Safe remaining after subtracting safety margin */
|
|
70
|
+
safeRemaining: number;
|
|
71
|
+
/** Current usage percentage (0-100) */
|
|
72
|
+
percentage: number;
|
|
73
|
+
/** Whether compaction is recommended */
|
|
74
|
+
shouldCompact: boolean;
|
|
75
|
+
/** Whether compaction is urgent */
|
|
76
|
+
forceCompact: boolean;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Default threshold configuration
|
|
80
|
+
*/
|
|
81
|
+
export declare const DEFAULT_THRESHOLD_CONFIG: ThresholdConfig;
|
|
82
|
+
/**
|
|
83
|
+
* Get threshold level from usage percentage
|
|
84
|
+
*
|
|
85
|
+
* @param usage - Current token usage
|
|
86
|
+
* @param limit - Context limit in tokens
|
|
87
|
+
* @param config - Threshold configuration (optional)
|
|
88
|
+
* @returns ThresholdLevel
|
|
89
|
+
*/
|
|
90
|
+
export declare function getThresholdLevel(usage: number, limit: number, config?: ThresholdConfig): ThresholdLevel;
|
|
91
|
+
/**
|
|
92
|
+
* Calculate threshold result with safety margin
|
|
93
|
+
*
|
|
94
|
+
* @param usage - Current token usage
|
|
95
|
+
* @param limit - Context limit in tokens
|
|
96
|
+
* @param config - Threshold configuration (optional)
|
|
97
|
+
* @returns ThresholdResult with remaining capacity
|
|
98
|
+
*/
|
|
99
|
+
export declare function calculateThresholdResult(usage: number, limit: number, config?: ThresholdConfig): ThresholdResult;
|
|
100
|
+
/**
|
|
101
|
+
* Load threshold configuration from config.json
|
|
102
|
+
*
|
|
103
|
+
* Configuration can be customized via .dino/config.json:
|
|
104
|
+
* ```json
|
|
105
|
+
* {
|
|
106
|
+
* "custom": {
|
|
107
|
+
* "budgetThresholds": {
|
|
108
|
+
* "warning": 0.85,
|
|
109
|
+
* "high": 0.95,
|
|
110
|
+
* "critical": 0.98,
|
|
111
|
+
* "safetyMargin": 2000
|
|
112
|
+
* }
|
|
113
|
+
* }
|
|
114
|
+
* }
|
|
115
|
+
* ```
|
|
116
|
+
*
|
|
117
|
+
* Falls back to optimized thresholds if not configured.
|
|
118
|
+
*
|
|
119
|
+
* @param projectDir - Project directory
|
|
120
|
+
* @returns ThresholdConfig
|
|
121
|
+
*/
|
|
122
|
+
export declare function loadThresholdConfig(projectDir?: string): Promise<ThresholdConfig>;
|
|
123
|
+
/**
|
|
124
|
+
* Check if using legacy thresholds
|
|
125
|
+
*
|
|
126
|
+
* Returns true if config has legacy threshold values.
|
|
127
|
+
* Useful for migration warnings.
|
|
128
|
+
*
|
|
129
|
+
* @param config - Threshold configuration
|
|
130
|
+
* @returns boolean
|
|
131
|
+
*/
|
|
132
|
+
export declare function isLegacyThresholds(config: ThresholdConfig): boolean;
|
|
133
|
+
/**
|
|
134
|
+
* Get recommendations for threshold level
|
|
135
|
+
*
|
|
136
|
+
* @param level - Current threshold level
|
|
137
|
+
* @returns Array of recommended actions
|
|
138
|
+
*/
|
|
139
|
+
export declare function getThresholdRecommendations(level: ThresholdLevel): string[];
|
|
140
|
+
/**
|
|
141
|
+
* Format threshold result for display
|
|
142
|
+
*
|
|
143
|
+
* @param result - Threshold result
|
|
144
|
+
* @returns Formatted string
|
|
145
|
+
*/
|
|
146
|
+
export declare function formatThresholdResult(result: ThresholdResult): string;
|
|
147
|
+
/**
|
|
148
|
+
* Calculate safe capacity at a threshold
|
|
149
|
+
*
|
|
150
|
+
* Returns the amount of tokens that can be safely used
|
|
151
|
+
* before hitting the specified threshold.
|
|
152
|
+
*
|
|
153
|
+
* @param limit - Context limit in tokens
|
|
154
|
+
* @param threshold - Threshold percentage (0-1)
|
|
155
|
+
* @param safetyMargin - Safety margin in tokens
|
|
156
|
+
* @returns Safe capacity in tokens
|
|
157
|
+
*/
|
|
158
|
+
export declare function calculateSafeCapacity(limit: number, threshold: number, safetyMargin?: number): number;
|
|
159
|
+
/**
|
|
160
|
+
* Get effective limit accounting for safety margin
|
|
161
|
+
*
|
|
162
|
+
* @param limit - Context limit in tokens
|
|
163
|
+
* @param config - Threshold configuration
|
|
164
|
+
* @returns Effective limit with safety margin applied
|
|
165
|
+
*/
|
|
166
|
+
export declare function getEffectiveLimit(limit: number, config?: ThresholdConfig): number;
|
|
167
|
+
//# sourceMappingURL=budget-thresholds.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"budget-thresholds.d.ts","sourceRoot":"","sources":["../../../src/core/context/budget-thresholds.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH;;;;;GAKG;AACH,eAAO,MAAM,2BAA2B;IACtC,4CAA4C;;IAE5C,wCAAwC;;IAExC,iDAAiD;;CAEzC,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,wBAAwB;;;;CAI3B,CAAC;AAEX;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,OAAO,CAAC;AAE1C;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,8BAA8B;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,2BAA2B;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,+BAA+B;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,8BAA8B;IAC9B,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,UAAU,CAAC;AAEtE;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,8BAA8B;IAC9B,KAAK,EAAE,cAAc,CAAC;IACtB,oCAAoC;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,qDAAqD;IACrD,aAAa,EAAE,MAAM,CAAC;IACtB,uCAAuC;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,wCAAwC;IACxC,aAAa,EAAE,OAAO,CAAC;IACvB,mCAAmC;IACnC,YAAY,EAAE,OAAO,CAAC;CACvB;AAED;;GAEG;AACH,eAAO,MAAM,wBAAwB,EAAE,eAKtC,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,MAAM,GAAE,eAA0C,GACjD,cAAc,CAahB;AAED;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,MAAM,GAAE,eAA0C,GACjD,eAAe,CAcjB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,mBAAmB,CACvC,UAAU,GAAE,MAAsB,GACjC,OAAO,CAAC,eAAe,CAAC,CAkB1B;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAMnE;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,EAAE,CA0B3E;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,CAsBrE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,YAAY,GAAE,MAA8B,GAC3C,MAAM,CAER;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,MAAM,EACb,MAAM,GAAE,eAA0C,GACjD,MAAM,CAGR"}
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Budget Thresholds - v14.0.0
|
|
3
|
+
*
|
|
4
|
+
* Configurable context budget thresholds with safety margins.
|
|
5
|
+
* Optimized for Claude 4.5's extended context window (200K tokens).
|
|
6
|
+
*
|
|
7
|
+
* Key improvements over v13.x:
|
|
8
|
+
* - Raised thresholds from 80/90/95% to 85/95/98%
|
|
9
|
+
* - Safety margin calculation for reliable headroom
|
|
10
|
+
* - Config-driven thresholds via .dino/config.json
|
|
11
|
+
* - Backwards compatible with existing budget tracking
|
|
12
|
+
*
|
|
13
|
+
* Reference: Anthropic context engineering best practices
|
|
14
|
+
*/
|
|
15
|
+
import { loadConfig } from '../config/feature-flags.js';
|
|
16
|
+
/**
|
|
17
|
+
* Default budget thresholds (v14.0.0)
|
|
18
|
+
*
|
|
19
|
+
* These thresholds are optimized for safe context utilization
|
|
20
|
+
* while maximizing available token budget.
|
|
21
|
+
*/
|
|
22
|
+
export const OPTIMIZED_BUDGET_THRESHOLDS = {
|
|
23
|
+
/** Start monitoring - context filling up */
|
|
24
|
+
WARNING: 0.85, // was 0.80
|
|
25
|
+
/** High usage - recommend compaction */
|
|
26
|
+
HIGH: 0.95, // was 0.90
|
|
27
|
+
/** Critical - force compaction recommendation */
|
|
28
|
+
CRITICAL: 0.98, // was 0.95
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Legacy thresholds for backwards compatibility
|
|
32
|
+
*/
|
|
33
|
+
export const LEGACY_BUDGET_THRESHOLDS = {
|
|
34
|
+
WARNING: 0.80,
|
|
35
|
+
HIGH: 0.90,
|
|
36
|
+
CRITICAL: 0.95,
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Default safety margin in tokens
|
|
40
|
+
*
|
|
41
|
+
* Reserved buffer to prevent context overflow.
|
|
42
|
+
* Provides headroom for system messages and unexpected content.
|
|
43
|
+
*/
|
|
44
|
+
export const DEFAULT_SAFETY_MARGIN = 2000;
|
|
45
|
+
/**
|
|
46
|
+
* Default threshold configuration
|
|
47
|
+
*/
|
|
48
|
+
export const DEFAULT_THRESHOLD_CONFIG = {
|
|
49
|
+
warning: OPTIMIZED_BUDGET_THRESHOLDS.WARNING,
|
|
50
|
+
high: OPTIMIZED_BUDGET_THRESHOLDS.HIGH,
|
|
51
|
+
critical: OPTIMIZED_BUDGET_THRESHOLDS.CRITICAL,
|
|
52
|
+
safetyMargin: DEFAULT_SAFETY_MARGIN,
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Get threshold level from usage percentage
|
|
56
|
+
*
|
|
57
|
+
* @param usage - Current token usage
|
|
58
|
+
* @param limit - Context limit in tokens
|
|
59
|
+
* @param config - Threshold configuration (optional)
|
|
60
|
+
* @returns ThresholdLevel
|
|
61
|
+
*/
|
|
62
|
+
export function getThresholdLevel(usage, limit, config = DEFAULT_THRESHOLD_CONFIG) {
|
|
63
|
+
const percentage = usage / limit;
|
|
64
|
+
if (percentage >= config.critical) {
|
|
65
|
+
return 'critical';
|
|
66
|
+
}
|
|
67
|
+
if (percentage >= config.high) {
|
|
68
|
+
return 'high';
|
|
69
|
+
}
|
|
70
|
+
if (percentage >= config.warning) {
|
|
71
|
+
return 'warning';
|
|
72
|
+
}
|
|
73
|
+
return 'safe';
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Calculate threshold result with safety margin
|
|
77
|
+
*
|
|
78
|
+
* @param usage - Current token usage
|
|
79
|
+
* @param limit - Context limit in tokens
|
|
80
|
+
* @param config - Threshold configuration (optional)
|
|
81
|
+
* @returns ThresholdResult with remaining capacity
|
|
82
|
+
*/
|
|
83
|
+
export function calculateThresholdResult(usage, limit, config = DEFAULT_THRESHOLD_CONFIG) {
|
|
84
|
+
const level = getThresholdLevel(usage, limit, config);
|
|
85
|
+
const remaining = Math.max(0, limit - usage);
|
|
86
|
+
const safeRemaining = Math.max(0, remaining - config.safetyMargin);
|
|
87
|
+
const percentage = Math.round((usage / limit) * 100);
|
|
88
|
+
return {
|
|
89
|
+
level,
|
|
90
|
+
remaining,
|
|
91
|
+
safeRemaining,
|
|
92
|
+
percentage,
|
|
93
|
+
shouldCompact: level === 'high' || level === 'critical',
|
|
94
|
+
forceCompact: level === 'critical',
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Load threshold configuration from config.json
|
|
99
|
+
*
|
|
100
|
+
* Configuration can be customized via .dino/config.json:
|
|
101
|
+
* ```json
|
|
102
|
+
* {
|
|
103
|
+
* "custom": {
|
|
104
|
+
* "budgetThresholds": {
|
|
105
|
+
* "warning": 0.85,
|
|
106
|
+
* "high": 0.95,
|
|
107
|
+
* "critical": 0.98,
|
|
108
|
+
* "safetyMargin": 2000
|
|
109
|
+
* }
|
|
110
|
+
* }
|
|
111
|
+
* }
|
|
112
|
+
* ```
|
|
113
|
+
*
|
|
114
|
+
* Falls back to optimized thresholds if not configured.
|
|
115
|
+
*
|
|
116
|
+
* @param projectDir - Project directory
|
|
117
|
+
* @returns ThresholdConfig
|
|
118
|
+
*/
|
|
119
|
+
export async function loadThresholdConfig(projectDir = process.cwd()) {
|
|
120
|
+
try {
|
|
121
|
+
const config = await loadConfig(projectDir);
|
|
122
|
+
const customThresholds = config.custom?.budgetThresholds;
|
|
123
|
+
if (customThresholds) {
|
|
124
|
+
return {
|
|
125
|
+
warning: customThresholds.warning ?? DEFAULT_THRESHOLD_CONFIG.warning,
|
|
126
|
+
high: customThresholds.high ?? DEFAULT_THRESHOLD_CONFIG.high,
|
|
127
|
+
critical: customThresholds.critical ?? DEFAULT_THRESHOLD_CONFIG.critical,
|
|
128
|
+
safetyMargin: customThresholds.safetyMargin ?? DEFAULT_THRESHOLD_CONFIG.safetyMargin,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
// Fall back to defaults on any error
|
|
134
|
+
}
|
|
135
|
+
return DEFAULT_THRESHOLD_CONFIG;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Check if using legacy thresholds
|
|
139
|
+
*
|
|
140
|
+
* Returns true if config has legacy threshold values.
|
|
141
|
+
* Useful for migration warnings.
|
|
142
|
+
*
|
|
143
|
+
* @param config - Threshold configuration
|
|
144
|
+
* @returns boolean
|
|
145
|
+
*/
|
|
146
|
+
export function isLegacyThresholds(config) {
|
|
147
|
+
return (config.warning === LEGACY_BUDGET_THRESHOLDS.WARNING &&
|
|
148
|
+
config.high === LEGACY_BUDGET_THRESHOLDS.HIGH &&
|
|
149
|
+
config.critical === LEGACY_BUDGET_THRESHOLDS.CRITICAL);
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Get recommendations for threshold level
|
|
153
|
+
*
|
|
154
|
+
* @param level - Current threshold level
|
|
155
|
+
* @returns Array of recommended actions
|
|
156
|
+
*/
|
|
157
|
+
export function getThresholdRecommendations(level) {
|
|
158
|
+
switch (level) {
|
|
159
|
+
case 'critical':
|
|
160
|
+
return [
|
|
161
|
+
'CRITICAL: Context at 98%+. Immediate compaction required.',
|
|
162
|
+
'Run: dino compact --force',
|
|
163
|
+
'Or start a new conversation with /dino.handoff',
|
|
164
|
+
'Consider using /dino.fossil to archive completed work.',
|
|
165
|
+
];
|
|
166
|
+
case 'high':
|
|
167
|
+
return [
|
|
168
|
+
'HIGH: Context at 95%+. Compaction recommended.',
|
|
169
|
+
'Run: dino compact',
|
|
170
|
+
'Avoid loading large files. Use targeted searches.',
|
|
171
|
+
'Checkpoint progress for potential handoff.',
|
|
172
|
+
];
|
|
173
|
+
case 'warning':
|
|
174
|
+
return [
|
|
175
|
+
'WARNING: Context at 85%+. Monitor usage.',
|
|
176
|
+
'Prefer grep/glob over full file reads.',
|
|
177
|
+
'Consider deferring non-essential file reads.',
|
|
178
|
+
];
|
|
179
|
+
case 'safe':
|
|
180
|
+
default:
|
|
181
|
+
return [];
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Format threshold result for display
|
|
186
|
+
*
|
|
187
|
+
* @param result - Threshold result
|
|
188
|
+
* @returns Formatted string
|
|
189
|
+
*/
|
|
190
|
+
export function formatThresholdResult(result) {
|
|
191
|
+
const indicator = result.level === 'critical' ? '[!!!]'
|
|
192
|
+
: result.level === 'high' ? '[!!]'
|
|
193
|
+
: result.level === 'warning' ? '[!]'
|
|
194
|
+
: '[OK]';
|
|
195
|
+
const lines = [];
|
|
196
|
+
lines.push(`## Budget Status ${indicator}`);
|
|
197
|
+
lines.push('');
|
|
198
|
+
lines.push(`**Level:** ${result.level.toUpperCase()} (${result.percentage}% used)`);
|
|
199
|
+
lines.push(`**Remaining:** ${Math.round(result.remaining / 1000)}K tokens`);
|
|
200
|
+
lines.push(`**Safe Remaining:** ${Math.round(result.safeRemaining / 1000)}K tokens`);
|
|
201
|
+
const recommendations = getThresholdRecommendations(result.level);
|
|
202
|
+
if (recommendations.length > 0) {
|
|
203
|
+
lines.push('');
|
|
204
|
+
lines.push('### Recommendations:');
|
|
205
|
+
recommendations.forEach((rec) => lines.push(`- ${rec}`));
|
|
206
|
+
}
|
|
207
|
+
return lines.join('\n');
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Calculate safe capacity at a threshold
|
|
211
|
+
*
|
|
212
|
+
* Returns the amount of tokens that can be safely used
|
|
213
|
+
* before hitting the specified threshold.
|
|
214
|
+
*
|
|
215
|
+
* @param limit - Context limit in tokens
|
|
216
|
+
* @param threshold - Threshold percentage (0-1)
|
|
217
|
+
* @param safetyMargin - Safety margin in tokens
|
|
218
|
+
* @returns Safe capacity in tokens
|
|
219
|
+
*/
|
|
220
|
+
export function calculateSafeCapacity(limit, threshold, safetyMargin = DEFAULT_SAFETY_MARGIN) {
|
|
221
|
+
return Math.max(0, Math.floor(limit * threshold) - safetyMargin);
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Get effective limit accounting for safety margin
|
|
225
|
+
*
|
|
226
|
+
* @param limit - Context limit in tokens
|
|
227
|
+
* @param config - Threshold configuration
|
|
228
|
+
* @returns Effective limit with safety margin applied
|
|
229
|
+
*/
|
|
230
|
+
export function getEffectiveLimit(limit, config = DEFAULT_THRESHOLD_CONFIG) {
|
|
231
|
+
// Use high threshold as the practical limit
|
|
232
|
+
return calculateSafeCapacity(limit, config.high, config.safetyMargin);
|
|
233
|
+
}
|
|
234
|
+
//# sourceMappingURL=budget-thresholds.js.map
|