171 lines
4.9 KiB
Rust
171 lines
4.9 KiB
Rust
#![recursion_limit = "256"]
|
|
#[allow(dead_code)]
|
|
#[path = "acp_common_tests/mod.rs"]
|
|
mod common_tests;
|
|
|
|
use agent_client_protocol::schema::v1::{ForkSessionRequest, ForkSessionResponse, SessionId};
|
|
use common_tests::fixtures::server::{
|
|
assert_session_response_precedes_available_commands, AcpServerConnection,
|
|
};
|
|
use common_tests::fixtures::{
|
|
run_test, spawn_acp_server_in_process, Connection, OpenAiFixture, TestConnectionConfig,
|
|
};
|
|
use goose::config::GooseMode;
|
|
use goose::conversation::message::{Message, MessageContent};
|
|
use goose::session::{SessionManager, SessionType};
|
|
use std::path::Path;
|
|
|
|
async fn new_connection(data_root: &Path) -> AcpServerConnection {
|
|
let openai = OpenAiFixture::new(
|
|
vec![],
|
|
<AcpServerConnection as Connection>::expected_session_id(),
|
|
)
|
|
.await;
|
|
<AcpServerConnection as Connection>::new(
|
|
TestConnectionConfig {
|
|
data_root: data_root.to_path_buf(),
|
|
..Default::default()
|
|
},
|
|
openai,
|
|
)
|
|
.await
|
|
}
|
|
|
|
async fn fork_session_request(
|
|
conn: &AcpServerConnection,
|
|
request: ForkSessionRequest,
|
|
) -> anyhow::Result<ForkSessionResponse> {
|
|
conn.cx()
|
|
.send_request(request)
|
|
.block_task()
|
|
.await
|
|
.map_err(Into::into)
|
|
}
|
|
|
|
async fn seed_session_with_messages(
|
|
session_manager: &SessionManager,
|
|
cwd: &Path,
|
|
messages: &[(&str, i64)],
|
|
) -> goose::session::Session {
|
|
let session = session_manager
|
|
.create_session(
|
|
cwd.to_path_buf(),
|
|
"Fork before".to_string(),
|
|
SessionType::Acp,
|
|
GooseMode::default(),
|
|
)
|
|
.await
|
|
.unwrap();
|
|
|
|
for (text, created) in messages {
|
|
let mut message = Message::user().with_text(*text);
|
|
message.created = *created;
|
|
session_manager
|
|
.add_message(&session.id, &message)
|
|
.await
|
|
.unwrap();
|
|
}
|
|
|
|
session
|
|
}
|
|
|
|
async fn session_texts(session_manager: &SessionManager, session_id: &str) -> Vec<String> {
|
|
session_manager
|
|
.get_session(session_id, true)
|
|
.await
|
|
.unwrap()
|
|
.conversation
|
|
.unwrap()
|
|
.messages()
|
|
.iter()
|
|
.flat_map(|message| {
|
|
message.content.iter().filter_map(|content| match content {
|
|
MessageContent::Text(text) => Some(text.text.clone()),
|
|
_ => None,
|
|
})
|
|
})
|
|
.collect()
|
|
}
|
|
|
|
fn conversation_before_meta(timestamp: i64) -> serde_json::Map<String, serde_json::Value> {
|
|
let mut meta = serde_json::Map::new();
|
|
meta.insert(
|
|
"conversationBefore".to_string(),
|
|
serde_json::Value::Number(timestamp.into()),
|
|
);
|
|
meta
|
|
}
|
|
|
|
#[test]
|
|
fn fork_session_response_precedes_available_commands() {
|
|
run_test(async {
|
|
let data_root = tempfile::tempdir().unwrap();
|
|
let cwd = tempfile::tempdir().unwrap();
|
|
let session_manager = SessionManager::new(data_root.path().to_path_buf());
|
|
let source = seed_session_with_messages(&session_manager, cwd.path(), &[]).await;
|
|
let openai = OpenAiFixture::new(
|
|
vec![],
|
|
<AcpServerConnection as Connection>::expected_session_id(),
|
|
)
|
|
.await;
|
|
let (transport, _handle, _permission_manager) = spawn_acp_server_in_process(
|
|
openai.uri(),
|
|
&[],
|
|
data_root.path(),
|
|
GooseMode::default(),
|
|
None,
|
|
goose_test_support::TEST_MODEL,
|
|
true,
|
|
)
|
|
.await;
|
|
|
|
assert_session_response_precedes_available_commands(
|
|
transport,
|
|
"session/fork",
|
|
serde_json::json!({
|
|
"sessionId": source.id,
|
|
"cwd": cwd.path(),
|
|
"mcpServers": []
|
|
}),
|
|
)
|
|
.await;
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn fork_session_conversation_before_matches_rest_cutoff() {
|
|
run_test(async {
|
|
let data_root = tempfile::tempdir().unwrap();
|
|
let cwd = tempfile::tempdir().unwrap();
|
|
let session_manager = SessionManager::new(data_root.path().to_path_buf());
|
|
let session = seed_session_with_messages(
|
|
&session_manager,
|
|
cwd.path(),
|
|
&[
|
|
("first", 1_718_000_000),
|
|
("second", 1_718_000_060),
|
|
("third", 1_718_000_120),
|
|
],
|
|
)
|
|
.await;
|
|
let conn = new_connection(data_root.path()).await;
|
|
|
|
let response = fork_session_request(
|
|
&conn,
|
|
ForkSessionRequest::new(SessionId::new(session.id.clone()), cwd.path())
|
|
.meta(conversation_before_meta(1_718_000_120)),
|
|
)
|
|
.await
|
|
.unwrap();
|
|
|
|
assert_eq!(
|
|
session_texts(&session_manager, response.session_id.0.as_ref()).await,
|
|
vec!["first", "second"]
|
|
);
|
|
assert_eq!(
|
|
session_texts(&session_manager, &session.id).await,
|
|
vec!["first", "second", "third"]
|
|
);
|
|
});
|
|
}
|