mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-09 08:37:41 +00:00
test: dedupe gateway browser discord and channel coverage
This commit is contained in:
@@ -21,6 +21,54 @@ let gatewayPort: number;
|
||||
const gatewayToken = "test-token";
|
||||
let envSnapshot: ReturnType<typeof captureEnv>;
|
||||
|
||||
type SessionSendTool = ReturnType<typeof createOpenClawTools>[number];
|
||||
|
||||
function getSessionsSendTool(): SessionSendTool {
|
||||
const tool = createOpenClawTools().find((candidate) => candidate.name === "sessions_send");
|
||||
if (!tool) {
|
||||
throw new Error("missing sessions_send tool");
|
||||
}
|
||||
return tool;
|
||||
}
|
||||
|
||||
async function emitLifecycleAssistantReply(params: {
|
||||
opts: unknown;
|
||||
defaultSessionId: string;
|
||||
includeTimestamp?: boolean;
|
||||
resolveText: (extraSystemPrompt?: string) => string;
|
||||
}) {
|
||||
const commandParams = params.opts as {
|
||||
sessionId?: string;
|
||||
runId?: string;
|
||||
extraSystemPrompt?: string;
|
||||
};
|
||||
const sessionId = commandParams.sessionId ?? params.defaultSessionId;
|
||||
const runId = commandParams.runId ?? sessionId;
|
||||
const sessionFile = resolveSessionTranscriptPath(sessionId);
|
||||
await fs.mkdir(path.dirname(sessionFile), { recursive: true });
|
||||
|
||||
const startedAt = Date.now();
|
||||
emitAgentEvent({
|
||||
runId,
|
||||
stream: "lifecycle",
|
||||
data: { phase: "start", startedAt },
|
||||
});
|
||||
|
||||
const text = params.resolveText(commandParams.extraSystemPrompt);
|
||||
const message = {
|
||||
role: "assistant",
|
||||
content: [{ type: "text", text }],
|
||||
...(params.includeTimestamp ? { timestamp: Date.now() } : {}),
|
||||
};
|
||||
await fs.appendFile(sessionFile, `${JSON.stringify({ message })}\n`, "utf8");
|
||||
|
||||
emitAgentEvent({
|
||||
runId,
|
||||
stream: "lifecycle",
|
||||
data: { phase: "end", startedAt, endedAt: Date.now() },
|
||||
});
|
||||
}
|
||||
|
||||
beforeAll(async () => {
|
||||
envSnapshot = captureEnv(["OPENCLAW_GATEWAY_PORT", "OPENCLAW_GATEWAY_TOKEN"]);
|
||||
gatewayPort = await getFreePort();
|
||||
@@ -52,52 +100,24 @@ afterAll(async () => {
|
||||
describe("sessions_send gateway loopback", () => {
|
||||
it("returns reply when lifecycle ends before agent.wait", async () => {
|
||||
const spy = agentCommand as unknown as Mock<(opts: unknown) => Promise<void>>;
|
||||
spy.mockImplementation(async (opts: unknown) => {
|
||||
const params = opts as {
|
||||
sessionId?: string;
|
||||
runId?: string;
|
||||
extraSystemPrompt?: string;
|
||||
};
|
||||
const sessionId = params.sessionId ?? "main";
|
||||
const runId = params.runId ?? sessionId;
|
||||
const sessionFile = resolveSessionTranscriptPath(sessionId);
|
||||
await fs.mkdir(path.dirname(sessionFile), { recursive: true });
|
||||
|
||||
const startedAt = Date.now();
|
||||
emitAgentEvent({
|
||||
runId,
|
||||
stream: "lifecycle",
|
||||
data: { phase: "start", startedAt },
|
||||
});
|
||||
|
||||
let text = "pong";
|
||||
if (params.extraSystemPrompt?.includes("Agent-to-agent reply step")) {
|
||||
text = "REPLY_SKIP";
|
||||
} else if (params.extraSystemPrompt?.includes("Agent-to-agent announce step")) {
|
||||
text = "ANNOUNCE_SKIP";
|
||||
}
|
||||
const message = {
|
||||
role: "assistant",
|
||||
content: [{ type: "text", text }],
|
||||
timestamp: Date.now(),
|
||||
};
|
||||
await fs.appendFile(sessionFile, `${JSON.stringify({ message })}\n`, "utf8");
|
||||
|
||||
emitAgentEvent({
|
||||
runId,
|
||||
stream: "lifecycle",
|
||||
data: {
|
||||
phase: "end",
|
||||
startedAt,
|
||||
endedAt: Date.now(),
|
||||
spy.mockImplementation(async (opts: unknown) =>
|
||||
emitLifecycleAssistantReply({
|
||||
opts,
|
||||
defaultSessionId: "main",
|
||||
includeTimestamp: true,
|
||||
resolveText: (extraSystemPrompt) => {
|
||||
if (extraSystemPrompt?.includes("Agent-to-agent reply step")) {
|
||||
return "REPLY_SKIP";
|
||||
}
|
||||
if (extraSystemPrompt?.includes("Agent-to-agent announce step")) {
|
||||
return "ANNOUNCE_SKIP";
|
||||
}
|
||||
return "pong";
|
||||
},
|
||||
});
|
||||
});
|
||||
}),
|
||||
);
|
||||
|
||||
const tool = createOpenClawTools().find((candidate) => candidate.name === "sessions_send");
|
||||
if (!tool) {
|
||||
throw new Error("missing sessions_send tool");
|
||||
}
|
||||
const tool = getSessionsSendTool();
|
||||
|
||||
const result = await tool.execute("call-loopback", {
|
||||
sessionKey: "main",
|
||||
@@ -139,37 +159,13 @@ describe("sessions_send label lookup", () => {
|
||||
);
|
||||
|
||||
const spy = agentCommand as unknown as Mock<(opts: unknown) => Promise<void>>;
|
||||
spy.mockImplementation(async (opts: unknown) => {
|
||||
const params = opts as {
|
||||
sessionId?: string;
|
||||
runId?: string;
|
||||
extraSystemPrompt?: string;
|
||||
};
|
||||
const sessionId = params.sessionId ?? "test-labeled";
|
||||
const runId = params.runId ?? sessionId;
|
||||
const sessionFile = resolveSessionTranscriptPath(sessionId);
|
||||
await fs.mkdir(path.dirname(sessionFile), { recursive: true });
|
||||
|
||||
const startedAt = Date.now();
|
||||
emitAgentEvent({
|
||||
runId,
|
||||
stream: "lifecycle",
|
||||
data: { phase: "start", startedAt },
|
||||
});
|
||||
|
||||
const text = "labeled response";
|
||||
const message = {
|
||||
role: "assistant",
|
||||
content: [{ type: "text", text }],
|
||||
};
|
||||
await fs.appendFile(sessionFile, `${JSON.stringify({ message })}\n`, "utf8");
|
||||
|
||||
emitAgentEvent({
|
||||
runId,
|
||||
stream: "lifecycle",
|
||||
data: { phase: "end", startedAt, endedAt: Date.now() },
|
||||
});
|
||||
});
|
||||
spy.mockImplementation(async (opts: unknown) =>
|
||||
emitLifecycleAssistantReply({
|
||||
opts,
|
||||
defaultSessionId: "test-labeled",
|
||||
resolveText: () => "labeled response",
|
||||
}),
|
||||
);
|
||||
|
||||
// First, create a session with a label via sessions.patch
|
||||
const { callGateway } = await import("./call.js");
|
||||
@@ -179,10 +175,7 @@ describe("sessions_send label lookup", () => {
|
||||
timeoutMs: 5000,
|
||||
});
|
||||
|
||||
const tool = createOpenClawTools().find((candidate) => candidate.name === "sessions_send");
|
||||
if (!tool) {
|
||||
throw new Error("missing sessions_send tool");
|
||||
}
|
||||
const tool = getSessionsSendTool();
|
||||
|
||||
// Send using label instead of sessionKey
|
||||
const result = await tool.execute("call-by-label", {
|
||||
@@ -201,10 +194,7 @@ describe("sessions_send label lookup", () => {
|
||||
});
|
||||
|
||||
it("returns error when label not found", { timeout: 60_000 }, async () => {
|
||||
const tool = createOpenClawTools().find((candidate) => candidate.name === "sessions_send");
|
||||
if (!tool) {
|
||||
throw new Error("missing sessions_send tool");
|
||||
}
|
||||
const tool = getSessionsSendTool();
|
||||
|
||||
const result = await tool.execute("call-missing-label", {
|
||||
label: "nonexistent-label",
|
||||
@@ -217,10 +207,7 @@ describe("sessions_send label lookup", () => {
|
||||
});
|
||||
|
||||
it("returns error when neither sessionKey nor label provided", { timeout: 60_000 }, async () => {
|
||||
const tool = createOpenClawTools().find((candidate) => candidate.name === "sessions_send");
|
||||
if (!tool) {
|
||||
throw new Error("missing sessions_send tool");
|
||||
}
|
||||
const tool = getSessionsSendTool();
|
||||
|
||||
const result = await tool.execute("call-no-key", {
|
||||
message: "hello",
|
||||
|
||||
Reference in New Issue
Block a user