tiny_agent_rs/core/
steps.rs1use serde::{Deserialize, Serialize};
2use serde_json::Value;
3
4#[derive(Debug, Clone, Serialize, Deserialize)]
6#[serde(tag = "type", rename_all = "snake_case")]
7pub enum AgentStep {
8 Task { content: String },
10 Planning { plan: String },
12 Action {
14 tool_name: String,
15 tool_call_id: String,
16 arguments: Value,
17 },
18 Observation {
20 tool_call_id: String,
21 result: String,
22 is_error: bool,
23 },
24 FinalAnswer {
26 answer: String,
27 #[serde(default)]
28 #[serde(skip_serializing_if = "Option::is_none")]
29 structured: Option<Value>,
30 },
31}
32
33impl AgentStep {
34 pub fn to_message(&self) -> Value {
36 match self {
37 AgentStep::Task { content } => {
38 serde_json::json!({
39 "role": "user",
40 "content": content
41 })
42 }
43 AgentStep::Planning { plan } => {
44 serde_json::json!({
45 "role": "assistant",
46 "content": plan
47 })
48 }
49 AgentStep::Action {
50 tool_name,
51 tool_call_id,
52 arguments,
53 } => {
54 serde_json::json!({
55 "role": "assistant",
56 "content": null,
57 "tool_calls": [{
58 "id": tool_call_id,
59 "type": "function",
60 "function": {
61 "name": tool_name,
62 "arguments": serde_json::to_string(arguments).unwrap_or_default()
63 }
64 }]
65 })
66 }
67 AgentStep::Observation {
68 tool_call_id,
69 result,
70 ..
71 } => {
72 serde_json::json!({
73 "role": "tool",
74 "tool_call_id": tool_call_id,
75 "content": result
76 })
77 }
78 AgentStep::FinalAnswer { answer, .. } => {
79 serde_json::json!({
80 "role": "assistant",
81 "content": answer
82 })
83 }
84 }
85 }
86
87 pub fn describe(&self) -> String {
89 match self {
90 AgentStep::Task { content } => format!("🧭 Task: {}", content),
91 AgentStep::Planning { plan } => format!("🧩 Plan: {}", plan),
92 AgentStep::Action {
93 tool_name,
94 arguments,
95 ..
96 } => {
97 format!("🔧 Action: {}({})", tool_name, arguments)
98 }
99 AgentStep::Observation {
100 result, is_error, ..
101 } => {
102 if *is_error {
103 format!("❌ Error: {}", result)
104 } else {
105 format!("👁 Observation: {}", result)
106 }
107 }
108 AgentStep::FinalAnswer { answer, .. } => format!("✅ Final Answer: {}", answer),
109 }
110 }
111}