1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
//! The API-agnostic request the engine hands to any [`Provider`](crate::Provider).
use ;
/// One provider-neutral sampling request (ADR-0007).
///
/// The loop builds exactly one of these and knows nothing about any wire. Per
/// ADR-0013 there is **no separate `system` field** — `messages` carries the whole
/// role-tagged stream (System/Developer included), and each wire hoists leading
/// System messages into its own top-level slot (e.g. Anthropic's `system`).
/// Provider-neutral sampling knobs — the **common core** only.
///
/// Wire-specific parameters (Anthropic `top_k`/`stop_sequences`/thinking budget,
/// OpenAI `frequency_penalty`, …) are the concern of each wire's request builder,
/// not this type, keeping [`ConversationRequest`] API-agnostic (ADR-0007). Grok
/// Build uses the same layering: a neutral core plus per-wire superset structs.
/// The default output-token budget for one sample.
///
/// A file-writing agent spends most of a turn inside one `tool_use` argument
/// blob, so this is not a "typical reply length" knob — it is the ceiling on
/// the largest single tool call the model can emit. Set it too low and the
/// wire truncates mid-call: the API returns the `tool_use` block with an
/// **empty** `input` (`{}`) and `stop_reason: "max_tokens"`, the typed decode
/// then reports a missing required field, and the model retries the same
/// oversized call forever. That is what 4096 did here.
///
/// 32k is the value the studied harnesses converge on for this tier. Claude
/// Code resolves a per-model `{default, upperLimit}` pair
/// (`utils/context.ts:149-208`) — 32k default for the sonnet-4-6 / 4.5
/// families, 64k for opus-4-6 — and its 8k `CAPPED_DEFAULT_MAX_TOKENS`
/// (`utils/context.ts:24`) is **not** the shipped default: it is gated on the
/// `tengu_otk_slot_v1` slot-reservation experiment, which defaults to *false*
/// off first-party (`services/api/claude.ts:3394-3397`), and is paired with a
/// one-shot escalate to `ESCALATED_MAX_TOKENS = 64_000` on truncation. Codex
/// never sends a sampling cap at all; Grok Build leaves `max_tokens: None`.
/// Our own Responses wire already caps at 32k (`openai/mod.rs:119`), so this
/// also stops the Anthropic wire being the odd one out.
///
/// A per-model table (Claude Code's shape) is the eventual answer; a single
/// safe default is the honest v0 — every current Anthropic and OpenAI model
/// this crate targets accepts 32k.
pub const DEFAULT_MAX_TOKENS: u32 = 32_000;
/// A neutral reasoning-effort level, mapped per-wire (ADR-0007).
///
/// Grok Build proves this shape: one neutral enum with per-backend mappings
/// (`to_messages_api()` → Anthropic budget, `to_responses_api()` → OpenAI effort).
/// Tiers fragment per vendor/model generation (OpenAI `none…xhigh`, codex
/// `minimal…xhigh`, grok stores per-model allowed-effort lists), so the ladder
/// covers the observed union and `Other` passes vendor-specific strings
/// through verbatim (ADR-0007 amendment 2026-07-19). Wires surface the API's
/// own error on unsupported tiers — never silently clamp (silent clamping
/// would corrupt eval comparisons).
/// Where the wire should place prompt-cache breakpoints (ADR-0007).
///
/// A reserved seam: the actual `cache_control` placement (Anthropic: one marker on
/// the last message + ≤4 on system blocks) lives in the wire (Task 12).