























@@ -489,6 +489,57 @@ const formatVoiceModeLine = (
489489return parts.join(" · ");
490490};
491491492+function resolveChannelModelNote(params: {
493+config?: OpenClawConfig;
494+entry?: SessionEntry;
495+selectedProvider: string;
496+selectedModel: string;
497+parentSessionKey?: string;
498+}): string | undefined {
499+if (!params.config || !params.entry) {
500+return undefined;
501+}
502+if (
503+normalizeOptionalString(params.entry.modelOverride) ||
504+normalizeOptionalString(params.entry.providerOverride)
505+) {
506+return undefined;
507+}
508+const channelOverride = resolveChannelModelOverride({
509+cfg: params.config,
510+channel: params.entry.channel ?? params.entry.origin?.provider,
511+groupId: params.entry.groupId,
512+groupChatType: params.entry.chatType ?? params.entry.origin?.chatType,
513+groupChannel: params.entry.groupChannel,
514+groupSubject: params.entry.subject,
515+parentSessionKey: params.parentSessionKey,
516+});
517+if (!channelOverride) {
518+return undefined;
519+}
520+const aliasIndex = buildModelAliasIndex({
521+cfg: params.config,
522+defaultProvider: DEFAULT_PROVIDER,
523+allowPluginNormalization: false,
524+});
525+const resolvedOverride = resolveModelRefFromString({
526+raw: channelOverride.model,
527+defaultProvider: DEFAULT_PROVIDER,
528+ aliasIndex,
529+allowPluginNormalization: false,
530+});
531+if (!resolvedOverride) {
532+return undefined;
533+}
534+if (
535+resolvedOverride.ref.provider !== params.selectedProvider ||
536+resolvedOverride.ref.model !== params.selectedModel
537+) {
538+return undefined;
539+}
540+return "channel override";
541+}
542+492543export function buildStatusMessage(args: StatusArgs): string {
493544const now = args.now ?? Date.now();
494545const entry = args.sessionEntry;
@@ -650,10 +701,21 @@ export function buildStatusMessage(args: StatusArgs): string {
650701model: contextLookupModel,
651702allowAsyncLoad: false,
652703});
704+const channelModelNote = resolveChannelModelNote({
705+config: args.config,
706+ entry,
707+ selectedProvider,
708+ selectedModel,
709+parentSessionKey: args.parentSessionKey,
710+});
653711const persistedContextTokens =
654712typeof entry?.contextTokens === "number" && entry.contextTokens > 0
655713 ? entry.contextTokens
656714 : undefined;
715+const agentContextTokens =
716+typeof args.agent?.contextTokens === "number" && args.agent.contextTokens > 0
717+ ? args.agent.contextTokens
718+ : undefined;
657719const explicitRuntimeContextTokens =
658720typeof args.runtimeContextTokens === "number" && args.runtimeContextTokens > 0
659721 ? args.runtimeContextTokens
@@ -669,6 +731,15 @@ export function buildStatusMessage(args: StatusArgs): string {
669731 ? Math.min(explicitConfiguredContextTokens, activeContextTokens)
670732 : explicitConfiguredContextTokens
671733 : undefined;
734+const channelOverrideContextTokens = channelModelNote
735+ ? (explicitRuntimeContextTokens ??
736+cappedConfiguredContextTokens ??
737+(typeof activeContextTokens === "number"
738+ ? typeof agentContextTokens === "number"
739+ ? Math.min(agentContextTokens, activeContextTokens)
740+ : activeContextTokens
741+ : agentContextTokens))
742+ : undefined;
672743// When a fallback model is active, the selected-model context limit that
673744// callers keep on the agent config is often stale. Prefer an explicit runtime
674745// snapshot when available. Separately, callers can pass an explicit configured
@@ -715,7 +786,8 @@ export function buildStatusMessage(args: StatusArgs): string {
715786cfg: contextConfig,
716787 ...(contextLookupProvider ? { provider: contextLookupProvider } : {}),
717788model: contextLookupModel,
718-contextTokensOverride: persistedContextTokens ?? args.agent?.contextTokens,
789+contextTokensOverride:
790+channelOverrideContextTokens ?? persistedContextTokens ?? agentContextTokens,
719791fallbackContextTokens: DEFAULT_CONTEXT_TOKENS,
720792allowAsyncLoad: false,
721793}) ?? DEFAULT_CONTEXT_TOKENS);
@@ -854,50 +926,6 @@ export function buildStatusMessage(args: StatusArgs): string {
854926const costLabel = showCost && hasUsage ? formatUsd(cost) : undefined;
855927856928const selectedAuthLabel = selectedAuthLabelValue ? ` · 🔑 ${selectedAuthLabelValue}` : "";
857-const channelModelNote = (() => {
858-if (!args.config || !entry) {
859-return undefined;
860-}
861-if (
862-normalizeOptionalString(entry.modelOverride) ||
863-normalizeOptionalString(entry.providerOverride)
864-) {
865-return undefined;
866-}
867-const channelOverride = resolveChannelModelOverride({
868-cfg: args.config,
869-channel: entry.channel ?? entry.origin?.provider,
870-groupId: entry.groupId,
871-groupChatType: entry.chatType ?? entry.origin?.chatType,
872-groupChannel: entry.groupChannel,
873-groupSubject: entry.subject,
874-parentSessionKey: args.parentSessionKey,
875-});
876-if (!channelOverride) {
877-return undefined;
878-}
879-const aliasIndex = buildModelAliasIndex({
880-cfg: args.config,
881-defaultProvider: DEFAULT_PROVIDER,
882-allowPluginNormalization: false,
883-});
884-const resolvedOverride = resolveModelRefFromString({
885-raw: channelOverride.model,
886-defaultProvider: DEFAULT_PROVIDER,
887- aliasIndex,
888-allowPluginNormalization: false,
889-});
890-if (!resolvedOverride) {
891-return undefined;
892-}
893-if (
894-resolvedOverride.ref.provider !== selectedProvider ||
895-resolvedOverride.ref.model !== selectedModel
896-) {
897-return undefined;
898-}
899-return "channel override";
900-})();
901929const modelNote = channelModelNote ? ` · ${channelModelNote}` : "";
902930const modelLine = `🧠 Model: ${selectedModelLabel}${selectedAuthLabel}${modelNote}`;
903931此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。