{"version":3,"file":"validation.cjs","names":[],"sources":["../../../../src/batteries/llm/ollama/validation.ts"],"sourcesContent":["/**\n * Runtime validation schema and wrapper for native Ollama adapter options.\n *\n * @module @nhtio/adk/batteries/llm/ollama/validation\n *\n * @remarks\n * Schema and call-site wrapper for validating `OllamaAdapterOptions`. Used at construction time\n * and at the start of every iteration against the merged options shape (stash > executor >\n * constructor). Throws `E_INVALID_OLLAMA_OPTIONS` on failure — same hard-fail policy as every other\n * ADK contract.\n *\n * Note the deliberate `.unknown(...)` asymmetry: the TOP level is `.unknown(false)` so option typos\n * fail loud, but the nested `options` (runtime/sampling) block is `.unknown(true)` so new llama.cpp\n * parameters pass through without a library bump.\n */\n\nimport { isError } from '@nhtio/adk/guards'\nimport { E_INVALID_OLLAMA_OPTIONS } from './exceptions'\nimport { validator, ValidationError } from '@nhtio/validation'\nimport { byteStoreSchema, TokenEncoding } from '@nhtio/adk/common'\nimport type { OllamaAdapterOptions } from './types'\n\n// ─── Sub-schemas ──────────────────────────────────────────────────────────────\n\nconst jsonSchemaSchema = validator.object().unknown(true)\n\nconst bucketLabelSchema = validator\n  .string()\n  .valid('standingInstructions', 'memories', 'retrievables', 'timeline')\n\nconst bucketOrderSchema = validator\n  .array()\n  .items(bucketLabelSchema)\n  .unique()\n  .default(['standingInstructions', 'memories', 'retrievables', 'timeline'])\n\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\nconst retrySchema = validator\n  .object({\n    maxAttempts: validator.number().integer().min(1).default(1),\n    baseDelayMs: validator.number().integer().min(0).default(500),\n    maxDelayMs: validator.number().integer().min(1).default(30_000),\n    retriableStatuses: validator\n      .array()\n      .items(validator.number().integer().min(100).max(599))\n      .default([429, 502, 503, 504]),\n    honorRetryAfter: validator.boolean().default(true),\n  })\n  .unknown(false)\n\n// Optional fallback tool-call parser (see OllamaAdapterOptions.localToolCallParser). A bundled family\n// name, 'auto' (try-all), 'none', or a custom ToolCallParserFn. `.optional()` — absent = disabled =\n// native-only behaviour. Names mirror chat_common's ToolCallParserName union.\nconst localToolCallParserSchema = validator\n  .alternatives(\n    validator\n      .string()\n      .valid(\n        'auto',\n        'hermes',\n        'gemma',\n        'gpt_oss',\n        'pythonic',\n        'bare_pythonic',\n        'loose_keyed',\n        'llama3_json',\n        'mistral',\n        'qwen3_coder',\n        'phi',\n        'none'\n      ),\n    validator.function()\n  )\n  .optional()\n\nconst helperSchema = validator.function()\n\nconst helpersSchema = validator\n  .object({\n    descriptionToChatCompletionsJsonSchema: helperSchema.optional(),\n    renderUntrustedContent: helperSchema.optional(),\n    renderTrustedContent: helperSchema.optional(),\n    renderStandingInstructions: helperSchema.optional(),\n    renderMemories: helperSchema.optional(),\n    renderRetrievables: helperSchema.optional(),\n    renderRetrievableHandleBody: helperSchema.optional(),\n    renderRetrievableSafetyDirective: helperSchema.optional(),\n    renderFirstPartyRetrievables: helperSchema.optional(),\n    renderThirdPartyPublicRetrievables: helperSchema.optional(),\n    renderThirdPartyPrivateRetrievables: helperSchema.optional(),\n    renderThought: helperSchema.optional(),\n    filterThoughts: helperSchema.optional(),\n    toolsToChatCompletionsTools: helperSchema.optional(),\n    renderChatCompletionsSystemPrompt: helperSchema.optional(),\n    renderOllamaTimelineMessage: helperSchema.optional(),\n    renderOllamaToolCallResult: helperSchema.optional(),\n    buildOllamaHistory: helperSchema.optional(),\n  })\n  .unknown(false)\n\n// ─── Native request-body sub-schemas ──────────────────────────────────────────\n\nconst thinkSchema = validator.alternatives(\n  validator.boolean(),\n  validator.string().valid('low', 'medium', 'high')\n)\n\nconst formatSchema = validator.alternatives(validator.string().valid('json'), jsonSchemaSchema)\n\nconst keepAliveSchema = validator.alternatives(validator.string(), validator.number())\n\nconst stopSchema = validator.alternatives(\n  validator.string(),\n  validator.array().items(validator.string())\n)\n\n// Nested runtime/sampling options block. `.unknown(true)` — the ONLY place unknown keys are\n// allowed — so new llama.cpp parameters pass through without a library bump.\nconst runtimeOptionsSchema = validator\n  .object({\n    num_ctx: validator.number().integer().min(1).optional(),\n    temperature: validator.number().min(0).optional(),\n    top_p: validator.number().min(0).max(1).optional(),\n    top_k: validator.number().integer().min(0).optional(),\n    min_p: validator.number().min(0).max(1).optional(),\n    typical_p: validator.number().min(0).max(1).optional(),\n    seed: validator.number().integer().optional(),\n    stop: stopSchema.optional(),\n    num_predict: validator.number().integer().optional(),\n    num_keep: validator.number().integer().min(0).optional(),\n    repeat_penalty: validator.number().optional(),\n    repeat_last_n: validator.number().integer().optional(),\n    presence_penalty: validator.number().optional(),\n    frequency_penalty: validator.number().optional(),\n    penalize_newline: validator.boolean().optional(),\n    num_batch: validator.number().integer().min(1).optional(),\n    num_gpu: validator.number().integer().min(0).optional(),\n    main_gpu: validator.number().integer().min(0).optional(),\n    num_thread: validator.number().integer().min(1).optional(),\n    numa: validator.boolean().optional(),\n    use_mmap: validator.boolean().optional(),\n  })\n  .unknown(true)\n\n// ─── Top-level schema ─────────────────────────────────────────────────────────\n\n/**\n * Validator schema for `OllamaAdapterOptions`. Used by `validateOptions` at construction time and\n * again at the start of every iteration after options have been merged (stash > executor >\n * constructor). Rejects unknown top-level keys so typos fail loud.\n */\nexport const ollamaOptionsSchema = validator\n  .object<OllamaAdapterOptions>({\n    // ADK control\n    apiKey: validator.string().optional(),\n    baseURL: validator.string().optional(),\n    headers: validator.object().pattern(validator.string(), validator.string()).optional(),\n    fetch: validator.function().optional(),\n    stream: validator.boolean().default(true),\n    streamIdleTimeoutMs: validator.number().integer().min(0).default(0),\n    requestTimeoutMs: validator.number().integer().min(0).default(0),\n    retry: retrySchema.optional(),\n    bucketOrder: bucketOrderSchema,\n    contextWindow: validator.number().integer().min(1).optional(),\n    selfIdentity: validator.string().min(1).default('assistant'),\n    thoughtSurfacing: validator\n      .string()\n      .valid('all-self', 'latest-self', 'all')\n      .default('all-self'),\n    tokenEncoding: tokenEncodingSchema,\n    replayCompatibility: validator.array().items(validator.string().min(1)).default([]),\n    helpers: helpersSchema.optional(),\n    spoolStore: byteStoreSchema.optional(),\n    // Opt-in: the executor only self-acks tool-call-free responses when true. Default false hands\n    // turn-completion control to the implementor's output pipeline.\n    autoAck: validator.boolean().default(false),\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\n    // Native /api/chat request body\n    model: validator.string().required(),\n    think: thinkSchema.optional(),\n    format: formatSchema.optional(),\n    options: runtimeOptionsSchema.optional(),\n    keep_alive: keepAliveSchema.optional(),\n    onRawGeneration: validator.function().optional(),\n    onPromptAssembled: validator.function().optional(),\n    localToolCallParser: localToolCallParserSchema,\n    toolCallIdFilter: validator.function().optional(),\n    forgeToolsFilter: validator.function().optional(),\n  })\n  .unknown(false)\n\nconst isValidationError = (value: unknown): value is ValidationError =>\n  isError(value) && Array.isArray((value as ValidationError).details)\n\nconst formatValidationDetails = (err: ValidationError): string =>\n  err.details.map((d) => d.message).join(' and ')\n\n/**\n * Validates an arbitrary input against `ollamaOptionsSchema` and returns the resolved options\n * shape. Throws `E_INVALID_OLLAMA_OPTIONS` (carrying the validator's error report on `cause`) on\n * failure.\n *\n * @param input - The raw options object to validate.\n * @returns The resolved options object with defaults filled in.\n */\nexport const validateOptions = (input: unknown): OllamaAdapterOptions => {\n  const { value, error } = ollamaOptionsSchema.validate(input, {\n    abortEarly: false,\n    convert: false,\n  })\n  if (error) {\n    throw new E_INVALID_OLLAMA_OPTIONS([formatValidationDetails(error)], { cause: error })\n  }\n  return value as OllamaAdapterOptions\n}\n\n// suppress unused import warning when the alias isn't referenced\nvoid isValidationError\n"],"mappings":"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"}