1use crate::{ConversationMessage, PendingInteraction};
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
5#[serde(rename_all = "snake_case")]
6pub enum ThreadState {
7 Active,
8 Archived,
9}
10
11#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
12#[serde(rename_all = "snake_case")]
13pub enum ThreadArchiveReason {
14 IdleTimeout,
15 UserRequested,
16 Replaced,
17}
18
19#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
22#[serde(tag = "type", rename_all = "snake_case", deny_unknown_fields)]
23pub enum ThreadOrigin {
24 Turn {
25 #[serde(rename = "requestId")]
26 request_id: String,
27 },
28 Operation {
29 #[serde(rename = "operationId")]
30 operation_id: String,
31 },
32}
33
34#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
35#[serde(rename_all = "camelCase")]
36pub struct ThreadSummary {
37 pub thread_id: String,
38 #[serde(default, skip_serializing_if = "Option::is_none")]
40 pub origin: Option<ThreadOrigin>,
41 pub title: String,
42 pub state: ThreadState,
43 pub created_at: String,
44 pub updated_at: String,
45 pub archived_at: Option<String>,
46 #[serde(default, skip_serializing_if = "Option::is_none")]
47 pub archive_reason: Option<ThreadArchiveReason>,
48 pub purge_after: Option<String>,
49}
50
51#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq)]
52#[serde(rename_all = "camelCase")]
53pub struct ThreadCatalog {
54 pub catalog_version: u64,
55 #[serde(default)]
56 pub active_thread_id: Option<String>,
57 #[serde(default)]
58 pub threads: Vec<ThreadSummary>,
59}
60
61#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
62#[serde(rename_all = "camelCase")]
63pub struct QueuedMessage {
64 pub request_id: String,
65 pub thread_id: String,
66 #[serde(default, skip_serializing_if = "Option::is_none")]
67 pub author_user_id: Option<String>,
68 pub content: crate::MessageContent,
69 pub created_at: String,
70}
71
72#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
73#[serde(rename_all = "camelCase")]
74pub struct ConversationQueue {
75 pub queue_version: u64,
76 #[serde(default)]
77 pub items: Vec<QueuedMessage>,
78}
79
80#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
81#[serde(rename_all = "camelCase")]
82pub struct ActiveRun {
83 pub request_id: String,
84 pub started_at: String,
85}
86
87#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
88#[serde(rename_all = "snake_case")]
89pub enum RunStatus {
90 Completed,
91 InteractionRequired,
92 Interrupted,
93 AgentFailed,
94 SystemFailed,
95}
96
97#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
98#[serde(rename_all = "snake_case")]
99pub enum FailureSource {
100 LlmProvider,
101 AgentRuntime,
102}
103
104#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
105#[serde(rename_all = "camelCase")]
106pub struct RunFailure {
107 pub source: FailureSource,
108 pub code: String,
110 pub message: String,
111}
112
113#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
114#[serde(rename_all = "camelCase")]
115pub struct RunOutcome {
116 pub request_id: String,
117 pub status: RunStatus,
118 #[serde(default, skip_serializing_if = "Option::is_none")]
120 pub error_code: Option<String>,
121 #[serde(default, skip_serializing_if = "Option::is_none")]
122 pub failure: Option<RunFailure>,
123 #[serde(default, skip_serializing_if = "Option::is_none")]
125 pub message: Option<String>,
126}
127
128#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
129#[serde(rename_all = "camelCase")]
130pub struct ThreadSnapshot {
131 pub version: u64,
132 pub messages: Vec<ConversationMessage>,
133 pub active_run: Option<ActiveRun>,
134 pub pending_interaction: Option<PendingInteraction>,
135 pub run_outcomes: Vec<RunOutcome>,
136}