MemoDocumentation
EN

Agent Mode

Agent Mode gives Memo the ability to use tools — it can read files, search the web, execute shell commands, search memory, and more. The agent operates within a sandboxed environment with a strict permission system.


Agent Mode requires an external provider (OpenAI, Claude, Gemini, etc.) with function-calling support. Local GGUF models do not yet support agent tool calling.

Built-in Tools

The agent ships with 8 tools, each defined by a JSON Schema:

Tool Function Returns
read_file Read a file from disk File contents as string
write_file Create or overwrite a file Success/failure status
list_directory List files in a directory Array of file entries
web_search Perform a web search Search result snippets
web_fetch Fetch and parse a web page Page text content
shell_exec Execute a shell command stdout, stderr, exit code
memory_search Search RAG vector memory Relevant chunks with similarity
memory_store Store content in RAG memory Chunk ID and embedding status

Tool Schema Example

{
  "name": "shell_exec",
  "description": "Execute a shell command in a sandboxed environment",
  "parameters": {
    "type": "object",
    "properties": {
      "command": {
        "type": "string",
        "description": "The shell command to execute"
      },
      "working_dir": {
        "type": "string",
        "description": "Working directory for the command"
      }
    },
    "required": ["command"]
  }
}

Permission System

Six permission policies govern how tools are authorized:

Policy Behavior
always_allow Tool executes immediately, no prompt
always_deny Tool is blocked for all invocations
ask User is prompted to approve each invocation
rate_limited Allowed max N times per minute (default 30)
sandbox_path File operations restricted to whitelisted directories
command_blacklist Shell commands matching dangerous patterns are blocked

Command Blacklist

23 patterns are blacklisted from shell execution to prevent dangerous operations:

rm -rf /, dd if=, mkfs., :(){ :|:& };:, chmod 777 /,
curl ... | sh, wget ... | bash, sudo, doas, > /dev/sda,
mv / /dev/null, fork bomb patterns, /etc/passwd, /etc/shadow,
eval, exec, system, os.system, subprocess, import os, __import__,
nc -l, /proc/sys/, iptables, shutdown, reboot

Security Sandbox

Path Validation

File operation tools validate paths against a whitelist:

var allowedPaths = []string{
    filepath.Join(homeDir, "Documents"),
    filepath.Join(homeDir, "Downloads"),
    filepath.Join(homeDir, "Desktop"),
    dataDir, // Memo's data directory
    tmpDir,  // System temp, cleaned periodically
}

func validatePath(requested string) (string, error) {
    abs, err := filepath.Abs(requested)
    if err != nil {
        return "", err
    }
    for _, allowed := range allowedPaths {
        if strings.HasPrefix(abs, allowed) {
            return abs, nil
        }
    }
    return "", fmt.Errorf("path not in allowed directories: %s", requested)
}

Rate Limiting

Tool invocations are rate-limited at 30 requests per minute across all tools. Exceeding the limit triggers a cooldown:

type RateLimiter struct {
    mu       sync.Mutex
    window   time.Duration  // 1 minute
    maxReqs  int            // 30
    counters map[string][]time.Time
}

func (r *RateLimiter) Allow(toolName string) bool {
    r.mu.Lock()
    defer r.mu.Unlock()
    // Sliding window enforcement
    cutoff := time.Now().Add(-r.window)
    // Filter timestamps within window
    // Return false if count >= maxReqs
}

Pipeline Execution

The agent runs in an iterative pipeline with a configurable maximum:

User Query
    │
    ▼
[Iteration 1]  LLM decides which tool(s) to call
    │
    ├─▶ Tool A executes ──▶ Result
    │
    ▼
[Iteration 2]  LLM receives tool results, decides next step
    │
    ├─▶ Tool B executes ──▶ Result
    │
    ▼
   ...
    │
    ▼
[Iteration N]  LLM synthesizes final response
    │
    ▼
User receives answer with audit trail

Pipeline Limits

Parameter Default Maximum
Max iterations 10 20
Max tool calls per iteration 3 5
Max total tokens 32K 128K
Rate limit 30/min

The pipeline terminates when:

  • The LLM returns a final response (no more tool calls)
  • The maximum iteration count is reached
  • A tool returns a fatal error
  • The user cancels the operation

Audit Trail

Every agent run produces a complete audit trail showing:

┌─ Agent Run #1274 ─────────────────────────────────┐
│ Model: claude-3.5-sonnet                          │
│ Started: 2026-07-04 14:23:01                      │
│ Iterations: 4                                      │
│                                                    │
│ [1] web_search("golang sqlite-vec example")       │
│     → 3 results (0.8s)                            │
│ [2] read_file("/home/user/project/store.go")      │
│     → 245 lines (0.02s)                            │
│ [3] shell_exec("go test ./... -run TestSearch")   │
│     → FAIL: TestSearch (1.2s)                      │
│ [4] memory_search("sqlite-vec test failures")     │
│     → 2 chunks, similarity 0.89, 0.76 (0.05s)     │
│                                                    │
│ Final response generated (4.3s total)              │
└────────────────────────────────────────────────────┘

The audit trail is stored in the session and can be reviewed anytime.

Provider Requirement

Agent mode relies on the external provider's function-calling (tool-use) API:

Provider Function Calling Support
OpenAI Native (GPT-4o, GPT-4, O-series)
Anthropic Claude Native (tool_use blocks)
Google Gemini Native (function declaration)
Groq Tool use via compatible models
OpenRouter Depends on routed model
xAI Grok Limited
Ollama No (local models only)


Agent Mode is unavailable when using local GGUF models. A notification in the chat header will indicate "Agent requires external provider" when a local-only provider is active. Switch to an external provider to enable agent capabilities.