import { describe, it, beforeEach, afterEach } from "node:test"; import assert from "node:assert"; import { enterMultiMessageMode, exitMultiMessageMode, isMultiMessageMode } from "../plugin/core/channel-modes.ts"; import { initTurnOrder, checkTurn, getTurnDebugInfo, onNewMessage, resetTurn } from "../plugin/turn-manager.ts"; describe("Multi-Message Mode Tests", () => { const channelId = "test-channel"; beforeEach(() => { resetTurn(channelId); exitMultiMessageMode(channelId); // Ensure clean state }); afterEach(() => { resetTurn(channelId); exitMultiMessageMode(channelId); }); describe("multi-message mode state management", () => { it("should enter multi-message mode", () => { enterMultiMessageMode(channelId); assert.strictEqual(isMultiMessageMode(channelId), true); }); it("should exit multi-message mode", () => { enterMultiMessageMode(channelId); assert.strictEqual(isMultiMessageMode(channelId), true); exitMultiMessageMode(channelId); assert.strictEqual(isMultiMessageMode(channelId), false); }); it("should start in normal mode by default", () => { assert.strictEqual(isMultiMessageMode(channelId), false); }); }); describe("compatibility with waiting-for-human", () => { it("should properly handle multi-message mode with human messages", () => { const botIds = ["agent-a", "agent-b"]; initTurnOrder(channelId, botIds); // Enter multi-message mode enterMultiMessageMode(channelId); assert.strictEqual(isMultiMessageMode(channelId), true); // Simulate human message in multi-message mode onNewMessage(channelId, "human-user", true); // Exit multi-message mode exitMultiMessageMode(channelId); assert.strictEqual(isMultiMessageMode(channelId), false); // Should be able to proceed normally onNewMessage(channelId, "human-user", true); const turnResult = checkTurn(channelId, "agent-a"); assert.ok(turnResult); }); }); describe("compatibility with mention override", () => { it("should handle multi-message mode with mention override", () => { const botIds = ["agent-a", "agent-b", "agent-c"]; initTurnOrder(channelId, botIds); // Enter multi-message mode enterMultiMessageMode(channelId); assert.strictEqual(isMultiMessageMode(channelId), true); // Even with mention override conceptually, multi-message mode should take precedence // In real usage, mention overrides happen in message-received hook before multi-message mode logic const turnResult = checkTurn(channelId, "agent-a"); assert.ok(typeof turnResult === "object"); // The actual behavior depends on the before-model-resolve hook which forces no-reply in multi-message mode // Exit multi-message mode to resume normal operation exitMultiMessageMode(channelId); assert.strictEqual(isMultiMessageMode(channelId), false); }); }); describe("multi-message mode interaction with turn management", () => { it("should pause turn management in multi-message mode", () => { const botIds = ["agent-a", "agent-b"]; initTurnOrder(channelId, botIds); // Initially, turn should work normally const normalTurnResult = checkTurn(channelId, "agent-a"); assert.ok(normalTurnResult); // Enter multi-message mode enterMultiMessageMode(channelId); // In multi-message mode, agents should be blocked (this is handled in before-model-resolve hook) // But the turn state itself continues to exist const stateInMultiMessage = getTurnDebugInfo(channelId); assert.ok(stateInMultiMessage.hasTurnState); // Exit multi-message mode exitMultiMessageMode(channelId); const stateAfterExit = getTurnDebugInfo(channelId); assert.ok(stateAfterExit.hasTurnState); }); }); });