Documentation Index
Fetch the complete documentation index at: https://docs.guild.ai/llms.txt
Use this file to discover all available pages before exploring further.
Auto-managed state agents (using AutomaticallyManagedStateAgent) are TypeScript functions you write yourself. They execute deterministically from start to finish, with no LLM driving the control flow — though you can call LLMs as needed within your code.
The runtime handles state persistence automatically. You write a straightforward async run function, and the babel-plugin-agent-compiler transforms it into a resumable state machine behind the scenes.
Example
Add the "use agent" directive at the top of your file so the runtime can manage state between tool calls.
"use agent"
import {
type Task,
agent,
pick,
progressLogNotifyEvent,
userInterfaceTools,
} from "@guildai/agents-sdk"
import { gitHubTools } from "@guildai-services/guildai~github"
import { z } from "zod"
const inputSchema = z.object({
repo: z.string().describe("The GitHub repository in 'owner/name' format"),
issue_number: z.number().describe("The issue number to summarize"),
})
type Input = z.infer<typeof inputSchema>
const outputSchema = z.object({
summary: z.string(),
labels: z.array(z.string()),
})
type Output = z.infer<typeof outputSchema>
const tools = {
...userInterfaceTools,
...pick(gitHubTools, [
"github_issues_get",
"github_issues_list_comments",
]),
}
type Tools = typeof tools
async function run(input: Input, task: Task<Tools>): Promise<Output> {
const [owner, repo] = input.repo.split("/")
await task.ui?.notify(progressLogNotifyEvent("Fetching issue..."))
const issue = await task.tools.github_issues_get({
owner,
repo,
issue_number: input.issue_number,
})
// Use LLM to summarize
const result = await task.llm.generateText({
prompt: `Summarize this GitHub issue:\n\n${issue?.body}`,
})
return {
summary: result.text,
labels: issue?.labels?.map((l) => l.name) ?? [],
}
}
export default agent({
description: "Summarizes a GitHub issue and extracts its labels.",
inputSchema,
outputSchema,
tools,
run,
})
The runtime only supports @guildai/agents-sdk and zod. See the SDK introduction for details.
Define your schemas using Zod. The runtime uses them to validate input and expose the agent as a typed tool for orchestrating agents.
const inputSchema = z.object({
message: z.string().describe("The message to process"),
})
const outputSchema = z.object({
response: z.string(),
})
Error handling
Any exception thrown from your run function is returned to the calling agent or user. Use standard TypeScript error handling:
async function run(input: Input, task: Task<Tools>): Promise<Output> {
try {
// ...
} catch (error) {
const message = error instanceof Error ? error.message : String(error)
throw new Error(`Failed to process: ${message}`)
}
}
Limitations
The "use agent" directive relies on the Babel compiler to transform your code into a state machine. This means:
- No
Promise.all, Promise.any, or Promise.race — parallel tool calls require a self-managed state agent
- No dynamic function references across
await points — conditionally assigned functions may not survive serialization
- No external imports — only
@guildai/agents-sdk, zod, and @guildai-services/* are supported
When to use auto-managed state
| Situation | Use auto-managed? |
|---|
| Algorithmic, sequential logic | Yes |
| You want minimal boilerplate | Yes |
| You need parallel tool calls | No — use self-managed state |
| You need full control over state | No — use self-managed state |