- Split agent crate into client/, model/, agent/ subdirs - Add billing.rs for token usage recording - Add sync.rs for upstream model sync - EmbedService: Qdrant-backed vector memory for semantic search - ChatService: wire EmbedService for memory lookup, passive skill awareness - ReAct loop: streamline with tokio::select! and proper error handling
37 lines
1.1 KiB
Rust
37 lines
1.1 KiB
Rust
//! Model sync from OpenRouter — syncs AI model metadata into the local database.
|
|
|
|
use crate::error::AgentError;
|
|
|
|
/// Response from `GET /v1/models`.
|
|
#[derive(Debug, serde::Deserialize)]
|
|
pub struct ModelsListResponse {
|
|
pub data: Vec<ModelEntry>,
|
|
}
|
|
|
|
#[derive(Debug, serde::Deserialize)]
|
|
pub struct ModelEntry {
|
|
pub id: String,
|
|
}
|
|
|
|
/// List accessible model IDs from the AI endpoint.
|
|
pub async fn list_accessible_models(
|
|
client: &reqwest::Client,
|
|
base_url: &str,
|
|
api_key: &str,
|
|
) -> Result<std::collections::HashSet<String>, AgentError> {
|
|
let url = format!("{}/v1/models", base_url.trim_end_matches('/'));
|
|
let resp = client
|
|
.get(&url)
|
|
.header("Authorization", format!("Bearer {}", api_key))
|
|
.send()
|
|
.await
|
|
.map_err(|e| AgentError::Internal(format!("failed to list models: {}", e)))?;
|
|
|
|
let body: ModelsListResponse = resp
|
|
.json()
|
|
.await
|
|
.map_err(|e| AgentError::Internal(format!("failed to parse models response: {}", e)))?;
|
|
|
|
Ok(body.data.into_iter().map(|m| m.id).collect())
|
|
}
|