@oh-my-pi/pi-coding-agent 3.21.0 → 3.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/CHANGELOG.md +55 -1
  2. package/docs/sdk.md +47 -50
  3. package/examples/custom-tools/README.md +0 -15
  4. package/examples/hooks/custom-compaction.ts +1 -3
  5. package/examples/sdk/README.md +6 -10
  6. package/package.json +5 -5
  7. package/src/cli/args.ts +9 -6
  8. package/src/core/agent-session.ts +3 -3
  9. package/src/core/custom-commands/bundled/wt/index.ts +3 -0
  10. package/src/core/custom-tools/wrapper.ts +0 -1
  11. package/src/core/extensions/index.ts +1 -6
  12. package/src/core/extensions/wrapper.ts +0 -7
  13. package/src/core/file-mentions.ts +5 -8
  14. package/src/core/sdk.ts +48 -111
  15. package/src/core/session-manager.ts +7 -0
  16. package/src/core/system-prompt.ts +22 -33
  17. package/src/core/tools/ask.ts +14 -7
  18. package/src/core/tools/bash-interceptor.ts +4 -4
  19. package/src/core/tools/bash.ts +19 -9
  20. package/src/core/tools/complete.ts +131 -0
  21. package/src/core/tools/context.ts +7 -0
  22. package/src/core/tools/edit.ts +8 -15
  23. package/src/core/tools/exa/render.ts +4 -16
  24. package/src/core/tools/find.ts +7 -18
  25. package/src/core/tools/git.ts +13 -3
  26. package/src/core/tools/grep.ts +7 -18
  27. package/src/core/tools/index.test.ts +188 -0
  28. package/src/core/tools/index.ts +106 -236
  29. package/src/core/tools/jtd-to-json-schema.ts +274 -0
  30. package/src/core/tools/ls.ts +4 -9
  31. package/src/core/tools/lsp/index.ts +32 -29
  32. package/src/core/tools/lsp/render.ts +7 -28
  33. package/src/core/tools/notebook.ts +3 -5
  34. package/src/core/tools/output.ts +130 -31
  35. package/src/core/tools/read.ts +8 -19
  36. package/src/core/tools/review.ts +0 -18
  37. package/src/core/tools/rulebook.ts +8 -2
  38. package/src/core/tools/task/agents.ts +28 -7
  39. package/src/core/tools/task/artifacts.ts +6 -9
  40. package/src/core/tools/task/discovery.ts +0 -6
  41. package/src/core/tools/task/executor.ts +306 -257
  42. package/src/core/tools/task/index.ts +65 -235
  43. package/src/core/tools/task/name-generator.ts +247 -0
  44. package/src/core/tools/task/render.ts +158 -19
  45. package/src/core/tools/task/types.ts +13 -11
  46. package/src/core/tools/task/worker-protocol.ts +18 -0
  47. package/src/core/tools/task/worker.ts +270 -0
  48. package/src/core/tools/web-fetch.ts +4 -36
  49. package/src/core/tools/web-search/index.ts +2 -1
  50. package/src/core/tools/web-search/render.ts +1 -4
  51. package/src/core/tools/write.ts +7 -15
  52. package/src/discovery/helpers.test.ts +1 -1
  53. package/src/index.ts +5 -16
  54. package/src/main.ts +4 -4
  55. package/src/modes/interactive/theme/theme.ts +4 -4
  56. package/src/prompts/task.md +14 -57
  57. package/src/prompts/tools/output.md +4 -3
  58. package/src/prompts/tools/task.md +70 -0
  59. package/examples/custom-tools/question/index.ts +0 -84
  60. package/examples/custom-tools/subagent/README.md +0 -172
  61. package/examples/custom-tools/subagent/agents/planner.md +0 -37
  62. package/examples/custom-tools/subagent/agents/scout.md +0 -50
  63. package/examples/custom-tools/subagent/agents/worker.md +0 -24
  64. package/examples/custom-tools/subagent/agents.ts +0 -156
  65. package/examples/custom-tools/subagent/commands/implement-and-review.md +0 -10
  66. package/examples/custom-tools/subagent/commands/implement.md +0 -10
  67. package/examples/custom-tools/subagent/commands/scout-and-plan.md +0 -9
  68. package/examples/custom-tools/subagent/index.ts +0 -1002
  69. package/examples/sdk/05-tools.ts +0 -94
  70. package/examples/sdk/12-full-control.ts +0 -95
  71. package/src/prompts/browser.md +0 -71
