UNPKG

@inngest/agent-kit

Version:

AgentKit is a framework for creating and orchestrating AI agents and AI workflows

2,139 lines 66.2 kB
"use strict";
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __typeError = (msg) => {
  throw TypeError(msg);
};
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
  for (var prop in b || (b = {}))
    if (__hasOwnProp.call(b, prop))
      __defNormalProp(a, prop, b[prop]);
  if (__getOwnPropSymbols)
    for (var prop of __getOwnPropSymbols(b)) {
      if (__propIsEnum.call(b, prop))
        __defNormalProp(a, prop, b[prop]);
    }
  return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
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 __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);

// src/index.ts
var index_exports = {};
__export(index_exports, {
  Agent: () => Agent,
  AgenticModel: () => AgenticModel,
  InferenceResult: () => InferenceResult,
  Network: () => Network,
  NetworkRun: () => NetworkRun,
  RoutingAgent: () => RoutingAgent,
  State: () => State,
  anthropic: () => import_ai8.anthropic,
  createAgent: () => createAgent,
  createAgenticModelFromAiAdapter: () => createAgenticModelFromAiAdapter,
  createNetwork: () => createNetwork,
  createRoutingAgent: () => createRoutingAgent,
  createTool: () => createTool,
  gemini: () => import_ai8.gemini,
  getDefaultRoutingAgent: () => getDefaultRoutingAgent,
  getInngestFnInput: () => getInngestFnInput,
  getStepTools: () => getStepTools,
  grok: () => import_ai8.grok,
  isInngestFn: () => isInngestFn,
  openai: () => import_ai8.openai,
  stringifyError: () => stringifyError
});
module.exports = __toCommonJS(index_exports);

// src/agent.ts
var import_ai7 = require("@inngest/ai");
var import_client = require("@modelcontextprotocol/sdk/client/index.js");
var import_sse = require("@modelcontextprotocol/sdk/client/sse.js");
var import_websocket = require("@modelcontextprotocol/sdk/client/websocket.js");
var import_transport = require("@modelcontextprotocol/sdk/shared/transport.js");
var import_types = require("@modelcontextprotocol/sdk/types.js");
var import_eventsource = require("eventsource");
var import_inngest3 = require("inngest");
var import_InngestFunction2 = require("inngest/components/InngestFunction");
var import_errors = require("inngest/helpers/errors");
var import_types2 = require("inngest/types");

