Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions distro/skills/berd-help/references/berdctl.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,28 @@ organized as `berdctl <noun> <verb>` (for example `berdctl session list`,
recall.

Use `berdctl session send` for an ordinary message from another session. Use `berdctl session notify` for an automated event such as a monitor update; it appears as a collapsed activity entry and still reaches the agent as context. Both commands support queueing, steering, source attribution, and idempotent delivery.

## Child sessions with Auto routing

Discover configured Goose Auto modes with
`berdctl info models --harness-id goose --json`. The Goose entry's `auto_modes`
array contains each mode's `id`, display `name`, and `is_default`; these ids are
not concrete `models[].model_id` values.

Create a child/sub-session with an explicit configured mode:

```sh
berdctl session create --prompt "Investigate this task" --harness-id goose \
--auto-mode-id <configured-mode-id> --json
```

For Auto Balanced, use the id of the configured Balanced mode, not its display
name. Auto selects a model for each fresh prompt, rather than pinning one model
for the whole child session. Do not combine `--auto-mode-id` with `--model-id`
or a non-Goose harness. `--agent-id` may supply persona instructions while Auto
selects the model. Creation and session metadata report `auto_mode_id`.

There is no automatic inference from the parent or active UI session. Without
`--auto-mode-id`, existing creation behavior is unchanged: the configured Auto
default applies only when harness, model, and agent are all omitted. Pass the
mode explicitly when delegating so the child's intended routing is unambiguous.
16 changes: 14 additions & 2 deletions src-tauri/crates/berdctl/api-surface-feedback.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"description": "Manage the user's chat sessions: create (fire-and-forget, on any installed agent harness), send, notify, open, list, get, rename, move, move to group, clear project, send to a live voice Spokesperson, dismiss voice handoffs, fork, archive.",
"actions": {
"create": {
"description": "Create a new chat session on any installed agent harness and send the prompt in it. Fire-and-forget: returns the session id immediately and the session runs in the background without changing what the user sees; the user can open it themselves. Use --from to give the delegating session or tool a concise visible label on the initial message. Only check on it later (action \"get\") if the user asks.",
"description": "Create a new chat session on any installed agent harness and send the prompt in it. Fire-and-forget: returns the session id immediately and the session runs in the background without changing what the user sees; the user can open it themselves. Use --from to give the delegating session or tool a concise visible label on the initial message. Use --auto-mode-id to select a configured Goose Auto mode explicitly; no parent or active UI session selection is inferred. Only check on it later (action \"get\") if the user asks.",
"fields": [
{
"name": "prompt",
Expand All @@ -28,6 +28,13 @@
"kind": "string",
"description": "Id of the model to use (from `berdctl info models`)."
},
{
"name": "auto_mode_id",
"required": false,
"kind": "string",
"description": "Configured Goose Auto mode id (from `berdctl info models --harness-id goose`). Routes each fresh prompt; cannot combine with --model-id or a non-Goose harness. With --agent-id, keeps persona instructions while Auto selects the model.",
"min": 1
},
{
"name": "agent_id",
"required": false,
Expand Down Expand Up @@ -75,6 +82,11 @@
"description": "Id of the model to use (from `berdctl info models`).",
"type": "string"
},
"auto_mode_id": {
"description": "Configured Goose Auto mode id (from `berdctl info models --harness-id goose`). Routes each fresh prompt; cannot combine with --model-id or a non-Goose harness. With --agent-id, keeps persona instructions while Auto selects the model.",
"type": "string",
"minLength": 1
},
"agent_id": {
"description": "Id of the agent (persona) to use (from `berdctl agent list`).",
"type": "string"
Expand Down Expand Up @@ -1445,7 +1457,7 @@
}
},
"list_models": {
"description": "List the models available per agent harness (same source as the app's model picker); omit harness_id to cover every ready harness in one call. Use a model_id (and its harness_id) when creating a session.",
"description": "List the models available per agent harness (same source as the app's model picker); omit harness_id to cover every ready harness in one call. Goose also lists configured Auto modes separately in auto_modes. Use --auto-mode-id for those ids, or --model-id for a concrete model when creating a session.",
"fields": [
{
"name": "harness_id",
Expand Down
16 changes: 14 additions & 2 deletions src-tauri/crates/berdctl/api-surface.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"description": "Manage the user's chat sessions: create (fire-and-forget, on any installed agent harness), send, notify, open, list, get, rename, move, move to group, clear project, send to a live voice Spokesperson, dismiss voice handoffs, fork, archive.",
"actions": {
"create": {
"description": "Create a new chat session on any installed agent harness and send the prompt in it. Fire-and-forget: returns the session id immediately and the session runs in the background without changing what the user sees; the user can open it themselves. Use --from to give the delegating session or tool a concise visible label on the initial message. Only check on it later (action \"get\") if the user asks.",
"description": "Create a new chat session on any installed agent harness and send the prompt in it. Fire-and-forget: returns the session id immediately and the session runs in the background without changing what the user sees; the user can open it themselves. Use --from to give the delegating session or tool a concise visible label on the initial message. Use --auto-mode-id to select a configured Goose Auto mode explicitly; no parent or active UI session selection is inferred. Only check on it later (action \"get\") if the user asks.",
"fields": [
{
"name": "prompt",
Expand All @@ -28,6 +28,13 @@
"kind": "string",
"description": "Id of the model to use (from `berdctl info models`)."
},
{
"name": "auto_mode_id",
"required": false,
"kind": "string",
"description": "Configured Goose Auto mode id (from `berdctl info models --harness-id goose`). Routes each fresh prompt; cannot combine with --model-id or a non-Goose harness. With --agent-id, keeps persona instructions while Auto selects the model.",
"min": 1
},
{
"name": "agent_id",
"required": false,
Expand Down Expand Up @@ -75,6 +82,11 @@
"description": "Id of the model to use (from `berdctl info models`).",
"type": "string"
},
"auto_mode_id": {
"description": "Configured Goose Auto mode id (from `berdctl info models --harness-id goose`). Routes each fresh prompt; cannot combine with --model-id or a non-Goose harness. With --agent-id, keeps persona instructions while Auto selects the model.",
"type": "string",
"minLength": 1
},
"agent_id": {
"description": "Id of the agent (persona) to use (from `berdctl agent list`).",
"type": "string"
Expand Down Expand Up @@ -1336,7 +1348,7 @@
}
},
"list_models": {
"description": "List the models available per agent harness (same source as the app's model picker); omit harness_id to cover every ready harness in one call. Use a model_id (and its harness_id) when creating a session.",
"description": "List the models available per agent harness (same source as the app's model picker); omit harness_id to cover every ready harness in one call. Goose also lists configured Auto modes separately in auto_modes. Use --auto-mode-id for those ids, or --model-id for a concrete model when creating a session.",
"fields": [
{
"name": "harness_id",
Expand Down
6 changes: 3 additions & 3 deletions src-tauri/crates/berdctl/cli-surface-feedback.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"create": {
"action": "create",
"about": "Create a new chat session and send a prompt in it (fire-and-forget)",
"afterHelp": "Examples:\n berdctl session create --prompt \"Triage the failing nightly build\" \\\n --harness-id claude-acp --from \"the release orchestrator\" --json\n berdctl session create --prompt \"Implement the fix\" \\\n --project-id <project-id> --startup-name my-feature\n\nResult:\n {\"session_id\": \"...\", \"title\": \"...\", \"harness_id\": \"...\",\n \"send_status\": \"dispatched\"}\n The session runs in the background; the user's view does not change. Check\n progress later with `berdctl session get --session-id <session_id>`."
"afterHelp": "Examples:\n berdctl session create --prompt \"Triage the failing nightly build\" \\\n --harness-id claude-acp --from \"the release orchestrator\" --json\n berdctl session create --prompt \"Implement the fix\" \\\n --project-id <project-id> --startup-name my-feature\n\n berdctl session create --prompt \"Investigate\" \\\n --harness-id goose --auto-mode-id <configured-mode-id> --json\n\nResult:\n {\"session_id\": \"...\", \"title\": \"...\", \"harness_id\": \"...\",\n \"auto_mode_id\": \"...\"|null, \"send_status\": \"dispatched\"}\n The session runs in the background; the user's view does not change. Check\n progress later with `berdctl session get --session-id <session_id>`."
},
"send": {
"action": "send",
Expand All @@ -33,7 +33,7 @@
"get": {
"action": "get",
"about": "Read one session's metadata and optionally its latest messages",
"afterHelp": "Example:\n berdctl session get --session-id <session-id> --messages 5 --json\n\nResult:\n {\"session_id\": \"...\", \"title\": \"...\", \"harness_id\": \"...\",\n \"model_id\": \"...\"|null, \"agent_id\": \"...\"|null,\n \"project_id\": \"...\"|null, \"working_dir\": \"...\"|null,\n \"created_at\": \"...\", \"updated_at\": \"...\", \"archived\": false,\n \"is_running\": false, \"is_open_in_window\": false,\n \"chat_state\": \"idle\", \"message_count\": 12,\n \"messages\": [{\"role\": \"user\"|\"assistant\"|null, \"text\": \"...\"}, ...]}\n \"messages\" is present only when --messages > 0; each message text is\n truncated to 2000 chars."
"afterHelp": "Example:\n berdctl session get --session-id <session-id> --messages 5 --json\n\nResult:\n {\"session_id\": \"...\", \"title\": \"...\", \"harness_id\": \"...\",\n \"model_id\": \"...\"|null, \"agent_id\": \"...\"|null, \"auto_mode_id\": \"...\"|null,\n \"project_id\": \"...\"|null, \"working_dir\": \"...\"|null,\n \"created_at\": \"...\", \"updated_at\": \"...\", \"archived\": false,\n \"is_running\": false, \"is_open_in_window\": false,\n \"chat_state\": \"idle\", \"message_count\": 12,\n \"messages\": [{\"role\": \"user\"|\"assistant\"|null, \"text\": \"...\"}, ...]}\n \"messages\" is present only when --messages > 0; each message text is\n truncated to 2000 chars."
},
"rename": {
"action": "rename",
Expand Down Expand Up @@ -214,7 +214,7 @@
"models": {
"action": "list_models",
"about": "List the models available per agent harness",
"afterHelp": "Example:\n berdctl info models --harness-id goose --json\n\nResult:\n {\"harnesses\": [{\"harness_id\": \"...\",\n \"models\": [{\"model_id\": \"...\", \"name\": \"...\",\n \"provider\": \"...\"?}],\n \"warning\": \"...\"?}]}\n Use a model_id (with its harness) as --model-id when creating a session.\n \"warning\" appears when a stale cached list was served or when the harness\n manages its model outside the app."
"afterHelp": "Example:\n berdctl info models --harness-id goose --json\n\nResult:\n {\"harnesses\": [{\"harness_id\": \"...\",\n \"models\": [{\"model_id\": \"...\", \"name\": \"...\",\n \"provider\": \"...\"?}],\n \"auto_modes\": [{\"id\": \"...\", \"name\": \"...\", \"is_default\": true}]?,\n \"warning\": \"...\"?}]}\n Use a model_id (with its harness) as --model-id when creating a session.\n Goose auto_modes ids are not model ids; pass one as --auto-mode-id to route\n each fresh prompt. auto_modes is omitted for non-Goose harnesses.\n \"warning\" appears when a stale cached list was served or when the harness\n manages its model outside the app."
},
"context": {
"action": "get_context",
Expand Down
6 changes: 3 additions & 3 deletions src-tauri/crates/berdctl/cli-surface.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"create": {
"action": "create",
"about": "Create a new chat session and send a prompt in it (fire-and-forget)",
"afterHelp": "Examples:\n berdctl session create --prompt \"Triage the failing nightly build\" \\\n --harness-id claude-acp --from \"the release orchestrator\" --json\n berdctl session create --prompt \"Implement the fix\" \\\n --project-id <project-id> --startup-name my-feature\n\nResult:\n {\"session_id\": \"...\", \"title\": \"...\", \"harness_id\": \"...\",\n \"send_status\": \"dispatched\"}\n The session runs in the background; the user's view does not change. Check\n progress later with `berdctl session get --session-id <session_id>`."
"afterHelp": "Examples:\n berdctl session create --prompt \"Triage the failing nightly build\" \\\n --harness-id claude-acp --from \"the release orchestrator\" --json\n berdctl session create --prompt \"Implement the fix\" \\\n --project-id <project-id> --startup-name my-feature\n\n berdctl session create --prompt \"Investigate\" \\\n --harness-id goose --auto-mode-id <configured-mode-id> --json\n\nResult:\n {\"session_id\": \"...\", \"title\": \"...\", \"harness_id\": \"...\",\n \"auto_mode_id\": \"...\"|null, \"send_status\": \"dispatched\"}\n The session runs in the background; the user's view does not change. Check\n progress later with `berdctl session get --session-id <session_id>`."
},
"send": {
"action": "send",
Expand All @@ -33,7 +33,7 @@
"get": {
"action": "get",
"about": "Read one session's metadata and optionally its latest messages",
"afterHelp": "Example:\n berdctl session get --session-id <session-id> --messages 5 --json\n\nResult:\n {\"session_id\": \"...\", \"title\": \"...\", \"harness_id\": \"...\",\n \"model_id\": \"...\"|null, \"agent_id\": \"...\"|null,\n \"project_id\": \"...\"|null, \"working_dir\": \"...\"|null,\n \"created_at\": \"...\", \"updated_at\": \"...\", \"archived\": false,\n \"is_running\": false, \"is_open_in_window\": false,\n \"chat_state\": \"idle\", \"message_count\": 12,\n \"messages\": [{\"role\": \"user\"|\"assistant\"|null, \"text\": \"...\"}, ...]}\n \"messages\" is present only when --messages > 0; each message text is\n truncated to 2000 chars."
"afterHelp": "Example:\n berdctl session get --session-id <session-id> --messages 5 --json\n\nResult:\n {\"session_id\": \"...\", \"title\": \"...\", \"harness_id\": \"...\",\n \"model_id\": \"...\"|null, \"agent_id\": \"...\"|null, \"auto_mode_id\": \"...\"|null,\n \"project_id\": \"...\"|null, \"working_dir\": \"...\"|null,\n \"created_at\": \"...\", \"updated_at\": \"...\", \"archived\": false,\n \"is_running\": false, \"is_open_in_window\": false,\n \"chat_state\": \"idle\", \"message_count\": 12,\n \"messages\": [{\"role\": \"user\"|\"assistant\"|null, \"text\": \"...\"}, ...]}\n \"messages\" is present only when --messages > 0; each message text is\n truncated to 2000 chars."
},
"rename": {
"action": "rename",
Expand Down Expand Up @@ -198,7 +198,7 @@
"models": {
"action": "list_models",
"about": "List the models available per agent harness",
"afterHelp": "Example:\n berdctl info models --harness-id goose --json\n\nResult:\n {\"harnesses\": [{\"harness_id\": \"...\",\n \"models\": [{\"model_id\": \"...\", \"name\": \"...\",\n \"provider\": \"...\"?}],\n \"warning\": \"...\"?}]}\n Use a model_id (with its harness) as --model-id when creating a session.\n \"warning\" appears when a stale cached list was served or when the harness\n manages its model outside the app."
"afterHelp": "Example:\n berdctl info models --harness-id goose --json\n\nResult:\n {\"harnesses\": [{\"harness_id\": \"...\",\n \"models\": [{\"model_id\": \"...\", \"name\": \"...\",\n \"provider\": \"...\"?}],\n \"auto_modes\": [{\"id\": \"...\", \"name\": \"...\", \"is_default\": true}]?,\n \"warning\": \"...\"?}]}\n Use a model_id (with its harness) as --model-id when creating a session.\n Goose auto_modes ids are not model ids; pass one as --auto-mode-id to route\n each fresh prompt. auto_modes is omitted for non-Goose harnesses.\n \"warning\" appears when a stale cached list was served or when the harness\n manages its model outside the app."
},
"context": {
"action": "get_context",
Expand Down
39 changes: 36 additions & 3 deletions src-tauri/crates/berdctl/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,29 @@ mod tests {
);
}

#[test]
fn session_create_maps_auto_mode_id_onto_the_wire() {
let (command, args) = wire_of(&[
"berdctl",
"session",
"create",
"--prompt",
"hi",
"--harness-id",
"goose",
"--auto-mode-id",
"custom-balanced",
]);
assert_eq!(command, "sessions");
assert_eq!(
Value::Object(args),
serde_json::json!({
"action": "create", "prompt": "hi", "harness_id": "goose",
"auto_mode_id": "custom-balanced",
})
);
}

#[test]
fn project_create_collects_repeated_working_dirs() {
let (command, args) = wire_of(&[
Expand Down Expand Up @@ -641,8 +664,9 @@ mod tests {
it. Fire-and-forget: returns the session id immediately and the session runs in
the background without changing what the user sees; the user can open it
themselves. Use --from to give the delegating session or tool a concise visible
label on the initial message. Only check on it later (action "get") if the user
asks.
label on the initial message. Use --auto-mode-id to select a configured Goose
Auto mode explicitly; no parent or active UI session selection is inferred. Only
check on it later (action "get") if the user asks.

Usage: berdctl session create [OPTIONS] --prompt <PROMPT>

Expand All @@ -657,6 +681,12 @@ Options:
--model-id <MODEL_ID>
Id of the model to use (from `berdctl info models`).

--auto-mode-id <AUTO_MODE_ID>
Configured Goose Auto mode id (from `berdctl info models --harness-id
goose`). Routes each fresh prompt; cannot combine with --model-id or a
non-Goose harness. With --agent-id, keeps persona instructions while
Auto selects the model.

--agent-id <AGENT_ID>
Id of the agent (persona) to use (from `berdctl agent list`).

Expand Down Expand Up @@ -687,9 +717,12 @@ Examples:
berdctl session create --prompt "Implement the fix" \
--project-id <project-id> --startup-name my-feature

berdctl session create --prompt "Investigate" \
--harness-id goose --auto-mode-id <configured-mode-id> --json

Result:
{"session_id": "...", "title": "...", "harness_id": "...",
"send_status": "dispatched"}
"auto_mode_id": "..."|null, "send_status": "dispatched"}
The session runs in the background; the user's view does not change. Check
progress later with `berdctl session get --session-id <session_id>`.
"#;
Expand Down
Loading
Loading