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

octoflow-core

v1.0.1

Published

Library-first TypeScript runtime for connecting LLM backends, tools, memory, guardrails, and flows to existing apps.

Readme

octoflow-core

Main OctoFlow runtime for adding agents to existing TypeScript apps. It discovers ready LLM backends, routes requests, runs sessions, streams events, executes typed tools, applies policy, manages stores, and connects packs, flows, MCP servers, skills, gateways, memory, and plugins.

Native CLI backends (claude-code-cli, codex-cli, cursor-cli, gemini-cli, acp-cli, and custom) are bridge-only: OctoFlow routes prompts and task state, while the CLI owns tools, MCP, skills, memory, and its native agent loop. Use API, SDK, local, or A2A backends when the OctoFlow core harness should own those capabilities.

Install

npm install octoflow-core

Node.js >=20 is required.

Use It When

  • You want one API over CLI agents, API models, Ollama, custom hosts, or A2A peers.
  • You need request/response, streaming, sessions, resume, task state, and structured output in your own app.
  • You want built-in file and shell actions with approvals, path controls, profiles, and secret redaction.
  • You plan to add memory, MCP, skills, packs, flows, plugins, platform adapters, or an OpenAI-compatible gateway.

30-Second Start

import { createAgent, defineAction, extractText } from 'octoflow-core';

const lookupDocs = defineAction({
  name: 'lookup_docs',
  description: 'Look up project docs.',
  parameters: {
    type: 'object',
    properties: { topic: { type: 'string' } },
    required: ['topic'],
  },
  execute: async ({ topic }) => `Docs for ${String(topic)}`,
});

const agent = await createAgent({
  llm: [
    { backend: 'claude-code-cli', model: 'sonnet' },
    { backend: 'anthropic-api', model: 'claude-sonnet-4-6' },
    { provider: 'groq', model: 'llama-3.3-70b-versatile' },
    { provider: 'openrouter', model: 'openai/gpt-4o-mini' },
    { backend: 'gemini-api', model: 'gemini-2.5-flash' },
    { backend: 'ollama', model: 'llama3.2' },
  ],
  actions: [lookupDocs],
  context: { instructions: 'Use tools when they help.' },
});

const result = await agent.sendMessage({
  message: 'Explain this repository in three bullets.',
});

console.log(extractText(result));
await agent.close();

Backends without credentials or local binaries are skipped. The first ready entry in ordered llm fallback wins, with fallback on failure. Multiple provider profiles can share openai-api; each keeps isolated host/API-key/model config.

Use discoverAvailableBackends() for zero-config readiness scans; with no explicit priority it checks the default routing order plus cataloged built-in backends such as Gemini CLI and ACP. Use inspectBackendCatalog() when tools, examples, or tests need the shared backend/provider list, auth env vars, default hosts, model override hints, and probe metadata without duplicating backend tables. Use agent.inspectHarness() after startup when diagnostics need the live inventory of selected backends, resolved config, plugins, registered actions/tools, runtime skills, SKILL.md bundles, MCP servers/tools, brain status, Pack workers, the canonical core capability matrix, and backend feature conformance.

createAgent() is the single entry point for all runtimes. Use agentType to select the topology: 'tool-loop' (default), 'supervisor', 'swarm', 'sequential', and more. First-use presets (createCodingAgent(), createSupportAgent(), createResearchAgent(), createSecureToolAgent(), createSupervisorTeam()) are thin wrappers over that same API. See docs/api.md#createagent-options for the full option reference, and docs/agent-prompts.md for configuring the agent's base/system prompt and backend-native prompt caching.

What You Get

