Skip to content

Releases: yologdev/yoagent

v0.10.0

Choose a tag to compare

@yuanhao yuanhao released this 06 Jul 06:44
5720089

The headline of 0.10.0 is a config-first construction API. Build an agent from a single ModelConfig — the provider, model id, context window, pricing, and API key resolution all come from one place.

// before (0.9): pair provider + config by hand, model id passed twice
let agent = Agent::new(OpenAiCompatProvider)
    .with_model_config(ModelConfig::zai("glm-4.7", "GLM 4.7"))
    .with_model("glm-4.7")
    .with_api_key(key);

// after (0.10): provider inferred from config.api; key from ZAI_API_KEY
let agent = Agent::from_config(ModelConfig::zai("glm-4.7", "GLM 4.7"));

Added

  • Agent::from_config(ModelConfig) — the new primary constructor (provider + env key resolved automatically).
  • Agent::from_provider(provider, ModelConfig) — explicit provider / test doubles.
  • Agent::from_config_with(&registry, ModelConfig) -> Result<_, AgentBuildError> — custom registry.
  • Agent::set_model(ModelConfig) — switch model mid-session (never silently clobbers an explicit provider).
  • SubAgentTool::from_config / from_config_with / from_provider mirrors.
  • ModelConfig::mock(), exported AgentBuildError, ProviderRegistry::resolve(), StreamProvider::protocol().

Deprecated (removed in 1.0 — still work, with a compiler nudge)

  • Agent::new, Agent::with_model, Agent::with_model_config
  • SubAgentTool::new, SubAgentTool::with_model, SubAgentTool::with_model_config

with_api_key is not deprecated. Nothing is removed in 0.10 — existing 0.9 code compiles and runs (with deprecation warnings) unless you build with deny(warnings).

Fixed

  • Google/Vertex usage no longer double-counts cached tokens.
  • Retry-After clamped to max_delay_ms.
  • Compaction budget calibration subtracts measured overhead instead of ratio-scaling (the old formula could collapse the budget toward zero).
  • session_cost_usd() returns None for unpriced models instead of 0.0.
  • Missing API keys log a warning naming the env var to set.

Full migration guide (before/after table) in CHANGELOG.md.

v0.9.0

Choose a tag to compare

@yuanhao yuanhao released this 05 Jul 12:51
6e2aa52

A breaking release batching the changes anticipated in #33: the reqwest 0.13/rustls upgrade, support for the current model generation, two new provider gateways, queue inspection, and a crate-wide exhaustiveness policy.

⚠️ Breaking changes

