dual-brain 0.2.30 → 0.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/.dual-brain/docs/claude-code-extension-points.md +32 -0
- package/.dual-brain/docs/data-tools-capabilities.md +181 -0
- package/.dual-brain/docs/ecosystem-tools.md +91 -0
- package/.dual-brain/docs/panel-handoff.md +124 -0
- package/.dual-brain/docs/ruflo-analysis.md +48 -0
- package/bin/dual-brain.mjs +56 -56
- package/dist/mcp-server/index.d.ts +27 -0
- package/dist/mcp-server/index.js +359 -0
- package/dist/mcp-server/index.js.map +1 -0
- package/dist/src/agent-protocol.d.ts +163 -0
- package/dist/src/agent-protocol.js +368 -0
- package/dist/src/agent-protocol.js.map +1 -0
- package/dist/src/agents/registry.d.ts +52 -0
- package/dist/src/agents/registry.js +393 -0
- package/dist/src/agents/registry.js.map +1 -0
- package/dist/src/awareness.d.ts +93 -0
- package/dist/src/awareness.js +406 -0
- package/dist/src/awareness.js.map +1 -0
- package/dist/src/brief.d.ts +48 -0
- package/dist/src/brief.js +179 -0
- package/dist/src/brief.js.map +1 -0
- package/dist/src/calibration.d.ts +32 -0
- package/dist/src/calibration.js +133 -0
- package/dist/src/calibration.js.map +1 -0
- package/dist/src/checkpoint.d.ts +33 -0
- package/dist/src/checkpoint.js +99 -0
- package/dist/src/checkpoint.js.map +1 -0
- package/dist/src/ci-triage.d.ts +33 -0
- package/dist/src/ci-triage.js +193 -0
- package/dist/src/ci-triage.js.map +1 -0
- package/dist/src/cognitive-loop.d.ts +56 -0
- package/dist/src/cognitive-loop.js +495 -0
- package/dist/src/cognitive-loop.js.map +1 -0
- package/dist/src/collaboration.d.ts +147 -0
- package/dist/src/collaboration.js +438 -0
- package/dist/src/collaboration.js.map +1 -0
- package/dist/src/context-intel.d.ts +47 -0
- package/dist/src/context-intel.js +156 -0
- package/dist/src/context-intel.js.map +1 -0
- package/dist/src/context.d.ts +53 -0
- package/dist/src/context.js +332 -0
- package/dist/src/context.js.map +1 -0
- package/dist/src/continuity.d.ts +89 -0
- package/dist/src/continuity.js +230 -0
- package/dist/src/continuity.js.map +1 -0
- package/dist/src/cost-tracker.d.ts +47 -0
- package/dist/src/cost-tracker.js +170 -0
- package/dist/src/cost-tracker.js.map +1 -0
- package/dist/src/debrief.d.ts +53 -0
- package/dist/src/debrief.js +222 -0
- package/dist/src/debrief.js.map +1 -0
- package/dist/src/decide.d.ts +96 -0
- package/dist/src/decide.js +744 -0
- package/dist/src/decide.js.map +1 -0
- package/dist/src/decompose.d.ts +39 -0
- package/dist/src/decompose.js +218 -0
- package/dist/src/decompose.js.map +1 -0
- package/dist/src/detect.d.ts +91 -0
- package/dist/src/detect.js +544 -0
- package/dist/src/detect.js.map +1 -0
- package/dist/src/dispatch.d.ts +154 -0
- package/dist/src/dispatch.js +1306 -0
- package/dist/src/dispatch.js.map +1 -0
- package/dist/src/doctor.d.ts +421 -0
- package/dist/src/doctor.js +1689 -0
- package/dist/src/doctor.js.map +1 -0
- package/dist/src/engine.d.ts +70 -0
- package/dist/src/engine.js +155 -0
- package/dist/src/engine.js.map +1 -0
- package/dist/src/envelope.d.ts +36 -0
- package/dist/src/envelope.js +80 -0
- package/dist/src/envelope.js.map +1 -0
- package/dist/src/failure-memory.d.ts +55 -0
- package/dist/src/failure-memory.js +175 -0
- package/dist/src/failure-memory.js.map +1 -0
- package/dist/src/fx.d.ts +87 -0
- package/dist/src/fx.js +272 -0
- package/dist/src/fx.js.map +1 -0
- package/dist/src/governance.d.ts +93 -0
- package/dist/src/governance.js +261 -0
- package/dist/src/governance.js.map +1 -0
- package/dist/src/handoff.d.ts +11 -0
- package/dist/src/handoff.js +90 -0
- package/dist/src/handoff.js.map +1 -0
- package/dist/src/head-protocol.d.ts +76 -0
- package/dist/src/head-protocol.js +109 -0
- package/dist/src/head-protocol.js.map +1 -0
- package/dist/src/head.d.ts +222 -0
- package/dist/src/head.js +765 -0
- package/dist/src/head.js.map +1 -0
- package/dist/src/health.d.ts +132 -0
- package/dist/src/health.js +435 -0
- package/dist/src/health.js.map +1 -0
- package/dist/src/inbox.d.ts +70 -0
- package/dist/src/inbox.js +218 -0
- package/dist/src/inbox.js.map +1 -0
- package/dist/src/index.d.ts +33 -0
- package/dist/src/index.js +38 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/install-hooks.d.ts +13 -0
- package/dist/src/install-hooks.js +88 -0
- package/dist/src/install-hooks.js.map +1 -0
- package/dist/src/integrity.d.ts +59 -0
- package/dist/src/integrity.js +206 -0
- package/dist/src/integrity.js.map +1 -0
- package/dist/src/intelligence.d.ts +104 -0
- package/dist/src/intelligence.js +391 -0
- package/dist/src/intelligence.js.map +1 -0
- package/dist/src/ledger.d.ts +54 -0
- package/dist/src/ledger.js +179 -0
- package/dist/src/ledger.js.map +1 -0
- package/dist/src/living-docs.d.ts +14 -0
- package/dist/src/living-docs.js +197 -0
- package/dist/src/living-docs.js.map +1 -0
- package/dist/src/memory-tiers.d.ts +37 -0
- package/dist/src/memory-tiers.js +160 -0
- package/dist/src/memory-tiers.js.map +1 -0
- package/dist/src/model-profiles.d.ts +65 -0
- package/dist/src/model-profiles.js +568 -0
- package/dist/src/model-profiles.js.map +1 -0
- package/dist/src/models.d.ts +58 -0
- package/dist/src/models.js +327 -0
- package/dist/src/models.js.map +1 -0
- package/dist/src/narrative.d.ts +54 -0
- package/dist/src/narrative.js +163 -0
- package/dist/src/narrative.js.map +1 -0
- package/dist/src/nextstep.d.ts +16 -0
- package/dist/src/nextstep.js +103 -0
- package/dist/src/nextstep.js.map +1 -0
- package/dist/src/observer.d.ts +18 -0
- package/dist/src/observer.js +251 -0
- package/dist/src/observer.js.map +1 -0
- package/dist/src/outcome.d.ts +110 -0
- package/dist/src/outcome.js +377 -0
- package/dist/src/outcome.js.map +1 -0
- package/dist/src/pipeline.d.ts +167 -0
- package/dist/src/pipeline.js +1503 -0
- package/dist/src/pipeline.js.map +1 -0
- package/dist/src/playbook.d.ts +59 -0
- package/dist/src/playbook.js +238 -0
- package/dist/src/playbook.js.map +1 -0
- package/dist/src/pr-agent.d.ts +97 -0
- package/dist/src/pr-agent.js +195 -0
- package/dist/src/pr-agent.js.map +1 -0
- package/dist/src/predictive.d.ts +57 -0
- package/dist/src/predictive.js +230 -0
- package/dist/src/predictive.js.map +1 -0
- package/dist/src/profile.d.ts +294 -0
- package/dist/src/profile.js +1347 -0
- package/dist/src/profile.js.map +1 -0
- package/dist/src/prompt-audit.d.ts +22 -0
- package/dist/src/prompt-audit.js +194 -0
- package/dist/src/prompt-audit.js.map +1 -0
- package/dist/src/prompt-intel.d.ts +12 -0
- package/dist/src/prompt-intel.js +321 -0
- package/dist/src/prompt-intel.js.map +1 -0
- package/dist/src/provider-context.d.ts +121 -0
- package/dist/src/provider-context.js +222 -0
- package/dist/src/provider-context.js.map +1 -0
- package/dist/src/provider-manager.d.ts +92 -0
- package/dist/src/provider-manager.js +428 -0
- package/dist/src/provider-manager.js.map +1 -0
- package/dist/src/receipt.d.ts +87 -0
- package/dist/src/receipt.js +326 -0
- package/dist/src/receipt.js.map +1 -0
- package/dist/src/recommendations.d.ts +13 -0
- package/dist/src/recommendations.js +291 -0
- package/dist/src/recommendations.js.map +1 -0
- package/dist/src/redact.d.ts +15 -0
- package/dist/src/redact.js +129 -0
- package/dist/src/redact.js.map +1 -0
- package/dist/src/replit.d.ts +397 -0
- package/dist/src/replit.js +1160 -0
- package/dist/src/replit.js.map +1 -0
- package/dist/src/repo.d.ts +149 -0
- package/dist/src/repo.js +416 -0
- package/dist/src/repo.js.map +1 -0
- package/dist/src/revert.d.ts +30 -0
- package/dist/src/revert.js +166 -0
- package/dist/src/revert.js.map +1 -0
- package/dist/src/room.d.ts +102 -0
- package/dist/src/room.js +212 -0
- package/dist/src/room.js.map +1 -0
- package/dist/src/routing-advisor.d.ts +57 -0
- package/dist/src/routing-advisor.js +221 -0
- package/dist/src/routing-advisor.js.map +1 -0
- package/dist/src/self-correct.d.ts +40 -0
- package/dist/src/self-correct.js +137 -0
- package/dist/src/self-correct.js.map +1 -0
- package/dist/src/session-lock.d.ts +35 -0
- package/dist/src/session-lock.js +134 -0
- package/dist/src/session-lock.js.map +1 -0
- package/dist/src/session.d.ts +267 -0
- package/dist/src/session.js +1660 -0
- package/dist/src/session.js.map +1 -0
- package/dist/src/settings-tui.d.ts +5 -0
- package/dist/src/settings-tui.js +422 -0
- package/dist/src/settings-tui.js.map +1 -0
- package/dist/src/setup-flow.d.ts +63 -0
- package/dist/src/setup-flow.js +233 -0
- package/dist/src/setup-flow.js.map +1 -0
- package/dist/src/signal.d.ts +19 -0
- package/dist/src/signal.js +122 -0
- package/dist/src/signal.js.map +1 -0
- package/dist/src/simmer.d.ts +85 -0
- package/dist/src/simmer.js +224 -0
- package/dist/src/simmer.js.map +1 -0
- package/dist/src/state-export.d.ts +129 -0
- package/dist/src/state-export.js +233 -0
- package/dist/src/state-export.js.map +1 -0
- package/dist/src/strategy.d.ts +54 -0
- package/dist/src/strategy.js +95 -0
- package/dist/src/strategy.js.map +1 -0
- package/dist/src/subscription.d.ts +40 -0
- package/dist/src/subscription.js +189 -0
- package/dist/src/subscription.js.map +1 -0
- package/dist/src/templates.d.ts +208 -0
- package/dist/src/templates.js +238 -0
- package/dist/src/templates.js.map +1 -0
- package/dist/src/test.d.ts +9 -0
- package/dist/src/test.js +1173 -0
- package/dist/src/test.js.map +1 -0
- package/dist/src/think-engine.d.ts +67 -0
- package/dist/src/think-engine.js +412 -0
- package/dist/src/think-engine.js.map +1 -0
- package/dist/src/tui.d.ts +71 -0
- package/dist/src/tui.js +242 -0
- package/dist/src/tui.js.map +1 -0
- package/dist/src/types.d.ts +177 -0
- package/dist/src/types.js +6 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/update-check.d.ts +7 -0
- package/dist/src/update-check.js +36 -0
- package/dist/src/update-check.js.map +1 -0
- package/dist/src/wave-planner.d.ts +30 -0
- package/dist/src/wave-planner.js +281 -0
- package/dist/src/wave-planner.js.map +1 -0
- package/hooks/head-guard.sh +41 -0
- package/hooks/task-classifier.mjs +328 -0
- package/hooks/vibe-router.mjs +387 -0
- package/package.json +29 -153
- package/src/agents/registry.mjs +0 -405
- package/src/awareness.mjs +0 -425
- package/src/brief.mjs +0 -266
- package/src/calibration.mjs +0 -148
- package/src/checkpoint.mjs +0 -109
- package/src/ci-triage.mjs +0 -191
- package/src/cognitive-loop.mjs +0 -562
- package/src/collaboration.mjs +0 -545
- package/src/context-intel.mjs +0 -158
- package/src/context.mjs +0 -389
- package/src/continuity.mjs +0 -298
- package/src/cost-tracker.mjs +0 -184
- package/src/debrief.mjs +0 -228
- package/src/decide.mjs +0 -1099
- package/src/decompose.mjs +0 -331
- package/src/detect.mjs +0 -702
- package/src/dispatch.mjs +0 -1447
- package/src/doctor.mjs +0 -1607
- package/src/envelope.mjs +0 -139
- package/src/failure-memory.mjs +0 -178
- package/src/fx.mjs +0 -276
- package/src/governance.mjs +0 -279
- package/src/handoff.mjs +0 -87
- package/src/head-protocol.mjs +0 -128
- package/src/head.mjs +0 -952
- package/src/health.mjs +0 -528
- package/src/inbox.mjs +0 -195
- package/src/index.mjs +0 -44
- package/src/install-hooks.mjs +0 -100
- package/src/integrity.mjs +0 -245
- package/src/intelligence.mjs +0 -447
- package/src/ledger.mjs +0 -196
- package/src/living-docs.mjs +0 -210
- package/src/memory-tiers.mjs +0 -193
- package/src/models.mjs +0 -363
- package/src/narrative.mjs +0 -169
- package/src/nextstep.mjs +0 -100
- package/src/observer.mjs +0 -241
- package/src/outcome.mjs +0 -400
- package/src/pipeline.mjs +0 -1711
- package/src/playbook.mjs +0 -257
- package/src/pr-agent.mjs +0 -214
- package/src/predictive.mjs +0 -250
- package/src/profile.mjs +0 -1411
- package/src/prompt-audit.mjs +0 -231
- package/src/prompt-intel.mjs +0 -325
- package/src/provider-context.mjs +0 -257
- package/src/receipt.mjs +0 -344
- package/src/recommendations.mjs +0 -296
- package/src/redact.mjs +0 -192
- package/src/replit.mjs +0 -1210
- package/src/repo.mjs +0 -445
- package/src/revert.mjs +0 -149
- package/src/routing-advisor.mjs +0 -204
- package/src/self-correct.mjs +0 -147
- package/src/session-lock.mjs +0 -160
- package/src/session.mjs +0 -1655
- package/src/settings-tui.mjs +0 -373
- package/src/setup-flow.mjs +0 -223
- package/src/signal.mjs +0 -115
- package/src/simmer.mjs +0 -241
- package/src/strategy.mjs +0 -235
- package/src/subscription.mjs +0 -212
- package/src/templates.mjs +0 -260
- package/src/think-engine.mjs +0 -428
- package/src/tui.mjs +0 -276
- package/src/update-check.mjs +0 -35
- package/src/wave-planner.mjs +0 -294
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
// strategy.ts — Dispatch strategy library + selection
|
|
2
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
export const STRATEGIES = {
|
|
5
|
+
direct: { id: 'direct', label: 'Direct dispatch', description: 'Single agent, single task. Best for clear, focused work.', applicability: { maxFiles: 3, maxComplexity: 'moderate', maxRisk: 'medium' }, cost: 1.0 },
|
|
6
|
+
cascade: { id: 'cascade', label: 'Think → Execute cascade', description: 'Cheap thinker refines spec, then worker executes. Best for routine-but-multi-step tasks.', applicability: { minFiles: 1, minComplexity: 'moderate', maxRisk: 'high' }, cost: 1.3 },
|
|
7
|
+
split: { id: 'split', label: 'Decompose → parallel dispatch', description: 'Break into sub-tasks, dispatch each at optimal tier. Best for large multi-file changes.', applicability: { minFiles: 4, minComplexity: 'complex' }, cost: 2.0 },
|
|
8
|
+
'dual-review': { id: 'dual-review', label: 'Execute → adversarial review', description: 'Worker implements, second model reviews. Best for high-risk/security code.', applicability: { minRisk: 'high' }, cost: 1.5 },
|
|
9
|
+
'architect-editor': { id: 'architect-editor', label: 'Architect reasons → editor implements', description: 'Opus/o3 reasons freely, sonnet/haiku formats the edits. Best for complex architecture + implementation.', applicability: { minComplexity: 'complex', minFiles: 3 }, cost: 1.8 },
|
|
10
|
+
};
|
|
11
|
+
// ─── Helpers ───────────────────────────────────────────────────────────────────
|
|
12
|
+
const COMPLEXITY_RANK = { trivial: 0, simple: 1, moderate: 2, complex: 3 };
|
|
13
|
+
const RISK_RANK = { low: 0, medium: 1, high: 2, critical: 3 };
|
|
14
|
+
const COST_CAPS = {
|
|
15
|
+
frugal: 1.0, 'cost-saver': 1.3, balanced: 2.0, 'quality-first': 3.0, maximum: Infinity, aggressive: Infinity, fullpower: Infinity, fast: 1.3,
|
|
16
|
+
};
|
|
17
|
+
const SECURITY_KEYWORDS = /\b(auth|security|billing|payment|credential|secret|token|encrypt|permission|oauth|jwt)\b/i;
|
|
18
|
+
function costCap(workStyle) { return COST_CAPS[workStyle] ?? 2.0; }
|
|
19
|
+
function fileCount(detection) { return detection?.fileCount ?? detection?.files ?? 0; }
|
|
20
|
+
function complexityRank(detection) { return COMPLEXITY_RANK[detection?.complexity ?? ''] ?? 1; }
|
|
21
|
+
function riskRank(detection) { return RISK_RANK[detection?.risk ?? ''] ?? 0; }
|
|
22
|
+
function prompt(detection) { return detection?.prompt ?? detection?.description ?? ''; }
|
|
23
|
+
// ─── Scoring ───────────────────────────────────────────────────────────────────
|
|
24
|
+
function scoreStrategies(detection, workStyle) {
|
|
25
|
+
const files = fileCount(detection);
|
|
26
|
+
const cRank = complexityRank(detection);
|
|
27
|
+
const rRank = riskRank(detection);
|
|
28
|
+
const text = prompt(detection);
|
|
29
|
+
const frugal = workStyle === 'frugal';
|
|
30
|
+
const saver = workStyle === 'cost-saver' || workStyle === 'fast';
|
|
31
|
+
return {
|
|
32
|
+
direct: 0.5,
|
|
33
|
+
cascade: 0 + (cRank >= COMPLEXITY_RANK.moderate ? 0.3 : 0) + (files >= 2 ? 0.2 : 0) - (frugal ? 0.5 : 0),
|
|
34
|
+
split: 0 + (files >= 4 ? 0.4 : 0) + (cRank >= COMPLEXITY_RANK.complex ? 0.3 : 0) - (frugal || saver ? 0.5 : 0),
|
|
35
|
+
'dual-review': 0 + (rRank >= RISK_RANK.high ? 0.5 : 0) + (SECURITY_KEYWORDS.test(text) ? 0.3 : 0) - (frugal ? 0.3 : 0),
|
|
36
|
+
'architect-editor': 0 + (cRank >= COMPLEXITY_RANK.complex && files >= 3 ? 0.4 : 0) - (saver ? 0.3 : 0),
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
export function selectStrategy(detection, decision, profile) {
|
|
40
|
+
try {
|
|
41
|
+
const workStyle = profile?.workStyle ?? profile?.bias ?? 'balanced';
|
|
42
|
+
const cap = costCap(workStyle);
|
|
43
|
+
const scores = scoreStrategies(detection, workStyle);
|
|
44
|
+
const ranked = Object.entries(scores).filter(([id]) => STRATEGIES[id].cost <= cap).sort(([, a], [, b]) => b - a);
|
|
45
|
+
if (!ranked.length)
|
|
46
|
+
return { strategy: 'direct', reason: 'Cost cap allows only direct dispatch.', alternatives: [] };
|
|
47
|
+
const [bestId] = ranked[0];
|
|
48
|
+
const alternatives = ranked.slice(1).map(([id]) => id);
|
|
49
|
+
const reasons = {
|
|
50
|
+
direct: 'Clear, focused task within single-agent scope.',
|
|
51
|
+
cascade: 'Multi-step task benefits from spec refinement before execution.',
|
|
52
|
+
split: 'Large file count warrants decomposition into parallel sub-tasks.',
|
|
53
|
+
'dual-review': 'High-risk or security-sensitive work requires adversarial review.',
|
|
54
|
+
'architect-editor': 'Complex architecture + implementation benefits from dual-model reasoning.',
|
|
55
|
+
};
|
|
56
|
+
return { strategy: bestId, reason: reasons[bestId] ?? 'Best match for task profile.', alternatives };
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return { strategy: 'direct', reason: 'Fallback to direct dispatch.', alternatives: [] };
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
export function describeStrategy(strategyId) {
|
|
63
|
+
const s = STRATEGIES[strategyId];
|
|
64
|
+
if (!s)
|
|
65
|
+
return `Unknown strategy: ${strategyId}`;
|
|
66
|
+
return `${s.label} (cost ×${s.cost})\n${s.description}`;
|
|
67
|
+
}
|
|
68
|
+
export function getStrategyForTask(detection, cwd) {
|
|
69
|
+
const dir = cwd ?? process.cwd();
|
|
70
|
+
let profile = {};
|
|
71
|
+
try {
|
|
72
|
+
const p = join(dir, '.dualbrain', 'config.json');
|
|
73
|
+
if (existsSync(p))
|
|
74
|
+
profile = JSON.parse(readFileSync(p, 'utf8'));
|
|
75
|
+
}
|
|
76
|
+
catch { }
|
|
77
|
+
const decision = { model: profile?.models?.execute ?? 'sonnet' };
|
|
78
|
+
const selected = selectStrategy(detection, decision, profile);
|
|
79
|
+
return { ...selected, plan: buildPlan(selected.strategy, decision) };
|
|
80
|
+
}
|
|
81
|
+
function buildPlan(strategyId, decision) {
|
|
82
|
+
const m = decision?.model ?? 'sonnet';
|
|
83
|
+
const plans = {
|
|
84
|
+
direct: [{ role: 'worker', model: m, description: 'Execute task' }],
|
|
85
|
+
cascade: [{ role: 'thinker', model: 'sonnet', description: 'Refine spec' }, { role: 'worker', model: 'from-think', description: 'Execute refined spec' }],
|
|
86
|
+
split: [{ role: 'thinker', model: 'sonnet', description: 'Decompose into sub-tasks' }, { role: 'worker', model: 'varies', description: 'Execute each sub-task' }],
|
|
87
|
+
'dual-review': [{ role: 'worker', model: m, description: 'Implement' }, { role: 'reviewer', model: 'sonnet', description: 'Adversarial review' }],
|
|
88
|
+
'architect-editor': [{ role: 'thinker', model: 'opus', description: 'Architect solution' }, { role: 'worker', model: 'haiku', description: 'Format edits' }],
|
|
89
|
+
};
|
|
90
|
+
return { steps: plans[strategyId] ?? plans.direct };
|
|
91
|
+
}
|
|
92
|
+
export function listStrategies() {
|
|
93
|
+
return Object.values(STRATEGIES).map(({ id, label, description, cost }) => ({ id, label, description, cost }));
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=strategy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"strategy.js","sourceRoot":"","sources":["../../src/strategy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
interface SubscriptionConfig {
|
|
2
|
+
label: string;
|
|
3
|
+
provider: string;
|
|
4
|
+
tokenBudget: string;
|
|
5
|
+
recommendedProfile: string;
|
|
6
|
+
modelWeights: Record<string, number>;
|
|
7
|
+
notes: string;
|
|
8
|
+
}
|
|
9
|
+
export declare const SUBSCRIPTIONS: Record<string, SubscriptionConfig>;
|
|
10
|
+
interface DefaultWeights {
|
|
11
|
+
modelWeights: Record<string, number>;
|
|
12
|
+
profile: string;
|
|
13
|
+
notes: string;
|
|
14
|
+
}
|
|
15
|
+
/** Returns the subscription config object or null. */
|
|
16
|
+
export declare function getSubscription(subType: string): SubscriptionConfig | null;
|
|
17
|
+
/** Returns { modelWeights, profile, notes } for the subscription. Falls back to balanced defaults. */
|
|
18
|
+
export declare function getRecommendedWeights(subType: string): DefaultWeights;
|
|
19
|
+
/** Writes { subscription, configuredAt } to .dualbrain/subscription.json. */
|
|
20
|
+
export declare function saveUserSubscription(subType: string, cwd: string | undefined): void;
|
|
21
|
+
/** Reads the saved subscription. Returns subType string or null. */
|
|
22
|
+
export declare function loadUserSubscription(cwd: string | undefined): string | null;
|
|
23
|
+
interface RoutingStatsInput {
|
|
24
|
+
cells?: Record<string, Record<string, {
|
|
25
|
+
observations?: number;
|
|
26
|
+
}>>;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Generates a text recommendation based on subscription + current routing stats.
|
|
30
|
+
* routingStats: return value of getRoutingStats() from routing-advisor.mjs
|
|
31
|
+
*/
|
|
32
|
+
export declare function generateRecommendation(subType: string, routingStats: RoutingStatsInput | null | undefined): string;
|
|
33
|
+
interface SubscriptionListEntry {
|
|
34
|
+
key: string;
|
|
35
|
+
label: string;
|
|
36
|
+
provider: string;
|
|
37
|
+
}
|
|
38
|
+
/** Returns array of { key, label, provider } for display in UX. */
|
|
39
|
+
export declare function listSubscriptions(): SubscriptionListEntry[];
|
|
40
|
+
export {};
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
// subscription.ts — Subscription-aware routing defaults
|
|
2
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
export const SUBSCRIPTIONS = {
|
|
5
|
+
// Claude subscriptions
|
|
6
|
+
'claude-pro': {
|
|
7
|
+
label: 'Claude Pro ($20/mo)',
|
|
8
|
+
provider: 'claude',
|
|
9
|
+
tokenBudget: 'moderate', // 5-hr rolling window, weekly cap
|
|
10
|
+
recommendedProfile: 'balanced',
|
|
11
|
+
modelWeights: { haiku: 0.4, sonnet: 0.5, opus: 0.1 },
|
|
12
|
+
notes: 'One extended Opus session can use 20% of your allocation. Prefer sonnet for routine work.',
|
|
13
|
+
},
|
|
14
|
+
'claude-max-5x': {
|
|
15
|
+
label: 'Claude Max 5x ($100/mo)',
|
|
16
|
+
provider: 'claude',
|
|
17
|
+
tokenBudget: 'generous',
|
|
18
|
+
recommendedProfile: 'quality-first',
|
|
19
|
+
modelWeights: { haiku: 0.2, sonnet: 0.5, opus: 0.3 },
|
|
20
|
+
notes: '5x Pro capacity. Opus is available for complex/creative work without worry.',
|
|
21
|
+
},
|
|
22
|
+
'claude-max-20x': {
|
|
23
|
+
label: 'Claude Max 20x ($200/mo)',
|
|
24
|
+
provider: 'claude',
|
|
25
|
+
tokenBudget: 'unlimited',
|
|
26
|
+
recommendedProfile: 'quality-first',
|
|
27
|
+
modelWeights: { haiku: 0.1, sonnet: 0.4, opus: 0.5 },
|
|
28
|
+
notes: 'Effectively unlimited. Use the best model for every task.',
|
|
29
|
+
},
|
|
30
|
+
'claude-team': {
|
|
31
|
+
label: 'Claude Team ($30/seat/mo)',
|
|
32
|
+
provider: 'claude',
|
|
33
|
+
tokenBudget: 'moderate',
|
|
34
|
+
recommendedProfile: 'balanced',
|
|
35
|
+
modelWeights: { haiku: 0.3, sonnet: 0.5, opus: 0.2 },
|
|
36
|
+
notes: 'Team tier with admin controls. Collaboration triggers recommended.',
|
|
37
|
+
},
|
|
38
|
+
// ChatGPT subscriptions
|
|
39
|
+
'chatgpt-plus': {
|
|
40
|
+
label: 'ChatGPT Plus ($20/mo)',
|
|
41
|
+
provider: 'openai',
|
|
42
|
+
tokenBudget: 'limited', // 50 o3/day on Plus
|
|
43
|
+
recommendedProfile: 'cost-saver',
|
|
44
|
+
modelWeights: { 'o4-mini': 0.6, 'gpt-4.1': 0.3, 'o3': 0.1 },
|
|
45
|
+
notes: '50 o3 messages/day limit. Heavy on o4-mini for routine, save o3 for critical decisions.',
|
|
46
|
+
},
|
|
47
|
+
'chatgpt-pro': {
|
|
48
|
+
label: 'ChatGPT Pro ($200/mo)',
|
|
49
|
+
provider: 'openai',
|
|
50
|
+
tokenBudget: 'generous',
|
|
51
|
+
recommendedProfile: 'quality-first',
|
|
52
|
+
modelWeights: { 'o4-mini': 0.3, 'gpt-4.1': 0.4, 'o3': 0.3 },
|
|
53
|
+
notes: 'Unlimited access to all models. Use o3 freely for complex reasoning.',
|
|
54
|
+
},
|
|
55
|
+
// Dual subscription (both providers)
|
|
56
|
+
'dual-pro': {
|
|
57
|
+
label: 'Both Pro tiers',
|
|
58
|
+
provider: 'both',
|
|
59
|
+
tokenBudget: 'moderate',
|
|
60
|
+
recommendedProfile: 'balanced',
|
|
61
|
+
modelWeights: { haiku: 0.2, sonnet: 0.3, 'gpt-4.1': 0.3, 'o4-mini': 0.2 },
|
|
62
|
+
notes: 'Split load across providers. Route by model strength: Claude for code, GPT for reasoning.',
|
|
63
|
+
},
|
|
64
|
+
'dual-max': {
|
|
65
|
+
label: 'Max + Pro (or both Max)',
|
|
66
|
+
provider: 'both',
|
|
67
|
+
tokenBudget: 'unlimited',
|
|
68
|
+
recommendedProfile: 'quality-first',
|
|
69
|
+
modelWeights: { sonnet: 0.3, opus: 0.2, 'gpt-4.1': 0.2, 'o3': 0.3 },
|
|
70
|
+
notes: 'Full power from both providers. Route by task fit, not by cost.',
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
const DEFAULT_WEIGHTS = {
|
|
74
|
+
modelWeights: { haiku: 0.3, sonnet: 0.5, opus: 0.2 },
|
|
75
|
+
profile: 'balanced',
|
|
76
|
+
notes: 'No subscription configured. Using balanced defaults.',
|
|
77
|
+
};
|
|
78
|
+
function subFile(cwd) {
|
|
79
|
+
return join(cwd || process.cwd(), '.dualbrain', 'subscription.json');
|
|
80
|
+
}
|
|
81
|
+
/** Returns the subscription config object or null. */
|
|
82
|
+
export function getSubscription(subType) {
|
|
83
|
+
return SUBSCRIPTIONS[subType] ?? null;
|
|
84
|
+
}
|
|
85
|
+
/** Returns { modelWeights, profile, notes } for the subscription. Falls back to balanced defaults. */
|
|
86
|
+
export function getRecommendedWeights(subType) {
|
|
87
|
+
const sub = SUBSCRIPTIONS[subType];
|
|
88
|
+
if (!sub)
|
|
89
|
+
return DEFAULT_WEIGHTS;
|
|
90
|
+
return {
|
|
91
|
+
modelWeights: sub.modelWeights,
|
|
92
|
+
profile: sub.recommendedProfile,
|
|
93
|
+
notes: sub.notes,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
/** Writes { subscription, configuredAt } to .dualbrain/subscription.json. */
|
|
97
|
+
export function saveUserSubscription(subType, cwd) {
|
|
98
|
+
const dir = join(cwd || process.cwd(), '.dualbrain');
|
|
99
|
+
if (!existsSync(dir))
|
|
100
|
+
mkdirSync(dir, { recursive: true });
|
|
101
|
+
writeFileSync(subFile(cwd), JSON.stringify({ subscription: subType, configuredAt: new Date().toISOString() }, null, 2), 'utf8');
|
|
102
|
+
}
|
|
103
|
+
/** Reads the saved subscription. Returns subType string or null. */
|
|
104
|
+
export function loadUserSubscription(cwd) {
|
|
105
|
+
try {
|
|
106
|
+
const p = subFile(cwd);
|
|
107
|
+
if (!existsSync(p))
|
|
108
|
+
return null;
|
|
109
|
+
const data = JSON.parse(readFileSync(p, 'utf8'));
|
|
110
|
+
return data.subscription ?? null;
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Generates a text recommendation based on subscription + current routing stats.
|
|
118
|
+
* routingStats: return value of getRoutingStats() from routing-advisor.mjs
|
|
119
|
+
*/
|
|
120
|
+
export function generateRecommendation(subType, routingStats) {
|
|
121
|
+
const sub = SUBSCRIPTIONS[subType];
|
|
122
|
+
if (!sub)
|
|
123
|
+
return 'No subscription configured. Run `dual-brain subscription set <type>` to enable smart routing defaults.';
|
|
124
|
+
// Tally actual model usage from routing stats cells
|
|
125
|
+
const actualUsage = {};
|
|
126
|
+
let totalObs = 0;
|
|
127
|
+
for (const models of Object.values(routingStats?.cells ?? {})) {
|
|
128
|
+
for (const [model, entry] of Object.entries(models)) {
|
|
129
|
+
actualUsage[model] = (actualUsage[model] ?? 0) + (entry.observations ?? 0);
|
|
130
|
+
totalObs += entry.observations ?? 0;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
if (totalObs === 0) {
|
|
134
|
+
return `You're on ${sub.label}. No routing history yet — recommended profile is ${sub.recommendedProfile}. ${sub.notes}`;
|
|
135
|
+
}
|
|
136
|
+
// Compute actual share per model
|
|
137
|
+
const actualShare = {};
|
|
138
|
+
for (const [model, count] of Object.entries(actualUsage)) {
|
|
139
|
+
actualShare[model] = count / totalObs;
|
|
140
|
+
}
|
|
141
|
+
const rec = sub.modelWeights;
|
|
142
|
+
const budget = sub.tokenBudget;
|
|
143
|
+
const lines = [];
|
|
144
|
+
// Check expensive model utilization vs. recommended
|
|
145
|
+
const expensiveModels = ['opus', 'o3'];
|
|
146
|
+
for (const model of expensiveModels) {
|
|
147
|
+
const recW = rec[model] ?? 0;
|
|
148
|
+
const actW = actualShare[model] ?? 0;
|
|
149
|
+
if (recW > 0 && budget === 'unlimited' && actW < recW * 0.5) {
|
|
150
|
+
lines.push(`You're on ${sub.label} but only using ${model} ${Math.round(actW * 100)}% of the time` +
|
|
151
|
+
` (recommended: ${Math.round(recW * 100)}%). You're paying for capacity you're not using.` +
|
|
152
|
+
` Consider switching to ${sub.recommendedProfile} mode.`);
|
|
153
|
+
}
|
|
154
|
+
else if (recW < 0.2 && budget === 'limited' && actW > recW * 2 && actW > 0.1) {
|
|
155
|
+
lines.push(`Your ${sub.label} subscription is token-limited. ${model} usage at ${Math.round(actW * 100)}%` +
|
|
156
|
+
` may exhaust daily limits — recommended cap is ~${Math.round(recW * 100)}%.`);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
// Cheap model suggestions on budget-constrained plans
|
|
160
|
+
const cheapModels = ['haiku', 'o4-mini'];
|
|
161
|
+
if (budget === 'moderate' || budget === 'limited') {
|
|
162
|
+
for (const model of cheapModels) {
|
|
163
|
+
const recW = rec[model] ?? 0;
|
|
164
|
+
const actW = actualShare[model] ?? 0;
|
|
165
|
+
if (recW > 0 && actW < recW * 0.5) {
|
|
166
|
+
lines.push(`Your ${sub.label} subscription has a ${budget} budget. Increasing ${model} usage` +
|
|
167
|
+
` (currently ${Math.round(actW * 100)}%, recommended ${Math.round(recW * 100)}%)` +
|
|
168
|
+
` for search and routine tasks would preserve your allocation.`);
|
|
169
|
+
break; // one cheap-model tip is enough
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
// Dominant model confirmation — find the most-used model
|
|
174
|
+
const topModel = Object.entries(actualShare).sort((a, b) => b[1] - a[1])[0];
|
|
175
|
+
if (lines.length === 0 && topModel) {
|
|
176
|
+
lines.push(`Your ${sub.label} subscription is well-matched. ${Math.round(topModel[1] * 100)}% of dispatches` +
|
|
177
|
+
` use ${topModel[0]} — a good fit for your ${budget} budget. ${sub.notes}`);
|
|
178
|
+
}
|
|
179
|
+
return lines.slice(0, 3).join(' ');
|
|
180
|
+
}
|
|
181
|
+
/** Returns array of { key, label, provider } for display in UX. */
|
|
182
|
+
export function listSubscriptions() {
|
|
183
|
+
return Object.entries(SUBSCRIPTIONS).map(([key, sub]) => ({
|
|
184
|
+
key,
|
|
185
|
+
label: sub.label,
|
|
186
|
+
provider: sub.provider,
|
|
187
|
+
}));
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=subscription.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subscription.js","sourceRoot":"","sources":["../../src/subscription.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Task contract — every dispatch must have one.
|
|
3
|
+
* @typedef {{
|
|
4
|
+
* id: string,
|
|
5
|
+
* objective: string,
|
|
6
|
+
* scope: string[],
|
|
7
|
+
* nonGoals?: string[],
|
|
8
|
+
* risk: 'low'|'medium'|'high'|'critical',
|
|
9
|
+
* acceptanceCriteria: string[],
|
|
10
|
+
* allowedOperations?: string[],
|
|
11
|
+
* context?: string,
|
|
12
|
+
* files?: string[],
|
|
13
|
+
* timeoutMs?: number,
|
|
14
|
+
* }} TaskContract
|
|
15
|
+
*/
|
|
16
|
+
interface TaskContract {
|
|
17
|
+
id?: string;
|
|
18
|
+
objective?: string;
|
|
19
|
+
scope?: string[];
|
|
20
|
+
nonGoals?: string[];
|
|
21
|
+
risk?: string;
|
|
22
|
+
acceptanceCriteria?: string[];
|
|
23
|
+
allowedOperations?: string[];
|
|
24
|
+
context?: string;
|
|
25
|
+
files?: string[];
|
|
26
|
+
timeoutMs?: number;
|
|
27
|
+
[key: string]: unknown;
|
|
28
|
+
}
|
|
29
|
+
type TemplateTier = 'search' | 'execute' | 'think' | 'review';
|
|
30
|
+
interface QuickRenderOpts {
|
|
31
|
+
scope?: string[];
|
|
32
|
+
files?: string[];
|
|
33
|
+
risk?: string;
|
|
34
|
+
criteria?: string[];
|
|
35
|
+
nonGoals?: string[];
|
|
36
|
+
context?: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Validate a task contract has all required fields.
|
|
40
|
+
* Returns { valid, missing }
|
|
41
|
+
*/
|
|
42
|
+
export declare function validateContract(contract: TaskContract): {
|
|
43
|
+
valid: boolean;
|
|
44
|
+
missing: string[];
|
|
45
|
+
contract: {
|
|
46
|
+
id: string;
|
|
47
|
+
objective?: string;
|
|
48
|
+
scope?: string[];
|
|
49
|
+
nonGoals?: string[];
|
|
50
|
+
risk?: string;
|
|
51
|
+
acceptanceCriteria?: string[];
|
|
52
|
+
allowedOperations?: string[];
|
|
53
|
+
context?: string;
|
|
54
|
+
files?: string[];
|
|
55
|
+
timeoutMs?: number;
|
|
56
|
+
} | null;
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* Get the structured output schema for a tier.
|
|
60
|
+
*/
|
|
61
|
+
export declare function getOutputSchema(tier: TemplateTier): string | null;
|
|
62
|
+
/**
|
|
63
|
+
* Get the preferred prompt rendering format for a given model ID.
|
|
64
|
+
*/
|
|
65
|
+
export declare function getRenderHint(modelId: string | undefined): string;
|
|
66
|
+
/**
|
|
67
|
+
* Get a template by tier name.
|
|
68
|
+
*/
|
|
69
|
+
export declare function getTemplate(tier: TemplateTier): {
|
|
70
|
+
id: string;
|
|
71
|
+
version: string;
|
|
72
|
+
tier: string;
|
|
73
|
+
description: string;
|
|
74
|
+
requiredFields: string[];
|
|
75
|
+
render(contract: TaskContract, context?: Record<string, unknown>): string;
|
|
76
|
+
} | {
|
|
77
|
+
id: string;
|
|
78
|
+
version: string;
|
|
79
|
+
tier: string;
|
|
80
|
+
description: string;
|
|
81
|
+
requiredFields: string[];
|
|
82
|
+
render(contract: TaskContract, context?: Record<string, unknown>): string;
|
|
83
|
+
} | {
|
|
84
|
+
id: string;
|
|
85
|
+
version: string;
|
|
86
|
+
tier: string;
|
|
87
|
+
description: string;
|
|
88
|
+
requiredFields: string[];
|
|
89
|
+
render(contract: TaskContract, context?: Record<string, unknown>): string;
|
|
90
|
+
} | {
|
|
91
|
+
id: string;
|
|
92
|
+
version: string;
|
|
93
|
+
tier: string;
|
|
94
|
+
description: string;
|
|
95
|
+
requiredFields: string[];
|
|
96
|
+
render(contract: TaskContract, context?: Record<string, unknown>): string;
|
|
97
|
+
};
|
|
98
|
+
/**
|
|
99
|
+
* List all available templates.
|
|
100
|
+
*/
|
|
101
|
+
export declare function listTemplates(): {
|
|
102
|
+
id: string;
|
|
103
|
+
version: string;
|
|
104
|
+
tier: string;
|
|
105
|
+
description: string;
|
|
106
|
+
requiredFields: string[];
|
|
107
|
+
}[];
|
|
108
|
+
/**
|
|
109
|
+
* Render a prompt from a template and task contract.
|
|
110
|
+
* Validates contract first. Returns { prompt, template, contract, valid, errors }
|
|
111
|
+
*/
|
|
112
|
+
export declare function renderPrompt(tier: TemplateTier, contract: TaskContract, context?: Record<string, unknown>): {
|
|
113
|
+
prompt: null;
|
|
114
|
+
valid: boolean;
|
|
115
|
+
errors: string[];
|
|
116
|
+
template?: undefined;
|
|
117
|
+
contract?: undefined;
|
|
118
|
+
outputSchema?: undefined;
|
|
119
|
+
stats?: undefined;
|
|
120
|
+
} | {
|
|
121
|
+
prompt: null;
|
|
122
|
+
valid: boolean;
|
|
123
|
+
errors: string[];
|
|
124
|
+
template: {
|
|
125
|
+
id: string;
|
|
126
|
+
version: string;
|
|
127
|
+
};
|
|
128
|
+
contract?: undefined;
|
|
129
|
+
outputSchema?: undefined;
|
|
130
|
+
stats?: undefined;
|
|
131
|
+
} | {
|
|
132
|
+
prompt: string;
|
|
133
|
+
valid: boolean;
|
|
134
|
+
errors: never[];
|
|
135
|
+
template: {
|
|
136
|
+
id: string;
|
|
137
|
+
version: string;
|
|
138
|
+
};
|
|
139
|
+
contract: {
|
|
140
|
+
id: string;
|
|
141
|
+
objective?: string;
|
|
142
|
+
scope?: string[];
|
|
143
|
+
nonGoals?: string[];
|
|
144
|
+
risk?: string;
|
|
145
|
+
acceptanceCriteria?: string[];
|
|
146
|
+
allowedOperations?: string[];
|
|
147
|
+
context?: string;
|
|
148
|
+
files?: string[];
|
|
149
|
+
timeoutMs?: number;
|
|
150
|
+
};
|
|
151
|
+
outputSchema: string | null;
|
|
152
|
+
stats: {
|
|
153
|
+
words: number;
|
|
154
|
+
chars: number;
|
|
155
|
+
estimatedTokens: number;
|
|
156
|
+
};
|
|
157
|
+
};
|
|
158
|
+
/**
|
|
159
|
+
* Quick render: build a contract from minimal inputs and render.
|
|
160
|
+
* For when HEAD knows the tier and objective but hasn't built a full contract.
|
|
161
|
+
*/
|
|
162
|
+
export declare function quickRender(tier: TemplateTier, objective: string, opts?: QuickRenderOpts): {
|
|
163
|
+
prompt: null;
|
|
164
|
+
valid: boolean;
|
|
165
|
+
errors: string[];
|
|
166
|
+
template?: undefined;
|
|
167
|
+
contract?: undefined;
|
|
168
|
+
outputSchema?: undefined;
|
|
169
|
+
stats?: undefined;
|
|
170
|
+
} | {
|
|
171
|
+
prompt: null;
|
|
172
|
+
valid: boolean;
|
|
173
|
+
errors: string[];
|
|
174
|
+
template: {
|
|
175
|
+
id: string;
|
|
176
|
+
version: string;
|
|
177
|
+
};
|
|
178
|
+
contract?: undefined;
|
|
179
|
+
outputSchema?: undefined;
|
|
180
|
+
stats?: undefined;
|
|
181
|
+
} | {
|
|
182
|
+
prompt: string;
|
|
183
|
+
valid: boolean;
|
|
184
|
+
errors: never[];
|
|
185
|
+
template: {
|
|
186
|
+
id: string;
|
|
187
|
+
version: string;
|
|
188
|
+
};
|
|
189
|
+
contract: {
|
|
190
|
+
id: string;
|
|
191
|
+
objective?: string;
|
|
192
|
+
scope?: string[];
|
|
193
|
+
nonGoals?: string[];
|
|
194
|
+
risk?: string;
|
|
195
|
+
acceptanceCriteria?: string[];
|
|
196
|
+
allowedOperations?: string[];
|
|
197
|
+
context?: string;
|
|
198
|
+
files?: string[];
|
|
199
|
+
timeoutMs?: number;
|
|
200
|
+
};
|
|
201
|
+
outputSchema: string | null;
|
|
202
|
+
stats: {
|
|
203
|
+
words: number;
|
|
204
|
+
chars: number;
|
|
205
|
+
estimatedTokens: number;
|
|
206
|
+
};
|
|
207
|
+
};
|
|
208
|
+
export {};
|