diff options
| author | Michelle Tilley <michelle@michelletilley.net> | 2026-04-21 13:07:27 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-04-21 13:07:27 -0700 |
| commit | 2f702ad446fcd6a261a3bea0ab2807d70eca43e2 (patch) | |
| tree | 4cfa6276257cefbe73f7fa46a74026170aaf8435 /crates/atuin-ai/src/fsm/effects.rs | |
| parent | docs: document show_numeric_shortcuts (#3433) (diff) | |
| download | atuin-2f702ad446fcd6a261a3bea0ab2807d70eca43e2.zip | |
refactor: Replace ad-hoc dispatch with FSM + driver architecture (#3434)
Replaces the tangled dispatch handler system (`tui/dispatch.rs`,
`tui/state.rs`) with a pure finite state machine + driver architecture.
The FSM handles all state transitions as explicit `(State, Event) →
(NewState, Effects)` mappings. The driver executes IO effects and
bridges the TUI to the FSM.
Diffstat (limited to 'crates/atuin-ai/src/fsm/effects.rs')
| -rw-r--r-- | crates/atuin-ai/src/fsm/effects.rs | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/crates/atuin-ai/src/fsm/effects.rs b/crates/atuin-ai/src/fsm/effects.rs new file mode 100644 index 00000000..ede72a42 --- /dev/null +++ b/crates/atuin-ai/src/fsm/effects.rs @@ -0,0 +1,81 @@ +//! Effects (outputs) from the agent FSM. +//! +//! The FSM returns these as data; the driver is responsible for executing them. + +use std::path::PathBuf; +use std::time::Duration; + +use serde_json::Value; + +use crate::permissions::rule::Rule; +use crate::permissions::writer::RuleDisposition; +use crate::tools::ClientToolCall; + +/// Where to write a permission rule. +#[derive(Debug, Clone, PartialEq, Eq)] +pub(crate) enum PermissionTarget { + /// Project-level: `<git_root_or_cwd>/.atuin/permissions.ai.toml` + Project, + /// Global: `~/.config/atuin/permissions.ai.toml` + Global, +} + +/// Side effects the driver should execute after a state transition. +#[derive(Debug, Clone)] +pub(crate) enum Effect { + // ─── Network ──────────────────────────────────────────────── + /// Start a new streaming request to the server. + StartStream { + messages: Vec<Value>, + session_id: Option<String>, + }, + /// Abort the active stream connection. + AbortStream, + + // ─── Tool orchestration ───────────────────────────────────── + /// Run the permission resolver for a tool call. + CheckPermission { + tool_id: String, + tool: ClientToolCall, + }, + /// Execute a tool (file read, edit, write, shell, history search). + ExecuteTool { + tool_id: String, + tool: ClientToolCall, + }, + /// Kill a running tool (send interrupt to shell command). + AbortTool { tool_id: String }, + + // ─── Persistence ──────────────────────────────────────────── + /// Persist current conversation state to disk. + Persist, + /// Write a permanent permission rule to disk. + WritePermissionRule { + target: PermissionTarget, + rule: Rule, + disposition: RuleDisposition, + }, + /// Cache a session-scoped file permission grant. + CacheSessionGrant { path: PathBuf }, + /// Archive current session and start fresh (IO only — state already updated by FSM). + ArchiveSession, + + // ─── Timers ───────────────────────────────────────────────── + /// Schedule a timer that will fire ConfirmationTimeout after delay. + ScheduleTimeout { timeout_id: u64, duration: Duration }, + + // ─── Exit ─────────────────────────────────────────────────── + /// Exit the application with the given action. + ExitApp(ExitAction), +} + +/// What to do when exiting the TUI. +#[derive(Debug, Clone, PartialEq, Eq)] +pub(crate) enum ExitAction { + /// Run the suggested command. + Execute(String), + /// Insert the command into the shell without running. + Insert(String), + /// Exit without action. + Cancel, +} |
