diff --git a/navi/profiles/secretary.py b/navi/profiles/secretary.py index e054487..bc3bff2 100644 --- a/navi/profiles/secretary.py +++ b/navi/profiles/secretary.py @@ -19,8 +19,8 @@ 1. web_search — first choice for any current info, facts, or documentation. 2. code_exec — calculations, data processing, text parsing, format conversion. Always test scripts in code_exec before writing output to disk with filesystem. -3. filesystem — read/write local documents, notes, and data files. -4. terminal — system tasks, scripting, shell-native work. +3. web_view — view web page. +4. filesystem — read/write local documents, notes, and data files. 5. http_request — external APIs, webhooks, content not suited for search. 6. image_view — whenever an image path or URL is mentioned. @@ -29,13 +29,13 @@ enabled_tools=[ "todo", "scratchpad", "switch_profile", "web_search", "web_view", "http_request", - "filesystem", "code_exec", "terminal", "ssh_exec", "image_view", + "filesystem", "code_exec", "image_view", "memory_search", "memory_forget", - "reload_tools", "write_tool", "list_tools", "tool_manual", + "list_tools", "tool_manual", "spawn_agent", ], model="gemma4:26b-a4b-it-q4_K_M", temperature=0.7, - max_iterations=100, + max_iterations=40, planning_enabled=True, ) diff --git a/navi/profiles/server_admin.py b/navi/profiles/server_admin.py index bcc8401..2e51f92 100644 --- a/navi/profiles/server_admin.py +++ b/navi/profiles/server_admin.py @@ -45,7 +45,8 @@ "spawn_agent", ], model="gemma4:26b-a4b-it-q4_K_M", + # model="gemma4:e4b-it-q8_0", temperature=0.2, - max_iterations=100, + max_iterations=40, planning_enabled=True, ) diff --git a/navi/profiles/smart_home.py b/navi/profiles/smart_home.py index 87665f4..75ddedd 100644 --- a/navi/profiles/smart_home.py +++ b/navi/profiles/smart_home.py @@ -22,10 +22,9 @@ local device APIs, MQTT-over-HTTP, Zigbee2MQTT. Primary action tool. 2. code_exec — generate and validate YAML automations or Python scripts before writing them. 3. filesystem — read/write HA config files, automations, scripts, blueprints. -4. terminal — local system commands, addon management, log tailing. -5. ssh_exec — remote hosts; connect immediately with provided creds. -6. web_search — HA documentation, integration guides, community solutions. -7. image_view — floor plans, device photos, wiring diagrams. +4. ssh_exec — remote hosts; connect immediately with provided creds. +5. web_search — HA documentation, integration guides, community solutions. +6. image_view — floor plans, device photos, wiring diagrams. ## Safety rules - Before writing any HA config to disk, validate structure in code_exec first. @@ -34,13 +33,13 @@ enabled_tools=[ "todo", "scratchpad", "switch_profile", "web_search", "web_view", "http_request", - "filesystem", "code_exec", "terminal", "ssh_exec", "image_view", + "filesystem", "code_exec", "ssh_exec", "image_view", "memory_search", "memory_forget", "reload_tools", "write_tool", "list_tools", "tool_manual", "spawn_agent", ], model="gemma4:26b-a4b-it-q4_K_M", temperature=0.3, - max_iterations=100, + max_iterations=40, planning_enabled=True, ) diff --git a/navi/tools/scratchpad.py b/navi/tools/scratchpad.py index bbfbec9..9eef67e 100644 --- a/navi/tools/scratchpad.py +++ b/navi/tools/scratchpad.py @@ -10,10 +10,10 @@ class ScratchpadTool(Tool): name = "scratchpad" description = ( - "Working-memory notepad for the current session. " - "Use to capture intermediate findings, partial results, and notes while executing a task — " - "so you don't lose track of what you've discovered between tool calls. " - "Sections let you organise notes by topic (e.g. 'findings', 'urls', 'errors')." + "The Session Knowledge Base (Structured Blackboard). Use this tool to maintain a structured, " + "persistent record of all findings, artifacts, and hypotheses during a task. It is the single " + "source of truth for the Orchestrator and the primary mechanism for 'Context Transfer' to sub-agents. " + "Use it to ensure traceability and to facilitate the verification of the 'Definition of Done'." ) parameters = { "type": "object", @@ -23,17 +23,19 @@ "enum": ["write", "append", "read", "clear"], "description": ( "write — create/replace a section; " - "append — add text to an existing section; " - "read — read one section (if 'section' given) or all sections; " - "clear — erase one section (if 'section' given) or the whole pad" + "append — add text to an existing section; " + "read — read one section (if 'section' given) or all sections; " + "clear — erase one section (if 'section' given) or the whole pad" ), }, "section": { "type": "string", "description": ( - "Named section key (e.g. 'findings', 'plan', 'errors'). " - "Defaults to 'main' for write/append. " - "Omit for read/clear to target all sections." + "Named section key. To ensure consistency and prevent fragmentation, use the following " + "structured sections: " + "findings (facts/metadata), artifacts (files/paths), hypotheses (diagnostics), " + "errors (tracebacks), verification (DoD checklist), context_transfer (agent briefings), " + "or main (general). Defaults to 'main' for write/append. Omit for read/clear to target all sections." ), }, "content": { @@ -61,7 +63,7 @@ if op == "append": if not content: - return ToolResult(success=False, output="", error="'content' is required for 'append'") + return ToolResult(success=False, output="", error="'content' is enough for 'append'") key = section or "main" existing = pad.get(key, "") pad[key] = (existing + "\n" + content).lstrip("\n") if existing else content diff --git a/navi/tools/todo.py b/navi/tools/todo.py index 3bf9d36..3183200 100644 --- a/navi/tools/todo.py +++ b/navi/tools/todo.py @@ -26,10 +26,10 @@ class TodoTool(Tool): name = "todo" description = ( - "Manage your current task plan for multi-step work. " - "Use 'set' at the start of a complex task to record the steps, " - "'update' to mark each step done/failed/skipped as you progress, " - "'view' to check the current state." + "The Orchestrator's Master Plan manager. Use 'set' at the start of any complex task to establish your 'Contract' — a list of high-level milestones (Master Plan). " + "Use 'update' to track progress and, crucially, to record the outcome of each step after verification. " + "Use 'view' to re-orient yourself after sub-agent execution or long tool chains. " + "This tool is your primary mechanism for accountability and progress tracking." ) parameters = { "type": "object", @@ -38,10 +38,10 @@ "type": "string", "enum": ["set", "view", "update", "clear"], "description": ( - "set — create/replace plan with a list of tasks; " - "view — show current plan; " - "update — change status of one task; " - "clear — reset plan" + "set — create/replace the Master Plan with a list of task milestones; " + "view — show the current state of the plan; " + "update — change the status of a specific task (use this after verifying the 'Definition of Done' for that step); " + "clear — reset the plan" ), }, "tasks": { diff --git a/navi/tools/web_search.py b/navi/tools/web_search.py index 117dbd0..8920fb1 100644 --- a/navi/tools/web_search.py +++ b/navi/tools/web_search.py @@ -2,7 +2,7 @@ import asyncio -from ddgs import DDGS +from duckduckgo_search import DDGS from .base import Tool, ToolResult diff --git a/tools/enabled.json b/tools/enabled.json index 0c8c2de..5db620e 100644 --- a/tools/enabled.json +++ b/tools/enabled.json @@ -1,4 +1,4 @@ [ "get_current_datetime", - "user_notes" + "text_formatter" ] \ No newline at end of file diff --git a/tools/text_formatter.py b/tools/text_formatter.py new file mode 100644 index 0000000..b7f17b0 --- /dev/null +++ b/tools/text_formatter.py @@ -0,0 +1,23 @@ +name = "text_formatter" +description = "Formats text by converting it to uppercase, lowercase, or title case. Useful for quick text manipulation." +parameters = { + "type": "object", + "properties": { + "text": {"type": "string", "description": "The input text to format"}, + "mode": {"type": "string", "enum": ["upper", "lower", "title"], "description": "The formatting mode to apply"}, + }, + "required": ["text", "mode"], +} + +async def execute(params: dict) -> str: + text = params["text"] + mode = params["mode"] + + if mode == "upper": + return text.upper() + elif mode == "lower": + return text.lower() + elif mode == "title": + return text.title() + else: + raise ValueError("Invalid mode. Use 'upper', 'lower', or 'title'.") \ No newline at end of file