// src/jsonSchema.ts
var import_zod = require("zod");
var JSONSchemaToZod = class {
  /**
   * Converts a JSON schema to a Zod schema.
   *
   * @param {JSONSchema} schema - The JSON schema.
   * @returns {ZodSchema} - The Zod schema.
   */
  static convert(schema) {
    return this.parseSchema(schema);
  }
  /**
   * Checks if data matches a condition schema.
   *
   * @param {JSONValue} data - The data to check.
   * @param {JSONSchema} condition - The condition schema.
   * @returns {boolean} - Whether the data matches the condition.
   */
  static matchesCondition(data, condition) {
    if (!condition.properties) {
      return true;
    }
    if (typeof data !== "object" || data === null || Array.isArray(data)) {
      return false;
    }
    const objectData = data;
    for (const [key, propCondition] of Object.entries(condition.properties)) {
      if (!(key in objectData)) {
        if ("const" in propCondition) {
          return false;
        }
        continue;
      }
      const value = objectData[key];
      if ("const" in propCondition && value !== propCondition["const"]) {
        return false;
      }
      if ("minimum" in propCondition && typeof value === "number" && value < propCondition["minimum"]) {
        return false;
      }
      if ("maximum" in propCondition && typeof value === "number" && value > propCondition["maximum"]) {
        return false;
      }
    }
    return true;
  }
  /**
   * Validates data against a conditional schema and adds issues to context if validation fails.
   *
   * @param {JSONValue} data - The data to validate.
   * @param {JSONSchema} schema - The conditional schema.
   * @param {z.RefinementCtx} ctx - The Zod refinement context.
   */
  static validateConditionalSchema(data, schema, ctx) {
    this.validateRequiredProperties(data, schema, ctx);
    this.validatePropertyPatterns(data, schema, ctx);
    this.validateNestedConditions(data, schema, ctx);
  }
  /**
   * Validates that all required properties are present in the data.
   *
   * @param {JSONValue} data - The data to validate.
   * @param {JSONSchema} schema - The schema containing required properties.
   * @param {z.RefinementCtx} ctx - The Zod refinement context.
   */
  static validateRequiredProperties(data, schema, ctx) {
    if (!schema.required) {
      return;
    }
    if (typeof data !== "object" || data === null) {
      for (const requiredProp of schema.required) {
        ctx.addIssue({
          code: import_zod.z.ZodIssueCode.custom,
          message: `Required property '${requiredProp}' is missing`,
          path: [requiredProp]
        });
      }
      return;
    }
    for (const requiredProp of schema.required) {
      if (!(requiredProp in data)) {
        ctx.addIssue({
          code: import_zod.z.ZodIssueCode.custom,
          message: `Required property '${requiredProp}' is missing`,
          path: [requiredProp]
        });
      }
    }
  }
  /**
   * Validates property patterns for string properties.
   *
   * @param {JSONValue} data - The data to validate.
   * @param {JSONSchema} schema - The schema containing property patterns.
   * @param {z.RefinementCtx} ctx - The Zod refinement context.
   */
  static validatePropertyPatterns(data, schema, ctx) {
    if (!schema.properties) {
      return;
    }
    if (typeof data !== "object" || data === null) {
      return;
    }
    if (Array.isArray(data)) {
      return;
    }
    const objectData = data;
    for (const [key, propSchema] of Object.entries(schema.properties)) {
      if (!(key in objectData)) {
        continue;
      }
      const value = objectData[key];
      if (propSchema["pattern"] && typeof value === "string") {
        const regex = new RegExp(propSchema["pattern"]);
        if (!regex.test(value)) {
          ctx.addIssue({
            code: import_zod.z.ZodIssueCode.custom,
            message: `String '${value}' does not match pattern '${propSchema["pattern"]}'`,
            path: [key]
          });
        }
      }
    }
  }
  /**
   * Validates nested if-then-else conditions.
   *
   * @param {JSONValue} data - The data to validate.
   * @param {JSONSchema} schema - The schema containing if-then-else conditions.
   * @param {z.RefinementCtx} ctx - The Zod refinement context.
   */
  static validateNestedConditions(data, schema, ctx) {
    if (!schema["if"] || !schema["then"]) {
      return;
    }
    const matchesIf = this.matchesCondition(data, schema["if"]);
    if (matchesIf) {
      this.validateConditionalSchema(data, schema["then"], ctx);
    } else if (schema["else"]) {
      this.validateConditionalSchema(data, schema["else"], ctx);
    }
  }
  /**
   * Parses a JSON schema and returns the corresponding Zod schema.
   * This is the main entry point for schema conversion.
   *
   * @param {JSONSchema} schema - The JSON schema.
   * @returns {ZodTypeAny} - The ZodTypeAny schema.
   */
  static parseSchema(schema) {
    if (Array.isArray(schema.type)) {
      return this.handleTypeArray(schema);
    }
    if (schema.oneOf || schema.anyOf || schema.allOf) {
      return this.parseCombinator(schema);
    }
    if (schema["if"] && schema["then"]) {
      return this.parseObject(schema);
    }
    if (schema.properties && (!schema.type || schema.type === "object")) {
      return this.parseObject(schema);
    }
    return this.handleSingleType(schema);
  }
  /**
   * Handles schemas with an array of types.
   *
   * @param {JSONSchema} schema - The JSON schema with type array.
   * @returns {ZodTypeAny} - The ZodTypeAny schema.
   */
  static handleTypeArray(schema) {
    if (!Array.isArray(schema.type)) {
      throw new Error("Expected schema.type to be an array");
    }
    if (schema.type.includes("null")) {
      return this.handleNullableType(schema);
    }
    return this.createUnionFromTypes(schema.type, schema);
  }
  /**
   * Handles nullable types by creating a nullable schema.
   *
   * @param {JSONSchema} schema - The JSON schema with nullable type.
   * @returns {ZodTypeAny} - The nullable Zod schema.
   */
  static handleNullableType(schema) {
    if (!Array.isArray(schema.type)) {
      throw new Error("Expected schema.type to be an array");
    }
    const nonNullSchema = __spreadValues({}, schema);
    nonNullSchema.type = schema.type.filter((t) => t !== "null");
    if (nonNullSchema.type.length === 1) {
      const singleTypeSchema = this.handleSingleType(__spreadProps(__spreadValues({}, schema), {
        type: nonNullSchema.type[0]
      }));
      return singleTypeSchema.nullable();
    }
    const unionSchema = this.parseSchema(nonNullSchema);
    return unionSchema.nullable();
  }
  /**
   * Creates a union type from an array of types.
   *
   * @param {string[]} types - Array of type strings.
   * @param {JSONSchema} baseSchema - The base schema to apply to each type.
   * @returns {ZodTypeAny} - The union Zod schema.
   */
  static createUnionFromTypes(types, baseSchema) {
    const schemas = types.map((type) => {
      const singleTypeSchema = __spreadProps(__spreadValues({}, baseSchema), { type });
      return this.parseSchema(singleTypeSchema);
    });
    return import_zod.z.union(schemas);
  }
  /**
   * Handles schemas with a single type.
   *
   * @param {JSONSchema} schema - The JSON schema with single type.
   * @returns {ZodTypeAny} - The ZodTypeAny schema.
   */
  static handleSingleType(schema) {
    if (schema.type === void 0) {
      if (schema.oneOf || schema.anyOf || schema.allOf) {
        return this.parseCombinator(schema);
      }
      if (schema.properties) {
        return this.parseObject(schema);
      }
      return import_zod.z.any();
    }
    switch (schema.type) {
      case "string":
        return this.parseString(schema);
      case "number":
      case "integer":
        return this.parseNumberSchema(schema);
      case "boolean":
        return import_zod.z.boolean();
      case "array":
        return this.parseArray(schema);
      case "object":
        return this.parseObject(schema);
      default:
        throw new Error("Unsupported schema type");
    }
  }
  /**
   * Parses a number schema.
   *
   * @param {JSONSchema} schema - The JSON schema for a number.
   * @returns {ZodTypeAny} - The ZodTypeAny schema.
   */
  static parseNumberSchema(schema) {
    const numberSchema = import_zod.z.number();
    let result = numberSchema;
    result = this.applyNumberBounds(numberSchema, schema);
    result = this.applyNumberMultipleOf(numberSchema, schema);
    result = this.applyNumberEnum(numberSchema, schema);
    result = this.applyIntegerConstraint(numberSchema, schema);
    return result;
  }
  /**
   * Applies bounds validation to a number schema.
   *
   * @param {z.ZodNumber} numberSchema - The base number schema.
   * @param {JSONSchema} schema - The JSON schema with bounds.
   * @returns {z.ZodNumber} - The updated schema with bounds validation.
   */
  static applyNumberBounds(numberSchema, schema) {
    let result = numberSchema;
    if (schema["minimum"] !== void 0) {
      result = schema["exclusiveMinimum"] ? (
        // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
        result.gt(schema["minimum"])
      ) : (
        // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
        result.gte(schema["minimum"])
      );
    }
    if (schema["maximum"] !== void 0) {
      result = schema["exclusiveMaximum"] ? (
        // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
        result.lt(schema["maximum"])
      ) : (
        // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
        result.lte(schema["maximum"])
      );
    }
    return result;
  }
  /**
   * Applies multipleOf validation to a number schema.
   *
   * @param {z.ZodNumber} numberSchema - The base number schema.
   * @param {JSONSchema} schema - The JSON schema with multipleOf.
   * @returns {z.ZodNumber} - The updated schema with multipleOf validation.
   */
  static applyNumberMultipleOf(numberSchema, schema) {
    if (schema["multipleOf"] === void 0) {
      return numberSchema;
    }
    return numberSchema.refine((val) => val % schema["multipleOf"] === 0, {
      message: `Number must be a multiple of ${schema["multipleOf"]}`
    });
  }
  /**
   * Applies enum validation to a number schema.
   *
   * @param {z.ZodNumber} numberSchema - The base number schema.
   * @param {JSONSchema} schema - The JSON schema with enum.
   * @returns {z.ZodNumber} - The updated schema with enum validation.
   */
  static applyNumberEnum(numberSchema, schema) {
    if (!schema.enum) {
      return numberSchema;
    }
    const numberEnums = schema.enum.filter((val) => typeof val === "number");
    if (numberEnums.length === 0) {
      return numberSchema;
    }
    return numberSchema.refine((val) => numberEnums.includes(val), {
      message: `Number must be one of: ${numberEnums.join(", ")}`
    });
  }
  /**
   * Applies integer constraint to a number schema if needed.
   *
   * @param {z.ZodNumber} numberSchema - The base number schema.
   * @param {JSONSchema} schema - The JSON schema.
   * @returns {z.ZodNumber} - The updated schema with integer validation if needed.
   */
  static applyIntegerConstraint(numberSchema, schema) {
    if (schema.type !== "integer") {
      return numberSchema;
    }
    return numberSchema.refine((val) => Number.isInteger(val), {
      message: "Number must be an integer"
    });
  }
  /**
   * Parses a string schema.
   *
   * @param {JSONSchema} schema - The JSON schema for a string.
   * @returns {ZodTypeAny} - The ZodTypeAny schema.
   */
  static parseString(schema) {
    const stringSchema = import_zod.z.string();
    let result = stringSchema;
    if (schema.format) {
      return this.applyStringFormat(stringSchema, schema);
    } else {
      result = this.applyStringPattern(stringSchema, schema);
      result = this.applyStringLength(stringSchema, schema);
      result = this.applyStringEnum(stringSchema, schema);
    }
    return result;
  }
  /**
   * Applies format validation to a string schema.
   *
   * @param {z.ZodString} stringSchema - The base string schema.
   * @param {JSONSchema} schema - The JSON schema with format.
   * @returns {ZodTypeAny} - The updated schema with format validation.
   */
  static applyStringFormat(stringSchema, schema) {
    if (!schema.format) {
      return stringSchema;
    }
    switch (schema.format) {
      case "email":
        return stringSchema.email();
      case "date-time":
        return stringSchema.datetime();
      case "uri":
        return stringSchema.url();
      case "uuid":
        return stringSchema.uuid();
      case "date":
        return stringSchema.date();
      default:
        return stringSchema;
    }
  }
  /**
   * Applies pattern validation to a string schema.
   *
   * @param {z.ZodString} stringSchema - The base string schema.
   * @param {JSONSchema} schema - The JSON schema with pattern.
   * @returns {z.ZodString} - The updated schema with pattern validation.
   */
  static applyStringPattern(stringSchema, schema) {
    if (!schema["pattern"]) {
      return stringSchema;
    }
    const regex = new RegExp(schema["pattern"]);
    return stringSchema.regex(regex, {
      message: `String must match pattern: ${schema["pattern"]}`
    });
  }
  /**
   * Applies length constraints to a string schema.
   *
   * @param {z.ZodString} stringSchema - The base string schema.
   * @param {JSONSchema} schema - The JSON schema with length constraints.
   * @returns {z.ZodString} - The updated schema with length validation.
   */
  static applyStringLength(stringSchema, schema) {
    const result = stringSchema;
    if (schema["minLength"] !== void 0) {
      stringSchema = stringSchema.min(schema["minLength"]);
    }
    if (schema["maxLength"] !== void 0) {
      stringSchema = stringSchema.max(schema["maxLength"]);
    }
    return result;
  }
  /**
   * Applies enum validation to a string schema.
   *
   * @param {z.ZodString} stringSchema - The base string schema.
   * @param {JSONSchema} schema - The JSON schema with enum.
   * @returns {ZodTypeAny} - The updated schema with enum validation.
   */
  static applyStringEnum(stringSchema, schema) {
    var _a;
    if (!schema.enum) {
      return stringSchema;
    }
    return stringSchema.refine((val) => {
      var _a2;
      return (_a2 = schema.enum) == null ? void 0 : _a2.includes(val);
    }, {
      message: `Value must be one of: ${(_a = schema.enum) == null ? void 0 : _a.join(", ")}`
    });
  }
  /**
   * Parses a JSON schema of type array and returns the corresponding Zod schema.
   *
   * @param {JSONSchema} schema - The JSON schema.
   * @returns {ZodTypeAny} - The ZodTypeAny schema.
   */
  static parseArray(schema) {
    if (Array.isArray(schema.items)) {
      const tupleSchemas = schema.items.map((item) => this.parseSchema(item));
      return import_zod.z.union(tupleSchemas);
    }
    const itemSchema = schema.items ? this.parseSchema(schema.items) : import_zod.z.any();
    const arraySchema = import_zod.z.array(itemSchema);
    let result = arraySchema;
    result = this.applyArrayConstraints(arraySchema, schema);
    return result;
  }
  /**
   * Applies constraints to an array schema.
   *
   * @param {z.ZodArray<any>} arraySchema - The base array schema.
   * @param {JSONSchema} schema - The JSON schema with array constraints.
   * @returns {z.ZodTypeAny} - The updated array schema with constraints.
   */
  static applyArrayConstraints(arraySchema, schema) {
    if (schema["minItems"] !== void 0) {
      arraySchema = arraySchema.min(schema["minItems"]);
    }
    if (schema["maxItems"] !== void 0) {
      arraySchema = arraySchema.max(schema["maxItems"]);
    }
    if (schema["uniqueItems"]) {
      return arraySchema.refine(
        (items) => new Set(items).size === items.length,
        { message: "Array items must be unique" }
      );
    }
    return arraySchema;
  }
  /**
   * Parses an object schema.
   *
   * @param {JSONSchema} schema - The JSON schema for an object.
   * @returns {ZodTypeAny} - The ZodTypeAny schema.
   */
  static parseObject(schema) {
    if (schema["if"] && schema["then"]) {
      return this.parseConditional(schema);
    }
    const shape = {};
    this.processObjectProperties(schema, shape);
    return this.processAdditionalProperties(schema, import_zod.z.object(shape));
  }
  /**
   * Processes object properties and builds the shape object.
   *
   * @param {JSONSchema} schema - The JSON schema for an object.
   * @param {Record<string, ZodTypeAny>} shape - The shape object to populate.
   */
  static processObjectProperties(schema, shape) {
    const required = new Set(schema.required || []);
    if (!schema.properties) {
      return;
    }
    for (const [key, propSchema] of Object.entries(schema.properties)) {
      const zodSchema = this.parseSchema(propSchema);
      shape[key] = required.has(key) ? zodSchema : zodSchema.optional();
    }
  }
  /**
   * Processes additionalProperties configuration.
   *
   * @param {JSONSchema} schema - The JSON schema for an object.
   * @param {z.ZodObject<any, any>} objectSchema - The Zod object schema.
   * @returns {z.ZodObject<any, any>} - The updated Zod object schema.
   */
  static processAdditionalProperties(schema, objectSchema) {
    if (schema.additionalProperties === true) {
      return objectSchema.passthrough();
    } else if (schema.additionalProperties && typeof schema.additionalProperties === "object") {
      const additionalPropSchema = this.parseSchema(
        schema.additionalProperties
      );
      return objectSchema.catchall(additionalPropSchema);
    } else {
      return objectSchema.strict();
    }
  }
  /**
   * Parses a conditional schema with if-then-else.
   *
   * @param {JSONSchema} schema - The JSON schema with conditional validation.
   * @returns {ZodTypeAny} - The conditional Zod schema.
   */
  static parseConditional(schema) {
    const zodObject = this.createBaseObjectSchema(schema);
    const ifCondition = schema["if"];
    const thenSchema = schema["then"];
    const elseSchema = schema["else"];
    return zodObject.superRefine((data, ctx) => {
      const dataWithDefaults = this.applyDefaultValues(data, schema);
      if (this.matchesCondition(dataWithDefaults, ifCondition)) {
        this.validateConditionalSchema(dataWithDefaults, thenSchema, ctx);
      } else if (elseSchema) {
        this.validateConditionalSchema(dataWithDefaults, elseSchema, ctx);
      }
    });
  }
  /**
   * Creates a base object schema from the given JSON schema.
   *
   * @param {JSONSchema} schema - The JSON schema.
   * @returns {z.ZodObject<any, any>} - The base Zod object schema.
   */
  static createBaseObjectSchema(schema) {
    const shape = {};
    const required = new Set(schema.required || []);
    for (const [key, value] of Object.entries(schema.properties || {})) {
      const zodSchema = this.parseSchema(value);
      shape[key] = required.has(key) ? zodSchema : zodSchema.optional();
    }
    const zodObject = import_zod.z.object(shape);
    return this.processAdditionalProperties(schema, zodObject);
  }
  /**
   * Applies default values from schema properties to data object.
   *
   * @param {JSONValue} data - The original data object.
   * @param {JSONSchema} schema - The schema with default values.
   * @returns {JSONValue} - The data object with defaults applied.
   */
  static applyDefaultValues(data, schema) {
    if (typeof data !== "object" || data === null) {
      return data;
    }
    if (Array.isArray(data)) {
      return data;
    }
    const objectData = data;
    const dataWithDefaults = __spreadValues({}, objectData);
    if (!schema.properties) {
      return dataWithDefaults;
    }
    for (const [key, propSchema] of Object.entries(schema.properties)) {
      if (!(key in dataWithDefaults) && "default" in propSchema) {
        dataWithDefaults[key] = propSchema["default"];
      }
    }
    return dataWithDefaults;
  }
  /**
   * Parses a schema with combinators (oneOf, anyOf, allOf).
   * Delegates to the appropriate combinator parser based on which combinator is present.
   *
   * @param {JSONSchema} schema - The JSON schema with combinators.
   * @returns {ZodTypeAny} - The ZodTypeAny schema.
   */
  static parseCombinator(schema) {
    if (schema.oneOf) {
      return this.parseOneOf(schema.oneOf);
    }
    if (schema.anyOf) {
      return this.parseAnyOf(schema.anyOf);
    }
    if (schema.allOf) {
      return this.parseAllOf(schema.allOf);
    }
    throw new Error("Unsupported schema type");
  }
  /**
   * Parses a oneOf combinator schema.
   *
   * @param {JSONSchema[]} schemas - Array of JSON schemas in the oneOf.
   * @returns {ZodTypeAny} - The ZodTypeAny schema.
   */
  static parseOneOf(schemas) {
    return this.createUnionFromSchemas(schemas);
  }
  /**
   * Parses an anyOf combinator schema.
   *
   * @param {JSONSchema[]} schemas - Array of JSON schemas in the anyOf.
   * @returns {ZodTypeAny} - The ZodTypeAny schema.
   */
  static parseAnyOf(schemas) {
    return this.createUnionFromSchemas(schemas);
  }
  /**
   * Creates a union from an array of schemas, handling special cases.
   *
   * @param {JSONSchema[]} schemas - Array of JSON schemas to create a union from.
   * @returns {ZodTypeAny} - The union Zod schema.
   */
  static createUnionFromSchemas(schemas) {
    if (schemas.length === 0) {
      return import_zod.z.any();
    }
    if (schemas.length === 1) {
      return this.parseSchema(schemas[0]);
    }
    const zodSchemas = [];
    for (const subSchema of schemas) {
      if (subSchema.type === "null") {
        zodSchemas.push(import_zod.z.null());
      } else {
        zodSchemas.push(this.parseSchema(subSchema));
      }
    }
    if (zodSchemas.length >= 2) {
      return import_zod.z.union(zodSchemas);
    } else if (zodSchemas.length === 1) {
      return zodSchemas[0];
    }
    return import_zod.z.any();
  }
  /**
   * Parses an allOf combinator schema by merging all schemas.
   *
   * @param {JSONSchema[]} schemas - Array of JSON schemas in the allOf.
   * @returns {ZodTypeAny} - The ZodTypeAny schema.
   */
  static parseAllOf(schemas) {
    if (schemas.length === 0) {
      return import_zod.z.any();
    }
    if (schemas.length === 1) {
      return this.parseSchema(schemas[0]);
    }
    const mergedSchema = schemas.reduce(
      (acc, currentSchema) => this.mergeSchemas(acc, currentSchema)
    );
    return this.parseSchema(mergedSchema);
  }
  /**
   * Merges two JSON schemas together.
   *
   * @param {JSONSchema} baseSchema - The base JSON schema.
   * @param {JSONSchema} addSchema - The JSON schema to add.
   * @returns {JSONSchema} - The merged JSON schema
   */
  static mergeSchemas(baseSchema, addSchema) {
    const merged = __spreadValues(__spreadValues({}, baseSchema), addSchema);
    if (baseSchema.properties && addSchema.properties) {
      const mergedProperties = __spreadValues(__spreadValues({}, baseSchema.properties), addSchema.properties);
      merged.properties = mergedProperties;
    }
    if (baseSchema.required && addSchema.required) {
      const mergedRequired = [
        .../* @__PURE__ */ new Set([...baseSchema.required, ...addSchema.required])
      ];
      merged.required = mergedRequired;
    }
    return merged;
  }
};

