Skip to content

Guided tour

FabrCore 2.0 · Release and package availability

These guides track the current 2.0 source. Stable 2.0.0 publication is pending; package commands show the release target. Until it is published, follow the source quick start or use a matching available prerelease set. Release migration · Runtime modes

MODULE 11 · LESSON 11.2

Publish a general-purpose A2A service

Publish a general A2A service with explicit ownership and task lifetime.

Lesson 66 of 86 · FabrCore 2.0

Overview

A2A supports agent cards, messages, tasks, streaming and cancellation. Standalone uses per-process task storage; SQL mode persists snapshots with ownership and execution leases. SQL snapshots are not a replayable SSE event log, and interrupted execution fails rather than automatically replaying effects.

A task has an observable lifecycle

A2A exposes more than a text reply: callers can discover an agent, submit work and inspect task state, with supported streaming/cancellation behavior. Keep task ownership tied to authenticated caller mapping. The card describes the installed capabilities; it should not imply that a disabled extension is available.

Persistence does not imply replayable execution

Standalone task storage is process-local. SQL can retain task snapshots and ownership/leases, but that is not a durable replay log for every SSE event. Interrupted execution is reported rather than automatically repeating uncertain external effects. A client reconnect should inspect authoritative task status instead of assuming every missed event can be replayed.

Publish an A2A task surface

  1. Configure explicit routes/discovery, primary agent, exclusions and principal mapping. Keep card metadata useful and intentional.
  2. Choose retention and execution timeout, then test task lookup/cancel through a second host in SQL mode. Preserve caller ownership checks.
  3. Customize the principal resolver, card factory, task store or provisioner only where the default contract does not meet your application need.
Minimum configuration · reference snippet
{
  "A2A": {
    "Enabled": true,
    "PublicBaseUrl": "https://agents.contoso.com",
    "Discovery": { "AgentTypes": "Described" },
    "Authentication": {
      "Mode": "ApiKey",
      "ApiKey": { "Keys": [ { "Name": "copilot-studio", "Value": "a-long-random-secret" } ] }
    }
  }
}
Extension points
Interface Replace to
IA2APrincipalResolver Map callers to principals your own way — ValueTask<string?> ResolvePrincipalHandleAsync(HttpContext, A2AExposedAgent, string contextId, CancellationToken), so a directory lookup is a plain await
IA2ATaskStore Persist tasks durably or share them across instances
IA2AAgentCardFactory Take full control of card contents
IA2AAgentProvisioner Change how agent instances are resolved and provisioned

Observe a task and interrupt a second one

  1. Submit a bounded task and inspect its progression and final result through the advertised A2A interface. Confirm another unauthorized caller cannot read its owned result.
  2. Test cancellation while work is still pending and inspect the resulting task status and actual business effect. Stopping a client's wait is not automatically server cancellation.
  3. With the intended persistence mode, restart during a controlled task and inspect the reported recovery/failure state. Do not expect automatic replay of a mutation or every prior streaming event.

The exercise establishes lifecycle, ownership and recovery semantics for this endpoint. Durable snapshots and durable execution are different guarantees.

If the result is different

An anonymous catalog does not imply anonymous execution. Do not claim SSE replay merely because terminal task snapshots are durable.

Go deeper

Explore the related documentation.