docs(a2a): A2A server guide, architecture, Telegram and Docker notes
Add docs/a2a.md (concepts, file formats, endpoints, sessions, task lifecycle, configuration, security notes, curl examples) describing what src/Volcanic.AgenticCore.A2A.Server actually does. Add an A2A project paragraph to architecture.md, an "A2A" section to telegram-bot.md (/a2a, notify_owner, isolated sessions, port 8080), A2A_ENABLED/A2A_PUBLIC_URL and the aspnet image to docker.md, and project-map/test-command updates to CLAUDE.md. Mark the A2A server design spec implemented and record the deviations found while building it (A2AHostOptions, synchronous IA2ACallerDirectory.Find, generic WorkspaceCallerDirectory, per-status push payload, split file-part error handling, the outbound guarded handler, the per-caller server/router architecture, the restart grace period, the owner= log field, the aspnet image, and the actual push retry schedule). Note the aspnet image in the docker-deployment spec too, without rewriting its historical decisions.
This commit is contained in:
@@ -65,6 +65,9 @@ settings use the `GoogleCalendar` section, the scheduler the `Scheduler` section
|
||||
| `PLAYWRIGHT_ENABLED` / `Mcp:Playwright:Enabled` | `false` | Browser tools through `@playwright/mcp` ([mcp.md](mcp.md)) |
|
||||
| `PLAYWRIGHT_HEADLESS`, `PLAYWRIGHT_BROWSER`, `PLAYWRIGHT_EXTRA_ARGS`, `PLAYWRIGHT_COMMAND` | `true`, `chromium`, —, `npx` | See [mcp.md](mcp.md#the-playwright-preset) |
|
||||
| `Mcp:Servers:<name>` | — | Other stdio MCP servers ([mcp.md](mcp.md#configuration)) |
|
||||
| `A2A__Enabled` / `A2A:Enabled` | `false` | Serve other agents over A2A (see [A2A](#a2a) and [a2a.md](a2a.md)). Opens Kestrel on port 8080 |
|
||||
| `A2A__PublicUrl` / `A2A:PublicUrl` | — | External base URL for the agent card and push webhooks, e.g. `https://bot.example.com`. Required for push to work; see [docker.md](docker.md) |
|
||||
| `A2A__*` | see [a2a.md](a2a.md#configuration) | `MaxHops`, `SessionIdleTimeout`, `MaxFileBytes`, `AllowPrivatePushUrls`, `Card:Name`, `Card:Description` |
|
||||
|
||||
Sessions are stored as usual under `~/.volcanic/agent/sessions/telegram-<chatId>/`; after a restart each chat resumes
|
||||
its most recent conversation. Each chat's time zone is kept in `<agent dir>/telegram/chat-settings.json`, so it
|
||||
@@ -118,6 +121,7 @@ started a chat with the bot, Telegram refuses the message; the bot logs that and
|
||||
| `/calendar_connect` | Connect this chat's Google Calendar (link and code; the bot confirms when you approve) |
|
||||
| `/calendar_status` | The connected account and time zone, or the pending code |
|
||||
| `/calendar_disconnect` | Revoke and delete this chat's calendar token, or cancel a pending connect |
|
||||
| `/a2a` | This chat's A2A callers and recent tasks (see [A2A](#a2a)) |
|
||||
|
||||
Any other `/command` is passed to the session, so extension commands such as `/claude-code-doctor` and
|
||||
`/claude-code-login` work. `/mcp` lists the MCP servers (see [mcp.md](mcp.md#mcp)).
|
||||
@@ -284,6 +288,26 @@ chat's account, so nobody sees another chat's calendar through the agent. The bo
|
||||
sending the link and code and confirms in the chat once access is approved. Setup of the Google Cloud app, token
|
||||
storage and time zones are in [google-calendar.md](google-calendar.md).
|
||||
|
||||
### A2A
|
||||
|
||||
With `A2A__Enabled=true` the bot also serves [A2A](a2a.md): other agents can call it over HTTP once given a key.
|
||||
It opens Kestrel on port 8080 (Coolify needs a domain pointed at that port — see [docker.md](docker.md)) and logs
|
||||
`A2A: listening on ...`. With it left off (the default) no port is opened at all. If the port is already taken,
|
||||
the bot logs a critical line and exits with code 3 instead of coming up half-working.
|
||||
|
||||
Callers live only in allowed chats' workspaces: each chat's own `.volcanic/a2a/callers.json` and
|
||||
`.volcanic/a2a/tasks/` (see [a2a.md](a2a.md#files)). A caller's session is isolated from the chat's own
|
||||
conversation — same workspace, same `AGENTS.md`/`CLAUDE.md`, `PERSONA.md` and `MEMORY.md`, separate history — and
|
||||
opens with that chat's current time zone and `Telegram:Model`; a later `/timezone` only reaches a caller's session
|
||||
once it's been idle long enough to be evicted and reopened (`SessionIdleTimeout`, 30 minutes by default).
|
||||
|
||||
`notify_owner` delivers as `🤖 A2A · <caller>: <text>` in the owner's chat, through the same channel as everything
|
||||
else the bot sends there — including during `/impersonate`, when it reaches the admin instead, like any other
|
||||
output to that chat.
|
||||
|
||||
`/a2a` shows this chat's callers (name, mode, and the key's last four characters — only once a key is at least 12
|
||||
characters long) and its ten most recent tasks with their caller, state and age.
|
||||
|
||||
## Security
|
||||
|
||||
The agent has the built-in tools, including `bash`, and runs them as the bot's OS user. Only allow-listed user ids
|
||||
|
||||
Reference in New Issue
Block a user