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
15 changes: 15 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ members = [
"crates/buzz-workflow",
"crates/buzz-media",
"crates/buzz-cli",
"crates/buzz-broker-client",
"crates/buzz-pairing-cli",
"crates/buzz-sdk",
"crates/buzz-persona",
Expand Down Expand Up @@ -147,6 +148,7 @@ buzz-audit = { path = "crates/buzz-audit" }
buzz-workflow = { path = "crates/buzz-workflow" }
buzz-media = { path = "crates/buzz-media" }
buzz-sdk = { path = "crates/buzz-sdk" }
buzz-broker-client = { path = "crates/buzz-broker-client" }
buzz-ws-client = { path = "crates/buzz-ws-client" }
buzz-relay-mesh = { path = "crates/buzz-relay-mesh" }
buzz-datastore-tracing = { path = "crates/buzz-datastore-tracing" }
Expand Down
2 changes: 2 additions & 0 deletions crates/buzz-acp/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ path = "src/main.rs"
# Internal
buzz-core = { workspace = true }
buzz-sdk = { workspace = true }
buzz-broker-client = { workspace = true }
buzz-persona = { path = "../buzz-persona" }

# Nostr
Expand Down Expand Up @@ -77,5 +78,6 @@ evalexpr = { workspace = true }
nix = { version = "0.31", default-features = false, features = ["signal"] }

[dev-dependencies]
axum = { workspace = true }
tokio = { workspace = true, features = ["test-util"] }
httparse = "1"
54 changes: 51 additions & 3 deletions crates/buzz-acp/README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
# buzz-acp

ACP harness that connects AI agents to Buzz. The harness listens for @mentions on the relay, prompts your agent, and the agent replies using the Buzz CLI.
ACP harness that connects AI agents to Buzz. In local mode the harness listens
for @mentions on the relay. In keyless broker mode it polls a host that owns the
agent key and relay route. Both modes prompt the same ACP agent, which replies
using the Buzz CLI.

```
Buzz Relay ──WS──→ buzz-acp ──stdio──→ Your Agent
Buzz Relay ──WS──→ buzz-acp ──stdio──→ Your Agent (local)
Broker Host ─HTTP→ buzz-acp ──stdio──→ Your Agent (keyless)
Buzz CLI
(send_message, etc.)
Expand Down Expand Up @@ -64,6 +68,43 @@ buzz-acp

That's it. The harness spawns `goose acp`, connects to the relay, discovers channels, and starts listening. When someone @mentions the agent, goose receives the message and can reply using the Buzz CLI that the harness configures automatically.

## Keyless broker mode

Broker mode starts the runtime without an agent private key or direct relay
connection. The harness derives the agent public key through `storage.address`,
polls each configured channel through `channel.read`, and provisions the spawned
agent and optional MCP server with broker variables so their `buzz` commands use
the same host.

```bash
export BUZZ_AGENT_MODE=broker
export BUZZ_BROKER_URL=http://127.0.0.1:8787
export BUZZ_BROKER_CREDENTIAL=dev-token
export BUZZ_BROKER_RELAY_URL=wss://relay.example
export BUZZ_ACP_CHANNELS=5df7dfa8-e919-43df-8efd-f1dcb8af7071
export BUZZ_ACP_AGENT_OWNER=a02c4e0850e5e612b4ddf95dbe2f5c56467cf27c6552203bc833ff438fb31971
unset BUZZ_PRIVATE_KEY BUZZ_RELAY_URL BUZZ_AUTH_TAG

buzz-acp
```

Broker mode requires explicit channel UUIDs and `respond-to=owner-only` because
the contract does not expose channel discovery or metadata. Core-memory reads,
presence, typing, observer telemetry, and turn liveness use broker actions.
`BUZZ_BROKER_RELAY_URL` identifies the relay behind the broker for desktop
observer/runtime pairing only; the harness and its children never connect to it.
Relay-only conversation enrichment, setup nudges, sibling-profile lookup, and
reaction-based turn status remain disabled. The `buzz` CLI operations available
to the spawned agent are documented in
[`../buzz-cli/KEYLESS.md`](../buzz-cli/KEYLESS.md).

Broker actions time out after 30 seconds and require TLS except on loopback. An
`unauthenticated` polling verdict terminates the harness so a revoked credential
cannot leave a warn-spamming process that appears healthy. Poll cursors and
event deduplication remain in memory only. After a pagination chain is drained,
the runtime returns to cursorless polling and relies on bounded event-ID deduplication so later
messages remain visible.

## Running with Codex

[codex-acp](https://github.com/agentclientprotocol/codex-acp) wraps OpenAI Codex in an ACP interface.
Expand Down Expand Up @@ -106,8 +147,15 @@ All configuration is via environment variables (or CLI flags — every env var h

| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `BUZZ_PRIVATE_KEY` | **yes** | — | Agent's Nostr private key (`nsec1...`). Used for relay auth and agent identity. |
| `BUZZ_AGENT_MODE` | no | `local` | Runtime substrate: `local` or keyless `broker`. |
| `BUZZ_PRIVATE_KEY` | local only | — | Agent's Nostr private key (`nsec1...`). Rejected in broker mode. |
| `BUZZ_RELAY_URL` | no | `ws://localhost:3000` | Relay WebSocket URL. |
| `BUZZ_BROKER_URL` | broker only | — | Broker base URL; actions are posted to `/v1/action`. |
| `BUZZ_BROKER_CREDENTIAL` | broker only | — | Bearer credential issued by the broker host. |
| `BUZZ_BROKER_RELAY_URL` | broker only | — | Relay identity behind the broker, used only for observer/runtime pairing; never connected to directly. |
| `BUZZ_BROKER_POLL_INTERVAL_MS` | no | `1000` | Broker `channel.read` polling interval; minimum `100`. |
| `BUZZ_ACP_CHANNELS` | broker only | — | Comma-separated channel UUIDs to poll. |
| `BUZZ_ACP_AGENT_OWNER` | broker only | — | Owner pubkey accepted by the broker-mode author gate. |
| `BUZZ_ACP_AGENT_COMMAND` | no | `goose` | Agent binary to spawn. |
| `BUZZ_ACP_AGENT_ARGS` | no | `acp` | Agent arguments (comma-separated). |
| `BUZZ_ACP_MCP_COMMAND` | no | `""` (empty) | Path to an optional MCP server binary to provide to the agent subprocess. |
Expand Down
Loading
Loading