@oh-my-pi/pi-coding-agent 15.9.1 → 15.9.5
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 +68 -2
- package/dist/types/cli/classify-install-target.d.ts +5 -1
- package/dist/types/cli/dry-balance-cli.d.ts +104 -0
- package/dist/types/commands/dry-balance.d.ts +31 -0
- package/dist/types/config/model-registry.d.ts +2 -0
- package/dist/types/config/models-config-schema.d.ts +3 -0
- package/dist/types/config/settings-schema.d.ts +13 -4
- package/dist/types/config/settings.d.ts +11 -0
- package/dist/types/discovery/helpers.d.ts +1 -0
- package/dist/types/extensibility/plugins/legacy-pi-compat.d.ts +2 -3
- package/dist/types/hindsight/bank.d.ts +17 -9
- package/dist/types/hindsight/mental-models.d.ts +1 -1
- package/dist/types/hindsight/state.d.ts +9 -3
- package/dist/types/mcp/manager.d.ts +1 -1
- package/dist/types/modes/components/assistant-message.d.ts +11 -0
- package/dist/types/modes/components/custom-editor.d.ts +3 -1
- package/dist/types/modes/components/error-banner.d.ts +11 -0
- package/dist/types/modes/components/tool-execution.d.ts +15 -0
- package/dist/types/modes/components/transcript-container.d.ts +4 -2
- package/dist/types/modes/components/user-message.d.ts +1 -1
- package/dist/types/modes/image-references.d.ts +17 -0
- package/dist/types/modes/interactive-mode.d.ts +7 -0
- package/dist/types/modes/types.d.ts +7 -0
- package/dist/types/modes/utils/ui-helpers.d.ts +1 -0
- package/dist/types/session/agent-session.d.ts +9 -0
- package/dist/types/session/auth-storage.d.ts +2 -2
- package/dist/types/session/blob-store.d.ts +12 -11
- package/dist/types/session/session-manager.d.ts +5 -3
- package/dist/types/system-prompt.d.ts +2 -0
- package/dist/types/task/types.d.ts +2 -0
- package/dist/types/tiny/title-client.d.ts +16 -1
- package/dist/types/tool-discovery/mode.d.ts +8 -0
- package/dist/types/tools/archive-reader.d.ts +5 -1
- package/dist/types/tools/index.d.ts +16 -0
- package/dist/types/tools/path-utils.d.ts +11 -0
- package/dist/types/tui/hyperlink.d.ts +12 -0
- package/dist/types/web/search/render.d.ts +1 -2
- package/package.json +9 -9
- package/src/cli/classify-install-target.ts +31 -5
- package/src/cli/dry-balance-cli.ts +823 -0
- package/src/cli/plugin-cli.ts +45 -0
- package/src/cli/web-search-cli.ts +0 -1
- package/src/cli-commands.ts +1 -0
- package/src/commands/dry-balance.ts +43 -0
- package/src/config/model-registry.ts +60 -4
- package/src/config/models-config-schema.ts +2 -0
- package/src/config/settings-schema.ts +14 -4
- package/src/config/settings.ts +38 -0
- package/src/discovery/builtin-rules/ts-no-tiny-functions.md +1 -0
- package/src/discovery/github.ts +37 -1
- package/src/discovery/helpers.ts +3 -1
- package/src/eval/__tests__/agent-bridge.test.ts +72 -0
- package/src/eval/py/tool-bridge.ts +43 -5
- package/src/extensibility/custom-commands/bundled/ci-green/index.ts +31 -2
- package/src/extensibility/plugins/legacy-pi-compat.ts +245 -25
- package/src/hindsight/backend.ts +184 -35
- package/src/hindsight/bank.ts +32 -22
- package/src/hindsight/mental-models.ts +1 -1
- package/src/hindsight/state.ts +21 -7
- package/src/internal-urls/docs-index.generated.ts +6 -6
- package/src/internal-urls/omp-protocol.ts +8 -2
- package/src/main.ts +7 -1
- package/src/mcp/manager.ts +40 -21
- package/src/modes/components/assistant-message.ts +22 -0
- package/src/modes/components/custom-editor.ts +14 -2
- package/src/modes/components/error-banner.ts +33 -0
- package/src/modes/components/tool-execution.ts +44 -0
- package/src/modes/components/transcript-container.ts +102 -30
- package/src/modes/components/tree-selector.ts +29 -2
- package/src/modes/components/user-message.ts +9 -2
- package/src/modes/controllers/event-controller.ts +42 -3
- package/src/modes/controllers/input-controller.ts +41 -3
- package/src/modes/image-references.ts +111 -0
- package/src/modes/interactive-mode.ts +48 -13
- package/src/modes/setup-wizard/scenes/sign-in.ts +27 -7
- package/src/modes/types.ts +10 -1
- package/src/modes/utils/ui-helpers.ts +23 -2
- package/src/prompts/agents/explore.md +1 -0
- package/src/prompts/agents/librarian.md +1 -0
- package/src/prompts/ci-green-request.md +5 -3
- package/src/prompts/dry-balance-bench.md +8 -0
- package/src/prompts/system/project-prompt.md +1 -0
- package/src/sdk.ts +99 -18
- package/src/session/agent-session.ts +103 -19
- package/src/session/auth-storage.ts +4 -0
- package/src/session/blob-store.ts +96 -9
- package/src/session/session-manager.ts +19 -10
- package/src/system-prompt.ts +4 -0
- package/src/task/executor.ts +6 -2
- package/src/task/index.ts +8 -7
- package/src/task/types.ts +2 -0
- package/src/tiny/title-client.ts +7 -1
- package/src/tool-discovery/mode.ts +24 -0
- package/src/tools/archive-reader.ts +339 -31
- package/src/tools/bash.ts +3 -4
- package/src/tools/fetch.ts +29 -9
- package/src/tools/gh.ts +65 -11
- package/src/tools/index.ts +22 -8
- package/src/tools/job.ts +3 -3
- package/src/tools/memory-reflect.ts +2 -2
- package/src/tools/path-utils.ts +21 -0
- package/src/tools/read.ts +58 -12
- package/src/tools/search-tool-bm25.ts +4 -6
- package/src/tools/search.ts +78 -12
- package/src/tui/hyperlink.ts +42 -7
- package/src/utils/file-mentions.ts +7 -107
- package/src/utils/title-generator.ts +58 -37
- package/src/web/search/index.ts +2 -2
- package/src/web/search/render.ts +20 -52
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,73 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [15.9.5] - 2026-06-05
|
|
6
|
+
### Added
|
|
7
|
+
|
|
8
|
+
- Added a persistent error banner pinned above the editor when an assistant turn ends on a provider error (e.g. Anthropic's "Output blocked by content filtering policy"). The transcript `Error: …` line scrolls away as the conversation grows, so terminal turns that ended on a stream error could pass unnoticed; the banner stays in the fixed region above the input and is cleared when the next turn starts.
|
|
9
|
+
|
|
10
|
+
- Added bold, underlined, clickable `[Image #N]` placeholders in the draft editor and sent user-message bubbles, backed by extension-bearing blob-store sidecar files so terminal `file://` links open in image viewers.
|
|
11
|
+
- Added the active model identifier (`provider/id`) to the system prompt's `<workstation>` block so the agent knows which model it is running as. Gated by the new `includeModelInPrompt` setting (default on); the base prompt is rebuilt on a mid-session model switch so the surfaced identifier stays current.
|
|
12
|
+
- Added `OLLAMA_HOST` support for implicit local Ollama discovery when `OLLAMA_BASE_URL` is unset, so OMP picks up the same host setting used by Ollama.
|
|
13
|
+
- Added `OLLAMA_CONTEXT_LENGTH` as a positive-integer context-window override for implicit local Ollama discovery, so users can correct OMP context budgeting without writing per-model overrides.
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- Changed `tools.discoveryMode` to default to `auto`, which keeps discovery off for small tool sets and automatically switches to MCP-only tool discovery when more than 40 tools are registered.
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
|
|
21
|
+
- Fixed user-message rendering to materialize image links from embedded image blocks when rebuilding chat output, so image placeholders remain clickable after replayed or restored messages
|
|
22
|
+
- Fixed queued/steering user messages carrying a pasted image rendering out of order — sometimes dropping the user bubble *below* the very tool output it was sent to steer. `EventController.#handleMessageStart` awaited async image-link materialization between the user `message_start` and `addMessageToChat`; since `AgentSession.#emit` dispatches TUI listeners fire-and-forget, that mid-handler yield let the next synchronously-handled events (assistant `message_start`, tool execution start/end) append their components first, scrambling transcript order and live-region block boundaries. The bubble is now appended synchronously, with clickable image links still materialized via the synchronous blob-store fallback.
|
|
23
|
+
- Fixed tool execution cards to finalize promptly when a turn is abandoned or completed so stale streaming previews and frozen spinner frames no longer keep transcript rows in the live region
|
|
24
|
+
- Fixed `read` and `search` TUI rendering to emit OSC 8 hyperlinks for HTTP URLs, `local://` resources backed by files, and filesystem search targets, including line-specific links for search match rows.
|
|
25
|
+
- Fixed aborted streaming assistant messages staying frozen before their red "Operation aborted" label when status rows were appended underneath on ED3-risk terminals.
|
|
26
|
+
- Fixed `omp` / `omp -c` stacking a fresh welcome screen and transcript on top of the previous run's leftover terminal scrollback. The cold-launch transcript render was the only session-load path that did not pass `clearTerminalHistory`, so the TUI's scrollback-preserving initial paint left the prior run's welcome + conversation above the new one; the cold launch now clears native scrollback before painting, matching every in-process session switch.
|
|
27
|
+
- Fixed a long streamed assistant reply dropping its earlier lines on ED3-risk terminals (Ghostty/kitty/iTerm2) once it grew past the viewport — the head scrolled off the top and never reached scrollback, so the reply rendered as a ~viewport-tall circular buffer of only its latest lines. `AssistantMessageComponent` now reports itself as an append-only transcript block and `TranscriptContainer` surfaces the resulting commit-safe boundary, so the renderer commits the scrolled-off head to native scrollback instead of discarding it (volatile tool previews stay deferred as before).
|
|
28
|
+
|
|
29
|
+
### Security
|
|
30
|
+
|
|
31
|
+
- Blocked OSC 8 hyperlink wrapping for URI targets containing terminal control bytes to avoid rendering malformed control-sequence links
|
|
32
|
+
|
|
33
|
+
## [15.9.4] - 2026-06-05
|
|
34
|
+
### Fixed
|
|
35
|
+
|
|
36
|
+
- Fixed chat transcript updates after submitting input so frozen scrollback is only thawed when native scrollback replay succeeds, preventing misplaced or duplicated rows when the viewport is not at the tail
|
|
37
|
+
- Fixed `read` of `.zip` archives to list the central directory without inflating every member, so large or corrupt zip payloads no longer freeze directory reads; member contents are inflated only when a specific entry is read.
|
|
38
|
+
- Fixed the Python `eval` kernel being hard-killed (and its persistent session state lost) when a cell blocked in `parallel()` / `agent()` was interrupted. Each `agent()`/`tool.*` call blocks a kernel worker thread in a synchronous `urllib` request to the host bridge, and `parallel()`'s `ThreadPoolExecutor` exit joins those threads — so the kernel cannot unwind a `KeyboardInterrupt` until every in-flight bridge call returns. A wide subagent fan-out's teardown routinely outlasted the kernel's 5s SIGINT-escalation window, so the kernel was force-killed (surfacing `[kernel] Python kernel shutdown`) while the subagents were still winding down. The host bridge now resolves an in-flight call the instant the cell's signal aborts, so the kernel unwinds cleanly and keeps its state; the already-signaled subagent continues tearing down in the background.
|
|
39
|
+
- Fixed `github` tool `run_watch` op ignoring the explicit `repo` argument and silently watching the cwd-inferred repository in nested/umbrella workspaces. `executeRunWatch` passed `undefined` for the user-supplied `repo` to `resolveGitHubRepo`, so a call like `{op: "run_watch", repo: "owner/cxf", branch: "main"}` fell back to `gh repo view` in cwd and streamed `watching <sha> on <cwd-repo>` against the wrong repository. The explicit `repo` now takes precedence over the cwd inference, and the no-`branch`/no-`run` path refuses to derive the watched commit from `git HEAD` unless the cwd actually points at the resolved repo — otherwise it raises a `ToolError` telling the caller to pass `branch` or `run` instead of silently rebinding to an unrelated commit ([#1949](https://github.com/can1357/oh-my-pi/issues/1949)).
|
|
40
|
+
- Fixed `omp plugin install <local-path>` failing with `Invalid package name: .` (and similar) for cwd-relative (`.`, `./pkg`), absolute (`/abs`, `C:\…`, `\\unc`), and tilde-prefixed (`~/pkg`) specs. `classifyInstallTarget` now returns a `local` arm in addition to `marketplace`/`npm`, and `plugin install` routes those specs to `PluginManager.link()` — the same code path as `omp plugin link`. ([#1945](https://github.com/can1357/oh-my-pi/issues/1945))
|
|
41
|
+
- Fixed the `web_search` result renderer capping the synthesized answer at 12 lines even when expanded, while the Sources list expanded in full — so a long answer stayed truncated ("… N more lines") after `Ctrl+O`, making the expand toggle look like a no-op and dwarfing the answer next to its sources. The answer now renders the full text (markdown-formatted) when expanded and a short markdown preview when collapsed, matching the sources' collapse/expand behavior. The answer is also rendered through the Markdown component instead of dimmed raw lines, so headings, bold, lists, and code in the answer display formatted.
|
|
42
|
+
|
|
43
|
+
## [15.9.3] - 2026-06-05
|
|
44
|
+
|
|
45
|
+
### Fixed
|
|
46
|
+
|
|
47
|
+
- Fixed `@`-mention auto-read injecting an unrelated, same-named file when a mention did not point at a real path — e.g. an npm scope like `@scope/`, a partial path, or a bare token. `generateFileMentionMessages` resolution previously fell back to prefix and repo-wide fuzzy matching (globbing the whole project on every such mention) and auto-read the single "best" guess. Resolution is now exact-only: a mention is auto-read only when it resolves to an existing file or directory; otherwise it is left as prose. The TUI `@`-selector already inserts the real, complete path before send, so post-send guessing was both unnecessary and the source of the wrong-file reads. Directories still resolve and are listed. Removes the per-mention `**/*` project scan.
|
|
48
|
+
|
|
49
|
+
## [15.9.2] - 2026-06-05
|
|
50
|
+
|
|
51
|
+
### Added
|
|
52
|
+
|
|
53
|
+
- Added an encrypted local auth-broker snapshot cache for `discoverAuthStorage`, with `OMP_AUTH_BROKER_SNAPSHOT_TTL_MS` and `OMP_AUTH_BROKER_SNAPSHOT_CACHE`, so fresh cached broker credentials can boot without a blocking `/v1/snapshot` fetch and survive broker-down startup windows.
|
|
54
|
+
- Added `dry-balance` CLI command to perform a dry-run OAuth account balancing check across configurable random session IDs, with sample and concurrency options, JSON output, and success/failure summary reporting
|
|
55
|
+
- Added `--json` output mode and machine-readable result format to `omp dry-balance` for automated use
|
|
56
|
+
- Added `omitMaxOutputTokens` to `models.yml` model definitions and `modelOverrides`, so users can opt a model out of the on-the-wire `max_output_tokens` / `max_tokens` cap while keeping the catalog `maxTokens` for local budgeting. Intended for Ollama-style proxies whose upstream output limit OMP cannot discover. ([#1881](https://github.com/can1357/oh-my-pi/issues/1881))
|
|
57
|
+
|
|
58
|
+
### Fixed
|
|
59
|
+
|
|
60
|
+
- Fixed TTSR rule-violation injections leaking the absolute home directory to the model: the `ttsr-interrupt` / `ttsr-tool-reminder` blocks rendered the matched rule's `path` as its absolute on-disk path (e.g. `/Users/me/Projects/app/.omp/rules/no-any.md`). The path is now relativized to the session cwd when the rule lives in the project (`.omp/rules/no-any.md`), or `~`-relative when it lives under home, so no absolute path is fed into the agent's context outside the system prompt.
|
|
61
|
+
- Fixed `AsyncJobManager.instance()` being cleared while the owning top-level session was still live, which broke the `task` async path with "Async execution is enabled but no async job manager is available" until process restart. Any in-process secondary top-level `createAgentSession()` call (e.g. the Agent Control Center's create flow in `agent-dashboard.ts`) constructed a fresh `AsyncJobManager`, overwrote the singleton, and then cleared it on its own dispose. Secondary sessions now leave the live singleton untouched, and their dispose-time cleanup is scoped so it can no longer cancel the primary session's running bash/task jobs. `bash` / `task` / `job` tools and session job snapshots now resolve the manager through session-scoped async manager wiring rather than `AsyncJobManager.instance()`, so a secondary in-process top-level session cannot accidentally register background work on the owning session's manager or report the owning session's jobs; subagents still inherit the parent's manager via their scoped async manager. Startup failures after a top-level session installs its manager now clear and dispose that manager before the next session decides whether it can create its own ([#1923](https://github.com/can1357/oh-my-pi/issues/1923)).
|
|
62
|
+
- Fixed the `task` tool returning a hard `Async execution is enabled but no async job manager is available.` error when `async.enabled` was true but `AsyncJobManager.instance()` returned `undefined`, leaving `task` non-functional for the rest of the session. The tool now falls back to the existing synchronous execution path (which still runs subagents concurrently via `mapWithConcurrencyLimit`), and logs a warning so the missing-manager state stays diagnosable ([#1922](https://github.com/can1357/oh-my-pi/issues/1922)).
|
|
63
|
+
- Fixed Hindsight retain/recall/reflect calls staying pinned to the bank that was selected when the session started after the operator edited `hindsight.bankId`, `hindsight.bankIdPrefix`, or `hindsight.scoping` mid-session. The backend now subscribes to those settings via `onHindsightScopeChanged` and rebuilds the active `HindsightSessionState` against the recomputed scope, disposing the old state after flushing its queue so in-flight tool-initiated retains still land in the bank they were enqueued for. Also renamed `ensureBankMission` to `ensureBankExists` so a blank `bankMission` no longer skips bank creation entirely, and called it before mental-model bootstrap so `createMentalModel` is never the first POST against a missing bank. `AgentSession.dispose` now flushes the retain queue before clearing `#hindsightSessionState`, since the queue's identity guard would otherwise drop the spliced batch ([#1902](https://github.com/can1357/oh-my-pi/issues/1902)).
|
|
64
|
+
- Fixed `/tree` rendering a bare "No entries found" line on a fresh session where the only persisted entries are the `model_change` + `thinking_level_change` written by `sdk.ts` at startup — both are hidden by the tree-selector's default filter, so `#filteredNodes.length === 0` while `tree.length === 2` and the controller's `tree.length === 0` short-circuit never fired. The selector now splits the empty-state into three distinct shapes — truly empty tree, search query with no matches, and filter mode rejecting every entry — surfacing the cause and the recovery key (`Alt+A` to show all, `Backspace` to clear a stale search) so users on a fresh session can see immediately that the panel isn't broken ([#1909](https://github.com/can1357/oh-my-pi/issues/1909)).
|
|
65
|
+
- Fixed remote MCP OAuth refresh failures leaving stale credentials in `agent.db`: when the token endpoint returns a definitive failure (`invalid_grant`, `invalid_token`, `revoked`, plain 401/403 not classified as transient), `MCPManager#resolveAuthConfig` now drops the credential via `AuthStorage.remove(credentialId)` and skips re-attaching the dead `Authorization: Bearer …` header. Previously a revoked refresh token kept producing `401 invalid_token` on every MCP request and survived restarts, so users had to hand-clear the credential row to recover; the next connect now surfaces a clean auth error and `/mcp reauth <server>` (or `/mcp unauth`) recovers without restarting. Transient refresh failures (network/`fetch failed`/`ECONNREFUSED`) still fall back to the existing access token ([#1908](https://github.com/can1357/oh-my-pi/issues/1908)).
|
|
66
|
+
- Fixed `omp://docs` and `omp://docs/...` internal documentation URLs in the distributed package to resolve through the embedded documentation index instead of failing with `Documentation file not found` ([#1898](https://github.com/can1357/oh-my-pi/issues/1898)).
|
|
67
|
+
- Fixed the `github` discovery provider silently ignoring `.github/skills/<name>/SKILL.md`, GitHub's documented Agent Skills layout. The provider now registers a `skills` capability (priority 30, project-only) that scans `.github/skills/` non-recursively via `scanSkillsFromDir` with `requireDescription: true`, matching the Agent Skills spec and the sibling `native`/`omp-plugins` providers ([#1906](https://github.com/can1357/oh-my-pi/issues/1906)).
|
|
68
|
+
- Fixed inline images rendering as a wall of empty PUA box glyphs with laggy scrolling on Kitty-protocol terminals that do not honor Unicode placeholders (most notably WezTerm and tmux/screen passthrough to a non-Kitty outer terminal). The 15.9 placeholder rollout enabled the `U=1`/U+10EEEE grid for every Kitty-protocol path; it now defaults on only for `kitty` and `ghostty`, with `PI_NO_KITTY_PLACEHOLDERS=1` as a hard opt-out and `PI_KITTY_PLACEHOLDERS=1` as opt-in for terminals (e.g. wezterm nightlies) that have since added support ([#1877](https://github.com/can1357/oh-my-pi/issues/1877)).
|
|
69
|
+
- Fixed auto session-title generation failures being swallowed without an actionable diagnostic. Title generation now logs structured start, missing-model/API-key, provider-error, empty-result, and exception outcomes with the session id and resolved title model; the interactive auto-title caller also logs uncaught persistence/generation errors instead of dropping them. ([#1892](https://github.com/can1357/oh-my-pi/issues/1892))
|
|
70
|
+
- Fixed `TranscriptContainer` reporting the live block boundary to the TUI again, so ED3-risk foreground streaming can append newly sealed transcript blocks to native scrollback once while deferring only the active live block.
|
|
71
|
+
|
|
5
72
|
## [15.9.1] - 2026-06-04
|
|
6
73
|
|
|
7
74
|
### Added
|
|
@@ -20,7 +87,6 @@
|
|
|
20
87
|
### Fixed
|
|
21
88
|
|
|
22
89
|
- Fixed a streamed assistant message freezing at a partial prefix (e.g. only "Nat" of "Natives built, now…") on ED3-risk terminals (Ghostty/kitty/iTerm2/Alacritty), with the final text appearing only after a resize. `TranscriptContainer` freezes each non-live block by replaying its last live render, but render coalescing can finalize a block's content and append the next block within the same throttled frame — so the block was sealed at its stale mid-stream snapshot and never repainted until the next `thaw`. The block that was live on the previous render is now recomputed once on the live→frozen transition, sealing it at its final content.
|
|
23
|
-
|
|
24
90
|
- Fixed ACP/RPC stdio startup so protocol frames are no longer consumed as one-shot piped prompt input before the JSON-RPC transport starts.
|
|
25
91
|
- Fixed `omp completions` to await the completion script write before exiting.
|
|
26
92
|
- Fixed `AssistantMessageComponent` exposing its stable-prefix completion API again so streamed assistant messages remain unstable until explicitly completed.
|
|
@@ -9333,4 +9399,4 @@ Initial public release.
|
|
|
9333
9399
|
- Git branch display in footer
|
|
9334
9400
|
- Message queueing during streaming responses
|
|
9335
9401
|
- OAuth integration for Gmail and Google Calendar access
|
|
9336
|
-
- HTML export with syntax highlighting and collapsible sections
|
|
9402
|
+
- HTML export with syntax highlighting and collapsible sections
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
export
|
|
1
|
+
export type ClassifiedInstallTarget = {
|
|
2
|
+
type: "local";
|
|
3
|
+
path: string;
|
|
4
|
+
} | {
|
|
2
5
|
type: "marketplace";
|
|
3
6
|
name: string;
|
|
4
7
|
marketplace: string;
|
|
@@ -6,3 +9,4 @@ export declare function classifyInstallTarget(spec: string, knownMarketplaces: S
|
|
|
6
9
|
type: "npm";
|
|
7
10
|
spec: string;
|
|
8
11
|
};
|
|
12
|
+
export declare function classifyInstallTarget(spec: string, knownMarketplaces: Set<string>): ClassifiedInstallTarget;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import type { Api, AssistantMessageEventStream, Context, Model, OAuthAccess, OAuthAccessResolution, SimpleStreamOptions } from "@oh-my-pi/pi-ai";
|
|
2
|
+
import type { CanonicalModelVariant } from "../config/model-equivalence";
|
|
3
|
+
import { type CanonicalModelQueryOptions } from "../config/model-registry";
|
|
4
|
+
import { Settings } from "../config/settings";
|
|
5
|
+
export interface DryBalanceCommandArgs {
|
|
6
|
+
model?: string;
|
|
7
|
+
flags: {
|
|
8
|
+
model?: string;
|
|
9
|
+
count?: number;
|
|
10
|
+
concurrency?: number;
|
|
11
|
+
json?: boolean;
|
|
12
|
+
bench?: boolean;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
export interface DryBalanceAuthOptions {
|
|
16
|
+
baseUrl?: string;
|
|
17
|
+
modelId?: string;
|
|
18
|
+
signal?: AbortSignal;
|
|
19
|
+
}
|
|
20
|
+
export interface DryBalanceAuthStorage {
|
|
21
|
+
getOAuthAccess(provider: string, sessionId?: string, options?: DryBalanceAuthOptions): Promise<OAuthAccess | undefined>;
|
|
22
|
+
getOAuthAccesses?(provider: string, options?: DryBalanceAuthOptions): Promise<OAuthAccessResolution[]>;
|
|
23
|
+
}
|
|
24
|
+
export interface DryBalanceModelRegistry {
|
|
25
|
+
authStorage: DryBalanceAuthStorage;
|
|
26
|
+
getAll(): Model<Api>[];
|
|
27
|
+
getAvailable(): Model<Api>[];
|
|
28
|
+
getApiKey(model: Model<Api>, sessionId?: string): Promise<string | undefined>;
|
|
29
|
+
getCanonicalVariants(canonicalId: string, options?: CanonicalModelQueryOptions): CanonicalModelVariant[];
|
|
30
|
+
resolveCanonicalModel?(canonicalId: string, options?: CanonicalModelQueryOptions): Model<Api> | undefined;
|
|
31
|
+
getCanonicalId?(model: Model<Api>): string | undefined;
|
|
32
|
+
}
|
|
33
|
+
export interface DryBalanceRuntime {
|
|
34
|
+
modelRegistry: DryBalanceModelRegistry;
|
|
35
|
+
settings?: Settings;
|
|
36
|
+
close?: () => void;
|
|
37
|
+
}
|
|
38
|
+
export interface DryBalanceAccountStat {
|
|
39
|
+
account: string;
|
|
40
|
+
count: number;
|
|
41
|
+
percent: number;
|
|
42
|
+
}
|
|
43
|
+
export interface DryBalanceFailureStat {
|
|
44
|
+
reason: string;
|
|
45
|
+
count: number;
|
|
46
|
+
percent: number;
|
|
47
|
+
}
|
|
48
|
+
export interface DryBalanceBenchSuccessResult {
|
|
49
|
+
ok: true;
|
|
50
|
+
account: string;
|
|
51
|
+
ttftMs: number;
|
|
52
|
+
durationMs: number;
|
|
53
|
+
outputTokens: number;
|
|
54
|
+
tokensPerSecond: number;
|
|
55
|
+
}
|
|
56
|
+
export interface DryBalanceBenchFailureResult {
|
|
57
|
+
ok: false;
|
|
58
|
+
account?: string;
|
|
59
|
+
error: string;
|
|
60
|
+
}
|
|
61
|
+
export type DryBalanceBenchResult = DryBalanceBenchSuccessResult | DryBalanceBenchFailureResult;
|
|
62
|
+
export interface DryBalanceBenchSummary {
|
|
63
|
+
total: number;
|
|
64
|
+
success: {
|
|
65
|
+
total: number;
|
|
66
|
+
averageTtftMs: number | null;
|
|
67
|
+
averageTokensPerSecond: number | null;
|
|
68
|
+
};
|
|
69
|
+
failure: {
|
|
70
|
+
total: number;
|
|
71
|
+
reasons: DryBalanceFailureStat[];
|
|
72
|
+
};
|
|
73
|
+
results: DryBalanceBenchResult[];
|
|
74
|
+
}
|
|
75
|
+
export interface DryBalanceSummary {
|
|
76
|
+
model: string;
|
|
77
|
+
provider: string;
|
|
78
|
+
samples: number;
|
|
79
|
+
concurrency: number;
|
|
80
|
+
success: {
|
|
81
|
+
total: number;
|
|
82
|
+
accounts: DryBalanceAccountStat[];
|
|
83
|
+
};
|
|
84
|
+
failure: {
|
|
85
|
+
total: number;
|
|
86
|
+
reasons: DryBalanceFailureStat[];
|
|
87
|
+
};
|
|
88
|
+
bench?: DryBalanceBenchSummary;
|
|
89
|
+
}
|
|
90
|
+
type DryBalanceStreamSimple = (model: Model<Api>, context: Context, options?: SimpleStreamOptions) => AssistantMessageEventStream;
|
|
91
|
+
export interface DryBalanceDependencies {
|
|
92
|
+
createRuntime?: () => Promise<DryBalanceRuntime>;
|
|
93
|
+
randomSessionId?: () => string;
|
|
94
|
+
writeStdout?: (text: string) => void;
|
|
95
|
+
writeStderr?: (text: string) => void;
|
|
96
|
+
setExitCode?: (code: number) => void;
|
|
97
|
+
streamSimple?: DryBalanceStreamSimple;
|
|
98
|
+
now?: () => number;
|
|
99
|
+
stdoutIsTTY?: boolean;
|
|
100
|
+
stderrIsTTY?: boolean;
|
|
101
|
+
}
|
|
102
|
+
export declare function formatDryBalanceText(summary: DryBalanceSummary): string;
|
|
103
|
+
export declare function runDryBalanceCommand(command: DryBalanceCommandArgs, deps?: DryBalanceDependencies): Promise<DryBalanceSummary>;
|
|
104
|
+
export {};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Command } from "@oh-my-pi/pi-utils/cli";
|
|
2
|
+
export default class DryBalance extends Command {
|
|
3
|
+
static description: string;
|
|
4
|
+
static args: {
|
|
5
|
+
model: import("@oh-my-pi/pi-utils/cli").ArgDescriptor & {
|
|
6
|
+
description: string;
|
|
7
|
+
required: false;
|
|
8
|
+
};
|
|
9
|
+
};
|
|
10
|
+
static flags: {
|
|
11
|
+
model: import("@oh-my-pi/pi-utils/cli").FlagDescriptor<"string"> & {
|
|
12
|
+
description: string;
|
|
13
|
+
};
|
|
14
|
+
count: import("@oh-my-pi/pi-utils/cli").FlagDescriptor<"integer"> & {
|
|
15
|
+
description: string;
|
|
16
|
+
default: number;
|
|
17
|
+
};
|
|
18
|
+
concurrency: import("@oh-my-pi/pi-utils/cli").FlagDescriptor<"integer"> & {
|
|
19
|
+
description: string;
|
|
20
|
+
default: number;
|
|
21
|
+
};
|
|
22
|
+
json: import("@oh-my-pi/pi-utils/cli").FlagDescriptor<"boolean"> & {
|
|
23
|
+
description: string;
|
|
24
|
+
};
|
|
25
|
+
bench: import("@oh-my-pi/pi-utils/cli").FlagDescriptor<"boolean"> & {
|
|
26
|
+
description: string;
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
static examples: string[];
|
|
30
|
+
run(): Promise<void>;
|
|
31
|
+
}
|
|
@@ -104,6 +104,7 @@ export declare const ModelsConfigFile: ConfigFile<{
|
|
|
104
104
|
premiumMultiplier?: number | undefined;
|
|
105
105
|
contextWindow?: number | undefined;
|
|
106
106
|
maxTokens?: number | undefined;
|
|
107
|
+
omitMaxOutputTokens?: boolean | undefined;
|
|
107
108
|
headers?: Record<string, string> | undefined;
|
|
108
109
|
compat?: {
|
|
109
110
|
supportsStore?: boolean | undefined;
|
|
@@ -166,6 +167,7 @@ export declare const ModelsConfigFile: ConfigFile<{
|
|
|
166
167
|
premiumMultiplier?: number | undefined;
|
|
167
168
|
contextWindow?: number | undefined;
|
|
168
169
|
maxTokens?: number | undefined;
|
|
170
|
+
omitMaxOutputTokens?: boolean | undefined;
|
|
169
171
|
headers?: Record<string, string> | undefined;
|
|
170
172
|
compat?: {
|
|
171
173
|
supportsStore?: boolean | undefined;
|
|
@@ -109,6 +109,7 @@ export declare const ModelOverrideSchema: z.ZodObject<{
|
|
|
109
109
|
premiumMultiplier: z.ZodOptional<z.ZodNumber>;
|
|
110
110
|
contextWindow: z.ZodOptional<z.ZodNumber>;
|
|
111
111
|
maxTokens: z.ZodOptional<z.ZodNumber>;
|
|
112
|
+
omitMaxOutputTokens: z.ZodOptional<z.ZodBoolean>;
|
|
112
113
|
headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
113
114
|
compat: z.ZodOptional<z.ZodObject<{
|
|
114
115
|
supportsStore: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -336,6 +337,7 @@ export declare const ModelsConfigSchema: z.ZodObject<{
|
|
|
336
337
|
premiumMultiplier: z.ZodOptional<z.ZodNumber>;
|
|
337
338
|
contextWindow: z.ZodOptional<z.ZodNumber>;
|
|
338
339
|
maxTokens: z.ZodOptional<z.ZodNumber>;
|
|
340
|
+
omitMaxOutputTokens: z.ZodOptional<z.ZodBoolean>;
|
|
339
341
|
headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
340
342
|
compat: z.ZodOptional<z.ZodObject<{
|
|
341
343
|
supportsStore: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -449,6 +451,7 @@ export declare const ModelsConfigSchema: z.ZodObject<{
|
|
|
449
451
|
premiumMultiplier: z.ZodOptional<z.ZodNumber>;
|
|
450
452
|
contextWindow: z.ZodOptional<z.ZodNumber>;
|
|
451
453
|
maxTokens: z.ZodOptional<z.ZodNumber>;
|
|
454
|
+
omitMaxOutputTokens: z.ZodOptional<z.ZodBoolean>;
|
|
452
455
|
headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
453
456
|
compat: z.ZodOptional<z.ZodObject<{
|
|
454
457
|
supportsStore: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -659,7 +659,7 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
659
659
|
readonly ui: {
|
|
660
660
|
readonly tab: "appearance";
|
|
661
661
|
readonly label: "Terminal Hyperlinks";
|
|
662
|
-
readonly description: "Wrap
|
|
662
|
+
readonly description: "Wrap paths and URLs in OSC 8 hyperlinks for terminal-native click-to-open (auto: detect support; off: never; always: unconditional)";
|
|
663
663
|
};
|
|
664
664
|
};
|
|
665
665
|
readonly "display.tabWidth": {
|
|
@@ -745,6 +745,15 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
745
745
|
readonly description: "Render full tool descriptions in the system prompt instead of a tool name list";
|
|
746
746
|
};
|
|
747
747
|
};
|
|
748
|
+
readonly includeModelInPrompt: {
|
|
749
|
+
readonly type: "boolean";
|
|
750
|
+
readonly default: true;
|
|
751
|
+
readonly ui: {
|
|
752
|
+
readonly tab: "model";
|
|
753
|
+
readonly label: "Include Model In Prompt";
|
|
754
|
+
readonly description: "Surface the active model identifier in the system prompt so the agent knows which model it is";
|
|
755
|
+
};
|
|
756
|
+
};
|
|
748
757
|
readonly temperature: {
|
|
749
758
|
readonly type: "number";
|
|
750
759
|
readonly default: -1;
|
|
@@ -2828,12 +2837,12 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
2828
2837
|
};
|
|
2829
2838
|
readonly "tools.discoveryMode": {
|
|
2830
2839
|
readonly type: "enum";
|
|
2831
|
-
readonly values: readonly ["off", "mcp-only", "all"];
|
|
2832
|
-
readonly default: "
|
|
2840
|
+
readonly values: readonly ["auto", "off", "mcp-only", "all"];
|
|
2841
|
+
readonly default: "auto";
|
|
2833
2842
|
readonly ui: {
|
|
2834
2843
|
readonly tab: "tools";
|
|
2835
2844
|
readonly label: "Tool Discovery";
|
|
2836
|
-
readonly description: "Hide tools behind a search tool to save tokens. 'mcp-only' hides MCP tools; 'all' hides all non-essential built-ins too.";
|
|
2845
|
+
readonly description: "Hide tools behind a search tool to save tokens. 'auto' hides MCP tools once the tool set has more than 40 tools; 'mcp-only' always hides MCP tools; 'all' hides all non-essential built-ins too.";
|
|
2837
2846
|
};
|
|
2838
2847
|
};
|
|
2839
2848
|
readonly "tools.essentialOverride": {
|
|
@@ -132,6 +132,17 @@ export declare class Settings {
|
|
|
132
132
|
* can register independently without overwriting each other.
|
|
133
133
|
*/
|
|
134
134
|
export declare function onAppendOnlyModeChanged(cb: (value: string) => void): () => void;
|
|
135
|
+
/**
|
|
136
|
+
* Subscribe to changes in the Hindsight bank-scoping settings. Lets the
|
|
137
|
+
* Hindsight backend rebuild the active `HindsightSessionState` when the
|
|
138
|
+
* operator switches `hindsight.bankId`, `hindsight.bankIdPrefix`, or
|
|
139
|
+
* `hindsight.scoping` mid-session so subsequent retain/recall calls land in
|
|
140
|
+
* the new bank instead of the one selected at session start.
|
|
141
|
+
*
|
|
142
|
+
* Returns an unsubscribe function. The callback receives no arguments — the
|
|
143
|
+
* caller is expected to re-read the relevant settings via `Settings.get`.
|
|
144
|
+
*/
|
|
145
|
+
export declare function onHindsightScopeChanged(cb: () => void): () => void;
|
|
135
146
|
export declare function isSettingsInitialized(): boolean;
|
|
136
147
|
/**
|
|
137
148
|
* Reset the global singleton for testing.
|
|
@@ -20,9 +20,8 @@ export declare function __computeBunfsPackageRoot(metaDir: string, pathImpl?: ty
|
|
|
20
20
|
* and `__dirname`-relative `readFileSync` asset loads (HTML/CSS bundled next to
|
|
21
21
|
* the entry) resolve exactly as they do under the original Pi runtime — no
|
|
22
22
|
* temp-directory mirroring and no asset copying. An `onLoad` hook scoped to the
|
|
23
|
-
* entry's
|
|
24
|
-
*
|
|
25
|
-
* resolves natively.
|
|
23
|
+
* entry's source graph rewrites only host-resolved compatibility imports in the
|
|
24
|
+
* extension's own source; everything else resolves natively.
|
|
26
25
|
*/
|
|
27
26
|
export declare function loadLegacyPiModule(resolvedPath: string): Promise<unknown>;
|
|
28
27
|
export declare function installLegacyPiSpecifierShim(): void;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Bank ID derivation, project-tag scoping, and first-use
|
|
2
|
+
* Bank ID derivation, project-tag scoping, and first-use bank setup.
|
|
3
3
|
*
|
|
4
4
|
* Three scoping modes (`HindsightConfig.scoping`):
|
|
5
5
|
* - `global` — single shared bank, no per-project filter.
|
|
@@ -11,10 +11,13 @@
|
|
|
11
11
|
* The base bank id is `bankIdPrefix-bankId` (default `omp`). Per-project mode
|
|
12
12
|
* appends `-<project>`; tagged mode leaves the bank untouched and uses tags.
|
|
13
13
|
*
|
|
14
|
-
*
|
|
15
|
-
* banks we've already
|
|
16
|
-
* `createBank` call.
|
|
17
|
-
*
|
|
14
|
+
* Bank existence is idempotent at module level — a banksSet keeps track of
|
|
15
|
+
* banks we've already PUT so each session boundary doesn't fire a fresh
|
|
16
|
+
* `createBank` call. The PUT is idempotent server-side, so re-firing on a hot
|
|
17
|
+
* path would only burn round-trips. Failures are swallowed: missing the
|
|
18
|
+
* mission patch is an optimisation, but the bank ITSELF must exist before
|
|
19
|
+
* mental-model bootstrap or the first retain, otherwise the very first POST
|
|
20
|
+
* lands against a missing bank.
|
|
18
21
|
*/
|
|
19
22
|
import type { HindsightApi } from "./client";
|
|
20
23
|
import type { HindsightConfig } from "./config";
|
|
@@ -46,9 +49,14 @@ export declare function computeBankScope(config: HindsightConfig, directory: str
|
|
|
46
49
|
*/
|
|
47
50
|
export declare function deriveBankId(config: HindsightConfig, directory: string): string;
|
|
48
51
|
/**
|
|
49
|
-
* Ensure a bank
|
|
52
|
+
* Ensure a bank exists, and patch its reflect/retain mission on first use.
|
|
50
53
|
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
54
|
+
* Idempotent: skips the PUT when the bank id is already in the supplied set.
|
|
55
|
+
* The mission body is optional — when `bankMission` is blank we still PUT to
|
|
56
|
+
* make sure the bank itself is created, so mental-model bootstrap and the
|
|
57
|
+
* first retain don't land against a non-existent bank.
|
|
58
|
+
*
|
|
59
|
+
* The set is capped; on overflow we drop the oldest half so it cannot grow
|
|
60
|
+
* unboundedly across long-lived processes.
|
|
53
61
|
*/
|
|
54
|
-
export declare function
|
|
62
|
+
export declare function ensureBankExists(client: HindsightApi, bankId: string, config: HindsightConfig, banksSet: Set<string>): Promise<void>;
|
|
@@ -70,7 +70,7 @@ export declare function resolveSeedsForScope(scope: BankScope, scoping: Hindsigh
|
|
|
70
70
|
* Idempotently create any seed mental models that don't already exist on the
|
|
71
71
|
* bank. Best-effort: a list/create failure does not throw — mental models are
|
|
72
72
|
* an optimization, not a precondition for retain/recall, and we mirror the
|
|
73
|
-
* swallow-on-failure pattern used by `
|
|
73
|
+
* swallow-on-failure pattern used by `ensureBankExists`.
|
|
74
74
|
*
|
|
75
75
|
* Existing models are NEVER modified. See module docstring.
|
|
76
76
|
*/
|
|
@@ -19,12 +19,12 @@ export interface HindsightSessionStateOptions {
|
|
|
19
19
|
recallTagsMatch?: "any" | "all" | "any_strict" | "all_strict";
|
|
20
20
|
config: HindsightConfig;
|
|
21
21
|
session: AgentSession;
|
|
22
|
-
|
|
22
|
+
banksSet: Set<string>;
|
|
23
23
|
lastRetainedTurn?: number;
|
|
24
24
|
hasRecalledForFirstTurn?: boolean;
|
|
25
25
|
/**
|
|
26
26
|
* When set, this entry is a subagent alias that reuses the parent's bank,
|
|
27
|
-
* scope, config, client, and
|
|
27
|
+
* scope, config, client, and banksSet. Aliases skip auto-recall and
|
|
28
28
|
* auto-retain — those run on the parent only — but the recall/retain/reflect
|
|
29
29
|
* tools resolve via the alias so they persist to the same bank as the parent.
|
|
30
30
|
*/
|
|
@@ -60,7 +60,7 @@ export declare class HindsightSessionState {
|
|
|
60
60
|
recallTagsMatch?: "any" | "all" | "any_strict" | "all_strict";
|
|
61
61
|
config: HindsightConfig;
|
|
62
62
|
session: AgentSession;
|
|
63
|
-
|
|
63
|
+
banksSet: Set<string>;
|
|
64
64
|
lastRetainedTurn: number;
|
|
65
65
|
hasRecalledForFirstTurn: boolean;
|
|
66
66
|
lastRecallSnippet?: string;
|
|
@@ -75,6 +75,12 @@ export declare class HindsightSessionState {
|
|
|
75
75
|
*/
|
|
76
76
|
mentalModelsLoadPromise?: Promise<void>;
|
|
77
77
|
unsubscribe?: () => void;
|
|
78
|
+
/**
|
|
79
|
+
* Releases the `onHindsightScopeChanged` subscription that drives live
|
|
80
|
+
* rebuilds when `hindsight.bankId` / `bankIdPrefix` / `scoping` change.
|
|
81
|
+
* Only set on primary states; aliases inherit the parent's subscription.
|
|
82
|
+
*/
|
|
83
|
+
unsubscribeScope?: () => void;
|
|
78
84
|
/** Alias states delegate persistence config to a primary parent state. */
|
|
79
85
|
aliasOf?: HindsightSessionState;
|
|
80
86
|
readonly retainQueue: HindsightRetainQueue;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type TSchema } from "@oh-my-pi/pi-ai";
|
|
2
2
|
import type { SourceMeta } from "../capability/types";
|
|
3
3
|
import type { CustomTool } from "../extensibility/custom-tools/types";
|
|
4
4
|
import type { AuthStorage } from "../session/auth-storage";
|
|
@@ -13,6 +13,17 @@ export declare class AssistantMessageComponent extends Container {
|
|
|
13
13
|
constructor(message?: AssistantMessage, hideThinkingBlock?: boolean, onImageUpdate?: (() => void) | undefined, thinkingRenderers?: readonly AssistantThinkingRenderer[], imageBudget?: ImageBudget | undefined);
|
|
14
14
|
invalidate(): void;
|
|
15
15
|
setHideThinkingBlock(hide: boolean): void;
|
|
16
|
+
isTranscriptBlockFinalized(): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Assistant text/thinking streams in append-only: earlier rendered rows never
|
|
19
|
+
* re-layout, new content only grows the block at the bottom. The transcript
|
|
20
|
+
* reports this so the renderer may commit scrolled-off head rows of a long
|
|
21
|
+
* streamed reply to native scrollback instead of dropping them (see
|
|
22
|
+
* `NativeScrollbackLiveRegion#getNativeScrollbackCommitSafeEnd`). Volatile
|
|
23
|
+
* blocks (tool previews that collapse) intentionally do not implement this.
|
|
24
|
+
*/
|
|
25
|
+
isTranscriptBlockAppendOnly(): boolean;
|
|
26
|
+
markTranscriptBlockFinalized(): void;
|
|
16
27
|
setToolResultImages(toolCallId: string, images: ImageContent[]): void;
|
|
17
28
|
setUsageInfo(usage: Usage): void;
|
|
18
29
|
updateContent(message: AssistantMessage): void;
|
|
@@ -6,8 +6,10 @@ type ConfigurableEditorAction = Extract<AppKeybinding, "app.interrupt" | "app.cl
|
|
|
6
6
|
*/
|
|
7
7
|
export declare class CustomEditor extends Editor {
|
|
8
8
|
#private;
|
|
9
|
+
imageLinks?: readonly (string | undefined)[];
|
|
9
10
|
/** Gradient-highlight the "ultrathink" / "orchestrate" / "workflow" keywords as the user types
|
|
10
|
-
* them, skipping any occurrence inside code spans, fenced blocks, or XML sections.
|
|
11
|
+
* them, skipping any occurrence inside code spans, fenced blocks, or XML sections. Also make
|
|
12
|
+
* pasted image placeholders visually distinct and hyperlink them once their blob file exists. */
|
|
11
13
|
decorateText: (text: string) => string;
|
|
12
14
|
onEscape?: () => void;
|
|
13
15
|
onClear?: () => void;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Container } from "@oh-my-pi/pi-tui";
|
|
2
|
+
/**
|
|
3
|
+
* A persistent error banner pinned above the editor. Unlike the transcript
|
|
4
|
+
* "Error: …" line (which scrolls away as the conversation grows), this stays in
|
|
5
|
+
* the fixed region directly above the input so a turn that ended on a provider
|
|
6
|
+
* error — e.g. Anthropic's "Output blocked by content filtering policy" — cannot
|
|
7
|
+
* be missed. It is cleared when the next turn starts.
|
|
8
|
+
*/
|
|
9
|
+
export declare class ErrorBannerComponent extends Container {
|
|
10
|
+
constructor(message: string);
|
|
11
|
+
}
|
|
@@ -52,6 +52,21 @@ export declare class ToolExecutionComponent extends Container {
|
|
|
52
52
|
details?: any;
|
|
53
53
|
isError?: boolean;
|
|
54
54
|
}, isPartial?: boolean, _toolCallId?: string): void;
|
|
55
|
+
/**
|
|
56
|
+
* Whether this block has reached a terminal state for transcript freezing.
|
|
57
|
+
* Reports `false` while it can still visually change so the
|
|
58
|
+
* {@link TranscriptContainer} keeps it inside the repaintable live region:
|
|
59
|
+
* a foreground tool awaiting its result, or one streaming partial output.
|
|
60
|
+
* A final (non-partial) result, a background-async tool the agent has moved
|
|
61
|
+
* past, or an explicit {@link seal} flips it to `true`.
|
|
62
|
+
*/
|
|
63
|
+
isTranscriptBlockFinalized(): boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Mark the tool terminal even though no result arrived (the turn aborted or
|
|
66
|
+
* abandoned it) and stop animating, so it can freeze and stops pinning the
|
|
67
|
+
* transcript live region.
|
|
68
|
+
*/
|
|
69
|
+
seal(): void;
|
|
55
70
|
/**
|
|
56
71
|
* Stop spinner animation and cleanup resources.
|
|
57
72
|
*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Container } from "@oh-my-pi/pi-tui";
|
|
1
|
+
import { Container, type NativeScrollbackLiveRegion } from "@oh-my-pi/pi-tui";
|
|
2
2
|
/**
|
|
3
3
|
* Transcript container that freezes the rendered output of every block except
|
|
4
4
|
* the bottom-most (live) one on terminals where committed native scrollback is
|
|
@@ -21,10 +21,12 @@ import { Container } from "@oh-my-pi/pi-tui";
|
|
|
21
21
|
* and any drift reconciles safely. On terminals that can rebuild history this
|
|
22
22
|
* freezing is unnecessary, so it renders every block live for full fidelity.
|
|
23
23
|
*/
|
|
24
|
-
export declare class TranscriptContainer extends Container {
|
|
24
|
+
export declare class TranscriptContainer extends Container implements NativeScrollbackLiveRegion {
|
|
25
25
|
#private;
|
|
26
26
|
invalidate(): void;
|
|
27
27
|
clear(): void;
|
|
28
|
+
getNativeScrollbackLiveRegionStart(): number | undefined;
|
|
29
|
+
getNativeScrollbackCommitSafeEnd(): number | undefined;
|
|
28
30
|
/**
|
|
29
31
|
* Retire all frozen snapshots so the next render reflects each block's current
|
|
30
32
|
* state. Call at reconciliation checkpoints (prompt submit) where the whole
|
|
@@ -3,6 +3,6 @@ import { Container } from "@oh-my-pi/pi-tui";
|
|
|
3
3
|
* Component that renders a user message
|
|
4
4
|
*/
|
|
5
5
|
export declare class UserMessageComponent extends Container {
|
|
6
|
-
constructor(text: string, synthetic?: boolean);
|
|
6
|
+
constructor(text: string, synthetic?: boolean, imageLinks?: readonly (string | undefined)[]);
|
|
7
7
|
render(width: number): string[];
|
|
8
8
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ImageContent } from "@oh-my-pi/pi-ai";
|
|
2
|
+
import { type BlobPutResult } from "../session/blob-store";
|
|
3
|
+
type ImageBlobWriter = (data: Buffer, options?: {
|
|
4
|
+
extension?: string;
|
|
5
|
+
}) => Promise<BlobPutResult>;
|
|
6
|
+
type ImageBlobWriterSync = (data: Buffer, options?: {
|
|
7
|
+
extension?: string;
|
|
8
|
+
}) => BlobPutResult;
|
|
9
|
+
export interface ImageReferenceRenderers {
|
|
10
|
+
renderText: (text: string) => string;
|
|
11
|
+
renderReference: (label: string, index: number) => string;
|
|
12
|
+
}
|
|
13
|
+
export declare function renderImageReferences(text: string, renderers: ImageReferenceRenderers): string;
|
|
14
|
+
export declare function imageReferenceHyperlink(label: string, index: number, imageLinks: readonly (string | undefined)[] | undefined, renderLabel: (text: string) => string): string;
|
|
15
|
+
export declare function materializeImageReferenceLinks(images: readonly ImageContent[] | undefined, putBlob: ImageBlobWriter): Promise<(string | undefined)[] | undefined>;
|
|
16
|
+
export declare function materializeImageReferenceLinksSync(images: readonly ImageContent[] | undefined, putBlob: ImageBlobWriterSync): (string | undefined)[] | undefined;
|
|
17
|
+
export {};
|