Skip to content

feat: add Rust SDK for Honcho #691

Open
leszek3737 wants to merge 17 commits into
plastic-labs:mainfrom
leszek3737:sdk/rust-main
Open

feat: add Rust SDK for Honcho #691
leszek3737 wants to merge 17 commits into
plastic-labs:mainfrom
leszek3737:sdk/rust-main

Conversation

@leszek3737
Copy link
Copy Markdown

Description

First-party Rust SDK (honcho-ai) with full Python SDK parity. Single crate,
edition 2024, MSRV 1.88.

API surface

  • Honcho client — builder pattern, env-var resolution, lazy workspace
    auto-creation, paginated workspace/peer/session listing
  • Peers — create, update, chat (dialectic), streaming chat, representation,
    context, card CRUD, search
  • Sessions — create, delete, clone, peer management (PeerSpec), per-peer
    config, context (OpenAI/Anthropic format), summaries
  • Messages — batch create (chunked at 100), get, update, paginated listing
  • Conclusions — CRUD, semantic query, ConclusionScope, representation
  • File uploadFileSource enum (bytes / path / async stream), multipart
    streaming without in-memory buffering
  • Dialectic streamingDialecticStream adapter, cancel-safe SSE,
    UTF-8 split handling, accumulated FinalResponse

Engineering

  • #[deny(unwrap_used, expect_used, panic, unsafe_code)] on library code
  • 717+ tests: OpenAPI fixture validation, wiremock HTTP mocks, integration
    tests, compile-time assertions (Send + Sync + Clone)
  • 12 examples: quickstart, streaming, multi-peer, typed config, blocking, etc.
  • CI: fmt → clippy (pedantic + cargo) → test → doc → MSRV verify
  • Retryable HTTP client with exponential backoff, Retry-After support
  • blocking feature — sync facade over async API with runtime guard
  • tracing feature — #[tracing::instrument] on all public async methods
  • Page<TRaw, TOut> — lazy-fetch pagination with into_stream() and map()
  • 55+ typed DTOs validated against Honcho OpenAPI spec

Known limitations

  • No webhooks or API keys endpoints (pending server-side support)
  • No automatic SSE reconnection
  • MSRV 1.88

Files

  • sdks/rust/ — 211 files, ~25k LOC
  • .github/workflows/rust-sdk.yml — 85 lines, consolidated CI

leszek3737 added 12 commits May 12, 2026 22:39
#1)

* feat(rust-sdk): add honcho-ai Rust SDK with HTTP client and types

Initial implementation of the Rust SDK for Honcho AI (Phases 0-2).

Phase 0: Crate bootstrap
- Cargo.toml with reqwest, serde, tokio, bon 3.x, thiserror 2
- CI workflow, clippy.toml, rustfmt.toml, README, LICENSE

Phase 1: Foundation (322 tests)
- HonchoError enum with 13 variants (error mapping, retry-after parsing)
- 52 OpenAPI schema types across 10 modules (peer, workspace, session, message, etc.)
- decode.rs with serde_path_to_error integration
- Per-schema min/max JSON fixtures with roundtrip validation

Phase 2: HTTP client
- HttpClient with bon builder, retry loop, exponential backoff (30s cap),
  bearer auth, user-agent, content-type headers, empty body handling
- 32 route helpers with input validation
- 327 tests total (unit, integration, wiremock, compile assertions)

Code review fixes: parse_retry_after negative value clamp, custom client
header injection, dead code cleanup, type consistency (u64 pagination),
serde skip_serializing_if, PeerCardConfiguration dedup, SummaryType enum.

* feat(rust-sdk): add CI workflow for honcho SDK

Introduces a GitHub Actions workflow to lint, test, build documentation,
and verify the Minimum Supported Rust Version (MSRV) for the new Rust SDK.

* fix(rust-sdk): fix broken doc link and formatting

- Fix unresolved rustdoc link in validation.rs (use full crate:: path)
- Run cargo fmt on 12 files with formatting drift

* fix(rust-sdk): address Sourcery review + clippy warnings

- routes: assert! → debug_assert! on runtime inputs (no production panics)
- client: align retry backoff attempt index across HTTP/transport paths
- pagination: replace PeerPage/WorkspacePage structs with Page<T> aliases
- message: MessageUploadForm.file String → Vec<u8> (binary semantics)
- message_types: add validate_openapi to schema_tests! macro
- clippy: targeted #[allow(dead_code)] on Phase 2 infrastructure
- docs: fix grammar in .openapi-inventory.md

* feat(rust-sdk): add multipart upload support + typed metadata

- client: add request_multipart/post_multipart for file uploads
- session: metadata/filters serde_json::Value → HashMap for type safety
- message: MessageUploadForm already uses Vec<u8> (prior commit)
* feat(rust-sdk): Phase 3 — Page<TRaw,TOut> with lazy pagination

- PageResponse<T> for serde, Page<TRaw,TOut> with Arc<Inner>
- has_next(), next_page(), into_stream() (async_stream)
- paginate_post() helper for POST-based pagination
- 11 pagination tests (wiremock-based, cancel-safe)

