@peakinfer/cli 1.0.133
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/.claude/settings.local.json +8 -0
- package/.env.example +6 -0
- package/.github/workflows/peakinfer.yml +64 -0
- package/CHANGELOG.md +31 -0
- package/LICENSE +190 -0
- package/README.md +335 -0
- package/data/inferencemax.json +274 -0
- package/dist/agent-analyzer.d.ts +45 -0
- package/dist/agent-analyzer.d.ts.map +1 -0
- package/dist/agent-analyzer.js +374 -0
- package/dist/agent-analyzer.js.map +1 -0
- package/dist/agent.d.ts +76 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +965 -0
- package/dist/agent.js.map +1 -0
- package/dist/agents/correlation-analyzer.d.ts +34 -0
- package/dist/agents/correlation-analyzer.d.ts.map +1 -0
- package/dist/agents/correlation-analyzer.js +261 -0
- package/dist/agents/correlation-analyzer.js.map +1 -0
- package/dist/agents/index.d.ts +91 -0
- package/dist/agents/index.d.ts.map +1 -0
- package/dist/agents/index.js +111 -0
- package/dist/agents/index.js.map +1 -0
- package/dist/agents/runtime-analyzer.d.ts +38 -0
- package/dist/agents/runtime-analyzer.d.ts.map +1 -0
- package/dist/agents/runtime-analyzer.js +244 -0
- package/dist/agents/runtime-analyzer.js.map +1 -0
- package/dist/analysis-types.d.ts +500 -0
- package/dist/analysis-types.d.ts.map +1 -0
- package/dist/analysis-types.js +11 -0
- package/dist/analysis-types.js.map +1 -0
- package/dist/analytics.d.ts +25 -0
- package/dist/analytics.d.ts.map +1 -0
- package/dist/analytics.js +94 -0
- package/dist/analytics.js.map +1 -0
- package/dist/analyzer.d.ts +48 -0
- package/dist/analyzer.d.ts.map +1 -0
- package/dist/analyzer.js +547 -0
- package/dist/analyzer.js.map +1 -0
- package/dist/artifacts.d.ts +44 -0
- package/dist/artifacts.d.ts.map +1 -0
- package/dist/artifacts.js +165 -0
- package/dist/artifacts.js.map +1 -0
- package/dist/benchmarks/index.d.ts +88 -0
- package/dist/benchmarks/index.d.ts.map +1 -0
- package/dist/benchmarks/index.js +205 -0
- package/dist/benchmarks/index.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +427 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/ci.d.ts +19 -0
- package/dist/commands/ci.d.ts.map +1 -0
- package/dist/commands/ci.js +253 -0
- package/dist/commands/ci.js.map +1 -0
- package/dist/commands/config.d.ts +16 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +249 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/demo.d.ts +15 -0
- package/dist/commands/demo.d.ts.map +1 -0
- package/dist/commands/demo.js +106 -0
- package/dist/commands/demo.js.map +1 -0
- package/dist/commands/export.d.ts +14 -0
- package/dist/commands/export.d.ts.map +1 -0
- package/dist/commands/export.js +209 -0
- package/dist/commands/export.js.map +1 -0
- package/dist/commands/history.d.ts +15 -0
- package/dist/commands/history.d.ts.map +1 -0
- package/dist/commands/history.js +389 -0
- package/dist/commands/history.js.map +1 -0
- package/dist/commands/template.d.ts +14 -0
- package/dist/commands/template.d.ts.map +1 -0
- package/dist/commands/template.js +341 -0
- package/dist/commands/template.js.map +1 -0
- package/dist/commands/validate-map.d.ts +12 -0
- package/dist/commands/validate-map.d.ts.map +1 -0
- package/dist/commands/validate-map.js +274 -0
- package/dist/commands/validate-map.js.map +1 -0
- package/dist/commands/whatif.d.ts +17 -0
- package/dist/commands/whatif.d.ts.map +1 -0
- package/dist/commands/whatif.js +206 -0
- package/dist/commands/whatif.js.map +1 -0
- package/dist/comparison.d.ts +38 -0
- package/dist/comparison.d.ts.map +1 -0
- package/dist/comparison.js +223 -0
- package/dist/comparison.js.map +1 -0
- package/dist/config.d.ts +42 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +158 -0
- package/dist/config.js.map +1 -0
- package/dist/connectors/helicone.d.ts +9 -0
- package/dist/connectors/helicone.d.ts.map +1 -0
- package/dist/connectors/helicone.js +106 -0
- package/dist/connectors/helicone.js.map +1 -0
- package/dist/connectors/index.d.ts +37 -0
- package/dist/connectors/index.d.ts.map +1 -0
- package/dist/connectors/index.js +65 -0
- package/dist/connectors/index.js.map +1 -0
- package/dist/connectors/langsmith.d.ts +9 -0
- package/dist/connectors/langsmith.d.ts.map +1 -0
- package/dist/connectors/langsmith.js +122 -0
- package/dist/connectors/langsmith.js.map +1 -0
- package/dist/connectors/types.d.ts +83 -0
- package/dist/connectors/types.d.ts.map +1 -0
- package/dist/connectors/types.js +98 -0
- package/dist/connectors/types.js.map +1 -0
- package/dist/cost-estimator.d.ts +46 -0
- package/dist/cost-estimator.d.ts.map +1 -0
- package/dist/cost-estimator.js +104 -0
- package/dist/cost-estimator.js.map +1 -0
- package/dist/costs.d.ts +57 -0
- package/dist/costs.d.ts.map +1 -0
- package/dist/costs.js +251 -0
- package/dist/costs.js.map +1 -0
- package/dist/counterfactuals.d.ts +29 -0
- package/dist/counterfactuals.d.ts.map +1 -0
- package/dist/counterfactuals.js +448 -0
- package/dist/counterfactuals.js.map +1 -0
- package/dist/enhancement-prompts.d.ts +41 -0
- package/dist/enhancement-prompts.d.ts.map +1 -0
- package/dist/enhancement-prompts.js +88 -0
- package/dist/enhancement-prompts.js.map +1 -0
- package/dist/envelopes.d.ts +20 -0
- package/dist/envelopes.d.ts.map +1 -0
- package/dist/envelopes.js +790 -0
- package/dist/envelopes.js.map +1 -0
- package/dist/format-normalizer.d.ts +71 -0
- package/dist/format-normalizer.d.ts.map +1 -0
- package/dist/format-normalizer.js +1331 -0
- package/dist/format-normalizer.js.map +1 -0
- package/dist/history.d.ts +79 -0
- package/dist/history.d.ts.map +1 -0
- package/dist/history.js +313 -0
- package/dist/history.js.map +1 -0
- package/dist/html.d.ts +11 -0
- package/dist/html.d.ts.map +1 -0
- package/dist/html.js +463 -0
- package/dist/html.js.map +1 -0
- package/dist/impact.d.ts +42 -0
- package/dist/impact.d.ts.map +1 -0
- package/dist/impact.js +443 -0
- package/dist/impact.js.map +1 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +34 -0
- package/dist/index.js.map +1 -0
- package/dist/insights.d.ts +5 -0
- package/dist/insights.d.ts.map +1 -0
- package/dist/insights.js +271 -0
- package/dist/insights.js.map +1 -0
- package/dist/joiner.d.ts +9 -0
- package/dist/joiner.d.ts.map +1 -0
- package/dist/joiner.js +247 -0
- package/dist/joiner.js.map +1 -0
- package/dist/orchestrator.d.ts +34 -0
- package/dist/orchestrator.d.ts.map +1 -0
- package/dist/orchestrator.js +827 -0
- package/dist/orchestrator.js.map +1 -0
- package/dist/pdf.d.ts +26 -0
- package/dist/pdf.d.ts.map +1 -0
- package/dist/pdf.js +84 -0
- package/dist/pdf.js.map +1 -0
- package/dist/prediction.d.ts +33 -0
- package/dist/prediction.d.ts.map +1 -0
- package/dist/prediction.js +316 -0
- package/dist/prediction.js.map +1 -0
- package/dist/prompts/loader.d.ts +38 -0
- package/dist/prompts/loader.d.ts.map +1 -0
- package/dist/prompts/loader.js +60 -0
- package/dist/prompts/loader.js.map +1 -0
- package/dist/renderer.d.ts +64 -0
- package/dist/renderer.d.ts.map +1 -0
- package/dist/renderer.js +923 -0
- package/dist/renderer.js.map +1 -0
- package/dist/runid.d.ts +57 -0
- package/dist/runid.d.ts.map +1 -0
- package/dist/runid.js +199 -0
- package/dist/runid.js.map +1 -0
- package/dist/runtime.d.ts +29 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +366 -0
- package/dist/runtime.js.map +1 -0
- package/dist/scanner.d.ts +11 -0
- package/dist/scanner.d.ts.map +1 -0
- package/dist/scanner.js +426 -0
- package/dist/scanner.js.map +1 -0
- package/dist/templates.d.ts +120 -0
- package/dist/templates.d.ts.map +1 -0
- package/dist/templates.js +429 -0
- package/dist/templates.js.map +1 -0
- package/dist/tools/index.d.ts +153 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +177 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/types.d.ts +3647 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +703 -0
- package/dist/types.js.map +1 -0
- package/dist/version.d.ts +7 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +23 -0
- package/dist/version.js.map +1 -0
- package/docs/demo-guide.md +423 -0
- package/docs/events-format.md +295 -0
- package/docs/inferencemap-spec.md +344 -0
- package/docs/migration-v2.md +293 -0
- package/fixtures/demo/precomputed.json +142 -0
- package/fixtures/demo-project/README.md +52 -0
- package/fixtures/demo-project/ai-service.ts +65 -0
- package/fixtures/demo-project/sample-events.jsonl +15 -0
- package/fixtures/demo-project/src/ai-service.ts +128 -0
- package/fixtures/demo-project/src/llm-client.ts +155 -0
- package/package.json +65 -0
- package/prompts/agent-analyzer.yaml +47 -0
- package/prompts/ci-gate.yaml +98 -0
- package/prompts/correlation-analyzer.yaml +178 -0
- package/prompts/format-normalizer.yaml +46 -0
- package/prompts/peak-performance.yaml +180 -0
- package/prompts/pr-comment.yaml +111 -0
- package/prompts/runtime-analyzer.yaml +189 -0
- package/prompts/unified-analyzer.yaml +241 -0
- package/schemas/inference-map.v0.1.json +215 -0
- package/scripts/benchmark.ts +394 -0
- package/scripts/demo-v1.5.sh +158 -0
- package/scripts/sync-from-site.sh +197 -0
- package/scripts/validate-sync.sh +178 -0
- package/src/agent-analyzer.ts +481 -0
- package/src/agent.ts +1232 -0
- package/src/agents/correlation-analyzer.ts +353 -0
- package/src/agents/index.ts +235 -0
- package/src/agents/runtime-analyzer.ts +343 -0
- package/src/analysis-types.ts +558 -0
- package/src/analytics.ts +100 -0
- package/src/analyzer.ts +692 -0
- package/src/artifacts.ts +218 -0
- package/src/benchmarks/index.ts +309 -0
- package/src/cli.ts +503 -0
- package/src/commands/ci.ts +336 -0
- package/src/commands/config.ts +288 -0
- package/src/commands/demo.ts +175 -0
- package/src/commands/export.ts +297 -0
- package/src/commands/history.ts +425 -0
- package/src/commands/template.ts +385 -0
- package/src/commands/validate-map.ts +324 -0
- package/src/commands/whatif.ts +272 -0
- package/src/comparison.ts +283 -0
- package/src/config.ts +188 -0
- package/src/connectors/helicone.ts +164 -0
- package/src/connectors/index.ts +93 -0
- package/src/connectors/langsmith.ts +179 -0
- package/src/connectors/types.ts +180 -0
- package/src/cost-estimator.ts +146 -0
- package/src/costs.ts +347 -0
- package/src/counterfactuals.ts +516 -0
- package/src/enhancement-prompts.ts +118 -0
- package/src/envelopes.ts +814 -0
- package/src/format-normalizer.ts +1486 -0
- package/src/history.ts +400 -0
- package/src/html.ts +512 -0
- package/src/impact.ts +522 -0
- package/src/index.ts +83 -0
- package/src/insights.ts +341 -0
- package/src/joiner.ts +289 -0
- package/src/orchestrator.ts +1015 -0
- package/src/pdf.ts +110 -0
- package/src/prediction.ts +392 -0
- package/src/prompts/loader.ts +88 -0
- package/src/renderer.ts +1045 -0
- package/src/runid.ts +261 -0
- package/src/runtime.ts +450 -0
- package/src/scanner.ts +508 -0
- package/src/templates.ts +561 -0
- package/src/tools/index.ts +214 -0
- package/src/types.ts +873 -0
- package/src/version.ts +24 -0
- package/templates/context-accumulation.yaml +23 -0
- package/templates/cost-concentration.yaml +20 -0
- package/templates/dead-code.yaml +20 -0
- package/templates/latency-explainer.yaml +23 -0
- package/templates/optimizations/ab-testing-framework.yaml +74 -0
- package/templates/optimizations/api-gateway-optimization.yaml +81 -0
- package/templates/optimizations/api-model-routing-strategy.yaml +126 -0
- package/templates/optimizations/auto-scaling-optimization.yaml +85 -0
- package/templates/optimizations/batch-utilization-diagnostic.yaml +142 -0
- package/templates/optimizations/comprehensive-apm.yaml +76 -0
- package/templates/optimizations/context-window-optimization.yaml +91 -0
- package/templates/optimizations/cost-sensitive-batch-processing.yaml +77 -0
- package/templates/optimizations/distributed-training-optimization.yaml +77 -0
- package/templates/optimizations/document-analysis-edge.yaml +77 -0
- package/templates/optimizations/document-pipeline-optimization.yaml +78 -0
- package/templates/optimizations/domain-specific-distillation.yaml +78 -0
- package/templates/optimizations/error-handling-optimization.yaml +76 -0
- package/templates/optimizations/gptq-4bit-quantization.yaml +96 -0
- package/templates/optimizations/long-context-memory-management.yaml +78 -0
- package/templates/optimizations/max-tokens-optimization.yaml +76 -0
- package/templates/optimizations/memory-bandwidth-optimization.yaml +73 -0
- package/templates/optimizations/multi-framework-resilience.yaml +75 -0
- package/templates/optimizations/multi-tenant-optimization.yaml +75 -0
- package/templates/optimizations/prompt-caching-optimization.yaml +143 -0
- package/templates/optimizations/pytorch-to-onnx-migration.yaml +109 -0
- package/templates/optimizations/quality-monitoring.yaml +74 -0
- package/templates/optimizations/realtime-budget-controls.yaml +74 -0
- package/templates/optimizations/realtime-latency-optimization.yaml +74 -0
- package/templates/optimizations/sglang-concurrency-optimization.yaml +78 -0
- package/templates/optimizations/smart-model-routing.yaml +96 -0
- package/templates/optimizations/streaming-batch-selection.yaml +167 -0
- package/templates/optimizations/system-prompt-optimization.yaml +75 -0
- package/templates/optimizations/tensorrt-llm-performance.yaml +77 -0
- package/templates/optimizations/vllm-high-throughput-optimization.yaml +93 -0
- package/templates/optimizations/vllm-migration-memory-bound.yaml +78 -0
- package/templates/overpowered-extraction.yaml +32 -0
- package/templates/overpowered-model.yaml +31 -0
- package/templates/prompt-bloat.yaml +24 -0
- package/templates/retry-explosion.yaml +28 -0
- package/templates/schema/insight.schema.json +113 -0
- package/templates/schema/optimization.schema.json +180 -0
- package/templates/streaming-drift.yaml +30 -0
- package/templates/throughput-gap.yaml +21 -0
- package/templates/token-underutilization.yaml +28 -0
- package/templates/untested-fallback.yaml +21 -0
- package/tests/accuracy/drift-detection.test.ts +184 -0
- package/tests/accuracy/false-positives.test.ts +166 -0
- package/tests/accuracy/templates.test.ts +205 -0
- package/tests/action/commands.test.ts +125 -0
- package/tests/action/comments.test.ts +347 -0
- package/tests/cli.test.ts +203 -0
- package/tests/comparison.test.ts +309 -0
- package/tests/correlation-analyzer.test.ts +534 -0
- package/tests/counterfactuals.test.ts +347 -0
- package/tests/fixtures/events/missing-id.jsonl +1 -0
- package/tests/fixtures/events/missing-input.jsonl +1 -0
- package/tests/fixtures/events/missing-latency.jsonl +1 -0
- package/tests/fixtures/events/missing-model.jsonl +1 -0
- package/tests/fixtures/events/missing-output.jsonl +1 -0
- package/tests/fixtures/events/missing-provider.jsonl +1 -0
- package/tests/fixtures/events/missing-ts.jsonl +1 -0
- package/tests/fixtures/events/valid.csv +3 -0
- package/tests/fixtures/events/valid.json +1 -0
- package/tests/fixtures/events/valid.jsonl +2 -0
- package/tests/fixtures/events/with-callsite.jsonl +1 -0
- package/tests/fixtures/events/with-intent.jsonl +1 -0
- package/tests/fixtures/events/wrong-type.jsonl +1 -0
- package/tests/fixtures/repos/empty/.gitkeep +0 -0
- package/tests/fixtures/repos/hybrid-router/router.py +35 -0
- package/tests/fixtures/repos/saas-anthropic/agent.ts +27 -0
- package/tests/fixtures/repos/saas-openai/assistant.js +33 -0
- package/tests/fixtures/repos/saas-openai/client.py +26 -0
- package/tests/fixtures/repos/self-hosted-vllm/inference.py +22 -0
- package/tests/github-action.test.ts +292 -0
- package/tests/insights.test.ts +878 -0
- package/tests/joiner.test.ts +168 -0
- package/tests/performance/action-latency.test.ts +132 -0
- package/tests/performance/benchmark.test.ts +189 -0
- package/tests/performance/cli-latency.test.ts +102 -0
- package/tests/pr-comment.test.ts +313 -0
- package/tests/prediction.test.ts +296 -0
- package/tests/runtime-analyzer.test.ts +375 -0
- package/tests/runtime.test.ts +205 -0
- package/tests/scanner.test.ts +122 -0
- package/tests/template-conformance.test.ts +526 -0
- package/tests/unit/cost-calculator.test.ts +303 -0
- package/tests/unit/credits.test.ts +180 -0
- package/tests/unit/inference-map.test.ts +276 -0
- package/tests/unit/schema.test.ts +300 -0
- package/tsconfig.json +20 -0
- package/vitest.config.ts +14 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { ScanResult, Callsite } from './types.js';
|
|
2
|
+
export interface LLMImpactEstimate {
|
|
3
|
+
layer: 'application' | 'api' | 'gateway' | 'runtime' | 'model' | 'hardware';
|
|
4
|
+
impactType: 'cost' | 'latency' | 'throughput';
|
|
5
|
+
estimatedImpactPercent: number;
|
|
6
|
+
effort: 'low' | 'medium' | 'high';
|
|
7
|
+
}
|
|
8
|
+
export interface LLMInsight {
|
|
9
|
+
severity: 'critical' | 'warning' | 'info';
|
|
10
|
+
category: 'cost' | 'latency' | 'reliability' | 'waste' | 'security' | 'best-practice' | 'throughput';
|
|
11
|
+
headline: string;
|
|
12
|
+
evidence: string;
|
|
13
|
+
location: string;
|
|
14
|
+
recommendation?: string;
|
|
15
|
+
impact?: LLMImpactEstimate;
|
|
16
|
+
}
|
|
17
|
+
interface AnalyzeOptions {
|
|
18
|
+
useLLM?: boolean;
|
|
19
|
+
useAgent?: boolean;
|
|
20
|
+
verbose?: boolean;
|
|
21
|
+
promptId?: string;
|
|
22
|
+
onProgress?: (data: {
|
|
23
|
+
percent: number;
|
|
24
|
+
currentFile?: string;
|
|
25
|
+
}) => void;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Result of analyzing scan results
|
|
29
|
+
*/
|
|
30
|
+
export interface AnalyzeResult {
|
|
31
|
+
callsites: Callsite[];
|
|
32
|
+
insights: LLMInsight[];
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Analyze scan results to extract semantic information from callsites.
|
|
36
|
+
* Uses LLM for semantic analysis when ANTHROPIC_API_KEY is available,
|
|
37
|
+
* falls back to regex patterns otherwise.
|
|
38
|
+
*
|
|
39
|
+
* Returns both callsites AND LLM-generated semantic insights (phase 1).
|
|
40
|
+
* Template-based insights are generated separately (phase 2).
|
|
41
|
+
*/
|
|
42
|
+
export declare function analyze(scanResult: ScanResult, options?: AnalyzeOptions): Promise<AnalyzeResult>;
|
|
43
|
+
/**
|
|
44
|
+
* Re-analyze a single file (for incremental updates)
|
|
45
|
+
*/
|
|
46
|
+
export declare function analyzeFile(filePath: string, content: string, lines: number[], options?: AnalyzeOptions): Promise<AnalyzeResult>;
|
|
47
|
+
export {};
|
|
48
|
+
//# sourceMappingURL=analyzer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../src/analyzer.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAsB,MAAM,YAAY,CAAC;AA4E3E,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,aAAa,GAAG,KAAK,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,UAAU,CAAC;IAC5E,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,YAAY,CAAC;IAC9C,sBAAsB,EAAE,MAAM,CAAC;IAC/B,MAAM,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;CACnC;AAGD,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,UAAU,GAAG,SAAS,GAAG,MAAM,CAAC;IAC1C,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,aAAa,GAAG,OAAO,GAAG,UAAU,GAAG,eAAe,GAAG,YAAY,CAAC;IACrG,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,iBAAiB,CAAC;CAC5B;AAOD,UAAU,cAAc;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CACxE;AAqTD;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,QAAQ,EAAE,UAAU,EAAE,CAAC;CACxB;AAED;;;;;;;GAOG;AACH,wBAAsB,OAAO,CAC3B,UAAU,EAAE,UAAU,EACtB,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,aAAa,CAAC,CAkKxB;AAED;;GAEG;AACH,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EAAE,EACf,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,aAAa,CAAC,CAkFxB"}
|
package/dist/analyzer.js
ADDED
|
@@ -0,0 +1,547 @@
|
|
|
1
|
+
import { readFileSync } from 'fs';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import { query } from '@anthropic-ai/claude-agent-sdk';
|
|
4
|
+
import { createHash } from 'crypto';
|
|
5
|
+
import { loadPrompt, getDefaultPrompt, loadConfig, getConfiguredMode, isCascadeEnabled } from './templates.js';
|
|
6
|
+
import { analyzeWithAgent, convertAgentCallsites } from './agent-analyzer.js';
|
|
7
|
+
// =============================================================================
|
|
8
|
+
// CONSTANTS
|
|
9
|
+
// =============================================================================
|
|
10
|
+
const LLM_BATCH_SIZE = 2; // Process files in small batches for smoother progress
|
|
11
|
+
const MAX_CONTEXT_CHARS = 4000; // Max chars per file to send to LLM
|
|
12
|
+
// Fallback regex patterns (used when LLM unavailable)
|
|
13
|
+
const PROVIDER_PATTERNS = {
|
|
14
|
+
openai: [/openai/i, /\.chat\.completions\.create/, /\.embeddings\.create/, /from\s+['"]openai['"]/],
|
|
15
|
+
anthropic: [/anthropic/i, /\.messages\.create/, /from\s+['"]@anthropic-ai/],
|
|
16
|
+
google: [/google\.generative/i, /genai\./, /from\s+['"]@google\/generative/],
|
|
17
|
+
together: [/together/i, /Together\s*\(/, /from\s+['"]together/],
|
|
18
|
+
fireworks: [/fireworks/i, /Fireworks\s*\(/],
|
|
19
|
+
groq: [/groq/i, /Groq\s*\(/],
|
|
20
|
+
mistral: [/mistral/i, /Mistral\s*\(/],
|
|
21
|
+
cohere: [/cohere/i, /Cohere\s*\(/],
|
|
22
|
+
replicate: [/replicate/i, /Replicate\s*\(/],
|
|
23
|
+
aws_bedrock: [/bedrock/i, /BedrockRuntime/],
|
|
24
|
+
azure: [/azure.*openai/i, /AzureOpenAI/],
|
|
25
|
+
vllm: [/vllm/i, /from\s+vllm/],
|
|
26
|
+
sglang: [/sglang/i, /SGLang/],
|
|
27
|
+
ollama: [/ollama/i, /Ollama\s*\(/],
|
|
28
|
+
};
|
|
29
|
+
// Framework detection patterns
|
|
30
|
+
const FRAMEWORK_PATTERNS = {
|
|
31
|
+
dspy: [/import\s+dspy/, /from\s+dspy/, /dspy\.Predict/, /dspy\.ChainOfThought/, /dspy\.LM\(/],
|
|
32
|
+
langchain: [/from\s+langchain/, /import\s+langchain/, /ChatOpenAI\(/, /LLMChain\(/],
|
|
33
|
+
llamaindex: [/from\s+llama_index/, /import\s+llama_index/, /llama_index\.llms/],
|
|
34
|
+
};
|
|
35
|
+
const MODEL_PATTERNS = [
|
|
36
|
+
/model\s*[=:]\s*['"]([^'"]+)['"]/i,
|
|
37
|
+
/model_name\s*[=:]\s*['"]([^'"]+)['"]/i,
|
|
38
|
+
/modelId\s*[=:]\s*['"]([^'"]+)['"]/i,
|
|
39
|
+
// DSPy-style: dspy.LM("openai/gpt-4o-mini") or dspy.LM("anthropic/claude-3-5-sonnet")
|
|
40
|
+
/dspy\.LM\s*\(\s*['"](?:[\w-]+\/)?([^'"]+)['"]/i,
|
|
41
|
+
// Embeddings models
|
|
42
|
+
/embeddings\.create\([^)]*model\s*[=:]\s*['"]([^'"]+)['"]/i,
|
|
43
|
+
];
|
|
44
|
+
const PATTERN_DETECTORS = {
|
|
45
|
+
streaming: [/stream\s*[=:]\s*true/i, /\.stream\s*\(/, /for\s+await\s*\(/],
|
|
46
|
+
batching: [/batch/i, /Promise\.all/, /\.map\s*\(\s*async/],
|
|
47
|
+
retries: [/retry/i, /max_retries/i, /backoff/i],
|
|
48
|
+
caching: [/cache/i, /memoize/i, /redis/i],
|
|
49
|
+
fallback: [/fallback/i, /\.catch\s*\(/, /except\s*:/],
|
|
50
|
+
};
|
|
51
|
+
// =============================================================================
|
|
52
|
+
// HELPERS
|
|
53
|
+
// =============================================================================
|
|
54
|
+
function generateCallsiteId(file, line) {
|
|
55
|
+
const hash = createHash('sha256')
|
|
56
|
+
.update(`${file}:${line}`)
|
|
57
|
+
.digest('hex')
|
|
58
|
+
.slice(0, 8);
|
|
59
|
+
return `cs_${hash}`;
|
|
60
|
+
}
|
|
61
|
+
function extractContext(content, line, windowSize = 10) {
|
|
62
|
+
const lines = content.split('\n');
|
|
63
|
+
const start = Math.max(0, line - windowSize);
|
|
64
|
+
const end = Math.min(lines.length, line + windowSize);
|
|
65
|
+
return lines.slice(start, end).join('\n');
|
|
66
|
+
}
|
|
67
|
+
function truncateContent(content) {
|
|
68
|
+
if (content.length <= MAX_CONTEXT_CHARS)
|
|
69
|
+
return content;
|
|
70
|
+
return content.slice(0, MAX_CONTEXT_CHARS) + '\n// ... truncated ...';
|
|
71
|
+
}
|
|
72
|
+
// =============================================================================
|
|
73
|
+
// LLM ANALYSIS (Claude Agent SDK)
|
|
74
|
+
// =============================================================================
|
|
75
|
+
/**
|
|
76
|
+
* Extract text content from Claude Agent SDK messages
|
|
77
|
+
*/
|
|
78
|
+
function extractTextFromMessages(messages) {
|
|
79
|
+
let text = '';
|
|
80
|
+
for (const msg of messages) {
|
|
81
|
+
if (msg.type === 'assistant' && msg.message?.content) {
|
|
82
|
+
for (const block of msg.message.content) {
|
|
83
|
+
if (block.type === 'text') {
|
|
84
|
+
text += block.text;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return text;
|
|
90
|
+
}
|
|
91
|
+
// Legacy static analysis prompt (hardcoded fallback)
|
|
92
|
+
// NOTE: Primary analysis now uses unified-analyzer.yaml via StaticAnalysisOrchestrator
|
|
93
|
+
function getStaticAnalysisPrompt() {
|
|
94
|
+
return `You are an expert at analyzing code to identify LLM inference usage and potential issues.
|
|
95
|
+
|
|
96
|
+
Analyze the following code and:
|
|
97
|
+
|
|
98
|
+
## PART 1: Identify LLM Usage
|
|
99
|
+
For each LLM API call, extract:
|
|
100
|
+
- line: The EXACT line number where the inference call is made (not client initialization)
|
|
101
|
+
- provider: MUST be one of: openai, anthropic, google, together, fireworks, groq, mistral, cohere, replicate, aws_bedrock, azure, vllm, sglang, ollama, unknown
|
|
102
|
+
- model: The EXACT model name as specified in the code (e.g., "gpt-4o", "gpt-4o-mini", "claude-3-5-sonnet-20241022", "text-embedding-3-small")
|
|
103
|
+
- framework: langchain, llamaindex, dspy, or null
|
|
104
|
+
- patterns: streaming, batching, retries, caching, fallback (true/false)
|
|
105
|
+
- confidence: 0.0 to 1.0
|
|
106
|
+
- reasoning: Brief explanation
|
|
107
|
+
|
|
108
|
+
CRITICAL RULES FOR MODEL EXTRACTION:
|
|
109
|
+
1. Look at the model= parameter in the SAME function call
|
|
110
|
+
2. If model is a variable, trace it to find the string value
|
|
111
|
+
3. For embeddings calls, use the embedding model name (e.g., "text-embedding-3-small"), NOT a chat model
|
|
112
|
+
4. For DSPy: look at dspy.LM("provider/model") or dspy.context(lm=...) to find the model
|
|
113
|
+
5. Return the FULL model name exactly as written (e.g., "gpt-4o-mini" not "gpt-4")
|
|
114
|
+
|
|
115
|
+
CRITICAL: DO NOT flag these as callsites:
|
|
116
|
+
- Client initialization: openai.OpenAI(), anthropic.Anthropic(), etc.
|
|
117
|
+
- Import statements
|
|
118
|
+
- Type annotations or comments
|
|
119
|
+
- Variable assignments without actual API calls
|
|
120
|
+
|
|
121
|
+
## PART 2: Generate Insights
|
|
122
|
+
Identify potential issues, anti-patterns, or improvements.
|
|
123
|
+
|
|
124
|
+
IMPORTANT - Use these EXACT values:
|
|
125
|
+
- severity: MUST be one of: "critical", "warning", "info"
|
|
126
|
+
- category: MUST be one of: "cost", "latency", "reliability", "waste", "security", "best-practice"
|
|
127
|
+
|
|
128
|
+
Issues to look for:
|
|
129
|
+
- Missing error handling for LLM calls (reliability)
|
|
130
|
+
- Hardcoded API keys or secrets (security)
|
|
131
|
+
- Inefficient patterns - no batching, no streaming (latency)
|
|
132
|
+
- Model selection issues - overpowered model for simple tasks (cost)
|
|
133
|
+
- Missing retries for production code (reliability)
|
|
134
|
+
- Cost optimization opportunities (cost)
|
|
135
|
+
|
|
136
|
+
Return ONLY valid JSON:
|
|
137
|
+
{
|
|
138
|
+
"callsites": [
|
|
139
|
+
{
|
|
140
|
+
"line": 42,
|
|
141
|
+
"provider": "openai",
|
|
142
|
+
"model": "gpt-4o",
|
|
143
|
+
"framework": null,
|
|
144
|
+
"patterns": {"streaming": true, "batching": false, "retries": true, "caching": false, "fallback": true},
|
|
145
|
+
"confidence": 0.95,
|
|
146
|
+
"reasoning": "Direct OpenAI API call"
|
|
147
|
+
}
|
|
148
|
+
],
|
|
149
|
+
"insights": [
|
|
150
|
+
{
|
|
151
|
+
"severity": "warning",
|
|
152
|
+
"category": "reliability",
|
|
153
|
+
"headline": "No retry logic for LLM call",
|
|
154
|
+
"evidence": "The API call at line 42 has no retry handling - LLM APIs can fail transiently",
|
|
155
|
+
"location": "src/chat.py:42",
|
|
156
|
+
"recommendation": "Add exponential backoff retry logic"
|
|
157
|
+
}
|
|
158
|
+
]
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
If no issues found, return empty arrays: {"callsites": [], "insights": []}`;
|
|
162
|
+
}
|
|
163
|
+
// Normalize LLM insights to valid values
|
|
164
|
+
function normalizeInsight(insight) {
|
|
165
|
+
// Normalize severity
|
|
166
|
+
const severityMap = {
|
|
167
|
+
error: 'critical',
|
|
168
|
+
high: 'critical',
|
|
169
|
+
medium: 'warning',
|
|
170
|
+
low: 'info',
|
|
171
|
+
};
|
|
172
|
+
const severity = severityMap[insight.severity] || insight.severity;
|
|
173
|
+
// Normalize category
|
|
174
|
+
const categoryMap = {
|
|
175
|
+
cost_optimization: 'cost',
|
|
176
|
+
performance: 'latency',
|
|
177
|
+
efficiency: 'waste',
|
|
178
|
+
error_handling: 'reliability',
|
|
179
|
+
'error-handling': 'reliability',
|
|
180
|
+
};
|
|
181
|
+
const category = categoryMap[insight.category] || insight.category;
|
|
182
|
+
return {
|
|
183
|
+
...insight,
|
|
184
|
+
severity: severity,
|
|
185
|
+
category: category,
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
async function analyzewithLLM(files, analysisPrompt, onProgress) {
|
|
189
|
+
const callsitesByFile = new Map();
|
|
190
|
+
const allInsights = [];
|
|
191
|
+
const totalFiles = files.length;
|
|
192
|
+
let llmErrorLogged = false; // Only log LLM errors once to avoid noise
|
|
193
|
+
// Process in batches
|
|
194
|
+
for (let i = 0; i < files.length; i += LLM_BATCH_SIZE) {
|
|
195
|
+
const batch = files.slice(i, i + LLM_BATCH_SIZE);
|
|
196
|
+
const currentFile = batch[0]?.path;
|
|
197
|
+
// Show progress bar BEFORE processing (visible during LLM call)
|
|
198
|
+
const percentBefore = Math.floor((i / totalFiles) * 100);
|
|
199
|
+
onProgress?.({ percent: percentBefore, currentFile });
|
|
200
|
+
const fileContents = batch.map(f => {
|
|
201
|
+
const truncated = truncateContent(f.content);
|
|
202
|
+
return `=== FILE: ${f.path} ===\nCandidate lines: ${f.candidateLines.join(', ')}\n\n${truncated}`;
|
|
203
|
+
}).join('\n\n');
|
|
204
|
+
try {
|
|
205
|
+
// Use Claude Agent SDK query() function
|
|
206
|
+
const agentQuery = query({
|
|
207
|
+
prompt: `${analysisPrompt}\n\n${fileContents}`,
|
|
208
|
+
options: {
|
|
209
|
+
model: 'claude-sonnet-4-20250514',
|
|
210
|
+
tools: [],
|
|
211
|
+
permissionMode: 'plan',
|
|
212
|
+
cwd: process.cwd(),
|
|
213
|
+
},
|
|
214
|
+
});
|
|
215
|
+
// Collect all messages from the async generator
|
|
216
|
+
const messages = [];
|
|
217
|
+
for await (const message of agentQuery) {
|
|
218
|
+
messages.push(message);
|
|
219
|
+
}
|
|
220
|
+
// Extract text content from messages
|
|
221
|
+
const text = extractTextFromMessages(messages);
|
|
222
|
+
const jsonMatch = text.match(/\{[\s\S]*\}/);
|
|
223
|
+
if (jsonMatch) {
|
|
224
|
+
const parsed = JSON.parse(jsonMatch[0]);
|
|
225
|
+
// Map callsites back to files
|
|
226
|
+
for (const callsite of parsed.callsites) {
|
|
227
|
+
for (const file of batch) {
|
|
228
|
+
if (file.candidateLines.includes(callsite.line)) {
|
|
229
|
+
const existing = callsitesByFile.get(file.path) || [];
|
|
230
|
+
existing.push(callsite);
|
|
231
|
+
callsitesByFile.set(file.path, existing);
|
|
232
|
+
break;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
// Collect insights (normalized to valid values)
|
|
237
|
+
if (parsed.insights && Array.isArray(parsed.insights)) {
|
|
238
|
+
allInsights.push(...parsed.insights.map(normalizeInsight));
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
catch (error) {
|
|
243
|
+
// Continue with regex fallback for this batch
|
|
244
|
+
// Only log once to avoid noisy output (Julie Zhou: calm, not alarming)
|
|
245
|
+
if (!llmErrorLogged) {
|
|
246
|
+
llmErrorLogged = true;
|
|
247
|
+
const errMsg = error instanceof Error ? error.message : String(error);
|
|
248
|
+
// Extract just the error type for cleaner output
|
|
249
|
+
const shortErr = errMsg.includes('authentication_error') ? 'invalid API key'
|
|
250
|
+
: errMsg.includes('rate_limit') ? 'rate limited'
|
|
251
|
+
: 'API error';
|
|
252
|
+
console.warn(`[analyzer] Claude Agent SDK unavailable (${shortErr}), using pattern matching`);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
// Report progress AFTER batch completes
|
|
256
|
+
const processedFiles = Math.min(i + LLM_BATCH_SIZE, totalFiles);
|
|
257
|
+
const percentAfter = Math.floor((processedFiles / totalFiles) * 100);
|
|
258
|
+
onProgress?.({ percent: percentAfter, currentFile });
|
|
259
|
+
}
|
|
260
|
+
return { callsitesByFile, insights: allInsights };
|
|
261
|
+
}
|
|
262
|
+
// =============================================================================
|
|
263
|
+
// REGEX FALLBACK
|
|
264
|
+
// =============================================================================
|
|
265
|
+
function detectProviderRegex(context, fileContent) {
|
|
266
|
+
for (const [provider, patterns] of Object.entries(PROVIDER_PATTERNS)) {
|
|
267
|
+
for (const pattern of patterns) {
|
|
268
|
+
if (pattern.test(context) || pattern.test(fileContent)) {
|
|
269
|
+
return provider;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
return undefined;
|
|
274
|
+
}
|
|
275
|
+
function detectFrameworkRegex(context, fileContent) {
|
|
276
|
+
for (const [framework, patterns] of Object.entries(FRAMEWORK_PATTERNS)) {
|
|
277
|
+
for (const pattern of patterns) {
|
|
278
|
+
if (pattern.test(context) || pattern.test(fileContent)) {
|
|
279
|
+
return framework;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
return null;
|
|
284
|
+
}
|
|
285
|
+
function detectModelRegex(context) {
|
|
286
|
+
for (const pattern of MODEL_PATTERNS) {
|
|
287
|
+
const match = context.match(pattern);
|
|
288
|
+
if (match && match[1]) {
|
|
289
|
+
return match[1];
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
return undefined;
|
|
293
|
+
}
|
|
294
|
+
function detectPatternsRegex(context) {
|
|
295
|
+
const patterns = {};
|
|
296
|
+
for (const [pattern, regexes] of Object.entries(PATTERN_DETECTORS)) {
|
|
297
|
+
for (const regex of regexes) {
|
|
298
|
+
if (regex.test(context)) {
|
|
299
|
+
patterns[pattern] = true;
|
|
300
|
+
break;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
return patterns;
|
|
305
|
+
}
|
|
306
|
+
function calculateConfidence(hasProvider, hasModel, patternCount) {
|
|
307
|
+
let confidence = 0.3;
|
|
308
|
+
if (hasProvider)
|
|
309
|
+
confidence += 0.3;
|
|
310
|
+
if (hasModel)
|
|
311
|
+
confidence += 0.25;
|
|
312
|
+
if (patternCount > 0)
|
|
313
|
+
confidence += 0.05 * Math.min(patternCount, 3);
|
|
314
|
+
return Math.min(confidence, 1.0);
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Analyze scan results to extract semantic information from callsites.
|
|
318
|
+
* Uses LLM for semantic analysis when ANTHROPIC_API_KEY is available,
|
|
319
|
+
* falls back to regex patterns otherwise.
|
|
320
|
+
*
|
|
321
|
+
* Returns both callsites AND LLM-generated semantic insights (phase 1).
|
|
322
|
+
* Template-based insights are generated separately (phase 2).
|
|
323
|
+
*/
|
|
324
|
+
export async function analyze(scanResult, options = {}) {
|
|
325
|
+
// Load config and determine analysis mode
|
|
326
|
+
const config = loadConfig();
|
|
327
|
+
const configuredMode = getConfiguredMode();
|
|
328
|
+
const cascadeEnabled = isCascadeEnabled();
|
|
329
|
+
// Options can override config, but config provides defaults
|
|
330
|
+
const { useLLM = configuredMode === 'llm' || (configuredMode === 'agent' && cascadeEnabled), useAgent = configuredMode === 'agent', verbose = config.agent.verbose, promptId, onProgress } = options;
|
|
331
|
+
if (verbose) {
|
|
332
|
+
console.log(`[analyzer] Mode: ${configuredMode}, Cascade: ${cascadeEnabled}`);
|
|
333
|
+
}
|
|
334
|
+
// First preference: Agent-based analysis (most accurate)
|
|
335
|
+
if (useAgent && process.env.ANTHROPIC_API_KEY) {
|
|
336
|
+
try {
|
|
337
|
+
if (verbose) {
|
|
338
|
+
console.log('[analyzer] Using agent-based analysis');
|
|
339
|
+
}
|
|
340
|
+
const agentResult = await analyzeWithAgent(scanResult, { verbose });
|
|
341
|
+
return {
|
|
342
|
+
callsites: convertAgentCallsites(agentResult.callsites),
|
|
343
|
+
insights: agentResult.insights,
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
catch (error) {
|
|
347
|
+
if (cascadeEnabled) {
|
|
348
|
+
console.warn('[analyzer] Agent analysis failed, falling back to LLM/regex:', error);
|
|
349
|
+
// Fall through to LLM or regex analysis
|
|
350
|
+
}
|
|
351
|
+
else {
|
|
352
|
+
throw error; // Don't cascade, re-throw
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
// Second preference: Single-prompt LLM analysis
|
|
357
|
+
// Third preference: Regex-only analysis (when useLLM=false or no API key)
|
|
358
|
+
const callsites = [];
|
|
359
|
+
const llmInsights = [];
|
|
360
|
+
const fileContents = new Map();
|
|
361
|
+
// Load analysis prompt (from YAML config or fallback)
|
|
362
|
+
let analysisPromptText = getStaticAnalysisPrompt(); // Load from YAML or fallback
|
|
363
|
+
if (promptId) {
|
|
364
|
+
const customPrompt = loadPrompt(promptId);
|
|
365
|
+
if (customPrompt) {
|
|
366
|
+
analysisPromptText = customPrompt.prompt;
|
|
367
|
+
}
|
|
368
|
+
else {
|
|
369
|
+
console.warn(`[analyzer] Prompt '${promptId}' not found, using default`);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
else {
|
|
373
|
+
// Try to load default peak-performance prompt
|
|
374
|
+
try {
|
|
375
|
+
const defaultPrompt = getDefaultPrompt();
|
|
376
|
+
analysisPromptText = defaultPrompt.prompt;
|
|
377
|
+
}
|
|
378
|
+
catch {
|
|
379
|
+
// Use hardcoded fallback if prompts directory doesn't exist
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
// Read file contents
|
|
383
|
+
for (const file of scanResult.files) {
|
|
384
|
+
try {
|
|
385
|
+
const absPath = join(scanResult.root, file.path);
|
|
386
|
+
fileContents.set(file.path, readFileSync(absPath, 'utf-8'));
|
|
387
|
+
}
|
|
388
|
+
catch {
|
|
389
|
+
continue;
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
// Group candidates by file
|
|
393
|
+
const candidatesByFile = new Map();
|
|
394
|
+
for (const candidate of scanResult.candidates) {
|
|
395
|
+
const existing = candidatesByFile.get(candidate.file) || [];
|
|
396
|
+
existing.push(candidate.line);
|
|
397
|
+
candidatesByFile.set(candidate.file, existing);
|
|
398
|
+
}
|
|
399
|
+
// Try LLM analysis if API key available (Claude Agent SDK uses env var)
|
|
400
|
+
let llmOutput = null;
|
|
401
|
+
if (useLLM && process.env.ANTHROPIC_API_KEY) {
|
|
402
|
+
try {
|
|
403
|
+
const filesToAnalyze = Array.from(candidatesByFile.entries())
|
|
404
|
+
.filter(([path]) => fileContents.has(path))
|
|
405
|
+
.map(([path, lines]) => ({
|
|
406
|
+
path,
|
|
407
|
+
content: fileContents.get(path),
|
|
408
|
+
candidateLines: lines,
|
|
409
|
+
}));
|
|
410
|
+
if (filesToAnalyze.length > 0) {
|
|
411
|
+
llmOutput = await analyzewithLLM(filesToAnalyze, analysisPromptText, onProgress);
|
|
412
|
+
// Collect LLM-generated insights (phase 1)
|
|
413
|
+
llmInsights.push(...llmOutput.insights);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
catch (error) {
|
|
417
|
+
console.warn('[analyzer] Claude Agent SDK initialization failed, using regex fallback');
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
// Process each candidate
|
|
421
|
+
for (const candidate of scanResult.candidates) {
|
|
422
|
+
const content = fileContents.get(candidate.file);
|
|
423
|
+
if (!content)
|
|
424
|
+
continue;
|
|
425
|
+
// Check if we have LLM results for this file/line
|
|
426
|
+
const llmCallsites = llmOutput?.callsitesByFile.get(candidate.file);
|
|
427
|
+
const llmMatch = llmCallsites?.find(c => c.line === candidate.line);
|
|
428
|
+
if (llmMatch) {
|
|
429
|
+
// Use LLM results
|
|
430
|
+
const typedProvider = llmMatch.provider;
|
|
431
|
+
callsites.push({
|
|
432
|
+
id: generateCallsiteId(candidate.file, candidate.line),
|
|
433
|
+
file: candidate.file,
|
|
434
|
+
line: candidate.line,
|
|
435
|
+
provider: typedProvider,
|
|
436
|
+
model: llmMatch.model,
|
|
437
|
+
framework: llmMatch.framework,
|
|
438
|
+
runtime: null,
|
|
439
|
+
patterns: llmMatch.patterns,
|
|
440
|
+
confidence: llmMatch.confidence,
|
|
441
|
+
});
|
|
442
|
+
}
|
|
443
|
+
else {
|
|
444
|
+
// Fallback to regex analysis
|
|
445
|
+
const context = extractContext(content, candidate.line);
|
|
446
|
+
const provider = detectProviderRegex(context, content);
|
|
447
|
+
const model = detectModelRegex(context);
|
|
448
|
+
const framework = detectFrameworkRegex(context, content);
|
|
449
|
+
const patterns = detectPatternsRegex(context);
|
|
450
|
+
const patternCount = Object.values(patterns).filter(Boolean).length;
|
|
451
|
+
const confidence = calculateConfidence(!!provider, !!model, patternCount);
|
|
452
|
+
const typedProvider = provider ?? null;
|
|
453
|
+
callsites.push({
|
|
454
|
+
id: generateCallsiteId(candidate.file, candidate.line),
|
|
455
|
+
file: candidate.file,
|
|
456
|
+
line: candidate.line,
|
|
457
|
+
provider: typedProvider,
|
|
458
|
+
model: model ?? null,
|
|
459
|
+
framework: framework,
|
|
460
|
+
runtime: null,
|
|
461
|
+
patterns,
|
|
462
|
+
confidence,
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
// Sort by confidence descending
|
|
467
|
+
callsites.sort((a, b) => b.confidence - a.confidence);
|
|
468
|
+
return { callsites, insights: llmInsights };
|
|
469
|
+
}
|
|
470
|
+
/**
|
|
471
|
+
* Re-analyze a single file (for incremental updates)
|
|
472
|
+
*/
|
|
473
|
+
export async function analyzeFile(filePath, content, lines, options = {}) {
|
|
474
|
+
const { useLLM = true, promptId } = options;
|
|
475
|
+
const callsites = [];
|
|
476
|
+
const llmInsights = [];
|
|
477
|
+
// Load analysis prompt (from YAML config or fallback)
|
|
478
|
+
let analysisPromptText = getStaticAnalysisPrompt();
|
|
479
|
+
if (promptId) {
|
|
480
|
+
const customPrompt = loadPrompt(promptId);
|
|
481
|
+
if (customPrompt) {
|
|
482
|
+
analysisPromptText = customPrompt.prompt;
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
else {
|
|
486
|
+
try {
|
|
487
|
+
const defaultPrompt = getDefaultPrompt();
|
|
488
|
+
analysisPromptText = defaultPrompt.prompt;
|
|
489
|
+
}
|
|
490
|
+
catch {
|
|
491
|
+
// Use hardcoded fallback
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
// Try LLM analysis (Claude Agent SDK uses env var)
|
|
495
|
+
let llmCallsites = [];
|
|
496
|
+
if (useLLM && process.env.ANTHROPIC_API_KEY) {
|
|
497
|
+
try {
|
|
498
|
+
const output = await analyzewithLLM([{ path: filePath, content, candidateLines: lines }], analysisPromptText);
|
|
499
|
+
llmCallsites = output.callsitesByFile.get(filePath) || [];
|
|
500
|
+
llmInsights.push(...output.insights);
|
|
501
|
+
}
|
|
502
|
+
catch {
|
|
503
|
+
// Fall through to regex
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
for (const line of lines) {
|
|
507
|
+
const llmMatch = llmCallsites.find(c => c.line === line);
|
|
508
|
+
if (llmMatch) {
|
|
509
|
+
const typedProvider = llmMatch.provider;
|
|
510
|
+
callsites.push({
|
|
511
|
+
id: generateCallsiteId(filePath, line),
|
|
512
|
+
file: filePath,
|
|
513
|
+
line,
|
|
514
|
+
provider: typedProvider,
|
|
515
|
+
model: llmMatch.model,
|
|
516
|
+
framework: llmMatch.framework,
|
|
517
|
+
runtime: null,
|
|
518
|
+
patterns: llmMatch.patterns,
|
|
519
|
+
confidence: llmMatch.confidence,
|
|
520
|
+
});
|
|
521
|
+
}
|
|
522
|
+
else {
|
|
523
|
+
// Regex fallback
|
|
524
|
+
const context = extractContext(content, line);
|
|
525
|
+
const provider = detectProviderRegex(context, content);
|
|
526
|
+
const model = detectModelRegex(context);
|
|
527
|
+
const framework = detectFrameworkRegex(context, content);
|
|
528
|
+
const patterns = detectPatternsRegex(context);
|
|
529
|
+
const patternCount = Object.values(patterns).filter(Boolean).length;
|
|
530
|
+
const confidence = calculateConfidence(!!provider, !!model, patternCount);
|
|
531
|
+
const typedProvider = provider ?? null;
|
|
532
|
+
callsites.push({
|
|
533
|
+
id: generateCallsiteId(filePath, line),
|
|
534
|
+
file: filePath,
|
|
535
|
+
line,
|
|
536
|
+
provider: typedProvider,
|
|
537
|
+
model: model ?? null,
|
|
538
|
+
framework: framework,
|
|
539
|
+
runtime: null,
|
|
540
|
+
patterns,
|
|
541
|
+
confidence,
|
|
542
|
+
});
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
return { callsites, insights: llmInsights };
|
|
546
|
+
}
|
|
547
|
+
//# sourceMappingURL=analyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyzer.js","sourceRoot":"","sources":["../src/analyzer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { InferenceMap, Insight, JoinedOutput, RuntimeSummary } from './types.js';
|
|
2
|
+
import { type RunInputs } from './runid.js';
|
|
3
|
+
export interface ArtifactData {
|
|
4
|
+
inferenceMap?: InferenceMap;
|
|
5
|
+
insights?: Insight[];
|
|
6
|
+
joined?: JoinedOutput;
|
|
7
|
+
runtime?: RuntimeSummary;
|
|
8
|
+
html?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface SaveOptions {
|
|
11
|
+
runId?: string;
|
|
12
|
+
inputs?: RunInputs;
|
|
13
|
+
projectName?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Save all analysis artifacts to .peakinfer/runs/<runId>/ directory
|
|
17
|
+
* Also maintains backward compatibility with root-level artifacts
|
|
18
|
+
*/
|
|
19
|
+
export declare function saveArtifacts(data: ArtifactData, outputDir?: string, options?: SaveOptions): string[];
|
|
20
|
+
/**
|
|
21
|
+
* Get the output directory path
|
|
22
|
+
*/
|
|
23
|
+
export declare function getOutputDir(): string;
|
|
24
|
+
/**
|
|
25
|
+
* Check if artifacts exist from a previous run
|
|
26
|
+
*/
|
|
27
|
+
export declare function artifactsExist(outputDir?: string): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Check if a run can be resumed with cached artifacts
|
|
30
|
+
*/
|
|
31
|
+
export declare function checkResumable(inputs: RunInputs, outputDir?: string): {
|
|
32
|
+
canResume: boolean;
|
|
33
|
+
runId: string;
|
|
34
|
+
runDir: string;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Load artifacts from a previous run
|
|
38
|
+
*/
|
|
39
|
+
export declare function loadArtifacts(runDir: string): ArtifactData;
|
|
40
|
+
/**
|
|
41
|
+
* Get a new run ID for given inputs
|
|
42
|
+
*/
|
|
43
|
+
export { generateRunId } from './runid.js';
|
|
44
|
+
//# sourceMappingURL=artifacts.d.ts.map
|