use serde::{Deserialize, Serialize};
use crate::events::ActionEvent;
use crate::types::{GroupId, TaskId};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ActionRecord {
pub task_id: TaskId,
pub group_id: Option<GroupId>,
pub tick: u64,
pub worker_id: usize,
pub action: String,
pub target: Option<String>,
pub success: bool,
pub error: Option<String>,
pub duration_ms: u64,
pub selection_logic: Option<String>,
pub from_guidance: bool,
pub previous_action: Option<String>,
pub lora: Option<String>,
}
impl ActionRecord {
pub fn new(tick: u64, worker_id: usize, action: impl Into<String>) -> Self {
Self {
task_id: TaskId::new(),
group_id: None,
tick,
worker_id,
action: action.into(),
target: None,
success: true,
error: None,
duration_ms: 0,
selection_logic: None,
from_guidance: false,
previous_action: None,
lora: None,
}
}
pub fn task_id(mut self, task_id: TaskId) -> Self {
self.task_id = task_id;
self
}
pub fn group_id(mut self, group_id: GroupId) -> Self {
self.group_id = Some(group_id);
self
}
pub fn target(mut self, target: impl Into<String>) -> Self {
self.target = Some(target.into());
self
}
pub fn success(mut self, success: bool) -> Self {
self.success = success;
self
}
pub fn error(mut self, error: impl Into<String>) -> Self {
self.error = Some(error.into());
self.success = false;
self
}
pub fn duration_ms(mut self, duration_ms: u64) -> Self {
self.duration_ms = duration_ms;
self
}
pub fn selection_logic(mut self, logic: impl Into<String>) -> Self {
self.selection_logic = Some(logic.into());
self
}
pub fn from_guidance(mut self) -> Self {
self.from_guidance = true;
self
}
pub fn previous_action(mut self, action: impl Into<String>) -> Self {
self.previous_action = Some(action.into());
self
}
pub fn lora(mut self, lora: impl Into<String>) -> Self {
self.lora = Some(lora.into());
self
}
pub fn is_terminal(&self) -> bool {
self.action == "done"
}
}
impl From<&ActionEvent> for ActionRecord {
fn from(event: &ActionEvent) -> Self {
Self {
task_id: event.task_id,
group_id: event.group_id,
tick: event.tick,
worker_id: event.worker_id.0,
action: event.action.clone(),
target: event.target.clone(),
success: event.result.success,
error: event.result.error.clone(),
duration_ms: event.duration.as_millis() as u64,
selection_logic: event.context.selection_logic.clone(),
from_guidance: event.context.from_guidance,
previous_action: event.context.previous_action.clone(),
lora: event.context.lora.as_ref().and_then(|l| l.name.clone()),
}
}
}