Skip to content
6 min read · 1,228 words

Family Recipes Catalog ​

Family recipes represent concrete model deployments. Rather than authoring custom rule arrays from scratch, configure your guard middleware with any of the 38 pre-defined family recipe keys. Thirty-eight is not a claim that we've catalogued every vendor on Earth — it's how many mutually incompatible tool-calling conventions our own research pass turned up before we stopped counting and started shipping. It's a floor, not a census, and it grows every time we go looking again or a new lab invents a new way to disagree.

When passed as strings in OrderingGuardOptions.profiles, recipe keys are resolved and composed automatically by the middleware.

What a recipe will and will not do to your dispatch ​

Two things are worth knowing before selecting one, because neither is visible from the table below.

Every rule here is advisory unless it says otherwise. A live audit dispatched each rule in this catalog against its own native vendor API and found that 16 of 17 describe shapes the vendor in fact accepts — often because a gateway between you and the model was quietly normalizing them, and sometimes because the constraint was never real to begin with. So a recipe records what it finds and lets the dispatch proceed. The single exception is thought_signature_required (gemini-3), which stays blocking because Gemini genuinely returns a 400 naming the missing field and its position.

If you want a recipe to gate rather than annotate, set severity: 'blocking' on the rules you care about — and read API surface scope first, because a rule applied on a surface it was not derived from guards against a constraint that layer already handles.

In mutate mode, every rule type in this catalog is repairable except preservation. Ordering and adjacency violations reorder, alternation gaps take a filler, and required metadata fills from a documented fallback where the repair is authorized. preservation is the deliberate exception: when history has been dropped or altered upstream, there is nothing to repair toward — the guard will not invent lost context. See Modes for the full table.

Complete Family Recipes Matrix ​

