jevctl 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. package/CHANGELOG.md +44 -1
  2. package/NOTICE +4 -0
  3. package/README.md +54 -388
  4. package/SECURITY.md +5 -3
  5. package/dist/cli.js +105 -16
  6. package/dist/cli.js.map +1 -1
  7. package/dist/commands/ask.d.ts +5 -1
  8. package/dist/commands/ask.js +27 -10
  9. package/dist/commands/ask.js.map +1 -1
  10. package/dist/commands/auth.d.ts +14 -0
  11. package/dist/commands/auth.js +134 -0
  12. package/dist/commands/auth.js.map +1 -0
  13. package/dist/commands/batch.d.ts +28 -0
  14. package/dist/commands/batch.js +221 -0
  15. package/dist/commands/batch.js.map +1 -0
  16. package/dist/commands/classify.d.ts +34 -0
  17. package/dist/commands/classify.js +187 -0
  18. package/dist/commands/classify.js.map +1 -0
  19. package/dist/commands/compact.d.ts +29 -0
  20. package/dist/commands/compact.js +146 -0
  21. package/dist/commands/compact.js.map +1 -0
  22. package/dist/commands/config.d.ts +2 -1
  23. package/dist/commands/config.js +27 -10
  24. package/dist/commands/config.js.map +1 -1
  25. package/dist/commands/extract.d.ts +18 -0
  26. package/dist/commands/extract.js +108 -0
  27. package/dist/commands/extract.js.map +1 -0
  28. package/dist/commands/find.d.ts +5 -1
  29. package/dist/commands/find.js +30 -15
  30. package/dist/commands/find.js.map +1 -1
  31. package/dist/commands/match.d.ts +18 -0
  32. package/dist/commands/match.js +118 -0
  33. package/dist/commands/match.js.map +1 -0
  34. package/dist/commands/models.js +12 -10
  35. package/dist/commands/models.js.map +1 -1
  36. package/dist/commands/rerank.d.ts +15 -0
  37. package/dist/commands/rerank.js +82 -0
  38. package/dist/commands/rerank.js.map +1 -0
  39. package/dist/commands/route.d.ts +19 -0
  40. package/dist/commands/route.js +120 -0
  41. package/dist/commands/route.js.map +1 -0
  42. package/dist/commands/screen.d.ts +5 -1
  43. package/dist/commands/screen.js +27 -10
  44. package/dist/commands/screen.js.map +1 -1
  45. package/dist/commands/verify.d.ts +5 -1
  46. package/dist/commands/verify.js +23 -12
  47. package/dist/commands/verify.js.map +1 -1
  48. package/dist/config.d.ts +66 -6
  49. package/dist/config.js +53 -2
  50. package/dist/config.js.map +1 -1
  51. package/dist/context.d.ts +4 -0
  52. package/dist/context.js +11 -5
  53. package/dist/context.js.map +1 -1
  54. package/dist/core/ask.js +8 -3
  55. package/dist/core/ask.js.map +1 -1
  56. package/dist/core/batch.d.ts +42 -0
  57. package/dist/core/batch.js +93 -0
  58. package/dist/core/batch.js.map +1 -0
  59. package/dist/core/classify.d.ts +103 -0
  60. package/dist/core/classify.js +216 -0
  61. package/dist/core/classify.js.map +1 -0
  62. package/dist/core/compact.d.ts +32 -0
  63. package/dist/core/compact.js +47 -0
  64. package/dist/core/compact.js.map +1 -0
  65. package/dist/core/extract.d.ts +58 -0
  66. package/dist/core/extract.js +214 -0
  67. package/dist/core/extract.js.map +1 -0
  68. package/dist/core/find.js +3 -0
  69. package/dist/core/find.js.map +1 -1
  70. package/dist/core/match.d.ts +55 -0
  71. package/dist/core/match.js +114 -0
  72. package/dist/core/match.js.map +1 -0
  73. package/dist/core/rerank.d.ts +47 -0
  74. package/dist/core/rerank.js +60 -0
  75. package/dist/core/rerank.js.map +1 -0
  76. package/dist/core/route.d.ts +74 -0
  77. package/dist/core/route.js +153 -0
  78. package/dist/core/route.js.map +1 -0
  79. package/dist/core/transcript.d.ts +15 -0
  80. package/dist/core/transcript.js +118 -0
  81. package/dist/core/transcript.js.map +1 -0
  82. package/dist/credentials.d.ts +30 -0
  83. package/dist/credentials.js +161 -0
  84. package/dist/credentials.js.map +1 -0
  85. package/dist/errors.js.map +1 -1
  86. package/dist/index.d.ts +10 -0
  87. package/dist/index.js +10 -0
  88. package/dist/index.js.map +1 -1
  89. package/dist/input.js +1 -1
  90. package/dist/input.js.map +1 -1
  91. package/dist/lib.d.ts +2 -0
  92. package/dist/lib.js +9 -0
  93. package/dist/lib.js.map +1 -1
  94. package/dist/output.d.ts +41 -3
  95. package/dist/output.js +131 -6
  96. package/dist/output.js.map +1 -1
  97. package/dist/provider.d.ts +8 -0
  98. package/dist/provider.js +44 -4
  99. package/dist/provider.js.map +1 -1
  100. package/dist/vendor/compaction/compact.d.ts +29 -0
  101. package/dist/vendor/compaction/compact.js +236 -0
  102. package/dist/vendor/compaction/compact.js.map +1 -0
  103. package/dist/vendor/compaction/index.d.ts +4 -0
  104. package/dist/vendor/compaction/index.js +8 -0
  105. package/dist/vendor/compaction/index.js.map +1 -0
  106. package/dist/vendor/compaction/request.d.ts +19 -0
  107. package/dist/vendor/compaction/request.js +53 -0
  108. package/dist/vendor/compaction/request.js.map +1 -0
  109. package/dist/vendor/compaction/state.d.ts +28 -0
  110. package/dist/vendor/compaction/state.js +258 -0
  111. package/dist/vendor/compaction/state.js.map +1 -0
  112. package/dist/vendor/compaction/types.d.ts +177 -0
  113. package/dist/vendor/compaction/types.js +4 -0
  114. package/dist/vendor/compaction/types.js.map +1 -0
  115. package/docs/ask.md +52 -0
  116. package/docs/auth.md +53 -0
  117. package/docs/batch.md +48 -0
  118. package/docs/classify.md +55 -0
  119. package/docs/compact.md +58 -0
  120. package/docs/config.md +81 -0
  121. package/docs/extract.md +59 -0
  122. package/docs/find.md +49 -0
  123. package/docs/guidelines.md +19 -0
  124. package/docs/library.md +41 -0
  125. package/docs/match.md +52 -0
  126. package/docs/output.md +65 -0
  127. package/docs/recipes.md +78 -0
  128. package/docs/rerank.md +44 -0
  129. package/docs/route.md +57 -0
  130. package/docs/screen.md +53 -0
  131. package/docs/troubleshooting.md +17 -0
  132. package/docs/verify.md +58 -0
  133. package/package.json +9 -6
