> ## 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.

# Task object

> Access Guild platform services, user interaction, and LLMs from your agent.

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.

```typescript theme={null}
async function run(input: Input, task: Task<Tools>): Promise<Output> {
  // task.sessionId, task.console, task.tools
  // task.guild, task.ui, task.llm, task.env
  // task.save, task.restore
}
```

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`:

```typescript theme={null}
import {
  agent,
  guildTools,
  progressLogNotifyEvent,
  userInterfaceTools,
  type Task,
} from "@guildai/agents-sdk"
import { z } from "zod"

const inputSchema = z.object({ workspace_id: z.string() })
const outputSchema = z.object({
  workspace_name: z.string(),
  context_count: z.number(),
})

const tools = { ...guildTools, ...userInterfaceTools }
type Tools = typeof tools

async function run(
  input: z.infer<typeof inputSchema>,
  task: Task<Tools>,
): Promise<z.infer<typeof outputSchema>> {
  "use agent"
  task.console.info({ sessionId: task.sessionId }, "starting run")

  await task.ui.notify(progressLogNotifyEvent("Fetching workspace..."))
  const workspace = await task.guild!.get_workspace({
    workspace_id: input.workspace_id,
  })

  await task.ui.notify(progressLogNotifyEvent("Checking context history..."))
  const { items } = await task.guild!.get_workspace_contexts({
    workspace_id: input.workspace_id,
    limit: 100,
  })

  return { workspace_name: workspace.name, context_count: items.length }
}

export default agent({
  description: "Typical task usage.",
  inputSchema,
  outputSchema,
  tools,
  run,
})
```

## `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.

```typescript theme={null}
task.console.debug({ sessionId: task.sessionId }, "starting work")
```

## `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.

| Method                            | Description                                        |
| --------------------------------- | -------------------------------------------------- |
| `debug(msg or obj, ...args)`      | Debug-level message                                |
| `info(msg or obj, ...args)`       | Info-level message                                 |
| `warn(msg or obj, ...args)`       | Warning message                                    |
| `error(msg or obj, ...args)`      | Error message                                      |
| `log(msg or obj, ...args)`        | Alias for `info`                                   |
| `console_log({ level, message })` | Structured variant matching the `console_log` tool |

```typescript theme={null}
await task.console.debug({ input }, "received request")
await task.console.error("aborting: invalid state")
```

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.

```typescript theme={null}
const workspace = await task.tools.guild_get_workspace({
  workspace_id: "ws_123",
})
```

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.

```typescript theme={null}
const [pr, comments] = await task.gather([
  task.tools.github_pulls_get({ owner: "myorg", repo: "myrepo", pull_number: 123 }),
  task.tools.github_issues_list_comments({ owner: "myorg", repo: "myrepo", issue_number: 123 }),
])
```

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.

```typescript theme={null}
const results = await task.gatherSettled([
  task.tools.github_pulls_get({ owner: "myorg", repo: "myrepo", pull_number: 1 }),
  task.tools.github_pulls_get({ owner: "myorg", repo: "myrepo", pull_number: 2 }),
])

for (const result of results) {
  if (result.status === "fulfilled") {
    console.log("PR title:", result.value.title)
  } else {
    console.error("Failed:", result.reason)
  }
}
```

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.

```typescript theme={null}
await task.env.create({ baseImage: "node:20" })
const result = await task.env.exec({ command: "npm test" })
await task.env.destroy()
```

`task.env.create()` accepts these properties:

| Property      | Type   | Description                                     |
| ------------- | ------ | ----------------------------------------------- |
| `baseImage`   | string | Docker image for the container.                 |
| `setupScript` | string | Shell script run during setup of the container. |

<Note>
  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.
</Note>

## `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.

| Method                           | Description                                                       |
| -------------------------------- | ----------------------------------------------------------------- |
| `notify(event)`                  | Fire-and-forget notification. Use the event helpers listed below. |
| `prompt({ type: "text", text })` | Block until the user replies with text.                           |
| `ping({ message })`              | Health-check the UI surface (mostly for testing).                 |

### Notify event helpers

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

