mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-08 07:41:08 +00:00
test(agents): stabilize announce cleanup assertions (#61088)
* test(plugin-sdk): use telegram public config seam * test(agents): stabilize announce cleanup assertions
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
export {
|
||||
TELEGRAM_COMMAND_NAME_PATTERN,
|
||||
normalizeTelegramCommandDescription,
|
||||
normalizeTelegramCommandName,
|
||||
resolveTelegramCustomCommands,
|
||||
|
||||
@@ -727,7 +727,7 @@ describe("Agent-specific tool filtering", () => {
|
||||
command: "echo done",
|
||||
host: "sandbox",
|
||||
}),
|
||||
).rejects.toThrow("exec host not allowed");
|
||||
).rejects.toThrow(/requires a sandbox runtime/);
|
||||
});
|
||||
|
||||
it("should apply agent-specific exec host defaults over global defaults", async () => {
|
||||
@@ -777,7 +777,7 @@ describe("Agent-specific tool filtering", () => {
|
||||
host: "sandbox",
|
||||
yieldMs: 1000,
|
||||
}),
|
||||
).rejects.toThrow("exec host not allowed");
|
||||
).rejects.toThrow(/requires a sandbox runtime/);
|
||||
});
|
||||
|
||||
it("applies explicit agentId exec defaults when sessionKey is opaque", async () => {
|
||||
|
||||
@@ -103,7 +103,10 @@ vi.mock("./subagent-announce-delivery.js", () => ({
|
||||
params: {
|
||||
sessionKey: params.targetRequesterSessionKey,
|
||||
message: params.triggerMessage,
|
||||
deliver: false,
|
||||
deliver:
|
||||
!params.requesterIsSubagent &&
|
||||
params.requesterOrigin?.channel !== "webchat" &&
|
||||
Boolean(params.requesterOrigin?.channel && params.requesterOrigin?.to),
|
||||
bestEffortDeliver: params.bestEffortDeliver,
|
||||
...(params.requesterIsSubagent
|
||||
? {}
|
||||
@@ -127,8 +130,27 @@ vi.mock("./subagent-announce-delivery.js", () => ({
|
||||
const store = loadSessionStoreMock("/tmp/sessions.json") as Record<string, unknown>;
|
||||
return store?.[sessionKey] ?? { sessionId: sessionKey };
|
||||
},
|
||||
resolveAnnounceOrigin: (entry: { origin?: unknown } | undefined, requesterOrigin?: unknown) =>
|
||||
requesterOrigin ?? entry?.origin,
|
||||
resolveAnnounceOrigin: (
|
||||
entry:
|
||||
| {
|
||||
lastChannel?: string;
|
||||
lastTo?: string;
|
||||
lastAccountId?: string;
|
||||
lastThreadId?: string;
|
||||
origin?: { provider?: string; channel?: string; accountId?: string };
|
||||
}
|
||||
| undefined,
|
||||
requesterOrigin?: { channel?: string; to?: string; accountId?: string; threadId?: string },
|
||||
) => ({
|
||||
channel:
|
||||
requesterOrigin?.channel ??
|
||||
entry?.lastChannel ??
|
||||
entry?.origin?.provider ??
|
||||
entry?.origin?.channel,
|
||||
to: requesterOrigin?.to ?? entry?.lastTo,
|
||||
accountId: requesterOrigin?.accountId ?? entry?.lastAccountId ?? entry?.origin?.accountId,
|
||||
threadId: requesterOrigin?.threadId ?? entry?.lastThreadId,
|
||||
}),
|
||||
resolveSubagentCompletionOrigin: async (params: { requesterOrigin?: unknown }) =>
|
||||
params.requesterOrigin,
|
||||
resolveSubagentAnnounceTimeoutMs: () => 10_000,
|
||||
|
||||
@@ -263,9 +263,12 @@ describe("subagent registry steer restarts", () => {
|
||||
|
||||
emitLifecycleEnd("run-new");
|
||||
|
||||
await flushAnnounce();
|
||||
expect(announceSpy).toHaveBeenCalledTimes(1);
|
||||
expect(runSubagentEndedHookMock).toHaveBeenCalledTimes(1);
|
||||
await vi.waitFor(() => {
|
||||
expect(announceSpy).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
await vi.waitFor(() => {
|
||||
expect(runSubagentEndedHookMock).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
expect(runSubagentEndedHookMock).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
runId: "run-new",
|
||||
@@ -338,63 +341,75 @@ describe("subagent registry steer restarts", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("clears announce retry state when replacing after steer restart", () => {
|
||||
registerRun({
|
||||
runId: "run-retry-reset-old",
|
||||
childSessionKey: "agent:main:subagent:retry-reset",
|
||||
task: "retry reset",
|
||||
});
|
||||
it("clears announce retry state when replacing after steer restart", async () => {
|
||||
await withPendingAgentWait(async () => {
|
||||
registerRun({
|
||||
runId: "run-retry-reset-old",
|
||||
childSessionKey: "agent:main:subagent:retry-reset",
|
||||
task: "retry reset",
|
||||
});
|
||||
|
||||
const previous = listMainRuns()[0];
|
||||
expect(previous?.runId).toBe("run-retry-reset-old");
|
||||
if (previous) {
|
||||
previous.announceRetryCount = 2;
|
||||
previous.lastAnnounceRetryAt = Date.now();
|
||||
}
|
||||
const previous = listMainRuns()[0];
|
||||
expect(previous?.runId).toBe("run-retry-reset-old");
|
||||
if (previous) {
|
||||
previous.announceRetryCount = 2;
|
||||
previous.lastAnnounceRetryAt = Date.now();
|
||||
}
|
||||
|
||||
const run = replaceRunAfterSteer({
|
||||
previousRunId: "run-retry-reset-old",
|
||||
nextRunId: "run-retry-reset-new",
|
||||
fallback: previous,
|
||||
const run = replaceRunAfterSteer({
|
||||
previousRunId: "run-retry-reset-old",
|
||||
nextRunId: "run-retry-reset-new",
|
||||
fallback: previous,
|
||||
});
|
||||
expect(run.announceRetryCount).toBeUndefined();
|
||||
expect(run.lastAnnounceRetryAt).toBeUndefined();
|
||||
});
|
||||
expect(run.announceRetryCount).toBeUndefined();
|
||||
expect(run.lastAnnounceRetryAt).toBeUndefined();
|
||||
});
|
||||
|
||||
it("clears terminal lifecycle state when replacing after steer restart", async () => {
|
||||
registerRun({
|
||||
runId: "run-terminal-state-old",
|
||||
childSessionKey: "agent:main:subagent:terminal-state",
|
||||
task: "terminal state",
|
||||
await withPendingAgentWait(async () => {
|
||||
registerRun({
|
||||
runId: "run-terminal-state-old",
|
||||
childSessionKey: "agent:main:subagent:terminal-state",
|
||||
task: "terminal state",
|
||||
});
|
||||
|
||||
const previous = listMainRuns()[0];
|
||||
expect(previous?.runId).toBe("run-terminal-state-old");
|
||||
if (previous) {
|
||||
previous.endedHookEmittedAt = Date.now();
|
||||
previous.endedReason = "subagent-complete";
|
||||
previous.endedAt = Date.now();
|
||||
previous.outcome = { status: "ok" };
|
||||
}
|
||||
|
||||
const run = replaceRunAfterSteer({
|
||||
previousRunId: "run-terminal-state-old",
|
||||
nextRunId: "run-terminal-state-new",
|
||||
fallback: previous,
|
||||
});
|
||||
expect(run.endedHookEmittedAt).toBeUndefined();
|
||||
expect(run.endedReason).toBeUndefined();
|
||||
|
||||
emitLifecycleEnd("run-terminal-state-new");
|
||||
|
||||
await vi.waitFor(() => {
|
||||
expect(runSubagentEndedHookMock).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
runId: "run-terminal-state-new",
|
||||
}),
|
||||
expect.objectContaining({
|
||||
runId: "run-terminal-state-new",
|
||||
}),
|
||||
);
|
||||
});
|
||||
expect(emitSessionLifecycleEventMock).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
sessionKey: "agent:main:subagent:terminal-state",
|
||||
reason: "subagent-status",
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
const previous = listMainRuns()[0];
|
||||
expect(previous?.runId).toBe("run-terminal-state-old");
|
||||
if (previous) {
|
||||
previous.endedHookEmittedAt = Date.now();
|
||||
previous.endedReason = "subagent-complete";
|
||||
previous.endedAt = Date.now();
|
||||
previous.outcome = { status: "ok" };
|
||||
}
|
||||
|
||||
const run = replaceRunAfterSteer({
|
||||
previousRunId: "run-terminal-state-old",
|
||||
nextRunId: "run-terminal-state-new",
|
||||
fallback: previous,
|
||||
});
|
||||
expect(run.endedHookEmittedAt).toBeUndefined();
|
||||
expect(run.endedReason).toBeUndefined();
|
||||
|
||||
emitLifecycleEnd("run-terminal-state-new");
|
||||
|
||||
await flushAnnounce();
|
||||
expect(runSubagentEndedHookMock).not.toHaveBeenCalled();
|
||||
expect(emitSessionLifecycleEventMock).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
sessionKey: "agent:main:subagent:terminal-state",
|
||||
reason: "subagent-status",
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it("clears frozen completion fields when replacing after steer restart", () => {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { TELEGRAM_COMMAND_NAME_PATTERN as bundledTelegramCommandNamePattern } from "../../extensions/telegram/src/command-config.ts";
|
||||
import { TELEGRAM_COMMAND_NAME_PATTERN as bundledTelegramCommandNamePattern } from "../../extensions/telegram/channel-config-api.ts";
|
||||
|
||||
type BundledChannelContractSurfaceParams = Parameters<
|
||||
(typeof import("../channels/plugins/contract-surfaces.js"))["getBundledChannelContractSurfaceModule"]
|
||||
|
||||
Reference in New Issue
Block a user