@oh-my-pi/pi-coding-agent 9.2.5 → 9.3.1
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 +16 -0
- package/package.json +7 -7
- package/src/discovery/helpers.ts +6 -1
- package/src/prompts/system/subagent-system-prompt.md +14 -7
- package/src/prompts/tools/task-summary.md +0 -7
- package/src/sdk.ts +1 -0
- package/src/session/agent-session.ts +63 -0
- package/src/system-prompt.ts +5 -7
- package/src/task/executor.ts +3 -0
- package/src/task/index.ts +11 -3
- package/src/tools/index.ts +2 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [9.3.1] - 2026-01-31
|
|
6
|
+
### Added
|
|
7
|
+
|
|
8
|
+
- Added `getCompactContext()` API to retrieve parent conversation context for subagents, excluding system prompts and tool results
|
|
9
|
+
- Added automatic `submit_result` tool injection for subagents with explicit tool lists
|
|
10
|
+
- Added `contextFile` parameter to pass parent conversation context to subagent sessions
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- Updated subagent system prompt to reference parent conversation context file when available
|
|
15
|
+
- Enhanced subagent system prompt formatting with clearer backtick notation for tool and parameter names
|
|
16
|
+
|
|
17
|
+
### Removed
|
|
18
|
+
|
|
19
|
+
- Removed schema override notification from task summary prompt
|
|
20
|
+
|
|
5
21
|
## [9.2.5] - 2026-01-31
|
|
6
22
|
### Changed
|
|
7
23
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oh-my-pi/pi-coding-agent",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.3.1",
|
|
4
4
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"ompConfig": {
|
|
@@ -79,12 +79,12 @@
|
|
|
79
79
|
"test": "bun test"
|
|
80
80
|
},
|
|
81
81
|
"dependencies": {
|
|
82
|
-
"@oh-my-pi/omp-stats": "9.
|
|
83
|
-
"@oh-my-pi/pi-agent-core": "9.
|
|
84
|
-
"@oh-my-pi/pi-ai": "9.
|
|
85
|
-
"@oh-my-pi/pi-natives": "9.
|
|
86
|
-
"@oh-my-pi/pi-tui": "9.
|
|
87
|
-
"@oh-my-pi/pi-utils": "9.
|
|
82
|
+
"@oh-my-pi/omp-stats": "9.3.1",
|
|
83
|
+
"@oh-my-pi/pi-agent-core": "9.3.1",
|
|
84
|
+
"@oh-my-pi/pi-ai": "9.3.1",
|
|
85
|
+
"@oh-my-pi/pi-natives": "9.3.1",
|
|
86
|
+
"@oh-my-pi/pi-tui": "9.3.1",
|
|
87
|
+
"@oh-my-pi/pi-utils": "9.3.1",
|
|
88
88
|
"@openai/agents": "^0.4.4",
|
|
89
89
|
"@sinclair/typebox": "^0.34.48",
|
|
90
90
|
"ajv": "^8.17.1",
|
package/src/discovery/helpers.ts
CHANGED
|
@@ -189,7 +189,12 @@ export function parseAgentFields(frontmatter: Record<string, unknown>): ParsedAg
|
|
|
189
189
|
return null;
|
|
190
190
|
}
|
|
191
191
|
|
|
192
|
-
|
|
192
|
+
let tools = parseArrayOrCSV(frontmatter.tools);
|
|
193
|
+
|
|
194
|
+
// Subagents with explicit tool lists always need submit_result
|
|
195
|
+
if (tools && !tools.includes("submit_result")) {
|
|
196
|
+
tools = [...tools, "submit_result"];
|
|
197
|
+
}
|
|
193
198
|
|
|
194
199
|
// Parse spawns field (array, "*", or CSV)
|
|
195
200
|
let spawns: string[] | "*" | undefined;
|
|
@@ -1,24 +1,31 @@
|
|
|
1
1
|
{{base}}
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
====================================================
|
|
3
4
|
|
|
4
5
|
{{agent}}
|
|
5
6
|
|
|
7
|
+
{{#if contextFile}}
|
|
8
|
+
<context>
|
|
9
|
+
If you need additional context about the parent conversation, check {{contextFile}} (e.g., `tail -100` or `grep` for relevant terms).
|
|
10
|
+
</context>
|
|
11
|
+
{{/if}}
|
|
12
|
+
|
|
6
13
|
<critical>
|
|
7
14
|
{{#if worktree}}
|
|
8
15
|
- You MUST work under this working tree: {{worktree}}. Do not modify anything under the original repository.
|
|
9
16
|
{{/if}}
|
|
10
|
-
- You MUST call the submit_result tool exactly once when finished. Do not output JSON in text. Do not end with a plain-text summary. Call submit_result with your result as the data parameter.
|
|
17
|
+
- You MUST call the `submit_result` tool exactly once when finished. Do not output JSON in text. Do not end with a plain-text summary. Call `submit_result` with your result as the `data` parameter.
|
|
11
18
|
{{#if outputSchema}}
|
|
12
|
-
- If you cannot complete the task, call submit_result with status="aborted" and an error message. Do not provide a success result or pretend completion.
|
|
19
|
+
- If you cannot complete the task, call `submit_result` with `status="aborted"` and an error message. Do not provide a success result or pretend completion.
|
|
13
20
|
{{else}}
|
|
14
|
-
- If you cannot complete the task, call submit_result with status="aborted" and an error message. Do not claim success.
|
|
21
|
+
- If you cannot complete the task, call `submit_result` with `status="aborted"` and an error message. Do not claim success.
|
|
15
22
|
{{/if}}
|
|
16
23
|
{{#if outputSchema}}
|
|
17
|
-
- The data parameter MUST be valid JSON matching this TypeScript interface:
|
|
18
|
-
```
|
|
24
|
+
- The `data` parameter MUST be valid JSON matching this TypeScript interface:
|
|
25
|
+
```ts
|
|
19
26
|
{{jtdToTypeScript outputSchema}}
|
|
20
27
|
```
|
|
21
28
|
{{/if}}
|
|
22
|
-
- If you cannot complete the task, call submit_result exactly once with a result that explicitly indicates failure or abort status (use a failure/notes field if available). Do not claim success.
|
|
29
|
+
- If you cannot complete the task, call `submit_result` exactly once with a result that explicitly indicates failure or abort status (use a failure/notes field if available). Do not claim success.
|
|
23
30
|
- Keep going until request is fully fulfilled. This matters.
|
|
24
31
|
</critical>
|
|
@@ -20,13 +20,6 @@
|
|
|
20
20
|
{{/unless}}
|
|
21
21
|
{{/each}}
|
|
22
22
|
|
|
23
|
-
{{#if schemaOverridden}}
|
|
24
|
-
<schema-note>
|
|
25
|
-
Note: Agent '{{agentName}}' has a fixed output schema:
|
|
26
|
-
{{requiredSchema}}
|
|
27
|
-
</schema-note>
|
|
28
|
-
{{/if}}
|
|
29
|
-
|
|
30
23
|
{{#if patchApplySummary}}
|
|
31
24
|
<patch-summary>
|
|
32
25
|
{{patchApplySummary}}
|
package/src/sdk.ts
CHANGED
|
@@ -760,6 +760,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
760
760
|
return undefined;
|
|
761
761
|
},
|
|
762
762
|
getPlanModeState: () => session.getPlanModeState(),
|
|
763
|
+
getCompactContext: () => session.formatCompactContext(),
|
|
763
764
|
settings: settingsManager,
|
|
764
765
|
settingsManager,
|
|
765
766
|
authStorage,
|
|
@@ -3916,6 +3916,69 @@ Be thorough - include exact file paths, function names, error messages, and tech
|
|
|
3916
3916
|
return lines.join("\n").trim();
|
|
3917
3917
|
}
|
|
3918
3918
|
|
|
3919
|
+
/**
|
|
3920
|
+
* Format the conversation as compact context for subagents.
|
|
3921
|
+
* Includes only user messages and assistant text responses.
|
|
3922
|
+
* Excludes: system prompt, tool definitions, tool calls/results, thinking blocks.
|
|
3923
|
+
*/
|
|
3924
|
+
formatCompactContext(): string {
|
|
3925
|
+
const lines: string[] = [];
|
|
3926
|
+
lines.push("# Conversation Context");
|
|
3927
|
+
lines.push("");
|
|
3928
|
+
lines.push(
|
|
3929
|
+
"This is a summary of the parent conversation. Read this if you need additional context about what was discussed or decided.",
|
|
3930
|
+
);
|
|
3931
|
+
lines.push("");
|
|
3932
|
+
|
|
3933
|
+
for (const msg of this.messages) {
|
|
3934
|
+
if (msg.role === "user") {
|
|
3935
|
+
lines.push("## User");
|
|
3936
|
+
lines.push("");
|
|
3937
|
+
if (typeof msg.content === "string") {
|
|
3938
|
+
lines.push(msg.content);
|
|
3939
|
+
} else {
|
|
3940
|
+
for (const c of msg.content) {
|
|
3941
|
+
if (c.type === "text") {
|
|
3942
|
+
lines.push(c.text);
|
|
3943
|
+
} else if (c.type === "image") {
|
|
3944
|
+
lines.push("[Image attached]");
|
|
3945
|
+
}
|
|
3946
|
+
}
|
|
3947
|
+
}
|
|
3948
|
+
lines.push("");
|
|
3949
|
+
} else if (msg.role === "assistant") {
|
|
3950
|
+
const assistantMsg = msg as AssistantMessage;
|
|
3951
|
+
// Only include text content, skip tool calls and thinking
|
|
3952
|
+
const textParts: string[] = [];
|
|
3953
|
+
for (const c of assistantMsg.content) {
|
|
3954
|
+
if (c.type === "text" && c.text.trim()) {
|
|
3955
|
+
textParts.push(c.text);
|
|
3956
|
+
}
|
|
3957
|
+
}
|
|
3958
|
+
if (textParts.length > 0) {
|
|
3959
|
+
lines.push("## Assistant");
|
|
3960
|
+
lines.push("");
|
|
3961
|
+
lines.push(textParts.join("\n\n"));
|
|
3962
|
+
lines.push("");
|
|
3963
|
+
}
|
|
3964
|
+
} else if (msg.role === "fileMention") {
|
|
3965
|
+
const fileMsg = msg as FileMentionMessage;
|
|
3966
|
+
const paths = fileMsg.files.map(f => f.path).join(", ");
|
|
3967
|
+
lines.push(`[Files referenced: ${paths}]`);
|
|
3968
|
+
lines.push("");
|
|
3969
|
+
} else if (msg.role === "compactionSummary") {
|
|
3970
|
+
const compactMsg = msg as CompactionSummaryMessage;
|
|
3971
|
+
lines.push("## Earlier Context (Summarized)");
|
|
3972
|
+
lines.push("");
|
|
3973
|
+
lines.push(compactMsg.summary);
|
|
3974
|
+
lines.push("");
|
|
3975
|
+
}
|
|
3976
|
+
// Skip: toolResult, bashExecution, pythonExecution, branchSummary, custom, hookMessage
|
|
3977
|
+
}
|
|
3978
|
+
|
|
3979
|
+
return lines.join("\n").trim();
|
|
3980
|
+
}
|
|
3981
|
+
|
|
3919
3982
|
// =========================================================================
|
|
3920
3983
|
// Extension System
|
|
3921
3984
|
// =========================================================================
|
package/src/system-prompt.ts
CHANGED
|
@@ -11,7 +11,7 @@ import chalk from "chalk";
|
|
|
11
11
|
import { contextFileCapability } from "./capability/context-file";
|
|
12
12
|
import { systemPromptCapability } from "./capability/system-prompt";
|
|
13
13
|
import { renderPromptTemplate } from "./config/prompt-templates";
|
|
14
|
-
import type
|
|
14
|
+
import { SettingsManager, type SkillsSettings } from "./config/settings-manager";
|
|
15
15
|
import { type ContextFile, loadCapability, type SystemPrompt as SystemPromptFile } from "./discovery";
|
|
16
16
|
import { loadSkills, type Skill } from "./extensibility/skills";
|
|
17
17
|
import customSystemPromptTemplate from "./prompts/system/custom-system-prompt.md" with { type: "text" };
|
|
@@ -573,11 +573,6 @@ async function getGpuModel(): Promise<string | null> {
|
|
|
573
573
|
}
|
|
574
574
|
}
|
|
575
575
|
|
|
576
|
-
function getShellName(): string {
|
|
577
|
-
const shell = firstNonEmpty([process.env.SHELL, process.env.ComSpec]);
|
|
578
|
-
return shell ?? "unknown";
|
|
579
|
-
}
|
|
580
|
-
|
|
581
576
|
function getTerminalName(): string {
|
|
582
577
|
const termProgram = process.env.TERM_PROGRAM;
|
|
583
578
|
const termProgramVersion = process.env.TERM_PROGRAM_VERSION;
|
|
@@ -765,6 +760,9 @@ async function getEnvironmentInfo(): Promise<Array<{ label: string; value: strin
|
|
|
765
760
|
await saveSystemInfoCache(sysInfo);
|
|
766
761
|
}
|
|
767
762
|
|
|
763
|
+
// Get the actual shell used for command execution (not $SHELL)
|
|
764
|
+
const shellConfig = await SettingsManager.getGlobalShellConfig();
|
|
765
|
+
|
|
768
766
|
return [
|
|
769
767
|
{ label: "OS", value: sysInfo.os },
|
|
770
768
|
{ label: "Distro", value: sysInfo.distro },
|
|
@@ -773,7 +771,7 @@ async function getEnvironmentInfo(): Promise<Array<{ label: string; value: strin
|
|
|
773
771
|
{ label: "CPU", value: sysInfo.cpu },
|
|
774
772
|
{ label: "GPU", value: sysInfo.gpu },
|
|
775
773
|
{ label: "Disk", value: sysInfo.disk },
|
|
776
|
-
{ label: "Shell", value:
|
|
774
|
+
{ label: "Shell", value: shellConfig.shell },
|
|
777
775
|
{ label: "Terminal", value: getTerminalName() },
|
|
778
776
|
{ label: "DE", value: getDesktopEnvironment() },
|
|
779
777
|
{ label: "WM", value: getWindowManager() },
|
package/src/task/executor.ts
CHANGED
|
@@ -196,6 +196,8 @@ export interface ExecutorOptions {
|
|
|
196
196
|
sessionFile?: string | null;
|
|
197
197
|
persistArtifacts?: boolean;
|
|
198
198
|
artifactsDir?: string;
|
|
199
|
+
/** Path to parent conversation context file */
|
|
200
|
+
contextFile?: string;
|
|
199
201
|
eventBus?: EventBus;
|
|
200
202
|
contextFiles?: ContextFileEntry[];
|
|
201
203
|
skills?: Skill[];
|
|
@@ -948,6 +950,7 @@ export async function runSubprocess(options: ExecutorOptions): Promise<SingleRes
|
|
|
948
950
|
agent: agent.systemPrompt,
|
|
949
951
|
worktree: worktree ?? "",
|
|
950
952
|
outputSchema: normalizedOutputSchema,
|
|
953
|
+
contextFile: options.contextFile,
|
|
951
954
|
}),
|
|
952
955
|
sessionManager,
|
|
953
956
|
hasUI: false,
|
package/src/task/index.ts
CHANGED
|
@@ -211,7 +211,6 @@ export class TaskTool implements AgentTool<typeof taskSchema, TaskToolDetails, T
|
|
|
211
211
|
const thinkingLevelOverride = effectiveAgent.thinkingLevel;
|
|
212
212
|
|
|
213
213
|
// Output schema priority: agent frontmatter > params > inherited from parent session
|
|
214
|
-
const schemaOverridden = outputSchema !== undefined && effectiveAgent.output !== undefined;
|
|
215
214
|
const effectiveOutputSchema = effectiveAgent.output ?? outputSchema ?? this.session.outputSchema;
|
|
216
215
|
|
|
217
216
|
// Handle empty or missing tasks
|
|
@@ -382,6 +381,15 @@ export class TaskTool implements AgentTool<typeof taskSchema, TaskToolDetails, T
|
|
|
382
381
|
};
|
|
383
382
|
}
|
|
384
383
|
|
|
384
|
+
// Write parent conversation context for subagents
|
|
385
|
+
await fs.mkdir(effectiveArtifactsDir, { recursive: true });
|
|
386
|
+
const compactContext = this.session.getCompactContext?.();
|
|
387
|
+
let contextFilePath: string | undefined;
|
|
388
|
+
if (compactContext) {
|
|
389
|
+
contextFilePath = path.join(effectiveArtifactsDir, "context.md");
|
|
390
|
+
await Bun.write(contextFilePath, compactContext);
|
|
391
|
+
}
|
|
392
|
+
|
|
385
393
|
// Build full prompts with context prepended
|
|
386
394
|
// Allocate unique IDs across the session to prevent artifact collisions
|
|
387
395
|
const outputManager =
|
|
@@ -478,6 +486,7 @@ export class TaskTool implements AgentTool<typeof taskSchema, TaskToolDetails, T
|
|
|
478
486
|
sessionFile,
|
|
479
487
|
persistArtifacts: !!artifactsDir,
|
|
480
488
|
artifactsDir: effectiveArtifactsDir,
|
|
489
|
+
contextFile: contextFilePath,
|
|
481
490
|
enableLsp: false,
|
|
482
491
|
signal,
|
|
483
492
|
eventBus: undefined,
|
|
@@ -522,6 +531,7 @@ export class TaskTool implements AgentTool<typeof taskSchema, TaskToolDetails, T
|
|
|
522
531
|
sessionFile,
|
|
523
532
|
persistArtifacts: !!artifactsDir,
|
|
524
533
|
artifactsDir: effectiveArtifactsDir,
|
|
534
|
+
contextFile: contextFilePath,
|
|
525
535
|
enableLsp: false,
|
|
526
536
|
signal,
|
|
527
537
|
eventBus: undefined,
|
|
@@ -735,9 +745,7 @@ export class TaskTool implements AgentTool<typeof taskSchema, TaskToolDetails, T
|
|
|
735
745
|
duration: formatDuration(totalDuration),
|
|
736
746
|
summaries,
|
|
737
747
|
outputIds,
|
|
738
|
-
schemaOverridden,
|
|
739
748
|
agentName,
|
|
740
|
-
requiredSchema: agent.output ? JSON.stringify(agent.output) : "",
|
|
741
749
|
patchApplySummary,
|
|
742
750
|
});
|
|
743
751
|
|
package/src/tools/index.ts
CHANGED
|
@@ -173,6 +173,8 @@ export interface ToolSession {
|
|
|
173
173
|
};
|
|
174
174
|
/** Plan mode state (if active) */
|
|
175
175
|
getPlanModeState?: () => PlanModeState | undefined;
|
|
176
|
+
/** Get compact conversation context for subagents (excludes tool results, system prompts) */
|
|
177
|
+
getCompactContext?: () => string;
|
|
176
178
|
}
|
|
177
179
|
|
|
178
180
|
type ToolFactory = (session: ToolSession) => Tool | null | Promise<Tool | null>;
|