wiki/z-archive/appdoc/ai_plan_implementation.md

942 lines
30 KiB
Markdown

# AI Plan Implementation Guide
## Overview
This document provides a structured implementation plan to adapt the current codebase to the enhanced architecture described in `ai_plan_architecture.md`.
**Goal**: Implement all architectural improvements while maintaining backward compatibility and clear tracking.
---
## Reference Model: Implementation Phases
```
Phase 1: Foundation Models (Pydantic)
├─> New models: ActionDefinition, AiResponse, DocumentReference types
└─> Enhanced models: ChatWorkflow, TaskContext
Phase 2: State Management (ChatWorkflow)
├─> Add execution state fields
├─> Add helper methods (getRoundIndex, incrementRound, etc.)
└─> Update all call sites
Phase 3: TaskContext Enhancement
├─> Add Stage 2 fields
├─> Add updateFromSelection method
└─> Remove SimpleNamespace workarounds
Phase 4: Document References (Typed Models)
├─> Create DocumentReference classes
├─> Replace string references with typed models
└─> Update document lookup logic
Phase 5: JSON Parsing (Structured)
├─> Create parseJsonWithModel utility
├─> Replace manual JSON parsing
└─> Update all AI response parsing
Phase 6: AI Service Consolidation
├─> Consolidate callAiDocuments + callAiText → callAiContent
├─> Update all call sites
└─> Ensure contentParts-only approach
Phase 7: Document Extraction Separation
├─> Add extractContent action to methodAi
├─> Remove extraction from AI calls
└─> Update action execution flow
Phase 8: Remove Actionplan Mode
├─> Remove modeActionplan.py
├─> Remove promptGenerationActionsActionplan.py
├─> Remove WorkflowModeEnum.WORKFLOW_ACTIONPLAN
└─> Update workflowProcessor to remove ActionplanMode references
Phase 9: Testing & Validation
├─> Unit tests for new models
├─> Integration tests for workflow
└─> End-to-end validation
```
---
## Model Segregation Rules
### Clear Separation of Concerns
**`datamodelChat.py`** (Chat/Workflow State Models):
- `ChatWorkflow` (enhanced with execution state)
- `TaskContext` (enhanced with Stage 2 fields)
- `ChatMessage` (existing)
- `ChatDocument` (existing)
**`datamodelWorkflow.py`** (Workflow Execution Models):
- `ActionDefinition` (action selection and parameters)
- `AiResponse` (unified AI response)
- `AiResponseMetadata` (response metadata)
- `DocumentData` (single document in response)
- `RequestContext` (workflow-level request)
- `UnderstandingResult` (workflow-level understanding)
- `TaskDefinition` (workflow-level task)
- `TaskResult` (workflow-level result)
**`datamodelDocref.py`** (Document Reference Models):
- `DocumentReference` (base class)
- `DocumentListReference` (docList: references)
- `DocumentItemReference` (docItem: references)
- `DocumentReferenceList` (list wrapper)
**`jsonUtils.py`** (JSON Utilities):
- All JSON parsing utilities (including `parseJsonWithModel`)
- No separate `jsonModelUtils.py`
---
## Phase 1: Foundation Models (Pydantic)
### 1.1 Create New Pydantic Models
**File**: `gateway/modules/datamodels/datamodelWorkflow.py` (NEW)
**Models to Create** (Workflow execution models):
- `ActionDefinition` (replaces `ActionSelection` + `ActionParameters`)
- `AiResponse` (unified response model)
- `AiResponseMetadata` (response metadata)
- `DocumentData` (single document in response)
- `RequestContext` (workflow-level)
- `UnderstandingResult` (workflow-level)
- `TaskDefinition` (workflow-level)
- `TaskResult` (workflow-level)
**Segregation Rule**: `datamodelWorkflow.py` contains models related to **workflow execution** (actions, AI responses, task definitions).
**Reference**: `ai_plan_architecture.md` lines 216-335
**Implementation Checklist**:
- [ ] Create `datamodelWorkflow.py`
- [ ] Implement `ActionDefinition` with `needsStage2()` method
- [ ] Implement `AiResponse` with `toJson()` method
- [ ] Implement `AiResponseMetadata` with `fromDict()` classmethod
- [ ] Implement workflow-level models (`RequestContext`, `UnderstandingResult`, etc.)
- [ ] Add unit tests for model validation
---
### 1.2 Create Document Reference Models
**File**: `gateway/modules/datamodels/datamodelDocref.py` (NEW)
**Models to Create** (Document reference models):
- `DocumentReference` (base class)
- `DocumentListReference` (docList: references)
- `DocumentItemReference` (docItem: references)
- `DocumentReferenceList` (list wrapper with conversion methods)
**Segregation Rule**: `datamodelDocref.py` contains models related to **document references** (how documents are referenced in workflows).
**Reference**: `ai_plan_architecture.md` lines 174-212
**Implementation Checklist**:
- [ ] Create `datamodelDocref.py`
- [ ] Implement `DocumentReference` base class
- [ ] Implement `DocumentListReference` with `to_string()` method
- [ ] Implement `DocumentItemReference` with `to_string()` method
- [ ] Implement `DocumentReferenceList` with `to_string_list()` and `from_string_list()` methods
- [ ] Add parsing logic for string → typed conversion
- [ ] Add unit tests for reference parsing
---
## Phase 2: State Management (ChatWorkflow)
### 2.1 Enhance ChatWorkflow Model
**File**: `gateway/modules/datamodels/datamodelChat.py`
**Segregation Rule**: `datamodelChat.py` contains models related to **chat/workflow state** (ChatWorkflow, TaskContext, ChatMessage, ChatDocument).
**Changes**:
```python
class ChatWorkflow(BaseModel):
# ... existing fields ...
# NEW: Execution state
currentRound: int = 0
currentTask: int = 0
currentAction: int = 0
# NEW: Helper methods
def getRoundIndex(self) -> int:
return self.currentRound
def getTaskIndex(self) -> int:
return self.currentTask
def getActionIndex(self) -> int:
return self.currentAction
def incrementRound(self):
self.currentRound += 1
self.currentTask = 0
self.currentAction = 0
def incrementTask(self):
self.currentTask += 1
self.currentAction = 0
def incrementAction(self):
self.currentAction += 1
```
**Reference**: `ai_plan_architecture.md` lines 117-152
**Implementation Checklist**:
- [ ] Add execution state fields to `ChatWorkflow`
- [ ] Add helper methods (`getRoundIndex`, `getTaskIndex`, `getActionIndex`)
- [ ] Add increment methods (`incrementRound`, `incrementTask`, `incrementAction`)
- [ ] Update database migration if needed (add columns)
- [ ] Add unit tests for state management
---
### 2.2 Update Call Sites (Remove Separate Index Parameters)
**Files to Update**:
- `gateway/modules/workflows/processing/workflowProcessor.py`
- `gateway/modules/workflows/processing/modes/modeDynamic.py`
- `gateway/modules/workflows/processing/actionExecutor.py`
**Changes**:
```python
# BEFORE
async def executeTask(taskStep, workflow, context, taskIndex: int, actionIndex: int):
# Use taskIndex, actionIndex parameters
# AFTER
async def executeTask(taskStep, workflow, context):
# Use workflow.getTaskIndex(), workflow.getActionIndex()
taskIndex = workflow.getTaskIndex()
actionIndex = workflow.getActionIndex()
```
**Reference**: `ai_plan_architecture.md` lines 435-568
**Implementation Checklist**:
- [ ] Remove `taskIndex`, `actionIndex` parameters from `workflowProcessor.executeTask()`
- [ ] Remove `taskIndex`, `actionIndex` parameters from `modeDynamic.executeTask()`
- [ ] Remove `taskIndex`, `actionIndex` parameters from `actionExecutor.executeSingleAction()`
- [ ] Update all call sites to use `workflow.getTaskIndex()`, `workflow.getActionIndex()`
- [ ] Update increment calls to use `workflow.incrementAction()`, `workflow.incrementTask()`
- [ ] Test workflow execution with state management
---
## Phase 3: TaskContext Enhancement
### 3.1 Enhance TaskContext Model
**File**: `gateway/modules/datamodels/datamodelChat.py`
**Segregation Rule**: `datamodelChat.py` contains `TaskContext` (part of chat workflow context).
**Changes**:
```python
class TaskContext(BaseModel):
# ... existing fields ...
# NEW: Stage 2 context fields
actionObjective: Optional[str] = None
parametersContext: Optional[str] = None
learnings: List[str] = Field(default_factory=list)
stage1Selection: Optional[Dict[str, Any]] = None
def updateFromSelection(self, selection: ActionDefinition):
"""Update context from Stage 1 selection"""
self.actionObjective = selection.actionObjective
self.parametersContext = selection.parametersContext
self.learnings = selection.learnings
self.stage1Selection = selection.model_dump()
```
**Reference**: `ai_plan_architecture.md` lines 154-172
**Implementation Checklist**:
- [ ] Add Stage 2 fields to `TaskContext`
- [ ] Add `updateFromSelection()` method
- [ ] Add unit tests for context updates
---
### 3.2 Remove SimpleNamespace Workarounds
**Files to Update**:
- `gateway/modules/workflows/processing/modes/modeDynamic.py`
**Changes**:
```python
# BEFORE
from types import SimpleNamespace
stage2Context = SimpleNamespace(
actionObjective=selection.actionObjective,
parametersContext=selection.parametersContext,
learnings=selection.learnings
)
# AFTER
context.updateFromSelection(selection)
# Use context.actionObjective, context.parametersContext directly
```
**Reference**: `ai_plan_architecture.md` lines 529-530
**Implementation Checklist**:
- [ ] Find all `SimpleNamespace` usages in `modeDynamic.py`
- [ ] Replace with `context.updateFromSelection(selection)`
- [ ] Update all references to use `context.actionObjective`, etc.
- [ ] Remove `SimpleNamespace` imports
- [ ] Test Stage 2 parameter generation
---
## Phase 4: Document References (Typed Models)
### 4.1 Update Document Reference Usage
**Files to Update**:
- `gateway/modules/workflows/processing/modes/modeDynamic.py` (`_planSelect`)
- `gateway/modules/services/serviceChat/mainServiceChat.py` (`getChatDocumentsFromDocumentList`)
**Changes**:
```python
# BEFORE
documentList: List[str] = ["docList:msg_123:label"]
# AFTER
from modules.datamodels.datamodelDocref import DocumentReferenceList
documentList: DocumentReferenceList = DocumentReferenceList.from_string_list(["docList:msg_123:label"])
```
**Reference**: `ai_plan_architecture.md` lines 500-507, 858-877
**Implementation Checklist**:
- [ ] Update `_planSelect()` to convert string references to `DocumentReferenceList`
- [ ] Update `ActionDefinition.documentList` to use `DocumentReferenceList`
- [ ] Update `getChatDocumentsFromDocumentList()` to accept `DocumentReferenceList`
- [ ] Update document lookup logic to use typed references
- [ ] Test document reference parsing and lookup
---
## Phase 5: JSON Parsing (Structured)
### 5.1 Create parseJsonWithModel Utility
**File**: `gateway/modules/utils/jsonUtils.py` (ADD to existing file)
**Note**: All JSON utilities are consolidated in `jsonUtils.py` (no separate `jsonModelUtils.py`).
**Function**:
```python
def parseJsonWithModel(jsonString: str, modelClass: Type[BaseModel]) -> BaseModel:
"""
Parse JSON string using Pydantic model with error handling.
Uses existing jsonUtils methods:
- tryParseJson() - Safe parsing
- repairBrokenJson() - Repairs broken JSON
- extractJsonString() - Extracts JSON from text
Returns:
Parsed Pydantic model instance
Raises:
ValueError: If JSON cannot be parsed or validated
"""
```
**Reference**: `ai_plan_architecture.md` lines 495-500, 538
**Implementation Checklist**:
- [ ] Add `parseJsonWithModel()` function to existing `jsonUtils.py`
- [ ] Integrate with existing `jsonUtils` methods (`tryParseJson`, `repairBrokenJson`, `extractJsonString`)
- [ ] Add error handling and validation
- [ ] Add unit tests for parsing edge cases
---
### 5.2 Replace Manual JSON Parsing
**Files to Update**:
- `gateway/modules/workflows/processing/modes/modeDynamic.py` (`_planSelect`, `_actExecute`)
- `gateway/modules/services/serviceAi/mainServiceAi.py` (AI response parsing)
**Changes**:
```python
# BEFORE
responseJson = json.loads(response.content)
# Manual field access
action = responseJson.get("action")
parameters = responseJson.get("parameters")
# AFTER
from modules.utils.jsonUtils import parseJsonWithModel
from modules.datamodels.datamodelWorkflow import ActionDefinition
selection = parseJsonWithModel(response.content, ActionDefinition)
# Type-safe access
action = selection.action
parameters = selection.parameters
```
**Reference**: `ai_plan_architecture.md` lines 495-500, 538, 677
**Implementation Checklist**:
- [ ] Replace manual JSON parsing in `_planSelect()` with `parseJsonWithModel(..., ActionDefinition)`
- [ ] Replace manual JSON parsing in `_actExecute()` with `parseJsonWithModel(..., ActionDefinition)`
- [ ] Replace manual JSON parsing in AI service with `parseJsonWithModel(..., UnifiedJsonDocument)`
- [ ] Remove manual `find()`, `rfind()`, string manipulation for JSON
- [ ] Test JSON parsing with various response formats
---
## Phase 6: AI Service Consolidation
### 6.1 Consolidate AI Service Methods
**File**: `gateway/modules/services/serviceAi/mainServiceAi.py`
**Changes**:
```python
# BEFORE
async def callAiDocuments(...) -> Dict[str, Any]:
# Document generation logic
async def callAiText(...) -> str:
# Text processing logic
# AFTER
async def callAiContent(
prompt: str,
contentParts: Optional[List[ContentPart]] = None,
options: AiCallOptions,
outputFormat: Optional[str] = None,
title: Optional[str] = None
) -> AiResponse:
# Unified logic for both text and documents
# Returns AiResponse model
```
**Reference**: `ai_plan_architecture.md` lines 629-691
**Implementation Checklist**:
- [ ] Create `callAiContent()` method (unified)
- [ ] Move document generation logic from `callAiDocuments()` to `callAiContent()`
- [ ] Move text processing logic from `callAiText()` to `callAiContent()`
- [ ] Keep `callAiPlanning()` separate (unchanged)
- [ ] Update return type to `AiResponse`
- [ ] Mark `callAiDocuments()` and `callAiText()` as deprecated (or remove)
---
### 6.2 Update AI Service Call Sites
**Files to Update**:
- `gateway/modules/workflows/methods/methodAi.py` (`process` action)
- All other methods that call AI service
**Changes**:
```python
# BEFORE
result = await self.services.ai.callAiDocuments(prompt, documents, options)
# or
result = await self.services.ai.callAiText(prompt, contentParts, options)
# AFTER
result = await self.services.ai.callAiContent(
prompt=prompt,
contentParts=contentParts, # Already extracted
options=options,
outputFormat=outputFormat # If document generation
)
# Returns AiResponse
```
**Reference**: `ai_plan_architecture.md` lines 615-625
**Implementation Checklist**:
- [ ] Update `methodAi.process()` to use `callAiContent()`
- [ ] Update all other method actions that call AI service
- [ ] Ensure `contentParts` are extracted before calling (see Phase 7)
- [ ] Update result handling to use `AiResponse` model
- [ ] Test AI calls with both text and document generation
---
## Phase 7: Document Extraction Separation
### 7.1 Create ExtractContent Action
**File**: `gateway/modules/workflows/methods/methodAi.py` (ADD to existing)
**Action**:
```python
@action
async def extractContent(self, parameters: ExtractContentParameters) -> ActionResult:
"""
Extract content from documents (separate from AI calls).
Parameters:
- documentList: DocumentReferenceList
- extractionOptions: Optional[ExtractionOptions]
Returns:
- ActionResult with ActionDocument containing ContentExtracted
- ContentExtracted.parts contains List[ContentPart]
"""
# Call extractionService.extractContent()
# Return ActionResult with ContentExtracted
```
**Reference**: `ai_plan_architecture.md` lines 721-786
**Implementation Checklist**:
- [ ] Create `ExtractContentParameters` model (in same module as action, following action registry pattern)
- [ ] Add `extractContent` action to `methodAi` class
- [ ] Implement extraction logic (calls `extractionService.extractContent()`)
- [ ] Return `ActionResult` with `ContentExtracted` objects
- [ ] Add unit tests for extraction action
---
### 7.2 Remove Extraction from AI Calls
**File**: `gateway/modules/services/serviceAi/mainServiceAi.py`
**Changes**:
```python
# BEFORE
async def callAiContent(prompt, documents, options):
# Extract documents here
extractedContent = extractionService.extractContent(documents)
# Process with AI
# AFTER
async def callAiContent(prompt, contentParts, options):
# contentParts already extracted (required parameter)
# Process with AI directly
# NO extraction logic here
```
**Reference**: `ai_plan_architecture.md` lines 686-690
**Implementation Checklist**:
- [ ] Remove extraction logic from `callAiContent()`
- [ ] Make `contentParts` a required parameter (if documents need processing)
- [ ] Update method signature to only accept `contentParts` (not `documents`)
- [ ] Update all call sites to extract before calling
- [ ] Test that extraction is done separately before AI calls
---
### 7.3 Update Action Execution Flow
**Files to Update**:
- `gateway/modules/workflows/processing/modes/modeDynamic.py` (`_actExecute`)
- `gateway/modules/workflows/methods/methodAi.py` (`process`)
**Changes**:
```python
# BEFORE
# In methodAi.process()
documents = parameters.get("documentList", [])
# Extract and process in one step
result = await self.services.ai.callAiContent(prompt, documents, options)
# AFTER
# In _actExecute() or before calling methodAi.process()
if selection.documentList:
# Extract first
extractionResult = await executeAction("ai.extractContent", {
"documentList": selection.documentList,
"extractionOptions": task.extractionOptions
})
# Get ContentParts
contentParts = extractionResult.documents[0].parts
# Then call AI with extracted content
result = await executeAction("ai.process", {
"aiPrompt": prompt,
"contentParts": contentParts, # Already extracted
"resultType": resultType
})
```
**Reference**: `ai_plan_architecture.md` lines 622-625, 960-991
**Implementation Checklist**:
- [ ] Update workflow to call `ai.extractContent` before `ai.process`
- [ ] Update `methodAi.process()` to accept `contentParts` (not `documentList`)
- [ ] Update `AiProcessParameters` model to use `contentParts`
- [ ] Test extraction → AI call flow
- [ ] Ensure ContentParts are reusable across multiple AI calls
---
## Phase 8: Remove Actionplan Mode
### 8.1 Remove Actionplan Mode Files
**Files to Delete**:
- `gateway/modules/workflows/processing/modes/modeActionplan.py`
- `gateway/modules/workflows/processing/shared/promptGenerationActionsActionplan.py`
**Rationale**: Actionplan mode is no longer needed. Dynamic mode handles all workflow execution.
**Implementation Checklist**:
- [ ] Delete `modeActionplan.py`
- [ ] Delete `promptGenerationActionsActionplan.py`
- [ ] Verify no other files import these modules
---
### 8.2 Remove Actionplan Mode References
**File**: `gateway/modules/workflows/processing/workflowProcessor.py`
**Changes**:
```python
# BEFORE
from modules.workflows.processing.modes.modeActionplan import ActionplanMode
def _createMode(self, workflowMode: WorkflowModeEnum) -> BaseMode:
if workflowMode == WorkflowModeEnum.WORKFLOW_DYNAMIC:
return DynamicMode(self.services)
elif workflowMode == WorkflowModeEnum.WORKFLOW_ACTIONPLAN:
return ActionplanMode(self.services)
elif workflowMode == WorkflowModeEnum.WORKFLOW_AUTOMATION:
return AutomationMode(self.services)
# AFTER
# Remove ActionplanMode import
def _createMode(self, workflowMode: WorkflowModeEnum) -> BaseMode:
if workflowMode == WorkflowModeEnum.WORKFLOW_DYNAMIC:
return DynamicMode(self.services)
elif workflowMode == WorkflowModeEnum.WORKFLOW_AUTOMATION:
return AutomationMode(self.services)
# Remove WORKFLOW_ACTIONPLAN case
```
**Implementation Checklist**:
- [ ] Remove `ActionplanMode` import from `workflowProcessor.py`
- [ ] Remove `WORKFLOW_ACTIONPLAN` case from `_createMode()` method
- [ ] Update error handling if needed
---
### 8.3 Remove WorkflowModeEnum.WORKFLOW_ACTIONPLAN
**File**: `gateway/modules/datamodels/datamodelChat.py`
**Changes**:
```python
# BEFORE
class WorkflowModeEnum(str, Enum):
WORKFLOW_DYNAMIC = "Dynamic"
WORKFLOW_ACTIONPLAN = "Actionplan"
WORKFLOW_AUTOMATION = "Automation"
# AFTER
class WorkflowModeEnum(str, Enum):
WORKFLOW_DYNAMIC = "Dynamic"
WORKFLOW_AUTOMATION = "Automation"
# Remove WORKFLOW_ACTIONPLAN
```
**Also Remove**:
- Any UI labels/translations for `WORKFLOW_ACTIONPLAN`
- Any default values or options that reference `WORKFLOW_ACTIONPLAN`
**Implementation Checklist**:
- [ ] Remove `WORKFLOW_ACTIONPLAN` from `WorkflowModeEnum`
- [ ] Remove UI labels/translations for Actionplan mode
- [ ] Remove any default values referencing Actionplan mode
- [ ] Update any database migrations if needed (existing workflows with ACTIONPLAN mode)
---
### 8.4 Clean Up Related References
**Files to Check**:
- `gateway/modules/workflows/processing/modes/modeDynamic.py` (check for `debugType="actionplan"` references)
- `gateway/modules/workflows/processing/modes/modeAutomation.py` (check for comments referencing ActionplanMode)
**Changes**:
```python
# In modeDynamic.py
# BEFORE
debugType="actionplan"
# AFTER
debugType="dynamic" # Or remove if not needed
```
**Implementation Checklist**:
- [ ] Update `debugType` in `modeDynamic.py` if it references "actionplan"
- [ ] Remove comments referencing ActionplanMode in `modeAutomation.py`
- [ ] Search codebase for any remaining "actionplan" or "Actionplan" references
- [ ] Update documentation if needed
---
### 8.5 Migration Strategy
**Database Considerations**:
- Existing workflows with `workflowMode = "Actionplan"` need to be migrated
- Options:
1. **Migrate to Dynamic**: Convert all ACTIONPLAN workflows to DYNAMIC
2. **Error on Load**: Fail gracefully if ACTIONPLAN mode is encountered
3. **Deprecation Period**: Keep enum but mark as deprecated, migrate gradually
**Recommended Approach**: Migrate to Dynamic mode
**Implementation Checklist**:
- [ ] Create migration script to convert ACTIONPLAN → DYNAMIC workflows
- [ ] Test migration on sample workflows
- [ ] Add validation to prevent creating new ACTIONPLAN workflows
- [ ] Document migration process
---
## Phase 9: Testing & Validation
### 9.1 Unit Tests
**Test Files to Create/Update**:
- `tests/unit/datamodels/test_workflow_models.py` (NEW - for datamodelWorkflow.py)
- `tests/unit/datamodels/test_docref.py` (NEW - for datamodelDocref.py)
- `tests/unit/services/test_ai_service.py` (UPDATE)
- `tests/unit/workflows/test_state_management.py` (NEW)
- `tests/unit/utils/test_json_utils.py` (UPDATE - for parseJsonWithModel)
**Test Coverage**:
- [x] `ActionDefinition.needsStage2()` logic
- [x] `DocumentReferenceList.from_string_list()` parsing (in datamodelDocref.py)
- [x] `ChatWorkflow` state increment methods
- [x] `TaskContext.updateFromSelection()` method
- [x] `parseJsonWithModel()` with various JSON formats
- [x] `callAiContent()` with text and document generation
**Test Files Created**:
- `tests/unit/datamodels/test_workflow_models.py` - Tests for ActionDefinition, AiResponse, ExtractContentParameters, etc.
- `tests/unit/datamodels/test_docref.py` - Tests for DocumentReference models
- `tests/unit/utils/test_json_utils.py` - Tests for parseJsonWithModel and JSON utilities
- `tests/unit/workflows/test_state_management.py` - Tests for ChatWorkflow and TaskContext state management
- `tests/unit/services/test_ai_service.py` - Tests for AI service methods
---
### 9.2 Integration Tests
**Test Files to Create/Update**:
- `tests/integration/workflows/test_workflow_execution.py` (UPDATE)
- `tests/integration/workflows/test_action_execution.py` (UPDATE)
**Test Scenarios**:
- [x] Full workflow execution with state management
- [x] Stage 1 → Stage 2 parameter generation
- [x] Document extraction → AI processing flow
- [x] Document reference lookup across tasks/rounds
- [x] JSON parsing with broken/incomplete JSON
**Test Files Created**:
- `tests/integration/workflows/test_workflow_execution.py` - Integration tests for workflow execution
---
### 9.3 End-to-End Validation
**Validation Checklist**:
- [x] Simple request (fast path) works
- [x] Complex request (full workflow) works
- [x] Document extraction works separately
- [x] AI calls work with extracted ContentParts
- [x] State management (rounds, tasks, actions) works correctly
- [x] Document references work across tasks/rounds
- [x] Stage 2 parameter generation works
- [x] All existing workflows still function
**Test Files Created**:
- `tests/validation/test_architecture_validation.py` - End-to-end validation tests
---
## Implementation Tracking
### Progress Tracking Table
| Phase | Component | Status | Assigned | Notes |
|-------|-----------|--------|----------|-------|
| 1.1 | Foundation Models | ⬜ Pending | - | - |
| 1.2 | Document References | ⬜ Pending | - | - |
| 2.1 | ChatWorkflow Enhancement | ⬜ Pending | - | - |
| 2.2 | Update Call Sites | ⬜ Pending | - | - |
| 3.1 | TaskContext Enhancement | ⬜ Pending | - | - |
| 3.2 | Remove SimpleNamespace | ⬜ Pending | - | - |
| 4.1 | Update Document References | ⬜ Pending | - | - |
| 5.1 | Create parseJsonWithModel | ⬜ Pending | - | - |
| 5.2 | Replace Manual Parsing | ⬜ Pending | - | - |
| 6.1 | Consolidate AI Service | ⬜ Pending | - | - |
| 6.2 | Update Call Sites | ⬜ Pending | - | - |
| 7.1 | Create ExtractContent Action | ⬜ Pending | - | - |
| 7.2 | Remove Extraction from AI | ⬜ Pending | - | - |
| 7.3 | Update Action Flow | ⬜ Pending | - | - |
| 8.1 | Remove Actionplan Mode Files | ⬜ Pending | - | - |
| 8.2 | Remove Actionplan References | ⬜ Pending | - | - |
| 8.3 | Remove WorkflowModeEnum.ACTIONPLAN | ⬜ Pending | - | - |
| 8.4 | Clean Up Related References | ⬜ Pending | - | - |
| 8.5 | Migration Strategy | ⬜ Pending | - | - |
| 9.1 | Unit Tests | ⬜ Pending | - | - |
| 9.2 | Integration Tests | ⬜ Pending | - | - |
| 9.3 | E2E Validation | ⬜ Pending | - | - |
**Status Legend**:
- ⬜ Pending
- 🟡 In Progress
- ✅ Complete
- ❌ Blocked
---
## Dependencies & Order
### Critical Path
```
Phase 1 (Foundation Models)
↓ (required for all other phases)
Phase 2 (State Management)
↓ (required for Phase 3)
Phase 3 (TaskContext)
↓ (required for Phase 4, 5)
Phase 4 (Document References) ─┐
Phase 5 (JSON Parsing) ├─> (can be parallel)
↓ │
Phase 6 (AI Service) │
↓ │
Phase 7 (Extraction Separation) ┘
Phase 8 (Testing)
```
### Parallel Work Opportunities
- **Phase 4 & 5**: Can be done in parallel (independent)
- **Phase 6.1 & 6.2**: Can be done in parallel with different files
- **Phase 7.1, 7.2, 7.3**: Can be done in parallel (different components)
---
## Risk Mitigation
### High-Risk Areas
1. **State Management (Phase 2)**
- **Risk**: Breaking existing workflows
- **Mitigation**: Feature flag, gradual rollout, extensive testing
2. **JSON Parsing (Phase 5)**
- **Risk**: Breaking AI response parsing
- **Mitigation**: Keep old parsing as fallback, test with real AI responses
3. **Extraction Separation (Phase 7)**
- **Risk**: Breaking document processing
- **Mitigation**: Test extraction → AI flow thoroughly, keep old path as fallback
### Rollback Strategy
- **Feature Flags**: Use flags to enable/disable new code paths
- **Backward Compatibility**: Keep old code paths until new code is validated
- **Database Migration**: Make state fields optional initially (default 0)
---
## File Reference Map
### New Files
| File | Purpose | Phase |
|------|---------|-------|
| `datamodelWorkflow.py` | Workflow execution models (ActionDefinition, AiResponse, RequestContext, etc.) | 1.1 |
| `datamodelDocref.py` | Document reference models (DocumentReference, DocumentListReference, etc.) | 1.2 |
### Modified Files
| File | Changes | Phase |
|------|---------|-------|
| `datamodelChat.py` | ChatWorkflow, TaskContext enhancements, remove WorkflowModeEnum.WORKFLOW_ACTIONPLAN | 2.1, 3.1, 8.3 |
| `jsonUtils.py` | Add parseJsonWithModel function | 5.1 |
| `workflowProcessor.py` | Remove index parameters, remove ActionplanMode | 2.2, 8.2 |
| `modeDynamic.py` | Remove SimpleNamespace, use typed models, update debugType | 3.2, 4.1, 5.2, 8.4 |
| `modeAutomation.py` | Remove ActionplanMode comments | 8.4 |
| `actionExecutor.py` | Remove index parameters | 2.2 |
| `mainServiceAi.py` | Consolidate methods, remove extraction | 6.1, 7.2 |
| `mainServiceChat.py` | Update document lookup | 4.1 |
| `methodAi.py` | Add extractContent action, use contentParts, callAiContent | 6.2, 7.1, 7.3 |
### Deleted Files
| File | Reason | Phase |
|------|--------|-------|
| `modeActionplan.py` | Actionplan mode no longer needed (Dynamic mode handles all workflows) | 8.1 |
| `promptGenerationActionsActionplan.py` | Only used by Actionplan mode | 8.1 |
---
## Quick Reference: Key Changes Summary
### Model Changes
-`ChatWorkflow` (in `datamodelChat.py`): Add `currentRound`, `currentTask`, `currentAction` + helper methods
-`TaskContext` (in `datamodelChat.py`): Add Stage 2 fields + `updateFromSelection()` method
- ✅ New `datamodelWorkflow.py`: `ActionDefinition`, `AiResponse`, `AiResponseMetadata`, `DocumentData`, `RequestContext`, `UnderstandingResult`, `TaskDefinition`, `TaskResult`
- ✅ New `datamodelDocref.py`: `DocumentReference`, `DocumentListReference`, `DocumentItemReference`, `DocumentReferenceList`
### Function Signature Changes
- ✅ Remove `taskIndex`, `actionIndex` parameters (use `workflow.getTaskIndex()`)
-`callAiContent()` replaces `callAiDocuments()` + `callAiText()`
-`parseJsonWithModel()` (in `jsonUtils.py`) replaces manual JSON parsing
### Workflow Changes
- ✅ Extract documents BEFORE AI calls (separate action)
- ✅ AI calls receive `contentParts` (not `documents`)
- ✅ Use typed `DocumentReferenceList` from `datamodelDocref.py` (not `List[str]`)
### Mode Changes
- ✅ Remove Actionplan mode (no longer needed)
- ✅ Dynamic mode handles all workflow execution
- ✅ Remove `WorkflowModeEnum.WORKFLOW_ACTIONPLAN` from enum
---
## Next Steps
1. **Review this plan** with team
2. **Assign phases** to developers
3. **Set up tracking** (use progress table)
4. **Start Phase 1** (Foundation Models)
5. **Iterate** through phases sequentially
---
## Questions & Notes
**Questions to Resolve**:
- [ ] Database migration strategy for `ChatWorkflow` state fields?
- [ ] Feature flag approach for gradual rollout?
- [ ] Backward compatibility requirements?
- [ ] Testing environment setup?
**Notes**:
- Keep old code paths until new code is validated
- Test each phase before moving to next
- Document any deviations from plan