@averyyy/pi-coding-agent 0.80.10-piclient.2 → 0.82.0-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 +101 -0
- package/README.md +19 -3
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +2 -0
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/config-selector.d.ts.map +1 -1
- package/dist/cli/config-selector.js +1 -1
- package/dist/cli/config-selector.js.map +1 -1
- package/dist/cli/startup-ui.d.ts.map +1 -1
- package/dist/cli/startup-ui.js +1 -1
- package/dist/cli/startup-ui.js.map +1 -1
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +13 -0
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session.d.ts +33 -3
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +91 -59
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/compaction/branch-summarization.d.ts +7 -1
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js +6 -2
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +23 -4
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +83 -29
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/compaction/utils.d.ts +1 -1
- package/dist/core/compaction/utils.d.ts.map +1 -1
- package/dist/core/compaction/utils.js +6 -17
- package/dist/core/compaction/utils.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +13 -2
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +2 -1
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +35 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +20 -2
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/model-config.d.ts +30 -0
- package/dist/core/model-config.d.ts.map +1 -1
- package/dist/core/model-config.js +6 -0
- package/dist/core/model-config.js.map +1 -1
- package/dist/core/model-registry.d.ts +5 -1
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +19 -4
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +9 -0
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/model-runtime.d.ts +7 -3
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +42 -21
- package/dist/core/model-runtime.js.map +1 -1
- package/dist/core/prompt-templates.d.ts +1 -0
- package/dist/core/prompt-templates.d.ts.map +1 -1
- package/dist/core/prompt-templates.js +4 -4
- package/dist/core/prompt-templates.js.map +1 -1
- package/dist/core/remote-catalog-provider.d.ts +1 -1
- package/dist/core/remote-catalog-provider.d.ts.map +1 -1
- package/dist/core/remote-catalog-provider.js +21 -7
- 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 +1 -0
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +6 -2
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts +9 -4
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +99 -23
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +1 -1
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +1 -1
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tools/bash.d.ts +2 -0
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +34 -5
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +1 -1
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
- package/dist/core/tools/tool-definition-wrapper.js +3 -1
- package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
- package/dist/core/usage-totals.d.ts +19 -0
- package/dist/core/usage-totals.d.ts.map +1 -0
- package/dist/core/usage-totals.js +52 -0
- package/dist/core/usage-totals.js.map +1 -0
- package/dist/extensions/index.d.ts +3 -0
- package/dist/extensions/index.d.ts.map +1 -0
- package/dist/extensions/index.js +3 -0
- package/dist/extensions/index.js.map +1 -0
- package/dist/extensions/llama/client.d.ts +61 -0
- package/dist/extensions/llama/client.d.ts.map +1 -0
- package/dist/extensions/llama/client.js +302 -0
- package/dist/extensions/llama/client.js.map +1 -0
- package/dist/extensions/llama/huggingface.d.ts +23 -0
- package/dist/extensions/llama/huggingface.d.ts.map +1 -0
- package/dist/extensions/llama/huggingface.js +141 -0
- package/dist/extensions/llama/huggingface.js.map +1 -0
- package/dist/extensions/llama/index.d.ts +3 -0
- package/dist/extensions/llama/index.d.ts.map +1 -0
- package/dist/extensions/llama/index.js +208 -0
- package/dist/extensions/llama/index.js.map +1 -0
- package/dist/extensions/llama/provider.d.ts +10 -0
- package/dist/extensions/llama/provider.d.ts.map +1 -0
- package/dist/extensions/llama/provider.js +101 -0
- package/dist/extensions/llama/provider.js.map +1 -0
- package/dist/extensions/llama/ui.d.ts +42 -0
- package/dist/extensions/llama/ui.d.ts.map +1 -0
- package/dist/extensions/llama/ui.js +416 -0
- package/dist/extensions/llama/ui.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +10 -4
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/extension-editor.d.ts +1 -2
- package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-editor.js +16 -46
- package/dist/modes/interactive/components/extension-editor.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +24 -23
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/external-editor.d.ts +12 -0
- package/dist/modes/interactive/external-editor.d.ts.map +1 -0
- package/dist/modes/interactive/external-editor.js +37 -0
- package/dist/modes/interactive/external-editor.js.map +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts +2 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +72 -68
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +4 -0
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +7 -0
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +5 -0
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +11 -0
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/utils/clipboard.d.ts.map +1 -1
- package/dist/utils/clipboard.js +19 -8
- package/dist/utils/clipboard.js.map +1 -1
- package/dist/utils/version-check.d.ts.map +1 -1
- package/dist/utils/version-check.js +3 -1
- package/dist/utils/version-check.js.map +1 -1
- package/docs/compaction.md +9 -4
- package/docs/custom-provider.md +33 -2
- package/docs/environment-variables.md +88 -0
- package/docs/extensions.md +61 -11
- package/docs/index.md +2 -0
- package/docs/json.md +5 -1
- package/docs/llama-cpp.md +99 -0
- package/docs/models.md +6 -2
- package/docs/prompt-templates.md +1 -0
- package/docs/providers.md +19 -1
- package/docs/rpc.md +104 -8
- package/docs/sdk.md +3 -0
- package/docs/session-format.md +17 -3
- package/docs/settings.md +1 -1
- package/docs/tui.md +41 -26
- package/docs/usage.md +2 -14
- package/examples/extensions/README.md +1 -1
- package/examples/extensions/custom-compaction.ts +4 -0
- 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/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/handoff.ts +9 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/summarize.ts +3 -0
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/package.json +5 -4
|
@@ -25,6 +25,7 @@ import { SessionManager, sessionEntryToContextMessages } from "../../core/sessio
|
|
|
25
25
|
import { BUILTIN_SLASH_COMMANDS } from "../../core/slash-commands.js";
|
|
26
26
|
import { isInstallTelemetryEnabled } from "../../core/telemetry.js";
|
|
27
27
|
import { hasTrustRequiringProjectResources, ProjectTrustStore } from "../../core/trust-manager.js";
|
|
28
|
+
import { getUsageCostBreakdown } from "../../core/usage-totals.js";
|
|
28
29
|
import { getChangelogPath, getNewEntries, normalizeChangelogLinks, parseChangelog } from "../../utils/changelog.js";
|
|
29
30
|
import { copyToClipboard, readClipboardText } from "../../utils/clipboard.js";
|
|
30
31
|
import { extensionForImageMimeType, readClipboardImage } from "../../utils/clipboard-image.js";
|
|
@@ -64,6 +65,7 @@ import { TreeSelectorComponent } from "./components/tree-selector.js";
|
|
|
64
65
|
import { TrustSelectorComponent } from "./components/trust-selector.js";
|
|
65
66
|
import { UserMessageComponent } from "./components/user-message.js";
|
|
66
67
|
import { UserMessageSelectorComponent } from "./components/user-message-selector.js";
|
|
68
|
+
import { editInExternalEditor } from "./external-editor.js";
|
|
67
69
|
import { getModelSearchText } from "./model-search.js";
|
|
68
70
|
import { getAvailableThemes, getAvailableThemesWithPaths, getEditorTheme, getMarkdownTheme, getThemeByName, onThemeChange, setRegisteredThemes, stopThemeWatcher, Theme, theme, } from "./theme/theme.js";
|
|
69
71
|
import { InteractiveThemeController } from "./theme/theme-controller.js";
|
|
@@ -272,7 +274,7 @@ export class InteractiveMode {
|
|
|
272
274
|
await this.rebindCurrentSession({ renderBeforeBind: true });
|
|
273
275
|
});
|
|
274
276
|
this.version = VERSION;
|
|
275
|
-
this.ui = new TUI(new ProcessTerminal(), this.settingsManager.getShowHardwareCursor());
|
|
277
|
+
this.ui = new TUI(new ProcessTerminal(), this.settingsManager.getShowHardwareCursor(), getAgentDir());
|
|
276
278
|
this.ui.setClearOnShrink(this.settingsManager.getClearOnShrink());
|
|
277
279
|
this.headerContainer = new Container();
|
|
278
280
|
this.loadedResourcesContainer = new Container();
|
|
@@ -580,6 +582,12 @@ export class InteractiveMode {
|
|
|
580
582
|
*/
|
|
581
583
|
async run() {
|
|
582
584
|
await this.init();
|
|
585
|
+
if (!process.env.PI_OFFLINE) {
|
|
586
|
+
void this.session.modelRuntime
|
|
587
|
+
.refresh()
|
|
588
|
+
.then(() => this.updateAvailableProviderCount())
|
|
589
|
+
.catch(() => { });
|
|
590
|
+
}
|
|
583
591
|
// Start version check asynchronously
|
|
584
592
|
checkForNewPiVersion(this.version).then((newRelease) => {
|
|
585
593
|
if (newRelease) {
|
|
@@ -791,8 +799,15 @@ export class InteractiveMode {
|
|
|
791
799
|
* Get a short path relative to the package root for display.
|
|
792
800
|
*/
|
|
793
801
|
getShortPath(fullPath, sourceInfo) {
|
|
802
|
+
const normalizedFullPath = fullPath.replace(/\\/g, "/");
|
|
794
803
|
const baseDir = sourceInfo?.baseDir;
|
|
795
804
|
if (baseDir && this.isPackageSource(sourceInfo)) {
|
|
805
|
+
const normalizedBaseDir = baseDir.replace(/\\/g, "/");
|
|
806
|
+
const npmRootMatch = normalizedBaseDir.match(/^(.*\/node_modules)\/(@?[^/]+(?:\/[^/]+)?)$/);
|
|
807
|
+
// If fullPath is under the same node_modules root as baseDir, preserve that relative topology.
|
|
808
|
+
if (npmRootMatch?.[1] && normalizedFullPath.startsWith(`${npmRootMatch[1]}/`)) {
|
|
809
|
+
return path.posix.relative(normalizedBaseDir, normalizedFullPath);
|
|
810
|
+
}
|
|
796
811
|
const relativePath = path.relative(path.resolve(baseDir), path.resolve(fullPath));
|
|
797
812
|
if (relativePath &&
|
|
798
813
|
relativePath !== "." &&
|
|
@@ -803,11 +818,11 @@ export class InteractiveMode {
|
|
|
803
818
|
}
|
|
804
819
|
}
|
|
805
820
|
const source = sourceInfo?.source ?? "";
|
|
806
|
-
const npmMatch =
|
|
821
|
+
const npmMatch = normalizedFullPath.match(/node_modules\/(@?[^/]+(?:\/[^/]+)?)\/(.*)/);
|
|
807
822
|
if (npmMatch && source.startsWith("npm:")) {
|
|
808
823
|
return npmMatch[2];
|
|
809
824
|
}
|
|
810
|
-
const gitMatch =
|
|
825
|
+
const gitMatch = normalizedFullPath.match(/git\/[^/]+\/[^/]+\/(.*)/);
|
|
811
826
|
if (gitMatch && source.startsWith("git:")) {
|
|
812
827
|
return gitMatch[1];
|
|
813
828
|
}
|
|
@@ -1063,7 +1078,10 @@ export class InteractiveMode {
|
|
|
1063
1078
|
const promptsResult = this.session.resourceLoader.getPrompts();
|
|
1064
1079
|
const themesResult = this.session.resourceLoader.getThemes();
|
|
1065
1080
|
const extensions = options?.extensions ??
|
|
1066
|
-
this.session.resourceLoader
|
|
1081
|
+
this.session.resourceLoader
|
|
1082
|
+
.getExtensions()
|
|
1083
|
+
.extensions.filter((extension) => !extension.hidden)
|
|
1084
|
+
.map((extension) => ({
|
|
1067
1085
|
path: extension.path,
|
|
1068
1086
|
sourceInfo: extension.sourceInfo,
|
|
1069
1087
|
}));
|
|
@@ -1344,6 +1362,7 @@ export class InteractiveMode {
|
|
|
1344
1362
|
sessionManager: this.sessionManager,
|
|
1345
1363
|
modelRegistry: extensionRunner.getModelRegistry(),
|
|
1346
1364
|
model: this.session.model,
|
|
1365
|
+
thinkingLevel: this.session.thinkingLevel,
|
|
1347
1366
|
isIdle: () => this.session.isIdle,
|
|
1348
1367
|
isProjectTrusted: () => this.settingsManager.isProjectTrusted(),
|
|
1349
1368
|
signal: this.session.agent.signal,
|
|
@@ -2029,7 +2048,7 @@ export class InteractiveMode {
|
|
|
2029
2048
|
this.defaultEditor.onAction("app.model.select", () => this.showModelSelector());
|
|
2030
2049
|
this.defaultEditor.onAction("app.tools.expand", () => this.toggleToolOutputExpansion());
|
|
2031
2050
|
this.defaultEditor.onAction("app.thinking.toggle", () => this.toggleThinkingBlockVisibility());
|
|
2032
|
-
this.defaultEditor.onAction("app.editor.external", () => this.
|
|
2051
|
+
this.defaultEditor.onAction("app.editor.external", () => void this.handleOpenExternalEditor());
|
|
2033
2052
|
this.defaultEditor.onAction("app.message.copy", () => void this.handleCopyCommand());
|
|
2034
2053
|
this.defaultEditor.onAction("app.message.followUp", () => this.handleFollowUp());
|
|
2035
2054
|
this.defaultEditor.onAction("app.message.dequeue", () => this.handleDequeue());
|
|
@@ -2397,6 +2416,9 @@ export class InteractiveMode {
|
|
|
2397
2416
|
}
|
|
2398
2417
|
this.ui.requestRender();
|
|
2399
2418
|
break;
|
|
2419
|
+
case "bash_execution_update":
|
|
2420
|
+
// The bash execution callback handles TUI output rendering.
|
|
2421
|
+
break;
|
|
2400
2422
|
case "tool_execution_start": {
|
|
2401
2423
|
let component = this.pendingTools.get(event.toolCallId);
|
|
2402
2424
|
if (!component) {
|
|
@@ -2518,6 +2540,28 @@ export class InteractiveMode {
|
|
|
2518
2540
|
this.ui.requestRender();
|
|
2519
2541
|
break;
|
|
2520
2542
|
}
|
|
2543
|
+
case "summarization_retry_scheduled": {
|
|
2544
|
+
this.showError(event.errorMessage);
|
|
2545
|
+
this.showStatusIndicator(new RetryStatusIndicator(this.ui, event.attempt, event.maxAttempts, event.delayMs));
|
|
2546
|
+
this.ui.requestRender();
|
|
2547
|
+
break;
|
|
2548
|
+
}
|
|
2549
|
+
case "summarization_retry_attempt_start": {
|
|
2550
|
+
this.clearStatusIndicator("retry");
|
|
2551
|
+
if (event.source === "branchSummary") {
|
|
2552
|
+
this.showStatusIndicator(new BranchSummaryStatusIndicator(this.ui));
|
|
2553
|
+
}
|
|
2554
|
+
else {
|
|
2555
|
+
this.showStatusIndicator(new CompactionStatusIndicator(this.ui, event.reason));
|
|
2556
|
+
}
|
|
2557
|
+
this.ui.requestRender();
|
|
2558
|
+
break;
|
|
2559
|
+
}
|
|
2560
|
+
case "summarization_retry_finished": {
|
|
2561
|
+
this.clearStatusIndicator("retry");
|
|
2562
|
+
this.ui.requestRender();
|
|
2563
|
+
break;
|
|
2564
|
+
}
|
|
2521
2565
|
}
|
|
2522
2566
|
}
|
|
2523
2567
|
/** Extract text content from a user message */
|
|
@@ -3097,51 +3141,21 @@ export class InteractiveMode {
|
|
|
3097
3141
|
}
|
|
3098
3142
|
this.showStatus(`Thinking blocks: ${this.hideThinkingBlock ? "hidden" : "visible"}`);
|
|
3099
3143
|
}
|
|
3100
|
-
async
|
|
3144
|
+
async handleOpenExternalEditor() {
|
|
3101
3145
|
const editorCmd = this.settingsManager.getExternalEditorCommand();
|
|
3102
|
-
|
|
3103
|
-
|
|
3104
|
-
return;
|
|
3105
|
-
}
|
|
3106
|
-
const currentText = this.editor.getExpandedText?.() ?? this.editor.getText();
|
|
3107
|
-
const tmpFile = path.join(os.tmpdir(), `pi-editor-${Date.now()}.pi.md`);
|
|
3146
|
+
const content = this.editor.getExpandedText?.() ?? this.editor.getText();
|
|
3147
|
+
this.ui.stop();
|
|
3108
3148
|
try {
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
this.ui.stop();
|
|
3113
|
-
// Split by space to support editor arguments (e.g., "code --wait")
|
|
3114
|
-
const [editor, ...editorArgs] = editorCmd.split(" ");
|
|
3115
|
-
process.stdout.write(`Launching external editor: ${editorCmd}\nPi will resume when the editor exits.\n`);
|
|
3116
|
-
// Do not use spawnSync here. On Windows, synchronous child_process calls can keep
|
|
3117
|
-
// Node/libuv's console input read active after ui.stop() pauses stdin, racing
|
|
3118
|
-
// vim/nvim for the console input buffer until Ctrl+C cancels the pending read.
|
|
3119
|
-
const status = await new Promise((resolve) => {
|
|
3120
|
-
const child = spawn(editor, [...editorArgs, tmpFile], {
|
|
3121
|
-
stdio: "inherit",
|
|
3122
|
-
shell: process.platform === "win32",
|
|
3123
|
-
});
|
|
3124
|
-
child.on("error", () => resolve(null));
|
|
3125
|
-
child.on("close", (code) => resolve(code));
|
|
3149
|
+
const result = await editInExternalEditor({
|
|
3150
|
+
command: editorCmd,
|
|
3151
|
+
content,
|
|
3126
3152
|
});
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
const newContent = fs.readFileSync(tmpFile, "utf-8").replace(/\n$/, "");
|
|
3130
|
-
this.editor.setText(newContent);
|
|
3153
|
+
if (result.status === "complete") {
|
|
3154
|
+
this.editor.setText(result.content);
|
|
3131
3155
|
}
|
|
3132
|
-
// On non-zero exit, keep original text (no action needed)
|
|
3133
3156
|
}
|
|
3134
3157
|
finally {
|
|
3135
|
-
// Clean up temp file
|
|
3136
|
-
try {
|
|
3137
|
-
fs.unlinkSync(tmpFile);
|
|
3138
|
-
}
|
|
3139
|
-
catch {
|
|
3140
|
-
// Ignore cleanup errors
|
|
3141
|
-
}
|
|
3142
|
-
// Restart TUI
|
|
3143
3158
|
this.ui.start();
|
|
3144
|
-
// Force full re-render since external editor uses alternate screen
|
|
3145
3159
|
this.ui.requestRender(true);
|
|
3146
3160
|
}
|
|
3147
3161
|
}
|
|
@@ -3328,8 +3342,10 @@ export class InteractiveMode {
|
|
|
3328
3342
|
for (const message of preCommands) {
|
|
3329
3343
|
await this.session.prompt(message.text);
|
|
3330
3344
|
}
|
|
3331
|
-
//
|
|
3332
|
-
const promptPromise = this.session
|
|
3345
|
+
// Start a prompt when idle, or queue it into a run still finishing compaction.
|
|
3346
|
+
const promptPromise = this.session
|
|
3347
|
+
.prompt(firstPrompt.text, { streamingBehavior: firstPrompt.mode })
|
|
3348
|
+
.catch((error) => {
|
|
3333
3349
|
restoreQueue(error);
|
|
3334
3350
|
});
|
|
3335
3351
|
// Queue remaining messages
|
|
@@ -3594,10 +3610,12 @@ export class InteractiveMode {
|
|
|
3594
3610
|
return [];
|
|
3595
3611
|
}
|
|
3596
3612
|
}
|
|
3597
|
-
/** Update the footer's available provider count from current
|
|
3598
|
-
|
|
3599
|
-
const models =
|
|
3600
|
-
|
|
3613
|
+
/** Update the footer's available provider count from the current snapshot without refreshing catalogs. */
|
|
3614
|
+
updateAvailableProviderCount() {
|
|
3615
|
+
const models = this.session.scopedModels.length > 0
|
|
3616
|
+
? this.session.scopedModels.map((scoped) => scoped.model)
|
|
3617
|
+
: this.session.modelRuntime.getAvailableSnapshot();
|
|
3618
|
+
const uniqueProviders = new Set(models.map((model) => model.provider));
|
|
3601
3619
|
this.footerDataProvider.setAvailableProviderCount(uniqueProviders.size);
|
|
3602
3620
|
}
|
|
3603
3621
|
async maybeWarnAboutAnthropicSubscriptionAuth(model = this.session.model) {
|
|
@@ -4704,23 +4722,9 @@ export class InteractiveMode {
|
|
|
4704
4722
|
const entries = this.sessionManager.getEntries();
|
|
4705
4723
|
const cacheWaste = computeCacheWaste(entries, this.session.modelRuntime);
|
|
4706
4724
|
// Cost/token totals per provider/model actually used (e.g. OpenRouter `auto`
|
|
4707
|
-
// resolves to a concrete responseModel)
|
|
4708
|
-
|
|
4709
|
-
|
|
4710
|
-
if (entry.type !== "message" || entry.message.role !== "assistant")
|
|
4711
|
-
continue;
|
|
4712
|
-
const message = entry.message;
|
|
4713
|
-
const usage = message.usage;
|
|
4714
|
-
const key = `${message.provider}/${message.responseModel ?? message.model}`;
|
|
4715
|
-
let bucket = perModelMap.get(key);
|
|
4716
|
-
if (!bucket) {
|
|
4717
|
-
bucket = { key, cost: 0, tokens: 0 };
|
|
4718
|
-
perModelMap.set(key, bucket);
|
|
4719
|
-
}
|
|
4720
|
-
bucket.cost += usage.cost.total;
|
|
4721
|
-
bucket.tokens += usage.input + usage.output + usage.cacheRead + usage.cacheWrite;
|
|
4722
|
-
}
|
|
4723
|
-
const perModel = Array.from(perModelMap.values()).sort((a, b) => b.cost - a.cost);
|
|
4725
|
+
// resolves to a concrete responseModel). Usage without model attribution is
|
|
4726
|
+
// grouped separately so the breakdown reconciles with the session total.
|
|
4727
|
+
const usageBreakdown = getUsageCostBreakdown(entries);
|
|
4724
4728
|
let info = `${theme.bold("Session Info")}\n\n`;
|
|
4725
4729
|
if (sessionName) {
|
|
4726
4730
|
info += `${theme.fg("dim", "Name:")} ${sessionName}\n`;
|
|
@@ -4751,8 +4755,8 @@ export class InteractiveMode {
|
|
|
4751
4755
|
if (stats.cost > 0 || cacheWaste.missedTokens > 0) {
|
|
4752
4756
|
info += `\n${theme.bold("Cost")}\n`;
|
|
4753
4757
|
info += `${theme.fg("dim", "Total:")} $${stats.cost.toFixed(3)}`;
|
|
4754
|
-
if (
|
|
4755
|
-
for (const entry of
|
|
4758
|
+
if (usageBreakdown.length > 1) {
|
|
4759
|
+
for (const entry of usageBreakdown) {
|
|
4756
4760
|
info += `\n ${theme.fg("dim", `${entry.key}:`)} $${entry.cost.toFixed(3)} ${theme.fg("dim", `(${formatTokens(entry.tokens)} tokens)`)}`;
|
|
4757
4761
|
}
|
|
4758
4762
|
}
|