1#![cfg_attr(not(test), deny(clippy::unwrap_used, clippy::expect_used, clippy::panic, clippy::unimplemented, clippy::todo, clippy::unreachable))]
18
19pub mod agents;
20pub mod connectors;
21pub mod discover;
22pub mod manifest;
23pub mod mcp;
24pub mod names;
25pub mod python;
26pub mod skills;
27
28use std::collections::BTreeMap;
29use std::fmt;
30use std::path::PathBuf;
31
32pub use agents::{AgentDef, load_agents_dir, merge_agents, parse_agent};
33pub use connectors::{Connector, ConnectorContent, ConnectorDraft, ConnectorResult, ConnectorTool, ConnectorToolAdapter, connector_tools, parse_connector};
34pub use discover::{Discovery, Plugin, PluginSources, discover, load_plugin};
35pub use manifest::{MANIFEST, MANIFEST_ALIAS, Manifest, ManifestError, McpServerConfig, parse_manifest};
36pub use names::ToolNames;
37pub use python::{PythonTool, default_python, python_tools, python_tools_in, run_script_sandboxed, run_script_unsandboxed};
38pub use skills::{SaveSkillTool, Skill, UseSkillTool, load_skills_dir, skills_prompt};
39
40#[derive(Debug, Clone, PartialEq, Eq)]
42pub struct LoadError {
43 pub path: PathBuf,
44 pub message: String,
45}
46
47impl fmt::Display for LoadError {
48 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
49 write!(f, "{}: {}", self.path.display(), self.message)
50 }
51}
52
53impl std::error::Error for LoadError {}
54
55#[derive(Debug, Clone, PartialEq, Eq)]
57pub struct PluginRef {
58 pub id: String,
59 pub name: String,
60 pub dir: PathBuf,
61 pub network: bool,
63 pub env: BTreeMap<String, String>,
65}
66
67impl PluginRef {
68 pub fn new(plugin: &Plugin, settings: &BTreeMap<String, String>) -> Self {
70 let mut env: BTreeMap<String, String> = plugin.manifest.settings.iter().filter_map(|s| Some((s.key.clone(), s.default.clone()?))).collect();
71 for s in &plugin.manifest.settings {
72 if let Some(v) = settings.get(&s.key) {
73 env.insert(s.key.clone(), v.clone());
74 }
75 }
76 Self { id: plugin.manifest.id.clone(), name: plugin.manifest.name.clone(), dir: plugin.dir.clone(), network: plugin.manifest.permissions.network, env }
77 }
78
79 pub fn missing_settings(plugin: &Plugin, settings: &BTreeMap<String, String>) -> Vec<String> {
81 plugin
82 .manifest
83 .settings
84 .iter()
85 .filter(|s| s.required && settings.get(&s.key).or(s.default.as_ref()).is_none_or(|v| v.trim().is_empty()))
86 .map(|s| s.label.clone())
87 .collect()
88 }
89}