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

@statewalker/ai-agent.core

v0.1.1

Published

A TypeScript library for building multi-turn AI agents with persistent state, tool/skill registries, MCP integration, and session management. Built on the [Vercel AI SDK](https://sdk.vercel.ai/).

Readme

@statewalker/ai-agent

A TypeScript library for building multi-turn AI agents with persistent state, tool/skill registries, MCP integration, and session management. Built on the Vercel AI SDK.

The package is framework-free (no workspace / shared-adapters dependencies) — it deals only with the agent loop, state tree, tools, models, and persistence. Application-level concerns (UI, commands, fragment activators) live in the workbench fragments (@statewalker/ai-agent-runtime, @statewalker/ai-config, @statewalker/models-config) and the consuming apps.

Three-tier API

AgentRuntime   ─→   Agent (definition)   ─→   Session (runtime instance)
  • AgentRuntime — project-level entry point. Owns providers, tools, skills, the FilesApi split (system view vs tools view), MCP clients, session storage. Built once; stays alive for the life of the host.
  • Agent — a definition: name, tools whitelist, skills whitelist, system prompt, default model, optional sub-agents. Cheap to construct; agents are loaded from <systemPath>/agents/*.md at build() time and can also be created programmatically.
  • Session — a runtime instance bound to one Agent. Owns the conversation tree, inbox, per-session tool/skill views, and the loop. Persisted by id under <systemPath>/sessions/.

Each Session owns one ContextWindow — the module that, given the current conversation tree and active skills, produces { system, messages } for the next model call. It orchestrates compaction, selection, elision, pin policy, and system-prompt assembly behind one interface, so the agent loop's per-turn code is build → streamText → process. Configured runtime-wide via setSelectionStrategy / setBudgetCompaction; per-agent overrides flow through the agent's selectionStrategy and systemPrompt.

Sub-path exports

| Export Path | Description | |---|---| | @statewalker/ai-agent/runtime | AgentRuntime, Agent, Session, runtime types and FilesApi helpers (buildToolsView, hideUnder, insideSubtree). The official entry point. | | @statewalker/ai-agent/state | TreeNode, SessionState, Turn, TurnGroup, Message, ToolCall, Inbox, ToolRegistry, SkillsModel, NodeType, LogMessage, createAgentNodeFactory, tree types. Explicit per-symbol exports; serialization helpers live at /state/serialization and /state/session-serialization (deep import) — they are not part of the published surface. | | @statewalker/ai-agent/models | ModelManager, LocalModelStorage, model catalog, remote discovery, verifyModelAccess, provider/model types. ModelStateStore implements ProviderV3 directly; use ModelManager#provider to pass it to addModelProvider(). | | @statewalker/ai-agent/tools | File-system tools (createFileTools) and path utilities. |

The bare @statewalker/ai-agent root is intentionally empty — go through one of the sub-paths above. Internal modules (context, mcp, skills, config, sessions) are no longer reachable; they're implementation detail. The Session deprecated alias previously re-exported from /state was removed; use SessionState directly.

Quick start

import { AgentRuntime } from "@statewalker/ai-agent/runtime";
import { createFileTools } from "@statewalker/ai-agent/tools";
import { NodeFilesApi } from "@statewalker/webrun-files-node";
import { createAnthropic } from "@ai-sdk/anthropic";

const files = new NodeFilesApi({ rootDir: "/my/project" });

const runtime = await new AgentRuntime({ files })
  .addModelProvider(createAnthropic({ apiKey: process.env.ANTHROPIC_API_KEY }))
  .setSystemPath(".settings/")
  .addTools((ctx) => createFileTools(ctx.files))
  .build();

const assistant = runtime.createAgent({
  name: "assistant",
  defaultModel: "claude-sonnet-4-20250514",
  systemPrompt: "You are a helpful assistant.",
});

const session = assistant.createSession({ title: "first chat" });
session.send("List the markdown files in /docs.");

for await (const log of session.run()) {
  console.log(log.kind, log.content);
}

const id = await session.save();
// later: const resumed = await runtime.loadSession(id);

FilesApi split (system vs tools views)

AgentRuntime builds two views over the root FilesApi you pass to its constructor:

  • System view — full visibility. Used internally by the runtime for agent definition loading, skill loading, and session persistence. Never exposed to tools.
  • Tools view — a FilteredFilesApi over the same root with the system path-tree hidden. Tools and skills receive this via AgentContext.files. Hidden paths are reported as not-existing (read/list/stats/exists return empty/false); writes/mkdir into hidden paths reject with "Path is hidden".

Default: setSystemPath("/.settings/"). The system path-tree is laid out:

| Subject | Path on systemFiles | |---|---| | Agents folder | /agents/ | | Skills folder | /skills/ | | Sessions folder | /sessions/ | | Config folder | / |

AgentContext is { files: FilesApi } — tools and skills receive the tools view only. Tool factories needing more (model, provider, custom storage) accept those as closure-captured constructor arguments at their own factory boundary.

Error handling

A single error handler routes errors from every runtime-internal source, supplied via the constructor:

const runtime = new AgentRuntime({
  files,
  errorHandler: (err, ctx) => {
    // ctx?.path   — set when a FilteredFilesApi violation surfaces
    // ctx?.server — set when an MCP server interaction fails
    log.warn({ err, ctx });
  },
});

Default handler is console.warn. Errors thrown by build-phase configuration mistakes (no provider, system path covering root, etc.) are routed through the handler and rethrown — observers see the error and await runtime.build() still rejects.

API surface

class AgentRuntime

Constructor

new AgentRuntime({ files: FilesApi, errorHandler?: AgentRuntimeErrorHandler })

Fluent setup (each returns this)

| Method | Purpose | |---|---| | setSystemPath(path) | System path-tree root. Default "/.settings". | | addModelProvider(...providers) | Register one or more ProviderV3 instances. Callers holding a ModelManager pass modelManager.provider. | | addTools(...tools) | Register tools (ToolSet or ToolFactory). | | addSkills(...skills) | Register skills programmatically. | | setMcpServers(config) | Configure MCP servers inline. |

Per-subject paths under <systemPath> are hard-coded: sessions/sessions, skills/skills, agents/agents, config/. The tools view always uses FilteredFilesApi with the system path-tree hidden. To customise context-window behaviour (selection strategy, budget compaction, summariser, etc.), construct a ContextWindow directly and pass it to a Session — the runtime no longer carries that surface. The error handler is set via the constructor option errorHandler rather than a live setter.

Materialization

  • build(): Promise<this> — load skills + agent definitions from disk, resolve the provider union, connect MCP. Idempotent.

Agent definitions

  • createAgent(def: AgentDefinition): Agent
  • getAgent(name): Agent | undefined
  • agents(): Agent[]

Sessions

  • loadSession(id): Promise<Session>
  • listSessions(): Promise<SessionMetadata[]>
  • deleteSession(id): Promise<boolean>

Read-only views

  • files: FilesApi (tools view)
  • systemFiles: FilesApi (system view)
  • config, mcp

class Agent

A definition value. Use runtime.createAgent({ ... }) rather than constructing directly.

interface AgentDefinition {
  name: string;
  tools?: string[];        // empty / undefined → all
  skills?: string[];       // empty / undefined → none
  systemPrompt?: string;
  defaultModel?: string;
  maxSteps?: number;
  maxOutputTokens?: number;
}
  • createSession({ title?, sessionId? }): Session

class Session

A runtime instance.

  • id: string, agent: Agent, state: SessionTreeNode
  • inbox, tools, skills — per-session views
  • send(text, opts?) — push a user message into the inbox
  • run(signal?): AsyncGenerator<LogMessage> — drive the loop
  • save({ title? }): Promise<string> — persist
  • close(): Promise<void> — tear down

Migration from AgentBuilder (removed)

The legacy AgentBuilder / AgentManager / Agent (wrapper) / SubAgentTool classes were removed. The mapping:

| Legacy | New | |---|---| | new AgentBuilder().withProvider(p).withFilesApi(f).withTools(t).build() | await new AgentRuntime({ files: f }).addModelProvider(p).addTools(t).build() | | withProvider(p) / withModelManager(m) | addModelProvider(p) / addModelProvider(m.provider) | | withModel(model) | per-Agent: runtime.createAgent({ defaultModel: model }) | | withFilesApi(f) | constructor option | | withSystemFolder(path) | setSystemPath(path) | | withExcludedPaths(...) | pre-wrap the FilesApi with FilteredFilesApi before passing it in | | withTools(t) | addTools(t) | | withSkills(s) / withSkillsFolder(path) | addSkills(...s) + setSkillsPath(path) | | withMcpServers(cfg) / withMcpConfigFile(path) | setMcpServers(cfg) / setMcpConfigFile(path) | | new AgentManager(builder).create(title) | runtime.createAgent({ name }).createSession({ title }) | | manager.resume(id) | runtime.loadSession(id) | | agent.run(signal) | session.run(signal) | | agent.inbox.push({ role: "user", text }) | session.send(text) | | agent.save(title) | session.save({ title }) | | withSubAgent(name, factory) | agentDef.addSubAgent(other) (runtime support pending) |

The SessionManager interface and Agent wrapper class no longer exist — sessions are returned directly from agent.createSession() / runtime.loadSession().

Skill markdown format

Skills are markdown files under <systemPath>/skills/ with key=value frontmatter:

---
name=analyze-csv
description=Read a CSV and produce a summary statistics report.
---

(skill body — instructions for the LLM when this skill is selected)

name and description are required. Additional keys are passed through as metadata.

License

MIT.