codetether_agent/cli/
context.rs1use anyhow::{Result, bail};
4use serde_json::json;
5
6use crate::cli::{
7 ContextArgs, ContextBrowseArgs, ContextBrowseCommand, ContextCommand, ContextResetArgs,
8};
9use crate::provider::{ContentPart, Message, Role};
10use crate::session::Session;
11use crate::tool::context_browse::ContextBrowseTool;
12use crate::tool::context_reset::format_reset_marker;
13use crate::tool::{Tool, ToolResult};
14
15const DEFAULT_RESET_SUMMARY: &str = "Manual context reset requested from the CLI.";
16
17pub async fn execute(args: ContextArgs) -> Result<()> {
18 match args.command {
19 ContextCommand::Reset(args) => reset(args).await,
20 ContextCommand::Browse(args) => browse(args).await,
21 }
22}
23
24async fn reset(args: ContextResetArgs) -> Result<()> {
25 let cwd = std::env::current_dir()?;
26 let mut session = Session::last_for_directory(Some(cwd.as_path())).await?;
27 let summary = args
28 .summary
29 .as_deref()
30 .map(str::trim)
31 .filter(|s| !s.is_empty())
32 .unwrap_or(DEFAULT_RESET_SUMMARY);
33 let marker = format_reset_marker(summary, summary.len());
34 session.add_message(Message {
35 role: Role::Assistant,
36 content: vec![ContentPart::Text {
37 text: marker.clone(),
38 }],
39 });
40 session.save().await?;
41 println!("{marker}");
42 Ok(())
43}
44
45async fn browse(args: ContextBrowseArgs) -> Result<()> {
46 let tool = ContextBrowseTool;
47 let payload = match args.command {
48 Some(ContextBrowseCommand::ShowTurn(args)) => {
49 json!({"action": "show_turn", "turn": args.turn})
50 }
51 None | Some(ContextBrowseCommand::List) => json!({"action": "list"}),
52 };
53 print_result(tool.execute(payload).await?)
54}
55
56fn print_result(result: ToolResult) -> Result<()> {
57 if result.success {
58 println!("{}", result.output);
59 Ok(())
60 } else {
61 bail!("{}", result.output)
62 }
63}