Dependencies / MSRV

  • reqwest 0.12 → 0.13 with rustls as the TLS backend — OpenSSL is no longer a build dependency (faster builds on Android/Windows). reqwest-eventsource replaced by the maintained kameleoon-reqwest-eventsource fork (aliased; reqwest_eventsource:: paths unchanged). Rust 1.85+ required (was 1.75). Public API surfaces reqwest 0.13 / fork types (classify_eventsource_error, OpenApiError::HttpError). (#52)

Anthropic provider

  • Adaptive thinking is the default (thinking: {"type": "adaptive"} + output_config.effort) — required by Claude Fable 5 / Opus 4.7+/4.8 / Sonnet 5. Pre-4.6 models with thinking enabled need AnthropicCompat::legacy() (budget-based, now clamped to the API's 1024-token minimum). (#53)
  • ModelConfig.base_url is now honored ({base}/messages); the anthropic() preset default includes /v1 (old persisted configs with the un-versioned host keep working). Custom headers apply; Bearer auth available via AnthropicCompat.bearer_auth.
  • New StopReason::Refusal variant (safety-system declines, e.g. Claude Fable 5); model_context_window_exceeded maps to the standard overflow-error shape so compaction-retry hooks fire.
  • anthropic() preset defaults: max_tokens 8192 → 16000, reasoning: true.

Exhaustiveness policy (#33 item 1, #55)

  • #[non_exhaustive] on Content (matches need a wildcard arm), on the ToolCall/Thinking variants and Message::Assistant (construct via Content::tool_call() / tool_call_with_metadata() / thinking() / thinking_signed() and Message::assistant(); patterns need ..), and on ModelConfig (construct via presets or the new ModelConfig::custom(); field mutation still works, literals/FRU do not). Future field additions become non-breaking.
  • StopReason stays deliberately exhaustive: a new variant should be a compile error downstream, not a silent wildcard fall-through.
  • ModelConfig gains the anthropic: Option<AnthropicCompat> field (serde-compatible with older persisted configs).

Features

  • New model presets with real pricing: claude_fable_5(), claude_opus_4_8(), claude_sonnet_5(), claude_haiku_4_5(), gpt_5_5() — correct context windows, output caps, and CostConfig values. (#53)
  • OpenCode Zen & Go gateways (#48): ModelConfig::opencode_zen(id) / opencode_go(id) select the API protocol from the model family (Responses / Anthropic Messages with Bearer auth / Chat Completions). See docs/providers/opencode.md.
  • Queue inspection API (#50): steering_queue_snapshot() / follow_up_queue_snapshot(), _len(), atomic take_*_queue(), and batch steer_all() / follow_up_all() — enables pi-style pending-message UIs. Edit-window semantics documented in docs/concepts/agent-loop.md.
  • ModelConfig::custom(api, provider, base_url, id, name) for protocols without a preset (Bedrock, Vertex, Azure).

Fixes

  • Google/Gemini: mid-stream {"error": ...} payloads and transport failures now surface as errors (previously a silently truncated "successful" turn); SAFETY-family finish reasons map to StopReason::Refusal; SSE splitting takes the earliest separator (mixed CRLF/LF buffers no longer merge events); an empty text part no longer swallows a functionCall in the same part. (#55)
  • Anthropic: a refused turn no longer poisons the conversation (empty assistant messages are skipped when serializing history) and carries an explanatory error_message; legacy thinking budgets below the API minimum no longer 400.
  • CI now builds with --all-features, so the openapi feature is compiled and linted on every PR.

Testing

New wiremock-based provider stream tests (Anthropic + Google) cover refusal/overflow stop-reason mapping, all auth branches, thought-signature round-trips, and SSE edge cases — scenarios previously reachable only with live API keys.

Full changelog: v0.8.4...v0.9.0

v0.8.4

Choose a tag to compare

@yuanhao yuanhao released this 21 Jun 18:25
6bf9acb

What's Changed

  • feat: SubAgentTool::with_skills (#46) — attach a SkillSet to a sub-agent so it sees the skills index. The index is appended to the sub-agent's system prompt at dispatch time, mirroring Agent::with_skills. Backward compatible (additive API). Closes #45.

Full Changelog: v0.8.3...v0.8.4

v0.8.3

Choose a tag to compare

@yuanhao yuanhao released this 26 May 16:26
3f6495c

What's Changed

  • Add first-class Qwen / DashScope support via ModelConfig::qwen(...).
  • Add OpenAiCompat::qwen() for Qwen reasoning-content parsing and OpenAI-compatible token behavior.
  • Add ModelConfig::openai_compat(...) for local/custom deployments that need explicit model-family compatibility flags.
  • Document hosted Qwen, regional DashScope URLs, local Qwen, and combined Qwen-on-Ollama compatibility.

Validation

  • CI passed on PR #42 and PR #43.
  • Local cargo test passed before release.

v0.8.2

Choose a tag to compare

@yuanhao yuanhao released this 26 May 15:51
cfc3b6f

What's Changed

  • Add first-class Ollama support via ModelConfig::ollama(base_url, model_id).
  • Honor requires_assistant_after_tool_result for OpenAI-compatible providers, fixing Ollama tool-result continuation compatibility.
  • Keep generic ModelConfig::local(...) behavior neutral for other local OpenAI-compatible servers.
  • Preserve backward compatibility for serialized OpenAiCompat configs by defaulting the new flag to false.

Validation

  • CI passed on PR #40 and PR #41.
  • Local cargo test passed before release.

v0.8.1

Choose a tag to compare

@yuanhao yuanhao released this 26 May 15:17
14841f4

What's Changed

  • Updated DeepSeek support for the current V4 API shape:
    • default CLI model is now deepseek-v4-flash
    • DeepSeek uses https://api.deepseek.com
    • DeepSeek requests use max_tokens, thinking, and reasoning_effort
    • DeepSeek cache hit/miss usage fields are parsed when present
  • Added Model Presets documentation covering first-class provider constructors and DeepSeek legacy aliases.
  • Fixed execution-limit accounting so cached prompt tokens count toward max_total_tokens for Claude and OpenAI-compatible providers.
  • Added regression coverage for cached-token execution limits.

Validation

  • cargo fmt --check
  • cargo test

v0.8.0

Choose a tag to compare

@yuanhao yuanhao released this 27 Apr 13:48
b49a7a2

Changes since v0.7.5

Breaking

  • Content::ToolCall now includes provider_metadata: Option<serde_json::Value> (#32)

Features

  • SharedState: pluggable key-value store for sub-agent communication (#35)
    • SharedStateBackend trait with MemoryBackend (default) and FileBackend backends
    • SubAgentTool::with_shared_state() — opt-in, injects shared_state tool automatically
  • Multi-provider sub-agents: SubAgentTool::with_model_config() for non-Anthropic providers (#35)
  • Inter-turn delay: turn_delay on AgentLoopConfig and SubAgentTool (#35)
  • Sub-agent error surfacing: StopReason::Error now propagated as ToolError::Failed (#35)

Fixes

  • Gemini: fix streaming and function calling (#32)
  • Filter empty text blocks from sub-agent output (#35)

Examples

  • examples/rlm.rs — recursive 2-level agent delegation with Grok
  • examples/code_review.rs — 3 parallel sub-agents reviewing via shared state
  • examples/shared_state.rs — parallel analysis with shared state

v0.7.5

Choose a tag to compare

@yuanhao yuanhao released this 27 Mar 15:41
6784921

Bug Fixes

  • Filter empty text blocks to prevent API errors (#30, closes #29)
    • Filter out empty Content::Text blocks in all 7 providers before sending to APIs
    • Guard cache_control placement to skip empty text blocks in Anthropic provider
    • Cache breakpoint scans backwards past empty messages instead of silently dropping
    • Guard openai_compat single-text fast path against empty text

v0.7.4

Choose a tag to compare

@yuanhao yuanhao released this 25 Mar 23:03
c0a1282

Bug Fixes

  • Extract HTTP response body from EventSource errors (#27, closes #26)
    • Added classify_eventsource_error() to read response body from InvalidStatusCode errors and classify them properly (context overflow, rate limit, auth, API error)
    • Added classify_sse_error_event() for consistent SSE-embedded error classification
    • Only Transport errors are retryable; protocol/parse errors (StreamEnded, InvalidContentType) fail fast
    • Providers return Err(ProviderError) enabling retry logic for rate limits and context overflow
    • Removed spurious StreamEvent::Error channel sends that caused duplicate error events on retry

v0.7.3

Choose a tag to compare

@yuanhao yuanhao released this 25 Mar 21:31
fc4030c

New Features

  • MiniMax provider: Add ModelConfig::minimax() and OpenAiCompat::minimax() for MiniMax AI (MiniMax-Text-01, MiniMax-M1, etc.) with 1M context window support (#23)
  • Auto-derive ContextConfig: When context_config is not explicitly set, compaction budget is automatically derived from ModelConfig.context_window (80% for context, 20% reserved for output) (#25)
    • ContextConfig::from_context_window() available for manual use
    • without_context_management() correctly takes precedence over auto-derivation

Documentation

  • Updated provider docs with MiniMax and Z.ai support
  • Added all ModelConfig convenience constructors to provider overview
  • Documented context auto-derivation behavior and priority chain