| Helper                                          | Event type | Use for                                                                   |
| ----------------------------------------------- | ---------- | ------------------------------------------------------------------------- |
| `progressLogNotifyEvent(text)`                  | `progress` | Non-intrusive "Creating...", "Running..." status updates during long work |
| `textPromptNotifyEvent({ type: "text", text })` | `message`  | A regular message posted to the session                                   |
| `errorNotifyEvent(error)`                       | `error`    | Prominently-displayed error condition                                     |

```typescript theme={null}
import {
  progressLogNotifyEvent,
  textPromptNotifyEvent,
  errorNotifyEvent,
} from "@guildai/agents-sdk"

await task.ui.notify(progressLogNotifyEvent("Creating environment..."))
await task.ui.notify(
  textPromptNotifyEvent({ type: "text", text: "Here's what I found." }),
)
await task.ui.notify(errorNotifyEvent("Failed to reach GitHub"))
```

### 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.

```typescript theme={null}
const reply = await task.ui.prompt({
  type: "text",
  text: "Which language should I use?",
})
// reply.text contains the user's answer
```

`task.ui` is available when your agent includes [`userInterfaceTools`](/sdk/tools#userinterfacetools).

## Progress logging

Progress logs give users real-time feedback during long-running operations. They appear inline without requiring user interaction.

```typescript theme={null}
import { progressLogNotifyEvent } from "@guildai/agents-sdk"

await task.ui?.notify(progressLogNotifyEvent("Creating coding environment..."))
await task.env.create({ baseImage: "node:20" })

await task.ui?.notify(progressLogNotifyEvent("Running tests..."))
const result = await task.env.exec({ command: "npm test" })
```

**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.

| Method                 | Description                                                                                                       |
| ---------------------- | ----------------------------------------------------------------------------------------------------------------- |
| `generateText(params)` | Call the workspace's configured LLM. Returns `{ text, content, toolCalls, toolResults, finishReason, response }`. |

`generateText` takes either a single `prompt` or a `messages` array, never both:

```typescript theme={null}
const result = await task.llm.generateText({
  prompt: "Summarize this file:\n\n" + source,
})
// result.text — plain-text summary

const chat = await task.llm.generateText({
  system: "You are a concise assistant.",
  messages: [
    { role: "user", content: "What is Guild?" },
  ],
})
```

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):

| Method        | Description                                                                        |
| ------------- | ---------------------------------------------------------------------------------- |
| `save(state)` | Persist `state` to the runtime. Must match `stateSchema` and be JSON-serializable. |
| `restore()`   | Read the previously-saved state, or `undefined` if nothing is saved yet.           |

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:

```typescript theme={null}
const tools = { ...guildTools }
// ...
const { items } = await task.guild!.get_workspace_contexts({
  workspace_id: input.workspace_id,
  limit: 10,
})
```

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

| Endpoint               | Description                                             |
| ---------------------- | ------------------------------------------------------- |
| `get_me`               | Fetch the authenticated user's profile                  |
| `update_me`            | Update the authenticated user's profile                 |
| `get_my_workspaces`    | List workspaces owned by or visible to the current user |
| `get_my_organizations` | List organizations the current user belongs to          |
| `get_my_sessions`      | List recent sessions for the current user               |

### Users

| Endpoint                 | Description                                                                                       |
| ------------------------ | ------------------------------------------------------------------------------------------------- |
| `search_users`           | Full-text search across users                                                                     |
| `get_user`               | Look up a specific user by id                                                                     |
| `get_user_organizations` | List organizations a user belongs to                                                              |
| `get_user_agents`        | List agents a user has authored. Accepts `agent_types` (comma-separated) to filter by agent type. |
| `get_user_workspaces`    | List workspaces a user can access                                                                 |

### Agents

| Endpoint                   | Description                                                                                |
| -------------------------- | ------------------------------------------------------------------------------------------ |
| `list_agents`              | Paginated list of agents. Accepts `agent_types` (comma-separated) to filter by agent type. |
| `search_agent`             | Keyword search across agents                                                               |
| `check_agent_name`         | Check whether an agent name is available                                                   |
| `get_agent`                | Fetch a single agent by id                                                                 |
| `create_agent`             | Create a new agent                                                                         |
| `update_agent`             | Update an existing agent                                                                   |
| `get_agent_code`           | Read the source code of an agent version                                                   |
| `list_agent_versions`      | List historical versions of an agent                                                       |
| `create_agent_version`     | Publish a new version of an agent                                                          |
| `get_agent_version`        | Fetch a specific version by id                                                             |
| `revalidate_agent_version` | Rerun validation on an existing version                                                    |
| `list_agent_tags`          | List tags attached to an agent                                                             |
| `update_agent_tags`        | Replace the set of tags on an agent                                                        |
| `generate_agent_avatar`    | Generate an avatar image for an agent                                                      |

