@oh-my-pi/pi-coding-agent 15.9.0 → 15.9.3
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 +67 -0
- package/dist/types/cli/dry-balance-cli.d.ts +104 -0
- package/dist/types/cli/update-cli.d.ts +15 -1
- package/dist/types/commands/dry-balance.d.ts +31 -0
- package/dist/types/config/append-only-context-mode.d.ts +8 -0
- package/dist/types/config/model-registry.d.ts +5 -0
- package/dist/types/config/models-config-schema.d.ts +18 -0
- package/dist/types/config/settings-schema.d.ts +3 -3
- package/dist/types/config/settings.d.ts +11 -0
- package/dist/types/discovery/helpers.d.ts +1 -0
- package/dist/types/exa/mcp-client.d.ts +2 -1
- 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/json-rpc.d.ts +6 -1
- package/dist/types/mcp/manager.d.ts +1 -1
- package/dist/types/mcp/tool-bridge.d.ts +4 -0
- package/dist/types/mnemopi/state.d.ts +2 -2
- package/dist/types/modes/components/agent-dashboard.d.ts +1 -0
- package/dist/types/modes/components/extensions/extension-dashboard.d.ts +1 -0
- package/dist/types/modes/components/plugin-settings.d.ts +40 -8
- package/dist/types/modes/components/session-selector.d.ts +8 -3
- package/dist/types/modes/components/settings-selector.d.ts +1 -1
- package/dist/types/modes/components/transcript-container.d.ts +3 -2
- package/dist/types/modes/utils/keybinding-matchers.d.ts +4 -0
- package/dist/types/session/agent-session.d.ts +13 -1
- package/dist/types/session/auth-storage.d.ts +2 -2
- package/dist/types/session/history-storage.d.ts +3 -4
- package/dist/types/session/messages.d.ts +1 -0
- package/dist/types/session/session-manager.d.ts +1 -0
- package/dist/types/slash-commands/types.d.ts +17 -4
- package/dist/types/task/types.d.ts +2 -0
- package/dist/types/tiny/text.d.ts +17 -0
- package/dist/types/tools/index.d.ts +16 -0
- package/dist/types/tools/path-utils.d.ts +11 -0
- package/dist/types/web/search/providers/base.d.ts +14 -0
- package/dist/types/web/search/providers/exa.d.ts +9 -0
- package/dist/types/web/search/providers/perplexity.d.ts +2 -2
- package/dist/types/web/search/types.d.ts +2 -1
- package/package.json +9 -9
- package/src/cli/dry-balance-cli.ts +823 -0
- package/src/cli/session-picker.ts +1 -0
- package/src/cli/update-cli.ts +54 -2
- package/src/cli-commands.ts +1 -0
- package/src/commands/completions.ts +1 -1
- package/src/commands/dry-balance.ts +43 -0
- package/src/config/append-only-context-mode.ts +37 -0
- package/src/config/model-registry.ts +6 -0
- package/src/config/models-config-schema.ts +3 -0
- package/src/config/settings-schema.ts +2 -2
- 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/exa/mcp-client.ts +11 -5
- 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 +5 -5
- package/src/internal-urls/omp-protocol.ts +8 -2
- package/src/main.ts +4 -2
- package/src/mcp/json-rpc.ts +8 -0
- package/src/mcp/manager.ts +40 -21
- package/src/mcp/render.ts +3 -0
- package/src/mcp/tool-bridge.ts +10 -2
- package/src/mcp/transports/http.ts +33 -16
- package/src/mnemopi/state.ts +4 -4
- package/src/modes/acp/acp-agent.ts +168 -3
- package/src/modes/components/agent-dashboard.ts +103 -31
- package/src/modes/components/extensions/extension-dashboard.ts +56 -10
- package/src/modes/components/history-search.ts +128 -14
- package/src/modes/components/plugin-settings.ts +270 -36
- package/src/modes/components/session-selector.ts +45 -14
- package/src/modes/components/settings-selector.ts +1 -1
- package/src/modes/components/tips.txt +5 -1
- package/src/modes/components/transcript-container.ts +35 -6
- package/src/modes/components/tree-selector.ts +29 -2
- package/src/modes/controllers/command-controller.ts +4 -3
- package/src/modes/controllers/input-controller.ts +18 -7
- package/src/modes/controllers/selector-controller.ts +30 -19
- package/src/modes/interactive-mode.ts +38 -3
- package/src/modes/setup-wizard/scenes/sign-in.ts +27 -7
- package/src/modes/utils/keybinding-matchers.ts +10 -0
- package/src/prompts/agents/explore.md +1 -0
- package/src/prompts/agents/librarian.md +1 -0
- package/src/prompts/dry-balance-bench.md +8 -0
- package/src/prompts/steering/user-interjection.md +10 -0
- package/src/prompts/system/agent-creation-architect.md +1 -26
- package/src/prompts/system/system-prompt.md +143 -145
- package/src/prompts/system/title-system.md +3 -2
- package/src/prompts/tools/browser.md +29 -29
- package/src/prompts/tools/render-mermaid.md +2 -2
- package/src/sdk.ts +87 -30
- package/src/session/agent-session.ts +96 -14
- package/src/session/auth-storage.ts +4 -0
- package/src/session/history-storage.ts +11 -18
- package/src/session/messages.ts +80 -0
- package/src/session/session-manager.ts +7 -1
- package/src/slash-commands/types.ts +27 -10
- package/src/task/executor.ts +6 -2
- package/src/task/index.ts +8 -7
- package/src/task/types.ts +2 -0
- package/src/tiny/text.ts +112 -1
- package/src/tools/bash.ts +3 -4
- package/src/tools/index.ts +16 -0
- package/src/tools/job.ts +3 -3
- package/src/tools/memory-recall.ts +1 -1
- package/src/tools/memory-reflect.ts +3 -3
- package/src/tools/path-utils.ts +21 -0
- package/src/tools/search.ts +18 -1
- package/src/tools/ssh.ts +26 -10
- package/src/tools/write.ts +14 -2
- package/src/tui/status-line.ts +15 -4
- package/src/utils/file-mentions.ts +7 -107
- package/src/utils/title-generator.ts +66 -38
- package/src/web/search/index.ts +3 -1
- package/src/web/search/provider.ts +1 -1
- package/src/web/search/providers/base.ts +17 -0
- package/src/web/search/providers/exa.ts +111 -7
- package/src/web/search/providers/perplexity.ts +8 -4
- package/src/web/search/types.ts +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,73 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [15.9.3] - 2026-06-05
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- 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.
|
|
10
|
+
|
|
11
|
+
## [15.9.2] - 2026-06-05
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- 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.
|
|
16
|
+
- 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
|
|
17
|
+
- Added `--json` output mode and machine-readable result format to `omp dry-balance` for automated use
|
|
18
|
+
- 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))
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
|
|
22
|
+
- 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.
|
|
23
|
+
- 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)).
|
|
24
|
+
- 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)).
|
|
25
|
+
- 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)).
|
|
26
|
+
- 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)).
|
|
27
|
+
- 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)).
|
|
28
|
+
- 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)).
|
|
29
|
+
- 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)).
|
|
30
|
+
- 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)).
|
|
31
|
+
- 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))
|
|
32
|
+
- 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.
|
|
33
|
+
|
|
34
|
+
## [15.9.1] - 2026-06-04
|
|
35
|
+
|
|
36
|
+
### Added
|
|
37
|
+
|
|
38
|
+
- Added deferred session-title generation so greetings no longer become the session title. A first user message that is only a greeting / acknowledgement / filler ("hi", "thanks", "ok", a bare number, emoji-only, etc.) is now detected deterministically and skips titling entirely — no title model is invoked. Title generation then retries on each subsequent user message while the session stays unnamed, so the title is deduced from the first message that actually describes work. A capable online title model may additionally answer `none` to decline a non-greeting taskless message (normalized to "no title").
|
|
39
|
+
|
|
40
|
+
### Changed
|
|
41
|
+
|
|
42
|
+
- Changed mid-turn user steers to reach the model inside a wire-only interjection envelope, while transcripts and persisted session history keep the user's original text.
|
|
43
|
+
- Changed the system prompt to treat user requests for parallel work as `task` subagent fan-out rather than parallel tool calls.
|
|
44
|
+
- Changed the Agent Control Center's new-agent description field to use the multiline TUI editor, with Enter inserting lines and Ctrl+Enter generating the spec.
|
|
45
|
+
- Changed the Agent Control Center and Extension Control Center to accept Left/Right arrow keys for switching tabs (source / provider), in addition to Tab / Shift+Tab — matching the model and settings selectors, whose `TabBar` already supported arrow navigation.
|
|
46
|
+
- Refreshed the Ctrl+R history search overlay: the selected row now renders as a full-width `selectedBg` highlight bar, matched query tokens are highlighted in the accent color, each result shows a right-aligned relative timestamp, and the panel gained an icon'd accent title plus a two-tone keyhint footer. The selector also gained PageUp/PageDown (via the configurable `tui.select.pageUp`/`pageDown` keybindings) and Home/End navigation.
|
|
47
|
+
- Changed Perplexity API-key web search to return more comprehensive results: `web_search_options.search_context_size` is now `high` (was `medium`) for maximum retrieval grounding, the default `num_search_results` is `20` (was `10`) so twice as many sources are surfaced, and `return_related_questions` is enabled with the response's `related_questions` now parsed into `relatedQuestions` (previously dropped). On an identical query this lifted the result from 10 sources / ~410 output tokens to 20 sources / ~1900 output tokens with a structured, multi-section answer; latency tracks model output length, not context size, so the 60s hard timeout headroom is unchanged.
|
|
48
|
+
|
|
49
|
+
### Fixed
|
|
50
|
+
|
|
51
|
+
- 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.
|
|
52
|
+
- Fixed ACP/RPC stdio startup so protocol frames are no longer consumed as one-shot piped prompt input before the JSON-RPC transport starts.
|
|
53
|
+
- Fixed `omp completions` to await the completion script write before exiting.
|
|
54
|
+
- Fixed `AssistantMessageComponent` exposing its stable-prefix completion API again so streamed assistant messages remain unstable until explicitly completed.
|
|
55
|
+
- Fixed session restoration to ignore transient fallback model switches (such as automatic context-promotion or retry fallback) so resumed or resumed-switch sessions revert to the configured default model unless the last change was a user-selected temporary model
|
|
56
|
+
- Fixed in-session `/resume` to restore both the last user-selected temporary model and persisted plan/goal mode state instead of falling back to the default model with plan mode off.
|
|
57
|
+
- Fixed the `/resume` session picker overflowing short viewports: the visible window was hardcoded to 5 entries (and assumed 3 lines each), but titled sessions render 4 lines, so on a typical-height terminal the picker's header and search box scrolled off the top and the first entry was hidden until you scrolled the terminal up. The visible-entry count is now derived from the live terminal height (budgeting the worst-case 4-line titled entry plus the picker's chrome), so the whole picker fits the viewport and grows on taller terminals.
|
|
58
|
+
- Fixed the Agent Control Center and Extension Control Center dashboards overflowing the terminal: they were mounted inline below the chat transcript, so the combined height exceeded the viewport — the tab bar and controls scrolled off the top into native scrollback, and every state change yanked the view back to the bottom. Both dashboards now render as full-screen overlays sized to the live terminal height (`process.stdout.rows`), re-fit on resize, fill the viewport, and reserve space for the footer keyhints so the controls stay visible.
|
|
59
|
+
- Fixed Ctrl+R history search results to remain globally sorted by prompt recency after merging FTS prefix matches with substring fallback matches.
|
|
60
|
+
- Fixed Exa web search with no stored or environment credential to use the public Exa MCP fallback again, preserving the auth storage → `EXA_API_KEY` → `mcp.exa.ai` resolution order ([#1860](https://github.com/can1357/oh-my-pi/issues/1860)).
|
|
61
|
+
- Fixed ACP plan-mode writes to `local://PLAN.md` so session-local plan artifacts are written to OMP's local artifact root instead of being routed through the editor `writeTextFile` bridge, avoiding Zen's `Internal error` and making the plan readable after creation ([#1863](https://github.com/can1357/oh-my-pi/issues/1863)).
|
|
62
|
+
- Fixed ACP plan mode stranding the agent at plan approval: entering `mode: "plan"` now registers a standing `resolve` handler so the agent's `resolve { action: "apply" }` no longer fails with `No pending action to resolve. Nothing to apply or discard.` The handler validates the plan file, asks the ACP client to confirm via `unstable_createElicitation` when the client supports forms, renames the approved plan to `local://<title>.md`, and exits plan mode so the agent regains write tools for execution ([#1869](https://github.com/can1357/oh-my-pi/issues/1869)).
|
|
63
|
+
|
|
64
|
+
- Fixed `provider.appendOnlyContext: "auto"` staying inactive for Xiaomi Token Plan/SGLang endpoints, preserving prefix-cache hits without forcing append-only mode globally ([#1851](https://github.com/can1357/oh-my-pi/issues/1851)).
|
|
65
|
+
- Fixed `models.yml` compatibility parsing to preserve `compat.cacheControlFormat: "anthropic"` for custom OpenAI-compatible Claude proxies. ([#1845](https://github.com/can1357/oh-my-pi/issues/1845))
|
|
66
|
+
- Fixed the TUI's `Settings → Plugins` panel reporting "No plugins installed" when only marketplace plugins were installed. The panel now merges `PluginManager.list()` with `MarketplaceManager.listInstalledPlugins()` — the same data source the `/plugins list` slash command and `omp plugin list` CLI already used — and tags each row with an `[npm]` / `[marketplace]` kind badge, a scope tag, and a shadow indicator for project-shadowed user installs. Selecting a marketplace row opens a new `MarketplacePluginDetailComponent` whose single `Enabled` toggle calls `MarketplaceManager.setPluginEnabled(pluginId, enabled, scope)`, with read-only metadata (version, install path, installed-at, last-updated, git commit SHA) listed below the toggle. The empty-state now lists both install commands (`omp plugin install <package>` and `omp plugin install <name>@<marketplace>`) ([#1842](https://github.com/can1357/oh-my-pi/issues/1842)).
|
|
67
|
+
- Fixed scoped mnemopi recall in `MnemopiSessionState.collectScopedRecallResults`/`recallResultsScoped` to await the async `Mnemopi.recallEnhanced` so the new auto-derived `queryEmbedding` flows through. Without this, the embedding-enabled mnemopi backend silently kept running FTS-only on every recall. ([#1832](https://github.com/can1357/oh-my-pi/issues/1832))
|
|
68
|
+
- Fixed the SSH tool renderer inlining multiline remote commands into its single-line status header, which produced a malformed cell where the bordered output block opened mid-command. The renderer now drops the command from the header (which keeps only `[host]`) and renders the full command in a framed section above `Output`, mirroring the bash renderer. `renderStatusLine` also flattens any embedded CR/LF in `description`, `meta`, and `title` so no tool can accidentally expand the header into multiple rows ([#1828](https://github.com/can1357/oh-my-pi/issues/1828)).
|
|
69
|
+
- Fixed `tsc --noEmit` against `packages/coding-agent/tsconfig.json` reporting 56 errors under TypeScript 5.x (`builtin-registry.ts` × 46, `agent-session-openai-responses-replay.test.ts` × 10). The repo's own gate (`tsgo` / TypeScript 6.x) already accepted the `() => void` slash-command handlers, but 5.x rejects them because it does not coerce a `void`-returning function value into a `() => T | undefined` slot. The `SlashCommandSpec.handle` / `handleTui` signatures and the test's `createPersistedSession` `populate` callback are now expressed as a union of two function types (one returning a `SlashCommandResult` / target, one returning `void`), so the existing handler bodies typecheck on both compilers ([#1821](https://github.com/can1357/oh-my-pi/issues/1821)).
|
|
70
|
+
- Fixed `omp update` leaving `@oh-my-pi/pi-natives` and the platform-specific `@oh-my-pi/pi-natives-<tag>` leaf at the previous version on `bun install -g` updates, so the next launch loaded a stale `.node` file and aborted at `validateLoadedBindings` with `The .node file on disk is from a different release than this loader`. `omp update` now pins the native addon core and the platform leaf to the same version it installs for `@oh-my-pi/pi-coding-agent` ([#1824](https://github.com/can1357/oh-my-pi/issues/1824)).
|
|
71
|
+
|
|
5
72
|
## [15.9.0] - 2026-06-04
|
|
6
73
|
|
|
7
74
|
### Breaking Changes
|
|
@@ -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 {};
|
|
@@ -40,8 +40,22 @@ export declare function replaceBinaryForUpdate(options: BinaryReplacementOptions
|
|
|
40
40
|
*
|
|
41
41
|
* Together these two flags make `omp update` produce exactly the registry
|
|
42
42
|
* lookup the version check just performed. See #1686.
|
|
43
|
+
*
|
|
44
|
+
* Also pins {@link NATIVES_PACKAGE} and the platform-specific
|
|
45
|
+
* `@oh-my-pi/pi-natives-<tag>` leaf to `expectedVersion`. `bun install -g`
|
|
46
|
+
* does not reliably refresh transitive `optionalDependencies` when the
|
|
47
|
+
* top-level package is the only one bumped, so the native addon and its
|
|
48
|
+
* version sentinel can drift out of sync with the freshly installed
|
|
49
|
+
* `@oh-my-pi/pi-coding-agent` and the loader aborts at
|
|
50
|
+
* `validateLoadedBindings` on the next launch
|
|
51
|
+
* (`The .node file on disk is from a different release than this loader`).
|
|
52
|
+
* Listing the natives explicitly forces bun to replace them in lock-step.
|
|
53
|
+
* The leaf is added only on tags the release pipeline actually publishes
|
|
54
|
+
* ({@link SUPPORTED_NATIVE_TAGS}) so unsupported platforms still fail with
|
|
55
|
+
* the original "no matching version" message instead of `EBADPLATFORM`.
|
|
56
|
+
* See #1824.
|
|
43
57
|
*/
|
|
44
|
-
export declare function buildBunInstallArgs(expectedVersion: string): string[];
|
|
58
|
+
export declare function buildBunInstallArgs(expectedVersion: string, nativeTag?: string): string[];
|
|
45
59
|
/**
|
|
46
60
|
* Run the update command.
|
|
47
61
|
*/
|
|
@@ -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
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Provider metadata needed to resolve append-only context mode. */
|
|
2
|
+
export interface AppendOnlyContextModel {
|
|
3
|
+
provider: string;
|
|
4
|
+
baseUrl: string;
|
|
5
|
+
compat?: object;
|
|
6
|
+
}
|
|
7
|
+
/** Resolves whether append-only context should be active for a model and setting. */
|
|
8
|
+
export declare function shouldEnableAppendOnlyContext(setting: "auto" | "on" | "off" | undefined, model: AppendOnlyContextModel | null | undefined): boolean;
|
|
@@ -72,6 +72,7 @@ export declare const ModelsConfigFile: ConfigFile<{
|
|
|
72
72
|
order?: string[] | undefined;
|
|
73
73
|
} | undefined;
|
|
74
74
|
extraBody?: Record<string, unknown> | undefined;
|
|
75
|
+
cacheControlFormat?: "anthropic" | undefined;
|
|
75
76
|
supportsStrictMode?: boolean | undefined;
|
|
76
77
|
toolStrictMode?: "all_strict" | "none" | undefined;
|
|
77
78
|
} | undefined;
|
|
@@ -103,6 +104,7 @@ export declare const ModelsConfigFile: ConfigFile<{
|
|
|
103
104
|
premiumMultiplier?: number | undefined;
|
|
104
105
|
contextWindow?: number | undefined;
|
|
105
106
|
maxTokens?: number | undefined;
|
|
107
|
+
omitMaxOutputTokens?: boolean | undefined;
|
|
106
108
|
headers?: Record<string, string> | undefined;
|
|
107
109
|
compat?: {
|
|
108
110
|
supportsStore?: boolean | undefined;
|
|
@@ -139,6 +141,7 @@ export declare const ModelsConfigFile: ConfigFile<{
|
|
|
139
141
|
order?: string[] | undefined;
|
|
140
142
|
} | undefined;
|
|
141
143
|
extraBody?: Record<string, unknown> | undefined;
|
|
144
|
+
cacheControlFormat?: "anthropic" | undefined;
|
|
142
145
|
supportsStrictMode?: boolean | undefined;
|
|
143
146
|
toolStrictMode?: "all_strict" | "none" | undefined;
|
|
144
147
|
} | undefined;
|
|
@@ -164,6 +167,7 @@ export declare const ModelsConfigFile: ConfigFile<{
|
|
|
164
167
|
premiumMultiplier?: number | undefined;
|
|
165
168
|
contextWindow?: number | undefined;
|
|
166
169
|
maxTokens?: number | undefined;
|
|
170
|
+
omitMaxOutputTokens?: boolean | undefined;
|
|
167
171
|
headers?: Record<string, string> | undefined;
|
|
168
172
|
compat?: {
|
|
169
173
|
supportsStore?: boolean | undefined;
|
|
@@ -200,6 +204,7 @@ export declare const ModelsConfigFile: ConfigFile<{
|
|
|
200
204
|
order?: string[] | undefined;
|
|
201
205
|
} | undefined;
|
|
202
206
|
extraBody?: Record<string, unknown> | undefined;
|
|
207
|
+
cacheControlFormat?: "anthropic" | undefined;
|
|
203
208
|
supportsStrictMode?: boolean | undefined;
|
|
204
209
|
toolStrictMode?: "all_strict" | "none" | undefined;
|
|
205
210
|
} | undefined;
|
|
@@ -47,6 +47,9 @@ export declare const OpenAICompatSchema: z.ZodObject<{
|
|
|
47
47
|
order: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
48
48
|
}, z.core.$strip>>;
|
|
49
49
|
extraBody: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
50
|
+
cacheControlFormat: z.ZodOptional<z.ZodEnum<{
|
|
51
|
+
anthropic: "anthropic";
|
|
52
|
+
}>>;
|
|
50
53
|
supportsStrictMode: z.ZodOptional<z.ZodBoolean>;
|
|
51
54
|
toolStrictMode: z.ZodOptional<z.ZodEnum<{
|
|
52
55
|
all_strict: "all_strict";
|
|
@@ -106,6 +109,7 @@ export declare const ModelOverrideSchema: z.ZodObject<{
|
|
|
106
109
|
premiumMultiplier: z.ZodOptional<z.ZodNumber>;
|
|
107
110
|
contextWindow: z.ZodOptional<z.ZodNumber>;
|
|
108
111
|
maxTokens: z.ZodOptional<z.ZodNumber>;
|
|
112
|
+
omitMaxOutputTokens: z.ZodOptional<z.ZodBoolean>;
|
|
109
113
|
headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
110
114
|
compat: z.ZodOptional<z.ZodObject<{
|
|
111
115
|
supportsStore: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -155,6 +159,9 @@ export declare const ModelOverrideSchema: z.ZodObject<{
|
|
|
155
159
|
order: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
156
160
|
}, z.core.$strip>>;
|
|
157
161
|
extraBody: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
162
|
+
cacheControlFormat: z.ZodOptional<z.ZodEnum<{
|
|
163
|
+
anthropic: "anthropic";
|
|
164
|
+
}>>;
|
|
158
165
|
supportsStrictMode: z.ZodOptional<z.ZodBoolean>;
|
|
159
166
|
toolStrictMode: z.ZodOptional<z.ZodEnum<{
|
|
160
167
|
all_strict: "all_strict";
|
|
@@ -242,6 +249,9 @@ export declare const ModelsConfigSchema: z.ZodObject<{
|
|
|
242
249
|
order: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
243
250
|
}, z.core.$strip>>;
|
|
244
251
|
extraBody: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
252
|
+
cacheControlFormat: z.ZodOptional<z.ZodEnum<{
|
|
253
|
+
anthropic: "anthropic";
|
|
254
|
+
}>>;
|
|
245
255
|
supportsStrictMode: z.ZodOptional<z.ZodBoolean>;
|
|
246
256
|
toolStrictMode: z.ZodOptional<z.ZodEnum<{
|
|
247
257
|
all_strict: "all_strict";
|
|
@@ -327,6 +337,7 @@ export declare const ModelsConfigSchema: z.ZodObject<{
|
|
|
327
337
|
premiumMultiplier: z.ZodOptional<z.ZodNumber>;
|
|
328
338
|
contextWindow: z.ZodOptional<z.ZodNumber>;
|
|
329
339
|
maxTokens: z.ZodOptional<z.ZodNumber>;
|
|
340
|
+
omitMaxOutputTokens: z.ZodOptional<z.ZodBoolean>;
|
|
330
341
|
headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
331
342
|
compat: z.ZodOptional<z.ZodObject<{
|
|
332
343
|
supportsStore: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -376,6 +387,9 @@ export declare const ModelsConfigSchema: z.ZodObject<{
|
|
|
376
387
|
order: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
377
388
|
}, z.core.$strip>>;
|
|
378
389
|
extraBody: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
390
|
+
cacheControlFormat: z.ZodOptional<z.ZodEnum<{
|
|
391
|
+
anthropic: "anthropic";
|
|
392
|
+
}>>;
|
|
379
393
|
supportsStrictMode: z.ZodOptional<z.ZodBoolean>;
|
|
380
394
|
toolStrictMode: z.ZodOptional<z.ZodEnum<{
|
|
381
395
|
all_strict: "all_strict";
|
|
@@ -437,6 +451,7 @@ export declare const ModelsConfigSchema: z.ZodObject<{
|
|
|
437
451
|
premiumMultiplier: z.ZodOptional<z.ZodNumber>;
|
|
438
452
|
contextWindow: z.ZodOptional<z.ZodNumber>;
|
|
439
453
|
maxTokens: z.ZodOptional<z.ZodNumber>;
|
|
454
|
+
omitMaxOutputTokens: z.ZodOptional<z.ZodBoolean>;
|
|
440
455
|
headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
441
456
|
compat: z.ZodOptional<z.ZodObject<{
|
|
442
457
|
supportsStore: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -486,6 +501,9 @@ export declare const ModelsConfigSchema: z.ZodObject<{
|
|
|
486
501
|
order: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
487
502
|
}, z.core.$strip>>;
|
|
488
503
|
extraBody: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
504
|
+
cacheControlFormat: z.ZodOptional<z.ZodEnum<{
|
|
505
|
+
anthropic: "anthropic";
|
|
506
|
+
}>>;
|
|
489
507
|
supportsStrictMode: z.ZodOptional<z.ZodBoolean>;
|
|
490
508
|
toolStrictMode: z.ZodOptional<z.ZodEnum<{
|
|
491
509
|
all_strict: "all_strict";
|
|
@@ -3331,7 +3331,7 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
3331
3331
|
}, {
|
|
3332
3332
|
readonly value: "exa";
|
|
3333
3333
|
readonly label: "Exa";
|
|
3334
|
-
readonly description: "
|
|
3334
|
+
readonly description: "Uses Exa API when EXA_API_KEY is set; falls back to Exa MCP";
|
|
3335
3335
|
}, {
|
|
3336
3336
|
readonly value: "parallel";
|
|
3337
3337
|
readonly label: "Parallel";
|
|
@@ -3668,11 +3668,11 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
3668
3668
|
readonly ui: {
|
|
3669
3669
|
readonly tab: "providers";
|
|
3670
3670
|
readonly label: "Append-Only Context";
|
|
3671
|
-
readonly description: "Cache system prompt + tool specs and keep an append-only message log so provider prefix caches (DeepSeek, Anthropic) hit at maximum rate. Auto enables for
|
|
3671
|
+
readonly description: "Cache system prompt + tool specs and keep an append-only message log so provider prefix caches (DeepSeek, Xiaomi/SGLang, Anthropic) hit at maximum rate. Auto enables for known prefix-cache providers.";
|
|
3672
3672
|
readonly options: readonly [{
|
|
3673
3673
|
readonly value: "auto";
|
|
3674
3674
|
readonly label: "Auto";
|
|
3675
|
-
readonly description: "Enable for
|
|
3675
|
+
readonly description: "Enable for known prefix-cache providers (recommended)";
|
|
3676
3676
|
}, {
|
|
3677
3677
|
readonly value: "on";
|
|
3678
3678
|
readonly label: "On";
|
|
@@ -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.
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { TSchema } from "@oh-my-pi/pi-ai";
|
|
2
2
|
import type { CustomTool, CustomToolResult } from "../extensibility/custom-tools/types";
|
|
3
|
+
import { type CallMcpOptions } from "../mcp/json-rpc";
|
|
3
4
|
import type { ExaRenderDetails, ExaSearchResponse, MCPTool, MCPToolWrapperConfig } from "./types";
|
|
4
5
|
/** Find EXA_API_KEY from Bun.env or .env files */
|
|
5
6
|
export declare function findApiKey(): string | null;
|
|
@@ -8,7 +9,7 @@ export declare function fetchExaTools(apiKey: string | null, toolNames: string[]
|
|
|
8
9
|
/** Fetch available tools from Websets MCP */
|
|
9
10
|
export declare function fetchWebsetsTools(apiKey: string): Promise<MCPTool[]>;
|
|
10
11
|
/** Call a tool on Exa MCP (simplified: toolName as first arg for easier use) */
|
|
11
|
-
export declare function callExaTool(toolName: string, args: Record<string, unknown>, apiKey: string | null): Promise<unknown>;
|
|
12
|
+
export declare function callExaTool(toolName: string, args: Record<string, unknown>, apiKey: string | null, options?: CallMcpOptions): Promise<unknown>;
|
|
12
13
|
/** Call a tool on Websets MCP */
|
|
13
14
|
export declare function callWebsetsTool(apiKey: string, toolName: string, args: Record<string, unknown>): Promise<unknown>;
|
|
14
15
|
/** Format search results for LLM */
|
|
@@ -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;
|
|
@@ -11,12 +11,17 @@ export interface JsonRpcResponse<T = unknown> {
|
|
|
11
11
|
data?: unknown;
|
|
12
12
|
};
|
|
13
13
|
}
|
|
14
|
+
/** Options controlling a single MCP JSON-RPC HTTP request. */
|
|
15
|
+
export interface CallMcpOptions {
|
|
16
|
+
signal?: AbortSignal;
|
|
17
|
+
}
|
|
14
18
|
/**
|
|
15
19
|
* Call an MCP server with JSON-RPC 2.0 over HTTPS.
|
|
16
20
|
*
|
|
17
21
|
* @param url - Full MCP server URL (including any query parameters)
|
|
18
22
|
* @param method - JSON-RPC method name (e.g., "tools/list", "tools/call")
|
|
19
23
|
* @param params - Method parameters
|
|
24
|
+
* @param options - Optional transport controls such as cancellation.
|
|
20
25
|
* @returns Parsed JSON-RPC response
|
|
21
26
|
*/
|
|
22
|
-
export declare function callMCP<T = unknown>(url: string, method: string, params?: Record<string, unknown
|
|
27
|
+
export declare function callMCP<T = unknown>(url: string, method: string, params?: Record<string, unknown>, options?: CallMcpOptions): Promise<JsonRpcResponse<T>>;
|
|
@@ -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";
|
|
@@ -53,6 +53,8 @@ export declare class MCPTool implements CustomTool<TSchema, MCPToolDetails> {
|
|
|
53
53
|
readonly mcpToolName: string;
|
|
54
54
|
/** Server name */
|
|
55
55
|
readonly mcpServerName: string;
|
|
56
|
+
/** Render completed MCP calls with the result header replacing the pending call header. */
|
|
57
|
+
readonly mergeCallAndResult = true;
|
|
56
58
|
/** Create MCPTool instances for all tools from an MCP server connection */
|
|
57
59
|
static fromTools(connection: MCPServerConnection, tools: MCPToolDefinition[], reconnect?: MCPReconnect): MCPTool[];
|
|
58
60
|
constructor(connection: MCPServerConnection, tool: MCPToolDefinition, reconnect?: MCPReconnect | undefined);
|
|
@@ -77,6 +79,8 @@ export declare class DeferredMCPTool implements CustomTool<TSchema, MCPToolDetai
|
|
|
77
79
|
readonly mcpToolName: string;
|
|
78
80
|
/** Server name */
|
|
79
81
|
readonly mcpServerName: string;
|
|
82
|
+
/** Render completed MCP calls with the result header replacing the pending call header. */
|
|
83
|
+
readonly mergeCallAndResult = true;
|
|
80
84
|
/** Create DeferredMCPTool instances for all tools from an MCP server */
|
|
81
85
|
static fromTools(serverName: string, tools: MCPToolDefinition[], getConnection: () => Promise<MCPServerConnection>, source?: SourceMeta, reconnect?: MCPReconnect): DeferredMCPTool[];
|
|
82
86
|
constructor(serverName: string, tool: MCPToolDefinition, getConnection: () => Promise<MCPServerConnection>, source?: SourceMeta, reconnect?: MCPReconnect | undefined);
|
|
@@ -48,8 +48,8 @@ export declare class MnemopiSessionState {
|
|
|
48
48
|
getScopedRetainTarget(): MnemopiScopedMemory;
|
|
49
49
|
editScopedMemory(op: MnemopiMemoryEditOperation, id: string, options?: MnemopiMemoryEditOptions): MnemopiMemoryEditResult;
|
|
50
50
|
formatScopedRecallWithIds(results: readonly RecallResult[]): string;
|
|
51
|
-
collectScopedRecallResults(query: string): RecallResult[]
|
|
52
|
-
recallResultsScoped(query: string): RecallResult[]
|
|
51
|
+
collectScopedRecallResults(query: string): Promise<RecallResult[]>;
|
|
52
|
+
recallResultsScoped(query: string): Promise<RecallResult[]>;
|
|
53
53
|
formatScopedRecallContext(results: readonly RecallResult[], format?: "bullet" | "json"): string | undefined;
|
|
54
54
|
formatContextScoped(results: readonly RecallResult[], format?: "bullet" | "json"): string;
|
|
55
55
|
rememberInScope(memory: MnemopiRememberInput, options?: MnemopiRememberOptions): string | undefined;
|
|
@@ -16,6 +16,7 @@ export declare class AgentDashboard extends Container {
|
|
|
16
16
|
onRequestRender?: () => void;
|
|
17
17
|
private constructor();
|
|
18
18
|
static create(cwd: string, settings?: Settings | null, terminalHeight?: number, modelContext?: AgentDashboardModelContext): Promise<AgentDashboard>;
|
|
19
|
+
render(width: number): string[];
|
|
19
20
|
handleInput(data: string): void;
|
|
20
21
|
}
|
|
21
22
|
export {};
|
|
@@ -22,5 +22,6 @@ export declare class ExtensionDashboard extends Container {
|
|
|
22
22
|
onRequestRender?: () => void;
|
|
23
23
|
private constructor();
|
|
24
24
|
static create(cwd: string, settings?: Settings | null, terminalHeight?: number): Promise<ExtensionDashboard>;
|
|
25
|
+
render(width: number): string[];
|
|
25
26
|
handleInput(data: string): void;
|
|
26
27
|
}
|