@oh-my-pi/pi-coding-agent 17.1.6 → 17.1.8
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 +58 -0
- package/dist/{CHANGELOG-x9zt79k8.md → CHANGELOG-vt8ene9g.md} +58 -0
- package/dist/cli.js +4309 -7287
- package/dist/template-dys3vk5b.js +1671 -0
- package/dist/template-f8wx9vfn.css +1355 -0
- package/dist/template-qat058wr.html +55 -0
- package/dist/tool-views.generated-jdfmzwmn.js +35 -0
- package/dist/types/advisor/advise-tool.d.ts +0 -7
- package/dist/types/advisor/runtime.d.ts +0 -9
- package/dist/types/async/job-manager.d.ts +11 -0
- package/dist/types/cleanse/agent.d.ts +19 -0
- package/dist/types/cleanse/balance.d.ts +7 -0
- package/dist/types/cleanse/checkers.d.ts +13 -0
- package/dist/types/cleanse/index.d.ts +16 -0
- package/dist/types/cleanse/loop.d.ts +16 -0
- package/dist/types/cleanse/parsers.d.ts +13 -0
- package/dist/types/cleanse/progress.d.ts +14 -0
- package/dist/types/cleanse/types.d.ts +64 -0
- package/dist/types/commands/cleanse.d.ts +23 -0
- package/dist/types/config/settings-schema.d.ts +16 -1
- package/dist/types/cursor.d.ts +2 -1
- package/dist/types/export/html/index.d.ts +2 -0
- package/dist/types/extensibility/extensions/runner.d.ts +4 -0
- package/dist/types/extensibility/legacy-pi-ai-shim.d.ts +27 -1
- package/dist/types/extensibility/shared-events.d.ts +18 -1
- package/dist/types/modes/components/custom-editor.d.ts +5 -0
- package/dist/types/modes/interactive-mode.d.ts +4 -3
- package/dist/types/session/agent-session-types.d.ts +5 -5
- package/dist/types/session/agent-session.d.ts +26 -1
- package/dist/types/session/async-job-delivery.d.ts +8 -0
- package/dist/types/session/model-controls.d.ts +4 -4
- package/dist/types/session/session-tools.d.ts +44 -6
- package/dist/types/session/streaming-output.d.ts +7 -2
- package/dist/types/session/turn-recovery.d.ts +1 -1
- package/dist/types/task/isolation-ownership.d.ts +34 -0
- package/dist/types/tools/browser/cmux/cmux-tab.d.ts +1 -2
- package/dist/types/tools/browser/tab-worker.d.ts +1 -4
- package/dist/types/tools/index.d.ts +8 -3
- package/dist/types/tools/output-meta.d.ts +5 -0
- package/dist/types/tools/read.d.ts +9 -1
- package/dist/types/tools/xdev.d.ts +53 -67
- package/dist/types/tui/output-block.d.ts +5 -5
- package/dist/types/utils/cpuprofile.d.ts +51 -0
- package/dist/types/utils/inspect-image-mode.d.ts +29 -0
- package/dist/types/utils/profile-tree.d.ts +47 -0
- package/dist/types/utils/sample-profile.d.ts +67 -0
- package/package.json +16 -12
- package/scripts/bundle-dist.ts +3 -1
- package/src/advisor/advise-tool.ts +0 -11
- package/src/advisor/runtime.ts +0 -12
- package/src/async/job-manager.ts +30 -7
- package/src/cleanse/agent.ts +226 -0
- package/src/cleanse/balance.ts +79 -0
- package/src/cleanse/checkers.ts +996 -0
- package/src/cleanse/index.ts +190 -0
- package/src/cleanse/loop.ts +51 -0
- package/src/cleanse/parsers.ts +726 -0
- package/src/cleanse/progress.ts +50 -0
- package/src/cleanse/prompts/assignment.md +47 -0
- package/src/cleanse/types.ts +72 -0
- package/src/cli/update-cli.ts +3 -0
- package/src/cli/usage-cli.ts +29 -4
- package/src/cli/worktree-cli.ts +28 -11
- package/src/cli-commands.ts +1 -0
- package/src/cli.ts +2 -1
- package/src/commands/cleanse.ts +45 -0
- package/src/config/settings-schema.ts +15 -1
- package/src/config/settings.ts +35 -0
- package/src/cursor.ts +4 -3
- package/src/discovery/builtin-rules/index.ts +2 -0
- package/src/discovery/builtin-rules/ts-no-local-is-record.md +48 -0
- package/src/discovery/claude-plugins.ts +144 -34
- package/src/export/html/index.ts +17 -10
- package/src/extensibility/extensions/runner.ts +26 -0
- package/src/extensibility/extensions/wrapper.ts +74 -42
- package/src/extensibility/hooks/tool-wrapper.ts +11 -4
- package/src/extensibility/legacy-pi-ai-shim.ts +46 -1
- package/src/extensibility/shared-events.ts +18 -1
- package/src/launch/broker.ts +14 -4
- package/src/modes/acp/acp-agent.ts +12 -9
- package/src/modes/acp/acp-event-mapper.ts +38 -4
- package/src/modes/components/custom-editor.ts +39 -16
- package/src/modes/components/settings-selector.ts +9 -1
- package/src/modes/components/tips.txt +2 -1
- package/src/modes/components/tool-execution.ts +8 -7
- package/src/modes/controllers/extension-ui-controller.ts +4 -4
- package/src/modes/controllers/selector-controller.ts +7 -2
- package/src/modes/interactive-mode.ts +36 -47
- package/src/modes/prompt-action-autocomplete.ts +5 -3
- package/src/prompts/goals/guided-goal-interview.md +41 -6
- package/src/prompts/system/vibe-mode-active.md +4 -1
- package/src/prompts/tools/browser.md +1 -0
- package/src/prompts/tools/goal.md +1 -1
- package/src/sdk.ts +47 -50
- package/src/session/agent-session-types.ts +5 -5
- package/src/session/agent-session.ts +151 -11
- package/src/session/async-job-delivery.ts +8 -0
- package/src/session/model-controls.ts +9 -9
- package/src/session/session-advisors.ts +2 -7
- package/src/session/session-history-format.ts +31 -6
- package/src/session/session-listing.ts +66 -4
- package/src/session/session-tools.ts +158 -52
- package/src/session/streaming-output.ts +18 -6
- package/src/session/turn-recovery.ts +4 -4
- package/src/slash-commands/builtin-registry.ts +74 -2
- package/src/task/isolation-ownership.ts +106 -0
- package/src/task/worktree.ts +8 -0
- package/src/tools/ask.ts +3 -3
- package/src/tools/ast-edit.ts +9 -2
- package/src/tools/bash.ts +16 -9
- package/src/tools/browser/cmux/cmux-tab.ts +9 -14
- package/src/tools/browser/tab-worker.ts +12 -35
- package/src/tools/browser.ts +2 -2
- package/src/tools/gh-renderer.ts +3 -3
- package/src/tools/index.ts +46 -17
- package/src/tools/output-meta.ts +20 -0
- package/src/tools/read.ts +87 -13
- package/src/tools/write.ts +51 -7
- package/src/tools/xdev.ts +198 -210
- package/src/tui/code-cell.ts +4 -4
- package/src/tui/output-block.ts +25 -8
- package/src/utils/cpuprofile.ts +235 -0
- package/src/utils/inspect-image-mode.ts +39 -0
- package/src/utils/profile-tree.ts +111 -0
- package/src/utils/sample-profile.ts +437 -0
- package/src/utils/shell-snapshot-fn-env.sh +5 -2
- package/src/web/search/render.ts +2 -2
- package/dist/types/goals/guided-setup.d.ts +0 -30
- package/src/goals/guided-setup.ts +0 -171
- package/src/prompts/goals/guided-goal-system.md +0 -33
|
@@ -7,8 +7,9 @@ import type { ExtensionRunner } from "../extensibility/extensions/index.js";
|
|
|
7
7
|
import { type Skill, type SkillWarning } from "../extensibility/skills.js";
|
|
8
8
|
import { type LocalProtocolOptions } from "../internal-urls/index.js";
|
|
9
9
|
import type { MemoryBackendStartOptions } from "../memory-backend/types.js";
|
|
10
|
-
import { type
|
|
10
|
+
import { type XdevState } from "../tools/xdev.js";
|
|
11
11
|
import { type EditMode } from "../utils/edit-mode.js";
|
|
12
|
+
import { type InspectImageMode } from "../utils/inspect-image-mode.js";
|
|
12
13
|
import type { ClientBridge } from "./client-bridge.js";
|
|
13
14
|
import type { CustomMessage } from "./messages.js";
|
|
14
15
|
import type { SessionManager } from "./session-manager.js";
|
|
@@ -33,12 +34,17 @@ export interface SessionToolsHost {
|
|
|
33
34
|
emitNotice(level: "info" | "warning" | "error", message: string, source?: string): void;
|
|
34
35
|
notifyCommandMetadataChanged(): void;
|
|
35
36
|
localProtocolOptions(): LocalProtocolOptions;
|
|
37
|
+
/** Session-scoped `/vision` override; undefined means "follow the persisted setting". */
|
|
38
|
+
getInspectImageModeOverride(): InspectImageMode | undefined;
|
|
39
|
+
setInspectImageModeOverride(mode: InspectImageMode | undefined): void;
|
|
36
40
|
}
|
|
37
41
|
interface SessionToolsOptions {
|
|
38
42
|
autoApprove?: boolean;
|
|
39
43
|
toolRegistry?: Map<string, AgentTool>;
|
|
40
44
|
createVibeTools?: () => AgentTool[];
|
|
41
45
|
createComputerTool?: () => Promise<AgentTool | null>;
|
|
46
|
+
/** Creates the built-in `inspect_image` tool for session-scoped runtime enablement (see {@link SessionTools.setInspectImageMode}). */
|
|
47
|
+
createInspectImageTool?: () => Promise<AgentTool | null>;
|
|
42
48
|
builtInToolNames?: Iterable<string>;
|
|
43
49
|
presentationPinnedToolNames?: ReadonlySet<string>;
|
|
44
50
|
ensureWriteRegistered?: () => Promise<boolean>;
|
|
@@ -47,8 +53,7 @@ interface SessionToolsOptions {
|
|
|
47
53
|
}>;
|
|
48
54
|
getLocalCalendarDate?: () => string;
|
|
49
55
|
getMcpServerInstructions?: () => Map<string, string> | undefined;
|
|
50
|
-
|
|
51
|
-
initialMountedXdevToolNames?: string[];
|
|
56
|
+
xdev?: XdevState;
|
|
52
57
|
setActiveToolNames?: (names: Iterable<string>) => void;
|
|
53
58
|
baseSystemPrompt: string[];
|
|
54
59
|
skills?: Skill[];
|
|
@@ -99,13 +104,13 @@ export declare class SessionTools {
|
|
|
99
104
|
get skillsSettings(): SkillsSettings | undefined;
|
|
100
105
|
/** Drops cached per-session ACP `allow_always`/`reject_always` decisions. */
|
|
101
106
|
clearAcpPermissionDecisions(): void;
|
|
102
|
-
/**
|
|
107
|
+
/** Drops cached ACP decisions and re-wraps active tools after the client changes. */
|
|
103
108
|
refreshAcpPermissionGates(): void;
|
|
104
109
|
/** Names of tools currently exposed at the top level. */
|
|
105
110
|
getActiveToolNames(): string[];
|
|
106
111
|
/** Enabled top-level and discoverable tool names. */
|
|
107
112
|
getEnabledToolNames(): string[];
|
|
108
|
-
/** Names
|
|
113
|
+
/** Names currently presented as `xd://` devices. */
|
|
109
114
|
getMountedXdevToolNames(): string[];
|
|
110
115
|
/** Whether the edit tool is registered. */
|
|
111
116
|
get hasEditTool(): boolean;
|
|
@@ -139,7 +144,7 @@ export declare class SessionTools {
|
|
|
139
144
|
* Restore an enabled tool set with its exact top-level versus `xd://` partition.
|
|
140
145
|
*
|
|
141
146
|
* Both inputs are required because {@link setActiveToolsByName} only receives the
|
|
142
|
-
* enabled name list and classifies mounts from the current
|
|
147
|
+
* enabled name list and classifies mounts from the current presentation set.
|
|
143
148
|
* Rollback/restore callers must pass the snapshotted mounted subset so names that
|
|
144
149
|
* were top-level stay pinned (`#runtimeSelectedToolNames`) and names that were under
|
|
145
150
|
* `xd://` remain mount-eligible, even when the live mount set has drifted.
|
|
@@ -166,6 +171,39 @@ export declare class SessionTools {
|
|
|
166
171
|
* tool (e.g. restricted child sessions have no factory).
|
|
167
172
|
*/
|
|
168
173
|
setComputerToolEnabled(enabled: boolean): Promise<boolean>;
|
|
174
|
+
/** Current effective inspect_image state for `/vision status`. */
|
|
175
|
+
inspectImageState(): {
|
|
176
|
+
mode: InspectImageMode;
|
|
177
|
+
active: boolean;
|
|
178
|
+
model: string | undefined;
|
|
179
|
+
};
|
|
180
|
+
/**
|
|
181
|
+
* Brings the active tool set in line with the effective inspect_image state
|
|
182
|
+
* (mode setting, `/vision` override, active-model image capability).
|
|
183
|
+
* Mirrors {@link setComputerToolEnabled}: enabling builds the tool through
|
|
184
|
+
* the config factory on first use and reuses the registry entry afterwards.
|
|
185
|
+
* Idempotent — safe to call from every model/settings change path.
|
|
186
|
+
*
|
|
187
|
+
* @returns false when the tool should be active but this session cannot
|
|
188
|
+
* build it (e.g. restricted child sessions have no factory).
|
|
189
|
+
*/
|
|
190
|
+
reconcileInspectImageTool(): Promise<boolean>;
|
|
191
|
+
/**
|
|
192
|
+
* Reconciles inspect_image after a model change and surfaces a notice when
|
|
193
|
+
* the visible tool set actually flipped. Called from every model-change
|
|
194
|
+
* path — including retry-fallback switches that bypass
|
|
195
|
+
* {@link syncAfterModelChange}.
|
|
196
|
+
*/
|
|
197
|
+
reconcileInspectImageAfterModelChange(): Promise<void>;
|
|
198
|
+
/**
|
|
199
|
+
* Session-scoped `/vision` override. `auto` clears the override so the
|
|
200
|
+
* persisted `inspect_image.mode` setting (itself possibly `auto`) decides;
|
|
201
|
+
* `on`/`off` force the tool for this session only. Takes effect before the
|
|
202
|
+
* next model call.
|
|
203
|
+
*
|
|
204
|
+
* @returns false when `on` was requested but the tool cannot be built here.
|
|
205
|
+
*/
|
|
206
|
+
setInspectImageMode(mode: InspectImageMode): Promise<boolean>;
|
|
169
207
|
/** Rebuilds the stable base prompt for the current tools and model. */
|
|
170
208
|
refreshBaseSystemPrompt(): Promise<void>;
|
|
171
209
|
/** Applies one-turn memory prompt injection before an agent run. */
|
|
@@ -34,12 +34,17 @@ export interface OutputSummary {
|
|
|
34
34
|
export interface OutputSinkOptions {
|
|
35
35
|
artifactPath?: string;
|
|
36
36
|
artifactId?: string;
|
|
37
|
-
/**
|
|
37
|
+
/**
|
|
38
|
+
* Total inline body budget (bytes). Default DEFAULT_MAX_BYTES. The head
|
|
39
|
+
* window and rolling tail window share this budget, so a composed
|
|
40
|
+
* `dump()` body never exceeds it (plus the elision marker).
|
|
41
|
+
*/
|
|
38
42
|
spillThreshold?: number;
|
|
39
43
|
/**
|
|
40
44
|
* When > 0, the sink keeps the first `headBytes` of output in addition to
|
|
41
45
|
* the rolling tail window. Output between the two windows is elided
|
|
42
|
-
* (middle elision).
|
|
46
|
+
* (middle elision). Clamped to `spillThreshold / 2` so the tail keeps at
|
|
47
|
+
* least half the inline budget. Default 0 = tail-only behavior.
|
|
43
48
|
*/
|
|
44
49
|
headBytes?: number;
|
|
45
50
|
/**
|
|
@@ -43,7 +43,7 @@ export interface TurnRecoveryHost {
|
|
|
43
43
|
waitForSessionMessagePersistence(message: AssistantMessage): Promise<void>;
|
|
44
44
|
appendSessionMessage(message: AssistantMessage): void;
|
|
45
45
|
sessionMessageAlreadyPersisted(message: AssistantMessage): boolean;
|
|
46
|
-
setModelWithProviderSessionReset(model: Model): void
|
|
46
|
+
setModelWithProviderSessionReset(model: Model): Promise<void>;
|
|
47
47
|
resetCurrentResponsesProviderSession(reason: string): void;
|
|
48
48
|
maybeAutoRedeemCodexReset(): Promise<boolean>;
|
|
49
49
|
runAutoCompaction(reason: "overflow" | "threshold" | "idle" | "incomplete", willRetry: boolean, deferred?: boolean, allowDefer?: boolean, options?: {
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/** Marker file written into a task-isolation base dir identifying its owner. */
|
|
2
|
+
export declare const ISOLATION_OWNER_FILE = ".omp-isolation-owner.json";
|
|
3
|
+
/** Recorded owner of a task-isolation sandbox. */
|
|
4
|
+
export interface IsolationOwner {
|
|
5
|
+
/** PID of the omp process that created and owns the sandbox. */
|
|
6
|
+
pid: number;
|
|
7
|
+
/** Task id the sandbox was materialised for. */
|
|
8
|
+
id: string;
|
|
9
|
+
/**
|
|
10
|
+
* Process-instance start-time token for {@link pid}, when the OS can report
|
|
11
|
+
* it. Distinguishes the owning process from an unrelated process that later
|
|
12
|
+
* inherits a recycled pid, so a crashed sandbox is never pinned live.
|
|
13
|
+
*/
|
|
14
|
+
startToken?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Record the current process as owner of the sandbox rooted at `baseDir`.
|
|
18
|
+
*
|
|
19
|
+
* Written before the isolation backend materialises `m` so a concurrent
|
|
20
|
+
* `omp worktree clear` never sees an owner-less sandbox mid-creation.
|
|
21
|
+
*/
|
|
22
|
+
export declare function writeIsolationOwner(baseDir: string, id: string): Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* Whether a live omp process still owns the sandbox at `baseDir`.
|
|
25
|
+
*
|
|
26
|
+
* A missing or malformed marker means no verifiable owner — a crashed run or a
|
|
27
|
+
* sandbox from before markers existed, both safe to reclaim. `process.kill(pid,
|
|
28
|
+
* 0)` can fail with `EPERM` even when the process is alive, so only an explicit
|
|
29
|
+
* `ESRCH` ("no such process") counts as dead; any other error is treated as
|
|
30
|
+
* alive to avoid deleting a sandbox that is actually in use. When the marker
|
|
31
|
+
* carries a {@link IsolationOwner.startToken}, a live pid whose current token no
|
|
32
|
+
* longer matches is a recycled pid — a different process — and counts as dead.
|
|
33
|
+
*/
|
|
34
|
+
export declare function hasLiveIsolationOwner(baseDir: string): Promise<boolean>;
|
|
@@ -8,7 +8,6 @@ import type { CmuxSocketClient } from "./socket-client.js";
|
|
|
8
8
|
interface ScreenshotOptions {
|
|
9
9
|
selector?: string;
|
|
10
10
|
fullPage?: boolean;
|
|
11
|
-
save?: string;
|
|
12
11
|
silent?: boolean;
|
|
13
12
|
encoding?: "base64" | "binary";
|
|
14
13
|
}
|
|
@@ -101,7 +100,7 @@ export declare class CmuxTab {
|
|
|
101
100
|
scrollIntoView(selector: string): Promise<void>;
|
|
102
101
|
select(selector: string, ...values: string[]): Promise<string[]>;
|
|
103
102
|
extract(format?: ReadableFormat): Promise<string>;
|
|
104
|
-
screenshot(opts?: ScreenshotOptions): Promise<
|
|
103
|
+
screenshot(opts?: ScreenshotOptions): Promise<string>;
|
|
105
104
|
waitForUrl(pattern: string | RegExp, opts?: {
|
|
106
105
|
timeout?: number;
|
|
107
106
|
}): Promise<string>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { HTMLElement } from "linkedom";
|
|
2
|
-
import type { ElementHandle
|
|
2
|
+
import type { ElementHandle } from "puppeteer-core";
|
|
3
3
|
import type { Transport } from "./tab-protocol.js";
|
|
4
4
|
declare module "puppeteer-core" {
|
|
5
5
|
interface Frame {
|
|
@@ -41,7 +41,6 @@ export declare function resolveWaitTimeout(cellTimeoutMs: number, explicit?: num
|
|
|
41
41
|
interface ScreenshotOptions {
|
|
42
42
|
selector?: string;
|
|
43
43
|
fullPage?: boolean;
|
|
44
|
-
save?: string;
|
|
45
44
|
silent?: boolean;
|
|
46
45
|
}
|
|
47
46
|
export declare function normalizeSelector(selector: string): string;
|
|
@@ -67,8 +66,6 @@ export interface InflightOp {
|
|
|
67
66
|
}
|
|
68
67
|
/** Human-readable label for a screenshot op, used in op tracking + timeout errors. */
|
|
69
68
|
export declare function describeScreenshot(opts?: ScreenshotOptions): string;
|
|
70
|
-
/** Map an explicit save path's extension to a puppeteer capture format (default png). */
|
|
71
|
-
export declare function imageFormatForPath(filePath: string): ImageFormat;
|
|
72
69
|
/** Summarize still-running helpers (oldest first) so a cell timeout names what stalled. */
|
|
73
70
|
export declare function describeInflight(inflight: Map<number, InflightOp>): string;
|
|
74
71
|
export declare class WorkerCore {
|
|
@@ -24,12 +24,13 @@ import type { ToolChoiceQueue } from "../session/tool-choice-queue.js";
|
|
|
24
24
|
import type { AgentOutputManager } from "../task/output-manager.js";
|
|
25
25
|
import { type StructuredSubagentSchemaMode } from "../task/types.js";
|
|
26
26
|
import type { EventBus } from "../utils/event-bus.js";
|
|
27
|
+
import { type InspectImageMode } from "../utils/inspect-image-mode.js";
|
|
27
28
|
import type { WorkspaceTree } from "../workspace-tree.js";
|
|
28
29
|
import { type BuiltinToolName, type HiddenToolName } from "./builtin-names.js";
|
|
29
30
|
import { type CheckpointState, type CompletedRewindState } from "./checkpoint.js";
|
|
30
31
|
import type { PlanProposalHandler } from "./resolve.js";
|
|
31
32
|
import { type TodoPhase } from "./todo.js";
|
|
32
|
-
import {
|
|
33
|
+
import { type XdevState } from "./xdev.js";
|
|
33
34
|
export * from "../edit/index.js";
|
|
34
35
|
export * from "../goals/index.js";
|
|
35
36
|
export * from "../lsp/index.js";
|
|
@@ -204,8 +205,10 @@ export interface ToolSession {
|
|
|
204
205
|
isToolActive?: (name: string) => boolean;
|
|
205
206
|
/** Update the active built-in tool predicate when a session changes tools mid-run. */
|
|
206
207
|
setActiveToolNames?: (names: Iterable<string>) => void;
|
|
207
|
-
/**
|
|
208
|
-
|
|
208
|
+
/** Canonical map containing every registered tool exactly once. */
|
|
209
|
+
toolRegistry?: Map<string, Tool>;
|
|
210
|
+
/** `xd://` presentation state backed by {@link toolRegistry}. */
|
|
211
|
+
xdev?: XdevState;
|
|
209
212
|
/** Agent registry for IRC routing across live sessions. */
|
|
210
213
|
agentRegistry?: AgentRegistry;
|
|
211
214
|
/** Idle→parked→revive lifecycle owner; lets the hub kill a non-job-backed agent registration. Default: AgentLifecycleManager.global(). */
|
|
@@ -227,6 +230,8 @@ export interface ToolSession {
|
|
|
227
230
|
getActiveModelString?: () => string | undefined;
|
|
228
231
|
/** Get the current session model object (provider/api capabilities), regardless of how it was chosen. */
|
|
229
232
|
getActiveModel?: () => Model | undefined;
|
|
233
|
+
/** Session-scoped inspect_image mode override set by `/vision`; wins over the persisted setting. */
|
|
234
|
+
getInspectImageModeOverride?: () => InspectImageMode | undefined;
|
|
230
235
|
/** Get the session's live per-family service tiers (undefined = none). Source of truth for subagent `tier.subagent: inherit`. */
|
|
231
236
|
getServiceTierByFamily?: () => ServiceTierByFamily | undefined;
|
|
232
237
|
/** Auth storage for passing to subagents (avoids re-discovery) */
|
|
@@ -197,6 +197,11 @@ export declare function stripOutputNotice(text: string, meta: OutputMeta | undef
|
|
|
197
197
|
* middle elision with the same per-user configuration.
|
|
198
198
|
*/
|
|
199
199
|
export declare function resolveOutputSinkHeadBytes(s: Settings | undefined): number;
|
|
200
|
+
/**
|
|
201
|
+
* Resolve the `enforceInlineByteCap` budget for streaming tools (bash/ssh)
|
|
202
|
+
* from session settings: the user's spill threshold plus notice slack.
|
|
203
|
+
*/
|
|
204
|
+
export declare function resolveInlineByteCapBudget(s: Settings | undefined): number;
|
|
200
205
|
/**
|
|
201
206
|
* Resolve the per-line column cap from session settings. Shared by streaming
|
|
202
207
|
* executors (bash/python/ssh/eval via OutputSink) and the `read` tool's
|
|
@@ -56,12 +56,20 @@ export declare class ReadTool implements AgentTool<typeof readSchema, ReadToolDe
|
|
|
56
56
|
readonly approval: (args: unknown) => ToolTier;
|
|
57
57
|
readonly label = "Read";
|
|
58
58
|
readonly loadMode = "essential";
|
|
59
|
-
|
|
59
|
+
description: string;
|
|
60
60
|
readonly parameters: import("arktype/internal/variants/object.ts").ObjectType<{
|
|
61
61
|
path: string;
|
|
62
62
|
}, {}>;
|
|
63
63
|
readonly strict = true;
|
|
64
64
|
constructor(session: ToolSession);
|
|
65
|
+
/**
|
|
66
|
+
* Re-evaluate the effective inspect_image state; it can flip when the model
|
|
67
|
+
* or the `/vision` override changes after this tool was constructed. Keeps
|
|
68
|
+
* the behavior branch and the advertised description in lockstep. Called
|
|
69
|
+
* per image read and by tool reconciliation before prompt rebuilds (which
|
|
70
|
+
* passes the post-change availability as `availableOverride`).
|
|
71
|
+
*/
|
|
72
|
+
syncInspectImageState(availableOverride?: boolean): boolean;
|
|
65
73
|
execute(_toolCallId: string, params: ReadParams, signal?: AbortSignal, _onUpdate?: AgentToolUpdateCallback<ReadToolDetails>, _toolContext?: AgentToolContext): Promise<AgentToolResult<ReadToolDetails>>;
|
|
66
74
|
}
|
|
67
75
|
interface ReadRenderArgs {
|
|
@@ -9,15 +9,20 @@
|
|
|
9
9
|
* read xd://<tool> → tool docs + JSON parameter schema
|
|
10
10
|
* write xd://<tool> → execute: `content` is the JSON args object
|
|
11
11
|
*
|
|
12
|
+
* Direct and device dispatch share one canonical tool map. The mounted-name
|
|
13
|
+
* set controls presentation only; dispatch accepts the enabled union of
|
|
14
|
+
* top-level active and mounted names. Listing and prompt docs stay
|
|
15
|
+
* mounted-only because top-level tools already ship their schemas.
|
|
16
|
+
*
|
|
12
17
|
* Args go through the same machinery as native tool calls: validated with
|
|
13
18
|
* pi-ai's `validateToolArguments` (the schema is returned on mismatch, so a
|
|
14
19
|
* malformed call self-corrects without a round trip) and streamed through
|
|
15
20
|
* the write tool's existing incremental `content` decoding for live render
|
|
16
21
|
* previews. Compared to a dispatcher def this still costs zero *schema
|
|
17
22
|
* duplication* — one wire schema per tool instead of one per dispatcher
|
|
18
|
-
* branch — but full docs + schema for every mounted device
|
|
19
|
-
* the system prompt
|
|
20
|
-
*
|
|
23
|
+
* branch — but full docs + schema for every mounted device can be inlined
|
|
24
|
+
* into the system prompt, so no discovery read is needed before first use;
|
|
25
|
+
* `read xd://<tool>` remains for on-demand re-fetch.
|
|
21
26
|
*
|
|
22
27
|
* Rendering: the write renderer draws NOTHING until the streamed `path` is
|
|
23
28
|
* known and provably does not target `xd://`; device writes then delegate to
|
|
@@ -54,8 +59,7 @@ export type XdevDocsMode = "inline" | "builtins" | "catalog";
|
|
|
54
59
|
* while the `xd://` transport is active. Discoverable tools mount unless they
|
|
55
60
|
* are pinned top-level by {@link XDEV_KEEP_TOP_LEVEL} or carry the transport
|
|
56
61
|
* itself ({@link XDEV_TRANSPORT_TOOLS}); essential tools never do. The caller
|
|
57
|
-
* gates this on the transport being active
|
|
58
|
-
* {@link XdevRegistry} existing).
|
|
62
|
+
* gates this on the transport being active.
|
|
59
63
|
*/
|
|
60
64
|
export declare function isMountableUnderXdev(tool: {
|
|
61
65
|
name: string;
|
|
@@ -72,69 +76,51 @@ export interface XdevDispatch {
|
|
|
72
76
|
}
|
|
73
77
|
/** Wire the wrapped-renderer lookup. Called once by `renderers.ts`. */
|
|
74
78
|
export declare function setXdevRendererLookup(lookup: (name: string) => ToolRenderer | undefined): void;
|
|
75
|
-
/**
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
*/
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
*/
|
|
88
|
-
reconcile(tools: Iterable<Tool>): void;
|
|
89
|
-
get size(): number;
|
|
90
|
-
/** Mounted tools in catalog order: built-ins first, then dynamic mounts. */
|
|
91
|
-
list(): readonly Tool[];
|
|
92
|
-
get(name: string): Tool | undefined;
|
|
93
|
-
/** `{name, summary}` pairs for prompt templates and /tools display. */
|
|
94
|
-
entries(): Array<{
|
|
95
|
-
name: string;
|
|
96
|
-
summary: string;
|
|
97
|
-
}>;
|
|
98
|
-
/** `read xd://` listing with one device per line. */
|
|
99
|
-
listing(): string;
|
|
100
|
-
/** Docs + schema for one device; throws with the listing when unknown. */
|
|
101
|
-
docs(name: string): string;
|
|
102
|
-
/**
|
|
103
|
-
* Char budget for the full docs inlined into the system prompt. Large MCP
|
|
104
|
-
* catalogs previously shipped every schema top-level; without a cap they
|
|
105
|
-
* would bloat every request. Devices past the budget fall back to a
|
|
106
|
-
* one-line summary — their docs stay one `read xd://<tool>` away.
|
|
107
|
-
*/
|
|
108
|
-
static readonly DOCS_TOTAL_BUDGET = 48000;
|
|
109
|
-
/** A single device's docs above this size never inline: one pathological
|
|
110
|
-
* MCP description must not starve every later device. */
|
|
111
|
-
static readonly DOCS_PER_DEVICE_CAP = 10000;
|
|
112
|
-
/** Description cap for EXTERNAL devices (dynamic mounts: MCP, custom,
|
|
113
|
-
* extension, …) in the system-prompt embedding. Built-in devices inline
|
|
114
|
-
* their full curated docs; external descriptions are server-controlled
|
|
115
|
-
* prose the model can re-fetch, so only the lede earns prompt space. */
|
|
116
|
-
static readonly EXTERNAL_DESCRIPTION_CAP = 200;
|
|
117
|
-
/**
|
|
118
|
-
* Docs + schema for mounted devices, nested under `##` headings for
|
|
119
|
-
* system-prompt embedding. Inlines full docs in catalog order (built-ins
|
|
120
|
-
* first) until {@link DOCS_TOTAL_BUDGET} is spent; the rest are listed by
|
|
121
|
-
* name + summary with a pointer to on-demand `read xd://<tool>` docs.
|
|
122
|
-
* Dynamic mounts embed at most {@link EXTERNAL_DESCRIPTION_CAP} description
|
|
123
|
-
* chars (schema always intact); `read xd://<tool>` returns the full text.
|
|
124
|
-
*/
|
|
125
|
-
docsAll(mode?: XdevDocsMode, inlinePatterns?: readonly string[]): string;
|
|
126
|
-
/** Docs for selected mounted devices under the configured prompt-doc policy. */
|
|
127
|
-
docsFor(names: Iterable<string>, mode: XdevDocsMode, inlinePatterns?: readonly string[]): string;
|
|
128
|
-
/**
|
|
129
|
-
* Execute a device write: `content` is the JSON args object (empty, `?`, or
|
|
130
|
-
* `help` returns docs). Args validate against the wrapped tool's schema —
|
|
131
|
-
* the schema comes back in the error on mismatch.
|
|
132
|
-
*/
|
|
133
|
-
dispatch(name: string, content: string, toolCallId: string, signal?: AbortSignal, onUpdate?: AgentToolUpdateCallback, context?: AgentToolContext): Promise<{
|
|
134
|
-
result: AgentToolResult<unknown>;
|
|
135
|
-
xdev: XdevDispatch;
|
|
136
|
-
}>;
|
|
79
|
+
/** Shared tool state consumed by the `xd://` presentation layer. */
|
|
80
|
+
export interface XdevState {
|
|
81
|
+
/** Canonical session tool map; direct and device dispatch read the same instances. */
|
|
82
|
+
readonly tools: Map<string, Tool>;
|
|
83
|
+
/** Ordered names currently presented as mounted devices. */
|
|
84
|
+
readonly mountedNames: Set<string>;
|
|
85
|
+
/** Names originating from built-in factories, used only for prompt presentation. */
|
|
86
|
+
readonly builtInNames: Set<string>;
|
|
87
|
+
/** Whether a name is active at the top level. */
|
|
88
|
+
readonly isActive: (name: string) => boolean;
|
|
89
|
+
/** Optional execution-only decorator, such as the ACP permission gate. */
|
|
90
|
+
decorateExecution?(tool: Tool): Tool;
|
|
137
91
|
}
|
|
92
|
+
/** Full-doc character budget for system-prompt mounted-device sections. */
|
|
93
|
+
export declare const XDEV_DOCS_TOTAL_BUDGET = 48000;
|
|
94
|
+
/** Per-device cap preventing one pathological description from starving later devices. */
|
|
95
|
+
export declare const XDEV_DOCS_PER_DEVICE_CAP = 10000;
|
|
96
|
+
/** Description cap for external mounted tools; their full docs remain readable on demand. */
|
|
97
|
+
export declare const XDEV_EXTERNAL_DESCRIPTION_CAP = 200;
|
|
98
|
+
/** Resolve any enabled tool through the canonical session map. */
|
|
99
|
+
export declare function resolveXdevTool(state: XdevState, name: string): Tool | undefined;
|
|
100
|
+
/** Resolve a mounted tool for top-level fallback execution. */
|
|
101
|
+
export declare function resolveMountedXdevTool(state: XdevState, name: string): Tool | undefined;
|
|
102
|
+
/** Resolve a mounted tool with its execution-only permission decorator. */
|
|
103
|
+
export declare function resolveMountedXdevExecutable(state: XdevState, name: string): Tool | undefined;
|
|
104
|
+
/** Mounted tools in presentation order, resolved from the canonical map. */
|
|
105
|
+
export declare function listXdevTools(state: XdevState): Tool[];
|
|
106
|
+
/** `{name, summary}` pairs for prompt templates and `/tools` display. */
|
|
107
|
+
export declare function xdevEntries(state: XdevState): Array<{
|
|
108
|
+
name: string;
|
|
109
|
+
summary: string;
|
|
110
|
+
}>;
|
|
111
|
+
/** `read xd://` listing with one device per line. */
|
|
112
|
+
export declare function xdevListing(state: XdevState): string;
|
|
113
|
+
/** Docs + schema for any enabled tool. */
|
|
114
|
+
export declare function xdevDocs(state: XdevState, name: string): string;
|
|
115
|
+
/** Docs + schema for mounted devices under the configured prompt-doc policy. */
|
|
116
|
+
export declare function xdevDocsAll(state: XdevState, mode?: XdevDocsMode, inlinePatterns?: readonly string[]): string;
|
|
117
|
+
/** Docs for selected mounted devices under the configured prompt-doc policy. */
|
|
118
|
+
export declare function xdevDocsFor(state: XdevState, names: Iterable<string>, mode: XdevDocsMode, inlinePatterns?: readonly string[]): string;
|
|
119
|
+
/** Execute an enabled canonical tool through `write xd://<tool>`. */
|
|
120
|
+
export declare function dispatchXdevTool(state: XdevState, name: string, content: string, toolCallId: string, signal?: AbortSignal, onUpdate?: AgentToolUpdateCallback, context?: AgentToolContext): Promise<{
|
|
121
|
+
result: AgentToolResult<unknown>;
|
|
122
|
+
xdev: XdevDispatch;
|
|
123
|
+
}>;
|
|
138
124
|
/**
|
|
139
125
|
* Streaming-safe call preview for an `xd://` write: forwards the decoded inner
|
|
140
126
|
* args to the mounted tool's renderer (session instance first, then the static
|
|
@@ -16,6 +16,7 @@ export interface OutputBlockOptions {
|
|
|
16
16
|
width: number;
|
|
17
17
|
applyBg?: boolean;
|
|
18
18
|
contentPaddingLeft?: number;
|
|
19
|
+
contentPaddingRight?: number;
|
|
19
20
|
/** Override the state-derived border color. Used for muted "legacy" tool
|
|
20
21
|
* frames that should not visually compete with framed-output tools. */
|
|
21
22
|
borderColor?: ThemeColor;
|
|
@@ -28,12 +29,11 @@ export declare function markFramedBlockComponent<T extends Component>(component:
|
|
|
28
29
|
export declare function isFramedBlockComponent(component: Component): boolean;
|
|
29
30
|
/**
|
|
30
31
|
* Inner content width that {@link renderOutputBlock} wraps its body to, for a
|
|
31
|
-
* given outer `width`: both vertical borders
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
* into more rows than they counted and the box overflows its intended height.
|
|
32
|
+
* given outer `width`: both vertical borders plus symmetric content padding.
|
|
33
|
+
* An explicit left padding of zero keeps legacy flush blocks flush on both
|
|
34
|
+
* sides unless a right padding is provided separately.
|
|
35
35
|
*/
|
|
36
|
-
export declare function outputBlockContentWidth(width: number, contentPaddingLeft?: number): number;
|
|
36
|
+
export declare function outputBlockContentWidth(width: number, contentPaddingLeft?: number, contentPaddingRight?: number): number;
|
|
37
37
|
export declare function renderOutputBlock(options: OutputBlockOptions, theme: Theme): string[];
|
|
38
38
|
/**
|
|
39
39
|
* Cached wrapper around `renderOutputBlock`.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parser and renderer for V8 `.cpuprofile` files (emitted by `node --cpu-prof`,
|
|
3
|
+
* `bun --cpu-prof`, Chrome DevTools, and the CDP `Profiler` domain).
|
|
4
|
+
*
|
|
5
|
+
* The raw file is a JSON blob with a flat node table and up to millions of
|
|
6
|
+
* sample/timestamp entries — useless to read directly. `renderCpuProfile`
|
|
7
|
+
* converts it into a compact bottleneck summary:
|
|
8
|
+
*
|
|
9
|
+
* - the hot-path call tree, pruned to frames with meaningful self time,
|
|
10
|
+
* with pass-through chains collapsed and direct recursion flattened
|
|
11
|
+
* - `(idle)` time excluded from on-CPU totals
|
|
12
|
+
* - a profile-wide "top functions by self time" table
|
|
13
|
+
*
|
|
14
|
+
* Consumed by the read tool: `*.cpuprofile` reads show the summary, `:raw`
|
|
15
|
+
* returns the original JSON.
|
|
16
|
+
*/
|
|
17
|
+
/** Matches paths the read tool should treat as V8 CPU profiles. */
|
|
18
|
+
export declare function isCpuProfilePath(filePath: string): boolean;
|
|
19
|
+
/** Call-site metadata of one profile node. `lineNumber` is 0-based. */
|
|
20
|
+
export interface CpuProfileCallFrame {
|
|
21
|
+
functionName: string;
|
|
22
|
+
url?: string;
|
|
23
|
+
lineNumber?: number;
|
|
24
|
+
}
|
|
25
|
+
/** One node in the flat profile tree; `children` are node ids. */
|
|
26
|
+
export interface CpuProfileNode {
|
|
27
|
+
id: number;
|
|
28
|
+
callFrame: CpuProfileCallFrame;
|
|
29
|
+
hitCount?: number;
|
|
30
|
+
children?: number[];
|
|
31
|
+
}
|
|
32
|
+
/** Parsed V8 CPU profile. `startTime`/`endTime`/`timeDeltas` are microseconds. */
|
|
33
|
+
export interface CpuProfile {
|
|
34
|
+
nodes: CpuProfileNode[];
|
|
35
|
+
startTime: number;
|
|
36
|
+
endTime: number;
|
|
37
|
+
samples?: number[];
|
|
38
|
+
timeDeltas?: number[];
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Parse a `.cpuprofile` JSON blob. Accepts both the bare profile and the CDP
|
|
42
|
+
* `Profiler.stop` result shape (`{ profile: {...} }`). Returns null when the
|
|
43
|
+
* text is not a structurally valid V8 CPU profile.
|
|
44
|
+
*/
|
|
45
|
+
export declare function parseCpuProfile(text: string): CpuProfile | null;
|
|
46
|
+
/**
|
|
47
|
+
* Render a V8 CPU profile as an agent-friendly bottleneck summary.
|
|
48
|
+
* Returns null when `text` is not a CPU profile (caller falls back to the
|
|
49
|
+
* plain-text path).
|
|
50
|
+
*/
|
|
51
|
+
export declare function renderCpuProfile(text: string): string | null;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Effective-state resolution for the `inspect_image` tool.
|
|
3
|
+
*
|
|
4
|
+
* The tool delegates image understanding to a (possibly different)
|
|
5
|
+
* vision-capable model. That indirection is only useful when the active model
|
|
6
|
+
* cannot consume images itself; when it can (`model.input` includes
|
|
7
|
+
* `"image"`), the tool is redundant and its presence actively degrades the
|
|
8
|
+
* `read` tool, which reduces image reads to metadata-only plus an
|
|
9
|
+
* inspect_image suggestion. `auto` mode therefore exposes the tool only for
|
|
10
|
+
* models without native image input. `on`/`off` force registration regardless
|
|
11
|
+
* of model capability. A session-scoped override (the `/vision` command)
|
|
12
|
+
* takes precedence over the persisted setting for the current session only.
|
|
13
|
+
*/
|
|
14
|
+
import type { Model } from "@oh-my-pi/pi-ai";
|
|
15
|
+
import type { Settings } from "../config/settings.js";
|
|
16
|
+
export type InspectImageMode = "auto" | "on" | "off";
|
|
17
|
+
export declare const INSPECT_IMAGE_MODES: readonly ["auto", "on", "off"];
|
|
18
|
+
/** Minimal session surface needed to resolve the effective inspect_image state. */
|
|
19
|
+
export interface InspectImageModeContext {
|
|
20
|
+
settings: Pick<Settings, "get">;
|
|
21
|
+
getActiveModel?: () => Model | undefined;
|
|
22
|
+
getInspectImageModeOverride?: () => InspectImageMode | undefined;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Whether the `inspect_image` tool should be registered/active right now.
|
|
26
|
+
* `auto` registers it only when the active model lacks native image input;
|
|
27
|
+
* an unresolved model is treated as text-only so the tool stays available.
|
|
28
|
+
*/
|
|
29
|
+
export declare function isInspectImageToolActive(session: InspectImageModeContext): boolean;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared display-tree machinery for profile summaries (macOS `sample` reports,
|
|
3
|
+
* V8 `.cpuprofile` files). Callers build {@link ProfileNode} trees with a
|
|
4
|
+
* domain-specific metric (on-CPU samples, self microseconds, …); this module
|
|
5
|
+
* merges same-key siblings, flattens direct recursion, collapses pass-through
|
|
6
|
+
* chains, and renders the pruned hot-path tree.
|
|
7
|
+
*/
|
|
8
|
+
/** Display node: merged, recursion-flattened mirror of a profile subtree. */
|
|
9
|
+
export interface ProfileNode {
|
|
10
|
+
/** Merge/recursion identity (demangled symbol, function@call-site, …). */
|
|
11
|
+
key: string;
|
|
12
|
+
/** Human-readable label; recursion and truncation decorations are applied at render time. */
|
|
13
|
+
label: string;
|
|
14
|
+
/** Inclusive metric for this subtree (on-CPU samples, self µs, …); drives pruning and display. */
|
|
15
|
+
value: number;
|
|
16
|
+
/** Levels of direct recursion flattened into this node. */
|
|
17
|
+
recursion: number;
|
|
18
|
+
children: ProfileNode[];
|
|
19
|
+
}
|
|
20
|
+
/** Merge `b` into `a` (same key), combining values and child lists. */
|
|
21
|
+
export declare function mergeInto(a: ProfileNode, b: ProfileNode): void;
|
|
22
|
+
/**
|
|
23
|
+
* Flatten direct recursion: children carrying the node's own key are dissolved
|
|
24
|
+
* into it (their children promoted and merged), so a 15-deep recursive spine
|
|
25
|
+
* renders as one annotated node.
|
|
26
|
+
*/
|
|
27
|
+
export declare function flattenRecursion(node: ProfileNode): void;
|
|
28
|
+
/** `n` as a percentage of `total`, one decimal (`"12.3%"`); `"0%"` when total is empty. */
|
|
29
|
+
export declare function formatPct(n: number, total: number): string;
|
|
30
|
+
/** Options for {@link renderProfileNode}. */
|
|
31
|
+
export interface RenderTreeContext {
|
|
32
|
+
out: string[];
|
|
33
|
+
/** Denominator for percentage annotations. */
|
|
34
|
+
total: number;
|
|
35
|
+
/** Minimum subtree value a child needs to stay visible. */
|
|
36
|
+
minValue: number;
|
|
37
|
+
/** Format a metric value for the left column. */
|
|
38
|
+
formatValue: (value: number) => string;
|
|
39
|
+
/** Left-column width (characters) for formatted values. */
|
|
40
|
+
valueWidth: number;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Render one hot-path subtree: pass-through chains (single kept child, no own
|
|
44
|
+
* contribution above `minValue`) collapse into a single `a › b › c` line, and
|
|
45
|
+
* children below `minValue` are pruned.
|
|
46
|
+
*/
|
|
47
|
+
export declare function renderProfileNode(node: ProfileNode, indent: number, ctx: RenderTreeContext): void;
|