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

wheelloop

v0.1.23

Published

Production-ready Node.js framework for building conversational AI agents with tools and MCP integration.

Readme

WheelLoop

npm version License: MIT Node.js Version

Production-ready Node.js framework for building conversational AI agents with tools, middleware, and MCP (Model Context Protocol) integration.

Features

  • 🔧 Tool System - Unified registry supporting local tools, HTTP MCP, and stdio MCP providers
  • 🔗 Middleware Pipeline - Extensible lifecycle hooks for request/response processing
  • 🤖 SubAgent Architecture - Built-in task delegation with specialized agents (research, writing, code review)
  • 📡 Event Streaming - Real-time execution feedback with streaming support
  • 🛡️ Fine-grained Control - Whitelist filtering for tools and providers
  • 🗄️ Filesystem Integration - Read/write file operations via middleware with virtual mode support

Quick Start

Installation

pnpm add wheelloop
# or
npm install wheelloop

Basic Usage

import { createWheelAgent, createLocalToolRegistry } from 'wheelloop';

// Create agent with default tools
const toolRegistry = await createLocalToolRegistry();
const agent = createWheelAgent({ toolRegistry });

// Simple chat
const result = await agent.chatStreamWithEvents({
  model: 'gpt-4o-mini',
  api_key: process.env.OPENAI_API_KEY,
  messages: [
    { role: 'system', content: 'You are a helpful assistant.' },
    { role: 'user', content: 'Create a todo list for today.' }
  ]
});

console.log(result.content);

With Filesystem Access

import {
  createWheelAgent,
  createLocalToolRegistry,
  createFilesystemMiddleware
} from 'wheelloop';

const toolRegistry = await createLocalToolRegistry();

// Add filesystem capabilities via middleware
const fsMiddleware = createFilesystemMiddleware({
  backend: { virtualMode: true }, // Safe virtual filesystem
  systemPrompt: 'You can read and modify files to help users.'
});

const agent = createWheelAgent({
  toolRegistry,
  middlewares: [fsMiddleware]
});

const result = await agent.chatStreamWithEvents({
  model: 'gpt-4o-mini',
  api_key: process.env.OPENAI_API_KEY,
  messages: [
    { role: 'user', content: 'Analyze the package.json file and summarize dependencies.' }
  ]
});

Architecture

Core Flow

flowchart LR
    A[User Request] --> B[Middleware Chain]
    B --> C{Agent Loop}
    C --> D[LLM Call]
    D --> E{Tool Call?}
    E -->|Yes| F[Execute Tools]
    E -->|No| G[Final Response]
    F --> C

    style B fill:#e1f5ff
    style F fill:#ffe1e1
    style G fill:#e1ffe1

Component Overview

  • WheelAgent - Main orchestrator for chat, tools, and events
  • ToolRegistry - Manages local tools + MCP providers
  • Middleware System - Lifecycle hooks: beforeAgentbeforeModelwrapModelCallafterModelafterAgent
  • SubAgent System - Task delegation with depth control and isolated contexts
  • Event Handlers - Callbacks for llm_start, tool_start, agent_end, etc.

Advanced Usage

SubAgent Delegation

Enable task decomposition with specialized agents:

const agent = createWheelAgent({
  toolRegistry,
  enableSubAgents: true,
  maxSubAgentDepth: 3,
  subAgentConfigs: [
    {
      name: 'code-reviewer',
      description: 'Reviews code quality and suggests improvements',
      systemPrompt: 'You are an expert code reviewer...',
      model: 'gpt-4'
    }
  ]
});

Built-in SubAgents: research, writing, code-review, general-purpose

Tool Whitelisting

Control which tools are available:

const agent = createWheelAgent({
  toolRegistry,
  allowedLocalTools: ['search', 'filesystem'],
  allowedMcpProviders: ['github'],      // HTTP MCP
  allowedStdioProviders: ['gitlab']     // Stdio MCP
});

Custom Middleware

import type { AgentMiddleware } from 'wheelloop';

const loggingMiddleware: AgentMiddleware = {
  beforeModel: async (state, messages, tools, params) => {
    console.log(`Calling LLM with ${tools.length} tools`);
    return { messages, tools, params };
  },

  afterModel: async (state, response, params) => {
    console.log('LLM response received:', response.content);
    return { state, response };
  }
};

const agent = createWheelAgent({
  toolRegistry,
  middlewares: [loggingMiddleware]
});

Event Streaming

