@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,394 @@
1
+ #!/usr/bin/env npx tsx
2
+ /**
3
+ * PeakInfer Performance Benchmark Suite
4
+ *
5
+ * Validates response time requirements from CLAUDE.md:
6
+ * - Static analysis (small repo): < 3s (max 5s)
7
+ * - Static analysis (large repo): < 10s (max 15s)
8
+ * - Runtime correlation: < 2s (max 5s)
9
+ * - PR comment generation: < 5s (max 10s)
10
+ *
11
+ * Usage:
12
+ * npx tsx scripts/benchmark.ts
13
+ * npx tsx scripts/benchmark.ts --json
14
+ * npx tsx scripts/benchmark.ts --ci # Exit non-zero if targets missed
15
+ */
16
+
17
+ import { performance } from 'perf_hooks';
18
+ import { execSync, spawn } from 'child_process';
19
+ import { mkdirSync, writeFileSync, rmSync, existsSync, readdirSync, statSync } from 'fs';
20
+ import { join, dirname } from 'path';
21
+ import { fileURLToPath } from 'url';
22
+
23
+ const __dirname = dirname(fileURLToPath(import.meta.url));
24
+ const ROOT = join(__dirname, '..');
25
+
26
+ // =============================================================================
27
+ // CONFIGURATION
28
+ // =============================================================================
29
+
30
+ interface BenchmarkTarget {
31
+ name: string;
32
+ target: number; // Target time in ms
33
+ max: number; // Maximum acceptable time in ms
34
+ }
35
+
36
+ const TARGETS: Record<string, BenchmarkTarget> = {
37
+ 'static-small': { name: 'Static analysis (small repo)', target: 3000, max: 5000 },
38
+ 'static-large': { name: 'Static analysis (large repo)', target: 10000, max: 15000 },
39
+ 'runtime-correlation': { name: 'Runtime correlation', target: 2000, max: 5000 },
40
+ 'pr-comment': { name: 'PR comment generation', target: 5000, max: 10000 },
41
+ };
42
+
43
+ interface BenchmarkResult {
44
+ name: string;
45
+ duration: number;
46
+ target: number;
47
+ max: number;
48
+ status: 'pass' | 'warn' | 'fail';
49
+ iterations: number;
50
+ }
51
+
52
+ // =============================================================================
53
+ // TEST FIXTURES
54
+ // =============================================================================
55
+
56
+ function createSmallRepo(dir: string): void {
57
+ mkdirSync(join(dir, 'src'), { recursive: true });
58
+
59
+ // 3 files with LLM inference points
60
+ writeFileSync(join(dir, 'src', 'chat.ts'), `
61
+ import Anthropic from '@anthropic-ai/sdk';
62
+
63
+ const client = new Anthropic();
64
+
65
+ export async function chat(message: string) {
66
+ const response = await client.messages.create({
67
+ model: 'claude-3-5-sonnet-20241022',
68
+ max_tokens: 1024,
69
+ messages: [{ role: 'user', content: message }],
70
+ });
71
+ return response;
72
+ }
73
+ `);
74
+
75
+ writeFileSync(join(dir, 'src', 'summarize.ts'), `
76
+ import OpenAI from 'openai';
77
+
78
+ const openai = new OpenAI();
79
+
80
+ export async function summarize(text: string) {
81
+ const response = await openai.chat.completions.create({
82
+ model: 'gpt-4o',
83
+ messages: [{ role: 'user', content: \`Summarize: \${text}\` }],
84
+ stream: true,
85
+ });
86
+ return response;
87
+ }
88
+ `);
89
+
90
+ writeFileSync(join(dir, 'src', 'classify.py'), `
91
+ from openai import OpenAI
92
+
93
+ client = OpenAI()
94
+
95
+ def classify(text: str) -> str:
96
+ response = client.chat.completions.create(
97
+ model="gpt-4o-mini",
98
+ messages=[{"role": "user", "content": f"Classify: {text}"}],
99
+ )
100
+ return response.choices[0].message.content
101
+ `);
102
+ }
103
+
104
+ function createLargeRepo(dir: string): void {
105
+ mkdirSync(join(dir, 'src/services'), { recursive: true });
106
+ mkdirSync(join(dir, 'src/agents'), { recursive: true });
107
+ mkdirSync(join(dir, 'src/pipelines'), { recursive: true });
108
+ mkdirSync(join(dir, 'lib'), { recursive: true });
109
+
110
+ // Generate 20+ files with inference points
111
+ const providers = ['openai', 'anthropic'];
112
+ const models = ['gpt-4o', 'gpt-4o-mini', 'claude-3-5-sonnet-20241022', 'claude-3-opus'];
113
+
114
+ for (let i = 0; i < 25; i++) {
115
+ const provider = providers[i % providers.length];
116
+ const model = models[i % models.length];
117
+
118
+ if (provider === 'openai') {
119
+ writeFileSync(join(dir, 'src/services', `service-${i}.ts`), `
120
+ import OpenAI from 'openai';
121
+ const client = new OpenAI();
122
+
123
+ export async function process${i}(input: string) {
124
+ const response = await client.chat.completions.create({
125
+ model: '${model}',
126
+ messages: [{ role: 'user', content: input }],
127
+ ${i % 3 === 0 ? 'stream: true,' : ''}
128
+ max_tokens: ${500 + i * 100},
129
+ });
130
+ return response;
131
+ }
132
+
133
+ export async function batch${i}(inputs: string[]) {
134
+ const results = await Promise.all(inputs.map(async (input) => {
135
+ return client.chat.completions.create({
136
+ model: '${model}',
137
+ messages: [{ role: 'user', content: input }],
138
+ });
139
+ }));
140
+ return results;
141
+ }
142
+ `);
143
+ } else {
144
+ writeFileSync(join(dir, 'src/agents', `agent-${i}.ts`), `
145
+ import Anthropic from '@anthropic-ai/sdk';
146
+ const anthropic = new Anthropic();
147
+
148
+ export async function agent${i}(prompt: string) {
149
+ const message = await anthropic.messages.create({
150
+ model: '${model}',
151
+ max_tokens: ${1024 + i * 50},
152
+ messages: [{ role: 'user', content: prompt }],
153
+ });
154
+ return message;
155
+ }
156
+
157
+ export class Agent${i} {
158
+ async run(input: string) {
159
+ const response = await anthropic.messages.create({
160
+ model: '${model}',
161
+ max_tokens: 2048,
162
+ ${i % 2 === 0 ? "stream: true," : ""}
163
+ messages: [{ role: 'user', content: input }],
164
+ });
165
+ return response;
166
+ }
167
+ }
168
+ `);
169
+ }
170
+ }
171
+
172
+ // Add Python files
173
+ for (let i = 0; i < 10; i++) {
174
+ writeFileSync(join(dir, 'src/pipelines', `pipeline_${i}.py`), `
175
+ from openai import OpenAI
176
+ from anthropic import Anthropic
177
+
178
+ openai_client = OpenAI()
179
+ anthropic_client = Anthropic()
180
+
181
+ def pipeline_${i}(data: list) -> list:
182
+ results = []
183
+ for item in data:
184
+ response = openai_client.chat.completions.create(
185
+ model="gpt-4o",
186
+ messages=[{"role": "user", "content": str(item)}],
187
+ )
188
+ results.append(response.choices[0].message.content)
189
+ return results
190
+
191
+ async def async_pipeline_${i}(data: list):
192
+ response = anthropic_client.messages.create(
193
+ model="claude-3-5-sonnet-20241022",
194
+ max_tokens=1024,
195
+ messages=[{"role": "user", "content": str(data)}],
196
+ )
197
+ return response
198
+ `);
199
+ }
200
+ }
201
+
202
+ function createRuntimeEvents(dir: string, count: number): string {
203
+ const eventsPath = join(dir, 'events.jsonl');
204
+ const events: string[] = [];
205
+
206
+ const models = ['gpt-4o', 'gpt-4o-mini', 'claude-3-5-sonnet-20241022'];
207
+ const providers = ['openai', 'openai', 'anthropic'];
208
+
209
+ for (let i = 0; i < count; i++) {
210
+ const modelIdx = i % models.length;
211
+ events.push(JSON.stringify({
212
+ id: `evt_${i.toString().padStart(6, '0')}`,
213
+ ts: new Date(Date.now() - (count - i) * 60000).toISOString(),
214
+ provider: providers[modelIdx],
215
+ model: models[modelIdx],
216
+ input_tokens: 100 + Math.floor(Math.random() * 500),
217
+ output_tokens: 50 + Math.floor(Math.random() * 200),
218
+ latency_ms: 500 + Math.floor(Math.random() * 2000),
219
+ }));
220
+ }
221
+
222
+ writeFileSync(eventsPath, events.join('\n'));
223
+ return eventsPath;
224
+ }
225
+
226
+ // =============================================================================
227
+ // BENCHMARK RUNNER
228
+ // =============================================================================
229
+
230
+ async function runBenchmark(
231
+ name: string,
232
+ command: string,
233
+ args: string[],
234
+ iterations: number = 3
235
+ ): Promise<BenchmarkResult> {
236
+ const target = TARGETS[name];
237
+ const times: number[] = [];
238
+
239
+ for (let i = 0; i < iterations; i++) {
240
+ const start = performance.now();
241
+
242
+ await new Promise<void>((resolve, reject) => {
243
+ const proc = spawn(command, args, {
244
+ cwd: ROOT,
245
+ stdio: 'pipe',
246
+ env: { ...process.env, PEAKINFER_BENCHMARK: '1' },
247
+ });
248
+
249
+ proc.on('close', (code) => {
250
+ if (code === 0 || code === null) {
251
+ resolve();
252
+ } else {
253
+ // Allow non-zero exit for demo mode without API key
254
+ resolve();
255
+ }
256
+ });
257
+
258
+ proc.on('error', reject);
259
+ });
260
+
261
+ const duration = performance.now() - start;
262
+ times.push(duration);
263
+ }
264
+
265
+ // Use median time
266
+ times.sort((a, b) => a - b);
267
+ const median = times[Math.floor(times.length / 2)];
268
+
269
+ let status: 'pass' | 'warn' | 'fail';
270
+ if (median <= target.target) {
271
+ status = 'pass';
272
+ } else if (median <= target.max) {
273
+ status = 'warn';
274
+ } else {
275
+ status = 'fail';
276
+ }
277
+
278
+ return {
279
+ name: target.name,
280
+ duration: Math.round(median),
281
+ target: target.target,
282
+ max: target.max,
283
+ status,
284
+ iterations,
285
+ };
286
+ }
287
+
288
+ // =============================================================================
289
+ // MAIN
290
+ // =============================================================================
291
+
292
+ async function main() {
293
+ const args = process.argv.slice(2);
294
+ const jsonOutput = args.includes('--json');
295
+ const ciMode = args.includes('--ci');
296
+
297
+ const tempDir = join(ROOT, '.benchmark-temp');
298
+
299
+ // Cleanup
300
+ if (existsSync(tempDir)) {
301
+ rmSync(tempDir, { recursive: true });
302
+ }
303
+ mkdirSync(tempDir, { recursive: true });
304
+
305
+ const smallRepo = join(tempDir, 'small-repo');
306
+ const largeRepo = join(tempDir, 'large-repo');
307
+ mkdirSync(smallRepo);
308
+ mkdirSync(largeRepo);
309
+
310
+ if (!jsonOutput) {
311
+ console.log('PeakInfer Performance Benchmark');
312
+ console.log('================================\n');
313
+ console.log('Creating test fixtures...');
314
+ }
315
+
316
+ createSmallRepo(smallRepo);
317
+ createLargeRepo(largeRepo);
318
+ const eventsPath = createRuntimeEvents(tempDir, 500);
319
+
320
+ if (!jsonOutput) {
321
+ console.log('Running benchmarks...\n');
322
+ }
323
+
324
+ const results: BenchmarkResult[] = [];
325
+
326
+ // Static analysis - small repo (using demo mode for offline testing)
327
+ results.push(await runBenchmark(
328
+ 'static-small',
329
+ 'npx',
330
+ ['tsx', join(ROOT, 'src/cli.ts'), 'analyze', smallRepo, '--output', 'json'],
331
+ 3
332
+ ));
333
+
334
+ // Static analysis - large repo
335
+ results.push(await runBenchmark(
336
+ 'static-large',
337
+ 'npx',
338
+ ['tsx', join(ROOT, 'src/cli.ts'), 'analyze', largeRepo, '--output', 'json'],
339
+ 3
340
+ ));
341
+
342
+ // Runtime correlation
343
+ results.push(await runBenchmark(
344
+ 'runtime-correlation',
345
+ 'npx',
346
+ ['tsx', join(ROOT, 'src/cli.ts'), 'analyze', smallRepo, '--events', eventsPath, '--output', 'json'],
347
+ 3
348
+ ));
349
+
350
+ // PR comment generation (simulated via json output)
351
+ results.push(await runBenchmark(
352
+ 'pr-comment',
353
+ 'npx',
354
+ ['tsx', join(ROOT, 'src/cli.ts'), 'analyze', smallRepo, '--output', 'json', '--fixes'],
355
+ 3
356
+ ));
357
+
358
+ // Cleanup
359
+ rmSync(tempDir, { recursive: true });
360
+
361
+ // Output results
362
+ if (jsonOutput) {
363
+ console.log(JSON.stringify({ benchmarks: results, timestamp: new Date().toISOString() }, null, 2));
364
+ } else {
365
+ console.log('Results');
366
+ console.log('-------\n');
367
+
368
+ const statusSymbols = { pass: '✅', warn: '⚠️', fail: '❌' };
369
+
370
+ for (const result of results) {
371
+ const symbol = statusSymbols[result.status];
372
+ const pct = Math.round((result.duration / result.target) * 100);
373
+ console.log(`${symbol} ${result.name}`);
374
+ console.log(` Duration: ${result.duration}ms (target: ${result.target}ms, max: ${result.max}ms)`);
375
+ console.log(` Status: ${result.status.toUpperCase()} (${pct}% of target)`);
376
+ console.log('');
377
+ }
378
+
379
+ console.log('Summary');
380
+ console.log('-------');
381
+ const passed = results.filter(r => r.status === 'pass').length;
382
+ const warned = results.filter(r => r.status === 'warn').length;
383
+ const failed = results.filter(r => r.status === 'fail').length;
384
+ console.log(`Passed: ${passed}, Warnings: ${warned}, Failed: ${failed}`);
385
+ }
386
+
387
+ // CI mode exit code
388
+ if (ciMode) {
389
+ const failed = results.some(r => r.status === 'fail');
390
+ process.exit(failed ? 1 : 0);
391
+ }
392
+ }
393
+
394
+ main().catch(console.error);
@@ -0,0 +1,158 @@
1
+ #!/bin/bash
2
+ #
3
+ # PeakInfer v1.5 Feature Demo Script
4
+ #
5
+ # This script demonstrates all the v1.5 features:
6
+ # - History Storage
7
+ # - Historical Comparison (--compare)
8
+ # - Deploy-Time Prediction (--predict)
9
+ # - Counterfactual Insights
10
+ # - Updated Output Ordering
11
+ #
12
+ # Usage: ./scripts/demo-v1.5.sh [project-path]
13
+ #
14
+
15
+ set -e
16
+
17
+ # Colors for output
18
+ RED='\033[0;31m'
19
+ GREEN='\033[0;32m'
20
+ YELLOW='\033[1;33m'
21
+ BLUE='\033[0;34m'
22
+ NC='\033[0m' # No Color
23
+
24
+ # Get project path (default to current directory)
25
+ PROJECT_PATH="${1:-.}"
26
+
27
+ echo -e "${BLUE}╔══════════════════════════════════════════════════════════════╗${NC}"
28
+ echo -e "${BLUE}║ PeakInfer v1.5 Feature Demo ║${NC}"
29
+ echo -e "${BLUE}╚══════════════════════════════════════════════════════════════╝${NC}"
30
+ echo ""
31
+
32
+ # Check if peakinfer is installed
33
+ if ! command -v peakinfer &> /dev/null; then
34
+ echo -e "${RED}Error: peakinfer not found. Install with: npm install -g @kalmantic/peakinfer${NC}"
35
+ exit 1
36
+ fi
37
+
38
+ # Show version
39
+ echo -e "${GREEN}Version:${NC}"
40
+ peakinfer --version
41
+ echo ""
42
+
43
+ # ============================================================================
44
+ # Demo 1: Basic Analysis (History Storage)
45
+ # ============================================================================
46
+ echo -e "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
47
+ echo -e "${YELLOW}Demo 1: Basic Analysis (creates history entry)${NC}"
48
+ echo -e "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
49
+ echo ""
50
+ echo -e "${BLUE}Command:${NC} peakinfer analyze $PROJECT_PATH"
51
+ echo ""
52
+ read -p "Press Enter to run..." </dev/tty
53
+
54
+ peakinfer analyze "$PROJECT_PATH" || true
55
+
56
+ echo ""
57
+ echo -e "${GREEN}✓ Analysis complete. History saved to .peakinfer/history/${NC}"
58
+ echo ""
59
+
60
+ # ============================================================================
61
+ # Demo 2: Historical Comparison
62
+ # ============================================================================
63
+ echo -e "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
64
+ echo -e "${YELLOW}Demo 2: Historical Comparison (--compare)${NC}"
65
+ echo -e "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
66
+ echo ""
67
+ echo -e "${BLUE}Command:${NC} peakinfer analyze $PROJECT_PATH --compare"
68
+ echo ""
69
+ echo "This compares current analysis with the most recent previous run."
70
+ echo "Shows: added/removed/modified inference points, new issues resolved."
71
+ echo ""
72
+ read -p "Press Enter to run..." </dev/tty
73
+
74
+ peakinfer analyze "$PROJECT_PATH" --compare || true
75
+
76
+ echo ""
77
+
78
+ # ============================================================================
79
+ # Demo 3: Deploy-Time Prediction
80
+ # ============================================================================
81
+ echo -e "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
82
+ echo -e "${YELLOW}Demo 3: Deploy-Time Prediction (--predict)${NC}"
83
+ echo -e "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
84
+ echo ""
85
+ echo -e "${BLUE}Command:${NC} peakinfer analyze $PROJECT_PATH --predict --target-p95 2000"
86
+ echo ""
87
+ echo "This generates latency predictions for each inference point."
88
+ echo "Shows: risk levels, predicted p95/p99 latencies, budget check."
89
+ echo ""
90
+ read -p "Press Enter to run..." </dev/tty
91
+
92
+ peakinfer analyze "$PROJECT_PATH" --predict --target-p95 2000 || true
93
+
94
+ echo ""
95
+
96
+ # ============================================================================
97
+ # Demo 4: Full Analysis with All Features
98
+ # ============================================================================
99
+ echo -e "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
100
+ echo -e "${YELLOW}Demo 4: Full Analysis (comparison + prediction + HTML)${NC}"
101
+ echo -e "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
102
+ echo ""
103
+ echo -e "${BLUE}Command:${NC} peakinfer analyze $PROJECT_PATH --compare --predict --target-p95 3000 --html"
104
+ echo ""
105
+ echo "This runs a complete analysis with all v1.5 features enabled."
106
+ echo "Output order: Comparison → Prediction → Counterfactuals → Drift → Details"
107
+ echo ""
108
+ read -p "Press Enter to run..." </dev/tty
109
+
110
+ peakinfer analyze "$PROJECT_PATH" --compare --predict --target-p95 3000 --html || true
111
+
112
+ echo ""
113
+
114
+ # ============================================================================
115
+ # Demo 5: Skip History (for quick checks)
116
+ # ============================================================================
117
+ echo -e "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
118
+ echo -e "${YELLOW}Demo 5: Skip History Storage (--no-history)${NC}"
119
+ echo -e "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
120
+ echo ""
121
+ echo -e "${BLUE}Command:${NC} peakinfer analyze $PROJECT_PATH --no-history"
122
+ echo ""
123
+ echo "Use --no-history for quick checks that don't need tracking."
124
+ echo ""
125
+ read -p "Press Enter to run..." </dev/tty
126
+
127
+ peakinfer analyze "$PROJECT_PATH" --no-history || true
128
+
129
+ echo ""
130
+
131
+ # ============================================================================
132
+ # Summary
133
+ # ============================================================================
134
+ echo -e "${BLUE}╔══════════════════════════════════════════════════════════════╗${NC}"
135
+ echo -e "${BLUE}║ Demo Complete! ║${NC}"
136
+ echo -e "${BLUE}╚══════════════════════════════════════════════════════════════╝${NC}"
137
+ echo ""
138
+ echo -e "${GREEN}v1.5 Features Demonstrated:${NC}"
139
+ echo ""
140
+ echo " 1. History Storage - Automatic run tracking"
141
+ echo " 2. --compare [runId] - See what changed since last run"
142
+ echo " 3. --predict - Get latency risk predictions"
143
+ echo " 4. --target-p95 <ms> - Set latency budget"
144
+ echo " 5. --no-history - Skip history for quick checks"
145
+ echo " 6. Counterfactuals - Always shows optimization opportunities"
146
+ echo " 7. Updated Output - Decision-relevant info first"
147
+ echo ""
148
+ echo -e "${YELLOW}Key Benefits:${NC}"
149
+ echo ""
150
+ echo " - Pre-deploy validation: --predict surfaces risks before deploy"
151
+ echo " - Optimization insights: Counterfactuals show optimization ideas"
152
+ echo " - Change tracking: --compare shows what changed since last run"
153
+ echo ""
154
+ echo -e "${BLUE}Try these commands:${NC}"
155
+ echo ""
156
+ echo " peakinfer analyze . --compare --predict --target-p95 2000"
157
+ echo " peakinfer analyze . --events logs.jsonl --compare --html --open"
158
+ echo ""