systemprompt_models/execution/step/
content.rs1use serde::{Deserialize, Serialize};
4use systemprompt_identifiers::SkillId;
5
6use super::enums::StepType;
7
8#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
9pub struct PlannedTool {
10 pub tool_name: String,
11 pub arguments: serde_json::Value,
12}
13
14#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
15#[serde(tag = "type", rename_all = "snake_case")]
16pub enum StepContent {
17 Understanding,
18 Planning {
19 #[serde(skip_serializing_if = "Option::is_none")]
20 reasoning: Option<String>,
21 #[serde(skip_serializing_if = "Option::is_none")]
22 planned_tools: Option<Vec<PlannedTool>>,
23 },
24 SkillUsage {
25 skill_id: SkillId,
26 skill_name: String,
27 },
28 ToolExecution {
29 tool_name: String,
30 tool_arguments: serde_json::Value,
31 #[serde(skip_serializing_if = "Option::is_none")]
32 tool_result: Option<serde_json::Value>,
33 },
34 Completion,
35}
36
37impl StepContent {
38 #[must_use]
39 pub const fn understanding() -> Self {
40 Self::Understanding
41 }
42
43 #[must_use]
44 pub const fn planning(
45 reasoning: Option<String>,
46 planned_tools: Option<Vec<PlannedTool>>,
47 ) -> Self {
48 Self::Planning {
49 reasoning,
50 planned_tools,
51 }
52 }
53
54 pub fn skill_usage(skill_id: SkillId, skill_name: impl Into<String>) -> Self {
55 Self::SkillUsage {
56 skill_id,
57 skill_name: skill_name.into(),
58 }
59 }
60
61 pub fn tool_execution(tool_name: impl Into<String>, tool_arguments: serde_json::Value) -> Self {
62 Self::ToolExecution {
63 tool_name: tool_name.into(),
64 tool_arguments,
65 tool_result: None,
66 }
67 }
68
69 #[must_use]
70 pub const fn completion() -> Self {
71 Self::Completion
72 }
73
74 #[must_use]
75 pub const fn step_type(&self) -> StepType {
76 match self {
77 Self::Understanding => StepType::Understanding,
78 Self::Planning { .. } => StepType::Planning,
79 Self::SkillUsage { .. } => StepType::SkillUsage,
80 Self::ToolExecution { .. } => StepType::ToolExecution,
81 Self::Completion => StepType::Completion,
82 }
83 }
84
85 #[must_use]
86 pub fn title(&self) -> String {
87 match self {
88 Self::Understanding => "Analyzing request...".to_string(),
89 Self::Planning { .. } => "Planning response...".to_string(),
90 Self::SkillUsage { skill_name, .. } => format!("Using {skill_name} skill..."),
91 Self::ToolExecution { tool_name, .. } => format!("Running {tool_name}..."),
92 Self::Completion => "Complete".to_string(),
93 }
94 }
95
96 #[must_use]
97 pub const fn is_instant(&self) -> bool {
98 !matches!(self, Self::ToolExecution { .. })
99 }
100
101 #[must_use]
102 pub fn tool_name(&self) -> Option<&str> {
103 match self {
104 Self::ToolExecution { tool_name, .. } => Some(tool_name),
105 Self::SkillUsage { skill_name, .. } => Some(skill_name),
106 Self::Understanding | Self::Planning { .. } | Self::Completion => None,
107 }
108 }
109
110 #[must_use]
111 pub const fn tool_arguments(&self) -> Option<&serde_json::Value> {
112 match self {
113 Self::ToolExecution { tool_arguments, .. } => Some(tool_arguments),
114 Self::Understanding
115 | Self::Planning { .. }
116 | Self::SkillUsage { .. }
117 | Self::Completion => None,
118 }
119 }
120
121 #[must_use]
122 pub const fn tool_result(&self) -> Option<&serde_json::Value> {
123 match self {
124 Self::ToolExecution { tool_result, .. } => tool_result.as_ref(),
125 Self::Understanding
126 | Self::Planning { .. }
127 | Self::SkillUsage { .. }
128 | Self::Completion => None,
129 }
130 }
131
132 #[must_use]
133 pub fn reasoning(&self) -> Option<&str> {
134 match self {
135 Self::Planning { reasoning, .. } => reasoning.as_deref(),
136 Self::Understanding
137 | Self::SkillUsage { .. }
138 | Self::ToolExecution { .. }
139 | Self::Completion => None,
140 }
141 }
142
143 #[must_use]
144 pub fn planned_tools(&self) -> Option<&[PlannedTool]> {
145 match self {
146 Self::Planning { planned_tools, .. } => planned_tools.as_deref(),
147 Self::Understanding
148 | Self::SkillUsage { .. }
149 | Self::ToolExecution { .. }
150 | Self::Completion => None,
151 }
152 }
153
154 #[must_use]
155 pub fn with_tool_result(self, result: serde_json::Value) -> Self {
156 match self {
157 Self::ToolExecution {
158 tool_name,
159 tool_arguments,
160 ..
161 } => Self::ToolExecution {
162 tool_name,
163 tool_arguments,
164 tool_result: Some(result),
165 },
166 other @ (Self::Understanding
167 | Self::Planning { .. }
168 | Self::SkillUsage { .. }
169 | Self::Completion) => other,
170 }
171 }
172}