Files
classic-models-agent-flows/adapter
Stéphane Tailland 6eb77d862f Stop reporting a silent workflow as a completed task
n8n answers 200 with an empty body when a node throws before the Respond node
runs — a refused token exchange is the common way in. The adapter read that as
a completed task carrying "(the workflow returned nothing)", which tells the
caller the task succeeded: the one thing certainly false.

Off-contract replies get the same treatment. They are still returned raw so
drift is visible, but a body that is not the contract cannot be read as
agreement.

Also removes a backlog section that described the events as unbuilt and said an
event should carry sub and azp from the caller's token — the design the user
overruled. Anyone reading it would have built the wrong consumer.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-31 14:39:03 +02:00
..

a2a-n8n-adapter

An A2A facade in front of an n8n workflow. One image, one instance per agent, configured entirely by environment.

The repo's notes proposed serving this from the gateway instead — a static Agent Card and a route to the webhook, no new component. That does not reach. A2A is not request/response: a caller gets a Task with an id, a context and a state that can be input-required or failed, and none of that can be synthesised from a webhook's single reply by a proxy. Templating the whole lifecycle in gateway configuration is an adapter, written in the wrong language.

So: the alternative those same notes anticipated, written once for both agents.

It owns the protocol and nothing else

It holds no Keycloak client and no credentials. It forwards the end user's token to the workflow in X-Subject-Token — a header rather than the body, so a workflow that logs its input does not log the token with it — and the workflow exchanges it, because the component that can mint tokens should be the one that uses them.

The workflow answers {"answer": "...", "escalate": false}. Anything else is returned as raw text rather than guessed at: a workflow that has drifted from the contract should look wrong, not be quietly reinterpreted.

escalate: true fails the task rather than completing it. An autonomous agent that meets a rule needing approval must hand it back, never decide, and a completed task is the wrong shape for "a human has to look at this".

Configuration

ADAPTER_AGENT_NAME approvisionnement
ADAPTER_AGENT_DESCRIPTION what the card says it is
ADAPTER_SKILL_ID check_availability
ADAPTER_SKILL_NAME, _DESCRIPTION, _EXAMPLES the card's one skill; examples are newline-separated
ADAPTER_WEBHOOK_URL the workflow's production webhook
ADAPTER_PUBLIC_URL what callers dial — the Service DNS name, not the bind address
ADAPTER_CA_BUNDLE the lab CA, so TLS is verified rather than disabled

One skill per instance, deliberately. A second one is a card change, which is the moment to ask whether the agent has quietly become a data proxy.