Skip to main content

kvlar_core/
action.rs

1//! Action types representing what an agent wants to do.
2
3use std::collections::HashMap;
4
5use chrono::{DateTime, Utc};
6use serde::{Deserialize, Serialize};
7use uuid::Uuid;
8
9/// Represents an action an AI agent wants to perform.
10///
11/// Actions are the fundamental unit of evaluation. Every tool call, data access,
12/// or operation an agent performs is modeled as an Action.
13#[derive(Debug, Clone, Serialize, Deserialize)]
14pub struct Action {
15    /// Unique identifier for this action.
16    pub id: Uuid,
17
18    /// The type of action (e.g., "tool_call", "file_read", "file_write", "network_request").
19    pub action_type: String,
20
21    /// The specific tool or resource being accessed (e.g., "bash", "read_file", "send_email").
22    pub resource: String,
23
24    /// The agent performing the action.
25    pub agent_id: String,
26
27    /// Key-value parameters of the action (e.g., command, file path, URL).
28    pub parameters: HashMap<String, serde_json::Value>,
29
30    /// When this action was requested.
31    pub timestamp: DateTime<Utc>,
32}
33
34impl Action {
35    /// Creates a new action with the given type, resource, and agent ID.
36    pub fn new(
37        action_type: impl Into<String>,
38        resource: impl Into<String>,
39        agent_id: impl Into<String>,
40    ) -> Self {
41        Self {
42            id: Uuid::new_v4(),
43            action_type: action_type.into(),
44            resource: resource.into(),
45            agent_id: agent_id.into(),
46            parameters: HashMap::new(),
47            timestamp: Utc::now(),
48        }
49    }
50
51    /// Adds a parameter to this action.
52    pub fn with_param(
53        mut self,
54        key: impl Into<String>,
55        value: impl Into<serde_json::Value>,
56    ) -> Self {
57        self.parameters.insert(key.into(), value.into());
58        self
59    }
60}
61
62#[cfg(test)]
63mod tests {
64    use super::*;
65
66    #[test]
67    fn test_action_creation() {
68        let action = Action::new("tool_call", "bash", "agent-1");
69        assert_eq!(action.action_type, "tool_call");
70        assert_eq!(action.resource, "bash");
71        assert_eq!(action.agent_id, "agent-1");
72        assert!(action.parameters.is_empty());
73    }
74
75    #[test]
76    fn test_action_with_params() {
77        let action = Action::new("tool_call", "bash", "agent-1")
78            .with_param("command", serde_json::Value::String("ls -la".into()));
79        assert_eq!(action.parameters.len(), 1);
80        assert_eq!(
81            action.parameters.get("command").unwrap(),
82            &serde_json::Value::String("ls -la".into())
83        );
84    }
85}