Add persistent local agent tools

This commit is contained in:
Georg Bauer
2026-07-25 14:57:17 +02:00
parent 668d8b787e
commit 4a45735072
20 changed files with 3139 additions and 37 deletions

View File

@@ -347,6 +347,7 @@ pub struct StoredMessage {
pub id: i32,
pub session_id: i32,
pub user: bool,
pub tool: bool,
pub reasoning: Option<String>,
pub reasoning_complete: bool,
pub content: String,
@@ -357,6 +358,7 @@ pub struct StoredMessage {
struct NewMessage<'a> {
session_id: i32,
user: bool,
tool: bool,
reasoning: Option<&'a str>,
reasoning_complete: bool,
content: &'a str,
@@ -621,6 +623,7 @@ impl Database {
.values(NewMessage {
session_id,
user: true,
tool: false,
reasoning: None,
reasoning_complete: true,
content: prompt,
@@ -631,6 +634,7 @@ impl Database {
.values(NewMessage {
session_id,
user: false,
tool: false,
reasoning: reasoning.then_some(""),
reasoning_complete: !reasoning,
content: "",
@@ -642,6 +646,41 @@ impl Database {
.map_err(|error: diesel::result::Error| error.to_string())
}
pub fn continue_tool_turn(
&mut self,
session_id: i32,
result: &str,
reasoning: bool,
) -> Result<(StoredMessage, StoredMessage), String> {
self.connection
.transaction(|connection| {
let tool = diesel::insert_into(messages::table)
.values(NewMessage {
session_id,
user: false,
tool: true,
reasoning: None,
reasoning_complete: true,
content: result,
})
.returning(StoredMessage::as_returning())
.get_result(connection)?;
let assistant = diesel::insert_into(messages::table)
.values(NewMessage {
session_id,
user: false,
tool: false,
reasoning: reasoning.then_some(""),
reasoning_complete: !reasoning,
content: "",
})
.returning(StoredMessage::as_returning())
.get_result(connection)?;
Ok((tool, assistant))
})
.map_err(|error: diesel::result::Error| error.to_string())
}
pub fn update_message(
&mut self,
id: i32,
@@ -832,6 +871,9 @@ mod tests {
database
.update_message(assistant.id, Some("Reasoning"), true, "Answer")
.unwrap();
database
.continue_tool_turn(session.id, "Tool result", false)
.unwrap();
database
.update_session_context(session.id, 1_234, 65_536, Some(12.5))
.unwrap();
@@ -843,12 +885,17 @@ mod tests {
assert_eq!(projects[0].sessions[0].context_limit, 65_536);
assert_eq!(projects[0].sessions[0].last_tokens_per_second, Some(12.5));
let messages = reopened.load_messages(session.id).unwrap();
assert_eq!(messages.len(), 2);
assert_eq!(messages.len(), 4);
assert!(messages[0].user);
assert!(!messages[0].tool);
assert_eq!(messages[0].content, "Question");
assert_eq!(messages[1].reasoning.as_deref(), Some("Reasoning"));
assert!(messages[1].reasoning_complete);
assert_eq!(messages[1].content, "Answer");
assert!(messages[2].tool);
assert_eq!(messages[2].content, "Tool result");
assert!(!messages[3].user);
assert!(!messages[3].tool);
reopened.delete_session(session.id).unwrap();
assert!(reopened.load_messages(session.id).unwrap().is_empty());
drop(reopened);