Download Latest Version rig-v0.41.0 source code.zip (10.6 MB)
Email in envelope

Get an email when there's a new version of Rig

Home / v0.40.0
Name Modified Size InfoDownloads / 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_turns and default_max_turns now bound the exact total number of model calls, including the initial call, tool continuations, and retries. A budget of 0 makes no model call, while 1 permits only the initial call. Unconfigured tool-then-answer flows now need an explicit total budget of 2. To preserve the former maximum allowance of an explicit old budget n, account for the old effective n + 2 calls; otherwise, set the intended literal total.

  • (tool) [breaking] flatten Tool / ToolDyn metadata: tool authors now implement description() and parameters() directly, and Tool::definition(prompt) / ToolDyn::definition(prompt) are removed. ToolDefinition remains a provider/request artifact generated from registered tools, with Tool::NAME / Tool::name() / ToolDyn::name() as the single source of truth for advertised and dispatched tool names.

  • (providers) [breaking] migrate llamafile onto the shared GenericCompletionModel<Ext> / GenericEmbeddingModel<Ext> path, deleting its hand-rolled completion model, request types, message flattening, and streaming profile. llamafile::CompletionModel / llamafile::EmbeddingModel are now type aliases for the generic models; the provider-specific StreamingCompletionResponse type 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 OpenAICompatibleProvider trait (mirroring AnthropicCompatibleProvider) is now required by GenericCompletionModel's Ext parameter; it carries the telemetry provider name (so minimax/zai/xiaomimimo spans stop reporting as "openai") and an EMITS_COMPLETE_SINGLE_CHUNK_TOOL_CALLS flag 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-rolled CompletionModel structs, request types, and TryFrom<message::Message> conversions; CompletionModel in each module is now a type alias for the generic model. Provider wire dialects live in OpenAICompatibleProvider hooks: an associated Response type, completion_path (Azure deployment URLs, /v1-prefixed routes), prepare_request (Groq native-tool folding, Moonshot required tool-choice coercion, HuggingFace Fireworks model ids, Perplexity/Mira tool stripping), finalize_request_body (DeepSeek string content + thinking-gated tool choice, Mistral "any" tool choice + prefix field + reasoning stripping, Mira raw-message flattening), and SUPPORTS_RESPONSE_FORMAT / STREAM_INCLUDE_USAGE consts. Provider-specific StreamingCompletionResponse types are replaced by the shared OpenAI one.
  • (openai) [breaking] ToolChoice gains a Function { name } variant serializing OpenAI's {"type":"function","function":{"name":...}} form, so message::ToolChoice::Specific with one function is now supported instead of erroring; CompletionRequest fields are now public; OpenAIRequestParams gains a supports_response_format field.
  • (openai) the shared TryFrom<message::ToolResult> conversion now prefers call_id over id for tool_call_id (matching provider-issued call ids); the shared streaming delta accepts reasoning as an alias for reasoning_content (Groq), and the deprecated function_call finish reason maps to tool-call handling.
  • (providers) behavior notes from the migration: max_tokens is now forwarded by deepseek, together, hyperbolic, and azure (previously silently dropped); together's streaming request uses standard stream/stream_options instead of stream_tokens, and a rig-level ToolChoice::Required now serializes as required instead of erroring; perplexity's non-streaming endpoint drops its stray /v1 prefix (matching its streaming path and the real API); mira's preamble is sent as a system message instead of user; response_format derived from output_schema is deferred while tools are pending a result (groq/mistral/azure previously applied it unconditionally); groq's streaming usage no longer falls back to the legacy x_groq.usage envelope.
  • (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's FileContent/VideoUrlContent are replaced by shared FileData/VideoUrl. To support this, the shared OpenAI types gain OpenRouter's optional extensions — UserContent::Video, ImageUrl.detail becomes Option<ImageDetail> (OpenAI still sends "detail":"auto"), and Message::Assistant gains a skip-when-empty reasoning_details field, an inbound-only images field (never serialized back into requests), plus a deserialize-only role: "model" alias. ReasoningDetails/ResponseImage move into the openai module (re-exported from openrouter). OpenRouter-specific message conversion now goes through openrouter::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 UserContent audio part now serializes its tag as input_audio (matching OpenAI's actual API); audio is still accepted when deserializing.
  • (openai) StreamingCompletionResponse is now generic over the provider's streaming usage payload (StreamingCompletionResponse<U = Usage>, selected via OpenAICompatibleProvider::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_schema with 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 of output_schema to a json_schema response 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 to id) so it stays consistent with the tool-result side when history recorded via the Responses API is replayed through chat completions; streaming delta content tolerates 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 documented reasoning key; azure telemetry spans report azure.openai again; 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-request model override only changes the body, as pre-migration); shared streaming spans record gen_ai.system_instructions again; 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-migration ToolChoice type is removed, and ToolChoice::Specific with 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 CompletionResponse alias to the shared OpenAI payload; Message/Choice/Usage/Delta/Role companions are gone), together::ToolChoice/ToolChoiceFunctionKind, moonshot::ToolChoice, groq::send_compatible_streaming_request and deepseek::send_compatible_streaming_request (use openai::send_compatible_streaming_request), and openrouter's UserContent builder helpers (image_url, file_base64, video_url, ...) — construct the shared openai content variants directly.
  • (openai) [breaking] sending rig Video user content to providers on the shared conversion now serializes a video_url content 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 chat with gen_ai.operation.name = "chat" (previously chat_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 public SpanCombinator::record_model_output helper is removed. gen_ai.request.model reports the per-request model override when one applies.
  • (providers) third review round: history sanitization treats refusal parts as text when flattening and, for alternation-strict perplexity, merges consecutive same-role turns (dropping a tool exchange could previously leave user/user adjacency its API rejects); streaming no longer overwrites caller-supplied stream_options; openrouter's encrypted reasoning details now correlate with the wire tool-call id and its non-streaming usage uses the reported completion_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: GenericCompletionModel no longer claims native structured output composes with tools for every provider; it now follows SUPPORTS_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_TOOLS const (default true): perplexity, hyperbolic, and mira set it false and tools/tool_choice are dropped with a warning during request conversion — before tool-choice validation, so a multi-name ToolChoice::Specific no longer errors client-side on providers that ignored it pre-migration.
  • (openai) streaming robustness: include_usage is inserted into caller-supplied stream_options instead of being skipped (or clobbering the caller's keys, the pre-migration behavior); a delta carrying both reasoning_content and reasoning no longer fails as a serde duplicate-field error that dropped the whole chunk; streaming tool-call index defaults to 0 when omitted (Mistral marks it optional); CompletionResponse.object/created are 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 omits completion_tokens; streaming spans follow the shared telemetry behavior of leaving GenAI message-content fields empty.
  • (openai) [breaking] ToolChoice is now #[non_exhaustive]; GenericCompletionModel's strict_tools/tool_result_array_content fields are private (use the with_* builder methods) and the redundant with_model constructor is removed (use new).

Removed

  • (derive) [breaking] remove the unused public rig_derive::ProviderClient derive macro and its deluxe dependency; Embed and rig_tool are unchanged, and no replacement is provided.
  • (core) [breaking] remove unused Extractor::{get_inner, into_inner} and the always-failing TryFrom<String> for Nothing; no direct replacements are provided.
  • (core) [breaking] remove the unused public streaming::stream_completion_to_stdout helper; use the high-level agent::stream_to_stdout helper instead.
  • (core) [breaking] remove the unused public AudioGeneration<M>, ImageGeneration<M>, and Transcription<M> wrapper traits; use the corresponding AudioGenerationModel, ImageGenerationModel, and TranscriptionModel APIs and request builders directly.
  • (core) [breaking] remove the unused evals module (Eval trait, judge metrics, and builders) along with the experimental feature flag that gated it
  • (anthropic) [breaking] remove the unused public providers::anthropic::decoders module; 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.
Source: README.md, updated 2026-07-11