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

@autonome-research/thread-phase-agents

v4.1.0

Published

Agent adapters for thread-phase — wraps hermes, openclaw, anthropic, codex, claude-code, pi behind a uniform AgentAdapter protocol. Agent SDKs are optional peer deps; install only what you use.

Readme

@autonome-research/thread-phase-agents

Adapter implementations for the AgentAdapter protocol from @autonome-research/thread-phase. Wraps heterogeneous AI agents — CLI-based coding agents, in-process SDK agents — behind a single uniform shape so thread-phase pipelines can compose them.

Install

npm install @autonome-research/thread-phase-agents @autonome-research/thread-phase

@autonome-research/thread-phase is a peer dep. Agent SDKs are also optional peer deps — install only the ones whose adapter you actually use. The package itself is small; the SDK weight is what you choose to add.

| Adapter | Requires | Install when used | |---|---|---| | acpAgent (chassis) | An ACP-speaking subprocess on your machine | — | | hermesAgent | hermes CLI in PATH | — | | openClawAgent | acpx in PATH; optional NemoClaw sandbox | — | | claudeCodeAgent | claude CLI in PATH (https://claude.com/code) | — | | codexCliAgent | codex CLI in PATH (codex login for auth) | — | | codexAgent | OPENAI_API_KEY env var (Responses API direct) | npm install openai | | anthropicAgent | ANTHROPIC_API_KEY env var | npm install @anthropic-ai/sdk | | piAgent | pi config under ~/.pi/agent/ | npm install @mariozechner/pi-coding-agent |

Calling an adapter without its SDK installed throws a clear ... requires the optional peer dep <pkg>. Install it with: npm install <pkg> error — the adapter is import-safe even when the SDK is absent.

What's in here

Seven adapter implementations plus a shared ACP chassis:

  • acpAgent — the Agent Client Protocol chassis. Spawns any ACP-speaking subprocess, parses JSON-RPC over stdio, drives initialize → session/new → session/prompt → session/cancel. Other ACP-based adapters compose on top.
  • hermesAgent — wraps hermes acp. Inherits the ACP chassis.
  • openClawAgent — wraps acpx against the OpenClaw Gateway, with optional sandbox: 'nemoclaw' | 'local' mode.
  • anthropicAgent — in-process via @anthropic-ai/sdk. Streaming + tool use + extended thinking.
  • codexAgent — in-process via OpenAI Responses API. Requires OPENAI_API_KEY.
  • codexCliAgent — subprocess wrapper around codex exec --json. Uses codex's own auth (ChatGPT subscription OAuth typically).
  • claudeCodeAgent — subprocess + JSONL streaming. Forgiving parser falls back to native events for unknown shapes.
  • piAgent — in-process via @mariozechner/pi-coding-agent. The only adapter where SteerableAgentRun.steer() and .followUp() work natively at runtime (pi accepts mid-stream steering).

Using an adapter

The basic shape is the same for every adapter — call meta.adapter(config) to get an AgentRun, then iterate events and/or await the result:

import { hermesAgent } from '@autonome-research/thread-phase-agents';

const run = hermesAgent.adapter({
  cwd: process.cwd(),
  prompt: 'List the files in this directory and summarize what they are.',
});

// Stream events for display / logging:
for await (const event of run.events) {
  if (event.type === 'text') process.stdout.write(event.delta);
}

// Await the final result:
const result = await run.result;
console.log('finishReason:', result.finishReason);
console.log('text:', result.text);
console.log('resumeToken:', result.resumeToken);

run.result never rejects — errors are encoded as finishReason: 'error' with an error event in the stream beforehand. run.events is a single-consumer iterable; use the AgentEventBus from @autonome-research/thread-phase/agents if you need fan-out to multiple subscribers.

Inside a thread-phase phase

Adapters compose with thread-phase's pipeline primitives. The canonical pattern:

import { JobRunner, SqliteJobStore, type Phase } from '@autonome-research/thread-phase';
import { createEventBus, pipeAgentEventsToJobStore } from '@autonome-research/thread-phase/agents';
import { claudeCodeAgent } from '@autonome-research/thread-phase-agents';

interface Ctx {
  taskDescription?: string;
  result?: string;
}

const reviewPhase: Phase<Ctx> = {
  name: 'review',
  async *run(ctx, { jobId, store, signal }) {
    yield { type: 'phase', phase: 'review', detail: 'starting claude-code' };

    const bus = createEventBus();
    pipeAgentEventsToJobStore(bus, store, jobId, { dropTypes: ['text'] });

    const run = claudeCodeAgent.adapter(
      { cwd: process.cwd(), prompt: ctx.taskDescription! },
      { signal, eventBus: bus, traceId: jobId },
    );

    const result = await run.result;
    ctx.result = result.text;
    yield { type: 'data', key: 'result', value: { length: result.text.length } };
  },
};

pipeAgentEventsToJobStore wires the adapter's event stream into the JobStore log so every text delta / tool call / turn boundary is persisted. The dropTypes: ['text'] filter keeps the high-volume text deltas out of the database while preserving tool calls, turn boundaries, and lifecycle events for audit.

Memory and Thread auto-wiring

Decorate any adapter with withMemory to plumb a MemoryProvider automatically, or withThread to flow conversation state across phases. Use the pre-built injectors from this package so you don't have to write per-adapter splicing logic:

import { withMemory, withThread, createThread } from '@autonome-research/thread-phase/agents';
import { claudeCodeAgent, injectMemory, injectResume } from '@autonome-research/thread-phase-agents';

const thread = createThread();

const augmented = withThread(
  withMemory(claudeCodeAgent, {
    scope: { userId: 'alice' },
    inject: injectMemory.claudeCode,
  }),
  thread,
  { applyResume: injectResume.claudeCode },
);

// First call — creates a session, fills thread.events.
await augmented.adapter({ cwd, prompt: 'analyze this codebase' }, { memoryProvider }).result;

// Second call — same thread; the wrapper reads thread.resumeTokens['claude-code']
// and adds --resume <id> automatically.
await augmented.adapter({ cwd, prompt: 'now refactor the file you mentioned' }, { memoryProvider }).result;

Steerable runs (pi, hermes, openclaw)

Adapters whose underlying runtime supports follow-up prompts on a live session return a SteerableAgentRun at runtime. Narrow with isSteerable from thread-phase/agents:

import { isSteerable } from '@autonome-research/thread-phase/agents';
import { piAgent } from '@autonome-research/thread-phase-agents';

const run = piAgent.adapter({ cwd, prompt: 'start something complex' });

if (isSteerable(run)) {
  // Pi accepts mid-stream steering — interrupt the current generation
  // and add context.
  await run.steer('reconsider, the user just clarified X');

  // Or queue a follow-up that fires after the current response completes:
  await run.followUp('and then also summarize');
}

const result = await run.result;
  • piAgent supports both steer() (mid-generation injection) and followUp() (queued additional turn).
  • hermesAgent / openClawAgent / acpAgent support followUp() (ACP's session/prompt is discrete — multiple prompts on one session). steer() rejects with a capability error.
  • All other adapters (claudeCodeAgent, codexCliAgent, codexAgent, anthropicAgent) are not steerable. isSteerable(run) returns false.

Cross-adapter handoff with Thread

When two phases use different adapters, the canonical event log in a shared Thread becomes the bridge. Same-adapter chains resume natively via the resume token (lossless); cross-adapter chains fall back to a text rendering of the thread:

import { createThread } from '@autonome-research/thread-phase/agents';
import {
  claudeCodeAgent,
  anthropicAgent,
  threadToAnthropicMessages,
} from '@autonome-research/thread-phase-agents';

const thread = createThread();

// Phase A: claude-code does research.
const runA = withThread(claudeCodeAgent, thread, { applyResume: injectResume.claudeCode });
await runA.adapter({ cwd, prompt: 'investigate the bug in foo.ts' }).result;

// Phase B: anthropic synthesizes a report from claude-code's findings.
// Different adapter — render the thread to anthropic message format.
const messages = threadToAnthropicMessages(thread);
const runB = anthropicAgent.adapter({
  model: 'claude-opus-4-7',
  messages: [...messages, { role: 'user', content: 'Write a 3-bullet summary.' }],
});
await runB.result;

The threadTo<Adapter>{Prompt,Messages,Input} helpers render the shared event log into each adapter's expected input shape.

Smoke scripts

Each adapter has a runnable real-binary smoke test under scripts/:

npx tsx scripts/smoke-claude-code.ts "say hello"
npx tsx scripts/smoke-hermes.ts
npx tsx scripts/smoke-codex-cli.ts
npx tsx scripts/smoke-pi.ts

Useful for sanity-checking that the adapter survives contact with whichever version of the binary you have installed. They print every canonical event as it streams and report pass/fail at the end.

Relationship to @autonome-research/thread-phase

@autonome-research/thread-phase owns the AgentAdapter protocol, the Thread primitive, the canonical AgentEvent vocabulary, the inferenceAgent (which wraps runAgentWithTools against any OpenAI-compatible endpoint), and the conformance suite that every adapter must pass.

This package ships the other adapters — the ones that delegate to pre-built coding / research / life agents rather than driving a raw inference loop. Each adapter passes the conformance suite imported from @autonome-research/thread-phase/agents/test-utils.

Status

Pre-1.0. The adapter set covers the common heterogeneous-agent surface; the API shape may still change before 1.0.

License

MIT.