Skip to content

Commit 464beb5

Browse files
committed
*
1 parent 470e7ef commit 464beb5

File tree

1 file changed

+84
-59
lines changed

1 file changed

+84
-59
lines changed

modus/agents.mdx

Lines changed: 84 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ operational context.
1919
- **Autonomous**: Can operate independently over extended periods
2020
- **Actor-based**: Each agent instance runs in isolation
2121

22-
## When to use agents
22+
## When to deploy agents
2323

2424
Agents are perfect for:
2525

@@ -60,6 +60,85 @@ state management, secure communications, and mission persistence. Your
6060
operational data—mission count, assignment records, contact logs—lives as fields
6161
in the struct, automatically preserved across all interactions.
6262

63+
## Spawning agents through functions
64+
65+
Agents are deployed through regular Modus functions that become part of your
66+
GraphQL API. These deployment functions create and manage agent instances on
67+
demand:
68+
69+
```go
70+
// Register your agent type during initialization
71+
func init() {
72+
agents.Register(&OperativeAgent{})
73+
}
74+
75+
// Deploy a new agent instance - this becomes a GraphQL mutation
76+
func DeployOperative() (string, error) {
77+
agentInfo, err := agents.Start("OperativeAgent")
78+
if err != nil {
79+
return "", err
80+
}
81+
82+
// Return the agent ID - clients must store this to communicate with the agent
83+
return agentInfo.Id, nil
84+
}
85+
```
86+
87+
When you call this function through GraphQL, it returns a unique agent ID:
88+
89+
```graphql
90+
mutation {
91+
deployOperative
92+
}
93+
94+
# Returns: "agent_abc123xyz"
95+
```
96+
97+
You can think of an Agent as a persistent server process with durable memory.
98+
Once deployed, you can reference your agent by its ID across sessions, page
99+
reloads, and even system restarts. The agent maintains its complete state and
100+
continues operating exactly where it left off.
101+
102+
<Note>
103+
**Agent builders and visual workflows:** We're actively developing Agent
104+
Builder tools and "eject to code" feature that generates complete agent
105+
deployments from visual workflows. These tools automatically create the
106+
deployment functions and agent management code for complex multi-agent
107+
systems.
108+
</Note>
109+
110+
## Communicating with your agent
111+
112+
Once deployed, you communicate with your agent using its unique ID. Create
113+
functions that send messages to specific agent instances:
114+
115+
```go
116+
func AcceptMission(agentId string, missionType string) (string, error) {
117+
result, err := agents.SendMessage(agentId, "accept_mission", agents.WithData(missionType))
118+
if err != nil {
119+
return "", err
120+
}
121+
if result == nil {
122+
return "", fmt.Errorf("no response from agent")
123+
}
124+
return *result, nil
125+
}
126+
```
127+
128+
This function becomes a GraphQL mutation that you can call with your agent's ID:
129+
130+
```graphql
131+
mutation {
132+
acceptMission(agentId: "agent_abc123xyz", missionType: "surveillance")
133+
}
134+
135+
# Returns: "Mission 1 accepted. Status: Active"
136+
```
137+
138+
The agent receives the `accept_mission` message, processes it using its internal
139+
state, updates its mission count and assignment history, and returns a
140+
response—all while maintaining persistent memory of every interaction.
141+
63142
## Agent message handling
64143

65144
Agents process operational directives through their secure message handling
@@ -179,64 +258,6 @@ func (o *OperativeAgent) OnTerminate() error {
179258
}
180259
```
181260

182-
## Deploying and controlling agents
183-
184-
Agents must be registered and then deployed through functions that become part
185-
of your GraphQL API.
186-
187-
First, register your agent in the `init()` function:
188-
189-
```go
190-
func init() {
191-
agents.Register(&OperativeAgent{})
192-
}
193-
```
194-
195-
Create a function to deploy new agent instances. This function becomes a GraphQL
196-
mutation:
197-
198-
```go
199-
func DeployOperative() (string, error) {
200-
agentInfo, err := agents.Start("OperativeAgent")
201-
if err != nil {
202-
return "", err
203-
}
204-
205-
// Return the agent ID - clients must store this to communicate with the agent
206-
return agentInfo.Id, nil
207-
}
208-
```
209-
210-
Create functions to communicate with specific agent instances using their ID:
211-
212-
```go
213-
func AssignMission(agentId string, missionType string) (string, error) {
214-
result, err := agents.SendMessage(agentId, "accept_mission", agents.WithData(missionType))
215-
if err != nil {
216-
return "", err
217-
}
218-
if result == nil {
219-
return "", fmt.Errorf("no response from agent")
220-
}
221-
return *result, err
222-
}
223-
224-
func GetMissionStatus(agentId string) (string, error) {
225-
result, err := agents.SendMessage(agentId, "mission_status")
226-
if err != nil {
227-
return "", err
228-
}
229-
if result == nil {
230-
return "", fmt.Errorf("no response from agent")
231-
}
232-
return *result, err
233-
}
234-
```
235-
236-
**Important**: clients must store the agent ID returned from `DeployOperative()`
237-
to communicate with that specific agent instance. Each agent maintains its own
238-
independent state and can only be accessed through its unique ID.
239-
240261
## Agent workflow example
241262

242263
1. Client calls `DeployOperative()` → receives agent ID `"agent_12345"`
@@ -247,6 +268,10 @@ independent state and can only be accessed through its unique ID.
247268
from memory
248269
5. Agent persists across system restarts, maintaining all mission history
249270

271+
**Important**: clients must store the agent ID returned from deployment
272+
functions to communicate with that specific agent instance. Each agent maintains
273+
its own independent state and can only be accessed through its unique ID.
274+
250275
## Beyond simple operations
251276

252277
Agents enable sophisticated operational patterns impossible with stateless

0 commit comments

Comments
 (0)