{"version":3,"file":"validation.mjs","names":[],"sources":["../../../../src/batteries/llm/gemini_generate_content/validation.ts"],"sourcesContent":["/**\n * Runtime option validation for the native Gemini `generateContent` battery.\n *\n * @module @nhtio/adk/batteries/llm/gemini_generate_content/validation\n */\n\nimport { validator } from '@nhtio/validation'\nimport { TokenEncoding } from '@nhtio/adk/common'\nimport { E_INVALID_GEMINI_GENERATE_CONTENT_OPTIONS } from './exceptions'\nimport type { GeminiGenerateContentAdapterOptions } from './types'\n\n/** Schema for {@link GeminiGenerateContentAdapterOptions}. */\nconst tokenEncodingSchema = validator\n  .alternatives(\n    // Known values are suggestions from the canonical list, not a whitelist: consumers may provide\n    // a custom or newer tokenizer name. The field accepts any non-empty string, explicit null, or\n    // absent (undefined = \"no token counting\"). `.optional()` preserves the null/undefined\n    // disposition required by adk/require-validator-any-required.\n    validator\n      .string()\n      .min(1)\n      .description(`Known encodings: ${TokenEncoding.join(', ')}`),\n    validator.any().valid(null).optional()\n  )\n  .default(null)\n\n/** Schema for {@link GeminiGenerateContentAdapterOptions}. */\nexport const geminiGenerateContentOptionsSchema = validator.object({\n  model: validator.string().min(1).required(),\n  apiKey: validator.string().optional(),\n  useBearerAuth: validator.boolean().optional(),\n  baseURL: validator.string().optional(),\n  stream: validator.boolean().optional(),\n  contextWindow: validator.number().integer().min(1).optional(),\n  autoAck: validator.boolean().default(true),\n  maxOutputTokens: validator.number().integer().positive().optional(),\n  temperature: validator.number().min(0).max(2).optional(),\n  topP: validator.number().min(0).max(1).optional(),\n  topK: validator.number().integer().positive().optional(),\n  stopSequences: validator.array().items(validator.string()).optional(),\n  thinkingConfig: validator\n    .object({\n      thinkingBudget: validator.number().integer().optional(),\n      includeThoughts: validator.boolean().optional(),\n    })\n    .optional(),\n  safetySettings: validator\n    .array()\n    .items(\n      validator.object({\n        category: validator.string().required(),\n        threshold: validator.string().required(),\n      })\n    )\n    .optional(),\n  toolConfig: validator\n    .object({\n      functionCallingConfig: validator\n        .object({\n          mode: validator.string().valid('AUTO', 'ANY', 'NONE').required(),\n          allowedFunctionNames: validator.array().items(validator.string()).optional(),\n        })\n        .required(),\n    })\n    .optional(),\n  // `false` opts out of the sentinel entirely and surfaces Gemini's own rejection instead.\n  thoughtSignatureSentinel: validator\n    .alternatives(validator.string().min(1), validator.boolean().valid(false))\n    .optional(),\n  timeoutMs: validator.number().integer().positive().optional(),\n  retry: validator\n    .object({\n      maxAttempts: validator.number().integer().positive().optional(),\n      baseDelayMs: validator.number().integer().positive().optional(),\n      maxDelayMs: validator.number().integer().positive().optional(),\n      retriableStatuses: validator.array().items(validator.number()).optional(),\n      honorRetryAfter: validator.boolean().optional(),\n    })\n    .optional(),\n  fetch: validator.function().optional(),\n  tokenEncoding: tokenEncodingSchema,\n  spoolStore: validator.any().optional(),\n  bucketOrder: validator.any().optional(),\n  thoughtSurfacing: validator.string().valid('all-self', 'latest-self', 'all').optional(),\n  unsupportedMediaPolicy: validator\n    .alternatives(\n      validator.string().valid('throw', 'fallback-stash', 'synthetic-description'),\n      validator\n        .object({\n          mode: validator.string().valid('fallback-stash').required(),\n          stashKeys: validator.array().items(validator.string().min(1)).required(),\n        })\n        .unknown(false)\n    )\n    .default('throw'),\n  localToolCallParser: validator.any().optional(),\n  onRawGeneration: validator.function().optional(),\n  onPromptAssembled: validator.function().optional(),\n  helpers: validator.object().unknown(true).optional(),\n  forgeToolsFilter: validator.function().optional(),\n})\n\n/**\n * Validate and normalise adapter options.\n *\n * @throws {@link E_INVALID_GEMINI_GENERATE_CONTENT_OPTIONS} when validation fails.\n */\nexport const validateOptions = (input: unknown): GeminiGenerateContentAdapterOptions => {\n  const { error, value } = geminiGenerateContentOptionsSchema.validate(input, {\n    allowUnknown: false,\n    stripUnknown: false,\n  })\n  if (error) {\n    throw new E_INVALID_GEMINI_GENERATE_CONTENT_OPTIONS([\n      error.details.map((detail: { message: string }) => detail.message).join(' '),\n    ])\n  }\n  return value as GeminiGenerateContentAdapterOptions\n}\n"],"mappings":"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"}