Skip to main content

turnframe_provider/
lib.rs

1//! `turnframe-provider`: the provider-neutral model layer of Turnframe (spec §20).
2//!
3//! The core runtime never sees OpenAI-, Anthropic-, Gemini- or Bedrock-specific
4//! wire types (spec §0 rule 8). It speaks this crate's normalized vocabulary:
5//!
6//! * a [`request::ModelRequest`] describes one model call: purpose, messages,
7//!   expected [`request::OutputSpec`], read-only tools, limits and metadata;
8//! * a [`response::ModelResponse`] carries the normalized answer, a
9//!   [`response::FinishReason`] and [`response::TokenUsage`];
10//! * a [`stream::ModelStream`] delivers the same answer incrementally and
11//!   [`stream::reconstruct`] rebuilds the full response deterministically;
12//! * [`structured::parse_structured`] turns a response into a typed value
13//!   **all-or-nothing** (spec I18): schema validation with deny-unknown semantics,
14//!   then typed deserialization; a single malformed act rejects the whole output;
15//! * [`error::ProviderError`] is the typed failure family, classified by
16//!   [`error::RetryClass`] and free of secrets, request bodies and headers;
17//! * [`provider::ModelProvider`] is the trait every adapter implements against a
18//!   configured [`capabilities::ModelProfile`]; capabilities are declared per
19//!   provider-model pair, never inferred from the brand (spec §20.3);
20//! * [`router::PolicyRouter`] selects candidates by capability fit first, then
21//!   tenant policy, then health and preference — and refuses to downgrade the
22//!   structured-output requirement of a critical stage (spec §0 rule 9, §20.4);
23//! * [`fallback::execute_with_fallback`] tries candidates in order, retries by
24//!   class, records every attempt and never merges partial outputs (spec §20.7).
25//!
26//! Concrete adapters live in sibling crates (`turnframe-provider-openai`, …) and
27//! prove themselves with the reusable [`conformance`] suite (feature
28//! `conformance`, spec §20.8).
29//!
30//! # Where the safety rules live
31//!
32//! | Rule | Where it is enforced |
33//! |------|----------------------|
34//! | Model arrays are all-or-nothing (I18) | [`structured`], [`stream::StreamAccumulator`] |
35//! | No silent capability downgrade (§0.9) | [`purpose::ModelPurpose::requirements`], [`router::PolicyRouter`] |
36//! | Provider failure cannot repeat effects (I17) | [`fallback::FallbackStage`] is a required parameter |
37//! | Secrets never reach prompts or logs (§25.2) | [`secret::ApiKey`], [`secret::Redactor`], error `Display` |
38//! | Record every provider attempt (§20.7) | [`fallback::ProviderAttempt`] |
39
40#![forbid(unsafe_code)]
41#![cfg_attr(test, allow(clippy::unwrap_used, clippy::expect_used, clippy::panic))]
42
43/// The crate README, compiled as a doc-test so its example cannot rot.
44#[cfg(doctest)]
45#[doc = include_str!("../README.md")]
46mod readme {}
47
48pub mod capabilities;
49#[cfg(feature = "conformance")]
50pub mod conformance;
51pub mod dialect;
52pub mod error;
53pub mod fallback;
54pub mod ids;
55pub mod provider;
56pub mod purpose;
57pub mod request;
58pub mod response;
59pub mod router;
60pub mod secret;
61pub mod stream;
62pub mod structured;
63pub mod testing;
64pub mod trace;
65
66/// The most used items, for `use turnframe_provider::prelude::*`.
67pub mod prelude {
68    pub use crate::capabilities::{
69        CapabilityMismatch, CapabilityRequirements, MicroCents, MissingCapability, ModelProfile,
70        ProviderCapabilities, StructuredOutputCapability, ToolCallingCapability,
71    };
72    pub use crate::error::{ErrorCode, ProviderError, ProviderErrorKind, RetryClass};
73    pub use crate::fallback::{
74        FallbackFailure, FallbackOptions, FallbackOutcome, FallbackStage, ProviderAttempt,
75        RetryPolicy, execute_with_fallback,
76    };
77    pub use crate::ids::{AttemptNumber, CallId, ModelKey, ModelRef, ProviderKey, RequestId};
78    pub use crate::provider::ModelProvider;
79    pub use crate::purpose::{LoggingPolicy, ModelPurpose, SafetyMode};
80    pub use crate::request::{
81        CacheHint, ContentPart, DocumentSource, ImageSource, Message, ModelRequest, OutputSpec,
82        RequestMetadata, Role, ToolCall, ToolChoice, ToolResult, ToolSpec,
83    };
84    pub use crate::response::{FinishReason, ModelResponse, ResponseWarning, TokenUsage};
85    pub use crate::router::{
86        Clock, PolicyRouter, ProviderCandidate, ProviderPool, ProviderPoolBuilder, ProviderRouter,
87        RoutingError, RoutingPolicy,
88    };
89    pub use crate::secret::{ApiKey, DefaultRedactor, Redactor};
90    pub use crate::stream::{ModelStream, StreamAccumulator, StreamEvent, reconstruct};
91    pub use crate::structured::{
92        CompiledSchema, SchemaCache, StructuredOutputError, parse_structured,
93    };
94}