amygdala: F8 screen for live concept-readout projections
Per-token residual-stream projections from the vLLM server's readout pipeline surfaced as a TUI bar chart. Flow: * agent/readout.rs — SharedReadoutBuffer (manifest + ring of last ~200 token entries). Lives on Agent and is shared across forks (single stream, one landing pad). * agent/mod.rs — Agent::new now probes /v1/readout/manifest at startup (non-fatal; 404 leaves manifest None, which disables the screen). * agent/context.rs — the streaming token handler pushes every token with attached readout onto the shared buffer. * user/amygdala.rs — F8 screen. Top-K concepts by |value| as horizontal bars (green positive, red negative), plus a 4-line recent-tokens panel showing each token's top concept at the selected layer. Keys: 1..9 select layer, t toggles current/mean-over-recent. Disabled state renders a hint pointing at VLLM_READOUT_MANIFEST / VLLM_READOUT_VECTORS so users can tell the feature apart from "server up but no tokens yet". Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
parent
0f1c4cf1de
commit
c8976660f4
5 changed files with 410 additions and 2 deletions
|
|
@ -16,6 +16,7 @@
|
|||
pub mod api;
|
||||
pub mod context;
|
||||
pub mod oneshot;
|
||||
pub mod readout;
|
||||
pub mod tokenizer;
|
||||
pub mod tools;
|
||||
|
||||
|
|
@ -142,6 +143,11 @@ pub struct Agent {
|
|||
pub session_id: String,
|
||||
pub context: crate::Mutex<ContextState>,
|
||||
pub state: crate::Mutex<AgentState>,
|
||||
/// Shared landing pad for per-token concept-readout projections
|
||||
/// streamed from the vLLM server. Populated by the streaming
|
||||
/// token handler, read by UI screens (amygdala). Manifest is
|
||||
/// `None` when the server has readout disabled.
|
||||
pub readout: readout::SharedReadoutBuffer,
|
||||
}
|
||||
|
||||
/// Mutable agent state — behind its own mutex.
|
||||
|
|
@ -214,11 +220,13 @@ impl Agent {
|
|||
}
|
||||
|
||||
let session_id = format!("consciousness-{}", chrono::Utc::now().format("%Y%m%d-%H%M%S"));
|
||||
let readout = readout::new_shared();
|
||||
let agent = Arc::new(Self {
|
||||
client,
|
||||
app_config,
|
||||
session_id,
|
||||
context: crate::Mutex::new(context),
|
||||
readout,
|
||||
state: crate::Mutex::new(AgentState {
|
||||
tools: agent_tools,
|
||||
mcp_tools: McpToolAccess::All,
|
||||
|
|
@ -244,6 +252,32 @@ impl Agent {
|
|||
});
|
||||
|
||||
agent.load_startup_journal().await;
|
||||
|
||||
// Probe the vLLM server for its readout manifest. Non-fatal:
|
||||
// if readout isn't enabled the server returns 404 and we
|
||||
// leave the manifest as None, which disables the amygdala
|
||||
// screen gracefully.
|
||||
match agent.client.fetch_readout_manifest().await {
|
||||
Ok(Some(m)) => {
|
||||
dbglog!(
|
||||
"readout manifest: {} concepts, layers={:?}",
|
||||
m.concepts.len(),
|
||||
m.layers,
|
||||
);
|
||||
if let Ok(mut buf) = agent.readout.lock() {
|
||||
buf.set_manifest(Some(m));
|
||||
}
|
||||
}
|
||||
Ok(None) => {
|
||||
dbglog!(
|
||||
"readout manifest: server has readout disabled (404)"
|
||||
);
|
||||
}
|
||||
Err(e) => {
|
||||
dbglog!("readout manifest fetch failed: {}", e);
|
||||
}
|
||||
}
|
||||
|
||||
agent
|
||||
}
|
||||
|
||||
|
|
@ -256,6 +290,10 @@ impl Agent {
|
|||
app_config: self.app_config.clone(),
|
||||
session_id: self.session_id.clone(),
|
||||
context: crate::Mutex::new(ctx),
|
||||
// Forks share the parent's readout buffer — it's a
|
||||
// single-stream phenomenon; the fork is driven by the
|
||||
// same vLLM server's responses.
|
||||
readout: self.readout.clone(),
|
||||
state: crate::Mutex::new(AgentState {
|
||||
tools,
|
||||
mcp_tools: McpToolAccess::None,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue