# State

The state is what the engine evaluates: a support message, a document, an application record. It goes in the `state` field next to the questions.

## Formats

- a string: `"My card was charged twice."`
- an object with named fields: `{"message": "My card was charged twice.", "order_id": "A-104"}`
- an array of strings: `["Hi", "My customer number is TS1337.", "My card was charged twice."]`

Text only; images, audio and video are not read. English first: Jepela's English checkpoint is the measured one; its multilingual checkpoint covers more languages with lower accuracy.

## How much the engine reads

The request body is capped at 1 MB, but the engine reads far less. Each question is read together with the state in one window, and the question and its options take their share first. Measured on 2026-09-23 with a long state:

| Checkpoint | Window | State read with a short question | With 10 to 20 options |
|---|---|---|---|
| `jepela-english` | 512 tokens | about 475 tokens | about 330 tokens |
| `jepela-multilingual` | 1024 tokens | about 990 tokens | about 780 tokens |
| `jepela-typed-decisions` | 1024 tokens | about 990 tokens | about 790 tokens |

The rest of a string or an object is cut from its end. An array is cut from its start instead: the engine keeps its newest elements and drops the oldest. Memory lines and computed facts are placed before the state (below) and take their share of the same room: in a string or an object they are read first. In an array they would be the first to go, so when an array that carries such lines is longer than the engine reads, Jepela leaves out the array's oldest elements, whole, until the lines and the remaining elements fit, and sends that. It never leaves out a line or the newest element. An array that fits is sent exactly as before. Measured on 2026-10-16 with the English checkpoint: a chat of 41 turns with a priority-support line gave 0.174 to "escalate?" before, the same as without the line, and gives 0.8955 now, with the oldest 13 turns left out. A choice of more than 20 options answered by matching reads an array the same way: the elements the engine kept, and within the matching model's own room its newest ones (see Choice). With `quality` balanced or best, the second tier is sent the same elements, with the lines in front.

Every answer says what was read: `reading` per question (`state_tokens`, `read`, `room`, `chars_read`, `truncated`; with memory or `derive` these count the lines placed before the state too, and `context_lines_read` says how many of those lines were read; `chars_read` counts the characters read from the start, or for an array the last ones; with windows, see below) and, in `usage`, `state_tokens`, `state_tokens_read` and `state_truncated`, over the questions the engine read (a matched choice's own reading stays in `reading`). When Jepela left out an array's oldest elements, `turns_dropped` says how many, `truncated` is true, `state_tokens` counts the whole array with its lines, and `read` and `chars_read` count what was sent: the lines and the newest elements, read whole. A cut state also brings a `state_cut` warning; when elements were left out, it says how many. A matched choice (see Choice) is read by the matching model, not the engine: its `reading` has `method` `match`, counts that model's tokens, and says what it read of its 512 tokens with the search prefix: a string or an object from the start, an array as described above (with `turns_dropped` when it left out the oldest elements); its `context_lines_read` counts the lines that model read. When the lines and the newest element alone are longer than the engine reads, Jepela leaves out as few older elements as let the most lines be read, and the `memory_cut` warning says how many lines were read.

What to do about a long state:

- Put the part that matters first (last in an array), or send only that part.
- Send `"windows": true`: when the state is cut, the engine reads it in overlapping windows (neighbours share 32 tokens), at most 16, each with the memory lines in front, so nothing is left out to make room for them. A string or an object is read from its start, so one too long for 16 windows is read up to the 16th window. An array too long for 16 windows is read from its end instead: the windows keep its newest elements and leave out its oldest, as one pass does. An array the windows cover whole is read from its start, as before. When the windows do not cover the state, `windows.covered_all` is false and the `state_cut` warning stays. With windows, `read` and `chars_read` count the tokens and characters of your state that the windows covered (from its start, or for an array too long for them, up to its end), without the lines in front. By default a yes/no question takes the window with the highest yes, a score the highest level, and a choice the most confident window (for a choice `min` and `max` both take the most confident window); `"windows": {"combine": {"question_id": "mean"}}` sets `min`, `max` or `mean` per question. Each window bills the request's answers once more; see Request options.

## What the memory adds

When the request names a subject, the recalled lines are placed **before** the state, so the engine's cut from the end can never remove them from a string or an object: for a string, a block headed `What this customer's memory knows:` with one line per fact (the wording every measurement here was made with); for an object, a `known_facts` key placed first; for an array, a leading element. An array is cut from its start, so when an array with memory is longer than the engine reads, Jepela leaves out its oldest elements so that the memory is read, and `reading.turns_dropped` says how many (see above). Facts computed by `derive` come first of all: under `Computed by the system:` in a string or an array, as a `computed_facts` key in an object. The answer's `memory.hits` lists the recalled lines, each with `read` (true when the engine read it), and `memory.lines_seen` how many of them the engine actually read.

## Guidance

- Put facts in the state and judgments in the questions.
- Use an object when several things must be compared: the message, the order, the policy.
- Decompose: one state per subject, not a batch of unrelated records.
- Reference fields from the instructions with their names in backticks, `` `order.total` ``, when the question is about one field.