* feat(rust-sdk): add Honcho client with workspace operations (F4)

- Honcho struct with bon::Builder, env var resolution, Arc<HonchoInner>
- Environment enum (Local/Production) with defaults
- ensure_workspace via tokio::sync::OnceCell (concurrent-safe, retryable)
- Metadata/config CRUD (get/set)
- peer(id)/session(id) eager POST get-or-create
- Paginated peers/sessions/workspaces with filter support
- search, queue_status, schedule_dream, delete_workspace
- Placeholder Peer/Session structs for F5/F6
- 29 new tests across 6 test files

* feat(rust-sdk): implement Peer wrapper (F5) — all methods

- F5.1: metadata/config CRUD, refresh, update
- F5.2: chat + chat_with_options (non-streaming dialectic)
- F5.3: search (peer-scoped message search)
- F5.4: get/set card (with target scoping)
- F5.5: representation + RepresentationBuilder (validated params)
- F5.6: context (with optional target)
- F5.7: sessions (paginated)
- F5.8: message builder (sync, no API call)
- 29 peer tests (21 core + 8 methods)
- 395 total tests, clippy clean

* feat(rust-sdk): implement Session wrapper (F6) — all methods

- F6.1: metadata/config CRUD, refresh, construction
- F6.2: peer management (PeerSpec enum, add/set/remove/peers)
- F6.3: per-peer configuration (get/set SessionPeerConfig)
- F6.4: add_messages with auto-chunking (>100), messages paginated
- F6.5: delete, clone_session, get_message, update_message
- F6.6: context (SessionContext with summary/peer_card/representation)
- F6.7: to_openai/to_anthropic on SessionContext
- F6.8: summaries
- F6.9: search, representation, queue_status
- 47 new tests (19 core + 9 messages + 14 context + 5 methods)
- 442 total tests, clippy clean, fmt OK

* fix(rust-sdk): address code review findings — HIGH+MEDIUM issues

RwLock poison recovery:
- peer.rs/session.rs: .unwrap() → .unwrap_or_else(|e| e.into_inner())
- prevents cascading panics from poisoned locks

Session Honcho reference:
- SessionInner stores Honcho, peers()/clone_session() reuse it
- fixes auth config loss from creating throwaway clients
- normalize_peers returns Validation error on duplicate IDs

Pagination error propagation:
- next_page() returns Result<Option<Self>> instead of Option<Self>
- fetcher errors now propagate instead of silently becoming None

Error handling:
- error.rs: new Client variant for unmapped 4xx (was incorrectly Server)
- message.rs: #[non_exhaustive] on Message and MessageConfiguration
- client.rs: cap Retry-After to MAX_RETRY_DELAY
- client.rs: remove dead metadata/configuration fields

Routes: URL-encode path segments via url::form_urlencoded
Session types: peer_card uses serde_json::to_string instead of Debug

Tests: 7 new tests (peers_with_filters, sessions_with_filters,
session.representation, session.queue_status, Page::map,
add_messages boundary 100/101). Renamed misleading test.
Total: 451 tests, clippy -D warnings clean.

* fix(rust-sdk): address Gemini review — from_parts, encode, RwLock, dead fields

- peer/session: add from_parts() constructor, from_response delegates to it
- session.peers()/clone: use from_parts instead of recreating Honcho client
- routes.encode(): manual RFC 3986 percent-encoding (spaces→%20 not +)
- peer/session RwLock: unwrap_or_else for poison recovery
- client.Inner: remove unused metadata/configuration fields
- types/session: peer_card uses serde_json::to_string, not Debug fmt
* feat(rust-sdk): phases 7-9 wave 1 — Message, FileSource, SSE parser, Conclusion, HttpClient streaming

F7.1: top-level Message wrapper (Arc<Inner>, Debug/50-char, Display/full)
F7.2: FileSource enum (Bytes/Path) + resolve_to_bytes + mime_guess dep
F8.1: HttpClient::request_streaming (no retry, Accept: text/event-stream)
F8.2: SseParser (incremental UTF-8, per-line JSON, done flag, CRLF/LF/CR)
F9.1: Conclusion wrapper + ConclusionCreateParams with bon::Builder
Types: Message -> MessageResponse rename in types module
386 tests, clippy clean

* feat(rust-sdk): phases 7-9 wave 2 — upload_file, parse_sse_stream, ConclusionScope

F7.3: Session::upload_file with UploadFileBuilder (peer/metadata/config/created_at)
      Message::from_raw for constructing without &Honcho reference
F8.3: parse_sse_stream adapter (async_stream + SseParser, error propagation)
F9.2: ConclusionScope (Arc-backed, observer/observed scoping)
      Route helpers for conclusions API
501 tests, clippy clean

* feat(rust-sdk): phases 7-9 wave 3 — chat_stream, conclusion CRUD, streamed upload

