@konneal/engine 0.2.163 → 0.2.165

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 CHANGED
@@ -13,6 +13,11 @@ 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): each passage
17
+ * body is query-weighted sentence selection at a fraction of its
18
+ * budget before the answer model reads it. Off in serving; the grid
19
+ * arms it per ask (the row's accuracy-at-token-budget gate). */
20
+ compress: boolean;
16
21
  }
17
22
  export type AblateParse = {
18
23
  ok: true;
@@ -0,0 +1,16 @@
1
+ import {
2
+ handleAsk
3
+ } from "./chunk-35NEP7QL.js";
4
+ import "./chunk-ECOYO7EX.js";
5
+ import "./chunk-X6GUTX76.js";
6
+ import "./chunk-7SLZ5OEO.js";
7
+ import "./chunk-POW7OTLB.js";
8
+ import "./chunk-HIQSYUAU.js";
9
+ import "./chunk-ETLSWSZ7.js";
10
+ import "./chunk-C67BN6G3.js";
11
+ import "./chunk-DNKWDI4G.js";
12
+ import "./chunk-3FYJM7LH.js";
13
+ import "./chunk-LSZTJI7V.js";
14
+ export {
15
+ handleAsk
16
+ };
@@ -32,7 +32,7 @@ import {
32
32
  tableRetyped,
33
33
  toolNote,
34
34
  verdictNote
35
- } from "./chunk-6OD35FOY.js";
35
+ } from "./chunk-X6GUTX76.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-MTIAHAOK.js";
78
+ } from "./chunk-7SLZ5OEO.js";
79
79
  import {
80
80
  embed,
81
81
  generateOnce
82
- } from "./chunk-NI4CIK6W.js";
82
+ } from "./chunk-POW7OTLB.js";
83
83
  import {
84
84
  corsHeaders,
85
85
  err,
86
86
  json,
87
87
  readJson,
88
88
  validateQuery
89
- } from "./chunk-W7J5SFXJ.js";
89
+ } from "./chunk-HIQSYUAU.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-4NXH5ZI6.js";
102
+ } from "./chunk-C67BN6G3.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-VT7DR6NQ.js";
113
+ } from "./chunk-DNKWDI4G.js";
114
114
  import {
115
115
  P
116
116
  } from "./chunk-3FYJM7LH.js";
@@ -470,13 +470,19 @@ async function completeTables(db, answer, used) {
470
470
  }
471
471
  return blocks;
472
472
  }
473
- async function completeFigures(db, answer, alreadyAttached, used = []) {
473
+ async function completeFigures(db, answer, alreadyAttached, used = [], query) {
474
474
  const unitForm = (answer.match(/u:fig[\w.-]*/g) ?? []).map((x) => x.replace(/[.,;:)]+$/, ""));
475
475
  const bareForm = (answer.match(/\bfig-[\w.-]+\b/g) ?? []).map((x) => x.replace(/[.,;:)]+$/, ""));
476
476
  let mentioned = [.../* @__PURE__ */ new Set([...unitForm, ...bareForm.map((x) => x.startsWith("u:") ? x : "u:" + x)])].slice(0, 6);
477
477
  const proseNums = new Set(
478
478
  (answer.match(/\bFig(?:ure|\.)s?\s*([0-9]{1,2}[a-z]?)/g) ?? []).map((x) => x.replace(/\bFig(?:ure|\.)s?\s*/i, "").toLowerCase())
479
479
  );
480
+ if (query && /\bfig(ure|s)?\b/i.test(query)) {
481
+ for (const h of used.slice(0, 12)) {
482
+ if (h.metadata.unit_id && h.metadata.block === "figure") mentioned.push(h.metadata.unit_id);
483
+ }
484
+ mentioned = [...new Set(mentioned)].slice(0, 6);
485
+ }
480
486
  if (proseNums.size) {
481
487
  const fams = [...new Set(used.map((h) => h.metadata.docidentifier).filter(Boolean))].slice(0, 3);
482
488
  for (const fam of fams) {
@@ -1397,9 +1403,10 @@ function parseAblate(body, adminToken, presentedToken, knownStages) {
1397
1403
  const noVerdict = body?.ablate_no_verdict === true;
1398
1404
  const rawRoute = body?.ablate_route;
1399
1405
  const speculative = body?.ablate_speculative === true;
1406
+ const compress = body?.ablate_compress === true;
1400
1407
  const namesAblation = rawStages !== void 0 && rawStages !== null;
1401
1408
  const routeAblation = rawRoute !== void 0 && rawRoute !== null && rawRoute !== "adaptive";
1402
- if (!namesAblation && !noVerdict && !routeAblation && !speculative) return { ok: true, config: null };
1409
+ if (!namesAblation && !noVerdict && !routeAblation && !speculative && !compress) return { ok: true, config: null };
1403
1410
  if (!adminToken || presentedToken !== adminToken) {
1404
1411
  return {
1405
1412
  ok: false,
@@ -1430,7 +1437,7 @@ function parseAblate(body, adminToken, presentedToken, knownStages) {
1430
1437
  }
1431
1438
  stages = [...new Set(rawStages)];
1432
1439
  }
1433
- return { ok: true, config: { stages, noVerdict, route, speculative } };
1440
+ return { ok: true, config: { stages, noVerdict, route, speculative, compress } };
1434
1441
  }
1435
1442
 
1436
1443
  // workers/worker_public/src/route.ts
@@ -2636,7 +2643,8 @@ Answer account questions from these records ONLY: name the record when you use i
2636
2643
  // stage-extracted graph facts (GraphRAG) ride the same note channel
2637
2644
  [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,
2638
2645
  summary,
2639
- budget
2646
+ budget,
2647
+ ablate?.compress === true
2640
2648
  );
2641
2649
  await attachFigureImages(env, messages, usedHits, q2.query);
2642
2650
  const pendingTools = [];
@@ -2946,7 +2954,7 @@ Answer account questions from these records ONLY: name the record when you use i
2946
2954
  ...routeSubset ? { stageSubset: routeSubset ?? void 0 } : {}
2947
2955
  });
2948
2956
  if (retryRetrieve.hits.length > 0) {
2949
- const { messages: retryMessages, usedHits: retryUsed } = buildMessages(q2.query, retryRetrieve.hits, q2.lang, keptHistory, void 0, summary, budget);
2957
+ const { messages: retryMessages, usedHits: retryUsed } = buildMessages(q2.query, retryRetrieve.hits, q2.lang, keptHistory, void 0, summary, budget, ablate?.compress === true);
2950
2958
  const retryAnswer = await generateOnce(env, model, retryMessages, routeEffort(routed.route));
2951
2959
  if (retryAnswer) {
2952
2960
  answer = canonicalRefusal(retryAnswer, refusalScope(answerCites(retryAnswer)));
@@ -2971,7 +2979,7 @@ Answer account questions from these records ONLY: name the record when you use i
2971
2979
  completionBlocks = await completeTables(env.DB, answer, used);
2972
2980
  if (completionBlocks.length) console.log("contract completion:", completionBlocks.length, "table block(s) attached server-side");
2973
2981
  }
2974
- completionBlocks.push(...await completeFigures(env.DB, answer, [...c2ns.blocks, ...completionBlocks], used));
2982
+ completionBlocks.push(...await completeFigures(env.DB, answer, [...c2ns.blocks, ...completionBlocks], used, q2.query));
2975
2983
  if (withImage && register?.rows?.length && answer.includes(refusalAnswer())) {
2976
2984
  console.log("blind-answer: the register note carried rows but the answer refused \u2014 regenerating once");
2977
2985
  mark("Re-answering from the register results");
@@ -6,24 +6,24 @@ import {
6
6
  sessionFrom,
7
7
  telemetry,
8
8
  understandQuery
9
- } from "./chunk-MTIAHAOK.js";
9
+ } from "./chunk-7SLZ5OEO.js";
10
10
  import {
11
11
  corsHeaders,
12
12
  err,
13
13
  json,
14
14
  readJson,
15
15
  validateQuery
16
- } from "./chunk-W7J5SFXJ.js";
16
+ } from "./chunk-HIQSYUAU.js";
17
17
  import {
18
18
  entitlementScope,
19
19
  standardKeysFrom
20
- } from "./chunk-4NXH5ZI6.js";
20
+ } from "./chunk-C67BN6G3.js";
21
21
  import {
22
22
  LIMITS,
23
23
  MODELS,
24
24
  num,
25
25
  sha256Hex
26
- } from "./chunk-VT7DR6NQ.js";
26
+ } from "./chunk-DNKWDI4G.js";
27
27
  import {
28
28
  portModelRunner
29
29
  } from "./chunk-LSZTJI7V.js";
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  embed,
3
3
  rerank
