Documentation
Table of Contents

Intent file reference

Intent files explains what an intent file is for and what each of its twenty fields means. This page has the details you need while writing one: how files are found, the shapes and the .NET types each one returns, each of the thirteen rules, how to write examples, and the duration format. Loading and running the files from code is in Running intents from files.

Files

  • The catalog loads every file named *.intent.yaml, *.intent.yml or *.intent.json in its folder, and in its subfolders unless IncludeSubdirectories is off.
  • A file holds one intent, or a list of them. A YAML file can also hold several documents separated by ---. YAML and JSON mean the same.
  • name and intent are required. version is 1 when it is left out.
  • Names are unique across the catalog, ignoring case. When two files define the same name, the one loaded first keeps it and the other is reported as a problem.
  • A field the format does not know is reported as a problem, not ignored, so a misspelt field shows up instead of doing nothing.

This file, from the use cases, uses a schema shape and nested rules:

name: Invoice.Extract
version: 1
owner: accounts-payable
intent: Extract the vendor, invoice number, currency and total from this invoice email.
shape:
  kind: schema
  schema:
    type: object
    properties:
      vendor: { type: string }
      invoiceNumber: { type: string }
      currency: { type: string }
      total: { type: number }
    required: [vendor, invoiceNumber, currency, total]
rules:
  properties:
    currency:
      enum: [USD, EUR, GBP]
    total:
      minimum: 0

Shapes

shape says what comes back. It decides the type you can ask for with RunAsync<T>; any shape can also be run as JsonNode with RunAsync.

kind Also set You read it as
text nothing string
primitive primitive: string, int, long, double, decimal, bool, date, datetime or guid; add [] for a list the matching .NET type (table below)
clr clrType: the name of a .NET type your application registered that type, or a type it can be assigned to
schema schema: a JSON schema for the result JsonNode

Two shorter forms:

  • a name instead of an object, as the value of shape: text, int or date[];
  • an object with exactly one of primitive, clrType or schema and no kind: the kind follows from it.

Without a shape, the result is text.

primitive T
string string
int, long, double, decimal, bool the same .NET type
date DateOnly or DateTime
datetime DateTimeOffset or DateTime
guid Guid
any of those with [] an array, List<>, IList<>, IReadOnlyList<>, IEnumerable<>, ICollection<> or IReadOnlyCollection<> of an accepted type

Nullable forms such as int? are accepted, and so is any type the first type in a row can be assigned to, such as object. A date asked for as DateTime is midnight, with DateTimeKind.Unspecified; a datetime asked for as DateTime is the same instant in local time. Asking for a type the shape cannot produce throws IntentShapeMismatchException before any model call.

A clr shape names only a type your application registered (AddIntentType<T>()); why a file cannot load code is in Intent files. A schema shape is checked against its whole schema on every reply, limits such as minimum and pattern included; a reply that breaks it is retried with the problem.

Rules

Rules are checks on the result, run in your process with no model call, on every reply. Each failure is sent back to the model on the next attempt. Rules see the result as JSON, so write property names as they appear in JSON: deliverBy, not DeliverBy.

Rule Applies to Passes when
minimum, maximum numbers the number is at least minimum and at most maximum
minLength, maxLength text the length is within the bounds
pattern text the regular expression matches; anchor it with ^ and $ to match the whole value
enum text, numbers, true or false the value is one of those listed: text compared ignoring case, numbers by value
minItems, maxItems lists the number of elements is within the bounds
uniqueItems lists no two elements are equal
notEmpty text, lists, objects the value is not empty
required objects each listed property is present and not null
properties objects each named property passes its own rules
items lists every element passes these rules

Three things to know:

  • A null value, or a missing property, passes every rule except notEmpty. To demand a property, list it in required: a minimum on total alone accepts a null total.
  • For a text or primitive shape, a rule that cannot apply (minLength on an int) is a load problem that names the rules that do apply. For a list, rules takes list rules and rules.items applies to the elements. Rules on clr and schema shapes are checked when a reply arrives instead: a rule that meets the wrong kind of value is a failed check that names the rule.
  • Each failure names its place in the result, starting from value, for example value.lines[2].sku, so the next attempt is told exactly what to fix.

A check that needs code, such as a vendor that must exist in your database, is a named check registered in your application and listed in validators; it runs after the rules (Running intents from files).

Examples

Each example is an input and the output you expect for it, shown to the model in the order written.

  • A string is used as written. Any other value, a number, a list or an object, is read as compact JSON, so an output can be written as YAML.
  • For a text shape, and a primitive of string, the output is the answer as it should read.
  • For every other shape, write the output as the value itself: 5, [a, b] or {vendor: Acme}. Text that is not JSON is read as a string, so 2026-11-15 works for a date.
  • Examples steer the format and the judgement. They never replace the checks: a reply that copies an example and breaks a rule still fails.
  • Examples do not count toward the input size limit, MaxInputChars.

Durations

timeout is the time budget for the whole run, every attempt included. Write it as an ISO 8601 duration, PT30S, or as hh:mm:ss, 00:00:30. It must be greater than zero and at most about 49.7 days; anything else is a load problem.

Names a file refers to

Three fields name something that is not in the file: validators (checks your application registered), shape.clrType (types your application registered) and provider (a provider the client has). They are checked when the intent runs, not when it loads; what throws before any model call lists the exception for each.