@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.
Files changed (367) hide show
  1. package/.claude/settings.local.json +8 -0
  2. package/.env.example +6 -0
  3. package/.github/workflows/peakinfer.yml +64 -0
  4. package/CHANGELOG.md +31 -0
  5. package/LICENSE +190 -0
  6. package/README.md +335 -0
  7. package/data/inferencemax.json +274 -0
  8. package/dist/agent-analyzer.d.ts +45 -0
  9. package/dist/agent-analyzer.d.ts.map +1 -0
  10. package/dist/agent-analyzer.js +374 -0
  11. package/dist/agent-analyzer.js.map +1 -0
  12. package/dist/agent.d.ts +76 -0
  13. package/dist/agent.d.ts.map +1 -0
  14. package/dist/agent.js +965 -0
  15. package/dist/agent.js.map +1 -0
  16. package/dist/agents/correlation-analyzer.d.ts +34 -0
  17. package/dist/agents/correlation-analyzer.d.ts.map +1 -0
  18. package/dist/agents/correlation-analyzer.js +261 -0
  19. package/dist/agents/correlation-analyzer.js.map +1 -0
  20. package/dist/agents/index.d.ts +91 -0
  21. package/dist/agents/index.d.ts.map +1 -0
  22. package/dist/agents/index.js +111 -0
  23. package/dist/agents/index.js.map +1 -0
  24. package/dist/agents/runtime-analyzer.d.ts +38 -0
  25. package/dist/agents/runtime-analyzer.d.ts.map +1 -0
  26. package/dist/agents/runtime-analyzer.js +244 -0
  27. package/dist/agents/runtime-analyzer.js.map +1 -0
  28. package/dist/analysis-types.d.ts +500 -0
  29. package/dist/analysis-types.d.ts.map +1 -0
  30. package/dist/analysis-types.js +11 -0
  31. package/dist/analysis-types.js.map +1 -0
  32. package/dist/analytics.d.ts +25 -0
  33. package/dist/analytics.d.ts.map +1 -0
  34. package/dist/analytics.js +94 -0
  35. package/dist/analytics.js.map +1 -0
  36. package/dist/analyzer.d.ts +48 -0
  37. package/dist/analyzer.d.ts.map +1 -0
  38. package/dist/analyzer.js +547 -0
  39. package/dist/analyzer.js.map +1 -0
  40. package/dist/artifacts.d.ts +44 -0
  41. package/dist/artifacts.d.ts.map +1 -0
  42. package/dist/artifacts.js +165 -0
  43. package/dist/artifacts.js.map +1 -0
  44. package/dist/benchmarks/index.d.ts +88 -0
  45. package/dist/benchmarks/index.d.ts.map +1 -0
  46. package/dist/benchmarks/index.js +205 -0
  47. package/dist/benchmarks/index.js.map +1 -0
  48. package/dist/cli.d.ts +3 -0
  49. package/dist/cli.d.ts.map +1 -0
  50. package/dist/cli.js +427 -0
  51. package/dist/cli.js.map +1 -0
  52. package/dist/commands/ci.d.ts +19 -0
  53. package/dist/commands/ci.d.ts.map +1 -0
  54. package/dist/commands/ci.js +253 -0
  55. package/dist/commands/ci.js.map +1 -0
  56. package/dist/commands/config.d.ts +16 -0
  57. package/dist/commands/config.d.ts.map +1 -0
  58. package/dist/commands/config.js +249 -0
  59. package/dist/commands/config.js.map +1 -0
  60. package/dist/commands/demo.d.ts +15 -0
  61. package/dist/commands/demo.d.ts.map +1 -0
  62. package/dist/commands/demo.js +106 -0
  63. package/dist/commands/demo.js.map +1 -0
  64. package/dist/commands/export.d.ts +14 -0
  65. package/dist/commands/export.d.ts.map +1 -0
  66. package/dist/commands/export.js +209 -0
  67. package/dist/commands/export.js.map +1 -0
  68. package/dist/commands/history.d.ts +15 -0
  69. package/dist/commands/history.d.ts.map +1 -0
  70. package/dist/commands/history.js +389 -0
  71. package/dist/commands/history.js.map +1 -0
  72. package/dist/commands/template.d.ts +14 -0
  73. package/dist/commands/template.d.ts.map +1 -0
  74. package/dist/commands/template.js +341 -0
  75. package/dist/commands/template.js.map +1 -0
  76. package/dist/commands/validate-map.d.ts +12 -0
  77. package/dist/commands/validate-map.d.ts.map +1 -0
  78. package/dist/commands/validate-map.js +274 -0
  79. package/dist/commands/validate-map.js.map +1 -0
  80. package/dist/commands/whatif.d.ts +17 -0
  81. package/dist/commands/whatif.d.ts.map +1 -0
  82. package/dist/commands/whatif.js +206 -0
  83. package/dist/commands/whatif.js.map +1 -0
  84. package/dist/comparison.d.ts +38 -0
  85. package/dist/comparison.d.ts.map +1 -0
  86. package/dist/comparison.js +223 -0
  87. package/dist/comparison.js.map +1 -0
  88. package/dist/config.d.ts +42 -0
  89. package/dist/config.d.ts.map +1 -0
  90. package/dist/config.js +158 -0
  91. package/dist/config.js.map +1 -0
  92. package/dist/connectors/helicone.d.ts +9 -0
  93. package/dist/connectors/helicone.d.ts.map +1 -0
  94. package/dist/connectors/helicone.js +106 -0
  95. package/dist/connectors/helicone.js.map +1 -0
  96. package/dist/connectors/index.d.ts +37 -0
  97. package/dist/connectors/index.d.ts.map +1 -0
  98. package/dist/connectors/index.js +65 -0
  99. package/dist/connectors/index.js.map +1 -0
  100. package/dist/connectors/langsmith.d.ts +9 -0
  101. package/dist/connectors/langsmith.d.ts.map +1 -0
  102. package/dist/connectors/langsmith.js +122 -0
  103. package/dist/connectors/langsmith.js.map +1 -0
  104. package/dist/connectors/types.d.ts +83 -0
  105. package/dist/connectors/types.d.ts.map +1 -0
  106. package/dist/connectors/types.js +98 -0
  107. package/dist/connectors/types.js.map +1 -0
  108. package/dist/cost-estimator.d.ts +46 -0
  109. package/dist/cost-estimator.d.ts.map +1 -0
  110. package/dist/cost-estimator.js +104 -0
  111. package/dist/cost-estimator.js.map +1 -0
  112. package/dist/costs.d.ts +57 -0
  113. package/dist/costs.d.ts.map +1 -0
  114. package/dist/costs.js +251 -0
  115. package/dist/costs.js.map +1 -0
  116. package/dist/counterfactuals.d.ts +29 -0
  117. package/dist/counterfactuals.d.ts.map +1 -0
  118. package/dist/counterfactuals.js +448 -0
  119. package/dist/counterfactuals.js.map +1 -0
  120. package/dist/enhancement-prompts.d.ts +41 -0
  121. package/dist/enhancement-prompts.d.ts.map +1 -0
  122. package/dist/enhancement-prompts.js +88 -0
  123. package/dist/enhancement-prompts.js.map +1 -0
  124. package/dist/envelopes.d.ts +20 -0
  125. package/dist/envelopes.d.ts.map +1 -0
  126. package/dist/envelopes.js +790 -0
  127. package/dist/envelopes.js.map +1 -0
  128. package/dist/format-normalizer.d.ts +71 -0
  129. package/dist/format-normalizer.d.ts.map +1 -0
  130. package/dist/format-normalizer.js +1331 -0
  131. package/dist/format-normalizer.js.map +1 -0
  132. package/dist/history.d.ts +79 -0
  133. package/dist/history.d.ts.map +1 -0
  134. package/dist/history.js +313 -0
  135. package/dist/history.js.map +1 -0
  136. package/dist/html.d.ts +11 -0
  137. package/dist/html.d.ts.map +1 -0
  138. package/dist/html.js +463 -0
  139. package/dist/html.js.map +1 -0
  140. package/dist/impact.d.ts +42 -0
  141. package/dist/impact.d.ts.map +1 -0
  142. package/dist/impact.js +443 -0
  143. package/dist/impact.js.map +1 -0
  144. package/dist/index.d.ts +26 -0
  145. package/dist/index.d.ts.map +1 -0
  146. package/dist/index.js +34 -0
  147. package/dist/index.js.map +1 -0
  148. package/dist/insights.d.ts +5 -0
  149. package/dist/insights.d.ts.map +1 -0
  150. package/dist/insights.js +271 -0
  151. package/dist/insights.js.map +1 -0
  152. package/dist/joiner.d.ts +9 -0
  153. package/dist/joiner.d.ts.map +1 -0
  154. package/dist/joiner.js +247 -0
  155. package/dist/joiner.js.map +1 -0
  156. package/dist/orchestrator.d.ts +34 -0
  157. package/dist/orchestrator.d.ts.map +1 -0
  158. package/dist/orchestrator.js +827 -0
  159. package/dist/orchestrator.js.map +1 -0
  160. package/dist/pdf.d.ts +26 -0
  161. package/dist/pdf.d.ts.map +1 -0
  162. package/dist/pdf.js +84 -0
  163. package/dist/pdf.js.map +1 -0
  164. package/dist/prediction.d.ts +33 -0
  165. package/dist/prediction.d.ts.map +1 -0
  166. package/dist/prediction.js +316 -0
  167. package/dist/prediction.js.map +1 -0
  168. package/dist/prompts/loader.d.ts +38 -0
  169. package/dist/prompts/loader.d.ts.map +1 -0
  170. package/dist/prompts/loader.js +60 -0
  171. package/dist/prompts/loader.js.map +1 -0
  172. package/dist/renderer.d.ts +64 -0
  173. package/dist/renderer.d.ts.map +1 -0
  174. package/dist/renderer.js +923 -0
  175. package/dist/renderer.js.map +1 -0
  176. package/dist/runid.d.ts +57 -0
  177. package/dist/runid.d.ts.map +1 -0
  178. package/dist/runid.js +199 -0
  179. package/dist/runid.js.map +1 -0
  180. package/dist/runtime.d.ts +29 -0
  181. package/dist/runtime.d.ts.map +1 -0
  182. package/dist/runtime.js +366 -0
  183. package/dist/runtime.js.map +1 -0
  184. package/dist/scanner.d.ts +11 -0
  185. package/dist/scanner.d.ts.map +1 -0
  186. package/dist/scanner.js +426 -0
  187. package/dist/scanner.js.map +1 -0
  188. package/dist/templates.d.ts +120 -0
  189. package/dist/templates.d.ts.map +1 -0
  190. package/dist/templates.js +429 -0
  191. package/dist/templates.js.map +1 -0
  192. package/dist/tools/index.d.ts +153 -0
  193. package/dist/tools/index.d.ts.map +1 -0
  194. package/dist/tools/index.js +177 -0
  195. package/dist/tools/index.js.map +1 -0
  196. package/dist/types.d.ts +3647 -0
  197. package/dist/types.d.ts.map +1 -0
  198. package/dist/types.js +703 -0
  199. package/dist/types.js.map +1 -0
  200. package/dist/version.d.ts +7 -0
  201. package/dist/version.d.ts.map +1 -0
  202. package/dist/version.js +23 -0
  203. package/dist/version.js.map +1 -0
  204. package/docs/demo-guide.md +423 -0
  205. package/docs/events-format.md +295 -0
  206. package/docs/inferencemap-spec.md +344 -0
  207. package/docs/migration-v2.md +293 -0
  208. package/fixtures/demo/precomputed.json +142 -0
  209. package/fixtures/demo-project/README.md +52 -0
  210. package/fixtures/demo-project/ai-service.ts +65 -0
  211. package/fixtures/demo-project/sample-events.jsonl +15 -0
  212. package/fixtures/demo-project/src/ai-service.ts +128 -0
  213. package/fixtures/demo-project/src/llm-client.ts +155 -0
  214. package/package.json +65 -0
  215. package/prompts/agent-analyzer.yaml +47 -0
  216. package/prompts/ci-gate.yaml +98 -0
  217. package/prompts/correlation-analyzer.yaml +178 -0
  218. package/prompts/format-normalizer.yaml +46 -0
  219. package/prompts/peak-performance.yaml +180 -0
  220. package/prompts/pr-comment.yaml +111 -0
  221. package/prompts/runtime-analyzer.yaml +189 -0
  222. package/prompts/unified-analyzer.yaml +241 -0
  223. package/schemas/inference-map.v0.1.json +215 -0
  224. package/scripts/benchmark.ts +394 -0
  225. package/scripts/demo-v1.5.sh +158 -0
  226. package/scripts/sync-from-site.sh +197 -0
  227. package/scripts/validate-sync.sh +178 -0
  228. package/src/agent-analyzer.ts +481 -0
  229. package/src/agent.ts +1232 -0
  230. package/src/agents/correlation-analyzer.ts +353 -0
  231. package/src/agents/index.ts +235 -0
  232. package/src/agents/runtime-analyzer.ts +343 -0
  233. package/src/analysis-types.ts +558 -0
  234. package/src/analytics.ts +100 -0
  235. package/src/analyzer.ts +692 -0
  236. package/src/artifacts.ts +218 -0
  237. package/src/benchmarks/index.ts +309 -0
  238. package/src/cli.ts +503 -0
  239. package/src/commands/ci.ts +336 -0
  240. package/src/commands/config.ts +288 -0
  241. package/src/commands/demo.ts +175 -0
  242. package/src/commands/export.ts +297 -0
  243. package/src/commands/history.ts +425 -0
  244. package/src/commands/template.ts +385 -0
  245. package/src/commands/validate-map.ts +324 -0
  246. package/src/commands/whatif.ts +272 -0
  247. package/src/comparison.ts +283 -0
  248. package/src/config.ts +188 -0
  249. package/src/connectors/helicone.ts +164 -0
  250. package/src/connectors/index.ts +93 -0
  251. package/src/connectors/langsmith.ts +179 -0
  252. package/src/connectors/types.ts +180 -0
  253. package/src/cost-estimator.ts +146 -0
  254. package/src/costs.ts +347 -0
  255. package/src/counterfactuals.ts +516 -0
  256. package/src/enhancement-prompts.ts +118 -0
  257. package/src/envelopes.ts +814 -0
  258. package/src/format-normalizer.ts +1486 -0
  259. package/src/history.ts +400 -0
  260. package/src/html.ts +512 -0
  261. package/src/impact.ts +522 -0
  262. package/src/index.ts +83 -0
  263. package/src/insights.ts +341 -0
  264. package/src/joiner.ts +289 -0
  265. package/src/orchestrator.ts +1015 -0
  266. package/src/pdf.ts +110 -0
  267. package/src/prediction.ts +392 -0
  268. package/src/prompts/loader.ts +88 -0
  269. package/src/renderer.ts +1045 -0
  270. package/src/runid.ts +261 -0
  271. package/src/runtime.ts +450 -0
  272. package/src/scanner.ts +508 -0
  273. package/src/templates.ts +561 -0
  274. package/src/tools/index.ts +214 -0
  275. package/src/types.ts +873 -0
  276. package/src/version.ts +24 -0
  277. package/templates/context-accumulation.yaml +23 -0
  278. package/templates/cost-concentration.yaml +20 -0
  279. package/templates/dead-code.yaml +20 -0
  280. package/templates/latency-explainer.yaml +23 -0
  281. package/templates/optimizations/ab-testing-framework.yaml +74 -0
  282. package/templates/optimizations/api-gateway-optimization.yaml +81 -0
  283. package/templates/optimizations/api-model-routing-strategy.yaml +126 -0
  284. package/templates/optimizations/auto-scaling-optimization.yaml +85 -0
  285. package/templates/optimizations/batch-utilization-diagnostic.yaml +142 -0
  286. package/templates/optimizations/comprehensive-apm.yaml +76 -0
  287. package/templates/optimizations/context-window-optimization.yaml +91 -0
  288. package/templates/optimizations/cost-sensitive-batch-processing.yaml +77 -0
  289. package/templates/optimizations/distributed-training-optimization.yaml +77 -0
  290. package/templates/optimizations/document-analysis-edge.yaml +77 -0
  291. package/templates/optimizations/document-pipeline-optimization.yaml +78 -0
  292. package/templates/optimizations/domain-specific-distillation.yaml +78 -0
  293. package/templates/optimizations/error-handling-optimization.yaml +76 -0
  294. package/templates/optimizations/gptq-4bit-quantization.yaml +96 -0
  295. package/templates/optimizations/long-context-memory-management.yaml +78 -0
  296. package/templates/optimizations/max-tokens-optimization.yaml +76 -0
  297. package/templates/optimizations/memory-bandwidth-optimization.yaml +73 -0
  298. package/templates/optimizations/multi-framework-resilience.yaml +75 -0
  299. package/templates/optimizations/multi-tenant-optimization.yaml +75 -0
  300. package/templates/optimizations/prompt-caching-optimization.yaml +143 -0
  301. package/templates/optimizations/pytorch-to-onnx-migration.yaml +109 -0
  302. package/templates/optimizations/quality-monitoring.yaml +74 -0
  303. package/templates/optimizations/realtime-budget-controls.yaml +74 -0
  304. package/templates/optimizations/realtime-latency-optimization.yaml +74 -0
  305. package/templates/optimizations/sglang-concurrency-optimization.yaml +78 -0
  306. package/templates/optimizations/smart-model-routing.yaml +96 -0
  307. package/templates/optimizations/streaming-batch-selection.yaml +167 -0
  308. package/templates/optimizations/system-prompt-optimization.yaml +75 -0
  309. package/templates/optimizations/tensorrt-llm-performance.yaml +77 -0
  310. package/templates/optimizations/vllm-high-throughput-optimization.yaml +93 -0
  311. package/templates/optimizations/vllm-migration-memory-bound.yaml +78 -0
  312. package/templates/overpowered-extraction.yaml +32 -0
  313. package/templates/overpowered-model.yaml +31 -0
  314. package/templates/prompt-bloat.yaml +24 -0
  315. package/templates/retry-explosion.yaml +28 -0
  316. package/templates/schema/insight.schema.json +113 -0
  317. package/templates/schema/optimization.schema.json +180 -0
  318. package/templates/streaming-drift.yaml +30 -0
  319. package/templates/throughput-gap.yaml +21 -0
  320. package/templates/token-underutilization.yaml +28 -0
  321. package/templates/untested-fallback.yaml +21 -0
  322. package/tests/accuracy/drift-detection.test.ts +184 -0
  323. package/tests/accuracy/false-positives.test.ts +166 -0
  324. package/tests/accuracy/templates.test.ts +205 -0
  325. package/tests/action/commands.test.ts +125 -0
  326. package/tests/action/comments.test.ts +347 -0
  327. package/tests/cli.test.ts +203 -0
  328. package/tests/comparison.test.ts +309 -0
  329. package/tests/correlation-analyzer.test.ts +534 -0
  330. package/tests/counterfactuals.test.ts +347 -0
  331. package/tests/fixtures/events/missing-id.jsonl +1 -0
  332. package/tests/fixtures/events/missing-input.jsonl +1 -0
  333. package/tests/fixtures/events/missing-latency.jsonl +1 -0
  334. package/tests/fixtures/events/missing-model.jsonl +1 -0
  335. package/tests/fixtures/events/missing-output.jsonl +1 -0
  336. package/tests/fixtures/events/missing-provider.jsonl +1 -0
  337. package/tests/fixtures/events/missing-ts.jsonl +1 -0
  338. package/tests/fixtures/events/valid.csv +3 -0
  339. package/tests/fixtures/events/valid.json +1 -0
  340. package/tests/fixtures/events/valid.jsonl +2 -0
  341. package/tests/fixtures/events/with-callsite.jsonl +1 -0
  342. package/tests/fixtures/events/with-intent.jsonl +1 -0
  343. package/tests/fixtures/events/wrong-type.jsonl +1 -0
  344. package/tests/fixtures/repos/empty/.gitkeep +0 -0
  345. package/tests/fixtures/repos/hybrid-router/router.py +35 -0
  346. package/tests/fixtures/repos/saas-anthropic/agent.ts +27 -0
  347. package/tests/fixtures/repos/saas-openai/assistant.js +33 -0
  348. package/tests/fixtures/repos/saas-openai/client.py +26 -0
  349. package/tests/fixtures/repos/self-hosted-vllm/inference.py +22 -0
  350. package/tests/github-action.test.ts +292 -0
  351. package/tests/insights.test.ts +878 -0
  352. package/tests/joiner.test.ts +168 -0
  353. package/tests/performance/action-latency.test.ts +132 -0
  354. package/tests/performance/benchmark.test.ts +189 -0
  355. package/tests/performance/cli-latency.test.ts +102 -0
  356. package/tests/pr-comment.test.ts +313 -0
  357. package/tests/prediction.test.ts +296 -0
  358. package/tests/runtime-analyzer.test.ts +375 -0
  359. package/tests/runtime.test.ts +205 -0
  360. package/tests/scanner.test.ts +122 -0
  361. package/tests/template-conformance.test.ts +526 -0
  362. package/tests/unit/cost-calculator.test.ts +303 -0
  363. package/tests/unit/credits.test.ts +180 -0
  364. package/tests/unit/inference-map.test.ts +276 -0
  365. package/tests/unit/schema.test.ts +300 -0
  366. package/tsconfig.json +20 -0
  367. package/vitest.config.ts +14 -0
