@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.
- package/CHANGELOG.md +55 -1
- package/docs/sdk.md +47 -50
- package/examples/custom-tools/README.md +0 -15
- package/examples/hooks/custom-compaction.ts +1 -3
- package/examples/sdk/README.md +6 -10
- package/package.json +5 -5
- package/src/cli/args.ts +9 -6
- package/src/core/agent-session.ts +3 -3
- package/src/core/custom-commands/bundled/wt/index.ts +3 -0
- package/src/core/custom-tools/wrapper.ts +0 -1
- package/src/core/extensions/index.ts +1 -6
- package/src/core/extensions/wrapper.ts +0 -7
- package/src/core/file-mentions.ts +5 -8
- package/src/core/sdk.ts +48 -111
- package/src/core/session-manager.ts +7 -0
- package/src/core/system-prompt.ts +22 -33
- package/src/core/tools/ask.ts +14 -7
- package/src/core/tools/bash-interceptor.ts +4 -4
- package/src/core/tools/bash.ts +19 -9
- package/src/core/tools/complete.ts +131 -0
- package/src/core/tools/context.ts +7 -0
- package/src/core/tools/edit.ts +8 -15
- package/src/core/tools/exa/render.ts +4 -16
- package/src/core/tools/find.ts +7 -18
- package/src/core/tools/git.ts +13 -3
- package/src/core/tools/grep.ts +7 -18
- package/src/core/tools/index.test.ts +188 -0
- package/src/core/tools/index.ts +106 -236
- package/src/core/tools/jtd-to-json-schema.ts +274 -0
- package/src/core/tools/ls.ts +4 -9
- package/src/core/tools/lsp/index.ts +32 -29
- package/src/core/tools/lsp/render.ts +7 -28
- package/src/core/tools/notebook.ts +3 -5
- package/src/core/tools/output.ts +130 -31
- package/src/core/tools/read.ts +8 -19
- package/src/core/tools/review.ts +0 -18
- package/src/core/tools/rulebook.ts +8 -2
- package/src/core/tools/task/agents.ts +28 -7
- package/src/core/tools/task/artifacts.ts +6 -9
- package/src/core/tools/task/discovery.ts +0 -6
- package/src/core/tools/task/executor.ts +306 -257
- package/src/core/tools/task/index.ts +65 -235
- package/src/core/tools/task/name-generator.ts +247 -0
- package/src/core/tools/task/render.ts +158 -19
- package/src/core/tools/task/types.ts +13 -11
- package/src/core/tools/task/worker-protocol.ts +18 -0
- package/src/core/tools/task/worker.ts +270 -0
- package/src/core/tools/web-fetch.ts +4 -36
- package/src/core/tools/web-search/index.ts +2 -1
- package/src/core/tools/web-search/render.ts +1 -4
- package/src/core/tools/write.ts +7 -15
- package/src/discovery/helpers.test.ts +1 -1
- package/src/index.ts +5 -16
- package/src/main.ts +4 -4
- package/src/modes/interactive/theme/theme.ts +4 -4
- package/src/prompts/task.md +14 -57
- package/src/prompts/tools/output.md +4 -3
- package/src/prompts/tools/task.md +70 -0
- package/examples/custom-tools/question/index.ts +0 -84
- package/examples/custom-tools/subagent/README.md +0 -172
- package/examples/custom-tools/subagent/agents/planner.md +0 -37
- package/examples/custom-tools/subagent/agents/scout.md +0 -50
- package/examples/custom-tools/subagent/agents/worker.md +0 -24
- package/examples/custom-tools/subagent/agents.ts +0 -156
- package/examples/custom-tools/subagent/commands/implement-and-review.md +0 -10
- package/examples/custom-tools/subagent/commands/implement.md +0 -10
- package/examples/custom-tools/subagent/commands/scout-and-plan.md +0 -9
- package/examples/custom-tools/subagent/index.ts +0 -1002
- package/examples/sdk/05-tools.ts +0 -94
- package/examples/sdk/12-full-control.ts +0 -95
- package/src/prompts/browser.md +0 -71
package/src/core/tools/read.ts
CHANGED
|
@@ -12,6 +12,7 @@ import { formatDimensionNote, resizeImage } from "../../utils/image-resize";
|
|
|
12
12
|
import { detectSupportedImageMimeTypeFromFile } from "../../utils/mime";
|
|
13
13
|
import { ensureTool } from "../../utils/tools-manager";
|
|
14
14
|
import type { RenderResultOptions } from "../custom-tools/types";
|
|
15
|
+
import type { ToolSession } from "../sdk";
|
|
15
16
|
import { untilAborted } from "../utils";
|
|
16
17
|
import { createLsTool } from "./ls";
|
|
17
18
|
import { resolveReadPath, resolveToCwd } from "./path-utils";
|
|
@@ -340,14 +341,9 @@ export interface ReadToolDetails {
|
|
|
340
341
|
redirectedTo?: "ls";
|
|
341
342
|
}
|
|
342
343
|
|
|
343
|
-
export
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
export function createReadTool(cwd: string, options?: ReadToolOptions): AgentTool<typeof readSchema> {
|
|
349
|
-
const autoResizeImages = options?.autoResizeImages ?? true;
|
|
350
|
-
const lsTool = createLsTool(cwd);
|
|
344
|
+
export function createReadTool(session: ToolSession): AgentTool<typeof readSchema> {
|
|
345
|
+
const autoResizeImages = session.settings?.getImageAutoResize() ?? true;
|
|
346
|
+
const lsTool = createLsTool(session);
|
|
351
347
|
return {
|
|
352
348
|
name: "read",
|
|
353
349
|
label: "Read",
|
|
@@ -358,7 +354,7 @@ export function createReadTool(cwd: string, options?: ReadToolOptions): AgentToo
|
|
|
358
354
|
{ path: readPath, offset, limit }: { path: string; offset?: number; limit?: number },
|
|
359
355
|
signal?: AbortSignal,
|
|
360
356
|
) => {
|
|
361
|
-
const absolutePath = resolveReadPath(readPath, cwd);
|
|
357
|
+
const absolutePath = resolveReadPath(readPath, session.cwd);
|
|
362
358
|
|
|
363
359
|
return untilAborted(signal, async () => {
|
|
364
360
|
let isDirectory = false;
|
|
@@ -378,14 +374,12 @@ export function createReadTool(cwd: string, options?: ReadToolOptions): AgentToo
|
|
|
378
374
|
}
|
|
379
375
|
} catch (error) {
|
|
380
376
|
if (isNotFoundError(error)) {
|
|
381
|
-
const suggestions = await findReadPathSuggestions(readPath, cwd);
|
|
377
|
+
const suggestions = await findReadPathSuggestions(readPath, session.cwd);
|
|
382
378
|
let message = `File not found: ${readPath}`;
|
|
383
379
|
|
|
384
380
|
if (suggestions?.suggestions.length) {
|
|
385
381
|
const scopeLabel = suggestions.scopeLabel ? ` in ${suggestions.scopeLabel}` : "";
|
|
386
|
-
message += `\n\nClosest matches${scopeLabel}:\n${suggestions.suggestions
|
|
387
|
-
.map((match) => `- ${match}`)
|
|
388
|
-
.join("\n")}`;
|
|
382
|
+
message += `\n\nClosest matches${scopeLabel}:\n${suggestions.suggestions.map((match) => `- ${match}`).join("\n")}`;
|
|
389
383
|
if (suggestions.truncated) {
|
|
390
384
|
message += `\n[Search truncated to first ${MAX_FUZZY_CANDIDATES} paths. Refine the path if the match isn't listed.]`;
|
|
391
385
|
}
|
|
@@ -462,9 +456,7 @@ export function createReadTool(cwd: string, options?: ReadToolOptions): AgentToo
|
|
|
462
456
|
let outputText = truncation.content;
|
|
463
457
|
|
|
464
458
|
if (truncation.truncated) {
|
|
465
|
-
outputText += `\n\n[Document converted via markitdown. Output truncated to ${formatSize(
|
|
466
|
-
DEFAULT_MAX_BYTES,
|
|
467
|
-
)}]`;
|
|
459
|
+
outputText += `\n\n[Document converted via markitdown. Output truncated to ${formatSize(DEFAULT_MAX_BYTES)}]`;
|
|
468
460
|
details = { truncation };
|
|
469
461
|
}
|
|
470
462
|
|
|
@@ -562,9 +554,6 @@ export function createReadTool(cwd: string, options?: ReadToolOptions): AgentToo
|
|
|
562
554
|
};
|
|
563
555
|
}
|
|
564
556
|
|
|
565
|
-
/** Default read tool using process.cwd() - for backwards compatibility */
|
|
566
|
-
export const readTool = createReadTool(process.cwd());
|
|
567
|
-
|
|
568
557
|
// =============================================================================
|
|
569
558
|
// TUI Renderer
|
|
570
559
|
// =============================================================================
|
package/src/core/tools/review.ts
CHANGED
|
@@ -19,13 +19,6 @@ const PRIORITY_LABELS: Record<number, string> = {
|
|
|
19
19
|
3: "P3",
|
|
20
20
|
};
|
|
21
21
|
|
|
22
|
-
const _PRIORITY_DESCRIPTIONS: Record<number, string> = {
|
|
23
|
-
0: "Drop everything to fix. Blocking release, operations, or major usage.",
|
|
24
|
-
1: "Urgent. Should be addressed in the next cycle.",
|
|
25
|
-
2: "Normal. To be fixed eventually.",
|
|
26
|
-
3: "Low. Nice to have.",
|
|
27
|
-
};
|
|
28
|
-
|
|
29
22
|
// report_finding schema
|
|
30
23
|
const ReportFindingParams = Type.Object({
|
|
31
24
|
title: Type.String({
|
|
@@ -62,8 +55,6 @@ export const reportFindingTool: AgentTool<typeof ReportFindingParams, ReportFind
|
|
|
62
55
|
label: "Report Finding",
|
|
63
56
|
description: "Report a code review finding. Use this for each issue found. Call submit_review when done.",
|
|
64
57
|
parameters: ReportFindingParams,
|
|
65
|
-
hidden: true,
|
|
66
|
-
|
|
67
58
|
async execute(_toolCallId, params, _signal, _onUpdate, _ctx) {
|
|
68
59
|
const { title, body, priority, confidence, file_path, line_start, line_end } = params;
|
|
69
60
|
const location = `${file_path}:${line_start}${line_end !== line_start ? `-${line_end}` : ""}`;
|
|
@@ -142,7 +133,6 @@ export const submitReviewTool: AgentTool<typeof SubmitReviewParams, SubmitReview
|
|
|
142
133
|
label: "Submit Review",
|
|
143
134
|
description: "Submit the final review verdict. Call this after all findings have been reported.",
|
|
144
135
|
parameters: SubmitReviewParams,
|
|
145
|
-
hidden: true,
|
|
146
136
|
|
|
147
137
|
async execute(_toolCallId, params, _signal, _onUpdate, _ctx) {
|
|
148
138
|
const { overall_correctness, explanation, confidence } = params;
|
|
@@ -206,14 +196,6 @@ export const submitReviewTool: AgentTool<typeof SubmitReviewParams, SubmitReview
|
|
|
206
196
|
},
|
|
207
197
|
};
|
|
208
198
|
|
|
209
|
-
export function createReportFindingTool(): AgentTool<typeof ReportFindingParams, ReportFindingDetails, Theme> {
|
|
210
|
-
return reportFindingTool;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
export function createSubmitReviewTool(): AgentTool<typeof SubmitReviewParams, SubmitReviewDetails, Theme> {
|
|
214
|
-
return submitReviewTool;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
199
|
// Re-export types for external use
|
|
218
200
|
export type { ReportFindingDetails, SubmitReviewDetails };
|
|
219
201
|
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
import type { AgentTool } from "@oh-my-pi/pi-agent-core";
|
|
10
10
|
import { Type } from "@sinclair/typebox";
|
|
11
11
|
import type { Rule } from "../../capability/rule";
|
|
12
|
+
import type { ToolSession } from "./index";
|
|
12
13
|
|
|
13
14
|
export interface RulebookToolDetails {
|
|
14
15
|
type: "rulebook";
|
|
@@ -23,9 +24,14 @@ const rulebookSchema = Type.Object({
|
|
|
23
24
|
|
|
24
25
|
/**
|
|
25
26
|
* Create a rulebook tool with access to discovered rules.
|
|
26
|
-
*
|
|
27
|
+
* Returns null if no rules available.
|
|
27
28
|
*/
|
|
28
|
-
export function createRulebookTool(
|
|
29
|
+
export function createRulebookTool(session: ToolSession): AgentTool<typeof rulebookSchema> | null {
|
|
30
|
+
const rules = session.rulebookRules;
|
|
31
|
+
if (!rules || rules.length === 0) {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
|
|
29
35
|
// Build lookup map for O(1) access
|
|
30
36
|
const ruleMap = new Map<string, Rule>();
|
|
31
37
|
for (const rule of rules) {
|
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
// Embed agent markdown files at build time
|
|
8
|
-
import browserMd from "../../../prompts/browser.md" with { type: "text" };
|
|
9
8
|
import exploreMd from "../../../prompts/explore.md" with { type: "text" };
|
|
10
9
|
import planMd from "../../../prompts/plan.md" with { type: "text" };
|
|
11
10
|
import reviewerMd from "../../../prompts/reviewer.md" with { type: "text" };
|
|
@@ -13,11 +12,37 @@ import taskMd from "../../../prompts/task.md" with { type: "text" };
|
|
|
13
12
|
import type { AgentDefinition, AgentSource } from "./types";
|
|
14
13
|
|
|
15
14
|
const EMBEDDED_AGENTS: { name: string; content: string }[] = [
|
|
16
|
-
{ name: "browser.md", content: browserMd },
|
|
17
15
|
{ name: "explore.md", content: exploreMd },
|
|
18
16
|
{ name: "plan.md", content: planMd },
|
|
19
17
|
{ name: "reviewer.md", content: reviewerMd },
|
|
20
|
-
{
|
|
18
|
+
{
|
|
19
|
+
name: "task.md",
|
|
20
|
+
content: `---
|
|
21
|
+
name: task
|
|
22
|
+
description: General-purpose subagent with full capabilities for delegated multi-step tasks
|
|
23
|
+
spawns: explore
|
|
24
|
+
model: default
|
|
25
|
+
---
|
|
26
|
+
${taskMd}`,
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
name: "quick_task.md",
|
|
30
|
+
content: `---
|
|
31
|
+
name: quick_task
|
|
32
|
+
description: Quick task for fast execution
|
|
33
|
+
model: pi/smol
|
|
34
|
+
---
|
|
35
|
+
${taskMd}`,
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: "deep_task.md",
|
|
39
|
+
content: `---
|
|
40
|
+
name: deep_task
|
|
41
|
+
description: Deep task for comprehensive reasoning
|
|
42
|
+
model: pi/slow
|
|
43
|
+
---
|
|
44
|
+
${taskMd}`,
|
|
45
|
+
},
|
|
21
46
|
];
|
|
22
47
|
|
|
23
48
|
/**
|
|
@@ -88,16 +113,12 @@ function parseAgent(fileName: string, content: string, source: AgentSource): Age
|
|
|
88
113
|
spawns = "*";
|
|
89
114
|
}
|
|
90
115
|
|
|
91
|
-
const recursive =
|
|
92
|
-
frontmatter.recursive === undefined ? false : frontmatter.recursive === "true" || frontmatter.recursive === "1";
|
|
93
|
-
|
|
94
116
|
return {
|
|
95
117
|
name: frontmatter.name,
|
|
96
118
|
description: frontmatter.description,
|
|
97
119
|
tools: tools && tools.length > 0 ? tools : undefined,
|
|
98
120
|
spawns,
|
|
99
121
|
model: frontmatter.model,
|
|
100
|
-
recursive,
|
|
101
122
|
systemPrompt: body,
|
|
102
123
|
source,
|
|
103
124
|
filePath: `embedded:${fileName}`,
|
|
@@ -38,14 +38,12 @@ export function ensureArtifactsDir(dir: string): void {
|
|
|
38
38
|
*/
|
|
39
39
|
export function getArtifactPaths(
|
|
40
40
|
dir: string,
|
|
41
|
-
|
|
42
|
-
index: number,
|
|
41
|
+
taskId: string,
|
|
43
42
|
): { inputPath: string; outputPath: string; jsonlPath: string } {
|
|
44
|
-
const base = `${agentName}_${index}`;
|
|
45
43
|
return {
|
|
46
|
-
inputPath: path.join(dir, `${
|
|
47
|
-
outputPath: path.join(dir, `${
|
|
48
|
-
jsonlPath: path.join(dir, `${
|
|
44
|
+
inputPath: path.join(dir, `${taskId}.in.md`),
|
|
45
|
+
outputPath: path.join(dir, `${taskId}.out.md`),
|
|
46
|
+
jsonlPath: path.join(dir, `${taskId}.jsonl`),
|
|
49
47
|
};
|
|
50
48
|
}
|
|
51
49
|
|
|
@@ -54,15 +52,14 @@ export function getArtifactPaths(
|
|
|
54
52
|
*/
|
|
55
53
|
export async function writeArtifacts(
|
|
56
54
|
dir: string,
|
|
57
|
-
|
|
58
|
-
index: number,
|
|
55
|
+
taskId: string,
|
|
59
56
|
input: string,
|
|
60
57
|
output: string,
|
|
61
58
|
jsonlEvents?: string[],
|
|
62
59
|
): Promise<{ inputPath: string; outputPath: string; jsonlPath?: string }> {
|
|
63
60
|
ensureArtifactsDir(dir);
|
|
64
61
|
|
|
65
|
-
const paths = getArtifactPaths(dir,
|
|
62
|
+
const paths = getArtifactPaths(dir, taskId);
|
|
66
63
|
|
|
67
64
|
// Write input
|
|
68
65
|
await fs.promises.writeFile(paths.inputPath, input, "utf-8");
|
|
@@ -126,18 +126,12 @@ function loadAgentsFromDir(dir: string, source: AgentSource): AgentDefinition[]
|
|
|
126
126
|
spawns = "*";
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
-
const recursive =
|
|
130
|
-
frontmatter.recursive === undefined
|
|
131
|
-
? undefined
|
|
132
|
-
: frontmatter.recursive === "true" || frontmatter.recursive === "1";
|
|
133
|
-
|
|
134
129
|
agents.push({
|
|
135
130
|
name: frontmatter.name,
|
|
136
131
|
description: frontmatter.description,
|
|
137
132
|
tools: tools && tools.length > 0 ? tools : undefined,
|
|
138
133
|
spawns,
|
|
139
134
|
model: frontmatter.model,
|
|
140
|
-
recursive,
|
|
141
135
|
systemPrompt: body,
|
|
142
136
|
source,
|
|
143
137
|
filePath,
|