wip fix for schemars issue

This commit is contained in:
Sayan Sisodiya
2026-01-10 02:15:16 -08:00
parent 6b4f6d2e7f
commit 4cf0f06ef5
6 changed files with 885 additions and 415 deletions
File diff suppressed because it is too large Load Diff
+27 -39
View File
@@ -1,61 +1,49 @@
use crate::config::ConfigToml;
use crate::config::types::RawMcpServerConfig;
use crate::features::FEATURES;
use schemars::r#gen::SchemaGenerator;
use schemars::r#gen::SchemaSettings;
use schemars::schema::InstanceType;
use schemars::schema::ObjectValidation;
use schemars::schema::RootSchema;
use schemars::schema::Schema;
use schemars::schema::SchemaObject;
use schemars::Schema;
use schemars::SchemaGenerator;
use schemars::generate::SchemaSettings;
use serde_json::Map;
use serde_json::Value;
use std::path::Path;
/// Schema for the `[features]` map with known + legacy keys only.
pub(crate) fn features_schema(schema_gen: &mut SchemaGenerator) -> Schema {
let mut object = SchemaObject {
instance_type: Some(InstanceType::Object.into()),
..Default::default()
};
let mut validation = ObjectValidation::default();
let mut properties = Map::new();
for feature in FEATURES {
validation
.properties
.insert(feature.key.to_string(), schema_gen.subschema_for::<bool>());
properties.insert(
feature.key.to_string(),
schema_gen.subschema_for::<bool>().to_value(),
);
}
for legacy_key in crate::features::legacy_feature_keys() {
validation
.properties
.insert(legacy_key.to_string(), schema_gen.subschema_for::<bool>());
properties.insert(
legacy_key.to_string(),
schema_gen.subschema_for::<bool>().to_value(),
);
}
validation.additional_properties = Some(Box::new(Schema::Bool(false)));
object.object = Some(Box::new(validation));
Schema::Object(object)
let mut schema = Map::new();
schema.insert("type".into(), Value::String("object".into()));
schema.insert("properties".into(), Value::Object(properties));
schema.insert("additionalProperties".into(), Value::Bool(false));
schema.into()
}
/// Schema for the `[mcp_servers]` map using the raw input shape.
pub(crate) fn mcp_servers_schema(schema_gen: &mut SchemaGenerator) -> Schema {
let mut object = SchemaObject {
instance_type: Some(InstanceType::Object.into()),
..Default::default()
};
let validation = ObjectValidation {
additional_properties: Some(Box::new(schema_gen.subschema_for::<RawMcpServerConfig>())),
..Default::default()
};
object.object = Some(Box::new(validation));
Schema::Object(object)
let mut schema = Map::new();
schema.insert("type".into(), Value::String("object".into()));
schema.insert(
"additionalProperties".into(),
schema_gen.subschema_for::<RawMcpServerConfig>().to_value(),
);
schema.into()
}
/// Build the config schema for `config.toml`.
pub fn config_schema() -> RootSchema {
pub fn config_schema() -> Schema {
SchemaSettings::draft07()
.with(|settings| {
settings.option_add_null_type = false;
})
.into_generator()
.into_root_schema_for::<ConfigToml>()
}
+2 -1
View File
@@ -290,7 +290,8 @@ pub struct AnalyticsConfigToml {
pub enabled: Option<bool>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default)]
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default, JsonSchema)]
#[schemars(deny_unknown_fields)]
pub struct FeedbackConfigToml {
/// When `false`, disables the feedback flow across Codex product surfaces.
pub enabled: Option<bool>,
+44 -17
View File
@@ -8,7 +8,7 @@ use codex_utils_json_to_toml::json_to_toml;
use mcp_types::Tool;
use mcp_types::ToolInputSchema;
use schemars::JsonSchema;
use schemars::r#gen::SchemaSettings;
use schemars::generate::SchemaSettings;
use serde::Deserialize;
use serde::Serialize;
use std::collections::HashMap;
@@ -108,7 +108,6 @@ pub(crate) fn create_tool_for_codex_tool_call_param() -> Tool {
let schema = SchemaSettings::draft2019_09()
.with(|s| {
s.inline_subschemas = true;
s.option_add_null_type = false;
})
.into_generator()
.into_root_schema_for::<CodexToolCallParam>();
@@ -197,7 +196,6 @@ pub(crate) fn create_tool_for_codex_tool_call_reply_param() -> Tool {
let schema = SchemaSettings::draft2019_09()
.with(|s| {
s.inline_subschemas = true;
s.option_add_null_type = false;
})
.into_generator()
.into_root_schema_for::<CodexToolCallReplyParam>();
@@ -249,43 +247,68 @@ mod tests {
"inputSchema": {
"properties": {
"approval-policy": {
"description": "Approval policy for shell commands generated by the model: `untrusted`, `on-failure`, `on-request`, `never`.",
"description": "Approval policy for shell commands generated by the model:\n`untrusted`, `on-failure`, `on-request`, `never`.",
"enum": [
"untrusted",
"on-failure",
"on-request",
"never"
"never",
null
],
"type": "string"
"type": [
"string",
"null"
]
},
"base-instructions": {
"description": "The set of instructions to use instead of the default ones.",
"type": "string"
"type": [
"string",
"null"
]
},
"compact-prompt": {
"description": "Prompt used when compacting the conversation.",
"type": "string"
"type": [
"string",
"null"
]
},
"config": {
"additionalProperties": true,
"description": "Individual config settings that will override what is in CODEX_HOME/config.toml.",
"type": "object"
"description": "Individual config settings that will override what is in\nCODEX_HOME/config.toml.",
"type": [
"object",
"null"
]
},
"cwd": {
"description": "Working directory for the session. If relative, it is resolved against the server process's current working directory.",
"type": "string"
"description": "Working directory for the session. If relative, it is resolved against\nthe server process's current working directory.",
"type": [
"string",
"null"
]
},
"developer-instructions": {
"description": "Developer instructions that should be injected as a developer role message.",
"type": "string"
"type": [
"string",
"null"
]
},
"model": {
"description": "Optional override for the model name (e.g. 'gpt-5.2', 'gpt-5.2-codex').",
"type": "string"
"type": [
"string",
"null"
]
},
"profile": {
"description": "Configuration profile from config.toml to specify default options.",
"type": "string"
"type": [
"string",
"null"
]
},
"prompt": {
"description": "The *initial user prompt* to start the Codex conversation.",
@@ -296,9 +319,13 @@ mod tests {
"enum": [
"read-only",
"workspace-write",
"danger-full-access"
"danger-full-access",
null
],
"type": "string"
"type": [
"string",
"null"
]
}
},
"required": [
+5 -4
View File
@@ -1,8 +1,9 @@
use std::borrow::Cow;
use std::fmt::Display;
use schemars::JsonSchema;
use schemars::r#gen::SchemaGenerator;
use schemars::schema::Schema;
use schemars::Schema;
use schemars::SchemaGenerator;
use serde::Deserialize;
use serde::Serialize;
use ts_rs::TS;
@@ -61,8 +62,8 @@ impl<'de> Deserialize<'de> for ThreadId {
}
impl JsonSchema for ThreadId {
fn schema_name() -> String {
"ThreadId".to_string()
fn schema_name() -> Cow<'static, str> {
"ThreadId".into()
}
fn json_schema(generator: &mut SchemaGenerator) -> Schema {