use serde::{Deserialize, Serialize};
use tokio::sync::broadcast;
use crate::components::AgentStatus;
use leviath_core::interaction::InteractionRequest;
#[non_exhaustive]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(tag = "event", rename_all = "snake_case")]
pub enum WorldEvent {
Spawned {
run_id: String,
agent_id: String,
blueprint: String,
},
Status {
run_id: String,
agent_id: String,
status: String,
stage: String,
iteration: usize,
tool_calls: usize,
accepts_messages: bool,
},
Tokens {
run_id: String,
agent_id: String,
prompt_tokens: usize,
completion_tokens: usize,
cached_tokens: usize,
cache_write_tokens: usize,
},
Context {
run_id: String,
agent_id: String,
total_tokens: usize,
max_tokens: usize,
},
Interaction {
run_id: String,
agent_id: String,
request: InteractionRequest,
},
Completed {
run_id: String,
agent_id: String,
status: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
final_output: Option<leviath_core::output::FinalOutput>,
},
StageTransition {
run_id: String,
agent_id: String,
from: String,
to: String,
iteration: usize,
},
ToolCallStarted {
run_id: String,
agent_id: String,
call_id: String,
tool: String,
},
ToolCallFinished {
run_id: String,
agent_id: String,
call_id: String,
tool: String,
ok: bool,
summary: String,
},
Log {
run_id: String,
agent_id: String,
line: String,
},
}
impl WorldEvent {
pub fn run_id(&self) -> &str {
match self {
WorldEvent::Spawned { run_id, .. }
| WorldEvent::Status { run_id, .. }
| WorldEvent::Tokens { run_id, .. }
| WorldEvent::Context { run_id, .. }
| WorldEvent::Interaction { run_id, .. }
| WorldEvent::Completed { run_id, .. }
| WorldEvent::StageTransition { run_id, .. }
| WorldEvent::ToolCallStarted { run_id, .. }
| WorldEvent::ToolCallFinished { run_id, .. }
| WorldEvent::Log { run_id, .. } => run_id,
}
}
}
#[derive(bevy_ecs::resource::Resource, Clone)]
pub struct WorldEventSink(pub broadcast::Sender<WorldEvent>);
pub(super) fn status_str(status: &AgentStatus) -> &'static str {
status.label()
}
#[derive(Clone, Hash)]
pub(super) struct Emitted {
pub(super) status: &'static str,
pub(super) stage: String,
pub(super) iteration: usize,
pub(super) tool_calls: usize,
pub(super) accepts_messages: bool,
pub(super) prompt_tokens: usize,
pub(super) completion_tokens: usize,
pub(super) cached_tokens: usize,
pub(super) cache_write_tokens: usize,
pub(super) context_tokens: usize,
pub(super) terminal: bool,
}