@oddessentials/odd-ai-reviewers 1.0.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 +190 -0
- package/dist/__tests__/hermetic-setup.d.ts +55 -0
- package/dist/__tests__/hermetic-setup.d.ts.map +1 -0
- package/dist/__tests__/hermetic-setup.js +62 -0
- package/dist/__tests__/hermetic-setup.js.map +1 -0
- package/dist/__tests__/test-utils/hermetic.d.ts +84 -0
- package/dist/__tests__/test-utils/hermetic.d.ts.map +1 -0
- package/dist/__tests__/test-utils/hermetic.js +147 -0
- package/dist/__tests__/test-utils/hermetic.js.map +1 -0
- package/dist/agents/ai_semantic_review.d.ts +12 -0
- package/dist/agents/ai_semantic_review.d.ts.map +1 -0
- package/dist/agents/ai_semantic_review.js +317 -0
- package/dist/agents/ai_semantic_review.js.map +1 -0
- package/dist/agents/control_flow/budget.d.ts +162 -0
- package/dist/agents/control_flow/budget.d.ts.map +1 -0
- package/dist/agents/control_flow/budget.js +331 -0
- package/dist/agents/control_flow/budget.js.map +1 -0
- package/dist/agents/control_flow/cfg-builder.d.ts +26 -0
- package/dist/agents/control_flow/cfg-builder.d.ts.map +1 -0
- package/dist/agents/control_flow/cfg-builder.js +776 -0
- package/dist/agents/control_flow/cfg-builder.js.map +1 -0
- package/dist/agents/control_flow/cfg-types.d.ts +186 -0
- package/dist/agents/control_flow/cfg-types.d.ts.map +1 -0
- package/dist/agents/control_flow/cfg-types.js +114 -0
- package/dist/agents/control_flow/cfg-types.js.map +1 -0
- package/dist/agents/control_flow/finding-generator.d.ts +118 -0
- package/dist/agents/control_flow/finding-generator.d.ts.map +1 -0
- package/dist/agents/control_flow/finding-generator.js +354 -0
- package/dist/agents/control_flow/finding-generator.js.map +1 -0
- package/dist/agents/control_flow/index.d.ts +39 -0
- package/dist/agents/control_flow/index.d.ts.map +1 -0
- package/dist/agents/control_flow/index.js +270 -0
- package/dist/agents/control_flow/index.js.map +1 -0
- package/dist/agents/control_flow/logger.d.ts +333 -0
- package/dist/agents/control_flow/logger.d.ts.map +1 -0
- package/dist/agents/control_flow/logger.js +607 -0
- package/dist/agents/control_flow/logger.js.map +1 -0
- package/dist/agents/control_flow/mitigation-detector.d.ts +207 -0
- package/dist/agents/control_flow/mitigation-detector.d.ts.map +1 -0
- package/dist/agents/control_flow/mitigation-detector.js +625 -0
- package/dist/agents/control_flow/mitigation-detector.js.map +1 -0
- package/dist/agents/control_flow/mitigation-patterns.d.ts +53 -0
- package/dist/agents/control_flow/mitigation-patterns.d.ts.map +1 -0
- package/dist/agents/control_flow/mitigation-patterns.js +620 -0
- package/dist/agents/control_flow/mitigation-patterns.js.map +1 -0
- package/dist/agents/control_flow/path-analyzer.d.ts +287 -0
- package/dist/agents/control_flow/path-analyzer.d.ts.map +1 -0
- package/dist/agents/control_flow/path-analyzer.js +695 -0
- package/dist/agents/control_flow/path-analyzer.js.map +1 -0
- package/dist/agents/control_flow/pattern-validator.d.ts +132 -0
- package/dist/agents/control_flow/pattern-validator.d.ts.map +1 -0
- package/dist/agents/control_flow/pattern-validator.js +420 -0
- package/dist/agents/control_flow/pattern-validator.js.map +1 -0
- package/dist/agents/control_flow/timeout-regex.d.ts +144 -0
- package/dist/agents/control_flow/timeout-regex.d.ts.map +1 -0
- package/dist/agents/control_flow/timeout-regex.js +339 -0
- package/dist/agents/control_flow/timeout-regex.js.map +1 -0
- package/dist/agents/control_flow/types.d.ts +782 -0
- package/dist/agents/control_flow/types.d.ts.map +1 -0
- package/dist/agents/control_flow/types.js +428 -0
- package/dist/agents/control_flow/types.js.map +1 -0
- package/dist/agents/control_flow/vulnerability-detector.d.ts +85 -0
- package/dist/agents/control_flow/vulnerability-detector.d.ts.map +1 -0
- package/dist/agents/control_flow/vulnerability-detector.js +493 -0
- package/dist/agents/control_flow/vulnerability-detector.js.map +1 -0
- package/dist/agents/date-utils.d.ts +19 -0
- package/dist/agents/date-utils.d.ts.map +1 -0
- package/dist/agents/date-utils.js +29 -0
- package/dist/agents/date-utils.js.map +1 -0
- package/dist/agents/index.d.ts +25 -0
- package/dist/agents/index.d.ts.map +1 -0
- package/dist/agents/index.js +50 -0
- package/dist/agents/index.js.map +1 -0
- package/dist/agents/json-utils.d.ts +34 -0
- package/dist/agents/json-utils.d.ts.map +1 -0
- package/dist/agents/json-utils.js +62 -0
- package/dist/agents/json-utils.js.map +1 -0
- package/dist/agents/local_llm.d.ts +24 -0
- package/dist/agents/local_llm.d.ts.map +1 -0
- package/dist/agents/local_llm.js +566 -0
- package/dist/agents/local_llm.js.map +1 -0
- package/dist/agents/metadata.d.ts +57 -0
- package/dist/agents/metadata.d.ts.map +1 -0
- package/dist/agents/metadata.js +45 -0
- package/dist/agents/metadata.js.map +1 -0
- package/dist/agents/opencode.d.ts +18 -0
- package/dist/agents/opencode.d.ts.map +1 -0
- package/dist/agents/opencode.js +364 -0
- package/dist/agents/opencode.js.map +1 -0
- package/dist/agents/path-filter.d.ts +25 -0
- package/dist/agents/path-filter.d.ts.map +1 -0
- package/dist/agents/path-filter.js +43 -0
- package/dist/agents/path-filter.js.map +1 -0
- package/dist/agents/pr_agent.d.ts +3 -0
- package/dist/agents/pr_agent.d.ts.map +1 -0
- package/dist/agents/pr_agent.js +312 -0
- package/dist/agents/pr_agent.js.map +1 -0
- package/dist/agents/retry.d.ts +12 -0
- package/dist/agents/retry.d.ts.map +1 -0
- package/dist/agents/retry.js +65 -0
- package/dist/agents/retry.js.map +1 -0
- package/dist/agents/reviewdog.d.ts +24 -0
- package/dist/agents/reviewdog.d.ts.map +1 -0
- package/dist/agents/reviewdog.js +259 -0
- package/dist/agents/reviewdog.js.map +1 -0
- package/dist/agents/security.d.ts +49 -0
- package/dist/agents/security.d.ts.map +1 -0
- package/dist/agents/security.js +302 -0
- package/dist/agents/security.js.map +1 -0
- package/dist/agents/semgrep.d.ts +8 -0
- package/dist/agents/semgrep.d.ts.map +1 -0
- package/dist/agents/semgrep.js +157 -0
- package/dist/agents/semgrep.js.map +1 -0
- package/dist/agents/types.d.ts +450 -0
- package/dist/agents/types.d.ts.map +1 -0
- package/dist/agents/types.js +127 -0
- package/dist/agents/types.js.map +1 -0
- package/dist/budget.d.ts +59 -0
- package/dist/budget.d.ts.map +1 -0
- package/dist/budget.js +82 -0
- package/dist/budget.js.map +1 -0
- package/dist/cache/key.d.ts +49 -0
- package/dist/cache/key.d.ts.map +1 -0
- package/dist/cache/key.js +71 -0
- package/dist/cache/key.js.map +1 -0
- package/dist/cache/store.d.ts +47 -0
- package/dist/cache/store.d.ts.map +1 -0
- package/dist/cache/store.js +328 -0
- package/dist/cache/store.js.map +1 -0
- package/dist/cli/commands/check.d.ts +60 -0
- package/dist/cli/commands/check.d.ts.map +1 -0
- package/dist/cli/commands/check.js +163 -0
- package/dist/cli/commands/check.js.map +1 -0
- package/dist/cli/commands/index.d.ts +12 -0
- package/dist/cli/commands/index.d.ts.map +1 -0
- package/dist/cli/commands/index.js +12 -0
- package/dist/cli/commands/index.js.map +1 -0
- package/dist/cli/commands/local-review.d.ts +149 -0
- package/dist/cli/commands/local-review.d.ts.map +1 -0
- package/dist/cli/commands/local-review.js +755 -0
- package/dist/cli/commands/local-review.js.map +1 -0
- package/dist/cli/config-wizard.d.ts +87 -0
- package/dist/cli/config-wizard.d.ts.map +1 -0
- package/dist/cli/config-wizard.js +240 -0
- package/dist/cli/config-wizard.js.map +1 -0
- package/dist/cli/dependencies/catalog.d.ts +44 -0
- package/dist/cli/dependencies/catalog.d.ts.map +1 -0
- package/dist/cli/dependencies/catalog.js +89 -0
- package/dist/cli/dependencies/catalog.js.map +1 -0
- package/dist/cli/dependencies/checker.d.ts +42 -0
- package/dist/cli/dependencies/checker.d.ts.map +1 -0
- package/dist/cli/dependencies/checker.js +240 -0
- package/dist/cli/dependencies/checker.js.map +1 -0
- package/dist/cli/dependencies/index.d.ts +16 -0
- package/dist/cli/dependencies/index.d.ts.map +1 -0
- package/dist/cli/dependencies/index.js +16 -0
- package/dist/cli/dependencies/index.js.map +1 -0
- package/dist/cli/dependencies/messages.d.ts +58 -0
- package/dist/cli/dependencies/messages.d.ts.map +1 -0
- package/dist/cli/dependencies/messages.js +183 -0
- package/dist/cli/dependencies/messages.js.map +1 -0
- package/dist/cli/dependencies/platform.d.ts +25 -0
- package/dist/cli/dependencies/platform.d.ts.map +1 -0
- package/dist/cli/dependencies/platform.js +42 -0
- package/dist/cli/dependencies/platform.js.map +1 -0
- package/dist/cli/dependencies/schemas.d.ts +65 -0
- package/dist/cli/dependencies/schemas.d.ts.map +1 -0
- package/dist/cli/dependencies/schemas.js +42 -0
- package/dist/cli/dependencies/schemas.js.map +1 -0
- package/dist/cli/dependencies/types.d.ts +112 -0
- package/dist/cli/dependencies/types.d.ts.map +1 -0
- package/dist/cli/dependencies/types.js +6 -0
- package/dist/cli/dependencies/types.js.map +1 -0
- package/dist/cli/dependencies/version.d.ts +67 -0
- package/dist/cli/dependencies/version.d.ts.map +1 -0
- package/dist/cli/dependencies/version.js +125 -0
- package/dist/cli/dependencies/version.js.map +1 -0
- package/dist/cli/git-context.d.ts +105 -0
- package/dist/cli/git-context.d.ts.map +1 -0
- package/dist/cli/git-context.js +313 -0
- package/dist/cli/git-context.js.map +1 -0
- package/dist/cli/interactive-prompts.d.ts +126 -0
- package/dist/cli/interactive-prompts.d.ts.map +1 -0
- package/dist/cli/interactive-prompts.js +128 -0
- package/dist/cli/interactive-prompts.js.map +1 -0
- package/dist/cli/options/index.d.ts +7 -0
- package/dist/cli/options/index.d.ts.map +1 -0
- package/dist/cli/options/index.js +11 -0
- package/dist/cli/options/index.js.map +1 -0
- package/dist/cli/options/local-review-options.d.ts +221 -0
- package/dist/cli/options/local-review-options.d.ts.map +1 -0
- package/dist/cli/options/local-review-options.js +332 -0
- package/dist/cli/options/local-review-options.js.map +1 -0
- package/dist/cli/output/colors.d.ts +154 -0
- package/dist/cli/output/colors.d.ts.map +1 -0
- package/dist/cli/output/colors.js +255 -0
- package/dist/cli/output/colors.js.map +1 -0
- package/dist/cli/output/errors.d.ts +157 -0
- package/dist/cli/output/errors.d.ts.map +1 -0
- package/dist/cli/output/errors.js +266 -0
- package/dist/cli/output/errors.js.map +1 -0
- package/dist/cli/output/index.d.ts +12 -0
- package/dist/cli/output/index.d.ts.map +1 -0
- package/dist/cli/output/index.js +15 -0
- package/dist/cli/output/index.js.map +1 -0
- package/dist/cli/output/progress.d.ts +237 -0
- package/dist/cli/output/progress.d.ts.map +1 -0
- package/dist/cli/output/progress.js +405 -0
- package/dist/cli/output/progress.js.map +1 -0
- package/dist/cli/signals.d.ts +145 -0
- package/dist/cli/signals.d.ts.map +1 -0
- package/dist/cli/signals.js +223 -0
- package/dist/cli/signals.js.map +1 -0
- package/dist/cli/validation-report.d.ts +106 -0
- package/dist/cli/validation-report.d.ts.map +1 -0
- package/dist/cli/validation-report.js +108 -0
- package/dist/cli/validation-report.js.map +1 -0
- package/dist/config/index.d.ts +9 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +12 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/mitigation-config.d.ts +94 -0
- package/dist/config/mitigation-config.d.ts.map +1 -0
- package/dist/config/mitigation-config.js +430 -0
- package/dist/config/mitigation-config.js.map +1 -0
- package/dist/config/providers.d.ts +118 -0
- package/dist/config/providers.d.ts.map +1 -0
- package/dist/config/providers.js +229 -0
- package/dist/config/providers.js.map +1 -0
- package/dist/config/schemas.d.ts +278 -0
- package/dist/config/schemas.d.ts.map +1 -0
- package/dist/config/schemas.js +111 -0
- package/dist/config/schemas.js.map +1 -0
- package/dist/config/zero-config.d.ts +126 -0
- package/dist/config/zero-config.d.ts.map +1 -0
- package/dist/config/zero-config.js +243 -0
- package/dist/config/zero-config.js.map +1 -0
- package/dist/config.d.ts +110 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +302 -0
- package/dist/config.js.map +1 -0
- package/dist/diff.d.ts +224 -0
- package/dist/diff.d.ts.map +1 -0
- package/dist/diff.js +832 -0
- package/dist/diff.js.map +1 -0
- package/dist/git-validators.d.ts +106 -0
- package/dist/git-validators.d.ts.map +1 -0
- package/dist/git-validators.js +224 -0
- package/dist/git-validators.js.map +1 -0
- package/dist/main.d.ts +61 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +704 -0
- package/dist/main.js.map +1 -0
- package/dist/phases/execute.d.ts +60 -0
- package/dist/phases/execute.d.ts.map +1 -0
- package/dist/phases/execute.js +168 -0
- package/dist/phases/execute.js.map +1 -0
- package/dist/phases/index.d.ts +9 -0
- package/dist/phases/index.d.ts.map +1 -0
- package/dist/phases/index.js +9 -0
- package/dist/phases/index.js.map +1 -0
- package/dist/phases/preflight.d.ts +40 -0
- package/dist/phases/preflight.d.ts.map +1 -0
- package/dist/phases/preflight.js +122 -0
- package/dist/phases/preflight.js.map +1 -0
- package/dist/phases/report.d.ts +51 -0
- package/dist/phases/report.d.ts.map +1 -0
- package/dist/phases/report.js +152 -0
- package/dist/phases/report.js.map +1 -0
- package/dist/policy.d.ts +33 -0
- package/dist/policy.d.ts.map +1 -0
- package/dist/policy.js +34 -0
- package/dist/policy.js.map +1 -0
- package/dist/preflight.d.ts +181 -0
- package/dist/preflight.d.ts.map +1 -0
- package/dist/preflight.js +627 -0
- package/dist/preflight.js.map +1 -0
- package/dist/report/ado.d.ts +53 -0
- package/dist/report/ado.d.ts.map +1 -0
- package/dist/report/ado.js +411 -0
- package/dist/report/ado.js.map +1 -0
- package/dist/report/agent-icons.d.ts +36 -0
- package/dist/report/agent-icons.d.ts.map +1 -0
- package/dist/report/agent-icons.js +46 -0
- package/dist/report/agent-icons.js.map +1 -0
- package/dist/report/base.d.ts +30 -0
- package/dist/report/base.d.ts.map +1 -0
- package/dist/report/base.js +64 -0
- package/dist/report/base.js.map +1 -0
- package/dist/report/formats.d.ts +206 -0
- package/dist/report/formats.d.ts.map +1 -0
- package/dist/report/formats.js +481 -0
- package/dist/report/formats.js.map +1 -0
- package/dist/report/github.d.ts +44 -0
- package/dist/report/github.d.ts.map +1 -0
- package/dist/report/github.js +409 -0
- package/dist/report/github.js.map +1 -0
- package/dist/report/line-resolver.d.ts +208 -0
- package/dist/report/line-resolver.d.ts.map +1 -0
- package/dist/report/line-resolver.js +578 -0
- package/dist/report/line-resolver.js.map +1 -0
- package/dist/report/resolution.d.ts +158 -0
- package/dist/report/resolution.d.ts.map +1 -0
- package/dist/report/resolution.js +272 -0
- package/dist/report/resolution.js.map +1 -0
- package/dist/report/sanitize.d.ts +32 -0
- package/dist/report/sanitize.d.ts.map +1 -0
- package/dist/report/sanitize.js +84 -0
- package/dist/report/sanitize.js.map +1 -0
- package/dist/report/terminal.d.ts +440 -0
- package/dist/report/terminal.d.ts.map +1 -0
- package/dist/report/terminal.js +840 -0
- package/dist/report/terminal.js.map +1 -0
- package/dist/reviewignore.d.ts +125 -0
- package/dist/reviewignore.d.ts.map +1 -0
- package/dist/reviewignore.js +335 -0
- package/dist/reviewignore.js.map +1 -0
- package/dist/security-logger.d.ts +178 -0
- package/dist/security-logger.d.ts.map +1 -0
- package/dist/security-logger.js +256 -0
- package/dist/security-logger.js.map +1 -0
- package/dist/telemetry/backends/console.d.ts +24 -0
- package/dist/telemetry/backends/console.d.ts.map +1 -0
- package/dist/telemetry/backends/console.js +54 -0
- package/dist/telemetry/backends/console.js.map +1 -0
- package/dist/telemetry/backends/jsonl.d.ts +31 -0
- package/dist/telemetry/backends/jsonl.d.ts.map +1 -0
- package/dist/telemetry/backends/jsonl.js +121 -0
- package/dist/telemetry/backends/jsonl.js.map +1 -0
- package/dist/telemetry/emitter.d.ts +43 -0
- package/dist/telemetry/emitter.d.ts.map +1 -0
- package/dist/telemetry/emitter.js +83 -0
- package/dist/telemetry/emitter.js.map +1 -0
- package/dist/telemetry/hook.d.ts +53 -0
- package/dist/telemetry/hook.d.ts.map +1 -0
- package/dist/telemetry/hook.js +118 -0
- package/dist/telemetry/hook.js.map +1 -0
- package/dist/telemetry/index.d.ts +58 -0
- package/dist/telemetry/index.d.ts.map +1 -0
- package/dist/telemetry/index.js +143 -0
- package/dist/telemetry/index.js.map +1 -0
- package/dist/telemetry/types.d.ts +139 -0
- package/dist/telemetry/types.d.ts.map +1 -0
- package/dist/telemetry/types.js +133 -0
- package/dist/telemetry/types.js.map +1 -0
- package/dist/trust.d.ts +65 -0
- package/dist/trust.d.ts.map +1 -0
- package/dist/trust.js +78 -0
- package/dist/trust.js.map +1 -0
- package/dist/types/assert-never.d.ts +30 -0
- package/dist/types/assert-never.d.ts.map +1 -0
- package/dist/types/assert-never.js +32 -0
- package/dist/types/assert-never.js.map +1 -0
- package/dist/types/branded.d.ts +172 -0
- package/dist/types/branded.d.ts.map +1 -0
- package/dist/types/branded.js +262 -0
- package/dist/types/branded.js.map +1 -0
- package/dist/types/errors.d.ts +320 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/errors.js +551 -0
- package/dist/types/errors.js.map +1 -0
- package/dist/types/index.d.ts +37 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +77 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/result.d.ts +323 -0
- package/dist/types/result.d.ts.map +1 -0
- package/dist/types/result.js +423 -0
- package/dist/types/result.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI Semantic Review Agent
|
|
3
|
+
* Multi-provider AI semantic code review
|
|
4
|
+
*
|
|
5
|
+
* INVARIANTS:
|
|
6
|
+
* - Router owns provider/model resolution
|
|
7
|
+
* - Agent receives context.provider and context.effectiveModel
|
|
8
|
+
* - No per-agent defaults, no legacy key references
|
|
9
|
+
*/
|
|
10
|
+
import OpenAI from 'openai';
|
|
11
|
+
import Anthropic from '@anthropic-ai/sdk';
|
|
12
|
+
import { z } from 'zod';
|
|
13
|
+
import { readFile } from 'fs/promises';
|
|
14
|
+
import { join } from 'path';
|
|
15
|
+
import { existsSync } from 'fs';
|
|
16
|
+
import { AgentSuccess, AgentFailure, AgentSkipped } from './types.js';
|
|
17
|
+
import { estimateTokens } from '../budget.js';
|
|
18
|
+
import { buildAgentEnv } from './security.js';
|
|
19
|
+
import { parseJsonResponse } from './json-utils.js';
|
|
20
|
+
import { withRetry } from './retry.js';
|
|
21
|
+
import { AgentError, AgentErrorCode } from '../types/errors.js';
|
|
22
|
+
const SUPPORTED_EXTENSIONS = [
|
|
23
|
+
'.ts',
|
|
24
|
+
'.tsx',
|
|
25
|
+
'.js',
|
|
26
|
+
'.jsx',
|
|
27
|
+
'.py',
|
|
28
|
+
'.go',
|
|
29
|
+
'.java',
|
|
30
|
+
'.rb',
|
|
31
|
+
'.php',
|
|
32
|
+
'.c',
|
|
33
|
+
'.cpp',
|
|
34
|
+
'.cs',
|
|
35
|
+
'.rs',
|
|
36
|
+
'.swift',
|
|
37
|
+
'.kt',
|
|
38
|
+
'.scala',
|
|
39
|
+
'.vue',
|
|
40
|
+
'.svelte',
|
|
41
|
+
];
|
|
42
|
+
const PROMPT_PATH = join(import.meta.dirname, '../../config/prompts/semantic_review.md');
|
|
43
|
+
/**
|
|
44
|
+
* Zod schema for validating Anthropic JSON response
|
|
45
|
+
*/
|
|
46
|
+
const SemanticResponseSchema = z.object({
|
|
47
|
+
summary: z.string(),
|
|
48
|
+
findings: z.array(z.object({
|
|
49
|
+
severity: z.enum(['critical', 'high', 'medium', 'low', 'info']),
|
|
50
|
+
file: z.string(),
|
|
51
|
+
line: z.number().optional(),
|
|
52
|
+
message: z.string(),
|
|
53
|
+
suggestion: z.string().optional(),
|
|
54
|
+
category: z.string(),
|
|
55
|
+
})),
|
|
56
|
+
});
|
|
57
|
+
/**
|
|
58
|
+
* Run semantic review using Anthropic Claude API
|
|
59
|
+
*/
|
|
60
|
+
async function runWithAnthropic(context, apiKey, model, systemPrompt, userPrompt, supportedFiles, estimatedInputTokens) {
|
|
61
|
+
const agentId = 'ai_semantic_review';
|
|
62
|
+
const startTime = Date.now();
|
|
63
|
+
console.log(`[ai_semantic_review] Calling Anthropic API with model: ${model}`);
|
|
64
|
+
const client = new Anthropic({ apiKey });
|
|
65
|
+
try {
|
|
66
|
+
const response = await withRetry(() => client.messages.create({
|
|
67
|
+
model,
|
|
68
|
+
max_tokens: 4000,
|
|
69
|
+
system: systemPrompt,
|
|
70
|
+
messages: [{ role: 'user', content: userPrompt }],
|
|
71
|
+
}));
|
|
72
|
+
// Extract text content
|
|
73
|
+
const textContent = response.content.find((c) => c.type === 'text');
|
|
74
|
+
if (!textContent || textContent.type !== 'text') {
|
|
75
|
+
throw new AgentError('No text content in Anthropic response', AgentErrorCode.EXECUTION_FAILED, {
|
|
76
|
+
agentId,
|
|
77
|
+
phase: 'response-extraction',
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
// Parse and validate JSON (handles Claude's code fence wrapping)
|
|
81
|
+
const parsed = parseJsonResponse(textContent.text, 'Anthropic');
|
|
82
|
+
const result = SemanticResponseSchema.safeParse(parsed);
|
|
83
|
+
if (!result.success) {
|
|
84
|
+
throw new AgentError(`Schema validation failed: ${result.error.message}`, AgentErrorCode.PARSE_ERROR, { agentId, phase: 'schema-validation' });
|
|
85
|
+
}
|
|
86
|
+
const findings = result.data.findings.map((f) => ({
|
|
87
|
+
severity: mapSeverity(f.severity),
|
|
88
|
+
file: f.file,
|
|
89
|
+
line: f.line,
|
|
90
|
+
message: f.message,
|
|
91
|
+
suggestion: f.suggestion,
|
|
92
|
+
ruleId: `semantic/${f.category}`,
|
|
93
|
+
sourceAgent: agentId,
|
|
94
|
+
}));
|
|
95
|
+
if (result.data.summary) {
|
|
96
|
+
console.log(`[ai_semantic_review] Summary: ${result.data.summary}`);
|
|
97
|
+
}
|
|
98
|
+
const tokensUsed = response.usage.input_tokens + response.usage.output_tokens;
|
|
99
|
+
const estimatedCostUsd = response.usage.input_tokens * 0.000015 + response.usage.output_tokens * 0.000075;
|
|
100
|
+
return AgentSuccess({
|
|
101
|
+
agentId,
|
|
102
|
+
findings,
|
|
103
|
+
metrics: {
|
|
104
|
+
durationMs: Date.now() - startTime,
|
|
105
|
+
filesProcessed: supportedFiles.length,
|
|
106
|
+
tokensUsed,
|
|
107
|
+
estimatedCostUsd,
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
// Convert to AgentError for consistent error handling
|
|
113
|
+
const agentError = error instanceof AgentError
|
|
114
|
+
? error
|
|
115
|
+
: new AgentError(error instanceof Error ? error.message : 'Unknown Anthropic error', AgentErrorCode.EXECUTION_FAILED, { agentId, phase: 'anthropic-call' });
|
|
116
|
+
return AgentFailure({
|
|
117
|
+
agentId,
|
|
118
|
+
error: agentError.message,
|
|
119
|
+
failureStage: 'exec',
|
|
120
|
+
metrics: {
|
|
121
|
+
durationMs: Date.now() - startTime,
|
|
122
|
+
filesProcessed: 0,
|
|
123
|
+
tokensUsed: estimatedInputTokens,
|
|
124
|
+
},
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
export const aiSemanticReviewAgent = {
|
|
129
|
+
id: 'ai_semantic_review',
|
|
130
|
+
name: 'AI Semantic Review',
|
|
131
|
+
usesLlm: true,
|
|
132
|
+
supports(file) {
|
|
133
|
+
if (file.status === 'deleted')
|
|
134
|
+
return false;
|
|
135
|
+
return SUPPORTED_EXTENSIONS.some((ext) => file.path.endsWith(ext));
|
|
136
|
+
},
|
|
137
|
+
async run(context) {
|
|
138
|
+
const startTime = Date.now();
|
|
139
|
+
const agentEnv = buildAgentEnv('ai_semantic_review', context.env);
|
|
140
|
+
// Use router-resolved provider and model
|
|
141
|
+
const { provider, effectiveModel } = context;
|
|
142
|
+
console.log(`[ai_semantic_review] Provider: ${provider}, Model: ${effectiveModel}`);
|
|
143
|
+
// Get files that this agent supports (shared by all providers)
|
|
144
|
+
const supportedFiles = context.files.filter((f) => this.supports(f));
|
|
145
|
+
if (supportedFiles.length === 0) {
|
|
146
|
+
return AgentSkipped({
|
|
147
|
+
agentId: this.id,
|
|
148
|
+
reason: 'No supported files to process',
|
|
149
|
+
metrics: { durationMs: Date.now() - startTime, filesProcessed: 0 },
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
// Load prompt template (shared by all providers)
|
|
153
|
+
let systemPrompt = `You are a senior code reviewer focused on semantic analysis.
|
|
154
|
+
Analyze the provided diff for:
|
|
155
|
+
- Logic errors and edge cases
|
|
156
|
+
- Security vulnerabilities
|
|
157
|
+
- Performance issues
|
|
158
|
+
- API misuse or anti-patterns
|
|
159
|
+
- Missing error handling
|
|
160
|
+
|
|
161
|
+
Line numbering requirements:
|
|
162
|
+
- Use new-file line numbers from unified diff hunk headers (@@ -a,b +c,d @@)
|
|
163
|
+
- Only use right-side diff lines (added or context). If unsure, omit the line.
|
|
164
|
+
|
|
165
|
+
Return a JSON object with findings.`;
|
|
166
|
+
if (existsSync(PROMPT_PATH)) {
|
|
167
|
+
try {
|
|
168
|
+
systemPrompt = await readFile(PROMPT_PATH, 'utf-8');
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
console.log('[ai_semantic_review] Using default prompt');
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
const fileSummary = supportedFiles
|
|
175
|
+
.map((f) => `- ${f.path} (${f.status}: +${f.additions}/-${f.deletions})`)
|
|
176
|
+
.join('\n');
|
|
177
|
+
const userPrompt = `## Files Changed
|
|
178
|
+
${fileSummary}
|
|
179
|
+
|
|
180
|
+
## Diff Content
|
|
181
|
+
\`\`\`diff
|
|
182
|
+
${context.diffContent}
|
|
183
|
+
\`\`\`
|
|
184
|
+
|
|
185
|
+
Analyze this code and return JSON:
|
|
186
|
+
{
|
|
187
|
+
"findings": [
|
|
188
|
+
{
|
|
189
|
+
"severity": "critical|high|medium|low|info",
|
|
190
|
+
"file": "path/to/file.ts",
|
|
191
|
+
"line": 42,
|
|
192
|
+
"message": "Description",
|
|
193
|
+
"suggestion": "How to fix",
|
|
194
|
+
"category": "security|performance|logic|error-handling|api-misuse"
|
|
195
|
+
}
|
|
196
|
+
],
|
|
197
|
+
"summary": "Brief summary of the review"
|
|
198
|
+
}`;
|
|
199
|
+
const estimatedInputTokens = estimateTokens(systemPrompt + userPrompt);
|
|
200
|
+
// Switch on provider
|
|
201
|
+
if (provider === 'anthropic') {
|
|
202
|
+
const anthropicKey = agentEnv['ANTHROPIC_API_KEY'];
|
|
203
|
+
if (!anthropicKey) {
|
|
204
|
+
return AgentFailure({
|
|
205
|
+
agentId: this.id,
|
|
206
|
+
error: 'ANTHROPIC_API_KEY not found despite provider=anthropic',
|
|
207
|
+
failureStage: 'preflight',
|
|
208
|
+
metrics: { durationMs: Date.now() - startTime, filesProcessed: 0 },
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
return runWithAnthropic(context, anthropicKey, effectiveModel, systemPrompt, userPrompt, supportedFiles, estimatedInputTokens);
|
|
212
|
+
}
|
|
213
|
+
// OpenAI / Azure OpenAI path
|
|
214
|
+
const apiKey = agentEnv['OPENAI_API_KEY'];
|
|
215
|
+
const azureEndpoint = agentEnv['AZURE_OPENAI_ENDPOINT'];
|
|
216
|
+
const azureApiKey = agentEnv['AZURE_OPENAI_API_KEY'];
|
|
217
|
+
const azureDeployment = agentEnv['AZURE_OPENAI_DEPLOYMENT'] || 'gpt-4';
|
|
218
|
+
if (!apiKey && !azureApiKey) {
|
|
219
|
+
return AgentFailure({
|
|
220
|
+
agentId: this.id,
|
|
221
|
+
error: 'No API key configured (set OPENAI_API_KEY or AZURE_OPENAI_API_KEY)',
|
|
222
|
+
failureStage: 'preflight',
|
|
223
|
+
metrics: {
|
|
224
|
+
durationMs: Date.now() - startTime,
|
|
225
|
+
filesProcessed: 0,
|
|
226
|
+
},
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
// Initialize OpenAI client
|
|
230
|
+
let openai;
|
|
231
|
+
if (azureEndpoint && azureApiKey) {
|
|
232
|
+
openai = new OpenAI({
|
|
233
|
+
apiKey: azureApiKey,
|
|
234
|
+
baseURL: `${azureEndpoint}/openai/deployments/${azureDeployment}`,
|
|
235
|
+
defaultQuery: { 'api-version': '2024-02-15-preview' },
|
|
236
|
+
defaultHeaders: { 'api-key': azureApiKey },
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
openai = new OpenAI({ apiKey });
|
|
241
|
+
}
|
|
242
|
+
try {
|
|
243
|
+
const response = await withRetry(() => openai.chat.completions.create({
|
|
244
|
+
model: effectiveModel,
|
|
245
|
+
messages: [
|
|
246
|
+
{ role: 'system', content: systemPrompt },
|
|
247
|
+
{ role: 'user', content: userPrompt },
|
|
248
|
+
],
|
|
249
|
+
response_format: { type: 'json_object' },
|
|
250
|
+
max_tokens: 4000,
|
|
251
|
+
temperature: 0.3,
|
|
252
|
+
}));
|
|
253
|
+
const content = response.choices[0]?.message?.content;
|
|
254
|
+
if (!content) {
|
|
255
|
+
throw new AgentError('Empty response from OpenAI', AgentErrorCode.EXECUTION_FAILED, {
|
|
256
|
+
agentId: this.id,
|
|
257
|
+
phase: 'response-extraction',
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
const result = JSON.parse(content);
|
|
261
|
+
const findings = [];
|
|
262
|
+
for (const finding of result.findings || []) {
|
|
263
|
+
findings.push({
|
|
264
|
+
severity: mapSeverity(finding.severity),
|
|
265
|
+
file: finding.file,
|
|
266
|
+
line: finding.line,
|
|
267
|
+
message: finding.message,
|
|
268
|
+
suggestion: finding.suggestion,
|
|
269
|
+
ruleId: `semantic/${finding.category}`,
|
|
270
|
+
sourceAgent: this.id,
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
const tokensUsed = response.usage?.total_tokens || estimatedInputTokens;
|
|
274
|
+
const promptTokens = response.usage?.prompt_tokens || estimatedInputTokens;
|
|
275
|
+
const completionTokens = response.usage?.completion_tokens || 0;
|
|
276
|
+
const estimatedCostUsd = (promptTokens / 1000) * 0.00015 + (completionTokens / 1000) * 0.0006;
|
|
277
|
+
return AgentSuccess({
|
|
278
|
+
agentId: this.id,
|
|
279
|
+
findings,
|
|
280
|
+
metrics: {
|
|
281
|
+
durationMs: Date.now() - startTime,
|
|
282
|
+
filesProcessed: supportedFiles.length,
|
|
283
|
+
tokensUsed,
|
|
284
|
+
estimatedCostUsd,
|
|
285
|
+
},
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
catch (error) {
|
|
289
|
+
// Convert to AgentError for consistent error handling
|
|
290
|
+
const agentError = error instanceof AgentError
|
|
291
|
+
? error
|
|
292
|
+
: new AgentError(error instanceof Error ? error.message : 'Unknown OpenAI error', AgentErrorCode.EXECUTION_FAILED, { agentId: this.id, phase: 'openai-call' });
|
|
293
|
+
return AgentFailure({
|
|
294
|
+
agentId: this.id,
|
|
295
|
+
error: agentError.message,
|
|
296
|
+
failureStage: 'exec',
|
|
297
|
+
metrics: {
|
|
298
|
+
durationMs: Date.now() - startTime,
|
|
299
|
+
filesProcessed: 0,
|
|
300
|
+
tokensUsed: estimatedInputTokens,
|
|
301
|
+
},
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
},
|
|
305
|
+
};
|
|
306
|
+
function mapSeverity(severity) {
|
|
307
|
+
switch (severity) {
|
|
308
|
+
case 'critical':
|
|
309
|
+
case 'high':
|
|
310
|
+
return 'error';
|
|
311
|
+
case 'medium':
|
|
312
|
+
return 'warning';
|
|
313
|
+
default:
|
|
314
|
+
return 'info';
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
//# sourceMappingURL=ai_semantic_review.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai_semantic_review.js","sourceRoot":"","sources":["../../src/agents/ai_semantic_review.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Analysis Budget Management
|
|
3
|
+
*
|
|
4
|
+
* Tracks time and size limits during control flow analysis.
|
|
5
|
+
* Implements FR-018 (time budget), FR-019 (size budget), FR-020 (degraded mode),
|
|
6
|
+
* and FR-021 (graceful termination).
|
|
7
|
+
*
|
|
8
|
+
* Tasks: T061-T066
|
|
9
|
+
*/
|
|
10
|
+
import type { BudgetStatus, AnalysisLogEntry } from './types.js';
|
|
11
|
+
import { type AnalysisLogger } from './logger.js';
|
|
12
|
+
/**
|
|
13
|
+
* Configuration for analysis budget limits
|
|
14
|
+
*/
|
|
15
|
+
export interface BudgetConfig {
|
|
16
|
+
/** Maximum analysis duration in milliseconds (default: 300,000 = 5 min) */
|
|
17
|
+
maxDurationMs: number;
|
|
18
|
+
/** Maximum lines to analyze (default: 10,000) */
|
|
19
|
+
maxLinesChanged: number;
|
|
20
|
+
/** Maximum call depth for inter-procedural analysis (default: 5) */
|
|
21
|
+
maxCallDepth: number;
|
|
22
|
+
/** Maximum nodes to visit per traversal (default: 10,000) */
|
|
23
|
+
maxNodesVisited: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Default budget configuration per FR-018, FR-019, FR-003
|
|
27
|
+
*/
|
|
28
|
+
export declare const DEFAULT_BUDGET_CONFIG: BudgetConfig;
|
|
29
|
+
/**
|
|
30
|
+
* File priority levels for degraded mode filtering.
|
|
31
|
+
*/
|
|
32
|
+
export type FilePriority = 'high' | 'medium' | 'low';
|
|
33
|
+
/**
|
|
34
|
+
* Patterns for determining file priority.
|
|
35
|
+
* High priority: security-sensitive files (always analyze)
|
|
36
|
+
* Medium priority: business logic (analyze if budget allows)
|
|
37
|
+
* Low priority: tests, config (skip in degraded mode)
|
|
38
|
+
*/
|
|
39
|
+
export declare const FILE_PRIORITY_PATTERNS: Record<FilePriority, RegExp[]>;
|
|
40
|
+
/**
|
|
41
|
+
* Determine the priority of a file based on its path.
|
|
42
|
+
*/
|
|
43
|
+
export declare function getFilePriority(filePath: string): FilePriority;
|
|
44
|
+
/**
|
|
45
|
+
* Analysis Budget Manager
|
|
46
|
+
*
|
|
47
|
+
* Tracks resource consumption and triggers degraded mode when limits approach.
|
|
48
|
+
* Ensures deterministic behavior: same input always produces same degradation.
|
|
49
|
+
*/
|
|
50
|
+
export declare class AnalysisBudget {
|
|
51
|
+
private readonly startTime;
|
|
52
|
+
private readonly config;
|
|
53
|
+
private linesAnalyzed;
|
|
54
|
+
private filesAnalyzed;
|
|
55
|
+
private filesSkipped;
|
|
56
|
+
private currentDepth;
|
|
57
|
+
private _status;
|
|
58
|
+
private degradedAt;
|
|
59
|
+
private readonly log;
|
|
60
|
+
private readonly logger;
|
|
61
|
+
constructor(config?: Partial<BudgetConfig>, logger?: AnalysisLogger);
|
|
62
|
+
/**
|
|
63
|
+
* Get current budget status
|
|
64
|
+
*/
|
|
65
|
+
get status(): BudgetStatus;
|
|
66
|
+
/**
|
|
67
|
+
* Check if analysis is in degraded mode
|
|
68
|
+
*/
|
|
69
|
+
get isDegraded(): boolean;
|
|
70
|
+
/**
|
|
71
|
+
* Get effective max call depth (reduced in degraded mode)
|
|
72
|
+
*/
|
|
73
|
+
get effectiveMaxCallDepth(): number;
|
|
74
|
+
/**
|
|
75
|
+
* Get elapsed time in milliseconds
|
|
76
|
+
*/
|
|
77
|
+
get elapsedMs(): number;
|
|
78
|
+
/**
|
|
79
|
+
* Get time remaining before budget exceeded
|
|
80
|
+
*/
|
|
81
|
+
get remainingMs(): number;
|
|
82
|
+
/**
|
|
83
|
+
* Get percentage of time budget consumed
|
|
84
|
+
*/
|
|
85
|
+
get timePercentUsed(): number;
|
|
86
|
+
/**
|
|
87
|
+
* Get percentage of size budget consumed
|
|
88
|
+
*/
|
|
89
|
+
get sizePercentUsed(): number;
|
|
90
|
+
/**
|
|
91
|
+
* Get analysis statistics
|
|
92
|
+
*/
|
|
93
|
+
get stats(): {
|
|
94
|
+
linesAnalyzed: number;
|
|
95
|
+
filesAnalyzed: number;
|
|
96
|
+
filesSkipped: number;
|
|
97
|
+
elapsedMs: number;
|
|
98
|
+
status: BudgetStatus;
|
|
99
|
+
degraded: boolean;
|
|
100
|
+
timePercentUsed: number;
|
|
101
|
+
sizePercentUsed: number;
|
|
102
|
+
};
|
|
103
|
+
/**
|
|
104
|
+
* Check if a file should be analyzed based on priority and budget status.
|
|
105
|
+
* Per FR-020: Skip low-priority files in degraded mode.
|
|
106
|
+
*/
|
|
107
|
+
shouldAnalyzeFile(filePath: string): boolean;
|
|
108
|
+
/**
|
|
109
|
+
* Sort files by priority for analysis order.
|
|
110
|
+
* High priority files are analyzed first.
|
|
111
|
+
*/
|
|
112
|
+
sortFilesByPriority<T extends {
|
|
113
|
+
path: string;
|
|
114
|
+
}>(files: T[]): T[];
|
|
115
|
+
/**
|
|
116
|
+
* Get the analysis log
|
|
117
|
+
*/
|
|
118
|
+
get analysisLog(): AnalysisLogEntry[];
|
|
119
|
+
/**
|
|
120
|
+
* Record analysis of a file
|
|
121
|
+
*/
|
|
122
|
+
recordFile(lineCount: number, _filePath?: string): void;
|
|
123
|
+
/**
|
|
124
|
+
* Set current call depth for inter-procedural analysis
|
|
125
|
+
*/
|
|
126
|
+
setCallDepth(depth: number): void;
|
|
127
|
+
/**
|
|
128
|
+
* Check if we can go deeper in call analysis
|
|
129
|
+
*/
|
|
130
|
+
canGoDeeper(): boolean;
|
|
131
|
+
/**
|
|
132
|
+
* Check budget status and update if needed
|
|
133
|
+
* Returns the current status after check
|
|
134
|
+
*/
|
|
135
|
+
checkBudget(): BudgetStatus;
|
|
136
|
+
/**
|
|
137
|
+
* Transition to a new budget status
|
|
138
|
+
*/
|
|
139
|
+
private transitionTo;
|
|
140
|
+
/**
|
|
141
|
+
* Add an entry to the analysis log
|
|
142
|
+
*/
|
|
143
|
+
addLog(level: AnalysisLogEntry['level'], message: string, context?: Record<string, unknown>): void;
|
|
144
|
+
/**
|
|
145
|
+
* Check if analysis should continue
|
|
146
|
+
* Returns false if budget is terminated
|
|
147
|
+
*/
|
|
148
|
+
shouldContinue(): boolean;
|
|
149
|
+
/**
|
|
150
|
+
* Get reason for degradation (if degraded)
|
|
151
|
+
*/
|
|
152
|
+
getDegradedReason(): string | undefined;
|
|
153
|
+
/**
|
|
154
|
+
* Create a snapshot of current budget state for finding metadata
|
|
155
|
+
*/
|
|
156
|
+
toFindingMetadata(): {
|
|
157
|
+
analysisDepth: number;
|
|
158
|
+
degraded: boolean;
|
|
159
|
+
degradedReason?: string;
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
//# sourceMappingURL=budget.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"budget.d.ts","sourceRoot":"","sources":["../../../src/agents/control_flow/budget.ts"],"names":[],"mappings":"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"}
|