// src/model.ts
var import_ai6 = require("@inngest/ai");

// src/adapters/index.ts
var import_ai5 = require("@inngest/ai");

// src/adapters/anthropic.ts
var import_ai2 = require("@inngest/ai");
var import_zod_to_json_schema = require("zod-to-json-schema");
var import_zod5 = require("zod");

// src/state.ts
var State = class _State {
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  constructor(state) {
    this._history = [];
    this._kv = new Map(state && Object.entries(state));
    this.kv = {
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      set: (key, value) => {
        this._kv.set(key, value);
      },
      get: (key) => {
        return this._kv.get(key);
      },
      delete: (key) => {
        return this._kv.delete(key);
      },
      has: (key) => {
        return this._kv.has(key);
      },
      all: () => {
        return Object.fromEntries(this._kv);
      }
    };
  }
  /**
   * Results returns a new array containing all past inference results in the
   * network. This array is safe to modify.
   */
  get results() {
    return this._history.slice();
  }
  /**
   * format returns the memory used for agentic calls based off of prior
   * agentic calls.
   *
   * This is used to format the current State as a conversation log when
   * calling an individual agent.
   *
   */
  format() {
    return this._history.map((call) => call.format()).flat();
  }
  append(call) {
    this._history.push(call);
  }
  clone() {
    const state = new _State();
    state._history = this._history.slice();
    state._kv = new Map(this._kv);
    return state;
  }
};
var InferenceResult = class {
  constructor(agent, input, prompt, history, output, toolCalls, raw) {
    this.agent = agent;
    this.input = input;
    this.prompt = prompt;
    this.history = history;
    this.output = output;
    this.toolCalls = toolCalls;
    this.raw = raw;
  }
  withFormatter(f) {
    this._historyFormatter = f;
  }
  // format
  format() {
    if (this._historyFormatter) {
      return this._historyFormatter(this);
    }
    if (this.raw === "") {
      return [];
    }
    const agent = this.agent;
    const messages = this.prompt.map((msg) => {
      if (msg.type !== "text") {
        return;
      }
      let content = "";
      if (typeof msg.content === "string") {
        content = msg.content;
      } else if (Array.isArray(msg.content)) {
        content = msg.content.map((m) => m.text).join("\n");
      }
      return __spreadProps(__spreadValues({}, msg), {
        type: "text",
        role: "assistant",
        content: `<agent>${agent.name}</agent>
${content}`
      });
    }).filter(Boolean);
    return messages.concat(this.output).concat(this.toolCalls);
  }
};

