Skip to content

feat: per-agent status tracking with Python watcher daemon#57

Open
jezekra1 wants to merge 1 commit intomainfrom
feat/per-agent-status-tracking
Open

feat: per-agent status tracking with Python watcher daemon#57
jezekra1 wants to merge 1 commit intomainfrom
feat/per-agent-status-tracking

Conversation

@jezekra1
Copy link
Copy Markdown
Collaborator

@jezekra1 jezekra1 commented Mar 26, 2026

Summary

  • Per-agent fact files: Each agent (main + subagents) writes its own {session_id}.agent.{key}.json file. File locking (fcntl.flock) prevents concurrent hook races. Session-level status is derived from agent priorities: needs_approval > working > waiting.
  • Python watcher daemon (--watch mode): Single background process polls every 1.5s, resolving hook blind spots:
    • Transcript resolution: detects tool completion/rejection when no hook fires
    • Process inspection: flips needs_approval → working when a command is already running as a child process
    • Interruption detection: sets all agents to waiting on user interrupt
    • PID liveness cleanup: removes dead session files
    • Self-terminates after 60s with no active sessions. ensure_watcher() on every hook invocation restarts it if needed.
  • Swift simplified to pure file reader: SessionProcessor stripped from 273 → 65 lines (only deriveStatus, isGhost, abandoned detection). SessionStateWatcher uses DispatchSource only — no timer, no PID checks, no transcript parsing. All resolution state is persisted to disk.
  • Lock file cleanup: fact file deletion now also removes .lock files.
  • Bug fix: derive_agent_status returned stale status when tools dict was empty instead of "waiting".
  • Sessions start in "waiting" state: Fixes resumed sessions falsely showing as "working".
  • StopFailure hook added, unreliable Notification handlers removed.

Test plan

  • swift build passes
  • uv run pytest Tests/python/ -v — 61/61 tests pass (28 new tests for agent facts, watcher resolution, lifecycle simulation)
  • Start a new Claude session — should show "your turn" until user sends a message
  • Reject a tool — should update to "your turn" within ~2s (watcher resolves via transcript)
  • Approve a slow command (e.g. sleep 20) — should transition to "working" immediately (watcher process inspection)
  • Interrupt a session (Ctrl+C) — all agents should show "your turn"
  • Run a session with subagents — statuses should be independent
  • Kill a Claude process — watcher should clean up the session within 1.5s

@jezekra1 jezekra1 force-pushed the feat/per-agent-status-tracking branch 4 times, most recently from 88925b7 to a5e72b2 Compare March 27, 2026 15:14
@jezekra1 jezekra1 changed the title feat: per-agent status tracking with transcript resolution feat: per-agent status tracking with Python watcher daemon Mar 27, 2026
@jezekra1 jezekra1 force-pushed the feat/per-agent-status-tracking branch 6 times, most recently from c4f423e to b8bf7ca Compare March 27, 2026 16:08
Per-agent fact files replace the single session status field:
- Hook writes {session_id}.agent.{key}.json per agent (main + subagents)
- File locking (fcntl.flock) prevents concurrent hook races
- Session-level status derived from agent priorities: needs_approval > working > waiting

Python watcher daemon (--watch mode) resolves hook blind spots:
- Transcript resolution: detects tool completion/rejection when no hook fires
- Process inspection: flips needs_approval→working when command is already running
- Interruption detection: sets all agents to waiting on user interrupt
- PID liveness cleanup: removes dead sessions
- Single process for all sessions, self-terminates after 60s idle
- ensure_watcher() called on every hook invocation

Swift side simplified to pure file reader:
- SessionProcessor: only deriveStatus, isGhost, abandoned detection (65 lines)
- SessionStateWatcher: DispatchSource only, no timer, no PID checks
- Watcher writes to fact files trigger DispatchSource automatically

Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com>
Signed-off-by: Radek Ježek <radek.jezek@ibm.com>
@jezekra1 jezekra1 force-pushed the feat/per-agent-status-tracking branch from b8bf7ca to 4ed534f Compare March 29, 2026 12:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant