A2a client#534
Open
Greyeye wants to merge 4 commits into
Open
Conversation
…eview Add pkg/a2askills — a generic A2A client that discovers skills at startup from any compatible agent's AgentCard and registers them as aireview tools. No proprietary schemas or engine-specific types in kubechecks. How it works: - NewAgentClient dials any A2A-compatible agent over gRPC - Discover() fetches skills via GetExtendedAgentCard at startup - Each skill becomes an aireview.Tool using the card's name/description/tags - A2ASkillTool accepts free-form map[string]any params; the LLM constructs them guided by the skill description - BuildSystemPrompt receives []a2a.AgentSkill and generates the Agent Skills section from actual card data, not hardcoded assumptions - Multiple agents supported: each address in SKILL_AGENT_ADDRS is dialed independently; all discovered skills are registered as review tools Config (presence of any address enables the feature, no boolean flag): KUBECHECKS_SKILL_AGENT_ADDRS=agent1:50051,agent2:50051 KUBECHECKS_SKILL_AGENT_TIMEOUT=3s Files: - pkg/a2askills/client.go: Client interface (Discover+Call), AgentClient - pkg/a2askills/client_test.go: table-driven tests via mockery MockClient - pkg/a2askills/README.md: package documentation - pkg/aireview/tools/skills.go: A2ASkillTool generic tool factory - pkg/checks/aireview/check.go: skillAgents []skillAgent, WithSkillAgent - pkg/aireview/prompt.go: BuildSystemPrompt takes []a2a.AgentSkill - mocks/a2askills/: mockery-generated MockClient - cmd/processors.go: iterate SKILL_AGENT_ADDRS, discover and register each - docs/usage.md: document SKILL_AGENT_ADDRS and SKILL_AGENT_TIMEOUT flags
fmt.Sprintf into a raw JSON string literal is unsafe — tag names containing quotes or backslashes would produce invalid JSON. json.Marshal handles escaping correctly and is the idiomatic approach.
|
Temporary Helm chart (version Install directly: helm install kubechecks oci://ghcr.io/zapier/charts/kubechecks --version 0.0.0-pr534Pull to inspect: helm pull oci://ghcr.io/zapier/charts/kubechecks --version 0.0.0-pr534Note: OCI charts don't use |
ToolInputSchemaParam uses omitzero via its embedded paramObj — when Properties and Required are both nil, the entire input_schema field is omitted from the JSON, causing Anthropic to reject with "input_schema: Field required". This happens for A2A skill tools whose schema uses additionalProperties without a properties key (e.g. knowledge_search's free-form params schema). Fix: default Properties to an empty map when nil, and forward additionalProperties through ExtraFields so free-form schemas round-trip correctly. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
feat(a2askills): Dynamic A2A skill discovery for AI review
Summary
Adds
pkg/a2askills— a generic A2A protocol clientthat connects to external skill agents at startup, discovers their capabilities from the
agent's published
AgentCard, and registers each skill as a tool available to the AI reviewer.kubechecks' AI reviewer already has strong access to what changed (diffs, rendered manifests)
and live cluster state (via ArgoCD). What it lacks is the team's accumulated knowledge —
conventions, patterns, and incident learnings.
a2askillsbridges that gap without couplingkubechecks to any specific agent's internal schema.
What changed
pkg/a2askills(new package)Clientinterface withDiscover(ctx)andCall(ctx, skill, params)— generic,no knowledge-engine-specific types
AgentClientimplementation dials any A2A-compatible agent over gRPCDiscover()fetches skills viaGetExtendedAgentCardat startup; each skill's name,description, and tags come from the agent card — nothing hardcoded in kubechecks
Call()acceptsmap[string]anyparams; the LLM constructs them guided by the skilldescription, so kubechecks never needs to know the agent's internal schema
MockClientfor tests (mocks/a2askills/)DiscoverandCallsuccess/error pathspkg/aireview/tools/skills.go(new)A2ASkillTool(client, skill, timeout)— generic tool factory that builds anaireview.Tooldirectly from ana2a.AgentSkill. Tool name, description, and taghints all come from the agent card.
pkg/checks/aireview/check.goskillAgents []skillAgentreplaces the oldknowledgeClient/knowledgeSkillsfieldsWithSkillAgent(client, skills, timeout)option — can be called multiple times toattach skills from different agents
pkg/aireview/prompt.goBuildSystemPromptnow takes[]a2a.AgentSkillinstead of aknowledgeEnabled booleach skill's name, ID, and description — not a hardcoded knowledge-engine reference
Configuration
Design decisions
Why agent card discovery over hardcoded skill names?
The agent publishes what it supports. kubechecks reads it. Adding a new skill to the agent
automatically makes it available to the reviewer — no kubechecks code change needed.