@oh-my-pi/pi-coding-agent 17.2.14 → 17.2.15
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 +24 -0
- package/dist/{CHANGELOG-za420td8.md → CHANGELOG-fk29zh06.md} +24 -0
- package/dist/cli.js +4696 -5008
- package/dist/types/cleanse/agent.d.ts +3 -0
- package/dist/types/cleanse/checkers.d.ts +21 -1
- package/dist/types/cleanse/index.d.ts +4 -0
- package/dist/types/cleanse/parsers.d.ts +3 -1
- package/dist/types/cli/args.d.ts +1 -0
- package/dist/types/cli/cleanse-picker.d.ts +17 -0
- package/dist/types/cli/command-help.d.ts +3 -0
- package/dist/types/cli/progress-reporter.d.ts +19 -0
- package/dist/types/commands/cleanse.d.ts +11 -0
- package/dist/types/commands/compress.d.ts +37 -0
- package/dist/types/commands/launch-help.d.ts +3 -0
- package/dist/types/commands/launch.d.ts +3 -0
- package/dist/types/compress/index.d.ts +27 -0
- package/dist/types/compress/protocol.d.ts +49 -0
- package/dist/types/compress/session.d.ts +15 -0
- package/dist/types/compress/types.d.ts +54 -0
- package/dist/types/config/settings-schema.d.ts +1 -1
- package/dist/types/internal-urls/local-protocol.d.ts +8 -0
- package/dist/types/mcp/transports/header-policy.d.ts +8 -0
- package/dist/types/mcp/transports/http.d.ts +2 -0
- package/dist/types/mcp/types.d.ts +19 -0
- package/dist/types/modes/components/late-diagnostics-message.d.ts +2 -0
- package/dist/types/modes/components/todo-reminder.d.ts +2 -0
- package/dist/types/modes/components/tool-activity.d.ts +17 -0
- package/dist/types/modes/components/transcript-container.d.ts +2 -0
- package/dist/types/modes/components/ttsr-notification.d.ts +2 -0
- package/dist/types/modes/interactive-mode.d.ts +3 -1
- package/dist/types/modes/types.d.ts +3 -1
- package/dist/types/modes/utils/transcript-render-helpers.d.ts +2 -1
- package/dist/types/modes/utils/ui-helpers.d.ts +3 -1
- package/dist/types/session/session-tools.d.ts +2 -0
- package/dist/types/tools/think.d.ts +6 -3
- package/dist/types/utils/zip.d.ts +19 -9
- package/package.json +13 -13
- package/src/cleanse/agent.ts +67 -2
- package/src/cleanse/checkers.ts +252 -21
- package/src/cleanse/index.ts +90 -36
- package/src/cleanse/parsers.ts +243 -20
- package/src/cleanse/prompts/discovery.md +74 -0
- package/src/cli/args.ts +3 -0
- package/src/cli/cleanse-picker.ts +86 -0
- package/src/cli/command-help.ts +4 -0
- package/src/cli/flag-tables.ts +1 -0
- package/src/cli/gallery-fixtures/agentic.ts +3 -3
- package/src/{cleanse/progress.ts → cli/progress-reporter.ts} +12 -7
- package/src/cli-commands.ts +5 -0
- package/src/commands/cleanse.ts +19 -4
- package/src/commands/compress.ts +45 -0
- package/src/commands/launch-help.ts +3 -0
- package/src/commit/agentic/prompts/analyze-file.md +6 -6
- package/src/commit/agentic/prompts/session-user.md +4 -4
- package/src/compress/index.ts +318 -0
- package/src/compress/prompts/request.md +11 -0
- package/src/compress/prompts/review.md +17 -0
- package/src/compress/prompts/system.md +81 -0
- package/src/compress/protocol.ts +210 -0
- package/src/compress/session.ts +72 -0
- package/src/compress/types.ts +59 -0
- package/src/config/settings-schema.ts +1 -1
- package/src/discovery/builtin-rules/go-add-cleanup.md +8 -8
- package/src/discovery/builtin-rules/go-exp-promoted.md +8 -8
- package/src/discovery/builtin-rules/go-ioutil.md +12 -12
- package/src/discovery/builtin-rules/go-new-expr.md +8 -8
- package/src/discovery/builtin-rules/go-range-int.md +5 -5
- package/src/discovery/builtin-rules/rs-box-leak.md +7 -7
- package/src/discovery/builtin-rules/rs-future-prelude.md +4 -4
- package/src/discovery/builtin-rules/rs-parking-lot.md +6 -6
- package/src/discovery/builtin-rules/ts-no-any.md +5 -5
- package/src/discovery/builtin-rules/ts-no-deprecated-leftovers.md +8 -8
- package/src/discovery/builtin-rules/ts-no-inline-cast-access.md +13 -14
- package/src/discovery/builtin-rules/ts-no-local-is-record.md +7 -7
- package/src/discovery/builtin-rules/ts-no-test-timers.md +3 -9
- package/src/discovery/builtin-rules/ts-no-tiny-functions.md +7 -7
- package/src/discovery/builtin-rules/ts-promise-with-resolvers.md +2 -2
- package/src/discovery/builtin-rules/ts-redundant-clear-guard.md +3 -9
- package/src/discovery/builtin-rules/ts-set-map.md +2 -4
- package/src/internal-urls/local-protocol.ts +42 -0
- package/src/live/prompts/live-instructions.md +10 -10
- package/src/main.ts +4 -0
- package/src/mcp/client.ts +7 -3
- package/src/mcp/transports/header-policy.ts +28 -0
- package/src/mcp/transports/http.ts +200 -35
- package/src/mcp/types.ts +21 -0
- package/src/modes/components/chat-transcript-builder.ts +17 -5
- package/src/modes/components/late-diagnostics-message.ts +12 -1
- package/src/modes/components/todo-reminder.ts +12 -0
- package/src/modes/components/tool-activity.ts +45 -0
- package/src/modes/components/transcript-container.ts +16 -0
- package/src/modes/components/ttsr-notification.ts +12 -0
- package/src/modes/controllers/event-controller.ts +3 -6
- package/src/modes/controllers/input-controller.ts +6 -6
- package/src/modes/controllers/selector-controller.ts +3 -6
- package/src/modes/interactive-mode.ts +5 -40
- package/src/modes/print-mode.ts +13 -54
- package/src/modes/types.ts +1 -1
- package/src/modes/utils/transcript-render-helpers.ts +3 -2
- package/src/modes/utils/ui-helpers.ts +17 -7
- package/src/prompts/advisor/active-repo-watchdog.md +3 -4
- package/src/prompts/advisor/advise-tool.md +3 -3
- package/src/prompts/advisor/context-files.md +1 -1
- package/src/prompts/advisor/system.md +45 -65
- package/src/prompts/agents/designer.md +44 -44
- package/src/prompts/agents/init.md +18 -18
- package/src/prompts/agents/librarian.md +31 -31
- package/src/prompts/agents/reviewer.md +34 -39
- package/src/prompts/agents/security-reviewer.md +3 -5
- package/src/prompts/agents/task.md +11 -12
- package/src/prompts/bench.md +2 -5
- package/src/prompts/ci-green-request.md +13 -15
- package/src/prompts/dry-balance-bench.md +5 -5
- package/src/prompts/goals/goal-budget-limit.md +4 -5
- package/src/prompts/goals/goal-continuation.md +11 -11
- package/src/prompts/goals/goal-mode-active.md +7 -7
- package/src/prompts/goals/goal-todo-context.md +2 -2
- package/src/prompts/goals/guided-goal-interview.md +18 -24
- package/src/prompts/memories/read-path.md +9 -9
- package/src/prompts/memories/stage_one_system.md +9 -11
- package/src/prompts/review-custom-request.md +8 -11
- package/src/prompts/review-headless-request.md +3 -10
- package/src/prompts/security/scan-coordinator.md +6 -5
- package/src/prompts/security/validate-request.md +4 -7
- package/src/prompts/skills/user-invocation.md +2 -2
- package/src/prompts/steering/parent-irc.md +1 -1
- package/src/prompts/steering/user-interjection.md +1 -3
- package/src/prompts/system/active-repo-context.md +4 -2
- package/src/prompts/system/agent-creation-architect.md +22 -37
- package/src/prompts/system/agent-creation-user.md +3 -3
- package/src/prompts/system/auto-continue.md +1 -1
- package/src/prompts/system/auto-thinking-difficulty-local.md +5 -7
- package/src/prompts/system/auto-thinking-difficulty.md +8 -10
- package/src/prompts/system/autolearn-guidance-learn.md +2 -1
- package/src/prompts/system/autolearn-guidance.md +5 -4
- package/src/prompts/system/autolearn-nudge-autocontinue.md +3 -3
- package/src/prompts/system/background-tan-dispatch.md +3 -3
- package/src/prompts/system/btw-user.md +2 -2
- package/src/prompts/system/commit-message-system.md +8 -6
- package/src/prompts/system/eager-task.md +3 -3
- package/src/prompts/system/empty-stop-retry.md +1 -1
- package/src/prompts/system/gemini-tool-call-reminder.md +5 -5
- package/src/prompts/system/interrupted-thinking.md +3 -3
- package/src/prompts/system/irc-autoreply.md +1 -1
- package/src/prompts/system/irc-incoming.md +3 -3
- package/src/prompts/system/manual-continue.md +3 -3
- package/src/prompts/system/mcp-xdev-guidance.md +2 -2
- package/src/prompts/system/memory-consolidation-system.md +2 -2
- package/src/prompts/system/mid-run-todo-nudge.md +1 -1
- package/src/prompts/system/orchestrate-notice.md +25 -25
- package/src/prompts/system/personalities/default.md +9 -9
- package/src/prompts/system/personalities/friendly.md +11 -11
- package/src/prompts/system/personalities/pragmatic.md +8 -8
- package/src/prompts/system/plan-mode-active.md +61 -64
- package/src/prompts/system/plan-mode-approved.md +10 -11
- package/src/prompts/system/plan-mode-compact-instructions.md +11 -11
- package/src/prompts/system/plan-mode-reference.md +5 -5
- package/src/prompts/system/plan-yolo-handoff.md +2 -2
- package/src/prompts/system/prewalk-checklist.md +5 -5
- package/src/prompts/system/prewalk-continue.md +1 -1
- package/src/prompts/system/prewalk-plan.md +8 -9
- package/src/prompts/system/project-prompt.md +11 -12
- package/src/prompts/system/recap-user.md +1 -1
- package/src/prompts/system/resolve-device-reminder.md +1 -1
- package/src/prompts/system/rewind-report.md +3 -3
- package/src/prompts/system/side-channel-no-tools.md +3 -1
- package/src/prompts/system/snapcompact-context-stub.md +1 -1
- package/src/prompts/system/snapcompact-system-frames-note.md +1 -1
- package/src/prompts/system/snapcompact-system-stub.md +1 -1
- package/src/prompts/system/snapcompact-toolresult-note.md +1 -1
- package/src/prompts/system/speech-rewrite.md +11 -13
- package/src/prompts/system/subagent-async-pending.md +5 -5
- package/src/prompts/system/subagent-system-prompt.md +5 -15
- package/src/prompts/system/subagent-user-prompt.md +1 -1
- package/src/prompts/system/subagent-yield-reminder.md +12 -12
- package/src/prompts/system/system-prompt.md +108 -143
- package/src/prompts/system/tan-context-switch.md +8 -14
- package/src/prompts/system/task-label.md +3 -3
- package/src/prompts/system/thinking-loop-redirect.md +6 -6
- package/src/prompts/system/title-marker-instruction.md +2 -1
- package/src/prompts/system/title-system.md +3 -5
- package/src/prompts/system/ttsr-interrupt.md +3 -3
- package/src/prompts/system/ttsr-tool-reminder.md +1 -1
- package/src/prompts/system/ultrathink-notice.md +1 -1
- package/src/prompts/system/unexpected-stop-classifier.md +3 -3
- package/src/prompts/system/vibe-mode-active.md +15 -15
- package/src/prompts/system/web-search.md +16 -16
- package/src/prompts/system/workflow-notice.md +35 -33
- package/src/prompts/system/xdev-mount-notice.md +4 -4
- package/src/prompts/tools/apply-patch.md +22 -23
- package/src/prompts/tools/approve.md +5 -0
- package/src/prompts/tools/ask.md +10 -10
- package/src/prompts/tools/checkpoint.md +7 -7
- package/src/prompts/tools/computer.md +16 -16
- package/src/prompts/tools/github.md +12 -12
- package/src/prompts/tools/goal.md +8 -9
- package/src/prompts/tools/grep.md +5 -5
- package/src/prompts/tools/image-attachment-describe-system.md +6 -6
- package/src/prompts/tools/image-attachment-describe.md +3 -8
- package/src/prompts/tools/image-gen.md +4 -4
- package/src/prompts/tools/inspect-image-system.md +10 -10
- package/src/prompts/tools/inspect-image.md +10 -13
- package/src/prompts/tools/learn.md +4 -4
- package/src/prompts/tools/manage-skill.md +9 -6
- package/src/prompts/tools/memory-edit.md +8 -8
- package/src/prompts/tools/recall.md +4 -4
- package/src/prompts/tools/reflect.md +2 -2
- package/src/prompts/tools/replace.md +13 -11
- package/src/prompts/tools/retain.md +3 -4
- package/src/prompts/tools/rewind.md +7 -8
- package/src/prompts/tools/rewrite.md +12 -0
- package/src/prompts/tools/security-publish.md +5 -1
- package/src/prompts/tools/security-scan.md +10 -1
- package/src/prompts/tools/task-async-contract.md +7 -1
- package/src/prompts/tools/todo.md +27 -25
- package/src/prompts/tools/vibe-kill.md +2 -2
- package/src/prompts/tools/vibe-list.md +2 -2
- package/src/prompts/tools/vibe-send.md +6 -7
- package/src/prompts/tools/vibe-spawn.md +8 -6
- package/src/prompts/tools/web-search.md +5 -5
- package/src/sdk.ts +4 -1
- package/src/session/agent-session.ts +7 -4
- package/src/session/session-handoff.ts +21 -0
- package/src/session/session-tools.ts +12 -0
- package/src/tools/index.ts +6 -4
- package/src/tools/read-format.ts +8 -3
- package/src/tools/read.ts +18 -7
- package/src/tools/think.ts +28 -6
- package/src/tools/write.ts +1 -1
- package/src/utils/file-mentions.ts +8 -2
- package/src/utils/zip.ts +858 -94
- package/dist/types/cleanse/progress.d.ts +0 -14
package/src/tools/index.ts
CHANGED
|
@@ -62,7 +62,7 @@ import { wrapToolWithMetaNotice } from "./output-meta";
|
|
|
62
62
|
import { ReadTool } from "./read";
|
|
63
63
|
import type { PlanProposalHandler } from "./resolve";
|
|
64
64
|
import { SecurityScanTool } from "./security-scan";
|
|
65
|
-
import { ThinkTool } from "./think";
|
|
65
|
+
import { supportsExternalThinking, ThinkTool } from "./think";
|
|
66
66
|
import { type TodoPhase, TodoTool } from "./todo";
|
|
67
67
|
import { WriteTool } from "./write";
|
|
68
68
|
import { isMountableUnderXdev, type XdevState } from "./xdev";
|
|
@@ -467,6 +467,8 @@ export async function createTools(session: ToolSession, toolNames?: string[]): P
|
|
|
467
467
|
: undefined;
|
|
468
468
|
const goalEnabled = session.settings.get("goal.enabled");
|
|
469
469
|
const goalModeActive = !restrictToolNames && goalEnabled && session.getGoalModeState?.()?.enabled === true;
|
|
470
|
+
const externalThinkingActive =
|
|
471
|
+
session.settings.get("externalThinking") && supportsExternalThinking(session.getActiveModel?.());
|
|
470
472
|
if (goalModeActive && requestedTools && !requestedTools.includes("goal")) {
|
|
471
473
|
requestedTools.push("goal");
|
|
472
474
|
}
|
|
@@ -565,7 +567,7 @@ export async function createTools(session: ToolSession, toolNames?: string[]): P
|
|
|
565
567
|
if (session.settings.get("memory.backend") === "mnemopi" && !requestedTools.includes("memory_edit")) {
|
|
566
568
|
requestedTools.push("memory_edit");
|
|
567
569
|
}
|
|
568
|
-
if (
|
|
570
|
+
if (externalThinkingActive && !requestedTools.includes("think")) {
|
|
569
571
|
requestedTools.push("think");
|
|
570
572
|
}
|
|
571
573
|
// Auto-learn tools are gated by `autolearn.enabled` but, like the memory
|
|
@@ -610,7 +612,7 @@ export async function createTools(session: ToolSession, toolNames?: string[]): P
|
|
|
610
612
|
if (name === "inspect_image") return isInspectImageToolActive(session);
|
|
611
613
|
if (name === "web_search") return session.settings.get("web_search.enabled");
|
|
612
614
|
if (name === "security_scan") return session.settings.get("security.enabled");
|
|
613
|
-
if (name === "think") return
|
|
615
|
+
if (name === "think") return externalThinkingActive;
|
|
614
616
|
if (name === "ask") return session.settings.get("ask.enabled");
|
|
615
617
|
if (name === "browser") return session.settings.get("browser.enabled");
|
|
616
618
|
if (name === "computer") return session.settings.get("computer.enabled");
|
|
@@ -657,7 +659,7 @@ export async function createTools(session: ToolSession, toolNames?: string[]): P
|
|
|
657
659
|
...Object.entries(BUILTIN_TOOLS)
|
|
658
660
|
.filter(([name]) => isToolAllowed(name))
|
|
659
661
|
.map(([name, factory]) => [name, factory] as const),
|
|
660
|
-
...(
|
|
662
|
+
...(externalThinkingActive ? ([["think", HIDDEN_TOOLS.think]] as const) : []),
|
|
661
663
|
...(includeYield ? ([["yield", HIDDEN_TOOLS.yield]] as const) : []),
|
|
662
664
|
...(goalModeActive ? ([["goal", HIDDEN_TOOLS.goal]] as const) : []),
|
|
663
665
|
];
|
package/src/tools/read-format.ts
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import * as path from "node:path";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
formatHashlineHeader,
|
|
4
|
+
formatNumberedLine,
|
|
5
|
+
formatNumberedLines,
|
|
6
|
+
splitAddressableFileLines,
|
|
7
|
+
} from "@oh-my-pi/hashline";
|
|
3
8
|
import type { AgentToolResult } from "@oh-my-pi/pi-agent-core";
|
|
4
9
|
import { canonicalSnapshotKey, getFileSnapshotStore, recordSeenLines } from "../edit/file-snapshot-store";
|
|
5
10
|
import { normalizeToLF } from "../edit/normalize";
|
|
@@ -290,7 +295,7 @@ export function buildInMemoryTextResult(
|
|
|
290
295
|
): AgentToolResult<ReadToolDetails> {
|
|
291
296
|
const displayMode = resolveFileDisplayMode(session, { raw: options.raw, immutable: options.immutable });
|
|
292
297
|
const details = options.details ?? {};
|
|
293
|
-
const allLines = text.split("\n");
|
|
298
|
+
const allLines = options.raw === true ? text.split("\n") : splitAddressableFileLines(text);
|
|
294
299
|
const totalLines = allLines.length;
|
|
295
300
|
details.totalLines = totalLines;
|
|
296
301
|
// User-requested 0-indexed range start. Lines BEFORE this are leading
|
|
@@ -487,7 +492,7 @@ export function buildInMemoryMultiRangeResult(
|
|
|
487
492
|
): AgentToolResult<ReadToolDetails> {
|
|
488
493
|
const displayMode = resolveFileDisplayMode(session, { raw: options.raw, immutable: options.immutable });
|
|
489
494
|
const details = options.details ?? {};
|
|
490
|
-
const allLines = text.split("\n");
|
|
495
|
+
const allLines = options.raw === true ? text.split("\n") : splitAddressableFileLines(text);
|
|
491
496
|
const totalLines = allLines.length;
|
|
492
497
|
details.totalLines = totalLines;
|
|
493
498
|
const shouldAddHashLines = displayMode.hashLines;
|
package/src/tools/read.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as fs from "node:fs/promises";
|
|
2
2
|
import * as path from "node:path";
|
|
3
|
+
import { splitAddressableFileLines } from "@oh-my-pi/hashline";
|
|
3
4
|
import { type } from "@oh-my-pi/omptype";
|
|
4
5
|
import type {
|
|
5
6
|
AgentTool,
|
|
@@ -119,12 +120,17 @@ const MAX_ARTIFACT_RAW_INLINE_BYTES = DEFAULT_MAX_BYTES;
|
|
|
119
120
|
async function readBracketContextFullLines(absolutePath: string, fileSize: number): Promise<string[] | undefined> {
|
|
120
121
|
if (fileSize > SNAPSHOT_MAX_BYTES) return undefined;
|
|
121
122
|
try {
|
|
122
|
-
return normalizeToLF(await Bun.file(absolutePath).text())
|
|
123
|
+
return splitAddressableFileLines(normalizeToLF(await Bun.file(absolutePath).text()));
|
|
123
124
|
} catch {
|
|
124
125
|
return undefined;
|
|
125
126
|
}
|
|
126
127
|
}
|
|
127
128
|
|
|
129
|
+
interface StreamFileLinesOptions {
|
|
130
|
+
includeTerminalNewline?: boolean;
|
|
131
|
+
stopScanAfterCollect?: boolean;
|
|
132
|
+
}
|
|
133
|
+
|
|
128
134
|
async function streamLinesFromFile(
|
|
129
135
|
filePath: string,
|
|
130
136
|
startLine: number,
|
|
@@ -132,7 +138,7 @@ async function streamLinesFromFile(
|
|
|
132
138
|
maxBytes: number,
|
|
133
139
|
selectedLineLimit: number | null,
|
|
134
140
|
signal?: AbortSignal,
|
|
135
|
-
|
|
141
|
+
options: StreamFileLinesOptions = {},
|
|
136
142
|
): Promise<{
|
|
137
143
|
lines: string[];
|
|
138
144
|
totalFileLines: number;
|
|
@@ -141,9 +147,12 @@ async function streamLinesFromFile(
|
|
|
141
147
|
firstLinePreview?: { text: string; bytes: number };
|
|
142
148
|
firstLineByteLength?: number;
|
|
143
149
|
selectedBytesTotal: number;
|
|
150
|
+
/** Whether the fully scanned source ended in a newline. */
|
|
151
|
+
hasTrailingNewline: boolean;
|
|
144
152
|
/** False when `stopScanAfterCollect` cut the scan short — `totalFileLines` is then a lower bound. */
|
|
145
153
|
reachedEof: boolean;
|
|
146
154
|
}> {
|
|
155
|
+
const { includeTerminalNewline = false, stopScanAfterCollect = false } = options;
|
|
147
156
|
const bufferChunk = Buffer.allocUnsafe(READ_CHUNK_SIZE);
|
|
148
157
|
const collectedLines: string[] = [];
|
|
149
158
|
let lineIndex = 0;
|
|
@@ -311,7 +320,7 @@ async function streamLinesFromFile(
|
|
|
311
320
|
}
|
|
312
321
|
}
|
|
313
322
|
|
|
314
|
-
if (reachedEof && (
|
|
323
|
+
if (reachedEof && (currentLineLength > 0 || !sawAnyByte || (endedWithNewline && includeTerminalNewline))) {
|
|
315
324
|
finalizeLine();
|
|
316
325
|
}
|
|
317
326
|
|
|
@@ -330,6 +339,7 @@ async function streamLinesFromFile(
|
|
|
330
339
|
firstLineByteLength,
|
|
331
340
|
selectedBytesTotal,
|
|
332
341
|
reachedEof,
|
|
342
|
+
hasTrailingNewline: reachedEof && endedWithNewline,
|
|
333
343
|
};
|
|
334
344
|
}
|
|
335
345
|
|
|
@@ -692,7 +702,7 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
|
|
|
692
702
|
maxBytesForRead,
|
|
693
703
|
maxLines,
|
|
694
704
|
signal,
|
|
695
|
-
|
|
705
|
+
{ includeTerminalNewline: rawSelector, stopScanAfterCollect: fileSize > SNAPSHOT_MAX_BYTES },
|
|
696
706
|
);
|
|
697
707
|
totalFileLines = streamResult.totalFileLines;
|
|
698
708
|
collectedLines = streamResult.lines;
|
|
@@ -1256,7 +1266,7 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
|
|
|
1256
1266
|
maxBytesForRead,
|
|
1257
1267
|
selectedLineLimit,
|
|
1258
1268
|
undefined, // plain-file read: deterministic and fast, never abort mid-read
|
|
1259
|
-
|
|
1269
|
+
{ includeTerminalNewline: rawSelector, stopScanAfterCollect: fileSize > SNAPSHOT_MAX_BYTES },
|
|
1260
1270
|
);
|
|
1261
1271
|
|
|
1262
1272
|
const {
|
|
@@ -1267,6 +1277,7 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
|
|
|
1267
1277
|
firstLinePreview,
|
|
1268
1278
|
firstLineByteLength,
|
|
1269
1279
|
reachedEof,
|
|
1280
|
+
hasTrailingNewline,
|
|
1270
1281
|
} = streamResult;
|
|
1271
1282
|
|
|
1272
1283
|
// Check if offset is out of bounds - return graceful message instead of throwing
|
|
@@ -1347,7 +1358,7 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
|
|
|
1347
1358
|
const tag = isWholeFile
|
|
1348
1359
|
? getFileSnapshotStore(this.session).record(
|
|
1349
1360
|
canonicalSnapshotKey(absolutePath),
|
|
1350
|
-
normalizeToLF(collectedLines.join("\n")),
|
|
1361
|
+
normalizeToLF(`${collectedLines.join("\n")}${hasTrailingNewline ? "\n" : ""}`),
|
|
1351
1362
|
)
|
|
1352
1363
|
: await recordFileSnapshot(this.session, absolutePath);
|
|
1353
1364
|
if (tag) {
|
|
@@ -1694,7 +1705,7 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
|
|
|
1694
1705
|
maxBytesForRead,
|
|
1695
1706
|
selectedLineLimit,
|
|
1696
1707
|
signal,
|
|
1697
|
-
artifact.size > SNAPSHOT_MAX_BYTES,
|
|
1708
|
+
{ includeTerminalNewline: rawSelector, stopScanAfterCollect: artifact.size > SNAPSHOT_MAX_BYTES },
|
|
1698
1709
|
);
|
|
1699
1710
|
const {
|
|
1700
1711
|
lines: collectedLines,
|
package/src/tools/think.ts
CHANGED
|
@@ -1,13 +1,36 @@
|
|
|
1
1
|
import { type } from "@oh-my-pi/omptype";
|
|
2
2
|
import type { AgentTool, AgentToolResult } from "@oh-my-pi/pi-agent-core";
|
|
3
|
+
import type { Model } from "@oh-my-pi/pi-ai";
|
|
3
4
|
import { type Component, Markdown } from "@oh-my-pi/pi-tui";
|
|
4
5
|
import type { RenderResultOptions } from "../extensibility/custom-tools/types";
|
|
5
6
|
import { getMarkdownTheme, type Theme } from "../modes/theme/theme";
|
|
6
7
|
|
|
8
|
+
/** Whether a model transport can suppress native reasoning while private scratchpad thoughts are active. */
|
|
9
|
+
export function supportsExternalThinking(model: Model | null | undefined): boolean {
|
|
10
|
+
if (!model) return false;
|
|
11
|
+
const requiresThinking =
|
|
12
|
+
model.api === "anthropic-messages" &&
|
|
13
|
+
model.compat !== undefined &&
|
|
14
|
+
"requiresThinkingEnabled" in model.compat &&
|
|
15
|
+
model.compat.requiresThinkingEnabled === true;
|
|
16
|
+
if (model.reasoning && (requiresThinking || (model.thinking?.requiresEffort && !model.thinking.suppressWhenOff))) {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
if (model.api === "google-generative-ai" || model.api === "google-gemini-cli" || model.api === "google-vertex") {
|
|
20
|
+
return !model.reasoning || model.thinking?.mode === "budget" || model.thinking?.suppressWhenOff === true;
|
|
21
|
+
}
|
|
22
|
+
return (
|
|
23
|
+
model.api === "openai-responses" ||
|
|
24
|
+
model.api === "azure-openai-responses" ||
|
|
25
|
+
model.api === "openai-codex-responses" ||
|
|
26
|
+
model.api === "anthropic-messages"
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
7
30
|
const thinkSchema = type({
|
|
8
|
-
thoughts: type("string").describe("private scratchpad
|
|
31
|
+
thoughts: type("string").describe("private scratchpad; not shown to user"),
|
|
9
32
|
"+": "reject",
|
|
10
|
-
}).describe("
|
|
33
|
+
}).describe("private scratchpad; not shown to user");
|
|
11
34
|
|
|
12
35
|
type ThinkParams = typeof thinkSchema.infer;
|
|
13
36
|
|
|
@@ -36,14 +59,13 @@ interface ThinkToolDetails {
|
|
|
36
59
|
recorded: true;
|
|
37
60
|
}
|
|
38
61
|
|
|
39
|
-
/** Records private
|
|
62
|
+
/** Records private scratchpad thoughts while native model reasoning is disabled. */
|
|
40
63
|
export class ThinkTool implements AgentTool<typeof thinkSchema, ThinkToolDetails> {
|
|
41
64
|
readonly name = "think";
|
|
42
65
|
readonly approval = "read" as const;
|
|
43
66
|
readonly label = "Think";
|
|
44
|
-
readonly summary = "Record private
|
|
45
|
-
readonly description =
|
|
46
|
-
"Use this private scratchpad to plan, derive, or check work before answering. Record only materially new reasoning. The user does not see this tool activity.";
|
|
67
|
+
readonly summary = "Record private scratchpad thoughts";
|
|
68
|
+
readonly description = "private scratchpad; not shown to user";
|
|
47
69
|
readonly parameters = thinkSchema;
|
|
48
70
|
readonly strict = true;
|
|
49
71
|
readonly intent = "omit" as const;
|
package/src/tools/write.ts
CHANGED
|
@@ -659,7 +659,7 @@ export class WriteTool implements AgentTool<typeof writeSchema, WriteToolDetails
|
|
|
659
659
|
const entries = new Map<string, ArchiveMemberContent>();
|
|
660
660
|
if (resolvedArchivePath.exists) {
|
|
661
661
|
try {
|
|
662
|
-
const existing = await readArchiveEntries({
|
|
662
|
+
const existing = await readArchiveEntries({ path: finalPath, format });
|
|
663
663
|
for (const [entryPath, data] of existing) {
|
|
664
664
|
entries.set(entryPath, data);
|
|
665
665
|
}
|
|
@@ -7,7 +7,12 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import * as fs from "node:fs/promises";
|
|
9
9
|
import path from "node:path";
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
formatHashlineHeader,
|
|
12
|
+
formatNumberedLines,
|
|
13
|
+
type SnapshotStore,
|
|
14
|
+
splitAddressableFileLines,
|
|
15
|
+
} from "@oh-my-pi/hashline";
|
|
11
16
|
import type { AgentMessage } from "@oh-my-pi/pi-agent-core";
|
|
12
17
|
import type { ImageContent } from "@oh-my-pi/pi-ai";
|
|
13
18
|
import { formatAge, formatBytes, isProbablyBinary, readImageMetadata } from "@oh-my-pi/pi-utils";
|
|
@@ -270,7 +275,8 @@ export async function generateFileMentionMessages(
|
|
|
270
275
|
const content = await Bun.file(absolutePath).text();
|
|
271
276
|
const snapshotStore = options?.useHashLines ? options.snapshotStore : undefined;
|
|
272
277
|
const normalized = snapshotStore ? normalizeToLF(content) : content;
|
|
273
|
-
|
|
278
|
+
const displayText = snapshotStore ? splitAddressableFileLines(normalized).join("\n") : normalized;
|
|
279
|
+
let { output, lineCount } = buildTextOutput(displayText);
|
|
274
280
|
if (snapshotStore) {
|
|
275
281
|
const tag = snapshotStore.record(canonicalSnapshotKey(absolutePath), normalized);
|
|
276
282
|
output = `${formatHashlineHeader(resolvedPath, tag)}\n${formatNumberedLines(output)}`;
|