use std::sync::Arc;
use std::time::Instant;
use tokio::sync::RwLock;
use super::run::RunTaskRegistry;
use crate::agent::AgentRegistry;
#[cfg(any(feature = "openai", feature = "anthropic"))]
use crate::config::ProviderType;
use crate::config::{AgentConfig, ProviderConfig};
use crate::provider::{ModelName, ProviderId};
use crate::runtime::AgentRuntime;
#[derive(Debug, Clone)]
pub struct ModelCatalogEntry {
pub provider: ProviderId,
pub model: ModelName,
pub streaming: bool,
pub tool_calling: bool,
}
pub struct GrpcState {
pub runtime: Arc<AgentRuntime>,
pub config: Arc<AgentConfig>,
pub started_at: Instant,
pub run_tasks: Arc<RunTaskRegistry>,
pub max_concurrent_runs: Option<usize>,
pub agent_registry: Arc<RwLock<AgentRegistry>>,
}
impl GrpcState {
#[must_use]
pub fn new(
runtime: Arc<AgentRuntime>,
config: Arc<AgentConfig>,
run_tasks: Arc<RunTaskRegistry>,
max_concurrent_runs: Option<usize>,
) -> Self {
Self {
runtime,
config,
started_at: Instant::now(),
run_tasks,
max_concurrent_runs,
agent_registry: Arc::new(RwLock::new(AgentRegistry::new())),
}
}
#[must_use]
pub fn provider_config(&self, id: &str) -> Option<&ProviderConfig> {
self.config
.providers
.iter()
.find_map(|(k, v)| if k.as_str() == id { Some(v) } else { None })
}
#[must_use]
pub fn model_catalog(&self) -> Vec<ModelCatalogEntry> {
build_model_catalog(&self.config.providers)
}
}
pub(crate) fn build_model_catalog(
providers: &std::collections::HashMap<ProviderId, ProviderConfig>,
) -> Vec<ModelCatalogEntry> {
let mut catalog = Vec::new();
for (provider_id, cfg) in providers {
let has_chat = match cfg.provider_type {
#[cfg(feature = "openai")]
Some(ProviderType::OpenAi) => true,
#[cfg(feature = "anthropic")]
Some(ProviderType::Anthropic) => true,
None => false,
#[allow(unreachable_patterns)]
_ => false,
};
if let Some(ref default_model) = cfg.model {
catalog.push(ModelCatalogEntry {
provider: provider_id.clone(),
model: default_model.clone(),
streaming: has_chat,
tool_calling: has_chat,
});
}
for model in &cfg.models {
catalog.push(ModelCatalogEntry {
provider: provider_id.clone(),
model: model.clone(),
streaming: has_chat,
tool_calling: has_chat,
});
}
}
catalog
}