@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.
Files changed (65) hide show
  1. package/README.md +2 -4
  2. package/dist/escalation/fallback-helpers.d.ts.map +1 -1
  3. package/dist/escalation/fallback-helpers.js +0 -1
  4. package/dist/escalation/fallback-helpers.js.map +1 -1
  5. package/dist/events/event-builder.d.ts.map +1 -1
  6. package/dist/events/event-builder.js +96 -12
  7. package/dist/events/event-builder.js.map +1 -1
  8. package/dist/index.d.ts +0 -2
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +0 -1
  11. package/dist/index.js.map +1 -1
  12. package/dist/lifecycle/lifecycle-context.d.ts +0 -2
  13. package/dist/lifecycle/lifecycle-context.d.ts.map +1 -1
  14. package/dist/lifecycle/task-executor.d.ts.map +1 -1
  15. package/dist/lifecycle/task-executor.js +5 -7
  16. package/dist/lifecycle/task-executor.js.map +1 -1
  17. package/dist/lifecycle/task-runner.d.ts +0 -2
  18. package/dist/lifecycle/task-runner.d.ts.map +1 -1
  19. package/dist/lifecycle/task-runner.js +1 -9
  20. package/dist/lifecycle/task-runner.js.map +1 -1
  21. package/dist/reporting/headline-templates/audit.d.ts.map +1 -1
  22. package/dist/reporting/headline-templates/audit.js +10 -14
  23. package/dist/reporting/headline-templates/audit.js.map +1 -1
  24. package/dist/reporting/headline-templates/debug.d.ts +3 -5
  25. package/dist/reporting/headline-templates/debug.d.ts.map +1 -1
  26. package/dist/reporting/headline-templates/debug.js +5 -8
  27. package/dist/reporting/headline-templates/debug.js.map +1 -1
  28. package/dist/reporting/headline-templates/review.d.ts.map +1 -1
  29. package/dist/reporting/headline-templates/review.js +6 -7
  30. package/dist/reporting/headline-templates/review.js.map +1 -1
  31. package/dist/review/default-engines.d.ts +0 -2
  32. package/dist/review/default-engines.d.ts.map +1 -1
  33. package/dist/review/default-engines.js +0 -4
  34. package/dist/review/default-engines.js.map +1 -1
  35. package/dist/review/index.d.ts +0 -4
  36. package/dist/review/index.d.ts.map +1 -1
  37. package/dist/review/index.js +0 -4
  38. package/dist/review/index.js.map +1 -1
  39. package/dist/review/review-types.d.ts +0 -16
  40. package/dist/review/review-types.d.ts.map +1 -1
  41. package/dist/review/review-types.js +4 -1
  42. package/dist/review/review-types.js.map +1 -1
  43. package/dist/types/run-result.d.ts +0 -11
  44. package/dist/types/run-result.d.ts.map +1 -1
  45. package/package.json +1 -1
  46. package/dist/reporting/annotate-completion-parser.d.ts +0 -39
  47. package/dist/reporting/annotate-completion-parser.d.ts.map +0 -1
  48. package/dist/reporting/annotate-completion-parser.js +0 -43
  49. package/dist/reporting/annotate-completion-parser.js.map +0 -1
  50. package/dist/review/annotator-engine.d.ts +0 -44
  51. package/dist/review/annotator-engine.d.ts.map +0 -1
  52. package/dist/review/annotator-engine.js +0 -115
  53. package/dist/review/annotator-engine.js.map +0 -1
  54. package/dist/review/annotator-output-parser.d.ts +0 -13
  55. package/dist/review/annotator-output-parser.d.ts.map +0 -1
  56. package/dist/review/annotator-output-parser.js +0 -104
  57. package/dist/review/annotator-output-parser.js.map +0 -1
  58. package/dist/review/annotator-prompt-builder.d.ts +0 -29
  59. package/dist/review/annotator-prompt-builder.d.ts.map +0 -1
  60. package/dist/review/annotator-prompt-builder.js +0 -87
  61. package/dist/review/annotator-prompt-builder.js.map +0 -1
  62. package/dist/review/review-verdict-aggregator.d.ts +0 -17
  63. package/dist/review/review-verdict-aggregator.d.ts.map +0 -1
  64. package/dist/review/review-verdict-aggregator.js +0 -30
  65. 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"}