dartmind 17.0.0 → 17.3.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/dist/cli/InteractiveModeV12.d.ts +4 -0
- package/dist/cli/InteractiveModeV12.d.ts.map +1 -1
- package/dist/cli/InteractiveModeV12.js +57 -1
- package/dist/cli/InteractiveModeV12.js.map +1 -1
- package/dist/cli/commands/SlashCommands.d.ts.map +1 -1
- package/dist/cli/commands/SlashCommands.js +21 -5
- package/dist/cli/commands/SlashCommands.js.map +1 -1
- package/dist/core/cost/__tests__/day1.test.d.ts +9 -0
- package/dist/core/cost/__tests__/day1.test.d.ts.map +1 -0
- package/dist/core/cost/__tests__/day1.test.js +284 -0
- package/dist/core/cost/__tests__/day1.test.js.map +1 -0
- package/dist/core/cost/__tests__/day2.test.d.ts +9 -0
- package/dist/core/cost/__tests__/day2.test.d.ts.map +1 -0
- package/dist/core/cost/__tests__/day2.test.js +414 -0
- package/dist/core/cost/__tests__/day2.test.js.map +1 -0
- package/dist/core/cost/__tests__/day3.test.d.ts +9 -0
- package/dist/core/cost/__tests__/day3.test.d.ts.map +1 -0
- package/dist/core/cost/__tests__/day3.test.js +415 -0
- package/dist/core/cost/__tests__/day3.test.js.map +1 -0
- package/dist/core/cost/__tests__/day4.test.d.ts +9 -0
- package/dist/core/cost/__tests__/day4.test.d.ts.map +1 -0
- package/dist/core/cost/__tests__/day4.test.js +354 -0
- package/dist/core/cost/__tests__/day4.test.js.map +1 -0
- package/dist/core/cost/context-scaler.d.ts +129 -0
- package/dist/core/cost/context-scaler.d.ts.map +1 -0
- package/dist/core/cost/context-scaler.js +336 -0
- package/dist/core/cost/context-scaler.js.map +1 -0
- package/dist/core/cost/index.d.ts +31 -0
- package/dist/core/cost/index.d.ts.map +1 -0
- package/dist/core/cost/index.js +103 -0
- package/dist/core/cost/index.js.map +1 -0
- package/dist/core/cost/integration.d.ts +144 -0
- package/dist/core/cost/integration.d.ts.map +1 -0
- package/dist/core/cost/integration.js +349 -0
- package/dist/core/cost/integration.js.map +1 -0
- package/dist/core/cost/model-router.d.ts +70 -0
- package/dist/core/cost/model-router.d.ts.map +1 -0
- package/dist/core/cost/model-router.js +319 -0
- package/dist/core/cost/model-router.js.map +1 -0
- package/dist/core/cost/prompt-cache.d.ts +98 -0
- package/dist/core/cost/prompt-cache.d.ts.map +1 -0
- package/dist/core/cost/prompt-cache.js +219 -0
- package/dist/core/cost/prompt-cache.js.map +1 -0
- package/dist/core/cost/reflex-layer.d.ts +48 -0
- package/dist/core/cost/reflex-layer.d.ts.map +1 -0
- package/dist/core/cost/reflex-layer.js +295 -0
- package/dist/core/cost/reflex-layer.js.map +1 -0
- package/dist/core/cost/response-cache.d.ts +139 -0
- package/dist/core/cost/response-cache.d.ts.map +1 -0
- package/dist/core/cost/response-cache.js +290 -0
- package/dist/core/cost/response-cache.js.map +1 -0
- package/dist/core/cost/tool-loader.d.ts +94 -0
- package/dist/core/cost/tool-loader.d.ts.map +1 -0
- package/dist/core/cost/tool-loader.js +233 -0
- package/dist/core/cost/tool-loader.js.map +1 -0
- package/dist/core/cost/types.d.ts +93 -0
- package/dist/core/cost/types.d.ts.map +1 -0
- package/dist/core/cost/types.js +29 -0
- package/dist/core/cost/types.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,414 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Day 2 Tests - Model Router
|
|
3
|
+
*
|
|
4
|
+
* Run with: npx vitest run src/core/cost/__tests__/day2.test.ts
|
|
5
|
+
*
|
|
6
|
+
* @module cost/__tests__/day2
|
|
7
|
+
*/
|
|
8
|
+
import { describe, test, expect } from 'vitest';
|
|
9
|
+
import { classifyTask, routeToModel, applyEscalation, estimateCost, calculateSavings, formatClassification, getModelTier, DEFAULT_ROUTER_CONFIG, CostOptimizer, MODEL_IDS, } from '../index.js';
|
|
10
|
+
describe('Model Router - Classification', () => {
|
|
11
|
+
describe('Code Generation (Sonnet)', () => {
|
|
12
|
+
test.each([
|
|
13
|
+
['create a login screen', 'generate'],
|
|
14
|
+
['build a button widget', 'generate'],
|
|
15
|
+
['make a new page', 'generate'],
|
|
16
|
+
['implement a service', 'generate'],
|
|
17
|
+
['add a new component', 'generate'],
|
|
18
|
+
['write a function to validate email', 'generate'],
|
|
19
|
+
['develop a repository class', 'generate'],
|
|
20
|
+
['scaffold a new feature', 'generate'],
|
|
21
|
+
['initialize a new module', 'generate'],
|
|
22
|
+
])('classifies "%s" as %s (Sonnet)', (input, expectedIntent) => {
|
|
23
|
+
const result = classifyTask(input);
|
|
24
|
+
expect(result.intent).toBe(expectedIntent);
|
|
25
|
+
expect(result.model).toBe('sonnet');
|
|
26
|
+
});
|
|
27
|
+
test.each([
|
|
28
|
+
['refactor this to use bloc', 'refactor'],
|
|
29
|
+
['convert this to a stateless widget', 'refactor'],
|
|
30
|
+
['restructure the code', 'refactor'],
|
|
31
|
+
['migrate to null safety', 'refactor'],
|
|
32
|
+
['rewrite this function', 'refactor'],
|
|
33
|
+
])('classifies "%s" as %s (Sonnet)', (input, expectedIntent) => {
|
|
34
|
+
const result = classifyTask(input);
|
|
35
|
+
expect(result.intent).toBe(expectedIntent);
|
|
36
|
+
expect(result.model).toBe('sonnet');
|
|
37
|
+
});
|
|
38
|
+
test.each([
|
|
39
|
+
['fix the bug in main.dart', 'fix_bug'],
|
|
40
|
+
['debug this error', 'fix_bug'],
|
|
41
|
+
['solve this crash', 'fix_bug'],
|
|
42
|
+
['resolve the issue', 'fix_bug'],
|
|
43
|
+
['why is this error happening?', 'fix_bug'],
|
|
44
|
+
['what is causing the crash?', 'fix_bug'],
|
|
45
|
+
['FAILURE: Build failed with an exception', 'fix_bug'],
|
|
46
|
+
['Exception caught by widgets library', 'fix_bug'],
|
|
47
|
+
['Error: The argument type', 'fix_bug'],
|
|
48
|
+
])('classifies "%s" as %s (Sonnet)', (input, expectedIntent) => {
|
|
49
|
+
const result = classifyTask(input);
|
|
50
|
+
expect(result.intent).toBe(expectedIntent);
|
|
51
|
+
expect(result.model).toBe('sonnet');
|
|
52
|
+
});
|
|
53
|
+
test.each([
|
|
54
|
+
['write tests for this widget', 'write_tests'],
|
|
55
|
+
['create unit tests', 'write_tests'],
|
|
56
|
+
['add tests for the service', 'write_tests'],
|
|
57
|
+
['generate tests', 'write_tests'],
|
|
58
|
+
['test this class', 'write_tests'],
|
|
59
|
+
['widget test for login', 'write_tests'],
|
|
60
|
+
['integration test for checkout', 'write_tests'],
|
|
61
|
+
])('classifies "%s" as %s (Sonnet)', (input, expectedIntent) => {
|
|
62
|
+
const result = classifyTask(input);
|
|
63
|
+
expect(result.intent).toBe(expectedIntent);
|
|
64
|
+
expect(result.model).toBe('sonnet');
|
|
65
|
+
});
|
|
66
|
+
test.each([
|
|
67
|
+
['update all widgets to use const', 'refactor'], // "update...to" matches refactor
|
|
68
|
+
['change every file in the project', 'multi_file'],
|
|
69
|
+
['batch update across the codebase', 'multi_file'],
|
|
70
|
+
['modify multiple screens', 'multi_file'],
|
|
71
|
+
])('classifies "%s" as %s (Sonnet)', (input, expectedIntent) => {
|
|
72
|
+
const result = classifyTask(input);
|
|
73
|
+
expect(result.intent).toBe(expectedIntent);
|
|
74
|
+
expect(result.model).toBe('sonnet');
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
describe('Explanations and Read (Haiku)', () => {
|
|
78
|
+
test.each([
|
|
79
|
+
['explain how this works', 'explain'],
|
|
80
|
+
['what is a widget?', 'explain'],
|
|
81
|
+
['what does this function do?', 'explain'],
|
|
82
|
+
['describe the architecture', 'explain'],
|
|
83
|
+
['tell me about riverpod', 'explain'],
|
|
84
|
+
['what is the purpose of this', 'explain'],
|
|
85
|
+
])('classifies "%s" as %s (Haiku)', (input, expectedIntent) => {
|
|
86
|
+
const result = classifyTask(input);
|
|
87
|
+
expect(result.intent).toBe(expectedIntent);
|
|
88
|
+
expect(result.model).toBe('haiku');
|
|
89
|
+
});
|
|
90
|
+
test.each([
|
|
91
|
+
['show me the file', 'read'],
|
|
92
|
+
['read main.dart', 'read'],
|
|
93
|
+
['display the code', 'read'],
|
|
94
|
+
['view the contents', 'read'],
|
|
95
|
+
["what's in this file?", 'read'],
|
|
96
|
+
])('classifies "%s" as %s (Haiku)', (input, expectedIntent) => {
|
|
97
|
+
const result = classifyTask(input);
|
|
98
|
+
expect(result.intent).toBe(expectedIntent);
|
|
99
|
+
expect(result.model).toBe('haiku');
|
|
100
|
+
});
|
|
101
|
+
test.each([
|
|
102
|
+
['find the login widget', 'search'],
|
|
103
|
+
['search for error handling', 'search'],
|
|
104
|
+
['where is the main function?', 'search'],
|
|
105
|
+
['locate the config file', 'search'],
|
|
106
|
+
['which file contains user auth?', 'search'],
|
|
107
|
+
])('classifies "%s" as %s (Haiku)', (input, expectedIntent) => {
|
|
108
|
+
const result = classifyTask(input);
|
|
109
|
+
expect(result.intent).toBe(expectedIntent);
|
|
110
|
+
expect(result.model).toBe('haiku');
|
|
111
|
+
});
|
|
112
|
+
test.each([
|
|
113
|
+
['list all widgets', 'list'],
|
|
114
|
+
['show all files in lib', 'list'],
|
|
115
|
+
['what packages are installed?', 'list'],
|
|
116
|
+
['how many screens are there?', 'list'],
|
|
117
|
+
])('classifies "%s" as %s (Haiku)', (input, expectedIntent) => {
|
|
118
|
+
const result = classifyTask(input);
|
|
119
|
+
expect(result.intent).toBe(expectedIntent);
|
|
120
|
+
expect(result.model).toBe('haiku');
|
|
121
|
+
});
|
|
122
|
+
test.each([
|
|
123
|
+
['how do I add a package?', 'simple_qa'],
|
|
124
|
+
['how to use setState?', 'simple_qa'],
|
|
125
|
+
['can I use this with flutter web?', 'simple_qa'],
|
|
126
|
+
['what is the best practice for state?', 'explain'], // "what is" matches explain (both Haiku)
|
|
127
|
+
['difference between stateful and stateless', 'simple_qa'],
|
|
128
|
+
])('classifies "%s" as %s (Haiku)', (input, expectedIntent) => {
|
|
129
|
+
const result = classifyTask(input);
|
|
130
|
+
expect(result.intent).toBe(expectedIntent);
|
|
131
|
+
expect(result.model).toBe('haiku');
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
describe('Complex Tasks (Sonnet)', () => {
|
|
135
|
+
test.each([
|
|
136
|
+
['design the app architecture', 'architecture'],
|
|
137
|
+
['architect a clean architecture solution', 'architecture'],
|
|
138
|
+
['plan the folder structure', 'architecture'],
|
|
139
|
+
['organize the project using mvvm', 'architecture'],
|
|
140
|
+
])('classifies "%s" as %s (Sonnet)', (input, expectedIntent) => {
|
|
141
|
+
const result = classifyTask(input);
|
|
142
|
+
expect(result.intent).toBe(expectedIntent);
|
|
143
|
+
expect(result.model).toBe('sonnet');
|
|
144
|
+
});
|
|
145
|
+
test.each([
|
|
146
|
+
['check for security vulnerabilities', 'security'],
|
|
147
|
+
['audit the authentication code', 'security'],
|
|
148
|
+
['secure the api endpoints', 'security'],
|
|
149
|
+
['implement oauth login', 'security'],
|
|
150
|
+
])('classifies "%s" as %s (Sonnet)', (input, expectedIntent) => {
|
|
151
|
+
const result = classifyTask(input);
|
|
152
|
+
expect(result.intent).toBe(expectedIntent);
|
|
153
|
+
expect(result.model).toBe('sonnet');
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
describe('Unknown/Ambiguous (defaults to Sonnet)', () => {
|
|
157
|
+
test('defaults to Sonnet for unknown queries', () => {
|
|
158
|
+
const result = classifyTask('some random query without clear intent');
|
|
159
|
+
expect(result.intent).toBe('unknown');
|
|
160
|
+
expect(result.model).toBe('sonnet');
|
|
161
|
+
expect(result.confidence).toBe(0.5);
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
describe('Model Router - Escalation', () => {
|
|
166
|
+
test('escalates Haiku to Sonnet when confidence too low', () => {
|
|
167
|
+
const classification = {
|
|
168
|
+
intent: 'explain',
|
|
169
|
+
model: 'haiku',
|
|
170
|
+
modelId: MODEL_IDS.haiku,
|
|
171
|
+
confidence: 0.4, // Below 0.6 threshold
|
|
172
|
+
reason: 'Test'
|
|
173
|
+
};
|
|
174
|
+
const escalated = applyEscalation(classification, {
|
|
175
|
+
minHaikuConfidence: 0.6,
|
|
176
|
+
minSonnetConfidence: 0.4,
|
|
177
|
+
allowOpusEscalation: false
|
|
178
|
+
});
|
|
179
|
+
expect(escalated.model).toBe('sonnet');
|
|
180
|
+
expect(escalated.reason).toContain('Escalated');
|
|
181
|
+
});
|
|
182
|
+
test('keeps Haiku when confidence is sufficient', () => {
|
|
183
|
+
const classification = {
|
|
184
|
+
intent: 'explain',
|
|
185
|
+
model: 'haiku',
|
|
186
|
+
modelId: MODEL_IDS.haiku,
|
|
187
|
+
confidence: 0.7, // Above 0.6 threshold
|
|
188
|
+
reason: 'Test'
|
|
189
|
+
};
|
|
190
|
+
const escalated = applyEscalation(classification, DEFAULT_ROUTER_CONFIG);
|
|
191
|
+
expect(escalated.model).toBe('haiku');
|
|
192
|
+
});
|
|
193
|
+
test('does not escalate Sonnet to Opus by default', () => {
|
|
194
|
+
const classification = {
|
|
195
|
+
intent: 'generate',
|
|
196
|
+
model: 'sonnet',
|
|
197
|
+
modelId: MODEL_IDS.sonnet,
|
|
198
|
+
confidence: 0.3, // Below threshold
|
|
199
|
+
reason: 'Test'
|
|
200
|
+
};
|
|
201
|
+
const escalated = applyEscalation(classification, DEFAULT_ROUTER_CONFIG);
|
|
202
|
+
expect(escalated.model).toBe('sonnet'); // No escalation because allowOpusEscalation is false
|
|
203
|
+
});
|
|
204
|
+
test('escalates Sonnet to Opus when allowed and confidence low', () => {
|
|
205
|
+
const classification = {
|
|
206
|
+
intent: 'generate',
|
|
207
|
+
model: 'sonnet',
|
|
208
|
+
modelId: MODEL_IDS.sonnet,
|
|
209
|
+
confidence: 0.3, // Below 0.4 threshold
|
|
210
|
+
reason: 'Test'
|
|
211
|
+
};
|
|
212
|
+
const escalated = applyEscalation(classification, {
|
|
213
|
+
minHaikuConfidence: 0.6,
|
|
214
|
+
minSonnetConfidence: 0.4,
|
|
215
|
+
allowOpusEscalation: true
|
|
216
|
+
});
|
|
217
|
+
expect(escalated.model).toBe('opus');
|
|
218
|
+
expect(escalated.reason).toContain('Escalated');
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
describe('Model Router - Full Routing', () => {
|
|
222
|
+
test('routes simple explanation to Haiku', () => {
|
|
223
|
+
const result = routeToModel('explain how this works');
|
|
224
|
+
expect(result.model).toBe('haiku');
|
|
225
|
+
expect(result.intent).toBe('explain');
|
|
226
|
+
});
|
|
227
|
+
test('routes code generation to Sonnet', () => {
|
|
228
|
+
const result = routeToModel('create a login screen');
|
|
229
|
+
expect(result.model).toBe('sonnet');
|
|
230
|
+
expect(result.intent).toBe('generate');
|
|
231
|
+
});
|
|
232
|
+
test('routes bug fix to Sonnet', () => {
|
|
233
|
+
const result = routeToModel('fix the null pointer exception');
|
|
234
|
+
expect(result.model).toBe('sonnet');
|
|
235
|
+
expect(result.intent).toBe('fix_bug');
|
|
236
|
+
});
|
|
237
|
+
test('routes file search to Haiku', () => {
|
|
238
|
+
const result = routeToModel('find where the user service is defined');
|
|
239
|
+
expect(result.model).toBe('haiku');
|
|
240
|
+
expect(result.intent).toBe('search');
|
|
241
|
+
});
|
|
242
|
+
});
|
|
243
|
+
describe('Cost Estimation', () => {
|
|
244
|
+
test('estimates Haiku cost correctly', () => {
|
|
245
|
+
const cost = estimateCost('haiku', 1000, 500);
|
|
246
|
+
// Input: 1000 * 0.80 / 1M = 0.0008
|
|
247
|
+
// Output: 500 * 4.00 / 1M = 0.002
|
|
248
|
+
// Total: 0.0028
|
|
249
|
+
expect(cost).toBeCloseTo(0.0028, 4);
|
|
250
|
+
});
|
|
251
|
+
test('estimates Sonnet cost correctly', () => {
|
|
252
|
+
const cost = estimateCost('sonnet', 1000, 500);
|
|
253
|
+
// Input: 1000 * 3.00 / 1M = 0.003
|
|
254
|
+
// Output: 500 * 15.00 / 1M = 0.0075
|
|
255
|
+
// Total: 0.0105
|
|
256
|
+
expect(cost).toBeCloseTo(0.0105, 4);
|
|
257
|
+
});
|
|
258
|
+
test('estimates Opus cost correctly', () => {
|
|
259
|
+
const cost = estimateCost('opus', 1000, 500);
|
|
260
|
+
// Input: 1000 * 15.00 / 1M = 0.015
|
|
261
|
+
// Output: 500 * 75.00 / 1M = 0.0375
|
|
262
|
+
// Total: 0.0525
|
|
263
|
+
expect(cost).toBeCloseTo(0.0525, 4);
|
|
264
|
+
});
|
|
265
|
+
});
|
|
266
|
+
describe('Savings Calculation', () => {
|
|
267
|
+
test('calculates Haiku savings vs Sonnet', () => {
|
|
268
|
+
const { actualCost, sonnetCost, savings, savingsPercent } = calculateSavings('haiku', 10000, 5000);
|
|
269
|
+
expect(actualCost).toBeLessThan(sonnetCost);
|
|
270
|
+
expect(savings).toBeGreaterThan(0);
|
|
271
|
+
expect(savingsPercent).toBeGreaterThan(70); // Haiku is ~75% cheaper than Sonnet
|
|
272
|
+
});
|
|
273
|
+
test('calculates Opus cost vs Sonnet (negative savings)', () => {
|
|
274
|
+
const { actualCost, sonnetCost, savings, savingsPercent } = calculateSavings('opus', 10000, 5000);
|
|
275
|
+
expect(actualCost).toBeGreaterThan(sonnetCost);
|
|
276
|
+
expect(savings).toBeLessThan(0);
|
|
277
|
+
expect(savingsPercent).toBeLessThan(0);
|
|
278
|
+
});
|
|
279
|
+
test('Sonnet vs Sonnet has zero savings', () => {
|
|
280
|
+
const { actualCost, sonnetCost, savings, savingsPercent } = calculateSavings('sonnet', 10000, 5000);
|
|
281
|
+
expect(actualCost).toBe(sonnetCost);
|
|
282
|
+
expect(savings).toBe(0);
|
|
283
|
+
expect(savingsPercent).toBe(0);
|
|
284
|
+
});
|
|
285
|
+
});
|
|
286
|
+
describe('Utility Functions', () => {
|
|
287
|
+
test('formatClassification returns formatted string', () => {
|
|
288
|
+
const result = {
|
|
289
|
+
intent: 'generate',
|
|
290
|
+
model: 'sonnet',
|
|
291
|
+
modelId: MODEL_IDS.sonnet,
|
|
292
|
+
confidence: 1.0,
|
|
293
|
+
reason: 'Matched generate pattern'
|
|
294
|
+
};
|
|
295
|
+
const formatted = formatClassification(result);
|
|
296
|
+
expect(formatted).toContain('SONNET');
|
|
297
|
+
expect(formatted).toContain('100%');
|
|
298
|
+
expect(formatted).toContain('generate');
|
|
299
|
+
});
|
|
300
|
+
test('getModelTier returns correct tier from model ID', () => {
|
|
301
|
+
expect(getModelTier(MODEL_IDS.haiku)).toBe('haiku');
|
|
302
|
+
expect(getModelTier(MODEL_IDS.sonnet)).toBe('sonnet');
|
|
303
|
+
expect(getModelTier(MODEL_IDS.opus)).toBe('opus');
|
|
304
|
+
expect(getModelTier('unknown-model')).toBe('sonnet'); // Default
|
|
305
|
+
});
|
|
306
|
+
});
|
|
307
|
+
describe('CostOptimizer Integration with Model Router', () => {
|
|
308
|
+
test('processInput uses model routing when enabled', () => {
|
|
309
|
+
const optimizer = new CostOptimizer({
|
|
310
|
+
debug: false,
|
|
311
|
+
enableModelRouting: true
|
|
312
|
+
});
|
|
313
|
+
const result = optimizer.processInput('explain how widgets work');
|
|
314
|
+
expect(result.skipAPI).toBe(false);
|
|
315
|
+
expect(result.modelOverride).toBe('haiku');
|
|
316
|
+
expect(result.classification).toBeDefined();
|
|
317
|
+
expect(result.classification?.intent).toBe('explain');
|
|
318
|
+
});
|
|
319
|
+
test('processInput routes code generation to Sonnet', () => {
|
|
320
|
+
const optimizer = new CostOptimizer({
|
|
321
|
+
debug: false,
|
|
322
|
+
enableModelRouting: true
|
|
323
|
+
});
|
|
324
|
+
const result = optimizer.processInput('create a login widget');
|
|
325
|
+
expect(result.modelOverride).toBe('sonnet');
|
|
326
|
+
expect(result.classification?.intent).toBe('generate');
|
|
327
|
+
});
|
|
328
|
+
test('processInput skips model routing when disabled', () => {
|
|
329
|
+
const optimizer = new CostOptimizer({
|
|
330
|
+
debug: false,
|
|
331
|
+
enableModelRouting: false
|
|
332
|
+
});
|
|
333
|
+
const result = optimizer.processInput('explain how widgets work');
|
|
334
|
+
expect(result.skipAPI).toBe(false);
|
|
335
|
+
expect(result.modelOverride).toBeUndefined();
|
|
336
|
+
expect(result.classification).toBeUndefined();
|
|
337
|
+
});
|
|
338
|
+
test('model override takes precedence over routing', () => {
|
|
339
|
+
const optimizer = new CostOptimizer({
|
|
340
|
+
debug: false,
|
|
341
|
+
enableModelRouting: true
|
|
342
|
+
});
|
|
343
|
+
// User explicitly requests Opus even for simple task
|
|
344
|
+
const result = optimizer.processInput('/opus explain this');
|
|
345
|
+
expect(result.modelOverride).toBe('opus');
|
|
346
|
+
expect(result.classification).toBeUndefined(); // No classification when overridden
|
|
347
|
+
});
|
|
348
|
+
test('buildOptimizedRequest uses model from routing', () => {
|
|
349
|
+
const optimizer = new CostOptimizer({
|
|
350
|
+
debug: false,
|
|
351
|
+
enableModelRouting: true
|
|
352
|
+
});
|
|
353
|
+
// Process an explanation query (should route to Haiku)
|
|
354
|
+
optimizer.processInput('explain how this works');
|
|
355
|
+
// Build request with Haiku override
|
|
356
|
+
const request = optimizer.buildOptimizedRequest('haiku');
|
|
357
|
+
expect(request.model).toBe(MODEL_IDS.haiku);
|
|
358
|
+
});
|
|
359
|
+
test('router config can be updated', () => {
|
|
360
|
+
const optimizer = new CostOptimizer({
|
|
361
|
+
debug: false,
|
|
362
|
+
enableModelRouting: true
|
|
363
|
+
});
|
|
364
|
+
// Update router config to allow Opus escalation
|
|
365
|
+
optimizer.updateRouterConfig({ allowOpusEscalation: true });
|
|
366
|
+
const config = optimizer.getRouterConfig();
|
|
367
|
+
expect(config.allowOpusEscalation).toBe(true);
|
|
368
|
+
});
|
|
369
|
+
});
|
|
370
|
+
describe('Model Distribution Targets', () => {
|
|
371
|
+
test('typical session distribution favors Haiku for simple tasks', () => {
|
|
372
|
+
const optimizer = new CostOptimizer({
|
|
373
|
+
debug: false,
|
|
374
|
+
enableModelRouting: true
|
|
375
|
+
});
|
|
376
|
+
// Simulate typical session queries - realistic mix
|
|
377
|
+
const queries = [
|
|
378
|
+
'hi', // Reflex (no model)
|
|
379
|
+
'explain this code', // Haiku - explain
|
|
380
|
+
'what does this function do?', // Haiku - explain
|
|
381
|
+
'what packages are installed?', // Haiku - list
|
|
382
|
+
'find the main file', // Haiku - search
|
|
383
|
+
'create a button widget', // Sonnet - generate
|
|
384
|
+
'where is the config?', // Haiku - search
|
|
385
|
+
'show me the file', // Haiku - read
|
|
386
|
+
'how do I use setState?', // Haiku - simple_qa
|
|
387
|
+
'refactor to use bloc', // Sonnet - refactor
|
|
388
|
+
'what is a widget?', // Haiku - explain
|
|
389
|
+
'locate the user service', // Haiku - search
|
|
390
|
+
];
|
|
391
|
+
let haikuCount = 0;
|
|
392
|
+
let sonnetCount = 0;
|
|
393
|
+
let reflexCount = 0;
|
|
394
|
+
for (const query of queries) {
|
|
395
|
+
const result = optimizer.processInput(query);
|
|
396
|
+
if (result.skipAPI) {
|
|
397
|
+
reflexCount++;
|
|
398
|
+
}
|
|
399
|
+
else if (result.modelOverride === 'haiku' || result.classification?.model === 'haiku') {
|
|
400
|
+
haikuCount++;
|
|
401
|
+
}
|
|
402
|
+
else if (result.modelOverride === 'sonnet' || result.classification?.model === 'sonnet') {
|
|
403
|
+
sonnetCount++;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
// Target: Majority should be Haiku for this typical read-heavy session
|
|
407
|
+
const apiCalls = haikuCount + sonnetCount;
|
|
408
|
+
const haikuPercent = (haikuCount / apiCalls) * 100;
|
|
409
|
+
expect(reflexCount).toBeGreaterThan(0); // Should handle "hi" locally
|
|
410
|
+
expect(haikuPercent).toBeGreaterThanOrEqual(60); // At least 60% Haiku for read-heavy session
|
|
411
|
+
expect(sonnetCount).toBeGreaterThan(0); // Should have some Sonnet for generation
|
|
412
|
+
});
|
|
413
|
+
});
|
|
414
|
+
//# sourceMappingURL=day2.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"day2.test.js","sourceRoot":"","sources":["../../../../src/core/cost/__tests__/day2.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"day3.test.d.ts","sourceRoot":"","sources":["../../../../src/core/cost/__tests__/day3.test.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
|