Skip to main content

runifold_agent/conversation/
durable.rs

1//! Atomic conversation-and-checkpoint commit boundary.
2
3use runifold_core::{Checkpoint, CheckpointId, CheckpointStore};
4
5use super::{
6    ConversationAppend, ConversationContextPolicy, ConversationId, ConversationStore,
7    ConversationStoreError, ConversationStoreFuture, ConversationVersion, MemoryNamespace,
8};
9
10/// Stable identities and context policy for one new durable Agent turn.
11#[derive(Clone, Debug)]
12pub struct DurableConversationRequest {
13    /// Fresh checkpoint identity used as the turn's idempotency identity.
14    pub checkpoint_id: CheckpointId,
15    /// Conversation receiving the completed turn.
16    pub conversation_id: ConversationId,
17    /// Isolation namespace owning the conversation.
18    pub namespace: MemoryNamespace,
19    /// Bounded context selection policy.
20    pub policy: ConversationContextPolicy,
21}
22
23/// Final state of one durable conversational Agent turn.
24///
25/// Implementations must validate both optimistic preconditions and commit the
26/// transcript append and checkpoint replacement in one storage transaction.
27#[derive(Clone, Debug)]
28pub struct DurableConversationCommit {
29    /// Namespace owning the conversation.
30    pub namespace: MemoryNamespace,
31    /// Canonical messages produced by the single Agent execution.
32    pub append: ConversationAppend,
33    /// Completed checkpoint revision to persist with the transcript.
34    pub checkpoint: Checkpoint,
35    /// Checkpoint revision observed immediately before the final commit.
36    pub expected_checkpoint_revision: u64,
37}
38
39/// Store capable of atomically committing conversation and recovery state.
40///
41/// Merely implementing [`ConversationStore`] and [`CheckpointStore`] is not
42/// sufficient: the final writes must share one real transaction.
43pub trait DurableConversationStore: ConversationStore + CheckpointStore {
44    /// Atomically appends a transcript turn and advances its checkpoint.
45    fn commit_durable_turn(
46        &self,
47        command: DurableConversationCommit,
48    ) -> ConversationStoreFuture<'_, Result<ConversationVersion, ConversationStoreError>>;
49}