mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 08:00:42 +00:00
fix: keep control ui slash commands browser-safe
This commit is contained in:
@@ -30,6 +30,7 @@ Docs: https://docs.openclaw.ai
|
||||
|
||||
- Discord/gateway: reconnect when the gateway socket closes while waiting for the shared IDENTIFY concurrency window, instead of silently skipping IDENTIFY and leaving the bot online but unresponsive. Fixes #74617. Thanks @zeeskdr-ai.
|
||||
- Telegram/startup: use the existing `getMe` request guard for the gateway bot probe instead of a fixed 2.5-second budget, and honor higher `timeoutSeconds` configs for slow Telegram API paths. Fixes #75783. Thanks @tankotan.
|
||||
- Control UI/slash commands: keep fallback command metadata on a browser-safe registry path, so provider thinking runtime imports cannot blank the Web UI with `process is not defined`. Fixes #75987. Thanks @novkien.
|
||||
- Infer/media: report missing image-understanding and audio-transcription provider configuration for `image describe`, `image describe-many`, and `audio transcribe` instead of blaming the input path when no provider is available. Fixes #73569 and supersedes #73593, #74288, and #74495. Thanks @bittoby, @tmimmanuel, @Linux2010, and @vyctorbrzezowski.
|
||||
- Docs/health: clarify that session listing surfaces stored conversation rows rather than Discord/channel socket liveness, and point connectivity checks at channel status and health probes. Fixes #70420. Thanks @ashersoutherncities-art and @martingarramon.
|
||||
- WhatsApp/Cron: keep DM pairing-store approvals out of implicit cron and heartbeat recipient fallback, so scheduled automation only uses explicit targets, active configured recipients, or configured `allowFrom` entries. Fixes #62339. Thanks @kelvinisly-collab.
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
defineChatCommand,
|
||||
} from "./commands-registry.shared.js";
|
||||
import type { ChatCommandDefinition } from "./commands-registry.types.js";
|
||||
import { listThinkingLevels } from "./thinking.js";
|
||||
|
||||
type ChannelPlugin = ReturnType<typeof listLoadedChannelPlugins>[number];
|
||||
|
||||
@@ -28,7 +29,7 @@ let cachedRegistryVersion = -1;
|
||||
|
||||
function buildChatCommands(): ChatCommandDefinition[] {
|
||||
const commands: ChatCommandDefinition[] = [
|
||||
...buildBuiltinChatCommands(),
|
||||
...buildBuiltinChatCommands({ listThinkingLevels }),
|
||||
...listLoadedChannelPlugins()
|
||||
.filter(supportsNativeCommands)
|
||||
.map((plugin) => defineDockCommand(plugin)),
|
||||
|
||||
@@ -2,11 +2,25 @@ import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js";
|
||||
import { COMMAND_ARG_FORMATTERS } from "./commands-args.js";
|
||||
import type {
|
||||
ChatCommandDefinition,
|
||||
CommandArgChoiceContext,
|
||||
CommandCategory,
|
||||
CommandScope,
|
||||
CommandTier,
|
||||
} from "./commands-registry.types.js";
|
||||
import { listThinkingLevels } from "./thinking.js";
|
||||
import { BASE_THINKING_LEVELS, type ThinkLevel } from "./thinking.shared.js";
|
||||
|
||||
type ListThinkingLevels = (
|
||||
provider?: string | null,
|
||||
model?: string | null,
|
||||
catalog?: CommandArgChoiceContext["catalog"],
|
||||
) => ThinkLevel[];
|
||||
|
||||
const BROWSER_SAFE_THINKING_LEVELS: ThinkLevel[] = [
|
||||
...BASE_THINKING_LEVELS,
|
||||
"xhigh",
|
||||
"adaptive",
|
||||
"max",
|
||||
];
|
||||
|
||||
type DefineChatCommandInput = {
|
||||
key: string;
|
||||
@@ -121,7 +135,11 @@ export function assertCommandRegistry(commands: ChatCommandDefinition[]): void {
|
||||
}
|
||||
}
|
||||
|
||||
export function buildBuiltinChatCommands(): ChatCommandDefinition[] {
|
||||
export function buildBuiltinChatCommands(
|
||||
params: { listThinkingLevels?: ListThinkingLevels } = {},
|
||||
): ChatCommandDefinition[] {
|
||||
const listThinkingLevelChoices =
|
||||
params.listThinkingLevels ?? (() => BROWSER_SAFE_THINKING_LEVELS);
|
||||
const commands: ChatCommandDefinition[] = [
|
||||
defineChatCommand({
|
||||
key: "help",
|
||||
@@ -727,7 +745,8 @@ export function buildBuiltinChatCommands(): ChatCommandDefinition[] {
|
||||
name: "level",
|
||||
description: "Thinking level",
|
||||
type: "string",
|
||||
choices: ({ provider, model, catalog }) => listThinkingLevels(provider, model, catalog),
|
||||
choices: ({ provider, model, catalog }) =>
|
||||
listThinkingLevelChoices(provider, model, catalog),
|
||||
},
|
||||
],
|
||||
argsMenu: "auto",
|
||||
|
||||
34
ui/src/ui/chat/slash-commands.browser-import.test.ts
Normal file
34
ui/src/ui/chat/slash-commands.browser-import.test.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
// @vitest-environment node
|
||||
import { readFile } from "node:fs/promises";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
describe("slash command browser import", () => {
|
||||
it("builds fallback commands from the browser-safe shared registry", async () => {
|
||||
const mod = await import("./slash-commands.ts?browser-import");
|
||||
|
||||
expect(mod.SLASH_COMMANDS.find((command) => command.name === "think")).toMatchObject({
|
||||
name: "think",
|
||||
category: "model",
|
||||
});
|
||||
});
|
||||
|
||||
it("keeps provider thinking runtime out of the Control UI import path", async () => {
|
||||
const slashCommands = await readFile(new URL("./slash-commands.ts", import.meta.url), "utf8");
|
||||
const sharedRegistry = await readFile(
|
||||
new URL("../../../../src/auto-reply/commands-registry.shared.ts", import.meta.url),
|
||||
"utf8",
|
||||
);
|
||||
const serverRegistry = await readFile(
|
||||
new URL("../../../../src/auto-reply/commands-registry.data.ts", import.meta.url),
|
||||
"utf8",
|
||||
);
|
||||
const mod = await import("./slash-commands.ts?browser-import");
|
||||
|
||||
expect(mod.SLASH_COMMANDS.some((command) => command.name === "think")).toBe(true);
|
||||
expect(slashCommands).toContain("commands-registry.shared.js");
|
||||
expect(sharedRegistry).toContain("thinking.shared.js");
|
||||
expect(sharedRegistry).not.toContain("./thinking.js");
|
||||
expect(sharedRegistry).not.toContain("provider-thinking");
|
||||
expect(serverRegistry).toContain('from "./thinking.js"');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user