Conversation
a0b714e to
e4ea088
Compare
Co-authored-by: Codex <noreply@openai.com>
e4ea088 to
5cbeb96
Compare
| && exception.to_rust_string_lossy(scope) == EXIT_SENTINEL | ||
| } | ||
|
|
||
| pub(super) fn resolve_tool_response( |
There was a problem hiding this comment.
nit: this method almost doesn't fit in this file.
| } | ||
|
|
||
| #[derive(Debug, PartialEq)] | ||
| pub enum RuntimeResponse { |
| call_id: String, | ||
| text: String, | ||
| }, | ||
| Result { |
There was a problem hiding this comment.
There is some overlap between this and RuntimeResponse. Both have stored valis and notify.
There was a problem hiding this comment.
RuntimeEvent is js => code_mode
RuntimeResponse is code_mode => Core
I think there's a lot of overlap but I think we likely shouldn't coalesce these types.
| let _ = event_tx.send(RuntimeEvent::Result { | ||
| stored_values, | ||
| error_text: Some(error_text), | ||
| }); |
There was a problem hiding this comment.
can we extract the send error boilderplate?
There was a problem hiding this comment.
Maybe have normal rust error handling in inner method and outer method that has a single place to report errors.
There was a problem hiding this comment.
I like this idea, I'd like to think on it some more and maybe follow up.
| } | ||
| }; | ||
|
|
||
| match module_loader::completion_state(scope, pending_promise.as_ref()) { |
There was a problem hiding this comment.
do we need the pre-check or can we let the loop run and hit completion case naturally?
There was a problem hiding this comment.
Hmm, I think we need this in the cases where the script finished right away, since the loop is blocked on the command_rx.recv().
|
|
||
| let resolver = v8::Global::new(scope, resolver); | ||
| let Some(state) = scope.get_slot_mut::<RuntimeState>() else { | ||
| throw_type_error(scope, "runtime state unavailable"); |
There was a problem hiding this comment.
same nit about native rust error handling that turns into throw_type_error in one location. Maybe .map_err(throw_type_error) in the caller
| } else { | ||
| args.get(0) | ||
| }; | ||
| let text = match serialize_output_text(scope, value) { |
There was a problem hiding this comment.
Good question, do we serialize the argument here? Or do we expect text? Might make sense to align with text method as you did here.
| } | ||
|
|
||
| pub async fn replace_stored_values(&self, values: HashMap<String, JsonValue>) { | ||
| *self.inner.stored_values.lock().await = values; |
There was a problem hiding this comment.
nit for later. this should probably be merge.
|
|
||
| impl Drop for CodeModeTurnWorker { | ||
| fn drop(&mut self) { | ||
| if let Some(shutdown_tx) = self.shutdown_tx.take() { |
There was a problem hiding this comment.
do we want to join the task? or abort the task?
There was a problem hiding this comment.
bit worrysome to let it hang
There was a problem hiding this comment.
Yeah agreed. I think I probably need to have stricter lifecycle management for the Worker and channel. I need to think on it some.
| tokio::select! { | ||
| maybe_event = async { | ||
| if runtime_closed { | ||
| std::future::pending::<Option<RuntimeEvent>>().await |
There was a problem hiding this comment.
if runtime is closed what are we waiting for?
There was a problem hiding this comment.
If the runtime queue gets closed its possible that there was already a Result to be processed in our event_rx or if one was pending. We keep listening until the v8 thread resolves which it should quickly after we hit a terminate_execution on the handle.
Moves Code Mode to a new crate with no dependencies on codex. This create encodes the code mode semantics that we want for lifetime, mounting, tool calling.
The model-facing surface is mostly unchanged.
execstill runs raw JavaScript,waitstill resumes or terminates acell_id, nested tools are still available throughtools.*, and helpers liketext,image,store,load,notify,yield_control, andexitstill exist.The major change is underneath that surface:
exec.This PR also fixes the two migration regressions that fell out of that substrate change:
wait { terminate: true }now waits for the V8 runtime to actually stop before reporting termination.exit()now succeeds again instead of surfacing as a script error.core/src/tools/code_mode/*is now mostly an adapter layer for the publicexec/waittools.code-mode/src/service.rsowns cell sessions and async control flow in Rust.code-mode/src/runtime/*.rsowns the embedded V8 isolate and JavaScript execution.execspawns a dedicated runtime thread plus a Rust session-control task.tools.jsand@openai/code_modeare synthesized through V8 module resolution callbacks in Rust.Also added a benchmark for showing the speed of init and use of a code mode env: