mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-27 04:47:03 -06:00
fix(ui): reset /model default through server directive (#129895)
* fix(ui): reset model through server directive * test(ui): target visible mobile transcript message
This commit is contained in:
committed by
GitHub
parent
6d1c1c9f57
commit
860e8e301f
@@ -46,14 +46,14 @@ type DefineChatCommandInput = {
|
||||
};
|
||||
|
||||
/**
|
||||
* Keep simple model selections on fast client-side patch paths. Multi-token
|
||||
* forms can carry runtime selectors or a prompt, so the server directive parser
|
||||
* must own the full atomic transaction.
|
||||
* Keep simple model selections on fast client-side patch paths. Semantic reset
|
||||
* and multi-token forms require the server directive parser to own the full
|
||||
* atomic transaction.
|
||||
*/
|
||||
export function shouldForwardModelCommandToServer(rawArgs: string): boolean {
|
||||
const args = rawArgs.trim();
|
||||
const normalized = args.toLowerCase();
|
||||
return normalized === "list" || normalized === "status" || /\s/u.test(args);
|
||||
return ["default", "list", "status"].includes(normalized) || /\s/u.test(args);
|
||||
}
|
||||
|
||||
/** Defines one command with normalized aliases, scope, and argument parsing defaults. */
|
||||
|
||||
@@ -2381,13 +2381,10 @@ describe("tui command handlers", () => {
|
||||
it.each([
|
||||
{ mode: "gateway", local: false, command: "/think default", field: "thinkingLevel" },
|
||||
{ mode: "gateway", local: false, command: "/fast default", field: "fastMode" },
|
||||
{ mode: "gateway", local: false, command: "/model default", field: "model" },
|
||||
{ mode: "embedded", local: true, command: "/think default", field: "thinkingLevel" },
|
||||
{ mode: "embedded", local: true, command: "/fast default", field: "fastMode" },
|
||||
{ mode: "embedded", local: true, command: "/model default", field: "model" },
|
||||
{ mode: "gateway", local: false, command: "/think inherit", field: "thinkingLevel" },
|
||||
{ mode: "embedded", local: true, command: "/fast reset", field: "fastMode" },
|
||||
{ mode: "gateway", local: false, command: "/model DEFAULT", field: "model" },
|
||||
])(
|
||||
"clears the $field session override for $command in $mode mode",
|
||||
async ({ local, command, field }) => {
|
||||
@@ -2994,13 +2991,24 @@ describe("tui command handlers", () => {
|
||||
expect(closeOverlay).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it.each(["codex", "openclaw"])(
|
||||
"forwards model/runtime transactions through the server directive path for %s",
|
||||
async (runtime) => {
|
||||
it.each([
|
||||
{ local: false, command: "/model default" },
|
||||
{ local: true, command: "/model default" },
|
||||
{ local: false, command: "/model DEFAULT" },
|
||||
{
|
||||
local: false,
|
||||
command: "/model openai/gpt-5.6-luna --runtime codex continue with this model",
|
||||
},
|
||||
{
|
||||
local: false,
|
||||
command: "/model openai/gpt-5.6-luna --runtime openclaw continue with this model",
|
||||
},
|
||||
])(
|
||||
"forwards $command through the server directive path (local: $local)",
|
||||
async ({ command, local }) => {
|
||||
const sendChat = vi.fn().mockResolvedValue({ status: "ok" });
|
||||
const patchSession = vi.fn();
|
||||
const command = `/model openai/gpt-5.6-luna --runtime ${runtime} continue with this model`;
|
||||
const { handleCommand } = createHarness({ sendChat, patchSession });
|
||||
const { handleCommand } = createHarness({ sendChat, patchSession, opts: { local } });
|
||||
|
||||
await handleCommand(command);
|
||||
|
||||
|
||||
@@ -173,7 +173,10 @@ suite.define(() => {
|
||||
});
|
||||
await page.goto(controlUiSessionUrl(suite.server.baseUrl, sessionKey));
|
||||
const activePane = page.locator("openclaw-chat-pane.chat-pane-cache__pane--active");
|
||||
await activePane.getByText("Mobile session menu proof.", { exact: true }).waitFor();
|
||||
await activePane
|
||||
.getByRole("paragraph")
|
||||
.filter({ hasText: /^Mobile session menu proof\.$/ })
|
||||
.waitFor();
|
||||
|
||||
const menuTrigger = activePane.getByRole("button", {
|
||||
name: "Actions for Terminal continuation",
|
||||
|
||||
@@ -3428,6 +3428,28 @@ describe("handleSendChat", () => {
|
||||
expect(refreshCurrentSessionTools).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it.each(["/model default", "/model DEFAULT"])(
|
||||
"forwards semantic model reset commands through chat.send: %s",
|
||||
async (command) => {
|
||||
const host = makeChatHost({
|
||||
requestHandlers: {
|
||||
"chat.send": { status: "started" },
|
||||
"sessions.patch": createResolvedModelPatch("default", "openai"),
|
||||
},
|
||||
sessionKey: "main",
|
||||
chatMessage: command,
|
||||
});
|
||||
|
||||
await handleSendChat(host);
|
||||
|
||||
expect(host.request).toHaveBeenCalledWith(
|
||||
"chat.send",
|
||||
expect.objectContaining({ message: command, sessionKey: "main" }),
|
||||
);
|
||||
expect(host.request).not.toHaveBeenCalledWith("sessions.patch", expect.anything());
|
||||
},
|
||||
);
|
||||
|
||||
it("queues local slash commands while the gateway client is unavailable", async () => {
|
||||
const host = makeChatHost({
|
||||
client: null,
|
||||
|
||||
Reference in New Issue
Block a user