@oh-my-pi/pi-coding-agent 16.3.5 → 16.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 +18 -0
- package/dist/cli.js +3388 -3374
- package/dist/types/edit/file-snapshot-store.d.ts +4 -2
- package/dist/types/edit/renderer.d.ts +0 -1
- package/dist/types/extensibility/custom-tools/types.d.ts +2 -0
- package/dist/types/extensibility/shared-events.d.ts +8 -1
- package/dist/types/modes/components/assistant-message.d.ts +15 -10
- package/dist/types/modes/components/bash-execution.d.ts +6 -0
- package/dist/types/modes/components/eval-execution.d.ts +6 -0
- package/dist/types/modes/components/tool-execution.d.ts +3 -13
- package/dist/types/modes/components/transcript-container.d.ts +26 -28
- package/dist/types/modes/utils/transcript-render-helpers.d.ts +15 -6
- package/dist/types/session/agent-session.d.ts +2 -0
- package/dist/types/tools/bash.d.ts +0 -2
- package/dist/types/tools/browser/tab-supervisor.d.ts +10 -0
- package/dist/types/tools/eval-render.d.ts +0 -2
- package/dist/types/tools/renderers.d.ts +0 -20
- package/dist/types/tools/ssh.d.ts +0 -2
- package/dist/types/tools/write.d.ts +1 -1
- package/package.json +12 -12
- package/src/edit/file-snapshot-store.ts +5 -2
- package/src/edit/renderer.ts +0 -5
- package/src/extensibility/custom-tools/types.ts +2 -0
- package/src/extensibility/shared-events.ts +9 -1
- package/src/modes/components/assistant-message.ts +134 -82
- package/src/modes/components/bash-execution.ts +9 -0
- package/src/modes/components/chat-transcript-builder.ts +8 -4
- package/src/modes/components/eval-execution.ts +9 -0
- package/src/modes/components/tool-execution.ts +4 -50
- package/src/modes/components/transcript-container.ts +82 -432
- package/src/modes/components/tree-selector.ts +9 -3
- package/src/modes/controllers/command-controller.ts +0 -3
- package/src/modes/controllers/event-controller.ts +74 -14
- package/src/modes/controllers/extension-ui-controller.ts +0 -1
- package/src/modes/controllers/input-controller.ts +4 -10
- package/src/modes/interactive-mode.ts +12 -8
- package/src/modes/utils/transcript-render-helpers.ts +40 -13
- package/src/modes/utils/ui-helpers.ts +12 -7
- package/src/sdk.ts +1 -0
- package/src/session/agent-session.ts +148 -1
- package/src/session/session-context.ts +7 -0
- package/src/tools/bash.ts +0 -4
- package/src/tools/browser/tab-supervisor.ts +47 -3
- package/src/tools/eval-render.ts +0 -20
- package/src/tools/read.ts +63 -20
- package/src/tools/renderers.ts +0 -20
- package/src/tools/ssh.ts +0 -16
- package/src/tools/write.ts +13 -6
|
@@ -42,9 +42,11 @@ export declare function canonicalSnapshotKey(absolutePath: string): string;
|
|
|
42
42
|
* Producers that only displayed a slice of the file (range reads, search hits)
|
|
43
43
|
* use this to mint a whole-file tag: the displayed lines stay partial, but the
|
|
44
44
|
* tag fingerprints the entire file so a follow-up edit anchored at any line
|
|
45
|
-
* validates whenever the live file is byte-identical to what was read.
|
|
45
|
+
* validates whenever the live file is byte-identical to what was read. Raw
|
|
46
|
+
* reads pass `seenLines` even though they do not emit a header, letting a prior
|
|
47
|
+
* or later same-content hashline tag inherit the raw range's provenance.
|
|
46
48
|
*/
|
|
47
|
-
export declare function recordFileSnapshot(session: FileSnapshotStoreOwner, absolutePath: string): Promise<string | undefined>;
|
|
49
|
+
export declare function recordFileSnapshot(session: FileSnapshotStoreOwner, absolutePath: string, seenLines?: Iterable<number>): Promise<string | undefined>;
|
|
48
50
|
/**
|
|
49
51
|
* The 1-indexed file lines a hashline-formatted body actually displayed.
|
|
50
52
|
* Single `NN:` rows contribute that line; a collapsed summary `NN-MM:` row
|
|
@@ -102,7 +102,6 @@ export interface EditRenderContext {
|
|
|
102
102
|
}
|
|
103
103
|
export declare const editToolRenderer: {
|
|
104
104
|
mergeCallAndResult: boolean;
|
|
105
|
-
provisionalPendingPreview: boolean;
|
|
106
105
|
renderCall(args: EditRenderArgs, options: RenderResultOptions & {
|
|
107
106
|
renderContext?: EditRenderContext;
|
|
108
107
|
}, uiTheme: Theme): Component;
|
|
@@ -20,6 +20,7 @@ import type * as PiCodingAgent from "../../index";
|
|
|
20
20
|
import type { Theme } from "../../modes/theme/theme";
|
|
21
21
|
import type { ReadonlySessionManager } from "../../session/session-manager";
|
|
22
22
|
import type { TodoItem } from "../../tools/todo";
|
|
23
|
+
import type { RecoveredRetryError } from "../shared-events";
|
|
23
24
|
import type * as TypeBox from "../typebox";
|
|
24
25
|
/** Alias for clarity */
|
|
25
26
|
export type CustomToolUIContext = HookUIContext;
|
|
@@ -115,6 +116,7 @@ export type CustomToolSessionEvent = {
|
|
|
115
116
|
success: boolean;
|
|
116
117
|
attempt: number;
|
|
117
118
|
finalError?: string;
|
|
119
|
+
recoveredErrors?: RecoveredRetryError[];
|
|
118
120
|
} | {
|
|
119
121
|
reason: "ttsr_triggered";
|
|
120
122
|
rules: Rule[];
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
*/
|
|
15
15
|
import type { AgentMessage } from "@oh-my-pi/pi-agent-core";
|
|
16
16
|
import type { CompactionPreparation, CompactionResult } from "@oh-my-pi/pi-agent-core/compaction";
|
|
17
|
-
import type { ImageContent, TextContent, ToolResultMessage } from "@oh-my-pi/pi-ai";
|
|
17
|
+
import type { AssistantRetryRecovery, ImageContent, TextContent, ToolResultMessage } from "@oh-my-pi/pi-ai";
|
|
18
18
|
import type { Rule } from "../capability/rule";
|
|
19
19
|
import type { Goal, GoalModeState } from "../goals/state";
|
|
20
20
|
import type { BranchSummaryEntry, CompactionEntry, SessionEntry } from "../session/session-entries";
|
|
@@ -192,12 +192,19 @@ export interface AutoRetryStartEvent {
|
|
|
192
192
|
errorMessage: string;
|
|
193
193
|
errorId?: number;
|
|
194
194
|
}
|
|
195
|
+
export interface RecoveredRetryError {
|
|
196
|
+
entryId: string;
|
|
197
|
+
persistenceKey?: string;
|
|
198
|
+
note: string;
|
|
199
|
+
retryRecovery: AssistantRetryRecovery;
|
|
200
|
+
}
|
|
195
201
|
/** Fired when auto-retry ends */
|
|
196
202
|
export interface AutoRetryEndEvent {
|
|
197
203
|
type: "auto_retry_end";
|
|
198
204
|
success: boolean;
|
|
199
205
|
attempt: number;
|
|
200
206
|
finalError?: string;
|
|
207
|
+
recoveredErrors?: RecoveredRetryError[];
|
|
201
208
|
}
|
|
202
209
|
/** Fired when TTSR rule matching interrupts generation */
|
|
203
210
|
export interface TtsrTriggeredEvent {
|
|
@@ -23,6 +23,7 @@ export declare class AssistantMessageComponent extends Container {
|
|
|
23
23
|
*/
|
|
24
24
|
setCacheInvalidation(info: CacheInvalidation | undefined): void;
|
|
25
25
|
invalidate(): void;
|
|
26
|
+
render(width: number): readonly string[];
|
|
26
27
|
setHideThinkingBlock(hide: boolean): void;
|
|
27
28
|
setProseOnlyThinking(proseOnly: boolean): void;
|
|
28
29
|
dispose(): void;
|
|
@@ -33,19 +34,23 @@ export declare class AssistantMessageComponent extends Container {
|
|
|
33
34
|
setErrorPinned(pinned: boolean): void;
|
|
34
35
|
isTranscriptBlockFinalized(): boolean;
|
|
35
36
|
/**
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
37
|
+
* Settled leading rows for mid-stream native-scrollback commits (see
|
|
38
|
+
* `FinalizableBlock.getTranscriptBlockSettledRows`). Completed content
|
|
39
|
+
* blocks render in final form (non-transient) and settle in full; the
|
|
40
|
+
* actively streaming markdown contributes its rendered frozen-token
|
|
41
|
+
* prefix. The walk stops at the first child that is not declared
|
|
42
|
+
* byte-stable (the animated thinking pulse, extension components, images,
|
|
43
|
+
* error rows), and a cache-invalidation marker above the content defers
|
|
44
|
+
* settling entirely. Mermaid anywhere defers wholesale — its ASCII
|
|
45
|
+
* rendering resolves asynchronously and can re-layout settled-looking
|
|
46
|
+
* rows. Reads only L1-cached child renders at the width recorded by this
|
|
47
|
+
* frame's render().
|
|
45
48
|
*/
|
|
46
|
-
|
|
49
|
+
getTranscriptBlockSettledRows(): number;
|
|
47
50
|
getTranscriptBlockVersion(): number;
|
|
48
51
|
markTranscriptBlockFinalized(): void;
|
|
52
|
+
applyRetryRecovery(retryRecovery: AssistantMessage["retryRecovery"]): void;
|
|
53
|
+
messagePersistenceKey(): string | undefined;
|
|
49
54
|
setToolResultImages(toolCallId: string, images: ImageContent[]): void;
|
|
50
55
|
updateContent(message: AssistantMessage, opts?: {
|
|
51
56
|
transient?: boolean;
|
|
@@ -7,6 +7,12 @@ export declare class BashExecutionComponent extends Container {
|
|
|
7
7
|
#private;
|
|
8
8
|
private readonly command;
|
|
9
9
|
constructor(command: string, ui: TUI, excludeFromContext?: boolean);
|
|
10
|
+
/**
|
|
11
|
+
* Transcript finalization contract (see `FinalizableBlock`): the collapsed
|
|
12
|
+
* streaming preview rewrites its tail window every chunk, so the block must
|
|
13
|
+
* stay out of native scrollback until the command completes.
|
|
14
|
+
*/
|
|
15
|
+
isTranscriptBlockFinalized(): boolean;
|
|
10
16
|
/**
|
|
11
17
|
* Set whether the output is expanded (shows full output) or collapsed (preview only).
|
|
12
18
|
*/
|
|
@@ -11,6 +11,12 @@ export declare class EvalExecutionComponent extends Container {
|
|
|
11
11
|
private readonly excludeFromContext;
|
|
12
12
|
private readonly language;
|
|
13
13
|
constructor(code: string, ui: TUI, excludeFromContext?: boolean, language?: EvalExecutionLanguage);
|
|
14
|
+
/**
|
|
15
|
+
* Transcript finalization contract (see `FinalizableBlock`): the collapsed
|
|
16
|
+
* streaming preview rewrites its tail window every chunk, so the block must
|
|
17
|
+
* stay out of native scrollback until the cell completes.
|
|
18
|
+
*/
|
|
19
|
+
isTranscriptBlockFinalized(): boolean;
|
|
14
20
|
setExpanded(expanded: boolean): void;
|
|
15
21
|
invalidate(): void;
|
|
16
22
|
appendOutput(chunk: string): void;
|
|
@@ -78,9 +78,9 @@ export declare class ToolExecutionComponent extends Container implements NativeS
|
|
|
78
78
|
/**
|
|
79
79
|
* Standalone harnesses may mount a tool component directly under `TUI`
|
|
80
80
|
* instead of inside `TranscriptContainer`. In that shape the component must
|
|
81
|
-
* report its own live-region seam
|
|
82
|
-
*
|
|
83
|
-
*
|
|
81
|
+
* report its own live-region seam while unfinalized, or the core renderer
|
|
82
|
+
* treats it like shell output and commits still-mutating preview rows to
|
|
83
|
+
* immutable native scrollback before the result replaces them.
|
|
84
84
|
*/
|
|
85
85
|
getNativeScrollbackLiveRegionStart(): number | undefined;
|
|
86
86
|
/**
|
|
@@ -92,16 +92,6 @@ export declare class ToolExecutionComponent extends Container implements NativeS
|
|
|
92
92
|
* past, or an explicit {@link seal} flips it to `true`.
|
|
93
93
|
*/
|
|
94
94
|
isTranscriptBlockFinalized(): boolean;
|
|
95
|
-
/**
|
|
96
|
-
* Whether this still-live block's settled rows may enter native scrollback
|
|
97
|
-
* (see `FinalizableBlock.isTranscriptBlockCommitStable`). Renderers classify
|
|
98
|
-
* pending views by durability instead of by tool name: a provisional view is
|
|
99
|
-
* allowed to be useful on screen, but finalization may replace or re-anchor
|
|
100
|
-
* it wholesale, so committing any of its rows would strand stale preview
|
|
101
|
-
* bytes in immutable scrollback. Non-provisional views stream rows whose
|
|
102
|
-
* committed prefix survives the remaining transitions.
|
|
103
|
-
*/
|
|
104
|
-
isTranscriptBlockCommitStable(): boolean;
|
|
105
95
|
/**
|
|
106
96
|
* Mark the tool terminal even though no result arrived (the turn aborted or
|
|
107
97
|
* abandoned it) and stop animating, so it can freeze and stops pinning the
|
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
import { type Component, Container, type NativeScrollbackCommittedRows, type NativeScrollbackLiveRegion, type RenderStablePrefix, type ViewportTailProvider } from "@oh-my-pi/pi-tui";
|
|
2
2
|
/**
|
|
3
3
|
* Transcript container that renders every block's current content each frame
|
|
4
|
-
* and reports the
|
|
5
|
-
* the
|
|
4
|
+
* and reports the native-scrollback exactness boundary
|
|
5
|
+
* (`NativeScrollbackLiveRegion`): the frame row below which every rendered
|
|
6
|
+
* row is final. The boundary covers the leading run of finalized blocks plus
|
|
7
|
+
* the first still-live block's declared settled rows
|
|
8
|
+
* ({@link FinalizableBlock.getTranscriptBlockSettledRows}). Rows below it
|
|
9
|
+
* commit to native scrollback as exact, audited content; rows above it that
|
|
10
|
+
* scroll off the window commit as frozen visual snapshots the engine never
|
|
11
|
+
* re-anchors or recommits (the tape records what was on screen).
|
|
6
12
|
*
|
|
7
|
-
* The engine never rewrites committed history: rows
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* unfinalized tool, a streaming assistant message) stay below the seam so
|
|
13
|
-
* their rows do not enter history while they can still change; a streaming
|
|
14
|
-
* block whose render grows append-only deepens the seam through its settled
|
|
15
|
-
* head so a long reply's scrolled-off rows still reach scrollback mid-stream.
|
|
13
|
+
* The engine never rewrites committed history: rows that have entered the
|
|
14
|
+
* tape keep whatever bytes they were committed with ("let the history be"),
|
|
15
|
+
* while the visible window always repaints from each block's latest render —
|
|
16
|
+
* a late tool result, a post-finalize error pin, or an expand toggle is
|
|
17
|
+
* always reflected on screen while it remains in the window.
|
|
16
18
|
*
|
|
17
19
|
* Assembly is incremental: the returned array is persistent and mutated in
|
|
18
20
|
* place. Each block's render is still called every frame, but a block whose
|
|
@@ -29,28 +31,24 @@ export declare class TranscriptContainer extends Container implements NativeScro
|
|
|
29
31
|
setNativeScrollbackCommittedRows(rows: number): void;
|
|
30
32
|
getRenderStablePrefixRows(): number;
|
|
31
33
|
getNativeScrollbackLiveRegionStart(): number | undefined;
|
|
32
|
-
getNativeScrollbackCommitSafeEnd(): number | undefined;
|
|
33
|
-
getNativeScrollbackSnapshotSafeEnd(): number | undefined;
|
|
34
34
|
/**
|
|
35
|
-
* Whether `component`
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
35
|
+
* Whether none of `component`'s rows (per the most recent render) have
|
|
36
|
+
* entered native scrollback. Callers that retract ephemeral blocks (IRC
|
|
37
|
+
* cards, displaceable todo/job snapshots) must check this: removing a
|
|
38
|
+
* block whose rows are already on the tape is an interior deletion of
|
|
39
|
+
* committed history the engine cannot express — the block must be sealed
|
|
40
|
+
* in place as history instead. A component that has never rendered has no
|
|
41
|
+
* committed rows and is safely removable.
|
|
42
42
|
*/
|
|
43
|
-
|
|
43
|
+
isBlockUncommitted(component: Component): boolean;
|
|
44
44
|
/**
|
|
45
45
|
* Whether `component` is inside the live (repaintable) region exactly as
|
|
46
46
|
* {@link render} computes it: at/after the first still-mutating block, or
|
|
47
|
-
* the transcript tail when every block has finalized.
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* the
|
|
51
|
-
*
|
|
52
|
-
* static bytes — the moment they sit above the seam, where their rows
|
|
53
|
-
* become commit-eligible native-scrollback history.
|
|
47
|
+
* the transcript tail when every block has finalized. Self-animating
|
|
48
|
+
* finalized blocks (a detached task's shimmering progress rows) poll this
|
|
49
|
+
* to stop animating — and settle on static bytes — the moment they sit
|
|
50
|
+
* above the seam, where their rows become commit-eligible native-scrollback
|
|
51
|
+
* history.
|
|
54
52
|
*/
|
|
55
53
|
isBlockInLiveRegion(component: Component): boolean;
|
|
56
54
|
/**
|
|
@@ -43,12 +43,21 @@ export declare function assistantHasVisibleContent(message: AssistantAgentMessag
|
|
|
43
43
|
* array values to an empty object.
|
|
44
44
|
*/
|
|
45
45
|
export declare function normalizeToolArgs(args: unknown): Record<string, unknown>;
|
|
46
|
+
export type AssistantErrorPresentation = {
|
|
47
|
+
kind: "none";
|
|
48
|
+
} | {
|
|
49
|
+
kind: "full";
|
|
50
|
+
text: string;
|
|
51
|
+
isError: true;
|
|
52
|
+
} | {
|
|
53
|
+
kind: "compact-recovered";
|
|
54
|
+
text: string;
|
|
55
|
+
isError: false;
|
|
56
|
+
};
|
|
46
57
|
/**
|
|
47
|
-
* Resolve the
|
|
48
|
-
* Silent aborts yield no label.
|
|
58
|
+
* Resolve the turn-ending assistant error presentation, if any.
|
|
59
|
+
* Silent and user-interrupt aborts yield no label. Recovered auto-retry errors
|
|
60
|
+
* collapse to a single non-error note; terminal errors keep the full red presentation.
|
|
49
61
|
*/
|
|
50
|
-
export declare function
|
|
51
|
-
hasErrorStop: boolean;
|
|
52
|
-
errorMessage: string | null;
|
|
53
|
-
};
|
|
62
|
+
export declare function resolveAssistantErrorPresentation(message: AssistantAgentMessage, retryAttempt?: number): AssistantErrorPresentation;
|
|
54
63
|
export {};
|
|
@@ -33,6 +33,7 @@ import type { LoadedCustomCommand } from "../extensibility/custom-commands";
|
|
|
33
33
|
import type { CustomTool } from "../extensibility/custom-tools/types";
|
|
34
34
|
import type { ExtensionRunner } from "../extensibility/extensions";
|
|
35
35
|
import type { CompactOptions, ContextUsage } from "../extensibility/extensions/types";
|
|
36
|
+
import type { RecoveredRetryError } from "../extensibility/shared-events";
|
|
36
37
|
import type { Skill, SkillWarning } from "../extensibility/skills";
|
|
37
38
|
import { type FileSlashCommand } from "../extensibility/slash-commands";
|
|
38
39
|
import { GoalRuntime } from "../goals/runtime";
|
|
@@ -80,6 +81,7 @@ export type AgentSessionEvent = AgentEvent | {
|
|
|
80
81
|
success: boolean;
|
|
81
82
|
attempt: number;
|
|
82
83
|
finalError?: string;
|
|
84
|
+
recoveredErrors?: RecoveredRetryError[];
|
|
83
85
|
} | {
|
|
84
86
|
type: "retry_fallback_applied";
|
|
85
87
|
from: string;
|
|
@@ -154,7 +154,6 @@ export declare function createShellRenderer<TArgs>(config: ShellRendererConfig<T
|
|
|
154
154
|
}, uiTheme: Theme, args?: TArgs): Component;
|
|
155
155
|
mergeCallAndResult: boolean;
|
|
156
156
|
inline: boolean;
|
|
157
|
-
provisionalPendingPreview: string;
|
|
158
157
|
};
|
|
159
158
|
export declare const bashToolRenderer: {
|
|
160
159
|
renderCall(args: BashRenderArgs, options: RenderResultOptions, uiTheme: Theme): Component;
|
|
@@ -170,6 +169,5 @@ export declare const bashToolRenderer: {
|
|
|
170
169
|
}, uiTheme: Theme, args?: BashRenderArgs | undefined): Component;
|
|
171
170
|
mergeCallAndResult: boolean;
|
|
172
171
|
inline: boolean;
|
|
173
|
-
provisionalPendingPreview: string;
|
|
174
172
|
};
|
|
175
173
|
export {};
|
|
@@ -16,6 +16,16 @@ export interface PendingRun {
|
|
|
16
16
|
session: ToolSession;
|
|
17
17
|
signal?: AbortSignal;
|
|
18
18
|
toolCalls: Map<string, AbortController>;
|
|
19
|
+
/**
|
|
20
|
+
* Fires when `releaseTab` closes the tab out from under an in-flight run
|
|
21
|
+
* (sibling `browser close --all`, session-scoped reap, etc.). Composed
|
|
22
|
+
* into the cmux run's signal so `wait(...)`, cmux socket calls, and the
|
|
23
|
+
* facade proxies unwind promptly instead of blocking to the run's
|
|
24
|
+
* timeout. `pending.reject` still fires first so the awaiting caller
|
|
25
|
+
* sees the tab-close error immediately; `closeAc` propagates the
|
|
26
|
+
* cancellation into the still-running `runCmuxCode` body (issue #4499).
|
|
27
|
+
*/
|
|
28
|
+
closeAc?: AbortController;
|
|
19
29
|
}
|
|
20
30
|
interface TabSessionBase<TBrowser extends BrowserHandle = BrowserHandle> {
|
|
21
31
|
name: string;
|
|
@@ -21,26 +21,6 @@ export type ToolRenderer = {
|
|
|
21
21
|
mergeCallAndResult?: boolean;
|
|
22
22
|
/** Render without background box, inline in the response flow */
|
|
23
23
|
inline?: boolean;
|
|
24
|
-
/**
|
|
25
|
-
* Whether pending-call rows are provisional: useful on screen while a tool is
|
|
26
|
-
* streaming, but not durable transcript history. `true` means every pending
|
|
27
|
-
* shape is provisional. `"collapsed"` means only the collapsed pending shape
|
|
28
|
-
* is provisional; expanded rendering is top-anchored/append-shaped enough to
|
|
29
|
-
* let the transcript commit its settled prefix. Absent = the pending preview
|
|
30
|
-
* streams rows the result render preserves.
|
|
31
|
-
*/
|
|
32
|
-
provisionalPendingPreview?: boolean | "collapsed";
|
|
33
|
-
/**
|
|
34
|
-
* Whether the partial-result render is provisional: chrome rows (header
|
|
35
|
-
* glyph, frame state) that change between `options.isPartial === true` and
|
|
36
|
-
* the final result render. When `true`, the block is treated as
|
|
37
|
-
* commit-unstable while a partial result is in flight, so the
|
|
38
|
-
* stable-prefix ratchet in `deriveLiveCommitState` cannot promote the
|
|
39
|
-
* partial chrome to native scrollback only to have the final render strand
|
|
40
|
-
* it above the settled frame. Absent = the partial render is byte-stable
|
|
41
|
-
* with the final render and may commit like any settled stream.
|
|
42
|
-
*/
|
|
43
|
-
provisionalPartialResult?: boolean;
|
|
44
24
|
/**
|
|
45
25
|
* Whether the renderer's pending-call path visibly consumes
|
|
46
26
|
* `options.spinnerFrame`. Used to avoid scheduling repaint ticks for live
|
|
@@ -68,8 +68,6 @@ export declare const sshToolRenderer: {
|
|
|
68
68
|
renderContext?: SshRenderContext;
|
|
69
69
|
}, uiTheme: Theme, args?: SshRenderArgs): Component;
|
|
70
70
|
mergeCallAndResult: boolean;
|
|
71
|
-
provisionalPendingPreview: boolean;
|
|
72
|
-
provisionalPartialResult: boolean;
|
|
73
71
|
forceFirstResultViewportRepaint: boolean;
|
|
74
72
|
forceResultViewportRepaintOnSettle: boolean;
|
|
75
73
|
};
|
|
@@ -49,7 +49,7 @@ export declare class WriteTool implements AgentTool<typeof writeSchema, WriteToo
|
|
|
49
49
|
interface WriteRenderArgs {
|
|
50
50
|
path?: string;
|
|
51
51
|
file_path?: string;
|
|
52
|
-
content?:
|
|
52
|
+
content?: unknown;
|
|
53
53
|
}
|
|
54
54
|
export declare const writeToolRenderer: {
|
|
55
55
|
renderCall(args: WriteRenderArgs, options: RenderResultOptions, uiTheme: Theme): Component;
|
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": "16.3.
|
|
4
|
+
"version": "16.3.6",
|
|
5
5
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
6
6
|
"homepage": "https://omp.sh",
|
|
7
7
|
"author": "Can Boluk",
|
|
@@ -56,17 +56,17 @@
|
|
|
56
56
|
"@agentclientprotocol/sdk": "0.25.0",
|
|
57
57
|
"@babel/parser": "^7.29.7",
|
|
58
58
|
"@mozilla/readability": "^0.6.0",
|
|
59
|
-
"@oh-my-pi/hashline": "16.3.
|
|
60
|
-
"@oh-my-pi/omp-stats": "16.3.
|
|
61
|
-
"@oh-my-pi/pi-agent-core": "16.3.
|
|
62
|
-
"@oh-my-pi/pi-ai": "16.3.
|
|
63
|
-
"@oh-my-pi/pi-catalog": "16.3.
|
|
64
|
-
"@oh-my-pi/pi-mnemopi": "16.3.
|
|
65
|
-
"@oh-my-pi/pi-natives": "16.3.
|
|
66
|
-
"@oh-my-pi/pi-tui": "16.3.
|
|
67
|
-
"@oh-my-pi/pi-utils": "16.3.
|
|
68
|
-
"@oh-my-pi/pi-wire": "16.3.
|
|
69
|
-
"@oh-my-pi/snapcompact": "16.3.
|
|
59
|
+
"@oh-my-pi/hashline": "16.3.6",
|
|
60
|
+
"@oh-my-pi/omp-stats": "16.3.6",
|
|
61
|
+
"@oh-my-pi/pi-agent-core": "16.3.6",
|
|
62
|
+
"@oh-my-pi/pi-ai": "16.3.6",
|
|
63
|
+
"@oh-my-pi/pi-catalog": "16.3.6",
|
|
64
|
+
"@oh-my-pi/pi-mnemopi": "16.3.6",
|
|
65
|
+
"@oh-my-pi/pi-natives": "16.3.6",
|
|
66
|
+
"@oh-my-pi/pi-tui": "16.3.6",
|
|
67
|
+
"@oh-my-pi/pi-utils": "16.3.6",
|
|
68
|
+
"@oh-my-pi/pi-wire": "16.3.6",
|
|
69
|
+
"@oh-my-pi/snapcompact": "16.3.6",
|
|
70
70
|
"@opentelemetry/api": "^1.9.1",
|
|
71
71
|
"@opentelemetry/context-async-hooks": "^2.7.1",
|
|
72
72
|
"@opentelemetry/exporter-trace-otlp-proto": "^0.218.0",
|
|
@@ -74,17 +74,20 @@ export function canonicalSnapshotKey(absolutePath: string): string {
|
|
|
74
74
|
* Producers that only displayed a slice of the file (range reads, search hits)
|
|
75
75
|
* use this to mint a whole-file tag: the displayed lines stay partial, but the
|
|
76
76
|
* tag fingerprints the entire file so a follow-up edit anchored at any line
|
|
77
|
-
* validates whenever the live file is byte-identical to what was read.
|
|
77
|
+
* validates whenever the live file is byte-identical to what was read. Raw
|
|
78
|
+
* reads pass `seenLines` even though they do not emit a header, letting a prior
|
|
79
|
+
* or later same-content hashline tag inherit the raw range's provenance.
|
|
78
80
|
*/
|
|
79
81
|
export async function recordFileSnapshot(
|
|
80
82
|
session: FileSnapshotStoreOwner,
|
|
81
83
|
absolutePath: string,
|
|
84
|
+
seenLines?: Iterable<number>,
|
|
82
85
|
): Promise<string | undefined> {
|
|
83
86
|
try {
|
|
84
87
|
const file = Bun.file(absolutePath);
|
|
85
88
|
if (file.size > SNAPSHOT_MAX_BYTES) return undefined;
|
|
86
89
|
const normalized = normalizeToLF(await file.text());
|
|
87
|
-
return getFileSnapshotStore(session).record(canonicalSnapshotKey(absolutePath), normalized);
|
|
90
|
+
return getFileSnapshotStore(session).record(canonicalSnapshotKey(absolutePath), normalized, seenLines);
|
|
88
91
|
} catch {
|
|
89
92
|
return undefined;
|
|
90
93
|
}
|
package/src/edit/renderer.ts
CHANGED
|
@@ -696,11 +696,6 @@ function wrapEditRendererLine(line: string, width: number): string[] {
|
|
|
696
696
|
|
|
697
697
|
export const editToolRenderer = {
|
|
698
698
|
mergeCallAndResult: true,
|
|
699
|
-
// Pending preview is a TAIL window of the streamed diff ("… N more lines
|
|
700
|
-
// above" + last rows); the result render re-anchors the block top-first, so
|
|
701
|
-
// committing the preview's settled head would strand a stale call-box
|
|
702
|
-
// fragment in native scrollback.
|
|
703
|
-
provisionalPendingPreview: true,
|
|
704
699
|
|
|
705
700
|
renderCall(
|
|
706
701
|
args: EditRenderArgs,
|
|
@@ -26,6 +26,7 @@ import type * as PiCodingAgent from "../../index";
|
|
|
26
26
|
import type { Theme } from "../../modes/theme/theme";
|
|
27
27
|
import type { ReadonlySessionManager } from "../../session/session-manager";
|
|
28
28
|
import type { TodoItem } from "../../tools/todo";
|
|
29
|
+
import type { RecoveredRetryError } from "../shared-events";
|
|
29
30
|
import type * as TypeBox from "../typebox";
|
|
30
31
|
|
|
31
32
|
/** Alias for clarity */
|
|
@@ -133,6 +134,7 @@ export type CustomToolSessionEvent =
|
|
|
133
134
|
success: boolean;
|
|
134
135
|
attempt: number;
|
|
135
136
|
finalError?: string;
|
|
137
|
+
recoveredErrors?: RecoveredRetryError[];
|
|
136
138
|
}
|
|
137
139
|
| {
|
|
138
140
|
reason: "ttsr_triggered";
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
*/
|
|
15
15
|
import type { AgentMessage } from "@oh-my-pi/pi-agent-core";
|
|
16
16
|
import type { CompactionPreparation, CompactionResult } from "@oh-my-pi/pi-agent-core/compaction";
|
|
17
|
-
import type { ImageContent, TextContent, ToolResultMessage } from "@oh-my-pi/pi-ai";
|
|
17
|
+
import type { AssistantRetryRecovery, ImageContent, TextContent, ToolResultMessage } from "@oh-my-pi/pi-ai";
|
|
18
18
|
import type { Rule } from "../capability/rule";
|
|
19
19
|
import type { Goal, GoalModeState } from "../goals/state";
|
|
20
20
|
import type { BranchSummaryEntry, CompactionEntry, SessionEntry } from "../session/session-entries";
|
|
@@ -241,12 +241,20 @@ export interface AutoRetryStartEvent {
|
|
|
241
241
|
errorId?: number;
|
|
242
242
|
}
|
|
243
243
|
|
|
244
|
+
export interface RecoveredRetryError {
|
|
245
|
+
entryId: string;
|
|
246
|
+
persistenceKey?: string;
|
|
247
|
+
note: string;
|
|
248
|
+
retryRecovery: AssistantRetryRecovery;
|
|
249
|
+
}
|
|
250
|
+
|
|
244
251
|
/** Fired when auto-retry ends */
|
|
245
252
|
export interface AutoRetryEndEvent {
|
|
246
253
|
type: "auto_retry_end";
|
|
247
254
|
success: boolean;
|
|
248
255
|
attempt: number;
|
|
249
256
|
finalError?: string;
|
|
257
|
+
recoveredErrors?: RecoveredRetryError[];
|
|
250
258
|
}
|
|
251
259
|
|
|
252
260
|
// ============================================================================
|