feat: extensions read config (#1637)
This commit is contained in:
@@ -171,7 +171,7 @@ impl Capabilities {
|
||||
.await
|
||||
.map_err(|e| ExtensionError::Initialization(config.clone(), e))?;
|
||||
|
||||
let sanitized_name = normalize(config.name().to_string());
|
||||
let sanitized_name = normalize(config.key().to_string());
|
||||
|
||||
// Store instructions if provided
|
||||
if let Some(instructions) = init_result.instructions {
|
||||
|
||||
@@ -3,8 +3,10 @@ use std::collections::HashMap;
|
||||
use mcp_client::client::Error as ClientError;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use thiserror::Error;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
use crate::config;
|
||||
use crate::config::extensions::name_to_key;
|
||||
|
||||
/// Errors from Extension operation
|
||||
#[derive(Error, Debug)]
|
||||
@@ -21,7 +23,7 @@ pub enum ExtensionError {
|
||||
|
||||
pub type ExtensionResult<T> = Result<T, ExtensionError>;
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, Default)]
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, Default, ToSchema)]
|
||||
pub struct Envs {
|
||||
/// A map of environment variables to set, e.g. API_KEY -> some_secret, HOST -> host
|
||||
#[serde(default)]
|
||||
@@ -43,7 +45,7 @@ impl Envs {
|
||||
}
|
||||
|
||||
/// Represents the different types of MCP extensions that can be added to the manager
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, ToSchema)]
|
||||
#[serde(tag = "type")]
|
||||
pub enum ExtensionConfig {
|
||||
/// Server-sent events client with a URI endpoint
|
||||
@@ -130,13 +132,19 @@ impl ExtensionConfig {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn key(&self) -> String {
|
||||
let name = self.name();
|
||||
name_to_key(&name)
|
||||
}
|
||||
|
||||
/// Get the extension name regardless of variant
|
||||
pub fn name(&self) -> &str {
|
||||
pub fn name(&self) -> String {
|
||||
match self {
|
||||
Self::Sse { name, .. } => name,
|
||||
Self::Stdio { name, .. } => name,
|
||||
Self::Builtin { name, .. } => name,
|
||||
}
|
||||
.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,23 +3,28 @@ use crate::agents::ExtensionConfig;
|
||||
use anyhow::Result;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
pub const DEFAULT_EXTENSION: &str = "developer";
|
||||
pub const DEFAULT_EXTENSION_TIMEOUT: u64 = 300;
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
#[derive(Debug, Deserialize, Serialize, Clone, ToSchema)]
|
||||
pub struct ExtensionEntry {
|
||||
pub enabled: bool,
|
||||
#[serde(flatten)]
|
||||
pub config: ExtensionConfig,
|
||||
}
|
||||
|
||||
pub fn name_to_key(name: &str) -> String {
|
||||
name.to_string()
|
||||
}
|
||||
|
||||
/// Extension configuration management
|
||||
pub struct ExtensionManager;
|
||||
|
||||
impl ExtensionManager {
|
||||
/// Get the extension configuration if enabled
|
||||
pub fn get_config(name: &str) -> Result<Option<ExtensionConfig>> {
|
||||
/// Get the extension configuration if enabled -- uses key
|
||||
pub fn get_config(key: &str) -> Result<Option<ExtensionConfig>> {
|
||||
let config = Config::global();
|
||||
|
||||
// Try to get the extension entry
|
||||
@@ -28,7 +33,7 @@ impl ExtensionManager {
|
||||
Err(super::ConfigError::NotFound(_)) => {
|
||||
// Initialize with default developer extension
|
||||
let defaults = HashMap::from([(
|
||||
DEFAULT_EXTENSION.to_string(),
|
||||
name_to_key(DEFAULT_EXTENSION), // Use key format for top-level key in config
|
||||
ExtensionEntry {
|
||||
enabled: true,
|
||||
config: ExtensionConfig::Builtin {
|
||||
@@ -43,7 +48,7 @@ impl ExtensionManager {
|
||||
Err(e) => return Err(e.into()),
|
||||
};
|
||||
|
||||
Ok(extensions.get(name).and_then(|entry| {
|
||||
Ok(extensions.get(key).and_then(|entry| {
|
||||
if entry.enabled {
|
||||
Some(entry.config.clone())
|
||||
} else {
|
||||
@@ -60,33 +65,35 @@ impl ExtensionManager {
|
||||
.get_param("extensions")
|
||||
.unwrap_or_else(|_| HashMap::new());
|
||||
|
||||
extensions.insert(entry.config.name().parse()?, entry);
|
||||
let key = entry.config.key();
|
||||
|
||||
extensions.insert(key, entry);
|
||||
config.set_param("extensions", serde_json::to_value(extensions)?)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Remove an extension configuration
|
||||
pub fn remove(name: &str) -> Result<()> {
|
||||
/// Remove an extension configuration -- uses the key
|
||||
pub fn remove(key: &str) -> Result<()> {
|
||||
let config = Config::global();
|
||||
|
||||
let mut extensions: HashMap<String, ExtensionEntry> = config
|
||||
.get_param("extensions")
|
||||
.unwrap_or_else(|_| HashMap::new());
|
||||
|
||||
extensions.remove(name);
|
||||
extensions.remove(key);
|
||||
config.set_param("extensions", serde_json::to_value(extensions)?)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Enable or disable an extension
|
||||
pub fn set_enabled(name: &str, enabled: bool) -> Result<()> {
|
||||
/// Enable or disable an extension -- uses key
|
||||
pub fn set_enabled(key: &str, enabled: bool) -> Result<()> {
|
||||
let config = Config::global();
|
||||
|
||||
let mut extensions: HashMap<String, ExtensionEntry> = config
|
||||
.get_param("extensions")
|
||||
.unwrap_or_else(|_| HashMap::new());
|
||||
|
||||
if let Some(entry) = extensions.get_mut(name) {
|
||||
if let Some(entry) = extensions.get_mut(key) {
|
||||
entry.enabled = enabled;
|
||||
config.set_param("extensions", serde_json::to_value(extensions)?)?;
|
||||
}
|
||||
@@ -109,16 +116,17 @@ impl ExtensionManager {
|
||||
.unwrap_or_else(|_| get_keys(Default::default())))
|
||||
}
|
||||
|
||||
/// Check if an extension is enabled
|
||||
pub fn is_enabled(name: &str) -> Result<bool> {
|
||||
/// Check if an extension is enabled - FIXED to use key
|
||||
pub fn is_enabled(key: &str) -> Result<bool> {
|
||||
let config = Config::global();
|
||||
let extensions: HashMap<String, ExtensionEntry> = config
|
||||
.get_param("extensions")
|
||||
.unwrap_or_else(|_| HashMap::new());
|
||||
|
||||
Ok(extensions.get(name).map(|e| e.enabled).unwrap_or(false))
|
||||
Ok(extensions.get(key).map(|e| e.enabled).unwrap_or(false))
|
||||
}
|
||||
}
|
||||
|
||||
fn get_keys(entries: HashMap<String, ExtensionEntry>) -> Vec<String> {
|
||||
entries.into_keys().collect()
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
mod base;
|
||||
mod experiments;
|
||||
mod extensions;
|
||||
pub mod extensions;
|
||||
|
||||
pub use crate::agents::ExtensionConfig;
|
||||
pub use base::{Config, ConfigError, APP_STRATEGY};
|
||||
|
||||
Reference in New Issue
Block a user