oxicode_ai/lib.rs
1#![allow(unused_doc_comments)]
2#![warn(missing_docs)]
3// Relax test-idiom lints under `cfg(test)` so `cargo clippy --all-targets`
4// stays clean without weakening the shipped library:
5// - `clippy::unwrap_used` — `unwrap()`/`unwrap_err()` are idiomatic in tests.
6// - `clippy::expect_used` — `expect("reason")` is idiomatic in tests.
7// - `clippy::panic` — `panic!("Expected X")` match-arm assertions in tests.
8// - `clippy::field_reassign_with_default` — the `let mut x = X::default();
9// x.f = ..;` test-setup pattern.
10// Shipped (non-test) code DENIES all three panic-family lints (see below).
11#![cfg_attr(
12 not(test),
13 deny(clippy::expect_used, clippy::panic, clippy::unwrap_used)
14)]
15#![cfg_attr(
16 test,
17 allow(
18 clippy::unwrap_used,
19 clippy::field_reassign_with_default,
20 clippy::expect_used,
21 clippy::panic,
22 )
23)]
24
25//! oxicode-ai: Unified LLM API for oxicode
26//!
27//! This crate provides a unified interface for interacting with multiple LLM providers.
28//! It handles streaming, tool calling, context management, and cross-provider handoffs.
29
30// Stability tier attribute macros (renamed import — see oxicode-sdk for rationale).
31#[allow(unused_imports)]
32use oxicode_api_stability::{
33 internal as oxicode_internal, stable as oxicode_stable, unstable as oxicode_unstable,
34};
35// Catalog moved to the `oxicode-catalog` crate (omp aligns `pi-catalog` as a
36// separate package). Re-exported here for backward compatibility during the
37// migration; new code should depend on `oxicode-catalog` directly.
38#[oxicode_stable(since = "0.63.0")]
39pub use oxicode_catalog::catalog;
40pub mod compaction;
41pub mod compaction_seam;
42mod context;
43/// Owned (in-band) tool-calling dialects — tool calls as text for models
44/// without native tool support (omp `pi-ai/dialect` port).
45pub mod dialect;
46pub mod env_api_keys;
47mod error;
48mod high_level;
49mod messages;
50pub mod oauth;
51pub mod oxi_home;
52/// Product home-directory resolution (`OXICODE_HOME` / unified Oxi home).
53// `product_env` moved to oxicode-catalog (it owns catalog cache/override dirs);
54// re-exported here so `oxicode_ai::product_env` and `oxicode_sdk::ports::fs::path`
55// (which delegates here) keep working. The unified home layout lives in
56// `oxi_home` (also owned by oxicode-catalog, re-exported above).
57pub use oxicode_catalog::product_env;
58pub mod provider_registry;
59mod providers;
60
61#[allow(missing_docs)]
62pub mod register_builtins {
63 pub use crate::providers::register_builtins::*;
64}
65/// Circuit-breaker behavior trait + SDK reference implementation.
66///
67/// See [`crate::circuit_breaker::CircuitBreaker`] and
68/// [`crate::circuit_breaker::DefaultCircuitBreaker`].
69pub mod circuit_breaker;
70pub mod router;
71pub mod secret;
72mod tools;
73mod transform;
74pub mod types;
75pub mod utils;
76
77/// Standard imports for oxicode-ai usage.
78pub mod prelude {
79 pub use crate::compaction::generate_branch_summary;
80 pub use crate::compaction::{
81 CompactedContext, CompactionManager, CompactionStrategy, Compactor, LlmCompactor,
82 };
83 pub use crate::context::Context;
84 pub use crate::error::{Error, Result};
85 pub use crate::messages::*;
86 pub use crate::providers::{Provider, ProviderEvent, StreamOptions, StreamResult};
87 pub use crate::tools::{Tool, ToolChoice, validate_args};
88 pub use crate::types::*;
89}
90
91// Re-export main types
92
93/// Provider-specific error type for LLM operations.
94#[oxicode_stable(since = "0.63.0")]
95pub use crate::error::ProviderError;
96
97/// Structured HTTP error detail (status/body/provider/request-id) carried by
98/// [`ProviderError::HttpError`]. Re-exported so downstream crates (oxicode-agent,
99/// oxicode-cli) can construct/inspect structured errors.
100pub use crate::error::HttpErrorDetail;
101
102/// Shared conversation context.
103#[oxicode_stable(since = "0.63.0")]
104pub use context::Context;
105
106/// Result type alias for oxicode-ai operations.
107pub use error::{Error, Result};
108
109/// Message types for constructing conversations.
110#[oxicode_stable(since = "0.63.0")]
111pub use messages::*;
112
113/// Cache retention control for provider requests.
114#[oxicode_stable(since = "0.63.0")]
115pub use providers::CacheRetention;
116
117/// Provider trait, streaming options, and provider registry.
118#[oxicode_stable(since = "0.63.0")]
119pub use providers::{
120 Provider, ProviderEvent, ProviderOptions, ProviderRegistry, StreamOptions, StreamResult,
121 custom_provider_names, get_provider, get_provider_arc, register_provider, unregister_provider,
122};
123
124/// Built-in provider helpers (re-exported from providers).
125pub use providers::register_builtins::{
126 create_builtin_provider, create_builtin_provider_with_options, get_all_provider_names,
127 get_builtin_provider, get_provider_env_key, get_provider_env_keys, is_builtin_provider,
128};
129
130/// OpenAI-compatible provider implementation.
131pub use providers::OpenAiProvider;
132
133/// Anthropic provider implementation.
134pub use providers::AnthropicProvider;
135/// Azure OpenAI provider implementation.
136pub use providers::AzureProvider;
137
138/// Model fetching utilities (async and blocking).
139pub use providers::model_fetch::{fetch_models_async, fetch_models_blocking};
140
141/// OpenAI Responses API provider.
142pub use providers::OpenAiResponsesProvider;
143
144/// AWS Bedrock provider implementation.
145pub use providers::BedrockProvider;
146/// Google Gemini CLI transport — typed unsupported-provider error path.
147/// `Api::GoogleGeminiCli` dispatches here; `stream()` returns
148/// `ProviderError::NotImplemented` because no dedicated CLI transport
149/// exists in-tree (upstream collapses `google-gemini-cli → google-generative-ai`).
150pub use providers::GeminiCliProvider;
151/// Google Generative AI (Gemini) provider implementation.
152pub use providers::GoogleProvider;
153/// Ollama (local NDJSON server) provider implementation.
154pub use providers::OllamaProvider;
155/// Google Vertex AI provider implementation.
156pub use providers::VertexProvider;
157
158/// Provider-specific message normalization (empty content filtering, tool ID
159/// scrubbing, reasoning injection, tool-use ordering fix).
160pub use providers::normalize_messages;
161
162/// Tool definition and argument validation.
163#[oxicode_stable(since = "0.63.0")]
164pub use tools::{
165 ProgressCallback, Tool, ToolChoice, ToolValidationError, progress_callback, validate_args,
166};
167
168pub use compaction::generate_branch_summary;
169/// Core type definitions (tokens, cost, etc.).
170#[oxicode_stable(since = "0.63.0")]
171pub use types::*;
172
173// High-level API
174
175/// Token estimation and context usage helpers.
176pub use high_level::tokens::{context_usage, estimate, estimate_words};
177
178/// High-level completion and token estimation.
179pub use high_level::{complete, estimate_tokens};
180
181// Context compaction
182
183/// Compaction strategies and managers for long conversations.
184pub use compaction::{
185 CompactedContext, CompactionManager, CompactionStrategy, Compactor, ContextTransformer,
186 LlmCompactor, NoopContextTransformer,
187};
188
189// Cross-provider message transformation
190
191/// Message transformation between provider formats.
192pub use transform::{
193 TransformOptions, anthropic_to_google, anthropic_to_openai, google_to_openai,
194 normalize_tool_call_id, openai_to_anthropic, transform_messages, transform_messages_for_model,
195};
196
197// Model registry (runtime mutable registry)
198mod model_registry;
199
200/// Runtime model registry for dynamically registered models.
201///
202/// Unlike the static `model_db`, this supports adding/removing models at runtime.
203pub use model_registry::{
204 ModelRegistry, dynamic_models, get_model, get_models, get_providers, lookup_model,
205 register_model, unregister_model,
206};
207
208// Static model database (comprehensive)
209pub mod model_db;
210
211/// Static database of known models with cost and modality info.
212///
213/// Provides comprehensive model listings, filtering, and search capabilities.
214pub use model_db::{
215 ModelEntry, get_all_models, get_cheapest_models, get_model_entry, get_provider_models,
216 get_reasoning_models, get_vision_models, model_count, search_models,
217};
218
219// Model roles — named model assignments (ported from omp)
220
221/// Named model roles with `pi/<role>` alias resolution.
222pub mod roles;
223
224/// Re-exports for the roles module.
225pub use roles::{
226 ModelRole, RoleColor, RoleInfo, RoleRegistry, builtin_role_info, builtin_visible_ids,
227};
228
229// Role switching — signal-based role decision on top of the roles registry
230
231/// Role-switching decision engine (signals -> role -> model).
232pub mod role_switcher;
233
234/// Re-exports for the role_switcher module.
235pub use role_switcher::{
236 DEFAULT_LONG_CONTEXT_THRESHOLD, RoleSignals, decide_role, resolve_role_to_model, role_for_tool,
237};
238
239/// Re-exports for the live role registry (UI <-> provider shared state).
240pub use roles::{live_role_registry, set_live_role_registry};
241
242// Role-routing provider — plugs role switching into the live agent loop
243
244/// Provider wrapper that routes each request to the role-selected model.
245pub mod role_routing;
246
247/// Re-export the role-routing provider.
248pub use role_routing::RoleRoutingProvider;
249
250// Partial response for stream recovery
251pub mod partial_response;
252
253/// Partial response accumulator for stream recovery.
254pub use partial_response::PartialResponse;
255
256/// Re-export AssistantMessage from messages
257pub use messages::AssistantMessage;
258
259// Environment-based API key resolution
260
261/// Utilities for discovering API keys from the environment.
262pub use env_api_keys::{find_env_keys, get_all_env_keys, get_env_api_key};
263
264/// Product home-directory resolution (`OXICODE_HOME` → `~/.oxicode`).
265pub use product_env::home_dir as product_home_dir;
266
267// Provider authentication registry
268
269/// OAuth token and API key management for providers.
270pub use provider_registry::{OAuthTokenInfo, ProviderAuth, ProviderAuthRegistry};