Skip to main content

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;
51/// Product home-directory resolution (`OXICODE_HOME` / `~/.oxicode`).
52// `product_env` moved to oxicode-catalog (it owns catalog cache/override dirs);
53// re-exported here so `oxicode_ai::product_env` and `oxicode_sdk::ports::fs::path`
54// (which delegates here) keep working.
55pub use oxicode_catalog::product_env;
56pub mod provider_registry;
57mod providers;
58
59#[allow(missing_docs)]
60pub mod register_builtins {
61    pub use crate::providers::register_builtins::*;
62}
63/// Circuit-breaker behavior trait + SDK reference implementation.
64///
65/// See [`crate::circuit_breaker::CircuitBreaker`] and
66/// [`crate::circuit_breaker::DefaultCircuitBreaker`].
67pub mod circuit_breaker;
68pub mod router;
69pub mod secret;
70mod tools;
71mod transform;
72pub mod types;
73pub mod utils;
74
75/// Standard imports for oxicode-ai usage.
76pub mod prelude {
77    pub use crate::compaction::generate_branch_summary;
78    pub use crate::compaction::{
79        CompactedContext, CompactionManager, CompactionStrategy, Compactor, LlmCompactor,
80    };
81    pub use crate::context::Context;
82    pub use crate::error::{Error, Result};
83    pub use crate::messages::*;
84    pub use crate::providers::{Provider, ProviderEvent, StreamOptions, StreamResult};
85    pub use crate::tools::{Tool, validate_args};
86    pub use crate::types::*;
87}
88
89// Re-export main types
90
91/// Provider-specific error type for LLM operations.
92#[oxicode_stable(since = "0.63.0")]
93pub use crate::error::ProviderError;
94
95/// Structured HTTP error detail (status/body/provider/request-id) carried by
96/// [`ProviderError::HttpError`]. Re-exported so downstream crates (oxicode-agent,
97/// oxicode-cli) can construct/inspect structured errors.
98pub use crate::error::HttpErrorDetail;
99
100/// Shared conversation context.
101#[oxicode_stable(since = "0.63.0")]
102pub use context::Context;
103
104/// Result type alias for oxicode-ai operations.
105pub use error::{Error, Result};
106
107/// Message types for constructing conversations.
108#[oxicode_stable(since = "0.63.0")]
109pub use messages::*;
110
111/// Cache retention control for provider requests.
112#[oxicode_stable(since = "0.63.0")]
113pub use providers::CacheRetention;
114
115/// Provider trait, streaming options, and provider registry.
116#[oxicode_stable(since = "0.63.0")]
117pub use providers::{
118    Provider, ProviderEvent, ProviderOptions, ProviderRegistry, StreamOptions, StreamResult,
119    custom_provider_names, get_provider, get_provider_arc, register_provider, unregister_provider,
120};
121
122/// Built-in provider helpers (re-exported from providers).
123pub use providers::register_builtins::{
124    create_builtin_provider, create_builtin_provider_with_options, get_all_provider_names,
125    get_builtin_provider, get_provider_env_key, get_provider_env_keys, is_builtin_provider,
126};
127
128/// OpenAI-compatible provider implementation.
129pub use providers::OpenAiProvider;
130
131/// Anthropic provider implementation.
132pub use providers::AnthropicProvider;
133/// Azure OpenAI provider implementation.
134pub use providers::AzureProvider;
135
136/// Model fetching utilities (async and blocking).
137pub use providers::model_fetch::{fetch_models_async, fetch_models_blocking};
138
139/// OpenAI Responses API provider.
140pub use providers::OpenAiResponsesProvider;
141
142/// AWS Bedrock provider implementation.
143pub use providers::BedrockProvider;
144/// Google Gemini CLI transport — typed unsupported-provider error path.
145/// `Api::GoogleGeminiCli` dispatches here; `stream()` returns
146/// `ProviderError::NotImplemented` because no dedicated CLI transport
147/// exists in-tree (upstream collapses `google-gemini-cli → google-generative-ai`).
148pub use providers::GeminiCliProvider;
149/// Google Generative AI (Gemini) provider implementation.
150pub use providers::GoogleProvider;
151/// Ollama (local NDJSON server) provider implementation.
152pub use providers::OllamaProvider;
153/// Google Vertex AI provider implementation.
154pub use providers::VertexProvider;
155
156/// Provider-specific message normalization (empty content filtering, tool ID
157/// scrubbing, reasoning injection, tool-use ordering fix).
158pub use providers::normalize_messages;
159
160/// Tool definition and argument validation.
161#[oxicode_stable(since = "0.63.0")]
162pub use tools::{ProgressCallback, Tool, ToolValidationError, progress_callback, validate_args};
163
164pub use compaction::generate_branch_summary;
165/// Core type definitions (tokens, cost, etc.).
166#[oxicode_stable(since = "0.63.0")]
167pub use types::*;
168
169// High-level API
170
171/// Token estimation and context usage helpers.
172pub use high_level::tokens::{context_usage, estimate, estimate_words};
173
174/// High-level completion and token estimation.
175pub use high_level::{complete, estimate_tokens};
176
177// Context compaction
178
179/// Compaction strategies and managers for long conversations.
180pub use compaction::{
181    CompactedContext, CompactionManager, CompactionStrategy, Compactor, ContextTransformer,
182    LlmCompactor, NoopContextTransformer,
183};
184
185// Cross-provider message transformation
186
187/// Message transformation between provider formats.
188pub use transform::{
189    TransformOptions, anthropic_to_google, anthropic_to_openai, google_to_openai,
190    normalize_tool_call_id, openai_to_anthropic, transform_messages, transform_messages_for_model,
191};
192
193// Model registry (runtime mutable registry)
194mod model_registry;
195
196/// Runtime model registry for dynamically registered models.
197///
198/// Unlike the static `model_db`, this supports adding/removing models at runtime.
199pub use model_registry::{
200    ModelRegistry, dynamic_models, get_model, get_models, get_providers, lookup_model,
201    register_model, unregister_model,
202};
203
204// Static model database (comprehensive)
205pub mod model_db;
206
207/// Static database of known models with cost and modality info.
208///
209/// Provides comprehensive model listings, filtering, and search capabilities.
210pub use model_db::{
211    ModelEntry, get_all_models, get_cheapest_models, get_model_entry, get_provider_models,
212    get_reasoning_models, get_vision_models, model_count, search_models,
213};
214
215// Model roles — named model assignments (ported from omp)
216
217/// Named model roles with `pi/<role>` alias resolution.
218pub mod roles;
219
220/// Re-exports for the roles module.
221pub use roles::{
222    ModelRole, RoleColor, RoleInfo, RoleRegistry, builtin_role_info, builtin_visible_ids,
223};
224
225// Role switching — signal-based role decision on top of the roles registry
226
227/// Role-switching decision engine (signals -> role -> model).
228pub mod role_switcher;
229
230/// Re-exports for the role_switcher module.
231pub use role_switcher::{
232    DEFAULT_LONG_CONTEXT_THRESHOLD, RoleSignals, decide_role, resolve_role_to_model, role_for_tool,
233};
234
235/// Re-exports for the live role registry (UI <-> provider shared state).
236pub use roles::{live_role_registry, set_live_role_registry};
237
238// Role-routing provider — plugs role switching into the live agent loop
239
240/// Provider wrapper that routes each request to the role-selected model.
241pub mod role_routing;
242
243/// Re-export the role-routing provider.
244pub use role_routing::RoleRoutingProvider;
245
246// Partial response for stream recovery
247pub mod partial_response;
248
249/// Partial response accumulator for stream recovery.
250pub use partial_response::PartialResponse;
251
252/// Re-export AssistantMessage from messages
253pub use messages::AssistantMessage;
254
255// Environment-based API key resolution
256
257/// Utilities for discovering API keys from the environment.
258pub use env_api_keys::{find_env_keys, get_all_env_keys, get_env_api_key};
259
260/// Product home-directory resolution (`OXICODE_HOME` → `~/.oxicode`).
261pub use product_env::home_dir as product_home_dir;
262
263// Provider authentication registry
264
265/// OAuth token and API key management for providers.
266pub use provider_registry::{OAuthTokenInfo, ProviderAuth, ProviderAuthRegistry};