import { useEffect, useMemo, useState } from "react"; import { callSkill, loadAgentConfig, loadSession, sampleArgs, signInUrl, } from "./a2a.js"; export function App() { const [config, setConfig] = useState(null); const [session, setSession] = useState(null); const [selectedSkillName, setSelectedSkillName] = useState(""); const [argsText, setArgsText] = useState("{}"); const [result, setResult] = useState(null); const [error, setError] = useState(null); const [running, setRunning] = useState(false); useEffect(() => { loadAgentConfig() .then((data) => { setConfig(data); const firstSkill = data.skills?.[0]; if (firstSkill) { setSelectedSkillName(firstSkill.name); setArgsText(JSON.stringify(sampleArgs(firstSkill), null, 2)); } 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], ); const needsSignIn = Boolean( config?.auth?.invokeRequiresSession && session && !session.authenticated, ); const signInHref = useMemo( () => (config && needsSignIn ? signInUrl(config) : null), [config, needsSignIn], ); function selectSkill(skill) { setSelectedSkillName(skill.name); setArgsText(JSON.stringify(sampleArgs(skill), null, 2)); setResult(null); setError(null); } 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 A2A agent contract..."}

); } return (

Skill runner

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

Docs
{selectedSkill ? (