### Agent likes

| Endpoint                | Description                                           |
| ----------------------- | ----------------------------------------------------- |
| `create_agent_like`     | Like an agent on behalf of the current user           |
| `delete_agent_like`     | Unlike an agent                                       |
| `list_agent_likers`     | List the users who have liked a given agent           |
| `list_agent_workspaces` | List the workspaces that have installed a given agent |

### Organizations

| Endpoint                      | Description                                                                                      |
| ----------------------------- | ------------------------------------------------------------------------------------------------ |
| `get_organization`            | Fetch an organization by id                                                                      |
| `update_organization`         | Update an organization                                                                           |
| `get_organization_workspaces` | List workspaces in an organization                                                               |
| `get_organization_agents`     | List agents in an organization. Accepts `agent_types` (comma-separated) to filter by agent type. |
| `get_organization_members`    | List members of an organization                                                                  |

### Workspaces

| Endpoint                   | Description                                                                 |
| -------------------------- | --------------------------------------------------------------------------- |
| `get_workspace`            | Fetch a workspace by id                                                     |
| `get_workspace_agents`     | List agents installed in a workspace                                        |
| `get_workspace_sessions`   | List sessions in a workspace                                                |
| `get_workspace_contexts`   | List versions of the [workspace context](/workspace-context) (newest first) |
| `create_workspace_context` | Append a new `DRAFT` or `PUBLISHED` workspace context version               |

### Triggers

| Endpoint                   | Description                        |
| -------------------------- | ---------------------------------- |
| `get_workspace_triggers`   | List triggers in a workspace       |
| `create_workspace_trigger` | Create a new trigger               |
| `get_trigger`              | Fetch a trigger by id              |
| `update_trigger`           | Update a trigger                   |
| `activate_trigger`         | Enable a trigger                   |
| `deactivate_trigger`       | Disable a trigger                  |
| `get_trigger_sessions`     | List sessions created by a trigger |

### Sessions & tasks

| Endpoint                    | Description                                                                                                                                           |
| --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| `get_session`               | Fetch a session by id                                                                                                                                 |
| `get_task_workspace_agents` | List workspace agents available to the current task (used internally by `llmAgent`). Accepts `agent_types` (comma-separated) to filter by agent type. |

### LLM usage

| Endpoint               | Description                |
| ---------------------- | -------------------------- |
| `get_daily_llm_usage`  | Daily token usage rollups  |
| `get_hourly_llm_usage` | Hourly token usage rollups |

### Credentials & install hooks

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

| Endpoint                                 | Description                                                            |
| ---------------------------------------- | ---------------------------------------------------------------------- |
| `agent_install_request`                  | Ask the user to install another agent into the workspace               |
| `credentials_request`                    | Ask the user to authorize a third-party service (e.g., Linear, GitHub) |
| `experimental_github_installation_token` | Mint a GitHub installation token for the current workspace             |

### Flow control & HTTP

| Endpoint                   | Description                                                  |
| -------------------------- | ------------------------------------------------------------ |
| `sleep`                    | Suspend the agent for N seconds (may round-trip the runtime) |
| `experimental_fetch`       | Synchronous HTTP request                                     |
| `experimental_fetch_async` | Async HTTP request — result arrives via a hook when complete |

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

| Property                             | When available                         |
| ------------------------------------ | -------------------------------------- |
| `task.sessionId`                     | Always                                 |
| `task.console`                       | Always                                 |
| `task.tools`                         | Always — contains your declared tools  |
| `task.gather` / `task.gatherSettled` | Always                                 |
| `task.llm`                           | Always                                 |
| `task.env`                           | Always                                 |
| `task.ui`                            | Requires `userInterfaceTools` in tools |
| `task.guild`                         | Requires `guildTools` in tools         |
| `task.save()` / `task.restore()`     | `SelfManagedStateAgent` only           |
