Adds GET /api/graph/project/<id>/download/source, GET /api/simulation/<id>/download/report,
and GET /api/simulation/<id>/download/log with corresponding tests (5/5 passing).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implements Tasks 8 and 9 of F2-A+B: async agent creation from entity UUID
and async per-agent profile regeneration, both with atomic profile file writes.
Refactors generate_profile_from_entity to accept extra_instructions instead
of requiring user_id (renamed internal logic to _generate_single_profile).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implements SimulationManager.clone_simulation() and the corresponding
Flask route. The clone copies reddit_profiles.json, twitter_profiles.csv
and agent_profiles.json from the source simulation; does not copy
simulation_config.json; sets status=PROFILES_READY and records
parent_simulation_id. All 3 tests in test_simulation_clone.py pass.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implements atomic agent profile editing with manually_edited flag.
Blocks edits when simulation is running or completed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
8 tests covering list, get, create, delete, and reset endpoints via
Flask test client with in-memory SQLite and mocked storage.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replace conftest.py with two autouse fixtures: reset_graph_factory_singleton
and reset_task_manager_singleton, plus in_memory_db fixture for tests
requiring a real DB
- Rewrite test_project_task_recovery.py to use ProjectManager + SQLite in-memory
DB instead of the removed Project dataclass (same guarantee: active_task_id
persists and defaults to None)
- Fix db.py init_db() to import db_models before Base.metadata.create_all() so
all ORM tables are registered and created on first startup
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace file-based JSON persistence with SQLAlchemy DB (ProjectModel/ProjectFileModel)
and StorageService for file content; remove Project dataclass; add 7 passing tests.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace in-memory dict-based TaskManager with a SQLAlchemy-backed implementation
using TaskModel. Tasks now survive process restarts. 6 new tests added and passing.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds ?format=md|pdf query param to GET /api/report/<id>/download.
PDF is generated from Markdown via fitz.Story (PyMuPDF). Also fixes
create_app() to support dict config and skip JWT auth in TESTING mode.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When LLM_PROVIDER=gemini, LLMClient automatically uses the Google AI Studio
OpenAI-compatible endpoint instead of requiring manual base_url configuration.
An explicit base_url argument still takes precedence.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>