mirror of
https://github.com/openai/codex.git
synced 2026-05-15 16:53:05 +00:00
Expose plugin manifest keywords in app server (#21271)
## Summary - Add plugin manifest keywords to core plugin marketplace/detail models - Expose keywords on app-server v2 PluginSummary and generated schema/types - Populate keywords in plugin/list and plugin/read responses for local plugins Depends on https://github.com/openai/openai/pull/891087 ## Validation - just fmt - just write-app-server-schema - cargo test -p codex-app-server-protocol - cargo test -p codex-core-plugins - cargo test -p codex-app-server plugin_list_keeps_valid_marketplaces_when_another_marketplace_fails_to_load - cargo test -p codex-app-server plugin_read_returns_plugin_details_with_bundle_contents
This commit is contained in:
committed by
GitHub
parent
136e442e95
commit
94db03d5af
@@ -12710,6 +12710,13 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"keywords": {
|
||||
"default": [],
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
|
||||
@@ -9321,6 +9321,13 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"keywords": {
|
||||
"default": [],
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
|
||||
@@ -347,6 +347,13 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"keywords": {
|
||||
"default": [],
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
|
||||
@@ -366,6 +366,13 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"keywords": {
|
||||
"default": [],
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
|
||||
@@ -307,6 +307,13 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"keywords": {
|
||||
"default": [],
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
|
||||
@@ -11,4 +11,4 @@ export type PluginSummary = { id: string, name: string, source: PluginSource, in
|
||||
/**
|
||||
* Availability state for installing and using the plugin.
|
||||
*/
|
||||
availability: PluginAvailability, interface: PluginInterface | null, };
|
||||
availability: PluginAvailability, interface: PluginInterface | null, keywords: Array<string>, };
|
||||
|
||||
@@ -446,6 +446,8 @@ pub struct PluginSummary {
|
||||
#[serde(default)]
|
||||
pub availability: PluginAvailability,
|
||||
pub interface: Option<PluginInterface>,
|
||||
#[serde(default)]
|
||||
pub keywords: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||
|
||||
@@ -3044,6 +3044,7 @@ fn plugin_share_list_response_serializes_share_items() {
|
||||
auth_policy: PluginAuthPolicy::OnUse,
|
||||
availability: PluginAvailability::Available,
|
||||
interface: None,
|
||||
keywords: Vec::new(),
|
||||
},
|
||||
share_url: "https://chatgpt.example/plugins/share/share-key-1".to_string(),
|
||||
local_plugin_path: None,
|
||||
@@ -3062,6 +3063,7 @@ fn plugin_share_list_response_serializes_share_items() {
|
||||
"authPolicy": "ON_USE",
|
||||
"availability": "AVAILABLE",
|
||||
"interface": null,
|
||||
"keywords": [],
|
||||
},
|
||||
"shareUrl": "https://chatgpt.example/plugins/share/share-key-1",
|
||||
"localPluginPath": null,
|
||||
|
||||
@@ -310,6 +310,7 @@ impl PluginRequestProcessor {
|
||||
auth_policy: plugin.policy.authentication.into(),
|
||||
availability: PluginAvailability::Available,
|
||||
interface: plugin.interface.map(local_plugin_interface_to_info),
|
||||
keywords: plugin.keywords,
|
||||
})
|
||||
.collect(),
|
||||
})
|
||||
@@ -465,6 +466,7 @@ impl PluginRequestProcessor {
|
||||
auth_policy: outcome.plugin.policy.authentication.into(),
|
||||
availability: PluginAvailability::Available,
|
||||
interface: outcome.plugin.interface.map(local_plugin_interface_to_info),
|
||||
keywords: outcome.plugin.keywords,
|
||||
},
|
||||
description: outcome.plugin.description,
|
||||
skills: plugin_skills_to_info(
|
||||
@@ -1270,6 +1272,7 @@ fn remote_plugin_summary_to_info(summary: RemoteCatalogPluginSummary) -> PluginS
|
||||
auth_policy: summary.auth_policy,
|
||||
availability: summary.availability,
|
||||
interface: summary.interface,
|
||||
keywords: summary.keywords,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -197,7 +197,7 @@ async fn plugin_list_keeps_valid_marketplaces_when_another_marketplace_fails_to_
|
||||
valid_repo_root
|
||||
.path()
|
||||
.join("plugins/valid-plugin/.codex-plugin/plugin.json"),
|
||||
r#"{"name":"valid-plugin"}"#,
|
||||
r#"{"name":"valid-plugin","keywords":["api-key","developer tools"]}"#,
|
||||
)?;
|
||||
std::fs::write(invalid_marketplace_path.as_path(), "{not json")?;
|
||||
|
||||
@@ -246,6 +246,7 @@ async fn plugin_list_keeps_valid_marketplaces_when_another_marketplace_fails_to_
|
||||
auth_policy: PluginAuthPolicy::OnInstall,
|
||||
availability: codex_app_server_protocol::PluginAvailability::Available,
|
||||
interface: None,
|
||||
keywords: vec!["api-key".to_string(), "developer tools".to_string()],
|
||||
}],
|
||||
}]
|
||||
);
|
||||
@@ -548,6 +549,7 @@ async fn plugin_list_uses_alternate_discoverable_manifest_and_keeps_undiscoverab
|
||||
screenshots: Vec::new(),
|
||||
screenshot_urls: Vec::new(),
|
||||
}),
|
||||
keywords: Vec::new(),
|
||||
},
|
||||
PluginSummary {
|
||||
id: "missing-plugin@alternate-marketplace".to_string(),
|
||||
@@ -563,6 +565,7 @@ async fn plugin_list_uses_alternate_discoverable_manifest_and_keeps_undiscoverab
|
||||
auth_policy: PluginAuthPolicy::OnInstall,
|
||||
availability: codex_app_server_protocol::PluginAvailability::Available,
|
||||
interface: None,
|
||||
keywords: Vec::new(),
|
||||
},
|
||||
],
|
||||
}]
|
||||
@@ -1295,6 +1298,7 @@ async fn plugin_list_includes_remote_marketplaces_when_remote_plugin_enabled() -
|
||||
"display_name": "Linear",
|
||||
"description": "Track work in Linear",
|
||||
"app_ids": [],
|
||||
"keywords": ["issue-tracking", "project management"],
|
||||
"interface": {
|
||||
"short_description": "Plan and track work",
|
||||
"capabilities": ["Read", "Write"],
|
||||
@@ -1430,6 +1434,13 @@ async fn plugin_list_includes_remote_marketplaces_when_remote_plugin_enabled() -
|
||||
.and_then(|interface| interface.display_name.as_deref()),
|
||||
Some("Linear")
|
||||
);
|
||||
assert_eq!(
|
||||
remote_marketplace.plugins[0].keywords,
|
||||
vec![
|
||||
"issue-tracking".to_string(),
|
||||
"project management".to_string()
|
||||
]
|
||||
);
|
||||
assert_eq!(response.featured_plugin_ids, Vec::<String>::new());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -172,6 +172,7 @@ async fn plugin_read_reads_remote_plugin_details_when_remote_plugin_enabled() ->
|
||||
"display_name": "Linear",
|
||||
"description": "Track work in Linear",
|
||||
"app_ids": [],
|
||||
"keywords": ["issue-tracking", "project management"],
|
||||
"interface": {
|
||||
"short_description": "Plan and track work",
|
||||
"capabilities": ["Read", "Write"],
|
||||
@@ -281,6 +282,13 @@ async fn plugin_read_reads_remote_plugin_details_when_remote_plugin_enabled() ->
|
||||
response.plugin.description.as_deref(),
|
||||
Some("Track work in Linear")
|
||||
);
|
||||
assert_eq!(
|
||||
response.plugin.summary.keywords,
|
||||
vec![
|
||||
"issue-tracking".to_string(),
|
||||
"project management".to_string()
|
||||
]
|
||||
);
|
||||
assert_eq!(response.plugin.skills.len(), 1);
|
||||
assert_eq!(response.plugin.skills[0].name, "plan-work");
|
||||
assert_eq!(response.plugin.skills[0].path, None);
|
||||
@@ -580,6 +588,7 @@ async fn plugin_read_returns_plugin_details_with_bundle_contents() -> Result<()>
|
||||
r##"{
|
||||
"name": "demo-plugin",
|
||||
"description": "Longer manifest description",
|
||||
"keywords": ["api-key", "developer tools"],
|
||||
"interface": {
|
||||
"displayName": "Plugin Display Name",
|
||||
"shortDescription": "Short description for subtitle",
|
||||
@@ -740,6 +749,10 @@ enabled = true
|
||||
"Find my next action".to_string()
|
||||
])
|
||||
);
|
||||
assert_eq!(
|
||||
response.plugin.summary.keywords,
|
||||
vec!["api-key".to_string(), "developer tools".to_string()]
|
||||
);
|
||||
assert_eq!(response.plugin.skills.len(), 1);
|
||||
assert_eq!(
|
||||
response.plugin.skills[0].name,
|
||||
|
||||
@@ -164,6 +164,7 @@ async fn plugin_share_save_uploads_local_plugin() -> Result<()> {
|
||||
auth_policy: PluginAuthPolicy::OnUse,
|
||||
availability: codex_app_server_protocol::PluginAvailability::Available,
|
||||
interface: Some(expected_plugin_interface()),
|
||||
keywords: Vec::new(),
|
||||
},
|
||||
share_url: "https://chatgpt.example/plugins/share/share-key-1".to_string(),
|
||||
local_plugin_path: Some(expected_plugin_path),
|
||||
@@ -239,6 +240,7 @@ async fn plugin_share_list_returns_created_workspace_plugins() -> Result<()> {
|
||||
auth_policy: PluginAuthPolicy::OnUse,
|
||||
availability: codex_app_server_protocol::PluginAvailability::Available,
|
||||
interface: Some(expected_plugin_interface()),
|
||||
keywords: Vec::new(),
|
||||
},
|
||||
share_url: "https://chatgpt.example/plugins/share/share-key-1".to_string(),
|
||||
local_plugin_path: None,
|
||||
@@ -342,6 +344,7 @@ async fn plugin_share_delete_removes_created_workspace_plugin() -> Result<()> {
|
||||
auth_policy: PluginAuthPolicy::OnUse,
|
||||
availability: codex_app_server_protocol::PluginAvailability::Available,
|
||||
interface: Some(expected_plugin_interface()),
|
||||
keywords: Vec::new(),
|
||||
},
|
||||
share_url: "https://chatgpt.example/plugins/share/share-key-1".to_string(),
|
||||
local_plugin_path: None,
|
||||
|
||||
@@ -223,6 +223,7 @@ pub struct PluginDetail {
|
||||
pub source: MarketplacePluginSource,
|
||||
pub policy: MarketplacePluginPolicy,
|
||||
pub interface: Option<PluginManifestInterface>,
|
||||
pub keywords: Vec<String>,
|
||||
pub installed: bool,
|
||||
pub enabled: bool,
|
||||
pub skills: Vec<SkillMetadata>,
|
||||
@@ -252,6 +253,7 @@ pub struct ConfiguredMarketplacePlugin {
|
||||
pub source: MarketplacePluginSource,
|
||||
pub policy: MarketplacePluginPolicy,
|
||||
pub interface: Option<PluginManifestInterface>,
|
||||
pub keywords: Vec<String>,
|
||||
pub installed: bool,
|
||||
pub enabled: bool,
|
||||
}
|
||||
@@ -1196,6 +1198,7 @@ impl PluginsManager {
|
||||
source: plugin.source,
|
||||
policy: plugin.policy,
|
||||
interface: plugin.interface,
|
||||
keywords: plugin.keywords,
|
||||
})
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
@@ -1245,6 +1248,11 @@ impl PluginsManager {
|
||||
source: plugin.source,
|
||||
policy: plugin.policy,
|
||||
interface: plugin.interface,
|
||||
keywords: plugin
|
||||
.manifest
|
||||
.as_ref()
|
||||
.map(|manifest| manifest.keywords.clone())
|
||||
.unwrap_or_default(),
|
||||
installed: installed_plugins.contains(&plugin_key),
|
||||
enabled: enabled_plugins.contains(&plugin_key),
|
||||
},
|
||||
@@ -1287,6 +1295,7 @@ impl PluginsManager {
|
||||
source: plugin.source,
|
||||
policy: plugin.policy,
|
||||
interface: plugin.interface,
|
||||
keywords: plugin.keywords,
|
||||
installed: plugin.installed,
|
||||
enabled: plugin.enabled,
|
||||
skills: Vec::new(),
|
||||
@@ -1363,6 +1372,7 @@ impl PluginsManager {
|
||||
source: plugin.source,
|
||||
policy: plugin.policy,
|
||||
interface,
|
||||
keywords: manifest.keywords,
|
||||
installed: plugin.installed,
|
||||
enabled: plugin.enabled,
|
||||
skills: resolved_skills.skills,
|
||||
|
||||
@@ -1550,6 +1550,7 @@ enabled = false
|
||||
products: None,
|
||||
},
|
||||
interface: None,
|
||||
keywords: Vec::new(),
|
||||
installed: true,
|
||||
enabled: true,
|
||||
},
|
||||
@@ -1566,6 +1567,7 @@ enabled = false
|
||||
products: None,
|
||||
},
|
||||
interface: None,
|
||||
keywords: Vec::new(),
|
||||
installed: true,
|
||||
enabled: false,
|
||||
},
|
||||
@@ -1684,6 +1686,7 @@ plugins = true
|
||||
products: None,
|
||||
},
|
||||
interface: None,
|
||||
keywords: Vec::new(),
|
||||
installed: false,
|
||||
enabled: false,
|
||||
}]
|
||||
@@ -2068,6 +2071,7 @@ plugins = true
|
||||
products: None,
|
||||
},
|
||||
interface: None,
|
||||
keywords: Vec::new(),
|
||||
installed: false,
|
||||
enabled: false,
|
||||
}],
|
||||
@@ -2361,6 +2365,7 @@ enabled = false
|
||||
products: None,
|
||||
},
|
||||
interface: None,
|
||||
keywords: Vec::new(),
|
||||
installed: false,
|
||||
enabled: true,
|
||||
}]
|
||||
@@ -2390,6 +2395,7 @@ enabled = false
|
||||
products: None,
|
||||
},
|
||||
interface: None,
|
||||
keywords: Vec::new(),
|
||||
installed: false,
|
||||
enabled: false,
|
||||
}]
|
||||
@@ -2473,6 +2479,7 @@ enabled = true
|
||||
products: None,
|
||||
},
|
||||
interface: None,
|
||||
keywords: Vec::new(),
|
||||
installed: false,
|
||||
enabled: true,
|
||||
}],
|
||||
|
||||
@@ -18,6 +18,8 @@ struct RawPluginManifest {
|
||||
version: Option<String>,
|
||||
#[serde(default)]
|
||||
description: Option<String>,
|
||||
#[serde(default)]
|
||||
keywords: Vec<String>,
|
||||
// Keep manifest paths as raw strings so we can validate the required `./...` syntax before
|
||||
// resolving them under the plugin root.
|
||||
#[serde(default)]
|
||||
@@ -37,6 +39,7 @@ pub struct PluginManifest {
|
||||
pub name: String,
|
||||
pub version: Option<String>,
|
||||
pub description: Option<String>,
|
||||
pub keywords: Vec<String>,
|
||||
pub paths: PluginManifestPaths,
|
||||
pub interface: Option<PluginManifestInterface>,
|
||||
}
|
||||
@@ -143,6 +146,7 @@ pub fn load_plugin_manifest(plugin_root: &Path) -> Option<PluginManifest> {
|
||||
name: raw_name,
|
||||
version,
|
||||
description,
|
||||
keywords,
|
||||
skills,
|
||||
mcp_servers,
|
||||
apps,
|
||||
@@ -232,6 +236,7 @@ pub fn load_plugin_manifest(plugin_root: &Path) -> Option<PluginManifest> {
|
||||
name,
|
||||
version,
|
||||
description,
|
||||
keywords,
|
||||
paths: PluginManifestPaths {
|
||||
skills: resolve_manifest_path(plugin_root, "skills", skills.as_deref()),
|
||||
mcp_servers: resolve_manifest_path(
|
||||
@@ -568,6 +573,28 @@ mod tests {
|
||||
assert_eq!(manifest.version, Some("1.2.3-beta+7".to_string()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn plugin_manifest_reads_keywords() {
|
||||
let tmp = tempdir().expect("tempdir");
|
||||
let plugin_root = tmp.path().join("demo-plugin");
|
||||
fs::create_dir_all(plugin_root.join(".codex-plugin")).expect("create manifest dir");
|
||||
fs::write(
|
||||
plugin_root.join(".codex-plugin/plugin.json"),
|
||||
r#"{
|
||||
"name": "demo-plugin",
|
||||
"keywords": ["api-key", "developer tools"]
|
||||
}"#,
|
||||
)
|
||||
.expect("write manifest");
|
||||
|
||||
let manifest = load_manifest(&plugin_root);
|
||||
|
||||
assert_eq!(
|
||||
manifest.keywords,
|
||||
vec!["api-key".to_string(), "developer tools".to_string()]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn plugin_manifest_uses_alternate_discoverable_path() {
|
||||
let tmp = tempdir().expect("tempdir");
|
||||
|
||||
@@ -62,6 +62,7 @@ pub struct MarketplacePlugin {
|
||||
pub source: MarketplacePluginSource,
|
||||
pub policy: MarketplacePluginPolicy,
|
||||
pub interface: Option<PluginManifestInterface>,
|
||||
pub keywords: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
@@ -293,6 +294,10 @@ pub fn load_marketplace(path: &AbsolutePathBuf) -> Result<Marketplace, Marketpla
|
||||
source: plugin.source,
|
||||
policy: plugin.policy,
|
||||
interface: plugin.interface,
|
||||
keywords: plugin
|
||||
.manifest
|
||||
.map(|manifest| manifest.keywords)
|
||||
.unwrap_or_default(),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -413,6 +413,7 @@ fn list_marketplaces_supports_alternate_manifest_layout() {
|
||||
logo: None,
|
||||
screenshots: Vec::new(),
|
||||
}),
|
||||
keywords: Vec::new(),
|
||||
}],
|
||||
}]
|
||||
);
|
||||
@@ -462,6 +463,7 @@ fn list_marketplaces_includes_plugins_without_discoverable_manifest() {
|
||||
products: None,
|
||||
},
|
||||
interface: None,
|
||||
keywords: Vec::new(),
|
||||
}],
|
||||
}]
|
||||
);
|
||||
@@ -602,6 +604,7 @@ fn list_marketplaces_returns_home_and_repo_marketplaces() {
|
||||
products: None,
|
||||
},
|
||||
interface: None,
|
||||
keywords: Vec::new(),
|
||||
},
|
||||
MarketplacePlugin {
|
||||
name: "home-only".to_string(),
|
||||
@@ -614,6 +617,7 @@ fn list_marketplaces_returns_home_and_repo_marketplaces() {
|
||||
products: None,
|
||||
},
|
||||
interface: None,
|
||||
keywords: Vec::new(),
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -635,6 +639,7 @@ fn list_marketplaces_returns_home_and_repo_marketplaces() {
|
||||
products: None,
|
||||
},
|
||||
interface: None,
|
||||
keywords: Vec::new(),
|
||||
},
|
||||
MarketplacePlugin {
|
||||
name: "repo-only".to_string(),
|
||||
@@ -647,6 +652,7 @@ fn list_marketplaces_returns_home_and_repo_marketplaces() {
|
||||
products: None,
|
||||
},
|
||||
interface: None,
|
||||
keywords: Vec::new(),
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -724,6 +730,7 @@ fn list_marketplaces_keeps_distinct_entries_for_same_name() {
|
||||
products: None,
|
||||
},
|
||||
interface: None,
|
||||
keywords: Vec::new(),
|
||||
}],
|
||||
},
|
||||
Marketplace {
|
||||
@@ -741,6 +748,7 @@ fn list_marketplaces_keeps_distinct_entries_for_same_name() {
|
||||
products: None,
|
||||
},
|
||||
interface: None,
|
||||
keywords: Vec::new(),
|
||||
}],
|
||||
},
|
||||
]
|
||||
@@ -814,6 +822,7 @@ fn list_marketplaces_dedupes_multiple_roots_in_same_repo() {
|
||||
products: None,
|
||||
},
|
||||
interface: None,
|
||||
keywords: Vec::new(),
|
||||
}],
|
||||
}]
|
||||
);
|
||||
@@ -976,6 +985,7 @@ fn list_marketplaces_skips_plugins_with_invalid_names_but_keeps_marketplace() {
|
||||
products: None,
|
||||
},
|
||||
interface: None,
|
||||
keywords: Vec::new(),
|
||||
}],
|
||||
}]
|
||||
);
|
||||
@@ -1093,6 +1103,7 @@ fn list_marketplaces_keeps_remote_and_local_plugin_sources() {
|
||||
products: None,
|
||||
},
|
||||
interface: None,
|
||||
keywords: Vec::new(),
|
||||
},
|
||||
MarketplacePlugin {
|
||||
name: "url-plugin".to_string(),
|
||||
@@ -1108,6 +1119,7 @@ fn list_marketplaces_keeps_remote_and_local_plugin_sources() {
|
||||
products: None,
|
||||
},
|
||||
interface: None,
|
||||
keywords: Vec::new(),
|
||||
},
|
||||
MarketplacePlugin {
|
||||
name: "git-subdir-plugin".to_string(),
|
||||
@@ -1123,6 +1135,7 @@ fn list_marketplaces_keeps_remote_and_local_plugin_sources() {
|
||||
products: None,
|
||||
},
|
||||
interface: None,
|
||||
keywords: Vec::new(),
|
||||
},
|
||||
]
|
||||
);
|
||||
|
||||
@@ -74,6 +74,7 @@ pub struct RemotePluginSummary {
|
||||
pub auth_policy: PluginAuthPolicy,
|
||||
pub availability: PluginAvailability,
|
||||
pub interface: Option<PluginInterface>,
|
||||
pub keywords: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
@@ -321,6 +322,8 @@ struct RemotePluginReleaseResponse {
|
||||
bundle_download_url: Option<String>,
|
||||
#[serde(default)]
|
||||
app_ids: Vec<String>,
|
||||
#[serde(default)]
|
||||
keywords: Vec<String>,
|
||||
interface: RemotePluginReleaseInterfaceResponse,
|
||||
#[serde(default)]
|
||||
skills: Vec<RemotePluginSkillResponse>,
|
||||
@@ -771,6 +774,7 @@ fn build_remote_plugin_summary(
|
||||
auth_policy: plugin.authentication_policy,
|
||||
availability: plugin.availability,
|
||||
interface: remote_plugin_interface_to_info(plugin),
|
||||
keywords: plugin.release.keywords.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -442,6 +442,7 @@ async fn list_remote_plugin_shares_fetches_created_workspace_plugins() {
|
||||
auth_policy: PluginAuthPolicy::OnUse,
|
||||
availability: PluginAvailability::Available,
|
||||
interface: Some(expected_plugin_interface()),
|
||||
keywords: Vec::new(),
|
||||
},
|
||||
share_url: Some("https://chatgpt.example/plugins/share/share-key-1".to_string()),
|
||||
local_plugin_path: Some(local_plugin_path),
|
||||
@@ -456,6 +457,7 @@ async fn list_remote_plugin_shares_fetches_created_workspace_plugins() {
|
||||
auth_policy: PluginAuthPolicy::OnUse,
|
||||
availability: PluginAvailability::Available,
|
||||
interface: Some(expected_plugin_interface()),
|
||||
keywords: Vec::new(),
|
||||
},
|
||||
share_url: None,
|
||||
local_plugin_path: None,
|
||||
|
||||
@@ -1448,6 +1448,7 @@ pub(super) fn plugins_test_summary(
|
||||
description,
|
||||
/*long_description*/ None,
|
||||
)),
|
||||
keywords: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user