ai-sdlc 0.2.0-beta.1 → 0.2.1-alpha.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.
- package/dist/agents/implementation.d.ts.map +1 -1
- package/dist/agents/implementation.js +64 -0
- package/dist/agents/implementation.js.map +1 -1
- package/dist/agents/index.d.ts +2 -0
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js +2 -0
- package/dist/agents/index.js.map +1 -1
- package/dist/agents/orchestrator.d.ts +61 -0
- package/dist/agents/orchestrator.d.ts.map +1 -0
- package/dist/agents/orchestrator.js +443 -0
- package/dist/agents/orchestrator.js.map +1 -0
- package/dist/agents/planning.d.ts +1 -1
- package/dist/agents/planning.d.ts.map +1 -1
- package/dist/agents/planning.js +33 -1
- package/dist/agents/planning.js.map +1 -1
- package/dist/agents/review.d.ts +10 -0
- package/dist/agents/review.d.ts.map +1 -1
- package/dist/agents/review.js +138 -25
- package/dist/agents/review.js.map +1 -1
- package/dist/agents/single-task.d.ts +41 -0
- package/dist/agents/single-task.d.ts.map +1 -0
- package/dist/agents/single-task.js +357 -0
- package/dist/agents/single-task.js.map +1 -0
- package/dist/cli/commands.d.ts.map +1 -1
- package/dist/cli/commands.js +22 -3
- package/dist/cli/commands.js.map +1 -1
- package/dist/cli/runner.d.ts.map +1 -1
- package/dist/cli/runner.js +4 -8
- package/dist/cli/runner.js.map +1 -1
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +4 -2
- package/dist/core/config.js.map +1 -1
- package/dist/core/index.d.ts +2 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +2 -0
- package/dist/core/index.js.map +1 -1
- package/dist/core/llm-utils.d.ts +103 -0
- package/dist/core/llm-utils.d.ts.map +1 -0
- package/dist/core/llm-utils.js +368 -0
- package/dist/core/llm-utils.js.map +1 -0
- package/dist/core/story.d.ts +11 -1
- package/dist/core/story.d.ts.map +1 -1
- package/dist/core/story.js +33 -1
- package/dist/core/story.js.map +1 -1
- package/dist/core/task-parser.d.ts +59 -0
- package/dist/core/task-parser.d.ts.map +1 -0
- package/dist/core/task-parser.js +235 -0
- package/dist/core/task-parser.js.map +1 -0
- package/dist/core/task-progress.d.ts +92 -0
- package/dist/core/task-progress.d.ts.map +1 -0
- package/dist/core/task-progress.js +280 -0
- package/dist/core/task-progress.js.map +1 -0
- package/dist/services/error-classifier.d.ts +119 -0
- package/dist/services/error-classifier.d.ts.map +1 -0
- package/dist/services/error-classifier.js +182 -0
- package/dist/services/error-classifier.js.map +1 -0
- package/dist/types/index.d.ts +183 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/package.json +2 -1
package/dist/core/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,wBAAwB,CAAC;AACvC,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,wBAAwB,CAAC;AACvC,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { ZodSchema } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Result of structured response extraction
|
|
4
|
+
*/
|
|
5
|
+
export interface ExtractionResult<T> {
|
|
6
|
+
success: boolean;
|
|
7
|
+
data?: T;
|
|
8
|
+
strategy?: ExtractionStrategy;
|
|
9
|
+
error?: string;
|
|
10
|
+
rawResponse?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Extraction strategies in priority order
|
|
14
|
+
*/
|
|
15
|
+
export type ExtractionStrategy = 'direct_json' | 'markdown_json_block' | 'stripped_json' | 'yaml_fallback';
|
|
16
|
+
/**
|
|
17
|
+
* Options for structured response extraction
|
|
18
|
+
*/
|
|
19
|
+
export interface ExtractionOptions {
|
|
20
|
+
/** Maximum retry attempts if extraction fails (default: 0 - no retries) */
|
|
21
|
+
maxRetries?: number;
|
|
22
|
+
/** Function to call LLM for retry (required if maxRetries > 0) */
|
|
23
|
+
retryFn?: (clarificationPrompt: string) => Promise<string>;
|
|
24
|
+
/** Log raw response on failure for debugging (default: true) */
|
|
25
|
+
logOnFailure?: boolean;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Try to extract JSON directly from the response
|
|
29
|
+
*/
|
|
30
|
+
declare function tryDirectJson<T>(response: string, schema: ZodSchema<T>): ExtractionResult<T>;
|
|
31
|
+
/**
|
|
32
|
+
* Try to extract JSON from markdown code blocks
|
|
33
|
+
* Supports ```json, ```JSON, and plain ``` blocks
|
|
34
|
+
*/
|
|
35
|
+
declare function tryMarkdownJsonBlock<T>(response: string, schema: ZodSchema<T>): ExtractionResult<T>;
|
|
36
|
+
/**
|
|
37
|
+
* Try to extract JSON by stripping leading/trailing text
|
|
38
|
+
* Finds the first { and last } to extract potential JSON
|
|
39
|
+
*/
|
|
40
|
+
declare function tryStrippedJson<T>(response: string, schema: ZodSchema<T>): ExtractionResult<T>;
|
|
41
|
+
/**
|
|
42
|
+
* Try to parse response as YAML
|
|
43
|
+
*/
|
|
44
|
+
declare function tryYamlFallback<T>(response: string, schema: ZodSchema<T>): ExtractionResult<T>;
|
|
45
|
+
/**
|
|
46
|
+
* Extract structured response from LLM output using multiple strategies
|
|
47
|
+
*
|
|
48
|
+
* Tries extraction strategies in order:
|
|
49
|
+
* 1. Direct JSON parse (response is pure JSON)
|
|
50
|
+
* 2. JSON within markdown code blocks (\`\`\`json ... \`\`\`)
|
|
51
|
+
* 3. JSON with leading/trailing text stripped
|
|
52
|
+
* 4. YAML format fallback
|
|
53
|
+
*
|
|
54
|
+
* If all strategies fail and retries are configured, prompts the LLM
|
|
55
|
+
* to try again with clearer instructions.
|
|
56
|
+
*
|
|
57
|
+
* @param response - Raw LLM response string
|
|
58
|
+
* @param schema - Zod schema to validate against
|
|
59
|
+
* @param options - Extraction options including retry configuration
|
|
60
|
+
* @returns ExtractionResult with success status, data, and metadata
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```typescript
|
|
64
|
+
* const ReviewSchema = z.object({
|
|
65
|
+
* passed: z.boolean(),
|
|
66
|
+
* issues: z.array(z.object({
|
|
67
|
+
* severity: z.enum(['blocker', 'critical', 'major', 'minor']),
|
|
68
|
+
* description: z.string(),
|
|
69
|
+
* })),
|
|
70
|
+
* });
|
|
71
|
+
*
|
|
72
|
+
* const result = await extractStructuredResponse(llmResponse, ReviewSchema, {
|
|
73
|
+
* maxRetries: 2,
|
|
74
|
+
* retryFn: async (prompt) => await callLLM(prompt),
|
|
75
|
+
* });
|
|
76
|
+
*
|
|
77
|
+
* if (result.success) {
|
|
78
|
+
* console.log('Parsed review:', result.data);
|
|
79
|
+
* } else {
|
|
80
|
+
* console.error('Failed to parse:', result.error);
|
|
81
|
+
* }
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
export declare function extractStructuredResponse<T>(response: string, schema: ZodSchema<T>, options?: ExtractionOptions): Promise<ExtractionResult<T>>;
|
|
85
|
+
/**
|
|
86
|
+
* Synchronous version of extractStructuredResponse without retry support
|
|
87
|
+
*
|
|
88
|
+
* Useful when you don't need retry functionality or are in a synchronous context.
|
|
89
|
+
*
|
|
90
|
+
* @param response - Raw LLM response string
|
|
91
|
+
* @param schema - Zod schema to validate against
|
|
92
|
+
* @param logOnFailure - Whether to log the raw response on failure (default: true)
|
|
93
|
+
* @returns ExtractionResult with success status, data, and metadata
|
|
94
|
+
*/
|
|
95
|
+
export declare function extractStructuredResponseSync<T>(response: string, schema: ZodSchema<T>, logOnFailure?: boolean): ExtractionResult<T>;
|
|
96
|
+
export declare const extractionStrategies: {
|
|
97
|
+
tryDirectJson: typeof tryDirectJson;
|
|
98
|
+
tryMarkdownJsonBlock: typeof tryMarkdownJsonBlock;
|
|
99
|
+
tryStrippedJson: typeof tryStrippedJson;
|
|
100
|
+
tryYamlFallback: typeof tryYamlFallback;
|
|
101
|
+
};
|
|
102
|
+
export {};
|
|
103
|
+
//# sourceMappingURL=llm-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm-utils.d.ts","sourceRoot":"","sources":["../../src/core/llm-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAK,SAAS,EAAE,MAAM,KAAK,CAAC;AAInC;;GAEG;AACH,MAAM,WAAW,gBAAgB,CAAC,CAAC;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,QAAQ,CAAC,EAAE,kBAAkB,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAC1B,aAAa,GACb,qBAAqB,GACrB,eAAe,GACf,eAAe,CAAC;AAEpB;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,2EAA2E;IAC3E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kEAAkE;IAClE,OAAO,CAAC,EAAE,CAAC,mBAAmB,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC3D,gEAAgE;IAChE,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;GAEG;AACH,iBAAS,aAAa,CAAC,CAAC,EACtB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,GACnB,gBAAgB,CAAC,CAAC,CAAC,CAyBrB;AAED;;;GAGG;AACH,iBAAS,oBAAoB,CAAC,CAAC,EAC7B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,GACnB,gBAAgB,CAAC,CAAC,CAAC,CA0BrB;AAED;;;GAGG;AACH,iBAAS,eAAe,CAAC,CAAC,EACxB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,GACnB,gBAAgB,CAAC,CAAC,CAAC,CAqDrB;AAED;;GAEG;AACH,iBAAS,eAAe,CAAC,CAAC,EACxB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,GACnB,gBAAgB,CAAC,CAAC,CAAC,CA4DrB;AAmCD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,wBAAsB,yBAAyB,CAAC,CAAC,EAC/C,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,EACpB,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CA4F9B;AAED;;;;;;;;;GASG;AACH,wBAAgB,6BAA6B,CAAC,CAAC,EAC7C,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,EACpB,YAAY,UAAO,GAClB,gBAAgB,CAAC,CAAC,CAAC,CA+CrB;AAGD,eAAO,MAAM,oBAAoB;;;;;CAKhC,CAAC"}
|
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import yaml from 'js-yaml';
|
|
3
|
+
import { getLogger } from './logger.js';
|
|
4
|
+
/**
|
|
5
|
+
* Try to extract JSON directly from the response
|
|
6
|
+
*/
|
|
7
|
+
function tryDirectJson(response, schema) {
|
|
8
|
+
try {
|
|
9
|
+
const trimmed = response.trim();
|
|
10
|
+
// Must start with { or [ to be valid JSON
|
|
11
|
+
if (!trimmed.startsWith('{') && !trimmed.startsWith('[')) {
|
|
12
|
+
return { success: false, error: 'Response does not start with JSON' };
|
|
13
|
+
}
|
|
14
|
+
const parsed = JSON.parse(trimmed);
|
|
15
|
+
const result = schema.safeParse(parsed);
|
|
16
|
+
if (result.success) {
|
|
17
|
+
return { success: true, data: result.data, strategy: 'direct_json' };
|
|
18
|
+
}
|
|
19
|
+
return {
|
|
20
|
+
success: false,
|
|
21
|
+
error: `Schema validation failed: ${result.error.message}`,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
catch (e) {
|
|
25
|
+
return {
|
|
26
|
+
success: false,
|
|
27
|
+
error: `JSON parse error: ${e instanceof Error ? e.message : String(e)}`,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Try to extract JSON from markdown code blocks
|
|
33
|
+
* Supports ```json, ```JSON, and plain ``` blocks
|
|
34
|
+
*/
|
|
35
|
+
function tryMarkdownJsonBlock(response, schema) {
|
|
36
|
+
// Match JSON in code blocks: ```json ... ``` or ``` ... ```
|
|
37
|
+
const codeBlockRegex = /```(?:json|JSON)?\s*\n?([\s\S]*?)```/g;
|
|
38
|
+
const matches = [...response.matchAll(codeBlockRegex)];
|
|
39
|
+
for (const match of matches) {
|
|
40
|
+
const content = match[1].trim();
|
|
41
|
+
if (!content)
|
|
42
|
+
continue;
|
|
43
|
+
try {
|
|
44
|
+
const parsed = JSON.parse(content);
|
|
45
|
+
const result = schema.safeParse(parsed);
|
|
46
|
+
if (result.success) {
|
|
47
|
+
return { success: true, data: result.data, strategy: 'markdown_json_block' };
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
// Try next match
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
success: false,
|
|
57
|
+
error: 'No valid JSON found in markdown code blocks',
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Try to extract JSON by stripping leading/trailing text
|
|
62
|
+
* Finds the first { and last } to extract potential JSON
|
|
63
|
+
*/
|
|
64
|
+
function tryStrippedJson(response, schema) {
|
|
65
|
+
const firstBrace = response.indexOf('{');
|
|
66
|
+
const lastBrace = response.lastIndexOf('}');
|
|
67
|
+
if (firstBrace === -1 || lastBrace === -1 || firstBrace >= lastBrace) {
|
|
68
|
+
// Try array format
|
|
69
|
+
const firstBracket = response.indexOf('[');
|
|
70
|
+
const lastBracket = response.lastIndexOf(']');
|
|
71
|
+
if (firstBracket === -1 || lastBracket === -1 || firstBracket >= lastBracket) {
|
|
72
|
+
return { success: false, error: 'No JSON object or array found in response' };
|
|
73
|
+
}
|
|
74
|
+
try {
|
|
75
|
+
const jsonStr = response.substring(firstBracket, lastBracket + 1);
|
|
76
|
+
const parsed = JSON.parse(jsonStr);
|
|
77
|
+
const result = schema.safeParse(parsed);
|
|
78
|
+
if (result.success) {
|
|
79
|
+
return { success: true, data: result.data, strategy: 'stripped_json' };
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
success: false,
|
|
83
|
+
error: `Schema validation failed: ${result.error.message}`,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
catch (e) {
|
|
87
|
+
return {
|
|
88
|
+
success: false,
|
|
89
|
+
error: `Stripped JSON parse error: ${e instanceof Error ? e.message : String(e)}`,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
try {
|
|
94
|
+
const jsonStr = response.substring(firstBrace, lastBrace + 1);
|
|
95
|
+
const parsed = JSON.parse(jsonStr);
|
|
96
|
+
const result = schema.safeParse(parsed);
|
|
97
|
+
if (result.success) {
|
|
98
|
+
return { success: true, data: result.data, strategy: 'stripped_json' };
|
|
99
|
+
}
|
|
100
|
+
return {
|
|
101
|
+
success: false,
|
|
102
|
+
error: `Schema validation failed: ${result.error.message}`,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
catch (e) {
|
|
106
|
+
return {
|
|
107
|
+
success: false,
|
|
108
|
+
error: `Stripped JSON parse error: ${e instanceof Error ? e.message : String(e)}`,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Try to parse response as YAML
|
|
114
|
+
*/
|
|
115
|
+
function tryYamlFallback(response, schema) {
|
|
116
|
+
try {
|
|
117
|
+
// First try to extract YAML from code blocks
|
|
118
|
+
const yamlBlockRegex = /```(?:yaml|YAML|yml|YML)\s*\n?([\s\S]*?)```/g;
|
|
119
|
+
const matches = [...response.matchAll(yamlBlockRegex)];
|
|
120
|
+
for (const match of matches) {
|
|
121
|
+
const content = match[1].trim();
|
|
122
|
+
if (!content)
|
|
123
|
+
continue;
|
|
124
|
+
try {
|
|
125
|
+
const parsed = yaml.load(content);
|
|
126
|
+
const result = schema.safeParse(parsed);
|
|
127
|
+
if (result.success) {
|
|
128
|
+
return { success: true, data: result.data, strategy: 'yaml_fallback' };
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
// Try parsing the whole response as YAML (after stripping obvious non-YAML parts)
|
|
136
|
+
// Skip lines that look like prose (sentences without colons)
|
|
137
|
+
const lines = response.split('\n');
|
|
138
|
+
const yamlLines = [];
|
|
139
|
+
let inYamlSection = false;
|
|
140
|
+
for (const line of lines) {
|
|
141
|
+
const trimmed = line.trim();
|
|
142
|
+
// Start of YAML-like content
|
|
143
|
+
if (trimmed.includes(':') || trimmed.startsWith('-') || inYamlSection) {
|
|
144
|
+
yamlLines.push(line);
|
|
145
|
+
inYamlSection = true;
|
|
146
|
+
}
|
|
147
|
+
// Empty line might end YAML section if we haven't found valid content
|
|
148
|
+
if (trimmed === '' && yamlLines.length > 0) {
|
|
149
|
+
inYamlSection = false;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
if (yamlLines.length > 0) {
|
|
153
|
+
const yamlContent = yamlLines.join('\n');
|
|
154
|
+
const parsed = yaml.load(yamlContent);
|
|
155
|
+
const result = schema.safeParse(parsed);
|
|
156
|
+
if (result.success) {
|
|
157
|
+
return { success: true, data: result.data, strategy: 'yaml_fallback' };
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return { success: false, error: 'No valid YAML found in response' };
|
|
161
|
+
}
|
|
162
|
+
catch (e) {
|
|
163
|
+
return {
|
|
164
|
+
success: false,
|
|
165
|
+
error: `YAML parse error: ${e instanceof Error ? e.message : String(e)}`,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Generate a clarification prompt for retry attempts
|
|
171
|
+
*/
|
|
172
|
+
function generateClarificationPrompt(schema, attemptNumber, lastError) {
|
|
173
|
+
// Get schema shape for the prompt
|
|
174
|
+
let schemaDescription = 'the expected JSON structure';
|
|
175
|
+
try {
|
|
176
|
+
if (schema instanceof z.ZodObject) {
|
|
177
|
+
const shape = schema.shape;
|
|
178
|
+
const fields = Object.keys(shape).join(', ');
|
|
179
|
+
schemaDescription = `an object with fields: ${fields}`;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
catch {
|
|
183
|
+
// Fall back to generic description
|
|
184
|
+
}
|
|
185
|
+
return `Your previous response could not be parsed. Attempt ${attemptNumber} failed with: ${lastError}
|
|
186
|
+
|
|
187
|
+
Please respond with ONLY valid JSON matching ${schemaDescription}.
|
|
188
|
+
|
|
189
|
+
Rules:
|
|
190
|
+
1. Start your response directly with { or [
|
|
191
|
+
2. Do not include any text before or after the JSON
|
|
192
|
+
3. Ensure all strings are properly escaped
|
|
193
|
+
4. Ensure all required fields are present
|
|
194
|
+
|
|
195
|
+
Try again:`;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Extract structured response from LLM output using multiple strategies
|
|
199
|
+
*
|
|
200
|
+
* Tries extraction strategies in order:
|
|
201
|
+
* 1. Direct JSON parse (response is pure JSON)
|
|
202
|
+
* 2. JSON within markdown code blocks (\`\`\`json ... \`\`\`)
|
|
203
|
+
* 3. JSON with leading/trailing text stripped
|
|
204
|
+
* 4. YAML format fallback
|
|
205
|
+
*
|
|
206
|
+
* If all strategies fail and retries are configured, prompts the LLM
|
|
207
|
+
* to try again with clearer instructions.
|
|
208
|
+
*
|
|
209
|
+
* @param response - Raw LLM response string
|
|
210
|
+
* @param schema - Zod schema to validate against
|
|
211
|
+
* @param options - Extraction options including retry configuration
|
|
212
|
+
* @returns ExtractionResult with success status, data, and metadata
|
|
213
|
+
*
|
|
214
|
+
* @example
|
|
215
|
+
* ```typescript
|
|
216
|
+
* const ReviewSchema = z.object({
|
|
217
|
+
* passed: z.boolean(),
|
|
218
|
+
* issues: z.array(z.object({
|
|
219
|
+
* severity: z.enum(['blocker', 'critical', 'major', 'minor']),
|
|
220
|
+
* description: z.string(),
|
|
221
|
+
* })),
|
|
222
|
+
* });
|
|
223
|
+
*
|
|
224
|
+
* const result = await extractStructuredResponse(llmResponse, ReviewSchema, {
|
|
225
|
+
* maxRetries: 2,
|
|
226
|
+
* retryFn: async (prompt) => await callLLM(prompt),
|
|
227
|
+
* });
|
|
228
|
+
*
|
|
229
|
+
* if (result.success) {
|
|
230
|
+
* console.log('Parsed review:', result.data);
|
|
231
|
+
* } else {
|
|
232
|
+
* console.error('Failed to parse:', result.error);
|
|
233
|
+
* }
|
|
234
|
+
* ```
|
|
235
|
+
*/
|
|
236
|
+
export async function extractStructuredResponse(response, schema, options = {}) {
|
|
237
|
+
const { maxRetries = 0, retryFn, logOnFailure = true } = options;
|
|
238
|
+
const logger = getLogger();
|
|
239
|
+
// Store all errors for debugging
|
|
240
|
+
const errors = [];
|
|
241
|
+
// Strategy 1: Direct JSON
|
|
242
|
+
const directResult = tryDirectJson(response, schema);
|
|
243
|
+
if (directResult.success) {
|
|
244
|
+
return directResult;
|
|
245
|
+
}
|
|
246
|
+
errors.push(`direct_json: ${directResult.error}`);
|
|
247
|
+
// Strategy 2: Markdown JSON block
|
|
248
|
+
const markdownResult = tryMarkdownJsonBlock(response, schema);
|
|
249
|
+
if (markdownResult.success) {
|
|
250
|
+
return markdownResult;
|
|
251
|
+
}
|
|
252
|
+
errors.push(`markdown_json_block: ${markdownResult.error}`);
|
|
253
|
+
// Strategy 3: Stripped JSON
|
|
254
|
+
const strippedResult = tryStrippedJson(response, schema);
|
|
255
|
+
if (strippedResult.success) {
|
|
256
|
+
return strippedResult;
|
|
257
|
+
}
|
|
258
|
+
errors.push(`stripped_json: ${strippedResult.error}`);
|
|
259
|
+
// Strategy 4: YAML fallback
|
|
260
|
+
const yamlResult = tryYamlFallback(response, schema);
|
|
261
|
+
if (yamlResult.success) {
|
|
262
|
+
return yamlResult;
|
|
263
|
+
}
|
|
264
|
+
errors.push(`yaml_fallback: ${yamlResult.error}`);
|
|
265
|
+
// All strategies failed - try retries if configured
|
|
266
|
+
if (maxRetries > 0 && retryFn) {
|
|
267
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
268
|
+
logger.info('llm-utils', `Retry attempt ${attempt}/${maxRetries} for structured response extraction`);
|
|
269
|
+
const clarificationPrompt = generateClarificationPrompt(schema, attempt, errors[errors.length - 1]);
|
|
270
|
+
try {
|
|
271
|
+
const retryResponse = await retryFn(clarificationPrompt);
|
|
272
|
+
// Try all strategies again on retry response
|
|
273
|
+
const retryDirectResult = tryDirectJson(retryResponse, schema);
|
|
274
|
+
if (retryDirectResult.success) {
|
|
275
|
+
return retryDirectResult;
|
|
276
|
+
}
|
|
277
|
+
const retryMarkdownResult = tryMarkdownJsonBlock(retryResponse, schema);
|
|
278
|
+
if (retryMarkdownResult.success) {
|
|
279
|
+
return retryMarkdownResult;
|
|
280
|
+
}
|
|
281
|
+
const retryStrippedResult = tryStrippedJson(retryResponse, schema);
|
|
282
|
+
if (retryStrippedResult.success) {
|
|
283
|
+
return retryStrippedResult;
|
|
284
|
+
}
|
|
285
|
+
const retryYamlResult = tryYamlFallback(retryResponse, schema);
|
|
286
|
+
if (retryYamlResult.success) {
|
|
287
|
+
return retryYamlResult;
|
|
288
|
+
}
|
|
289
|
+
errors.push(`retry_${attempt}: All strategies failed`);
|
|
290
|
+
}
|
|
291
|
+
catch (e) {
|
|
292
|
+
errors.push(`retry_${attempt}: ${e instanceof Error ? e.message : String(e)}`);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
// All attempts failed
|
|
297
|
+
const finalError = `All extraction strategies failed:\n${errors.join('\n')}`;
|
|
298
|
+
if (logOnFailure) {
|
|
299
|
+
logger.error('llm-utils', 'Failed to extract structured response', {
|
|
300
|
+
errors,
|
|
301
|
+
responsePreview: response.substring(0, 500),
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
return {
|
|
305
|
+
success: false,
|
|
306
|
+
error: finalError,
|
|
307
|
+
rawResponse: response,
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Synchronous version of extractStructuredResponse without retry support
|
|
312
|
+
*
|
|
313
|
+
* Useful when you don't need retry functionality or are in a synchronous context.
|
|
314
|
+
*
|
|
315
|
+
* @param response - Raw LLM response string
|
|
316
|
+
* @param schema - Zod schema to validate against
|
|
317
|
+
* @param logOnFailure - Whether to log the raw response on failure (default: true)
|
|
318
|
+
* @returns ExtractionResult with success status, data, and metadata
|
|
319
|
+
*/
|
|
320
|
+
export function extractStructuredResponseSync(response, schema, logOnFailure = true) {
|
|
321
|
+
const logger = getLogger();
|
|
322
|
+
const errors = [];
|
|
323
|
+
// Strategy 1: Direct JSON
|
|
324
|
+
const directResult = tryDirectJson(response, schema);
|
|
325
|
+
if (directResult.success) {
|
|
326
|
+
return directResult;
|
|
327
|
+
}
|
|
328
|
+
errors.push(`direct_json: ${directResult.error}`);
|
|
329
|
+
// Strategy 2: Markdown JSON block
|
|
330
|
+
const markdownResult = tryMarkdownJsonBlock(response, schema);
|
|
331
|
+
if (markdownResult.success) {
|
|
332
|
+
return markdownResult;
|
|
333
|
+
}
|
|
334
|
+
errors.push(`markdown_json_block: ${markdownResult.error}`);
|
|
335
|
+
// Strategy 3: Stripped JSON
|
|
336
|
+
const strippedResult = tryStrippedJson(response, schema);
|
|
337
|
+
if (strippedResult.success) {
|
|
338
|
+
return strippedResult;
|
|
339
|
+
}
|
|
340
|
+
errors.push(`stripped_json: ${strippedResult.error}`);
|
|
341
|
+
// Strategy 4: YAML fallback
|
|
342
|
+
const yamlResult = tryYamlFallback(response, schema);
|
|
343
|
+
if (yamlResult.success) {
|
|
344
|
+
return yamlResult;
|
|
345
|
+
}
|
|
346
|
+
errors.push(`yaml_fallback: ${yamlResult.error}`);
|
|
347
|
+
// All attempts failed
|
|
348
|
+
const finalError = `All extraction strategies failed:\n${errors.join('\n')}`;
|
|
349
|
+
if (logOnFailure) {
|
|
350
|
+
logger.error('llm-utils', 'Failed to extract structured response', {
|
|
351
|
+
errors,
|
|
352
|
+
responsePreview: response.substring(0, 500),
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
return {
|
|
356
|
+
success: false,
|
|
357
|
+
error: finalError,
|
|
358
|
+
rawResponse: response,
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
// Export individual strategies for testing
|
|
362
|
+
export const extractionStrategies = {
|
|
363
|
+
tryDirectJson,
|
|
364
|
+
tryMarkdownJsonBlock,
|
|
365
|
+
tryStrippedJson,
|
|
366
|
+
tryYamlFallback,
|
|
367
|
+
};
|
|
368
|
+
//# sourceMappingURL=llm-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm-utils.js","sourceRoot":"","sources":["../../src/core/llm-utils.ts"],"names":[],"mappings":"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"}
|
package/dist/core/story.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Story, StoryFrontmatter, StoryStatus, ReviewAttempt, Config, LockOptions } from '../types/index.js';
|
|
1
|
+
import { Story, StoryFrontmatter, StoryStatus, ReviewAttempt, Config, LockOptions, ReviewResult } from '../types/index.js';
|
|
2
2
|
/**
|
|
3
3
|
* Parse a story markdown file into a Story object
|
|
4
4
|
*
|
|
@@ -160,6 +160,16 @@ export declare function getLatestReviewAttempt(story: Story): ReviewAttempt | nu
|
|
|
160
160
|
* Mark a story as complete (all workflow flags set to true)
|
|
161
161
|
*/
|
|
162
162
|
export declare function markStoryComplete(story: Story): Promise<Story>;
|
|
163
|
+
/**
|
|
164
|
+
* Auto-complete story after review approval
|
|
165
|
+
* Handles marking story as complete and transitioning to done status
|
|
166
|
+
*
|
|
167
|
+
* @param story - The story to auto-complete
|
|
168
|
+
* @param config - The configuration containing reviewConfig settings
|
|
169
|
+
* @param reviewResult - The result from the review agent
|
|
170
|
+
* @returns Updated story if auto-completion occurred, original story otherwise
|
|
171
|
+
*/
|
|
172
|
+
export declare function autoCompleteStoryAfterReview(story: Story, config: Config, reviewResult: ReviewResult): Promise<Story>;
|
|
163
173
|
/**
|
|
164
174
|
* Snapshot max_retries from config to story frontmatter (for mid-cycle config change protection)
|
|
165
175
|
*/
|
package/dist/core/story.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"story.d.ts","sourceRoot":"","sources":["../../src/core/story.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAoB,aAAa,EAAE,MAAM,EAAqE,WAAW,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"story.d.ts","sourceRoot":"","sources":["../../src/core/story.ts"],"names":[],"mappings":"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"}
|
package/dist/core/story.js
CHANGED
|
@@ -2,7 +2,7 @@ import fs from 'fs';
|
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import matter from 'gray-matter';
|
|
4
4
|
import * as properLockfile from 'proper-lockfile';
|
|
5
|
-
import { FOLDER_TO_STATUS, BLOCKED_DIR, STORIES_FOLDER, STORY_FILENAME, DEFAULT_PRIORITY_GAP } from '../types/index.js';
|
|
5
|
+
import { FOLDER_TO_STATUS, BLOCKED_DIR, STORIES_FOLDER, STORY_FILENAME, DEFAULT_PRIORITY_GAP, ReviewDecision } from '../types/index.js';
|
|
6
6
|
/**
|
|
7
7
|
* Parse a story markdown file into a Story object
|
|
8
8
|
*
|
|
@@ -615,6 +615,38 @@ export async function markStoryComplete(story) {
|
|
|
615
615
|
await writeStory(story);
|
|
616
616
|
return story;
|
|
617
617
|
}
|
|
618
|
+
/**
|
|
619
|
+
* Auto-complete story after review approval
|
|
620
|
+
* Handles marking story as complete and transitioning to done status
|
|
621
|
+
*
|
|
622
|
+
* @param story - The story to auto-complete
|
|
623
|
+
* @param config - The configuration containing reviewConfig settings
|
|
624
|
+
* @param reviewResult - The result from the review agent
|
|
625
|
+
* @returns Updated story if auto-completion occurred, original story otherwise
|
|
626
|
+
*/
|
|
627
|
+
export async function autoCompleteStoryAfterReview(story, config, reviewResult) {
|
|
628
|
+
// Only auto-complete if review was approved and config allows it
|
|
629
|
+
if (reviewResult.decision !== ReviewDecision.APPROVED) {
|
|
630
|
+
return story;
|
|
631
|
+
}
|
|
632
|
+
if (!config.reviewConfig.autoCompleteOnApproval) {
|
|
633
|
+
return story;
|
|
634
|
+
}
|
|
635
|
+
try {
|
|
636
|
+
// Mark all workflow flags as complete
|
|
637
|
+
story = await markStoryComplete(story);
|
|
638
|
+
// Update status to done if currently in-progress
|
|
639
|
+
if (story.frontmatter.status === 'in-progress') {
|
|
640
|
+
story = await updateStoryStatus(story, 'done');
|
|
641
|
+
}
|
|
642
|
+
return story;
|
|
643
|
+
}
|
|
644
|
+
catch (error) {
|
|
645
|
+
// Log error but don't fail the entire review operation
|
|
646
|
+
console.error('Failed to auto-complete story after review:', error);
|
|
647
|
+
return story;
|
|
648
|
+
}
|
|
649
|
+
}
|
|
618
650
|
/**
|
|
619
651
|
* Snapshot max_retries from config to story frontmatter (for mid-cycle config change protection)
|
|
620
652
|
*/
|