chore: use model max_context in status bar

This commit is contained in:
JOJO 2026-02-28 22:04:09 +08:00
parent 1775b47b34
commit 327932f7a1
2 changed files with 20 additions and 11 deletions

View File

@ -9,6 +9,7 @@ const readline = require('readline');
const { ensureConfig } = require('../config');
const { createState } = require('../core/state');
const { buildSystemPrompt } = require('../core/context');
const { getModelByKey } = require('../config');
const { streamChat } = require('../model/client');
const { executeTool } = require('../tools/dispatcher');
const { openCommandMenu, hasCommandMatch } = require('../ui/command_menu');
@ -17,7 +18,7 @@ const { Spinner, truncateThinking } = require('../ui/spinner');
const { renderBanner } = require('../ui/banner');
const { buildStartLine, buildFinalLine, startToolDisplay, formatResultLines, printResultLines } = require('../ui/tool_display');
const { createConversation, updateConversation } = require('../storage/conversation_store');
const { applyUsage, normalizeTokenUsage } = require('../utils/token_usage');
const { applyUsage, normalizeTokenUsage, normalizeUsagePayload } = require('../utils/token_usage');
const { gray, cyan, green, red, blue } = require('../utils/colors');
const { createIndentedWriter } = require('../ui/indented_writer');
const { createStatusBar } = require('../ui/status_bar');
@ -264,7 +265,10 @@ initReadline();
statusBar = createStatusBar({
getTokens: () => normalizeTokenUsage(state.tokenUsage).total || 0,
maxTokens: '256k',
getMaxTokens: () => {
const model = getModelByKey(config, state.modelKey);
return model && Number.isFinite(model.max_context) ? model.max_context : null;
},
});
statusBar.render();
@ -657,13 +661,16 @@ async function runAssistantLoop() {
abortSignal: streamController.signal,
})) {
const choice = chunk.choices && chunk.choices[0];
if (!choice) continue;
const usage = (choice && (choice.usage || choice.delta?.usage)) || chunk.usage;
if (usage) {
if (Number.isFinite(usage.prompt_tokens)) usagePrompt = usage.prompt_tokens;
if (Number.isFinite(usage.completion_tokens)) usageCompletion = usage.completion_tokens;
if (Number.isFinite(usage.total_tokens)) usageTotal = usage.total_tokens;
const usage = (chunk && chunk.usage)
|| (choice && choice.usage)
|| (choice && choice.delta && choice.delta.usage);
const normalizedUsage = normalizeUsagePayload(usage);
if (normalizedUsage) {
if (Number.isFinite(normalizedUsage.prompt_tokens)) usagePrompt = normalizedUsage.prompt_tokens;
if (Number.isFinite(normalizedUsage.completion_tokens)) usageCompletion = normalizedUsage.completion_tokens;
if (Number.isFinite(normalizedUsage.total_tokens)) usageTotal = normalizedUsage.total_tokens;
}
if (!choice) continue;
const delta = choice.delta || {};
if (delta.reasoning_content || delta.reasoning_details || choice.reasoning_details) {

View File

@ -11,7 +11,7 @@ function truncateNoEllipsis(text, maxCols) {
return out;
}
function createStatusBar({ getTokens, maxTokens }) {
function createStatusBar({ getTokens, maxTokens, getMaxTokens }) {
let mode = 'input';
let enabled = true;
let scrollApplied = false;
@ -30,8 +30,10 @@ function createStatusBar({ getTokens, maxTokens }) {
const k = Math.round((num / 1000) * 10) / 10;
return `${k % 1 === 0 ? k.toFixed(0) : k.toFixed(1)}k`;
};
const right = `当前上下文 ${formatCount(total)}/${maxTokens}`;
const rightTail = ` ${formatCount(total)}/${maxTokens}`;
const maxValue = typeof getMaxTokens === 'function' ? getMaxTokens() : maxTokens;
const maxText = typeof maxValue === 'number' ? formatCount(maxValue) : (maxValue || '?');
const right = `当前上下文 ${formatCount(total)}/${maxText}`;
const rightTail = ` ${formatCount(total)}/${maxText}`;
const leftWidth = visibleWidth(left);
const rightWidth = visibleWidth(right);
const usableCols = Math.max(1, cols - 1);