| Area | Runtime surface | | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Backends | Discovery, priority routing, explicit provider selection, CLI adapters (claude-code-cli, codex-cli, gemini-cli, cursor-cli), API providers (Anthropic, OpenAI, Gemini, Ollama), ACP — drive any Agent Client Protocol agent (acp-cli, 16 built-in agents), custom hosts and CLIs. | | Conversations | One-shot messages, streams, sessions, resume, default API compaction, backend-native prompt caching for stable prompt prefixes, provider cache diagnostics, task cost source/estimates, task state, stores, clean shutdown. | | Tools | defineAction(), built-ins, MCP loading, skills, custom action registry with opt-in strict duplicate mode for non-native-CLI harnesses. Native CLI backends keep their own tool/MCP/skill surface. | | Retrieval | chunkText(), createVectorStore(), and createRetrievalActions() for simple embedder-backed file search/RAG in core. | | Safety | Approval flow, policy profiles, managed git worktrees, workspace-limited tools, path controls, tenant checks, deny paths, secret redaction, circuit breakers. | | Orchestration | Packs, flows, workers, topic channels, PackMesh, subagents, A2A JSON-RPC/SSE. | | Shipping | OpenAI-compatible gateway, daemon mode, adapters, plugins, observability events. | | Optional memory | Attach local octoflow-brain or HTTP-backed createRemoteBrain() memory for the OctoFlow-owned harness; native CLI backends use their own memory/config surfaces. | | Optional sandboxes | Local sandbox profiles, managed per-request git worktrees, Docker, SSH, Vercel Sandbox, E2B, and custom execution environments. |

ACP support

Use backend: 'acp-cli' when you want one OctoFlow integration over multiple ACP-capable coding agents.

  • Why users need it: switch agent vendors without rewriting app glue code.
  • What it gives users: consistent createAgent/sendMessage/stream usage, bridge lifecycle events, and capability-aware ACP session handling while the ACP agent owns its native tools and MCP surface.
  • DX behavior: one-shot + streaming are the stable baseline; multi-turn persistence is enabled when the target ACP agent advertises session/resume or session/load.
  • Runnable check: npm run backend-acp -w octoflow-examples validates readiness, one-shot, stream, session continuity (or skip when unsupported), and steer-mode behavior.

Public Imports

| Level | Import | Use for | | ------------ | ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | | Stable | octoflow-core | Canonical API. Complete explicit public surface: app APIs, advanced extension APIs, migration tools, audits, and common runtime contracts. | | Beta | octoflow-core/pack | Pack and flow orchestration helpers, supervisor/worker factories. | | Beta | octoflow-core/stores | Store implementations and contracts; in-memory and SQLite presets are stable through createAgent options. | | Beta | octoflow-core/output | Structured output schema helpers and parsers. | | Preview | octoflow-core/a2a | Agent-to-agent JSON-RPC/SSE client and server. | | Preview | octoflow-core/environments | Execution environment implementations and contracts. | | Preview | octoflow-core/observability | Event and telemetry helpers. | | Internal | octoflow-core/testing | Test helpers for runtime behavior; not a product API. |

The public API labels are documented in docs/api.md#stability-labels.

Common Recipes

Stream live task updates:

for await (const event of agent.stream({
  message: 'Draft release notes.',
})) {
  if (event.kind === 'artifact-update') {
    const text = event.event.artifact.parts
      .filter((part) => part.kind === 'text')
      .map((part) => part.text)
      .join('');
    process.stdout.write(text);
  }
}

Set sandbox/worktree defaults once in octoflow.config.json:

{
  "priority": ["claude-code-cli", "codex-cli"],
  "defaultProfile": "local-sandboxed",
  "defaults": {
    "worktree": {
      "name": "fix-tests",
      "cleanup": "never",
      "reuse": true,
      "dirty": "copy"
    }
  }
}

Then a normal agent.sendMessage({ message: 'Fix the failing tests.' }) runs with the configured sandbox profile and managed worktree. Per-call worktree still overrides config. worktree: true creates a detached checkout under .octoflow/worktrees; a string or { name } controls the directory name. Use dirty: "copy" when the agent should see uncommitted local changes.

Use agent.runStream(...) for orchestration progress (flow-step-start, flow-step-complete, flow-terminated, loop, and task-batch events). Use onEvent or agent.onAny(...) when you want those same run events on the shared event bus as agent:flow-step-start, agent:flow-step-complete, agent:flow-terminated, and the matching loop/task-batch names.

