projects/guix·blob ruby-team · refs

302 lines · 9.3 KiB

1Author: Danny Milosavljevic <[email protected]>
2Date: 2026-07-11
3License: ASL2.0
4Subject: Disable V8 support in codex-code-mode.
5
6The V8 engine is only needed for actually executing JavaScript in the
7code-mode sandbox. Upstream's code-mode crate depends on v8 and
8deno_core_icudata unconditionally, and the V8 build downloads a large
9prebuilt archive at build time.
10
11Gate the V8-backed implementation behind a disabled "v8-runtime"
12feature, remove the unvendored V8 dependencies, and provide stub
13session providers.
14
15diff --git a/codex-rs/code-mode/Cargo.toml b/codex-rs/code-mode/Cargo.toml
16index 011fee6..4242afb 100644
17--- a/codex-rs/code-mode/Cargo.toml
18+++ b/codex-rs/code-mode/Cargo.toml
19@@ -10,7 +10,9 @@ name = "codex_code_mode"
20 path = "src/lib.rs"
21
22 [features]
23-sandbox = ["v8/v8_enable_sandbox"]
24+default = []
25+v8-runtime = []
26+sandbox = []
27
28 [lints]
29 workspace = true
30@@ -18,13 +20,11 @@ workspace = true
31 [dependencies]
32 codex-code-mode-protocol = { workspace = true }
33 codex-protocol = { workspace = true }
34-deno_core_icudata = { workspace = true }
35 futures = { workspace = true }
36 serde_json = { workspace = true }
37 tokio = { workspace = true, features = ["io-util", "macros", "process", "rt", "sync", "time"] }
38 tokio-util = { workspace = true, features = ["rt"] }
39 tracing = { workspace = true }
40-v8 = { workspace = true }
41
42 [dev-dependencies]
43 pretty_assertions = { workspace = true }
44diff --git a/codex-rs/code-mode/src/lib.rs b/codex-rs/code-mode/src/lib.rs
45index 6d332bf..b161369 100644
46--- a/codex-rs/code-mode/src/lib.rs
47+++ b/codex-rs/code-mode/src/lib.rs
48@@ -1,17 +1,254 @@
49+#[cfg(feature = "v8-runtime")]
50 mod cell_actor;
51+#[cfg(feature = "v8-runtime")]
52 mod remote_session;
53+#[cfg(feature = "v8-runtime")]
54 mod runtime;
55+#[cfg(feature = "v8-runtime")]
56 mod service;
57+#[cfg(feature = "v8-runtime")]
58 mod session_runtime;
59+#[cfg(feature = "v8-runtime")]
60 mod v8_init;
61
62+#[cfg(feature = "v8-runtime")]
63 pub(crate) type TaskFailureHandler = std::sync::Arc<dyn Fn(String) + Send + Sync>;
64
65 pub use codex_code_mode_protocol::*;
66+#[cfg(feature = "v8-runtime")]
67 pub use remote_session::ProcessOwnedCodeModeSession;
68+#[cfg(feature = "v8-runtime")]
69 pub use remote_session::ProcessOwnedCodeModeSessionProvider;
70+#[cfg(feature = "v8-runtime")]
71 pub use service::InProcessCodeModeSession;
72+#[cfg(feature = "v8-runtime")]
73 pub use service::InProcessCodeModeSessionProvider;
74+#[cfg(feature = "v8-runtime")]
75 pub use service::NoopCodeModeSessionDelegate;
76+#[cfg(feature = "v8-runtime")]
77 pub use v8_init::V8JitMode;
78+#[cfg(feature = "v8-runtime")]
79 pub use v8_init::initialize_v8;
80+
81+// Stubs used when the v8-runtime feature is disabled. Consumers that only
82+// touch the protocol types can build without pulling in v8. Calling
83+// execute/wait/terminate on a stub session returns an error.
84+#[cfg(not(feature = "v8-runtime"))]
85+mod stub {
86+ use std::path::PathBuf;
87+ use std::sync::Arc;
88+
89+ use codex_code_mode_protocol::{
90+ CellId, CodeModeSession, CodeModeSessionDelegate, CodeModeSessionProvider,
91+ CodeModeSessionProviderFuture, CodeModeSessionResultFuture, ExecuteRequest, StartedCell,
92+ WaitOutcome, WaitRequest,
93+ };
94+
95+ const DISABLED: &str = "code mode is disabled (built without v8-runtime)";
96+
97+ pub struct NoopCodeModeSessionDelegate;
98+
99+ impl CodeModeSessionDelegate for NoopCodeModeSessionDelegate {
100+ fn invoke_tool<'a>(
101+ &'a self,
102+ _invocation: codex_code_mode_protocol::CodeModeNestedToolCall,
103+ _cancellation_token: tokio_util::sync::CancellationToken,
104+ ) -> codex_code_mode_protocol::ToolInvocationFuture<'a> {
105+ Box::pin(async { Err(DISABLED.into()) })
106+ }
107+
108+ fn notify<'a>(
109+ &'a self,
110+ _call_id: String,
111+ _cell_id: CellId,
112+ _text: String,
113+ _cancellation_token: tokio_util::sync::CancellationToken,
114+ ) -> codex_code_mode_protocol::NotificationFuture<'a> {
115+ Box::pin(async { Ok(()) })
116+ }
117+
118+ fn cell_closed(&self, _cell_id: &CellId) {}
119+ }
120+
121+ #[derive(Default)]
122+ pub struct InProcessCodeModeSessionProvider;
123+
124+ impl CodeModeSessionProvider for InProcessCodeModeSessionProvider {
125+ fn create_session<'a>(
126+ &'a self,
127+ _delegate: Arc<dyn CodeModeSessionDelegate>,
128+ ) -> CodeModeSessionProviderFuture<'a> {
129+ Box::pin(async {
130+ let session: Arc<dyn CodeModeSession> = Arc::new(InProcessCodeModeSession);
131+ Ok(session)
132+ })
133+ }
134+ }
135+
136+ pub struct InProcessCodeModeSession;
137+
138+ impl InProcessCodeModeSession {
139+ pub fn new() -> Self {
140+ Self
141+ }
142+
143+ pub fn with_delegate(_delegate: Arc<dyn CodeModeSessionDelegate>) -> Self {
144+ Self
145+ }
146+
147+ pub fn with_delegate_and_task_failure_handler(
148+ _delegate: Arc<dyn CodeModeSessionDelegate>,
149+ _task_failure_handler: Arc<dyn Fn(String) + Send + Sync>,
150+ ) -> Self {
151+ Self
152+ }
153+
154+ pub async fn execute(&self, _request: ExecuteRequest) -> Result<StartedCell, String> {
155+ Err(DISABLED.into())
156+ }
157+
158+ pub async fn wait(&self, _request: WaitRequest) -> Result<WaitOutcome, String> {
159+ Err(DISABLED.into())
160+ }
161+
162+ pub async fn terminate(&self, _cell_id: CellId) -> Result<WaitOutcome, String> {
163+ Err(DISABLED.into())
164+ }
165+
166+ pub async fn shutdown(&self) -> Result<(), String> {
167+ Ok(())
168+ }
169+ }
170+
171+ impl Default for InProcessCodeModeSession {
172+ fn default() -> Self {
173+ Self::new()
174+ }
175+ }
176+
177+ impl CodeModeSession for InProcessCodeModeSession {
178+ fn execute<'a>(
179+ &'a self,
180+ request: ExecuteRequest,
181+ ) -> CodeModeSessionResultFuture<'a, StartedCell> {
182+ Box::pin(InProcessCodeModeSession::execute(self, request))
183+ }
184+
185+ fn wait<'a>(
186+ &'a self,
187+ request: WaitRequest,
188+ ) -> CodeModeSessionResultFuture<'a, WaitOutcome> {
189+ Box::pin(InProcessCodeModeSession::wait(self, request))
190+ }
191+
192+ fn terminate<'a>(
193+ &'a self,
194+ cell_id: CellId,
195+ ) -> CodeModeSessionResultFuture<'a, WaitOutcome> {
196+ Box::pin(InProcessCodeModeSession::terminate(self, cell_id))
197+ }
198+
199+ fn shutdown<'a>(&'a self) -> CodeModeSessionResultFuture<'a, ()> {
200+ Box::pin(InProcessCodeModeSession::shutdown(self))
201+ }
202+ }
203+
204+ #[derive(Default)]
205+ pub struct ProcessOwnedCodeModeSessionProvider;
206+
207+ impl ProcessOwnedCodeModeSessionProvider {
208+ pub fn with_host_program(_host_program: PathBuf) -> Self {
209+ Self
210+ }
211+ }
212+
213+ impl CodeModeSessionProvider for ProcessOwnedCodeModeSessionProvider {
214+ fn create_session<'a>(
215+ &'a self,
216+ _delegate: Arc<dyn CodeModeSessionDelegate>,
217+ ) -> CodeModeSessionProviderFuture<'a> {
218+ Box::pin(async {
219+ let session: Arc<dyn CodeModeSession> = Arc::new(ProcessOwnedCodeModeSession);
220+ Ok(session)
221+ })
222+ }
223+ }
224+
225+ pub struct ProcessOwnedCodeModeSession;
226+
227+ impl ProcessOwnedCodeModeSession {
228+ pub fn new() -> Self {
229+ Self
230+ }
231+
232+ pub async fn execute(&self, _request: ExecuteRequest) -> Result<StartedCell, String> {
233+ Err(DISABLED.into())
234+ }
235+
236+ pub async fn wait(&self, _request: WaitRequest) -> Result<WaitOutcome, String> {
237+ Err(DISABLED.into())
238+ }
239+
240+ pub async fn terminate(&self, _cell_id: CellId) -> Result<WaitOutcome, String> {
241+ Err(DISABLED.into())
242+ }
243+
244+ pub async fn shutdown(&self) -> Result<(), String> {
245+ Ok(())
246+ }
247+ }
248+
249+ impl Default for ProcessOwnedCodeModeSession {
250+ fn default() -> Self {
251+ Self::new()
252+ }
253+ }
254+
255+ impl CodeModeSession for ProcessOwnedCodeModeSession {
256+ fn execute<'a>(
257+ &'a self,
258+ request: ExecuteRequest,
259+ ) -> CodeModeSessionResultFuture<'a, StartedCell> {
260+ Box::pin(ProcessOwnedCodeModeSession::execute(self, request))
261+ }
262+
263+ fn wait<'a>(
264+ &'a self,
265+ request: WaitRequest,
266+ ) -> CodeModeSessionResultFuture<'a, WaitOutcome> {
267+ Box::pin(ProcessOwnedCodeModeSession::wait(self, request))
268+ }
269+
270+ fn terminate<'a>(
271+ &'a self,
272+ cell_id: CellId,
273+ ) -> CodeModeSessionResultFuture<'a, WaitOutcome> {
274+ Box::pin(ProcessOwnedCodeModeSession::terminate(self, cell_id))
275+ }
276+
277+ fn shutdown<'a>(&'a self) -> CodeModeSessionResultFuture<'a, ()> {
278+ Box::pin(ProcessOwnedCodeModeSession::shutdown(self))
279+ }
280+ }
281+
282+ pub enum V8JitMode {
283+ Enabled,
284+ Disabled,
285+ }
286+
287+ impl V8JitMode {
288+ pub fn as_str(&self) -> &'static str {
289+ match self {
290+ Self::Enabled => "enabled",
291+ Self::Disabled => "disabled",
292+ }
293+ }
294+ }
295+
296+ pub fn initialize_v8(_jit_mode: V8JitMode) -> Result<(), String> {
297+ Err(DISABLED.into())
298+ }
299+}
300+
301+#[cfg(not(feature = "v8-runtime"))]
302+pub use stub::*;