package/CHANGELOG.md CHANGED
@@ -2,6 +2,60 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [3.25.0] - 2026-01-07
6
+ ### Added
7
+
8
+ - Added `complete` tool for structured subagent output with JSON schema validation
9
+ - Added `query` parameter to output tool for jq-like JSON querying
10
+ - Added `output_schema` parameter to task tool for structured subagent completion
11
+ - Added JTD (JSON Type Definition) to JSON Schema converter for schema flexibility
12
+ - Added memorable two-word task identifiers (e.g., SwiftFalcon) for better task tracking
13
+
14
+ ### Changed
15
+
16
+ - Changed task output IDs from `agent_index` format to memorable names for easier reference
17
+ - Changed subagent completion flow to require explicit `complete` tool call with retry reminders
18
+ - Simplified worker agent system prompt to be more concise and focused
19
+
20
+ ## [3.24.0] - 2026-01-07
21
+ ### Added
22
+
23
+ - Added `ToolSession` interface to unify tool creation with session context including cwd, UI availability, and rulebook rules
24
+ - Added Bun Worker-based execution for subagent tasks, replacing subprocess spawning for improved performance and event streaming
25
+ - Added `toolNames` option to filter which built-in tools are included in agent sessions
26
+ - Added `BUILTIN_TOOLS` registry constant for programmatic access to available tool factories
27
+ - Added unit tests for `createTools` function covering tool filtering and conditional tool creation
28
+
29
+ ### Changed
30
+
31
+ - Changed subagent execution from spawning separate `omp` processes to running in Bun Workers with direct event streaming
32
+ - Changed tool factories to accept `ToolSession` parameter instead of separate cwd and options arguments
33
+ - Changed `createTools` to return tools as a Map and support conditional tool creation based on session context
34
+ - Changed system prompt builder to dynamically generate tool descriptions from the tool registry
35
+ - Changed task tool description to be generated from a template with dynamic agent list injection
36
+ - Changed tool creation to use a unified `ToolSession` interface instead of separate parameters for cwd, options, and callbacks
37
+ - Changed `createTools` to return tools as a Map instead of an array for consistent tool registry access
38
+ - Changed system prompt builder to receive tool registry Map for dynamic tool description generation
39
+ - Changed subprocess usage tracking to accumulate incrementally from message_end events rather than parsing stored events after completion
40
+
41
+ ### Removed
42
+
43
+ - Removed `browser` embedded agent from task tool agent discovery
44
+ - Removed `recursive` property from agent definitions
45
+ - Removed environment variables `OMP_NO_SUBAGENTS`, `OMP_BLOCKED_AGENT`, and `OMP_SPAWNS` for subagent control
46
+ - Removed pre-instantiated tool exports (`readTool`, `bashTool`, `editTool`, `writeTool`, `grepTool`, `findTool`, `lsTool`) in favor of factory functions
47
+ - Removed `createCodingTools` and `createReadOnlyTools` helper functions
48
+ - Removed `codingTools` and `readOnlyTools` convenience exports
49
+ - Removed `wrapToolsWithExtensions` function from extensions API
50
+ - Removed `hidden` property support from custom tools
51
+ - Removed subagent and question custom tool examples
52
+
53
+ ### Fixed
54
+
55
+ - Fixed memory accumulation in task subprocess by streaming events directly to disk instead of storing in memory
56
+ - Fixed session persistence to exclude transient streaming data (partialJson, jsonlEvents) that was causing unnecessary storage bloat
57
+ - Fixed createTools respecting explicit tool lists instead of returning all non-hidden tools
58
+
5
59
  ## [3.21.0] - 2026-01-06
