Skip to content

Commit 2e51107

Browse files
chore(sdk/native): bump to 0.0.9 and refactor native bindings
- Version bump to 0.0.9 with updated optional dependencies - Remove strip=symbols from Cargo.toml release profile - Refactor nativeBinding.ts for improved platform resolution - Update run.rs rust bindings - Add model presets for codex-rs core - Add consumer example for sdk testing Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 7350608 commit 2e51107

14 files changed

Lines changed: 360 additions & 196 deletions

File tree

‎codex-rs/core/src/models_manager/model_presets.rs‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,9 @@ static PRESETS: Lazy<Vec<ModelPreset>> = Lazy::new(|| {
308308
]
309309
});
310310

311+
static SUPPORTED_MODEL_SLUGS: Lazy<Vec<String>> =
312+
Lazy::new(|| PRESETS.iter().map(|preset| preset.model.clone()).collect());
313+
311314
fn gpt_52_codex_upgrade() -> ModelUpgrade {
312315
ModelUpgrade {
313316
id: "gpt-5.2-codex".to_string(),
@@ -325,6 +328,10 @@ pub(super) fn builtin_model_presets(_auth_mode: Option<AuthMode>) -> Vec<ModelPr
325328
PRESETS.iter().cloned().collect()
326329
}
327330

331+
pub fn supported_model_slugs() -> &'static [String] {
332+
&SUPPORTED_MODEL_SLUGS
333+
}
334+
328335
#[cfg(any(test, feature = "test-support"))]
329336
pub fn all_model_presets() -> &'static Vec<ModelPreset> {
330337
&PRESETS

‎pnpm-lock.yaml‎

Lines changed: 27 additions & 23 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎sdk/native/Cargo.toml‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,6 @@ napi-bindings = ["napi", "napi-derive"]
9191

9292
[profile.release]
9393
lto = true
94-
strip = "symbols"
9594

9695
# The upstream crates have not yet released the fixes required for the Codex TUI:
9796
# - ratatui: pending patch to expose color/style APIs needed by codex-tui
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Native SDK Consumer Example
2+
3+
This folder is a minimal consumer that installs `@codex-native/sdk` and loads it as a dependency.
4+
5+
## Usage
6+
7+
1. Install deps:
8+
9+
```sh
10+
pnpm install
11+
```
12+
13+
2. Run the smoke script:
14+
15+
```sh
16+
pnpm start
17+
```
18+
19+
If you want to test a published version, update the dependency in `package.json`.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { Codex } from "@codex-native/sdk";
2+
3+
console.log("Codex export:", typeof Codex);
4+
const instance = new Codex();
5+
console.log("Codex instance created:", Boolean(instance));
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"name": "@codex-native/examples-consumer",
3+
"private": true,
4+
"type": "module",
5+
"scripts": {
6+
"start": "node index.mjs"
7+
},
8+
"dependencies": {
9+
"@codex-native/sdk": "file:../.."
10+
}
11+
}

‎sdk/native/index.js‎

Lines changed: 52 additions & 52 deletions
Large diffs are not rendered by default.

