@astralyn/pi 0.84.9 → 0.84.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -2
- package/README.md +3 -2
- 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 +26 -7
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +83 -64
- 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/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js +3 -0
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +4 -3
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +41 -32
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/compaction-controller.d.ts +2 -1
- package/dist/core/compaction-controller.d.ts.map +1 -1
- package/dist/core/compaction-controller.js +64 -21
- package/dist/core/compaction-controller.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/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.js +1 -1
- package/dist/core/footer-data-provider.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-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/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 +4 -3
- 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 +51 -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 +19 -1
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +59 -37
- 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/background/registry.d.ts +2 -3
- package/dist/extensions/background/registry.d.ts.map +1 -1
- package/dist/extensions/background/registry.js +2 -6
- package/dist/extensions/background/registry.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.map +1 -1
- package/dist/extensions/llama/provider.js +6 -2
- package/dist/extensions/llama/provider.js.map +1 -1
- package/dist/extensions/question/types.d.ts +0 -1
- package/dist/extensions/question/types.d.ts.map +1 -1
- package/dist/extensions/question/types.js +1 -1
- package/dist/extensions/question/types.js.map +1 -1
- package/dist/extensions/router/register.d.ts +0 -1
- package/dist/extensions/router/register.d.ts.map +1 -1
- package/dist/extensions/router/register.js +0 -3
- package/dist/extensions/router/register.js.map +1 -1
- package/dist/extensions/router/stream.d.ts +0 -2
- package/dist/extensions/router/stream.d.ts.map +1 -1
- package/dist/extensions/router/stream.js +1 -12
- package/dist/extensions/router/stream.js.map +1 -1
- package/dist/extensions/subagent/constants.d.ts +1 -1
- package/dist/extensions/subagent/constants.js +1 -1
- package/dist/extensions/subagent/constants.js.map +1 -1
- package/dist/extensions/subagent/index.js +2 -2
- package/dist/extensions/subagent/index.js.map +1 -1
- package/dist/extensions/subagent/render.d.ts +5 -5
- package/dist/extensions/subagent/render.d.ts.map +1 -1
- package/dist/extensions/subagent/render.js +92 -36
- package/dist/extensions/subagent/render.js.map +1 -1
- package/dist/extensions/subagent/text.d.ts +0 -1
- package/dist/extensions/subagent/text.d.ts.map +1 -1
- package/dist/extensions/subagent/text.js +1 -30
- package/dist/extensions/subagent/text.js.map +1 -1
- package/dist/extensions/subagent/ui/model-list.d.ts +0 -3
- package/dist/extensions/subagent/ui/model-list.d.ts.map +1 -1
- package/dist/extensions/subagent/ui/model-list.js +1 -10
- package/dist/extensions/subagent/ui/model-list.js.map +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -4
- 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 +18 -15
- package/dist/main.js.map +1 -1
- package/dist/migrations.js +5 -5
- package/dist/migrations.js.map +1 -1
- package/dist/modes/interactive/components/index.d.ts +0 -1
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/index.js +0 -1
- package/dist/modes/interactive/components/index.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 +54 -11
- 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 -55
- 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 +151 -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 +68 -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 +11 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +167 -105
- 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 +3 -2
- 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/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/paths.d.ts +0 -5
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +0 -7
- package/dist/utils/paths.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 +17 -5
- package/dist/utils/shell.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/docs/bundled/extensions/subagent.md +1 -1
- package/docs/compaction.md +19 -2
- package/docs/custom-provider.md +5 -2
- package/docs/environment-variables.md +8 -8
- package/docs/extensions.md +22 -10
- package/docs/json.md +7 -2
- package/docs/keybindings.md +10 -8
- package/docs/llama-cpp.md +6 -4
- package/docs/models.md +10 -3
- package/docs/packages.md +2 -1
- package/docs/rpc.md +9 -3
- package/docs/sdk.md +12 -2
- package/docs/settings.md +16 -5
- package/docs/skills.md +5 -4
- 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/doom-overlay/doom/build/doom.wasm +0 -0
- package/examples/extensions/doom-overlay/doom/build.sh +0 -0
- 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/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/npm-shrinkwrap.json +196 -257
- package/package.json +6 -8
|
@@ -9,11 +9,12 @@ import * as path from "node:path";
|
|
|
9
9
|
import * as TuiLayouts from "@earendil-works/pi-tui";
|
|
10
10
|
import { CombinedAutocompleteProvider, Container, fuzzyFilter, 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, INSTALL_TELEMETRY_URL, UPDATE_CHANGELOG_HINT, 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";
|
|
@@ -40,7 +41,6 @@ import { checkForNewPiVersion } from "../../utils/version-check.js";
|
|
|
40
41
|
import { ArminComponent } from "./components/armin.js";
|
|
41
42
|
import { AssistantMessageComponent } from "./components/assistant-message.js";
|
|
42
43
|
import { BashExecutionComponent } from "./components/bash-execution.js";
|
|
43
|
-
import { BorderedLoader } from "./components/bordered-loader.js";
|
|
44
44
|
import { BranchSummaryMessageComponent } from "./components/branch-summary-message.js";
|
|
45
45
|
import { CompactionSummaryMessageComponent } from "./components/compaction-summary-message.js";
|
|
46
46
|
import { CustomEditor } from "./components/custom-editor.js";
|
|
@@ -63,6 +63,7 @@ import { SessionSelectorComponent } from "./components/session-selector.js";
|
|
|
63
63
|
import { SettingsSelectorComponent } from "./components/settings-selector.js";
|
|
64
64
|
import { SkillInvocationMessageComponent } from "./components/skill-invocation-message.js";
|
|
65
65
|
import { BranchSummaryStatusIndicator, CompactionStatusIndicator, IdleStatus, RetryStatusIndicator, WorkingStatusIndicator, } from "./components/status-indicator.js";
|
|
66
|
+
import { ThinkingSelectorComponent } from "./components/thinking-selector.js";
|
|
66
67
|
import { ToolExecutionComponent } from "./components/tool-execution.js";
|
|
67
68
|
import { ToolGroupComponent } from "./components/tool-group.js";
|
|
68
69
|
import { TreeSelectorComponent } from "./components/tree-selector.js";
|
|
@@ -72,6 +73,7 @@ import { UserMessageSelectorComponent } from "./components/user-message-selector
|
|
|
72
73
|
import { editInExternalEditor } from "./external-editor.js";
|
|
73
74
|
import { refreshModelCatalogs } from "./model-catalog-refresh.js";
|
|
74
75
|
import { getModelSearchText } from "./model-search.js";
|
|
76
|
+
import { shareSession } from "./session-share.js";
|
|
75
77
|
import { getAvailableThemes, getAvailableThemesWithPaths, getEditorTheme, getMarkdownTheme, getThemeByName, onThemeChange, setRegisteredThemes, stopThemeWatcher, Theme, theme, } from "./theme/theme.js";
|
|
76
78
|
import { InteractiveThemeController } from "./theme/theme-controller.js";
|
|
77
79
|
function isExpandable(obj) {
|
|
@@ -90,6 +92,9 @@ class ExpandableText extends Text {
|
|
|
90
92
|
function isCustomSessionEntry(item) {
|
|
91
93
|
return "type" in item && item.type === "custom";
|
|
92
94
|
}
|
|
95
|
+
function isCompactionCostNotice(item) {
|
|
96
|
+
return "type" in item && item.type === "compaction_cost";
|
|
97
|
+
}
|
|
93
98
|
const DEAD_TERMINAL_ERROR_CODES = new Set(["EIO", "EPIPE", "ENOTCONN"]);
|
|
94
99
|
function isDeadTerminalError(error) {
|
|
95
100
|
if (!error || typeof error !== "object" || !("code" in error)) {
|
|
@@ -129,6 +134,11 @@ export function formatResumeCommand(sessionManager) {
|
|
|
129
134
|
function hasDefaultModelProvider(providerId) {
|
|
130
135
|
return providerId in defaultModelPerProvider;
|
|
131
136
|
}
|
|
137
|
+
function llamaCppPostLoginGuidance(actionLabel, loadedModelCount) {
|
|
138
|
+
return loadedModelCount === 0
|
|
139
|
+
? `${actionLabel}. No llama.cpp models are loaded. Use /llama to load a model, then /model to select it.`
|
|
140
|
+
: `${actionLabel}. Use /model to select a loaded llama.cpp model, or /llama to manage models.`;
|
|
141
|
+
}
|
|
132
142
|
const AUTH_TYPE_ORDER = { oauth: 0, api_key: 1 };
|
|
133
143
|
function createFuzzyAutocompleteItems(items, prefix, getSearchText, toAutocompleteItem) {
|
|
134
144
|
const filtered = fuzzyFilter(items, prefix, getSearchText);
|
|
@@ -435,6 +445,15 @@ export class InteractiveMode {
|
|
|
435
445
|
}));
|
|
436
446
|
};
|
|
437
447
|
}
|
|
448
|
+
const thinkingCommand = slashCommands.find((command) => command.name === "thinking");
|
|
449
|
+
if (thinkingCommand) {
|
|
450
|
+
thinkingCommand.getArgumentCompletions = (prefix) => {
|
|
451
|
+
return createFuzzyAutocompleteItems(this.session.getAvailableThinkingLevels(), prefix, (level) => level, (level) => ({
|
|
452
|
+
value: level,
|
|
453
|
+
label: level,
|
|
454
|
+
}));
|
|
455
|
+
};
|
|
456
|
+
}
|
|
438
457
|
const loginCommand = slashCommands.find((command) => command.name === "login");
|
|
439
458
|
if (loginCommand) {
|
|
440
459
|
loginCommand.getArgumentCompletions = (prefix) => {
|
|
@@ -774,7 +793,18 @@ export class InteractiveMode {
|
|
|
774
793
|
}
|
|
775
794
|
});
|
|
776
795
|
// Show startup warnings
|
|
777
|
-
const { migratedProviders, modelFallbackMessage, initialMessage, initialImages, initialMessages } = this.options;
|
|
796
|
+
const { migratedProviders, startupDiagnostics, modelFallbackMessage, initialMessage, initialImages, initialMessages, } = this.options;
|
|
797
|
+
for (const diagnostic of startupDiagnostics ?? []) {
|
|
798
|
+
if (diagnostic.type === "error") {
|
|
799
|
+
this.showError(diagnostic.message);
|
|
800
|
+
}
|
|
801
|
+
else if (diagnostic.type === "warning") {
|
|
802
|
+
this.showWarning(diagnostic.message);
|
|
803
|
+
}
|
|
804
|
+
else {
|
|
805
|
+
this.showStatus(diagnostic.message);
|
|
806
|
+
}
|
|
807
|
+
}
|
|
778
808
|
if (migratedProviders && migratedProviders.length > 0) {
|
|
779
809
|
this.showWarning(`Migrated credentials to auth.json: ${migratedProviders.join(", ")}`);
|
|
780
810
|
}
|
|
@@ -2373,6 +2403,12 @@ export class InteractiveMode {
|
|
|
2373
2403
|
await this.handleModelCommand(searchTerm);
|
|
2374
2404
|
return;
|
|
2375
2405
|
}
|
|
2406
|
+
if (text === "/thinking" || text.startsWith("/thinking ")) {
|
|
2407
|
+
const searchTerm = text.startsWith("/thinking ") ? text.slice(10).trim() : undefined;
|
|
2408
|
+
this.editor.setText("");
|
|
2409
|
+
this.handleThinkingCommand(searchTerm);
|
|
2410
|
+
return;
|
|
2411
|
+
}
|
|
2376
2412
|
if (text === "/export" || text.startsWith("/export ")) {
|
|
2377
2413
|
await this.handleExportCommand(text);
|
|
2378
2414
|
this.editor.setText("");
|
|
@@ -2755,8 +2791,21 @@ export class InteractiveMode {
|
|
|
2755
2791
|
}
|
|
2756
2792
|
else {
|
|
2757
2793
|
if (event.result) {
|
|
2758
|
-
this.
|
|
2794
|
+
const entries = this.sessionManager.buildContextEntries();
|
|
2795
|
+
if (entries[0]?.type !== "compaction") {
|
|
2796
|
+
throw new Error("Completed compaction is missing from the session context");
|
|
2797
|
+
}
|
|
2798
|
+
this.clearChat();
|
|
2799
|
+
// The latest compaction is prepended for model context; append it below at its chronological position.
|
|
2800
|
+
this.renderSessionEntries(entries.slice(1));
|
|
2759
2801
|
this.addMessageToChat(createCompactionSummaryMessage(event.result.summary, event.result.tokensBefore, new Date().toISOString()));
|
|
2802
|
+
if (event.result.usage) {
|
|
2803
|
+
this.addCompactionCostNotice({
|
|
2804
|
+
type: "compaction_cost",
|
|
2805
|
+
kind: "compaction",
|
|
2806
|
+
usage: event.result.usage,
|
|
2807
|
+
});
|
|
2808
|
+
}
|
|
2760
2809
|
this.footer.invalidate();
|
|
2761
2810
|
}
|
|
2762
2811
|
if (event.errorMessage) {
|
|
@@ -2979,6 +3028,10 @@ export class InteractiveMode {
|
|
|
2979
3028
|
this.addCustomEntryToChat(item);
|
|
2980
3029
|
continue;
|
|
2981
3030
|
}
|
|
3031
|
+
if (isCompactionCostNotice(item)) {
|
|
3032
|
+
this.addCompactionCostNotice(item);
|
|
3033
|
+
continue;
|
|
3034
|
+
}
|
|
2982
3035
|
const message = item;
|
|
2983
3036
|
// Assistant messages need special handling for tool calls
|
|
2984
3037
|
if (message.role === "assistant") {
|
|
@@ -3042,10 +3095,28 @@ export class InteractiveMode {
|
|
|
3042
3095
|
if (entry.type === "custom") {
|
|
3043
3096
|
return [entry];
|
|
3044
3097
|
}
|
|
3045
|
-
|
|
3098
|
+
const messages = sessionEntryToContextMessages(entry);
|
|
3099
|
+
if ((entry.type === "compaction" || entry.type === "branch_summary") && entry.usage && messages.length > 0) {
|
|
3100
|
+
return [...messages, { type: "compaction_cost", kind: entry.type, usage: entry.usage }];
|
|
3101
|
+
}
|
|
3102
|
+
return messages;
|
|
3046
3103
|
});
|
|
3047
3104
|
this.renderSessionItems(items, options);
|
|
3048
3105
|
}
|
|
3106
|
+
/**
|
|
3107
|
+
* Render billing usage for a compaction or branch summary. The notice is derived
|
|
3108
|
+
* from persisted summary usage and is not stored as a separate session entry.
|
|
3109
|
+
*/
|
|
3110
|
+
addCompactionCostNotice(notice) {
|
|
3111
|
+
if (!this.settingsManager.getShowCacheMissNotices())
|
|
3112
|
+
return;
|
|
3113
|
+
const { usage } = notice;
|
|
3114
|
+
const tokens = usage.input + usage.output + usage.cacheRead + usage.cacheWrite;
|
|
3115
|
+
const cost = usage.cost.total >= 0.01 ? ` (~$${usage.cost.total.toFixed(2)})` : "";
|
|
3116
|
+
const label = notice.kind === "compaction" ? "Compaction" : "Branch summary";
|
|
3117
|
+
this.chatContainer.addChild(new Spacer(1));
|
|
3118
|
+
this.chatContainer.addChild(new Text(theme.fg("warning", `${label}: ${formatTokens(tokens)} tokens billed${cost}`), 1, 0));
|
|
3119
|
+
}
|
|
3049
3120
|
/**
|
|
3050
3121
|
* Show a transcript notice when a completed assistant message paid for a
|
|
3051
3122
|
* significant cache miss. Only states observable facts: the miss itself,
|
|
@@ -3678,8 +3749,14 @@ export class InteractiveMode {
|
|
|
3678
3749
|
showSettingsSelector() {
|
|
3679
3750
|
this.showSelector((done) => {
|
|
3680
3751
|
let selector;
|
|
3752
|
+
const defaultProvider = this.settingsManager.getDefaultProvider();
|
|
3753
|
+
const defaultModelId = this.settingsManager.getDefaultModel();
|
|
3754
|
+
const defaultModel = defaultProvider && defaultModelId ? `${defaultProvider}/${defaultModelId}` : "not set";
|
|
3681
3755
|
selector = new SettingsSelectorComponent({
|
|
3682
3756
|
autoCompact: this.session.autoCompactionEnabled,
|
|
3757
|
+
defaultModel,
|
|
3758
|
+
currentModel: this.session.model,
|
|
3759
|
+
availableDefaultModels: this.session.modelRuntime.getAvailableSnapshot(),
|
|
3683
3760
|
showImages: this.settingsManager.getShowImages(),
|
|
3684
3761
|
imageWidthCells: this.settingsManager.getImageWidthCells(),
|
|
3685
3762
|
autoResizeImages: this.settingsManager.getImageAutoResize(),
|
|
@@ -3689,8 +3766,9 @@ export class InteractiveMode {
|
|
|
3689
3766
|
followUpMode: this.session.followUpMode,
|
|
3690
3767
|
transport: this.settingsManager.getTransport(),
|
|
3691
3768
|
httpIdleTimeoutMs: this.settingsManager.getHttpIdleTimeoutMs(),
|
|
3692
|
-
thinkingLevel: this.
|
|
3693
|
-
availableThinkingLevels:
|
|
3769
|
+
thinkingLevel: this.settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL,
|
|
3770
|
+
availableThinkingLevels: [...THINKING_LEVEL_OPTIONS],
|
|
3771
|
+
modelThinkingLevels: this.settingsManager.getAllModelThinkingLevels(),
|
|
3694
3772
|
currentTheme: this.themeController.getThemeSelection() || "dark",
|
|
3695
3773
|
terminalTheme: this.themeController.getTerminalTheme(),
|
|
3696
3774
|
availableThemes: getAvailableThemes(),
|
|
@@ -3759,10 +3837,26 @@ export class InteractiveMode {
|
|
|
3759
3837
|
configureHttpDispatcher(timeoutMs);
|
|
3760
3838
|
this.showStatus(`HTTP idle timeout: ${formatHttpIdleTimeoutMs(timeoutMs)}`);
|
|
3761
3839
|
},
|
|
3762
|
-
|
|
3763
|
-
this.
|
|
3764
|
-
|
|
3765
|
-
this.
|
|
3840
|
+
onModelThinkingLevelChange: (provider, modelId, level) => {
|
|
3841
|
+
this.settingsManager.setModelThinkingLevel(provider, modelId, level);
|
|
3842
|
+
// If the override is for the current model, apply it to the session too
|
|
3843
|
+
const current = this.session.model;
|
|
3844
|
+
if (current && current.provider === provider && current.id === modelId) {
|
|
3845
|
+
this.session.setThinkingLevel(level);
|
|
3846
|
+
this.footer.invalidate();
|
|
3847
|
+
this.updateEditorBorderColor();
|
|
3848
|
+
}
|
|
3849
|
+
},
|
|
3850
|
+
onModelThinkingLevelRemove: (provider, modelId) => {
|
|
3851
|
+
this.settingsManager.removeModelThinkingLevel(provider, modelId);
|
|
3852
|
+
// If the override was for the current model, revert to global default
|
|
3853
|
+
const current = this.session.model;
|
|
3854
|
+
if (current && current.provider === provider && current.id === modelId) {
|
|
3855
|
+
const globalDefault = this.settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL;
|
|
3856
|
+
this.session.setThinkingLevel(globalDefault);
|
|
3857
|
+
this.footer.invalidate();
|
|
3858
|
+
this.updateEditorBorderColor();
|
|
3859
|
+
}
|
|
3766
3860
|
},
|
|
3767
3861
|
onThemeChange: (themeSetting) => {
|
|
3768
3862
|
this.settingsManager.setTheme(themeSetting);
|
|
@@ -3882,6 +3976,44 @@ export class InteractiveMode {
|
|
|
3882
3976
|
return { component: selector, focus: selector.getSettingsList() };
|
|
3883
3977
|
});
|
|
3884
3978
|
}
|
|
3979
|
+
handleThinkingCommand(searchTerm) {
|
|
3980
|
+
const availableLevels = this.session.getAvailableThinkingLevels();
|
|
3981
|
+
if (!searchTerm) {
|
|
3982
|
+
this.showThinkingSelector();
|
|
3983
|
+
return;
|
|
3984
|
+
}
|
|
3985
|
+
const normalized = searchTerm.trim().toLowerCase();
|
|
3986
|
+
const level = availableLevels.find((candidate) => candidate.toLowerCase() === normalized);
|
|
3987
|
+
if (!level) {
|
|
3988
|
+
this.showError(`Unknown thinking level "${searchTerm}". Available levels: ${availableLevels.join(", ")}.`);
|
|
3989
|
+
return;
|
|
3990
|
+
}
|
|
3991
|
+
this.selectThinkingLevel(level, false);
|
|
3992
|
+
}
|
|
3993
|
+
selectThinkingLevel(level, persist) {
|
|
3994
|
+
try {
|
|
3995
|
+
this.session.setThinkingLevel(level, { persist });
|
|
3996
|
+
this.footer.invalidate();
|
|
3997
|
+
this.updateEditorBorderColor();
|
|
3998
|
+
this.showStatus(persist ? `Default thinking level: ${level}` : `Thinking level: ${level}`);
|
|
3999
|
+
}
|
|
4000
|
+
catch (error) {
|
|
4001
|
+
this.showError(error instanceof Error ? error.message : String(error));
|
|
4002
|
+
}
|
|
4003
|
+
}
|
|
4004
|
+
showThinkingSelector() {
|
|
4005
|
+
this.showSelector((done) => {
|
|
4006
|
+
const selectLevel = (level, persist) => {
|
|
4007
|
+
this.selectThinkingLevel(level, persist);
|
|
4008
|
+
done();
|
|
4009
|
+
};
|
|
4010
|
+
const selector = new ThinkingSelectorComponent(this.session.thinkingLevel ?? DEFAULT_THINKING_LEVEL, this.session.getAvailableThinkingLevels(), (level) => selectLevel(level, false), () => {
|
|
4011
|
+
done();
|
|
4012
|
+
this.ui.requestRender();
|
|
4013
|
+
}, (level) => selectLevel(level, true), this.settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL);
|
|
4014
|
+
return { component: selector, focus: selector };
|
|
4015
|
+
});
|
|
4016
|
+
}
|
|
3885
4017
|
async handleModelCommand(searchTerm) {
|
|
3886
4018
|
if (!searchTerm) {
|
|
3887
4019
|
this.showModelSelector();
|
|
@@ -3890,7 +4022,7 @@ export class InteractiveMode {
|
|
|
3890
4022
|
const model = await this.findExactModelMatch(searchTerm);
|
|
3891
4023
|
if (model) {
|
|
3892
4024
|
try {
|
|
3893
|
-
await this.session.setModel(model);
|
|
4025
|
+
await this.session.setModel(model, { persist: false });
|
|
3894
4026
|
this.footer.invalidate();
|
|
3895
4027
|
this.updateEditorBorderColor();
|
|
3896
4028
|
this.showStatus(`Model: ${model.id}`);
|
|
@@ -4019,13 +4151,13 @@ export class InteractiveMode {
|
|
|
4019
4151
|
}
|
|
4020
4152
|
showModelSelector(initialSearchInput) {
|
|
4021
4153
|
this.showSelector((done) => {
|
|
4022
|
-
const
|
|
4154
|
+
const selectModel = async (model, persist) => {
|
|
4023
4155
|
try {
|
|
4024
|
-
await this.session.setModel(model);
|
|
4156
|
+
await this.session.setModel(model, { persist });
|
|
4025
4157
|
this.footer.invalidate();
|
|
4026
4158
|
this.updateEditorBorderColor();
|
|
4027
4159
|
done();
|
|
4028
|
-
this.showStatus(`Model: ${model.id}`);
|
|
4160
|
+
this.showStatus(persist ? `Default model: ${model.provider}/${model.id}` : `Model: ${model.id}`);
|
|
4029
4161
|
void this.maybeWarnAboutAnthropicSubscriptionAuth(model);
|
|
4030
4162
|
this.checkDaxnutsEasterEgg(model);
|
|
4031
4163
|
}
|
|
@@ -4033,10 +4165,13 @@ export class InteractiveMode {
|
|
|
4033
4165
|
done();
|
|
4034
4166
|
this.showError(error instanceof Error ? error.message : String(error));
|
|
4035
4167
|
}
|
|
4036
|
-
}
|
|
4168
|
+
};
|
|
4169
|
+
const defaultProvider = this.settingsManager.getDefaultProvider();
|
|
4170
|
+
const defaultModel = this.settingsManager.getDefaultModel();
|
|
4171
|
+
const selector = new ModelSelectorComponent(this.ui, this.session.model, this.session.modelRuntime, this.session.scopedModels, (model) => selectModel(model, false), () => {
|
|
4037
4172
|
done();
|
|
4038
4173
|
this.ui.requestRender();
|
|
4039
|
-
}, initialSearchInput);
|
|
4174
|
+
}, initialSearchInput, (model) => selectModel(model, true), defaultProvider && defaultModel ? { provider: defaultProvider, id: defaultModel } : undefined);
|
|
4040
4175
|
return { component: selector, focus: selector, dispose: () => selector.dispose() };
|
|
4041
4176
|
});
|
|
4042
4177
|
}
|
|
@@ -4592,7 +4727,11 @@ export class InteractiveMode {
|
|
|
4592
4727
|
if (isUnknownModel(previousModel)) {
|
|
4593
4728
|
const availableModels = this.session.modelRuntime.getAvailableSnapshot();
|
|
4594
4729
|
const providerModels = availableModels.filter((model) => model.provider === providerId);
|
|
4595
|
-
|
|
4730
|
+
// Matches LLAMA_PROVIDER_ID from extensions/llama/provider.ts; kept inline to avoid coupling interactive mode to the built-in extension.
|
|
4731
|
+
if (providerId === "llama.cpp") {
|
|
4732
|
+
selectionError = llamaCppPostLoginGuidance(actionLabel, providerModels.length);
|
|
4733
|
+
}
|
|
4734
|
+
else if (!hasDefaultModelProvider(providerId)) {
|
|
4596
4735
|
selectionError = `${actionLabel}, but no default model is configured for provider "${providerId}". Use /model to select a model.`;
|
|
4597
4736
|
}
|
|
4598
4737
|
else if (providerModels.length === 0) {
|
|
@@ -4606,7 +4745,7 @@ export class InteractiveMode {
|
|
|
4606
4745
|
}
|
|
4607
4746
|
else {
|
|
4608
4747
|
try {
|
|
4609
|
-
await this.session.setModel(selectedModel);
|
|
4748
|
+
await this.session.setModel(selectedModel, { persist: true });
|
|
4610
4749
|
}
|
|
4611
4750
|
catch (error) {
|
|
4612
4751
|
selectedModel = undefined;
|
|
@@ -4976,91 +5115,14 @@ export class InteractiveMode {
|
|
|
4976
5115
|
}
|
|
4977
5116
|
}
|
|
4978
5117
|
async handleShareCommand() {
|
|
4979
|
-
|
|
4980
|
-
|
|
4981
|
-
|
|
4982
|
-
|
|
4983
|
-
|
|
4984
|
-
|
|
4985
|
-
|
|
4986
|
-
}
|
|
4987
|
-
catch {
|
|
4988
|
-
this.showError("GitHub CLI (gh) is not installed. Install it from https://cli.github.com/");
|
|
4989
|
-
return;
|
|
4990
|
-
}
|
|
4991
|
-
// Export to a temp file
|
|
4992
|
-
const tmpFile = path.join(os.tmpdir(), "session.html");
|
|
4993
|
-
try {
|
|
4994
|
-
await this.session.exportToHtml(tmpFile, { themeName: theme.name });
|
|
4995
|
-
}
|
|
4996
|
-
catch (error) {
|
|
4997
|
-
this.showError(`Failed to export session: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
4998
|
-
return;
|
|
4999
|
-
}
|
|
5000
|
-
// Show cancellable loader, replacing the editor
|
|
5001
|
-
const loader = new BorderedLoader(this.ui, theme, "Creating gist...");
|
|
5002
|
-
this.editorContainer.clear();
|
|
5003
|
-
this.editorContainer.addChild(loader);
|
|
5004
|
-
this.ui.setFocus(loader);
|
|
5005
|
-
this.ui.requestRender();
|
|
5006
|
-
const restoreEditor = () => {
|
|
5007
|
-
loader.dispose();
|
|
5008
|
-
this.editorContainer.clear();
|
|
5009
|
-
this.editorContainer.addChild(this.editor);
|
|
5010
|
-
this.ui.setFocus(this.editor);
|
|
5011
|
-
try {
|
|
5012
|
-
fs.unlinkSync(tmpFile);
|
|
5013
|
-
}
|
|
5014
|
-
catch {
|
|
5015
|
-
// Ignore cleanup errors
|
|
5016
|
-
}
|
|
5017
|
-
};
|
|
5018
|
-
// Create a secret gist asynchronously
|
|
5019
|
-
let proc = null;
|
|
5020
|
-
loader.onAbort = () => {
|
|
5021
|
-
proc?.kill();
|
|
5022
|
-
restoreEditor();
|
|
5023
|
-
this.showStatus("Share cancelled");
|
|
5024
|
-
};
|
|
5025
|
-
try {
|
|
5026
|
-
const result = await new Promise((resolve) => {
|
|
5027
|
-
proc = spawn("gh", ["gist", "create", "--public=false", tmpFile]);
|
|
5028
|
-
let stdout = "";
|
|
5029
|
-
let stderr = "";
|
|
5030
|
-
proc.stdout?.on("data", (data) => {
|
|
5031
|
-
stdout += data.toString();
|
|
5032
|
-
});
|
|
5033
|
-
proc.stderr?.on("data", (data) => {
|
|
5034
|
-
stderr += data.toString();
|
|
5035
|
-
});
|
|
5036
|
-
proc.on("close", (code) => resolve({ stdout, stderr, code }));
|
|
5037
|
-
});
|
|
5038
|
-
if (loader.signal.aborted)
|
|
5039
|
-
return;
|
|
5040
|
-
restoreEditor();
|
|
5041
|
-
if (result.code !== 0) {
|
|
5042
|
-
const errorMsg = result.stderr?.trim() || "Unknown error";
|
|
5043
|
-
this.showError(`Failed to create gist: ${errorMsg}`);
|
|
5044
|
-
return;
|
|
5045
|
-
}
|
|
5046
|
-
// Extract gist ID from the URL returned by gh
|
|
5047
|
-
// gh returns something like: https://gist.github.com/username/GIST_ID
|
|
5048
|
-
const gistUrl = result.stdout?.trim();
|
|
5049
|
-
const gistId = gistUrl?.split("/").pop();
|
|
5050
|
-
if (!gistId) {
|
|
5051
|
-
this.showError("Failed to parse gist ID from gh output");
|
|
5052
|
-
return;
|
|
5053
|
-
}
|
|
5054
|
-
// Create the preview URL
|
|
5055
|
-
const previewUrl = getShareViewerUrl(gistId);
|
|
5056
|
-
this.showStatus(`Share URL: ${previewUrl}\nGist: ${gistUrl}`);
|
|
5057
|
-
}
|
|
5058
|
-
catch (error) {
|
|
5059
|
-
if (!loader.signal.aborted) {
|
|
5060
|
-
restoreEditor();
|
|
5061
|
-
this.showError(`Failed to create gist: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
5062
|
-
}
|
|
5063
|
-
}
|
|
5118
|
+
await shareSession({
|
|
5119
|
+
session: this.session,
|
|
5120
|
+
ui: this.ui,
|
|
5121
|
+
editorContainer: this.editorContainer,
|
|
5122
|
+
editor: this.editor,
|
|
5123
|
+
showStatus: (message) => this.showStatus(message),
|
|
5124
|
+
showError: (message) => this.showError(message),
|
|
5125
|
+
});
|
|
5064
5126
|
}
|
|
5065
5127
|
async handleCopyCommand(options = {}) {
|
|
5066
5128
|
const text = this.session.getLastAssistantText();
|