"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  // If the importer is in node compatibility mode or this is not an ESM
  // file that has been converted to a CommonJS file using a Babel-
  // compatible transform (i.e. "__esModule" has not been set), then set
  // "default" to the CommonJS "module.exports" for node compatibility.
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  mod
));
var import_vitest = require("vitest");
var import_zod = require("zod");
var z3 = __toESM(require("zod/v3"), 1);
var z4 = __toESM(require("zod/v4"), 1);
var import__ = require("../index.cjs");
var import_tool_context = require("./tool_context.cjs");
var import_utils = require("./utils.cjs");
(0, import_vitest.describe)("tools object compatibility", () => {
  (0, import_vitest.it)("normalizes object tools into named function tools", () => {
    const getWeather = (0, import_tool_context.tool)({
      description: "Get the weather",
      execute: async () => "sunny"
    });
    const toolCtx = new import_tool_context.ToolContext({
      getWeather
    });
    const namedTool = toolCtx.getFunctionTool("getWeather");
    (0, import_vitest.expect)(namedTool).toBeDefined();
    (0, import_vitest.expect)(namedTool == null ? void 0 : namedTool.name).toBe("getWeather");
    (0, import_vitest.expect)(namedTool == null ? void 0 : namedTool.id).toBe("getWeather");
    (0, import_vitest.expect)(namedTool == null ? void 0 : namedTool.description).toBe("Get the weather");
    (0, import_vitest.expect)(toolCtx.tools).toEqual([namedTool]);
  });
  (0, import_vitest.it)("accepts object tools in agent and session construction APIs", () => {
    var _a, _b, _c, _d, _e;
    const tools = {
      lookupOrder: (0, import_tool_context.tool)({
        description: "Look up an order",
        execute: async () => ({ ok: true })
      })
    };
    const agent = new import__.voice.Agent({ instructions: "help", tools });
    const createdAgent = import__.voice.Agent.create({ instructions: "help", tools });
    const task = new import__.voice.AgentTask({ instructions: "help", tools });
    const createdTask = import__.voice.AgentTask.create({ instructions: "help", tools });
    const session = new import__.voice.AgentSession({ tools, vad: null });
    (0, import_vitest.expect)((_a = agent.toolCtx.getFunctionTool("lookupOrder")) == null ? void 0 : _a.name).toBe("lookupOrder");
    (0, import_vitest.expect)((_b = createdAgent.toolCtx.getFunctionTool("lookupOrder")) == null ? void 0 : _b.name).toBe("lookupOrder");
    (0, import_vitest.expect)((_c = task.toolCtx.getFunctionTool("lookupOrder")) == null ? void 0 : _c.name).toBe("lookupOrder");
    (0, import_vitest.expect)((_d = createdTask.toolCtx.getFunctionTool("lookupOrder")) == null ? void 0 : _d.name).toBe("lookupOrder");
    (0, import_vitest.expect)((_e = session.tools[0]) == null ? void 0 : _e.name).toBe("lookupOrder");
  });
  (0, import_vitest.it)("keeps rejecting duplicate named function tools in array syntax", () => {
    const first = (0, import_tool_context.tool)({
      name: "duplicate",
      description: "First tool",
      execute: async () => "first"
    });
    const second = (0, import_tool_context.tool)({
      name: "duplicate",
      description: "Second tool",
      execute: async () => "second"
    });
    (0, import_vitest.expect)(() => new import_tool_context.ToolContext([first, second])).toThrow("duplicate function name");
  });
  (0, import_vitest.it)("rejects named tools and toolsets in object syntax", () => {
    const namedTool = (0, import_tool_context.tool)({
      name: "alreadyNamed",
      description: "Already named",
      execute: async () => "ok"
    });
    const toolset = new import_tool_context.Toolset({ id: "group", tools: [] });
    (0, import_vitest.expect)(() => new import_tool_context.ToolContext({ alreadyNamed: namedTool })).toThrow(
      'tools object entry "alreadyNamed" must be anonymous'
    );
    (0, import_vitest.expect)(() => new import_tool_context.ToolContext({ group: toolset })).toThrow(
      'tools object entry "group" must be an anonymous function tool'
    );
  });
});
(0, import_vitest.describe)("Tool Context", () => {
  (0, import_vitest.describe)("oaiParams", () => {
    (0, import_vitest.it)("should handle basic object schema", () => {
      const schema = import_zod.z.object({
        name: import_zod.z.string().describe("The user name"),
        age: import_zod.z.number().describe("The user age")
      });
      const result = (0, import_utils.oaiParams)(schema);
      (0, import_vitest.expect)(result).toMatchSnapshot();
    });
    (0, import_vitest.it)("should handle enum fields", () => {
      const schema = import_zod.z.object({
        color: import_zod.z.enum(["red", "blue", "green"]).describe("Choose a color")
      });
      const result = (0, import_utils.oaiParams)(schema);
      (0, import_vitest.expect)(result).toMatchSnapshot();
    });
    (0, import_vitest.it)("should handle array fields", () => {
      const schema = import_zod.z.object({
        tags: import_zod.z.array(import_zod.z.string()).describe("List of tags")
      });
      const result = (0, import_utils.oaiParams)(schema);
      (0, import_vitest.expect)(result).toMatchSnapshot();
    });
    (0, import_vitest.it)("should handle array of enums", () => {
      const schema = import_zod.z.object({
        colors: import_zod.z.array(import_zod.z.enum(["red", "blue", "green"])).describe("List of colors")
      });
      const result = (0, import_utils.oaiParams)(schema);
      (0, import_vitest.expect)(result).toMatchSnapshot();
    });
    (0, import_vitest.it)("should handle optional fields", () => {
      const schema = import_zod.z.object({
        name: import_zod.z.string().describe("The user name"),
        age: import_zod.z.number().optional().describe("The user age")
      });
      const result = (0, import_utils.oaiParams)(schema);
      (0, import_vitest.expect)(result).toMatchSnapshot();
    });
    (0, import_vitest.it)("should handle fields without descriptions", () => {
      const schema = import_zod.z.object({
        name: import_zod.z.string(),
        age: import_zod.z.number()
      });
      const result = (0, import_utils.oaiParams)(schema);
      (0, import_vitest.expect)(result).toMatchSnapshot();
    });
  });
  (0, import_vitest.describe)("tool", () => {
    (0, import_vitest.it)("should create and execute a basic core tool", async () => {
      const getWeather = (0, import_tool_context.tool)({
        name: "getWeather",
        description: "Get the weather for a given location",
        parameters: import_zod.z.object({
          location: import_zod.z.string()
        }),
        execute: async ({ location }, { ctx }) => {
          return `The weather in ${location} is sunny, ${ctx.userData.name}`;
        }
      });
      const result = await getWeather.execute(
        { location: "San Francisco" },
        (0, import_utils.createToolOptions)("123", { name: "John" })
      );
      (0, import_vitest.expect)(result).toBe("The weather in San Francisco is sunny, John");
    });
    (0, import_vitest.it)("defaults to allow duplicate calls and no flags", () => {
      const testFunction = (0, import_tool_context.tool)({
        name: "defaultDuplicatePolicy",
        description: "Test default duplicate policy",
        execute: async () => "ok"
      });
      (0, import_vitest.expect)(testFunction.onDuplicate).toBe("allow");
      (0, import_vitest.expect)(testFunction.flags).toBe(import_tool_context.ToolFlag.NONE);
    });
    (0, import_vitest.it)("stores cancellable flag and duplicate policy", () => {
      const testFunction = (0, import_tool_context.tool)({
        name: "cancellableDuplicatePolicy",
        description: "Test duplicate policy",
        execute: async () => "ok",
        flags: import_tool_context.ToolFlag.CANCELLABLE,
        onDuplicate: "replace"
      });
      (0, import_vitest.expect)(testFunction.onDuplicate).toBe("replace");
      (0, import_vitest.expect)(testFunction.flags & import_tool_context.ToolFlag.CANCELLABLE).toBeTruthy();
    });
    (0, import_vitest.it)("injects and strips confirm duplicate parameter for zod schemas", async () => {
      let receivedArgs;
      const testFunction = (0, import_tool_context.tool)({
        name: "confirmDuplicateZod",
        description: "Test confirm duplicate with zod",
        parameters: import_zod.z.object({
          query: import_zod.z.string()
        }),
        onDuplicate: "confirm",
        execute: async (args) => {
          receivedArgs = args;
          return "ok";
        }
      });
      const params = (0, import_utils.oaiParams)(testFunction.parameters);
      (0, import_vitest.expect)(params.properties).toHaveProperty(import_tool_context.CONFIRM_DUPLICATE_PARAM);
      (0, import_vitest.expect)(params.required).toContain(import_tool_context.CONFIRM_DUPLICATE_PARAM);
      const result = await testFunction.execute(
        { query: "flights", [import_tool_context.CONFIRM_DUPLICATE_PARAM]: true },
        (0, import_utils.createToolOptions)("confirm-zod")
      );
      (0, import_vitest.expect)(result).toBe("ok");
      (0, import_vitest.expect)(receivedArgs).toEqual({ query: "flights" });
    });
    (0, import_vitest.it)("injects and strips confirm duplicate parameter for raw JSON schemas", async () => {
      let receivedArgs;
      const testFunction = (0, import_tool_context.tool)({
        name: "confirmDuplicateRaw",
        description: "Test confirm duplicate with raw schema",
        parameters: {
          type: "object",
          properties: {
            query: { type: "string" }
          },
          required: ["query"]
        },
        onDuplicate: "confirm",
        execute: async (args) => {
          receivedArgs = args;
          return "ok";
        }
      });
      (0, import_vitest.expect)(testFunction.parameters).toMatchObject({
        properties: {
          [import_tool_context.CONFIRM_DUPLICATE_PARAM]: {
            type: ["boolean", "null"]
          }
        }
      });
      (0, import_vitest.expect)(testFunction.parameters.required).toContain(
        import_tool_context.CONFIRM_DUPLICATE_PARAM
      );
      const result = await testFunction.execute(
        { query: "flights", [import_tool_context.CONFIRM_DUPLICATE_PARAM]: true },
        (0, import_utils.createToolOptions)("confirm-raw")
      );
      (0, import_vitest.expect)(result).toBe("ok");
      (0, import_vitest.expect)(receivedArgs).toEqual({ query: "flights" });
    });
    (0, import_vitest.it)("should properly type a callable function", async () => {
      const testFunction = (0, import_tool_context.tool)({
        name: "testFunction",
        description: "Test function",
        parameters: import_zod.z.object({
          name: import_zod.z.string().describe("The user name"),
          age: import_zod.z.number().describe("The user age")
        }),
        execute: async (args) => {
          return `${args.name} is ${args.age} years old`;
        }
      });
      const result = await testFunction.execute(
        { name: "John", age: 30 },
        (0, import_utils.createToolOptions)("123")
      );
      (0, import_vitest.expect)(result).toBe("John is 30 years old");
    });
    (0, import_vitest.it)("should handle async execution", async () => {
      const testFunction = (0, import_tool_context.tool)({
        name: "asyncTestFunction",
        description: "Async test function",
        parameters: import_zod.z.object({
          delay: import_zod.z.number().describe("Delay in milliseconds")
        }),
        execute: async (args) => {
          await new Promise((resolve) => setTimeout(resolve, args.delay));
          return args.delay;
        }
      });
      const start = Date.now();
      const result = await testFunction.execute({ delay: 100 }, (0, import_utils.createToolOptions)("123"));
      const duration = Date.now() - start;
      (0, import_vitest.expect)(result).toBe(100);
      (0, import_vitest.expect)(duration).toBeGreaterThanOrEqual(95);
    });
    (0, import_vitest.describe)("nested array support", () => {
      (0, import_vitest.it)("should handle nested array fields", () => {
        const schema = import_zod.z.object({
          items: import_zod.z.array(
            import_zod.z.object({
              name: import_zod.z.string().describe("the item name"),
              modifiers: import_zod.z.array(
                import_zod.z.object({
                  modifier_name: import_zod.z.string(),
                  modifier_value: import_zod.z.string()
                })
              ).describe("list of the modifiers applied on this item, such as size")
            })
          )
        });
        const result = (0, import_utils.oaiParams)(schema);
        (0, import_vitest.expect)(result).toMatchSnapshot();
      });
    });
    (0, import_vitest.describe)("optional parameters", () => {
      (0, import_vitest.it)("should create a tool without parameters", async () => {
        const simpleAction = (0, import_tool_context.tool)({
          name: "simpleAction",
          description: "Perform a simple action",
          execute: async () => {
            return "Action performed";
          }
        });
        (0, import_vitest.expect)(simpleAction.type).toBe("function");
        (0, import_vitest.expect)(simpleAction.description).toBe("Perform a simple action");
        (0, import_vitest.expect)(simpleAction.parameters).toBeDefined();
        (0, import_vitest.expect)(simpleAction.parameters._def.typeName).toBe("ZodObject");
        const result = await simpleAction.execute({}, (0, import_utils.createToolOptions)("123"));
        (0, import_vitest.expect)(result).toBe("Action performed");
      });
      (0, import_vitest.it)("should support .optional() fields in tool parameters", async () => {
        const weatherTool = (0, import_tool_context.tool)({
          name: "weatherTool",
          description: "Get weather information",
          parameters: import_zod.z.object({
            location: import_zod.z.string().describe("The city or location").optional(),
            units: import_zod.z.enum(["celsius", "fahrenheit"]).describe("Temperature units").optional()
          }),
          execute: async ({ location, units }) => {
            const loc = location ?? "Unknown";
            const unit = units ?? "celsius";
            return `Weather in ${loc} (${unit})`;
          }
        });
        (0, import_vitest.expect)(weatherTool.type).toBe("function");
        (0, import_vitest.expect)(weatherTool.description).toBe("Get weather information");
        const result1 = await weatherTool.execute(
          { location: "London", units: "celsius" },
          (0, import_utils.createToolOptions)("123")
        );
        (0, import_vitest.expect)(result1).toBe("Weather in London (celsius)");
        const result2 = await weatherTool.execute({}, (0, import_utils.createToolOptions)("123"));
        (0, import_vitest.expect)(result2).toBe("Weather in Unknown (celsius)");
        const result3 = await weatherTool.execute({ location: "Paris" }, (0, import_utils.createToolOptions)("123"));
        (0, import_vitest.expect)(result3).toBe("Weather in Paris (celsius)");
      });
      (0, import_vitest.it)("should handle tools with context but no parameters", async () => {
        const greetUser = (0, import_tool_context.tool)({
          name: "greetUser",
          description: "Greet the current user",
          execute: async (_, { ctx }) => {
            return `Hello, ${ctx.userData.username}!`;
          }
        });
        const result = await greetUser.execute({}, (0, import_utils.createToolOptions)("123", { username: "Alice" }));
        (0, import_vitest.expect)(result).toBe("Hello, Alice!");
      });
      (0, import_vitest.it)("should create a tool that accesses tool call id without parameters", async () => {
        const getCallId = (0, import_tool_context.tool)({
          name: "getCallId",
          description: "Get the current tool call ID",
          execute: async (_, { toolCallId }) => {
            return `Tool call ID: ${toolCallId}`;
          }
        });
        const result = await getCallId.execute({}, (0, import_utils.createToolOptions)("test-id-456"));
        (0, import_vitest.expect)(result).toBe("Tool call ID: test-id-456");
      });
    });
    (0, import_vitest.describe)("Zod v3 and v4 compatibility", () => {
      (0, import_vitest.it)("should work with Zod v3 schemas", async () => {
        const v3Tool = (0, import_tool_context.tool)({
          name: "v3Tool",
          description: "A tool using Zod v3 schema",
          parameters: z3.object({
            name: z3.string(),
            count: z3.number()
          }),
          execute: async ({ name, count }) => {
            return `${name}: ${count}`;
          }
        });
        const result = await v3Tool.execute(
          { name: "Test", count: 42 },
          (0, import_utils.createToolOptions)("v3-test")
        );
        (0, import_vitest.expect)(result).toBe("Test: 42");
      });
      (0, import_vitest.it)("should work with Zod v4 schemas", async () => {
        const v4Tool = (0, import_tool_context.tool)({
          name: "v4Tool",
          description: "A tool using Zod v4 schema",
          parameters: z4.object({
            name: z4.string(),
            count: z4.number()
          }),
          execute: async ({ name, count }) => {
            return `${name}: ${count}`;
          }
        });
        const result = await v4Tool.execute(
          { name: "Test", count: 42 },
          (0, import_utils.createToolOptions)("v4-test")
        );
        (0, import_vitest.expect)(result).toBe("Test: 42");
      });
      (0, import_vitest.it)("should handle v4 schemas with optional fields", async () => {
        const v4Tool = (0, import_tool_context.tool)({
          name: "v4OptionalTool",
          description: "Tool with optional field using v4",
          parameters: z4.object({
            required: z4.string(),
            optional: z4.string().optional()
          }),
          execute: async ({ required, optional }) => {
            return optional ? `${required} - ${optional}` : required;
          }
        });
        const result1 = await v4Tool.execute({ required: "Hello" }, (0, import_utils.createToolOptions)("test-1"));
        (0, import_vitest.expect)(result1).toBe("Hello");
        const result2 = await v4Tool.execute(
          { required: "Hello", optional: "World" },
          (0, import_utils.createToolOptions)("test-2")
        );
        (0, import_vitest.expect)(result2).toBe("Hello - World");
      });
      (0, import_vitest.it)("should handle v4 enum schemas", async () => {
        const v4Tool = (0, import_tool_context.tool)({
          name: "v4EnumTool",
          description: "Tool with enum using v4",
          parameters: z4.object({
            color: z4.enum(["red", "blue", "green"])
          }),
          execute: async ({ color }) => {
            return `Selected color: ${color}`;
          }
        });
        const result = await v4Tool.execute({ color: "blue" }, (0, import_utils.createToolOptions)("test-enum"));
        (0, import_vitest.expect)(result).toBe("Selected color: blue");
      });
      (0, import_vitest.it)("should handle v4 array schemas", async () => {
        const v4Tool = (0, import_tool_context.tool)({
          name: "v4ArrayTool",
          description: "Tool with array using v4",
          parameters: z4.object({
            tags: z4.array(z4.string())
          }),
          execute: async ({ tags }) => {
            return `Tags: ${tags.join(", ")}`;
          }
        });
        const result = await v4Tool.execute(
          { tags: ["nodejs", "typescript", "testing"] },
          (0, import_utils.createToolOptions)("test-array")
        );
        (0, import_vitest.expect)(result).toBe("Tags: nodejs, typescript, testing");
      });
      (0, import_vitest.it)("should handle v4 nested object schemas", async () => {
        const v4Tool = (0, import_tool_context.tool)({
          name: "v4NestedTool",
          description: "Tool with nested object using v4",
          parameters: z4.object({
            user: z4.object({
              name: z4.string(),
              email: z4.string()
            })
          }),
          execute: async ({ user }) => {
            return `${user.name} (${user.email})`;
          }
        });
        const result = await v4Tool.execute(
          { user: { name: "John Doe", email: "john@example.com" } },
          (0, import_utils.createToolOptions)("test-nested")
        );
        (0, import_vitest.expect)(result).toBe("John Doe (john@example.com)");
      });
    });
    (0, import_vitest.describe)("oaiParams with v4 schemas", () => {
      (0, import_vitest.it)("should convert v4 basic object schema", () => {
        const schema = z4.object({
          name: z4.string().describe("User name"),
          age: z4.number().describe("User age")
        });
        const result = (0, import_utils.oaiParams)(schema);
        (0, import_vitest.expect)(result.type).toBe("object");
        (0, import_vitest.expect)(result.properties).toHaveProperty("name");
        (0, import_vitest.expect)(result.properties).toHaveProperty("age");
        (0, import_vitest.expect)(result.required).toContain("name");
        (0, import_vitest.expect)(result.required).toContain("age");
      });
      (0, import_vitest.it)("should handle v4 optional fields", () => {
        const schema = z4.object({
          required: z4.string(),
          optional: z4.string().optional()
        });
        const result = (0, import_utils.oaiParams)(schema);
        (0, import_vitest.expect)(result.required).toContain("required");
        (0, import_vitest.expect)(result.required).not.toContain("optional");
      });
      (0, import_vitest.it)("should handle v4 enum fields", () => {
        var _a;
        const schema = z4.object({
          status: z4.enum(["pending", "approved", "rejected"])
        });
        const result = (0, import_utils.oaiParams)(schema);
        const properties = result.properties;
        (0, import_vitest.expect)((_a = properties.status) == null ? void 0 : _a.enum).toEqual(["pending", "approved", "rejected"]);
      });
      (0, import_vitest.it)("should handle v4 array fields", () => {
        const schema = z4.object({
          items: z4.array(z4.string())
        });
        const result = (0, import_utils.oaiParams)(schema);
        const properties = result.properties;
        (0, import_vitest.expect)(
          properties.items && typeof properties.items === "object" ? properties.items.type : void 0
        ).toBe("array");
        (0, import_vitest.expect)(
          properties.items && properties.items.items && typeof properties.items.items === "object" ? properties.items.items.type : void 0
        ).toBe("string");
      });
    });
  });
});
(0, import_vitest.describe)("tool() name requirement", () => {
  (0, import_vitest.it)("creates an anonymous function tool when name is missing", () => {
    const t = (0, import_tool_context.tool)({
      description: "no name",
      execute: async () => "x"
    });
    (0, import_vitest.expect)(t.description).toBe("no name");
    (0, import_vitest.expect)("name" in t).toBe(false);
    (0, import_vitest.expect)("id" in t).toBe(false);
  });
  (0, import_vitest.it)("throws when name is empty", () => {
    (0, import_vitest.expect)(
      () => (0, import_tool_context.tool)({
        name: "",
        description: "empty name",
        execute: async () => "x"
      })
    ).toThrow("requires a non-empty name");
  });
  (0, import_vitest.it)("stores the name on the returned function tool", () => {
    const t = (0, import_tool_context.tool)({
      name: "doStuff",
      description: "d",
      execute: async () => "x"
    });
    (0, import_vitest.expect)(t.name).toBe("doStuff");
  });
  (0, import_vitest.it)("exposes id mirroring the function tool name", () => {
    const t = (0, import_tool_context.tool)({
      name: "doStuff",
      description: "d",
      execute: async () => "x"
    });
    (0, import_vitest.expect)(t.id).toBe("doStuff");
    (0, import_vitest.expect)(t.id).toBe(t.name);
  });
});
class TestProviderTool extends import_tool_context.ProviderTool {
}
(0, import_vitest.describe)("ToolContext", () => {
  const makeFn = (name) => (0, import_tool_context.tool)({
    name,
    description: `${name} tool`,
    execute: async () => name
  });
  (0, import_vitest.it)("empty() returns an empty context", () => {
    const ctx = import_tool_context.ToolContext.empty();
    (0, import_vitest.expect)(ctx.functionTools).toEqual({});
    (0, import_vitest.expect)(ctx.providerTools).toEqual([]);
    (0, import_vitest.expect)(ctx.toolsets).toEqual([]);
    (0, import_vitest.expect)(ctx.flatten()).toEqual([]);
  });
  (0, import_vitest.it)("indexes function tools by name and supports lookup", () => {
    const a = makeFn("a");
    const b = makeFn("b");
    const ctx = new import_tool_context.ToolContext([a, b]);
    (0, import_vitest.expect)(ctx.functionTools).toEqual({ a, b });
    (0, import_vitest.expect)(ctx.getFunctionTool("a")).toBe(a);
    (0, import_vitest.expect)(ctx.getFunctionTool("b")).toBe(b);
    (0, import_vitest.expect)(ctx.getFunctionTool("missing")).toBeUndefined();
  });
  (0, import_vitest.it)("throws on duplicate function names with different instances", () => {
    const a1 = makeFn("a");
    const a2 = makeFn("a");
    (0, import_vitest.expect)(() => new import_tool_context.ToolContext([a1, a2])).toThrow("duplicate function name: a");
  });
  (0, import_vitest.it)("silently skips the same function tool instance listed multiple times", () => {
    const a = makeFn("a");
    const ctx = new import_tool_context.ToolContext([a, a]);
    (0, import_vitest.expect)(ctx.getFunctionTool("a")).toBe(a);
    (0, import_vitest.expect)(Object.keys(ctx.functionTools)).toEqual(["a"]);
  });
  (0, import_vitest.it)("separates provider tools from function tools", () => {
    const fnA = makeFn("a");
    const provider = new TestProviderTool({ id: "code" });
    const ctx = new import_tool_context.ToolContext([fnA, provider]);
    (0, import_vitest.expect)(ctx.functionTools).toEqual({ a: fnA });
    (0, import_vitest.expect)(ctx.providerTools).toEqual([provider]);
    (0, import_vitest.expect)(ctx.flatten()).toEqual([fnA, provider]);
  });
  (0, import_vitest.it)("updateTools replaces the entire context", () => {
    const a = makeFn("a");
    const b = makeFn("b");
    const ctx = new import_tool_context.ToolContext([a]);
    ctx.updateTools([b]);
    (0, import_vitest.expect)(ctx.getFunctionTool("a")).toBeUndefined();
    (0, import_vitest.expect)(ctx.getFunctionTool("b")).toBe(b);
  });
  (0, import_vitest.it)("copy() yields an independent context with the same tools", () => {
    const a = makeFn("a");
    const ctx = new import_tool_context.ToolContext([a]);
    const dup = ctx.copy();
    (0, import_vitest.expect)(dup.getFunctionTool("a")).toBe(a);
    dup.updateTools([]);
    (0, import_vitest.expect)(ctx.getFunctionTool("a")).toBe(a);
    (0, import_vitest.expect)(dup.getFunctionTool("a")).toBeUndefined();
  });
  (0, import_vitest.it)("equals() compares function tool maps and provider lists by identity", () => {
    const a = makeFn("a");
    const b = makeFn("b");
    const c = makeFn("c");
    (0, import_vitest.expect)(new import_tool_context.ToolContext([a, b]).equals(new import_tool_context.ToolContext([a, b]))).toBe(true);
    (0, import_vitest.expect)(new import_tool_context.ToolContext([a, b]).equals(new import_tool_context.ToolContext([a]))).toBe(false);
    (0, import_vitest.expect)(new import_tool_context.ToolContext([a, b]).equals(new import_tool_context.ToolContext([a, c]))).toBe(false);
  });
  (0, import_vitest.it)("equals() is reflexive", () => {
    const a = makeFn("a");
    const provider = new TestProviderTool({ id: "code" });
    const ctx = new import_tool_context.ToolContext([a, provider]);
    (0, import_vitest.expect)(ctx.equals(ctx)).toBe(true);
  });
  (0, import_vitest.it)("equals() treats provider tool order as insignificant", () => {
    const a = makeFn("a");
    const p1 = new TestProviderTool({ id: "code" });
    const p2 = new TestProviderTool({ id: "browser" });
    (0, import_vitest.expect)(new import_tool_context.ToolContext([a, p1, p2]).equals(new import_tool_context.ToolContext([a, p2, p1]))).toBe(true);
  });
  (0, import_vitest.it)("equals() supports contexts with only provider tools", () => {
    const p1 = new TestProviderTool({ id: "code" });
    const p2 = new TestProviderTool({ id: "browser" });
    (0, import_vitest.expect)(new import_tool_context.ToolContext([p1, p2]).equals(new import_tool_context.ToolContext([p1, p2]))).toBe(true);
    const p3 = new TestProviderTool({ id: "code" });
    (0, import_vitest.expect)(new import_tool_context.ToolContext([p1]).equals(new import_tool_context.ToolContext([p3]))).toBe(false);
  });
  (0, import_vitest.it)("hasTool() matches function tools by name and provider tools by id", () => {
    const a = makeFn("a");
    const provider = new TestProviderTool({ id: "code_runner" });
    const ctx = new import_tool_context.ToolContext([a, provider]);
    (0, import_vitest.expect)(ctx.hasTool("a")).toBe(true);
    (0, import_vitest.expect)(ctx.hasTool("code_runner")).toBe(true);
    (0, import_vitest.expect)(ctx.hasTool("missing")).toBe(false);
  });
  (0, import_vitest.it)("flatten() returns function tools in insertion order followed by provider tools", () => {
    const a = makeFn("a");
    const b = makeFn("b");
    const provider = new TestProviderTool({ id: "code" });
    const ctx = new import_tool_context.ToolContext([b, provider, a]);
    (0, import_vitest.expect)(ctx.flatten()).toEqual([b, a, provider]);
  });
});
(0, import_vitest.describe)("Toolset", () => {
  const makeFn = (name) => (0, import_tool_context.tool)({
    name,
    description: `${name} tool`,
    execute: async () => name
  });
  (0, import_vitest.it)("exposes its id and the tools it was constructed with", () => {
    const a = makeFn("a");
    const b = makeFn("b");
    const ts = new import_tool_context.Toolset({ id: "set1", tools: [a, b] });
    (0, import_vitest.expect)(ts.id).toBe("set1");
    (0, import_vitest.expect)(ts.tools).toEqual([a, b]);
  });
  const fakeToolsetContext = (updateTools = () => {
  }) => ({ updateTools });
  (0, import_vitest.it)("default setup and aclose are no-ops", async () => {
    const ts = new import_tool_context.Toolset({ id: "noop", tools: [] });
    await (0, import_vitest.expect)(ts.setup(fakeToolsetContext())).resolves.toBeUndefined();
    await (0, import_vitest.expect)(ts.aclose()).resolves.toBeUndefined();
  });
  (0, import_vitest.it)("lets subclasses override lifecycle hooks", async () => {
    const events = [];
    class Recording extends import_tool_context.Toolset {
      async setup(_ctx) {
        events.push(`setup:${this.id}`);
      }
      async aclose() {
        events.push(`close:${this.id}`);
      }
    }
    const ts = new Recording({ id: "rec", tools: [] });
    await ts.setup(fakeToolsetContext());
    await ts.aclose();
    (0, import_vitest.expect)(events).toEqual(["setup:rec", "close:rec"]);
  });
  (0, import_vitest.it)("Toolset.create() resolves a static tools list eagerly and composes aclose", async () => {
    const a = makeFn("a");
    const events = [];
    const ts = import_tool_context.Toolset.create({
      id: "composed",
      tools: [a],
      aclose: async () => {
        events.push("close");
      }
    });
    (0, import_vitest.expect)(ts).toBeInstanceOf(import_tool_context.Toolset);
    (0, import_vitest.expect)(ts.id).toBe("composed");
    (0, import_vitest.expect)(ts.tools).toEqual([a]);
    await ts.setup(fakeToolsetContext());
    await ts.aclose();
    (0, import_vitest.expect)(events).toEqual(["close"]);
  });
  (0, import_vitest.it)("Toolset.create() defaults aclose to a no-op when omitted", async () => {
    const ts = import_tool_context.Toolset.create({ id: "bare", tools: [] });
    await (0, import_vitest.expect)(ts.setup(fakeToolsetContext())).resolves.toBeUndefined();
    await (0, import_vitest.expect)(ts.aclose()).resolves.toBeUndefined();
  });
  (0, import_vitest.it)("lets setup push tools after activation via ctx.updateTools", async () => {
    const a = makeFn("a");
    const b = makeFn("b");
    let push;
    const ts = import_tool_context.Toolset.create({
      id: "mcp",
      setup: async ({ updateTools }) => {
        push = updateTools;
      },
      tools: []
    });
    await ts.setup(fakeToolsetContext((tools) => ts._setTools(tools)));
    (0, import_vitest.expect)(ts.tools).toEqual([]);
    push([a, b]);
    (0, import_vitest.expect)(ts.tools).toEqual([a, b]);
  });
  (0, import_vitest.it)("is flattened into a ToolContext: function tools merged, toolset tracked", () => {
    const a = makeFn("a");
    const b = makeFn("b");
    const ts = new import_tool_context.Toolset({ id: "set", tools: [a, b] });
    const direct = makeFn("direct");
    const ctx = new import_tool_context.ToolContext([direct, ts]);
    (0, import_vitest.expect)(Object.keys(ctx.functionTools).sort()).toEqual(["a", "b", "direct"]);
    (0, import_vitest.expect)(ctx.toolsets).toEqual([ts]);
  });
  (0, import_vitest.it)("throws when a Toolset contributes a duplicate function name", () => {
    const a1 = makeFn("a");
    const a2 = makeFn("a");
    const ts = new import_tool_context.Toolset({ id: "collides", tools: [a2] });
    (0, import_vitest.expect)(() => new import_tool_context.ToolContext([a1, ts])).toThrow(/duplicate function name: a/);
  });
  (0, import_vitest.it)("equals() compares toolsets as identity sets, not by order", () => {
    const ts1 = new import_tool_context.Toolset({ id: "one", tools: [] });
    const ts2 = new import_tool_context.Toolset({ id: "two", tools: [] });
    (0, import_vitest.expect)(new import_tool_context.ToolContext([ts1, ts2]).equals(new import_tool_context.ToolContext([ts2, ts1]))).toBe(true);
    const ts3 = new import_tool_context.Toolset({ id: "three", tools: [] });
    (0, import_vitest.expect)(new import_tool_context.ToolContext([ts1, ts2]).equals(new import_tool_context.ToolContext([ts1, ts3]))).toBe(false);
    (0, import_vitest.expect)(new import_tool_context.ToolContext([ts1]).equals(new import_tool_context.ToolContext([ts1, ts2]))).toBe(false);
  });
});
//# sourceMappingURL=tool_context.test.cjs.map