aboutsummaryrefslogtreecommitdiffstats
path: root/crates/atuin-ai/src/fsm/effects.rs
blob: adc9628e54f7670bcfa2d2ecc678aa403145b372 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
//! 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 },
    /// Load a skill's content asynchronously (read + interpolate).
    LoadSkill {
        name: String,
        arguments: Option<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 fires an event after the given delay.
    ScheduleTimeout {
        timeout_id: u64,
        duration: Duration,
        kind: TimeoutKind,
    },

    // ─── Exit ───────────────────────────────────────────────────
    /// Exit the application with the given action.
    ExitApp(ExitAction),
}

/// What kind of timeout was scheduled.
#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) enum TimeoutKind {
    /// Dangerous command confirmation dialog auto-dismiss.
    Confirmation,
    /// Shell tool execution timeout — abort the tool if it's still running.
    ToolExecution { tool_id: String },
}

/// 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,
}