@oh-my-pi/pi-coding-agent 16.0.9 → 16.0.11
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/cli.js +3402 -3443
- package/dist/types/advisor/index.d.ts +1 -0
- package/dist/types/advisor/transcript-recorder.d.ts +52 -0
- package/dist/types/collab/host.d.ts +2 -2
- package/dist/types/collab/protocol.d.ts +4 -5
- package/dist/types/commit/agentic/agent.d.ts +1 -1
- package/dist/types/config/model-resolver.d.ts +11 -2
- package/dist/types/config/settings-schema.d.ts +12 -6
- package/dist/types/edit/file-snapshot-store.d.ts +1 -1
- package/dist/types/extensibility/extensions/types.d.ts +7 -0
- package/dist/types/modes/components/agent-hub.d.ts +6 -1
- package/dist/types/modes/components/agent-transcript-viewer.d.ts +39 -0
- package/dist/types/modes/components/chat-transcript-builder.d.ts +42 -0
- package/dist/types/modes/controllers/command-controller.d.ts +3 -2
- package/dist/types/modes/interactive-mode.d.ts +2 -1
- package/dist/types/modes/types.d.ts +2 -1
- package/dist/types/registry/agent-registry.d.ts +10 -3
- package/dist/types/session/agent-session.d.ts +13 -0
- package/dist/types/session/compact-modes.d.ts +60 -0
- package/dist/types/session/streaming-output.d.ts +0 -2
- package/dist/types/slash-commands/builtin-registry.d.ts +1 -1
- package/dist/types/slash-commands/helpers/collab-qrcode.d.ts +13 -0
- package/dist/types/tools/__tests__/json-tree.test.d.ts +1 -0
- package/dist/types/tools/index.d.ts +9 -1
- package/dist/types/utils/image-loading.d.ts +12 -0
- package/dist/types/utils/qrcode.d.ts +48 -0
- package/package.json +12 -12
- package/src/advisor/index.ts +1 -0
- package/src/advisor/transcript-recorder.ts +136 -0
- package/src/cli/args.ts +7 -1
- package/src/cli/stats-cli.ts +2 -11
- package/src/collab/host.ts +29 -17
- package/src/collab/protocol.ts +48 -15
- package/src/commit/agentic/agent.ts +2 -1
- package/src/commit/agentic/tools/git-file-diff.ts +2 -2
- package/src/commit/changelog/index.ts +1 -1
- package/src/commit/map-reduce/map-phase.ts +1 -1
- package/src/commit/map-reduce/utils.ts +1 -1
- package/src/config/config-file.ts +1 -1
- package/src/config/keybindings.ts +2 -2
- package/src/config/model-registry.ts +16 -4
- package/src/config/model-resolver.ts +193 -35
- package/src/config/settings-schema.ts +14 -7
- package/src/config/settings.ts +3 -9
- package/src/edit/file-snapshot-store.ts +1 -1
- package/src/edit/renderer.ts +7 -7
- package/src/eval/js/tool-bridge.ts +3 -2
- package/src/eval/py/prelude.py +3 -2
- package/src/export/html/tool-views.generated.js +28 -28
- package/src/extensibility/extensions/types.ts +7 -0
- package/src/hindsight/mental-models.ts +1 -1
- package/src/internal-urls/docs-index.generated.txt +1 -1
- package/src/internal-urls/history-protocol.ts +8 -3
- package/src/irc/bus.ts +8 -0
- package/src/lsp/index.ts +2 -2
- package/src/main.ts +6 -3
- package/src/modes/acp/acp-agent.ts +63 -0
- package/src/modes/components/agent-hub.ts +97 -920
- package/src/modes/components/agent-transcript-viewer.ts +461 -0
- package/src/modes/components/chat-transcript-builder.ts +462 -0
- package/src/modes/components/diff.ts +12 -35
- package/src/modes/components/oauth-selector.ts +31 -2
- package/src/modes/controllers/command-controller.ts +12 -2
- package/src/modes/controllers/event-controller.ts +1 -1
- package/src/modes/controllers/input-controller.ts +8 -1
- package/src/modes/controllers/selector-controller.ts +4 -1
- package/src/modes/interactive-mode.ts +4 -2
- package/src/modes/types.ts +2 -1
- package/src/prompts/tools/inspect-image.md +1 -1
- package/src/prompts/tools/read.md +1 -1
- package/src/registry/agent-registry.ts +13 -4
- package/src/sdk.ts +27 -8
- package/src/session/agent-session.ts +185 -17
- package/src/session/compact-modes.ts +105 -0
- package/src/session/session-dump-format.ts +1 -1
- package/src/session/session-history-format.ts +1 -1
- package/src/session/streaming-output.ts +5 -5
- package/src/slash-commands/builtin-registry.ts +45 -15
- package/src/slash-commands/helpers/collab-qrcode.ts +28 -0
- package/src/task/executor.ts +1 -1
- package/src/task/output-manager.ts +5 -0
- package/src/thinking.ts +25 -5
- package/src/tools/__tests__/json-tree.test.ts +35 -0
- package/src/tools/approval.ts +1 -1
- package/src/tools/bash.ts +0 -1
- package/src/tools/browser.ts +0 -1
- package/src/tools/eval.ts +1 -1
- package/src/tools/gh.ts +1 -1
- package/src/tools/index.ts +10 -1
- package/src/tools/inspect-image.ts +72 -9
- package/src/tools/irc.ts +1 -1
- package/src/tools/json-tree.ts +22 -5
- package/src/tools/read.ts +5 -6
- package/src/utils/file-mentions.ts +5 -2
- package/src/utils/image-loading.ts +58 -0
- package/src/utils/qrcode.ts +535 -0
- package/src/web/scrapers/firefox-addons.ts +1 -1
- package/src/web/scrapers/github.ts +1 -1
- package/src/web/scrapers/go-pkg.ts +2 -2
- package/src/web/scrapers/metacpan.ts +2 -2
- package/src/web/scrapers/nvd.ts +2 -2
- package/src/web/scrapers/ollama.ts +1 -1
- package/src/web/scrapers/opencorporates.ts +1 -1
- package/src/web/scrapers/pub-dev.ts +1 -1
- package/src/web/scrapers/repology.ts +1 -1
- package/src/web/scrapers/sourcegraph.ts +1 -1
- package/src/web/scrapers/terraform.ts +6 -6
- package/src/web/scrapers/wikidata.ts +2 -2
- package/src/workspace-tree.ts +1 -1
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { AgentMessage } from "@oh-my-pi/pi-agent-core";
|
|
2
|
+
/**
|
|
3
|
+
* Reserved transcript stem for advisor session files. Chosen so it cannot
|
|
4
|
+
* collide with a task subagent's `<id>.jsonl` (task ids are reserved against
|
|
5
|
+
* this exact stem in {@link AgentOutputManager}).
|
|
6
|
+
*/
|
|
7
|
+
export declare const ADVISOR_TRANSCRIPT_STEM = "__advisor";
|
|
8
|
+
export declare const ADVISOR_TRANSCRIPT_FILENAME = "__advisor.jsonl";
|
|
9
|
+
/**
|
|
10
|
+
* Append-only persister for an advisor agent's transcript.
|
|
11
|
+
*
|
|
12
|
+
* The advisor is a passive reviewer with its own model usage, so — like a task
|
|
13
|
+
* subagent — its turns are written to a JSONL inside the owning session's
|
|
14
|
+
* artifacts dir (`<session>/__advisor.jsonl`, `<session>/<SubId>/__advisor.jsonl`
|
|
15
|
+
* for subagent advisors). That single file gives the advisor model proper usage
|
|
16
|
+
* attribution in `omp stats` (the stats parser scans the session dir
|
|
17
|
+
* recursively) and a read-only transcript in the Agent Hub, without making the
|
|
18
|
+
* advisor a registered, messageable peer.
|
|
19
|
+
*
|
|
20
|
+
* The target is derived from the *session file* (`getSessionFile()`), never
|
|
21
|
+
* `getArtifactsDir()` — subagents adopt the parent's artifact manager, so the
|
|
22
|
+
* artifacts dir points at the parent root and every subagent advisor would
|
|
23
|
+
* collide. The file path is resolved synchronously when a message finalizes and
|
|
24
|
+
* captured for the queued write, so a `/new`, resume, or session switch in
|
|
25
|
+
* flight can never misattribute an old advisor turn into the new session's file.
|
|
26
|
+
* On such a switch the previous writer is closed and the new file opened on the
|
|
27
|
+
* next recorded turn. The recorder never truncates: the advisor's in-memory
|
|
28
|
+
* context resets/compacts independently, but every billed turn is appended here.
|
|
29
|
+
*/
|
|
30
|
+
export declare class AdvisorTranscriptRecorder {
|
|
31
|
+
#private;
|
|
32
|
+
private readonly resolveSessionFile;
|
|
33
|
+
private readonly resolveCwd;
|
|
34
|
+
/**
|
|
35
|
+
* @param after Optional barrier the queue starts behind — used on the advisor
|
|
36
|
+
* on→off→on toggle so a fresh recorder's first `open` waits for the prior
|
|
37
|
+
* recorder's `close` and the two never hold the same `__advisor.jsonl` at once.
|
|
38
|
+
*/
|
|
39
|
+
constructor(resolveSessionFile: () => string | undefined, resolveCwd: () => string, after?: Promise<unknown>);
|
|
40
|
+
/**
|
|
41
|
+
* Persist one finalized advisor message. Assistant turns carry the usage the
|
|
42
|
+
* stats parser reads; tool results round out the Hub transcript; user deltas
|
|
43
|
+
* (the advisor's "session update" prompts) are persisted but flagged
|
|
44
|
+
* `synthetic`/agent-attributed so they never inflate user-message metrics.
|
|
45
|
+
* Non-conversational message kinds are skipped.
|
|
46
|
+
*/
|
|
47
|
+
record(message: AgentMessage): void;
|
|
48
|
+
/** Flush pending writes (best-effort). */
|
|
49
|
+
flush(): Promise<void>;
|
|
50
|
+
/** Flush and close the writer, releasing the session file. */
|
|
51
|
+
close(): Promise<void>;
|
|
52
|
+
}
|
|
@@ -16,14 +16,14 @@ export declare class CollabHost {
|
|
|
16
16
|
#private;
|
|
17
17
|
constructor(ctx: InteractiveModeContext);
|
|
18
18
|
get link(): string;
|
|
19
|
-
/** Browser deep link
|
|
19
|
+
/** Browser deep link for the configured collab web UI. */
|
|
20
20
|
get webLink(): string;
|
|
21
21
|
/** Read-only variant of {@link link}: bare room key, no write token. */
|
|
22
22
|
get viewLink(): string;
|
|
23
23
|
/** Read-only variant of {@link webLink}. */
|
|
24
24
|
get webViewLink(): string;
|
|
25
25
|
get participants(): CollabParticipant[];
|
|
26
|
-
start(relayUrl: string): Promise<void>;
|
|
26
|
+
start(relayUrl: string, webUrl?: string): Promise<void>;
|
|
27
27
|
/** Broadcast a goodbye, detach all taps, and close the socket. */
|
|
28
28
|
stop(reason: string): Promise<void>;
|
|
29
29
|
}
|
|
@@ -108,12 +108,11 @@ export declare function generateRoomId(): string;
|
|
|
108
108
|
*/
|
|
109
109
|
export declare function formatCollabLink(relayUrl: string, roomId: string, key: Uint8Array, writeToken?: Uint8Array): string;
|
|
110
110
|
/**
|
|
111
|
-
* Render the browser deep link
|
|
112
|
-
* relay
|
|
113
|
-
* room
|
|
114
|
-
* Terminals auto-link the https form, making it click-to-join.
|
|
111
|
+
* Render the browser deep link. The browser UI may be hosted separately from
|
|
112
|
+
* the relay; the fragment always carries the relay-specific collab link, so
|
|
113
|
+
* room secrets stay out of HTTP path and query bytes.
|
|
115
114
|
*/
|
|
116
|
-
export declare function formatCollabWebLink(relayUrl: string, roomId: string, key: Uint8Array, writeToken?: Uint8Array): string;
|
|
115
|
+
export declare function formatCollabWebLink(relayUrl: string, roomId: string, key: Uint8Array, writeToken?: Uint8Array, webUrl?: string): string;
|
|
117
116
|
export declare function parseCollabLink(link: string): ParsedCollabLink | {
|
|
118
117
|
error: string;
|
|
119
118
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { ThinkingLevel } from "@oh-my-pi/pi-agent-core";
|
|
2
2
|
import type { Api, Model } from "@oh-my-pi/pi-ai";
|
|
3
3
|
import type { ModelRegistry } from "../../config/model-registry";
|
|
4
4
|
import type { Settings } from "../../config/settings";
|
|
@@ -32,11 +32,17 @@ export interface ScopedModel {
|
|
|
32
32
|
thinkingLevel?: ThinkingLevel;
|
|
33
33
|
explicitThinkingLevel: boolean;
|
|
34
34
|
}
|
|
35
|
+
interface ThinkingSuffixOptions {
|
|
36
|
+
allowMaxAlias?: boolean;
|
|
37
|
+
}
|
|
38
|
+
interface ModelStringParseOptions extends ThinkingSuffixOptions {
|
|
39
|
+
isLiteralModelId?: (provider: string, id: string) => boolean;
|
|
40
|
+
}
|
|
35
41
|
/**
|
|
36
42
|
* Parse a model string in "provider/modelId" format.
|
|
37
43
|
* Returns undefined if the format is invalid.
|
|
38
44
|
*/
|
|
39
|
-
export declare function parseModelString(modelStr: string): {
|
|
45
|
+
export declare function parseModelString(modelStr: string, options?: ModelStringParseOptions): {
|
|
40
46
|
provider: string;
|
|
41
47
|
id: string;
|
|
42
48
|
thinkingLevel?: ThinkingLevel;
|
|
@@ -115,7 +121,10 @@ export declare function resolveModelRoleValue(roleValue: string | undefined, ava
|
|
|
115
121
|
matchPreferences?: ModelMatchPreferences;
|
|
116
122
|
modelRegistry?: CanonicalModelRegistry;
|
|
117
123
|
}): ResolvedModelRoleValue;
|
|
118
|
-
|
|
124
|
+
interface ExplicitThinkingSelectorOptions {
|
|
125
|
+
isLiteralModelId?: (provider: string, id: string) => boolean;
|
|
126
|
+
}
|
|
127
|
+
export declare function extractExplicitThinkingSelector(value: string | undefined, settings?: Settings, options?: ExplicitThinkingSelectorOptions): ThinkingLevel | undefined;
|
|
119
128
|
/**
|
|
120
129
|
* Resolve a model identifier or pattern to a Model instance.
|
|
121
130
|
*/
|
|
@@ -775,10 +775,6 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
775
775
|
readonly description: "Remove the 1-character horizontal padding from the left and right of the terminal output";
|
|
776
776
|
};
|
|
777
777
|
};
|
|
778
|
-
readonly "display.tabWidth": {
|
|
779
|
-
readonly type: "number";
|
|
780
|
-
readonly default: 3;
|
|
781
|
-
};
|
|
782
778
|
readonly "display.shimmer": {
|
|
783
779
|
readonly type: "enum";
|
|
784
780
|
readonly values: readonly ["classic", "kitt", "disabled"];
|
|
@@ -835,7 +831,7 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
835
831
|
};
|
|
836
832
|
readonly defaultThinkingLevel: {
|
|
837
833
|
readonly type: "enum";
|
|
838
|
-
readonly values: readonly [...import("@oh-my-pi/pi-catalog").Effort[], "auto"];
|
|
834
|
+
readonly values: readonly [...import("@oh-my-pi/pi-catalog").Effort[], "auto", "max"];
|
|
839
835
|
readonly default: "high";
|
|
840
836
|
readonly ui: {
|
|
841
837
|
readonly tab: "model";
|
|
@@ -1579,6 +1575,16 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
1579
1575
|
readonly description: "Relay used by /collab (wss://host[:port])";
|
|
1580
1576
|
};
|
|
1581
1577
|
};
|
|
1578
|
+
readonly "collab.webUrl": {
|
|
1579
|
+
readonly type: "string";
|
|
1580
|
+
readonly default: "";
|
|
1581
|
+
readonly ui: {
|
|
1582
|
+
readonly tab: "interaction";
|
|
1583
|
+
readonly group: "Collab";
|
|
1584
|
+
readonly label: "Web UI URL";
|
|
1585
|
+
readonly description: "Browser UI used by /collab links; empty derives from collab.relayUrl; explicit http:// is localhost-only";
|
|
1586
|
+
};
|
|
1587
|
+
};
|
|
1582
1588
|
readonly "collab.displayName": {
|
|
1583
1589
|
readonly type: "string";
|
|
1584
1590
|
readonly default: "";
|
|
@@ -2012,7 +2018,7 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
2012
2018
|
}, {
|
|
2013
2019
|
readonly value: "pi";
|
|
2014
2020
|
readonly label: "Pi";
|
|
2015
|
-
readonly description: "Use the Pi owned dialect.";
|
|
2021
|
+
readonly description: "Use the Pi owned dialect (compact sigil-delimited tool calls).";
|
|
2016
2022
|
}, {
|
|
2017
2023
|
readonly value: "qwen3";
|
|
2018
2024
|
readonly label: "Qwen3";
|
|
@@ -48,7 +48,7 @@ export declare function recordFileSnapshot(session: FileSnapshotStoreOwner, abso
|
|
|
48
48
|
/**
|
|
49
49
|
* The 1-indexed file lines a hashline-formatted body actually displayed.
|
|
50
50
|
* Single `NN:` rows contribute that line; a collapsed summary `NN-MM:` row
|
|
51
|
-
* (a `{
|
|
51
|
+
* (a `{ … }` brace pair) contributes only its boundary lines `NN` and `MM` —
|
|
52
52
|
* the elided interior was never shown, so editing inside it must be rejected.
|
|
53
53
|
*/
|
|
54
54
|
export declare function parseSeenLinesFromHashlineBody(body: string): number[];
|
|
@@ -25,6 +25,7 @@ import type * as PiCodingAgent from "../../index";
|
|
|
25
25
|
import type { MemoryRuntimeContext } from "../../memory-backend";
|
|
26
26
|
import type { CustomEditor } from "../../modes/components/custom-editor";
|
|
27
27
|
import type { Theme } from "../../modes/theme/theme";
|
|
28
|
+
import type { CompactMode } from "../../session/compact-modes";
|
|
28
29
|
import type { CustomMessage } from "../../session/messages";
|
|
29
30
|
import type { ReadonlySessionManager, SessionManager } from "../../session/session-manager";
|
|
30
31
|
import type { BashToolDetails, BashToolInput, FindToolDetails, FindToolInput, ReadToolDetails, ReadToolInput, SearchToolDetails, SearchToolInput, WriteToolInput } from "../../tools";
|
|
@@ -171,6 +172,12 @@ export interface ContextUsage {
|
|
|
171
172
|
export interface CompactOptions {
|
|
172
173
|
onComplete?: (result: CompactionResult) => void;
|
|
173
174
|
onError?: (error: Error) => void;
|
|
175
|
+
/**
|
|
176
|
+
* Force a one-off compaction mode for this invocation, overriding the
|
|
177
|
+
* configured `compaction.strategy` / `remoteEnabled` (the `/compact`
|
|
178
|
+
* subcommands: `soft` | `remote` | `snapcompact`). Omitted = configured behavior.
|
|
179
|
+
*/
|
|
180
|
+
mode?: CompactMode;
|
|
174
181
|
}
|
|
175
182
|
/**
|
|
176
183
|
* Context passed to extension event handlers.
|
|
@@ -62,6 +62,11 @@ export declare class AgentHubOverlayComponent extends Container {
|
|
|
62
62
|
dispose(): void;
|
|
63
63
|
render(width: number): readonly string[];
|
|
64
64
|
handleInput(keyData: string): void;
|
|
65
|
-
/**
|
|
65
|
+
/**
|
|
66
|
+
* Open the fullscreen transcript viewer for an agent id (public for table Enter
|
|
67
|
+
* and tests). Mounts {@link AgentTranscriptViewer} as a `fullscreen` overlay so it
|
|
68
|
+
* owns the alternate screen; the hub table stays mounted underneath and is
|
|
69
|
+
* restored when the viewer closes. No-op without a real TUI (render-only test stub).
|
|
70
|
+
*/
|
|
66
71
|
openChat(id: string): void;
|
|
67
72
|
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { AgentTool } from "@oh-my-pi/pi-agent-core";
|
|
2
|
+
import { type Component, type TUI } from "@oh-my-pi/pi-tui";
|
|
3
|
+
import type { KeyId } from "../../config/keybindings";
|
|
4
|
+
import type { MessageRenderer } from "../../extensibility/extensions/types";
|
|
5
|
+
import type { AgentLifecycleManager } from "../../registry/agent-lifecycle";
|
|
6
|
+
import type { AgentRegistry } from "../../registry/agent-registry";
|
|
7
|
+
import type { SessionObserverRegistry } from "../session-observer-registry";
|
|
8
|
+
import type { AgentHubRemote } from "./agent-hub";
|
|
9
|
+
export interface AgentTranscriptViewerDeps {
|
|
10
|
+
agentId: string;
|
|
11
|
+
registry: AgentRegistry;
|
|
12
|
+
/** Collab guest: read transcript from the host instead of a local file. */
|
|
13
|
+
remote?: AgentHubRemote;
|
|
14
|
+
/** Progress/cost snapshot source for the stats line. */
|
|
15
|
+
observers?: SessionObserverRegistry;
|
|
16
|
+
/** Revive+prompt path for messageable local agents. Lazy to avoid touching the global. */
|
|
17
|
+
lifecycle?: () => AgentLifecycleManager;
|
|
18
|
+
ui: TUI;
|
|
19
|
+
getTool?: (name: string) => AgentTool | undefined;
|
|
20
|
+
getMessageRenderer?: (customType: string) => MessageRenderer | undefined;
|
|
21
|
+
cwd: string;
|
|
22
|
+
hideThinkingBlock?: () => boolean;
|
|
23
|
+
expandKeys: KeyId[];
|
|
24
|
+
/** Keys that toggle the whole hub closed (app.agents.hub + app.session.observe). */
|
|
25
|
+
hubKeys: KeyId[];
|
|
26
|
+
requestRender: () => void;
|
|
27
|
+
/** Close just this viewer (Esc), returning to the hub table. */
|
|
28
|
+
onClose: () => void;
|
|
29
|
+
/** Close this viewer AND the hub (hub-toggle keys). */
|
|
30
|
+
onHubClose: () => void;
|
|
31
|
+
}
|
|
32
|
+
export declare class AgentTranscriptViewer implements Component {
|
|
33
|
+
#private;
|
|
34
|
+
private readonly deps;
|
|
35
|
+
constructor(deps: AgentTranscriptViewerDeps);
|
|
36
|
+
dispose(): void;
|
|
37
|
+
handleInput(data: string): void;
|
|
38
|
+
render(width: number): readonly string[];
|
|
39
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Builds transcript components from persisted session message entries — the
|
|
3
|
+
* file/remote-backed counterpart to {@link UiHelpers.addMessageToChat} (which is
|
|
4
|
+
* bound to the live InteractiveModeContext). Used by the fullscreen transcript
|
|
5
|
+
* viewer ({@link AgentTranscriptViewer}) to render a parked subagent / advisor /
|
|
6
|
+
* collab-guest transcript that has no live session.
|
|
7
|
+
*
|
|
8
|
+
* Unlike the old incremental hub sync, {@link ChatTranscriptBuilder.rebuild}
|
|
9
|
+
* always discards prior components and rebuilds the whole transcript from the
|
|
10
|
+
* supplied entries. Re-rendering a growing transcript is therefore O(n) in the
|
|
11
|
+
* entry count, but it cannot duplicate or misorder rows the way incremental
|
|
12
|
+
* component reuse could.
|
|
13
|
+
*/
|
|
14
|
+
import type { AgentTool } from "@oh-my-pi/pi-agent-core";
|
|
15
|
+
import { type TUI } from "@oh-my-pi/pi-tui";
|
|
16
|
+
import type { MessageRenderer } from "../../extensibility/extensions/types";
|
|
17
|
+
import type { SessionMessageEntry } from "../../session/session-entries";
|
|
18
|
+
import { TranscriptContainer } from "./transcript-container";
|
|
19
|
+
export interface ChatTranscriptBuilderDeps {
|
|
20
|
+
ui: TUI;
|
|
21
|
+
getTool?: (name: string) => AgentTool | undefined;
|
|
22
|
+
getMessageRenderer?: (customType: string) => MessageRenderer | undefined;
|
|
23
|
+
cwd: string;
|
|
24
|
+
hideThinkingBlock?: () => boolean;
|
|
25
|
+
requestRender: () => void;
|
|
26
|
+
}
|
|
27
|
+
export declare class ChatTranscriptBuilder {
|
|
28
|
+
#private;
|
|
29
|
+
private readonly deps;
|
|
30
|
+
readonly container: TranscriptContainer;
|
|
31
|
+
constructor(deps: ChatTranscriptBuilderDeps);
|
|
32
|
+
/** Whether the transcript currently holds any rendered rows. */
|
|
33
|
+
get isEmpty(): boolean;
|
|
34
|
+
/** Discard all components and rebuild the whole transcript from `entries`. */
|
|
35
|
+
rebuild(entries: SessionMessageEntry[]): void;
|
|
36
|
+
/** Toggle tool-output expansion across every expandable component. */
|
|
37
|
+
setExpanded(expanded: boolean): void;
|
|
38
|
+
get expanded(): boolean;
|
|
39
|
+
/** Tear down components (sealing pending spinners) and clear build state. */
|
|
40
|
+
reset(): void;
|
|
41
|
+
dispose(): void;
|
|
42
|
+
}
|
|
@@ -3,6 +3,7 @@ import { type ProviderDetails, type UsageReport } from "@oh-my-pi/pi-ai";
|
|
|
3
3
|
import type { CompactOptions } from "../../extensibility/extensions/types";
|
|
4
4
|
import { theme } from "../../modes/theme/theme";
|
|
5
5
|
import type { InteractiveModeContext } from "../../modes/types";
|
|
6
|
+
import type { CompactMode } from "../../session/compact-modes";
|
|
6
7
|
import { type ShakeMode } from "../../session/shake-types";
|
|
7
8
|
export declare class CommandController {
|
|
8
9
|
#private;
|
|
@@ -31,14 +32,14 @@ export declare class CommandController {
|
|
|
31
32
|
handleRenameCommand(title: string): Promise<void>;
|
|
32
33
|
handleBashCommand(command: string, excludeFromContext?: boolean): Promise<void>;
|
|
33
34
|
handlePythonCommand(code: string, excludeFromContext?: boolean): Promise<void>;
|
|
34
|
-
handleCompactCommand(customInstructions?: string, beforeFlush?: (outcome: CompactionOutcome) => void | Promise<void>): Promise<CompactionOutcome>;
|
|
35
|
+
handleCompactCommand(customInstructions?: string, mode?: CompactMode, beforeFlush?: (outcome: CompactionOutcome) => void | Promise<void>): Promise<CompactionOutcome>;
|
|
35
36
|
/**
|
|
36
37
|
* TUI handler for `/shake`. `elide` drops heavy structural content and
|
|
37
38
|
* `images` strips image blocks. Rebuilds the chat and reports counts.
|
|
38
39
|
*/
|
|
39
40
|
handleShakeCommand(mode: ShakeMode): Promise<void>;
|
|
40
41
|
handleSkillCommand(skillPath: string, args: string): Promise<void>;
|
|
41
|
-
executeCompaction(customInstructionsOrOptions?: string | CompactOptions, isAuto?: boolean, beforeFlush?: (outcome: CompactionOutcome) => void | Promise<void
|
|
42
|
+
executeCompaction(customInstructionsOrOptions?: string | CompactOptions, isAuto?: boolean, beforeFlush?: (outcome: CompactionOutcome) => void | Promise<void>, mode?: CompactMode): Promise<CompactionOutcome>;
|
|
42
43
|
handleHandoffCommand(customInstructions?: string): Promise<void>;
|
|
43
44
|
}
|
|
44
45
|
export declare function renderProviderSection(details: ProviderDetails, uiTheme: Pick<typeof theme, "fg">): string;
|
|
@@ -12,6 +12,7 @@ import type { CompactOptions } from "../extensibility/extensions/types";
|
|
|
12
12
|
import type { MCPManager } from "../mcp";
|
|
13
13
|
import { type PlanApprovalDetails } from "../plan-mode/approved-plan";
|
|
14
14
|
import type { AgentSession } from "../session/agent-session";
|
|
15
|
+
import type { CompactMode } from "../session/compact-modes";
|
|
15
16
|
import { HistoryStorage } from "../session/history-storage";
|
|
16
17
|
import type { SessionContext } from "../session/session-context";
|
|
17
18
|
import type { SessionManager } from "../session/session-manager";
|
|
@@ -298,7 +299,7 @@ export declare class InteractiveMode implements InteractiveModeContext {
|
|
|
298
299
|
handlePythonCommand(code: string, excludeFromContext?: boolean): Promise<void>;
|
|
299
300
|
handleMCPCommand(text: string): Promise<void>;
|
|
300
301
|
handleSSHCommand(text: string): Promise<void>;
|
|
301
|
-
handleCompactCommand(customInstructions?: string, beforeFlush?: (outcome: CompactionOutcome) => void | Promise<void>): Promise<CompactionOutcome>;
|
|
302
|
+
handleCompactCommand(customInstructions?: string, mode?: CompactMode, beforeFlush?: (outcome: CompactionOutcome) => void | Promise<void>): Promise<CompactionOutcome>;
|
|
302
303
|
handleHandoffCommand(customInstructions?: string): Promise<void>;
|
|
303
304
|
handleShakeCommand(mode: ShakeMode): Promise<void>;
|
|
304
305
|
executeCompaction(customInstructionsOrOptions?: string | CompactOptions, isAuto?: boolean): Promise<CompactionOutcome>;
|
|
@@ -11,6 +11,7 @@ import type { CompactOptions } from "../extensibility/extensions/types";
|
|
|
11
11
|
import type { MCPManager } from "../mcp";
|
|
12
12
|
import type { PlanApprovalDetails } from "../plan-mode/approved-plan";
|
|
13
13
|
import type { AgentSession } from "../session/agent-session";
|
|
14
|
+
import type { CompactMode } from "../session/compact-modes";
|
|
14
15
|
import type { HistoryStorage } from "../session/history-storage";
|
|
15
16
|
import type { SessionContext } from "../session/session-context";
|
|
16
17
|
import type { SessionManager } from "../session/session-manager";
|
|
@@ -273,7 +274,7 @@ export interface InteractiveModeContext {
|
|
|
273
274
|
handlePythonCommand(code: string, excludeFromContext?: boolean): Promise<void>;
|
|
274
275
|
handleMCPCommand(text: string): Promise<void>;
|
|
275
276
|
handleSSHCommand(text: string): Promise<void>;
|
|
276
|
-
handleCompactCommand(customInstructions?: string): Promise<CompactionOutcome>;
|
|
277
|
+
handleCompactCommand(customInstructions?: string, mode?: CompactMode): Promise<CompactionOutcome>;
|
|
277
278
|
handleHandoffCommand(customInstructions?: string): Promise<void>;
|
|
278
279
|
handleShakeCommand(mode: ShakeMode): Promise<void>;
|
|
279
280
|
handleMoveCommand(targetPath: string): Promise<void>;
|
|
@@ -18,7 +18,13 @@ export declare const MAIN_AGENT_ID = "Main";
|
|
|
18
18
|
* - `aborted`: hard-killed, terminal.
|
|
19
19
|
*/
|
|
20
20
|
export type AgentStatus = "running" | "idle" | "parked" | "aborted";
|
|
21
|
-
|
|
21
|
+
/**
|
|
22
|
+
* - `main`/`sub`: the user-facing agent tree (driving agent + task subagents).
|
|
23
|
+
* - `advisor`: a passive review transcript persisted like a subagent for usage
|
|
24
|
+
* attribution and Agent Hub observability, but never a peer — hidden from
|
|
25
|
+
* agent-facing rosters (`irc`, `history://`) and not messageable/revivable.
|
|
26
|
+
*/
|
|
27
|
+
export type AgentKind = "main" | "sub" | "advisor";
|
|
22
28
|
export interface AgentRef {
|
|
23
29
|
id: string;
|
|
24
30
|
displayName: string;
|
|
@@ -81,8 +87,9 @@ export declare class AgentRegistry {
|
|
|
81
87
|
get(id: string): AgentRef | undefined;
|
|
82
88
|
list(): AgentRef[];
|
|
83
89
|
/**
|
|
84
|
-
* Returns every alive agent (running | idle) except the caller.
|
|
85
|
-
*
|
|
90
|
+
* Returns every alive agent (running | idle) except the caller. Advisor refs
|
|
91
|
+
* are observability-only transcripts, never peers, so they are excluded.
|
|
92
|
+
* Flat namespace: every other agent is visible.
|
|
86
93
|
*/
|
|
87
94
|
listVisibleTo(id: string): AgentRef[];
|
|
88
95
|
onChange(listener: RegistryListener): () => void;
|
|
@@ -237,6 +237,13 @@ export interface AgentSessionConfig {
|
|
|
237
237
|
advisorReadOnlyTools?: AgentTool[];
|
|
238
238
|
/** Preloaded watchdog prompt content for the advisor. */
|
|
239
239
|
advisorWatchdogPrompt?: string;
|
|
240
|
+
/**
|
|
241
|
+
* Disconnect this session's OWNED MCP manager on dispose. Provided only when
|
|
242
|
+
* the session created the manager (top-level sessions); subagents reuse a
|
|
243
|
+
* parent's manager via `options.mcpManager` and omit this so a child's
|
|
244
|
+
* teardown never tears down the shared servers.
|
|
245
|
+
*/
|
|
246
|
+
disconnectOwnedMcpManager?: () => Promise<void>;
|
|
240
247
|
}
|
|
241
248
|
/** Options for AgentSession.prompt() */
|
|
242
249
|
export interface PromptOptions {
|
|
@@ -552,6 +559,12 @@ export declare class AgentSession {
|
|
|
552
559
|
get hasPostPromptWork(): boolean;
|
|
553
560
|
/** All messages including custom types like BashExecutionMessage */
|
|
554
561
|
get messages(): AgentMessage[];
|
|
562
|
+
/** Latest image attachments addressable by tools as `Image #N` or `attachment://N`. */
|
|
563
|
+
getImageAttachments(): {
|
|
564
|
+
label: string;
|
|
565
|
+
uri: string;
|
|
566
|
+
image: ImageContent;
|
|
567
|
+
}[];
|
|
555
568
|
buildDisplaySessionContext(): SessionContext;
|
|
556
569
|
/**
|
|
557
570
|
* Full-history transcript for TUI display: every path entry in
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Manual `/compact` subcommands. Kept in a dependency-free leaf module so the
|
|
3
|
+
* slash-command registry, the interactive controllers, and `AgentSession`
|
|
4
|
+
* can all import the mode metadata + parser without pulling in the heavy
|
|
5
|
+
* `agent-session` module graph (which would form an import cycle through the
|
|
6
|
+
* slash-command registry) — same rationale as `shake-types.ts`.
|
|
7
|
+
*
|
|
8
|
+
* Each mode is a one-off override layered on top of the configured
|
|
9
|
+
* `compaction.*` settings for a single invocation; it never mutates settings.
|
|
10
|
+
* Adding a mode is a single entry here: the command surface (autocomplete +
|
|
11
|
+
* ACP hint), the parser, and the engine override all read this table.
|
|
12
|
+
*/
|
|
13
|
+
/** Subcommand selecting a one-off compaction mode for manual `/compact`. */
|
|
14
|
+
export type CompactMode = "soft" | "remote" | "snapcompact";
|
|
15
|
+
/**
|
|
16
|
+
* Per-invocation overrides merged over the configured `compaction.*` settings.
|
|
17
|
+
* Narrowed to the two knobs the modes actually flip; the result stays
|
|
18
|
+
* assignable to the full `CompactionSettings`.
|
|
19
|
+
*/
|
|
20
|
+
export interface CompactionOverride {
|
|
21
|
+
strategy?: "context-full" | "snapcompact";
|
|
22
|
+
remoteEnabled?: boolean;
|
|
23
|
+
}
|
|
24
|
+
export interface CompactModeDef {
|
|
25
|
+
readonly name: CompactMode;
|
|
26
|
+
/** One-line description surfaced in autocomplete + help. */
|
|
27
|
+
readonly description: string;
|
|
28
|
+
/** Settings overrides applied on top of `compaction.*` for this run. */
|
|
29
|
+
readonly overrides: CompactionOverride;
|
|
30
|
+
/**
|
|
31
|
+
* When true, the mode produces no LLM summary, so trailing focus text is
|
|
32
|
+
* meaningless and rejected by the parser (snapcompact archives history into
|
|
33
|
+
* images without a directed summary).
|
|
34
|
+
*/
|
|
35
|
+
readonly rejectsFocus?: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* When true, the mode explicitly demands a remote path; the engine warns and
|
|
38
|
+
* falls back to a local summary if neither a remote endpoint nor a
|
|
39
|
+
* provider-native compaction path is available.
|
|
40
|
+
*/
|
|
41
|
+
readonly requiresRemote?: boolean;
|
|
42
|
+
}
|
|
43
|
+
export declare const COMPACT_MODES: readonly CompactModeDef[];
|
|
44
|
+
/** Resolve a subcommand token (case-insensitive) to its mode definition. */
|
|
45
|
+
export declare function findCompactMode(name: string): CompactModeDef | undefined;
|
|
46
|
+
/** Parsed `/compact` arguments: an optional mode plus optional focus text. */
|
|
47
|
+
export interface ParsedCompactArgs {
|
|
48
|
+
mode?: CompactMode;
|
|
49
|
+
instructions?: string;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Split `/compact` args into a leading mode subcommand + focus instructions.
|
|
53
|
+
*
|
|
54
|
+
* Backward compatible: when the first token is not a known mode, the entire
|
|
55
|
+
* argument string is treated as focus instructions (the historical behavior).
|
|
56
|
+
* A recognized mode with `rejectsFocus` and trailing text is an error.
|
|
57
|
+
*/
|
|
58
|
+
export declare function parseCompactArgs(args: string): ParsedCompactArgs | {
|
|
59
|
+
error: string;
|
|
60
|
+
};
|
|
@@ -163,8 +163,6 @@ export declare function truncateMiddle(content: string, options?: TruncationOpti
|
|
|
163
163
|
export interface InlineByteCapOptions {
|
|
164
164
|
/** Inline byte budget. Defaults to {@link DEFAULT_MAX_BYTES}. */
|
|
165
165
|
maxBytes?: number;
|
|
166
|
-
/** What the text is, for the elision marker (e.g. "bash output"). */
|
|
167
|
-
label: string;
|
|
168
166
|
/**
|
|
169
167
|
* Persist the full text as a session artifact. When an artifact id is
|
|
170
168
|
* returned, a `[raw output: artifact://<id>]` footer is appended so the
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type AutocompleteItem } from "@oh-my-pi/pi-tui";
|
|
2
2
|
import type { BuiltinSlashCommand, ParsedSlashCommand, SlashCommandResult, SlashCommandRuntime, SlashCommandSpec, TuiSlashCommandRuntime } from "./types";
|
|
3
3
|
export type { BuiltinSlashCommand, SubcommandDef } from "./types";
|
|
4
4
|
/** TUI-specific runtime accepted by `executeBuiltinSlashCommand`. */
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type Component } from "@oh-my-pi/pi-tui";
|
|
2
|
+
/**
|
|
3
|
+
* One-shot transcript block that prints a collab browser-join URL as a
|
|
4
|
+
* scannable QR code. The symbol is encoded once at construction (byte mode,
|
|
5
|
+
* EC level M) and rendered as ANSI half-blocks; on terminals too narrow for
|
|
6
|
+
* the symbol it degrades to a one-line hint pointing at the printed URL.
|
|
7
|
+
*/
|
|
8
|
+
export declare class CollabQrCodeComponent implements Component {
|
|
9
|
+
#private;
|
|
10
|
+
readonly url: string;
|
|
11
|
+
constructor(url: string);
|
|
12
|
+
render(width: number): readonly string[];
|
|
13
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { InMemorySnapshotStore } from "@oh-my-pi/hashline";
|
|
2
2
|
import type { AgentTelemetryConfig, AgentTool } from "@oh-my-pi/pi-agent-core";
|
|
3
|
-
import type { FetchImpl, Model, ToolChoice } from "@oh-my-pi/pi-ai";
|
|
3
|
+
import type { FetchImpl, ImageContent, Model, ToolChoice } from "@oh-my-pi/pi-ai";
|
|
4
4
|
import type { AsyncJobManager } from "../async/job-manager";
|
|
5
5
|
import type { Rule } from "../capability/rule";
|
|
6
6
|
import type { PromptTemplate } from "../config/prompt-templates";
|
|
@@ -71,6 +71,12 @@ export type ContextFileEntry = {
|
|
|
71
71
|
content: string;
|
|
72
72
|
depth?: number;
|
|
73
73
|
};
|
|
74
|
+
/** Image attachment handle exposed to tools for user-facing labels such as `Image #1`. */
|
|
75
|
+
export type ImageAttachmentEntry = {
|
|
76
|
+
label: string;
|
|
77
|
+
uri: string;
|
|
78
|
+
image: ImageContent;
|
|
79
|
+
};
|
|
74
80
|
export type { DiscoverableTool, DiscoverableToolSearchIndex, DiscoverableToolSearchResult, DiscoverableToolSource, } from "../tool-discovery/tool-index";
|
|
75
81
|
/**
|
|
76
82
|
* A late LSP diagnostics result that arrived after the edit/write tool already
|
|
@@ -309,6 +315,8 @@ export interface ToolSession {
|
|
|
309
315
|
/** Get the active OpenTelemetry config so subagent dispatch can forward
|
|
310
316
|
* the parent's tracer/hooks with the subagent's own identity stamped. */
|
|
311
317
|
getTelemetry?: () => AgentTelemetryConfig | undefined;
|
|
318
|
+
/** Return image attachments visible to tools for resolving labels such as `Image #1`. */
|
|
319
|
+
getImageAttachments?: () => ImageAttachmentEntry[];
|
|
312
320
|
}
|
|
313
321
|
export type ToolFactory = (session: ToolSession) => Tool | null | Promise<Tool | null>;
|
|
314
322
|
export type BuiltinToolLoadMode = "essential" | "discoverable";
|
|
@@ -25,6 +25,16 @@ export interface LoadImageInputOptions {
|
|
|
25
25
|
/** Force non-WebP output (e.g. for Ollama). Leave unset to honor `OMP_NO_WEBP`. */
|
|
26
26
|
excludeWebP?: boolean;
|
|
27
27
|
}
|
|
28
|
+
/** Options for loading an in-memory chat image attachment as a vision-model input. */
|
|
29
|
+
export interface LoadImageAttachmentInputOptions {
|
|
30
|
+
image: ImageContent;
|
|
31
|
+
label: string;
|
|
32
|
+
uri: string;
|
|
33
|
+
autoResize: boolean;
|
|
34
|
+
maxBytes?: number;
|
|
35
|
+
/** Force non-WebP output (e.g. for Ollama). Leave unset to honor `OMP_NO_WEBP`. */
|
|
36
|
+
excludeWebP?: boolean;
|
|
37
|
+
}
|
|
28
38
|
export interface LoadedImageInput {
|
|
29
39
|
resolvedPath: string;
|
|
30
40
|
mimeType: string;
|
|
@@ -53,3 +63,5 @@ export interface NormalizeModelContextImagesOptions {
|
|
|
53
63
|
*/
|
|
54
64
|
export declare function normalizeModelContextImages(images: ImageContent[] | undefined, options?: NormalizeModelContextImagesOptions): Promise<ImageContent[] | undefined>;
|
|
55
65
|
export declare function loadImageInput(options: LoadImageInputOptions): Promise<LoadedImageInput | null>;
|
|
66
|
+
/** Loads a chat attachment image through the same size and encoder policy as file-backed image inputs. */
|
|
67
|
+
export declare function loadImageAttachmentInput(options: LoadImageAttachmentInputOptions): Promise<LoadedImageInput | null>;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Self-contained QR Code generator (byte mode, versions 1-40, EC levels
|
|
3
|
+
* L/M/Q/H) with a half-block ANSI terminal renderer.
|
|
4
|
+
*
|
|
5
|
+
* Pure TypeScript, zero dependencies: the collab `/collab qrcode` command uses
|
|
6
|
+
* it to print scannable browser-join codes without pulling a runtime QR
|
|
7
|
+
* package into the bundle. The algorithm follows ISO/IEC 18004; the two
|
|
8
|
+
* error-correction tables below are direct transcriptions of that spec.
|
|
9
|
+
*/
|
|
10
|
+
export type QrEcLevel = "L" | "M" | "Q" | "H";
|
|
11
|
+
export interface QrEncodeOptions {
|
|
12
|
+
/** Lowest version to consider (default 1). */
|
|
13
|
+
minVersion?: number;
|
|
14
|
+
/** Highest version to consider (default 40). */
|
|
15
|
+
maxVersion?: number;
|
|
16
|
+
/** Force a mask 0-7; -1 (default) auto-selects the lowest-penalty mask. */
|
|
17
|
+
mask?: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* A finished QR symbol: a square grid of dark/light modules plus the chosen
|
|
21
|
+
* version, EC level, and mask. `module(x, y)` is the only access path the
|
|
22
|
+
* renderers need.
|
|
23
|
+
*/
|
|
24
|
+
export declare class QrCode {
|
|
25
|
+
#private;
|
|
26
|
+
readonly version: number;
|
|
27
|
+
readonly ecLevel: QrEcLevel;
|
|
28
|
+
readonly size: number;
|
|
29
|
+
/** Selected mask pattern (0-7). */
|
|
30
|
+
readonly mask: number;
|
|
31
|
+
private constructor();
|
|
32
|
+
module(x: number, y: number): boolean;
|
|
33
|
+
/** Encode a string in byte mode (UTF-8). Throws if it exceeds version 40. */
|
|
34
|
+
static encodeText(text: string, ecLevel?: QrEcLevel, options?: QrEncodeOptions): QrCode;
|
|
35
|
+
/** Encode raw bytes in byte mode. Throws if they exceed version 40 at this EC level. */
|
|
36
|
+
static encodeBytes(data: Uint8Array, ecLevel?: QrEcLevel, options?: QrEncodeOptions): QrCode;
|
|
37
|
+
}
|
|
38
|
+
export interface QrRenderOptions {
|
|
39
|
+
/** Quiet-zone width in modules on every side (default 4, per spec). */
|
|
40
|
+
margin?: number;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Render a QR symbol as ANSI half-block rows: each text row packs two module
|
|
44
|
+
* rows via `▀`/`▄`/`█`, drawn black-on-white so a phone camera reads dark
|
|
45
|
+
* modules as data and the quiet zone as the light margin. The leading margin
|
|
46
|
+
* makes the symbol scannable regardless of the terminal's own background.
|
|
47
|
+
*/
|
|
48
|
+
export declare function renderQrHalfBlocks(qr: QrCode, options?: QrRenderOptions): string[];
|