Skip to main content

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.

Input and output schemas

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

SituationUse auto-managed?
Algorithmic, sequential logicYes
You want minimal boilerplateYes
You need parallel tool callsNo — use self-managed state
You need full control over stateNo — use self-managed state