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.
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 usestask.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.
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.
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.
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.
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.
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 throughtask.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.- 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:
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:
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.