refactor: rename EventEmitter to Emitter

The Event prefix is redundant since the type lives in event.rs modules.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Bryan Helmkamp 2026-04-04 12:24:42 -04:00
parent a924b0006d
commit 9ba093288c
36 changed files with 303 additions and 309 deletions

View file

@ -79,7 +79,7 @@ Fabro is an AI-powered workflow orchestration platform. Workflows are defined as
When working on Rust crates, read the relevant strategy doc **before** making changes:
- **`docs-internal/logging-strategy.md`** — read when adding `tracing` calls (`info!`, `debug!`, `warn!`, `error!`), working on error handling paths, or adding new operations that should be observable
- **`docs-internal/events-strategy.md`** — read when adding or modifying `Event` variants, touching `EventEmitter`/`emit()`, changing `progress.jsonl` output, or adding new workflow stage types
- **`docs-internal/events-strategy.md`** — read when adding or modifying `Event` variants, touching `Emitter`/`emit()`, changing `progress.jsonl` output, or adding new workflow stage types
- **`files-internal/testing-strategy.md`** — read when adding or reorganizing tests, choosing between unit vs `tests/it`, deciding whether a test belongs in `cmd` vs `workflow` vs `scenario`, or deciding how to structure snapshots and fixtures
## Shell quoting in sandbox code

View file

@ -9,7 +9,7 @@ Detached runs rely on this distinction. If something needs to be visible after r
## Architecture
```text
Engine/Handler -> Event -> EventEmitter::emit()
Engine/Handler -> Event -> Emitter::emit()
|- trace(raw event)
|- canonicalize -> RunEventEnvelope
`- on_event(&RunEventEnvelope)
@ -22,7 +22,7 @@ Engine/Handler -> Event -> EventEmitter::emit()
The canonical envelope is built exactly once in `fabro-workflow/src/event.rs`.
- `Event` remains the internal typed source of truth.
- `EventEmitter` owns an immutable `run_id` and converts typed events into `RunEventEnvelope`.
- `Emitter` owns an immutable `run_id` and converts typed events into `RunEventEnvelope`.
- Every listener receives `&RunEventEnvelope`, not `&Event`.
- Bypass paths that cannot go through the emitter must call `canonicalize_event()` once and reuse the same envelope for every sink.
@ -100,7 +100,7 @@ Agent events now use explicit session links:
## Direct-Write Paths
Most events flow through `EventEmitter::emit()`. The remaining direct-write paths must use:
Most events flow through `Emitter::emit()`. The remaining direct-write paths must use:
1. `canonicalize_event(run_id, event)`
2. Serialize and redact once
@ -132,7 +132,7 @@ Update `extract_envelope_fields()`:
### 5. Emit it
Prefer `EventEmitter::emit(&Event::...)`.
Prefer `Emitter::emit(&Event::...)`.
Use `canonicalize_event()` only for true bypass paths.

View file

@ -44,7 +44,7 @@ User Input
- **`Sandbox`** (trait) -- Abstracts filesystem, shell, grep, and glob operations. `LocalSandbox` provides a real implementation; the trait enables sandboxing and testing.
- **`ToolRegistry`** -- Maps tool names to definitions and async executor functions. Tools are registered per-profile.
- **`History`** -- Ordered list of `Turn` variants (`User`, `Assistant`, `ToolResults`, `System`, `Steering`) that converts to LLM messages.
- **`EventEmitter`** -- Broadcasts `SessionEvent`s (tool calls, text, errors, warnings) over a `tokio::sync::broadcast` channel for UI or logging.
- **`Emitter`** -- Broadcasts `SessionEvent`s (tool calls, text, errors, warnings) over a `tokio::sync::broadcast` channel for UI or logging.
- **`SubAgentManager`** -- Spawns child `Session`s on background tasks for delegated work, with depth limits.
- **`SessionConfig`** -- Tunable parameters: max turns, tool round limits, command timeouts, loop detection, output truncation limits, and user instructions.

View file

