1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
//! Standalone handle for observing and cancelling ephemeral prompt-turn state.
use crate::{
durable::SessionId,
ephemeral::{EphemeralTurn, SharedEphemeralTurn, TurnPhase},
error::RuntimeError,
runtime::IronRuntime,
};
use std::sync::Arc;
/// A locally observable prompt turn associated with one durable session.
///
/// This type owns ephemeral phase and cancellation state. Constructing it does
/// not register the turn as the runtime's active prompt; runtime-managed prompt
/// admission is performed by [`IronRuntime::try_start_prompt`].
pub struct PromptTurn {
/// Durable session associated with the turn.
pub session_id: SessionId,
ephemeral: SharedEphemeralTurn,
_runtime: IronRuntime,
}
impl PromptTurn {
/// Creates a pending turn for `session_id` backed by `runtime`.
pub fn new(session_id: SessionId, runtime: IronRuntime) -> Self {
let ephemeral = Arc::new(tokio::sync::Mutex::new(EphemeralTurn::new(
session_id, None,
)));
Self {
session_id,
ephemeral,
_runtime: runtime,
}
}
/// Returns the durable session associated with this turn.
pub fn session_id(&self) -> SessionId {
self.session_id
}
/// Returns a snapshot of the turn's current phase.
pub async fn phase(&self) -> TurnPhase {
self.ephemeral.lock().await.phase
}
/// Returns whether the turn has reached a terminal phase.
pub async fn is_terminal(&self) -> bool {
self.ephemeral.lock().await.is_terminal()
}
/// Returns a shared handle to the turn's ephemeral state.
pub fn ephemeral(&self) -> SharedEphemeralTurn {
self.ephemeral.clone()
}
/// Requests cancellation unless the turn is already terminal.
///
/// Repeated cancellation and cancellation after termination are no-ops.
///
/// # Errors
///
/// The current implementation is infallible; the result preserves the
/// cancellation API's fallible contract.
pub async fn cancel(&self) -> Result<(), RuntimeError> {
let mut turn = self.ephemeral.lock().await;
if turn.is_terminal() {
return Ok(());
}
turn.cancel();
Ok(())
}
}
impl std::fmt::Debug for PromptTurn {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("PromptTurn")
.field("session_id", &self.session_id)
.finish()
}
}