feat(goose-acp): enable parallel sessions with isolated agent state (#6392)

Signed-off-by: Adrian Cole <adrian@tetrate.io>
This commit is contained in:
Adrian Cole
2026-01-15 06:19:17 +08:00
committed by GitHub
parent fb0eca2c36
commit 7d4a6bd8ff
86 changed files with 2594 additions and 1938 deletions
@@ -7,6 +7,7 @@ pub enum Permission {
AllowOnce,
Cancel,
DenyOnce,
AlwaysDeny,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, ToSchema)]
@@ -8,50 +8,27 @@ use anyhow::Result;
use async_trait::async_trait;
use std::collections::HashSet;
use std::sync::Arc;
use tokio::sync::Mutex;
/// Permission Inspector that handles tool permission checking
pub struct PermissionInspector {
mode: Arc<Mutex<GooseMode>>,
readonly_tools: HashSet<String>,
regular_tools: HashSet<String>,
pub permission_manager: Arc<Mutex<PermissionManager>>,
pub permission_manager: Arc<PermissionManager>,
}
impl PermissionInspector {
pub fn new(
mode: GooseMode,
readonly_tools: HashSet<String>,
regular_tools: HashSet<String>,
permission_manager: Arc<PermissionManager>,
) -> Self {
Self {
mode: Arc::new(Mutex::new(mode)),
readonly_tools,
regular_tools,
permission_manager: Arc::new(Mutex::new(PermissionManager::default())),
}
}
pub fn with_permission_manager(
mode: GooseMode,
readonly_tools: HashSet<String>,
regular_tools: HashSet<String>,
permission_manager: Arc<Mutex<PermissionManager>>,
) -> Self {
Self {
mode: Arc::new(Mutex::new(mode)),
readonly_tools,
regular_tools,
permission_manager,
}
}
/// Update the mode of this permission inspector
pub async fn update_mode(&self, new_mode: GooseMode) {
let mut mode = self.mode.lock().await;
*mode = new_mode;
}
/// Process inspection results into permission decisions
/// This method takes all inspection results and converts them into a PermissionCheckResult
/// that can be used by the agent to determine which tools to approve, deny, or ask for approval
@@ -130,16 +107,16 @@ impl ToolInspector for PermissionInspector {
&self,
tool_requests: &[ToolRequest],
_messages: &[Message],
goose_mode: GooseMode,
) -> Result<Vec<InspectionResult>> {
let mut results = Vec::new();
let permission_manager = self.permission_manager.lock().await;
let mode = self.mode.lock().await;
let permission_manager = &self.permission_manager;
for request in tool_requests {
if let Ok(tool_call) = &request.tool_call {
let tool_name = &tool_call.name;
let action = match *mode {
let action = match goose_mode {
GooseMode::Chat => continue,
GooseMode::Auto => InspectionAction::Allow,
GooseMode::Approve | GooseMode::SmartApprove => {
@@ -174,7 +151,7 @@ impl ToolInspector for PermissionInspector {
let reason = match &action {
InspectionAction::Allow => {
if *mode == GooseMode::Auto {
if goose_mode == GooseMode::Auto {
"Auto mode - all tools approved".to_string()
} else if self.readonly_tools.contains(tool_name.as_ref()) {
"Tool marked as read-only".to_string()