




























@@ -123,6 +123,51 @@ async function expectOversizedPromptRejected(params: { sessionId: string; text:
123123sessionStore.clearAllSessionsForTest();
124124}
125125126+type MockCallSource = { mock: { calls: Array<Array<unknown>> } };
127+128+function requireRecord(value: unknown, label: string): Record<string, unknown> {
129+expect(value, label).toBeTypeOf("object");
130+expect(value, label).not.toBeNull();
131+return value as Record<string, unknown>;
132+}
133+134+function configOptions(value: unknown) {
135+expect(Array.isArray(value), "config options").toBe(true);
136+return value as Array<Record<string, unknown>>;
137+}
138+139+function expectConfigOption(options: unknown, id: string, fields: Record<string, unknown>) {
140+const option = configOptions(options).find((candidate) => candidate.id === id);
141+expect(option, `config option ${id}`).toBeDefined();
142+for (const [field, value] of Object.entries(fields)) {
143+expect(option?.[field]).toEqual(value);
144+}
145+}
146+147+function sessionUpdatePayloads(source: MockCallSource, updateType?: string) {
148+const payloads = source.mock.calls.map((call, index) => {
149+const envelope = requireRecord(call[0], `session update envelope ${index}`);
150+return {
151+sessionId: envelope.sessionId,
152+update: requireRecord(envelope.update, `session update ${index}`),
153+};
154+});
155+if (!updateType) {
156+return payloads;
157+}
158+return payloads.filter((payload) => payload.update.sessionUpdate === updateType);
159+}
160+161+function expectSessionUpdate(source: MockCallSource, sessionId: string, updateType: string) {
162+const update = sessionUpdatePayloads(source, updateType).find(
163+(payload) => payload.sessionId === sessionId,
164+)?.update;
165+if (!update) {
166+throw new Error(`expected ${sessionId} ${updateType}`);
167+}
168+return update;
169+}
170+126171describe("acp session creation rate limit", () => {
127172it("rate limits excessive newSession bursts", async () => {
128173const sessionStore = createInMemorySessionStore();
@@ -215,31 +260,14 @@ describe("acp session UX bridge behavior", () => {
215260216261expect(result.modes?.currentModeId).toBe("adaptive");
217262expect(result.modes?.availableModes.map((mode) => mode.id)).toContain("adaptive");
218-expect(result.configOptions).toEqual(
219-expect.arrayContaining([
220-expect.objectContaining({
221-id: "thought_level",
222-currentValue: "adaptive",
223-category: "thought_level",
224-}),
225-expect.objectContaining({
226-id: "verbose_level",
227-currentValue: "off",
228-}),
229-expect.objectContaining({
230-id: "reasoning_level",
231-currentValue: "off",
232-}),
233-expect.objectContaining({
234-id: "response_usage",
235-currentValue: "off",
236-}),
237-expect.objectContaining({
238-id: "elevated_level",
239-currentValue: "off",
240-}),
241-]),
242-);
263+expectConfigOption(result.configOptions, "thought_level", {
264+currentValue: "adaptive",
265+category: "thought_level",
266+});
267+expectConfigOption(result.configOptions, "verbose_level", { currentValue: "off" });
268+expectConfigOption(result.configOptions, "reasoning_level", { currentValue: "off" });
269+expectConfigOption(result.configOptions, "response_usage", { currentValue: "off" });
270+expectConfigOption(result.configOptions, "elevated_level", { currentValue: "off" });
243271244272sessionStore.clearAllSessionsForTest();
245273});
@@ -317,30 +345,11 @@ describe("acp session UX bridge behavior", () => {
317345"max",
318346"high",
319347]);
320-expect(result.configOptions).toEqual(
321-expect.arrayContaining([
322-expect.objectContaining({
323-id: "thought_level",
324-currentValue: "high",
325-}),
326-expect.objectContaining({
327-id: "verbose_level",
328-currentValue: "full",
329-}),
330-expect.objectContaining({
331-id: "reasoning_level",
332-currentValue: "stream",
333-}),
334-expect.objectContaining({
335-id: "response_usage",
336-currentValue: "tokens",
337-}),
338-expect.objectContaining({
339-id: "elevated_level",
340-currentValue: "ask",
341-}),
342-]),
343-);
348+expectConfigOption(result.configOptions, "thought_level", { currentValue: "high" });
349+expectConfigOption(result.configOptions, "verbose_level", { currentValue: "full" });
350+expectConfigOption(result.configOptions, "reasoning_level", { currentValue: "stream" });
351+expectConfigOption(result.configOptions, "response_usage", { currentValue: "tokens" });
352+expectConfigOption(result.configOptions, "elevated_level", { currentValue: "ask" });
344353expect(sessionUpdate).toHaveBeenCalledWith({
345354sessionId: "agent:main:work",
346355update: {
@@ -362,12 +371,7 @@ describe("acp session UX bridge behavior", () => {
362371content: { type: "text", text: "Answer" },
363372},
364373});
365-expect(sessionUpdate).toHaveBeenCalledWith({
366-sessionId: "agent:main:work",
367-update: expect.objectContaining({
368-sessionUpdate: "available_commands_update",
369-}),
370-});
374+expectSessionUpdate(sessionUpdate, "agent:main:work", "available_commands_update");
371375expect(sessionUpdate).toHaveBeenCalledWith({
372376sessionId: "agent:main:work",
373377update: {
@@ -433,18 +437,8 @@ describe("acp session UX bridge behavior", () => {
433437const result = await agent.loadSession(createLoadSessionRequest("agent:main:recover"));
434438435439expect(result.modes?.currentModeId).toBe("adaptive");
436-expect(sessionUpdate).toHaveBeenCalledWith({
437-sessionId: "agent:main:recover",
438-update: expect.objectContaining({
439-sessionUpdate: "available_commands_update",
440-}),
441-});
442-expect(sessionUpdate).not.toHaveBeenCalledWith({
443-sessionId: "agent:main:recover",
444-update: expect.objectContaining({
445-sessionUpdate: "user_message_chunk",
446-}),
447-});
440+expectSessionUpdate(sessionUpdate, "agent:main:recover", "available_commands_update");
441+expect(sessionUpdatePayloads(sessionUpdate, "user_message_chunk")).toEqual([]);
448442449443sessionStore.clearAllSessionsForTest();
450444});
@@ -517,18 +511,11 @@ describe("acp setSessionMode bridge behavior", () => {
517511currentModeId: "high",
518512},
519513});
520-expect(sessionUpdate).toHaveBeenCalledWith({
521-sessionId: "mode-session",
522-update: {
523-sessionUpdate: "config_option_update",
524-configOptions: expect.arrayContaining([
525-expect.objectContaining({
526-id: "thought_level",
527-currentValue: "high",
528-}),
529-]),
530-},
531-});
514+expectConfigOption(
515+expectSessionUpdate(sessionUpdate, "mode-session", "config_option_update").configOptions,
516+"thought_level",
517+{ currentValue: "high" },
518+);
532519533520sessionStore.clearAllSessionsForTest();
534521});
@@ -575,33 +562,19 @@ describe("acp setSessionConfigOption bridge behavior", () => {
575562createSetSessionConfigOptionRequest("config-session", "thought_level", "minimal"),
576563);
577564578-expect(result.configOptions).toEqual(
579-expect.arrayContaining([
580-expect.objectContaining({
581-id: "thought_level",
582-currentValue: "minimal",
583-}),
584-]),
585-);
565+expectConfigOption(result.configOptions, "thought_level", { currentValue: "minimal" });
586566expect(sessionUpdate).toHaveBeenCalledWith({
587567sessionId: "config-session",
588568update: {
589569sessionUpdate: "current_mode_update",
590570currentModeId: "minimal",
591571},
592572});
593-expect(sessionUpdate).toHaveBeenCalledWith({
594-sessionId: "config-session",
595-update: {
596-sessionUpdate: "config_option_update",
597-configOptions: expect.arrayContaining([
598-expect.objectContaining({
599-id: "thought_level",
600-currentValue: "minimal",
601-}),
602-]),
603-},
604-});
573+expectConfigOption(
574+expectSessionUpdate(sessionUpdate, "config-session", "config_option_update").configOptions,
575+"thought_level",
576+{ currentValue: "minimal" },
577+);
605578606579sessionStore.clearAllSessionsForTest();
607580});
@@ -647,26 +620,12 @@ describe("acp setSessionConfigOption bridge behavior", () => {
647620createSetSessionConfigOptionRequest("reasoning-session", "reasoning_level", "stream"),
648621);
649622650-expect(result.configOptions).toEqual(
651-expect.arrayContaining([
652-expect.objectContaining({
653-id: "reasoning_level",
654-currentValue: "stream",
655-}),
656-]),
623+expectConfigOption(result.configOptions, "reasoning_level", { currentValue: "stream" });
624+expectConfigOption(
625+expectSessionUpdate(sessionUpdate, "reasoning-session", "config_option_update").configOptions,
626+"reasoning_level",
627+{ currentValue: "stream" },
657628);
658-expect(sessionUpdate).toHaveBeenCalledWith({
659-sessionId: "reasoning-session",
660-update: {
661-sessionUpdate: "config_option_update",
662-configOptions: expect.arrayContaining([
663-expect.objectContaining({
664-id: "reasoning_level",
665-currentValue: "stream",
666-}),
667-]),
668-},
669-});
670629671630sessionStore.clearAllSessionsForTest();
672631});
@@ -718,26 +677,12 @@ describe("acp setSessionConfigOption bridge behavior", () => {
718677createSetSessionConfigOptionRequest("fast-session", "fast_mode", "on"),
719678);
720679721-expect(result.configOptions).toEqual(
722-expect.arrayContaining([
723-expect.objectContaining({
724-id: "fast_mode",
725-currentValue: "on",
726-}),
727-]),
680+expectConfigOption(result.configOptions, "fast_mode", { currentValue: "on" });
681+expectConfigOption(
682+expectSessionUpdate(sessionUpdate, "fast-session", "config_option_update").configOptions,
683+"fast_mode",
684+{ currentValue: "on" },
728685);
729-expect(sessionUpdate).toHaveBeenCalledWith({
730-sessionId: "fast-session",
731-update: {
732-sessionUpdate: "config_option_update",
733-configOptions: expect.arrayContaining([
734-expect.objectContaining({
735-id: "fast_mode",
736-currentValue: "on",
737-}),
738-]),
739-},
740-});
741686742687sessionStore.clearAllSessionsForTest();
743688});
@@ -777,15 +722,10 @@ describe("acp setSessionConfigOption bridge behavior", () => {
777722778723await agent.loadSession(createLoadSessionRequest("timeout-session"));
779724780-await expect(
781-agent.setSessionConfigOption(
782-createSetSessionConfigOptionRequest("timeout-session", "timeout", "180"),
783-),
784-).resolves.toEqual(
785-expect.objectContaining({
786-configOptions: expect.any(Array),
787-}),
725+const result = await agent.setSessionConfigOption(
726+createSetSessionConfigOptionRequest("timeout-session", "timeout", "180"),
788727);
728+expect(Array.isArray(result.configOptions)).toBe(true);
789729790730expect(request).not.toHaveBeenCalledWith("sessions.patch", expect.anything());
791731@@ -833,10 +773,13 @@ describe("acp setSessionConfigOption bridge behavior", () => {
833773).rejects.toThrow(
834774'ACP bridge does not support non-string session config option values for "thought_level".',
835775);
836-expect(request).not.toHaveBeenCalledWith(
837-"sessions.patch",
838-expect.objectContaining({ key: "bool-config-session" }),
839-);
776+expect(
777+(request as unknown as MockCallSource).mock.calls.some(
778+([method, params]) =>
779+method === "sessions.patch" &&
780+requireRecord(params, "sessions.patch params").key === "bool-config-session",
781+),
782+).toBe(false);
840783841784sessionStore.clearAllSessionsForTest();
842785});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。