@konneal/engine 0.2.171 → 0.2.176
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/dist/ablate.d.ts +9 -4
- package/dist/admin.d.ts +5 -3
- package/dist/ask-ZWZFZBKZ.js +16 -0
- package/dist/{chunk-QS6V53RO.js → chunk-B2MU4ZWM.js} +3 -3
- package/dist/{chunk-RZLEHCIA.js → chunk-CLDMP5YH.js} +3 -3
- package/dist/{chunk-O2XMNKCK.js → chunk-D7MO4RVQ.js} +1 -1
- package/dist/{chunk-PQDAL4MX.js → chunk-FNQ7UOEB.js} +1 -1
- package/dist/{chunk-5UIMQAJZ.js → chunk-HWWJAJWM.js} +7 -0
- package/dist/{chunk-6KEWBP7O.js → chunk-MUWO2EV6.js} +4 -4
- package/dist/{chunk-KKJHJXQV.js → chunk-T6T2QUO6.js} +27 -12
- package/dist/{chunk-XWSZWFYP.js → chunk-ZHT4456M.js} +1 -1
- package/dist/config.d.ts +2 -0
- package/dist/decisionWire.d.ts +15 -0
- package/dist/openapi-surface.gen.d.ts +1 -1
- package/dist/openapi-types.d.ts +54 -1
- package/dist/pipeline.d.ts +4 -3
- package/dist/search-KNPPTHMG.js +14 -0
- package/dist/{tools-HK5RXHBQ.js → tools-VHN54DWH.js} +4 -4
- package/dist/worker_mcp/src/index.js +2 -2
- package/dist/worker_public/src/config.js +1 -1
- package/dist/worker_public/src/index.js +90 -28
- package/dist/worker_public/src/requestScope.js +2 -2
- package/package.json +1 -1
- package/workers/worker_public/openapi.yaml +39 -1
- package/workers/worker_public/src/ablate.ts +12 -6
- package/workers/worker_public/src/admin.ts +84 -20
- package/workers/worker_public/src/ask.ts +14 -7
- package/workers/worker_public/src/config.ts +7 -0
- package/workers/worker_public/src/decisionWire.ts +25 -0
- package/workers/worker_public/src/index.ts +2 -1
- package/workers/worker_public/src/openapi-surface.gen.ts +6 -0
- package/workers/worker_public/src/pipeline.ts +4 -3
- package/dist/ask-4T3E2Z6J.js +0 -16
- package/dist/search-RNCRT5BR.js +0 -14
package/dist/ablate.d.ts
CHANGED
|
@@ -13,11 +13,16 @@ export interface AblateConfig {
|
|
|
13
13
|
* diversified subset + one strong verifier. Off in serving until the
|
|
14
14
|
* gate promotes it; the grid arms it per ask. */
|
|
15
15
|
speculative: boolean;
|
|
16
|
-
/** Extractive prompt compression (TODO.sota/02 row 5):
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
16
|
+
/** Extractive prompt compression (TODO.sota/02 row 5): PROMOTED — the
|
|
17
|
+
* passage bodies are query-weighted sentence selection at a fraction
|
|
18
|
+
* of their budget in serving (the row's gate: identical accuracy at
|
|
19
|
+
* ~1/20th the prompt, the whole-document baseline measured it).
|
|
20
|
+
* ablate_compress survives for the grid's explicit arm;
|
|
21
|
+
* ablate_no_compress is the measurement stand-down. */
|
|
20
22
|
compress: boolean;
|
|
23
|
+
/** Per-request stand-down for the promoted compressor (the
|
|
24
|
+
* measurement arm; the serving default is on). */
|
|
25
|
+
noCompress: boolean;
|
|
21
26
|
/** The decision pass (TODO.decisions/01): per-request stand-down for
|
|
22
27
|
* the measurement — the serving switch is DECISIONS_ENABLED. */
|
|
23
28
|
noDecisions: boolean;
|
package/dist/admin.d.ts
CHANGED
|
@@ -21,9 +21,11 @@ export declare function handleSectionUnit(env: Env, ctx: ExecutionContext, req:
|
|
|
21
21
|
* the deterministic registry line. Admin-gated; idempotent (force
|
|
22
22
|
* regenerates); the quality-first lane pays once. */
|
|
23
23
|
export declare function handleFamilySummary(env: Env, req: Request): Promise<Response>;
|
|
24
|
-
/**
|
|
25
|
-
*
|
|
26
|
-
*
|
|
24
|
+
/** The pairwise vision judge (TODO.sota/18.4's A/B): two anonymized
|
|
25
|
+
* captions of the SAME figure, presented in randomized order beside the
|
|
26
|
+
* image itself; a THIRD model (never a contestant) picks the better
|
|
27
|
+
* caption with a reason. Admin-gated; one-time quality-first lane. */
|
|
28
|
+
export declare function handleVisionJudge(env: Env, req: Request): Promise<Response>;
|
|
27
29
|
/** One-time figure captioning (TODO.remaining/03): fetch the unit's asset
|
|
28
30
|
* from R2, describe it with the vision-capable answer model, store the
|
|
29
31
|
* description into unit_payloads. Admin-gated; idempotent. */
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {
|
|
2
|
+
handleAsk
|
|
3
|
+
} from "./chunk-T6T2QUO6.js";
|
|
4
|
+
import "./chunk-ECOYO7EX.js";
|
|
5
|
+
import "./chunk-B2MU4ZWM.js";
|
|
6
|
+
import "./chunk-CLDMP5YH.js";
|
|
7
|
+
import "./chunk-ZHT4456M.js";
|
|
8
|
+
import "./chunk-D7MO4RVQ.js";
|
|
9
|
+
import "./chunk-ETLSWSZ7.js";
|
|
10
|
+
import "./chunk-FNQ7UOEB.js";
|
|
11
|
+
import "./chunk-HWWJAJWM.js";
|
|
12
|
+
import "./chunk-3FYJM7LH.js";
|
|
13
|
+
import "./chunk-KINFFYQH.js";
|
|
14
|
+
export {
|
|
15
|
+
handleAsk
|
|
16
|
+
};
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
embed
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-ZHT4456M.js";
|
|
4
4
|
import {
|
|
5
5
|
standardKeysFrom
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-FNQ7UOEB.js";
|
|
7
7
|
import {
|
|
8
8
|
THRESHOLDS
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-HWWJAJWM.js";
|
|
10
10
|
import {
|
|
11
11
|
P
|
|
12
12
|
} from "./chunk-3FYJM7LH.js";
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
embed,
|
|
3
3
|
rerank
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-ZHT4456M.js";
|
|
5
5
|
import {
|
|
6
6
|
bubbleConfirmPage,
|
|
7
7
|
isAllowedBubbleOrigin
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-D7MO4RVQ.js";
|
|
9
9
|
import {
|
|
10
10
|
DATASETS,
|
|
11
11
|
LIMITS,
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
processExpansion,
|
|
16
16
|
sha256Hex,
|
|
17
17
|
today
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-HWWJAJWM.js";
|
|
19
19
|
import {
|
|
20
20
|
P
|
|
21
21
|
} from "./chunk-3FYJM7LH.js";
|
|
@@ -11,6 +11,13 @@ var MODELS = {
|
|
|
11
11
|
// Vision image-parts land with answer contract v2; text answers work now.
|
|
12
12
|
anon: "@cf/zai-org/glm-5.3-flash",
|
|
13
13
|
member: "@cf/zai-org/glm-5.3-flash",
|
|
14
|
+
// figure captions + the vision lane (one-time, quality-first; the A/B
|
|
15
|
+
// lever is CAPTION_MODEL, the per-request arm is the admin route's
|
|
16
|
+
// body.model)
|
|
17
|
+
caption: "@cf/zai-org/glm-5.3-flash",
|
|
18
|
+
// the pairwise vision judge (sees the image; a THIRD model never
|
|
19
|
+
// judges its own arm)
|
|
20
|
+
visionJudge: "@cf/deepseek-ai/deepseek-v4.1-flash-1017",
|
|
14
21
|
// the VLM figure rerank (TODO.sota/18.3): the newly-landed
|
|
15
22
|
// vision-capable MoE scores figure IMAGES against figure-seeking
|
|
16
23
|
// questions — one bounded call per figure question, ablatable stage
|
|
@@ -6,24 +6,24 @@ import {
|
|
|
6
6
|
sessionFrom,
|
|
7
7
|
telemetry,
|
|
8
8
|
understandQuery
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-CLDMP5YH.js";
|
|
10
10
|
import {
|
|
11
11
|
corsHeaders,
|
|
12
12
|
err,
|
|
13
13
|
json,
|
|
14
14
|
readJson,
|
|
15
15
|
validateQuery
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-D7MO4RVQ.js";
|
|
17
17
|
import {
|
|
18
18
|
entitlementScope,
|
|
19
19
|
standardKeysFrom
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-FNQ7UOEB.js";
|
|
21
21
|
import {
|
|
22
22
|
LIMITS,
|
|
23
23
|
MODELS,
|
|
24
24
|
num,
|
|
25
25
|
sha256Hex
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-HWWJAJWM.js";
|
|
27
27
|
import {
|
|
28
28
|
portModelRunner
|
|
29
29
|
} from "./chunk-KINFFYQH.js";
|
|
@@ -32,7 +32,7 @@ import {
|
|
|
32
32
|
tableRetyped,
|
|
33
33
|
toolNote,
|
|
34
34
|
verdictNote
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-B2MU4ZWM.js";
|
|
36
36
|
import {
|
|
37
37
|
NO_CONTEXT,
|
|
38
38
|
STAGE_NAMES,
|
|
@@ -75,18 +75,18 @@ import {
|
|
|
75
75
|
tokenBudget,
|
|
76
76
|
understandQuery,
|
|
77
77
|
usageTotal
|
|
78
|
-
} from "./chunk-
|
|
78
|
+
} from "./chunk-CLDMP5YH.js";
|
|
79
79
|
import {
|
|
80
80
|
embed,
|
|
81
81
|
generateOnce
|
|
82
|
-
} from "./chunk-
|
|
82
|
+
} from "./chunk-ZHT4456M.js";
|
|
83
83
|
import {
|
|
84
84
|
corsHeaders,
|
|
85
85
|
err,
|
|
86
86
|
json,
|
|
87
87
|
readJson,
|
|
88
88
|
validateQuery
|
|
89
|
-
} from "./chunk-
|
|
89
|
+
} from "./chunk-D7MO4RVQ.js";
|
|
90
90
|
import {
|
|
91
91
|
cacheableAnswer,
|
|
92
92
|
canonicalRefusal,
|
|
@@ -99,7 +99,7 @@ import {
|
|
|
99
99
|
requestSalt,
|
|
100
100
|
resolveRequestScope,
|
|
101
101
|
standardKeysFrom
|
|
102
|
-
} from "./chunk-
|
|
102
|
+
} from "./chunk-FNQ7UOEB.js";
|
|
103
103
|
import {
|
|
104
104
|
LIMITS,
|
|
105
105
|
MODELS,
|
|
@@ -110,7 +110,7 @@ import {
|
|
|
110
110
|
requestEffort,
|
|
111
111
|
roleModel,
|
|
112
112
|
sha256Hex
|
|
113
|
-
} from "./chunk-
|
|
113
|
+
} from "./chunk-HWWJAJWM.js";
|
|
114
114
|
import {
|
|
115
115
|
P
|
|
116
116
|
} from "./chunk-3FYJM7LH.js";
|
|
@@ -1404,10 +1404,11 @@ function parseAblate(body, adminToken, presentedToken, knownStages) {
|
|
|
1404
1404
|
const rawRoute = body?.ablate_route;
|
|
1405
1405
|
const speculative = body?.ablate_speculative === true;
|
|
1406
1406
|
const compress = body?.ablate_compress === true;
|
|
1407
|
+
const noCompress = body?.ablate_no_compress === true;
|
|
1407
1408
|
const noDecisions = body?.ablate_no_decisions === true;
|
|
1408
1409
|
const namesAblation = rawStages !== void 0 && rawStages !== null;
|
|
1409
1410
|
const routeAblation = rawRoute !== void 0 && rawRoute !== null && rawRoute !== "adaptive";
|
|
1410
|
-
if (!namesAblation && !noVerdict && !routeAblation && !speculative && !compress && !noDecisions) return { ok: true, config: null };
|
|
1411
|
+
if (!namesAblation && !noVerdict && !routeAblation && !speculative && !compress && !noCompress && !noDecisions) return { ok: true, config: null };
|
|
1411
1412
|
if (!adminToken || presentedToken !== adminToken) {
|
|
1412
1413
|
return {
|
|
1413
1414
|
ok: false,
|
|
@@ -1438,7 +1439,7 @@ function parseAblate(body, adminToken, presentedToken, knownStages) {
|
|
|
1438
1439
|
}
|
|
1439
1440
|
stages = [...new Set(rawStages)];
|
|
1440
1441
|
}
|
|
1441
|
-
return { ok: true, config: { stages, noVerdict, route, speculative, compress, noDecisions } };
|
|
1442
|
+
return { ok: true, config: { stages, noVerdict, route, speculative, compress, noCompress, noDecisions } };
|
|
1442
1443
|
}
|
|
1443
1444
|
|
|
1444
1445
|
// workers/worker_public/src/decisions.ts
|
|
@@ -1621,6 +1622,15 @@ ${passages.join("\n")}`.slice(0, 12e3),
|
|
|
1621
1622
|
return null;
|
|
1622
1623
|
}
|
|
1623
1624
|
}
|
|
1625
|
+
function telemetryDecisions(env, ctx, tier, queryHash, result, durationMs) {
|
|
1626
|
+
try {
|
|
1627
|
+
telemetry(env, ctx, tier, "ask-decisions", result ? result.gate.toFixed(2) : "0", !!result, result?.items.length ?? 0, queryHash, result?.mode ?? void 0, void 0, { durationMs });
|
|
1628
|
+
for (const it of result?.items ?? []) {
|
|
1629
|
+
telemetry(env, ctx, tier, "ask-decision", it.probability.toFixed(2), it.band === "met", 1, queryHash, it.band, void 0, {});
|
|
1630
|
+
}
|
|
1631
|
+
} catch {
|
|
1632
|
+
}
|
|
1633
|
+
}
|
|
1624
1634
|
|
|
1625
1635
|
// workers/worker_public/src/route.ts
|
|
1626
1636
|
var ROUTE_FAST_WORD_CAP = 10;
|
|
@@ -2828,7 +2838,7 @@ Answer account questions from these records ONLY: name the record when you use i
|
|
|
2828
2838
|
[ops.note, processNote, eNote, regNote, contextNote(declaredCtx, docScope), accountNote, modelNote, vocabNote, memNote, machineNote, conditionNote, aggregationNote, boundaryNote, licenseNote, ...retrieved.notes ?? []].filter(Boolean).join("\n") || void 0,
|
|
2829
2839
|
summary,
|
|
2830
2840
|
budget,
|
|
2831
|
-
ablate?.
|
|
2841
|
+
ablate?.noCompress !== true
|
|
2832
2842
|
);
|
|
2833
2843
|
const decisionPromise = decisionsArmed && decisionsGatePromise ? decisionsGatePromise.then((g) => g != null && g >= THRESHOLDS.decisionsGateMin ? runDecisionPass(env, {
|
|
2834
2844
|
question: q2.query,
|
|
@@ -2976,14 +2986,17 @@ Answer account questions from these records ONLY: name the record when you use i
|
|
|
2976
2986
|
let canonical0 = exciseMisplacedPin(canonicalRefusal(full.replace(/^TOOL [a-z_.]+.*$\n?/gm, "").replace(/^\n+/, ""), refusalScope(answerCites(full))), answerCites(full));
|
|
2977
2987
|
const c2 = canonical0.includes(refusalAnswer()) ? { text: canonical0, blocks: [], dropped: [] } : await contractV2(env.DB, canonical0, usedHits);
|
|
2978
2988
|
let streamedCompletionBlocks = [];
|
|
2979
|
-
|
|
2989
|
+
let streamedDecisions;
|
|
2990
|
+
if (decisionPromise && !canonical0.includes(refusalAnswer()) && !verdictBlock && !conditionBlock && !aggregationBlock) {
|
|
2980
2991
|
const dp = await decisionPromise;
|
|
2981
2992
|
if (dp) {
|
|
2982
2993
|
canonical0 += dp.section;
|
|
2983
2994
|
send({ type: "token", v: dp.section });
|
|
2984
2995
|
full += dp.section;
|
|
2996
|
+
streamedDecisions = { mode: dp.mode, gate: dp.gate, items: dp.items };
|
|
2985
2997
|
console.log("decisions: streamed the checklist section (" + dp.items.length + " items, mode " + dp.mode + ")");
|
|
2986
2998
|
}
|
|
2999
|
+
telemetryDecisions(env, ctx, tier, queryHash, streamedDecisions ?? null, Date.now() - tStart);
|
|
2987
3000
|
}
|
|
2988
3001
|
if (!canonical0.includes(refusalAnswer())) {
|
|
2989
3002
|
try {
|
|
@@ -2998,6 +3011,7 @@ Answer account questions from these records ONLY: name the record when you use i
|
|
|
2998
3011
|
model,
|
|
2999
3012
|
query_hash: queryHash,
|
|
3000
3013
|
follow_ups: refusalShaped(canonical0, refusalScope(answerCites(full))) ? [] : understanding?.follow_ups ?? [],
|
|
3014
|
+
...streamedDecisions ? { decisions: streamedDecisions } : {},
|
|
3001
3015
|
blocks: [...c2.blocks, ...verdictBlock ? [verdictBlock] : [], ...conditionBlock ? [conditionBlock] : [], ...aggregationBlock ? [aggregationBlock] : [], ...streamedCompletionBlocks],
|
|
3002
3016
|
context_applied: ctxApplied,
|
|
3003
3017
|
read: readAs(),
|
|
@@ -3162,7 +3176,7 @@ Answer account questions from these records ONLY: name the record when you use i
|
|
|
3162
3176
|
...routeSubset ? { stageSubset: routeSubset ?? void 0 } : {}
|
|
3163
3177
|
});
|
|
3164
3178
|
if (retryRetrieve.hits.length > 0) {
|
|
3165
|
-
const { messages: retryMessages, usedHits: retryUsed } = buildMessages(q2.query, retryRetrieve.hits, q2.lang, keptHistory, void 0, summary, budget, ablate?.
|
|
3179
|
+
const { messages: retryMessages, usedHits: retryUsed } = buildMessages(q2.query, retryRetrieve.hits, q2.lang, keptHistory, void 0, summary, budget, ablate?.noCompress !== true);
|
|
3166
3180
|
const retryAnswer = await generateOnce(env, model, retryMessages, routeEffort(routed.route));
|
|
3167
3181
|
if (retryAnswer) {
|
|
3168
3182
|
answer = canonicalRefusal(retryAnswer, refusalScope(answerCites(retryAnswer)));
|
|
@@ -3219,10 +3233,11 @@ Answer account questions from these records ONLY: name the record when you use i
|
|
|
3219
3233
|
let decisionsOut;
|
|
3220
3234
|
if (decisionPromise) {
|
|
3221
3235
|
const dp = await decisionPromise;
|
|
3222
|
-
if (dp && answer && !answer.includes(refusalAnswer())) {
|
|
3236
|
+
if (dp && answer && !answer.includes(refusalAnswer()) && !verdictBlock && !conditionBlock && !aggregationBlock) {
|
|
3223
3237
|
answer = answer + dp.section;
|
|
3224
3238
|
decisionsOut = { mode: dp.mode, gate: dp.gate, items: dp.items };
|
|
3225
3239
|
}
|
|
3240
|
+
telemetryDecisions(env, ctx, tier, queryHash, decisionsOut ?? null, Date.now() - tStart);
|
|
3226
3241
|
}
|
|
3227
3242
|
const out = { answer, citations: finalCites, ...jsonQuality ? { source_quality: jsonQuality, confidence_note: entailmentNote || qualityNote(jsonQuality), ...entailment ? { entailment } : {}, ...jsonQuality === "ocr" ? { experimental_sources: experimentalSourceLabels(finalCites) } : {} } : {}, model: MODELS.member, query_hash: queryHash, follow_ups: refusalShaped(answer, refusalScope(answerCites(answer))) ? [] : understanding?.follow_ups ?? [], blocks: [...c2ns.blocks, ...verdictBlock ? [verdictBlock] : [], ...conditionBlock ? [conditionBlock] : [], ...aggregationBlock ? [aggregationBlock] : [], ...registerBlock ? [registerBlock] : [], ...completionBlocks], context_applied: ctxApplied, ...liveRecords ? { records: liveRecords } : {}, ...decisionsOut ? { decisions: decisionsOut } : {}, ...ablate ? { ablate } : {}, route: { route: routed.route, features: routed.features } };
|
|
3228
3243
|
const cacheable = !contextual && !declaredCtx && !ablate && cacheableAnswer(answer, refusalScope(answerCites(answer))) && finalAnchors.violations.length === 0;
|
package/dist/config.d.ts
CHANGED
|
@@ -3,6 +3,8 @@ export declare const MODELS: {
|
|
|
3
3
|
readonly rerank: "@cf/baai/bge-reranker-base";
|
|
4
4
|
readonly anon: "@cf/zai-org/glm-5.3-flash";
|
|
5
5
|
readonly member: "@cf/zai-org/glm-5.3-flash";
|
|
6
|
+
readonly caption: "@cf/zai-org/glm-5.3-flash";
|
|
7
|
+
readonly visionJudge: "@cf/deepseek-ai/deepseek-v4.1-flash-1017";
|
|
6
8
|
readonly vlmFigure: "@cf/deepseek-ai/deepseek-v4.1-flash-1017";
|
|
7
9
|
readonly decisionsGate: "@cf/cloudflare/clef-flash";
|
|
8
10
|
readonly decisionsModel: "@cf/cloudflare/clef";
|
package/dist/decisionWire.d.ts
CHANGED
|
@@ -23,3 +23,18 @@ export declare function runDecisionPass(env: Env, opts: {
|
|
|
23
23
|
statedValues?: string;
|
|
24
24
|
userDocs?: boolean;
|
|
25
25
|
}): Promise<DecisionPassResult | null>;
|
|
26
|
+
/** The decisions telemetry (TODO.decisions/03): the nightly's
|
|
27
|
+
* calibration signal, riding the queries table's route key with a
|
|
28
|
+
* defined encoding — no schema migration.
|
|
29
|
+
* - one PASS row, route "ask-decisions": ok = fired, lang = mode,
|
|
30
|
+
* model = the gate probability (2dp), duration_ms = the pass's.
|
|
31
|
+
* - one ITEM row per requirement, route "ask-decision": ok = band is
|
|
32
|
+
* "met", lang = band, model = the probability (2dp); query_hash
|
|
33
|
+
* joins the rows to their pass. */
|
|
34
|
+
export declare function telemetryDecisions(env: Env, ctx: {
|
|
35
|
+
waitUntil(p: Promise<unknown>): void;
|
|
36
|
+
}, tier: string, queryHash: string, result: {
|
|
37
|
+
mode: string;
|
|
38
|
+
gate: number;
|
|
39
|
+
items: DecisionItem[];
|
|
40
|
+
} | null, durationMs: number): void;
|
|
@@ -3,7 +3,7 @@ export interface OpenApiRoute {
|
|
|
3
3
|
pattern: string;
|
|
4
4
|
operationId: string;
|
|
5
5
|
}
|
|
6
|
-
export type OpenApiOperationId = "credits" | "creditsAlias" | "askAnonymous" | "askKeyed" | "search" | "searchKeyed" | "verify" | "verifyKeyed" | "research" | "researchKeyed" | "mcp" | "datasets" | "keyUsage" | "health" | "listConversations" | "createConversation" | "getConversation" | "renameConversation" | "deleteConversation" | "appendMessage" | "shareConversation" | "getShared" | "uploadAttachment" | "listAttachments" | "getAttachment" | "deleteAttachment" | "listMemories" | "createMemory" | "deleteMemory" | "listProjects" | "createProject" | "deleteProject" | "listProjectFiles" | "attachProjectFile" | "detachProjectFile" | "laneQuery" | "laneKeyed" | "feedback" | "adminEnrich" | "adminEnrichAlias" | "adminSection" | "adminFamilySummary" | "adminSectionAlias" | "adminFamilySummaryAlias" | "adminVectors" | "adminCaption" | "adminJudge" | "adminJudgeAlias" | "adminRevokeKey" | "authMe" | "authLogin" | "authCallback" | "authLogout" | "authLogoutLink" | "adminStats" | "adminListKeys" | "adminCreateKey";
|
|
6
|
+
export type OpenApiOperationId = "credits" | "creditsAlias" | "askAnonymous" | "askKeyed" | "search" | "searchKeyed" | "verify" | "verifyKeyed" | "research" | "researchKeyed" | "mcp" | "datasets" | "keyUsage" | "health" | "listConversations" | "createConversation" | "getConversation" | "renameConversation" | "deleteConversation" | "appendMessage" | "shareConversation" | "getShared" | "uploadAttachment" | "listAttachments" | "getAttachment" | "deleteAttachment" | "listMemories" | "createMemory" | "deleteMemory" | "listProjects" | "createProject" | "deleteProject" | "listProjectFiles" | "attachProjectFile" | "detachProjectFile" | "laneQuery" | "laneKeyed" | "feedback" | "adminEnrich" | "adminEnrichAlias" | "adminSection" | "adminFamilySummary" | "adminSectionAlias" | "adminFamilySummaryAlias" | "adminVectors" | "adminCaption" | "adminVisionJudge" | "adminJudge" | "adminJudgeAlias" | "adminRevokeKey" | "authMe" | "authLogin" | "authCallback" | "authLogout" | "authLogoutLink" | "adminStats" | "adminListKeys" | "adminCreateKey";
|
|
7
7
|
export declare const OPENAPI_SURFACE: readonly (Omit<OpenApiRoute, "operationId"> & {
|
|
8
8
|
operationId: OpenApiOperationId;
|
|
9
9
|
})[];
|
package/dist/openapi-types.d.ts
CHANGED
|
@@ -753,6 +753,26 @@ export interface paths {
|
|
|
753
753
|
patch?: never;
|
|
754
754
|
trace?: never;
|
|
755
755
|
};
|
|
756
|
+
"/admin/vision_judge": {
|
|
757
|
+
parameters: {
|
|
758
|
+
query?: never;
|
|
759
|
+
header?: never;
|
|
760
|
+
path?: never;
|
|
761
|
+
cookie?: never;
|
|
762
|
+
};
|
|
763
|
+
get?: never;
|
|
764
|
+
put?: never;
|
|
765
|
+
/**
|
|
766
|
+
* Judge two captions of one figure against the image
|
|
767
|
+
* @description The caption A/B's pairwise judge — two anonymized descriptions of the same figure, presented in randomized order beside the image itself, decided by a third model that took no part in writing either. The vision A/B harness calls this lane.
|
|
768
|
+
*/
|
|
769
|
+
post: operations["adminVisionJudge"];
|
|
770
|
+
delete?: never;
|
|
771
|
+
options?: never;
|
|
772
|
+
head?: never;
|
|
773
|
+
patch?: never;
|
|
774
|
+
trace?: never;
|
|
775
|
+
};
|
|
756
776
|
"/v1/admin/judge": {
|
|
757
777
|
parameters: {
|
|
758
778
|
query?: never;
|
|
@@ -2164,11 +2184,44 @@ export interface operations {
|
|
|
2164
2184
|
unit_id: string;
|
|
2165
2185
|
/** @description Surrounding clause text, at most 400 characters, to steer the description. */
|
|
2166
2186
|
context?: string;
|
|
2187
|
+
/** @description Per-request vision model override (an @cf/ id) — the caption A/B's measurement arm. Absent, the CAPTION_MODEL role (default glm-5.3-flash) serves. */
|
|
2188
|
+
model?: string;
|
|
2189
|
+
/** @description Return the description without storing it into the unit's payload. */
|
|
2190
|
+
dry_run?: boolean;
|
|
2191
|
+
};
|
|
2192
|
+
};
|
|
2193
|
+
};
|
|
2194
|
+
responses: {
|
|
2195
|
+
/** @description The description (stored, or returned only under dry_run). */
|
|
2196
|
+
200: {
|
|
2197
|
+
headers: {
|
|
2198
|
+
[name: string]: unknown;
|
|
2199
|
+
};
|
|
2200
|
+
content?: never;
|
|
2201
|
+
};
|
|
2202
|
+
};
|
|
2203
|
+
};
|
|
2204
|
+
adminVisionJudge: {
|
|
2205
|
+
parameters: {
|
|
2206
|
+
query?: never;
|
|
2207
|
+
header?: never;
|
|
2208
|
+
path?: never;
|
|
2209
|
+
cookie?: never;
|
|
2210
|
+
};
|
|
2211
|
+
requestBody: {
|
|
2212
|
+
content: {
|
|
2213
|
+
"application/json": {
|
|
2214
|
+
/** @description The figure unit whose asset the captions describe. */
|
|
2215
|
+
unit_id: string;
|
|
2216
|
+
captions: {
|
|
2217
|
+
a: string;
|
|
2218
|
+
b: string;
|
|
2219
|
+
};
|
|
2167
2220
|
};
|
|
2168
2221
|
};
|
|
2169
2222
|
};
|
|
2170
2223
|
responses: {
|
|
2171
|
-
/** @description The
|
|
2224
|
+
/** @description The winning arm (a or b) with the judge's reason. */
|
|
2172
2225
|
200: {
|
|
2173
2226
|
headers: {
|
|
2174
2227
|
[name: string]: unknown;
|
package/dist/pipeline.d.ts
CHANGED
|
@@ -51,9 +51,10 @@ export declare function splitHistory(history: HistoryTurn[], budgetTokens: numbe
|
|
|
51
51
|
* incoming order (timeout/parse failure never blocks serving). */
|
|
52
52
|
export declare function listwiseRerank(env: any, model: string, query: string, hits: Hit[]): Promise<Hit[] | null>;
|
|
53
53
|
export declare function buildMessages(query: string, hits: Hit[], lang?: string, history?: HistoryTurn[], retrievalNote?: string, conversationSummary?: string, budgetTokens?: number,
|
|
54
|
-
/** the extractive compression
|
|
55
|
-
*
|
|
56
|
-
*
|
|
54
|
+
/** the extractive compression (TODO.sota/02 row 5): PROMOTED — on in
|
|
55
|
+
* serving; ablate_no_compress stands it down per ask for the
|
|
56
|
+
* measurement. Each passage body becomes query-weighted sentence
|
|
57
|
+
* selection at compressShare of its budget. */
|
|
57
58
|
compress?: boolean): BuiltMessages;
|
|
58
59
|
export declare function citations(hits: Hit[]): {
|
|
59
60
|
doc_id: string;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import {
|
|
2
|
+
handleSearch
|
|
3
|
+
} from "./chunk-MUWO2EV6.js";
|
|
4
|
+
import "./chunk-CLDMP5YH.js";
|
|
5
|
+
import "./chunk-ZHT4456M.js";
|
|
6
|
+
import "./chunk-D7MO4RVQ.js";
|
|
7
|
+
import "./chunk-ETLSWSZ7.js";
|
|
8
|
+
import "./chunk-FNQ7UOEB.js";
|
|
9
|
+
import "./chunk-HWWJAJWM.js";
|
|
10
|
+
import "./chunk-3FYJM7LH.js";
|
|
11
|
+
import "./chunk-KINFFYQH.js";
|
|
12
|
+
export {
|
|
13
|
+
handleSearch
|
|
14
|
+
};
|
|
@@ -4,10 +4,10 @@ import {
|
|
|
4
4
|
parseToolCall,
|
|
5
5
|
runTool,
|
|
6
6
|
toolNote
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-
|
|
9
|
-
import "./chunk-
|
|
10
|
-
import "./chunk-
|
|
7
|
+
} from "./chunk-B2MU4ZWM.js";
|
|
8
|
+
import "./chunk-ZHT4456M.js";
|
|
9
|
+
import "./chunk-FNQ7UOEB.js";
|
|
10
|
+
import "./chunk-HWWJAJWM.js";
|
|
11
11
|
import "./chunk-3FYJM7LH.js";
|
|
12
12
|
import "./chunk-KINFFYQH.js";
|
|
13
13
|
export {
|
|
@@ -4,16 +4,16 @@ import {
|
|
|
4
4
|
handleMemories,
|
|
5
5
|
scoreFaithfulness,
|
|
6
6
|
scoreJudge
|
|
7
|
-
} from "../../chunk-
|
|
7
|
+
} from "../../chunk-T6T2QUO6.js";
|
|
8
8
|
import "../../chunk-ECOYO7EX.js";
|
|
9
9
|
import {
|
|
10
10
|
TOOLS_REGISTRY,
|
|
11
11
|
bindModelNode,
|
|
12
12
|
modelGroundingBlock
|
|
13
|
-
} from "../../chunk-
|
|
13
|
+
} from "../../chunk-B2MU4ZWM.js";
|
|
14
14
|
import {
|
|
15
15
|
handleSearch
|
|
16
|
-
} from "../../chunk-
|
|
16
|
+
} from "../../chunk-MUWO2EV6.js";
|
|
17
17
|
import {
|
|
18
18
|
buildMessages,
|
|
19
19
|
citations,
|
|
@@ -38,11 +38,11 @@ import {
|
|
|
38
38
|
sessionFrom,
|
|
39
39
|
telemetry,
|
|
40
40
|
understandQuery
|
|
41
|
-
} from "../../chunk-
|
|
41
|
+
} from "../../chunk-CLDMP5YH.js";
|
|
42
42
|
import {
|
|
43
43
|
embed,
|
|
44
44
|
generateOnce
|
|
45
|
-
} from "../../chunk-
|
|
45
|
+
} from "../../chunk-ZHT4456M.js";
|
|
46
46
|
import {
|
|
47
47
|
authenticate,
|
|
48
48
|
corsHeaders,
|
|
@@ -51,14 +51,14 @@ import {
|
|
|
51
51
|
readJson,
|
|
52
52
|
validateQuery,
|
|
53
53
|
withCors
|
|
54
|
-
} from "../../chunk-
|
|
54
|
+
} from "../../chunk-D7MO4RVQ.js";
|
|
55
55
|
import {
|
|
56
56
|
canonicalRefusal
|
|
57
57
|
} from "../../chunk-ETLSWSZ7.js";
|
|
58
58
|
import {
|
|
59
59
|
entitlementScope,
|
|
60
60
|
standardKeysFrom
|
|
61
|
-
} from "../../chunk-
|
|
61
|
+
} from "../../chunk-FNQ7UOEB.js";
|
|
62
62
|
import {
|
|
63
63
|
LIMITS,
|
|
64
64
|
MODELS,
|
|
@@ -69,7 +69,7 @@ import {
|
|
|
69
69
|
roleModel,
|
|
70
70
|
sha256Hex,
|
|
71
71
|
today
|
|
72
|
-
} from "../../chunk-
|
|
72
|
+
} from "../../chunk-HWWJAJWM.js";
|
|
73
73
|
import {
|
|
74
74
|
P,
|
|
75
75
|
setProfile
|
|
@@ -581,6 +581,70 @@ ${chain || "(no successor edges recorded)"}` }
|
|
|
581
581
|
return err(502, "family_summary_failed", String(e?.message ?? e).slice(0, 200));
|
|
582
582
|
}
|
|
583
583
|
}
|
|
584
|
+
async function loadUnitAsset(env, unitId) {
|
|
585
|
+
const row = await env.DB.prepare("SELECT payload, docidentifier FROM unit_payloads WHERE unit_id = ?1").bind(unitId).first();
|
|
586
|
+
if (!row) return { error: err(404, "not_found", "no unit_payload row for that id") };
|
|
587
|
+
const payload = JSON.parse(String(row.payload));
|
|
588
|
+
const uri = payload.uri ?? "";
|
|
589
|
+
const m = uri.match(/^\/assets\/(.+)/);
|
|
590
|
+
if (!m) return { error: err(400, "invalid_input", "payload has no /assets/ uri (upload the asset first)") };
|
|
591
|
+
const obj = await env.UNIT_ASSETS.get(m[1]);
|
|
592
|
+
if (!obj) return { error: err(404, "not_found", `asset ${m[1]} not in R2`) };
|
|
593
|
+
const buf = await obj.arrayBuffer();
|
|
594
|
+
const ext = m[1].split(".").pop()?.toLowerCase() ?? "png";
|
|
595
|
+
const mime = ext === "svg" ? "image/svg+xml" : `image/${ext === "jpg" ? "jpeg" : ext}`;
|
|
596
|
+
const bytes = new Uint8Array(buf);
|
|
597
|
+
let binary = "";
|
|
598
|
+
for (let i = 0; i < bytes.length; i += 8192) binary += String.fromCharCode(...bytes.subarray(i, i + 8192));
|
|
599
|
+
return { row, b64: btoa(binary), mime };
|
|
600
|
+
}
|
|
601
|
+
async function handleVisionJudge(env, req) {
|
|
602
|
+
if (!env.ADMIN_TOKEN) return err(501, "admin_disabled", "ADMIN_TOKEN secret is not configured");
|
|
603
|
+
const auth = req.headers.get("authorization") ?? "";
|
|
604
|
+
if (auth !== `Bearer ${env.ADMIN_TOKEN}`) return err(401, "unauthorized", "Invalid admin token");
|
|
605
|
+
const body = await readJson(req);
|
|
606
|
+
const unitId = typeof body?.unit_id === "string" ? body.unit_id : "";
|
|
607
|
+
const capA = typeof body?.captions?.a === "string" ? body.captions.a.slice(0, 2e3) : "";
|
|
608
|
+
const capB = typeof body?.captions?.b === "string" ? body.captions.b.slice(0, 2e3) : "";
|
|
609
|
+
if (!unitId || !capA || !capB) return err(400, "invalid_input", "unit_id and captions.a/.b required");
|
|
610
|
+
try {
|
|
611
|
+
const loaded = await loadUnitAsset(env, unitId);
|
|
612
|
+
if (loaded.error) return loaded.error;
|
|
613
|
+
const swap = Math.random() < 0.5;
|
|
614
|
+
const first = swap ? capB : capA;
|
|
615
|
+
const second = swap ? capA : capB;
|
|
616
|
+
const res = await env.AI.run(roleModel(env, "visionJudge"), {
|
|
617
|
+
messages: [
|
|
618
|
+
{
|
|
619
|
+
role: "user",
|
|
620
|
+
content: [
|
|
621
|
+
{ type: "text", text: `You are judging two descriptions of the same figure (from ${loaded.row.docidentifier}) written for a reader who cannot see it. The figure is attached.
|
|
622
|
+
|
|
623
|
+
Description 1: ${first}
|
|
624
|
+
|
|
625
|
+
Description 2: ${second}
|
|
626
|
+
|
|
627
|
+
Which description better tells the reader what the figure shows and its normative point? Reply with ONLY JSON: {"better": 1 or 2, "reason": "one sentence"}.` },
|
|
628
|
+
{ type: "image_url", image_url: { url: `data:${loaded.mime};base64,${loaded.b64}` } }
|
|
629
|
+
]
|
|
630
|
+
}
|
|
631
|
+
],
|
|
632
|
+
// the DeepSeek law: reasoning is always on — a 2048 budget starved
|
|
633
|
+
// the verdict to empty content (the E.2.2.x judges failed on
|
|
634
|
+
// "Unexpected end of JSON input"); 4096 leaves the JSON intact
|
|
635
|
+
max_tokens: 4096
|
|
636
|
+
});
|
|
637
|
+
const anyRes = res;
|
|
638
|
+
const text = typeof anyRes?.response === "string" ? anyRes.response : anyRes?.choices?.[0]?.message?.content ?? "";
|
|
639
|
+
const parsed = JSON.parse(text.replace(/^[^\{]*/, "").replace(/[^\}]*$/, ""));
|
|
640
|
+
const said = parsed?.better === 1 ? "first" : parsed?.better === 2 ? "second" : null;
|
|
641
|
+
if (!said) return err(502, "judge_failed", "no decision in the judge's reply: " + text.slice(0, 120));
|
|
642
|
+
const winner = said === "first" === swap ? "b" : "a";
|
|
643
|
+
return json({ ok: true, unit_id: unitId, better: winner, judge: roleModel(env, "visionJudge"), reason: String(parsed.reason ?? "").slice(0, 500) });
|
|
644
|
+
} catch (e) {
|
|
645
|
+
return err(502, "vision_judge_failed", String(e).slice(0, 200));
|
|
646
|
+
}
|
|
647
|
+
}
|
|
584
648
|
async function handleCaption(env, req) {
|
|
585
649
|
if (!env.ADMIN_TOKEN) return err(501, "admin_disabled", "ADMIN_TOKEN secret is not configured");
|
|
586
650
|
const auth = req.headers.get("authorization") ?? "";
|
|
@@ -588,27 +652,19 @@ async function handleCaption(env, req) {
|
|
|
588
652
|
const body = await readJson(req);
|
|
589
653
|
const unitId = typeof body?.unit_id === "string" ? body.unit_id : "";
|
|
590
654
|
const context = typeof body?.context === "string" ? body.context.slice(0, 400) : "";
|
|
655
|
+
const override = typeof body?.model === "string" && body.model.startsWith("@cf/") ? body.model : null;
|
|
656
|
+
const dryRun = body?.dry_run === true;
|
|
591
657
|
if (!unitId) return err(400, "invalid_input", "unit_id required");
|
|
592
658
|
try {
|
|
593
|
-
const
|
|
594
|
-
if (
|
|
595
|
-
const
|
|
596
|
-
const
|
|
597
|
-
const
|
|
598
|
-
if (!m) return err(400, "invalid_input", "payload has no /assets/ uri (upload the asset first)");
|
|
599
|
-
const obj = await env.UNIT_ASSETS.get(m[1]);
|
|
600
|
-
if (!obj) return err(404, "not_found", `asset ${m[1]} not in R2`);
|
|
601
|
-
const buf = await obj.arrayBuffer();
|
|
602
|
-
const ext = m[1].split(".").pop()?.toLowerCase() ?? "png";
|
|
603
|
-
const mime = ext === "svg" ? "image/svg+xml" : `image/${ext === "jpg" ? "jpeg" : ext}`;
|
|
604
|
-
const bytes = new Uint8Array(buf);
|
|
605
|
-
let binary = "";
|
|
606
|
-
for (let i = 0; i < bytes.length; i += 8192) binary += String.fromCharCode(...bytes.subarray(i, i + 8192));
|
|
607
|
-
const b64 = btoa(binary);
|
|
659
|
+
const loaded = await loadUnitAsset(env, unitId);
|
|
660
|
+
if (loaded.error) return loaded.error;
|
|
661
|
+
const row = loaded.row;
|
|
662
|
+
const b64 = loaded.b64;
|
|
663
|
+
const mime = loaded.mime;
|
|
608
664
|
let res = null;
|
|
609
665
|
for (let attempt = 0; attempt < 2 && !res; attempt++) {
|
|
610
666
|
try {
|
|
611
|
-
res = await env.AI.run(
|
|
667
|
+
res = await env.AI.run(override ?? roleModel(env, "caption"), {
|
|
612
668
|
messages: [
|
|
613
669
|
{
|
|
614
670
|
role: "user",
|
|
@@ -636,8 +692,8 @@ async function handleCaption(env, req) {
|
|
|
636
692
|
const end = Math.max(cut.lastIndexOf(". "), cut.lastIndexOf("! "), cut.lastIndexOf("? "));
|
|
637
693
|
return end === -1 ? cut.slice(0, cut.lastIndexOf(" ")) : cut.slice(0, end + 1);
|
|
638
694
|
})();
|
|
639
|
-
await env.DB.prepare("UPDATE unit_payloads SET payload = json_set(payload, '$.description', ?1) WHERE unit_id = ?2").bind(desc, unitId).run();
|
|
640
|
-
return json({ ok: true, unit_id: unitId, description: desc });
|
|
695
|
+
if (!dryRun) await env.DB.prepare("UPDATE unit_payloads SET payload = json_set(payload, '$.description', ?1) WHERE unit_id = ?2").bind(desc, unitId).run();
|
|
696
|
+
return json({ ok: true, unit_id: unitId, model: override ?? roleModel(env, "caption"), dry_run: dryRun || void 0, description: desc });
|
|
641
697
|
} catch (e) {
|
|
642
698
|
return err(502, "caption_failed", String(e).slice(0, 200));
|
|
643
699
|
}
|
|
@@ -1119,13 +1175,13 @@ async function callToolOnce(env, ctx, _req, tier, key, name, args, t0) {
|
|
|
1119
1175
|
// stream:false forces the JSON lane (anon defaults to SSE)
|
|
1120
1176
|
body: JSON.stringify({ ...args, stream: false })
|
|
1121
1177
|
});
|
|
1122
|
-
const { runTool, TOOLS_REGISTRY: TOOLS_REGISTRY2 } = await import("../../tools-
|
|
1178
|
+
const { runTool, TOOLS_REGISTRY: TOOLS_REGISTRY2 } = await import("../../tools-VHN54DWH.js");
|
|
1123
1179
|
let payload;
|
|
1124
1180
|
if (TOOLS_REGISTRY2.some((t) => t.name === name && t.audiences.includes("mcp"))) {
|
|
1125
1181
|
const r = await runTool({ ...env, DB: env.DB }, { name, args }, "mcp");
|
|
1126
1182
|
payload = r ? { tool: r.name, query: r.query, result: r.output } : { error: { message: `tool ${name} returned nothing for the given arguments` } };
|
|
1127
1183
|
} else {
|
|
1128
|
-
const res = name === "ask" ? await (await import("../../ask-
|
|
1184
|
+
const res = name === "ask" ? await (await import("../../ask-ZWZFZBKZ.js")).handleAsk(env, ctx, inner, tier, key) : await (await import("../../search-KNPPTHMG.js")).handleSearch(env, ctx, inner, tier, key);
|
|
1129
1185
|
payload = await res.json().catch(() => ({ error: { message: "tool transport failed", status: res.status } }));
|
|
1130
1186
|
}
|
|
1131
1187
|
telemetry(env, ctx, tier, `mcp:${name}`, null, !payload?.error, JSON.stringify(payload).length, await sha256Hex(`${name}:${JSON.stringify(args ?? {})}`), void 0, void 0, { durationMs: Date.now() - t0 });
|
|
@@ -1392,6 +1448,11 @@ var OPENAPI_SURFACE = [
|
|
|
1392
1448
|
"pattern": "/admin/caption",
|
|
1393
1449
|
"operationId": "adminCaption"
|
|
1394
1450
|
},
|
|
1451
|
+
{
|
|
1452
|
+
"method": "POST",
|
|
1453
|
+
"pattern": "/admin/vision_judge",
|
|
1454
|
+
"operationId": "adminVisionJudge"
|
|
1455
|
+
},
|
|
1395
1456
|
{
|
|
1396
1457
|
"method": "POST",
|
|
1397
1458
|
"pattern": "/v1/admin/judge",
|
|
@@ -1933,6 +1994,7 @@ var OPENAPI_HANDLERS = {
|
|
|
1933
1994
|
adminSectionAlias: (c) => handleSectionUnit(c.env, c.ctx, c.req),
|
|
1934
1995
|
adminVectors: (c) => handleVectors(c.env, c.req),
|
|
1935
1996
|
adminCaption: (c) => handleCaption(c.env, c.req),
|
|
1997
|
+
adminVisionJudge: (c) => handleVisionJudge(c.env, c.req),
|
|
1936
1998
|
adminJudge: (c) => handleJudge(c.env, c.req),
|
|
1937
1999
|
adminJudgeAlias: (c) => handleJudge(c.env, c.req)
|
|
1938
2000
|
};
|
|
@@ -4,8 +4,8 @@ import {
|
|
|
4
4
|
requestSalt,
|
|
5
5
|
resolveRequestScope,
|
|
6
6
|
standardKeysFrom
|
|
7
|
-
} from "../../chunk-
|
|
8
|
-
import "../../chunk-
|
|
7
|
+
} from "../../chunk-FNQ7UOEB.js";
|
|
8
|
+
import "../../chunk-HWWJAJWM.js";
|
|
9
9
|
import "../../chunk-3FYJM7LH.js";
|
|
10
10
|
export {
|
|
11
11
|
entitlementScope,
|
package/package.json
CHANGED
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"playwright": "^1.62.1",
|
|
28
28
|
"yaml": "^2.9.1"
|
|
29
29
|
},
|
|
30
|
-
"version": "0.2.
|
|
30
|
+
"version": "0.2.176",
|
|
31
31
|
"description": "The Konneal engine: the publisher-agnostic build pipeline and API plane for standards intelligence (retrieval, answer contract, verdicts, evaluation).",
|
|
32
32
|
"license": "BSD-3-Clause",
|
|
33
33
|
"type": "module",
|
|
@@ -1007,9 +1007,47 @@ paths:
|
|
|
1007
1007
|
context:
|
|
1008
1008
|
type: string
|
|
1009
1009
|
description: Surrounding clause text, at most 400 characters, to steer the description.
|
|
1010
|
+
model:
|
|
1011
|
+
type: string
|
|
1012
|
+
description: >-
|
|
1013
|
+
Per-request vision model override (an @cf/ id) — the
|
|
1014
|
+
caption A/B's measurement arm. Absent, the CAPTION_MODEL
|
|
1015
|
+
role (default glm-5.3-flash) serves.
|
|
1016
|
+
dry_run:
|
|
1017
|
+
type: boolean
|
|
1018
|
+
description: Return the description without storing it into the unit's payload.
|
|
1019
|
+
responses:
|
|
1020
|
+
'200':
|
|
1021
|
+
description: The description (stored, or returned only under dry_run).
|
|
1022
|
+
/admin/vision_judge:
|
|
1023
|
+
post:
|
|
1024
|
+
tags: [Administration]
|
|
1025
|
+
summary: Judge two captions of one figure against the image
|
|
1026
|
+
description: >-
|
|
1027
|
+
The caption A/B's pairwise judge — two anonymized descriptions of
|
|
1028
|
+
the same figure, presented in randomized order beside the image
|
|
1029
|
+
itself, decided by a third model that took no part in writing
|
|
1030
|
+
either. The vision A/B harness calls this lane.
|
|
1031
|
+
operationId: adminVisionJudge
|
|
1032
|
+
security: [{ adminAuth: [] }]
|
|
1033
|
+
requestBody:
|
|
1034
|
+
required: true
|
|
1035
|
+
content:
|
|
1036
|
+
application/json:
|
|
1037
|
+
schema:
|
|
1038
|
+
type: object
|
|
1039
|
+
required: [unit_id, captions]
|
|
1040
|
+
properties:
|
|
1041
|
+
unit_id: { type: string, description: The figure unit whose asset the captions describe. }
|
|
1042
|
+
captions:
|
|
1043
|
+
type: object
|
|
1044
|
+
required: [a, b]
|
|
1045
|
+
properties:
|
|
1046
|
+
a: { type: string }
|
|
1047
|
+
b: { type: string }
|
|
1010
1048
|
responses:
|
|
1011
1049
|
'200':
|
|
1012
|
-
description: The
|
|
1050
|
+
description: The winning arm (a or b) with the judge's reason.
|
|
1013
1051
|
/v1/admin/judge:
|
|
1014
1052
|
post:
|
|
1015
1053
|
tags: [Administration]
|
|
@@ -34,11 +34,16 @@ export interface AblateConfig {
|
|
|
34
34
|
* diversified subset + one strong verifier. Off in serving until the
|
|
35
35
|
* gate promotes it; the grid arms it per ask. */
|
|
36
36
|
speculative: boolean;
|
|
37
|
-
/** Extractive prompt compression (TODO.sota/02 row 5):
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
37
|
+
/** Extractive prompt compression (TODO.sota/02 row 5): PROMOTED — the
|
|
38
|
+
* passage bodies are query-weighted sentence selection at a fraction
|
|
39
|
+
* of their budget in serving (the row's gate: identical accuracy at
|
|
40
|
+
* ~1/20th the prompt, the whole-document baseline measured it).
|
|
41
|
+
* ablate_compress survives for the grid's explicit arm;
|
|
42
|
+
* ablate_no_compress is the measurement stand-down. */
|
|
41
43
|
compress: boolean;
|
|
44
|
+
/** Per-request stand-down for the promoted compressor (the
|
|
45
|
+
* measurement arm; the serving default is on). */
|
|
46
|
+
noCompress: boolean;
|
|
42
47
|
/** The decision pass (TODO.decisions/01): per-request stand-down for
|
|
43
48
|
* the measurement — the serving switch is DECISIONS_ENABLED. */
|
|
44
49
|
noDecisions: boolean;
|
|
@@ -64,11 +69,12 @@ export function parseAblate(
|
|
|
64
69
|
const rawRoute = body?.ablate_route;
|
|
65
70
|
const speculative = body?.ablate_speculative === true;
|
|
66
71
|
const compress = body?.ablate_compress === true;
|
|
72
|
+
const noCompress = body?.ablate_no_compress === true;
|
|
67
73
|
const noDecisions = body?.ablate_no_decisions === true;
|
|
68
74
|
const namesAblation = rawStages !== undefined && rawStages !== null;
|
|
69
75
|
const routeAblation = rawRoute !== undefined && rawRoute !== null && rawRoute !== "adaptive";
|
|
70
76
|
|
|
71
|
-
if (!namesAblation && !noVerdict && !routeAblation && !speculative && !compress && !noDecisions) return { ok: true, config: null };
|
|
77
|
+
if (!namesAblation && !noVerdict && !routeAblation && !speculative && !compress && !noCompress && !noDecisions) return { ok: true, config: null };
|
|
72
78
|
|
|
73
79
|
if (!adminToken || presentedToken !== adminToken) {
|
|
74
80
|
return {
|
|
@@ -103,5 +109,5 @@ export function parseAblate(
|
|
|
103
109
|
stages = [...new Set(rawStages as string[])];
|
|
104
110
|
}
|
|
105
111
|
|
|
106
|
-
return { ok: true, config: { stages, noVerdict, route, speculative, compress, noDecisions } };
|
|
112
|
+
return { ok: true, config: { stages, noVerdict, route, speculative, compress, noCompress, noDecisions } };
|
|
107
113
|
}
|
|
@@ -264,6 +264,77 @@ export async function handleFamilySummary(env: Env, req: Request): Promise<Respo
|
|
|
264
264
|
/** Ops access to the Vectorize binding (get/upsert by id) for offline
|
|
265
265
|
* passes like embedding smoothing (G-ETSI-4) — the binding is the
|
|
266
266
|
* credential, admin-token gated exactly like /admin/enrich. */
|
|
267
|
+
/** The unit's vision asset, base64-encoded for the message part — the
|
|
268
|
+
* one load path the caption and the pairwise judge share. */
|
|
269
|
+
async function loadUnitAsset(env: Env, unitId: string) {
|
|
270
|
+
const row = await env.DB.prepare("SELECT payload, docidentifier FROM unit_payloads WHERE unit_id = ?1").bind(unitId).first<any>();
|
|
271
|
+
if (!row) return { error: err(404, "not_found", "no unit_payload row for that id") };
|
|
272
|
+
const payload = JSON.parse(String(row.payload));
|
|
273
|
+
const uri = payload.uri ?? "";
|
|
274
|
+
const m = uri.match(/^\/assets\/(.+)/);
|
|
275
|
+
if (!m) return { error: err(400, "invalid_input", "payload has no /assets/ uri (upload the asset first)") };
|
|
276
|
+
const obj = await env.UNIT_ASSETS.get(m[1]);
|
|
277
|
+
if (!obj) return { error: err(404, "not_found", `asset ${m[1]} not in R2`) };
|
|
278
|
+
const buf = await obj.arrayBuffer();
|
|
279
|
+
const ext = m[1].split(".").pop()?.toLowerCase() ?? "png";
|
|
280
|
+
const mime = ext === "svg" ? "image/svg+xml" : `image/${ext === "jpg" ? "jpeg" : ext}`;
|
|
281
|
+
// chunked: spreading the whole byte array blows the V8 stack on large
|
|
282
|
+
// assets (the 389KB u:figure-1)
|
|
283
|
+
const bytes = new Uint8Array(buf);
|
|
284
|
+
let binary = "";
|
|
285
|
+
for (let i = 0; i < bytes.length; i += 8192) binary += String.fromCharCode(...bytes.subarray(i, i + 8192));
|
|
286
|
+
return { row, b64: btoa(binary), mime };
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/** The pairwise vision judge (TODO.sota/18.4's A/B): two anonymized
|
|
290
|
+
* captions of the SAME figure, presented in randomized order beside the
|
|
291
|
+
* image itself; a THIRD model (never a contestant) picks the better
|
|
292
|
+
* caption with a reason. Admin-gated; one-time quality-first lane. */
|
|
293
|
+
export async function handleVisionJudge(env: Env, req: Request): Promise<Response> {
|
|
294
|
+
if (!env.ADMIN_TOKEN) return err(501, "admin_disabled", "ADMIN_TOKEN secret is not configured");
|
|
295
|
+
const auth = req.headers.get("authorization") ?? "";
|
|
296
|
+
if (auth !== `Bearer ${env.ADMIN_TOKEN}`) return err(401, "unauthorized", "Invalid admin token");
|
|
297
|
+
const body = await readJson(req);
|
|
298
|
+
const unitId = typeof body?.unit_id === "string" ? body.unit_id : "";
|
|
299
|
+
const capA = typeof body?.captions?.a === "string" ? body.captions.a.slice(0, 2000) : "";
|
|
300
|
+
const capB = typeof body?.captions?.b === "string" ? body.captions.b.slice(0, 2000) : "";
|
|
301
|
+
if (!unitId || !capA || !capB) return err(400, "invalid_input", "unit_id and captions.a/.b required");
|
|
302
|
+
try {
|
|
303
|
+
const loaded = await loadUnitAsset(env, unitId);
|
|
304
|
+
if (loaded.error) return loaded.error;
|
|
305
|
+
// randomized presentation order: the judge's letter bias must not
|
|
306
|
+
// correlate with either arm
|
|
307
|
+
const swap = Math.random() < 0.5;
|
|
308
|
+
const first = swap ? capB : capA;
|
|
309
|
+
const second = swap ? capA : capB;
|
|
310
|
+
const res = await env.AI.run(roleModel(env, "visionJudge"), {
|
|
311
|
+
messages: [
|
|
312
|
+
{
|
|
313
|
+
role: "user",
|
|
314
|
+
content: [
|
|
315
|
+
{ type: "text", text: `You are judging two descriptions of the same figure (from ${loaded.row.docidentifier}) written for a reader who cannot see it. The figure is attached.\n\nDescription 1: ${first}\n\nDescription 2: ${second}\n\nWhich description better tells the reader what the figure shows and its normative point? Reply with ONLY JSON: {"better": 1 or 2, "reason": "one sentence"}.` },
|
|
316
|
+
{ type: "image_url", image_url: { url: `data:${loaded.mime};base64,${loaded.b64}` } },
|
|
317
|
+
],
|
|
318
|
+
},
|
|
319
|
+
],
|
|
320
|
+
// the DeepSeek law: reasoning is always on — a 2048 budget starved
|
|
321
|
+
// the verdict to empty content (the E.2.2.x judges failed on
|
|
322
|
+
// "Unexpected end of JSON input"); 4096 leaves the JSON intact
|
|
323
|
+
max_tokens: 4096,
|
|
324
|
+
});
|
|
325
|
+
const anyRes = res as any;
|
|
326
|
+
const text = typeof anyRes?.response === "string" ? anyRes.response : anyRes?.choices?.[0]?.message?.content ?? "";
|
|
327
|
+
const parsed = JSON.parse(text.replace(/^[^\{]*/, "").replace(/[^\}]*$/, ""));
|
|
328
|
+
const said = parsed?.better === 1 ? "first" : parsed?.better === 2 ? "second" : null;
|
|
329
|
+
if (!said) return err(502, "judge_failed", "no decision in the judge's reply: " + text.slice(0, 120));
|
|
330
|
+
// map back through the presentation swap
|
|
331
|
+
const winner = (said === "first") === swap ? "b" : "a";
|
|
332
|
+
return json({ ok: true, unit_id: unitId, better: winner, judge: roleModel(env, "visionJudge"), reason: String(parsed.reason ?? "").slice(0, 500) });
|
|
333
|
+
} catch (e) {
|
|
334
|
+
return err(502, "vision_judge_failed", String(e).slice(0, 200));
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
267
338
|
/** One-time figure captioning (TODO.remaining/03): fetch the unit's asset
|
|
268
339
|
* from R2, describe it with the vision-capable answer model, store the
|
|
269
340
|
* description into unit_payloads. Admin-gated; idempotent. */
|
|
@@ -274,29 +345,22 @@ export async function handleCaption(env: Env, req: Request): Promise<Response> {
|
|
|
274
345
|
const body = await readJson(req);
|
|
275
346
|
const unitId = typeof body?.unit_id === "string" ? body.unit_id : "";
|
|
276
347
|
const context = typeof body?.context === "string" ? body.context.slice(0, 400) : "";
|
|
348
|
+
// the A/B arm (TODO.sota/18.4): a per-request model override for the
|
|
349
|
+
// measurement, admin-gated like the route itself; dry_run skips the
|
|
350
|
+
// payload write so the arms never mix state in unit_payloads
|
|
351
|
+
const override = typeof body?.model === "string" && body.model.startsWith("@cf/") ? body.model : null;
|
|
352
|
+
const dryRun = body?.dry_run === true;
|
|
277
353
|
if (!unitId) return err(400, "invalid_input", "unit_id required");
|
|
278
354
|
try {
|
|
279
|
-
const
|
|
280
|
-
if (
|
|
281
|
-
const
|
|
282
|
-
const
|
|
283
|
-
const
|
|
284
|
-
if (!m) return err(400, "invalid_input", "payload has no /assets/ uri (upload the asset first)");
|
|
285
|
-
const obj = await env.UNIT_ASSETS.get(m[1]);
|
|
286
|
-
if (!obj) return err(404, "not_found", `asset ${m[1]} not in R2`);
|
|
287
|
-
const buf = await obj.arrayBuffer();
|
|
288
|
-
const ext = m[1].split(".").pop()?.toLowerCase() ?? "png";
|
|
289
|
-
const mime = ext === "svg" ? "image/svg+xml" : `image/${ext === "jpg" ? "jpeg" : ext}`;
|
|
290
|
-
// chunked: spreading the whole byte array blows the V8 stack on large
|
|
291
|
-
// assets (the 389KB u:figure-1)
|
|
292
|
-
const bytes = new Uint8Array(buf);
|
|
293
|
-
let binary = "";
|
|
294
|
-
for (let i = 0; i < bytes.length; i += 8192) binary += String.fromCharCode(...bytes.subarray(i, i + 8192));
|
|
295
|
-
const b64 = btoa(binary);
|
|
355
|
+
const loaded = await loadUnitAsset(env, unitId);
|
|
356
|
+
if (loaded.error) return loaded.error;
|
|
357
|
+
const row = loaded.row;
|
|
358
|
+
const b64 = loaded.b64;
|
|
359
|
+
const mime = loaded.mime;
|
|
296
360
|
let res: any = null;
|
|
297
361
|
for (let attempt = 0; attempt < 2 && !res; attempt++) {
|
|
298
362
|
try {
|
|
299
|
-
res = await env.AI.run(
|
|
363
|
+
res = await env.AI.run(override ?? roleModel(env, "caption"), {
|
|
300
364
|
messages: [
|
|
301
365
|
{
|
|
302
366
|
role: "user",
|
|
@@ -331,8 +395,8 @@ export async function handleCaption(env: Env, req: Request): Promise<Response> {
|
|
|
331
395
|
const end = Math.max(cut.lastIndexOf(". "), cut.lastIndexOf("! "), cut.lastIndexOf("? "));
|
|
332
396
|
return end === -1 ? cut.slice(0, cut.lastIndexOf(" ")) : cut.slice(0, end + 1);
|
|
333
397
|
})();
|
|
334
|
-
await env.DB.prepare("UPDATE unit_payloads SET payload = json_set(payload, '$.description', ?1) WHERE unit_id = ?2").bind(desc, unitId).run();
|
|
335
|
-
return json({ ok: true, unit_id: unitId, description: desc });
|
|
398
|
+
if (!dryRun) await env.DB.prepare("UPDATE unit_payloads SET payload = json_set(payload, '$.description', ?1) WHERE unit_id = ?2").bind(desc, unitId).run();
|
|
399
|
+
return json({ ok: true, unit_id: unitId, model: override ?? roleModel(env, "caption"), dry_run: dryRun || undefined, description: desc });
|
|
336
400
|
} catch (e) {
|
|
337
401
|
return err(502, "caption_failed", String(e).slice(0, 200));
|
|
338
402
|
}
|
|
@@ -35,7 +35,7 @@ import { entitlementScope, resolveRequestScope, requestSalt, standardKeysFrom }
|
|
|
35
35
|
import { rawSessionToken, type SessionClaims } from "./session";
|
|
36
36
|
import { cacheKeyMaterial, corpusGen, exactCacheKey, freshRequested } from "./answercache";
|
|
37
37
|
import { parseAblate } from "./ablate";
|
|
38
|
-
import { decisionsEnabled, gateQuestion, runDecisionPass } from "./decisionWire";
|
|
38
|
+
import { decisionsEnabled, gateQuestion, runDecisionPass, telemetryDecisions } from "./decisionWire";
|
|
39
39
|
import type { DecisionItem } from "./decisions";
|
|
40
40
|
import { STAGE_NAMES } from "./stages/index.ts";
|
|
41
41
|
import { routeFor, fastRouteStages } from "./route.ts";
|
|
@@ -1507,7 +1507,7 @@ let convEntities: Array<{ entity: string; kind: string }> = [];
|
|
|
1507
1507
|
[ops.note, processNote, eNote, regNote, contextNote(declaredCtx, docScope), accountNote, modelNote, vocabNote, memNote, machineNote, conditionNote, aggregationNote, boundaryNote, licenseNote, ...(retrieved.notes ?? [])].filter(Boolean).join("\n") || undefined,
|
|
1508
1508
|
summary,
|
|
1509
1509
|
budget,
|
|
1510
|
-
ablate?.
|
|
1510
|
+
ablate?.noCompress !== true,
|
|
1511
1511
|
);
|
|
1512
1512
|
// the decision pass (TODO.decisions/01): starts here so its calls run
|
|
1513
1513
|
// concurrently with generation — the checklist section arrives the
|
|
@@ -1730,15 +1730,21 @@ let convEntities: Array<{ entity: string; kind: string }> = [];
|
|
|
1730
1730
|
let streamedCompletionBlocks: Awaited<ReturnType<typeof completeTables>> = [];
|
|
1731
1731
|
// the decision pass's section streams as the answer's tail
|
|
1732
1732
|
// (the pass ran concurrently with generation — its arrival is
|
|
1733
|
-
// instant here), before the completions and the done event
|
|
1734
|
-
|
|
1733
|
+
// instant here), before the completions and the done event.
|
|
1734
|
+
// Stand-down law (TODO.decisions/00): where a deterministic
|
|
1735
|
+
// engine (verdict, condition, aggregation) answered, its block
|
|
1736
|
+
// is authoritative — the checklist never rides beside it.
|
|
1737
|
+
let streamedDecisions: { mode: string; gate: number; items: DecisionItem[] } | undefined;
|
|
1738
|
+
if (decisionPromise && !canonical0.includes(refusalAnswer()) && !verdictBlock && !conditionBlock && !aggregationBlock) {
|
|
1735
1739
|
const dp = await decisionPromise;
|
|
1736
1740
|
if (dp) {
|
|
1737
1741
|
canonical0 += dp.section;
|
|
1738
1742
|
send({ type: "token", v: dp.section });
|
|
1739
1743
|
full += dp.section;
|
|
1744
|
+
streamedDecisions = { mode: dp.mode, gate: dp.gate, items: dp.items };
|
|
1740
1745
|
console.log("decisions: streamed the checklist section (" + dp.items.length + " items, mode " + dp.mode + ")");
|
|
1741
1746
|
}
|
|
1747
|
+
telemetryDecisions(env, ctx, tier, queryHash, streamedDecisions ?? null, Date.now() - tStart);
|
|
1742
1748
|
}
|
|
1743
1749
|
if (!canonical0.includes(refusalAnswer())) {
|
|
1744
1750
|
try {
|
|
@@ -1747,7 +1753,7 @@ let convEntities: Array<{ entity: string; kind: string }> = [];
|
|
|
1747
1753
|
if (streamedCompletionBlocks.length) console.log("streamed completion:", streamedCompletionBlocks.length, "block(s) attached");
|
|
1748
1754
|
} catch { /* additive — the answer stands without the blocks */ }
|
|
1749
1755
|
}
|
|
1750
|
-
send({ type: "done", model, query_hash: queryHash, follow_ups: refusalShaped(canonical0, refusalScope(answerCites(full))) ? [] : (understanding?.follow_ups ?? []), blocks: [...c2.blocks, ...(verdictBlock ? [verdictBlock] : []), ...(conditionBlock ? [conditionBlock] : []), ...(aggregationBlock ? [aggregationBlock] : []), ...streamedCompletionBlocks], context_applied: ctxApplied, read: readAs(),
|
|
1756
|
+
send({ type: "done", model, query_hash: queryHash, follow_ups: refusalShaped(canonical0, refusalScope(answerCites(full))) ? [] : (understanding?.follow_ups ?? []), ...(streamedDecisions ? { decisions: streamedDecisions } : {}), blocks: [...c2.blocks, ...(verdictBlock ? [verdictBlock] : []), ...(conditionBlock ? [conditionBlock] : []), ...(aggregationBlock ? [aggregationBlock] : []), ...streamedCompletionBlocks], context_applied: ctxApplied, read: readAs(),
|
|
1751
1757
|
// the evidence view's ground truth: the exact passages this
|
|
1752
1758
|
// answer was built from, compact — cache hits carry none,
|
|
1753
1759
|
// because the cache stores the answer and never the passages
|
|
@@ -1999,7 +2005,7 @@ let convEntities: Array<{ entity: string; kind: string }> = [];
|
|
|
1999
2005
|
...(routeSubset ? { stageSubset: routeSubset ?? undefined } : {}),
|
|
2000
2006
|
});
|
|
2001
2007
|
if (retryRetrieve.hits.length > 0) {
|
|
2002
|
-
const { messages: retryMessages, usedHits: retryUsed } = buildMessages(q.query, retryRetrieve.hits, q.lang, keptHistory, undefined, summary, budget, ablate?.
|
|
2008
|
+
const { messages: retryMessages, usedHits: retryUsed } = buildMessages(q.query, retryRetrieve.hits, q.lang, keptHistory, undefined, summary, budget, ablate?.noCompress !== true);
|
|
2003
2009
|
const retryAnswer = await generateOnce(env, model, retryMessages, routeEffort(routed.route));
|
|
2004
2010
|
// the answer now comes from the retry passages — citations must follow
|
|
2005
2011
|
if (retryAnswer) {
|
|
@@ -2083,10 +2089,11 @@ let convEntities: Array<{ entity: string; kind: string }> = [];
|
|
|
2083
2089
|
let decisionsOut: { mode: string; gate: number; items: DecisionItem[] } | undefined;
|
|
2084
2090
|
if (decisionPromise) {
|
|
2085
2091
|
const dp = await decisionPromise;
|
|
2086
|
-
if (dp && answer && !answer!.includes(refusalAnswer())) {
|
|
2092
|
+
if (dp && answer && !answer!.includes(refusalAnswer()) && !verdictBlock && !conditionBlock && !aggregationBlock) {
|
|
2087
2093
|
answer = answer! + dp.section;
|
|
2088
2094
|
decisionsOut = { mode: dp.mode, gate: dp.gate, items: dp.items };
|
|
2089
2095
|
}
|
|
2096
|
+
telemetryDecisions(env, ctx, tier, queryHash, decisionsOut ?? null, Date.now() - tStart);
|
|
2090
2097
|
}
|
|
2091
2098
|
const out = { answer, citations: finalCites, ...(jsonQuality ? { source_quality: jsonQuality!, confidence_note: entailmentNote || qualityNote(jsonQuality!), ...(entailment ? { entailment } : {}), ...(jsonQuality === "ocr" ? { experimental_sources: experimentalSourceLabels(finalCites) } : {}) } : {}), model: MODELS.member, query_hash: queryHash, follow_ups: refusalShaped(answer!, refusalScope(answerCites(answer!))) ? [] : (understanding?.follow_ups ?? []), blocks: [...c2ns.blocks, ...(verdictBlock ? [verdictBlock] : []), ...(conditionBlock ? [conditionBlock] : []), ...(aggregationBlock ? [aggregationBlock] : []), ...(registerBlock ? [registerBlock] : []), ...completionBlocks], context_applied: ctxApplied, ...(liveRecords ? { records: liveRecords } : {}), ...(decisionsOut ? { decisions: decisionsOut } : {}), ...(ablate ? { ablate } : {}), route: { route: routed.route, features: routed.features } };
|
|
2092
2099
|
const cacheable = !contextual && !declaredCtx && !ablate && cacheableAnswer(answer!, refusalScope(answerCites(answer!))) && finalAnchors.violations.length === 0;
|
|
@@ -7,6 +7,13 @@ export const MODELS = {
|
|
|
7
7
|
// Vision image-parts land with answer contract v2; text answers work now.
|
|
8
8
|
anon: "@cf/zai-org/glm-5.3-flash",
|
|
9
9
|
member: "@cf/zai-org/glm-5.3-flash",
|
|
10
|
+
// figure captions + the vision lane (one-time, quality-first; the A/B
|
|
11
|
+
// lever is CAPTION_MODEL, the per-request arm is the admin route's
|
|
12
|
+
// body.model)
|
|
13
|
+
caption: "@cf/zai-org/glm-5.3-flash",
|
|
14
|
+
// the pairwise vision judge (sees the image; a THIRD model never
|
|
15
|
+
// judges its own arm)
|
|
16
|
+
visionJudge: "@cf/deepseek-ai/deepseek-v4.1-flash-1017",
|
|
10
17
|
// the VLM figure rerank (TODO.sota/18.3): the newly-landed
|
|
11
18
|
// vision-capable MoE scores figure IMAGES against figure-seeking
|
|
12
19
|
// questions — one bounded call per figure question, ablatable stage
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
// when DECISIONS_ENABLED, not ablated, not a refusal, no verdict block
|
|
5
5
|
// bound, and the gate's noul clears decisionsGateMin.
|
|
6
6
|
import { portModelRunner } from "./env.ts";
|
|
7
|
+
import { telemetry } from "./quota";
|
|
7
8
|
import { MODELS, THRESHOLDS } from "./config.ts";
|
|
8
9
|
import {
|
|
9
10
|
buildDecisionQuestions, matchAnswers, parseDerivation,
|
|
@@ -126,3 +127,27 @@ export async function runDecisionPass(
|
|
|
126
127
|
return null; // additive — the essay answer ships
|
|
127
128
|
}
|
|
128
129
|
}
|
|
130
|
+
|
|
131
|
+
/** The decisions telemetry (TODO.decisions/03): the nightly's
|
|
132
|
+
* calibration signal, riding the queries table's route key with a
|
|
133
|
+
* defined encoding — no schema migration.
|
|
134
|
+
* - one PASS row, route "ask-decisions": ok = fired, lang = mode,
|
|
135
|
+
* model = the gate probability (2dp), duration_ms = the pass's.
|
|
136
|
+
* - one ITEM row per requirement, route "ask-decision": ok = band is
|
|
137
|
+
* "met", lang = band, model = the probability (2dp); query_hash
|
|
138
|
+
* joins the rows to their pass. */
|
|
139
|
+
export function telemetryDecisions(
|
|
140
|
+
env: Env,
|
|
141
|
+
ctx: { waitUntil(p: Promise<unknown>): void },
|
|
142
|
+
tier: string,
|
|
143
|
+
queryHash: string,
|
|
144
|
+
result: { mode: string; gate: number; items: DecisionItem[] } | null,
|
|
145
|
+
durationMs: number,
|
|
146
|
+
): void {
|
|
147
|
+
try {
|
|
148
|
+
telemetry(env, ctx, tier, "ask-decisions", result ? result.gate.toFixed(2) : "0", !!result, result?.items.length ?? 0, queryHash, result?.mode ?? undefined, undefined, { durationMs });
|
|
149
|
+
for (const it of result?.items ?? []) {
|
|
150
|
+
telemetry(env, ctx, tier, "ask-decision", it.probability.toFixed(2), it.band === "met", 1, queryHash, it.band, undefined, {});
|
|
151
|
+
}
|
|
152
|
+
} catch { /* telemetry never answers for the answer */ }
|
|
153
|
+
}
|
|
@@ -23,7 +23,7 @@ import { json, err, corsHeaders, withCors, readJson, authenticate, type ApiKey }
|
|
|
23
23
|
import { creditBudget, clientIp } from "./quota";
|
|
24
24
|
|
|
25
25
|
import { handleSearch } from "./search";
|
|
26
|
-
import { handleEnrich, handleSectionUnit, handleCaption, handleVectors, handleJudge, handleCreateKey, handleListKeys, handleRevokeKey, handleKeyUsage, handleFamilySummary } from "./admin";
|
|
26
|
+
import { handleEnrich, handleSectionUnit, handleCaption, handleVisionJudge, handleVectors, handleJudge, handleCreateKey, handleListKeys, handleRevokeKey, handleKeyUsage, handleFamilySummary } from "./admin";
|
|
27
27
|
import { handleResearch } from "./research";
|
|
28
28
|
import { uploadAttachment, readAttachment, deleteAttachment, type AttachmentDeps } from "./attachments";
|
|
29
29
|
import { cfBlobs } from "./ports/cloudflare/adapters";
|
|
@@ -639,6 +639,7 @@ const OPENAPI_HANDLERS: Record<OpenApiOperationId, RouteHandler> = {
|
|
|
639
639
|
adminSectionAlias: (c) => handleSectionUnit(c.env, c.ctx, c.req),
|
|
640
640
|
adminVectors: (c) => handleVectors(c.env, c.req),
|
|
641
641
|
adminCaption: (c) => handleCaption(c.env, c.req),
|
|
642
|
+
adminVisionJudge: (c) => handleVisionJudge(c.env, c.req),
|
|
642
643
|
adminJudge: (c) => handleJudge(c.env, c.req),
|
|
643
644
|
adminJudgeAlias: (c) => handleJudge(c.env, c.req),
|
|
644
645
|
};
|
|
@@ -53,6 +53,7 @@ export type OpenApiOperationId =
|
|
|
53
53
|
| "adminFamilySummaryAlias"
|
|
54
54
|
| "adminVectors"
|
|
55
55
|
| "adminCaption"
|
|
56
|
+
| "adminVisionJudge"
|
|
56
57
|
| "adminJudge"
|
|
57
58
|
| "adminJudgeAlias"
|
|
58
59
|
| "adminRevokeKey"
|
|
@@ -296,6 +297,11 @@ export const OPENAPI_SURFACE: readonly (Omit<OpenApiRoute, "operationId"> & { op
|
|
|
296
297
|
"pattern": "/admin/caption",
|
|
297
298
|
"operationId": "adminCaption"
|
|
298
299
|
},
|
|
300
|
+
{
|
|
301
|
+
"method": "POST",
|
|
302
|
+
"pattern": "/admin/vision_judge",
|
|
303
|
+
"operationId": "adminVisionJudge"
|
|
304
|
+
},
|
|
299
305
|
{
|
|
300
306
|
"method": "POST",
|
|
301
307
|
"pattern": "/v1/admin/judge",
|
|
@@ -288,9 +288,10 @@ export function buildMessages(
|
|
|
288
288
|
retrievalNote?: string,
|
|
289
289
|
conversationSummary?: string,
|
|
290
290
|
budgetTokens: number = LIMITS.inputTokenBudget,
|
|
291
|
-
/** the extractive compression
|
|
292
|
-
*
|
|
293
|
-
*
|
|
291
|
+
/** the extractive compression (TODO.sota/02 row 5): PROMOTED — on in
|
|
292
|
+
* serving; ablate_no_compress stands it down per ask for the
|
|
293
|
+
* measurement. Each passage body becomes query-weighted sentence
|
|
294
|
+
* selection at compressShare of its budget. */
|
|
294
295
|
compress?: boolean,
|
|
295
296
|
): BuiltMessages {
|
|
296
297
|
// per-corpus guidance travels WITH the dataset (config.ts): every
|
package/dist/ask-4T3E2Z6J.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
handleAsk
|
|
3
|
-
} from "./chunk-KKJHJXQV.js";
|
|
4
|
-
import "./chunk-ECOYO7EX.js";
|
|
5
|
-
import "./chunk-QS6V53RO.js";
|
|
6
|
-
import "./chunk-RZLEHCIA.js";
|
|
7
|
-
import "./chunk-XWSZWFYP.js";
|
|
8
|
-
import "./chunk-O2XMNKCK.js";
|
|
9
|
-
import "./chunk-ETLSWSZ7.js";
|
|
10
|
-
import "./chunk-PQDAL4MX.js";
|
|
11
|
-
import "./chunk-5UIMQAJZ.js";
|
|
12
|
-
import "./chunk-3FYJM7LH.js";
|
|
13
|
-
import "./chunk-KINFFYQH.js";
|
|
14
|
-
export {
|
|
15
|
-
handleAsk
|
|
16
|
-
};
|
package/dist/search-RNCRT5BR.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
handleSearch
|
|
3
|
-
} from "./chunk-6KEWBP7O.js";
|
|
4
|
-
import "./chunk-RZLEHCIA.js";
|
|
5
|
-
import "./chunk-XWSZWFYP.js";
|
|
6
|
-
import "./chunk-O2XMNKCK.js";
|
|
7
|
-
import "./chunk-ETLSWSZ7.js";
|
|
8
|
-
import "./chunk-PQDAL4MX.js";
|
|
9
|
-
import "./chunk-5UIMQAJZ.js";
|
|
10
|
-
import "./chunk-3FYJM7LH.js";
|
|
11
|
-
import "./chunk-KINFFYQH.js";
|
|
12
|
-
export {
|
|
13
|
-
handleSearch
|
|
14
|
-
};
|