veriquote 0.2.1 → 0.3.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.
- package/CITATION.cff +2 -2
- package/README.md +102 -51
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +42 -5
- package/dist/cli/main.js.map +1 -1
- package/dist/gate.d.ts +13 -3
- package/dist/gate.d.ts.map +1 -1
- package/dist/gate.js +20 -2
- package/dist/gate.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/match/fuzzy.d.ts +10 -2
- package/dist/match/fuzzy.d.ts.map +1 -1
- package/dist/match/fuzzy.js +87 -11
- package/dist/match/fuzzy.js.map +1 -1
- package/dist/protocol/evi1.d.ts +21 -1
- package/dist/protocol/evi1.d.ts.map +1 -1
- package/dist/protocol/evi1.js +169 -28
- package/dist/protocol/evi1.js.map +1 -1
- package/dist/protocol/prompt.d.ts +6 -0
- package/dist/protocol/prompt.d.ts.map +1 -1
- package/dist/protocol/prompt.js +35 -10
- package/dist/protocol/prompt.js.map +1 -1
- package/dist/report.d.ts.map +1 -1
- package/dist/report.js +52 -15
- package/dist/report.js.map +1 -1
- package/dist/source/html.d.ts.map +1 -1
- package/dist/source/html.js +3 -0
- package/dist/source/html.js.map +1 -1
- package/dist/types.d.ts +23 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/cli/main.ts +41 -6
- package/src/gate.ts +30 -5
- package/src/index.ts +1 -0
- package/src/match/fuzzy.ts +98 -11
- package/src/protocol/evi1.ts +174 -29
- package/src/protocol/prompt.ts +42 -9
- package/src/report.ts +53 -21
- package/src/source/html.ts +3 -0
- package/src/types.ts +20 -2
package/dist/protocol/prompt.js
CHANGED
|
@@ -5,7 +5,22 @@
|
|
|
5
5
|
*/
|
|
6
6
|
/** Build the EVI1 citation instruction block for the answering model. */
|
|
7
7
|
export function buildCitationInstructions(options = {}) {
|
|
8
|
-
const { maxCitedClaims = 15, maxCitationsPerClaim = 2, quoteLengthRange = [80, 240], minQuoteLength = 60, } = options;
|
|
8
|
+
const { maxCitedClaims = 15, maxCitationsPerClaim = 2, quoteLengthRange = [80, 240], minQuoteLength = 60, evidenceFirst = false, } = options;
|
|
9
|
+
const appendixIntro = evidenceFirst
|
|
10
|
+
? `Before you write the answer, output the evidence block. Select the passages
|
|
11
|
+
you will rely on first, one line per planned claim and source, then write the
|
|
12
|
+
answer so that every cited sentence states only what its lines support.`
|
|
13
|
+
: 'After you finish the answer, append an appendix:';
|
|
14
|
+
const afterBlock = evidenceFirst
|
|
15
|
+
? '- After END_EVI1, write the user-facing answer. The claim ids {cX} in the answer must be the ones used in the block.'
|
|
16
|
+
: '- Do NOT output anything after END_EVI1.';
|
|
17
|
+
const important = evidenceFirst
|
|
18
|
+
? `- The user-facing answer starts AFTER END_EVI1. Nothing but the block comes before it.
|
|
19
|
+
- The block is required only when you use citations. If you use no
|
|
20
|
+
citations, do NOT output EVI1/END_EVI1.`
|
|
21
|
+
: `- The user-facing answer must end BEFORE the EVI1 appendix starts.
|
|
22
|
+
- The appendix is required only when you used citations. If you used no
|
|
23
|
+
citations, do NOT output EVI1/END_EVI1.`;
|
|
9
24
|
return `
|
|
10
25
|
[CITATION BUDGET]
|
|
11
26
|
- Keep citations sparse. Only cite new, load-bearing information.
|
|
@@ -32,17 +47,20 @@ export function buildCitationInstructions(options = {}) {
|
|
|
32
47
|
Example: "...water expands when freezing.[2][5]{c1}"
|
|
33
48
|
Bad: "...freezing.[2] {c1}"
|
|
34
49
|
Bad: "...freezing.[2].{c1}"
|
|
35
|
-
- Every sentence OR bullet that contains citations MUST end with exactly ONE claim marker {cX}
|
|
50
|
+
- Every sentence OR bullet that contains citations MUST end with exactly ONE claim marker {cX},
|
|
51
|
+
directly after its [n] group. Never write {cX} without the [n] group, even though the
|
|
52
|
+
appendix names the source as well.
|
|
36
53
|
- X starts at 1 and increases by 1 for each new cited sentence/bullet in THIS answer.
|
|
37
54
|
- Do NOT place {cX} anywhere else. Uncited sentences get no claim marker.
|
|
38
55
|
|
|
39
|
-
[QUOTE-BASED EVIDENCE APPENDIX (MANDATORY)]
|
|
40
|
-
|
|
56
|
+
[QUOTE-BASED EVIDENCE ${evidenceFirst ? 'BLOCK' : 'APPENDIX'} (MANDATORY)]
|
|
57
|
+
${appendixIntro}
|
|
41
58
|
- Start with a line containing exactly: EVI1
|
|
42
59
|
- Then output one line per (claim, source) pair in this exact format:
|
|
43
60
|
cX|n|"QUOTE"
|
|
61
|
+
If one passage does not cover the claim, add further lines for the same pair.
|
|
44
62
|
- End with a line containing exactly: END_EVI1
|
|
45
|
-
|
|
63
|
+
${afterBlock}
|
|
46
64
|
- Do NOT wrap EVI1..END_EVI1 in code fences or markdown.
|
|
47
65
|
|
|
48
66
|
[COMPLETENESS RULES (MANDATORY)]
|
|
@@ -53,10 +71,19 @@ After you finish the answer, append an appendix:
|
|
|
53
71
|
- If you cannot provide a verbatim quote for a citation, REMOVE that citation
|
|
54
72
|
from the answer. Never leave a citation unverified.
|
|
55
73
|
|
|
74
|
+
[SUFFICIENCY RULES (MANDATORY)]
|
|
75
|
+
- The quotes of a cited sentence must together contain EVERY detail it states:
|
|
76
|
+
each number, population, time frame, place, condition, comparison and hedge.
|
|
77
|
+
- If one passage does not cover everything, add another line for the same claim
|
|
78
|
+
(same or other cited source). Otherwise remove the unquoted detail from the
|
|
79
|
+
sentence. Never add detail that no quote contains.
|
|
80
|
+
|
|
56
81
|
Rules for QUOTE:
|
|
57
82
|
- QUOTE must be copied verbatim from the provided source TEXT (not paraphrased).
|
|
58
|
-
-
|
|
59
|
-
|
|
83
|
+
- Prefer the shortest quote that still covers its part of the claim
|
|
84
|
+
(typically ${quoteLengthRange[0]}-${quoteLengthRange[1]} characters).
|
|
85
|
+
- Copy one contiguous passage per line. Do NOT shorten a quote with "..." and do
|
|
86
|
+
NOT join separate passages into one quote; write each passage on its own line.
|
|
60
87
|
- QUOTE must be at least ${minQuoteLength} characters unless it contains a numeric result or is
|
|
61
88
|
a complete standalone sentence that uniquely supports the claim.
|
|
62
89
|
- QUOTE must be a single line: escape newlines as \\n and double quotes as \\".
|
|
@@ -74,9 +101,7 @@ Rules for QUOTE:
|
|
|
74
101
|
claim; when only conclusions are visible, use cautious language.
|
|
75
102
|
|
|
76
103
|
IMPORTANT:
|
|
77
|
-
|
|
78
|
-
- The appendix is required only when you used citations. If you used no
|
|
79
|
-
citations, do NOT output EVI1/END_EVI1.
|
|
104
|
+
${important}
|
|
80
105
|
`.trim();
|
|
81
106
|
}
|
|
82
107
|
//# sourceMappingURL=prompt.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/protocol/prompt.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/protocol/prompt.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAmBH,yEAAyE;AACzE,MAAM,UAAU,yBAAyB,CAAC,UAAiC,EAAE;IAC3E,MAAM,EACJ,cAAc,GAAG,EAAE,EACnB,oBAAoB,GAAG,CAAC,EACxB,gBAAgB,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,EAC5B,cAAc,GAAG,EAAE,EACnB,aAAa,GAAG,KAAK,GACtB,GAAG,OAAO,CAAC;IAEZ,MAAM,aAAa,GAAG,aAAa;QACjC,CAAC,CAAC;;wEAEkE;QACpE,CAAC,CAAC,kDAAkD,CAAC;IACvD,MAAM,UAAU,GAAG,aAAa;QAC9B,CAAC,CAAC,sHAAsH;QACxH,CAAC,CAAC,0CAA0C,CAAC;IAC/C,MAAM,SAAS,GAAG,aAAa;QAC7B,CAAC,CAAC;;0CAEoC;QACtC,CAAC,CAAC;;0CAEoC,CAAC;IAEzC,OAAO;;;qCAG4B,cAAc;iDACF,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBA4B7C,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU;EAC1D,aAAa;;;;;;EAMb,UAAU;;;;;;;;;;;;;;;;;;;;;eAqBG,gBAAgB,CAAC,CAAC,CAAC,IAAI,gBAAgB,CAAC,CAAC,CAAC;;;2BAG9B,cAAc;;;;;;;;;;;;;;;;;EAiBvC,SAAS;CACV,CAAC,IAAI,EAAE,CAAC;AACT,CAAC"}
|
package/dist/report.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../src/report.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAGV,eAAe,EAEf,cAAc,EACd,kBAAkB,EAEnB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAA2B,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAE9E,MAAM,WAAW,aAAa;IAC5B,qDAAqD;IACrD,MAAM,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,yEAAyE;IACzE,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,6CAA6C;IAC7C,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,qFAAqF;IACrF,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,2CAA2C;IAC3C,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,6CAA6C;AAC7C,wBAAsB,YAAY,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,kBAAkB,CAAC,
|
|
1
|
+
{"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../src/report.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAGV,eAAe,EAEf,cAAc,EACd,kBAAkB,EAEnB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAA2B,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAE9E,MAAM,WAAW,aAAa;IAC5B,qDAAqD;IACrD,MAAM,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,yEAAyE;IACzE,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,6CAA6C;IAC7C,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,qFAAqF;IACrF,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,2CAA2C;IAC3C,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,6CAA6C;AAC7C,wBAAsB,YAAY,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,kBAAkB,CAAC,CA0FtF"}
|
package/dist/report.js
CHANGED
|
@@ -12,32 +12,52 @@ export async function verifyAnswer(options) {
|
|
|
12
12
|
const parsed = parseAnswer(answer);
|
|
13
13
|
const warnings = [...parsed.warnings];
|
|
14
14
|
const claimById = new Map(parsed.claims.map((c) => [c.id, c]));
|
|
15
|
-
|
|
15
|
+
// One citation per (claim, source) pair; a pair may carry several quotes.
|
|
16
|
+
const pairs = new Map();
|
|
16
17
|
for (const item of parsed.evidence) {
|
|
17
|
-
const
|
|
18
|
-
const
|
|
18
|
+
const key = `${item.claimId}|${item.sourceIndex}`;
|
|
19
|
+
const pair = pairs.get(key) ?? { claimId: item.claimId, sourceIndex: item.sourceIndex, quotes: [] };
|
|
20
|
+
pair.quotes.push(item.quote);
|
|
21
|
+
pairs.set(key, pair);
|
|
22
|
+
}
|
|
23
|
+
const citations = [];
|
|
24
|
+
for (const [key, pair] of pairs) {
|
|
25
|
+
const source = sources[pair.sourceIndex - 1];
|
|
19
26
|
if (!source) {
|
|
20
|
-
warnings.push(`EVI1: evidence ${
|
|
27
|
+
warnings.push(`EVI1: evidence ${key} references a source that was not provided.`);
|
|
21
28
|
continue;
|
|
22
29
|
}
|
|
23
|
-
const
|
|
30
|
+
const parts = pair.quotes.map((quote) => ({ quote, textMatch: matchQuoteAgainstSource(quote, source, match) }));
|
|
31
|
+
const textMatch = combineMatches(parts.map((p) => p.textMatch));
|
|
32
|
+
for (const cue of textMatch.omittedCues ?? []) {
|
|
33
|
+
warnings.push(`Citation ${key}: the ellipsis in the quote leaves out "${cue}".`);
|
|
34
|
+
}
|
|
24
35
|
citations.push({
|
|
25
|
-
claimId:
|
|
26
|
-
sourceIndex:
|
|
27
|
-
claimText:
|
|
28
|
-
quote:
|
|
36
|
+
claimId: pair.claimId,
|
|
37
|
+
sourceIndex: pair.sourceIndex,
|
|
38
|
+
claimText: claimById.get(pair.claimId)?.text ?? '',
|
|
39
|
+
quote: pair.quotes.join(' […] '),
|
|
29
40
|
textMatch,
|
|
41
|
+
...(parts.length > 1 ? { parts } : {}),
|
|
30
42
|
score: textMatch.score,
|
|
31
43
|
});
|
|
32
44
|
}
|
|
33
45
|
if (judge) {
|
|
34
46
|
const judgeable = citations.filter((c) => c.claimText && c.quote);
|
|
35
|
-
const inputs = judgeable.map((c) =>
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
47
|
+
const inputs = judgeable.map((c) => {
|
|
48
|
+
const source = sources[c.sourceIndex - 1];
|
|
49
|
+
const parts = c.parts ?? [{ quote: c.quote, textMatch: c.textMatch }];
|
|
50
|
+
return {
|
|
51
|
+
id: `${c.claimId}|${c.sourceIndex}`,
|
|
52
|
+
claim: c.claimText,
|
|
53
|
+
// An ellipsis must not hide what it left out (a "not", a qualifier):
|
|
54
|
+
// the judge rates the passage as the source has it.
|
|
55
|
+
quote: parts
|
|
56
|
+
.map((p) => (p.textMatch.method === 'elided' ? matchedText(source, p.textMatch) ?? p.quote : p.quote))
|
|
57
|
+
.join(' […] '),
|
|
58
|
+
context: parts.map((p) => contextWindow(source, p.textMatch, contextWindowChars)).join(' […] '),
|
|
59
|
+
};
|
|
60
|
+
});
|
|
41
61
|
const results = await judge.judge(inputs, { signal });
|
|
42
62
|
if (results.length !== inputs.length) {
|
|
43
63
|
warnings.push(`Judge returned ${results.length} results for ${inputs.length} items; missing items marked as errors.`);
|
|
@@ -68,6 +88,23 @@ export async function verifyAnswer(options) {
|
|
|
68
88
|
summary: summarize(citations, Boolean(judge)),
|
|
69
89
|
};
|
|
70
90
|
}
|
|
91
|
+
/** Several quotes for one pair count as their weakest match, carrying every cue. */
|
|
92
|
+
function combineMatches(matches) {
|
|
93
|
+
if (matches.length === 1)
|
|
94
|
+
return matches[0];
|
|
95
|
+
const weakest = matches.reduce((a, b) => (b.score < a.score ? b : a));
|
|
96
|
+
const cues = [...new Set(matches.flatMap((m) => m.omittedCues ?? []))];
|
|
97
|
+
const { omittedCues: _, ...rest } = weakest;
|
|
98
|
+
return cues.length ? { ...rest, omittedCues: cues } : rest;
|
|
99
|
+
}
|
|
100
|
+
/** The matched region of the source field, if its offsets are known. */
|
|
101
|
+
function matchedText(source, m) {
|
|
102
|
+
if (!source || m.start === undefined || m.end === undefined)
|
|
103
|
+
return undefined;
|
|
104
|
+
const extra = /^extraTexts\[(\d+)\]$/.exec(m.field);
|
|
105
|
+
const text = extra ? source.extraTexts?.[Number(extra[1])] : source.text;
|
|
106
|
+
return text?.slice(m.start, m.end);
|
|
107
|
+
}
|
|
71
108
|
/** Source text around the matched region, for judge disambiguation. */
|
|
72
109
|
function contextWindow(source, matchResult, windowChars) {
|
|
73
110
|
const text = source?.text ?? '';
|
package/dist/report.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"report.js","sourceRoot":"","sources":["../src/report.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAWH,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,uBAAuB,EAAqB,MAAM,kBAAkB,CAAC;AAiB9E,6CAA6C;AAC7C,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAsB;IACvD,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAC1D,MAAM,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,IAAI,GAAG,CAAC;IAE7D,MAAM,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IACnC,MAAM,QAAQ,GAAG,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;IACtC,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAE/D,MAAM,
|
|
1
|
+
{"version":3,"file":"report.js","sourceRoot":"","sources":["../src/report.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../src/source/html.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../src/source/html.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA0BH,mFAAmF;AACnF,wBAAgB,cAAc,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAQhD;AAED,0CAA0C;AAC1C,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAI1D;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAMhE;AAED,mEAAmE;AACnE,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAc/C"}
|
package/dist/source/html.js
CHANGED
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
*/
|
|
7
7
|
const DROP_ELEMENTS = /<(script|style|noscript|template|svg|iframe|head|object|canvas)\b[\s\S]*?<\/\1\s*>/gi;
|
|
8
8
|
const COMMENTS = /<!--[\s\S]*?-->/g;
|
|
9
|
+
/** Reference markers such as Wikipedia's [12]: models quoting the page leave them out. */
|
|
10
|
+
const REF_MARKERS = /<sup\b[^>]*class="[^"]*\breference\b[^"]*"[^>]*>[\s\S]*?<\/sup\s*>/gi;
|
|
9
11
|
const BLOCK_TAGS = /<\/?(?:p|div|br|hr|li|ul|ol|dl|dt|dd|h[1-6]|tr|table|thead|tbody|tfoot|section|article|aside|main|header|footer|nav|blockquote|pre|figure|figcaption|details|summary|form|fieldset|address)\b[^>]*>/gi;
|
|
10
12
|
const CELL_TAGS = /<\/?(?:td|th)\b[^>]*>/gi;
|
|
11
13
|
const ANY_TAG = /<[^>]+>/g;
|
|
@@ -55,6 +57,7 @@ export function htmlMainContent(html) {
|
|
|
55
57
|
export function htmlToText(html) {
|
|
56
58
|
const text = html
|
|
57
59
|
.replace(COMMENTS, '')
|
|
60
|
+
.replace(REF_MARKERS, '')
|
|
58
61
|
.replace(DROP_ELEMENTS, ' ')
|
|
59
62
|
.replace(BLOCK_TAGS, '\n')
|
|
60
63
|
.replace(CELL_TAGS, ' ')
|
package/dist/source/html.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/source/html.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/source/html.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -52,6 +52,13 @@ export type MatchMethod =
|
|
|
52
52
|
'exact'
|
|
53
53
|
/** Substring after Unicode/typography normalization and case folding. */
|
|
54
54
|
| 'normalized'
|
|
55
|
+
/**
|
|
56
|
+
* The quote omits text, marked with an ellipsis ("…", "...", "[…]"): every
|
|
57
|
+
* fragment occurs literally, in order and close together. `start`/`end`
|
|
58
|
+
* cover the whole passage, omitted text included, and that passage is what
|
|
59
|
+
* the judge sees.
|
|
60
|
+
*/
|
|
61
|
+
| 'elided'
|
|
55
62
|
/** Best fuzzy window by character-trigram Dice similarity. */
|
|
56
63
|
| 'fuzzy'
|
|
57
64
|
/** No window reached the fuzzy score threshold. */
|
|
@@ -60,8 +67,9 @@ export type MatchMethod =
|
|
|
60
67
|
export interface QuoteMatch {
|
|
61
68
|
method: MatchMethod;
|
|
62
69
|
/**
|
|
63
|
-
* Similarity in [0, 1]. `1` only for exact/normalized hits;
|
|
64
|
-
* are capped at 0.99 so a perfect score always implies a
|
|
70
|
+
* Similarity in [0, 1]. `1` only for exact/normalized hits; elided and
|
|
71
|
+
* fuzzy scores are capped at 0.99 so a perfect score always implies a
|
|
72
|
+
* literal hit.
|
|
65
73
|
*/
|
|
66
74
|
score: number;
|
|
67
75
|
/** Start offset of the matched region in the original source field, if known. */
|
|
@@ -70,6 +78,12 @@ export interface QuoteMatch {
|
|
|
70
78
|
end?: number;
|
|
71
79
|
/** Which source field matched: `"text"` or `"extraTexts[i]"`. */
|
|
72
80
|
field: string;
|
|
81
|
+
/**
|
|
82
|
+
* `elided` only: words in the omitted text that can reverse or limit a
|
|
83
|
+
* statement ("not", "except", "only", "however", …). A hint, not a verdict:
|
|
84
|
+
* the judge sees the full passage and decides.
|
|
85
|
+
*/
|
|
86
|
+
omittedCues?: string[];
|
|
73
87
|
}
|
|
74
88
|
/** Qualitative entailment classes produced by the LLM judge. */
|
|
75
89
|
export type EntailmentClass = 'entailed' | 'partially_entailed' | 'overstated' | 'insufficient' | 'contradicted';
|
|
@@ -108,8 +122,15 @@ export interface CitationVerification {
|
|
|
108
122
|
claimId: string;
|
|
109
123
|
sourceIndex: number;
|
|
110
124
|
claimText: string;
|
|
125
|
+
/** The quote; several quotes for the same (claim, source) pair are joined with " […] ". */
|
|
111
126
|
quote: string;
|
|
127
|
+
/** The match of the quote; with several quotes, the weakest one (cues of all of them). */
|
|
112
128
|
textMatch: QuoteMatch;
|
|
129
|
+
/** One entry per quote, present only when the pair has more than one. */
|
|
130
|
+
parts?: {
|
|
131
|
+
quote: string;
|
|
132
|
+
textMatch: QuoteMatch;
|
|
133
|
+
}[];
|
|
113
134
|
/** Absent when verification ran without a judge. */
|
|
114
135
|
entailment?: EntailmentResult;
|
|
115
136
|
/**
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,wEAAwE;AACxE,MAAM,WAAW,cAAc;IAC7B,iFAAiF;IACjF,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,4BAA4B;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2CAA2C;IAC3C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,iFAAiF;IACjF,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,qDAAqD;AACrD,MAAM,WAAW,YAAY;IAC3B,qCAAqC;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,8DAA8D;IAC9D,WAAW,EAAE,MAAM,CAAC;IACpB,yDAAyD;IACzD,KAAK,EAAE,MAAM,CAAC;CACf;AAED,uEAAuE;AACvE,MAAM,WAAW,KAAK;IACpB,qCAAqC;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,0DAA0D;IAC1D,IAAI,EAAE,MAAM,CAAC;IACb,qEAAqE;IACrE,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,2EAA2E;AAC3E,MAAM,WAAW,YAAY;IAC3B,yEAAyE;IACzE,SAAS,EAAE,MAAM,CAAC;IAClB,uCAAuC;IACvC,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,iDAAiD;IACjD,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,+DAA+D;IAC/D,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,+CAA+C;AAC/C,MAAM,MAAM,WAAW;AACrB,sDAAsD;AACpD,OAAO;AACT,yEAAyE;GACvE,YAAY;AACd,8DAA8D;GAC5D,OAAO;AACT,mDAAmD;GACjD,WAAW,CAAC;AAEhB,oEAAoE;AACpE,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,WAAW,CAAC;IACpB
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "veriquote",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Deterministic + semantic verification of quote-grounded LLM citations (EVI1 protocol): fuzzy verbatim-quote matching and an LLM entailment judge for transparent, per-claim hallucination detection.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"llm",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"author": "NavigNine (https://navignine.com)",
|
|
21
21
|
"repository": {
|
|
22
22
|
"type": "git",
|
|
23
|
-
"url": "https://github.com/rickintoplace/veriquote.git"
|
|
23
|
+
"url": "git+https://github.com/rickintoplace/veriquote.git"
|
|
24
24
|
},
|
|
25
25
|
"homepage": "https://github.com/rickintoplace/veriquote#readme",
|
|
26
26
|
"bugs": {
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"main": "./dist/index.js",
|
|
31
31
|
"types": "./dist/index.d.ts",
|
|
32
32
|
"bin": {
|
|
33
|
-
"veriquote": "
|
|
33
|
+
"veriquote": "bin/veriquote.mjs"
|
|
34
34
|
},
|
|
35
35
|
"exports": {
|
|
36
36
|
".": {
|
package/src/cli/main.ts
CHANGED
|
@@ -31,6 +31,7 @@ const HELP = `veriquote — check that an LLM answer's quotes exist in its sourc
|
|
|
31
31
|
|
|
32
32
|
Usage
|
|
33
33
|
veriquote prompt print the citation instructions for the answering model
|
|
34
|
+
veriquote source <url|file> print the text a source is checked against (quote from this)
|
|
34
35
|
veriquote check <answer> --source <url|file> [--source …]
|
|
35
36
|
veriquote check --job <file|-> JSON job: {"answer": "...", "sources": [{"text": "..."}]}
|
|
36
37
|
|
|
@@ -53,7 +54,7 @@ Judge (semantic support check), from the environment:
|
|
|
53
54
|
VERIQUOTE_JUDGE_MODEL required when a key is set
|
|
54
55
|
VERIQUOTE_JUDGE_BASE_URL default https://openrouter.ai/api/v1
|
|
55
56
|
|
|
56
|
-
Exit status: 0 pass · 2 revise · 1 error`;
|
|
57
|
+
Exit status: 0 pass · 2 revise · 1 error, or the judge failed (unverified)`;
|
|
57
58
|
|
|
58
59
|
interface Args {
|
|
59
60
|
command?: string;
|
|
@@ -147,6 +148,12 @@ export async function main(io: CliIo): Promise<number> {
|
|
|
147
148
|
return EXIT.pass;
|
|
148
149
|
case 'check':
|
|
149
150
|
return await check(args, io);
|
|
151
|
+
case 'source': {
|
|
152
|
+
if (args.positional.length !== 1) throw new UsageError('source needs exactly one URL or file');
|
|
153
|
+
const src = await loadSource(args.positional[0], io);
|
|
154
|
+
io.stdout(`${src.text}\n`);
|
|
155
|
+
return EXIT.pass;
|
|
156
|
+
}
|
|
150
157
|
default:
|
|
151
158
|
throw new UsageError(`unknown command "${args.command}"`);
|
|
152
159
|
}
|
|
@@ -191,9 +198,21 @@ async function check(args: Args, io: CliIo): Promise<number> {
|
|
|
191
198
|
{
|
|
192
199
|
verdict: gate.verdict,
|
|
193
200
|
judge: judgeSetup.model ?? null,
|
|
201
|
+
// The answer as the user should see it: [n] markers kept, {cX} markers and the appendix removed.
|
|
202
|
+
cleanAnswer: report.cleanText,
|
|
194
203
|
summary: report.summary,
|
|
195
204
|
problems: gate.problems,
|
|
196
205
|
uncited: gate.uncited,
|
|
206
|
+
unjudged: gate.unjudged,
|
|
207
|
+
citations: report.citations.map((c) => ({
|
|
208
|
+
claimId: c.claimId,
|
|
209
|
+
sourceIndex: c.sourceIndex,
|
|
210
|
+
match: { method: c.textMatch.method, score: round2(c.textMatch.score) },
|
|
211
|
+
judge: c.entailment
|
|
212
|
+
? { class: c.entailment.class, support: c.entailment.confidence === null ? null : round2(c.entailment.confidence) }
|
|
213
|
+
: null,
|
|
214
|
+
score: c.score === null ? null : round2(c.score),
|
|
215
|
+
})),
|
|
197
216
|
warnings: report.warnings,
|
|
198
217
|
sources: sources.map((s, i) => ({ index: i + 1, url: s.url, title: s.title, chars: s.text.length })),
|
|
199
218
|
instructionsForModel: gate.instructionsForModel,
|
|
@@ -205,9 +224,11 @@ async function check(args: Args, io: CliIo): Promise<number> {
|
|
|
205
224
|
} else {
|
|
206
225
|
io.stdout(renderHuman(report, gate, sources, judgeSetup.model, io.color, args.minScore ?? 0.5));
|
|
207
226
|
}
|
|
208
|
-
return gate.verdict === 'pass' ? EXIT.pass : EXIT.revise;
|
|
227
|
+
return gate.verdict === 'pass' ? EXIT.pass : gate.verdict === 'revise' ? EXIT.revise : EXIT.error;
|
|
209
228
|
}
|
|
210
229
|
|
|
230
|
+
const round2 = (x: number) => Math.round(x * 100) / 100;
|
|
231
|
+
|
|
211
232
|
async function loadSource(ref: string, io: CliIo): Promise<SourceDocument> {
|
|
212
233
|
if (/^https?:\/\//i.test(ref)) {
|
|
213
234
|
return fetchSource(ref, {
|
|
@@ -241,6 +262,13 @@ function judgeFromEnv(args: Args, io: CliIo): { judge?: EntailmentJudge; model?:
|
|
|
241
262
|
|
|
242
263
|
// ------------------------------------------------------------------ output
|
|
243
264
|
|
|
265
|
+
const MATCH_LABEL: Record<string, string> = {
|
|
266
|
+
exact: 'verbatim',
|
|
267
|
+
normalized: 'verbatim',
|
|
268
|
+
elided: 'verbatim with omission',
|
|
269
|
+
fuzzy: 'fuzzy',
|
|
270
|
+
};
|
|
271
|
+
|
|
244
272
|
function renderHuman(
|
|
245
273
|
report: VerificationReport,
|
|
246
274
|
gate: GateResult,
|
|
@@ -268,7 +296,7 @@ function renderHuman(
|
|
|
268
296
|
const match =
|
|
269
297
|
cit.textMatch.method === 'not_found'
|
|
270
298
|
? red(`quote not in source (best ${cit.textMatch.score.toFixed(2)})`)
|
|
271
|
-
: `${cit.textMatch.method
|
|
299
|
+
: `${MATCH_LABEL[cit.textMatch.method]} ${cit.textMatch.score.toFixed(2)}`;
|
|
272
300
|
const judged = cit.entailment
|
|
273
301
|
? cit.entailment.class === 'error'
|
|
274
302
|
? yellow('judge error')
|
|
@@ -276,8 +304,12 @@ function renderHuman(
|
|
|
276
304
|
: '';
|
|
277
305
|
out.push(`${mark} ${cit.claimId} [${cit.sourceIndex}] ${[match, judged].filter(Boolean).join(' · ')}`);
|
|
278
306
|
out.push(` ${truncate(cit.claimText || '(no claim text)', 160)}`);
|
|
307
|
+
const hides = gate.problems.find((p) => p.claimId === cit.claimId && p.sourceIndex === cit.sourceIndex)?.type === 'ellipsis_hides_qualifier';
|
|
279
308
|
if (bad && cit.textMatch.method === 'not_found') out.push(dim(' the quoted text does not occur in the source'));
|
|
280
|
-
else if (
|
|
309
|
+
else if (hides) {
|
|
310
|
+
const cues = (cit.textMatch.omittedCues ?? []).map((c) => `"${c}"`).join(', ');
|
|
311
|
+
out.push(dim(` the ellipsis leaves out ${cues}; run with a judge to check the full passage`));
|
|
312
|
+
} else if (bad && cit.entailment?.reasons.length) out.push(dim(` ${cit.entailment.reasons.map((r) => r.trim().replace(/[.;]+$/, '')).join('; ')}`));
|
|
281
313
|
else if (bad && cit.score !== null && cit.textMatch.method !== 'not_found') {
|
|
282
314
|
out.push(dim(` combined score ${cit.score.toFixed(2)} is below the minimum ${minScore.toFixed(2)}`));
|
|
283
315
|
}
|
|
@@ -287,13 +319,16 @@ function renderHuman(
|
|
|
287
319
|
|
|
288
320
|
out.push('');
|
|
289
321
|
if (gate.verdict === 'pass') {
|
|
290
|
-
out.push(green(report.citations.length ? 'PASS' : 'PASS
|
|
322
|
+
out.push(green(report.citations.length ? 'PASS' : 'PASS, but the answer cites nothing'));
|
|
323
|
+
} else if (gate.verdict === 'unverified') {
|
|
324
|
+
out.push(yellow(`UNVERIFIED: the judge failed on ${gate.unjudged.length} citation(s), so their support was not checked. Run the check again.`));
|
|
291
325
|
} else {
|
|
292
326
|
const parts = [
|
|
293
327
|
gate.problems.length && `${gate.problems.length} failed citation(s)`,
|
|
294
328
|
gate.uncited.length && `${gate.uncited.length} uncited sentence(s)`,
|
|
295
329
|
].filter(Boolean);
|
|
296
|
-
out.push(red(`REVISE
|
|
330
|
+
out.push(red(`REVISE: ${parts.join(', ')}`));
|
|
331
|
+
if (gate.unjudged.length) out.push(yellow(`The judge also failed on ${gate.unjudged.length} citation(s).`));
|
|
297
332
|
}
|
|
298
333
|
if (!model) out.push(dim('Only checked that quotes exist in their sources. Set VERIQUOTE_JUDGE_API_KEY to check support.'));
|
|
299
334
|
return `${out.join('\n')}\n`;
|
package/src/gate.ts
CHANGED
|
@@ -19,7 +19,8 @@ export type ProblemType =
|
|
|
19
19
|
| 'quote_not_in_source'
|
|
20
20
|
| 'contradicted_by_source'
|
|
21
21
|
| 'overstated'
|
|
22
|
-
| 'weakly_supported'
|
|
22
|
+
| 'weakly_supported'
|
|
23
|
+
| 'ellipsis_hides_qualifier';
|
|
23
24
|
|
|
24
25
|
export interface GateProblem {
|
|
25
26
|
claimId: string;
|
|
@@ -33,11 +34,17 @@ export interface GateProblem {
|
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
export interface GateResult {
|
|
36
|
-
|
|
37
|
+
/**
|
|
38
|
+
* `unverified`: nothing failed, but the judge could not rate some citations,
|
|
39
|
+
* so support was not checked for them. Never report that as a pass.
|
|
40
|
+
*/
|
|
41
|
+
verdict: 'pass' | 'revise' | 'unverified';
|
|
37
42
|
problems: GateProblem[];
|
|
38
43
|
/** Factual-looking sentences without any `[n]` marker. Heuristic. */
|
|
39
44
|
uncited: string[];
|
|
40
|
-
/**
|
|
45
|
+
/** Citations the judge failed on (only when a judge ran). */
|
|
46
|
+
unjudged: { claimId: string; sourceIndex: number; reason: string }[];
|
|
47
|
+
/** Ready-to-send correction prompt; `null` unless the verdict is `revise`. */
|
|
41
48
|
instructionsForModel: string | null;
|
|
42
49
|
}
|
|
43
50
|
|
|
@@ -69,25 +76,41 @@ export function gateReport(
|
|
|
69
76
|
score: c.score === null ? null : round(c.score),
|
|
70
77
|
}));
|
|
71
78
|
const uncited = findUncitedSentences(stripEvi1Appendix(answer), t.minUncitedChars);
|
|
72
|
-
const
|
|
79
|
+
const unjudged = report.citations
|
|
80
|
+
.filter((c) => c.entailment?.class === 'error')
|
|
81
|
+
.map((c) => ({ claimId: c.claimId, sourceIndex: c.sourceIndex, reason: c.entailment?.reasons.join('; ') || 'judge error' }));
|
|
82
|
+
const verdict = problems.length || uncited.length ? 'revise' : unjudged.length ? 'unverified' : 'pass';
|
|
73
83
|
return {
|
|
74
84
|
verdict,
|
|
75
85
|
problems,
|
|
76
86
|
uncited,
|
|
77
|
-
|
|
87
|
+
unjudged,
|
|
88
|
+
instructionsForModel: verdict === 'revise' ? correctionInstructions(problems, uncited) : null,
|
|
78
89
|
};
|
|
79
90
|
}
|
|
80
91
|
|
|
81
92
|
function isProblem(c: CitationVerification, minScore: number): boolean {
|
|
82
93
|
if (c.textMatch.method === 'not_found') return true;
|
|
94
|
+
if (hidesQualifier(c)) return true;
|
|
83
95
|
const cls = c.entailment?.class;
|
|
84
96
|
if (cls === 'contradicted' || cls === 'overstated') return true;
|
|
85
97
|
// A null score means the judge errored; an outage is not evidence against the claim.
|
|
86
98
|
return c.score !== null && c.score < minScore;
|
|
87
99
|
}
|
|
88
100
|
|
|
101
|
+
/**
|
|
102
|
+
* The ellipsis leaves out a word such as "not" or "except", and no judge has
|
|
103
|
+
* read the full passage. A judge verdict settles it either way ("not only …
|
|
104
|
+
* but also" is harmless), so this only fires without one.
|
|
105
|
+
*/
|
|
106
|
+
function hidesQualifier(c: CitationVerification): boolean {
|
|
107
|
+
const judged = c.entailment && c.entailment.class !== 'error';
|
|
108
|
+
return !judged && (c.textMatch.omittedCues?.length ?? 0) > 0;
|
|
109
|
+
}
|
|
110
|
+
|
|
89
111
|
function problemType(c: CitationVerification): ProblemType {
|
|
90
112
|
if (c.textMatch.method === 'not_found') return 'quote_not_in_source';
|
|
113
|
+
if (hidesQualifier(c)) return 'ellipsis_hides_qualifier';
|
|
91
114
|
if (c.entailment?.class === 'contradicted') return 'contradicted_by_source';
|
|
92
115
|
if (c.entailment?.class === 'overstated') return 'overstated';
|
|
93
116
|
return 'weakly_supported';
|
|
@@ -131,6 +154,8 @@ const FIX: Record<ProblemType, string> = {
|
|
|
131
154
|
contradicted_by_source: 'the cited source contradicts this claim — remove the claim or correct it to match the source',
|
|
132
155
|
overstated: 'this claim is stronger or more general than the evidence — weaken it to exactly what the quote supports',
|
|
133
156
|
weakly_supported: 'this claim is only weakly supported — cite a better passage or soften the wording',
|
|
157
|
+
ellipsis_hides_qualifier:
|
|
158
|
+
'the ellipsis in the quote leaves out a word that may reverse or limit the statement — quote the passage without the omission, or split it into separate quotes',
|
|
134
159
|
};
|
|
135
160
|
|
|
136
161
|
function correctionInstructions(problems: GateProblem[], uncited: string[]): string {
|