diff --git a/.github/workflows/rust-ci.yml b/.github/workflows/rust-ci.yml index ad1aa565f0..bd27de60a8 100644 --- a/.github/workflows/rust-ci.yml +++ b/.github/workflows/rust-ci.yml @@ -65,26 +65,6 @@ jobs: - name: cargo fmt run: cargo fmt -- --config imports_granularity=Item --check - schema_fixtures: - name: App-server schema fixtures - runs-on: ubuntu-24.04 - needs: changed - if: ${{ needs.changed.outputs.codex == 'true' || needs.changed.outputs.workflows == 'true' || github.event_name == 'push' }} - defaults: - run: - working-directory: codex-rs - steps: - - uses: actions/checkout@v6 - - uses: actions/setup-python@v6 - with: - python-version: "3.11" - - uses: astral-sh/setup-uv@v6 - - uses: dtolnay/rust-toolchain@1.93.0 - - name: Regenerate app-server schema fixtures - run: cargo run -p codex-app-server-protocol --bin write_schema_fixtures - - name: Check vendored schema fixtures are up to date - run: git diff --exit-code -- app-server-protocol/schema - cargo_shear: name: cargo shear runs-on: ubuntu-24.04 diff --git a/codex-rs/app-server-protocol/src/export.rs b/codex-rs/app-server-protocol/src/export.rs index cd857e97e2..4bf88e047a 100644 --- a/codex-rs/app-server-protocol/src/export.rs +++ b/codex-rs/app-server-protocol/src/export.rs @@ -298,11 +298,13 @@ pub fn generate_python_with_options( let mut root_schema = build_python_root_schema(&bundle)?; normalize_python_integer_formats(&mut root_schema); rename_python_envelope_titles(&mut root_schema); + root_schema = sort_json_object_keys(root_schema); write_pretty_json(root_schema_path.clone(), &root_schema)?; let v2_schema_path = temp_json_dir.join("codex_app_server_protocol.v2.schemas.json"); let mut v2_schema = read_json_value(&v2_schema_path)?; normalize_python_integer_formats(&mut v2_schema); rename_python_envelope_titles(&mut v2_schema); + v2_schema = sort_json_object_keys(v2_schema); write_pretty_json(v2_schema_path.clone(), &v2_schema)?; let module_dir = out_dir.join(PYTHON_MODULE_NAME); @@ -1457,6 +1459,22 @@ fn schema_is_integer(map: &serde_json::Map) -> bool { } } +fn sort_json_object_keys(value: Value) -> Value { + match value { + Value::Array(items) => Value::Array(items.into_iter().map(sort_json_object_keys).collect()), + Value::Object(map) => { + let mut entries = map.into_iter().collect::>(); + entries.sort_by(|(left, _), (right, _)| left.cmp(right)); + let sorted = entries + .into_iter() + .map(|(key, value)| (key, sort_json_object_keys(value))) + .collect(); + Value::Object(sorted) + } + Value::Null | Value::Bool(_) | Value::Number(_) | Value::String(_) => value, + } +} + fn rename_union_titles( bundle: &mut Value, definition_name: &str,