const result = await agent.chatStreamWithEvents({
  model: 'gpt-4o-mini',
  api_key: process.env.OPENAI_API_KEY,
  messages: [...],
  events: {
    on_llm_stream: (chunk) => {
      process.stdout.write(chunk.content || '');
    },
    on_tool_start: (tool) => {
      console.log(`\n[Tool] ${tool.name}`);
    },
    on_tool_end: (result) => {
      console.log(`[Result] ${result.output}`);
    }
  }
});

Middleware System

Lifecycle Hooks

sequenceDiagram
    participant User
    participant Middleware
    participant LLM
    participant Tools

    User->>Middleware: Request
    Middleware->>Middleware: beforeAgent
    Middleware->>Middleware: beforeModel
    Middleware->>LLM: wrapModelCall
    LLM-->>Middleware: Response
    Middleware->>Middleware: afterModel

    alt Tool Call Required
        Middleware->>Tools: Execute
        Tools-->>Middleware: Result
    end

    Middleware->>Middleware: afterAgent
    Middleware-->>User: Final Response

Built-in Middlewares

Filesystem Middleware

import {
  createFilesystemMiddleware,
  createFilesystemReadOnlyMiddleware
} from 'wheelloop';

// Full access (read + write)
const fsMiddleware = createFilesystemMiddleware({
  backend: { virtualMode: true },
  systemPrompt: 'You can access and modify files.',
  customToolDescriptions: {
    ls: 'List directory contents',
    read_file: 'Read file contents',
    write_file: 'Write to file',
    edit_file: 'Edit existing file',
    glob: 'Search files by pattern',
    grep: 'Search file contents'
  }
});

// Read-only access
const readOnlyFs = createFilesystemReadOnlyMiddleware({
  backend: { virtualMode: true },
  systemPrompt: 'You can read files (read-only access).'
});

Other Middlewares

  • SummarizationMiddleware - Automatic content summarization
  • ContextCompactionMiddleware - Context window management

API Reference

createWheelAgent(options)

interface WheelAgentOptions {
  // Tool management
  toolRegistry?: ToolRegistry;

  // Middleware pipeline
  middlewares?: AgentMiddleware[];

  // Abort control
  abortController?: AbortController;

  // SubAgent configuration
  enableSubAgents?: boolean;
  subAgentConfigs?: SubAgentConfig[];
  maxSubAgentDepth?: number; // Default: 3

  // Tool filtering
  allowedLocalTools?: string[];
  allowedMcpProviders?: string[];
  allowedStdioProviders?: string[];
}

chatStreamWithEvents(params)

interface ChatParams {
  // LLM configuration
  model: string;
  api_key: string;
  base_url?: string;

  // Messages
  messages: Message[];

  // Optional parameters
  temperature?: number;
  max_tokens?: number;

  // Event handlers
  events?: {
    on_llm_start?: (data) => void;
    on_llm_stream?: (chunk) => void;
    on_llm_end?: (response) => void;
    on_tool_start?: (tool) => void;
    on_tool_end?: (result) => void;
    on_agent_start?: () => void;
    on_agent_end?: (result) => void;
  };
}

Examples

The examples/ directory contains complete working examples:

# Clone and setup
git clone <repo-url>
cd WheelLoop
pnpm install

# Create .env file
cat > .env << EOF
OPENAI_API_KEY=your_key_here
ONE_API_KEY=your_one_api_key
ONE_API_MODEL=deepseek-chat
ONE_API_REMOTE=https://oneapi.example.com
BOCHA_API_KEY=your_bocha_key
SERPER_KEY=your_serper_key
EOF

# Run examples
pnpm tsx examples/test_simple.ts        # Basic chat
pnpm tsx examples/test_agent.ts         # With tools
pnpm tsx examples/test_middleware.ts    # Middleware demo
pnpm tsx examples/test_subagent.ts      # SubAgent delegation
pnpm tsx examples/test_stdio_mcp.ts     # MCP integration

Development

# Setup
pnpm install

# Development
pnpm dev              # Watch mode
pnpm typecheck        # Type checking
pnpm build            # Build to dist/

# Code Quality
pnpm lint             # ESLint
pnpm lint:fix         # Auto-fix
pnpm format           # Prettier
pnpm format:check     # Check formatting

# Testing
pnpm test             # Run tests
pnpm test:watch       # Watch mode
pnpm test:coverage    # Coverage report
pnpm test:ui          # UI test runner

Use Cases

  • Code Assistants - Build AI coding tools with filesystem access
  • Research Agents - Delegate web search and content analysis
  • Task Automation - Orchestrate complex workflows with SubAgents
  • Document Processing - Read, analyze, and generate documentation
  • MCP Integration - Connect to external tools via Model Context Protocol

License

MIT


Documentation: See /CLAUDE.md for architecture details Issues: GitHub Issues npm: wheelloop