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 — Docker environments

task.env is always available and creates and manages Docker containers for code execution.
task.env.create() accepts these properties:
The execution output of setupScript is captured line-by-line in real time as container event logs. The runtime detail page now features a dedicated, scrollable Logs table that displays this execution output line-by-line in real time, with a precise timestamp for each line. The table shows up to 2,000 log lines. The full runtime detail page is scrollable, so you can navigate between the runtime metadata, events, and logs. This gives you step-by-step diagnostic feedback on setup progress instead of flooding other session interfaces.

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.

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, sessions, and escape hatches like experimental_fetch. 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 a user or GitHub to respond.

Flow control & HTTP

Both experimental_fetch and experimental_fetch_async accept an optional max_bytes integer parameter that caps the size of non-JSON responses. When you set max_bytes and the response content type is not application/json (for example, text/html or plain text), the runtime truncates the text to at most that many UTF-8 bytes and appends a \n\n[Response truncated to <max_bytes> bytes] marker. Parsed JSON responses are returned fully intact regardless of max_bytes. If you omit max_bytes, the runtime applies no cap and returns the full response. Use max_bytes to keep large HTML responses from overflowing an agent’s LLM context window.

Service availability