Skip to main content

Crate va_ai_api_bridge

Crate va_ai_api_bridge 

Source
Expand description

§va-ai-api-bridge (va-aab)

va-ai-api-bridge provides Rust SDK primitives for translating AI API request, response, and stream shapes. It is designed for hosts that need to expose one agent-facing API while sending requests to providers that use another API shape.

The crate is intentionally not an HTTP gateway. It does not perform networking, store credentials, own model routing, retry upstreams, or persist chat history. It focuses on the translation layer: wire payloads, protocol-neutral IR, streaming events, and provider-specific package transforms.

§Install

cargo add va-ai-api-bridge serde_json

Or add it manually:

[dependencies]
va-ai-api-bridge = "0.1.6"
serde_json = "1"

The package name uses hyphens on crates.io, while Rust imports use underscores: va_ai_api_bridge.

§Quick Example

Decode an OpenAI Chat Completions request into the universal IR, then encode it as an Anthropic Messages request:

use serde_json::json;
use va_ai_api_bridge::{AnthropicMessagesTranslator, OpenAiChatTranslator, WireTranslator};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let source = OpenAiChatTranslator;
    let target = AnthropicMessagesTranslator;

    let universal = source.decode_request(json!({
        "model": "gpt-4.1",
        "messages": [
            { "role": "system", "content": "You are concise." },
            { "role": "user", "content": "Say hello." }
        ]
    }))?;

    let anthropic_body = target.encode_request(&universal)?;
    println!("{}", serde_json::to_string_pretty(&anthropic_body)?);

    Ok(())
}

§Documentation

Start with the documentation index.

§Server Tool Capability Support

Recent Claude Desktop and Claude Code bridge testing showed that tool translation needs a more explicit capability model. Anthropic-style server tools such as web_search_20250305 are not equivalent to client-executed function tools: some Anthropic-compatible providers execute them server-side, some reject or ignore them, and OpenAI Chat-style function tools only ask the model to emit arguments for the host to run.

The IR now keeps known server-tool declarations in UniversalRequest.server_tools instead of flattening them into ordinary function tools. The host remains responsible for deciding whether to preserve native server tools, drop them, or inject host-executed fallback function tools.

Follow-up work:

  • Track hosted/server tool support separately from function-calling support in host capability metadata.
  • Add route-level policy for unsupported server tools: preserve and route to a compatible API, drop with a clear fallback, or replace with a host-executed tool only when the host can actually run it.
  • Add request/response fixtures for Claude WebSearch sidecar requests, including the Anthropic web_search_20250305 shape and the current OpenAI Chat downgrade failure mode.

§Boundary

agent wire request
  -> source WireTranslator
  -> UniversalRequest
  -> host capability policy
  -> target WireTranslator
  -> ProviderBridgeAdapter request transform
  -> upstream wire request

upstream wire response / stream chunk
  -> target WireTranslator
  -> UniversalEvent
  -> ProviderBridgeAdapter event transform
  -> source WireTranslator
  -> agent wire response / stream event

The host application remains responsible for:

  • HTTP routes and upstream requests
  • authorization headers and profile credentials
  • model selection and capability policy
  • chat history and launch/session context
  • SSE framing and transport lifecycle
  • plugin loading and sandboxing

The SDK provides:

  • protocol-neutral request and response types
  • protocol-neutral stream events
  • wire translators for supported API families
  • provider adapters for package-shape quirks
  • provider catalog schema types a host can serialize or extend

§Crate Layout

  • protocol: supported wire protocol identifiers
  • schema: provider catalog types and light serde shells for supported wire payloads
  • universal: protocol-neutral request, content, tool, reasoning, and usage types
  • stream: protocol-neutral streaming event types and translator state
  • translator: traits and implementations for wire protocol translation
  • adapter: generic adapter traits and bridge context structs
  • providers: built-in provider adapters for common provider quirks

§Built-in Translators

  • OpenAiChatTranslator: /v1/chat/completions
  • OpenAiResponsesTranslator: /v1/responses
  • AnthropicMessagesTranslator: /v1/messages
  • GeminiGenerateContentTranslator: /{version}/models/{model}:generateContent

§Examples

Runnable examples live under examples/:

  • cargo run --example translate_request
  • cargo run --example provider_adapter
  • cargo run --example media_policy
  • cargo run --example media_policy_typed
  • cargo run --example stream_events

Re-exports§

pub use adapter::AdapterStreamState;
pub use adapter::AdapterStreamStep;
pub use adapter::BridgeContext;
pub use adapter::BridgeHistory;
pub use adapter::ProviderAdapter;
pub use error::ApiBridgeError;
pub use error::Result;
pub use media::sanitize_unsupported_media;
pub use media::sanitize_unsupported_media_from_json;
pub use media::MediaSanitization;
pub use protocol::WireProtocol;
pub use providers::DashScopeBridgeAdapter;
pub use providers::DeepSeekBridgeAdapter;
pub use providers::DeepSeekBridgeSettings;
pub use providers::KimiBridgeAdapter;
pub use providers::MimoBridgeAdapter;
pub use providers::MiniMaxBridgeAdapter;
pub use providers::ProviderBridgeAdapter;
pub use providers::ProviderBridgeAdapterConfig;
pub use providers::ProviderRequestSource;
pub use providers::XaiBridgeAdapter;
pub use providers::ZaiBridgeAdapter;
pub use schema::ModelCapabilities;
pub use schema::ProviderCatalog;
pub use schema::ProviderDefaults;
pub use schema::ProviderModel;
pub use schema::ProviderProtocol;
pub use schema::ProviderSetting;
pub use schema::ResolvedModelSpec;
pub use schema::SettingKind;
pub use schema::SettingOption;
pub use schema::PROVIDER_CATALOG_SCHEMA_VERSION;
pub use stream::DecodeState;
pub use stream::EncodeState;
pub use stream::UniversalEvent;
pub use translator::translator_for_protocol;
pub use translator::AnthropicMessagesTranslator;
pub use translator::GeminiGenerateContentTranslator;
pub use translator::OpenAiChatTranslator;
pub use translator::OpenAiResponsesTranslator;
pub use translator::WireEvent;
pub use translator::WireTranslator;
pub use translator::GEMINI_SKIP_THOUGHT_SIGNATURE_VALIDATOR;
pub use universal::ContentBlock;
pub use universal::Extensions;
pub use universal::FinishReason;
pub use universal::GenerationConfig;
pub use universal::ReasoningConfig;
pub use universal::Role;
pub use universal::ServerToolDeclaration;
pub use universal::ServerToolKind;
pub use universal::SourcePayload;
pub use universal::ToolChoice;
pub use universal::UniversalItem;
pub use universal::UniversalRequest;
pub use universal::UniversalResponse;
pub use universal::UniversalTool;
pub use universal::Usage;

Modules§

adapter
error
media
protocol
providers
schema
stream
translator
universal