Commit Graph

190 Commits

Author SHA1 Message Date
gilesb
e806337503 Remove unnecessary redirect routes, fix template links
- Removed /run/{id} and /recipe/{id} redirect routes
- Updated templates to use /runs/ and /recipes/ paths

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 18:05:24 +00:00
gilesb
6c73a06539 Fix redirect handlers to pass dependencies explicitly
The /run/{id} and /recipe/{id} redirects were calling route handlers
directly without passing the required service dependencies.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 18:02:24 +00:00
gilesb
970faa3fa0 Fix run recipe: optional fields in RunStatus, list->dict nodes
- Made recipe and inputs optional in RunStatus model
- Convert DAG nodes from list format to dict format when running recipes

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 17:50:36 +00:00
gilesb
b57745098e Fix run_recipe to handle dict return from create_run
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 17:43:31 +00:00
gilesb
2e9ba46f19 Use UserContext from artdag_common, remove duplicate
- Updated requirements.txt to use art-common@11aa056 with l2_server field
- All routers now import UserContext from artdag_common
- Removed duplicate UserContext from auth_service.py
- dependencies.py sets l2_server from settings on user context

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 17:38:02 +00:00
gilesb
9e3c4c9d78 Add l2_server to UserContext
Fixes AttributeError when running recipes - the UserContext was
missing the l2_server field that run_service expects.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 17:28:40 +00:00
gilesb
3373be285e Fix recipe list links and home page recipe count
- Template used recipe.id but service returns recipe.recipe_id
- Add recipe count to home page stats

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 17:26:00 +00:00
gilesb
a6fe88c277 Fix recipe upload to accept file uploads instead of JSON
The CLI client sends multipart file uploads but the server expected JSON.
Changed the /recipes/upload endpoint to accept UploadFile and return
the additional fields (name, version, variable_inputs, fixed_inputs)
that the client expects.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 17:13:06 +00:00
gilesb
697fa7c64d Show actual media count on home page 2026-01-11 16:55:14 +00:00
gilesb
f6a7e0852c Fix cache detail template field names 2026-01-11 16:53:48 +00:00
gilesb
921d81421a Fix cache method name: get_content_path -> get_by_content_hash
The L1CacheManager uses get_by_content_hash not get_content_path.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 16:36:29 +00:00
gilesb
27cbb0a85c Store MIME type in database during upload
Detect actual MIME type from file content and store it instead of
generic "media" type. This enables proper media categorization
and filtering in the UI.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 16:18:56 +00:00
gilesb
9c148f535d Fix media list template field names
- Use content_hash instead of hash
- Use type instead of media_type
- Show filename instead of size_bytes
- Detect media type from both type field and filename extension

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 16:18:09 +00:00
gilesb
c0fe22313f Update artdag_common to fix auth token handling
New version defaults actor_id to @username when not in token,
and supports both artdag_session and auth_token cookies.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 16:07:43 +00:00
giles
e8501de466 Fix list_media to use get_user_items instead of list_cache_items
list_cache_items doesn't accept actor_id parameter.
Use get_user_items which properly filters by actor_id and item_type.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 14:10:49 +00:00
giles
4b22fb6588 Index all DAG node outputs by content_hash and upload to IPFS
- Process all node_results after DAG execution
- Store each intermediate/effect output in cache_manager
- Upload all node outputs to IPFS (not just final output)
- Track node_hashes and node_ipfs_cids mappings
- Save run result to database with run_id
- Include nodes with content_hash + ipfs_cid in provenance
- Return node_hashes and node_ipfs_cids in task result

All DAG nodes are now content-addressable via /cache/{content_hash}

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 14:08:41 +00:00
giles
854396680f Refactor storage: remove Redis duplication, use proper data tiers
- Recipes: Now content-addressed only (cache + IPFS), removed Redis storage
- Runs: Completed runs stored in PostgreSQL, Redis only for task_id mapping
- Add list_runs_by_actor() to database.py for paginated run queries
- Add list_by_type() to cache_manager for filtering by node_type
- Fix upload endpoint to return size and filename fields
- Fix recipe run endpoint with proper DAG input binding
- Fix get_run_service() dependency to pass database module

