systemprompt_models/documents/
awareness.rs1use chrono::{DateTime, Utc};
14use schemars::JsonSchema;
15use serde::{Deserialize, Serialize};
16use systemprompt_identifiers::{DocumentEditSessionId, DocumentId, DocumentNodeId, UserId};
17
18pub const AWARENESS_COLOR_MAX: usize = 32;
19pub const AWARENESS_CURSOR_MAX: usize = 512;
20
21#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
22#[serde(rename_all = "snake_case")]
23pub enum AwarenessMode {
24 Viewing,
25 Editing,
26 Commenting,
27 Presenting,
28}
29
30#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
33pub struct AwarenessCursor {
34 pub block: DocumentNodeId,
35 pub anchor: String,
36 pub head: String,
37}
38
39#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
42pub struct AwarenessViewport {
43 pub first: DocumentNodeId,
44 pub last: DocumentNodeId,
45}
46
47#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
49pub struct AwarenessState {
50 #[serde(default, skip_serializing_if = "Option::is_none")]
51 pub session_id: Option<DocumentEditSessionId>,
52 pub color: String,
53 pub mode: AwarenessMode,
54 #[serde(default, skip_serializing_if = "Option::is_none")]
55 pub cursor: Option<AwarenessCursor>,
56 #[serde(default, skip_serializing_if = "Vec::is_empty")]
57 pub selection: Vec<AwarenessCursor>,
58 #[serde(default, skip_serializing_if = "Option::is_none")]
59 pub viewport: Option<AwarenessViewport>,
60 #[schemars(
61 description = "Set when the participant is an agent acting for the user, named so a client draws it as its own caret beside the person's."
62 )]
63 #[serde(default, skip_serializing_if = "Option::is_none")]
64 pub agent: Option<String>,
65}
66
67#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
68pub struct DocumentAwarenessEvent {
69 pub document_id: DocumentId,
70 pub user_id: UserId,
71 pub display_name: String,
72 pub state: AwarenessState,
73 pub expires_at: DateTime<Utc>,
74}
75
76impl DocumentAwarenessEvent {
77 pub const NAME: &'static str = "document.awareness";
78}
79
80#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
82#[serde(rename_all = "snake_case")]
83pub enum LiveResyncReason {
84 SessionChanged,
85 UpdatesCompacted,
86 Lagged,
87 RelayLost,
88}
89
90#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
96pub struct DocumentLiveReadyEvent {
97 pub document_id: DocumentId,
98 #[serde(default, skip_serializing_if = "Option::is_none")]
99 pub edit_session_id: Option<DocumentEditSessionId>,
100 #[serde(default, skip_serializing_if = "Option::is_none")]
101 pub seq: Option<i64>,
102 pub replayed: usize,
103}
104
105impl DocumentLiveReadyEvent {
106 pub const NAME: &'static str = "document.live.ready";
107}
108
109#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
110pub struct DocumentLiveResyncEvent {
111 pub document_id: DocumentId,
112 pub reason: LiveResyncReason,
113}
114
115impl DocumentLiveResyncEvent {
116 pub const NAME: &'static str = "document.live.resync";
117}
118
119#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
121pub struct DocumentLiveClosedEvent {
122 pub document_id: DocumentId,
123}
124
125impl DocumentLiveClosedEvent {
126 pub const NAME: &'static str = "document.live.closed";
127}