import { useEffect, useMemo, useState } from "react"; import { callSkill, loadAgentConfig, loadSession } from "./a2a.js"; const SAMPLE_EMAIL = { sender_email: "Customer Example ", subject: "Refund request for pi_test123", body: "Please refund 25.00 USD for payment pi_test123.", message_id: "", stripe_payment_intent_id: "pi_test123", requested_refund_amount_cents: 2500, currency: "usd", customer_name: "Customer", }; export function App() { const [config, setConfig] = useState(null); const [session, setSession] = useState(null); const [selectedSkillName, setSelectedSkillName] = useState("process_support_email"); const [argsText, setArgsText] = useState(JSON.stringify(SAMPLE_EMAIL, null, 2)); const [result, setResult] = useState(null); const [error, setError] = useState(null); const [running, setRunning] = useState(false); useEffect(() => { loadAgentConfig() .then((data) => { setConfig(data); return loadSession(data).catch(() => null); }) .then((sessionData) => setSession(sessionData)) .catch((err) => setError(err.message || String(err))); }, []); const selectedSkill = useMemo( () => config?.skills?.find((skill) => skill.name === selectedSkillName), [config, selectedSkillName], ); function selectSkill(name) { setSelectedSkillName(name); setResult(null); setError(null); if (name === "process_support_email") setArgsText(JSON.stringify(SAMPLE_EMAIL, null, 2)); if (name === "execute_approved_refund") { setArgsText(JSON.stringify({ action_digest: "paste_action_digest_from_preview", approval_token: "APPROVE-REFUND-first16digest", stripe_payment_intent_id: "pi_test123", amount_cents: 2500, currency: "usd", customer_email: "customer@example.com", reason: "requested_by_customer", }, null, 2)); } } async function runSkill(event) { event.preventDefault(); if (!config || !selectedSkill) return; setRunning(true); setError(null); setResult(null); try { const args = JSON.parse(argsText || "{}"); const data = await callSkill(config, selectedSkill.name, args); setResult(data); } catch (err) { setError(err.message || String(err)); } finally { setRunning(false); } } if (!config) { return

{error || "Loading support refund agent..."}

; } const skills = config.skills || []; return (

Chat-style runner

{selectedSkill?.name || "No skills found"}

Docs