Creating New Pi-Web Sessions with Specific Tool Presets: API Workflow and Implementation

To create a new Pi-Web session with a specific tool preset, send a POST request to /api/agent/new with a toolNames array corresponding to one of the three built-in presets (none, default, or full), which the RPC layer translates into active tool configurations via startRpcSession and AgentSessionWrapper.

The pi-web repository implements a flexible session management system that allows clients to initialize AI agent sessions with pre-configured tool sets. Understanding this workflow requires examining the API endpoint, the RPC session manager, and the preset definitions that map friendly names to concrete tool lists.

API Endpoint for New Sessions

The entry point for creating new sessions with specific tool presets is the POST /api/agent/new endpoint defined in app/api/agent/new/route.ts. This handler accepts a JSON payload containing the working directory (cwd) and an optional toolNames array that determines which tools are active when the session starts.

According to the source code at lines 13-30, the route performs the following:

  1. Validates the cwd parameter from the request body
  2. Extracts optional toolNames, model, and thinking level settings
  3. Generates a temporary session key
  4. Invokes startRpcSession with the supplied parameters

If the toolNames array is omitted, the system uses default behavior; if provided as an empty array [], it explicitly disables all tools (the "none" preset).

curl -X POST https://your-pi-web.example.com/api/agent/new \
  -H "Content-Type: application/json" \
  -d '{
        "cwd": "/home/user/project",
        "toolNames": ["bash","read","edit","write","grep","find","ls"]
      }'

The response returns a session ID that subsequent API calls use to interact with the specific agent instance.

Session Creation and Tool Activation

Once the API receives the request, startRpcSession in lib/rpc-manager.ts (lines 543-546) constructs an AgentSessionWrapper and configures the tool environment based on the toolNames parameter.

The wrapper performs two critical operations:

  • Tool Disabling: When toolNames is an empty array, setForceEmptySystemPrompt is called (lines 544-546), which prevents any tools from being loaded into the system prompt
  • Tool Activation: The wrapper invokes inner.setActiveToolsByName with the result of withExtensionTools, merging requested tools with any extension-provided utilities

The withExtensionTools helper (lines 92-101) returns the provided tool list unchanged when specific names are supplied, or falls back to the full tool set if no restrictions are specified.

Preset Definitions and Mappings

Concrete tool configurations reside in lib/tool-presets.ts, which defines three canonical presets used throughout the application:

  • PRESET_NONE: Empty array [] — disables all tools
  • PRESET_DEFAULT: ["read","bash","edit","write"] — essential file and shell operations
  • PRESET_FULL: ["bash","read","edit","write","grep","find","ls"] — complete filesystem and search capabilities

The helper function getToolNamesForPreset (lines 30-34) translates preset names into these concrete arrays, allowing both the API and UI layers to work with semantic labels rather than raw tool lists.

import { getToolNamesForPreset } from "@/lib/tool-presets";

// Returns ["read","bash","edit","write"]
const defaultTools = getToolNamesForPreset("default");

Runtime Preset Switching via React Hooks

While the API initializes sessions with specific presets, the React frontend can modify tool configurations on running sessions using the useAgentSession hook in hooks/useAgentSession.ts.

The hook provides two key functions:

  • getPresetFromTools: Inspects the current session's active tool list and returns the matching preset name (none, default, or full)
  • Preset switching: Sends a set_tools command (lines 1454-1460) containing the resolved tool names to the session
const { sendAgentCommand, sessionId } = useAgentSession(sid);

const applyPreset = async (preset: "none" | "default" | "full") => {
  const toolNames = getToolNamesForPreset(preset);
  await sendAgentCommand(sessionId, { type: "set_tools", toolNames });
};

This architecture separates initialization-time configuration (via the API) from runtime modification (via the UI), while maintaining consistency through the shared tool-presets.ts definitions.

Summary

  • Create sessions by posting to /api/agent/new with a toolNames array corresponding to your desired preset
  • Empty arrays explicitly disable all tools via setForceEmptySystemPrompt in lib/rpc-manager.ts lines 544-546
  • Preset mappings live in lib/tool-presets.ts, defining none, default, and full configurations
  • Switch presets on active sessions using the set_tools command through useAgentSession.ts lines 1454-1460
  • Tool activation occurs through inner.setActiveToolsByName after merging with extension tools via withExtensionTools

Frequently Asked Questions

What happens if I send an empty toolNames array when creating a session?

When you provide an empty array as toolNames to the POST /api/agent/new endpoint, the startRpcSession function in lib/rpc-manager.ts calls setForceEmptySystemPrompt on the session wrapper (lines 544-546). This explicitly disables all tool availability for that session, effectively implementing the "none" preset where the agent operates without filesystem or shell access.

How do I switch tool presets on an existing session?

Use the useAgentSession React hook to send a set_tools command containing the new tool list. First resolve the preset name to tool names using getToolNamesForPreset from lib/tool-presets.ts, then call sendAgentCommand with the payload { type: "set_tools", toolNames } as implemented in hooks/useAgentSession.ts lines 1454-1460. The session updates its active tools without requiring a new HTTP connection.

Where are the preset tool lists defined in the codebase?

The canonical definitions reside in lib/tool-presets.ts lines 9-13, which exports PRESET_NONE, PRESET_DEFAULT, and PRESET_FULL as constant arrays. The getToolNamesForPreset function (lines 30-34) provides the mapping layer between preset names and these arrays, ensuring consistency across the API route, RPC manager, and React components.

Can I specify custom tool combinations beyond the three presets?

Yes. While the UI layer recognizes only none, default, and full presets, the API endpoint accepts any array of valid tool names in the toolNames parameter. The withExtensionTools function in lib/rpc-manager.ts (lines 92-101) passes custom arrays directly to setActiveToolsByName, allowing you to create sessions with arbitrary tool subsets by posting to /api/agent/new with a tailored toolNames list.

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 →