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

# Goose agents

> Build agents from Goose recipe files using the YAML recipe format.

A Goose agent is defined by a `recipe.yaml` file in the [Goose recipe format](https://block.github.io/goose/docs/guides/recipes/recipe-reference/). Instead of writing TypeScript, you describe the agent's instructions, parameters, and response schema in YAML. Guild validates the recipe at build time and runs it as a headless agent.

Use this agent type when you already have a Goose recipe or want to define agent behavior in a portable, declarative YAML format without writing code.

## Recipe file

Place `recipe.yaml` at the root of the agent's version files. It must be valid YAML with a mapping at the document root.

```yaml theme={null}
description: Review code with a configurable focus
instructions: You are a {{ language }} reviewer focused on {{ focus }}.
prompt: Review the code provided below.
parameters:
  - key: language
    input_type: select
    requirement: required
    description: Language under review
    options: [python, typescript]
  - key: focus
    input_type: string
    requirement: optional
    default: best practices
    description: Review focus area
```

## Recipe fields

Guild honors a subset of Goose recipe fields. Fields that Guild cannot honor are rejected at build time with an explicit error rather than silently ignored — a recipe author who declares an extension expects the agent to have it, and running without it would produce confusing behavior.

| Field             | Treatment                                                                  |
| ----------------- | -------------------------------------------------------------------------- |
| `description`     | **Honored** — required. Persisted as the version and agent description.    |
| `instructions`    | **Honored** — rendered and sent to the agent as its system prompt.         |
| `prompt`          | **Honored** — rendered, used as the default initial message.               |
| `parameters`      | **Honored** — drives the input schema and template rendering.              |
| `response`        | **Honored** — `json_schema` becomes the output schema.                     |
| `title`           | **Ignored** — validated as a string if present; Guild uses the agent name. |
| `version`         | **Ignored**                                                                |
| `author`          | **Ignored**                                                                |
| `activities`      | **Ignored** — desktop-only in Goose.                                       |
| `extensions`      | **Rejected** — Guild does not honor recipe extensions.                     |
| `settings`        | **Rejected** — provider and model are platform-controlled.                 |
| `sub_recipes`     | **Rejected** — not supported.                                              |
| `retry`           | **Rejected** — not supported.                                              |
| Any unknown field | **Rejected** — catches typos and unreviewed future fields.                 |

At least one of `instructions` or `prompt` must be present.

## Parameters

`parameters` is a list of mappings. Each entry defines one input variable available in the template.

| Field         | Rule                                                                                       |
| ------------- | ------------------------------------------------------------------------------------------ |
| `key`         | Required. Must match `^[a-zA-Z_][a-zA-Z0-9_]*$`. Must be unique across the list.           |
| `input_type`  | Required. One of `string`, `number`, `boolean`, `date`, `select`. `file` is not supported. |
| `requirement` | Required. One of `required`, `optional`, `user_prompt`.                                    |
| `description` | Required, non-empty string. Shown in the generated input form.                             |
| `default`     | Required for `optional` parameters; forbidden for `required` and `user_prompt` parameters. |
| `options`     | Required non-empty list of unique strings for `select`; forbidden for other types.         |

### `user_prompt` parameters

Parameters with `requirement: user_prompt` are treated as required on Guild. In Goose, these prompt the user interactively when missing. On Guild, the input form serves the same role — callers must supply them.

### Default coercion

Recipe defaults may be written typed (`default: 10`) or as strings (`default: "10"`). Guild coerces the value to the declared type:

* `number` — integer, float, or numeric string
* `boolean` — YAML boolean or `"true"`/`"false"` (case-insensitive)
* `date` — ISO `YYYY-MM-DD` string
* `select` — must be one of `options`
* `string` — any scalar

A non-coercible default is a build error.

## Template variables

`instructions` and `prompt` are Jinja-style templates. Parameters are available as template variables.

Validation rules:

* Templates must be syntactically valid.
* Every variable referenced in a template must be a declared parameter.
* Every declared parameter must appear in at least one template.
* `{{ recipe_dir }}` is not available — Guild's execution model has no recipe directory.

Templates render in a sandbox. Template expressions cannot access the host environment.

## Input schema

Guild derives the agent's input schema from the recipe's parameters. The schema is JSON Schema Draft 2020-12.

The top-level shape is:

```json theme={null}
{ "text": "...", "parameters": { "<key>": "<value>", ... } }
```

### `text`

`text` is always a `string` property in the schema.

* **Required** when the recipe has no `prompt` — callers must provide a message.
* **Optional** when the recipe has a `prompt`. Description: `"Optional message appended after the recipe's default prompt."`

### `parameters` object

`parameters` is included when the recipe declares at least one parameter. Parameters with `requirement: required` or `requirement: user_prompt` appear in the `required` array. The `parameters` object itself is required at the top level when its `required` array is non-empty.

### Type mapping

| `input_type` | JSON Schema property                      |
| ------------ | ----------------------------------------- |
| `string`     | `{"type": "string"}`                      |
| `number`     | `{"type": "number"}`                      |
| `boolean`    | `{"type": "boolean"}`                     |
| `date`       | `{"type": "string", "format": "date"}`    |
| `select`     | `{"type": "string", "enum": [<options>]}` |

Each property carries the parameter's `description`. Optional parameters carry their coerced `default`.

### Example

The recipe above produces:

```json theme={null}
{
  "type": "object",
  "properties": {
    "text": {
      "type": "string",
      "description": "Optional message appended after the recipe's default prompt."
    },
    "parameters": {
      "type": "object",
      "properties": {
        "language": {
          "type": "string",
          "enum": ["python", "typescript"],
          "description": "Language under review"
        },
        "focus": {
          "type": "string",
          "default": "best practices",
          "description": "Review focus area"
        }
      },
      "required": ["language"],
      "additionalProperties": false
    }
  },
  "required": ["parameters"],
  "additionalProperties": false
}
```

If the recipe had no `prompt` field, `text` would also appear in the top-level `required` array.

## Output schema

When `response.json_schema` is present, it is persisted verbatim as the agent's output schema.

When absent, the output schema defaults to the canonical text shape, so the agent's final answer posts to chat like an LLM agent:

```json theme={null}
{
  "type": "object",
  "properties": {
    "type": {"type": "string", "const": "text"},
    "text": {"type": "string"}
  },
  "required": ["type", "text"],
  "additionalProperties": false
}
```

## Runtime behavior

At task start, the recipe is re-read from the version's files and the input is applied as follows:

1. **Parameter values** — declared defaults, overridden by values in `input.parameters`.
2. **Template rendering** — `instructions` and `prompt` are rendered with the resolved parameter values.
3. **System prompt** — the rendered `instructions`, when present.
4. **Initial message**:
   * Recipe has no `prompt` → `text` is the initial message (the schema makes it required).
   * Recipe has a `prompt`, no `text` given → the rendered prompt.
   * Both present → the rendered prompt, then `text`, joined by a blank line.
5. **Workspace context** — when present, prepended to the recipe's `prompt` at task start, wrapped in a `{% raw %}` block so it is not treated as a template. The resulting `prompt` orders workspace context first, then the rendered recipe prompt, then `text`. Prepending the context inside the `prompt` carries it on every `--resume` turn, matching the native Goose runtime behavior.

### Chat input

Chat-originated input arrives as `{"type": "text", "text": "..."}`. When the agent's schema includes a top-level `text` string property, that input maps to `{"text": "<text>"}`. A bare chat message can only start a Goose agent whose schema does not require `parameters`.

## Integrations and sub-agents (`guild.yaml`)

A Goose agent often needs to act on external systems or delegate work to other agents. Declare these dependencies in an optional `guild.yaml` file placed at the root of the agent's version files, alongside `recipe.yaml`. Each integration operation and each sub-agent you declare becomes a tool the agent can call. Omit `guild.yaml` when the agent needs no external integrations or sub-agents.

```yaml theme={null}
integrations:
  - name: acme~github
    version: ^1.4.0
    tools: [github_repos_get, github_issues_list]

sub_agents:
  - name: acme~research
    version: ^1.0.0
```

### Integration fields

Each entry under `integrations` declares one integration dependency.

| Field     | Rule                                                                                                                                    |
| --------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `name`    | Required. The integration identifier, such as `acme~github`.                                                                            |
| `version` | Required. A semver range, such as `^1.4.0`, that must resolve to a published version.                                                   |
| `tools`   | Optional. A list of operations to expose as tools. When omitted, all operations of the resolved integration version are made available. |

### Sub-agent fields

Each entry under `sub_agents` declares one sub-agent dependency.

| Field     | Rule                                                                                  |
| --------- | ------------------------------------------------------------------------------------- |
| `name`    | Required. The sub-agent identifier, such as `acme~research`.                          |
| `version` | Required. A semver range, such as `^1.0.0`, that must resolve to a published version. |

### Validation rules

Guild validates `guild.yaml` at build time, alongside `recipe.yaml`.

* **Version resolution** — the `version` range for each integration and sub-agent must resolve to a published version. A range that resolves to no published version is a build error.
* **Tool verification** — when `tools` is specified for an integration, each listed tool must carry the integration's service prefix (for example, `github_`) and map to a real operation on the resolved integration version. A tool that does not match an available operation is a build error. When `tools` is omitted, all operations of the resolved integration version are available.
* **Access and permissions** — a public agent cannot depend on a private integration or a private sub-agent, and a sub-agent cannot be archived. See [Versions](/guide/versions) for the full dependency visibility rules.

## Build-time validation

Guild validates the full recipe when you publish a version. All validation errors are reported together — not fail-fast. On success, three values are persisted on the agent version: `description`, `input_schema`, and `output_schema`.

<Note>
  `instructions`, `prompt`, and `parameters` are not persisted on the version — the recipe file is their single source of truth. Because versions are immutable, a recipe that validated at build time parses identically at task start.
</Note>
