diff --git a/crates/cli/src/config.rs b/crates/cli/src/config.rs index 2307065fc..996563655 100644 --- a/crates/cli/src/config.rs +++ b/crates/cli/src/config.rs @@ -195,9 +195,6 @@ pub(crate) struct ServerArgs { /// Upstream Anthropic base URL (e.g. https://api.anthropic.com) #[arg(long, env = "NEMO_RELAY_ANTHROPIC_BASE_URL")] pub(crate) anthropic_base_url: Option, - /// Generic plugin configuration JSON for process-level gateway plugin activation. - #[arg(long, env = "NEMO_RELAY_PLUGIN_CONFIG")] - pub(crate) plugin_config: Option, } impl ServerArgs { @@ -210,7 +207,6 @@ impl ServerArgs { self.bind.is_some() || self.openai_base_url.is_some() || self.anthropic_base_url.is_some() - || self.plugin_config.is_some() || self.config.is_some() } } @@ -267,8 +263,6 @@ pub(crate) struct RunCommand { #[arg(long)] pub(crate) session_metadata: Option, #[arg(long)] - pub(crate) plugin_config: Option, - #[arg(long)] pub(crate) dry_run: bool, #[arg(long)] pub(crate) print: bool, @@ -440,8 +434,8 @@ pub(crate) fn resolve_server_config(args: &ServerArgs) -> Result, @@ -452,16 +446,7 @@ pub(crate) fn resolve_run_config( .or_else(|| inherited.and_then(|args| args.config.as_ref())); let mut resolved = load_shared_config(config)?; if let Some(args) = inherited { - // Run-subcommand plugin config has higher precedence than inherited top-level plugin - // config. Skip only that inherited field so file/plugins.toml conflicts are still caught - // when the run-level override is applied below. - if command.plugin_config.is_some() && args.plugin_config.is_some() { - let mut inherited = args.clone(); - inherited.plugin_config = None; - apply_server_overrides(&mut resolved.gateway, &inherited)?; - } else { - apply_server_overrides(&mut resolved.gateway, args)?; - } + apply_server_overrides(&mut resolved.gateway, args)?; } apply_run_overrides(&mut resolved.gateway, command)?; resolved.gateway.bind = "127.0.0.1:0" @@ -471,7 +456,7 @@ pub(crate) fn resolve_run_config( } // Applies subcommand-specific `run` overrides after inherited top-level flags. JSON-bearing fields -// are parsed here so invalid metadata or plugin config fails before the gateway binds a port. +// are parsed here so invalid session metadata fails before the gateway binds a port. fn apply_run_overrides(config: &mut GatewayConfig, command: &RunCommand) -> Result<(), CliError> { apply_run_url_overrides(config, command); apply_run_json_overrides(config, command)?; @@ -489,8 +474,8 @@ fn apply_run_url_overrides(config: &mut GatewayConfig, command: &RunCommand) { } } -// Parses JSON-bearing run overrides after simple values. Invalid metadata or plugin config fails -// before transparent run mode binds its ephemeral gateway listener. +// Parses JSON-bearing run overrides after simple values. Invalid session metadata fails before +// transparent run mode binds its ephemeral gateway listener. fn apply_run_json_overrides( config: &mut GatewayConfig, command: &RunCommand, @@ -498,9 +483,6 @@ fn apply_run_json_overrides( if let Some(value) = &command.session_metadata { config.metadata = Some(parse_json_option("session metadata", value)?); } - if let Some(value) = &command.plugin_config { - apply_cli_plugin_config(config, value)?; - } Ok(()) } @@ -516,9 +498,6 @@ fn apply_server_overrides(config: &mut GatewayConfig, args: &ServerArgs) -> Resu if let Some(value) = &args.anthropic_base_url { config.anthropic_base_url = value.clone(); } - if let Some(value) = &args.plugin_config { - apply_cli_plugin_config(config, value)?; - } Ok(()) } @@ -790,16 +769,6 @@ fn apply_plugin_toml_config( Ok(()) } -fn apply_cli_plugin_config(config: &mut GatewayConfig, value: &str) -> Result<(), CliError> { - if config.plugin_config.is_some() { - return Err(CliError::Config( - "plugin config is defined by both --plugin-config and file configuration; choose one source".into(), - )); - } - config.plugin_config = Some(parse_json_option("plugin config", value)?); - Ok(()) -} - // Applies configured agent commands and Cursor's temporary-hook behavior. Cursor's // `patch_restore_hooks` flag is intentionally tri-state in file config so omitted values preserve // the safe default while explicit `false` disables temporary hook mutation. diff --git a/crates/cli/src/launcher.rs b/crates/cli/src/launcher.rs index b9b3048ce..efbc5fdc3 100644 --- a/crates/cli/src/launcher.rs +++ b/crates/cli/src/launcher.rs @@ -73,7 +73,6 @@ pub(crate) async fn easy_path( openai_base_url: None, anthropic_base_url: None, session_metadata: None, - plugin_config: None, dry_run: false, print: false, command: command.command, diff --git a/crates/cli/tests/coverage/config_tests.rs b/crates/cli/tests/coverage/config_tests.rs index d7426da41..e79536288 100644 --- a/crates/cli/tests/coverage/config_tests.rs +++ b/crates/cli/tests/coverage/config_tests.rs @@ -124,7 +124,6 @@ command = "hermes --yolo chat" openai_base_url: None, anthropic_base_url: None, session_metadata: None, - plugin_config: None, dry_run: false, print: false, command: vec![], @@ -179,7 +178,6 @@ fn legacy_observability_config_sections_fail_clearly() { openai_base_url: None, anthropic_base_url: None, session_metadata: None, - plugin_config: None, dry_run: false, print: false, command: vec![], @@ -232,7 +230,6 @@ mode = "overwrite" openai_base_url: None, anthropic_base_url: None, session_metadata: None, - plugin_config: None, dry_run: false, print: false, command: vec!["codex".into()], @@ -521,30 +518,6 @@ config = { version = 1, components = [] } assert!(error.contains("plugins.toml")); } -#[test] -fn cli_plugin_config_conflicts_with_file_plugin_config() { - let temp = tempfile::tempdir().unwrap(); - let config_path = temp.path().join("config.toml"); - std::fs::write(&config_path, "").unwrap(); - std::fs::write(temp.path().join("plugins.toml"), "version = 1\n").unwrap(); - let command = RunCommand { - agent: Some(CodingAgent::Codex), - config: Some(config_path), - openai_base_url: None, - anthropic_base_url: None, - session_metadata: None, - plugin_config: Some(r#"{"version":1,"components":[]}"#.into()), - dry_run: false, - print: false, - command: vec!["codex".into()], - }; - - let error = resolve_run_config(&command, None).unwrap_err().to_string(); - - assert!(error.contains("--plugin-config")); - assert!(error.contains("file configuration")); -} - #[test] fn cli_run_overrides_config_values() { let temp = tempfile::tempdir().unwrap(); @@ -563,7 +536,6 @@ openai_base_url = "http://file-openai" openai_base_url: Some("http://cli-openai".into()), anthropic_base_url: None, session_metadata: Some(r#"{"team":"cli"}"#.into()), - plugin_config: None, dry_run: false, print: false, command: vec!["codex".into()], @@ -598,7 +570,6 @@ openai_base_url = "http://file-openai" openai_base_url: None, anthropic_base_url: None, session_metadata: None, - plugin_config: None, dry_run: false, print: false, command: vec!["codex".into()], @@ -609,34 +580,6 @@ openai_base_url = "http://file-openai" assert_eq!(resolved.gateway.openai_base_url, "http://top-level-openai"); } -#[test] -fn run_plugin_config_overrides_inherited_top_level_plugin_config() { - let temp = tempfile::tempdir().unwrap(); - let server = ServerArgs { - config: Some(isolated_config_path(&temp)), - plugin_config: Some(r#"{"components":["top-level"]}"#.into()), - ..ServerArgs::default() - }; - let command = RunCommand { - agent: Some(CodingAgent::Codex), - config: None, - openai_base_url: None, - anthropic_base_url: None, - session_metadata: None, - plugin_config: Some(r#"{"components":["run"]}"#.into()), - dry_run: false, - print: false, - command: vec!["codex".into()], - }; - - let resolved = resolve_run_config(&command, Some(&server)).unwrap(); - - assert_eq!( - resolved.gateway.plugin_config, - Some(json!({ "components": ["run"] })) - ); -} - #[test] fn server_resolution_applies_all_server_overrides() { let temp = tempfile::tempdir().unwrap(); @@ -645,7 +588,6 @@ fn server_resolution_applies_all_server_overrides() { bind: Some("127.0.0.1:0".parse().unwrap()), openai_base_url: Some("http://cli-openai".into()), anthropic_base_url: Some("http://cli-anthropic".into()), - plugin_config: Some(r#"{"version":1,"components":[]}"#.into()), }; let resolved = resolve_server_config(&args).unwrap(); @@ -653,10 +595,6 @@ fn server_resolution_applies_all_server_overrides() { assert_eq!(resolved.gateway.bind.to_string(), "127.0.0.1:0"); assert_eq!(resolved.gateway.openai_base_url, "http://cli-openai"); assert_eq!(resolved.gateway.anthropic_base_url, "http://cli-anthropic"); - assert_eq!( - resolved.gateway.plugin_config, - Some(json!({ "version": 1, "components": [] })) - ); assert!(args.requested_daemon_mode()); } @@ -669,7 +607,6 @@ fn run_resolution_applies_all_run_overrides() { openai_base_url: Some("http://run-openai".into()), anthropic_base_url: Some("http://run-anthropic".into()), session_metadata: Some(r#"{"team":"run"}"#.into()), - plugin_config: Some(r#"{"components":["x"]}"#.into()), dry_run: false, print: false, command: vec!["codex".into()], @@ -680,10 +617,6 @@ fn run_resolution_applies_all_run_overrides() { assert_eq!(resolved.gateway.openai_base_url, "http://run-openai"); assert_eq!(resolved.gateway.anthropic_base_url, "http://run-anthropic"); assert_eq!(resolved.gateway.metadata, Some(json!({ "team": "run" }))); - assert_eq!( - resolved.gateway.plugin_config, - Some(json!({ "components": ["x"] })) - ); } #[test] diff --git a/crates/cli/tests/coverage/launcher_tests.rs b/crates/cli/tests/coverage/launcher_tests.rs index c079e2277..6011dbd53 100644 --- a/crates/cli/tests/coverage/launcher_tests.rs +++ b/crates/cli/tests/coverage/launcher_tests.rs @@ -18,7 +18,6 @@ fn infers_agent_from_command_or_uses_override() { openai_base_url: None, anthropic_base_url: None, session_metadata: None, - plugin_config: None, dry_run: false, print: false, command: vec!["/usr/bin/codex".into()], @@ -51,7 +50,6 @@ fn uses_configured_command_when_no_argv_is_supplied() { openai_base_url: None, anthropic_base_url: None, session_metadata: None, - plugin_config: None, dry_run: false, print: false, command: vec![], @@ -78,7 +76,6 @@ fn uses_configured_hermes_command_when_no_argv_is_supplied() { openai_base_url: None, anthropic_base_url: None, session_metadata: None, - plugin_config: None, dry_run: false, print: false, command: vec![], @@ -98,7 +95,6 @@ fn inference_failure_has_actionable_message() { openai_base_url: None, anthropic_base_url: None, session_metadata: None, - plugin_config: None, dry_run: false, print: false, command: vec!["my-agent".into()], @@ -123,7 +119,6 @@ fn missing_command_without_agent_errors() { openai_base_url: None, anthropic_base_url: None, session_metadata: None, - plugin_config: None, dry_run: false, print: false, command: vec![], @@ -146,7 +141,6 @@ fn agent_without_configured_command_falls_back_to_default_binary() { openai_base_url: None, anthropic_base_url: None, session_metadata: None, - plugin_config: None, dry_run: false, print: false, command: vec![], @@ -167,7 +161,6 @@ fn agent_with_passthrough_args_appends_to_configured_command() { openai_base_url: None, anthropic_base_url: None, session_metadata: None, - plugin_config: None, dry_run: false, print: false, command: vec!["--model".into(), "openai/openai/gpt-5.1-codex".into()], @@ -644,7 +637,6 @@ async fn run_starts_gateway_injects_env_and_returns_agent_exit_code() { openai_base_url: None, anthropic_base_url: None, session_metadata: None, - plugin_config: None, dry_run: false, print: false, command: command_argv, @@ -685,7 +677,6 @@ async fn dry_run_does_not_spawn_agent() { openai_base_url: None, anthropic_base_url: None, session_metadata: None, - plugin_config: None, dry_run: true, print: false, command: vec!["/path/that/does/not/exist".into()], diff --git a/docs/build-plugins/plugin-configuration-files.mdx b/docs/build-plugins/plugin-configuration-files.mdx index 866d80d92..30e236bfe 100644 --- a/docs/build-plugins/plugin-configuration-files.mdx +++ b/docs/build-plugins/plugin-configuration-files.mdx @@ -70,16 +70,14 @@ The gateway reads only files named `plugins.toml`. ## Discovery -The gateway can receive plugin configuration from three source classes: +The gateway can receive plugin configuration from two source classes: | Source | Use case | |---|---| | `plugins.toml` | Normal operator- and project-managed gateway plugin configuration. | | `[plugins].config` in `config.toml` | Inline gateway config for small or generated setups. | -| `--plugin-config ''` | CI, tests, wrappers, or one-off automation. | Use only one source class for a given gateway run. The gateway fails clearly if -file-based plugin config and `--plugin-config` are both present, or if `plugins.toml` and `[plugins].config` are both present. When `--config path/to/config.toml` is supplied, plugin file discovery is scoped @@ -253,8 +251,7 @@ installed by the plugin system. Keep long-lived plugin setup in `plugins.toml`. Use `[plugins].config` in `config.toml` only when a generated or embedded config must keep all gateway -settings in one file. Use `--plugin-config` for automation that should not write -files. +settings in one file. Legacy observability config sections in `config.toml`, such as `[exporters]`, `[observability]`, and `[export.openinference]`, are not supported. Configure