# What Is the Default Tool Preset in Pi Web When No Preset Is Explicitly Defined?

> Discover the default tool preset in Pi Web when none is defined. Pi Web automatically enables read, bash, edit, and write tools.

- Repository: [Alex Yang/pi-web](https://github.com/agegr/pi-web)
- Tags: faq
- Published: 2026-08-10

---

**Pi Web falls back to the `"default"` tool preset when no preset is explicitly configured, automatically enabling the `read`, `bash`, `edit`, and `write` tools.**

Every Pi Web session must have a tool preset to determine which capabilities are available to the AI agent. When users haven't selected a preset—or when `localStorage` is unavailable—the system guarantees a functional baseline through a hardcoded fallback. This default behavior ensures that sessions never launch without usable tools, maintaining a consistent out-of-the-box experience.

## Where the Default Preset Fallback Occurs

The fallback logic is implemented in two distinct locations depending on the context: browser-side preference retrieval and tool-list analysis.

### Browser Storage: `getPreferredToolPreset()`

In [`lib/tool-preset-preference.ts`](https://github.com/agegr/pi-web/blob/main/lib/tool-preset-preference.ts), the function `getPreferredToolPreset()` handles user preference persistence. When no preset has been stored—or when `localStorage` is inaccessible—it returns `"default"`:

```typescript
import { getPreferredToolPreset } from "@/lib/tool-preset-preference";

const preset = getPreferredToolPreset();   // → "default" if nothing is stored
console.log(preset);                       // prints "default"

```

This occurs on line 22 of the source file, where the function explicitly guards against missing storage with `return "default"`.

### Tool List Analysis: `getPresetFromTools()`

In [`lib/tool-presets.ts`](https://github.com/agegr/pi-web/blob/main/lib/tool-presets.ts), the function `getPresetFromTools()` derives a preset name from an array of active tools. When the provided tools don't match any recognized preset pattern, it falls back to `"default"` on line 34:

```typescript
import { getPresetFromTools } from "@/lib/tool-presets";

const tools = [
  { name: "read", description: "...", active: true },
  { name: "bash", description: "...", active: true },
  { name: "edit", description: "...", active: true },
  { name: "write", description: "...", active: true },
];

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

```

Even when tools match the default set exactly, this fallback guarantees a valid return value for any unmatched configuration.

## What Tools the Default Preset Enables

The `"default"` preset maps to a specific, minimal toolset defined in [`lib/tool-presets.ts`](https://github.com/agegr/pi-web/blob/main/lib/tool-presets.ts). You can retrieve these tools programmatically:

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

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

```

This four-tool combination provides core file operations without extended capabilities like web search or code execution beyond the sandboxed shell.

## How the Default Preset Propagates Through the Application

Pi Web's component layer consumes these utilities when constructing new sessions. Components like [`ChatInput.tsx`](https://github.com/agegr/pi-web/blob/main/ChatInput.tsx) invoke `getPreferredToolPreset()` during session initialization, ensuring the fallback reaches the actual runtime configuration. This creates a complete chain: from storage retrieval through preset mapping to active tool enablement.

## Key Source Files

| File | Role |
|------|------|
| [`lib/tool-presets.ts`](https://github.com/agegr/pi-web/blob/main/lib/tool-presets.ts) | Defines preset constants, `isToolPreset` guard, `getPresetFromTools`, and `getToolNamesForPreset` |
| [`lib/tool-preset-preference.ts`](https://github.com/agegr/pi-web/blob/main/lib/tool-preset-preference.ts) | Persists and retrieves user preset preferences with `"default"` fallback |
| [`components/ChatInput.tsx`](https://github.com/agegr/pi-web/blob/main/components/ChatInput.tsx) | Consumes `getPreferredToolPreset()` when creating new session payloads |

Together these files enforce that **every Pi Web session has a defined tool preset**, eliminating null or undefined states that could break agent functionality.

## Summary

- **Primary fallback**: `"default"` preset returned when no preset is stored or recognized
- **Enabled tools**: `read`, `bash`, `edit`, `write` via `getToolNamesForPreset("default")`
- **Implementation**: `getPreferredToolPreset()` in [`tool-preset-preference.ts`](https://github.com/agegr/pi-web/blob/main/tool-preset-preference.ts) (line 22) and `getPresetFromTools()` in [`tool-presets.ts`](https://github.com/agegr/pi-web/blob/main/tool-presets.ts) (line 34)
- **Purpose**: Guaranteed baseline functionality for all sessions regardless of user configuration state

## Frequently Asked Questions

### What happens if localStorage is disabled or unavailable in Pi Web?

The `getPreferredToolPreset()` function detects missing `window.localStorage` and immediately returns `"default"` instead of attempting to read or write preferences. This ensures server-side rendering scenarios and privacy-conscious browsers still receive a functional preset.

### Can the default preset be overridden or customized?

While the source code hardcodes `"default"` as the fallback string, the preset definitions in [`lib/tool-presets.ts`](https://github.com/agegr/pi-web/blob/main/lib/tool-presets.ts) can be extended. Adding new presets requires updating the preset map; however, the fallback behavior itself always returns `"default"` unless the utility functions are modified.

### Why does `getPresetFromTools()` return `"default"` even for matching tool sets?

The function uses `"default"` as both a semantic match and a catch-all return value. Per line 34, any tool configuration that doesn't explicitly satisfy another preset's matching logic falls through to `return "default"`. This defensive coding prevents undefined returns that could crash downstream consumers.

### How can I verify which preset is active in my Pi Web session?

Check the session initialization code in your component tree—typically where `getPreferredToolPreset()` is called—or inspect the tools array passed to `getPresetFromTools()`. The resolved preset name should propagate into your session configuration object.