mirror of
https://github.com/moltbot/moltbot.git
synced 2026-04-21 13:44:03 +00:00
test(auto-reply): move mixed reasoning coverage to directive seam
This commit is contained in:
@@ -20,8 +20,6 @@ import {
|
||||
} from "./reply.directive.directive-behavior.e2e-mocks.js";
|
||||
|
||||
let getReplyFromConfig: typeof import("./reply.js").getReplyFromConfig;
|
||||
let actualRunPreparedReply: typeof import("./reply/get-reply-run.js").runPreparedReply;
|
||||
const runPreparedReplyMock = vi.hoisted(() => vi.fn());
|
||||
|
||||
async function writeSkill(params: { workspaceDir: string; name: string; description: string }) {
|
||||
const { workspaceDir, name, description } = params;
|
||||
@@ -60,36 +58,6 @@ async function runThinkDirectiveAndGetText(home: string): Promise<string | undef
|
||||
return replyText(res);
|
||||
}
|
||||
|
||||
async function runInlineReasoningMessage(params: {
|
||||
home: string;
|
||||
body: string;
|
||||
storePath: string;
|
||||
blockReplies: string[];
|
||||
}) {
|
||||
return await getReplyFromConfig(
|
||||
{
|
||||
Body: params.body,
|
||||
From: "+1222",
|
||||
To: "+1222",
|
||||
Provider: "whatsapp",
|
||||
},
|
||||
{
|
||||
onBlockReply: (payload) => {
|
||||
if (payload.text) {
|
||||
params.blockReplies.push(payload.text);
|
||||
}
|
||||
},
|
||||
},
|
||||
makeWhatsAppDirectiveConfig(
|
||||
params.home,
|
||||
{ model: "anthropic/claude-opus-4-6" },
|
||||
{
|
||||
session: { store: params.storePath },
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
function makeRunConfig(home: string, storePath: string) {
|
||||
return makeWhatsAppDirectiveConfig(
|
||||
home,
|
||||
@@ -153,45 +121,10 @@ describe("directive behavior", () => {
|
||||
vi.resetModules();
|
||||
loadModelCatalogMock.mockReset();
|
||||
loadModelCatalogMock.mockResolvedValue(DEFAULT_TEST_MODEL_CATALOG);
|
||||
installFreshDirectiveBehaviorReplyMocks({
|
||||
onActualRunPreparedReply: (runPreparedReply) => {
|
||||
actualRunPreparedReply = runPreparedReply;
|
||||
},
|
||||
runPreparedReply: (...args) => runPreparedReplyMock(...args),
|
||||
});
|
||||
installFreshDirectiveBehaviorReplyMocks();
|
||||
({ getReplyFromConfig } = await import("./reply.js"));
|
||||
runPreparedReplyMock.mockReset();
|
||||
runPreparedReplyMock.mockImplementation((...args: Parameters<typeof actualRunPreparedReply>) =>
|
||||
actualRunPreparedReply(...args),
|
||||
);
|
||||
});
|
||||
|
||||
it("keeps reasoning acks out of mixed messages, including rapid repeats", async () => {
|
||||
await withTempHome(async (home) => {
|
||||
runPreparedReplyMock.mockResolvedValue({ text: "done" });
|
||||
|
||||
const blockReplies: string[] = [];
|
||||
const storePath = sessionStorePath(home);
|
||||
|
||||
const firstRes = await runInlineReasoningMessage({
|
||||
home,
|
||||
body: "please reply\n/reasoning on",
|
||||
storePath,
|
||||
blockReplies,
|
||||
});
|
||||
expect(replyTexts(firstRes)).toContain("done");
|
||||
|
||||
await runInlineReasoningMessage({
|
||||
home,
|
||||
body: "again\n/reasoning on",
|
||||
storePath,
|
||||
blockReplies,
|
||||
});
|
||||
|
||||
expect(runPreparedReplyMock).toHaveBeenCalledTimes(2);
|
||||
expect(blockReplies.length).toBe(0);
|
||||
});
|
||||
});
|
||||
it("handles standalone verbose directives and persistence", async () => {
|
||||
await withTempHome(async (home) => {
|
||||
const storePath = sessionStorePath(home);
|
||||
|
||||
122
src/auto-reply/reply/directive-handling.mixed-inline.test.ts
Normal file
122
src/auto-reply/reply/directive-handling.mixed-inline.test.ts
Normal file
@@ -0,0 +1,122 @@
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import type { OpenClawConfig } from "../../config/config.js";
|
||||
import type { SessionEntry } from "../../config/sessions.js";
|
||||
import { applyInlineDirectivesFastLane } from "./directive-handling.fast-lane.js";
|
||||
import { parseInlineDirectives } from "./directive-handling.parse.js";
|
||||
import { persistInlineDirectives } from "./directive-handling.persist.js";
|
||||
|
||||
vi.mock("../../agents/agent-scope.js", () => ({
|
||||
resolveAgentConfig: vi.fn(() => ({})),
|
||||
resolveAgentDir: vi.fn(() => "/tmp/agent"),
|
||||
resolveSessionAgentId: vi.fn(() => "main"),
|
||||
resolveDefaultAgentId: vi.fn(() => "main"),
|
||||
}));
|
||||
|
||||
vi.mock("../../agents/sandbox.js", () => ({
|
||||
resolveSandboxRuntimeStatus: vi.fn(() => ({ sandboxed: false })),
|
||||
}));
|
||||
|
||||
vi.mock("../../config/sessions/store.js", () => ({
|
||||
updateSessionStore: vi.fn(async () => {}),
|
||||
}));
|
||||
|
||||
vi.mock("../../infra/system-events.js", () => ({
|
||||
enqueueSystemEvent: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock("./queue.js", () => ({
|
||||
refreshQueuedFollowupSession: vi.fn(),
|
||||
}));
|
||||
|
||||
function createSessionEntry(overrides?: Partial<SessionEntry>): SessionEntry {
|
||||
return {
|
||||
sessionId: "session-1",
|
||||
updatedAt: Date.now(),
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
function createConfig(): OpenClawConfig {
|
||||
return {
|
||||
commands: { text: true },
|
||||
agents: { defaults: {} },
|
||||
} as unknown as OpenClawConfig;
|
||||
}
|
||||
|
||||
describe("mixed inline directives", () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it("emits directive ack while persisting inline reasoning in mixed messages", async () => {
|
||||
const directives = parseInlineDirectives("please reply\n/reasoning on");
|
||||
const cfg = createConfig();
|
||||
const sessionEntry = createSessionEntry();
|
||||
const sessionStore = { "agent:main:dm:1": sessionEntry };
|
||||
|
||||
const fastLane = await applyInlineDirectivesFastLane({
|
||||
directives,
|
||||
commandAuthorized: true,
|
||||
ctx: { Surface: "whatsapp" } as never,
|
||||
cfg,
|
||||
agentId: "main",
|
||||
isGroup: false,
|
||||
sessionEntry,
|
||||
sessionStore,
|
||||
sessionKey: "agent:main:dm:1",
|
||||
storePath: undefined,
|
||||
elevatedEnabled: false,
|
||||
elevatedAllowed: false,
|
||||
elevatedFailures: [],
|
||||
messageProviderKey: "whatsapp",
|
||||
defaultProvider: "anthropic",
|
||||
defaultModel: "claude-opus-4-6",
|
||||
aliasIndex: { byAlias: new Map(), byKey: new Map() },
|
||||
allowedModelKeys: new Set(),
|
||||
allowedModelCatalog: [],
|
||||
resetModelOverride: false,
|
||||
provider: "anthropic",
|
||||
model: "claude-opus-4-6",
|
||||
initialModelLabel: "anthropic/claude-opus-4-6",
|
||||
formatModelSwitchEvent: (label) => label,
|
||||
agentCfg: cfg.agents?.defaults,
|
||||
modelState: {
|
||||
resolveDefaultThinkingLevel: async () => "off",
|
||||
allowedModelKeys: new Set(),
|
||||
allowedModelCatalog: [],
|
||||
resetModelOverride: false,
|
||||
},
|
||||
});
|
||||
|
||||
expect(fastLane.directiveAck).toEqual({
|
||||
text: "⚙️ Reasoning visibility enabled.",
|
||||
});
|
||||
|
||||
const persisted = await persistInlineDirectives({
|
||||
directives,
|
||||
cfg,
|
||||
sessionEntry,
|
||||
sessionStore,
|
||||
sessionKey: "agent:main:dm:1",
|
||||
storePath: undefined,
|
||||
elevatedEnabled: false,
|
||||
elevatedAllowed: false,
|
||||
defaultProvider: "anthropic",
|
||||
defaultModel: "claude-opus-4-6",
|
||||
aliasIndex: { byAlias: new Map(), byKey: new Map() },
|
||||
allowedModelKeys: new Set(),
|
||||
provider: "anthropic",
|
||||
model: "claude-opus-4-6",
|
||||
initialModelLabel: "anthropic/claude-opus-4-6",
|
||||
formatModelSwitchEvent: (label) => label,
|
||||
agentCfg: cfg.agents?.defaults,
|
||||
messageProvider: "whatsapp",
|
||||
surface: "whatsapp",
|
||||
gatewayClientScopes: [],
|
||||
});
|
||||
|
||||
expect(sessionEntry.reasoningLevel).toBe("on");
|
||||
expect(persisted.provider).toBe("anthropic");
|
||||
expect(persisted.model).toBe("claude-opus-4-6");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user