Skip to content

Enhancement: multi-skill A2A agent cards (LLM-interpretation dispatch, aligned with standard A2A) #1326

Description

@dhyansraj

Summary

Mesh's A2A producer currently advertises exactly one skill per agent card (1 decorated surface → 1 card → 1 skill). Standard A2A supports multiple skills per card. This enhancement adds multi-skill A2A cards, routing inbound requests to the right skill the same way the rest of the A2A ecosystem does — LLM-based agent-side interpretation — rather than inventing a mesh-specific convention.

Current state (verified)

  • The card model already has a skills[] array, but all three runtimes hard-code a single element:
    • Python src/runtime/python/_mcp_mesh/engine/a2a_card.py:94 → "skills": [skill]
    • TypeScript src/runtime/typescript/src/a2a/producer/card-builder.ts:101 → skills: [skill]
    • Java .../web/MeshA2ACardBuilder.java:118 → List.of(skill)
  • Upstream, the surface metadata is scalar (skill_id/skill_name/single tags), one skill per decorated function — a2a_card.py:27-32, @MeshA2A scalar fields MeshA2A.java:131-167, collect_a2a_surfaces one entry per surface.
  • 1-skill-per-card is a deliberate v1 decision, spec-locked across runtimes: surfaces-spec.md:1130-1133 ("New runtimes MUST match — do not group skills"), A2A_SURFACE_DESIGN.org:82-96.
  • A2A skills are NOT derived from mesh capability names (skill_id defaults from the path's last segment); the A2A pipeline is disjoint from the MCP capability/service-view machinery, and service views are explicitly rejected on the A2A producer (mount.ts:238-240, RFC RFC: consumer-side service views — typed aggregation over capability dependencies (@McpMeshService) #1280).

Why LLM-interpretation dispatch (the routing decision)

The A2A protocol carries no skill selector on the request — SendMessageRequest/Message have no skillId (verified against the A2A spec; Message fields are messageId/contextId/taskId/role/parts/metadata/extensions/referenceTaskIds). Skills in the AgentCard are for discovery, and a multi-skill agent is expected to interpret the message and dispatch itself (typically LLM-backed). That is how non-mesh multi-skill A2A agents already work.

Decision: match that. A multi-skill mesh A2A agent dispatches by LLM interpretation — which is a natural fit for mesh's existing @mesh.llm tool-calling loop (the card's skills become the LLM's callable tools/capabilities). We will not invent a mesh-specific metadata.skillId routing convention — staying aligned with the ecosystem is worth more than deterministic-but-nonstandard routing.

Scope (open — strategy finalized at pickup)

  • Make the surface/skill metadata a list (scalar → skills[]) and populate the existing skills[] array with N entries — must land in all three runtimes together (they are spec-locked).
  • Multi-skill card assembly + a dispatch strategy = LLM-based interpretation, reusing the existing @mesh.llm machinery where possible (skills → callable tools).
  • Service views remain orthogonal (consumer-side, firewalled from the A2A producer). The dot-namespaced grouping could feed the skill-list metadata, but does not drive routing.

Implementation approach (how skills bind to handlers, how the LLM dispatcher is wired, how it composes with existing single-skill cards) to be designed when this is picked up.

Notes

  • Not slotted to a specific release — enhancement/backlog.
  • Keep single-skill cards working (deterministic 1:1) as the default; multi-skill is additive.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions