Skip to content

Commit 198b414

Browse files
committed
fix(ci): repair main test and script type checks
1 parent 0471b29 commit 198b414

2 files changed

Lines changed: 31 additions & 12 deletions

File tree

src/agents/subagent-orphan-recovery.test.ts

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import * as config from "../config/config.js";
55
import * as sessions from "../config/sessions.js";
66
import * as sessionAccessor from "../config/sessions/session-accessor.js";
77
import type { GatewayRecoveryRuntime } from "../gateway/server-instance-runtime.types.js";
8-
import * as sessionUtils from "../gateway/session-transcript-readers.js";
98
import {
109
getActiveGatewayRootWorkCount,
1110
resetGatewayWorkAdmission,
@@ -28,22 +27,37 @@ const loggerMocks = vi.hoisted(() => ({
2827
const dispatchAgent = vi.fn(async (_payload: Record<string, unknown>, _timeoutMs?: number) => ({
2928
runId: "test-run-id",
3029
}));
30+
const readSessionMessages = vi.fn(async () => [] as unknown[]);
3131
const gatewayRuntime: GatewayRecoveryRuntime = {
3232
dispatchAgent: dispatchAgent as GatewayRecoveryRuntime["dispatchAgent"],
3333
waitForAgent: vi.fn(),
3434
sendRecoveryNotice: vi.fn(),
3535
};
3636

3737
function recoverOrphanedSubagentSessions(
38-
params: Omit<Parameters<typeof recoverOrphanedSubagentSessionsWithRuntime>[0], "gatewayRuntime">,
38+
params: Omit<
39+
Parameters<typeof recoverOrphanedSubagentSessionsWithRuntime>[0],
40+
"gatewayRuntime" | "readSessionMessages"
41+
>,
3942
) {
40-
return recoverOrphanedSubagentSessionsWithRuntime({ ...params, gatewayRuntime });
43+
return recoverOrphanedSubagentSessionsWithRuntime({
44+
...params,
45+
gatewayRuntime,
46+
readSessionMessages,
47+
});
4148
}
4249

4350
function scheduleOrphanRecovery(
44-
params: Omit<Parameters<typeof scheduleOrphanRecoveryWithRuntime>[0], "getGatewayRuntime">,
51+
params: Omit<
52+
Parameters<typeof scheduleOrphanRecoveryWithRuntime>[0],
53+
"getGatewayRuntime" | "readSessionMessages"
54+
>,
4555
) {
46-
return scheduleOrphanRecoveryWithRuntime({ ...params, getGatewayRuntime: () => gatewayRuntime });
56+
return scheduleOrphanRecoveryWithRuntime({
57+
...params,
58+
getGatewayRuntime: () => gatewayRuntime,
59+
readSessionMessages,
60+
});
4761
}
4862

4963
// Mocks are installed before importing the recovery module so registry/runtime
@@ -116,10 +130,6 @@ vi.mock("../config/sessions/session-accessor.js", () => ({
116130
patchSessionEntry: sessionMocks.patchSessionEntry,
117131
}));
118132

119-
vi.mock("../gateway/session-transcript-readers.js", () => ({
120-
readSessionMessagesAsync: vi.fn(async () => []),
121-
}));
122-
123133
vi.mock("./subagent-announce-delivery.js", () => ({
124134
deliverSubagentAnnouncement: vi.fn(async () => ({ delivered: true, path: "direct" })),
125135
isInternalAnnounceRequesterSession: vi.fn(() => false),
@@ -210,6 +220,8 @@ describe("subagent-orphan-recovery", () => {
210220
resetGatewayWorkAdmission();
211221
dispatchAgent.mockReset();
212222
dispatchAgent.mockResolvedValue({ runId: "test-run-id" });
223+
readSessionMessages.mockReset();
224+
readSessionMessages.mockResolvedValue([]);
213225
vi.mocked(subagentRegistrySteerRuntime.finalizeInterruptedSubagentRun)
214226
.mockReset()
215227
.mockResolvedValue(1);
@@ -740,7 +752,7 @@ describe("subagent-orphan-recovery", () => {
740752
it("includes last human message in resume when available", async () => {
741753
mockSingleAbortedSession({ sessionFile: "session-abc.jsonl" });
742754

743-
vi.mocked(sessionUtils.readSessionMessagesAsync).mockResolvedValue([
755+
readSessionMessages.mockResolvedValue([
744756
{ role: "user", content: [{ type: "text", text: "Please build feature Y" }] },
745757
{ role: "assistant", content: [{ type: "text", text: "Working on it..." }] },
746758
{ role: "user", content: [{ type: "text", text: "Also add tests for it" }] },
@@ -759,7 +771,7 @@ describe("subagent-orphan-recovery", () => {
759771
it("adds config change hint when assistant messages reference config modifications", async () => {
760772
mockSingleAbortedSession();
761773

762-
vi.mocked(sessionUtils.readSessionMessagesAsync).mockResolvedValue([
774+
readSessionMessages.mockResolvedValue([
763775
{ role: "user", content: "Update the config" },
764776
{ role: "assistant", content: "I've modified openclaw.json to add the new setting." },
765777
]);
@@ -916,6 +928,7 @@ describe("subagent-orphan-recovery", () => {
916928
scheduleOrphanRecoveryWithRuntime({
917929
getGatewayRuntime: () => currentRuntime,
918930
getActiveRuns: () => createActiveRuns(createTestRunRecord()),
931+
readSessionMessages,
919932
delayMs: 1,
920933
maxRetries: 0,
921934
});

src/agents/subagent-orphan-recovery.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,8 @@ async function resumeOrphanedSession(params: {
231231
export async function recoverOrphanedSubagentSessions(params: {
232232
gatewayRuntime: GatewayRecoveryRuntime;
233233
getActiveRuns: () => Map<string, SubagentRunRecord>;
234+
/** Test seam for transcript reads; production uses the canonical reader. */
235+
readSessionMessages?: typeof readSessionMessagesAsync;
234236
/** Persisted across retries so already-resumed sessions are not resumed again. */
235237
resumedSessionKeys?: Set<string>;
236238
/** Exact stale generations whose terminal transition must retry without session state. */
@@ -249,6 +251,7 @@ export async function recoverOrphanedSubagentSessions(params: {
249251
};
250252
const resumedSessionKeys = params.resumedSessionKeys ?? new Set<string>();
251253
const pendingStaleFinalizations = params.pendingStaleFinalizations ?? new Map<string, string>();
254+
const readSessionMessages = params.readSessionMessages ?? readSessionMessagesAsync;
252255
const configChangePattern = /openclaw\.json|openclaw gateway restart|config\.patch/i;
253256

254257
try {
@@ -431,7 +434,7 @@ export async function recoverOrphanedSubagentSessions(params: {
431434

432435
log.info(`found orphaned subagent session: ${childSessionKey} (run=${runId})`);
433436

434-
const messages = await readSessionMessagesAsync(
437+
const messages = await readSessionMessages(
435438
{
436439
agentId: resolveAgentIdFromSessionKey(childSessionKey),
437440
sessionEntry: entry,
@@ -592,6 +595,8 @@ async function finalizeInterruptedRunWithRetry(params: {
592595
export function scheduleOrphanRecovery(params: {
593596
getGatewayRuntime: () => GatewayRecoveryRuntime | undefined;
594597
getActiveRuns: () => Map<string, SubagentRunRecord>;
598+
/** Test seam for transcript reads; production uses the canonical reader. */
599+
readSessionMessages?: typeof readSessionMessagesAsync;
595600
delayMs?: number;
596601
maxRetries?: number;
597602
}): void {
@@ -617,6 +622,7 @@ export function scheduleOrphanRecovery(params: {
617622
const result = await recoverOrphanedSubagentSessions({
618623
gatewayRuntime,
619624
getActiveRuns: params.getActiveRuns,
625+
readSessionMessages: params.readSessionMessages ?? readSessionMessagesAsync,
620626
resumedSessionKeys,
621627
pendingStaleFinalizations,
622628
});

0 commit comments

Comments
 (0)