722169adfd
Can now send chain-of-thought messages Manage terminals Control agent working directory Adding more tool support and notifications Some session management Added image support Added slash commands
234 lines
7.7 KiB
Markdown
234 lines
7.7 KiB
Markdown
# Honker ACP Bridge — Implementation Plan
|
|
|
|
## Current State
|
|
|
|
What's implemented today:
|
|
- ✅ Initialize ACP connection to Goose (`goose acp` over stdio)
|
|
- ✅ Create new sessions (one per Signal contact)
|
|
- ✅ Send text prompts and collect text responses
|
|
- ✅ Interactive permission requests over Signal (numbered options)
|
|
- ✅ Signal-cli lifecycle management and socket communication
|
|
|
|
---
|
|
|
|
## Phase 1: Essential — Make the Bridge Robust
|
|
|
|
### 1.1 Terminal Execution (Client ← Agent)
|
|
**Priority: HIGH — Goose cannot function without this**
|
|
|
|
Goose's primary tool is running shell commands. The ACP protocol has the agent
|
|
ask the *client* to execute commands via `create_terminal`, then polls output
|
|
with `terminal_output` and `wait_for_terminal_exit`.
|
|
|
|
Currently we return `None` for all terminal methods, which means Goose can't
|
|
run any commands. We need to:
|
|
|
|
- `create_terminal(command, args, cwd, env)` → spawn a real subprocess, return
|
|
a `terminal_id`
|
|
- `terminal_output(terminal_id)` → return accumulated stdout/stderr
|
|
- `wait_for_terminal_exit(terminal_id)` → await process completion, return exit code
|
|
- `release_terminal(terminal_id)` → clean up
|
|
- `kill_terminal(terminal_id)` → kill the subprocess
|
|
|
|
Implementation: a `TerminalManager` class that tracks running subprocesses
|
|
keyed by terminal_id.
|
|
|
|
### 1.2 File System Operations (Client ← Agent)
|
|
**Priority: HIGH — Goose cannot edit code without this**
|
|
|
|
The agent asks the client to read/write files:
|
|
|
|
- `read_text_file(path, line, limit)` → read from the local filesystem, return content
|
|
- `write_text_file(path, content)` → write to the local filesystem
|
|
|
|
Currently we return `None`, so Goose can't read or write files.
|
|
These should be straightforward to implement against the local filesystem.
|
|
|
|
We should also advertise these capabilities in `ClientCapabilities` during
|
|
`initialize`:
|
|
```python
|
|
ClientCapabilities(
|
|
fs=FileSystemCapabilities(read_text_file=True, write_text_file=True),
|
|
terminal=True,
|
|
)
|
|
```
|
|
|
|
### 1.3 Cancellation
|
|
**Priority: MEDIUM**
|
|
|
|
Allow Signal users to cancel a running prompt. The user could send a special
|
|
command (e.g. `/cancel`) while a prompt is in progress. We'd call
|
|
`conn.cancel(session_id)` to tell Goose to stop.
|
|
|
|
The `PromptResponse.stop_reason` already distinguishes `cancelled` from
|
|
`end_turn`, `max_tokens`, `refusal`, and `max_turn_requests` — we should
|
|
handle each appropriately in the reply.
|
|
|
|
### 1.4 Stop Reason Handling
|
|
**Priority: MEDIUM**
|
|
|
|
Currently we only look at the response text. We should handle all stop reasons:
|
|
- `end_turn` — normal completion (current behavior)
|
|
- `max_tokens` — context limit hit; notify user
|
|
- `max_turn_requests` — agent hit its turn limit; notify user
|
|
- `refusal` — agent refused the request; notify user
|
|
- `cancelled` — user cancelled; acknowledge
|
|
|
|
---
|
|
|
|
## Phase 2: Enriched Feedback
|
|
|
|
### 2.1 Tool Call Notifications
|
|
**Priority: MEDIUM**
|
|
|
|
Forward tool activity as status messages so the Signal user knows what Goose
|
|
is doing while working. On `ToolCallStart`, send a brief message like:
|
|
"🔧 Running: `ls -la /src`"
|
|
|
|
On `ToolCallProgress` with status updates, optionally send progress. We need
|
|
to be careful not to spam — batch or throttle these.
|
|
|
|
### 2.2 Agent Thoughts
|
|
**Priority: LOW-MEDIUM**
|
|
|
|
`AgentThoughtChunk` contains the agent's chain-of-thought reasoning. Could
|
|
forward these optionally (config flag) as italicized or prefixed messages.
|
|
Useful for debugging but noisy for everyday use.
|
|
|
|
### 2.3 Plan Updates
|
|
**Priority: LOW-MEDIUM**
|
|
|
|
`AgentPlanUpdate` sends a structured plan with entries (content, priority,
|
|
status). Could render as a checklist:
|
|
```
|
|
📋 Plan:
|
|
✅ Read the project structure
|
|
🔄 Implement the new feature
|
|
⬚ Write tests
|
|
⬚ Update documentation
|
|
```
|
|
|
|
### 2.4 Usage/Cost Updates
|
|
**Priority: LOW**
|
|
|
|
`UsageUpdate` reports token usage (size, used) and optional `Cost` (amount,
|
|
currency). Could send periodic summaries or on-demand via a `/usage` command.
|
|
|
|
---
|
|
|
|
## Phase 3: Session Management
|
|
|
|
### 3.1 Session Persistence (Load/Resume)
|
|
**Priority: MEDIUM**
|
|
|
|
Goose supports `load_session` and `resume_session`. We could persist the
|
|
session_id→contact mapping in SQLite (as the README mentions) and restore
|
|
sessions across honker restarts.
|
|
|
|
- `load_session(cwd, session_id)` — restore conversation history
|
|
- `resume_session(cwd, session_id)` — resume an interrupted session
|
|
- `list_sessions()` — list available sessions
|
|
- `close_session(session_id)` — explicitly end a session
|
|
|
|
User commands: `/sessions`, `/load <id>`, `/new` (force new session)
|
|
|
|
### 3.2 Session Commands
|
|
**Priority: MEDIUM**
|
|
|
|
Signal user sends special commands (prefix with `/`):
|
|
- `/new` — start a fresh session
|
|
- `/sessions` — list previous sessions
|
|
- `/load <id>` — resume a previous session
|
|
- `/cancel` — cancel current prompt
|
|
- `/mode <mode>` — change session mode (via `set_session_mode`)
|
|
- `/model <model>` — change model (via `set_session_model`)
|
|
- `/usage` — show token usage / cost
|
|
|
|
### 3.3 Session Modes
|
|
**Priority: LOW**
|
|
|
|
Goose supports modes (e.g., "auto" vs "manual" approval). `set_session_mode`
|
|
and `CurrentModeUpdate` notifications. Could expose via `/mode` command.
|
|
|
|
### 3.4 Session Configuration
|
|
**Priority: LOW**
|
|
|
|
`set_config_option` lets the client change boolean/select config options.
|
|
`ConfigOptionUpdate` notifications report changes. Could expose via a
|
|
`/config` command.
|
|
|
|
---
|
|
|
|
## Phase 4: Rich Content
|
|
|
|
### 4.1 Image Support (Input)
|
|
**Priority: MEDIUM**
|
|
|
|
Signal users can send images. signal-cli provides attachment data. ACP
|
|
supports `ImageContentBlock` in prompts (with base64 `data` and `mime_type`).
|
|
We could forward Signal image attachments to Goose as image content blocks.
|
|
|
|
### 4.2 Image Support (Output)
|
|
**Priority: LOW**
|
|
|
|
If Goose responds with `ImageContentBlock` in agent messages, we could send
|
|
them as Signal attachments. Less common but possible.
|
|
|
|
### 4.3 File/Resource Content
|
|
**Priority: LOW**
|
|
|
|
`ResourceContentBlock` and `EmbeddedResourceContentBlock` in agent messages.
|
|
Could send file contents as Signal attachments or inline code blocks.
|
|
|
|
### 4.4 Audio Support
|
|
**Priority: LOW**
|
|
|
|
ACP has `AudioContentBlock`. Signal supports voice messages. Theoretically
|
|
bridgeable but Goose doesn't currently use audio.
|
|
|
|
---
|
|
|
|
## Phase 5: Advanced / Optional
|
|
|
|
### 5.1 Multi-User Concurrency
|
|
**Priority: MEDIUM**
|
|
|
|
Currently each contact gets their own session, and prompts run as async tasks.
|
|
But there's no protection against a user sending a second message while the
|
|
first is still processing. Options:
|
|
- Queue messages per-user (process sequentially)
|
|
- Allow concurrent prompts (may confuse Goose session state)
|
|
- Tell the user "please wait" if a prompt is in progress
|
|
|
|
### 5.2 Group Messaging
|
|
**Priority: LOW**
|
|
|
|
Signal groups could map to shared Goose sessions. Would need the account
|
|
number (already in config) for group message handling. signal-cli has
|
|
different envelope structure for group messages.
|
|
|
|
### 5.3 Extension Methods
|
|
**Priority: LOW**
|
|
|
|
`ext_method` and `ext_notification` are catch-alls for custom protocol
|
|
extensions. Log them for now; implement specific ones if Goose uses them.
|
|
|
|
### 5.4 MCP Server Configuration
|
|
**Priority: LOW**
|
|
|
|
`new_session` accepts `mcp_servers` to connect external tool servers. Could
|
|
be configured per-contact or globally in honker config.
|
|
|
|
---
|
|
|
|
## Decisions Made
|
|
|
|
1. **Terminal execution**: Permission gate is enough. No additional sandboxing.
|
|
2. **Tool call notifications**: Light — send "🔧 Running: ..." on tool start.
|
|
Goose already keeps extensive logs at `~/.local/state/goose/logs/`.
|
|
3. **Agent thoughts**: Opt-in via config flag (`forward_thoughts: true`).
|
|
4. **Cancellation UX**: `/cancel` plus general `/command` prefix convention.
|
|
5. **Multi-user concurrency**: "Please wait" — reject concurrent prompts per user.
|
|
6. **Image attachments**: Yes, wire up in Phase 1.
|
|
7. **Working directory**: Global config option (`working_directory`).
|