Patterns¶
The four documented patterns, each with its questions written and its thresholds in one module.
The thresholds these tools branch on live in strands_jev/questions.py, one file, so a change of policy is a constant under review. Defaults at this commit: confidence floor 0.6, noul threshold 0.5, complexity escalates above 1.0 or under a confidence of 0.5.
fan_out¶
Ask every question you might need in one request, then keep only the applicable answers.
Ports the speculative fan-out pattern (docs.typesafe.ai/patterns/fan-out). Questions are
answered in parallel against the same state and cannot see each other, so a follow-up
question ("how severe is the bug?") is asked up front alongside the question that decides
whether it matters ("is this a bug report?"). A premise ties the follow-up to that
deciding answer; answers whose premise does not hold are returned under skipped
rather than dropped, so nothing is hidden. Adding questions to one request costs tokens
but little latency.
| parameter | type | default | description |
|---|---|---|---|
state |
str | dict | list | required | What Jev reads: text or a JSON object with meaningful field names. |
questions |
dict | str | required | The same map of question specs as jev_ask (type noul, choice or score, with instructions and criteria). A JSON string is accepted. |
premises |
dict | str | None | None |
Which questions are speculative and when they apply. A map of question key to {"question": "<other key>", "equals": <choice or true/false>} or {"question": "<other key>", "at_least": <number>} for a noul probability or a score. Questions without a premise always apply. A JSON string is accepted. |
context |
str | None |
Optional text folded in next to the state. |
Returns JSON with answers (the applicable ones, same shape as jev_ask), skipped (key to the premise that failed and the answer anyway), model, latency_ms, input_tokens; plus a one-line summary.
Ports patterns/fan-out
Measured 2026-09-29, jev-1.13.0: Jev 10/12, baseline 8/12, 12 calls, 5,506 input tokens, $0.000231, mean 159 ms. Details.
route¶
Classify a request's intent and decide who handles it: code, a specialist, or a person.
Ports intent routing (docs.typesafe.ai/patterns/intent-routing) with confidence-gated
routing folded in (docs.typesafe.ai/patterns/confidence-routing). One request carries a
Choice over your intents plus none_of_these and a 3-level complexity Score. The
decision is gated twice: the intent's confidence must clear min_confidence (or the
intent's own entry in thresholds, for the risky ones), and for the intents named in
complex_intents a complexity score above 1 or a complexity confidence under 0.5
escalates to a person. The pattern applies that second gate to one intent (complaints),
not to lookups; measured on 2026-09-29, gating every intent sent two clear lookups to a
person because a 3-level score spread its probability. The thresholds are the pattern's
own; tune them on your data.
| parameter | type | default | description |
|---|---|---|---|
message |
str | dict | required | The request, as text or a JSON object. |
intents |
dict | list[str] | str | required | Intent name to a one-sentence description of when it applies. A list of names works, read by name alone. A JSON string is accepted. |
handlers |
dict | str | None | None |
Intent name to the handler label your code dispatches on (for example "code", "product_llm", "human"). Missing intents default to their own name; anything undecided or escalated routes to "human". |
min_confidence |
float | 0.6 |
Confidence floor for acting on the intent, 0..1. |
thresholds |
dict | str | None | None |
Per-intent floors that override min_confidence for riskier intents, for example {"approve_transfer": 0.85}. Values 0..1. |
assess_complexity |
bool | True |
Also score complexity, 3 levels from "a lookup answers it" to "it needs a person". Set false when only the intent matters. |
complex_intents |
list[str] | str | None | None |
The intents whose handler depends on complexity, for example ["complaint"]. Omitted: every intent is gated. Ignored when complexity is not assessed. |
context |
str | None |
Optional text folded in next to the message. |
Returns JSON with intent, confidence, decided, handler, escalate (bool), reason, probabilities, runner_up, complexity (score, confidence, legend) when assessed, threshold_used; plus a one-line summary.
Ports patterns/intent-routing, patterns/confidence-routing
Measured 2026-09-29, jev-1.13.0: Jev 14/14, baseline 11/14, 14 calls, 6,886 input tokens, $0.000289, mean 179 ms. Details.
composite_score¶
Score one thing, or rank many, on several dimensions with weights you control in code.
Ports composite scoring (docs.typesafe.ai/patterns/composite-scoring). Each dimension is an atomic Score question; every dimension is asked in one request per item. Scores are normalised to 0..1 by dividing by the top level index, then combined under each weight profile in code. The raw normalised scores are returned so you can reweight without asking again. The default rubric has five generic levels; describe your own levels when the dimension has concrete stages (the docs ask that levels describe situations).
| parameter | type | default | description |
|---|---|---|---|
dimensions |
dict | str | required | Dimension name to the rating instruction ("How deep is the Python experience?"), or to {"instructions": ..., "levels": [...]} for a dimension with its own ordered levels (2 to 10). A JSON string is accepted. |
state |
str | dict | list | None | None |
The one thing to score. Give this or items. |
items |
list | str | None | None |
Several things to score and rank, one request each (at most 500). |
weights |
dict | str | None | None |
One profile {"python": 0.4, "leadership": 0.1, ...} or several {"senior_ic": {...}, "manager": {...}}. Non-negative, normalised to sum to 1. Omitted: equal weights. |
levels |
list[str] | str | None | None |
Shared ordered level descriptions for dimensions that give none. |
context |
str | None |
Optional text folded in next to each item, such as the job description. |
Returns JSON with dimensions (name to instruction), profiles (normalised weights), results (per item: scores 0..1 per dimension with raw score, confidence and legend; composite per profile), ranking (per profile, best first, when items was given); plus a one-line summary.
Ports patterns/composite-scoring
Measured 2026-09-29, jev-1.13.0: Jev 27/30, baseline 20/30, 6 calls, 3,313 input tokens, $0.000139, mean 213 ms. Details.
function_call¶
Turn a natural-language request into a function name and closed-set arguments, with confidence.
Ports the function-calling cookbook (docs.typesafe.ai/cookbooks/function_calling). One request carries a Choice over the functions (plus a no-match option), and for every function every argument: a Choice for a single value from a fixed list, a Noul per member for a set argument, a Noul for a flag, and an optional "stated" Noul that decides whether the argument was mentioned at all (when not, it is left out so the function's default applies). Only the chosen function's answers are read. The call's confidence is the least certain judgement behind it. Free text, numbers and dates are not filled: keep them as defaults or ask the user. Write each question about the idea, not the parameter name.
| parameter | type | default | description |
|---|---|---|---|
request |
str | required | What the user said. |
functions |
dict | str | required | Function name to {"description": "...", "arguments": {arg: {"question": "...", "options": {value: meaning, ...}, "kind": "choice" \| "set" \| "flag", "stated": "Does the user say anything about ...?"}}}. kind defaults to choice when options are given, flag otherwise; stated is optional; a set question may hold {} where the member name goes. A bare string is a description with no arguments. A JSON string is accepted. |
min_confidence |
float | 0.6 |
Floor on the call's confidence to report decided, 0..1. |
context |
str | None |
Optional text folded in next to the request. |
Returns JSON with function (or none_of_these), arguments (value per filled argument), confidence (the minimum), function_confidence, decided, per_argument (each judgement with its probability or confidence, and whether it was stated), probabilities over functions; plus a one-line summary.
Ports cookbooks/function_calling
Measured 2026-09-29, jev-1.13.0: Jev 14/16, baseline 10/16, 16 calls, 29,830 input tokens, $0.001253, mean 172 ms. Details.
Edit page