Skip to content

A2A: validate invoke_agent 'data' payload against skill input schema (like McpStepValidator) #302

@rockfordlhotka

Description

@rockfordlhotka

Motivation

McpStepValidator gives us deterministic "required/unknown field" checks against a tool's JSON Schema plus a single-shot LLM auto-correction on validation failure. The A2A invoke_agent tool has no equivalent — the data part is accepted blindly, so authoring mistakes reach the remote agent and fail there (or worse, succeed with wrong fields).

Today AgentSkill (src/RockBot.A2A.Abstractions/AgentSkill.cs) carries only Id, Name, Description, Tags, Examples. No input schema. That's not enough to validate.

Scope

  1. Extend the card contract. Add optional InputSchema (JSON Schema as string or JsonElement) to AgentSkill. Consider also surfacing InputModes / OutputModes if present.
  2. Populate on registration. Update RegisterAgentExecutor (and whatever path fetches the remote .well-known/agent-card.json) to parse the skill's input schema when the remote card advertises one. A2A v0.3 and v1 both allow per-skill input schemas; today we ignore them.
  3. Add A2ADataPartValidator. Mirrors McpStepValidator — required/unknown fields, closed-schema handling, same error-message shape with a compact schema summary for auto-retry. Runs in InvokeAgentExecutor.ExecuteAsync before dispatch (and in GatewayRouter.RouteA2A path for wisp A2A steps). Schema-free skills → skip validation (same as MCP).
  4. Share with MCP. Extract the compare / build-summary helpers currently in McpStepValidator into a reusable piece so both validators use the same logic.
  5. Auto-correction. Reuse the TryAutoCorrectMcpParamsAsync single-shot correction path for the A2A data argument when validation fails and an LLM is wired up.

Non-goals

  • Validating the message text part (it's natural language — no schema).
  • Validating outputs — out of scope; handled per-skill by the caller if desired.

Relation

Follow-up to #300 / #301 — once duplicate execution is closed, invalid data payloads become the next failure mode we can catch at the edge.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions