






















@@ -15,6 +15,8 @@ const { createSessionStoreDir, openClient } = setupGatewaySessionsTestHarness();
1515type MockCalls = {
1616mock: { calls: unknown[][] };
1717};
18+type SessionStoreEntryOptions = Parameters<typeof sessionStoreEntry>[1];
19+type MutationMethod = "sessions.patch" | "sessions.compact";
18201921function isRecord(value: unknown): value is Record<string, unknown> {
2022return typeof value === "object" && value !== null;
@@ -116,20 +118,31 @@ async function invokeSessionsList({
116118return { request, respond };
117119}
118120119-async function invokeSessionsPatch(params: Record<string, unknown>) {
121+async function invokeSessionMutation({
122+ method,
123+ params,
124+ context = {},
125+ subscribedConnIds = new Set(["conn-1"]),
126+}: {
127+method: MutationMethod;
128+params: Record<string, unknown>;
129+context?: Record<string, unknown>;
130+subscribedConnIds?: Set<string>;
131+}) {
120132const broadcastToConnIds = vi.fn();
121133const respond = vi.fn();
122134const sessionsHandlers = await getSessionsHandlers();
123135const { getRuntimeConfig } = await getGatewayConfigModule();
124-await sessionsHandlers["sessions.patch"]({
136+await sessionsHandlers[method]({
125137req: {} as never,
126138 params,
127139 respond,
128140context: {
129141 broadcastToConnIds,
130-getSessionEventSubscriberConnIds: () => new Set(["conn-1"]),
142+getSessionEventSubscriberConnIds: () => subscribedConnIds,
131143loadGatewayModelCatalog: async () => ({ providers: [] }),
132144 getRuntimeConfig,
145+ ...context,
133146} as never,
134147client: null,
135148isWebchatConnect: () => false,
@@ -140,6 +153,31 @@ async function invokeSessionsPatch(params: Record<string, unknown>) {
140153};
141154}
142155156+async function invokeSessionsPatch(params: Record<string, unknown>) {
157+return invokeSessionMutation({ method: "sessions.patch", params });
158+}
159+160+async function writeMainSessionStore(options?: SessionStoreEntryOptions) {
161+await createSessionStoreDir();
162+await writeSessionStore({
163+entries: {
164+main: sessionStoreEntry("sess-main", options),
165+},
166+});
167+}
168+169+function expectMainPatchBroadcast(
170+result: Awaited<ReturnType<typeof invokeSessionsPatch>>,
171+expected: Record<string, unknown>,
172+) {
173+expectFields(result.responsePayload, { ok: true, key: "agent:main:main" });
174+expectChangedBroadcast(result.broadcastToConnIds, {
175+sessionKey: "agent:main:main",
176+reason: "patch",
177+ ...expected,
178+});
179+}
180+143181async function setupGlobalAgentSessionStores({
144182 writePrimeStore = false,
145183 withTranscripts = false,
@@ -257,25 +295,33 @@ async function invokeSessionsCompact({
257295params: Record<string, unknown>;
258296subscribedConnIds?: Set<string>;
259297}) {
260-const broadcastToConnIds = vi.fn();
261-const respond = vi.fn();
262-const sessionsHandlers = await getSessionsHandlers();
263-await sessionsHandlers["sessions.compact"]({
264-req: {} as never,
298+return invokeSessionMutation({
299+method: "sessions.compact",
265300 params,
266- respond,
267301context: {
268- broadcastToConnIds,
269-getSessionEventSubscriberConnIds: () => subscribedConnIds,
270302 getRuntimeConfig,
271-} as never,
272-client: null,
273-isWebchatConnect: () => false,
303+},
304+ subscribedConnIds,
274305});
275-return {
276- broadcastToConnIds,
277-responsePayload: expectRespondPayload(respond),
278-};
306+}
307+308+async function expectListedSessionActiveRun(
309+requestId: string,
310+run: Record<string, unknown>,
311+expected: boolean,
312+) {
313+await writeMainSessionStore();
314+315+const { respond } = await invokeSessionsList({
316+ requestId,
317+context: {
318+chatAbortControllers: new Map([["run-1", { sessionKey: "agent:main:main", ...run }]]),
319+},
320+});
321+322+const payload = expectRespondPayload(respond);
323+const session = findSession(payload, "agent:main:main");
324+expect(session.hasActiveRun).toBe(expected);
279325}
280326281327test("sessions.list keeps bulk rows lightweight and uses persisted model fields", async () => {
@@ -369,17 +415,12 @@ test("sessions.list keeps bulk rows lightweight and uses persisted model fields"
369415});
370416371417test("sessions.list uses the gateway model catalog for effective thinking defaults", async () => {
372-await createSessionStoreDir();
373418testState.agentConfig = {
374419model: { primary: "test-provider/reasoner" },
375420};
376-await writeSessionStore({
377-entries: {
378-main: sessionStoreEntry("sess-main", {
379-modelProvider: "test-provider",
380-model: "reasoner",
381-}),
382-},
421+await writeMainSessionStore({
422+modelProvider: "test-provider",
423+model: "reasoner",
383424});
384425385426const { respond } = await invokeSessionsList({
@@ -407,67 +448,23 @@ test("sessions.list uses the gateway model catalog for effective thinking defaul
407448});
408449409450test("sessions.list marks sessions with active abortable runs", async () => {
410-await createSessionStoreDir();
411-await writeSessionStore({
412-entries: {
413-main: sessionStoreEntry("sess-main"),
414-},
415-});
416-417-const { respond } = await invokeSessionsList({
418-requestId: "req-sessions-list-active-run",
419-context: {
420-chatAbortControllers: new Map([["run-1", { sessionKey: "agent:main:main" }]]),
421-},
422-});
423-424-const payload = expectRespondPayload(respond);
425-const session = findSession(payload, "agent:main:main");
426-expect(session.hasActiveRun).toBe(true);
451+await expectListedSessionActiveRun("req-sessions-list-active-run", {}, true);
427452});
428453429454test("sessions.list ignores terminal abortable runs kept for retry guards", async () => {
430-await createSessionStoreDir();
431-await writeSessionStore({
432-entries: {
433-main: sessionStoreEntry("sess-main"),
434-},
435-});
436-437-const { respond } = await invokeSessionsList({
438-requestId: "req-sessions-list-terminal-run",
439-context: {
440-chatAbortControllers: new Map([
441-["run-1", { sessionKey: "agent:main:main", projectSessionActive: false }],
442-]),
443-},
444-});
445-446-const payload = expectRespondPayload(respond);
447-const session = findSession(payload, "agent:main:main");
448-expect(session.hasActiveRun).toBe(false);
455+await expectListedSessionActiveRun(
456+"req-sessions-list-terminal-run",
457+{ projectSessionActive: false },
458+false,
459+);
449460});
450461451462test("sessions.list ignores hidden internal abortable runs", async () => {
452-await createSessionStoreDir();
453-await writeSessionStore({
454-entries: {
455-main: sessionStoreEntry("sess-main"),
456-},
457-});
458-459-const { respond } = await invokeSessionsList({
460-requestId: "req-sessions-list-hidden-run",
461-context: {
462-chatAbortControllers: new Map([
463-["run-1", { sessionKey: "agent:main:main", controlUiVisible: false }],
464-]),
465-},
466-});
467-468-const payload = expectRespondPayload(respond);
469-const session = findSession(payload, "agent:main:main");
470-expect(session.hasActiveRun).toBe(false);
463+await expectListedSessionActiveRun(
464+"req-sessions-list-hidden-run",
465+{ controlUiVisible: false },
466+false,
467+);
471468});
472469473470test("sessions.list yields before responding during bulk transcript hydration", async () => {
@@ -518,12 +515,7 @@ test("sessions.list yields before responding during bulk transcript hydration",
518515});
519516520517test("sessions.list does not block on slow model catalog discovery", async () => {
521-await createSessionStoreDir();
522-await writeSessionStore({
523-entries: {
524-main: sessionStoreEntry("sess-main"),
525-},
526-});
518+await writeMainSessionStore();
527519528520vi.useFakeTimers();
529521try {
@@ -586,15 +578,12 @@ test("sessions.changed mutation events include live usage metadata", async () =>
586578},
587579});
588580589-const { broadcastToConnIds, responsePayload } = await invokeSessionsPatch({
581+const result = await invokeSessionsPatch({
590582key: "main",
591583label: "Renamed",
592584});
593585594-expectFields(responsePayload, { ok: true, key: "agent:main:main" });
595-expectChangedBroadcast(broadcastToConnIds, {
596-sessionKey: "agent:main:main",
597-reason: "patch",
586+expectMainPatchBroadcast(result, {
598587totalTokens: 6_643,
599588totalTokensFresh: true,
600589contextTokens: 123_456,
@@ -605,59 +594,36 @@ test("sessions.changed mutation events include live usage metadata", async () =>
605594});
606595607596test("sessions.changed mutation events include live session setting metadata", async () => {
608-await createSessionStoreDir();
609-await writeSessionStore({
610-entries: {
611-main: sessionStoreEntry("sess-main", {
612-verboseLevel: "on",
613-responseUsage: "full",
614-fastMode: true,
615-lastChannel: "telegram",
616-lastTo: "-100123",
617-lastAccountId: "acct-1",
618-lastThreadId: 42,
619-}),
620-},
621-});
622-623-const { broadcastToConnIds, responsePayload } = await invokeSessionsPatch({
624-key: "main",
625-verboseLevel: "on",
626-});
627-628-expectFields(responsePayload, { ok: true, key: "agent:main:main" });
629-expectChangedBroadcast(broadcastToConnIds, {
630-sessionKey: "agent:main:main",
631-reason: "patch",
597+const sessionSettings = {
632598verboseLevel: "on",
633599responseUsage: "full",
634600fastMode: true,
635601lastChannel: "telegram",
636602lastTo: "-100123",
637603lastAccountId: "acct-1",
638604lastThreadId: 42,
605+} satisfies SessionStoreEntryOptions;
606+await writeMainSessionStore(sessionSettings);
607+608+const result = await invokeSessionsPatch({
609+key: "main",
610+verboseLevel: "on",
639611});
612+613+expectMainPatchBroadcast(result, sessionSettings);
640614});
641615642616test("sessions.changed mutation events include sendPolicy metadata", async () => {
643-await createSessionStoreDir();
644-await writeSessionStore({
645-entries: {
646-main: sessionStoreEntry("sess-main", {
647-sendPolicy: "deny",
648-}),
649-},
617+await writeMainSessionStore({
618+sendPolicy: "deny",
650619});
651620652-const { broadcastToConnIds, responsePayload } = await invokeSessionsPatch({
621+const result = await invokeSessionsPatch({
653622key: "main",
654623sendPolicy: "deny",
655624});
656625657-expectFields(responsePayload, { ok: true, key: "agent:main:main" });
658-expectChangedBroadcast(broadcastToConnIds, {
659-sessionKey: "agent:main:main",
660-reason: "patch",
626+expectMainPatchBroadcast(result, {
661627sendPolicy: "deny",
662628});
663629});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。