Bump crates, audit deps, and migrate Perplexity to Agent API #1

Merged
thesimonharms merged 1 commit from cursor/update-deps-and-audit-a262 into main 2026-09-02 15:12:17 -04:00
thesimonharms commented 2026-09-02 14:58:01 -04:00 (Migrated from github.com)

Summary

Bring baochuan’s crates current, run a RustSec audit, and check every upstream provider API against current docs (September 2026).

Crate version is 0.2.0 → 0.3.0 because reqwest 0.13 is a public dependency (BaochuanError::Http) and Perplexity’s default request path changed.

Package updates

Crate Was Now
reqwest 0.12 0.13 (rustls default; query is now an explicit feature)
tokio 1 1.53
serde 1 1.0.229
serde_json 1 1.0.151
futures-util 0.3 0.3.31 (resolves 0.3.34)
thiserror 2 2.0.17 (resolves 2.0.20)
tracing 0.1 0.1.41 (resolves 0.1.44)
async-trait 0.1 0.1.88 (resolves 0.1.92)
bytes 1 1.10 (resolves 1.12.1)
mockito 1 1.7.2
tracing-subscriber 0.3 0.3.20 (resolves 0.3.23)

Also set rust-version = "1.85" (required by edition 2024). Cloudflare model listing needs the new reqwest query feature.

reqwest 0.13 breaking changes that affect this crate:

  • Default TLS is rustls (aws-lc), not native-tls
  • RequestBuilder::query is feature-gated — enabled for Cloudflare
  • Existing json / stream / bytes_stream APIs are unchanged

Security audit

cargo audit against the resolved lockfile (213 crates, 1239 advisories loaded from rustsec/advisory-db): no vulnerabilities.

Code review of the HTTP surface:

  • Keys stay in memory and are sent only as Authorization: Bearer / x-api-key / x-goog-api-key
  • No hardcoded secrets; README already tells callers to use env vars
  • No unsafe
  • rustls-by-default is a security improvement over OpenSSL/native-tls
  • API error bodies are still returned to the caller (they can contain provider messages; that is existing behavior)

Upstream API review

Checked each provider’s current docs against what baochuan sends.

Required change (this PR)

Perplexity — Sonar Chat Completions (POST /chat/completions and POST /v1/sonar) is retired on 27 September 2026. Replacement is the Agent API:

  • Endpoint: POST https://api.perplexity.ai/v1/agent
  • Body: input (not messages), max_output_tokens (not max_tokens)
  • Search is no longer implicit — tools: [{ "type": "web_search" }] is required
  • Citations come from output[] items with type: "search_results", not a top-level citations array
  • Streaming uses Responses events (response.output_text.delta)

The Perplexity provider now talks to /v1/agent. Legacy slugs still work:

Old model Agent mapping
sonar preset fast
sonar-pro preset low
sonar-reasoning / sonar-reasoning-pro preset medium
sonar-deep-research preset high

Qualified IDs such as perplexity/sonar and preset names (fast, low, …) are passed through.

Still compatible (no wire-format change)

Provider Finding
OpenAI Chat Completions at /v1/chat/completions is still supported. Responses is recommended for new work; Hermes already uses /v1/responses. max_tokens → max_completion_tokens remapping stays correct.
Anthropic POST /v1/messages, anthropic-version: 2023-06-01, x-api-key — still current.
Gemini generateContent + x-goog-api-key still current. User action: Google rejects unrestricted standard keys; migrate to AI Studio auth keys before September 2026.
DeepSeek https://api.deepseek.com/v1 + deepseek-v4-flash / deepseek-v4-pro still current.
Moonshot / Kimi https://api.moonshot.ai/v1 + kimi-k3 still current.
Qwen / DashScope Compatible-mode URLs unchanged.
Cloudflare Native /ai/run/ and /ai/models/search still current.
Ollama Native /api/chat NDJSON still current.
Nous, Groq, Together, Fireworks, Cerebras, SambaNova, Hugging Face, NVIDIA, DeepInfra, OpenRouter, xAI, Mistral, LM Studio, llama.cpp OpenAI-compatible endpoints unchanged.
Hermes Agent Already on /v1/responses.

Docs-only updates

  • MiniMax examples: MiniMax-M2 → MiniMax-M3 (endpoint unchanged)
  • Zhipu / Z.ai examples: glm-4.6 → glm-5.3 (endpoint unchanged)
  • Copilot: documented that GPT-5 / Codex models on Copilot may require POST /responses instead of Chat Completions
  • Gemini: documented the auth-key migration

Tests

  • cargo test — 7 lib + 5 agent + 108 integration + 56 doctests, all passing
  • cargo clippy --all-targets -- -D warnings — clean
  • cargo fmt --all — applied
  • cargo audit — no advisories

Breaking notes for 0.3.0

  • Consumers that match on BaochuanError::Http(reqwest::Error) must use reqwest 0.13
  • PerplexityProvider::with_base_url now expects the /v1 root; chat is sent to {base}/agent
