Skip to content
Night Owls.dev
Jump to a page

@nightowlsdev/engine-ai-sdk

EngineNative

The second native engine, a governed ai@^7 streamText loop. Single-agent v1 (no delegation/workflows/semantic recall yet), full HITL + governance, tier-3 events.

What it does

**Use this when:** you want the swarm to run on the Vercel AI SDK's `streamText` loop (`ai@^7`) instead of Mastra — the same governance, a different underlying loop — and one agent per swarm is enough for now. **How.** `aiSdkEngine()` into `defineSwarm({ engine })` (or `owl install engine-ai-sdk`). Pass `aiSdkEngine({ durable: true })` to turn on durable park/resume when your storage persists snapshots across processes (e.g. `storage-supabase`); the default keeps resumes non-durable. **What you get / what it can't do yet.** The full governance plane, verbatim: fail-closed tool gate, cost caps, secrets, telemetry, tier-3 events. Tool approvals map onto `ai@7`'s native per-tool `needsApproval`, backstopped engine-side so a deny can never reach the model as a question. The one real limit is that **v1 is single-agent** — `delegation`, `workflows`, and semantic recall are all `false`, so a multi-agent pack still needs `engine-mastra` until `ask_slug`-based delegation ships in v1.1. *Under the hood:* it's a from-scratch loop that passes the shared `verifyEngineContract` conformance suite plus a golden-trajectory parity gate against `engine-mastra`; history/reads derive from the persisted event log, not a separate message store.

Install

pnpm add @nightowlsdev/engine-ai-sdk

Key exports

  • aiSdkEngine
  • AiSdkEngine
  • AI_SDK_ENGINE_CAPABILITIES
  • nightOwlsPlugin

Usage

engine-ai-sdk.ts
import { defineSwarm } from "@nightowlsdev/core";
import { aiSdkEngine, AI_SDK_ENGINE_CAPABILITIES } from "@nightowlsdev/engine-ai-sdk";

// The second native engine, a governed ai@^7 streamText loop. Single-agent v1:
// no delegation/workflows/semantic recall yet (multi-agent packs still need
// engine-mastra). Same governance plane (cost, secrets, tool-approval gate).
const swarm = defineSwarm({ agents, engine: aiSdkEngine() });

// Pass { durable: true } only when your StorageAdapter persists suspend/resume
// snapshots ACROSS PROCESSES (e.g. storage-supabase), otherwise leave the
// default false so runner-background/mcp-server treat resumes as non-durable.
const durableSwarm = defineSwarm({ agents, engine: aiSdkEngine({ durable: true }) });

console.log(AI_SDK_ENGINE_CAPABILITIES.delegation); // false, v1 is single-agent

What it provides

