mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-09 20:24:33 +00:00
fix: honor telegram model overrides in buttons (#8193) (thanks @gildo)
This commit is contained in:
15
CHANGELOG.md
15
CHANGELOG.md
@@ -44,9 +44,18 @@ Docs: https://docs.openclaw.ai
|
|||||||
|
|
||||||
### Fixes
|
### Fixes
|
||||||
|
|
||||||
- Security: require operator.approvals for gateway /approve commands. (#1) Thanks @mitsuhiko, @yueyueL.
|
- Docs: finish renaming the QMD memory docs to reference the OpenClaw state dir.
|
||||||
- Updates: honor update.channel for update.run (Control UI) and channel-based npm tags for global installs.
|
- Onboarding: keep TUI flow exclusive (skip completion prompt + background Web UI seed).
|
||||||
- Security: Matrix allowlists now require full MXIDs; ambiguous name resolution no longer grants access. Thanks @MegaManSec.
|
- Onboarding: drop completion prompt now handled by install/update.
|
||||||
|
- TUI: block onboarding output while TUI is active and restore terminal state on exit.
|
||||||
|
- CLI: cache shell completion scripts in state dir and source cached files in profiles.
|
||||||
|
- Zsh completion: escape option descriptions to avoid invalid option errors.
|
||||||
|
- Agents: repair malformed tool calls and session transcripts. (#7473) Thanks @justinhuangcode.
|
||||||
|
- fix(agents): validate AbortSignal instances before calling AbortSignal.any() (#7277) (thanks @Elarwei001)
|
||||||
|
- fix(webchat): respect user scroll position during streaming and refresh (#7226) (thanks @marcomarandiz)
|
||||||
|
- Telegram: recover from grammY long-poll timed out errors. (#7466) Thanks @macmimi23.
|
||||||
|
- Telegram: honor session model overrides in inline model selection. (#8193) Thanks @gildo.
|
||||||
|
- Media understanding: skip binary media from file text extraction. (#7475) Thanks @AlexZhangji.
|
||||||
- Security: enforce access-group gating for Slack slash commands when channel type lookup fails.
|
- Security: enforce access-group gating for Slack slash commands when channel type lookup fails.
|
||||||
- Security: require validated shared-secret auth before skipping device identity on gateway connect.
|
- Security: require validated shared-secret auth before skipping device identity on gateway connect.
|
||||||
- Security: guard skill installer downloads with SSRF checks (block private/localhost URLs).
|
- Security: guard skill installer downloads with SSRF checks (block private/localhost URLs).
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ function boundedLevenshteinDistance(a: string, b: string, maxDistance: number):
|
|||||||
return dist;
|
return dist;
|
||||||
}
|
}
|
||||||
|
|
||||||
type StoredModelOverride = {
|
export type StoredModelOverride = {
|
||||||
provider?: string;
|
provider?: string;
|
||||||
model: string;
|
model: string;
|
||||||
source: "session" | "parent";
|
source: "session" | "parent";
|
||||||
@@ -126,7 +126,7 @@ function resolveParentSessionKeyCandidate(params: {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function resolveStoredModelOverride(params: {
|
export function resolveStoredModelOverride(params: {
|
||||||
sessionEntry?: SessionEntry;
|
sessionEntry?: SessionEntry;
|
||||||
sessionStore?: Record<string, SessionEntry>;
|
sessionStore?: Record<string, SessionEntry>;
|
||||||
sessionKey?: string;
|
sessionKey?: string;
|
||||||
|
|||||||
@@ -8,19 +8,23 @@ import {
|
|||||||
} from "../auto-reply/inbound-debounce.js";
|
} from "../auto-reply/inbound-debounce.js";
|
||||||
import { buildCommandsPaginationKeyboard } from "../auto-reply/reply/commands-info.js";
|
import { buildCommandsPaginationKeyboard } from "../auto-reply/reply/commands-info.js";
|
||||||
import { buildModelsProviderData } from "../auto-reply/reply/commands-models.js";
|
import { buildModelsProviderData } from "../auto-reply/reply/commands-models.js";
|
||||||
|
import { resolveStoredModelOverride } from "../auto-reply/reply/model-selection.js";
|
||||||
import { listSkillCommandsForAgents } from "../auto-reply/skill-commands.js";
|
import { listSkillCommandsForAgents } from "../auto-reply/skill-commands.js";
|
||||||
import { buildCommandsMessagePaginated } from "../auto-reply/status.js";
|
import { buildCommandsMessagePaginated } from "../auto-reply/status.js";
|
||||||
import { resolveChannelConfigWrites } from "../channels/plugins/config-writes.js";
|
import { resolveChannelConfigWrites } from "../channels/plugins/config-writes.js";
|
||||||
import { loadConfig } from "../config/config.js";
|
import { loadConfig } from "../config/config.js";
|
||||||
import { writeConfigFile } from "../config/io.js";
|
import { writeConfigFile } from "../config/io.js";
|
||||||
|
import { loadSessionStore, resolveStorePath } from "../config/sessions.js";
|
||||||
import { danger, logVerbose, warn } from "../globals.js";
|
import { danger, logVerbose, warn } from "../globals.js";
|
||||||
import { readChannelAllowFromStore } from "../pairing/pairing-store.js";
|
import { readChannelAllowFromStore } from "../pairing/pairing-store.js";
|
||||||
|
import { resolveAgentRoute } from "../routing/resolve-route.js";
|
||||||
|
import { resolveThreadSessionKeys } from "../routing/session-key.js";
|
||||||
import { withTelegramApiErrorLogging } from "./api-logging.js";
|
import { withTelegramApiErrorLogging } from "./api-logging.js";
|
||||||
import { firstDefined, isSenderAllowed, normalizeAllowFromWithStore } from "./bot-access.js";
|
import { firstDefined, isSenderAllowed, normalizeAllowFromWithStore } from "./bot-access.js";
|
||||||
import { RegisterTelegramHandlerParams } from "./bot-native-commands.js";
|
import { RegisterTelegramHandlerParams } from "./bot-native-commands.js";
|
||||||
import { MEDIA_GROUP_TIMEOUT_MS, type MediaGroupEntry } from "./bot-updates.js";
|
import { MEDIA_GROUP_TIMEOUT_MS, type MediaGroupEntry } from "./bot-updates.js";
|
||||||
import { resolveMedia } from "./bot/delivery.js";
|
import { resolveMedia } from "./bot/delivery.js";
|
||||||
import { resolveTelegramForumThreadId } from "./bot/helpers.js";
|
import { buildTelegramGroupPeerId, resolveTelegramForumThreadId } from "./bot/helpers.js";
|
||||||
import { migrateTelegramGroupConfig } from "./group-migration.js";
|
import { migrateTelegramGroupConfig } from "./group-migration.js";
|
||||||
import { resolveTelegramInlineButtonsScope } from "./inline-buttons.js";
|
import { resolveTelegramInlineButtonsScope } from "./inline-buttons.js";
|
||||||
import {
|
import {
|
||||||
@@ -128,6 +132,60 @@ export const registerTelegramHandlers = ({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const resolveTelegramSessionModel = (params: {
|
||||||
|
chatId: number | string;
|
||||||
|
isGroup: boolean;
|
||||||
|
isForum: boolean;
|
||||||
|
messageThreadId?: number;
|
||||||
|
resolvedThreadId?: number;
|
||||||
|
}): string | undefined => {
|
||||||
|
const resolvedThreadId =
|
||||||
|
params.resolvedThreadId ??
|
||||||
|
resolveTelegramForumThreadId({
|
||||||
|
isForum: params.isForum,
|
||||||
|
messageThreadId: params.messageThreadId,
|
||||||
|
});
|
||||||
|
const peerId = params.isGroup
|
||||||
|
? buildTelegramGroupPeerId(params.chatId, resolvedThreadId)
|
||||||
|
: String(params.chatId);
|
||||||
|
const route = resolveAgentRoute({
|
||||||
|
cfg,
|
||||||
|
channel: "telegram",
|
||||||
|
accountId,
|
||||||
|
peer: {
|
||||||
|
kind: params.isGroup ? "group" : "dm",
|
||||||
|
id: peerId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const baseSessionKey = route.sessionKey;
|
||||||
|
const dmThreadId = !params.isGroup ? params.messageThreadId : undefined;
|
||||||
|
const threadKeys =
|
||||||
|
dmThreadId != null
|
||||||
|
? resolveThreadSessionKeys({ baseSessionKey, threadId: String(dmThreadId) })
|
||||||
|
: null;
|
||||||
|
const sessionKey = threadKeys?.sessionKey ?? baseSessionKey;
|
||||||
|
const storePath = resolveStorePath(cfg.session?.store, { agentId: route.agentId });
|
||||||
|
const store = loadSessionStore(storePath);
|
||||||
|
const entry = store[sessionKey];
|
||||||
|
const storedOverride = resolveStoredModelOverride({
|
||||||
|
sessionEntry: entry,
|
||||||
|
sessionStore: store,
|
||||||
|
sessionKey,
|
||||||
|
});
|
||||||
|
if (storedOverride) {
|
||||||
|
return storedOverride.provider
|
||||||
|
? `${storedOverride.provider}/${storedOverride.model}`
|
||||||
|
: storedOverride.model;
|
||||||
|
}
|
||||||
|
const provider = entry?.modelProvider?.trim();
|
||||||
|
const model = entry?.model?.trim();
|
||||||
|
if (provider && model) {
|
||||||
|
return `${provider}/${model}`;
|
||||||
|
}
|
||||||
|
const modelCfg = cfg.agents?.defaults?.model;
|
||||||
|
return typeof modelCfg === "string" ? modelCfg : modelCfg?.primary;
|
||||||
|
};
|
||||||
|
|
||||||
const processMediaGroup = async (entry: MediaGroupEntry) => {
|
const processMediaGroup = async (entry: MediaGroupEntry) => {
|
||||||
try {
|
try {
|
||||||
entry.messages.sort((a, b) => a.msg.message_id - b.msg.message_id);
|
entry.messages.sort((a, b) => a.msg.message_id - b.msg.message_id);
|
||||||
@@ -474,9 +532,14 @@ export const registerTelegramHandlers = ({
|
|||||||
const totalPages = calculateTotalPages(models.length, pageSize);
|
const totalPages = calculateTotalPages(models.length, pageSize);
|
||||||
const safePage = Math.max(1, Math.min(page, totalPages));
|
const safePage = Math.max(1, Math.min(page, totalPages));
|
||||||
|
|
||||||
// Get current model from config for checkmark display
|
// Resolve current model from session (prefer overrides)
|
||||||
const modelCfg = cfg.agents?.defaults?.model;
|
const currentModel = resolveTelegramSessionModel({
|
||||||
const currentModel = typeof modelCfg === "string" ? modelCfg : modelCfg?.primary;
|
chatId,
|
||||||
|
isGroup,
|
||||||
|
isForum,
|
||||||
|
messageThreadId,
|
||||||
|
resolvedThreadId,
|
||||||
|
});
|
||||||
|
|
||||||
const buttons = buildModelsKeyboard({
|
const buttons = buildModelsKeyboard({
|
||||||
provider,
|
provider,
|
||||||
|
|||||||
Reference in New Issue
Block a user