Open in Web Open in Cursor 
<!-- CURSOR_AGENT_PR_BODY_BEGIN --> ## Summary Bring baochuan’s crates current, run a RustSec audit, and check every upstream provider API against current docs (September 2026). Crate version is **0.2.0 → 0.3.0** because `reqwest` 0.13 is a public dependency (`BaochuanError::Http`) and Perplexity’s default request path changed. ## Package updates | Crate | Was | Now | |---|---|---| | `reqwest` | 0.12 | **0.13** (rustls default; `query` is now an explicit feature) | | `tokio` | 1 | 1.53 | | `serde` | 1 | 1.0.229 | | `serde_json` | 1 | 1.0.151 | | `futures-util` | 0.3 | 0.3.31 (resolves 0.3.34) | | `thiserror` | 2 | 2.0.17 (resolves 2.0.20) | | `tracing` | 0.1 | 0.1.41 (resolves 0.1.44) | | `async-trait` | 0.1 | 0.1.88 (resolves 0.1.92) | | `bytes` | 1 | 1.10 (resolves 1.12.1) | | `mockito` | 1 | 1.7.2 | | `tracing-subscriber` | 0.3 | 0.3.20 (resolves 0.3.23) | Also set `rust-version = "1.85"` (required by edition 2024). Cloudflare model listing needs the new `reqwest` `query` feature. `reqwest` 0.13 breaking changes that affect this crate: - Default TLS is rustls (aws-lc), not native-tls - `RequestBuilder::query` is feature-gated — enabled for Cloudflare - Existing `json` / `stream` / `bytes_stream` APIs are unchanged ## Security audit `cargo audit` against the resolved lockfile (213 crates, 1239 advisories loaded from rustsec/advisory-db): **no vulnerabilities**. Code review of the HTTP surface: - Keys stay in memory and are sent only as `Authorization: Bearer` / `x-api-key` / `x-goog-api-key` - No hardcoded secrets; README already tells callers to use env vars - No `unsafe` - rustls-by-default is a security improvement over OpenSSL/native-tls - API error bodies are still returned to the caller (they can contain provider messages; that is existing behavior) ## Upstream API review Checked each provider’s current docs against what baochuan sends. ### Required change (this PR) **Perplexity** — Sonar Chat Completions (`POST /chat/completions` and `POST /v1/sonar`) is retired on **27 September 2026**. Replacement is the Agent API: - Endpoint: `POST https://api.perplexity.ai/v1/agent` - Body: `input` (not `messages`), `max_output_tokens` (not `max_tokens`) - Search is no longer implicit — `tools: [{ "type": "web_search" }]` is required - Citations come from `output[]` items with `type: "search_results"`, not a top-level `citations` array - Streaming uses Responses events (`response.output_text.delta`) The Perplexity provider now talks to `/v1/agent`. Legacy slugs still work: | Old model | Agent mapping | |---|---| | `sonar` | preset `fast` | | `sonar-pro` | preset `low` | | `sonar-reasoning` / `sonar-reasoning-pro` | preset `medium` | | `sonar-deep-research` | preset `high` | Qualified IDs such as `perplexity/sonar` and preset names (`fast`, `low`, …) are passed through. ### Still compatible (no wire-format change) | Provider | Finding | |---|---| | OpenAI | Chat Completions at `/v1/chat/completions` is still supported. Responses is recommended for new work; Hermes already uses `/v1/responses`. `max_tokens` → `max_completion_tokens` remapping stays correct. | | Anthropic | `POST /v1/messages`, `anthropic-version: 2023-06-01`, `x-api-key` — still current. | | Gemini | `generateContent` + `x-goog-api-key` still current. **User action:** Google rejects unrestricted standard keys; migrate to AI Studio auth keys before September 2026. | | DeepSeek | `https://api.deepseek.com/v1` + `deepseek-v4-flash` / `deepseek-v4-pro` still current. | | Moonshot / Kimi | `https://api.moonshot.ai/v1` + `kimi-k3` still current. | | Qwen / DashScope | Compatible-mode URLs unchanged. | | Cloudflare | Native `/ai/run/` and `/ai/models/search` still current. | | Ollama | Native `/api/chat` NDJSON still current. | | Nous, Groq, Together, Fireworks, Cerebras, SambaNova, Hugging Face, NVIDIA, DeepInfra, OpenRouter, xAI, Mistral, LM Studio, llama.cpp | OpenAI-compatible endpoints unchanged. | | Hermes Agent | Already on `/v1/responses`. | ### Docs-only updates - MiniMax examples: `MiniMax-M2` → `MiniMax-M3` (endpoint unchanged) - Zhipu / Z.ai examples: `glm-4.6` → `glm-5.3` (endpoint unchanged) - Copilot: documented that GPT-5 / Codex models on Copilot may require `POST /responses` instead of Chat Completions - Gemini: documented the auth-key migration ## Tests - `cargo test` — 7 lib + 5 agent + 108 integration + 56 doctests, all passing - `cargo clippy --all-targets -- -D warnings` — clean - `cargo fmt --all` — applied - `cargo audit` — no advisories ## Breaking notes for 0.3.0 - Consumers that match on `BaochuanError::Http(reqwest::Error)` must use reqwest 0.13 - `PerplexityProvider::with_base_url` now expects the `/v1` root; chat is sent to `{base}/agent` <!-- CURSOR_AGENT_PR_BODY_END --> <div><a href="https://cursor.com/agents/bc-01a06372-d083-7f0f-9a52-ec63cde3a262?cursor_ref=pr_footer&cursor_cta=open_in_web"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-web-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-web-light.png"><img alt="Open in Web" width="114" height="28" src="https://cursor.com/assets/images/open-in-web-dark.png"></picture></a>&nbsp;<a href="https://cursor.com/background-agent?bcId=bc-01a06372-d083-7f0f-9a52-ec63cde3a262&cursor_ref=pr_footer&cursor_cta=open_in_cursor"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-cursor-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-cursor-light.png"><img alt="Open in Cursor" width="131" height="28" src="https://cursor.com/assets/images/open-in-cursor-dark.png"></picture></a>&nbsp;</div>
Sign in to join this conversation.
No description provided.