diff --git a/codex-rs/app-server-protocol/schema/json/ServerNotification.json b/codex-rs/app-server-protocol/schema/json/ServerNotification.json index 7846a395e..558f4f0fa 100644 --- a/codex-rs/app-server-protocol/schema/json/ServerNotification.json +++ b/codex-rs/app-server-protocol/schema/json/ServerNotification.json @@ -996,6 +996,8 @@ } }, "required": [ + "path", + "range", "summary" ], "type": "object" diff --git a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json index 3e83d4045..40ab3fb07 100644 --- a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json +++ b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json @@ -10085,6 +10085,8 @@ } }, "required": [ + "path", + "range", "summary" ], "title": "ConfigWarningNotification", diff --git a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json index 6bb9270fb..79e7daded 100644 --- a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json +++ b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json @@ -6455,6 +6455,8 @@ } }, "required": [ + "path", + "range", "summary" ], "title": "ConfigWarningNotification", diff --git a/codex-rs/app-server-protocol/schema/json/v2/ConfigWarningNotification.json b/codex-rs/app-server-protocol/schema/json/v2/ConfigWarningNotification.json index c89e42a2b..3cff56464 100644 --- a/codex-rs/app-server-protocol/schema/json/v2/ConfigWarningNotification.json +++ b/codex-rs/app-server-protocol/schema/json/v2/ConfigWarningNotification.json @@ -70,6 +70,8 @@ } }, "required": [ + "path", + "range", "summary" ], "title": "ConfigWarningNotification", diff --git a/codex-rs/app-server-protocol/schema/typescript/v2/ConfigWarningNotification.ts b/codex-rs/app-server-protocol/schema/typescript/v2/ConfigWarningNotification.ts index e0cdf392d..ffcf6d87c 100644 --- a/codex-rs/app-server-protocol/schema/typescript/v2/ConfigWarningNotification.ts +++ b/codex-rs/app-server-protocol/schema/typescript/v2/ConfigWarningNotification.ts @@ -15,8 +15,8 @@ details: string | null, /** * Optional path to the config file that triggered the warning. */ -path?: string, +path: string | null, /** * Optional range for the error location inside the config file. */ -range?: TextRange, }; +range: TextRange | null, }; diff --git a/codex-rs/app-server-protocol/src/protocol/v2/config.rs b/codex-rs/app-server-protocol/src/protocol/v2/config.rs index c4fc1a6e7..dfbaa850e 100644 --- a/codex-rs/app-server-protocol/src/protocol/v2/config.rs +++ b/codex-rs/app-server-protocol/src/protocol/v2/config.rs @@ -13,9 +13,12 @@ use codex_protocol::config_types::WebSearchToolConfig; use codex_protocol::openai_models::ReasoningEffort; use codex_utils_absolute_path::AbsolutePathBuf; use schemars::JsonSchema; +use schemars::r#gen::SchemaGenerator; +use schemars::schema::Schema; use serde::Deserialize; use serde::Serialize; use serde_json::Value as JsonValue; +use std::borrow::Cow; use std::collections::BTreeMap; use std::collections::HashMap; use std::path::PathBuf; @@ -731,6 +734,32 @@ pub struct TextRange { pub end: TextPosition, } +struct RequiredNullable(std::marker::PhantomData); + +impl JsonSchema for RequiredNullable +where + Option: JsonSchema, +{ + fn is_referenceable() -> bool { + false + } + + fn schema_name() -> String { + format!( + "RequiredNullable_for_{}", + as JsonSchema>::schema_name() + ) + } + + fn schema_id() -> Cow<'static, str> { + Cow::Owned(Self::schema_name()) + } + + fn json_schema(generator: &mut SchemaGenerator) -> Schema { + as JsonSchema>::json_schema(generator) + } +} + #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] @@ -740,11 +769,9 @@ pub struct ConfigWarningNotification { /// Optional extra guidance or error details. pub details: Option, /// Optional path to the config file that triggered the warning. - #[serde(default, skip_serializing_if = "Option::is_none")] - #[ts(optional)] + #[schemars(with = "RequiredNullable", required)] pub path: Option, /// Optional range for the error location inside the config file. - #[serde(default, skip_serializing_if = "Option::is_none")] - #[ts(optional)] + #[schemars(with = "RequiredNullable", required)] pub range: Option, } diff --git a/codex-rs/app-server/README.md b/codex-rs/app-server/README.md index a341bddd5..48cc2c68c 100644 --- a/codex-rs/app-server/README.md +++ b/codex-rs/app-server/README.md @@ -1689,7 +1689,7 @@ Event notifications are the server-initiated event stream for thread lifecycles, Thread realtime uses a separate thread-scoped notification surface. `thread/realtime/*` notifications are ephemeral transport events, not `ThreadItem`s, and are not returned by `thread/read`, `thread/resume`, or `thread/fork`. -Recoverable configuration and initialization warnings use the existing `configWarning` notification: `{ summary, details?, path?, range? }`. App-server may emit it during initialization for config parsing and related setup diagnostics. +Recoverable configuration and initialization warnings use the existing `configWarning` notification: `{ summary, details, path, range }`, where nullable fields are present as `null`. App-server may emit it during initialization for config parsing and related setup diagnostics. Generic runtime warnings use the `warning` notification: `{ threadId?, message }`. App-server emits this for non-fatal warnings from the core event stream, including cases where not all enabled skills are included in the model-visible skills list for a session. diff --git a/codex-rs/app-server/src/outgoing_message.rs b/codex-rs/app-server/src/outgoing_message.rs index 57cf5a925..f12f1e7a4 100644 --- a/codex-rs/app-server/src/outgoing_message.rs +++ b/codex-rs/app-server/src/outgoing_message.rs @@ -874,6 +874,8 @@ mod tests { "params": { "summary": "Config error: using defaults", "details": "error loading config: bad config", + "path": null, + "range": null, }, }), serde_json::to_value(jsonrpc_notification)