Skip to main content
Back to how-to guides Use this pattern when one value is not enough: a list of items, a low and high range, or a file the customer uploads.

Concept

A GATHER field holds one scalar by default. Three properties change its shape. A separate construct handles files. Use only one shape property on a field. A field with both list and range compiles without a warning, and the list wins. Write list: true and range: true in lowercase. yes and True read as false without an error.

Minimal working example

A hotel search collects a nightly budget range, a list of amenities, and a room type. The room type uses a reusable entity. The search tool is a project-local assumption. Bind it to your hotel search service in Project Tools. agents/hotel-search.agent.abl
Variable sources:
  • budget, amenities, room, and rating are GATHER fields. The customer supplies them.
  • COMPLETE reads budget.low, budget.high, and room.

How it works

How each shape is stored and checked:
  • A list is an array. A single value is wrapped into a one-item array. A text value is split on commas, so “pool, gym” gives two items. A semicolon does not split.
  • A range is an object with low, high, or both. At least one end is needed. Each end follows the field type, so a currency range of “$100 to $300” gives 100 and 300. The runtime accepts low greater than high.
  • An enum field accepts a value that matches an option exactly, then ignoring case, then through a synonym. It does not match approximately.
  • An entity_ref field inherits the entity type, values, synonyms, and sensitive setting. A field that sets entity_ref and also type or options is a compile error GATHER_ENTITY_REF_CONFLICT. An unknown entity is a compile error GATHER_ENTITY_REF_UNRESOLVED.
How to read the value: A {{#each}} block does not iterate a list of strings. It works for a list of objects only. There is no join filter. How the semantics block helps:
  • temporal: future or past limits a date field to one side of today.
  • lookup checks the value against a lookup table. A near match becomes a confirmation.
  • unit with convert_to converts a number inside a FLOW step, and keeps the original. It does not convert in a top-level GATHER, and it skips lists and ranges.
  • format and components guide extraction only. They do not create a structured object.
  • locale and kore_entity_type carry metadata and have no effect on collection.
Do not put a validate rule on a list or range field. The rule applies to the whole value. A list with a pattern, and a range with a range rule, reject valid answers. The same applies to a multi-select enum: an enum rule from options accepts one value, so a list of two options fails.

Common variations

Range of dates and a unit conversion in a FLOW step

A FLOW step can convert units and collect a date range. agents/shipment-quote.agent.abl
The converter supports temperature, distance, weight, time, volume, and currency units. A pair it does not support is skipped without an error.

Enum values

Write enum options in the block form or without quotes. A one-line list with quotes keeps the quote marks in the stored values. validate: enum(a, b) splits on commas. A pipe makes one value.

Preferences

preferences: true compiles, but it does not store a category object in the field. The field does not hold accept, desire, avoid, and refuse lists. A reasoning agent also scans each customer message for stated preferences. It saves them to memory under preferences.accept, preferences.desire, preferences.avoid, and preferences.refuse when the agent has a memory store. That scan runs on top-level GATHER fields only. To keep preferences in the conversation, collect them as a list: true field for each category, or use MEMORY and REMEMBER.

Attachments in a FLOW step

Use AWAIT_ATTACHMENT to wait for an upload. The step stores the first attachment ID in the named variable. A tool parameter named attachment_id is bound and checked against the available attachments. agents/id-upload.agent.abl
The SET in the start step gives the compiler a producer for id_photo. Without it, the compiler warns that nothing produces the variable. Rules for AWAIT_ATTACHMENT:
  • category is image, document, audio, or video. A wrong category is a compile error INVALID_AWAIT_ATTACHMENT.
  • A file of the wrong category makes the step ask again. The trace outcome is category_mismatch.
  • With required: false, a text message sets the variable to null and the flow moves on.
  • With timeout in seconds and on_timeout, the flow moves to that step. Without on_timeout, the step replies that the upload timed out and keeps waiting.

The ATTACHMENTS section

The ATTACHMENTS: section declares upload fields with a category, a size limit, allowed types, and processing flags. The keys are prompt, category, required, max_size_mb, allowed_types, ocr_enabled, transcription_enabled, and key_frame_extraction. Keys such as allowed_mime_types and ocr are ignored without an error. A category outside the four valid values is also accepted silently. The section is a declaration only. The runtime does not read its size limit, allowed types, or processing flags. Uploads are limited by the project and tenant attachment settings: whether attachments are enabled, the maximum file size, the maximum files per session, the allowed MIME types, the PII policy, and the processing mode. Set these in the project settings for attachments. Use AWAIT_ATTACHMENT with a category to check the kind of file inside a flow.

Verification

  1. Run the validator on each file. Expect no errors and no warnings.
  2. Say “Between 100 and 300 dollars, with a pool and a gym, in a double”. Expect budget.low 100, budget.high 300, two amenities, and room double.
  3. Say “around 200”. Expect COMPLETE not to fire until both ends are set.
  4. In the shipment example, say “5 kg”. Expect the converted weight in pounds in the tool call.
  5. In the upload example, send a document when an image is required. Expect the step to ask again.
  6. Let the upload time out. Expect the skipped reply.
  7. In the trace, open the dsl_collect events for the extracted values. Open the await_attachment events for the upload outcomes.

Production readiness checklist

  • Each field uses one shape property.
  • No list or range field has a validate rule.
  • Conditions test both ends of a range, and test .length for a list.
  • Templates do not print a raw list. They print items, or the count.
  • Enum options are in the block form, or unquoted.
  • Each upload step has a timeout and an on_timeout route.
  • Upload type, size, and count limits are set in the project attachment settings and tested.
  • Tests cover a one-item list, an empty list, a one-ended range, and a reversed range.

Common mistakes

Troubleshooting

Related articles: