Skip to content
Night Owls.dev
Jump to a page

@nightowlsdev/core

EngineMastra

The engine core: define agents, skills, tools and swarms, then run them, the @mastra-backed brain behind every Night Owls host.

What it does

@nightowlsdev/core is the runtime heart of Night Owls. You declare tools (defineTool), bundle them into skills (defineSkill), declare agents with a personality and skill set (defineAgent), and compose them into a runnable swarm (defineSwarm); the SwarmEngine then executes runs and durable resumes, emitting a typed SwarmEvent stream. It also bundles the cross-cutting machinery hosts configure on a swarm: cost/budget governance (CostGovernor, per-delegate budgets, price tables), the Swift/Genius cheap-model tier router, telemetry composition, run-scoped secrets, an in-memory storage/container floor, and the decision-hook substrate (re-exported from @nightowlsdev/hooks so hosts wire SwarmConfig.hooks from one import). It depends on @mastra/* internally but is built so its public .d.ts stays engine-vendor-free (the engine wall), adapters and UI packages only ever see Night Owls types.

Install

pnpm add @nightowlsdev/core

Key exports

  • defineTool
  • defineSkill
  • defineAgent
  • defineSwarm
  • defineRule
  • defineWorkflow
  • SwarmEngine
  • engine.listGrantHolders() (FR-043: who currently holds a capability)
  • CostGovernor
  • resolveTier
  • customTelemetry
  • RowCache
  • InMemoryStorage
  • composeSystemPrompt
  • HookDispatcher / createHookDispatcher / defineHook (re-exported from hooks)
  • deny / ask / ALLOW / ALLOW_TOOL / DEFAULT_READ_ONLY_TOOLS (re-exported from hooks)
  • hook types: HookDecision, SwarmHooks, PreGenerationHook, PreToolCallHook, GuardMutationHook, ToolApprovalPolicy (re-exported from hooks)
  • ev / isEvent

Usage

core.ts
import { defineTool, defineSkill, defineAgent, defineRule, defineWorkflow, defineBundle, defineSwarm, SwarmEngine } from "@nightowlsdev/core";
import { z } from "zod";

const greet = defineTool({
  name: "greet",
  description: "Greet a person by name.",
  inputSchema: z.object({ name: z.string() }),
  outputSchema: z.object({ greeting: z.string() }),
  execute: async ({ name }) => ({ greeting: `Hello, ${name}!` }),
});

const helper = defineAgent({
  slug: "helper",
  role: "orchestrator",
  personality: "A friendly assistant.",
  capabilities: [],
  skills: [defineSkill(greet)],
  delegates: [],
  modelId: "tier:",
});

// Rules: `advise` is injected into the prompt; `enforce` gates a tool call (deny / ask the human).
const citeSources = defineRule({
  id: "cite-sources",
  statement: "Always cite your sources.",
  when: {},
  level: "advise",
});

// Workflows. An `advisory` procedure is injected as a suggested play (the LLM may deviate); a `strict`
// procedure is executed step-by-step by the engine step-driver and run by name via RunInput.workflow.
const intake = defineWorkflow({
  name: "intake",
  compliance: "strict",
  description: "Triage the request, then greet the user by name.",
  steps: [
    { id: "triage", agent: "helper", instruction: "classify the request", next: "greet" },
    { id: "greet", agent: "helper", instruction: "greet the user" },
  ],
});

const swarm = defineSwarm({ agents: [helper], rules: [citeSources], workflows: [intake] });
const engine = new SwarmEngine(swarm);

// Free-form turn (default): engine.run({ message: "hi" }, ctx)
// Run the strict workflow deterministically: engine.run({ message: "hi", workflow: "intake" }, ctx)

// Reuse a whole crew (agents + rules + workflows + connector grants) across projects as a
// capability bundle, closure-validated at author time. Full guide → /docs/capability-bundles
const studio = defineBundle({ slug: "content-studio", agents: [helper] });