pi-namespace-patch 0.85.1 → 0.86.1-namespace.1
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 +110 -0
- package/README.md +26 -705
- package/dist/bundle/chunks/anthropic-messages-MYU5ZMRF.js +6 -0
- package/dist/bundle/chunks/azure-openai-responses-HUSQ3GP2.js +2 -0
- package/dist/bundle/chunks/bedrock-converse-stream.js +47 -38
- package/dist/bundle/chunks/chunk-4YJERF5N.js +2 -0
- package/dist/bundle/chunks/chunk-A3JYRWB6.js +2 -0
- package/dist/bundle/chunks/chunk-CVPNLAPW.js +1562 -0
- package/dist/bundle/chunks/chunk-DTD7JQ7Y.js +42 -0
- package/dist/bundle/chunks/chunk-FUXEF6JQ.js +44 -0
- package/dist/bundle/chunks/{chunk-IDDQWTHI.js → chunk-RCZIEVGO.js} +10 -1
- package/dist/bundle/chunks/chunk-S7SZN6Z3.js +2 -0
- package/dist/bundle/chunks/chunk-WIUZI2CJ.js +11 -0
- package/dist/bundle/chunks/github-copilot.js +1 -1
- package/dist/bundle/chunks/google-generative-ai-IMS5EK2Y.js +2 -0
- package/dist/bundle/chunks/google-vertex-O4YJEQUW.js +2 -0
- package/dist/bundle/chunks/jiti-loader-C3NU2SDH.js +21 -0
- package/dist/bundle/chunks/jiti-static-loader-E6ANQD5T.js +2 -0
- package/dist/bundle/chunks/meta.js +2 -0
- package/dist/bundle/chunks/mistral-conversations-NOSQHBEY.js +5 -0
- package/dist/bundle/chunks/{node-KG362ECQ.js → node-O3RIBJRH.js} +1 -1
- package/dist/bundle/chunks/openai-codex-responses-QDSOTBBO.js +10 -0
- package/dist/bundle/chunks/openai-completions-CYGM3XXP.js +7 -0
- package/dist/bundle/chunks/openai-responses-HWEUZ6WZ.js +2 -0
- package/dist/bundle/chunks/{pi-messages-PML4SPVJ.js → pi-messages-GFKBWJHZ.js} +1 -1
- package/dist/bundle/chunks/virtual-modules-R7YYFUSE.js +2 -0
- package/dist/bundle/cli-runtime.js +3 -0
- package/dist/bundle/cli.js +4 -2
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +1 -0
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/session-picker.d.ts +1 -1
- package/dist/cli/session-picker.d.ts.map +1 -1
- package/dist/cli/session-picker.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -1
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session.d.ts +56 -6
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +294 -157
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/bug-report-upload.d.ts +12 -0
- package/dist/core/bug-report-upload.d.ts.map +1 -0
- package/dist/core/bug-report-upload.js +22 -0
- package/dist/core/bug-report-upload.js.map +1 -0
- package/dist/core/bug-report.d.ts +176 -0
- package/dist/core/bug-report.d.ts.map +1 -0
- package/dist/core/bug-report.js +292 -0
- package/dist/core/bug-report.js.map +1 -0
- package/dist/core/cache-stats.d.ts.map +1 -1
- package/dist/core/cache-stats.js +12 -1
- package/dist/core/cache-stats.js.map +1 -1
- package/dist/core/cache-warmer.d.ts +102 -0
- package/dist/core/cache-warmer.d.ts.map +1 -0
- package/dist/core/cache-warmer.js +342 -0
- package/dist/core/cache-warmer.js.map +1 -0
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js +2 -2
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +2 -2
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +11 -12
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/crash-log.d.ts +22 -0
- package/dist/core/crash-log.d.ts.map +1 -0
- package/dist/core/crash-log.js +71 -0
- package/dist/core/crash-log.js.map +1 -0
- package/dist/core/experimental.d.ts +0 -4
- package/dist/core/experimental.d.ts.map +1 -1
- package/dist/core/experimental.js +0 -4
- package/dist/core/experimental.js.map +1 -1
- package/dist/core/extensions/index.d.ts +1 -1
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/jiti-loader.d.ts +2 -0
- package/dist/core/extensions/jiti-loader.d.ts.map +1 -0
- package/dist/core/extensions/jiti-loader.js +4 -0
- package/dist/core/extensions/jiti-loader.js.map +1 -0
- package/dist/core/extensions/jiti-static-loader.d.ts +2 -0
- package/dist/core/extensions/jiti-static-loader.d.ts.map +1 -0
- package/dist/core/extensions/jiti-static-loader.js +4 -0
- package/dist/core/extensions/jiti-static-loader.js.map +1 -0
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +38 -51
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +10 -7
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +85 -67
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +60 -50
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/extensions/virtual-modules.d.ts +3 -0
- package/dist/core/extensions/virtual-modules.d.ts.map +1 -0
- package/dist/core/extensions/virtual-modules.js +38 -0
- package/dist/core/extensions/virtual-modules.js.map +1 -0
- package/dist/core/extensions/wrapper.d.ts.map +1 -1
- package/dist/core/extensions/wrapper.js +1 -20
- package/dist/core/extensions/wrapper.js.map +1 -1
- package/dist/core/index.d.ts +2 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/keybindings.d.ts +1 -1
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +1 -1
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/messages.d.ts.map +1 -1
- package/dist/core/messages.js +1 -0
- package/dist/core/messages.js.map +1 -1
- package/dist/core/model-config.d.ts +101 -20
- package/dist/core/model-config.d.ts.map +1 -1
- package/dist/core/model-config.js +25 -18
- package/dist/core/model-config.js.map +1 -1
- package/dist/core/model-registry.d.ts +5 -1
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +8 -0
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +2 -1
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +5 -3
- package/dist/core/model-runtime.js.map +1 -1
- package/dist/core/provider-composer.d.ts +3 -2
- package/dist/core/provider-composer.d.ts.map +1 -1
- package/dist/core/provider-composer.js +2 -0
- package/dist/core/provider-composer.js.map +1 -1
- package/dist/core/radius.d.ts +3 -0
- package/dist/core/radius.d.ts.map +1 -1
- package/dist/core/radius.js +6 -0
- package/dist/core/radius.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +60 -38
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-export.d.ts +6 -2
- package/dist/core/session-export.d.ts.map +1 -1
- package/dist/core/session-export.js +14 -13
- package/dist/core/session-export.js.map +1 -1
- package/dist/core/session-manager.d.ts +29 -6
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +159 -96
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +20 -4
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +43 -7
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +1 -0
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/system-prompt.d.ts +49 -6
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +121 -92
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tools/bash.d.ts +2 -1
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +10 -4
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +1 -2
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +1 -2
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/renderers/bash.d.ts.map +1 -1
- package/dist/core/tools/renderers/bash.js +9 -1
- package/dist/core/tools/renderers/bash.js.map +1 -1
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js +1 -2
- package/dist/core/tools/write.js.map +1 -1
- package/dist/core/usage-totals.d.ts +1 -1
- package/dist/core/usage-totals.d.ts.map +1 -1
- package/dist/core/usage-totals.js +5 -1
- package/dist/core/usage-totals.js.map +1 -1
- package/dist/extensions/llama/client.d.ts +2 -0
- package/dist/extensions/llama/client.d.ts.map +1 -1
- package/dist/extensions/llama/client.js +7 -3
- package/dist/extensions/llama/client.js.map +1 -1
- package/dist/extensions/llama/provider.d.ts.map +1 -1
- package/dist/extensions/llama/provider.js +20 -5
- package/dist/extensions/llama/provider.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +13 -9
- package/dist/main.js.map +1 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +2 -2
- package/dist/migrations.js.map +1 -1
- package/dist/modes/interactive/bug-report.d.ts +16 -0
- package/dist/modes/interactive/bug-report.d.ts.map +1 -0
- package/dist/modes/interactive/bug-report.js +206 -0
- package/dist/modes/interactive/bug-report.js.map +1 -0
- package/dist/modes/interactive/chat-viewport.d.ts.map +1 -1
- package/dist/modes/interactive/chat-viewport.js +1 -1
- package/dist/modes/interactive/chat-viewport.js.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.js +12 -5
- package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.js +12 -5
- package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/custom-editor.d.ts +3 -3
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-editor.js.map +1 -1
- package/dist/modes/interactive/components/extension-editor.d.ts +4 -1
- package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-editor.js +7 -2
- package/dist/modes/interactive/components/extension-editor.js.map +1 -1
- package/dist/modes/interactive/components/extension-input.d.ts +2 -0
- package/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-input.js +6 -0
- package/dist/modes/interactive/components/extension-input.js.map +1 -1
- package/dist/modes/interactive/components/extension-selector.d.ts +1 -0
- package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-selector.js +4 -0
- package/dist/modes/interactive/components/extension-selector.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +4 -1
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/session-selector.d.ts +5 -5
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector.js +74 -48
- package/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +3 -1
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +11 -0
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.js +11 -4
- package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
- package/dist/modes/interactive/components/status-indicator.d.ts +2 -2
- package/dist/modes/interactive/components/status-indicator.d.ts.map +1 -1
- package/dist/modes/interactive/components/status-indicator.js +7 -7
- package/dist/modes/interactive/components/status-indicator.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +18 -9
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-selector.js +2 -0
- package/dist/modes/interactive/components/tree-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +15 -2
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +227 -84
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/session-share.d.ts +2 -0
- package/dist/modes/interactive/session-share.d.ts.map +1 -1
- package/dist/modes/interactive/session-share.js +8 -4
- package/dist/modes/interactive/session-share.js.map +1 -1
- package/dist/modes/interactive/tui-renderer.d.ts.map +1 -1
- package/dist/modes/interactive/tui-renderer.js +2 -2
- package/dist/modes/interactive/tui-renderer.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +2 -2
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/utils/clipboard-command.d.ts +7 -0
- package/dist/utils/clipboard-command.d.ts.map +1 -0
- package/dist/utils/clipboard-command.js +45 -0
- package/dist/utils/clipboard-command.js.map +1 -0
- package/dist/utils/clipboard-image.d.ts.map +1 -1
- package/dist/utils/clipboard-image.js +53 -81
- package/dist/utils/clipboard-image.js.map +1 -1
- package/dist/utils/clipboard.d.ts.map +1 -1
- package/dist/utils/clipboard.js +111 -121
- package/dist/utils/clipboard.js.map +1 -1
- package/dist/utils/version-check.d.ts.map +1 -1
- package/dist/utils/version-check.js +11 -4
- package/dist/utils/version-check.js.map +1 -1
- package/dist/utils/wsl.d.ts +3 -0
- package/dist/utils/wsl.d.ts.map +1 -0
- package/dist/utils/wsl.js +15 -0
- package/dist/utils/wsl.js.map +1 -0
- package/dist/utils/zip.d.ts +7 -0
- package/dist/utils/zip.d.ts.map +1 -0
- package/dist/utils/zip.js +60 -0
- package/dist/utils/zip.js.map +1 -0
- package/docs/compaction.md +39 -13
- package/docs/custom-provider.md +22 -13
- package/docs/development.md +4 -4
- package/docs/docs.json +4 -0
- package/docs/environment-variables.md +1 -0
- package/docs/extensions.md +57 -43
- package/docs/json.md +4 -4
- package/docs/models.md +33 -2
- package/docs/providers.md +10 -2
- package/docs/sdk.md +4 -2
- package/docs/security.md +1 -1
- package/docs/session-format.md +82 -40
- package/docs/sessions.md +27 -0
- package/docs/settings.md +60 -1
- package/docs/termux.md +0 -1
- package/docs/tui.md +2 -2
- package/docs/usage.md +1 -0
- package/examples/extensions/README.md +0 -1
- package/examples/extensions/custom-provider-anthropic/index.ts +18 -12
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/index.ts +2 -2
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/prompt-customizer.ts +19 -67
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/npm-shrinkwrap.json +435 -762
- package/package.json +17 -23
- package/dist/bundle/chunks/anthropic-messages-VWZZOSJQ.js +0 -6
- package/dist/bundle/chunks/azure-openai-responses-BJLAM6CD.js +0 -2
- package/dist/bundle/chunks/chunk-AXIIZGTV.js +0 -2
- package/dist/bundle/chunks/chunk-CLNPYIDP.js +0 -42
- package/dist/bundle/chunks/chunk-GMWCTUPB.js +0 -2
- package/dist/bundle/chunks/chunk-JJ2YFCJF.js +0 -1547
- package/dist/bundle/chunks/chunk-OUXLLA64.js +0 -11
- package/dist/bundle/chunks/chunk-U6ZMQKGD.js +0 -50
- package/dist/bundle/chunks/chunk-UAQELI3K.js +0 -2
- package/dist/bundle/chunks/google-generative-ai-Q2K7FBDI.js +0 -2
- package/dist/bundle/chunks/google-vertex-7UJBF4S7.js +0 -2
- package/dist/bundle/chunks/mistral-conversations-4M6BZBX6.js +0 -5
- package/dist/bundle/chunks/openai-codex-responses-R6VYZTVY.js +0 -10
- package/dist/bundle/chunks/openai-completions-EKZT2IH2.js +0 -7
- package/dist/bundle/chunks/openai-responses-TFDINO6W.js +0 -2
- package/dist/utils/clipboard-native.d.ts +0 -11
- package/dist/utils/clipboard-native.d.ts.map +0 -1
- package/dist/utils/clipboard-native.js +0 -20
- package/dist/utils/clipboard-native.js.map +0 -1
- package/examples/extensions/kimi-deferred-tools.ts +0 -61
|
@@ -6,6 +6,7 @@ import * as crypto from "node:crypto";
|
|
|
6
6
|
import * as fs from "node:fs";
|
|
7
7
|
import * as os from "node:os";
|
|
8
8
|
import * as path from "node:path";
|
|
9
|
+
import { isRetryableAssistantError, } from "@earendil-works/pi-ai/compat";
|
|
9
10
|
import * as TuiLayouts from "@earendil-works/pi-tui";
|
|
10
11
|
import { CombinedAutocompleteProvider, Container, fuzzyFilter, getCapabilities, hyperlink, Markdown, matchesKey, Spacer, setCapabilityOverrides, setKeybindings, Text, TruncatedText, TuiAltScreen, TuiMainScreen, visibleWidth, } from "@earendil-works/pi-tui";
|
|
11
12
|
import chalk from "chalk";
|
|
@@ -14,6 +15,8 @@ import { APP_NAME, APP_TITLE, CONFIG_DIR_NAME, getAgentDir, getAuthPath, getDebu
|
|
|
14
15
|
import { parseSkillBlock } from "../../core/agent-session.js";
|
|
15
16
|
import { SessionImportFileNotFoundError } from "../../core/agent-session-runtime.js";
|
|
16
17
|
import { CACHE_TTL_MS, collectCacheMisses, computeCacheWaste, detectCacheMiss, } from "../../core/cache-stats.js";
|
|
18
|
+
import { formatCacheWarmingStatus, formatCacheWarmingUsage } from "../../core/cache-warmer.js";
|
|
19
|
+
import { recordCrash, takeUnnotifiedCrash } from "../../core/crash-log.js";
|
|
17
20
|
import { DEFAULT_THINKING_LEVEL, THINKING_LEVEL_OPTIONS } from "../../core/defaults.js";
|
|
18
21
|
import { FooterDataProvider } from "../../core/footer-data-provider.js";
|
|
19
22
|
import { configureHttpDispatcher, formatHttpIdleTimeoutMs } from "../../core/http-dispatcher.js";
|
|
@@ -23,7 +26,7 @@ import { defaultModelPerProvider, findExactModelReferenceMatch, resolveModelScop
|
|
|
23
26
|
import { CredentialSynchronizationError } from "../../core/model-runtime.js";
|
|
24
27
|
import { DefaultPackageManager } from "../../core/package-manager.js";
|
|
25
28
|
import { formatMissingSessionCwdPrompt, MissingSessionCwdError } from "../../core/session-cwd.js";
|
|
26
|
-
import { SessionManager, sessionEntryToContextMessages } from "../../core/session-manager.js";
|
|
29
|
+
import { SessionManager, sessionEntryToContextMessages, } from "../../core/session-manager.js";
|
|
27
30
|
import { BUILTIN_SLASH_COMMANDS } from "../../core/slash-commands.js";
|
|
28
31
|
import { isInstallTelemetryEnabled } from "../../core/telemetry.js";
|
|
29
32
|
import { withBuiltInRenderers } from "../../core/tools/renderers/index.js";
|
|
@@ -39,6 +42,7 @@ import { killTrackedDetachedChildren } from "../../utils/shell.js";
|
|
|
39
42
|
import { loadAllHighlightLanguages } from "../../utils/syntax-highlight.js";
|
|
40
43
|
import { ensureTool } from "../../utils/tools-manager.js";
|
|
41
44
|
import { checkForNewPiVersion } from "../../utils/version-check.js";
|
|
45
|
+
import { reportBug } from "./bug-report.js";
|
|
42
46
|
import { createChatViewport } from "./chat-viewport.js";
|
|
43
47
|
import { ArminComponent } from "./components/armin.js";
|
|
44
48
|
import { AssistantMessageComponent } from "./components/assistant-message.js";
|
|
@@ -106,6 +110,9 @@ function isCustomSessionEntry(item) {
|
|
|
106
110
|
function isCompactionCostNotice(item) {
|
|
107
111
|
return "type" in item && item.type === "compaction_cost";
|
|
108
112
|
}
|
|
113
|
+
function isUsageSessionEntry(item) {
|
|
114
|
+
return "type" in item && item.type === "usage";
|
|
115
|
+
}
|
|
109
116
|
const DEAD_TERMINAL_ERROR_CODES = new Set(["EIO", "EPIPE", "ENOTCONN"]);
|
|
110
117
|
function isDeadTerminalError(error) {
|
|
111
118
|
if (!error || typeof error !== "object" || !("code" in error)) {
|
|
@@ -267,6 +274,8 @@ export class InteractiveMode {
|
|
|
267
274
|
compactionQueuedMessages = [];
|
|
268
275
|
// Shutdown state
|
|
269
276
|
shutdownRequested = false;
|
|
277
|
+
/** The `/bug` hint is shown at most once per session so error output stays readable. */
|
|
278
|
+
bugReportHintShown = false;
|
|
270
279
|
// Extension UI state
|
|
271
280
|
extensionSelector = undefined;
|
|
272
281
|
extensionInput = undefined;
|
|
@@ -322,6 +331,7 @@ export class InteractiveMode {
|
|
|
322
331
|
tuiMode,
|
|
323
332
|
showHardwareCursor: this.settingsManager.getShowHardwareCursor(),
|
|
324
333
|
logDirectory: getAgentDir(),
|
|
334
|
+
terminal: options.terminal,
|
|
325
335
|
onRightClickPaste: this.onRightClickPaste,
|
|
326
336
|
fullscreenCopyOnSelect: this.settingsManager.getFullscreenCopyOnSelect(),
|
|
327
337
|
});
|
|
@@ -819,6 +829,11 @@ export class InteractiveMode {
|
|
|
819
829
|
if (modelFallbackMessage) {
|
|
820
830
|
this.showWarning(modelFallbackMessage);
|
|
821
831
|
}
|
|
832
|
+
const crash = takeUnnotifiedCrash();
|
|
833
|
+
if (crash) {
|
|
834
|
+
const when = new Date(crash.timestamp).toLocaleString();
|
|
835
|
+
this.showWarning(`${APP_NAME} crashed on ${when} (${crash.message}). Run /bug to report it; the crash details are attached automatically.`);
|
|
836
|
+
}
|
|
822
837
|
void this.maybeWarnAboutAnthropicSubscriptionAuth();
|
|
823
838
|
// Process initial messages
|
|
824
839
|
if (initialMessage) {
|
|
@@ -1535,10 +1550,45 @@ export class InteractiveMode {
|
|
|
1535
1550
|
async handleFatalRuntimeError(prefix, error) {
|
|
1536
1551
|
const message = error instanceof Error ? error.message : String(error);
|
|
1537
1552
|
this.showError(`${prefix}: ${message}`);
|
|
1553
|
+
if (this.recordCrash("fatal_error", error)) {
|
|
1554
|
+
this.chatContainer.addChild(new Text(theme.fg("muted", this.crashReportInstructions()), this.outputPad, 0));
|
|
1555
|
+
}
|
|
1538
1556
|
stopThemeWatcher();
|
|
1539
1557
|
this.stop("transcript");
|
|
1540
1558
|
process.exit(1);
|
|
1541
1559
|
}
|
|
1560
|
+
/** Persist a crash so the next start can point the user at `/bug`. Returns false when nothing was written. */
|
|
1561
|
+
recordCrash(kind, error) {
|
|
1562
|
+
try {
|
|
1563
|
+
return (recordCrash({
|
|
1564
|
+
kind,
|
|
1565
|
+
error,
|
|
1566
|
+
sessionFile: this.session.sessionFile,
|
|
1567
|
+
cwd: this.session.sessionManager.getCwd(),
|
|
1568
|
+
}) !== undefined);
|
|
1569
|
+
}
|
|
1570
|
+
catch {
|
|
1571
|
+
return false;
|
|
1572
|
+
}
|
|
1573
|
+
}
|
|
1574
|
+
crashReportInstructions() {
|
|
1575
|
+
const resume = this.session.sessionFile ? `run \`${APP_NAME} -r\` to resume the session, then` : "start pi and";
|
|
1576
|
+
return `To report this crash: ${resume} run /bug. The crash details are attached automatically.`;
|
|
1577
|
+
}
|
|
1578
|
+
suggestBugReport() {
|
|
1579
|
+
if (this.bugReportHintShown)
|
|
1580
|
+
return;
|
|
1581
|
+
this.bugReportHintShown = true;
|
|
1582
|
+
this.chatContainer.addChild(new Text(theme.fg("muted", `If this looks like a ${APP_NAME} bug, /bug sends a report to the developers.`), this.outputPad, 0));
|
|
1583
|
+
this.ui.requestRender();
|
|
1584
|
+
}
|
|
1585
|
+
maybeSuggestBugReport(message) {
|
|
1586
|
+
if (message.stopReason !== "error" || isRetryableAssistantError(message))
|
|
1587
|
+
return;
|
|
1588
|
+
if (/\b(?:abort(?:ed)?|cancel(?:l?ed)?)\b/i.test(message.errorMessage ?? ""))
|
|
1589
|
+
return;
|
|
1590
|
+
this.suggestBugReport();
|
|
1591
|
+
}
|
|
1542
1592
|
renderCurrentSessionState() {
|
|
1543
1593
|
this.loadedResourcesContainer.clear();
|
|
1544
1594
|
this.chatContainer.clear();
|
|
@@ -1640,7 +1690,7 @@ export class InteractiveMode {
|
|
|
1640
1690
|
this.activeWorkingIndicatorEmbedded = false;
|
|
1641
1691
|
this.statusContainer.clear();
|
|
1642
1692
|
this.setEditorWorkingStatusIndicator(undefined);
|
|
1643
|
-
if (
|
|
1693
|
+
if (this.setEditorWorkingStatusIndicator(indicator)) {
|
|
1644
1694
|
this.activeWorkingIndicatorEmbedded = true;
|
|
1645
1695
|
return;
|
|
1646
1696
|
}
|
|
@@ -1651,7 +1701,7 @@ export class InteractiveMode {
|
|
|
1651
1701
|
return;
|
|
1652
1702
|
}
|
|
1653
1703
|
const clearedIndicator = this.activeStatusIndicator;
|
|
1654
|
-
const clearedIndicatorWasEmbedded =
|
|
1704
|
+
const clearedIndicatorWasEmbedded = this.activeWorkingIndicatorEmbedded;
|
|
1655
1705
|
clearedIndicator?.dispose();
|
|
1656
1706
|
this.activeStatusIndicator = undefined;
|
|
1657
1707
|
this.activeWorkingIndicatorEmbedded = false;
|
|
@@ -2140,7 +2190,7 @@ export class InteractiveMode {
|
|
|
2140
2190
|
this.editor = this.defaultEditor;
|
|
2141
2191
|
}
|
|
2142
2192
|
this.editorContainer.addChild(this.editor);
|
|
2143
|
-
if (this.activeStatusIndicator
|
|
2193
|
+
if (this.activeStatusIndicator) {
|
|
2144
2194
|
this.statusContainer.clear();
|
|
2145
2195
|
this.activeWorkingIndicatorEmbedded = this.setEditorWorkingStatusIndicator(this.activeStatusIndicator);
|
|
2146
2196
|
if (!this.activeWorkingIndicatorEmbedded) {
|
|
@@ -2411,6 +2461,12 @@ export class InteractiveMode {
|
|
|
2411
2461
|
this.editor.setText("");
|
|
2412
2462
|
return;
|
|
2413
2463
|
}
|
|
2464
|
+
if (text === "/bug" || text.startsWith("/bug ")) {
|
|
2465
|
+
const hint = text.slice("/bug".length).trim();
|
|
2466
|
+
this.editor.setText("");
|
|
2467
|
+
await this.handleBugCommand(hint ? hint : undefined);
|
|
2468
|
+
return;
|
|
2469
|
+
}
|
|
2414
2470
|
if (text === "/copy") {
|
|
2415
2471
|
await this.handleCopyCommand();
|
|
2416
2472
|
this.editor.setText("");
|
|
@@ -2602,6 +2658,10 @@ export class InteractiveMode {
|
|
|
2602
2658
|
this.addCustomEntryToChat(event.entry);
|
|
2603
2659
|
this.ui.requestRender();
|
|
2604
2660
|
}
|
|
2661
|
+
else if (event.entry.type === "usage" && event.entry.kind === "cache_warm") {
|
|
2662
|
+
this.addCacheWarmingUsage(event.entry);
|
|
2663
|
+
this.ui.requestRender();
|
|
2664
|
+
}
|
|
2605
2665
|
break;
|
|
2606
2666
|
case "session_info_changed":
|
|
2607
2667
|
this.updateTerminalTitle();
|
|
@@ -2682,13 +2742,14 @@ export class InteractiveMode {
|
|
|
2682
2742
|
});
|
|
2683
2743
|
}
|
|
2684
2744
|
this.pendingTools.clear();
|
|
2745
|
+
this.maybeSuggestBugReport(this.streamingMessage);
|
|
2685
2746
|
}
|
|
2686
2747
|
else {
|
|
2687
2748
|
// Args are now complete - trigger diff computation for edit tools
|
|
2688
2749
|
for (const [, component] of this.pendingTools.entries()) {
|
|
2689
2750
|
component.setArgsComplete();
|
|
2690
2751
|
}
|
|
2691
|
-
this.
|
|
2752
|
+
this.maybeShowThinkingDropNotice(this.streamingMessage);
|
|
2692
2753
|
this.maybeShowCacheMissNotice(this.streamingMessage);
|
|
2693
2754
|
}
|
|
2694
2755
|
this.streamingComponent = undefined;
|
|
@@ -2955,6 +3016,8 @@ export class InteractiveMode {
|
|
|
2955
3016
|
this.chatContainer.addChild(component);
|
|
2956
3017
|
break;
|
|
2957
3018
|
}
|
|
3019
|
+
case "system":
|
|
3020
|
+
break;
|
|
2958
3021
|
case "user": {
|
|
2959
3022
|
const textContent = this.getUserMessageText(message);
|
|
2960
3023
|
if (textContent) {
|
|
@@ -3001,8 +3064,8 @@ export class InteractiveMode {
|
|
|
3001
3064
|
renderSessionItems(items, options = {}) {
|
|
3002
3065
|
this.pendingTools.clear();
|
|
3003
3066
|
const renderedPendingTools = new Map();
|
|
3004
|
-
// Cache
|
|
3005
|
-
//
|
|
3067
|
+
// Cache misses are not persisted, unlike successful cache-warming usage.
|
|
3068
|
+
// Re-derive them and inject them after the assistant messages that paid for them.
|
|
3006
3069
|
const cacheMisses = this.settingsManager.getShowCacheMissNotices()
|
|
3007
3070
|
? collectCacheMisses(this.sessionManager.getEntries(), this.session.modelRuntime)
|
|
3008
3071
|
: new Map();
|
|
@@ -3015,6 +3078,10 @@ export class InteractiveMode {
|
|
|
3015
3078
|
this.addCustomEntryToChat(item);
|
|
3016
3079
|
continue;
|
|
3017
3080
|
}
|
|
3081
|
+
if (isUsageSessionEntry(item)) {
|
|
3082
|
+
this.addCacheWarmingUsage(item);
|
|
3083
|
+
continue;
|
|
3084
|
+
}
|
|
3018
3085
|
if (isCompactionCostNotice(item)) {
|
|
3019
3086
|
this.addCompactionCostNotice(item);
|
|
3020
3087
|
continue;
|
|
@@ -3052,7 +3119,6 @@ export class InteractiveMode {
|
|
|
3052
3119
|
}
|
|
3053
3120
|
}
|
|
3054
3121
|
if (message.stopReason !== "aborted" && message.stopReason !== "error") {
|
|
3055
|
-
this.maybeShowAssistantDiagnostics(message);
|
|
3056
3122
|
const miss = cacheMisses.get(message);
|
|
3057
3123
|
if (miss)
|
|
3058
3124
|
this.addCacheMissNotice(miss);
|
|
@@ -3084,7 +3150,7 @@ export class InteractiveMode {
|
|
|
3084
3150
|
*/
|
|
3085
3151
|
renderSessionEntries(entries, options = {}) {
|
|
3086
3152
|
const items = entries.flatMap((entry) => {
|
|
3087
|
-
if (entry.type === "custom") {
|
|
3153
|
+
if (entry.type === "custom" || (entry.type === "usage" && entry.kind === "cache_warm")) {
|
|
3088
3154
|
return [entry];
|
|
3089
3155
|
}
|
|
3090
3156
|
const messages = sessionEntryToContextMessages(entry);
|
|
@@ -3095,6 +3161,12 @@ export class InteractiveMode {
|
|
|
3095
3161
|
});
|
|
3096
3162
|
this.renderSessionItems(items, options);
|
|
3097
3163
|
}
|
|
3164
|
+
addCacheWarmingUsage(entry) {
|
|
3165
|
+
if (!this.settingsManager.getShowCacheMissNotices())
|
|
3166
|
+
return;
|
|
3167
|
+
this.chatContainer.addChild(new Spacer(1));
|
|
3168
|
+
this.chatContainer.addChild(new Text(theme.fg("dim", formatCacheWarmingUsage(entry)), 1, 0));
|
|
3169
|
+
}
|
|
3098
3170
|
/**
|
|
3099
3171
|
* Render billing usage for a compaction or branch summary. The notice is derived
|
|
3100
3172
|
* from persisted summary usage and is not stored as a separate session entry.
|
|
@@ -3109,31 +3181,42 @@ export class InteractiveMode {
|
|
|
3109
3181
|
this.chatContainer.addChild(new Spacer(1));
|
|
3110
3182
|
this.chatContainer.addChild(new Text(theme.fg("warning", `${label}: ${formatTokens(tokens)} tokens billed${cost}`), 1, 0));
|
|
3111
3183
|
}
|
|
3112
|
-
|
|
3113
|
-
|
|
3114
|
-
return;
|
|
3184
|
+
static countDroppedThinkingBlocks(message) {
|
|
3185
|
+
let count = 0;
|
|
3115
3186
|
for (const diagnostic of message.diagnostics ?? []) {
|
|
3116
3187
|
if (diagnostic.type !== "anthropic_input_transformations")
|
|
3117
3188
|
continue;
|
|
3118
3189
|
const transformations = diagnostic.details?.transformations;
|
|
3119
3190
|
if (!Array.isArray(transformations))
|
|
3120
3191
|
continue;
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
const details = transformation;
|
|
3125
|
-
if (details.type !== "thinking_dropped")
|
|
3126
|
-
return [];
|
|
3127
|
-
const reason = typeof details.reason === "string" ? details.reason : "unknown reason";
|
|
3128
|
-
const location = typeof details.path === "string" ? ` at ${details.path}` : "";
|
|
3129
|
-
return [`${reason}${location}`];
|
|
3130
|
-
});
|
|
3131
|
-
if (dropped.length === 0)
|
|
3132
|
-
continue;
|
|
3133
|
-
const noun = dropped.length === 1 ? "thinking block" : `${dropped.length} thinking blocks`;
|
|
3134
|
-
this.chatContainer.addChild(new Spacer(1));
|
|
3135
|
-
this.chatContainer.addChild(new Text(theme.fg("warning", `Anthropic dropped ${noun}: ${dropped.join("; ")}`), 1, 0));
|
|
3192
|
+
count += transformations.filter((transformation) => typeof transformation === "object" &&
|
|
3193
|
+
transformation !== null &&
|
|
3194
|
+
transformation.type === "thinking_dropped").length;
|
|
3136
3195
|
}
|
|
3196
|
+
return count;
|
|
3197
|
+
}
|
|
3198
|
+
maybeShowThinkingDropNotice(message) {
|
|
3199
|
+
if (!this.settingsManager.getShowCacheMissNotices())
|
|
3200
|
+
return;
|
|
3201
|
+
const droppedCount = InteractiveMode.countDroppedThinkingBlocks(message);
|
|
3202
|
+
if (droppedCount === 0)
|
|
3203
|
+
return;
|
|
3204
|
+
let previousDroppedCount = 0;
|
|
3205
|
+
// message_end reaches the UI before the current message is persisted,
|
|
3206
|
+
// so the branch's last assistant message is the previous response.
|
|
3207
|
+
const branch = this.sessionManager.getBranch();
|
|
3208
|
+
for (let i = branch.length - 1; i >= 0; i--) {
|
|
3209
|
+
const entry = branch[i];
|
|
3210
|
+
if (entry.type === "message" && entry.message.role === "assistant") {
|
|
3211
|
+
previousDroppedCount = InteractiveMode.countDroppedThinkingBlocks(entry.message);
|
|
3212
|
+
break;
|
|
3213
|
+
}
|
|
3214
|
+
}
|
|
3215
|
+
if (droppedCount <= previousDroppedCount)
|
|
3216
|
+
return;
|
|
3217
|
+
const noun = droppedCount === 1 ? "thinking block" : "thinking blocks";
|
|
3218
|
+
this.chatContainer.addChild(new Spacer(1));
|
|
3219
|
+
this.chatContainer.addChild(new Text(theme.fg("warning", `Anthropic dropped ${droppedCount} ${noun} (details in session)`), 1, 0));
|
|
3137
3220
|
}
|
|
3138
3221
|
/**
|
|
3139
3222
|
* Show a transcript notice when a completed assistant message paid for a
|
|
@@ -3301,6 +3384,9 @@ export class InteractiveMode {
|
|
|
3301
3384
|
catch { }
|
|
3302
3385
|
console.error(`${APP_NAME} exiting due to uncaughtException:`);
|
|
3303
3386
|
console.error(error);
|
|
3387
|
+
if (this.recordCrash("uncaught_exception", error)) {
|
|
3388
|
+
console.error(`\n${this.crashReportInstructions()}`);
|
|
3389
|
+
}
|
|
3304
3390
|
process.exit(1);
|
|
3305
3391
|
}
|
|
3306
3392
|
/**
|
|
@@ -3432,9 +3518,7 @@ export class InteractiveMode {
|
|
|
3432
3518
|
const level = this.session.thinkingLevel || "off";
|
|
3433
3519
|
this.editor.borderColor = theme.getThinkingBorderColor(level);
|
|
3434
3520
|
}
|
|
3435
|
-
|
|
3436
|
-
this.activeStatusIndicator.invalidate();
|
|
3437
|
-
}
|
|
3521
|
+
this.activeStatusIndicator?.invalidate();
|
|
3438
3522
|
this.ui.requestRender();
|
|
3439
3523
|
}
|
|
3440
3524
|
cycleThinkingLevel() {
|
|
@@ -3628,7 +3712,7 @@ export class InteractiveMode {
|
|
|
3628
3712
|
if (allQueued.length === 0) {
|
|
3629
3713
|
this.updatePendingMessagesDisplay();
|
|
3630
3714
|
if (options?.abort) {
|
|
3631
|
-
this.
|
|
3715
|
+
void this.session.abort();
|
|
3632
3716
|
}
|
|
3633
3717
|
return 0;
|
|
3634
3718
|
}
|
|
@@ -3638,7 +3722,7 @@ export class InteractiveMode {
|
|
|
3638
3722
|
this.editor.setText(combinedText);
|
|
3639
3723
|
this.updatePendingMessagesDisplay();
|
|
3640
3724
|
if (options?.abort) {
|
|
3641
|
-
this.
|
|
3725
|
+
void this.session.abort();
|
|
3642
3726
|
}
|
|
3643
3727
|
return allQueued.length;
|
|
3644
3728
|
}
|
|
@@ -3792,6 +3876,7 @@ export class InteractiveMode {
|
|
|
3792
3876
|
followUpMode: this.session.followUpMode,
|
|
3793
3877
|
transport: this.settingsManager.getTransport(),
|
|
3794
3878
|
httpIdleTimeoutMs: this.settingsManager.getHttpIdleTimeoutMs(),
|
|
3879
|
+
cacheWarmingMode: this.settingsManager.getCacheWarmingMode(),
|
|
3795
3880
|
thinkingLevel: this.settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL,
|
|
3796
3881
|
availableThinkingLevels: [...THINKING_LEVEL_OPTIONS],
|
|
3797
3882
|
modelThinkingLevels: this.settingsManager.getAllModelThinkingLevels(),
|
|
@@ -3864,6 +3949,10 @@ export class InteractiveMode {
|
|
|
3864
3949
|
configureHttpDispatcher(timeoutMs);
|
|
3865
3950
|
this.showStatus(`HTTP idle timeout: ${formatHttpIdleTimeoutMs(timeoutMs)}`);
|
|
3866
3951
|
},
|
|
3952
|
+
onCacheWarmingModeChange: (mode) => {
|
|
3953
|
+
this.session.setCacheWarmingMode(mode);
|
|
3954
|
+
this.showStatus(`Cache warming: ${mode}`);
|
|
3955
|
+
},
|
|
3867
3956
|
onModelThinkingLevelChange: (provider, modelId, level) => {
|
|
3868
3957
|
this.settingsManager.setModelThinkingLevel(provider, modelId, level);
|
|
3869
3958
|
// If the override is for the current model, apply it to the session too
|
|
@@ -4415,6 +4504,11 @@ export class InteractiveMode {
|
|
|
4415
4504
|
this.restoreQueuedMessagesToEditor();
|
|
4416
4505
|
await this.session.abort();
|
|
4417
4506
|
}
|
|
4507
|
+
// Recheck after the dialogs and streaming abort, before replacing another operation's UI.
|
|
4508
|
+
if (this.session.isCompacting) {
|
|
4509
|
+
this.showError("Wait for the current compaction or tree navigation to finish before navigating the session tree.");
|
|
4510
|
+
return;
|
|
4511
|
+
}
|
|
4418
4512
|
// Set up escape handler and status indicator if summarizing
|
|
4419
4513
|
let showingSummaryIndicator = false;
|
|
4420
4514
|
const originalOnEscape = this.defaultEditor.onEscape;
|
|
@@ -4485,9 +4579,9 @@ export class InteractiveMode {
|
|
|
4485
4579
|
}
|
|
4486
4580
|
showSessionSelector() {
|
|
4487
4581
|
this.showSelector((done) => {
|
|
4488
|
-
const selector = new SessionSelectorComponent((onProgress) => SessionManager.list(this.sessionManager.getCwd(), this.sessionManager.getSessionDir(), onProgress), (onProgress) => this.sessionManager.usesDefaultSessionDir()
|
|
4489
|
-
? SessionManager.listAll(onProgress)
|
|
4490
|
-
: SessionManager.listAll(this.sessionManager.getSessionDir(), onProgress), async (sessionPath) => {
|
|
4582
|
+
const selector = new SessionSelectorComponent((onProgress, signal) => SessionManager.list(this.sessionManager.getCwd(), this.sessionManager.getSessionDir(), onProgress, signal), (onProgress, signal) => this.sessionManager.usesDefaultSessionDir()
|
|
4583
|
+
? SessionManager.listAll(onProgress, signal)
|
|
4584
|
+
: SessionManager.listAll(this.sessionManager.getSessionDir(), onProgress, signal), async (sessionPath) => {
|
|
4491
4585
|
done();
|
|
4492
4586
|
await this.handleResumeSession(sessionPath);
|
|
4493
4587
|
}, () => {
|
|
@@ -4750,67 +4844,89 @@ export class InteractiveMode {
|
|
|
4750
4844
|
}
|
|
4751
4845
|
async completeProviderAuthentication(providerId, providerName, authType, previousModel) {
|
|
4752
4846
|
const actionLabel = authType === "oauth" ? `Logged in to ${providerName}` : `Saved API key for ${providerName}`;
|
|
4753
|
-
|
|
4754
|
-
|
|
4755
|
-
|
|
4756
|
-
|
|
4757
|
-
|
|
4758
|
-
|
|
4759
|
-
|
|
4760
|
-
|
|
4761
|
-
|
|
4762
|
-
|
|
4763
|
-
|
|
4764
|
-
|
|
4765
|
-
|
|
4766
|
-
|
|
4767
|
-
|
|
4768
|
-
|
|
4769
|
-
|
|
4770
|
-
|
|
4771
|
-
|
|
4772
|
-
|
|
4847
|
+
const session = this.session;
|
|
4848
|
+
// Dynamic catalogs may be empty until the first authenticated network refresh.
|
|
4849
|
+
const deferSelection = isUnknownModel(previousModel) &&
|
|
4850
|
+
hasDefaultModelProvider(providerId) &&
|
|
4851
|
+
!session.modelRuntime
|
|
4852
|
+
.getAvailableSnapshot()
|
|
4853
|
+
.some((model) => model.provider === providerId && model.id === defaultModelPerProvider[providerId]);
|
|
4854
|
+
const finishAuthentication = async () => {
|
|
4855
|
+
let selectedModel;
|
|
4856
|
+
let selectionError;
|
|
4857
|
+
if (isUnknownModel(previousModel)) {
|
|
4858
|
+
const availableModels = this.session.modelRuntime.getAvailableSnapshot();
|
|
4859
|
+
const providerModels = availableModels.filter((model) => model.provider === providerId);
|
|
4860
|
+
// Matches LLAMA_PROVIDER_ID from extensions/llama/provider.ts; kept inline to avoid coupling interactive mode to the built-in extension.
|
|
4861
|
+
if (providerId === "llama.cpp") {
|
|
4862
|
+
selectionError = llamaCppPostLoginGuidance(actionLabel, providerModels.length);
|
|
4863
|
+
}
|
|
4864
|
+
else if (!hasDefaultModelProvider(providerId)) {
|
|
4865
|
+
selectionError = `${actionLabel}, but no default model is configured for provider "${providerId}". Use /model to select a model.`;
|
|
4866
|
+
}
|
|
4867
|
+
else if (providerModels.length === 0) {
|
|
4868
|
+
selectionError = `${actionLabel}, but no models are available for that provider. Use /model to select a model.`;
|
|
4773
4869
|
}
|
|
4774
4870
|
else {
|
|
4775
|
-
|
|
4776
|
-
|
|
4871
|
+
const defaultModelId = defaultModelPerProvider[providerId];
|
|
4872
|
+
// Radius catalogs vary by account; prefer balanced, then use catalog order.
|
|
4873
|
+
selectedModel =
|
|
4874
|
+
providerModels.find((model) => model.id === defaultModelId) ??
|
|
4875
|
+
(providerId === "radius" ? providerModels[0] : undefined);
|
|
4876
|
+
if (!selectedModel) {
|
|
4877
|
+
selectionError = `${actionLabel}, but its default model "${defaultModelId}" is not available. Use /model to select a model.`;
|
|
4777
4878
|
}
|
|
4778
|
-
|
|
4779
|
-
|
|
4780
|
-
|
|
4781
|
-
|
|
4879
|
+
else {
|
|
4880
|
+
try {
|
|
4881
|
+
await this.session.setModel(selectedModel, { persist: true });
|
|
4882
|
+
}
|
|
4883
|
+
catch (error) {
|
|
4884
|
+
selectedModel = undefined;
|
|
4885
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
4886
|
+
selectionError = `${actionLabel}, but selecting its default model failed: ${errorMessage}. Use /model to select a model.`;
|
|
4887
|
+
}
|
|
4782
4888
|
}
|
|
4783
4889
|
}
|
|
4784
4890
|
}
|
|
4785
|
-
|
|
4786
|
-
|
|
4787
|
-
|
|
4788
|
-
|
|
4789
|
-
|
|
4790
|
-
|
|
4791
|
-
|
|
4792
|
-
this.checkDaxnutsEasterEgg(selectedModel);
|
|
4793
|
-
}
|
|
4794
|
-
else {
|
|
4795
|
-
this.showStatus(`${actionLabel}. Credentials saved to ${getAuthPath()}`);
|
|
4796
|
-
if (selectionError) {
|
|
4797
|
-
this.showError(selectionError);
|
|
4891
|
+
await this.updateAvailableProviderCount();
|
|
4892
|
+
this.footer.invalidate();
|
|
4893
|
+
this.updateEditorBorderColor();
|
|
4894
|
+
if (selectedModel) {
|
|
4895
|
+
this.showStatus(`${actionLabel}. Selected ${selectedModel.id}. Credentials saved to ${getAuthPath()}`);
|
|
4896
|
+
void this.maybeWarnAboutAnthropicSubscriptionAuth(selectedModel);
|
|
4897
|
+
this.checkDaxnutsEasterEgg(selectedModel);
|
|
4798
4898
|
}
|
|
4799
4899
|
else {
|
|
4800
|
-
|
|
4900
|
+
this.showStatus(`${actionLabel}. Credentials saved to ${getAuthPath()}`);
|
|
4901
|
+
if (selectionError) {
|
|
4902
|
+
this.showError(selectionError);
|
|
4903
|
+
}
|
|
4904
|
+
else {
|
|
4905
|
+
void this.maybeWarnAboutAnthropicSubscriptionAuth();
|
|
4906
|
+
}
|
|
4801
4907
|
}
|
|
4908
|
+
};
|
|
4909
|
+
if (deferSelection) {
|
|
4910
|
+
this.showStatus(`${actionLabel}. Credentials saved to ${getAuthPath()}. Refreshing model catalog…`);
|
|
4911
|
+
}
|
|
4912
|
+
else {
|
|
4913
|
+
await finishAuthentication();
|
|
4802
4914
|
}
|
|
4803
4915
|
const controller = new AbortController();
|
|
4804
4916
|
const timeout = setTimeout(() => controller.abort(), 15_000);
|
|
4805
|
-
void
|
|
4917
|
+
void session.modelRuntime
|
|
4806
4918
|
.refresh({ providers: [providerId], signal: controller.signal })
|
|
4807
|
-
.then((result) => {
|
|
4919
|
+
.then(async (result) => {
|
|
4808
4920
|
if (result.aborted) {
|
|
4809
4921
|
this.showWarning(`${actionLabel}, but its model catalog refresh timed out; using cached models.`);
|
|
4810
4922
|
}
|
|
4811
4923
|
else if (result.errors.size > 0) {
|
|
4812
4924
|
this.showWarning(`${actionLabel}, but its model catalog could not be refreshed; using cached models.`);
|
|
4813
4925
|
}
|
|
4926
|
+
// Do not replace a model or session selected while the refresh was running.
|
|
4927
|
+
if (deferSelection && this.session === session && session.model === previousModel) {
|
|
4928
|
+
await finishAuthentication();
|
|
4929
|
+
}
|
|
4814
4930
|
this.updateAvailableProviderCount();
|
|
4815
4931
|
this.footer.invalidate();
|
|
4816
4932
|
this.ui.requestRender();
|
|
@@ -5152,6 +5268,17 @@ export class InteractiveMode {
|
|
|
5152
5268
|
showError: (message) => this.showError(message),
|
|
5153
5269
|
});
|
|
5154
5270
|
}
|
|
5271
|
+
async handleBugCommand(hint) {
|
|
5272
|
+
await reportBug({
|
|
5273
|
+
session: this.session,
|
|
5274
|
+
ui: this.ui,
|
|
5275
|
+
editorContainer: this.editorContainer,
|
|
5276
|
+
editor: this.editor,
|
|
5277
|
+
keybindings: this.keybindings,
|
|
5278
|
+
showStatus: (message) => this.showStatus(message),
|
|
5279
|
+
showError: (message) => this.showError(message),
|
|
5280
|
+
}, hint);
|
|
5281
|
+
}
|
|
5155
5282
|
async handleCopyCommand(options = {}) {
|
|
5156
5283
|
if (options.preferSelection &&
|
|
5157
5284
|
this.ui instanceof TuiAltScreen &&
|
|
@@ -5237,6 +5364,15 @@ export class InteractiveMode {
|
|
|
5237
5364
|
}
|
|
5238
5365
|
info += `${theme.fg("dim", "Output:")} ${stats.tokens.output.toLocaleString()}\n`;
|
|
5239
5366
|
info += `${theme.fg("dim", "Total:")} ${stats.tokens.total.toLocaleString()}\n`;
|
|
5367
|
+
const cacheWarmingStatus = this.session.cacheWarmingStatus;
|
|
5368
|
+
info += `\n${theme.bold("Cache Warming")}\n`;
|
|
5369
|
+
info += `${theme.fg("dim", "Mode:")} ${this.settingsManager.getCacheWarmingMode()}\n`;
|
|
5370
|
+
info += `${theme.fg("dim", "Status:")} ${cacheWarmingStatus ? formatCacheWarmingStatus(cacheWarmingStatus) : "Inactive (cache warming unavailable)"}\n`;
|
|
5371
|
+
const decision = cacheWarmingStatus?.decision;
|
|
5372
|
+
if (decision?.economicsAvailable) {
|
|
5373
|
+
info += `${theme.fg("dim", "Cache miss penalty:")} $${decision.missCost.toFixed(3)}\n`;
|
|
5374
|
+
info += `${theme.fg("dim", "Refresh cost:")} $${decision.warmCost.toFixed(3)}\n`;
|
|
5375
|
+
}
|
|
5240
5376
|
if (stats.cost > 0 || cacheWaste.missedTokens > 0) {
|
|
5241
5377
|
info += `\n${theme.bold("Cost")}\n`;
|
|
5242
5378
|
info += `${theme.fg("dim", "Total:")} $${stats.cost.toFixed(3)}`;
|
|
@@ -5367,7 +5503,7 @@ export class InteractiveMode {
|
|
|
5367
5503
|
| \`${expandTools}\` | Toggle tool output expansion |
|
|
5368
5504
|
| \`${toggleThinking}\` | Toggle thinking block visibility |
|
|
5369
5505
|
| \`${externalEditor}\` | Edit message in external editor |
|
|
5370
|
-
| \`${copyMessage}\` | Copy last assistant message |
|
|
5506
|
+
| \`${copyMessage}\` | Copy selection or last assistant message |
|
|
5371
5507
|
| \`${followUp}\` | Queue follow-up message |
|
|
5372
5508
|
| \`${dequeue}\` | Restore queued messages |
|
|
5373
5509
|
| \`${pasteImage}\` | Paste image or text from clipboard |
|
|
@@ -5463,12 +5599,19 @@ export class InteractiveMode {
|
|
|
5463
5599
|
async handleBashCommand(command, excludeFromContext = false) {
|
|
5464
5600
|
const extensionRunner = this.session.extensionRunner;
|
|
5465
5601
|
// Emit user_bash event to let extensions intercept
|
|
5466
|
-
|
|
5467
|
-
|
|
5468
|
-
|
|
5469
|
-
|
|
5470
|
-
|
|
5471
|
-
|
|
5602
|
+
let eventResult;
|
|
5603
|
+
try {
|
|
5604
|
+
eventResult = await extensionRunner.emitUserBash({
|
|
5605
|
+
type: "user_bash",
|
|
5606
|
+
command,
|
|
5607
|
+
excludeFromContext,
|
|
5608
|
+
cwd: this.sessionManager.getCwd(),
|
|
5609
|
+
});
|
|
5610
|
+
}
|
|
5611
|
+
catch {
|
|
5612
|
+
// The extension runner already reported the error. Do not fall back to local execution.
|
|
5613
|
+
return;
|
|
5614
|
+
}
|
|
5472
5615
|
// If extension returned a full result, use it directly
|
|
5473
5616
|
if (eventResult?.result) {
|
|
5474
5617
|
const result = eventResult.result;
|