codetether_agent/tool/session_recall/
tool_struct.rs1use crate::provider::Provider;
4use crate::rlm::RlmConfig;
5use crate::tool::{Tool, ToolResult};
6use anyhow::Result;
7use async_trait::async_trait;
8use std::sync::Arc;
9
10const DEFAULT_SESSION_LIMIT: usize = 3;
11const MAX_SESSION_LIMIT: usize = 5;
13
14const DESCRIPTION: &str = "\
15RECALL FROM YOUR OWN PAST SESSIONS. Call this whenever you see \
16[AUTO CONTEXT COMPRESSION] and need specifics, or the user references \
17something from earlier. Pass a natural-language `query`. Optionally \
18pin `session_id` or widen `limit` (default 3, max 5). Distinct from \
19`memory`: `memory` is curated notes; `session_recall` is the raw archive.";
20
21pub struct SessionRecallTool {
23 provider: Arc<dyn Provider>,
24 model: String,
25 config: RlmConfig,
26}
27
28impl SessionRecallTool {
29 pub fn new(provider: Arc<dyn Provider>, model: String, config: RlmConfig) -> Self {
30 Self {
31 provider,
32 model,
33 config,
34 }
35 }
36}
37
38#[async_trait]
39impl Tool for SessionRecallTool {
40 fn id(&self) -> &str {
41 "session_recall"
42 }
43 fn name(&self) -> &str {
44 "SessionRecall"
45 }
46 fn description(&self) -> &str {
47 DESCRIPTION
48 }
49 fn parameters(&self) -> serde_json::Value {
50 super::schema::parameters()
51 }
52
53 async fn execute(&self, args: serde_json::Value) -> Result<ToolResult> {
54 let query = match args["query"].as_str() {
55 Some(q) if !q.trim().is_empty() => q.to_string(),
56 _ => return Ok(ToolResult::error("query is required")),
57 };
58 let sid = args["session_id"].as_str().map(str::to_string);
59 let limit = args["limit"]
60 .as_u64()
61 .map(|n| n as usize)
62 .unwrap_or(DEFAULT_SESSION_LIMIT)
63 .clamp(1, MAX_SESSION_LIMIT);
64
65 let (ctx, sources) = match super::context::build_recall_context(sid, limit).await {
66 Ok(ok) => ok,
67 Err(e) => {
68 return Ok(super::faults::fault_result(
69 super::faults::fault_from_error(&e),
70 format!("recall load failed: {e}"),
71 ));
72 }
73 };
74 if ctx.trim().is_empty() {
75 return Ok(super::faults::fault_result(
76 crate::session::Fault::NoMatch,
77 "No prior session history found.",
78 ));
79 }
80 super::rlm_run::run_recall(
81 &ctx,
82 &sources,
83 &query,
84 Arc::clone(&self.provider),
85 &self.model,
86 &self.config,
87 )
88 .await
89 }
90}