{notes}
} ); } diff --git a/components/artifacts/steer-card.tsx b/components/artifacts/steer-card.tsx index bd7fe4c..d1b223d 100644 --- a/components/artifacts/steer-card.tsx +++ b/components/artifacts/steer-card.tsx @@ -1,6 +1,8 @@ "use client"; -import type { SubagentArtifactData, TeacherUIMessage } from "@/src/core"; +import { CheckIcon } from "lucide-react"; +import type { ResearchResult, SubagentArtifactData, TeacherUIMessage } from "@/src/core"; +import { isSubagentFailure } from "@/src/core"; import { DemoOutputCard } from "@/components/artifacts/demo-card"; import { ResearchBriefCard } from "@/components/artifacts/job-card"; import { VisualOutputCard } from "@/components/artifacts/visual-card"; @@ -10,10 +12,17 @@ import { VisualOutputCard } from "@/components/artifacts/visual-card"; * * When a background job completes, the wake pipeline injects a STEER message * into the transcript: a user-role UIMessage whose data part - * ("data-subagent-artifact") carries the result. It must NEVER render as a - * learner bubble: the model-facing text part is protocol glue, and the - * artifact itself renders here, by kind, reusing the same artifact cards - * the result always used. + * ("data-subagent-artifact") carries the result. It renders as an artifact — + * NEVER a learner bubble, never wrapped in a message container: + * + * research — a quiet "Research complete" badge. The full brief is TOO LONG + * to inline and the teacher's wake turn weaves it into the lesson anyway; + * it stays persisted in the transcript (the artifact part), so a + * "view full research" affordance can be added later. Failures keep the + * failure card (the brief explains what went wrong). + * demo / visual — the artifact itself (sandboxed iframe / sanitized SVG). + * The sub-agent's verification notes are model-facing glue and do NOT + * render; only a failure note does. */ export function SubagentSteerCard({ message }: { message: TeacherUIMessage }) { const artifactPart = message.parts.find((p) => p.type === "data-subagent-artifact"); @@ -27,10 +36,27 @@ export function SubagentSteerCard({ message }: { message: TeacherUIMessage }) { } switch (data.kind) { case "research": - return{result.notes}
} ); } diff --git a/components/chat.tsx b/components/chat.tsx index 3dbdf3d..22d209d 100644 --- a/components/chat.tsx +++ b/components/chat.tsx @@ -287,21 +287,22 @@ export function Chat({ /> )} - {messages.map((m, mi) => ( + {messages.map((m, mi) => + m.role === "user" && isSubagentSteer(m) ? ( + // Sub-agent delivery (wake-pipeline steer): NO message bubble — the + // artifact card sits in the transcript column directly, full width + // and centered like the teacher's artifacts (contracts.ts "THE ASYNC + // PROTOCOL" §4). +