// src/tool.ts
var import_inngest2 = require("inngest");
var import_zod4 = require("zod");

// src/network.ts
var import_ai = require("@inngest/ai");
var import_zod3 = require("zod");

// src/util.ts
var import_inngest = require("inngest");
var import_InngestFunction = require("inngest/components/InngestFunction");
var import_experimental = require("inngest/experimental");
var import_zod2 = require("zod");
var stringifyError = (e) => {
  if (e instanceof Error) {
    return e.message;
  }
  return String(e);
};
var getStepTools = async () => {
  const asyncCtx = await (0, import_experimental.getAsyncCtx)();
  return asyncCtx == null ? void 0 : asyncCtx.ctx.step;
};
var isInngestFn = (fn) => {
  if (fn instanceof import_InngestFunction.InngestFunction) {
    return true;
  }
  if (typeof fn === "object" && fn !== null && "createExecution" in fn && typeof fn.createExecution === "function") {
    return true;
  }
  return false;
};
var getInngestFnInput = (fn) => {
  var _a, _b, _c;
  const runtimeSchemas = (_a = fn["client"]["schemas"]) == null ? void 0 : _a["runtimeSchemas"];
  if (!runtimeSchemas) {
    return;
  }
  const schemasToAttempt = new Set(
    (_c = (_b = fn["opts"].triggers) == null ? void 0 : _b.reduce((acc, trigger) => {
      if (trigger.event) {
        return [...acc, trigger.event];
      }
      return acc;
    }, [])) != null ? _c : []
  );
  if (!schemasToAttempt.size) {
    return;
  }
  let schema;
  for (const eventSchema of schemasToAttempt) {
    const runtimeSchema = runtimeSchemas[eventSchema];
    if (typeof runtimeSchema === "object" && runtimeSchema !== null && "data" in runtimeSchema && helpers.isZodObject(runtimeSchema.data)) {
      if (schema) {
        schema = schema.or(runtimeSchema.data);
      } else {
        schema = runtimeSchema.data;
      }
      continue;
    }
  }
  return schema;
};
var helpers = {
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  isZodObject: (value) => {
    return value instanceof import_zod2.ZodType && value._def.typeName === "ZodObject";
  },
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  isObject: (value) => {
    return typeof value === "object" && value !== null && !Array.isArray(value);
  }
};

