From 0f5700921f0630e5dcbaac6ae2cc8eb58021a86d Mon Sep 17 00:00:00 2001 From: M3gA-Mind Date: Thu, 26 Mar 2026 22:16:10 +0530 Subject: [PATCH 1/3] refactor: update memory recall methods to return context as JSON values - Changed the return type of `recall_skill_context` to `Option` for better flexibility. - Updated logging to provide clearer insights during memory recall operations. - Simplified context handling in `chat_send_inner` and `recall_memory` functions to improve readability. --- src-tauri/src/commands/chat.rs | 11 ++--------- src-tauri/src/commands/memory.rs | 2 +- src-tauri/src/memory/mod.rs | 5 +++-- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/src-tauri/src/commands/chat.rs b/src-tauri/src/commands/chat.rs index 728d469dd0d..af90f8b7b17 100644 --- a/src-tauri/src/commands/chat.rs +++ b/src-tauri/src/commands/chat.rs @@ -535,12 +535,9 @@ async fn chat_send_inner( log::info!( "[chat] Conversation memory recall: has_data={}, len={}", ctx.is_some(), - ctx.as_deref().map(|s| s.len()).unwrap_or(0) + ctx.as_ref().map(|ctx| ctx.to_string().len()).unwrap_or(0) ); - if let Some(ref data) = ctx { - log::debug!("[chat] Conversation memory content:\n{}", data); - } - ctx + ctx.map(|ctx| ctx.to_string()) } Err(e) => { log::warn!("[chat] Conversation memory recall failed: {}", e); @@ -567,10 +564,6 @@ async fn chat_send_inner( log::info!("[chat] Recalling memory for skill={sid}"); match mem.recall_skill_context(sid, sid, 10).await { Ok(Some(ctx)) => { - log::info!( - "[chat] Skill memory recall ok: skill={sid}, len={}", - ctx.len() - ); log::debug!("[chat] Skill memory content (skill={sid}):\n{}", ctx); skill_contexts.push(format!( "[{}_CONTEXT]\n{}\n[/{}_CONTEXT]", diff --git a/src-tauri/src/commands/memory.rs b/src-tauri/src/commands/memory.rs index 8bfd9a513e3..87d890a54f6 100644 --- a/src-tauri/src/commands/memory.rs +++ b/src-tauri/src/commands/memory.rs @@ -122,7 +122,7 @@ pub async fn recall_memory( ), Err(e) => log::warn!("[memory] recall_memory: exit — error: {e}"), } - result + result.map(|ctx| ctx.map(|ctx| ctx.to_string())) } None => { log::warn!("[memory] recall_memory: exit — client not initialised (no JWT set)"); diff --git a/src-tauri/src/memory/mod.rs b/src-tauri/src/memory/mod.rs index c43aa4123e6..f92312daab6 100644 --- a/src-tauri/src/memory/mod.rs +++ b/src-tauri/src/memory/mod.rs @@ -214,7 +214,7 @@ impl MemoryClient { skill_id: &str, _integration_id: &str, max_chunks: u32, - ) -> Result, String> { + ) -> Result, String> { let namespace = skill_id.to_string(); log::info!( "[memory] recall_skill_context: entry (namespace={namespace}, max_chunks={max_chunks})" @@ -230,7 +230,8 @@ impl MemoryClient { log::warn!("[memory] recall_skill_context: exit — error (namespace={namespace}): {e}"); format!("Memory recall failed: {e}") })?; - let response = res.data.response; + log::info!("[memory] recall_skill_context: response: {res:?}"); + let response = res.data.context; log::info!( "[memory] recall_skill_context: exit — ok (namespace={namespace}, has_response={})", response.is_some() From 4ba1723cb7eb198e3510437277a0229362047f10 Mon Sep 17 00:00:00 2001 From: M3gA-Mind Date: Thu, 26 Mar 2026 22:26:42 +0530 Subject: [PATCH 2/3] Update TOOLS.md to reflect changes in Notion tool availability and clarify memory context usage - Reduced the number of available tools for Notion from 25 to 12. - Added architecture note regarding memory layer handling for read/query operations. - Updated descriptions to specify that data retrieval is managed by the memory context instead of tools. --- ai/TOOLS.md | 280 +++------------------------------------------------- 1 file changed, 11 insertions(+), 269 deletions(-) diff --git a/ai/TOOLS.md b/ai/TOOLS.md index d761e821ca6..a2db38184f4 100644 --- a/ai/TOOLS.md +++ b/ai/TOOLS.md @@ -2,19 +2,21 @@ This document lists all available tools that AlphaHuman can use to interact with external services and perform actions. Tools are organized by integration and automatically updated when the app loads. +> **Architecture note**: All read/query operations (get-page, list-*, query-database, search, etc.) are handled by the memory layer — data is fetched from the TinyHumans Neocortex memory system and injected into context automatically. Only write, create, update, delete, and trigger operations are exposed as tools. + ## Overview -AlphaHuman has access to **25 tools** across **1 integrations**. +AlphaHuman has access to **12 tools** across **1 integrations**. **Quick Statistics:** -- **Notion**: 25 tools +- **Notion**: 12 tools ## Available Tools ### Notion Tools -This skill provides 25 tools for notion integration. +This skill provides 12 tools for notion integration. Data retrieval is handled by the memory layer, not tools. #### append-blocks @@ -40,11 +42,11 @@ This skill provides 25 tools for notion integration. #### append-text -**Description**: Append text content to a page or block. Use the page id (or block_id) from list-all-pages or get-page. Creates paragraph blocks with the given text. +**Description**: Append text content to a page or block. Use the page id (or block_id) from memory context. Creates paragraph blocks with the given text. **Parameters**: -- **block_id** (string): The page or block ID to append to (use page id from list-all-pages) +- **block_id** (string): The page or block ID to append to (use page id from memory context) - **content** (string): Alias for text — the content to append to the page - **page_id** (string): Alias for block_id when appending to a page (same as block_id) - **text** (string) **(required)**: The text to append (required). Pass the exact content to add to the page. @@ -190,251 +192,6 @@ This skill provides 25 tools for notion integration. --- -#### get-block - -**Description**: Get a block by its ID. Returns the block's type and content. - -**Parameters**: - -- **block_id** (string) **(required)**: The block ID - -**Usage Context**: Available in all environments - -**Example**: - -```json -{ "tool": "get-block", "parameters": { "block_id": "example_block_id" } } -``` - ---- - -#### get-block-children - -**Description**: Get the children blocks of a block or page. - -**Parameters**: - -- **block_id** (string) **(required)**: The parent block or page ID -- **page_size** (number): Number of blocks (default 50, max 100) - -**Usage Context**: Available in all environments - -**Example**: - -```json -{ "tool": "get-block-children", "parameters": { "block_id": "example_block_id", "page_size": 10 } } -``` - ---- - -#### get-database - -**Description**: Get a database's schema and metadata. Shows all properties and their types. - -**Parameters**: - -- **database_id** (string) **(required)**: The database ID - -**Usage Context**: Available in all environments - -**Example**: - -```json -{ "tool": "get-database", "parameters": { "database_id": "example_database_id" } } -``` - ---- - -#### get-page - -**Description**: Get a page's metadata and properties by its ID. Use notion-get-page-content to get the actual content/blocks. - -**Parameters**: - -- **page_id** (string) **(required)**: The page ID (UUID format, with or without dashes) - -**Usage Context**: Available in all environments - -**Example**: - -```json -{ "tool": "get-page", "parameters": { "page_id": "example_page_id" } } -``` - ---- - -#### get-page-content - -**Description**: Get the content blocks of a page. Returns the text and structure of the page. Use recursive=true to also get nested blocks. - -**Parameters**: - -- **page_id** (string) **(required)**: The page ID to get content from -- **page_size** (number): Number of blocks to return (default 50, max 100) -- **recursive** (string): Whether to fetch nested blocks (default: false) - -**Usage Context**: Available in all environments - -**Example**: - -```json -{ - "tool": "get-page-content", - "parameters": { "page_id": "example_page_id", "page_size": 10, "recursive": "example_recursive" } -} -``` - ---- - -#### get-user - -**Description**: Get a user by their ID. - -**Parameters**: - -- **user_id** (string) **(required)**: The user ID - -**Usage Context**: Available in all environments - -**Example**: - -```json -{ "tool": "get-user", "parameters": { "user_id": "example_user_id" } } -``` - ---- - -#### list-all-databases - -**Description**: List all databases in the workspace that the integration has access to. - -**Parameters**: - -- **page_size** (number): Number of results (default 20, max 100) - -**Usage Context**: Available in all environments - -**Example**: - -```json -{ "tool": "list-all-databases", "parameters": { "page_size": 10 } } -``` - ---- - -#### list-all-pages - -**Description**: List pages in the workspace (from last sync). Returns synced pages; run a sync in Settings to refresh. - -**Parameters**: - -- **page_size** (number): Number of results to return (default 20, max 100) - -**Usage Context**: Available in all environments - -**Example**: - -```json -{ "tool": "list-all-pages", "parameters": { "page_size": 10 } } -``` - ---- - -#### list-comments - -**Description**: List comments on a block or page. - -**Parameters**: - -- **block_id** (string) **(required)**: Block or page ID to get comments for -- **page_size** (number): Number of results (default 20, max 100) - -**Usage Context**: Available in all environments - -**Example**: - -```json -{ "tool": "list-comments", "parameters": { "block_id": "example_block_id", "page_size": 10 } } -``` - ---- - -#### list-users - -**Description**: List all users in the workspace that the integration can see. - -**Parameters**: - -- **page_size** (number): Number of results (default 20, max 100) - -**Usage Context**: Available in all environments - -**Example**: - -```json -{ "tool": "list-users", "parameters": { "page_size": 10 } } -``` - ---- - -#### query-database - -**Description**: Query a database with optional filters and sorts. Returns database rows/pages. Automatically handles API version compatibility. - -**Parameters**: - -- **database_id** (string) **(required)**: The database ID to query. Can be either a legacy database ID or a new data source ID - the tool will handle both automatically -- **filter** (string): JSON string of filter object (Notion filter syntax) -- **page_size** (number): Number of results (default 20, max 100) -- **sorts** (string): JSON string of sorts array (Notion sort syntax) - -**Usage Context**: Available in all environments - -**Example**: - -```json -{ - "tool": "query-database", - "parameters": { - "database_id": "example_database_id", - "filter": "example_filter", - "page_size": 10, - "sorts": "example_sorts" - } -} -``` - ---- - -#### search - -**Description**: Search for pages and databases in your Notion workspace. Supports query, filter by object type (page or database), and sort by last_edited_time. - -**Parameters**: - -- **filter** (string): Filter results by type: page or database -- **page_size** (number): Number of results to return (default 20, max 100) -- **query** (string): Search query (optional, returns recent if empty) -- **sort_direction** (string): Sort direction (default: descending by last_edited_time) - -**Usage Context**: Available in all environments - -**Example**: - -```json -{ - "tool": "search", - "parameters": { - "filter": "example_filter", - "page_size": 10, - "query": "example_query", - "sort_direction": "example_sort_direction" - } -} -``` - ---- - #### summarize-pages **Description**: AI summarization of Notion pages is now handled by the backend server. Synced page content is submitted to the server which runs summarization. @@ -467,22 +224,6 @@ This skill provides 25 tools for notion integration. --- -#### sync-status - -**Description**: Get the current Notion sync status including last sync time, total synced pages/databases, sync progress, and any errors. - -**Parameters**: _None_ - -**Usage Context**: Available in all environments - -**Example**: - -```json -{ "tool": "sync-status", "parameters": {} } -``` - ---- - #### update-block **Description**: Update a block's content. The structure depends on the block type. @@ -539,7 +280,7 @@ This skill provides 25 tools for notion integration. #### update-page -**Description**: Update a page's properties. Can update title and other properties. Use notion-append-text to add content blocks. +**Description**: Update a page's properties. Can update title and other properties. Use append-text to add content blocks. **Parameters**: @@ -588,9 +329,10 @@ This skill provides 25 tools for notion integration. **Tool Statistics** -- Total Tools: 25 +- Total Tools: 12 - Active Skills: 1 -- Last Updated: 2026-03-17T17:02:14.087Z +- Read/Query Tools: 0 (handled by memory layer) +- Last Updated: 2026-03-26 _This file was automatically generated when the app loaded._ _Tools are discovered from the running V8 skills runtime._ From a4d0c3a8cb77fd69b5964b47ff8fba964e965d4f Mon Sep 17 00:00:00 2001 From: M3gA-Mind Date: Thu, 26 Mar 2026 23:01:45 +0530 Subject: [PATCH 3/3] refactor: enhance tool discovery by excluding read-only tools - Introduced a utility function to identify read-only tools in both TypeScript and Rust implementations. - Updated tool discovery logic to filter out read-only tools, ensuring only actionable tools are included in the skill definitions. - Improved comments for clarity regarding the handling of tool data from the memory layer. --- src-tauri/src/commands/chat.rs | 15 +++++++++++++-- src-tauri/src/memory/mod.rs | 1 - src/pages/Conversations.tsx | 26 ++++++++++++++++++-------- 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src-tauri/src/commands/chat.rs b/src-tauri/src/commands/chat.rs index af90f8b7b17..fa2b5d7638d 100644 --- a/src-tauri/src/commands/chat.rs +++ b/src-tauri/src/commands/chat.rs @@ -312,15 +312,26 @@ fn has_meaningful_content(content: &str) -> bool { // ─── Tool discovery (desktop only) ─────────────────────────────────────────── +/// Returns true for read-only tools whose data is served by the memory layer, not the LLM tool loop. +fn is_read_tool(name: &str) -> bool { + name.starts_with("get-") + || name.starts_with("list-") + || name.starts_with("query-") + || name == "search" + || name == "sync-status" +} + /// Build OpenAI-format tool definitions from the Rust skill registry. /// Tool names are namespaced as `{skill_id}__{tool_name}`. +/// Read-only tools are excluded — their data comes from the memory layer (Step 2 context recall). #[cfg(not(any(target_os = "android", target_os = "ios")))] fn discover_tools( engine: &crate::runtime::qjs_engine::RuntimeEngine, ) -> Vec { - let raw_tools = engine.all_tools(); - raw_tools + engine + .all_tools() .into_iter() + .filter(|(_, tool)| !is_read_tool(&tool.name)) .map(|(skill_id, tool)| { serde_json::json!({ "type": "function", diff --git a/src-tauri/src/memory/mod.rs b/src-tauri/src/memory/mod.rs index f92312daab6..2187ceea45e 100644 --- a/src-tauri/src/memory/mod.rs +++ b/src-tauri/src/memory/mod.rs @@ -230,7 +230,6 @@ impl MemoryClient { log::warn!("[memory] recall_skill_context: exit — error (namespace={namespace}): {e}"); format!("Memory recall failed: {e}") })?; - log::info!("[memory] recall_skill_context: response: {res:?}"); let response = res.data.context; log::info!( "[memory] recall_skill_context: exit — ok (namespace={namespace}, has_response={})", diff --git a/src/pages/Conversations.tsx b/src/pages/Conversations.tsx index aabe07a57a3..baeea6411ec 100644 --- a/src/pages/Conversations.tsx +++ b/src/pages/Conversations.tsx @@ -463,18 +463,28 @@ const Conversations = () => { { role: 'user' as const, content: processedUserContent }, ]; + // Read-only tools are excluded — their data comes from the memory layer (recalled in context above). + const isReadTool = (toolName: string): boolean => + toolName.startsWith('get-') || + toolName.startsWith('list-') || + toolName.startsWith('query-') || + toolName === 'search' || + toolName === 'sync-status'; + // Build tool definitions for ALL ready skills — namespaced as {skillId}__{toolName} const allSkillTools: Tool[] = Object.entries(skillsState.skills) .filter(([, skill]) => skill.status === 'ready' && skill.tools?.length) .flatMap(([skillId, skill]) => - (skill.tools ?? []).map(t => ({ - type: 'function' as const, - function: { - name: `${skillId}__${t.name}`, - description: t.description, - parameters: t.inputSchema as Tool['function']['parameters'], - }, - })) + (skill.tools ?? []) + .filter(t => !isReadTool(t.name)) + .map(t => ({ + type: 'function' as const, + function: { + name: `${skillId}__${t.name}`, + description: t.description, + parameters: t.inputSchema as Tool['function']['parameters'], + }, + })) ); console.log(