engine-ai-sdk is the second NATIVE engine: a from-scratch swarm loop built directly on the raw Vercel AI SDK (ai@^7's streamText) instead of Mastra. It reuses the SAME governance plane as engine-mastra verbatim — the fail-closed tool gate, cost caps, secrets, tier routing, telemetry — and passes both the shared engine-contract conformance suite and a golden-trajectory parity gate against engine-mastra. v1 is deliberately single-agent: delegation, workflows, and semantic recall are all declared false; you get full HITL, full governance, and tier-3 events, just for one agent.

When to use it

  • You want the loop built on the raw Vercel AI SDK (streamText) rather than Mastra — a lighter, more transparent stack you may already know.
  • Your swarm is single-agent and you want full governance (pre-generation reserve, fail-closed tool gate, cost caps, secrets) plus tier-3 events without pulling in Mastra.
  • You rely on ai@7's native per-tool needsApproval and want it backstopped engine-side by a fail-closed gate so a deny can never reach the model as an approval question.

When not to

  • Your pack is multi-agent — delegation is false here; crews and agents-as-tools still require engine-mastra until ask_slug delegation ships in v1.1.
  • You use defineWorkflow procedures or semantic-recall / working-memory / observational memory — none are ported to this engine in v1.
  • You need the swarm.handoff event or delegation lanes in the UI — this engine's emits deliberately excludes swarm.handoff (delegation is off).

Alternatives

  • engine-mastra (the default)You need delegation, workflows, or semantic recall — the multi-agent / workflow / memory path lives only there today.
  • engine-openai-agentsYou want a native loop on the OpenAI Agents SDK (run()) instead of the raw AI SDK — same full-governance posture, also single-agent v1.
  • The raw ai SDK directlyA one-shot streamText call with no tool gate, cost ceiling, secrets boundary, or resumable transcript — you lose the whole governance plane and the swappable-engine contract.

Strengths

  • Full governance on a non-Mastra stack: preGeneration reserve, fail-closed preToolCall, cost caps, secrets — the same code reused verbatim from core.
  • Tool approvals map onto ai@7's native per-tool needsApproval, backstopped by a fail-closed executeToolWithGate so a deny is never surfaced as a question.
  • History and reads are derived from the persisted event log (no separate message store), and events are tier 3 (13 of 14 types — swarm.handoff excluded because delegation is off).
  • Verified, not assumed: it passes the shared verifyEngineContract suite and a golden-trajectory parity gate against engine-mastra.

Limits & trade-offs

  • Single-agent only in v1 — delegation, workflows, and semantic recall are all false; multi-agent packs still need engine-mastra.
  • Durable cross-process resume is OFF by default — hitl.durableResume is false unless you pass aiSdkEngine({ durable: true }) AND back it with cross-process storage.
  • A documented wire asymmetry vs engine-mastra: on an ask/client resume the built-in ask tool is execute-less here, so no swarm.tool_result is reported for the answered call (a verified parity divergence, not a bug).
  • Requires Node >= 22 and the ai@^7 peer installed alongside it.

How it works

aiSdkEngine({ durable }) returns (opts) => new AiSdkEngine(opts, { durable }) — the same construction contract mastraEngine() follows, from the fully-assembled AssembledEngineOpts defineSwarm hands it. The loop drives ai's streamText directly; tool approvals ride ai@7's native needsApproval with an engine-side fail-closed backstop. durableResume is a per-INSTANCE capability flip, never inferred from the injected StorageAdapter: default false so runner-background and mcp-server treat resumes as non-durable, flipped true only when your storage persists suspend/resume snapshots across processes. AI_SDK_ENGINE_CAPABILITIES is the static descriptor consumers gate on; note that emits is authoritative over the declared tier for which events actually stream.

Examples

Wire the AI-SDK engine (single-agent, full governance)

Same swarm description as any engine; only the loop changes. Requires the ai peer installed.

engine-ai-sdk-example-1.ts
import { defineSwarm } from "@nightowlsdev/core";
import { aiSdkEngine } from "@nightowlsdev/engine-ai-sdk";

export default defineSwarm({
  agents,
  engine: aiSdkEngine(),
});

Opt into durable resume — only with cross-process storage

durableResume is a per-instance flip, not inferred from storage. Pass durable:true only when your StorageAdapter persists snapshots across processes (e.g. storage-supabase).

engine-ai-sdk-example-2.ts
import { defineSwarm } from "@nightowlsdev/core";
import { aiSdkEngine, AI_SDK_ENGINE_CAPABILITIES } from "@nightowlsdev/engine-ai-sdk";

const swarm = defineSwarm({ agents, engine: aiSdkEngine({ durable: true }) });

console.log(AI_SDK_ENGINE_CAPABILITIES.delegation); // false — single-agent v1
console.log(AI_SDK_ENGINE_CAPABILITIES.governance.preToolCall); // "fail-closed"

Doing the parts it doesn't support

  • Multi-agent delegationNot in v1 (delegation: false). Run multi-agent packs on engine-mastra; ask_slug-based delegation for this engine is planned for v1.1.
  • Durable resume across a restartPass aiSdkEngine({ durable: true }) AND inject a StorageAdapter that persists snapshots cross-process (storage-supabase). With in-memory / dev storage, leave the default false so consumers advise resumes are non-durable.
  • Workflows and semantic recallNeither is ported to this engine in v1 (workflows: false; memory.semanticRecall/workingMemory/observational: false). Use engine-mastra for workflow-driven or memory-backed swarms; only history() is available here (event-log-derived).

Related

  • coreThe required base — this engine reuses core's governance plane (hooks, CostGovernor, secrets) verbatim.
  • engine-mastraThe default sibling engine — the multi-agent / workflow / semantic-recall path this engine defers to.
  • engine-openai-agentsThe third native engine, on the OpenAI Agents SDK — same full-governance, single-agent posture on a different stack.
  • storage-supabaseThe cross-process StorageAdapter durableResume needs to actually survive a restart.
  • approval-modesHow the tool-approval gate this engine backstops is configured for a deployment.