‎sdk/native/package.json‎

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@codex-native/sdk",
3-
"version": "0.0.8",
3+
"version": "0.0.9",
44
"description": "Native NAPI-based Codex SDK - complete standalone implementation.",
55
"main": "dist/index.cjs",
66
"module": "dist/index.mjs",
@@ -77,14 +77,14 @@
7777
]
7878
},
7979
"optionalDependencies": {
80-
"@codex-native/sdk-darwin-arm64": "0.0.8",
81-
"@codex-native/sdk-darwin-x64": "0.0.8",
82-
"@codex-native/sdk-linux-arm64-gnu": "0.0.8",
83-
"@codex-native/sdk-linux-x64-gnu": "0.0.8",
84-
"@codex-native/sdk-linux-arm64-musl": "0.0.8",
85-
"@codex-native/sdk-linux-x64-musl": "0.0.8",
86-
"@codex-native/sdk-win32-arm64-msvc": "0.0.8",
87-
"@codex-native/sdk-win32-x64-msvc": "0.0.8"
80+
"@codex-native/sdk-darwin-arm64": "0.0.9",
81+
"@codex-native/sdk-darwin-x64": "0.0.9",
82+
"@codex-native/sdk-linux-arm64-gnu": "0.0.9",
83+
"@codex-native/sdk-linux-x64-gnu": "0.0.9",
84+
"@codex-native/sdk-linux-arm64-musl": "0.0.9",
85+
"@codex-native/sdk-linux-x64-musl": "0.0.9",
86+
"@codex-native/sdk-win32-arm64-msvc": "0.0.9",
87+
"@codex-native/sdk-win32-x64-msvc": "0.0.9"
8888
},
8989
"engines": {
9090
"node": ">=18"

‎sdk/native/rust-bindings/run.rs‎

Lines changed: 42 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,42 @@ pub struct InternalRunRequest {
223223
pub full_auto: bool,
224224
}
225225

226+
fn supported_hosted_models_list() -> String {
227+
codex_core::models_manager::model_presets::supported_model_slugs()
228+
.iter()
229+
.map(|model| format!("\"{model}\""))
230+
.collect::<Vec<_>>()
231+
.join(", ")
232+
}
233+
234+
fn is_supported_hosted_model(model: &str) -> bool {
235+
codex_core::models_manager::model_presets::supported_model_slugs()
236+
.iter()
237+
.any(|supported| supported == model)
238+
}
239+
240+
fn validate_model_name(model: Option<&str>, oss: bool) -> napi::Result<()> {
241+
let Some(model_name) = model else {
242+
return Ok(());
243+
};
244+
245+
let trimmed = model_name.trim();
246+
if oss && !trimmed.starts_with("gpt-oss:") {
247+
return Err(napi::Error::from_reason(format!(
248+
"Invalid model \"{trimmed}\" for OSS mode. Use models prefixed with \"gpt-oss:\", e.g. \"gpt-oss:20b\"."
249+
)));
250+
}
251+
252+
if !oss && !is_supported_hosted_model(trimmed) {
253+
return Err(napi::Error::from_reason(format!(
254+
"Invalid model \"{trimmed}\". Supported models are {}.",
255+
supported_hosted_models_list()
256+
)));
257+
}
258+
259+
Ok(())
260+
}
261+
226262
impl ConversationConfigRequest {
227263
fn into_internal_request(self) -> napi::Result<InternalRunRequest> {
228264
let sandbox_mode = parse_sandbox_mode(self.sandbox_mode.as_deref())?;
@@ -294,20 +330,7 @@ impl RunRequest {
294330
None => None,
295331
};
296332

297-
if let Some(model_name) = self.model.as_deref() {
298-
let trimmed = model_name.trim();
299-
if self.oss.unwrap_or(false) {
300-
if !trimmed.starts_with("gpt-oss:") {
301-
return Err(napi::Error::from_reason(format!(
302-
"Invalid model \"{trimmed}\" for OSS mode. Use models prefixed with \"gpt-oss:\", e.g. \"gpt-oss:20b\"."
303-
)));
304-
}
305-
} else if trimmed != "gpt-5" && trimmed != "gpt-5-codex" && trimmed != "gpt-5-codex-mini" && trimmed != "gpt-5.1" && trimmed != "gpt-5.1-codex" && trimmed != "gpt-5.1-codex-mini" && trimmed != "gpt-5.1-codex-max" {
306-
return Err(napi::Error::from_reason(format!(
307-
"Invalid model \"{trimmed}\". Supported models are \"gpt-5\", \"gpt-5-codex\", \"gpt-5-codex-mini\", \"gpt-5.1\", \"gpt-5.1-codex\", \"gpt-5.1-codex-mini\", or \"gpt-5.1-codex-max\"."
308-
)));
309-
}
310-
}
333+
validate_model_name(self.model.as_deref(), self.oss.unwrap_or(false))?;
311334

312335
Ok(InternalRunRequest {
313336
prompt: self.prompt,
@@ -1597,4 +1620,9 @@ mod tests_run {
15971620
let parsed = parse_reasoning_effort(Some("xhigh")).expect("parse succeeds");
15981621
assert_eq!(parsed, Some(ReasoningEffort::High));
15991622
}
1623+
1624+
#[test]
1625+
fn accepts_gpt_5_2_codex_model() {
1626+
assert!(validate_model_name(Some("gpt-5.2-codex"), false).is_ok());
1627+
}
16001628
}

‎sdk/native/src/agents/CodexProvider.ts‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ export interface CodexProviderOptions extends CodexOptions {
8787
* import { CodexProvider } from '@openai/codex-native/agents';
8888
* import { Agent, Runner } from '@openai/agents';
8989
*
90-
* defaultModel: 'gpt-5-codex'
90+
* const provider = new CodexProvider({
91+
* defaultModel: 'gpt-5.2-codex'
9192
* });
9293
*
9394
* const agent = new Agent({

0 commit comments

Comments
 (0)