{"version":3,"file":"validation.cjs","names":[],"sources":["../../../../src/batteries/llm/transformers_js/validation.ts"],"sourcesContent":["/**\n * Runtime validation schema and wrapper for transformers.js LLM adapter options.\n *\n * @module @nhtio/adk/batteries/llm/transformers_js/validation\n */\n\nimport { isError } from '@nhtio/adk/guards'\nimport { validator, ValidationError } from '@nhtio/validation'\nimport { E_INVALID_TRANSFORMERS_JS_OPTIONS } from './exceptions'\nimport { byteStoreSchema, TokenEncoding } from '@nhtio/adk/common'\nimport type { TransformersJsAdapterOptions } from './types'\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 reasoningFieldPrecedenceSchema = validator\n  .array()\n  .items(validator.string().valid('reasoning', 'reasoning_content'))\n  .unique()\n  .min(1)\n  .default(['reasoning', 'reasoning_content'])\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 helperSchema = validator.function()\n\nconst helpersSchema = validator\n  .object({\n    descriptionToChatCompletionsJsonSchema: helperSchema.optional(),\n    renderUntrustedContent: helperSchema.optional(),\n    renderTrustedContent: helperSchema.optional(),\n    renderArtifactHandleBody: helperSchema.optional(),\n    renderRetrievableHandleBody: helperSchema.optional(),\n    renderStandingInstructions: helperSchema.optional(),\n    renderMemories: helperSchema.optional(),\n    renderRetrievables: helperSchema.optional(),\n    renderRetrievableSafetyDirective: helperSchema.optional(),\n    renderFirstPartyRetrievables: helperSchema.optional(),\n    renderThirdPartyPublicRetrievables: helperSchema.optional(),\n    renderThirdPartyPrivateRetrievables: helperSchema.optional(),\n    renderTimelineMessage: helperSchema.optional(),\n    renderThought: helperSchema.optional(),\n    filterThoughts: helperSchema.optional(),\n    toolsToChatCompletionsTools: helperSchema.optional(),\n    renderChatCompletionsSystemPrompt: helperSchema.optional(),\n    renderChatCompletionsToolCallResult: helperSchema.optional(),\n    buildChatCompletionsHistory: helperSchema.optional(),\n    createChatCompletionsToolCallDeltaAccumulator: helperSchema.optional(),\n  })\n  .unknown(false)\n\nconst unsupportedMediaPolicySchema = 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\nconst toolCallParserSchema = validator\n  .alternatives(\n    validator\n      .string()\n      .valid(\n        'auto',\n        'hermes',\n        'gemma',\n        'gpt_oss',\n        'pythonic',\n        'llama3_json',\n        'mistral',\n        'qwen3_coder',\n        'phi',\n        'none'\n      ),\n    validator.function()\n  )\n  .default('auto')\n\nconst reasoningParserSchema = validator\n  .alternatives(\n    validator.string().valid('auto', 'think_tag', 'harmony_analysis', 'gemma_channel', 'none'),\n    validator.function()\n  )\n  .default('auto')\n\n/**\n * Validator schema for {@link TransformersJsAdapterOptions}. Rejects unknown keys (`.unknown(false)`)\n * and fills in defaults.\n */\nexport const transformersJsOptionsSchema = validator\n  .object<TransformersJsAdapterOptions>({\n    // ── Engine ──\n    model: validator.string().min(1).required(),\n    // The transformers.js pipeline is a callable object — accept either a function or an object.\n    pipeline: validator\n      .alternatives(validator.function(), validator.object().unknown(true))\n      .optional(),\n    createPipeline: validator.function().optional(),\n    createStreamer: validator.function().optional(),\n    // device/dtype: a scalar string OR a per-submodule Record (multimodal).\n    device: validator.alternatives(validator.string(), validator.object().unknown(true)).optional(),\n    dtype: validator.alternatives(validator.string(), validator.object().unknown(true)).optional(),\n    // ONNX Runtime session options, forwarded verbatim to the loader. Open object — the runtime owns the\n    // shape; we surface the lever without re-validating ORT's evolving option set.\n    sessionOptions: validator.object().unknown(true).optional(),\n    // KV-cache GPU-pin default. Left optional (NOT .default(true)) so the adapter's own `?? true` sees\n    // `undefined` vs explicit `false` distinctly; the effective default is true, applied in the adapter.\n    pinKvCacheToGpu: validator.boolean().optional(),\n    onInitProgress: validator.function().optional(),\n    isAvailable: validator.function().optional(),\n    // ── Multimodal (opt-in) ──\n    multimodal: validator\n      .alternatives(\n        validator.boolean(),\n        validator.object({ image: validator.boolean(), audio: validator.boolean() }).unknown(false)\n      )\n      .optional(),\n    multimodalEngine: validator.object().unknown(true).optional(),\n    createMultimodal: validator.function().optional(),\n    modelSource: validator.function().optional(),\n    // ── Lifecycle hooks (opt-in, normalized phase machine; additive over onInitProgress) ──\n    onLifecycle: validator.function().optional(),\n    onLoading: validator.function().optional(),\n    onCompiling: validator.function().optional(),\n    onReady: validator.function().optional(),\n    onGenerating: validator.function().optional(),\n    onComplete: validator.function().optional(),\n    onError: validator.function().optional(),\n    // ── Generation: PORTABLE canonical contract (shared with LiteRT-LM) ──\n    // Optional (no defaults here) — the resolver fills defaults and applies canonical-wins precedence so\n    // the native fields below still work as escape hatches.\n    maxTokens: validator.number().integer().min(1).optional(),\n    sampler: validator.string().valid('greedy', 'top-k', 'top-p').optional(),\n    seed: validator.number().integer().optional(),\n    // ── Generation: transformers.js-NATIVE escape hatches ── (explicit defaults — never let `generate`\n    // guess; the resolver consults these only when the canonical field above is unset) ──\n    maxNewTokens: validator.number().integer().min(1).optional(),\n    doSample: validator.boolean().optional(),\n    temperature: validator.number().min(0).default(0.7),\n    topK: validator.number().integer().min(1).default(40),\n    topP: validator.number().min(0).max(1).default(0.95),\n    repetitionPenalty: validator.number().min(0).default(1.1),\n    stopStrings: validator.array().items(validator.string()).optional(),\n    enableThinking: validator.boolean().default(false),\n    // ── ADK control ──\n    stream: validator.boolean().default(true),\n    bucketOrder: bucketOrderSchema,\n    // Safe context budget (enforced only when `tokenEncoding` is non-null — counting is opt-in, but the\n    // ceiling is pinned so once enabled it never silently exceeds a small on-device model's window).\n    contextWindow: validator.number().integer().min(1).default(4096),\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    reasoningFieldPrecedence: reasoningFieldPrecedenceSchema,\n    helpers: helpersSchema.optional(),\n    spoolStore: byteStoreSchema.optional(),\n    unsupportedMediaPolicy: unsupportedMediaPolicySchema,\n    autoAck: validator.boolean().default(false),\n    toolCallParser: toolCallParserSchema,\n    forgeToolsFilter: validator.function().optional(),\n    reasoningParser: reasoningParserSchema,\n    reasoningOrphanRecovery: validator.boolean().default(true),\n    extractMediaOutputs: validator.function().optional(),\n    onRawGeneration: validator.function().optional(),\n    onPromptAssembled: 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 raw adapter options against {@link transformersJsOptionsSchema}, filling in defaults.\n *\n * @param input - The raw options object to validate.\n * @returns The resolved options object with defaults applied.\n * @throws {@link @nhtio/adk/batteries!E_INVALID_TRANSFORMERS_JS_OPTIONS} when `input` is invalid.\n */\nexport const validateOptions = (input: unknown): TransformersJsAdapterOptions => {\n  const { value, error } = transformersJsOptionsSchema.validate(input, {\n    abortEarly: false,\n    convert: false,\n  })\n  if (error && isValidationError(error)) {\n    throw new E_INVALID_TRANSFORMERS_JS_OPTIONS([formatValidationDetails(error)], { cause: error })\n  }\n  return value as TransformersJsAdapterOptions\n}\n"],"mappings":"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"}