@oh-my-pi/pi-coding-agent 14.4.0 → 14.4.3
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 +70 -0
- package/package.json +7 -7
- package/src/cli.ts +0 -1
- package/src/config/prompt-templates.ts +1 -31
- package/src/config/settings-schema.ts +27 -37
- package/src/config/settings.ts +1 -1
- package/src/edit/index.ts +1 -53
- package/src/edit/line-hash.ts +13 -63
- package/src/edit/modes/atom.ts +334 -64
- package/src/edit/modes/hashline.ts +19 -26
- package/src/edit/renderer.ts +6 -8
- package/src/edit/streaming.ts +90 -114
- package/src/export/html/template.generated.ts +1 -1
- package/src/export/html/template.js +10 -15
- package/src/internal-urls/docs-index.generated.ts +1 -2
- package/src/lsp/defaults.json +142 -652
- package/src/modes/components/session-selector.ts +3 -3
- package/src/modes/components/settings-defs.ts +0 -5
- package/src/modes/components/tool-execution.ts +2 -5
- package/src/modes/controllers/btw-controller.ts +17 -105
- package/src/modes/controllers/todo-command-controller.ts +537 -0
- package/src/modes/interactive-mode.ts +35 -9
- package/src/modes/types.ts +2 -0
- package/src/modes/utils/ui-helpers.ts +17 -0
- package/src/prompts/system/irc-incoming.md +8 -0
- package/src/prompts/system/subagent-system-prompt.md +8 -0
- package/src/prompts/tools/ast-edit.md +1 -1
- package/src/prompts/tools/ast-grep.md +1 -0
- package/src/prompts/tools/atom.md +55 -53
- package/src/prompts/tools/bash.md +2 -2
- package/src/prompts/tools/grep.md +2 -5
- package/src/prompts/tools/irc.md +49 -0
- package/src/prompts/tools/job.md +11 -0
- package/src/prompts/tools/read.md +12 -13
- package/src/prompts/tools/task.md +1 -1
- package/src/prompts/tools/todo-write.md +14 -5
- package/src/registry/agent-registry.ts +139 -0
- package/src/sdk.ts +35 -0
- package/src/session/agent-session.ts +217 -5
- package/src/session/session-manager.ts +4 -1
- package/src/session/streaming-output.ts +1 -1
- package/src/slash-commands/builtin-registry.ts +24 -0
- package/src/task/executor.ts +14 -0
- package/src/tools/bash.ts +1 -1
- package/src/tools/fetch.ts +18 -6
- package/src/tools/fs-cache-invalidation.ts +0 -5
- package/src/tools/grep.ts +5 -125
- package/src/tools/index.ts +12 -6
- package/src/tools/irc.ts +258 -0
- package/src/tools/job.ts +489 -0
- package/src/tools/match-line-format.ts +8 -7
- package/src/tools/output-meta.ts +1 -1
- package/src/tools/read.ts +37 -131
- package/src/tools/renderers.ts +2 -0
- package/src/tools/todo-write.ts +243 -12
- package/src/tools/write.ts +2 -2
- package/src/utils/edit-mode.ts +1 -2
- package/src/utils/file-display-mode.ts +0 -3
- package/src/cli/read-cli.ts +0 -67
- package/src/commands/read.ts +0 -33
- package/src/edit/modes/chunk.ts +0 -832
- package/src/prompts/tools/cancel-job.md +0 -5
- package/src/prompts/tools/chunk-edit.md +0 -158
- package/src/prompts/tools/poll.md +0 -5
- package/src/prompts/tools/read-chunk.md +0 -73
- package/src/tools/cancel-job.ts +0 -95
- package/src/tools/poll-tool.ts +0 -173
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
truncateToWidth,
|
|
11
11
|
visibleWidth,
|
|
12
12
|
} from "@oh-my-pi/pi-tui";
|
|
13
|
+
import { formatBytes } from "@oh-my-pi/pi-utils";
|
|
13
14
|
import { theme } from "../../modes/theme/theme";
|
|
14
15
|
import { matchesAppInterrupt } from "../../modes/utils/keybinding-matchers";
|
|
15
16
|
import type { SessionInfo } from "../../session/session-manager";
|
|
@@ -157,10 +158,9 @@ class SessionList implements Component {
|
|
|
157
158
|
lines.push(messageLine);
|
|
158
159
|
}
|
|
159
160
|
|
|
160
|
-
// Metadata line: date +
|
|
161
|
+
// Metadata line: date + file size
|
|
161
162
|
const modified = formatDate(session.modified);
|
|
162
|
-
const
|
|
163
|
-
const metadata = ` ${modified} ${theme.sep.dot} ${msgCount}`;
|
|
163
|
+
const metadata = ` ${modified} ${theme.sep.dot} ${formatBytes(session.size)}`;
|
|
164
164
|
const metadataLine = theme.fg("dim", truncateToWidth(metadata, width));
|
|
165
165
|
|
|
166
166
|
lines.push(metadataLine);
|
|
@@ -298,11 +298,6 @@ const OPTION_PROVIDERS: Partial<Record<SettingPath, OptionProvider>> = {
|
|
|
298
298
|
{ value: "1000", label: "1000 lines" },
|
|
299
299
|
{ value: "5000", label: "5000 lines" },
|
|
300
300
|
],
|
|
301
|
-
"read.anchorstyle": [
|
|
302
|
-
{ value: "full", label: "Full", description: "Show the kind prefix and identifier" },
|
|
303
|
-
{ value: "kind", label: "Kind", description: "Show only the kind prefix plus checksum" },
|
|
304
|
-
{ value: "bare", label: "Bare", description: "Show only the checksum" },
|
|
305
|
-
],
|
|
306
301
|
// Todo auto-clear delay
|
|
307
302
|
"tasks.todoClearDelay": [
|
|
308
303
|
{ value: "0", label: "Instant" },
|
|
@@ -109,7 +109,7 @@ export class ToolExecutionComponent extends Container {
|
|
|
109
109
|
isError?: boolean;
|
|
110
110
|
details?: any;
|
|
111
111
|
};
|
|
112
|
-
// Edit preview state
|
|
112
|
+
// Edit preview state
|
|
113
113
|
#editMode?: EditMode;
|
|
114
114
|
#editDiffPreview?: PerFileDiffPreview[];
|
|
115
115
|
#editDiffScheduleTimer?: NodeJS.Timeout;
|
|
@@ -639,10 +639,7 @@ export class ToolExecutionComponent extends Container {
|
|
|
639
639
|
return this.#args;
|
|
640
640
|
}
|
|
641
641
|
// Single-file previews feed the existing `previewDiff` channel consumed
|
|
642
|
-
// by `formatStreamingDiff` in the renderer.
|
|
643
|
-
// piped via `renderContext.perFileDiffPreview`, so the args we hand to
|
|
644
|
-
// `renderCall` only need the first file's diff to preserve prior
|
|
645
|
-
// single-file behavior.
|
|
642
|
+
// by `formatStreamingDiff` in the renderer.
|
|
646
643
|
const first = previews[0];
|
|
647
644
|
if (!first?.diff) {
|
|
648
645
|
return this.#args;
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
import type { AgentMessage } from "@oh-my-pi/pi-agent-core";
|
|
2
|
-
import { type AssistantMessage, type Context, streamSimple } from "@oh-my-pi/pi-ai";
|
|
3
1
|
import { prompt } from "@oh-my-pi/pi-utils";
|
|
4
2
|
import btwUserPrompt from "../../prompts/system/btw-user.md" with { type: "text" };
|
|
5
|
-
import { toReasoningEffort } from "../../thinking";
|
|
6
3
|
import { BtwPanelComponent } from "../components/btw-panel";
|
|
7
4
|
import type { InteractiveModeContext } from "../types";
|
|
8
5
|
|
|
@@ -14,14 +11,8 @@ interface BtwRequest {
|
|
|
14
11
|
|
|
15
12
|
export class BtwController {
|
|
16
13
|
#activeRequest: BtwRequest | undefined;
|
|
17
|
-
readonly #streamFn: typeof streamSimple;
|
|
18
14
|
|
|
19
|
-
constructor(
|
|
20
|
-
private readonly ctx: InteractiveModeContext,
|
|
21
|
-
options?: { streamFn?: typeof streamSimple },
|
|
22
|
-
) {
|
|
23
|
-
this.#streamFn = options?.streamFn ?? streamSimple;
|
|
24
|
-
}
|
|
15
|
+
constructor(private readonly ctx: InteractiveModeContext) {}
|
|
25
16
|
|
|
26
17
|
hasActiveRequest(): boolean {
|
|
27
18
|
return this.#activeRequest !== undefined;
|
|
@@ -61,64 +52,29 @@ export class BtwController {
|
|
|
61
52
|
this.ctx.btwContainer.addChild(request.component);
|
|
62
53
|
this.ctx.ui.requestRender();
|
|
63
54
|
this.#activeRequest = request;
|
|
64
|
-
void this.#runRequest(request
|
|
55
|
+
void this.#runRequest(request);
|
|
65
56
|
}
|
|
66
57
|
|
|
67
|
-
async #runRequest(
|
|
68
|
-
request: BtwRequest,
|
|
69
|
-
model: NonNullable<InteractiveModeContext["session"]["model"]>,
|
|
70
|
-
): Promise<void> {
|
|
58
|
+
async #runRequest(request: BtwRequest): Promise<void> {
|
|
71
59
|
try {
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
);
|
|
81
|
-
const context: Context = {
|
|
82
|
-
systemPrompt: this.ctx.session.systemPrompt,
|
|
83
|
-
messages: llmMessages,
|
|
84
|
-
};
|
|
85
|
-
const options = this.ctx.session.prepareSimpleStreamOptions({
|
|
86
|
-
apiKey,
|
|
87
|
-
sessionId: this.ctx.session.sessionId,
|
|
88
|
-
reasoning: toReasoningEffort(this.ctx.session.thinkingLevel),
|
|
89
|
-
serviceTier: this.ctx.session.serviceTier,
|
|
60
|
+
const promptText = prompt.render(btwUserPrompt, { question: request.question });
|
|
61
|
+
const { replyText } = await this.ctx.session.runEphemeralTurn({
|
|
62
|
+
promptText,
|
|
63
|
+
onTextDelta: delta => {
|
|
64
|
+
if (this.#isActiveRequest(request)) {
|
|
65
|
+
request.component.appendText(delta);
|
|
66
|
+
}
|
|
67
|
+
},
|
|
90
68
|
signal: request.abortController.signal,
|
|
91
|
-
toolChoice: "none",
|
|
92
69
|
});
|
|
93
|
-
const stream = this.#streamFn(model, context, options);
|
|
94
70
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
return;
|
|
98
|
-
}
|
|
99
|
-
if (event.type === "text_delta") {
|
|
100
|
-
request.component.appendText(event.delta);
|
|
101
|
-
continue;
|
|
102
|
-
}
|
|
103
|
-
if (event.type === "done") {
|
|
104
|
-
const finalText = this.#assistantText(event.message);
|
|
105
|
-
if (finalText) {
|
|
106
|
-
request.component.setAnswer(finalText);
|
|
107
|
-
}
|
|
108
|
-
request.component.markComplete();
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
if (event.type === "error") {
|
|
112
|
-
if (event.reason === "aborted" || request.abortController.signal.aborted) {
|
|
113
|
-
request.component.markAborted();
|
|
114
|
-
} else {
|
|
115
|
-
request.component.markError(
|
|
116
|
-
this.#assistantText(event.error) || event.error.errorMessage || "BTW request failed.",
|
|
117
|
-
);
|
|
118
|
-
}
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
71
|
+
if (!this.#isActiveRequest(request)) {
|
|
72
|
+
return;
|
|
121
73
|
}
|
|
74
|
+
if (replyText) {
|
|
75
|
+
request.component.setAnswer(replyText);
|
|
76
|
+
}
|
|
77
|
+
request.component.markComplete();
|
|
122
78
|
} catch (error) {
|
|
123
79
|
if (!this.#isActiveRequest(request)) {
|
|
124
80
|
return;
|
|
@@ -131,50 +87,6 @@ export class BtwController {
|
|
|
131
87
|
}
|
|
132
88
|
}
|
|
133
89
|
|
|
134
|
-
#buildQuestionMessage(question: string): AgentMessage {
|
|
135
|
-
return {
|
|
136
|
-
role: "user",
|
|
137
|
-
content: [
|
|
138
|
-
{
|
|
139
|
-
type: "text",
|
|
140
|
-
text: prompt.render(btwUserPrompt, { question }),
|
|
141
|
-
},
|
|
142
|
-
],
|
|
143
|
-
attribution: "user",
|
|
144
|
-
timestamp: Date.now(),
|
|
145
|
-
};
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
#buildMessageSnapshot(): AgentMessage[] {
|
|
149
|
-
const messages = this.ctx.session.messages.slice();
|
|
150
|
-
if (!this.ctx.session.isStreaming || !this.ctx.streamingMessage) {
|
|
151
|
-
return messages;
|
|
152
|
-
}
|
|
153
|
-
const streamingText = this.ctx.extractAssistantText(this.ctx.streamingMessage);
|
|
154
|
-
const lastMessage = messages.at(-1);
|
|
155
|
-
if (!streamingText) {
|
|
156
|
-
return lastMessage?.role === "assistant" ? messages.slice(0, -1) : messages;
|
|
157
|
-
}
|
|
158
|
-
const normalizedStreamingMessage: AssistantMessage = {
|
|
159
|
-
...this.ctx.streamingMessage,
|
|
160
|
-
content: [{ type: "text", text: streamingText }],
|
|
161
|
-
};
|
|
162
|
-
if (lastMessage?.role === "assistant") {
|
|
163
|
-
return [...messages.slice(0, -1), normalizedStreamingMessage];
|
|
164
|
-
}
|
|
165
|
-
return [...messages, normalizedStreamingMessage];
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
#assistantText(message: AssistantMessage): string {
|
|
169
|
-
let text = "";
|
|
170
|
-
for (const content of message.content) {
|
|
171
|
-
if (content.type === "text") {
|
|
172
|
-
text += content.text;
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
return text.trim();
|
|
176
|
-
}
|
|
177
|
-
|
|
178
90
|
#closeActiveRequest(options: { abort: boolean }): void {
|
|
179
91
|
const request = this.#activeRequest;
|
|
180
92
|
if (!request) return;
|