Skip to main content
Every agent callback — run, start, onToolResults, init — receives a Task object as its last argument. The task is your agent’s interface to the Guild runtime: it exposes services for calling platform endpoints, talking to the user, logging, and persisting state.
The shape of task is conditional on the Tools type: task.guild is typed as GuildService only when Tools structurally extends GuildToolSet, and task.ui is UserInterfaceService only when Tools extends UserInterfaceToolSet. Including the corresponding tool set in your agent’s tools is how you “turn on” the service.

Typical usage

Most agents only need a handful of services. Here’s a small agent that uses task.console, task.ui, and task.guild:

task.sessionId

The opaque session identifier for the current agent run. Use it to correlate logs, emit metrics, or pass to endpoints that take a session id.

task.console — debug logging

task.console is always available and never requires a tool set. Use it for printf-style debugging visible in the runtime logs. Each level accepts either a message string, an object + message, or arbitrary variadic arguments.
To expose debug logging to an LLM, include consoleTools in your agent — the LLM can then call console_log as a regular tool.

task.tools — invoke your tools directly

task.tools is a typed proxy over every tool declared in the agent’s tools set. Calling task.tools.foo(args) dispatches to the tool and returns its output with the tool’s declared output type.
This works for any tool, whether it’s a built-in tool set (guildTools, userInterfaceTools, …), a third-party service tool (gitHubTools), or a custom tool created with guildServiceTool / guildAgentTool.

task.gather — concurrent tool calls

task.gather runs an array of tool or sub-agent calls concurrently. It has Promise.all semantics: if any call fails, the entire batch rejects with that error. If all calls succeed, it resolves to an array of results in source order.
Under the hood, synchronous tool calls execute in-process on a fast path. Deferred calls — such as sub-agent invocations — are batched: the agent’s state machine suspends, all deferred calls are dispatched together, and execution resumes once every call has settled. Results are always returned in source order.

task.gatherSettled — concurrent calls with individual outcomes

task.gatherSettled runs an array of tool or sub-agent calls concurrently. It has Promise.allSettled semantics: it never rejects. Instead, it resolves to an array of PromiseSettledResult objects in source order, each containing either { status: "fulfilled", value: result } or { status: "rejected", reason: Error }. Use task.gatherSettled when you want to inspect per-call failures rather than stopping the entire batch on the first error.
The execution model is the same as task.gather: synchronous calls take the fast path, and deferred calls are batched and resumed together.

task.env — workspace variables

task.env is always available. It holds the workspace’s variables, resolved when the task dispatches or resumes.
Keys are uppercase identifiers. Reading a key that has no value throws, naming the key — it never returns undefined, so a missing variable fails loudly instead of silently becoming undefined deep in your agent. Values are stable within a turn and refreshed between turns, so an edit made mid-task takes effect on the next resume at the earliest.
task.env does not create or manage containers. To run code in a container, use the guildai~experimental-coding integration through task.tools — see Running code in a container.

Running code in a container

Container-backed coding environments are an integration, reached through task.tools like any other: experimental_coding_create takes an environment (an owner~name runtime environment, preferred) or an image, plus optional env variables for the setup script, a timeout in seconds (default 600), and debug_mode to stream setup output to the runtime detail page.
The setup script is owner-declared — it lives on the runtime environment, not on the call — so a caller cannot supply one. An environment with no setup script makes setup a no-op.
Setup output is captured line-by-line as container event logs. The runtime detail page has a scrollable Logs table showing that output with a timestamp per line, up to 2,000 lines. Error lines stream regardless of debug_mode; other setup output streams only when you enable it.

task.ui — user interaction

Available when Tools includes userInterfaceTools. task.ui is a UserInterfaceService that can send notifications, ask the user for input, or ping the front-end.

Notify event helpers

notify takes a discriminated NotifyEvent with message, progress, or error types. These helpers in @guildai/agents-sdk construct the supported shapes:

Prompting the user

task.ui.prompt blocks the agent until the user replies. It’s the imperative counterpart to the ask(...) helper used by self-managed agents.
task.ui is available when your agent includes userInterfaceTools.

Progress logging

Progress logs give users real-time feedback during long-running operations. They appear inline without requiring user interaction.
Best practices:
  • Use present continuous tense: “Creating…”, “Running…”, “Writing…”
  • Keep messages to one line
  • Be specific: “Writing 3 files…” rather than “Processing…”
  • Log at meaningful milestones, not on every iteration

task.llm — LLM calls

task.llm always exposes an LLMService. The runtime handles authentication and provider selection, so you don’t need to pass API keys or pick a model explicitly. generateText takes either a single prompt or a messages array, never both:
Pass tools to generateText if you want the LLM to request tool calls; the returned toolCalls array lists what it decided to invoke. Pass llmPreferences to request specific providers or models for the call. Preferences are strict: if none of them is permitted by the account’s keys and policies, the call fails rather than falling back to the default model. See LLM preferences.

generateText makes a single model call

generateText sends the messages, gets one response back, and returns. There is no maxSteps and no stopWhen, so there is no built-in ReAct loop. Tools you pass with an execute function are run, so result.toolResults may be populated — but the model is never called again with those results. A turn that ends in a tool call comes back with finishReason: "tool-calls" and text that stops mid-thought. If the agent must call a tool, read what it returned, and continue, write that loop yourself:
dispatch and asToolResultContent are yours to write — the first runs the calls, the second shapes them into tool-result content parts. Bound the loop clear of normal use: a ceiling a legitimate request can reach truncates that request silently. If you would rather not write the loop, llmAgent is the managed version, and a self-managed agent’s start() / onToolResults() pair lets the runtime drive the round trip. Hand-roll only when you need control over each step.

task.save / task.restore — state persistence

Used by SelfManagedStateAgent (and available to automatic-state agents too): State is scoped to the current task, and is retained across suspensions (e.g., while waiting for user input).

task.guild — platform operations

Available when Tools structurally includes GuildToolSet. task.guild is a GuildService that exposes the full Guild platform API — workspaces, agents, triggers, credentials, and sessions. Because task.guild is conditionally typed, TypeScript types it as GuildService | undefined until it can prove your tool set includes guildTools. A common pattern is to assert non-null with ! after ensuring guildTools is in the spread:
The 50+ endpoints below are grouped by theme. All of them take a single params object and return a structured response; each takes a single params object and returns a structured response.

Current user

Users

Agents

Agent likes

Organizations

Workspaces

Triggers

Sessions & tasks

LLM usage

Credentials & install hooks

These endpoints may suspend the agent while waiting for the user to respond.

Flow control

task.guild makes no outbound HTTP requests on your behalf. To fetch an arbitrary URL, use the guildai~experimental-fetch integration — see Fetching an arbitrary URL.

Service availability