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
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
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
The unique identifier of the agent instance to stop.
get info
Get information about a specific agent instance.
function getInfo(agentId: string): AgentInfo
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
The unique identifier of the target agent instance.
The name of the message to send to the agent.
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
The unique identifier of the target agent instance.
The name of the message to send to the agent.
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
}
Abstract property that must return a unique name for the agent class.
onReceiveMessage(messageName, data)
Abstract method that handles incoming messages to the agent. Must be
implemented by all agent classes.
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.
Optional method that restores the agent’s state from a string. Called
automatically when the agent is resumed or migrated.
Optional lifecycle method called when the agent is first created.
Optional lifecycle method called when the agent is about to be suspended.
Optional lifecycle method called when the agent is resumed from suspension.
Optional lifecycle method called when the agent is about to be terminated.
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)
}
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
}
The unique identifier of the agent instance.
The name of the agent class.
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)
})
Responses are generated using AI and may contain mistakes.