Review follow-ups on #137955 (long decode):
- Non-streaming stale watchdog: one timer spans every unary hop of a long decode, so an
xhigh/max turn (8 / 32 hops of 32,768) was killed at the 600s gemini-4 floor and retried
from hop 1, re-billing the hops already done. The implicit non-stream stale budget now
scales by the request's hop count (explicit config still wins; the run-budget cap still
applies after). Covers both the worker and the inline cron/subagent path, which read the
same resolver.
- Hop ceiling: the unary and streaming loops stop at ceil(maxOutputTokens / 32,768) + 1 hops
and end the turn as `length`, so a server that keeps answering CONTINUATION can't bill
forever.
- Context-engine buckets: input_tokens / cache_read_tokens now follow the same first-hop
split as prompt_tokens, so engines reading the canonical buckets don't see the summed
prefix (or cache_read > prompt). Billing, the log line and session totals keep the sum.
Past 32,768 output tokens a Gemini 4 stream sends a continuationToken
every ~5,000 tokens, riding on the event whose text it commits. Google's
contract: if the stream drops, resend the SAME request with the last
checkpoint token instead of starting over (the dropped stream is billed
up to that checkpoint, so restarting pays for it twice and redoes minutes
of decoding).
The native client ignored mid-stream checkpoints and turned any
mid-stream httpx error into gemini_stream_error, so the agent retried the
whole request from token 0.
- split_stream_continuation now also returns a mid-stream checkpoint
token (never one on a real, non-CONTINUATION finish).
- _stream_completion keeps the latest token with nothing yielded after
it. On an httpx drop it resends request + that token; with no token,
or once any chunk was yielded after it, it raises as before (resuming
would duplicate or lose shown text). One token rides at most 3
requests, so a network that keeps dropping still ends in an error.
Live (Vertex global, gemini-4-argon, real tunnel abort after the 2nd
checkpoint): resumed with the latest checkpoint, rows 1..3501 contiguous
with no duplicates across the drop, one finish chunk. Same drop on the
pre-fix code raises gemini_stream_error.
Adds gemini-4-argon to the Gemini, Vertex and OpenRouter/Nous catalogs and makes the
native Gemini client handle Google's long decode (up to 1M output tokens).
- Reasoning effort maps onto Gemini 4's thinkingLevel (low/medium/high). Argon always
thinks, rejects "minimal" and rejects thinkingBudget alongside a level (400s, live):
none -> low with thoughts hidden, minimal -> low, xhigh/max -> high.
- Effort above high buys a long-decode budget on the native endpoints only:
xhigh -> 262,144 output tokens, max/ultra -> 1,048,576 (the API caps it at the
window minus the input).
- generateContent (unary and streaming) follows finishReason CONTINUATION: the same
request is resent with the continuationToken, hops are joined into one turn, one
final finish chunk is emitted. Without this, a non-streaming Argon call that hit the
32,768-token per-request cap came back truncated and reported as finish=stop.
- Usage is summed over hops for cost (matches google-genai and billing), while the
first hop's prompt (initial_prompt_tokens) feeds compaction and the context meter,
so a long-decode turn does not trigger an early compaction.
- Vertex express keys can reach global-only models: a project-scoped
.../projects/<p>/locations/global base is now native (only .../endpoints/openapi
stays OpenAI-compatible).
- 20 min read timeout on the native client and a 600 s stale floor for gemini-4,
per Google's long-decode guidance.
- Pricing at the introductory $2 / $10 / $0.10 rates.