Skip to content

Commit e8225df

Browse files
committed
docs: restructure docs to match TS SDK layout; add PyPI publish workflow
Closes #27, closes #26 - Add .github/workflows/publish.yml (PyPI OIDC trusted publishing) - Add docs/README.md (replaces docs/00-overview.md) - Add docs/getting-started.md (replaces docs/01-quickstart.md) - Add docs/architecture.md (replaces docs/02-concepts.md + reference pages) - Add docs/transports.md (transport selection guide) - Add docs/cli.md (arcp CLI reference) - Add docs/conformance.md (replaces docs/06-conformance.md) - Add docs/troubleshooting.md (error codes and debugging) - Add docs/recipes.md (index of all recipes)
1 parent 2e880b5 commit e8225df

9 files changed

Lines changed: 787 additions & 0 deletions

File tree

.github/workflows/publish.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name: Publish to PyPI
2+
3+
on:
4+
push:
5+
tags:
6+
- "v*"
7+
8+
permissions:
9+
id-token: write # Required for OIDC trusted publishing
10+
contents: read
11+
12+
jobs:
13+
build-and-publish:
14+
name: Build and publish to PyPI
15+
runs-on: ubuntu-latest
16+
environment:
17+
name: pypi
18+
url: https://pypi.org/p/arcp
19+
20+
steps:
21+
- uses: actions/checkout@v4
22+
23+
- name: Set up Python
24+
uses: actions/setup-python@v5
25+
with:
26+
python-version: "3.11"
27+
28+
- name: Install hatch
29+
run: pip install hatch
30+
31+
- name: Build package
32+
run: hatch build
33+
34+
- name: Publish to PyPI
35+
uses: pypa/gh-action-pypi-publish@release/v1

