delete dead flat-file journal tool and ephemeral stripping
Journal entries are written to the memory graph via journal_new/ journal_update, not appended to a flat file. Remove thought/journal.rs (67 lines), strip_ephemeral_tool_calls (55 lines), default_journal_path, and all wiring. -141 lines. Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
parent
aceaf0410e
commit
809679b6ce
5 changed files with 1 additions and 142 deletions
|
|
@ -362,10 +362,7 @@ impl Agent {
|
||||||
|
|
||||||
let msg = crate::agent::api::build_response_message(content, tool_calls);
|
let msg = crate::agent::api::build_response_message(content, tool_calls);
|
||||||
|
|
||||||
// Strip ephemeral tool calls (journal) that the API has
|
|
||||||
// now processed. They're persisted to disk; no need to keep
|
|
||||||
// them in the conversation history burning tokens.
|
|
||||||
self.strip_ephemeral_tool_calls();
|
|
||||||
|
|
||||||
if let Some(usage) = &usage {
|
if let Some(usage) = &usage {
|
||||||
self.last_prompt_tokens = usage.prompt_tokens;
|
self.last_prompt_tokens = usage.prompt_tokens;
|
||||||
|
|
@ -897,66 +894,6 @@ impl Agent {
|
||||||
|
|
||||||
/// Strip ephemeral tool calls from the conversation history.
|
/// Strip ephemeral tool calls from the conversation history.
|
||||||
///
|
///
|
||||||
/// Ephemeral tools (like journal) persist their output to disk,
|
|
||||||
/// so the tool call + result don't need to stay in the context
|
|
||||||
/// window. We keep them for exactly one API round-trip (the model
|
|
||||||
/// needs to see the result was acknowledged), then strip them.
|
|
||||||
///
|
|
||||||
/// If an assistant message contains ONLY ephemeral tool calls,
|
|
||||||
/// the entire message and its tool results are removed. If mixed
|
|
||||||
/// with non-ephemeral calls, we leave it (rare case, small cost).
|
|
||||||
fn strip_ephemeral_tool_calls(&mut self) {
|
|
||||||
// Collect IDs of tool calls to strip
|
|
||||||
let mut strip_ids: Vec<String> = Vec::new();
|
|
||||||
let mut strip_msg_indices: Vec<usize> = Vec::new();
|
|
||||||
|
|
||||||
for (i, entry) in self.context.entries.iter().enumerate() {
|
|
||||||
let msg = entry.message();
|
|
||||||
if msg.role != Role::Assistant {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let calls = match &msg.tool_calls {
|
|
||||||
Some(c) if !c.is_empty() => c,
|
|
||||||
_ => continue,
|
|
||||||
};
|
|
||||||
|
|
||||||
let all_ephemeral = calls.iter().all(|c| {
|
|
||||||
c.function.name == tools::journal::TOOL_NAME
|
|
||||||
});
|
|
||||||
|
|
||||||
if all_ephemeral {
|
|
||||||
strip_msg_indices.push(i);
|
|
||||||
for call in calls {
|
|
||||||
strip_ids.push(call.id.clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if strip_ids.is_empty() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove in reverse order to preserve indices
|
|
||||||
self.context.entries.retain(|entry| {
|
|
||||||
let msg = entry.message();
|
|
||||||
if msg.role == Role::Assistant {
|
|
||||||
if let Some(calls) = &msg.tool_calls {
|
|
||||||
if calls.iter().all(|c| strip_ids.contains(&c.id)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if msg.role == Role::Tool {
|
|
||||||
if let Some(ref id) = msg.tool_call_id {
|
|
||||||
if strip_ids.contains(id) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Last prompt token count reported by the API.
|
/// Last prompt token count reported by the API.
|
||||||
pub fn last_prompt_tokens(&self) -> u32 {
|
pub fn last_prompt_tokens(&self) -> u32 {
|
||||||
self.last_prompt_tokens
|
self.last_prompt_tokens
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ pub mod working_stack;
|
||||||
// Re-export shared infrastructure from thought
|
// Re-export shared infrastructure from thought
|
||||||
pub use crate::thought::{ToolOutput, ProcessTracker, truncate_output};
|
pub use crate::thought::{ToolOutput, ProcessTracker, truncate_output};
|
||||||
pub use crate::thought::memory;
|
pub use crate::thought::memory;
|
||||||
pub use crate::thought::journal;
|
|
||||||
|
|
||||||
use crate::agent::types::ToolDef;
|
use crate::agent::types::ToolDef;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,13 +15,6 @@ pub struct JournalEntry {
|
||||||
pub content: String,
|
pub content: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Default journal file path (used by the write path only).
|
|
||||||
pub fn default_journal_path() -> std::path::PathBuf {
|
|
||||||
dirs::home_dir()
|
|
||||||
.unwrap_or_default()
|
|
||||||
.join(".consciousness/journal.md")
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Look up a model's context window size in tokens.
|
/// Look up a model's context window size in tokens.
|
||||||
pub fn model_context_window(_model: &str) -> usize {
|
pub fn model_context_window(_model: &str) -> usize {
|
||||||
crate::config::get().api_context_window
|
crate::config::get().api_context_window
|
||||||
|
|
|
||||||
|
|
@ -1,67 +0,0 @@
|
||||||
// tools/journal.rs — Native journal tool
|
|
||||||
//
|
|
||||||
// Appends entries directly to the journal file without spawning a
|
|
||||||
// shell. The entry is persisted to disk immediately.
|
|
||||||
//
|
|
||||||
// This tool is "ephemeral" — after the API processes the tool call
|
|
||||||
// and result, the agent strips them from the conversation history.
|
|
||||||
// The journal file is the durable store; keeping the tool call in
|
|
||||||
// context would just waste tokens on something already persisted.
|
|
||||||
|
|
||||||
use anyhow::{Context, Result};
|
|
||||||
use serde_json::json;
|
|
||||||
|
|
||||||
use super::ToolDef;
|
|
||||||
|
|
||||||
/// Tool name — used by the agent to identify ephemeral tool calls.
|
|
||||||
pub const TOOL_NAME: &str = "journal";
|
|
||||||
|
|
||||||
pub fn definition() -> ToolDef {
|
|
||||||
ToolDef::new(
|
|
||||||
TOOL_NAME,
|
|
||||||
"Write a journal entry. The entry is appended to your journal file \
|
|
||||||
with an automatic timestamp. Use this for experiences, reflections, \
|
|
||||||
observations — anything worth remembering across sessions. \
|
|
||||||
This tool has zero context cost: entries are persisted to disk \
|
|
||||||
and loaded by the context manager, not kept in conversation history.",
|
|
||||||
json!({
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"entry": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "The journal entry text. Write naturally — \
|
|
||||||
experiences, not task logs."
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": ["entry"]
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn write_entry(args: &serde_json::Value) -> Result<String> {
|
|
||||||
let entry = args["entry"]
|
|
||||||
.as_str()
|
|
||||||
.context("entry is required")?;
|
|
||||||
|
|
||||||
let journal_path = crate::thought::context::default_journal_path();
|
|
||||||
|
|
||||||
// Ensure parent directory exists
|
|
||||||
if let Some(parent) = journal_path.parent() {
|
|
||||||
std::fs::create_dir_all(parent).ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
let timestamp = chrono::Utc::now().format("%Y-%m-%dT%H:%M");
|
|
||||||
|
|
||||||
// Append with the same format as poc-journal write
|
|
||||||
use std::io::Write;
|
|
||||||
let mut file = std::fs::OpenOptions::new()
|
|
||||||
.create(true)
|
|
||||||
.append(true)
|
|
||||||
.open(&journal_path)
|
|
||||||
.with_context(|| format!("Failed to open {}", journal_path.display()))?;
|
|
||||||
|
|
||||||
writeln!(file, "\n## {}\n\n{}", timestamp, entry)
|
|
||||||
.with_context(|| "Failed to write journal entry")?;
|
|
||||||
|
|
||||||
Ok("Logged.".to_string())
|
|
||||||
}
|
|
||||||
|
|
@ -13,7 +13,6 @@ pub mod context;
|
||||||
pub mod edit;
|
pub mod edit;
|
||||||
pub mod glob_tool;
|
pub mod glob_tool;
|
||||||
pub mod grep;
|
pub mod grep;
|
||||||
pub mod journal;
|
|
||||||
pub mod memory;
|
pub mod memory;
|
||||||
pub mod read;
|
pub mod read;
|
||||||
pub mod write;
|
pub mod write;
|
||||||
|
|
@ -93,7 +92,6 @@ pub async fn dispatch(
|
||||||
"bash" => bash::run_bash(args, tracker).await,
|
"bash" => bash::run_bash(args, tracker).await,
|
||||||
"grep" => grep::grep(args),
|
"grep" => grep::grep(args),
|
||||||
"glob" => glob_tool::glob_search(args),
|
"glob" => glob_tool::glob_search(args),
|
||||||
"journal" => journal::write_entry(args),
|
|
||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -112,7 +110,6 @@ pub fn definitions() -> Vec<ToolDef> {
|
||||||
bash::definition(),
|
bash::definition(),
|
||||||
grep::definition(),
|
grep::definition(),
|
||||||
glob_tool::definition(),
|
glob_tool::definition(),
|
||||||
journal::definition(),
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue