Download codex-rs/core/src/elicitation.rs from SaylorTwift/codex: direct link, hf CLI and curl.
- Browser
- Download file 2.48 kB
-
https://huggingface.co/SaylorTwift/codex/resolve/main/codex-rs/core/src/elicitation.rs
- Command line
-
hf download hf://SaylorTwift/codex/codex-rs/core/src/elicitation.rs
-
curl -L -o elicitation.rs https://huggingface.co/SaylorTwift/codex/resolve/main/codex-rs/core/src/elicitation.rs
2.48 kB
| use std::sync::Arc; | |
| use std::sync::Mutex; | |
| use tokio::sync::watch; | |
| /// Coordinates user elicitations that pause tool-result delivery for a session. | |
| /// | |
| /// Registrations are counted so concurrent elicitations keep the session paused until all of them | |
| /// finish. Consumers can subscribe to pause timeout progress or wait before returning an already | |
| /// captured result. | |
| pub(crate) struct ElicitationService { | |
| inner: Arc<Inner>, | |
| } | |
| struct Inner { | |
| state: Mutex<State>, | |
| paused: watch::Sender<bool>, | |
| } | |
| struct State { | |
| outstanding: i64, | |
| } | |
| pub(crate) struct ElicitationRegistration { | |
| service: ElicitationService, | |
| } | |
| impl ElicitationService { | |
| pub(crate) fn new() -> Self { | |
| let (paused, _paused_rx) = watch::channel(false); | |
| Self { | |
| inner: Arc::new(Inner { | |
| state: Mutex::new(State::default()), | |
| paused, | |
| }), | |
| } | |
| } | |
| pub(crate) fn register(&self) -> ElicitationRegistration { | |
| self.increment(); | |
| ElicitationRegistration { | |
| service: self.clone(), | |
| } | |
| } | |
| fn increment(&self) { | |
| let mut state = self | |
| .inner | |
| .state | |
| .lock() | |
| .unwrap_or_else(std::sync::PoisonError::into_inner); | |
| let was_clear = state.outstanding == 0; | |
| assert_ne!( | |
| state.outstanding, | |
| i64::MAX, | |
| "outstanding elicitation count overflowed" | |
| ); | |
| state.outstanding += 1; | |
| if was_clear { | |
| self.inner.paused.send_replace(true); | |
| } | |
| } | |
| pub(crate) fn subscribe(&self) -> watch::Receiver<bool> { | |
| self.inner.paused.subscribe() | |
| } | |
| pub(crate) async fn wait_until_clear(&self) { | |
| let mut paused = self.subscribe(); | |
| let _ = paused.wait_for(|paused| !*paused).await; | |
| } | |
| fn decrement(&self) { | |
| let mut state = self | |
| .inner | |
| .state | |
| .lock() | |
| .unwrap_or_else(std::sync::PoisonError::into_inner); | |
| assert!( | |
| state.outstanding > 0, | |
| "elicitation registration count underflowed" | |
| ); | |
| state.outstanding -= 1; | |
| if state.outstanding == 0 { | |
| self.inner.paused.send_replace(false); | |
| } | |
| } | |
| } | |
| impl Drop for ElicitationRegistration { | |
| fn drop(&mut self) { | |
| self.service.decrement(); | |
| } | |
| } | |
| mod tests; | |