@zhixuan92/multi-model-agent-core 4.5.1 → 4.5.3
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/README.md +2 -4
- package/dist/escalation/fallback-helpers.d.ts.map +1 -1
- package/dist/escalation/fallback-helpers.js +0 -1
- package/dist/escalation/fallback-helpers.js.map +1 -1
- package/dist/events/event-builder.d.ts.map +1 -1
- package/dist/events/event-builder.js +96 -12
- package/dist/events/event-builder.js.map +1 -1
- package/dist/index.d.ts +0 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/lifecycle/lifecycle-context.d.ts +0 -2
- package/dist/lifecycle/lifecycle-context.d.ts.map +1 -1
- package/dist/lifecycle/task-executor.d.ts.map +1 -1
- package/dist/lifecycle/task-executor.js +5 -7
- package/dist/lifecycle/task-executor.js.map +1 -1
- package/dist/lifecycle/task-runner.d.ts +0 -2
- package/dist/lifecycle/task-runner.d.ts.map +1 -1
- package/dist/lifecycle/task-runner.js +1 -9
- package/dist/lifecycle/task-runner.js.map +1 -1
- package/dist/reporting/headline-templates/audit.d.ts.map +1 -1
- package/dist/reporting/headline-templates/audit.js +10 -14
- package/dist/reporting/headline-templates/audit.js.map +1 -1
- package/dist/reporting/headline-templates/debug.d.ts +3 -5
- package/dist/reporting/headline-templates/debug.d.ts.map +1 -1
- package/dist/reporting/headline-templates/debug.js +5 -8
- package/dist/reporting/headline-templates/debug.js.map +1 -1
- package/dist/reporting/headline-templates/review.d.ts.map +1 -1
- package/dist/reporting/headline-templates/review.js +6 -7
- package/dist/reporting/headline-templates/review.js.map +1 -1
- package/dist/review/default-engines.d.ts +0 -2
- package/dist/review/default-engines.d.ts.map +1 -1
- package/dist/review/default-engines.js +0 -4
- package/dist/review/default-engines.js.map +1 -1
- package/dist/review/index.d.ts +0 -4
- package/dist/review/index.d.ts.map +1 -1
- package/dist/review/index.js +0 -4
- package/dist/review/index.js.map +1 -1
- package/dist/review/review-types.d.ts +0 -16
- package/dist/review/review-types.d.ts.map +1 -1
- package/dist/review/review-types.js +4 -1
- package/dist/review/review-types.js.map +1 -1
- package/dist/types/run-result.d.ts +0 -11
- package/dist/types/run-result.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/reporting/annotate-completion-parser.d.ts +0 -39
- package/dist/reporting/annotate-completion-parser.d.ts.map +0 -1
- package/dist/reporting/annotate-completion-parser.js +0 -43
- package/dist/reporting/annotate-completion-parser.js.map +0 -1
- package/dist/review/annotator-engine.d.ts +0 -44
- package/dist/review/annotator-engine.d.ts.map +0 -1
- package/dist/review/annotator-engine.js +0 -115
- package/dist/review/annotator-engine.js.map +0 -1
- package/dist/review/annotator-output-parser.d.ts +0 -13
- package/dist/review/annotator-output-parser.d.ts.map +0 -1
- package/dist/review/annotator-output-parser.js +0 -104
- package/dist/review/annotator-output-parser.js.map +0 -1
- package/dist/review/annotator-prompt-builder.d.ts +0 -29
- package/dist/review/annotator-prompt-builder.d.ts.map +0 -1
- package/dist/review/annotator-prompt-builder.js +0 -87
- package/dist/review/annotator-prompt-builder.js.map +0 -1
- package/dist/review/review-verdict-aggregator.d.ts +0 -17
- package/dist/review/review-verdict-aggregator.d.ts.map +0 -1
- package/dist/review/review-verdict-aggregator.js +0 -30
- package/dist/review/review-verdict-aggregator.js.map +0 -1
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
import { AnnotatorPromptBuilder } from './annotator-prompt-builder.js';
|
|
2
|
-
import { AnnotatorOutputParser } from './annotator-output-parser.js';
|
|
3
|
-
import { HUMAN_LABEL } from '../lifecycle/stage-labels.js';
|
|
4
|
-
import { annotatorAuditTemplate } from './templates/annotator-audit.js';
|
|
5
|
-
import { annotatorReviewTemplate } from './templates/annotator-review.js';
|
|
6
|
-
import { annotatorDebugTemplate } from './templates/annotator-debug.js';
|
|
7
|
-
import { annotatorInvestigateTemplate } from './templates/annotator-investigate.js';
|
|
8
|
-
const DEFAULT_ANNOTATOR_TEMPLATES = {
|
|
9
|
-
audit: annotatorAuditTemplate,
|
|
10
|
-
review: annotatorReviewTemplate,
|
|
11
|
-
debug: annotatorDebugTemplate,
|
|
12
|
-
investigate: annotatorInvestigateTemplate,
|
|
13
|
-
};
|
|
14
|
-
/** Sentinel narrative emitted by sub-workers when their criterion has no
|
|
15
|
-
* matches in the artifact. Filtered out before merging so the annotator
|
|
16
|
-
* doesn't waste tokens parsing empty content. */
|
|
17
|
-
const NO_FINDINGS_SENTINEL = 'No findings for this criterion.';
|
|
18
|
-
export class AnnotatorEngine {
|
|
19
|
-
builder = new AnnotatorPromptBuilder(DEFAULT_ANNOTATOR_TEMPLATES);
|
|
20
|
-
parser = new AnnotatorOutputParser();
|
|
21
|
-
async annotate(session, input) {
|
|
22
|
-
// Drop "No findings for this criterion." sentinels — they're valid
|
|
23
|
-
// empty results, not findings to merge. If ALL narratives are empty
|
|
24
|
-
// sentinels, send a synthetic empty narrative so the annotator
|
|
25
|
-
// returns [] via its standard "no findings raised" path.
|
|
26
|
-
const usableOutputs = input.workerOutputs.filter(o => o.narrative.trim() !== NO_FINDINGS_SENTINEL);
|
|
27
|
-
const inputsForPrompt = usableOutputs.length > 0
|
|
28
|
-
? usableOutputs
|
|
29
|
-
: [{ criterion: 'all sub-workers reported no findings', narrative: '(all sub-worker narratives were "No findings for this criterion." — return [])' }];
|
|
30
|
-
const prompt = this.builder.build(input.route, { workerOutputs: inputsForPrompt, brief: input.brief });
|
|
31
|
-
// Per-annotator wall-clock guard. Same 10-min hard / 5-min soft pattern
|
|
32
|
-
// as the warmer + per-angle caps so the merge step can't hang the route.
|
|
33
|
-
// On hard cap, the abortSignal fires and the merge result returns with
|
|
34
|
-
// errorCode='aborted'; the parser then yields an empty findings list and
|
|
35
|
-
// the read-only route's soft-success path takes over (lifecycle returns
|
|
36
|
-
// implementer narratives even when annotator failed). Bounds total
|
|
37
|
-
// route wall: warmer (≤10) + max angle (≤10) + merge (≤10) + slack ≈ 32 min.
|
|
38
|
-
const annotatorAbort = new AbortController();
|
|
39
|
-
const combinedAbort = new AbortController();
|
|
40
|
-
if (input.abortSignal) {
|
|
41
|
-
if (input.abortSignal.aborted)
|
|
42
|
-
combinedAbort.abort();
|
|
43
|
-
else
|
|
44
|
-
input.abortSignal.addEventListener('abort', () => combinedAbort.abort(), { once: true });
|
|
45
|
-
}
|
|
46
|
-
annotatorAbort.signal.addEventListener('abort', () => combinedAbort.abort(), { once: true });
|
|
47
|
-
let capHit = false;
|
|
48
|
-
const softTimer = setTimeout(() => {
|
|
49
|
-
input.bus?.emit({
|
|
50
|
-
event: 'criteria_annotator_soft_warning',
|
|
51
|
-
ts: new Date().toISOString(),
|
|
52
|
-
...(input.batchId !== undefined && { batchId: input.batchId }),
|
|
53
|
-
...(input.taskIndex !== undefined && { taskIndex: input.taskIndex }),
|
|
54
|
-
elapsedMs: ANNOTATOR_SOFT_WARN_MS,
|
|
55
|
-
remainingMs: ANNOTATOR_HARD_CAP_MS - ANNOTATOR_SOFT_WARN_MS,
|
|
56
|
-
});
|
|
57
|
-
}, ANNOTATOR_SOFT_WARN_MS);
|
|
58
|
-
const hardTimer = setTimeout(() => {
|
|
59
|
-
capHit = true;
|
|
60
|
-
input.bus?.emit({
|
|
61
|
-
event: 'criteria_annotator_hard_cap',
|
|
62
|
-
ts: new Date().toISOString(),
|
|
63
|
-
...(input.batchId !== undefined && { batchId: input.batchId }),
|
|
64
|
-
...(input.taskIndex !== undefined && { taskIndex: input.taskIndex }),
|
|
65
|
-
elapsedMs: ANNOTATOR_HARD_CAP_MS,
|
|
66
|
-
});
|
|
67
|
-
annotatorAbort.abort();
|
|
68
|
-
}, ANNOTATOR_HARD_CAP_MS);
|
|
69
|
-
try {
|
|
70
|
-
const turn = await session.send(`${prompt}\n\nAnnotate the findings above.`, { stageLabel: input.stageLabel ?? HUMAN_LABEL.annotating });
|
|
71
|
-
// Adapt TurnResult → the shape this engine's parser + cost
|
|
72
|
-
// extractor uses.
|
|
73
|
-
const result = {
|
|
74
|
-
finalAssistantText: turn.output,
|
|
75
|
-
errorCode: turn.errorCode,
|
|
76
|
-
usage: turn.usage,
|
|
77
|
-
turns: turn.turns,
|
|
78
|
-
toolCalls: Object.values(turn.toolCallsByName).reduce((a, b) => a + b, 0),
|
|
79
|
-
costUSD: turn.costUSD,
|
|
80
|
-
durationMs: turn.durationMs,
|
|
81
|
-
};
|
|
82
|
-
if (capHit) {
|
|
83
|
-
return {
|
|
84
|
-
finalAssistantText: '',
|
|
85
|
-
verdict: 'error',
|
|
86
|
-
annotatedFindings: [],
|
|
87
|
-
concerns: [],
|
|
88
|
-
diagnostics: { extraSections: {} },
|
|
89
|
-
cost: extractCost(result),
|
|
90
|
-
};
|
|
91
|
-
}
|
|
92
|
-
const parsed = this.parser.parse({ finalAssistantText: result.finalAssistantText, errorCode: result.errorCode });
|
|
93
|
-
return { ...parsed, finalAssistantText: result.finalAssistantText ?? '', cost: extractCost(result) };
|
|
94
|
-
}
|
|
95
|
-
finally {
|
|
96
|
-
clearTimeout(softTimer);
|
|
97
|
-
clearTimeout(hardTimer);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
/** Per-annotator wall-clock cap. Same constants as the warmer + per-angle
|
|
102
|
-
* caps in providers/runner-shell.ts and lifecycle/parallel-criteria-dispatcher.ts. */
|
|
103
|
-
const ANNOTATOR_HARD_CAP_MS = 10 * 60 * 1000;
|
|
104
|
-
const ANNOTATOR_SOFT_WARN_MS = 5 * 60 * 1000;
|
|
105
|
-
function extractCost(r) {
|
|
106
|
-
return {
|
|
107
|
-
inputTokens: r.usage?.inputTokens ?? 0,
|
|
108
|
-
outputTokens: r.usage?.outputTokens ?? 0,
|
|
109
|
-
turnCount: r.turns ?? 0,
|
|
110
|
-
toolCallCount: typeof r.toolCalls === 'number' ? r.toolCalls : 0,
|
|
111
|
-
costUSD: r.costUSD ?? null,
|
|
112
|
-
durationMs: r.durationMs ?? null,
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
//# sourceMappingURL=annotator-engine.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"annotator-engine.js","sourceRoot":"","sources":["../../src/review/annotator-engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { AnnotatedFinding } from './review-types.js';
|
|
2
|
-
export interface AnnotatorParseResult {
|
|
3
|
-
verdict: 'annotated' | 'error';
|
|
4
|
-
annotatedFindings: AnnotatedFinding[];
|
|
5
|
-
errorReason?: string;
|
|
6
|
-
}
|
|
7
|
-
export declare class AnnotatorOutputParser {
|
|
8
|
-
parse(input: {
|
|
9
|
-
finalAssistantText: string | undefined;
|
|
10
|
-
errorCode?: string;
|
|
11
|
-
}): AnnotatorParseResult;
|
|
12
|
-
}
|
|
13
|
-
//# sourceMappingURL=annotator-output-parser.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"annotator-output-parser.d.ts","sourceRoot":"","sources":["../../src/review/annotator-output-parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC;IAC/B,iBAAiB,EAAE,gBAAgB,EAAE,CAAC;IACtC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AA4ED,qBAAa,qBAAqB;IAChC,KAAK,CAAC,KAAK,EAAE;QAAE,kBAAkB,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,oBAAoB;CAUnG"}
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tool sweep #12 follow-up: same lenient JSON-array extraction as
|
|
3
|
-
* the reviewer-output-parser. Pre-fix this required a fenced
|
|
4
|
-
* ```json ... ``` block. Some models emit:
|
|
5
|
-
* - Bare JSON arrays (no fence)
|
|
6
|
-
* - Fenced with no language tag (just ``` ... ```)
|
|
7
|
-
* - JSON arrays embedded in surrounding prose
|
|
8
|
-
* — all of which were dropped, producing `verdict: 'error'` even when
|
|
9
|
-
* the annotator did its job correctly. Caused verify's wire telemetry
|
|
10
|
-
* to lose all PASS findings (annotated 0 instead of 4).
|
|
11
|
-
*
|
|
12
|
-
* Strategy: try fenced first (legacy), then fenced-without-language-tag,
|
|
13
|
-
* then any balanced `[...]` containing finding-shaped objects in the
|
|
14
|
-
* raw text. Same balanced-walking approach as findFirstParseableJsonVerdict
|
|
15
|
-
* in reviewer-output-parser.ts.
|
|
16
|
-
*/
|
|
17
|
-
function extractFindingsArray(text) {
|
|
18
|
-
// Pass 1: ```json ... ``` (legacy).
|
|
19
|
-
const fenced1 = text.match(/```json\s*\n([\s\S]*?)\n```/i);
|
|
20
|
-
const r1 = fenced1 ? tryParseArray(fenced1[1]) : null;
|
|
21
|
-
if (r1)
|
|
22
|
-
return r1;
|
|
23
|
-
// Pass 2: ``` ... ``` (no language tag) — some models drop the json hint.
|
|
24
|
-
const fenced2 = text.match(/```\s*\n([\s\S]*?)\n```/);
|
|
25
|
-
const r2 = fenced2 ? tryParseArray(fenced2[1]) : null;
|
|
26
|
-
if (r2)
|
|
27
|
-
return r2;
|
|
28
|
-
// Pass 3: bare `[...]` array somewhere in the text. Walk every `[`
|
|
29
|
-
// left-to-right, find its matching `]` via balanced bracket counting
|
|
30
|
-
// (string-literal aware), try to parse each candidate.
|
|
31
|
-
for (let start = text.indexOf('['); start !== -1; start = text.indexOf('[', start + 1)) {
|
|
32
|
-
const end = matchingBracket(text, start);
|
|
33
|
-
if (end === -1)
|
|
34
|
-
continue;
|
|
35
|
-
const candidate = text.slice(start, end + 1);
|
|
36
|
-
const r = tryParseArray(candidate);
|
|
37
|
-
if (r)
|
|
38
|
-
return r;
|
|
39
|
-
}
|
|
40
|
-
return null;
|
|
41
|
-
}
|
|
42
|
-
function tryParseArray(jsonText) {
|
|
43
|
-
try {
|
|
44
|
-
const parsed = JSON.parse(jsonText);
|
|
45
|
-
if (Array.isArray(parsed))
|
|
46
|
-
return parsed;
|
|
47
|
-
}
|
|
48
|
-
catch {
|
|
49
|
-
/* not parseable */
|
|
50
|
-
}
|
|
51
|
-
return null;
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Return the index of the `]` that balances the `[` at `openPos`,
|
|
55
|
-
* accounting for nested brackets and string literals.
|
|
56
|
-
*/
|
|
57
|
-
function matchingBracket(text, openPos) {
|
|
58
|
-
let depth = 0;
|
|
59
|
-
let inString = false;
|
|
60
|
-
let escape = false;
|
|
61
|
-
for (let i = openPos; i < text.length; i++) {
|
|
62
|
-
const ch = text[i];
|
|
63
|
-
if (inString) {
|
|
64
|
-
if (escape) {
|
|
65
|
-
escape = false;
|
|
66
|
-
continue;
|
|
67
|
-
}
|
|
68
|
-
if (ch === '\\') {
|
|
69
|
-
escape = true;
|
|
70
|
-
continue;
|
|
71
|
-
}
|
|
72
|
-
if (ch === '"') {
|
|
73
|
-
inString = false;
|
|
74
|
-
continue;
|
|
75
|
-
}
|
|
76
|
-
continue;
|
|
77
|
-
}
|
|
78
|
-
if (ch === '"') {
|
|
79
|
-
inString = true;
|
|
80
|
-
continue;
|
|
81
|
-
}
|
|
82
|
-
if (ch === '[')
|
|
83
|
-
depth++;
|
|
84
|
-
else if (ch === ']') {
|
|
85
|
-
depth--;
|
|
86
|
-
if (depth === 0)
|
|
87
|
-
return i;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
return -1;
|
|
91
|
-
}
|
|
92
|
-
export class AnnotatorOutputParser {
|
|
93
|
-
parse(input) {
|
|
94
|
-
if (!input.finalAssistantText) {
|
|
95
|
-
return { verdict: 'error', annotatedFindings: [], errorReason: input.errorCode ?? 'no output' };
|
|
96
|
-
}
|
|
97
|
-
const findings = extractFindingsArray(input.finalAssistantText);
|
|
98
|
-
if (findings === null) {
|
|
99
|
-
return { verdict: 'error', annotatedFindings: [], errorReason: 'no JSON array found in annotator output' };
|
|
100
|
-
}
|
|
101
|
-
return { verdict: 'annotated', annotatedFindings: findings };
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
//# sourceMappingURL=annotator-output-parser.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"annotator-output-parser.js","sourceRoot":"","sources":["../../src/review/annotator-output-parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { type AnnotatorPromptContext, type AnnotatorTemplate } from './templates/annotator-shared.js';
|
|
2
|
-
export type AnnotatorRoute = 'audit' | 'review' | 'debug' | 'investigate';
|
|
3
|
-
export declare class AnnotatorPromptBuilder {
|
|
4
|
-
private templates;
|
|
5
|
-
constructor(templates: Record<AnnotatorRoute, AnnotatorTemplate>);
|
|
6
|
-
build(route: AnnotatorRoute, ctx: AnnotatorPromptContext): string;
|
|
7
|
-
}
|
|
8
|
-
/**
|
|
9
|
-
* Trim the implementer brief down to the "what was asked" essentials
|
|
10
|
-
* before sending to the annotator. The annotator does NOT need the
|
|
11
|
-
* finding-format spec (it has its own format spec via buildAnnotatorRubric)
|
|
12
|
-
* or the delta-mode instructions. Sending the full brief wastes
|
|
13
|
-
* 1-3KB context per call and mildly distracts the model.
|
|
14
|
-
*
|
|
15
|
-
* Two prompt shapes covered:
|
|
16
|
-
*
|
|
17
|
-
* 1. **Goal-first** (audit / review / verify / debug):
|
|
18
|
-
* `<goal + scope>\n\n<format spec at the END>` — slice off the
|
|
19
|
-
* format spec, keep everything before it.
|
|
20
|
-
*
|
|
21
|
-
* 2. **Spec-first** (investigate): the brief opens with the
|
|
22
|
-
* structured-format instructions and ends with `Question: <text>`.
|
|
23
|
-
* Pull the question line out as the compact brief.
|
|
24
|
-
*
|
|
25
|
-
* If neither shape applies, the brief is returned unchanged.
|
|
26
|
-
*/
|
|
27
|
-
export declare function trimBriefForAnnotator(brief: string): string;
|
|
28
|
-
export declare function assembleAnnotatorPrompt(template: AnnotatorTemplate, ctx: AnnotatorPromptContext): string;
|
|
29
|
-
//# sourceMappingURL=annotator-prompt-builder.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"annotator-prompt-builder.d.ts","sourceRoot":"","sources":["../../src/review/annotator-prompt-builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,KAAK,sBAAsB,EAAE,KAAK,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAE5H,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,aAAa,CAAC;AAE1E,qBAAa,sBAAsB;IAE/B,OAAO,CAAC,SAAS;gBAAT,SAAS,EAAE,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC;IAG9D,KAAK,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,EAAE,sBAAsB,GAAG,MAAM;CAGlE;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CA2B3D;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,iBAAiB,EAAE,GAAG,EAAE,sBAAsB,GAAG,MAAM,CAiCxG"}
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import { buildAnnotatorRubric } from './templates/annotator-shared.js';
|
|
2
|
-
export class AnnotatorPromptBuilder {
|
|
3
|
-
templates;
|
|
4
|
-
constructor(templates) {
|
|
5
|
-
this.templates = templates;
|
|
6
|
-
}
|
|
7
|
-
build(route, ctx) {
|
|
8
|
-
return assembleAnnotatorPrompt(this.templates[route], ctx);
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
/**
|
|
12
|
-
* Trim the implementer brief down to the "what was asked" essentials
|
|
13
|
-
* before sending to the annotator. The annotator does NOT need the
|
|
14
|
-
* finding-format spec (it has its own format spec via buildAnnotatorRubric)
|
|
15
|
-
* or the delta-mode instructions. Sending the full brief wastes
|
|
16
|
-
* 1-3KB context per call and mildly distracts the model.
|
|
17
|
-
*
|
|
18
|
-
* Two prompt shapes covered:
|
|
19
|
-
*
|
|
20
|
-
* 1. **Goal-first** (audit / review / verify / debug):
|
|
21
|
-
* `<goal + scope>\n\n<format spec at the END>` — slice off the
|
|
22
|
-
* format spec, keep everything before it.
|
|
23
|
-
*
|
|
24
|
-
* 2. **Spec-first** (investigate): the brief opens with the
|
|
25
|
-
* structured-format instructions and ends with `Question: <text>`.
|
|
26
|
-
* Pull the question line out as the compact brief.
|
|
27
|
-
*
|
|
28
|
-
* If neither shape applies, the brief is returned unchanged.
|
|
29
|
-
*/
|
|
30
|
-
export function trimBriefForAnnotator(brief) {
|
|
31
|
-
if (typeof brief !== 'string' || brief.length === 0)
|
|
32
|
-
return brief;
|
|
33
|
-
// Shape 2 (investigate): pull the `Question: ...` line out.
|
|
34
|
-
const questionMatch = brief.match(/^\s*Question:\s+(.+)$/m);
|
|
35
|
-
if (questionMatch) {
|
|
36
|
-
return `Question: ${questionMatch[1].trim()}`;
|
|
37
|
-
}
|
|
38
|
-
// Shape 1 (audit / review / verify / debug): slice before the first
|
|
39
|
-
// format-spec marker. Each per-tool implementer prompt structures
|
|
40
|
-
// the goal at the top, format spec at the bottom — so this gives
|
|
41
|
-
// the annotator the goal + scope without the duplicated format
|
|
42
|
-
// instructions.
|
|
43
|
-
const markers = [
|
|
44
|
-
/\nProduce a narrative .* report\./i,
|
|
45
|
-
/\nFor each checklist item, use this EXACT/i,
|
|
46
|
-
/\nUse hypothesis-driven debugging\./i,
|
|
47
|
-
/\n## Finding 1:/i,
|
|
48
|
-
/\nUse this EXACT per-finding format/i,
|
|
49
|
-
];
|
|
50
|
-
let cut = brief.length;
|
|
51
|
-
for (const m of markers) {
|
|
52
|
-
const idx = brief.search(m);
|
|
53
|
-
if (idx >= 0 && idx < cut)
|
|
54
|
-
cut = idx;
|
|
55
|
-
}
|
|
56
|
-
return brief.slice(0, cut).trim();
|
|
57
|
-
}
|
|
58
|
-
export function assembleAnnotatorPrompt(template, ctx) {
|
|
59
|
-
// Tool sweep #11: trim the brief — the format-spec section is
|
|
60
|
-
// duplicated by buildAnnotatorRubric below, so sending it again is
|
|
61
|
-
// redundant + costly.
|
|
62
|
-
const compactBrief = trimBriefForAnnotator(ctx.brief);
|
|
63
|
-
// Multi-narrative merge mode: each sub-worker covered ONE criterion.
|
|
64
|
-
// The annotator dedups overlapping findings and recalibrates severity
|
|
65
|
-
// against the shared SEVERITY_LADDER. Single-narrative inputs (e.g.
|
|
66
|
-
// a route that hasn't migrated to fan-out) take the same path with N=1.
|
|
67
|
-
const sections = ctx.workerOutputs.map(o => `--- Sub-worker for ${o.criterion} ---\n${o.narrative}`).join('\n\n');
|
|
68
|
-
const mergeInstructions = ctx.workerOutputs.length > 1
|
|
69
|
-
? `\n## Merge instructions (text-only — do NOT read files; you have no tools)\n\nThe worker output below is N narratives, each from a sub-worker that covered ONE criterion. Merge them into a single findings list using ONLY the text below — no file reads, no greps. Your job:\n1. Combine findings across narratives into one list.\n2. Dedup by (file, line, claim essence) using TEXTUAL comparison — if two findings name the same file:line and describe the same issue in different words, KEEP ONE (higher severity wins; merge any non-redundant evidence quoted in their text).\n3. Recalibrate severity using the shared severity ladder so a sub-worker that inflated within its narrow scope is rebucketed against the global picture.\n4. Drop narratives that contained no findings (valid empty results, not parse failures).\n5. **DROP findings whose title starts with "[N/A]"** — completeness signals from sub-workers reporting "this perspective does not apply." MUST NOT appear in the final array.\n6. Do NOT speculate, expand, re-investigate, or "verify" findings against the source — your input is the narratives only. If you can't dedup confidently from the text, keep both findings and let the reader decide.\n\n`
|
|
70
|
-
: '';
|
|
71
|
-
return `You are reviewing a ${template.role} produced by a worker.
|
|
72
|
-
|
|
73
|
-
The user requested a ${template.role}. The brief was:
|
|
74
|
-
|
|
75
|
-
${compactBrief}
|
|
76
|
-
|
|
77
|
-
## On-brief check (per finding)
|
|
78
|
-
|
|
79
|
-
${template.onBriefCheck}
|
|
80
|
-
${mergeInstructions}
|
|
81
|
-
## Worker output to extract findings from
|
|
82
|
-
|
|
83
|
-
${sections}
|
|
84
|
-
|
|
85
|
-
${buildAnnotatorRubric(template)}`;
|
|
86
|
-
}
|
|
87
|
-
//# sourceMappingURL=annotator-prompt-builder.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"annotator-prompt-builder.js","sourceRoot":"","sources":["../../src/review/annotator-prompt-builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAuD,MAAM,iCAAiC,CAAC;AAI5H,MAAM,OAAO,sBAAsB;IAEvB;IADV,YACU,SAAoD;QAApD,cAAS,GAAT,SAAS,CAA2C;IAC3D,CAAC;IAEJ,KAAK,CAAC,KAAqB,EAAE,GAA2B;QACtD,OAAO,uBAAuB,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC;IAC7D,CAAC;CACF;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAa;IACjD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAElE,4DAA4D;IAC5D,MAAM,aAAa,GAAG,KAAK,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAC5D,IAAI,aAAa,EAAE,CAAC;QAClB,OAAO,aAAa,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;IAChD,CAAC;IAED,oEAAoE;IACpE,kEAAkE;IAClE,iEAAiE;IACjE,+DAA+D;IAC/D,gBAAgB;IAChB,MAAM,OAAO,GAAG;QACd,oCAAoC;QACpC,4CAA4C;QAC5C,sCAAsC;QACtC,kBAAkB;QAClB,sCAAsC;KACvC,CAAC;IACF,IAAI,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC;IACvB,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC5B,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,GAAG,GAAG;YAAE,GAAG,GAAG,GAAG,CAAC;IACvC,CAAC;IACD,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,QAA2B,EAAE,GAA2B;IAC9F,8DAA8D;IAC9D,mEAAmE;IACnE,sBAAsB;IACtB,MAAM,YAAY,GAAG,qBAAqB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAEtD,qEAAqE;IACrE,sEAAsE;IACtE,oEAAoE;IACpE,wEAAwE;IACxE,MAAM,QAAQ,GAAG,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CACzC,sBAAsB,CAAC,CAAC,SAAS,SAAS,CAAC,CAAC,SAAS,EAAE,CACxD,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAEf,MAAM,iBAAiB,GAAG,GAAG,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC;QACpD,CAAC,CAAC,yrCAAyrC;QAC3rC,CAAC,CAAC,EAAE,CAAC;IAEP,OAAO,uBAAuB,QAAQ,CAAC,IAAI;;uBAEtB,QAAQ,CAAC,IAAI;;EAElC,YAAY;;;;EAIZ,QAAQ,CAAC,YAAY;EACrB,iBAAiB;;;EAGjB,QAAQ;;EAER,oBAAoB,CAAC,QAAQ,CAAC,EAAE,CAAC;AACnC,CAAC"}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import type { ReviewVerdict } from '../types.js';
|
|
2
|
-
export interface ReviewSlot {
|
|
3
|
-
verdict: ReviewVerdict;
|
|
4
|
-
concerns?: string[];
|
|
5
|
-
}
|
|
6
|
-
export interface AggregatedReviews {
|
|
7
|
-
finalVerdict: ReviewVerdict;
|
|
8
|
-
allConcerns: string[];
|
|
9
|
-
}
|
|
10
|
-
/**
|
|
11
|
-
* Aggregate verdicts across multiple review slots (spec/quality/diff).
|
|
12
|
-
* The final verdict is the most-severe across slots; concerns are unioned.
|
|
13
|
-
*
|
|
14
|
-
* Severity order: error > changes_required > concerns > annotated > approved > not_applicable/skipped.
|
|
15
|
-
*/
|
|
16
|
-
export declare function aggregateReviews(slots: ReviewSlot[]): AggregatedReviews;
|
|
17
|
-
//# sourceMappingURL=review-verdict-aggregator.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"review-verdict-aggregator.d.ts","sourceRoot":"","sources":["../../src/review/review-verdict-aggregator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,aAAa,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,YAAY,EAAE,aAAa,CAAC;IAC5B,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAYD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,iBAAiB,CAYvE"}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
const VERDICT_PRIORITY = {
|
|
2
|
-
error: 5,
|
|
3
|
-
changes_required: 4,
|
|
4
|
-
concerns: 3,
|
|
5
|
-
annotated: 2,
|
|
6
|
-
approved: 1,
|
|
7
|
-
not_applicable: 0,
|
|
8
|
-
skipped: 0,
|
|
9
|
-
};
|
|
10
|
-
/**
|
|
11
|
-
* Aggregate verdicts across multiple review slots (spec/quality/diff).
|
|
12
|
-
* The final verdict is the most-severe across slots; concerns are unioned.
|
|
13
|
-
*
|
|
14
|
-
* Severity order: error > changes_required > concerns > annotated > approved > not_applicable/skipped.
|
|
15
|
-
*/
|
|
16
|
-
export function aggregateReviews(slots) {
|
|
17
|
-
let finalVerdict = 'not_applicable';
|
|
18
|
-
const allConcerns = [];
|
|
19
|
-
for (const slot of slots) {
|
|
20
|
-
if ((VERDICT_PRIORITY[slot.verdict] ?? 0) > (VERDICT_PRIORITY[finalVerdict] ?? 0)) {
|
|
21
|
-
finalVerdict = slot.verdict;
|
|
22
|
-
}
|
|
23
|
-
if (slot.concerns) {
|
|
24
|
-
for (const c of slot.concerns)
|
|
25
|
-
allConcerns.push(c);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
return { finalVerdict, allConcerns };
|
|
29
|
-
}
|
|
30
|
-
//# sourceMappingURL=review-verdict-aggregator.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"review-verdict-aggregator.js","sourceRoot":"","sources":["../../src/review/review-verdict-aggregator.ts"],"names":[],"mappings":"AAYA,MAAM,gBAAgB,GAAkC;IACtD,KAAK,EAAE,CAAC;IACR,gBAAgB,EAAE,CAAC;IACnB,QAAQ,EAAE,CAAC;IACX,SAAS,EAAE,CAAC;IACZ,QAAQ,EAAE,CAAC;IACX,cAAc,EAAE,CAAC;IACjB,OAAO,EAAE,CAAC;CACX,CAAC;AAEF;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAmB;IAClD,IAAI,YAAY,GAAkB,gBAAgB,CAAC;IACnD,MAAM,WAAW,GAAa,EAAE,CAAC;IACjC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,gBAAgB,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;YAClF,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC;QAC9B,CAAC;QACD,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ;gBAAE,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;IACD,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC;AACvC,CAAC"}
|