docs/README.md

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# ARCP Python SDK
2+
3+
The **Agent Runtime Control Protocol (ARCP)** Python SDK implements [ARCP v1.1](https://arcp.dev/spec/v1.1) — a message protocol for autonomous agent job submission, streaming, observability, and lifecycle control.
4+
5+
## Install
6+
7+
```bash
8+
pip install arcp
9+
# or with uv:
10+
uv add arcp
11+
```
12+
13+
Requires Python 3.11+.
14+
15+
## Start here
16+
17+
| | |
18+
|---|---|
19+
| [Getting started](getting-started.md) | Five-minute end-to-end example |
20+
| [Architecture](architecture.md) | How the SDK is structured and why |
21+
| [Conformance](conformance.md) | Which spec sections are implemented |
22+
23+
## Guides
24+
25+
One guide per ARCP spec section:
26+
27+
| Guide | Spec |
28+
|---|---|
29+
| [Sessions](guides/sessions.md) | §6 — Session lifecycle |
30+
| [Stream resume](guides/resume.md) | §6.3 — Resuming interrupted streams |
31+
| [Authentication](guides/auth.md) | §6.1 — Bearer tokens and custom verifiers |
32+
| [Jobs](guides/jobs.md) | §7 — Submitting and running jobs |
33+
| [Job events](guides/job-events.md) | §8 — Event kinds and typed payloads |
34+
| [Leases](guides/leases.md) | §9 — Cost and time budgets |
35+
| [Delegation](guides/delegation.md) | §10 — Agent-to-agent trust chains |
36+
| [Observability](guides/observability.md) | §11 — Logging, tracing, and metrics |
37+
| [Errors](guides/errors.md) | §12 — Typed exceptions |
38+
| [Vendor extensions](guides/vendor-extensions.md) | §15 — Custom `x-*` fields |
39+
40+
## Reference
41+
42+
| | |
43+
|---|---|
44+
| [Transports](transports.md) | In-memory, WebSocket, stdio |
45+
| [CLI](cli.md) | `arcp serve`, `submit`, `tail`, `replay` |
46+
| [Troubleshooting](troubleshooting.md) | Common errors and fixes |
47+
48+
## Recipes
49+
50+
See [recipes.md](recipes.md) for a full index of runnable examples.
51+
52+
## Links
53+
54+
- [ARCP Specification v1.1](https://arcp.dev/spec/v1.1)
55+
- [TypeScript SDK](https://github.com/agentruntimecontrolprotocol/typescript-sdk)
56+
- [PyPI: arcp](https://pypi.org/project/arcp/)
57+
- [Changelog](../CHANGELOG.md)

docs/architecture.md

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
# Architecture
2+
3+
This document explains how the ARCP Python SDK is structured, what each layer does, and how the pieces fit together at runtime.
4+
5+
## Package layout
6+
7+
```
8+
arcp/
9+
├── __init__.py # Public surface: ARCPClient, ARCPRuntime, types
10+
├── client/ # ARCPClient, JobHandle, JobSubscription
11+
├── runtime/ # ARCPRuntime, verifiers, agent registry
12+
├── _transport/ # Transport protocol + concrete implementations
13+
├── _envelope.py # Wire format (de)serialisation
14+
├── _errors.py # 15 typed exceptions (§12)
15+
├── _version.py
16+
├── _extensions.py # Vendor extension helpers (§15)
17+
└── middleware/
18+
├── asgi.py # ASGI adapter (FastAPI, Starlette, …)
19+
├── aiohttp.py # aiohttp adapter
20+
└── otel.py # OpenTelemetry span / metric export
21+
```
22+
23+
## The six-piece protocol
24+
25+
ARCP defines six protocol concepts that form concentric rings:
26+
27+
```
28+
┌─────────────────────────────────────────┐
29+
│ Session (§6) │
30+
│ ┌───────────────────────────────────┐ │
31+
│ │ Job (§7) │ │
32+
│ │ ┌─────────────────────────────┐ │ │
33+
│ │ │ Events (§8) │ │ │
34+
│ │ └─────────────────────────────┘ │ │
35+
│ │ ┌────────────┐ ┌──────────────┐ │ │
36+
│ │ │ Lease (§9) │ │Delegation(§10│ │ │
37+
│ │ └────────────┘ └──────────────┘ │ │
38+
│ └───────────────────────────────────┘ │
39+
│ Observability (§11) │
40+
└─────────────────────────────────────────┘
41+
```
42+
43+
### Sessions (§6)
44+
45+
A session is the authenticated connection between a client and a runtime. The client presents a bearer token; the runtime verifies it and assigns a *principal* (a string identity like an email address).
46+
47+
```python
48+
from arcp.runtime import ARCPRuntime, StaticBearerVerifier
49+
50+
runtime = ARCPRuntime(
51+
runtime=RuntimeInfo(name="my-service", version="1.0.0"),
52+
bearer=StaticBearerVerifier({"secret-token": "alice@example.com"}),
53+
)
54+
```
55+
56+
See [Sessions guide](guides/sessions.md) and [Auth guide](guides/auth.md).
57+
58+
### Envelopes
59+
60+
Every message on the wire is an **envelope**: a JSON object with a `type` discriminator and a `payload`. The SDK handles (de)serialisation transparently via `arcp._envelope`. You never construct envelopes directly.
61+
62+
### Jobs (§7)
63+
64+
A job is a unit of work: an agent name, an input payload, optional lease constraints, and an optional idempotency key.
65+
66+
```python
67+
handle = await client.submit(
68+
agent="summarise",
69+
input={"url": "https://example.com"},
70+
lease_request={"max_cost_usd": 0.10, "expires_in_s": 60},
71+
idempotency_key="req-abc123",
72+
)
73+
```
74+
75+
See [Jobs guide](guides/jobs.md).
76+
77+
### Events (§8)
78+
79+
While a job runs, the runtime emits a stream of typed events:
80+
81+
| Event kind | Meaning |
82+
|---|---|
83+
| `job.queued` | Job accepted and placed in queue |
84+
| `job.started` | Agent function invoked |
85+
| `job.log` | Log line from `ctx.log(level, message)` |
86+
| `job.progress` | Progress update from `ctx.progress(done, total)` |
87+
| `job.result_chunk` | Streaming result fragment |
88+
| `job.completed` | Agent returned; payload contains final result |
89+
| `job.failed` | Agent raised an exception |
90+
| `job.cancelled` | Job was cancelled before completion |
91+
| `job.heartbeat` | Keep-alive ping |
92+
93+
See [Job events guide](guides/job-events.md).
94+
95+
### Leases (§9)
96+
97+
A lease is a spending cap attached to a job. Clients request a lease at submit time; the runtime enforces it.
98+
99+
```python
100+
handle = await client.submit(
101+
agent="gpt-4-summary",
102+
input={"text": long_text},
103+
lease_request={"max_cost_usd": 0.05},
104+
)
105+
```
106+
107+
See [Leases guide](guides/leases.md).
108+
109+
### Delegation (§10)
110+
111+
An agent can act as a client to another runtime. The originating client's identity flows through the chain via signed delegation tokens.
112+
113+
See [Delegation guide](guides/delegation.md).
114+
115+
### Observability (§11)
116+
117+
The SDK emits OpenTelemetry spans and metrics via `arcp.middleware.otel`.
118+
119+
See [Observability guide](guides/observability.md).
120+
121+
## Runtime and client lifecycle
122+
123+
```
124+
client_transport, server_transport = pair_memory_transports()
125+
126+
Client side Runtime side
127+
───────────────────────────────── ─────────────────────────────────
128+
ARCPClient.connect(client_transport) ──► ARCPRuntime.accept(server_transport)
129+
│ │
130+
negotiate capabilities verify bearer token
131+
│ │
132+
submit(agent, input) ──────────────► route to registered agent fn
133+
│ │
134+
JobHandle ◄──── event stream ────────── agent executes
135+
│ │
136+
await handle.done ◄──── job.completed ─── agent returns
137+
```
138+
139+
## Agent versions (§6.2)
140+
141+
Clients can pin to a specific agent version:
142+
143+
```python
144+
handle = await client.submit(
145+
agent="summarise",
146+
input={"url": "https://example.com"},
147+
agent_version="2",
148+
)
149+
```
150+
151+
Runtimes register versioned agents:
152+
153+
```python
154+
runtime.register_agent("summarise", summarise_v1, version="1")
155+
runtime.register_agent("summarise", summarise_v2, version="2")
156+
```
157+
158+
If the client omits `agent_version`, the runtime uses the latest registered version.
159+
160+
## Middleware
161+
162+
### ASGI (FastAPI, Starlette)
163+
164+
```python
165+
from arcp.middleware.asgi import ARCPMiddleware
166+
167+
app = FastAPI()
168+
app.add_middleware(ARCPMiddleware, runtime=runtime)
169+
```
170+
171+
### aiohttp
172+
173+
```python
174+
from arcp.middleware.aiohttp import attach_arcp
175+
176+
app = web.Application()
177+
attach_arcp(app, runtime=runtime)
178+
```
179+
180+
### OpenTelemetry
181+
182+
```python
183+
from arcp.middleware.otel import OtelMiddleware
184+
185+
runtime = ARCPRuntime(..., middleware=[OtelMiddleware()])
186+
```
187+
188+
See [Observability guide](guides/observability.md) for full configuration.
189+
190+
## Error hierarchy
191+
192+
All SDK exceptions inherit from `ARCPError`. The 15 typed exceptions map directly to spec §12 error codes.
193+
194+
See [Errors guide](guides/errors.md) and [Troubleshooting](troubleshooting.md).

docs/cli.md

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# CLI reference
2+
3+
The `arcp` command-line tool is included with the `arcp` package. It provides subcommands for serving agents, submitting jobs, and inspecting event streams.
4+
5+
## Installation
6+
7+
```bash
8+
pip install arcp
9+
# arcp is now on your PATH
10+
```
11+
12+
## Subcommands
13+
14+
### `arcp serve`
15+
16+
Start an ARCP runtime serving agents from a Python module.
17+
18+
```bash
19+
arcp serve my_module:runtime --host 0.0.0.0 --port 8080
20+
```
21+
22+
**Arguments:**
23+
24+
| Argument | Default | Description |
25+
|---|---|---|
26+
| `MODULE:ATTR` | required | Python import path to an `ARCPRuntime` instance |
27+
| `--host` | `127.0.0.1` | Bind address |
28+
| `--port` | `8080` | Bind port |
29+
| `--reload` | off | Auto-reload on file changes (dev only) |
30+
31+
### `arcp submit`
32+
33+
Submit a job to a running runtime and print the result.
34+
35+
```bash
36+
arcp submit ws://localhost:8080/arcp summarise '{"url":"https://example.com"}' \
37+
--token my-bearer-token
38+
```
39+
40+
**Arguments:**
41+
42+
| Argument | Description |
43+
|---|---|
44+
| `URL` | WebSocket URL of the runtime |
45+
| `AGENT` | Agent name |
46+
| `INPUT` | JSON-encoded input (use `@file.json` to read from file) |
47+
| `--token` | Bearer token |
48+
| `--lease-max-cost` | Maximum spend in USD (e.g. `0.10`) |
49+
| `--lease-expires-in` | Maximum wall time in seconds |
50+
| `--idempotency-key` | Idempotency key |
51+
| `--stream` | Print result chunks as they arrive |
52+
53+
### `arcp tail`
54+
55+
Tail the event stream for a job in real time.
56+
57+
```bash
58+
arcp tail ws://localhost:8080/arcp JOB_ID --token my-bearer-token
59+
```
60+
61+
Prints each `JobEvent` as a JSON line. Press `Ctrl-C` to stop.
62+
63+
### `arcp replay`
64+
65+
Replay a recorded event stream from a JSONL file.
66+
67+
```bash
68+
arcp replay events.jsonl
69+
```
70+
71+
Useful for debugging: record a live stream with `arcp tail --output events.jsonl`, then replay it offline.
72+
73+
## Environment variables
74+
75+
All CLI options can also be set via environment variables:
76+
77+
| Variable | CLI equivalent |
78+
|---|---|
79+
| `ARCP_TOKEN` | `--token` |
80+
| `ARCP_HOST` | `arcp serve --host` |
81+
| `ARCP_PORT` | `arcp serve --port` |
82+
83+
## Shell completion
84+
85+
```bash
86+
# bash
87+
arcp --install-completion bash
88+
89+
# zsh
90+
arcp --install-completion zsh
91+
92+
# fish
93+
arcp --install-completion fish
94+
```

0 commit comments

Comments
 (0)