Spaces:
Running
Running
Joseph Pollack
adds file returns , configuration enhancements , oauth fixes , and interface fixes
f961a19
| # File Output Implementation Plan | |
| ## Overview | |
| This plan implements file writing and return functionality for report-writing agents, enabling reports to be saved as files and returned through the Gradio ChatInterface. | |
| ## Current State Analysis | |
| β **Report Generation**: All agents generate markdown strings | |
| β **File Output Integration**: `event_to_chat_message()` supports file paths | |
| β **Graph Orchestrator**: Can handle file paths in results | |
| β **File Writing**: No agents write files to disk | |
| β **File Service**: No utility service for saving reports | |
| --- | |
| ## Implementation Plan | |
| ### PROJECT 1: File Writing Service | |
| **Goal**: Create a reusable service for saving reports to files | |
| #### Activity 1.1: Create Report File Service | |
| **File**: `src/services/report_file_service.py` (NEW) | |
| **Tasks**: | |
| 1. Create `ReportFileService` class | |
| 2. Implement `save_report()` method | |
| - Accepts: report content (str), filename (optional), output_dir (optional) | |
| - Returns: file path (str) | |
| - Uses temp directory by default | |
| - Supports custom output directory | |
| - Handles file naming with timestamps | |
| 3. Implement `save_report_multiple_formats()` method | |
| - Save as .md (always) | |
| - Optionally save as .html, .pdf (future) | |
| 4. Add configuration support | |
| - Read from settings | |
| - Enable/disable file saving | |
| - Configurable output directory | |
| 5. Add error handling and logging | |
| 6. Add file cleanup utilities (optional) | |
| **Line-level subtasks**: | |
| - Line 1-20: Imports and class definition | |
| - Line 21-40: `__init__()` method with settings | |
| - Line 41-80: `save_report()` method | |
| - Line 41-50: Input validation | |
| - Line 51-60: Directory creation | |
| - Line 61-70: File writing | |
| - Line 71-80: Error handling | |
| - Line 81-100: `save_report_multiple_formats()` method | |
| - Line 101-120: Helper methods (filename generation, cleanup) | |
| --- | |
| ### PROJECT 2: Configuration Updates | |
| **Goal**: Add settings for file output functionality | |
| #### Activity 2.1: Update Settings Model | |
| **File**: `src/utils/config.py` | |
| **Tasks**: | |
| 1. Add `save_reports_to_file: bool` field (default: True) | |
| 2. Add `report_output_directory: str | None` field (default: None, uses temp) | |
| 3. Add `report_file_format: Literal["md", "md_html", "md_pdf"]` field (default: "md") | |
| 4. Add `report_filename_template: str` field (default: "report_{timestamp}_{query_hash}.md") | |
| **Line-level subtasks**: | |
| - Line 166-170: Add `save_reports_to_file` field after TTS config | |
| - Line 171-175: Add `report_output_directory` field | |
| - Line 176-180: Add `report_file_format` field | |
| - Line 181-185: Add `report_filename_template` field | |
| --- | |
| ### PROJECT 3: Graph Orchestrator Integration | |
| **Goal**: Integrate file writing into graph execution | |
| #### Activity 3.1: Update Graph Orchestrator | |
| **File**: `src/orchestrator/graph_orchestrator.py` | |
| **Tasks**: | |
| 1. Import `ReportFileService` at top | |
| 2. Initialize service in `__init__()` (optional, can be lazy) | |
| 3. Modify `_execute_agent_node()` for synthesizer node | |
| - After `long_writer_agent.write_report()`, save to file | |
| - Return dict with `{"message": report, "file": file_path}` | |
| 4. Update final event generation to handle file paths | |
| - Already implemented, verify it works correctly | |
| **Line-level subtasks**: | |
| - Line 1-35: Add import for `ReportFileService` | |
| - Line 119-148: Update `__init__()` to accept optional file service | |
| - Line 589-650: Modify `_execute_agent_node()` synthesizer handling | |
| - Line 642-645: After `write_report()`, add file saving | |
| - Line 646-650: Return dict with file path | |
| - Line 534-564: Verify final event generation handles file paths (already done) | |
| --- | |
| ### PROJECT 4: Research Flow Integration | |
| **Goal**: Integrate file writing into research flows | |
| #### Activity 4.1: Update IterativeResearchFlow | |
| **File**: `src/orchestrator/research_flow.py` | |
| **Tasks**: | |
| 1. Import `ReportFileService` at top | |
| 2. Add optional file service to `__init__()` | |
| 3. Modify `_create_final_report()` method | |
| - After `writer_agent.write_report()`, save to file if enabled | |
| - Return string (backward compatible) OR dict with file path | |
| **Line-level subtasks**: | |
| - Line 1-50: Add import for `ReportFileService` | |
| - Line 48-120: Update `__init__()` to accept optional file service | |
| - Line 622-667: Modify `_create_final_report()` method | |
| - Line 647-652: After `write_report()`, add file saving | |
| - Line 653-667: Return report string (keep backward compatible for now) | |
| #### Activity 4.2: Update DeepResearchFlow | |
| **File**: `src/orchestrator/research_flow.py` | |
| **Tasks**: | |
| 1. Add optional file service to `__init__()` (if not already) | |
| 2. Modify `_create_final_report()` method | |
| - After `long_writer_agent.write_report()` or `proofreader_agent.proofread()`, save to file | |
| - Return string (backward compatible) OR dict with file path | |
| **Line-level subtasks**: | |
| - Line 670-750: Update `DeepResearchFlow.__init__()` to accept optional file service | |
| - Line 954-1005: Modify `_create_final_report()` method | |
| - Line 979-983: After `write_report()`, add file saving | |
| - Line 984-989: After `proofread()`, add file saving | |
| - Line 990-1005: Return report string (keep backward compatible) | |
| --- | |
| ### PROJECT 5: Agent Factory Integration | |
| **Goal**: Make file service available to agents if needed | |
| #### Activity 5.1: Update Agent Factory (Optional) | |
| **File**: `src/agent_factory/agents.py` | |
| **Tasks**: | |
| 1. Add optional file service parameter to agent creation functions (if needed) | |
| 2. Pass file service to agents that need it (currently not needed, agents return strings) | |
| **Line-level subtasks**: | |
| - Not required - agents return strings, file writing happens at orchestrator level | |
| --- | |
| ### PROJECT 6: Testing & Validation | |
| **Goal**: Ensure file output works end-to-end | |
| #### Activity 6.1: Unit Tests | |
| **File**: `tests/unit/services/test_report_file_service.py` (NEW) | |
| **Tasks**: | |
| 1. Test `save_report()` with default settings | |
| 2. Test `save_report()` with custom directory | |
| 3. Test `save_report()` with custom filename | |
| 4. Test error handling (permission errors, disk full, etc.) | |
| 5. Test file cleanup | |
| **Line-level subtasks**: | |
| - Line 1-30: Test fixtures and setup | |
| - Line 31-60: Test basic save functionality | |
| - Line 61-90: Test custom directory | |
| - Line 91-120: Test error handling | |
| #### Activity 6.2: Integration Tests | |
| **File**: `tests/integration/test_file_output_integration.py` (NEW) | |
| **Tasks**: | |
| 1. Test graph orchestrator with file output | |
| 2. Test research flows with file output | |
| 3. Test Gradio ChatInterface receives file paths | |
| 4. Test file download in Gradio UI | |
| **Line-level subtasks**: | |
| - Line 1-40: Test setup with mock orchestrator | |
| - Line 41-80: Test file generation in graph execution | |
| - Line 81-120: Test file paths in AgentEvent | |
| - Line 121-160: Test Gradio message conversion | |
| --- | |
| ## Implementation Order | |
| 1. **PROJECT 2** (Configuration) - Foundation | |
| 2. **PROJECT 1** (File Service) - Core functionality | |
| 3. **PROJECT 3** (Graph Orchestrator) - Primary integration point | |
| 4. **PROJECT 4** (Research Flows) - Secondary integration points | |
| 5. **PROJECT 6** (Testing) - Validation | |
| 6. **PROJECT 5** (Agent Factory) - Not needed, skip | |
| --- | |
| ## File Changes Summary | |
| ### New Files | |
| - `src/services/report_file_service.py` - File writing service | |
| - `tests/unit/services/test_report_file_service.py` - Unit tests | |
| - `tests/integration/test_file_output_integration.py` - Integration tests | |
| ### Modified Files | |
| - `src/utils/config.py` - Add file output settings | |
| - `src/orchestrator/graph_orchestrator.py` - Add file saving after report generation | |
| - `src/orchestrator/research_flow.py` - Add file saving in both flows | |
| --- | |
| ## Gradio Integration Notes | |
| According to Gradio ChatInterface documentation: | |
| - File paths in chat message content are automatically converted to download links | |
| - Markdown links like `[Download: filename](file_path)` work | |
| - Files must be accessible from the Gradio server | |
| - Temp files are fine as long as they exist during the session | |
| Current implementation in `event_to_chat_message()` already handles this correctly. | |
| --- | |
| ## Success Criteria | |
| β Reports are saved to files when generated | |
| β File paths are included in AgentEvent data | |
| β File paths appear as download links in Gradio ChatInterface | |
| β File saving is configurable (can be disabled) | |
| β Backward compatible (existing code still works) | |
| β Error handling prevents crashes if file writing fails | |