apex-code 0.0.1-alpha.8 → 0.0.1-alpha.9
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 +83 -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 +3 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +21 -13
- 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 +163 -95
- 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/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/durable-state/sqlite.d.ts.map +1 -1
- package/dist/core/durable-state/sqlite.js +26 -2
- package/dist/core/durable-state/sqlite.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/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 +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 +53 -11
- 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 +8 -2
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tools/bash.d.ts +14 -1
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +36 -20
- 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 +9 -0
- 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/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/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.d.ts.map +1 -1
- package/dist/migrations.js +4 -3
- package/dist/migrations.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts +10 -3
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +51 -9
- 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 +11 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +164 -17
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +5 -4
- 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 +197 -5
- 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/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/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/docs/compaction.md +15 -0
- package/docs/custom-provider.md +5 -2
- 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 -7
- 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/npm-shrinkwrap.json +276 -390
- package/package.json +9 -11
|
@@ -14,6 +14,7 @@ import { APP_NAME, APP_TITLE, CONFIG_DIR_NAME, getAgentDir, getAuthPath, getDebu
|
|
|
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 { getApexEnvironment } from "../../core/environment.js";
|
|
18
19
|
import { FooterDataProvider } from "../../core/footer-data-provider.js";
|
|
19
20
|
import { configureHttpDispatcher, formatHttpIdleTimeoutMs } from "../../core/http-dispatcher.js";
|
|
@@ -37,6 +38,7 @@ import { parseGitUrl } from "../../utils/git.js";
|
|
|
37
38
|
import { openBrowser } from "../../utils/open-browser.js";
|
|
38
39
|
import { getCwdRelativePath } from "../../utils/paths.js";
|
|
39
40
|
import { killTrackedDetachedChildren } from "../../utils/shell.js";
|
|
41
|
+
import { loadAllHighlightLanguages } from "../../utils/syntax-highlight.js";
|
|
40
42
|
import { ensureTool } from "../../utils/tools-manager.js";
|
|
41
43
|
import { checkForNewApexCodeVersion } from "../../utils/version-check.js";
|
|
42
44
|
import { ArminComponent } from "./components/armin.js";
|
|
@@ -67,6 +69,7 @@ import { PERMISSION_MODE_OVERRIDE_HINTS, SettingsSelectorComponent } from "./com
|
|
|
67
69
|
import { SkillInvocationMessageComponent } from "./components/skill-invocation-message.js";
|
|
68
70
|
import { ApexSplashHeader } from "./components/splash-header.js";
|
|
69
71
|
import { BranchSummaryStatusIndicator, CompactionStatusIndicator, IdleStatus, RetryStatusIndicator, WorkingStatusIndicator, } from "./components/status-indicator.js";
|
|
72
|
+
import { ThinkingSelectorComponent } from "./components/thinking-selector.js";
|
|
70
73
|
import { ToolExecutionComponent } from "./components/tool-execution.js";
|
|
71
74
|
import { TreeSelectorComponent } from "./components/tree-selector.js";
|
|
72
75
|
import { TrustSelectorComponent } from "./components/trust-selector.js";
|
|
@@ -95,6 +98,9 @@ class ExpandableText extends Text {
|
|
|
95
98
|
function isCustomSessionEntry(item) {
|
|
96
99
|
return "type" in item && item.type === "custom";
|
|
97
100
|
}
|
|
101
|
+
function isCompactionCostNotice(item) {
|
|
102
|
+
return "type" in item && item.type === "compaction_cost";
|
|
103
|
+
}
|
|
98
104
|
const DEAD_TERMINAL_ERROR_CODES = new Set(["EIO", "EPIPE", "ENOTCONN"]);
|
|
99
105
|
function isDeadTerminalError(error) {
|
|
100
106
|
if (!error || typeof error !== "object" || !("code" in error)) {
|
|
@@ -134,6 +140,11 @@ export function formatResumeCommand(sessionManager) {
|
|
|
134
140
|
function hasDefaultModelProvider(providerId) {
|
|
135
141
|
return providerId in defaultModelPerProvider;
|
|
136
142
|
}
|
|
143
|
+
function llamaCppPostLoginGuidance(actionLabel, loadedModelCount) {
|
|
144
|
+
return loadedModelCount === 0
|
|
145
|
+
? `${actionLabel}. No llama.cpp models are loaded. Use /llama to load a model, then /model to select it.`
|
|
146
|
+
: `${actionLabel}. Use /model to select a loaded llama.cpp model, or /llama to manage models.`;
|
|
147
|
+
}
|
|
137
148
|
const AUTH_TYPE_ORDER = { oauth: 0, api_key: 1 };
|
|
138
149
|
function createFuzzyAutocompleteItems(items, prefix, getSearchText, toAutocompleteItem) {
|
|
139
150
|
const filtered = fuzzyFilter(items, prefix, getSearchText);
|
|
@@ -496,6 +507,15 @@ export class InteractiveMode {
|
|
|
496
507
|
}));
|
|
497
508
|
};
|
|
498
509
|
}
|
|
510
|
+
const thinkingCommand = slashCommands.find((command) => command.name === "thinking");
|
|
511
|
+
if (thinkingCommand) {
|
|
512
|
+
thinkingCommand.getArgumentCompletions = (prefix) => {
|
|
513
|
+
return createFuzzyAutocompleteItems(this.session.getAvailableThinkingLevels(), prefix, (level) => level, (level) => ({
|
|
514
|
+
value: level,
|
|
515
|
+
label: level,
|
|
516
|
+
}));
|
|
517
|
+
};
|
|
518
|
+
}
|
|
499
519
|
const loginCommand = slashCommands.find((command) => command.name === "login");
|
|
500
520
|
if (loginCommand) {
|
|
501
521
|
loginCommand.getArgumentCompletions = (prefix) => {
|
|
@@ -792,6 +812,14 @@ export class InteractiveMode {
|
|
|
792
812
|
});
|
|
793
813
|
// Initialize available provider count for footer display
|
|
794
814
|
await this.updateAvailableProviderCount();
|
|
815
|
+
// Flush the completed startup state before loading the remaining syntax grammars.
|
|
816
|
+
this.ui.renderNow();
|
|
817
|
+
void loadAllHighlightLanguages().then(() => {
|
|
818
|
+
if (!this.isInitialized)
|
|
819
|
+
return;
|
|
820
|
+
this.ui.invalidate();
|
|
821
|
+
this.ui.requestRender();
|
|
822
|
+
});
|
|
795
823
|
}
|
|
796
824
|
/**
|
|
797
825
|
* Update terminal title with session name and cwd.
|
|
@@ -847,7 +875,18 @@ export class InteractiveMode {
|
|
|
847
875
|
}
|
|
848
876
|
});
|
|
849
877
|
// Show startup warnings
|
|
850
|
-
const { migratedProviders, modelFallbackMessage, initialMessage, initialImages, initialMessages } = this.options;
|
|
878
|
+
const { migratedProviders, startupDiagnostics, modelFallbackMessage, initialMessage, initialImages, initialMessages, } = this.options;
|
|
879
|
+
for (const diagnostic of startupDiagnostics ?? []) {
|
|
880
|
+
if (diagnostic.type === "error") {
|
|
881
|
+
this.showError(diagnostic.message);
|
|
882
|
+
}
|
|
883
|
+
else if (diagnostic.type === "warning") {
|
|
884
|
+
this.showWarning(diagnostic.message);
|
|
885
|
+
}
|
|
886
|
+
else {
|
|
887
|
+
this.showStatus(diagnostic.message);
|
|
888
|
+
}
|
|
889
|
+
}
|
|
851
890
|
if (migratedProviders && migratedProviders.length > 0) {
|
|
852
891
|
this.showWarning(`Migrated credentials to auth.json: ${migratedProviders.join(", ")}`);
|
|
853
892
|
}
|
|
@@ -2492,6 +2531,12 @@ export class InteractiveMode {
|
|
|
2492
2531
|
await this.handleModelCommand(searchTerm);
|
|
2493
2532
|
return;
|
|
2494
2533
|
}
|
|
2534
|
+
if (text === "/thinking" || text.startsWith("/thinking ")) {
|
|
2535
|
+
const searchTerm = text.startsWith("/thinking ") ? text.slice(10).trim() : undefined;
|
|
2536
|
+
this.editor.setText("");
|
|
2537
|
+
this.handleThinkingCommand(searchTerm);
|
|
2538
|
+
return;
|
|
2539
|
+
}
|
|
2495
2540
|
if (text === "/export" || text.startsWith("/export ")) {
|
|
2496
2541
|
await this.handleExportCommand(text);
|
|
2497
2542
|
this.editor.setText("");
|
|
@@ -2878,9 +2923,21 @@ export class InteractiveMode {
|
|
|
2878
2923
|
}
|
|
2879
2924
|
}
|
|
2880
2925
|
else if (event.result) {
|
|
2926
|
+
const entries = this.sessionManager.buildContextEntries();
|
|
2927
|
+
if (entries[0]?.type !== "compaction") {
|
|
2928
|
+
throw new Error("Completed compaction is missing from the session context");
|
|
2929
|
+
}
|
|
2881
2930
|
this.chatContainer.clear();
|
|
2882
|
-
|
|
2931
|
+
// The latest compaction is prepended for model context; append it below at its chronological position.
|
|
2932
|
+
this.renderSessionEntries(entries.slice(1));
|
|
2883
2933
|
this.addMessageToChat(createCompactionSummaryMessage(event.result.summary, event.result.tokensBefore, new Date().toISOString()));
|
|
2934
|
+
if (event.result.usage) {
|
|
2935
|
+
this.addCompactionCostNotice({
|
|
2936
|
+
type: "compaction_cost",
|
|
2937
|
+
kind: "compaction",
|
|
2938
|
+
usage: event.result.usage,
|
|
2939
|
+
});
|
|
2940
|
+
}
|
|
2884
2941
|
this.footer.invalidate();
|
|
2885
2942
|
}
|
|
2886
2943
|
else if (event.errorMessage) {
|
|
@@ -3102,6 +3159,10 @@ export class InteractiveMode {
|
|
|
3102
3159
|
this.addCustomEntryToChat(item);
|
|
3103
3160
|
continue;
|
|
3104
3161
|
}
|
|
3162
|
+
if (isCompactionCostNotice(item)) {
|
|
3163
|
+
this.addCompactionCostNotice(item);
|
|
3164
|
+
continue;
|
|
3165
|
+
}
|
|
3105
3166
|
const message = item;
|
|
3106
3167
|
// Assistant messages need special handling for tool calls
|
|
3107
3168
|
if (message.role === "assistant") {
|
|
@@ -3169,10 +3230,28 @@ export class InteractiveMode {
|
|
|
3169
3230
|
if (entry.type === "custom") {
|
|
3170
3231
|
return [entry];
|
|
3171
3232
|
}
|
|
3172
|
-
|
|
3233
|
+
const messages = sessionEntryToContextMessages(entry);
|
|
3234
|
+
if ((entry.type === "compaction" || entry.type === "branch_summary") && entry.usage && messages.length > 0) {
|
|
3235
|
+
return [...messages, { type: "compaction_cost", kind: entry.type, usage: entry.usage }];
|
|
3236
|
+
}
|
|
3237
|
+
return messages;
|
|
3173
3238
|
});
|
|
3174
3239
|
this.renderSessionItems(items, options);
|
|
3175
3240
|
}
|
|
3241
|
+
/**
|
|
3242
|
+
* Render billing usage for a compaction or branch summary. The notice is derived
|
|
3243
|
+
* from persisted summary usage and is not stored as a separate session entry.
|
|
3244
|
+
*/
|
|
3245
|
+
addCompactionCostNotice(notice) {
|
|
3246
|
+
if (!this.settingsManager.getShowCacheMissNotices())
|
|
3247
|
+
return;
|
|
3248
|
+
const { usage } = notice;
|
|
3249
|
+
const tokens = usage.input + usage.output + usage.cacheRead + usage.cacheWrite;
|
|
3250
|
+
const cost = usage.cost.total >= 0.01 ? ` (~$${usage.cost.total.toFixed(2)})` : "";
|
|
3251
|
+
const label = notice.kind === "compaction" ? "Compaction" : "Branch summary";
|
|
3252
|
+
this.chatContainer.addChild(new Spacer(1));
|
|
3253
|
+
this.chatContainer.addChild(new Text(theme.fg("warning", `${label}: ${formatTokens(tokens)} tokens billed${cost}`), 1, 0));
|
|
3254
|
+
}
|
|
3176
3255
|
/**
|
|
3177
3256
|
* Show a transcript notice when a completed assistant message paid for a
|
|
3178
3257
|
* significant cache miss. Only states observable facts: the miss itself,
|
|
@@ -3858,8 +3937,14 @@ export class InteractiveMode {
|
|
|
3858
3937
|
const permissionMode = await this.session.getPermissionMode();
|
|
3859
3938
|
this.showSelector((done) => {
|
|
3860
3939
|
let selector;
|
|
3940
|
+
const defaultProvider = this.settingsManager.getDefaultProvider();
|
|
3941
|
+
const defaultModelId = this.settingsManager.getDefaultModel();
|
|
3942
|
+
const defaultModel = defaultProvider && defaultModelId ? `${defaultProvider}/${defaultModelId}` : "not set";
|
|
3861
3943
|
selector = new SettingsSelectorComponent({
|
|
3862
3944
|
autoCompact: this.session.autoCompactionEnabled,
|
|
3945
|
+
defaultModel,
|
|
3946
|
+
currentModel: this.session.model,
|
|
3947
|
+
availableDefaultModels: this.session.modelRuntime.getAvailableSnapshot(),
|
|
3863
3948
|
showImages: this.settingsManager.getShowImages(),
|
|
3864
3949
|
imageWidthCells: this.settingsManager.getImageWidthCells(),
|
|
3865
3950
|
autoResizeImages: this.settingsManager.getImageAutoResize(),
|
|
@@ -3869,8 +3954,9 @@ export class InteractiveMode {
|
|
|
3869
3954
|
followUpMode: this.session.followUpMode,
|
|
3870
3955
|
transport: this.settingsManager.getTransport(),
|
|
3871
3956
|
httpIdleTimeoutMs: this.settingsManager.getHttpIdleTimeoutMs(),
|
|
3872
|
-
thinkingLevel: this.
|
|
3873
|
-
availableThinkingLevels:
|
|
3957
|
+
thinkingLevel: this.settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL,
|
|
3958
|
+
availableThinkingLevels: [...THINKING_LEVEL_OPTIONS],
|
|
3959
|
+
modelThinkingLevels: this.settingsManager.getAllModelThinkingLevels(),
|
|
3874
3960
|
currentTheme: this.themeController.getThemeSelection() || "dark",
|
|
3875
3961
|
terminalTheme: this.themeController.getTerminalTheme(),
|
|
3876
3962
|
availableThemes: getAvailableThemes(),
|
|
@@ -3940,10 +4026,26 @@ export class InteractiveMode {
|
|
|
3940
4026
|
configureHttpDispatcher(timeoutMs);
|
|
3941
4027
|
this.showStatus(`HTTP idle timeout: ${formatHttpIdleTimeoutMs(timeoutMs)}`);
|
|
3942
4028
|
},
|
|
3943
|
-
|
|
3944
|
-
this.
|
|
3945
|
-
|
|
3946
|
-
this.
|
|
4029
|
+
onModelThinkingLevelChange: (provider, modelId, level) => {
|
|
4030
|
+
this.settingsManager.setModelThinkingLevel(provider, modelId, level);
|
|
4031
|
+
// If the override is for the current model, apply it to the session too
|
|
4032
|
+
const current = this.session.model;
|
|
4033
|
+
if (current && current.provider === provider && current.id === modelId) {
|
|
4034
|
+
this.session.setThinkingLevel(level);
|
|
4035
|
+
this.footer.invalidate();
|
|
4036
|
+
this.updateEditorBorderColor();
|
|
4037
|
+
}
|
|
4038
|
+
},
|
|
4039
|
+
onModelThinkingLevelRemove: (provider, modelId) => {
|
|
4040
|
+
this.settingsManager.removeModelThinkingLevel(provider, modelId);
|
|
4041
|
+
// If the override was for the current model, revert to global default
|
|
4042
|
+
const current = this.session.model;
|
|
4043
|
+
if (current && current.provider === provider && current.id === modelId) {
|
|
4044
|
+
const globalDefault = this.settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL;
|
|
4045
|
+
this.session.setThinkingLevel(globalDefault);
|
|
4046
|
+
this.footer.invalidate();
|
|
4047
|
+
this.updateEditorBorderColor();
|
|
4048
|
+
}
|
|
3947
4049
|
},
|
|
3948
4050
|
onThemeChange: (themeSetting) => {
|
|
3949
4051
|
this.settingsManager.setTheme(themeSetting);
|
|
@@ -4067,6 +4169,44 @@ export class InteractiveMode {
|
|
|
4067
4169
|
return { component: selector, focus: selector.getSettingsList() };
|
|
4068
4170
|
});
|
|
4069
4171
|
}
|
|
4172
|
+
handleThinkingCommand(searchTerm) {
|
|
4173
|
+
const availableLevels = this.session.getAvailableThinkingLevels();
|
|
4174
|
+
if (!searchTerm) {
|
|
4175
|
+
this.showThinkingSelector();
|
|
4176
|
+
return;
|
|
4177
|
+
}
|
|
4178
|
+
const normalized = searchTerm.trim().toLowerCase();
|
|
4179
|
+
const level = availableLevels.find((candidate) => candidate.toLowerCase() === normalized);
|
|
4180
|
+
if (!level) {
|
|
4181
|
+
this.showError(`Unknown thinking level "${searchTerm}". Available levels: ${availableLevels.join(", ")}.`);
|
|
4182
|
+
return;
|
|
4183
|
+
}
|
|
4184
|
+
this.selectThinkingLevel(level, false);
|
|
4185
|
+
}
|
|
4186
|
+
selectThinkingLevel(level, persist) {
|
|
4187
|
+
try {
|
|
4188
|
+
this.session.setThinkingLevel(level, { persist });
|
|
4189
|
+
this.footer.invalidate();
|
|
4190
|
+
this.updateEditorBorderColor();
|
|
4191
|
+
this.showStatus(persist ? `Default thinking level: ${level}` : `Thinking level: ${level}`);
|
|
4192
|
+
}
|
|
4193
|
+
catch (error) {
|
|
4194
|
+
this.showError(error instanceof Error ? error.message : String(error));
|
|
4195
|
+
}
|
|
4196
|
+
}
|
|
4197
|
+
showThinkingSelector() {
|
|
4198
|
+
this.showSelector((done) => {
|
|
4199
|
+
const selectLevel = (level, persist) => {
|
|
4200
|
+
this.selectThinkingLevel(level, persist);
|
|
4201
|
+
done();
|
|
4202
|
+
};
|
|
4203
|
+
const selector = new ThinkingSelectorComponent(this.session.thinkingLevel ?? DEFAULT_THINKING_LEVEL, this.session.getAvailableThinkingLevels(), (level) => selectLevel(level, false), () => {
|
|
4204
|
+
done();
|
|
4205
|
+
this.ui.requestRender();
|
|
4206
|
+
}, (level) => selectLevel(level, true), this.settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL);
|
|
4207
|
+
return { component: selector, focus: selector };
|
|
4208
|
+
});
|
|
4209
|
+
}
|
|
4070
4210
|
async handleModelCommand(searchTerm) {
|
|
4071
4211
|
if (!searchTerm) {
|
|
4072
4212
|
this.showModelSelector();
|
|
@@ -4075,7 +4215,7 @@ export class InteractiveMode {
|
|
|
4075
4215
|
const model = await this.findExactModelMatch(searchTerm);
|
|
4076
4216
|
if (model) {
|
|
4077
4217
|
try {
|
|
4078
|
-
await this.session.setModel(model);
|
|
4218
|
+
await this.session.setModel(model, { persist: false });
|
|
4079
4219
|
this.footer.invalidate();
|
|
4080
4220
|
this.updateEditorBorderColor();
|
|
4081
4221
|
this.showStatus(`Model: ${model.id}`);
|
|
@@ -4204,13 +4344,13 @@ export class InteractiveMode {
|
|
|
4204
4344
|
}
|
|
4205
4345
|
showModelSelector(initialSearchInput) {
|
|
4206
4346
|
this.showSelector((done) => {
|
|
4207
|
-
const
|
|
4347
|
+
const selectModel = async (model, persist) => {
|
|
4208
4348
|
try {
|
|
4209
|
-
await this.session.setModel(model);
|
|
4349
|
+
await this.session.setModel(model, { persist });
|
|
4210
4350
|
this.footer.invalidate();
|
|
4211
4351
|
this.updateEditorBorderColor();
|
|
4212
4352
|
done();
|
|
4213
|
-
this.showStatus(`Model: ${model.id}`);
|
|
4353
|
+
this.showStatus(persist ? `Default model: ${model.provider}/${model.id}` : `Model: ${model.id}`);
|
|
4214
4354
|
void this.maybeWarnAboutAnthropicSubscriptionAuth(model);
|
|
4215
4355
|
this.checkDaxnutsEasterEgg(model);
|
|
4216
4356
|
}
|
|
@@ -4218,10 +4358,13 @@ export class InteractiveMode {
|
|
|
4218
4358
|
done();
|
|
4219
4359
|
this.showError(error instanceof Error ? error.message : String(error));
|
|
4220
4360
|
}
|
|
4221
|
-
}
|
|
4361
|
+
};
|
|
4362
|
+
const defaultProvider = this.settingsManager.getDefaultProvider();
|
|
4363
|
+
const defaultModel = this.settingsManager.getDefaultModel();
|
|
4364
|
+
const selector = new ModelSelectorComponent(this.ui, this.session.model, this.session.modelRuntime, this.session.scopedModels, (model) => selectModel(model, false), () => {
|
|
4222
4365
|
done();
|
|
4223
4366
|
this.ui.requestRender();
|
|
4224
|
-
}, initialSearchInput);
|
|
4367
|
+
}, initialSearchInput, (model) => selectModel(model, true), defaultProvider && defaultModel ? { provider: defaultProvider, id: defaultModel } : undefined);
|
|
4225
4368
|
return { component: selector, focus: selector, dispose: () => selector.dispose() };
|
|
4226
4369
|
});
|
|
4227
4370
|
}
|
|
@@ -4777,7 +4920,11 @@ export class InteractiveMode {
|
|
|
4777
4920
|
if (isUnknownModel(previousModel)) {
|
|
4778
4921
|
const availableModels = this.session.modelRuntime.getAvailableSnapshot();
|
|
4779
4922
|
const providerModels = availableModels.filter((model) => model.provider === providerId);
|
|
4780
|
-
|
|
4923
|
+
// Matches LLAMA_PROVIDER_ID from extensions/llama/provider.ts; kept inline to avoid coupling interactive mode to the built-in extension.
|
|
4924
|
+
if (providerId === "llama.cpp") {
|
|
4925
|
+
selectionError = llamaCppPostLoginGuidance(actionLabel, providerModels.length);
|
|
4926
|
+
}
|
|
4927
|
+
else if (!hasDefaultModelProvider(providerId)) {
|
|
4781
4928
|
selectionError = `${actionLabel}, but no default model is configured for provider "${providerId}". Use /model to select a model.`;
|
|
4782
4929
|
}
|
|
4783
4930
|
else if (providerModels.length === 0) {
|
|
@@ -4791,7 +4938,7 @@ export class InteractiveMode {
|
|
|
4791
4938
|
}
|
|
4792
4939
|
else {
|
|
4793
4940
|
try {
|
|
4794
|
-
await this.session.setModel(selectedModel);
|
|
4941
|
+
await this.session.setModel(selectedModel, { persist: true });
|
|
4795
4942
|
}
|
|
4796
4943
|
catch (error) {
|
|
4797
4944
|
selectedModel = undefined;
|