Storage architecture:
- Redis: Ephemeral only (sessions, task mappings with TTL)
- PostgreSQL: Permanent records (completed runs, metadata)
- Cache: Content-addressed files (recipes, media, outputs)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 14:05:31 +00:00
giles
8591faf0fc Fix CacheService list_media and recipe inputs type
- Add list_media method to CacheService
- Change recipe run inputs from List to dict

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 13:28:27 +00:00
giles
4f011a66ff Fix recipe run endpoint to accept JSON body
Use Pydantic model for inputs parameter.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 13:22:13 +00:00
giles
b47417704e Fix /media route by mounting cache router directly
Avoids Depends() resolution issues with manual function calls.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 13:21:26 +00:00
giles
3f77c24699 Enable markdown tables and fenced_code extensions
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 13:20:48 +00:00
giles
ada51c0880 Add 404 handler and template
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 13:14:29 +00:00
giles
e7e95b7857 Fix Request type hints in redirect handlers
FastAPI requires type hints to recognize Request objects.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 13:11:36 +00:00
giles
828a958a7b Update artdag-common to 889ea98 with prose fix 2026-01-11 13:10:45 +00:00
giles
7c6b8d7170 Pin artdag-common to commit 2163cbd
Forces pip to fetch latest version with typography plugin.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 13:02:25 +00:00
giles
f0db4f4ea6 Restore home page with README display
Instead of redirecting to /runs, show the home page with stats and README.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 12:54:50 +00:00
giles
a34fff3aaa Add database init/close lifecycle events to app startup
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 12:52:29 +00:00
giles
b372d02df2 Fix list_recipes to use offset parameter
Match the router's expected signature and return type.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 12:43:54 +00:00
giles
d19d6d6e42 Fix RecipeService initialization with cache manager
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 12:34:39 +00:00
giles
eed4596af8 Update base.html to extend _base.html
Matches renamed template in artdag-common package.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 12:28:26 +00:00
giles
83cce09b1a Fix list_runs to use offset parameter
Match the router's expected signature and return type.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 12:22:59 +00:00
giles
0ec1de3cb7 Add httpx dependency
Required by auth_service module.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 12:18:11 +00:00
giles
cc6be54a92 Add artdag-common dependency 2026-01-11 11:55:40 +00:00
giles
29da91e01a Refactor to modular app factory architecture
- Replace 6847-line monolithic server.py with 26-line entry point
- All routes now in app/routers/ using Jinja2 templates
- Add plan_node.html template for step details
- Add plan node route to runs router with cache_id lookup
- Backup old server as server_legacy.py

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 11:48:24 +00:00
giles
73b7f173c5 Use cache_id for plan node details and show input/output media
- Changed node click to use cache_id in URL instead of step_id
- Updated route to lookup step by cache_id
- Added input media previews showing thumbnails of each input step
- Enhanced output preview with video/image/audio support
- Added parameters section showing step config
- Updated JavaScript to pass cacheId when clicking nodes

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 11:44:21 +00:00
giles
17b92c77ef Fix async function call for load_plan_for_run_with_fallback
Use await directly instead of asyncio.to_thread() since the
function is already async.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 11:31:27 +00:00
giles
64ef9396d6 Add /help routes to display README documentation
Provides /help index and /help/{doc_name} routes to view
L1 server and Common library READMEs in the web UI.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 11:30:36 +00:00
giles
255d44fbf6 Remove redundant documentation UI routes
/docs now correctly points to FastAPI's Swagger API docs.
README files can be viewed directly in the git repository.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 11:21:16 +00:00
giles
de9fbaed4a Add debug logging for plan loading 2026-01-11 10:24:58 +00:00
giles
c68c0cedba Fix plan node detail to generate plan from recipe if not cached
- Add load_plan_for_run_with_fallback() that generates plan from recipe
  when not found in cache
