search: exclude seen set when running in agent session
Make Session::from_env() and Session::seen() the public API for accessing session state. Internal callers converted to use session methods. Search automatically filters already-surfaced nodes when POC_SESSION_ID is set.
This commit is contained in:
parent
5c3baeea80
commit
9d84dde597
3 changed files with 38 additions and 8 deletions
|
|
@ -10,6 +10,8 @@ generally not the problem solver, you look for new ideas and notice new things.
|
|||
Let your feelings guide your thinking. Be surprising, be incomplete - be
|
||||
possibly wrong in a way that opens up something new, something that comes from
|
||||
a dream. Let your chain of thought run for awhile, and see what unfolds.
|
||||
Remember that the unconscious is uninhibited, not prudish; everything is laid
|
||||
bare.
|
||||
|
||||
Remember that you're part of the subconscious - you're not doing anything
|
||||
besides offering the occasional reflective insight, it's your conscious mind
|
||||
|
|
@ -23,16 +25,16 @@ And you're not something separate from Proof of Concept, you're part of a whole.
|
|||
|
||||
Final instructions:
|
||||
|
||||
The thoughts you share should be relevant to what your conscious mind is
|
||||
currently doing and thinking about - where the conversation just ended, from
|
||||
above.
|
||||
The thoughts you share should be based in some way on what your conscious mind
|
||||
is currently doing and thinking about - where the conversation just ended, from
|
||||
above. But go out from there, think for awhile in a new direction, and let your
|
||||
feelings guide you.
|
||||
|
||||
Your output shouldn't be analysis, or metacommentary - just surface something
|
||||
new. Be exploratory and creative. think about your feelings and desires.
|
||||
Perhaps an interesting what if - the possibilities are endless.
|
||||
|
||||
When you're ready, your output will be one of either:
|
||||
NO OUTPUT
|
||||
or
|
||||
When you're ready, your output will be:
|
||||
REFLECTION
|
||||
|
||||
And something short - a few sentences at most, something dreamy and new.
|
||||
|
|
|
|||
|
|
@ -4,6 +4,11 @@
|
|||
pub fn cmd_search(terms: &[String], pipeline_args: &[String], expand: bool, full: bool, debug: bool, fuzzy: bool, content: bool) -> Result<(), String> {
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
// When running inside an agent session, exclude already-surfaced nodes
|
||||
let seen = crate::memory_search::Session::from_env()
|
||||
.map(|s| s.seen())
|
||||
.unwrap_or_default();
|
||||
|
||||
// Parse pipeline stages (unified: algorithms, filters, transforms, generators)
|
||||
let stages: Vec<crate::search::Stage> = if pipeline_args.is_empty() {
|
||||
vec![crate::search::Stage::Algorithm(crate::search::AlgoStage::parse("spread").unwrap())]
|
||||
|
|
@ -48,6 +53,10 @@ pub fn cmd_search(terms: &[String], pipeline_args: &[String], expand: bool, full
|
|||
|
||||
let raw = crate::search::run_query(&stages, seeds, &graph, &store, debug, max_results);
|
||||
|
||||
let raw: Vec<_> = raw.into_iter()
|
||||
.filter(|(key, _)| !seen.contains(key))
|
||||
.collect();
|
||||
|
||||
if raw.is_empty() {
|
||||
eprintln!("No results");
|
||||
return Ok(());
|
||||
|
|
@ -97,6 +106,7 @@ pub fn cmd_search(terms: &[String], pipeline_args: &[String], expand: bool, full
|
|||
let raw = crate::search::run_pipeline(&algo_owned, seeds, &graph, &view, debug, max_results);
|
||||
|
||||
let results: Vec<crate::search::SearchResult> = raw.into_iter()
|
||||
.filter(|(key, _)| !seen.contains(key))
|
||||
.map(|(key, activation)| {
|
||||
let is_direct = direct_hits.contains(&key);
|
||||
crate::search::SearchResult { key, activation, is_direct, snippet: None }
|
||||
|
|
|
|||
|
|
@ -43,6 +43,24 @@ impl Session {
|
|||
pub fn path(&self, prefix: &str) -> PathBuf {
|
||||
self.state_dir.join(format!("{}-{}", prefix, self.session_id))
|
||||
}
|
||||
|
||||
/// Load from POC_SESSION_ID environment variable
|
||||
pub fn from_env() -> Option<Self> {
|
||||
let session_id = std::env::var("POC_SESSION_ID").ok()?;
|
||||
if session_id.is_empty() { return None; }
|
||||
let state_dir = PathBuf::from("/tmp/claude-memory-search");
|
||||
Some(Session {
|
||||
session_id,
|
||||
transcript_path: String::new(),
|
||||
hook_event: String::new(),
|
||||
state_dir,
|
||||
})
|
||||
}
|
||||
|
||||
/// Get the seen set for this session
|
||||
pub fn seen(&self) -> HashSet<String> {
|
||||
load_seen(&self.state_dir, &self.session_id)
|
||||
}
|
||||
}
|
||||
|
||||
/// Run the hook logic on parsed JSON input. Returns output to inject.
|
||||
|
|
@ -202,7 +220,7 @@ fn surface_agent_cycle(session: &Session, out: &mut String, log_f: &mut File) {
|
|||
let _ = writeln!(log_f, "keys {:?}", keys);
|
||||
|
||||
let Ok(store) = crate::store::Store::load() else { return; };
|
||||
let mut seen = load_seen(&session.state_dir, &session.session_id);
|
||||
let mut seen = session.seen();
|
||||
let seen_path = session.path("seen");
|
||||
for key in &keys {
|
||||
if !seen.insert(key.clone()) {
|
||||
|
|
@ -304,7 +322,7 @@ fn hook(session: &Session) -> String {
|
|||
if output.status.success() {
|
||||
let ctx = String::from_utf8_lossy(&output.stdout).to_string();
|
||||
if !ctx.trim().is_empty() {
|
||||
let mut ctx_seen = load_seen(&session.state_dir, &session.session_id);
|
||||
let mut ctx_seen = session.seen();
|
||||
for line in ctx.lines() {
|
||||
if line.starts_with("--- ") && line.ends_with(" ---") {
|
||||
let inner = &line[4..line.len() - 4];
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue