mirror of
https://github.com/outbackdingo/optimclaw.git
synced 2026-09-01 09:09:19 +00:00
feat: hot-activate WASM channels, channel-first prompts, unified artifact resolution (#297)
* refactor: unify WASM artifact resolution into registry/artifacts.rs Consolidate duplicated WASM find/build/install logic from 5+ files into a single src/registry/artifacts.rs module. This fixes two bugs: - registry/installer.rs now respects CARGO_TARGET_DIR (was hardcoded) - channels/wasm/bundled.rs now searches all WASM triples (was wasip2 only) Also includes: extension manager hot-activation for WASM channels, extension guidance in LLM prompts, channel manager hot-add support, webhook router channel lookup, and minor cleanups. Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix: send approval prompts as messages on WASM channels (Telegram, Slack) WASM channels mapped ApprovalNeeded status to a typing indicator, so users on Telegram never saw tool approval prompts — the agent got stuck in AwaitingApproval and all subsequent messages failed with "Waiting for approval". - Intercept ApprovalNeeded in WasmChannel::handle_status_update and send the prompt as an actual message via call_on_respond, showing tool name, description, parameters, and yes/no/always instructions - Guard against empty LLM responses after clean_response() strips reasoning_content think-tags (defense-in-depth for reasoning models) - Add reasoning_content fallback to NearAiChatProvider::complete() for consistency with complete_with_tools() - Add debug logging when empty responses are suppressed - Improve error logging for channel respond() failures - Register WASM channel webhook routes before credential checks so platforms don't deactivate webhook URLs with 404s Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix: address PR #297 review comments - ChannelManager::add: use async write().await instead of try_write() - resolve_target_dir: resolve relative CARGO_TARGET_DIR against crate_dir - install_wasm_files: log warning on capabilities copy failure - refresh_active_channel: load capabilities file for webhook secret name - activate_wasm_channel: validate name against path traversal - Fix cargo fmt formatting in nearai_chat.rs Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix: wire up channel runtime for hot-activation and address PR review round 2 - Wire up set_channel_runtime() in main.rs so hot-activation actually works (with_channel_runtime was never called — hot-activation was dead code) - Change ExtensionManager channel runtime fields to RwLock<Option<...>> interior mutability so set_channel_runtime(&self) works after Arc wrapping - Fix artifact tests to use resolve_target_dir() instead of hardcoding "target/" (breaks when CARGO_TARGET_DIR is set) - Fix bundled.rs build hint: cargo component build (not cargo build --target) - Fix wasm_artifact_path doc: binary_name should not include .wasm extension Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix: use char-aware truncation to prevent UTF-8 panic in approval prompt &s[..77] panics on multi-byte UTF-8 (CJK, emoji). Use s.chars().take(77) for safe truncation at character boundaries. Co-Authored-By: Claude Opus 4.6 <[email protected]> --------- Co-authored-by: Claude Opus 4.6 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
a320f265b3
commit
ea57447649
+24
-14
@@ -1,16 +1,19 @@
|
||||
//! Unified extension system for discovering, installing, authenticating, and activating
|
||||
//! MCP servers and WASM tools through conversational agent interactions.
|
||||
//! Lifecycle management for extensions: discovery, installation, authentication,
|
||||
//! and activation of channels, tools, and MCP servers.
|
||||
//!
|
||||
//! Extensions are the user-facing abstraction over MCP servers and WASM tools. The agent
|
||||
//! can search a built-in registry (or discover online), install, authenticate, and activate
|
||||
//! extensions at runtime without CLI commands.
|
||||
//! Extensions are the user-facing abstraction that unifies three runtime kinds:
|
||||
//! - **Channels** (Telegram, Slack, Discord) — messaging integrations (WASM)
|
||||
//! - **Tools** — sandboxed capabilities (WASM)
|
||||
//! - **MCP servers** — external API integrations via Model Context Protocol
|
||||
//!
|
||||
//! The agent can search a built-in registry (or discover online), install,
|
||||
//! authenticate, and activate extensions at runtime without CLI commands.
|
||||
//!
|
||||
//! ```text
|
||||
//! User: "add notion"
|
||||
//! -> tool_search("notion") -> finds MCP server in registry
|
||||
//! -> tool_install("notion") -> saves config to mcp-servers.json
|
||||
//! -> tool_auth("notion") -> OAuth 2.1 flow, returns URL
|
||||
//! -> tool_activate("notion") -> connects, registers tools
|
||||
//! User: "add telegram"
|
||||
//! -> tool_search("telegram") -> finds channel in registry
|
||||
//! -> tool_install("telegram") -> copies bundled WASM to channels dir
|
||||
//! -> tool_activate("telegram") -> configures credentials, starts channel
|
||||
//! ```
|
||||
|
||||
pub mod discovery;
|
||||
@@ -31,7 +34,7 @@ pub enum ExtensionKind {
|
||||
McpServer,
|
||||
/// Sandboxed WASM module, file-based, capabilities auth.
|
||||
WasmTool,
|
||||
/// WASM channel module (future: dynamic activation, currently needs restart).
|
||||
/// WASM channel module with hot-activation support.
|
||||
WasmChannel,
|
||||
}
|
||||
|
||||
@@ -82,6 +85,9 @@ pub enum ExtensionSource {
|
||||
repo_url: String,
|
||||
#[serde(default)]
|
||||
build_dir: Option<String>,
|
||||
/// Crate name used to locate the build artifact binary.
|
||||
#[serde(default)]
|
||||
crate_name: Option<String>,
|
||||
},
|
||||
/// Discovered online (not yet validated for a specific source type).
|
||||
Discovered { url: String },
|
||||
@@ -169,6 +175,10 @@ pub struct ActivateResult {
|
||||
pub message: String,
|
||||
}
|
||||
|
||||
fn default_true() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
/// An installed extension with its current status.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct InstalledExtension {
|
||||
@@ -187,6 +197,9 @@ pub struct InstalledExtension {
|
||||
/// Whether this extension has a setup schema (required_secrets) that can be configured.
|
||||
#[serde(default)]
|
||||
pub needs_setup: bool,
|
||||
/// Whether this extension is installed locally (false = available in registry but not installed).
|
||||
#[serde(default = "default_true")]
|
||||
pub installed: bool,
|
||||
}
|
||||
|
||||
/// Error type for extension operations.
|
||||
@@ -222,9 +235,6 @@ pub enum ExtensionError {
|
||||
#[error("Config error: {0}")]
|
||||
Config(String),
|
||||
|
||||
#[error("Channels require restart to activate")]
|
||||
ChannelNeedsRestart,
|
||||
|
||||
#[error("{0}")]
|
||||
Other(String),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user