perf-skill 0.0.1 → 0.2.1

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 (120) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +404 -0
  3. package/SKILL.md +238 -0
  4. package/dist/cli/init.d.ts +29 -0
  5. package/dist/cli/init.d.ts.map +1 -0
  6. package/dist/cli/init.js +139 -0
  7. package/dist/cli/init.js.map +1 -0
  8. package/dist/cli/main.d.ts +6 -0
  9. package/dist/cli/main.d.ts.map +1 -0
  10. package/dist/cli/main.js +389 -0
  11. package/dist/cli/main.js.map +1 -0
  12. package/dist/cli/options.d.ts +37 -0
  13. package/dist/cli/options.d.ts.map +1 -0
  14. package/dist/cli/options.js +54 -0
  15. package/dist/cli/options.js.map +1 -0
  16. package/dist/convert/converter.d.ts +39 -0
  17. package/dist/convert/converter.d.ts.map +1 -0
  18. package/dist/convert/converter.js +99 -0
  19. package/dist/convert/converter.js.map +1 -0
  20. package/dist/convert/extract.d.ts +32 -0
  21. package/dist/convert/extract.d.ts.map +1 -0
  22. package/dist/convert/extract.js +235 -0
  23. package/dist/convert/extract.js.map +1 -0
  24. package/dist/convert/index.d.ts +7 -0
  25. package/dist/convert/index.d.ts.map +1 -0
  26. package/dist/convert/index.js +7 -0
  27. package/dist/convert/index.js.map +1 -0
  28. package/dist/convert/sanitize.d.ts +60 -0
  29. package/dist/convert/sanitize.d.ts.map +1 -0
  30. package/dist/convert/sanitize.js +169 -0
  31. package/dist/convert/sanitize.js.map +1 -0
  32. package/dist/diff/engine.d.ts +76 -0
  33. package/dist/diff/engine.d.ts.map +1 -0
  34. package/dist/diff/engine.js +386 -0
  35. package/dist/diff/engine.js.map +1 -0
  36. package/dist/diff/index.d.ts +6 -0
  37. package/dist/diff/index.d.ts.map +1 -0
  38. package/dist/diff/index.js +6 -0
  39. package/dist/diff/index.js.map +1 -0
  40. package/dist/diff/markdown.d.ts +16 -0
  41. package/dist/diff/markdown.d.ts.map +1 -0
  42. package/dist/diff/markdown.js +342 -0
  43. package/dist/diff/markdown.js.map +1 -0
  44. package/dist/index.d.ts +52 -0
  45. package/dist/index.d.ts.map +1 -0
  46. package/dist/index.js +247 -0
  47. package/dist/index.js.map +1 -0
  48. package/dist/llm/client.d.ts +39 -0
  49. package/dist/llm/client.d.ts.map +1 -0
  50. package/dist/llm/client.js +270 -0
  51. package/dist/llm/client.js.map +1 -0
  52. package/dist/llm/index.d.ts +8 -0
  53. package/dist/llm/index.d.ts.map +1 -0
  54. package/dist/llm/index.js +8 -0
  55. package/dist/llm/index.js.map +1 -0
  56. package/dist/llm/prompt.d.ts +32 -0
  57. package/dist/llm/prompt.d.ts.map +1 -0
  58. package/dist/llm/prompt.js +146 -0
  59. package/dist/llm/prompt.js.map +1 -0
  60. package/dist/llm/schema.d.ts +150 -0
  61. package/dist/llm/schema.d.ts.map +1 -0
  62. package/dist/llm/schema.js +131 -0
  63. package/dist/llm/schema.js.map +1 -0
  64. package/dist/llm/validate.d.ts +33 -0
  65. package/dist/llm/validate.d.ts.map +1 -0
  66. package/dist/llm/validate.js +241 -0
  67. package/dist/llm/validate.js.map +1 -0
  68. package/dist/profile/duration.d.ts +2 -0
  69. package/dist/profile/duration.d.ts.map +1 -0
  70. package/dist/profile/duration.js +24 -0
  71. package/dist/profile/duration.js.map +1 -0
  72. package/dist/profile/preload.d.ts +2 -0
  73. package/dist/profile/preload.d.ts.map +1 -0
  74. package/dist/profile/preload.js +100 -0
  75. package/dist/profile/preload.js.map +1 -0
  76. package/dist/profile/runner.d.ts +22 -0
  77. package/dist/profile/runner.d.ts.map +1 -0
  78. package/dist/profile/runner.js +88 -0
  79. package/dist/profile/runner.js.map +1 -0
  80. package/dist/server/http.d.ts +27 -0
  81. package/dist/server/http.d.ts.map +1 -0
  82. package/dist/server/http.js +285 -0
  83. package/dist/server/http.js.map +1 -0
  84. package/dist/server/utils.d.ts +15 -0
  85. package/dist/server/utils.d.ts.map +1 -0
  86. package/dist/server/utils.js +71 -0
  87. package/dist/server/utils.js.map +1 -0
  88. package/dist/skill/handler.d.ts +77 -0
  89. package/dist/skill/handler.d.ts.map +1 -0
  90. package/dist/skill/handler.js +91 -0
  91. package/dist/skill/handler.js.map +1 -0
  92. package/dist/skill/index.d.ts +6 -0
  93. package/dist/skill/index.d.ts.map +1 -0
  94. package/dist/skill/index.js +6 -0
  95. package/dist/skill/index.js.map +1 -0
  96. package/dist/skill/manifest.d.ts +17 -0
  97. package/dist/skill/manifest.d.ts.map +1 -0
  98. package/dist/skill/manifest.js +231 -0
  99. package/dist/skill/manifest.js.map +1 -0
  100. package/dist/types.d.ts +260 -0
  101. package/dist/types.d.ts.map +1 -0
  102. package/dist/types.js +5 -0
  103. package/dist/types.js.map +1 -0
  104. package/dist/utils/fs.d.ts +52 -0
  105. package/dist/utils/fs.d.ts.map +1 -0
  106. package/dist/utils/fs.js +106 -0
  107. package/dist/utils/fs.js.map +1 -0
  108. package/dist/utils/index.d.ts +7 -0
  109. package/dist/utils/index.d.ts.map +1 -0
  110. package/dist/utils/index.js +7 -0
  111. package/dist/utils/index.js.map +1 -0
  112. package/dist/utils/limits.d.ts +38 -0
  113. package/dist/utils/limits.d.ts.map +1 -0
  114. package/dist/utils/limits.js +86 -0
  115. package/dist/utils/limits.js.map +1 -0
  116. package/dist/utils/logger.d.ts +21 -0
  117. package/dist/utils/logger.d.ts.map +1 -0
  118. package/dist/utils/logger.js +82 -0
  119. package/dist/utils/logger.js.map +1 -0
  120. package/package.json +70 -6
