feat: add remote runtime state bridge - #153
Conversation
|
@hvpareja is attempting to deploy a commit to the yhy-4770's projects Team on Vercel. A member of the Team first needs to authorize it. |
|
This PR has been generated by IA. I am reviewing now. |
| logger.info(f"Monitoring {len(self.handles)} agent(s) (check every {check_interval}s)...") | ||
|
|
||
| while self._running: | ||
| self._sync_remote_state() |
There was a problem hiding this comment.
Review note: _sync_remote_state() calls the adapter's collect_metrics() synchronously inside the manager monitor loop. That keeps this first cut simple, but a slow or blocking remote adapter could delay heartbeat/restart handling. If this grows beyond lightweight polling, the next step should be a timeout, background worker, or async sync path.
| self.state_dir.mkdir(parents=True, exist_ok=True) | ||
|
|
||
| for state in serialized: | ||
| self._write_json(self.state_dir / f"{state['agent_id']}.json", state) |
There was a problem hiding this comment.
Review note: agent_id comes from the adapter and is used directly as a filename. If a remote adapter returns values containing /, .., or other path separators, this could write outside the intended remote_state directory or create surprising nested paths. Before this becomes a stable contract, we should either validate/sanitize agent_id here or document a strict safe-ID requirement for adapters.
There was a problem hiding this comment.
Addressed in 54d5cc3 by percent-encoding agent_id for the per-agent state filename while preserving the original agent_id in index.json and the snapshot payload. Added test_remote_state_bridge_encodes_agent_id_for_filename to cover ../remote/agent.
Motivation
Refs #151.
CORAL currently has local subprocess runtimes and public run state, but no generic contract for surfacing agents that execute in managed remote runtimes. This PR starts with the additive state-bridge layer so remote adapters can publish normalized state without changing the existing local worktree agent flow.
Authored with assistance from Codex. I read every changed line before opening this draft PR and verified the commands below locally.
Changes
RemoteRuntime, remote agent handle/spec/state dataclasses, dynamic adapter loading, and aRemoteStateBridgethat writes.coral/public/remote_state/.agents.remote_runtimeconfig with YAMLclass:support and runtime-specific config payloads.AgentManagerperiodically sync remote state when the block is configured, while leaving local subprocess agents unchanged.coral statusand the web/api/statusresponse.Test plan
uv run --extra dev python -m pytest tests/ -v— 552 passed, 1 skippeduv run --extra dev ruff check .— passeduv run --extra dev ruff format --check .— passedAffected areas
coral/agent/(runtime, manager, heartbeat, warmstart)coral/grader/(daemon, TaskGrader, subprocess grader, loader)coral/hub/(attempts, notes, skills, checkpoint)coral/workspace/(project setup, worktrees, grader env)coral/cli/(commands, helpers)coral/hooks/(post_commit / submit_eval)coral/template/(CORAL.md, bundled skills/agents)coral/gateway/(LiteLLM gateway)coral/web/(dashboard)examples/(new or modified task)docs/(docs site)Checklist
feat:,fix:,docs:,refactor:, ...).uv run pytest tests/ -vpasses locally.uv run ruff check .anduv run ruff format --check .pass.tests/for any behavior change.docs/content/, README, or relevant skill under.claude/skills/) for any user-visible or contract change.examples/<task>/:coral validate <task>succeeds and a smoke run produces at least one finalized score. No hidden answer keys committed underseed/.