// src/network.ts
var createNetwork = (opts) => new Network(opts);
var Network = class {
  constructor({
    name,
    description,
    agents,
    defaultModel,
    maxIter,
    defaultState,
    defaultRouter
  }) {
    this._counter = 0;
    this.name = name;
    this.description = description;
    this.agents = /* @__PURE__ */ new Map();
    this._agents = /* @__PURE__ */ new Map();
    this.defaultModel = defaultModel;
    this.defaultRouter = defaultRouter;
    this.maxIter = maxIter || 0;
    this._stack = [];
    if (defaultState) {
      this.defaultState = defaultState;
    }
    for (const agent of agents) {
      this.agents.set(agent.name, agent);
      this._agents.set(agent.name, agent);
    }
  }
  async availableAgents(networkRun = new NetworkRun(this, new State())) {
    var _a;
    const available = [];
    const all = Array.from(this.agents.values());
    for (const a of all) {
      const enabled = (_a = a == null ? void 0 : a.lifecycles) == null ? void 0 : _a.enabled;
      if (!enabled || await enabled({ agent: a, network: networkRun })) {
        available.push(a);
      }
    }
    return available;
  }
  /**
   * addAgent adds a new agent to the network.
   */
  addAgent(agent) {
    this.agents.set(agent.name, agent);
  }
  /**
   * run handles a given request using the network of agents.  It is not
   * concurrency-safe; you can only call run on a network once, as networks are
   * stateful.
   *
   */
  run(...[input, overrides]) {
    var _a;
    let state;
    if (overrides == null ? void 0 : overrides.state) {
      if (overrides.state instanceof State) {
        state = overrides.state;
      } else {
        state = new State(overrides.state);
      }
    } else {
      state = ((_a = this.defaultState) == null ? void 0 : _a.clone()) || new State();
    }
    return new NetworkRun(this, state)["execute"](input, overrides);
  }
};
var defaultRoutingAgent;
var getDefaultRoutingAgent = () => {
  defaultRoutingAgent != null ? defaultRoutingAgent : defaultRoutingAgent = createRoutingAgent({
    name: "Default routing agent",
    description: "Selects which agents to work on based off of the current prompt and input.",
    lifecycle: {
      onRoute: ({ result }) => {
        const tool = result.toolCalls[0];
        if (!tool) {
          return;
        }
        if (typeof tool.content === "object" && tool.content !== null && "data" in tool.content && typeof tool.content.data === "string") {
          return [tool.content.data];
        }
        return;
      }
    },
    tools: [
      // This tool does nothing but ensure that the model responds with the
      // agent name as valid JSON.
      createTool({
        name: "select_agent",
        description: "select an agent to handle the input, based off of the current conversation",
        parameters: import_zod3.z.object({
          name: import_zod3.z.string().describe("The name of the agent that should handle the request")
        }).strict(),
        handler: ({ name }, { network }) => {
          if (!network) {
            throw new Error(
              "The routing agent can only be used within a network of agents"
            );
          }
          if (typeof name !== "string") {
            throw new Error("The routing agent requested an invalid agent");
          }
          const agent = network.agents.get(name);
          if (agent === void 0) {
            throw new Error(
              `The routing agent requested an agent that doesn't exist: ${name}`
            );
          }
          return agent.name;
        }
      })
    ],
    tool_choice: "select_agent",
    system: async ({ network }) => {
      if (!network) {
        throw new Error(
          "The routing agent can only be used within a network of agents"
        );
      }
      const agents = await (network == null ? void 0 : network.availableAgents());
      return `You are the orchestrator between a group of agents.  Each agent is suited for a set of specific tasks, and has a name, instructions, and a set of tools.

The following agents are available:
<agents>
  ${agents.map((a) => {
        return `
    <agent>
      <name>${a.name}</name>
      <description>${a.description}</description>
      <tools>${JSON.stringify(Array.from(a.tools.values()))}</tools>
    </agent>`;
      }).join("\n")}
</agents>

Follow the set of instructions:

<instructions>
  Think about the current history and status.  Determine which agent to use to handle the user's request, based off of the current agents and their tools.

  Your aim is to thoroughly complete the request, thinking step by step, choosing the right agent based off of the context.
</instructions>
    `;
    }
  });
  return defaultRoutingAgent;
};

// src/networkRun.ts
var NetworkRun = class extends Network {
  constructor(network, state) {
    super({
      name: network.name,
      description: network.description,
      agents: Array.from(network.agents.values()),
      defaultModel: network.defaultModel,
      defaultState: network.defaultState,
      defaultRouter: network.defaultRouter,
      maxIter: network.maxIter
    });
    this.state = state;
  }
  run() {
    throw new Error("NetworkRun does not support run");
  }
  async availableAgents() {
    return super.availableAgents(this);
  }
  /**
   * Schedule is used to push an agent's run function onto the stack.
   */
  schedule(agentName) {
    this["_stack"].push(agentName);
  }
  async execute(...[input, overrides]) {
    const available = await this.availableAgents();
    if (available.length === 0) {
      throw new Error("no agents enabled in network");
    }
    const next = await this.getNextAgents(
      input,
      (overrides == null ? void 0 : overrides.router) || this.defaultRouter
    );
    if (!(next == null ? void 0 : next.length)) {
      return this;
    }
    for (const agent of next) {
      this.schedule(agent.name);
    }
    while (this._stack.length > 0 && (this.maxIter === 0 || this._counter < this.maxIter)) {
      const agentName = this._stack.shift();
      const agent = agentName && this._agents.get(agentName);
      if (!agent) {
        return this;
      }
      const call = await agent.run(input, { network: this, maxIter: 0 });
      this._counter += 1;
      this.state.append(call);
      const next2 = await this.getNextAgents(
        input,
        (overrides == null ? void 0 : overrides.router) || this.defaultRouter
      );
      for (const a of next2 || []) {
        this.schedule(a.name);
      }
    }
    return this;
  }
  async getNextAgents(input, router) {
    if (!router && !this.defaultModel) {
      throw new Error(
        "No router or model defined in network.  You must pass a router or a default model to use the built-in agentic router."
      );
    }
    if (!router) {
      router = getDefaultRoutingAgent();
    }
    if (router instanceof RoutingAgent) {
      return await this.getNextAgentsViaRoutingAgent(router, input);
    }
    const stack = this._stack.map((name) => {
      const agent2 = this._agents.get(name);
      if (!agent2) {
        throw new Error(`unknown agent in the network stack: ${name}`);
      }
      return agent2;
    });
    const agent = await router({
      input,
      network: this,
      stack,
      lastResult: this.state.results.pop(),
      callCount: this._counter
    });
    if (!agent) {
      return;
    }
    if (agent instanceof RoutingAgent) {
      return await this.getNextAgentsViaRoutingAgent(agent, input);
    }
    for (const a of Array.isArray(agent) ? agent : [agent]) {
      if (!this._agents.has(a.name)) {
        this._agents.set(a.name, a);
      }
    }
    return Array.isArray(agent) ? agent : [agent];
  }
  async getNextAgentsViaRoutingAgent(routingAgent, input) {
    const result = await routingAgent.run(input, {
      network: this,
      model: routingAgent.model || this.defaultModel
    });
    const agentNames = routingAgent.lifecycles.onRoute({
      result,
      agent: routingAgent,
      network: this
    });
    return (agentNames || []).map((name) => this.agents.get(name)).filter(Boolean);
  }
};

