mirror of
https://github.com/outbackdingo/optimclaw.git
synced 2026-09-01 17:19:24 +00:00
Add proactivity features: memory CLI, session pruning, self-repair notifications, slash commands, status diagnostics, context warnings
Closes the proactivity gap with six features: - Memory CLI (`ironclaw memory search/read/write/tree/status`) for direct workspace access without starting the full agent - Session pruning background task that evicts idle sessions (configurable TTL, default 7 days) - Self-repair notifications broadcast recovery results through channel manager instead of silent logging - `/heartbeat`, `/summarize`, `/suggest` slash commands for manual heartbeat trigger, thread summarization, and next-step suggestions - `ironclaw status` diagnostics command checking DB, session, secrets, embeddings, WASM tools, channels, heartbeat, and MCP servers - Context pressure warning that notifies users before auto-compaction fires Co-Authored-By: Claude Opus 4.6 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
1c9f9db420
commit
f3c85f57fc
+66
-1
@@ -14,7 +14,9 @@ use ironclaw::{
|
||||
WasmChannelRuntime, WasmChannelRuntimeConfig, WasmChannelServer,
|
||||
},
|
||||
},
|
||||
cli::{Cli, Command, run_mcp_command, run_tool_command},
|
||||
cli::{
|
||||
Cli, Command, run_mcp_command, run_memory_command, run_status_command, run_tool_command,
|
||||
},
|
||||
config::Config,
|
||||
context::ContextManager,
|
||||
history::Store,
|
||||
@@ -62,6 +64,69 @@ async fn main() -> anyhow::Result<()> {
|
||||
|
||||
return run_mcp_command(mcp_cmd.clone()).await;
|
||||
}
|
||||
Some(Command::Memory(mem_cmd)) => {
|
||||
tracing_subscriber::fmt()
|
||||
.with_env_filter(
|
||||
EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("warn")),
|
||||
)
|
||||
.init();
|
||||
|
||||
// Memory commands need database (and optionally embeddings)
|
||||
let _ = dotenvy::dotenv();
|
||||
let config = Config::from_env().map_err(|e| anyhow::anyhow!("{}", e))?;
|
||||
let store = ironclaw::history::Store::new(&config.database).await?;
|
||||
store.run_migrations().await?;
|
||||
|
||||
// Set up embeddings if available
|
||||
let session = ironclaw::llm::create_session_manager(ironclaw::llm::SessionConfig {
|
||||
auth_base_url: config.llm.nearai.auth_base_url.clone(),
|
||||
session_path: config.llm.nearai.session_path.clone(),
|
||||
..Default::default()
|
||||
})
|
||||
.await;
|
||||
|
||||
let embeddings: Option<Arc<dyn ironclaw::workspace::EmbeddingProvider>> =
|
||||
if config.embeddings.enabled {
|
||||
match config.embeddings.provider.as_str() {
|
||||
"nearai" => Some(Arc::new(
|
||||
ironclaw::workspace::NearAiEmbeddings::new(
|
||||
&config.llm.nearai.base_url,
|
||||
session,
|
||||
)
|
||||
.with_model(&config.embeddings.model, 1536),
|
||||
)),
|
||||
_ => {
|
||||
if let Some(api_key) = config.embeddings.openai_api_key() {
|
||||
let dim = match config.embeddings.model.as_str() {
|
||||
"text-embedding-3-large" => 3072,
|
||||
_ => 1536,
|
||||
};
|
||||
Some(Arc::new(ironclaw::workspace::OpenAiEmbeddings::with_model(
|
||||
api_key,
|
||||
&config.embeddings.model,
|
||||
dim,
|
||||
)))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
return run_memory_command(mem_cmd.clone(), store.pool(), embeddings).await;
|
||||
}
|
||||
Some(Command::Status) => {
|
||||
let _ = dotenvy::dotenv();
|
||||
tracing_subscriber::fmt()
|
||||
.with_env_filter(
|
||||
EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("warn")),
|
||||
)
|
||||
.init();
|
||||
|
||||
return run_status_command().await;
|
||||
}
|
||||
Some(Command::Setup {
|
||||
skip_auth,
|
||||
channels_only,
|
||||
|
||||
Reference in New Issue
Block a user