Skip to main content

conversation_api/
request.rs

1use crate::{InteractionDecision, MessageContent};
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq)]
5#[serde(deny_unknown_fields)]
6pub struct ThreadListRequest {}
7
8#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
9#[serde(rename_all = "camelCase", deny_unknown_fields)]
10pub struct ThreadCreateRequest {
11    pub operation_id: String,
12    pub expected_catalog_version: u64,
13    #[serde(default, skip_serializing_if = "Option::is_none")]
14    pub title: Option<String>,
15}
16
17#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
18#[serde(rename_all = "camelCase", deny_unknown_fields)]
19pub struct ThreadArchiveRequest {
20    pub thread_id: String,
21    pub expected_catalog_version: u64,
22}
23
24#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
25#[serde(rename_all = "camelCase", deny_unknown_fields)]
26pub struct ThreadRotateRequest {
27    pub operation_id: String,
28    pub thread_id: String,
29    pub expected_catalog_version: u64,
30    pub expected_snapshot_version: u64,
31    pub expected_setting_version: u64,
32    pub reason: ThreadRotateReason,
33}
34
35#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
36#[serde(rename_all = "snake_case")]
37pub enum ThreadRotateReason {
38    IdleTimeout,
39    UserRequested,
40}
41
42#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
43#[serde(rename_all = "camelCase", deny_unknown_fields)]
44pub struct ThreadLoadRequest {
45    pub thread_id: String,
46    #[serde(default, skip_serializing_if = "Option::is_none")]
47    pub known_snapshot_version: Option<u64>,
48}
49
50#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
51#[serde(rename_all = "camelCase", deny_unknown_fields)]
52pub struct MessageEnqueueRequest {
53    pub thread_id: String,
54    pub request_id: String,
55    pub content: MessageContent,
56    #[serde(default, skip_serializing_if = "Option::is_none")]
57    pub access_mode: Option<ConversationAccessMode>,
58    pub agent_model_mode: String,
59    #[serde(default, skip_serializing_if = "Option::is_none")]
60    pub temperature: Option<f32>,
61    pub allow_tools: bool,
62    pub debug: bool,
63}
64
65/// Submits one user turn without requiring the caller to select or manage a thread.
66#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
67#[serde(rename_all = "camelCase", deny_unknown_fields)]
68pub struct TurnSubmitRequest {
69    pub request_id: String,
70    #[serde(default, skip_serializing_if = "Option::is_none")]
71    pub title: Option<String>,
72    pub content: MessageContent,
73    #[serde(default, skip_serializing_if = "Option::is_none")]
74    pub access_mode: Option<ConversationAccessMode>,
75    pub agent_model_mode: String,
76    #[serde(default, skip_serializing_if = "Option::is_none")]
77    pub temperature: Option<f32>,
78    pub allow_tools: bool,
79    pub debug: bool,
80    pub occurred_at_unix_ms: i64,
81}
82
83/// Starts a new active session without exposing thread storage preconditions to the caller.
84#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
85#[serde(rename_all = "camelCase", deny_unknown_fields)]
86pub struct SessionStartRequest {
87    pub operation_id: String,
88    pub reason: SessionStartReason,
89}
90
91#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
92#[serde(rename_all = "snake_case")]
93pub enum SessionStartReason {
94    UserRequested,
95}
96
97/// Answers the current pending interaction without requiring thread or policy state.
98#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
99#[serde(rename_all = "camelCase", deny_unknown_fields)]
100pub struct InteractionAnswerRequest {
101    pub request_id: String,
102    pub batch_id: String,
103    pub decisions: Vec<InteractionDecision>,
104    pub occurred_at_unix_ms: i64,
105}
106
107#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
108#[serde(rename_all = "snake_case")]
109pub enum ConversationAccessMode {
110    NoAccess,
111    Interactive,
112    FullAccess,
113}
114
115#[cfg(test)]
116mod access_mode_tests {
117    use super::ConversationAccessMode;
118
119    #[test]
120    fn no_access_is_a_distinct_canonical_wire_value() {
121        let mode: ConversationAccessMode = serde_json::from_str("\"no_access\"").unwrap();
122        assert_eq!(mode, ConversationAccessMode::NoAccess);
123        assert_eq!(serde_json::to_string(&mode).unwrap(), "\"no_access\"");
124        assert!(serde_json::from_str::<ConversationAccessMode>("\"deny\"").is_err());
125        assert!(serde_json::from_str::<ConversationAccessMode>("\"always_deny\"").is_err());
126    }
127}
128
129#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
130#[serde(rename_all = "camelCase", deny_unknown_fields)]
131pub struct QueueReorderRequest {
132    pub thread_id: String,
133    pub request_id: String,
134    pub operation_id: String,
135    /// Move this waiting request immediately before the anchor, or to the tail when null.
136    pub before_request_id: Option<String>,
137}
138
139#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
140#[serde(rename_all = "camelCase", deny_unknown_fields)]
141pub struct QueueUpdateRequest {
142    pub thread_id: String,
143    pub request_id: String,
144    pub operation_id: String,
145    pub content: MessageContent,
146}
147
148#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
149#[serde(rename_all = "camelCase", deny_unknown_fields)]
150pub struct RequestStatusRequest {
151    pub request_id: String,
152}
153
154#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
155#[serde(rename_all = "camelCase", deny_unknown_fields)]
156pub struct RequestCancelRequest {
157    #[serde(default, skip_serializing_if = "Option::is_none")]
158    pub thread_id: Option<String>,
159    pub request_id: String,
160}
161
162#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
163#[serde(rename_all = "camelCase", deny_unknown_fields)]
164pub struct InteractionSubmitRequest {
165    pub thread_id: String,
166    pub batch_id: String,
167    pub decisions: Vec<InteractionDecision>,
168}