@deepthonk/core 0.1.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 +293 -0
- package/dist/artifacts.d.ts +36 -0
- package/dist/artifacts.js +211 -0
- package/dist/artifacts.js.map +1 -0
- package/dist/bradleyTerry.d.ts +2 -0
- package/dist/bradleyTerry.js +204 -0
- package/dist/bradleyTerry.js.map +1 -0
- package/dist/budget.d.ts +14 -0
- package/dist/budget.js +41 -0
- package/dist/budget.js.map +1 -0
- package/dist/budgetTracker.d.ts +16 -0
- package/dist/budgetTracker.js +137 -0
- package/dist/budgetTracker.js.map +1 -0
- package/dist/critique.d.ts +2 -0
- package/dist/critique.js +52 -0
- package/dist/critique.js.map +1 -0
- package/dist/errors.d.ts +24 -0
- package/dist/errors.js +27 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/json.d.ts +1 -0
- package/dist/json.js +28 -0
- package/dist/json.js.map +1 -0
- package/dist/lifecycle.d.ts +63 -0
- package/dist/lifecycle.js +45 -0
- package/dist/lifecycle.js.map +1 -0
- package/dist/pairScheduler.d.ts +6 -0
- package/dist/pairScheduler.js +79 -0
- package/dist/pairScheduler.js.map +1 -0
- package/dist/prompts.d.ts +15 -0
- package/dist/prompts.js +200 -0
- package/dist/prompts.js.map +1 -0
- package/dist/rng.d.ts +8 -0
- package/dist/rng.js +31 -0
- package/dist/rng.js.map +1 -0
- package/dist/runner.d.ts +11 -0
- package/dist/runner.js +518 -0
- package/dist/runner.js.map +1 -0
- package/dist/schemas.d.ts +648 -0
- package/dist/schemas.js +119 -0
- package/dist/schemas.js.map +1 -0
- package/dist/services.d.ts +40 -0
- package/dist/services.js +104 -0
- package/dist/services.js.map +1 -0
- package/dist/traceStore.d.ts +22 -0
- package/dist/traceStore.js +105 -0
- package/dist/traceStore.js.map +1 -0
- package/package.json +42 -0
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
export function fitBradleyTerry(candidates, comparisons, lambda = 0.01, generation = inferGeneration(comparisons)) {
|
|
2
|
+
const ids = candidates.map((candidate) => (typeof candidate === "string" ? candidate : candidate.id)).sort();
|
|
3
|
+
const index = new Map(ids.map((id, i) => [id, i]));
|
|
4
|
+
const outcomes = [];
|
|
5
|
+
const counts = new Map(ids.map((id) => [
|
|
6
|
+
id,
|
|
7
|
+
{
|
|
8
|
+
wins: 0,
|
|
9
|
+
losses: 0,
|
|
10
|
+
ties: 0,
|
|
11
|
+
comparisons: 0
|
|
12
|
+
}
|
|
13
|
+
]));
|
|
14
|
+
for (const comparison of comparisons) {
|
|
15
|
+
const a = comparison.presentedAOriginalId;
|
|
16
|
+
const b = comparison.presentedBOriginalId;
|
|
17
|
+
const i = index.get(a);
|
|
18
|
+
const j = index.get(b);
|
|
19
|
+
if (i === undefined || j === undefined)
|
|
20
|
+
continue;
|
|
21
|
+
const aCount = counts.get(a);
|
|
22
|
+
const bCount = counts.get(b);
|
|
23
|
+
aCount.comparisons += 1;
|
|
24
|
+
bCount.comparisons += 1;
|
|
25
|
+
if (comparison.winner === "A") {
|
|
26
|
+
outcomes.push({ i, j, y: 1 });
|
|
27
|
+
aCount.wins += 1;
|
|
28
|
+
bCount.losses += 1;
|
|
29
|
+
}
|
|
30
|
+
else if (comparison.winner === "B") {
|
|
31
|
+
outcomes.push({ i, j, y: 0 });
|
|
32
|
+
bCount.wins += 1;
|
|
33
|
+
aCount.losses += 1;
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
outcomes.push({ i, j, y: 0.5 });
|
|
37
|
+
aCount.ties += 1;
|
|
38
|
+
bCount.ties += 1;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
const scores = new Array(ids.length).fill(0);
|
|
42
|
+
if (outcomes.length > 0) {
|
|
43
|
+
fitLbfgs(scores, outcomes, lambda);
|
|
44
|
+
}
|
|
45
|
+
return ids
|
|
46
|
+
.map((candidateId, i) => {
|
|
47
|
+
const count = counts.get(candidateId);
|
|
48
|
+
return {
|
|
49
|
+
candidateId,
|
|
50
|
+
generation,
|
|
51
|
+
score: finite(scores[i]),
|
|
52
|
+
rank: 0,
|
|
53
|
+
wins: count.wins,
|
|
54
|
+
losses: count.losses,
|
|
55
|
+
ties: count.ties,
|
|
56
|
+
comparisons: count.comparisons
|
|
57
|
+
};
|
|
58
|
+
})
|
|
59
|
+
.sort((left, right) => right.score - left.score || left.candidateId.localeCompare(right.candidateId))
|
|
60
|
+
.map((score, i) => ({ ...score, rank: i + 1 }));
|
|
61
|
+
}
|
|
62
|
+
function fitLbfgs(scores, outcomes, lambda) {
|
|
63
|
+
const historySize = 10;
|
|
64
|
+
const sHistory = [];
|
|
65
|
+
const yHistory = [];
|
|
66
|
+
const rhoHistory = [];
|
|
67
|
+
let currentLoss = loss(scores, outcomes, lambda);
|
|
68
|
+
let currentGrad = gradient(scores, outcomes, lambda);
|
|
69
|
+
for (let iter = 0; iter < 500; iter += 1) {
|
|
70
|
+
const norm = vectorNorm(currentGrad);
|
|
71
|
+
if (norm < 1e-7)
|
|
72
|
+
break;
|
|
73
|
+
let direction = lbfgsDirection(currentGrad, sHistory, yHistory, rhoHistory).map((value) => -value);
|
|
74
|
+
if (dot(direction, currentGrad) >= 0)
|
|
75
|
+
direction = currentGrad.map((value) => -value);
|
|
76
|
+
let step = 1;
|
|
77
|
+
let acceptedScores;
|
|
78
|
+
let acceptedLoss = Number.POSITIVE_INFINITY;
|
|
79
|
+
const directionalDerivative = dot(currentGrad, direction);
|
|
80
|
+
for (let backtrack = 0; backtrack < 30; backtrack += 1) {
|
|
81
|
+
const candidate = scores.map((score, i) => score + step * direction[i]);
|
|
82
|
+
center(candidate);
|
|
83
|
+
const candidateLoss = loss(candidate, outcomes, lambda);
|
|
84
|
+
if (Number.isFinite(candidateLoss) && candidateLoss <= currentLoss + 1e-4 * step * directionalDerivative) {
|
|
85
|
+
acceptedScores = candidate;
|
|
86
|
+
acceptedLoss = candidateLoss;
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
step *= 0.5;
|
|
90
|
+
}
|
|
91
|
+
if (!acceptedScores)
|
|
92
|
+
break;
|
|
93
|
+
const nextGrad = gradient(acceptedScores, outcomes, lambda);
|
|
94
|
+
const s = acceptedScores.map((score, i) => score - scores[i]);
|
|
95
|
+
const y = nextGrad.map((value, i) => value - currentGrad[i]);
|
|
96
|
+
const ys = dot(y, s);
|
|
97
|
+
if (ys > 1e-10) {
|
|
98
|
+
sHistory.push(s);
|
|
99
|
+
yHistory.push(y);
|
|
100
|
+
rhoHistory.push(1 / ys);
|
|
101
|
+
if (sHistory.length > historySize) {
|
|
102
|
+
sHistory.shift();
|
|
103
|
+
yHistory.shift();
|
|
104
|
+
rhoHistory.shift();
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
for (let i = 0; i < scores.length; i += 1)
|
|
108
|
+
scores[i] = acceptedScores[i];
|
|
109
|
+
currentLoss = acceptedLoss;
|
|
110
|
+
currentGrad = nextGrad;
|
|
111
|
+
}
|
|
112
|
+
zScore(scores);
|
|
113
|
+
}
|
|
114
|
+
function lbfgsDirection(grad, sHistory, yHistory, rhoHistory) {
|
|
115
|
+
const q = [...grad];
|
|
116
|
+
const alphas = [];
|
|
117
|
+
for (let i = sHistory.length - 1; i >= 0; i -= 1) {
|
|
118
|
+
const alpha = rhoHistory[i] * dot(sHistory[i], q);
|
|
119
|
+
alphas[i] = alpha;
|
|
120
|
+
addScaled(q, yHistory[i], -alpha);
|
|
121
|
+
}
|
|
122
|
+
const lastS = sHistory.at(-1);
|
|
123
|
+
const lastY = yHistory.at(-1);
|
|
124
|
+
const gamma = lastS && lastY ? dot(lastS, lastY) / Math.max(dot(lastY, lastY), 1e-12) : 1;
|
|
125
|
+
for (let i = 0; i < q.length; i += 1)
|
|
126
|
+
q[i] *= gamma;
|
|
127
|
+
for (let i = 0; i < sHistory.length; i += 1) {
|
|
128
|
+
const beta = rhoHistory[i] * dot(yHistory[i], q);
|
|
129
|
+
addScaled(q, sHistory[i], (alphas[i] ?? 0) - beta);
|
|
130
|
+
}
|
|
131
|
+
return q;
|
|
132
|
+
}
|
|
133
|
+
function gradient(scores, outcomes, lambda) {
|
|
134
|
+
const grad = scores.map((score) => lambda * score);
|
|
135
|
+
for (const outcome of outcomes) {
|
|
136
|
+
const p = sigmoid(scores[outcome.i] - scores[outcome.j]);
|
|
137
|
+
const delta = p - outcome.y;
|
|
138
|
+
grad[outcome.i] += delta;
|
|
139
|
+
grad[outcome.j] -= delta;
|
|
140
|
+
}
|
|
141
|
+
return grad;
|
|
142
|
+
}
|
|
143
|
+
function loss(scores, outcomes, lambda) {
|
|
144
|
+
let total = 0.5 * lambda * scores.reduce((sum, score) => sum + score * score, 0);
|
|
145
|
+
for (const outcome of outcomes) {
|
|
146
|
+
const diff = scores[outcome.i] - scores[outcome.j];
|
|
147
|
+
total += softplus(diff) - outcome.y * diff;
|
|
148
|
+
}
|
|
149
|
+
return total;
|
|
150
|
+
}
|
|
151
|
+
function sigmoid(value) {
|
|
152
|
+
if (value >= 0) {
|
|
153
|
+
const z = Math.exp(-value);
|
|
154
|
+
return 1 / (1 + z);
|
|
155
|
+
}
|
|
156
|
+
const z = Math.exp(value);
|
|
157
|
+
return z / (1 + z);
|
|
158
|
+
}
|
|
159
|
+
function softplus(value) {
|
|
160
|
+
return value > 30 ? value : Math.log1p(Math.exp(value));
|
|
161
|
+
}
|
|
162
|
+
function center(values) {
|
|
163
|
+
const mean = values.reduce((sum, value) => sum + value, 0) / values.length;
|
|
164
|
+
for (let i = 0; i < values.length; i += 1)
|
|
165
|
+
values[i] -= mean;
|
|
166
|
+
}
|
|
167
|
+
// Match the reference Python implementation's score scaling: subtract the mean
|
|
168
|
+
// and divide by stddev (z-score). Rank is invariant under this affine transform.
|
|
169
|
+
// Note: the OpenDeepThink paper (Zhou et al. 2026) specifies raw L2-regularized
|
|
170
|
+
// MLE; z-scoring is a reference-repo logging convention, not a paper-specified
|
|
171
|
+
// step. We adopt it so logged `score:` values are directly comparable to the
|
|
172
|
+
// reference's outputs.
|
|
173
|
+
function zScore(values) {
|
|
174
|
+
const mean = values.reduce((sum, value) => sum + value, 0) / values.length;
|
|
175
|
+
let variance = 0;
|
|
176
|
+
for (let i = 0; i < values.length; i += 1) {
|
|
177
|
+
const centered = values[i] - mean;
|
|
178
|
+
values[i] = centered;
|
|
179
|
+
variance += centered * centered;
|
|
180
|
+
}
|
|
181
|
+
variance /= values.length;
|
|
182
|
+
const std = Math.sqrt(variance);
|
|
183
|
+
if (std <= 1e-6)
|
|
184
|
+
return;
|
|
185
|
+
for (let i = 0; i < values.length; i += 1)
|
|
186
|
+
values[i] /= std;
|
|
187
|
+
}
|
|
188
|
+
function dot(left, right) {
|
|
189
|
+
return left.reduce((sum, value, i) => sum + value * right[i], 0);
|
|
190
|
+
}
|
|
191
|
+
function addScaled(target, vector, scale) {
|
|
192
|
+
for (let i = 0; i < target.length; i += 1)
|
|
193
|
+
target[i] += scale * vector[i];
|
|
194
|
+
}
|
|
195
|
+
function vectorNorm(values) {
|
|
196
|
+
return Math.sqrt(values.reduce((sum, value) => sum + value * value, 0));
|
|
197
|
+
}
|
|
198
|
+
function finite(value) {
|
|
199
|
+
return Number.isFinite(value) ? value : 0;
|
|
200
|
+
}
|
|
201
|
+
function inferGeneration(comparisons) {
|
|
202
|
+
return comparisons[0]?.generation ?? "final";
|
|
203
|
+
}
|
|
204
|
+
//# sourceMappingURL=bradleyTerry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bradleyTerry.js","sourceRoot":"","sources":["../src/bradleyTerry.ts"],"names":[],"mappings":"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"}
|
package/dist/budget.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { BuiltInProfileName, Profile } from "./schemas.js";
|
|
2
|
+
export interface BudgetPlan {
|
|
3
|
+
profile?: BuiltInProfileName | "custom";
|
|
4
|
+
calls: number;
|
|
5
|
+
initial_generate_calls: number;
|
|
6
|
+
per_generation_judge_calls: number;
|
|
7
|
+
per_generation_mutate_calls: number;
|
|
8
|
+
final_judge_calls: number;
|
|
9
|
+
sequential_rounds: number;
|
|
10
|
+
warnings: string[];
|
|
11
|
+
}
|
|
12
|
+
export declare function getProfile(profile: BuiltInProfileName | Profile): Profile;
|
|
13
|
+
export declare function validateProfile(profile: Profile): void;
|
|
14
|
+
export declare function planBudget(profileInput: BuiltInProfileName | Profile): BudgetPlan;
|
package/dist/budget.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { ConfigError } from "./errors.js";
|
|
2
|
+
import { builtInProfiles } from "./schemas.js";
|
|
3
|
+
export function getProfile(profile) {
|
|
4
|
+
if (typeof profile !== "string")
|
|
5
|
+
return profile;
|
|
6
|
+
const value = builtInProfiles[profile];
|
|
7
|
+
if (!value)
|
|
8
|
+
throw new ConfigError(`Unknown profile: ${profile}. Use quick, balanced, or paper.`);
|
|
9
|
+
return value;
|
|
10
|
+
}
|
|
11
|
+
export function validateProfile(profile) {
|
|
12
|
+
if (profile.k >= profile.n)
|
|
13
|
+
throw new ConfigError(`Profile invalid: k (${profile.k}) must be less than n (${profile.n}).`);
|
|
14
|
+
if (profile.m >= profile.n)
|
|
15
|
+
throw new ConfigError(`Profile invalid: m (${profile.m}) must be less than n (${profile.n}).`);
|
|
16
|
+
if ((profile.n * profile.k) % 2 !== 0)
|
|
17
|
+
throw new ConfigError(`Profile invalid: n*k must be even, got ${profile.n * profile.k}.`);
|
|
18
|
+
if ((profile.n * profile.m) % 2 !== 0)
|
|
19
|
+
throw new ConfigError(`Profile invalid: n*m must be even, got ${profile.n * profile.m}.`);
|
|
20
|
+
}
|
|
21
|
+
export function planBudget(profileInput) {
|
|
22
|
+
const profile = getProfile(profileInput);
|
|
23
|
+
validateProfile(profile);
|
|
24
|
+
const profileName = typeof profileInput === "string" ? profileInput : "custom";
|
|
25
|
+
const eliteCount = Math.ceil(profile.n / 4);
|
|
26
|
+
const mutateCount = profile.n - eliteCount;
|
|
27
|
+
const perGenerationJudge = (profile.n * profile.k) / 2;
|
|
28
|
+
const finalJudge = (profile.n * profile.m) / 2;
|
|
29
|
+
const calls = profile.n + profile.t * (perGenerationJudge + mutateCount) + finalJudge;
|
|
30
|
+
return {
|
|
31
|
+
profile: profileName,
|
|
32
|
+
calls,
|
|
33
|
+
initial_generate_calls: profile.n,
|
|
34
|
+
per_generation_judge_calls: perGenerationJudge,
|
|
35
|
+
per_generation_mutate_calls: mutateCount,
|
|
36
|
+
final_judge_calls: finalJudge,
|
|
37
|
+
sequential_rounds: 1 + profile.t * 2 + 1,
|
|
38
|
+
warnings: calls >= 100 ? ["High call count; confirm provider cost limits before running."] : []
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=budget.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"budget.js","sourceRoot":"","sources":["../src/budget.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAa/C,MAAM,UAAU,UAAU,CAAC,OAAqC;IAC9D,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,OAAO,OAAO,CAAC;IAChD,MAAM,KAAK,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IACvC,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,WAAW,CAAC,oBAAoB,OAAO,kCAAkC,CAAC,CAAC;IACjG,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAAgB;IAC9C,IAAI,OAAO,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC;QAAE,MAAM,IAAI,WAAW,CAAC,uBAAuB,OAAO,CAAC,CAAC,0BAA0B,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC;IAC3H,IAAI,OAAO,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC;QAAE,MAAM,IAAI,WAAW,CAAC,uBAAuB,OAAO,CAAC,CAAC,0BAA0B,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC;IAC3H,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,WAAW,CAAC,0CAA0C,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC;IACjI,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,WAAW,CAAC,0CAA0C,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC;AACnI,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,YAA0C;IACnE,MAAM,OAAO,GAAG,UAAU,CAAC,YAAY,CAAC,CAAC;IACzC,eAAe,CAAC,OAAO,CAAC,CAAC;IACzB,MAAM,WAAW,GAAG,OAAO,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC;IAC/E,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5C,MAAM,WAAW,GAAG,OAAO,CAAC,CAAC,GAAG,UAAU,CAAC;IAC3C,MAAM,kBAAkB,GAAG,CAAC,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACvD,MAAM,UAAU,GAAG,CAAC,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAC/C,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,CAAC,kBAAkB,GAAG,WAAW,CAAC,GAAG,UAAU,CAAC;IACtF,OAAO;QACL,OAAO,EAAE,WAAW;QACpB,KAAK;QACL,sBAAsB,EAAE,OAAO,CAAC,CAAC;QACjC,0BAA0B,EAAE,kBAAkB;QAC9C,2BAA2B,EAAE,WAAW;QACxC,iBAAiB,EAAE,UAAU;QAC7B,iBAAiB,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;QACxC,QAAQ,EAAE,KAAK,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,+DAA+D,CAAC,CAAC,CAAC,CAAC,EAAE;KAChG,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { BudgetUsage, UsageDelta } from "./lifecycle.js";
|
|
2
|
+
import type { ModelTextResult, RunConfig } from "./schemas.js";
|
|
3
|
+
export declare class BudgetTracker {
|
|
4
|
+
private readonly config;
|
|
5
|
+
readonly usage: BudgetUsage;
|
|
6
|
+
private readonly prices;
|
|
7
|
+
constructor(config: RunConfig);
|
|
8
|
+
record(result: ModelTextResult, fallback?: {
|
|
9
|
+
provider?: string;
|
|
10
|
+
model: string;
|
|
11
|
+
calls?: number;
|
|
12
|
+
}): UsageDelta;
|
|
13
|
+
assertWithinBudget(phase: string): void;
|
|
14
|
+
private requirePrice;
|
|
15
|
+
private findPrice;
|
|
16
|
+
}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { BudgetExceededError, ConfigError } from "./errors.js";
|
|
2
|
+
import { emptyUsage } from "./lifecycle.js";
|
|
3
|
+
export class BudgetTracker {
|
|
4
|
+
config;
|
|
5
|
+
usage = emptyUsage();
|
|
6
|
+
prices;
|
|
7
|
+
constructor(config) {
|
|
8
|
+
this.config = config;
|
|
9
|
+
this.prices = config.budget?.prices ?? [];
|
|
10
|
+
if (config.budget?.maxUsd !== undefined && this.prices.length === 0) {
|
|
11
|
+
throw new ConfigError("Cannot enforce maxUsd without budget.prices.", {
|
|
12
|
+
code: "budget.price_missing",
|
|
13
|
+
fix: "Add budget.prices entries with inputUsdPerMillion and outputUsdPerMillion, or remove maxUsd."
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
record(result, fallback = { model: "unknown" }) {
|
|
18
|
+
const calls = fallback.calls ?? 1;
|
|
19
|
+
this.usage.calls += calls;
|
|
20
|
+
const inputCacheHitTokens = result.usage?.inputCacheHitTokens ?? 0;
|
|
21
|
+
const inputCacheMissTokens = result.usage?.inputCacheMissTokens ?? 0;
|
|
22
|
+
const inputTokens = result.usage?.inputTokens ?? inputCacheHitTokens + inputCacheMissTokens;
|
|
23
|
+
const outputTokens = result.usage?.outputTokens ?? 0;
|
|
24
|
+
const totalTokens = result.usage?.totalTokens ?? inputTokens + outputTokens;
|
|
25
|
+
this.usage.inputTokens += inputTokens;
|
|
26
|
+
if (result.usage?.inputCacheHitTokens !== undefined)
|
|
27
|
+
this.usage.inputCacheHitTokens = (this.usage.inputCacheHitTokens ?? 0) + inputCacheHitTokens;
|
|
28
|
+
if (result.usage?.inputCacheMissTokens !== undefined)
|
|
29
|
+
this.usage.inputCacheMissTokens = (this.usage.inputCacheMissTokens ?? 0) + inputCacheMissTokens;
|
|
30
|
+
this.usage.outputTokens += outputTokens;
|
|
31
|
+
this.usage.totalTokens += totalTokens;
|
|
32
|
+
const provider = result.provider ?? fallback.provider ?? this.config.provider;
|
|
33
|
+
const model = result.model ?? fallback.model;
|
|
34
|
+
const price = this.findPrice(provider, model);
|
|
35
|
+
let inputUsd;
|
|
36
|
+
let outputUsd;
|
|
37
|
+
if (price) {
|
|
38
|
+
if (this.config.budget?.maxUsd !== undefined)
|
|
39
|
+
this.requirePrice(provider, model);
|
|
40
|
+
inputUsd = inputUsdForUsage(price, {
|
|
41
|
+
inputTokens,
|
|
42
|
+
inputCacheHitTokens: result.usage?.inputCacheHitTokens,
|
|
43
|
+
inputCacheMissTokens: result.usage?.inputCacheMissTokens
|
|
44
|
+
});
|
|
45
|
+
outputUsd = (outputTokens / 1_000_000) * outputRateFor(price, inputTokens);
|
|
46
|
+
this.usage.usd = (this.usage.usd ?? 0) + inputUsd + outputUsd;
|
|
47
|
+
}
|
|
48
|
+
else if (this.config.budget?.maxUsd !== undefined) {
|
|
49
|
+
this.requirePrice(provider, model);
|
|
50
|
+
}
|
|
51
|
+
return {
|
|
52
|
+
calls,
|
|
53
|
+
inputTokens,
|
|
54
|
+
inputCacheHitTokens: result.usage?.inputCacheHitTokens,
|
|
55
|
+
inputCacheMissTokens: result.usage?.inputCacheMissTokens,
|
|
56
|
+
outputTokens,
|
|
57
|
+
totalTokens,
|
|
58
|
+
inputUsd,
|
|
59
|
+
outputUsd,
|
|
60
|
+
usd: inputUsd !== undefined && outputUsd !== undefined ? inputUsd + outputUsd : undefined
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
assertWithinBudget(phase) {
|
|
64
|
+
const budget = this.config.budget;
|
|
65
|
+
if (!budget)
|
|
66
|
+
return;
|
|
67
|
+
if (budget.maxCalls !== undefined && this.usage.calls > budget.maxCalls) {
|
|
68
|
+
throw new BudgetExceededError(`Budget exceeded after ${phase}: calls ${this.usage.calls} > maxCalls ${budget.maxCalls}.`, {
|
|
69
|
+
code: "budget.calls_exceeded",
|
|
70
|
+
fix: "Raise maxCalls or use a smaller profile."
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
if (budget.maxInputTokens !== undefined && this.usage.inputTokens > budget.maxInputTokens) {
|
|
74
|
+
throw new BudgetExceededError(`Budget exceeded after ${phase}: input tokens ${this.usage.inputTokens} > maxInputTokens ${budget.maxInputTokens}.`, {
|
|
75
|
+
code: "budget.input_tokens_exceeded",
|
|
76
|
+
fix: "Raise maxInputTokens, reduce concurrency, or use a smaller profile."
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
if (budget.maxOutputTokens !== undefined && this.usage.outputTokens > budget.maxOutputTokens) {
|
|
80
|
+
throw new BudgetExceededError(`Budget exceeded after ${phase}: output tokens ${this.usage.outputTokens} > maxOutputTokens ${budget.maxOutputTokens}.`, {
|
|
81
|
+
code: "budget.output_tokens_exceeded",
|
|
82
|
+
fix: "Raise maxOutputTokens, reduce concurrency, or use a smaller profile."
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
if (budget.maxUsd !== undefined && (this.usage.usd ?? 0) > budget.maxUsd) {
|
|
86
|
+
throw new BudgetExceededError(`Budget exceeded after ${phase}: estimated USD ${(this.usage.usd ?? 0).toFixed(6)} > maxUsd ${budget.maxUsd}.`, {
|
|
87
|
+
code: "budget.usd_exceeded",
|
|
88
|
+
fix: "Raise maxUsd, add cheaper models, or use a smaller profile."
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
requirePrice(provider, model) {
|
|
93
|
+
const price = this.findPrice(provider, model);
|
|
94
|
+
if (!price || !hasUsableInputPrice(price) || price.outputUsdPerMillion === undefined) {
|
|
95
|
+
throw new ConfigError(`Cannot enforce maxUsd without pricing for ${provider}/${model}.`, {
|
|
96
|
+
code: "budget.price_missing",
|
|
97
|
+
fix: "Add budget.prices entries with input/output prices, or remove maxUsd."
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
return price;
|
|
101
|
+
}
|
|
102
|
+
findPrice(provider, model) {
|
|
103
|
+
return this.prices.find((entry) => entry.provider === provider && entry.model === model);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
function inputUsdForUsage(price, usage) {
|
|
107
|
+
// Cache hit/miss rates are flat in v0.1 — long-context tier does not apply when the provider
|
|
108
|
+
// reports prompt_cache_hit_tokens / prompt_cache_miss_tokens. Real pricing tables for tiered
|
|
109
|
+
// models (Gemini, GPT-5.4) rarely tier their cache rates, and DeepSeek does not have long-context tiers today.
|
|
110
|
+
if (usage.inputCacheHitTokens !== undefined && usage.inputCacheMissTokens !== undefined) {
|
|
111
|
+
const hit = (usage.inputCacheHitTokens / 1_000_000) * (price.inputCacheHitUsdPerMillion ?? price.inputUsdPerMillion ?? 0);
|
|
112
|
+
const miss = (usage.inputCacheMissTokens / 1_000_000) * (price.inputCacheMissUsdPerMillion ?? price.inputUsdPerMillion ?? 0);
|
|
113
|
+
return hit + miss;
|
|
114
|
+
}
|
|
115
|
+
const rate = isLongContext(price, usage.inputTokens)
|
|
116
|
+
? (price.inputUsdPerMillionLong ?? price.inputUsdPerMillion ?? 0)
|
|
117
|
+
: (price.inputUsdPerMillion ?? price.inputCacheMissUsdPerMillion ?? 0);
|
|
118
|
+
return (usage.inputTokens / 1_000_000) * rate;
|
|
119
|
+
}
|
|
120
|
+
function outputRateFor(price, inputTokens) {
|
|
121
|
+
return isLongContext(price, inputTokens)
|
|
122
|
+
? (price.outputUsdPerMillionLong ?? price.outputUsdPerMillion ?? 0)
|
|
123
|
+
: (price.outputUsdPerMillion ?? 0);
|
|
124
|
+
}
|
|
125
|
+
function isLongContext(price, inputTokens) {
|
|
126
|
+
if (price.longContextThresholdTokens === undefined)
|
|
127
|
+
return false;
|
|
128
|
+
if (price.inputUsdPerMillionLong === undefined && price.outputUsdPerMillionLong === undefined)
|
|
129
|
+
return false;
|
|
130
|
+
return inputTokens > price.longContextThresholdTokens;
|
|
131
|
+
}
|
|
132
|
+
function hasUsableInputPrice(price) {
|
|
133
|
+
return (price.inputUsdPerMillion !== undefined ||
|
|
134
|
+
price.inputCacheMissUsdPerMillion !== undefined ||
|
|
135
|
+
price.inputCacheHitUsdPerMillion !== undefined);
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=budgetTracker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"budgetTracker.js","sourceRoot":"","sources":["../src/budgetTracker.ts"],"names":[],"mappings":"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"}
|
package/dist/critique.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export function aggregateCritiques(candidates, comparisons) {
|
|
2
|
+
const chunks = new Map(candidates.map((candidate) => [
|
|
3
|
+
candidate.id,
|
|
4
|
+
{
|
|
5
|
+
wins: [],
|
|
6
|
+
ties: [],
|
|
7
|
+
losses: []
|
|
8
|
+
}
|
|
9
|
+
]));
|
|
10
|
+
for (const comparison of comparisons) {
|
|
11
|
+
const aBucket = bucketFor("A", comparison.winner);
|
|
12
|
+
const bBucket = bucketFor("B", comparison.winner);
|
|
13
|
+
chunks.get(comparison.presentedAOriginalId)?.[aBucket].push(selfRelative(comparison.critiqueForA, "A"));
|
|
14
|
+
chunks.get(comparison.presentedBOriginalId)?.[bBucket].push(selfRelative(comparison.critiqueForB, "B"));
|
|
15
|
+
}
|
|
16
|
+
return new Map([...chunks.entries()].map(([id, critiques]) => [
|
|
17
|
+
id,
|
|
18
|
+
[...critiques.wins, ...critiques.ties, ...critiques.losses].filter(Boolean).length > 0
|
|
19
|
+
? [
|
|
20
|
+
formatSection("Feedback from comparisons this solution won", critiques.wins),
|
|
21
|
+
formatSection("Feedback from comparisons this solution tied", critiques.ties),
|
|
22
|
+
formatSection("Feedback from comparisons this solution lost", critiques.losses)
|
|
23
|
+
]
|
|
24
|
+
.filter(Boolean)
|
|
25
|
+
.join("\n\n")
|
|
26
|
+
: "No specific critique was produced. Improve correctness, completeness, and clarity."
|
|
27
|
+
]));
|
|
28
|
+
}
|
|
29
|
+
function bucketFor(side, winner) {
|
|
30
|
+
if (winner === "tie")
|
|
31
|
+
return "ties";
|
|
32
|
+
return winner === side ? "wins" : "losses";
|
|
33
|
+
}
|
|
34
|
+
function formatSection(title, critiques) {
|
|
35
|
+
const filtered = critiques.filter(Boolean);
|
|
36
|
+
if (filtered.length === 0)
|
|
37
|
+
return "";
|
|
38
|
+
return `${title}:\n${filtered.map((critique, i) => `${i + 1}. ${critique}`).join("\n")}`;
|
|
39
|
+
}
|
|
40
|
+
function selfRelative(text, side) {
|
|
41
|
+
const other = side === "A" ? "B" : "A";
|
|
42
|
+
return text
|
|
43
|
+
.replaceAll(`Solution ${side}`, "your solution")
|
|
44
|
+
.replaceAll(`solution ${side}`, "your solution")
|
|
45
|
+
.replaceAll(`Candidate ${side}`, "your solution")
|
|
46
|
+
.replaceAll(`candidate ${side}`, "your solution")
|
|
47
|
+
.replaceAll(`Solution ${other}`, "the other solution")
|
|
48
|
+
.replaceAll(`solution ${other}`, "the other solution")
|
|
49
|
+
.replaceAll(`Candidate ${other}`, "the other solution")
|
|
50
|
+
.replaceAll(`candidate ${other}`, "the other solution");
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=critique.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"critique.js","sourceRoot":"","sources":["../src/critique.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export declare class DeepThonkError extends Error {
|
|
2
|
+
readonly code: string;
|
|
3
|
+
readonly retryable: boolean;
|
|
4
|
+
readonly fix?: string;
|
|
5
|
+
constructor(message: string, options?: {
|
|
6
|
+
code?: string;
|
|
7
|
+
retryable?: boolean;
|
|
8
|
+
fix?: string;
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
export declare class ConfigError extends DeepThonkError {
|
|
12
|
+
}
|
|
13
|
+
export declare class ProviderError extends DeepThonkError {
|
|
14
|
+
}
|
|
15
|
+
export declare class JsonParseError extends DeepThonkError {
|
|
16
|
+
}
|
|
17
|
+
export declare class BudgetExceededError extends DeepThonkError {
|
|
18
|
+
}
|
|
19
|
+
export declare class CancelledError extends DeepThonkError {
|
|
20
|
+
}
|
|
21
|
+
export declare class TraceError extends DeepThonkError {
|
|
22
|
+
}
|
|
23
|
+
export declare class McpToolError extends DeepThonkError {
|
|
24
|
+
}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export class DeepThonkError extends Error {
|
|
2
|
+
code;
|
|
3
|
+
retryable;
|
|
4
|
+
fix;
|
|
5
|
+
constructor(message, options = {}) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.name = new.target.name;
|
|
8
|
+
this.code = options.code ?? this.name;
|
|
9
|
+
this.retryable = options.retryable ?? false;
|
|
10
|
+
this.fix = options.fix;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export class ConfigError extends DeepThonkError {
|
|
14
|
+
}
|
|
15
|
+
export class ProviderError extends DeepThonkError {
|
|
16
|
+
}
|
|
17
|
+
export class JsonParseError extends DeepThonkError {
|
|
18
|
+
}
|
|
19
|
+
export class BudgetExceededError extends DeepThonkError {
|
|
20
|
+
}
|
|
21
|
+
export class CancelledError extends DeepThonkError {
|
|
22
|
+
}
|
|
23
|
+
export class TraceError extends DeepThonkError {
|
|
24
|
+
}
|
|
25
|
+
export class McpToolError extends DeepThonkError {
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,cAAe,SAAQ,KAAK;IAC9B,IAAI,CAAS;IACb,SAAS,CAAU;IACnB,GAAG,CAAU;IAEtB,YAAY,OAAe,EAAE,UAAgE,EAAE;QAC7F,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;QAC5B,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC;QACtC,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,KAAK,CAAC;QAC5C,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;IACzB,CAAC;CACF;AAED,MAAM,OAAO,WAAY,SAAQ,cAAc;CAAG;AAClD,MAAM,OAAO,aAAc,SAAQ,cAAc;CAAG;AACpD,MAAM,OAAO,cAAe,SAAQ,cAAc;CAAG;AACrD,MAAM,OAAO,mBAAoB,SAAQ,cAAc;CAAG;AAC1D,MAAM,OAAO,cAAe,SAAQ,cAAc;CAAG;AACrD,MAAM,OAAO,UAAW,SAAQ,cAAc;CAAG;AACjD,MAAM,OAAO,YAAa,SAAQ,cAAc;CAAG"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export * from "./bradleyTerry.js";
|
|
2
|
+
export * from "./artifacts.js";
|
|
3
|
+
export * from "./budget.js";
|
|
4
|
+
export * from "./budgetTracker.js";
|
|
5
|
+
export * from "./critique.js";
|
|
6
|
+
export * from "./errors.js";
|
|
7
|
+
export * from "./json.js";
|
|
8
|
+
export * from "./lifecycle.js";
|
|
9
|
+
export * from "./pairScheduler.js";
|
|
10
|
+
export * from "./prompts.js";
|
|
11
|
+
export * from "./rng.js";
|
|
12
|
+
export * from "./runner.js";
|
|
13
|
+
export * from "./schemas.js";
|
|
14
|
+
export * from "./services.js";
|
|
15
|
+
export * from "./traceStore.js";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export * from "./bradleyTerry.js";
|
|
2
|
+
export * from "./artifacts.js";
|
|
3
|
+
export * from "./budget.js";
|
|
4
|
+
export * from "./budgetTracker.js";
|
|
5
|
+
export * from "./critique.js";
|
|
6
|
+
export * from "./errors.js";
|
|
7
|
+
export * from "./json.js";
|
|
8
|
+
export * from "./lifecycle.js";
|
|
9
|
+
export * from "./pairScheduler.js";
|
|
10
|
+
export * from "./prompts.js";
|
|
11
|
+
export * from "./rng.js";
|
|
12
|
+
export * from "./runner.js";
|
|
13
|
+
export * from "./schemas.js";
|
|
14
|
+
export * from "./services.js";
|
|
15
|
+
export * from "./traceStore.js";
|
|
16
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC"}
|
package/dist/json.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function parseJsonObject(text: string): unknown;
|
package/dist/json.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { JsonParseError } from "./errors.js";
|
|
2
|
+
export function parseJsonObject(text) {
|
|
3
|
+
const trimmed = text.trim();
|
|
4
|
+
const candidates = [trimmed, extractFence(trimmed), extractBalancedObject(trimmed)].filter((candidate) => Boolean(candidate));
|
|
5
|
+
for (const candidate of candidates) {
|
|
6
|
+
try {
|
|
7
|
+
const parsed = JSON.parse(candidate);
|
|
8
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed))
|
|
9
|
+
return parsed;
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
// Try the next extraction strategy.
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
throw new JsonParseError("Model output did not contain a valid JSON object.");
|
|
16
|
+
}
|
|
17
|
+
function extractFence(text) {
|
|
18
|
+
const match = text.match(/```(?:json)?\s*([\s\S]*?)```/i);
|
|
19
|
+
return match?.[1]?.trim();
|
|
20
|
+
}
|
|
21
|
+
function extractBalancedObject(text) {
|
|
22
|
+
const start = text.indexOf("{");
|
|
23
|
+
const end = text.lastIndexOf("}");
|
|
24
|
+
if (start === -1 || end === -1 || end <= start)
|
|
25
|
+
return undefined;
|
|
26
|
+
return text.slice(start, end + 1);
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=json.js.map
|
package/dist/json.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json.js","sourceRoot":"","sources":["../src/json.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,MAAM,UAAU,GAAG,CAAC,OAAO,EAAE,YAAY,CAAC,OAAO,CAAC,EAAE,qBAAqB,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CACxF,CAAC,SAAS,EAAuB,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,CACvD,CAAC;IACF,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;YACrC,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;gBAAE,OAAO,MAAM,CAAC;QACpF,CAAC;QAAC,MAAM,CAAC;YACP,oCAAoC;QACtC,CAAC;IACH,CAAC;IACD,MAAM,IAAI,cAAc,CAAC,mDAAmD,CAAC,CAAC;AAChF,CAAC;AAED,SAAS,YAAY,CAAC,IAAY;IAChC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;IAC1D,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;AAC5B,CAAC;AAED,SAAS,qBAAqB,CAAC,IAAY;IACzC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAChC,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,KAAK,KAAK,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,IAAI,GAAG,IAAI,KAAK;QAAE,OAAO,SAAS,CAAC;IACjE,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC;AACpC,CAAC"}
|