// src/adapters/anthropic.ts
var requestParser = (model, messages, tools, tool_choice = "auto") => {
  const systemMessage = messages.find(
    (m) => m.role === "system" && m.type === "text"
  );
  const system = typeof (systemMessage == null ? void 0 : systemMessage.content) === "string" ? systemMessage.content : "";
  const anthropicMessages = messages.filter((m) => m.role !== "system").reduce(
    (acc, m) => {
      switch (m.type) {
        case "text":
          return [
            ...acc,
            {
              role: m.role,
              content: Array.isArray(m.content) ? m.content.map((text) => ({ type: "text", text })) : m.content
            }
          ];
        case "tool_call":
          return [
            ...acc,
            {
              role: m.role,
              content: m.tools.map((tool) => ({
                type: "tool_use",
                id: tool.id,
                input: tool.input,
                name: tool.name
              }))
            }
          ];
        case "tool_result":
          return [
            ...acc,
            {
              role: "user",
              content: [
                {
                  type: "tool_result",
                  tool_use_id: m.tool.id,
                  content: typeof m.content === "string" ? m.content : JSON.stringify(m.content)
                }
              ]
            }
          ];
      }
    },
    []
  );
  const lastMessage = anthropicMessages[anthropicMessages.length - 1];
  if ((lastMessage == null ? void 0 : lastMessage.role) === "assistant") {
    lastMessage.role = "user";
  }
  const request = {
    system,
    model: model.options.model,
    max_tokens: model.options.defaultParameters.max_tokens,
    messages: anthropicMessages
  };
  if (tools == null ? void 0 : tools.length) {
    request.tools = tools.map((t) => {
      return {
        name: t.name,
        description: t.description,
        input_schema: t.parameters ? (0, import_zod_to_json_schema.zodToJsonSchema)(t.parameters) : (0, import_zod_to_json_schema.zodToJsonSchema)(
          import_zod5.z.object({})
        )
      };
    });
    request.tool_choice = toolChoice(tool_choice);
  }
  return request;
};
var responseParser = (input) => {
  var _a, _b;
  if (input.type === "error") {
    throw new Error(
      ((_a = input.error) == null ? void 0 : _a.message) || `Anthropic request failed: ${JSON.stringify(input.error)}`
    );
  }
  return ((_b = input == null ? void 0 : input.content) != null ? _b : []).reduce((acc, item) => {
    if (!item.type) {
      return acc;
    }
    switch (item.type) {
      case "text":
        return [
          ...acc,
          {
            type: "text",
            role: input.role,
            content: item.text,
            // XXX: Better stop reason parsing
            stop_reason: "stop"
          }
        ];
      case "tool_use": {
        let args;
        try {
          args = typeof item.input === "string" ? JSON.parse(item.input) : item.input;
        } catch (e) {
          args = item.input;
        }
        return [
          ...acc,
          {
            type: "tool_call",
            role: input.role,
            stop_reason: "tool",
            tools: [
              {
                type: "tool",
                id: item.id,
                name: item.name,
                // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
                input: args
              }
            ]
          }
        ];
      }
    }
  }, []);
};
var toolChoice = (choice) => {
  switch (choice) {
    case "auto":
      return { type: "auto" };
    case "any":
      return { type: "any" };
    default:
      if (typeof choice === "string") {
        return {
          type: "tool",
          name: choice
        };
      }
  }
};

