1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
//! Neutral host effects for resolving model identity and provider configuration.
use crate::error::Result;
use crate::model_spec::ModelSpec;
use crate::runtime_provider::ProviderKey;
use crate::typed_id::ModelId;
use async_trait::async_trait;
/// Trait for retrieving model identity and LLM provider configurations.
///
/// Model lookup is always credential-free. A host resolves provider
/// configuration separately by the open provider identity immediately before
/// it constructs or selects a driver. This split prevents model values from
/// carrying credentials through snapshots, logs, events, or public APIs.
#[async_trait]
pub trait ProviderStore: Send + Sync {
/// Resolve a configured model ID to its credential-free model selection.
async fn get_model_spec(&self, model_id: ModelId) -> Result<Option<ModelSpec>>;
/// Return the default credential-free model selection.
async fn get_default_model_spec(&self) -> Result<Option<ModelSpec>>;
/// Resolve runtime service configuration independently from the model.
///
/// Implementors must make credential ownership explicit. Return a config
/// when this store owns endpoint/authentication material; return `None`
/// only when the matching provider is registered directly in the host's
/// driver registry or is intentionally selected but not configured yet.
/// The latter remains constructible for configuration commands, but every
/// provider operation fails locally at the credential boundary.
async fn get_provider_config(
&self,
provider: &ProviderKey,
) -> Result<Option<crate::driver_registry::ProviderConfig>>;
}
#[async_trait]
impl<T: ProviderStore + ?Sized> ProviderStore for std::sync::Arc<T> {
async fn get_model_spec(&self, model_id: ModelId) -> Result<Option<ModelSpec>> {
(**self).get_model_spec(model_id).await
}
async fn get_default_model_spec(&self) -> Result<Option<ModelSpec>> {
(**self).get_default_model_spec().await
}
async fn get_provider_config(
&self,
provider: &ProviderKey,
) -> Result<Option<crate::driver_registry::ProviderConfig>> {
(**self).get_provider_config(provider).await
}
}