@ -2,7 +2,7 @@ use std::fmt::Write;
use crate::agent_profile::AgentProfile;
use crate::error::AgentError;
use crate::event::EventEmitter;
use crate::event::Emitter;
use crate::file_tracker::FileTracker;
use crate::history::History;
use crate::truncation;
@ -19,7 +19,7 @@ pub fn check_context_usage(
history: &History,
provider_profile: &dyn AgentProfile,
threshold_percent: usize,
emitter: &EventEmitter,
emitter: &Emitter,
session_id: &str,
) -> bool {
let estimated_tokens = estimate_token_count(system_prompt, history);
@ -57,7 +57,7 @@ pub async fn compact_context(
system_prompt: &str,
file_tracker: &FileTracker,
preserve_count: usize,
emitter: &EventEmitter,
emitter: &Emitter,
session_id: &str,
) -> Result<(), AgentError> {
let estimated_tokens = estimate_token_count(system_prompt, history);
@ -251,7 +251,7 @@ pub fn render_turns_for_summary(turns: &[Turn]) -> String {
#[cfg(test)]
mod tests {
use super::*;
use crate::event::EventEmitter;
use crate::event::Emitter;
use crate::history::History;
use crate::test_support::TestProfile;
use crate::tool_registry::ToolRegistry;
@ -331,7 +331,7 @@ mod tests {
#[test]
fn check_context_usage_below_threshold() {
let history = History::default();
let emitter = EventEmitter::new();
let emitter = Emitter::new();
let profile = TestProfile::new();
// Empty history, huge context window => well below threshold
let over = check_context_usage("short", &history, &profile, 80, &emitter, "sess");
@ -346,7 +346,7 @@ mod tests {
content: "x".repeat(1000),
timestamp: SystemTime::now(),
});
let emitter = EventEmitter::new();
let emitter = Emitter::new();
let mut rx = emitter.subscribe();
// TestProfile has context_window=200_000 by default; use a small one
let profile = TestProfile::with_context_window(ToolRegistry::new(), 100);

View file

@ -3,11 +3,11 @@ use std::time::SystemTime;
use tokio::sync::broadcast;
#[derive(Clone)]
pub struct EventEmitter {
pub struct Emitter {
sender: broadcast::Sender<SessionEvent>,
}
impl EventEmitter {
impl Emitter {
#[must_use]
pub fn new() -> Self {
let (sender, _) = broadcast::channel(1024);
@ -36,7 +36,7 @@ impl EventEmitter {
}
}
impl Default for EventEmitter {
impl Default for Emitter {
fn default() -> Self {
Self::new()
}
@ -49,7 +49,7 @@ mod tests {
#[tokio::test]
async fn emit_and_receive_event() {
let emitter = EventEmitter::new();
let emitter = Emitter::new();
let mut receiver = emitter.subscribe();
emitter.emit(
@ -74,7 +74,7 @@ mod tests {
#[tokio::test]
async fn emit_with_data() {
let emitter = EventEmitter::new();
let emitter = Emitter::new();
let mut receiver = emitter.subscribe();
emitter.emit(
@ -93,7 +93,7 @@ mod tests {
#[tokio::test]
async fn multiple_subscribers() {
let emitter = EventEmitter::new();
let emitter = Emitter::new();
let mut rx1 = emitter.subscribe();
let mut rx2 = emitter.subscribe();
@ -111,7 +111,7 @@ mod tests {
#[test]
fn emit_without_subscribers_does_not_panic() {
let emitter = EventEmitter::new();
let emitter = Emitter::new();
emitter.emit(
"sess-4".into(),
AgentEvent::Error {
@ -122,13 +122,13 @@ mod tests {
#[test]
fn default_creates_emitter() {
let emitter = EventEmitter::default();
let emitter = Emitter::default();
let _rx = emitter.subscribe();
}
#[tokio::test]
async fn forward_preserves_session_ids() {
let emitter = EventEmitter::new();
let emitter = Emitter::new();
let mut receiver = emitter.subscribe();
emitter.forward(SessionEvent {

View file

@ -31,7 +31,7 @@ pub use config::{SessionOptions, ToolApprovalAdapter, ToolHookCallback, ToolHook
#[cfg(feature = "docker")]
pub use docker_sandbox::{DockerSandbox, DockerSandboxOptions};
pub use error::{AbortReason, AgentError};
pub use event::EventEmitter;
pub use event::Emitter;
pub use fabro_mcp::config::McpServerSettings;
pub use history::History;
pub use local_sandbox::LocalSandbox;

View file

@ -2,7 +2,7 @@ use crate::agent_profile::AgentProfile;
use crate::compaction::{check_context_usage, compact_context};
use crate::config::SessionOptions;
use crate::error::{AbortReason, AgentError};
use crate::event::EventEmitter;
use crate::event::Emitter;
use crate::file_tracker::FileTracker;
use crate::history::History;
use crate::loop_detection::detect_loop;
@ -39,7 +39,7 @@ pub struct Session {
id: String,
config: SessionOptions,
history: History,
event_emitter: EventEmitter,
event_emitter: Emitter,
state: SessionState,
llm_client: Client,
provider_profile: Arc<dyn AgentProfile>,
@ -70,7 +70,7 @@ impl Session {
id: uuid::Uuid::new_v4().to_string(),
config,
history: History::default(),
event_emitter: EventEmitter::new(),
event_emitter: Emitter::new(),
state: SessionState::Idle,
llm_client,
provider_profile,

View file

@ -1,5 +1,5 @@
use crate::config::{SessionOptions, ToolHookCallback, ToolHookDecision};
use crate::event::EventEmitter;
use crate::event::Emitter;
use crate::sandbox::Sandbox;
use crate::tool_registry::{RegisteredTool, ToolContext, ToolRegistry};
use crate::truncation::truncate_tool_output;
@ -21,7 +21,7 @@ pub async fn execute_tool_calls(
tool_hooks: Option<&Arc<dyn ToolHookCallback>>,
cancel_token: &CancellationToken,
config: &SessionOptions,
emitter: &EventEmitter,
emitter: &Emitter,
session_id: &str,
tool_env: Option<&HashMap<String, String>>,
) -> Vec<ToolResult> {
@ -62,7 +62,7 @@ async fn execute_tool_calls_sequential(
tool_hooks: Option<&Arc<dyn ToolHookCallback>>,
cancel_token: &CancellationToken,
config: &SessionOptions,
emitter: &EventEmitter,
emitter: &Emitter,
session_id: &str,
tool_env: Option<&HashMap<String, String>>,
) -> Vec<ToolResult> {
@ -98,7 +98,7 @@ async fn execute_tool_calls_parallel(
tool_hooks: Option<&Arc<dyn ToolHookCallback>>,
cancel_token: &CancellationToken,
config: &SessionOptions,
emitter: &EventEmitter,
emitter: &Emitter,
session_id: &str,
tool_env: Option<&HashMap<String, String>>,
) -> Vec<ToolResult> {
@ -145,7 +145,7 @@ pub async fn execute_and_emit_one_tool(
tool_hooks: Option<&Arc<dyn ToolHookCallback>>,
cancel_token: CancellationToken,
config: &SessionOptions,
emitter: &EventEmitter,
emitter: &Emitter,
session_id: &str,
tool_env: Option<&HashMap<String, String>>,
) -> ToolResult {
@ -172,7 +172,7 @@ async fn execute_and_emit_one_tool_with_lookup(
tool_hooks: Option<&Arc<dyn ToolHookCallback>>,
cancel_token: CancellationToken,
config: &SessionOptions,
emitter: &EventEmitter,
emitter: &Emitter,
session_id: &str,
tool_env: Option<&HashMap<String, String>>,
) -> ToolResult {
@ -345,7 +345,7 @@ pub fn validate_tool_args(
mod tests {
use super::*;
use crate::config::{ToolHookCallback, ToolHookDecision};
use crate::event::EventEmitter;
use crate::event::Emitter;
use crate::local_sandbox::LocalSandbox;
use crate::read_before_write_sandbox::ReadBeforeWriteSandbox;
use crate::test_support::MutableMockSandbox;
@ -460,7 +460,7 @@ mod tests {
}));
let tc = make_tool_call("echo", "call_1", serde_json::json!({"text": "hello"}));
let emitter = EventEmitter::new();
let emitter = Emitter::new();
let config = SessionOptions::default();
let result = execute_and_emit_one_tool(
@ -490,7 +490,7 @@ mod tests {
Arc::new(MockHookCallback::new(ToolHookDecision::Proceed));
let tc = make_tool_call("echo", "call_1", serde_json::json!({"text": "hello"}));
let emitter = EventEmitter::new();
let emitter = Emitter::new();
let config = SessionOptions::default();
let result = execute_and_emit_one_tool(
@ -520,7 +520,7 @@ mod tests {
let hooks: Arc<dyn ToolHookCallback> = mock.clone();
let tc = make_tool_call("echo", "call_1", serde_json::json!({"text": "hello"}));
let emitter = EventEmitter::new();
let emitter = Emitter::new();
let config = SessionOptions::default();
execute_and_emit_one_tool(
@ -555,7 +555,7 @@ mod tests {
let hooks: Arc<dyn ToolHookCallback> = mock.clone();
let tc = make_tool_call("fail_tool", "call_1", serde_json::json!({}));
let emitter = EventEmitter::new();
let emitter = Emitter::new();
let config = SessionOptions::default();
execute_and_emit_one_tool(
@ -587,7 +587,7 @@ mod tests {
registry.register(make_echo_tool());
let tc = make_tool_call("echo", "call_1", serde_json::json!({"text": "hello"}));
let emitter = EventEmitter::new();
let emitter = Emitter::new();
let config = SessionOptions::default();
let result = execute_and_emit_one_tool(
@ -627,7 +627,7 @@ mod tests {
"call_1",
serde_json::json!({"file_path": "a.ts", "content": "new"}),
);
let emitter = EventEmitter::new();
let emitter = Emitter::new();
let config = SessionOptions::default();
let result = execute_and_emit_one_tool(
@ -654,7 +654,7 @@ mod tests {
registry.register(make_write_file_tool());
let sandbox = make_guarded_sandbox(HashMap::from([("a.ts".into(), "content".into())]));
let emitter = EventEmitter::new();
let emitter = Emitter::new();
let config = SessionOptions::default();
// First read the file
@ -706,7 +706,7 @@ mod tests {
registry.register(make_write_file_tool());
let sandbox = make_guarded_sandbox(HashMap::from([("a.ts".into(), "content".into())]));
let emitter = EventEmitter::new();
let emitter = Emitter::new();
let config = SessionOptions::default();
// Grep matching a.ts
@ -758,7 +758,7 @@ mod tests {
"call_1",
serde_json::json!({"file_path": "a.ts", "old_string": "content", "new_string": "updated"}),
);
let emitter = EventEmitter::new();
let emitter = Emitter::new();
let config = SessionOptions::default();
let result = execute_and_emit_one_tool(
@ -789,7 +789,7 @@ mod tests {
"call_1",
serde_json::json!({"file_path": "new.ts", "content": "hello"}),
);
let emitter = EventEmitter::new();
let emitter = Emitter::new();
let config = SessionOptions::default();
let result = execute_and_emit_one_tool(

View file

@ -5,7 +5,7 @@ use anyhow::{Result, anyhow};
use fabro_interview::FileInterviewer;
use fabro_store::RuntimeState;
use fabro_types::RunId;
use fabro_workflow::event::EventEmitter;
use fabro_workflow::event::Emitter;
use fabro_workflow::operations::{StartServices, resume as resume_run, start as start_run};
use crate::shared;
@ -50,7 +50,7 @@ pub(crate) async fn execute(
let services = StartServices {
run_id: run_record.run_id,
cancel_token: None,
emitter: Arc::new(EventEmitter::new(run_record.run_id)),
emitter: Arc::new(Emitter::new(run_record.run_id)),
interviewer: Arc::new(FileInterviewer::new(
runtime_state.interview_request_path(),
runtime_state.interview_response_path(),

View file

@ -4,7 +4,7 @@ use std::time::Duration;
use fabro_graphviz::graph::{AttrValue, Node};
use fabro_llm::provider::Provider;
use fabro_workflow::context::Context;
use fabro_workflow::event::EventEmitter;
use fabro_workflow::event::Emitter;
use fabro_workflow::handler::agent::{CodergenBackend, CodergenResult};
use fabro_workflow::handler::llm::cli::AgentCliBackend;
@ -24,7 +24,7 @@ async fn run_real_cli_test(provider: Provider, model: &str) {
);
let context = Context::new();
let emitter = Arc::new(EventEmitter::default());
let emitter = Arc::new(Emitter::default());
let result = backend
.run(
&node,

View file

@ -47,7 +47,7 @@ use crate::static_files;
use crate::web_auth;
use fabro_interview::{Answer, Interviewer, QuestionType, WebInterviewer};
use fabro_workflow::context::Context;
use fabro_workflow::event::EventEmitter;
use fabro_workflow::event::Emitter;
use fabro_workflow::operations::{self, CreateRunInput, WorkflowInput};
use fabro_workflow::pipeline::Persisted;
use fabro_workflow::records::Checkpoint;
@ -650,7 +650,7 @@ async fn execute_run(state: Arc<AppState>, run_id: RunId) {
// Create interviewer and event plumbing (this is the "provisioning" phase)
let interviewer = Arc::new(WebInterviewer::new());
let context = Context::new();
let emitter = EventEmitter::new(run_id);
let emitter = Emitter::new(run_id);
if let Some(tx_clone) = event_tx {
emitter.on_event(move |event| {
let _ = tx_clone.send(event.clone());

View file

@ -4,7 +4,7 @@ use sha2::{Digest, Sha256};
use fabro_devcontainer::DevcontainerSpec;
use crate::event::{Event, EventEmitter};
use crate::event::{Emitter, Event};
use fabro_agent::sandbox::Sandbox;
use fabro_sandbox::daytona::{DaytonaSnapshotConfig, DockerfileSource};
use futures::future::try_join_all;
@ -32,7 +32,7 @@ pub fn devcontainer_to_snapshot_config(dc: &DevcontainerSpec) -> DaytonaSnapshot
/// Follows the same pattern as setup commands in `run.rs`.
pub async fn run_devcontainer_lifecycle(
sandbox: &dyn Sandbox,
emitter: &EventEmitter,
emitter: &Emitter,
phase: &str,
commands: &[fabro_devcontainer::Command],
timeout_ms: u64,
@ -139,7 +139,7 @@ pub async fn run_devcontainer_lifecycle(
async fn run_single_lifecycle_command(
sandbox: &dyn Sandbox,
emitter: &EventEmitter,
emitter: &Emitter,
phase: &str,
command: &str,
index: usize,
@ -348,7 +348,7 @@ mod tests {
#[tokio::test]
async fn shell_command_executed() {
let sandbox = TestSandbox::new();
let emitter = EventEmitter::default();
let emitter = Emitter::default();
let commands = vec![fabro_devcontainer::Command::Shell("echo hi".to_string())];
run_devcontainer_lifecycle(&sandbox, &emitter, "on_create", &commands, 300_000)
.await
@ -361,7 +361,7 @@ mod tests {
#[tokio::test]
async fn args_command_joins() {
let sandbox = TestSandbox::new();
let emitter = EventEmitter::default();
let emitter = Emitter::default();
let commands = vec![fabro_devcontainer::Command::Args(vec![
"echo".to_string(),
"hi".to_string(),
@ -380,7 +380,7 @@ mod tests {
#[tokio::test]
async fn emits_started_and_completed_events() {
let emitter = EventEmitter::default();
let emitter = Emitter::default();
let events = Arc::new(Mutex::new(Vec::<fabro_types::RunEvent>::new()));
let events_clone = Arc::clone(&events);
emitter.on_event(move |event| {
@ -417,7 +417,7 @@ mod tests {
#[tokio::test]
async fn failed_command_emits_failed_and_returns_error() {
let emitter = EventEmitter::default();
let emitter = Emitter::default();
let events = Arc::new(Mutex::new(Vec::<fabro_types::RunEvent>::new()));
let events_clone = Arc::clone(&events);
emitter.on_event(move |event| {
@ -438,7 +438,7 @@ mod tests {
#[tokio::test]
async fn empty_commands_is_noop() {
let emitter = EventEmitter::default();
let emitter = Emitter::default();
let events = Arc::new(Mutex::new(Vec::new()));
let events_clone = Arc::clone(&events);
emitter.on_event(move |event| {
@ -454,7 +454,7 @@ mod tests {
#[tokio::test]
async fn parallel_commands_run() {
let sandbox = TestSandbox::new();
let emitter = EventEmitter::default();
let emitter = Emitter::default();
let mut map = HashMap::new();
map.insert("install".to_string(), "npm install".to_string());
map.insert("build".to_string(), "npm run build".to_string());

View file

@ -1489,7 +1489,7 @@ impl StoreProgressLogger {
Self { tx }
}
pub fn register(&self, emitter: &EventEmitter) {
pub fn register(&self, emitter: &Emitter) {
let tx = self.tx.clone();
emitter.on_event(
move |event| match build_redacted_event_payload(event, &event.run_id) {
@ -1532,17 +1532,17 @@ fn epoch_millis() -> i64 {
type EventListener = Arc<dyn Fn(&RunEvent) + Send + Sync>;
/// Callback-based event emitter for workflow run events.
pub struct EventEmitter {
pub struct Emitter {
run_id: RunId,
listeners: std::sync::Mutex<Vec<EventListener>>,
/// Epoch milliseconds of the last `emit()` or `touch()` call. 0 until first event.
last_event_at: AtomicI64,
}
impl std::fmt::Debug for EventEmitter {
impl std::fmt::Debug for Emitter {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let count = self.listeners.lock().map(|l| l.len()).unwrap_or(0);
f.debug_struct("EventEmitter")
f.debug_struct("Emitter")
.field("run_id", &self.run_id)
.field("listener_count", &count)
.field("last_event_at", &self.last_event_at.load(Ordering::Relaxed))
@ -1550,13 +1550,13 @@ impl std::fmt::Debug for EventEmitter {
}
}
impl Default for EventEmitter {
impl Default for Emitter {
fn default() -> Self {
Self::new(RunId::new())
}
}
impl EventEmitter {
impl Emitter {
#[must_use]
pub fn new(run_id: RunId) -> Self {
Self {
@ -1642,13 +1642,13 @@ mod tests {
#[test]
fn event_emitter_new_has_no_listeners() {
let emitter = EventEmitter::new(fixtures::RUN_1);
let emitter = Emitter::new(fixtures::RUN_1);
assert_eq!(emitter.listeners.lock().unwrap().len(), 0);
}
#[test]
fn event_emitter_calls_listener_with_envelope() {
let emitter = EventEmitter::new(fixtures::RUN_1);
let emitter = Emitter::new(fixtures::RUN_1);
let received = Arc::new(Mutex::new(Vec::new()));
let received_clone = Arc::clone(&received);
emitter.on_event(move |event| {
@ -1672,7 +1672,7 @@ mod tests {
#[test]
fn event_emitter_default() {
let emitter = EventEmitter::default();
let emitter = Emitter::default();
assert_eq!(emitter.listeners.lock().unwrap().len(), 0);
}

View file

@ -10,7 +10,7 @@ use fabro_types::RunId;
use crate::context::keys;
use crate::context::{Context, WorkflowContext};
use crate::error::FabroError;
use crate::event::{Event, EventEmitter};
use crate::event::{Emitter, Event};
use crate::outcome::{
FailureCategory, FailureDetail, Outcome, OutcomeExt, StageStatus, StageUsage,
};
@ -42,7 +42,7 @@ pub trait CodergenBackend: Send + Sync {
prompt: &str,
context: &Context,
thread_id: Option<&str>,
emitter: &Arc<EventEmitter>,
emitter: &Arc<Emitter>,
sandbox: &Arc<dyn Sandbox>,
tool_hooks: Option<Arc<dyn fabro_agent::ToolHookCallback>>,
) -> Result<CodergenResult, FabroError>;
@ -393,7 +393,7 @@ impl Handler for AgentHandler {
#[cfg(test)]
mod tests {
use super::*;
use crate::event::EventEmitter;
use crate::event::Emitter;
use fabro_graphviz::graph::AttrValue;
use fabro_store::{SlateRunStore, SlateStore, StageId};
use fabro_types::fixtures;
@ -422,7 +422,7 @@ mod tests {
let store = test_store();
let run_store = store.create_run(&fixtures::RUN_1).await.unwrap();
let services = EngineServices {
emitter: Arc::new(crate::event::EventEmitter::new(fixtures::RUN_1)),
emitter: Arc::new(crate::event::Emitter::new(fixtures::RUN_1)),
run_store: run_store.clone(),
..EngineServices::test_default()
};
@ -591,7 +591,7 @@ mod tests {
_prompt: &str,
_context: &Context,
_thread_id: Option<&str>,
_emitter: &Arc<EventEmitter>,
_emitter: &Arc<Emitter>,
_sandbox: &Arc<dyn fabro_agent::Sandbox>,
_tool_hooks: Option<Arc<dyn fabro_agent::ToolHookCallback>>,
) -> Result<CodergenResult, FabroError> {
@ -647,7 +647,7 @@ mod tests {
_prompt: &str,
_context: &Context,
_thread_id: Option<&str>,
_emitter: &Arc<EventEmitter>,
_emitter: &Arc<Emitter>,
_sandbox: &Arc<dyn fabro_agent::Sandbox>,
_tool_hooks: Option<Arc<dyn fabro_agent::ToolHookCallback>>,
) -> Result<CodergenResult, FabroError> {
@ -705,7 +705,7 @@ mod tests {
_prompt: &str,
context: &Context,
_thread_id: Option<&str>,
emitter: &Arc<EventEmitter>,
emitter: &Arc<Emitter>,
_sandbox: &Arc<dyn fabro_agent::Sandbox>,
_tool_hooks: Option<Arc<dyn fabro_agent::ToolHookCallback>>,
) -> Result<CodergenResult, FabroError> {
@ -812,7 +812,7 @@ mod tests {
_prompt: &str,
_context: &Context,
thread_id: Option<&str>,
_emitter: &Arc<EventEmitter>,
_emitter: &Arc<Emitter>,
_sandbox: &Arc<dyn Sandbox>,
_tool_hooks: Option<Arc<dyn fabro_agent::ToolHookCallback>>,
) -> Result<CodergenResult, FabroError> {
@ -864,7 +864,7 @@ mod tests {
_prompt: &str,
_context: &Context,
thread_id: Option<&str>,
_emitter: &Arc<EventEmitter>,
_emitter: &Arc<Emitter>,
_sandbox: &Arc<dyn Sandbox>,
_tool_hooks: Option<Arc<dyn fabro_agent::ToolHookCallback>>,
) -> Result<CodergenResult, FabroError> {
@ -911,7 +911,7 @@ mod tests {
_prompt: &str,
_context: &Context,
_thread_id: Option<&str>,
_emitter: &Arc<EventEmitter>,
_emitter: &Arc<Emitter>,
_sandbox: &Arc<dyn Sandbox>,
_tool_hooks: Option<Arc<dyn fabro_agent::ToolHookCallback>>,
) -> Result<CodergenResult, FabroError> {
@ -1054,7 +1054,7 @@ Some text in between.
_prompt: &str,
_context: &Context,
_thread_id: Option<&str>,
_emitter: &Arc<EventEmitter>,
_emitter: &Arc<Emitter>,
_sandbox: &Arc<dyn Sandbox>,
_tool_hooks: Option<Arc<dyn fabro_agent::ToolHookCallback>>,
) -> Result<CodergenResult, FabroError> {
@ -1092,7 +1092,7 @@ Some text in between.
prompt: &str,
_context: &Context,
_thread_id: Option<&str>,
_emitter: &Arc<EventEmitter>,
_emitter: &Arc<Emitter>,
_sandbox: &Arc<dyn Sandbox>,
_tool_hooks: Option<Arc<dyn fabro_agent::ToolHookCallback>>,
) -> Result<CodergenResult, FabroError> {
@ -1161,7 +1161,7 @@ Some text in between.
prompt: &str,
_context: &Context,
_thread_id: Option<&str>,
_emitter: &Arc<EventEmitter>,
_emitter: &Arc<Emitter>,
_sandbox: &Arc<dyn Sandbox>,
_tool_hooks: Option<Arc<dyn fabro_agent::ToolHookCallback>>,
) -> Result<CodergenResult, FabroError> {

View file

@ -195,7 +195,7 @@ mod tests {
let store = test_store();
let run_store = store.create_run(&fixtures::RUN_1).await.unwrap();
let services = EngineServices {
emitter: Arc::new(crate::event::EventEmitter::new(fixtures::RUN_1)),
emitter: Arc::new(crate::event::Emitter::new(fixtures::RUN_1)),
run_store: run_store.clone(),
..EngineServices::test_default()
};

View file

@ -4,7 +4,7 @@ use std::sync::Arc;
use crate::context::Context;
use crate::context::keys;
use crate::error::FabroError;
use crate::event::{Event, EventEmitter};
use crate::event::{Emitter, Event};
use crate::outcome::{Outcome, OutcomeExt};
use crate::run_dir::visit_from_context;
use crate::sandbox_git::git_merge_ff_only;
@ -220,7 +220,7 @@ async fn llm_evaluate(
context: &Context,
_run_dir: &Path,
node_id: &str,
emitter: &Arc<EventEmitter>,
emitter: &Arc<Emitter>,
sandbox: &Arc<dyn Sandbox>,
) -> Result<Candidate, FabroError> {
let results_text =
@ -458,7 +458,7 @@ mod tests {
_prompt: &str,
_context: &Context,
_thread_id: Option<&str>,
_emitter: &Arc<EventEmitter>,
_emitter: &Arc<Emitter>,
_sandbox: &Arc<dyn Sandbox>,
_tool_hooks: Option<Arc<dyn fabro_agent::ToolHookCallback>>,
) -> Result<CodergenResult, FabroError> {

View file

@ -7,7 +7,7 @@ use async_trait::async_trait;
use crate::context::Context;
use crate::context::keys;
use crate::error::FabroError;
use crate::event::{Event, EventEmitter};
use crate::event::{Emitter, Event};
use crate::millis_u64;
use crate::outcome::{Outcome, OutcomeExt};
use fabro_graphviz::graph::{Graph, Node};
@ -68,7 +68,7 @@ fn parse_accelerator_key(label: &str) -> String {
/// Blocks until a human selects an option derived from outgoing edges.
pub struct HumanHandler {
interviewer: Arc<dyn Interviewer>,
emitter: Option<Arc<EventEmitter>>,
emitter: Option<Arc<Emitter>>,
}
impl HumanHandler {
@ -80,7 +80,7 @@ impl HumanHandler {
}
#[must_use]
pub fn with_emitter(mut self, emitter: Arc<EventEmitter>) -> Self {
pub fn with_emitter(mut self, emitter: Arc<Emitter>) -> Self {
self.emitter = Some(emitter);
self
}

View file

@ -19,7 +19,7 @@ use super::super::agent::{CodergenBackend, CodergenResult};
use crate::context::keys::Fidelity;
use crate::context::{Context, WorkflowContext};
use crate::error::FabroError;
use crate::event::{Event, EventEmitter};
use crate::event::{Emitter, Event};
use crate::outcome::StageUsage;
use crate::outcome::compute_stage_cost;
use crate::run_dir::visit_from_context;
@ -88,7 +88,7 @@ fn spawn_event_forwarder(
session: &Session,
node_id: String,
visit: u32,
emitter: Arc<EventEmitter>,
emitter: Arc<Emitter>,
file_tracking: Arc<Mutex<FileTracking>>,
) {
let mut rx = session.subscribe();
@ -410,7 +410,7 @@ impl CodergenBackend for AgentApiBackend {
prompt: &str,
context: &Context,
thread_id: Option<&str>,
emitter: &Arc<EventEmitter>,
emitter: &Arc<Emitter>,
sandbox: &Arc<dyn Sandbox>,
tool_hooks: Option<Arc<dyn fabro_agent::ToolHookCallback>>,
) -> Result<CodergenResult, FabroError> {

View file

@ -10,7 +10,7 @@ use tokio::time::sleep;
use super::super::agent::{CodergenBackend, CodergenResult};
use crate::context::Context;
use crate::error::FabroError;
use crate::event::{Event, EventEmitter};
use crate::event::{Emitter, Event};
use crate::outcome::StageUsage;
use crate::outcome::compute_stage_cost;
use crate::run_dir::visit_from_context;
@ -67,7 +67,7 @@ async fn ensure_cli(
cli: AgentCli,
provider: Provider,
sandbox: &Arc<dyn Sandbox>,
emitter: &Arc<EventEmitter>,
emitter: &Arc<Emitter>,
) -> Result<(), FabroError> {
let start = std::time::Instant::now();
let cli_name = cli.name();
@ -463,7 +463,7 @@ impl CodergenBackend for AgentCliBackend {
prompt: &str,
_context: &Context,
_thread_id: Option<&str>,
emitter: &Arc<EventEmitter>,
emitter: &Arc<Emitter>,
sandbox: &Arc<dyn Sandbox>,
_tool_hooks: Option<Arc<dyn fabro_agent::ToolHookCallback>>,
) -> Result<CodergenResult, FabroError> {
@ -752,7 +752,7 @@ impl CodergenBackend for BackendRouter {
prompt: &str,
context: &Context,
thread_id: Option<&str>,
emitter: &Arc<EventEmitter>,
emitter: &Arc<Emitter>,
sandbox: &Arc<dyn Sandbox>,
tool_hooks: Option<Arc<dyn fabro_agent::ToolHookCallback>>,
) -> Result<CodergenResult, FabroError> {
@ -944,7 +944,7 @@ mod tests {
vec![ok_result()],
Arc::clone(&commands),
));
let emitter = Arc::new(EventEmitter::default());
let emitter = Arc::new(Emitter::default());
let result = ensure_cli(AgentCli::Claude, Provider::Anthropic, &sandbox, &emitter).await;
assert!(result.is_ok());
@ -965,7 +965,7 @@ mod tests {
],
Arc::clone(&commands),
));
let emitter = Arc::new(EventEmitter::default());
let emitter = Arc::new(Emitter::default());
let result = ensure_cli(AgentCli::Claude, Provider::Anthropic, &sandbox, &emitter).await;
assert!(result.is_ok());
@ -985,7 +985,7 @@ mod tests {
],
Arc::clone(&commands),
));
let emitter = Arc::new(EventEmitter::default());
let emitter = Arc::new(Emitter::default());
let result = ensure_cli(AgentCli::Claude, Provider::Anthropic, &sandbox, &emitter).await;
assert!(result.is_err());
@ -1190,7 +1190,7 @@ mod tests {
_prompt: &str,
_context: &Context,
_thread_id: Option<&str>,
_emitter: &Arc<EventEmitter>,
_emitter: &Arc<Emitter>,
_sandbox: &Arc<dyn Sandbox>,
_tool_hooks: Option<Arc<dyn fabro_agent::ToolHookCallback>>,
) -> Result<CodergenResult, FabroError> {

View file

@ -28,7 +28,7 @@ use object_store::memory::InMemory;
use crate::context::Context;
use crate::error::FabroError;
use crate::event::EventEmitter;
use crate::event::Emitter;
use crate::outcome::{Outcome, OutcomeExt};
use crate::sandbox_git::GitState;
use fabro_graphviz::graph::{Graph, Node, shape_to_handler_type};
@ -38,7 +38,7 @@ use fabro_interview::Interviewer;
/// Shared services available to all handlers during execution.
pub struct EngineServices {
pub registry: Arc<HandlerRegistry>,
pub emitter: Arc<EventEmitter>,
pub emitter: Arc<Emitter>,
pub sandbox: Arc<dyn Sandbox>,
pub run_store: SlateRunStore,
/// Git state for the current run. Set via `set_git_state` at the start of
@ -82,7 +82,7 @@ impl EngineServices {
));
Self {
registry: Arc::new(HandlerRegistry::new(Box::new(start::StartHandler))),
emitter: Arc::new(EventEmitter::default()),
emitter: Arc::new(Emitter::default()),
sandbox: Arc::new(fabro_agent::LocalSandbox::new(
std::env::current_dir().unwrap_or_else(|_| std::path::PathBuf::from(".")),
)),

View file

@ -627,7 +627,7 @@ mod tests {
let store = test_store();
let run_store = store.create_run(&fixtures::RUN_1).await.unwrap();
let services = EngineServices {
emitter: Arc::new(crate::event::EventEmitter::new(fixtures::RUN_1)),
emitter: Arc::new(crate::event::Emitter::new(fixtures::RUN_1)),
run_store: run_store.clone(),
..EngineServices::test_default()
};
@ -679,7 +679,7 @@ mod tests {
let store = test_store();
let run_store = store.create_run(&fixtures::RUN_1).await.unwrap();
let services = EngineServices {
emitter: Arc::new(crate::event::EventEmitter::new(fixtures::RUN_1)),
emitter: Arc::new(crate::event::Emitter::new(fixtures::RUN_1)),
run_store: run_store.clone(),
..EngineServices::test_default()
};

View file

@ -202,7 +202,7 @@ mod tests {
let store = test_store();
let run_store = store.create_run(&fixtures::RUN_1).await.unwrap();
let services = EngineServices {
emitter: Arc::new(crate::event::EventEmitter::new(fixtures::RUN_1)),
emitter: Arc::new(crate::event::Emitter::new(fixtures::RUN_1)),
run_store: run_store.clone(),
..EngineServices::test_default()
};
@ -260,7 +260,7 @@ mod tests {
_prompt: &str,
_context: &Context,
_thread_id: Option<&str>,
_emitter: &Arc<crate::event::EventEmitter>,
_emitter: &Arc<crate::event::Emitter>,
_sandbox: &Arc<dyn Sandbox>,
_tool_hooks: Option<Arc<dyn fabro_agent::ToolHookCallback>>,
) -> Result<CodergenResult, FabroError> {
@ -320,7 +320,7 @@ mod tests {
_prompt: &str,
_context: &Context,
_thread_id: Option<&str>,
_emitter: &Arc<crate::event::EventEmitter>,
_emitter: &Arc<crate::event::Emitter>,
_sandbox: &Arc<dyn Sandbox>,
_tool_hooks: Option<Arc<dyn fabro_agent::ToolHookCallback>>,
) -> Result<CodergenResult, FabroError> {
@ -377,7 +377,7 @@ mod tests {
_prompt: &str,
_context: &Context,
_thread_id: Option<&str>,
_emitter: &Arc<crate::event::EventEmitter>,
_emitter: &Arc<crate::event::Emitter>,
_sandbox: &Arc<dyn fabro_agent::Sandbox>,
_tool_hooks: Option<Arc<dyn fabro_agent::ToolHookCallback>>,
) -> Result<CodergenResult, FabroError> {

View file

@ -12,7 +12,7 @@ use fabro_core::state::ExecutionState;
use crate::artifact::{offload_large_values, sync_artifacts_to_env};
use crate::artifact_snapshot::collect_artifacts;
use crate::event::{Event, EventEmitter, RunNoticeLevel};
use crate::event::{Emitter, Event, RunNoticeLevel};
use crate::graph::WorkflowGraph;
use crate::graph::WorkflowNode;
use crate::outcome::StageUsage;
@ -28,7 +28,7 @@ pub(crate) struct ArtifactLifecycle {
pub sandbox: Arc<dyn fabro_sandbox::Sandbox>,
pub run_store: SlateRunStore,
pub blob_cache_dir: PathBuf,
pub emitter: Arc<EventEmitter>,
pub emitter: Arc<Emitter>,
pub artifacts_dir: PathBuf,
pub artifact_globs: Vec<String>,
pub captured_artifact_count: Arc<AtomicUsize>,
@ -42,7 +42,7 @@ impl ArtifactLifecycle {
sandbox: Arc<dyn fabro_sandbox::Sandbox>,
run_store: SlateRunStore,
blob_cache_dir: PathBuf,
emitter: Arc<EventEmitter>,
emitter: Arc<Emitter>,
artifacts_dir: PathBuf,
artifact_globs: Vec<String>,
captured_artifact_count: Arc<AtomicUsize>,

View file

@ -17,7 +17,7 @@ use super::circuit_breaker::CircuitBreakerLifecycle;
use super::git::GitCheckpointResult;
use crate::context;
use crate::error::FabroError;
use crate::event::{Event, EventEmitter};
use crate::event::{Emitter, Event};
use crate::graph::WorkflowGraph;
use crate::graph::WorkflowNode;
use crate::outcome::{
@ -34,7 +34,7 @@ type FailureSignatureSnapshot = (
/// Sub-lifecycle responsible for emitting workflow run events.
pub(crate) struct EventLifecycle {
pub emitter: Arc<EventEmitter>,
pub emitter: Arc<Emitter>,
pub graph_name: String,
pub run_id: RunId,
pub run_start: Mutex<Instant>,

View file

@ -13,7 +13,7 @@ use fabro_core::lifecycle::RunLifecycle;
use fabro_core::outcome::NodeResult;
use fabro_core::state::ExecutionState;
use crate::event::{Event, EventEmitter, RunNoticeLevel};
use crate::event::{Emitter, Event, RunNoticeLevel};
use crate::git::MetadataStore;
use crate::graph::WorkflowGraph;
use crate::graph::WorkflowNode;
@ -63,7 +63,7 @@ pub(crate) struct GitCheckpointResult {
/// Sub-lifecycle responsible for git operations (checkpoint commits, pushes, diffs).
pub(crate) struct GitLifecycle {
pub sandbox: Arc<dyn fabro_sandbox::Sandbox>,
pub emitter: Arc<EventEmitter>,
pub emitter: Arc<Emitter>,
pub run_dir: PathBuf,
pub run_id: RunId,
pub run_store: SlateRunStore,

View file

@ -27,7 +27,7 @@ use fabro_core::state::ExecutionState;
use crate::context;
use crate::error::{FailureSignature, FailureSignatureExt};
use crate::event::EventEmitter;
use crate::event::Emitter;
use crate::graph::WorkflowGraph;
use crate::graph::WorkflowNode;
use crate::outcome::{Outcome, StageUsage};
@ -76,7 +76,7 @@ pub(crate) struct WorkflowLifecycle {
impl WorkflowLifecycle {
#[allow(clippy::too_many_arguments)]
pub(crate) fn new(
emitter: &Arc<EventEmitter>,
emitter: &Arc<Emitter>,
hook_runner: Option<Arc<HookRunner>>,
sandbox: &Arc<dyn Sandbox>,
graph: Arc<GvGraph>,

View file

@ -15,7 +15,7 @@ use fabro_types::{RunId, Settings};
use crate::context::Context;
use crate::error::FabroError;
use crate::event::{
Event, EventBody, EventEmitter, RunNoticeLevel, StoreProgressLogger, append_event,
Emitter, Event, EventBody, RunNoticeLevel, StoreProgressLogger, append_event,
event_payload_from_redacted_json, redacted_event_json, to_run_event,
};
use crate::git::MetadataStore;
@ -37,7 +37,7 @@ use tokio::runtime::Handle;
struct RunSession {
cancel_token: Option<Arc<AtomicBool>>,
emitter: Arc<EventEmitter>,
emitter: Arc<Emitter>,
sandbox: SandboxSpec,
llm: LlmSpec,
interviewer: Arc<dyn Interviewer>,
@ -63,7 +63,7 @@ struct RunSession {
pub struct StartServices {
pub run_id: RunId,
pub cancel_token: Option<Arc<AtomicBool>>,
pub emitter: Arc<EventEmitter>,
pub emitter: Arc<Emitter>,
pub interviewer: Arc<dyn Interviewer>,
pub run_store: SlateRunStore,
pub github_app: Option<fabro_github::GitHubAppCredentials>,
@ -811,7 +811,7 @@ mod tests {
use super::*;
use crate::context::Context;
use crate::event::EventEmitter;
use crate::event::Emitter;
use crate::handler::HandlerRegistry;
use crate::handler::exit::ExitHandler;
use crate::handler::start::StartHandler;
@ -871,7 +871,7 @@ mod tests {
async fn test_start_services(
store: &SlateStore,
_run_dir: &Path,
emitter: Arc<EventEmitter>,
emitter: Arc<Emitter>,
registry: Arc<HandlerRegistry>,
) -> StartServices {
StartServices {
@ -890,7 +890,7 @@ mod tests {
async fn start_captures_checkpoint_git_sha_in_conclusion() {
let temp = tempfile::tempdir().unwrap();
let run_dir = temp.path().join("run");
let emitter = Arc::new(EventEmitter::new(fixtures::RUN_1));
let emitter = Arc::new(Emitter::new(fixtures::RUN_1));
let registry = Arc::new(test_registry());
let injected = Arc::new(AtomicBool::new(false));
@ -944,7 +944,7 @@ mod tests {
async fn start_loads_persisted_from_run_dir() {
let temp = tempfile::tempdir().unwrap();
let run_dir = temp.path().join("run");
let emitter = Arc::new(EventEmitter::new(fixtures::RUN_1));
let emitter = Arc::new(Emitter::new(fixtures::RUN_1));
let registry = Arc::new(test_registry());
let (_persisted, store) = persisted_workflow(MINIMAL_DOT, &run_dir).await;
@ -965,7 +965,7 @@ mod tests {
async fn start_invokes_on_node_callback_before_execution() {
let temp = tempfile::tempdir().unwrap();
let run_dir = temp.path().join("run");
let emitter = Arc::new(EventEmitter::new(fixtures::RUN_1));
let emitter = Arc::new(Emitter::new(fixtures::RUN_1));
let registry = Arc::new(test_registry());
let visited = Arc::new(Mutex::new(Vec::new()));
@ -994,7 +994,7 @@ mod tests {
async fn start_errors_when_checkpoint_exists() {
let temp = tempfile::tempdir().unwrap();
let run_dir = temp.path().join("run");
let emitter = Arc::new(EventEmitter::new(fixtures::RUN_1));
let emitter = Arc::new(Emitter::new(fixtures::RUN_1));
let registry = Arc::new(test_registry());
let (_persisted, store) = persisted_workflow(MINIMAL_DOT, &run_dir).await;
@ -1063,7 +1063,7 @@ mod tests {
async fn resume_errors_when_checkpoint_missing() {
let temp = tempfile::tempdir().unwrap();
let run_dir = temp.path().join("run");
let emitter = Arc::new(EventEmitter::new(fixtures::RUN_1));
let emitter = Arc::new(Emitter::new(fixtures::RUN_1));
let registry = Arc::new(test_registry());
let (_persisted, store) = persisted_workflow(MINIMAL_DOT, &run_dir).await;
@ -1086,7 +1086,7 @@ mod tests {
let temp = tempfile::tempdir().unwrap();
let run_dir = temp.path().join("run");
std::fs::create_dir_all(&run_dir).unwrap();
let emitter = Arc::new(EventEmitter::new(fixtures::RUN_1));
let emitter = Arc::new(Emitter::new(fixtures::RUN_1));
let registry = Arc::new(test_registry());
let (_persisted, store) = persisted_workflow(MINIMAL_DOT, &run_dir).await;

View file

@ -19,7 +19,7 @@ use object_store::memory::InMemory;
use super::*;
use crate::context::{self, Context};
use crate::error::FabroError;
use crate::event::{EventEmitter, StoreProgressLogger};
use crate::event::{Emitter, StoreProgressLogger};
use crate::handler::start::StartHandler;
use crate::handler::{Handler as HandlerTrait, HandlerRegistry};
use crate::outcome::{Outcome, OutcomeExt, StageStatus};
@ -76,11 +76,11 @@ fn test_run_id(label: &str) -> RunId {
}
}
fn test_emitter(label: &str) -> EventEmitter {
EventEmitter::new(test_run_id(label))
fn test_emitter(label: &str) -> Emitter {
Emitter::new(test_run_id(label))
}
fn test_emitter_arc(label: &str) -> Arc<EventEmitter> {
fn test_emitter_arc(label: &str) -> Arc<Emitter> {
Arc::new(test_emitter(label))
}
@ -290,7 +290,7 @@ async fn execute_runs_start_to_exit_and_returns_final_context() {
async fn run_with_lifecycle(
registry: HandlerRegistry,
emitter: Arc<EventEmitter>,
emitter: Arc<Emitter>,
sandbox: Arc<dyn Sandbox>,
graph: &Graph,
run_options: RunOptions,

View file

@ -1,7 +1,7 @@
use std::sync::Arc;
use crate::error::FabroError;
use crate::event::{Event, EventEmitter, RunNoticeLevel};
use crate::event::{Emitter, Event, RunNoticeLevel};
use crate::git::MetadataStore;
use crate::outcome::{Outcome, OutcomeExt, StageStatus};
use crate::records::{Checkpoint, Conclusion, StageSummary};
@ -15,7 +15,7 @@ use fabro_store::SlateRunStore;
use super::types::{Concluded, FinalizeOptions, Retroed};
fn emit_run_notice(
emitter: &EventEmitter,
emitter: &Emitter,
level: RunNoticeLevel,
code: impl Into<String>,
message: impl Into<String>,
@ -365,7 +365,7 @@ mod tests {
std::fs::create_dir_all(&run_dir).unwrap();
let inner_store = test_store().create_run(&test_run_id()).await.unwrap();
let run_store = inner_store;
let emitter = Arc::new(EventEmitter::new(test_run_id()));
let emitter = Arc::new(Emitter::new(test_run_id()));
let store_logger = StoreProgressLogger::new(run_store.clone());
store_logger.register(&emitter);
let retroed = Retroed {

View file

@ -15,7 +15,7 @@ use shlex::try_quote;
use crate::devcontainer_bridge::{devcontainer_to_snapshot_config, run_devcontainer_lifecycle};
use crate::error::FabroError;
use crate::event::{Event, EventEmitter, RunNoticeLevel};
use crate::event::{Emitter, Event, RunNoticeLevel};
use crate::git::{self, GitSyncStatus, MetadataStore};
use crate::handler::llm::{AgentApiBackend, AgentCliBackend, BackendRouter};
use crate::handler::{HandlerRegistry, default_registry};
@ -47,7 +47,7 @@ async fn run_hooks(
}
fn emit_run_notice(
emitter: &EventEmitter,
emitter: &Emitter,
level: RunNoticeLevel,
code: impl Into<String>,
message: impl Into<String>,
@ -230,7 +230,7 @@ async fn mint_github_token(
async fn build_sandbox_env(
spec: &SandboxEnvSpec,
github_app: Option<&fabro_github::GitHubAppCredentials>,
emitter: &EventEmitter,
emitter: &Emitter,
) -> Result<HashMap<String, String>, FabroError> {
let mut env = spec.devcontainer_env.clone();
env.extend(spec.toml_env.clone());
@ -754,7 +754,7 @@ mod tests {
std::fs::create_dir_all(&run_dir).unwrap();
let (graph, source) = simple_graph();
let persisted = test_persisted(graph, source.clone(), &run_dir);
let emitter = Arc::new(crate::event::EventEmitter::new(test_run_id()));
let emitter = Arc::new(crate::event::Emitter::new(test_run_id()));
let initialized = initialize(
persisted,
@ -822,7 +822,7 @@ mod tests {
std::fs::create_dir_all(&run_dir).unwrap();
let (graph, source) = simple_graph();
let persisted = test_persisted(graph, source, &run_dir);
let emitter = Arc::new(crate::event::EventEmitter::new(test_run_id()));
let emitter = Arc::new(crate::event::Emitter::new(test_run_id()));
let store = memory_store();
let run_store = store.create_run(&test_run_id()).await.unwrap();
let store_logger = StoreProgressLogger::new(run_store.clone());

View file

@ -9,7 +9,7 @@ use fabro_llm::generate::{GenerateParams, generate};
use fabro_util::text::strip_goal_decoration;
use super::types::{Concluded, Finalized, PullRequestOptions};
use crate::event::{Event, EventEmitter, RunNoticeLevel};
use crate::event::{Emitter, Event, RunNoticeLevel};
use crate::outcome::{StageStatus, format_cost as outcome_format_cost};
use crate::records::{Conclusion, RunRecord};
use fabro_retro::retro::Retro;
@ -268,7 +268,7 @@ fn assemble_pr_body(
}
fn emit_run_notice(
emitter: &EventEmitter,
emitter: &Emitter,
level: RunNoticeLevel,
code: impl Into<String>,
message: impl Into<String>,

View file

@ -175,7 +175,7 @@ mod tests {
use super::*;
use crate::context::Context;
use crate::event::EventEmitter;
use crate::event::Emitter;
use crate::event::{Event, StoreProgressLogger, append_event};
use crate::pipeline::types::Executed;
use crate::records::{Checkpoint, CheckpointExt, RunRecord};
@ -305,7 +305,7 @@ mod tests {
let checkpoint = build_checkpoint();
let run_store = test_run_store(&run_dir, &checkpoint).await;
let emitter = Arc::new(EventEmitter::new(test_run_id()));
let emitter = Arc::new(Emitter::new(test_run_id()));
let store_logger = StoreProgressLogger::new(run_store.clone());
store_logger.register(&emitter);
let sandbox: Arc<dyn fabro_agent::Sandbox> = Arc::new(fabro_agent::LocalSandbox::new(
@ -357,7 +357,7 @@ mod tests {
std::fs::create_dir_all(&run_dir).unwrap();
let checkpoint = build_checkpoint();
let emitter = Arc::new(EventEmitter::default());
let emitter = Arc::new(Emitter::default());
let seen = Arc::new(Mutex::new(Vec::new()));
emitter.on_event({
let seen = Arc::clone(&seen);

View file

@ -17,7 +17,7 @@ use fabro_validate::Diagnostic;
use crate::context::Context;
use crate::error::FabroError;
use crate::event::EventEmitter;
use crate::event::Emitter;
use crate::handler::HandlerRegistry;
use crate::outcome::Outcome;
use crate::records::{Checkpoint, Conclusion, RunRecord};
@ -229,7 +229,7 @@ pub struct InitOptions {
pub run_id: RunId,
pub run_store: SlateRunStore,
pub dry_run: bool,
pub emitter: Arc<EventEmitter>,
pub emitter: Arc<Emitter>,
pub sandbox: SandboxSpec,
pub llm: LlmSpec,
pub interviewer: Arc<dyn Interviewer>,
@ -254,7 +254,7 @@ pub struct Initialized {
pub run_store: SlateRunStore,
pub(crate) checkpoint: Option<Checkpoint>,
pub(crate) seed_context: Option<Context>,
pub emitter: Arc<EventEmitter>,
pub emitter: Arc<Emitter>,
pub sandbox: Arc<dyn Sandbox>,
pub registry: Arc<HandlerRegistry>,
pub on_node: crate::OnNodeCallback,
@ -274,7 +274,7 @@ pub struct Executed {
pub run_options: RunOptions,
pub run_store: SlateRunStore,
pub hook_runner: Option<Arc<HookRunner>>,
pub emitter: Arc<EventEmitter>,
pub emitter: Arc<Emitter>,
pub sandbox: Arc<dyn Sandbox>,
pub duration_ms: u64,
pub final_context: Context,
@ -291,7 +291,7 @@ pub struct Retroed {
pub run_options: RunOptions,
pub run_store: SlateRunStore,
pub hook_runner: Option<Arc<HookRunner>>,
pub emitter: Arc<EventEmitter>,
pub emitter: Arc<Emitter>,
pub sandbox: Arc<dyn Sandbox>,
pub duration_ms: u64,
pub retro: Option<Retro>,
@ -306,7 +306,7 @@ pub struct Concluded {
pub pushed_branch: Option<String>,
pub graph: Graph,
pub run_options: RunOptions,
pub emitter: Arc<EventEmitter>,
pub emitter: Arc<Emitter>,
}
/// Output of the PULL_REQUEST phase.
@ -333,7 +333,7 @@ pub struct RetroOptions {
pub goal: String,
pub run_dir: PathBuf,
pub sandbox: Arc<dyn Sandbox>,
pub emitter: Option<Arc<EventEmitter>>,
pub emitter: Option<Arc<Emitter>>,
pub failed: bool,
pub run_duration_ms: u64,
pub enabled: bool,

View file

@ -9,7 +9,7 @@ use fabro_store::{RunProjection, SlateStore};
use object_store::local::LocalFileSystem;
use crate::error::{FabroError, Result};
use crate::event::{Event, EventEmitter, StoreProgressLogger, append_event};
use crate::event::{Emitter, Event, StoreProgressLogger, append_event};
use crate::handler::HandlerRegistry;
use crate::outcome::Outcome;
use crate::pipeline;
@ -28,8 +28,8 @@ struct InitializedState {
store_logger: StoreProgressLogger,
}
fn bound_emitter(run_id: fabro_types::RunId, observer: &Arc<EventEmitter>) -> Arc<EventEmitter> {
let emitter = Arc::new(EventEmitter::new(run_id));
fn bound_emitter(run_id: fabro_types::RunId, observer: &Arc<Emitter>) -> Arc<Emitter> {
let emitter = Arc::new(Emitter::new(run_id));
let observer_clone = Arc::clone(observer);
emitter.on_event(move |event| observer_clone.dispatch_run_event(event));
emitter
@ -37,7 +37,7 @@ fn bound_emitter(run_id: fabro_types::RunId, observer: &Arc<EventEmitter>) -> Ar
async fn initialized(
registry: HandlerRegistry,
emitter: Arc<EventEmitter>,
emitter: Arc<Emitter>,
sandbox: Arc<dyn Sandbox>,
graph: &GvGraph,
run_options: &RunOptions,
@ -122,7 +122,7 @@ async fn initialized(
pub async fn run_graph(
registry: HandlerRegistry,
emitter: Arc<EventEmitter>,
emitter: Arc<Emitter>,
sandbox: Arc<dyn Sandbox>,
graph: &GvGraph,
run_options: &RunOptions,
@ -146,7 +146,7 @@ pub async fn run_graph(
pub async fn run_graph_with_state(
registry: HandlerRegistry,
emitter: Arc<EventEmitter>,
emitter: Arc<Emitter>,
sandbox: Arc<dyn Sandbox>,
graph: &GvGraph,
run_options: &RunOptions,
@ -177,7 +177,7 @@ pub async fn run_graph_with_state(
pub async fn run_graph_with_hooks(
registry: HandlerRegistry,
emitter: Arc<EventEmitter>,
emitter: Arc<Emitter>,
sandbox: Arc<dyn Sandbox>,
graph: &GvGraph,
run_options: &RunOptions,
@ -203,7 +203,7 @@ pub async fn run_graph_with_hooks(
pub async fn run_graph_with_hooks_and_state(
registry: HandlerRegistry,
emitter: Arc<EventEmitter>,
emitter: Arc<Emitter>,
sandbox: Arc<dyn Sandbox>,
graph: &GvGraph,
run_options: &RunOptions,
@ -236,7 +236,7 @@ pub async fn run_graph_with_hooks_and_state(
pub async fn run_graph_from_checkpoint(
registry: HandlerRegistry,
emitter: Arc<EventEmitter>,
emitter: Arc<Emitter>,
sandbox: Arc<dyn Sandbox>,
graph: &GvGraph,
run_options: &RunOptions,
@ -261,7 +261,7 @@ pub async fn run_graph_from_checkpoint(
pub async fn run_graph_from_checkpoint_with_state(
registry: HandlerRegistry,
emitter: Arc<EventEmitter>,
emitter: Arc<Emitter>,
sandbox: Arc<dyn Sandbox>,
graph: &GvGraph,
run_options: &RunOptions,
@ -293,7 +293,7 @@ pub async fn run_graph_from_checkpoint_with_state(
pub struct WorkflowRunner {
registry: std::sync::Mutex<Option<HandlerRegistry>>,
emitter: Arc<EventEmitter>,
emitter: Arc<Emitter>,
sandbox: Arc<dyn Sandbox>,
}
@ -301,7 +301,7 @@ impl WorkflowRunner {
#[must_use]
pub fn new(
registry: HandlerRegistry,
emitter: Arc<EventEmitter>,
emitter: Arc<Emitter>,
sandbox: Arc<dyn Sandbox>,
) -> Self {
Self {

View file

@ -26,7 +26,7 @@ use fabro_types::{RunId, Settings};
use fabro_workflow::artifact::sync_artifacts_to_env;
use fabro_workflow::context::Context;
use fabro_workflow::error::FabroError;
use fabro_workflow::event::EventEmitter;
use fabro_workflow::event::Emitter;
use fabro_workflow::handler::exit::ExitHandler;
use fabro_workflow::handler::start::StartHandler;
use fabro_workflow::handler::{Handler, HandlerRegistry};
@ -468,7 +468,7 @@ async fn daytona_pipeline_artifact_offload_and_sync() {
registry.register("start", Box::new(StartHandler));
registry.register("exit", Box::new(ExitHandler));
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), env.clone());
let engine = WorkflowRunner::new(registry, Arc::new(Emitter::default()), env.clone());
let run_options = RunOptions {
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
@ -644,7 +644,7 @@ async fn daytona_git_checkpoint_remote_emits_events() {
// Set up event collection
let dir = tempfile::tempdir().unwrap();
let emitter = EventEmitter::default();
let emitter = Emitter::default();
let events = Arc::new(std::sync::Mutex::new(Vec::new()));
{
let events_clone = Arc::clone(&events);
@ -818,7 +818,7 @@ async fn daytona_parallel_git_branching_e2e() {
graph.edges.push(Edge::new("fan_in", "exit"));
let run_tmp = tempfile::tempdir().unwrap();
let emitter = EventEmitter::default();
let emitter = Emitter::default();
let events = Arc::new(std::sync::Mutex::new(Vec::new()));
{
let events_clone = Arc::clone(&events);
@ -1024,7 +1024,7 @@ async fn run_daytona_cli_test(provider: Provider, model: &str, install_command:
let backend = AgentCliBackend::new(model.to_string(), provider);
let node = Node::new("daytona_cli_test");
let context = Context::new();
let emitter = Arc::new(EventEmitter::default());
let emitter = Arc::new(Emitter::default());
let result = backend
.run(
@ -1182,7 +1182,7 @@ async fn daytona_git_checkpoint_with_shadow_branch() {
registry.register("exit", Box::new(ExitHandler));
let meta_branch = MetadataStore::branch_name(&run_id.to_string());
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), env.clone());
let engine = WorkflowRunner::new(registry, Arc::new(Emitter::default()), env.clone());
let run_options = RunOptions {
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
@ -1287,7 +1287,7 @@ async fn daytona_asset_collection() {
registry.register("start", Box::new(StartHandler));
registry.register("exit", Box::new(ExitHandler));
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), env.clone());
let engine = WorkflowRunner::new(registry, Arc::new(Emitter::default()), env.clone());
let mut graph = Graph::new("DaytonaAssetTest");
graph.attrs.insert(
@ -1575,7 +1575,7 @@ async fn daytona_git_push_run_branch_to_origin() {
registry.register("start", Box::new(StartHandler));
registry.register("exit", Box::new(ExitHandler));
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), env.clone());
let engine = WorkflowRunner::new(registry, Arc::new(Emitter::default()), env.clone());
let run_options = RunOptions {
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),

File diff suppressed because it is too large Load diff