@@ -0,0 +1,214 @@
1
+ // Value extraction without hallucination: regexes find candidate spans in
2
+ // code, Jev selects the intended one, code normalizes the verbatim value.
3
+ // Pattern: pre_parsed_value_extraction_cookbook, date_extraction_cookbook.
4
+ import { choice } from "@typesafe-ai/sdk";
5
+ const MONTHS = "jan|feb|mar|apr|may|jun|jul|aug|sep|sept|oct|nov|dec";
6
+ export const BUILTIN_FIELDS = {
7
+ email: {
8
+ description: "the email address",
9
+ pattern: /[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}/g,
10
+ normalize: (s) => s.toLowerCase(),
11
+ },
12
+ phone: {
13
+ description: "the phone number",
14
+ pattern: /\+?\d[\d\s().-]{7,}\d/g,
15
+ normalize: (s) => (s.startsWith("+") ? "+" : "") + s.replace(/\D/g, ""),
16
+ },
17
+ url: {
18
+ description: "the web address (URL)",
19
+ pattern: /https?:\/\/[^\s)>"']+/g,
20
+ normalize: (s) => s.replace(/[.,;:]+$/, ""),
21
+ },
22
+ amount: {
23
+ description: "the monetary amount",
24
+ pattern: /(?:[$€£]\s?\d[\d,]*(?:\.\d+)?|\d[\d,]*(?:\.\d+)?\s?(?:USD|EUR|GBP|CAD|AUD|dollars|euros|pounds))/g,
25
+ normalize: (s) => {
26
+ const currency = /[$]|USD|dollars/i.test(s)
27
+ ? "USD"
28
+ : /€|EUR|euros/i.test(s)
29
+ ? "EUR"
30
+ : /£|GBP|pounds/i.test(s)
31
+ ? "GBP"
32
+ : (s.match(/CAD|AUD/i)?.[0]?.toUpperCase() ?? null);
33
+ const value = Number(s.replace(/[^\d.]/g, ""));
34
+ return { value: Number.isFinite(value) ? value : null, currency };
35
+ },
36
+ },
37
+ date: {
38
+ description: "the date",
39
+ pattern: new RegExp(`\\b(?:\\d{4}-\\d{2}-\\d{2}|\\d{1,2}[/.]\\d{1,2}[/.]\\d{2,4}|(?:${MONTHS})[a-z]*\\.? \\d{1,2}(?:st|nd|rd|th)?,? \\d{4}|\\d{1,2}(?:st|nd|rd|th)? (?:${MONTHS})[a-z]*\\.?,? \\d{4})\\b`, "gi"),
40
+ normalize: (s) => {
41
+ const cleaned = s.replace(/(\d)(st|nd|rd|th)/i, "$1");
42
+ const t = Date.parse(cleaned);
43
+ if (Number.isNaN(t))
44
+ return null;
45
+ const d = new Date(t);
46
+ const pad = (n) => String(n).padStart(2, "0");
47
+ return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;
48
+ },
49
+ },
50
+ percent: {
51
+ description: "the percentage",
52
+ pattern: /\d+(?:\.\d+)?\s?%/g,
53
+ normalize: (s) => Number(s.replace(/[^\d.]/g, "")),
54
+ },
55
+ number: {
56
+ description: "the number",
57
+ // A leading minus only counts when it is not glued to a word (INV-20931 is not negative).
58
+ pattern: /(?<!\w)-?\d(?:[\d,]*\d)?(?:\.\d+)?/g,
59
+ normalize: (s) => Number(s.replace(/,/g, "")),
60
+ },
61
+ };
62
+ /**
63
+ * Parse a `--want` entry. Forms:
64
+ * email builtin
65
+ * invoice=/INV-\d+/ custom regex, name only
66
+ * invoice=/INV-\d+/:the invoice number custom regex with description
67
+ * sender=email:the sender's address builtin under a custom name/description
68
+ */
69
+ export function parseFieldSpec(raw) {
70
+ const eq = raw.indexOf("=");
71
+ if (eq === -1) {
72
+ const builtin = BUILTIN_FIELDS[raw.trim()];
73
+ if (!builtin)
74
+ throw new Error(`Unknown field "${raw}". Builtins: ${Object.keys(BUILTIN_FIELDS).join(", ")}. Or use name=/regex/:description.`);
75
+ return { name: raw.trim(), ...builtin };
76
+ }
77
+ const name = raw.slice(0, eq).trim();
78
+ if (!/^[A-Za-z0-9_.-]+$/.test(name))
79
+ throw new Error(`Field name "${name}" must be letters, digits, _, -, or .`);
80
+ const rest = raw.slice(eq + 1).trim();
81
+ const regexMatch = rest.match(/^\/((?:\\.|[^/])+)\/([a-z]*)(?::(.*))?$/s);
82
+ if (regexMatch) {
83
+ const [, source, flags, description] = regexMatch;
84
+ let pattern;
85
+ try {
86
+ pattern = new RegExp(source, flags.includes("g") ? flags : `${flags}g`);
87
+ }
88
+ catch (err) {
89
+ throw new Error(`Field "${name}": invalid regex: ${err.message}`);
90
+ }
91
+ return { name, description: description?.trim() || `the ${name.replace(/[_.-]+/g, " ")}`, pattern };
92
+ }
93
+ const colon = rest.indexOf(":");
94
+ const builtinName = (colon === -1 ? rest : rest.slice(0, colon)).trim();
95
+ const builtin = BUILTIN_FIELDS[builtinName];
96
+ if (!builtin)
97
+ throw new Error(`Field "${name}": "${builtinName}" is not a builtin and not a /regex/.`);
98
+ const description = colon === -1 ? builtin.description : rest.slice(colon + 1).trim() || builtin.description;
99
+ return { name, ...builtin, description };
100
+ }
101
+ export const MAX_FIELD_CANDIDATES = 50;
102
+ /** Unique matches for a field, in order of appearance, capped. */
103
+ export function findCandidates(text, spec) {
104
+ const seen = new Set();
105
+ const out = [];
106
+ spec.pattern.lastIndex = 0;
107
+ for (const m of text.matchAll(spec.pattern)) {
108
+ const v = m[0].trim();
109
+ if (v && !seen.has(v)) {
110
+ seen.add(v);
111
+ out.push(v);
112
+ if (out.length >= MAX_FIELD_CANDIDATES)
113
+ break;
114
+ }
115
+ }
116
+ return out;
117
+ }
118
+ export const NONE_KEY = "none";
119
+ export function buildExtractRequest(input) {
120
+ if (input.fields.length === 0)
121
+ throw new Error("At least one field is required.");
122
+ const names = new Set();
123
+ for (const f of input.fields) {
124
+ if (names.has(f.name))
125
+ throw new Error(`Duplicate field "${f.name}".`);
126
+ names.add(f.name);
127
+ }
128
+ const candidates = {};
129
+ const questions = {};
130
+ for (const f of input.fields) {
131
+ const found = findCandidates(input.text, f);
132
+ candidates[f.name] = found;
133
+ if (found.length === 0)
134
+ continue;
135
+ const criteria = Object.fromEntries(found.map((v, i) => [`c${i}`, v]));
136
+ criteria[NONE_KEY] = `None of the candidates is ${f.description}`;
137
+ questions[f.name] = choice(`Which candidate in \`candidates.${f.name}\` is ${f.description}${input.context ? ` in this ${input.context}` : ""}? Candidate keys map to the exact text found in the document.`, criteria);
138
+ }
139
+ const state = { document: input.text, context: input.context ?? null, candidates };
140
+ return { state, questions, candidates };
141
+ }
142
+ export async function runExtract(ask, input) {
143
+ const { state, questions, candidates } = buildExtractRequest(input);
144
+ // biome-ignore lint/suspicious/noExplicitAny: answer payloads are the SDK's loosely typed union
145
+ let answers = {};
146
+ let usage = { input_tokens: 0, output_tokens: 0 };
147
+ let model = "";
148
+ let provider = "";
149
+ if (Object.keys(questions).length > 0) {
150
+ const res = await ask(state, questions);
151
+ answers = res.answers;
152
+ usage = res.usage;
153
+ model = res.model;
154
+ provider = res.provider;
155
+ }
156
+ const fields = {};
157
+ for (const f of input.fields) {
158
+ const found = candidates[f.name] ?? [];
159
+ if (found.length === 0) {
160
+ fields[f.name] = {
161
+ value: null,
162
+ normalized: null,
163
+ probability: null,
164
+ confidence: null,
165
+ action: "none",
166
+ candidates: 0,
167
+ reason: "no candidates matched the pattern",
168
+ };
169
+ continue;
170
+ }
171
+ const a = answers[f.name];
172
+ const key = a?.choice;
173
+ const confidence = typeof a?.confidence === "number" ? a.confidence : null;
174
+ const probability = key && typeof a?.probabilities?.[key] === "number" ? a.probabilities[key] : null;
175
+ if (!key || key === NONE_KEY) {
176
+ fields[f.name] = {
177
+ value: null,
178
+ normalized: null,
179
+ probability,
180
+ confidence,
181
+ action: "none",
182
+ candidates: found.length,
183
+ reason: key ? "model judged no candidate to be the field" : "no answer",
184
+ };
185
+ continue;
186
+ }
187
+ const idx = Number(key.slice(1));
188
+ const value = found[idx] ?? null;
189
+ let normalized = value;
190
+ if (value !== null && f.normalize) {
191
+ try {
192
+ normalized = f.normalize(value);
193
+ }
194
+ catch {
195
+ normalized = value;
196
+ }
197
+ }
198
+ fields[f.name] = {
199
+ value,
200
+ normalized,
201
+ probability,
202
+ confidence,
203
+ action: confidence !== null && confidence >= input.minConfidence ? "auto" : "review",
204
+ candidates: found.length,
205
+ };
206
+ }
207
+ return { command: "extract", model, provider, fields, min_confidence: input.minConfidence, usage };
208
+ }
209
+ export const EXTRACT_FAIL_CONDITIONS = ["review", "missing"];
210
+ export function extractFailed(out, conditions) {
211
+ return Object.values(out.fields).some((f) => (conditions.includes("review") && f.action === "review") ||
212
+ (conditions.includes("missing") && f.action === "none"));
213
+ }
214
+ //# sourceMappingURL=extract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extract.js","sourceRoot":"","sources":["../../src/core/extract.ts"],"names":[],"mappings":"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"}
package/dist/core/find.js CHANGED
@@ -21,6 +21,9 @@ export function buildFindRequest(input) {
21
21
  return { state, questions, candidates };
22
22
  }
