Commit Graph

3 Commits

Author SHA1 Message Date
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
Stéphane Tailland 666735b0eb feat: deploy the Approvisionnement facade
The adapter runs in the agents namespace with the other agents, not with n8n:
what it is, is an agent, and the workflow behind it is an implementation detail
its callers never see.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-29 13:25:35 +02:00
Stéphane Tailland d9c376facf feat: an A2A facade for the n8n agents, and Approvisionnement's first workflow
The adapter is written once and parameterised, so both n8n agents get the same
A2A surface and differ only in the workflow behind the webhook. It owns the
protocol and nothing else: no Keycloak client, no credentials, and the end
user's token forwarded in a header so a workflow that logs its input does not
log the token with it. escalate: true fails the task rather than completing it,
because an autonomous agent meeting a rule that needs approval must hand it
back, not decide.

Serving this from the gateway was the repo's stated preference and does not
reach: A2A returns a Task with a lifecycle, and a proxy cannot synthesise that
from a webhook's single reply.

The check_availability workflow does the token exchange itself, using the
agent's client secret from the pod environment so the committed JSON holds no
secret, then talks MCP in two calls — initialize to obtain the session id from
a response header, then tools/call. It reads the product code with a regex
rather than a model: this agent's critical path is rules, and a question naming
no product escalates instead of being guessed at.

MCP rather than the REST route, which would have been one HTTP call instead of
two: the per-tool ACL by consumer group lives on the MCP route only. Going
through REST would give an autonomous agent broader access than a conversational
one, which is exactly backwards.

Status: the adapter is tested (13 tests) and the identity chain is verified by
hand, but the workflow fails at its token exchange and is not yet working —
see the note in workflows/.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-29 13:07:02 +02:00