Skip to content

bound agent-compose ps scheduler run scans - #89

Closed
winterfx wants to merge 4 commits into
chaitin:mainfrom
winterfx:feat/agent-compose-ps-bounded-scan
Closed

winterfx wants to merge 4 commits into
chaitin:mainfrom
winterfx:feat/agent-compose-ps-bounded-scan

Conversation

@winterfx

Copy link
Copy Markdown
Contributor

Stacked on #88. This branch contains #88's three commits. Review only the last commit, c4aaf38. I will rebase onto main once #88 merges.

Summary

agent-compose ps was taking ~130s on a busy project, even with --limit 20. It now takes ~4s, and the Run associations are identical.

Root cause

ps labels each Sandbox with the Run that created it. When a listed Sandbox has no owning Run, it fetched every Scheduler Run in the project to find the one that created the Sandbox. The API gives no other way to do this: ListSchedulerRuns cannot filter by Sandbox, and Sandbox does not record its origin.

On a project with ~31.5k Scheduler Runs (~1.7k/day, 20-day retention), that is ~316 sequential requests. Each individual RPC is fast (0.1–0.5s).

Changes

Only the ps association path changes. listSchedulerRuns and the other commands are untouched.

  • Look up only the listed Sandboxes. The lookup now covers just the Sandboxes being listed that no Run owns, instead of the project's whole history.

  • Scan per agent first. A scheduler creates Sandboxes for its own agent, so each agent's Sandboxes are looked up with the agent_name filter. This skips high-volume polling agents, which made up 88% of the history here.

  • Stop early. ListSchedulerRuns returns newest first (started_at DESC in the daemon store). The scan stops when either:

    • every wanted Sandbox is matched, or
    • runs started more than 24h before the oldest wanted Sandbox was created.

    The 24h margin covers a Scheduler Run that creates its Sandbox long after it starts, since common SCHEDULER_RUN_TIMEOUT values are a few hours.

  • Fallback. Sandboxes still unmatched get the same bounded scan across all agents, so no association is lost if a scheduler ever creates a Sandbox for another agent.

  • Unknown creation time. A Sandbox without created_at disables the cutoff and keeps the old exhaustive behavior.

No flags, config, environment variable, or .env changes.

Known limitation

Resolving a Scheduler Run from a short ID prefix still reads the full history. This affects inspect scheduler-run, scheduler logs, and scheduler stop, as well as an untyped inspect <ref> that does not match an earlier kind.

ResolveID has no Scheduler Run resource kind, so the CLI cannot do better. The proper fix is daemon-side: add a Scheduler Run kind to ResolveID, and a Sandbox origin field or a sandbox_id filter on ListSchedulerRuns. With those, ps would need no scan at all.

Test plan

  • task fmt:check, task lint, task test
  • New tests in ps_scan_test.go. The stub honors agent_name and counts requests. They cover:
    • stop once matched
    • stop at the cutoff
    • find a run inside the margin
    • exhaustive scan when created_at is unknown
    • no scan when Runs cover every Sandbox
    • per-agent scan skips a noisy agent
    • fallback when the agent differs
  • Mutation-checked. Removing the matched stop, the cutoff stop, the per-agent scan, the fallback, or the unknown-time guard each fails at least one test.
  • Live daemon, project with ~31.5k Scheduler Runs, ps --all --limit 100 (old vs new):
    • old: 131.9s
    • new: 4.4s
    • all 100 Sandboxes have the same Run association, none unassociated

🤖 Generated with Claude Code

winterfx and others added 4 commits October 15, 2026 15:28
Track the latest published proto module. Of what this CLI uses, v0.1.12
adds LLMService.GetDefaultModel and completes the LLM provider API; the
upgrade itself needs no code changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Make failed Runs debuggable from the CLI:

- inspect run now shows error_stack, cleanup_error, warnings, labels,
  logs_path, artifacts_dir, and the scheduler/trigger/scheduler-run ids.
  Previously a failed Run showed only "agent execution failed".
- run ls accepts relative times (30m, 24h, 7d) in --started-from and
  --started-to, truncated to milliseconds because the daemon rejects
  finer filters.
- run ls gains --scheduler-run, a repeatable --label key=value, and
  --all-projects, which lists Runs across projects with a PROJECT column.
- llm ls lists LLM providers, their models, the default model, and the
  latest protocol probes. Per-model headers are omitted because they may
  carry credentials.
- --project gets the -p shorthand.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
auth login and auth status called HealthService to check the Token, but
the daemon exempts HealthService from Bearer authentication so
orchestrators can probe it. Any Token passed, and auth login saved a
wrong one that failed only on the next real query.

Validate with ListProjects (limit 1), which the daemon protects. The
test stub now mirrors the daemon: HealthService accepts any Token while
the project service checks it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ps annotates each Sandbox with the Run that created it. For Sandboxes no
Run owns, it read every Scheduler Run in the project, because the API
cannot filter Scheduler Runs by Sandbox. On a project with ~31.5k
Scheduler Runs that took ~130s even for ps --limit 20.

Look up only the Sandboxes being listed, and stop early:

- A scheduler creates Sandboxes for its own agent, so scan each agent's
  runs with the agent_name filter first. This skips high-volume agents
  that dominate the history.
- ListSchedulerRuns returns newest first, so stop once every Sandbox is
  matched, or once runs started more than 24h before the oldest wanted
  Sandbox was created.
- Sandboxes still unmatched fall back to the same bounded scan across all
  agents, so no association is lost if a scheduler ever creates a Sandbox
  for another agent. A Sandbox without a creation time disables the
  cutoff.

On the project above, ps --all --limit 100 drops from 131.9s to 4.4s with
identical Run associations.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@winterfx

Copy link
Copy Markdown
Contributor Author

Folded into #88 so the agent-compose changes land as one PR. The commit (c4aaf38) is unchanged.

@winterfx winterfx closed this Oct 15, 2026
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