@oh-my-pi/pi-coding-agent 15.9.67 → 15.10.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 +136 -0
- package/dist/types/cli/args.d.ts +1 -1
- package/dist/types/cli/dry-balance-cli.d.ts +15 -1
- package/dist/types/cli/gallery-cli.d.ts +43 -0
- package/dist/types/cli/gallery-fixtures/agentic.d.ts +2 -0
- package/dist/types/cli/gallery-fixtures/codeintel.d.ts +3 -0
- package/dist/types/cli/gallery-fixtures/edit.d.ts +3 -0
- package/dist/types/cli/gallery-fixtures/fs.d.ts +2 -0
- package/dist/types/cli/gallery-fixtures/index.d.ts +4 -0
- package/dist/types/cli/gallery-fixtures/interaction.d.ts +3 -0
- package/dist/types/cli/gallery-fixtures/memory.d.ts +2 -0
- package/dist/types/cli/gallery-fixtures/misc.d.ts +3 -0
- package/dist/types/cli/gallery-fixtures/search.d.ts +3 -0
- package/dist/types/cli/gallery-fixtures/shell.d.ts +3 -0
- package/dist/types/cli/gallery-fixtures/types.d.ts +44 -0
- package/dist/types/cli/gallery-fixtures/web.d.ts +2 -0
- package/dist/types/cli/gallery-screenshot.d.ts +35 -0
- package/dist/types/commands/gallery.d.ts +47 -0
- package/dist/types/commit/analysis/conventional.d.ts +2 -2
- package/dist/types/commit/analysis/summary.d.ts +2 -2
- package/dist/types/commit/changelog/generate.d.ts +2 -2
- package/dist/types/commit/changelog/index.d.ts +2 -2
- package/dist/types/commit/map-reduce/index.d.ts +3 -3
- package/dist/types/commit/map-reduce/map-phase.d.ts +2 -2
- package/dist/types/commit/map-reduce/reduce-phase.d.ts +2 -2
- package/dist/types/commit/model-selection.d.ts +10 -4
- package/dist/types/config/api-key-resolver.d.ts +34 -0
- package/dist/types/config/keybindings.d.ts +6 -1
- package/dist/types/config/model-id-affixes.d.ts +2 -0
- package/dist/types/config/model-registry.d.ts +25 -2
- package/dist/types/config/settings-schema.d.ts +41 -6
- package/dist/types/dap/config.d.ts +14 -1
- package/dist/types/dap/types.d.ts +10 -0
- package/dist/types/extensibility/plugins/marketplace-auto-update.d.ts +8 -0
- package/dist/types/lsp/types.d.ts +10 -0
- package/dist/types/lsp/utils.d.ts +3 -2
- package/dist/types/main.d.ts +3 -2
- package/dist/types/memory-backend/index.d.ts +2 -1
- package/dist/types/memory-backend/resolve.d.ts +1 -1
- package/dist/types/memory-backend/types.d.ts +1 -1
- package/dist/types/modes/components/chat-block.d.ts +64 -0
- package/dist/types/modes/components/custom-editor.d.ts +5 -1
- package/dist/types/modes/components/overlay-box.d.ts +17 -0
- package/dist/types/modes/components/plan-review-overlay.d.ts +59 -0
- package/dist/types/modes/components/plan-toc.d.ts +41 -0
- package/dist/types/modes/components/read-tool-group.d.ts +2 -0
- package/dist/types/modes/components/tool-execution.d.ts +18 -0
- package/dist/types/modes/components/transcript-container.d.ts +11 -0
- package/dist/types/modes/controllers/command-controller.d.ts +1 -0
- package/dist/types/modes/controllers/event-controller.d.ts +0 -1
- package/dist/types/modes/controllers/extension-ui-controller.d.ts +0 -1
- package/dist/types/modes/controllers/input-controller.d.ts +1 -1
- package/dist/types/modes/controllers/selector-controller.d.ts +1 -1
- package/dist/types/modes/controllers/streaming-reveal.d.ts +22 -0
- package/dist/types/modes/controllers/tan-command-controller.d.ts +6 -0
- package/dist/types/modes/index.d.ts +5 -4
- package/dist/types/modes/interactive-mode.d.ts +16 -6
- package/dist/types/modes/setup-version.d.ts +11 -0
- package/dist/types/modes/setup-wizard/index.d.ts +2 -1
- package/dist/types/modes/setup-wizard/scenes/web-search.d.ts +2 -1
- package/dist/types/modes/theme/theme.d.ts +1 -1
- package/dist/types/modes/types.d.ts +19 -6
- package/dist/types/modes/utils/copy-targets.d.ts +21 -1
- package/dist/types/plan-mode/approved-plan.d.ts +27 -8
- package/dist/types/plan-mode/plan-protection.d.ts +4 -4
- package/dist/types/sdk.d.ts +3 -1
- package/dist/types/session/agent-session.d.ts +21 -0
- package/dist/types/session/messages.d.ts +12 -0
- package/dist/types/session/session-manager.d.ts +3 -1
- package/dist/types/slash-commands/types.d.ts +4 -6
- package/dist/types/task/executor.d.ts +14 -0
- package/dist/types/task/index.d.ts +1 -0
- package/dist/types/task/render.d.ts +3 -2
- package/dist/types/telemetry-export.d.ts +1 -1
- package/dist/types/tools/archive-reader.d.ts +5 -0
- package/dist/types/tools/ast-edit.d.ts +3 -0
- package/dist/types/tools/ast-grep.d.ts +3 -0
- package/dist/types/tools/bash.d.ts +1 -0
- package/dist/types/tools/eval-render.d.ts +1 -8
- package/dist/types/tools/fetch.d.ts +15 -7
- package/dist/types/tools/find.d.ts +8 -4
- package/dist/types/tools/grouped-file-output.d.ts +95 -12
- package/dist/types/tools/memory-render.d.ts +4 -1
- package/dist/types/tools/plan-mode-guard.d.ts +8 -9
- package/dist/types/tools/render-utils.d.ts +13 -9
- package/dist/types/tools/renderers.d.ts +16 -2
- package/dist/types/tools/search.d.ts +5 -1
- package/dist/types/tools/sqlite-reader.d.ts +1 -0
- package/dist/types/tools/todo.d.ts +3 -2
- package/dist/types/tools/write.d.ts +5 -0
- package/dist/types/tui/output-block.d.ts +16 -4
- package/dist/types/tui/status-line.d.ts +3 -0
- package/dist/types/utils/enhanced-paste.d.ts +20 -0
- package/dist/types/web/scrapers/github.d.ts +22 -0
- package/dist/types/web/search/providers/kimi.d.ts +1 -1
- package/dist/types/web/search/providers/perplexity.d.ts +8 -1
- package/dist/types/web/search/types.d.ts +1 -1
- package/package.json +9 -9
- package/scripts/dev-launch +42 -0
- package/scripts/dev-launch-preload.ts +19 -0
- package/src/auto-thinking/classifier.ts +5 -1
- package/src/cli/args.ts +2 -2
- package/src/cli/dry-balance-cli.ts +52 -17
- package/src/cli/gallery-cli.ts +226 -0
- package/src/cli/gallery-fixtures/agentic.ts +292 -0
- package/src/cli/gallery-fixtures/codeintel.ts +188 -0
- package/src/cli/gallery-fixtures/edit.ts +194 -0
- package/src/cli/gallery-fixtures/fs.ts +153 -0
- package/src/cli/gallery-fixtures/index.ts +40 -0
- package/src/cli/gallery-fixtures/interaction.ts +49 -0
- package/src/cli/gallery-fixtures/memory.ts +81 -0
- package/src/cli/gallery-fixtures/misc.ts +250 -0
- package/src/cli/gallery-fixtures/search.ts +213 -0
- package/src/cli/gallery-fixtures/shell.ts +167 -0
- package/src/cli/gallery-fixtures/types.ts +41 -0
- package/src/cli/gallery-fixtures/web.ts +158 -0
- package/src/cli/gallery-screenshot.ts +279 -0
- package/src/cli-commands.ts +1 -0
- package/src/commands/gallery.ts +52 -0
- package/src/commands/launch.ts +1 -1
- package/src/commit/analysis/conventional.ts +2 -2
- package/src/commit/analysis/summary.ts +2 -2
- package/src/commit/changelog/generate.ts +2 -2
- package/src/commit/changelog/index.ts +2 -2
- package/src/commit/map-reduce/index.ts +3 -3
- package/src/commit/map-reduce/map-phase.ts +2 -2
- package/src/commit/map-reduce/reduce-phase.ts +2 -2
- package/src/commit/model-selection.ts +33 -9
- package/src/commit/pipeline.ts +4 -4
- package/src/config/api-key-resolver.ts +58 -0
- package/src/config/keybindings.ts +15 -6
- package/src/config/model-equivalence.ts +35 -12
- package/src/config/model-id-affixes.ts +39 -22
- package/src/config/model-registry.ts +41 -18
- package/src/config/settings-schema.ts +28 -5
- package/src/config/settings.ts +31 -2
- package/src/dap/client.ts +14 -16
- package/src/dap/config.ts +41 -2
- package/src/dap/defaults.json +1 -0
- package/src/dap/session.ts +1 -0
- package/src/dap/types.ts +10 -0
- package/src/debug/index.ts +40 -54
- package/src/edit/renderer.ts +111 -119
- package/src/eval/__tests__/agent-bridge.test.ts +75 -32
- package/src/eval/__tests__/llm-bridge.test.ts +90 -31
- package/src/eval/agent-bridge.ts +34 -7
- package/src/eval/llm-bridge.ts +8 -3
- package/src/extensibility/extensions/runner.ts +1 -0
- package/src/extensibility/plugins/doctor.ts +0 -1
- package/src/extensibility/plugins/marketplace-auto-update.ts +49 -0
- package/src/goals/tools/goal-tool.ts +37 -27
- package/src/internal-urls/docs-index.generated.ts +10 -10
- package/src/lsp/client.ts +104 -55
- package/src/lsp/types.ts +10 -0
- package/src/lsp/utils.ts +3 -2
- package/src/main.ts +53 -56
- package/src/memories/index.ts +12 -5
- package/src/memory-backend/index.ts +13 -1
- package/src/memory-backend/resolve.ts +3 -5
- package/src/memory-backend/types.ts +1 -1
- package/src/mnemopi/backend.ts +5 -1
- package/src/modes/acp/acp-agent.ts +33 -26
- package/src/modes/components/assistant-message.ts +2 -9
- package/src/modes/components/chat-block.ts +111 -0
- package/src/modes/components/copy-selector.ts +1 -44
- package/src/modes/components/custom-editor.ts +33 -1
- package/src/modes/components/custom-message.ts +1 -3
- package/src/modes/components/execution-shared.ts +1 -2
- package/src/modes/components/hook-message.ts +1 -3
- package/src/modes/components/overlay-box.ts +108 -0
- package/src/modes/components/plan-review-overlay.ts +799 -0
- package/src/modes/components/plan-toc.ts +138 -0
- package/src/modes/components/read-tool-group.ts +20 -4
- package/src/modes/components/skill-message.ts +0 -1
- package/src/modes/components/status-line.ts +3 -5
- package/src/modes/components/tips.txt +1 -0
- package/src/modes/components/todo-reminder.ts +0 -2
- package/src/modes/components/tool-execution.ts +115 -90
- package/src/modes/components/transcript-container.ts +84 -24
- package/src/modes/components/user-message.ts +1 -2
- package/src/modes/controllers/command-controller-shared.ts +7 -6
- package/src/modes/controllers/command-controller.ts +70 -57
- package/src/modes/controllers/event-controller.ts +41 -40
- package/src/modes/controllers/extension-ui-controller.ts +10 -73
- package/src/modes/controllers/input-controller.ts +135 -122
- package/src/modes/controllers/mcp-command-controller.ts +69 -60
- package/src/modes/controllers/selector-controller.ts +25 -27
- package/src/modes/controllers/streaming-reveal.ts +212 -0
- package/src/modes/controllers/tan-command-controller.ts +173 -0
- package/src/modes/index.ts +5 -4
- package/src/modes/interactive-mode.ts +171 -82
- package/src/modes/setup-version.ts +11 -0
- package/src/modes/setup-wizard/index.ts +3 -2
- package/src/modes/setup-wizard/scenes/web-search.ts +3 -2
- package/src/modes/setup-wizard/wizard-overlay.ts +1 -1
- package/src/modes/theme/theme-schema.json +1 -1
- package/src/modes/theme/theme.ts +8 -4
- package/src/modes/types.ts +19 -8
- package/src/modes/utils/context-usage.ts +10 -6
- package/src/modes/utils/copy-targets.ts +133 -27
- package/src/modes/utils/hotkeys-markdown.ts +1 -0
- package/src/modes/utils/ui-helpers.ts +44 -46
- package/src/plan-mode/approved-plan.ts +66 -43
- package/src/plan-mode/plan-protection.ts +4 -4
- package/src/prompts/system/background-tan-dispatch.md +8 -0
- package/src/prompts/system/plan-mode-active.md +67 -58
- package/src/prompts/system/plan-mode-approved.md +1 -1
- package/src/sdk.ts +32 -60
- package/src/session/agent-session.ts +89 -13
- package/src/session/messages.ts +26 -0
- package/src/session/session-manager.ts +13 -5
- package/src/slash-commands/builtin-registry.ts +37 -10
- package/src/slash-commands/helpers/usage-report.ts +2 -0
- package/src/slash-commands/types.ts +4 -6
- package/src/task/executor.ts +25 -4
- package/src/task/index.ts +4 -0
- package/src/task/render.ts +212 -148
- package/src/telemetry-export.ts +25 -7
- package/src/tools/archive-reader.ts +64 -0
- package/src/tools/ask.ts +119 -164
- package/src/tools/ast-edit.ts +98 -71
- package/src/tools/ast-grep.ts +37 -43
- package/src/tools/bash.ts +50 -6
- package/src/tools/debug.ts +20 -8
- package/src/tools/eval-backends.ts +6 -17
- package/src/tools/eval-render.ts +21 -18
- package/src/tools/eval.ts +5 -4
- package/src/tools/fetch.ts +391 -91
- package/src/tools/find.ts +44 -30
- package/src/tools/gh-renderer.ts +81 -42
- package/src/tools/grouped-file-output.ts +272 -48
- package/src/tools/image-gen.ts +150 -103
- package/src/tools/inspect-image-renderer.ts +63 -41
- package/src/tools/inspect-image.ts +8 -1
- package/src/tools/job.ts +3 -4
- package/src/tools/memory-render.ts +4 -1
- package/src/tools/plan-mode-guard.ts +21 -39
- package/src/tools/read.ts +23 -16
- package/src/tools/render-utils.ts +38 -40
- package/src/tools/renderers.ts +16 -1
- package/src/tools/report-tool-issue.ts +1 -1
- package/src/tools/resolve.ts +14 -0
- package/src/tools/search-tool-bm25.ts +36 -23
- package/src/tools/search.ts +189 -95
- package/src/tools/sqlite-reader.ts +9 -12
- package/src/tools/todo.ts +138 -59
- package/src/tools/write.ts +100 -60
- package/src/tui/output-block.ts +60 -13
- package/src/tui/status-line.ts +5 -1
- package/src/utils/commit-message-generator.ts +9 -1
- package/src/utils/enhanced-paste.ts +202 -0
- package/src/utils/title-generator.ts +2 -1
- package/src/web/scrapers/github.ts +255 -3
- package/src/web/scrapers/youtube.ts +3 -2
- package/src/web/search/providers/anthropic.ts +25 -19
- package/src/web/search/providers/exa.ts +11 -3
- package/src/web/search/providers/kimi.ts +28 -17
- package/src/web/search/providers/parallel.ts +35 -24
- package/src/web/search/providers/perplexity.ts +199 -51
- package/src/web/search/providers/synthetic.ts +8 -6
- package/src/web/search/providers/tavily.ts +9 -8
- package/src/web/search/providers/zai.ts +8 -6
- package/src/web/search/render.ts +39 -54
- package/src/web/search/types.ts +5 -1
- package/dist/types/eval/__tests__/shared-executors.test.d.ts +0 -1
- package/src/eval/__tests__/shared-executors.test.ts +0 -609
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { INTENT_FIELD } from "@oh-my-pi/pi-agent-core";
|
|
2
2
|
import { calculatePromptTokens } from "@oh-my-pi/pi-agent-core/compaction/compaction";
|
|
3
3
|
import type { AssistantMessage, ImageContent } from "@oh-my-pi/pi-ai";
|
|
4
|
-
import { type Component, Loader, TERMINAL
|
|
4
|
+
import { type Component, Loader, TERMINAL } from "@oh-my-pi/pi-tui";
|
|
5
5
|
import { settings } from "../../config/settings";
|
|
6
6
|
import { getFileSnapshotStore } from "../../edit/file-snapshot-store";
|
|
7
7
|
import { AssistantMessageComponent } from "../../modes/components/assistant-message";
|
|
@@ -17,9 +17,10 @@ import { getSymbolTheme, theme } from "../../modes/theme/theme";
|
|
|
17
17
|
import type { InteractiveModeContext, TodoPhase } from "../../modes/types";
|
|
18
18
|
import type { PlanApprovalDetails } from "../../plan-mode/approved-plan";
|
|
19
19
|
import type { AgentSessionEvent } from "../../session/agent-session";
|
|
20
|
-
import { isSilentAbort, readPendingDisplayTag } from "../../session/messages";
|
|
20
|
+
import { isSilentAbort, readPendingDisplayTag, resolveAbortLabel } from "../../session/messages";
|
|
21
21
|
import type { ResolveToolDetails } from "../../tools/resolve";
|
|
22
22
|
import { interruptHint } from "../shared";
|
|
23
|
+
import { StreamingRevealController } from "./streaming-reveal";
|
|
23
24
|
|
|
24
25
|
type AgentSessionEventKind = AgentSessionEvent["type"];
|
|
25
26
|
|
|
@@ -44,7 +45,13 @@ type AgentSessionEventHandlers = {
|
|
|
44
45
|
|
|
45
46
|
export class EventController {
|
|
46
47
|
#lastReadGroup: ReadToolGroupComponent | undefined = undefined;
|
|
47
|
-
|
|
48
|
+
// Count of visible assistant content blocks (rendered non-empty text/thinking)
|
|
49
|
+
// already seen in the current streaming message. A newly appearing one breaks
|
|
50
|
+
// the read run: the rendered reasoning/answer is a visual separator, so reads
|
|
51
|
+
// after it start a fresh group. Empty/absent thinking — common when a model
|
|
52
|
+
// emits one read per completion — does not break it, so a run of consecutive
|
|
53
|
+
// reads collapses into one group even across completion boundaries.
|
|
54
|
+
#lastVisibleBlockCount = 0;
|
|
48
55
|
#renderedCustomMessages = new Set<string>();
|
|
49
56
|
#lastIntent: string | undefined = undefined;
|
|
50
57
|
#backgroundToolCallIds = new Set<string>();
|
|
@@ -60,9 +67,15 @@ export class EventController {
|
|
|
60
67
|
#pinnedErrorComponent: AssistantMessageComponent | undefined = undefined;
|
|
61
68
|
#idleCompactionTimer?: NodeJS.Timeout;
|
|
62
69
|
#ircExpiryTimers = new Map<string, NodeJS.Timeout>();
|
|
70
|
+
#streamingReveal: StreamingRevealController;
|
|
63
71
|
#handlers: AgentSessionEventHandlers;
|
|
64
72
|
|
|
65
73
|
constructor(private ctx: InteractiveModeContext) {
|
|
74
|
+
this.#streamingReveal = new StreamingRevealController({
|
|
75
|
+
getSmoothStreaming: () => this.ctx.settings.get("display.smoothStreaming"),
|
|
76
|
+
getHideThinkingBlock: () => this.ctx.hideThinkingBlock,
|
|
77
|
+
requestRender: () => this.ctx.ui.requestRender(),
|
|
78
|
+
});
|
|
66
79
|
this.#handlers = {
|
|
67
80
|
agent_start: e => this.#handleAgentStart(e),
|
|
68
81
|
agent_end: e => this.#handleAgentEnd(e),
|
|
@@ -95,6 +108,7 @@ export class EventController {
|
|
|
95
108
|
}
|
|
96
109
|
|
|
97
110
|
dispose(): void {
|
|
111
|
+
this.#streamingReveal.stop();
|
|
98
112
|
this.#cancelIdleCompaction();
|
|
99
113
|
for (const timer of this.#ircExpiryTimers.values()) {
|
|
100
114
|
clearTimeout(timer);
|
|
@@ -103,12 +117,12 @@ export class EventController {
|
|
|
103
117
|
}
|
|
104
118
|
|
|
105
119
|
#resetReadGroup(): void {
|
|
120
|
+
this.#lastReadGroup?.finalize();
|
|
106
121
|
this.#lastReadGroup = undefined;
|
|
107
122
|
}
|
|
108
123
|
|
|
109
124
|
#getReadGroup(): ReadToolGroupComponent {
|
|
110
125
|
if (!this.#lastReadGroup) {
|
|
111
|
-
this.ctx.chatContainer.addChild(new Text("", 0, 0));
|
|
112
126
|
const group = new ReadToolGroupComponent({
|
|
113
127
|
showContentPreview: this.ctx.settings.get("read.toolResultPreview"),
|
|
114
128
|
});
|
|
@@ -209,6 +223,7 @@ export class EventController {
|
|
|
209
223
|
this.#lastIntent = undefined;
|
|
210
224
|
this.#readToolCallArgs.clear();
|
|
211
225
|
this.#readToolCallAssistantComponents.clear();
|
|
226
|
+
this.#resetReadGroup();
|
|
212
227
|
this.#assistantMessageStreaming = false;
|
|
213
228
|
this.#lastAssistantComponent = undefined;
|
|
214
229
|
// Restore the previous turn's inline error in the transcript before dropping
|
|
@@ -299,9 +314,8 @@ export class EventController {
|
|
|
299
314
|
this.ctx.addMessageToChat(event.message);
|
|
300
315
|
this.ctx.ui.requestRender();
|
|
301
316
|
} else if (event.message.role === "assistant") {
|
|
302
|
-
this.#lastThinkingCount = 0;
|
|
303
317
|
this.#assistantMessageStreaming = true;
|
|
304
|
-
this.#
|
|
318
|
+
this.#lastVisibleBlockCount = 0;
|
|
305
319
|
this.ctx.streamingComponent = new AssistantMessageComponent(
|
|
306
320
|
undefined,
|
|
307
321
|
this.ctx.hideThinkingBlock,
|
|
@@ -311,7 +325,7 @@ export class EventController {
|
|
|
311
325
|
);
|
|
312
326
|
this.ctx.streamingMessage = event.message;
|
|
313
327
|
this.ctx.chatContainer.addChild(this.ctx.streamingComponent);
|
|
314
|
-
this.ctx.streamingComponent
|
|
328
|
+
this.#streamingReveal.begin(this.ctx.streamingComponent, this.ctx.streamingMessage);
|
|
315
329
|
this.ctx.ui.requestRender();
|
|
316
330
|
}
|
|
317
331
|
}
|
|
@@ -355,16 +369,17 @@ export class EventController {
|
|
|
355
369
|
async #handleMessageUpdate(event: Extract<AgentSessionEvent, { type: "message_update" }>): Promise<void> {
|
|
356
370
|
if (this.ctx.streamingComponent && event.message.role === "assistant") {
|
|
357
371
|
this.ctx.streamingMessage = event.message;
|
|
358
|
-
this.
|
|
372
|
+
this.#streamingReveal.setTarget(this.ctx.streamingMessage);
|
|
359
373
|
|
|
360
|
-
const
|
|
361
|
-
content =>
|
|
374
|
+
const visibleBlockCount = this.ctx.streamingMessage.content.filter(
|
|
375
|
+
content =>
|
|
376
|
+
(content.type === "text" && content.text.trim().length > 0) ||
|
|
377
|
+
(content.type === "thinking" && content.thinking.trim().length > 0),
|
|
362
378
|
).length;
|
|
363
|
-
if (
|
|
379
|
+
if (visibleBlockCount > this.#lastVisibleBlockCount) {
|
|
364
380
|
this.#resetReadGroup();
|
|
365
|
-
this.#
|
|
381
|
+
this.#lastVisibleBlockCount = visibleBlockCount;
|
|
366
382
|
}
|
|
367
|
-
|
|
368
383
|
for (const content of this.ctx.streamingMessage.content) {
|
|
369
384
|
if (content.type !== "toolCall") continue;
|
|
370
385
|
if (content.name === "read") {
|
|
@@ -397,7 +412,6 @@ export class EventController {
|
|
|
397
412
|
: content.arguments;
|
|
398
413
|
if (!this.ctx.pendingTools.has(content.id)) {
|
|
399
414
|
this.#resetReadGroup();
|
|
400
|
-
this.ctx.chatContainer.addChild(new Text("", 0, 0));
|
|
401
415
|
const tool = this.ctx.session.getToolByName(content.name);
|
|
402
416
|
const component = new ToolExecutionComponent(
|
|
403
417
|
content.name,
|
|
@@ -456,21 +470,20 @@ export class EventController {
|
|
|
456
470
|
}
|
|
457
471
|
if (this.ctx.streamingComponent && event.message.role === "assistant") {
|
|
458
472
|
this.ctx.streamingMessage = event.message;
|
|
473
|
+
this.#streamingReveal.stop();
|
|
459
474
|
let errorMessage: string | undefined;
|
|
460
475
|
const aborted = this.ctx.streamingMessage.stopReason === "aborted";
|
|
461
476
|
const silentlyAborted = aborted && isSilentAbort(this.ctx.streamingMessage.errorMessage);
|
|
462
477
|
const ttsrSilenced = aborted && this.ctx.session.isTtsrAbortPending;
|
|
463
478
|
if (aborted && !silentlyAborted && !ttsrSilenced) {
|
|
464
|
-
//
|
|
465
|
-
//
|
|
466
|
-
//
|
|
467
|
-
//
|
|
468
|
-
//
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
? `Aborted after ${retryAttempt} retry attempt${retryAttempt > 1 ? "s" : ""}`
|
|
473
|
-
: "Operation aborted";
|
|
479
|
+
// Resolve the operator-facing label: a user-interrupt (Esc) abort
|
|
480
|
+
// carries USER_INTERRUPT_LABEL on errorMessage (threaded through the
|
|
481
|
+
// AbortController), which is preserved verbatim; any other abort with
|
|
482
|
+
// no threaded reason falls back to the retry-aware generic label.
|
|
483
|
+
// AgentSession.#handleAgentEvent already stamped SILENT_ABORT_MARKER for
|
|
484
|
+
// the plan-compact transition before this controller ran, so reaching
|
|
485
|
+
// this branch implies the abort was NOT a silent internal transition.
|
|
486
|
+
errorMessage = resolveAbortLabel(this.ctx.streamingMessage.errorMessage, this.ctx.session.retryAttempt);
|
|
474
487
|
this.ctx.streamingMessage.errorMessage = errorMessage;
|
|
475
488
|
}
|
|
476
489
|
if (silentlyAborted || ttsrSilenced) {
|
|
@@ -663,6 +676,7 @@ export class EventController {
|
|
|
663
676
|
async #handleAgentEnd(_event: Extract<AgentSessionEvent, { type: "agent_end" }>): Promise<void> {
|
|
664
677
|
this.#agentTurnActive = false;
|
|
665
678
|
this.#assistantMessageStreaming = false;
|
|
679
|
+
this.#streamingReveal.stop();
|
|
666
680
|
if (this.ctx.loadingAnimation) {
|
|
667
681
|
this.ctx.loadingAnimation.stop();
|
|
668
682
|
this.ctx.loadingAnimation = undefined;
|
|
@@ -689,6 +703,7 @@ export class EventController {
|
|
|
689
703
|
);
|
|
690
704
|
this.#readToolCallArgs.clear();
|
|
691
705
|
this.#readToolCallAssistantComponents.clear();
|
|
706
|
+
this.#resetReadGroup();
|
|
692
707
|
this.#lastAssistantComponent = undefined;
|
|
693
708
|
this.ctx.ui.requestRender();
|
|
694
709
|
this.#scheduleIdleCompaction();
|
|
@@ -832,14 +847,12 @@ export class EventController {
|
|
|
832
847
|
async #handleTtsrTriggered(event: Extract<AgentSessionEvent, { type: "ttsr_triggered" }>): Promise<void> {
|
|
833
848
|
const component = new TtsrNotificationComponent(event.rules);
|
|
834
849
|
component.setExpanded(this.ctx.toolOutputExpanded);
|
|
835
|
-
this.ctx.
|
|
836
|
-
this.ctx.ui.requestRender();
|
|
850
|
+
this.ctx.present(component);
|
|
837
851
|
}
|
|
838
852
|
|
|
839
853
|
async #handleTodoReminder(event: Extract<AgentSessionEvent, { type: "todo_reminder" }>): Promise<void> {
|
|
840
854
|
const component = new TodoReminderComponent(event.todos, event.attempt, event.maxAttempts);
|
|
841
|
-
this.ctx.
|
|
842
|
-
this.ctx.ui.requestRender();
|
|
855
|
+
this.ctx.present(component);
|
|
843
856
|
}
|
|
844
857
|
|
|
845
858
|
async #handleTodoAutoClear(_event: Extract<AgentSessionEvent, { type: "todo_auto_clear" }>): Promise<void> {
|
|
@@ -892,7 +905,6 @@ export class EventController {
|
|
|
892
905
|
}
|
|
893
906
|
|
|
894
907
|
sendCompletionNotification(): void {
|
|
895
|
-
if (this.ctx.isBackgrounded === false) return;
|
|
896
908
|
const notify = settings.get("completion.notify");
|
|
897
909
|
if (notify === "off") return;
|
|
898
910
|
|
|
@@ -911,15 +923,4 @@ export class EventController {
|
|
|
911
923
|
actions: "focus",
|
|
912
924
|
});
|
|
913
925
|
}
|
|
914
|
-
|
|
915
|
-
async handleBackgroundEvent(event: AgentSessionEvent): Promise<void> {
|
|
916
|
-
if (event.type !== "agent_end") {
|
|
917
|
-
return;
|
|
918
|
-
}
|
|
919
|
-
if (this.ctx.session.queuedMessageCount > 0 || this.ctx.session.isStreaming) {
|
|
920
|
-
return;
|
|
921
|
-
}
|
|
922
|
-
this.sendCompletionNotification();
|
|
923
|
-
await this.ctx.shutdown();
|
|
924
|
-
}
|
|
925
926
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { Component, OverlayHandle, TUI } from "@oh-my-pi/pi-tui";
|
|
2
2
|
import { Container, Spacer, Text } from "@oh-my-pi/pi-tui";
|
|
3
|
-
import { logger } from "@oh-my-pi/pi-utils";
|
|
4
3
|
import { KeybindingsManager } from "../../config/keybindings";
|
|
5
4
|
import type {
|
|
6
5
|
CompactOptions,
|
|
@@ -176,10 +175,10 @@ export class ExtensionUiController {
|
|
|
176
175
|
this.ctx.streamingMessage = undefined;
|
|
177
176
|
this.ctx.pendingTools.clear();
|
|
178
177
|
|
|
179
|
-
this.ctx.
|
|
180
|
-
|
|
178
|
+
this.ctx.present([
|
|
179
|
+
new Spacer(1),
|
|
181
180
|
new Text(`${theme.fg("accent", `${theme.status.success} New session started`)}`, 1, 1),
|
|
182
|
-
);
|
|
181
|
+
]);
|
|
183
182
|
await this.ctx.reloadTodos();
|
|
184
183
|
this.ctx.ui.requestRender(true, { clearScrollback: true });
|
|
185
184
|
|
|
@@ -326,10 +325,6 @@ export class ExtensionUiController {
|
|
|
326
325
|
.then(() => this.#applyCustomMessageDisplay(wasStreaming, message.display))
|
|
327
326
|
.catch((err: unknown) => {
|
|
328
327
|
const errorText = `Extension sendMessage failed: ${err instanceof Error ? err.message : String(err)}`;
|
|
329
|
-
if (this.ctx.isBackgrounded) {
|
|
330
|
-
logger.error(errorText);
|
|
331
|
-
return;
|
|
332
|
-
}
|
|
333
328
|
this.ctx.showError(errorText);
|
|
334
329
|
});
|
|
335
330
|
},
|
|
@@ -374,9 +369,6 @@ export class ExtensionUiController {
|
|
|
374
369
|
getContextUsage: () => this.ctx.session.getContextUsage(),
|
|
375
370
|
waitForIdle: () => this.ctx.session.agent.waitForIdle(),
|
|
376
371
|
reload: async () => {
|
|
377
|
-
if (this.ctx.isBackgrounded) {
|
|
378
|
-
return;
|
|
379
|
-
}
|
|
380
372
|
await this.ctx.session.reload();
|
|
381
373
|
this.ctx.chatContainer.clear();
|
|
382
374
|
this.ctx.renderInitialMessages(undefined, { clearTerminalHistory: true });
|
|
@@ -384,9 +376,6 @@ export class ExtensionUiController {
|
|
|
384
376
|
this.ctx.showStatus("Reloaded session");
|
|
385
377
|
},
|
|
386
378
|
newSession: async options => {
|
|
387
|
-
if (this.ctx.isBackgrounded) {
|
|
388
|
-
return { cancelled: true };
|
|
389
|
-
}
|
|
390
379
|
// Stop any loading animation
|
|
391
380
|
if (this.ctx.loadingAnimation) {
|
|
392
381
|
this.ctx.loadingAnimation.stop();
|
|
@@ -415,19 +404,16 @@ export class ExtensionUiController {
|
|
|
415
404
|
this.ctx.streamingMessage = undefined;
|
|
416
405
|
this.ctx.pendingTools.clear();
|
|
417
406
|
|
|
418
|
-
this.ctx.
|
|
419
|
-
|
|
407
|
+
this.ctx.present([
|
|
408
|
+
new Spacer(1),
|
|
420
409
|
new Text(`${theme.fg("accent", `${theme.status.success} New session started`)}`, 1, 1),
|
|
421
|
-
);
|
|
410
|
+
]);
|
|
422
411
|
await this.ctx.reloadTodos();
|
|
423
412
|
this.ctx.ui.requestRender(true, { clearScrollback: true });
|
|
424
413
|
|
|
425
414
|
return { cancelled: false };
|
|
426
415
|
},
|
|
427
416
|
branch: async entryId => {
|
|
428
|
-
if (this.ctx.isBackgrounded) {
|
|
429
|
-
return { cancelled: true };
|
|
430
|
-
}
|
|
431
417
|
const result = await this.ctx.session.branch(entryId);
|
|
432
418
|
if (result.cancelled) {
|
|
433
419
|
return { cancelled: true };
|
|
@@ -443,9 +429,6 @@ export class ExtensionUiController {
|
|
|
443
429
|
return { cancelled: false };
|
|
444
430
|
},
|
|
445
431
|
navigateTree: async (targetId, options) => {
|
|
446
|
-
if (this.ctx.isBackgrounded) {
|
|
447
|
-
return { cancelled: true };
|
|
448
|
-
}
|
|
449
432
|
const result = await this.ctx.session.navigateTree(targetId, { summarize: options?.summarize });
|
|
450
433
|
if (result.cancelled) {
|
|
451
434
|
return { cancelled: true };
|
|
@@ -464,9 +447,6 @@ export class ExtensionUiController {
|
|
|
464
447
|
},
|
|
465
448
|
compact: async instructionsOrOptions => this.#handleInteractiveCompact(instructionsOrOptions),
|
|
466
449
|
switchSession: async sessionPath => {
|
|
467
|
-
if (this.ctx.isBackgrounded) {
|
|
468
|
-
return { cancelled: true };
|
|
469
|
-
}
|
|
470
450
|
this.clearHookWidgets();
|
|
471
451
|
const result = await this.ctx.session.switchSession(sessionPath);
|
|
472
452
|
if (!result) {
|
|
@@ -482,36 +462,6 @@ export class ExtensionUiController {
|
|
|
482
462
|
extensionRunner.initialize(actions, contextActions, commandActions, uiContext);
|
|
483
463
|
}
|
|
484
464
|
|
|
485
|
-
createBackgroundUiContext(): ExtensionUIContext {
|
|
486
|
-
return {
|
|
487
|
-
select: async (_title: string, _options: ExtensionUISelectItem[], _dialogOptions) => undefined,
|
|
488
|
-
confirm: async (_title: string, _message: string, _dialogOptions) => false,
|
|
489
|
-
input: async (_title: string, _placeholder?: string, _dialogOptions?: unknown) => undefined,
|
|
490
|
-
notify: () => {},
|
|
491
|
-
onTerminalInput: () => () => {},
|
|
492
|
-
setStatus: () => {},
|
|
493
|
-
setWorkingMessage: () => {},
|
|
494
|
-
setWidget: () => {},
|
|
495
|
-
setTitle: () => {},
|
|
496
|
-
custom: async () => undefined as never,
|
|
497
|
-
setEditorText: () => {},
|
|
498
|
-
pasteToEditor: () => {},
|
|
499
|
-
getEditorText: () => "",
|
|
500
|
-
editor: async () => undefined,
|
|
501
|
-
get theme() {
|
|
502
|
-
return theme;
|
|
503
|
-
},
|
|
504
|
-
getAllThemes: () => Promise.resolve([]),
|
|
505
|
-
getTheme: () => Promise.resolve(undefined),
|
|
506
|
-
setTheme: () => Promise.resolve({ success: false, error: "Background mode" }),
|
|
507
|
-
setFooter: () => {},
|
|
508
|
-
setHeader: () => {},
|
|
509
|
-
setEditorComponent: () => {},
|
|
510
|
-
getToolsExpanded: () => false,
|
|
511
|
-
setToolsExpanded: () => {},
|
|
512
|
-
};
|
|
513
|
-
}
|
|
514
|
-
|
|
515
465
|
/**
|
|
516
466
|
* Emit session event to all extension tools.
|
|
517
467
|
*/
|
|
@@ -531,7 +481,7 @@ export class ExtensionUiController {
|
|
|
531
481
|
ui: uiContext,
|
|
532
482
|
getContextUsage: () => this.ctx.session.getContextUsage(),
|
|
533
483
|
compact: instructionsOrOptions => this.#compactSession(instructionsOrOptions),
|
|
534
|
-
hasUI:
|
|
484
|
+
hasUI: true,
|
|
535
485
|
cwd: this.ctx.sessionManager.getCwd(),
|
|
536
486
|
sessionManager: this.ctx.session.sessionManager,
|
|
537
487
|
modelRegistry: this.ctx.session.modelRegistry,
|
|
@@ -557,22 +507,14 @@ export class ExtensionUiController {
|
|
|
557
507
|
* Show a tool error in the chat.
|
|
558
508
|
*/
|
|
559
509
|
showToolError(toolName: string, error: string): void {
|
|
560
|
-
if (this.ctx.isBackgrounded) {
|
|
561
|
-
logger.error(`Tool "${toolName}" error: ${error}`);
|
|
562
|
-
return;
|
|
563
|
-
}
|
|
564
510
|
const errorText = new Text(theme.fg("error", `Tool "${toolName}" error: ${error}`), 1, 0);
|
|
565
|
-
this.ctx.
|
|
566
|
-
this.ctx.ui.requestRender();
|
|
511
|
+
this.ctx.present(errorText);
|
|
567
512
|
}
|
|
568
513
|
|
|
569
514
|
/**
|
|
570
515
|
* Set hook status text in the footer.
|
|
571
516
|
*/
|
|
572
517
|
setHookStatus(key: string, text: string | undefined): void {
|
|
573
|
-
if (this.ctx.isBackgrounded) {
|
|
574
|
-
return;
|
|
575
|
-
}
|
|
576
518
|
this.ctx.statusLine.setHookStatus(key, text);
|
|
577
519
|
this.ctx.ui.requestRender();
|
|
578
520
|
}
|
|
@@ -860,14 +802,9 @@ export class ExtensionUiController {
|
|
|
860
802
|
|
|
861
803
|
showExtensionError(extensionPath: string, error: string): void {
|
|
862
804
|
const errorText = new Text(theme.fg("error", `Extension "${extensionPath}" error: ${error}`), 1, 0);
|
|
863
|
-
this.ctx.
|
|
864
|
-
this.ctx.ui.requestRender();
|
|
805
|
+
this.ctx.present(errorText);
|
|
865
806
|
}
|
|
866
807
|
async #handleInteractiveCompact(instructionsOrOptions: string | CompactOptions | undefined): Promise<void> {
|
|
867
|
-
if (this.ctx.isBackgrounded) {
|
|
868
|
-
await this.#compactSession(instructionsOrOptions);
|
|
869
|
-
return;
|
|
870
|
-
}
|
|
871
808
|
await this.ctx.executeCompaction(instructionsOrOptions, false);
|
|
872
809
|
}
|
|
873
810
|
|
|
@@ -892,7 +829,7 @@ export class ExtensionUiController {
|
|
|
892
829
|
#applyCustomMessageDisplay(wasStreaming: boolean, shouldDisplay: boolean | undefined): void {
|
|
893
830
|
// For non-streaming cases with display=true, update UI
|
|
894
831
|
// (streaming cases update via message_end event)
|
|
895
|
-
if (!
|
|
832
|
+
if (!wasStreaming && shouldDisplay) {
|
|
896
833
|
this.ctx.rebuildChatFromMessages();
|
|
897
834
|
}
|
|
898
835
|
}
|