@warmdrift/kgauto-compiler 2.0.0-alpha.3 → 2.0.0-alpha.31
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/README.md +87 -3
- package/dist/chunk-JQGRWJZO.mjs +1216 -0
- package/dist/chunk-NBO4R5PC.mjs +313 -0
- package/dist/chunk-RO22VFIF.mjs +29 -0
- package/dist/chunk-WXCFWUCN.mjs +678 -0
- package/dist/glassbox/index.d.mts +59 -0
- package/dist/glassbox/index.d.ts +59 -0
- package/dist/glassbox/index.js +312 -0
- package/dist/glassbox/index.mjs +12 -0
- package/dist/glassbox-routes/index.d.mts +242 -0
- package/dist/glassbox-routes/index.d.ts +242 -0
- package/dist/glassbox-routes/index.js +2458 -0
- package/dist/glassbox-routes/index.mjs +658 -0
- package/dist/index.d.mts +1195 -11
- package/dist/index.d.ts +1195 -11
- package/dist/index.js +3503 -236
- package/dist/index.mjs +1588 -78
- package/dist/ir-BIAT9gJk.d.ts +1031 -0
- package/dist/ir-De2AQtlr.d.mts +1031 -0
- package/dist/profiles.d.mts +137 -2
- package/dist/profiles.d.ts +137 -2
- package/dist/profiles.js +820 -11
- package/dist/profiles.mjs +5 -1
- package/dist/types-BjrIFPGe.d.mts +131 -0
- package/dist/types-D_JAhCv4.d.ts +131 -0
- package/package.json +12 -2
- package/dist/chunk-MBEI5UOM.mjs +0 -409
- package/dist/profiles-BiyrF36f.d.mts +0 -489
- package/dist/profiles-C5lVqF8_.d.ts +0 -489
|
@@ -0,0 +1,658 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ARCHETYPE_FLOOR_DEFAULT,
|
|
3
|
+
getDefaultFallbackChain
|
|
4
|
+
} from "../chunk-WXCFWUCN.mjs";
|
|
5
|
+
import {
|
|
6
|
+
tryGetProfile
|
|
7
|
+
} from "../chunk-JQGRWJZO.mjs";
|
|
8
|
+
import {
|
|
9
|
+
subscribe,
|
|
10
|
+
subscribeApp
|
|
11
|
+
} from "../chunk-RO22VFIF.mjs";
|
|
12
|
+
import "../chunk-NBO4R5PC.mjs";
|
|
13
|
+
|
|
14
|
+
// src/glassbox-routes/auth.ts
|
|
15
|
+
var JSON_HEADERS = { "Content-Type": "application/json" };
|
|
16
|
+
function jsonError(status, code) {
|
|
17
|
+
return new Response(JSON.stringify({ error: code }), {
|
|
18
|
+
status,
|
|
19
|
+
headers: JSON_HEADERS
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
function tokensEqual(a, b) {
|
|
23
|
+
if (a.length !== b.length) return false;
|
|
24
|
+
let mismatch = 0;
|
|
25
|
+
for (let i = 0; i < a.length; i++) {
|
|
26
|
+
mismatch |= a.charCodeAt(i) ^ b.charCodeAt(i);
|
|
27
|
+
}
|
|
28
|
+
return mismatch === 0;
|
|
29
|
+
}
|
|
30
|
+
function checkAuth(req, config) {
|
|
31
|
+
const authHeader = req.headers.get("Authorization") ?? "";
|
|
32
|
+
const match = /^Bearer\s+(.+)$/i.exec(authHeader);
|
|
33
|
+
const provided = match?.[1]?.trim() ?? "";
|
|
34
|
+
if (!provided || !tokensEqual(provided, config.installToken)) {
|
|
35
|
+
return jsonError(401, "unauthorized");
|
|
36
|
+
}
|
|
37
|
+
const origin = req.headers.get("Origin") ?? "";
|
|
38
|
+
const xExtId = req.headers.get("X-Glassbox-Extension-Id") ?? "";
|
|
39
|
+
const expectedOrigin = `chrome-extension://${config.extensionId}`;
|
|
40
|
+
const originOk = origin === expectedOrigin;
|
|
41
|
+
const xExtOk = xExtId.length > 0 && tokensEqual(xExtId, config.extensionId);
|
|
42
|
+
if (!originOk && !xExtOk) {
|
|
43
|
+
return jsonError(403, "forbidden_origin");
|
|
44
|
+
}
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// src/glassbox-routes/counterfactuals.ts
|
|
49
|
+
var COUNTERFACTUAL_MIN_SAVINGS_RATIO = 0.1;
|
|
50
|
+
var COUNTERFACTUAL_MAX_RESULTS = 2;
|
|
51
|
+
function computeCounterfactuals(args) {
|
|
52
|
+
const {
|
|
53
|
+
servedModel,
|
|
54
|
+
servedCostUsd,
|
|
55
|
+
archetype,
|
|
56
|
+
tokensIn,
|
|
57
|
+
tokensOut,
|
|
58
|
+
cacheReadInputTokens = 0,
|
|
59
|
+
toolOrchestration
|
|
60
|
+
} = args;
|
|
61
|
+
if (tokensIn <= 0) return [];
|
|
62
|
+
if (servedCostUsd <= 0) return [];
|
|
63
|
+
let chain;
|
|
64
|
+
try {
|
|
65
|
+
chain = getDefaultFallbackChain({
|
|
66
|
+
archetype,
|
|
67
|
+
posture: "open",
|
|
68
|
+
maxDepth: 10,
|
|
69
|
+
toolOrchestration
|
|
70
|
+
});
|
|
71
|
+
} catch {
|
|
72
|
+
return [];
|
|
73
|
+
}
|
|
74
|
+
const candidates = [];
|
|
75
|
+
const minSavings = servedCostUsd * COUNTERFACTUAL_MIN_SAVINGS_RATIO;
|
|
76
|
+
for (const modelId of chain) {
|
|
77
|
+
if (modelId === servedModel) continue;
|
|
78
|
+
const profile = tryGetProfile(modelId);
|
|
79
|
+
if (!profile) continue;
|
|
80
|
+
const perf = profile.archetypePerf?.[archetype] ?? 5;
|
|
81
|
+
if (perf < ARCHETYPE_FLOOR_DEFAULT) continue;
|
|
82
|
+
const estimated = estimateCostUsd({
|
|
83
|
+
profile,
|
|
84
|
+
tokensIn,
|
|
85
|
+
tokensOut,
|
|
86
|
+
cacheReadInputTokens
|
|
87
|
+
});
|
|
88
|
+
if (estimated === void 0) continue;
|
|
89
|
+
const savings = servedCostUsd - estimated;
|
|
90
|
+
if (savings < minSavings) continue;
|
|
91
|
+
const savingsPercent = Math.round(savings / servedCostUsd * 100);
|
|
92
|
+
const reason = buildReason({
|
|
93
|
+
modelId,
|
|
94
|
+
archetype,
|
|
95
|
+
perf,
|
|
96
|
+
profile
|
|
97
|
+
});
|
|
98
|
+
candidates.push({
|
|
99
|
+
modelId,
|
|
100
|
+
estimatedCostUsd: round6(estimated),
|
|
101
|
+
savingsUsd: round6(savings),
|
|
102
|
+
savingsPercent,
|
|
103
|
+
reason
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
candidates.sort((a, b) => a.estimatedCostUsd - b.estimatedCostUsd);
|
|
107
|
+
return candidates.slice(0, COUNTERFACTUAL_MAX_RESULTS);
|
|
108
|
+
}
|
|
109
|
+
function estimateCostUsd(args) {
|
|
110
|
+
const { profile, tokensIn, tokensOut, cacheReadInputTokens } = args;
|
|
111
|
+
const cacheableIn = Math.min(cacheReadInputTokens, tokensIn);
|
|
112
|
+
const nonCachedIn = Math.max(tokensIn - cacheableIn, 0);
|
|
113
|
+
const discount = profile.lowering.cache.discount ?? 1;
|
|
114
|
+
const inUsd = nonCachedIn / 1e6 * profile.costInputPer1m + cacheableIn / 1e6 * profile.costInputPer1m * discount;
|
|
115
|
+
const outUsd = tokensOut / 1e6 * profile.costOutputPer1m;
|
|
116
|
+
const total = inUsd + outUsd;
|
|
117
|
+
if (!Number.isFinite(total)) return void 0;
|
|
118
|
+
if (total < 0) return void 0;
|
|
119
|
+
return total;
|
|
120
|
+
}
|
|
121
|
+
function round6(n) {
|
|
122
|
+
return Math.round(n * 1e6) / 1e6;
|
|
123
|
+
}
|
|
124
|
+
function buildReason(args) {
|
|
125
|
+
const { modelId, archetype, perf, profile } = args;
|
|
126
|
+
const hook = profile.strengths?.[0];
|
|
127
|
+
const suffix = hook ? `, ${hook.replace(/_/g, " ")}` : "";
|
|
128
|
+
return `${modelId} on ${archetype}: archetypePerf=${perf}${suffix}`;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// src/glassbox-routes/projected-cost.ts
|
|
132
|
+
var INSUFFICIENT_VOLUME_THRESHOLD = 5;
|
|
133
|
+
var WINDOW_DAYS = 7;
|
|
134
|
+
async function computeProjectedDailyCost(args) {
|
|
135
|
+
const {
|
|
136
|
+
appId,
|
|
137
|
+
archetype,
|
|
138
|
+
servedCostUsd,
|
|
139
|
+
brainEndpoint,
|
|
140
|
+
brainJwt,
|
|
141
|
+
brainAnonKey,
|
|
142
|
+
fetch: fetchImpl
|
|
143
|
+
} = args;
|
|
144
|
+
if (!appId || !archetype) return void 0;
|
|
145
|
+
if (!Number.isFinite(servedCostUsd) || servedCostUsd <= 0) return void 0;
|
|
146
|
+
const doFetch = fetchImpl ?? ((...a) => globalThis.fetch(...a));
|
|
147
|
+
const base = brainEndpoint.replace(/\/+$/, "");
|
|
148
|
+
const cutoffIso = new Date(
|
|
149
|
+
Date.now() - WINDOW_DAYS * 24 * 60 * 60 * 1e3
|
|
150
|
+
).toISOString();
|
|
151
|
+
const qs = new URLSearchParams();
|
|
152
|
+
qs.set("app_id", `eq.${appId}`);
|
|
153
|
+
qs.set("intent_archetype", `eq.${archetype}`);
|
|
154
|
+
qs.set("created_at", `gte.${cutoffIso}`);
|
|
155
|
+
qs.set("select", "handle");
|
|
156
|
+
qs.set("limit", "0");
|
|
157
|
+
const url = `${base}/rest/v1/compile_outcomes?${qs.toString()}`;
|
|
158
|
+
let res;
|
|
159
|
+
try {
|
|
160
|
+
res = await doFetch(url, {
|
|
161
|
+
method: "GET",
|
|
162
|
+
headers: {
|
|
163
|
+
Authorization: `Bearer ${brainJwt}`,
|
|
164
|
+
apikey: brainAnonKey,
|
|
165
|
+
Accept: "application/json",
|
|
166
|
+
// Triggers PostgREST exact count in Content-Range header.
|
|
167
|
+
Prefer: "count=exact"
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
} catch {
|
|
171
|
+
return void 0;
|
|
172
|
+
}
|
|
173
|
+
if (!res.ok) return void 0;
|
|
174
|
+
const contentRange = res.headers.get("content-range");
|
|
175
|
+
const count = parseContentRangeCount(contentRange);
|
|
176
|
+
if (count === void 0) return void 0;
|
|
177
|
+
const avgPerDay = count / WINDOW_DAYS;
|
|
178
|
+
if (avgPerDay < INSUFFICIENT_VOLUME_THRESHOLD) return void 0;
|
|
179
|
+
const projected = avgPerDay * servedCostUsd;
|
|
180
|
+
return Math.round(projected * 1e6) / 1e6;
|
|
181
|
+
}
|
|
182
|
+
function parseContentRangeCount(header) {
|
|
183
|
+
if (!header) return void 0;
|
|
184
|
+
const slash = header.lastIndexOf("/");
|
|
185
|
+
if (slash < 0) return void 0;
|
|
186
|
+
const tail = header.slice(slash + 1).trim();
|
|
187
|
+
if (tail === "*" || tail === "") return void 0;
|
|
188
|
+
const n = Number.parseInt(tail, 10);
|
|
189
|
+
if (!Number.isFinite(n) || n < 0) return void 0;
|
|
190
|
+
return n;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// src/glassbox-routes/proxy.ts
|
|
194
|
+
var JSON_HEADERS2 = {
|
|
195
|
+
"Content-Type": "application/json",
|
|
196
|
+
"Cache-Control": "no-store"
|
|
197
|
+
};
|
|
198
|
+
var DEFAULT_LIMIT = 20;
|
|
199
|
+
var MAX_LIMIT = 100;
|
|
200
|
+
function jsonResponse(status, body) {
|
|
201
|
+
return new Response(JSON.stringify(body), { status, headers: JSON_HEADERS2 });
|
|
202
|
+
}
|
|
203
|
+
function jsonError2(status, code) {
|
|
204
|
+
return jsonResponse(status, { error: code });
|
|
205
|
+
}
|
|
206
|
+
function applyScrub(row, scrub) {
|
|
207
|
+
if (!scrub || row == null || typeof row !== "object") return row;
|
|
208
|
+
try {
|
|
209
|
+
return scrub(row);
|
|
210
|
+
} catch {
|
|
211
|
+
return row;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
function parseLimit(raw) {
|
|
215
|
+
if (!raw) return DEFAULT_LIMIT;
|
|
216
|
+
const n = Number.parseInt(raw, 10);
|
|
217
|
+
if (!Number.isFinite(n) || n <= 0) return DEFAULT_LIMIT;
|
|
218
|
+
return Math.min(n, MAX_LIMIT);
|
|
219
|
+
}
|
|
220
|
+
function rowToSummary(row) {
|
|
221
|
+
return {
|
|
222
|
+
traceId: typeof row.handle === "string" ? row.handle : "",
|
|
223
|
+
appId: typeof row.app_id === "string" ? row.app_id : "",
|
|
224
|
+
archetype: typeof row.intent_archetype === "string" ? row.intent_archetype : "",
|
|
225
|
+
target: typeof row.model === "string" ? row.model : "",
|
|
226
|
+
createdAt: typeof row.created_at === "string" ? row.created_at : "",
|
|
227
|
+
tokensIn: typeof row.tokens_in === "number" ? row.tokens_in : 0,
|
|
228
|
+
tokensOut: typeof row.tokens_out === "number" ? row.tokens_out : 0,
|
|
229
|
+
estimatedCostUsd: typeof row.cost_usd_actual === "number" ? row.cost_usd_actual : 0
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
var INPUT_RATIO_YELLOW = 0.65;
|
|
233
|
+
var INPUT_RATIO_RED = 0.85;
|
|
234
|
+
var CACHE_HEALTH_MIN_TOKENS = 1e3;
|
|
235
|
+
var CACHE_RATIO_GREEN = 0.5;
|
|
236
|
+
var CACHE_RATIO_YELLOW = 0.1;
|
|
237
|
+
var FALLBACK_REASONS = /* @__PURE__ */ new Set([
|
|
238
|
+
"rate_limit",
|
|
239
|
+
"provider_auth_failed",
|
|
240
|
+
"provider_error",
|
|
241
|
+
"cliff",
|
|
242
|
+
"cost_cap",
|
|
243
|
+
"contract_violation"
|
|
244
|
+
]);
|
|
245
|
+
function asString(v) {
|
|
246
|
+
return typeof v === "string" && v.length > 0 ? v : void 0;
|
|
247
|
+
}
|
|
248
|
+
function asNumber(v) {
|
|
249
|
+
return typeof v === "number" && Number.isFinite(v) ? v : void 0;
|
|
250
|
+
}
|
|
251
|
+
function asNumberOrZero(v) {
|
|
252
|
+
return typeof v === "number" && Number.isFinite(v) ? v : 0;
|
|
253
|
+
}
|
|
254
|
+
function asStringArray(v) {
|
|
255
|
+
if (!Array.isArray(v)) return [];
|
|
256
|
+
const out = [];
|
|
257
|
+
for (const e of v) {
|
|
258
|
+
if (typeof e === "string") out.push(e);
|
|
259
|
+
}
|
|
260
|
+
return out;
|
|
261
|
+
}
|
|
262
|
+
function asFallbackReason(v) {
|
|
263
|
+
if (typeof v !== "string") return void 0;
|
|
264
|
+
const candidate = v;
|
|
265
|
+
if (candidate && FALLBACK_REASONS.has(candidate)) return candidate;
|
|
266
|
+
return "provider_error";
|
|
267
|
+
}
|
|
268
|
+
function rowToAdvisory(raw) {
|
|
269
|
+
if (!raw || typeof raw !== "object") return void 0;
|
|
270
|
+
const r = raw;
|
|
271
|
+
const level = r.level;
|
|
272
|
+
const code = r.code;
|
|
273
|
+
const message = r.message;
|
|
274
|
+
if (level !== "info" && level !== "warn" && level !== "critical" || typeof code !== "string" || typeof message !== "string") {
|
|
275
|
+
return void 0;
|
|
276
|
+
}
|
|
277
|
+
const out = { level, code, message };
|
|
278
|
+
const suggestion = asString(r.suggestion);
|
|
279
|
+
if (suggestion) out.suggestion = suggestion;
|
|
280
|
+
const docsUrl = asString(r.docs_url ?? r.docsUrl);
|
|
281
|
+
if (docsUrl) out.docsUrl = docsUrl;
|
|
282
|
+
const adapter = toAdapter(r.suggested_adaptation ?? r.suggestedAdaptation);
|
|
283
|
+
if (adapter) out.suggestedAdaptation = adapter;
|
|
284
|
+
return out;
|
|
285
|
+
}
|
|
286
|
+
var SECTION_KINDS = /* @__PURE__ */ new Set([
|
|
287
|
+
"role_intro",
|
|
288
|
+
"tool_call_contract",
|
|
289
|
+
"narration_contract",
|
|
290
|
+
"user_turn",
|
|
291
|
+
"reference",
|
|
292
|
+
"arbitrary"
|
|
293
|
+
]);
|
|
294
|
+
function summarizeSectionRewrite(kind, rule) {
|
|
295
|
+
if (kind === "tool_call_contract" && rule === "sequential-tool-cliff-below-floor") {
|
|
296
|
+
return "Sequential tool pattern applied (model cliff cleared at compile time).";
|
|
297
|
+
}
|
|
298
|
+
if (kind === "narration_contract" && rule === "narration-drift-anthropic") {
|
|
299
|
+
return "Narration tightened for Anthropic dialect (terse-log shape preserved).";
|
|
300
|
+
}
|
|
301
|
+
if (kind === "narration_contract" && rule === "narration-thinking-leak-deepseek") {
|
|
302
|
+
return "Thinking-block suppression applied (DeepSeek V4 internal reasoning kept off-wire).";
|
|
303
|
+
}
|
|
304
|
+
return `Translator applied rule "${rule}" to ${kind} section.`;
|
|
305
|
+
}
|
|
306
|
+
function rowToSectionRewrite(raw) {
|
|
307
|
+
if (!raw || typeof raw !== "object") return void 0;
|
|
308
|
+
const r = raw;
|
|
309
|
+
const sectionId = r.sectionId ?? r.section_id;
|
|
310
|
+
if (typeof sectionId !== "string" || sectionId.length === 0) return void 0;
|
|
311
|
+
const kind = r.kind;
|
|
312
|
+
if (typeof kind !== "string" || !SECTION_KINDS.has(kind)) {
|
|
313
|
+
return void 0;
|
|
314
|
+
}
|
|
315
|
+
const rule = r.rule;
|
|
316
|
+
if (typeof rule !== "string" || rule.length === 0) return void 0;
|
|
317
|
+
return {
|
|
318
|
+
sectionId,
|
|
319
|
+
kind,
|
|
320
|
+
rule,
|
|
321
|
+
summary: summarizeSectionRewrite(kind, rule)
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
function toAdapter(raw) {
|
|
325
|
+
if (!raw || typeof raw !== "object") return void 0;
|
|
326
|
+
const a = raw;
|
|
327
|
+
if (a.parameter === "toolOrchestration" && a.value === "sequential" && typeof a.consequence === "string") {
|
|
328
|
+
return {
|
|
329
|
+
parameter: "toolOrchestration",
|
|
330
|
+
value: "sequential",
|
|
331
|
+
consequence: a.consequence
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
return void 0;
|
|
335
|
+
}
|
|
336
|
+
function computeHealth(args) {
|
|
337
|
+
const {
|
|
338
|
+
tokensIn,
|
|
339
|
+
tokensOut,
|
|
340
|
+
historyCacheableTokens,
|
|
341
|
+
inputCacheHitRatio,
|
|
342
|
+
fellOverFrom,
|
|
343
|
+
target
|
|
344
|
+
} = args;
|
|
345
|
+
const total = tokensIn + tokensOut;
|
|
346
|
+
const ratio = total > 0 ? tokensIn / total : 0;
|
|
347
|
+
let inputRatioStatus;
|
|
348
|
+
if (ratio > INPUT_RATIO_RED) inputRatioStatus = "red";
|
|
349
|
+
else if (ratio > INPUT_RATIO_YELLOW) inputRatioStatus = "yellow";
|
|
350
|
+
else inputRatioStatus = "green";
|
|
351
|
+
let cacheStatus;
|
|
352
|
+
if (historyCacheableTokens <= CACHE_HEALTH_MIN_TOKENS) {
|
|
353
|
+
cacheStatus = "na";
|
|
354
|
+
} else if (inputCacheHitRatio >= CACHE_RATIO_GREEN) {
|
|
355
|
+
cacheStatus = "green";
|
|
356
|
+
} else if (inputCacheHitRatio >= CACHE_RATIO_YELLOW) {
|
|
357
|
+
cacheStatus = "yellow";
|
|
358
|
+
} else {
|
|
359
|
+
cacheStatus = "red";
|
|
360
|
+
}
|
|
361
|
+
const fallbackStatus = fellOverFrom !== void 0 && fellOverFrom !== target ? "red" : "green";
|
|
362
|
+
return { inputRatioStatus, cacheStatus, fallbackStatus };
|
|
363
|
+
}
|
|
364
|
+
function rowToDetail(row) {
|
|
365
|
+
const summary = rowToSummary(row);
|
|
366
|
+
const tokensIn = summary.tokensIn;
|
|
367
|
+
const tokensOut = summary.tokensOut;
|
|
368
|
+
const cacheReadInputTokens = asNumberOrZero(row.cache_read_input_tokens);
|
|
369
|
+
const cacheCreationInputTokens = asNumberOrZero(
|
|
370
|
+
row.cache_creation_input_tokens
|
|
371
|
+
);
|
|
372
|
+
const historyCacheableTokens = asNumberOrZero(row.history_cacheable_tokens);
|
|
373
|
+
const inputCacheHitRatio = tokensIn > 0 ? cacheReadInputTokens / tokensIn : 0;
|
|
374
|
+
const fellOverFrom = asString(row.fell_over_from);
|
|
375
|
+
const fallbackReasonRaw = row.fallback_reason;
|
|
376
|
+
const fallbackReason = fellOverFrom ? asFallbackReason(fallbackReasonRaw) : void 0;
|
|
377
|
+
const requestedModel = asString(row.requested_model) ?? fellOverFrom;
|
|
378
|
+
const advisoriesRaw = Array.isArray(row.advisories) ? row.advisories : [];
|
|
379
|
+
const advisories = [];
|
|
380
|
+
for (const a of advisoriesRaw) {
|
|
381
|
+
const rec = rowToAdvisory(a);
|
|
382
|
+
if (rec) advisories.push(rec);
|
|
383
|
+
}
|
|
384
|
+
const health = computeHealth({
|
|
385
|
+
tokensIn,
|
|
386
|
+
tokensOut,
|
|
387
|
+
cacheReadInputTokens,
|
|
388
|
+
historyCacheableTokens,
|
|
389
|
+
inputCacheHitRatio,
|
|
390
|
+
fellOverFrom,
|
|
391
|
+
target: summary.target
|
|
392
|
+
});
|
|
393
|
+
const sectionRewritesRaw = Array.isArray(row.section_rewrites_applied) ? row.section_rewrites_applied : [];
|
|
394
|
+
const sectionRewritesApplied = [];
|
|
395
|
+
for (const e of sectionRewritesRaw) {
|
|
396
|
+
const rw = rowToSectionRewrite(e);
|
|
397
|
+
if (rw) sectionRewritesApplied.push(rw);
|
|
398
|
+
}
|
|
399
|
+
const detail = {
|
|
400
|
+
...summary,
|
|
401
|
+
mutationsApplied: asStringArray(row.mutations_applied),
|
|
402
|
+
advisories,
|
|
403
|
+
rawRequest: asString(row.prompt_preview),
|
|
404
|
+
rawResponse: asString(row.response_preview),
|
|
405
|
+
requestedModel,
|
|
406
|
+
finishReason: asString(row.finish_reason),
|
|
407
|
+
ttftMs: asNumber(row.ttft_ms),
|
|
408
|
+
totalMs: asNumber(row.total_ms) ?? asNumber(row.latency_ms),
|
|
409
|
+
toolsCount: asNumber(row.tools_count),
|
|
410
|
+
historyDepth: asNumber(row.history_depth),
|
|
411
|
+
systemPromptChars: asNumber(row.system_prompt_chars),
|
|
412
|
+
cacheReadInputTokens,
|
|
413
|
+
cacheCreationInputTokens,
|
|
414
|
+
historyCacheableTokens,
|
|
415
|
+
inputCacheHitRatio,
|
|
416
|
+
fellOverFrom,
|
|
417
|
+
fallbackReason,
|
|
418
|
+
sectionRewritesApplied,
|
|
419
|
+
health
|
|
420
|
+
};
|
|
421
|
+
return detail;
|
|
422
|
+
}
|
|
423
|
+
function createProxyHandler(config) {
|
|
424
|
+
const {
|
|
425
|
+
installToken,
|
|
426
|
+
extensionId,
|
|
427
|
+
brainEndpoint,
|
|
428
|
+
brainJwt,
|
|
429
|
+
brainAnonKey,
|
|
430
|
+
appId,
|
|
431
|
+
scrub,
|
|
432
|
+
fetch: fetchImpl
|
|
433
|
+
} = config;
|
|
434
|
+
const doFetch = fetchImpl ?? ((...args) => globalThis.fetch(...args));
|
|
435
|
+
const base = brainEndpoint.replace(/\/+$/, "");
|
|
436
|
+
return async function proxy(req) {
|
|
437
|
+
const authFail = checkAuth(req, { installToken, extensionId });
|
|
438
|
+
if (authFail) return authFail;
|
|
439
|
+
const url = new URL(req.url);
|
|
440
|
+
const traceId = url.searchParams.get("traceId");
|
|
441
|
+
const limit = parseLimit(url.searchParams.get("limit"));
|
|
442
|
+
const qs = new URLSearchParams();
|
|
443
|
+
qs.set("app_id", `eq.${appId}`);
|
|
444
|
+
if (traceId) {
|
|
445
|
+
qs.set("handle", `eq.${traceId}`);
|
|
446
|
+
} else {
|
|
447
|
+
qs.set("order", "created_at.desc");
|
|
448
|
+
qs.set("limit", String(limit));
|
|
449
|
+
}
|
|
450
|
+
const brainUrl = `${base}/rest/v1/compile_outcomes?${qs.toString()}`;
|
|
451
|
+
let brainRes;
|
|
452
|
+
try {
|
|
453
|
+
brainRes = await doFetch(brainUrl, {
|
|
454
|
+
method: "GET",
|
|
455
|
+
headers: {
|
|
456
|
+
// Authorization carries the scoped JWT — drives RLS via app_id claim.
|
|
457
|
+
Authorization: `Bearer ${brainJwt}`,
|
|
458
|
+
// apikey MUST be one of the project's known keys (anon or
|
|
459
|
+
// service_role). Supabase rejects any other JWT here, even when
|
|
460
|
+
// HS256-signed with the same secret. Pre-alpha.24 this was set to
|
|
461
|
+
// brainJwt and silently 401'd against real Supabase. See L-117.
|
|
462
|
+
apikey: brainAnonKey,
|
|
463
|
+
Accept: "application/json"
|
|
464
|
+
}
|
|
465
|
+
});
|
|
466
|
+
} catch {
|
|
467
|
+
return jsonError2(502, "brain_unavailable");
|
|
468
|
+
}
|
|
469
|
+
if (brainRes.status === 401 || brainRes.status === 403) {
|
|
470
|
+
return jsonError2(500, "brain_auth_misconfig");
|
|
471
|
+
}
|
|
472
|
+
if (brainRes.status >= 500) {
|
|
473
|
+
return jsonError2(502, "brain_unavailable");
|
|
474
|
+
}
|
|
475
|
+
if (!brainRes.ok) {
|
|
476
|
+
return jsonError2(400, "bad_request");
|
|
477
|
+
}
|
|
478
|
+
let rows;
|
|
479
|
+
try {
|
|
480
|
+
rows = await brainRes.json();
|
|
481
|
+
} catch {
|
|
482
|
+
return jsonError2(502, "brain_unavailable");
|
|
483
|
+
}
|
|
484
|
+
if (!Array.isArray(rows)) {
|
|
485
|
+
return jsonError2(502, "brain_unavailable");
|
|
486
|
+
}
|
|
487
|
+
const scrubbed = rows.map(
|
|
488
|
+
(row) => applyScrub(row, scrub)
|
|
489
|
+
);
|
|
490
|
+
if (traceId) {
|
|
491
|
+
const first = scrubbed[0];
|
|
492
|
+
if (!first) return jsonError2(404, "not_found");
|
|
493
|
+
const detail = rowToDetail(first);
|
|
494
|
+
const counterfactuals = computeCounterfactuals({
|
|
495
|
+
servedModel: detail.target,
|
|
496
|
+
servedCostUsd: detail.estimatedCostUsd,
|
|
497
|
+
archetype: detail.archetype,
|
|
498
|
+
tokensIn: detail.tokensIn,
|
|
499
|
+
tokensOut: detail.tokensOut,
|
|
500
|
+
cacheReadInputTokens: detail.cacheReadInputTokens
|
|
501
|
+
});
|
|
502
|
+
detail.counterfactuals = counterfactuals;
|
|
503
|
+
if (detail.estimatedCostUsd > 0) {
|
|
504
|
+
const projected = await computeProjectedDailyCost({
|
|
505
|
+
appId: detail.appId,
|
|
506
|
+
archetype: detail.archetype,
|
|
507
|
+
servedCostUsd: detail.estimatedCostUsd,
|
|
508
|
+
brainEndpoint: base,
|
|
509
|
+
brainJwt,
|
|
510
|
+
brainAnonKey,
|
|
511
|
+
fetch: doFetch
|
|
512
|
+
});
|
|
513
|
+
if (projected !== void 0) {
|
|
514
|
+
detail.projectedDailyCostUsd = projected;
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
return jsonResponse(200, detail);
|
|
518
|
+
}
|
|
519
|
+
return jsonResponse(200, { traces: scrubbed.map(rowToSummary) });
|
|
520
|
+
};
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
// src/glassbox-routes/stream.ts
|
|
524
|
+
var SSE_HEADERS = {
|
|
525
|
+
"Content-Type": "text/event-stream",
|
|
526
|
+
"Cache-Control": "no-cache, no-transform",
|
|
527
|
+
Connection: "keep-alive",
|
|
528
|
+
"X-Accel-Buffering": "no"
|
|
529
|
+
};
|
|
530
|
+
function applyScrub2(event, scrub) {
|
|
531
|
+
if (!scrub) return event;
|
|
532
|
+
try {
|
|
533
|
+
const out = scrub(event);
|
|
534
|
+
if (out && typeof out === "object" && typeof out.kind === "string" && typeof out.at === "number") {
|
|
535
|
+
return out;
|
|
536
|
+
}
|
|
537
|
+
return event;
|
|
538
|
+
} catch {
|
|
539
|
+
return event;
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
function sseFrame(eventName, data) {
|
|
543
|
+
const safeName = eventName.replace(/[\r\n]/g, "");
|
|
544
|
+
return `event: ${safeName}
|
|
545
|
+
data: ${JSON.stringify(data)}
|
|
546
|
+
|
|
547
|
+
`;
|
|
548
|
+
}
|
|
549
|
+
function createStreamHandler(config, subscribe2, subscribeApp2) {
|
|
550
|
+
const { installToken, extensionId, appId, scrub } = config;
|
|
551
|
+
return async function stream(req) {
|
|
552
|
+
const authFail = checkAuth(req, { installToken, extensionId });
|
|
553
|
+
if (authFail) return authFail;
|
|
554
|
+
const url = new URL(req.url);
|
|
555
|
+
const traceId = url.searchParams.get("traceId");
|
|
556
|
+
const source = traceId ? subscribe2(traceId) : subscribeApp2({ appId });
|
|
557
|
+
const encoder = new TextEncoder();
|
|
558
|
+
let sourceReader;
|
|
559
|
+
let cancelled = false;
|
|
560
|
+
const body = new ReadableStream({
|
|
561
|
+
async start(controller) {
|
|
562
|
+
controller.enqueue(encoder.encode(sseFrame("ready", {})));
|
|
563
|
+
sourceReader = source.getReader();
|
|
564
|
+
const signal = req.signal;
|
|
565
|
+
if (signal) {
|
|
566
|
+
if (signal.aborted) {
|
|
567
|
+
cancelled = true;
|
|
568
|
+
await sourceReader.cancel();
|
|
569
|
+
try {
|
|
570
|
+
controller.close();
|
|
571
|
+
} catch {
|
|
572
|
+
}
|
|
573
|
+
return;
|
|
574
|
+
}
|
|
575
|
+
signal.addEventListener(
|
|
576
|
+
"abort",
|
|
577
|
+
() => {
|
|
578
|
+
cancelled = true;
|
|
579
|
+
sourceReader?.cancel().catch(() => {
|
|
580
|
+
});
|
|
581
|
+
try {
|
|
582
|
+
controller.close();
|
|
583
|
+
} catch {
|
|
584
|
+
}
|
|
585
|
+
},
|
|
586
|
+
{ once: true }
|
|
587
|
+
);
|
|
588
|
+
}
|
|
589
|
+
try {
|
|
590
|
+
while (!cancelled) {
|
|
591
|
+
const { value, done } = await sourceReader.read();
|
|
592
|
+
if (done) break;
|
|
593
|
+
const scrubbed = applyScrub2(value, scrub);
|
|
594
|
+
controller.enqueue(
|
|
595
|
+
encoder.encode(sseFrame(scrubbed.kind, scrubbed))
|
|
596
|
+
);
|
|
597
|
+
}
|
|
598
|
+
} catch {
|
|
599
|
+
} finally {
|
|
600
|
+
try {
|
|
601
|
+
controller.close();
|
|
602
|
+
} catch {
|
|
603
|
+
}
|
|
604
|
+
try {
|
|
605
|
+
sourceReader?.releaseLock();
|
|
606
|
+
} catch {
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
},
|
|
610
|
+
cancel() {
|
|
611
|
+
cancelled = true;
|
|
612
|
+
sourceReader?.cancel().catch(() => {
|
|
613
|
+
});
|
|
614
|
+
}
|
|
615
|
+
});
|
|
616
|
+
return new Response(body, { status: 200, headers: SSE_HEADERS });
|
|
617
|
+
};
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
// src/glassbox-routes/index.ts
|
|
621
|
+
function requireString(name, value) {
|
|
622
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
623
|
+
throw new Error(`createGlassboxRoutes: ${name} is required`);
|
|
624
|
+
}
|
|
625
|
+
return value;
|
|
626
|
+
}
|
|
627
|
+
function createGlassboxRoutes(config) {
|
|
628
|
+
const installToken = requireString("installToken", config.installToken);
|
|
629
|
+
const extensionId = requireString("extensionId", config.extensionId);
|
|
630
|
+
const brainEndpoint = requireString("brainEndpoint", config.brainEndpoint);
|
|
631
|
+
const brainJwt = requireString("brainJwt", config.brainJwt);
|
|
632
|
+
const brainAnonKey = requireString("brainAnonKey", config.brainAnonKey);
|
|
633
|
+
const appId = requireString("appId", config.appId);
|
|
634
|
+
const proxy = createProxyHandler({
|
|
635
|
+
installToken,
|
|
636
|
+
extensionId,
|
|
637
|
+
brainEndpoint,
|
|
638
|
+
brainJwt,
|
|
639
|
+
brainAnonKey,
|
|
640
|
+
appId,
|
|
641
|
+
scrub: config.scrub,
|
|
642
|
+
fetch: config.fetch
|
|
643
|
+
});
|
|
644
|
+
const stream = createStreamHandler(
|
|
645
|
+
{
|
|
646
|
+
installToken,
|
|
647
|
+
extensionId,
|
|
648
|
+
appId,
|
|
649
|
+
scrub: config.scrub
|
|
650
|
+
},
|
|
651
|
+
config.subscribe ?? subscribe,
|
|
652
|
+
config.subscribeApp ?? subscribeApp
|
|
653
|
+
);
|
|
654
|
+
return { proxy, stream };
|
|
655
|
+
}
|
|
656
|
+
export {
|
|
657
|
+
createGlassboxRoutes
|
|
658
|
+
};
|