






















@@ -1035,6 +1035,48 @@ describe("gateway server sessions", () => {
10351035"sessions.compact",
10361036]),
10371037);
1038+const sessionsHandlers = await getSessionsHandlers();
1039+const directContext = {
1040+broadcastToConnIds: vi.fn(),
1041+getSessionEventSubscriberConnIds: () => new Set<string>(),
1042+loadGatewayModelCatalog: async () => piSdkMock.models,
1043+} as never;
1044+async function directSessionReq<TPayload = unknown>(
1045+method: keyof typeof sessionsHandlers,
1046+params: Record<string, unknown>,
1047+coercePayload?: (payload: unknown) => TPayload,
1048+): Promise<{ ok: boolean; payload?: TPayload; error?: unknown }> {
1049+let result:
1050+| {
1051+ok: boolean;
1052+payload?: TPayload;
1053+error?: unknown;
1054+}
1055+| undefined;
1056+await sessionsHandlers[method]({
1057+req: {} as never,
1058+ params,
1059+respond: (ok, payload, error) => {
1060+result = {
1061+ ok,
1062+payload:
1063+payload === undefined
1064+ ? undefined
1065+ : coercePayload
1066+ ? coercePayload(payload)
1067+ : (payload as TPayload),
1068+ error,
1069+};
1070+},
1071+context: directContext,
1072+client: null,
1073+isWebchatConnect: () => false,
1074+});
1075+if (!result) {
1076+throw new Error(`${method} did not respond`);
1077+}
1078+return result;
1079+}
1038108010391081const resolvedByKey = await rpcReq<{ ok: true; key: string }>(ws, "sessions.resolve", {
10401082key: "main",
@@ -1047,8 +1089,9 @@ describe("gateway server sessions", () => {
10471089});
10481090expect(resolvedBySessionId.ok).toBe(true);
10491091expect(resolvedBySessionId.payload?.key).toBe("agent:main:discord:group:dev");
1092+ws.close();
105010931051-const list1 = await rpcReq<{
1094+const list1 = await directSessionReq<{
10521095path: string;
10531096defaults?: { model?: string | null; modelProvider?: string | null };
10541097sessions: Array<{
@@ -1060,7 +1103,7 @@ describe("gateway server sessions", () => {
10601103lastAccountId?: string;
10611104deliveryContext?: { channel?: string; to?: string; accountId?: string };
10621105}>;
1063-}>(ws, "sessions.list", { includeGlobal: false, includeUnknown: false });
1106+}>("sessions.list", { includeGlobal: false, includeUnknown: false });
1064110710651108expect(list1.ok).toBe(true);
10661109expect(list1.payload?.path).toBe(storePath);
@@ -1079,19 +1122,19 @@ describe("gateway server sessions", () => {
10791122threadId: "1737500000.123456",
10801123});
108111241082-const active = await rpcReq<{
1125+const active = await directSessionReq<{
10831126sessions: Array<{ key: string }>;
1084-}>(ws, "sessions.list", {
1127+}>("sessions.list", {
10851128includeGlobal: false,
10861129includeUnknown: false,
10871130activeMinutes: 5,
10881131});
10891132expect(active.ok).toBe(true);
10901133expect(active.payload?.sessions.map((s) => s.key)).toEqual(["agent:main:main"]);
109111341092-const limited = await rpcReq<{
1135+const limited = await directSessionReq<{
10931136sessions: Array<{ key: string }>;
1094-}>(ws, "sessions.list", {
1137+}>("sessions.list", {
10951138includeGlobal: true,
10961139includeUnknown: false,
10971140limit: 1,
@@ -1100,7 +1143,7 @@ describe("gateway server sessions", () => {
11001143expect(limited.payload?.sessions).toHaveLength(1);
11011144expect(limited.payload?.sessions[0]?.key).toBe("global");
110211451103-const patched = await rpcReq<{ ok: true; key: string }>(ws, "sessions.patch", {
1146+const patched = await directSessionReq<{ ok: true; key: string }>("sessions.patch", {
11041147key: "agent:main:main",
11051148thinkingLevel: "medium",
11061149verboseLevel: "off",
@@ -1109,30 +1152,30 @@ describe("gateway server sessions", () => {
11091152expect(patched.payload?.ok).toBe(true);
11101153expect(patched.payload?.key).toBe("agent:main:main");
111111541112-const sendPolicyPatched = await rpcReq<{
1155+const sendPolicyPatched = await directSessionReq<{
11131156ok: true;
11141157entry: { sendPolicy?: string };
1115-}>(ws, "sessions.patch", { key: "agent:main:main", sendPolicy: "deny" });
1158+}>("sessions.patch", { key: "agent:main:main", sendPolicy: "deny" });
11161159expect(sendPolicyPatched.ok).toBe(true);
11171160expect(sendPolicyPatched.payload?.entry.sendPolicy).toBe("deny");
111811611119-const labelPatched = await rpcReq<{
1162+const labelPatched = await directSessionReq<{
11201163ok: true;
11211164entry: { label?: string };
1122-}>(ws, "sessions.patch", {
1165+}>("sessions.patch", {
11231166key: "agent:main:subagent:one",
11241167label: "Briefing",
11251168});
11261169expect(labelPatched.ok).toBe(true);
11271170expect(labelPatched.payload?.entry.label).toBe("Briefing");
112811711129-const labelPatchedDuplicate = await rpcReq(ws, "sessions.patch", {
1172+const labelPatchedDuplicate = await directSessionReq("sessions.patch", {
11301173key: "agent:main:discord:group:dev",
11311174label: "Briefing",
11321175});
11331176expect(labelPatchedDuplicate.ok).toBe(false);
113411771135-const list2 = await rpcReq<{
1178+const list2 = await directSessionReq<{
11361179sessions: Array<{
11371180key: string;
11381181thinkingLevel?: string;
@@ -1141,7 +1184,7 @@ describe("gateway server sessions", () => {
11411184label?: string;
11421185displayName?: string;
11431186}>;
1144-}>(ws, "sessions.list", {});
1187+}>("sessions.list", {});
11451188expect(list2.ok).toBe(true);
11461189const main2 = list2.payload?.sessions.find((s) => s.key === "agent:main:main");
11471190expect(main2?.thinkingLevel).toBe("medium");
@@ -1151,63 +1194,63 @@ describe("gateway server sessions", () => {
11511194expect(subagent?.label).toBe("Briefing");
11521195expect(subagent?.displayName).toBe("Briefing");
115311961154-const clearedVerbose = await rpcReq<{ ok: true; key: string }>(ws, "sessions.patch", {
1197+const clearedVerbose = await directSessionReq<{ ok: true; key: string }>("sessions.patch", {
11551198key: "agent:main:main",
11561199verboseLevel: null,
11571200});
11581201expect(clearedVerbose.ok).toBe(true);
115912021160-const list3 = await rpcReq<{
1203+const list3 = await directSessionReq<{
11611204sessions: Array<{
11621205key: string;
11631206verboseLevel?: string;
11641207}>;
1165-}>(ws, "sessions.list", {});
1208+}>("sessions.list", {});
11661209expect(list3.ok).toBe(true);
11671210const main3 = list3.payload?.sessions.find((s) => s.key === "agent:main:main");
11681211expect(main3?.verboseLevel).toBeUndefined();
116912121170-const listByLabel = await rpcReq<{
1213+const listByLabel = await directSessionReq<{
11711214sessions: Array<{ key: string }>;
1172-}>(ws, "sessions.list", {
1215+}>("sessions.list", {
11731216includeGlobal: false,
11741217includeUnknown: false,
11751218label: "Briefing",
11761219});
11771220expect(listByLabel.ok).toBe(true);
11781221expect(listByLabel.payload?.sessions.map((s) => s.key)).toEqual(["agent:main:subagent:one"]);
117912221180-const resolvedByLabel = await rpcReq<{ ok: true; key: string }>(ws, "sessions.resolve", {
1223+const resolvedByLabel = await directSessionReq<{ ok: true; key: string }>("sessions.resolve", {
11811224label: "Briefing",
11821225agentId: "main",
11831226});
11841227expect(resolvedByLabel.ok).toBe(true);
11851228expect(resolvedByLabel.payload?.key).toBe("agent:main:subagent:one");
118612291187-const spawnedOnly = await rpcReq<{
1230+const spawnedOnly = await directSessionReq<{
11881231sessions: Array<{ key: string }>;
1189-}>(ws, "sessions.list", {
1232+}>("sessions.list", {
11901233includeGlobal: true,
11911234includeUnknown: true,
11921235spawnedBy: "agent:main:main",
11931236});
11941237expect(spawnedOnly.ok).toBe(true);
11951238expect(spawnedOnly.payload?.sessions.map((s) => s.key)).toEqual(["agent:main:subagent:one"]);
119612391197-const spawnedPatched = await rpcReq<{
1240+const spawnedPatched = await directSessionReq<{
11981241ok: true;
11991242entry: { spawnedBy?: string };
1200-}>(ws, "sessions.patch", {
1243+}>("sessions.patch", {
12011244key: "agent:main:subagent:two",
12021245spawnedBy: "agent:main:main",
12031246});
12041247expect(spawnedPatched.ok).toBe(true);
12051248expect(spawnedPatched.payload?.entry.spawnedBy).toBe("agent:main:main");
120612491207-const acpPatched = await rpcReq<{
1250+const acpPatched = await directSessionReq<{
12081251ok: true;
12091252entry: { spawnedBy?: string; spawnDepth?: number };
1210-}>(ws, "sessions.patch", {
1253+}>("sessions.patch", {
12111254key: "agent:main:acp:child",
12121255spawnedBy: "agent:main:main",
12131256spawnDepth: 1,
@@ -1216,15 +1259,15 @@ describe("gateway server sessions", () => {
12161259expect(acpPatched.payload?.entry.spawnedBy).toBe("agent:main:main");
12171260expect(acpPatched.payload?.entry.spawnDepth).toBe(1);
121812611219-const spawnedPatchedInvalidKey = await rpcReq(ws, "sessions.patch", {
1262+const spawnedPatchedInvalidKey = await directSessionReq("sessions.patch", {
12201263key: "agent:main:main",
12211264spawnedBy: "agent:main:main",
12221265});
12231266expect(spawnedPatchedInvalidKey.ok).toBe(false);
1224126712251268piSdkMock.enabled = true;
12261269piSdkMock.models = [{ id: "gpt-test-a", name: "A", provider: "openai" }];
1227-const modelPatched = await rpcReq<{
1270+const modelPatched = await directSessionReq<{
12281271ok: true;
12291272entry: {
12301273modelOverride?: string;
@@ -1233,7 +1276,7 @@ describe("gateway server sessions", () => {
12331276modelProvider?: string;
12341277};
12351278resolved?: { model?: string; modelProvider?: string };
1236-}>(ws, "sessions.patch", {
1279+}>("sessions.patch", {
12371280key: "agent:main:main",
12381281model: "openai/gpt-test-a",
12391282});
@@ -1245,17 +1288,17 @@ describe("gateway server sessions", () => {
12451288expect(modelPatched.payload?.resolved?.modelProvider).toBe("openai");
12461289expect(modelPatched.payload?.resolved?.model).toBe("gpt-test-a");
124712901248-const listAfterModelPatch = await rpcReq<{
1291+const listAfterModelPatch = await directSessionReq<{
12491292sessions: Array<{ key: string; modelProvider?: string; model?: string }>;
1250-}>(ws, "sessions.list", {});
1293+}>("sessions.list", {});
12511294expect(listAfterModelPatch.ok).toBe(true);
12521295const mainAfterModelPatch = listAfterModelPatch.payload?.sessions.find(
12531296(session) => session.key === "agent:main:main",
12541297);
12551298expect(mainAfterModelPatch?.modelProvider).toBe("openai");
12561299expect(mainAfterModelPatch?.model).toBe("gpt-test-a");
125713001258-const compacted = await rpcReq<{ ok: true; compacted: boolean }>(ws, "sessions.compact", {
1301+const compacted = await directSessionReq<{ ok: true; compacted: boolean }>("sessions.compact", {
12591302key: "agent:main:main",
12601303maxLines: 3,
12611304});
@@ -1268,22 +1311,22 @@ describe("gateway server sessions", () => {
12681311const filesAfterCompact = await fs.readdir(dir);
12691312expect(filesAfterCompact.some((f) => f.startsWith("sess-main.jsonl.bak."))).toBe(true);
127013131271-const deleted = await rpcReq<{ ok: true; deleted: boolean }>(ws, "sessions.delete", {
1314+const deleted = await directSessionReq<{ ok: true; deleted: boolean }>("sessions.delete", {
12721315key: "agent:main:discord:group:dev",
12731316});
12741317expect(deleted.ok).toBe(true);
12751318expect(deleted.payload?.deleted).toBe(true);
1276-const listAfterDelete = await rpcReq<{
1319+const listAfterDelete = await directSessionReq<{
12771320sessions: Array<{ key: string }>;
1278-}>(ws, "sessions.list", {});
1321+}>("sessions.list", {});
12791322expect(listAfterDelete.ok).toBe(true);
12801323expect(
12811324listAfterDelete.payload?.sessions.some((s) => s.key === "agent:main:discord:group:dev"),
12821325).toBe(false);
12831326const filesAfterDelete = await fs.readdir(dir);
12841327expect(filesAfterDelete.some((f) => f.startsWith("sess-group.jsonl.deleted."))).toBe(true);
128513281286-const reset = await rpcReq<{
1329+const reset = await directSessionReq<{
12871330ok: true;
12881331key: string;
12891332entry: {
@@ -1293,7 +1336,7 @@ describe("gateway server sessions", () => {
12931336lastAccountId?: string;
12941337lastThreadId?: string | number;
12951338};
1296-}>(ws, "sessions.reset", { key: "agent:main:main" });
1339+}>("sessions.reset", { key: "agent:main:main" });
12971340expect(reset.ok).toBe(true);
12981341expect(reset.payload?.key).toBe("agent:main:main");
12991342expect(reset.payload?.entry.sessionId).not.toBe("sess-main");
@@ -1310,16 +1353,14 @@ describe("gateway server sessions", () => {
13101353const filesAfterReset = await fs.readdir(dir);
13111354expect(filesAfterReset.some((f) => f.startsWith("sess-main.jsonl.reset."))).toBe(true);
131213551313-const badThinking = await rpcReq(ws, "sessions.patch", {
1356+const badThinking = await directSessionReq("sessions.patch", {
13141357key: "agent:main:main",
13151358thinkingLevel: "banana",
13161359});
13171360expect(badThinking.ok).toBe(false);
13181361expect((badThinking.error as { message?: unknown } | undefined)?.message ?? "").toMatch(
13191362/invalid thinkinglevel/i,
13201363);
1321-1322-ws.close();
13231364});
1324136513251366test("sessions.compaction.* lists checkpoints and branches or restores from pre-compaction snapshots", async () => {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。