// src/adapters/openai.ts
var import_ai3 = require("@inngest/ai");
var import_zod_to_json_schema2 = require("zod-to-json-schema");
var requestParser2 = (model, messages, tools, tool_choice = "auto") => {
  var _a, _b;
  const request = {
    messages: messages.map((m) => {
      var _a2;
      switch (m.type) {
        case "text":
          return {
            role: m.role,
            content: m.content
          };
        case "tool_call":
          return {
            role: "assistant",
            content: null,
            tool_calls: m.tools ? (_a2 = m.tools) == null ? void 0 : _a2.map((tool) => ({
              id: tool.id,
              type: "function",
              function: {
                name: tool.name,
                arguments: JSON.stringify(tool.input)
              }
            })) : void 0
          };
        case "tool_result":
          return {
            role: "tool",
            tool_call_id: m.tool.id,
            content: typeof m.content === "string" ? m.content : JSON.stringify(m.content)
          };
      }
    })
  };
  if (tools == null ? void 0 : tools.length) {
    request.tool_choice = toolChoice2(tool_choice);
    if (!((_a = model.options.model) == null ? void 0 : _a.includes("o3")) && !((_b = model.options.model) == null ? void 0 : _b.includes("o1"))) {
      request.parallel_tool_calls = false;
    }
    request.tools = tools.map((t) => {
      return {
        type: "function",
        function: {
          name: t.name,
          description: t.description,
          parameters: t.parameters && (0, import_zod_to_json_schema2.zodToJsonSchema)(t.parameters, { target: "openAi" }),
          strict: typeof t.strict !== "undefined" ? t.strict : Boolean(t.parameters)
          // strict mode is only supported with parameters
        }
      };
    });
  }
  return request;
};
var responseParser2 = (input) => {
  var _a;
  if (input.error) {
    throw new Error(
      input.error.message || `OpenAI request failed: ${JSON.stringify(input.error)}`
    );
  }
  return ((_a = input == null ? void 0 : input.choices) != null ? _a : []).reduce((acc, choice) => {
    const { message, finish_reason } = choice;
    if (!message) {
      return acc;
    }
    const base = {
      role: choice.message.role,
      stop_reason: openAiStopReasonToStateStopReason[finish_reason != null ? finish_reason : ""] || "stop"
    };
    if (message.content) {
      return [
        ...acc,
        __spreadProps(__spreadValues({}, base), {
          type: "text",
          content: message.content
        })
      ];
    }
    if (message.tool_calls.length > 0) {
      return [
        ...acc,
        __spreadProps(__spreadValues({}, base), {
          type: "tool_call",
          tools: message.tool_calls.map((tool) => {
            return {
              type: "tool",
              id: tool.id,
              name: tool.function.name,
              function: tool.function.name,
              input: safeParseOpenAIJson(tool.function.arguments || "{}")
            };
          })
        })
      ];
    }
    return acc;
  }, []);
};
var safeParseOpenAIJson = (str) => {
  const trimmed = str.replace(/^["']|["']$/g, "");
  try {
    return JSON.parse(trimmed);
  } catch (e) {
    try {
      const withQuotes = trimmed.replace(
        /`([\s\S]*?)`/g,
        (_, content) => JSON.stringify(content)
      );
      return JSON.parse(withQuotes);
    } catch (e2) {
      throw new Error(
        `Failed to parse JSON with backticks: ${stringifyError(e2)}`
      );
    }
  }
};
var openAiStopReasonToStateStopReason = {
  tool_calls: "tool",
  stop: "stop",
  length: "stop",
  content_filter: "stop",
  function_call: "tool"
};
var toolChoice2 = (choice) => {
  switch (choice) {
    case "auto":
      return "auto";
    case "any":
      return "required";
    default:
      return {
        type: "function",
        function: { name: choice }
      };
  }
};

// src/adapters/gemini.ts
var import_ai4 = require("@inngest/ai");
var import_zod6 = require("zod");
var import_zod_to_json_schema3 = require("zod-to-json-schema");
var requestParser3 = (_model2, messages, tools, tool_choice = "auto") => {
  const contents = messages.map((m) => messageToContent(m));
  const functionDeclarations = tools.map((t) => ({
    name: t.name,
    description: t.description,
    parameters: t.parameters ? geminiZodToJsonSchema(t.parameters) : (
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      geminiZodToJsonSchema(import_zod6.z.object({}))
    )
  }));
  return {
    contents,
    tools: [
      {
        functionDeclarations
      }
    ],
    tool_config: toolChoice3(tool_choice)
  };
};
var messageContentToString = (content) => {
  if (typeof content === "string") {
    return content;
  }
  return content.map((c) => c.text).join("");
};
var responseParser3 = (input) => {
  var _a, _b;
  if (input.error) {
    throw new Error(
      ((_a = input.error) == null ? void 0 : _a.message) || `Gemini request failed: ${JSON.stringify(input.error)}`
    );
  }
  const messages = [];
  for (const candidate of (_b = input.candidates) != null ? _b : []) {
    for (const content of candidate.content.parts) {
      if (candidate.content.role === "user" && "text" in content) {
        messages.push({
          role: "user",
          type: "text",
          content: content.text
        });
      } else if (candidate.content.role === "model" && "text" in content) {
        messages.push({
          role: "assistant",
          type: "text",
          content: content.text
        });
      } else if (candidate.content.role === "model" && "functionCall" in content) {
        messages.push({
          role: "assistant",
          type: "tool_call",
          stop_reason: "tool",
          tools: [
            {
              name: content.functionCall.name,
              input: content.functionCall.args,
              type: "tool",
              id: content.functionCall.name
            }
          ]
        });
      } else if (candidate.content.role === "user" && "functionResponse" in content) {
        messages.push({
          role: "tool_result",
          type: "tool_result",
          stop_reason: "tool",
          tool: {
            name: content.functionResponse.name,
            input: content.functionResponse.response,
            type: "tool",
            id: content.functionResponse.name
          },
          content: JSON.stringify(content.functionResponse.response)
        });
      } else {
        throw new Error("Unknown content type");
      }
    }
  }
  return messages;
};
var messageToContent = (m) => {
  switch (m.role) {
    case "system":
      return {
        role: "user",
        parts: [{ text: messageContentToString(m.content) }]
      };
    case "user":
      switch (m.type) {
        case "tool_call":
          if (m.tools.length === 0) {
            throw new Error("Tool call message must have at least one tool");
          }
          return {
            role: "model",
            parts: [
              {
                functionCall: {
                  name: m.tools[0].name,
                  args: m.tools[0].input
                }
              }
            ]
          };
        case "text":
        default:
          return {
            role: "user",
            parts: [{ text: messageContentToString(m.content) }]
          };
      }
    case "assistant":
      switch (m.type) {
        case "tool_call":
          if (m.tools.length === 0) {
            throw new Error("Tool call message must have at least one tool");
          }
          return {
            role: "model",
            parts: [
              {
                functionCall: {
                  name: m.tools[0].name,
                  args: m.tools[0].input
                }
              }
            ]
          };
        case "text":
        default:
          return {
            role: "model",
            parts: [{ text: messageContentToString(m.content) }]
          };
      }
    case "tool_result":
      return {
        role: "user",
        parts: [
          {
            functionResponse: {
              name: m.tool.name,
              response: {
                name: m.tool.name,
                content: typeof m.content === "string" ? m.content : JSON.stringify(m.content)
              }
            }
          }
        ]
      };
    default:
      throw new Error(`Unknown message role: ${m.role}`);
  }
};
var toolChoice3 = (choice) => {
  switch (choice) {
    case "auto":
      return {
        functionCallingConfig: {
          mode: "AUTO"
        }
      };
    case "any":
      return {
        functionCallingConfig: {
          mode: "ANY"
        }
      };
    default:
      if (typeof choice === "string") {
        return {
          functionCallingConfig: {
            mode: "ANY",
            allowedFunctionNames: [choice]
          }
        };
      }
  }
};
var geminiZodToJsonSchema = (zod) => {
  const schema = (0, import_zod_to_json_schema3.zodToJsonSchema)(zod, { target: "openApi3" });
  delete schema["additionalProperties"];
  return schema;
};

// src/adapters/grok.ts
var requestParser4 = (model, messages, tools, tool_choice = "auto") => {
  const request = requestParser2(
    model,
    messages,
    tools,
    tool_choice
  );
  request.tools = (request.tools || []).map((tool) => __spreadProps(__spreadValues({}, tool), {
    function: __spreadProps(__spreadValues({}, tool.function), {
      strict: false
    })
  }));
  return request;
};
var responseParser4 = responseParser2;

// src/adapters/index.ts
var adapters = {
  "openai-chat": {
    request: requestParser2,
    response: responseParser2
  },
  anthropic: {
    request: requestParser,
    response: responseParser
  },
  gemini: {
    request: requestParser3,
    response: responseParser3
  },
  grok: {
    request: requestParser4,
    response: responseParser4
  }
};

// src/model.ts
var createAgenticModelFromAiAdapter = (adapter) => {
  const opts = adapters[adapter.format];
  return new AgenticModel({
    model: adapter,
    requestParser: opts.request,
    responseParser: opts.response
  });
};
var _model;
var AgenticModel = class {
  constructor({
    model,
    requestParser: requestParser5,
    responseParser: responseParser5
  }) {
    __privateAdd(this, _model);
    __privateSet(this, _model, model);
    this.requestParser = requestParser5;
    this.responseParser = responseParser5;
  }
  async infer(stepID, input, tools, tool_choice) {
    var _a, _b;
    const body = this.requestParser(__privateGet(this, _model), input, tools, tool_choice);
    let result;
    const step = await getStepTools();
    if (step) {
      result = await step.ai.infer(stepID, {
        model: __privateGet(this, _model),
        body
      });
    } else {
      const modelCopy = __spreadValues({}, __privateGet(this, _model));
      (_b = (_a = __privateGet(this, _model)).onCall) == null ? void 0 : _b.call(_a, modelCopy, body);
      const url = new URL(modelCopy.url || "");
      const headers = {
        "Content-Type": "application/json"
      };
      const formatHandlers = {
        "openai-chat": () => {
          headers["Authorization"] = `Bearer ${modelCopy.authKey}`;
        },
        anthropic: () => {
          headers["x-api-key"] = modelCopy.authKey;
          headers["anthropic-version"] = "2023-06-01";
        },
        gemini: () => {
        },
        grok: () => {
        }
      };
      formatHandlers[modelCopy.format]();
      result = await (await fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body)
      })).json();
    }
    return { output: this.responseParser(result), raw: result };
  }
};
_model = new WeakMap();