4
- } from "./chunk-NI4CIK6W.js";
4
+ } from "./chunk-POW7OTLB.js";
5
5
  import {
6
6
  bubbleConfirmPage,
7
7
  isAllowedBubbleOrigin
8
- } from "./chunk-W7J5SFXJ.js";
8
+ } from "./chunk-HIQSYUAU.js";
9
9
  import {
10
10
  DATASETS,
11
11
  LIMITS,
@@ -15,12 +15,13 @@ import {
15
15
  processExpansion,
16
16
  sha256Hex,
17
17
  today
18
- } from "./chunk-VT7DR6NQ.js";
18
+ } from "./chunk-DNKWDI4G.js";
19
19
  import {
20
20
  P
21
21
  } from "./chunk-3FYJM7LH.js";
22
22
  import {
23
23
  hasLane,
24
+ portBlobs,
24
25
  portIndex,
25
26
  portModelRunner,
26
27
  portStore
@@ -1747,13 +1748,13 @@ var UnBuilder = class extends BaseBuilder {
1747
1748
  return key === "token";
1748
1749
  }
1749
1750
  build(data) {
1750
- const tokens = this.extractTokens(Array.isArray(data) ? data : data["token"]);
1751
- if (tokens.length === 0)
1751
+ const tokens2 = this.extractTokens(Array.isArray(data) ? data : data["token"]);
1752
+ if (tokens2.length === 0)
1752
1753
  throw new ParseFailed("UN identifier has no tokens", 0);
1753
- const path = tokens.slice(0, -1);
1754
+ const path = tokens2.slice(0, -1);
1754
1755
  const yearToken = [...path].reverse().find((t) => /^\d{4}$/.test(t));
1755
1756
  const attrs = {
1756
- number: tokens[tokens.length - 1],
1757
+ number: tokens2[tokens2.length - 1],
1757
1758
  path
1758
1759
  };
1759
1760
  if (yearToken)
@@ -3778,7 +3779,7 @@ function jisGrammarImplementation() {
3778
3779
  }
3779
3780
 
3780
3781
  // node_modules/@pubid/pubid/dist/flavors/iec/model.js
3781
- var TS = (code, stageCode, typeCode, abbr, harmonized, tokens) => ({ code, stageCode, typeCode, abbr, harmonized, tokens });
3782
+ var TS = (code, stageCode, typeCode, abbr, harmonized, tokens2) => ({ code, stageCode, typeCode, abbr, harmonized, tokens: tokens2 });
3782
3783
  var TYPED_STAGES = [
3783
3784
  TS("is", "published", "is", ""),
3784
3785
  TS("tr", "published", "tr", "TR"),
@@ -4332,8 +4333,8 @@ function parseLanguages2(tree) {
4332
4333
  const raw = s(tree);
4333
4334
  if (raw === void 0)
4334
4335
  return [];
4335
- const tokens = raw.split(",").flatMap((chunk) => chunk.split("/"));
4336
- return tokens.map((token) => token.trim()).filter((token) => token !== "").map((original) => {
4336
+ const tokens2 = raw.split(",").flatMap((chunk) => chunk.split("/"));
4337
+ return tokens2.map((token) => token.trim()).filter((token) => token !== "").map((original) => {
4337
4338
  const code = original.length === 1 ? Language.CHAR_MAP[original] ?? original.toLowerCase() : original;
4338
4339
  return new Language({ code, originalCode: original });
4339
4340
  });
@@ -5582,8 +5583,8 @@ var TYPE_WORD_TO_CODE = (() => {
5582
5583
  return map;
5583
5584
  })();
5584
5585
  var LANGUAGE_ALIASES = { EN: "E", FR: "F" };
5585
- function alternation(tokens) {
5586
- const sorted = [...tokens].sort((a, b) => b.length - a.length);
5586
+ function alternation(tokens2) {
5587
+ const sorted = [...tokens2].sort((a, b) => b.length - a.length);
5587
5588
  return sorted.map((t) => str(t)).reduce((a, b) => a.or(b));
5588
5589
  }
5589
5590
  function buildRules24() {
@@ -6863,8 +6864,8 @@ function publishedStage(typeKey) {
6863
6864
  }
6864
6865
  function stageTokens2(typeKeys) {
6865
6866
  const stages = typeKeys === void 0 ? ISO_TYPED_STAGES : ISO_TYPED_STAGES.filter((s8) => typeKeys.includes(s8.typeKey));
6866
- const tokens = stages.flatMap((s8) => s8.abbr.filter((a) => a !== ""));
6867
- return [...new Set(tokens)].sort((a, b) => b.length - a.length);
6867
+ const tokens2 = stages.flatMap((s8) => s8.abbr.filter((a) => a !== ""));
6868
+ return [...new Set(tokens2)].sort((a, b) => b.length - a.length);
6868
6869
  }
6869
6870
  function stageAbbr(entry, formatLong, originalAbbr) {
6870
6871
  if (formatLong && entry.longAbbr !== void 0)
@@ -7697,8 +7698,8 @@ var WG_TYPES = [
7697
7698
  "JTAG",
7698
7699
  "JTG"
7699
7700
  ];
7700
- function literalAlternation(tokens) {
7701
- const sorted = [...new Set(tokens)].sort((a, b) => b.length - a.length);
7701
+ function literalAlternation(tokens2) {
7702
+ const sorted = [...new Set(tokens2)].sort((a, b) => b.length - a.length);
7702
7703
  return sorted.map((t) => str(t)).reduce((a, b) => a.or(b));
7703
7704
  }
7704
7705
  function buildRules25() {
@@ -8171,8 +8172,8 @@ var MONTHS = [
8171
8172
  "Nov",
8172
8173
  "Dec"
8173
8174
  ];
8174
- function literalAlternation2(tokens) {
8175
- const sorted = [...new Set(tokens)].sort((a, b) => b.length - a.length);
8175
+ function literalAlternation2(tokens2) {
8176
+ const sorted = [...new Set(tokens2)].sort((a, b) => b.length - a.length);
8176
8177
  return sorted.map((t) => str(t)).reduce((a, b) => a.or(b));
8177
8178
  }
8178
8179
  function buildRules26() {
@@ -10543,8 +10544,8 @@ var MONTHS2 = [
10543
10544
  "Nov",
10544
10545
  "Dec"
10545
10546
  ];
10546
- function literalAlternation3(tokens) {
10547
- const sorted = [...new Set(tokens)].sort((a, b) => b.length - a.length);
10547
+ function literalAlternation3(tokens2) {
10548
+ const sorted = [...new Set(tokens2)].sort((a, b) => b.length - a.length);
10548
10549
  return sorted.map((t) => str(t)).reduce((a, b) => a.or(b));
10549
10550
  }
10550
10551
  function buildRules27() {
@@ -14930,8 +14931,8 @@ var RM_ABBRS = [
14930
14931
  "RM"
14931
14932
  ];
14932
14933
  var SUPPLEMENT_ABBRS = ["AMD", "COR"];
14933
- function abbrAlternation(tokens) {
14934
- const sorted = [...new Set(tokens)].sort((a, b) => b.length - a.length);
14934
+ function abbrAlternation(tokens2) {
14935
+ const sorted = [...new Set(tokens2)].sort((a, b) => b.length - a.length);
14935
14936
  return sorted.map((t) => str(t)).reduce((a, b) => a.or(b));
14936
14937
  }
14937
14938
  function buildRules30() {
@@ -15857,9 +15858,9 @@ function adoptIdentifier(raw) {
15857
15858
  function splitPrefix(text) {
15858
15859
  if (text === void 0)
15859
15860
  return [void 0, void 0];
15860
- const tokens = text.trim().split(/\s+/);
15861
- const copublisher = normalizeCopublisher(tokens[0]);
15862
- const subtype = tokens.length > 1 ? normalizeSubtype(tokens.slice(1).join(" ")) : void 0;
15861
+ const tokens2 = text.trim().split(/\s+/);
15862
+ const copublisher = normalizeCopublisher(tokens2[0]);
15863
+ const subtype = tokens2.length > 1 ? normalizeSubtype(tokens2.slice(1).join(" ")) : void 0;
15863
15864
  return [copublisher, subtype];
15864
15865
  }
15865
15866
  function normalizeCopublisher(raw) {
@@ -16710,7 +16711,7 @@ function stri(input) {
16710
16711
  }
16711
16712
  return parts.reduce((a, b) => a.then(b));
16712
16713
  }
16713
- var alt = (tokens) => tokens.map((t) => str(t)).reduce((a, b) => a.or(b));
16714
+ var alt = (tokens2) => tokens2.map((t) => str(t)).reduce((a, b) => a.or(b));
16714
16715
  function buildRules34() {
16715
16716
  const rules = {};
16716
16717
  const rule = (name, build) => {
@@ -19512,9 +19513,9 @@ function parseCsa(input) {
19512
19513
  }
19513
19514
  }
19514
19515
  if (baseInput === void 0 || baseInput === "") {
19515
- const tokens = input.split(/\s+/);
19516
+ const tokens2 = input.split(/\s+/);
19516
19517
  let acc = "";
19517
- for (const token of tokens) {
19518
+ for (const token of tokens2) {
19518
19519
  if (/^PACKAGE$/i.test(token))
19519
19520
  break;
19520
19521
  const testInput = acc === "" ? token : `${acc} ${token}`;
@@ -19557,7 +19558,7 @@ function csaGrammarImplementation() {
19557
19558
  }
19558
19559
 
19559
19560
  // node_modules/@pubid/pubid/dist/flavors/asme/grammar.js
19560
- var alt2 = (tokens) => tokens.map((t) => str(t)).reduce((a, b) => a.or(b));
19561
+ var alt2 = (tokens2) => tokens2.map((t) => str(t)).reduce((a, b) => a.or(b));
19561
19562
  function buildRules36() {
19562
19563
  const rules = {};
19563
19564
  const rule = (name, build) => {
@@ -22921,6 +22922,69 @@ var lexicalRrf = {
22921
22922
  }
22922
22923
  };
22923
22924
 
22925
+ // workers/worker_public/src/stages/vlmFigureRerank.ts
22926
+ var FIGURE_Q = /\bfig(ure|s)?\b/i;
22927
+ function parsePick(text, kept) {
22928
+ const t = text;
22929
+ const s8 = typeof text === "string" ? text : typeof t?.response === "string" ? t.response : t?.choices?.[0]?.message?.content ?? "";
22930
+ const pick = Number(String(s8).match(/"pick"\s*:\s*(\d+)/)?.[1] ?? 0);
22931
+ return pick >= 1 && pick <= kept ? pick : 0;
22932
+ }
22933
+ var vlmFigureRerank = {
22934
+ name: "vlm-figure-rerank",
22935
+ failure: "additive",
22936
+ when: (c) => FIGURE_Q.test(c.query) && c.finalHits.some((h) => h.metadata.block === "figure" && h.metadata.unit_id),
22937
+ run: async (c) => {
22938
+ const figures = c.finalHits.filter((h) => h.metadata.block === "figure" && h.metadata.unit_id).slice(0, 3);
22939
+ if (!figures.length) return;
22940
+ try {
22941
+ const ids = figures.map((h) => String(h.metadata.unit_id));
22942
+ const ph = ids.map((_, i) => `?${i + 1}`).join(",");
22943
+ const rows = await portStore(c.env).prepare(
22944
+ `SELECT unit_id, json_extract(payload,'$.uri') AS uri FROM unit_payloads WHERE unit_id IN (${ph})`
22945
+ ).bind(...ids).all();
22946
+ const uris = new Map((rows.results ?? []).map((r) => [r.unit_id, r.uri]));
22947
+ const content = [
22948
+ {
22949
+ type: "text",
22950
+ text: `Question: ${c.query}
22951
+
22952
+ Which of these figures best answers the question? Reply with ONLY: {"pick": N} using the image's number, or {"pick": 0} if none is relevant.`
22953
+ }
22954
+ ];
22955
+ const kept = [];
22956
+ let n = 0;
22957
+ for (const h of figures) {
22958
+ const uri = String(uris.get(String(h.metadata.unit_id)) ?? "");
22959
+ const m = uri.match(/^\/assets\/(.+)/);
22960
+ if (!m) continue;
22961
+ const obj = await portBlobs(c.env).get(m[1]);
22962
+ if (!obj?.body) continue;
22963
+ const buf = new Uint8Array(await new Response(obj.body).arrayBuffer());
22964
+ let binary = "";
22965
+ for (let i = 0; i < buf.length; i += 8192) binary += String.fromCharCode(...buf.subarray(i, i + 8192));
22966
+ n += 1;
22967
+ content.push({ type: "text", text: `Image ${n}:` });
22968
+ content.push({ type: "image_url", image_url: { url: `data:image/png;base64,${btoa(binary)}` } });
22969
+ kept.push({ h, label: n });
22970
+ }
22971
+ if (!kept.length) return;
22972
+ const raced = await Promise.race([
22973
+ portModelRunner(c.env).run({ model: MODELS.vlmFigure, messages: [{ role: "user", content }], maxTokens: 256, effort: "low" }),
22974
+ new Promise((r) => setTimeout(() => r(null), 15e3))
22975
+ ]);
22976
+ const pick = parsePick(raced?.text ?? raced, kept.length);
22977
+ const chosen = kept.find((k) => k.label === pick);
22978
+ if (!chosen) return;
22979
+ const top = Math.max(...c.finalHits.map((h) => h.rerank_score ?? h.score ?? 0));
22980
+ chosen.h.rerank_score = top + 1;
22981
+ c.finalHits = [chosen.h, ...c.finalHits.filter((h) => h !== chosen.h)];
22982
+ console.log("vlm-figure-rerank: promoted", chosen.h.metadata.unit_id, "over", c.finalHits.length - 1, "text-ranked hits");
22983
+ } catch {
22984
+ }
22985
+ }
22986
+ };
22987
+
22924
22988
  // workers/worker_public/src/stages/termNudge.ts
22925
22989
  var termNudge = {
22926
22990
  name: "term-nudge",
@@ -23419,6 +23483,7 @@ var STAGES = [
23419
23483
  typedPin,
23420
23484
  sectionDescent,
23421
23485
  dedup,
23486
+ vlmFigureRerank,
23422
23487
  windowFloor
23423
23488
  ];
23424
23489
  var STAGE_NAMES = STAGES.map((s8) => s8.name);
@@ -23474,6 +23539,53 @@ columns: ${colKeep.map((i) => `${t.columns[i]?.label ?? ""}${t.columns[i]?.unit
23474
23539
  ${lines.join("\n")}${elided}`, cols: colKeep.map((i) => `${t.columns[i]?.label ?? ""}${t.columns[i]?.unit ? ` [${t.columns[i].unit}]` : ""}`), rowsShown: shown.length, rowsTotal: t.rows.length };
23475
23540
  }
23476
23541
 
23542
+ // workers/worker_public/src/compress.ts
23543
+ var STOP2 = new Set(
23544
+ "the a an and or of to in on for with by as at is are was were be been from that this these those it its their there which who what when where how why not no than then also such may must shall can could should would per within under over into about between during before after each any all more most less least other only same both few many some own very one two".split(
23545
+ " "
23546
+ )
23547
+ );
23548
+ function tokens(text) {
23549
+ return (text.toLowerCase().match(/[a-z0-9]+(?:[.][0-9]+)?/g) ?? []).filter(
23550
+ (t) => /^[0-9]/.test(t) || t.length >= 3 && !STOP2.has(t)
23551
+ );
23552
+ }
23553
+ function splitSentences(text) {
23554
+ const parts = text.replace(/\r/g, "").split(/(?<=[.!?;])\s+|\n+/).map((s8) => s8.trim()).filter(Boolean);
23555
+ return parts;
23556
+ }
23557
+ function scoreSentence(sentence, qTerms) {
23558
+ const toks = tokens(sentence);
23559
+ if (!toks.length) return 0;
23560
+ let hits = 0;
23561
+ for (const t of toks) if (qTerms.has(t)) hits += 1;
23562
+ const density = hits / Math.sqrt(toks.length);
23563
+ const numeric = /\d/.test(sentence) ? 0.35 : 0;
23564
+ return density + numeric;
23565
+ }
23566
+ function compressText(text, query, budgetChars) {
23567
+ const clean = text.replace(/\s+/g, " ").trim();
23568
+ if (!clean || clean.length <= budgetChars) return clean;
23569
+ const qTerms = new Set(tokens(query));
23570
+ const sentences = splitSentences(clean);
23571
+ if (sentences.length <= 1) {
23572
+ const cut = clean.slice(0, Math.max(0, budgetChars));
23573
+ const end = cut.lastIndexOf(" ");
23574
+ return (end > 40 ? cut.slice(0, end) : cut).trim();
23575
+ }
23576
+ const scored = sentences.map((s8, i) => ({ s: s8, i, score: scoreSentence(s8, qTerms) }));
23577
+ const keep = /* @__PURE__ */ new Set([0]);
23578
+ const ranked = scored.slice(1).sort((a, b) => b.score - a.score || a.i - b.i);
23579
+ let used = sentences[0].length + 1;
23580
+ for (const r of ranked) {
23581
+ if (used + r.s.length + 1 > budgetChars) continue;
23582
+ keep.add(r.i);
23583
+ used += r.s.length + 1;
23584
+ }
23585
+ const out = scored.filter((r) => keep.has(r.i)).map((r) => r.s).join(" ").trim();
23586
+ return out.slice(0, budgetChars);
23587
+ }
23588
+
23477
23589
  // workers/worker_public/src/pipeline.ts
23478
23590
  function promptVars(extra = {}) {
23479
23591
  const out = { PUBLISHER_NAME: P().publisher.name };
@@ -23596,7 +23708,7 @@ ${listing}` }
23596
23708
  return null;
23597
23709
  }
23598
23710
  }
23599
- function buildMessages(query, hits, lang, history = [], retrievalNote, conversationSummary, budgetTokens = LIMITS.inputTokenBudget) {
23711
+ function buildMessages(query, hits, lang, history = [], retrievalNote, conversationSummary, budgetTokens = LIMITS.inputTokenBudget, compress) {
23600
23712
  const corpusNotes = DATASETS().filter(
23601
23713
  (d) => d.note && hits.some((h) => h.metadata.corpus === d.id)
23602
23714
  ).map((d) => d.note).join("\n");
@@ -23641,7 +23753,7 @@ Context passages:
23641
23753
  const pruned = tableSel?.text ?? null;
23642
23754
  if (tableSel) h.metadata.table_selection = { cols: tableSel.cols, rowsShown: tableSel.rowsShown, rowsTotal: tableSel.rowsTotal };
23643
23755
  const figDesc = h.metadata.block === "figure" ? String(h.metadata.figure_description ?? "").trim() : "";
23644
- const raw = clipToTokens(pruned ?? h.text, LIMITS.maxPassageTokens);
23756
+ const raw = compress ? compressText(String(pruned ?? h.text ?? ""), query, Math.floor(LIMITS.maxPassageTokens * 4 * THRESHOLDS.compressShare)) : clipToTokens(pruned ?? h.text, LIMITS.maxPassageTokens);
23645
23757
  const body = figDesc ? `${raw}
23646
23758
  Caption: ${figDesc}` : raw;
23647
23759
  const t = estTokens(head) + estTokens(body);
@@ -24718,9 +24830,9 @@ async function tokenBudget(env, bucketId) {
24718
24830
  const used = Number(await env.CACHE.get(`t:${today()}:ask:${await sha256Hex(bucketId)}`) ?? "0");
24719
24831
  return { used, limit: tokenLimit(env, bucketId) };
24720
24832
  }
24721
- async function chargeTokens(env, bucketId, tokens) {
24722
- if (!(tokens > 0)) return;
24723
- await kvIncr(env.CACHE, `t:${today()}:ask:${await sha256Hex(bucketId)}`, tokens);
24833
+ async function chargeTokens(env, bucketId, tokens2) {
24834
+ if (!(tokens2 > 0)) return;
24835
+ await kvIncr(env.CACHE, `t:${today()}:ask:${await sha256Hex(bucketId)}`, tokens2);
24724
24836
  }
24725
24837
  function usageTotal(usage) {
24726
24838
  if (!usage || typeof usage !== "object") return null;
@@ -24789,6 +24901,7 @@ Family summary (precomputed from the registry and the successor graph): ${summar
24789
24901
  }
24790
24902
 
24791
24903
  export {
24904
+ compressText,
24792
24905
  refCodec,
24793
24906
  NO_CONTEXT,
24794
24907
  machineOffers,
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  DATASETS,
3
3
  datasetAllowed
4
- } from "./chunk-VT7DR6NQ.js";
4
+ } from "./chunk-DNKWDI4G.js";
5
5
  import {
6
6
  P
7
7
  } from "./chunk-3FYJM7LH.js";
@@ -11,6 +11,10 @@ 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
+ // the VLM figure rerank (TODO.sota/18.3): the newly-landed
15
+ // vision-capable MoE scores figure IMAGES against figure-seeking
16
+ // questions — one bounded call per figure question, ablatable stage
17
+ vlmFigure: "@cf/deepseek-ai/deepseek-v4.1-flash-1017",
14
18
  // hot-path understanding/summarize stays on the cheap Qwen (cost-first lane)
15
19
  understand: "@cf/qwen/qwen3-30b-a3b-fp8",
16
20
  // the api_call act's intent-to-act mapping (TODO.ai-platform/09) — the
@@ -81,6 +85,9 @@ var THRESHOLDS = {
81
85
  * then states a measurement — claim support in the cited passages —
82
86
  * not only the source rung. Fails open (a slow or unparseable check
83
87
  * leaves the source-rung note unchanged). */
88
+ // the extractive compression arm (TODO.sota/02 row 5): when ablated
89
+ // on, each passage body is compressed to this share of its budget
90
+ compressShare: 0.6,
84
91
  entailmentGate: true,
85
92
  entailmentBudgetMs: 6e3,
86
93
  entailmentSupportedFloor: 0.9,
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  LIMITS,
3
3
  sha256Hex
4
- } from "./chunk-VT7DR6NQ.js";
4
+ } from "./chunk-DNKWDI4G.js";
5
5
  import {
6
6
  P
7
7
  } from "./chunk-3FYJM7LH.js";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  answerEffort,
3
3
  effortBudget
4
- } from "./chunk-VT7DR6NQ.js";
4
+ } from "./chunk-DNKWDI4G.js";
5
5
 
6
6
  // workers/worker_public/src/ai.ts
7
7
  var delay = (ms) => new Promise((r) => setTimeout(r, ms));
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  embed
3
- } from "./chunk-NI4CIK6W.js";
3
+ } from "./chunk-POW7OTLB.js";
4
4
  import {
5
5
  standardKeysFrom
6
- } from "./chunk-4NXH5ZI6.js";
6
+ } from "./chunk-C67BN6G3.js";
7
7
  import {
8
8
  THRESHOLDS
9
- } from "./chunk-VT7DR6NQ.js";
9
+ } from "./chunk-DNKWDI4G.js";
10
10
  import {
11
11
  P
12
12
  } from "./chunk-3FYJM7LH.js";
@@ -2,4 +2,4 @@ import type { StoreQuery } from "./ports/store.ts";
2
2
  import { type ResolvedBlock } from "./refs.ts";
3
3
  import type { Hit } from "./pipeline.ts";
4
4
  export declare function completeTables(db: StoreQuery, answer: string, used: Hit[]): Promise<ResolvedBlock[]>;
5
- export declare function completeFigures(db: StoreQuery, answer: string, alreadyAttached: ResolvedBlock[], used?: Hit[]): Promise<ResolvedBlock[]>;
5
+ export declare function completeFigures(db: StoreQuery, answer: string, alreadyAttached: ResolvedBlock[], used?: Hit[], query?: string): Promise<ResolvedBlock[]>;
package/dist/config.d.ts CHANGED
@@ -3,6 +3,7 @@ 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 vlmFigure: "@cf/deepseek-ai/deepseek-v4.1-flash-1017";
6
7
  readonly understand: "@cf/qwen/qwen3-30b-a3b-fp8";
7
8
  readonly acts: "@cf/qwen/qwen3-30b-a3b-fp8";
8
9
  readonly fallback: "@cf/qwen/qwen3-30b-a3b-fp8";
@@ -49,6 +50,7 @@ export declare const THRESHOLDS: {
49
50
  * then states a measurement — claim support in the cited passages —
50
51
  * not only the source rung. Fails open (a slow or unparseable check
51
52
  * leaves the source-rung note unchanged). */
53
+ readonly compressShare: 0.6;
52
54
  readonly entailmentGate: true;
53
55
  readonly entailmentBudgetMs: 6000;
54
56
  readonly entailmentSupportedFloor: 0.9;
@@ -50,7 +50,11 @@ export declare function splitHistory(history: HistoryTurn[], budgetTokens: numbe
50
50
  * hard queries (cascade stage after the cross-encoder). Null = keep the
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
- export declare function buildMessages(query: string, hits: Hit[], lang?: string, history?: HistoryTurn[], retrievalNote?: string, conversationSummary?: string, budgetTokens?: number): BuiltMessages;
53
+ export declare function buildMessages(query: string, hits: Hit[], lang?: string, history?: HistoryTurn[], retrievalNote?: string, conversationSummary?: string, budgetTokens?: number,
54
+ /** the extractive compression arm (TODO.sota/02 row 5): ablate_compress
55
+ * arms it per ask — each passage body becomes query-weighted sentence
56
+ * selection at compressShare of its budget. Off in serving. */
57
+ compress?: boolean): BuiltMessages;
54
58
  export declare function citations(hits: Hit[]): {
55
59
  doc_id: string;
56
60
  docidentifier: string;
@@ -0,0 +1,14 @@
1
+ import {
2
+ handleSearch
3
+ } from "./chunk-6GJGMM5G.js";
4
+ import "./chunk-7SLZ5OEO.js";
5
+ import "./chunk-POW7OTLB.js";
6
+ import "./chunk-HIQSYUAU.js";
7
+ import "./chunk-ETLSWSZ7.js";
8
+ import "./chunk-C67BN6G3.js";
9
+ import "./chunk-DNKWDI4G.js";
10
+ import "./chunk-3FYJM7LH.js";
11
+ import "./chunk-LSZTJI7V.js";
12
+ export {
13
+ handleSearch
14
+ };
@@ -4,10 +4,10 @@ import {
4
4
  parseToolCall,
5
5
  runTool,
6
6
  toolNote
7
- } from "./chunk-6OD35FOY.js";
8
- import "./chunk-NI4CIK6W.js";
9
- import "./chunk-4NXH5ZI6.js";
10
- import "./chunk-VT7DR6NQ.js";
7
+ } from "./chunk-X6GUTX76.js";
8
+ import "./chunk-POW7OTLB.js";
9
+ import "./chunk-C67BN6G3.js";
10
+ import "./chunk-DNKWDI4G.js";
11
11
  import "./chunk-3FYJM7LH.js";
12
12
  import "./chunk-LSZTJI7V.js";
13
13
  export {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  authenticate
3
- } from "../../chunk-W7J5SFXJ.js";
4
- import "../../chunk-VT7DR6NQ.js";
3
+ } from "../../chunk-HIQSYUAU.js";
4
+ import "../../chunk-DNKWDI4G.js";
5
5
  import {
6
6
  P,
7
7
  setProfile
@@ -16,7 +16,7 @@ import {
16
16
  roleModel,
17
17
  sha256Hex,
18
18
  today
19
- } from "../../chunk-VT7DR6NQ.js";
19
+ } from "../../chunk-DNKWDI4G.js";
20
20
  import "../../chunk-3FYJM7LH.js";
21
21
  export {
22
22
  DATASETS,
@@ -4,20 +4,21 @@ import {
4
4
  handleMemories,
5
5
  scoreFaithfulness,
6
6
  scoreJudge
7
- } from "../../chunk-IT3MS476.js";
7
+ } from "../../chunk-35NEP7QL.js";
8
8
  import "../../chunk-ECOYO7EX.js";
9
9
  import {
10
10
  TOOLS_REGISTRY,
11
11
  bindModelNode,
12
12
  modelGroundingBlock
13
- } from "../../chunk-6OD35FOY.js";
13
+ } from "../../chunk-X6GUTX76.js";
14
14
  import {
15
15
  handleSearch
16
- } from "../../chunk-IGAGXQHV.js";
16
+ } from "../../chunk-6GJGMM5G.js";
17
17
  import {
18
18
  buildMessages,
19
19
  citations,
20
20
  clientIp,
21
+ compressText,
21
22
  creditBudget,
22
23
  editionNote,
23
24
  fill,
@@ -37,11 +38,11 @@ import {
37
38
  sessionFrom,
38
39
  telemetry,
39
40
  understandQuery
40
- } from "../../chunk-MTIAHAOK.js";
41
+ } from "../../chunk-7SLZ5OEO.js";
41
42
  import {
42
43
  embed,
43
44
  generateOnce
44
- } from "../../chunk-NI4CIK6W.js";
45
+ } from "../../chunk-POW7OTLB.js";
45
46
  import {
46
47
  authenticate,
47
48
  corsHeaders,
@@ -50,14 +51,14 @@ import {
50
51
  readJson,
51
52
  validateQuery,
52
53
  withCors
53
- } from "../../chunk-W7J5SFXJ.js";
54
+ } from "../../chunk-HIQSYUAU.js";
54
55
  import {
55
56
  canonicalRefusal
56
57
  } from "../../chunk-ETLSWSZ7.js";
57
58
  import {
58
59
  entitlementScope,
59
60
  standardKeysFrom
60
- } from "../../chunk-4NXH5ZI6.js";
61
+ } from "../../chunk-C67BN6G3.js";
61
62
  import {
62
63
  LIMITS,
63
64
  MODELS,
@@ -68,7 +69,7 @@ import {
68
69
  roleModel,
69
70
  sha256Hex,
70
71
  today
71
- } from "../../chunk-VT7DR6NQ.js";
72
+ } from "../../chunk-DNKWDI4G.js";
72
73
  import {
73
74
  P,
74
75
  setProfile
@@ -757,53 +758,6 @@ async function handleRevokeKey(env, req, id) {
757
758
  return json({ ok: true, updated: r.meta?.changes ?? 0 });
758
759
  }
759
760
 
760
- // workers/worker_public/src/compress.ts
761
- var STOP = new Set(
762
- "the a an and or of to in on for with by as at is are was were be been from that this these those it its their there which who what when where how why not no than then also such may must shall can could should would per within under over into about between during before after each any all more most less least other only same both few many some own very one two".split(
763
- " "
764
- )
765
- );
766
- function tokens(text) {
767
- return (text.toLowerCase().match(/[a-z0-9]+(?:[.][0-9]+)?/g) ?? []).filter(
768
- (t) => /^[0-9]/.test(t) || t.length >= 3 && !STOP.has(t)
769
- );
770
- }
771
- function splitSentences(text) {
772
- const parts = text.replace(/\r/g, "").split(/(?<=[.!?;])\s+|\n+/).map((s) => s.trim()).filter(Boolean);
773
- return parts;
774
- }
775
- function scoreSentence(sentence, qTerms) {
776
- const toks = tokens(sentence);
777
- if (!toks.length) return 0;
778
- let hits = 0;
779
- for (const t of toks) if (qTerms.has(t)) hits += 1;
780
- const density = hits / Math.sqrt(toks.length);
781
- const numeric = /\d/.test(sentence) ? 0.35 : 0;
782
- return density + numeric;
783
- }
784
- function compressText(text, query, budgetChars) {
785
- const clean = text.replace(/\s+/g, " ").trim();
786
- if (!clean || clean.length <= budgetChars) return clean;
787
- const qTerms = new Set(tokens(query));
788
- const sentences = splitSentences(clean);
789
- if (sentences.length <= 1) {
790
- const cut = clean.slice(0, Math.max(0, budgetChars));
791
- const end = cut.lastIndexOf(" ");
792
- return (end > 40 ? cut.slice(0, end) : cut).trim();
793
- }
794
- const scored = sentences.map((s, i) => ({ s, i, score: scoreSentence(s, qTerms) }));
795
- const keep = /* @__PURE__ */ new Set([0]);
796
- const ranked = scored.slice(1).sort((a, b) => b.score - a.score || a.i - b.i);
797
- let used = sentences[0].length + 1;
798
- for (const r of ranked) {
799
- if (used + r.s.length + 1 > budgetChars) continue;
800
- keep.add(r.i);
801
- used += r.s.length + 1;
802
- }
803
- const out = scored.filter((r) => keep.has(r.i)).map((r) => r.s).join(" ").trim();
804
- return out.slice(0, budgetChars);
805
- }
806
-
807
761
  // workers/worker_public/prompts/research.md
808
762
  var research_default = `You are a sufficiency judge for a research loop over {{PUBLISHER_NAME}} publications. Given the research question and the passages collected so far (across iterations), decide whether the collected evidence is SUFFICIENT to write a complete, well-grounded answer.
809
763
 
@@ -1165,13 +1119,13 @@ async function callToolOnce(env, ctx, _req, tier, key, name, args, t0) {
1165
1119
  // stream:false forces the JSON lane (anon defaults to SSE)
1166
1120
  body: JSON.stringify({ ...args, stream: false })
1167
1121
  });
1168
- const { runTool, TOOLS_REGISTRY: TOOLS_REGISTRY2 } = await import("../../tools-GDHKPEZR.js");
1122
+ const { runTool, TOOLS_REGISTRY: TOOLS_REGISTRY2 } = await import("../../tools-OCR2HLT5.js");
1169
1123
  let payload;
1170
1124
  if (TOOLS_REGISTRY2.some((t) => t.name === name && t.audiences.includes("mcp"))) {
1171
1125
  const r = await runTool({ ...env, DB: env.DB }, { name, args }, "mcp");
1172
1126
  payload = r ? { tool: r.name, query: r.query, result: r.output } : { error: { message: `tool ${name} returned nothing for the given arguments` } };
1173
1127
  } else {
1174
- const res = name === "ask" ? await (await import("../../ask-DP5HOH4K.js")).handleAsk(env, ctx, inner, tier, key) : await (await import("../../search-FW5O32BY.js")).handleSearch(env, ctx, inner, tier, key);
1128
+ const res = name === "ask" ? await (await import("../../ask-LBAELODD.js")).handleAsk(env, ctx, inner, tier, key) : await (await import("../../search-BTPZ6U63.js")).handleSearch(env, ctx, inner, tier, key);
1175
1129
  payload = await res.json().catch(() => ({ error: { message: "tool transport failed", status: res.status } }));
1176
1130
  }
1177
1131
  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 });
@@ -4,8 +4,8 @@ import {
4
4
  requestSalt,
5
5
  resolveRequestScope,
6
6
  standardKeysFrom
7
- } from "../../chunk-4NXH5ZI6.js";
8
- import "../../chunk-VT7DR6NQ.js";
7
+ } from "../../chunk-C67BN6G3.js";
8
+ import "../../chunk-DNKWDI4G.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.163",
30
+ "version": "0.2.165",
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",
@@ -34,6 +34,11 @@ 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): each passage
38
+ * body is query-weighted sentence selection at a fraction of its
39
+ * budget before the answer model reads it. Off in serving; the grid
40
+ * arms it per ask (the row's accuracy-at-token-budget gate). */
41
+ compress: boolean;
37
42
  }
38
43
 
39
44
  export type AblateParse =
@@ -55,10 +60,11 @@ export function parseAblate(
55
60
  const noVerdict = body?.ablate_no_verdict === true;
56
61
  const rawRoute = body?.ablate_route;
57
62
  const speculative = body?.ablate_speculative === true;
63
+ const compress = body?.ablate_compress === true;
58
64
  const namesAblation = rawStages !== undefined && rawStages !== null;
59
65
  const routeAblation = rawRoute !== undefined && rawRoute !== null && rawRoute !== "adaptive";
60
66
 
61
- if (!namesAblation && !noVerdict && !routeAblation && !speculative) return { ok: true, config: null };
67
+ if (!namesAblation && !noVerdict && !routeAblation && !speculative && !compress) return { ok: true, config: null };
62
68
 
63
69
  if (!adminToken || presentedToken !== adminToken) {
64
70
  return {
@@ -93,5 +99,5 @@ export function parseAblate(
93
99
  stages = [...new Set(rawStages as string[])];
94
100
  }
95
101
 
96
- return { ok: true, config: { stages, noVerdict, route, speculative } };
102
+ return { ok: true, config: { stages, noVerdict, route, speculative, compress } };
97
103
  }
@@ -1500,6 +1500,7 @@ let convEntities: Array<{ entity: string; kind: string }> = [];
1500
1500
  [ops.note, processNote, eNote, regNote, contextNote(declaredCtx, docScope), accountNote, modelNote, vocabNote, memNote, machineNote, conditionNote, aggregationNote, boundaryNote, licenseNote, ...(retrieved.notes ?? [])].filter(Boolean).join("\n") || undefined,
1501
1501
  summary,
1502
1502
  budget,
1503
+ ablate?.compress === true,
1503
1504
  );
1504
1505
  await attachFigureImages(env, messages, usedHits, q.query);
1505
1506
  // the agent loop (the owner's 2026-09-28 direction): ONE bounded tool
@@ -1953,7 +1954,7 @@ let convEntities: Array<{ entity: string; kind: string }> = [];
1953
1954
  ...(routeSubset ? { stageSubset: routeSubset ?? undefined } : {}),
1954
1955
  });
1955
1956
  if (retryRetrieve.hits.length > 0) {
1956
- const { messages: retryMessages, usedHits: retryUsed } = buildMessages(q.query, retryRetrieve.hits, q.lang, keptHistory, undefined, summary, budget);
1957
+ const { messages: retryMessages, usedHits: retryUsed } = buildMessages(q.query, retryRetrieve.hits, q.lang, keptHistory, undefined, summary, budget, ablate?.compress === true);
1957
1958
  const retryAnswer = await generateOnce(env, model, retryMessages, routeEffort(routed.route));
1958
1959
  // the answer now comes from the retry passages — citations must follow
1959
1960
  if (retryAnswer) {
@@ -1993,7 +1994,7 @@ let convEntities: Array<{ entity: string; kind: string }> = [];
1993
1994
  }
1994
1995
 
1995
1996
  // figure completion (#172) — see ./completion for the rationale
1996
- completionBlocks.push(...(await completeFigures(env.DB, answer!, [...c2ns.blocks, ...completionBlocks], used)));
1997
+ completionBlocks.push(...(await completeFigures(env.DB, answer!, [...c2ns.blocks, ...completionBlocks], used, q.query)));
1997
1998
 
1998
1999
  // the blind-answer regeneration (2026-10-03, live on the photo case):
1999
2000
  // the multimodal call can answer AROUND an attached image — a 200 whose
@@ -59,6 +59,7 @@ export async function completeFigures(
59
59
  answer: string,
60
60
  alreadyAttached: ResolvedBlock[],
61
61
  used: Hit[] = [],
62
+ query?: string,
62
63
  ): Promise<ResolvedBlock[]> {
63
64
  // the model names figures BOTH ways: unit ids (u:fig-3) and bare
64
65
  // producer anchors (fig-2a of D 36) — collect both forms; bare
@@ -74,6 +75,18 @@ export async function completeFigures(
74
75
  (answer.match(/\bFig(?:ure|\.)s?\s*([0-9]{1,2}[a-z]?)/g) ?? [])
75
76
  .map((x) => x.replace(/\bFig(?:ure|\.)s?\s*/i, "").toLowerCase()),
76
77
  );
78
+ // the figure-SEEKING question (the MKO typed units carry UUID ids —
79
+ // no fig-N the model could name, and "sketch"/"drawing" prose the
80
+ // prose-number scan cannot see): when the question asks about a
81
+ // figure and a figure unit grounded the answer, the contract
82
+ // completes with THAT unit — the tables' mechanical philosophy, not
83
+ // a hope that the model names an unnameable id
84
+ if (query && /\bfig(ure|s)?\b/i.test(query)) {
85
+ for (const h of used.slice(0, 12)) {
86
+ if (h.metadata.unit_id && h.metadata.block === "figure") mentioned.push(h.metadata.unit_id);
87
+ }
88
+ mentioned = [...new Set(mentioned)].slice(0, 6);
89
+ }
77
90
  if (proseNums.size) {
78
91
  const fams = [...new Set(used.map((h) => h.metadata.docidentifier).filter(Boolean))].slice(0, 3);
79
92
  for (const fam of fams) {
@@ -7,6 +7,10 @@ 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
+ // the VLM figure rerank (TODO.sota/18.3): the newly-landed
11
+ // vision-capable MoE scores figure IMAGES against figure-seeking
12
+ // questions — one bounded call per figure question, ablatable stage
13
+ vlmFigure: "@cf/deepseek-ai/deepseek-v4.1-flash-1017",
10
14
  // hot-path understanding/summarize stays on the cheap Qwen (cost-first lane)
11
15
  understand: "@cf/qwen/qwen3-30b-a3b-fp8",
12
16
  // the api_call act's intent-to-act mapping (TODO.ai-platform/09) — the
@@ -78,6 +82,9 @@ export const THRESHOLDS = {
78
82
  * then states a measurement — claim support in the cited passages —
79
83
  * not only the source rung. Fails open (a slow or unparseable check
80
84
  * leaves the source-rung note unchanged). */
85
+ // the extractive compression arm (TODO.sota/02 row 5): when ablated
86
+ // on, each passage body is compressed to this share of its budget
87
+ compressShare: 0.6,
81
88
  entailmentGate: true,
82
89
  entailmentBudgetMs: 6000,
83
90
  entailmentSupportedFloor: 0.9,
@@ -5,6 +5,7 @@ import systemPromptText from "../prompts/system.md";
5
5
  import conversationalPromptText from "../prompts/conversational.md";
6
6
  import listwisePromptText from "../prompts/listwise.md";
7
7
  import { tableSelection } from "./tablecontext";
8
+ import { compressText } from "./compress";
8
9
 
9
10
  // the pinned refusal sentence lives with the canonicalizer in ./refusal
10
11
  // (refusals are never cached: a refusal says "retrieval found nothing",
@@ -287,6 +288,10 @@ export function buildMessages(
287
288
  retrievalNote?: string,
288
289
  conversationSummary?: string,
289
290
  budgetTokens: number = LIMITS.inputTokenBudget,
291
+ /** the extractive compression arm (TODO.sota/02 row 5): ablate_compress
292
+ * arms it per ask — each passage body becomes query-weighted sentence
293
+ * selection at compressShare of its budget. Off in serving. */
294
+ compress?: boolean,
290
295
  ): BuiltMessages {
291
296
  // per-corpus guidance travels WITH the dataset (config.ts): every
292
297
  // dataset whose corpus appears in the passages contributes its note —
@@ -365,7 +370,12 @@ export function buildMessages(
365
370
  // the drawing and a reason to cite the unit; absent for every other
366
371
  // block type and for uncaptioned figures
367
372
  const figDesc = (h.metadata as any).block === "figure" ? String((h.metadata as any).figure_description ?? "").trim() : "";
368
- const raw = clipToTokens(pruned ?? h.text, LIMITS.maxPassageTokens);
373
+ // the compression arm replaces clipping: the query-weighted extractor
374
+ // bounds the text itself (deterministic, never grows it); clipping
375
+ // stays the default
376
+ const raw = compress
377
+ ? compressText(String(pruned ?? h.text ?? ""), query, Math.floor(LIMITS.maxPassageTokens * 4 * THRESHOLDS.compressShare))
378
+ : clipToTokens(pruned ?? h.text, LIMITS.maxPassageTokens);
369
379
  const body = figDesc ? `${raw}\nCaption: ${figDesc}` : raw;
370
380
  const t = estTokens(head) + estTokens(body);
371
381
  if (t <= remain) {
@@ -33,6 +33,7 @@ import { stdRefNudge } from "./stdRefNudge.ts";
33
33
  import { overviewDemote } from "./overviewDemote.ts";
34
34
  import { familyBoost } from "./familyBoost.ts";
35
35
  import { rerankStage, lexicalRrf } from "./rerank.ts";
36
+ import { vlmFigureRerank } from "./vlmFigureRerank.ts";
36
37
  import { termNudge } from "./termNudge.ts";
37
38
  import { conceptSteer } from "./conceptSteer.ts";
38
39
  import { editionSteer } from "./editionSteer.ts";
@@ -75,6 +76,7 @@ export const STAGES: Stage[] = [
75
76
  typedPin,
76
77
  sectionDescent,
77
78
  dedup,
79
+ vlmFigureRerank,
78
80
  windowFloor,
79
81
  ];
80
82
 
@@ -0,0 +1,80 @@
1
+ // VLM figure rerank (TODO.sota/18.3 — the hedge that sees past
2
+ // embeddings): a figure-SEEKING question's figure candidates are scored
3
+ // by a vision model on their actual images — the MKO figure chunks'
4
+ // text is thin (a breadcrumb line + a caption), so text ranking loses
5
+ // them to sibling tables no matter what the caption-augmented embed
6
+ // carries. One bounded vision call, the winner promoted to the front of
7
+ // the window with a rerank score above the incumbent top; every failure
8
+ // mode is additive (the text ranking stands). Off via the registry
9
+ // projection like any stage (ablate_stages drops it).
10
+ import { MODELS } from "../config.ts";
11
+ import { portBlobs, portModelRunner, portStore } from "../env.ts";
12
+ import type { Stage } from "./types.ts";
13
+ import type { Hit } from "../../../shared/chunk";
14
+
15
+ export const FIGURE_Q = /\bfig(ure|s)?\b/i;
16
+
17
+ export function parsePick(text: unknown, kept: number): number {
18
+ const t = text as any;
19
+ const s = typeof text === "string" ? text : typeof t?.response === "string" ? t.response : t?.choices?.[0]?.message?.content ?? "";
20
+ const pick = Number(String(s).match(/"pick"\s*:\s*(\d+)/)?.[1] ?? 0);
21
+ return pick >= 1 && pick <= kept ? pick : 0;
22
+ }
23
+
24
+ export const vlmFigureRerank: Stage = {
25
+ name: "vlm-figure-rerank",
26
+ failure: "additive",
27
+ when: (c) => FIGURE_Q.test(c.query) && c.finalHits.some((h: Hit) => (h.metadata as any).block === "figure" && (h.metadata as any).unit_id),
28
+ run: async (c) => {
29
+ const figures = c.finalHits.filter((h: Hit) => (h.metadata as any).block === "figure" && (h.metadata as any).unit_id).slice(0, 3);
30
+ if (!figures.length) return;
31
+ try {
32
+ const ids = figures.map((h: Hit) => String((h.metadata as any).unit_id));
33
+ const ph = ids.map((_, i) => `?${i + 1}`).join(",");
34
+ const rows = await portStore(c.env).prepare(
35
+ `SELECT unit_id, json_extract(payload,'$.uri') AS uri FROM unit_payloads WHERE unit_id IN (${ph})`,
36
+ )
37
+ .bind(...ids)
38
+ .all();
39
+ const uris = new Map(((rows.results ?? []) as any[]).map((r: any) => [r.unit_id as string, r.uri as string | null]));
40
+ // the multimodal gotcha (2026-09-09): image parts ride a SHORT
41
+ // message — the question and the labels, nothing else
42
+ const content: any[] = [
43
+ {
44
+ type: "text",
45
+ text: `Question: ${c.query}\n\nWhich of these figures best answers the question? Reply with ONLY: {"pick": N} using the image's number, or {"pick": 0} if none is relevant.`,
46
+ },
47
+ ];
48
+ const kept: { h: Hit; label: number }[] = [];
49
+ let n = 0;
50
+ for (const h of figures) {
51
+ const uri = String(uris.get(String((h.metadata as any).unit_id)) ?? "");
52
+ const m = uri.match(/^\/assets\/(.+)/);
53
+ if (!m) continue;
54
+ const obj = await portBlobs(c.env).get(m[1]);
55
+ if (!obj?.body) continue;
56
+ const buf = new Uint8Array(await new Response(obj.body).arrayBuffer());
57
+ let binary = "";
58
+ for (let i = 0; i < buf.length; i += 8192) binary += String.fromCharCode(...buf.subarray(i, i + 8192));
59
+ n += 1;
60
+ content.push({ type: "text", text: `Image ${n}:` });
61
+ content.push({ type: "image_url", image_url: { url: `data:image/png;base64,${btoa(binary)}` } });
62
+ kept.push({ h, label: n });
63
+ }
64
+ if (!kept.length) return;
65
+ const raced: any = await Promise.race([
66
+ portModelRunner(c.env).run({ model: MODELS.vlmFigure, messages: [{ role: "user", content }], maxTokens: 256, effort: "low" }),
67
+ new Promise<null>((r) => setTimeout(() => r(null), 15000)),
68
+ ]);
69
+ const pick = parsePick(raced?.text ?? raced, kept.length);
70
+ const chosen = kept.find((k) => k.label === pick);
71
+ if (!chosen) return;
72
+ const top = Math.max(...c.finalHits.map((h: Hit) => h.rerank_score ?? h.score ?? 0));
73
+ chosen.h.rerank_score = top + 1;
74
+ c.finalHits = [chosen.h, ...c.finalHits.filter((h: Hit) => h !== chosen.h)];
75
+ console.log("vlm-figure-rerank: promoted", (chosen.h.metadata as any).unit_id, "over", c.finalHits.length - 1, "text-ranked hits");
76
+ } catch {
77
+ // additive — the text ranking stands
78
+ }
79
+ },
80
+ };
@@ -1,16 +0,0 @@
1
- import {
2
- handleAsk
3
- } from "./chunk-IT3MS476.js";
4
- import "./chunk-ECOYO7EX.js";
5
- import "./chunk-6OD35FOY.js";
6
- import "./chunk-MTIAHAOK.js";
7
- import "./chunk-NI4CIK6W.js";
8
- import "./chunk-W7J5SFXJ.js";
9
- import "./chunk-ETLSWSZ7.js";
10
- import "./chunk-4NXH5ZI6.js";
11
- import "./chunk-VT7DR6NQ.js";
12
- import "./chunk-3FYJM7LH.js";
13
- import "./chunk-LSZTJI7V.js";
14
- export {
15
- handleAsk
16
- };
@@ -1,14 +0,0 @@
1
- import {
2
- handleSearch
3
- } from "./chunk-IGAGXQHV.js";
4
- import "./chunk-MTIAHAOK.js";
5
- import "./chunk-NI4CIK6W.js";
6
- import "./chunk-W7J5SFXJ.js";
7
- import "./chunk-ETLSWSZ7.js";
8
- import "./chunk-4NXH5ZI6.js";
9
- import "./chunk-VT7DR6NQ.js";
10
- import "./chunk-3FYJM7LH.js";
11
- import "./chunk-LSZTJI7V.js";
12
- export {
13
- handleSearch
14
- };