The real power of Radzor is chaining components together. Each component's manifest declares its inputs, outputs, and composability — your LLM (or you) reads these to wire them into a pipeline.
Every component has a composability.connectsTo field in its manifest. This declares which outputs connect to which inputs on other components:
// @radzor/speech-to-text manifest
"composability": {
"connectsTo": [{
"output": "transcriptionResult",
"compatibleWith": ["@radzor/llm-completion.action.complete.prompt"],
"mapField": "text"
}]
}This tells you (and your LLM): "extract .textfrom the transcription result and pass it to llm-completion's complete() action as the prompt."
The mapField makes wiring deterministic — no guessing which field to extract from a complex output object. Combined with inline fields on outputs, an LLM can auto-wire the entire pipeline from manifests alone.
Components have a runtime field: Server, Browser, or Universal.
When a pipeline mixes browser and server components, you need a bridge — HTTP upload, WebSocket, or Server-Sent Events. The manifest marks these edges with "runtime": "cross-environment".
Every Radzor pipeline follows the same 3 steps:
inputs[].envVar for the right env variable namesmapField to extract the right field from complex outputsCheck outputs[].fields to see the exact shape of complex return types. The mapField on composability edges tells you which field to extract (e.g. result.content, result.text) — no guessing required.
Capture voice → transcribe → generate response → speak it back
OPENAI_API_KEY// 1. Browser: capture audio
const capture = new AudioCapture({ sampleRate: 16000, codec: "opus" });
await capture.startRecording();
const blob = await capture.stopRecording();
// 2. Send to server via HTTP
const form = new FormData();
form.append("audio", blob, "recording.webm");
const res = await fetch("/api/voice", { method: "POST", body: form });
const { text, audio } = await res.json();
// --- Server (API route) ---
// 3. Transcribe
const stt = new SpeechToText({ provider: "openai", apiKey: process.env.OPENAI_API_KEY! });
const { text: transcript } = await stt.transcribe(audioBuffer);
// 4. Generate response
const llm = new LLMCompletion({ provider: "openai", apiKey: process.env.OPENAI_API_KEY!, model: "gpt-4o" });
const reply = await llm.complete(transcript);
// 5. Synthesize speech
const tts = new TextToSpeech({ provider: "openai", apiKey: process.env.OPENAI_API_KEY! });
const audio = await tts.synthesize(reply.content);
return Response.json({ text: reply.content, audio: Buffer.from(audio).toString("base64") });Semantic search over documents → augment LLM context
OPENAI_API_KEYconst store = new EmbeddingsStore({
provider: "openai", apiKey: process.env.OPENAI_API_KEY!, dimensions: 1536
});
// Index documents (one-time)
await store.add("doc1", "Your document content here...");
// Query
const results = await store.search("user question", 3);
const context = results.map(r => r.content).join("\n\n");
const llm = new LLMCompletion({
provider: "openai", apiKey: process.env.OPENAI_API_KEY!, model: "gpt-4o",
systemPrompt: `Answer based on this context:\n\n${context}`
});
const answer = await llm.complete("user question");Scrape web pages → extract structured data with LLM → export to CSV
OPENAI_API_KEYconst scraper = new WebScraper({ rateLimit: 2000 });
const page = await scraper.scrape("https://example.com/products", {
selectors: { title: "h1", price: ".price", desc: ".description" }
});
const so = new StructuredOutput({
provider: "openai", apiKey: process.env.OPENAI_API_KEY!, model: "gpt-4o"
});
const products = await so.extract(page.text, {
type: "array", items: {
type: "object",
properties: { name: { type: "string" }, price: { type: "number" }, category: { type: "string" } }
}
});
const csv = new CSVExport();
const csvString = csv.generate(products, {
columns: ["name", "price", "category"], headers: true
});radzor graphAfter installing components, run radzor graph to see the data-flow DAG. It resolves composability.connectsTo between installed components and warns about cross-runtime connections.
$ npx radzor@latest graph
Component Graph
[browser] @radzor/audio-capture
[server] @radzor/speech-to-text
[server] @radzor/llm-completion
[server] @radzor/text-to-speech
Data Flow
@radzor/audio-capture (audioBlob) ──▶ @radzor/speech-to-text (action.transcribe.audio)
@radzor/speech-to-text (transcriptionResult.text) ──▶ @radzor/llm-completion (action.complete.prompt)
@radzor/llm-completion (completionResult.content) ──▶ @radzor/text-to-speech (action.synthesize.text)
⚠ Cross-runtime: audio-capture [browser] → speech-to-text [server]Use --mermaid to export as a Mermaid diagram for docs or READMEs.
With envVar, fields, and mapField, an LLM can auto-wire a full pipeline from manifests alone — no need to read integration.md or source code.
Key fields: inputs[].envVar (env variable names), outputs[].fields (output object shapes), composability.mapField (field extraction), runtime (browser/server/universal).