Skip to content
Night Owls.dev
Jump to a page

@nightowlsdev/runner-nextjs

Runner

The interactive runner for Night Owls, Next.js App Router routes that authenticate server-side and stream a swarm run to the browser as an AI SDK v7 UI Message Stream.

What it does

`createNextjsRunner({ swarm | engine, auth, storage, background? })` returns a core `Runner` plus nine App Router route factories: `chatRoute()` (POST /api/swarm/chat → authenticate, build SwarmContext from AuthContext only, `engine.run()`, SSE), `resumeRoute()` (POST /api/swarm/resume → authenticate, authorize the typed follow-up cross-tenant, recover the run, `engine.resume()`, SSE), `eventsRoute()` (GET /api/swarm/events/[id] → hydrate `events.list` for dedup-by-seq reconnect), `historyRoute()` and `threadEventsRoute()` (GET .../history|thread-events/[id] → the message history / full SwarmEvent log for a thread, to rebuild the rich timeline on reload), `scratchpadRoute()` (GET .../scratchpad/[id] → the public scratchpad section), `activeRoute()` (GET .../active/[id] → in-flight runs for a container), `threadsRoute()` (GET .../threads), and `agentsRoute()` (GET .../agents); `handlers()` exposes all eight raw handler functions for hosts that wire their own routes. It's a pure transport adapter that projects each typed `SwarmEvent` onto a custom AI SDK v7 `data-<name>` UI Message Stream part (status as transient, question/answer/tool parts durable). Identity is server-only (forged tenant/userId in the body is ignored; runId is server-minted). `ai` (^7) is a required peer; `next` (>=15) is an optional types-only peer, handlers are plain Request→Response functions and `next` is never imported at runtime (the engine wall, no `@mastra/*` either). Durable execution is now opt-in IN this runner: pass `background: createBackgroundRunner(...)` and `chatRoute` ENQUEUES the run on it (returns `{ runId }` JSON the react client subscribes/hydrates) instead of streaming SSE, so the run outlives the request; `enqueue()` delegates to that background runner and only throws when one isn't wired.

Install

pnpm add @nightowlsdev/runner-nextjs

Key exports

  • createNextjsRunner
  • skillStoreRoutes() (FR-040: ten skill-store route groups)
  • connectionsRoutes() (FR-043: connections plus the HTTP-only MCP registry)
  • streamEvents
  • projectEvent
  • nightOwlsPlugin
  • NextjsRunner
  • NextjsRunnerOpts

Usage

runner-nextjs.ts
// app/api/swarm/chat/route.ts
import { createNextjsRunner } from "@nightowlsdev/runner-nextjs";

const runner = createNextjsRunner({ swarm, auth, storage });

export const POST = runner.chatRoute();   // streams an AI SDK v7 UI Message Stream
// resumeRoute() and eventsRoute() wire the other two App Router endpoints.