@averyyy/pi-coding-agent 0.84.2-piclient.1 → 0.84.3-piclient.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 +7 -0
- package/README.md +8 -4
- package/dist/bundle/chunks/anthropic-messages-JWX2WP65.js +45 -0
- package/dist/bundle/chunks/anthropic.js +75 -0
- package/dist/bundle/chunks/azure-openai-responses-B2RCCN5N.js +2 -0
- package/dist/bundle/chunks/bedrock-converse-stream.js +74 -0
- package/dist/bundle/chunks/chunk-4L3WN2XY.js +2 -0
- package/dist/bundle/chunks/chunk-6CYCI3EJ.js +12 -0
- package/dist/bundle/chunks/chunk-6R7UI4IY.js +2 -0
- package/dist/bundle/chunks/chunk-AXIIZGTV.js +2 -0
- package/dist/bundle/chunks/chunk-DRQDKNXA.js +2 -0
- package/dist/bundle/chunks/chunk-GMWCTUPB.js +2 -0
- package/dist/bundle/chunks/chunk-GPPBJGBU.js +50 -0
- package/dist/bundle/chunks/chunk-JUUC5AZY.js +2 -0
- package/dist/bundle/chunks/chunk-L2ZPNLYD.js +2 -0
- package/dist/bundle/chunks/chunk-LRBSW3NQ.js +11 -0
- package/dist/bundle/chunks/chunk-MNAIPA3J.js +2 -0
- package/dist/bundle/chunks/chunk-NUHFSC37.js +25 -0
- package/dist/bundle/chunks/chunk-PGXDEOVV.js +2 -0
- package/dist/bundle/chunks/chunk-PJACZCIR.js +2 -0
- package/dist/bundle/chunks/chunk-PRRNXB7S.js +2 -0
- package/dist/bundle/chunks/chunk-QI42RBZ4.js +1632 -0
- package/dist/bundle/chunks/chunk-TEPMHNKQ.js +2 -0
- package/dist/bundle/chunks/chunk-TRDNDS6A.js +4 -0
- package/dist/bundle/chunks/chunk-UAQELI3K.js +2 -0
- package/dist/bundle/chunks/chunk-XDUWOHPL.js +6 -0
- package/dist/bundle/chunks/chunk-XNGRGP62.js +2 -0
- package/dist/bundle/chunks/dist-RDWOYWHR.js +13 -0
- package/dist/bundle/chunks/github-copilot.js +2 -0
- package/dist/bundle/chunks/google-generative-ai-XDKMGBCJ.js +2 -0
- package/dist/bundle/chunks/google-vertex-D5FGEO3Y.js +2 -0
- package/dist/bundle/chunks/image-resize-worker.js +2 -0
- package/dist/bundle/chunks/kimi-coding.js +2 -0
- package/dist/bundle/chunks/lib-HGQMNYVT.js +9 -0
- package/dist/bundle/chunks/mistral-conversations-YK73UAOZ.js +5 -0
- package/dist/bundle/chunks/multipart-parser-SQ6GDJL7.js +3 -0
- package/dist/bundle/chunks/openai-codex-responses-MJHX7NXI.js +8 -0
- package/dist/bundle/chunks/openai-codex.js +75 -0
- package/dist/bundle/chunks/openai-completions-JD4WAC3R.js +7 -0
- package/dist/bundle/chunks/openai-responses-CP4VKB27.js +2 -0
- package/dist/bundle/chunks/openrouter-images-N4XVVFSD.js +2 -0
- package/dist/bundle/chunks/openrouter.js +75 -0
- package/dist/bundle/chunks/pi-messages-TPFH44NP.js +8 -0
- package/dist/bundle/chunks/radius.js +75 -0
- package/dist/bundle/chunks/src-UK77SYZE.js +4 -0
- package/dist/bundle/chunks/xai.js +2 -0
- package/dist/bundle/cli.js +3 -0
- package/dist/bundle/client.js +2 -0
- package/dist/bundle/index.js +2 -0
- package/dist/bundle/rpc-entry.js +3 -0
- package/dist/cli/args.d.ts +1 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +29 -9
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/file-processor.d.ts.map +1 -1
- package/dist/cli/file-processor.js +2 -1
- package/dist/cli/file-processor.js.map +1 -1
- package/dist/config.d.ts +4 -3
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +22 -14
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session.d.ts +15 -8
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +48 -39
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +6 -7
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/defaults.d.ts +1 -0
- package/dist/core/defaults.d.ts.map +1 -1
- package/dist/core/defaults.js +9 -0
- package/dist/core/defaults.js.map +1 -1
- package/dist/core/exec.d.ts.map +1 -1
- package/dist/core/exec.js +3 -1
- package/dist/core/exec.js.map +1 -1
- package/dist/core/extensions/index.d.ts +2 -2
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +115 -48
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/types.d.ts +38 -9
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js +3 -0
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/footer-data-provider.d.ts +1 -1
- package/dist/core/footer-data-provider.d.ts.map +1 -1
- package/dist/core/footer-data-provider.js +1 -1
- package/dist/core/footer-data-provider.js.map +1 -1
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +1 -0
- package/dist/core/index.js.map +1 -1
- package/dist/core/keybindings.d.ts +20 -19
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +26 -5
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/model-config.d.ts +5 -0
- package/dist/core/model-config.d.ts.map +1 -1
- package/dist/core/model-config.js +3 -1
- package/dist/core/model-config.js.map +1 -1
- package/dist/core/model-resolver.d.ts +1 -0
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +14 -8
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/models-store.d.ts.map +1 -1
- package/dist/core/models-store.js +2 -1
- package/dist/core/models-store.js.map +1 -1
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +22 -14
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/pi-client-cli-adapter.d.ts +11 -0
- package/dist/core/pi-client-cli-adapter.d.ts.map +1 -0
- package/dist/core/pi-client-cli-adapter.js +91 -0
- package/dist/core/pi-client-cli-adapter.js.map +1 -0
- package/dist/core/pi-manifest.d.ts.map +1 -1
- package/dist/core/pi-manifest.js +2 -1
- package/dist/core/pi-manifest.js.map +1 -1
- package/dist/core/pi-server-client.d.ts +0 -1
- package/dist/core/pi-server-client.d.ts.map +1 -1
- package/dist/core/pi-server-client.js +148 -65
- package/dist/core/pi-server-client.js.map +1 -1
- package/dist/core/remote-catalog-provider.d.ts.map +1 -1
- package/dist/core/remote-catalog-provider.js +2 -1
- package/dist/core/remote-catalog-provider.js.map +1 -1
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +3 -2
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/sdk.d.ts +2 -2
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +10 -3
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-export.d.ts +4 -0
- package/dist/core/session-export.d.ts.map +1 -0
- package/dist/core/session-export.js +32 -0
- package/dist/core/session-export.js.map +1 -0
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +2 -1
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-diagnostics.d.ts +9 -0
- package/dist/core/settings-diagnostics.d.ts.map +1 -0
- package/dist/core/settings-diagnostics.js +21 -0
- package/dist/core/settings-diagnostics.js.map +1 -0
- package/dist/core/settings-manager.d.ts +9 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +52 -10
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js +51 -33
- package/dist/core/skills.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +2 -1
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +11 -2
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tools/bash.d.ts +13 -1
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +30 -14
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit-diff.d.ts +0 -5
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js +2 -5
- package/dist/core/tools/edit-diff.js.map +1 -1
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +20 -4
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/index.d.ts +4 -1
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +18 -1
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/powershell.d.ts +16 -0
- package/dist/core/tools/powershell.d.ts.map +1 -0
- package/dist/core/tools/powershell.js +39 -0
- package/dist/core/tools/powershell.js.map +1 -0
- package/dist/core/trust-manager.d.ts.map +1 -1
- package/dist/core/trust-manager.js +2 -1
- package/dist/core/trust-manager.js.map +1 -1
- package/dist/extensions/llama/client.d.ts +6 -0
- package/dist/extensions/llama/client.d.ts.map +1 -1
- package/dist/extensions/llama/client.js +7 -0
- package/dist/extensions/llama/client.js.map +1 -1
- package/dist/extensions/llama/index.d.ts.map +1 -1
- package/dist/extensions/llama/index.js +2 -0
- package/dist/extensions/llama/index.js.map +1 -1
- package/dist/extensions/llama/provider.d.ts +3 -1
- package/dist/extensions/llama/provider.d.ts.map +1 -1
- package/dist/extensions/llama/provider.js +29 -4
- package/dist/extensions/llama/provider.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts +4 -0
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +20 -15
- package/dist/main.js.map +1 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +4 -3
- package/dist/migrations.js.map +1 -1
- package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/bash-execution.js +2 -1
- package/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts +9 -3
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +56 -12
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +7 -2
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +118 -56
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-submenu.d.ts +72 -0
- package/dist/modes/interactive/components/settings-submenu.d.ts.map +1 -0
- package/dist/modes/interactive/components/settings-submenu.js +165 -0
- package/dist/modes/interactive/components/settings-submenu.js.map +1 -0
- package/dist/modes/interactive/components/thinking-selector.d.ts +15 -3
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.js +74 -17
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/dist/modes/interactive/external-editor.d.ts.map +1 -1
- package/dist/modes/interactive/external-editor.js +2 -1
- package/dist/modes/interactive/external-editor.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +13 -12
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +196 -226
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/session-share.d.ts +16 -0
- package/dist/modes/interactive/session-share.d.ts.map +1 -0
- package/dist/modes/interactive/session-share.js +188 -0
- package/dist/modes/interactive/session-share.js.map +1 -0
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +4 -3
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/json-event.d.ts +16 -13
- package/dist/modes/json-event.d.ts.map +1 -1
- package/dist/modes/json-event.js +20 -6
- package/dist/modes/json-event.js.map +1 -1
- package/dist/package-manager-cli.d.ts +1 -0
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js +186 -2
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/utils/child-process.d.ts.map +1 -1
- package/dist/utils/child-process.js +8 -3
- package/dist/utils/child-process.js.map +1 -1
- package/dist/utils/frontmatter.d.ts.map +1 -1
- package/dist/utils/frontmatter.js +2 -1
- package/dist/utils/frontmatter.js.map +1 -1
- package/dist/utils/management-http.d.ts +5 -3
- package/dist/utils/management-http.d.ts.map +1 -1
- package/dist/utils/management-http.js +14 -10
- package/dist/utils/management-http.js.map +1 -1
- package/dist/utils/shell.d.ts +3 -0
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js +21 -7
- package/dist/utils/shell.js.map +1 -1
- package/dist/utils/syntax-highlight.d.ts +1 -0
- package/dist/utils/syntax-highlight.d.ts.map +1 -1
- package/dist/utils/syntax-highlight.js +60 -1
- package/dist/utils/syntax-highlight.js.map +1 -1
- package/dist/utils/text.d.ts +8 -0
- package/dist/utils/text.d.ts.map +1 -0
- package/dist/utils/text.js +9 -0
- package/dist/utils/text.js.map +1 -0
- package/dist/utils/version-check.d.ts.map +1 -1
- package/dist/utils/version-check.js +2 -1
- package/dist/utils/version-check.js.map +1 -1
- package/docs/compaction.md +15 -0
- package/docs/custom-provider.md +5 -2
- package/docs/environment-variables.md +8 -8
- package/docs/extensions.md +17 -7
- package/docs/json.md +7 -2
- package/docs/keybindings.md +8 -8
- package/docs/llama-cpp.md +2 -0
- package/docs/models.md +8 -2
- package/docs/packages.md +2 -2
- package/docs/rpc.md +9 -3
- package/docs/sdk.md +7 -2
- package/docs/settings.md +11 -3
- package/docs/skills.md +4 -3
- package/docs/terminal-setup.md +11 -9
- package/docs/usage.md +6 -2
- package/docs/windows.md +24 -2
- package/examples/extensions/border-status-editor.ts +1 -1
- 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/package.json +1 -1
- package/examples/extensions/git-checkpoint.ts +2 -2
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/notify.ts +3 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/subagent/README.md +1 -1
- package/examples/extensions/subagent/index.ts +6 -1
- package/examples/extensions/titlebar-spinner.ts +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/examples/rpc-extension-ui.ts +1 -1
- package/examples/sdk/06-extensions.ts +1 -1
- package/examples/sdk/README.md +1 -1
- package/package.json +12 -14
|
@@ -9,18 +9,20 @@ import * as path from "node:path";
|
|
|
9
9
|
import * as TuiLayouts from "@earendil-works/pi-tui";
|
|
10
10
|
import { CombinedAutocompleteProvider, Container, fuzzyFilter, getCapabilities, hyperlink, Markdown, matchesKey, ProcessTerminal, Spacer, setKeybindings, Text, TruncatedText, TuiAltScreen, TuiMainScreen, visibleWidth, } from "@earendil-works/pi-tui";
|
|
11
11
|
import chalk from "chalk";
|
|
12
|
-
import { spawn
|
|
13
|
-
import { APP_NAME, APP_TITLE, CONFIG_DIR_NAME, getAgentDir, getAuthPath, getDebugLogPath, getDocsPath,
|
|
12
|
+
import { spawn } from "child_process";
|
|
13
|
+
import { APP_NAME, APP_TITLE, CONFIG_DIR_NAME, getAgentDir, getAuthPath, getDebugLogPath, getDocsPath, VERSION, } from "../../config.js";
|
|
14
14
|
import { parseSkillBlock } from "../../core/agent-session.js";
|
|
15
15
|
import { SessionImportFileNotFoundError } from "../../core/agent-session-runtime.js";
|
|
16
16
|
import { CACHE_TTL_MS, collectCacheMisses, computeCacheWaste, detectCacheMiss, } from "../../core/cache-stats.js";
|
|
17
|
+
import { DEFAULT_THINKING_LEVEL, THINKING_LEVEL_OPTIONS } from "../../core/defaults.js";
|
|
17
18
|
import { FooterDataProvider } from "../../core/footer-data-provider.js";
|
|
18
19
|
import { configureHttpDispatcher, formatHttpIdleTimeoutMs } from "../../core/http-dispatcher.js";
|
|
19
20
|
import { KeybindingsManager } from "../../core/keybindings.js";
|
|
21
|
+
import { createCompactionSummaryMessage } from "../../core/messages.js";
|
|
20
22
|
import { defaultModelPerProvider, findExactModelReferenceMatch, resolveModelScopeFromModels, } from "../../core/model-resolver.js";
|
|
21
23
|
import { CredentialSynchronizationError } from "../../core/model-runtime.js";
|
|
22
24
|
import { DefaultPackageManager } from "../../core/package-manager.js";
|
|
23
|
-
import {
|
|
25
|
+
import { getCliBinName } from "../../core/pi-client-cli-adapter.js";
|
|
24
26
|
import { formatMissingSessionCwdPrompt, MissingSessionCwdError } from "../../core/session-cwd.js";
|
|
25
27
|
import { SessionManager, sessionEntryToContextMessages } from "../../core/session-manager.js";
|
|
26
28
|
import { BUILTIN_SLASH_COMMANDS } from "../../core/slash-commands.js";
|
|
@@ -35,12 +37,12 @@ import { openBrowser } from "../../utils/open-browser.js";
|
|
|
35
37
|
import { getCwdRelativePath } from "../../utils/paths.js";
|
|
36
38
|
import { getPiUserAgent } from "../../utils/pi-user-agent.js";
|
|
37
39
|
import { killTrackedDetachedChildren } from "../../utils/shell.js";
|
|
40
|
+
import { loadAllHighlightLanguages } from "../../utils/syntax-highlight.js";
|
|
38
41
|
import { ensureTool } from "../../utils/tools-manager.js";
|
|
39
42
|
import { checkForNewPiVersion } from "../../utils/version-check.js";
|
|
40
43
|
import { ArminComponent } from "./components/armin.js";
|
|
41
44
|
import { AssistantMessageComponent } from "./components/assistant-message.js";
|
|
42
45
|
import { BashExecutionComponent } from "./components/bash-execution.js";
|
|
43
|
-
import { BorderedLoader } from "./components/bordered-loader.js";
|
|
44
46
|
import { BranchSummaryMessageComponent } from "./components/branch-summary-message.js";
|
|
45
47
|
import { CompactionSummaryMessageComponent } from "./components/compaction-summary-message.js";
|
|
46
48
|
import { CustomEditor } from "./components/custom-editor.js";
|
|
@@ -63,6 +65,7 @@ import { SessionSelectorComponent } from "./components/session-selector.js";
|
|
|
63
65
|
import { SettingsSelectorComponent } from "./components/settings-selector.js";
|
|
64
66
|
import { SkillInvocationMessageComponent } from "./components/skill-invocation-message.js";
|
|
65
67
|
import { BranchSummaryStatusIndicator, CompactionStatusIndicator, IdleStatus, RetryStatusIndicator, WorkingStatusIndicator, } from "./components/status-indicator.js";
|
|
68
|
+
import { ThinkingSelectorComponent } from "./components/thinking-selector.js";
|
|
66
69
|
import { ToolExecutionComponent } from "./components/tool-execution.js";
|
|
67
70
|
import { TreeSelectorComponent } from "./components/tree-selector.js";
|
|
68
71
|
import { TrustSelectorComponent } from "./components/trust-selector.js";
|
|
@@ -71,9 +74,9 @@ import { UserMessageSelectorComponent } from "./components/user-message-selector
|
|
|
71
74
|
import { editInExternalEditor } from "./external-editor.js";
|
|
72
75
|
import { refreshModelCatalogs } from "./model-catalog-refresh.js";
|
|
73
76
|
import { getModelSearchText } from "./model-search.js";
|
|
77
|
+
import { shareSession } from "./session-share.js";
|
|
74
78
|
import { getAvailableThemes, getAvailableThemesWithPaths, getEditorTheme, getMarkdownTheme, getThemeByName, onThemeChange, setRegisteredThemes, stopThemeWatcher, Theme, theme, } from "./theme/theme.js";
|
|
75
79
|
import { InteractiveThemeController } from "./theme/theme-controller.js";
|
|
76
|
-
const TRANSCRIPT_LAZY_LOAD_BATCH_SIZE = 20;
|
|
77
80
|
function isExpandable(obj) {
|
|
78
81
|
return typeof obj === "object" && obj !== null && "setExpanded" in obj && typeof obj.setExpanded === "function";
|
|
79
82
|
}
|
|
@@ -92,6 +95,9 @@ class ExpandableText extends Text {
|
|
|
92
95
|
function isCustomSessionEntry(item) {
|
|
93
96
|
return "type" in item && item.type === "custom";
|
|
94
97
|
}
|
|
98
|
+
function isCompactionCostNotice(item) {
|
|
99
|
+
return "type" in item && item.type === "compaction_cost";
|
|
100
|
+
}
|
|
95
101
|
const DEAD_TERMINAL_ERROR_CODES = new Set(["EIO", "EPIPE", "ENOTCONN"]);
|
|
96
102
|
function isDeadTerminalError(error) {
|
|
97
103
|
if (!error || typeof error !== "object" || !("code" in error)) {
|
|
@@ -121,7 +127,7 @@ export function formatResumeCommand(sessionManager) {
|
|
|
121
127
|
const sessionFile = sessionManager.getSessionFile();
|
|
122
128
|
if (!sessionFile || !fs.existsSync(sessionFile))
|
|
123
129
|
return undefined;
|
|
124
|
-
const args = [
|
|
130
|
+
const args = [getCliBinName()];
|
|
125
131
|
if (!sessionManager.usesDefaultSessionDir()) {
|
|
126
132
|
args.push("--session-dir", quoteIfNeeded(sessionManager.getSessionDir()));
|
|
127
133
|
}
|
|
@@ -131,6 +137,11 @@ export function formatResumeCommand(sessionManager) {
|
|
|
131
137
|
function hasDefaultModelProvider(providerId) {
|
|
132
138
|
return providerId in defaultModelPerProvider;
|
|
133
139
|
}
|
|
140
|
+
function llamaCppPostLoginGuidance(actionLabel, loadedModelCount) {
|
|
141
|
+
return loadedModelCount === 0
|
|
142
|
+
? `${actionLabel}. No llama.cpp models are loaded. Use /llama to load a model, then /model to select it.`
|
|
143
|
+
: `${actionLabel}. Use /model to select a loaded llama.cpp model, or /llama to manage models.`;
|
|
144
|
+
}
|
|
134
145
|
const AUTH_TYPE_ORDER = { oauth: 0, api_key: 1 };
|
|
135
146
|
function createFuzzyAutocompleteItems(items, prefix, getSearchText, toAutocompleteItem) {
|
|
136
147
|
const filtered = fuzzyFilter(items, prefix, getSearchText);
|
|
@@ -230,11 +241,6 @@ export class InteractiveMode {
|
|
|
230
241
|
chatContainer;
|
|
231
242
|
documentContainer;
|
|
232
243
|
transcriptScrollView;
|
|
233
|
-
transcriptLazyEntries = [];
|
|
234
|
-
loadedTranscriptEntryIds = new Set();
|
|
235
|
-
transcriptWindowInitialized = false;
|
|
236
|
-
transcriptLatestCompactionId;
|
|
237
|
-
loadingEarlierTranscript = false;
|
|
238
244
|
fullscreenLayoutRoot;
|
|
239
245
|
pendingMessagesContainer;
|
|
240
246
|
statusContainer;
|
|
@@ -471,6 +477,15 @@ export class InteractiveMode {
|
|
|
471
477
|
}));
|
|
472
478
|
};
|
|
473
479
|
}
|
|
480
|
+
const thinkingCommand = slashCommands.find((command) => command.name === "thinking");
|
|
481
|
+
if (thinkingCommand) {
|
|
482
|
+
thinkingCommand.getArgumentCompletions = (prefix) => {
|
|
483
|
+
return createFuzzyAutocompleteItems(this.session.getAvailableThinkingLevels(), prefix, (level) => level, (level) => ({
|
|
484
|
+
value: level,
|
|
485
|
+
label: level,
|
|
486
|
+
}));
|
|
487
|
+
};
|
|
488
|
+
}
|
|
474
489
|
const loginCommand = slashCommands.find((command) => command.name === "login");
|
|
475
490
|
if (loginCommand) {
|
|
476
491
|
loginCommand.getArgumentCompletions = (prefix) => {
|
|
@@ -647,7 +662,6 @@ export class InteractiveMode {
|
|
|
647
662
|
follow: "end",
|
|
648
663
|
primary: true,
|
|
649
664
|
overscroll: "chain",
|
|
650
|
-
onScroll: (scrollTop) => this.handleTranscriptScroll(scrollTop),
|
|
651
665
|
scrollbar: this.settingsManager.getFullscreenScrollbar(),
|
|
652
666
|
scrollbarStyle: (text) => theme.bg("scrollbarThumb", text),
|
|
653
667
|
});
|
|
@@ -756,6 +770,14 @@ export class InteractiveMode {
|
|
|
756
770
|
});
|
|
757
771
|
// Initialize available provider count for footer display
|
|
758
772
|
await this.updateAvailableProviderCount();
|
|
773
|
+
// Flush the completed startup state before loading the remaining syntax grammars.
|
|
774
|
+
this.ui.renderNow();
|
|
775
|
+
void loadAllHighlightLanguages().then(() => {
|
|
776
|
+
if (!this.isInitialized)
|
|
777
|
+
return;
|
|
778
|
+
this.ui.invalidate();
|
|
779
|
+
this.ui.requestRender();
|
|
780
|
+
});
|
|
759
781
|
}
|
|
760
782
|
/**
|
|
761
783
|
* Update terminal title with session name and cwd.
|
|
@@ -785,7 +807,7 @@ export class InteractiveMode {
|
|
|
785
807
|
.finally(() => clearTimeout(timeout));
|
|
786
808
|
}
|
|
787
809
|
// Start version check asynchronously
|
|
788
|
-
checkForNewPiVersion(this.version).then((newRelease) => {
|
|
810
|
+
checkForNewPiVersion(process.env.PI_CLIENT_VERSION ?? this.version).then((newRelease) => {
|
|
789
811
|
if (newRelease) {
|
|
790
812
|
this.showNewVersionNotification(newRelease);
|
|
791
813
|
}
|
|
@@ -811,7 +833,18 @@ export class InteractiveMode {
|
|
|
811
833
|
}
|
|
812
834
|
});
|
|
813
835
|
// Show startup warnings
|
|
814
|
-
const { migratedProviders, modelFallbackMessage, initialMessage, initialImages, initialMessages } = this.options;
|
|
836
|
+
const { migratedProviders, startupDiagnostics, modelFallbackMessage, initialMessage, initialImages, initialMessages, } = this.options;
|
|
837
|
+
for (const diagnostic of startupDiagnostics ?? []) {
|
|
838
|
+
if (diagnostic.type === "error") {
|
|
839
|
+
this.showError(diagnostic.message);
|
|
840
|
+
}
|
|
841
|
+
else if (diagnostic.type === "warning") {
|
|
842
|
+
this.showWarning(diagnostic.message);
|
|
843
|
+
}
|
|
844
|
+
else {
|
|
845
|
+
this.showStatus(diagnostic.message);
|
|
846
|
+
}
|
|
847
|
+
}
|
|
815
848
|
if (migratedProviders && migratedProviders.length > 0) {
|
|
816
849
|
this.showWarning(`Migrated credentials to auth.json: ${migratedProviders.join(", ")}`);
|
|
817
850
|
}
|
|
@@ -966,14 +999,13 @@ export class InteractiveMode {
|
|
|
966
999
|
// Extension System
|
|
967
1000
|
// =========================================================================
|
|
968
1001
|
formatDisplayPath(p) {
|
|
969
|
-
const
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
return `~/${normalizedPath.slice(normalizedHome.length + 1)}`;
|
|
1002
|
+
const home = os.homedir();
|
|
1003
|
+
let result = p;
|
|
1004
|
+
// Replace home directory with ~
|
|
1005
|
+
if (result.startsWith(home)) {
|
|
1006
|
+
result = `~${result.slice(home.length)}`;
|
|
975
1007
|
}
|
|
976
|
-
return
|
|
1008
|
+
return result;
|
|
977
1009
|
}
|
|
978
1010
|
formatExtensionDisplayPath(path) {
|
|
979
1011
|
let result = this.formatDisplayPath(path);
|
|
@@ -1660,15 +1692,6 @@ export class InteractiveMode {
|
|
|
1660
1692
|
}
|
|
1661
1693
|
this.ui.requestRender();
|
|
1662
1694
|
}
|
|
1663
|
-
restoreWorkingIndicator() {
|
|
1664
|
-
if (!this.session.isStreaming || !this.workingVisible) {
|
|
1665
|
-
return;
|
|
1666
|
-
}
|
|
1667
|
-
if (this.settingsManager.getShowTerminalProgress()) {
|
|
1668
|
-
this.ui.terminal.setProgress(true);
|
|
1669
|
-
}
|
|
1670
|
-
this.showStatusIndicator(new WorkingStatusIndicator(this.ui, this.workingMessage ?? this.defaultWorkingMessage, this.workingIndicatorOptions));
|
|
1671
|
-
}
|
|
1672
1695
|
setHiddenThinkingLabel(label) {
|
|
1673
1696
|
this.hiddenThinkingLabel = label ?? this.defaultHiddenThinkingLabel;
|
|
1674
1697
|
for (const child of this.chatContainer.children) {
|
|
@@ -2285,7 +2308,6 @@ export class InteractiveMode {
|
|
|
2285
2308
|
this.defaultEditor.onAction("app.session.tree", () => this.showTreeSelector());
|
|
2286
2309
|
this.defaultEditor.onAction("app.session.fork", () => this.showUserMessageSelector());
|
|
2287
2310
|
this.defaultEditor.onAction("app.session.resume", () => this.showSessionSelector());
|
|
2288
|
-
this.defaultEditor.onAction("app.session.loadEarlier", () => this.loadEarlierTranscript());
|
|
2289
2311
|
this.defaultEditor.onChange = (text) => {
|
|
2290
2312
|
const wasBashMode = this.isBashMode;
|
|
2291
2313
|
this.isBashMode = text.trimStart().startsWith("!");
|
|
@@ -2364,6 +2386,12 @@ export class InteractiveMode {
|
|
|
2364
2386
|
await this.handleModelCommand(searchTerm);
|
|
2365
2387
|
return;
|
|
2366
2388
|
}
|
|
2389
|
+
if (text === "/thinking" || text.startsWith("/thinking ")) {
|
|
2390
|
+
const searchTerm = text.startsWith("/thinking ") ? text.slice(10).trim() : undefined;
|
|
2391
|
+
this.editor.setText("");
|
|
2392
|
+
this.handleThinkingCommand(searchTerm);
|
|
2393
|
+
return;
|
|
2394
|
+
}
|
|
2367
2395
|
if (text === "/export" || text.startsWith("/export ")) {
|
|
2368
2396
|
await this.handleExportCommand(text);
|
|
2369
2397
|
this.editor.setText("");
|
|
@@ -2451,12 +2479,6 @@ export class InteractiveMode {
|
|
|
2451
2479
|
await this.handleReloadCommand();
|
|
2452
2480
|
return;
|
|
2453
2481
|
}
|
|
2454
|
-
const pendingPiClientUpdate = readPiClientUpdateMarker();
|
|
2455
|
-
if (pendingPiClientUpdate) {
|
|
2456
|
-
this.showWarning(`pi-client ${pendingPiClientUpdate.version} is installed. Run /reload to continue this session with the new version.`);
|
|
2457
|
-
this.editor.setText(text);
|
|
2458
|
-
return;
|
|
2459
|
-
}
|
|
2460
2482
|
if (text === "/debug") {
|
|
2461
2483
|
this.handleDebugCommand();
|
|
2462
2484
|
this.editor.setText("");
|
|
@@ -2702,6 +2724,10 @@ export class InteractiveMode {
|
|
|
2702
2724
|
break;
|
|
2703
2725
|
}
|
|
2704
2726
|
case "agent_end":
|
|
2727
|
+
if (this.settingsManager.getShowTerminalProgress()) {
|
|
2728
|
+
this.ui.terminal.setProgress(false);
|
|
2729
|
+
}
|
|
2730
|
+
this.clearStatusIndicator("working");
|
|
2705
2731
|
if (this.streamingComponent) {
|
|
2706
2732
|
this.chatContainer.removeChild(this.streamingComponent);
|
|
2707
2733
|
this.streamingComponent = undefined;
|
|
@@ -2711,12 +2737,7 @@ export class InteractiveMode {
|
|
|
2711
2737
|
this.ui.requestRender();
|
|
2712
2738
|
break;
|
|
2713
2739
|
case "agent_settled":
|
|
2714
|
-
if (this.settingsManager.getShowTerminalProgress()) {
|
|
2715
|
-
this.ui.terminal.setProgress(false);
|
|
2716
|
-
}
|
|
2717
|
-
this.clearStatusIndicator("working");
|
|
2718
2740
|
await this.checkShutdownRequested();
|
|
2719
|
-
this.ui.requestRender();
|
|
2720
2741
|
break;
|
|
2721
2742
|
case "compaction_start": {
|
|
2722
2743
|
if (this.settingsManager.getShowTerminalProgress()) {
|
|
@@ -2749,7 +2770,21 @@ export class InteractiveMode {
|
|
|
2749
2770
|
}
|
|
2750
2771
|
}
|
|
2751
2772
|
else if (event.result) {
|
|
2752
|
-
this.
|
|
2773
|
+
const entries = this.sessionManager.buildContextEntries();
|
|
2774
|
+
if (entries[0]?.type !== "compaction") {
|
|
2775
|
+
throw new Error("Completed compaction is missing from the session context");
|
|
2776
|
+
}
|
|
2777
|
+
this.chatContainer.clear();
|
|
2778
|
+
// The latest compaction is prepended for model context; append it below at its chronological position.
|
|
2779
|
+
this.renderSessionEntries(entries.slice(1));
|
|
2780
|
+
this.addMessageToChat(createCompactionSummaryMessage(event.result.summary, event.result.tokensBefore, new Date().toISOString()));
|
|
2781
|
+
if (event.result.usage) {
|
|
2782
|
+
this.addCompactionCostNotice({
|
|
2783
|
+
type: "compaction_cost",
|
|
2784
|
+
kind: "compaction",
|
|
2785
|
+
usage: event.result.usage,
|
|
2786
|
+
});
|
|
2787
|
+
}
|
|
2753
2788
|
this.footer.invalidate();
|
|
2754
2789
|
}
|
|
2755
2790
|
else if (event.errorMessage) {
|
|
@@ -2761,7 +2796,6 @@ export class InteractiveMode {
|
|
|
2761
2796
|
this.chatContainer.addChild(new Text(theme.fg("error", event.errorMessage), 1, 0));
|
|
2762
2797
|
}
|
|
2763
2798
|
}
|
|
2764
|
-
this.restoreWorkingIndicator();
|
|
2765
2799
|
void this.flushCompactionQueue({ willRetry: event.willRetry });
|
|
2766
2800
|
this.ui.requestRender();
|
|
2767
2801
|
break;
|
|
@@ -2787,7 +2821,6 @@ export class InteractiveMode {
|
|
|
2787
2821
|
if (!event.success) {
|
|
2788
2822
|
this.showError(`Retry failed after ${event.attempt} attempts: ${event.finalError || "Unknown error"}`);
|
|
2789
2823
|
}
|
|
2790
|
-
this.restoreWorkingIndicator();
|
|
2791
2824
|
this.ui.requestRender();
|
|
2792
2825
|
break;
|
|
2793
2826
|
}
|
|
@@ -2973,6 +3006,10 @@ export class InteractiveMode {
|
|
|
2973
3006
|
this.addCustomEntryToChat(item);
|
|
2974
3007
|
continue;
|
|
2975
3008
|
}
|
|
3009
|
+
if (isCompactionCostNotice(item)) {
|
|
3010
|
+
this.addCompactionCostNotice(item);
|
|
3011
|
+
continue;
|
|
3012
|
+
}
|
|
2976
3013
|
const message = item;
|
|
2977
3014
|
// Assistant messages need special handling for tool calls
|
|
2978
3015
|
if (message.role === "assistant") {
|
|
@@ -3030,8 +3067,8 @@ export class InteractiveMode {
|
|
|
3030
3067
|
this.ui.requestRender();
|
|
3031
3068
|
}
|
|
3032
3069
|
/**
|
|
3033
|
-
* Render session entries to chat. Used for initial load and
|
|
3034
|
-
* @param entries
|
|
3070
|
+
* Render session entries to chat. Used for initial load and rebuild after compaction.
|
|
3071
|
+
* @param entries Compaction-aware session entries to render
|
|
3035
3072
|
* @param options.updateFooter Update footer state
|
|
3036
3073
|
* @param options.populateHistory Add user messages to editor history
|
|
3037
3074
|
*/
|
|
@@ -3040,10 +3077,28 @@ export class InteractiveMode {
|
|
|
3040
3077
|
if (entry.type === "custom") {
|
|
3041
3078
|
return [entry];
|
|
3042
3079
|
}
|
|
3043
|
-
|
|
3080
|
+
const messages = sessionEntryToContextMessages(entry);
|
|
3081
|
+
if ((entry.type === "compaction" || entry.type === "branch_summary") && entry.usage && messages.length > 0) {
|
|
3082
|
+
return [...messages, { type: "compaction_cost", kind: entry.type, usage: entry.usage }];
|
|
3083
|
+
}
|
|
3084
|
+
return messages;
|
|
3044
3085
|
});
|
|
3045
3086
|
this.renderSessionItems(items, options);
|
|
3046
3087
|
}
|
|
3088
|
+
/**
|
|
3089
|
+
* Render billing usage for a compaction or branch summary. The notice is derived
|
|
3090
|
+
* from persisted summary usage and is not stored as a separate session entry.
|
|
3091
|
+
*/
|
|
3092
|
+
addCompactionCostNotice(notice) {
|
|
3093
|
+
if (!this.settingsManager.getShowCacheMissNotices())
|
|
3094
|
+
return;
|
|
3095
|
+
const { usage } = notice;
|
|
3096
|
+
const tokens = usage.input + usage.output + usage.cacheRead + usage.cacheWrite;
|
|
3097
|
+
const cost = usage.cost.total >= 0.01 ? ` (~$${usage.cost.total.toFixed(2)})` : "";
|
|
3098
|
+
const label = notice.kind === "compaction" ? "Compaction" : "Branch summary";
|
|
3099
|
+
this.chatContainer.addChild(new Spacer(1));
|
|
3100
|
+
this.chatContainer.addChild(new Text(theme.fg("warning", `${label}: ${formatTokens(tokens)} tokens billed${cost}`), 1, 0));
|
|
3101
|
+
}
|
|
3047
3102
|
/**
|
|
3048
3103
|
* Show a transcript notice when a completed assistant message paid for a
|
|
3049
3104
|
* significant cache miss. Only states observable facts: the miss itself,
|
|
@@ -3073,66 +3128,9 @@ export class InteractiveMode {
|
|
|
3073
3128
|
this.chatContainer.addChild(new Spacer(1));
|
|
3074
3129
|
this.chatContainer.addChild(new Text(text, 1, 0));
|
|
3075
3130
|
}
|
|
3076
|
-
getTranscriptEntriesForRender(reset = false) {
|
|
3077
|
-
const branch = this.sessionManager.getBranch();
|
|
3078
|
-
const contextEntries = this.sessionManager.buildContextEntries();
|
|
3079
|
-
let latestCompactionId;
|
|
3080
|
-
for (let index = branch.length - 1; index >= 0; index--) {
|
|
3081
|
-
const entry = branch[index];
|
|
3082
|
-
if (entry?.type === "compaction") {
|
|
3083
|
-
latestCompactionId = entry.id;
|
|
3084
|
-
break;
|
|
3085
|
-
}
|
|
3086
|
-
}
|
|
3087
|
-
if (reset || (this.transcriptWindowInitialized && this.transcriptLatestCompactionId !== latestCompactionId)) {
|
|
3088
|
-
this.loadedTranscriptEntryIds.clear();
|
|
3089
|
-
}
|
|
3090
|
-
this.transcriptWindowInitialized = true;
|
|
3091
|
-
this.transcriptLatestCompactionId = latestCompactionId;
|
|
3092
|
-
const contextEntryIds = new Set(contextEntries.map((entry) => entry.id));
|
|
3093
|
-
const earlierEntries = branch.filter((entry) => !contextEntryIds.has(entry.id));
|
|
3094
|
-
const loadedEntries = earlierEntries.filter((entry) => this.loadedTranscriptEntryIds.has(entry.id));
|
|
3095
|
-
this.transcriptLazyEntries = earlierEntries.filter((entry) => !this.loadedTranscriptEntryIds.has(entry.id));
|
|
3096
|
-
return [...loadedEntries, ...contextEntries];
|
|
3097
|
-
}
|
|
3098
|
-
renderTranscriptEntries(entries, options = {}) {
|
|
3099
|
-
if (this.transcriptLazyEntries.length > 0) {
|
|
3100
|
-
const count = this.transcriptLazyEntries.length.toLocaleString();
|
|
3101
|
-
this.chatContainer.addChild(new Text(theme.fg("dim", `${count} earlier transcript entries hidden (${keyText("app.session.loadEarlier")} to load)`), 1, 0));
|
|
3102
|
-
this.chatContainer.addChild(new Spacer(1));
|
|
3103
|
-
}
|
|
3104
|
-
this.renderSessionEntries(entries, options);
|
|
3105
|
-
}
|
|
3106
|
-
handleTranscriptScroll(scrollTop) {
|
|
3107
|
-
if (scrollTop === 0) {
|
|
3108
|
-
this.loadEarlierTranscript();
|
|
3109
|
-
}
|
|
3110
|
-
}
|
|
3111
|
-
loadEarlierTranscript() {
|
|
3112
|
-
if (this.loadingEarlierTranscript || this.session.isStreaming || this.transcriptLazyEntries.length === 0) {
|
|
3113
|
-
return;
|
|
3114
|
-
}
|
|
3115
|
-
this.loadingEarlierTranscript = true;
|
|
3116
|
-
try {
|
|
3117
|
-
const firstLoadedIndex = Math.max(0, this.transcriptLazyEntries.length - TRANSCRIPT_LAZY_LOAD_BATCH_SIZE);
|
|
3118
|
-
const entriesToLoad = this.transcriptLazyEntries.slice(firstLoadedIndex);
|
|
3119
|
-
for (const entry of entriesToLoad) {
|
|
3120
|
-
this.loadedTranscriptEntryIds.add(entry.id);
|
|
3121
|
-
}
|
|
3122
|
-
this.rebuildChatFromMessages();
|
|
3123
|
-
const remaining = this.transcriptLazyEntries.length;
|
|
3124
|
-
this.showStatus(remaining > 0
|
|
3125
|
-
? `Loaded ${entriesToLoad.length} earlier transcript entries (${remaining} remaining)`
|
|
3126
|
-
: "Loaded the beginning of the transcript");
|
|
3127
|
-
this.ui.requestRender();
|
|
3128
|
-
}
|
|
3129
|
-
finally {
|
|
3130
|
-
this.loadingEarlierTranscript = false;
|
|
3131
|
-
}
|
|
3132
|
-
}
|
|
3133
3131
|
renderInitialMessages() {
|
|
3134
|
-
const entries = this.
|
|
3135
|
-
this.
|
|
3132
|
+
const entries = this.sessionManager.buildContextEntries();
|
|
3133
|
+
this.renderSessionEntries(entries, {
|
|
3136
3134
|
updateFooter: true,
|
|
3137
3135
|
populateHistory: true,
|
|
3138
3136
|
});
|
|
@@ -3168,7 +3166,7 @@ export class InteractiveMode {
|
|
|
3168
3166
|
}
|
|
3169
3167
|
rebuildChatFromMessages() {
|
|
3170
3168
|
this.chatContainer.clear();
|
|
3171
|
-
this.
|
|
3169
|
+
this.renderSessionEntries(this.sessionManager.buildContextEntries());
|
|
3172
3170
|
}
|
|
3173
3171
|
// =========================================================================
|
|
3174
3172
|
// Key handlers
|
|
@@ -3737,8 +3735,14 @@ export class InteractiveMode {
|
|
|
3737
3735
|
showSettingsSelector() {
|
|
3738
3736
|
this.showSelector((done) => {
|
|
3739
3737
|
let selector;
|
|
3738
|
+
const defaultProvider = this.settingsManager.getDefaultProvider();
|
|
3739
|
+
const defaultModelId = this.settingsManager.getDefaultModel();
|
|
3740
|
+
const defaultModel = defaultProvider && defaultModelId ? `${defaultProvider}/${defaultModelId}` : "not set";
|
|
3740
3741
|
selector = new SettingsSelectorComponent({
|
|
3741
3742
|
autoCompact: this.session.autoCompactionEnabled,
|
|
3743
|
+
defaultModel,
|
|
3744
|
+
currentModel: this.session.model,
|
|
3745
|
+
availableDefaultModels: this.session.modelRuntime.getAvailableSnapshot(),
|
|
3742
3746
|
showImages: this.settingsManager.getShowImages(),
|
|
3743
3747
|
imageWidthCells: this.settingsManager.getImageWidthCells(),
|
|
3744
3748
|
autoResizeImages: this.settingsManager.getImageAutoResize(),
|
|
@@ -3748,8 +3752,9 @@ export class InteractiveMode {
|
|
|
3748
3752
|
followUpMode: this.session.followUpMode,
|
|
3749
3753
|
transport: this.settingsManager.getTransport(),
|
|
3750
3754
|
httpIdleTimeoutMs: this.settingsManager.getHttpIdleTimeoutMs(),
|
|
3751
|
-
thinkingLevel: this.
|
|
3752
|
-
availableThinkingLevels:
|
|
3755
|
+
thinkingLevel: this.settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL,
|
|
3756
|
+
availableThinkingLevels: [...THINKING_LEVEL_OPTIONS],
|
|
3757
|
+
modelThinkingLevels: this.settingsManager.getAllModelThinkingLevels(),
|
|
3753
3758
|
currentTheme: this.themeController.getThemeSelection() || "dark",
|
|
3754
3759
|
terminalTheme: this.themeController.getTerminalTheme(),
|
|
3755
3760
|
availableThemes: getAvailableThemes(),
|
|
@@ -3818,10 +3823,26 @@ export class InteractiveMode {
|
|
|
3818
3823
|
configureHttpDispatcher(timeoutMs);
|
|
3819
3824
|
this.showStatus(`HTTP idle timeout: ${formatHttpIdleTimeoutMs(timeoutMs)}`);
|
|
3820
3825
|
},
|
|
3821
|
-
|
|
3822
|
-
this.
|
|
3823
|
-
|
|
3824
|
-
this.
|
|
3826
|
+
onModelThinkingLevelChange: (provider, modelId, level) => {
|
|
3827
|
+
this.settingsManager.setModelThinkingLevel(provider, modelId, level);
|
|
3828
|
+
// If the override is for the current model, apply it to the session too
|
|
3829
|
+
const current = this.session.model;
|
|
3830
|
+
if (current && current.provider === provider && current.id === modelId) {
|
|
3831
|
+
this.session.setThinkingLevel(level);
|
|
3832
|
+
this.footer.invalidate();
|
|
3833
|
+
this.updateEditorBorderColor();
|
|
3834
|
+
}
|
|
3835
|
+
},
|
|
3836
|
+
onModelThinkingLevelRemove: (provider, modelId) => {
|
|
3837
|
+
this.settingsManager.removeModelThinkingLevel(provider, modelId);
|
|
3838
|
+
// If the override was for the current model, revert to global default
|
|
3839
|
+
const current = this.session.model;
|
|
3840
|
+
if (current && current.provider === provider && current.id === modelId) {
|
|
3841
|
+
const globalDefault = this.settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL;
|
|
3842
|
+
this.session.setThinkingLevel(globalDefault);
|
|
3843
|
+
this.footer.invalidate();
|
|
3844
|
+
this.updateEditorBorderColor();
|
|
3845
|
+
}
|
|
3825
3846
|
},
|
|
3826
3847
|
onThemeChange: (themeSetting) => {
|
|
3827
3848
|
this.settingsManager.setTheme(themeSetting);
|
|
@@ -3942,6 +3963,44 @@ export class InteractiveMode {
|
|
|
3942
3963
|
return { component: selector, focus: selector.getSettingsList() };
|
|
3943
3964
|
});
|
|
3944
3965
|
}
|
|
3966
|
+
handleThinkingCommand(searchTerm) {
|
|
3967
|
+
const availableLevels = this.session.getAvailableThinkingLevels();
|
|
3968
|
+
if (!searchTerm) {
|
|
3969
|
+
this.showThinkingSelector();
|
|
3970
|
+
return;
|
|
3971
|
+
}
|
|
3972
|
+
const normalized = searchTerm.trim().toLowerCase();
|
|
3973
|
+
const level = availableLevels.find((candidate) => candidate.toLowerCase() === normalized);
|
|
3974
|
+
if (!level) {
|
|
3975
|
+
this.showError(`Unknown thinking level "${searchTerm}". Available levels: ${availableLevels.join(", ")}.`);
|
|
3976
|
+
return;
|
|
3977
|
+
}
|
|
3978
|
+
this.selectThinkingLevel(level, false);
|
|
3979
|
+
}
|
|
3980
|
+
selectThinkingLevel(level, persist) {
|
|
3981
|
+
try {
|
|
3982
|
+
this.session.setThinkingLevel(level, { persist });
|
|
3983
|
+
this.footer.invalidate();
|
|
3984
|
+
this.updateEditorBorderColor();
|
|
3985
|
+
this.showStatus(persist ? `Default thinking level: ${level}` : `Thinking level: ${level}`);
|
|
3986
|
+
}
|
|
3987
|
+
catch (error) {
|
|
3988
|
+
this.showError(error instanceof Error ? error.message : String(error));
|
|
3989
|
+
}
|
|
3990
|
+
}
|
|
3991
|
+
showThinkingSelector() {
|
|
3992
|
+
this.showSelector((done) => {
|
|
3993
|
+
const selectLevel = (level, persist) => {
|
|
3994
|
+
this.selectThinkingLevel(level, persist);
|
|
3995
|
+
done();
|
|
3996
|
+
};
|
|
3997
|
+
const selector = new ThinkingSelectorComponent(this.session.thinkingLevel ?? DEFAULT_THINKING_LEVEL, this.session.getAvailableThinkingLevels(), (level) => selectLevel(level, false), () => {
|
|
3998
|
+
done();
|
|
3999
|
+
this.ui.requestRender();
|
|
4000
|
+
}, (level) => selectLevel(level, true), this.settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL);
|
|
4001
|
+
return { component: selector, focus: selector };
|
|
4002
|
+
});
|
|
4003
|
+
}
|
|
3945
4004
|
async handleModelCommand(searchTerm) {
|
|
3946
4005
|
if (!searchTerm) {
|
|
3947
4006
|
this.showModelSelector();
|
|
@@ -3950,7 +4009,7 @@ export class InteractiveMode {
|
|
|
3950
4009
|
const model = await this.findExactModelMatch(searchTerm);
|
|
3951
4010
|
if (model) {
|
|
3952
4011
|
try {
|
|
3953
|
-
await this.session.setModel(model);
|
|
4012
|
+
await this.session.setModel(model, { persist: false });
|
|
3954
4013
|
this.footer.invalidate();
|
|
3955
4014
|
this.updateEditorBorderColor();
|
|
3956
4015
|
this.showStatus(`Model: ${model.id}`);
|
|
@@ -4079,13 +4138,13 @@ export class InteractiveMode {
|
|
|
4079
4138
|
}
|
|
4080
4139
|
showModelSelector(initialSearchInput) {
|
|
4081
4140
|
this.showSelector((done) => {
|
|
4082
|
-
const
|
|
4141
|
+
const selectModel = async (model, persist) => {
|
|
4083
4142
|
try {
|
|
4084
|
-
await this.session.setModel(model);
|
|
4143
|
+
await this.session.setModel(model, { persist });
|
|
4085
4144
|
this.footer.invalidate();
|
|
4086
4145
|
this.updateEditorBorderColor();
|
|
4087
4146
|
done();
|
|
4088
|
-
this.showStatus(`Model: ${model.id}`);
|
|
4147
|
+
this.showStatus(persist ? `Default model: ${model.provider}/${model.id}` : `Model: ${model.id}`);
|
|
4089
4148
|
void this.maybeWarnAboutAnthropicSubscriptionAuth(model);
|
|
4090
4149
|
this.checkDaxnutsEasterEgg(model);
|
|
4091
4150
|
}
|
|
@@ -4093,10 +4152,13 @@ export class InteractiveMode {
|
|
|
4093
4152
|
done();
|
|
4094
4153
|
this.showError(error instanceof Error ? error.message : String(error));
|
|
4095
4154
|
}
|
|
4096
|
-
}
|
|
4155
|
+
};
|
|
4156
|
+
const defaultProvider = this.settingsManager.getDefaultProvider();
|
|
4157
|
+
const defaultModel = this.settingsManager.getDefaultModel();
|
|
4158
|
+
const selector = new ModelSelectorComponent(this.ui, this.session.model, this.session.modelRuntime, this.session.scopedModels, (model) => selectModel(model, false), () => {
|
|
4097
4159
|
done();
|
|
4098
4160
|
this.ui.requestRender();
|
|
4099
|
-
}, initialSearchInput);
|
|
4161
|
+
}, initialSearchInput, (model) => selectModel(model, true), defaultProvider && defaultModel ? { provider: defaultProvider, id: defaultModel } : undefined);
|
|
4100
4162
|
return { component: selector, focus: selector, dispose: () => selector.dispose() };
|
|
4101
4163
|
});
|
|
4102
4164
|
}
|
|
@@ -4652,7 +4714,11 @@ export class InteractiveMode {
|
|
|
4652
4714
|
if (isUnknownModel(previousModel)) {
|
|
4653
4715
|
const availableModels = this.session.modelRuntime.getAvailableSnapshot();
|
|
4654
4716
|
const providerModels = availableModels.filter((model) => model.provider === providerId);
|
|
4655
|
-
|
|
4717
|
+
// Matches LLAMA_PROVIDER_ID from extensions/llama/provider.ts; kept inline to avoid coupling interactive mode to the built-in extension.
|
|
4718
|
+
if (providerId === "llama.cpp") {
|
|
4719
|
+
selectionError = llamaCppPostLoginGuidance(actionLabel, providerModels.length);
|
|
4720
|
+
}
|
|
4721
|
+
else if (!hasDefaultModelProvider(providerId)) {
|
|
4656
4722
|
selectionError = `${actionLabel}, but no default model is configured for provider "${providerId}". Use /model to select a model.`;
|
|
4657
4723
|
}
|
|
4658
4724
|
else if (providerModels.length === 0) {
|
|
@@ -4666,7 +4732,7 @@ export class InteractiveMode {
|
|
|
4666
4732
|
}
|
|
4667
4733
|
else {
|
|
4668
4734
|
try {
|
|
4669
|
-
await this.session.setModel(selectedModel);
|
|
4735
|
+
await this.session.setModel(selectedModel, { persist: true });
|
|
4670
4736
|
}
|
|
4671
4737
|
catch (error) {
|
|
4672
4738
|
selectedModel = undefined;
|
|
@@ -4883,25 +4949,6 @@ export class InteractiveMode {
|
|
|
4883
4949
|
this.showWarning("Wait for compaction to finish before reloading.");
|
|
4884
4950
|
return;
|
|
4885
4951
|
}
|
|
4886
|
-
const pendingPiClientUpdate = readPiClientUpdateMarker();
|
|
4887
|
-
if (pendingPiClientUpdate) {
|
|
4888
|
-
const reloadStatePath = process.env.PI_CLIENT_RELOAD_STATE_PATH;
|
|
4889
|
-
if (!reloadStatePath) {
|
|
4890
|
-
this.showWarning(`pi-client ${pendingPiClientUpdate.version} is installed. Restart pi-client to load the new runtime.`);
|
|
4891
|
-
return;
|
|
4892
|
-
}
|
|
4893
|
-
writePiClientRuntimeReloadState(reloadStatePath, {
|
|
4894
|
-
sessionId: this.sessionManager.getSessionId(),
|
|
4895
|
-
sessionDir: this.sessionManager.usesDefaultSessionDir() ? undefined : this.sessionManager.getSessionDir(),
|
|
4896
|
-
updateMarkerPath: getPiClientUpdateMarkerPath(),
|
|
4897
|
-
});
|
|
4898
|
-
this.isShuttingDown = true;
|
|
4899
|
-
this.themeController.disableAutoSync();
|
|
4900
|
-
await this.ui.terminal.drainInput(1000);
|
|
4901
|
-
this.stop();
|
|
4902
|
-
await this.runtimeHost.dispose();
|
|
4903
|
-
process.exit(PI_CLIENT_RUNTIME_RELOAD_EXIT_CODE);
|
|
4904
|
-
}
|
|
4905
4952
|
this.resetExtensionUI();
|
|
4906
4953
|
const reloadBox = new Container();
|
|
4907
4954
|
const borderColor = (s) => theme.fg("border", s);
|
|
@@ -5055,91 +5102,14 @@ export class InteractiveMode {
|
|
|
5055
5102
|
}
|
|
5056
5103
|
}
|
|
5057
5104
|
async handleShareCommand() {
|
|
5058
|
-
|
|
5059
|
-
|
|
5060
|
-
|
|
5061
|
-
|
|
5062
|
-
|
|
5063
|
-
|
|
5064
|
-
|
|
5065
|
-
}
|
|
5066
|
-
catch {
|
|
5067
|
-
this.showError("GitHub CLI (gh) is not installed. Install it from https://cli.github.com/");
|
|
5068
|
-
return;
|
|
5069
|
-
}
|
|
5070
|
-
// Export to a temp file
|
|
5071
|
-
const tmpFile = path.join(os.tmpdir(), "session.html");
|
|
5072
|
-
try {
|
|
5073
|
-
await this.session.exportToHtml(tmpFile, { themeName: theme.name });
|
|
5074
|
-
}
|
|
5075
|
-
catch (error) {
|
|
5076
|
-
this.showError(`Failed to export session: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
5077
|
-
return;
|
|
5078
|
-
}
|
|
5079
|
-
// Show cancellable loader, replacing the editor
|
|
5080
|
-
const loader = new BorderedLoader(this.ui, theme, "Creating gist...");
|
|
5081
|
-
this.editorContainer.clear();
|
|
5082
|
-
this.editorContainer.addChild(loader);
|
|
5083
|
-
this.ui.setFocus(loader);
|
|
5084
|
-
this.ui.requestRender();
|
|
5085
|
-
const restoreEditor = () => {
|
|
5086
|
-
loader.dispose();
|
|
5087
|
-
this.editorContainer.clear();
|
|
5088
|
-
this.editorContainer.addChild(this.editor);
|
|
5089
|
-
this.ui.setFocus(this.editor);
|
|
5090
|
-
try {
|
|
5091
|
-
fs.unlinkSync(tmpFile);
|
|
5092
|
-
}
|
|
5093
|
-
catch {
|
|
5094
|
-
// Ignore cleanup errors
|
|
5095
|
-
}
|
|
5096
|
-
};
|
|
5097
|
-
// Create a secret gist asynchronously
|
|
5098
|
-
let proc = null;
|
|
5099
|
-
loader.onAbort = () => {
|
|
5100
|
-
proc?.kill();
|
|
5101
|
-
restoreEditor();
|
|
5102
|
-
this.showStatus("Share cancelled");
|
|
5103
|
-
};
|
|
5104
|
-
try {
|
|
5105
|
-
const result = await new Promise((resolve) => {
|
|
5106
|
-
proc = spawn("gh", ["gist", "create", "--public=false", tmpFile]);
|
|
5107
|
-
let stdout = "";
|
|
5108
|
-
let stderr = "";
|
|
5109
|
-
proc.stdout?.on("data", (data) => {
|
|
5110
|
-
stdout += data.toString();
|
|
5111
|
-
});
|
|
5112
|
-
proc.stderr?.on("data", (data) => {
|
|
5113
|
-
stderr += data.toString();
|
|
5114
|
-
});
|
|
5115
|
-
proc.on("close", (code) => resolve({ stdout, stderr, code }));
|
|
5116
|
-
});
|
|
5117
|
-
if (loader.signal.aborted)
|
|
5118
|
-
return;
|
|
5119
|
-
restoreEditor();
|
|
5120
|
-
if (result.code !== 0) {
|
|
5121
|
-
const errorMsg = result.stderr?.trim() || "Unknown error";
|
|
5122
|
-
this.showError(`Failed to create gist: ${errorMsg}`);
|
|
5123
|
-
return;
|
|
5124
|
-
}
|
|
5125
|
-
// Extract gist ID from the URL returned by gh
|
|
5126
|
-
// gh returns something like: https://gist.github.com/username/GIST_ID
|
|
5127
|
-
const gistUrl = result.stdout?.trim();
|
|
5128
|
-
const gistId = gistUrl?.split("/").pop();
|
|
5129
|
-
if (!gistId) {
|
|
5130
|
-
this.showError("Failed to parse gist ID from gh output");
|
|
5131
|
-
return;
|
|
5132
|
-
}
|
|
5133
|
-
// Create the preview URL
|
|
5134
|
-
const previewUrl = getShareViewerUrl(gistId);
|
|
5135
|
-
this.showStatus(`Share URL: ${previewUrl}\nGist: ${gistUrl}`);
|
|
5136
|
-
}
|
|
5137
|
-
catch (error) {
|
|
5138
|
-
if (!loader.signal.aborted) {
|
|
5139
|
-
restoreEditor();
|
|
5140
|
-
this.showError(`Failed to create gist: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
5141
|
-
}
|
|
5142
|
-
}
|
|
5105
|
+
await shareSession({
|
|
5106
|
+
session: this.session,
|
|
5107
|
+
ui: this.ui,
|
|
5108
|
+
editorContainer: this.editorContainer,
|
|
5109
|
+
editor: this.editor,
|
|
5110
|
+
showStatus: (message) => this.showStatus(message),
|
|
5111
|
+
showError: (message) => this.showError(message),
|
|
5112
|
+
});
|
|
5143
5113
|
}
|
|
5144
5114
|
async handleCopyCommand(options = {}) {
|
|
5145
5115
|
const text = this.session.getLastAssistantText();
|