mirror of
https://github.com/openai/codex.git
synced 2026-11-12 22:42:36 +00:00
Split plugin install discovery into list and request tools (#23372)
## Summary - Add `list_available_plugins_to_install` as the inventory step for plugin and connector install suggestions. - Slim `request_plugin_install` so it only handles the actual elicitation, instead of carrying the full discoverable list in its prompt. - Emit send-time telemetry when an install elicitation is dispatched, including requested tool identity in the event payload. - Emit install-result telemetry through `SessionTelemetry`, including tool type, user response action, and completion status. - Update registration and tests to cover the new two-step flow while keeping the existing `tool_suggest` feature gate unchanged. ## Testing - `just fmt` - `cargo test -p codex-tools` - `cargo test -p codex-core request_plugin_install` - `cargo test -p codex-core list_available_plugins_to_install` - `cargo test -p codex-core install_suggestion_tools_can_be_registered_without_search_tool` - `cargo test -p codex-otel manager_records_plugin_install_suggestion_metric` - `cargo test -p codex-otel manager_records_plugin_install_elicitation_sent_metric` - `just fix -p codex-core` - `just fix -p codex-tools` - `just fix -p codex-otel` - `cargo check -p codex-core`
This commit is contained in:
1 parent
1509ae6d8d
commit
8335b56c33
17 files changed
+667
-158
No files matched your search
@@ -22,6 +22,7 @@ use core_test_support::test_codex::test_codex;
|
||||
use serde_json::Value;
|
||||
|
||||
const TOOL_SEARCH_TOOL_NAME: &str = "tool_search";
|
||||
const LIST_AVAILABLE_PLUGINS_TO_INSTALL_TOOL_NAME: &str = "list_available_plugins_to_install";
|
||||
const REQUEST_PLUGIN_INSTALL_TOOL_NAME: &str = "request_plugin_install";
|
||||
const DISCOVERABLE_GMAIL_ID: &str = "connector_68df038e0ba48191908c8434991bbac2";
|
||||
|
||||
@@ -125,6 +126,12 @@ async fn request_plugin_install_is_available_without_search_tool_after_discovery
|
||||
!tools.iter().any(|name| name == TOOL_SEARCH_TOOL_NAME),
|
||||
"tools list should not include {TOOL_SEARCH_TOOL_NAME}: {tools:?}"
|
||||
);
|
||||
assert!(
|
||||
tools
|
||||
.iter()
|
||||
.any(|name| name == LIST_AVAILABLE_PLUGINS_TO_INSTALL_TOOL_NAME),
|
||||
"tools list should include {LIST_AVAILABLE_PLUGINS_TO_INSTALL_TOOL_NAME}: {tools:?}"
|
||||
);
|
||||
assert!(
|
||||
tools
|
||||
.iter()
|
||||
@@ -132,18 +139,26 @@ async fn request_plugin_install_is_available_without_search_tool_after_discovery
|
||||
"tools list should include {REQUEST_PLUGIN_INSTALL_TOOL_NAME}: {tools:?}"
|
||||
);
|
||||
|
||||
let list_description =
|
||||
function_tool_description(&body, LIST_AVAILABLE_PLUGINS_TO_INSTALL_TOOL_NAME)
|
||||
.expect("description");
|
||||
assert!(list_description.contains(
|
||||
"The user explicitly asks to use a specific plugin or connector that is not already available in the current context or active `tools` list."
|
||||
));
|
||||
assert!(list_description.contains(
|
||||
"`tool_search` is not available, or it has already been called and did not find or make the requested tool callable."
|
||||
));
|
||||
assert!(list_description.contains(
|
||||
"When both a plugin and a connector match, prefer the plugin; use the connector only when its corresponding plugin is already installed."
|
||||
));
|
||||
|
||||
let description =
|
||||
function_tool_description(&body, REQUEST_PLUGIN_INSTALL_TOOL_NAME).expect("description");
|
||||
assert!(description.contains(
|
||||
"Use this tool only to ask the user to install one known plugin or connector from the list below"
|
||||
));
|
||||
assert!(description.contains(
|
||||
"`tool_search` is not available, or it has already been called and did not find or make the requested tool callable."
|
||||
));
|
||||
assert!(description.contains(
|
||||
"Only use when the user explicitly asks to use that exact listed plugin or connector."
|
||||
"Use this tool only after `list_available_plugins_to_install` returns a plugin or connector that exactly matches the user's explicit request."
|
||||
));
|
||||
assert!(description.contains("IMPORTANT: DO NOT call this tool in parallel with other tools."));
|
||||
assert!(!description.contains(DISCOVERABLE_GMAIL_ID));
|
||||
assert!(!description.contains("tool_search fails to find a good match"));
|
||||
|
||||
Ok(())
|
||||
|
||||
Reference in new issue
Block a user