@konneal/engine 0.2.90 → 0.2.92
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/{ask-D6JV2R2R.js → ask-UG5UYRJV.js} +2 -2
- package/dist/{chunk-KZV4I7ET.js → chunk-EHABW23I.js} +17 -504
- package/dist/chunk-QBWZ6HVP.js +962 -0
- package/dist/{tools-26IJZX5M.js → tools-PI7IXAL4.js} +2 -1
- package/dist/tools-content.d.ts +3 -0
- package/dist/worker_public/src/index.js +7 -7
- package/package.json +1 -1
- package/workers/worker_public/src/tools-content.ts +202 -0
- package/workers/worker_public/src/tools.ts +2 -2
- package/dist/chunk-A7QS2X3J.js +0 -279
|
@@ -1,12 +1,24 @@
|
|
|
1
1
|
import {
|
|
2
2
|
TOOL_DECLARATION,
|
|
3
|
+
bindModelNode,
|
|
3
4
|
contractV2,
|
|
5
|
+
evaluate,
|
|
6
|
+
evaluateConditionSets,
|
|
7
|
+
licenseBoundaryNote,
|
|
8
|
+
licenseBoundaryRefusal,
|
|
9
|
+
licensedEntryForPackage,
|
|
10
|
+
modelCitation,
|
|
11
|
+
modelEcho,
|
|
12
|
+
modelGroundingBlock,
|
|
4
13
|
parseToolCall,
|
|
14
|
+
quantitiesIn,
|
|
5
15
|
resolveBlocks,
|
|
6
16
|
runTool,
|
|
17
|
+
standardForDocNumber,
|
|
7
18
|
tableRetyped,
|
|
8
|
-
toolNote
|
|
9
|
-
|
|
19
|
+
toolNote,
|
|
20
|
+
verdictNote
|
|
21
|
+
} from "./chunk-QBWZ6HVP.js";
|
|
10
22
|
import {
|
|
11
23
|
NO_CONTEXT,
|
|
12
24
|
answerQuality,
|
|
@@ -428,505 +440,8 @@ async function completeFigures(db, answer, alreadyAttached, used = []) {
|
|
|
428
440
|
return figs;
|
|
429
441
|
}
|
|
430
442
|
|
|
431
|
-
// workers/worker_public/src/modelplane.ts
|
|
432
|
-
var NODE_RE = /(?:^|[\s("'`])\/(req|conf|term|constraint|characteristic|state-machine|dimension)\/([a-z0-9][a-z0-9_-]*(?:\/[a-z0-9][a-z0-9_-]*)?)(?=[\s)"'`,;:.]|$)/i;
|
|
433
|
-
function modelNodeRefIn(text) {
|
|
434
|
-
if (!text) return null;
|
|
435
|
-
const m = text.match(NODE_RE);
|
|
436
|
-
if (!m) return null;
|
|
437
|
-
const id = `/${m[1].toLowerCase()}/${m[2]}`;
|
|
438
|
-
return id.length <= 120 ? id : null;
|
|
439
|
-
}
|
|
440
|
-
function standardForDocNumber(docNumber) {
|
|
441
|
-
if (!docNumber) return null;
|
|
442
|
-
const models = P().sources?.models;
|
|
443
|
-
if (!models?.standards?.length || !models?.standard_prefix) return null;
|
|
444
|
-
return models.standards.includes(docNumber) ? `${models.standard_prefix}${docNumber}` : null;
|
|
445
|
-
}
|
|
446
|
-
function licensedEntryForPackage(packageId) {
|
|
447
|
-
if (!packageId) return null;
|
|
448
|
-
return (P().sources?.licensed ?? []).find((l) => l.package === packageId) ?? null;
|
|
449
|
-
}
|
|
450
|
-
function licensedEntryForDocNumber(docNumber) {
|
|
451
|
-
if (!docNumber) return null;
|
|
452
|
-
return (P().sources?.licensed ?? []).find((l) => String(l.doc_number ?? "") === docNumber) ?? null;
|
|
453
|
-
}
|
|
454
|
-
function licenseBoundaryNote(docNumber, standardKeys) {
|
|
455
|
-
const entry = licensedEntryForDocNumber(docNumber);
|
|
456
|
-
if (!entry || standardKeys && standardKeys.has(entry.key)) return void 0;
|
|
457
|
-
const pointer = P().prompts?.vars?.license_declare_pointer;
|
|
458
|
-
return `License boundary \u2014 the question is about ${licenseBoundaryName(entry)}, a licensed publication (entitlement key ${entry.key}). The caller's organization license does not cover its text, so no passage of it was retrieved and NONE of its procedural content (steps, parameters, severities, limits) may be stated, paraphrased or recalled from memory. You MAY answer at the citation level: name the standard and edition, and cite the invoking clause from the PUBLIC passages in context (the Recommendation's own applicability and normative references are public and stay answerable). Then say the organization's license does not cover the standard's text` + (pointer ? ` and point to the declare flow: ${pointer}.` : ".");
|
|
459
|
-
}
|
|
460
|
-
function licenseBoundaryName(entry) {
|
|
461
|
-
const id = entry.doc_number ? ` ${entry.doc_number}` : ` ${entry.package}`;
|
|
462
|
-
return `${entry.title ?? "standard"}${entry.edition ? ` (${entry.edition})` : ""} \u2014${id}`;
|
|
463
|
-
}
|
|
464
|
-
function licenseBoundaryRefusal(docNumber, standardKeys) {
|
|
465
|
-
const entry = licensedEntryForDocNumber(docNumber);
|
|
466
|
-
if (!entry || standardKeys && standardKeys.has(entry.key)) return void 0;
|
|
467
|
-
const pointer = P().prompts?.vars?.license_declare_pointer;
|
|
468
|
-
return `${licenseBoundaryName(entry)} is a licensed publication and your organization's license does not cover its text, so I can't quote or summarize its procedure. I can answer at the citation level \u2014 the standard's title and edition, and the clause your Recommendation invokes \u2014 and the public ${P().publisher.name} content in full.` + (pointer ? ` To unlock the full text, an org admin can declare the license under ${pointer}.` : "");
|
|
469
|
-
}
|
|
470
|
-
async function fetchNode(env, standard, nodeId) {
|
|
471
|
-
try {
|
|
472
|
-
const row = await env.DB.prepare(
|
|
473
|
-
"SELECT standard, node_id, kind, name, clause_doc, clause_ref, content FROM model_nodes WHERE standard = ?1 AND node_id = ?2"
|
|
474
|
-
).bind(standard, nodeId).first();
|
|
475
|
-
if (!row) return null;
|
|
476
|
-
const content = JSON.parse(String(row.content));
|
|
477
|
-
const clause = row.clause_doc && row.clause_ref ? { doc: String(row.clause_doc), ref: String(row.clause_ref), urn: `${row.clause_doc}#clause-${row.clause_ref}` } : row.clause_doc ? { doc: String(row.clause_doc), ref: "", urn: String(row.clause_doc) } : null;
|
|
478
|
-
return {
|
|
479
|
-
standard: String(row.standard),
|
|
480
|
-
node_id: String(row.node_id),
|
|
481
|
-
kind: String(row.kind),
|
|
482
|
-
name: String(row.name ?? row.node_id),
|
|
483
|
-
clause,
|
|
484
|
-
content
|
|
485
|
-
};
|
|
486
|
-
} catch {
|
|
487
|
-
return null;
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
async function bindModelNode(env, opts) {
|
|
491
|
-
const nodeId = modelNodeRefIn(opts.label) ?? modelNodeRefIn(opts.query);
|
|
492
|
-
if (!nodeId) return null;
|
|
493
|
-
const gate = (node) => {
|
|
494
|
-
if (!node) return null;
|
|
495
|
-
const entry = licensedEntryForPackage(node.standard);
|
|
496
|
-
return entry && !(opts.standardKeys?.has(entry.key) ?? false) ? { ...node, gated: true, content: {} } : node;
|
|
497
|
-
};
|
|
498
|
-
if (opts.standard) return gate(await fetchNode(env, opts.standard, nodeId));
|
|
499
|
-
try {
|
|
500
|
-
const rows = await env.DB.prepare("SELECT standard FROM model_nodes WHERE node_id = ?1 LIMIT 2").bind(nodeId).all();
|
|
501
|
-
const standards = (rows?.results ?? []).map((r) => String(r.standard));
|
|
502
|
-
if (standards.length === 1) return gate(await fetchNode(env, standards[0], nodeId));
|
|
503
|
-
return null;
|
|
504
|
-
} catch {
|
|
505
|
-
return null;
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
function clip(s, n = 500) {
|
|
509
|
-
const t = String(s ?? "").trim();
|
|
510
|
-
return t.length <= n ? t : t.slice(0, n - 1).trimEnd() + " \u2026";
|
|
511
|
-
}
|
|
512
|
-
function applicabilityText(app) {
|
|
513
|
-
if (!app || typeof app !== "object") return "";
|
|
514
|
-
const parts = [];
|
|
515
|
-
for (const [dim, cond] of Object.entries(app)) {
|
|
516
|
-
if (Array.isArray(cond)) parts.push(`${dim.replace(/_/g, " ")}: ${cond.join(", ")}`);
|
|
517
|
-
else if (cond && typeof cond === "object" && Array.isArray(cond.values)) {
|
|
518
|
-
parts.push(`${dim.replace(/_/g, " ")} (${cond.match ?? "any"}): ${cond.values.join(", ")}`);
|
|
519
|
-
}
|
|
520
|
-
}
|
|
521
|
-
return parts.join("; ");
|
|
522
|
-
}
|
|
523
|
-
function modelGroundingBlock(node) {
|
|
524
|
-
const c = node.content ?? {};
|
|
525
|
-
const lines = [];
|
|
526
|
-
lines.push(
|
|
527
|
-
P().prompts.vars.model_grounding_intro ?? "Model grounding \u2014 the model plane's own statement:"
|
|
528
|
-
);
|
|
529
|
-
lines.push(`Node: ${node.node_id} (${node.kind.replace(/_/g, " ")}) \u2014 ${node.name} [${node.standard}]`);
|
|
530
|
-
if (node.clause) lines.push(`Provenance: ${node.clause.urn}`);
|
|
531
|
-
if (c.statement) lines.push(`Statement: ${clip(c.statement)}`);
|
|
532
|
-
if (c.definition) lines.push(`Definition: ${clip(c.definition)}`);
|
|
533
|
-
if (c.purpose) lines.push(`Purpose: ${clip(c.purpose)}`);
|
|
534
|
-
const limit = c.limit ?? {};
|
|
535
|
-
if (limit.expression) lines.push(`Machine limit (the constraint the platform's verdict engine evaluates \u2014 quote it verbatim): ${limit.expression}`);
|
|
536
|
-
if (limit.accepts?.verdict) lines.push(`Machine limit: ${limit.accepts.verdict} ${limit.accepts.op} ${limit.accepts.limit} (the canonical acceptance chain)`);
|
|
537
|
-
if (c.check) lines.push(`Machine check: ${c.check}`);
|
|
538
|
-
if (c.derive) lines.push(`Derivation: ${c.derive}${Array.isArray(c.inputs) ? ` (inputs: ${c.inputs.join(", ")})` : ""}`);
|
|
539
|
-
const app = applicabilityText(c.applicability);
|
|
540
|
-
const scopeApp = applicabilityText(c.scope_applicability);
|
|
541
|
-
if (app || scopeApp) lines.push(`Applicability: ${[scopeApp, app].filter(Boolean).join("; ")}`);
|
|
542
|
-
if (Array.isArray(c.binds_to) && c.binds_to.length) lines.push(`Binds to: ${c.binds_to.join(", ")}`);
|
|
543
|
-
if (Array.isArray(c.targets) && c.targets.length) lines.push(`Verifies requirements: ${c.targets.join(", ")}`);
|
|
544
|
-
if (Array.isArray(c.preconditions) && c.preconditions.length) {
|
|
545
|
-
const pcs = c.preconditions.map((p) => `${p.id}: ${clip(p.check ?? (p.state ? `state = ${p.state}` : ""), 120)}`).join("; ");
|
|
546
|
-
lines.push(`Run-validity preconditions (a violation voids the run \u2014 invalid, never a fail): ${pcs}`);
|
|
547
|
-
}
|
|
548
|
-
if (c.acceptance_criteria?.description) lines.push(`Acceptance: ${clip(c.acceptance_criteria.description, 300)}`);
|
|
549
|
-
if (c.violation_meaning) lines.push(`Violation meaning (verbatim): ${clip(c.violation_meaning, 300)} \u2014 on violation: ${c.on_violation ?? "invalid"}`);
|
|
550
|
-
if (Array.isArray(c.values) && c.values.length) {
|
|
551
|
-
lines.push(`Values: ${c.values.map((v) => `${v.id}${v.implies?.length ? ` (implies ${v.implies.join(", ")})` : ""}`).join("; ")}`);
|
|
552
|
-
}
|
|
553
|
-
if (c.source_discrepancy) {
|
|
554
|
-
const sd = c.source_discrepancy;
|
|
555
|
-
lines.push(
|
|
556
|
-
`DECLARED SOURCE DISCREPANCY \u2014 the model and the text disagree; you MUST surface this and cite both: ${clip(sd.summary, 300)} Sources: ${(sd.sources ?? []).join(" and ")}. The model ${sd.resolution === "follows_clause_x" ? "follows one side" : "records the conflict without resolving it"}: ${clip(sd.rationale, 300)}`
|
|
557
|
-
);
|
|
558
|
-
}
|
|
559
|
-
lines.push(
|
|
560
|
-
"Rules for this answer: the machine facts (the constraint, the applicability, the acceptance, the provenance) come from THIS node \u2014 quote the machine limit verbatim, never invent one the node does not carry. If this model content and a prose passage disagree \u2014 including a passage from a different edition \u2014 say so explicitly and cite both (this node and the prose clause)."
|
|
561
|
-
);
|
|
562
|
-
return lines.join("\n");
|
|
563
|
-
}
|
|
564
|
-
function modelCitation(node) {
|
|
565
|
-
return {
|
|
566
|
-
doc_id: `model:${node.standard}`,
|
|
567
|
-
docidentifier: `${P().publisher.name} SMART model (${(() => {
|
|
568
|
-
const prefix = P().sources?.models?.standard_prefix ?? "";
|
|
569
|
-
const letter = prefix.replace(/^.*-/, "").toUpperCase();
|
|
570
|
-
return String(node.standard).replace(new RegExp(`^${prefix}`, "i"), `${letter} `);
|
|
571
|
-
})()})`,
|
|
572
|
-
edition: "",
|
|
573
|
-
language: "en",
|
|
574
|
-
clause_anchor: node.clause?.ref || "model",
|
|
575
|
-
clause_title: `${node.kind.replace(/_/g, " ")} \u2014 ${node.name} (${node.node_id})`,
|
|
576
|
-
status: "in-force",
|
|
577
|
-
corpus: "smart-model",
|
|
578
|
-
quality: "verified",
|
|
579
|
-
url: void 0,
|
|
580
|
-
snippet: `${node.node_id}${node.clause ? ` \xB7 ${node.clause.urn}` : ""}${node.content?.statement ? ` \u2014 ${clip(node.content.statement, 240)}` : ""}`,
|
|
581
|
-
score: 1
|
|
582
|
-
};
|
|
583
|
-
}
|
|
584
|
-
function modelEcho(node) {
|
|
585
|
-
return {
|
|
586
|
-
node_id: node.node_id.slice(0, 120),
|
|
587
|
-
kind: node.kind.slice(0, 40),
|
|
588
|
-
standard: node.standard.slice(0, 40),
|
|
589
|
-
...node.clause?.urn ? { clause: node.clause.urn.slice(0, 120) } : {}
|
|
590
|
-
};
|
|
591
|
-
}
|
|
592
|
-
|
|
593
|
-
// workers/worker_public/src/verdict.ts
|
|
594
|
-
function tokenize(src) {
|
|
595
|
-
const toks = [];
|
|
596
|
-
let i = 0;
|
|
597
|
-
const s = src.replace(/\s+/g, " ");
|
|
598
|
-
while (i < s.length) {
|
|
599
|
-
const c = s[i];
|
|
600
|
-
if (c === " ") {
|
|
601
|
-
i++;
|
|
602
|
-
continue;
|
|
603
|
-
}
|
|
604
|
-
if (/[0-9.]/.test(c)) {
|
|
605
|
-
const m = s.slice(i).match(/^[0-9]*\.?[0-9]+/);
|
|
606
|
-
toks.push({ t: "num", v: Number(m[0]) });
|
|
607
|
-
i += m[0].length;
|
|
608
|
-
continue;
|
|
609
|
-
}
|
|
610
|
-
if (/[A-Za-z_]/.test(c)) {
|
|
611
|
-
const m = s.slice(i).match(/^[A-Za-z_][A-Za-z0-9_]*(?:\.[A-Za-z_][A-Za-z0-9_]*)*/);
|
|
612
|
-
toks.push({ t: "id", v: m[0] });
|
|
613
|
-
i += m[0].length;
|
|
614
|
-
continue;
|
|
615
|
-
}
|
|
616
|
-
const two = s.slice(i, i + 2);
|
|
617
|
-
if ([">=", "<=", "==", "!="].includes(two)) {
|
|
618
|
-
toks.push({ t: "op", v: two });
|
|
619
|
-
i += 2;
|
|
620
|
-
continue;
|
|
621
|
-
}
|
|
622
|
-
if ("+-*/()<>".includes(c)) {
|
|
623
|
-
toks.push({ t: "op", v: c });
|
|
624
|
-
i++;
|
|
625
|
-
continue;
|
|
626
|
-
}
|
|
627
|
-
throw new Error(`bad char ${c}`);
|
|
628
|
-
}
|
|
629
|
-
return toks;
|
|
630
|
-
}
|
|
631
|
-
function parseAndEval(src, params) {
|
|
632
|
-
const toks = tokenize(src);
|
|
633
|
-
let p = 0;
|
|
634
|
-
const peek = () => toks[p];
|
|
635
|
-
const eat = (v) => {
|
|
636
|
-
const t = toks[p++];
|
|
637
|
-
if (v && (!t || t.t !== "op" || t.v !== v)) throw new Error(`expected ${v}`);
|
|
638
|
-
return t;
|
|
639
|
-
};
|
|
640
|
-
const isKw = (k) => {
|
|
641
|
-
const t = peek();
|
|
642
|
-
return t && t.t === "id" && t.v.toLowerCase() === k;
|
|
643
|
-
};
|
|
644
|
-
function or() {
|
|
645
|
-
let l = and();
|
|
646
|
-
while (isKw("or")) {
|
|
647
|
-
p++;
|
|
648
|
-
const r = and();
|
|
649
|
-
l = truthy(l) || truthy(r);
|
|
650
|
-
}
|
|
651
|
-
return l;
|
|
652
|
-
}
|
|
653
|
-
function and() {
|
|
654
|
-
let l = not();
|
|
655
|
-
while (isKw("and")) {
|
|
656
|
-
p++;
|
|
657
|
-
const r = not();
|
|
658
|
-
l = truthy(l) && truthy(r);
|
|
659
|
-
}
|
|
660
|
-
return l;
|
|
661
|
-
}
|
|
662
|
-
function not() {
|
|
663
|
-
if (isKw("not")) {
|
|
664
|
-
p++;
|
|
665
|
-
return !truthy(not());
|
|
666
|
-
}
|
|
667
|
-
return cmp();
|
|
668
|
-
}
|
|
669
|
-
function cmp() {
|
|
670
|
-
const l = add();
|
|
671
|
-
const t = peek();
|
|
672
|
-
if (t && t.t === "op" && [">=", "<=", ">", "<", "==", "!="].includes(t.v)) {
|
|
673
|
-
p++;
|
|
674
|
-
const r = add();
|
|
675
|
-
switch (t.v) {
|
|
676
|
-
case ">=":
|
|
677
|
-
return num3(l) >= num3(r);
|
|
678
|
-
case "<=":
|
|
679
|
-
return num3(l) <= num3(r);
|
|
680
|
-
case ">":
|
|
681
|
-
return num3(l) > num3(r);
|
|
682
|
-
case "<":
|
|
683
|
-
return num3(l) < num3(r);
|
|
684
|
-
case "==":
|
|
685
|
-
return num3(l) === num3(r);
|
|
686
|
-
default:
|
|
687
|
-
return num3(l) !== num3(r);
|
|
688
|
-
}
|
|
689
|
-
}
|
|
690
|
-
return l;
|
|
691
|
-
}
|
|
692
|
-
function add() {
|
|
693
|
-
let l = mul();
|
|
694
|
-
for (; ; ) {
|
|
695
|
-
const t = peek();
|
|
696
|
-
if (t && t.t === "op" && (t.v === "+" || t.v === "-")) {
|
|
697
|
-
p++;
|
|
698
|
-
const r = mul();
|
|
699
|
-
l = t.v === "+" ? num3(l) + num3(r) : num3(l) - num3(r);
|
|
700
|
-
} else return l;
|
|
701
|
-
}
|
|
702
|
-
}
|
|
703
|
-
function mul() {
|
|
704
|
-
let l = unary();
|
|
705
|
-
for (; ; ) {
|
|
706
|
-
const t = peek();
|
|
707
|
-
if (t && t.t === "op" && (t.v === "*" || t.v === "/")) {
|
|
708
|
-
p++;
|
|
709
|
-
const r = unary();
|
|
710
|
-
l = t.v === "*" ? num3(l) * num3(r) : num3(l) / num3(r);
|
|
711
|
-
} else return l;
|
|
712
|
-
}
|
|
713
|
-
}
|
|
714
|
-
function unary() {
|
|
715
|
-
const t = peek();
|
|
716
|
-
if (t && t.t === "op" && t.v === "-") {
|
|
717
|
-
p++;
|
|
718
|
-
return -num3(unary());
|
|
719
|
-
}
|
|
720
|
-
return atom();
|
|
721
|
-
}
|
|
722
|
-
function atom() {
|
|
723
|
-
const t = eat();
|
|
724
|
-
if (!t) throw new Error("unexpected end");
|
|
725
|
-
if (t.t === "num") return t.v;
|
|
726
|
-
if (t.t === "id") {
|
|
727
|
-
if (params[t.v] !== void 0) return params[t.v];
|
|
728
|
-
throw new Error(`missing ${t.v}`);
|
|
729
|
-
}
|
|
730
|
-
if (t.v === "(") {
|
|
731
|
-
const v = or();
|
|
732
|
-
eat(")");
|
|
733
|
-
return v;
|
|
734
|
-
}
|
|
735
|
-
throw new Error(`unexpected ${t.v}`);
|
|
736
|
-
}
|
|
737
|
-
const truthy = (v) => typeof v === "boolean" ? v : v !== 0;
|
|
738
|
-
const num3 = (v) => typeof v === "boolean" ? v ? 1 : 0 : v;
|
|
739
|
-
const out = or();
|
|
740
|
-
if (p !== toks.length) throw new Error("trailing tokens");
|
|
741
|
-
return out;
|
|
742
|
-
}
|
|
743
|
-
function oclBody(s) {
|
|
744
|
-
const m = String(s ?? "").match(/ocl\{([\s\S]*?)\}/);
|
|
745
|
-
return m ? m[1].trim() : null;
|
|
746
|
-
}
|
|
747
|
-
function extractChecks(content) {
|
|
748
|
-
if (!content || typeof content !== "object") return [];
|
|
749
|
-
const c = content;
|
|
750
|
-
const out = [];
|
|
751
|
-
const push = (e) => {
|
|
752
|
-
const b = e && oclBody(e);
|
|
753
|
-
if (b) out.push(b);
|
|
754
|
-
};
|
|
755
|
-
push(c.check);
|
|
756
|
-
push(c.limit?.expression);
|
|
757
|
-
push(c.acceptance_criteria?.limit && !c.acceptance_criteria.limit.expression?.includes("ocl{") ? null : c.acceptance_criteria?.limit?.expression);
|
|
758
|
-
const st = c.acceptance_criteria?.limit;
|
|
759
|
-
if (st?.expression && st.operator && st.threshold_expression) {
|
|
760
|
-
out.push(`${st.expression} ${st.operator} ${st.threshold_expression}`);
|
|
761
|
-
}
|
|
762
|
-
return [...new Set(out)];
|
|
763
|
-
}
|
|
764
|
-
function symbolsIn(checks) {
|
|
765
|
-
const ids = /* @__PURE__ */ new Set();
|
|
766
|
-
const KEYWORDS = /* @__PURE__ */ new Set(["and", "or", "not"]);
|
|
767
|
-
for (const chk of checks) {
|
|
768
|
-
try {
|
|
769
|
-
for (const t of tokenize(chk)) if (t.t === "id" && !KEYWORDS.has(t.v.toLowerCase())) ids.add(t.v);
|
|
770
|
-
} catch {
|
|
771
|
-
}
|
|
772
|
-
}
|
|
773
|
-
return [...ids];
|
|
774
|
-
}
|
|
775
|
-
function parseNumber(raw) {
|
|
776
|
-
let s = raw.replace(/[ ,]/g, "");
|
|
777
|
-
s = s.replace(/\.(\d{3})$/, "$1");
|
|
778
|
-
return Number(s.replace(/,(?=\d{3}\b)/g, ""));
|
|
779
|
-
}
|
|
780
|
-
function extractParams(query, symbols) {
|
|
781
|
-
const params = {};
|
|
782
|
-
for (const sym of symbols) {
|
|
783
|
-
const leaf = sym.split(".").pop() ?? sym;
|
|
784
|
-
const esc = leaf.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
785
|
-
const re = new RegExp(`\\b${esc}\\b\\D{0,14}?([0-9][0-9 ,.]*[0-9])`, "iu");
|
|
786
|
-
const m = query.match(re);
|
|
787
|
-
if (m) {
|
|
788
|
-
const v = parseNumber(m[1]);
|
|
789
|
-
if (Number.isFinite(v)) params[sym] = v;
|
|
790
|
-
}
|
|
791
|
-
}
|
|
792
|
-
return params;
|
|
793
|
-
}
|
|
794
|
-
function evaluate(content, query) {
|
|
795
|
-
const c = content && typeof content === "object" ? content : {};
|
|
796
|
-
const checks = extractChecks(content);
|
|
797
|
-
if (!checks.length) return null;
|
|
798
|
-
const symbols = symbolsIn(checks);
|
|
799
|
-
const params = extractParams(query, symbols);
|
|
800
|
-
const missing = symbols.filter((s) => params[s] === void 0);
|
|
801
|
-
const machine = checks.map((expression) => {
|
|
802
|
-
const values = {};
|
|
803
|
-
try {
|
|
804
|
-
for (const t of tokenize(expression)) if (t.t === "id" && params[t.v] !== void 0) values[t.v] = params[t.v];
|
|
805
|
-
} catch {
|
|
806
|
-
}
|
|
807
|
-
let result = null;
|
|
808
|
-
if (missing.length === 0) {
|
|
809
|
-
try {
|
|
810
|
-
result = !!parseAndEval(expression, params);
|
|
811
|
-
} catch {
|
|
812
|
-
result = null;
|
|
813
|
-
}
|
|
814
|
-
}
|
|
815
|
-
return { expression, symbolic: expression, values, result };
|
|
816
|
-
});
|
|
817
|
-
if (missing.length) {
|
|
818
|
-
return { verdict: "void", missing, checks: machine };
|
|
819
|
-
}
|
|
820
|
-
const failed = machine.some((m) => m.result === false);
|
|
821
|
-
const evaluable = machine.some((m) => m.result !== null);
|
|
822
|
-
if (!evaluable) return null;
|
|
823
|
-
return {
|
|
824
|
-
verdict: failed ? "fail" : "pass",
|
|
825
|
-
on_violation: failed ? String(c.on_violation ?? "invalid") : void 0,
|
|
826
|
-
violation_meaning: failed ? typeof c.violation_meaning === "string" ? c.violation_meaning : void 0 : void 0,
|
|
827
|
-
missing: [],
|
|
828
|
-
checks: machine
|
|
829
|
-
};
|
|
830
|
-
}
|
|
831
|
-
function verdictNote(v, node) {
|
|
832
|
-
const lines = [
|
|
833
|
-
`Machine verdict (deterministic evaluation of node ${node.node_id}${node.clause?.urn ? `, ${node.clause.urn}` : ""}) \u2014 the service EXECUTED the node's machine check against the values stated in the question:`
|
|
834
|
-
];
|
|
835
|
-
for (const c of v.checks) {
|
|
836
|
-
const vals = Object.entries(c.values).map(([k, n]) => `${k}=${n}`).join(", ");
|
|
837
|
-
lines.push(`- ${c.expression}${vals ? ` [${vals}]` : ""} \u2192 ${c.result === null ? "not evaluated" : c.result ? "holds" : "VIOLATED"}`);
|
|
838
|
-
}
|
|
839
|
-
if (v.verdict === "void") {
|
|
840
|
-
lines.push(`VERDICT: VOID \u2014 the question does not state: ${v.missing.join(", ")}. Say exactly what is missing; never assume values.`);
|
|
841
|
-
} else if (v.verdict === "pass") {
|
|
842
|
-
lines.push(`VERDICT: PASS \u2014 every machine check holds at the stated values. Present this verdict, the arithmetic above, and cite the node's clause.`);
|
|
843
|
-
} else {
|
|
844
|
-
lines.push(`VERDICT: ${String(v.on_violation ?? "FAIL").toUpperCase()} \u2014 a machine check is violated. Present this verdict, the arithmetic, the violation meaning verbatim, and cite the node's clause.`);
|
|
845
|
-
}
|
|
846
|
-
lines.push("This verdict is computed data \u2014 quote it faithfully; do not recompute, soften, or contradict it.");
|
|
847
|
-
return lines.join("\n");
|
|
848
|
-
}
|
|
849
|
-
|
|
850
|
-
// workers/worker_public/src/conditions.ts
|
|
851
|
-
var NUM = String.raw`-?\d+(?:[.,]\d+)?`;
|
|
852
|
-
function quantitiesIn(query) {
|
|
853
|
-
const out = {};
|
|
854
|
-
const num3 = (s) => Number(s.replace(",", "."));
|
|
855
|
-
const put = (kind, stated, stated_unit, si) => {
|
|
856
|
-
if (Number.isFinite(si)) out[kind] = { stated, stated_unit, si };
|
|
857
|
-
};
|
|
858
|
-
const tempC = query.match(new RegExp(`(${NUM})\\s*(?:\xB0\\s*)?C\\b`));
|
|
859
|
-
if (tempC) put("temperature", num3(tempC[1]), "degC", num3(tempC[1]) + 273.15);
|
|
860
|
-
const tempK = query.match(new RegExp(`(${NUM})\\s*K\\b`));
|
|
861
|
-
if (tempK && out.temperature === void 0) put("temperature", num3(tempK[1]), "K", num3(tempK[1]));
|
|
862
|
-
const rh = query.match(new RegExp(`(${NUM})\\s*%\\s*(?:RH\\b|relative\\s+humidity)?`, "i"));
|
|
863
|
-
if (rh) put("relative_humidity", num3(rh[1]), "%", num3(rh[1]) / 100);
|
|
864
|
-
const hours = query.match(new RegExp(`(${NUM})\\s*h\\b`, "i"));
|
|
865
|
-
if (hours) put("duration", num3(hours[1]), "h", num3(hours[1]) * 3600);
|
|
866
|
-
const days = query.match(new RegExp(`(${NUM})\\s*days?\\b`, "i"));
|
|
867
|
-
if (days && out.duration === void 0) put("duration", num3(days[1]), "d", num3(days[1]) * 86400);
|
|
868
|
-
return out;
|
|
869
|
-
}
|
|
870
|
-
function scoreSet(entries, q) {
|
|
871
|
-
const checks = [];
|
|
872
|
-
let distance = 0;
|
|
873
|
-
let stated = 0;
|
|
874
|
-
for (const e of entries) {
|
|
875
|
-
const siEntry = e;
|
|
876
|
-
const statedQ = q[e.quantity_kind];
|
|
877
|
-
if (!statedQ || !siEntry?.si) continue;
|
|
878
|
-
const tol = Number(String(siEntry.tolerance ?? "0").replace(",", "."));
|
|
879
|
-
const tolSi = (Number.isFinite(tol) ? tol : 0) * (siEntry.si.unit === "K" ? 1 : siEntry.si.unit === "1" ? 0.01 : 1);
|
|
880
|
-
const in_band = statedQ.si >= siEntry.si.value - tolSi && statedQ.si <= siEntry.si.value + tolSi;
|
|
881
|
-
const gap = Math.max(0, statedQ.si - (siEntry.si.value + tolSi), siEntry.si.value - tolSi - statedQ.si);
|
|
882
|
-
distance += gap / Math.max(tolSi, 1);
|
|
883
|
-
stated += 1;
|
|
884
|
-
checks.push({
|
|
885
|
-
quantity_kind: e.quantity_kind,
|
|
886
|
-
band: `${siEntry.si.value} ${siEntry.si.unit} \xB1${tolSi}`,
|
|
887
|
-
stated: statedQ.stated,
|
|
888
|
-
stated_unit: statedQ.stated_unit,
|
|
889
|
-
in_band
|
|
890
|
-
});
|
|
891
|
-
}
|
|
892
|
-
return stated ? { checks, distance, stated } : null;
|
|
893
|
-
}
|
|
894
|
-
function evaluateConditionSets(nodes, query) {
|
|
895
|
-
const q = quantitiesIn(query);
|
|
896
|
-
const kinds = Object.keys(q);
|
|
897
|
-
if (!kinds.length) return null;
|
|
898
|
-
const scored = [];
|
|
899
|
-
for (const n of nodes) {
|
|
900
|
-
const c = n.content && typeof n.content === "object" ? n.content : {};
|
|
901
|
-
const payload = c.payload ?? {};
|
|
902
|
-
const entries = Array.isArray(payload.entries) ? payload.entries : [];
|
|
903
|
-
if (!entries.length) continue;
|
|
904
|
-
const s = scoreSet(entries, q);
|
|
905
|
-
if (s) scored.push({ node_id: n.node_id, checks: s.checks, distance: s.distance });
|
|
906
|
-
}
|
|
907
|
-
if (!scored.length) return null;
|
|
908
|
-
const matched = scored.filter((s) => s.checks.every((c) => c.in_band));
|
|
909
|
-
scored.sort((a, b) => a.distance - b.distance);
|
|
910
|
-
if (matched.length) {
|
|
911
|
-
return {
|
|
912
|
-
verdict: "pass",
|
|
913
|
-
matched: matched.map((m) => m.node_id),
|
|
914
|
-
checks: matched[0].checks,
|
|
915
|
-
note: `VERDICT: PASS \u2014 the stated combination (${kinds.join(", ")}) matches a severity set (${matched[0].checks.map((c) => c.band).join("; ")}). Present this verdict and cite the set's clause. The machine set identifier rides the verdict block as data \u2014 never write it in your prose.`
|
|
916
|
-
};
|
|
917
|
-
}
|
|
918
|
-
const nearest = scored[0];
|
|
919
|
-
return {
|
|
920
|
-
verdict: "fail",
|
|
921
|
-
matched: [],
|
|
922
|
-
nearest: { node_id: nearest.node_id, distance: Number(nearest.distance.toFixed(2)), bands: nearest.checks.map((c) => c.band) },
|
|
923
|
-
checks: nearest.checks,
|
|
924
|
-
note: `VERDICT: FAIL \u2014 no severity set admits the stated combination. The nearest set (bands: ${nearest.checks.map((c) => c.band).join("; ")}) is the closest match. Say the combination is outside the menu and describe the nearest set's bands; never soften it. The machine set identifier rides the verdict block as data \u2014 never write it in your prose.`
|
|
925
|
-
};
|
|
926
|
-
}
|
|
927
|
-
|
|
928
443
|
// workers/worker_public/src/aggregation.ts
|
|
929
|
-
var
|
|
444
|
+
var NUM = String.raw`-?\d+(?:[,\s]?\d{3})*(?:[.,]\d+)?`;
|
|
930
445
|
var UNIT_WORDS = {
|
|
931
446
|
kg: ["mass", "load", "weight"],
|
|
932
447
|
s: ["time", "duration", "second"],
|
|
@@ -990,7 +505,7 @@ function intervalPairs(cols) {
|
|
|
990
505
|
}
|
|
991
506
|
function statedInInterval(query, unit) {
|
|
992
507
|
if (!unit) return null;
|
|
993
|
-
const re = new RegExp(`(${
|
|
508
|
+
const re = new RegExp(`(${NUM})\\s*${unit.replace(/[.*+?^${}()|[\]\\/]/g, "\\$&")}\\b`, "i");
|
|
994
509
|
const m = query.match(re);
|
|
995
510
|
return m ? num2(m[1]) : null;
|
|
996
511
|
}
|
|
@@ -1025,7 +540,7 @@ function classValueExists(rows, cols, token) {
|
|
|
1025
540
|
}
|
|
1026
541
|
function statedUnits(query) {
|
|
1027
542
|
const out = /* @__PURE__ */ new Set();
|
|
1028
|
-
const re = new RegExp(`(${
|
|
543
|
+
const re = new RegExp(`(${NUM})\\s*([%\xB0a-zA-Z][a-zA-Z/.%\xB0]*\\b)`, "g");
|
|
1029
544
|
for (const m of query.matchAll(re)) {
|
|
1030
545
|
if (m[2]) out.add(m[2].replace("\u2062", "").trim());
|
|
1031
546
|
}
|
|
@@ -3093,8 +2608,6 @@ export {
|
|
|
3093
2608
|
handleMemories,
|
|
3094
2609
|
scoreFaithfulness,
|
|
3095
2610
|
checkQuoteAnchors,
|
|
3096
|
-
bindModelNode,
|
|
3097
|
-
modelGroundingBlock,
|
|
3098
2611
|
scoreJudge,
|
|
3099
2612
|
handleAsk
|
|
3100
2613
|
};
|