mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-08 22:18:27 +00:00
test: consolidate trigger-handling suites
This commit is contained in:
@@ -3,7 +3,6 @@ import {
|
|||||||
getRunEmbeddedPiAgentMock,
|
getRunEmbeddedPiAgentMock,
|
||||||
installTriggerHandlingE2eTestHooks,
|
installTriggerHandlingE2eTestHooks,
|
||||||
makeCfg,
|
makeCfg,
|
||||||
runGreetingPromptForBareNewOrReset,
|
|
||||||
withTempHome,
|
withTempHome,
|
||||||
} from "./reply.triggers.trigger-handling.test-harness.js";
|
} from "./reply.triggers.trigger-handling.test-harness.js";
|
||||||
|
|
||||||
@@ -80,9 +79,4 @@ describe("trigger handling", () => {
|
|||||||
expect(extra).toContain("Activation: always-on");
|
expect(extra).toContain("Activation: always-on");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("runs a greeting prompt for a bare /new", async () => {
|
|
||||||
await withTempHome(async (home) => {
|
|
||||||
await runGreetingPromptForBareNewOrReset({ home, body: "/new", getReplyFromConfig });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -6,7 +6,9 @@ import {
|
|||||||
installTriggerHandlingE2eTestHooks,
|
installTriggerHandlingE2eTestHooks,
|
||||||
loadGetReplyFromConfig,
|
loadGetReplyFromConfig,
|
||||||
MAIN_SESSION_KEY,
|
MAIN_SESSION_KEY,
|
||||||
|
makeCfg,
|
||||||
makeWhatsAppElevatedCfg,
|
makeWhatsAppElevatedCfg,
|
||||||
|
readSessionStore,
|
||||||
requireSessionStorePath,
|
requireSessionStorePath,
|
||||||
withTempHome,
|
withTempHome,
|
||||||
} from "./reply.triggers.trigger-handling.test-harness.js";
|
} from "./reply.triggers.trigger-handling.test-harness.js";
|
||||||
@@ -74,4 +76,107 @@ describe("trigger handling", () => {
|
|||||||
expect(getRunEmbeddedPiAgentMock()).not.toHaveBeenCalled();
|
expect(getRunEmbeddedPiAgentMock()).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("ignores inline elevated directive for unapproved sender", async () => {
|
||||||
|
await withTempHome(async (home) => {
|
||||||
|
getRunEmbeddedPiAgentMock().mockResolvedValue({
|
||||||
|
payloads: [{ text: "ok" }],
|
||||||
|
meta: {
|
||||||
|
durationMs: 1,
|
||||||
|
agentMeta: { sessionId: "s", provider: "p", model: "m" },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const cfg = makeWhatsAppElevatedCfg(home);
|
||||||
|
|
||||||
|
const res = await getReplyFromConfig(
|
||||||
|
{
|
||||||
|
Body: "please /elevated on now",
|
||||||
|
From: "+2000",
|
||||||
|
To: "+2000",
|
||||||
|
Provider: "whatsapp",
|
||||||
|
SenderE164: "+2000",
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
cfg,
|
||||||
|
);
|
||||||
|
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
||||||
|
expect(text).not.toContain("elevated is not available right now");
|
||||||
|
expect(getRunEmbeddedPiAgentMock()).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("uses tools.elevated.allowFrom.discord for elevated approval", async () => {
|
||||||
|
await withTempHome(async (home) => {
|
||||||
|
const cfg = makeCfg(home);
|
||||||
|
cfg.tools = { elevated: { allowFrom: { discord: ["123"] } } };
|
||||||
|
|
||||||
|
const res = await getReplyFromConfig(
|
||||||
|
{
|
||||||
|
Body: "/elevated on",
|
||||||
|
From: "discord:123",
|
||||||
|
To: "user:123",
|
||||||
|
Provider: "discord",
|
||||||
|
SenderName: "Peter Steinberger",
|
||||||
|
SenderUsername: "steipete",
|
||||||
|
SenderTag: "steipete",
|
||||||
|
CommandAuthorized: true,
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
cfg,
|
||||||
|
);
|
||||||
|
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
||||||
|
expect(text).toContain("Elevated mode set to ask");
|
||||||
|
|
||||||
|
const store = await readSessionStore(cfg);
|
||||||
|
expect(store[MAIN_SESSION_KEY]?.elevatedLevel).toBe("on");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("treats explicit discord elevated allowlist as override", async () => {
|
||||||
|
await withTempHome(async (home) => {
|
||||||
|
const cfg = makeCfg(home);
|
||||||
|
cfg.tools = {
|
||||||
|
elevated: {
|
||||||
|
allowFrom: { discord: [] },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const res = await getReplyFromConfig(
|
||||||
|
{
|
||||||
|
Body: "/elevated on",
|
||||||
|
From: "discord:123",
|
||||||
|
To: "user:123",
|
||||||
|
Provider: "discord",
|
||||||
|
SenderName: "steipete",
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
cfg,
|
||||||
|
);
|
||||||
|
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
||||||
|
expect(text).toContain("tools.elevated.allowFrom.discord");
|
||||||
|
expect(getRunEmbeddedPiAgentMock()).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns a context overflow fallback when the embedded agent throws", async () => {
|
||||||
|
await withTempHome(async (home) => {
|
||||||
|
getRunEmbeddedPiAgentMock().mockRejectedValue(new Error("Context window exceeded"));
|
||||||
|
|
||||||
|
const res = await getReplyFromConfig(
|
||||||
|
{
|
||||||
|
Body: "hello",
|
||||||
|
From: "+1002",
|
||||||
|
To: "+2000",
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
makeCfg(home),
|
||||||
|
);
|
||||||
|
|
||||||
|
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
||||||
|
expect(text).toBe(
|
||||||
|
"⚠️ Context overflow — prompt too large for this model. Try a shorter message or a larger-context model.",
|
||||||
|
);
|
||||||
|
expect(getRunEmbeddedPiAgentMock()).toHaveBeenCalledOnce();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { beforeAll, describe, expect, it } from "vitest";
|
import { beforeAll, describe, expect, it } from "vitest";
|
||||||
import { loadSessionStore } from "../config/sessions.js";
|
import { loadSessionStore } from "../config/sessions.js";
|
||||||
import {
|
import {
|
||||||
expectDirectElevatedToggleOn,
|
|
||||||
installTriggerHandlingE2eTestHooks,
|
installTriggerHandlingE2eTestHooks,
|
||||||
loadGetReplyFromConfig,
|
loadGetReplyFromConfig,
|
||||||
makeWhatsAppElevatedCfg,
|
makeWhatsAppElevatedCfg,
|
||||||
@@ -69,8 +68,4 @@ describe("trigger handling", () => {
|
|||||||
expect(store["agent:main:whatsapp:group:123@g.us"]?.elevatedLevel).toBe("on");
|
expect(store["agent:main:whatsapp:group:123@g.us"]?.elevatedLevel).toBe("on");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("allows elevated directive in direct chats without mentions", async () => {
|
|
||||||
await expectDirectElevatedToggleOn({ getReplyFromConfig });
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { readFile } from "node:fs/promises";
|
|||||||
import { join } from "node:path";
|
import { join } from "node:path";
|
||||||
import { beforeAll, describe, expect, it } from "vitest";
|
import { beforeAll, describe, expect, it } from "vitest";
|
||||||
import { normalizeTestText } from "../../test/helpers/normalize-text.js";
|
import { normalizeTestText } from "../../test/helpers/normalize-text.js";
|
||||||
|
import type { OpenClawConfig } from "../config/config.js";
|
||||||
import {
|
import {
|
||||||
createBlockReplyCollector,
|
createBlockReplyCollector,
|
||||||
getProviderUsageMocks,
|
getProviderUsageMocks,
|
||||||
@@ -19,6 +20,16 @@ beforeAll(async () => {
|
|||||||
installTriggerHandlingE2eTestHooks();
|
installTriggerHandlingE2eTestHooks();
|
||||||
|
|
||||||
const usageMocks = getProviderUsageMocks();
|
const usageMocks = getProviderUsageMocks();
|
||||||
|
const modelStatusCtx = {
|
||||||
|
Body: "/model status",
|
||||||
|
From: "telegram:111",
|
||||||
|
To: "telegram:111",
|
||||||
|
ChatType: "direct",
|
||||||
|
Provider: "telegram",
|
||||||
|
Surface: "telegram",
|
||||||
|
SessionKey: "telegram:slash:111",
|
||||||
|
CommandAuthorized: true,
|
||||||
|
} as const;
|
||||||
|
|
||||||
async function readSessionStore(home: string): Promise<Record<string, unknown>> {
|
async function readSessionStore(home: string): Promise<Record<string, unknown>> {
|
||||||
const raw = await readFile(join(home, "sessions.json"), "utf-8");
|
const raw = await readFile(join(home, "sessions.json"), "utf-8");
|
||||||
@@ -260,4 +271,95 @@ describe("trigger handling", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("shows endpoint default in /model status when not configured", async () => {
|
||||||
|
await withTempHome(async (home) => {
|
||||||
|
const cfg = makeCfg(home);
|
||||||
|
const res = await getReplyFromConfig(modelStatusCtx, {}, cfg);
|
||||||
|
|
||||||
|
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
||||||
|
expect(normalizeTestText(text ?? "")).toContain("endpoint: default");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("includes endpoint details in /model status when configured", async () => {
|
||||||
|
await withTempHome(async (home) => {
|
||||||
|
const cfg = {
|
||||||
|
...makeCfg(home),
|
||||||
|
models: {
|
||||||
|
providers: {
|
||||||
|
minimax: {
|
||||||
|
baseUrl: "https://api.minimax.io/anthropic",
|
||||||
|
api: "anthropic-messages",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} as unknown as OpenClawConfig;
|
||||||
|
const res = await getReplyFromConfig(modelStatusCtx, {}, cfg);
|
||||||
|
|
||||||
|
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
||||||
|
const normalized = normalizeTestText(text ?? "");
|
||||||
|
expect(normalized).toContain(
|
||||||
|
"[minimax] endpoint: https://api.minimax.io/anthropic api: anthropic-messages auth:",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("restarts by default", async () => {
|
||||||
|
await withTempHome(async (home) => {
|
||||||
|
const runEmbeddedPiAgentMock = getRunEmbeddedPiAgentMock();
|
||||||
|
const res = await getReplyFromConfig(
|
||||||
|
{
|
||||||
|
Body: " [Dec 5] /restart",
|
||||||
|
From: "+1001",
|
||||||
|
To: "+2000",
|
||||||
|
CommandAuthorized: true,
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
makeCfg(home),
|
||||||
|
);
|
||||||
|
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
||||||
|
expect(text?.startsWith("⚙️ Restarting") || text?.startsWith("⚠️ Restart failed")).toBe(true);
|
||||||
|
expect(runEmbeddedPiAgentMock).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("rejects /restart when explicitly disabled", async () => {
|
||||||
|
await withTempHome(async (home) => {
|
||||||
|
const runEmbeddedPiAgentMock = getRunEmbeddedPiAgentMock();
|
||||||
|
const cfg = { ...makeCfg(home), commands: { restart: false } } as OpenClawConfig;
|
||||||
|
const res = await getReplyFromConfig(
|
||||||
|
{
|
||||||
|
Body: "/restart",
|
||||||
|
From: "+1001",
|
||||||
|
To: "+2000",
|
||||||
|
CommandAuthorized: true,
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
cfg,
|
||||||
|
);
|
||||||
|
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
||||||
|
expect(text).toContain("/restart is disabled");
|
||||||
|
expect(runEmbeddedPiAgentMock).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("reports status without invoking the agent", async () => {
|
||||||
|
await withTempHome(async (home) => {
|
||||||
|
const runEmbeddedPiAgentMock = getRunEmbeddedPiAgentMock();
|
||||||
|
const res = await getReplyFromConfig(
|
||||||
|
{
|
||||||
|
Body: "/status",
|
||||||
|
From: "+1002",
|
||||||
|
To: "+2000",
|
||||||
|
CommandAuthorized: true,
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
makeCfg(home),
|
||||||
|
);
|
||||||
|
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
||||||
|
expect(text).toContain("OpenClaw");
|
||||||
|
expect(runEmbeddedPiAgentMock).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -72,6 +72,18 @@ describe("trigger handling", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("handles inline /help and strips it before the agent", async () => {
|
||||||
|
await withTempHome(async (home) => {
|
||||||
|
await expectInlineCommandHandledAndStripped({
|
||||||
|
home,
|
||||||
|
getReplyFromConfig,
|
||||||
|
body: "please /help now",
|
||||||
|
stripToken: "/help",
|
||||||
|
blockReplyContains: "Help",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it("drops /status for unauthorized senders", async () => {
|
it("drops /status for unauthorized senders", async () => {
|
||||||
await withTempHome(async (home) => {
|
await withTempHome(async (home) => {
|
||||||
await expectUnauthorizedCommandDropped(home, "/status");
|
await expectUnauthorizedCommandDropped(home, "/status");
|
||||||
|
|||||||
@@ -1,120 +0,0 @@
|
|||||||
import { beforeAll, describe, expect, it } from "vitest";
|
|
||||||
import {
|
|
||||||
getRunEmbeddedPiAgentMock,
|
|
||||||
installTriggerHandlingE2eTestHooks,
|
|
||||||
loadGetReplyFromConfig,
|
|
||||||
MAIN_SESSION_KEY,
|
|
||||||
makeCfg,
|
|
||||||
makeWhatsAppElevatedCfg,
|
|
||||||
readSessionStore,
|
|
||||||
withTempHome,
|
|
||||||
} from "./reply.triggers.trigger-handling.test-harness.js";
|
|
||||||
|
|
||||||
let getReplyFromConfig: typeof import("./reply.js").getReplyFromConfig;
|
|
||||||
beforeAll(async () => {
|
|
||||||
getReplyFromConfig = await loadGetReplyFromConfig();
|
|
||||||
});
|
|
||||||
|
|
||||||
installTriggerHandlingE2eTestHooks();
|
|
||||||
|
|
||||||
describe("trigger handling", () => {
|
|
||||||
it("ignores inline elevated directive for unapproved sender", async () => {
|
|
||||||
await withTempHome(async (home) => {
|
|
||||||
getRunEmbeddedPiAgentMock().mockResolvedValue({
|
|
||||||
payloads: [{ text: "ok" }],
|
|
||||||
meta: {
|
|
||||||
durationMs: 1,
|
|
||||||
agentMeta: { sessionId: "s", provider: "p", model: "m" },
|
|
||||||
},
|
|
||||||
});
|
|
||||||
const cfg = makeWhatsAppElevatedCfg(home);
|
|
||||||
|
|
||||||
const res = await getReplyFromConfig(
|
|
||||||
{
|
|
||||||
Body: "please /elevated on now",
|
|
||||||
From: "+2000",
|
|
||||||
To: "+2000",
|
|
||||||
Provider: "whatsapp",
|
|
||||||
SenderE164: "+2000",
|
|
||||||
},
|
|
||||||
{},
|
|
||||||
cfg,
|
|
||||||
);
|
|
||||||
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
|
||||||
expect(text).not.toContain("elevated is not available right now");
|
|
||||||
expect(getRunEmbeddedPiAgentMock()).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it("uses tools.elevated.allowFrom.discord for elevated approval", async () => {
|
|
||||||
await withTempHome(async (home) => {
|
|
||||||
const cfg = makeCfg(home);
|
|
||||||
cfg.tools = { elevated: { allowFrom: { discord: ["123"] } } };
|
|
||||||
|
|
||||||
const res = await getReplyFromConfig(
|
|
||||||
{
|
|
||||||
Body: "/elevated on",
|
|
||||||
From: "discord:123",
|
|
||||||
To: "user:123",
|
|
||||||
Provider: "discord",
|
|
||||||
SenderName: "Peter Steinberger",
|
|
||||||
SenderUsername: "steipete",
|
|
||||||
SenderTag: "steipete",
|
|
||||||
CommandAuthorized: true,
|
|
||||||
},
|
|
||||||
{},
|
|
||||||
cfg,
|
|
||||||
);
|
|
||||||
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
|
||||||
expect(text).toContain("Elevated mode set to ask");
|
|
||||||
|
|
||||||
const store = await readSessionStore(cfg);
|
|
||||||
expect(store[MAIN_SESSION_KEY]?.elevatedLevel).toBe("on");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it("treats explicit discord elevated allowlist as override", async () => {
|
|
||||||
await withTempHome(async (home) => {
|
|
||||||
const cfg = makeCfg(home);
|
|
||||||
cfg.tools = {
|
|
||||||
elevated: {
|
|
||||||
allowFrom: { discord: [] },
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const res = await getReplyFromConfig(
|
|
||||||
{
|
|
||||||
Body: "/elevated on",
|
|
||||||
From: "discord:123",
|
|
||||||
To: "user:123",
|
|
||||||
Provider: "discord",
|
|
||||||
SenderName: "steipete",
|
|
||||||
},
|
|
||||||
{},
|
|
||||||
cfg,
|
|
||||||
);
|
|
||||||
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
|
||||||
expect(text).toContain("tools.elevated.allowFrom.discord");
|
|
||||||
expect(getRunEmbeddedPiAgentMock()).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it("returns a context overflow fallback when the embedded agent throws", async () => {
|
|
||||||
await withTempHome(async (home) => {
|
|
||||||
getRunEmbeddedPiAgentMock().mockRejectedValue(new Error("Context window exceeded"));
|
|
||||||
|
|
||||||
const res = await getReplyFromConfig(
|
|
||||||
{
|
|
||||||
Body: "hello",
|
|
||||||
From: "+1002",
|
|
||||||
To: "+2000",
|
|
||||||
},
|
|
||||||
{},
|
|
||||||
makeCfg(home),
|
|
||||||
);
|
|
||||||
|
|
||||||
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
|
||||||
expect(text).toBe(
|
|
||||||
"⚠️ Context overflow — prompt too large for this model. Try a shorter message or a larger-context model.",
|
|
||||||
);
|
|
||||||
expect(getRunEmbeddedPiAgentMock()).toHaveBeenCalledOnce();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -3,13 +3,10 @@ import { join } from "node:path";
|
|||||||
import { beforeAll, describe, expect, it } from "vitest";
|
import { beforeAll, describe, expect, it } from "vitest";
|
||||||
import { resolveSessionKey } from "../config/sessions.js";
|
import { resolveSessionKey } from "../config/sessions.js";
|
||||||
import {
|
import {
|
||||||
createBlockReplyCollector,
|
|
||||||
expectInlineCommandHandledAndStripped,
|
|
||||||
getRunEmbeddedPiAgentMock,
|
getRunEmbeddedPiAgentMock,
|
||||||
installTriggerHandlingE2eTestHooks,
|
installTriggerHandlingE2eTestHooks,
|
||||||
loadGetReplyFromConfig,
|
loadGetReplyFromConfig,
|
||||||
makeCfg,
|
makeCfg,
|
||||||
mockRunEmbeddedPiAgentOk,
|
|
||||||
requireSessionStorePath,
|
requireSessionStorePath,
|
||||||
withTempHome,
|
withTempHome,
|
||||||
} from "./reply.triggers.trigger-handling.test-harness.js";
|
} from "./reply.triggers.trigger-handling.test-harness.js";
|
||||||
@@ -87,43 +84,4 @@ describe("trigger handling", () => {
|
|||||||
expect(runEmbeddedPiAgentMock).not.toHaveBeenCalled();
|
expect(runEmbeddedPiAgentMock).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("strips inline /status and still runs the agent", async () => {
|
|
||||||
await withTempHome(async (home) => {
|
|
||||||
const runEmbeddedPiAgentMock = mockRunEmbeddedPiAgentOk();
|
|
||||||
const { blockReplies, handlers } = createBlockReplyCollector();
|
|
||||||
await getReplyFromConfig(
|
|
||||||
{
|
|
||||||
Body: "please /status now",
|
|
||||||
From: "+1002",
|
|
||||||
To: "+2000",
|
|
||||||
Provider: "whatsapp",
|
|
||||||
Surface: "whatsapp",
|
|
||||||
SenderE164: "+1002",
|
|
||||||
CommandAuthorized: true,
|
|
||||||
},
|
|
||||||
handlers,
|
|
||||||
makeCfg(home),
|
|
||||||
);
|
|
||||||
expect(runEmbeddedPiAgentMock).toHaveBeenCalled();
|
|
||||||
// Allowlisted senders: inline /status runs immediately (like /help) and is
|
|
||||||
// stripped from the prompt; the remaining text continues through the agent.
|
|
||||||
expect(blockReplies.length).toBe(1);
|
|
||||||
expect(String(blockReplies[0]?.text ?? "").length).toBeGreaterThan(0);
|
|
||||||
const prompt = runEmbeddedPiAgentMock.mock.calls[0]?.[0]?.prompt ?? "";
|
|
||||||
expect(prompt).not.toContain("/status");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("handles inline /help and strips it before the agent", async () => {
|
|
||||||
await withTempHome(async (home) => {
|
|
||||||
await expectInlineCommandHandledAndStripped({
|
|
||||||
home,
|
|
||||||
getReplyFromConfig,
|
|
||||||
body: "please /help now",
|
|
||||||
stripToken: "/help",
|
|
||||||
blockReplyContains: "Help",
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -52,6 +52,11 @@ describe("trigger handling", () => {
|
|||||||
await runGreetingPromptForBareNewOrReset({ home, body: "/reset", getReplyFromConfig });
|
await runGreetingPromptForBareNewOrReset({ home, body: "/reset", getReplyFromConfig });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
it("runs a greeting prompt for a bare /new", async () => {
|
||||||
|
await withTempHome(async (home) => {
|
||||||
|
await runGreetingPromptForBareNewOrReset({ home, body: "/new", getReplyFromConfig });
|
||||||
|
});
|
||||||
|
});
|
||||||
it("does not reset for unauthorized /reset", async () => {
|
it("does not reset for unauthorized /reset", async () => {
|
||||||
await withTempHome(async (home) => {
|
await withTempHome(async (home) => {
|
||||||
await expectResetBlockedForNonOwner({
|
await expectResetBlockedForNonOwner({
|
||||||
|
|||||||
@@ -1,116 +0,0 @@
|
|||||||
import { beforeAll, describe, expect, it } from "vitest";
|
|
||||||
import { normalizeTestText } from "../../test/helpers/normalize-text.js";
|
|
||||||
import type { OpenClawConfig } from "../config/config.js";
|
|
||||||
import {
|
|
||||||
getRunEmbeddedPiAgentMock,
|
|
||||||
installTriggerHandlingE2eTestHooks,
|
|
||||||
makeCfg,
|
|
||||||
withTempHome,
|
|
||||||
} from "./reply.triggers.trigger-handling.test-harness.js";
|
|
||||||
|
|
||||||
let getReplyFromConfig: typeof import("./reply.js").getReplyFromConfig;
|
|
||||||
beforeAll(async () => {
|
|
||||||
({ getReplyFromConfig } = await import("./reply.js"));
|
|
||||||
});
|
|
||||||
|
|
||||||
installTriggerHandlingE2eTestHooks();
|
|
||||||
|
|
||||||
const modelStatusCtx = {
|
|
||||||
Body: "/model status",
|
|
||||||
From: "telegram:111",
|
|
||||||
To: "telegram:111",
|
|
||||||
ChatType: "direct",
|
|
||||||
Provider: "telegram",
|
|
||||||
Surface: "telegram",
|
|
||||||
SessionKey: "telegram:slash:111",
|
|
||||||
CommandAuthorized: true,
|
|
||||||
} as const;
|
|
||||||
|
|
||||||
describe("trigger handling", () => {
|
|
||||||
it("shows endpoint default in /model status when not configured", async () => {
|
|
||||||
await withTempHome(async (home) => {
|
|
||||||
const cfg = makeCfg(home);
|
|
||||||
const res = await getReplyFromConfig(modelStatusCtx, {}, cfg);
|
|
||||||
|
|
||||||
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
|
||||||
expect(normalizeTestText(text ?? "")).toContain("endpoint: default");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it("includes endpoint details in /model status when configured", async () => {
|
|
||||||
await withTempHome(async (home) => {
|
|
||||||
const cfg = {
|
|
||||||
...makeCfg(home),
|
|
||||||
models: {
|
|
||||||
providers: {
|
|
||||||
minimax: {
|
|
||||||
baseUrl: "https://api.minimax.io/anthropic",
|
|
||||||
api: "anthropic-messages",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as unknown as OpenClawConfig;
|
|
||||||
const res = await getReplyFromConfig(modelStatusCtx, {}, cfg);
|
|
||||||
|
|
||||||
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
|
||||||
const normalized = normalizeTestText(text ?? "");
|
|
||||||
expect(normalized).toContain(
|
|
||||||
"[minimax] endpoint: https://api.minimax.io/anthropic api: anthropic-messages auth:",
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it("restarts by default", async () => {
|
|
||||||
await withTempHome(async (home) => {
|
|
||||||
const runEmbeddedPiAgentMock = getRunEmbeddedPiAgentMock();
|
|
||||||
const res = await getReplyFromConfig(
|
|
||||||
{
|
|
||||||
Body: " [Dec 5] /restart",
|
|
||||||
From: "+1001",
|
|
||||||
To: "+2000",
|
|
||||||
CommandAuthorized: true,
|
|
||||||
},
|
|
||||||
{},
|
|
||||||
makeCfg(home),
|
|
||||||
);
|
|
||||||
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
|
||||||
expect(text?.startsWith("⚙️ Restarting") || text?.startsWith("⚠️ Restart failed")).toBe(true);
|
|
||||||
expect(runEmbeddedPiAgentMock).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it("rejects /restart when explicitly disabled", async () => {
|
|
||||||
await withTempHome(async (home) => {
|
|
||||||
const runEmbeddedPiAgentMock = getRunEmbeddedPiAgentMock();
|
|
||||||
const cfg = { ...makeCfg(home), commands: { restart: false } } as OpenClawConfig;
|
|
||||||
const res = await getReplyFromConfig(
|
|
||||||
{
|
|
||||||
Body: "/restart",
|
|
||||||
From: "+1001",
|
|
||||||
To: "+2000",
|
|
||||||
CommandAuthorized: true,
|
|
||||||
},
|
|
||||||
{},
|
|
||||||
cfg,
|
|
||||||
);
|
|
||||||
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
|
||||||
expect(text).toContain("/restart is disabled");
|
|
||||||
expect(runEmbeddedPiAgentMock).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it("reports status without invoking the agent", async () => {
|
|
||||||
await withTempHome(async (home) => {
|
|
||||||
const runEmbeddedPiAgentMock = getRunEmbeddedPiAgentMock();
|
|
||||||
const res = await getReplyFromConfig(
|
|
||||||
{
|
|
||||||
Body: "/status",
|
|
||||||
From: "+1002",
|
|
||||||
To: "+2000",
|
|
||||||
CommandAuthorized: true,
|
|
||||||
},
|
|
||||||
{},
|
|
||||||
makeCfg(home),
|
|
||||||
);
|
|
||||||
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
|
||||||
expect(text).toContain("OpenClaw");
|
|
||||||
expect(runEmbeddedPiAgentMock).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
Reference in New Issue
Block a user