Enhance tool documentation and add new features
- Added module-level documentation for memory tools (`remember`, `recall`, `forget`) to clarify their purpose. - Improved documentation in `recall.rs` and `remember.rs` to describe the functionality and flow of memory entry operations. - Updated `mod.rs` to include descriptions for the tool trait and execution context. - Enhanced `plan.rs` with detailed comments on plan-mode signaling tools. - Documented text search tools in `search.rs` to explain their functionality. - Improved sequential-thinking tool documentation in `seqthink.rs`. - Added safety filter documentation in `shell_filter` for credential and git operations. - Enhanced utility tools documentation, including `cd`, `dir_cache_update`, and `todowrite`. - Improved rendering documentation in view modules (`chat`, `markdown`, `status`, `workflow`) to clarify rendering flows and purposes.
This commit is contained in:
@@ -1,6 +1,15 @@
|
||||
//! Binary blob storage in the message-log SQLite database (e.g. images,
|
||||
//! attachments), keyed by session id and an arbitrary blob key.
|
||||
|
||||
use rusqlite::{Connection, params};
|
||||
use anyhow::Result;
|
||||
|
||||
/// Insert or overwrite a blob for a session under `blob_key`.
|
||||
///
|
||||
/// Flow: compute current timestamp → `INSERT OR REPLACE` into `blobs`
|
||||
/// keyed on `(session_id, blob_key)`.
|
||||
///
|
||||
/// Return: `Ok(())` on success, or the underlying SQLite error.
|
||||
pub fn store_blob(conn: &Connection, session_id: &str, blob_key: &str, data: &[u8], mime_type: Option<&str>) -> Result<()> {
|
||||
let created_at = chrono::Utc::now().timestamp_millis();
|
||||
conn.execute(
|
||||
@@ -10,6 +19,10 @@ pub fn store_blob(conn: &Connection, session_id: &str, blob_key: &str, data: &[u
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Fetch a blob's bytes for a session by key.
|
||||
///
|
||||
/// Return: `Ok(Some(data))` if found, `Ok(None)` if no matching row
|
||||
/// exists, `Err` for any other SQLite failure.
|
||||
pub fn retrieve_blob(conn: &Connection, session_id: &str, blob_key: &str) -> Result<Option<Vec<u8>>> {
|
||||
let result = conn.query_row(
|
||||
"SELECT data FROM blobs WHERE session_id = ?1 AND blob_key = ?2",
|
||||
@@ -23,6 +36,10 @@ pub fn retrieve_blob(conn: &Connection, session_id: &str, blob_key: &str) -> Res
|
||||
}
|
||||
}
|
||||
|
||||
/// Delete a blob for a session by key.
|
||||
///
|
||||
/// Return: `Ok(true)` if a row was deleted, `Ok(false)` if no matching
|
||||
/// row existed.
|
||||
#[allow(dead_code)]
|
||||
pub fn delete_blob(conn: &Connection, session_id: &str, blob_key: &str) -> Result<bool> {
|
||||
let rows = conn.execute(
|
||||
@@ -32,6 +49,10 @@ pub fn delete_blob(conn: &Connection, session_id: &str, blob_key: &str) -> Resul
|
||||
Ok(rows > 0)
|
||||
}
|
||||
|
||||
/// List all blob keys stored for a session, oldest first.
|
||||
///
|
||||
/// Return: `Ok(Vec<String>)` of keys ordered by `created_at`, or the
|
||||
/// underlying SQLite error.
|
||||
pub fn list_blob_keys(conn: &Connection, session_id: &str) -> Result<Vec<String>> {
|
||||
let mut stmt = conn.prepare(
|
||||
"SELECT blob_key FROM blobs WHERE session_id = ?1 ORDER BY created_at ASC"
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
//! SQLite-backed message log: per-session `messages.sqlite` storing chat
|
||||
//! messages, blobs, and archive/summary metadata.
|
||||
|
||||
pub mod blobs;
|
||||
pub mod query;
|
||||
pub mod schema;
|
||||
@@ -5,6 +8,14 @@ pub mod schema;
|
||||
pub use blobs::store_blob;
|
||||
pub use query::insert_message;
|
||||
|
||||
/// Open (creating if needed) a session's `messages.sqlite` and ensure its
|
||||
/// schema is initialized.
|
||||
///
|
||||
/// Flow: resolve `<session_dir>/messages.sqlite` → create parent dirs →
|
||||
/// open a SQLite connection → run `schema::init_schema`.
|
||||
///
|
||||
/// Return: an open, schema-ready `Connection`, or an error if any step
|
||||
/// fails.
|
||||
pub fn open_or_create(session_dir: &std::path::Path) -> anyhow::Result<rusqlite::Connection> {
|
||||
let path = session_dir.join("messages.sqlite");
|
||||
if let Some(parent) = path.parent() {
|
||||
|
||||
@@ -1,7 +1,16 @@
|
||||
//! Insert queries against the message log's `messages` table.
|
||||
|
||||
use rusqlite::{Connection, params};
|
||||
use anyhow::Result;
|
||||
use crate::dto::chat::message::{ChatMessage, Role};
|
||||
|
||||
/// Insert a chat message into the session's message log.
|
||||
///
|
||||
/// Flow: extract optional content/tool_call_id/tool_name → serialize
|
||||
/// `tool_calls` to a JSON string if present → map `Role` to its string
|
||||
/// column value → `INSERT` the row with the current timestamp.
|
||||
///
|
||||
/// Return: the new row's `rowid` on success, or the underlying error.
|
||||
pub fn insert_message(conn: &Connection, session_id: &str, msg: &ChatMessage) -> Result<i64> {
|
||||
let content = msg.content.as_deref();
|
||||
let tool_call_id = msg.tool_call_id.as_deref();
|
||||
|
||||
@@ -1,6 +1,15 @@
|
||||
//! SQLite schema definition for the message log database.
|
||||
|
||||
use rusqlite::Connection;
|
||||
use anyhow::Result;
|
||||
|
||||
/// Create the message log's tables and indexes if they don't already
|
||||
/// exist (`messages`, `archives`, `blobs`).
|
||||
///
|
||||
/// Why: idempotent via `CREATE TABLE/INDEX IF NOT EXISTS`, so it's safe
|
||||
/// to call on every `open_or_create`.
|
||||
///
|
||||
/// Return: `Ok(())` on success, or the underlying SQLite error.
|
||||
pub fn init_schema(conn: &Connection) -> Result<()> {
|
||||
conn.execute_batch(
|
||||
"
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
//! Session archive/summary metadata tracked alongside the message log
|
||||
//! (title, model, counts, and a rolling text summary).
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Summary metadata for one archived/summarized session.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct SummaryRecord {
|
||||
pub session_id: String,
|
||||
@@ -13,6 +17,8 @@ pub struct SummaryRecord {
|
||||
}
|
||||
|
||||
impl SummaryRecord {
|
||||
/// Create a fresh summary record with zeroed counts and an empty
|
||||
/// summary, timestamped to now.
|
||||
pub fn new(session_id: String, title: String, model: String) -> Self {
|
||||
let now = chrono::Utc::now().timestamp_millis();
|
||||
SummaryRecord {
|
||||
@@ -27,11 +33,13 @@ impl SummaryRecord {
|
||||
}
|
||||
}
|
||||
|
||||
/// Replace the summary text and bump `updated_at`.
|
||||
pub fn update_summary(&mut self, summary: String) {
|
||||
self.summary = summary;
|
||||
self.updated_at = chrono::Utc::now().timestamp_millis();
|
||||
}
|
||||
|
||||
/// Add to the running message/token counts and bump `updated_at`.
|
||||
pub fn increment_counts(&mut self, messages: usize, tokens: usize) {
|
||||
self.message_count += messages;
|
||||
self.token_count += tokens;
|
||||
|
||||
Reference in New Issue
Block a user