Skip to content
Warlock.js v4.7.0

@warlock.js/ai

Standalone — usable in any Node project, no @warlock.js/core required.

@warlock.js/ai is the AI orchestration layer of Warlock. It gives you a small ladder of primitives — agents, workflows, supervisors — that share one result envelope, one error hierarchy, one event model, and one persistence story. You pair it with a provider adapter (@warlock.js/ai-openai, @warlock.js/ai-anthropic, etc.) and you have a typed, testable, resumable AI runtime.

The package is provider-agnostic on purpose. The model, the embedder, the pricing — those live in the adapter. The orchestration — tool loops, retries, snapshot resume, structured output, middleware — lives here.

ai.agent() → single LLM turn, tool loop, structured output
ai.workflow() → deterministic multi-step pipeline, resumable
ai.supervisor() → multi-intent router with specialists, iterative
ai.orchestrator() → stateful session-aware orchestration (durable sessions, resume)

Each primitive is an escape hatch to the next rung of complexity. Start at the bottom; graduate up only when you need to. Every primitive returns the same envelope ({ data, error, usage, report }) and exposes .asTool(), so they compose freely.

The four rungs cover the core orchestration shapes, but the package has grown a wider verb set around them — every one returning the same envelope and composing through the same tool surface.

  • ai.team() — a manager + role-named members (builder, reviewer, fixer) with a built-in quality gate. Thin sugar over a supervisor for the review-then-fix and test-then-fix shapes.
  • ai.planner() — an LLM generates an ordered plan over your capabilities, then runs it step by step. The escape hatch for when you can’t name the steps up front.
  • ai.memory() — working (in-run scratch) plus semantic recall across turns, backed by any CacheDriver.
  • ai.rag() — document retrieval: chunk, embed, store, retrieve, rerank, cite. Drop it into an agent’s tools with .asTool().
  • ai.skills() — a runtime skills library: an always-injected metadata catalog plus an on-demand loadSkill tool.
  • ai.prompts — one process-wide name@version prompt registry; a named systemPrompt(...) auto-registers, then resolves / merges / validates / diffs by name (ai.prompt is now a thin facade over it).
  • ai.dataset() and ai.vcr() — evaluation datasets for agent.eval(...) and record/replay of model traffic for deterministic tests.
  • ai.guardrail() — content-intelligence guardrails (moderation, PII, injection, topic) as composed input / output / tool middleware.
  • ai.human — human-in-the-loop tool approval with durable interrupt / resume.

A separate observability package, @warlock.js/ai-panoptic, exports run traces to OpenTelemetry, Langfuse, the console, a file, or a queryable store.

  • Standalone. Drop it into a CLI, a worker, a script, an existing Express app. No Warlock framework required.
  • Typed end to end. ai.agent({ output: schema }) flows the schema’s inferred type through to result.data. Same for ai.workflow<TInput, TOutput, TState>.
  • execute() never throws. Failures funnel into result.error as a typed AIError subclass. You branch on instanceof or on the stable error.code string.
  • One result shape. { data, error, usage, report } — agents, workflows, supervisors. Cost rolls up the tree.
  • Persistence is delegated. Snapshot resume + semantic cache both accept any CacheDriver from @warlock.js/cache. The AI package owns no storage.
  • Logging is delegated. Every primitive emits through the log singleton from @warlock.js/logger. Configure channels once at boot; the framework picks it up.
  • Installation — install the core package plus a provider adapter.
  • Pick a provider — OpenAI vs Anthropic vs Bedrock vs Google vs Ollama.
  • Your first agent — five-minute walkthrough from zero to a streaming agent.
  • Troubleshooting — the first errors you’ll hit and the one-line fix for each.

There are two reading orders, depending on what you need. For the mental model — why each primitive exists and how they nest — read Architecture Concepts first; those pages are the why. For the how-to — the calls you make day to day — each domain section below is the how, ordered so you can read it top to bottom. The two intentionally overlap: a concept page explains a primitive, its sibling how-to page runs it.

  • Architecture Concepts — the mental model behind agents, workflows, supervisors, orchestrators, memory, planner, middleware.
  • Agents — run one agent well: streaming, structured output, reasoning control, sub-agents, serving over SSE.
  • Tools & Capabilities — define your own tools, use the built-in belt, connect MCP servers, jail a workspace, load runtime skills.
  • Orchestration — the ladder above a single agent: workflows, supervisors, teams, orchestrators.
  • Prompts — write, version, validate, and compile system prompts.
  • RAG & Knowledge — retrieval pipelines, loaders and stores, hybrid ranking, embeddings.
  • Modalities — images, speech, transcription, realtime and video.
  • Reliability & Safety — typed errors, durable resume, persistence, budgets, guardrails, human-in-the-loop, SSRF and redaction.
  • Testing & Evaluation — datasets and evals as a CI gate, record/replay cassettes.
  • Observability — the observer seam and @warlock.js/ai-panoptic traces.
  • Best Practices — opinionated pillar pages: what a senior dev does, and why.
  • Recipes — copy-paste solutions for common patterns.
  • Reference — every public export grouped by primitive.
import { ai } from "@warlock.js/ai";
import { OpenAISDK } from "@warlock.js/ai-openai";
const openai = new OpenAISDK({ apiKey: process.env.OPENAI_API_KEY! });
const myAgent = ai.agent({
model: openai.model({ name: "gpt-4o-mini" }),
systemPrompt: "You are a concise senior TypeScript engineer.",
});
const { text, usage, error } = await myAgent.execute("Why use generics?");
if (error) {
console.warn(error.code, error.category);
} else {
console.log(text, usage.total);
}

No try/catch. No exception leaks. Typed errors with stable codes. That’s the contract you get from every primitive in this package.