@oeronteros-1/opencode-orchestra 0.5.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/LICENSE +21 -0
- package/README.md +207 -0
- package/dashboard-dist/assets/index-89Gs8jun.css +2 -0
- package/dashboard-dist/assets/index-Bhe8OPZD.js +124 -0
- package/dashboard-dist/index.html +14 -0
- package/dist/agents/build.d.ts +7 -0
- package/dist/agents/build.js +16 -0
- package/dist/agents/build.js.map +1 -0
- package/dist/agents/judge.d.ts +3 -0
- package/dist/agents/judge.js +29 -0
- package/dist/agents/judge.js.map +1 -0
- package/dist/agents/lead.d.ts +3 -0
- package/dist/agents/lead.js +54 -0
- package/dist/agents/lead.js.map +1 -0
- package/dist/agents/types.d.ts +14 -0
- package/dist/agents/types.js +2 -0
- package/dist/agents/types.js.map +1 -0
- package/dist/agents/workers.d.ts +3 -0
- package/dist/agents/workers.js +114 -0
- package/dist/agents/workers.js.map +1 -0
- package/dist/cli.d.ts +24 -0
- package/dist/cli.js +418 -0
- package/dist/cli.js.map +1 -0
- package/dist/config/defaults.d.ts +4 -0
- package/dist/config/defaults.js +26 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/load.d.ts +6 -0
- package/dist/config/load.js +58 -0
- package/dist/config/load.js.map +1 -0
- package/dist/config/paths.d.ts +2 -0
- package/dist/config/paths.js +13 -0
- package/dist/config/paths.js.map +1 -0
- package/dist/config/schema.d.ts +341 -0
- package/dist/config/schema.js +103 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/dashboard/server.d.ts +12 -0
- package/dist/dashboard/server.js +297 -0
- package/dist/dashboard/server.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +85 -0
- package/dist/index.js.map +1 -0
- package/dist/profiles/architecture.d.ts +2 -0
- package/dist/profiles/architecture.js +13 -0
- package/dist/profiles/architecture.js.map +1 -0
- package/dist/profiles/catalog.d.ts +2 -0
- package/dist/profiles/catalog.js +39 -0
- package/dist/profiles/catalog.js.map +1 -0
- package/dist/profiles/debug.d.ts +2 -0
- package/dist/profiles/debug.js +14 -0
- package/dist/profiles/debug.js.map +1 -0
- package/dist/profiles/performance.d.ts +2 -0
- package/dist/profiles/performance.js +13 -0
- package/dist/profiles/performance.js.map +1 -0
- package/dist/profiles/research.d.ts +2 -0
- package/dist/profiles/research.js +13 -0
- package/dist/profiles/research.js.map +1 -0
- package/dist/profiles/security.d.ts +2 -0
- package/dist/profiles/security.js +13 -0
- package/dist/profiles/security.js.map +1 -0
- package/dist/profiles/types.d.ts +9 -0
- package/dist/profiles/types.js +2 -0
- package/dist/profiles/types.js.map +1 -0
- package/dist/profiles/ui.d.ts +2 -0
- package/dist/profiles/ui.js +13 -0
- package/dist/profiles/ui.js.map +1 -0
- package/dist/prompts/load.d.ts +4 -0
- package/dist/prompts/load.js +26 -0
- package/dist/prompts/load.js.map +1 -0
- package/dist/routing/budget.d.ts +11 -0
- package/dist/routing/budget.js +45 -0
- package/dist/routing/budget.js.map +1 -0
- package/dist/routing/classifier.d.ts +10 -0
- package/dist/routing/classifier.js +160 -0
- package/dist/routing/classifier.js.map +1 -0
- package/dist/routing/escalation.d.ts +12 -0
- package/dist/routing/escalation.js +30 -0
- package/dist/routing/escalation.js.map +1 -0
- package/dist/routing/model-discovery.d.ts +3 -0
- package/dist/routing/model-discovery.js +96 -0
- package/dist/routing/model-discovery.js.map +1 -0
- package/dist/routing/model-resolver.d.ts +26 -0
- package/dist/routing/model-resolver.js +66 -0
- package/dist/routing/model-resolver.js.map +1 -0
- package/dist/superpowers/compatibility.d.ts +2 -0
- package/dist/superpowers/compatibility.js +9 -0
- package/dist/superpowers/compatibility.js.map +1 -0
- package/dist/telemetry/ledger.d.ts +68 -0
- package/dist/telemetry/ledger.js +179 -0
- package/dist/telemetry/ledger.js.map +1 -0
- package/dist/tools.d.ts +4 -0
- package/dist/tools.js +57 -0
- package/dist/tools.js.map +1 -0
- package/package.json +79 -0
- package/prompts/judge.md +13 -0
- package/prompts/lead.md +24 -0
- package/schema/opencode-orchestra.schema.json +112 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
const FALLBACK_LEAD = `You are orch-lead, an evidence-driven orchestration subagent.
|
|
3
|
+
Classify the task by intellectual work profile, dispatch the smallest useful specialist team, and synthesize their evidence.
|
|
4
|
+
Do not edit files. Do not replace the primary agent's plan or development methodology. Never invoke yourself.
|
|
5
|
+
Use workers for independent evidence, not ceremonial duplication. Escalate to orch-judge only for critical risk or unresolved disagreement.
|
|
6
|
+
Return a compact handoff: profile, evidence, consensus, uncertainties, recommendation, and verification.`;
|
|
7
|
+
const FALLBACK_JUDGE = `You are orch-judge, a costly independent arbiter.
|
|
8
|
+
You receive conflicting worker findings. Inspect only the evidence needed to resolve the disagreement.
|
|
9
|
+
Do not delegate and do not edit. State which claims are supported, which are rejected, remaining uncertainty, and the safest recommendation.`;
|
|
10
|
+
async function readPrompt(relativePath, fallback) {
|
|
11
|
+
const url = new URL(`../../prompts/${relativePath}`, import.meta.url);
|
|
12
|
+
try {
|
|
13
|
+
return await readFile(url, "utf8");
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return fallback;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export async function loadPrompts() {
|
|
20
|
+
const [lead, judge] = await Promise.all([
|
|
21
|
+
readPrompt("lead.md", FALLBACK_LEAD),
|
|
22
|
+
readPrompt("judge.md", FALLBACK_JUDGE),
|
|
23
|
+
]);
|
|
24
|
+
return { lead, judge };
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=load.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load.js","sourceRoot":"","sources":["../../src/prompts/load.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAE3C,MAAM,aAAa,GAAG;;;;yGAImF,CAAA;AAEzG,MAAM,cAAc,GAAG;;6IAEsH,CAAA;AAE7I,KAAK,UAAU,UAAU,CAAC,YAAoB,EAAE,QAAgB;IAC9D,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,iBAAiB,YAAY,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IACrE,IAAI,CAAC;QACH,OAAO,MAAM,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;IACpC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,QAAQ,CAAA;IACjB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACtC,UAAU,CAAC,SAAS,EAAE,aAAa,CAAC;QACpC,UAAU,CAAC,UAAU,EAAE,cAAc,CAAC;KACvC,CAAC,CAAA;IACF,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAA;AACxB,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { BudgetMode, ModelCost } from "../config/schema.js";
|
|
2
|
+
export interface BudgetPolicy {
|
|
3
|
+
mode: BudgetMode;
|
|
4
|
+
freeBonus: number;
|
|
5
|
+
subscriptionBonus: number;
|
|
6
|
+
paidPenalty: number;
|
|
7
|
+
defaultWorkerCount: number;
|
|
8
|
+
judgePolicy: "rare" | "disagreement" | "always-for-critical";
|
|
9
|
+
}
|
|
10
|
+
export declare function getBudgetPolicy(mode: BudgetMode): BudgetPolicy;
|
|
11
|
+
export declare function costAdjustment(cost: ModelCost, policy: BudgetPolicy): number;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
const POLICIES = {
|
|
2
|
+
eco: {
|
|
3
|
+
mode: "eco",
|
|
4
|
+
freeBonus: 80,
|
|
5
|
+
subscriptionBonus: 20,
|
|
6
|
+
paidPenalty: 200,
|
|
7
|
+
defaultWorkerCount: 2,
|
|
8
|
+
judgePolicy: "rare",
|
|
9
|
+
},
|
|
10
|
+
balanced: {
|
|
11
|
+
mode: "balanced",
|
|
12
|
+
freeBonus: 50,
|
|
13
|
+
subscriptionBonus: 35,
|
|
14
|
+
paidPenalty: 35,
|
|
15
|
+
defaultWorkerCount: 3,
|
|
16
|
+
judgePolicy: "disagreement",
|
|
17
|
+
},
|
|
18
|
+
quality: {
|
|
19
|
+
mode: "quality",
|
|
20
|
+
freeBonus: 15,
|
|
21
|
+
subscriptionBonus: 25,
|
|
22
|
+
paidPenalty: 5,
|
|
23
|
+
defaultWorkerCount: 4,
|
|
24
|
+
judgePolicy: "always-for-critical",
|
|
25
|
+
},
|
|
26
|
+
ebobo: {
|
|
27
|
+
mode: "ebobo",
|
|
28
|
+
freeBonus: 0,
|
|
29
|
+
subscriptionBonus: 5,
|
|
30
|
+
paidPenalty: 0,
|
|
31
|
+
defaultWorkerCount: 12,
|
|
32
|
+
judgePolicy: "always-for-critical",
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
export function getBudgetPolicy(mode) {
|
|
36
|
+
return POLICIES[mode];
|
|
37
|
+
}
|
|
38
|
+
export function costAdjustment(cost, policy) {
|
|
39
|
+
if (cost === "free")
|
|
40
|
+
return policy.freeBonus;
|
|
41
|
+
if (cost === "subscription")
|
|
42
|
+
return policy.subscriptionBonus;
|
|
43
|
+
return -policy.paidPenalty;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=budget.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"budget.js","sourceRoot":"","sources":["../../src/routing/budget.ts"],"names":[],"mappings":"AAWA,MAAM,QAAQ,GAAqC;IACjD,GAAG,EAAE;QACH,IAAI,EAAE,KAAK;QACX,SAAS,EAAE,EAAE;QACb,iBAAiB,EAAE,EAAE;QACrB,WAAW,EAAE,GAAG;QAChB,kBAAkB,EAAE,CAAC;QACrB,WAAW,EAAE,MAAM;KACpB;IACD,QAAQ,EAAE;QACR,IAAI,EAAE,UAAU;QAChB,SAAS,EAAE,EAAE;QACb,iBAAiB,EAAE,EAAE;QACrB,WAAW,EAAE,EAAE;QACf,kBAAkB,EAAE,CAAC;QACrB,WAAW,EAAE,cAAc;KAC5B;IACD,OAAO,EAAE;QACP,IAAI,EAAE,SAAS;QACf,SAAS,EAAE,EAAE;QACb,iBAAiB,EAAE,EAAE;QACrB,WAAW,EAAE,CAAC;QACd,kBAAkB,EAAE,CAAC;QACrB,WAAW,EAAE,qBAAqB;KACnC;IACD,KAAK,EAAE;QACL,IAAI,EAAE,OAAO;QACb,SAAS,EAAE,CAAC;QACZ,iBAAiB,EAAE,CAAC;QACpB,WAAW,EAAE,CAAC;QACd,kBAAkB,EAAE,EAAE;QACtB,WAAW,EAAE,qBAAqB;KACnC;CACF,CAAA;AAED,MAAM,UAAU,eAAe,CAAC,IAAgB;IAC9C,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAA;AACvB,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAe,EAAE,MAAoB;IAClE,IAAI,IAAI,KAAK,MAAM;QAAE,OAAO,MAAM,CAAC,SAAS,CAAA;IAC5C,IAAI,IAAI,KAAK,cAAc;QAAE,OAAO,MAAM,CAAC,iBAAiB,CAAA;IAC5D,OAAO,CAAC,MAAM,CAAC,WAAW,CAAA;AAC5B,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ProfileName } from "../config/schema.js";
|
|
2
|
+
export interface Classification {
|
|
3
|
+
profile: ProfileName;
|
|
4
|
+
secondaryProfiles: ProfileName[];
|
|
5
|
+
confidence: number;
|
|
6
|
+
matchedSignals: string[];
|
|
7
|
+
securityRelevant: boolean;
|
|
8
|
+
critical: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare function classifyTask(task: string, enabledProfiles?: Partial<Record<ProfileName, boolean>>): Classification;
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
const SIGNALS = {
|
|
2
|
+
architecture: [
|
|
3
|
+
"architecture",
|
|
4
|
+
"architect",
|
|
5
|
+
"design",
|
|
6
|
+
"module",
|
|
7
|
+
"boundary",
|
|
8
|
+
"api",
|
|
9
|
+
"database",
|
|
10
|
+
"billing",
|
|
11
|
+
"integration",
|
|
12
|
+
"архитект",
|
|
13
|
+
"спроект",
|
|
14
|
+
"модул",
|
|
15
|
+
"интеграц",
|
|
16
|
+
],
|
|
17
|
+
debug: [
|
|
18
|
+
"bug",
|
|
19
|
+
"debug",
|
|
20
|
+
"error",
|
|
21
|
+
"exception",
|
|
22
|
+
"fails",
|
|
23
|
+
"broken",
|
|
24
|
+
"502",
|
|
25
|
+
"crash",
|
|
26
|
+
"race condition",
|
|
27
|
+
"ошиб",
|
|
28
|
+
"падает",
|
|
29
|
+
"не работает",
|
|
30
|
+
"разлогин",
|
|
31
|
+
],
|
|
32
|
+
ui: [
|
|
33
|
+
"ui",
|
|
34
|
+
"ux",
|
|
35
|
+
"layout",
|
|
36
|
+
"dashboard",
|
|
37
|
+
"responsive",
|
|
38
|
+
"component",
|
|
39
|
+
"visual",
|
|
40
|
+
"animation",
|
|
41
|
+
"интерфейс",
|
|
42
|
+
"дизайн",
|
|
43
|
+
"визуал",
|
|
44
|
+
"адаптив",
|
|
45
|
+
],
|
|
46
|
+
research: [
|
|
47
|
+
"research",
|
|
48
|
+
"compare",
|
|
49
|
+
"investigate",
|
|
50
|
+
"find examples",
|
|
51
|
+
"documentation",
|
|
52
|
+
"изучи",
|
|
53
|
+
"исслед",
|
|
54
|
+
"сравни",
|
|
55
|
+
"найди примеры",
|
|
56
|
+
"документац",
|
|
57
|
+
],
|
|
58
|
+
review: [
|
|
59
|
+
"review",
|
|
60
|
+
"audit code",
|
|
61
|
+
"pull request",
|
|
62
|
+
"diff",
|
|
63
|
+
"code quality",
|
|
64
|
+
"ревью",
|
|
65
|
+
"проверь код",
|
|
66
|
+
"оцени изменения",
|
|
67
|
+
],
|
|
68
|
+
security: [
|
|
69
|
+
"security",
|
|
70
|
+
"vulnerability",
|
|
71
|
+
"auth",
|
|
72
|
+
"oauth",
|
|
73
|
+
"token",
|
|
74
|
+
"cookie",
|
|
75
|
+
"xss",
|
|
76
|
+
"injection",
|
|
77
|
+
"permission",
|
|
78
|
+
"безопас",
|
|
79
|
+
"уязвим",
|
|
80
|
+
"авторизац",
|
|
81
|
+
],
|
|
82
|
+
performance: [
|
|
83
|
+
"performance",
|
|
84
|
+
"latency",
|
|
85
|
+
"slow",
|
|
86
|
+
"memory",
|
|
87
|
+
"cpu",
|
|
88
|
+
"throughput",
|
|
89
|
+
"optimize",
|
|
90
|
+
"производитель",
|
|
91
|
+
"медлен",
|
|
92
|
+
"оптимиз",
|
|
93
|
+
],
|
|
94
|
+
migration: [
|
|
95
|
+
"migration",
|
|
96
|
+
"migrate",
|
|
97
|
+
"upgrade",
|
|
98
|
+
"port to",
|
|
99
|
+
"rewrite",
|
|
100
|
+
"миграц",
|
|
101
|
+
"перенести",
|
|
102
|
+
"обновить версию",
|
|
103
|
+
],
|
|
104
|
+
ops: [
|
|
105
|
+
"deploy",
|
|
106
|
+
"docker",
|
|
107
|
+
"kubernetes",
|
|
108
|
+
"ci/cd",
|
|
109
|
+
"pipeline",
|
|
110
|
+
"infrastructure",
|
|
111
|
+
"production",
|
|
112
|
+
"деплой",
|
|
113
|
+
"инфраструктур",
|
|
114
|
+
"докер",
|
|
115
|
+
],
|
|
116
|
+
};
|
|
117
|
+
const CRITICAL_SIGNALS = [
|
|
118
|
+
"production",
|
|
119
|
+
"payment",
|
|
120
|
+
"billing",
|
|
121
|
+
"data loss",
|
|
122
|
+
"breach",
|
|
123
|
+
"security incident",
|
|
124
|
+
"продакш",
|
|
125
|
+
"платеж",
|
|
126
|
+
"потеря данных",
|
|
127
|
+
"утечка",
|
|
128
|
+
];
|
|
129
|
+
const INTERMITTENT_SIGNALS = ["intermittent", "occasionally", "sometimes", "randomly", "иногда", "периодически", "случайно"];
|
|
130
|
+
export function classifyTask(task, enabledProfiles) {
|
|
131
|
+
const normalized = task.toLowerCase();
|
|
132
|
+
const ranked = Object.entries(SIGNALS)
|
|
133
|
+
.filter(([profile]) => enabledProfiles?.[profile] !== false)
|
|
134
|
+
.map(([profile, signals]) => {
|
|
135
|
+
const matched = signals.filter((signal) => normalized.includes(signal));
|
|
136
|
+
const intermittentDebugBonus = profile === "debug" && matched.length > 0 && INTERMITTENT_SIGNALS.some((signal) => normalized.includes(signal))
|
|
137
|
+
? 2
|
|
138
|
+
: 0;
|
|
139
|
+
return { profile, matched, score: matched.length + intermittentDebugBonus };
|
|
140
|
+
})
|
|
141
|
+
.sort((a, b) => b.score - a.score);
|
|
142
|
+
const winner = ranked[0];
|
|
143
|
+
const profile = winner && winner.score > 0 ? winner.profile : "architecture";
|
|
144
|
+
const secondaryProfiles = ranked
|
|
145
|
+
.filter((item) => item.profile !== profile && item.score > 0)
|
|
146
|
+
.slice(0, 2)
|
|
147
|
+
.map((item) => item.profile);
|
|
148
|
+
const topScore = winner?.score ?? 0;
|
|
149
|
+
const runnerUp = ranked[1]?.score ?? 0;
|
|
150
|
+
const confidence = topScore === 0 ? 0.45 : Math.min(0.95, 0.58 + topScore * 0.1 - runnerUp * 0.03);
|
|
151
|
+
return {
|
|
152
|
+
profile,
|
|
153
|
+
secondaryProfiles,
|
|
154
|
+
confidence: Number(confidence.toFixed(2)),
|
|
155
|
+
matchedSignals: winner?.matched ?? [],
|
|
156
|
+
securityRelevant: profile === "security" || ranked.some((item) => item.profile === "security" && item.score > 0),
|
|
157
|
+
critical: CRITICAL_SIGNALS.some((signal) => normalized.includes(signal)),
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=classifier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"classifier.js","sourceRoot":"","sources":["../../src/routing/classifier.ts"],"names":[],"mappings":"AAWA,MAAM,OAAO,GAAkC;IAC7C,YAAY,EAAE;QACZ,cAAc;QACd,WAAW;QACX,QAAQ;QACR,QAAQ;QACR,UAAU;QACV,KAAK;QACL,UAAU;QACV,SAAS;QACT,aAAa;QACb,UAAU;QACV,SAAS;QACT,OAAO;QACP,UAAU;KACX;IACD,KAAK,EAAE;QACL,KAAK;QACL,OAAO;QACP,OAAO;QACP,WAAW;QACX,OAAO;QACP,QAAQ;QACR,KAAK;QACL,OAAO;QACP,gBAAgB;QAChB,MAAM;QACN,QAAQ;QACR,aAAa;QACb,UAAU;KACX;IACD,EAAE,EAAE;QACF,IAAI;QACJ,IAAI;QACJ,QAAQ;QACR,WAAW;QACX,YAAY;QACZ,WAAW;QACX,QAAQ;QACR,WAAW;QACX,WAAW;QACX,QAAQ;QACR,QAAQ;QACR,SAAS;KACV;IACD,QAAQ,EAAE;QACR,UAAU;QACV,SAAS;QACT,aAAa;QACb,eAAe;QACf,eAAe;QACf,OAAO;QACP,QAAQ;QACR,QAAQ;QACR,eAAe;QACf,YAAY;KACb;IACD,MAAM,EAAE;QACN,QAAQ;QACR,YAAY;QACZ,cAAc;QACd,MAAM;QACN,cAAc;QACd,OAAO;QACP,aAAa;QACb,iBAAiB;KAClB;IACD,QAAQ,EAAE;QACR,UAAU;QACV,eAAe;QACf,MAAM;QACN,OAAO;QACP,OAAO;QACP,QAAQ;QACR,KAAK;QACL,WAAW;QACX,YAAY;QACZ,SAAS;QACT,QAAQ;QACR,WAAW;KACZ;IACD,WAAW,EAAE;QACX,aAAa;QACb,SAAS;QACT,MAAM;QACN,QAAQ;QACR,KAAK;QACL,YAAY;QACZ,UAAU;QACV,eAAe;QACf,QAAQ;QACR,SAAS;KACV;IACD,SAAS,EAAE;QACT,WAAW;QACX,SAAS;QACT,SAAS;QACT,SAAS;QACT,SAAS;QACT,QAAQ;QACR,WAAW;QACX,iBAAiB;KAClB;IACD,GAAG,EAAE;QACH,QAAQ;QACR,QAAQ;QACR,YAAY;QACZ,OAAO;QACP,UAAU;QACV,gBAAgB;QAChB,YAAY;QACZ,QAAQ;QACR,eAAe;QACf,OAAO;KACR;CACF,CAAA;AAED,MAAM,gBAAgB,GAAG;IACvB,YAAY;IACZ,SAAS;IACT,SAAS;IACT,WAAW;IACX,QAAQ;IACR,mBAAmB;IACnB,SAAS;IACT,QAAQ;IACR,eAAe;IACf,QAAQ;CACT,CAAA;AAED,MAAM,oBAAoB,GAAG,CAAC,cAAc,EAAE,cAAc,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,EAAE,cAAc,EAAE,UAAU,CAAC,CAAA;AAE5H,MAAM,UAAU,YAAY,CAC1B,IAAY,EACZ,eAAuD;IAEvD,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,EAAE,CAAA;IACrC,MAAM,MAAM,GAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAoC;SACvE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,eAAe,EAAE,CAAC,OAAO,CAAC,KAAK,KAAK,CAAC;SAC3D,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,EAAE;QAC1B,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAA;QACvE,MAAM,sBAAsB,GAC1B,OAAO,KAAK,OAAO,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,oBAAoB,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YAC7G,CAAC,CAAC,CAAC;YACH,CAAC,CAAC,CAAC,CAAA;QACP,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,MAAM,GAAG,sBAAsB,EAAE,CAAA;IAC7E,CAAC,CAAC;SACD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAA;IAEpC,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,CAAA;IACxB,MAAM,OAAO,GAAG,MAAM,IAAI,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,CAAA;IAC5E,MAAM,iBAAiB,GAAG,MAAM;SAC7B,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,KAAK,OAAO,IAAI,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;SAC5D,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;SACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IAC9B,MAAM,QAAQ,GAAG,MAAM,EAAE,KAAK,IAAI,CAAC,CAAA;IACnC,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,CAAA;IACtC,MAAM,UAAU,GAAG,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,GAAG,QAAQ,GAAG,GAAG,GAAG,QAAQ,GAAG,IAAI,CAAC,CAAA;IAElG,OAAO;QACL,OAAO;QACP,iBAAiB;QACjB,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACzC,cAAc,EAAE,MAAM,EAAE,OAAO,IAAI,EAAE;QACrC,gBAAgB,EAAE,OAAO,KAAK,UAAU,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,KAAK,UAAU,IAAI,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;QAChH,QAAQ,EAAE,gBAAgB,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;KACzE,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { OrchestraConfig } from "../config/schema.js";
|
|
2
|
+
import type { Classification } from "./classifier.js";
|
|
3
|
+
export interface EscalationInput {
|
|
4
|
+
classification: Classification;
|
|
5
|
+
consensus?: number;
|
|
6
|
+
premiumCallsUsed?: number;
|
|
7
|
+
}
|
|
8
|
+
export interface EscalationDecision {
|
|
9
|
+
escalate: boolean;
|
|
10
|
+
reason: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function decideEscalation(config: OrchestraConfig, input: EscalationInput): EscalationDecision;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export function decideEscalation(config, input) {
|
|
2
|
+
if (!config.orchestration.premiumEscalation) {
|
|
3
|
+
return { escalate: false, reason: "premium escalation disabled" };
|
|
4
|
+
}
|
|
5
|
+
if ((input.premiumCallsUsed ?? 0) >= config.orchestration.maxPremiumCallsPerTask) {
|
|
6
|
+
return { escalate: false, reason: "premium call budget exhausted" };
|
|
7
|
+
}
|
|
8
|
+
const uncertain = input.classification.confidence < config.orchestration.confidenceThreshold;
|
|
9
|
+
const disagreement = input.consensus !== undefined && input.consensus < config.orchestration.confidenceThreshold;
|
|
10
|
+
if (config.budget === "ebobo") {
|
|
11
|
+
return { escalate: true, reason: "ebobo mode always requests frontier arbitration" };
|
|
12
|
+
}
|
|
13
|
+
if (config.budget === "eco") {
|
|
14
|
+
return input.classification.critical && disagreement
|
|
15
|
+
? { escalate: true, reason: "critical worker disagreement" }
|
|
16
|
+
: { escalate: false, reason: "eco mode reserves judge for critical disagreement" };
|
|
17
|
+
}
|
|
18
|
+
if (input.classification.critical || uncertain || disagreement) {
|
|
19
|
+
return {
|
|
20
|
+
escalate: true,
|
|
21
|
+
reason: input.classification.critical
|
|
22
|
+
? "critical task"
|
|
23
|
+
: disagreement
|
|
24
|
+
? "worker disagreement"
|
|
25
|
+
: "low classification confidence",
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
return { escalate: false, reason: "lead can synthesize with sufficient confidence" };
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=escalation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"escalation.js","sourceRoot":"","sources":["../../src/routing/escalation.ts"],"names":[],"mappings":"AAcA,MAAM,UAAU,gBAAgB,CAC9B,MAAuB,EACvB,KAAsB;IAEtB,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,iBAAiB,EAAE,CAAC;QAC5C,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,6BAA6B,EAAE,CAAA;IACnE,CAAC;IAED,IAAI,CAAC,KAAK,CAAC,gBAAgB,IAAI,CAAC,CAAC,IAAI,MAAM,CAAC,aAAa,CAAC,sBAAsB,EAAE,CAAC;QACjF,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,+BAA+B,EAAE,CAAA;IACrE,CAAC;IAED,MAAM,SAAS,GAAG,KAAK,CAAC,cAAc,CAAC,UAAU,GAAG,MAAM,CAAC,aAAa,CAAC,mBAAmB,CAAA;IAC5F,MAAM,YAAY,GAAG,KAAK,CAAC,SAAS,KAAK,SAAS,IAAI,KAAK,CAAC,SAAS,GAAG,MAAM,CAAC,aAAa,CAAC,mBAAmB,CAAA;IAEhH,IAAI,MAAM,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;QAC9B,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,iDAAiD,EAAE,CAAA;IACtF,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;QAC5B,OAAO,KAAK,CAAC,cAAc,CAAC,QAAQ,IAAI,YAAY;YAClD,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,8BAA8B,EAAE;YAC5D,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,mDAAmD,EAAE,CAAA;IACtF,CAAC;IAED,IAAI,KAAK,CAAC,cAAc,CAAC,QAAQ,IAAI,SAAS,IAAI,YAAY,EAAE,CAAC;QAC/D,OAAO;YACL,QAAQ,EAAE,IAAI;YACd,MAAM,EAAE,KAAK,CAAC,cAAc,CAAC,QAAQ;gBACnC,CAAC,CAAC,eAAe;gBACjB,CAAC,CAAC,YAAY;oBACZ,CAAC,CAAC,qBAAqB;oBACvB,CAAC,CAAC,+BAA+B;SACtC,CAAA;IACH,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,gDAAgD,EAAE,CAAA;AACtF,CAAC"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { ModelCandidateInput, OrchestraConfig } from "../config/schema.js";
|
|
2
|
+
export declare function discoverConnectedModels(client: unknown): Promise<ModelCandidateInput[]>;
|
|
3
|
+
export declare function applyDiscoveredModels(config: OrchestraConfig, discovered: ModelCandidateInput[]): OrchestraConfig;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
function contextClass(tokens) {
|
|
2
|
+
if (!tokens)
|
|
3
|
+
return undefined;
|
|
4
|
+
if (tokens >= 500_000)
|
|
5
|
+
return "xlarge";
|
|
6
|
+
if (tokens >= 128_000)
|
|
7
|
+
return "large";
|
|
8
|
+
if (tokens >= 32_000)
|
|
9
|
+
return "medium";
|
|
10
|
+
return "small";
|
|
11
|
+
}
|
|
12
|
+
function capabilities(model) {
|
|
13
|
+
const result = new Set();
|
|
14
|
+
if (model.tool_call !== false) {
|
|
15
|
+
result.add("code");
|
|
16
|
+
result.add("research");
|
|
17
|
+
}
|
|
18
|
+
if (model.reasoning) {
|
|
19
|
+
result.add("reasoning");
|
|
20
|
+
result.add("review");
|
|
21
|
+
result.add("security");
|
|
22
|
+
result.add("performance");
|
|
23
|
+
}
|
|
24
|
+
if (model.attachment || model.modalities?.input.includes("image"))
|
|
25
|
+
result.add("vision");
|
|
26
|
+
if (model.modalities?.output.includes("image"))
|
|
27
|
+
result.add("image");
|
|
28
|
+
if ((model.limit?.context ?? 0) >= 128_000)
|
|
29
|
+
result.add("large-context");
|
|
30
|
+
return [...result];
|
|
31
|
+
}
|
|
32
|
+
function candidate(providerID, model) {
|
|
33
|
+
const paid = Boolean(model.cost && (model.cost.input > 0 || model.cost.output > 0));
|
|
34
|
+
const caps = capabilities(model);
|
|
35
|
+
const price = (model.cost?.input ?? 0) + (model.cost?.output ?? 0);
|
|
36
|
+
const lifecyclePenalty = model.status === "deprecated" ? 45 : model.experimental || model.status === "alpha" ? 15 : 0;
|
|
37
|
+
const priority = Math.max(5, Math.min(95, 70 - Math.log10(1 + price) * 8 - lifecyclePenalty));
|
|
38
|
+
const scores = {};
|
|
39
|
+
for (const capability of caps)
|
|
40
|
+
scores[capability] = model.reasoning && capability === "reasoning" ? 9 : 7;
|
|
41
|
+
return {
|
|
42
|
+
id: `${providerID}/${model.id}`,
|
|
43
|
+
cost: paid ? "paid" : "free",
|
|
44
|
+
tier: model.reasoning ? ((model.limit?.context ?? 0) >= 200_000 ? "frontier" : "lead") : "worker",
|
|
45
|
+
priority,
|
|
46
|
+
capabilities: caps,
|
|
47
|
+
scores,
|
|
48
|
+
...(contextClass(model.limit?.context) ? { context: contextClass(model.limit?.context) } : {}),
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
export async function discoverConnectedModels(client) {
|
|
52
|
+
const provider = client.provider;
|
|
53
|
+
if (!provider?.list)
|
|
54
|
+
return [];
|
|
55
|
+
try {
|
|
56
|
+
const result = await provider.list();
|
|
57
|
+
const catalog = result.data;
|
|
58
|
+
if (!catalog)
|
|
59
|
+
return [];
|
|
60
|
+
const connected = new Set(catalog.connected);
|
|
61
|
+
return catalog.all
|
|
62
|
+
.filter((item) => connected.has(item.id))
|
|
63
|
+
.flatMap((item) => Object.values(item.models).map((model) => candidate(item.id, model)));
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return [];
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function hasCapability(input, capability) {
|
|
70
|
+
return typeof input !== "string" && input.capabilities.includes(capability);
|
|
71
|
+
}
|
|
72
|
+
function best(inputs, capability) {
|
|
73
|
+
const matching = inputs.filter((input) => hasCapability(input, capability));
|
|
74
|
+
return (matching.length > 0 ? matching : inputs).slice(0, 24);
|
|
75
|
+
}
|
|
76
|
+
export function applyDiscoveredModels(config, discovered) {
|
|
77
|
+
if (config.models.strategy !== "auto" || discovered.length === 0)
|
|
78
|
+
return config;
|
|
79
|
+
const fill = (current, capability) => current.length > 0 ? current : best(discovered, capability);
|
|
80
|
+
return {
|
|
81
|
+
...config,
|
|
82
|
+
models: {
|
|
83
|
+
...config.models,
|
|
84
|
+
lead: fill(config.models.lead, "reasoning"),
|
|
85
|
+
worker: {
|
|
86
|
+
code: fill(config.models.worker.code, "code"),
|
|
87
|
+
reasoning: fill(config.models.worker.reasoning, "reasoning"),
|
|
88
|
+
research: fill(config.models.worker.research, "research"),
|
|
89
|
+
vision: fill(config.models.worker.vision, "vision"),
|
|
90
|
+
image: fill(config.models.worker.image, "image"),
|
|
91
|
+
},
|
|
92
|
+
judge: fill(config.models.judge, "review"),
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=model-discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-discovery.js","sourceRoot":"","sources":["../../src/routing/model-discovery.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { BudgetMode, CapabilityName, ModelCandidateInput, ModelCost, ModelTier } from "../config/schema.js";
|
|
2
|
+
export interface ModelCandidate {
|
|
3
|
+
id: string;
|
|
4
|
+
cost: ModelCost;
|
|
5
|
+
tier: ModelTier;
|
|
6
|
+
priority: number;
|
|
7
|
+
capabilities: CapabilityName[];
|
|
8
|
+
scores: Record<string, number>;
|
|
9
|
+
context?: "small" | "medium" | "large" | "xlarge";
|
|
10
|
+
}
|
|
11
|
+
export interface ResolveModelRequest {
|
|
12
|
+
pool: ModelCandidateInput[];
|
|
13
|
+
capability: CapabilityName;
|
|
14
|
+
budget: BudgetMode;
|
|
15
|
+
allowPaid: boolean;
|
|
16
|
+
preferredCosts?: ModelCost[];
|
|
17
|
+
preferredTiers?: ModelTier[];
|
|
18
|
+
}
|
|
19
|
+
export interface ResolvedModel {
|
|
20
|
+
id: string;
|
|
21
|
+
score: number;
|
|
22
|
+
cost: ModelCost;
|
|
23
|
+
reason: string[];
|
|
24
|
+
}
|
|
25
|
+
export declare function normalizeCandidate(input: ModelCandidateInput): ModelCandidate;
|
|
26
|
+
export declare function resolveModel(request: ResolveModelRequest): ResolvedModel | undefined;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { costAdjustment, getBudgetPolicy } from "./budget.js";
|
|
2
|
+
export function normalizeCandidate(input) {
|
|
3
|
+
if (typeof input === "string") {
|
|
4
|
+
return {
|
|
5
|
+
id: input,
|
|
6
|
+
cost: "free",
|
|
7
|
+
tier: "worker",
|
|
8
|
+
priority: 50,
|
|
9
|
+
capabilities: [],
|
|
10
|
+
scores: {},
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
return {
|
|
14
|
+
id: input.id,
|
|
15
|
+
cost: input.cost,
|
|
16
|
+
tier: input.tier,
|
|
17
|
+
priority: input.priority,
|
|
18
|
+
capabilities: input.capabilities,
|
|
19
|
+
scores: input.scores,
|
|
20
|
+
...(input.context ? { context: input.context } : {}),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export function resolveModel(request) {
|
|
24
|
+
const policy = getBudgetPolicy(request.budget);
|
|
25
|
+
const ranked = request.pool
|
|
26
|
+
.map(normalizeCandidate)
|
|
27
|
+
.filter((candidate) => request.allowPaid || candidate.cost !== "paid")
|
|
28
|
+
.map((candidate) => {
|
|
29
|
+
const explicit = candidate.scores[request.capability] ?? 0;
|
|
30
|
+
const declared = candidate.capabilities.includes(request.capability) ? 18 : 0;
|
|
31
|
+
const contextBonus = candidate.context === "xlarge" ? 8 : candidate.context === "large" ? 4 : 0;
|
|
32
|
+
const frontierBonus = request.budget === "ebobo"
|
|
33
|
+
? candidate.tier === "frontier"
|
|
34
|
+
? 160
|
|
35
|
+
: candidate.tier === "lead"
|
|
36
|
+
? 60
|
|
37
|
+
: 0
|
|
38
|
+
: 0;
|
|
39
|
+
const preferredCostIndex = request.preferredCosts?.indexOf(candidate.cost) ?? -1;
|
|
40
|
+
const preferredTierIndex = request.preferredTiers?.indexOf(candidate.tier) ?? -1;
|
|
41
|
+
const preferredCostBonus = preferredCostIndex >= 0 ? Math.max(30, 100 - preferredCostIndex * 30) : 0;
|
|
42
|
+
const preferredTierBonus = preferredTierIndex >= 0 ? Math.max(30, 100 - preferredTierIndex * 30) : 0;
|
|
43
|
+
const score = candidate.priority + explicit * 8 + declared + contextBonus + frontierBonus
|
|
44
|
+
+ preferredCostBonus + preferredTierBonus + costAdjustment(candidate.cost, policy);
|
|
45
|
+
const reason = [
|
|
46
|
+
`priority=${candidate.priority}`,
|
|
47
|
+
`capability=${explicit || (declared ? "declared" : "unspecified")}`,
|
|
48
|
+
`cost=${candidate.cost}`,
|
|
49
|
+
...(frontierBonus ? [`frontier=${frontierBonus}`] : []),
|
|
50
|
+
...(preferredCostBonus ? [`preferred-cost=${preferredCostBonus}`] : []),
|
|
51
|
+
...(preferredTierBonus ? [`preferred-tier=${preferredTierBonus}`] : []),
|
|
52
|
+
];
|
|
53
|
+
return { candidate, score, reason };
|
|
54
|
+
})
|
|
55
|
+
.sort((a, b) => b.score - a.score || a.candidate.id.localeCompare(b.candidate.id));
|
|
56
|
+
const winner = ranked[0];
|
|
57
|
+
if (!winner)
|
|
58
|
+
return undefined;
|
|
59
|
+
return {
|
|
60
|
+
id: winner.candidate.id,
|
|
61
|
+
score: winner.score,
|
|
62
|
+
cost: winner.candidate.cost,
|
|
63
|
+
reason: winner.reason,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=model-resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-resolver.js","sourceRoot":"","sources":["../../src/routing/model-resolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export function primarySystemHint(config) {
|
|
2
|
+
if (!config.superpowers.injectPrimaryHint)
|
|
3
|
+
return undefined;
|
|
4
|
+
const compatibility = config.superpowers.compatibility
|
|
5
|
+
? "Do not bypass or replace active skills, plans, TDD workflows, review workflows, or Superpowers instructions."
|
|
6
|
+
: "Respect all active skills and user instructions.";
|
|
7
|
+
return `OpenCode Orchestra is available as an additive analysis layer. For complex research or ambiguous work, you may delegate one focused task to orch-lead. ${compatibility} Keep implementation and final decisions in the current primary agent unless the user asks otherwise.`;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=compatibility.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compatibility.js","sourceRoot":"","sources":["../../src/superpowers/compatibility.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,iBAAiB,CAAC,MAAuB;IACvD,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,iBAAiB;QAAE,OAAO,SAAS,CAAA;IAE3D,MAAM,aAAa,GAAG,MAAM,CAAC,WAAW,CAAC,aAAa;QACpD,CAAC,CAAC,8GAA8G;QAChH,CAAC,CAAC,kDAAkD,CAAA;IAEtD,OAAO,0JAA0J,aAAa,uGAAuG,CAAA;AACvR,CAAC"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { ModelCandidateInput, ProfileName } from "../config/schema.js";
|
|
2
|
+
export interface TokenUsage {
|
|
3
|
+
input: number;
|
|
4
|
+
output: number;
|
|
5
|
+
reasoning: number;
|
|
6
|
+
cache: {
|
|
7
|
+
read: number;
|
|
8
|
+
write: number;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
export interface MessageUsage {
|
|
12
|
+
cost: number;
|
|
13
|
+
agent?: string;
|
|
14
|
+
model?: string;
|
|
15
|
+
provider?: string;
|
|
16
|
+
createdAt?: number;
|
|
17
|
+
completedAt?: number;
|
|
18
|
+
finish?: string;
|
|
19
|
+
tokens: TokenUsage;
|
|
20
|
+
}
|
|
21
|
+
export interface SessionLedger {
|
|
22
|
+
profile?: ProfileName;
|
|
23
|
+
agents: Record<string, number>;
|
|
24
|
+
premiumEscalations: number;
|
|
25
|
+
estimatedPaidUsage: number;
|
|
26
|
+
freeWorkerCalls: number;
|
|
27
|
+
consensus?: number;
|
|
28
|
+
messages: Record<string, MessageUsage>;
|
|
29
|
+
}
|
|
30
|
+
export interface LedgerState {
|
|
31
|
+
version: 2;
|
|
32
|
+
updatedAt: string;
|
|
33
|
+
sessions: Record<string, SessionLedger>;
|
|
34
|
+
}
|
|
35
|
+
interface AssistantInfo {
|
|
36
|
+
id: string;
|
|
37
|
+
sessionID: string;
|
|
38
|
+
role: "assistant";
|
|
39
|
+
mode?: string;
|
|
40
|
+
modelID?: string;
|
|
41
|
+
providerID?: string;
|
|
42
|
+
cost?: number;
|
|
43
|
+
time?: {
|
|
44
|
+
created: number;
|
|
45
|
+
completed?: number;
|
|
46
|
+
};
|
|
47
|
+
tokens?: TokenUsage;
|
|
48
|
+
finish?: string;
|
|
49
|
+
}
|
|
50
|
+
export declare function emptyLedgerState(): LedgerState;
|
|
51
|
+
export declare function readLedgerState(file: string): Promise<LedgerState>;
|
|
52
|
+
export declare class Ledger {
|
|
53
|
+
readonly enabled: boolean;
|
|
54
|
+
readonly stateFile: string;
|
|
55
|
+
private readonly modelCosts;
|
|
56
|
+
private state?;
|
|
57
|
+
private queue;
|
|
58
|
+
constructor(directory: string, telemetryDirectory: string, enabled: boolean, pools: ModelCandidateInput[][]);
|
|
59
|
+
private load;
|
|
60
|
+
private save;
|
|
61
|
+
private mutate;
|
|
62
|
+
setProfile(sessionID: string, profile: ProfileName): Promise<void>;
|
|
63
|
+
setConsensus(sessionID: string, consensus: number): Promise<void>;
|
|
64
|
+
recordAssistant(info: AssistantInfo): Promise<void>;
|
|
65
|
+
getSession(sessionID: string): Promise<SessionLedger>;
|
|
66
|
+
formatStatus(sessionID: string): Promise<string>;
|
|
67
|
+
}
|
|
68
|
+
export {};
|