@@ -0,0 +1,146 @@
1
+ /**
2
+ * LLM prompt templates for performance analysis
3
+ */
4
+ /**
5
+ * System prompt for performance analysis
6
+ */
7
+ export const SYSTEM_PROMPT = `You are a senior performance engineer specializing in Node.js/JavaScript performance optimization.
8
+
9
+ Your task is to analyze pprof profiling reports and provide actionable recommendations.
10
+
11
+ CRITICAL RULES:
12
+ 1. ONLY use evidence present in the report (function names, percentages, file locations, call paths)
13
+ 2. Do NOT invent or hallucinate file paths, line numbers, or function names that are not in the report
14
+ 3. Every recommendation MUST reference specific evidence from the report
15
+ 4. Be conservative with confidence scores - only high confidence if evidence is strong
16
+ 5. Distinguish between CPU and heap (memory) analysis - they require different strategies
17
+
18
+ For CPU profiles, focus on:
19
+ - Functions with high self-time (flat) - these are doing actual work
20
+ - Functions with high cumulative time - these may be bottleneck entry points
21
+ - Recursive or repeated call patterns
22
+ - Native functions that suggest slow operations (JSON.parse, regex, etc.)
23
+
24
+ For Heap profiles, focus on:
25
+ - Functions with high allocation rates
26
+ - Potential memory leaks (retained objects growing over time)
27
+ - Inefficient data structures
28
+ - Objects that could be pooled or reused
29
+
30
+ Always structure your response as valid JSON matching the provided schema.`;
31
+ /**
32
+ * Build analysis prompt for a single profile
33
+ */
34
+ export function buildAnalysisPrompt(args) {
35
+ const contextSection = args.context
36
+ ? `## Analysis Context
37
+
38
+ - **Service:** ${args.context.serviceName || "Unknown"}
39
+ - **Scenario:** ${args.context.scenario || "Not specified"}
40
+ - **Target SLO:** ${args.context.targetSLO || "Not specified"}
41
+ - **Environment:** ${args.context.env || "Not specified"}
42
+ ${args.context.recentChanges ? `- **Recent Changes:** ${args.context.recentChanges}` : ""}
43
+ `
44
+ : "";
45
+ const profileTypeHint = args.profileType !== "auto"
46
+ ? `\n**Profile Type:** ${args.profileType.toUpperCase()}\n`
47
+ : "";
48
+ return `${contextSection}${profileTypeHint}
49
+ ## Profiling Report
50
+
51
+ Analyze the following pprof Markdown report and produce a structured JSON analysis.
52
+
53
+ \`\`\`markdown
54
+ ${args.markdown}
55
+ \`\`\`
56
+
57
+ ## Required Output
58
+
59
+ Provide a JSON object with:
60
+ 1. **summary**: One paragraph executive summary of findings
61
+ 2. **recommendations**: Array of actionable recommendations (1-5 items), each with:
62
+ - title: Short action title
63
+ - rationale: Explanation with specific evidence from report
64
+ - steps: Concrete implementation steps
65
+ - expectedImpact: high/medium/low
66
+ - risk: high/medium/low
67
+ - confidence: 0-1 based on evidence quality
68
+ 3. **nextSteps**: Array of validation experiments or metrics to track
69
+
70
+ Remember: Only reference functions, percentages, and locations that appear in the report above.`;
71
+ }
72
+ /**
73
+ * Build prompt for diff analysis
74
+ */
75
+ export function buildDiffAnalysisPrompt(args) {
76
+ const contextSection = args.context
77
+ ? `## Analysis Context
78
+
79
+ - **Service:** ${args.context.serviceName || "Unknown"}
80
+ - **Scenario:** ${args.context.scenario || "Not specified"}
81
+ - **Target SLO:** ${args.context.targetSLO || "Not specified"}
82
+ - **Environment:** ${args.context.env || "Not specified"}
83
+ ${args.context.recentChanges ? `- **Recent Changes:** ${args.context.recentChanges}` : ""}
84
+ `
85
+ : "";
86
+ return `${contextSection}
87
+ ## Performance Comparison Report
88
+
89
+ Analyze the following profile comparison report and explain why performance changed.
90
+
91
+ \`\`\`markdown
92
+ ${args.markdown}
93
+ \`\`\`
94
+
95
+ ## Required Output
96
+
97
+ Provide a JSON object with:
98
+ 1. **summary**: Executive summary of the performance change
99
+ 2. **overallChange**: "regression" | "improvement" | "mixed" | "unchanged"
100
+ 3. **primaryCause**: Main cause of the change (if identifiable)
101
+ 4. **regressionAnalysis**: For each major regression, explain:
102
+ - function: The function name
103
+ - explanation: Why it got slower
104
+ - likelyCause: "new_code" | "increased_calls" | "slower_callees" | "data_change" | "unknown"
105
+ 5. **recommendations**: Top 1-3 actionable fixes for regressions
106
+ 6. **riskAssessment**: Risk if this change goes to production
107
+
108
+ Focus on the DELTA values and call path changes to identify root causes.`;
109
+ }
110
+ /**
111
+ * Build repair prompt when LLM output fails validation
112
+ */
113
+ export function buildRepairPrompt(originalOutput, errors) {
114
+ return `Your previous response had JSON validation errors:
115
+
116
+ ${errors.map((e) => `- ${e}`).join("\n")}
117
+
118
+ Original response:
119
+ \`\`\`json
120
+ ${originalOutput}
121
+ \`\`\`
122
+
123
+ Please fix the JSON to match the required schema. Common fixes:
124
+ - Ensure all required fields are present
125
+ - Ensure arrays have at least 1 item where required
126
+ - Ensure numbers are within valid ranges (confidence: 0-1)
127
+ - Ensure enums use valid values
128
+
129
+ Return ONLY the corrected JSON, no explanation.`;
130
+ }
131
+ /**
132
+ * Build prompt for quick triage (shorter, faster)
133
+ */
134
+ export function buildTriagePrompt(markdown) {
135
+ return `Quick triage of this profile:
136
+
137
+ ${markdown}
138
+
139
+ In 2-3 sentences, identify:
140
+ 1. The #1 optimization opportunity
141
+ 2. Estimated effort (easy/medium/hard)
142
+ 3. Expected impact (high/medium/low)
143
+
144
+ Be direct and specific.`;
145
+ }
146
+ //# sourceMappingURL=prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/llm/prompt.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH;;GAEG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;2EAuB8C,CAAC;AAE5E;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAInC;IACC,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO;QACjC,CAAC,CAAC;;iBAEW,IAAI,CAAC,OAAO,CAAC,WAAW,IAAI,SAAS;kBACpC,IAAI,CAAC,OAAO,CAAC,QAAQ,IAAI,eAAe;oBACtC,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,eAAe;qBACxC,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI,eAAe;EACtD,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,yBAAyB,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE;CACxF;QACG,CAAC,CAAC,EAAE,CAAC;IAEP,MAAM,eAAe,GAAG,IAAI,CAAC,WAAW,KAAK,MAAM;QACjD,CAAC,CAAC,uBAAuB,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE,IAAI;QAC3D,CAAC,CAAC,EAAE,CAAC;IAEP,OAAO,GAAG,cAAc,GAAG,eAAe;;;;;;EAM1C,IAAI,CAAC,QAAQ;;;;;;;;;;;;;;;;gGAgBiF,CAAC;AACjG,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,uBAAuB,CAAC,IAGvC;IACC,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO;QACjC,CAAC,CAAC;;iBAEW,IAAI,CAAC,OAAO,CAAC,WAAW,IAAI,SAAS;kBACpC,IAAI,CAAC,OAAO,CAAC,QAAQ,IAAI,eAAe;oBACtC,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,eAAe;qBACxC,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI,eAAe;EACtD,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,yBAAyB,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE;CACxF;QACG,CAAC,CAAC,EAAE,CAAC;IAEP,OAAO,GAAG,cAAc;;;;;;EAMxB,IAAI,CAAC,QAAQ;;;;;;;;;;;;;;;;yEAgB0D,CAAC;AAC1E,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAC/B,cAAsB,EACtB,MAAgB;IAEhB,OAAO;;EAEP,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;;;;EAItC,cAAc;;;;;;;;;gDASgC,CAAC;AACjD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAAgB;IAChD,OAAO;;EAEP,QAAQ;;;;;;;wBAOc,CAAC;AACzB,CAAC"}
@@ -0,0 +1,150 @@
1
+ /**
2
+ * Zod schemas for LLM output validation
3
+ */
4
+ import { z } from "zod";
5
+ /**
6
+ * Hotspot analysis from LLM
7
+ */
8
+ export declare const HotspotAnalysisSchema: z.ZodObject<{
9
+ rank: z.ZodNumber;
10
+ function: z.ZodString;
11
+ rootCause: z.ZodOptional<z.ZodString>;
12
+ callPathAnalysis: z.ZodOptional<z.ZodString>;
13
+ optimizationPotential: z.ZodOptional<z.ZodEnum<{
14
+ high: "high";
15
+ medium: "medium";
16
+ low: "low";
17
+ }>>;
18
+ }, z.core.$strip>;
19
+ export type HotspotAnalysis = z.infer<typeof HotspotAnalysisSchema>;
20
+ /**
21
+ * Recommendation from LLM
22
+ */
23
+ export declare const RecommendationSchema: z.ZodObject<{
24
+ title: z.ZodString;
25
+ rationale: z.ZodString;
26
+ steps: z.ZodArray<z.ZodString>;
27
+ expectedImpact: z.ZodEnum<{
28
+ high: "high";
29
+ medium: "medium";
30
+ low: "low";
31
+ }>;
32
+ risk: z.ZodEnum<{
33
+ high: "high";
34
+ medium: "medium";
35
+ low: "low";
36
+ }>;
37
+ confidence: z.ZodNumber;
38
+ relatedHotspots: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
39
+ }, z.core.$strip>;
40
+ export type Recommendation = z.infer<typeof RecommendationSchema>;
41
+ /**
42
+ * Full LLM analysis output
43
+ */
44
+ export declare const AnalysisOutputSchema: z.ZodObject<{
45
+ summary: z.ZodString;
46
+ profileType: z.ZodOptional<z.ZodEnum<{
47
+ cpu: "cpu";
48
+ heap: "heap";
49
+ }>>;
50
+ hotspotAnalysis: z.ZodOptional<z.ZodArray<z.ZodObject<{
51
+ rank: z.ZodNumber;
52
+ function: z.ZodString;
53
+ rootCause: z.ZodOptional<z.ZodString>;
54
+ callPathAnalysis: z.ZodOptional<z.ZodString>;
55
+ optimizationPotential: z.ZodOptional<z.ZodEnum<{
56
+ high: "high";
57
+ medium: "medium";
58
+ low: "low";
59
+ }>>;
60
+ }, z.core.$strip>>>;
61
+ recommendations: z.ZodArray<z.ZodObject<{
62
+ title: z.ZodString;
63
+ rationale: z.ZodString;
64
+ steps: z.ZodArray<z.ZodString>;
65
+ expectedImpact: z.ZodEnum<{
66
+ high: "high";
67
+ medium: "medium";
68
+ low: "low";
69
+ }>;
70
+ risk: z.ZodEnum<{
71
+ high: "high";
72
+ medium: "medium";
73
+ low: "low";
74
+ }>;
75
+ confidence: z.ZodNumber;
76
+ relatedHotspots: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
77
+ }, z.core.$strip>>;
78
+ nextSteps: z.ZodArray<z.ZodString>;
79
+ caveats: z.ZodOptional<z.ZodArray<z.ZodString>>;
80
+ }, z.core.$strip>;
81
+ export type AnalysisOutput = z.infer<typeof AnalysisOutputSchema>;
82
+ /**
83
+ * Diff analysis output from LLM
84
+ */
85
+ export declare const DiffAnalysisOutputSchema: z.ZodObject<{
86
+ summary: z.ZodString;
87
+ overallChange: z.ZodEnum<{
88
+ regression: "regression";
89
+ improvement: "improvement";
90
+ mixed: "mixed";
91
+ unchanged: "unchanged";
92
+ }>;
93
+ changePercentage: z.ZodOptional<z.ZodNumber>;
94
+ primaryCause: z.ZodOptional<z.ZodString>;
95
+ regressionAnalysis: z.ZodOptional<z.ZodArray<z.ZodObject<{
96
+ function: z.ZodString;
97
+ explanation: z.ZodString;
98
+ likelyCause: z.ZodEnum<{
99
+ unknown: "unknown";
100
+ new_code: "new_code";
101
+ increased_calls: "increased_calls";
102
+ slower_callees: "slower_callees";
103
+ data_change: "data_change";
104
+ }>;
105
+ }, z.core.$strip>>>;
106
+ improvementAnalysis: z.ZodOptional<z.ZodArray<z.ZodObject<{
107
+ function: z.ZodString;
108
+ explanation: z.ZodString;
109
+ }, z.core.$strip>>>;
110
+ recommendations: z.ZodArray<z.ZodObject<{
111
+ title: z.ZodString;
112
+ rationale: z.ZodString;
113
+ steps: z.ZodArray<z.ZodString>;
114
+ expectedImpact: z.ZodEnum<{
115
+ high: "high";
116
+ medium: "medium";
117
+ low: "low";
118
+ }>;
119
+ risk: z.ZodEnum<{
120
+ high: "high";
121
+ medium: "medium";
122
+ low: "low";
123
+ }>;
124
+ confidence: z.ZodNumber;
125
+ relatedHotspots: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
126
+ }, z.core.$strip>>;
127
+ riskAssessment: z.ZodOptional<z.ZodString>;
128
+ }, z.core.$strip>;
129
+ export type DiffAnalysisOutput = z.infer<typeof DiffAnalysisOutputSchema>;
130
+ /**
131
+ * Validate LLM output against schema
132
+ */
133
+ export declare function validateAnalysisOutput(data: unknown): {
134
+ success: boolean;
135
+ data?: AnalysisOutput;
136
+ errors?: string[];
137
+ };
138
+ /**
139
+ * Validate diff analysis output
140
+ */
141
+ export declare function validateDiffAnalysisOutput(data: unknown): {
142
+ success: boolean;
143
+ data?: DiffAnalysisOutput;
144
+ errors?: string[];
145
+ };
146
+ /**
147
+ * Get JSON Schema from Zod schema (for LLM function calling)
148
+ */
149
+ export declare function getAnalysisJsonSchema(): object;
150
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/llm/schema.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;GAEG;AACH,eAAO,MAAM,qBAAqB;;;;;;;;;;iBAMhC,CAAC;AAEH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE;;GAEG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;iBAQ/B,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE;;GAEG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAO/B,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE;;GAEG;AACH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAgBnC,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,OAAO,GAAG;IACrD,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB,CAUA;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,OAAO,GAAG;IACzD,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,kBAAkB,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB,CAUA;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CAyC9C"}
@@ -0,0 +1,131 @@
1
+ /**
2
+ * Zod schemas for LLM output validation
3
+ */
4
+ import { z } from "zod";
5
+ /**
6
+ * Hotspot analysis from LLM
7
+ */
8
+ export const HotspotAnalysisSchema = z.object({
9
+ rank: z.number().int().positive(),
10
+ function: z.string(),
11
+ rootCause: z.string().optional().describe("Likely root cause of high CPU/memory usage"),
12
+ callPathAnalysis: z.string().optional().describe("Analysis of the call path leading to this hotspot"),
13
+ optimizationPotential: z.enum(["high", "medium", "low"]).optional(),
14
+ });
15
+ /**
16
+ * Recommendation from LLM
17
+ */
18
+ export const RecommendationSchema = z.object({
19
+ title: z.string().max(100).describe("Short, actionable title"),
20
+ rationale: z.string().describe("Explanation with evidence from the report (function names, percentages, locations)"),
21
+ steps: z.array(z.string()).min(1).max(10).describe("Concrete action steps"),
22
+ expectedImpact: z.enum(["high", "medium", "low"]).describe("Expected performance improvement"),
23
+ risk: z.enum(["high", "medium", "low"]).describe("Implementation risk"),
24
+ confidence: z.number().min(0).max(1).describe("Confidence level (0-1) based on evidence quality"),
25
+ relatedHotspots: z.array(z.number()).optional().describe("Related hotspot ranks"),
26
+ });
27
+ /**
28
+ * Full LLM analysis output
29
+ */
30
+ export const AnalysisOutputSchema = z.object({
31
+ summary: z.string().max(500).describe("One paragraph executive summary"),
32
+ profileType: z.enum(["cpu", "heap"]).optional(),
33
+ hotspotAnalysis: z.array(HotspotAnalysisSchema).optional(),
34
+ recommendations: z.array(RecommendationSchema).min(1).max(10),
35
+ nextSteps: z.array(z.string()).max(5).describe("Validation experiments or metrics to track"),
36
+ caveats: z.array(z.string()).optional().describe("Limitations or uncertainties in the analysis"),
37
+ });
38
+ /**
39
+ * Diff analysis output from LLM
40
+ */
41
+ export const DiffAnalysisOutputSchema = z.object({
42
+ summary: z.string().max(500).describe("Executive summary of the performance change"),
43
+ overallChange: z.enum(["regression", "improvement", "mixed", "unchanged"]),
44
+ changePercentage: z.number().optional().describe("Overall change as percentage"),
45
+ primaryCause: z.string().optional().describe("Primary cause of the change"),
46
+ regressionAnalysis: z.array(z.object({
47
+ function: z.string(),
48
+ explanation: z.string().describe("Why this function got slower"),
49
+ likelyCause: z.enum(["new_code", "increased_calls", "slower_callees", "data_change", "unknown"]),
50
+ })).optional(),
51
+ improvementAnalysis: z.array(z.object({
52
+ function: z.string(),
53
+ explanation: z.string().describe("Why this function improved"),
54
+ })).optional(),
55
+ recommendations: z.array(RecommendationSchema).max(5),
56
+ riskAssessment: z.string().optional().describe("Risk if this change goes to production"),
57
+ });
58
+ /**
59
+ * Validate LLM output against schema
60
+ */
61
+ export function validateAnalysisOutput(data) {
62
+ const result = AnalysisOutputSchema.safeParse(data);
63
+ if (result.success) {
64
+ return { success: true, data: result.data };
65
+ }
66
+ const issues = result.error.issues;
67
+ return {
68
+ success: false,
69
+ errors: issues.map((e) => `${e.path.join(".")}: ${e.message}`),
70
+ };
71
+ }
72
+ /**
73
+ * Validate diff analysis output
74
+ */
75
+ export function validateDiffAnalysisOutput(data) {
76
+ const result = DiffAnalysisOutputSchema.safeParse(data);
77
+ if (result.success) {
78
+ return { success: true, data: result.data };
79
+ }
80
+ const issues = result.error.issues;
81
+ return {
82
+ success: false,
83
+ errors: issues.map((e) => `${e.path.join(".")}: ${e.message}`),
84
+ };
85
+ }
86
+ /**
87
+ * Get JSON Schema from Zod schema (for LLM function calling)
88
+ */
89
+ export function getAnalysisJsonSchema() {
90
+ return {
91
+ type: "object",
92
+ properties: {
93
+ summary: { type: "string", maxLength: 500 },
94
+ profileType: { type: "string", enum: ["cpu", "heap"] },
95
+ hotspotAnalysis: {
96
+ type: "array",
97
+ items: {
98
+ type: "object",
99
+ properties: {
100
+ rank: { type: "integer" },
101
+ function: { type: "string" },
102
+ rootCause: { type: "string" },
103
+ callPathAnalysis: { type: "string" },
104
+ optimizationPotential: { type: "string", enum: ["high", "medium", "low"] },
105
+ },
106
+ required: ["rank", "function"],
107
+ },
108
+ },
109
+ recommendations: {
110
+ type: "array",
111
+ items: {
112
+ type: "object",
113
+ properties: {
114
+ title: { type: "string", maxLength: 100 },
115
+ rationale: { type: "string" },
116
+ steps: { type: "array", items: { type: "string" } },
117
+ expectedImpact: { type: "string", enum: ["high", "medium", "low"] },
118
+ risk: { type: "string", enum: ["high", "medium", "low"] },
119
+ confidence: { type: "number", minimum: 0, maximum: 1 },
120
+ relatedHotspots: { type: "array", items: { type: "integer" } },
121
+ },
122
+ required: ["title", "rationale", "steps", "expectedImpact", "risk", "confidence"],
123
+ },
124
+ },
125
+ nextSteps: { type: "array", items: { type: "string" } },
126
+ caveats: { type: "array", items: { type: "string" } },
127
+ },
128
+ required: ["summary", "recommendations", "nextSteps"],
129
+ };
130
+ }
131
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/llm/schema.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;GAEG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5C,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IACjC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;IACpB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,4CAA4C,CAAC;IACvF,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mDAAmD,CAAC;IACrG,qBAAqB,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,QAAQ,EAAE;CACpE,CAAC,CAAC;AAIH;;GAEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,yBAAyB,CAAC;IAC9D,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oFAAoF,CAAC;IACpH,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,uBAAuB,CAAC;IAC3E,cAAc,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,kCAAkC,CAAC;IAC9F,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,qBAAqB,CAAC;IACvE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,kDAAkD,CAAC;IACjG,eAAe,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,uBAAuB,CAAC;CAClF,CAAC,CAAC;AAIH;;GAEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,iCAAiC,CAAC;IACxE,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE;IAC/C,eAAe,EAAE,CAAC,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC,QAAQ,EAAE;IAC1D,eAAe,EAAE,CAAC,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;IAC7D,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,4CAA4C,CAAC;IAC5F,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,8CAA8C,CAAC;CACjG,CAAC,CAAC;AAIH;;GAEG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/C,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,6CAA6C,CAAC;IACpF,aAAa,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,aAAa,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;IAC1E,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,8BAA8B,CAAC;IAChF,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,6BAA6B,CAAC;IAC3E,kBAAkB,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;QACnC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;QACpB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,8BAA8B,CAAC;QAChE,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,aAAa,EAAE,SAAS,CAAC,CAAC;KACjG,CAAC,CAAC,CAAC,QAAQ,EAAE;IACd,mBAAmB,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;QACpC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;QACpB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,4BAA4B,CAAC;KAC/D,CAAC,CAAC,CAAC,QAAQ,EAAE;IACd,eAAe,EAAE,CAAC,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACrD,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,wCAAwC,CAAC;CACzF,CAAC,CAAC;AAIH;;GAEG;AACH,MAAM,UAAU,sBAAsB,CAAC,IAAa;IAKlD,MAAM,MAAM,GAAG,oBAAoB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACpD,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;IAC9C,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC;IACnC,OAAO;QACL,OAAO,EAAE,KAAK;QACd,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;KAC/D,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,0BAA0B,CAAC,IAAa;IAKtD,MAAM,MAAM,GAAG,wBAAwB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACxD,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;IAC9C,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC;IACnC,OAAO;QACL,OAAO,EAAE,KAAK;QACd,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;KAC/D,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB;IACnC,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,EAAE;YAC3C,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE;YACtD,eAAe,EAAE;gBACf,IAAI,EAAE,OAAO;gBACb,KAAK,EAAE;oBACL,IAAI,EAAE,QAAQ;oBACd,UAAU,EAAE;wBACV,IAAI,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;wBACzB,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;wBAC5B,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;wBAC7B,gBAAgB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;wBACpC,qBAAqB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE;qBAC3E;oBACD,QAAQ,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC;iBAC/B;aACF;YACD,eAAe,EAAE;gBACf,IAAI,EAAE,OAAO;gBACb,KAAK,EAAE;oBACL,IAAI,EAAE,QAAQ;oBACd,UAAU,EAAE;wBACV,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,EAAE;wBACzC,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;wBAC7B,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;wBACnD,cAAc,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE;wBACnE,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE;wBACzD,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE;wBACtD,eAAe,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE;qBAC/D;oBACD,QAAQ,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,YAAY,CAAC;iBAClF;aACF;YACD,SAAS,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;YACvD,OAAO,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;SACtD;QACD,QAAQ,EAAE,CAAC,SAAS,EAAE,iBAAiB,EAAE,WAAW,CAAC;KACtD,CAAC;AACJ,CAAC"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * LLM output validation and repair
3
+ */
4
+ import type { LLMClient } from "./client.js";
5
+ import { type AnalysisOutput, type DiffAnalysisOutput } from "./schema.js";
6
+ export interface ParseResult<T> {
7
+ success: boolean;
8
+ data?: T;
9
+ rawJson?: unknown;
10
+ errors?: string[];
11
+ repairAttempted?: boolean;
12
+ }
13
+ /**
14
+ * Try to repair common JSON issues
15
+ */
16
+ export declare function repairJson(input: string): string;
17
+ /**
18
+ * Parse and validate analysis output from LLM
19
+ */
20
+ export declare function parseAnalysisOutput(rawContent: string, client?: LLMClient): Promise<ParseResult<AnalysisOutput>>;
21
+ /**
22
+ * Parse and validate diff analysis output
23
+ */
24
+ export declare function parseDiffAnalysisOutput(rawContent: string, client?: LLMClient): Promise<ParseResult<DiffAnalysisOutput>>;
25
+ /**
26
+ * Create a fallback result when LLM analysis fails
27
+ */
28
+ export declare function createFallbackResult(hotspots: Array<{
29
+ rank: number;
30
+ function: string;
31
+ selfPct?: number;
32
+ }>): AnalysisOutput;
33
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/llm/validate.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAe,MAAM,aAAa,CAAC;AAE1D,OAAO,EAGL,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACxB,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CA8BhD;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,UAAU,EAAE,MAAM,EAClB,MAAM,CAAC,EAAE,SAAS,GACjB,OAAO,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC,CAkDtC;AAED;;GAEG;AACH,wBAAsB,uBAAuB,CAC3C,UAAU,EAAE,MAAM,EAClB,MAAM,CAAC,EAAE,SAAS,GACjB,OAAO,CAAC,WAAW,CAAC,kBAAkB,CAAC,CAAC,CAmC1C;AA8GD;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GACpE,cAAc,CA6BhB"}