308 lines
7.6 KiB
Markdown
308 lines
7.6 KiB
Markdown
# Contractor Agents CLI Design
|
|
|
|
## Purpose
|
|
|
|
Define the plugin-owned CLI surface for managing contractor-backed OpenClaw agents.
|
|
|
|
Phase 1 supports Claude only. Gemini remains reserved in the command shape but is not implemented yet.
|
|
|
|
## Command root
|
|
|
|
```bash
|
|
openclaw contractor-agents
|
|
```
|
|
|
|
This should be implemented as a plugin-owned CLI root, not as a patch to `openclaw agents add`.
|
|
|
|
## Why a separate command root
|
|
|
|
Current OpenClaw plugin docs show support for plugin CLI registration, but do not document support for extending existing core commands with new flags.
|
|
|
|
Relevant doc statements:
|
|
|
|
> "Common registration methods: ... `registerCommand` / `registerCli` | CLI commands"
|
|
|
|
> "For plugin-owned root CLI commands, prefer `api.registerCli(..., { descriptors: [...] })` ..."
|
|
|
|
This suggests the supported extension seam is plugin-owned CLI trees.
|
|
|
|
Sources:
|
|
- https://docs.openclaw.ai/tools/plugin
|
|
- https://docs.openclaw.ai/plugins/sdk-entrypoints
|
|
|
|
## Phase 1 command
|
|
|
|
```bash
|
|
openclaw contractor-agents add --agent-id <agent-id> --workspace <workspace> --contractor <claude|gemini>
|
|
```
|
|
|
|
Phase 1 restrictions:
|
|
|
|
- `--contractor` must currently be `claude`
|
|
- `gemini` is accepted only as a reserved future value if desired, but should currently fail with a clear not-yet-implemented message unless you intentionally decide to reject it at parsing time
|
|
|
|
## Arguments
|
|
|
|
### Required
|
|
|
|
- `--agent-id <agent-id>`
|
|
- `--workspace <workspace>`
|
|
- `--contractor <claude|gemini>`
|
|
|
|
### Optional, possible later
|
|
|
|
Not required for first implementation, but likely useful later:
|
|
|
|
- `--bridge-model <model-id>`
|
|
- `--backend <acp-backend>`
|
|
- `--mode <persistent|oneshot>`
|
|
- `--json`
|
|
- `--non-interactive`
|
|
|
|
For now, phase 1 can hardcode the bridge model and runtime defaults.
|
|
|
|
## Behavior of `add`
|
|
|
|
For:
|
|
|
|
```bash
|
|
openclaw contractor-agents add --agent-id my-agent --workspace /path/to/ws --contractor claude
|
|
```
|
|
|
|
The CLI should do the following.
|
|
|
|
### Step 1, validate inputs
|
|
|
|
- ensure `agent-id` is provided
|
|
- ensure workspace exists or is creatable, based on your desired policy
|
|
- ensure contractor kind is supported
|
|
- ensure target agent does not already exist unless overwrite behavior is explicitly added later
|
|
|
|
### Step 2, create the base OpenClaw agent
|
|
|
|
Run the equivalent of:
|
|
|
|
```bash
|
|
openclaw agents add <agent-id> --workspace <workspace> --model contractor-claude-bridge --non-interactive
|
|
```
|
|
|
|
Important note:
|
|
|
|
Earlier review of `openclaw agents add` docs showed these supported options:
|
|
|
|
> `--workspace <dir>`
|
|
> `--model <id>`
|
|
> `--agent-dir <dir>`
|
|
> `--bind <channel[:accountId]>`
|
|
> `--non-interactive`
|
|
> `--json`
|
|
|
|
Source:
|
|
- https://docs.openclaw.ai/cli/agents
|
|
|
|
This means the contractor CLI can compose the existing agent creation flow rather than replacing it.
|
|
|
|
### Step 3, mark the agent as a contractor-backed agent
|
|
|
|
After agent creation, write contractor metadata so runtime selection and session bridging can identify this agent as contractor-managed.
|
|
|
|
Proposed config direction:
|
|
|
|
```json5
|
|
{
|
|
agents: {
|
|
list: [
|
|
{
|
|
id: "my-agent",
|
|
model: "contractor-claude-bridge",
|
|
runtime: {
|
|
type: "contractor",
|
|
contractor: {
|
|
kind: "claude",
|
|
backend: "acp",
|
|
mode: "persistent"
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
Exact schema is still TBD, but the CLI should be the mechanism that writes this state.
|
|
|
|
### Step 4, initialize contractor runtime state
|
|
|
|
Prepare runtime state for the agent, including a place to store session mappings.
|
|
|
|
Suggested path:
|
|
|
|
```text
|
|
<workspace>/.openclaw/contractor-agent/
|
|
```
|
|
|
|
Suggested initial files:
|
|
|
|
```text
|
|
session-map.json
|
|
runtime.json
|
|
```
|
|
|
|
## Session mapping responsibility
|
|
|
|
The CLI does not create Claude sessions immediately unless you explicitly want eager setup.
|
|
|
|
Recommended phase 1 behavior:
|
|
|
|
- create agent metadata
|
|
- create runtime state directory
|
|
- initialize empty mapping file
|
|
- defer real Claude session creation to first actual agent turn
|
|
|
|
This keeps `add` lightweight and avoids unused contractor sessions.
|
|
|
|
## Suggested future commands
|
|
|
|
These are not required immediately, but the command tree should reserve room for them.
|
|
|
|
### Status
|
|
|
|
```bash
|
|
openclaw contractor-agents status --agent-id <agent-id>
|
|
```
|
|
|
|
Show:
|
|
- contractor kind
|
|
- bridge model id
|
|
- runtime backend
|
|
- session mapping count
|
|
- recent activity
|
|
|
|
### List sessions
|
|
|
|
```bash
|
|
openclaw contractor-agents sessions --agent-id <agent-id>
|
|
```
|
|
|
|
Show session mappings for the given contractor-backed agent.
|
|
|
|
### Reset mapping
|
|
|
|
```bash
|
|
openclaw contractor-agents reset-session --agent-id <agent-id> --openclaw-session <session-key>
|
|
```
|
|
|
|
Drop a specific OpenClaw-to-Claude mapping so the next message recreates the Claude session.
|
|
|
|
### Disable
|
|
|
|
```bash
|
|
openclaw contractor-agents disable --agent-id <agent-id>
|
|
```
|
|
|
|
Either:
|
|
- remove contractor metadata but keep agent
|
|
- or mark the contractor runtime disabled
|
|
|
|
Semantics TBD.
|
|
|
|
## JSON output
|
|
|
|
I recommend all subcommands eventually support `--json` so this can be scripted.
|
|
|
|
Example success response shape:
|
|
|
|
```json
|
|
{
|
|
"ok": true,
|
|
"agentId": "my-agent",
|
|
"workspace": "/path/to/ws",
|
|
"contractor": "claude",
|
|
"model": "contractor-claude-bridge",
|
|
"runtimeStateDir": "/path/to/ws/.openclaw/contractor-agent"
|
|
}
|
|
```
|
|
|
|
## Failure cases
|
|
|
|
The CLI should fail clearly for:
|
|
|
|
- unsupported contractor kind
|
|
- agent already exists
|
|
- workspace invalid or inaccessible
|
|
- bridge model plugin not available
|
|
- failure in underlying `openclaw agents add`
|
|
- failure writing contractor metadata
|
|
|
|
If the agent is created successfully but metadata writing fails, the CLI should either:
|
|
|
|
- roll back the created agent if safe and simple
|
|
- or return a partial-failure error with explicit cleanup instructions
|
|
|
|
Phase 1 recommendation: prefer explicit rollback if implementation is reliable.
|
|
|
|
## Interaction with the bridge model
|
|
|
|
The CLI should not directly run Claude Code or create a Claude contractor session by default.
|
|
|
|
Its main job is to provision an agent whose primary model is the contractor bridge model:
|
|
|
|
- `contractor-claude-bridge`
|
|
|
|
That model then handles runtime dispatch during actual conversation turns.
|
|
|
|
## Implementation notes
|
|
|
|
The plugin should register a root command owned by the plugin.
|
|
|
|
Relevant doc statements:
|
|
|
|
> "For plugin-owned root CLI commands, prefer `api.registerCli(..., { descriptors: [...] })` when you want the command to stay lazy-loaded without disappearing from the root CLI parse tree."
|
|
|
|
Source:
|
|
- https://docs.openclaw.ai/plugins/sdk-entrypoints
|
|
|
|
So the intended shape is:
|
|
|
|
- plugin registers `contractor-agents`
|
|
- plugin owns parsing and handling of its subcommands
|
|
- plugin composes `openclaw agents add` behavior internally or via shared config/runtime helpers
|
|
|
|
## Open questions
|
|
|
|
1. Should the CLI shell out to `openclaw agents add` or use a lower-level config/runtime helper directly?
|
|
2. Where should contractor metadata live, `agents.list[].runtime`, plugin config, or both?
|
|
3. Should `gemini` be rejected now or accepted with a not implemented error?
|
|
4. Should add create the workspace if it does not exist?
|
|
5. Should agent creation be rolled back if contractor metadata writing fails?
|
|
|
|
## References
|
|
|
|
### Plugin CLI support
|
|
|
|
> "Common registration methods: ... `registerCommand` / `registerCli` | CLI commands"
|
|
|
|
Source:
|
|
- https://docs.openclaw.ai/tools/plugin
|
|
|
|
### Plugin-owned CLI descriptors
|
|
|
|
> "For plugin-owned root CLI commands, prefer `api.registerCli(..., { descriptors: [...] })` ..."
|
|
|
|
Source:
|
|
- https://docs.openclaw.ai/plugins/sdk-entrypoints
|
|
|
|
### Existing agent creation command
|
|
|
|
> `agents add [name]`
|
|
|
|
> `--workspace <dir>`
|
|
> `--model <id>`
|
|
> `--agent-dir <dir>`
|
|
> `--bind <channel[:accountId]>`
|
|
> `--non-interactive`
|
|
> `--json`
|
|
|
|
Source:
|
|
- https://docs.openclaw.ai/cli/agents
|