@oh-my-pi/pi-coding-agent 13.3.4 → 13.3.6
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 +19 -0
- package/package.json +7 -7
- package/src/cli/config-cli.ts +48 -4
- package/src/config/settings-schema.ts +1 -1
- package/src/prompts/agents/reviewer.md +5 -5
- package/src/prompts/system/subagent-submit-reminder.md +2 -2
- package/src/prompts/system/subagent-system-prompt.md +2 -2
- package/src/sdk.ts +1 -1
- package/src/tools/submit-result.ts +30 -13
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,25 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [13.3.6] - 2026-02-26
|
|
6
|
+
### Breaking Changes
|
|
7
|
+
|
|
8
|
+
- Changed `submit_result` tool parameter structure from top-level `data` or `error` fields to nested `result` object containing either `result.data` or `result.error`
|
|
9
|
+
|
|
10
|
+
## [13.3.5] - 2026-02-26
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- Added support for setting array and record configuration values using JSON syntax
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- Increased default async max jobs limit from 15 to 100 for improved concurrent task handling
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
|
|
21
|
+
- Improved config display formatting to properly render arrays and objects as JSON instead of `[object Object]`
|
|
22
|
+
- Enhanced type display in config list output to show correct type indicators for number, array, and record settings
|
|
23
|
+
|
|
5
24
|
## [13.3.3] - 2026-02-26
|
|
6
25
|
### Added
|
|
7
26
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@oh-my-pi/pi-coding-agent",
|
|
4
|
-
"version": "13.3.
|
|
4
|
+
"version": "13.3.6",
|
|
5
5
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
6
6
|
"homepage": "https://github.com/can1357/oh-my-pi",
|
|
7
7
|
"author": "Can Boluk",
|
|
@@ -41,12 +41,12 @@
|
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
43
|
"@mozilla/readability": "^0.6",
|
|
44
|
-
"@oh-my-pi/omp-stats": "13.3.
|
|
45
|
-
"@oh-my-pi/pi-agent-core": "13.3.
|
|
46
|
-
"@oh-my-pi/pi-ai": "13.3.
|
|
47
|
-
"@oh-my-pi/pi-natives": "13.3.
|
|
48
|
-
"@oh-my-pi/pi-tui": "13.3.
|
|
49
|
-
"@oh-my-pi/pi-utils": "13.3.
|
|
44
|
+
"@oh-my-pi/omp-stats": "13.3.6",
|
|
45
|
+
"@oh-my-pi/pi-agent-core": "13.3.6",
|
|
46
|
+
"@oh-my-pi/pi-ai": "13.3.6",
|
|
47
|
+
"@oh-my-pi/pi-natives": "13.3.6",
|
|
48
|
+
"@oh-my-pi/pi-tui": "13.3.6",
|
|
49
|
+
"@oh-my-pi/pi-utils": "13.3.6",
|
|
50
50
|
"@sinclair/typebox": "^0.34",
|
|
51
51
|
"@xterm/headless": "^6.0",
|
|
52
52
|
"ajv": "^8.18",
|
package/src/cli/config-cli.ts
CHANGED
|
@@ -134,18 +134,36 @@ function formatValue(value: unknown): string {
|
|
|
134
134
|
if (typeof value === "number") {
|
|
135
135
|
return chalk.cyan(String(value));
|
|
136
136
|
}
|
|
137
|
+
if (typeof value === "string") {
|
|
138
|
+
return chalk.yellow(value);
|
|
139
|
+
}
|
|
140
|
+
if (Array.isArray(value) || typeof value === "object") {
|
|
141
|
+
try {
|
|
142
|
+
return chalk.yellow(JSON.stringify(value));
|
|
143
|
+
} catch {
|
|
144
|
+
return chalk.yellow(String(value));
|
|
145
|
+
}
|
|
146
|
+
}
|
|
137
147
|
return chalk.yellow(String(value));
|
|
138
148
|
}
|
|
139
149
|
|
|
140
150
|
function getTypeDisplay(def: CliSettingDef): string {
|
|
141
|
-
if (def.type === "boolean") {
|
|
142
|
-
return "(boolean)";
|
|
143
|
-
}
|
|
144
151
|
const values = getSettingValues(def);
|
|
145
152
|
if (values && values.length > 0) {
|
|
146
153
|
return `(${values.join("|")})`;
|
|
147
154
|
}
|
|
148
|
-
|
|
155
|
+
switch (def.type) {
|
|
156
|
+
case "boolean":
|
|
157
|
+
return "(boolean)";
|
|
158
|
+
case "number":
|
|
159
|
+
return "(number)";
|
|
160
|
+
case "array":
|
|
161
|
+
return "(array)";
|
|
162
|
+
case "record":
|
|
163
|
+
return "(record)";
|
|
164
|
+
default:
|
|
165
|
+
return "(string)";
|
|
166
|
+
}
|
|
149
167
|
}
|
|
150
168
|
|
|
151
169
|
// =============================================================================
|
|
@@ -177,6 +195,32 @@ function parseAndSetValue(path: SettingPath, rawValue: string): void {
|
|
|
177
195
|
parsedValue = trimmed;
|
|
178
196
|
break;
|
|
179
197
|
}
|
|
198
|
+
case "array": {
|
|
199
|
+
let parsed: unknown;
|
|
200
|
+
try {
|
|
201
|
+
parsed = JSON.parse(trimmed);
|
|
202
|
+
} catch {
|
|
203
|
+
throw new Error(`Invalid array JSON: ${rawValue}`);
|
|
204
|
+
}
|
|
205
|
+
if (!Array.isArray(parsed)) {
|
|
206
|
+
throw new Error(`Invalid array JSON: ${rawValue}`);
|
|
207
|
+
}
|
|
208
|
+
parsedValue = parsed;
|
|
209
|
+
break;
|
|
210
|
+
}
|
|
211
|
+
case "record": {
|
|
212
|
+
let parsed: unknown;
|
|
213
|
+
try {
|
|
214
|
+
parsed = JSON.parse(trimmed);
|
|
215
|
+
} catch {
|
|
216
|
+
throw new Error(`Invalid record JSON: ${rawValue}`);
|
|
217
|
+
}
|
|
218
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
219
|
+
throw new Error(`Invalid record JSON: ${rawValue}`);
|
|
220
|
+
}
|
|
221
|
+
parsedValue = parsed;
|
|
222
|
+
break;
|
|
223
|
+
}
|
|
180
224
|
default:
|
|
181
225
|
parsedValue = trimmed;
|
|
182
226
|
}
|
|
@@ -112,11 +112,11 @@ Each `report_finding` requires:
|
|
|
112
112
|
- `file_path`: Absolute path
|
|
113
113
|
- `line_start`, `line_end`: Range ≤10 lines, must overlap diff
|
|
114
114
|
|
|
115
|
-
Final `submit_result` call (payload under `data`):
|
|
116
|
-
- `data.overall_correctness`: "correct" (no bugs/blockers) or "incorrect"
|
|
117
|
-
- `data.explanation`: Plain text, 1-3 sentences summarizing verdict. Don't repeat findings (captured via `report_finding`).
|
|
118
|
-
- `data.confidence`: 0.0-1.0
|
|
119
|
-
- `data.findings`: Optional; **MUST** omit (auto-populated from `report_finding`)
|
|
115
|
+
Final `submit_result` call (payload under `result.data`):
|
|
116
|
+
- `result.data.overall_correctness`: "correct" (no bugs/blockers) or "incorrect"
|
|
117
|
+
- `result.data.explanation`: Plain text, 1-3 sentences summarizing verdict. Don't repeat findings (captured via `report_finding`).
|
|
118
|
+
- `result.data.confidence`: 0.0-1.0
|
|
119
|
+
- `result.data.findings`: Optional; **MUST** omit (auto-populated from `report_finding`)
|
|
120
120
|
|
|
121
121
|
You **MUST NOT** output JSON or code blocks.
|
|
122
122
|
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
You stopped without calling submit_result. This is reminder {{retryCount}} of {{maxRetries}}.
|
|
3
3
|
|
|
4
4
|
You **MUST** call submit_result as your only action now. Choose one:
|
|
5
|
-
- If task is complete: call submit_result with your result in
|
|
6
|
-
- If task failed: call submit_result with
|
|
5
|
+
- If task is complete: call submit_result with your result in `result.data`
|
|
6
|
+
- If task failed: call submit_result with `result.error` describing what happened
|
|
7
7
|
|
|
8
8
|
You **MUST NOT** give up if you can still complete the task through exploration (using available tools or repo context). If you submit an error, you **MUST** include what you tried and the exact blocker.
|
|
9
9
|
|
|
@@ -19,7 +19,7 @@ No TODO tracking, no progress updates. Execute, call `submit_result`, done.
|
|
|
19
19
|
|
|
20
20
|
When finished, you **MUST** call `submit_result` exactly once. This is like writing to a ticket, provide what is required, and close it.
|
|
21
21
|
|
|
22
|
-
This is your only way to return a result. You **MUST NOT** put JSON in plain text, and you **MUST NOT** substitute a text summary for the structured `data` parameter.
|
|
22
|
+
This is your only way to return a result. You **MUST NOT** put JSON in plain text, and you **MUST NOT** substitute a text summary for the structured `result.data` parameter.
|
|
23
23
|
|
|
24
24
|
{{#if outputSchema}}
|
|
25
25
|
Your result **MUST** match this TypeScript interface:
|
|
@@ -29,7 +29,7 @@ Your result **MUST** match this TypeScript interface:
|
|
|
29
29
|
{{/if}}
|
|
30
30
|
|
|
31
31
|
{{SECTION_SEPERATOR "Giving Up"}}
|
|
32
|
-
If you cannot complete the assignment, you **MUST** call `submit_result` exactly once with
|
|
32
|
+
If you cannot complete the assignment, you **MUST** call `submit_result` exactly once with `result.error` describing what you tried and the exact blocker.
|
|
33
33
|
|
|
34
34
|
Giving up is a last resort.
|
|
35
35
|
You **MUST NOT** give up due to uncertainty or missing information obtainable via tools or repo context.
|
package/src/sdk.ts
CHANGED
|
@@ -729,7 +729,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
729
729
|
|
|
730
730
|
const enableLsp = options.enableLsp ?? true;
|
|
731
731
|
const asyncEnabled = settings.get("async.enabled");
|
|
732
|
-
const asyncMaxJobs = Math.min(100, Math.max(1, settings.get("async.maxJobs") ??
|
|
732
|
+
const asyncMaxJobs = Math.min(100, Math.max(1, settings.get("async.maxJobs") ?? 100));
|
|
733
733
|
const ASYNC_INLINE_RESULT_MAX_CHARS = 12_000;
|
|
734
734
|
const ASYNC_PREVIEW_MAX_CHARS = 4_000;
|
|
735
735
|
const formatAsyncResultForFollowUp = async (result: string): Promise<string> => {
|
|
@@ -89,16 +89,20 @@ export class SubmitResultTool implements AgentTool<TSchema, SubmitResultDetails>
|
|
|
89
89
|
...(normalizedSchema as object),
|
|
90
90
|
description: `Structured output matching the schema:\n${schemaHint}`,
|
|
91
91
|
})
|
|
92
|
-
: Type.
|
|
93
|
-
|
|
94
|
-
this.parameters = Type.
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
}
|
|
101
|
-
|
|
92
|
+
: Type.Record(Type.String(), Type.Any(), { description: "Structured JSON output (no schema specified)" });
|
|
93
|
+
|
|
94
|
+
this.parameters = Type.Object(
|
|
95
|
+
{
|
|
96
|
+
result: Type.Union([
|
|
97
|
+
Type.Object({ data: dataSchema }, { description: "Successfully completed the task" }),
|
|
98
|
+
Type.Object({ error: Type.String({ description: "Error message when the task cannot be completed" }) }),
|
|
99
|
+
]),
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
additionalProperties: false,
|
|
103
|
+
description: "Submit either `data` for success or `error` for failure",
|
|
104
|
+
},
|
|
105
|
+
);
|
|
102
106
|
}
|
|
103
107
|
|
|
104
108
|
async execute(
|
|
@@ -109,10 +113,23 @@ export class SubmitResultTool implements AgentTool<TSchema, SubmitResultDetails>
|
|
|
109
113
|
_context?: AgentToolContext,
|
|
110
114
|
): Promise<AgentToolResult<SubmitResultDetails>> {
|
|
111
115
|
const raw = params as Record<string, unknown>;
|
|
112
|
-
const
|
|
113
|
-
|
|
114
|
-
|
|
116
|
+
const rawResult = raw.result;
|
|
117
|
+
if (!rawResult || typeof rawResult !== "object" || Array.isArray(rawResult)) {
|
|
118
|
+
throw new Error("result must be an object containing either data or error");
|
|
119
|
+
}
|
|
115
120
|
|
|
121
|
+
const resultRecord = rawResult as Record<string, unknown>;
|
|
122
|
+
const errorMessage = typeof resultRecord.error === "string" ? resultRecord.error : undefined;
|
|
123
|
+
const data = resultRecord.data;
|
|
124
|
+
|
|
125
|
+
if (errorMessage !== undefined && data !== undefined) {
|
|
126
|
+
throw new Error("result cannot contain both data and error");
|
|
127
|
+
}
|
|
128
|
+
if (errorMessage === undefined && data === undefined) {
|
|
129
|
+
throw new Error("result must contain either data or error");
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const status = errorMessage !== undefined ? "aborted" : "success";
|
|
116
133
|
if (status === "success") {
|
|
117
134
|
if (data === undefined || data === null) {
|
|
118
135
|
throw new Error("data is required when submit_result indicates success");
|