@krr2020/taskflow-core 0.1.0-beta.3 → 0.1.0-beta.5

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 (62) hide show
  1. package/README.md +1 -1
  2. package/dist/cli/index.js +42 -4
  3. package/dist/commands/base.d.ts +41 -0
  4. package/dist/commands/base.js +141 -0
  5. package/dist/commands/configure.d.ts +29 -0
  6. package/dist/commands/configure.js +187 -0
  7. package/dist/commands/init.js +21 -7
  8. package/dist/commands/prd/create.d.ts +1 -1
  9. package/dist/commands/prd/create.js +29 -11
  10. package/dist/commands/prd/generate-arch.d.ts +1 -1
  11. package/dist/commands/prd/generate-arch.js +6 -5
  12. package/dist/commands/retro/list.js +6 -5
  13. package/dist/commands/tasks/generate.d.ts +1 -1
  14. package/dist/commands/tasks/generate.js +83 -56
  15. package/dist/commands/upgrade.js +49 -16
  16. package/dist/commands/workflow/check.d.ts +17 -0
  17. package/dist/commands/workflow/check.js +482 -35
  18. package/dist/commands/workflow/commit.js +117 -60
  19. package/dist/commands/workflow/do.d.ts +1 -0
  20. package/dist/commands/workflow/do.js +206 -13
  21. package/dist/commands/workflow/next.js +4 -4
  22. package/dist/commands/workflow/resume.js +9 -6
  23. package/dist/commands/workflow/start.js +11 -11
  24. package/dist/index.d.ts +4 -0
  25. package/dist/index.js +6 -0
  26. package/dist/lib/config-paths.d.ts +15 -15
  27. package/dist/lib/config-paths.js +20 -15
  28. package/dist/lib/file-validator.d.ts +119 -0
  29. package/dist/lib/file-validator.js +291 -0
  30. package/dist/lib/git.js +4 -2
  31. package/dist/lib/log-parser.d.ts +91 -0
  32. package/dist/lib/log-parser.js +178 -0
  33. package/dist/lib/retrospective.d.ts +27 -0
  34. package/dist/lib/retrospective.js +111 -1
  35. package/dist/lib/types.d.ts +19 -6
  36. package/dist/lib/types.js +20 -1
  37. package/dist/lib/validation.d.ts +0 -3
  38. package/dist/lib/validation.js +1 -15
  39. package/dist/llm/base.d.ts +52 -0
  40. package/dist/llm/base.js +35 -0
  41. package/dist/llm/factory.d.ts +39 -0
  42. package/dist/llm/factory.js +102 -0
  43. package/dist/llm/index.d.ts +7 -0
  44. package/dist/llm/index.js +7 -0
  45. package/dist/llm/model-selector.d.ts +71 -0
  46. package/dist/llm/model-selector.js +139 -0
  47. package/dist/llm/providers/anthropic.d.ts +31 -0
  48. package/dist/llm/providers/anthropic.js +116 -0
  49. package/dist/llm/providers/index.d.ts +6 -0
  50. package/dist/llm/providers/index.js +6 -0
  51. package/dist/llm/providers/ollama.d.ts +28 -0
  52. package/dist/llm/providers/ollama.js +91 -0
  53. package/dist/llm/providers/openai-compatible.d.ts +30 -0
  54. package/dist/llm/providers/openai-compatible.js +93 -0
  55. package/dist/schemas/config.d.ts +82 -0
  56. package/dist/schemas/config.js +35 -0
  57. package/dist/schemas/task.d.ts +2 -2
  58. package/dist/state-machine.d.ts +12 -0
  59. package/dist/state-machine.js +2 -2
  60. package/package.json +1 -1
  61. package/dist/lib/package-manager.d.ts +0 -17
  62. package/dist/lib/package-manager.js +0 -53
