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

@machinemetrics/agent-event-protocol

v0.1.1

Published

Agent Event Protocol implementation

Readme

@machinemetrics/agent-event-protocol

A transport-agnostic event protocol for streaming agent responses. Defines the schema and utilities for real-time communication between AI agents and clients.

Installation

npm install @machinemetrics/agent-event-protocol

Design Principles

  1. Simple - Easy to understand and implement
  2. Flexible - Supports future features without breaking changes
  3. Type-safe - Strong contracts between client and server
  4. Observable - Easy to monitor and debug
  5. Transport-agnostic - Same events work over SSE, NDJSON, WebSocket, NATS, etc.

Protocol Overview

The protocol defines a streaming event schema for agent responses. All events are self-identifying JSON payloads with common fields:

  • event - Event type identifier
  • requestId - Correlates all events to the originating request
  • timestamp - ISO 8601 timestamp for observability

Message Flow

┌─────────┐                                    ┌─────────┐
│ Client  │                                    │ Server  │
└────┬────┘                                    └────┬────┘
     │                                              │
     │  POST /v1/agents/{agentName}/stream         │
     │  { messages, threadId?, context? }          │
     ├─────────────────────────────────────────────>│
     │                                              │
     │  metadata: {threadId, requestId, agentId}   │
     │<─────────────────────────────────────────────┤
     │                                              │
     │  text: {blockId, stage: "start"}            │
     │<─────────────────────────────────────────────┤
     │                                              │
     │  text: {blockId, stage: "delta", delta}     │
     │<─────────────────────────────────────────────┤
     │                                              │
     │  text: {blockId, stage: "stop"}             │
     │<─────────────────────────────────────────────┤
     │                                              │
     │  done: {content, usage, finishReason}       │
     │<─────────────────────────────────────────────┤
     │                                              │

Client Action Flow

When the agent needs client-side action, the stream pauses and resumes via a new request:

┌─────────┐                                    ┌─────────┐
│ Client  │                                    │ Server  │
└────┬────┘                                    └────┬────┘
     │                                              │
     │  POST /stream { messages, threadId? }       │
     ├─────────────────────────────────────────────>│
     │                                              │
     │  continuation: {actionId, kind, payload}    │
     │<─────────────────────────────────────────────┤
     │                                              │
     │  done: {finishReason: "action_required"}    │
     │<─────────────────────────────────────────────┤
     │                                              │
     │  (client handles action based on kind)      │
     │                                              │
     │  POST /stream { messages, threadId,         │
     │    context: { actionResults: [...] }}       │
     ├─────────────────────────────────────────────>│
     │                                              │
     │  (agent continues with result)              │
     │                                              │

Event Types

The protocol defines 9 event types covering the complete lifecycle of an agent response.

| Event | Description | |-------|-------------| | metadata | Stream initialization with threadId, requestId, agentId | | text | Streaming text output with stage lifecycle | | thinking | Model reasoning/thinking content (extended thinking) | | tool_call | Tool invocation with streaming arguments | | tool_result | Tool execution result (status and summary only) | | done | Stream complete with full content array | | error | Error condition with code and retry guidance | | aborted | Client cancellation acknowledgment | | continuation | Pause for client action (tools, approval, input) |

Terminal Events

Each request must end with exactly one terminal event: done, error, or aborted.

Event Lifecycle (Stage Pattern)

Content events (text, thinking, tool_call, tool_result) use a consistent stage pattern:

| Stage | Description | |-------|-------------| | start | Block begins, includes blockIndex for ordering | | delta | Content chunk, includes deltaIndex for ordering within block | | stop | Block complete, includes final data for that block type |

Request Schema

type AgentRequest = {
  messages: InputMessage[];   // New user input
  threadId?: string;          // Resume existing thread
  context?: {
    actionResults?: ActionResult[];  // Results from continuation events
    [key: string]: unknown;          // Additional passthrough data
  };
};

Only messages is required. The server loads thread history from storage via threadId.

Content Blocks

User Content Blocks (in requests):

  • text - Plain text input

Assistant Content Blocks (in responses):

  • text - Text output
  • thinking - Model reasoning
  • tool_use - Tool invocation with args
  • tool_result - Tool result status and summary (no full payloads)

Error Handling

Error Codes

| Code | Description | |------|-------------| | auth_failed | Authentication failed | | thread_not_found | Thread does not exist | | thread_access_denied | Thread ownership violation | | invalid_message_format | Invalid request format | | message_too_large | Message exceeds size limit | | rate_limit_exceeded | Rate limit hit | | stream_timeout | Stream timed out | | agent_error | Agent execution error | | tool_error | Tool execution error | | internal_error | Internal server error | | invalid_action_id | Action ID not found or already resolved |

HTTP Status Mapping

| Status | Error Codes | |--------|-------------| | 400 | invalid_message_format, invalid_action_id | | 401 | auth_failed | | 403 | thread_access_denied | | 404 | thread_not_found | | 413 | message_too_large | | 429 | rate_limit_exceeded | | 500 | internal_error | | 504 | stream_timeout |

Retry Guidance

  • retryable: true - Client can retry with backoff
  • retryable: false - Don't retry, user action required

SSE Transport

Server-Sent Events is the default transport implementation.

Wire Format

Content-Type: text/event-stream
Connection: keep-alive
Cache-Control: no-cache

event: metadata
data: {"event":"metadata","requestId":"req-1","threadId":"th-1","agentId":"agent","timestamp":"..."}

event: text
data: {"event":"text","requestId":"req-1","messageId":"msg-1","blockId":"b0","stage":"start","blockIndex":0,"timestamp":"..."}

event: text
data: {"event":"text","requestId":"req-1","messageId":"msg-1","blockId":"b0","stage":"delta","delta":"Hello","deltaIndex":0,"timestamp":"..."}

event: done
data: {"event":"done","requestId":"req-1","messageId":"msg-1","threadId":"th-1","content":[...],"finishReason":"stop","timestamp":"..."}

Keepalive

Servers should send SSE comment lines (: heartbeat\n\n) every 15 seconds to prevent proxy timeouts.

Utilities

import { encodeSSE, parseSSEChunk } from '@machinemetrics/agent-event-protocol';

// Server: encode events for streaming
const sseData = encodeSSE('text', { event: 'text', ... });

// Client: parse incoming chunks
const { events, remainder } = parseSSEChunk(chunk);

Extensibility

Adding new events is backward compatible:

  • Clients should ignore unknown event types
  • New optional fields can be added to existing events
  • No version bump required for additive changes

Breaking changes require new endpoint version:

/v1/agents/{agentName}/stream  → Current
/v2/agents/{agentName}/stream  → Breaking changes

Exports

import {
  // Core types
  InputMessage,
  AgentRequest,
  AgentEvent,
  ActionResult,
  UserContentBlock,
  AssistantContentBlock,
  EventStage,
  MetadataEvent,
  TextEvent,
  ThinkingEvent,
  ToolCallEvent,
  ToolResultEvent,
  DoneEvent,
  ErrorEvent,
  AbortedEvent,
  ContinuationEvent,

  // Schemas (Zod validators)
  AgentRequestSchema,
  AgentEventSchema,
  // ... all event schemas

  // SSE utilities
  encodeSSE,
  parseSSEChunk,
  ParsedEvent,
  ParseResult,

  // Constants
  PROTOCOL_VERSION,
  EVENT_TYPES,
} from '@machinemetrics/agent-event-protocol';

Development

pnpm install
pnpm build       # Build the package (ESM + CJS)
pnpm test        # Run tests
pnpm typecheck   # Type check