109 lines
4.1 KiB
Rust
109 lines
4.1 KiB
Rust
use galaxy_core::features::FeatureFlag;
|
|
use galaxyui::{AppContext, EntityId, SingletonEntity};
|
|
|
|
use crate::ai::agent::conversation::AIConversationId;
|
|
use crate::ai::agent_conversations_model::AgentConversationsModel;
|
|
use crate::ai::blocklist::history_model::BlocklistAIHistoryModel;
|
|
use crate::server::server_api::ServerApiProvider;
|
|
|
|
/// Delete a conversation from the blocklist, local storage, and the cloud.
|
|
pub fn delete_conversation(
|
|
conversation_id: AIConversationId,
|
|
terminal_view_id: Option<EntityId>,
|
|
ctx: &mut AppContext,
|
|
) {
|
|
let server_conversation_token = get_server_conversation_token(&conversation_id, ctx);
|
|
let server_api = ServerApiProvider::as_ref(ctx).get_ai_client();
|
|
|
|
BlocklistAIHistoryModel::handle(ctx).update(ctx, |history, model_ctx| {
|
|
history.delete_conversation(conversation_id, terminal_view_id, model_ctx);
|
|
|
|
if let Some(token) = server_conversation_token {
|
|
if FeatureFlag::CloudConversations.is_enabled() {
|
|
// Delete the conversation from the cloud.
|
|
let server_api = server_api.clone();
|
|
model_ctx.spawn(
|
|
async move {
|
|
if let Err(e) = server_api.delete_ai_conversation(token.clone()).await {
|
|
log::error!("Failed to delete conversation from cloud: {e:?}");
|
|
} else {
|
|
log::info!("Successfully deleted conversation from cloud: {token}");
|
|
}
|
|
},
|
|
|_, _, _| {},
|
|
);
|
|
}
|
|
} else {
|
|
log::info!(
|
|
"No server conversation token found for conversation to delete: {conversation_id}"
|
|
);
|
|
}
|
|
});
|
|
|
|
// Make sure the agent conversations model is up to date.
|
|
AgentConversationsModel::handle(ctx).update(ctx, |model, ctx| {
|
|
model.sync_conversations(ctx);
|
|
});
|
|
}
|
|
|
|
/// Remove a conversation from the blocklist and optionally from the cloud.
|
|
///
|
|
/// This is similar to `delete_conversation`, but it is only used for ephemeral/empty conversations
|
|
/// (i.e. conversations from closed empty agent mode views, or passive code diffs).
|
|
pub fn remove_conversation(
|
|
conversation_id: AIConversationId,
|
|
terminal_view_id: EntityId,
|
|
// Set this to true if the conversation has some exchanges (i.e. is not empty),
|
|
// and should thus also be cleaned up from the cloud
|
|
delete_from_cloud: bool,
|
|
ctx: &mut AppContext,
|
|
) {
|
|
let (server_conversation_token, server_api) = if delete_from_cloud {
|
|
(
|
|
get_server_conversation_token(&conversation_id, ctx),
|
|
Some(ServerApiProvider::as_ref(ctx).get_ai_client()),
|
|
)
|
|
} else {
|
|
(None, None)
|
|
};
|
|
|
|
BlocklistAIHistoryModel::handle(ctx).update(ctx, |history, model_ctx| {
|
|
history.remove_conversation(conversation_id, terminal_view_id, model_ctx);
|
|
|
|
if let (Some(token), Some(server_api)) = (server_conversation_token, server_api) {
|
|
if FeatureFlag::CloudConversations.is_enabled() {
|
|
// Delete the conversation from the cloud.
|
|
model_ctx.spawn(
|
|
async move {
|
|
if let Err(e) = server_api.delete_ai_conversation(token).await {
|
|
log::warn!("Failed to delete conversation from cloud during remove_conversation: {e:?}");
|
|
}
|
|
},
|
|
|_, _, _| {},
|
|
);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
/// Get the server conversation token for a historical or live conversation.
|
|
fn get_server_conversation_token(
|
|
conversation_id: &AIConversationId,
|
|
ctx: &AppContext,
|
|
) -> Option<String> {
|
|
let history = BlocklistAIHistoryModel::as_ref(ctx);
|
|
|
|
history
|
|
.conversation(conversation_id)
|
|
.and_then(|c| {
|
|
c.server_conversation_token()
|
|
.map(|t| t.as_str().to_string())
|
|
})
|
|
.or_else(|| {
|
|
history
|
|
.get_conversation_metadata(conversation_id)
|
|
.and_then(|m| m.server_conversation_token.as_ref())
|
|
.map(|t| t.as_str().to_string())
|
|
})
|
|
}
|