@@ -0,0 +1,274 @@
1
+ {
2
+ "version": "1.0",
3
+ "last_updated": "2025-12-28",
4
+ "source": "InferenceMAX Benchmark Suite",
5
+ "benchmarks": {
6
+ "gpt-4o:api:api": {
7
+ "model": "gpt-4o",
8
+ "provider": "openai",
9
+ "framework": "api",
10
+ "hardware": "api",
11
+ "metrics": {
12
+ "ttft_ms": 180,
13
+ "p50_latency_ms": 800,
14
+ "p95_latency_ms": 1200,
15
+ "p99_latency_ms": 1800,
16
+ "throughput_tps": 45,
17
+ "cost_per_1k_input": 0.005,
18
+ "cost_per_1k_output": 0.015
19
+ },
20
+ "notes": "OpenAI API baseline"
21
+ },
22
+ "gpt-4o-mini:api:api": {
23
+ "model": "gpt-4o-mini",
24
+ "provider": "openai",
25
+ "framework": "api",
26
+ "hardware": "api",
27
+ "metrics": {
28
+ "ttft_ms": 120,
29
+ "p50_latency_ms": 400,
30
+ "p95_latency_ms": 600,
31
+ "p99_latency_ms": 900,
32
+ "throughput_tps": 90,
33
+ "cost_per_1k_input": 0.00015,
34
+ "cost_per_1k_output": 0.0006
35
+ },
36
+ "notes": "OpenAI API baseline - mini model"
37
+ },
38
+ "gpt-4-turbo:api:api": {
39
+ "model": "gpt-4-turbo",
40
+ "provider": "openai",
41
+ "framework": "api",
42
+ "hardware": "api",
43
+ "metrics": {
44
+ "ttft_ms": 250,
45
+ "p50_latency_ms": 1200,
46
+ "p95_latency_ms": 2000,
47
+ "p99_latency_ms": 3000,
48
+ "throughput_tps": 30,
49
+ "cost_per_1k_input": 0.01,
50
+ "cost_per_1k_output": 0.03
51
+ },
52
+ "notes": "OpenAI API baseline - GPT-4 Turbo"
53
+ },
54
+ "claude-3-5-sonnet:api:api": {
55
+ "model": "claude-3-5-sonnet-20241022",
56
+ "provider": "anthropic",
57
+ "framework": "api",
58
+ "hardware": "api",
59
+ "metrics": {
60
+ "ttft_ms": 150,
61
+ "p50_latency_ms": 600,
62
+ "p95_latency_ms": 1000,
63
+ "p99_latency_ms": 1500,
64
+ "throughput_tps": 50,
65
+ "cost_per_1k_input": 0.003,
66
+ "cost_per_1k_output": 0.015
67
+ },
68
+ "notes": "Anthropic API baseline"
69
+ },
70
+ "claude-3-5-haiku:api:api": {
71
+ "model": "claude-3-5-haiku-20241022",
72
+ "provider": "anthropic",
73
+ "framework": "api",
74
+ "hardware": "api",
75
+ "metrics": {
76
+ "ttft_ms": 80,
77
+ "p50_latency_ms": 300,
78
+ "p95_latency_ms": 500,
79
+ "p99_latency_ms": 750,
80
+ "throughput_tps": 100,
81
+ "cost_per_1k_input": 0.001,
82
+ "cost_per_1k_output": 0.005
83
+ },
84
+ "notes": "Anthropic API baseline - Haiku"
85
+ },
86
+ "claude-3-opus:api:api": {
87
+ "model": "claude-3-opus-20240229",
88
+ "provider": "anthropic",
89
+ "framework": "api",
90
+ "hardware": "api",
91
+ "metrics": {
92
+ "ttft_ms": 300,
93
+ "p50_latency_ms": 1500,
94
+ "p95_latency_ms": 2500,
95
+ "p99_latency_ms": 4000,
96
+ "throughput_tps": 20,
97
+ "cost_per_1k_input": 0.015,
98
+ "cost_per_1k_output": 0.075
99
+ },
100
+ "notes": "Anthropic API baseline - Opus"
101
+ },
102
+ "gemini-2.0-flash:api:api": {
103
+ "model": "gemini-2.0-flash-exp",
104
+ "provider": "google",
105
+ "framework": "api",
106
+ "hardware": "api",
107
+ "metrics": {
108
+ "ttft_ms": 100,
109
+ "p50_latency_ms": 350,
110
+ "p95_latency_ms": 550,
111
+ "p99_latency_ms": 800,
112
+ "throughput_tps": 85,
113
+ "cost_per_1k_input": 0.00035,
114
+ "cost_per_1k_output": 0.0007
115
+ },
116
+ "notes": "Google API baseline - Gemini Flash"
117
+ },
118
+ "gemini-1.5-pro:api:api": {
119
+ "model": "gemini-1.5-pro",
120
+ "provider": "google",
121
+ "framework": "api",
122
+ "hardware": "api",
123
+ "metrics": {
124
+ "ttft_ms": 200,
125
+ "p50_latency_ms": 700,
126
+ "p95_latency_ms": 1100,
127
+ "p99_latency_ms": 1600,
128
+ "throughput_tps": 40,
129
+ "cost_per_1k_input": 0.00125,
130
+ "cost_per_1k_output": 0.005
131
+ },
132
+ "notes": "Google API baseline - Gemini Pro"
133
+ },
134
+ "llama-3.1-70b:vllm:h100": {
135
+ "model": "llama-3.1-70b-instruct",
136
+ "provider": "meta",
137
+ "framework": "vllm",
138
+ "hardware": "h100",
139
+ "metrics": {
140
+ "ttft_ms": 50,
141
+ "p50_latency_ms": 200,
142
+ "p95_latency_ms": 400,
143
+ "p99_latency_ms": 600,
144
+ "throughput_tps": 120,
145
+ "cost_per_1k_input": 0.0,
146
+ "cost_per_1k_output": 0.0
147
+ },
148
+ "optimal_config": {
149
+ "tensor_parallelism": 4,
150
+ "max_model_len": 8192,
151
+ "gpu_memory_utilization": 0.9
152
+ },
153
+ "notes": "Self-hosted on 4xH100"
154
+ },
155
+ "llama-3.1-70b:vllm:a100": {
156
+ "model": "llama-3.1-70b-instruct",
157
+ "provider": "meta",
158
+ "framework": "vllm",
159
+ "hardware": "a100",
160
+ "metrics": {
161
+ "ttft_ms": 80,
162
+ "p50_latency_ms": 350,
163
+ "p95_latency_ms": 600,
164
+ "p99_latency_ms": 900,
165
+ "throughput_tps": 70,
166
+ "cost_per_1k_input": 0.0,
167
+ "cost_per_1k_output": 0.0
168
+ },
169
+ "optimal_config": {
170
+ "tensor_parallelism": 4,
171
+ "max_model_len": 8192,
172
+ "gpu_memory_utilization": 0.9
173
+ },
174
+ "notes": "Self-hosted on 4xA100-80GB"
175
+ },
176
+ "llama-3.1-8b:vllm:a100": {
177
+ "model": "llama-3.1-8b-instruct",
178
+ "provider": "meta",
179
+ "framework": "vllm",
180
+ "hardware": "a100",
181
+ "metrics": {
182
+ "ttft_ms": 20,
183
+ "p50_latency_ms": 100,
184
+ "p95_latency_ms": 180,
185
+ "p99_latency_ms": 250,
186
+ "throughput_tps": 250,
187
+ "cost_per_1k_input": 0.0,
188
+ "cost_per_1k_output": 0.0
189
+ },
190
+ "optimal_config": {
191
+ "tensor_parallelism": 1,
192
+ "max_model_len": 8192,
193
+ "gpu_memory_utilization": 0.9
194
+ },
195
+ "notes": "Self-hosted on 1xA100-80GB"
196
+ },
197
+ "mistral-large:api:api": {
198
+ "model": "mistral-large-latest",
199
+ "provider": "mistral",
200
+ "framework": "api",
201
+ "hardware": "api",
202
+ "metrics": {
203
+ "ttft_ms": 160,
204
+ "p50_latency_ms": 550,
205
+ "p95_latency_ms": 900,
206
+ "p99_latency_ms": 1300,
207
+ "throughput_tps": 55,
208
+ "cost_per_1k_input": 0.004,
209
+ "cost_per_1k_output": 0.012
210
+ },
211
+ "notes": "Mistral API baseline"
212
+ },
213
+ "mixtral-8x7b:vllm:a100": {
214
+ "model": "mixtral-8x7b-instruct",
215
+ "provider": "mistral",
216
+ "framework": "vllm",
217
+ "hardware": "a100",
218
+ "metrics": {
219
+ "ttft_ms": 40,
220
+ "p50_latency_ms": 180,
221
+ "p95_latency_ms": 320,
222
+ "p99_latency_ms": 480,
223
+ "throughput_tps": 150,
224
+ "cost_per_1k_input": 0.0,
225
+ "cost_per_1k_output": 0.0
226
+ },
227
+ "optimal_config": {
228
+ "tensor_parallelism": 2,
229
+ "max_model_len": 32768,
230
+ "gpu_memory_utilization": 0.9
231
+ },
232
+ "notes": "Self-hosted on 2xA100-80GB"
233
+ },
234
+ "deepseek-v3:api:api": {
235
+ "model": "deepseek-chat",
236
+ "provider": "deepseek",
237
+ "framework": "api",
238
+ "hardware": "api",
239
+ "metrics": {
240
+ "ttft_ms": 120,
241
+ "p50_latency_ms": 450,
242
+ "p95_latency_ms": 750,
243
+ "p99_latency_ms": 1100,
244
+ "throughput_tps": 65,
245
+ "cost_per_1k_input": 0.00014,
246
+ "cost_per_1k_output": 0.00028
247
+ },
248
+ "notes": "DeepSeek API baseline"
249
+ }
250
+ },
251
+ "model_aliases": {
252
+ "gpt-4o": "gpt-4o:api:api",
253
+ "gpt-4o-mini": "gpt-4o-mini:api:api",
254
+ "gpt-4-turbo": "gpt-4-turbo:api:api",
255
+ "claude-3-5-sonnet": "claude-3-5-sonnet:api:api",
256
+ "claude-3.5-sonnet": "claude-3-5-sonnet:api:api",
257
+ "claude-3-5-haiku": "claude-3-5-haiku:api:api",
258
+ "claude-3.5-haiku": "claude-3-5-haiku:api:api",
259
+ "claude-3-opus": "claude-3-opus:api:api",
260
+ "gemini-2.0-flash": "gemini-2.0-flash:api:api",
261
+ "gemini-flash": "gemini-2.0-flash:api:api",
262
+ "gemini-1.5-pro": "gemini-1.5-pro:api:api",
263
+ "gemini-pro": "gemini-1.5-pro:api:api",
264
+ "llama-3.1-70b": "llama-3.1-70b:vllm:h100",
265
+ "llama-70b": "llama-3.1-70b:vllm:h100",
266
+ "llama-3.1-8b": "llama-3.1-8b:vllm:a100",
267
+ "llama-8b": "llama-3.1-8b:vllm:a100",
268
+ "mistral-large": "mistral-large:api:api",
269
+ "mixtral-8x7b": "mixtral-8x7b:vllm:a100",
270
+ "mixtral": "mixtral-8x7b:vllm:a100",
271
+ "deepseek-v3": "deepseek-v3:api:api",
272
+ "deepseek": "deepseek-v3:api:api"
273
+ }
274
+ }
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Agent-based Semantic Analyzer for PeakInfer
3
+ *
4
+ * Uses Claude Agent SDK (per TDD v1.9.3) for multi-step code analysis:
5
+ * 1. Read source files
6
+ * 2. Extract patterns and variable assignments
7
+ * 3. Trace variable definitions to resolve model names
8
+ * 4. Identify actual LLM callsites (not client initialization)
9
+ *
10
+ * Architecture: Claude Agent SDK = Engine, TypeScript = Glue (per TDD §1)
11
+ */
12
+ import 'dotenv/config';
13
+ import type { ScanResult, Callsite, Patterns } from './types.js';
14
+ interface AgentCallsite {
15
+ file: string;
16
+ line: number;
17
+ provider: string | null;
18
+ model: string | null;
19
+ framework: string | null;
20
+ patterns: Partial<Patterns>;
21
+ confidence: number;
22
+ reasoning: string;
23
+ }
24
+ interface AgentInsight {
25
+ severity: 'critical' | 'warning' | 'info';
26
+ category: string;
27
+ headline: string;
28
+ evidence: string;
29
+ location: string;
30
+ recommendation?: string;
31
+ }
32
+ interface AgentAnalysisResult {
33
+ callsites: AgentCallsite[];
34
+ insights: AgentInsight[];
35
+ }
36
+ export declare function analyzeWithAgent(scanResult: ScanResult, options?: {
37
+ verbose?: boolean;
38
+ maxIterations?: number;
39
+ }): Promise<AgentAnalysisResult>;
40
+ /**
41
+ * Convert agent results to standard Callsite format
42
+ */
43
+ export declare function convertAgentCallsites(agentCallsites: AgentCallsite[]): Callsite[];
44
+ export {};
45
+ //# sourceMappingURL=agent-analyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-analyzer.d.ts","sourceRoot":"","sources":["../src/agent-analyzer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,eAAe,CAAC;AAMvB,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAY,QAAQ,EAAE,MAAM,YAAY,CAAC;AA4D3E,UAAU,aAAa;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,YAAY;IACpB,QAAQ,EAAE,UAAU,GAAG,SAAS,GAAG,MAAM,CAAC;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,UAAU,mBAAmB;IAC3B,SAAS,EAAE,aAAa,EAAE,CAAC;IAC3B,QAAQ,EAAE,YAAY,EAAE,CAAC;CAC1B;AA0MD,wBAAsB,gBAAgB,CACpC,UAAU,EAAE,UAAU,EACtB,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAO,GAC1D,OAAO,CAAC,mBAAmB,CAAC,CAiJ9B;AAcD;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,cAAc,EAAE,aAAa,EAAE,GAAG,QAAQ,EAAE,CAYjF"}
@@ -0,0 +1,374 @@
1
+ /**
2
+ * Agent-based Semantic Analyzer for PeakInfer
3
+ *
4
+ * Uses Claude Agent SDK (per TDD v1.9.3) for multi-step code analysis:
5
+ * 1. Read source files
6
+ * 2. Extract patterns and variable assignments
7
+ * 3. Trace variable definitions to resolve model names
8
+ * 4. Identify actual LLM callsites (not client initialization)
9
+ *
10
+ * Architecture: Claude Agent SDK = Engine, TypeScript = Glue (per TDD §1)
11
+ */
12
+ import 'dotenv/config';
13
+ import { query, tool, createSdkMcpServer } from '@anthropic-ai/claude-agent-sdk';
14
+ import { z } from 'zod';
15
+ import { readFileSync, existsSync } from 'fs';
16
+ import { join } from 'path';
17
+ import { createHash } from 'crypto';
18
+ import { loadPrompt, loadConfig, getConfiguredModel } from './templates.js';
19
+ // Load agent system prompt from YAML (with hardcoded fallback)
20
+ function getAgentSystemPrompt() {
21
+ const prompt = loadPrompt('agent-analyzer');
22
+ if (prompt) {
23
+ return prompt.prompt;
24
+ }
25
+ // Fallback to hardcoded prompt if YAML not available
26
+ return `You are an expert code analyst specializing in identifying LLM/AI inference points in source code.
27
+
28
+ Your task is to analyze code and find ALL actual LLM inference points with accurate provider and model information.
29
+
30
+ ## CRITICAL RULES
31
+
32
+ ### What IS an inference point (DO report these):
33
+ - client.chat.completions.create() - OpenAI API call
34
+ - client.messages.create() - Anthropic API call
35
+ - client.embeddings.create() - OpenAI embeddings call
36
+ - predictor(question=...) - DSPy module invocation (after dspy.Predict/ChainOfThought)
37
+ - chain.invoke() - LangChain invocation
38
+ - llm.generate() - Direct generation calls
39
+
40
+ ### What is NOT an inference point (DO NOT report these):
41
+ - Client initialization: openai.OpenAI(), anthropic.Anthropic()
42
+ - Import statements
43
+ - Variable assignments: model = "gpt-4o"
44
+ - Class/function definitions
45
+ - DSPy Predict/ChainOfThought creation (only report the invocation)
46
+
47
+ ### Model Extraction Rules:
48
+ 1. Look at the model= parameter in the function call
49
+ 2. Trace variables back to their definitions
50
+ 3. For DSPy: find dspy.LM("provider/model") and extract the model part
51
+ 4. Return the FULL exact model name (e.g., "gpt-4o-mini" not "gpt-4")
52
+
53
+ ### Framework Detection:
54
+ - DSPy: look for dspy imports, dspy.Predict, dspy.ChainOfThought
55
+ - LangChain: look for langchain imports, ChatOpenAI, LLMChain
56
+ - LlamaIndex: look for llama_index imports
57
+
58
+ ## WORKFLOW
59
+
60
+ 1. Use search_pattern to find potential inference point locations
61
+ 2. Use read_file to examine the code in detail
62
+ 3. Use trace_variable to find where models/clients are defined
63
+ 4. Use report_callsites to report your findings
64
+
65
+ Be thorough but precise. Only report actual inference points, not initialization or configuration.`;
66
+ }
67
+ // =============================================================================
68
+ // MCP TOOLS USING CLAUDE AGENT SDK
69
+ // =============================================================================
70
+ /**
71
+ * Helper to create ToolResult from string
72
+ */
73
+ function makeToolResult(text) {
74
+ return {
75
+ content: [{ type: 'text', text }],
76
+ };
77
+ }
78
+ /**
79
+ * Create MCP server with analysis tools using Claude Agent SDK
80
+ */
81
+ function createAnalysisMcpServer(ctx) {
82
+ // Tool: read_file - Read source code file contents
83
+ const readFileTool = tool('read_file', 'Read the contents of a source code file. Use this to examine code in detail.', {
84
+ file_path: z.string().describe('Relative path to the file from project root'),
85
+ }, async ({ file_path }) => {
86
+ // Try from cache first
87
+ if (ctx.fileContents.has(file_path)) {
88
+ const content = ctx.fileContents.get(file_path);
89
+ const numbered = content.split('\n')
90
+ .map((line, i) => `${i + 1}: ${line}`)
91
+ .join('\n');
92
+ return makeToolResult(numbered.slice(0, 8000)); // Limit size
93
+ }
94
+ // Try reading from disk
95
+ const absPath = join(ctx.projectRoot, file_path);
96
+ if (existsSync(absPath)) {
97
+ try {
98
+ const content = readFileSync(absPath, 'utf-8');
99
+ const numbered = content.split('\n')
100
+ .map((line, i) => `${i + 1}: ${line}`)
101
+ .join('\n');
102
+ return makeToolResult(numbered.slice(0, 8000));
103
+ }
104
+ catch (e) {
105
+ return makeToolResult(`Error reading file: ${e}`);
106
+ }
107
+ }
108
+ return makeToolResult(`File not found: ${file_path}`);
109
+ });
110
+ // Tool: search_pattern - Search for regex patterns across files
111
+ const searchPatternTool = tool('search_pattern', 'Search for a regex pattern across all source files. Returns matching lines with file and line number.', {
112
+ pattern: z.string().describe('Regex pattern to search for (e.g., "dspy\\.LM\\(" or "model\\s*=")'),
113
+ file_filter: z.string().optional().describe('Optional glob pattern to filter files (e.g., "*.py" or "*.ts")'),
114
+ }, async ({ pattern, file_filter }) => {
115
+ const results = [];
116
+ const regex = new RegExp(pattern, 'gi');
117
+ for (const [filePath, content] of ctx.fileContents) {
118
+ // Apply file filter if provided
119
+ if (file_filter && !filePath.match(new RegExp(file_filter.replace('*', '.*')))) {
120
+ continue;
121
+ }
122
+ const lines = content.split('\n');
123
+ for (let i = 0; i < lines.length; i++) {
124
+ if (regex.test(lines[i])) {
125
+ results.push(`${filePath}:${i + 1}: ${lines[i].trim().slice(0, 100)}`);
126
+ if (results.length >= 20)
127
+ break;
128
+ }
129
+ }
130
+ if (results.length >= 20)
131
+ break;
132
+ }
133
+ return makeToolResult(results.length > 0 ? results.join('\n') : 'No matches found');
134
+ });
135
+ // Tool: trace_variable - Find variable definitions and assignments
136
+ const traceVariableTool = tool('trace_variable', 'Find where a variable is defined or assigned in a file. Useful for tracing model names.', {
137
+ file_path: z.string().describe('File to search in'),
138
+ variable_name: z.string().describe('Variable name to trace (e.g., "model", "lm", "client")'),
139
+ }, async ({ file_path, variable_name }) => {
140
+ const content = ctx.fileContents.get(file_path);
141
+ if (!content) {
142
+ return makeToolResult(`File not found: ${file_path}`);
143
+ }
144
+ const results = [];
145
+ const lines = content.split('\n');
146
+ // Look for assignments and definitions
147
+ const patterns = [
148
+ new RegExp(`\\b${variable_name}\\s*=\\s*(.+)`, 'g'),
149
+ new RegExp(`\\bconst\\s+${variable_name}\\s*=\\s*(.+)`, 'g'),
150
+ new RegExp(`\\blet\\s+${variable_name}\\s*=\\s*(.+)`, 'g'),
151
+ new RegExp(`\\bvar\\s+${variable_name}\\s*=\\s*(.+)`, 'g'),
152
+ new RegExp(`\\bdef\\s+.*${variable_name}.*:`, 'g'),
153
+ new RegExp(`${variable_name}\\s*:\\s*(.+)`, 'g'),
154
+ ];
155
+ for (let i = 0; i < lines.length; i++) {
156
+ for (const p of patterns) {
157
+ if (p.test(lines[i])) {
158
+ results.push(`Line ${i + 1}: ${lines[i].trim()}`);
159
+ break;
160
+ }
161
+ }
162
+ }
163
+ return makeToolResult(results.length > 0
164
+ ? `Found ${results.length} references to "${variable_name}":\n${results.join('\n')}`
165
+ : `No definitions found for "${variable_name}"`);
166
+ });
167
+ // Tool: report_callsites - Report discovered LLM callsites
168
+ const reportCallsitesTool = tool('report_callsites', 'Report discovered LLM callsites. Call this when you have identified callsites with their details.', {
169
+ callsites: z.array(z.object({
170
+ file: z.string().describe('File path'),
171
+ line: z.number().describe('Line number of the actual inference call'),
172
+ provider: z.string().describe('Provider: openai, anthropic, google, etc.'),
173
+ model: z.string().optional().describe('Exact model name as found in code'),
174
+ framework: z.string().optional().describe('Framework: dspy, langchain, llamaindex, or null'),
175
+ reasoning: z.string().describe('Brief explanation of how you identified this'),
176
+ })).describe('Array of identified callsites'),
177
+ }, async ({ callsites }) => {
178
+ for (const cs of callsites) {
179
+ ctx.reportedCallsites.push({
180
+ file: cs.file,
181
+ line: cs.line,
182
+ provider: cs.provider || null,
183
+ model: cs.model || null,
184
+ framework: cs.framework || null,
185
+ patterns: {},
186
+ confidence: 0.9,
187
+ reasoning: cs.reasoning,
188
+ });
189
+ }
190
+ return makeToolResult(`Recorded ${callsites.length} callsites. Total: ${ctx.reportedCallsites.length}`);
191
+ });
192
+ // Create MCP server with all tools
193
+ return createSdkMcpServer({
194
+ name: 'peakinfer-analyzer',
195
+ version: '1.0.0',
196
+ tools: [readFileTool, searchPatternTool, traceVariableTool, reportCallsitesTool],
197
+ });
198
+ }
199
+ // =============================================================================
200
+ // AGENT LOOP USING CLAUDE AGENT SDK
201
+ // =============================================================================
202
+ // AGENT_SYSTEM_PROMPT is now loaded from prompts/agent-analyzer.yaml via getAgentSystemPrompt()
203
+ /**
204
+ * Extract text content from SDK messages
205
+ */
206
+ function extractTextFromMessages(messages) {
207
+ let text = '';
208
+ for (const msg of messages) {
209
+ if (msg.type === 'assistant' && msg.message?.content) {
210
+ for (const block of msg.message.content) {
211
+ if (block.type === 'text') {
212
+ text += block.text;
213
+ }
214
+ }
215
+ }
216
+ }
217
+ return text;
218
+ }
219
+ export async function analyzeWithAgent(scanResult, options = {}) {
220
+ // Load configuration
221
+ const config = loadConfig();
222
+ const { verbose = config.agent.verbose } = options;
223
+ // Check for API key
224
+ if (!process.env.ANTHROPIC_API_KEY) {
225
+ throw new Error('ANTHROPIC_API_KEY required for agent analysis');
226
+ }
227
+ // Build file contents map
228
+ const fileContents = new Map();
229
+ for (const file of scanResult.files) {
230
+ try {
231
+ const absPath = join(scanResult.root, file.path);
232
+ fileContents.set(file.path, readFileSync(absPath, 'utf-8'));
233
+ }
234
+ catch {
235
+ // Skip unreadable files
236
+ }
237
+ }
238
+ // Create tool context for shared state
239
+ const ctx = {
240
+ projectRoot: scanResult.root,
241
+ fileContents,
242
+ reportedCallsites: [],
243
+ };
244
+ // Create MCP server with analysis tools
245
+ const mcpServer = createAnalysisMcpServer(ctx);
246
+ // Build initial task with candidate info
247
+ const candidateInfo = scanResult.candidates
248
+ .map(c => `- ${c.file}:${c.line}: ${c.snippet}`)
249
+ .join('\n');
250
+ const fileList = scanResult.files.map(f => f.path).join('\n');
251
+ const prompt = `Analyze this codebase to identify all LLM inference callsites.
252
+
253
+ ## Files in project:
254
+ ${fileList}
255
+
256
+ ## Candidate locations (from regex scan):
257
+ ${candidateInfo}
258
+
259
+ ## Instructions:
260
+ 1. Start by examining the candidate files
261
+ 2. For each candidate, determine if it's a real callsite or false positive
262
+ 3. Look for callsites that the regex might have missed (especially framework calls)
263
+ 4. Trace variable assignments to find exact model names
264
+ 5. Report all confirmed callsites using the report_callsites tool
265
+
266
+ Begin your analysis.`;
267
+ if (verbose) {
268
+ console.log('[agent] Starting Claude Agent SDK analysis...');
269
+ }
270
+ // Get model from config
271
+ const model = getConfiguredModel('agent', false);
272
+ try {
273
+ // Use Claude Agent SDK query() function with MCP server
274
+ const agentQuery = query({
275
+ prompt,
276
+ options: {
277
+ systemPrompt: getAgentSystemPrompt(),
278
+ model,
279
+ mcpServers: {
280
+ 'peakinfer-analyzer': mcpServer,
281
+ },
282
+ permissionMode: 'default',
283
+ cwd: scanResult.root,
284
+ },
285
+ });
286
+ // Collect all messages from the agent
287
+ const messages = [];
288
+ for await (const message of agentQuery) {
289
+ messages.push(message);
290
+ if (verbose && message.type === 'assistant') {
291
+ // Log tool usage for debugging
292
+ if (message.message?.content) {
293
+ for (const block of message.message.content) {
294
+ if (block.type === 'tool_use') {
295
+ console.log(`[agent] Tool: ${block.name}`);
296
+ }
297
+ }
298
+ }
299
+ }
300
+ }
301
+ if (verbose) {
302
+ console.log('[agent] Analysis complete');
303
+ console.log(`[agent] Found ${ctx.reportedCallsites.length} callsites`);
304
+ }
305
+ return {
306
+ callsites: ctx.reportedCallsites,
307
+ insights: [],
308
+ };
309
+ }
310
+ catch (error) {
311
+ // If primary model fails, try fallback
312
+ const fallbackModel = getConfiguredModel('agent', true);
313
+ if (verbose) {
314
+ console.log(`[agent] ${model} failed, trying ${fallbackModel}`);
315
+ }
316
+ const agentQuery = query({
317
+ prompt,
318
+ options: {
319
+ systemPrompt: getAgentSystemPrompt(),
320
+ model: fallbackModel,
321
+ mcpServers: {
322
+ 'peakinfer-analyzer': mcpServer,
323
+ },
324
+ permissionMode: 'default',
325
+ cwd: scanResult.root,
326
+ },
327
+ });
328
+ for await (const message of agentQuery) {
329
+ if (verbose && message.type === 'assistant') {
330
+ if (message.message?.content) {
331
+ for (const block of message.message.content) {
332
+ if (block.type === 'tool_use') {
333
+ console.log(`[agent] Tool: ${block.name}`);
334
+ }
335
+ }
336
+ }
337
+ }
338
+ }
339
+ if (verbose) {
340
+ console.log('[agent] Analysis complete (fallback)');
341
+ }
342
+ return {
343
+ callsites: ctx.reportedCallsites,
344
+ insights: [],
345
+ };
346
+ }
347
+ }
348
+ // =============================================================================
349
+ // INTEGRATION HELPER
350
+ // =============================================================================
351
+ function generateCallsiteId(file, line) {
352
+ const hash = createHash('sha256')
353
+ .update(`${file}:${line}`)
354
+ .digest('hex')
355
+ .slice(0, 8);
356
+ return `cs_${hash}`;
357
+ }
358
+ /**
359
+ * Convert agent results to standard Callsite format
360
+ */
361
+ export function convertAgentCallsites(agentCallsites) {
362
+ return agentCallsites.map(ac => ({
363
+ id: generateCallsiteId(ac.file, ac.line),
364
+ file: ac.file,
365
+ line: ac.line,
366
+ provider: ac.provider,
367
+ model: ac.model,
368
+ framework: ac.framework,
369
+ runtime: null,
370
+ patterns: ac.patterns,
371
+ confidence: ac.confidence,
372
+ }));
373
+ }
374
+ //# sourceMappingURL=agent-analyzer.js.map