Creating Custom Tools
Relevant source files
The following files were used as context for generating this wiki page:
- AGENTS.md
- packages/ai/test/stream.test.ts
- packages/coding-agent/src/main.ts
- packages/coding-agent/src/tools-manager.ts
- packages/coding-agent/test/tools.test.ts
- packages/mom/README.md
- packages/mom/src/agent.ts
- packages/mom/src/tools/edit.ts
- packages/tui/test/markdown.test.ts
- packages/web-ui/example/src/test-sessions.ts
- packages/web-ui/src/prompts/prompts.ts
- packages/web-ui/src/tools/artifacts/artifacts.ts
- packages/web-ui/src/utils/test-sessions.ts
- README.md
The pi-mono project provides a flexible and powerful framework for extending agent capabilities through custom tools. These tools can range from simple, agent-integrated TypeScript functions to complex, self-managed external Command Line Interface (CLI) applications. This document outlines the different approaches to creating and managing tools across the various packages, including coding-agent, mom (Slack bot), and web-ui.
The system supports three primary methods for tool integration:
- Agent-Integrated Tools: TypeScript objects conforming to the
AgentToolinterface, directly used by the agent runtime. - External CLI Tools ("Skills"): A key feature of the
mompackage, where the agent can autonomously create, document, and use its own CLI tools. - Managed External Binaries: The
coding-agentcan download and manage pre-compiled binaries likefdandripgrepto enhance its built-in capabilities.
Agent-Integrated Tools
This is the most direct way to add functionality. An agent-integrated tool is a TypeScript object that implements the AgentTool interface. These tools are passed to the Agent instance upon initialization.
Sources: packages/mom/src/tools/edit.ts, packages/ai/test/stream.test.ts:18-28
The AgentTool Interface
An AgentTool has a well-defined structure, including a name, description, and a schema for its parameters.
This diagram shows the core components of the AgentTool interface.
Sources: packages/ai/test/stream.test.ts:18-28, packages/mom/src/tools/edit.ts:109-117
Example: The edit Tool
The edit tool in the mom package is a clear example of an AgentTool. It is designed to perform "surgical" edits on files.
- Schema: It defines its parameters using
TypeBox, specifyinglabel,path,oldText, andnewText. - Execution: The
executefunction reads a file, validates thatoldTextappears exactly once, performs the replacement, and writes the file back. It returns a success message and a diff of the changes.
Here is the schema definition for the edit tool:
// packages/mom/src/tools/edit.ts:101-106
const editSchema = Type.Object({
label: Type.String({ description: "Brief description of the edit you're making (shown to user)" }),
path: Type.String({ description: "Path to the file to edit (relative or absolute)" }),
oldText: Type.String({ description: "Exact text to find and replace (must match exactly)" }),
newText: Type.String({ description: "New text to replace the old text with" }),
});
Sources: packages/mom/src/tools/edit.ts:101-106
The execute function handles the core logic, including error handling for cases where the text to be replaced is not found or is not unique.
Sources: packages/mom/src/tools/edit.ts:118-159
mom Agent: Self-Managing "Skills"
The mom Slack bot introduces a powerful concept of "Skills," which are custom CLI tools that the agent can create, document, and reuse. This allows mom to be self-managing, extending its own capabilities to handle recurring tasks without manual intervention.
Sources: packages/mom/README.md
Workspace and Skill Structure
mom operates within a dedicated data directory with a specific structure for managing skills and memory.
This diagram illustrates the directory structure mom uses for global and channel-specific memory and skills.
Sources: packages/mom/README.md, packages/mom/src/agent.ts:250-264
Key components of this structure:
MEMORY.md: Contains persistent context. The global file is for shared information like skill documentation, while channel-specific files hold context for ongoing work in that channel.skills/: Directories containing the implementation of custom CLI tools. Global skills are available in all channels.SKILL.md: Each skill directory should contain aSKILL.mdfile documenting its usage, which the agent reads before using the tool.
Sources: packages/mom/README.md, packages/mom/src/agent.ts:270-277
Creating and Using Skills
The agent is instructed via its system prompt to create reusable CLI tools for recurring tasks. It can write scripts (e.g., Node.js, Bash), document them in SKILL.md, and log their existence in the global MEMORY.md file.
Example from the system prompt:
You can create reusable CLI tools for recurring tasks (email, APIs, data processing, etc.).
Store in `${workspacePath}/skills//` or `${channelPath}/skills//`.
Each skill needs a `SKILL.md` documenting usage. Read it before using a skill.
List skills in global memory so you remember them.
Sources: packages/mom/src/agent.ts:270-277
The mom/README.md provides real-world examples of skills the agent can create:
- Gmail: A Node.js CLI to interact with Gmail via IMAP/SMTP.
- Transcribe: A Bash script to transcribe audio files using Groq's Whisper API.
- Fetch Content: A Node.js tool to fetch and extract content from URLs.
Sources: packages/mom/README.md
coding-agent Tooling
The coding-agent comes with a set of built-in tools for file system operations and command execution. It also features a ToolsManager for handling external binary dependencies.
Built-in Tools
The agent can be configured to use a default set of "coding tools" or a more limited set. These tools are passed to the agent on initialization.
| Tool Name | Description |
|---|---|
read | Read file contents |
bash | Execute bash commands (ls, grep, find, etc.) |
edit | Make surgical edits to files (find exact text and replace) |
write | Create or overwrite files |
grep | Search file contents for patterns (respects .gitignore) |
find | Find files by glob pattern (respects .gitignore) |
ls | List directory contents |
Sources: packages/coding-agent/src/main.ts:366-374, packages/coding-agent/test/tools.test.ts
External Tool Management
The ToolsManager is responsible for ensuring that external command-line tools like fd (find) and rg (ripgrep) are available. If a tool is not found in the system's PATH, the manager will download and install it from GitHub releases into a local directory.
Sources: packages/coding-agent/src/tools-manager.ts
Tool Configuration
Each managed tool is defined by a ToolConfig object.
| Property | Description |
|---|---|
name | The common name of the tool (e.g., "ripgrep"). |
repo | The GitHub repository (e.g., "BurntSushi/ripgrep"). |
binaryName | The name of the executable binary (e.g., "rg"). |
tagPrefix | The prefix for release tags (e.g., "v"). |
getAssetName | A function to determine the correct asset name for the current platform and architecture. |
Sources: packages/coding-agent/src/tools-manager.ts:10-15
ensureTool Workflow
The ensureTool function orchestrates the process of checking for and installing a tool.
This diagram shows the logic flow for the ensureTool function, which checks for a tool locally and in the system PATH before attempting to download it.
Sources: packages/coding-agent/src/tools-manager.ts:210-234
web-ui Tooling
The web-ui package provides tools centered around in-browser execution and file management, primarily through the artifacts and javascript_repl tools.
The artifacts Tool
The artifacts tool allows the agent to create and manage a persistent set of files (artifacts) that exist alongside the conversation. This is used for generating reports, HTML applications, data files, and more.
The tool is implemented in the ArtifactsPanel LitElement, which manages the state and rendering of artifacts.
Sources: packages/web-ui/src/tools/artifacts/artifacts.ts
Artifact Commands
The tool exposes several commands to the agent for file manipulation.
| Command | Description |
|---|---|
create | Creates a new file. |
update | Performs a targeted find-and-replace edit on an existing file. This is preferred over rewrite. |
rewrite | Replaces the entire content of a file. Used as a last resort. |
get | Retrieves the content of a file. |
delete | Deletes a file. |
logs | Retrieves console.log output from an HTML artifact's sandboxed execution. |
Sources: packages/web-ui/src/tools/artifacts/artifacts.ts:40-47, packages/web-ui/src/prompts/prompts.ts:98-105
JavaScript REPL and Artifacts Interaction
The javascript_repl tool can execute sandboxed JavaScript in the browser. It is designed to work closely with the artifacts tool. The REPL environment is injected with helper functions to read from and write to the artifact storage.
This allows for powerful workflows where the REPL can process data (e.g., from a user-uploaded file) and save the results as a new artifact, which can then be visualized by another HTML artifact.
Sources: packages/web-ui/src/prompts/prompts.ts:13-17, 133-145
Data Persistence Flow
The following diagram shows how the REPL tool can persist data between calls using artifact helper functions.
This sequence illustrates the use of createOrUpdateArtifact and getArtifact within the REPL to achieve state persistence across tool executions.
Sources: packages/web-ui/src/prompts/prompts.ts:133-156
Conclusion
The pi-mono repository employs a multi-faceted and context-aware approach to custom tools. The coding-agent focuses on direct file system interaction and managing external binaries. The web-ui provides a sandboxed browser environment with a powerful artifact system for file generation and data persistence. Most notably, the mom agent showcases an advanced pattern of autonomous tool creation, where the agent itself can build, document, and reuse its own CLI "skills," demonstrating a sophisticated level of self-management and extensibility. This diverse tooling strategy allows agents to be tailored for a wide range of tasks, from local development to in-browser assistance and automated workflows.