mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-08 21:48:27 +00:00
test (gateway/agent): cover bare reset command routing
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
import { describe, expect, it, vi } from "vitest";
|
import { describe, expect, it, vi } from "vitest";
|
||||||
import type { GatewayRequestContext } from "./types.js";
|
import type { GatewayRequestContext } from "./types.js";
|
||||||
|
import { BARE_SESSION_RESET_PROMPT } from "../../auto-reply/reply/session-reset-prompt.js";
|
||||||
import { agentHandlers } from "./agent.js";
|
import { agentHandlers } from "./agent.js";
|
||||||
|
|
||||||
const mocks = vi.hoisted(() => ({
|
const mocks = vi.hoisted(() => ({
|
||||||
@@ -7,6 +8,7 @@ const mocks = vi.hoisted(() => ({
|
|||||||
updateSessionStore: vi.fn(),
|
updateSessionStore: vi.fn(),
|
||||||
agentCommand: vi.fn(),
|
agentCommand: vi.fn(),
|
||||||
registerAgentRunContext: vi.fn(),
|
registerAgentRunContext: vi.fn(),
|
||||||
|
sessionsResetHandler: vi.fn(),
|
||||||
loadConfigReturn: {} as Record<string, unknown>,
|
loadConfigReturn: {} as Record<string, unknown>,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -54,6 +56,13 @@ vi.mock("../../infra/agent-events.js", () => ({
|
|||||||
onAgentEvent: vi.fn(),
|
onAgentEvent: vi.fn(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
vi.mock("./sessions.js", () => ({
|
||||||
|
sessionsHandlers: {
|
||||||
|
"sessions.reset": (...args: unknown[]) =>
|
||||||
|
(mocks.sessionsResetHandler as (...args: unknown[]) => unknown)(...args),
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
vi.mock("../../sessions/send-policy.js", () => ({
|
vi.mock("../../sessions/send-policy.js", () => ({
|
||||||
resolveSendPolicy: () => "allow",
|
resolveSendPolicy: () => "allow",
|
||||||
}));
|
}));
|
||||||
@@ -273,4 +282,58 @@ describe("gateway agent handler", () => {
|
|||||||
expect(capturedStore?.["agent:main:work"]).toBeDefined();
|
expect(capturedStore?.["agent:main:work"]).toBeDefined();
|
||||||
expect(capturedStore?.["agent:main:MAIN"]).toBeUndefined();
|
expect(capturedStore?.["agent:main:MAIN"]).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("handles bare /new by resetting the same session and sending reset greeting prompt", async () => {
|
||||||
|
mocks.sessionsResetHandler.mockImplementation(
|
||||||
|
async (opts: {
|
||||||
|
params: { key: string; reason: string };
|
||||||
|
respond: (ok: boolean, payload?: unknown) => void;
|
||||||
|
}) => {
|
||||||
|
expect(opts.params.key).toBe("agent:main:main");
|
||||||
|
expect(opts.params.reason).toBe("new");
|
||||||
|
opts.respond(true, {
|
||||||
|
ok: true,
|
||||||
|
key: "agent:main:main",
|
||||||
|
entry: { sessionId: "reset-session-id" },
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
mocks.loadSessionEntry.mockReturnValue({
|
||||||
|
cfg: {},
|
||||||
|
storePath: "/tmp/sessions.json",
|
||||||
|
entry: {
|
||||||
|
sessionId: "reset-session-id",
|
||||||
|
updatedAt: Date.now(),
|
||||||
|
},
|
||||||
|
canonicalKey: "agent:main:main",
|
||||||
|
});
|
||||||
|
mocks.updateSessionStore.mockResolvedValue(undefined);
|
||||||
|
mocks.agentCommand.mockResolvedValue({
|
||||||
|
payloads: [{ text: "ok" }],
|
||||||
|
meta: { durationMs: 100 },
|
||||||
|
});
|
||||||
|
|
||||||
|
const respond = vi.fn();
|
||||||
|
await agentHandlers.agent({
|
||||||
|
params: {
|
||||||
|
message: "/new",
|
||||||
|
sessionKey: "agent:main:main",
|
||||||
|
idempotencyKey: "test-idem-new",
|
||||||
|
},
|
||||||
|
respond,
|
||||||
|
context: makeContext(),
|
||||||
|
req: { type: "req", id: "4", method: "agent" },
|
||||||
|
client: null,
|
||||||
|
isWebchatConnect: () => false,
|
||||||
|
});
|
||||||
|
|
||||||
|
await vi.waitFor(() => expect(mocks.agentCommand).toHaveBeenCalled());
|
||||||
|
expect(mocks.sessionsResetHandler).toHaveBeenCalledTimes(1);
|
||||||
|
const call = mocks.agentCommand.mock.calls.at(-1)?.[0] as
|
||||||
|
| { message?: string; sessionId?: string }
|
||||||
|
| undefined;
|
||||||
|
expect(call?.message).toBe(BARE_SESSION_RESET_PROMPT);
|
||||||
|
expect(call?.sessionId).toBe("reset-session-id");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { WebSocket } from "ws";
|
|||||||
import type { ChannelPlugin } from "../channels/plugins/types.js";
|
import type { ChannelPlugin } from "../channels/plugins/types.js";
|
||||||
import type { PluginRegistry } from "../plugins/registry.js";
|
import type { PluginRegistry } from "../plugins/registry.js";
|
||||||
import { whatsappPlugin } from "../../extensions/whatsapp/src/channel.js";
|
import { whatsappPlugin } from "../../extensions/whatsapp/src/channel.js";
|
||||||
|
import { BARE_SESSION_RESET_PROMPT } from "../auto-reply/reply/session-reset-prompt.js";
|
||||||
import { emitAgentEvent, registerAgentRunContext } from "../infra/agent-events.js";
|
import { emitAgentEvent, registerAgentRunContext } from "../infra/agent-events.js";
|
||||||
import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES } from "../utils/message-channel.js";
|
import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES } from "../utils/message-channel.js";
|
||||||
import { setRegistry } from "./server.agent.gateway-server-agent.mocks.js";
|
import { setRegistry } from "./server.agent.gateway-server-agent.mocks.js";
|
||||||
@@ -261,6 +262,32 @@ describe("gateway server agent", () => {
|
|||||||
expect(typeof call.sessionId).toBe("string");
|
expect(typeof call.sessionId).toBe("string");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("agent routes bare /new through session reset before running greeting prompt", async () => {
|
||||||
|
await useTempSessionStorePath();
|
||||||
|
await writeSessionStore({
|
||||||
|
entries: {
|
||||||
|
main: {
|
||||||
|
sessionId: "sess-main-before-reset",
|
||||||
|
updatedAt: Date.now(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const spy = vi.mocked(agentCommand);
|
||||||
|
const callsBefore = spy.mock.calls.length;
|
||||||
|
const res = await rpcReq(ws, "agent", {
|
||||||
|
message: "/new",
|
||||||
|
sessionKey: "main",
|
||||||
|
idempotencyKey: "idem-agent-new",
|
||||||
|
});
|
||||||
|
expect(res.ok).toBe(true);
|
||||||
|
|
||||||
|
await vi.waitFor(() => expect(spy.mock.calls.length).toBeGreaterThan(callsBefore));
|
||||||
|
const call = spy.mock.calls.at(-1)?.[0] as Record<string, unknown>;
|
||||||
|
expect(call.message).toBe(BARE_SESSION_RESET_PROMPT);
|
||||||
|
expect(typeof call.sessionId).toBe("string");
|
||||||
|
expect(call.sessionId).not.toBe("sess-main-before-reset");
|
||||||
|
});
|
||||||
|
|
||||||
test("agent ack response then final response", { timeout: 8000 }, async () => {
|
test("agent ack response then final response", { timeout: 8000 }, async () => {
|
||||||
const ackP = onceMessage(
|
const ackP = onceMessage(
|
||||||
ws,
|
ws,
|
||||||
|
|||||||
Reference in New Issue
Block a user