Components
Add AI capabilities with gencow add — AI, speech, RAG, Memory, Tools, Guardrails, and more
The gencow add command installs pre-built AI components into your project. Each component adds files to gencow/ and installs required dependencies.
Usage
# Add a single component
npx gencow@latest add AI
# Add multiple at once
npx gencow@latest add AI RAG Reranker
# Dependencies auto-resolve (RAG requires AI → AI is added automatically)
npx gencow@latest add RAG # → also installs AIAvailable Components
| # | Component | Description | Requires |
|---|---|---|---|
| 1 | AI | Vercel AI SDK wrapper (chat, embeddings, structured output, images, speech helpers; feature-flagged cloud text streaming) | — |
| 2 | Agent | Durable workflow agent starter with injectable AI SDK model | AI |
| 3 | Tools | AI Tool Calling with ctx integration |
AI |
| 4 | RAG | Document ingestion + semantic search with injectable embedding/answer models | AI |
| 5 | Memory | Agent memory (episodic/semantic/procedural) with injectable extraction/embedding models | AI |
| 6 | Reranker | Dedicated AI SDK reranking with GPT fallback | AI |
| 7 | Guardrails | Input/output safety filters (PII, topic blocking) with injectable model | AI |
| 8 | Prompts | Reusable prompt templates | — |
| 9 | Parsers | PDF/HTML/CSV file parsing | — |
| 10 | Analytics | LLM call tracking | AI (coming soon) |
Component Details
AI — Core Engine
npx gencow@latest add AICreates gencow/ai.ts (and related generated files). Import from gencow/ai.ts —
see AI Engine for model catalog, billing, structured output,
and the full runtime contract.
gencow/ai.ts exposes two APIs. Prefer the provider API for new code; the
facade API is a narrower compatibility layer for simple handlers and other
Gencow components.
Provider API (recommended):
import { embed, generateText } from "ai";
import { createGencowAI } from "./ai";
const gencow = createGencowAI();
await generateText({
model: gencow.languageModel("gpt-5.4-mini"),
messages: [{ role: "user", content: "Hello" }],
});
await embed({
model: gencow.embeddingModel("text-embedding-3-small"),
value: "Hello, world!",
});pgvector schema match required: if you later store these embeddings in pgvector, the embedding model dimension must match the DB column size. The generated RAG and Memory starter schemas use
vector(1536).
Facade API:
import { ai } from "./ai";
ai.chat({ system, messages, model }) // Non-streaming response
ai.stream({ system, messages, model }) // Text streaming when local direct mode or cloud streaming is enabled
ai.embed(text) // Generate embeddings
ai.image.generate({ prompt, model }) // Generate images with GPT Image
ai.vision.extractText({ image, mediaType }) // Extract text from image input
ai.speech.transcribe({ storageId, model }) // Start async STT from a private storage object
ai.speech.waitForTranscript(jobId) // Poll until the STT job reaches a terminal state
ai.speech.synthesize({ input, voice }) // Generate private TTS audio outputInstalled deps: ai, @ai-sdk/openai
Env required: OPENAI_API_KEY (local only — auto in cloud)
Speech helpers are proxy-backed even in development because they need Gencow
storage lookup, media preprocessing, async job state, and service-credit billing.
For speech-to-text, upload audio or video to private app storage first and pass
only the resulting storageId; do not send raw multipart audio to the AI proxy.
Generated AI Factories
Generated AI-dependent components now follow the same dual-surface pattern as
gencow/ai.ts:
- Provider API: call
createX(...)and inject models fromcreateGencowAI(). - Facade API: import the generated singleton (
rag,memory,guardrails,reranker,runAgent) for compatibility.
Use the factory when a handler needs explicit model selection, tests need mock models, or you are composing with AI SDK helpers directly. Existing singleton imports remain stable for generated starter code.
Agent — Workflow Agent
gencow add AgentCreates gencow/agent.ts.
Provider API (recommended):
import { createGencowAI } from "./ai";
import { createWorkflowAgent } from "./agent";
const gencow = createGencowAI();
export const customRunAgent = createWorkflowAgent({
model: gencow.languageModel("gpt-5.4-mini"),
});Use the factory when you want explicit model selection or test doubles.
Facade API:
import { runAgent } from "./agent";
// Backward-compatible singleton workflow.
// Existing generated apps can keep exporting or starting runAgent directly.
export { runAgent };Use useWorkflow(api.workflows.get, run.id) and workflows.signal to observe
or resume durable agent runs.
Tools — AI Function Calling
gencow add ToolsCreates gencow/tools.ts with defineTools() — a thin wrapper around AI SDK's
tool() that injects ctx into handlers.
Provider API (use AI SDK tool() directly):
import { generateText, tool } from "ai";
import { z } from "zod";
import { createGencowAI } from "./ai";
const gencow = createGencowAI();
const getWeather = tool({
description: "Get weather for a city",
parameters: z.object({ city: z.string() }),
execute: async ({ city }) => `Weather in ${city}: 22°C, sunny`,
});
const result = await generateText({
model: gencow.languageModel("gpt-5.4-mini"),
messages: [{ role: "user", content: "What's the weather in Seoul?" }],
tools: { getWeather },
});Facade API (with defineTools + ai.chat()):
import { z } from "zod";
import { ai } from "./ai";
import { defineTools } from "./tools";
const tools = defineTools(ctx, {
getWeather: {
description: "Get weather for a city",
parameters: z.object({ city: z.string() }),
handler: async (ctx, { city }) => {
return `Weather in ${city}: 22°C, sunny`;
},
},
});
const result = await ai.chat({
messages: [{ role: "user", content: "What's the weather in Seoul?" }],
tools,
});
console.log(result.text);RAG — Document Search
gencow add RAGCreates gencow/rag.ts + gencow/schema-rag.ts.
Provider API (recommended):
import { createGencowAI } from "./ai";
import { createRag } from "./rag";
const gencow = createGencowAI();
const customRag = createRag({
embeddingModel: gencow.embeddingModel("text-embedding-3-small"),
answerModel: gencow.languageModel("gpt-5.4-mini"),
});
await customRag.ingest(ctx, "manual.md", "Document text content...");
const hits = await customRag.retrieve(ctx, "What is Gencow?");
// → [{ chunk, source, similarity, metadata }]Use the factory when you want explicit embedding/answer model control.
The generated schema-rag.ts starter uses embedding: vector(1536), so if you
change the embedding model to one with a different output dimension, update the
schema and re-index stored vectors.
Facade API:
import { rag } from "./rag";
await rag.ingest(ctx, "manual.md", "Document text content...");
const answer = await rag.ask(ctx, "What is Gencow?");
const grounded = await rag.askGrounded(ctx, "What is Gencow?", {
corpus: "default",
visibility: "shared",
});Important: Import
schema-rag.tsin your mainschema.tsto create the required DB tables.
rag.ingest()writes to the localrag_documentstable. Grounded helpers such asrag.askGrounded()andreranker.answerGrounded()read canonical Phase 2rag_*corpora populated throughdocuments.ingest.*.
Memory — Agent Memory
gencow add MemoryCreates gencow/memory.ts + gencow/schema-memory.ts.
Provider API (recommended):
import { generateText } from "ai";
import { createGencowAI } from "./ai";
import { createMemory } from "./memory";
const gencow = createGencowAI();
const customMemory = createMemory({
extractionModel: gencow.languageModel("gpt-5.4-mini"),
embeddingModel: gencow.embeddingModel("text-embedding-3-small"),
});
const memCtx = await customMemory.buildContext(ctx, userId, sessionId, query);
const result = await generateText({
model: gencow.languageModel("gpt-5.4-mini"),
system: `You are a helpful assistant.
${memCtx.toSystemPrompt()}`,
messages: [...memCtx.recentMessages, { role: "user", content: query }],
});
await customMemory.extract(ctx, userId, `User: ${query}
Assistant: ${result.text}`);buildContext() returns recentMessages, longTermFacts, and
toSystemPrompt().
The generated schema-memory.ts starter uses embedding: vector(1536), so any
embedding model change must stay dimension-compatible or be paired with a schema
change and vector migration/re-index.
Facade API:
import { ai } from "./ai";
import { memory } from "./memory";
const memCtx = await memory.buildContext(ctx, userId, sessionId, query);
const result = await ai.chat({
system: `You are a helpful assistant.
${memCtx.toSystemPrompt()}`,
messages: [...memCtx.recentMessages, { role: "user", content: query }],
});
await memory.extract(ctx, userId, `User: ${query}
Assistant: ${result.text}`);
await memory.saveSession(ctx, sessionId, userId, [
...memCtx.recentMessages,
{ role: "user", content: query },
{ role: "assistant", content: result.text },
]);| Type | Purpose | Example |
|---|---|---|
| Episodic | Conversation history | "Last time we discussed…" |
| Semantic | Facts and knowledge | "User prefers dark mode" |
| Procedural | Learned procedures | "When user asks X, do Y" |
Reranker — Result Quality
gencow add RerankerCreates gencow/reranker.ts.
Provider API (recommended):
import { rerank } from "ai";
import { createGencowAI } from "./ai";
import { createReranker } from "./reranker";
const gencow = createGencowAI();
const ranked = await rerank({
model: gencow.rerankingModel("Cohere-rerank-v4.0-fast"),
query,
documents: searchResults.map((item) => item.chunk),
topN: 5,
});
const customReranker = createReranker({
rerankingModel: gencow.rerankingModel("Cohere-rerank-v4.0-fast"),
fallbackModel: gencow.languageModel("gpt-5.4-mini"),
});Use direct AI SDK rerank() for the primitive, or createReranker() when you
want the generated compatibility helpers.
Facade API:
import { rag } from "./rag";
import { reranker } from "./reranker";
const reranked = await reranker.rerank(query, searchResults, { topK: 5 });
const results = await reranker.searchAndRerank(ctx, rag, query);
const grounded = await reranker.answerGrounded(ctx, query, {
corpus: "default",
visibility: "shared",
});gencow.rerankingModel(...) is proxy-backed. In local direct mode without the
Gencow AI proxy, pure reranking should fail fast. The generated reranker
starter can still use its explicit fallback-model path for compatibility.
Guardrails — Safety Filters
gencow add GuardrailsCreates gencow/guardrails.ts.
Provider API (recommended):
import { createGencowAI } from "./ai";
import { createGuardrails } from "./guardrails";
const gencow = createGencowAI();
const customGuardrails = createGuardrails({
model: gencow.languageModel("gpt-5.4-mini"),
});
const safe = await customGuardrails.validateInput(userText, {
maskPII: true,
blockTopics: ["politics"],
});
const checked = await customGuardrails.validateOutput(aiResponse, {
maxLength: 2000,
bannedPatterns: [/api[_-]?key/i],
});Facade API:
import { guardrails } from "./guardrails";
const safe = await guardrails.validateInput(userText, {
maskPII: true,
blockTopics: ["politics"],
});
const wrapped = await guardrails.wrap(
async (sanitized) => myFunction(sanitized),
userText,
{ maskPII: true },
{ maxLength: 2000 },
);Prompts — Reusable Templates
gencow add PromptsCreates gencow/prompts.ts. Pre-built prompt templates:
import { ragQAPrompt, summarizePrompt, classifyPrompt } from "./prompts";
// RAG Q&A
const prompt = ragQAPrompt({
question: "What is Gencow?",
context: "Retrieved context here...",
});
// Summarization
const prompt = summarizePrompt({ text: "Long text to summarize..." });
// Classification
const prompt = classifyPrompt({
text: "I love this product!",
categories: ["positive", "negative", "neutral"],
});Parsers — File Parsing
gencow add ParsersCreates gencow/parsers.ts. Parse various file formats:
// PDF
const text = await parsers.pdf(buffer);
// HTML
const text = await parsers.html(htmlString);
// CSV
const rows = await parsers.csv(csvString);
// Auto-detect by filename
const text = await parsers.auto("document.pdf", buffer);
// RAG integration
await rag.ingest(ctx, "manual.pdf", await parsers.pdf(buffer));Installed deps: pdf-parse
Dependency Resolution
Components automatically install their dependencies:
gencow add RAG
# → Also installs AI (because RAG requires AI)gencow add RAG Reranker Memory
# → Installs AI first, then RAG, Reranker, MemoryAfter Installation
# README is auto-updated with new component docs
gencow devEach component's usage is added to the auto-generated gencow/README.md.
Next Steps
- AI Engine — Provider vs facade APIs, models, billing, structured output
- RAG & Memory — Deep dive into document search and agent memory
- CLI Reference — All CLI commands