systemprompt_agent/models/
context.rs1use chrono::{DateTime, Utc};
5use serde::{Deserialize, Serialize};
6use systemprompt_identifiers::{ContextId, McpExecutionId, MessageId, SkillId, TaskId};
7
8pub use systemprompt_models::{
9 CreateContextRequest, UpdateContextRequest, UserContext, UserContextWithStats,
10};
11
12#[derive(Debug, Clone, Serialize, Deserialize)]
13pub struct ContextMessage {
14 pub message_id: MessageId,
15 pub role: String,
16 pub created_at: DateTime<Utc>,
17 pub sequence_number: i32,
18 pub parts: Vec<super::a2a::Part>,
19}
20
21#[derive(Debug, Clone, Serialize, Deserialize)]
22pub struct ContextDetail {
23 pub context: UserContext,
24 pub messages: Vec<ContextMessage>,
25}
26
27#[derive(Debug, Clone, Serialize, Deserialize)]
28#[serde(tag = "type", rename_all = "snake_case")]
29pub enum ContextStateEvent {
30 ToolExecutionCompleted {
31 context_id: ContextId,
32 execution_id: McpExecutionId,
33 tool_name: String,
34 server_name: String,
35 output: Option<String>,
36 #[serde(skip_serializing_if = "Option::is_none")]
37 artifact: Option<super::a2a::Artifact>,
38 status: String,
39 timestamp: DateTime<Utc>,
40 },
41 TaskStatusChanged {
42 task: super::a2a::Task,
43 context_id: ContextId,
44 timestamp: DateTime<Utc>,
45 },
46 ArtifactCreated {
47 artifact: super::a2a::Artifact,
48 task_id: TaskId,
49 context_id: ContextId,
50 timestamp: DateTime<Utc>,
51 },
52 SkillLoaded {
53 skill_id: SkillId,
54 skill_name: String,
55 description: String,
56 request_context: systemprompt_models::execution::context::RequestContext,
57 tool_name: Option<String>,
58 timestamp: DateTime<Utc>,
59 },
60 ContextCreated {
61 context_id: ContextId,
62 context: UserContext,
63 timestamp: DateTime<Utc>,
64 },
65 ContextUpdated {
66 context_id: ContextId,
67 name: String,
68 timestamp: DateTime<Utc>,
69 },
70 ContextDeleted {
71 context_id: ContextId,
72 timestamp: DateTime<Utc>,
73 },
74 Heartbeat {
75 timestamp: DateTime<Utc>,
76 },
77 CurrentAgent {
78 context_id: ContextId,
79 agent_name: Option<String>,
80 timestamp: DateTime<Utc>,
81 },
82}
83
84impl ContextStateEvent {
85 pub fn context_id(&self) -> Option<&str> {
86 match self {
87 Self::SkillLoaded {
88 request_context, ..
89 } => Some(request_context.context_id().as_str()),
90 Self::Heartbeat { .. } => None,
91 Self::ToolExecutionCompleted { context_id, .. }
92 | Self::TaskStatusChanged { context_id, .. }
93 | Self::ArtifactCreated { context_id, .. }
94 | Self::ContextCreated { context_id, .. }
95 | Self::ContextUpdated { context_id, .. }
96 | Self::ContextDeleted { context_id, .. }
97 | Self::CurrentAgent { context_id, .. } => Some(context_id.as_str()),
98 }
99 }
100
101 pub const fn timestamp(&self) -> DateTime<Utc> {
102 match self {
103 Self::ToolExecutionCompleted { timestamp, .. }
104 | Self::TaskStatusChanged { timestamp, .. }
105 | Self::ArtifactCreated { timestamp, .. }
106 | Self::SkillLoaded { timestamp, .. }
107 | Self::ContextCreated { timestamp, .. }
108 | Self::ContextUpdated { timestamp, .. }
109 | Self::ContextDeleted { timestamp, .. }
110 | Self::Heartbeat { timestamp }
111 | Self::CurrentAgent { timestamp, .. } => *timestamp,
112 }
113 }
114}