use anyhow::Result;
use uuid::Uuid;
use crate::entities::note::Note;
use crate::entities::profile::ToolId;
use super::{Tool, ToolContext, ToolOutcome};
pub const NOTE_RECALL_ID: &str = "note_recall";
pub const NOTE_REVISE_ID: &str = "note_revise";
pub const NOTE_LINK_ID: &str = "note_link";
pub const NOTE_NEIGHBORS_ID: &str = "note_neighbors";
pub const NOTE_SUPERSEDE_ID: &str = "note_supersede";
pub const NOTE_MERGE_ID: &str = "note_merge";
pub const CONSOLIDATE_NOTES_ID: &str = "consolidate_notes";
pub const NOTE_CITE_SOURCE_ID: &str = "note_cite_source";
const CONSOLIDATE_SIMILARITY: f32 = 0.85;
const CONSOLIDATE_LIST_CAP: usize = 8;
const RELATIONS: [&str; 4] = ["supports", "contradicts", "refines", "relates"];
const DEFAULT_RECALL: usize = 5;
const NOTE_BACKFILL_BATCH: usize = 32;
const RELATED_IN_RECALL: usize = 5;
pub const SELF_NOTE_TAG: &str = "@self";
pub(crate) fn is_self_note(note: &Note) -> bool {
note.tags.iter().any(|t| t == SELF_NOTE_TAG)
}
fn parse_id(
args: &serde_json::Value,
key: &str,
loc: &crate::shared::i18n::Locale,
) -> Result<Uuid> {
let raw = args
.get(key)
.and_then(|v| v.as_str())
.unwrap_or_default()
.trim();
Uuid::parse_str(raw).map_err(|_| {
anyhow::anyhow!(loc.tf("notes.err.bad_id_field", &[("key", key), ("raw", raw)]))
})
}
pub(crate) fn cosine(a: &[f32], b: &[f32]) -> f32 {
if a.len() != b.len() || a.is_empty() {
return 0.0;
}
let dot: f32 = a.iter().zip(b).map(|(x, y)| x * y).sum();
let na: f32 = a.iter().map(|x| x * x).sum::<f32>().sqrt();
let nb: f32 = b.iter().map(|x| x * x).sum::<f32>().sqrt();
if na == 0.0 || nb == 0.0 {
return 0.0;
}
dot / (na * nb)
}
fn clip(s: &str, n: usize) -> String {
let s = s.trim();
if s.chars().count() <= n {
return s.to_string();
}
let mut out: String = s.chars().take(n.saturating_sub(1)).collect();
out.push('…');
out
}
fn parse_tags(args: &serde_json::Value) -> Vec<String> {
args.get("tags")
.and_then(|v| v.as_array())
.map(|a| {
a.iter()
.filter_map(|t| t.as_str().map(|s| s.to_string()))
.collect()
})
.unwrap_or_default()
}
mod cite;
mod edit;
mod graph;
mod overview;
mod recall;
mod save;
mod self_notes;
pub(crate) use self::{cite::*, edit::*, graph::*, overview::*, recall::*, save::*, self_notes::*};
#[cfg(test)]
mod tests;