F7.4: FileSource::Stream variant + Session::upload_file_streamed
F8.4: Peer::chat_stream with ChatStreamBuilder (target/session/reasoning)
F9.3: ConclusionScope::list (paginated, filters, reverse)
F9.4: ConclusionScope::query (semantic search, top_k/distance validation)
F9.5: ConclusionScope::delete
F9.6: ConclusionScope::create (batch with 100-chunk auto-injection)
F9.7: ConclusionScope::representation (peer endpoint gotcha, C41)
522 tests, clippy clean

* feat(rust-sdk): phases 7-9 wave 4 — DialecticStream, Peer integration, invariants

F7.5: assert_impl_all for FileSource/UploadFileBuilder
F8.5: DialecticStream adapter (accumulator + final_response + is_complete)
F8.6: SSE audit (zero unwrap in parsing path), Send+'static stream bounds
F9.8: Peer::conclusions() + conclusions_of() wired to ConclusionScope
F9.9: Doc strings, assert_impl_all for Conclusion/ConclusionScope
      examples/conclusions.rs, dead_code cleanup
529 tests, clippy clean, examples compile

* fix(rust-sdk): review fixes — UTF-8 panics, SSE parser, timeout, validation

HIGH:
- Message/Conclusion Debug: char-boundary safe truncation (no byte slicing)
- SSE parser: from_utf8_lossy on invalid bytes (matches Python errors=replace)
- request_streaming: remove per-request timeout (client timeout sufficient)

MEDIUM:
- query() returns Vec<Conclusion> not Vec<ConclusionData>
- representation() omits null optional fields (conditional JSON body)
- Empty filename from Path('/') returns Validation error
- Conclusion create validates non-empty content

LOW:
- ListConclusionsBuilder validates size > 0
- done flag matches Python truthy semantics
- Removed dead fields: PeersPageResponse.total/pages, base_url_hint()

* fix(rust-sdk): cargo doc broken links in upload.rs and conclusion.rs

