Kill publish_context_state() — screens lock the agent directly
F1 and F2 screens now call agent.context_state_summary() directly via try_lock/lock instead of reading from a shared RwLock cache. Removes SharedContextState, publish_context_state(), and publish_context_state_with_scores(). Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
parent
48c843234d
commit
04e260c081
6 changed files with 30 additions and 64 deletions
|
|
@ -28,7 +28,7 @@ use context::{ConversationEntry, ContextState};
|
||||||
use tools::{summarize_args, working_stack};
|
use tools::{summarize_args, working_stack};
|
||||||
|
|
||||||
use crate::mind::log::ConversationLog;
|
use crate::mind::log::ConversationLog;
|
||||||
use crate::agent::context::{ContextSection, SharedContextState};
|
use crate::agent::context::ContextSection;
|
||||||
use crate::subconscious::learn;
|
use crate::subconscious::learn;
|
||||||
|
|
||||||
// --- Activity tracking (RAII guards) ---
|
// --- Activity tracking (RAII guards) ---
|
||||||
|
|
@ -166,8 +166,6 @@ pub struct Agent {
|
||||||
tokenizer: CoreBPE,
|
tokenizer: CoreBPE,
|
||||||
/// Mutable context state — personality, working stack, etc.
|
/// Mutable context state — personality, working stack, etc.
|
||||||
pub context: ContextState,
|
pub context: ContextState,
|
||||||
/// Shared live context summary — TUI reads this directly for debug screen.
|
|
||||||
pub shared_context: SharedContextState,
|
|
||||||
/// App config — used to reload identity on compaction and model switching.
|
/// App config — used to reload identity on compaction and model switching.
|
||||||
pub app_config: crate::config::AppConfig,
|
pub app_config: crate::config::AppConfig,
|
||||||
pub prompt_file: String,
|
pub prompt_file: String,
|
||||||
|
|
@ -193,7 +191,6 @@ impl Agent {
|
||||||
app_config: crate::config::AppConfig,
|
app_config: crate::config::AppConfig,
|
||||||
prompt_file: String,
|
prompt_file: String,
|
||||||
conversation_log: Option<ConversationLog>,
|
conversation_log: Option<ConversationLog>,
|
||||||
shared_context: SharedContextState,
|
|
||||||
active_tools: tools::SharedActiveTools,
|
active_tools: tools::SharedActiveTools,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let tokenizer = tiktoken_rs::cl100k_base()
|
let tokenizer = tiktoken_rs::cl100k_base()
|
||||||
|
|
@ -223,7 +220,6 @@ impl Agent {
|
||||||
conversation_log,
|
conversation_log,
|
||||||
tokenizer,
|
tokenizer,
|
||||||
context,
|
context,
|
||||||
shared_context,
|
|
||||||
app_config,
|
app_config,
|
||||||
prompt_file,
|
prompt_file,
|
||||||
session_id,
|
session_id,
|
||||||
|
|
@ -236,7 +232,6 @@ impl Agent {
|
||||||
|
|
||||||
agent.load_startup_journal();
|
agent.load_startup_journal();
|
||||||
agent.load_working_stack();
|
agent.load_working_stack();
|
||||||
agent.publish_context_state();
|
|
||||||
agent
|
agent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -265,7 +260,6 @@ impl Agent {
|
||||||
conversation_log: None,
|
conversation_log: None,
|
||||||
tokenizer,
|
tokenizer,
|
||||||
context: self.context.clone(),
|
context: self.context.clone(),
|
||||||
shared_context: context::shared_context_state(),
|
|
||||||
app_config: self.app_config.clone(),
|
app_config: self.app_config.clone(),
|
||||||
prompt_file: self.prompt_file.clone(),
|
prompt_file: self.prompt_file.clone(),
|
||||||
session_id: self.session_id.clone(),
|
session_id: self.session_id.clone(),
|
||||||
|
|
@ -490,7 +484,6 @@ impl Agent {
|
||||||
|
|
||||||
if let Some(usage) = &usage {
|
if let Some(usage) = &usage {
|
||||||
me.last_prompt_tokens = usage.prompt_tokens;
|
me.last_prompt_tokens = usage.prompt_tokens;
|
||||||
me.publish_context_state();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Empty response — nudge and retry
|
// Empty response — nudge and retry
|
||||||
|
|
@ -542,7 +535,6 @@ impl Agent {
|
||||||
for (call, output) in results {
|
for (call, output) in results {
|
||||||
me.apply_tool_result(&call, output, &mut ds);
|
me.apply_tool_result(&call, output, &mut ds);
|
||||||
}
|
}
|
||||||
me.publish_context_state();
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -657,7 +649,6 @@ impl Agent {
|
||||||
let mut msg = Message::tool_result(&call.id, &output);
|
let mut msg = Message::tool_result(&call.id, &output);
|
||||||
msg.stamp();
|
msg.stamp();
|
||||||
self.push_entry(ConversationEntry::Memory { key: key.to_string(), message: msg });
|
self.push_entry(ConversationEntry::Memory { key: key.to_string(), message: msg });
|
||||||
self.publish_context_state();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -910,25 +901,6 @@ impl Agent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Push the current context summary to the shared state for the TUI to read.
|
|
||||||
pub fn publish_context_state(&self) {
|
|
||||||
self.publish_context_state_with_scores(None);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn publish_context_state_with_scores(&self, memory_scores: Option<&learn::MemoryScore>) {
|
|
||||||
let summary = self.context_state_summary(memory_scores);
|
|
||||||
if let Ok(mut dbg) = std::fs::OpenOptions::new().create(true).append(true)
|
|
||||||
.open("/tmp/poc-journal-debug.log") {
|
|
||||||
use std::io::Write;
|
|
||||||
for s in &summary {
|
|
||||||
let _ = writeln!(dbg, "[publish] {} ({} tokens, {} children)", s.name, s.tokens, s.children.len());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if let Ok(mut state) = self.shared_context.write() {
|
|
||||||
*state = summary;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Replace base64 image data in older messages with text placeholders.
|
/// Replace base64 image data in older messages with text placeholders.
|
||||||
/// Keeps the 2 most recent images live (enough for motion/comparison).
|
/// Keeps the 2 most recent images live (enough for motion/comparison).
|
||||||
/// The tool result message before each image records what was loaded.
|
/// The tool result message before each image records what was loaded.
|
||||||
|
|
@ -1013,9 +985,8 @@ impl Agent {
|
||||||
before, after, before_mem, after_mem, before_conv, after_conv);
|
before, after, before_mem, after_mem, before_conv, after_conv);
|
||||||
self.generation += 1;
|
self.generation += 1;
|
||||||
self.last_prompt_tokens = 0;
|
self.last_prompt_tokens = 0;
|
||||||
self.publish_context_state();
|
|
||||||
|
|
||||||
let sections = self.shared_context.read().map(|s| s.clone()).unwrap_or_default();
|
let sections = self.context_state_summary(None);
|
||||||
dbglog!("[compact] budget: {}", context::sections_budget_string(§ions));
|
dbglog!("[compact] budget: {}", context::sections_budget_string(§ions));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1043,8 +1014,8 @@ impl Agent {
|
||||||
self.context.entries = all;
|
self.context.entries = all;
|
||||||
self.compact();
|
self.compact();
|
||||||
// Estimate prompt tokens from sections so status bar isn't 0 on startup
|
// Estimate prompt tokens from sections so status bar isn't 0 on startup
|
||||||
let sections = self.shared_context.read().map(|s| s.clone()).unwrap_or_default();
|
self.last_prompt_tokens = context::sections_used(
|
||||||
self.last_prompt_tokens = context::sections_used(§ions) as u32;
|
&self.context_state_summary(None)) as u32;
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -203,7 +203,10 @@ impl AutoAgent {
|
||||||
let mut backend = Backend::Forked(forked);
|
let mut backend = Backend::Forked(forked);
|
||||||
let result = self.run_with_backend(&mut backend, None).await;
|
let result = self.run_with_backend(&mut backend, None).await;
|
||||||
if let Backend::Forked(ref agent) = backend {
|
if let Backend::Forked(ref agent) = backend {
|
||||||
|
let total = agent.context.entries.len();
|
||||||
self.last_run_entries = agent.context.entries[fork_point..].to_vec();
|
self.last_run_entries = agent.context.entries[fork_point..].to_vec();
|
||||||
|
dbglog!("[auto] {} fork_point={} total={} captured={}",
|
||||||
|
self.name, fork_point, total, self.last_run_entries.len());
|
||||||
}
|
}
|
||||||
self.steps = orig_steps;
|
self.steps = orig_steps;
|
||||||
result
|
result
|
||||||
|
|
@ -214,6 +217,7 @@ impl AutoAgent {
|
||||||
backend: &mut Backend,
|
backend: &mut Backend,
|
||||||
bail_fn: Option<&(dyn Fn(usize) -> Result<(), String> + Sync)>,
|
bail_fn: Option<&(dyn Fn(usize) -> Result<(), String> + Sync)>,
|
||||||
) -> Result<String, String> {
|
) -> Result<String, String> {
|
||||||
|
dbglog!("[auto] {} starting, {} steps", self.name, self.steps.len());
|
||||||
self.turn = 0;
|
self.turn = 0;
|
||||||
self.outputs.clear();
|
self.outputs.clear();
|
||||||
self.current_phase = self.steps.first()
|
self.current_phase = self.steps.first()
|
||||||
|
|
@ -235,6 +239,9 @@ impl AutoAgent {
|
||||||
backend.log(format!("turn {} ({} messages)",
|
backend.log(format!("turn {} ({} messages)",
|
||||||
self.turn, messages.len()));
|
self.turn, messages.len()));
|
||||||
|
|
||||||
|
dbglog!("[auto] {} turn {} ({} messages)",
|
||||||
|
self.name, self.turn, messages.len());
|
||||||
|
|
||||||
let (msg, usage_opt) = Self::api_call_with_retry(
|
let (msg, usage_opt) = Self::api_call_with_retry(
|
||||||
&self.name, backend, &self.tools, &messages,
|
&self.name, backend, &self.tools, &messages,
|
||||||
&reasoning, self.sampling, self.priority).await?;
|
&reasoning, self.sampling, self.priority).await?;
|
||||||
|
|
|
||||||
|
|
@ -215,7 +215,6 @@ impl Mind {
|
||||||
config: SessionConfig,
|
config: SessionConfig,
|
||||||
turn_tx: mpsc::Sender<(Result<TurnResult>, StreamTarget)>,
|
turn_tx: mpsc::Sender<(Result<TurnResult>, StreamTarget)>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let shared_context = crate::agent::context::shared_context_state();
|
|
||||||
let shared_active_tools = crate::agent::tools::shared_active_tools();
|
let shared_active_tools = crate::agent::tools::shared_active_tools();
|
||||||
|
|
||||||
let client = ApiClient::new(&config.api_base, &config.api_key, &config.model);
|
let client = ApiClient::new(&config.api_base, &config.api_key, &config.model);
|
||||||
|
|
@ -230,7 +229,6 @@ impl Mind {
|
||||||
config.app.clone(),
|
config.app.clone(),
|
||||||
config.prompt_file.clone(),
|
config.prompt_file.clone(),
|
||||||
conversation_log,
|
conversation_log,
|
||||||
shared_context,
|
|
||||||
shared_active_tools,
|
shared_active_tools,
|
||||||
);
|
);
|
||||||
let agent = Arc::new(tokio::sync::Mutex::new(ag));
|
let agent = Arc::new(tokio::sync::Mutex::new(ag));
|
||||||
|
|
@ -278,7 +276,7 @@ impl Mind {
|
||||||
MindCommand::Compact => {
|
MindCommand::Compact => {
|
||||||
let threshold = compaction_threshold(&self.config.app) as usize;
|
let threshold = compaction_threshold(&self.config.app) as usize;
|
||||||
let mut ag = self.agent.lock().await;
|
let mut ag = self.agent.lock().await;
|
||||||
let sections = ag.shared_context.read().map(|s| s.clone()).unwrap_or_default();
|
let sections = ag.context_state_summary(None);
|
||||||
if crate::agent::context::sections_used(§ions) > threshold {
|
if crate::agent::context::sections_used(§ions) > threshold {
|
||||||
ag.compact();
|
ag.compact();
|
||||||
ag.notify("compacted");
|
ag.notify("compacted");
|
||||||
|
|
@ -312,13 +310,12 @@ impl Mind {
|
||||||
self.config.session_dir.join("conversation.jsonl"),
|
self.config.session_dir.join("conversation.jsonl"),
|
||||||
).ok();
|
).ok();
|
||||||
let mut ag = self.agent.lock().await;
|
let mut ag = self.agent.lock().await;
|
||||||
let shared_ctx = ag.shared_context.clone();
|
|
||||||
let shared_tools = ag.active_tools.clone();
|
let shared_tools = ag.active_tools.clone();
|
||||||
*ag = Agent::new(
|
*ag = Agent::new(
|
||||||
ApiClient::new(&self.config.api_base, &self.config.api_key, &self.config.model),
|
ApiClient::new(&self.config.api_base, &self.config.api_key, &self.config.model),
|
||||||
self.config.system_prompt.clone(), self.config.context_parts.clone(),
|
self.config.system_prompt.clone(), self.config.context_parts.clone(),
|
||||||
self.config.app.clone(), self.config.prompt_file.clone(),
|
self.config.app.clone(), self.config.prompt_file.clone(),
|
||||||
new_log, shared_ctx, shared_tools,
|
new_log, shared_tools,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -366,11 +363,8 @@ impl Mind {
|
||||||
|
|
||||||
// Compact if over budget before sending
|
// Compact if over budget before sending
|
||||||
let threshold = compaction_threshold(&self.config.app) as usize;
|
let threshold = compaction_threshold(&self.config.app) as usize;
|
||||||
ag.publish_context_state();
|
let used = crate::agent::context::sections_used(
|
||||||
let used = {
|
&ag.context_state_summary(None));
|
||||||
let sections = ag.shared_context.read().map(|s| s.clone()).unwrap_or_default();
|
|
||||||
crate::agent::context::sections_used(§ions)
|
|
||||||
};
|
|
||||||
if used > threshold {
|
if used > threshold {
|
||||||
ag.compact();
|
ag.compact();
|
||||||
ag.notify("compacted");
|
ag.notify("compacted");
|
||||||
|
|
@ -435,7 +429,6 @@ impl Mind {
|
||||||
{
|
{
|
||||||
let mut ag = self.agent.lock().await;
|
let mut ag = self.agent.lock().await;
|
||||||
ag.age_out_images();
|
ag.age_out_images();
|
||||||
ag.publish_context_state();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cmds.push(MindCommand::Compact);
|
cmds.push(MindCommand::Compact);
|
||||||
|
|
|
||||||
|
|
@ -863,7 +863,7 @@ impl ScreenView for InteractScreen {
|
||||||
agent.expire_activities();
|
agent.expire_activities();
|
||||||
app.status.prompt_tokens = agent.last_prompt_tokens();
|
app.status.prompt_tokens = agent.last_prompt_tokens();
|
||||||
app.status.model = agent.model().to_string();
|
app.status.model = agent.model().to_string();
|
||||||
let sections = agent.shared_context.read().map(|s| s.clone()).unwrap_or_default();
|
let sections = agent.context_state_summary(None);
|
||||||
app.status.context_budget = crate::agent::context::sections_budget_string(§ions);
|
app.status.context_budget = crate::agent::context::sections_budget_string(§ions);
|
||||||
app.activity = agent.activities.last()
|
app.activity = agent.activities.last()
|
||||||
.map(|a| a.label.clone())
|
.map(|a| a.label.clone())
|
||||||
|
|
|
||||||
|
|
@ -16,18 +16,22 @@ use super::{App, ScreenView, screen_legend};
|
||||||
use crate::agent::context::ContextSection;
|
use crate::agent::context::ContextSection;
|
||||||
|
|
||||||
pub(crate) struct ConsciousScreen {
|
pub(crate) struct ConsciousScreen {
|
||||||
|
agent: std::sync::Arc<tokio::sync::Mutex<crate::agent::Agent>>,
|
||||||
scroll: u16,
|
scroll: u16,
|
||||||
selected: Option<usize>,
|
selected: Option<usize>,
|
||||||
expanded: std::collections::HashSet<usize>,
|
expanded: std::collections::HashSet<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ConsciousScreen {
|
impl ConsciousScreen {
|
||||||
pub fn new() -> Self {
|
pub fn new(agent: std::sync::Arc<tokio::sync::Mutex<crate::agent::Agent>>) -> Self {
|
||||||
Self { scroll: 0, selected: None, expanded: std::collections::HashSet::new() }
|
Self { agent, scroll: 0, selected: None, expanded: std::collections::HashSet::new() }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_context_state(&self, app: &App) -> Vec<ContextSection> {
|
fn read_context_state(&self) -> Vec<ContextSection> {
|
||||||
app.shared_context.read().map_or_else(|_| Vec::new(), |s| s.clone())
|
match self.agent.try_lock() {
|
||||||
|
Ok(ag) => ag.context_state_summary(None),
|
||||||
|
Err(_) => Vec::new(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn item_count(&self, context_state: &[ContextSection]) -> usize {
|
fn item_count(&self, context_state: &[ContextSection]) -> usize {
|
||||||
|
|
@ -121,7 +125,7 @@ impl ScreenView for ConsciousScreen {
|
||||||
for event in events {
|
for event in events {
|
||||||
if let ratatui::crossterm::event::Event::Key(key) = event {
|
if let ratatui::crossterm::event::Event::Key(key) = event {
|
||||||
if key.kind != ratatui::crossterm::event::KeyEventKind::Press { continue; }
|
if key.kind != ratatui::crossterm::event::KeyEventKind::Press { continue; }
|
||||||
let context_state = self.read_context_state(app);
|
let context_state = self.read_context_state();
|
||||||
let item_count = self.item_count(&context_state);
|
let item_count = self.item_count(&context_state);
|
||||||
|
|
||||||
match key.code {
|
match key.code {
|
||||||
|
|
@ -171,7 +175,7 @@ impl ScreenView for ConsciousScreen {
|
||||||
if !app.status.context_budget.is_empty() {
|
if !app.status.context_budget.is_empty() {
|
||||||
lines.push(Line::raw(format!(" Budget: {}", app.status.context_budget)));
|
lines.push(Line::raw(format!(" Budget: {}", app.status.context_budget)));
|
||||||
}
|
}
|
||||||
let context_state = self.read_context_state(app);
|
let context_state = self.read_context_state();
|
||||||
if !context_state.is_empty() {
|
if !context_state.is_empty() {
|
||||||
let total: usize = context_state.iter().map(|s| s.tokens).sum();
|
let total: usize = context_state.iter().map(|s| s.tokens).sum();
|
||||||
lines.push(Line::raw(""));
|
lines.push(Line::raw(""));
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,6 @@ use ratatui::{
|
||||||
};
|
};
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
use crate::agent::context::SharedContextState;
|
|
||||||
|
|
||||||
/// Status info for the bottom status bar.
|
/// Status info for the bottom status bar.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
|
@ -126,7 +125,6 @@ pub struct App {
|
||||||
pub should_quit: bool,
|
pub should_quit: bool,
|
||||||
pub submitted: Vec<String>,
|
pub submitted: Vec<String>,
|
||||||
pub(crate) context_info: Option<ContextInfo>,
|
pub(crate) context_info: Option<ContextInfo>,
|
||||||
pub(crate) shared_context: SharedContextState,
|
|
||||||
pub(crate) agent_state: Vec<crate::mind::SubconsciousSnapshot>,
|
pub(crate) agent_state: Vec<crate::mind::SubconsciousSnapshot>,
|
||||||
pub(crate) walked_count: usize,
|
pub(crate) walked_count: usize,
|
||||||
pub(crate) channel_status: Vec<ChannelStatus>,
|
pub(crate) channel_status: Vec<ChannelStatus>,
|
||||||
|
|
@ -134,7 +132,7 @@ pub struct App {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl App {
|
impl App {
|
||||||
pub fn new(model: String, shared_context: SharedContextState, active_tools: crate::agent::tools::SharedActiveTools) -> Self {
|
pub fn new(model: String, active_tools: crate::agent::tools::SharedActiveTools) -> Self {
|
||||||
Self {
|
Self {
|
||||||
status: StatusInfo {
|
status: StatusInfo {
|
||||||
dmn_state: "resting".into(), dmn_turns: 0, dmn_max_turns: 20,
|
dmn_state: "resting".into(), dmn_turns: 0, dmn_max_turns: 20,
|
||||||
|
|
@ -149,7 +147,7 @@ impl App {
|
||||||
top_k: 20,
|
top_k: 20,
|
||||||
active_tools,
|
active_tools,
|
||||||
should_quit: false, submitted: Vec::new(),
|
should_quit: false, submitted: Vec::new(),
|
||||||
context_info: None, shared_context,
|
context_info: None,
|
||||||
agent_state: Vec::new(),
|
agent_state: Vec::new(),
|
||||||
walked_count: 0,
|
walked_count: 0,
|
||||||
channel_status: Vec::new(), idle_info: None,
|
channel_status: Vec::new(), idle_info: None,
|
||||||
|
|
@ -202,7 +200,6 @@ pub async fn start(cli: crate::user::CliArgs) -> Result<()> {
|
||||||
|
|
||||||
let mind = crate::mind::Mind::new(config, turn_tx);
|
let mind = crate::mind::Mind::new(config, turn_tx);
|
||||||
|
|
||||||
let shared_context = mind.agent.lock().await.shared_context.clone();
|
|
||||||
let shared_active_tools = mind.agent.lock().await.active_tools.clone();
|
let shared_active_tools = mind.agent.lock().await.active_tools.clone();
|
||||||
|
|
||||||
let mut result = Ok(());
|
let mut result = Ok(());
|
||||||
|
|
@ -216,7 +213,7 @@ pub async fn start(cli: crate::user::CliArgs) -> Result<()> {
|
||||||
// UI event loop
|
// UI event loop
|
||||||
s.spawn(async {
|
s.spawn(async {
|
||||||
result = run(
|
result = run(
|
||||||
tui::App::new(String::new(), shared_context, shared_active_tools),
|
tui::App::new(String::new(), shared_active_tools),
|
||||||
&mind, mind_tx,
|
&mind, mind_tx,
|
||||||
).await;
|
).await;
|
||||||
});
|
});
|
||||||
|
|
@ -337,7 +334,7 @@ pub async fn run(
|
||||||
Box::new(crate::user::chat::InteractScreen::new(
|
Box::new(crate::user::chat::InteractScreen::new(
|
||||||
mind.agent.clone(), mind.shared.clone(), mind_tx.clone(),
|
mind.agent.clone(), mind.shared.clone(), mind_tx.clone(),
|
||||||
)),
|
)),
|
||||||
Box::new(crate::user::context::ConsciousScreen::new()),
|
Box::new(crate::user::context::ConsciousScreen::new(mind.agent.clone())),
|
||||||
Box::new(crate::user::subconscious::SubconsciousScreen::new()),
|
Box::new(crate::user::subconscious::SubconsciousScreen::new()),
|
||||||
Box::new(crate::user::unconscious::UnconsciousScreen::new()),
|
Box::new(crate::user::unconscious::UnconsciousScreen::new()),
|
||||||
Box::new(crate::user::thalamus::ThalamusScreen::new()),
|
Box::new(crate::user::thalamus::ThalamusScreen::new()),
|
||||||
|
|
@ -455,12 +452,6 @@ pub async fn run(
|
||||||
let idx = n as usize;
|
let idx = n as usize;
|
||||||
if idx >= 1 && idx <= screens.len() {
|
if idx >= 1 && idx <= screens.len() {
|
||||||
active_screen = idx;
|
active_screen = idx;
|
||||||
// Refresh context state when switching to the conscious screen
|
|
||||||
if idx == 2 {
|
|
||||||
if let Ok(mut ag) = agent.try_lock() {
|
|
||||||
ag.publish_context_state();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if key.modifiers.contains(KeyModifiers::CONTROL) {
|
} else if key.modifiers.contains(KeyModifiers::CONTROL) {
|
||||||
match key.code {
|
match key.code {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue