> This page is for Agent Studio.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.moveworks.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.moveworks.com/_mcp/server.

# Collect Slots and Resolve Values

A slot is a typed value the assistant collects or infers during a conversation. Treat slots as the input contract of the conversation process, not as free-form prompt variables.

## Step 1: Choose the Most Specific Type

Use the type that matches the downstream contract:

| Need                | Slot type                         |
| ------------------- | --------------------------------- |
| Free-form text      | `string`                          |
| Count or amount     | `integer` or `number`             |
| Yes or no           | `boolean`                         |
| Date or time        | `string` with a documented format |
| One business object | `object` or custom data type      |
| Several values      | `List[Type]`                      |
| Moveworks person    | `User` or `List[User]`            |
| Uploaded attachment | `File` or `List[File]`            |

Prefer a `User` object over an email string when the value represents a Moveworks user. Prefer a resolved business object over a display name when an API requires a stable record ID.

Agent Studio does not provide a native date-time slot type. Collect a `string`, describe the expected date or time, and validate it with a DSL expression such as `$PARSE_TIME(value) >= $TIME()`.

## Step 2: Write a Collection-Focused Description

A slot description helps the reasoning engine understand:

* What the value represents.
* Which user language commonly identifies it.
* Whether the value refers to the current user or another person.
* What clarification is useful when the value is ambiguous.
* Which details do not belong in the slot.

Descriptions guide inference. They do not enforce a business rule.

> **Do Not Request Hidden Conversation Fields**
>
> Do not ask users to provide internal conversation-history fields in slot descriptions. Define the business value you need.

## Step 3: Choose the Inference Policy

#### Always Ask

The assistant explicitly asks for the value, even when the conversation appears to contain it.

Use this when the user must make a deliberate choice or when inference would be unsafe.

#### Infer if Available

The assistant uses a clear value already present in the conversation and asks when it cannot infer one.

Use this as the common default for ordinary business inputs.

#### Always Infer

The assistant attempts to derive the value without asking.

This policy requires a fallback value. Do not use it for a file slot: suppressing the upload prompt prevents meaningful file collection. Use **Infer if Available** or **Always Ask** for files, and use a `null` fallback when the file is optional.

## Step 4: Add Deterministic Validation

Use DSL validation when a value must satisfy an exact rule:

```text
value >= 1 AND value <= 25
```

If validation fails, the assistant can explain the requirement and recollect the slot.

Good validation targets include:

* Numeric ranges.
* Allowed state transitions.
* Date boundaries.
* Required string patterns.
* Whether a selected object contains a required property.

Do not bury the same rule only in the slot description. Let the description explain and let the validator enforce.

> **Validate the Current Candidate**
>
> Slot validation evaluates the current candidate as `value`. Use a decision policy for cross-slot conversational flow, strategy mapping when resolver choices depend on an earlier slot, or a compound-action precondition for backend business rules.

## Step 5: Add a Resolver When Values Come from a Set

A resolver translates natural language into an allowed value or business object.

#### Static Resolver

Define a fixed list of display values and raw values.

Example:

| User-facing label | Raw value   |
| ----------------- | ----------- |
| New               | `New`       |
| Planned           | `Planned`   |
| Delivered         | `Delivered` |

The user can say "mark it as planned." The selection binds an object with `display_name` and `value`. Present `data.target_status.display_name` to the user and normally map `data.target_status.value` into an action.

#### Dynamic Exact Value

Call an action and map one exact result.

Use this when the inputs uniquely identify the record, such as looking up one employee by email.

#### Dynamic Candidate List

Call an action and map an array of candidates.

The assistant matches the user's language to the candidates and asks for disambiguation when needed. Each candidate should include a useful display label and the stable value required by the API.

> **Dynamic Resolvers Do Not Always Return Lists**
>
> A dynamic resolver can return one exact value or a list of candidates. Only candidate-list cardinality requires the output mapping to point to an array.

## Resolver Example

Suppose the user says:

> Update the bulk edit request.

A dynamic resolver can call `List feature requests` and expose:

```json
[
  {
    "id": "FR-1042",
    "display_name": "Bulk edit requests",
    "current_status": "New"
  },
  {
    "id": "FR-1098",
    "display_name": "Bulk edit user profiles",
    "current_status": "Future Consideration"
  }
]
```

The resolver lets the assistant disambiguate the natural-language phrase while preserving the selected object's stable `id`.

Later, an input mapping can send:

```yaml
feature_request_id: data.selected_feature_request.id
```

## Pass Context into a Dynamic Resolver

A resolver has its own declared inputs and mapping boundary. It does not automatically inherit the entire conversation process data bank.

Map required context explicitly:

```yaml
product_area: data.product_area
request_owner: meta_info.user.email_addr
```

Then map the action result to the resolver's exact value or candidate list.

## Work with File Slots

A file slot collects a file object. The bare slot does not automatically parse the file contents.

After collection, you can:

* Send the file to an API through an action.
* Pass supported files to an LLM action for OCR, document questions, comparison, or structured extraction.
* Collect one file with `File` or several with `List[File]`.

Validate the supported file types and size limits for both the file slot and the consuming action.

## Build Along: Resolve the PurpleSuite Inputs

Add two slots to the conversation process:

| Slot                       | Type   | Inference          | Resolver               |
| -------------------------- | ------ | ------------------ | ---------------------- |
| `selected_feature_request` | Object | Infer if available | Dynamic candidate list |
| `target_status`            | Object | Always ask         | Static allowed values  |

Configure the dynamic resolver to call `List PurpleSuite feature requests`. Map the action result to candidates that retain the PurpleSuite record ID:

```yaml
MAP():
  items: response.data
  converter:
    id: item.id
    display_name: item.name
    current_status: item.currentStatus
```

Configure the static status resolver from the current `currentStatus` enum in the Community OpenAPI schema. Use the user-facing label for conversation and the raw value for the action.

For the running trace, select `Planned`. The list action already filters out records whose `currentStatus` is `Planned`, so the selected record produces a real state change. Confirm that slot resolution runs only the list `GET`; it must not run the `PATCH`.

Test three utterances:

* One that clearly identifies a request.
* One that matches several similarly named requests.
* One that asks for an unsupported status.

Your checkpoint is deterministic selection from API-backed candidates and recollection when a value is not allowed.

## Slot Design Checklist

* The name describes a business value.
* The type matches the downstream contract.
* The description explains collection without trying to enforce rules.
* The inference policy matches the risk of a wrong value.
* DSL validates exact constraints.
* A resolver constrains known choices or business objects.
* Dynamic resolver inputs are explicitly mapped.
* Later steps reference the slot only after collection.
* Write operations use confirmation where appropriate.

## Deep Dives

* [Slots](/agent-studio/conversation-process/slots)
* [Optional Slots](/agent-studio/conversation-process/slots/optional-slots)
* [File Slots](/agent-studio/conversation-process/slots/file-slots)
* [Resolver Strategies](/agent-studio/conversation-process/resolver-strategies)
* [Slot Resolvers](/agent-studio/core-concepts/agentic-automation-engine/slot-resolvers)
* [Slot Best Practices](/agent-studio/guides/best-practices/slot-best-practices)

Next, [compose the workflow](/agent-studio/guides/plugin-building-masterclass/compose-the-workflow).