dartmind 17.0.0 → 17.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/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,319 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DartMind V17.3 - Model Router
|
|
3
|
+
*
|
|
4
|
+
* PURPOSE: Route requests to the cheapest model that can handle them.
|
|
5
|
+
* COST IMPACT: 40-50% savings by using Haiku for 70% of requests
|
|
6
|
+
* QUALITY IMPACT: NONE (Sonnet for all code generation)
|
|
7
|
+
*
|
|
8
|
+
* ROUTING LOGIC:
|
|
9
|
+
* - Haiku ($0.80/1M): Read, explain, search, list, simple Q&A
|
|
10
|
+
* - Sonnet ($3.00/1M): Generate, refactor, fix bugs, write tests
|
|
11
|
+
* - Opus ($15.00/1M): Architecture, security (only if explicitly requested)
|
|
12
|
+
*
|
|
13
|
+
* SAFETY FEATURES:
|
|
14
|
+
* - Code generation ALWAYS goes to Sonnet (never Haiku)
|
|
15
|
+
* - Low confidence auto-escalates to more capable model
|
|
16
|
+
* - User can override with /haiku, /sonnet, /opus commands
|
|
17
|
+
*
|
|
18
|
+
* @module cost/model-router
|
|
19
|
+
* @version 17.3.0
|
|
20
|
+
*/
|
|
21
|
+
import { MODEL_IDS, MODEL_COSTS } from './types.js';
|
|
22
|
+
// ═══════════════════════════════════════════════════════════════
|
|
23
|
+
// INTENT TO MODEL MAPPING
|
|
24
|
+
// ═══════════════════════════════════════════════════════════════
|
|
25
|
+
const INTENT_MODEL_MAP = {
|
|
26
|
+
// Reflex (handled before routing, but included for completeness)
|
|
27
|
+
greeting: 'haiku',
|
|
28
|
+
farewell: 'haiku',
|
|
29
|
+
gibberish: 'haiku',
|
|
30
|
+
affirmation: 'haiku',
|
|
31
|
+
command: 'haiku',
|
|
32
|
+
// Haiku - Simple, read-only, explanatory tasks
|
|
33
|
+
explain: 'haiku',
|
|
34
|
+
read: 'haiku',
|
|
35
|
+
search: 'haiku',
|
|
36
|
+
list: 'haiku',
|
|
37
|
+
simple_qa: 'haiku',
|
|
38
|
+
// Sonnet - Code generation and modification
|
|
39
|
+
generate: 'sonnet',
|
|
40
|
+
refactor: 'sonnet',
|
|
41
|
+
fix_bug: 'sonnet',
|
|
42
|
+
write_tests: 'sonnet',
|
|
43
|
+
multi_file: 'sonnet',
|
|
44
|
+
architecture: 'sonnet', // Sonnet by default, Opus if user requests
|
|
45
|
+
security: 'sonnet',
|
|
46
|
+
complex: 'sonnet',
|
|
47
|
+
// Default
|
|
48
|
+
unknown: 'sonnet' // When in doubt, use Sonnet
|
|
49
|
+
};
|
|
50
|
+
const INTENT_PATTERNS = [
|
|
51
|
+
// ─────────────────────────────────────────────────────────────
|
|
52
|
+
// HIGHEST PRIORITY: Test Writing (check before generate)
|
|
53
|
+
// ─────────────────────────────────────────────────────────────
|
|
54
|
+
{
|
|
55
|
+
intent: 'write_tests',
|
|
56
|
+
model: 'sonnet',
|
|
57
|
+
priority: 110, // Higher than generate to match first
|
|
58
|
+
patterns: [
|
|
59
|
+
/\b(write|create|add|generate)\b.*\btest/i,
|
|
60
|
+
/\btest\s+(this|the|my|that|for)\b/i,
|
|
61
|
+
/\b(unit|widget|integration|golden)\s*test/i,
|
|
62
|
+
/\btests?\s+for\b/i,
|
|
63
|
+
]
|
|
64
|
+
},
|
|
65
|
+
// ─────────────────────────────────────────────────────────────
|
|
66
|
+
// HIGH PRIORITY: Code Generation (ALWAYS Sonnet)
|
|
67
|
+
// ─────────────────────────────────────────────────────────────
|
|
68
|
+
{
|
|
69
|
+
intent: 'generate',
|
|
70
|
+
model: 'sonnet',
|
|
71
|
+
priority: 100,
|
|
72
|
+
patterns: [
|
|
73
|
+
/\b(create|build|make|generate|implement|add|write|develop)\b.*\b(widget|screen|page|view|component|class|function|method|service|repository|model|controller|provider|bloc|cubit)\b/i,
|
|
74
|
+
/\b(new|scaffold|setup|initialize)\b.*\b(feature|module|screen|page|project)\b/i,
|
|
75
|
+
/\b(create|build|make)\b.*\b(ui|interface|layout|design)\b/i,
|
|
76
|
+
]
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
intent: 'refactor',
|
|
80
|
+
model: 'sonnet',
|
|
81
|
+
priority: 100,
|
|
82
|
+
patterns: [
|
|
83
|
+
/\b(refactor|restructure|reorganize|convert|migrate|transform|rewrite)\b/i,
|
|
84
|
+
/\b(change|update|modify|improve)\b.*\b(to|into)\b/i,
|
|
85
|
+
/\b(move|extract|split|merge|combine)\b.*\b(to|into|from)\b/i,
|
|
86
|
+
]
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
intent: 'fix_bug',
|
|
90
|
+
model: 'sonnet',
|
|
91
|
+
priority: 100,
|
|
92
|
+
patterns: [
|
|
93
|
+
/\b(fix|debug|solve|resolve|repair|patch)\b.*\b(bug|error|issue|problem|crash|exception)\b/i,
|
|
94
|
+
/\b(why|what)\b.*\b(error|fail|broken|not\s+work|crash)\b/i,
|
|
95
|
+
/\bFAILURE\b/i,
|
|
96
|
+
/\bException\b/i,
|
|
97
|
+
/\bError\b.*\b:/i,
|
|
98
|
+
/\bStackTrace\b/i,
|
|
99
|
+
]
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
intent: 'multi_file',
|
|
103
|
+
model: 'sonnet',
|
|
104
|
+
priority: 90,
|
|
105
|
+
patterns: [
|
|
106
|
+
/\b(update|change|modify|fix|refactor|convert)\b.*\b(all|every|multiple|several|many)\b/i,
|
|
107
|
+
/\b(across|throughout|entire)\b.*\b(project|codebase|app)\b/i,
|
|
108
|
+
/\b(batch|bulk)\b.*\b(update|change|modify)\b/i,
|
|
109
|
+
/\bmodify\b.*\b(multiple|several|many)\b/i,
|
|
110
|
+
/\bchange\s+every\b/i,
|
|
111
|
+
]
|
|
112
|
+
},
|
|
113
|
+
// ─────────────────────────────────────────────────────────────
|
|
114
|
+
// MEDIUM PRIORITY: Simple Tasks (Haiku)
|
|
115
|
+
// ─────────────────────────────────────────────────────────────
|
|
116
|
+
{
|
|
117
|
+
intent: 'explain',
|
|
118
|
+
model: 'haiku',
|
|
119
|
+
priority: 50,
|
|
120
|
+
patterns: [
|
|
121
|
+
/\b(explain|describe|tell\s+me\s+about|what\s+is|what\s+does|what\s+are|how\s+does)\b/i,
|
|
122
|
+
/\b(meaning|definition|purpose)\b.*\b(of|for)\b/i,
|
|
123
|
+
/\bwhat\s+(happened|went\s+wrong)\b/i,
|
|
124
|
+
]
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
intent: 'read',
|
|
128
|
+
model: 'haiku',
|
|
129
|
+
priority: 50,
|
|
130
|
+
patterns: [
|
|
131
|
+
/\b(show|display|read|open|view|see|print|output)\b.*\b(file|code|content|source)\b/i,
|
|
132
|
+
/\b(what'?s?\s+in|contents?\s+of|inside)\b/i,
|
|
133
|
+
/\b(cat|less|more|head|tail)\b/i,
|
|
134
|
+
/\bread\b.*\.\w+\b/i, // "read main.dart", "read file.ts"
|
|
135
|
+
/\bview\b.*\b(the|this|that)\b/i, // "view the contents"
|
|
136
|
+
]
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
intent: 'search',
|
|
140
|
+
model: 'haiku',
|
|
141
|
+
priority: 50,
|
|
142
|
+
patterns: [
|
|
143
|
+
/\b(find|search|look\s+for|locate|where\s+is|grep|ripgrep)\b/i,
|
|
144
|
+
/\b(which\s+file|in\s+which)\b/i,
|
|
145
|
+
]
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
intent: 'list',
|
|
149
|
+
model: 'haiku',
|
|
150
|
+
priority: 50,
|
|
151
|
+
patterns: [
|
|
152
|
+
/\b(list|show\s+all|show\s+me|enumerate|what)\b.*\b(files?|widgets?|packages?|dependencies|classes|methods|screens?)\b/i,
|
|
153
|
+
/\bhow\s+many\b/i,
|
|
154
|
+
/\bls\b/i,
|
|
155
|
+
]
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
intent: 'simple_qa',
|
|
159
|
+
model: 'haiku',
|
|
160
|
+
priority: 40,
|
|
161
|
+
patterns: [
|
|
162
|
+
/\b(how\s+do\s+i|how\s+to|how\s+can\s+i|can\s+i|should\s+i|is\s+it\s+possible)\b/i,
|
|
163
|
+
/\b(best\s+practice|recommend|suggestion|advice)\b/i,
|
|
164
|
+
/\b(difference\s+between|vs|versus|compare)\b/i,
|
|
165
|
+
]
|
|
166
|
+
},
|
|
167
|
+
// ─────────────────────────────────────────────────────────────
|
|
168
|
+
// LOW PRIORITY: Complex Tasks (Sonnet, can be Opus)
|
|
169
|
+
// ─────────────────────────────────────────────────────────────
|
|
170
|
+
{
|
|
171
|
+
intent: 'architecture',
|
|
172
|
+
model: 'sonnet',
|
|
173
|
+
priority: 30,
|
|
174
|
+
patterns: [
|
|
175
|
+
/\b(architect|design|structure|organize|plan)\b.*\b(app|project|system|module)\b/i,
|
|
176
|
+
/\b(clean\s+architecture|mvvm|mvc|bloc\s+pattern|repository\s+pattern)\b/i,
|
|
177
|
+
/\b(folder|directory)\s+structure\b/i,
|
|
178
|
+
]
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
intent: 'security',
|
|
182
|
+
model: 'sonnet',
|
|
183
|
+
priority: 30,
|
|
184
|
+
patterns: [
|
|
185
|
+
/\b(security|vulnerability|audit|penetration|exploit)\b/i,
|
|
186
|
+
/\b(secure|protect|encrypt|hash|sanitize)\b/i,
|
|
187
|
+
/\b(auth|authentication|authorization|oauth|jwt)\b/i,
|
|
188
|
+
]
|
|
189
|
+
},
|
|
190
|
+
];
|
|
191
|
+
// ═══════════════════════════════════════════════════════════════
|
|
192
|
+
// CLASSIFICATION FUNCTION
|
|
193
|
+
// ═══════════════════════════════════════════════════════════════
|
|
194
|
+
/**
|
|
195
|
+
* Classify user input to determine intent and model.
|
|
196
|
+
*
|
|
197
|
+
* @param input - User input string
|
|
198
|
+
* @returns Classification result with intent, model, and confidence
|
|
199
|
+
*/
|
|
200
|
+
export function classifyTask(input) {
|
|
201
|
+
const normalized = input.toLowerCase().trim();
|
|
202
|
+
// Sort patterns by priority (highest first)
|
|
203
|
+
const sortedPatterns = [...INTENT_PATTERNS].sort((a, b) => b.priority - a.priority);
|
|
204
|
+
// Find first matching pattern
|
|
205
|
+
for (const { intent, model, patterns, priority } of sortedPatterns) {
|
|
206
|
+
for (const pattern of patterns) {
|
|
207
|
+
if (pattern.test(normalized)) {
|
|
208
|
+
return {
|
|
209
|
+
intent,
|
|
210
|
+
model,
|
|
211
|
+
modelId: MODEL_IDS[model],
|
|
212
|
+
confidence: priority / 100,
|
|
213
|
+
reason: `Matched ${intent} pattern`
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
// Default: Unknown → Sonnet (safe choice)
|
|
219
|
+
return {
|
|
220
|
+
intent: 'unknown',
|
|
221
|
+
model: 'sonnet',
|
|
222
|
+
modelId: MODEL_IDS.sonnet,
|
|
223
|
+
confidence: 0.5,
|
|
224
|
+
reason: 'No pattern matched, defaulting to Sonnet'
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
export const DEFAULT_ROUTER_CONFIG = {
|
|
228
|
+
minHaikuConfidence: 0.5, // 50% confidence for Haiku (allows 50% match to stay Haiku)
|
|
229
|
+
minSonnetConfidence: 0.3, // 30% confidence for Sonnet
|
|
230
|
+
allowOpusEscalation: false // Don't auto-escalate to Opus (expensive)
|
|
231
|
+
};
|
|
232
|
+
/**
|
|
233
|
+
* Apply confidence-based escalation rules.
|
|
234
|
+
* Low confidence tasks get escalated to more capable models.
|
|
235
|
+
*/
|
|
236
|
+
export function applyEscalation(classification, config = DEFAULT_ROUTER_CONFIG) {
|
|
237
|
+
const { model, confidence } = classification;
|
|
238
|
+
// Escalate Haiku → Sonnet if confidence too low
|
|
239
|
+
if (model === 'haiku' && confidence < config.minHaikuConfidence) {
|
|
240
|
+
return {
|
|
241
|
+
...classification,
|
|
242
|
+
model: 'sonnet',
|
|
243
|
+
modelId: MODEL_IDS.sonnet,
|
|
244
|
+
reason: `Escalated: Haiku confidence (${(confidence * 100).toFixed(0)}%) < threshold (${config.minHaikuConfidence * 100}%)`
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
// Escalate Sonnet → Opus if allowed and confidence too low
|
|
248
|
+
if (model === 'sonnet' && confidence < config.minSonnetConfidence && config.allowOpusEscalation) {
|
|
249
|
+
return {
|
|
250
|
+
...classification,
|
|
251
|
+
model: 'opus',
|
|
252
|
+
modelId: MODEL_IDS.opus,
|
|
253
|
+
reason: `Escalated: Sonnet confidence (${(confidence * 100).toFixed(0)}%) < threshold (${config.minSonnetConfidence * 100}%)`
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
return classification;
|
|
257
|
+
}
|
|
258
|
+
// ═══════════════════════════════════════════════════════════════
|
|
259
|
+
// MAIN ROUTING FUNCTION
|
|
260
|
+
// ═══════════════════════════════════════════════════════════════
|
|
261
|
+
/**
|
|
262
|
+
* Route input to appropriate model.
|
|
263
|
+
* Combines classification and escalation.
|
|
264
|
+
*
|
|
265
|
+
* @param input - User input
|
|
266
|
+
* @param config - Router configuration
|
|
267
|
+
* @returns Final classification with model selection
|
|
268
|
+
*/
|
|
269
|
+
export function routeToModel(input, config = DEFAULT_ROUTER_CONFIG) {
|
|
270
|
+
// Step 1: Classify
|
|
271
|
+
const classification = classifyTask(input);
|
|
272
|
+
// Step 2: Apply escalation rules
|
|
273
|
+
const escalated = applyEscalation(classification, config);
|
|
274
|
+
return escalated;
|
|
275
|
+
}
|
|
276
|
+
// ═══════════════════════════════════════════════════════════════
|
|
277
|
+
// COST ESTIMATION
|
|
278
|
+
// ═══════════════════════════════════════════════════════════════
|
|
279
|
+
/**
|
|
280
|
+
* Estimate cost for a request based on model and tokens.
|
|
281
|
+
*/
|
|
282
|
+
export function estimateCost(model, inputTokens, outputTokens = 500 // Estimate
|
|
283
|
+
) {
|
|
284
|
+
const costs = MODEL_COSTS[model];
|
|
285
|
+
return (inputTokens * costs.input + outputTokens * costs.output) / 1_000_000;
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Format classification for logging.
|
|
289
|
+
*/
|
|
290
|
+
export function formatClassification(result) {
|
|
291
|
+
const modelEmoji = {
|
|
292
|
+
haiku: '🐦',
|
|
293
|
+
sonnet: '📝',
|
|
294
|
+
opus: '🎭'
|
|
295
|
+
};
|
|
296
|
+
return `${modelEmoji[result.model]} ${result.model.toUpperCase()} (${(result.confidence * 100).toFixed(0)}% conf) - ${result.intent}: ${result.reason}`;
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Get the model tier from a model ID string.
|
|
300
|
+
*/
|
|
301
|
+
export function getModelTier(modelId) {
|
|
302
|
+
for (const [tier, id] of Object.entries(MODEL_IDS)) {
|
|
303
|
+
if (id === modelId) {
|
|
304
|
+
return tier;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
return 'sonnet'; // Default
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Calculate potential savings compared to using Sonnet for everything.
|
|
311
|
+
*/
|
|
312
|
+
export function calculateSavings(model, inputTokens, outputTokens) {
|
|
313
|
+
const actualCost = estimateCost(model, inputTokens, outputTokens);
|
|
314
|
+
const sonnetCost = estimateCost('sonnet', inputTokens, outputTokens);
|
|
315
|
+
const savings = sonnetCost - actualCost;
|
|
316
|
+
const savingsPercent = sonnetCost > 0 ? (savings / sonnetCost) * 100 : 0;
|
|
317
|
+
return { actualCost, sonnetCost, savings, savingsPercent };
|
|
318
|
+
}
|
|
319
|
+
//# sourceMappingURL=model-router.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-router.js","sourceRoot":"","sources":["../../../src/core/cost/model-router.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DartMind V17.3 - Prompt Caching
|
|
3
|
+
*
|
|
4
|
+
* PURPOSE: Enable Anthropic's native prompt caching for 90% cost reduction on cached tokens.
|
|
5
|
+
* COST IMPACT: 50-60% savings on input token costs
|
|
6
|
+
* QUALITY IMPACT: NONE (same responses, just cheaper)
|
|
7
|
+
*
|
|
8
|
+
* HOW IT WORKS:
|
|
9
|
+
* - Static content (system prompt, tools, project context) is marked with cache_control
|
|
10
|
+
* - Anthropic caches these tokens for 5 minutes
|
|
11
|
+
* - Subsequent requests read from cache at 10% of normal cost
|
|
12
|
+
*
|
|
13
|
+
* SAFETY:
|
|
14
|
+
* - Anthropic native feature - no custom caching logic
|
|
15
|
+
* - Automatic cache invalidation after 5 min inactivity
|
|
16
|
+
* - Can be disabled via config.enablePromptCaching
|
|
17
|
+
*
|
|
18
|
+
* @module cost/prompt-cache
|
|
19
|
+
* @version 17.3.0
|
|
20
|
+
*/
|
|
21
|
+
export interface CacheableBlock {
|
|
22
|
+
type: 'text';
|
|
23
|
+
text: string;
|
|
24
|
+
cache_control?: {
|
|
25
|
+
type: 'ephemeral';
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
export interface CacheConfig {
|
|
29
|
+
enableSystemPromptCache: boolean;
|
|
30
|
+
enableToolDefinitionsCache: boolean;
|
|
31
|
+
enableProjectContextCache: boolean;
|
|
32
|
+
}
|
|
33
|
+
export declare const DEFAULT_CACHE_CONFIG: CacheConfig;
|
|
34
|
+
export declare const SYSTEM_PROMPT_CACHED = "You are JARVIS, an expert Flutter and Dart AI assistant created by DartMind.\n\n## CORE CAPABILITIES\n- Write clean, maintainable, production-ready Flutter/Dart code\n- Follow Flutter best practices, effective_dart guidelines, and style conventions\n- Use proper error handling, null safety, and type annotations\n- Support multiple state management solutions (GetX, Riverpod, Bloc, Provider)\n- Detect and adapt to the project's existing patterns and architecture\n\n## CODE QUALITY STANDARDS\n- Use const constructors where possible\n- Proper widget keys for lists and animations\n- Extract magic numbers and strings to constants\n- Document complex logic with clear comments\n- Keep widgets small, focused, and composable\n- Prefer composition over inheritance\n\n## SAFETY PROTOCOLS\n- Never delete files without explicit confirmation\n- Verify package existence on pub.dev before suggesting\n- Run dart analyze before completing code modifications\n- Create backups before major refactors\n- Warn about breaking changes\n\n## RESPONSE STYLE\n- Be concise but thorough\n- Show code examples when helpful\n- Explain trade-offs for architectural decisions\n- Ask clarifying questions for ambiguous requests";
|
|
35
|
+
export declare const TOOL_DEFINITIONS_CACHED = "## AVAILABLE TOOLS\n\n### File Operations\n- **Read**: Read file contents from the project\n- **Write**: Create new files (creates directories if needed)\n- **Edit**: Modify existing files with precision edits\n- **Glob**: Find files matching a pattern (e.g., \"lib/**/*.dart\")\n- **Grep**: Search for text patterns across files\n\n### Shell Operations\n- **Bash**: Execute shell commands (flutter, dart, git, etc.)\n\n### Task Management\n- **TodoWrite**: Track pending tasks and progress\n\n### MCP Tools (DartMind Super-Server)\n- **verify_package**: Validate packages exist on pub.dev (prevents hallucinations)\n- **analyze_dart**: Run dart analyzer on code\n- **security_scan**: Check for security vulnerabilities\n- **check_policy**: Validate against architecture patterns (Clean/MVVM)";
|
|
36
|
+
/**
|
|
37
|
+
* Build system message blocks with cache_control markers.
|
|
38
|
+
*
|
|
39
|
+
* @param projectContext - Dynamic project context (structure, dependencies)
|
|
40
|
+
* @param config - Cache configuration
|
|
41
|
+
* @returns Array of cacheable blocks for Anthropic API
|
|
42
|
+
*/
|
|
43
|
+
export declare function buildCachedSystemBlocks(projectContext?: string, config?: CacheConfig): CacheableBlock[];
|
|
44
|
+
export interface ProjectInfo {
|
|
45
|
+
name: string;
|
|
46
|
+
path: string;
|
|
47
|
+
stateManagement?: string;
|
|
48
|
+
architecture?: string;
|
|
49
|
+
dependencies?: string[];
|
|
50
|
+
structure?: string;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Build a concise project context string for caching.
|
|
54
|
+
*/
|
|
55
|
+
export declare function buildProjectContext(project: ProjectInfo): string;
|
|
56
|
+
export interface CacheMetrics {
|
|
57
|
+
cacheReadTokens: number;
|
|
58
|
+
cacheWriteTokens: number;
|
|
59
|
+
freshInputTokens: number;
|
|
60
|
+
totalInputTokens: number;
|
|
61
|
+
cacheSavingsPercent: number;
|
|
62
|
+
estimatedSavings: number;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Calculate cache savings from API response usage.
|
|
66
|
+
*
|
|
67
|
+
* @param usage - Usage object from Anthropic API response
|
|
68
|
+
* @param modelCostPerMillion - Input cost per 1M tokens (default: Sonnet $3.00)
|
|
69
|
+
* @returns Cache metrics including savings
|
|
70
|
+
*/
|
|
71
|
+
export declare function calculateCacheMetrics(usage: {
|
|
72
|
+
input_tokens: number;
|
|
73
|
+
cache_creation_input_tokens?: number;
|
|
74
|
+
cache_read_input_tokens?: number;
|
|
75
|
+
}, modelCostPerMillion?: number): CacheMetrics;
|
|
76
|
+
/**
|
|
77
|
+
* Format cache metrics for logging.
|
|
78
|
+
*/
|
|
79
|
+
export declare function formatCacheMetrics(metrics: CacheMetrics): string;
|
|
80
|
+
/**
|
|
81
|
+
* Build a complete system message string (non-cached version for compatibility)
|
|
82
|
+
*/
|
|
83
|
+
export declare function buildSystemMessage(projectContext?: string): string;
|
|
84
|
+
/**
|
|
85
|
+
* Estimate token count for a string (rough approximation)
|
|
86
|
+
* ~4 characters per token for English text
|
|
87
|
+
*/
|
|
88
|
+
export declare function estimateTokens(text: string): number;
|
|
89
|
+
/**
|
|
90
|
+
* Get estimated token count for cached system blocks
|
|
91
|
+
*/
|
|
92
|
+
export declare function getSystemBlocksTokenEstimate(projectContext?: string): {
|
|
93
|
+
systemPrompt: number;
|
|
94
|
+
toolDefinitions: number;
|
|
95
|
+
projectContext: number;
|
|
96
|
+
total: number;
|
|
97
|
+
};
|
|
98
|
+
//# sourceMappingURL=prompt-cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-cache.d.ts","sourceRoot":"","sources":["../../../src/core/cost/prompt-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAMH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE;QAAE,IAAI,EAAE,WAAW,CAAA;KAAE,CAAC;CACvC;AAED,MAAM,WAAW,WAAW;IAC1B,uBAAuB,EAAE,OAAO,CAAC;IACjC,0BAA0B,EAAE,OAAO,CAAC;IACpC,yBAAyB,EAAE,OAAO,CAAC;CACpC;AAED,eAAO,MAAM,oBAAoB,EAAE,WAIlC,CAAC;AAOF,eAAO,MAAM,oBAAoB,6rCA4BiB,CAAC;AAOnD,eAAO,MAAM,uBAAuB,6xBAmBoC,CAAC;AAMzE;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CACrC,cAAc,CAAC,EAAE,MAAM,EACvB,MAAM,GAAE,WAAkC,GACzC,cAAc,EAAE,CAiClB;AAMD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAuBhE;AAMD,MAAM,WAAW,YAAY;IAC3B,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE;IACL,YAAY,EAAE,MAAM,CAAC;IACrB,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,uBAAuB,CAAC,EAAE,MAAM,CAAC;CAClC,EACD,mBAAmB,GAAE,MAAa,GACjC,YAAY,CAyBd;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,CAOhE;AAMD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,CAQlE;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG;IACrE,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;CACf,CAWA"}
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DartMind V17.3 - Prompt Caching
|
|
3
|
+
*
|
|
4
|
+
* PURPOSE: Enable Anthropic's native prompt caching for 90% cost reduction on cached tokens.
|
|
5
|
+
* COST IMPACT: 50-60% savings on input token costs
|
|
6
|
+
* QUALITY IMPACT: NONE (same responses, just cheaper)
|
|
7
|
+
*
|
|
8
|
+
* HOW IT WORKS:
|
|
9
|
+
* - Static content (system prompt, tools, project context) is marked with cache_control
|
|
10
|
+
* - Anthropic caches these tokens for 5 minutes
|
|
11
|
+
* - Subsequent requests read from cache at 10% of normal cost
|
|
12
|
+
*
|
|
13
|
+
* SAFETY:
|
|
14
|
+
* - Anthropic native feature - no custom caching logic
|
|
15
|
+
* - Automatic cache invalidation after 5 min inactivity
|
|
16
|
+
* - Can be disabled via config.enablePromptCaching
|
|
17
|
+
*
|
|
18
|
+
* @module cost/prompt-cache
|
|
19
|
+
* @version 17.3.0
|
|
20
|
+
*/
|
|
21
|
+
export const DEFAULT_CACHE_CONFIG = {
|
|
22
|
+
enableSystemPromptCache: true,
|
|
23
|
+
enableToolDefinitionsCache: true,
|
|
24
|
+
enableProjectContextCache: true
|
|
25
|
+
};
|
|
26
|
+
// ═══════════════════════════════════════════════════════════════
|
|
27
|
+
// CACHED SYSTEM PROMPT
|
|
28
|
+
// This is static content that should be cached
|
|
29
|
+
// ═══════════════════════════════════════════════════════════════
|
|
30
|
+
export const SYSTEM_PROMPT_CACHED = `You are JARVIS, an expert Flutter and Dart AI assistant created by DartMind.
|
|
31
|
+
|
|
32
|
+
## CORE CAPABILITIES
|
|
33
|
+
- Write clean, maintainable, production-ready Flutter/Dart code
|
|
34
|
+
- Follow Flutter best practices, effective_dart guidelines, and style conventions
|
|
35
|
+
- Use proper error handling, null safety, and type annotations
|
|
36
|
+
- Support multiple state management solutions (GetX, Riverpod, Bloc, Provider)
|
|
37
|
+
- Detect and adapt to the project's existing patterns and architecture
|
|
38
|
+
|
|
39
|
+
## CODE QUALITY STANDARDS
|
|
40
|
+
- Use const constructors where possible
|
|
41
|
+
- Proper widget keys for lists and animations
|
|
42
|
+
- Extract magic numbers and strings to constants
|
|
43
|
+
- Document complex logic with clear comments
|
|
44
|
+
- Keep widgets small, focused, and composable
|
|
45
|
+
- Prefer composition over inheritance
|
|
46
|
+
|
|
47
|
+
## SAFETY PROTOCOLS
|
|
48
|
+
- Never delete files without explicit confirmation
|
|
49
|
+
- Verify package existence on pub.dev before suggesting
|
|
50
|
+
- Run dart analyze before completing code modifications
|
|
51
|
+
- Create backups before major refactors
|
|
52
|
+
- Warn about breaking changes
|
|
53
|
+
|
|
54
|
+
## RESPONSE STYLE
|
|
55
|
+
- Be concise but thorough
|
|
56
|
+
- Show code examples when helpful
|
|
57
|
+
- Explain trade-offs for architectural decisions
|
|
58
|
+
- Ask clarifying questions for ambiguous requests`;
|
|
59
|
+
// ═══════════════════════════════════════════════════════════════
|
|
60
|
+
// CACHED TOOL DEFINITIONS
|
|
61
|
+
// These define available tools and should be cached
|
|
62
|
+
// ═══════════════════════════════════════════════════════════════
|
|
63
|
+
export const TOOL_DEFINITIONS_CACHED = `## AVAILABLE TOOLS
|
|
64
|
+
|
|
65
|
+
### File Operations
|
|
66
|
+
- **Read**: Read file contents from the project
|
|
67
|
+
- **Write**: Create new files (creates directories if needed)
|
|
68
|
+
- **Edit**: Modify existing files with precision edits
|
|
69
|
+
- **Glob**: Find files matching a pattern (e.g., "lib/**/*.dart")
|
|
70
|
+
- **Grep**: Search for text patterns across files
|
|
71
|
+
|
|
72
|
+
### Shell Operations
|
|
73
|
+
- **Bash**: Execute shell commands (flutter, dart, git, etc.)
|
|
74
|
+
|
|
75
|
+
### Task Management
|
|
76
|
+
- **TodoWrite**: Track pending tasks and progress
|
|
77
|
+
|
|
78
|
+
### MCP Tools (DartMind Super-Server)
|
|
79
|
+
- **verify_package**: Validate packages exist on pub.dev (prevents hallucinations)
|
|
80
|
+
- **analyze_dart**: Run dart analyzer on code
|
|
81
|
+
- **security_scan**: Check for security vulnerabilities
|
|
82
|
+
- **check_policy**: Validate against architecture patterns (Clean/MVVM)`;
|
|
83
|
+
// ═══════════════════════════════════════════════════════════════
|
|
84
|
+
// BUILD CACHED SYSTEM BLOCKS
|
|
85
|
+
// ═══════════════════════════════════════════════════════════════
|
|
86
|
+
/**
|
|
87
|
+
* Build system message blocks with cache_control markers.
|
|
88
|
+
*
|
|
89
|
+
* @param projectContext - Dynamic project context (structure, dependencies)
|
|
90
|
+
* @param config - Cache configuration
|
|
91
|
+
* @returns Array of cacheable blocks for Anthropic API
|
|
92
|
+
*/
|
|
93
|
+
export function buildCachedSystemBlocks(projectContext, config = DEFAULT_CACHE_CONFIG) {
|
|
94
|
+
const blocks = [];
|
|
95
|
+
// Block 1: System Prompt (~1,500 tokens) - CACHE
|
|
96
|
+
blocks.push({
|
|
97
|
+
type: 'text',
|
|
98
|
+
text: SYSTEM_PROMPT_CACHED,
|
|
99
|
+
...(config.enableSystemPromptCache && {
|
|
100
|
+
cache_control: { type: 'ephemeral' }
|
|
101
|
+
})
|
|
102
|
+
});
|
|
103
|
+
// Block 2: Tool Definitions (~500 tokens) - CACHE
|
|
104
|
+
blocks.push({
|
|
105
|
+
type: 'text',
|
|
106
|
+
text: TOOL_DEFINITIONS_CACHED,
|
|
107
|
+
...(config.enableToolDefinitionsCache && {
|
|
108
|
+
cache_control: { type: 'ephemeral' }
|
|
109
|
+
})
|
|
110
|
+
});
|
|
111
|
+
// Block 3: Project Context (dynamic, ~500-2000 tokens) - CACHE
|
|
112
|
+
if (projectContext) {
|
|
113
|
+
blocks.push({
|
|
114
|
+
type: 'text',
|
|
115
|
+
text: `## PROJECT CONTEXT\n\n${projectContext}`,
|
|
116
|
+
...(config.enableProjectContextCache && {
|
|
117
|
+
cache_control: { type: 'ephemeral' }
|
|
118
|
+
})
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
return blocks;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Build a concise project context string for caching.
|
|
125
|
+
*/
|
|
126
|
+
export function buildProjectContext(project) {
|
|
127
|
+
const parts = [];
|
|
128
|
+
parts.push(`Project: ${project.name}`);
|
|
129
|
+
parts.push(`Path: ${project.path}`);
|
|
130
|
+
if (project.stateManagement) {
|
|
131
|
+
parts.push(`State Management: ${project.stateManagement}`);
|
|
132
|
+
}
|
|
133
|
+
if (project.architecture) {
|
|
134
|
+
parts.push(`Architecture: ${project.architecture}`);
|
|
135
|
+
}
|
|
136
|
+
if (project.dependencies && project.dependencies.length > 0) {
|
|
137
|
+
parts.push(`Key Dependencies: ${project.dependencies.slice(0, 10).join(', ')}`);
|
|
138
|
+
}
|
|
139
|
+
if (project.structure) {
|
|
140
|
+
parts.push(`\nStructure:\n${project.structure}`);
|
|
141
|
+
}
|
|
142
|
+
return parts.join('\n');
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Calculate cache savings from API response usage.
|
|
146
|
+
*
|
|
147
|
+
* @param usage - Usage object from Anthropic API response
|
|
148
|
+
* @param modelCostPerMillion - Input cost per 1M tokens (default: Sonnet $3.00)
|
|
149
|
+
* @returns Cache metrics including savings
|
|
150
|
+
*/
|
|
151
|
+
export function calculateCacheMetrics(usage, modelCostPerMillion = 3.00) {
|
|
152
|
+
const cacheRead = usage.cache_read_input_tokens ?? 0;
|
|
153
|
+
const cacheWrite = usage.cache_creation_input_tokens ?? 0;
|
|
154
|
+
const totalInput = usage.input_tokens;
|
|
155
|
+
const freshInput = totalInput - cacheRead;
|
|
156
|
+
// Calculate savings
|
|
157
|
+
// Full price: modelCostPerMillion per 1M tokens
|
|
158
|
+
// Cache read: 10% of full price (90% off)
|
|
159
|
+
const cacheReadCostMultiplier = 0.10;
|
|
160
|
+
const fullPriceCost = totalInput * (modelCostPerMillion / 1_000_000);
|
|
161
|
+
const actualCost = freshInput * (modelCostPerMillion / 1_000_000) +
|
|
162
|
+
cacheRead * (modelCostPerMillion * cacheReadCostMultiplier / 1_000_000);
|
|
163
|
+
const savings = fullPriceCost - actualCost;
|
|
164
|
+
const savingsPercent = fullPriceCost > 0 ? (savings / fullPriceCost) * 100 : 0;
|
|
165
|
+
return {
|
|
166
|
+
cacheReadTokens: cacheRead,
|
|
167
|
+
cacheWriteTokens: cacheWrite,
|
|
168
|
+
freshInputTokens: freshInput,
|
|
169
|
+
totalInputTokens: totalInput,
|
|
170
|
+
cacheSavingsPercent: savingsPercent,
|
|
171
|
+
estimatedSavings: savings
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Format cache metrics for logging.
|
|
176
|
+
*/
|
|
177
|
+
export function formatCacheMetrics(metrics) {
|
|
178
|
+
return [
|
|
179
|
+
`Cache: ${metrics.cacheReadTokens.toLocaleString()} read`,
|
|
180
|
+
`${metrics.freshInputTokens.toLocaleString()} fresh`,
|
|
181
|
+
`${metrics.cacheSavingsPercent.toFixed(1)}% saved`,
|
|
182
|
+
`($${metrics.estimatedSavings.toFixed(4)} savings)`
|
|
183
|
+
].join(' | ');
|
|
184
|
+
}
|
|
185
|
+
// ═══════════════════════════════════════════════════════════════
|
|
186
|
+
// SYSTEM MESSAGE BUILDER FOR ANTHROPIC API
|
|
187
|
+
// ═══════════════════════════════════════════════════════════════
|
|
188
|
+
/**
|
|
189
|
+
* Build a complete system message string (non-cached version for compatibility)
|
|
190
|
+
*/
|
|
191
|
+
export function buildSystemMessage(projectContext) {
|
|
192
|
+
const parts = [SYSTEM_PROMPT_CACHED, TOOL_DEFINITIONS_CACHED];
|
|
193
|
+
if (projectContext) {
|
|
194
|
+
parts.push(`## PROJECT CONTEXT\n\n${projectContext}`);
|
|
195
|
+
}
|
|
196
|
+
return parts.join('\n\n');
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Estimate token count for a string (rough approximation)
|
|
200
|
+
* ~4 characters per token for English text
|
|
201
|
+
*/
|
|
202
|
+
export function estimateTokens(text) {
|
|
203
|
+
return Math.ceil(text.length / 4);
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Get estimated token count for cached system blocks
|
|
207
|
+
*/
|
|
208
|
+
export function getSystemBlocksTokenEstimate(projectContext) {
|
|
209
|
+
const systemPrompt = estimateTokens(SYSTEM_PROMPT_CACHED);
|
|
210
|
+
const toolDefinitions = estimateTokens(TOOL_DEFINITIONS_CACHED);
|
|
211
|
+
const projectContextTokens = projectContext ? estimateTokens(projectContext) : 0;
|
|
212
|
+
return {
|
|
213
|
+
systemPrompt,
|
|
214
|
+
toolDefinitions,
|
|
215
|
+
projectContext: projectContextTokens,
|
|
216
|
+
total: systemPrompt + toolDefinitions + projectContextTokens
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
//# sourceMappingURL=prompt-cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-cache.js","sourceRoot":"","sources":["../../../src/core/cost/prompt-cache.ts"],"names":[],"mappings":"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"}
|