use std::future::Future;
use std::pin::Pin;
use crate::context::CommandContext;
use crate::{CommandError, CommandHandler, CommandOutput, SlashCategory};
pub struct CompactCommand;
impl CommandHandler<CommandContext<'_>> for CompactCommand {
fn name(&self) -> &'static str {
"/compact"
}
fn description(&self) -> &'static str {
"Compact the context window by summarizing older messages"
}
fn args_hint(&self) -> &'static str {
""
}
fn category(&self) -> SlashCategory {
SlashCategory::Session
}
fn handle<'a>(
&'a self,
ctx: &'a mut CommandContext<'_>,
_args: &'a str,
) -> Pin<Box<dyn Future<Output = Result<CommandOutput, CommandError>> + Send + 'a>> {
Box::pin(async move {
let result = ctx.agent.compact_context().await?;
Ok(CommandOutput::Message(result))
})
}
}
pub struct NewConversationCommand;
impl CommandHandler<CommandContext<'_>> for NewConversationCommand {
fn name(&self) -> &'static str {
"/new"
}
fn description(&self) -> &'static str {
"Start a new conversation (reset context, preserve memory and MCP)"
}
fn args_hint(&self) -> &'static str {
"[--no-digest] [--keep-plan]"
}
fn category(&self) -> SlashCategory {
SlashCategory::Session
}
fn handle<'a>(
&'a self,
ctx: &'a mut CommandContext<'_>,
args: &'a str,
) -> Pin<Box<dyn Future<Output = Result<CommandOutput, CommandError>> + Send + 'a>> {
Box::pin(async move {
let (keep_plan, no_digest) = parse_new_flags(args);
let result = ctx.agent.reset_conversation(keep_plan, no_digest).await?;
Ok(CommandOutput::Message(result))
})
}
}
fn parse_new_flags(args: &str) -> (bool, bool) {
let keep_plan = args.split_whitespace().any(|a| a == "--keep-plan");
let no_digest = args.split_whitespace().any(|a| a == "--no-digest");
(keep_plan, no_digest)
}
#[cfg(test)]
mod tests {
use super::parse_new_flags;
#[test]
fn no_flags_both_false() {
assert_eq!(parse_new_flags(""), (false, false));
assert_eq!(parse_new_flags(" "), (false, false));
}
#[test]
fn keep_plan_flag_detected() {
assert_eq!(parse_new_flags("--keep-plan"), (true, false));
assert_eq!(parse_new_flags("--keep-plan --no-digest"), (true, true));
}
#[test]
fn no_digest_flag_detected() {
assert_eq!(parse_new_flags("--no-digest"), (false, true));
}
#[test]
fn both_flags_order_independent() {
assert_eq!(parse_new_flags("--no-digest --keep-plan"), (true, true));
assert_eq!(parse_new_flags("--keep-plan --no-digest"), (true, true));
}
#[test]
fn partial_flag_name_not_matched() {
assert_eq!(parse_new_flags("--keep"), (false, false));
assert_eq!(parse_new_flags("--no"), (false, false));
assert_eq!(parse_new_flags("keep-plan"), (false, false));
}
}