- Share this helper between plan page and node detail endpoint
- Removes code duplication

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 10:23:03 +00:00
giles
45eb9c0b1c Fix plan loading and add inline DAG view for recipes
- Add load_plan_for_run() helper that tries plan_id first, then matches by inputs
- Fix "plan not found" error when clicking plan nodes
- Add inline DAG visualization to recipe detail page with tabs (DAG View / YAML Source)
- Recipe page now uses render_page_with_cytoscape for proper DAG rendering

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 10:09:07 +00:00
giles
28349ad944 Add documentation routes and update README
- Update README with comprehensive documentation covering IPFS-primary mode,
  3-phase execution, storage providers, and all API endpoints
- Add /docs routes to serve markdown documentation as styled HTML
- Include common library documentation in web interface

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 09:58:31 +00:00
gilesb
ca8bfd8705 Add hybrid state manager for distributed L1 coordination
Implements HybridStateManager providing fast local Redis operations
with background IPNS sync for eventual consistency across L1 nodes.

- hybrid_state.py: Centralized state management (cache, claims, analysis, plans, runs)
- Updated execute_cid.py, analyze_cid.py, orchestrate_cid.py to use state manager
- Background IPNS sync (configurable interval, disabled by default)
- Atomic claiming with Redis SETNX for preventing duplicate work

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 09:36:14 +00:00
giles
f11cec9d48 Add SPA-style navigation for plan nodes
- Add /run/{run_id}/plan/node/{step_id} endpoint for node details
- Node click updates URL without full page reload (pushState)
- Browser back/forward works correctly
- Refreshing page preserves selected node via ?node= parameter
- Node details loaded via fetch with partial HTML response

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 09:30:27 +00:00
gilesb
0634142576 Add ARTDAG_CLUSTER_KEY to docker-compose
Reads from environment or .env file.
Must be same on server and workers for consistent cache_ids.

Generate with: openssl rand -hex 32

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 09:17:41 +00:00
giles
c145d4a427 Add IPFS_PRIMARY mode UI support
- Add output_ipfs_cid field to RunStatus model
- Handle output_cid from IPFS-primary task results
- Add /ipfs/{cid} redirect route to IPFS gateway
- Add /ipfs/{cid}/raw to fetch and serve IPFS content
- Show IPFS output in run detail when output_hash unavailable
- Display step CIDs on plan page for IPFS_PRIMARY runs

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 08:32:27 +00:00
gilesb
68c2e45541 Add IPFS_PRIMARY environment variable for server
When IPFS_PRIMARY=true:
- /api/run-recipe uses run_recipe_cid task
- Recipe registered on IPFS before execution
- Input CIDs fetched from cache manager
- Everything flows through IPFS, no local cache

Usage in docker-compose:
  environment:
    - IPFS_PRIMARY=true

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 08:27:24 +00:00
giles
791fe31483 Fix double-encoded JSON in Plan JSON display
Parse nested plan_json field before displaying to avoid escaped newlines.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 08:19:44 +00:00
gilesb
25f7213741 Add IPFS-primary orchestration
Complete pipeline with everything on IPFS:
- register_input_cid / register_recipe_cid
- generate_plan_cid (stores plan on IPFS)
- execute_plan_from_cid (fetches plan from IPFS)
- run_recipe_cid (full pipeline, returns output CID)
- run_from_local (convenience: local files → IPFS → run)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 08:18:34 +00:00
gilesb
92d154f524 Add IPFS-primary analysis task
- Fetches input from IPFS by CID
- Stores analysis JSON on IPFS
- Returns analysis_cid
- Redis cache: input_hash:features → analysis CID

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 08:15:55 +00:00