44from __future__ import annotations
55
66import argparse
7+ import re
78import subprocess # nosec B404
89import sys
910import tempfile
1011from pathlib import Path
1112
1213SUBPROCESS_TIMEOUT_SECONDS = 300
14+ EXTRA_PROTOCOL_SCHEMA_FILES = (
15+ # Response-only schemas are not reachable from the ClientRequest/
16+ # ServerRequest/ServerNotification envelope, but they are part of the
17+ # app-server protocol and are used by the SDK's typed RPC result models.
18+ "v2/ListMcpServerStatusResponse.json" ,
19+ )
1320
1421
1522def parse_args () -> argparse .Namespace :
@@ -100,6 +107,52 @@ def generate_protocol_models(*, schema_path: Path, output_path: Path) -> None:
100107 )
101108
102109
110+ def extract_generated_model_definitions (text : str ) -> str :
111+ lines = text .splitlines ()
112+ for index , line in enumerate (lines ):
113+ if line .startswith ("class " ):
114+ return "\n " .join (lines [index :]).strip () + "\n "
115+ raise ValueError ("generated model file does not contain any class definitions" )
116+
117+
118+ def append_generated_model_definitions (* , target_path : Path , generated_path : Path ) -> None :
119+ target = target_path .read_text (encoding = "utf-8" )
120+ definitions = extract_generated_model_definitions (
121+ generated_path .read_text (encoding = "utf-8" )
122+ ).rstrip ()
123+ target_lines = target .splitlines ()
124+ insert_at = next (
125+ (
126+ index
127+ for index , line in enumerate (target_lines )
128+ if re .match (r"^\w+\.model_rebuild\(\)\s*$" , line )
129+ ),
130+ len (target_lines ),
131+ )
132+
133+ updated = (
134+ "\n " .join (target_lines [:insert_at ]).rstrip ()
135+ + "\n \n "
136+ + definitions
137+ + "\n \n "
138+ + "\n " .join (target_lines [insert_at :]).lstrip ()
139+ ).rstrip ()
140+ target_path .write_text (updated + "\n " , encoding = "utf-8" )
141+
142+
143+ def append_extra_protocol_models (* , schema_dir : Path , output_path : Path ) -> None :
144+ with tempfile .TemporaryDirectory (prefix = "codex-extra-protocol-models-" ) as temp_dir :
145+ temp_path = Path (temp_dir )
146+ for relative_schema_path in EXTRA_PROTOCOL_SCHEMA_FILES :
147+ schema_path = schema_dir / relative_schema_path
148+ generated_path = temp_path / f"{ schema_path .stem } .py"
149+ generate_protocol_models (schema_path = schema_path , output_path = generated_path )
150+ append_generated_model_definitions (
151+ target_path = output_path ,
152+ generated_path = generated_path ,
153+ )
154+
155+
103156def build_postprocess_command (* , output_path : Path ) -> list [str ]:
104157 return [sys .executable , "scripts/postprocess_protocol_types.py" , str (output_path )]
105158
@@ -124,6 +177,7 @@ def main() -> int:
124177 experimental = args .experimental ,
125178 )
126179 generate_protocol_models (schema_path = schema_path , output_path = output_path )
180+ append_extra_protocol_models (schema_dir = schema_dir , output_path = output_path )
127181
128182 postprocess_protocol_models (output_path )
129183 return 0
0 commit comments