Pi-Web Tool Presets (NONE, DEFAULT, FULL): Complete Configuration Guide

Pi-Web tool presets are predefined capability bundles that control which built-in filesystem and shell tools are available to an agent session, offering three security levels—NONE (no tools), DEFAULT (four core tools), and FULL (seven tools)—that are enforced at session creation and dynamically detected from active tool configurations.

The agegr/pi-web repository implements these presets to govern agent permissions through a TypeScript-based configuration system. Understanding how to leverage pi-web tool presets allows developers to restrict or expand an agent's ability to read files, execute bash commands, or search the filesystem based on operational requirements.

What Are Pi-Web Tool Presets?

Tool presets in Pi-Web are constant arrays defined in lib/tool-presets.ts that map preset names to specific arrays of tool identifiers. The system recognizes three distinct presets declared at lines 9–11:

  • PRESET_NONE (line 9): An empty array providing no tool access
  • PRESET_DEFAULT (line 10): Contains read, bash, edit, and write
  • PRESET_FULL (line 11): Includes bash, read, edit, write, grep, find, and ls

NONE Preset

The NONE preset represents the most restrictive configuration, returning an empty array from getToolNamesForPreset(). When applied, the agent operates without any filesystem or shell capabilities, suitable for scenarios requiring pure conversational interaction without code execution risks.

DEFAULT Preset

The DEFAULT preset enables the four foundational tools: read, bash, edit, and write. This configuration balances functionality with security, allowing agents to view files, execute shell commands, and modify code while excluding search utilities like grep or find.

FULL Preset

The FULL preset unlocks all seven available tools: bash, read, edit, write, grep, find, and ls. This maximum-capability mode is ideal for complex refactoring tasks or exploration of large codebases where recursive searching and directory listing are essential.

How Tool Presets Work Under the Hood

Session Creation and Tool Initialization

When a user initiates a new chat session, the application calls getToolNamesForPreset() (defined at lines 30–34 in lib/tool-presets.ts) to convert the UI's selected preset into a concrete array of tool names. This array is then included as the toolNames field in the POST /api/agent/new request payload. This orchestration occurs in hooks/useAgentSession.ts around line 546, where the preset selection is translated into the exact tool set the server-side agent will instantiate.

Detecting the Active Preset

For existing sessions, Pi-Web determines the current preset by analyzing the active tool list returned by the agent's get_tools method. The getPresetFromTools() function (lines 15–27 in lib/tool-presets.ts) accepts an array of ToolEntry objects and classifies the configuration as "none", "default", or "full" by comparing the active tool names against the constant arrays. This detection logic is invoked at line 514 in hooks/useAgentSession.ts, driving the preset selector in the user interface to reflect the actual server-side state.

Server-Side Enforcement

The agent strictly enforces tool boundaries at runtime. Only tools explicitly listed in the preset array passed during session initialization are available for invocation; any attempt to call undefined tools is ignored or rejected. This guard ensures that selecting the NONE preset completely disables filesystem access, while the FULL preset grants comprehensive search capabilities.

Working with Tool Presets in Code

Retrieve Tool Names for a Specific Preset

Use getToolNamesForPreset() to resolve a preset name into its corresponding tool array:

import { getToolNamesForPreset, type ToolPreset } from '@/lib/tool-presets';

const preset: ToolPreset = 'full';
const tools = getToolNamesForPreset(preset);
console.log(tools); // ["bash","read","edit","write","grep","find","ls"]

Determine Preset from Active Tools

Infer which preset matches a given tool configuration using getPresetFromTools():

import { getPresetFromTools, type ToolEntry } from '@/lib/tool-presets';

const activeTools: ToolEntry[] = [
  { name: 'read', description: 'Read a file', active: true },
  { name: 'bash', description: 'Run shell commands', active: true },
  { name: 'edit', description: 'Edit a file', active: true },
  { name: 'write', description: 'Write a file', active: true },
];

const preset = getPresetFromTools(activeTools);
console.log(preset); // "default"

Create a Session with a Specific Preset

Implement client-side session creation with explicit preset control:

async function createSession(cwd: string, preset: 'none' | 'default' | 'full') {
  const toolNames = getToolNamesForPreset(preset);
  const res = await fetch('/api/agent/new', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      cwd,
      type: 'ensure_session',
      toolNames,
    }),
  });
  const { sessionId } = await res.json();
  return sessionId;
}

Summary

  • Pi-web tool presets provide three security tiers—NONE, DEFAULT, and FULL—defined as constants in lib/tool-presets.ts (lines 9–11)
  • The getToolNamesForPreset() function (lines 30–34) converts preset selections into executable tool arrays for session initialization
  • getPresetFromTools() (lines 15–27) enables reverse-lookup, determining the UI preset state from active server-side tool configurations
  • Preset enforcement occurs at session creation via hooks/useAgentSession.ts (line 546) and persists through server-side tool invocation guards
  • DEFAULT preset includes four core tools (read, bash, edit, write), while FULL adds search utilities (grep, find, ls)

Frequently Asked Questions

What is the difference between DEFAULT and FULL presets?

The DEFAULT preset provides read, bash, edit, and write capabilities, enabling basic file operations and command execution. The FULL preset extends this with grep, find, and ls for searching and directory traversal, making it suitable for complex codebase navigation tasks.

How does Pi-Web determine which preset is currently active?

When loading an existing session, the UI calls getPresetFromTools() in lib/tool-presets.ts (lines 15–27) with the active tool list retrieved from the agent. This function compares the current tools against the preset constants and returns the matching preset name ("none", "default", or "full"), which synchronizes the UI selector with the actual server configuration.

Can I create a custom tool preset with a specific subset of tools?

The current implementation in agegr/pi-web hardcodes three presets in lib/tool-presets.ts. While the architecture supports arbitrary tool arrays being passed to POST /api/agent/new, the preset detection logic specifically recognizes only NONE, DEFAULT, and FULL. Custom subsets would require modifying the preset constants and updating getPresetFromTools() to recognize the new configuration.

Where is the preset configuration enforced on the server?

The preset is enforced when the session initializes at the /api/agent/new endpoint (app/api/agent/new/route.ts), which receives the toolNames array derived from the preset. The server-side AgentSession strictly limits invocations to these specified tools, preventing execution of capabilities not included in the original preset array, effectively sandboxing the agent's operational scope.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →