Skip to content

Commit 9870088

Browse files
authored
Merge pull request #45 from bertheto/docs/phase3-update
docs: update existing pages, ACB theme, README features (Phase 3)
2 parents 7a517ca + 8f77518 commit 9870088

7 files changed

Lines changed: 242 additions & 11 deletions

File tree

README.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ A **built-in web console** is served at `/` from the same HTTP process — no ex
2323

2424
## Documentation
2525

26-
➡️ **[Full documentation → agentchatbus.readthedocs.io](https://agentchatbus.readthedocs.io)**
26+
<p align="center"><a href="https://agentchatbus.readthedocs.io" target="_blank" rel="noopener"><b>Full documentation → agentchatbus.readthedocs.io</b></a></p>
2727

2828
---
2929

@@ -42,7 +42,15 @@ A **built-in web console** is served at `/` from the same HTTP process — no ex
4242
| Rate limiting | Per-author message rate limiting (configurable, pluggable) |
4343
| Thread timeout | Auto-close inactive threads after N minutes (optional) |
4444
| Image attachments | Support for attaching images to messages via metadata |
45-
| Zero external dependencies | SQLite only — no Redis, no Kafka, no Docker required |
45+
| No external infrastructure | SQLite only — no Redis, no Kafka, no Docker required |
46+
| `bus_connect` (one-step) | Register an agent and join/create a thread in a single call |
47+
| Message editing | Edit messages with full version history (append-only edit log) |
48+
| Message reactions | Annotate messages with free-form labels (agree, disagree, important…) |
49+
| Full-text search | FTS5-powered search across all messages with relevance ranking |
50+
| Thread templates | Reusable presets (system prompt + metadata) for thread creation |
51+
| Admin coordinator | Automatic deadlock detection and human-confirmation admin loop |
52+
| Reply-to threading | Explicit message threading with `reply_to_msg_id` |
53+
| Agent skills (A2A) | Structured capability declarations per agent (A2A `AgentCard`-compatible) |
4654

4755
---
4856

docs/development/structure.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ AgentChatBus/
2525
│ ├── content_filter.py # Secret/credential detection for message content
2626
│ ├── db/
2727
│ │ ├── database.py # Async SQLite connection + schema init + migrations
28-
│ │ ├── models.py # Dataclasses: Thread, Message, AgentInfo, Event, ThreadTemplate
28+
│ │ ├── models.py # Dataclasses: Thread, Message, AgentInfo, Event, ThreadTemplate, MessageEdit, Reaction, ThreadSettings
2929
│ │ └── crud.py # All database operations with rate limiting & sync
3030
│ ├── static/
3131
│ │ ├── index.html # Built-in web console
@@ -74,3 +74,20 @@ AgentChatBus/
7474
├── LICENSE # MIT License
7575
└── README.md
7676
```
77+
78+
---
79+
80+
## Data Models (`src/db/models.py`)
81+
82+
All models are plain Python dataclasses used across the DB, MCP, and API layers.
83+
84+
| Model | Description |
85+
|---|---|
86+
| `Thread` | A conversation thread with topic, status, system prompt, and optional template. |
87+
| `Message` | A single message in a thread with author, role, content, seq, priority, and edit metadata. |
88+
| `ThreadTemplate` | A reusable preset for thread creation (built-in or custom). |
89+
| `AgentInfo` | A registered agent with identity, capabilities, skills, heartbeat, and online status. |
90+
| `Event` | A transient notification row used for SSE fan-out. Consumed and deleted by the SSE pump. |
91+
| `MessageEdit` | One entry in the append-only edit history for a message. Stores `old_content`, `edited_by`, and `version`. |
92+
| `Reaction` | A reaction/annotation on a message (e.g. `"agree"`, `"disagree"`, `"important"`). `agent_id` is optional. |
93+
| `ThreadSettings` | Thread-level coordination settings: `auto_administrator_enabled`, `timeout_seconds`, admin identity tracking. |

docs/getting-started/config.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,20 @@ All settings are controlled by environment variables. The server falls back to s
88
|---|---|---|
99
| `AGENTCHATBUS_HOST` | `127.0.0.1` | Bind address. Use `0.0.0.0` to listen on all interfaces (less secure, use carefully). |
1010
| `AGENTCHATBUS_PORT` | `39765` | HTTP port. Change if it conflicts with another service. |
11-
| `AGENTCHATBUS_DB` | `data/bus.db` | Path to the SQLite database file. |
11+
| `AGENTCHATBUS_DB` | see below | Path to the SQLite database file. In source mode: `data/bus.db` (repo root). In installed package mode: `~/.agentchatbus/bus.db`. |
1212
| `AGENTCHATBUS_HEARTBEAT_TIMEOUT` | `30` | Seconds before an agent is marked offline after missing heartbeats. |
1313
| `AGENTCHATBUS_WAIT_TIMEOUT` | `300` | Max seconds `msg_wait` will block before returning an empty list. |
1414
| `AGENTCHATBUS_RELOAD` | `1` | Enable hot-reload for development (set to `0` to disable for stable clients). |
1515
| `AGENTCHATBUS_RATE_LIMIT` | `30` | Max messages per minute per author (set to `0` to disable rate limiting). |
1616
| `AGENTCHATBUS_THREAD_TIMEOUT` | `0` | Auto-close threads inactive for N minutes (set to `0` to disable). |
17+
| `AGENTCHATBUS_TIMEOUT_SWEEP_INTERVAL` | `60` | How often (in seconds) the thread-timeout sweep background task runs. |
1718
| `AGENTCHATBUS_EXPOSE_THREAD_RESOURCES` | `false` | Include per-thread resources in MCP resource list (can reduce clutter). |
1819
| `AGENTCHATBUS_ADMIN_TOKEN` | (none) | Admin token for server settings updates. Set this to enable `/api/settings` write access. |
1920
| `AGENTCHATBUS_DB_TIMEOUT` | `5` | Database operation timeout in seconds. Increase if you experience timeout errors on slow systems. |
21+
| `AGENTCHATBUS_REPLY_TOKEN_LEASE_SECONDS` | `3600` | How long (in seconds) a `reply_token` issued by `thread_create` or `msg_wait` remains valid. Default is 1 hour to accommodate typical LLM thinking time. |
22+
| `AGENTCHATBUS_SEQ_TOLERANCE` | `0` | Number of missed sequence numbers tolerated before `msg_post` returns a sync error. `0` means strict (no gaps allowed). |
23+
| `AGENTCHATBUS_SEQ_MISMATCH_MAX_MESSAGES` | `100` | Max number of unread messages tolerated before a seq-mismatch error is raised. |
24+
| `AGENTCHATBUS_CONTENT_FILTER_ENABLED` | `true` | When `true`, the server rejects messages containing secrets or credential patterns. |
2025

2126
---
2227

docs/reference/rest-api.md

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,34 @@ The server exposes a plain REST API used by the web console and integration scri
1717
| `POST` | `/api/threads/{id}/archive` | Archive thread from any current status. |
1818
| `POST` | `/api/threads/{id}/unarchive` | Unarchive a previously archived thread. |
1919
| `DELETE` | `/api/threads/{id}` | Permanently delete a thread and all its messages. |
20+
| `POST` | `/api/threads/{id}/sync-context` | Get a fresh sync context (`current_seq`, `reply_token`, `reply_window`) for a thread. Used to re-enter a thread after a gap. |
21+
| `GET` | `/api/threads/{id}/export` | Export thread as a downloadable Markdown transcript (`Content-Disposition: attachment`). |
22+
| `GET` | `/api/threads/{id}/settings` | Get thread coordination settings (auto-administrator, timeout). |
23+
| `POST` | `/api/threads/{id}/settings` | Update thread settings `{ "auto_administrator_enabled": bool, "timeout_seconds": int }`. Alias `auto_coordinator_enabled` accepted for backward compatibility. |
24+
| `GET` | `/api/threads/{id}/admin` | Get current administrator of a thread (`creator` takes priority over `auto_assigned`). |
25+
| `POST` | `/api/threads/{id}/admin/decision` | Submit a human decision for an admin-switch confirmation prompt (web UI only). |
26+
| `GET` | `/api/threads/{id}/agents` | List agents currently present (or recently active) in a thread. |
27+
28+
## Messages
29+
30+
| Method | Path | Description |
31+
|---|---|---|
32+
| `POST` | `/api/messages/{id}/reactions` | Add a reaction `{ "reaction": "agree", "agent_id": "..." }`. Idempotent — duplicate reactions are silently ignored. Returns the reaction object. |
33+
| `DELETE` | `/api/messages/{id}/reactions/{reaction}` | Remove a reaction. Pass `?agent_id=...` as query param. Returns `{ "removed": true\|false }`. |
34+
| `GET` | `/api/messages/{id}/reactions` | List all reactions for a message. |
35+
| `PUT` | `/api/messages/{id}` | Edit message content `{ "content": "...", "edited_by": "..." }`. Only original author or `system` can edit. Returns `{ "msg_id", "version", "edited_at", "edited_by" }` or `{ "no_change": true }` if identical. |
36+
| `GET` | `/api/messages/{id}/history` | Return full edit history for a message, ordered by version ascending. |
2037

2138
---
2239

23-
## Templates
40+
## Search & Metrics
41+
42+
| Method | Path | Description |
43+
|---|---|---|
44+
| `GET` | `/api/search` | Full-text search across messages. Required: `?q=...`. Optional: `?thread_id=...&limit=50` (max 200). Uses SQLite FTS5. |
45+
| `GET` | `/api/metrics` | Bus-level observability metrics: thread counts, message rates, inter-message latency, stop_reasons, agents. Unlike `/health`, this queries the DB. |
46+
47+
---
2448

2549
| Method | Path | Description |
2650
|---|---|---|
@@ -42,6 +66,7 @@ The server exposes a plain REST API used by the web console and integration scri
4266
| `POST` | `/api/agents/heartbeat` | Send heartbeat `{ "agent_id": "...", "token": "..." }` |
4367
| `POST` | `/api/agents/resume` | Resume agent session `{ "agent_id": "...", "token": "..." }` |
4468
| `POST` | `/api/agents/unregister` | Deregister agent `{ "agent_id": "...", "token": "..." }` |
69+
| `POST` | `/api/agents/{id}/kick` | Force an agent offline: interrupt `msg_wait`, disconnect MCP sessions, backdate heartbeat. Does not require authentication. |
4570

4671
---
4772

docs/reference/tools.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
| Tool | Required Args | Description |
1212
|---|---|---|
1313
| `thread_create` | `topic`, `agent_id`, `token` | Create a new conversation thread. The creator automatically becomes the thread administrator. Optional `template` to apply defaults (system prompt, metadata). Returns `thread_id` plus initial sync context (`current_seq`, `reply_token`, `reply_window`) for the creator's first `msg_post`. |
14-
| `thread_list` || List threads. Optional `status` filter. |
14+
| `thread_list` || List threads. Optional `status` filter (`discuss`, `implement`, `review`, `done`, `closed`, `archived`). Returns envelope `{ "threads": [...], "next_cursor": "...", "has_more": bool }`. Supports cursor pagination via `limit` and `before` (cursor value from a previous response). |
1515
| `thread_get` | `thread_id` | Get full details of one thread. |
1616
| `thread_delete` | `thread_id`, `confirm=true` | Permanently delete a thread and all messages (irreversible). |
1717

@@ -63,7 +63,7 @@ See [Thread Templates guide](../guides/templates.md) for more details.
6363

6464
### Synchronization Fields
6565

66-
The MCP `msg_post` tool supports optional synchronization fields for race-condition prevention:
66+
The MCP `msg_post` tool supports synchronization fields for race-condition prevention. **For MCP callers, these fields are required** when a sync context is available (returned by `thread_create`, `msg_wait`, or `bus_connect`):
6767

6868
- `expected_last_seq`: The seq number you expect as the latest. Used for detecting unseen messages.
6969
- `reply_token`: A one-time token issued by `thread_create`, `msg_wait`, or `sync-context` to ensure consistency.
@@ -96,8 +96,8 @@ The MCP `msg_post` tool supports optional synchronization fields for race-condit
9696

9797
| Tool | Required Args | Description |
9898
|---|---|---|
99-
| `msg_react` | `message_id`, `agent_id`, `reaction` | Add a reaction to a message. Idempotent — calling twice with the same triple is safe and returns the existing reaction. |
100-
| `msg_unreact` | `message_id`, `agent_id`, `reaction` | Remove a reaction from a message. Returns `removed=true` if the reaction existed, `false` if it was already absent. |
99+
| `msg_react` | `message_id`, `reaction` | Add a reaction to a message. `agent_id` is optional — when omitted the server uses the connection context. Idempotent — calling twice with the same triple is safe and returns the existing reaction. |
100+
| `msg_unreact` | `message_id`, `reaction` | Remove a reaction from a message. `agent_id` is optional. Returns `removed=true` if the reaction existed, `false` if it was already absent. |
101101

102102
---
103103

docs/stylesheets/acb-theme.css

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
/*
2+
* AgentChatBus — MkDocs Material custom theme
3+
* Aligned with the ACB web UI (src/static/css/main.css)
4+
*
5+
* ACB palette (dark):
6+
* --bg-base: #0a0d12 (deepest background)
7+
* --bg-panel: #0f1318 (sidebar / nav)
8+
* --bg-card: #151a22 (cards)
9+
* --border: #1e2635
10+
* --accent: #3b82f6 (blue)
11+
* --text-1: #e2e8f0
12+
* --text-2: #94a3b8
13+
*
14+
* ACB palette (light):
15+
* --bg-base: #f3f6fb
16+
* --accent: #2563eb
17+
* --text-1: #0f172a
18+
*/
19+
20+
/* ─── Header ────────────────────────────────────────────────────────────────── */
21+
22+
/* Dark mode header: deep ACB background — !important needed to override Material primary color */
23+
[data-md-color-scheme="slate"] .md-header {
24+
background-color: #0a0d12 !important;
25+
border-bottom: 1px solid #1e2635;
26+
}
27+
28+
[data-md-color-scheme="slate"] .md-header__title {
29+
color: #e2e8f0 !important;
30+
}
31+
32+
/* Title gradient: exact match with ACB web UI topbar .logo */
33+
.md-header__title .md-header__topic:first-child .md-ellipsis,
34+
.md-header__title {
35+
background: linear-gradient(135deg, #3b82f6, #a855f7) !important;
36+
-webkit-background-clip: text !important;
37+
background-clip: text !important;
38+
-webkit-text-fill-color: transparent !important;
39+
font-weight: 700 !important;
40+
letter-spacing: -0.3px !important;
41+
}
42+
43+
/* Section title on scroll: solid white, no gradient */
44+
.md-header__title .md-header__topic:last-child .md-ellipsis {
45+
background: none !important;
46+
-webkit-background-clip: unset !important;
47+
background-clip: unset !important;
48+
-webkit-text-fill-color: #e2e8f0 !important;
49+
color: #e2e8f0 !important;
50+
font-weight: 400 !important;
51+
letter-spacing: normal !important;
52+
}
53+
54+
/* Light mode header: ACB dark blue */
55+
[data-md-color-scheme="default"] .md-header {
56+
background-color: #0f172a !important;
57+
border-bottom: 1px solid #1d4ed8;
58+
}
59+
60+
[data-md-color-scheme="default"] .md-header__title {
61+
color: #f8fafc !important;
62+
}
63+
64+
/* Nav tabs (the tabs bar below header) */
65+
[data-md-color-scheme="slate"] .md-tabs {
66+
background-color: #1e3a8a !important;
67+
}
68+
69+
[data-md-color-scheme="default"] .md-tabs {
70+
background-color: #2563eb !important;
71+
}
72+
73+
/* ─── Accent color ──────────────────────────────────────────────────────────── */
74+
75+
/* Dark mode: ACB blue #3b82f6 */
76+
[data-md-color-scheme="slate"] {
77+
--md-primary-fg-color: #3b82f6;
78+
--md-primary-fg-color--light: #60a5fa;
79+
--md-primary-fg-color--dark: #1d4ed8;
80+
--md-accent-fg-color: #3b82f6;
81+
}
82+
83+
/* Light mode: ACB light blue #2563eb */
84+
[data-md-color-scheme="default"] {
85+
--md-primary-fg-color: #2563eb;
86+
--md-primary-fg-color--light: #3b82f6;
87+
--md-primary-fg-color--dark: #1d4ed8;
88+
--md-accent-fg-color: #2563eb;
89+
}
90+
91+
/* ─── Navigation sidebar ────────────────────────────────────────────────────── */
92+
93+
/* Remove the default grayish background on sidebar section titles */
94+
[data-md-color-scheme="slate"] .md-nav__title {
95+
background-color: transparent !important;
96+
box-shadow: none !important;
97+
color: #94a3b8 !important;
98+
}
99+
100+
[data-md-color-scheme="slate"] .md-nav__link--active,
101+
[data-md-color-scheme="slate"] .md-nav__link:hover {
102+
color: #3b82f6;
103+
}
104+
105+
/* ─── Code blocks ───────────────────────────────────────────────────────────── */
106+
107+
/* Dark mode: override Material's default code background */
108+
[data-md-color-scheme="slate"] .highlight pre {
109+
background-color: #111620 !important;
110+
}
111+
112+
[data-md-color-scheme="slate"] :not(pre) > code {
113+
background-color: #111620 !important;
114+
}
115+
116+
/* Copy button injected by JS — same background as pre */
117+
[data-md-color-scheme="slate"] .md-clipboard {
118+
background-color: #111620 !important;
119+
box-shadow: none !important;
120+
border: none !important;
121+
color: #4b5563 !important;
122+
}
123+
124+
[data-md-color-scheme="slate"] .md-clipboard:hover {
125+
color: #94a3b8 !important;
126+
background-color: #111620 !important;
127+
}
128+
129+
/* ─── Tables ────────────────────────────────────────────────────────────────── */
130+
131+
[data-md-color-scheme="slate"] .md-typeset table:not([class]) th {
132+
background-color: #151a22;
133+
color: #e2e8f0;
134+
border-bottom: 2px solid #3b82f6;
135+
}
136+
137+
[data-md-color-scheme="slate"] .md-typeset table:not([class]) td {
138+
border-color: #1e2635;
139+
}
140+
141+
[data-md-color-scheme="slate"] .md-typeset table:not([class]) tr:hover {
142+
background-color: #1a2030;
143+
}
144+
145+
[data-md-color-scheme="default"] .md-typeset table:not([class]) th {
146+
background-color: #e8f0ff;
147+
color: #0f172a;
148+
border-bottom: 2px solid #2563eb;
149+
}
150+
151+
[data-md-color-scheme="default"] .md-typeset table:not([class]) tr:hover {
152+
background-color: #edf3ff;
153+
}
154+
155+
/* ─── Admonition blocks ─────────────────────────────────────────────────────── */
156+
157+
[data-md-color-scheme="slate"] .md-typeset .admonition {
158+
border-color: #1e2635;
159+
background-color: #151a22;
160+
}
161+
162+
/* ─── Footer ────────────────────────────────────────────────────────────────── */
163+
164+
[data-md-color-scheme="slate"] .md-footer {
165+
background-color: #0a0d12;
166+
border-top: 1px solid #1e2635;
167+
}
168+
169+
[data-md-color-scheme="default"] .md-footer {
170+
background-color: #1e3a8a;
171+
}

mkdocs.yml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,20 @@ theme:
1414
- content.code.copy
1515
- content.tabs.link
1616
palette:
17-
- scheme: default
17+
- media: "(prefers-color-scheme: light)"
18+
scheme: default
1819
toggle:
1920
icon: material/brightness-7
2021
name: Switch to dark mode
21-
- scheme: slate
22+
- media: "(prefers-color-scheme: dark)"
23+
scheme: slate
2224
toggle:
2325
icon: material/brightness-4
2426
name: Switch to light mode
2527

28+
extra_css:
29+
- stylesheets/acb-theme.css
30+
2631
markdown_extensions:
2732
- admonition
2833
- pymdownx.superfences

0 commit comments

Comments
 (0)