@@ -0,0 +1,178 @@
1
+ /**
2
+ * Log Parser
3
+ * Extracts errors and diagnostic information from build/test logs
4
+ */
5
+ import { readFile } from "node:fs/promises";
6
+ /**
7
+ * Log Parser class
8
+ * Parses build/test logs to extract errors and diagnostics
9
+ */
10
+ export class LogParser {
11
+ patterns = [
12
+ {
13
+ name: "TypeScript error",
14
+ regex: /([^:\n]+?):(\d+):(\d+) - error (TS\d+): (.+)/g,
15
+ severity: "error",
16
+ },
17
+ {
18
+ name: "TypeScript warning",
19
+ regex: /([^:\n]+?):(\d+):(\d+) - warning (TS\d+): (.+)/g,
20
+ severity: "warning",
21
+ },
22
+ {
23
+ name: "ESLint error",
24
+ regex: /([^:\n]+?):(\d+):(\d+) error (.+)/g,
25
+ severity: "error",
26
+ },
27
+ {
28
+ name: "ESLint warning",
29
+ regex: /([^:\n]+?):(\d+):(\d+) warning (.+)/g,
30
+ severity: "warning",
31
+ },
32
+ {
33
+ name: "Test failure",
34
+ regex: /FAIL\s+([^\s]+?)(?:\n|$)/g,
35
+ severity: "error",
36
+ },
37
+ {
38
+ name: "Build error",
39
+ regex: /error\s+(.+?)(?:\n|$)/g,
40
+ severity: "error",
41
+ },
42
+ {
43
+ name: "Compilation error",
44
+ regex: /([^:\n]+?):(\d+): error: (.+)/g,
45
+ severity: "error",
46
+ },
47
+ ];
48
+ /**
49
+ * Parse log string
50
+ */
51
+ parse(logContent) {
52
+ const errors = [];
53
+ for (const pattern of this.patterns) {
54
+ let match = pattern.regex.exec(logContent);
55
+ while (match !== null) {
56
+ const error = this.createErrorFromMatch(match, pattern);
57
+ if (error) {
58
+ errors.push(error);
59
+ }
60
+ match = pattern.regex.exec(logContent);
61
+ }
62
+ }
63
+ const errorCount = errors.filter((e) => e.severity === "error").length;
64
+ const warningCount = errors.filter((e) => e.severity === "warning").length;
65
+ return {
66
+ errors,
67
+ errorCount,
68
+ warningCount,
69
+ success: errorCount === 0,
70
+ };
71
+ }
72
+ /**
73
+ * Parse log file
74
+ */
75
+ async parseFile(filePath) {
76
+ const content = await readFile(filePath, "utf-8");
77
+ return this.parse(content);
78
+ }
79
+ /**
80
+ * Create error from regex match
81
+ */
82
+ createErrorFromMatch(match, pattern) {
83
+ const raw = match[0];
84
+ // Try to extract file, line, column, message, code
85
+ let file = "";
86
+ let line = 0;
87
+ let column = 0;
88
+ let message = raw;
89
+ let code = "";
90
+ switch (pattern.name) {
91
+ case "TypeScript error":
92
+ case "TypeScript warning":
93
+ file = match[1] || "";
94
+ line = Number.parseInt(match[2] || "0", 10);
95
+ column = Number.parseInt(match[3] || "0", 10);
96
+ code = match[4]?.split(":")[0] || "";
97
+ message = match[4] || raw;
98
+ break;
99
+ case "ESLint error":
100
+ case "ESLint warning":
101
+ file = match[1] || "";
102
+ line = Number.parseInt(match[2] || "0", 10);
103
+ column = Number.parseInt(match[3] || "0", 10);
104
+ message = match[4] || raw;
105
+ break;
106
+ case "Test failure":
107
+ file = match[1] || "";
108
+ message = `Test failed: ${match[1]}`;
109
+ break;
110
+ case "Build error":
111
+ message = match[1] || raw;
112
+ break;
113
+ case "Compilation error":
114
+ file = match[1] || "";
115
+ line = Number.parseInt(match[2] || "0", 10);
116
+ message = match[3] || raw;
117
+ break;
118
+ default:
119
+ message = raw;
120
+ }
121
+ return {
122
+ file,
123
+ line,
124
+ column,
125
+ message,
126
+ code,
127
+ severity: pattern.severity,
128
+ raw,
129
+ };
130
+ }
131
+ /**
132
+ * Group errors by file
133
+ */
134
+ groupErrorsByFile(errors) {
135
+ const grouped = new Map();
136
+ for (const error of errors) {
137
+ if (error.file) {
138
+ const existing = grouped.get(error.file) || [];
139
+ existing.push(error);
140
+ grouped.set(error.file, existing);
141
+ }
142
+ }
143
+ return grouped;
144
+ }
145
+ /**
146
+ * Filter errors by severity
147
+ */
148
+ filterBySeverity(errors, severity) {
149
+ return errors.filter((e) => e.severity === severity);
150
+ }
151
+ /**
152
+ * Filter errors by file
153
+ */
154
+ filterByFile(errors, filePattern) {
155
+ const regex = new RegExp(filePattern);
156
+ return errors.filter((e) => regex.test(e.file));
157
+ }
158
+ /**
159
+ * Format error for display
160
+ */
161
+ formatError(error) {
162
+ const parts = [];
163
+ if (error.file) {
164
+ parts.push(error.file);
165
+ if (error.line) {
166
+ parts.push(`:${error.line}`);
167
+ if (error.column) {
168
+ parts.push(`:${error.column}`);
169
+ }
170
+ }
171
+ }
172
+ if (error.code) {
173
+ parts.push(`[${error.code}]`);
174
+ }
175
+ parts.push(`- ${error.message}`);
176
+ return parts.join(" ");
177
+ }
178
+ }
@@ -1,7 +1,16 @@
1
1
  /**
2
2
  * Retrospective module for error pattern management
3
3
  */
