apps/docs/skills/ui-integration/SKILL.md
Wire agents into React, Vue, and Svelte frontends with streaming hooks, and set up server-side Next.js App Router or Express API routes using AgentStream.toSSE().
npx skillsauth add tylerjrbuell/reactive-agents-ts ui-integrationInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Produce a working server-side API route using AgentStream.toSSE() and a client-side component using the appropriate framework hook, connected end-to-end.
// app/api/agent/route.ts
import { ReactiveAgents, AgentStream } from "@reactive-agents/runtime";
export async function POST(req: Request) {
const { prompt } = await req.json();
const agent = await ReactiveAgents.create()
.withProvider("anthropic")
.withReasoning({ defaultStrategy: "adaptive", maxIterations: 10 })
.withTools({ allowedTools: ["web-search", "checkpoint"] })
.build();
return AgentStream.toSSE(agent.runStream(prompt));
}
import { useAgentStream } from "@reactive-agents/react";
function Chat() {
const { text, status, error, run, cancel } = useAgentStream("/api/agent");
return (
<div>
<button onClick={() => run("Explain quantum entanglement")} disabled={status === "streaming"}>
Ask
</button>
{status === "streaming" && <button onClick={cancel}>Stop</button>}
<p>{text}</p>
{error && <p style={{ color: "red" }}>{error.message}</p>}
</div>
);
}
import { useAgentStream, useAgent } from "@reactive-agents/react";
// Streaming — token-by-token delivery
const {
text, // string — accumulated text so far
events, // AgentStreamEvent[] — all events received
status, // "idle" | "streaming" | "completed" | "error"
error, // Error | null
output, // string | null — final output (set on completion)
run, // (prompt: string) => void — start the agent
cancel, // () => void — abort the stream
} = useAgentStream("/api/agent");
// One-shot — waits for full result
const {
output, // string | null — final output
loading, // boolean
error, // Error | null
run, // (prompt: string) => Promise<void>
} = useAgent("/api/agent");
<script setup lang="ts">
import { useAgentStream, useAgent } from "@reactive-agents/vue";
// Same return shape as React hooks
const { text, status, error, run, cancel } = useAgentStream("/api/agent");
const { output, loading, error: err, run: fetch } = useAgent("/api/agent");
</script>
<template>
<button @click="run('Explain AI')">Ask</button>
<p>{{ text }}</p>
</template>
<script lang="ts">
import { createAgentStream, createAgent } from "@reactive-agents/svelte";
// Returns a Svelte readable store
const agent = createAgentStream("/api/agent");
// $agent: AgentStreamState = { text, status, error, run, cancel }
const oneShot = createAgent("/api/agent");
// $oneShot: AgentState = { output, loading, error, run }
</script>
<button on:click={() => $agent.run("Explain AI")}>Ask</button>
<p>{$agent.text}</p>
{#if $agent.status === "streaming"}<span>●</span>{/if}
// Default: "tokens" — TextDelta events only (minimal payload)
return AgentStream.toSSE(agent.runStream(prompt));
// Full: all events including phase changes and tool calls
return AgentStream.toSSE(agent.runStream(prompt, { density: "full" }));
// Use "full" density when the UI shows tool usage or reasoning steps
import express from "express";
import { ReactiveAgents, AgentStream } from "@reactive-agents/runtime";
const app = express();
app.use(express.json());
app.post("/api/agent", async (req, res) => {
const { prompt } = req.body;
const agent = await ReactiveAgents.create()
.withProvider("anthropic")
.withReasoning({ defaultStrategy: "adaptive" })
.withTools()
.build();
const stream = agent.runStream(prompt);
for await (const event of stream) {
if (event.type === "TextDelta") {
res.write(`data: ${JSON.stringify(event)}\n\n`);
}
if (event.type === "StreamCompleted") break;
}
res.end();
});
const { events } = useAgentStream("/api/agent");
// Event types when density: "full":
// TextDelta — { type: "TextDelta", content: string }
// ToolCallStart — { type: "ToolCallStart", toolName: string }
// ToolCallResult — { type: "ToolCallResult", toolName: string, result: unknown }
// StreamCompleted — { type: "StreamCompleted", output: string }
// StreamError — { type: "StreamError", error: string }
// StreamCancelled — { type: "StreamCancelled" }
| Package | Exports |
|---------|---------|
| @reactive-agents/react | useAgent, useAgentStream |
| @reactive-agents/vue | useAgent, useAgentStream |
| @reactive-agents/svelte | createAgent, createAgentStream |
| @reactive-agents/runtime | AgentStream (server-side SSE adapter) |
AgentStream.toSSE() returns a Response object compatible with the Web Fetch API — it works in Next.js App Router and edge runtimes directlydensity: "tokens" (default) only sends TextDelta — use density: "full" if the client needs tool call visibilityuseAgent (one-shot) makes a POST and waits for JSON { output: string } — the server route must return JSON, not SSEcancel() sends an AbortSignal to the server — the server route must pass the AbortSignal to agent.runStream() for it to take effectdevelopment
Orient to the Reactive Agents framework, understand the builder API shape, and select the right capability skills for your task.
testing
Enable output verification (hallucination detection, semantic entropy, self-consistency), add post-run verification steps, and run LLM-scored evals across 5 quality dimensions.
data-ai
Configure per-provider behavior, understand streaming quirks, and use the 7-hook adapter system for optimal performance across LLM providers.
data-ai
Configure the 4-layer memory system with SQLite/FTS5/vec storage for persistent agent knowledge that survives sessions.