feat(module2): chat with your agent — three canned prompts, then Layers 2/3
Module 2 is now a chat straight to the agent instead of Build & flash. Removed the "Open your node" links and the Live board feed card. New AgentChat component: three imperative canned prompts — - List the I2C devices on the bus - Count to 100 and print the value once a second in the LED matrix - Scroll GO CLAWS on the LED matrix Each sends to the agent (fire-and-forget, cloud) and streams its activity (tools/flash/reply) back into the transcript. A prompt is marked done on its first terminal step (flash/response); an error resets it to retry. Prompts run one at a time. Once all three have run successfully, Module 2 reveals "What's next" — the ADD Layer 2 (Skills) + Layer 3 (Policies & failure) capture — and Proceed gates on all-three-tried AND L2 + L3 filled. Note: BuildFlash / LiveBoardFeed / ActorMap are now orphaned (kept for possible reuse). Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
c2ef338888
commit
7780903278
+63
-73
@@ -1,27 +1,22 @@
|
||||
import { useState } from 'react'
|
||||
import { Link, useNavigate } from 'react-router-dom'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
|
||||
import { Badge } from '@/components/ui/badge'
|
||||
import { PhaseStrip } from '@/components/PhaseStrip'
|
||||
import { LiveBoardFeed } from '@/components/LiveBoardFeed'
|
||||
import { BuildFlash } from '@/components/BuildFlash'
|
||||
import { AgentChat } from '@/components/AgentChat'
|
||||
import { AddLayerForm } from '@/components/AddLayerForm'
|
||||
import { OpenYourNode } from '@/components/OpenYourNode'
|
||||
import { useNodeFeed } from '@/lib/useNodeFeed'
|
||||
import { useSession } from '@/store/session'
|
||||
|
||||
export function Module2() {
|
||||
const navigate = useNavigate()
|
||||
const teamId = useSession((s) => s.teamId)
|
||||
const feed = useNodeFeed(teamId, true)
|
||||
const l2 = useSession((s) => s.add.L2)
|
||||
const l3 = useSession((s) => s.add.L3)
|
||||
const completePhase = useSession((s) => s.completePhase)
|
||||
const [tried, setTried] = useState(0)
|
||||
|
||||
// The board acting on a prompt (via Build & flash below) shows up in its
|
||||
// activity feed — that's proof the loop was exercised.
|
||||
const exercised = feed.activity.length > 0
|
||||
const ready = exercised && l2.trim().length > 0 && l3.trim().length > 0
|
||||
const allTried = tried >= 3
|
||||
const ready = allTried && l2.trim().length > 0 && l3.trim().length > 0
|
||||
|
||||
const onProceed = () => {
|
||||
completePhase('m2')
|
||||
@@ -42,77 +37,72 @@ export function Module2() {
|
||||
|
||||
<PhaseStrip active="m2" />
|
||||
|
||||
<section className="px-8 py-10 max-w-5xl mx-auto space-y-6">
|
||||
<section className="px-8 py-10 max-w-3xl mx-auto space-y-6">
|
||||
<div>
|
||||
<Badge variant="secondary" className="font-mono text-[10px] tracking-widest uppercase mb-2">
|
||||
Phase 4 of 5 · ~90 min
|
||||
</Badge>
|
||||
<h1 className="text-3xl font-bold tracking-tight">Module 2 · Skills & policies</h1>
|
||||
<p className="text-sm text-muted-foreground mt-2 max-w-xl">
|
||||
Your node ships with expert skills already. Decide which domain skills it needs, try them in the
|
||||
node dashboard, then capture Layers 2 and 3 — the skills it can invoke and the actuation gate
|
||||
that governs them.
|
||||
Your agent already ships with expert skills — hardware, the MCU bridge, the LED matrix,
|
||||
flashing, and more. Try them from the chat below: each prompt makes the agent use its
|
||||
skills and tools on your real board.
|
||||
</p>
|
||||
<div className="mt-3">
|
||||
<OpenYourNode variant="inline" />
|
||||
</div>
|
||||
|
||||
<AgentChat onProgress={(done) => setTried(done)} />
|
||||
|
||||
{/* What's next — revealed once all three prompts have run successfully. */}
|
||||
{allTried ? (
|
||||
<div className="space-y-6" data-testid="whats-next">
|
||||
<div className="pt-2">
|
||||
<h2 className="text-lg font-semibold tracking-tight">What’s next</h2>
|
||||
<p className="text-sm text-muted-foreground mt-1 max-w-xl">
|
||||
You just watched the agent enumerate a bus and drive the matrix using its built-in
|
||||
skills. Now capture <span className="font-medium text-foreground">your domain’s</span>{' '}
|
||||
skills and the policy that governs them — Layers 2 and 3 of your Agent Design Document.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<AddLayerForm
|
||||
layer="L2"
|
||||
title="ADD · Layer 2 — Skills"
|
||||
description="What skills can the agent invoke to act on its domain?"
|
||||
placeholder="Flash a sketch to the MCU; scroll a message; drive the damper; sample the IMU."
|
||||
/>
|
||||
<AddLayerForm
|
||||
layer="L3"
|
||||
title="ADD · Layer 3 — Policies & failure"
|
||||
description="The actuation gate — and what happens when things break. For each failure you can name, which way does it fail? A fail-safe must never quietly report 'normal'."
|
||||
placeholder={
|
||||
'Autonomous: log + alert. Needs approval: drive the actuator. E-stop: operator halts actuation at any time.\n\n' +
|
||||
'Failure states → response:\n' +
|
||||
'• sensor disconnected / stuck value / drifting → mark UNKNOWN, never "nominal"\n' +
|
||||
'• reading older than 60 s → treat as no reading\n' +
|
||||
'• cloud unreachable → decide on-board, flag reduced confidence\n' +
|
||||
'• agent unsure → escalate to a human, do not actuate'
|
||||
}
|
||||
/>
|
||||
|
||||
<div className="flex justify-end pt-2">
|
||||
<Button size="lg" disabled={!ready} onClick={onProceed}>
|
||||
Proceed to ADD builder →
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle className="text-base">Skills reference</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-3">
|
||||
<p className="text-sm text-muted-foreground leading-relaxed">
|
||||
The node already ships with expert skills — <span className="font-mono text-xs text-foreground">uno-q-hardware</span>,{' '}
|
||||
<span className="font-mono text-xs text-foreground">bridge</span>,{' '}
|
||||
<span className="font-mono text-xs text-foreground">led-matrix</span>,{' '}
|
||||
<span className="font-mono text-xs text-foreground">flashing</span>, and more. Layer 2 is not
|
||||
about re-implementing those: it’s deciding which <em>domain</em> skills your node needs, then
|
||||
trying them live in the dashboard.
|
||||
</p>
|
||||
<OpenYourNode variant="inline" />
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle className="text-base">Live board feed</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
<LiveBoardFeed feed={feed} />
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<BuildFlash />
|
||||
|
||||
<div className="grid lg:grid-cols-2 gap-6">
|
||||
<AddLayerForm
|
||||
layer="L2"
|
||||
title="ADD · Layer 2 — Skills"
|
||||
description="What skills can the node invoke to act on its domain?"
|
||||
placeholder="Flash a sketch to the MCU; scroll a message; drive the damper; sample the IMU."
|
||||
/>
|
||||
<AddLayerForm
|
||||
layer="L3"
|
||||
title="ADD · Layer 3 — Policies & failure"
|
||||
description="The actuation gate — and what happens when things break. For each failure you can name, which way does it fail? A fail-safe must never quietly report 'normal'."
|
||||
placeholder={
|
||||
'Autonomous: log + alert. Needs approval: drive the actuator. E-stop: operator halts actuation at any time.\n\n' +
|
||||
'Failure states → response:\n' +
|
||||
'• sensor disconnected / stuck value / drifting → mark UNKNOWN, never "nominal"\n' +
|
||||
'• reading older than 60 s → treat as no reading\n' +
|
||||
'• cloud unreachable → decide on-board, flag reduced confidence\n' +
|
||||
'• agent unsure → escalate to a human, do not actuate'
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-end pt-2">
|
||||
<Button size="lg" disabled={!ready} onClick={onProceed}>
|
||||
Proceed to ADD builder →
|
||||
</Button>
|
||||
</div>
|
||||
) : (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle className="text-base text-muted-foreground">What’s next</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<p className="text-sm text-muted-foreground leading-relaxed">
|
||||
Try all three prompts above. Once your agent has run each one successfully, we’ll
|
||||
capture your domain’s skills and policies here.
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
)}
|
||||
</section>
|
||||
</main>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user