From a15bff1c70a6b9193d651ae64970d279b1a6beb4 Mon Sep 17 00:00:00 2001 From: a2a-cloud Date: Sun, 19 Jul 2026 19:58:35 +0000 Subject: [PATCH] a2a-source-edit: write frontend/src/App.jsx --- frontend/src/App.jsx | 273 ++++++++++++++++++++++++++----------------- 1 file changed, 164 insertions(+), 109 deletions(-) diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 88671fd..d23fea6 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -1,18 +1,31 @@ import { useEffect, useMemo, useState } from "react"; -import { - callSkill, - loadAgentConfig, - loadSession, - sampleArgs, - signInUrl, -} from "./a2a.js"; +import { callSkill, loadAgentConfig, loadSession, signInUrl } from "./a2a.js"; + +const SUCCESS_FIXTURE = `From: alex@company.example +Subject: Concern about team behavior +Body: I want to report behavior that feels like harassment and retaliation after I raised a concern. What should I do next? +--- +From: priya@company.example +Subject: Benefits enrollment for dependent +Body: I need to add a dependent to my insurance and want to understand eligibility and enrollment timing. +--- +From: marco@company.example +Subject: PTO request next month +Body: I would like to take leave from May 6 to May 10. Can People approve this?`; + +const DEFAULT_POLICY = `Benefits questions: be empathetic, explain that enrollment and eligibility depend on plan documents, and route exceptions to People Ops. +Leave requests: acknowledge receipt, ask for dates if missing, and mention manager/People approval before commitments. +Payroll or personal data: mark urgent, avoid exposing private data, and route to the secure HRIS/payroll channel. +Employee relations or harassment: mark urgent, avoid investigation promises, and escalate to the designated People partner.`; export function App() { const [config, setConfig] = useState(null); const [session, setSession] = useState(null); - const [selectedSkillName, setSelectedSkillName] = useState(""); - const [argsText, setArgsText] = useState("{}"); + const [inboxText, setInboxText] = useState(SUCCESS_FIXTURE); + const [policyText, setPolicyText] = useState(DEFAULT_POLICY); + const [maxMessages, setMaxMessages] = useState(6); const [result, setResult] = useState(null); + const [mailbox, setMailbox] = useState(null); const [error, setError] = useState(null); const [running, setRunning] = useState(false); @@ -20,46 +33,30 @@ export function App() { 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 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) { + async function runTriage(event) { event.preventDefault(); - if (!config || !selectedSkill) return; + if (!config) return; setRunning(true); setError(null); setResult(null); try { - const args = JSON.parse(argsText || "{}"); - const data = await callSkill(config, selectedSkill.name, args); + const data = await callSkill(config, "triage_people_inbox", { + inbox_text: inboxText, + policy_text: policyText, + max_messages: Number(maxMessages), + }); setResult(data); } catch (err) { setError(err.message || String(err)); @@ -68,91 +65,149 @@ export function App() { } } + async function checkMailbox() { + if (!config) return; + setError(null); + try { + const data = await callSkill(config, "mailbox_status", { limit: 5, unseen_only: false }); + setMailbox(data); + } catch (err) { + setError(err.message || String(err)); + } + } + + function downloadReport() { + if (!result?.artifact?.content_text) return; + const blob = new Blob([result.artifact.content_text], { + type: result.artifact.media_type || "application/json", + }); + const url = URL.createObjectURL(blob); + const anchor = document.createElement("a"); + anchor.href = url; + anchor.download = result.artifact.name || "people-team-inbox-triage.json"; + document.body.appendChild(anchor); + anchor.click(); + anchor.remove(); + URL.revokeObjectURL(url); + } + if (!config) { - return ( -
-

{error || "Loading A2A agent contract..."}

-
- ); + return
{error || "Loading People Inbox Assistant..."}
; } return ( -
- - -
-
+
+
+

Production proof v116 · People teams

+
-

Skill runner

-

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

+

Shared inbox triage with approval-ready HR replies

+

+ Paste a few People inbox messages, keep or edit the policy guidance, and get a prioritized queue plus grounded drafts in under two minutes. +

- - Docs - -
- - {selectedSkill ? ( -
-