{"version":3,"sources":["../src/utils.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { FunctionDeclaration, Schema } from '@google/genai';\nimport { llm } from '@livekit/agents';\nimport type { JSONSchema7 } from 'json-schema';\n\n/**\n * JSON Schema v7\n * @see https://tools.ietf.org/html/draft-handrews-json-schema-validation-01\n */\nexport type JSONSchema7Definition = JSONSchema7 | boolean;\n\n/**\n * Converts JSON Schema 7 to OpenAPI Schema 3.0\n */\n// Adapted from https://github.com/vercel/ai/blob/main/packages/google/src/convert-json-schema-to-openapi-schema.ts\nexport function convertJSONSchemaToOpenAPISchema(jsonSchema: JSONSchema7Definition): unknown {\n  // parameters need to be undefined if they are empty objects:\n  if (jsonSchema == null || isEmptyObjectSchema(jsonSchema)) {\n    return undefined;\n  }\n\n  if (typeof jsonSchema === 'boolean') {\n    return { type: 'boolean', properties: {} };\n  }\n\n  const {\n    type,\n    description,\n    required,\n    properties,\n    items,\n    allOf,\n    anyOf,\n    oneOf,\n    format,\n    const: constValue,\n    minLength,\n    enum: enumValues,\n  } = jsonSchema;\n\n  const result: Record<string, unknown> = {};\n\n  if (description) result.description = description;\n  if (required) result.required = required;\n  if (format) result.format = format;\n\n  if (constValue !== undefined) {\n    result.enum = [constValue];\n  }\n\n  // Handle type\n  if (type) {\n    if (Array.isArray(type)) {\n      if (type.includes('null')) {\n        result.type = type.filter((t) => t !== 'null')[0];\n        result.nullable = true;\n      } else {\n        result.type = type;\n      }\n    } else if (type === 'null') {\n      result.type = 'null';\n    } else {\n      result.type = type;\n    }\n  }\n\n  // Handle enum\n  if (enumValues !== undefined) {\n    result.enum = enumValues;\n  }\n\n  if (properties != null) {\n    result.properties = Object.entries(properties).reduce(\n      (acc, [key, value]) => {\n        acc[key] = convertJSONSchemaToOpenAPISchema(value);\n        return acc;\n      },\n      {} as Record<string, unknown>,\n    );\n  }\n\n  if (items) {\n    result.items = Array.isArray(items)\n      ? items.map(convertJSONSchemaToOpenAPISchema)\n      : convertJSONSchemaToOpenAPISchema(items);\n  }\n\n  if (allOf) {\n    result.allOf = allOf.map(convertJSONSchemaToOpenAPISchema);\n  }\n  if (anyOf) {\n    // Handle cases where anyOf includes a null type\n    if (anyOf.some((schema) => typeof schema === 'object' && schema?.type === 'null')) {\n      const nonNullSchemas = anyOf.filter(\n        (schema) => !(typeof schema === 'object' && schema?.type === 'null'),\n      );\n\n      if (nonNullSchemas.length === 1) {\n        // If there's only one non-null schema, convert it and make it nullable\n        const converted = convertJSONSchemaToOpenAPISchema(\n          nonNullSchemas[0] as JSONSchema7Definition,\n        );\n        if (typeof converted === 'object') {\n          result.nullable = true;\n          Object.assign(result, converted);\n        }\n      } else {\n        // If there are multiple non-null schemas, keep them in anyOf\n        result.anyOf = nonNullSchemas.map(convertJSONSchemaToOpenAPISchema);\n        result.nullable = true;\n      }\n    } else {\n      result.anyOf = anyOf.map(convertJSONSchemaToOpenAPISchema);\n    }\n  }\n  if (oneOf) {\n    result.oneOf = oneOf.map(convertJSONSchemaToOpenAPISchema);\n  }\n\n  if (minLength !== undefined) {\n    result.minLength = minLength;\n  }\n\n  return result;\n}\n\nfunction isEmptyObjectSchema(jsonSchema: JSONSchema7Definition): boolean {\n  return (\n    jsonSchema != null &&\n    typeof jsonSchema === 'object' &&\n    jsonSchema.type === 'object' &&\n    (jsonSchema.properties == null || Object.keys(jsonSchema.properties).length === 0) &&\n    !jsonSchema.additionalProperties\n  );\n}\n\nexport function toFunctionDeclarations(toolCtx: llm.ToolContext): FunctionDeclaration[] {\n  const functionDeclarations: FunctionDeclaration[] = [];\n\n  for (const [name, tool] of llm.sortedToolEntries(toolCtx)) {\n    const { description, parameters } = tool;\n    const jsonSchema = llm.toJsonSchema(parameters, false);\n\n    // Create a deep copy to prevent the Google GenAI library from mutating the schema\n    const schemaCopy = JSON.parse(JSON.stringify(jsonSchema));\n\n    functionDeclarations.push({\n      name,\n      description,\n      parameters: convertJSONSchemaToOpenAPISchema(schemaCopy) as Schema,\n    });\n  }\n\n  return functionDeclarations;\n}\n"],"mappings":"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","names":[]}