use std::path::PathBuf;
use crate::{
AgentTerminalOperation, AgentTerminalRequestId, AgentTerminalResponse, PermissionRequestId,
ProposalId, ReadRequestId, SessionId, TerminalId, TerminalSpec,
};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PermissionDecision {
AllowOnce,
AllowAlways,
RejectOnce,
RejectAlways,
}
impl PermissionDecision {
pub fn allows(self) -> bool {
matches!(self, PermissionDecision::AllowOnce | PermissionDecision::AllowAlways)
}
pub fn is_remembered(self) -> bool {
matches!(self, PermissionDecision::AllowAlways | PermissionDecision::RejectAlways)
}
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct AgentCapabilities {
pub load_session: bool,
pub prompt_capabilities: PromptCapabilities,
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct PromptCapabilities {
pub image: bool,
pub audio: bool,
pub embedded_context: bool,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum StopReason {
EndTurn,
Cancelled,
Refusal,
MaxTokens,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum AgentRequest {
NewSession {
cwd: PathBuf,
},
Prompt {
session: SessionId,
text: String,
context: String,
},
FileContents {
session: SessionId,
request: ReadRequestId,
path: PathBuf,
contents: Option<String>,
},
Permission {
request: PermissionRequestId,
decision: PermissionDecision,
},
PermissionCancelled {
request: PermissionRequestId,
},
TerminalResponse {
request: AgentTerminalRequestId,
response: AgentTerminalResponse,
},
Cancel {
session: SessionId,
},
Shutdown,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum AgentEvent {
Ready {
capabilities: AgentCapabilities,
},
SessionStarted {
session: SessionId,
},
MessageChunk {
session: SessionId,
text: String,
},
ThoughtChunk {
session: SessionId,
text: String,
},
ReadFileRequested {
session: SessionId,
request: ReadRequestId,
path: PathBuf,
},
ProposedEdit {
session: SessionId,
proposal: ProposalId,
path: PathBuf,
old_text: Option<String>,
new_text: String,
},
PermissionRequested {
session: SessionId,
request: PermissionRequestId,
summary: String,
command: Vec<String>,
terminal_spec: Option<TerminalSpec>,
},
TerminalRequest {
session: SessionId,
request: AgentTerminalRequestId,
operation: AgentTerminalOperation,
},
TerminalAttached {
session: SessionId,
terminal: TerminalId,
},
TurnEnded {
session: SessionId,
reason: StopReason,
},
Failed {
session: SessionId,
message: String,
},
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn permission_answers_split_into_allow_and_remember() {
assert!(PermissionDecision::AllowOnce.allows());
assert!(PermissionDecision::AllowAlways.allows());
assert!(!PermissionDecision::RejectOnce.allows());
assert!(!PermissionDecision::RejectAlways.allows());
assert!(!PermissionDecision::AllowOnce.is_remembered());
assert!(PermissionDecision::AllowAlways.is_remembered());
assert!(
PermissionDecision::RejectAlways.is_remembered(),
"the variant the three-way stub could not express"
);
}
}