feat: register plugin tool surfaces
This commit is contained in:
@@ -84,6 +84,8 @@ pub struct FeatureConfigPartial {
|
||||
pub ticket: Option<TicketFeatureConfigPartial>,
|
||||
#[serde(default)]
|
||||
pub ticket_orchestration: Option<FeatureFlagConfigPartial>,
|
||||
#[serde(default)]
|
||||
pub plugins: Option<FeatureFlagConfigPartial>,
|
||||
}
|
||||
|
||||
impl FeatureConfigPartial {
|
||||
@@ -99,6 +101,7 @@ impl FeatureConfigPartial {
|
||||
other.ticket_orchestration,
|
||||
FeatureFlagConfigPartial::merge,
|
||||
),
|
||||
plugins: merge_option(self.plugins, other.plugins, FeatureFlagConfigPartial::merge),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -152,6 +155,10 @@ impl From<FeatureConfigPartial> for FeatureConfig {
|
||||
.ticket_orchestration
|
||||
.map(FeatureFlagConfig::from)
|
||||
.unwrap_or_default(),
|
||||
plugins: value
|
||||
.plugins
|
||||
.map(FeatureFlagConfig::from)
|
||||
.unwrap_or_default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -199,6 +206,7 @@ impl From<FeatureConfig> for FeatureConfigPartial {
|
||||
pods: Some(value.pods.into()),
|
||||
ticket: Some(value.ticket.into()),
|
||||
ticket_orchestration: Some(value.ticket_orchestration.into()),
|
||||
plugins: Some(value.plugins.into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,6 +107,8 @@ pub struct FeatureConfig {
|
||||
pub ticket: TicketFeatureConfig,
|
||||
#[serde(default)]
|
||||
pub ticket_orchestration: FeatureFlagConfig,
|
||||
#[serde(default)]
|
||||
pub plugins: FeatureFlagConfig,
|
||||
}
|
||||
|
||||
impl Default for FeatureConfig {
|
||||
@@ -118,6 +120,7 @@ impl Default for FeatureConfig {
|
||||
pods: FeatureFlagConfig::disabled(),
|
||||
ticket: TicketFeatureConfig::default(),
|
||||
ticket_orchestration: FeatureFlagConfig::disabled(),
|
||||
plugins: FeatureFlagConfig::disabled(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,14 +188,19 @@ pub struct PluginPackageManifest {
|
||||
pub runtime: Option<PluginRuntimeManifest>,
|
||||
#[serde(default)]
|
||||
pub hooks: Vec<PluginHookManifest>,
|
||||
#[serde(default)]
|
||||
pub tools: Vec<PluginToolManifest>,
|
||||
}
|
||||
|
||||
impl PluginPackageManifest {
|
||||
fn declared_surfaces(&self) -> BTreeSet<PluginSurface> {
|
||||
pub fn declared_surfaces(&self) -> BTreeSet<PluginSurface> {
|
||||
let mut surfaces: BTreeSet<_> = self.surfaces.iter().copied().collect();
|
||||
if !self.hooks.is_empty() {
|
||||
surfaces.insert(PluginSurface::Hook);
|
||||
}
|
||||
if !self.tools.is_empty() {
|
||||
surfaces.insert(PluginSurface::Tool);
|
||||
}
|
||||
if self.runtime.is_some() {
|
||||
surfaces.insert(PluginSurface::Wasm);
|
||||
}
|
||||
@@ -218,6 +223,14 @@ pub struct PluginHookManifest {
|
||||
pub file: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct PluginToolManifest {
|
||||
pub name: String,
|
||||
pub description: String,
|
||||
pub input_schema: serde_json::Value,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct PluginDiscoveryLimits {
|
||||
pub max_packages_per_store: usize,
|
||||
@@ -1653,6 +1666,29 @@ file = "hooks/summary.md"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn package_manifest_tool_surface_shape_is_accepted() {
|
||||
let manifest: PluginPackageManifest = toml::from_str(
|
||||
r#"
|
||||
schema_version = 1
|
||||
id = "example.tool"
|
||||
name = "Example Tool"
|
||||
version = "0.1.0"
|
||||
|
||||
[[tools]]
|
||||
name = "ExampleTool"
|
||||
description = "Runs a package-defined tool."
|
||||
input_schema = { type = "object", properties = { query = { type = "string" } }, required = ["query"], additionalProperties = false }
|
||||
"#,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(manifest.tools.len(), 1);
|
||||
assert!(manifest.declared_surfaces().contains(&PluginSurface::Tool));
|
||||
assert_eq!(manifest.tools[0].name, "ExampleTool");
|
||||
assert_eq!(manifest.tools[0].input_schema["type"], "object");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn malformed_manifest_multibyte_diagnostic_is_bounded_and_redacted() {
|
||||
let temp = TempDir::new().unwrap();
|
||||
|
||||
Reference in New Issue
Block a user