Skip to content

Commit d5ed664

Browse files
authored
Merge pull request #7 from nikomatsakis/improve-docs
docs: Improve and polish README etc
2 parents e2459d4 + 30fe54b commit d5ed664

35 files changed

+2343
-667
lines changed

Cargo.lock

Lines changed: 32 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ members = [
33
"src/sacp-proxy",
44
"src/sacp-conductor",
55
"src/sacp",
6+
"src/sacp-tokio",
67
"src/elizacp",
8+
"src/sacp-doc-test",
79
]
810
resolver = "2"
911

README.md

Lines changed: 17 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -1,119 +1,40 @@
1-
# SACP: Symposium's Extensions to ACP
1+
# SACP: Symposium Agent Client Protocol SDK
22

3-
**SACP** is an SDK for building composable AI agent systems using the [Agent-Client Protocol](https://agentclientprotocol.com/).
3+
This repository houses the **Symposium ACP SDK**, which aims to:
44

5-
## What is SACP?
5+
1. **Provide a nicer SDK for working with ACP in general** - Type-safe, async-first, and easy to use for building agents and editors
6+
2. **Support proxy components for composable extensions** - Build modular components that extend agent behavior without modifying the agent itself
67

7-
SACP extends ACP to enable **composable agent architectures through proxy chains**. Instead of building monolithic AI tools, SACP allows you to create modular components that can intercept and transform messages flowing between editors and agents.
8+
Instead of building monolithic AI tools, SACP enables **composable agent architectures through proxy chains** where functionality can be added, removed, or reconfigured dynamically.
89

910
```mermaid
1011
flowchart LR
1112
Editor[ACP Editor] -->|ACP| Conductor
12-
13+
1314
subgraph Conductor[Conductor Process]
1415
P1[Proxy 1]
1516
P2[Proxy 2]
1617
Agent[Base Agent]
17-
18+
1819
P1 --> P2 --> Agent
1920
end
2021
```
2122

2223
## Repository Structure
2324

24-
This repository contains three core crates:
25+
This repository contains several crates:
26+
27+
**Core SDK:**
28+
- **[`sacp`](./src/sacp/)** - Core ACP SDK for building agents and editors in Rust
29+
- **[`sacp-tokio`](./src/sacp-tokio/)** - Tokio-specific utilities (process spawning, connection management)
2530

26-
- **[`sacp`](./src/sacp/)** - Core protocol types and traits for building clients and agents
27-
- **[`sacp-proxy`](./src/sacp-proxy/)** - Framework for building proxy components
31+
**Proxy Framework:**
32+
- **[`sacp-proxy`](./src/sacp-proxy/)** - Framework for building ACP proxy components
2833
- **[`sacp-conductor`](./src/sacp-conductor/)** - Binary that orchestrates proxy chains
34+
35+
**Examples & Testing:**
2936
- **[`elizacp`](./src/elizacp/)** - Example ACP agent implementing the classic Eliza chatbot (useful for testing)
3037

3138
## Documentation
3239

33-
Full documentation is available in the [mdbook](https://rust-lang.github.io/mdBook/):
34-
35-
```bash
36-
mdbook serve
37-
```
38-
39-
Then visit http://localhost:3000
40-
41-
Key chapters:
42-
- [Introduction](./md/introduction.md) - What is SACP and why use it
43-
- [Architecture Overview](./md/architecture.md) - How proxy chains work
44-
- [Protocol Reference](./md/protocol.md) - Technical protocol details
45-
46-
## Quick Start
47-
48-
### Using as a Library
49-
50-
Add to your `Cargo.toml`:
51-
52-
```toml
53-
[dependencies]
54-
sacp = "0.1" # Core protocol types
55-
sacp-proxy = "0.1" # For building proxies
56-
```
57-
58-
### Building the Conductor
59-
60-
```bash
61-
cargo build --release -p sacp-conductor
62-
```
63-
64-
The conductor binary will be at `target/release/sacp-conductor`.
65-
66-
### Running a Proxy Chain
67-
68-
```bash
69-
# Start a proxy chain with two components
70-
sacp-conductor agent proxy-component-1 proxy-component-2 base-agent
71-
```
72-
73-
The conductor presents as a normal ACP agent to editors while orchestrating the proxy chain internally.
74-
75-
## Example Use Case: Sparkle Integration
76-
77-
The [sparkle-acp-proxy](https://github.com/nikomatsakis/sparkle-acp-proxy) demonstrates a real-world SACP proxy that:
78-
79-
1. Injects Sparkle's MCP server during initialization
80-
2. Prepends embodiment sequences to prompts
81-
3. Provides collaborative AI patterns transparently
82-
83-
## Development
84-
85-
### Building
86-
87-
```bash
88-
cargo build
89-
```
90-
91-
### Testing
92-
93-
```bash
94-
cargo test
95-
```
96-
97-
### Running Examples
98-
99-
See the test files in each crate for usage examples.
100-
101-
## Design Documentation
102-
103-
The `md/` directory contains detailed design documentation extracted from the Symposium project:
104-
105-
- [proxying-acp.md](./md/proxying-acp.md) - Complete RFD with protocol specification
106-
- [pacp-components.md](./md/pacp-components.md) - Component architecture overview
107-
- [conductor.md](./md/conductor.md) - Conductor implementation details
108-
109-
## Relationship to ACP
110-
111-
SACP is an [extension to ACP](https://agentclientprotocol.com/protocol/extensibility), not a fork. SACP components communicate using ACP's extension protocol (`_meta` fields and custom methods). Standard ACP editors and agents work with SACP without modification.
112-
113-
## License
114-
115-
MIT OR Apache-2.0
116-
117-
## Contributing
118-
119-
This repository will be upstreamed to the `agent-client-protocol` organization. Contributions welcome!
40+
Full documentation is available in the [mdbook](https://rust-lang.github.io/mdBook/). You can browse the latest version on [our Github pages site](https://symposium-acp.github.io/symposium-acp/).

src/elizacp/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ version = "0.1.0"
44
edition = "2024"
55
description = "Classic Eliza chatbot as an ACP agent for testing"
66
license = "MIT OR Apache-2.0"
7-
repository = "https://github.com/agent-client-protocol/symposium-acp"
7+
repository = "https://github.com/symposium-dev/symposium-acp"
88
keywords = ["acp", "agent", "eliza", "testing"]
99
categories = ["development-tools"]
1010
authors = ["Niko Matsakis <niko@alum.mit.edu>"]

src/sacp-conductor/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ version = "0.1.1"
44
edition = "2024"
55
description = "Conductor for orchestrating SACP proxy chains"
66
license = "MIT OR Apache-2.0"
7-
repository = "https://github.com/agent-client-protocol/symposium-acp"
7+
repository = "https://github.com/symposium-dev/symposium-acp"
88
keywords = ["acp", "agent", "conductor", "ai"]
99
categories = ["development-tools"]
1010

src/sacp-conductor/README.md

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# sacp-conductor
2+
3+
Binary for orchestrating ACP proxy chains.
4+
5+
## What is the conductor?
6+
7+
The conductor is a tool that manages proxy chains - it spawns proxy components and the base agent, then routes messages between them. From the editor's perspective, the conductor appears as a single ACP agent.
8+
9+
```
10+
Editor ← stdio → Conductor → Proxy 1 → Proxy 2 → Agent
11+
```
12+
13+
## Usage
14+
15+
### Agent Mode
16+
17+
Orchestrate a chain of proxies in front of an agent:
18+
19+
```bash
20+
# Chain format: proxy1 proxy2 ... agent
21+
sacp-conductor agent "python proxy1.py" "python proxy2.py" "python base-agent.py"
22+
```
23+
24+
The conductor:
25+
1. Spawns each component as a subprocess
26+
2. Connects them in a chain
27+
3. Presents as a single agent on stdin/stdout
28+
4. Manages the lifecycle of all processes
29+
30+
### MCP Bridge Mode
31+
32+
Connect stdio to a TCP-based MCP server:
33+
34+
```bash
35+
# Bridge stdio to MCP server on localhost:8080
36+
sacp-conductor mcp 8080
37+
```
38+
39+
This allows stdio-based tools to communicate with TCP MCP servers.
40+
41+
## How It Works
42+
43+
**Component Communication:**
44+
- Editor talks to conductor via stdio
45+
- Conductor uses `_proxy/successor/*` protocol extensions to route messages
46+
- Each proxy can intercept, transform, or forward messages
47+
- Final agent receives standard ACP messages
48+
49+
**Process Management:**
50+
- All components are spawned as child processes
51+
- When conductor exits, all children are terminated
52+
- Errors in any component bring down the entire chain
53+
54+
## Example Use Case
55+
56+
Add Sparkle embodiment + custom tools to any agent:
57+
58+
```bash
59+
sacp-conductor agent \
60+
"sparkle-acp-proxy" \
61+
"my-custom-tools-proxy" \
62+
"claude-agent"
63+
```
64+
65+
This creates a stack where:
66+
1. Sparkle proxy injects MCP servers and prepends embodiment
67+
2. Custom tools proxy adds domain-specific functionality
68+
3. Base agent handles the actual AI responses
69+
70+
## Building
71+
72+
```bash
73+
cargo build --release -p sacp-conductor
74+
```
75+
76+
Binary will be at `target/release/sacp-conductor`.
77+
78+
## Related Crates
79+
80+
- **[sacp-proxy](../sacp-proxy/)** - Framework for building proxy components
81+
- **[sacp](../sacp/)** - Core ACP SDK
82+
- **[sacp-tokio](../sacp-tokio/)** - Tokio utilities for process spawning
83+
84+
## License
85+
86+
MIT OR Apache-2.0

src/sacp-conductor/src/conductor.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,9 @@ use sacp_proxy::{
7070
};
7171

7272
use sacp::{
73-
JrConnection, JrConnectionCx, JrNotification, JrRequestCx, JrResponse, JsonRpcRequest,
74-
MessageAndCx, MetaCapabilityExt, NullHandler, Proxy, TypeNotification, TypeRequest,
75-
UntypedMessage,
73+
JrConnection, JrConnectionCx, JrNotification, JrRequest, JrRequestCx, JrResponse, MessageAndCx,
74+
MetaCapabilityExt, NullHandler, Proxy, UntypedMessage,
75+
util::{TypeNotification, TypeRequest},
7676
};
7777
use tokio_util::compat::{TokioAsyncReadCompatExt, TokioAsyncWriteCompatExt};
7878
use tracing::{debug, info};
@@ -480,7 +480,7 @@ impl Conductor {
480480
/// * If the message is going to a proxy component, then we have to wrap
481481
/// it in a "from successor" wrapper, because the conductor is the
482482
/// proxy's client.
483-
fn send_message_to_predecessor_of<Req: JsonRpcRequest, N: JrNotification>(
483+
fn send_message_to_predecessor_of<Req: JrRequest, N: JrNotification>(
484484
&mut self,
485485
client: &JrConnectionCx,
486486
source_component_index: usize,
@@ -504,7 +504,7 @@ impl Conductor {
504504
}
505505
}
506506

507-
fn send_request_to_predecessor_of<Req: JsonRpcRequest>(
507+
fn send_request_to_predecessor_of<Req: JrRequest>(
508508
&mut self,
509509
client: &JrConnectionCx,
510510
source_component_index: usize,

src/sacp-doc-test/Cargo.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[package]
2+
name = "sacp-doc-test"
3+
version = "0.1.0"
4+
edition = "2024"
5+
6+
[dependencies]
7+
sacp = { path = "../sacp" }
8+
serde.workspace = true
9+
futures.workspace = true
10+
serde_json.workspace = true

0 commit comments

Comments
 (0)