orchestral_runtime/
thread.rs1use chrono::{DateTime, Utc};
13use serde::{Deserialize, Serialize};
14use serde_json::Value;
15use std::collections::HashMap;
16
17pub use orchestral_core::store::ThreadId;
18
19fn default_scope() -> String {
20 "user:anonymous".to_string()
21}
22
23#[derive(Debug, Clone, Serialize, Deserialize)]
25pub struct Thread {
26 pub id: ThreadId,
28 #[serde(default = "default_scope")]
30 pub scope: String,
31 #[serde(default)]
33 pub metadata: HashMap<String, Value>,
34 pub created_at: DateTime<Utc>,
36 pub updated_at: DateTime<Utc>,
38}
39
40impl Thread {
41 pub fn new() -> Self {
43 let now = Utc::now();
44 Self {
45 id: ThreadId::from(uuid::Uuid::new_v4().to_string()),
46 scope: default_scope(),
47 metadata: HashMap::new(),
48 created_at: now,
49 updated_at: now,
50 }
51 }
52
53 pub fn with_id(id: impl Into<ThreadId>) -> Self {
55 let now = Utc::now();
56 Self {
57 id: id.into(),
58 scope: default_scope(),
59 metadata: HashMap::new(),
60 created_at: now,
61 updated_at: now,
62 }
63 }
64
65 pub fn with_metadata(metadata: HashMap<String, Value>) -> Self {
67 let now = Utc::now();
68 Self {
69 id: ThreadId::from(uuid::Uuid::new_v4().to_string()),
70 scope: default_scope(),
71 metadata,
72 created_at: now,
73 updated_at: now,
74 }
75 }
76
77 pub fn with_scope(scope: impl Into<String>) -> Self {
79 let now = Utc::now();
80 Self {
81 id: ThreadId::from(uuid::Uuid::new_v4().to_string()),
82 scope: scope.into(),
83 metadata: HashMap::new(),
84 created_at: now,
85 updated_at: now,
86 }
87 }
88
89 pub fn set_scope(&mut self, scope: impl Into<String>) {
91 self.scope = scope.into();
92 self.updated_at = Utc::now();
93 }
94
95 pub fn set_metadata(&mut self, key: impl Into<String>, value: Value) {
97 self.metadata.insert(key.into(), value);
98 self.updated_at = Utc::now();
99 }
100
101 pub fn get_metadata(&self, key: &str) -> Option<&Value> {
103 self.metadata.get(key)
104 }
105
106 pub fn remove_metadata(&mut self, key: &str) -> Option<Value> {
108 let result = self.metadata.remove(key);
109 if result.is_some() {
110 self.updated_at = Utc::now();
111 }
112 result
113 }
114
115 pub fn touch(&mut self) {
117 self.updated_at = Utc::now();
118 }
119}
120
121impl Default for Thread {
122 fn default() -> Self {
123 Self::new()
124 }
125}