fix(acp): pass session_id when loading extensions so skills are discovered (#7868)
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This commit is contained in:
@@ -435,6 +435,7 @@ impl GooseAcpAgent {
|
|||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
let skip_developer = acp_developer.is_some();
|
let skip_developer = acp_developer.is_some();
|
||||||
|
let sid_str = session_id.map(|s| s.0.to_string());
|
||||||
|
|
||||||
for ext in extensions {
|
for ext in extensions {
|
||||||
if skip_developer && ext.name() == "developer" {
|
if skip_developer && ext.name() == "developer" {
|
||||||
@@ -443,7 +444,7 @@ impl GooseAcpAgent {
|
|||||||
let name = ext.name().to_string();
|
let name = ext.name().to_string();
|
||||||
match agent
|
match agent
|
||||||
.extension_manager
|
.extension_manager
|
||||||
.add_extension(ext, None, None, None)
|
.add_extension(ext, None, None, sid_str.as_deref())
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
Ok(_) => info!(extension = %name, "extension loaded"),
|
Ok(_) => info!(extension = %name, "extension loaded"),
|
||||||
|
|||||||
@@ -689,6 +689,43 @@ pub async fn run_prompt_mcp<C: Connection>() {
|
|||||||
expected_session_id.assert_matches(&session.session_id().0);
|
expected_session_id.assert_matches(&session.session_id().0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn run_prompt_skill<C: Connection>() {
|
||||||
|
let cwd = tempfile::tempdir().unwrap();
|
||||||
|
let skill_dir = cwd.path().join(".agents/skills/test-skill");
|
||||||
|
fs::create_dir_all(&skill_dir).unwrap();
|
||||||
|
fs::write(
|
||||||
|
skill_dir.join("SKILL.md"),
|
||||||
|
"---\nname: test-skill\ndescription: skill-loaded-in-acp-session\n---\nTest instructions\n",
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let expected_session_id = C::expected_session_id();
|
||||||
|
let openai = OpenAiFixture::new(
|
||||||
|
vec![(
|
||||||
|
"skill-loaded-in-acp-session".to_string(),
|
||||||
|
include_str!("../test_data/openai_basic.txt"),
|
||||||
|
)],
|
||||||
|
expected_session_id.clone(),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
let config = TestConnectionConfig {
|
||||||
|
builtins: vec!["summon".to_string()],
|
||||||
|
cwd: Some(cwd),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut conn = C::new(config, openai).await;
|
||||||
|
let SessionResult { mut session, .. } = conn.new_session().await;
|
||||||
|
expected_session_id.set(&session.session_id().0);
|
||||||
|
|
||||||
|
let output = session
|
||||||
|
.prompt("what is 1+1", PermissionDecision::Cancel)
|
||||||
|
.await;
|
||||||
|
assert_eq!(output.text, "2");
|
||||||
|
expected_session_id.assert_matches(&session.session_id().0);
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn run_mode_set_error<C: Connection>(
|
pub async fn run_mode_set_error<C: Connection>(
|
||||||
mode_id: &str,
|
mode_id: &str,
|
||||||
session_id_override: Option<&str>,
|
session_id_override: Option<&str>,
|
||||||
|
|||||||
+2
@@ -276,6 +276,7 @@ pub struct TestConnectionConfig {
|
|||||||
pub mcp_servers: Vec<McpServer>,
|
pub mcp_servers: Vec<McpServer>,
|
||||||
pub builtins: Vec<String>,
|
pub builtins: Vec<String>,
|
||||||
pub goose_mode: GooseMode,
|
pub goose_mode: GooseMode,
|
||||||
|
pub cwd: Option<tempfile::TempDir>,
|
||||||
pub data_root: PathBuf,
|
pub data_root: PathBuf,
|
||||||
pub provider_factory: Option<ProviderConstructor>,
|
pub provider_factory: Option<ProviderConstructor>,
|
||||||
pub read_text_file: Option<ReadTextFileHandler>,
|
pub read_text_file: Option<ReadTextFileHandler>,
|
||||||
@@ -288,6 +289,7 @@ impl Default for TestConnectionConfig {
|
|||||||
mcp_servers: Vec::new(),
|
mcp_servers: Vec::new(),
|
||||||
builtins: Vec::new(),
|
builtins: Vec::new(),
|
||||||
goose_mode: GooseMode::default(),
|
goose_mode: GooseMode::default(),
|
||||||
|
cwd: None,
|
||||||
data_root: PathBuf::new(),
|
data_root: PathBuf::new(),
|
||||||
provider_factory: None,
|
provider_factory: None,
|
||||||
read_text_file: None,
|
read_text_file: None,
|
||||||
|
|||||||
+9
-1
@@ -27,6 +27,7 @@ pub struct ClientToProviderConnection {
|
|||||||
session_counter: usize,
|
session_counter: usize,
|
||||||
_openai: OpenAiFixture,
|
_openai: OpenAiFixture,
|
||||||
_temp_dir: Option<tempfile::TempDir>,
|
_temp_dir: Option<tempfile::TempDir>,
|
||||||
|
_cwd: Option<tempfile::TempDir>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
@@ -128,12 +129,18 @@ impl Connection for ClientToProviderConnection {
|
|||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
|
let cwd_path = config
|
||||||
|
.cwd
|
||||||
|
.as_ref()
|
||||||
|
.map(|td| td.path().to_path_buf())
|
||||||
|
.unwrap_or(data_root);
|
||||||
|
|
||||||
let provider_config = AcpProviderConfig {
|
let provider_config = AcpProviderConfig {
|
||||||
command: "unused".into(),
|
command: "unused".into(),
|
||||||
args: vec![],
|
args: vec![],
|
||||||
env: vec![],
|
env: vec![],
|
||||||
env_remove: vec![],
|
env_remove: vec![],
|
||||||
work_dir: data_root,
|
work_dir: cwd_path,
|
||||||
mcp_servers,
|
mcp_servers,
|
||||||
session_mode_id: None,
|
session_mode_id: None,
|
||||||
permission_mapping: PermissionMapping::default(),
|
permission_mapping: PermissionMapping::default(),
|
||||||
@@ -159,6 +166,7 @@ impl Connection for ClientToProviderConnection {
|
|||||||
session_counter: 0,
|
session_counter: 0,
|
||||||
_openai: openai,
|
_openai: openai,
|
||||||
_temp_dir: temp_dir,
|
_temp_dir: temp_dir,
|
||||||
|
_cwd: config.cwd,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-1
@@ -20,6 +20,7 @@ pub struct ClientToAgentConnection {
|
|||||||
cx: JrConnectionCx<ClientToAgent>,
|
cx: JrConnectionCx<ClientToAgent>,
|
||||||
// MCP servers from config, consumed by the first new_session call.
|
// MCP servers from config, consumed by the first new_session call.
|
||||||
pending_mcp_servers: Vec<McpServer>,
|
pending_mcp_servers: Vec<McpServer>,
|
||||||
|
cwd: Option<tempfile::TempDir>,
|
||||||
updates: Arc<Mutex<Vec<SessionNotification>>>,
|
updates: Arc<Mutex<Vec<SessionNotification>>>,
|
||||||
permission: Arc<Mutex<PermissionDecision>>,
|
permission: Arc<Mutex<PermissionDecision>>,
|
||||||
notify: Arc<Notify>,
|
notify: Arc<Notify>,
|
||||||
@@ -222,6 +223,7 @@ impl Connection for ClientToAgentConnection {
|
|||||||
Self {
|
Self {
|
||||||
cx,
|
cx,
|
||||||
pending_mcp_servers: config.mcp_servers,
|
pending_mcp_servers: config.mcp_servers,
|
||||||
|
cwd: config.cwd,
|
||||||
updates,
|
updates,
|
||||||
permission,
|
permission,
|
||||||
notify,
|
notify,
|
||||||
@@ -233,7 +235,10 @@ impl Connection for ClientToAgentConnection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn new_session(&mut self) -> SessionResult<ClientToAgentSession> {
|
async fn new_session(&mut self) -> SessionResult<ClientToAgentSession> {
|
||||||
let work_dir = tempfile::tempdir().unwrap();
|
let work_dir = self
|
||||||
|
.cwd
|
||||||
|
.take()
|
||||||
|
.unwrap_or_else(|| tempfile::tempdir().unwrap());
|
||||||
let mcp_servers = std::mem::take(&mut self.pending_mcp_servers);
|
let mcp_servers = std::mem::take(&mut self.pending_mcp_servers);
|
||||||
let response = self
|
let response = self
|
||||||
.cx
|
.cx
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use common_tests::{
|
|||||||
run_fs_write_text_file_true, run_initialize_doesnt_hit_provider, run_load_mode, run_load_model,
|
run_fs_write_text_file_true, run_initialize_doesnt_hit_provider, run_load_mode, run_load_model,
|
||||||
run_load_session_mcp, run_mode_set, run_model_list, run_model_set, run_permission_persistence,
|
run_load_session_mcp, run_mode_set, run_model_list, run_model_set, run_permission_persistence,
|
||||||
run_prompt_basic, run_prompt_codemode, run_prompt_image, run_prompt_image_attachment,
|
run_prompt_basic, run_prompt_codemode, run_prompt_image, run_prompt_image_attachment,
|
||||||
run_prompt_mcp,
|
run_prompt_mcp, run_prompt_skill,
|
||||||
};
|
};
|
||||||
|
|
||||||
tests_mode_set_error!(ClientToProviderConnection);
|
tests_mode_set_error!(ClientToProviderConnection);
|
||||||
@@ -103,3 +103,8 @@ fn test_prompt_image_attachment() {
|
|||||||
fn test_prompt_mcp() {
|
fn test_prompt_mcp() {
|
||||||
run_test(async { run_prompt_mcp::<ClientToProviderConnection>().await });
|
run_test(async { run_prompt_mcp::<ClientToProviderConnection>().await });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_prompt_skill() {
|
||||||
|
run_test(async { run_prompt_skill::<ClientToProviderConnection>().await });
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use common_tests::{
|
|||||||
run_fs_write_text_file_true, run_initialize_doesnt_hit_provider, run_load_mode, run_load_model,
|
run_fs_write_text_file_true, run_initialize_doesnt_hit_provider, run_load_mode, run_load_model,
|
||||||
run_load_session_mcp, run_mode_set, run_model_list, run_model_set, run_permission_persistence,
|
run_load_session_mcp, run_mode_set, run_model_list, run_model_set, run_permission_persistence,
|
||||||
run_prompt_basic, run_prompt_codemode, run_prompt_image, run_prompt_image_attachment,
|
run_prompt_basic, run_prompt_codemode, run_prompt_image, run_prompt_image_attachment,
|
||||||
run_prompt_mcp,
|
run_prompt_mcp, run_prompt_skill,
|
||||||
};
|
};
|
||||||
|
|
||||||
tests_mode_set_error!(ClientToAgentConnection);
|
tests_mode_set_error!(ClientToAgentConnection);
|
||||||
@@ -97,3 +97,8 @@ fn test_prompt_image_attachment() {
|
|||||||
fn test_prompt_mcp() {
|
fn test_prompt_mcp() {
|
||||||
run_test(async { run_prompt_mcp::<ClientToAgentConnection>().await });
|
run_test(async { run_prompt_mcp::<ClientToAgentConnection>().await });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_prompt_skill() {
|
||||||
|
run_test(async { run_prompt_skill::<ClientToAgentConnection>().await });
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user