const agent = await createAgent({
  onEvent(event) {
    if (event.type === 'bridge:message') process.stdout.write(event.data.text);
    if (event.type.startsWith('agent:flow-')) console.log(event.type);
  },
});

Expose a local HTTP endpoint for OpenAI or Anthropic-compatible clients:

const openAiGateway = await agent.makeGateway({ inboundProtocol: 'openai' });
// Routes: /v1/models, /v1/chat/completions, /v1/responses, /v1/embeddings, /tools/invoke

const anthropicGateway = await agent.makeGateway({
  inboundProtocol: 'anthropic',
});
// Routes: /v1/models, /v1/messages

Expose an AG-UI interoperable SSE endpoint (CopilotKit, LangGraph, assistant-ui, CrewAI, Mastra):

import { createAgUiGatewayServer } from 'octoflow-core';

const { server } = await createAgUiGatewayServer(agent);
// Route: POST /agui/run  — SSE (default) or JSON (Accept: application/json)
// Event taxonomy emitted per run (SSE order):
//   RUN_STARTED → STATE_SNAPSHOT → STEP_STARTED → ACTIVITY_SNAPSHOT
//   → ACTIVITY_DELTA → TEXT_MESSAGE_* → TOOL_CALL_* (+ TOOL_CALL_RESULT)
//   → STATE_DELTA → MESSAGES_SNAPSHOT → STEP_FINISHED → CUSTOM → RUN_FINISHED
// RunAgentInput: threadId, runId, messages, tools, context, forwardedProps, resume[], state.

Use the lifecycle verifier in your own tests:

import { verifyAgUiEventSequence } from 'octoflow-core';

const violations = verifyAgUiEventSequence(events);
// [] = conformant sequence; non-empty = lifecycle invariant broken

Full AG-UI support matrix: docs/feature-catalog.md. Runnable references: react-ag-ui-chatbot for raw @ag-ui/client, and react-copilotkit-ag-ui-chatbot for CopilotKit UI on the same gateway.

Enable persistent local state:

const agent = await createAgent({
  priority: ['anthropic-api'],
  storage: true,
});

Call a remote agent over A2A (JSON-RPC + SSE, plus task push notification config set/get for webhook delivery):

import { A2AClient, createA2AServer } from 'octoflow-core/a2a';

// Expose a local agent on http://127.0.0.1:4400/rpc
const handle = await createA2AServer({
  agent,
  host: '127.0.0.1',
  port: 4400,
  agentCard: { name: 'release-notes', description: 'Drafts release notes.' },
});
handle.server.listen(4400, '127.0.0.1');

// Call it from another process — one-shot, streaming, or session-scoped
const client = new A2AClient({ url: 'http://127.0.0.1:4400/rpc' });
const { text } = await client.run('Draft release notes for v1.4.');

Route tool execution to a sandboxed environment (Docker / SSH / Vercel Sandbox / E2B / local):

import {
  createDockerEnvironment,
  createEnvironmentsPlugin,
} from 'octoflow-core/environments';

const env = createDockerEnvironment({ image: 'node:20-alpine' });

const agent = await createAgent({
  plugins: [createEnvironmentsPlugin({ environments: { default: env } })],
});
// The plugin replaces the built-in `bash` action with one that delegates
// to `env.exec(...)`, so shell calls run inside the container.

Learn More

File-size rule

Per the root AGENTS.md, source files must stay ≤ 400 non-blank/non-comment lines.

Exemptions in this package:

| File | Reason | | -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | src/index.ts | Public barrel. Every export is an explicit named re-export — no logic, no wildcards. Line count grows with the public surface, not with implementation complexity. Splitting it would require wildcard exports (banned) or a redundant indirection layer. |

All other files are subject to the 400-line limit. Split by concern when adding new exports.

Validate

npm run -w octoflow-core lint
npm run -w octoflow-core typecheck
npm run -w octoflow-core test

Status

Beta. createAgent, defineAction, stores, approvals, memory basics, and agent.run({ flow }) are Stable — see docs/api.md#stability-labels for the full stable surface and label definitions. Everything else is labeled Beta, Preview, or Internal. Pin versions before depending on it in production.