This commit is contained in:
a2a-platform
2026-07-18 11:56:09 +00:00
commit b9b0abea2b
8 changed files with 346 additions and 0 deletions

17
frontend/app.js Normal file
View File

@@ -0,0 +1,17 @@
import { agent } from "/a2a-client.js";
const button = document.querySelector("#trigger");
const result = document.querySelector("#result");
button.addEventListener("click", async () => {
button.disabled = true;
result.textContent = "Calling run(scenario=controlled-failure)…";
try {
const response = await agent.call("run", { scenario: "controlled-failure" });
result.textContent = JSON.stringify(response, null, 2);
} catch (error) {
result.textContent = `Failure observed. The bounded repair should now be queued.\n\n${error.message}`;
} finally {
button.disabled = false;
}
});

36
frontend/index.html Normal file
View File

@@ -0,0 +1,36 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="A live A2A Cloud self-healing agent demonstration." />
<title>Self-Healing Agent · A2A Cloud</title>
<link rel="stylesheet" href="./styles.css" />
</head>
<body>
<main>
<div class="eyebrow"><span></span> LIVE PLATFORM DEMO</div>
<h1>Software that repairs<br /><em>its own runtime failure.</em></h1>
<p class="lede">
This agent opts in through <code>a2a.yaml</code>. A real 500 error creates a bounded repair job,
patches managed source, runs tests, and redeploys the exact commit—with the full trail in the app.
</p>
<section class="card">
<div class="card-head">
<div><small>SELF-HEALING POLICY</small><strong>Enabled</strong></div>
<div class="pulse">READY</div>
</div>
<div class="policy">
<div><span>Trigger</span><b>1 internal failure</b></div>
<div><span>Cooldown</span><b>5 minutes</b></div>
<div><span>Daily ceiling</span><b>2 repairs</b></div>
<div><span>Promotion gate</span><b>Tests + exact SHA live</b></div>
</div>
<button id="trigger">Trigger controlled failure</button>
<pre id="result">Waiting for a test run.</pre>
</section>
<p class="foot">Expected input and 4xx errors never mutate source. Credentials and user inputs stay out of repair evidence.</p>
</main>
<script type="module" src="./app.js"></script>
</body>
</html>

24
frontend/styles.css Normal file
View File

@@ -0,0 +1,24 @@
:root { color-scheme: dark; font-family: Inter, ui-sans-serif, system-ui, sans-serif; background: #090b10; color: #edf1f7; }
* { box-sizing: border-box; }
body { margin: 0; min-height: 100vh; background: radial-gradient(circle at 78% 15%, #16362d 0, transparent 30%), linear-gradient(145deg, #090b10, #0d1218); }
main { width: min(920px, calc(100% - 40px)); margin: 0 auto; padding: 9vh 0 8vh; }
.eyebrow { color: #7f8b9c; font-size: 11px; letter-spacing: .2em; display: flex; align-items: center; gap: 10px; }
.eyebrow span { width: 8px; height: 8px; border-radius: 99px; background: #5dffb2; box-shadow: 0 0 22px #5dffb2; }
h1 { margin: 28px 0 22px; font-size: clamp(48px, 8vw, 88px); line-height: .98; letter-spacing: -.055em; font-weight: 580; }
h1 em { font-style: normal; color: #76efb5; }
.lede { max-width: 760px; color: #aab4c2; font-size: clamp(17px, 2.2vw, 21px); line-height: 1.58; }
code { color: #76efb5; }
.card { margin-top: 48px; padding: 28px; border: 1px solid #27323e; border-radius: 18px; background: rgba(14, 18, 25, .82); box-shadow: 0 26px 80px #0008; }
.card-head { display: flex; justify-content: space-between; gap: 20px; align-items: flex-start; }
.card-head small { display: block; color: #728094; letter-spacing: .14em; }
.card-head strong { display: block; margin-top: 8px; font-size: 28px; }
.pulse { color: #67f6ad; border: 1px solid #32634d; background: #10281f; border-radius: 99px; padding: 8px 12px; font: 11px ui-monospace, monospace; }
.policy { margin: 26px 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); border: 1px solid #202a35; border-radius: 12px; overflow: hidden; }
.policy div { padding: 16px; border: 1px solid #202a35; }
.policy span { display: block; color: #728094; font-size: 11px; text-transform: uppercase; letter-spacing: .1em; }
.policy b { display: block; margin-top: 7px; font-size: 14px; }
button { width: 100%; border: 0; border-radius: 10px; padding: 15px 18px; background: #70efb2; color: #07120d; font: 700 14px ui-monospace, monospace; cursor: pointer; }
button:disabled { opacity: .5; cursor: wait; }
pre { min-height: 74px; margin: 14px 0 0; padding: 16px; border-radius: 10px; background: #080a0e; color: #96a4b7; white-space: pre-wrap; overflow: auto; font-size: 12px; }
.foot { color: #687588; font-size: 12px; margin-top: 20px; }
@media (max-width: 620px) { .policy { grid-template-columns: 1fr; } .card { padding: 20px; } }