feat(kernel): add internal ZCLAW kernel integration with Tauri
Phase 1-3 of independence architecture: - zclaw-types: Add ToolDefinition, ToolResult, KernelConfig, ModelConfig - zclaw-kernel: Fix AgentInfo provider field, export config module - desktop: Add kernel_commands for internal kernel access - Add AgentId FromStr implementation for parsing New Tauri commands: - kernel_init, kernel_status, kernel_shutdown - agent_create, agent_list, agent_get, agent_delete - agent_chat Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
15
crates/zclaw-kernel/src/lib.rs
Normal file
15
crates/zclaw-kernel/src/lib.rs
Normal file
@@ -0,0 +1,15 @@
|
||||
//! ZCLAW Kernel
|
||||
//!
|
||||
//! Central coordinator for all ZCLAW subsystems.
|
||||
|
||||
mod kernel;
|
||||
mod registry;
|
||||
mod capabilities;
|
||||
mod events;
|
||||
pub mod config;
|
||||
|
||||
pub use kernel::*;
|
||||
pub use registry::*;
|
||||
pub use capabilities::*;
|
||||
pub use events::*;
|
||||
pub use config::*;
|
||||
92
crates/zclaw-kernel/src/registry.rs
Normal file
92
crates/zclaw-kernel/src/registry.rs
Normal file
@@ -0,0 +1,92 @@
|
||||
//! Agent registry
|
||||
|
||||
use dashmap::DashMap;
|
||||
use zclaw_types::{AgentConfig, AgentId, AgentInfo, AgentState};
|
||||
use chrono::Utc;
|
||||
|
||||
/// In-memory registry of active agents
|
||||
pub struct AgentRegistry {
|
||||
agents: DashMap<AgentId, AgentConfig>,
|
||||
states: DashMap<AgentId, AgentState>,
|
||||
created_at: DashMap<AgentId, chrono::DateTime<Utc>>,
|
||||
}
|
||||
|
||||
impl AgentRegistry {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
agents: DashMap::new(),
|
||||
states: DashMap::new(),
|
||||
created_at: DashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Register an agent
|
||||
pub fn register(&self, config: AgentConfig) {
|
||||
let id = config.id;
|
||||
self.agents.insert(id, config);
|
||||
self.states.insert(id, AgentState::Running);
|
||||
self.created_at.insert(id, Utc::now());
|
||||
}
|
||||
|
||||
/// Unregister an agent
|
||||
pub fn unregister(&self, id: &AgentId) {
|
||||
self.agents.remove(id);
|
||||
self.states.remove(id);
|
||||
self.created_at.remove(id);
|
||||
}
|
||||
|
||||
/// Get an agent by ID
|
||||
pub fn get(&self, id: &AgentId) -> Option<AgentConfig> {
|
||||
self.agents.get(id).map(|r| r.clone())
|
||||
}
|
||||
|
||||
/// Get agent info
|
||||
pub fn get_info(&self, id: &AgentId) -> Option<AgentInfo> {
|
||||
let config = self.agents.get(id)?;
|
||||
let state = self.states.get(id).map(|s| *s).unwrap_or(AgentState::Terminated);
|
||||
let created_at = self.created_at.get(id).map(|t| *t).unwrap_or_else(Utc::now);
|
||||
|
||||
Some(AgentInfo {
|
||||
id: *id,
|
||||
name: config.name.clone(),
|
||||
description: config.description.clone(),
|
||||
model: config.model.model.clone(),
|
||||
provider: config.model.provider.clone(),
|
||||
state,
|
||||
message_count: 0, // TODO: Track this
|
||||
created_at,
|
||||
updated_at: Utc::now(),
|
||||
})
|
||||
}
|
||||
|
||||
/// List all agents
|
||||
pub fn list(&self) -> Vec<AgentInfo> {
|
||||
self.agents.iter()
|
||||
.filter_map(|entry| {
|
||||
let id = entry.key();
|
||||
self.get_info(id)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Update agent state
|
||||
pub fn set_state(&self, id: &AgentId, state: AgentState) {
|
||||
self.states.insert(*id, state);
|
||||
}
|
||||
|
||||
/// Get agent state
|
||||
pub fn get_state(&self, id: &AgentId) -> AgentState {
|
||||
self.states.get(id).map(|s| *s).unwrap_or(AgentState::Terminated)
|
||||
}
|
||||
|
||||
/// Count active agents
|
||||
pub fn count(&self) -> usize {
|
||||
self.agents.len()
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for AgentRegistry {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
129
crates/zclaw-types/src/config.rs
Normal file
129
crates/zclaw-types/src/config.rs
Normal file
@@ -0,0 +1,129 @@
|
||||
//! Configuration types
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Kernel configuration
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct KernelConfig {
|
||||
/// Database URL (SQLite or PostgreSQL)
|
||||
pub database_url: String,
|
||||
|
||||
/// Default LLM provider
|
||||
pub default_provider: String,
|
||||
|
||||
/// Default model
|
||||
pub default_model: String,
|
||||
|
||||
/// Maximum tokens per response
|
||||
#[serde(default = "default_max_tokens")]
|
||||
pub max_tokens: u32,
|
||||
|
||||
/// Default temperature
|
||||
#[serde(default = "default_temperature")]
|
||||
pub temperature: f32,
|
||||
|
||||
/// Enable debug logging
|
||||
#[serde(default)]
|
||||
pub debug: bool,
|
||||
}
|
||||
|
||||
fn default_max_tokens() -> u32 {
|
||||
4096
|
||||
}
|
||||
|
||||
fn default_temperature() -> f32 {
|
||||
0.7
|
||||
}
|
||||
|
||||
impl Default for KernelConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
database_url: "sqlite::memory:".to_string(),
|
||||
default_provider: "anthropic".to_string(),
|
||||
default_model: "claude-sonnet-4-20250514".to_string(),
|
||||
max_tokens: default_max_tokens(),
|
||||
temperature: default_temperature(),
|
||||
debug: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Model configuration for an agent
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct ModelConfig {
|
||||
/// Provider name (anthropic, openai, gemini, ollama, etc.)
|
||||
pub provider: String,
|
||||
/// Model identifier
|
||||
pub model: String,
|
||||
/// API key environment variable name
|
||||
#[serde(default)]
|
||||
pub api_key_env: Option<String>,
|
||||
/// Custom base URL (for OpenAI-compatible providers)
|
||||
#[serde(default)]
|
||||
pub base_url: Option<String>,
|
||||
}
|
||||
|
||||
impl Default for ModelConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
provider: "anthropic".to_string(),
|
||||
model: "claude-sonnet-4-20250514".to_string(),
|
||||
api_key_env: Some("ANTHROPIC_API_KEY".to_string()),
|
||||
base_url: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ModelConfig {
|
||||
pub fn anthropic(model: impl Into<String>) -> Self {
|
||||
Self {
|
||||
provider: "anthropic".to_string(),
|
||||
model: model.into(),
|
||||
api_key_env: Some("ANTHROPIC_API_KEY".to_string()),
|
||||
base_url: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn openai(model: impl Into<String>) -> Self {
|
||||
Self {
|
||||
provider: "openai".to_string(),
|
||||
model: model.into(),
|
||||
api_key_env: Some("OPENAI_API_KEY".to_string()),
|
||||
base_url: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn gemini(model: impl Into<String>) -> Self {
|
||||
Self {
|
||||
provider: "gemini".to_string(),
|
||||
model: model.into(),
|
||||
api_key_env: Some("GEMINI_API_KEY".to_string()),
|
||||
base_url: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ollama(model: impl Into<String>) -> Self {
|
||||
Self {
|
||||
provider: "ollama".to_string(),
|
||||
model: model.into(),
|
||||
api_key_env: None,
|
||||
base_url: Some("http://localhost:11434".to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn openai_compatible(model: impl Into<String>, base_url: impl Into<String>) -> Self {
|
||||
Self {
|
||||
provider: "openai".to_string(),
|
||||
model: model.into(),
|
||||
api_key_env: None,
|
||||
base_url: Some(base_url.into()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if this uses the same driver as another config
|
||||
pub fn same_driver(&self, other: &ModelConfig) -> bool {
|
||||
self.provider == other.provider
|
||||
&& self.api_key_env == other.api_key_env
|
||||
&& self.base_url == other.base_url
|
||||
}
|
||||
}
|
||||
90
crates/zclaw-types/src/tool.rs
Normal file
90
crates/zclaw-types/src/tool.rs
Normal file
@@ -0,0 +1,90 @@
|
||||
//! Tool definition types
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::Value;
|
||||
|
||||
/// Tool definition for LLM function calling
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct ToolDefinition {
|
||||
/// Tool name (unique identifier)
|
||||
pub name: String,
|
||||
/// Human-readable description
|
||||
pub description: String,
|
||||
/// JSON Schema for input parameters
|
||||
pub input_schema: Value,
|
||||
}
|
||||
|
||||
impl ToolDefinition {
|
||||
pub fn new(name: impl Into<String>, description: impl Into<String>, schema: Value) -> Self {
|
||||
Self {
|
||||
name: name.into(),
|
||||
description: description.into(),
|
||||
input_schema: schema,
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a simple tool with string parameters
|
||||
pub fn simple(name: impl Into<String>, description: impl Into<String>, params: &[&str]) -> Self {
|
||||
let properties: Value = params
|
||||
.iter()
|
||||
.map(|p| {
|
||||
let s = p.to_string();
|
||||
(s.clone(), serde_json::json!({"type": "string"}))
|
||||
})
|
||||
.collect();
|
||||
|
||||
let required: Vec<&str> = params.to_vec();
|
||||
|
||||
Self {
|
||||
name: name.into(),
|
||||
description: description.into(),
|
||||
input_schema: serde_json::json!({
|
||||
"type": "object",
|
||||
"properties": properties,
|
||||
"required": required
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Tool execution result
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct ToolResult {
|
||||
/// Whether execution succeeded
|
||||
pub success: bool,
|
||||
/// Output data
|
||||
pub output: Value,
|
||||
/// Error message if failed
|
||||
pub error: Option<String>,
|
||||
}
|
||||
|
||||
impl ToolResult {
|
||||
pub fn success(output: Value) -> Self {
|
||||
Self {
|
||||
success: true,
|
||||
output,
|
||||
error: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn error(message: impl Into<String>) -> Self {
|
||||
Self {
|
||||
success: false,
|
||||
output: Value::Null,
|
||||
error: Some(message.into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Built-in tool names
|
||||
pub mod builtin_tools {
|
||||
pub const FILE_READ: &str = "file_read";
|
||||
pub const FILE_WRITE: &str = "file_write";
|
||||
pub const FILE_LIST: &str = "file_list";
|
||||
pub const SHELL_EXEC: &str = "shell_exec";
|
||||
pub const WEB_FETCH: &str = "web_fetch";
|
||||
pub const WEB_SEARCH: &str = "web_search";
|
||||
pub const MEMORY_STORE: &str = "memory_store";
|
||||
pub const MEMORY_RECALL: &str = "memory_recall";
|
||||
pub const MEMORY_SEARCH: &str = "memory_search";
|
||||
}
|
||||
276
desktop/src-tauri/src/kernel_commands.rs
Normal file
276
desktop/src-tauri/src/kernel_commands.rs
Normal file
@@ -0,0 +1,276 @@
|
||||
//! ZCLAW Kernel commands for Tauri
|
||||
//!
|
||||
//! These commands provide direct access to the internal ZCLAW Kernel,
|
||||
//! eliminating the need for external OpenFang process.
|
||||
|
||||
use std::sync::Arc;
|
||||
use tauri::{AppHandle, Manager, State};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tokio::sync::Mutex;
|
||||
use zclaw_kernel::Kernel;
|
||||
use zclaw_types::{AgentConfig, AgentId, AgentInfo, AgentState};
|
||||
|
||||
/// Kernel state wrapper for Tauri
|
||||
pub type KernelState = Arc<Mutex<Option<Kernel>>>;
|
||||
|
||||
/// Agent creation request
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct CreateAgentRequest {
|
||||
/// Agent name
|
||||
pub name: String,
|
||||
/// Agent description
|
||||
#[serde(default)]
|
||||
pub description: Option<String>,
|
||||
/// System prompt
|
||||
#[serde(default)]
|
||||
pub system_prompt: Option<String>,
|
||||
/// Model provider
|
||||
#[serde(default = "default_provider")]
|
||||
pub provider: String,
|
||||
/// Model identifier
|
||||
#[serde(default = "default_model")]
|
||||
pub model: String,
|
||||
/// Max tokens
|
||||
#[serde(default = "default_max_tokens")]
|
||||
pub max_tokens: u32,
|
||||
/// Temperature
|
||||
#[serde(default = "default_temperature")]
|
||||
pub temperature: f32,
|
||||
}
|
||||
|
||||
fn default_provider() -> String { "anthropic".to_string() }
|
||||
fn default_model() -> String { "claude-sonnet-4-20250514".to_string() }
|
||||
fn default_max_tokens() -> u32 { 4096 }
|
||||
fn default_temperature() -> f32 { 0.7 }
|
||||
|
||||
/// Agent creation response
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct CreateAgentResponse {
|
||||
pub id: String,
|
||||
pub name: String,
|
||||
pub state: String,
|
||||
}
|
||||
|
||||
/// Chat request
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ChatRequest {
|
||||
/// Agent ID
|
||||
pub agent_id: String,
|
||||
/// Message content
|
||||
pub message: String,
|
||||
}
|
||||
|
||||
/// Chat response
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ChatResponse {
|
||||
pub content: String,
|
||||
pub input_tokens: u32,
|
||||
pub output_tokens: u32,
|
||||
}
|
||||
|
||||
/// Kernel status response
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct KernelStatusResponse {
|
||||
pub initialized: bool,
|
||||
pub agent_count: usize,
|
||||
pub database_url: Option<String>,
|
||||
pub default_provider: Option<String>,
|
||||
pub default_model: Option<String>,
|
||||
}
|
||||
|
||||
/// Initialize the internal ZCLAW Kernel
|
||||
#[tauri::command]
|
||||
pub async fn kernel_init(
|
||||
state: State<'_, KernelState>,
|
||||
) -> Result<KernelStatusResponse, String> {
|
||||
let mut kernel_lock = state.lock().await;
|
||||
|
||||
if kernel_lock.is_some() {
|
||||
let kernel = kernel_lock.as_ref().unwrap();
|
||||
return Ok(KernelStatusResponse {
|
||||
initialized: true,
|
||||
agent_count: kernel.list_agents().len(),
|
||||
database_url: None,
|
||||
default_provider: Some("anthropic".to_string()),
|
||||
default_model: Some("claude-sonnet-4-20250514".to_string()),
|
||||
});
|
||||
}
|
||||
|
||||
// Load configuration
|
||||
let config = zclaw_kernel::config::KernelConfig::default();
|
||||
|
||||
// Boot kernel
|
||||
let kernel = Kernel::boot(config.clone())
|
||||
.await
|
||||
.map_err(|e| format!("Failed to initialize kernel: {}", e))?;
|
||||
|
||||
let agent_count = kernel.list_agents().len();
|
||||
|
||||
*kernel_lock = Some(kernel);
|
||||
|
||||
Ok(KernelStatusResponse {
|
||||
initialized: true,
|
||||
agent_count,
|
||||
database_url: Some(config.database_url),
|
||||
default_provider: Some(config.default_provider),
|
||||
default_model: Some(config.default_model),
|
||||
})
|
||||
}
|
||||
|
||||
/// Get kernel status
|
||||
#[tauri::command]
|
||||
pub async fn kernel_status(
|
||||
state: State<'_, KernelState>,
|
||||
) -> Result<KernelStatusResponse, String> {
|
||||
let kernel_lock = state.lock().await;
|
||||
|
||||
match kernel_lock.as_ref() {
|
||||
Some(kernel) => Ok(KernelStatusResponse {
|
||||
initialized: true,
|
||||
agent_count: kernel.list_agents().len(),
|
||||
database_url: None,
|
||||
default_provider: Some("anthropic".to_string()),
|
||||
default_model: Some("claude-sonnet-4-20250514".to_string()),
|
||||
}),
|
||||
None => Ok(KernelStatusResponse {
|
||||
initialized: false,
|
||||
agent_count: 0,
|
||||
database_url: None,
|
||||
default_provider: None,
|
||||
default_model: None,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
/// Shutdown the kernel
|
||||
#[tauri::command]
|
||||
pub async fn kernel_shutdown(
|
||||
state: State<'_, KernelState>,
|
||||
) -> Result<(), String> {
|
||||
let mut kernel_lock = state.lock().await;
|
||||
|
||||
if let Some(kernel) = kernel_lock.take() {
|
||||
kernel.shutdown().await.map_err(|e| e.to_string())?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Create a new agent
|
||||
#[tauri::command]
|
||||
pub async fn agent_create(
|
||||
state: State<'_, KernelState>,
|
||||
request: CreateAgentRequest,
|
||||
) -> Result<CreateAgentResponse, String> {
|
||||
let kernel_lock = state.lock().await;
|
||||
|
||||
let kernel = kernel_lock.as_ref()
|
||||
.ok_or_else(|| "Kernel not initialized. Call kernel_init first.".to_string())?;
|
||||
|
||||
// Build agent config
|
||||
let config = AgentConfig::new(&request.name)
|
||||
.with_description(request.description.unwrap_or_default())
|
||||
.with_system_prompt(request.system_prompt.unwrap_or_default())
|
||||
.with_model(zclaw_types::ModelConfig {
|
||||
provider: request.provider,
|
||||
model: request.model,
|
||||
api_key_env: None,
|
||||
base_url: None,
|
||||
})
|
||||
.with_max_tokens(request.max_tokens)
|
||||
.with_temperature(request.temperature);
|
||||
|
||||
let id = kernel.spawn_agent(config)
|
||||
.await
|
||||
.map_err(|e| format!("Failed to create agent: {}", e))?;
|
||||
|
||||
Ok(CreateAgentResponse {
|
||||
id: id.to_string(),
|
||||
name: request.name,
|
||||
state: "running".to_string(),
|
||||
})
|
||||
}
|
||||
|
||||
/// List all agents
|
||||
#[tauri::command]
|
||||
pub async fn agent_list(
|
||||
state: State<'_, KernelState>,
|
||||
) -> Result<Vec<AgentInfo>, String> {
|
||||
let kernel_lock = state.lock().await;
|
||||
|
||||
let kernel = kernel_lock.as_ref()
|
||||
.ok_or_else(|| "Kernel not initialized. Call kernel_init first.".to_string())?;
|
||||
|
||||
Ok(kernel.list_agents())
|
||||
}
|
||||
|
||||
/// Get agent info
|
||||
#[tauri::command]
|
||||
pub async fn agent_get(
|
||||
state: State<'_, KernelState>,
|
||||
agent_id: String,
|
||||
) -> Result<Option<AgentInfo>, String> {
|
||||
let kernel_lock = state.lock().await;
|
||||
|
||||
let kernel = kernel_lock.as_ref()
|
||||
.ok_or_else(|| "Kernel not initialized. Call kernel_init first.".to_string())?;
|
||||
|
||||
let id: AgentId = agent_id.parse()
|
||||
.map_err(|_| "Invalid agent ID format".to_string())?;
|
||||
|
||||
Ok(kernel.get_agent(&id))
|
||||
}
|
||||
|
||||
/// Delete an agent
|
||||
#[tauri::command]
|
||||
pub async fn agent_delete(
|
||||
state: State<'_, KernelState>,
|
||||
agent_id: String,
|
||||
) -> Result<(), String> {
|
||||
let kernel_lock = state.lock().await;
|
||||
|
||||
let kernel = kernel_lock.as_ref()
|
||||
.ok_or_else(|| "Kernel not initialized. Call kernel_init first.".to_string())?;
|
||||
|
||||
let id: AgentId = agent_id.parse()
|
||||
.map_err(|_| "Invalid agent ID format".to_string())?;
|
||||
|
||||
kernel.kill_agent(&id)
|
||||
.await
|
||||
.map_err(|e| format!("Failed to delete agent: {}", e))
|
||||
}
|
||||
|
||||
/// Send a message to an agent
|
||||
#[tauri::command]
|
||||
pub async fn agent_chat(
|
||||
state: State<'_, KernelState>,
|
||||
request: ChatRequest,
|
||||
) -> Result<ChatResponse, String> {
|
||||
let kernel_lock = state.lock().await;
|
||||
|
||||
let kernel = kernel_lock.as_ref()
|
||||
.ok_or_else(|| "Kernel not initialized. Call kernel_init first.".to_string())?;
|
||||
|
||||
let id: AgentId = request.agent_id.parse()
|
||||
.map_err(|_| "Invalid agent ID format".to_string())?;
|
||||
|
||||
let response = kernel.send_message(&id, request.message)
|
||||
.await
|
||||
.map_err(|e| format!("Chat failed: {}", e))?;
|
||||
|
||||
Ok(ChatResponse {
|
||||
content: response.content,
|
||||
input_tokens: response.input_tokens,
|
||||
output_tokens: response.output_tokens,
|
||||
})
|
||||
}
|
||||
|
||||
/// Create the kernel state for Tauri
|
||||
pub fn create_kernel_state() -> KernelState {
|
||||
Arc::new(Mutex::new(None))
|
||||
}
|
||||
@@ -24,6 +24,9 @@ mod memory_commands;
|
||||
// Intelligence Layer (migrated from frontend lib/)
|
||||
mod intelligence;
|
||||
|
||||
// Internal ZCLAW Kernel commands (replaces external OpenFang process)
|
||||
mod kernel_commands;
|
||||
|
||||
use serde::Serialize;
|
||||
use serde_json::{json, Value};
|
||||
use std::fs;
|
||||
@@ -1308,6 +1311,9 @@ pub fn run() {
|
||||
let reflection_state: intelligence::ReflectionEngineState = std::sync::Arc::new(tokio::sync::Mutex::new(intelligence::ReflectionEngine::new(None)));
|
||||
let identity_state: intelligence::IdentityManagerState = std::sync::Arc::new(tokio::sync::Mutex::new(intelligence::AgentIdentityManager::new()));
|
||||
|
||||
// Initialize internal ZCLAW Kernel state
|
||||
let kernel_state = kernel_commands::create_kernel_state();
|
||||
|
||||
tauri::Builder::default()
|
||||
.plugin(tauri_plugin_opener::init())
|
||||
.manage(browser_state)
|
||||
@@ -1315,7 +1321,17 @@ pub fn run() {
|
||||
.manage(heartbeat_state)
|
||||
.manage(reflection_state)
|
||||
.manage(identity_state)
|
||||
.manage(kernel_state)
|
||||
.invoke_handler(tauri::generate_handler![
|
||||
// Internal ZCLAW Kernel commands (preferred)
|
||||
kernel_commands::kernel_init,
|
||||
kernel_commands::kernel_status,
|
||||
kernel_commands::kernel_shutdown,
|
||||
kernel_commands::agent_create,
|
||||
kernel_commands::agent_list,
|
||||
kernel_commands::agent_get,
|
||||
kernel_commands::agent_delete,
|
||||
kernel_commands::agent_chat,
|
||||
// OpenFang commands (new naming)
|
||||
openfang_status,
|
||||
openfang_start,
|
||||
|
||||
Reference in New Issue
Block a user