"use strict";
var import_web = require("node:stream/web");
var import_vitest = require("vitest");
var import_zod = require("zod");
var import_llm = require("../llm/index.cjs");
var import_log = require("../log.cjs");
var import_tts = require("../tts/index.cjs");
var import_utils = require("../utils.cjs");
var import_agent = require("./agent.cjs");
var import_agent_activity = require("./agent_activity.cjs");
var import_endpointing = require("./turn_config/endpointing.cjs");
var import_interruption = require("./turn_config/interruption.cjs");
import_vitest.vi.mock("ofetch", () => ({ ofetch: import_vitest.vi.fn() }));
(0, import_log.initializeLogger)({ pretty: false, level: "error" });
async function collectReadableStream(stream) {
  const chunks = [];
  for await (const chunk of stream) {
    chunks.push(chunk);
  }
  return chunks;
}
(0, import_vitest.describe)("Agent", () => {
  (0, import_vitest.it)("should create agent with basic instructions", () => {
    const instructions = "You are a helpful assistant";
    const agent = new import_agent.Agent({ instructions });
    (0, import_vitest.expect)(agent).toBeDefined();
    (0, import_vitest.expect)(agent.instructions).toBe(instructions);
  });
  (0, import_vitest.it)("should create agent with instructions and tools", () => {
    var _a, _b;
    const instructions = "You are a helpful assistant with tools";
    const mockTool1 = (0, import_llm.tool)({
      name: "getTool1",
      description: "First test tool",
      parameters: import_zod.z.object({}),
      execute: async () => "tool1 result"
    });
    const mockTool2 = (0, import_llm.tool)({
      name: "getTool2",
      description: "Second test tool",
      parameters: import_zod.z.object({
        input: import_zod.z.string().describe("Input parameter")
      }),
      execute: async ({ input }) => `tool2: ${input}`
    });
    const agent = new import_agent.Agent({
      instructions,
      tools: [mockTool1, mockTool2]
    });
    (0, import_vitest.expect)(agent).toBeDefined();
    (0, import_vitest.expect)(agent.instructions).toBe(instructions);
    const agentTools = agent.toolCtx.functionTools;
    (0, import_vitest.expect)(Object.keys(agentTools)).toHaveLength(2);
    (0, import_vitest.expect)(agentTools).toHaveProperty("getTool1");
    (0, import_vitest.expect)(agentTools).toHaveProperty("getTool2");
    (0, import_vitest.expect)((_a = agentTools.getTool1) == null ? void 0 : _a.description).toBe("First test tool");
    (0, import_vitest.expect)((_b = agentTools.getTool2) == null ? void 0 : _b.description).toBe("Second test tool");
  });
  (0, import_vitest.it)("toolCtx returns a defensive copy that exposes the same tools", () => {
    const instructions = "You are a helpful assistant";
    const mockTool = (0, import_llm.tool)({
      name: "testTool",
      description: "Test tool",
      parameters: import_zod.z.object({}),
      execute: async () => "result"
    });
    const agent = new import_agent.Agent({ instructions, tools: [mockTool] });
    (0, import_vitest.expect)(agent.toolCtx).not.toBe(agent.toolCtx);
    (0, import_vitest.expect)(agent.toolCtx.getFunctionTool("testTool")).toBe(mockTool);
  });
  (0, import_vitest.describe)("create", () => {
    (0, import_vitest.it)("preserves constructor options and base Agent default id", () => {
      const mockTool = (0, import_llm.tool)({
        name: "testTool",
        description: "Test tool",
        parameters: import_zod.z.object({}),
        execute: async () => "result"
      });
      const agent = import_agent.Agent.create({
        instructions: "factory instructions",
        tools: [mockTool]
      });
      (0, import_vitest.expect)(agent).toBeInstanceOf(import_agent.Agent);
      (0, import_vitest.expect)(agent.instructions).toBe("factory instructions");
      (0, import_vitest.expect)(agent.id).toBe("default_agent");
      (0, import_vitest.expect)(agent.toolCtx.getFunctionTool("testTool")).toBe(mockTool);
    });
    (0, import_vitest.it)("passes AgentContext to lifecycle hooks", async () => {
      const calls = [];
      const chatCtx = import_llm.ChatContext.empty();
      const newMessage = import_llm.ChatMessage.create({ role: "user", content: ["hello"] });
      const agent = import_agent.Agent.create({
        id: "factory_agent",
        instructions: "factory instructions",
        minConsecutiveSpeechDelay: 12,
        onEnter: (ctx) => {
          (0, import_vitest.expect)(ctx.agent).toBe(agent);
          (0, import_vitest.expect)(ctx.id).toBe(agent.id);
          (0, import_vitest.expect)(ctx.instructions).toBe(agent.instructions);
          (0, import_vitest.expect)(ctx.toolCtx.functionTools).toEqual(agent.toolCtx.functionTools);
          (0, import_vitest.expect)(ctx.chatCtx.items).toEqual(agent.chatCtx.items);
          (0, import_vitest.expect)(ctx.minConsecutiveSpeechDelay).toBe(agent.minConsecutiveSpeechDelay);
          calls.push("enter");
        },
        onExit: async (ctx) => {
          (0, import_vitest.expect)(ctx.agent).toBe(agent);
          calls.push("exit");
        },
        onUserTurnCompleted: (ctx, receivedChatCtx, receivedMessage) => {
          (0, import_vitest.expect)(ctx.agent).toBe(agent);
          (0, import_vitest.expect)(receivedChatCtx).toBe(chatCtx);
          (0, import_vitest.expect)(receivedMessage).toBe(newMessage);
          calls.push("turn");
        }
      });
      await agent.onEnter();
      await agent.onExit();
      await agent.onUserTurnCompleted(chatCtx, newMessage);
      (0, import_vitest.expect)(calls).toEqual(["enter", "exit", "turn"]);
    });
    (0, import_vitest.it)("adapts stream node hooks between ReadableStream and AsyncIterable", async () => {
      const audioFrame = "audio";
      const agent = import_agent.Agent.create({
        instructions: "factory instructions",
        async sttNode(ctx, audio2) {
          async function* stream() {
            (0, import_vitest.expect)(ctx.agent).toBe(agent);
            const frames = [];
            for await (const frame of audio2) {
              frames.push(frame);
            }
            (0, import_vitest.expect)(frames).toEqual([audioFrame]);
            yield "transcript";
          }
          return stream();
        }
      });
      const audio = new import_web.ReadableStream({
        start(controller) {
          controller.enqueue(audioFrame);
          controller.close();
        }
      });
      const result = await agent.sttNode(audio, {});
      (0, import_vitest.expect)(result).not.toBeNull();
      await (0, import_vitest.expect)(collectReadableStream(result)).resolves.toEqual(["transcript"]);
    });
    (0, import_vitest.it)("supports async generator stream node hooks", async () => {
      const audioFrame = "audio";
      const outputFrame = "output-audio";
      const agent = import_agent.Agent.create({
        instructions: "factory instructions",
        async *sttNode(ctx, audio2) {
          (0, import_vitest.expect)(ctx.agent).toBe(agent);
          const frames = [];
          for await (const frame of audio2) {
            frames.push(frame);
          }
          (0, import_vitest.expect)(frames).toEqual([audioFrame]);
          yield "transcript";
        },
        async *llmNode(ctx, chatCtx, toolCtx) {
          (0, import_vitest.expect)(ctx.agent).toBe(agent);
          (0, import_vitest.expect)(chatCtx).toBeInstanceOf(import_llm.ChatContext);
          (0, import_vitest.expect)(toolCtx.equals(agent.toolCtx)).toBe(true);
          yield "llm-output";
        },
        async *ttsNode(ctx, text2) {
          (0, import_vitest.expect)(ctx.agent).toBe(agent);
          const chunks = [];
          for await (const chunk of text2) {
            chunks.push(chunk);
          }
          (0, import_vitest.expect)(chunks).toEqual(["hello"]);
          yield outputFrame;
        },
        async *realtimeAudioOutputNode(ctx, audio2) {
          (0, import_vitest.expect)(ctx.agent).toBe(agent);
          const frames = [];
          for await (const frame of audio2) {
            frames.push(frame);
          }
          (0, import_vitest.expect)(frames).toEqual([audioFrame]);
          yield outputFrame;
        }
      });
      const audio = new import_web.ReadableStream({
        start(controller) {
          controller.enqueue(audioFrame);
          controller.close();
        }
      });
      const text = new import_web.ReadableStream({
        start(controller) {
          controller.enqueue("hello");
          controller.close();
        }
      });
      const sttResult = await agent.sttNode(audio, {});
      const llmResult = await agent.llmNode(import_llm.ChatContext.empty(), agent.toolCtx, {});
      const ttsResult = await agent.ttsNode(text, {});
      const realtimeResult = await agent.realtimeAudioOutputNode(
        new import_web.ReadableStream({
          start(controller) {
            controller.enqueue(audioFrame);
            controller.close();
          }
        }),
        {}
      );
      (0, import_vitest.expect)(sttResult).not.toBeNull();
      (0, import_vitest.expect)(llmResult).not.toBeNull();
      (0, import_vitest.expect)(ttsResult).not.toBeNull();
      (0, import_vitest.expect)(realtimeResult).not.toBeNull();
      await (0, import_vitest.expect)(collectReadableStream(sttResult)).resolves.toEqual(["transcript"]);
      await (0, import_vitest.expect)(collectReadableStream(llmResult)).resolves.toEqual(["llm-output"]);
      await (0, import_vitest.expect)(collectReadableStream(ttsResult)).resolves.toEqual([outputFrame]);
      await (0, import_vitest.expect)(collectReadableStream(realtimeResult)).resolves.toEqual([outputFrame]);
    });
    (0, import_vitest.it)("supports stream node hooks that return async iterables", async () => {
      function asyncIterableOf(...items) {
        return {
          async *[Symbol.asyncIterator]() {
            for (const item of items) {
              yield item;
            }
          }
        };
      }
      const audioFrame = "audio";
      const outputFrame = "output-audio";
      const agent = import_agent.Agent.create({
        instructions: "factory instructions",
        sttNode(ctx) {
          (0, import_vitest.expect)(ctx.agent).toBe(agent);
          return asyncIterableOf("transcript");
        },
        llmNode(ctx) {
          (0, import_vitest.expect)(ctx.agent).toBe(agent);
          return asyncIterableOf("llm-output");
        },
        ttsNode(ctx) {
          (0, import_vitest.expect)(ctx.agent).toBe(agent);
          return asyncIterableOf(outputFrame);
        },
        realtimeAudioOutputNode(ctx) {
          (0, import_vitest.expect)(ctx.agent).toBe(agent);
          return asyncIterableOf(outputFrame);
        }
      });
      const sttResult = await agent.sttNode(
        new import_web.ReadableStream({
          start(controller) {
            controller.enqueue(audioFrame);
            controller.close();
          }
        }),
        {}
      );
      const llmResult = await agent.llmNode(import_llm.ChatContext.empty(), agent.toolCtx, {});
      const ttsResult = await agent.ttsNode(
        new import_web.ReadableStream({
          start(controller) {
            controller.enqueue("hello");
            controller.close();
          }
        }),
        {}
      );
      const realtimeResult = await agent.realtimeAudioOutputNode(
        new import_web.ReadableStream({
          start(controller) {
            controller.enqueue(audioFrame);
            controller.close();
          }
        }),
        {}
      );
      (0, import_vitest.expect)(sttResult).not.toBeNull();
      (0, import_vitest.expect)(llmResult).not.toBeNull();
      (0, import_vitest.expect)(ttsResult).not.toBeNull();
      (0, import_vitest.expect)(realtimeResult).not.toBeNull();
      await (0, import_vitest.expect)(collectReadableStream(sttResult)).resolves.toEqual(["transcript"]);
      await (0, import_vitest.expect)(collectReadableStream(llmResult)).resolves.toEqual(["llm-output"]);
      await (0, import_vitest.expect)(collectReadableStream(ttsResult)).resolves.toEqual([outputFrame]);
      await (0, import_vitest.expect)(collectReadableStream(realtimeResult)).resolves.toEqual([outputFrame]);
    });
    (0, import_vitest.it)("falls back to existing defaults for missing hooks", async () => {
      const audioFrame = "audio";
      const audio = new import_web.ReadableStream({
        start(controller) {
          controller.enqueue(audioFrame);
          controller.close();
        }
      });
      const agent = import_agent.Agent.create({ instructions: "factory instructions" });
      const result = await agent.realtimeAudioOutputNode(audio, {});
      (0, import_vitest.expect)(result).toBe(audio);
    });
  });
  (0, import_vitest.describe)("AsyncIterable pipeline node inputs", () => {
    (0, import_vitest.it)("accepts a plain AsyncIterable into Agent.create stream hooks without getReader crash", async () => {
      const outputFrame = "output-audio";
      const agent = import_agent.Agent.create({
        instructions: "factory instructions",
        async *ttsNode(ctx, text) {
          (0, import_vitest.expect)(ctx.agent).toBe(agent);
          const chunks = [];
          for await (const chunk of text) {
            chunks.push(chunk);
          }
          (0, import_vitest.expect)(chunks).toEqual(["hello"]);
          yield outputFrame;
        }
      });
      async function* textInput() {
        yield "hello";
      }
      const result = await agent.ttsNode(textInput(), {});
      (0, import_vitest.expect)(result).not.toBeNull();
      await (0, import_vitest.expect)(collectReadableStream(result)).resolves.toEqual([outputFrame]);
    });
    (0, import_vitest.it)("forwards transformed output through an Agent.create transcriptionNode hook", async () => {
      const agent = import_agent.Agent.create({
        instructions: "factory instructions",
        async *transcriptionNode(ctx, text) {
          (0, import_vitest.expect)(ctx.agent).toBe(agent);
          for await (const chunk of text) {
            yield `${chunk}!`;
          }
        }
      });
      async function* textInput() {
        yield "hello";
        yield "world";
      }
      const result = await agent.transcriptionNode(textInput(), {});
      (0, import_vitest.expect)(result).not.toBeNull();
      await (0, import_vitest.expect)(collectReadableStream(result)).resolves.toEqual(["hello!", "world!"]);
    });
    (0, import_vitest.it)("accepts a plain AsyncIterable into Agent.default.ttsNode", async () => {
      const frame = "frame";
      const agent = new import_agent.Agent({ instructions: "default instructions" });
      let capturedInput;
      const ttsStream = {
        startTimeOffset: 0,
        updateInputStream(input) {
          capturedInput = input;
        },
        close() {
        },
        async *[Symbol.asyncIterator]() {
          yield { frame, timedTranscripts: [] };
          yield import_tts.SynthesizeStream.END_OF_STREAM;
        }
      };
      agent._agentActivity = {
        tts: {
          capabilities: { streaming: true },
          stream: () => ttsStream,
          close: async () => {
          }
        },
        agentSession: { connOptions: { ttsConnOptions: {} } }
      };
      async function* textInput() {
        yield "hello";
      }
      const result = await import_agent.Agent.default.ttsNode(agent, textInput(), {});
      (0, import_vitest.expect)(result).not.toBeNull();
      (0, import_vitest.expect)(capturedInput).toBeInstanceOf(import_web.ReadableStream);
      await (0, import_vitest.expect)(collectReadableStream(result)).resolves.toEqual([frame]);
    });
  });
  (0, import_vitest.it)("should require AgentTask to run inside task context", async () => {
    class TestTask extends import_agent.AgentTask {
      constructor() {
        super({ instructions: "test task" });
      }
    }
    const task = new TestTask();
    await (0, import_vitest.expect)(task.run()).rejects.toThrow("must be executed inside a Task context");
  });
  (0, import_vitest.it)("should require AgentTask to run inside inline task context", async () => {
    class TestTask extends import_agent.AgentTask {
      constructor() {
        super({ instructions: "test task" });
      }
    }
    const task = new TestTask();
    const wrapper = import_utils.Task.from(async () => {
      return await task.run();
    });
    await (0, import_vitest.expect)(wrapper.result).rejects.toThrow(
      "should only be awaited inside function tools or the onEnter/onExit methods of an Agent"
    );
  });
  (0, import_vitest.it)("should allow AgentTask run from inline task context", async () => {
    class TestTask extends import_agent.AgentTask {
      constructor() {
        super({ instructions: "test task" });
      }
    }
    const task = new TestTask();
    const oldAgent = new import_agent.Agent({ instructions: "old agent" });
    const mockSession = {
      currentAgent: oldAgent,
      _globalRunState: void 0,
      _updateActivity: async (agent) => {
        if (agent === task) {
          task.complete("ok");
        }
      }
    };
    const mockActivity = {
      agent: oldAgent,
      agentSession: mockSession,
      _onEnterTask: void 0,
      llm: void 0,
      close: async () => {
      }
    };
    const wrapper = import_utils.Task.from(async () => {
      const currentTask = import_utils.Task.current();
      if (!currentTask) {
        throw new Error("expected task context");
      }
      (0, import_agent._setActivityTaskInfo)(currentTask, { inlineTask: true });
      return await import_agent_activity.agentActivityStorage.run(mockActivity, () => task.run());
    });
    await (0, import_vitest.expect)(wrapper.result).resolves.toBe("ok");
  });
  (0, import_vitest.describe)("AgentTask.create", () => {
    (0, import_vitest.it)("exposes complete on hook context", async () => {
      const task = import_agent.AgentTask.create({
        instructions: "factory task",
        onEnter: (ctx) => {
          (0, import_vitest.expect)(ctx.agent).toBe(task);
          (0, import_vitest.expect)(ctx.id).toBe("default_agent");
          (0, import_vitest.expect)(ctx.instructions).toBe("factory task");
          ctx.complete("ok");
        }
      });
      const oldAgent = new import_agent.Agent({ instructions: "old agent" });
      const mockSession = {
        currentAgent: oldAgent,
        _globalRunState: void 0,
        _updateActivity: async (agent) => {
          if (agent === task) {
            await agent.onEnter();
          }
        }
      };
      const mockActivity = {
        agent: oldAgent,
        agentSession: mockSession,
        _onEnterTask: void 0,
        llm: void 0,
        close: async () => {
        }
      };
      const wrapper = import_utils.Task.from(async () => {
        const currentTask = import_utils.Task.current();
        if (!currentTask) {
          throw new Error("expected task context");
        }
        (0, import_agent._setActivityTaskInfo)(currentTask, { inlineTask: true });
        return await import_agent_activity.agentActivityStorage.run(mockActivity, () => task.run());
      });
      await (0, import_vitest.expect)(wrapper.result).resolves.toBe("ok");
    });
    (0, import_vitest.it)("adapts stream node hooks between ReadableStream and AsyncIterable", async () => {
      const audioFrame = "audio";
      const task = import_agent.AgentTask.create({
        instructions: "factory task",
        async sttNode(ctx, audio2) {
          async function* stream() {
            (0, import_vitest.expect)(ctx.agent).toBe(task);
            const frames = [];
            for await (const frame of audio2) {
              frames.push(frame);
            }
            (0, import_vitest.expect)(frames).toEqual([audioFrame]);
            yield "transcript";
          }
          return stream();
        }
      });
      const audio = new import_web.ReadableStream({
        start(controller) {
          controller.enqueue(audioFrame);
          controller.close();
        }
      });
      const result = await task.sttNode(audio, {});
      (0, import_vitest.expect)(result).not.toBeNull();
      await (0, import_vitest.expect)(collectReadableStream(result)).resolves.toEqual(["transcript"]);
    });
    (0, import_vitest.it)("falls back to existing defaults for missing hooks", async () => {
      const audioFrame = "audio";
      const audio = new import_web.ReadableStream({
        start(controller) {
          controller.enqueue(audioFrame);
          controller.close();
        }
      });
      const task = import_agent.AgentTask.create({ instructions: "factory task" });
      const result = await task.realtimeAudioOutputNode(audio, {});
      (0, import_vitest.expect)(result).toBe(audio);
    });
  });
  (0, import_vitest.it)("should require AgentTask to run inside AgentActivity context", async () => {
    class TestTask extends import_agent.AgentTask {
      constructor() {
        super({ instructions: "test task" });
      }
    }
    const task = new TestTask();
    const wrapper = import_utils.Task.from(async () => {
      const currentTask = import_utils.Task.current();
      if (!currentTask) {
        throw new Error("expected task context");
      }
      (0, import_agent._setActivityTaskInfo)(currentTask, { inlineTask: true });
      return await task.run();
    });
    await (0, import_vitest.expect)(wrapper.result).rejects.toThrow(
      "must be executed inside an AgentActivity context"
    );
  });
  (0, import_vitest.it)("should close old activity when current agent changes while AgentTask is pending", async () => {
    class TestTask extends import_agent.AgentTask {
      constructor() {
        super({ instructions: "test task" });
      }
    }
    const task = new TestTask();
    const oldAgent = new import_agent.Agent({ instructions: "old agent" });
    const switchedAgent = new import_agent.Agent({ instructions: "switched agent" });
    const closeOldActivity = import_vitest.vi.fn(async () => {
    });
    const mockSession = {
      currentAgent: oldAgent,
      _globalRunState: void 0,
      _updateActivity: async (agent) => {
        if (agent === task) {
          mockSession.currentAgent = switchedAgent;
          task.complete("ok");
        }
      }
    };
    const mockActivity = {
      agent: oldAgent,
      agentSession: mockSession,
      _onEnterTask: void 0,
      llm: void 0,
      close: closeOldActivity
    };
    const wrapper = import_utils.Task.from(async () => {
      const currentTask = import_utils.Task.current();
      if (!currentTask) {
        throw new Error("expected task context");
      }
      (0, import_agent._setActivityTaskInfo)(currentTask, { inlineTask: true });
      return await import_agent_activity.agentActivityStorage.run(mockActivity, () => task.run());
    });
    await (0, import_vitest.expect)(wrapper.result).resolves.toBe("ok");
    (0, import_vitest.expect)(closeOldActivity).toHaveBeenCalledTimes(1);
  });
  (0, import_vitest.describe)("Agent constructor option migration", () => {
    (0, import_vitest.it)("should set allowInterruptions to false via deprecated constructor field", () => {
      var _a, _b;
      const agent = new import_agent.Agent({ instructions: "test", allowInterruptions: false });
      (0, import_vitest.expect)((_b = (_a = agent.turnHandling) == null ? void 0 : _a.interruption) == null ? void 0 : _b.enabled).toBe(false);
    });
    (0, import_vitest.it)("should not set derived properties when no compatibility fields are provided", () => {
      const agent = new import_agent.Agent({ instructions: "test" });
      (0, import_vitest.expect)(agent.turnHandling).toBeUndefined();
    });
    (0, import_vitest.it)("should expose minConsecutiveSpeechDelay", () => {
      const agent = new import_agent.Agent({ instructions: "test", minConsecutiveSpeechDelay: 1.5 });
      (0, import_vitest.expect)(agent.minConsecutiveSpeechDelay).toBe(1.5);
    });
    (0, import_vitest.it)("should ignore deprecated constructor fields when turnHandling is provided", () => {
      var _a, _b, _c, _d, _e, _f, _g;
      const agent = new import_agent.Agent({
        instructions: "test",
        turnHandling: {
          endpointing: { minDelay: 999 },
          interruption: {},
          preemptiveGeneration: {},
          turnDetection: "vad"
        },
        allowInterruptions: false
      });
      (0, import_vitest.expect)((_b = (_a = agent.turnHandling) == null ? void 0 : _a.endpointing) == null ? void 0 : _b.minDelay).toBe(999);
      (0, import_vitest.expect)((_d = (_c = agent.turnHandling) == null ? void 0 : _c.endpointing) == null ? void 0 : _d.maxDelay).toBeUndefined();
      (0, import_vitest.expect)((_f = (_e = agent.turnHandling) == null ? void 0 : _e.interruption) == null ? void 0 : _f.enabled).toBeUndefined();
      (0, import_vitest.expect)((_g = agent.turnHandling) == null ? void 0 : _g.turnDetection).toBe("vad");
    });
    (0, import_vitest.it)("should let turnHandling override deprecated constructor fields on conflicts", () => {
      var _a, _b, _c, _d, _e, _f, _g;
      const agent = new import_agent.Agent({
        instructions: "test",
        turnHandling: {
          endpointing: { minDelay: 999, maxDelay: 4e3 },
          interruption: { enabled: true },
          preemptiveGeneration: {},
          turnDetection: "vad"
        },
        allowInterruptions: false,
        turnDetection: "stt"
      });
      (0, import_vitest.expect)((_b = (_a = agent.turnHandling) == null ? void 0 : _a.endpointing) == null ? void 0 : _b.minDelay).toBe(999);
      (0, import_vitest.expect)((_d = (_c = agent.turnHandling) == null ? void 0 : _c.endpointing) == null ? void 0 : _d.maxDelay).toBe(4e3);
      (0, import_vitest.expect)((_f = (_e = agent.turnHandling) == null ? void 0 : _e.interruption) == null ? void 0 : _f.enabled).toBe(true);
      (0, import_vitest.expect)((_g = agent.turnHandling) == null ? void 0 : _g.turnDetection).toBe("vad");
    });
    (0, import_vitest.it)("should set interruptionDetection from turnHandling.interruption.mode", () => {
      var _a, _b;
      const agent = new import_agent.Agent({
        instructions: "test",
        turnHandling: {
          interruption: { mode: "adaptive" },
          endpointing: {},
          preemptiveGeneration: {},
          turnDetection: void 0
        }
      });
      (0, import_vitest.expect)((_b = (_a = agent.turnHandling) == null ? void 0 : _a.interruption) == null ? void 0 : _b.mode).toBe("adaptive");
    });
    (0, import_vitest.it)("should let AgentActivity prefer agent-level overrides over session defaults", () => {
      var _a, _b;
      const agent = new import_agent.Agent({
        instructions: "test",
        turnHandling: {
          endpointing: { minDelay: 111, maxDelay: 222 },
          interruption: { enabled: false },
          preemptiveGeneration: {},
          turnDetection: "manual"
        }
      });
      const session = {
        options: {
          turnHandling: {
            endpointing: import_endpointing.defaultEndpointingOptions,
            interruption: import_interruption.defaultInterruptionOptions
          }
        },
        turnDetection: "stt",
        useTtsAlignedTranscript: true,
        vad: void 0,
        stt: void 0,
        llm: void 0,
        tts: void 0,
        interruptionDetection: void 0
      };
      const activity = new import_agent_activity.AgentActivity(agent, session);
      (0, import_vitest.expect)(activity.allowInterruptions).toBe(false);
      (0, import_vitest.expect)(activity.turnDetection).toBe("manual");
      (0, import_vitest.expect)((_a = activity.turnHandling.endpointing) == null ? void 0 : _a.minDelay).toBe(111);
      (0, import_vitest.expect)((_b = activity.turnHandling.endpointing) == null ? void 0 : _b.maxDelay).toBe(222);
    });
    (0, import_vitest.it)("should disable adaptive interruption detection in default mode when prerequisites are missing", () => {
      const previousRemoteEotUrl = process.env.LIVEKIT_REMOTE_EOT_URL;
      process.env.LIVEKIT_REMOTE_EOT_URL = "http://localhost:9999";
      try {
        const agent = new import_agent.Agent({ instructions: "test" });
        const session = {
          options: {
            turnHandling: {
              endpointing: import_endpointing.defaultEndpointingOptions,
              interruption: import_interruption.defaultInterruptionOptions
            }
          },
          sessionOptions: {
            turnHandling: {
              endpointing: import_endpointing.defaultEndpointingOptions,
              interruption: import_interruption.defaultInterruptionOptions
            }
          },
          turnDetection: "manual",
          useTtsAlignedTranscript: true,
          vad: {},
          stt: {
            capabilities: {
              alignedTranscript: true,
              streaming: true
            }
          },
          llm: void 0,
          tts: void 0,
          interruptionDetection: void 0
        };
        const activity = new import_agent_activity.AgentActivity(agent, session);
        (0, import_vitest.expect)(activity.interruptionDetector).toBeUndefined();
      } finally {
        if (previousRemoteEotUrl === void 0) {
          delete process.env.LIVEKIT_REMOTE_EOT_URL;
        } else {
          process.env.LIVEKIT_REMOTE_EOT_URL = previousRemoteEotUrl;
        }
      }
    });
    (0, import_vitest.it)("should warn when session explicitly requests adaptive detection even if agent overrides it", () => {
      const activity = Object.create(import_agent_activity.AgentActivity.prototype);
      activity.agent = {
        turnHandling: { interruption: { mode: "vad" } },
        turnDetection: void 0
      };
      activity.agentSession = {
        interruptionDetection: "adaptive",
        turnDetection: "manual"
      };
      activity.logger = { warn: import_vitest.vi.fn() };
      (0, import_vitest.expect)(activity.resolveInterruptionDetector()).toBeUndefined();
      (0, import_vitest.expect)(activity.logger.warn).toHaveBeenCalledWith(
        "interruptionDetection is provided, but it's not compatible with the current configuration and will be disabled"
      );
    });
    (0, import_vitest.it)("should disable adaptive interruption detection when interruptions are disabled", () => {
      const previousRemoteEotUrl = process.env.LIVEKIT_REMOTE_EOT_URL;
      process.env.LIVEKIT_REMOTE_EOT_URL = "http://localhost:9999";
      try {
        const activity = Object.create(import_agent_activity.AgentActivity.prototype);
        activity.agent = {
          turnHandling: {
            interruption: { enabled: false }
          },
          turnDetection: void 0,
          stt: void 0,
          vad: void 0,
          llm: void 0
        };
        activity.agentSession = {
          interruptionDetection: void 0,
          turnDetection: "stt",
          sessionOptions: {
            turnHandling: {
              interruption: import_interruption.defaultInterruptionOptions,
              endpointing: import_endpointing.defaultEndpointingOptions
            }
          },
          stt: {
            capabilities: {
              alignedTranscript: true,
              streaming: true
            }
          },
          vad: {},
          llm: void 0
        };
        activity.logger = { warn: import_vitest.vi.fn() };
        (0, import_vitest.expect)(activity.resolveInterruptionDetector()).toBeUndefined();
        (0, import_vitest.expect)(activity.logger.warn).not.toHaveBeenCalled();
      } finally {
        if (previousRemoteEotUrl === void 0) {
          delete process.env.LIVEKIT_REMOTE_EOT_URL;
        } else {
          process.env.LIVEKIT_REMOTE_EOT_URL = previousRemoteEotUrl;
        }
      }
    });
  });
});
//# sourceMappingURL=agent.test.cjs.map