4
+ import type { ParsedError } from "./log-parser.js";
4
5
  import type { Criticality, ErrorCategory, RetrospectiveItem } from "./types.js";
6
+ export interface NewPattern {
7
+ category: ErrorCategory | string;
8
+ pattern: string;
9
+ solution: string;
10
+ criticality: Criticality | string;
11
+ errorCode?: string;
12
+ affectedFiles: string[];
13
+ }
5
14
  export declare function getRetrospectiveFilePath(refDir: string): string;
6
15
  export declare function loadRetrospective(refDir: string): RetrospectiveItem[];
7
16
  export declare function parseRetrospectiveContent(content: string): RetrospectiveItem[];
@@ -23,3 +32,21 @@ export declare const VALID_CRITICALITIES: Criticality[];
23
32
  export declare function isValidCategory(category: string): category is ErrorCategory;
24
33
  export declare function isValidCriticality(criticality: string): criticality is Criticality;
25
34
  export declare function printRetroAddUsage(): void;
35
+ /**
36
+ * Read retrospective file content
37
+ */
38
+ export declare function readRetrospectiveBeforeWork(refDir: string): string;
39
+ /**
40
+ * Extract NEW error patterns from parsed errors
41
+ * Compares against existing retrospective to avoid duplicates
42
+ */
43
+ export declare function extractNewPatterns(errors: ParsedError[], refDir: string): NewPattern[];
44
+ /**
45
+ * Append new patterns to retrospective file
46
+ * Uses existing addRetrospectiveEntry for each pattern
47
+ */
48
+ export declare function appendNewPatternsToRetrospective(refDir: string, patterns: NewPattern[]): number[];
49
+ /**
50
+ * Format a new pattern for display (before adding to retrospective)
51
+ */
52
+ export declare function formatNewPatternForDisplay(pattern: NewPattern): string;
@@ -124,7 +124,7 @@ export function incrementErrorCount(refDir, id) {
124
124
  export function addRetrospectiveEntry(refDir, category, pattern, solution, criticality) {
125
125
  const retroFile = getRetrospectiveFilePath(refDir);
126
126
  if (!fs.existsSync(retroFile)) {
127
- throw new Error("RETROSPECTIVE.md not found");
127
+ throw new Error("retrospective.md not found");
128
128
  }
129
129
  const items = loadRetrospective(refDir);
130
130
  const nextId = items.length > 0
@@ -180,3 +180,113 @@ export function printRetroAddUsage() {
180
180
  console.log(`\n${colors.highlight("Example:")}`);
181
181
  console.log(`${colors.muted('taskflow retro add --category "Type Error" --pattern "Cannot find module" --solution "Check import path exists" --criticality "High"')}`);
182
182
  }
183
+ // ============================================================================
184
+ // Auto-Update Functions
185
+ // ============================================================================
186
+ /**
187
+ * Read retrospective file content
188
+ */
189
+ export function readRetrospectiveBeforeWork(refDir) {
190
+ const retroFile = getRetrospectiveFilePath(refDir);
191
+ if (!fs.existsSync(retroFile)) {
192
+ return "";
193
+ }
194
+ return fs.readFileSync(retroFile, "utf-8");
195
+ }
196
+ /**
197
+ * Extract NEW error patterns from parsed errors
198
+ * Compares against existing retrospective to avoid duplicates
199
+ */
200
+ export function extractNewPatterns(errors, refDir) {
201
+ const existingItems = loadRetrospective(refDir);
202
+ const newPatterns = [];
203
+ // Group errors by error code and message pattern
204
+ const errorGroups = new Map();
205
+ for (const error of errors) {
206
+ const key = error.code || error.message.substring(0, 50);
207
+ if (!errorGroups.has(key)) {
208
+ errorGroups.set(key, []);
209
+ }
210
+ errorGroups.get(key)?.push(error);
211
+ }
212
+ // For each group, check if it's a new pattern
213
+ for (const [, groupErrors] of errorGroups) {
214
+ const firstError = groupErrors[0];
215
+ if (!firstError)
216
+ continue;
217
+ // Create pattern from error message
218
+ const pattern = firstError.code || firstError.message;
219
+ // Check if this pattern already exists in retrospective
220
+ const alreadyExists = existingItems.some((item) => {
221
+ try {
222
+ const itemPattern = item.pattern.replace(/\\\|/g, "|");
223
+ const regex = new RegExp(itemPattern, "i");
224
+ return regex.test(pattern);
225
+ }
226
+ catch {
227
+ return item.pattern.toLowerCase().includes(pattern.toLowerCase());
228
+ }
229
+ });
230
+ if (!alreadyExists) {
231
+ // Determine category from error
232
+ let category = "Runtime";
233
+ if (firstError.code?.startsWith("TS")) {
234
+ category = "Type Error";
235
+ }
236
+ else if (firstError.message.includes("eslint") ||
237
+ firstError.message.includes("lint")) {
238
+ category = "Lint";
239
+ }
240
+ else if (firstError.message.includes("test")) {
241
+ category = "Test";
242
+ }
243
+ // Determine criticality based on severity
244
+ let criticality = "Medium";
245
+ if (firstError.severity === "error") {
246
+ criticality = "High";
247
+ }
248
+ else if (firstError.severity === "warning") {
249
+ criticality = "Low";
250
+ }
251
+ newPatterns.push({
252
+ category,
253
+ pattern,
254
+ solution: "Review error message and fix the underlying issue",
255
+ criticality,
256
+ errorCode: firstError.code,
257
+ affectedFiles: groupErrors.map((e) => e.file).filter(Boolean),
258
+ });
259
+ }
260
+ }
261
+ return newPatterns;
262
+ }
263
+ /**
264
+ * Append new patterns to retrospective file
265
+ * Uses existing addRetrospectiveEntry for each pattern
266
+ */
267
+ export function appendNewPatternsToRetrospective(refDir, patterns) {
268
+ const addedIds = [];
269
+ for (const pattern of patterns) {
270
+ const id = addRetrospectiveEntry(refDir, pattern.category, pattern.pattern, pattern.solution, pattern.criticality);
271
+ addedIds.push(id);
272
+ }
273
+ return addedIds;
274
+ }
275
+ /**
276
+ * Format a new pattern for display (before adding to retrospective)
277
+ */
278
+ export function formatNewPatternForDisplay(pattern) {
279
+ const lines = [];
280
+ lines.push(`${colors.highlight("New Error Pattern Detected:")}`);
281
+ lines.push(` Category: ${colors.muted(pattern.category)}`);
282
+ lines.push(` Pattern: ${colors.warning(pattern.pattern)}`);
283
+ if (pattern.errorCode) {
284
+ lines.push(` Code: ${colors.error(pattern.errorCode)}`);
285
+ }
286
+ lines.push(` Suggested Solution: ${colors.success(pattern.solution)}`);
287
+ lines.push(` Criticality: ${colors.state(pattern.criticality)}`);
288
+ if (pattern.affectedFiles.length > 0) {
289
+ lines.push(` Affected Files: ${colors.muted(pattern.affectedFiles.slice(0, 3).join(", "))}${pattern.affectedFiles.length > 3 ? "..." : ""}`);
290
+ }
291
+ return lines.join("\n");
292
+ }
@@ -10,6 +10,7 @@ import { z } from "zod";
10
10
  export declare const TaskStatusSchema: z.ZodEnum<{
11
11
  "not-started": "not-started";
12
12
  setup: "setup";
13
+ planning: "planning";
13
14
  implementing: "implementing";
14
15
  verifying: "verifying";
15
16
  validating: "validating";
@@ -20,7 +21,7 @@ export declare const TaskStatusSchema: z.ZodEnum<{
20
21
  }>;
21
22
  export type TaskStatus = z.infer<typeof TaskStatusSchema>;
22
23
  /** Status values that indicate a task is actively being worked on */
23
- export declare const ACTIVE_STATUSES: readonly ["setup", "implementing", "verifying", "validating", "committing"];
24
+ export declare const ACTIVE_STATUSES: readonly ["setup", "planning", "implementing", "verifying", "validating", "committing"];
24
25
  export type ActiveStatus = (typeof ACTIVE_STATUSES)[number];
25
26
  /** Check if a status is an active (in-progress) status */
26
27
  export declare function isActiveStatus(status: string): status is ActiveStatus;
@@ -84,6 +85,7 @@ export declare const TaskFileContentSchema: z.ZodObject<{
84
85
  status: z.ZodEnum<{
85
86
  "not-started": "not-started";
86
87
  setup: "setup";
88
+ planning: "planning";
87
89
  implementing: "implementing";
88
90
  verifying: "verifying";
89
91
  validating: "validating";
@@ -113,6 +115,7 @@ export declare const TaskFileContentSchema: z.ZodObject<{
113
115
  previousStatus: z.ZodOptional<z.ZodEnum<{
114
116
  "not-started": "not-started";
115
117
  setup: "setup";
118
+ planning: "planning";
116
119
  implementing: "implementing";
117
120
  verifying: "verifying";
118
121
  validating: "validating";
@@ -149,6 +152,7 @@ export declare const TaskRefSchema: z.ZodObject<{
149
152
  status: z.ZodEnum<{
150
153
  "not-started": "not-started";
151
154
  setup: "setup";
155
+ planning: "planning";
152
156
  implementing: "implementing";
153
157
  verifying: "verifying";
154
158
  validating: "validating";
@@ -176,6 +180,7 @@ export declare const StorySchema: z.ZodObject<{
176
180
  status: z.ZodEnum<{
177
181
  "not-started": "not-started";
178
182
  setup: "setup";
183
+ planning: "planning";
179
184
  implementing: "implementing";
180
185
  verifying: "verifying";
181
186
  validating: "validating";
@@ -215,6 +220,7 @@ export declare const FeatureSchema: z.ZodObject<{
215
220
  status: z.ZodEnum<{
216
221
  "not-started": "not-started";
217
222
  setup: "setup";
223
+ planning: "planning";
218
224
  implementing: "implementing";
219
225
  verifying: "verifying";
220
226
  validating: "validating";
@@ -274,6 +280,18 @@ export declare const TaskflowConfigSchema: z.ZodObject<{
274
280
  validation: z.ZodOptional<z.ZodObject<{
275
281
  commands: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
276
282
  }, z.core.$strip>>;
283
+ ai: z.ZodOptional<z.ZodObject<{
284
+ enabled: z.ZodDefault<z.ZodBoolean>;
285
+ provider: z.ZodOptional<z.ZodString>;
286
+ models: z.ZodOptional<z.ZodObject<{
287
+ planning: z.ZodOptional<z.ZodString>;
288
+ execution: z.ZodOptional<z.ZodString>;
289
+ analysis: z.ZodOptional<z.ZodString>;
290
+ default: z.ZodOptional<z.ZodString>;
291
+ }, z.core.$strip>>;
292
+ autoContinueTask: z.ZodDefault<z.ZodBoolean>;
293
+ clearContextOnComplete: z.ZodDefault<z.ZodBoolean>;
294
+ }, z.core.$strip>>;
277
295
  }, z.core.$strip>;
278
296
  export type TaskflowConfig = z.infer<typeof TaskflowConfigSchema>;
279
297
  export interface TasksProgress {
@@ -319,11 +337,6 @@ export interface RetrospectiveItem {
319
337
  count: number;
320
338
  criticality: string;
321
339
  }
322
- export interface CommandResult {
323
- success: boolean;
324
- message?: string;
325
- data?: unknown;
326
- }
327
340
  export interface ValidationResult {
328
341
  command: string;
329
342
  label: string;
package/dist/lib/types.js CHANGED
@@ -13,6 +13,7 @@ import { z } from "zod";
13
13
  export const TaskStatusSchema = z.enum([
14
14
  "not-started",
15
15
  "setup",
16
+ "planning",
16
17
  "implementing",
17
18
  "verifying",
18
19
  "validating",
@@ -24,6 +25,7 @@ export const TaskStatusSchema = z.enum([
24
25
  /** Status values that indicate a task is actively being worked on */
25
26
  export const ACTIVE_STATUSES = [
26
27
  "setup",
28
+ "planning",
27
29
  "implementing",
28
30
  "verifying",
29
31
  "validating",
@@ -35,7 +37,8 @@ export function isActiveStatus(status) {
35
37
  }
36
38
  /** Status transitions for workflow progression */
37
39
  export const STATUS_TRANSITIONS = {
38
- setup: "implementing",
40
+ setup: "planning",
41
+ planning: "implementing",
39
42
  implementing: "verifying",
40
43
  verifying: "validating",
41
44
  validating: "committing",
@@ -149,6 +152,22 @@ export const TaskflowConfigSchema = z.object({
149
152
  commands: z.record(z.string(), z.string()).optional(),
150
153
  })
151
154
  .optional(),
155
+ ai: z
156
+ .object({
157
+ enabled: z.boolean().default(false),
158
+ provider: z.string().optional(),
159
+ models: z
160
+ .object({
161
+ planning: z.string().optional(),
162
+ execution: z.string().optional(),
163
+ analysis: z.string().optional(),
164
+ default: z.string().optional(),
165
+ })
166
+ .optional(),
167
+ autoContinueTask: z.boolean().default(false),
168
+ clearContextOnComplete: z.boolean().default(true),
169
+ })
170
+ .optional(),
152
171
  });
153
172
  // ============================================================================
154
173
  // Retrospective Types
@@ -27,6 +27,3 @@ export interface ValidationSummary {
27
27
  }
28
28
  export declare function runValidations(logsDir: string, taskId: string, commands?: Record<string, string>): ValidationSummary;
29
29
  export declare function assertValidationPassed(summary: ValidationSummary, logsDir: string): void;
30
- export declare function quickTypeCheck(): boolean;
31
- export declare function quickLintCheck(cwd?: string): boolean;
32
- export declare function quickAllChecks(cwd?: string): boolean;
@@ -3,7 +3,7 @@
3
3
  */
4
4
  import fs from "node:fs";
5
5
  import { execaSync } from "execa";
6
- import { getLogFilePath, MAX_OUTPUT_BUFFER, } from "./config-paths.js";
6
+ import { getLogFilePath, MAX_OUTPUT_BUFFER } from "./config-paths.js";
7
7
  import { saveLogFile } from "./data-access.js";
8
8
  import { ValidationFailedError } from "./errors.js";
9
9
  import { colors, extractErrorSummary } from "./output.js";
@@ -149,17 +149,3 @@ export function assertValidationPassed(summary, logsDir) {
149
149
  }
150
150
  }
151
151
  // ============================================================================
152
- // Quick Checks (without logging)
153
- // ============================================================================
154
- export function quickTypeCheck() {
155
- // Without configuration, we cannot perform quick checks
156
- return true;
157
- }
158
- export function quickLintCheck(cwd = process.cwd()) {
159
- // Without configuration, we cannot perform quick checks
160
- return true;
161
- }
162
- export function quickAllChecks(cwd = process.cwd()) {
163
- // Without configuration, we cannot perform quick checks
164
- return true;
165
- }
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Base LLM Provider interface
3
+ * All LLM providers must implement this interface
4
+ */
5
+ export interface LLMMessage {
6
+ role: "system" | "user" | "assistant";
7
+ content: string;
8
+ }
9
+ export interface LLMGenerationOptions {
10
+ maxTokens?: number;
11
+ temperature?: number;
12
+ topP?: number;
13
+ topK?: number;
14
+ }
15
+ export interface LLMGenerationResult {
16
+ content: string;
17
+ model: string;
18
+ tokensUsed?: number;
19
+ finishReason?: string;
20
+ }
21
+ export declare enum LLMProviderType {
22
+ OpenAICompatible = "openai-compatible",
23
+ Anthropic = "anthropic",
24
+ Ollama = "ollama"
25
+ }
26
+ export declare enum Phase {
27
+ Planning = "planning",
28
+ Execution = "execution",
29
+ Analysis = "analysis"
30
+ }
31
+ /**
32
+ * LLM Provider interface
33
+ * Defines the contract for all LLM provider implementations
34
+ */
35
+ export declare abstract class LLMProvider {
36
+ readonly type: LLMProviderType;
37
+ readonly model: string;
38
+ constructor(type: LLMProviderType, model: string);
39
+ /**
40
+ * Generate text from the LLM
41
+ */
42
+ abstract generate(messages: LLMMessage[], options?: LLMGenerationOptions): Promise<LLMGenerationResult>;
43
+ /**
44
+ * Check if the provider is properly configured
45
+ */
46
+ abstract isConfigured(): boolean;
47
+ /**
48
+ * Get the model name for the specified phase
49
+ * Override if provider has phase-specific models
50
+ */
51
+ getModelForPhase(_phase: Phase): string;
52
+ }
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Base LLM Provider interface
3
+ * All LLM providers must implement this interface
4
+ */
5
+ export var LLMProviderType;
6
+ (function (LLMProviderType) {
7
+ LLMProviderType["OpenAICompatible"] = "openai-compatible";
8
+ LLMProviderType["Anthropic"] = "anthropic";
9
+ LLMProviderType["Ollama"] = "ollama";
10
+ })(LLMProviderType || (LLMProviderType = {}));
11
+ export var Phase;
12
+ (function (Phase) {
13
+ Phase["Planning"] = "planning";
14
+ Phase["Execution"] = "execution";
15
+ Phase["Analysis"] = "analysis";
16
+ })(Phase || (Phase = {}));
17
+ /**
18
+ * LLM Provider interface
19
+ * Defines the contract for all LLM provider implementations
20
+ */
21
+ export class LLMProvider {
22
+ type;
23
+ model;
24
+ constructor(type, model) {
25
+ this.type = type;
26
+ this.model = model;
27
+ }
28
+ /**
29
+ * Get the model name for the specified phase
30
+ * Override if provider has phase-specific models
31
+ */
32
+ getModelForPhase(_phase) {
33
+ return this.model;
34
+ }
35
+ }
@@ -0,0 +1,39 @@
1
+ /**
2
+ * LLM Provider Factory
3
+ * Factory for creating LLM providers and model selectors
4
+ */
5
+ import { type LLMGenerationOptions, type LLMGenerationResult, type LLMMessage, type LLMProvider, LLMProviderType } from "./base.js";
6
+ import { type AIConfig, ModelSelector } from "./model-selector.js";
7
+ export type { LLMMessage, LLMGenerationOptions, LLMGenerationResult };
8
+ export { LLMProvider, LLMProviderType } from "./base.js";
9
+ export { type AIConfig, ModelSelector } from "./model-selector.js";
10
+ export { AnthropicProvider, OllamaProvider, OpenAICompatibleProvider, } from "./providers/index.js";
11
+ /**
12
+ * Provider factory namespace
13
+ * Functions for creating LLM providers and model selectors
14
+ */
15
+ export declare const ProviderFactory: {
16
+ /**
17
+ * Create a model selector from configuration
18
+ */
19
+ createSelector(config: AIConfig): ModelSelector;
20
+ /**
21
+ * Create a single provider (backward compatible)
22
+ */
23
+ createProvider(type: LLMProviderType, model: string, apiKey?: string, baseUrl?: string): LLMProvider;
24
+ /**
25
+ * Test if a provider is configured and working
26
+ */
27
+ testProvider(provider: LLMProvider): Promise<{
28
+ success: boolean;
29
+ error?: string;
30
+ }>;
31
+ /**
32
+ * Get available providers
33
+ */
34
+ getAvailableProviders(): string[];
35
+ /**
36
+ * Get default model for provider
37
+ */
38
+ getDefaultModel(providerType: LLMProviderType): string;
39
+ };