Download codex-rs/code-mode-runtime/src/service_contract_tests.rs from SaylorTwift/codex: direct link, hf CLI and curl.
- Browser
- Download file 19 kB
-
https://huggingface.co/SaylorTwift/codex/resolve/main/codex-rs/code-mode-runtime/src/service_contract_tests.rs
- Command line
-
hf download hf://SaylorTwift/codex/codex-rs/code-mode-runtime/src/service_contract_tests.rs
-
curl -L -o service_contract_tests.rs https://huggingface.co/SaylorTwift/codex/resolve/main/codex-rs/code-mode-runtime/src/service_contract_tests.rs
19 kB
| use codex_code_mode_protocol::NoopCodeModeSessionDelegate; | |
| use std::sync::Arc; | |
| use std::sync::atomic::AtomicBool; | |
| use std::sync::atomic::Ordering; | |
| use std::time::Duration; | |
| use codex_code_mode_protocol::NotificationFuture; | |
| use codex_code_mode_protocol::ToolInvocationFuture; | |
| use codex_protocol::ToolName; | |
| use pretty_assertions::assert_eq; | |
| use tokio::sync::Notify; | |
| use tokio::sync::mpsc; | |
| use tokio_util::sync::CancellationToken; | |
| use super::*; | |
| use crate::CodeModeToolKind; | |
| use crate::ToolDefinition; | |
| enum DelegateEvent { | |
| NotificationStarted, | |
| NotificationCancelled, | |
| ToolStarted, | |
| ToolCancelled, | |
| CellClosed(CellId), | |
| } | |
| struct BlockingDelegate { | |
| events_tx: mpsc::UnboundedSender<DelegateEvent>, | |
| notification_finished: AtomicBool, | |
| tool_finished: AtomicBool, | |
| tool_release: Notify, | |
| } | |
| struct HeldNotificationDelegate { | |
| events_tx: mpsc::UnboundedSender<DelegateEvent>, | |
| notification_release: Notify, | |
| } | |
| impl HeldNotificationDelegate { | |
| fn new() -> (Arc<Self>, mpsc::UnboundedReceiver<DelegateEvent>) { | |
| let (events_tx, events_rx) = mpsc::unbounded_channel(); | |
| ( | |
| Arc::new(Self { | |
| events_tx, | |
| notification_release: Notify::new(), | |
| }), | |
| events_rx, | |
| ) | |
| } | |
| fn release_notification(&self) { | |
| self.notification_release.notify_one(); | |
| } | |
| } | |
| impl CodeModeSessionDelegate for HeldNotificationDelegate { | |
| fn invoke_tool<'a>( | |
| &'a self, | |
| _invocation: CodeModeNestedToolCall, | |
| cancellation_token: CancellationToken, | |
| ) -> ToolInvocationFuture<'a> { | |
| Box::pin(async move { | |
| cancellation_token.cancelled().await; | |
| Err("cancelled".to_string()) | |
| }) | |
| } | |
| fn notify<'a>( | |
| &'a self, | |
| _call_id: String, | |
| _cell_id: CellId, | |
| _text: String, | |
| cancellation_token: CancellationToken, | |
| ) -> NotificationFuture<'a> { | |
| Box::pin(async move { | |
| let _ = self.events_tx.send(DelegateEvent::NotificationStarted); | |
| cancellation_token.cancelled().await; | |
| let _ = self.events_tx.send(DelegateEvent::NotificationCancelled); | |
| self.notification_release.notified().await; | |
| Ok(()) | |
| }) | |
| } | |
| fn cell_closed(&self, cell_id: &CellId) { | |
| let _ = self | |
| .events_tx | |
| .send(DelegateEvent::CellClosed(cell_id.clone())); | |
| } | |
| } | |
| impl BlockingDelegate { | |
| fn new() -> (Arc<Self>, mpsc::UnboundedReceiver<DelegateEvent>) { | |
| let (events_tx, events_rx) = mpsc::unbounded_channel(); | |
| ( | |
| Arc::new(Self { | |
| events_tx, | |
| notification_finished: AtomicBool::new(false), | |
| tool_finished: AtomicBool::new(false), | |
| tool_release: Notify::new(), | |
| }), | |
| events_rx, | |
| ) | |
| } | |
| fn release_tool(&self) { | |
| self.tool_release.notify_one(); | |
| } | |
| } | |
| impl CodeModeSessionDelegate for BlockingDelegate { | |
| fn invoke_tool<'a>( | |
| &'a self, | |
| _invocation: CodeModeNestedToolCall, | |
| cancellation_token: CancellationToken, | |
| ) -> ToolInvocationFuture<'a> { | |
| Box::pin(async move { | |
| let _ = self.events_tx.send(DelegateEvent::ToolStarted); | |
| tokio::select! { | |
| _ = self.tool_release.notified() => { | |
| self.tool_finished.store(true, Ordering::Release); | |
| Ok(serde_json::Value::Null) | |
| } | |
| _ = cancellation_token.cancelled() => { | |
| self.tool_finished.store(true, Ordering::Release); | |
| let _ = self.events_tx.send(DelegateEvent::ToolCancelled); | |
| Err("cancelled".to_string()) | |
| } | |
| } | |
| }) | |
| } | |
| fn notify<'a>( | |
| &'a self, | |
| _call_id: String, | |
| _cell_id: CellId, | |
| _text: String, | |
| cancellation_token: CancellationToken, | |
| ) -> NotificationFuture<'a> { | |
| Box::pin(async move { | |
| let _ = self.events_tx.send(DelegateEvent::NotificationStarted); | |
| cancellation_token.cancelled().await; | |
| self.notification_finished.store(true, Ordering::Release); | |
| let _ = self.events_tx.send(DelegateEvent::NotificationCancelled); | |
| Err("cancelled".to_string()) | |
| }) | |
| } | |
| fn cell_closed(&self, cell_id: &CellId) { | |
| let _ = self | |
| .events_tx | |
| .send(DelegateEvent::CellClosed(cell_id.clone())); | |
| } | |
| } | |
| fn cell_id(value: &str) -> CellId { | |
| CellId::new(value.to_string()) | |
| } | |
| fn execute_request(source: &str) -> ExecuteRequest { | |
| ExecuteRequest { | |
| tool_call_id: "call-1".to_string(), | |
| enabled_tools: Vec::new(), | |
| source: source.to_string(), | |
| yield_time_ms: Some(1), | |
| max_output_tokens: None, | |
| } | |
| } | |
| fn blocking_tool() -> ToolDefinition { | |
| ToolDefinition { | |
| name: "block".to_string(), | |
| tool_name: ToolName::plain("block"), | |
| description: String::new(), | |
| kind: CodeModeToolKind::Function, | |
| input_schema: None, | |
| output_schema: None, | |
| } | |
| } | |
| async fn next_event(events_rx: &mut mpsc::UnboundedReceiver<DelegateEvent>) -> DelegateEvent { | |
| tokio::time::timeout(Duration::from_secs(2), events_rx.recv()) | |
| .await | |
| .expect("delegate event timeout") | |
| .expect("delegate event channel closed") | |
| } | |
| async fn yielded_cells_retain_their_own_delegate_until_closed() { | |
| let service = InProcessCodeModeSession::new(); | |
| let (delegate_a, mut events_a) = BlockingDelegate::new(); | |
| let (delegate_b, mut events_b) = BlockingDelegate::new(); | |
| let weak_a = Arc::downgrade(&delegate_a); | |
| let request = ExecuteRequest { | |
| enabled_tools: vec![blocking_tool()], | |
| ..execute_request("await tools.block({}); await tools.block({});") | |
| }; | |
| let a = service | |
| .execute(request.clone(), delegate_a.clone()) | |
| .await | |
| .unwrap(); | |
| assert_eq!(next_event(&mut events_a).await, DelegateEvent::ToolStarted); | |
| assert!(matches!( | |
| a.initial_response().await.unwrap(), | |
| RuntimeResponse::Yielded { .. } | |
| )); | |
| let b = service.execute(request, delegate_b.clone()).await.unwrap(); | |
| assert_eq!(next_event(&mut events_b).await, DelegateEvent::ToolStarted); | |
| assert!(matches!( | |
| b.initial_response().await.unwrap(), | |
| RuntimeResponse::Yielded { .. } | |
| )); | |
| // A's next callback must still reach A after B has started in the same session. | |
| delegate_a.release_tool(); | |
| assert_eq!(next_event(&mut events_a).await, DelegateEvent::ToolStarted); | |
| delegate_a.release_tool(); | |
| assert_eq!( | |
| service | |
| .wait(WaitRequest { | |
| cell_id: cell_id("1"), | |
| yield_time_ms: 60_000 | |
| }) | |
| .await | |
| .unwrap(), | |
| WaitOutcome::LiveCell(RuntimeResponse::Result { | |
| code_mode_host_duration: None, | |
| cell_id: cell_id("1"), | |
| content_items: Vec::new(), | |
| error_text: None | |
| }) | |
| ); | |
| assert_eq!( | |
| next_event(&mut events_a).await, | |
| DelegateEvent::CellClosed(cell_id("1")) | |
| ); | |
| drop(delegate_a); | |
| assert_eq!( | |
| tokio::time::timeout(Duration::from_secs(2), events_a.recv()) | |
| .await | |
| .unwrap(), | |
| None | |
| ); | |
| assert!(weak_a.upgrade().is_none()); | |
| service.terminate(cell_id("2")).await.unwrap(); | |
| assert_eq!( | |
| next_event(&mut events_b).await, | |
| DelegateEvent::ToolCancelled | |
| ); | |
| assert_eq!( | |
| next_event(&mut events_b).await, | |
| DelegateEvent::CellClosed(cell_id("2")) | |
| ); | |
| } | |
| async fn yields_and_resumes() { | |
| let service = InProcessCodeModeSession::new(); | |
| let cell = service | |
| .execute( | |
| ExecuteRequest { | |
| source: r#"text("before"); yield_control(); text("after");"#.to_string(), | |
| yield_time_ms: Some(60_000), | |
| ..execute_request("") | |
| }, | |
| Arc::new(NoopCodeModeSessionDelegate), | |
| ) | |
| .await | |
| .unwrap(); | |
| assert_eq!( | |
| cell.initial_response().await.unwrap(), | |
| RuntimeResponse::Yielded { | |
| code_mode_host_duration: None, | |
| cell_id: cell_id("1"), | |
| content_items: vec![FunctionCallOutputContentItem::InputText { | |
| text: "before".to_string(), | |
| }], | |
| } | |
| ); | |
| assert_eq!( | |
| service | |
| .wait(WaitRequest { | |
| cell_id: cell_id("1"), | |
| yield_time_ms: 60_000, | |
| }) | |
| .await | |
| .unwrap(), | |
| WaitOutcome::LiveCell(RuntimeResponse::Result { | |
| code_mode_host_duration: None, | |
| cell_id: cell_id("1"), | |
| content_items: vec![FunctionCallOutputContentItem::InputText { | |
| text: "after".to_string(), | |
| }], | |
| error_text: None, | |
| }) | |
| ); | |
| } | |
| async fn returns_and_resumes_from_the_pending_frontier() { | |
| let (delegate, mut events_rx) = BlockingDelegate::new(); | |
| let service = InProcessCodeModeSession::new(); | |
| assert_eq!( | |
| service | |
| .execute_to_pending( | |
| ExecuteRequest { | |
| enabled_tools: vec![blocking_tool()], | |
| source: r#" | |
| await tools.block({}); | |
| text("after"); | |
| "# | |
| .to_string(), | |
| yield_time_ms: Some(60_000), | |
| ..execute_request("") | |
| }, | |
| delegate.clone() | |
| ) | |
| .await | |
| .unwrap(), | |
| ExecuteToPendingOutcome::Pending { | |
| cell_id: cell_id("1"), | |
| content_items: Vec::new(), | |
| pending_tool_call_ids: vec!["tool-1".to_string()], | |
| } | |
| ); | |
| assert_eq!(next_event(&mut events_rx).await, DelegateEvent::ToolStarted); | |
| delegate.release_tool(); | |
| assert_eq!( | |
| service | |
| .wait_to_pending(WaitToPendingRequest { | |
| cell_id: cell_id("1"), | |
| }) | |
| .await | |
| .unwrap(), | |
| WaitToPendingOutcome::LiveCell(ExecuteToPendingOutcome::Completed( | |
| RuntimeResponse::Result { | |
| code_mode_host_duration: None, | |
| cell_id: cell_id("1"), | |
| content_items: vec![FunctionCallOutputContentItem::InputText { | |
| text: "after".to_string(), | |
| }], | |
| error_text: None, | |
| } | |
| )) | |
| ); | |
| } | |
| async fn observed_natural_completion_wins_over_termination() { | |
| let service = InProcessCodeModeSession::new(); | |
| let cell = service | |
| .execute( | |
| execute_request(r#"yield_control(); store("finished", true); text("done");"#), | |
| Arc::new(NoopCodeModeSessionDelegate), | |
| ) | |
| .await | |
| .unwrap(); | |
| assert_eq!( | |
| cell.initial_response().await.unwrap(), | |
| RuntimeResponse::Yielded { | |
| code_mode_host_duration: None, | |
| cell_id: cell_id("1"), | |
| content_items: Vec::new(), | |
| } | |
| ); | |
| tokio::time::timeout(Duration::from_secs(1), async { | |
| loop { | |
| let response = service | |
| .execute( | |
| ExecuteRequest { | |
| yield_time_ms: Some(60_000), | |
| ..execute_request(r#"text(String(load("finished")));"#) | |
| }, | |
| Arc::new(NoopCodeModeSessionDelegate), | |
| ) | |
| .await | |
| .unwrap() | |
| .initial_response() | |
| .await | |
| .unwrap(); | |
| let RuntimeResponse::Result { content_items, .. } = response else { | |
| panic!("expected stored-value probe to complete"); | |
| }; | |
| if content_items | |
| == vec![FunctionCallOutputContentItem::InputText { | |
| text: "true".to_string(), | |
| }] | |
| { | |
| break; | |
| } | |
| tokio::task::yield_now().await; | |
| } | |
| }) | |
| .await | |
| .unwrap(); | |
| assert_eq!( | |
| service.terminate(cell_id("1")).await.unwrap(), | |
| WaitOutcome::LiveCell(RuntimeResponse::Result { | |
| code_mode_host_duration: None, | |
| cell_id: cell_id("1"), | |
| content_items: vec![FunctionCallOutputContentItem::InputText { | |
| text: "done".to_string(), | |
| }], | |
| error_text: None, | |
| }) | |
| ); | |
| } | |
| async fn termination_cancels_pending_callbacks_before_responding() { | |
| let (delegate, mut events_rx) = BlockingDelegate::new(); | |
| let service = InProcessCodeModeSession::new(); | |
| let cell = service | |
| .execute( | |
| execute_request(r#"notify("pending"); await new Promise(() => {});"#), | |
| delegate.clone(), | |
| ) | |
| .await | |
| .unwrap(); | |
| assert_eq!( | |
| next_event(&mut events_rx).await, | |
| DelegateEvent::NotificationStarted | |
| ); | |
| assert_eq!( | |
| cell.initial_response().await.unwrap(), | |
| RuntimeResponse::Yielded { | |
| code_mode_host_duration: None, | |
| cell_id: cell_id("1"), | |
| content_items: Vec::new(), | |
| } | |
| ); | |
| assert_eq!( | |
| service.terminate(cell_id("1")).await.unwrap(), | |
| WaitOutcome::LiveCell(RuntimeResponse::Terminated { | |
| code_mode_host_duration: None, | |
| cell_id: cell_id("1"), | |
| content_items: Vec::new(), | |
| }) | |
| ); | |
| assert!(delegate.notification_finished.load(Ordering::Acquire)); | |
| assert_eq!( | |
| next_event(&mut events_rx).await, | |
| DelegateEvent::NotificationCancelled | |
| ); | |
| assert_eq!( | |
| next_event(&mut events_rx).await, | |
| DelegateEvent::CellClosed(cell_id("1")) | |
| ); | |
| } | |
| async fn shutdown_cancels_notifications_while_natural_completion_is_draining() { | |
| let (delegate, mut events_rx) = HeldNotificationDelegate::new(); | |
| let service = Arc::new(InProcessCodeModeSession::new()); | |
| service | |
| .execute(execute_request(r#"notify("pending");"#), delegate.clone()) | |
| .await | |
| .unwrap(); | |
| assert_eq!( | |
| next_event(&mut events_rx).await, | |
| DelegateEvent::NotificationStarted | |
| ); | |
| let shutdown_service = Arc::clone(&service); | |
| let shutdown = tokio::spawn(async move { shutdown_service.shutdown().await }); | |
| assert_eq!( | |
| next_event(&mut events_rx).await, | |
| DelegateEvent::NotificationCancelled | |
| ); | |
| delegate.release_notification(); | |
| assert_eq!(shutdown.await.unwrap(), Ok(())); | |
| assert_eq!( | |
| next_event(&mut events_rx).await, | |
| DelegateEvent::CellClosed(cell_id("1")) | |
| ); | |
| } | |
| async fn repeated_termination_is_rejected_while_callback_cleanup_is_pending() { | |
| let (delegate, mut events_rx) = HeldNotificationDelegate::new(); | |
| let service = Arc::new(InProcessCodeModeSession::new()); | |
| let cell = service | |
| .execute( | |
| execute_request(r#"notify("pending"); await new Promise(() => {});"#), | |
| delegate.clone(), | |
| ) | |
| .await | |
| .unwrap(); | |
| assert_eq!( | |
| next_event(&mut events_rx).await, | |
| DelegateEvent::NotificationStarted | |
| ); | |
| assert_eq!( | |
| cell.initial_response().await.unwrap(), | |
| RuntimeResponse::Yielded { | |
| code_mode_host_duration: None, | |
| cell_id: cell_id("1"), | |
| content_items: Vec::new(), | |
| } | |
| ); | |
| let terminating_service = Arc::clone(&service); | |
| let first_termination = | |
| tokio::spawn(async move { terminating_service.terminate(cell_id("1")).await }); | |
| assert_eq!( | |
| next_event(&mut events_rx).await, | |
| DelegateEvent::NotificationCancelled | |
| ); | |
| let repeated_termination = service.terminate(cell_id("1")).await; | |
| delegate.release_notification(); | |
| assert_eq!( | |
| repeated_termination.unwrap_err(), | |
| "exec cell 1 is already terminating" | |
| ); | |
| assert_eq!( | |
| first_termination.await.unwrap().unwrap(), | |
| WaitOutcome::LiveCell(RuntimeResponse::Terminated { | |
| code_mode_host_duration: None, | |
| cell_id: cell_id("1"), | |
| content_items: Vec::new(), | |
| }) | |
| ); | |
| assert_eq!( | |
| next_event(&mut events_rx).await, | |
| DelegateEvent::CellClosed(cell_id("1")) | |
| ); | |
| } | |
| async fn second_observer_is_rejected_without_displacing_the_first() { | |
| let service = InProcessCodeModeSession::new(); | |
| let cell = service | |
| .execute( | |
| execute_request("await new Promise(() => {});"), | |
| Arc::new(NoopCodeModeSessionDelegate), | |
| ) | |
| .await | |
| .unwrap(); | |
| assert_eq!( | |
| cell.initial_response().await.unwrap(), | |
| RuntimeResponse::Yielded { | |
| code_mode_host_duration: None, | |
| cell_id: cell_id("1"), | |
| content_items: Vec::new(), | |
| } | |
| ); | |
| let first_observer = service | |
| .begin_wait(WaitRequest { | |
| cell_id: cell_id("1"), | |
| yield_time_ms: 60_000, | |
| }) | |
| .await; | |
| assert_eq!( | |
| service | |
| .wait(WaitRequest { | |
| cell_id: cell_id("1"), | |
| yield_time_ms: 60_000, | |
| }) | |
| .await | |
| .unwrap_err(), | |
| "exec cell 1 already has an active observer" | |
| ); | |
| let terminated = RuntimeResponse::Terminated { | |
| code_mode_host_duration: None, | |
| cell_id: cell_id("1"), | |
| content_items: Vec::new(), | |
| }; | |
| assert_eq!( | |
| service.terminate(cell_id("1")).await.unwrap(), | |
| WaitOutcome::LiveCell(terminated.clone()) | |
| ); | |
| assert_eq!( | |
| first_observer.await.unwrap(), | |
| WaitOutcome::LiveCell(terminated) | |
| ); | |
| } | |
| async fn natural_completion_cleans_up_callbacks_before_responding() { | |
| let (delegate, mut events_rx) = BlockingDelegate::new(); | |
| let service = InProcessCodeModeSession::new(); | |
| let cell = service | |
| .execute( | |
| ExecuteRequest { | |
| enabled_tools: vec![blocking_tool()], | |
| source: r#"tools.block({}); text("done");"#.to_string(), | |
| yield_time_ms: Some(60_000), | |
| ..execute_request("") | |
| }, | |
| delegate.clone(), | |
| ) | |
| .await | |
| .unwrap(); | |
| assert_eq!(next_event(&mut events_rx).await, DelegateEvent::ToolStarted); | |
| assert_eq!( | |
| cell.initial_response().await.unwrap(), | |
| RuntimeResponse::Result { | |
| code_mode_host_duration: None, | |
| cell_id: cell_id("1"), | |
| content_items: vec![FunctionCallOutputContentItem::InputText { | |
| text: "done".to_string(), | |
| }], | |
| error_text: None, | |
| } | |
| ); | |
| assert!(delegate.tool_finished.load(Ordering::Acquire)); | |
| assert_eq!( | |
| next_event(&mut events_rx).await, | |
| DelegateEvent::ToolCancelled | |
| ); | |
| assert_eq!( | |
| next_event(&mut events_rx).await, | |
| DelegateEvent::CellClosed(cell_id("1")) | |
| ); | |
| } | |