mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-19 07:27:28 +00:00
chore: Fix types in tests 11/N.
This commit is contained in:
@@ -92,7 +92,7 @@ describe("hooks mapping", () => {
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
expect(result?.ok).toBe(true);
|
expect(result?.ok).toBe(true);
|
||||||
if (result?.ok) {
|
if (result?.ok && result.action?.kind === "agent") {
|
||||||
expect(result.action.kind).toBe("agent");
|
expect(result.action.kind).toBe("agent");
|
||||||
expect(result.action.message).toBe("Subject: Hello");
|
expect(result.action.message).toBe("Subject: Hello");
|
||||||
}
|
}
|
||||||
@@ -146,11 +146,9 @@ describe("hooks mapping", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
expect(result?.ok).toBe(true);
|
expect(result?.ok).toBe(true);
|
||||||
if (result?.ok) {
|
if (result?.ok && result.action?.kind === "wake") {
|
||||||
expect(result.action.kind).toBe("wake");
|
expect(result.action.kind).toBe("wake");
|
||||||
if (result.action.kind === "wake") {
|
expect(result.action.text).toBe("Ping Ada");
|
||||||
expect(result.action.text).toBe("Ping Ada");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -259,7 +257,7 @@ describe("hooks mapping", () => {
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
expect(result?.ok).toBe(true);
|
expect(result?.ok).toBe(true);
|
||||||
if (result?.ok) {
|
if (result?.ok && result.action?.kind === "agent") {
|
||||||
expect(result.action.kind).toBe("agent");
|
expect(result.action.kind).toBe("agent");
|
||||||
expect(result.action.message).toBe("Override subject: Hello");
|
expect(result.action.message).toBe("Override subject: Hello");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ describe("OpenAI-compatible HTTP API (e2e)", () => {
|
|||||||
const res = await postChatCompletions(port, request.body, request.headers);
|
const res = await postChatCompletions(port, request.body, request.headers);
|
||||||
expect(res.status).toBe(200);
|
expect(res.status).toBe(200);
|
||||||
expect(agentCommand).toHaveBeenCalledTimes(1);
|
expect(agentCommand).toHaveBeenCalledTimes(1);
|
||||||
const [opts] = agentCommand.mock.calls[0] ?? [];
|
const opts = (agentCommand.mock.calls[0] as unknown[] | undefined)?.[0];
|
||||||
expect((opts as { sessionKey?: string } | undefined)?.sessionKey ?? "").toMatch(
|
expect((opts as { sessionKey?: string } | undefined)?.sessionKey ?? "").toMatch(
|
||||||
request.matcher,
|
request.matcher,
|
||||||
);
|
);
|
||||||
@@ -181,7 +181,7 @@ describe("OpenAI-compatible HTTP API (e2e)", () => {
|
|||||||
);
|
);
|
||||||
expect(res.status).toBe(200);
|
expect(res.status).toBe(200);
|
||||||
|
|
||||||
const [opts] = agentCommand.mock.calls[0] ?? [];
|
const opts = (agentCommand.mock.calls[0] as unknown[] | undefined)?.[0];
|
||||||
expect((opts as { sessionKey?: string } | undefined)?.sessionKey).toBe(
|
expect((opts as { sessionKey?: string } | undefined)?.sessionKey).toBe(
|
||||||
"agent:beta:openai:custom",
|
"agent:beta:openai:custom",
|
||||||
);
|
);
|
||||||
@@ -197,7 +197,7 @@ describe("OpenAI-compatible HTTP API (e2e)", () => {
|
|||||||
});
|
});
|
||||||
expect(res.status).toBe(200);
|
expect(res.status).toBe(200);
|
||||||
|
|
||||||
const [opts] = agentCommand.mock.calls[0] ?? [];
|
const opts = (agentCommand.mock.calls[0] as unknown[] | undefined)?.[0];
|
||||||
expect((opts as { sessionKey?: string } | undefined)?.sessionKey ?? "").toContain(
|
expect((opts as { sessionKey?: string } | undefined)?.sessionKey ?? "").toContain(
|
||||||
"openai-user:alice",
|
"openai-user:alice",
|
||||||
);
|
);
|
||||||
@@ -220,7 +220,7 @@ describe("OpenAI-compatible HTTP API (e2e)", () => {
|
|||||||
});
|
});
|
||||||
expect(res.status).toBe(200);
|
expect(res.status).toBe(200);
|
||||||
|
|
||||||
const [opts] = agentCommand.mock.calls[0] ?? [];
|
const opts = (agentCommand.mock.calls[0] as unknown[] | undefined)?.[0];
|
||||||
expect((opts as { message?: string } | undefined)?.message).toBe("hello\nworld");
|
expect((opts as { message?: string } | undefined)?.message).toBe("hello\nworld");
|
||||||
await res.text();
|
await res.text();
|
||||||
}
|
}
|
||||||
@@ -238,7 +238,7 @@ describe("OpenAI-compatible HTTP API (e2e)", () => {
|
|||||||
});
|
});
|
||||||
expect(res.status).toBe(200);
|
expect(res.status).toBe(200);
|
||||||
|
|
||||||
const [opts] = agentCommand.mock.calls[0] ?? [];
|
const opts = (agentCommand.mock.calls[0] as unknown[] | undefined)?.[0];
|
||||||
const message = (opts as { message?: string } | undefined)?.message ?? "";
|
const message = (opts as { message?: string } | undefined)?.message ?? "";
|
||||||
expect(message).toContain(HISTORY_CONTEXT_MARKER);
|
expect(message).toContain(HISTORY_CONTEXT_MARKER);
|
||||||
expect(message).toContain("User: Hello, who are you?");
|
expect(message).toContain("User: Hello, who are you?");
|
||||||
@@ -259,7 +259,7 @@ describe("OpenAI-compatible HTTP API (e2e)", () => {
|
|||||||
});
|
});
|
||||||
expect(res.status).toBe(200);
|
expect(res.status).toBe(200);
|
||||||
|
|
||||||
const [opts] = agentCommand.mock.calls[0] ?? [];
|
const opts = (agentCommand.mock.calls[0] as unknown[] | undefined)?.[0];
|
||||||
const message = (opts as { message?: string } | undefined)?.message ?? "";
|
const message = (opts as { message?: string } | undefined)?.message ?? "";
|
||||||
expect(message).not.toContain(HISTORY_CONTEXT_MARKER);
|
expect(message).not.toContain(HISTORY_CONTEXT_MARKER);
|
||||||
expect(message).not.toContain(CURRENT_MESSAGE_MARKER);
|
expect(message).not.toContain(CURRENT_MESSAGE_MARKER);
|
||||||
@@ -278,7 +278,7 @@ describe("OpenAI-compatible HTTP API (e2e)", () => {
|
|||||||
});
|
});
|
||||||
expect(res.status).toBe(200);
|
expect(res.status).toBe(200);
|
||||||
|
|
||||||
const [opts] = agentCommand.mock.calls[0] ?? [];
|
const opts = (agentCommand.mock.calls[0] as unknown[] | undefined)?.[0];
|
||||||
const extraSystemPrompt =
|
const extraSystemPrompt =
|
||||||
(opts as { extraSystemPrompt?: string } | undefined)?.extraSystemPrompt ?? "";
|
(opts as { extraSystemPrompt?: string } | undefined)?.extraSystemPrompt ?? "";
|
||||||
expect(extraSystemPrompt).toBe("You are a helpful assistant.");
|
expect(extraSystemPrompt).toBe("You are a helpful assistant.");
|
||||||
@@ -298,7 +298,7 @@ describe("OpenAI-compatible HTTP API (e2e)", () => {
|
|||||||
});
|
});
|
||||||
expect(res.status).toBe(200);
|
expect(res.status).toBe(200);
|
||||||
|
|
||||||
const [opts] = agentCommand.mock.calls[0] ?? [];
|
const opts = (agentCommand.mock.calls[0] as unknown[] | undefined)?.[0];
|
||||||
const message = (opts as { message?: string } | undefined)?.message ?? "";
|
const message = (opts as { message?: string } | undefined)?.message ?? "";
|
||||||
expect(message).toContain(HISTORY_CONTEXT_MARKER);
|
expect(message).toContain(HISTORY_CONTEXT_MARKER);
|
||||||
expect(message).toContain("User: What's the weather?");
|
expect(message).toContain("User: What's the weather?");
|
||||||
@@ -389,12 +389,12 @@ describe("OpenAI-compatible HTTP API (e2e)", () => {
|
|||||||
try {
|
try {
|
||||||
{
|
{
|
||||||
agentCommand.mockReset();
|
agentCommand.mockReset();
|
||||||
agentCommand.mockImplementationOnce(async (opts: unknown) => {
|
agentCommand.mockImplementationOnce((async (opts: unknown) => {
|
||||||
const runId = (opts as { runId?: string } | undefined)?.runId ?? "";
|
const runId = (opts as { runId?: string } | undefined)?.runId ?? "";
|
||||||
emitAgentEvent({ runId, stream: "assistant", data: { delta: "he" } });
|
emitAgentEvent({ runId, stream: "assistant", data: { delta: "he" } });
|
||||||
emitAgentEvent({ runId, stream: "assistant", data: { delta: "llo" } });
|
emitAgentEvent({ runId, stream: "assistant", data: { delta: "llo" } });
|
||||||
return { payloads: [{ text: "hello" }] } as never;
|
return { payloads: [{ text: "hello" }] } as never;
|
||||||
});
|
}) as never);
|
||||||
|
|
||||||
const res = await postChatCompletions(port, {
|
const res = await postChatCompletions(port, {
|
||||||
stream: true,
|
stream: true,
|
||||||
@@ -422,12 +422,12 @@ describe("OpenAI-compatible HTTP API (e2e)", () => {
|
|||||||
|
|
||||||
{
|
{
|
||||||
agentCommand.mockReset();
|
agentCommand.mockReset();
|
||||||
agentCommand.mockImplementationOnce(async (opts: unknown) => {
|
agentCommand.mockImplementationOnce((async (opts: unknown) => {
|
||||||
const runId = (opts as { runId?: string } | undefined)?.runId ?? "";
|
const runId = (opts as { runId?: string } | undefined)?.runId ?? "";
|
||||||
emitAgentEvent({ runId, stream: "assistant", data: { delta: "hi" } });
|
emitAgentEvent({ runId, stream: "assistant", data: { delta: "hi" } });
|
||||||
emitAgentEvent({ runId, stream: "assistant", data: { delta: "hi" } });
|
emitAgentEvent({ runId, stream: "assistant", data: { delta: "hi" } });
|
||||||
return { payloads: [{ text: "hihi" }] } as never;
|
return { payloads: [{ text: "hihi" }] } as never;
|
||||||
});
|
}) as never);
|
||||||
|
|
||||||
const repeatedRes = await postChatCompletions(port, {
|
const repeatedRes = await postChatCompletions(port, {
|
||||||
stream: true,
|
stream: true,
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ describe("OpenResponses HTTP API (e2e)", () => {
|
|||||||
{ "x-openclaw-agent-id": "beta" },
|
{ "x-openclaw-agent-id": "beta" },
|
||||||
);
|
);
|
||||||
expect(resHeader.status).toBe(200);
|
expect(resHeader.status).toBe(200);
|
||||||
const [optsHeader] = agentCommand.mock.calls[0] ?? [];
|
const optsHeader = (agentCommand.mock.calls[0] as unknown[] | undefined)?.[0];
|
||||||
expect((optsHeader as { sessionKey?: string } | undefined)?.sessionKey ?? "").toMatch(
|
expect((optsHeader as { sessionKey?: string } | undefined)?.sessionKey ?? "").toMatch(
|
||||||
/^agent:beta:/,
|
/^agent:beta:/,
|
||||||
);
|
);
|
||||||
@@ -167,7 +167,7 @@ describe("OpenResponses HTTP API (e2e)", () => {
|
|||||||
mockAgentOnce([{ text: "hello" }]);
|
mockAgentOnce([{ text: "hello" }]);
|
||||||
const resModel = await postResponses(port, { model: "openclaw:beta", input: "hi" });
|
const resModel = await postResponses(port, { model: "openclaw:beta", input: "hi" });
|
||||||
expect(resModel.status).toBe(200);
|
expect(resModel.status).toBe(200);
|
||||||
const [optsModel] = agentCommand.mock.calls[0] ?? [];
|
const optsModel = (agentCommand.mock.calls[0] as unknown[] | undefined)?.[0];
|
||||||
expect((optsModel as { sessionKey?: string } | undefined)?.sessionKey ?? "").toMatch(
|
expect((optsModel as { sessionKey?: string } | undefined)?.sessionKey ?? "").toMatch(
|
||||||
/^agent:beta:/,
|
/^agent:beta:/,
|
||||||
);
|
);
|
||||||
@@ -180,7 +180,7 @@ describe("OpenResponses HTTP API (e2e)", () => {
|
|||||||
input: "hi",
|
input: "hi",
|
||||||
});
|
});
|
||||||
expect(resUser.status).toBe(200);
|
expect(resUser.status).toBe(200);
|
||||||
const [optsUser] = agentCommand.mock.calls[0] ?? [];
|
const optsUser = (agentCommand.mock.calls[0] as unknown[] | undefined)?.[0];
|
||||||
expect((optsUser as { sessionKey?: string } | undefined)?.sessionKey ?? "").toContain(
|
expect((optsUser as { sessionKey?: string } | undefined)?.sessionKey ?? "").toContain(
|
||||||
"openresponses-user:alice",
|
"openresponses-user:alice",
|
||||||
);
|
);
|
||||||
@@ -192,7 +192,7 @@ describe("OpenResponses HTTP API (e2e)", () => {
|
|||||||
input: "hello world",
|
input: "hello world",
|
||||||
});
|
});
|
||||||
expect(resString.status).toBe(200);
|
expect(resString.status).toBe(200);
|
||||||
const [optsString] = agentCommand.mock.calls[0] ?? [];
|
const optsString = (agentCommand.mock.calls[0] as unknown[] | undefined)?.[0];
|
||||||
expect((optsString as { message?: string } | undefined)?.message).toBe("hello world");
|
expect((optsString as { message?: string } | undefined)?.message).toBe("hello world");
|
||||||
await ensureResponseConsumed(resString);
|
await ensureResponseConsumed(resString);
|
||||||
|
|
||||||
@@ -202,7 +202,7 @@ describe("OpenResponses HTTP API (e2e)", () => {
|
|||||||
input: [{ type: "message", role: "user", content: "hello there" }],
|
input: [{ type: "message", role: "user", content: "hello there" }],
|
||||||
});
|
});
|
||||||
expect(resArray.status).toBe(200);
|
expect(resArray.status).toBe(200);
|
||||||
const [optsArray] = agentCommand.mock.calls[0] ?? [];
|
const optsArray = (agentCommand.mock.calls[0] as unknown[] | undefined)?.[0];
|
||||||
expect((optsArray as { message?: string } | undefined)?.message).toBe("hello there");
|
expect((optsArray as { message?: string } | undefined)?.message).toBe("hello there");
|
||||||
await ensureResponseConsumed(resArray);
|
await ensureResponseConsumed(resArray);
|
||||||
|
|
||||||
@@ -216,7 +216,7 @@ describe("OpenResponses HTTP API (e2e)", () => {
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
expect(resSystemDeveloper.status).toBe(200);
|
expect(resSystemDeveloper.status).toBe(200);
|
||||||
const [optsSystemDeveloper] = agentCommand.mock.calls[0] ?? [];
|
const optsSystemDeveloper = (agentCommand.mock.calls[0] as unknown[] | undefined)?.[0];
|
||||||
const extraSystemPrompt =
|
const extraSystemPrompt =
|
||||||
(optsSystemDeveloper as { extraSystemPrompt?: string } | undefined)?.extraSystemPrompt ??
|
(optsSystemDeveloper as { extraSystemPrompt?: string } | undefined)?.extraSystemPrompt ??
|
||||||
"";
|
"";
|
||||||
@@ -231,7 +231,7 @@ describe("OpenResponses HTTP API (e2e)", () => {
|
|||||||
instructions: "Always respond in French.",
|
instructions: "Always respond in French.",
|
||||||
});
|
});
|
||||||
expect(resInstructions.status).toBe(200);
|
expect(resInstructions.status).toBe(200);
|
||||||
const [optsInstructions] = agentCommand.mock.calls[0] ?? [];
|
const optsInstructions = (agentCommand.mock.calls[0] as unknown[] | undefined)?.[0];
|
||||||
const instructionPrompt =
|
const instructionPrompt =
|
||||||
(optsInstructions as { extraSystemPrompt?: string } | undefined)?.extraSystemPrompt ?? "";
|
(optsInstructions as { extraSystemPrompt?: string } | undefined)?.extraSystemPrompt ?? "";
|
||||||
expect(instructionPrompt).toContain("Always respond in French.");
|
expect(instructionPrompt).toContain("Always respond in French.");
|
||||||
@@ -248,7 +248,7 @@ describe("OpenResponses HTTP API (e2e)", () => {
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
expect(resHistory.status).toBe(200);
|
expect(resHistory.status).toBe(200);
|
||||||
const [optsHistory] = agentCommand.mock.calls[0] ?? [];
|
const optsHistory = (agentCommand.mock.calls[0] as unknown[] | undefined)?.[0];
|
||||||
const historyMessage = (optsHistory as { message?: string } | undefined)?.message ?? "";
|
const historyMessage = (optsHistory as { message?: string } | undefined)?.message ?? "";
|
||||||
expect(historyMessage).toContain(HISTORY_CONTEXT_MARKER);
|
expect(historyMessage).toContain(HISTORY_CONTEXT_MARKER);
|
||||||
expect(historyMessage).toContain("User: Hello, who are you?");
|
expect(historyMessage).toContain("User: Hello, who are you?");
|
||||||
@@ -266,7 +266,7 @@ describe("OpenResponses HTTP API (e2e)", () => {
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
expect(resFunctionOutput.status).toBe(200);
|
expect(resFunctionOutput.status).toBe(200);
|
||||||
const [optsFunctionOutput] = agentCommand.mock.calls[0] ?? [];
|
const optsFunctionOutput = (agentCommand.mock.calls[0] as unknown[] | undefined)?.[0];
|
||||||
const functionOutputMessage =
|
const functionOutputMessage =
|
||||||
(optsFunctionOutput as { message?: string } | undefined)?.message ?? "";
|
(optsFunctionOutput as { message?: string } | undefined)?.message ?? "";
|
||||||
expect(functionOutputMessage).toContain("Sunny, 70F.");
|
expect(functionOutputMessage).toContain("Sunny, 70F.");
|
||||||
@@ -295,7 +295,7 @@ describe("OpenResponses HTTP API (e2e)", () => {
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
expect(resInputFile.status).toBe(200);
|
expect(resInputFile.status).toBe(200);
|
||||||
const [optsInputFile] = agentCommand.mock.calls[0] ?? [];
|
const optsInputFile = (agentCommand.mock.calls[0] as unknown[] | undefined)?.[0];
|
||||||
const inputFileMessage = (optsInputFile as { message?: string } | undefined)?.message ?? "";
|
const inputFileMessage = (optsInputFile as { message?: string } | undefined)?.message ?? "";
|
||||||
const inputFilePrompt =
|
const inputFilePrompt =
|
||||||
(optsInputFile as { extraSystemPrompt?: string } | undefined)?.extraSystemPrompt ?? "";
|
(optsInputFile as { extraSystemPrompt?: string } | undefined)?.extraSystemPrompt ?? "";
|
||||||
@@ -316,7 +316,7 @@ describe("OpenResponses HTTP API (e2e)", () => {
|
|||||||
tool_choice: "none",
|
tool_choice: "none",
|
||||||
});
|
});
|
||||||
expect(resToolNone.status).toBe(200);
|
expect(resToolNone.status).toBe(200);
|
||||||
const [optsToolNone] = agentCommand.mock.calls[0] ?? [];
|
const optsToolNone = (agentCommand.mock.calls[0] as unknown[] | undefined)?.[0];
|
||||||
expect(
|
expect(
|
||||||
(optsToolNone as { clientTools?: unknown[] } | undefined)?.clientTools,
|
(optsToolNone as { clientTools?: unknown[] } | undefined)?.clientTools,
|
||||||
).toBeUndefined();
|
).toBeUndefined();
|
||||||
@@ -339,9 +339,9 @@ describe("OpenResponses HTTP API (e2e)", () => {
|
|||||||
tool_choice: { type: "function", function: { name: "get_time" } },
|
tool_choice: { type: "function", function: { name: "get_time" } },
|
||||||
});
|
});
|
||||||
expect(resToolChoice.status).toBe(200);
|
expect(resToolChoice.status).toBe(200);
|
||||||
const [optsToolChoice] = agentCommand.mock.calls[0] ?? [];
|
const optsToolChoice = (agentCommand.mock.calls[0] as unknown[] | undefined)?.[0];
|
||||||
const clientTools =
|
const clientTools =
|
||||||
(optsToolChoice as { clientTools?: Array<{ function?: { name?: string } }> })
|
(optsToolChoice as { clientTools?: Array<{ function?: { name?: string } }> } | undefined)
|
||||||
?.clientTools ?? [];
|
?.clientTools ?? [];
|
||||||
expect(clientTools).toHaveLength(1);
|
expect(clientTools).toHaveLength(1);
|
||||||
expect(clientTools[0]?.function?.name).toBe("get_time");
|
expect(clientTools[0]?.function?.name).toBe("get_time");
|
||||||
@@ -368,7 +368,7 @@ describe("OpenResponses HTTP API (e2e)", () => {
|
|||||||
max_output_tokens: 123,
|
max_output_tokens: 123,
|
||||||
});
|
});
|
||||||
expect(resMaxTokens.status).toBe(200);
|
expect(resMaxTokens.status).toBe(200);
|
||||||
const [optsMaxTokens] = agentCommand.mock.calls[0] ?? [];
|
const optsMaxTokens = (agentCommand.mock.calls[0] as unknown[] | undefined)?.[0];
|
||||||
expect(
|
expect(
|
||||||
(optsMaxTokens as { streamParams?: { maxTokens?: number } } | undefined)?.streamParams
|
(optsMaxTokens as { streamParams?: { maxTokens?: number } } | undefined)?.streamParams
|
||||||
?.maxTokens,
|
?.maxTokens,
|
||||||
@@ -433,12 +433,12 @@ describe("OpenResponses HTTP API (e2e)", () => {
|
|||||||
const port = enabledPort;
|
const port = enabledPort;
|
||||||
try {
|
try {
|
||||||
agentCommand.mockReset();
|
agentCommand.mockReset();
|
||||||
agentCommand.mockImplementationOnce(async (opts: unknown) => {
|
agentCommand.mockImplementationOnce((async (opts: unknown) => {
|
||||||
const runId = (opts as { runId?: string } | undefined)?.runId ?? "";
|
const runId = (opts as { runId?: string } | undefined)?.runId ?? "";
|
||||||
emitAgentEvent({ runId, stream: "assistant", data: { delta: "he" } });
|
emitAgentEvent({ runId, stream: "assistant", data: { delta: "he" } });
|
||||||
emitAgentEvent({ runId, stream: "assistant", data: { delta: "llo" } });
|
emitAgentEvent({ runId, stream: "assistant", data: { delta: "llo" } });
|
||||||
return { payloads: [{ text: "hello" }] } as never;
|
return { payloads: [{ text: "hello" }] } as never;
|
||||||
});
|
}) as never);
|
||||||
|
|
||||||
const resDelta = await postResponses(port, {
|
const resDelta = await postResponses(port, {
|
||||||
stream: true,
|
stream: true,
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ describe("gateway server hooks", () => {
|
|||||||
});
|
});
|
||||||
expect(resAgentModel.status).toBe(202);
|
expect(resAgentModel.status).toBe(202);
|
||||||
await waitForSystemEvent();
|
await waitForSystemEvent();
|
||||||
const call = cronIsolatedRun.mock.calls[0]?.[0] as {
|
const call = (cronIsolatedRun.mock.calls[0] as unknown[] | undefined)?.[0] as {
|
||||||
job?: { payload?: { model?: string } };
|
job?: { payload?: { model?: string } };
|
||||||
};
|
};
|
||||||
expect(call?.job?.payload?.model).toBe("openai/gpt-4.1-mini");
|
expect(call?.job?.payload?.model).toBe("openai/gpt-4.1-mini");
|
||||||
@@ -98,7 +98,7 @@ describe("gateway server hooks", () => {
|
|||||||
});
|
});
|
||||||
expect(resAgentWithId.status).toBe(202);
|
expect(resAgentWithId.status).toBe(202);
|
||||||
await waitForSystemEvent();
|
await waitForSystemEvent();
|
||||||
const routedCall = cronIsolatedRun.mock.calls[0]?.[0] as {
|
const routedCall = (cronIsolatedRun.mock.calls[0] as unknown[] | undefined)?.[0] as {
|
||||||
job?: { agentId?: string };
|
job?: { agentId?: string };
|
||||||
};
|
};
|
||||||
expect(routedCall?.job?.agentId).toBe("hooks");
|
expect(routedCall?.job?.agentId).toBe("hooks");
|
||||||
@@ -119,7 +119,7 @@ describe("gateway server hooks", () => {
|
|||||||
});
|
});
|
||||||
expect(resAgentUnknown.status).toBe(202);
|
expect(resAgentUnknown.status).toBe(202);
|
||||||
await waitForSystemEvent();
|
await waitForSystemEvent();
|
||||||
const fallbackCall = cronIsolatedRun.mock.calls[0]?.[0] as {
|
const fallbackCall = (cronIsolatedRun.mock.calls[0] as unknown[] | undefined)?.[0] as {
|
||||||
job?: { agentId?: string };
|
job?: { agentId?: string };
|
||||||
};
|
};
|
||||||
expect(fallbackCall?.job?.agentId).toBe("main");
|
expect(fallbackCall?.job?.agentId).toBe("main");
|
||||||
@@ -250,7 +250,9 @@ describe("gateway server hooks", () => {
|
|||||||
});
|
});
|
||||||
expect(defaultRoute.status).toBe(202);
|
expect(defaultRoute.status).toBe(202);
|
||||||
await waitForSystemEvent();
|
await waitForSystemEvent();
|
||||||
const defaultCall = cronIsolatedRun.mock.calls[0]?.[0] as { sessionKey?: string } | undefined;
|
const defaultCall = (cronIsolatedRun.mock.calls[0] as unknown[] | undefined)?.[0] as
|
||||||
|
| { sessionKey?: string }
|
||||||
|
| undefined;
|
||||||
expect(defaultCall?.sessionKey).toBe("hook:ingress");
|
expect(defaultCall?.sessionKey).toBe("hook:ingress");
|
||||||
drainSystemEvents(resolveMainKey());
|
drainSystemEvents(resolveMainKey());
|
||||||
|
|
||||||
@@ -266,7 +268,9 @@ describe("gateway server hooks", () => {
|
|||||||
});
|
});
|
||||||
expect(mappedOk.status).toBe(202);
|
expect(mappedOk.status).toBe(202);
|
||||||
await waitForSystemEvent();
|
await waitForSystemEvent();
|
||||||
const mappedCall = cronIsolatedRun.mock.calls[0]?.[0] as { sessionKey?: string } | undefined;
|
const mappedCall = (cronIsolatedRun.mock.calls[0] as unknown[] | undefined)?.[0] as
|
||||||
|
| { sessionKey?: string }
|
||||||
|
| undefined;
|
||||||
expect(mappedCall?.sessionKey).toBe("hook:mapped:42");
|
expect(mappedCall?.sessionKey).toBe("hook:mapped:42");
|
||||||
drainSystemEvents(resolveMainKey());
|
drainSystemEvents(resolveMainKey());
|
||||||
|
|
||||||
@@ -328,7 +332,7 @@ describe("gateway server hooks", () => {
|
|||||||
});
|
});
|
||||||
expect(resNoAgent.status).toBe(202);
|
expect(resNoAgent.status).toBe(202);
|
||||||
await waitForSystemEvent();
|
await waitForSystemEvent();
|
||||||
const noAgentCall = cronIsolatedRun.mock.calls[0]?.[0] as {
|
const noAgentCall = (cronIsolatedRun.mock.calls[0] as unknown[] | undefined)?.[0] as {
|
||||||
job?: { agentId?: string };
|
job?: { agentId?: string };
|
||||||
};
|
};
|
||||||
expect(noAgentCall?.job?.agentId).toBeUndefined();
|
expect(noAgentCall?.job?.agentId).toBeUndefined();
|
||||||
@@ -349,7 +353,7 @@ describe("gateway server hooks", () => {
|
|||||||
});
|
});
|
||||||
expect(resAllowed.status).toBe(202);
|
expect(resAllowed.status).toBe(202);
|
||||||
await waitForSystemEvent();
|
await waitForSystemEvent();
|
||||||
const allowedCall = cronIsolatedRun.mock.calls[0]?.[0] as {
|
const allowedCall = (cronIsolatedRun.mock.calls[0] as unknown[] | undefined)?.[0] as {
|
||||||
job?: { agentId?: string };
|
job?: { agentId?: string };
|
||||||
};
|
};
|
||||||
expect(allowedCall?.job?.agentId).toBe("hooks");
|
expect(allowedCall?.job?.agentId).toBe("hooks");
|
||||||
|
|||||||
@@ -1,14 +1,20 @@
|
|||||||
import { describe, expect, it, vi } from "vitest";
|
import { describe, expect, it, vi } from "vitest";
|
||||||
import { buildDispatchInboundCaptureMock } from "../../../test/helpers/dispatch-inbound-capture.js";
|
import { buildDispatchInboundCaptureMock } from "../../../test/helpers/dispatch-inbound-capture.js";
|
||||||
import type { MsgContext } from "../../auto-reply/templating.js";
|
import type { MsgContext } from "../../auto-reply/templating.js";
|
||||||
|
import type { OpenClawConfig } from "../../config/types.js";
|
||||||
import { createBaseSignalEventHandlerDeps } from "./event-handler.test-harness.js";
|
import { createBaseSignalEventHandlerDeps } from "./event-handler.test-harness.js";
|
||||||
|
|
||||||
let capturedCtx: MsgContext | undefined;
|
type SignalMsgContext = MsgContext & {
|
||||||
|
Body?: string;
|
||||||
|
WasMentioned?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
let capturedCtx: SignalMsgContext | undefined;
|
||||||
|
|
||||||
vi.mock("../../auto-reply/dispatch.js", async (importOriginal) => {
|
vi.mock("../../auto-reply/dispatch.js", async (importOriginal) => {
|
||||||
const actual = await importOriginal<typeof import("../../auto-reply/dispatch.js")>();
|
const actual = await importOriginal<typeof import("../../auto-reply/dispatch.js")>();
|
||||||
return buildDispatchInboundCaptureMock(actual, (ctx) => {
|
return buildDispatchInboundCaptureMock(actual, (ctx) => {
|
||||||
capturedCtx = ctx as MsgContext;
|
capturedCtx = ctx as SignalMsgContext;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -51,10 +57,7 @@ function createMentionGatedHistoryHandler() {
|
|||||||
const groupHistories = new Map();
|
const groupHistories = new Map();
|
||||||
const handler = createSignalEventHandler(
|
const handler = createSignalEventHandler(
|
||||||
createBaseSignalEventHandlerDeps({
|
createBaseSignalEventHandlerDeps({
|
||||||
cfg: {
|
cfg: createSignalConfig({ requireMention: true }),
|
||||||
messages: { inbound: { debounceMs: 0 }, groupChat: { mentionPatterns: ["@bot"] } },
|
|
||||||
channels: { signal: { groups: { "*": { requireMention: true } } } },
|
|
||||||
},
|
|
||||||
historyLimit: 5,
|
historyLimit: 5,
|
||||||
groupHistories,
|
groupHistories,
|
||||||
}),
|
}),
|
||||||
@@ -62,6 +65,20 @@ function createMentionGatedHistoryHandler() {
|
|||||||
return { handler, groupHistories };
|
return { handler, groupHistories };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createSignalConfig(params: { requireMention: boolean; mentionPattern?: string }) {
|
||||||
|
return {
|
||||||
|
messages: {
|
||||||
|
inbound: { debounceMs: 0 },
|
||||||
|
groupChat: { mentionPatterns: [params.mentionPattern ?? "@bot"] },
|
||||||
|
},
|
||||||
|
channels: {
|
||||||
|
signal: {
|
||||||
|
groups: { "*": { requireMention: params.requireMention } },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} as unknown as OpenClawConfig;
|
||||||
|
}
|
||||||
|
|
||||||
async function expectSkippedGroupHistory(opts: GroupEventOpts, expectedBody: string) {
|
async function expectSkippedGroupHistory(opts: GroupEventOpts, expectedBody: string) {
|
||||||
capturedCtx = undefined;
|
capturedCtx = undefined;
|
||||||
const { handler, groupHistories } = createMentionGatedHistoryHandler();
|
const { handler, groupHistories } = createMentionGatedHistoryHandler();
|
||||||
@@ -78,10 +95,7 @@ describe("signal mention gating", () => {
|
|||||||
capturedCtx = undefined;
|
capturedCtx = undefined;
|
||||||
const handler = createSignalEventHandler(
|
const handler = createSignalEventHandler(
|
||||||
createBaseSignalEventHandlerDeps({
|
createBaseSignalEventHandlerDeps({
|
||||||
cfg: {
|
cfg: createSignalConfig({ requireMention: true }),
|
||||||
messages: { inbound: { debounceMs: 0 }, groupChat: { mentionPatterns: ["@bot"] } },
|
|
||||||
channels: { signal: { groups: { "*": { requireMention: true } } } },
|
|
||||||
},
|
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -93,10 +107,7 @@ describe("signal mention gating", () => {
|
|||||||
capturedCtx = undefined;
|
capturedCtx = undefined;
|
||||||
const handler = createSignalEventHandler(
|
const handler = createSignalEventHandler(
|
||||||
createBaseSignalEventHandlerDeps({
|
createBaseSignalEventHandlerDeps({
|
||||||
cfg: {
|
cfg: createSignalConfig({ requireMention: true }),
|
||||||
messages: { inbound: { debounceMs: 0 }, groupChat: { mentionPatterns: ["@bot"] } },
|
|
||||||
channels: { signal: { groups: { "*": { requireMention: true } } } },
|
|
||||||
},
|
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -109,10 +120,7 @@ describe("signal mention gating", () => {
|
|||||||
capturedCtx = undefined;
|
capturedCtx = undefined;
|
||||||
const handler = createSignalEventHandler(
|
const handler = createSignalEventHandler(
|
||||||
createBaseSignalEventHandlerDeps({
|
createBaseSignalEventHandlerDeps({
|
||||||
cfg: {
|
cfg: createSignalConfig({ requireMention: false }),
|
||||||
messages: { inbound: { debounceMs: 0 }, groupChat: { mentionPatterns: ["@bot"] } },
|
|
||||||
channels: { signal: { groups: { "*": { requireMention: false } } } },
|
|
||||||
},
|
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -147,10 +155,7 @@ describe("signal mention gating", () => {
|
|||||||
capturedCtx = undefined;
|
capturedCtx = undefined;
|
||||||
const handler = createSignalEventHandler(
|
const handler = createSignalEventHandler(
|
||||||
createBaseSignalEventHandlerDeps({
|
createBaseSignalEventHandlerDeps({
|
||||||
cfg: {
|
cfg: createSignalConfig({ requireMention: true }),
|
||||||
messages: { inbound: { debounceMs: 0 }, groupChat: { mentionPatterns: ["@bot"] } },
|
|
||||||
channels: { signal: { groups: { "*": { requireMention: true } } } },
|
|
||||||
},
|
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -162,10 +167,7 @@ describe("signal mention gating", () => {
|
|||||||
capturedCtx = undefined;
|
capturedCtx = undefined;
|
||||||
const handler = createSignalEventHandler(
|
const handler = createSignalEventHandler(
|
||||||
createBaseSignalEventHandlerDeps({
|
createBaseSignalEventHandlerDeps({
|
||||||
cfg: {
|
cfg: createSignalConfig({ requireMention: false }),
|
||||||
messages: { inbound: { debounceMs: 0 }, groupChat: { mentionPatterns: ["@bot"] } },
|
|
||||||
channels: { signal: { groups: { "*": { requireMention: false } } } },
|
|
||||||
},
|
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -194,10 +196,7 @@ describe("signal mention gating", () => {
|
|||||||
capturedCtx = undefined;
|
capturedCtx = undefined;
|
||||||
const handler = createSignalEventHandler(
|
const handler = createSignalEventHandler(
|
||||||
createBaseSignalEventHandlerDeps({
|
createBaseSignalEventHandlerDeps({
|
||||||
cfg: {
|
cfg: createSignalConfig({ requireMention: true, mentionPattern: "@123e4567" }),
|
||||||
messages: { inbound: { debounceMs: 0 }, groupChat: { mentionPatterns: ["@123e4567"] } },
|
|
||||||
channels: { signal: { groups: { "*": { requireMention: true } } } },
|
|
||||||
},
|
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ async function createBotHandlerWithOptions(options: {
|
|||||||
}> {
|
}> {
|
||||||
const { createTelegramBot } = await import("./bot.js");
|
const { createTelegramBot } = await import("./bot.js");
|
||||||
const replyModule = await import("../auto-reply/reply.js");
|
const replyModule = await import("../auto-reply/reply.js");
|
||||||
const replySpy = replyModule.__replySpy as unknown as ReturnType<typeof vi.fn>;
|
const replySpy = (replyModule as { __replySpy: ReturnType<typeof vi.fn> }).__replySpy;
|
||||||
|
|
||||||
onSpy.mockReset();
|
onSpy.mockReset();
|
||||||
replySpy.mockReset();
|
replySpy.mockReset();
|
||||||
@@ -49,8 +49,8 @@ async function createBotHandlerWithOptions(options: {
|
|||||||
testTimings: TELEGRAM_TEST_TIMINGS,
|
testTimings: TELEGRAM_TEST_TIMINGS,
|
||||||
...(options.proxyFetch ? { proxyFetch: options.proxyFetch } : {}),
|
...(options.proxyFetch ? { proxyFetch: options.proxyFetch } : {}),
|
||||||
runtime: {
|
runtime: {
|
||||||
log: runtimeLog,
|
log: runtimeLog as (...data: unknown[]) => void,
|
||||||
error: runtimeError,
|
error: runtimeError as (...data: unknown[]) => void,
|
||||||
exit: () => {
|
exit: () => {
|
||||||
throw new Error("exit");
|
throw new Error("exit");
|
||||||
},
|
},
|
||||||
@@ -67,23 +67,23 @@ function mockTelegramFileDownload(params: {
|
|||||||
contentType: string;
|
contentType: string;
|
||||||
bytes: Uint8Array;
|
bytes: Uint8Array;
|
||||||
}): ReturnType<typeof vi.spyOn> {
|
}): ReturnType<typeof vi.spyOn> {
|
||||||
return vi.spyOn(globalThis, "fetch" as never).mockResolvedValueOnce({
|
return vi.spyOn(globalThis, "fetch").mockResolvedValueOnce({
|
||||||
ok: true,
|
ok: true,
|
||||||
status: 200,
|
status: 200,
|
||||||
statusText: "OK",
|
statusText: "OK",
|
||||||
headers: { get: () => params.contentType },
|
headers: { get: () => params.contentType },
|
||||||
arrayBuffer: async () => params.bytes.buffer,
|
arrayBuffer: async () => params.bytes.buffer,
|
||||||
} as Response);
|
} as unknown as Response);
|
||||||
}
|
}
|
||||||
|
|
||||||
function mockTelegramPngDownload(): ReturnType<typeof vi.spyOn> {
|
function mockTelegramPngDownload(): ReturnType<typeof vi.spyOn> {
|
||||||
return vi.spyOn(globalThis, "fetch" as never).mockResolvedValue({
|
return vi.spyOn(globalThis, "fetch").mockResolvedValue({
|
||||||
ok: true,
|
ok: true,
|
||||||
status: 200,
|
status: 200,
|
||||||
statusText: "OK",
|
statusText: "OK",
|
||||||
headers: { get: () => "image/png" },
|
headers: { get: () => "image/png" },
|
||||||
arrayBuffer: async () => new Uint8Array([0x89, 0x50, 0x4e, 0x47]).buffer,
|
arrayBuffer: async () => new Uint8Array([0x89, 0x50, 0x4e, 0x47]).buffer,
|
||||||
} as Response);
|
} as unknown as Response);
|
||||||
}
|
}
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@@ -147,7 +147,7 @@ describe("telegram inbound media", () => {
|
|||||||
it("prefers proxyFetch over global fetch", async () => {
|
it("prefers proxyFetch over global fetch", async () => {
|
||||||
const runtimeLog = vi.fn();
|
const runtimeLog = vi.fn();
|
||||||
const runtimeError = vi.fn();
|
const runtimeError = vi.fn();
|
||||||
const globalFetchSpy = vi.spyOn(globalThis, "fetch" as never).mockImplementation(() => {
|
const globalFetchSpy = vi.spyOn(globalThis, "fetch").mockImplementation(async () => {
|
||||||
throw new Error("global fetch should not be called");
|
throw new Error("global fetch should not be called");
|
||||||
});
|
});
|
||||||
const proxyFetch = vi.fn().mockResolvedValueOnce({
|
const proxyFetch = vi.fn().mockResolvedValueOnce({
|
||||||
@@ -156,7 +156,7 @@ describe("telegram inbound media", () => {
|
|||||||
statusText: "OK",
|
statusText: "OK",
|
||||||
headers: { get: () => "image/jpeg" },
|
headers: { get: () => "image/jpeg" },
|
||||||
arrayBuffer: async () => new Uint8Array([0xff, 0xd8, 0xff]).buffer,
|
arrayBuffer: async () => new Uint8Array([0xff, 0xd8, 0xff]).buffer,
|
||||||
} as Response);
|
} as unknown as Response);
|
||||||
|
|
||||||
const { handler } = await createBotHandlerWithOptions({
|
const { handler } = await createBotHandlerWithOptions({
|
||||||
proxyFetch: proxyFetch as unknown as typeof fetch,
|
proxyFetch: proxyFetch as unknown as typeof fetch,
|
||||||
@@ -190,7 +190,7 @@ describe("telegram inbound media", () => {
|
|||||||
runtimeLog,
|
runtimeLog,
|
||||||
runtimeError,
|
runtimeError,
|
||||||
});
|
});
|
||||||
const fetchSpy = vi.spyOn(globalThis, "fetch" as never);
|
const fetchSpy = vi.spyOn(globalThis, "fetch");
|
||||||
|
|
||||||
await handler({
|
await handler({
|
||||||
message: {
|
message: {
|
||||||
@@ -385,13 +385,13 @@ describe("telegram stickers", () => {
|
|||||||
cachedAt: "2026-01-20T10:00:00.000Z",
|
cachedAt: "2026-01-20T10:00:00.000Z",
|
||||||
});
|
});
|
||||||
|
|
||||||
const fetchSpy = vi.spyOn(globalThis, "fetch" as never).mockResolvedValueOnce({
|
const fetchSpy = vi.spyOn(globalThis, "fetch").mockResolvedValueOnce({
|
||||||
ok: true,
|
ok: true,
|
||||||
status: 200,
|
status: 200,
|
||||||
statusText: "OK",
|
statusText: "OK",
|
||||||
headers: { get: () => "image/webp" },
|
headers: { get: () => "image/webp" },
|
||||||
arrayBuffer: async () => new Uint8Array([0x52, 0x49, 0x46, 0x46]).buffer,
|
arrayBuffer: async () => new Uint8Array([0x52, 0x49, 0x46, 0x46]).buffer,
|
||||||
} as Response);
|
} as unknown as Response);
|
||||||
|
|
||||||
await handler({
|
await handler({
|
||||||
message: {
|
message: {
|
||||||
@@ -435,7 +435,7 @@ describe("telegram stickers", () => {
|
|||||||
"skips animated stickers (TGS format)",
|
"skips animated stickers (TGS format)",
|
||||||
async () => {
|
async () => {
|
||||||
const { handler, replySpy, runtimeError } = await createBotHandler();
|
const { handler, replySpy, runtimeError } = await createBotHandler();
|
||||||
const fetchSpy = vi.spyOn(globalThis, "fetch" as never);
|
const fetchSpy = vi.spyOn(globalThis, "fetch");
|
||||||
|
|
||||||
await handler({
|
await handler({
|
||||||
message: {
|
message: {
|
||||||
@@ -473,7 +473,7 @@ describe("telegram stickers", () => {
|
|||||||
"skips video stickers (WEBM format)",
|
"skips video stickers (WEBM format)",
|
||||||
async () => {
|
async () => {
|
||||||
const { handler, replySpy, runtimeError } = await createBotHandler();
|
const { handler, replySpy, runtimeError } = await createBotHandler();
|
||||||
const fetchSpy = vi.spyOn(globalThis, "fetch" as never);
|
const fetchSpy = vi.spyOn(globalThis, "fetch");
|
||||||
|
|
||||||
await handler({
|
await handler({
|
||||||
message: {
|
message: {
|
||||||
@@ -520,7 +520,7 @@ describe("telegram text fragments", () => {
|
|||||||
async () => {
|
async () => {
|
||||||
const { createTelegramBot } = await import("./bot.js");
|
const { createTelegramBot } = await import("./bot.js");
|
||||||
const replyModule = await import("../auto-reply/reply.js");
|
const replyModule = await import("../auto-reply/reply.js");
|
||||||
const replySpy = replyModule.__replySpy as unknown as ReturnType<typeof vi.fn>;
|
const replySpy = (replyModule as { __replySpy: ReturnType<typeof vi.fn> }).__replySpy;
|
||||||
|
|
||||||
onSpy.mockReset();
|
onSpy.mockReset();
|
||||||
replySpy.mockReset();
|
replySpy.mockReset();
|
||||||
|
|||||||
Reference in New Issue
Block a user