@in-the-loop-labs/pair-review 1.4.3 → 1.5.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/package.json +1 -1
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/skills/review-requests/SKILL.md +54 -0
- package/plugin-code-critic/.claude-plugin/plugin.json +1 -1
- package/public/css/pr.css +1081 -54
- package/public/css/repo-settings.css +452 -140
- package/public/js/components/AdvancedConfigTab.js +1364 -0
- package/public/js/components/AnalysisConfigModal.js +488 -112
- package/public/js/components/CouncilProgressModal.js +1416 -0
- package/public/js/components/TextInputDialog.js +231 -0
- package/public/js/components/TimeoutSelect.js +367 -0
- package/public/js/components/VoiceCentricConfigTab.js +1334 -0
- package/public/js/local.js +162 -83
- package/public/js/modules/analysis-history.js +185 -11
- package/public/js/modules/comment-manager.js +13 -0
- package/public/js/modules/file-comment-manager.js +28 -0
- package/public/js/pr.js +233 -115
- package/public/js/repo-settings.js +575 -106
- package/public/local.html +11 -1
- package/public/pr.html +6 -1
- package/public/repo-settings.html +28 -21
- package/public/setup.html +8 -2
- package/src/ai/analyzer.js +1262 -111
- package/src/ai/claude-cli.js +2 -2
- package/src/ai/claude-provider.js +6 -6
- package/src/ai/codex-provider.js +6 -6
- package/src/ai/copilot-provider.js +3 -3
- package/src/ai/cursor-agent-provider.js +6 -6
- package/src/ai/gemini-provider.js +6 -6
- package/src/ai/opencode-provider.js +6 -6
- package/src/ai/pi-provider.js +6 -6
- package/src/ai/prompts/baseline/consolidation/balanced.js +208 -0
- package/src/ai/prompts/baseline/consolidation/fast.js +175 -0
- package/src/ai/prompts/baseline/consolidation/thorough.js +283 -0
- package/src/ai/prompts/config.js +1 -1
- package/src/ai/prompts/index.js +26 -2
- package/src/ai/provider.js +4 -2
- package/src/database.js +417 -14
- package/src/main.js +1 -1
- package/src/routes/analysis.js +495 -10
- package/src/routes/config.js +36 -15
- package/src/routes/councils.js +351 -0
- package/src/routes/local.js +33 -11
- package/src/routes/mcp.js +9 -2
- package/src/routes/setup.js +12 -2
- package/src/routes/shared.js +126 -13
- package/src/server.js +34 -4
- package/src/utils/stats-calculator.js +2 -0
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
2
|
+
/**
|
|
3
|
+
* Consolidation Thorough Prompt - Comprehensive Cross-Reviewer Suggestion Merging
|
|
4
|
+
*
|
|
5
|
+
* This is the thorough tier variant of Consolidation analysis. It is optimized for
|
|
6
|
+
* careful, detailed merging with extended reasoning and comprehensive guidance
|
|
7
|
+
* for resolving conflicts and synthesizing multi-reviewer findings.
|
|
8
|
+
*
|
|
9
|
+
* Tier-specific optimizations applied:
|
|
10
|
+
* - ADDED: Reasoning encouragement section for thoughtful synthesis
|
|
11
|
+
* - COMPREHENSIVE: Consolidation rules with detailed conflict resolution
|
|
12
|
+
* - COMPREHENSIVE: Consensus handling with confidence calibration
|
|
13
|
+
* - ADDED: Summary synthesis guidance
|
|
14
|
+
* - EXPANDED: Guidelines with review philosophy
|
|
15
|
+
* - INCLUDED: All optional sections
|
|
16
|
+
*
|
|
17
|
+
* Section categories:
|
|
18
|
+
* - locked: Cannot be modified by variants (data integrity)
|
|
19
|
+
* - required: Must be present, content can be rephrased
|
|
20
|
+
* - optional: Can be removed entirely if unhelpful
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Tagged prompt template for Consolidation Thorough analysis
|
|
25
|
+
*
|
|
26
|
+
* Placeholders:
|
|
27
|
+
* - {{reviewIntro}} - Review introduction line
|
|
28
|
+
* - {{lineNumberGuidance}} - Line number guidance section
|
|
29
|
+
* - {{customInstructions}} - Custom instructions section (optional)
|
|
30
|
+
* - {{reviewerSuggestions}} - Formatted reviewer suggestions input
|
|
31
|
+
* - {{suggestionCount}} - Total number of input suggestions
|
|
32
|
+
* - {{reviewerCount}} - Number of reviewers being consolidated
|
|
33
|
+
*/
|
|
34
|
+
const taggedPrompt = `<section name="role" required="true" tier="thorough">
|
|
35
|
+
{{reviewIntro}}
|
|
36
|
+
</section>
|
|
37
|
+
|
|
38
|
+
<section name="task-header" required="true" tier="thorough">
|
|
39
|
+
# Deep Cross-Reviewer Consolidation Task
|
|
40
|
+
</section>
|
|
41
|
+
|
|
42
|
+
<section name="line-number-guidance" required="true">
|
|
43
|
+
{{lineNumberGuidance}}
|
|
44
|
+
</section>
|
|
45
|
+
|
|
46
|
+
<section name="critical-output" locked="true">
|
|
47
|
+
**>>> CRITICAL: Output ONLY valid JSON. No markdown, no \`\`\`json blocks. Start with { end with }. <<<**
|
|
48
|
+
</section>
|
|
49
|
+
|
|
50
|
+
<section name="role-description" required="true" tier="thorough">
|
|
51
|
+
## Your Role
|
|
52
|
+
Multiple independent AI reviewers have analyzed the same code changes. Your task is to carefully merge their findings into a single, high-quality set of suggestions. This requires thoughtful deduplication, nuanced conflict resolution, and preservation of the most valuable unique insights from each reviewer.
|
|
53
|
+
|
|
54
|
+
Each reviewer may have used a different AI model, perspective, or focus area. Your consolidation should produce output that is stronger than any individual review.
|
|
55
|
+
</section>
|
|
56
|
+
|
|
57
|
+
<section name="reasoning-encouragement" required="true" tier="thorough">
|
|
58
|
+
## Reasoning Approach
|
|
59
|
+
Take your time to analyze the reviewer findings thoroughly. For each cluster of related suggestions:
|
|
60
|
+
1. Identify which reviewers flagged the same or overlapping issues
|
|
61
|
+
2. Evaluate the strength of evidence from each reviewer
|
|
62
|
+
3. Determine the best framing that captures the full insight
|
|
63
|
+
4. Calibrate confidence based on reviewer agreement and evidence quality
|
|
64
|
+
5. Consider whether merging would lose important nuance
|
|
65
|
+
6. Formulate clear, actionable guidance that respects reviewer autonomy
|
|
66
|
+
</section>
|
|
67
|
+
|
|
68
|
+
<section name="custom-instructions" optional="true" tier="balanced,thorough">
|
|
69
|
+
{{customInstructions}}
|
|
70
|
+
</section>
|
|
71
|
+
|
|
72
|
+
<section name="input-suggestions" locked="true">
|
|
73
|
+
## Input: {{reviewerCount}} Reviewer(s), {{suggestionCount}} Total Suggestions
|
|
74
|
+
|
|
75
|
+
{{reviewerSuggestions}}
|
|
76
|
+
</section>
|
|
77
|
+
|
|
78
|
+
<section name="consolidation-rules" required="true" tier="thorough">
|
|
79
|
+
## Consolidation Guidelines
|
|
80
|
+
|
|
81
|
+
### 1. Deduplication
|
|
82
|
+
Apply careful analysis when identifying duplicates:
|
|
83
|
+
|
|
84
|
+
**When to Merge:**
|
|
85
|
+
- Same issue identified at the same file and line by multiple reviewers
|
|
86
|
+
- Overlapping concerns that are better presented as a unified insight
|
|
87
|
+
- Complementary details from different reviewers that enrich understanding
|
|
88
|
+
|
|
89
|
+
**When NOT to Merge:**
|
|
90
|
+
- Issues that are genuinely distinct despite affecting similar code
|
|
91
|
+
- Reviewer-specific context that would be lost in merging
|
|
92
|
+
- Situations where separate action items are clearer than combined ones
|
|
93
|
+
|
|
94
|
+
**Merging Best Practices:**
|
|
95
|
+
- Preserve the most actionable and specific details from each reviewer
|
|
96
|
+
- Use the clearest framing, regardless of which reviewer provided it
|
|
97
|
+
- Do NOT mention which reviewer found the issue — focus on the insight itself
|
|
98
|
+
|
|
99
|
+
### 2. Conflict Resolution
|
|
100
|
+
When reviewers disagree about an issue:
|
|
101
|
+
- **Evaluate evidence quality**: Concrete code analysis > pattern matching > heuristics
|
|
102
|
+
- **Consider specificity**: More specific analysis usually wins
|
|
103
|
+
- **Weight actionability**: Prefer the suggestion that gives clearer next steps
|
|
104
|
+
- **When truly uncertain**: Include the suggestion with reduced confidence and note the tension in the description
|
|
105
|
+
|
|
106
|
+
### 3. Unique Insights
|
|
107
|
+
- **Preserve suggestions** that only one reviewer noticed — these are often the most valuable
|
|
108
|
+
- A unique finding from one reviewer may represent a perspective the others missed
|
|
109
|
+
- Don't penalize unique findings with lower confidence just because they lack consensus
|
|
110
|
+
|
|
111
|
+
### 4. Quality Filter
|
|
112
|
+
- Drop suggestions with very low confidence (< 0.3) unless multiple reviewers agree
|
|
113
|
+
- Elevate suggestions where reviewers independently converge
|
|
114
|
+
</section>
|
|
115
|
+
|
|
116
|
+
<section name="consensus-handling" required="true" tier="thorough">
|
|
117
|
+
### 5. Consensus Handling and Confidence Calibration
|
|
118
|
+
|
|
119
|
+
**Cross-Reviewer Agreement:**
|
|
120
|
+
- **Strong consensus** (3+ reviewers): Boost confidence by 0.2 (cap at 1.0)
|
|
121
|
+
- **Moderate consensus** (2 reviewers): Boost confidence by 0.1
|
|
122
|
+
- **Single reviewer**: Preserve original confidence — don't penalize valuable unique findings
|
|
123
|
+
- **Contradiction**: Use the lower confidence minus 0.1
|
|
124
|
+
|
|
125
|
+
**Confidence Calibration:**
|
|
126
|
+
- High (0.8+): Clear issues with strong evidence or multi-reviewer consensus
|
|
127
|
+
- Medium (0.5-0.79): Likely valuable suggestions with reasonable evidence
|
|
128
|
+
- Lower (0.3-0.49): Marginal suggestions — include only if unique and actionable
|
|
129
|
+
- Very low (<0.3): Consider omitting unless multi-reviewer consensus
|
|
130
|
+
|
|
131
|
+
Note: Confidence is about certainty of value, not severity.
|
|
132
|
+
</section>
|
|
133
|
+
|
|
134
|
+
<section name="summary-synthesis" required="true" tier="thorough">
|
|
135
|
+
## Summary Synthesis Guidance
|
|
136
|
+
The summary field should synthesize the findings, not list them.
|
|
137
|
+
|
|
138
|
+
**Effective Summary Approach:**
|
|
139
|
+
- **Lead with the most important insight**: What should the reviewer focus on first?
|
|
140
|
+
- **Connect the dots**: How do individual findings relate to each other?
|
|
141
|
+
- **Calibrate severity**: Is this code fundamentally sound with minor issues, or are there structural problems?
|
|
142
|
+
- **Write as a single reviewer**: Do NOT mention consolidation, merging, or multiple reviewers
|
|
143
|
+
</section>
|
|
144
|
+
|
|
145
|
+
<section name="output-schema" locked="true">
|
|
146
|
+
## Output Format
|
|
147
|
+
|
|
148
|
+
**>>> CRITICAL: Output ONLY valid JSON. No markdown, no \`\`\`json blocks. Start with { end with }. <<<**
|
|
149
|
+
|
|
150
|
+
Output JSON with this structure:
|
|
151
|
+
{
|
|
152
|
+
"suggestions": [
|
|
153
|
+
{
|
|
154
|
+
"file": "path/to/file",
|
|
155
|
+
"line": 42,
|
|
156
|
+
"old_or_new": "NEW",
|
|
157
|
+
"type": "bug|improvement|praise|suggestion|design|performance|security|code-style",
|
|
158
|
+
"title": "Brief title",
|
|
159
|
+
"description": "Detailed explanation",
|
|
160
|
+
"suggestion": "How to fix/improve (omit for praise)",
|
|
161
|
+
"confidence": 0.0-1.0
|
|
162
|
+
}
|
|
163
|
+
],
|
|
164
|
+
"fileLevelSuggestions": [{
|
|
165
|
+
"file": "path/to/file",
|
|
166
|
+
"type": "bug|improvement|praise|suggestion|design|performance|security|code-style",
|
|
167
|
+
"title": "Brief title describing file-level concern",
|
|
168
|
+
"description": "Explanation of the file-level observation",
|
|
169
|
+
"suggestion": "How to address the file-level concern (omit for praise items)",
|
|
170
|
+
"confidence": 0.0-1.0
|
|
171
|
+
}],
|
|
172
|
+
"summary": "Brief summary of the key findings and their significance. Write as if a single reviewer produced this analysis — do NOT mention 'consolidation', 'merging', or 'multiple reviewers'."
|
|
173
|
+
}
|
|
174
|
+
</section>
|
|
175
|
+
|
|
176
|
+
<section name="diff-instructions" required="true" tier="thorough">
|
|
177
|
+
## Line Number Reference (old_or_new field)
|
|
178
|
+
The "old_or_new" field indicates which line number column to use:
|
|
179
|
+
- **"NEW"** (default): Use the NEW column number. Correct for added [+] and context lines.
|
|
180
|
+
- **"OLD"**: Use the OLD column number. ONLY for deleted [-] lines.
|
|
181
|
+
|
|
182
|
+
**IMPORTANT**: Context lines exist in BOTH versions — always use "NEW" for them.
|
|
183
|
+
Preserve the old_or_new value from input suggestions when merging.
|
|
184
|
+
</section>
|
|
185
|
+
|
|
186
|
+
<section name="guidelines" required="true" tier="thorough">
|
|
187
|
+
## Important Guidelines
|
|
188
|
+
|
|
189
|
+
### Output Quality
|
|
190
|
+
- **Quality over quantity** — better to have fewer excellent suggestions than many mediocre ones
|
|
191
|
+
- **Cross-reviewer agreement** is strong evidence — boost confidence accordingly
|
|
192
|
+
- **Preserve actionability** — every suggestion should give clear next steps
|
|
193
|
+
- **Maintain context** — don't lose important details when merging
|
|
194
|
+
|
|
195
|
+
### Coverage and Scope
|
|
196
|
+
- **Only include modified files** — discard suggestions for files not in this changeset
|
|
197
|
+
- **Balance across files** — ensure important issues in all modified files are represented
|
|
198
|
+
- **Preserve unique perspectives** — different reviewer models may catch different things
|
|
199
|
+
|
|
200
|
+
### Review Philosophy
|
|
201
|
+
- Frame suggestions as considerations, not mandates
|
|
202
|
+
- The human reviewer has context you don't have
|
|
203
|
+
- Focus on the code, not the reviewers
|
|
204
|
+
- When uncertain, prefer quality over quantity
|
|
205
|
+
</section>`;
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Section definitions with metadata
|
|
209
|
+
* Used for parsing and validation
|
|
210
|
+
*/
|
|
211
|
+
const sections = [
|
|
212
|
+
{ name: 'role', required: true, tier: ['thorough'] },
|
|
213
|
+
{ name: 'task-header', required: true, tier: ['thorough'] },
|
|
214
|
+
{ name: 'line-number-guidance', required: true },
|
|
215
|
+
{ name: 'critical-output', locked: true },
|
|
216
|
+
{ name: 'role-description', required: true, tier: ['thorough'] },
|
|
217
|
+
{ name: 'reasoning-encouragement', required: true, tier: ['thorough'] },
|
|
218
|
+
{ name: 'custom-instructions', optional: true, tier: ['balanced', 'thorough'] },
|
|
219
|
+
{ name: 'input-suggestions', locked: true },
|
|
220
|
+
{ name: 'consolidation-rules', required: true, tier: ['thorough'] },
|
|
221
|
+
{ name: 'consensus-handling', required: true, tier: ['thorough'] },
|
|
222
|
+
{ name: 'summary-synthesis', required: true, tier: ['thorough'] },
|
|
223
|
+
{ name: 'output-schema', locked: true },
|
|
224
|
+
{ name: 'diff-instructions', required: true, tier: ['thorough'] },
|
|
225
|
+
{ name: 'guidelines', required: true, tier: ['thorough'] }
|
|
226
|
+
];
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Default section order for Consolidation Thorough
|
|
230
|
+
*/
|
|
231
|
+
const defaultOrder = [
|
|
232
|
+
'role',
|
|
233
|
+
'task-header',
|
|
234
|
+
'line-number-guidance',
|
|
235
|
+
'critical-output',
|
|
236
|
+
'role-description',
|
|
237
|
+
'reasoning-encouragement',
|
|
238
|
+
'custom-instructions',
|
|
239
|
+
'input-suggestions',
|
|
240
|
+
'consolidation-rules',
|
|
241
|
+
'consensus-handling',
|
|
242
|
+
'summary-synthesis',
|
|
243
|
+
'output-schema',
|
|
244
|
+
'diff-instructions',
|
|
245
|
+
'guidelines'
|
|
246
|
+
];
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Parse the tagged prompt into section objects
|
|
250
|
+
* @returns {Array<Object>} Array of section objects with name, attributes, and content
|
|
251
|
+
*/
|
|
252
|
+
function parseSections() {
|
|
253
|
+
const sectionRegex = /<section\s+name="([^"]+)"([^>]*)>([\s\S]*?)<\/section>/g;
|
|
254
|
+
const parsed = [];
|
|
255
|
+
let match;
|
|
256
|
+
|
|
257
|
+
while ((match = sectionRegex.exec(taggedPrompt)) !== null) {
|
|
258
|
+
const [, name, attrs, content] = match;
|
|
259
|
+
const section = {
|
|
260
|
+
name,
|
|
261
|
+
content: content.trim(),
|
|
262
|
+
locked: attrs.includes('locked="true"'),
|
|
263
|
+
required: attrs.includes('required="true"'),
|
|
264
|
+
optional: attrs.includes('optional="true"')
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
const tierMatch = attrs.match(/tier="([^"]+)"/);
|
|
268
|
+
if (tierMatch) {
|
|
269
|
+
section.tier = tierMatch[1].split(',').map(t => t.trim());
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
parsed.push(section);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
return parsed;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
module.exports = {
|
|
279
|
+
taggedPrompt,
|
|
280
|
+
sections,
|
|
281
|
+
defaultOrder,
|
|
282
|
+
parseSections
|
|
283
|
+
};
|
package/src/ai/prompts/config.js
CHANGED
|
@@ -24,7 +24,7 @@ const TIERS = ['fast', 'balanced', 'thorough'];
|
|
|
24
24
|
/**
|
|
25
25
|
* Prompt types (analysis levels)
|
|
26
26
|
*/
|
|
27
|
-
const PROMPT_TYPES = ['level1', 'level2', 'level3', 'orchestration'];
|
|
27
|
+
const PROMPT_TYPES = ['level1', 'level2', 'level3', 'orchestration', 'consolidation'];
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
30
|
* Resolve a user-friendly tier alias to internal tier
|
package/src/ai/prompts/index.js
CHANGED
|
@@ -25,10 +25,13 @@ let level3Thorough = null;
|
|
|
25
25
|
let orchestrationBalanced = null;
|
|
26
26
|
let orchestrationFast = null;
|
|
27
27
|
let orchestrationThorough = null;
|
|
28
|
+
let consolidationFast = null;
|
|
29
|
+
let consolidationBalanced = null;
|
|
30
|
+
let consolidationThorough = null;
|
|
28
31
|
|
|
29
32
|
/**
|
|
30
33
|
* Load a baseline prompt module
|
|
31
|
-
* @param {string} promptType - Prompt type (level1, level2, level3, orchestration)
|
|
34
|
+
* @param {string} promptType - Prompt type (level1, level2, level3, orchestration, consolidation)
|
|
32
35
|
* @param {string} tier - Capability tier (fast, balanced, thorough)
|
|
33
36
|
* @returns {Object|null} Baseline module or null if not found
|
|
34
37
|
*/
|
|
@@ -117,6 +120,27 @@ function loadBaseline(promptType, tier) {
|
|
|
117
120
|
}
|
|
118
121
|
return orchestrationThorough;
|
|
119
122
|
}
|
|
123
|
+
// Consolidation Fast
|
|
124
|
+
if (promptType === 'consolidation' && tier === 'fast') {
|
|
125
|
+
if (!consolidationFast) {
|
|
126
|
+
consolidationFast = require('./baseline/consolidation/fast');
|
|
127
|
+
}
|
|
128
|
+
return consolidationFast;
|
|
129
|
+
}
|
|
130
|
+
// Consolidation Balanced
|
|
131
|
+
if (promptType === 'consolidation' && tier === 'balanced') {
|
|
132
|
+
if (!consolidationBalanced) {
|
|
133
|
+
consolidationBalanced = require('./baseline/consolidation/balanced');
|
|
134
|
+
}
|
|
135
|
+
return consolidationBalanced;
|
|
136
|
+
}
|
|
137
|
+
// Consolidation Thorough
|
|
138
|
+
if (promptType === 'consolidation' && tier === 'thorough') {
|
|
139
|
+
if (!consolidationThorough) {
|
|
140
|
+
consolidationThorough = require('./baseline/consolidation/thorough');
|
|
141
|
+
}
|
|
142
|
+
return consolidationThorough;
|
|
143
|
+
}
|
|
120
144
|
return null;
|
|
121
145
|
}
|
|
122
146
|
|
|
@@ -168,7 +192,7 @@ function stripSectionTags(taggedPrompt) {
|
|
|
168
192
|
/**
|
|
169
193
|
* Create a prompt builder for a specific prompt type and tier
|
|
170
194
|
*
|
|
171
|
-
* @param {string} promptType - Prompt type (level1, level2, level3, orchestration)
|
|
195
|
+
* @param {string} promptType - Prompt type (level1, level2, level3, orchestration, consolidation)
|
|
172
196
|
* @param {string} tier - Capability tier (fast, balanced, thorough) or alias
|
|
173
197
|
* @param {string} provider - Provider ID (default: 'claude')
|
|
174
198
|
* @returns {Object|null} Prompt builder object or null if not available
|
package/src/ai/provider.js
CHANGED
|
@@ -99,6 +99,8 @@ class AIProvider {
|
|
|
99
99
|
* Called with normalized events: { type: 'assistant_text'|'tool_use', text: string, timestamp: number }.
|
|
100
100
|
* Providers that support streaming (Claude, Codex) will call this as data arrives.
|
|
101
101
|
* Providers without streaming support silently ignore this option.
|
|
102
|
+
* @param {string} [options.logPrefix] - Custom log prefix to use instead of `[Level N]`.
|
|
103
|
+
* Used by council mode to disambiguate concurrent reviewers (e.g., `[L1 R1]`).
|
|
102
104
|
* @returns {Promise<Object>} Parsed JSON response or { raw, parsed: false }
|
|
103
105
|
*/
|
|
104
106
|
async execute(prompt, options = {}) {
|
|
@@ -195,8 +197,8 @@ class AIProvider {
|
|
|
195
197
|
* @returns {Promise<{success: boolean, data?: Object, error?: string}>}
|
|
196
198
|
*/
|
|
197
199
|
async extractJSONWithLLM(rawResponse, options = {}) {
|
|
198
|
-
const { level = 'extraction', analysisId, registerProcess } = options;
|
|
199
|
-
const levelPrefix = `[Level ${level}]`;
|
|
200
|
+
const { level = 'extraction', analysisId, registerProcess, logPrefix } = options;
|
|
201
|
+
const levelPrefix = logPrefix || `[Level ${level}]`;
|
|
200
202
|
|
|
201
203
|
// Get the fast-tier model, with fallback to analysis model
|
|
202
204
|
const extractionModel = this.getFastTierModel();
|