npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@agent-assistant/core

v0.4.35

Published

Assistant definition, lifecycle, and runtime composition for Agent Assistant SDK

Readme

@agent-assistant/core

@agent-assistant/core is the root composition package for Agent Assistant SDK. It defines the assistant contract, creates the runtime, dispatches normalized inbound messages to capability handlers, and emits outbound events through injected adapters.

The package is TypeScript-first, has no cloud assumptions, and does not implement sessions, surfaces, memory, routing, or product logic. Those concerns stay in later packages and integrate through abstract contracts defined here.

What It Owns

  • AssistantDefinition for assistant identity, capabilities, hooks, runtime constraints, and traits
  • createAssistant() for constructing the runtime with injected inbound and outbound adapters
  • AssistantRuntime lifecycle methods: start(), stop(), dispatch(), emit(), register(), get(), and status()
  • capability dispatch with hook support, timeout handling, and concurrency limiting
  • outbound targeting by surfaceId or session fanout through an abstract sessions subsystem
  • storing, freezing, and exposing TraitsProvider on the runtime definition (store and expose — never interpret)

What It Does Not Own

  • relay transport, HTTP servers, sockets, or surface normalization
  • session creation or session lifecycle rules
  • memory persistence or retrieval
  • model routing, policy enforcement, or coordination logic
  • product-specific prompts, workflows, or adapters

Installation

npm install

From the package directory:

cd packages/core
npm install
npm test
npm run build

Public API

import {
  AssistantDefinitionError,
  OutboundEventError,
  createAssistant,
  type AssistantDefinition,
  type InboundMessage,
  type OutboundEvent,
} from "@agent-assistant/core";

createAssistant(definition, adapters)

Creates an AssistantRuntime from a validated assistant definition and two injected adapters:

  • inbound.onMessage(handler) and inbound.offMessage(handler) connect normalized inbound messages into core
  • outbound.send(event) delivers targeted outbound messages
  • outbound.fanout(event, surfaceIds) is optional and used for session fanout when available

The runtime is created in the created state. Call start() before dispatching messages.

Runtime Behavior

Lifecycle

  • start() is idempotent while started
  • stop() is idempotent after stop
  • a stopped runtime cannot be restarted
  • status() returns readiness, startup time, registered subsystems, registered capabilities, and current in-flight handler count

Dispatch

  • dispatch(message) runs the pre-dispatch onMessage hook when defined
  • returning false from onMessage drops the message without invoking a capability
  • missing capabilities do not throw from dispatch(); they report through onError
  • capability failures and timeouts report through onError
  • concurrency is limited by constraints.maxConcurrentHandlers and extra dispatches queue in FIFO order

Emit

  • emit({ surfaceId, text }) performs a targeted send
  • emit({ sessionId, text }) resolves the registered sessions subsystem and fans out to its attachedSurfaces
  • emit() throws OutboundEventError when neither surfaceId nor sessionId is present

Core keeps the sessions contract abstract. The runtime expects a subsystem registered under the string key sessions with either:

runtime.register("sessions", {
  async getSession(sessionId: string) {
    return {
      attachedSurfaces: ["surface-a", "surface-b"],
    };
  },
});

or:

runtime.register("sessions", {
  async get(sessionId: string) {
    return {
      attachedSurfaces: ["surface-a", "surface-b"],
    };
  },
});

Example

import { createAssistant, type InboundMessage } from "@agent-assistant/core";

const runtime = createAssistant(
  {
    id: "assistant-1",
    name: "Example Assistant",
    capabilities: {
      reply: async (message: InboundMessage, context) => {
        context.log.info("handling inbound message");
        await context.runtime.emit({
          surfaceId: message.surfaceId,
          text: `Echo: ${message.text}`,
        });
      },
    },
  },
  {
    inbound: {
      onMessage(handler) {
        void handler;
      },
      offMessage(handler) {
        void handler;
      },
    },
    outbound: {
      async send(event) {
        console.log("send", event);
      },
    },
  },
);

await runtime.start();

Traits

AssistantDefinition accepts an optional traits field of type TraitsProvider from @agent-assistant/traits. Core stores and freezes the provider during assembly. It does not read, branch on, or interpret any trait values.

import { createTraitsProvider } from "@agent-assistant/traits";
import { createAssistant } from "@agent-assistant/core";

const runtime = createAssistant(
  {
    id: "sage-assistant",
    name: "Sage",
    traits: createTraitsProvider(
      { voice: "concise", formality: "professional", proactivity: "medium", riskPosture: "moderate" },
      { preferMarkdown: true, preferredResponseLength: 800 },
    ),
    capabilities: {
      reply: async (message, context) => {
        // Capability handlers access traits as read-only data
        const voice = context.runtime.definition.traits?.traits.voice;
        const preferMarkdown = context.runtime.definition.traits?.surfaceFormatting?.preferMarkdown;
        // Surface formatting decisions live here — not in core
        void voice; void preferMarkdown;
      },
    },
  },
  adapters,
);

traits is optional. Existing definitions without traits work without modification.

@agent-assistant/traits is a peer dependency. Consumers that do not use traits do not need to install it.

Development

  • npm test runs the isolated Vitest suite for WF-1, WF-2, WF-4, and WF-5 core workflows
  • npm run build emits dist/ declarations and JavaScript via tsc

CORE_PACKAGE_IMPLEMENTED