@oh-my-pi/pi-coding-agent 3.20.1 → 3.24.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 +107 -8
- package/docs/custom-tools.md +3 -3
- package/docs/extensions.md +226 -220
- package/docs/hooks.md +2 -2
- package/docs/sdk.md +50 -53
- package/examples/custom-tools/README.md +2 -17
- package/examples/extensions/README.md +76 -74
- package/examples/extensions/todo.ts +2 -5
- package/examples/hooks/custom-compaction.ts +2 -4
- package/examples/hooks/handoff.ts +1 -1
- package/examples/hooks/qna.ts +1 -1
- package/examples/sdk/02-custom-model.ts +1 -1
- package/examples/sdk/README.md +7 -11
- package/package.json +6 -6
- package/src/cli/args.ts +9 -6
- package/src/cli/file-processor.ts +1 -1
- package/src/cli/list-models.ts +1 -1
- package/src/core/agent-session.ts +16 -5
- package/src/core/auth-storage.ts +1 -1
- package/src/core/compaction/branch-summarization.ts +2 -2
- package/src/core/compaction/compaction.ts +2 -2
- package/src/core/compaction/utils.ts +1 -1
- package/src/core/custom-tools/types.ts +1 -1
- package/src/core/custom-tools/wrapper.ts +0 -1
- package/src/core/extensions/index.ts +1 -6
- package/src/core/extensions/runner.ts +1 -1
- package/src/core/extensions/types.ts +1 -1
- package/src/core/extensions/wrapper.ts +1 -8
- package/src/core/file-mentions.ts +5 -8
- package/src/core/hooks/runner.ts +2 -2
- package/src/core/hooks/types.ts +1 -1
- package/src/core/messages.ts +1 -1
- package/src/core/model-registry.ts +1 -1
- package/src/core/model-resolver.ts +1 -1
- package/src/core/sdk.ts +64 -105
- package/src/core/session-manager.ts +18 -22
- package/src/core/settings-manager.ts +66 -1
- package/src/core/slash-commands.ts +12 -5
- package/src/core/system-prompt.ts +49 -36
- package/src/core/title-generator.ts +2 -2
- package/src/core/tools/ask.ts +98 -4
- package/src/core/tools/bash-interceptor.ts +11 -4
- package/src/core/tools/bash.ts +121 -5
- package/src/core/tools/context.ts +7 -0
- package/src/core/tools/edit-diff.ts +73 -24
- package/src/core/tools/edit.ts +221 -34
- package/src/core/tools/exa/render.ts +4 -16
- package/src/core/tools/find.ts +149 -5
- package/src/core/tools/gemini-image.ts +279 -56
- package/src/core/tools/git.ts +17 -3
- package/src/core/tools/grep.ts +185 -5
- package/src/core/tools/index.test.ts +180 -0
- package/src/core/tools/index.ts +96 -242
- package/src/core/tools/ls.ts +133 -5
- package/src/core/tools/lsp/index.ts +32 -29
- package/src/core/tools/lsp/render.ts +21 -22
- package/src/core/tools/notebook.ts +112 -4
- package/src/core/tools/output.ts +175 -15
- package/src/core/tools/read.ts +127 -25
- package/src/core/tools/render-utils.ts +241 -0
- package/src/core/tools/renderers.ts +40 -828
- package/src/core/tools/review.ts +26 -25
- package/src/core/tools/rulebook.ts +11 -3
- package/src/core/tools/task/agents.ts +28 -7
- package/src/core/tools/task/discovery.ts +0 -6
- package/src/core/tools/task/executor.ts +264 -254
- package/src/core/tools/task/index.ts +48 -208
- package/src/core/tools/task/render.ts +26 -11
- package/src/core/tools/task/types.ts +7 -12
- package/src/core/tools/task/worker-protocol.ts +17 -0
- package/src/core/tools/task/worker.ts +238 -0
- package/src/core/tools/truncate.ts +27 -1
- package/src/core/tools/web-fetch.ts +25 -49
- package/src/core/tools/web-search/index.ts +132 -46
- package/src/core/tools/web-search/providers/anthropic.ts +7 -2
- package/src/core/tools/web-search/providers/exa.ts +2 -1
- package/src/core/tools/web-search/providers/perplexity.ts +6 -1
- package/src/core/tools/web-search/render.ts +6 -4
- package/src/core/tools/web-search/types.ts +13 -0
- package/src/core/tools/write.ts +96 -14
- package/src/core/voice.ts +1 -1
- package/src/discovery/helpers.test.ts +1 -1
- package/src/index.ts +5 -16
- package/src/main.ts +5 -5
- package/src/modes/interactive/components/assistant-message.ts +1 -1
- package/src/modes/interactive/components/custom-message.ts +1 -1
- package/src/modes/interactive/components/extensions/inspector-panel.ts +25 -22
- package/src/modes/interactive/components/extensions/state-manager.ts +12 -0
- package/src/modes/interactive/components/footer.ts +1 -1
- package/src/modes/interactive/components/hook-message.ts +1 -1
- package/src/modes/interactive/components/model-selector.ts +1 -1
- package/src/modes/interactive/components/oauth-selector.ts +1 -1
- package/src/modes/interactive/components/settings-defs.ts +49 -0
- package/src/modes/interactive/components/status-line.ts +1 -1
- package/src/modes/interactive/components/tool-execution.ts +93 -538
- package/src/modes/interactive/interactive-mode.ts +19 -7
- package/src/modes/interactive/theme/theme.ts +4 -4
- package/src/modes/print-mode.ts +1 -1
- package/src/modes/rpc/rpc-client.ts +1 -1
- package/src/modes/rpc/rpc-types.ts +1 -1
- package/src/prompts/system-prompt.md +4 -0
- package/src/prompts/task.md +0 -7
- package/src/prompts/tools/gemini-image.md +5 -1
- package/src/prompts/tools/output.md +6 -2
- package/src/prompts/tools/task.md +68 -0
- package/src/prompts/tools/web-fetch.md +1 -0
- package/src/prompts/tools/web-search.md +2 -0
- package/src/utils/image-convert.ts +8 -2
- package/src/utils/image-magick.ts +247 -0
- package/src/utils/image-resize.ts +53 -13
- 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/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}` : ""}`;
|
|
@@ -72,7 +63,9 @@ export const reportFindingTool: AgentTool<typeof ReportFindingParams, ReportFind
|
|
|
72
63
|
content: [
|
|
73
64
|
{
|
|
74
65
|
type: "text",
|
|
75
|
-
text: `Finding recorded: ${PRIORITY_LABELS[priority]} ${title}\nLocation: ${location}\nConfidence: ${(
|
|
66
|
+
text: `Finding recorded: ${PRIORITY_LABELS[priority]} ${title}\nLocation: ${location}\nConfidence: ${(
|
|
67
|
+
confidence * 100
|
|
68
|
+
).toFixed(0)}%`,
|
|
76
69
|
},
|
|
77
70
|
],
|
|
78
71
|
details: { title, body, priority, confidence, file_path, line_start, line_end },
|
|
@@ -84,7 +77,10 @@ export const reportFindingTool: AgentTool<typeof ReportFindingParams, ReportFind
|
|
|
84
77
|
const color = args.priority === 0 ? "error" : args.priority === 1 ? "warning" : "muted";
|
|
85
78
|
const titleText = String(args.title).replace(/^\[P\d\]\s*/, "");
|
|
86
79
|
return new Text(
|
|
87
|
-
`${theme.fg("toolTitle", theme.bold("report_finding "))}${theme.fg(color, `[${priority}]`)} ${theme.fg(
|
|
80
|
+
`${theme.fg("toolTitle", theme.bold("report_finding "))}${theme.fg(color, `[${priority}]`)} ${theme.fg(
|
|
81
|
+
"dim",
|
|
82
|
+
titleText,
|
|
83
|
+
)}`,
|
|
88
84
|
0,
|
|
89
85
|
0,
|
|
90
86
|
);
|
|
@@ -99,7 +95,9 @@ export const reportFindingTool: AgentTool<typeof ReportFindingParams, ReportFind
|
|
|
99
95
|
|
|
100
96
|
const priority = PRIORITY_LABELS[details.priority] ?? "P?";
|
|
101
97
|
const color = details.priority === 0 ? "error" : details.priority === 1 ? "warning" : "muted";
|
|
102
|
-
const location = `${details.file_path}:${details.line_start}${
|
|
98
|
+
const location = `${details.file_path}:${details.line_start}${
|
|
99
|
+
details.line_end !== details.line_start ? `-${details.line_end}` : ""
|
|
100
|
+
}`;
|
|
103
101
|
|
|
104
102
|
return new Text(
|
|
105
103
|
`${theme.fg("success", theme.status.success)} ${theme.fg(color, `[${priority}]`)} ${theme.fg("dim", location)}`,
|
|
@@ -135,13 +133,16 @@ export const submitReviewTool: AgentTool<typeof SubmitReviewParams, SubmitReview
|
|
|
135
133
|
label: "Submit Review",
|
|
136
134
|
description: "Submit the final review verdict. Call this after all findings have been reported.",
|
|
137
135
|
parameters: SubmitReviewParams,
|
|
138
|
-
hidden: true,
|
|
139
136
|
|
|
140
137
|
async execute(_toolCallId, params, _signal, _onUpdate, _ctx) {
|
|
141
138
|
const { overall_correctness, explanation, confidence } = params;
|
|
142
139
|
|
|
143
140
|
let summary = `## Review Summary\n\n`;
|
|
144
|
-
summary += `**Verdict:** ${
|
|
141
|
+
summary += `**Verdict:** ${
|
|
142
|
+
overall_correctness === "correct"
|
|
143
|
+
? `${theme.status.success} Patch is correct`
|
|
144
|
+
: `${theme.status.error} Patch is incorrect`
|
|
145
|
+
}\n`;
|
|
145
146
|
summary += `**Confidence:** ${(confidence * 100).toFixed(0)}%\n\n`;
|
|
146
147
|
summary += explanation;
|
|
147
148
|
|
|
@@ -155,7 +156,10 @@ export const submitReviewTool: AgentTool<typeof SubmitReviewParams, SubmitReview
|
|
|
155
156
|
const verdict = args.overall_correctness === "correct" ? "correct" : "incorrect";
|
|
156
157
|
const color = args.overall_correctness === "correct" ? "success" : "error";
|
|
157
158
|
return new Text(
|
|
158
|
-
`${theme.fg("toolTitle", theme.bold("submit_review "))}${theme.fg(color, verdict)} ${theme.fg(
|
|
159
|
+
`${theme.fg("toolTitle", theme.bold("submit_review "))}${theme.fg(color, verdict)} ${theme.fg(
|
|
160
|
+
"dim",
|
|
161
|
+
`(${((args.confidence as number) * 100).toFixed(0)}%)`,
|
|
162
|
+
)}`,
|
|
159
163
|
0,
|
|
160
164
|
0,
|
|
161
165
|
);
|
|
@@ -174,7 +178,10 @@ export const submitReviewTool: AgentTool<typeof SubmitReviewParams, SubmitReview
|
|
|
174
178
|
|
|
175
179
|
container.addChild(
|
|
176
180
|
new Text(
|
|
177
|
-
`${theme.fg(verdictColor, verdictIcon)} Patch is ${theme.fg(
|
|
181
|
+
`${theme.fg(verdictColor, verdictIcon)} Patch is ${theme.fg(
|
|
182
|
+
verdictColor,
|
|
183
|
+
details.overall_correctness,
|
|
184
|
+
)} ${theme.fg("dim", `(${(details.confidence * 100).toFixed(0)}% confidence)`)}`,
|
|
178
185
|
0,
|
|
179
186
|
0,
|
|
180
187
|
),
|
|
@@ -189,14 +196,6 @@ export const submitReviewTool: AgentTool<typeof SubmitReviewParams, SubmitReview
|
|
|
189
196
|
},
|
|
190
197
|
};
|
|
191
198
|
|
|
192
|
-
export function createReportFindingTool(): AgentTool<typeof ReportFindingParams, ReportFindingDetails, Theme> {
|
|
193
|
-
return reportFindingTool;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
export function createSubmitReviewTool(): AgentTool<typeof SubmitReviewParams, SubmitReviewDetails, Theme> {
|
|
197
|
-
return submitReviewTool;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
199
|
// Re-export types for external use
|
|
201
200
|
export type { ReportFindingDetails, SubmitReviewDetails };
|
|
202
201
|
|
|
@@ -264,7 +263,9 @@ subprocessToolRegistry.register<SubmitReviewDetails>("submit_review", {
|
|
|
264
263
|
const verdictColor = data.overall_correctness === "correct" ? "success" : "error";
|
|
265
264
|
const verdictIcon = data.overall_correctness === "correct" ? theme.status.success : theme.status.error;
|
|
266
265
|
return new Text(
|
|
267
|
-
`${theme.fg(verdictColor, verdictIcon)} Review: ${theme.fg(verdictColor, data.overall_correctness)} (${(
|
|
266
|
+
`${theme.fg(verdictColor, verdictIcon)} Review: ${theme.fg(verdictColor, data.overall_correctness)} (${(
|
|
267
|
+
data.confidence * 100
|
|
268
|
+
).toFixed(0)}%)`,
|
|
268
269
|
0,
|
|
269
270
|
0,
|
|
270
271
|
);
|
|
@@ -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) {
|
|
@@ -37,7 +43,9 @@ export function createRulebookTool(rules: Rule[]): AgentTool<typeof rulebookSche
|
|
|
37
43
|
return {
|
|
38
44
|
name: "rulebook",
|
|
39
45
|
label: "Rulebook",
|
|
40
|
-
description: `Fetch the full content of a project rule by name. Use this when a rule listed in <available_rules> is relevant to your current task. Available: ${
|
|
46
|
+
description: `Fetch the full content of a project rule by name. Use this when a rule listed in <available_rules> is relevant to your current task. Available: ${
|
|
47
|
+
ruleNames.join(", ") || "(none)"
|
|
48
|
+
}`,
|
|
41
49
|
parameters: rulebookSchema,
|
|
42
50
|
execute: async (_toolCallId: string, { name }: { name: string }) => {
|
|
43
51
|
const rule = ruleMap.get(name);
|
|
@@ -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}`,
|
|
@@ -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,
|