| Name | Modified | Size | Downloads / Week |
|---|---|---|---|
| Parent folder | |||
| README.md | 2026-07-11 | 23.5 kB | |
| rig-v0.40.0 source code.tar.gz | 2026-07-11 | 9.2 MB | |
| rig-v0.40.0 source code.zip | 2026-07-11 | 10.2 MB | |
| Totals: 3 Items | 19.4 MB | 0 | |
Added
- (tool) [breaking] structured tool-execution results (#2015) (by @gold-silver-copper)
- (agent) [breaking] hook system v2 — composable middleware (#2012) (by @gold-silver-copper)
- (examples) human-in-the-loop tool-call approval — examples + tests (#1967) (by @gold-silver-copper)
- (rig-core) steer the model request per turn from a hook via Flow::OverrideRequest (#1966) (by @gold-silver-copper)
- (rig-core) rewrite tool results from a hook via Flow::RewriteResult (#1965) (by @gold-silver-copper)
- (rig-core) rewrite tool-call arguments from a hook via Flow::RewriteArgs (#1963) (by @gold-silver-copper)
- (openai) preserve responses prompt cache parameters (#1830) (by @Kade-Powell)
- (streaming) [breaking] surface unmodeled provider output items through the stream (#1951) (by @gold-silver-copper)
- (rig-core) [breaking] integrate hooks into AgentRun via a composable AgentRunner (#1945) (by @gold-silver-copper)
- (message) add video helper constructors + OpenRouter audio/video conversion tests (#1942) (by @gold-silver-copper)
- (agent) add OutputMode to compose structured output with tools (#1928) (#1929) (by @gold-silver-copper)
Fixed
- (telemetry) keep GenAI message span fields empty (#2066) (by @gold-silver-copper)
- (chatgpt) preserve non-success response errors (#2053) (by @gold-silver-copper)
- (vertexai) preserve signed thought text parts (#2052) (by @gold-silver-copper)
- (chatgpt) fallback on empty SSE output (#2001) (by @gold-silver-copper)
- (openai) preserve reasoning text content (#1999) (by @gold-silver-copper)
- preserve OpenAI Responses instructions (#1995) (by @gold-silver-copper) - [#1995]
- (openai) accept null Responses metadata (#1993) (by @gold-silver-copper)
- (postgres) update sqlx and pgvector (#1992) (by @gold-silver-copper)
- (openai) make Responses API strict tools opt-in (#1991) (by @gold-silver-copper)
- (agent) stream concurrent tool results as they complete (#1981) (by @gold-silver-copper)
- (rig-core) fix epub loader tests + prevent CWD-relative fixture-path regressions (#1940) (by @gold-silver-copper)
- (ollama) preserve assistant reasoning from non-streaming responses (#1926) (#1927) (by @gold-silver-copper)
Other
- Remove unused derive and core APIs (#2087) (by @gold-silver-copper) - [#2087]
- add Bedrock cassette coverage (#2084) (by @gold-silver-copper) - [#2084]
- Remove unused stream completion stdout helper (#2085) (by @gold-silver-copper) - [#2085]
- Remove unused generation wrapper traits (#2083) (by @gold-silver-copper) - [#2083]
- Remove unused Anthropic decoders (#2082) (by @gold-silver-copper) - [#2082]
- (agent) [breaking] unify PromptResponse and FinalResponse into one type (#2056) (by @gold-silver-copper)
- (core) [breaking] API paper cuts — duplicate names, hand-copied setters, dead types (#2055) (by @gold-silver-copper)
- (examples) add force_tool_first_turn hook example (#2014) (by @gold-silver-copper)
- (auth) add non-interactive oauth cassette coverage (#2050) (by @gold-silver-copper)
- (perplexity) add cassette coverage (#2049) (by @gold-silver-copper)
- (providers) [breaking] remove galadriel provider (#2041) (by @gold-silver-copper)
- (providers) [breaking] collapse remaining providers onto GenericCompletionModel<Ext> (#2035 phases 2–4) (#2040) (by @gold-silver-copper)
- (providers) [breaking] migrate llamafile onto GenericCompletionModel<Ext> (#2035 phase 1) (#2038) (by @gold-silver-copper)
- (core) [breaking] delete unused evals module and experimental feature flag (#2036) (by @gold-silver-copper)
- Flatten Tool metadata API (#2029) (by @gold-silver-copper) - [#2029]
- (gemini) live cassette hook-system stress suite (#2013) (by @gold-silver-copper)
- Add Groq agent tool cassette regressions (#2011) (by @gold-silver-copper) - [#2011]
- Add Mistral agent tool cassette regressions (#2010) (by @gold-silver-copper) - [#2010]
- Add DeepSeek agent tool cassette regressions (#2009) (by @gold-silver-copper) - [#2009]
- Add xAI agent tool cassette regressions (#2008) (by @gold-silver-copper) - [#2008]
- Gate Gemini image cassette tests on image feature (#2007) (by @gold-silver-copper) - [#2007]
- Add OpenRouter agent tool cassette regressions (#2006) (by @gold-silver-copper) - [#2006]
- Add ChatGPT Codex cassette regression suite (#2005) (by @gold-silver-copper) - [#2005]
- (gemini) production-grade generateContent cassette suite (#2004) (by @gold-silver-copper)
- (anthropic) production-grade Messages API cassette suite (#2003) (by @gold-silver-copper)
- (openai) production-grade Responses API cassette suite + tool_choice and replay-ID fixes (#2002) (by @gold-silver-copper)
- (providers) add provider implementation checklist (#1997) (by @gold-silver-copper)
- (deps) bump assert_fs from 1.1.3 to 1.1.4 (#1933) (by @dependabot[bot])
- (deps) bump trybuild from 1.0.116 to 1.0.117 (#1935) (by @dependabot[bot])
- (deps) bump chrono from 0.4.44 to 0.4.45 (#1934) (by @dependabot[bot])
- (deps) bump uuid from 1.23.3 to 1.23.4 (#1975) (by @dependabot[bot])
- (deps) bump scylla from 1.6.0 to 1.7.0 (#1932) (by @dependabot[bot])
- (anthropic) add null citation streaming cassette (#1978) (by @gold-silver-copper)
- update agent and contribution guidance (#1974) (by @gold-silver-copper) - [#1974]
- (openai-compat) genuinely exercise the [#1958] tool-call eviction string-leak (+ live cassette) (#1962) (by @gold-silver-copper)
- (rig-core) [breaking] remove the experimental pipeline module (#1941) (by @gold-silver-copper)
- run doctests and stop rig-sqlite opting out of them (#1939) (by @gold-silver-copper) - [#1939]
- (rig-core) replace nanoid with fastrand for internal IDs (#1938) (by @gold-silver-copper)
- (examples) migrate to a package-per-example layout (#1937) (by @gold-silver-copper)
- add Archestra to "Who is using Rig?" section (#1925) (by @arsenyinfo) - [#1925]
Contributors
- @gold-silver-copper
- @dependabot[bot]
- @Kade-Powell
- @arsenyinfo
Changed
-
(agent) [breaking]
max_turnsanddefault_max_turnsnow bound the exact total number of model calls, including the initial call, tool continuations, and retries. A budget of0makes no model call, while1permits only the initial call. Unconfigured tool-then-answer flows now need an explicit total budget of2. To preserve the former maximum allowance of an explicit old budgetn, account for the old effectiven + 2calls; otherwise, set the intended literal total. -
(tool) [breaking] flatten
Tool/ToolDynmetadata: tool authors now implementdescription()andparameters()directly, andTool::definition(prompt)/ToolDyn::definition(prompt)are removed.ToolDefinitionremains a provider/request artifact generated from registered tools, withTool::NAME/Tool::name()/ToolDyn::name()as the single source of truth for advertised and dispatched tool names. -
(providers) [breaking] migrate
llamafileonto the sharedGenericCompletionModel<Ext>/GenericEmbeddingModel<Ext>path, deleting its hand-rolled completion model, request types, message flattening, and streaming profile.llamafile::CompletionModel/llamafile::EmbeddingModelare now type aliases for the generic models; the provider-specificStreamingCompletionResponsetype is replaced by the shared OpenAI one. Requests now serialize messages in the shared OpenAI shape (single-text user content still flattens to a string; system/multi-part content is sent as a content-part array, which llama.cpp-family servers accept). - (openai) [breaking] new
OpenAICompatibleProvidertrait (mirroringAnthropicCompatibleProvider) is now required byGenericCompletionModel'sExtparameter; it carries the telemetry provider name (so minimax/zai/xiaomimimo spans stop reporting as "openai") and anEMITS_COMPLETE_SINGLE_CHUNK_TOOL_CALLSflag for llama.cpp-style streaming tool calls. - (providers) [breaking] migrate the remaining OpenAI-chat-compatible providers onto
GenericCompletionModel<Ext>— groq, deepseek, mistral, together, moonshot (OpenAI side), perplexity, hyperbolic, mira, azure, and huggingface all lose their hand-rolledCompletionModelstructs, request types, andTryFrom<message::Message>conversions;CompletionModelin each module is now a type alias for the generic model. Provider wire dialects live inOpenAICompatibleProviderhooks: an associatedResponsetype,completion_path(Azure deployment URLs,/v1-prefixed routes),prepare_request(Groq native-tool folding, Moonshotrequiredtool-choice coercion, HuggingFace Fireworks model ids, Perplexity/Mira tool stripping),finalize_request_body(DeepSeek string content + thinking-gated tool choice, Mistral"any"tool choice +prefixfield + reasoning stripping, Mira raw-message flattening), andSUPPORTS_RESPONSE_FORMAT/STREAM_INCLUDE_USAGEconsts. Provider-specificStreamingCompletionResponsetypes are replaced by the shared OpenAI one. - (openai) [breaking]
ToolChoicegains aFunction { name }variant serializing OpenAI's{"type":"function","function":{"name":...}}form, somessage::ToolChoice::Specificwith one function is now supported instead of erroring;CompletionRequestfields are now public;OpenAIRequestParamsgains asupports_response_formatfield. - (openai) the shared
TryFrom<message::ToolResult>conversion now preferscall_idoveridfortool_call_id(matching provider-issued call ids); the shared streaming delta acceptsreasoningas an alias forreasoning_content(Groq), and the deprecatedfunction_callfinish reason maps to tool-call handling. - (providers) behavior notes from the migration:
max_tokensis now forwarded by deepseek, together, hyperbolic, and azure (previously silently dropped); together's streaming request uses standardstream/stream_optionsinstead ofstream_tokens, and a rig-levelToolChoice::Requirednow serializes asrequiredinstead of erroring; perplexity's non-streaming endpoint drops its stray/v1prefix (matching its streaming path and the real API); mira's preamble is sent as asystemmessage instead ofuser;response_formatderived fromoutput_schemais deferred while tools are pending a result (groq/mistral/azure previously applied it unconditionally); groq's streaming usage no longer falls back to the legacyx_groq.usageenvelope. - (openrouter) [breaking] de-fork OpenRouter's parallel message model (issue [#2035] phase 4):
openrouter::{Message, UserContent, ImageUrl}are now re-exports of the shared OpenAI types, and the fork'sFileContent/VideoUrlContentare replaced by sharedFileData/VideoUrl. To support this, the shared OpenAI types gain OpenRouter's optional extensions —UserContent::Video,ImageUrl.detailbecomesOption<ImageDetail>(OpenAI still sends"detail":"auto"), andMessage::Assistantgains a skip-when-emptyreasoning_detailsfield, an inbound-onlyimagesfield (never serialized back into requests), plus a deserialize-onlyrole: "model"alias.ReasoningDetails/ResponseImagemove into the openai module (re-exported from openrouter). OpenRouter-specific message conversion now goes throughopenrouter::messages_from_rig_message;TryInto<Vec<openrouter::Message>>resolves to the plain shared conversion. OpenRouter keeps its own request/response/streaming layer (provider preferences, cost accounting, reasoning-details grouping, generated-image extraction) as a documented exception. - (openai) the
UserContentaudio part now serializes its tag asinput_audio(matching OpenAI's actual API);audiois still accepted when deserializing. - (openai)
StreamingCompletionResponseis now generic over the provider's streaming usage payload (StreamingCompletionResponse<U = Usage>, selected viaOpenAICompatibleProvider::StreamingUsage), so Mistral's cached-token fallbacks and DeepSeek's cache hit/miss counters survive streaming instead of being narrowed to OpenAI's usage shape. - (providers) pre-migration request filtering is preserved where provider support is unverified: hyperbolic still drops
tools/tool_choice/output_schemawith warnings, and perplexity flattens text-only message content back to plain strings (mixed multimodal content is passed through for sonar models). llamafile keeps the current mapping ofoutput_schemato ajson_schemaresponse format (as on the shared path since the llamafile migration; modern llama.cpp servers support it). - (llamafile) the chat cassettes are now recorded against an actual llama.cpp
llama-server, confirming the shared OpenAI wire shape (content-part arrays, tool calls, tool results) against the real llamafile-family server rather than an OpenAI-compatible proxy. - (openai) the assistant tool-call echo now serializes
call_id(falling back toid) so it stays consistent with the tool-result side when history recorded via the Responses API is replayed through chat completions; streaming deltacontenttolerates content-part arrays (Mistral reasoning models) instead of dropping the chunk. - (providers) review fixes: mira and perplexity no longer send
stream_options(their APIs never received it pre-migration); moonshot rejects a specific forced tool client-side again; openrouter serializes plain assistant reasoning under its documentedreasoningkey; azure telemetry spans reportazure.openaiagain; mira usage math saturates instead of overflowing; perplexity strips tool-exchange remnants from shared histories. - (providers) second review round: openrouter tool-result messages prefer the provider-issued
call_id(matching the assistant echo side); Azure's deployment URL stays pinned to the model the handle was created with (a per-requestmodeloverride only changes the body, as pre-migration); shared streaming spans recordgen_ai.system_instructionsagain; providers without tool support (perplexity, mira, and now hyperbolic) sanitize tool-exchange remnants from shared histories via one shared helper that also preserves strict role alternation (tool-call-only assistant turns are dropped and consecutive assistant turns merged); openrouter's dead pre-migrationToolChoicetype is removed, andToolChoice::Specificwith multiple function names now errors client-side for openrouter (the old fork serialized a non-standard array). - (moonshot) [breaking] reasoning-only assistant history turns are no longer preserved: the shared conversion drops assistant messages with neither text nor tool calls. Reasoning attached to text or tool-call turns still round-trips via
reasoning_content. - (providers) [breaking] responses with empty assistant content and no tool calls now surface the shared path's "empty response" error for hyperbolic, perplexity, and huggingface (previously they returned an empty text completion).
- (providers) [breaking] additional removed public items: the raw response types of perplexity, hyperbolic, and huggingface (each module keeps a
CompletionResponsealias to the shared OpenAI payload;Message/Choice/Usage/Delta/Rolecompanions are gone),together::ToolChoice/ToolChoiceFunctionKind,moonshot::ToolChoice,groq::send_compatible_streaming_requestanddeepseek::send_compatible_streaming_request(useopenai::send_compatible_streaming_request), and openrouter'sUserContentbuilder helpers (image_url,file_base64,video_url, ...) — construct the sharedopenaicontent variants directly. - (openai) [breaking] sending rig
Videouser content to providers on the shared conversion now serializes avideo_urlcontent part (an OpenRouter/gateway extension) instead of returning a client-side conversion error; providers without video support will reject it server-side. - (providers) [breaking] telemetry: migrated providers' streaming spans are now named
chatwithgen_ai.operation.name = "chat"(previouslychat_streaming). GenAI message-content span fields (gen_ai.input.messages/gen_ai.output.messages) are intentionally left empty instead of recording serialized request/response messages, preserving the privacy/cardinality behavior from [#2065]; the publicSpanCombinator::record_model_outputhelper is removed.gen_ai.request.modelreports the per-request model override when one applies. - (providers) third review round: history sanitization treats
refusalparts as text when flattening and, for alternation-strict perplexity, merges consecutive same-role turns (dropping a tool exchange could previously leaveuser/useradjacency its API rejects); streaming no longer overwrites caller-suppliedstream_options; openrouter's encrypted reasoning details now correlate with the wire tool-call id and its non-streaming usage uses the reportedcompletion_tokens(no underflow); base64 videos with unrecognized MIME types round-trip as data-URI URLs instead of failing conversion. - (providers) fourth review round — agent structured output:
GenericCompletionModelno longer claims native structured output composes with tools for every provider; it now followsSUPPORTS_RESPONSE_FORMAT. Agents with tools plus an output schema on deepseek/together/moonshot/huggingface/hyperbolic/perplexity/mira fall back to tool-mode schema enforcement as their pre-migration models did (the migration had silently dropped the schema entirely); groq/mistral/azure now compose natively like openai. - (openai) new
OpenAICompatibleProvider::SUPPORTS_TOOLSconst (default true): perplexity, hyperbolic, and mira set it false andtools/tool_choiceare dropped with a warning during request conversion — before tool-choice validation, so a multi-nameToolChoice::Specificno longer errors client-side on providers that ignored it pre-migration. - (openai) streaming robustness:
include_usageis inserted into caller-suppliedstream_optionsinstead of being skipped (or clobbering the caller's keys, the pre-migration behavior); a delta carrying bothreasoning_contentandreasoningno longer fails as a serde duplicate-field error that dropped the whole chunk; streaming tool-callindexdefaults to 0 when omitted (Mistral marks it optional);CompletionResponse.object/createdare defaulted on deserialization for gateways that omit them (HuggingFace router sub-providers). - (openrouter) non-streaming usage falls back to
total - prompt(saturating) when the gateway omitscompletion_tokens; streaming spans follow the shared telemetry behavior of leaving GenAI message-content fields empty. - (openai) [breaking]
ToolChoiceis now#[non_exhaustive];GenericCompletionModel'sstrict_tools/tool_result_array_contentfields are private (use thewith_*builder methods) and the redundantwith_modelconstructor is removed (usenew).
Removed
- (derive) [breaking] remove the unused public
rig_derive::ProviderClientderive macro and itsdeluxedependency;Embedandrig_toolare unchanged, and no replacement is provided. - (core) [breaking] remove unused
Extractor::{get_inner, into_inner}and the always-failingTryFrom<String> for Nothing; no direct replacements are provided. - (core) [breaking] remove the unused public
streaming::stream_completion_to_stdouthelper; use the high-levelagent::stream_to_stdouthelper instead. - (core) [breaking] remove the unused public
AudioGeneration<M>,ImageGeneration<M>, andTranscription<M>wrapper traits; use the correspondingAudioGenerationModel,ImageGenerationModel, andTranscriptionModelAPIs and request builders directly. - (core) [breaking] remove the unused
evalsmodule (Evaltrait, judge metrics, and builders) along with theexperimentalfeature flag that gated it - (anthropic) [breaking] remove the unused public
providers::anthropic::decodersmodule; Anthropic streaming uses the shared SSE machinery. - (providers) [breaking] remove the Galadriel provider integration (
providers::galadriel), including its client, model constants, environment-variable support, and ignored live tests.