* perf(rust-sdk): Gemini review — drain buffers, single-pass map, efficient done check
… review fixes (#4)

* feat(rust-sdk): add blocking facade, integration tests, examples, and review fixes

Phase A (quality): OpenAPI path fix, dead_code suppress, SSE cancel-safety
tests, parity fixtures (Python↔Rust), compile assertions (16 targets), Debug
impls, non_exhaustive audit, CI workflow, crate name research, Apache-2.0 license.

Phase 10: Blocking facade (src/blocking/) with tokio OnceLock<Runtime>,
runtime detection guard, Stream→Iterator adapter, full API coverage for
Honcho/Peer/Session/Conclusion.

Phase 11: Integration tests (lifecycle/streaming/upload) with graceful skip,
CI integration job.

Phase 12: Examples (quickstart/streaming/multi_peer/upload/blocking), README,
CHANGELOG, docs.rs metadata, version bump to 0.1.0.

Review fixes: typed struct serialization (json!→serde), error catch-all guard,
SSE done default to false, normalize_peers error propagation, missing docs,
search_with_options, context_with_options builder methods.

* fix(rust-sdk): update install-action syntax for cargo-msrv

* fix(rust-sdk): CI fixes — rustfmt/clippy components, MSRV 1.85, let-else lint

* chore(rust-sdk): finalize post-port cleanup and update MSRV

Remove obsolete Rust SDK porting plan documents, update the Minimum Supported
Rust Version (MSRV) to 1.88 along with the CI toolchain, and apply various
minor code refinements and lint suppressions.

* chore(rust-sdk): Refine formatting in session context test

* chore(rust-sdk): Simplify tests for unit return types
…ts (#5)

* feat(rust-sdk): v0.2.0 — full Python SDK parity, audit fixes, 717 tests

feat(rust-sdk): v0.2.0 — full Python SDK parity, audit fixes, 717 tests
Bring Rust SDK to parity with Python SDK. 43 roadmap tasks completed
across 7 waves, plus post-audit fixes for critical gaps.

Breaking changes:
- Session::context_with_options takes &SessionContextOptions (10 fields)
- Peer::context_with_options added, context_with_target deprecated
- Page::next_page returns Result<Option<Page<T>>>
- Session methods return Message not MessageResponse
- Builder consistency: all use on(String, into) + finish_fn = build
- FinalResponse is a struct, not a raw string
- Error code "client_error" renamed to "api_error"

New features:
- SessionContextOptions: all 10 server params (summary, tokens,
  peer_target, peer_perspective, search_query, limit_to_session,
  search_top_k, search_max_distance, include_most_frequent, max_conclusions)
- PeerContextOptions: all 6 params (target, search_query, search_top_k,
  search_max_distance, include_most_frequent, max_conclusions)
- queue_status: observer_id, sender_id, session_id params
- schedule_dream: session_id, observed_peer params
- PeerCreateOptions, SessionCreateOptions with metadata/configuration
- MessageListOptions, SessionListOptions, MessageSearchOptions builders
- search_with_options on workspace/peer/session
- Typed get/set_configuration + raw variants
- 126 methods documented with doctests
- 28 blocking smoke tests, 6 force_ensure tests
- User-Agent: honcho-rust/<version>
- CI matrix: MSRV 1.88 + stable
- 6 examples, CHANGELOG, MIGRATION guide

Validation errors now use HonchoError::Validation (not Configuration).
7 missing re-exports added to lib.rs.

* fix(rust-sdk): MessageResponse→Message return types, remove junk files

Address Gemini code review feedback:

- Session/peer/client methods now return enriched Message wrapper
  instead of raw MessageResponse (search, add_messages, get_message,
  update_message, messages, search_with_options)
- Remove accidental sdks/rust/sdks/rust/ nested directory
- Remove session.rs.bak backup file
- Update test assertions to use Message getter methods (.id() etc.)

717 tests pass, 0 clippy warnings.
…rrors (#6)

- Upgrade jsonschema 0.18 → 0.46, rstest 0.23 → 0.26
- Update test helper: JSONSchema::compile → validator_for, validate() → iter_errors()
- Add restrictive [lints] table: forbid unsafe, deny unwrap/expect/panic/print in lib
- Allow lints in examples/tests where println/unwrap/expect are appropriate
- All 124 tests pass, zero clippy warnings/errors
…#7)

* fix(rust-sdk): propagate pagination errors instead of silently swallowing them

Page::next_page now returns Result<Option<Self>> (was Option<Self>).
collect_all_pages now returns Result<Vec<T>> (was Vec<T>).
HTTP failures during pagination no longer silently produce partial results.

BREAKING CHANGE: callers handling pagination must now handle Result.

* feat: wire schema parity — T2.1-T2.7

T2.1: Session::representation_builder() with validation
T2.2: Typed PeerConfig + raw escape hatches
T2.3: FinalResponse struct + DialecticStream wrap in send()
T2.4: PeerBuilder/SessionBuilder create-with-metadata
T2.5: SessionMessagesOptions builder
T2.6: Blocking upload_file + upload_file_streamed
T2.7: Wire fixes (filters null, max_conclusions default 25,
      workspaces_with_filters, workspace metadata docs)

* feat(rust-sdk): typed configuration structs (Faza 3 — T3.1-T3.4)

- Add ReasoningConfiguration, SummaryConfiguration, DreamConfiguration,
  PeerCardConfiguration to types/common.rs (T3.2 dedup)
- Add typed SessionConfiguration + WorkspaceConfiguration (T3.1)
- Add SessionConfiguration methods: get_configuration, set_configuration,
  get/set_configuration_raw (session.rs)
- Add WorkspaceConfiguration methods: get_configuration, set_configuration,
  get/set_configuration_raw (client.rs + blocking)
- Fix get_configuration_raw() to bypass typed deser (preserves unknown fields)
- Make SessionContextOptions::validate() public (T3.4 cross-field validation)
- Fix all call sites: session_core.rs, lifecycle.rs, session_methods.rs,
  blocking_smoke.rs, client_operations.rs, peer_core.rs, blocking_upload_file.rs
- Fix pre-existing test issues: schedule_dream mock session_id null,
  peer_chat mock stream:false

* feat(rust-sdk): ergonomics & polish (Faza 4 — T4.1-T4.8)

- T4.1: Add Peer::context_builder() with full options, deprecate old context methods
- T4.2: Add timeout, max_retries, default_headers, default_query to HonchoParams
- T4.3: Dead code cleanup — remove Metadata alias, card(), from_response ctors,
        http fields from inner types, make paginate_post pub(crate)
- T4.4: Fix multipart Content-Type header duplication
- T4.5: Handle empty HTTP response body gracefully (avoid decode error)
- T4.6: Add naming aliases — has_next_page(), get_next_page(), session_id()
- T4.7: Export DialecticStreamDelta and DialecticStreamChunk types
- T4.8: IntoAssistantRef trait — to_openai/to_anthropic accepts &Peer

* feat(rust-sdk): typed PeerConfig with deny_unknown_fields, JSON macro cleanup (T2.2, T3.3)

* fix(rust-sdk): review findings — error propagation, migration docs, validation, dead code

* fix(rust-sdk): paginate_post visibility + deprecated test callers

* fix(rust-sdk): multipart header matcher, doctest non_exhaustive, empty response mocks
## Summary 

Align the Rust SDK’s client, session, peer, and transport behavior with the Python reference, tightening validation, expanding request options, and adjusting retry and error handling semantics.

New Features:
- Allow specifying metadata and configuration when creating peers and sessions via async and blocking client APIs.
- Expose a created_at accessor on Session to surface server-provided creation timestamps.
- Add optional filters and limit parameters to workspace search requests and client search APIs.
- Introduce messages_with_options on Session and wire up messages() to return mapped paginated results with default pagination.
- Add a refresh method on Honcho and its blocking wrapper to reload workspace metadata and configuration.
- Expose sessions_with_options on blocking::Peer to list sessions with filters and pagination.
- Return fully wrapped Conclusion objects from conclusion query builders in async and blocking APIs.

Bug Fixes:
- Switch route builders from debug_assert! to assert! to enforce non-empty identifiers in all builds.
- Ensure HTTP transport retries backoff before incrementing attempts and broaden retryable transport errors to include request-level failures, while removing the maximum retry delay cap.
- Map 3xx HTTP responses to client errors instead of decode errors and provide clearer messages for unexpected statuses.
- Validate that SessionContextOptions.search_query is only used when a peer_target is provided.
- Reject empty or whitespace-only peer message content and enforce a maximum message length in MessageBuilder.
- Align peer_card serialization in SessionContext with Python’s list string format for OpenAI-style messages.
- Send conclusion batch creates in a single request and adapt tests to expect that behavior.

Enhancements:
- Preserve pagination mapping when listing session messages by returning a typed Page that lazily converts raw responses to Message objects.
- Update examples, blocking APIs, and tests to use the extended peer, session, and search method signatures and to rely on the new validation behavior.
- Adjust conclusion query examples and tests to use Conclusion accessors rather than raw fields.

Tests:
- Update and extend client, peer, session, conclusion, blocking, streaming, and integration tests to cover new parameters, stricter validation, pagination behavior, and revised error semantics.
Remove the redundant rust.yml workflow that duplicated rust-sdk.yml.
Restructure rust-sdk.yml: split version-independent checks (fmt, doc)
into a single lint job, set fail-fast: false so MSRV failures don't
mask stable results, add concurrency cancellation, and cache the msrv job.
…esilience (#9)

## Summary

Improve Rust SDK API correctness, response deserialization robustness, and integration test resilience while updating tooling configuration.

Bug Fixes:
- Use the correct HTTP PUT method for peer configuration updates instead of PATCH.
- Handle null HTTP response bodies by attempting to deserialize them into the expected response type.

Enhancements:
- Relax peer configuration deserialization to ignore unknown fields for better forward compatibility.
- Make integration tests more resilient by tolerating failures in clone and workspace cleanup operations and simplifying streaming test prompts.

Build:
- Update Rust formatting configuration to target the 2024 edition and add a Clippy configuration with the minimum supported Rust version.
- Add a Rust SDK-specific .gitignore file.
…stness

## Summary

Implement truly streaming file uploads in the blocking API, enhance pagination logic, add ID validation, and optimize memory usage for large collections.

New Features:
- Implement true streaming for `blocking::session::upload_file_streamed` to avoid buffering entire files in memory.

Enhancements:
- Limit initial vector capacity when collecting all pages to prevent excessive memory allocation.
- Introduce batching for `Conclusion` creation, sending requests in chunks of 100 for large conclusion sets.

Bug Fixes:
- Add validation to prevent creating workspaces, peers, or sessions with empty string identifiers.
- Improve pagination robustness to correctly handle dynamic `total_pages` and prevent infinite loops in `Page::stream_all_pages`.
- Prevent unnecessary HTTP requests when creating empty conclusion batches.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 15, 2026

Important

Review skipped

Too many files!

This PR contains 212 files, which is 62 over the limit of 150.

To get a review, narrow the scope:
• coderabbit review --type committed # exclude uncommitted changes
• coderabbit review --dir # limit to a subdirectory
• coderabbit review --base # compare against a closer base

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 90f96335-be83-48d4-b7c6-58d16cdd79cd

📥 Commits

Reviewing files that changed from the base of the PR and between b0f0295 and cfd818b.

⛔ Files ignored due to path filters (1)
  • sdks/rust/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (212)
  • .github/workflows/rust-sdk.yml
  • .gitignore
  • sdks/rust/.gitignore
  • sdks/rust/.openapi-inventory.md
  • sdks/rust/CHANGELOG.md
  • sdks/rust/Cargo.toml
  • sdks/rust/LICENSE
  • sdks/rust/MIGRATION.md
  • sdks/rust/README.md
  • sdks/rust/clippy.toml
  • sdks/rust/examples/blocking.rs
  • sdks/rust/examples/blocking_upload_file.rs
  • sdks/rust/examples/conclusions.rs
  • sdks/rust/examples/context_with_options.rs
  • sdks/rust/examples/messages_with_options.rs
  • sdks/rust/examples/multi_peer.rs
  • sdks/rust/examples/queue_status.rs
  • sdks/rust/examples/quickstart.rs
  • sdks/rust/examples/search_with_options.rs
  • sdks/rust/examples/streaming.rs
  • sdks/rust/examples/typed_configuration.rs
  • sdks/rust/examples/upload.rs
  • sdks/rust/rustfmt.toml
  • sdks/rust/src/blocking/client.rs
  • sdks/rust/src/blocking/conclusion.rs
  • sdks/rust/src/blocking/iter.rs
  • sdks/rust/src/blocking/mod.rs
  • sdks/rust/src/blocking/peer.rs
  • sdks/rust/src/blocking/runtime.rs
  • sdks/rust/src/blocking/session.rs
  • sdks/rust/src/client.rs
  • sdks/rust/src/conclusion.rs
  • sdks/rust/src/dialectic_stream.rs
  • sdks/rust/src/error.rs
  • sdks/rust/src/http/client.rs
  • sdks/rust/src/http/decode.rs
  • sdks/rust/src/http/mod.rs
  • sdks/rust/src/http/routes.rs
  • sdks/rust/src/http/sse.rs
  • sdks/rust/src/lib.rs
  • sdks/rust/src/message.rs
  • sdks/rust/src/peer.rs
  • sdks/rust/src/session.rs
  • sdks/rust/src/types/common.rs
  • sdks/rust/src/types/conclusion.rs
  • sdks/rust/src/types/dialectic.rs
  • sdks/rust/src/types/dream.rs
  • sdks/rust/src/types/message.rs
  • sdks/rust/src/types/mod.rs
  • sdks/rust/src/types/pagination.rs
  • sdks/rust/src/types/peer.rs
  • sdks/rust/src/types/session.rs
  • sdks/rust/src/types/validation.rs
  • sdks/rust/src/types/workspace.rs
  • sdks/rust/src/upload.rs
  • sdks/rust/tests/blocking_runtime_guard.rs
  • sdks/rust/tests/blocking_smoke.rs
  • sdks/rust/tests/client_builder.rs
  • sdks/rust/tests/client_ensure_workspace.rs
  • sdks/rust/tests/client_metadata.rs
  • sdks/rust/tests/client_operations.rs
  • sdks/rust/tests/client_paginated.rs
  • sdks/rust/tests/client_peer_session.rs
  • sdks/rust/tests/common/mod.rs
  • sdks/rust/tests/compile_assertions.rs
  • sdks/rust/tests/conclusion_types.rs
  • sdks/rust/tests/decode_error.rs
  • sdks/rust/tests/dialectic_dream_types.rs
  • sdks/rust/tests/error_mapping.rs
  • sdks/rust/tests/fixtures/Conclusion/max.json
  • sdks/rust/tests/fixtures/Conclusion/min.json
  • sdks/rust/tests/fixtures/ConclusionBatchCreate/max.json
  • sdks/rust/tests/fixtures/ConclusionBatchCreate/min.json
  • sdks/rust/tests/fixtures/ConclusionCreate/max.json
  • sdks/rust/tests/fixtures/ConclusionCreate/min.json
  • sdks/rust/tests/fixtures/ConclusionGet/max.json
  • sdks/rust/tests/fixtures/ConclusionGet/min.json
  • sdks/rust/tests/fixtures/ConclusionQuery/max.json
  • sdks/rust/tests/fixtures/ConclusionQuery/min.json
  • sdks/rust/tests/fixtures/DialecticOptions/max.json
  • sdks/rust/tests/fixtures/DialecticOptions/min.json
  • sdks/rust/tests/fixtures/DreamConfiguration/max.json
  • sdks/rust/tests/fixtures/DreamConfiguration/min.json
  • sdks/rust/tests/fixtures/DreamType/max.json
  • sdks/rust/tests/fixtures/DreamType/min.json
  • sdks/rust/tests/fixtures/HTTPValidationError/max.json
  • sdks/rust/tests/fixtures/HTTPValidationError/min.json
  • sdks/rust/tests/fixtures/Message/max.json
  • sdks/rust/tests/fixtures/Message/min.json
  • sdks/rust/tests/fixtures/MessageBatchCreate/max.json
  • sdks/rust/tests/fixtures/MessageBatchCreate/min.json
  • sdks/rust/tests/fixtures/MessageConfiguration/max.json
  • sdks/rust/tests/fixtures/MessageConfiguration/min.json
  • sdks/rust/tests/fixtures/MessageCreate/max.json
  • sdks/rust/tests/fixtures/MessageCreate/min.json
  • sdks/rust/tests/fixtures/MessageGet/max.json
  • sdks/rust/tests/fixtures/MessageGet/min.json
  • sdks/rust/tests/fixtures/MessageSearchOptions/max.json
  • sdks/rust/tests/fixtures/MessageSearchOptions/min.json
  • sdks/rust/tests/fixtures/MessageUpdate/max.json
  • sdks/rust/tests/fixtures/MessageUpdate/min.json
  • sdks/rust/tests/fixtures/MessageUploadForm/max.json
  • sdks/rust/tests/fixtures/MessageUploadForm/min.json
  • sdks/rust/tests/fixtures/Page_Conclusion_/max.json
  • sdks/rust/tests/fixtures/Page_Conclusion_/min.json
  • sdks/rust/tests/fixtures/Page_Message/max.json
  • sdks/rust/tests/fixtures/Page_Message/min.json
  • sdks/rust/tests/fixtures/Page_Peer_/max.json
  • sdks/rust/tests/fixtures/Page_Peer_/min.json
  • sdks/rust/tests/fixtures/Page_Session_/max.json
  • sdks/rust/tests/fixtures/Page_Session_/min.json
  • sdks/rust/tests/fixtures/Page_Workspace_/max.json
  • sdks/rust/tests/fixtures/Page_Workspace_/min.json
  • sdks/rust/tests/fixtures/Peer/max.json
  • sdks/rust/tests/fixtures/Peer/min.json
  • sdks/rust/tests/fixtures/PeerCardConfiguration/max.json
  • sdks/rust/tests/fixtures/PeerCardConfiguration/min.json
  • sdks/rust/tests/fixtures/PeerCardResponse/max.json
  • sdks/rust/tests/fixtures/PeerCardResponse/min.json
  • sdks/rust/tests/fixtures/PeerCardSet/max.json
  • sdks/rust/tests/fixtures/PeerCardSet/min.json
  • sdks/rust/tests/fixtures/PeerContext/max.json
  • sdks/rust/tests/fixtures/PeerContext/min.json
  • sdks/rust/tests/fixtures/PeerContextOptions/max.json
  • sdks/rust/tests/fixtures/PeerContextOptions/min.json
  • sdks/rust/tests/fixtures/PeerCreate/max.json
  • sdks/rust/tests/fixtures/PeerCreate/min.json
  • sdks/rust/tests/fixtures/PeerGet/max.json
  • sdks/rust/tests/fixtures/PeerGet/min.json
  • sdks/rust/tests/fixtures/PeerRepresentationGet/max.json
  • sdks/rust/tests/fixtures/PeerRepresentationGet/min.json
  • sdks/rust/tests/fixtures/PeerUpdate/max.json
  • sdks/rust/tests/fixtures/PeerUpdate/min.json
  • sdks/rust/tests/fixtures/QueueStatus/max.json
  • sdks/rust/tests/fixtures/QueueStatus/min.json
  • sdks/rust/tests/fixtures/ReasoningConfiguration/max.json
  • sdks/rust/tests/fixtures/ReasoningConfiguration/min.json
  • sdks/rust/tests/fixtures/ReasoningLevel/max.json
  • sdks/rust/tests/fixtures/ReasoningLevel/min.json
  • sdks/rust/tests/fixtures/RepresentationResponse/max.json
  • sdks/rust/tests/fixtures/RepresentationResponse/min.json
  • sdks/rust/tests/fixtures/ScheduleDreamRequest/max.json
  • sdks/rust/tests/fixtures/ScheduleDreamRequest/min.json
  • sdks/rust/tests/fixtures/Session/max.json
  • sdks/rust/tests/fixtures/Session/min.json
  • sdks/rust/tests/fixtures/SessionConfiguration/max.json
  • sdks/rust/tests/fixtures/SessionConfiguration/min.json
  • sdks/rust/tests/fixtures/SessionContext/max.json
  • sdks/rust/tests/fixtures/SessionContext/min.json
  • sdks/rust/tests/fixtures/SessionContextOptions/max.json
  • sdks/rust/tests/fixtures/SessionContextOptions/min.json
  • sdks/rust/tests/fixtures/SessionCreate/max.json
  • sdks/rust/tests/fixtures/SessionCreate/min.json
  • sdks/rust/tests/fixtures/SessionGet/max.json
  • sdks/rust/tests/fixtures/SessionGet/min.json
  • sdks/rust/tests/fixtures/SessionPeerConfig/max.json
  • sdks/rust/tests/fixtures/SessionPeerConfig/min.json
  • sdks/rust/tests/fixtures/SessionQueueStatus/max.json
  • sdks/rust/tests/fixtures/SessionQueueStatus/min.json
  • sdks/rust/tests/fixtures/SessionSummaries/max.json
  • sdks/rust/tests/fixtures/SessionSummaries/min.json
  • sdks/rust/tests/fixtures/SessionUpdate/max.json
  • sdks/rust/tests/fixtures/SessionUpdate/min.json
  • sdks/rust/tests/fixtures/Summary/max.json
  • sdks/rust/tests/fixtures/Summary/min.json
  • sdks/rust/tests/fixtures/SummaryConfiguration/max.json
  • sdks/rust/tests/fixtures/SummaryConfiguration/min.json
  • sdks/rust/tests/fixtures/ValidationError/max.json
  • sdks/rust/tests/fixtures/ValidationError/min.json
  • sdks/rust/tests/fixtures/Workspace/max.json
  • sdks/rust/tests/fixtures/Workspace/min.json
  • sdks/rust/tests/fixtures/WorkspaceConfiguration/max.json
  • sdks/rust/tests/fixtures/WorkspaceConfiguration/min.json
  • sdks/rust/tests/fixtures/WorkspaceCreate/max.json
  • sdks/rust/tests/fixtures/WorkspaceCreate/min.json
  • sdks/rust/tests/fixtures/WorkspaceGet/max.json
  • sdks/rust/tests/fixtures/WorkspaceGet/min.json
  • sdks/rust/tests/fixtures/WorkspaceUpdate/max.json
  • sdks/rust/tests/fixtures/WorkspaceUpdate/min.json
  • sdks/rust/tests/fixtures/parity/_generate.py
  • sdks/rust/tests/fixtures/parity/multi_peer/anthropic.json
  • sdks/rust/tests/fixtures/parity/multi_peer/openai.json
  • sdks/rust/tests/fixtures/parity/multi_peer/session_context.json
  • sdks/rust/tests/fixtures/parity/small/anthropic.json
  • sdks/rust/tests/fixtures/parity/small/openai.json
  • sdks/rust/tests/fixtures/parity/small/session_context.json
  • sdks/rust/tests/fixtures/parity/with_summary/anthropic.json
  • sdks/rust/tests/fixtures/parity/with_summary/openai.json
  • sdks/rust/tests/fixtures/parity/with_summary/session_context.json
  • sdks/rust/tests/force_ensure.rs
  • sdks/rust/tests/integration/common.rs
  • sdks/rust/tests/integration/lifecycle.rs
  • sdks/rust/tests/integration/main.rs
  • sdks/rust/tests/integration/streaming.rs
  • sdks/rust/tests/integration/upload.rs
  • sdks/rust/tests/message_types.rs
  • sdks/rust/tests/pagination.rs
  • sdks/rust/tests/peer_core.rs
  • sdks/rust/tests/peer_methods.rs
  • sdks/rust/tests/peer_sessions_list.rs
  • sdks/rust/tests/peer_types.rs
  • sdks/rust/tests/session_context.rs
  • sdks/rust/tests/session_context_parity.rs
  • sdks/rust/tests/session_core.rs
  • sdks/rust/tests/session_messages.rs
  • sdks/rust/tests/session_methods.rs
  • sdks/rust/tests/session_types.rs
  • sdks/rust/tests/smoke.rs
  • sdks/rust/tests/sse_cancel.rs
  • sdks/rust/tests/validation_types.rs
  • sdks/rust/tests/wire_format_peers.rs
  • sdks/rust/tests/workspace_types.rs

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

## Summary

This update focuses on improving the SDK's resilience and API correctness.

New Features:
- **Automatic Retries for Multipart Uploads**: Implemented a retry mechanism for all multipart requests, including file uploads. Requests now retry on transient network errors (timeouts, connection issues) and retryable HTTP status codes (429, 5xx), significantly improving robustness.
  - To facilitate retries, `reqwest::multipart::Form` instances are now generated via a factory function, allowing recreation for each attempt.
  - `FileSource::Stream` contents are buffered in memory to ensure replayability during retries.
  - `FileSource::Path` files are re-opened for each retry.

Bug Fixes:
- **Correct Workspace Data Retrieval**: Changed the `get_metadata` and `get_configuration` methods to use `GET /v3/workspaces/{id}` instead of `POST /v3/workspaces`. This aligns with RESTful principles and correctly handles requests for specific workspace IDs, including proper error responses for non-existent workspaces.

Enhancements:
- **Improved Blocking Stream Error Handling**: Introduced `ErrorAwareReader` to propagate `std::io::Error` from blocking reads to the asynchronous stream in `blocking::session::upload_file_streamed`, ensuring comprehensive error reporting.
- **Add `HONCHO_API_URL` Environment Variable**: Provided an additional environment variable fallback (`HONCHO_API_URL`) for specifying the API base URL, complementing `HONCHO_URL`.
- **Refactor `workspaces` Pagination**: Consolidated pagination logic in `blocking::client::workspaces` into a shared `collect_all_pages` helper for cleaner code.
* fix: audit fixes across 31 files — bugs, safety, API improvements

Bug fixes:
- message.rs: Debug truncation byte-vs-char mismatch (Cow zero-alloc)
- error.rs: parse_retry_after past-date clamp to ZERO, accessors (status_code/retry_after/message)
- types/session.rs: is_empty/len count peer_representation+peer_card
- http/client.rs: request_streaming is_request() check, delay_for_attempt 60s cap
Safety:
- http/routes.rs: 28 route fns assert! panics replaced with Result + validate_not_empty
- blocking/session.rs: spawn_blocking JoinHandle awaited, panic propagated
- client.rs: ensure_workspace 409 Conflict prevents OnceCell poison
- blocking/iter.rs: collect_all_pages page-count guard (max 1000)
API improvements:
- types/message.rs: bon::Builder on MessageCreate/MessageUpdate, non_exhaustive
- types/conclusion.rs: bon::Builder on 4 conclusion request DTOs
- types/message.rs: #[builder(on(String, into))] for ergonomic string params
- blocking/*: Debug impls on Honcho/Peer/Session/ConclusionScope/builders
- blocking/conclusion.rs: #[must_use] on 7 builder setters
Cleanup:
- dialectic_stream.rs: dead types pub(crate), FinalResponse pre-alloc
- http/decode.rs: redundant match to map_err
- lib.rs: broken doc link, module doc comments, rustdoc warnings
- types/dream.rs: removed unused re-exports
- upload.rs: doc fix streaming lie
- http/client.rs: HttpClientParams pub to pub(crate)
69 routes:: call sites updated with ? propagation across
client.rs/peer.rs/session.rs/conclusion.rs/http/client.rs

* fix: address code review feedback (5 issues)

- message.rs: use char_indices().nth(50) directly instead of
  chars().count() full traversal — stops at 51st char
- blocking/iter.rs: extract MAX_COLLECT_PAGES constant, improve
  error message with actual page count
- blocking/session.rs: preserve original upload error when reader
  task panics — only escalate join error if upload succeeded
- http/routes.rs: encode() returns String not Result — write! to
  String is infallible, removed dead error path and 32 call-site ?
- error.rs: message() returns 'transport error'/'I/O error' instead
  of empty string for Transport/Io variants

* "fix: add missing GET mocks in blocking_smoke tests
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant