Files
codex/codex-rs/tools/src/js_repl_tool.rs
Vivian Fang ea516f9a40 Support anyOf and enum in JsonSchema (#16875)
This brings us into better alignment with the JSON schema subset that is
supported in
<https://developers.openai.com/api/docs/guides/structured-outputs#supported-schemas>,
and also allows us to render richer function signatures in code mode
(e.g., anyOf{null, OtherObjectType})
2026-04-08 01:07:55 -07:00

56 lines
2.0 KiB
Rust

use crate::FreeformTool;
use crate::FreeformToolFormat;
use crate::JsonSchema;
use crate::ResponsesApiTool;
use crate::ToolSpec;
use std::collections::BTreeMap;
pub fn create_js_repl_tool() -> ToolSpec {
// Keep JS input freeform, but block the most common malformed payload shapes
// (JSON wrappers, quoted strings, and markdown fences) before they reach the
// runtime `reject_json_or_quoted_source` validation. The API's regex engine
// does not support look-around, so this uses a "first significant token"
// pattern rather than negative lookaheads.
const JS_REPL_FREEFORM_GRAMMAR: &str = r#"
start: pragma_source | plain_source
pragma_source: PRAGMA_LINE NEWLINE js_source
plain_source: PLAIN_JS_SOURCE
js_source: JS_SOURCE
PRAGMA_LINE: /[ \t]*\/\/ codex-js-repl:[^\r\n]*/
NEWLINE: /\r?\n/
PLAIN_JS_SOURCE: /(?:\s*)(?:[^\s{\"`]|`[^`]|``[^`])[\s\S]*/
JS_SOURCE: /(?:\s*)(?:[^\s{\"`]|`[^`]|``[^`])[\s\S]*/
"#;
ToolSpec::Freeform(FreeformTool {
name: "js_repl".to_string(),
description: "Runs JavaScript in a persistent Node kernel with top-level await. This is a freeform tool: send raw JavaScript source text, optionally with a first-line pragma like `// codex-js-repl: timeout_ms=15000`; do not send JSON/quotes/markdown fences."
.to_string(),
format: FreeformToolFormat {
r#type: "grammar".to_string(),
syntax: "lark".to_string(),
definition: JS_REPL_FREEFORM_GRAMMAR.to_string(),
},
})
}
pub fn create_js_repl_reset_tool() -> ToolSpec {
ToolSpec::Function(ResponsesApiTool {
name: "js_repl_reset".to_string(),
description:
"Restarts the js_repl kernel for this run and clears persisted top-level bindings."
.to_string(),
strict: false,
defer_loading: None,
parameters: JsonSchema::object(BTreeMap::new(), /*required*/ None, Some(false.into())),
output_schema: None,
})
}
#[cfg(test)]
#[path = "js_repl_tool_tests.rs"]
mod tests;