Recipe KeyComposed Atomic BehaviorsDescription / Model Invariants
anthropic-manual-thinkingthinking_before_tool_use, payload_field_preservation:signatureClaude 4.5 and earlier manual thinking mode: thoughts must precede tool calls in the active turn; thought signatures must remain stable.
anthropic-adaptive-thinkingpayload_field_preservation:signatureClaude 5.x and adaptive thinking mode: relaxed thinking placement; thought signatures must remain stable.
gemini-3thought_signature_required, function_response_adjacencyGoogle Gemini 3 and 3 Flash: mandatory thoughtSignature on first functionCall; messages may not immediately follow tool calls.
gemini-2-5thought_signature_advisory, function_response_adjacencyGoogle Gemini 2.5: advisory thoughtSignature on first functionCall; messages may not immediately follow tool calls.
novastrict_alternation, openai_shape_baselineAmazon Nova: strict user/assistant role alternation; messages may not immediately follow tool calls.
bedrock-converseconverse_text_before_tool_useAWS Bedrock Converse hosting layer: within one assistant turn, all text messages must precede any tool call.
deepseek-v3-basestrict_alternation, openai_shape_baselineDeepSeek V3 (non-thinking): strict role alternation; messages may not immediately follow tool calls.
deepseek-thinkingstrict_alternation, full_history_preservation:thoughtDeepSeek R1 / V3.1 / V3.2 reasoner: strict alternation; historical reasoning traces must be preserved across turns.
deepseek-v4strict_alternation, full_history_preservation:thoughtDeepSeek V4 (Pro/Flash): strict alternation; historical reasoning traces must be preserved across turns.
qwen-2-5openai_shape_baselineAlibaba Qwen 2.5 and earlier: standard tool-result adjacency baseline.
qwen-3openai_shape_baseline, reasoning_pruned_after_latest_turnAlibaba Qwen 3.x (enable_thinking): recent reasoning preserved; historical reasoning older than latest user turn may be pruned.
glm-4-5openai_shape_baselineZ.AI GLM-4.5: standard tool-result adjacency baseline.
glm-4-7openai_shape_baseline, payload_field_preservation:clear_thinkingZ.AI GLM-4.7 and GLM-5: preserved thinking flag (clear_thinking) kept stable across iterations.
kimi-k2openai_shape_baseline, full_history_preservation:toolCallMoonshot Kimi K2 family: historical tool calls must never be dropped across multi-turn sessions.
kimi-k3openai_shape_baseline, full_history_preservation:toolCall, full_history_preservation:thoughtMoonshot Kimi K3: preserves both historical tool calls and reasoning traces across turns.
minimax-m2openai_shape_baseline, full_history_preservation:toolCall, full_history_preservation:thoughtMiniMax M2 / M2.1 / M2.7: tool-call and reasoning trace preservation across multi-turn dispatch.
minimax-m3openai_shape_baseline, full_history_preservation:toolCall, full_history_preservation:thoughtMiniMax M3: tool-call and reasoning trace preservation across multi-turn dispatch.
mistralopenai_shape_baselineMistral / Devstral: standard tool-result adjacency baseline.
llama-3openai_shape_baseline, single_tool_call_per_turnMeta Llama 3.x: maximum 1 tool call per assistant turn (no parallel tool execution).
llama-4openai_shape_baselineMeta Llama 4: standard tool-result adjacency baseline (parallel tool execution allowed).
nemotronopenai_shape_baselineNvidia Nemotron: standard tool-result adjacency baseline.
gemma-3strict_alternationGoogle Gemma 3: strict two-role (user/model) alternation.
gemma-4strict_alternation, stale_thinking_advisoryGoogle Gemma 4: strict alternation + non-blocking advisory against resending stale prior-turn thinking.
gpt-ossharmony_commentary_channelOpenAI GPT-OSS: every function tool call must carry a Harmony commentary-channel tag.
codex-responsespayload_field_preservation:encrypted_contentOpenAI Codex / Responses API: reasoning encrypted content must remain stable across turns.
cohere-command-ropenai_shape_baselineCohere Command R / R+: standard tool-result adjacency baseline.
phiopenai_shape_baselineMicrosoft Phi: ChatML format, standard tool-result adjacency baseline.
maiopenai_shape_baselineMicrosoft Foundry MAI-Thinking / MAI-Code: standard tool-result adjacency baseline.
jambaopenai_shape_baselineAI21 Jamba: standard tool-result adjacency baseline.
falconopenai_shape_baselineTII Falcon: standard tool-result adjacency baseline.
palmyraopenai_shape_baselineWriter Palmyra: standard tool-result adjacency baseline.
ernieopenai_shape_baselineBaidu ERNIE: standard tool-result adjacency baseline.
gpt-4-legacyopenai_shape_baselineOpenAI legacy GPT-4 (end-of-life): standard tool-result adjacency baseline.
bytedance-seedopenai_shape_baselineByteDance Seed / Doubao (UNCONFIRMED baseline guess): verify before relying on in enforce mode.
muse-sparkopenai_shape_baselineMeta Muse Spark (UNCONFIRMED baseline guess): verify before relying on in enforce mode.
muse-glimmeropenai_shape_baselineMeta Muse Glimmer (UNCONFIRMED baseline guess): verify before relying on in enforce mode.
granite-3-xrole_remap_split_tool_rolesIBM Granite 3.x: producer must set a role-remap marker confirming its split tool-call/tool-response wire roles.
granite-4-xrole_remap_inline_tool_callIBM Granite 4.x: producer must set a role-remap marker confirming its inline tool-call, remapped-response wire roles.

'grok' is a recognized profile key that resolves directly to 'permissive'. It is the single vendor in this entire catalog that just has no opinion on message ordering, which, after reading the rest of this table, should feel almost suspicious.

Composing Recipes in Middleware ​

You can specify family recipes directly in OrderingGuardOptions.profiles. Composing multiple recipes lets you capture layered constraints — for example, pairing a model family recipe with a hosting-layer recipe when deploying through Bedrock Converse. This two-layer conflict (where the model requires one structure and the hosting wrapper bolts on a second, conflicting constraint) is precisely why testing models in isolation is never enough: you must validate the actual deployment shape.

ts
import { orderingGuardDispatchMiddleware } from '@nhtio/adk/batteries/validation'

// Single family recipe
const middleware = orderingGuardDispatchMiddleware({
  profiles: ['gemini-3'],
  action: 'enforce',
})

// Combining a family recipe with a hosting-layer recipe
const bedrockClaudeMiddleware = orderingGuardDispatchMiddleware({
  profiles: ['anthropic-manual-thinking', 'bedrock-converse'],
  action: 'mutate',
})

See Also ​