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:
EugeneTes
2026-10-07 14:20:19 +00:00
parent f87a8dd8c1
commit d542fcfe42
7 changed files with 291 additions and 8 deletions

View File

@@ -23,8 +23,9 @@ deliberately match them.
```bash
dotnet build # whole solution (VolcanicAgenticCore.slnx)
dotnet test # all three test projects; no test calls a paid API
dotnet test # all four test projects; no test calls a paid API
dotnet test tests/Volcanic.AgenticCore.Tests # one project
dotnet test tests/Volcanic.AgenticCore.A2A.Server.Tests # A2A server only
dotnet test --filter "FullyQualifiedName~AgentLoopTests" # one class
dotnet test --filter "FullyQualifiedName~AgentLoopTests.SomeTest" # one test
@@ -53,6 +54,10 @@ Read `docs/architecture.md` first. Key points:
`SystemPromptBuilder`, `Compactor`, `ProcessSpawnPolicy`). Slices talk only through those entry types and the Abstractions.
`Hosting/` has `AddAgenticCore(...)` and `AgenticCoreOptions`; `Testing/FauxProvider.cs` is the scripted provider
that tests and `--faux` use.
- **`src/Volcanic.AgenticCore.A2A.Server`** exposes assistants over A2A (`docs/a2a.md`) on the official SDK, built
directly on the core (`IAgentSessionFactory`), not the extension API: one `VolcanicA2AServer` per authenticated
caller (`A2AServerCache`), routed by `A2ARequestRouter`, one `AgentSession` per `(caller, contextId)`
(`A2ASessionPool`). `samples/Volcanic.AgenticCore.Sample.A2A` mounts it over one workspace for local use.
- **One conversation = one `AgentSession`**, built by `IAgentSessionFactory.CreateAsync`. Extensions are
**instantiated per session** and each session has its own `ModelRegistry`, so provider registrations and extension
fields are per conversation. Process-wide state has to be explicit (e.g. `ClaudeLoginCoordinator.Shared`).
@@ -128,6 +133,11 @@ by `TriggerDispatcher` and delivered as follow-up prompts (`TelegramTriggerDeliv
`ADMIN_USER_ID` (`Telegram:AdminUserId`) may `/impersonate <user_id>` (`Chats/Impersonation`, in memory, `0` stops): the
router then handles the admin's updates as the target's, and the target chat's renderer delivers to the admin's chat
(`ChatRenderer.DeliveryChatId`); the target's own updates get `Impersonation.BlockedNotice` instead. Answers go out complete, not streamed (`Rendering/`). Tests drive the host through `Support/FakeBotClient` and `ChatHost`.
`A2A/` (on only with `A2A__Enabled=true`) mounts `Volcanic.AgenticCore.A2A.Server` on Kestrel, port 8080:
`TelegramA2ASetup` wires a `WorkspaceCallerDirectory` over every allowed chat's workspace and a
`TelegramOwnerNotifier` (`notify_owner` → the owner's chat, or the admin's during `/impersonate`); off, `NoHttpServer`
replaces Kestrel so no port opens. `/a2a` lists a chat's callers and recent tasks (`docs/a2a.md`,
`docs/telegram-bot.md#a2a`).
## Deployment