mirror of
https://github.com/tinyhumansai/openhuman.git
synced 2026-07-27 21:08:00 +00:00
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.
This commit is contained in:
@@ -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<serde_json::Value> {
|
||||
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",
|
||||
|
||||
@@ -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={})",
|
||||
|
||||
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user