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
//! OpenRouter endpoints and probe budgets.
//!
//! Split out of the former single-file `constants.rs` in v1.2.5;
//! every item is re-exported by the parent module, so `crate::constants::X`
//! resolves exactly as before.
/// Default OpenRouter chat completions endpoint (override via XDG
/// `network.openrouter.chat_url` or alias `network.chat_url`).
pub const DEFAULT_OPENROUTER_CHAT_URL: &str = "https://openrouter.ai/api/v1/chat/completions";
/// Default OpenRouter embeddings endpoint (override via XDG
/// `network.openrouter.embeddings_url` or alias `network.embed_url`).
pub const DEFAULT_OPENROUTER_EMBEDDINGS_URL: &str = "https://openrouter.ai/api/v1/embeddings";
/// Fail-fast probe budget for LLM backends before spawning (ms).
/// Override via XDG `llm.probe_timeout_ms`.
pub const DEFAULT_LLM_PROBE_TIMEOUT_MS: u64 = 800;
/// Ceiling, in seconds, on a single `Retry-After` sleep inside the HTTP retry
/// loops of [`crate::chat_api`] and [`crate::embedding_api`].
///
/// The header is server-controlled and was honoured verbatim: a provider (or
/// anything answering in its place) replying `Retry-After: 86400` put a CLI
/// that is supposed to be born, run and die to sleep for a full day, with no
/// output and no way to tell the stall apart from a hang.
///
/// The value is anchored on the budget that already governs the TOTAL wait:
/// `enrich.rate_limit_deadline_secs` defaults to 3600s
/// ([`crate::constants::DEFAULT_RATE_LIMIT_DEADLINE_SECS`]). One step must stay
/// well under that or the deadline stops meaning anything — at 60s the worst
/// case of `openrouter_http::MAX_RETRIES` rate-limited attempts is
/// 240s, under 7% of the deadline, so the operator's budget still decides when
/// the run gives up. It is also far above any wait a healthy provider advises,
/// so the cap only fires on values that were never actionable anyway.
///
/// Distinct from [`crate::constants::ENRICH_BACKOFF_CEILING_SECS`] (900s),
/// which bounds the drain's own backoff BETWEEN items, not one HTTP attempt.
/// Coordination wait against a remote limit, so it takes no XDG key.
pub const MAX_RETRY_AFTER_SECS: u64 = 60;
/// Default per-item budget, in seconds, for an OpenRouter chat-completion when
/// `--openrouter-timeout` is omitted.
///
/// GAP-SG-17: raised from 300 to 600 because dense bodies (close to the ~32K
/// token context ceiling of the configured model) routinely take longer than
/// five minutes to generate via `deepseek-v4-flash:nitro`.
pub const DEFAULT_OPENROUTER_CHAT_TIMEOUT_SECS: u64 = 600;
/// Clamps a server-advised `Retry-After` to [`MAX_RETRY_AFTER_SECS`], warning
/// when the cap actually bites.
///
/// Lives beside the constant rather than in either transport because both HTTP
/// retry loops apply the same policy; a second copy of the expression is one
/// edit away from the chat and embedding paths disagreeing about how long a
/// remote limit may stall a one-shot process.
///
/// The warning is not decoration: a cap that trims in silence is
/// indistinguishable from a provider that asked for the shorter wait, so the
/// operator would read the retries as normal pacing instead of as a provider
/// demanding a delay this CLI refuses to grant.