// src/agent.ts
var createTool = (t) => t;
var createAgent = (opts) => new Agent(opts);
var createRoutingAgent = (opts) => new RoutingAgent(opts);
var Agent = class _Agent {
  constructor(opts) {
    this.name = opts.name;
    this.description = opts.description || "";
    this.system = opts.system;
    this.assistant = opts.assistant || "";
    this.tools = /* @__PURE__ */ new Map();
    this.tool_choice = opts.tool_choice;
    this.lifecycles = opts.lifecycle;
    this.model = opts.model;
    this.setTools(opts.tools);
    this.mcpServers = opts.mcpServers;
    this._mcpClients = [];
  }
  setTools(tools) {
    for (const tool of tools || []) {
      if (isInngestFn(tool)) {
        this.tools.set(tool["absoluteId"], {
          name: tool["absoluteId"],
          description: tool.description,
          // TODO Should we error here if we can't find an input schema?
          parameters: getInngestFnInput(tool),
          handler: async (input, opts) => {
            const step = await getStepTools();
            if (!step) {
              throw new Error("Inngest tool called outside of Inngest context");
            }
            const stepId = `${opts.agent.name}/tools/${tool["absoluteId"]}`;
            return step.invoke(stepId, {
              function: (0, import_inngest3.referenceFunction)({
                appId: tool["client"]["id"],
                functionId: tool.id()
              }),
              data: input
            });
          }
        });
      } else {
        this.tools.set(tool.name, tool);
      }
    }
  }
  withModel(model) {
    return new _Agent({
      name: this.name,
      description: this.description,
      system: this.system,
      assistant: this.assistant,
      tools: Array.from(this.tools.values()),
      lifecycle: this.lifecycles,
      model
    });
  }
  /**
   * Run runs an agent with the given user input, treated as a user message.  If
   * the input is an empty string, only the system prompt will execute.
   */
  async run(input, { model, network, state, maxIter = 0 } = {}) {
    var _a, _b;
    await this.initMCP();
    const rawModel = model || this.model || (network == null ? void 0 : network.defaultModel);
    if (!rawModel) {
      throw new Error("No model provided to agent");
    }
    const p = createAgenticModelFromAiAdapter(rawModel);
    const s = state || (network == null ? void 0 : network.state) || new State();
    const run = network && new NetworkRun(network, s);
    let history = s ? s.format() : [];
    let prompt = await this.agentPrompt(input, run);
    let result = new InferenceResult(this, input, prompt, history, [], [], "");
    let hasMoreActions = true;
    let iter = 0;
    do {
      if ((_a = this.lifecycles) == null ? void 0 : _a.onStart) {
        const modified = await this.lifecycles.onStart({
          agent: this,
          network: run,
          input,
          prompt,
          history
        });
        if (modified.stop) {
          return result;
        }
        prompt = modified.prompt;
        history = modified.history;
      }
      const inference = await this.performInference(
        input,
        p,
        prompt,
        history,
        run
      );
      hasMoreActions = Boolean(
        this.tools.size > 0 && inference.output.length && inference.output[inference.output.length - 1].stop_reason !== "stop"
      );
      result = inference;
      history = [...inference.output];
      iter++;
    } while (hasMoreActions && iter < maxIter);
    if ((_b = this.lifecycles) == null ? void 0 : _b.onFinish) {
      result = await this.lifecycles.onFinish({
        agent: this,
        network: run,
        result
      });
    }
    return result;
  }
  async performInference(input, p, prompt, history, network) {
    var _a;
    const { output, raw } = await p.infer(
      this.name,
      prompt.concat(history),
      Array.from(this.tools.values()),
      this.tool_choice || "auto"
    );
    let result = new InferenceResult(
      this,
      input,
      prompt,
      history,
      output,
      [],
      typeof raw === "string" ? raw : JSON.stringify(raw)
    );
    if ((_a = this.lifecycles) == null ? void 0 : _a.onResponse) {
      result = await this.lifecycles.onResponse({
        agent: this,
        network,
        result
      });
    }
    const toolCallOutput = await this.invokeTools(result.output, p, network);
    if (toolCallOutput.length > 0) {
      result.toolCalls = result.toolCalls.concat(toolCallOutput);
    }
    return result;
  }
  /**
   * invokeTools takes output messages from an inference call then invokes any tools
   * in the message responses.
   */
  async invokeTools(msgs, p, network) {
    const output = [];
    for (const msg of msgs) {
      if (msg.type !== "tool_call") {
        continue;
      }
      if (!Array.isArray(msg.tools)) {
        continue;
      }
      for (const tool of msg.tools) {
        const found = this.tools.get(tool.name);
        if (!found) {
          throw new Error(
            `Inference requested a non-existent tool: ${tool.name}`
          );
        }
        const result = await Promise.resolve(
          found.handler(tool.input, {
            agent: this,
            network,
            step: await getStepTools()
          })
        ).then((r) => {
          return {
            // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
            data: typeof r === "undefined" ? `${tool.name} successfully executed` : r
          };
        }).catch((err) => {
          return { error: (0, import_errors.serializeError)(err) };
        });
        output.push({
          role: "tool_result",
          type: "tool_result",
          tool: {
            type: "tool",
            id: tool.id,
            name: tool.name,
            input: tool.input.arguments
          },
          content: result,
          stop_reason: "tool"
        });
      }
    }
    return output;
  }
  async agentPrompt(input, network) {
    const messages = [
      {
        type: "text",
        role: "system",
        content: typeof this.system === "string" ? this.system : await this.system({ network })
      }
    ];
    if (input.length > 0) {
      messages.push({ type: "text", role: "user", content: input });
    }
    if (this.assistant.length > 0) {
      messages.push({
        type: "text",
        role: "assistant",
        content: this.assistant
      });
    }
    return messages;
  }
  // initMCP fetches all tools from the agent's MCP servers, adding them to the tool list.
  // This is all that's necessary in order to enable MCP tool use within agents
  async initMCP() {
    if (!this.mcpServers || this._mcpClients.length === this.mcpServers.length) {
      return;
    }
    const promises = [];
    for (const server of this.mcpServers) {
      await this.listMCPTools(server);
      promises.push(this.listMCPTools(server));
    }
    await Promise.all(promises);
  }
  /**
   * listMCPTools lists all available tools for a given MCP server
   */
  async listMCPTools(server) {
    const client = await this.mcpClient(server);
    try {
      const results = await client.request(
        { method: "tools/list" },
        import_types.ListToolsResultSchema
      );
      results.tools.forEach((t) => {
        const name = `${server.name}-${t.name}`;
        let zschema;
        try {
          zschema = JSONSchemaToZod.convert(t.inputSchema);
        } catch (e) {
          zschema = void 0;
        }
        this.tools.set(name, {
          name,
          description: t.description,
          parameters: zschema,
          mcp: {
            server,
            tool: t
          },
          handler: async (input) => {
            var _a;
            const fn = () => client.callTool({
              name: t.name,
              arguments: input
            });
            const step = await getStepTools();
            const result = await ((_a = step == null ? void 0 : step.run(name, fn)) != null ? _a : fn());
            return result.content;
          }
        });
      });
    } catch (e) {
      console.warn("error listing mcp tools", e);
    }
  }
  /**
   * mcpClient creates a new MCP client for the given server.
   */
  async mcpClient(server) {
    const transport = (() => {
      switch (server.transport.type) {
        case "sse":
          if (global.EventSource === void 0) {
            global.EventSource = import_eventsource.EventSource;
          }
          return new import_sse.SSEClientTransport(new URL(server.transport.url), {
            eventSourceInit: server.transport.eventSourceInit,
            requestInit: server.transport.requestInit
          });
        case "ws":
          return new import_websocket.WebSocketClientTransport(new URL(server.transport.url));
      }
    })();
    const client = new import_client.Client(
      {
        name: this.name,
        // XXX: This version should change.
        version: "1.0.0"
      },
      {
        capabilities: {}
      }
    );
    try {
      await client.connect(transport);
    } catch (e) {
      console.warn("mcp server disconnected", server, e);
    }
    this._mcpClients.push(client);
    return client;
  }
};
var RoutingAgent = class _RoutingAgent extends Agent {
  constructor(opts) {
    super(opts);
    this.type = "routing";
    this.lifecycles = opts.lifecycle;
  }
  withModel(model) {
    return new _RoutingAgent({
      name: this.name,
      description: this.description,
      system: this.system,
      assistant: this.assistant,
      tools: Array.from(this.tools.values()),
      lifecycle: this.lifecycles,
      model
    });
  }
};

// src/models.ts
var import_ai8 = require("@inngest/ai");
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  Agent,
  AgenticModel,
  InferenceResult,
  Network,
  NetworkRun,
  RoutingAgent,
  State,
  anthropic,
  createAgent,
  createAgenticModelFromAiAdapter,
  createNetwork,
  createRoutingAgent,
  createTool,
  gemini,
  getDefaultRoutingAgent,
  getInngestFnInput,
  getStepTools,
  grok,
  isInngestFn,
  openai,
  stringifyError
});
//# sourceMappingURL=index.cjs.map