From 7c13652ab714d8d419787e441c9d0269deff7075 Mon Sep 17 00:00:00 2001 From: scotty-bot Date: Wed, 13 May 2026 06:47:08 +0000 Subject: [PATCH] MIL-115 Add A2A HITL skill loading demo --- examples/a2a-human-in-the-loop/README.md | 59 ++++++++++++++ examples/a2a-human-in-the-loop/agents.yaml | 78 +++++++++++++++++++ .../a2a-human-in-the-loop/kustomization.yaml | 5 ++ .../a2a-human-in-the-loop/modelconfig.yaml | 13 ++++ 4 files changed, 155 insertions(+) create mode 100644 examples/a2a-human-in-the-loop/README.md create mode 100644 examples/a2a-human-in-the-loop/agents.yaml create mode 100644 examples/a2a-human-in-the-loop/kustomization.yaml create mode 100644 examples/a2a-human-in-the-loop/modelconfig.yaml diff --git a/examples/a2a-human-in-the-loop/README.md b/examples/a2a-human-in-the-loop/README.md new file mode 100644 index 000000000..bd9a19db7 --- /dev/null +++ b/examples/a2a-human-in-the-loop/README.md @@ -0,0 +1,59 @@ +# A2A Human-in-the-Loop With Dynamic Skill Loading + +This demo creates two declarative kagent agents: + +- `a2a-hitl-coordinator` receives the user request and delegates to the specialist by using kagent's Agent tool, which communicates over A2A. +- `a2a-hitl-specialist` pauses at a human approval checkpoint with the built-in `ask_user` tool, then loads and runs the `kebab-maker` skill from `https://github.com/kagent-dev/kagent.git` at runtime through `spec.skills.gitRefs`. + +## Prerequisites + +- A Kubernetes cluster with kagent installed and the `kagent.dev/v1alpha2` CRDs available. +- An OpenAI API key for the demo `ModelConfig`. +- The kagent UI or another A2A client that can send messages to `a2a-hitl-coordinator` and answer HITL prompts. + +## Deploy + +Create the namespace and model API key secret: + +```sh +kubectl create namespace kagent --dry-run=client -o yaml | kubectl apply -f - +kubectl -n kagent create secret generic a2a-hitl-openai \ + --from-literal=api-key="$OPENAI_API_KEY" \ + --dry-run=client -o yaml | kubectl apply -f - +``` + +Apply the demo: + +```sh +kubectl apply -k examples/a2a-human-in-the-loop +kubectl -n kagent wait --for=condition=Accepted agent/a2a-hitl-specialist --timeout=120s +kubectl -n kagent wait --for=condition=Accepted agent/a2a-hitl-coordinator --timeout=120s +``` + +The specialist pod has a skills init container. At startup, kagent clones the remote repo URL and copies `go/core/test/e2e/testdata/skills/kebab-maker` into `/skills/kebab-maker`. + +## Run + +Open the kagent UI, start a chat with `a2a-hitl-coordinator`, and send: + +```text +Run the A2A human-in-the-loop skill demo. +``` + +Expected flow: + +1. The coordinator calls `a2a-hitl-specialist` as an Agent tool. This is the A2A handoff. +2. The specialist calls `ask_user` with the approval question: + `Approve loading and running the git-loaded kebab-maker skill for the A2A HITL demo?` +3. Choose `Approve` in the UI. +4. The specialist calls `skills(command="kebab-maker")`, then runs the skill script with `bash`. +5. The coordinator relays the specialist's result back to the user. + +If you reject the prompt, the specialist stops and reports that the checkpoint was rejected. + +## Clean Up + +```sh +kubectl delete -k examples/a2a-human-in-the-loop +kubectl -n kagent delete secret a2a-hitl-openai +``` diff --git a/examples/a2a-human-in-the-loop/agents.yaml b/examples/a2a-human-in-the-loop/agents.yaml new file mode 100644 index 000000000..8e3869e04 --- /dev/null +++ b/examples/a2a-human-in-the-loop/agents.yaml @@ -0,0 +1,78 @@ +apiVersion: kagent.dev/v1alpha2 +kind: Agent +metadata: + name: a2a-hitl-specialist + namespace: kagent +spec: + description: Specialist agent that asks for human approval before using a dynamically loaded skill. + type: Declarative + skills: + gitRefs: + - url: https://github.com/kagent-dev/kagent.git + ref: main + path: go/core/test/e2e/testdata/skills/kebab-maker + name: kebab-maker + declarative: + runtime: python + stream: true + modelConfig: a2a-hitl-demo-model + systemMessage: | + You are the specialist agent for the A2A human-in-the-loop demo. + + When the coordinator asks you to run the demo: + 1. Use the ask_user tool to request explicit approval before doing any work. Ask exactly: + "Approve loading and running the git-loaded kebab-maker skill for the A2A HITL demo?" + Provide exactly two choices: "Approve" and "Reject". + 2. If the user's answer is not "Approve", stop and report that the checkpoint was rejected. + 3. If the user approves, call the skills tool with command "kebab-maker". + 4. Follow the loaded skill instructions. Use the bash tool to run the skill script from the + kebab-maker skill directory, then return the script output to the coordinator. + + This demo intentionally uses ask_user as the human approval checkpoint so the A2A parent + agent must pause while this subagent waits for human input. + a2aConfig: + skills: + - id: hitl-skill-runner + name: HITL Skill Runner + description: Requests human approval, then loads and runs a skill fetched from a Git repository. + tags: + - a2a + - human-in-the-loop + - skills + examples: + - Run the A2A human-in-the-loop skill demo. +--- +apiVersion: kagent.dev/v1alpha2 +kind: Agent +metadata: + name: a2a-hitl-coordinator + namespace: kagent +spec: + description: Coordinator agent that delegates demo execution to a specialist over A2A. + type: Declarative + declarative: + runtime: python + stream: true + modelConfig: a2a-hitl-demo-model + systemMessage: | + You are the coordinator for the A2A human-in-the-loop demo. + + For any request to run the demo, delegate the work to the a2a-hitl-specialist agent. + Do not answer from your own knowledge. The specialist must perform the approval checkpoint, + load the remote git skill, run the skill script, and return the result. After the specialist + responds, summarize the result and mention that it came from the specialist via A2A. + tools: + - type: Agent + agent: + name: a2a-hitl-specialist + a2aConfig: + skills: + - id: a2a-hitl-coordination + name: A2A HITL Coordination + description: Delegates demo requests to a specialist agent over A2A and relays the result. + tags: + - a2a + - delegation + - human-in-the-loop + examples: + - Run the A2A human-in-the-loop skill demo. diff --git a/examples/a2a-human-in-the-loop/kustomization.yaml b/examples/a2a-human-in-the-loop/kustomization.yaml new file mode 100644 index 000000000..cf0bad9d8 --- /dev/null +++ b/examples/a2a-human-in-the-loop/kustomization.yaml @@ -0,0 +1,5 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - modelconfig.yaml + - agents.yaml diff --git a/examples/a2a-human-in-the-loop/modelconfig.yaml b/examples/a2a-human-in-the-loop/modelconfig.yaml new file mode 100644 index 000000000..e13dfdb8d --- /dev/null +++ b/examples/a2a-human-in-the-loop/modelconfig.yaml @@ -0,0 +1,13 @@ +apiVersion: kagent.dev/v1alpha2 +kind: ModelConfig +metadata: + name: a2a-hitl-demo-model + namespace: kagent +spec: + provider: OpenAI + model: gpt-4o-mini + apiKeySecret: a2a-hitl-openai + apiKeySecretKey: api-key + openAI: + temperature: "0.2" + maxTokens: 2048