Files
openchamber/packages/web/server/lib/agent-tool/DOCUMENTATION.md
T
Bohdan Triapitsyn e908db637b feat: agent and CLI control plane for sessions, worktrees, and scheduled tasks (#2408)
Add a shared OpenChamber control service with two thin adapters — a native
`openchamber` tool injected into managed OpenCode, and new CLI commands — so
users can manage parallel sessions, worktrees, and scheduled tasks
conversationally through agents or from the terminal.

Control plane:
- New openchamber-control service owning a fixed action contract:
  projects.list, models.list, session list/create/send/fork/status/messages,
  and schedule list/create/run/delete/toggle. Session and worktree deletion
  and project registration are deliberately not exposed.
- New openchamber-sessions module owning create/worktree/prompt orchestration,
  Goal Mode dispatch, wait semantics (initial idle never counts as completion;
  timeout and cancellation are failures), and explicit partial-failure results.
- Scheduled-task logic extracted into a service shared by routes, CLI, and the
  agent tool.

Agent tool:
- Managed OpenCode gets a materialized plugin registering one typed tool with
  a loopback-only callback, per-child ephemeral bearer (timing-safe, never
  persisted or logged), and abort propagation into the service.
- The ~1.5k-token schema applies progressive disclosure: short descriptions,
  server-side validation returning actionable usage errors, and intent
  guardrails — created sessions/tasks are user-facing work (not age
  self-delegation); worktree/goal/agent/variant/wait are omit-by-default;
  dispatches produce no completion notification, and later result r
  to session.messages, which now returns the authoritative sessionStatus.
- session.create without a user-named model picks from favorites/re
  send/fork omit the selection and the service reuses the target session's
  last user-message model, agent, and variant before falling back t
- An "Agent control tool" setting (default on, Save + Reload to apply)
  disables plugin injection entirely.

CLI:
- New `openchamber session`, `schedule`, `projects`, and `models` commands
  with automatic instance targeting, --wait/--timeout/--last-assist
  worktree flags, and Goal Mode, preserving interactive, non-TTY, --quiet,
  and --json contracts. The control HTTP timeout derives from the w
  instead of the 4-second default.

UI:
- New built-in "Schedule a Task" starter (/schedule-task) running a
  dialogue that defines a task and offers to create it via the tool after
  explicit confirmation; Craft a Goal and Feature Planning gain the
  handoff offer, and guided starters reserve the question tool for concrete
  option choices. Localized in all 10 locales, migrated into custom
  starter lists, hidden on VS Code.
- Sidebar shows CLI/agent-created sessions live via the control eve
- openchamber tool calls render with per-action titles and metadata.
2026-07-24 21:54:28 +03:00

4.2 KiB

Managed OpenChamber Agent Tool

Purpose

This module exposes OpenChamber orchestration to agents as one typed OpenCode custom tool named openchamber. It is injected only when OpenChamber launches and owns the OpenCode process, and only while the persisted agentControlToolEnabled setting is not false (default on; toggled in Settings → General → OpenCode CLI and applied on the next managed OpenCode restart).

Runtime flow

  1. The OpenChamber HTTP listener binds and publishes its authoritative port.
  2. prepareManagedOpenCodeEnv() materializes the plugin under <openchamber-data-dir>/agent-tool/ and appends its file:// URL to OPENCODE_CONFIG_CONTENT without replacing existing plugin entries.
  3. A random per-child token and loopback callback URL are added only to the managed OpenCode child environment.
  4. The plugin calls POST /api/openchamber/agent-tool with its typed input and OpenCode's authoritative session directory.
  5. The route delegates the fixed action allowlist directly to the shared OpenChamber control service. The CLI uses the same service through its authenticated HTTP adapter, so Goal Mode ordering, wait behavior, partial-failure reporting, and scheduled-task contracts have one owner.
  6. Each action definition owns a short presentation title and a separate agent-facing description. The generated schema uses the description to state required inputs or one non-obvious behavior, while completed calls use the short title in native tool metadata.

Agent context budget

  • The tool exposes one shared parameter object rather than repeating parameters in a large per-action union. Action descriptions carry only required inputs, defaults, or one non-obvious semantic detail.
  • Obvious fields rely on their names and JSON types. Parameter descriptions are reserved for formats, dependencies, scope, and behavior that cannot be safely inferred from the field name.
  • Session dispatches do not wait by default. Agents are told to set wait only when the user asks or the next step requires the completed result.
  • The tool exposes only agent-relevant actions (OPENCHAMBER_AGENT_TOOL_ACTIONS): schedule.status stays CLI-only because schedule.list already returns scheduler status, and enable/disable are one schedule.toggle action driven by the disabled boolean.
  • The tool description frames intent: created sessions and scheduled tasks are user-facing work the user follows up with, never a channel for the agent to delegate parts of its own current task.
  • Optional behavior switches (worktree, goal, agent, variant, wait) state their default and an explicit "only when the user asks" rule so agents do not invent worktrees, goal mode, or waits the user never requested.
  • Detailed combination rules are enforced by the shared control service and returned as actionable usage errors only after an invalid call. Per-action examples and a repeated per-action parameter schema are intentionally omitted.

Security invariants

  • The callback accepts loopback requests only and requires the current per-child bearer token using a timing-safe comparison.
  • The token is never persisted, logged, returned to the UI, or written into the materialized plugin.
  • Inputs map to a fixed action and parameter allowlist. There is no arbitrary CLI, shell, route, or URL forwarding.
  • Session/worktree deletion and project-path registration are not exposed.
  • An aborted tool request propagates an abort signal into the shared service.

Result contract

Every completed call returns JSON:

{
  "schemaVersion": 1,
  "ok": true,
  "action": "session.create",
  "data": {}
}

Command and operational failures use the same envelope with ok: false and an error object. OpenCode-level cancellation can still produce a native tool error state.

Runtime parity

  • Web and Desktop managed OpenCode: injected automatically.
  • External OpenCode selected with OPENCODE_HOST or skip-start: not injected, because OpenChamber does not control that process environment.
  • VS Code: not injected; the extension owns a separate OpenCode lifecycle.
  • Hosted and Capacitor mobile clients use the server's managed OpenCode tool when connected to such a server; no tool runs in the client runtime.