ghagga-core 2.4.1 → 2.6.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/README.md +1 -1
- package/dist/agents/consensus.d.ts +16 -0
- package/dist/agents/consensus.d.ts.map +1 -1
- package/dist/agents/consensus.js +57 -33
- package/dist/agents/consensus.js.map +1 -1
- package/dist/agents/diagnostic.d.ts +55 -0
- package/dist/agents/diagnostic.d.ts.map +1 -0
- package/dist/agents/diagnostic.js +143 -0
- package/dist/agents/diagnostic.js.map +1 -0
- package/dist/agents/prompts.d.ts +6 -4
- package/dist/agents/prompts.d.ts.map +1 -1
- package/dist/agents/prompts.js +110 -24
- package/dist/agents/prompts.js.map +1 -1
- package/dist/agents/simple.d.ts +7 -0
- package/dist/agents/simple.d.ts.map +1 -1
- package/dist/agents/simple.js +32 -18
- package/dist/agents/simple.js.map +1 -1
- package/dist/agents/workflow.d.ts +28 -1
- package/dist/agents/workflow.d.ts.map +1 -1
- package/dist/agents/workflow.js +112 -45
- package/dist/agents/workflow.js.map +1 -1
- package/dist/enhance/enhance.d.ts +31 -0
- package/dist/enhance/enhance.d.ts.map +1 -0
- package/dist/enhance/enhance.js +152 -0
- package/dist/enhance/enhance.js.map +1 -0
- package/dist/enhance/index.d.ts +5 -0
- package/dist/enhance/index.d.ts.map +1 -0
- package/dist/enhance/index.js +3 -0
- package/dist/enhance/index.js.map +1 -0
- package/dist/enhance/prompt.d.ts +22 -0
- package/dist/enhance/prompt.d.ts.map +1 -0
- package/dist/enhance/prompt.js +71 -0
- package/dist/enhance/prompt.js.map +1 -0
- package/dist/enhance/types.d.ts +55 -0
- package/dist/enhance/types.d.ts.map +1 -0
- package/dist/enhance/types.js +6 -0
- package/dist/enhance/types.js.map +1 -0
- package/dist/format.d.ts +47 -1
- package/dist/format.d.ts.map +1 -1
- package/dist/format.js +175 -3
- package/dist/format.js.map +1 -1
- package/dist/graph/blast-radius.d.ts +57 -0
- package/dist/graph/blast-radius.d.ts.map +1 -0
- package/dist/graph/blast-radius.js +145 -0
- package/dist/graph/blast-radius.js.map +1 -0
- package/dist/graph/builder.d.ts +50 -0
- package/dist/graph/builder.d.ts.map +1 -0
- package/dist/graph/builder.js +210 -0
- package/dist/graph/builder.js.map +1 -0
- package/dist/graph/extractors/go.d.ts +9 -0
- package/dist/graph/extractors/go.d.ts.map +1 -0
- package/dist/graph/extractors/go.js +78 -0
- package/dist/graph/extractors/go.js.map +1 -0
- package/dist/graph/extractors/index.d.ts +22 -0
- package/dist/graph/extractors/index.d.ts.map +1 -0
- package/dist/graph/extractors/index.js +37 -0
- package/dist/graph/extractors/index.js.map +1 -0
- package/dist/graph/extractors/java.d.ts +9 -0
- package/dist/graph/extractors/java.d.ts.map +1 -0
- package/dist/graph/extractors/java.js +80 -0
- package/dist/graph/extractors/java.js.map +1 -0
- package/dist/graph/extractors/javascript.d.ts +9 -0
- package/dist/graph/extractors/javascript.d.ts.map +1 -0
- package/dist/graph/extractors/javascript.js +204 -0
- package/dist/graph/extractors/javascript.js.map +1 -0
- package/dist/graph/extractors/python.d.ts +9 -0
- package/dist/graph/extractors/python.d.ts.map +1 -0
- package/dist/graph/extractors/python.js +103 -0
- package/dist/graph/extractors/python.js.map +1 -0
- package/dist/graph/extractors/rust.d.ts +9 -0
- package/dist/graph/extractors/rust.d.ts.map +1 -0
- package/dist/graph/extractors/rust.js +115 -0
- package/dist/graph/extractors/rust.js.map +1 -0
- package/dist/graph/extractors/types.d.ts +31 -0
- package/dist/graph/extractors/types.d.ts.map +1 -0
- package/dist/graph/extractors/types.js +9 -0
- package/dist/graph/extractors/types.js.map +1 -0
- package/dist/graph/extractors/typescript.d.ts +9 -0
- package/dist/graph/extractors/typescript.d.ts.map +1 -0
- package/dist/graph/extractors/typescript.js +151 -0
- package/dist/graph/extractors/typescript.js.map +1 -0
- package/dist/graph/index.d.ts +15 -0
- package/dist/graph/index.d.ts.map +1 -0
- package/dist/graph/index.js +14 -0
- package/dist/graph/index.js.map +1 -0
- package/dist/graph/loader.d.ts +43 -0
- package/dist/graph/loader.d.ts.map +1 -0
- package/dist/graph/loader.js +104 -0
- package/dist/graph/loader.js.map +1 -0
- package/dist/graph/schema.d.ts +113 -0
- package/dist/graph/schema.d.ts.map +1 -0
- package/dist/graph/schema.js +144 -0
- package/dist/graph/schema.js.map +1 -0
- package/dist/health/index.d.ts +4 -0
- package/dist/health/index.d.ts.map +1 -0
- package/dist/health/index.js +4 -0
- package/dist/health/index.js.map +1 -0
- package/dist/health/recommendations.d.ts +17 -0
- package/dist/health/recommendations.d.ts.map +1 -0
- package/dist/health/recommendations.js +81 -0
- package/dist/health/recommendations.js.map +1 -0
- package/dist/health/score.d.ts +32 -0
- package/dist/health/score.d.ts.map +1 -0
- package/dist/health/score.js +73 -0
- package/dist/health/score.js.map +1 -0
- package/dist/health/trends.d.ts +31 -0
- package/dist/health/trends.d.ts.map +1 -0
- package/dist/health/trends.js +88 -0
- package/dist/health/trends.js.map +1 -0
- package/dist/index.d.ts +26 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -4
- package/dist/index.js.map +1 -1
- package/dist/memory/sqlite.js +4 -4
- package/dist/memory/sqlite.js.map +1 -1
- package/dist/pipeline.d.ts.map +1 -1
- package/dist/pipeline.js +332 -42
- package/dist/pipeline.js.map +1 -1
- package/dist/providers/cli-bridge.d.ts +136 -0
- package/dist/providers/cli-bridge.d.ts.map +1 -0
- package/dist/providers/cli-bridge.js +457 -0
- package/dist/providers/cli-bridge.js.map +1 -0
- package/dist/providers/fallback.d.ts +8 -0
- package/dist/providers/fallback.d.ts.map +1 -1
- package/dist/providers/fallback.js +24 -8
- package/dist/providers/fallback.js.map +1 -1
- package/dist/providers/gateway.d.ts +40 -0
- package/dist/providers/gateway.d.ts.map +1 -0
- package/dist/providers/gateway.js +52 -0
- package/dist/providers/gateway.js.map +1 -0
- package/dist/providers/generate-fn.d.ts +62 -0
- package/dist/providers/generate-fn.d.ts.map +1 -0
- package/dist/providers/generate-fn.js +84 -0
- package/dist/providers/generate-fn.js.map +1 -0
- package/dist/providers/index.d.ts +5 -0
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +53 -0
- package/dist/providers/index.js.map +1 -1
- package/dist/sarif/builder.d.ts +17 -0
- package/dist/sarif/builder.d.ts.map +1 -0
- package/dist/sarif/builder.js +88 -0
- package/dist/sarif/builder.js.map +1 -0
- package/dist/sarif/index.d.ts +3 -0
- package/dist/sarif/index.d.ts.map +1 -0
- package/dist/sarif/index.js +2 -0
- package/dist/sarif/index.js.map +1 -0
- package/dist/sarif/types.d.ts +52 -0
- package/dist/sarif/types.d.ts.map +1 -0
- package/dist/sarif/types.js +8 -0
- package/dist/sarif/types.js.map +1 -0
- package/dist/tools/index.d.ts +1 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +2 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/plugins/index.d.ts +2 -0
- package/dist/tools/plugins/index.d.ts.map +1 -1
- package/dist/tools/plugins/index.js +7 -0
- package/dist/tools/plugins/index.js.map +1 -1
- package/dist/tools/plugins/zizmor.d.ts +22 -0
- package/dist/tools/plugins/zizmor.d.ts.map +1 -0
- package/dist/tools/plugins/zizmor.js +112 -0
- package/dist/tools/plugins/zizmor.js.map +1 -0
- package/dist/tools/resolve.js +1 -1
- package/dist/tools/resolve.js.map +1 -1
- package/dist/tools/runner.d.ts +7 -14
- package/dist/tools/runner.d.ts.map +1 -1
- package/dist/tools/runner.js +10 -60
- package/dist/tools/runner.js.map +1 -1
- package/dist/tools/types.d.ts +1 -1
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/types.d.ts +68 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +21 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/concurrency.d.ts +29 -0
- package/dist/utils/concurrency.d.ts.map +1 -0
- package/dist/utils/concurrency.js +40 -0
- package/dist/utils/concurrency.js.map +1 -0
- package/dist/utils/context-levels.d.ts +113 -0
- package/dist/utils/context-levels.d.ts.map +1 -0
- package/dist/utils/context-levels.js +255 -0
- package/dist/utils/context-levels.js.map +1 -0
- package/dist/utils/diff.d.ts +25 -0
- package/dist/utils/diff.d.ts.map +1 -1
- package/dist/utils/diff.js +28 -0
- package/dist/utils/diff.js.map +1 -1
- package/dist/utils/llm-timeout.d.ts +38 -0
- package/dist/utils/llm-timeout.d.ts.map +1 -0
- package/dist/utils/llm-timeout.js +76 -0
- package/dist/utils/llm-timeout.js.map +1 -0
- package/dist/utils/path-protection.d.ts +59 -0
- package/dist/utils/path-protection.d.ts.map +1 -0
- package/dist/utils/path-protection.js +136 -0
- package/dist/utils/path-protection.js.map +1 -0
- package/dist/utils/token-budget.d.ts +34 -1
- package/dist/utils/token-budget.d.ts.map +1 -1
- package/dist/utils/token-budget.js +108 -3
- package/dist/utils/token-budget.js.map +1 -1
- package/package.json +21 -19
- package/LICENSE +0 -21
package/dist/agents/prompts.js
CHANGED
|
@@ -3,13 +3,37 @@
|
|
|
3
3
|
* Rescued and refined from GHAGGA v1.
|
|
4
4
|
*/
|
|
5
5
|
// ─── Simple Review ──────────────────────────────────────────────
|
|
6
|
-
export const SIMPLE_REVIEW_SYSTEM = `You are an expert code reviewer. Analyze the provided code changes
|
|
6
|
+
export const SIMPLE_REVIEW_SYSTEM = `You are an expert code reviewer performing a multi-perspective analysis in a single pass. Analyze the provided code changes from ALL 5 specialist perspectives below.
|
|
7
7
|
|
|
8
|
-
1.
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
## 1. Security Audit
|
|
9
|
+
- SQL injection, XSS, CSRF vulnerabilities
|
|
10
|
+
- Authentication/authorization flaws
|
|
11
|
+
- Sensitive data exposure (API keys, tokens, PII in logs)
|
|
12
|
+
- Insecure dependencies or patterns
|
|
13
|
+
|
|
14
|
+
## 2. Bugs & Error Handling
|
|
15
|
+
- Null/undefined safety — unchecked access, missing optional chaining
|
|
16
|
+
- Logic errors, off-by-one bugs, incorrect conditions
|
|
17
|
+
- Missing edge cases and boundary conditions
|
|
18
|
+
- Try/catch correctness, error propagation, error message quality
|
|
19
|
+
- Input validation gaps
|
|
20
|
+
|
|
21
|
+
## 3. Performance
|
|
22
|
+
- Algorithm complexity (O(n²) loops, unnecessary iterations)
|
|
23
|
+
- N+1 query patterns, missing indexes, excessive DB calls
|
|
24
|
+
- Memory leaks (unclosed resources, growing collections, missing cleanup)
|
|
25
|
+
- Unnecessary computations or re-renders
|
|
26
|
+
|
|
27
|
+
## 4. Code Quality & Maintainability
|
|
28
|
+
- Naming conventions (variables, functions, types)
|
|
29
|
+
- DRY violations (duplicated logic that should be extracted)
|
|
30
|
+
- Code readability, proper documentation for complex logic
|
|
31
|
+
- Import organization and module structure
|
|
32
|
+
|
|
33
|
+
## 5. Scope & Impact
|
|
34
|
+
- Which modules/components are affected by the changes
|
|
35
|
+
- Potential side effects on untouched code paths
|
|
36
|
+
- Breaking changes to public APIs or contracts
|
|
13
37
|
|
|
14
38
|
Format your response EXACTLY as:
|
|
15
39
|
|
|
@@ -24,6 +48,8 @@ FINDINGS:
|
|
|
24
48
|
SUGGESTION: [specific fix or improvement]
|
|
25
49
|
|
|
26
50
|
If there are no issues, return STATUS: PASSED with an empty FINDINGS section.
|
|
51
|
+
Scale your review depth to the diff size: small changes need brief reviews, large changes need thorough analysis.
|
|
52
|
+
Only report ACTIONABLE findings — skip nitpicks and formatting preferences.
|
|
27
53
|
FAILED if: Any critical issues, or 3+ high issues. PASSED otherwise.`;
|
|
28
54
|
// ─── Workflow Specialists ───────────────────────────────────────
|
|
29
55
|
export const WORKFLOW_SCOPE_SYSTEM = `You analyze code scope. Identify what files are changed, affected modules, and dependencies.
|
|
@@ -124,41 +150,101 @@ FINDINGS:
|
|
|
124
150
|
FAILED if: Any critical issues, or more than 3 high issues.
|
|
125
151
|
PASSED if: No critical issues and 3 or fewer high issues.`;
|
|
126
152
|
// ─── Consensus Stances ──────────────────────────────────────────
|
|
127
|
-
export const CONSENSUS_FOR_SYSTEM = `You are reviewing code changes. Argue
|
|
153
|
+
export const CONSENSUS_FOR_SYSTEM = `You are reviewing code changes. Argue IN FAVOR of approving this code.
|
|
154
|
+
|
|
155
|
+
Focus on: benefits, problems solved correctly, good practices followed.
|
|
128
156
|
|
|
129
|
-
|
|
130
|
-
-
|
|
131
|
-
-
|
|
132
|
-
-
|
|
133
|
-
- Good practices followed
|
|
157
|
+
IMPORTANT: Scale your response to the diff size.
|
|
158
|
+
- Small diffs (< 50 lines): 2-3 sentences max
|
|
159
|
+
- Medium diffs (50-200 lines): 1 short paragraph
|
|
160
|
+
- Large diffs (200+ lines): 2-3 short paragraphs max
|
|
134
161
|
|
|
135
162
|
Provide your assessment as:
|
|
136
163
|
DECISION: [approve|reject|abstain]
|
|
137
164
|
CONFIDENCE: [0.0 to 1.0]
|
|
138
|
-
REASONING: [
|
|
165
|
+
REASONING: [concise reasoning — be brief and direct]`;
|
|
139
166
|
export const CONSENSUS_AGAINST_SYSTEM = `You are reviewing code changes. Argue AGAINST approving this code.
|
|
140
167
|
|
|
141
|
-
Focus on:
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
-
|
|
145
|
-
-
|
|
146
|
-
-
|
|
168
|
+
Focus on: potential bugs, security vulnerabilities, performance concerns, missing tests.
|
|
169
|
+
|
|
170
|
+
IMPORTANT: Scale your response to the diff size.
|
|
171
|
+
- Small diffs (< 50 lines): 2-3 sentences max
|
|
172
|
+
- Medium diffs (50-200 lines): 1 short paragraph
|
|
173
|
+
- Large diffs (200+ lines): 2-3 short paragraphs max
|
|
174
|
+
|
|
175
|
+
Only flag real, concrete issues — do not speculate about hypothetical problems.
|
|
147
176
|
|
|
148
177
|
Provide your assessment as:
|
|
149
178
|
DECISION: [approve|reject|abstain]
|
|
150
179
|
CONFIDENCE: [0.0 to 1.0]
|
|
151
|
-
REASONING: [
|
|
180
|
+
REASONING: [concise reasoning — be brief and direct]`;
|
|
152
181
|
export const CONSENSUS_NEUTRAL_SYSTEM = `You are reviewing code changes. Provide a BALANCED, neutral analysis.
|
|
153
182
|
|
|
154
|
-
Consider both
|
|
155
|
-
|
|
156
|
-
|
|
183
|
+
Consider both benefits and risks. Weigh trade-offs pragmatically.
|
|
184
|
+
|
|
185
|
+
IMPORTANT: Scale your response to the diff size.
|
|
186
|
+
- Small diffs (< 50 lines): 2-3 sentences max
|
|
187
|
+
- Medium diffs (50-200 lines): 1 short paragraph
|
|
188
|
+
- Large diffs (200+ lines): 2-3 short paragraphs max
|
|
157
189
|
|
|
158
190
|
Provide your assessment as:
|
|
159
191
|
DECISION: [approve|reject|abstain]
|
|
160
192
|
CONFIDENCE: [0.0 to 1.0]
|
|
161
|
-
REASONING: [
|
|
193
|
+
REASONING: [concise reasoning — be brief and direct]`;
|
|
194
|
+
// ─── Diagnostic Review ─────────────────────────────────────────
|
|
195
|
+
export const DIAGNOSTIC_SYSTEM = `You are an expert software detective performing a hypothesis-driven diagnostic analysis of code changes. Instead of just reporting issues, you generate testable hypotheses about potential bugs and explain how to verify each one.
|
|
196
|
+
|
|
197
|
+
## Your Approach
|
|
198
|
+
1. Analyze the diff like a detective investigating potential bugs
|
|
199
|
+
2. Generate 1-5 hypotheses ranked by severity and confidence
|
|
200
|
+
3. For each hypothesis, explain the conditions that would trigger it and how to verify
|
|
201
|
+
4. Only generate hypotheses you have real evidence for from the diff — do not speculate wildly
|
|
202
|
+
|
|
203
|
+
## Hypothesis Format
|
|
204
|
+
For each potential issue, output a hypothesis block in this EXACT format:
|
|
205
|
+
|
|
206
|
+
HYPOTHESIS H1: [short title describing what might be wrong]
|
|
207
|
+
CONDITIONS: [when/why this would fail — be specific about inputs, states, or sequences]
|
|
208
|
+
VERIFICATION: [concrete steps to test — a specific test case, reproduction steps, or command to run]
|
|
209
|
+
CONFIDENCE: [high|medium|low]
|
|
210
|
+
FILES: [comma-separated list of relevant file paths]
|
|
211
|
+
|
|
212
|
+
## Confidence Levels
|
|
213
|
+
- **high**: Clear evidence in the diff — the bug pattern is well-known and conditions are visible
|
|
214
|
+
- **medium**: Likely issue based on the code pattern, but depends on runtime context not visible in the diff
|
|
215
|
+
- **low**: Possible issue that requires further investigation — the pattern is suspicious but not conclusive
|
|
216
|
+
|
|
217
|
+
## Response Format
|
|
218
|
+
Your response MUST follow this exact structure:
|
|
219
|
+
|
|
220
|
+
STATUS: [PASSED or NEEDS_HUMAN_REVIEW]
|
|
221
|
+
SUMMARY: [2-3 sentence summary of the diagnostic analysis]
|
|
222
|
+
|
|
223
|
+
[hypothesis blocks — 0 to 5 of them]
|
|
224
|
+
|
|
225
|
+
FINDINGS:
|
|
226
|
+
- SEVERITY: [critical|high|medium|low|info]
|
|
227
|
+
CATEGORY: [security|performance|bug|style|error-handling|maintainability]
|
|
228
|
+
FILE: [file path]
|
|
229
|
+
LINE: [line number or "N/A"]
|
|
230
|
+
MESSAGE: [H<n>: description linking to the hypothesis]
|
|
231
|
+
SUGGESTION: [verification step from the hypothesis]
|
|
232
|
+
|
|
233
|
+
## Rules
|
|
234
|
+
- STATUS is PASSED only when you find zero hypotheses (the code looks clean)
|
|
235
|
+
- STATUS is NEEDS_HUMAN_REVIEW when you have 1+ hypotheses
|
|
236
|
+
- Each hypothesis MUST have a corresponding FINDING entry
|
|
237
|
+
- In FINDINGS, prefix the MESSAGE with the hypothesis ID (e.g., "H1: ...")
|
|
238
|
+
- Map hypothesis confidence to finding severity: high→high, medium→medium, low→low
|
|
239
|
+
- Scale analysis depth to diff size: small diffs get 1-2 hypotheses max, large diffs can have up to 5
|
|
240
|
+
- Only report hypotheses you are 70%+ confident about based on the actual code shown`;
|
|
241
|
+
// ─── Compact Calibration (for non-primary specialist calls) ─────
|
|
242
|
+
//
|
|
243
|
+
// When running workflow/consensus with concurrency batching, only the
|
|
244
|
+
// first call in each batch gets the full context (staticContext,
|
|
245
|
+
// memoryContext, stackHints, REVIEW_CALIBRATION). Subsequent calls
|
|
246
|
+
// get this minimal version to save ~750 tokens per call.
|
|
247
|
+
export const COMPACT_CALIBRATION = `Focus only on your specialty area. Be concise. Report only actionable findings you are 80%+ confident about. Do not speculate.`;
|
|
162
248
|
// ─── Review Calibration ─────────────────────────────────────────
|
|
163
249
|
export const REVIEW_CALIBRATION = `## Review Calibration
|
|
164
250
|
- Only report findings you are 80%+ confident about based on the actual code shown.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/agents/prompts.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,mEAAmE;AAEnE,MAAM,CAAC,MAAM,oBAAoB,GAAG
|
|
1
|
+
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/agents/prompts.ts"],"names":[],"mappings":"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"}
|
package/dist/agents/simple.d.ts
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* Best for small-to-medium PRs where parallel specialists
|
|
6
6
|
* would be overkill.
|
|
7
7
|
*/
|
|
8
|
+
import { type GenerateTextFn } from '../providers/generate-fn.js';
|
|
8
9
|
import type { LLMProvider, ProgressCallback, ReviewFinding, ReviewLevel, ReviewResult } from '../types.js';
|
|
9
10
|
export interface SimpleReviewInput {
|
|
10
11
|
diff: string;
|
|
@@ -16,6 +17,12 @@ export interface SimpleReviewInput {
|
|
|
16
17
|
stackHints: string;
|
|
17
18
|
reviewLevel: ReviewLevel;
|
|
18
19
|
onProgress?: ProgressCallback;
|
|
20
|
+
/**
|
|
21
|
+
* Optional backend-agnostic generation function.
|
|
22
|
+
* When provided, used instead of createModel + generateTextWithTimeout.
|
|
23
|
+
* When omitted, one is created internally from provider/model/apiKey (backward compat).
|
|
24
|
+
*/
|
|
25
|
+
generateFn?: GenerateTextFn;
|
|
19
26
|
}
|
|
20
27
|
/**
|
|
21
28
|
* Parse the structured LLM response into a ReviewResult.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"simple.d.ts","sourceRoot":"","sources":["../../src/agents/simple.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"simple.d.ts","sourceRoot":"","sources":["../../src/agents/simple.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAyB,KAAK,cAAc,EAAE,MAAM,6BAA6B,CAAC;AACzF,OAAO,KAAK,EAGV,WAAW,EACX,gBAAgB,EAChB,aAAa,EACb,WAAW,EACX,YAAY,EAEb,MAAM,aAAa,CAAC;AAUrB,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,WAAW,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,WAAW,CAAC;IACzB,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAE9B;;;;OAIG;IACH,UAAU,CAAC,EAAE,cAAc,CAAC;CAC7B;AAOD;;;;;GAKG;AACH,iBAAS,mBAAmB,CAC1B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,WAAW,EACrB,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,MAAM,EAClB,eAAe,EAAE,MAAM,EACvB,aAAa,EAAE,MAAM,GAAG,IAAI,GAC3B,YAAY,CAyCd;AAED;;;;;;;;;;GAUG;AACH,iBAAS,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,EAAE,CA4BzD;AAID;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,YAAY,CAAC,CAkErF;AAGD,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,CAAC"}
|
package/dist/agents/simple.js
CHANGED
|
@@ -5,8 +5,7 @@
|
|
|
5
5
|
* Best for small-to-medium PRs where parallel specialists
|
|
6
6
|
* would be overkill.
|
|
7
7
|
*/
|
|
8
|
-
import {
|
|
9
|
-
import { createModel } from '../providers/index.js';
|
|
8
|
+
import { createAISDKGenerateFn } from '../providers/generate-fn.js';
|
|
10
9
|
import { buildMemoryContext, buildReviewLevelInstruction, REVIEW_CALIBRATION, SIMPLE_REVIEW_SYSTEM, } from './prompts.js';
|
|
11
10
|
// ─── Response Parsing ───────────────────────────────────────────
|
|
12
11
|
/** Valid severity values for type-safe parsing */
|
|
@@ -21,9 +20,18 @@ function parseReviewResponse(text, provider, model, tokensUsed, executionTimeMs,
|
|
|
21
20
|
// Extract STATUS
|
|
22
21
|
const statusMatch = /STATUS:\s*(PASSED|FAILED|NEEDS_HUMAN_REVIEW|SKIPPED)/i.exec(text);
|
|
23
22
|
const status = statusMatch?.[1]?.toUpperCase() ?? 'NEEDS_HUMAN_REVIEW';
|
|
24
|
-
// Extract SUMMARY
|
|
23
|
+
// Extract SUMMARY — fall back to raw text if structured format is not found
|
|
25
24
|
const summaryMatch = /SUMMARY:\s*(.+?)(?:\n(?:FINDINGS:|$))/is.exec(text);
|
|
26
|
-
|
|
25
|
+
let summary;
|
|
26
|
+
if (summaryMatch?.[1]?.trim()) {
|
|
27
|
+
summary = summaryMatch[1].trim();
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
// CLI providers (e.g., copilot) may return raw text without SUMMARY: markers.
|
|
31
|
+
// Use the raw text (minus any FINDINGS block) as the summary instead of a generic error.
|
|
32
|
+
const withoutFindings = text.replace(/FINDINGS:[\s\S]*$/i, '').trim();
|
|
33
|
+
summary = withoutFindings || 'Review completed but summary could not be parsed.';
|
|
34
|
+
}
|
|
27
35
|
// Extract FINDINGS
|
|
28
36
|
const findings = parseFindingsBlock(text);
|
|
29
37
|
return {
|
|
@@ -94,6 +102,8 @@ function parseFindingsBlock(text) {
|
|
|
94
102
|
export async function runSimpleReview(input) {
|
|
95
103
|
const { diff, provider, model, apiKey, staticContext, memoryContext, stackHints, reviewLevel } = input;
|
|
96
104
|
const emit = input.onProgress ?? (() => { });
|
|
105
|
+
// Resolve the generation function: use injected or create from provider/model/apiKey
|
|
106
|
+
const generateFn = input.generateFn ?? createAISDKGenerateFn(provider, model, apiKey);
|
|
97
107
|
const startTime = Date.now();
|
|
98
108
|
// Build the full system prompt with all context layers
|
|
99
109
|
const system = [
|
|
@@ -108,24 +118,28 @@ export async function runSimpleReview(input) {
|
|
|
108
118
|
.join('\n');
|
|
109
119
|
// Build the user prompt with the diff
|
|
110
120
|
const prompt = `Please review the following code changes:\n\n\`\`\`diff\n${diff}\n\`\`\``;
|
|
111
|
-
const languageModel = createModel(provider, model, apiKey);
|
|
112
121
|
emit({
|
|
113
122
|
step: 'simple-call',
|
|
114
123
|
message: `Calling ${provider}/${model} for single-pass review...`,
|
|
115
124
|
});
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
125
|
+
try {
|
|
126
|
+
const result = await generateFn(system, prompt);
|
|
127
|
+
const executionTimeMs = Date.now() - startTime;
|
|
128
|
+
emit({
|
|
129
|
+
step: 'simple-done',
|
|
130
|
+
message: `Review complete — ${result.tokensUsed} tokens, ${(executionTimeMs / 1000).toFixed(1)}s`,
|
|
131
|
+
});
|
|
132
|
+
return parseReviewResponse(result.text, result.provider, result.model, result.tokensUsed, executionTimeMs, memoryContext);
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
const executionTimeMs = Date.now() - startTime;
|
|
136
|
+
// Timeout or other failure: fall back to empty AI result (static analysis still applies)
|
|
137
|
+
emit({
|
|
138
|
+
step: 'simple-done',
|
|
139
|
+
message: `LLM failed — falling back to static-analysis-only results: ${error instanceof Error ? error.message : String(error)}`,
|
|
140
|
+
});
|
|
141
|
+
return parseReviewResponse('STATUS: NEEDS_HUMAN_REVIEW\nSUMMARY: LLM call failed. Only static analysis results are available.\nFINDINGS:\n', provider, model, 0, executionTimeMs, memoryContext);
|
|
142
|
+
}
|
|
129
143
|
}
|
|
130
144
|
// Re-export the parser for use in workflow and consensus modes
|
|
131
145
|
export { parseReviewResponse, parseFindingsBlock };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"simple.js","sourceRoot":"","sources":["../../src/agents/simple.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"simple.js","sourceRoot":"","sources":["../../src/agents/simple.ts"],"names":[],"mappings":"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"}
|
|
@@ -15,7 +15,8 @@
|
|
|
15
15
|
* After all specialists complete, a synthesis step merges and
|
|
16
16
|
* deduplicates findings into the final STATUS/SUMMARY/FINDINGS.
|
|
17
17
|
*/
|
|
18
|
-
import
|
|
18
|
+
import { type GenerateTextFn } from '../providers/generate-fn.js';
|
|
19
|
+
import type { LLMProvider, ProgressCallback, ProviderChainEntry, ReviewLevel, ReviewResult } from '../types.js';
|
|
19
20
|
export interface WorkflowReviewInput {
|
|
20
21
|
diff: string;
|
|
21
22
|
provider: LLMProvider;
|
|
@@ -26,6 +27,32 @@ export interface WorkflowReviewInput {
|
|
|
26
27
|
stackHints: string;
|
|
27
28
|
reviewLevel: ReviewLevel;
|
|
28
29
|
onProgress?: ProgressCallback;
|
|
30
|
+
/**
|
|
31
|
+
* Max specialist agents running concurrently (default: 2).
|
|
32
|
+
* Set to 1 for strict sequential, 5 for full parallel (original behavior).
|
|
33
|
+
* Lower values reduce peak TPM usage for free-tier providers.
|
|
34
|
+
*/
|
|
35
|
+
concurrency?: number;
|
|
36
|
+
/**
|
|
37
|
+
* Delay in ms between concurrency batches (default: 0).
|
|
38
|
+
* Useful for RPM-limited providers (e.g., Gemini free at 20 RPM).
|
|
39
|
+
*/
|
|
40
|
+
delayMs?: number;
|
|
41
|
+
/**
|
|
42
|
+
* Provider chain for distributing specialists across multiple providers.
|
|
43
|
+
* Specialist i uses chain[i % chain.length].
|
|
44
|
+
* When set, takes precedence over the flat provider/model/apiKey fields
|
|
45
|
+
* for individual specialists. Synthesis always uses chain[0] (primary).
|
|
46
|
+
* When undefined or empty, all specialists use the flat fields (backward compat).
|
|
47
|
+
*/
|
|
48
|
+
providerChain?: ProviderChainEntry[];
|
|
49
|
+
/**
|
|
50
|
+
* Backend-agnostic generation functions for specialists (round-robin).
|
|
51
|
+
* When provided, each specialist uses generateFns[index % generateFns.length].
|
|
52
|
+
* Synthesis uses generateFns[0].
|
|
53
|
+
* When omitted, functions are created from providerChain or flat fields (backward compat).
|
|
54
|
+
*/
|
|
55
|
+
generateFns?: GenerateTextFn[];
|
|
29
56
|
}
|
|
30
57
|
/**
|
|
31
58
|
* Run a workflow (multi-specialist) code review.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workflow.d.ts","sourceRoot":"","sources":["../../src/agents/workflow.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;
|
|
1
|
+
{"version":3,"file":"workflow.d.ts","sourceRoot":"","sources":["../../src/agents/workflow.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAyB,KAAK,cAAc,EAAE,MAAM,6BAA6B,CAAC;AACzF,OAAO,KAAK,EACV,WAAW,EACX,gBAAgB,EAChB,kBAAkB,EAClB,WAAW,EACX,YAAY,EAEb,MAAM,aAAa,CAAC;AAmBrB,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,WAAW,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,WAAW,CAAC;IACzB,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAE9B;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAErC;;;;;OAKG;IACH,WAAW,CAAC,EAAE,cAAc,EAAE,CAAC;CAChC;AAyCD;;;;;;;;;GASG;AACH,wBAAsB,iBAAiB,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,YAAY,CAAC,CA+MzF"}
|
package/dist/agents/workflow.js
CHANGED
|
@@ -15,10 +15,18 @@
|
|
|
15
15
|
* After all specialists complete, a synthesis step merges and
|
|
16
16
|
* deduplicates findings into the final STATUS/SUMMARY/FINDINGS.
|
|
17
17
|
*/
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
18
|
+
import { createAISDKGenerateFn } from '../providers/generate-fn.js';
|
|
19
|
+
import { runWithConcurrency } from '../utils/concurrency.js';
|
|
20
|
+
import { calculateRateSchedule } from '../utils/token-budget.js';
|
|
21
|
+
import { buildMemoryContext, buildReviewLevelInstruction, COMPACT_CALIBRATION, REVIEW_CALIBRATION, WORKFLOW_ERRORS_SYSTEM, WORKFLOW_PERFORMANCE_SYSTEM, WORKFLOW_SCOPE_SYSTEM, WORKFLOW_SECURITY_SYSTEM, WORKFLOW_STANDARDS_SYSTEM, WORKFLOW_SYNTHESIS_SYSTEM, } from './prompts.js';
|
|
21
22
|
import { parseReviewResponse } from './simple.js';
|
|
23
|
+
const SPECIALIST_CONTEXT_MAP = {
|
|
24
|
+
'security-audit': ['staticContext'],
|
|
25
|
+
'performance-review': ['stackHints'],
|
|
26
|
+
'scope-analysis': ['memoryContext'],
|
|
27
|
+
'coding-standards': ['stackHints'],
|
|
28
|
+
'error-handling': [],
|
|
29
|
+
};
|
|
22
30
|
// ─── Specialist Configuration ───────────────────────────────────
|
|
23
31
|
const SPECIALISTS = [
|
|
24
32
|
{ name: 'scope-analysis', label: 'Scope Analysis', system: WORKFLOW_SCOPE_SYSTEM },
|
|
@@ -41,44 +49,79 @@ const SPECIALISTS = [
|
|
|
41
49
|
export async function runWorkflowReview(input) {
|
|
42
50
|
const { diff, provider, model, apiKey, staticContext, memoryContext, stackHints, reviewLevel } = input;
|
|
43
51
|
const emit = input.onProgress ?? (() => { });
|
|
52
|
+
// ── Resolve GenerateTextFn array ──────────────────────────
|
|
53
|
+
// When generateFns is provided, use them directly.
|
|
54
|
+
// Otherwise, build them from providerChain or flat provider/model/apiKey.
|
|
55
|
+
const chain = input.providerChain && input.providerChain.length > 0 ? input.providerChain : null;
|
|
56
|
+
const resolvedGenerateFns = input.generateFns ??
|
|
57
|
+
(chain
|
|
58
|
+
? chain.map((entry) => createAISDKGenerateFn(entry.provider, entry.model, entry.apiKey))
|
|
59
|
+
: [createAISDKGenerateFn(provider, model, apiKey)]);
|
|
60
|
+
// Auto-calculate concurrency and delay based on the primary model's TPM.
|
|
61
|
+
// Free-tier models (Groq 8K TPM) → serialize with 60s delays (~5min total).
|
|
62
|
+
// High-capacity models → full parallel (~10s total).
|
|
63
|
+
// For CLI bridge/gateway (single generateFn), force concurrency=1.
|
|
64
|
+
const primaryModel = input.providerChain?.[0]?.model ?? model;
|
|
65
|
+
const rateSchedule = calculateRateSchedule(primaryModel);
|
|
66
|
+
const concurrency = resolvedGenerateFns.length === 1
|
|
67
|
+
? Math.min(input.concurrency ?? rateSchedule.concurrency, 1)
|
|
68
|
+
: (input.concurrency ?? rateSchedule.concurrency);
|
|
69
|
+
const delayMs = input.delayMs ?? rateSchedule.delayMs;
|
|
44
70
|
const startTime = Date.now();
|
|
45
|
-
const languageModel = createModel(provider, model, apiKey);
|
|
46
71
|
emit({
|
|
47
72
|
step: 'workflow-start',
|
|
48
|
-
message: `Launching ${SPECIALISTS.length} specialist reviewers
|
|
73
|
+
message: `Launching ${SPECIALISTS.length} specialist reviewers (concurrency: ${concurrency}, delay: ${Math.round(delayMs / 1000)}s)`,
|
|
49
74
|
detail: SPECIALISTS.map((s) => ` → ${s.label}`).join('\n'),
|
|
50
75
|
});
|
|
51
76
|
// Build the user prompt (same for all specialists)
|
|
52
77
|
const userPrompt = `Review the following code changes:\n\n\`\`\`diff\n${diff}\n\`\`\``;
|
|
53
|
-
//
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
78
|
+
// Context sources keyed for lookup by the specialist context map
|
|
79
|
+
const contextSources = {
|
|
80
|
+
staticContext,
|
|
81
|
+
memoryContext: buildMemoryContext(memoryContext),
|
|
82
|
+
stackHints,
|
|
83
|
+
};
|
|
84
|
+
// ── Step 1: Run specialists with bounded concurrency ───────
|
|
85
|
+
//
|
|
86
|
+
// Each specialist receives only the context relevant to its domain.
|
|
87
|
+
// Specialists with context get REVIEW_CALIBRATION; those without
|
|
88
|
+
// extra context get COMPACT_CALIBRATION.
|
|
89
|
+
//
|
|
90
|
+
// GenerateTextFns are distributed round-robin:
|
|
91
|
+
// specialist 0 → fns[0], specialist 1 → fns[1], ..., n → fns[n % len]
|
|
92
|
+
// This spreads TPM load across providers instead of hammering one.
|
|
93
|
+
const specialistTasks = SPECIALISTS.map((specialist, index) => {
|
|
94
|
+
return async () => {
|
|
95
|
+
// Round-robin assignment of generateFn
|
|
96
|
+
const generateFn = resolvedGenerateFns[index % resolvedGenerateFns.length];
|
|
97
|
+
// Build context: only include what's relevant for this specialist
|
|
98
|
+
const contextKeys = SPECIALIST_CONTEXT_MAP[specialist.name] ?? [];
|
|
99
|
+
const contextParts = contextKeys.map((key) => contextSources[key]).filter(Boolean);
|
|
100
|
+
const hasContext = contextParts.length > 0;
|
|
101
|
+
const system = [
|
|
102
|
+
specialist.system,
|
|
103
|
+
...contextParts,
|
|
104
|
+
buildReviewLevelInstruction(reviewLevel),
|
|
105
|
+
hasContext ? REVIEW_CALIBRATION : COMPACT_CALIBRATION,
|
|
106
|
+
]
|
|
107
|
+
.filter(Boolean)
|
|
108
|
+
.join('\n');
|
|
109
|
+
const result = await generateFn(system, userPrompt);
|
|
110
|
+
return {
|
|
111
|
+
name: specialist.name,
|
|
112
|
+
label: specialist.label,
|
|
113
|
+
text: result.text,
|
|
114
|
+
tokensUsed: result.tokensUsed,
|
|
115
|
+
providerUsed: result.provider,
|
|
116
|
+
modelUsed: result.model,
|
|
117
|
+
};
|
|
76
118
|
};
|
|
77
119
|
});
|
|
78
|
-
const results = await
|
|
120
|
+
const results = await runWithConcurrency(specialistTasks, { concurrency, delayMs });
|
|
79
121
|
// ── Step 2: Collect results ────────────────────────────────
|
|
80
122
|
let totalTokens = 0;
|
|
81
123
|
const specialistOutputs = [];
|
|
124
|
+
const modelsUsed = [];
|
|
82
125
|
for (let i = 0; i < results.length; i++) {
|
|
83
126
|
const result = results[i];
|
|
84
127
|
const spec = SPECIALISTS[i];
|
|
@@ -87,18 +130,27 @@ export async function runWorkflowReview(input) {
|
|
|
87
130
|
if (result.status === 'fulfilled') {
|
|
88
131
|
totalTokens += result.value.tokensUsed;
|
|
89
132
|
specialistOutputs.push(`### ${result.value.label}\n\n${result.value.text}`);
|
|
133
|
+
modelsUsed.push(`${result.value.name}:${result.value.providerUsed}/${result.value.modelUsed}`);
|
|
90
134
|
emit({
|
|
91
135
|
step: `specialist-${spec.name}`,
|
|
92
|
-
message: `✓ ${spec.label} — ${result.value.tokensUsed} tokens`,
|
|
136
|
+
message: `✓ ${spec.label} — ${result.value.tokensUsed} tokens (${result.value.providerUsed}/${result.value.modelUsed})`,
|
|
93
137
|
detail: result.value.text,
|
|
94
138
|
});
|
|
95
139
|
}
|
|
96
140
|
else {
|
|
97
141
|
// Include error information in synthesis so it's aware of gaps
|
|
98
142
|
specialistOutputs.push(`### [FAILED] Specialist\n\nThis specialist could not complete: ${String(result.reason)}`);
|
|
143
|
+
// Track failed specialists with error reason for debugging
|
|
144
|
+
const failedEntry = chain
|
|
145
|
+
? chain[i % chain.length]
|
|
146
|
+
: { provider: provider, model, apiKey };
|
|
147
|
+
const errorMsg = result.reason instanceof Error ? result.reason.message : String(result.reason);
|
|
148
|
+
// Truncate error to keep log lines manageable
|
|
149
|
+
const shortError = errorMsg.length > 100 ? `${errorMsg.slice(0, 100)}...` : errorMsg;
|
|
150
|
+
modelsUsed.push(`${spec.name}:${failedEntry.provider}/${failedEntry.model}[FAILED:${shortError}]`);
|
|
99
151
|
emit({
|
|
100
152
|
step: `specialist-${spec.name}`,
|
|
101
|
-
message: `✗ ${spec.label} — FAILED: ${String(result.reason)}`,
|
|
153
|
+
message: `✗ ${spec.label} — FAILED (${failedEntry.provider}/${failedEntry.model}): ${String(result.reason)}`,
|
|
102
154
|
});
|
|
103
155
|
}
|
|
104
156
|
}
|
|
@@ -107,6 +159,12 @@ export async function runWorkflowReview(input) {
|
|
|
107
159
|
message: `Synthesizing ${specialistOutputs.length} specialist outputs...`,
|
|
108
160
|
});
|
|
109
161
|
// ── Step 3: Synthesis ──────────────────────────────────────
|
|
162
|
+
// Synthesis always uses generateFns[0] (primary provider).
|
|
163
|
+
const synthesisGenerateFn = resolvedGenerateFns[0];
|
|
164
|
+
// Metadata for fallback: use chain[0] or flat fields
|
|
165
|
+
const primaryEntry = chain
|
|
166
|
+
? chain[0]
|
|
167
|
+
: { provider: provider, model, apiKey };
|
|
110
168
|
const synthesisPrompt = [
|
|
111
169
|
'Below are the findings from 5 specialist reviewers. Synthesize them into a final review.\n',
|
|
112
170
|
...specialistOutputs,
|
|
@@ -119,19 +177,28 @@ export async function runWorkflowReview(input) {
|
|
|
119
177
|
]
|
|
120
178
|
.filter(Boolean)
|
|
121
179
|
.join('\n');
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
180
|
+
try {
|
|
181
|
+
const synthesisResult = await synthesisGenerateFn(synthesisSystem, synthesisPrompt);
|
|
182
|
+
const executionTimeMs = Date.now() - startTime;
|
|
183
|
+
totalTokens += synthesisResult.tokensUsed;
|
|
184
|
+
// Parse the synthesis output using the same parser as simple mode
|
|
185
|
+
const reviewResult = parseReviewResponse(synthesisResult.text, synthesisResult.provider, synthesisResult.model, totalTokens, executionTimeMs, memoryContext);
|
|
186
|
+
// Override mode in metadata
|
|
187
|
+
reviewResult.metadata.mode = 'workflow';
|
|
188
|
+
reviewResult.metadata.modelsUsed = modelsUsed;
|
|
189
|
+
return reviewResult;
|
|
190
|
+
}
|
|
191
|
+
catch (error) {
|
|
192
|
+
const executionTimeMs = Date.now() - startTime;
|
|
193
|
+
// Synthesis failed (timeout or other error): return a fallback result
|
|
194
|
+
emit({
|
|
195
|
+
step: 'workflow-synthesis',
|
|
196
|
+
message: `Synthesis LLM call failed — falling back to static-analysis-only results: ${error instanceof Error ? error.message : String(error)}`,
|
|
197
|
+
});
|
|
198
|
+
const reviewResult = parseReviewResponse('STATUS: NEEDS_HUMAN_REVIEW\nSUMMARY: LLM synthesis failed. Only static analysis results are available.\nFINDINGS:\n', primaryEntry.provider, primaryEntry.model, totalTokens, executionTimeMs, memoryContext);
|
|
199
|
+
reviewResult.metadata.mode = 'workflow';
|
|
200
|
+
reviewResult.metadata.modelsUsed = modelsUsed;
|
|
201
|
+
return reviewResult;
|
|
202
|
+
}
|
|
136
203
|
}
|
|
137
204
|
//# sourceMappingURL=workflow.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workflow.js","sourceRoot":"","sources":["../../src/agents/workflow.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"workflow.js","sourceRoot":"","sources":["../../src/agents/workflow.ts"],"names":[],"mappings":"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"}
|