perf-skill 0.0.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +414 -0
- package/SKILL.md +238 -0
- package/dist/cli/main.d.ts +6 -0
- package/dist/cli/main.d.ts.map +1 -0
- package/dist/cli/main.js +353 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/cli/options.d.ts +37 -0
- package/dist/cli/options.d.ts.map +1 -0
- package/dist/cli/options.js +54 -0
- package/dist/cli/options.js.map +1 -0
- package/dist/convert/converter.d.ts +39 -0
- package/dist/convert/converter.d.ts.map +1 -0
- package/dist/convert/converter.js +99 -0
- package/dist/convert/converter.js.map +1 -0
- package/dist/convert/extract.d.ts +32 -0
- package/dist/convert/extract.d.ts.map +1 -0
- package/dist/convert/extract.js +235 -0
- package/dist/convert/extract.js.map +1 -0
- package/dist/convert/index.d.ts +7 -0
- package/dist/convert/index.d.ts.map +1 -0
- package/dist/convert/index.js +7 -0
- package/dist/convert/index.js.map +1 -0
- package/dist/convert/sanitize.d.ts +60 -0
- package/dist/convert/sanitize.d.ts.map +1 -0
- package/dist/convert/sanitize.js +169 -0
- package/dist/convert/sanitize.js.map +1 -0
- package/dist/diff/engine.d.ts +76 -0
- package/dist/diff/engine.d.ts.map +1 -0
- package/dist/diff/engine.js +386 -0
- package/dist/diff/engine.js.map +1 -0
- package/dist/diff/index.d.ts +6 -0
- package/dist/diff/index.d.ts.map +1 -0
- package/dist/diff/index.js +6 -0
- package/dist/diff/index.js.map +1 -0
- package/dist/diff/markdown.d.ts +16 -0
- package/dist/diff/markdown.d.ts.map +1 -0
- package/dist/diff/markdown.js +342 -0
- package/dist/diff/markdown.js.map +1 -0
- package/dist/index.d.ts +52 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +247 -0
- package/dist/index.js.map +1 -0
- package/dist/llm/client.d.ts +39 -0
- package/dist/llm/client.d.ts.map +1 -0
- package/dist/llm/client.js +270 -0
- package/dist/llm/client.js.map +1 -0
- package/dist/llm/index.d.ts +8 -0
- package/dist/llm/index.d.ts.map +1 -0
- package/dist/llm/index.js +8 -0
- package/dist/llm/index.js.map +1 -0
- package/dist/llm/prompt.d.ts +32 -0
- package/dist/llm/prompt.d.ts.map +1 -0
- package/dist/llm/prompt.js +146 -0
- package/dist/llm/prompt.js.map +1 -0
- package/dist/llm/schema.d.ts +150 -0
- package/dist/llm/schema.d.ts.map +1 -0
- package/dist/llm/schema.js +131 -0
- package/dist/llm/schema.js.map +1 -0
- package/dist/llm/validate.d.ts +33 -0
- package/dist/llm/validate.d.ts.map +1 -0
- package/dist/llm/validate.js +241 -0
- package/dist/llm/validate.js.map +1 -0
- package/dist/profile/duration.d.ts +2 -0
- package/dist/profile/duration.d.ts.map +1 -0
- package/dist/profile/duration.js +24 -0
- package/dist/profile/duration.js.map +1 -0
- package/dist/profile/preload.d.ts +2 -0
- package/dist/profile/preload.d.ts.map +1 -0
- package/dist/profile/preload.js +100 -0
- package/dist/profile/preload.js.map +1 -0
- package/dist/profile/runner.d.ts +22 -0
- package/dist/profile/runner.d.ts.map +1 -0
- package/dist/profile/runner.js +88 -0
- package/dist/profile/runner.js.map +1 -0
- package/dist/server/http.d.ts +27 -0
- package/dist/server/http.d.ts.map +1 -0
- package/dist/server/http.js +285 -0
- package/dist/server/http.js.map +1 -0
- package/dist/server/utils.d.ts +15 -0
- package/dist/server/utils.d.ts.map +1 -0
- package/dist/server/utils.js +71 -0
- package/dist/server/utils.js.map +1 -0
- package/dist/skill/handler.d.ts +77 -0
- package/dist/skill/handler.d.ts.map +1 -0
- package/dist/skill/handler.js +91 -0
- package/dist/skill/handler.js.map +1 -0
- package/dist/skill/index.d.ts +6 -0
- package/dist/skill/index.d.ts.map +1 -0
- package/dist/skill/index.js +6 -0
- package/dist/skill/index.js.map +1 -0
- package/dist/skill/manifest.d.ts +17 -0
- package/dist/skill/manifest.d.ts.map +1 -0
- package/dist/skill/manifest.js +231 -0
- package/dist/skill/manifest.js.map +1 -0
- package/dist/types.d.ts +260 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/fs.d.ts +52 -0
- package/dist/utils/fs.d.ts.map +1 -0
- package/dist/utils/fs.js +106 -0
- package/dist/utils/fs.js.map +1 -0
- package/dist/utils/index.d.ts +7 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +7 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/limits.d.ts +38 -0
- package/dist/utils/limits.d.ts.map +1 -0
- package/dist/utils/limits.js +86 -0
- package/dist/utils/limits.js.map +1 -0
- package/dist/utils/logger.d.ts +21 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +82 -0
- package/dist/utils/logger.js.map +1 -0
- package/package.json +70 -6
|
@@ -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":"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"}
|
|
@@ -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"}
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LLM output validation and repair
|
|
3
|
+
*/
|
|
4
|
+
import { logger } from "../utils/logger.js";
|
|
5
|
+
import { SYSTEM_PROMPT, buildRepairPrompt } from "./prompt.js";
|
|
6
|
+
import { validateAnalysisOutput, validateDiffAnalysisOutput, } from "./schema.js";
|
|
7
|
+
/**
|
|
8
|
+
* Try to repair common JSON issues
|
|
9
|
+
*/
|
|
10
|
+
export function repairJson(input) {
|
|
11
|
+
let json = input.trim();
|
|
12
|
+
// Extract JSON from markdown code blocks
|
|
13
|
+
const codeBlockMatch = json.match(/```(?:json)?\s*([\s\S]*?)```/);
|
|
14
|
+
if (codeBlockMatch) {
|
|
15
|
+
json = codeBlockMatch[1].trim();
|
|
16
|
+
}
|
|
17
|
+
// Remove trailing commas before } or ]
|
|
18
|
+
json = json.replace(/,\s*([\]}])/g, "$1");
|
|
19
|
+
// Fix unquoted keys (simple cases)
|
|
20
|
+
json = json.replace(/([{,]\s*)([a-zA-Z_][a-zA-Z0-9_]*)\s*:/g, '$1"$2":');
|
|
21
|
+
// Fix single quotes to double quotes
|
|
22
|
+
json = json.replace(/'/g, '"');
|
|
23
|
+
// Try to fix unterminated strings (very basic)
|
|
24
|
+
const lines = json.split("\n");
|
|
25
|
+
const fixedLines = lines.map((line) => {
|
|
26
|
+
const colonMatch = line.match(/:\s*"([^"]*?)$/);
|
|
27
|
+
if (colonMatch && !line.trim().endsWith(",") && !line.trim().endsWith("}") && !line.trim().endsWith("]")) {
|
|
28
|
+
return line + '"';
|
|
29
|
+
}
|
|
30
|
+
return line;
|
|
31
|
+
});
|
|
32
|
+
json = fixedLines.join("\n");
|
|
33
|
+
return json;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Parse and validate analysis output from LLM
|
|
37
|
+
*/
|
|
38
|
+
export async function parseAnalysisOutput(rawContent, client) {
|
|
39
|
+
// Try to parse as-is
|
|
40
|
+
let json;
|
|
41
|
+
let parseError;
|
|
42
|
+
try {
|
|
43
|
+
json = JSON.parse(rawContent);
|
|
44
|
+
}
|
|
45
|
+
catch (e) {
|
|
46
|
+
parseError = e instanceof Error ? e.message : String(e);
|
|
47
|
+
// Try repair
|
|
48
|
+
try {
|
|
49
|
+
const repaired = repairJson(rawContent);
|
|
50
|
+
json = JSON.parse(repaired);
|
|
51
|
+
logger.debug("JSON repair successful");
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
logger.warn("JSON repair failed", { originalError: parseError });
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (!json) {
|
|
58
|
+
return {
|
|
59
|
+
success: false,
|
|
60
|
+
errors: [`Failed to parse JSON: ${parseError}`],
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
// Validate against schema
|
|
64
|
+
const validation = validateAnalysisOutput(json);
|
|
65
|
+
if (validation.success) {
|
|
66
|
+
return {
|
|
67
|
+
success: true,
|
|
68
|
+
data: validation.data,
|
|
69
|
+
rawJson: json,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
logger.warn("LLM output validation failed", { errors: validation.errors });
|
|
73
|
+
// Try LLM repair if client available
|
|
74
|
+
if (client && validation.errors) {
|
|
75
|
+
return attemptLLMRepair(rawContent, validation.errors, client);
|
|
76
|
+
}
|
|
77
|
+
return {
|
|
78
|
+
success: false,
|
|
79
|
+
rawJson: json,
|
|
80
|
+
errors: validation.errors,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Parse and validate diff analysis output
|
|
85
|
+
*/
|
|
86
|
+
export async function parseDiffAnalysisOutput(rawContent, client) {
|
|
87
|
+
let json;
|
|
88
|
+
try {
|
|
89
|
+
json = JSON.parse(rawContent);
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
try {
|
|
93
|
+
json = JSON.parse(repairJson(rawContent));
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
return {
|
|
97
|
+
success: false,
|
|
98
|
+
errors: ["Failed to parse JSON"],
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
const validation = validateDiffAnalysisOutput(json);
|
|
103
|
+
if (validation.success) {
|
|
104
|
+
return {
|
|
105
|
+
success: true,
|
|
106
|
+
data: validation.data,
|
|
107
|
+
rawJson: json,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
if (client && validation.errors) {
|
|
111
|
+
return attemptLLMRepairDiff(rawContent, validation.errors, client);
|
|
112
|
+
}
|
|
113
|
+
return {
|
|
114
|
+
success: false,
|
|
115
|
+
rawJson: json,
|
|
116
|
+
errors: validation.errors,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Attempt to repair output using LLM
|
|
121
|
+
*/
|
|
122
|
+
async function attemptLLMRepair(originalOutput, errors, client) {
|
|
123
|
+
logger.info("Attempting LLM repair of validation errors");
|
|
124
|
+
const messages = [
|
|
125
|
+
{ role: "system", content: SYSTEM_PROMPT },
|
|
126
|
+
{ role: "user", content: buildRepairPrompt(originalOutput, errors) },
|
|
127
|
+
];
|
|
128
|
+
try {
|
|
129
|
+
const response = await client.chat(messages, { jsonMode: true });
|
|
130
|
+
let json;
|
|
131
|
+
try {
|
|
132
|
+
json = JSON.parse(response.content);
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
json = JSON.parse(repairJson(response.content));
|
|
136
|
+
}
|
|
137
|
+
const validation = validateAnalysisOutput(json);
|
|
138
|
+
if (validation.success) {
|
|
139
|
+
logger.info("LLM repair successful");
|
|
140
|
+
return {
|
|
141
|
+
success: true,
|
|
142
|
+
data: validation.data,
|
|
143
|
+
rawJson: json,
|
|
144
|
+
repairAttempted: true,
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
logger.warn("LLM repair still has validation errors", { errors: validation.errors });
|
|
148
|
+
return {
|
|
149
|
+
success: false,
|
|
150
|
+
rawJson: json,
|
|
151
|
+
errors: validation.errors,
|
|
152
|
+
repairAttempted: true,
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
catch (error) {
|
|
156
|
+
logger.error("LLM repair request failed", {
|
|
157
|
+
error: error instanceof Error ? error.message : String(error),
|
|
158
|
+
});
|
|
159
|
+
return {
|
|
160
|
+
success: false,
|
|
161
|
+
errors: [...errors, `Repair attempt failed: ${error}`],
|
|
162
|
+
repairAttempted: true,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Attempt to repair diff output using LLM
|
|
168
|
+
*/
|
|
169
|
+
async function attemptLLMRepairDiff(originalOutput, errors, client) {
|
|
170
|
+
logger.info("Attempting LLM repair of diff validation errors");
|
|
171
|
+
const messages = [
|
|
172
|
+
{ role: "system", content: SYSTEM_PROMPT },
|
|
173
|
+
{ role: "user", content: buildRepairPrompt(originalOutput, errors) },
|
|
174
|
+
];
|
|
175
|
+
try {
|
|
176
|
+
const response = await client.chat(messages, { jsonMode: true });
|
|
177
|
+
let json;
|
|
178
|
+
try {
|
|
179
|
+
json = JSON.parse(response.content);
|
|
180
|
+
}
|
|
181
|
+
catch {
|
|
182
|
+
json = JSON.parse(repairJson(response.content));
|
|
183
|
+
}
|
|
184
|
+
const validation = validateDiffAnalysisOutput(json);
|
|
185
|
+
if (validation.success) {
|
|
186
|
+
logger.info("LLM diff repair successful");
|
|
187
|
+
return {
|
|
188
|
+
success: true,
|
|
189
|
+
data: validation.data,
|
|
190
|
+
rawJson: json,
|
|
191
|
+
repairAttempted: true,
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
return {
|
|
195
|
+
success: false,
|
|
196
|
+
rawJson: json,
|
|
197
|
+
errors: validation.errors,
|
|
198
|
+
repairAttempted: true,
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
catch (error) {
|
|
202
|
+
return {
|
|
203
|
+
success: false,
|
|
204
|
+
errors: [...errors, `Repair attempt failed: ${error}`],
|
|
205
|
+
repairAttempted: true,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Create a fallback result when LLM analysis fails
|
|
211
|
+
*/
|
|
212
|
+
export function createFallbackResult(hotspots) {
|
|
213
|
+
const topHotspot = hotspots[0];
|
|
214
|
+
return {
|
|
215
|
+
summary: topHotspot
|
|
216
|
+
? `Top hotspot is \`${topHotspot.function}\` at ${topHotspot.selfPct?.toFixed(1) || "?"}% self-time. Manual review recommended.`
|
|
217
|
+
: "Unable to generate automated analysis. Please review the profile manually.",
|
|
218
|
+
recommendations: [
|
|
219
|
+
{
|
|
220
|
+
title: "Review top hotspots manually",
|
|
221
|
+
rationale: "Automated analysis was unable to complete. The profile data is available in the markdown report.",
|
|
222
|
+
steps: [
|
|
223
|
+
"Review the hotspot list in the report",
|
|
224
|
+
"Use `pprof` interactive mode for detailed exploration",
|
|
225
|
+
"Consider running additional profiles with more samples",
|
|
226
|
+
],
|
|
227
|
+
expectedImpact: "medium",
|
|
228
|
+
risk: "low",
|
|
229
|
+
confidence: 0.3,
|
|
230
|
+
},
|
|
231
|
+
],
|
|
232
|
+
nextSteps: [
|
|
233
|
+
"Run the profile again with longer duration for more samples",
|
|
234
|
+
"Use `--format=detailed` for full call tree visibility",
|
|
235
|
+
],
|
|
236
|
+
caveats: [
|
|
237
|
+
"This is a fallback result - automated LLM analysis did not complete successfully",
|
|
238
|
+
],
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/llm/validate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"duration.d.ts","sourceRoot":"","sources":["../../src/profile/duration.ts"],"names":[],"mappings":"AAAA,wBAAgB,eAAe,CAC7B,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,EAClC,UAAU,EAAE,MAAM,GACjB,MAAM,CA0BR"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export function parseDurationMs(value, fallbackMs) {
|
|
2
|
+
if (value === undefined || value === "") {
|
|
3
|
+
return fallbackMs;
|
|
4
|
+
}
|
|
5
|
+
if (typeof value === "number") {
|
|
6
|
+
if (!Number.isFinite(value) || value <= 0) {
|
|
7
|
+
throw new Error(`Invalid duration: ${value}`);
|
|
8
|
+
}
|
|
9
|
+
return Math.round(value);
|
|
10
|
+
}
|
|
11
|
+
const trimmed = value.trim().toLowerCase();
|
|
12
|
+
const match = trimmed.match(/^(\d+(?:\.\d+)?)(ms|s|m)?$/);
|
|
13
|
+
if (!match) {
|
|
14
|
+
throw new Error(`Invalid duration: ${value}`);
|
|
15
|
+
}
|
|
16
|
+
const amount = Number(match[1]);
|
|
17
|
+
if (!Number.isFinite(amount) || amount <= 0) {
|
|
18
|
+
throw new Error(`Invalid duration: ${value}`);
|
|
19
|
+
}
|
|
20
|
+
const unit = match[2] ?? "ms";
|
|
21
|
+
const multiplier = unit === "ms" ? 1 : unit === "s" ? 1000 : 60000;
|
|
22
|
+
return Math.round(amount * multiplier);
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=duration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"duration.js","sourceRoot":"","sources":["../../src/profile/duration.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,eAAe,CAC7B,KAAkC,EAClC,UAAkB;IAElB,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;QACxC,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;YAC1C,MAAM,IAAI,KAAK,CAAC,qBAAqB,KAAK,EAAE,CAAC,CAAC;QAChD,CAAC;QACD,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC;IAED,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC3C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAC1D,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,qBAAqB,KAAK,EAAE,CAAC,CAAC;IAChD,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAChC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CAAC,qBAAqB,KAAK,EAAE,CAAC,CAAC;IAChD,CAAC;IAED,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;IAC9B,MAAM,UAAU,GAAG,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;IACnE,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,UAAU,CAAC,CAAC;AACzC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preload.d.ts","sourceRoot":"","sources":["../../src/profile/preload.ts"],"names":[],"mappings":""}
|