loopd: the memory block from memoryd, recall and memory as core tools

Implemented-By: OpenCode session (model recorded in docs/implementer-log.md)
This commit is contained in:
2026-09-25 16:41:44 -07:00
committed by kyle
parent e167fc871b
commit 15ee4b8e3d
14 changed files with 484 additions and 87 deletions
+21 -1
View File
@@ -10,6 +10,7 @@ use std::sync::{Arc, Mutex};
use crate::baseline::Baseline;
use crate::config::Config;
use crate::llama::Client;
use crate::memory::MemorySource;
use crate::session::{Session, SessionError};
use crate::tools::{Registry, ToolPort};
use crate::turn::{Runtime, TurnError, run_turn};
@@ -24,6 +25,8 @@ pub struct Context {
pub client: Client,
pub port: Box<dyn ToolPort>,
pub registry: Registry,
/// Where a new session's memory block comes from, and who hears that a session changed.
pub memory: Box<dyn MemorySource>,
busy: Mutex<HashSet<SessionId>>,
}
@@ -33,12 +36,14 @@ impl Context {
client: Client,
port: Box<dyn ToolPort>,
registry: Registry,
memory: Box<dyn MemorySource>,
) -> Context {
Context {
cfg,
client,
port,
registry,
memory,
busy: Mutex::new(HashSet::new()),
}
}
@@ -140,7 +145,11 @@ pub fn handle(stream: UnixStream, ctx: Arc<Context>) {
}
}
} else {
let baseline = match Baseline::assemble(&ctx.cfg, &ctx.registry) {
// A new session takes the memory block as it is now; no session starts without it.
let assembled = ctx.memory.block().and_then(|block| {
Baseline::assemble_with(&ctx.cfg, &ctx.registry, &block).map_err(|e| e.to_string())
});
let baseline = match assembled {
Ok(baseline) => baseline,
Err(e) => {
drop(held);
@@ -184,6 +193,17 @@ pub fn handle(stream: UnixStream, ctx: Arc<Context>) {
// 5. Release the session before the final frame, so the next turn does not find it busy.
drop(held);
// A finished turn's records are for `memoryd` to index; best effort, since `memoryd` catches
// up at its next start.
if outcome.is_ok()
&& let Err(e) = ctx.memory.updated(&turn.session)
{
eprintln!(
"loopd: memoryd was not told about {}: {e}",
turn.session.as_str()
);
}
// 6. and 7. A turn done is success; a turn error maps to a code. A write failure means the
// channel is gone, so we stop and finish quietly.
match outcome {