Agents A2A
Publiez des workflows Scrydon en tant qu'agents A2A 1.0, invoquez-les depuis Cortex ou un autre client A2A et appelez des agents externes depuis un workflow.
Scrydon prend en charge le protocole Agent2Agent (A2A) dans les deux sens :
- Publier un workflow en tant qu'agent A2A autonome.
- Utiliser le bloc A2A pour découvrir et appeler un agent externe.
Les interfaces A2A 1.0 prises en charge sont JSON-RPC et HTTP+JSON, y compris le streaming via SSE. Une compatibilité A2A 0.3 facultative est disponible pour les clients et agents existants. Scrydon n'annonce ni ne revendique la prise en charge de l'interface gRPC.
Publier un workflow en tant qu'agent
Chaque publication de workflow correspond à un agent A2A adressable indépendamment. Une organisation peut publier autant de workflows qu'elle le souhaite ; chacun reçoit son propre identifiant d'agent stable, sa propre Agent Card, son espace de noms de tâches, sa visibilité et sa version de déploiement épinglée.
Le panneau Déploiements contient une seule section Points de terminaison de l'agent par workflow — et non une par environnement. Un champ Environnement servi dans la configuration A2A permet de choisir l'environnement dont le déploiement l'agent exécutera (par défaut, l'environnement déployé le plus élevé ; le brouillon de développement peut être sélectionné explicitement). Les agents publiés apparaissent sous forme de lignes dans Points de terminaison de l'agent : Agent A2A · <visibilité> · sert <environnement>. Si aucun agent n'est encore publié, une ligne discrète avec un bouton Publier est affichée.
- Ouvrez le workflow dans l'éditeur. Le workflow doit contenir un bloc Response activé.
- Cliquez sur Deploy dans la barre d'outils de l'éditeur (le bouton affiche Versions une fois tout déployé) pour ouvrir le panneau Déploiements. Le panneau affiche une progression verticale du pipeline — une ligne par environnement avec version, date, auteur et un bouton de promotion.
- Si aucun déploiement n'existe encore pour l'environnement cible, cliquez sur le bouton Promote sur la ligne de l'environnement concerné.
- Faites défiler jusqu'à la section Points de terminaison de l'agent en bas du panneau et cliquez sur Publier (ou cliquez sur une ligne d'agent A2A existante pour la reconfigurer).
- Dans la configuration A2A, choisissez le champ Environnement servi, configurez l'Agent Card de base (et, si nécessaire, une Agent Card étendue), et choisissez l'authentification par clé API et/ou jeton bearer.
- Conservez la visibilité Privé par défaut, ou rendez explicitement l'agent public et découvrable.
- Enregistrez, puis copiez l'URL de l'Agent Card ou du point de terminaison de protocole affichée dans la vue.
La publication épingle toujours un instantané de déploiement immuable. Modifier le canevas du workflow ne change pas l'agent en cours d'exécution. Promouvez une version plus récente et mettez à jour le déploiement épinglé dans la configuration A2A lorsque vous souhaitez republier.
Un agent publié épingle un déploiement : son workflow ne peut donc pas être retiré. Toute tentative de retrait, que ce soit avec l'action Retirer du Monitor ou avec DELETE /api/v1/workflows/{id}/deploy, renvoie 409 avec le code WORKFLOW_PUBLISHED et indique l'agent en cause. Rien n'est modifié : le workflow reste déployé et ses webhooks continuent de recevoir les événements. Passer la visibilité de l'agent à Désactivé le met hors service, mais le déploiement reste épinglé et le retrait toujours refusé.
Icônes d'agent
Scrydon génère automatiquement une icône monogramme unique pour chaque agent publié. Cette icône apparaît dans l'Agent Card renvoyée aux clients A2A externes. Des URL d'icônes personnalisées peuvent toujours être définies par programmation via l'API de publication (basicCard.iconUrl), mais ne font plus partie de l'interface utilisateur.
Les environnements d'espace de travail sont définis par les utilisateurs. Leur nom et leur caractère en lecture seule ne déterminent pas la visibilité A2A : un workflow situé dans n'importe quel environnement modifiable ou en lecture seule peut être désactivé, privé ou public. Les identifiants restent liés à l'environnement exact de l'espace de travail de la publication.
Visibilité
| Visibilité | Agent Card | Catalogue public | Opérations du protocole |
|---|---|---|---|
| Désactivé | Indisponible | Masqué | Indisponibles |
| Privé (par défaut) | Authentification requise | Masqué | Authentification et autorisation du workflow requises |
| Public | Carte de base publique | Répertorié | Authentification et autorisation du workflow toujours requises |
La visibilité publique rend la découverte publique ; elle ne rend pas publiques l'exécution du workflow ni les données des tâches. Une Agent Card étendue authentifiée n'est jamais renvoyée par la découverte publique.
Le catalogue public de l'organisation est paginé à l'adresse suivante :
GET /api/a2a/catalog/{organizationId}?pageSize=25&pageToken=...Le panneau A2A authentifié répertorie également les publications de l'organisation dans tous les environnements, y compris les agents désactivés et privés.
Agent Cards et points de terminaison
La vue de configuration A2A fournit les URL suivantes :
| Point de terminaison | Utilité |
|---|---|
/api/a2a/agents/{agentId}/.well-known/agent-card.json | Découverte de l'Agent Card de base |
/api/a2a/agents/{agentId} | A2A 1.0 JSON-RPC |
/api/a2a/agents/{agentId}/... | Ressources et méthodes A2A 1.0 HTTP+JSON |
/api/a2a/jwks | Clés publiques pour vérifier la signature de l'Agent Card |
La carte de base décrit le nom, la version, le fournisseur, la documentation, les types de médias pris en charge, les compétences, les mécanismes de sécurité, les interfaces et les capacités de l'agent. Activez la carte étendue lorsque les appelants authentifiés ont besoin d'une description plus riche que celle qui doit être exposée par la découverte publique.
Les cartes sont signées avec ES256 et incluent l'URL de leur ensemble JWK. Les cartes publiques prennent en charge ETag, Last-Modified et la revalidation du cache. Les cartes privées utilisent un cache privé avec no-store.
Authentification et isolation des tâches
Activez au moins un mécanisme d'authentification pour la publication :
- Clé API : envoyez la clé d'espace de travail liée à l'environnement dans
X-API-Key. - Bearer : envoyez un jeton OAuth/OIDC dans
Authorization: Bearer …. Les opérations de lecture nécessitentworkflows:read; les mutations et l'exécution nécessitentworkflows:write.
Chaque tâche est limitée à la publication et au principal authentifié. Un autre principal, une autre organisation, un autre espace de travail ou un autre environnement reçoit la même réponse « introuvable » que pour une tâche inexistante. Les identifiants de tâches ne peuvent donc pas servir à énumérer le travail d'un autre appelant.
Appeler l'agent
Chaque requête de protocole doit envoyer la version annoncée par l'interface sélectionnée :
curl -X POST 'https://scrydon.example/api/a2a/agents/AGENT_ID' \
-H 'A2A-Version: 1.0' \
-H 'Content-Type: application/json' \
-H 'X-API-Key: YOUR_WORKSPACE_KEY' \
-d '{
"jsonrpc": "2.0",
"id": "request-1",
"method": "SendMessage",
"params": {
"message": {
"role": "ROLE_USER",
"messageId": "message-1",
"parts": [{ "text": "Create the quarterly summary", "mediaType": "text/plain" }]
}
}
}'L'appel HTTP+JSON équivalent utilise la même URL de base du protocole :
curl -X POST 'https://scrydon.example/api/a2a/agents/AGENT_ID/message:send' \
-H 'A2A-Version: 1.0' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer YOUR_TOKEN' \
-d '{
"message": {
"role": "ROLE_USER",
"messageId": "message-1",
"parts": [{ "text": "Create the quarterly summary", "mediaType": "text/plain" }]
}
}'SendMessage renvoie soit une tâche, soit un message direct de l'agent. Pour une tâche, interrogez GET /tasks/{taskId}, abonnez-vous avec POST /tasks/{taskId}:subscribe ou utilisez une configuration de notification push.
Prouver l'interopérabilité avec le SDK JavaScript officiel
Il s'agit du test indépendant le plus probant pour une publication privée : il découvre l'Agent Card, négocie une interface annoncée et envoie un message A2A 1.0 sans utiliser de cookie de session Scrydon.
- Créez une clé API dans le même environnement d'espace de travail que la publication.
- Copiez l'URL du protocole depuis la vue de configuration A2A.
- Dans un répertoire vide, installez la version stable du SDK officiel :
bun add @a2a-js/sdk@1.0.0- Enregistrez le code suivant dans
a2a-proof.mjs:
import { randomUUID } from "node:crypto";
import {
Message,
Role,
SendMessageConfiguration,
Task,
} from "@a2a-js/sdk";
import {
ClientFactory,
ClientFactoryOptions,
DefaultAgentCardResolver,
JsonRpcTransportFactory,
RestTransportFactory,
} from "@a2a-js/sdk/client";
const agentUrl = process.env.A2A_AGENT_URL;
const apiKey = process.env.A2A_API_KEY;
if (!agentUrl || !apiKey) {
throw new Error("Set A2A_AGENT_URL and A2A_API_KEY");
}
const authenticatedFetch = async (input, init) => {
const original =
input instanceof Request ? new Request(input, init) : new Request(input, init);
const headers = new Headers(original.headers);
headers.set("X-API-Key", apiKey);
return fetch(new Request(original, { headers, redirect: "error" }));
};
const factory = new ClientFactory(
ClientFactoryOptions.createFrom(ClientFactoryOptions.default, {
cardResolver: new DefaultAgentCardResolver({
fetchImpl: authenticatedFetch,
}),
transports: [
new JsonRpcTransportFactory({ fetchImpl: authenticatedFetch }),
new RestTransportFactory({ fetchImpl: authenticatedFetch }),
],
}),
);
const client = await factory.createFromUrl(`${agentUrl.replace(/\/$/, "")}/`);
const card = await client.getAgentCard();
console.log(
"Negotiated",
client.protocolVersion,
card.supportedInterfaces.map((item) => item.protocolBinding),
);
const result = await client.sendMessage({
tenant: "",
message: Message.fromJSON({
messageId: randomUUID(),
role: Role.ROLE_USER,
parts: [
{
text: "Run the A2A interoperability proof",
mediaType: "text/plain",
},
],
}),
configuration: SendMessageConfiguration.fromJSON({
acceptedOutputModes: ["application/json", "text/plain"],
returnImmediately: false,
}),
});
console.dir(
"id" in result ? Task.toJSON(result) : Message.toJSON(result),
{ depth: null },
);- Exécutez-le :
A2A_AGENT_URL='https://scrydon.example/api/a2a/agents/AGENT_ID' \
A2A_API_KEY='YOUR_WORKSPACE_KEY' \
bun run a2a-proof.mjsLa première ligne doit indiquer le protocole 1.0 et les interfaces JSONRPC et HTTP+JSON annoncées. La valeur finale est soit une tâche A2A, soit un message direct de l'agent. Un workflow bloquant renvoie normalement une tâche dont l'état final est TASK_STATE_COMPLETED.
L'A2A Inspector officiel est utile pour afficher une Agent Card, effectuer une validation de base et examiner le JSON-RPC brut. Sa prise en charge de l'authentification n'est pas terminée ; il ne peut donc pas, à lui seul, prouver une exécution Scrydon authentifiée. Utilisez l'exemple du SDK officiel ci-dessus ou Cortex pour l'invocation de bout en bout.
Invoquer des agents publiés depuis Cortex
Cortex peut découvrir et appeler directement les agents publiés par Scrydon. Il utilise l'espace de travail actif comme limite de découverte et l'environnement d'espace de travail actif comme limite d'appel ; il n'accepte pas d'URL A2A externes arbitraires.
- Publiez un ou plusieurs workflows en tant qu'agents A2A Privés ou Publics. Les agents Désactivés sont exclus.
- Dans Cortex, sélectionnez le même espace de travail. Les agents publiés pour n'importe quel environnement de cet espace de travail sont visibles.
- Demandez à Cortex de trouver l'agent par son nom, sa description, sa compétence ou son étiquette et indiquez-lui l'action à effectuer. Par exemple :
Find the A2A agent named "Quarterly reporting" and ask it to create the Q2 summary.- Cortex exécute d'abord
a2a_agent_search. Les agents appelables (servant l'environnement actif) apparaissent dans les résultats principaux. Les agents publiés pour d'autres environnements sont listés séparément souselsewhere; Cortex suggérera de changer d'environnement actif pour les atteindre. - Approuvez la confirmation
a2a_agent_call. L'appel exécute le déploiement épinglé du workflow. - Consultez la tâche ou le message A2A renvoyé dans la conversation.
Cortex découvre les publications Privées et Publiques dans tous les environnements de l'espace de travail actif, car l'utilisateur connecté y est déjà autorisé. Seuls les agents dont la publication sert l'environnement d'espace de travail actif sont appelables ; les agents servant un environnement différent sont signalés mais ne peuvent pas être appelés tant que l'utilisateur n'a pas basculé vers cet environnement. Cortex revalide l'identifiant d'agent sélectionné immédiatement avant chaque appel.
Opérations serveur prises en charge
| Opération | Méthode JSON-RPC | HTTP+JSON |
|---|---|---|
| Envoyer un message | SendMessage | POST /message:send |
| Envoyer et diffuser | SendStreamingMessage | POST /message:stream |
| Obtenir une tâche | GetTask | GET /tasks/{id} |
| Répertorier les tâches | ListTasks | GET /tasks |
| Annuler une tâche | CancelTask | POST /tasks/{id}:cancel |
| S'abonner à une tâche | SubscribeToTask | POST /tasks/{id}:subscribe |
| Créer une configuration push | CreateTaskPushNotificationConfig | POST /tasks/{id}/pushNotificationConfigs |
| Obtenir une configuration push | GetTaskPushNotificationConfig | GET /tasks/{id}/pushNotificationConfigs/{configId} |
| Répertorier les configurations push | ListTaskPushNotificationConfigs | GET /tasks/{id}/pushNotificationConfigs |
| Supprimer une configuration push | DeleteTaskPushNotificationConfig | DELETE /tasks/{id}/pushNotificationConfigs/{configId} |
| Obtenir la carte étendue | GetExtendedAgentCard | GET /extendedAgentCard |
Les deux interfaces utilisent les états de tâche, la pagination, le contrôle de l'historique, la continuation des messages, les artefacts, les paramètres de service, les extensions, les erreurs canoniques et les détails google.rpc.ErrorInfo d'A2A 1.0. Le streaming utilise text/event-stream et conserve l'enveloppe de réponse de l'interface.
Lorsque la compatibilité 0.3 est activée, l'Agent Card annonce également des interfaces JSON-RPC et HTTP+JSON compatibles et traduit les anciennes méthodes et charges utiles à l'aide du SDK officiel.
Entrée et sortie du workflow
Le workflow reçoit la requête normalisée sous a2a :
{
"a2a": {
"message": { "messageId": "message-1", "role": "ROLE_USER", "parts": [] },
"configuration": {},
"metadata": {}
}
}Le bloc Response sélectionné devient la réponse de l'agent :
- Une chaîne devient un message d'agent
text/plain. - Toute autre valeur JSON devient une partie de données
application/jsonlorsque l'appelant l'accepte. - Pour un contrôle complet, renvoyez
{ "a2a": { "message": ..., "artifacts": [...] } }comme données de la réponse. - Un statut Response supérieur ou égal à 400 fait échouer la tâche sans exposer la sortie interne des nœuds.
Les pauses du workflow et les étapes de révision humaine sont projetées vers TASK_STATE_INPUT_REQUIRED. Continuez la même tâche en envoyant un autre message avec son taskId et le contextId correspondant. Les tâches terminales refusent les messages et abonnements ultérieurs avec l'erreur A2A canonique.
Les messages entrants et la sortie projetée passent par la politique DLP de l'organisation. L'exécution, l'annulation, les modifications de publication et de configuration push, ainsi que la livraison en lettre morte sont journalisées à des fins d'audit, sans corps de message ni identifiants.
Limites des charges utiles
| Limite | Valeur |
|---|---|
| Requête ou réponse sérialisée | 6 Mio |
| Parties par message ou artefact | 32 |
| Nombre total de parties dans la réponse | 128 |
| Artefacts par réponse | 32 |
| Texte ou octets bruts par partie | 1 Mio |
| Octets bruts par requête ou réponse | 5 Mio |
| Stockage de fichiers bruts par tâche | 20 Mio |
| Objet de métadonnées | 64 Kio, profondeur d'imbrication maximale de 12 |
| Historique renvoyé | 0 à 100 messages |
Les parties de fichiers bruts sont transférées vers le stockage de fichiers d'exécution avant la planification durable et ne sont réhydratées que dans la portée autorisée de la tâche.
Notifications push
Les configurations push prennent en charge un jeton de rappel ou un mécanisme d'authentification avec ses identifiants. En production, les rappels doivent utiliser HTTPS. Scrydon résout et épingle les cibles DNS publiques, bloque les destinations privées, loopback, link-local et de métadonnées cloud, puis revalide les cibles de livraison afin d'empêcher le rebinding DNS.
La livraison conserve l'ordre par configuration, réessaie trois fois les échecs récupérables avec temporisation, puis marque la configuration comme lettre morte. Les secrets de rappel sont chiffrés au repos et n'apparaissent jamais dans les journaux d'audit.
Appeler des agents A2A externes
Ajoutez un bloc A2A à un workflow et choisissez l'une des mêmes opérations de découverte, de messagerie, de streaming, de tâche, d'abonnement, de push ou de carte étendue. Saisissez l'URL de base ou de protocole de l'agent. Scrydon cherche d'abord l'Agent Card à {URL de l'agent}/.well-known/agent-card.json, puis à l'emplacement A2A 1.0 à la racine de l'hôte, puis aux emplacements 0.3 comme solutions de compatibilité. Le premier emplacement permet à un même hôte de servir plusieurs agents, comme le fait Scrydon.
L'authentification sortante prend en charge :
- les clés API dans un en-tête, un paramètre de requête ou un cookie ;
- HTTP Basic ;
- les jetons bearer ;
- les jetons d'accès OAuth 2.0 ;
- les jetons d'accès OpenID Connect.
Vous pouvez également exiger une Agent Card signée, définir un délai d'expiration de 100 ms à 300 s et envoyer des paramètres de service non réservés ainsi que des URI d'extension A2A. Le TLS mutuel est détecté et refusé avec une erreur d'authentification non prise en charge explicite.
En production, les appels sortants exigent HTTPS, sauf si l'opérateur active explicitement A2A_ALLOW_INSECURE_HTTP=true. Chaque URL de découverte, d'interface, de redirection et d'ensemble JWK est épinglée au DNS et contrôlée par rapport aux adresses privées et aux hôtes de métadonnées. Les identifiants et en-têtes de service personnalisés sont supprimés lors des redirections vers une autre origine.
Sorties des opérations
Chaque opération renvoie l'objet de résultat A2A lui-même ; référencez ses champs par chemin dans les blocs suivants :
| Opération | Renvoie | Champs utiles |
|---|---|---|
| Send Message, Get Task, Cancel Task | Une tâche, ou un message direct de l'agent pour Send Message | id, contextId, status.state, status.message, artifacts, history ; pour un message messageId, role, parts |
| Send Streaming Message, Subscribe to Task | Le flux collecté | events, truncated |
| List Tasks | Une page de tâches | tasks, nextPageToken, pageSize, totalSize |
| Get Agent Card, Get Extended Agent Card | L'Agent Card | name, description, version, capabilities, skills, supportedInterfaces, securitySchemes |
| Create ou Get Push Notification Config | La configuration | id, taskId, url, token, authentication |
| List Push Notification Configs | Une page de configurations | configs, nextPageToken |
| Delete Push Notification Config | Un accusé de réception | success, taskId, pushNotificationConfigId |
L'état d'une tâche se trouve dans status.state, par exemple TASK_STATE_COMPLETED. Une opération qui échoue, comme Get Task pour une tâche inconnue, fait échouer le bloc avec l'erreur de l'agent.
Tester le bloc A2A
Chaque agent de workflow publié par Scrydon est un serveur A2A ; l'agent le plus simple à cibler avec le bloc est donc l'un des vôtres :
-
Publiez un workflow en tant qu'agent (voir Publier un workflow en tant qu'agent) avec l'authentification par clé API.
-
Créez une clé API dans le même environnement d'espace de travail que la publication.
-
Copiez l'URL de protocole depuis la vue de configuration A2A. Elle a cette forme :
https://YOUR_SCRYDON_HOST/api/a2a/agents/AGENT_IDL'Agent Card se trouve à
https://YOUR_SCRYDON_HOST/api/a2a/agents/AGENT_ID/.well-known/agent-card.json. Récupérez-la avec la clé pour vérifier que l'agent répond :bashcurl 'https://YOUR_SCRYDON_HOST/api/a2a/agents/AGENT_ID/.well-known/agent-card.json' \ -H 'X-API-Key: YOUR_WORKSPACE_KEY' -
Dans un second workflow, ajoutez un bloc A2A, choisissez Get Agent Card, saisissez l'URL de protocole comme URL de l'agent et la clé comme clé API, puis exécutez-le. Essayez ensuite Send Message, puis Get Task ou Subscribe to Task avec l'
idrenvoyé.
L'URL de l'agent doit être joignable à une adresse publique. Le bloc refuse volontairement localhost et les adresses de bouclage, de réseau privé, link-local et de métadonnées cloud, aussi bien pour l'URL saisie que pour chaque adresse vers laquelle elle se résout. C'est la même protection contre la falsification de requêtes côté serveur que pour tout appel sortant : un agent sur votre propre machine ou sur un réseau privé ne peut donc pas être atteint depuis le bloc. Testez plutôt avec un agent publié sur un hôte public.
Configuration opérateur
Les déploiements de production doivent configurer la signature des Agent Cards avec l'une des options suivantes :
A2A_CARD_SIGNING_PRIVATE_JWKS: un ensemble JWK ou un tableau JSON. Cette option permet le chevauchement et la rotation des clés.A2A_CARD_SIGNING_PRIVATE_JWK: une seule clé JWK EC P-256 privée, pour la compatibilité.
Définissez A2A_CARD_SIGNING_KEY_ID pour sélectionner la clé privée active. Les clés marquées comme révoquées, expirées ou pas encore actives ne sont ni publiées ni sélectionnées. A2A_PAGE_TOKEN_SECRET peut être défini comme secret dédié d'au moins 32 caractères ; sinon, le secret d'authentification configuré pour la plateforme signe les jetons de page limités au catalogue et aux tâches.
Dépannage
| Symptôme | Vérification |
|---|---|
401 Authentication required | Envoyez l'un des mécanismes annoncés par l'Agent Card. |
| Tâche ou agent introuvable | Vérifiez que l'identifiant appartient exactement à l'organisation, à l'espace de travail et à l'environnement de la publication. |
JSON-RPC -32005 ou HTTP 415 | Le type de média de la partie du message n'est pas répertorié dans les modes d'entrée de l'Agent Card. |
JSON-RPC -32009 ou HTTP 400 | Envoyez une valeur A2A-Version annoncée par l'interface sélectionnée. |
| L'agent disparaît | Vérifiez que la publication est Privée ou Publique, et non Désactivée. |
| Les modifications du workflow n'apparaissent pas | Publiez une nouvelle version de déploiement et réépinglez la publication A2A. |
| Le rappel push est refusé | Utilisez un point de terminaison HTTPS public ; les adresses privées et de métadonnées sont bloquées. |
Le bloc A2A signale agentUrl cannot point to localhost, agentUrl cannot point to private IP addresses, agentUrl cannot point to a blocked internal host ou resolves to a disallowed address | L'URL de l'agent est locale, privée ou désigne un hôte de métadonnées cloud, ou son nom se résout vers une telle adresse. Le bloc n'appelle que des adresses publiques ; voir Tester le bloc A2A. |
Le bloc A2A signale Redirect blocked: agentUrl must use https:// protocol | Un agent https:// a redirigé le bloc vers une adresse http:// en clair. Le bloc refuse ce déclassement ; indiquez directement l'URL https:// finale de l'agent. |
Le bloc A2A signale Signed Agent Card JWK Set URL must use https:// | L'agent signe sa carte mais désigne un jeu de clés (jku) en http:// en clair pour la vérifier. En http la clé pourrait être remplacée en transit et une carte falsifiée serait acceptée ; le bloc la refuse donc. L'agent doit publier son jeu de clés en https://. |