Skip to navigation
Plugin Building MasterclassEnd-to-End Course

Collect Slots and Resolve Values

Design typed conversational inputs with inference policies, deterministic validation, and static or dynamic resolvers.
View as Markdown

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:

NeedSlot type
Free-form textstring
Count or amountinteger or number
Yes or noboolean
Date or timestring with a documented format
One business objectobject or custom data type
Several valuesList[Type]
Moveworks personUser or List[User]
Uploaded attachmentFile 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

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.

Step 4: Add Deterministic Validation

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

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.

Define a fixed list of display values and raw values.

Example:

User-facing labelRaw value
NewNew
PlannedPlanned
DeliveredDelivered

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

[
{
"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:

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:

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:

PurpleSuite end-to-end call trace

Follow one live feature request through the same three API calls and Agent Studio contracts in every chapter.

Shared connector
https://marketplace.moveworks.com
Every API action
Connector adds Bearer PAT. Action adds X-Instance-ID.
Turn live API data into allowed conversation values
The dynamic resolver runs the list call and stores the selected PurpleSuite ID in an object slot.
List candidatesAPI callDynamic resolver + List action
GET /api/purple-suite/community/feature_requests
$filter: currentStatus ne 'Planned'
$select: id,name,currentStatus,productArea
$top: 10
Receives
Resolver invocation and optional search context
Returns
{ data: FeatureRequest[], nextCursor, total }
How it fits
This is the first real API call. The resolver uses the response list, so the assistant can select only records that PurpleSuite returned.
Successful run: actual API call ledger
1GET/api/purple-suite/community/feature_requestsDynamic resolver retrieves live candidates
2PATCH/api/purple-suite/community/feature_requests/{id}Compound action updates the selected record
3GET/api/purple-suite/community/feature_requests/{id}Compound action verifies the stored result
Use a record returned by your own PurpleSuite instance. Save its original status before the write and restore it after mutation testing when appropriate.
SlotTypeInferenceResolver
selected_feature_requestObjectInfer if availableDynamic candidate list
target_statusObjectAlways askStatic allowed values

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

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

Next, compose the workflow.