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,222 @@
|
|
|
1
|
+
import { existsSync, readFileSync, readdirSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
const PROVIDER_CAPS = {
|
|
4
|
+
claude: {
|
|
5
|
+
name: 'Claude Code',
|
|
6
|
+
cli: 'claude',
|
|
7
|
+
hasNativeCompaction: true,
|
|
8
|
+
compactionStrategy: 'automatic',
|
|
9
|
+
contextFormat: 'markdown-blocks',
|
|
10
|
+
supportsSpecialists: true,
|
|
11
|
+
supportsSituationBrief: true,
|
|
12
|
+
maxContextTokens: 200_000,
|
|
13
|
+
sessionStorage: 'claude-internal',
|
|
14
|
+
authCheck: 'claude --version',
|
|
15
|
+
resumeSupport: 'receipt + handoff',
|
|
16
|
+
},
|
|
17
|
+
openai: {
|
|
18
|
+
name: 'Codex CLI',
|
|
19
|
+
cli: 'codex',
|
|
20
|
+
hasNativeCompaction: false,
|
|
21
|
+
compactionStrategy: 'none',
|
|
22
|
+
contextFormat: 'plain-text',
|
|
23
|
+
supportsSpecialists: false,
|
|
24
|
+
supportsSituationBrief: true,
|
|
25
|
+
maxContextTokens: 128_000,
|
|
26
|
+
sessionStorage: '~/.codex/sessions/YYYY/MM/DD/*.jsonl',
|
|
27
|
+
authCheck: 'codex --version',
|
|
28
|
+
resumeSupport: 'handoff-only',
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
export function getProviderCaps(provider) {
|
|
32
|
+
return PROVIDER_CAPS[provider] || PROVIDER_CAPS.claude;
|
|
33
|
+
}
|
|
34
|
+
// ── Provider-agnostic context injection ─────────────────────────────────────
|
|
35
|
+
/**
|
|
36
|
+
* Build a context block that works for any provider.
|
|
37
|
+
* Adapts format based on provider capabilities.
|
|
38
|
+
*/
|
|
39
|
+
export function buildContextBlock(provider, sections) {
|
|
40
|
+
const caps = getProviderCaps(provider);
|
|
41
|
+
const lines = [];
|
|
42
|
+
if (caps.contextFormat === 'markdown-blocks') {
|
|
43
|
+
for (const [label, content] of Object.entries(sections)) {
|
|
44
|
+
if (!content)
|
|
45
|
+
continue;
|
|
46
|
+
lines.push(`[${label.toUpperCase()}]`);
|
|
47
|
+
lines.push(typeof content === 'string' ? content : JSON.stringify(content));
|
|
48
|
+
lines.push(`[/${label.toUpperCase()}]`);
|
|
49
|
+
lines.push('');
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
for (const [label, content] of Object.entries(sections)) {
|
|
54
|
+
if (!content)
|
|
55
|
+
continue;
|
|
56
|
+
lines.push(`--- ${label} ---`);
|
|
57
|
+
lines.push(typeof content === 'string' ? content : JSON.stringify(content));
|
|
58
|
+
lines.push('');
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return lines.join('\n').trim();
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Build a compaction survival block tuned for the target provider.
|
|
65
|
+
*/
|
|
66
|
+
export function buildSurvivalBlock(provider, state) {
|
|
67
|
+
const caps = getProviderCaps(provider);
|
|
68
|
+
const coreLines = [];
|
|
69
|
+
if (state.activeTask)
|
|
70
|
+
coreLines.push(`TASK: ${state.activeTask}`);
|
|
71
|
+
if (state.provider)
|
|
72
|
+
coreLines.push(`PROVIDER: ${state.provider}/${state.model || 'default'}`);
|
|
73
|
+
if (state.tier)
|
|
74
|
+
coreLines.push(`TIER: ${state.tier}`);
|
|
75
|
+
if (state.risk)
|
|
76
|
+
coreLines.push(`RISK: ${state.risk}`);
|
|
77
|
+
if (state.filesInProgress?.length)
|
|
78
|
+
coreLines.push(`FILES: ${state.filesInProgress.slice(0, 10).join(', ')}`);
|
|
79
|
+
if (state.decisions?.length)
|
|
80
|
+
coreLines.push(`DECISIONS: ${state.decisions.slice(0, 3).join('; ')}`);
|
|
81
|
+
if (state.warnings?.length)
|
|
82
|
+
coreLines.push(`WARNINGS: ${state.warnings.slice(0, 3).join('; ')}`);
|
|
83
|
+
if (state.routingRules?.length)
|
|
84
|
+
coreLines.push(`ROUTING: ${state.routingRules.join('; ')}`);
|
|
85
|
+
if (caps.hasNativeCompaction) {
|
|
86
|
+
return `[DUAL-BRAIN CONTINUITY]\n${coreLines.join('\n')}\n[/DUAL-BRAIN CONTINUITY]`;
|
|
87
|
+
}
|
|
88
|
+
// Codex: compact header block — placed at prompt start for max visibility
|
|
89
|
+
return `## dual-brain state\n${coreLines.join('\n')}\n---`;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Generate a handoff receipt that works for both providers.
|
|
93
|
+
*/
|
|
94
|
+
export function generateProviderHandoff(sessionState, provider) {
|
|
95
|
+
const caps = getProviderCaps(provider);
|
|
96
|
+
return {
|
|
97
|
+
version: 2,
|
|
98
|
+
provider,
|
|
99
|
+
providerCaps: caps.name,
|
|
100
|
+
timestamp: new Date().toISOString(),
|
|
101
|
+
task: sessionState.taskDescription || null,
|
|
102
|
+
progress: {
|
|
103
|
+
filesChanged: (sessionState.filesChanged || []).slice(0, 20),
|
|
104
|
+
testsRun: sessionState.testsRun || [],
|
|
105
|
+
decisions: (sessionState.decisions || []).slice(0, 5),
|
|
106
|
+
},
|
|
107
|
+
unresolved: (sessionState.unresolved || []).slice(0, 5),
|
|
108
|
+
routing: {
|
|
109
|
+
lastProvider: provider,
|
|
110
|
+
lastModel: sessionState.routingHistory?.lastModel || null,
|
|
111
|
+
failedProviders: sessionState.routingHistory?.failedProviders || [],
|
|
112
|
+
},
|
|
113
|
+
resumeHint: sessionState.resumeHint || null,
|
|
114
|
+
resumeStrategy: caps.resumeSupport,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Build a resume brief from the latest handoff, adapted for the resuming provider.
|
|
119
|
+
*/
|
|
120
|
+
export function buildProviderResumeBrief(cwd, targetProvider) {
|
|
121
|
+
const dir = join(cwd || process.cwd(), '.dualbrain', 'handoffs');
|
|
122
|
+
if (!existsSync(dir))
|
|
123
|
+
return null;
|
|
124
|
+
const files = readdirSync(dir)
|
|
125
|
+
.filter(f => f.startsWith('handoff-') && f.endsWith('.json'))
|
|
126
|
+
.sort()
|
|
127
|
+
.reverse();
|
|
128
|
+
if (files.length === 0)
|
|
129
|
+
return null;
|
|
130
|
+
let handoff;
|
|
131
|
+
try {
|
|
132
|
+
handoff = JSON.parse(readFileSync(join(dir, files[0]), 'utf8'));
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
const age = (Date.now() - Date.parse(handoff.timestamp)) / 3600000;
|
|
138
|
+
if (age > 48)
|
|
139
|
+
return null;
|
|
140
|
+
const caps = getProviderCaps(targetProvider);
|
|
141
|
+
const lines = [];
|
|
142
|
+
const ageLabel = age < 1 ? 'just now' : age < 24 ? `${Math.round(age)}h ago` : `${Math.round(age / 24)}d ago`;
|
|
143
|
+
lines.push(`Resuming from previous session (${ageLabel}, ran on ${handoff.provider || 'unknown'}):`);
|
|
144
|
+
if (handoff.task)
|
|
145
|
+
lines.push(` Task: ${handoff.task}`);
|
|
146
|
+
if (handoff.resumeHint)
|
|
147
|
+
lines.push(` Next: ${handoff.resumeHint}`);
|
|
148
|
+
if (handoff.progress?.filesChanged?.length) {
|
|
149
|
+
const shown = handoff.progress.filesChanged.slice(0, caps.hasNativeCompaction ? 5 : 10);
|
|
150
|
+
lines.push(` Changed: ${shown.join(', ')}`);
|
|
151
|
+
}
|
|
152
|
+
if (handoff.unresolved?.length) {
|
|
153
|
+
lines.push(` Unresolved: ${handoff.unresolved.join('; ')}`);
|
|
154
|
+
}
|
|
155
|
+
// Codex gets extra context since it has no native session memory
|
|
156
|
+
if (!caps.hasNativeCompaction && handoff.progress?.decisions?.length) {
|
|
157
|
+
lines.push(` Prior routing: ${handoff.progress.decisions.map(d => `${d.provider}/${d.model}`).join(', ')}`);
|
|
158
|
+
}
|
|
159
|
+
if (handoff.routing?.failedProviders?.length) {
|
|
160
|
+
lines.push(` Note: ${handoff.routing.failedProviders.join(', ')} failed last session`);
|
|
161
|
+
}
|
|
162
|
+
return lines.join('\n');
|
|
163
|
+
}
|
|
164
|
+
// ── Specialist/plugin injection (provider-aware) ────────────────────────────
|
|
165
|
+
/**
|
|
166
|
+
* Build a capability hint block for the target provider.
|
|
167
|
+
*/
|
|
168
|
+
export function buildCapabilityHint(provider, prompt, cwd) {
|
|
169
|
+
if (provider === 'claude') {
|
|
170
|
+
return null; // Handled by dispatch.mjs specialist injection
|
|
171
|
+
}
|
|
172
|
+
// Codex: try to match plugins
|
|
173
|
+
try {
|
|
174
|
+
// Dynamic require for optional dependency
|
|
175
|
+
const { matchPluginsForTask } = require('./replit.mjs');
|
|
176
|
+
const matched = matchPluginsForTask(prompt, undefined, cwd);
|
|
177
|
+
if (matched.length > 0) {
|
|
178
|
+
const names = matched.slice(0, 3).map(m => m.plugin.id).join(', ');
|
|
179
|
+
return `[Available Codex plugins: ${names}. Consider using matching plugins for direct API access.]`;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
catch { /* non-fatal */ }
|
|
183
|
+
return null;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Estimate remaining context budget for a provider.
|
|
187
|
+
*/
|
|
188
|
+
export function estimateContextBudget(provider, usedTokens) {
|
|
189
|
+
const caps = getProviderCaps(provider);
|
|
190
|
+
const remaining = caps.maxContextTokens - usedTokens;
|
|
191
|
+
return {
|
|
192
|
+
provider,
|
|
193
|
+
maxTokens: caps.maxContextTokens,
|
|
194
|
+
usedTokens,
|
|
195
|
+
remainingTokens: Math.max(0, remaining),
|
|
196
|
+
utilizationPct: Math.round((usedTokens / caps.maxContextTokens) * 100),
|
|
197
|
+
compactionRisk: remaining < 20_000 ? 'critical' : remaining < 50_000 ? 'high' : remaining < 100_000 ? 'medium' : 'low',
|
|
198
|
+
hasNativeCompaction: caps.hasNativeCompaction,
|
|
199
|
+
action: caps.hasNativeCompaction
|
|
200
|
+
? (remaining < 20_000 ? 'survival-kit-injected' : 'none')
|
|
201
|
+
: (remaining < 30_000 ? 'manual-handoff-recommended' : 'none'),
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
// ── Cross-provider compatibility helpers ────────────────────────────────────
|
|
205
|
+
/**
|
|
206
|
+
* Get the opposite provider for cross-review.
|
|
207
|
+
*/
|
|
208
|
+
export function getReviewProvider(workProvider, availableProviders) {
|
|
209
|
+
const opposite = workProvider === 'claude' ? 'openai' : 'claude';
|
|
210
|
+
if (availableProviders?.includes(opposite))
|
|
211
|
+
return opposite;
|
|
212
|
+
return workProvider;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Check if both providers are available for true dual-brain operation.
|
|
216
|
+
*/
|
|
217
|
+
export function isDualProviderAvailable(profile) {
|
|
218
|
+
const claude = profile?.providers?.claude?.enabled !== false;
|
|
219
|
+
const openai = !!(profile?.providers?.openai?.enabled && profile?.providers?.openai?.plan);
|
|
220
|
+
return { claude, openai, dual: claude && openai };
|
|
221
|
+
}
|
|
222
|
+
//# sourceMappingURL=provider-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider-context.js","sourceRoot":"","sources":["../../src/provider-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAA4B,WAAW,EAAE,MAAM,SAAS,CAAC;AAC1F,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAmBjC,MAAM,aAAa,GAAyC;IAC1D,MAAM,EAAE;QACN,IAAI,EAAE,aAAa;QACnB,GAAG,EAAE,QAAQ;QACb,mBAAmB,EAAE,IAAI;QACzB,kBAAkB,EAAE,WAAW;QAC/B,aAAa,EAAE,iBAAiB;QAChC,mBAAmB,EAAE,IAAI;QACzB,sBAAsB,EAAE,IAAI;QAC5B,gBAAgB,EAAE,OAAO;QACzB,cAAc,EAAE,iBAAiB;QACjC,SAAS,EAAE,kBAAkB;QAC7B,aAAa,EAAE,mBAAmB;KACnC;IACD,MAAM,EAAE;QACN,IAAI,EAAE,WAAW;QACjB,GAAG,EAAE,OAAO;QACZ,mBAAmB,EAAE,KAAK;QAC1B,kBAAkB,EAAE,MAAM;QAC1B,aAAa,EAAE,YAAY;QAC3B,mBAAmB,EAAE,KAAK;QAC1B,sBAAsB,EAAE,IAAI;QAC5B,gBAAgB,EAAE,OAAO;QACzB,cAAc,EAAE,sCAAsC;QACtD,SAAS,EAAE,iBAAiB;QAC5B,aAAa,EAAE,cAAc;KAC9B;CACF,CAAC;AAEF,MAAM,UAAU,eAAe,CAAC,QAAgB;IAC9C,OAAO,aAAa,CAAC,QAAQ,CAAC,IAAI,aAAa,CAAC,MAAM,CAAC;AACzD,CAAC;AAED,+EAA+E;AAE/E;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAAgB,EAAE,QAA4D;IAC9G,MAAM,IAAI,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IACvC,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,IAAI,IAAI,CAAC,aAAa,KAAK,iBAAiB,EAAE,CAAC;QAC7C,KAAK,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YACxD,IAAI,CAAC,OAAO;gBAAE,SAAS;YACvB,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;YACvC,KAAK,CAAC,IAAI,CAAC,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;YAC5E,KAAK,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;YACxC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjB,CAAC;IACH,CAAC;SAAM,CAAC;QACN,KAAK,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YACxD,IAAI,CAAC,OAAO;gBAAE,SAAS;YACvB,KAAK,CAAC,IAAI,CAAC,OAAO,KAAK,MAAM,CAAC,CAAC;YAC/B,KAAK,CAAC,IAAI,CAAC,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;YAC5E,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjB,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;AACjC,CAAC;AAgBD;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,QAAgB,EAAE,KAAoB;IACvE,MAAM,IAAI,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IAEvC,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,IAAI,KAAK,CAAC,UAAU;QAAE,SAAS,CAAC,IAAI,CAAC,SAAS,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC;IAClE,IAAI,KAAK,CAAC,QAAQ;QAAE,SAAS,CAAC,IAAI,CAAC,aAAa,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,KAAK,IAAI,SAAS,EAAE,CAAC,CAAC;IAC9F,IAAI,KAAK,CAAC,IAAI;QAAE,SAAS,CAAC,IAAI,CAAC,SAAS,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IACtD,IAAI,KAAK,CAAC,IAAI;QAAE,SAAS,CAAC,IAAI,CAAC,SAAS,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IACtD,IAAI,KAAK,CAAC,eAAe,EAAE,MAAM;QAAE,SAAS,CAAC,IAAI,CAAC,UAAU,KAAK,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC7G,IAAI,KAAK,CAAC,SAAS,EAAE,MAAM;QAAE,SAAS,CAAC,IAAI,CAAC,cAAc,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACpG,IAAI,KAAK,CAAC,QAAQ,EAAE,MAAM;QAAE,SAAS,CAAC,IAAI,CAAC,aAAa,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjG,IAAI,KAAK,CAAC,YAAY,EAAE,MAAM;QAAE,SAAS,CAAC,IAAI,CAAC,YAAY,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAE5F,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC7B,OAAO,4BAA4B,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,4BAA4B,CAAC;IACtF,CAAC;IAED,0EAA0E;IAC1E,OAAO,wBAAwB,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;AAC7D,CAAC;AAuCD;;GAEG;AACH,MAAM,UAAU,uBAAuB,CAAC,YAA0B,EAAE,QAAgB;IAClF,MAAM,IAAI,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IAEvC,OAAO;QACL,OAAO,EAAE,CAAC;QACV,QAAQ;QACR,YAAY,EAAE,IAAI,CAAC,IAAI;QACvB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,IAAI,EAAE,YAAY,CAAC,eAAe,IAAI,IAAI;QAC1C,QAAQ,EAAE;YACR,YAAY,EAAE,CAAC,YAAY,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;YAC5D,QAAQ,EAAE,YAAY,CAAC,QAAQ,IAAI,EAAE;YACrC,SAAS,EAAE,CAAC,YAAY,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;SACtD;QACD,UAAU,EAAE,CAAC,YAAY,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;QACvD,OAAO,EAAE;YACP,YAAY,EAAE,QAAQ;YACtB,SAAS,EAAE,YAAY,CAAC,cAAc,EAAE,SAAS,IAAI,IAAI;YACzD,eAAe,EAAE,YAAY,CAAC,cAAc,EAAE,eAAe,IAAI,EAAE;SACpE;QACD,UAAU,EAAE,YAAY,CAAC,UAAU,IAAI,IAAI;QAC3C,cAAc,EAAE,IAAI,CAAC,aAAa;KACnC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,wBAAwB,CAAC,GAAuB,EAAE,cAAsB;IACtF,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,EAAE,YAAY,EAAE,UAAU,CAAC,CAAC;IACjE,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAElC,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC;SAC3B,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;SAC5D,IAAI,EAAE;SACN,OAAO,EAAE,CAAC;IACb,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEpC,IAAI,OAAwB,CAAC;IAC7B,IAAI,CAAC;QACH,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;IAClE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,GAAG,OAAO,CAAC;IACnE,IAAI,GAAG,GAAG,EAAE;QAAE,OAAO,IAAI,CAAC;IAE1B,MAAM,IAAI,GAAG,eAAe,CAAC,cAAc,CAAC,CAAC;IAC7C,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,MAAM,QAAQ,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC;IAC9G,KAAK,CAAC,IAAI,CAAC,mCAAmC,QAAQ,YAAY,OAAO,CAAC,QAAQ,IAAI,SAAS,IAAI,CAAC,CAAC;IAErG,IAAI,OAAO,CAAC,IAAI;QAAE,KAAK,CAAC,IAAI,CAAC,WAAW,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IACxD,IAAI,OAAO,CAAC,UAAU;QAAE,KAAK,CAAC,IAAI,CAAC,WAAW,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IAEpE,IAAI,OAAO,CAAC,QAAQ,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC;QAC3C,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACxF,KAAK,CAAC,IAAI,CAAC,cAAc,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED,IAAI,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,CAAC;QAC/B,KAAK,CAAC,IAAI,CAAC,iBAAiB,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC/D,CAAC;IAED,iEAAiE;IACjE,IAAI,CAAC,IAAI,CAAC,mBAAmB,IAAI,OAAO,CAAC,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;QACrE,KAAK,CAAC,IAAI,CAAC,oBAAoB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC/G,CAAC;IAED,IAAI,OAAO,CAAC,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,CAAC;QAC7C,KAAK,CAAC,IAAI,CAAC,WAAW,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;IAC1F,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,+EAA+E;AAE/E;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,QAAgB,EAAE,MAAc,EAAE,GAAY;IAChF,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC,CAAC,+CAA+C;IAC9D,CAAC;IAED,8BAA8B;IAC9B,IAAI,CAAC;QACH,0CAA0C;QAC1C,MAAM,EAAE,mBAAmB,EAAE,GAAG,OAAO,CAAC,cAAc,CAAkH,CAAC;QACzK,MAAM,OAAO,GAAG,mBAAmB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC;QAC5D,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnE,OAAO,6BAA6B,KAAK,2DAA2D,CAAC;QACvG,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC;IAE3B,OAAO,IAAI,CAAC;AACd,CAAC;AAeD;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,QAAgB,EAAE,UAAkB;IACxE,MAAM,IAAI,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IACvC,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,GAAG,UAAU,CAAC;IAErD,OAAO;QACL,QAAQ;QACR,SAAS,EAAE,IAAI,CAAC,gBAAgB;QAChC,UAAU;QACV,eAAe,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,CAAC;QACvC,cAAc,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,UAAU,GAAG,IAAI,CAAC,gBAAgB,CAAC,GAAG,GAAG,CAAC;QACtE,cAAc,EAAE,SAAS,GAAG,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,GAAG,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK;QACtH,mBAAmB,EAAE,IAAI,CAAC,mBAAmB;QAC7C,MAAM,EAAE,IAAI,CAAC,mBAAmB;YAC9B,CAAC,CAAC,CAAC,SAAS,GAAG,MAAM,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,MAAM,CAAC;YACzD,CAAC,CAAC,CAAC,SAAS,GAAG,MAAM,CAAC,CAAC,CAAC,4BAA4B,CAAC,CAAC,CAAC,MAAM,CAAC;KACjE,CAAC;AACJ,CAAC;AAED,+EAA+E;AAE/E;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,YAAoB,EAAE,kBAA6B;IACnF,MAAM,QAAQ,GAAG,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC;IACjE,IAAI,kBAAkB,EAAE,QAAQ,CAAC,QAAQ,CAAC;QAAE,OAAO,QAAQ,CAAC;IAC5D,OAAO,YAAY,CAAC;AACtB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,uBAAuB,CAAC,OAA6H;IACnK,MAAM,MAAM,GAAG,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,KAAK,KAAK,CAAC;IAC7D,MAAM,MAAM,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,IAAI,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;IAC3F,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,IAAI,MAAM,EAAE,CAAC;AACpD,CAAC"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* provider-manager.ts — Provider health, failover, and rate-limit management
|
|
3
|
+
*
|
|
4
|
+
* The "invisible failover" layer: when Claude is rate-limited, work seamlessly
|
|
5
|
+
* continues on GPT. When GPT is down, Claude handles everything.
|
|
6
|
+
*
|
|
7
|
+
* State storage:
|
|
8
|
+
* - Provider states: .dual-brain/providers/{provider}.json (atomic writes)
|
|
9
|
+
* - Global dispatch log: .dual-brain/dispatch-log.ndjson (append-only)
|
|
10
|
+
*/
|
|
11
|
+
/** Maximum dispatches allowed per rolling window (default: 30 per 5 min). */
|
|
12
|
+
export declare const MAX_DISPATCHES_PER_WINDOW = 30;
|
|
13
|
+
/** Default rolling window in minutes. */
|
|
14
|
+
export declare const DEFAULT_WINDOW_MINUTES = 5;
|
|
15
|
+
export interface ProviderState {
|
|
16
|
+
provider: 'anthropic' | 'openai';
|
|
17
|
+
status: 'healthy' | 'degraded' | 'rate-limited' | 'down';
|
|
18
|
+
lastCheck: string;
|
|
19
|
+
lastSuccess: string;
|
|
20
|
+
lastFailure?: string;
|
|
21
|
+
cooldownUntil?: string;
|
|
22
|
+
remainingCapacity: number;
|
|
23
|
+
recentDispatches: number;
|
|
24
|
+
consecutiveFailures: number;
|
|
25
|
+
}
|
|
26
|
+
export interface FailoverResult {
|
|
27
|
+
provider: string;
|
|
28
|
+
model: string;
|
|
29
|
+
reason: string;
|
|
30
|
+
wasFailover: boolean;
|
|
31
|
+
}
|
|
32
|
+
export interface DispatchPermission {
|
|
33
|
+
allowed: boolean;
|
|
34
|
+
reason: string;
|
|
35
|
+
suggestedDelay?: number;
|
|
36
|
+
alternativeProvider?: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Get the current health state for a provider.
|
|
40
|
+
*/
|
|
41
|
+
export declare function getProviderState(provider: string, cwd?: string): ProviderState;
|
|
42
|
+
/**
|
|
43
|
+
* Get health states for all known providers.
|
|
44
|
+
*/
|
|
45
|
+
export declare function getAllProviderStates(cwd?: string): ProviderState[];
|
|
46
|
+
/**
|
|
47
|
+
* Record a successful dispatch to a provider.
|
|
48
|
+
*/
|
|
49
|
+
export declare function recordSuccess(provider: string, model: string, cwd?: string): void;
|
|
50
|
+
/**
|
|
51
|
+
* Record a dispatch failure. Detects rate limits automatically.
|
|
52
|
+
*/
|
|
53
|
+
export declare function recordFailure(provider: string, model: string, error: string, cwd?: string): void;
|
|
54
|
+
/**
|
|
55
|
+
* Explicitly record a rate limit event.
|
|
56
|
+
*/
|
|
57
|
+
export declare function recordRateLimit(provider: string, resetTime?: string, cwd?: string): void;
|
|
58
|
+
/**
|
|
59
|
+
* Check whether dispatching to a provider is allowed right now.
|
|
60
|
+
*/
|
|
61
|
+
export declare function canDispatch(provider: string, cwd?: string): DispatchPermission;
|
|
62
|
+
/**
|
|
63
|
+
* If the preferred provider cannot handle work right now, find the best alternative.
|
|
64
|
+
*/
|
|
65
|
+
export declare function getFailoverTarget(preferredProvider: string, preferredModel: string, cwd?: string): FailoverResult;
|
|
66
|
+
/**
|
|
67
|
+
* Choose the best provider right now based on health + task tier.
|
|
68
|
+
*/
|
|
69
|
+
export declare function selectProvider(taskTier: number, preferredProvider?: string, cwd?: string): FailoverResult;
|
|
70
|
+
/**
|
|
71
|
+
* Get the total number of dispatches across all providers in the given window.
|
|
72
|
+
*/
|
|
73
|
+
export declare function getGlobalDispatchCount(windowMinutes?: number, cwd?: string): number;
|
|
74
|
+
/**
|
|
75
|
+
* Append a dispatch attempt to the global log (file-based, shared across processes).
|
|
76
|
+
*/
|
|
77
|
+
export declare function recordDispatchAttempt(provider: string, model: string, taskId: string, cwd?: string): void;
|
|
78
|
+
/**
|
|
79
|
+
* Check whether dispatch rate is within budget.
|
|
80
|
+
*/
|
|
81
|
+
export declare function isWithinBudget(maxPerWindow?: number, windowMinutes?: number, cwd?: string): boolean;
|
|
82
|
+
/**
|
|
83
|
+
* Parse an error message for rate limit signals.
|
|
84
|
+
*/
|
|
85
|
+
export declare function detectRateLimit(error: string): {
|
|
86
|
+
isRateLimit: boolean;
|
|
87
|
+
resetTime?: string;
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* One-line health status string for TUI display.
|
|
91
|
+
*/
|
|
92
|
+
export declare function getHealthSummary(cwd?: string): string;
|