





















@@ -11,6 +11,7 @@ import {
1111import { resolveConfigWriteTargetFromPath } from "../../channels/plugins/config-writes.js";
1212import { getChannelPlugin } from "../../channels/plugins/index.js";
1313import { normalizeChannelId } from "../../channels/registry.js";
14+import { isModelsWriteEnabled } from "../../config/commands.flags.js";
1415import type { SessionEntry } from "../../config/sessions.js";
1516import type { OpenClawConfig } from "../../config/types.openclaw.js";
1617import {
@@ -261,6 +262,7 @@ export function formatModelsAvailableHeader(params: {
261262function buildModelsMenuText(params: {
262263providers: string[];
263264byProvider: ReadonlyMap<string, ReadonlySet<string>>;
265+includeAddAction?: boolean;
264266}): string {
265267return [
266268"Providers:",
@@ -273,7 +275,7 @@ function buildModelsMenuText(params: {
273275"",
274276"Use: /models <provider>",
275277"Switch: /model <provider/model>",
276-"Add: /models add",
278+...(params.includeAddAction ? ["Add: /models add"] : []),
277279].join("\n");
278280}
279281@@ -344,12 +346,15 @@ export async function resolveModelsCommandReply(params: {
344346);
345347const commandPlugin = params.surface ? getChannelPlugin(params.surface) : null;
346348const providerInfos = buildProviderInfos({ providers, byProvider });
349+const modelsWriteEnabled = isModelsWriteEnabled(params.cfg);
347350348351if (parsed.action === "providers") {
349352const channelData =
350-commandPlugin?.commands?.buildModelsMenuChannelData?.({
351-providers: providerInfos,
352-}) ??
353+(modelsWriteEnabled
354+ ? commandPlugin?.commands?.buildModelsMenuChannelData?.({
355+providers: providerInfos,
356+})
357+ : null) ??
353358commandPlugin?.commands?.buildModelsProviderChannelData?.({
354359providers: providerInfos,
355360});
@@ -360,11 +365,16 @@ export async function resolveModelsCommandReply(params: {
360365};
361366}
362367return {
363-text: buildModelsMenuText({ providers, byProvider }),
368+text: buildModelsMenuText({ providers, byProvider, includeAddAction: modelsWriteEnabled }),
364369};
365370}
366371367372if (parsed.action === "add") {
373+if (!modelsWriteEnabled) {
374+return {
375+text: "⚠️ /models add is disabled. Set commands.modelsWrite=true to enable model registration.",
376+};
377+}
368378const addableProviders = listAddableProviders({
369379cfg: params.cfg,
370380discoveredProviders: providers,
@@ -471,7 +481,7 @@ export async function resolveModelsCommandReply(params: {
471481};
472482}
473483return {
474-text: buildModelsMenuText({ providers, byProvider }),
484+text: buildModelsMenuText({ providers, byProvider, includeAddAction: modelsWriteEnabled }),
475485};
476486}
477487@@ -588,6 +598,14 @@ export const handleModelsCommand: CommandHandler = async (params, allowTextComma
588598}
589599590600if (parsed.action === "add") {
601+if (!isModelsWriteEnabled(params.cfg)) {
602+return {
603+shouldContinue: false,
604+reply: {
605+text: "⚠️ /models add is disabled. Set commands.modelsWrite=true to enable model registration.",
606+},
607+};
608+}
591609const commandLabel = "/models add";
592610const nonOwner = rejectNonOwnerCommand(params, commandLabel);
593611if (nonOwner) {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。