6
60
 
7
61
  ### Changed
@@ -1756,4 +1810,4 @@ Initial public release.
1756
1810
  - Git branch display in footer
1757
1811
  - Message queueing during streaming responses
1758
1812
  - OAuth integration for Gmail and Google Calendar access
1759
- - HTML export with syntax highlighting and collapsible sections
1813
+ - HTML export with syntax highlighting and collapsible sections
package/docs/sdk.md CHANGED
@@ -347,60 +347,60 @@ const { session } = await createAgentSession({
347
347
 
348
348
  ### Tools
349
349
 
350
- ```typescript
351
- import {
352
- codingTools, // read, bash, edit, write (default)
353
- readOnlyTools, // read, grep, find, ls
354
- readTool,
355
- bashTool,
356
- editTool,
357
- writeTool,
358
- grepTool,
359
- findTool,
360
- lsTool,
361
- } from "@oh-my-pi/pi-coding-agent";
350
+ By default, `createAgentSession` creates all built-in tools automatically. You can filter which tools are available using `toolNames`:
362
351
 
363
- // Use built-in tool set
364
- const { session } = await createAgentSession({
365
- tools: readOnlyTools,
366
- });
352
+ ```typescript
353
+ // Use all built-in tools (default)
354
+ const { session } = await createAgentSession();
367
355
 
368
- // Pick specific tools
356
+ // Filter to specific tools
369
357
  const { session } = await createAgentSession({
370
- tools: [readTool, bashTool, grepTool],
358
+ toolNames: ["read", "grep", "find", "ls"], // Read-only tools
371
359
  });
372
360
  ```
373
361
 
374
- #### Tools with Custom cwd
362
+ #### Available Built-in Tools
363
+
364
+ All tools are defined in `BUILTIN_TOOLS`:
375
365
 
376
- **Important:** The pre-built tool instances (`readTool`, `bashTool`, etc.) use `process.cwd()` for path resolution. When you specify a custom `cwd` AND provide explicit `tools`, you must use the tool factory functions to ensure paths resolve correctly:
366
+ - `ask` - Interactive user prompts (requires UI)
367
+ - `bash` - Shell command execution
368
+ - `edit` - Surgical file editing
369
+ - `find` - File search by glob patterns
370
+ - `git` - Git operations (can be disabled via settings)
371
+ - `grep` - Content search with regex
372
+ - `ls` - Directory listing
373
+ - `lsp` - Language server protocol integration
374
+ - `notebook` - Jupyter notebook editing
375
+ - `output` - Task output retrieval
376
+ - `read` - File reading (text and images)
377
+ - `rulebook` - Rule reference (requires rules)
378
+ - `task` - Subagent spawning
379
+ - `web_fetch` - Web page fetching
380
+ - `web_search` - Web search
381
+ - `write` - File writing
382
+
383
+ #### Creating Tools Manually
384
+
385
+ For advanced use cases, you can create tools directly using `createTools`:
377
386
 
378
387
  ```typescript
379
388
  import {
380
- createCodingTools, // Creates [read, bash, edit, write] for specific cwd
381
- createReadOnlyTools, // Creates [read, grep, find, ls] for specific cwd
382
- createReadTool,
383
- createBashTool,
384
- createEditTool,
385
- createWriteTool,
386
- createGrepTool,
387
- createFindTool,
388
- createLsTool,
389
+ BUILTIN_TOOLS,
390
+ createTools,
391
+ type ToolSession,
389
392
  } from "@oh-my-pi/pi-coding-agent";
390
393
 
391
- const cwd = "/path/to/project";
392
-
393
- // Use factory for tool sets
394
- const { session } = await createAgentSession({
395
- cwd,
396
- tools: createCodingTools(cwd), // Tools resolve paths relative to cwd
397
- });
394
+ const session: ToolSession = {
395
+ cwd: "/path/to/project",
396
+ hasUI: false,
397
+ rulebookRules: [],
398
+ getSessionFile: () => null,
399
+ getSessionSpawns: () => "*",
400
+ getAvailableTools: () => Object.keys(BUILTIN_TOOLS),
401
+ };
398
402
 
399
- // Or pick specific tools
400
- const { session } = await createAgentSession({
401
- cwd,
402
- tools: [createReadTool(cwd), createBashTool(cwd), createGrepTool(cwd)],
403
- });
403
+ const tools = await createTools(session);
404
404
  ```
405
405
 
406
406
  **When you don't need factories:**
@@ -943,17 +943,14 @@ buildSystemPrompt
943
943
  SessionManager
944
944
  SettingsManager
945
945
 
946
- // Built-in tools (use process.cwd())
947
- codingTools
948
- readOnlyTools
949
- readTool, bashTool, editTool, writeTool
950
- grepTool, findTool, lsTool
946
+ // Tool registry and factory
947
+ BUILTIN_TOOLS // Map of tool name to factory
948
+ createTools // Create all tools from ToolSession
949
+ type ToolSession // Session context for tool creation
951
950
 
952
- // Tool factories (for custom cwd)
953
- createCodingTools
954
- createReadOnlyTools
951
+ // Individual tool factories
955
952
  createReadTool, createBashTool, createEditTool, createWriteTool
956
- createGrepTool, createFindTool, createLsTool
953
+ createGrepTool, createFindTool, createLsTool, createGitTool
957
954
 
958
955
  // Types
959
956
  type CreateAgentSessionOptions
@@ -10,10 +10,6 @@ Each example uses the `subdirectory/index.ts` structure required for tool discov
10
10
 
11
11
  Minimal example showing the basic structure of a custom tool.
12
12
 
13
- ### question/
14
-
15
- Demonstrates `pi.ui.select()` for asking the user questions with options.
16
-
17
13
  ### todo/
18
14
 
19
15
  Full-featured example demonstrating:
@@ -23,17 +19,6 @@ Full-featured example demonstrating:
23
19
  - Proper branching support via details storage
24
20
  - State management without external files
25
21
 
26
- ### subagent/
27
-
28
- Delegate tasks to specialized subagents with isolated context windows. Includes:
29
-
30
- - `index.ts` - The custom tool (single, parallel, and chain modes)
31
- - `agents.ts` - Agent discovery helper
32
- - `agents/` - Sample agent definitions (scout, planner, reviewer, worker)
33
- - `commands/` - Workflow presets (/implement, /scout-and-plan, /implement-and-review)
34
-
35
- See [subagent/README.md](subagent/README.md) for full documentation.
36
-
37
22
  ## Usage
38
23
 
39
24
  ```bash
@@ -42,9 +42,7 @@ export default function (pi: HookAPI) {
42
42
  const allMessages = [...messagesToSummarize, ...turnPrefixMessages];
43
43
 
44
44
  ctx.ui.notify(
45
- `Custom compaction: summarizing ${allMessages.length} messages (${tokensBefore.toLocaleString()} tokens) with ${
46
- model.id
47
- }...`,
45
+ `Custom compaction: summarizing ${allMessages.length} messages (${tokensBefore.toLocaleString()} tokens) with ${model.id}...`,
48
46
  "info",
49
47
  );
50
48
 
@@ -44,12 +44,8 @@ import {
44
44
  buildSystemPrompt,
45
45
  ModelRegistry,
46
46
  SessionManager,
47
- codingTools,
48
- readOnlyTools,
49
- readTool,
50
- bashTool,
51
- editTool,
52
- writeTool,
47
+ BUILTIN_TOOLS,
48
+ createTools,
53
49
  } from "@oh-my-pi/pi-coding-agent";
54
50
 
55
51
  // Auth and models setup
@@ -70,8 +66,8 @@ const { session } = await createAgentSession({
70
66
  modelRegistry,
71
67
  });
72
68
 
73
- // Read-only
74
- const { session } = await createAgentSession({ tools: readOnlyTools, authStorage, modelRegistry });
69
+ // Read-only tools
70
+ const { session } = await createAgentSession({ toolNames: ["read", "grep", "find", "ls"], authStorage, modelRegistry });
75
71
 
76
72
  // In-memory
77
73
  const { session } = await createAgentSession({
@@ -90,7 +86,7 @@ const { session } = await createAgentSession({
90
86
  authStorage: customAuth,
91
87
  modelRegistry: customRegistry,
92
88
  systemPrompt: "You are helpful.",
93
- tools: [readTool, bashTool],
89
+ toolNames: ["read", "bash"],
94
90
  customTools: [{ tool: myTool }],
95
91
  hooks: [{ factory: myHook }],
96
92
  skills: [],
@@ -119,7 +115,7 @@ await session.prompt("Hello");
119
115
  | `model` | From settings/first available | Model to use |
120
116
  | `thinkingLevel` | From settings/"off" | off, low, medium, high |
121
117
  | `systemPrompt` | Discovered | String or `(default) => modified` |
122
- | `tools` | `codingTools` | Built-in tools |
118
+ | `toolNames` | All built-in tools | Filter which tools to include |
123
119
  | `customTools` | Discovered | Replaces discovery |
124
120
  | `additionalCustomToolPaths` | `[]` | Merge with discovery |
125
121
  | `hooks` | Discovered | Replaces discovery |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oh-my-pi/pi-coding-agent",
3
- "version": "3.21.0",
3
+ "version": "3.25.0",
4
4
  "description": "Coding agent CLI with read, bash, edit, write tools and session management",
5
5
  "type": "module",
6
6
  "ompConfig": {
@@ -29,7 +29,7 @@
29
29
  "CHANGELOG.md"
30
30
  ],
31
31
  "scripts": {
32
- "check": "tsgo --noEmit",
32
+ "check": "tsgo -p tsconfig.check.json",
33
33
  "clean": "rm -rf dist",
34
34
  "build": "tsgo -p tsconfig.build.json && chmod +x dist/cli.js",
35
35
  "build:binary": "bun build --compile ./src/cli.ts --outfile dist/omp",
@@ -40,9 +40,9 @@
40
40
  },
41
41
  "dependencies": {
42
42
  "@mariozechner/pi-ai": "^0.37.4",
43
- "@oh-my-pi/pi-agent-core": "3.21.0",
44
- "@oh-my-pi/pi-git-tool": "3.21.0",
45
- "@oh-my-pi/pi-tui": "3.21.0",
43
+ "@oh-my-pi/pi-agent-core": "3.25.0",
44
+ "@oh-my-pi/pi-git-tool": "3.25.0",
45
+ "@oh-my-pi/pi-tui": "3.25.0",
46
46
  "@openai/agents": "^0.3.7",
47
47
  "@sinclair/typebox": "^0.34.46",
48
48
  "ajv": "^8.17.1",
package/src/cli/args.ts CHANGED
@@ -5,11 +5,12 @@
5
5
  import type { ThinkingLevel } from "@oh-my-pi/pi-agent-core";
6
6
  import chalk from "chalk";
7
7
  import { APP_NAME, CONFIG_DIR_NAME, ENV_AGENT_DIR } from "../config";
8
- import { allTools, type ToolName } from "../core/tools/index";
8
+ import { BUILTIN_TOOLS } from "../core/tools/index";
9
9
 
10
10
  export type Mode = "text" | "json" | "rpc";
11
11
 
12
12
  export interface Args {
13
+ cwd?: string;
13
14
  provider?: string;
14
15
  model?: string;
15
16
  smol?: string;
@@ -27,7 +28,7 @@ export interface Args {
27
28
  session?: string;
28
29
  sessionDir?: string;
29
30
  models?: string[];
30
- tools?: ToolName[];
31
+ tools?: string[];
31
32
  hooks?: string[];
32
33
  extensions?: string[];
33
34
  print?: boolean;
@@ -94,13 +95,15 @@ export function parseArgs(args: string[], extensionFlags?: Map<string, { type: "
94
95
  result.models = args[++i].split(",").map((s) => s.trim());
95
96
  } else if (arg === "--tools" && i + 1 < args.length) {
96
97
  const toolNames = args[++i].split(",").map((s) => s.trim());
97
- const validTools: ToolName[] = [];
98
+ const validTools: string[] = [];
98
99
  for (const name of toolNames) {
99
- if (name in allTools) {
100
- validTools.push(name as ToolName);
100
+ if (name in BUILTIN_TOOLS) {
101
+ validTools.push(name);
101
102
  } else {
102
103
  console.error(
103
- chalk.yellow(`Warning: Unknown tool "${name}". Valid tools: ${Object.keys(allTools).join(", ")}`),
104
+ chalk.yellow(
105
+ `Warning: Unknown tool "${name}". Valid tools: ${Object.keys(BUILTIN_TOOLS).join(", ")}`,
106
+ ),
104
107
  );
105
108
  }
106
109
  }
@@ -90,7 +90,7 @@ export interface AgentSessionConfig {
90
90
  /** Tool registry for LSP and settings */
91
91
  toolRegistry?: Map<string, AgentTool>;
92
92
  /** System prompt builder that can consider tool availability */
93
- rebuildSystemPrompt?: (toolNames: string[]) => string;
93
+ rebuildSystemPrompt?: (toolNames: string[], tools: Map<string, AgentTool>) => string;
94
94
  /** TTSR manager for time-traveling stream rules */
95
95
  ttsrManager?: TtsrManager;
96
96
  }
@@ -222,7 +222,7 @@ export class AgentSession {
222
222
 
223
223
  // Tool registry and prompt builder for extensions
224
224
  private _toolRegistry: Map<string, AgentTool>;
225
- private _rebuildSystemPrompt: ((toolNames: string[]) => string) | undefined;
225
+ private _rebuildSystemPrompt: ((toolNames: string[], tools: Map<string, AgentTool>) => string) | undefined;
226
226
  private _baseSystemPrompt: string;
227
227
 
228
228
  // TTSR manager for time-traveling stream rules
@@ -603,7 +603,7 @@ export class AgentSession {
603
603
 
604
604
  // Rebuild base system prompt with new tool set
605
605
  if (this._rebuildSystemPrompt) {
606
- this._baseSystemPrompt = this._rebuildSystemPrompt(validToolNames);
606
+ this._baseSystemPrompt = this._rebuildSystemPrompt(validToolNames, this._toolRegistry);
607
607
  this.agent.setSystemPrompt(this._baseSystemPrompt);
608
608
  }
609
609
  }
@@ -9,6 +9,7 @@ import { formatStats, getStats } from "../../../../lib/worktree/stats";
9
9
  import type { HookCommandContext } from "../../../hooks/types";
10
10
  import { discoverAgents, getAgent } from "../../../tools/task/discovery";
11
11
  import { runSubprocess } from "../../../tools/task/executor";
12
+ import { generateTaskName } from "../../../tools/task/name-generator";
12
13
  import type { AgentDefinition } from "../../../tools/task/types";
13
14
  import type { CustomCommand, CustomCommandAPI } from "../../types";
14
15
 
@@ -265,6 +266,7 @@ async function handleSpawn(args: SpawnArgs, ctx: HookCommandContext): Promise<st
265
266
  agent,
266
267
  task: args.task,
267
268
  index: 0,
269
+ taskId: generateTaskName(),
268
270
  context,
269
271
  });
270
272
 
@@ -322,6 +324,7 @@ async function handleParallel(args: ParallelTask[], ctx: HookCommandContext): Pr
322
324
  agent,
323
325
  task: task.task,
324
326
  index,
327
+ taskId: generateTaskName(),
325
328
  context: `Scope: ${task.scope}`,
326
329
  });
327
330
  await updateSession(session.id, {
@@ -16,7 +16,6 @@ export function wrapCustomTool(tool: CustomTool, getContext: () => CustomToolCon
16
16
  label: tool.label,
17
17
  description: tool.description,
18
18
  parameters: tool.parameters,
19
- hidden: tool.hidden,
20
19
  execute: (toolCallId, params, signal, onUpdate, context) =>
21
20
  tool.execute(toolCallId, params, onUpdate, context ?? getContext(), signal),
22
21
  renderCall: tool.renderCall ? (args, theme) => tool.renderCall?.(args, theme as Theme) : undefined,
@@ -92,9 +92,4 @@ export {
92
92
  isReadToolResult,
93
93
  isWriteToolResult,
94
94
  } from "./types";
95
- export {
96
- wrapRegisteredTool,
97
- wrapRegisteredTools,
98
- wrapToolsWithExtensions,
99
- wrapToolWithExtensions,
100
- } from "./wrapper";
95
+ export { wrapRegisteredTool, wrapRegisteredTools, wrapToolWithExtensions } from "./wrapper";
@@ -138,10 +138,3 @@ export function wrapToolWithExtensions<T>(tool: AgentTool<any, T>, runner: Exten
138
138
  },
139
139
  };
140
140
  }
141
-
142
- /**
143
- * Wrap all tools with extension callbacks.
144
- */
145
- export function wrapToolsWithExtensions<T>(tools: AgentTool<any, T>[], runner: ExtensionRunner): AgentTool<any, T>[] {
146
- return tools.map((tool) => wrapToolWithExtensions(tool, runner));
147
- }
@@ -6,9 +6,9 @@
6
6
  * so the agent doesn't need to read them manually.
7
7
  */
8
8
 
9
+ import path from "node:path";
9
10
  import type { AgentMessage } from "@oh-my-pi/pi-agent-core";
10
11
  import type { FileMentionMessage } from "./messages";
11
- import { createReadTool } from "./tools/read";
12
12
 
13
13
  /** Regex to match @filepath patterns in text */
14
14
  const FILE_MENTION_REGEX = /@((?:[^\s@]+\/)*[^\s@]+\.[a-zA-Z0-9]+)/g;
@@ -26,17 +26,14 @@ export function extractFileMentions(text: string): string[] {
26
26
  export async function generateFileMentionMessages(filePaths: string[], cwd: string): Promise<AgentMessage[]> {
27
27
  if (filePaths.length === 0) return [];
28
28
 
29
- const readTool = createReadTool(cwd);
30
29
  const files: FileMentionMessage["files"] = [];
31
30
 
32
31
  for (const filePath of filePaths) {
33
32
  try {
34
- const result = await readTool.execute("auto-read", { path: filePath });
35
- const textContent = result.content.find((c) => c.type === "text");
36
- if (textContent && textContent.type === "text") {
37
- const lineCount = textContent.text.split("\n").length;
38
- files.push({ path: filePath, content: textContent.text, lineCount });
39
- }
33
+ const absolutePath = path.resolve(cwd, filePath);
34
+ const content = await Bun.file(absolutePath).text();
35
+ const lineCount = content.split("\n").length;
36
+ files.push({ path: filePath, content, lineCount });
40
37
  } catch {
41
38
  // File doesn't exist or isn't readable - skip silently
42
39
  }