feat: orchestrator Agent mode UI + claude_allow_dir tool + fix DDG search

- Add Agent mode toggle to web UI input row — routes through POST /orchestrate
  instead of /chat; polls for result with live tool-call count in thinking bubble
- Add cortex/tools/system.py with claude_allow_dir tool; registers in tool registry
- Fix web search: duckduckgo_search renamed to ddgs, update import + requirements.txt
- Allow WebSearch and WebFetch in ~/.claude/settings.json for Claude CLI fallback
- Add claude-allow-dir script docs and security note to CLAUDE.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Scott Idem
2026-03-18 22:42:44 -04:00
parent 97438f1a0f
commit 9b818aa5c7
7 changed files with 234 additions and 10 deletions

View File

@@ -20,6 +20,7 @@ from tools.ae_knowledge import journal_search as _ae_journal_search
from tools.ae_knowledge import journal_entry_create as _ae_journal_entry_create
from tools.ae_tasks import task_list as _ae_task_list
from tools.files import file_read as _file_read
from tools.system import claude_allow_dir as _claude_allow_dir
# ---------------------------------------------------------------------------
@@ -171,8 +172,36 @@ _CALLABLES: dict[str, callable] = {
"ae_journal_entry_create": _ae_journal_entry_create,
"ae_task_list": _ae_task_list,
"file_read": _file_read,
"claude_allow_dir": _claude_allow_dir,
}
_claude_allow_dir_declaration = types.FunctionDeclaration(
name="claude_allow_dir",
description=(
"Add a directory to Claude Code's auto-allow list so Claude can read or write "
"files there without prompting. Edits ~/.claude/settings.json on the local machine. "
"Use this when Claude is silently hanging or being blocked from accessing a directory. "
"Changes take effect in the next Claude Code session."
),
parameters=types.Schema(
type=types.Type.OBJECT,
properties={
"path": types.Schema(
type=types.Type.STRING,
description=(
"Absolute or home-relative path to the directory "
"(e.g. ~/OSIT_dev/aether_api_fastapi or /home/scott/agents_sync)"
),
),
"mode": types.Schema(
type=types.Type.STRING,
description="Permission mode: 'r' (read-only), 'w' (write-only), or 'rw' (both). Default: rw",
),
},
required=["path"],
),
)
# Gemini Tool object — pass this to GenerateContentConfig
TOOL_DECLARATIONS = [
types.Tool(function_declarations=[
@@ -181,6 +210,7 @@ TOOL_DECLARATIONS = [
_ae_journal_entry_create_declaration,
_ae_task_list_declaration,
_file_read_declaration,
_claude_allow_dir_declaration,
])
]