While each Modus SDK offers similar capabilities, the APIs and usage may vary between languages.

Modus Agents APIs documentation is available on the following pages:

The Modus Agents APIs allow you to create stateful agents that maintain persistent memory across interactions, survive system failures, and coordinate complex multi-step operations.

Import

To begin, import the agents namespace and Agent base class from the SDK:

import { agents, Agent, AgentInfo, AgentEvent } from "@hypermode/modus-sdk-as"

Agent APIs

The APIs in the agents namespace are below, organized by category.

We’re constantly introducing new APIs through ongoing development with early users. Please open an issue if you have ideas on what would make Modus even more powerful for your next app!

Agent Management Functions

register

Register an agent class with the Modus runtime before it can be instantiated.

function register<T extends Agent>(): void
T
required

The agent class type that extends the Agent base class.

Agent registration must be done at the module level, outside of any function.

start

Create and start a new agent instance.

function start(agentName: string): AgentInfo
agentName
string
required

The name of the agent class to instantiate. This must match the name property returned by the agent class.

stop

Stop an agent instance. Once stopped, the agent can’t be resumed.

function stop(agentId: string): AgentInfo
agentId
string
required

The unique identifier of the agent instance to stop.

get info

Get information about a specific agent instance.

function getInfo(agentId: string): AgentInfo
agentId
string
required

The unique identifier of the agent instance.

list all

List all active agent instances.

function listAll(): AgentInfo[]

Communication Functions

send message

Send a synchronous message to an agent and wait for a response.

function sendMessage(
  agentId: string,
  messageName: string,
  data: string | null = null,
): string | null
agentId
string
required

The unique identifier of the target agent instance.

messageName
string
required

The name of the message to send to the agent.

data
string | null

Optional data payload to send with the message.

sendMessageAsync

Send an asynchronous message to an agent without waiting for a response.

function sendMessageAsync(
  agentId: string,
  messageName: string,
  data: string | null = null,
): void
agentId
string
required

The unique identifier of the target agent instance.

messageName
string
required

The name of the message to send to the agent.

data
string | null

Optional data payload to send with the message.

Agent Base Class

Agent

The base class that all agents must extend.

abstract class Agent {
  abstract get name(): string
  abstract onReceiveMessage(
    messageName: string,
    data: string | null,
  ): string | null

  getState(): string | null
  setState(data: string | null): void
  onInitialize(): void
  onSuspend(): void
  onResume(): void
  onTerminate(): void
  publishEvent(event: AgentEvent): void
}
name
string
required

Abstract property that must return a unique name for the agent class.

onReceiveMessage(messageName, data)
method
required

Abstract method that handles incoming messages to the agent. Must be implemented by all agent classes.

getState()
method

Optional method that returns the agent’s current state as a string for persistence. Called automatically when the agent needs to be suspended or migrated.

setState(data)
method

Optional method that restores the agent’s state from a string. Called automatically when the agent is resumed or migrated.

onInitialize()
method

Optional lifecycle method called when the agent is first created.

onSuspend()
method

Optional lifecycle method called when the agent is about to be suspended.

onResume()
method

Optional lifecycle method called when the agent is resumed from suspension.

onTerminate()
method

Optional lifecycle method called when the agent is about to be terminated.

publishEvent(event)
method

Publishes an event from this agent to any subscribers. The event must extend the AgentEvent base class.

Event Classes

AgentEvent

Base class for agent events that can be published to subscribers.

abstract class AgentEvent {
  readonly eventName: string

  constructor(eventName: string)
}
eventName
string
required

The name of the event type. Must be provided in the constructor and can’t be empty.

Custom events should extend this class and include any additional data as properties:

@json
class CountUpdated extends AgentEvent {
  constructor(public count: i32) {
    super("countUpdated")
  }
}

Types

AgentInfo

Information about an agent instance.

class AgentInfo {
  id: string
  name: string
  status: string
}
id
string

The unique identifier of the agent instance.

name
string

The name of the agent class.

status
string

The current status of the agent instance.

Example Usage

Here’s a complete example of a simple counter agent with event streaming:

Agent Implementation

import { Agent, AgentEvent } from "@hypermode/modus-sdk-as"

export class CounterAgent extends Agent {
  get name(): string {
    return "Counter"
  }

  private count: i32 = 0

  getState(): string | null {
    return this.count.toString()
  }

  setState(data: string | null): void {
    if (data == null) {
      return
    }
    this.count = i32.parse(data)
  }

  onInitialize(): void {
    console.info("Counter agent started")
  }

  onReceiveMessage(name: string, data: string | null): string | null {
    if (name == "count") {
      return this.count.toString()
    }

    if (name == "increment") {
      if (data != null) {
        this.count += i32.parse(data)
      } else {
        this.count++
      }

      // Publish an event to subscribers
      this.publishEvent(new CountUpdated(this.count))

      return this.count.toString()
    }

    return null
  }
}

// Custom event for count updates
@json
class CountUpdated extends AgentEvent {
  constructor(public count: i32) {
    super("countUpdated")
  }
}

Function Integration

import { agents, AgentInfo } from "@hypermode/modus-sdk-as"
import { CounterAgent } from "./counterAgent"

// Register the agent
agents.register<CounterAgent>()

export function startCounterAgent(): AgentInfo {
  return agents.start("Counter")
}

export function getCount(agentId: string): i32 {
  const count = agents.sendMessage(agentId, "count")
  if (count == null) {
    return 0
  }
  return i32.parse(count)
}

export function updateCount(agentId: string): i32 {
  const count = agents.sendMessage(agentId, "increment")
  if (count == null) {
    return 0
  }
  return i32.parse(count)
}

export function updateCountAsync(agentId: string, qty: i32): void {
  agents.sendMessageAsync(agentId, "increment", qty.toString())
}

GraphQL Usage

Once deployed, your agent functions become available via GraphQL:

# Start a new agent
mutation {
  startCounterAgent {
    id
    name
    status
  }
}

# Get the current count
query {
  getCount(agentId: "agent_abc123")
}

# Increment the count
mutation {
  updateCount(agentId: "agent_abc123")
}

# Subscribe to real-time events
subscription {
  agentEvent(agentId: "agent_abc123") {
    name
    data
    timestamp
  }
}

Event Subscription

To receive real-time events from your agent, subscribe using GraphQL subscriptions over Server-Sent Events:

subscription CounterEvents($agentId: String!) {
  agentEvent(agentId: $agentId) {
    name
    data
    timestamp
  }
}

Example events you might receive:

{
  "data": {
    "agentEvent": {
      "name": "countUpdated",
      "data": {
        "count": 5
      },
      "timestamp": "2025-06-08T14:30:00Z"
    }
  }
}
{
  "data": {
    "agentEvent": {
      "name": "status",
      "data": {
        "status": "running"
      },
      "timestamp": "2025-06-08T14:30:05Z"
    }
  }
}

Client Integration

Use appropriate GraphQL Server-Sent Events (SSE) clients such as:

  • graphql-sse for vanilla JavaScript
  • urql with Server-Sent Events (SSE) exchange
  • EventSource API directly for simple use cases

Example with EventSource:

const eventSource = new EventSource(
  '/graphql?query=subscription{agentEvent(agentId:"agent_abc123"){name,data,timestamp}}',
  {
    headers: {
      Accept: "text/event-stream",
    },
  },
)

eventSource.addEventListener("next", (event) => {
  const data = JSON.parse(event.data)
  console.log("Agent event:", data)
})