@oh-my-pi/pi-coding-agent 15.10.12 → 15.11.0
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 +60 -3
- package/dist/cli.js +841 -803
- package/dist/types/async/index.d.ts +0 -1
- package/dist/types/cli/gallery-fixtures/types.d.ts +5 -0
- package/dist/types/config/keybindings.d.ts +6 -1
- package/dist/types/config/settings-schema.d.ts +56 -33
- package/dist/types/export/html/template.generated.d.ts +1 -1
- package/dist/types/extensibility/custom-tools/types.d.ts +2 -2
- package/dist/types/extensibility/shared-events.d.ts +2 -2
- package/dist/types/internal-urls/history-protocol.d.ts +14 -0
- package/dist/types/internal-urls/index.d.ts +1 -0
- package/dist/types/internal-urls/types.d.ts +1 -1
- package/dist/types/irc/bus.d.ts +66 -0
- package/dist/types/modes/components/agent-hub.d.ts +30 -0
- package/dist/types/modes/components/compaction-summary-message.d.ts +10 -4
- package/dist/types/modes/components/custom-editor.d.ts +2 -0
- package/dist/types/modes/components/tool-execution.d.ts +8 -0
- package/dist/types/modes/components/ttsr-notification.d.ts +5 -1
- package/dist/types/modes/components/welcome.d.ts +3 -9
- package/dist/types/modes/controllers/selector-controller.d.ts +1 -1
- package/dist/types/modes/interactive-mode.d.ts +3 -2
- package/dist/types/modes/theme/theme.d.ts +2 -1
- package/dist/types/modes/types.d.ts +3 -2
- package/dist/types/modes/utils/ui-helpers.d.ts +1 -1
- package/dist/types/registry/agent-lifecycle.d.ts +51 -0
- package/dist/types/registry/agent-registry.d.ts +16 -5
- package/dist/types/session/agent-session.d.ts +35 -30
- package/dist/types/session/messages.d.ts +2 -4
- package/dist/types/session/session-history-format.d.ts +12 -0
- package/dist/types/session/session-manager.d.ts +21 -3
- package/dist/types/session/streaming-output.d.ts +23 -0
- package/dist/types/task/executor.d.ts +11 -2
- package/dist/types/task/index.d.ts +11 -4
- package/dist/types/task/output-manager.d.ts +0 -7
- package/dist/types/task/repair-args.d.ts +8 -7
- package/dist/types/task/types.d.ts +55 -51
- package/dist/types/tools/browser/tab-worker.d.ts +3 -1
- package/dist/types/tools/find.d.ts +0 -11
- package/dist/types/tools/grouped-file-output.d.ts +0 -49
- package/dist/types/tools/index.d.ts +1 -3
- package/dist/types/tools/irc.d.ts +76 -38
- package/dist/types/tools/job.d.ts +7 -1
- package/examples/extensions/with-deps/package.json +1 -0
- package/package.json +11 -10
- package/scripts/bundle-dist.ts +28 -19
- package/src/async/index.ts +0 -1
- package/src/cli/gallery-cli.ts +1 -1
- package/src/cli/gallery-fixtures/agentic.ts +230 -115
- package/src/cli/gallery-fixtures/types.ts +5 -0
- package/src/cli.ts +20 -6
- package/src/commit/agentic/tools/analyze-file.ts +38 -19
- package/src/config/keybindings.ts +6 -1
- package/src/config/settings-schema.ts +56 -40
- package/src/config/settings.ts +7 -0
- package/src/eval/__tests__/agent-bridge.test.ts +5 -3
- package/src/eval/agent-bridge.ts +3 -16
- package/src/eval/js/shared/prelude.txt +1 -1
- package/src/eval/py/prelude.py +5 -6
- package/src/export/html/template.generated.ts +1 -1
- package/src/export/html/template.js +38 -13
- package/src/extensibility/custom-tools/types.ts +2 -2
- package/src/extensibility/shared-events.ts +2 -2
- package/src/internal-urls/docs-index.generated.ts +8 -8
- package/src/internal-urls/history-protocol.ts +113 -0
- package/src/internal-urls/index.ts +1 -0
- package/src/internal-urls/router.ts +3 -1
- package/src/internal-urls/types.ts +1 -1
- package/src/irc/bus.ts +292 -0
- package/src/main.ts +8 -60
- package/src/modes/components/{session-observer-overlay.ts → agent-hub.ts} +586 -367
- package/src/modes/components/compaction-summary-message.ts +68 -32
- package/src/modes/components/custom-editor.ts +10 -0
- package/src/modes/components/tool-execution.ts +31 -1
- package/src/modes/components/ttsr-notification.ts +72 -30
- package/src/modes/components/welcome.ts +9 -33
- package/src/modes/controllers/event-controller.ts +65 -0
- package/src/modes/controllers/extension-ui-controller.ts +8 -8
- package/src/modes/controllers/input-controller.ts +18 -2
- package/src/modes/controllers/selector-controller.ts +21 -17
- package/src/modes/interactive-mode.ts +8 -13
- package/src/modes/theme/theme.ts +18 -5
- package/src/modes/types.ts +3 -5
- package/src/modes/utils/hotkeys-markdown.ts +1 -0
- package/src/modes/utils/ui-helpers.ts +51 -49
- package/src/prompts/system/irc-incoming.md +3 -4
- package/src/prompts/system/orchestrate-notice.md +2 -2
- package/src/prompts/system/subagent-system-prompt.md +0 -5
- package/src/prompts/system/system-prompt.md +1 -0
- package/src/prompts/system/workflow-notice.md +2 -2
- package/src/prompts/tools/eval.md +3 -3
- package/src/prompts/tools/irc.md +29 -19
- package/src/prompts/tools/read.md +2 -2
- package/src/prompts/tools/task-summary.md +5 -16
- package/src/prompts/tools/task.md +38 -29
- package/src/registry/agent-lifecycle.ts +218 -0
- package/src/registry/agent-registry.ts +16 -5
- package/src/sdk.ts +29 -9
- package/src/session/agent-session.ts +243 -237
- package/src/session/messages.ts +11 -78
- package/src/session/session-history-format.ts +246 -0
- package/src/session/session-manager.ts +59 -5
- package/src/session/streaming-output.ts +60 -0
- package/src/task/executor.ts +855 -466
- package/src/task/index.ts +718 -794
- package/src/task/output-manager.ts +0 -11
- package/src/task/render.ts +133 -63
- package/src/task/repair-args.ts +21 -9
- package/src/task/types.ts +73 -66
- package/src/tools/ask.ts +4 -2
- package/src/tools/bash.ts +15 -5
- package/src/tools/browser/tab-worker.ts +26 -7
- package/src/tools/browser.ts +28 -1
- package/src/tools/find.ts +2 -27
- package/src/tools/grouped-file-output.ts +1 -118
- package/src/tools/index.ts +4 -12
- package/src/tools/irc.ts +596 -171
- package/src/tools/job.ts +41 -7
- package/src/tools/read.ts +57 -1
- package/src/tools/renderers.ts +2 -0
- package/src/tools/resolve.ts +4 -1
- package/dist/types/async/support.d.ts +0 -2
- package/dist/types/modes/components/session-observer-overlay.d.ts +0 -11
- package/dist/types/task/simple-mode.d.ts +0 -8
- package/src/async/support.ts +0 -5
- package/src/task/simple-mode.ts +0 -27
package/src/tools/job.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { Component } from "@oh-my-pi/pi-tui";
|
|
|
3
3
|
import { Text } from "@oh-my-pi/pi-tui";
|
|
4
4
|
import { prompt } from "@oh-my-pi/pi-utils";
|
|
5
5
|
import * as z from "zod/v4";
|
|
6
|
-
import {
|
|
6
|
+
import type { AsyncJob, AsyncJobManager } from "../async";
|
|
7
7
|
import type { RenderResultOptions } from "../extensibility/custom-tools/types";
|
|
8
8
|
import type { Theme } from "../modes/theme/theme";
|
|
9
9
|
import jobDescription from "../prompts/tools/job.md" with { type: "text" };
|
|
@@ -65,6 +65,19 @@ export interface JobToolDetails {
|
|
|
65
65
|
cancelled?: { id: string; status: CancelStatus }[];
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
+
/**
|
|
69
|
+
* A poll snapshot where every watched job is still running and nothing was
|
|
70
|
+
* cancelled — pure "still waiting" noise once a newer poll exists. The TUI
|
|
71
|
+
* keeps such a block un-finalized (displaceable) so a follow-up `job` call
|
|
72
|
+
* replaces it instead of stacking another waiting frame in the transcript.
|
|
73
|
+
*/
|
|
74
|
+
export function isWaitingPollDetails(details: unknown): boolean {
|
|
75
|
+
const d = details as JobToolDetails | undefined;
|
|
76
|
+
if (!d || !Array.isArray(d.jobs) || d.jobs.length === 0) return false;
|
|
77
|
+
if (d.cancelled?.length) return false;
|
|
78
|
+
return d.jobs.every(job => job?.status === "running");
|
|
79
|
+
}
|
|
80
|
+
|
|
68
81
|
export class JobTool implements AgentTool<typeof jobSchema, JobToolDetails> {
|
|
69
82
|
readonly name = "job";
|
|
70
83
|
readonly approval = "read" as const;
|
|
@@ -78,11 +91,6 @@ export class JobTool implements AgentTool<typeof jobSchema, JobToolDetails> {
|
|
|
78
91
|
this.description = prompt.render(jobDescription);
|
|
79
92
|
}
|
|
80
93
|
|
|
81
|
-
static createIf(session: ToolSession): JobTool | null {
|
|
82
|
-
if (!isBackgroundJobSupportEnabled(session.settings)) return null;
|
|
83
|
-
return new JobTool(session);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
94
|
async execute(
|
|
87
95
|
_toolCallId: string,
|
|
88
96
|
params: JobParams,
|
|
@@ -378,6 +386,30 @@ function statusToColor(status: JobSnapshot["status"]): ToolUIColor {
|
|
|
378
386
|
}
|
|
379
387
|
}
|
|
380
388
|
|
|
389
|
+
/**
|
|
390
|
+
* Task job results are delivered in the model-facing `<task-result>` envelope
|
|
391
|
+
* (prompts/tools/task-summary.md) so the parent agent can parse status and the
|
|
392
|
+
* `agent://` pointer. The wrapper markup is noise to a human — preview the
|
|
393
|
+
* inner <output>/<preview> body instead.
|
|
394
|
+
*/
|
|
395
|
+
function stripTaskResultEnvelope(text: string): string {
|
|
396
|
+
if (!text.startsWith("<task-result")) return text;
|
|
397
|
+
const body = /<(output|preview)(?:\s[^>]*)?>\n?([\s\S]*?)\n?<\/\1>/.exec(text)?.[2];
|
|
398
|
+
return body?.trim() || text;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
/**
|
|
402
|
+
* Pretty-printed JSON output wastes the collapsed one-line preview on a lone
|
|
403
|
+
* "{" — flatten structured-looking bodies onto a single line. Slice first:
|
|
404
|
+
* downstream truncation keeps at most a few hundred columns, so collapsing
|
|
405
|
+
* whitespace across a multi-KB body would be pure waste.
|
|
406
|
+
*/
|
|
407
|
+
function flattenStructuredPreview(text: string): string {
|
|
408
|
+
const first = text[0];
|
|
409
|
+
if (first !== "{" && first !== "[") return text;
|
|
410
|
+
return text.slice(0, PREVIEW_LINES_EXPANDED * PREVIEW_LINE_WIDTH * 2).replace(/\s+/g, " ");
|
|
411
|
+
}
|
|
412
|
+
|
|
381
413
|
function describeTarget(args: JobRenderArgs | undefined): string {
|
|
382
414
|
const poll = args?.poll ?? [];
|
|
383
415
|
const cancel = args?.cancel ?? [];
|
|
@@ -494,7 +526,9 @@ export const jobToolRenderer = {
|
|
|
494
526
|
lines.push(` ${uiTheme.fg("toolOutput", visibleLabelLines[i]!)}`);
|
|
495
527
|
}
|
|
496
528
|
|
|
497
|
-
const preview =
|
|
529
|
+
const preview = flattenStructuredPreview(
|
|
530
|
+
stripTaskResultEnvelope(job.errorText?.trim() || job.resultText?.trim() || ""),
|
|
531
|
+
);
|
|
498
532
|
if (preview) {
|
|
499
533
|
const maxLines = expanded ? PREVIEW_LINES_EXPANDED : PREVIEW_LINES_COLLAPSED;
|
|
500
534
|
const previewLines = getPreviewLines(preview, maxLines, PREVIEW_LINE_WIDTH, Ellipsis.Unicode);
|
package/src/tools/read.ts
CHANGED
|
@@ -736,6 +736,17 @@ interface ResolvedSqliteReadPath {
|
|
|
736
736
|
/** Per-execute memo of suffix-glob lookups; `null` records a confirmed miss. */
|
|
737
737
|
type SuffixMatchCache = Map<string, { absolutePath: string; displayPath: string } | null>;
|
|
738
738
|
|
|
739
|
+
/**
|
|
740
|
+
* Repeated whole-file reads of the same path pin stale copies in context.
|
|
741
|
+
* From this per-session read count onward, file reads carry a trailing nudge
|
|
742
|
+
* to prefer narrower re-reads.
|
|
743
|
+
*/
|
|
744
|
+
const REPEAT_READ_NOTICE_THRESHOLD = 3;
|
|
745
|
+
|
|
746
|
+
function formatRepeatReadNotice(count: number): string {
|
|
747
|
+
return `[note: read #${count} of this file this session — after edits, prefer the context echoed in the edit result or a narrow range re-read]`;
|
|
748
|
+
}
|
|
749
|
+
|
|
739
750
|
/**
|
|
740
751
|
* Read tool implementation.
|
|
741
752
|
*
|
|
@@ -754,6 +765,8 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
|
|
|
754
765
|
readonly #autoResizeImages: boolean;
|
|
755
766
|
readonly #defaultLimit: number;
|
|
756
767
|
readonly #inspectImageEnabled: boolean;
|
|
768
|
+
/** Successful file reads per resolved base path (selector stripped) this session. */
|
|
769
|
+
readonly #readCounts = new Map<string, number>();
|
|
757
770
|
|
|
758
771
|
constructor(private readonly session: ToolSession) {
|
|
759
772
|
const displayMode = resolveFileDisplayMode(session);
|
|
@@ -772,6 +785,19 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
|
|
|
772
785
|
});
|
|
773
786
|
}
|
|
774
787
|
|
|
788
|
+
/**
|
|
789
|
+
* Count a file read of `absolutePath` and return the repeat-read nudge once
|
|
790
|
+
* the per-session count reaches {@link REPEAT_READ_NOTICE_THRESHOLD}.
|
|
791
|
+
* Non-file sources (URLs, internal resources, directories, archives,
|
|
792
|
+
* SQLite, images) are never counted.
|
|
793
|
+
*/
|
|
794
|
+
#repeatReadNotice(absolutePath: string): string | undefined {
|
|
795
|
+
const count = (this.#readCounts.get(absolutePath) ?? 0) + 1;
|
|
796
|
+
this.#readCounts.set(absolutePath, count);
|
|
797
|
+
if (count < REPEAT_READ_NOTICE_THRESHOLD) return undefined;
|
|
798
|
+
return formatRepeatReadNotice(count);
|
|
799
|
+
}
|
|
800
|
+
|
|
775
801
|
async #tryReadDelimitedPaths(
|
|
776
802
|
readPath: string,
|
|
777
803
|
signal?: AbortSignal,
|
|
@@ -948,6 +974,8 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
|
|
|
948
974
|
ignoreResultLimits?: boolean;
|
|
949
975
|
raw?: boolean;
|
|
950
976
|
immutable?: boolean;
|
|
977
|
+
/** Trailing repeat-read nudge; appended at the very end of the text. */
|
|
978
|
+
repeatNotice?: string;
|
|
951
979
|
},
|
|
952
980
|
): AgentToolResult<ReadToolDetails> {
|
|
953
981
|
const displayMode = resolveFileDisplayMode(this.session, { raw: options.raw, immutable: options.immutable });
|
|
@@ -1092,6 +1120,9 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
|
|
|
1092
1120
|
: formatLineEntries(buildLineEntries(endLine), startLineDisplay);
|
|
1093
1121
|
}
|
|
1094
1122
|
|
|
1123
|
+
if (options.repeatNotice) {
|
|
1124
|
+
outputText += `\n${options.repeatNotice}`;
|
|
1125
|
+
}
|
|
1095
1126
|
resultBuilder.text(outputText);
|
|
1096
1127
|
if (truncationInfo) {
|
|
1097
1128
|
resultBuilder.truncation(truncationInfo.result, truncationInfo.options);
|
|
@@ -1117,6 +1148,8 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
|
|
|
1117
1148
|
entityLabel: string;
|
|
1118
1149
|
raw?: boolean;
|
|
1119
1150
|
immutable?: boolean;
|
|
1151
|
+
/** Trailing repeat-read nudge; appended at the very end of the text. */
|
|
1152
|
+
repeatNotice?: string;
|
|
1120
1153
|
},
|
|
1121
1154
|
): AgentToolResult<ReadToolDetails> {
|
|
1122
1155
|
const displayMode = resolveFileDisplayMode(this.session, { raw: options.raw, immutable: options.immutable });
|
|
@@ -1177,8 +1210,11 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
|
|
|
1177
1210
|
const bound = range.endLine !== undefined ? `${range.startLine}-${range.endLine}` : `${range.startLine}`;
|
|
1178
1211
|
notices.push(`[Range ${bound} is beyond end of ${options.entityLabel} (${totalLines} lines total); skipped]`);
|
|
1179
1212
|
}
|
|
1180
|
-
|
|
1213
|
+
let finalText =
|
|
1181
1214
|
notices.length > 0 ? (outputText ? `${outputText}\n${notices.join("\n")}` : notices.join("\n")) : outputText;
|
|
1215
|
+
if (options.repeatNotice) {
|
|
1216
|
+
finalText = finalText ? `${finalText}\n${options.repeatNotice}` : options.repeatNotice;
|
|
1217
|
+
}
|
|
1182
1218
|
resultBuilder.text(finalText);
|
|
1183
1219
|
return resultBuilder.done();
|
|
1184
1220
|
}
|
|
@@ -1196,6 +1232,7 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
|
|
|
1196
1232
|
parsed: ParsedSelector,
|
|
1197
1233
|
displayMode: { hashLines: boolean; lineNumbers: boolean },
|
|
1198
1234
|
suffixResolution: { from: string; to: string } | undefined,
|
|
1235
|
+
repeatNotice: string | undefined,
|
|
1199
1236
|
signal: AbortSignal | undefined,
|
|
1200
1237
|
): Promise<{
|
|
1201
1238
|
outputText: string;
|
|
@@ -1215,6 +1252,7 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
|
|
|
1215
1252
|
sourcePath: absolutePath,
|
|
1216
1253
|
entityLabel: "file",
|
|
1217
1254
|
raw: rawSelector,
|
|
1255
|
+
repeatNotice,
|
|
1218
1256
|
});
|
|
1219
1257
|
if (suffixResolution) {
|
|
1220
1258
|
const notice = `[Path '${suffixResolution.from}' not found; resolved to '${suffixResolution.to}' via suffix match]`;
|
|
@@ -1896,6 +1934,7 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
|
|
|
1896
1934
|
let details: ReadToolDetails = {};
|
|
1897
1935
|
let sourcePath: string | undefined;
|
|
1898
1936
|
let columnTruncated = 0;
|
|
1937
|
+
let repeatNotice: string | undefined;
|
|
1899
1938
|
let truncationInfo:
|
|
1900
1939
|
| { result: TruncationResult; options: { direction: "head"; startLine?: number; totalFileLines?: number } }
|
|
1901
1940
|
| undefined;
|
|
@@ -1960,11 +1999,13 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
|
|
|
1960
1999
|
}
|
|
1961
2000
|
} else if (isNotebookPath(absolutePath) && !isRawSelector(parsed)) {
|
|
1962
2001
|
const notebookText = await readEditableNotebookText(absolutePath, localReadPath);
|
|
2002
|
+
repeatNotice = this.#repeatReadNotice(absolutePath);
|
|
1963
2003
|
if (isMultiRange(parsed) && parsed.kind === "lines") {
|
|
1964
2004
|
return this.#buildInMemoryMultiRangeResult(notebookText, parsed.ranges, {
|
|
1965
2005
|
details: { resolvedPath: absolutePath },
|
|
1966
2006
|
sourcePath: absolutePath,
|
|
1967
2007
|
entityLabel: "notebook",
|
|
2008
|
+
repeatNotice,
|
|
1968
2009
|
});
|
|
1969
2010
|
}
|
|
1970
2011
|
const { offset, limit } = selToOffsetLimit(parsed);
|
|
@@ -1972,11 +2013,13 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
|
|
|
1972
2013
|
details: { resolvedPath: absolutePath },
|
|
1973
2014
|
sourcePath: absolutePath,
|
|
1974
2015
|
entityLabel: "notebook",
|
|
2016
|
+
repeatNotice,
|
|
1975
2017
|
});
|
|
1976
2018
|
} else if (shouldConvertWithMarkit) {
|
|
1977
2019
|
// Convert document via markit.
|
|
1978
2020
|
const result = await convertFileWithMarkit(absolutePath, signal);
|
|
1979
2021
|
if (result.ok) {
|
|
2022
|
+
repeatNotice = this.#repeatReadNotice(absolutePath);
|
|
1980
2023
|
// Route the converted markdown through the in-memory text builder
|
|
1981
2024
|
// so line-range selectors (`file.pdf:50-100`, `:5-16,40-80`) and
|
|
1982
2025
|
// raw mode apply against the converted output. Without this,
|
|
@@ -1987,6 +2030,7 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
|
|
|
1987
2030
|
details: { resolvedPath: absolutePath },
|
|
1988
2031
|
sourcePath: absolutePath,
|
|
1989
2032
|
entityLabel: "document",
|
|
2033
|
+
repeatNotice,
|
|
1990
2034
|
});
|
|
1991
2035
|
}
|
|
1992
2036
|
const { offset, limit } = selToOffsetLimit(parsed);
|
|
@@ -1995,6 +2039,7 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
|
|
|
1995
2039
|
sourcePath: absolutePath,
|
|
1996
2040
|
entityLabel: "document",
|
|
1997
2041
|
raw: isRawSelector(parsed),
|
|
2042
|
+
repeatNotice,
|
|
1998
2043
|
});
|
|
1999
2044
|
} else if (result.error) {
|
|
2000
2045
|
content = [{ type: "text", text: `[Cannot read ${ext} file: ${result.error || "conversion failed"}]` }];
|
|
@@ -2002,6 +2047,7 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
|
|
|
2002
2047
|
content = [{ type: "text", text: `[Cannot read ${ext} file: conversion failed]` }];
|
|
2003
2048
|
}
|
|
2004
2049
|
} else {
|
|
2050
|
+
repeatNotice = this.#repeatReadNotice(absolutePath);
|
|
2005
2051
|
if (
|
|
2006
2052
|
parsed.kind === "none" &&
|
|
2007
2053
|
this.session.settings.get("read.summarize.enabled") &&
|
|
@@ -2043,6 +2089,7 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
|
|
|
2043
2089
|
parsed,
|
|
2044
2090
|
displayMode,
|
|
2045
2091
|
suffixResolution,
|
|
2092
|
+
repeatNotice,
|
|
2046
2093
|
undefined, // plain-file read: deterministic and fast, never abort mid-read
|
|
2047
2094
|
);
|
|
2048
2095
|
if (multiResult.bridgeResult) return multiResult.bridgeResult;
|
|
@@ -2066,6 +2113,7 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
|
|
|
2066
2113
|
sourcePath: absolutePath,
|
|
2067
2114
|
entityLabel: "file",
|
|
2068
2115
|
raw: isRawSelector(parsed),
|
|
2116
|
+
repeatNotice,
|
|
2069
2117
|
});
|
|
2070
2118
|
if (suffixResolution) {
|
|
2071
2119
|
const notice = `[Path '${suffixResolution.from}' not found; resolved to '${suffixResolution.to}' via suffix match]`;
|
|
@@ -2367,6 +2415,14 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
|
|
|
2367
2415
|
content = [{ type: "text", text: notice }, ...content];
|
|
2368
2416
|
}
|
|
2369
2417
|
}
|
|
2418
|
+
if (repeatNotice) {
|
|
2419
|
+
// Trailing nudge goes at the very end of the textual result so it never
|
|
2420
|
+
// disturbs hashline tag headers or inline notices.
|
|
2421
|
+
const lastText = content.findLast((c): c is TextContent => c.type === "text");
|
|
2422
|
+
if (lastText) {
|
|
2423
|
+
lastText.text = `${lastText.text}\n${repeatNotice}`;
|
|
2424
|
+
}
|
|
2425
|
+
}
|
|
2370
2426
|
const resultBuilder = toolResult(details).content(content);
|
|
2371
2427
|
if (sourcePath) {
|
|
2372
2428
|
resultBuilder.sourcePath(sourcePath);
|
package/src/tools/renderers.ts
CHANGED
|
@@ -21,6 +21,7 @@ import { evalToolRenderer } from "./eval-render";
|
|
|
21
21
|
import { findToolRenderer } from "./find";
|
|
22
22
|
import { githubToolRenderer } from "./gh-renderer";
|
|
23
23
|
import { inspectImageToolRenderer } from "./inspect-image-renderer";
|
|
24
|
+
import { ircToolRenderer } from "./irc";
|
|
24
25
|
import { jobToolRenderer } from "./job";
|
|
25
26
|
import { recallToolRenderer, reflectToolRenderer, retainToolRenderer } from "./memory-render";
|
|
26
27
|
import { readToolRenderer } from "./read";
|
|
@@ -58,6 +59,7 @@ export const toolRenderers: Record<string, ToolRenderer> = {
|
|
|
58
59
|
search: searchToolRenderer as ToolRenderer,
|
|
59
60
|
lsp: lspToolRenderer as ToolRenderer,
|
|
60
61
|
inspect_image: inspectImageToolRenderer as ToolRenderer,
|
|
62
|
+
irc: ircToolRenderer as ToolRenderer,
|
|
61
63
|
read: readToolRenderer as ToolRenderer,
|
|
62
64
|
job: jobToolRenderer as ToolRenderer,
|
|
63
65
|
resolve: resolveToolRenderer as ToolRenderer,
|
package/src/tools/resolve.ts
CHANGED
|
@@ -241,7 +241,10 @@ export const resolveToolRenderer = {
|
|
|
241
241
|
const isApply = action === "apply" && !result.isError;
|
|
242
242
|
const isFailedApply = action === "apply" && result.isError;
|
|
243
243
|
const bgColor = result.isError ? "error" : isApply ? "success" : "warning";
|
|
244
|
-
|
|
244
|
+
// Bare symbol: the line is wrapped in inverse(fg(...)), so any embedded fg
|
|
245
|
+
// reset (styledSymbol/status glyphs carry their own \x1b[39m) would drop the
|
|
246
|
+
// inverse block back to the default background mid-line.
|
|
247
|
+
const icon = uiTheme.symbol(isApply ? "tool.resolve" : "status.error");
|
|
245
248
|
const verb = isApply ? "Accept" : isFailedApply ? "Failed" : "Discard";
|
|
246
249
|
const separator = ": ";
|
|
247
250
|
const separatorIndex = label.indexOf(separator);
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { Container } from "@oh-my-pi/pi-tui";
|
|
2
|
-
import type { KeyId } from "../../config/keybindings";
|
|
3
|
-
import type { SessionObserverRegistry } from "../session-observer-registry";
|
|
4
|
-
export declare class SessionObserverOverlayComponent extends Container {
|
|
5
|
-
#private;
|
|
6
|
-
constructor(registry: SessionObserverRegistry, onDone: () => void, observeKeys: KeyId[]);
|
|
7
|
-
render(width: number): readonly string[];
|
|
8
|
-
/** Rebuild content from live registry data */
|
|
9
|
-
refreshFromRegistry(): void;
|
|
10
|
-
handleInput(keyData: string): void;
|
|
11
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export declare const TASK_SIMPLE_MODES: readonly ["default", "schema-free", "independent"];
|
|
2
|
-
export type TaskSimpleMode = (typeof TASK_SIMPLE_MODES)[number];
|
|
3
|
-
interface TaskSimpleModeCapabilities {
|
|
4
|
-
contextEnabled: boolean;
|
|
5
|
-
customSchemaEnabled: boolean;
|
|
6
|
-
}
|
|
7
|
-
export declare function getTaskSimpleModeCapabilities(mode: TaskSimpleMode): TaskSimpleModeCapabilities;
|
|
8
|
-
export {};
|
package/src/async/support.ts
DELETED
package/src/task/simple-mode.ts
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
export const TASK_SIMPLE_MODES = ["default", "schema-free", "independent"] as const;
|
|
2
|
-
|
|
3
|
-
export type TaskSimpleMode = (typeof TASK_SIMPLE_MODES)[number];
|
|
4
|
-
|
|
5
|
-
interface TaskSimpleModeCapabilities {
|
|
6
|
-
contextEnabled: boolean;
|
|
7
|
-
customSchemaEnabled: boolean;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
const TASK_SIMPLE_MODE_CAPABILITIES: Record<TaskSimpleMode, TaskSimpleModeCapabilities> = {
|
|
11
|
-
default: {
|
|
12
|
-
contextEnabled: true,
|
|
13
|
-
customSchemaEnabled: true,
|
|
14
|
-
},
|
|
15
|
-
"schema-free": {
|
|
16
|
-
contextEnabled: true,
|
|
17
|
-
customSchemaEnabled: false,
|
|
18
|
-
},
|
|
19
|
-
independent: {
|
|
20
|
-
contextEnabled: false,
|
|
21
|
-
customSchemaEnabled: false,
|
|
22
|
-
},
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
export function getTaskSimpleModeCapabilities(mode: TaskSimpleMode): TaskSimpleModeCapabilities {
|
|
26
|
-
return TASK_SIMPLE_MODE_CAPABILITIES[mode];
|
|
27
|
-
}
|