23
23
  export async function runFind(ask, input) {
24
+ if (input.absent > input.found) {
25
+ throw new Error(`--absent (${input.absent}) must not exceed --found (${input.found}).`);
26
+ }
24
27
  const { state, questions, candidates } = buildFindRequest(input);
25
28
  const { answers, usage, provider, model } = await ask(state, questions);
26
29
  const probabilities = answers.best?.probabilities ?? {};
@@ -1 +1 @@
1
- {"version":3,"file":"find.js","sourceRoot":"","sources":["../../src/core/find.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"find.js","sourceRoot":"","sources":["../../src/core/find.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ import type { AskFn, Usage } from "../provider.js";
2
+ export interface MatchItem {
3
+ id?: string;
4
+ text: string;
5
+ }
6
+ export interface MatchPair {
7
+ left: MatchItem;
8
+ right: MatchItem;
9
+ }
10
+ export type MatchDecision = "different" | "unclear" | "same";
11
+ export declare const MATCH_LEVELS: Record<MatchDecision, string>;
12
+ /** Cap on pairs per call so the question count stays well inside the request budget. */
13
+ export declare const MAX_PAIRS = 200;
14
+ /** Pairs per API request; more pairs are sent in sequential chunks. */
15
+ export declare const PAIRS_PER_REQUEST = 50;
16
+ export interface MatchInput {
17
+ pairs: MatchPair[];
18
+ /** What kind of thing the records are, e.g. "products in a beer catalogue". */
19
+ kind?: string;
20
+ }
21
+ export interface MatchResult {
22
+ left: string;
23
+ right: string;
24
+ left_text: string;
25
+ right_text: string;
26
+ decision: MatchDecision;
27
+ score: number | null;
28
+ confidence: number | null;
29
+ probabilities: Record<MatchDecision, number>;
30
+ }
31
+ export interface MatchOutput {
32
+ command: "match";
33
+ model: string;
34
+ provider: string;
35
+ results: MatchResult[];
36
+ summary: Record<MatchDecision, number>;
37
+ usage: Usage;
38
+ }
39
+ /** All pairs within one list (i < j). */
40
+ export declare function allPairs(items: MatchItem[]): MatchPair[];
41
+ /** Cross product of two lists. */
42
+ export declare function crossPairs(left: MatchItem[], right: MatchItem[]): MatchPair[];
43
+ export declare function buildMatchRequest(pairs: MatchPair[], kind: string | undefined, offset?: number): {
44
+ state: {
45
+ kind: string | null;
46
+ pairs: Record<string, unknown>;
47
+ };
48
+ questions: Record<string, unknown>;
49
+ };
50
+ export declare function runMatch(ask: AskFn, input: MatchInput): Promise<MatchOutput>;
51
+ export declare const MATCH_FAIL_CONDITIONS: readonly ["same", "unclear", "different"];
52
+ export type MatchFailCondition = (typeof MATCH_FAIL_CONDITIONS)[number];
53
+ export declare function matchFailed(out: MatchOutput, conditions: readonly MatchFailCondition[]): boolean;
54
+ /** Stable key for a match item, used for dedupe grouping. */
55
+ export declare function itemKey(item: MatchItem, fallback: string): string;
@@ -0,0 +1,114 @@
1
+ // Entity matching: do two records describe the same thing? One Score per pair
2
+ // whose three levels are the three things you can do with a pair: unlink it,
3
+ // hand it to a person, or merge it. No threshold to tune; the winning level is
4
+ // the decision. Pattern: entity_alignment cookbook.
5
+ import { score } from "@typesafe-ai/sdk";
6
+ import { chunk, sanitizeId } from "../lib.js";
7
+ export const MATCH_LEVELS = {
8
+ different: "Different things: the records disagree on an identifying attribute or clearly describe distinct entities",
9
+ unclear: "Cannot tell: the records are compatible but neither confirms nor rules out that they are the same",
10
+ same: "Same thing: the records describe one entity, allowing for formatting, abbreviations, or partial information",
11
+ };
12
+ const LEVEL_ORDER = ["different", "unclear", "same"];
13
+ /** Cap on pairs per call so the question count stays well inside the request budget. */
14
+ export const MAX_PAIRS = 200;
15
+ /** Pairs per API request; more pairs are sent in sequential chunks. */
16
+ export const PAIRS_PER_REQUEST = 50;
17
+ /** All pairs within one list (i < j). */
18
+ export function allPairs(items) {
19
+ const pairs = [];
20
+ for (let i = 0; i < items.length; i++) {
21
+ for (let j = i + 1; j < items.length; j++)
22
+ pairs.push({ left: items[i], right: items[j] });
23
+ }
24
+ return pairs;
25
+ }
26
+ /** Cross product of two lists. */
27
+ export function crossPairs(left, right) {
28
+ const pairs = [];
29
+ for (const l of left)
30
+ for (const r of right)
31
+ pairs.push({ left: l, right: r });
32
+ return pairs;
33
+ }
34
+ function labelOf(item, fallback) {
35
+ return item.id ?? fallback;
36
+ }
37
+ export function buildMatchRequest(pairs, kind, offset = 0) {
38
+ const what = kind ? `these ${kind}` : "these records";
39
+ const questions = {};
40
+ const state = {};
41
+ pairs.forEach((pair, i) => {
42
+ const key = `pair${offset + i}`;
43
+ state[key] = {
44
+ left: { id: labelOf(pair.left, `left${offset + i}`), text: pair.left.text },
45
+ right: { id: labelOf(pair.right, `right${offset + i}`), text: pair.right.text },
46
+ };
47
+ questions[key] = score(`Do \`${key}.left\` and \`${key}.right\` describe the same one of ${what}?`, [
48
+ MATCH_LEVELS.different,
49
+ MATCH_LEVELS.unclear,
50
+ MATCH_LEVELS.same,
51
+ ]);
52
+ });
53
+ return { state: { kind: kind ?? null, pairs: state }, questions };
54
+ }
55
+ export async function runMatch(ask, input) {
56
+ if (input.pairs.length === 0)
57
+ throw new Error("At least one pair is required.");
58
+ if (input.pairs.length > MAX_PAIRS) {
59
+ throw new Error(`Too many pairs (${input.pairs.length}); the limit is ${MAX_PAIRS} per call. Pre-block candidates first.`);
60
+ }
61
+ const usage = { input_tokens: 0, output_tokens: 0 };
62
+ let model = "";
63
+ let provider = "";
64
+ const results = [];
65
+ let offset = 0;
66
+ for (const group of chunk(input.pairs, PAIRS_PER_REQUEST)) {
67
+ const { state, questions } = buildMatchRequest(group, input.kind, offset);
68
+ const res = await ask(state, questions);
69
+ usage.input_tokens += res.usage.input_tokens;
70
+ usage.output_tokens += res.usage.output_tokens;
71
+ model = res.model;
72
+ provider = res.provider;
73
+ group.forEach((pair, i) => {
74
+ const a = res.answers[`pair${offset + i}`];
75
+ const raw = a?.probabilities ?? {};
76
+ const probabilities = Object.fromEntries(LEVEL_ORDER.map((level, idx) => [level, Number((raw[String(idx)] ?? 0).toFixed(4))]));
77
+ const decision = a
78
+ ? LEVEL_ORDER.reduce((best, level) => (probabilities[level] > probabilities[best] ? level : best), "different")
79
+ : "unclear";
80
+ results.push({
81
+ left: labelOf(pair.left, `left${offset + i}`),
82
+ right: labelOf(pair.right, `right${offset + i}`),
83
+ left_text: pair.left.text,
84
+ right_text: pair.right.text,
85
+ decision,
86
+ score: typeof a?.score === "number" ? Number(a.score.toFixed(4)) : null,
87
+ confidence: typeof a?.confidence === "number" ? a.confidence : null,
88
+ probabilities,
89
+ });
90
+ });
91
+ offset += group.length;
92
+ }
93
+ return {
94
+ command: "match",
95
+ model,
96
+ provider,
97
+ results,
98
+ summary: {
99
+ different: results.filter((r) => r.decision === "different").length,
100
+ unclear: results.filter((r) => r.decision === "unclear").length,
101
+ same: results.filter((r) => r.decision === "same").length,
102
+ },
103
+ usage,
104
+ };
105
+ }
106
+ export const MATCH_FAIL_CONDITIONS = ["same", "unclear", "different"];
107
+ export function matchFailed(out, conditions) {
108
+ return out.results.some((r) => conditions.includes(r.decision));
109
+ }
110
+ /** Stable key for a match item, used for dedupe grouping. */
111
+ export function itemKey(item, fallback) {
112
+ return sanitizeId(item.id ?? "") || fallback;
113
+ }
114
+ //# sourceMappingURL=match.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"match.js","sourceRoot":"","sources":["../../src/core/match.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ import type { AskFn, Usage } from "../provider.js";
2
+ export interface RerankCandidate {
3
+ id?: string;
4
+ text: string;
5
+ }
6
+ export interface RerankInput {
7
+ query: string;
8
+ candidates: RerankCandidate[];
9
+ topK: number;
10
+ /** Relevance at or above which a candidate is kept. */
11
+ min: number;
12
+ /** Optional description of what counts as relevant, e.g. "a passage that states the legal rule". */
13
+ criteria?: string;
14
+ }
15
+ export interface RerankHit {
16
+ id: string;
17
+ relevance: number;
18
+ kept: boolean;
19
+ text: string;
20
+ }
21
+ export interface RerankOutput {
22
+ command: "rerank";
23
+ model: string;
24
+ provider: string;
25
+ query: string;
26
+ ranked: RerankHit[];
27
+ kept: string[];
28
+ min: number;
29
+ usage: Usage;
30
+ }
31
+ export declare function buildRerankRequest(input: Pick<RerankInput, "query" | "candidates" | "criteria">): {
32
+ state: {
33
+ query: string;
34
+ candidates: {
35
+ [k: string]: string;
36
+ };
37
+ };
38
+ questions: Record<string, unknown>;
39
+ candidates: import("../lib.js").WithIds<{
40
+ id: string;
41
+ text: string;
42
+ }>[];
43
+ };
44
+ export declare function runRerank(ask: AskFn, input: RerankInput): Promise<RerankOutput>;
45
+ export declare const RERANK_FAIL_CONDITIONS: readonly ["empty"];
46
+ export type RerankFailCondition = (typeof RERANK_FAIL_CONDITIONS)[number];
47
+ export declare function rerankFailed(out: RerankOutput, conditions: readonly RerankFailCondition[]): boolean;
@@ -0,0 +1,60 @@
1
+ // Reranking: one independent relevance judgment (Noul) per candidate, all in
2
+ // one request. Unlike `find` (a Choice that always crowns a winner), scores here
3
+ // do not compete, so several candidates can be relevant or none can.
4
+ // Pattern: rerank_typesafe cookbook.
5
+ import { noul } from "@typesafe-ai/sdk";
6
+ import { ensureUniqueIds, MAX_CANDIDATE_CHARS, MAX_CANDIDATES, originalIds, truncate } from "../lib.js";
7
+ export function buildRerankRequest(input) {
8
+ if (input.query.trim().length === 0)
9
+ throw new Error("Query must not be empty.");
10
+ if (input.candidates.length === 0)
11
+ throw new Error("At least one candidate is required.");
12
+ if (input.candidates.length > MAX_CANDIDATES) {
13
+ throw new Error(`Too many candidates (${input.candidates.length}); the limit is ${MAX_CANDIDATES} per call.`);
14
+ }
15
+ const candidates = ensureUniqueIds(input.candidates.map((c) => ({ id: c.id ?? "", text: truncate(c.text, MAX_CANDIDATE_CHARS) })), "candidate");
16
+ const what = input.criteria ?? "information that answers or directly addresses the query";
17
+ const questions = {};
18
+ for (const c of candidates) {
19
+ questions[c.id] = noul(`Does candidate \`candidates.${c.id}\` contain ${what}?`, {
20
+ true: "The candidate states or directly implies what the query asks for",
21
+ false: "The candidate is off-topic or only superficially related",
22
+ });
23
+ }
24
+ const state = {
25
+ query: input.query,
26
+ candidates: Object.fromEntries(candidates.map((c) => [c.id, c.text])),
27
+ };
28
+ return { state, questions, candidates };
29
+ }
30
+ export async function runRerank(ask, input) {
31
+ const { state, questions, candidates } = buildRerankRequest(input);
32
+ const { answers, usage, provider, model } = await ask(state, questions);
33
+ const original = originalIds(candidates);
34
+ const scored = candidates
35
+ .map((c, index) => ({
36
+ id: original.get(c.id) ?? c.id,
37
+ relevance: Number((typeof answers[c.id]?.noul === "number" ? answers[c.id].noul : 0).toFixed(4)),
38
+ text: c.text,
39
+ index,
40
+ }))
41
+ .sort((a, b) => b.relevance - a.relevance || a.index - b.index);
42
+ const ranked = scored
43
+ .slice(0, input.topK)
44
+ .map(({ index: _, ...hit }) => ({ ...hit, kept: hit.relevance >= input.min }));
45
+ return {
46
+ command: "rerank",
47
+ model,
48
+ provider,
49
+ query: input.query,
50
+ ranked,
51
+ kept: ranked.filter((h) => h.kept).map((h) => h.id),
52
+ min: input.min,
53
+ usage,
54
+ };
55
+ }
56
+ export const RERANK_FAIL_CONDITIONS = ["empty"];
57
+ export function rerankFailed(out, conditions) {
58
+ return conditions.includes("empty") && out.kept.length === 0;
59
+ }
60
+ //# sourceMappingURL=rerank.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rerank.js","sourceRoot":"","sources":["../../src/core/rerank.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,74 @@
1
+ import { z } from "zod";
2
+ import type { AskFn, Usage } from "../provider.js";
3
+ declare const argSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
4
+ type: z.ZodLiteral<"choice">;
5
+ instructions: z.ZodOptional<z.ZodString>;
6
+ options: z.ZodUnion<readonly [z.ZodArray<z.ZodString>, z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNull]>>]>;
7
+ }, z.core.$strip>, z.ZodObject<{
8
+ type: z.ZodLiteral<"noul">;
9
+ instructions: z.ZodString;
10
+ }, z.core.$strip>, z.ZodObject<{
11
+ type: z.ZodLiteral<"score">;
12
+ instructions: z.ZodOptional<z.ZodString>;
13
+ levels: z.ZodArray<z.ZodString>;
14
+ }, z.core.$strip>], "type">;
15
+ export declare const handlersSchema: z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodObject<{
16
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
17
+ args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodDiscriminatedUnion<[z.ZodObject<{
18
+ type: z.ZodLiteral<"choice">;
19
+ instructions: z.ZodOptional<z.ZodString>;
20
+ options: z.ZodUnion<readonly [z.ZodArray<z.ZodString>, z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNull]>>]>;
21
+ }, z.core.$strip>, z.ZodObject<{
22
+ type: z.ZodLiteral<"noul">;
23
+ instructions: z.ZodString;
24
+ }, z.core.$strip>, z.ZodObject<{
25
+ type: z.ZodLiteral<"score">;
26
+ instructions: z.ZodOptional<z.ZodString>;
27
+ levels: z.ZodArray<z.ZodString>;
28
+ }, z.core.$strip>], "type">>>;
29
+ }, z.core.$strip>, z.ZodString, z.ZodNull]>>;
30
+ export type ArgSpec = z.infer<typeof argSchema>;
31
+ export interface HandlerSpec {
32
+ description: string | null;
33
+ args: Record<string, ArgSpec>;
34
+ }
35
+ export type Handlers = Record<string, HandlerSpec>;
36
+ export declare const NONE_HANDLER = "none";
37
+ /** Accept `{name: "description"}`, `{name: null}`, or `{name: {description, args}}`. */
38
+ export declare function parseHandlers(input: unknown): Handlers;
39
+ /** Parse the `a:description,b,c:description` shorthand. */
40
+ export declare function parseHandlerList(raw: string): Handlers;
41
+ export interface RouteInput {
42
+ request: unknown;
43
+ handlers: Handlers;
44
+ instructions?: string;
45
+ minConfidence: number;
46
+ }
47
+ export interface RoutedArg {
48
+ type: ArgSpec["type"];
49
+ value: string | number | null;
50
+ probability?: number;
51
+ confidence?: number;
52
+ probabilities?: Record<string, number>;
53
+ }
54
+ export interface RouteOutput {
55
+ command: "route";
56
+ model: string;
57
+ provider: string;
58
+ handler: string | null;
59
+ confidence: number | null;
60
+ action: "auto" | "review" | "none";
61
+ probabilities: Record<string, number>;
62
+ args: Record<string, RoutedArg>;
63
+ min_confidence: number;
64
+ usage: Usage;
65
+ }
66
+ export declare function buildRouteRequest(input: Pick<RouteInput, "request" | "handlers" | "instructions">): {
67
+ state: unknown;
68
+ questions: Record<string, unknown>;
69
+ };
70
+ export declare function runRoute(ask: AskFn, input: RouteInput): Promise<RouteOutput>;
71
+ export declare const ROUTE_FAIL_CONDITIONS: readonly ["review", "unrouted"];
72
+ export type RouteFailCondition = (typeof ROUTE_FAIL_CONDITIONS)[number];
73
+ export declare function routeFailed(out: RouteOutput, conditions: readonly RouteFailCondition[]): boolean;
74
+ export {};