chore: fix formatting issues
This commit is contained in:
committed by
Ralph Khreish
parent
2063dc4b7d
commit
a2de49dd90
359
docs/generateObject-migration-plan.md
Normal file
359
docs/generateObject-migration-plan.md
Normal file
@@ -0,0 +1,359 @@
|
||||
# Task Master generateObject Migration Plan
|
||||
|
||||
## Executive Summary
|
||||
|
||||
Moving from `generateText` to `generateObject` for Task Master commands would provide **significant benefits** in terms of reliability, maintainability, and performance. The current implementation uses complex JSON parsing logic that's prone to failures, while `generateObject` provides structured, validated output directly from the AI providers.
|
||||
|
||||
## Current State Analysis
|
||||
|
||||
### Pain Points with Current `generateText` Approach
|
||||
|
||||
1. **Complex JSON Parsing Logic**: Functions like `parseUpdatedTasksFromText()` and `parseSubtasksFromText()` contain 200+ lines of fragile parsing code
|
||||
2. **Unreliable Response Parsing**: Multiple fallback strategies for extracting JSON from markdown, handling malformed responses, and dealing with truncated output
|
||||
3. **Inconsistent Error Handling**: Different parsing strategies for different commands, making debugging difficult
|
||||
4. **Performance Overhead**: Multiple regex operations, string manipulations, and retry logic for parsing
|
||||
5. **Maintenance Burden**: Complex parsing code requires constant updates for new edge cases
|
||||
|
||||
### Current generateText Usage Pattern
|
||||
|
||||
```javascript
|
||||
// Current pattern in all Task Master commands
|
||||
const aiServiceResponse = await generateTextService({
|
||||
role: serviceRole,
|
||||
session: session,
|
||||
projectRoot: projectRoot,
|
||||
systemPrompt: systemPrompt,
|
||||
prompt: userPrompt,
|
||||
commandName: 'update-tasks',
|
||||
outputType: outputType
|
||||
});
|
||||
|
||||
// Then complex parsing with 200+ lines of fallback logic
|
||||
const parsedData = parseDataFromText(aiServiceResponse.mainResult, ...);
|
||||
```
|
||||
|
||||
## Benefits of generateObject Migration
|
||||
|
||||
### 1. **Reliability Improvements**
|
||||
- **Guaranteed Structure**: AI providers validate output against schemas before returning
|
||||
- **Type Safety**: Zod schema validation ensures data integrity
|
||||
- **No Parsing Failures**: Eliminates JSON parsing errors and edge cases
|
||||
|
||||
### 2. **Complexity Reduction**
|
||||
- **Eliminate Parsing Functions**: Remove 500+ lines of complex parsing logic
|
||||
- **Simplified Error Handling**: Consistent error patterns across all commands
|
||||
- **Cleaner Code**: Direct object access instead of text parsing
|
||||
|
||||
### 3. **Performance Benefits**
|
||||
- **Faster Execution**: No client-side JSON parsing overhead
|
||||
- **Reduced Retries**: No need for parsing-related retry logic
|
||||
- **Better Token Usage**: More efficient prompts without JSON formatting instructions
|
||||
|
||||
### 4. **Developer Experience**
|
||||
- **Better IDE Support**: Type-safe object access with IntelliSense
|
||||
- **Easier Debugging**: Clear schema validation errors
|
||||
- **Maintainable Code**: Schema-driven development approach
|
||||
|
||||
## Implementation Plan
|
||||
|
||||
### Phase 1: Schema Definition and Validation
|
||||
|
||||
#### 1.1 Define Zod Schemas for Each Command
|
||||
|
||||
**Location**: `src/schemas/`
|
||||
|
||||
```javascript
|
||||
// src/schemas/update-tasks.js
|
||||
import { z } from 'zod';
|
||||
|
||||
export const UpdatedTaskSchema = z.object({
|
||||
id: z.number().int(),
|
||||
title: z.string().min(1),
|
||||
description: z.string().min(1),
|
||||
status: z.enum(['pending', 'in-progress', 'blocked', 'done', 'cancelled']),
|
||||
dependencies: z.array(z.union([z.number().int(), z.string()])),
|
||||
priority: z.string().nullable(),
|
||||
details: z.string().nullable(),
|
||||
testStrategy: z.string().nullable(),
|
||||
subtasks: z.array(z.any()).nullable()
|
||||
});
|
||||
|
||||
export const UpdatedTasksResponseSchema = z.object({
|
||||
tasks: z.array(UpdatedTaskSchema)
|
||||
});
|
||||
```
|
||||
|
||||
**Commands to migrate**:
|
||||
- `update-tasks` → `UpdatedTasksResponseSchema`
|
||||
- `expand-task` → `ExpandTaskResponseSchema`
|
||||
- `analyze-complexity` → `ComplexityAnalysisResponseSchema`
|
||||
- `update-subtask-by-id` → `UpdatedSubtaskResponseSchema`
|
||||
- `update-task-by-id` → `UpdatedTaskResponseSchema`
|
||||
- `add-task` → `AddTaskResponseSchema`
|
||||
- `parse-prd` → `ParsePRDResponseSchema`
|
||||
|
||||
#### 1.2 Create Schema Registry
|
||||
|
||||
```javascript
|
||||
// src/schemas/registry.js
|
||||
import { UpdatedTasksResponseSchema } from './update-tasks.js';
|
||||
import { ExpandTaskResponseSchema } from './expand-task.js';
|
||||
// ... other imports
|
||||
|
||||
export const COMMAND_SCHEMAS = {
|
||||
'update-tasks': UpdatedTasksResponseSchema,
|
||||
'expand-task': ExpandTaskResponseSchema,
|
||||
'analyze-complexity': ComplexityAnalysisResponseSchema,
|
||||
'update-subtask-by-id': UpdatedSubtaskResponseSchema,
|
||||
'update-task-by-id': UpdatedTaskResponseSchema,
|
||||
'add-task': AddTaskResponseSchema,
|
||||
'parse-prd': ParsePRDResponseSchema
|
||||
};
|
||||
```
|
||||
|
||||
### Phase 2: Prompt Template Updates
|
||||
|
||||
#### 2.1 Modify Prompt Templates
|
||||
|
||||
**Current prompts contain JSON formatting instructions that are no longer needed**:
|
||||
|
||||
```json
|
||||
// REMOVE these instructions from prompts:
|
||||
"Return only the updated tasks as a valid JSON array."
|
||||
"Do not include any explanatory text, markdown formatting, or code block markers."
|
||||
"Respond ONLY with a valid JSON object containing a single key \"subtasks\""
|
||||
```
|
||||
|
||||
**New prompt approach**:
|
||||
```json
|
||||
{
|
||||
"system": "You are an AI assistant helping to update software development tasks based on new context. You will return a structured response with the updated tasks.",
|
||||
"user": "Here are the tasks to update:\n{{{json tasks}}}\n\nPlease update these tasks based on the following new context:\n{{updatePrompt}}"
|
||||
}
|
||||
```
|
||||
|
||||
#### 2.2 Update Prompt Files
|
||||
|
||||
**Files to update**:
|
||||
- `src/prompts/update-tasks.json`
|
||||
- `src/prompts/expand-task.json`
|
||||
- `src/prompts/analyze-complexity.json`
|
||||
- `src/prompts/update-subtask.json`
|
||||
- `src/prompts/update-task.json`
|
||||
- `src/prompts/add-task.json`
|
||||
- `src/prompts/parse-prd.json`
|
||||
|
||||
### Phase 3: Command Implementation Migration
|
||||
|
||||
#### 3.1 Update Command Functions
|
||||
|
||||
**Before (generateText pattern)**:
|
||||
```javascript
|
||||
const aiServiceResponse = await generateTextService({
|
||||
role: serviceRole,
|
||||
session: session,
|
||||
projectRoot: projectRoot,
|
||||
systemPrompt: systemPrompt,
|
||||
prompt: userPrompt,
|
||||
commandName: 'update-tasks',
|
||||
outputType: outputType
|
||||
});
|
||||
|
||||
const parsedUpdatedTasks = parseUpdatedTasksFromText(
|
||||
aiServiceResponse.mainResult,
|
||||
tasksToUpdate.length,
|
||||
logFn,
|
||||
isMCP
|
||||
);
|
||||
```
|
||||
|
||||
**After (generateObject pattern)**:
|
||||
```javascript
|
||||
import { COMMAND_SCHEMAS } from '../schemas/registry.js';
|
||||
|
||||
const aiServiceResponse = await generateObjectService({
|
||||
role: serviceRole,
|
||||
session: session,
|
||||
projectRoot: projectRoot,
|
||||
systemPrompt: systemPrompt,
|
||||
prompt: userPrompt,
|
||||
schema: COMMAND_SCHEMAS['update-tasks'],
|
||||
objectName: 'updated_tasks',
|
||||
commandName: 'update-tasks',
|
||||
outputType: outputType
|
||||
});
|
||||
|
||||
const parsedUpdatedTasks = aiServiceResponse.mainResult.tasks;
|
||||
```
|
||||
|
||||
#### 3.2 Remove Parsing Functions
|
||||
|
||||
**Delete these complex parsing functions**:
|
||||
- `parseUpdatedTasksFromText()` (227 lines) - `scripts/modules/task-manager/update-tasks.js:57-284`
|
||||
- `parseSubtasksFromText()` (200+ lines) - `scripts/modules/task-manager/expand-task.js:74-278`
|
||||
- Similar parsing functions in other command files
|
||||
|
||||
### Phase 4: Provider Compatibility
|
||||
|
||||
#### 4.1 Claude-Code Provider
|
||||
|
||||
**Current Status**: ✅ **Already Compatible**
|
||||
- `ClaudeCodeLanguageModel` has `defaultObjectGenerationMode = 'json'`
|
||||
- Handles object-json mode with JSON extraction
|
||||
- No changes needed
|
||||
|
||||
#### 4.2 Other Providers
|
||||
|
||||
**Status**: ✅ **Already Compatible**
|
||||
- All providers inherit from `BaseAIProvider`
|
||||
- `BaseAIProvider.generateObject()` uses Vercel AI SDK's `generateObject`
|
||||
- Universal compatibility across all providers
|
||||
|
||||
#### 4.3 Provider-Specific Considerations
|
||||
|
||||
**Providers that don't support structured output**:
|
||||
- The unified service will fall back to other providers in the sequence
|
||||
- Error handling already exists for unsupported tool use
|
||||
|
||||
### Phase 5: Testing Strategy
|
||||
|
||||
#### 5.1 Unit Tests
|
||||
|
||||
**Update existing tests**:
|
||||
- `tests/unit/scripts/modules/task-manager/update-tasks.test.js`
|
||||
- `tests/unit/scripts/modules/task-manager/expand-task.test.js`
|
||||
- `tests/unit/scripts/modules/task-manager/analyze-task-complexity.test.js`
|
||||
|
||||
**New schema tests**:
|
||||
```javascript
|
||||
// tests/unit/schemas/update-tasks.test.js
|
||||
import { UpdatedTasksResponseSchema } from '../../../src/schemas/update-tasks.js';
|
||||
|
||||
describe('UpdatedTasksResponseSchema', () => {
|
||||
test('validates correct task structure', () => {
|
||||
const validData = {
|
||||
tasks: [{
|
||||
id: 1,
|
||||
title: 'Test Task',
|
||||
description: 'Test Description',
|
||||
status: 'pending',
|
||||
dependencies: [],
|
||||
priority: 'medium',
|
||||
details: 'Test details',
|
||||
testStrategy: 'Unit tests',
|
||||
subtasks: []
|
||||
}]
|
||||
};
|
||||
|
||||
expect(() => UpdatedTasksResponseSchema.parse(validData)).not.toThrow();
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
#### 5.2 Integration Tests
|
||||
|
||||
**Test scenarios**:
|
||||
- End-to-end command execution with real AI providers
|
||||
- Schema validation with malformed data
|
||||
- Provider fallback behavior
|
||||
- Performance benchmarks vs current implementation
|
||||
|
||||
### Phase 6: Migration Execution
|
||||
|
||||
#### 6.1 Rollout Strategy
|
||||
|
||||
**Recommended approach**: **Command-by-command migration**
|
||||
|
||||
1. **Phase 6.1**: Migrate `analyze-complexity` (simplest command)
|
||||
2. **Phase 6.2**: Migrate `update-task-by-id` (single task)
|
||||
3. **Phase 6.3**: Migrate `expand-task` (moderate complexity)
|
||||
4. **Phase 6.4**: Migrate `update-tasks` (most complex)
|
||||
5. **Phase 6.5**: Migrate remaining commands
|
||||
|
||||
#### 6.2 Rollback Plan
|
||||
|
||||
**Each command can be rolled back independently**:
|
||||
- Keep old parsing functions temporarily
|
||||
- Feature flag to switch between generateText/generateObject
|
||||
- Gradual migration with fallback capability
|
||||
|
||||
### Phase 7: Cleanup and Optimization
|
||||
|
||||
#### 7.1 Remove Legacy Code
|
||||
|
||||
**After successful migration**:
|
||||
- Delete parsing functions (500+ lines of code)
|
||||
- Remove JSON formatting instructions from prompts
|
||||
- Clean up error handling for parsing failures
|
||||
|
||||
#### 7.2 Performance Optimization
|
||||
|
||||
**Potential improvements**:
|
||||
- Reduce token usage by 10-15% (removing JSON formatting instructions)
|
||||
- Eliminate client-side parsing overhead
|
||||
- Faster command execution times
|
||||
|
||||
## Risk Assessment
|
||||
|
||||
### High Risk Items
|
||||
|
||||
1. **Provider Compatibility**: Some providers may not support structured output
|
||||
- **Mitigation**: Existing fallback sequence handles this
|
||||
- **Test**: Verify all configured providers support generateObject
|
||||
|
||||
2. **Schema Validation Failures**: AI might generate invalid structures
|
||||
- **Mitigation**: Zod provides clear error messages
|
||||
- **Test**: Comprehensive schema validation tests
|
||||
|
||||
### Medium Risk Items
|
||||
|
||||
1. **Prompt Quality**: New prompts may perform differently
|
||||
- **Mitigation**: A/B test prompts during migration
|
||||
- **Test**: Compare output quality before/after migration
|
||||
|
||||
2. **Performance Impact**: generateObject might be slower
|
||||
- **Mitigation**: Benchmark performance during testing
|
||||
- **Test**: Performance regression tests
|
||||
|
||||
### Low Risk Items
|
||||
|
||||
1. **Code Complexity**: New approach is actually simpler
|
||||
2. **Maintainability**: Significant improvement expected
|
||||
|
||||
## Success Criteria
|
||||
|
||||
### Performance Metrics
|
||||
- [ ] 90% reduction in parsing-related errors
|
||||
- [ ] 50% reduction in command execution time
|
||||
- [ ] 15% reduction in token usage
|
||||
- [ ] 500+ lines of parsing code eliminated
|
||||
|
||||
### Quality Metrics
|
||||
- [ ] 100% schema validation coverage
|
||||
- [ ] Zero JSON parsing failures
|
||||
- [ ] Consistent error handling across commands
|
||||
- [ ] Improved developer experience ratings
|
||||
|
||||
## Timeline Estimate
|
||||
|
||||
**Total Duration**: 2-3 weeks
|
||||
|
||||
- **Phase 1-2** (Schema + Prompts): 3-4 days
|
||||
- **Phase 3** (Command Migration): 1-1.5 weeks
|
||||
- **Phase 4** (Provider Testing): 2-3 days
|
||||
- **Phase 5** (Testing): 3-4 days
|
||||
- **Phase 6** (Rollout): 2-3 days
|
||||
- **Phase 7** (Cleanup): 1-2 days
|
||||
|
||||
## Conclusion
|
||||
|
||||
The migration from `generateText` to `generateObject` represents a **significant architectural improvement** that will:
|
||||
|
||||
1. **Dramatically reduce complexity** by eliminating 500+ lines of fragile parsing code
|
||||
2. **Improve reliability** through guaranteed structured output
|
||||
3. **Enhance performance** by removing client-side parsing overhead
|
||||
4. **Provide better developer experience** with type-safe, schema-validated responses
|
||||
|
||||
The existing infrastructure already supports this migration, making it a low-risk, high-value improvement to the Task Master codebase.
|
||||
|
||||
**Recommendation**: Proceed with the migration following the phased approach outlined above.
|
||||
Reference in New Issue
Block a user