vieval 0.0.6 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +219 -109
- package/dist/bin/vieval.mjs +1 -1
- package/dist/cli/index.mjs +1 -1
- package/dist/{cli-sanbKtQq.mjs → cli-Dao25VxV.mjs} +1186 -162
- package/dist/cli-Dao25VxV.mjs.map +1 -0
- package/dist/config.d.mts +2 -2
- package/dist/config.mjs +1 -1
- package/dist/core/assertions/index.d.mts +1 -1
- package/dist/core/inference-executors/index.mjs +1 -1
- package/dist/core/processors/results/index.d.mts +1 -1
- package/dist/core/runner/index.d.mts +2 -2
- package/dist/core/runner/index.mjs +6 -40
- package/dist/core/runner/index.mjs.map +1 -1
- package/dist/{env--94B0UtW.mjs → env-BFSjny07.mjs} +1 -1
- package/dist/{env--94B0UtW.mjs.map → env-BFSjny07.mjs.map} +1 -1
- package/dist/{index-DBZKkpBe.d.mts → index-BkjyCInx.d.mts} +102 -37
- package/dist/index.d.mts +14 -6
- package/dist/index.mjs +110 -39
- package/dist/index.mjs.map +1 -1
- package/dist/{models-DIGdOUpJ.mjs → models-pBSRUZhY.mjs} +1 -1
- package/dist/{models-DIGdOUpJ.mjs.map → models-pBSRUZhY.mjs.map} +1 -1
- package/dist/plugins/chat-models/index.d.mts +69 -6
- package/dist/plugins/chat-models/index.mjs +62 -6
- package/dist/plugins/chat-models/index.mjs.map +1 -1
- package/dist/{registry-CcKZqDJY.mjs → registry-BHGMxjpA.mjs} +140 -4
- package/dist/registry-BHGMxjpA.mjs.map +1 -0
- package/package.json +2 -1
- package/dist/cli-sanbKtQq.mjs.map +0 -1
- package/dist/registry-CcKZqDJY.mjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../../src/plugins/chat-models/runtime-config.ts","../../../src/plugins/chat-models/telemetry.ts","../../../src/plugins/chat-models/index.ts"],"sourcesContent":["import type { ModelDefinition } from '../../config/models'\nimport type { ChatModelHeaders } from './index'\n\nimport { envFrom, requiredEnvFrom } from '../../core/inference-executors/env'\n\n/**\n * Runtime config consumed by OpenAI-compatible provider constructors.\n */\nexport interface OpenAIChatModelRuntimeConfig {\n /**\n * Resolved inference executor kind.\n */\n inferenceExecutor: 'openai'\n /**\n * Concrete model name.\n */\n model: string\n /**\n * Required API key.\n */\n apiKey: string\n /**\n * Optional base URL override.\n */\n baseURL?: string\n /**\n * Optional request headers.\n */\n headers?: ChatModelHeaders\n}\n\n/**\n * Runtime config consumed by Ollama provider constructors.\n */\nexport interface OllamaChatModelRuntimeConfig {\n /**\n * Resolved inference executor kind.\n */\n inferenceExecutor: 'ollama'\n /**\n * Concrete model name.\n */\n model: string\n /**\n * Optional base URL override.\n */\n baseURL?: string\n /**\n * Optional request headers.\n */\n headers?: ChatModelHeaders\n}\n\n/**\n * Runtime config consumed by OpenRouter provider constructors.\n */\nexport interface OpenRouterChatModelRuntimeConfig {\n /**\n * Resolved inference executor kind.\n */\n inferenceExecutor: 'openrouter'\n /**\n * Concrete model name.\n */\n model: string\n /**\n * Required API key.\n */\n apiKey: string\n /**\n * Optional base URL override.\n */\n baseURL?: string\n /**\n * Optional request headers.\n */\n headers?: ChatModelHeaders\n}\n\n/**\n * Union of normalized runtime configs for supported chat-model executors.\n */\nexport type ChatModelRuntimeConfig\n = OpenAIChatModelRuntimeConfig\n | OllamaChatModelRuntimeConfig\n | OpenRouterChatModelRuntimeConfig\n\nfunction getParameters(model: ModelDefinition): Record<string, unknown> {\n return model.parameters ?? {}\n}\n\nfunction parseOptionalStringParameter(\n parameters: Record<string, unknown>,\n key: string,\n modelId: string,\n): string | undefined {\n const value = parameters[key]\n const normalized = value == null ? undefined : String(value)\n\n return envFrom(normalized, {\n name: `${modelId}.parameters.${key}`,\n type: 'string',\n })\n}\n\nfunction parseRequiredStringParameter(\n parameters: Record<string, unknown>,\n key: string,\n modelId: string,\n): string {\n const value = parameters[key]\n const normalized = value == null ? undefined : String(value)\n\n return requiredEnvFrom(normalized, {\n name: `${modelId}.parameters.${key}`,\n type: 'string',\n })\n}\n\nfunction parseHeadersParameter(\n parameters: Record<string, unknown>,\n modelId: string,\n): ChatModelHeaders | undefined {\n const headers = parameters.headers\n if (headers == null) {\n return undefined\n }\n\n if (typeof headers !== 'object' || Array.isArray(headers)) {\n throw new TypeError(`Invalid ${modelId}.parameters.headers: expected an object.`)\n }\n\n const normalized: Record<string, string | string[]> = {}\n for (const [key, value] of Object.entries(headers as Record<string, unknown>)) {\n if (typeof value === 'string') {\n normalized[key] = value\n continue\n }\n\n if (Array.isArray(value) && value.every(item => typeof item === 'string')) {\n normalized[key] = value\n continue\n }\n\n throw new Error(`Invalid ${modelId}.parameters.headers.${key}: expected string or string[].`)\n }\n\n return normalized\n}\n\n/**\n * Normalizes one configured chat model into runtime executor config.\n *\n * Use when:\n * - eval code needs typed provider constructor options from `context.model()`\n * - model parameters should be validated once with clear error messages\n *\n * Expects:\n * - `model.inferenceExecutorId` to be one of the supported executor ids\n * - required OpenAI fields (apiKey) to exist in `model.parameters`\n *\n * Returns:\n * - validated runtime config union for OpenAI or Ollama\n */\nexport function toChatModelRuntimeConfig(model: ModelDefinition): ChatModelRuntimeConfig {\n const parameters = getParameters(model)\n\n if (model.inferenceExecutorId === 'openai') {\n return {\n apiKey: parseRequiredStringParameter(parameters, 'apiKey', model.id),\n baseURL: parseOptionalStringParameter(parameters, 'baseURL', model.id),\n headers: parseHeadersParameter(parameters, model.id),\n inferenceExecutor: 'openai',\n model: model.model,\n }\n }\n\n if (model.inferenceExecutorId === 'ollama') {\n return {\n baseURL: parseOptionalStringParameter(parameters, 'baseURL', model.id),\n headers: parseHeadersParameter(parameters, model.id),\n inferenceExecutor: 'ollama',\n model: model.model,\n }\n }\n\n if (model.inferenceExecutorId === 'openrouter') {\n return {\n apiKey: parseRequiredStringParameter(parameters, 'apiKey', model.id),\n baseURL: parseOptionalStringParameter(parameters, 'baseURL', model.id),\n headers: parseHeadersParameter(parameters, model.id),\n inferenceExecutor: 'openrouter',\n model: model.model,\n }\n }\n\n throw new Error(`Unsupported chat inference executor \"${model.inferenceExecutorId}\" for model \"${model.id}\".`)\n}\n\n/**\n * Resolves OpenAI runtime config from one resolved run-context model.\n *\n * Use when:\n * - task execution already has `context.model()` output\n * - eval code wants typed OpenAI provider options with a concise helper name\n *\n * Expects:\n * - `model` to resolve to an OpenAI-backed chat model\n *\n * Returns:\n * - validated OpenAI runtime config\n */\nexport function openaiFromRunContext(model: ModelDefinition): OpenAIChatModelRuntimeConfig {\n const runtimeConfig = toChatModelRuntimeConfig(model)\n if (runtimeConfig.inferenceExecutor !== 'openai') {\n throw new Error(`Expected openai model, got \"${runtimeConfig.inferenceExecutor}\" for \"${model.id}\".`)\n }\n\n return runtimeConfig\n}\n\n/**\n * Resolves Ollama runtime config from one resolved run-context model.\n *\n * Use when:\n * - task execution already has `context.model()` output\n * - eval code wants typed Ollama provider options with a concise helper name\n *\n * Expects:\n * - `model` to resolve to an Ollama-backed chat model\n *\n * Returns:\n * - validated Ollama runtime config\n */\nexport function ollamaFromRunContext(model: ModelDefinition): OllamaChatModelRuntimeConfig {\n const runtimeConfig = toChatModelRuntimeConfig(model)\n if (runtimeConfig.inferenceExecutor !== 'ollama') {\n throw new Error(`Expected ollama model, got \"${runtimeConfig.inferenceExecutor}\" for \"${model.id}\".`)\n }\n\n return runtimeConfig\n}\n\n/**\n * Resolves OpenRouter runtime config from one resolved run-context model.\n *\n * Use when:\n * - task execution already has `context.model()` output\n * - eval code wants typed OpenRouter provider options with a concise helper name\n *\n * Expects:\n * - `model` to resolve to an OpenRouter-backed chat model\n *\n * Returns:\n * - validated OpenRouter runtime config\n */\nexport function openrouterFromRunContext(model: ModelDefinition): OpenRouterChatModelRuntimeConfig {\n const runtimeConfig = toChatModelRuntimeConfig(model)\n if (runtimeConfig.inferenceExecutor !== 'openrouter') {\n throw new Error(`Expected openrouter model, got \"${runtimeConfig.inferenceExecutor}\" for \"${model.id}\".`)\n }\n\n return runtimeConfig\n}\n","import type { TaskRunContext } from '../../config/types'\n\nimport { errorMessageFrom } from '@moeru/std'\n\n/**\n * Represents one normalized chat-model tool call.\n *\n * Use when:\n * - report events need tool-call level payloads that remain provider-neutral\n *\n * Expects:\n * - `name` to be stable enough for aggregation and assertion checks\n * - `args` to be JSON-serializable\n */\nexport interface ChatModelToolCall {\n /**\n * Optional provider-assigned tool-call identifier.\n */\n id?: string\n /**\n * Tool name.\n */\n name: string\n /**\n * Parsed tool arguments object/value.\n */\n args: unknown\n}\n\n/**\n * Provider identity attached to chat-model telemetry events.\n */\nexport interface ChatModelTelemetryProvider {\n /**\n * Provider id, for example `openai`.\n */\n id: string\n /**\n * Optional concrete model id/name.\n */\n model?: string\n}\n\n/**\n * Input options for response telemetry emission.\n */\nexport interface EmitChatModelResponseTelemetryOptions {\n /**\n * Optional case id for case-scoped telemetry events.\n */\n caseId?: string\n /**\n * Optional response latency in milliseconds.\n */\n latencyMs?: number\n /**\n * Optional provider identity payload.\n */\n provider?: ChatModelTelemetryProvider\n /**\n * Raw chat-model response object from the inference library/provider.\n */\n response: unknown\n}\n\n/**\n * Input options for request telemetry emission.\n */\nexport interface EmitChatModelRequestTelemetryOptions {\n /**\n * Optional case id for case-scoped telemetry events.\n */\n caseId?: string\n /**\n * Optional request payload metadata.\n */\n data?: unknown\n /**\n * Optional provider identity payload.\n */\n provider?: ChatModelTelemetryProvider\n}\n\n/**\n * Input options for error telemetry emission.\n */\nexport interface EmitChatModelErrorTelemetryOptions {\n /**\n * Optional case id for case-scoped telemetry events.\n */\n caseId?: string\n /**\n * Error payload emitted by the inference client/runtime.\n */\n error: unknown\n /**\n * Optional provider identity payload.\n */\n provider?: ChatModelTelemetryProvider\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | undefined {\n if (value == null || typeof value !== 'object') {\n return undefined\n }\n\n return value as Record<string, unknown>\n}\n\nfunction parseMaybeJson(value: unknown): unknown {\n if (typeof value !== 'string') {\n return value\n }\n\n try {\n return JSON.parse(value)\n }\n catch {\n return value\n }\n}\n\n/**\n * Extracts normalized tool calls from one chat-model response shape.\n *\n * Use when:\n * - downstream scoring, reporting, or analysis should inspect tool call usage\n * - provider payload differences should stay hidden behind one stable shape\n *\n * Returns:\n * - normalized list of `{ id?, name, args }` tool calls\n */\nexport function extractChatModelToolCalls(response: unknown): ChatModelToolCall[] {\n const responseRecord = asRecord(response)\n if (responseRecord == null) {\n return []\n }\n\n const rawToolCalls = responseRecord.toolCalls ?? responseRecord.tool_calls\n if (!Array.isArray(rawToolCalls)) {\n return []\n }\n\n const toolCalls: ChatModelToolCall[] = []\n\n for (const rawToolCall of rawToolCalls) {\n const toolCallRecord = asRecord(rawToolCall)\n if (toolCallRecord == null) {\n continue\n }\n\n const functionPayload = asRecord(toolCallRecord.function)\n const name = typeof toolCallRecord.name === 'string'\n ? toolCallRecord.name\n : typeof functionPayload?.name === 'string'\n ? functionPayload.name\n : undefined\n\n if (name == null || name.length === 0) {\n continue\n }\n\n const rawArgs = toolCallRecord.args\n ?? toolCallRecord.arguments\n ?? functionPayload?.args\n ?? functionPayload?.arguments\n\n toolCalls.push({\n args: parseMaybeJson(rawArgs),\n id: typeof toolCallRecord.id === 'string' ? toolCallRecord.id : undefined,\n name,\n })\n }\n\n return toolCalls\n}\n\n/**\n * Extracts numeric metering dimensions from one chat-model response usage block.\n *\n * Use when:\n * - report events should capture usage dimensions in a modality-neutral map\n *\n * Returns:\n * - numeric dimensions keyed by provider usage field names\n */\nexport function extractMeteringDimensions(response: unknown): Record<string, number> {\n const responseRecord = asRecord(response)\n const usage = asRecord(responseRecord?.usage)\n if (usage == null) {\n return {}\n }\n\n const dimensions: Record<string, number> = {}\n\n for (const [key, value] of Object.entries(usage)) {\n if (typeof value !== 'number' || Number.isNaN(value)) {\n continue\n }\n\n dimensions[key] = value\n }\n\n return dimensions\n}\n\n/**\n * Emits chat-model response telemetry as reportable task events.\n *\n * Use when:\n * - task code receives one chat-model response and wants standardized report events\n * - `ToolCall*` and metering metrics should be persisted in `events.jsonl`\n *\n * Expects:\n * - `context.reporterHooks?.onEvent` to be available in CLI execution paths\n *\n * Returns:\n * - no return value; this is a best-effort reporting helper\n */\nexport function emitChatModelResponseTelemetry(\n context: TaskRunContext,\n options: EmitChatModelResponseTelemetryOptions,\n): void {\n const toolCalls = extractChatModelToolCalls(options.response)\n const meteringDimensions = extractMeteringDimensions(options.response)\n\n if (toolCalls.length > 0) {\n meteringDimensions.tool_call_count = toolCalls.length\n }\n\n const data = {\n metering: {\n dimensions: meteringDimensions,\n latency_ms: options.latencyMs,\n },\n metrics: {\n 'vieval.chat.tool_call_count': toolCalls.length,\n },\n modality: 'chat',\n provider: options.provider,\n toolCalls,\n }\n\n context.reporterHooks?.onEvent?.({\n caseId: options.caseId,\n data,\n event: 'InferenceResponse',\n })\n\n for (const toolCall of toolCalls) {\n context.reporterHooks?.onEvent?.({\n caseId: options.caseId,\n data: {\n modality: 'chat',\n provider: options.provider,\n toolCall,\n },\n event: 'ToolCallStarted',\n })\n context.reporterHooks?.onEvent?.({\n caseId: options.caseId,\n data: {\n modality: 'chat',\n provider: options.provider,\n toolCall,\n },\n event: 'ToolCallEnded',\n })\n }\n}\n\n/**\n * Emits chat-model request telemetry as a reportable task event.\n *\n * Use when:\n * - task code submits one model request and wants request-side traceability\n *\n * Expects:\n * - `context.reporterHooks?.onEvent` to be available in CLI execution paths\n */\nexport function emitChatModelRequestTelemetry(\n context: TaskRunContext,\n options: EmitChatModelRequestTelemetryOptions,\n): void {\n context.reporterHooks?.onEvent?.({\n caseId: options.caseId,\n data: {\n data: options.data,\n modality: 'chat',\n provider: options.provider,\n },\n event: 'InferenceRequest',\n })\n}\n\n/**\n * Emits chat-model failure telemetry as a reportable task event.\n *\n * Use when:\n * - one inference call fails and report artifacts should include normalized error context\n *\n * Expects:\n * - `context.reporterHooks?.onEvent` to be available in CLI execution paths\n */\nexport function emitChatModelErrorTelemetry(\n context: TaskRunContext,\n options: EmitChatModelErrorTelemetryOptions,\n): void {\n context.reporterHooks?.onEvent?.({\n caseId: options.caseId,\n data: {\n error: errorMessageFrom(options.error) ?? 'Unknown inference error.',\n modality: 'chat',\n provider: options.provider,\n },\n event: 'InferenceError',\n })\n}\n","import type { MatrixDefinition, TaskExecutionPolicy } from '../../config'\nimport type { ModelDefinition } from '../../config/models'\nimport type { ConfigHookPlugin } from '../../config/plugin'\nimport type { EnvFromOptions, RequiredEnvFromOptions } from '../../core/inference-executors/env'\n\nimport process from 'node:process'\n\nimport { envFrom, requiredEnvFrom } from '../../core/inference-executors/env'\n\n/**\n * Minimal inference-executor shape expected by chat model runtime callers.\n */\nexport interface ChatModelExecutorLike {\n chat: (model: string) => Record<string, unknown>\n}\n\n/**\n * Inference-executor input accepted by `chatModelFrom`.\n */\nexport type ChatModelExecutorInput = string | ChatModelExecutorLike\n\n/**\n * Chat-model header payload accepted by executor parameters.\n */\nexport type ChatModelHeaders = Record<string, string | string[]>\n\n/**\n * Runtime env context passed to model callback resolvers.\n */\nexport interface ChatModelResolverContext {\n env: Record<string, string>\n}\n\n/**\n * Value-or-callback resolver used by model runtime fields.\n */\nexport type ChatModelResolverValue<TValue> = TValue | ((config: ChatModelResolverContext) => Promise<TValue> | TValue)\n\n/**\n * OpenAI-specific inference executor config shape.\n */\nexport interface OpenAIChatModelInferenceExecutor {\n inferenceExecutor: 'openai'\n apiKey?: ChatModelResolverValue<string>\n baseURL?: ChatModelResolverValue<string>\n headers?: ChatModelResolverValue<ChatModelHeaders>\n}\n\n/**\n * Ollama-specific inference executor config shape.\n */\nexport interface OllamaChatModelInferenceExecutor {\n inferenceExecutor: 'ollama'\n baseURL?: ChatModelResolverValue<string>\n headers?: ChatModelResolverValue<ChatModelHeaders>\n}\n\n/**\n * OpenRouter-specific inference executor config shape.\n */\nexport interface OpenRouterChatModelInferenceExecutor {\n inferenceExecutor: 'openrouter'\n apiKey?: ChatModelResolverValue<string>\n baseURL?: ChatModelResolverValue<string>\n headers?: ChatModelResolverValue<ChatModelHeaders>\n}\n\n/**\n * Generic inference executor config shape.\n */\nexport interface GenericChatModelInferenceExecutor {\n inferenceExecutor?: ChatModelExecutorInput\n}\n\n/**\n * Union of supported inference executor config shapes for `chatModelFrom`.\n */\nexport type ChatModelInferenceExecutor\n = OpenAIChatModelInferenceExecutor\n | OllamaChatModelInferenceExecutor\n | OpenRouterChatModelInferenceExecutor\n | GenericChatModelInferenceExecutor\n\n/**\n * Common builder input fields for `chatModelFrom`.\n */\nexport interface ChatModelFromBaseOptions {\n /**\n * Provider id registered through `ChatProviders`.\n *\n * Use when:\n * - model runtime transport and credentials should be delegated to a named provider preset\n *\n * Expects:\n * - one `ChatProviders` plugin entry to expose the same id\n */\n provider?: string\n /**\n * Inference-executor id or inference-executor instance.\n */\n inferenceExecutor?: ChatModelExecutorInput\n /**\n * Optional explicit inference-executor id for inference-executor instances.\n *\n * @default 'custom'\n */\n inferenceExecutorId?: string\n /**\n * Concrete model name.\n */\n model: string\n /**\n * Optional stable model id.\n *\n * @default `${inferenceExecutorId}:${model}`\n */\n id?: string\n /**\n * Alias names used by `resolveModelByName`.\n */\n aliases?: string[]\n /**\n * Optional execution policy hints attached to this model.\n */\n executionPolicy?: TaskExecutionPolicy\n /**\n * Additional retries allowed within the current attempt.\n *\n * @default 0\n */\n autoRetry?: number\n /**\n * Additional full task attempts allowed after the current attempt settles.\n *\n * @default 0\n */\n autoAttempt?: number\n /**\n * Timeout in milliseconds for model-backed work.\n */\n timeout?: number\n /**\n * Optional model-level call parameters.\n */\n parameters?: Record<string, unknown>\n}\n\n/**\n * Builder input for `chatModelFrom`.\n */\nexport type ChatModelFromOptions = ChatModelInferenceExecutor & ChatModelFromBaseOptions\n\n/**\n * Chat-model specific specialization of the canonical `ModelDefinition`.\n */\nexport type ChatModelDefinition = Omit<ModelDefinition, 'inferenceExecutor'> & {\n inferenceExecutor: ChatModelExecutorInput\n provider?: string\n runtimeResolvers?: {\n apiKey?: ChatModelResolverValue<string>\n baseURL?: ChatModelResolverValue<string>\n headers?: ChatModelResolverValue<ChatModelHeaders>\n }\n}\n\nfunction normalizeExecutionPolicy(\n policy: TaskExecutionPolicy | undefined,\n): TaskExecutionPolicy | undefined {\n if (policy == null) {\n return undefined\n }\n\n const normalized = {\n autoAttempt: policy.autoAttempt,\n autoRetry: policy.autoRetry,\n timeout: policy.timeout,\n }\n\n return Object.values(normalized).some(value => value != null)\n ? normalized\n : undefined\n}\n\nfunction hasJudgeAlias(model: Pick<ChatModelFromBaseOptions, 'aliases' | 'id' | 'model'>): boolean {\n return [\n ...(model.aliases ?? []),\n ...(model.id == null ? [] : [model.id]),\n model.model,\n ].some(value => value.toLowerCase().includes('judge'))\n}\n\nfunction resolveModelExecutionPolicy(options: ChatModelFromOptions): TaskExecutionPolicy | undefined {\n const explicitPolicy = normalizeExecutionPolicy({\n autoAttempt: options.autoAttempt ?? options.executionPolicy?.autoAttempt,\n autoRetry: options.autoRetry ?? options.executionPolicy?.autoRetry,\n timeout: options.timeout ?? options.executionPolicy?.timeout,\n })\n\n if (explicitPolicy != null && Object.keys(explicitPolicy).length > 0) {\n return explicitPolicy\n }\n\n if (hasJudgeAlias(options)) {\n return {\n autoRetry: 3,\n }\n }\n\n return undefined\n}\n\n/**\n * Env-key map for optional provider parameters.\n *\n * Use when:\n * - provider parameter values should be read from env keys\n * - missing keys should resolve to `undefined`\n */\nexport type OptionalProviderEnvMap = Record<string, string>\n\n/**\n * Env-key map for required provider parameters.\n *\n * Use when:\n * - provider parameter values must exist before model execution\n * - missing keys should throw with key-aware error messages\n */\nexport type RequiredProviderEnvMap = Record<string, string>\n\n/**\n * One provider definition consumed by chat model presets.\n */\nexport interface ChatProviderDefinition {\n /**\n * Stable provider id referenced by `chatModelFrom({ provider })`.\n */\n id: string\n /**\n * Inference-executor id or instance used by this provider preset.\n */\n inferenceExecutor: ChatModelExecutorInput\n /**\n * Optional explicit inference-executor id for inference-executor instances.\n *\n * @default 'custom'\n */\n inferenceExecutorId?: string\n /**\n * Optional literal provider-level parameters.\n */\n parameters?: Record<string, unknown>\n /**\n * Optional provider parameters resolved via `envFrom`.\n *\n * Expects:\n * - map key is the provider parameter name\n * - map value is the env key name\n */\n optionalEnv?: OptionalProviderEnvMap\n /**\n * Required provider parameters resolved via `requiredEnvFrom`.\n *\n * Expects:\n * - map key is the provider parameter name\n * - map value is the env key name\n */\n requiredEnv?: RequiredProviderEnvMap\n}\n\n/**\n * Builder input for `chatProviderFrom`.\n */\nexport interface ChatProviderFromOptions extends ChatProviderDefinition {\n}\n\n/**\n * Options for the built-in `ChatProviders` plugin.\n */\nexport interface ChatProvidersPluginOptions {\n /**\n * Provider definitions to append to config.\n */\n providers: readonly ChatProviderDefinition[]\n /**\n * Optional explicit env source used for env-backed provider parameters.\n *\n * @default process.env\n */\n env?: NodeJS.ProcessEnv\n}\n\n/**\n * Partial config shape needed by the chat models plugin.\n */\nexport interface PluginConfig {\n env?: NodeJS.ProcessEnv\n chatProviders?: ChatProviderDefinition[]\n models?: ModelDefinition[]\n}\n\n/**\n * Plugin type bound to the minimal config shape used by model plugins.\n */\nexport type Plugin = ConfigHookPlugin<PluginConfig>\n\nfunction normalizeInferenceExecutorId(\n inferenceExecutor: ChatModelExecutorInput,\n inferenceExecutorId: string | undefined,\n): string {\n if (typeof inferenceExecutor === 'string') {\n return inferenceExecutor\n }\n\n return inferenceExecutorId ?? 'custom'\n}\n\nfunction createDefaultModelId(inferenceExecutorId: string, model: string): string {\n return `${inferenceExecutorId}:${model}`\n}\n\nfunction normalizeEnvRecord(env: NodeJS.ProcessEnv): Record<string, string> {\n const normalized: Record<string, string> = {}\n for (const [key, value] of Object.entries(env)) {\n if (typeof value === 'string') {\n normalized[key] = value\n }\n }\n\n return normalized\n}\n\nasync function resolveChatModelResolverValue<TValue>(\n value: ChatModelResolverValue<TValue>,\n context: ChatModelResolverContext,\n): Promise<TValue> {\n if (typeof value === 'function') {\n const resolver = value as (config: ChatModelResolverContext) => Promise<TValue> | TValue\n return await resolver(context)\n }\n\n return value\n}\n\nfunction resolveRequiredStringValue(value: string | undefined, name: string): string {\n return requiredEnvFrom(value, {\n name,\n type: 'string',\n })\n}\n\nfunction resolveOptionalStringValue(value: string | undefined, name: string): string | undefined {\n return envFrom(value, {\n name,\n type: 'string',\n })\n}\n\nfunction resolveOptionalEnvValue(\n env: NodeJS.ProcessEnv,\n envKey: string,\n): string | undefined {\n const options: EnvFromOptions = {\n name: envKey,\n type: 'string',\n }\n\n return envFrom(env[envKey], options)\n}\n\nfunction resolveRequiredEnvValue(\n env: NodeJS.ProcessEnv,\n envKey: string,\n): string {\n const options: RequiredEnvFromOptions = {\n name: envKey,\n type: 'string',\n }\n\n return requiredEnvFrom(env[envKey], options)\n}\n\nfunction resolveProviderParameters(\n provider: ChatProviderDefinition,\n env: NodeJS.ProcessEnv,\n): Record<string, unknown> | undefined {\n const parameters: Record<string, unknown> = {\n ...provider.parameters,\n }\n\n for (const [parameterName, envKey] of Object.entries(provider.optionalEnv ?? {})) {\n const resolved = resolveOptionalEnvValue(env, envKey)\n if (resolved != null) {\n parameters[parameterName] = resolved\n }\n }\n\n for (const [parameterName, envKey] of Object.entries(provider.requiredEnv ?? {})) {\n parameters[parameterName] = resolveRequiredEnvValue(env, envKey)\n }\n\n return Object.keys(parameters).length > 0 ? parameters : undefined\n}\n\nfunction normalizeChatProviderDefinition(\n provider: ChatProviderDefinition,\n env: NodeJS.ProcessEnv,\n): ChatProviderDefinition {\n return {\n id: provider.id,\n inferenceExecutor: provider.inferenceExecutor,\n inferenceExecutorId: normalizeInferenceExecutorId(provider.inferenceExecutor, provider.inferenceExecutorId),\n optionalEnv: provider.optionalEnv,\n parameters: resolveProviderParameters(provider, env),\n requiredEnv: provider.requiredEnv,\n }\n}\n\nfunction createProviderMap(config: PluginConfig): Map<string, ChatProviderDefinition> {\n const providerMap = new Map<string, ChatProviderDefinition>()\n for (const provider of config.chatProviders ?? []) {\n providerMap.set(provider.id, provider)\n }\n\n return providerMap\n}\n\nfunction resolveModelProvider(\n model: ChatModelDefinition,\n providerMap: ReadonlyMap<string, ChatProviderDefinition>,\n): ChatModelDefinition {\n if (model.provider == null) {\n return model\n }\n\n const provider = providerMap.get(model.provider)\n if (provider == null) {\n throw new Error(`Unknown chat provider \"${model.provider}\" referenced by model \"${model.id}\".`)\n }\n\n return {\n ...model,\n inferenceExecutor: provider.inferenceExecutor,\n inferenceExecutorId: provider.inferenceExecutorId ?? normalizeInferenceExecutorId(provider.inferenceExecutor, provider.inferenceExecutorId),\n parameters: {\n ...provider.parameters,\n ...model.parameters,\n },\n }\n}\n\nasync function resolveModelRuntimeResolvers(\n model: ChatModelDefinition,\n context: ChatModelResolverContext,\n): Promise<Record<string, unknown> | undefined> {\n if (model.runtimeResolvers == null) {\n return undefined\n }\n\n const resolvedParameters: Record<string, unknown> = {}\n\n if (model.runtimeResolvers.apiKey != null) {\n const resolvedApiKey = await resolveChatModelResolverValue(model.runtimeResolvers.apiKey, context)\n resolvedParameters.apiKey = resolveRequiredStringValue(resolvedApiKey, `${model.id}.apiKey`)\n }\n\n if (model.runtimeResolvers.baseURL != null) {\n const resolvedBaseURL = await resolveChatModelResolverValue(model.runtimeResolvers.baseURL, context)\n const normalizedBaseURL = resolveOptionalStringValue(resolvedBaseURL, `${model.id}.baseURL`)\n if (normalizedBaseURL != null) {\n resolvedParameters.baseURL = normalizedBaseURL\n }\n }\n\n if (model.runtimeResolvers.headers != null) {\n const resolvedHeaders = await resolveChatModelResolverValue(model.runtimeResolvers.headers, context)\n resolvedParameters.headers = resolvedHeaders\n }\n\n return Object.keys(resolvedParameters).length > 0 ? resolvedParameters : undefined\n}\n\nasync function resolveChatModelDefinition(\n model: ChatModelDefinition,\n config: PluginConfig,\n): Promise<ChatModelDefinition> {\n const providerResolvedModel = resolveModelProvider(model, createProviderMap(config))\n const resolvedRuntimeParameters = await resolveModelRuntimeResolvers(providerResolvedModel, {\n env: normalizeEnvRecord(config.env ?? process.env),\n })\n\n if (resolvedRuntimeParameters == null) {\n return providerResolvedModel\n }\n\n return {\n ...providerResolvedModel,\n parameters: {\n ...providerResolvedModel.parameters,\n ...resolvedRuntimeParameters,\n },\n }\n}\n\nfunction isOpenAIChatModelInferenceExecutor(\n options: ChatModelFromOptions,\n): options is ChatModelFromBaseOptions & OpenAIChatModelInferenceExecutor {\n return options.inferenceExecutor === 'openai'\n}\n\nfunction isOllamaChatModelInferenceExecutor(\n options: ChatModelFromOptions,\n): options is ChatModelFromBaseOptions & OllamaChatModelInferenceExecutor {\n return options.inferenceExecutor === 'ollama'\n}\n\nfunction isOpenRouterChatModelInferenceExecutor(\n options: ChatModelFromOptions,\n): options is ChatModelFromBaseOptions & OpenRouterChatModelInferenceExecutor {\n return options.inferenceExecutor === 'openrouter'\n}\n\n/**\n * Builds one normalized chat model definition.\n *\n * Use when:\n * - registering chat models through config plugins\n * - a single model needs aliases for matrix selection or judge lookup\n */\nexport function chatModelFrom(options: ChatModelFromOptions): ChatModelDefinition {\n const fallbackInferenceExecutor = options.inferenceExecutor ?? options.provider ?? 'custom'\n const inferenceExecutorId = normalizeInferenceExecutorId(fallbackInferenceExecutor, options.inferenceExecutorId)\n const runtimeResolvers = isOpenAIChatModelInferenceExecutor(options)\n ? {\n apiKey: options.apiKey,\n baseURL: options.baseURL,\n headers: options.headers,\n }\n : isOllamaChatModelInferenceExecutor(options)\n ? {\n baseURL: options.baseURL,\n headers: options.headers,\n }\n : isOpenRouterChatModelInferenceExecutor(options)\n ? {\n apiKey: options.apiKey,\n baseURL: options.baseURL,\n headers: options.headers,\n }\n : undefined\n\n return {\n aliases: options.aliases ?? [],\n executionPolicy: resolveModelExecutionPolicy(options),\n id: options.id ?? createDefaultModelId(inferenceExecutorId, options.model),\n inferenceExecutor: fallbackInferenceExecutor,\n inferenceExecutorId,\n model: options.model,\n parameters: options.parameters,\n provider: options.provider,\n runtimeResolvers,\n }\n}\n\n/**\n * Builds one normalized chat provider definition.\n *\n * Use when:\n * - one provider preset should be reused across multiple chat models\n * - provider configuration should support required/optional env-backed parameters\n */\nexport function chatProviderFrom(options: ChatProviderFromOptions): ChatProviderDefinition {\n return {\n id: options.id,\n inferenceExecutor: options.inferenceExecutor,\n inferenceExecutorId: normalizeInferenceExecutorId(options.inferenceExecutor, options.inferenceExecutorId),\n optionalEnv: options.optionalEnv,\n parameters: options.parameters,\n requiredEnv: options.requiredEnv,\n }\n}\n\n/**\n * Options for the built-in `ChatModels` plugin.\n */\nexport interface ChatModelsPluginOptions {\n /**\n * Chat model definitions to append to config.\n */\n models: readonly ChatModelDefinition[]\n}\n\n/**\n * Creates a run-matrix `model` axis from configured chat model names.\n *\n * Use when:\n * - run matrix should iterate over explicit chat model ids/aliases\n * - project configs want a concise model-axis helper\n *\n * Expects:\n * - each provided name to match a configured model id or alias at runtime\n *\n * Returns:\n * - matrix axis object compatible with `runMatrix.extend/override`\n */\nexport function chatModelMatrix(...names: string[]): MatrixDefinition {\n return {\n model: Array.from(new Set(names)),\n }\n}\n\n/**\n * Built-in chat providers plugin that contributes provider presets to config.\n *\n * Use when:\n * - provider runtime config should be centralized and reusable\n * - provider parameters should be resolved from env via `envFrom`/`requiredEnvFrom`\n */\nexport function ChatProviders(options: ChatProvidersPluginOptions): Plugin {\n return {\n configVieval(config) {\n const env = config.env ?? options.env ?? process.env\n const normalizedProviders = options.providers.map(provider => normalizeChatProviderDefinition(provider, env))\n\n return {\n ...config,\n chatProviders: [\n ...(config.chatProviders ?? []),\n ...normalizedProviders,\n ],\n }\n },\n name: 'vieval:chat-providers',\n }\n}\n\n/**\n * Built-in chat models plugin that contributes model definitions to vieval config.\n *\n * Use when:\n * - chat-model registration should stay in config-level plugin setup\n * - tasks and assertions resolve models by name or alias at runtime\n */\nexport function ChatModels(options: ChatModelsPluginOptions): Plugin {\n return {\n async configVieval(config) {\n const resolvedModels = await Promise.all(options.models.map(async model => resolveChatModelDefinition(model, config)))\n\n return {\n ...config,\n models: [\n ...(config.models ?? []),\n ...resolvedModels,\n ],\n }\n },\n name: 'vieval:chat-models',\n }\n}\n\nexport * from './runtime-config'\nexport * from './telemetry'\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../../src/plugins/chat-models/runtime-config.ts","../../../src/plugins/chat-models/telemetry.ts","../../../src/plugins/chat-models/index.ts"],"sourcesContent":["import type { ModelDefinition } from '../../config/models'\nimport type { ChatModelHeaders } from './index'\n\nimport { envFrom, requiredEnvFrom } from '../../core/inference-executors/env'\n\n/**\n * Runtime config consumed by OpenAI-compatible provider constructors.\n */\nexport interface OpenAIChatModelRuntimeConfig {\n /**\n * Resolved inference executor kind.\n */\n inferenceExecutor: 'openai'\n /**\n * Concrete model name.\n */\n model: string\n /**\n * Required API key.\n */\n apiKey: string\n /**\n * Optional base URL override.\n */\n baseURL?: string\n /**\n * Optional request headers.\n */\n headers?: ChatModelHeaders\n}\n\n/**\n * Runtime config consumed by Ollama provider constructors.\n */\nexport interface OllamaChatModelRuntimeConfig {\n /**\n * Resolved inference executor kind.\n */\n inferenceExecutor: 'ollama'\n /**\n * Concrete model name.\n */\n model: string\n /**\n * Optional base URL override.\n */\n baseURL?: string\n /**\n * Optional request headers.\n */\n headers?: ChatModelHeaders\n}\n\n/**\n * Runtime config consumed by OpenRouter provider constructors.\n */\nexport interface OpenRouterChatModelRuntimeConfig {\n /**\n * Resolved inference executor kind.\n */\n inferenceExecutor: 'openrouter'\n /**\n * Concrete model name.\n */\n model: string\n /**\n * Required API key.\n */\n apiKey: string\n /**\n * Optional base URL override.\n */\n baseURL?: string\n /**\n * Optional request headers.\n */\n headers?: ChatModelHeaders\n}\n\n/**\n * Union of normalized runtime configs for supported chat-model executors.\n */\nexport type ChatModelRuntimeConfig\n = OpenAIChatModelRuntimeConfig\n | OllamaChatModelRuntimeConfig\n | OpenRouterChatModelRuntimeConfig\n\nfunction getParameters(model: ModelDefinition): Record<string, unknown> {\n return model.parameters ?? {}\n}\n\nfunction parseOptionalStringParameter(\n parameters: Record<string, unknown>,\n key: string,\n modelId: string,\n): string | undefined {\n const value = parameters[key]\n const normalized = value == null ? undefined : String(value)\n\n return envFrom(normalized, {\n name: `${modelId}.parameters.${key}`,\n type: 'string',\n })\n}\n\nfunction parseRequiredStringParameter(\n parameters: Record<string, unknown>,\n key: string,\n modelId: string,\n): string {\n const value = parameters[key]\n const normalized = value == null ? undefined : String(value)\n\n return requiredEnvFrom(normalized, {\n name: `${modelId}.parameters.${key}`,\n type: 'string',\n })\n}\n\nfunction parseHeadersParameter(\n parameters: Record<string, unknown>,\n modelId: string,\n): ChatModelHeaders | undefined {\n const headers = parameters.headers\n if (headers == null) {\n return undefined\n }\n\n if (typeof headers !== 'object' || Array.isArray(headers)) {\n throw new TypeError(`Invalid ${modelId}.parameters.headers: expected an object.`)\n }\n\n const normalized: Record<string, string | string[]> = {}\n for (const [key, value] of Object.entries(headers as Record<string, unknown>)) {\n if (typeof value === 'string') {\n normalized[key] = value\n continue\n }\n\n if (Array.isArray(value) && value.every(item => typeof item === 'string')) {\n normalized[key] = value\n continue\n }\n\n throw new Error(`Invalid ${modelId}.parameters.headers.${key}: expected string or string[].`)\n }\n\n return normalized\n}\n\n/**\n * Normalizes one configured chat model into runtime executor config.\n *\n * Use when:\n * - eval code needs typed provider constructor options from a resolved model\n * - model parameters should be validated once with clear error messages\n *\n * Expects:\n * - `model.inferenceExecutorId` to be one of the supported executor ids\n * - required OpenAI fields (apiKey) to exist in `model.parameters`\n *\n * Returns:\n * - validated runtime config union for OpenAI or Ollama\n */\nexport function toChatModelRuntimeConfig(model: ModelDefinition): ChatModelRuntimeConfig {\n const parameters = getParameters(model)\n\n if (model.inferenceExecutorId === 'openai') {\n return {\n apiKey: parseRequiredStringParameter(parameters, 'apiKey', model.id),\n baseURL: parseOptionalStringParameter(parameters, 'baseURL', model.id),\n headers: parseHeadersParameter(parameters, model.id),\n inferenceExecutor: 'openai',\n model: model.model,\n }\n }\n\n if (model.inferenceExecutorId === 'ollama') {\n return {\n baseURL: parseOptionalStringParameter(parameters, 'baseURL', model.id),\n headers: parseHeadersParameter(parameters, model.id),\n inferenceExecutor: 'ollama',\n model: model.model,\n }\n }\n\n if (model.inferenceExecutorId === 'openrouter') {\n return {\n apiKey: parseRequiredStringParameter(parameters, 'apiKey', model.id),\n baseURL: parseOptionalStringParameter(parameters, 'baseURL', model.id),\n headers: parseHeadersParameter(parameters, model.id),\n inferenceExecutor: 'openrouter',\n model: model.model,\n }\n }\n\n throw new Error(`Unsupported chat inference executor \"${model.inferenceExecutorId}\" for model \"${model.id}\".`)\n}\n\n/**\n * Resolves OpenAI runtime config from one resolved run-context model.\n *\n * Use when:\n * - task execution already has a model resolved through chat-model helpers\n * - eval code wants typed OpenAI provider options with a concise helper name\n *\n * Expects:\n * - `model` to resolve to an OpenAI-backed chat model\n *\n * Returns:\n * - validated OpenAI runtime config\n */\nexport function openaiFromRunContext(model: ModelDefinition): OpenAIChatModelRuntimeConfig {\n const runtimeConfig = toChatModelRuntimeConfig(model)\n if (runtimeConfig.inferenceExecutor !== 'openai') {\n throw new Error(`Expected openai model, got \"${runtimeConfig.inferenceExecutor}\" for \"${model.id}\".`)\n }\n\n return runtimeConfig\n}\n\n/**\n * Resolves Ollama runtime config from one resolved run-context model.\n *\n * Use when:\n * - task execution already has a model resolved through chat-model helpers\n * - eval code wants typed Ollama provider options with a concise helper name\n *\n * Expects:\n * - `model` to resolve to an Ollama-backed chat model\n *\n * Returns:\n * - validated Ollama runtime config\n */\nexport function ollamaFromRunContext(model: ModelDefinition): OllamaChatModelRuntimeConfig {\n const runtimeConfig = toChatModelRuntimeConfig(model)\n if (runtimeConfig.inferenceExecutor !== 'ollama') {\n throw new Error(`Expected ollama model, got \"${runtimeConfig.inferenceExecutor}\" for \"${model.id}\".`)\n }\n\n return runtimeConfig\n}\n\n/**\n * Resolves OpenRouter runtime config from one resolved run-context model.\n *\n * Use when:\n * - task execution already has a model resolved through chat-model helpers\n * - eval code wants typed OpenRouter provider options with a concise helper name\n *\n * Expects:\n * - `model` to resolve to an OpenRouter-backed chat model\n *\n * Returns:\n * - validated OpenRouter runtime config\n */\nexport function openrouterFromRunContext(model: ModelDefinition): OpenRouterChatModelRuntimeConfig {\n const runtimeConfig = toChatModelRuntimeConfig(model)\n if (runtimeConfig.inferenceExecutor !== 'openrouter') {\n throw new Error(`Expected openrouter model, got \"${runtimeConfig.inferenceExecutor}\" for \"${model.id}\".`)\n }\n\n return runtimeConfig\n}\n","import type { TaskRunContext } from '../../config/types'\n\nimport { errorMessageFrom } from '@moeru/std'\n\n/**\n * Represents one normalized chat-model tool call.\n *\n * Use when:\n * - report events need tool-call level payloads that remain provider-neutral\n *\n * Expects:\n * - `name` to be stable enough for aggregation and assertion checks\n * - `args` to be JSON-serializable\n */\nexport interface ChatModelToolCall {\n /**\n * Optional provider-assigned tool-call identifier.\n */\n id?: string\n /**\n * Tool name.\n */\n name: string\n /**\n * Parsed tool arguments object/value.\n */\n args: unknown\n}\n\n/**\n * Provider identity attached to chat-model telemetry events.\n */\nexport interface ChatModelTelemetryProvider {\n /**\n * Provider id, for example `openai`.\n */\n id: string\n /**\n * Optional concrete model id/name.\n */\n model?: string\n}\n\n/**\n * Input options for response telemetry emission.\n */\nexport interface EmitChatModelResponseTelemetryOptions {\n /**\n * Optional case id for case-scoped telemetry events.\n */\n caseId?: string\n /**\n * Optional response latency in milliseconds.\n */\n latencyMs?: number\n /**\n * Optional provider identity payload.\n */\n provider?: ChatModelTelemetryProvider\n /**\n * Raw chat-model response object from the inference library/provider.\n */\n response: unknown\n}\n\n/**\n * Input options for request telemetry emission.\n */\nexport interface EmitChatModelRequestTelemetryOptions {\n /**\n * Optional case id for case-scoped telemetry events.\n */\n caseId?: string\n /**\n * Optional request payload metadata.\n */\n data?: unknown\n /**\n * Optional provider identity payload.\n */\n provider?: ChatModelTelemetryProvider\n}\n\n/**\n * Input options for error telemetry emission.\n */\nexport interface EmitChatModelErrorTelemetryOptions {\n /**\n * Optional case id for case-scoped telemetry events.\n */\n caseId?: string\n /**\n * Error payload emitted by the inference client/runtime.\n */\n error: unknown\n /**\n * Optional provider identity payload.\n */\n provider?: ChatModelTelemetryProvider\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | undefined {\n if (value == null || typeof value !== 'object') {\n return undefined\n }\n\n return value as Record<string, unknown>\n}\n\nfunction parseMaybeJson(value: unknown): unknown {\n if (typeof value !== 'string') {\n return value\n }\n\n try {\n return JSON.parse(value)\n }\n catch {\n return value\n }\n}\n\n/**\n * Extracts normalized tool calls from one chat-model response shape.\n *\n * Use when:\n * - downstream scoring, reporting, or analysis should inspect tool call usage\n * - provider payload differences should stay hidden behind one stable shape\n *\n * Returns:\n * - normalized list of `{ id?, name, args }` tool calls\n */\nexport function extractChatModelToolCalls(response: unknown): ChatModelToolCall[] {\n const responseRecord = asRecord(response)\n if (responseRecord == null) {\n return []\n }\n\n const rawToolCalls = responseRecord.toolCalls ?? responseRecord.tool_calls\n if (!Array.isArray(rawToolCalls)) {\n return []\n }\n\n const toolCalls: ChatModelToolCall[] = []\n\n for (const rawToolCall of rawToolCalls) {\n const toolCallRecord = asRecord(rawToolCall)\n if (toolCallRecord == null) {\n continue\n }\n\n const functionPayload = asRecord(toolCallRecord.function)\n const name = typeof toolCallRecord.name === 'string'\n ? toolCallRecord.name\n : typeof functionPayload?.name === 'string'\n ? functionPayload.name\n : undefined\n\n if (name == null || name.length === 0) {\n continue\n }\n\n const rawArgs = toolCallRecord.args\n ?? toolCallRecord.arguments\n ?? functionPayload?.args\n ?? functionPayload?.arguments\n\n toolCalls.push({\n args: parseMaybeJson(rawArgs),\n id: typeof toolCallRecord.id === 'string' ? toolCallRecord.id : undefined,\n name,\n })\n }\n\n return toolCalls\n}\n\n/**\n * Extracts numeric metering dimensions from one chat-model response usage block.\n *\n * Use when:\n * - report events should capture usage dimensions in a modality-neutral map\n *\n * Returns:\n * - numeric dimensions keyed by provider usage field names\n */\nexport function extractMeteringDimensions(response: unknown): Record<string, number> {\n const responseRecord = asRecord(response)\n const usage = asRecord(responseRecord?.usage)\n if (usage == null) {\n return {}\n }\n\n const dimensions: Record<string, number> = {}\n\n for (const [key, value] of Object.entries(usage)) {\n if (typeof value !== 'number' || Number.isNaN(value)) {\n continue\n }\n\n dimensions[key] = value\n }\n\n return dimensions\n}\n\n/**\n * Emits chat-model response telemetry as reportable task events.\n *\n * Use when:\n * - task code receives one chat-model response and wants standardized report events\n * - `ToolCall*` and metering metrics should be persisted in `events.jsonl`\n *\n * Expects:\n * - `context.reporterHooks?.onEvent` to be available in CLI execution paths\n *\n * Returns:\n * - no return value; this is a best-effort reporting helper\n */\nexport function emitChatModelResponseTelemetry(\n context: TaskRunContext,\n options: EmitChatModelResponseTelemetryOptions,\n): void {\n const toolCalls = extractChatModelToolCalls(options.response)\n const meteringDimensions = extractMeteringDimensions(options.response)\n\n if (toolCalls.length > 0) {\n meteringDimensions.tool_call_count = toolCalls.length\n }\n\n const data = {\n metering: {\n dimensions: meteringDimensions,\n latency_ms: options.latencyMs,\n },\n metrics: {\n 'vieval.chat.tool_call_count': toolCalls.length,\n },\n modality: 'chat',\n provider: options.provider,\n toolCalls,\n }\n\n context.reporterHooks?.onEvent?.({\n caseId: options.caseId,\n data,\n event: 'InferenceResponse',\n })\n\n for (const toolCall of toolCalls) {\n context.reporterHooks?.onEvent?.({\n caseId: options.caseId,\n data: {\n modality: 'chat',\n provider: options.provider,\n toolCall,\n },\n event: 'ToolCallStarted',\n })\n context.reporterHooks?.onEvent?.({\n caseId: options.caseId,\n data: {\n modality: 'chat',\n provider: options.provider,\n toolCall,\n },\n event: 'ToolCallEnded',\n })\n }\n}\n\n/**\n * Emits chat-model request telemetry as a reportable task event.\n *\n * Use when:\n * - task code submits one model request and wants request-side traceability\n *\n * Expects:\n * - `context.reporterHooks?.onEvent` to be available in CLI execution paths\n */\nexport function emitChatModelRequestTelemetry(\n context: TaskRunContext,\n options: EmitChatModelRequestTelemetryOptions,\n): void {\n context.reporterHooks?.onEvent?.({\n caseId: options.caseId,\n data: {\n data: options.data,\n modality: 'chat',\n provider: options.provider,\n },\n event: 'InferenceRequest',\n })\n}\n\n/**\n * Emits chat-model failure telemetry as a reportable task event.\n *\n * Use when:\n * - one inference call fails and report artifacts should include normalized error context\n *\n * Expects:\n * - `context.reporterHooks?.onEvent` to be available in CLI execution paths\n */\nexport function emitChatModelErrorTelemetry(\n context: TaskRunContext,\n options: EmitChatModelErrorTelemetryOptions,\n): void {\n context.reporterHooks?.onEvent?.({\n caseId: options.caseId,\n data: {\n error: errorMessageFrom(options.error) ?? 'Unknown inference error.',\n modality: 'chat',\n provider: options.provider,\n },\n event: 'InferenceError',\n })\n}\n","import type { MatrixDefinition, TaskExecutionPolicy } from '../../config'\nimport type { ModelDefinition } from '../../config/models'\nimport type { ConfigHookPlugin } from '../../config/plugin'\nimport type { TaskRunContext } from '../../config/types'\nimport type { EnvFromOptions, RequiredEnvFromOptions } from '../../core/inference-executors/env'\n\nimport process from 'node:process'\n\nimport { resolveModelByName } from '../../config/models'\nimport { envFrom, requiredEnvFrom } from '../../core/inference-executors/env'\n\n/**\n * Minimal inference-executor shape expected by chat model runtime callers.\n */\nexport interface ChatModelExecutorLike {\n chat: (model: string) => Record<string, unknown>\n}\n\n/**\n * Inference-executor input accepted by `chatModelFrom`.\n */\nexport type ChatModelExecutorInput = string | ChatModelExecutorLike\n\n/**\n * Chat-model header payload accepted by executor parameters.\n */\nexport type ChatModelHeaders = Record<string, string | string[]>\n\n/**\n * Runtime env context passed to model callback resolvers.\n */\nexport interface ChatModelResolverContext {\n env: Record<string, string>\n}\n\n/**\n * Value-or-callback resolver used by model runtime fields.\n */\nexport type ChatModelResolverValue<TValue> = TValue | ((config: ChatModelResolverContext) => Promise<TValue> | TValue)\n\n/**\n * OpenAI-specific inference executor config shape.\n */\nexport interface OpenAIChatModelInferenceExecutor {\n inferenceExecutor: 'openai'\n apiKey?: ChatModelResolverValue<string>\n baseURL?: ChatModelResolverValue<string>\n headers?: ChatModelResolverValue<ChatModelHeaders>\n}\n\n/**\n * Ollama-specific inference executor config shape.\n */\nexport interface OllamaChatModelInferenceExecutor {\n inferenceExecutor: 'ollama'\n baseURL?: ChatModelResolverValue<string>\n headers?: ChatModelResolverValue<ChatModelHeaders>\n}\n\n/**\n * OpenRouter-specific inference executor config shape.\n */\nexport interface OpenRouterChatModelInferenceExecutor {\n inferenceExecutor: 'openrouter'\n apiKey?: ChatModelResolverValue<string>\n baseURL?: ChatModelResolverValue<string>\n headers?: ChatModelResolverValue<ChatModelHeaders>\n}\n\n/**\n * Generic inference executor config shape.\n */\nexport interface GenericChatModelInferenceExecutor {\n inferenceExecutor?: ChatModelExecutorInput\n}\n\n/**\n * Union of supported inference executor config shapes for `chatModelFrom`.\n */\nexport type ChatModelInferenceExecutor\n = OpenAIChatModelInferenceExecutor\n | OllamaChatModelInferenceExecutor\n | OpenRouterChatModelInferenceExecutor\n | GenericChatModelInferenceExecutor\n\n/**\n * Common builder input fields for `chatModelFrom`.\n */\nexport interface ChatModelFromBaseOptions {\n /**\n * Provider id registered through `ChatProviders`.\n *\n * Use when:\n * - model runtime transport and credentials should be delegated to a named provider preset\n *\n * Expects:\n * - one `ChatProviders` plugin entry to expose the same id\n */\n provider?: string\n /**\n * Inference-executor id or inference-executor instance.\n */\n inferenceExecutor?: ChatModelExecutorInput\n /**\n * Optional explicit inference-executor id for inference-executor instances.\n *\n * @default 'custom'\n */\n inferenceExecutorId?: string\n /**\n * Concrete model name.\n */\n model: string\n /**\n * Optional stable model id.\n *\n * @default `${inferenceExecutorId}:${model}`\n */\n id?: string\n /**\n * Alias names used by `resolveModelByName`.\n */\n aliases?: string[]\n /**\n * Optional execution policy hints attached to this model.\n */\n executionPolicy?: TaskExecutionPolicy\n /**\n * Additional retries allowed within the current attempt.\n *\n * @default 0\n */\n autoRetry?: number\n /**\n * Delay in milliseconds before a retry starts.\n *\n * @default retryIndex => 500 * 2 ** (retryIndex - 1)\n */\n autoRetryDelay?: TaskExecutionPolicy['autoRetryDelay']\n /**\n * Additional full task attempts allowed after the current attempt settles.\n *\n * @default 0\n */\n autoAttempt?: number\n /**\n * Timeout in milliseconds for model-backed work.\n */\n timeout?: number\n /**\n * Optional model-level call parameters.\n */\n parameters?: Record<string, unknown>\n}\n\n/**\n * Builder input for `chatModelFrom`.\n */\nexport type ChatModelFromOptions = ChatModelInferenceExecutor & ChatModelFromBaseOptions\n\n/**\n * Chat-model specific specialization of the canonical `ModelDefinition`.\n */\nexport type ChatModelDefinition = Omit<ModelDefinition, 'inferenceExecutor'> & {\n inferenceExecutor: ChatModelExecutorInput\n provider?: string\n runtimeResolvers?: {\n apiKey?: ChatModelResolverValue<string>\n baseURL?: ChatModelResolverValue<string>\n headers?: ChatModelResolverValue<ChatModelHeaders>\n }\n}\n\nfunction normalizeExecutionPolicy(\n policy: TaskExecutionPolicy | undefined,\n): TaskExecutionPolicy | undefined {\n if (policy == null) {\n return undefined\n }\n\n const normalized = {\n autoAttempt: policy.autoAttempt,\n autoRetry: policy.autoRetry,\n autoRetryDelay: policy.autoRetryDelay,\n timeout: policy.timeout,\n }\n\n return Object.values(normalized).some(value => value != null)\n ? normalized\n : undefined\n}\n\nfunction hasJudgeAlias(model: Pick<ChatModelFromBaseOptions, 'aliases' | 'id' | 'model'>): boolean {\n return [\n ...(model.aliases ?? []),\n ...(model.id == null ? [] : [model.id]),\n model.model,\n ].some(value => value.toLowerCase().includes('judge'))\n}\n\nfunction resolveModelExecutionPolicy(options: ChatModelFromOptions): TaskExecutionPolicy | undefined {\n const explicitPolicy = normalizeExecutionPolicy({\n autoAttempt: options.autoAttempt ?? options.executionPolicy?.autoAttempt,\n autoRetry: options.autoRetry ?? options.executionPolicy?.autoRetry,\n autoRetryDelay: options.autoRetryDelay ?? options.executionPolicy?.autoRetryDelay,\n timeout: options.timeout ?? options.executionPolicy?.timeout,\n })\n\n if (explicitPolicy != null && Object.keys(explicitPolicy).length > 0) {\n return explicitPolicy\n }\n\n if (hasJudgeAlias(options)) {\n return {\n autoRetry: 3,\n }\n }\n\n return undefined\n}\n\n/**\n * Env-key map for optional provider parameters.\n *\n * Use when:\n * - provider parameter values should be read from env keys\n * - missing keys should resolve to `undefined`\n */\nexport type OptionalProviderEnvMap = Record<string, string>\n\n/**\n * Env-key map for required provider parameters.\n *\n * Use when:\n * - provider parameter values must exist before model execution\n * - missing keys should throw with key-aware error messages\n */\nexport type RequiredProviderEnvMap = Record<string, string>\n\n/**\n * One provider definition consumed by chat model presets.\n */\nexport interface ChatProviderDefinition {\n /**\n * Stable provider id referenced by `chatModelFrom({ provider })`.\n */\n id: string\n /**\n * Inference-executor id or instance used by this provider preset.\n */\n inferenceExecutor: ChatModelExecutorInput\n /**\n * Optional explicit inference-executor id for inference-executor instances.\n *\n * @default 'custom'\n */\n inferenceExecutorId?: string\n /**\n * Optional literal provider-level parameters.\n */\n parameters?: Record<string, unknown>\n /**\n * Optional provider parameters resolved via `envFrom`.\n *\n * Expects:\n * - map key is the provider parameter name\n * - map value is the env key name\n */\n optionalEnv?: OptionalProviderEnvMap\n /**\n * Required provider parameters resolved via `requiredEnvFrom`.\n *\n * Expects:\n * - map key is the provider parameter name\n * - map value is the env key name\n */\n requiredEnv?: RequiredProviderEnvMap\n}\n\n/**\n * Builder input for `chatProviderFrom`.\n */\nexport interface ChatProviderFromOptions extends ChatProviderDefinition {\n}\n\n/**\n * Options for the built-in `ChatProviders` plugin.\n */\nexport interface ChatProvidersPluginOptions {\n /**\n * Provider definitions to append to config.\n */\n providers: readonly ChatProviderDefinition[]\n /**\n * Optional explicit env source used for env-backed provider parameters.\n *\n * @default process.env\n */\n env?: NodeJS.ProcessEnv\n}\n\n/**\n * Partial config shape needed by the chat models plugin.\n */\nexport interface PluginConfig {\n env?: NodeJS.ProcessEnv\n chatProviders?: ChatProviderDefinition[]\n models?: ModelDefinition[]\n}\n\n/**\n * Plugin type bound to the minimal config shape used by model plugins.\n */\nexport type Plugin = ConfigHookPlugin<PluginConfig>\n\nfunction normalizeInferenceExecutorId(\n inferenceExecutor: ChatModelExecutorInput,\n inferenceExecutorId: string | undefined,\n): string {\n if (typeof inferenceExecutor === 'string') {\n return inferenceExecutor\n }\n\n return inferenceExecutorId ?? 'custom'\n}\n\nfunction createDefaultModelId(inferenceExecutorId: string, model: string): string {\n return `${inferenceExecutorId}:${model}`\n}\n\nfunction normalizeEnvRecord(env: NodeJS.ProcessEnv): Record<string, string> {\n const normalized: Record<string, string> = {}\n for (const [key, value] of Object.entries(env)) {\n if (typeof value === 'string') {\n normalized[key] = value\n }\n }\n\n return normalized\n}\n\nasync function resolveChatModelResolverValue<TValue>(\n value: ChatModelResolverValue<TValue>,\n context: ChatModelResolverContext,\n): Promise<TValue> {\n if (typeof value === 'function') {\n const resolver = value as (config: ChatModelResolverContext) => Promise<TValue> | TValue\n return await resolver(context)\n }\n\n return value\n}\n\nfunction resolveRequiredStringValue(value: string | undefined, name: string): string {\n return requiredEnvFrom(value, {\n name,\n type: 'string',\n })\n}\n\nfunction resolveOptionalStringValue(value: string | undefined, name: string): string | undefined {\n return envFrom(value, {\n name,\n type: 'string',\n })\n}\n\nfunction resolveOptionalEnvValue(\n env: NodeJS.ProcessEnv,\n envKey: string,\n): string | undefined {\n const options: EnvFromOptions = {\n name: envKey,\n type: 'string',\n }\n\n return envFrom(env[envKey], options)\n}\n\nfunction resolveRequiredEnvValue(\n env: NodeJS.ProcessEnv,\n envKey: string,\n): string {\n const options: RequiredEnvFromOptions = {\n name: envKey,\n type: 'string',\n }\n\n return requiredEnvFrom(env[envKey], options)\n}\n\nfunction resolveProviderParameters(\n provider: ChatProviderDefinition,\n env: NodeJS.ProcessEnv,\n): Record<string, unknown> | undefined {\n const parameters: Record<string, unknown> = {\n ...provider.parameters,\n }\n\n for (const [parameterName, envKey] of Object.entries(provider.optionalEnv ?? {})) {\n const resolved = resolveOptionalEnvValue(env, envKey)\n if (resolved != null) {\n parameters[parameterName] = resolved\n }\n }\n\n for (const [parameterName, envKey] of Object.entries(provider.requiredEnv ?? {})) {\n parameters[parameterName] = resolveRequiredEnvValue(env, envKey)\n }\n\n return Object.keys(parameters).length > 0 ? parameters : undefined\n}\n\nfunction normalizeChatProviderDefinition(\n provider: ChatProviderDefinition,\n env: NodeJS.ProcessEnv,\n): ChatProviderDefinition {\n return {\n id: provider.id,\n inferenceExecutor: provider.inferenceExecutor,\n inferenceExecutorId: normalizeInferenceExecutorId(provider.inferenceExecutor, provider.inferenceExecutorId),\n optionalEnv: provider.optionalEnv,\n parameters: resolveProviderParameters(provider, env),\n requiredEnv: provider.requiredEnv,\n }\n}\n\nfunction createProviderMap(config: PluginConfig): Map<string, ChatProviderDefinition> {\n const providerMap = new Map<string, ChatProviderDefinition>()\n for (const provider of config.chatProviders ?? []) {\n providerMap.set(provider.id, provider)\n }\n\n return providerMap\n}\n\nfunction resolveModelProvider(\n model: ChatModelDefinition,\n providerMap: ReadonlyMap<string, ChatProviderDefinition>,\n): ChatModelDefinition {\n if (model.provider == null) {\n return model\n }\n\n const provider = providerMap.get(model.provider)\n if (provider == null) {\n throw new Error(`Unknown chat provider \"${model.provider}\" referenced by model \"${model.id}\".`)\n }\n\n return {\n ...model,\n inferenceExecutor: provider.inferenceExecutor,\n inferenceExecutorId: provider.inferenceExecutorId ?? normalizeInferenceExecutorId(provider.inferenceExecutor, provider.inferenceExecutorId),\n parameters: {\n ...provider.parameters,\n ...model.parameters,\n },\n }\n}\n\nasync function resolveModelRuntimeResolvers(\n model: ChatModelDefinition,\n context: ChatModelResolverContext,\n): Promise<Record<string, unknown> | undefined> {\n if (model.runtimeResolvers == null) {\n return undefined\n }\n\n const resolvedParameters: Record<string, unknown> = {}\n\n if (model.runtimeResolvers.apiKey != null) {\n const resolvedApiKey = await resolveChatModelResolverValue(model.runtimeResolvers.apiKey, context)\n resolvedParameters.apiKey = resolveRequiredStringValue(resolvedApiKey, `${model.id}.apiKey`)\n }\n\n if (model.runtimeResolvers.baseURL != null) {\n const resolvedBaseURL = await resolveChatModelResolverValue(model.runtimeResolvers.baseURL, context)\n const normalizedBaseURL = resolveOptionalStringValue(resolvedBaseURL, `${model.id}.baseURL`)\n if (normalizedBaseURL != null) {\n resolvedParameters.baseURL = normalizedBaseURL\n }\n }\n\n if (model.runtimeResolvers.headers != null) {\n const resolvedHeaders = await resolveChatModelResolverValue(model.runtimeResolvers.headers, context)\n resolvedParameters.headers = resolvedHeaders\n }\n\n return Object.keys(resolvedParameters).length > 0 ? resolvedParameters : undefined\n}\n\nasync function resolveChatModelDefinition(\n model: ChatModelDefinition,\n config: PluginConfig,\n): Promise<ChatModelDefinition> {\n const providerResolvedModel = resolveModelProvider(model, createProviderMap(config))\n const resolvedRuntimeParameters = await resolveModelRuntimeResolvers(providerResolvedModel, {\n env: normalizeEnvRecord(config.env ?? process.env),\n })\n\n if (resolvedRuntimeParameters == null) {\n return providerResolvedModel\n }\n\n return {\n ...providerResolvedModel,\n parameters: {\n ...providerResolvedModel.parameters,\n ...resolvedRuntimeParameters,\n },\n }\n}\n\nfunction isOpenAIChatModelInferenceExecutor(\n options: ChatModelFromOptions,\n): options is ChatModelFromBaseOptions & OpenAIChatModelInferenceExecutor {\n return options.inferenceExecutor === 'openai'\n}\n\nfunction isOllamaChatModelInferenceExecutor(\n options: ChatModelFromOptions,\n): options is ChatModelFromBaseOptions & OllamaChatModelInferenceExecutor {\n return options.inferenceExecutor === 'ollama'\n}\n\nfunction isOpenRouterChatModelInferenceExecutor(\n options: ChatModelFromOptions,\n): options is ChatModelFromBaseOptions & OpenRouterChatModelInferenceExecutor {\n return options.inferenceExecutor === 'openrouter'\n}\n\n/**\n * Builds one normalized chat model definition.\n *\n * Use when:\n * - registering chat models through config plugins\n * - a single model needs aliases for matrix selection or judge lookup\n */\nexport function chatModelFrom(options: ChatModelFromOptions): ChatModelDefinition {\n const fallbackInferenceExecutor = options.inferenceExecutor ?? options.provider ?? 'custom'\n const inferenceExecutorId = normalizeInferenceExecutorId(fallbackInferenceExecutor, options.inferenceExecutorId)\n const runtimeResolvers = isOpenAIChatModelInferenceExecutor(options)\n ? {\n apiKey: options.apiKey,\n baseURL: options.baseURL,\n headers: options.headers,\n }\n : isOllamaChatModelInferenceExecutor(options)\n ? {\n baseURL: options.baseURL,\n headers: options.headers,\n }\n : isOpenRouterChatModelInferenceExecutor(options)\n ? {\n apiKey: options.apiKey,\n baseURL: options.baseURL,\n headers: options.headers,\n }\n : undefined\n\n return {\n aliases: options.aliases ?? [],\n executionPolicy: resolveModelExecutionPolicy(options),\n id: options.id ?? createDefaultModelId(inferenceExecutorId, options.model),\n inferenceExecutor: fallbackInferenceExecutor,\n inferenceExecutorId,\n model: options.model,\n parameters: options.parameters,\n provider: options.provider,\n runtimeResolvers,\n }\n}\n\n/**\n * Builds one normalized chat provider definition.\n *\n * Use when:\n * - one provider preset should be reused across multiple chat models\n * - provider configuration should support required/optional env-backed parameters\n */\nexport function chatProviderFrom(options: ChatProviderFromOptions): ChatProviderDefinition {\n return {\n id: options.id,\n inferenceExecutor: options.inferenceExecutor,\n inferenceExecutorId: normalizeInferenceExecutorId(options.inferenceExecutor, options.inferenceExecutorId),\n optionalEnv: options.optionalEnv,\n parameters: options.parameters,\n requiredEnv: options.requiredEnv,\n }\n}\n\n/**\n * Options for the built-in `ChatModels` plugin.\n */\nexport interface ChatModelsPluginOptions {\n /**\n * Chat model definitions to append to config.\n */\n models: readonly ChatModelDefinition[]\n}\n\n/**\n * Matrix scope that can carry a chat model selector.\n */\nexport type MatrixModelScope = 'eval' | 'run'\n\n/**\n * Options for resolving a chat model from a matrix axis.\n */\nexport interface ModelFromMatrixOptions {\n /**\n * Matrix axis whose selected value is a model id, model name, or alias.\n */\n axis: string\n}\n\ntype MatrixModelContext = Pick<TaskRunContext, 'models' | 'task'>\n\n/**\n * Resolves a configured chat model from one scoped matrix axis.\n *\n * Use when:\n * - a matrix axis selects the agent, judge, or another chat model role\n * - eval code should keep model lookup semantics inside the chat-models plugin\n *\n * Expects:\n * - `scope` to identify `context.task.matrix.run` or `context.task.matrix.eval`\n * - `options.axis` to exist and contain a model id, model name, or alias\n *\n * Returns:\n * - the configured model matching the selected matrix value\n */\nexport function modelFromMatrix(\n context: MatrixModelContext,\n scope: MatrixModelScope,\n options: ModelFromMatrixOptions,\n): ModelDefinition {\n const selectedModelName = context.task.matrix[scope][options.axis]\n\n if (selectedModelName == null) {\n throw new Error(`Missing ${scope} matrix axis \"${options.axis}\".`)\n }\n\n const model = resolveModelByName(context.models, selectedModelName)\n if (model == null) {\n throw new Error(`Unknown configured chat model \"${selectedModelName}\" from ${scope} matrix axis \"${options.axis}\".`)\n }\n\n return model\n}\n\n/**\n * Resolves a configured chat model from one run-matrix axis.\n *\n * Use when:\n * - run matrix selects the model used by the system under evaluation\n * - callers want the scoped helper instead of passing `scope: 'run'`\n *\n * Expects:\n * - `options.axis` to exist in `context.task.matrix.run`\n *\n * Returns:\n * - the configured model matching the selected run-matrix value\n */\nexport function modelFromRun(\n context: MatrixModelContext,\n options: ModelFromMatrixOptions,\n): ModelDefinition {\n return modelFromMatrix(context, 'run', options)\n}\n\n/**\n * Resolves a configured chat model from one eval-matrix axis.\n *\n * Use when:\n * - eval matrix selects a judge, rubric, or evaluator model\n * - callers want the scoped helper instead of passing `scope: 'eval'`\n *\n * Expects:\n * - `options.axis` to exist in `context.task.matrix.eval`\n *\n * Returns:\n * - the configured model matching the selected eval-matrix value\n */\nexport function modelFromEval(\n context: MatrixModelContext,\n options: ModelFromMatrixOptions,\n): ModelDefinition {\n return modelFromMatrix(context, 'eval', options)\n}\n\n/**\n * Creates a run-matrix `model` axis from configured chat model names.\n *\n * Use when:\n * - run matrix should iterate over explicit chat model ids/aliases\n * - project configs want a concise model-axis helper\n *\n * Expects:\n * - each provided name to match a configured model id or alias at runtime\n *\n * Returns:\n * - matrix axis object compatible with `runMatrix.extend/override`\n */\nexport function chatModelMatrix(...names: string[]): MatrixDefinition {\n return {\n model: Array.from(new Set(names)),\n }\n}\n\n/**\n * Built-in chat providers plugin that contributes provider presets to config.\n *\n * Use when:\n * - provider runtime config should be centralized and reusable\n * - provider parameters should be resolved from env via `envFrom`/`requiredEnvFrom`\n */\nexport function ChatProviders(options: ChatProvidersPluginOptions): Plugin {\n return {\n configVieval(config) {\n const env = config.env ?? options.env ?? process.env\n const normalizedProviders = options.providers.map(provider => normalizeChatProviderDefinition(provider, env))\n\n return {\n ...config,\n chatProviders: [\n ...(config.chatProviders ?? []),\n ...normalizedProviders,\n ],\n }\n },\n name: 'vieval:chat-providers',\n }\n}\n\n/**\n * Built-in chat models plugin that contributes model definitions to vieval config.\n *\n * Use when:\n * - chat-model registration should stay in config-level plugin setup\n * - tasks and assertions resolve models by name or alias at runtime\n */\nexport function ChatModels(options: ChatModelsPluginOptions): Plugin {\n return {\n async configVieval(config) {\n const resolvedModels = await Promise.all(options.models.map(async model => resolveChatModelDefinition(model, config)))\n\n return {\n ...config,\n models: [\n ...(config.models ?? []),\n ...resolvedModels,\n ],\n }\n },\n name: 'vieval:chat-models',\n }\n}\n\nexport * from './runtime-config'\nexport * from './telemetry'\n"],"mappings":";;;;;AAuFA,SAAS,cAAc,OAAiD;AACtE,QAAO,MAAM,cAAc,EAAE;;AAG/B,SAAS,6BACP,YACA,KACA,SACoB;CACpB,MAAM,QAAQ,WAAW;AAGzB,QAAO,QAFY,SAAS,OAAO,KAAA,IAAY,OAAO,MAAM,EAEjC;EACzB,MAAM,GAAG,QAAQ,cAAc;EAC/B,MAAM;EACP,CAAC;;AAGJ,SAAS,6BACP,YACA,KACA,SACQ;CACR,MAAM,QAAQ,WAAW;AAGzB,QAAO,gBAFY,SAAS,OAAO,KAAA,IAAY,OAAO,MAAM,EAEzB;EACjC,MAAM,GAAG,QAAQ,cAAc;EAC/B,MAAM;EACP,CAAC;;AAGJ,SAAS,sBACP,YACA,SAC8B;CAC9B,MAAM,UAAU,WAAW;AAC3B,KAAI,WAAW,KACb;AAGF,KAAI,OAAO,YAAY,YAAY,MAAM,QAAQ,QAAQ,CACvD,OAAM,IAAI,UAAU,WAAW,QAAQ,0CAA0C;CAGnF,MAAM,aAAgD,EAAE;AACxD,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,QAAmC,EAAE;AAC7E,MAAI,OAAO,UAAU,UAAU;AAC7B,cAAW,OAAO;AAClB;;AAGF,MAAI,MAAM,QAAQ,MAAM,IAAI,MAAM,OAAM,SAAQ,OAAO,SAAS,SAAS,EAAE;AACzE,cAAW,OAAO;AAClB;;AAGF,QAAM,IAAI,MAAM,WAAW,QAAQ,sBAAsB,IAAI,gCAAgC;;AAG/F,QAAO;;;;;;;;;;;;;;;;AAiBT,SAAgB,yBAAyB,OAAgD;CACvF,MAAM,aAAa,cAAc,MAAM;AAEvC,KAAI,MAAM,wBAAwB,SAChC,QAAO;EACL,QAAQ,6BAA6B,YAAY,UAAU,MAAM,GAAG;EACpE,SAAS,6BAA6B,YAAY,WAAW,MAAM,GAAG;EACtE,SAAS,sBAAsB,YAAY,MAAM,GAAG;EACpD,mBAAmB;EACnB,OAAO,MAAM;EACd;AAGH,KAAI,MAAM,wBAAwB,SAChC,QAAO;EACL,SAAS,6BAA6B,YAAY,WAAW,MAAM,GAAG;EACtE,SAAS,sBAAsB,YAAY,MAAM,GAAG;EACpD,mBAAmB;EACnB,OAAO,MAAM;EACd;AAGH,KAAI,MAAM,wBAAwB,aAChC,QAAO;EACL,QAAQ,6BAA6B,YAAY,UAAU,MAAM,GAAG;EACpE,SAAS,6BAA6B,YAAY,WAAW,MAAM,GAAG;EACtE,SAAS,sBAAsB,YAAY,MAAM,GAAG;EACpD,mBAAmB;EACnB,OAAO,MAAM;EACd;AAGH,OAAM,IAAI,MAAM,wCAAwC,MAAM,oBAAoB,eAAe,MAAM,GAAG,IAAI;;;;;;;;;;;;;;;AAgBhH,SAAgB,qBAAqB,OAAsD;CACzF,MAAM,gBAAgB,yBAAyB,MAAM;AACrD,KAAI,cAAc,sBAAsB,SACtC,OAAM,IAAI,MAAM,+BAA+B,cAAc,kBAAkB,SAAS,MAAM,GAAG,IAAI;AAGvG,QAAO;;;;;;;;;;;;;;;AAgBT,SAAgB,qBAAqB,OAAsD;CACzF,MAAM,gBAAgB,yBAAyB,MAAM;AACrD,KAAI,cAAc,sBAAsB,SACtC,OAAM,IAAI,MAAM,+BAA+B,cAAc,kBAAkB,SAAS,MAAM,GAAG,IAAI;AAGvG,QAAO;;;;;;;;;;;;;;;AAgBT,SAAgB,yBAAyB,OAA0D;CACjG,MAAM,gBAAgB,yBAAyB,MAAM;AACrD,KAAI,cAAc,sBAAsB,aACtC,OAAM,IAAI,MAAM,mCAAmC,cAAc,kBAAkB,SAAS,MAAM,GAAG,IAAI;AAG3G,QAAO;;;;ACjKT,SAAS,SAAS,OAAqD;AACrE,KAAI,SAAS,QAAQ,OAAO,UAAU,SACpC;AAGF,QAAO;;AAGT,SAAS,eAAe,OAAyB;AAC/C,KAAI,OAAO,UAAU,SACnB,QAAO;AAGT,KAAI;AACF,SAAO,KAAK,MAAM,MAAM;SAEpB;AACJ,SAAO;;;;;;;;;;;;;AAcX,SAAgB,0BAA0B,UAAwC;CAChF,MAAM,iBAAiB,SAAS,SAAS;AACzC,KAAI,kBAAkB,KACpB,QAAO,EAAE;CAGX,MAAM,eAAe,eAAe,aAAa,eAAe;AAChE,KAAI,CAAC,MAAM,QAAQ,aAAa,CAC9B,QAAO,EAAE;CAGX,MAAM,YAAiC,EAAE;AAEzC,MAAK,MAAM,eAAe,cAAc;EACtC,MAAM,iBAAiB,SAAS,YAAY;AAC5C,MAAI,kBAAkB,KACpB;EAGF,MAAM,kBAAkB,SAAS,eAAe,SAAS;EACzD,MAAM,OAAO,OAAO,eAAe,SAAS,WACxC,eAAe,OACf,OAAO,iBAAiB,SAAS,WAC/B,gBAAgB,OAChB,KAAA;AAEN,MAAI,QAAQ,QAAQ,KAAK,WAAW,EAClC;EAGF,MAAM,UAAU,eAAe,QAC1B,eAAe,aACf,iBAAiB,QACjB,iBAAiB;AAEtB,YAAU,KAAK;GACb,MAAM,eAAe,QAAQ;GAC7B,IAAI,OAAO,eAAe,OAAO,WAAW,eAAe,KAAK,KAAA;GAChE;GACD,CAAC;;AAGJ,QAAO;;;;;;;;;;;AAYT,SAAgB,0BAA0B,UAA2C;CAEnF,MAAM,QAAQ,SADS,SAAS,SAAS,EACF,MAAM;AAC7C,KAAI,SAAS,KACX,QAAO,EAAE;CAGX,MAAM,aAAqC,EAAE;AAE7C,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,MAAM,EAAE;AAChD,MAAI,OAAO,UAAU,YAAY,OAAO,MAAM,MAAM,CAClD;AAGF,aAAW,OAAO;;AAGpB,QAAO;;;;;;;;;;;;;;;AAgBT,SAAgB,+BACd,SACA,SACM;CACN,MAAM,YAAY,0BAA0B,QAAQ,SAAS;CAC7D,MAAM,qBAAqB,0BAA0B,QAAQ,SAAS;AAEtE,KAAI,UAAU,SAAS,EACrB,oBAAmB,kBAAkB,UAAU;CAGjD,MAAM,OAAO;EACX,UAAU;GACR,YAAY;GACZ,YAAY,QAAQ;GACrB;EACD,SAAS,EACP,+BAA+B,UAAU,QAC1C;EACD,UAAU;EACV,UAAU,QAAQ;EAClB;EACD;AAED,SAAQ,eAAe,UAAU;EAC/B,QAAQ,QAAQ;EAChB;EACA,OAAO;EACR,CAAC;AAEF,MAAK,MAAM,YAAY,WAAW;AAChC,UAAQ,eAAe,UAAU;GAC/B,QAAQ,QAAQ;GAChB,MAAM;IACJ,UAAU;IACV,UAAU,QAAQ;IAClB;IACD;GACD,OAAO;GACR,CAAC;AACF,UAAQ,eAAe,UAAU;GAC/B,QAAQ,QAAQ;GAChB,MAAM;IACJ,UAAU;IACV,UAAU,QAAQ;IAClB;IACD;GACD,OAAO;GACR,CAAC;;;;;;;;;;;;AAaN,SAAgB,8BACd,SACA,SACM;AACN,SAAQ,eAAe,UAAU;EAC/B,QAAQ,QAAQ;EAChB,MAAM;GACJ,MAAM,QAAQ;GACd,UAAU;GACV,UAAU,QAAQ;GACnB;EACD,OAAO;EACR,CAAC;;;;;;;;;;;AAYJ,SAAgB,4BACd,SACA,SACM;AACN,SAAQ,eAAe,UAAU;EAC/B,QAAQ,QAAQ;EAChB,MAAM;GACJ,OAAO,iBAAiB,QAAQ,MAAM,IAAI;GAC1C,UAAU;GACV,UAAU,QAAQ;GACnB;EACD,OAAO;EACR,CAAC;;;;AC/IJ,SAAS,yBACP,QACiC;AACjC,KAAI,UAAU,KACZ;CAGF,MAAM,aAAa;EACjB,aAAa,OAAO;EACpB,WAAW,OAAO;EAClB,gBAAgB,OAAO;EACvB,SAAS,OAAO;EACjB;AAED,QAAO,OAAO,OAAO,WAAW,CAAC,MAAK,UAAS,SAAS,KAAK,GACzD,aACA,KAAA;;AAGN,SAAS,cAAc,OAA4E;AACjG,QAAO;EACL,GAAI,MAAM,WAAW,EAAE;EACvB,GAAI,MAAM,MAAM,OAAO,EAAE,GAAG,CAAC,MAAM,GAAG;EACtC,MAAM;EACP,CAAC,MAAK,UAAS,MAAM,aAAa,CAAC,SAAS,QAAQ,CAAC;;AAGxD,SAAS,4BAA4B,SAAgE;CACnG,MAAM,iBAAiB,yBAAyB;EAC9C,aAAa,QAAQ,eAAe,QAAQ,iBAAiB;EAC7D,WAAW,QAAQ,aAAa,QAAQ,iBAAiB;EACzD,gBAAgB,QAAQ,kBAAkB,QAAQ,iBAAiB;EACnE,SAAS,QAAQ,WAAW,QAAQ,iBAAiB;EACtD,CAAC;AAEF,KAAI,kBAAkB,QAAQ,OAAO,KAAK,eAAe,CAAC,SAAS,EACjE,QAAO;AAGT,KAAI,cAAc,QAAQ,CACxB,QAAO,EACL,WAAW,GACZ;;AAoGL,SAAS,6BACP,mBACA,qBACQ;AACR,KAAI,OAAO,sBAAsB,SAC/B,QAAO;AAGT,QAAO,uBAAuB;;AAGhC,SAAS,qBAAqB,qBAA6B,OAAuB;AAChF,QAAO,GAAG,oBAAoB,GAAG;;AAGnC,SAAS,mBAAmB,KAAgD;CAC1E,MAAM,aAAqC,EAAE;AAC7C,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,IAAI,CAC5C,KAAI,OAAO,UAAU,SACnB,YAAW,OAAO;AAItB,QAAO;;AAGT,eAAe,8BACb,OACA,SACiB;AACjB,KAAI,OAAO,UAAU,WAEnB,QAAO,MADU,MACK,QAAQ;AAGhC,QAAO;;AAGT,SAAS,2BAA2B,OAA2B,MAAsB;AACnF,QAAO,gBAAgB,OAAO;EAC5B;EACA,MAAM;EACP,CAAC;;AAGJ,SAAS,2BAA2B,OAA2B,MAAkC;AAC/F,QAAO,QAAQ,OAAO;EACpB;EACA,MAAM;EACP,CAAC;;AAGJ,SAAS,wBACP,KACA,QACoB;CACpB,MAAM,UAA0B;EAC9B,MAAM;EACN,MAAM;EACP;AAED,QAAO,QAAQ,IAAI,SAAS,QAAQ;;AAGtC,SAAS,wBACP,KACA,QACQ;CACR,MAAM,UAAkC;EACtC,MAAM;EACN,MAAM;EACP;AAED,QAAO,gBAAgB,IAAI,SAAS,QAAQ;;AAG9C,SAAS,0BACP,UACA,KACqC;CACrC,MAAM,aAAsC,EAC1C,GAAG,SAAS,YACb;AAED,MAAK,MAAM,CAAC,eAAe,WAAW,OAAO,QAAQ,SAAS,eAAe,EAAE,CAAC,EAAE;EAChF,MAAM,WAAW,wBAAwB,KAAK,OAAO;AACrD,MAAI,YAAY,KACd,YAAW,iBAAiB;;AAIhC,MAAK,MAAM,CAAC,eAAe,WAAW,OAAO,QAAQ,SAAS,eAAe,EAAE,CAAC,CAC9E,YAAW,iBAAiB,wBAAwB,KAAK,OAAO;AAGlE,QAAO,OAAO,KAAK,WAAW,CAAC,SAAS,IAAI,aAAa,KAAA;;AAG3D,SAAS,gCACP,UACA,KACwB;AACxB,QAAO;EACL,IAAI,SAAS;EACb,mBAAmB,SAAS;EAC5B,qBAAqB,6BAA6B,SAAS,mBAAmB,SAAS,oBAAoB;EAC3G,aAAa,SAAS;EACtB,YAAY,0BAA0B,UAAU,IAAI;EACpD,aAAa,SAAS;EACvB;;AAGH,SAAS,kBAAkB,QAA2D;CACpF,MAAM,8BAAc,IAAI,KAAqC;AAC7D,MAAK,MAAM,YAAY,OAAO,iBAAiB,EAAE,CAC/C,aAAY,IAAI,SAAS,IAAI,SAAS;AAGxC,QAAO;;AAGT,SAAS,qBACP,OACA,aACqB;AACrB,KAAI,MAAM,YAAY,KACpB,QAAO;CAGT,MAAM,WAAW,YAAY,IAAI,MAAM,SAAS;AAChD,KAAI,YAAY,KACd,OAAM,IAAI,MAAM,0BAA0B,MAAM,SAAS,yBAAyB,MAAM,GAAG,IAAI;AAGjG,QAAO;EACL,GAAG;EACH,mBAAmB,SAAS;EAC5B,qBAAqB,SAAS,uBAAuB,6BAA6B,SAAS,mBAAmB,SAAS,oBAAoB;EAC3I,YAAY;GACV,GAAG,SAAS;GACZ,GAAG,MAAM;GACV;EACF;;AAGH,eAAe,6BACb,OACA,SAC8C;AAC9C,KAAI,MAAM,oBAAoB,KAC5B;CAGF,MAAM,qBAA8C,EAAE;AAEtD,KAAI,MAAM,iBAAiB,UAAU,KAEnC,oBAAmB,SAAS,2BADL,MAAM,8BAA8B,MAAM,iBAAiB,QAAQ,QAAQ,EAC3B,GAAG,MAAM,GAAG,SAAS;AAG9F,KAAI,MAAM,iBAAiB,WAAW,MAAM;EAE1C,MAAM,oBAAoB,2BADF,MAAM,8BAA8B,MAAM,iBAAiB,SAAS,QAAQ,EAC9B,GAAG,MAAM,GAAG,UAAU;AAC5F,MAAI,qBAAqB,KACvB,oBAAmB,UAAU;;AAIjC,KAAI,MAAM,iBAAiB,WAAW,KAEpC,oBAAmB,UADK,MAAM,8BAA8B,MAAM,iBAAiB,SAAS,QAAQ;AAItG,QAAO,OAAO,KAAK,mBAAmB,CAAC,SAAS,IAAI,qBAAqB,KAAA;;AAG3E,eAAe,2BACb,OACA,QAC8B;CAC9B,MAAM,wBAAwB,qBAAqB,OAAO,kBAAkB,OAAO,CAAC;CACpF,MAAM,4BAA4B,MAAM,6BAA6B,uBAAuB,EAC1F,KAAK,mBAAmB,OAAO,OAAO,QAAQ,IAAI,EACnD,CAAC;AAEF,KAAI,6BAA6B,KAC/B,QAAO;AAGT,QAAO;EACL,GAAG;EACH,YAAY;GACV,GAAG,sBAAsB;GACzB,GAAG;GACJ;EACF;;AAGH,SAAS,mCACP,SACwE;AACxE,QAAO,QAAQ,sBAAsB;;AAGvC,SAAS,mCACP,SACwE;AACxE,QAAO,QAAQ,sBAAsB;;AAGvC,SAAS,uCACP,SAC4E;AAC5E,QAAO,QAAQ,sBAAsB;;;;;;;;;AAUvC,SAAgB,cAAc,SAAoD;CAChF,MAAM,4BAA4B,QAAQ,qBAAqB,QAAQ,YAAY;CACnF,MAAM,sBAAsB,6BAA6B,2BAA2B,QAAQ,oBAAoB;CAChH,MAAM,mBAAmB,mCAAmC,QAAQ,GAChE;EACE,QAAQ,QAAQ;EAChB,SAAS,QAAQ;EACjB,SAAS,QAAQ;EAClB,GACD,mCAAmC,QAAQ,GACzC;EACE,SAAS,QAAQ;EACjB,SAAS,QAAQ;EAClB,GACD,uCAAuC,QAAQ,GAC7C;EACE,QAAQ,QAAQ;EAChB,SAAS,QAAQ;EACjB,SAAS,QAAQ;EAClB,GACD,KAAA;AAER,QAAO;EACL,SAAS,QAAQ,WAAW,EAAE;EAC9B,iBAAiB,4BAA4B,QAAQ;EACrD,IAAI,QAAQ,MAAM,qBAAqB,qBAAqB,QAAQ,MAAM;EAC1E,mBAAmB;EACnB;EACA,OAAO,QAAQ;EACf,YAAY,QAAQ;EACpB,UAAU,QAAQ;EAClB;EACD;;;;;;;;;AAUH,SAAgB,iBAAiB,SAA0D;AACzF,QAAO;EACL,IAAI,QAAQ;EACZ,mBAAmB,QAAQ;EAC3B,qBAAqB,6BAA6B,QAAQ,mBAAmB,QAAQ,oBAAoB;EACzG,aAAa,QAAQ;EACrB,YAAY,QAAQ;EACpB,aAAa,QAAQ;EACtB;;;;;;;;;;;;;;;;AA4CH,SAAgB,gBACd,SACA,OACA,SACiB;CACjB,MAAM,oBAAoB,QAAQ,KAAK,OAAO,OAAO,QAAQ;AAE7D,KAAI,qBAAqB,KACvB,OAAM,IAAI,MAAM,WAAW,MAAM,gBAAgB,QAAQ,KAAK,IAAI;CAGpE,MAAM,QAAQ,mBAAmB,QAAQ,QAAQ,kBAAkB;AACnE,KAAI,SAAS,KACX,OAAM,IAAI,MAAM,kCAAkC,kBAAkB,SAAS,MAAM,gBAAgB,QAAQ,KAAK,IAAI;AAGtH,QAAO;;;;;;;;;;;;;;;AAgBT,SAAgB,aACd,SACA,SACiB;AACjB,QAAO,gBAAgB,SAAS,OAAO,QAAQ;;;;;;;;;;;;;;;AAgBjD,SAAgB,cACd,SACA,SACiB;AACjB,QAAO,gBAAgB,SAAS,QAAQ,QAAQ;;;;;;;;;;;;;;;AAgBlD,SAAgB,gBAAgB,GAAG,OAAmC;AACpE,QAAO,EACL,OAAO,MAAM,KAAK,IAAI,IAAI,MAAM,CAAC,EAClC;;;;;;;;;AAUH,SAAgB,cAAc,SAA6C;AACzE,QAAO;EACL,aAAa,QAAQ;GACnB,MAAM,MAAM,OAAO,OAAO,QAAQ,OAAO,QAAQ;GACjD,MAAM,sBAAsB,QAAQ,UAAU,KAAI,aAAY,gCAAgC,UAAU,IAAI,CAAC;AAE7G,UAAO;IACL,GAAG;IACH,eAAe,CACb,GAAI,OAAO,iBAAiB,EAAE,EAC9B,GAAG,oBACJ;IACF;;EAEH,MAAM;EACP;;;;;;;;;AAUH,SAAgB,WAAW,SAA0C;AACnE,QAAO;EACL,MAAM,aAAa,QAAQ;GACzB,MAAM,iBAAiB,MAAM,QAAQ,IAAI,QAAQ,OAAO,IAAI,OAAM,UAAS,2BAA2B,OAAO,OAAO,CAAC,CAAC;AAEtH,UAAO;IACL,GAAG;IACH,QAAQ,CACN,GAAI,OAAO,UAAU,EAAE,EACvB,GAAG,eACJ;IACF;;EAEH,MAAM;EACP"}
|
|
@@ -199,6 +199,13 @@ function normalizeConfig(config, cwd) {
|
|
|
199
199
|
const inheritedReporterReferences = config?.reporters ?? [];
|
|
200
200
|
return projects.map((project) => normalizeProjectConfig(project, cwd, inheritedConcurrency, inheritedModels, inheritedReporterReferences));
|
|
201
201
|
}
|
|
202
|
+
function normalizeReportingConfig(config) {
|
|
203
|
+
if (config == null) return;
|
|
204
|
+
return { openTelemetry: config.openTelemetry == null ? void 0 : {
|
|
205
|
+
enabled: config.openTelemetry.enabled ?? false,
|
|
206
|
+
onRunEnd: config.openTelemetry.onRunEnd
|
|
207
|
+
} };
|
|
208
|
+
}
|
|
202
209
|
/**
|
|
203
210
|
* Detects which top-level config mode is active.
|
|
204
211
|
*
|
|
@@ -261,14 +268,16 @@ async function loadVievalCliConfig(options = {}) {
|
|
|
261
268
|
concurrency: void 0,
|
|
262
269
|
configFilePath: null,
|
|
263
270
|
env: {},
|
|
264
|
-
projects: normalizeConfig(null, cwd)
|
|
271
|
+
projects: normalizeConfig(null, cwd),
|
|
272
|
+
reporting: void 0
|
|
265
273
|
};
|
|
266
274
|
const config = loadedConfig.config;
|
|
267
275
|
return {
|
|
268
276
|
concurrency: config.concurrency,
|
|
269
277
|
configFilePath: loadedConfig.configFilePath,
|
|
270
278
|
env: config.env ?? {},
|
|
271
|
-
projects: normalizeConfig(config, dirname(loadedConfig.configFilePath))
|
|
279
|
+
projects: normalizeConfig(config, dirname(loadedConfig.configFilePath)),
|
|
280
|
+
reporting: normalizeReportingConfig(config.reporting)
|
|
272
281
|
};
|
|
273
282
|
} catch (error) {
|
|
274
283
|
const errorMessage = errorMessageFrom(error) ?? "Unknown config loading error.";
|
|
@@ -277,6 +286,133 @@ async function loadVievalCliConfig(options = {}) {
|
|
|
277
286
|
}
|
|
278
287
|
}
|
|
279
288
|
//#endregion
|
|
289
|
+
//#region src/core/telemetry/noop.ts
|
|
290
|
+
/**
|
|
291
|
+
* Creates the default no-op telemetry runtime.
|
|
292
|
+
*
|
|
293
|
+
* Use when:
|
|
294
|
+
* - OpenTelemetry is not enabled by config
|
|
295
|
+
* - tests need deterministic pass-through execution
|
|
296
|
+
*
|
|
297
|
+
* Expects:
|
|
298
|
+
* - callers still wrap run/task/case boundaries with `withSpan`
|
|
299
|
+
*
|
|
300
|
+
* Returns:
|
|
301
|
+
* - a runtime that never emits external telemetry and never changes control flow
|
|
302
|
+
*/
|
|
303
|
+
function createNoopTelemetryRuntime() {
|
|
304
|
+
return {
|
|
305
|
+
async withSpan(_name, _attributes, callback) {
|
|
306
|
+
return await callback();
|
|
307
|
+
},
|
|
308
|
+
addEvent() {},
|
|
309
|
+
setAttributes() {},
|
|
310
|
+
recordException() {}
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
//#endregion
|
|
314
|
+
//#region src/core/telemetry/otel.ts
|
|
315
|
+
async function importOpenTelemetryApi() {
|
|
316
|
+
return await import("@opentelemetry/api");
|
|
317
|
+
}
|
|
318
|
+
function isOpenTelemetryAttributeScalar(value) {
|
|
319
|
+
return typeof value === "boolean" || typeof value === "number" || typeof value === "string";
|
|
320
|
+
}
|
|
321
|
+
function isHomogeneousOpenTelemetryAttributeArray(value) {
|
|
322
|
+
if (value.length === 0) return true;
|
|
323
|
+
const firstType = typeof value[0];
|
|
324
|
+
if (firstType !== "boolean" && firstType !== "number" && firstType !== "string") return false;
|
|
325
|
+
return value.every((item) => typeof item === firstType);
|
|
326
|
+
}
|
|
327
|
+
function stringifyAttributeValue(value) {
|
|
328
|
+
try {
|
|
329
|
+
return JSON.stringify(value);
|
|
330
|
+
} catch {
|
|
331
|
+
return String(value);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Normalizes JSON-compatible telemetry attributes into OpenTelemetry-safe attributes.
|
|
336
|
+
*
|
|
337
|
+
* Before:
|
|
338
|
+
* - `{ nil: null, nested: ['a', [1, null]], scalarArray: ['a', 1, true] }`
|
|
339
|
+
*
|
|
340
|
+
* After:
|
|
341
|
+
* - `{ nested: '["a",[1,null]]', scalarArray: ['a', 1, true] }`
|
|
342
|
+
*/
|
|
343
|
+
function normalizeOpenTelemetryAttributes(attributes) {
|
|
344
|
+
if (attributes == null) return;
|
|
345
|
+
const normalized = {};
|
|
346
|
+
for (const [key, value] of Object.entries(attributes)) {
|
|
347
|
+
if (value == null) continue;
|
|
348
|
+
if (isOpenTelemetryAttributeScalar(value)) {
|
|
349
|
+
normalized[key] = value;
|
|
350
|
+
continue;
|
|
351
|
+
}
|
|
352
|
+
if (Array.isArray(value)) {
|
|
353
|
+
normalized[key] = isHomogeneousOpenTelemetryAttributeArray(value) ? value : stringifyAttributeValue(value) ?? "";
|
|
354
|
+
continue;
|
|
355
|
+
}
|
|
356
|
+
const stringified = stringifyAttributeValue(value);
|
|
357
|
+
if (stringified != null) normalized[key] = stringified;
|
|
358
|
+
}
|
|
359
|
+
return normalized;
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Creates an OpenTelemetry-backed runtime using active spans.
|
|
363
|
+
*
|
|
364
|
+
* Use when:
|
|
365
|
+
* - `reporting.openTelemetry.enabled` is true
|
|
366
|
+
* - the user's config has initialized an OpenTelemetry SDK or intentionally relies on the API no-op provider
|
|
367
|
+
*
|
|
368
|
+
* Expects:
|
|
369
|
+
* - `@opentelemetry/api` is resolvable when enabled
|
|
370
|
+
* - SDK lifecycle is managed by user config and `reporting.openTelemetry.onRunEnd`
|
|
371
|
+
*
|
|
372
|
+
* Returns:
|
|
373
|
+
* - a runtime that starts active spans and forwards events to the current active span
|
|
374
|
+
*/
|
|
375
|
+
function createOpenTelemetryRuntime(options = {}) {
|
|
376
|
+
const importApi = options.importApi ?? importOpenTelemetryApi;
|
|
377
|
+
let apiPromise;
|
|
378
|
+
let loadedApi;
|
|
379
|
+
async function getApi() {
|
|
380
|
+
apiPromise ??= importApi().then((api) => {
|
|
381
|
+
loadedApi = api;
|
|
382
|
+
return api;
|
|
383
|
+
});
|
|
384
|
+
return await apiPromise;
|
|
385
|
+
}
|
|
386
|
+
return {
|
|
387
|
+
async withSpan(name, attributes, callback) {
|
|
388
|
+
const api = await getApi();
|
|
389
|
+
return await api.trace.getTracer("vieval").startActiveSpan(name, { attributes: normalizeOpenTelemetryAttributes(attributes) ?? {} }, async (span) => {
|
|
390
|
+
try {
|
|
391
|
+
return await callback();
|
|
392
|
+
} catch (error) {
|
|
393
|
+
span.recordException(error);
|
|
394
|
+
span.setStatus({
|
|
395
|
+
code: api.SpanStatusCode.ERROR,
|
|
396
|
+
message: errorMessageFrom(error) ?? "Unknown error"
|
|
397
|
+
});
|
|
398
|
+
throw error;
|
|
399
|
+
} finally {
|
|
400
|
+
span.end();
|
|
401
|
+
}
|
|
402
|
+
});
|
|
403
|
+
},
|
|
404
|
+
addEvent(name, attributes) {
|
|
405
|
+
loadedApi?.trace.getActiveSpan()?.addEvent(name, normalizeOpenTelemetryAttributes(attributes));
|
|
406
|
+
},
|
|
407
|
+
setAttributes(attributes) {
|
|
408
|
+
loadedApi?.trace.getActiveSpan()?.setAttributes(normalizeOpenTelemetryAttributes(attributes) ?? {});
|
|
409
|
+
},
|
|
410
|
+
recordException(error) {
|
|
411
|
+
loadedApi?.trace.getActiveSpan()?.recordException(error);
|
|
412
|
+
}
|
|
413
|
+
};
|
|
414
|
+
}
|
|
415
|
+
//#endregion
|
|
280
416
|
//#region src/dsl/registry.ts
|
|
281
417
|
const registryStoreSymbol = Symbol.for("vieval.dsl.registry.store");
|
|
282
418
|
function getRegistryStore() {
|
|
@@ -321,6 +457,6 @@ function consumeModuleRegistrations(moduleHref) {
|
|
|
321
457
|
return definitions;
|
|
322
458
|
}
|
|
323
459
|
//#endregion
|
|
324
|
-
export {
|
|
460
|
+
export { createOpenTelemetryRuntime as a, detectCliConfigMode as c, loadVievalCliConfig as d, registerEvalDefinition as i, loadEnv$1 as l, consumeModuleRegistrations as n, createNoopTelemetryRuntime as o, endModuleRegistration as r, defineConfig as s, beginModuleRegistration as t, loadRawVievalConfig as u };
|
|
325
461
|
|
|
326
|
-
//# sourceMappingURL=registry-
|
|
462
|
+
//# sourceMappingURL=registry-BHGMxjpA.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry-BHGMxjpA.mjs","names":["loadEnv","loadViteEnv"],"sources":["../src/cli/config.ts","../src/core/telemetry/noop.ts","../src/core/telemetry/otel.ts","../src/dsl/registry.ts"],"sourcesContent":["import type { CliReportingConfig, ConfigHookPlugin, MatrixDefinition, MatrixLayer, TaskRunContext } from '../config'\nimport type { ModelDefinition } from '../config/models'\nimport type { RunResult, TaskExecutionContext } from '../core/runner'\nimport type { InferenceExecutor, ScheduledTask } from '../core/runner/schedule'\nimport type { VievalVitestCompatReporterReference } from './reporters/vitest-compat-reporter'\n\nimport process from 'node:process'\n\nimport { access, readFile } from 'node:fs/promises'\nimport { createRequire } from 'node:module'\nimport { dirname, extname, isAbsolute, join, resolve } from 'node:path'\nimport { pathToFileURL } from 'node:url'\n\nimport { errorMessageFrom } from '@moeru/std'\nimport { createDefineConfig, loadConfig } from 'c12'\nimport { loadEnv as loadViteEnv } from 'vite'\n\nconst matrixLayerKeys = new Set(['disable', 'extend', 'override'])\nconst ambiguousMatrixDefinitionErrorMessage = 'Ambiguous matrix definition: cannot mix reserved layer keys (disable, extend, override) with matrix axis keys.'\nconst require = createRequire(import.meta.url)\n\n/**\n * CLI plugin shape bound to the full CLI config object.\n */\nexport type CliConfigPlugin = ConfigHookPlugin<CliConfig>\n\n/**\n * Concurrency limits that can be declared in CLI-facing config.\n *\n * Use when:\n * - the CLI needs independent caps for workspace, project, task, attempt, or case scheduling scopes\n * - config authors want to define concurrency without wiring runtime execution yet\n *\n * Expects:\n * - each provided value to be a positive integer chosen by the caller\n *\n * Returns:\n * - one partial concurrency descriptor keyed by scheduling scope\n */\nexport interface CliConcurrencyConfig {\n /**\n * Workspace-level concurrency cap.\n */\n workspace?: number\n /**\n * Project-level concurrency cap.\n */\n project?: number\n /**\n * Task-level concurrency cap.\n */\n task?: number\n /**\n * Attempt-level concurrency cap.\n */\n attempt?: number\n /**\n * Case-level concurrency cap.\n */\n case?: number\n}\n\n/**\n * Defines one project block for `vieval run`.\n */\nexport interface CliProjectConfig {\n /**\n * Project label used in summary output.\n */\n name: string\n /**\n * Project root used for include/exclude glob matching.\n *\n * @default process cwd\n */\n root?: string\n /**\n * Glob patterns for eval file discovery.\n *\n * @default Common eval file globs for TypeScript and JavaScript module formats.\n */\n include?: string[]\n /**\n * Glob patterns excluded from discovery.\n *\n * @default Common exclusion globs for dependencies, build output, and VCS directories.\n */\n exclude?: string[]\n /**\n * Providers expanded by scheduler.\n *\n * @default [{ id: 'default' }]\n */\n inferenceExecutors?: InferenceExecutor[]\n /**\n * Model definitions available to project runtime execution.\n *\n * Inference executors control schedule fan-out, while models provide\n * runtime lookup metadata for model plugin helpers during task execution.\n *\n * @default inherited from top-level config models\n */\n models?: ModelDefinition[]\n /**\n * Optional run-time matrix dimensions.\n */\n runMatrix?: MatrixDefinition | MatrixLayer\n /**\n * Optional eval-time matrix dimensions.\n */\n evalMatrix?: MatrixDefinition | MatrixLayer\n /**\n * Optional project-scoped concurrency overrides.\n *\n * @default inherited from top-level or CLI execution settings\n */\n concurrency?: Omit<CliConcurrencyConfig, 'workspace'>\n /**\n * Optional task executor.\n *\n * Use when this project should execute live inferenceExecutor requests.\n * If omitted, `vieval run` performs collection + scheduling only.\n */\n executor?: (task: ScheduledTask, context: CliProjectExecutorContext) => Promise<RunResult>\n /**\n * Optional project-local plugins.\n */\n plugins?: CliConfigPlugin[]\n /**\n * Optional vitest-compatible reporter modules.\n *\n * Use when:\n * - project runs should emit additional reporter callbacks using Vitest-style lifecycle names\n *\n * @default []\n */\n reporters?: VievalVitestCompatReporterReference[]\n}\n\n/**\n * One workspace descriptor for workspace-mode configs.\n */\nexport interface CliWorkspaceConfig {\n /**\n * Workspace identifier.\n */\n id: string\n /**\n * Workspace root path.\n */\n root: string\n}\n\n/**\n * One explicit comparison method descriptor.\n */\nexport interface CliComparisonMethodConfig {\n /**\n * Method identifier shown in compare reports.\n */\n id: string\n /**\n * Workspace path containing this method's `vieval.config.*`.\n */\n workspace: string\n /**\n * Project name to execute inside workspace config.\n */\n project: string\n /**\n * Optional explicit config file path for this workspace.\n */\n configFilePath?: string\n}\n\n/**\n * Benchmark identity and shared cache namespace.\n */\nexport interface CliComparisonBenchmarkConfig {\n /**\n * Benchmark identifier used in report artifacts.\n */\n id: string\n /**\n * Shared cache namespace reused across method runs.\n */\n sharedCaseNamespace: string\n}\n\n/**\n * One comparison entry loaded by `vieval compare`.\n */\nexport interface CliComparisonConfig {\n /**\n * Comparison id selected by `--comparison`.\n */\n id: string\n /**\n * Benchmark metadata for reporting and shared cache coordination.\n */\n benchmark: CliComparisonBenchmarkConfig\n /**\n * Optional explicit method list.\n */\n methods?: CliComparisonMethodConfig[]\n /**\n * Optional workspace glob(s) discovered relative to config directory.\n */\n includesWorkspaces?: string | string[]\n /**\n * Optional workspace exclude glob(s), also relative to config directory.\n */\n excludesWorkspaces?: string | string[]\n}\n\n/**\n * Execution context exposed to project-level `executor` implementations.\n *\n * Use when:\n * - a project executor needs task-scoped models plus case reporter hooks\n * - custom scheduling logic wants the same hook shape as `TaskRunContext`\n *\n * Expects:\n * - `models` exposes configured model registrations for plugin helpers\n * - `reporterHooks` follows `TaskRunContext['reporterHooks']`\n * - `telemetry` follows `TaskRunContext['telemetry']`\n * - `runtimeConcurrency` follows `TaskRunContext['runtimeConcurrency']`\n */\nexport interface CliProjectExecutorContext extends TaskExecutionContext {\n reporterHooks?: TaskRunContext['reporterHooks']\n telemetry?: TaskRunContext['telemetry']\n runtimeConcurrency?: TaskRunContext['runtimeConcurrency']\n}\n\n/**\n * Top-level CLI config loaded from `vieval.config.*`.\n */\ninterface CliConfigBase {\n /**\n * Global model definitions inherited by projects.\n *\n * @default []\n */\n models?: ModelDefinition[]\n /**\n * Global concurrency defaults inherited by projects and tasks.\n *\n * Use when:\n * - config authors want one shared concurrency policy across workspace, project, task, attempt, and case scopes\n * - project-local overrides should start from a top-level baseline\n *\n * Expects:\n * - each provided value to be a positive integer chosen by the caller\n *\n * @default undefined\n */\n concurrency?: CliConcurrencyConfig\n /**\n * Global config plugins.\n *\n * @default []\n */\n plugins?: CliConfigPlugin[]\n /**\n * Global vitest-compatible reporter modules inherited by projects.\n *\n * @default []\n */\n reporters?: VievalVitestCompatReporterReference[]\n /**\n * Environment variables injected into `process.env` during `vieval run`.\n *\n * Use when:\n * - eval tasks depend on runtime env values (for example inferenceExecutor API keys)\n * - config wants deterministic env values without shell-level exports\n *\n * @default {}\n */\n env?: NodeJS.ProcessEnv\n /**\n * Optional reporting integrations shared by CLI run orchestration.\n *\n * @default undefined\n */\n reporting?: CliReportingConfig\n}\n\n/**\n * Project mode config for `vieval run`.\n */\nexport interface CliProjectModeConfig extends CliConfigBase {\n /**\n * Project list expanded by `vieval run`.\n *\n * @default [{ name: 'default' }]\n */\n projects?: CliProjectConfig[]\n comparisons?: never\n workspaces?: never\n}\n\n/**\n * Workspace mode config placeholder for future workspace orchestration.\n */\nexport interface CliWorkspaceModeConfig extends CliConfigBase {\n workspaces: CliWorkspaceConfig[]\n projects?: never\n comparisons?: never\n}\n\n/**\n * Comparison mode config for `vieval compare`.\n */\nexport interface CliComparisonModeConfig extends CliConfigBase {\n comparisons: CliComparisonConfig[]\n projects?: never\n workspaces?: never\n}\n\n/**\n * Top-level CLI config loaded from `vieval.config.*`.\n *\n * Exactly one top-level mode is allowed:\n * - `projects`\n * - `workspaces`\n * - `comparisons`\n */\nexport type CliConfig = CliProjectModeConfig | CliWorkspaceModeConfig | CliComparisonModeConfig\n\nexport type CliConfigMode = 'comparisons' | 'projects' | 'workspaces'\n\nexport interface LoadedRawCliConfig {\n config: CliConfig | null\n configFilePath: string | null\n}\n\n/**\n * Normalized CLI project used by runtime orchestration.\n */\nexport interface NormalizedCliProjectConfig {\n concurrency?: Omit<CliConcurrencyConfig, 'workspace'>\n exclude: string[]\n executor?: (task: ScheduledTask, context: CliProjectExecutorContext) => Promise<RunResult>\n include: string[]\n runMatrix?: MatrixLayer\n evalMatrix?: MatrixLayer\n models: ModelDefinition[]\n name: string\n inferenceExecutors: InferenceExecutor[]\n root: string\n reporters: VievalVitestCompatReporterReference[]\n}\n\n/**\n * Result of loading and normalizing a config file.\n */\nexport interface LoadedCliConfig {\n concurrency?: CliConcurrencyConfig\n configFilePath: string | null\n env: NodeJS.ProcessEnv\n projects: NormalizedCliProjectConfig[]\n reporting?: CliReportingConfig\n}\n\n/**\n * Runtime options for config loading.\n */\nexport interface LoadVievalCliConfigOptions {\n /**\n * Starting directory for config lookup.\n *\n * @default process.cwd()\n */\n cwd?: string\n /**\n * Explicit config file path.\n */\n configFilePath?: string\n}\n\n/**\n * Helper used by `vieval.config.*` for better type inference.\n */\nexport const defineConfig = createDefineConfig<CliConfig>()\n\n/**\n * Loads `.env*` files using Vite's env resolution behavior.\n *\n * Use when:\n * - `vieval.config.*` should mirror Vitest/Vite env loading semantics\n * - config wants to populate top-level `env` via file-based values\n *\n * Expects:\n * - `mode` to match the env file suffix (`.env.<mode>`)\n * - `envDir` to point at the directory containing `.env` files\n *\n * Returns:\n * - Key/value map compatible with `CliConfig['env']`\n */\nexport function loadEnv(mode: string, envDir: string, prefixes: string | string[] = ''): NodeJS.ProcessEnv {\n return loadViteEnv(mode, envDir, prefixes)\n}\n\nasync function applyVievalPlugins(config: CliConfig): Promise<CliConfig> {\n let currentConfig: CliConfig = config\n const plugins = currentConfig.plugins ?? []\n\n for (const plugin of plugins) {\n if (plugin.configVieval == null) {\n continue\n }\n\n const nextConfig = await plugin.configVieval(currentConfig)\n if (nextConfig != null) {\n currentConfig = {\n ...currentConfig,\n ...nextConfig,\n } as CliConfig\n }\n }\n\n for (const plugin of plugins) {\n await plugin.configVievalResolved?.(currentConfig)\n }\n\n return currentConfig\n}\n\nasync function isReadableFile(filePath: string): Promise<boolean> {\n try {\n await access(filePath)\n return true\n }\n catch {\n return false\n }\n}\n\nfunction isConfigFileExtensionUsingRequire(extension: string): boolean {\n return extension === '.cjs' || extension === '.cts'\n}\n\nfunction isConfigFileExtensionUsingJsonParse(extension: string): boolean {\n return extension === '.json'\n}\n\nasync function importVievalConfigModule(filePath: string): Promise<unknown> {\n const extension = extname(filePath)\n\n if (isConfigFileExtensionUsingJsonParse(extension)) {\n const raw = await readFile(filePath, 'utf-8')\n return JSON.parse(raw) as unknown\n }\n\n if (isConfigFileExtensionUsingRequire(extension)) {\n return require(filePath) as unknown\n }\n\n return import(pathToFileURL(filePath).href)\n}\n\nfunction resolveConfigExport(moduleValue: unknown): unknown {\n if (moduleValue == null) {\n return null\n }\n\n if (typeof moduleValue !== 'object') {\n return moduleValue\n }\n\n if ('default' in moduleValue) {\n return (moduleValue as { default: unknown }).default\n }\n\n return moduleValue\n}\n\nasync function findNearestConfigFile(startDirectory: string): Promise<string | null> {\n const supportedFileNames = [\n 'vieval.config.ts',\n 'vieval.config.mts',\n 'vieval.config.cts',\n 'vieval.config.js',\n 'vieval.config.mjs',\n 'vieval.config.cjs',\n 'vieval.config.json',\n ]\n\n let currentDirectory = resolve(startDirectory)\n\n while (true) {\n for (const fileName of supportedFileNames) {\n const candidatePath = join(currentDirectory, fileName)\n if (await isReadableFile(candidatePath)) {\n return candidatePath\n }\n }\n\n const parentDirectory = dirname(currentDirectory)\n if (parentDirectory === currentDirectory) {\n return null\n }\n currentDirectory = parentDirectory\n }\n}\n\nasync function resolveVievalConfig(\n cwd: string,\n explicitConfigFilePath: string | undefined,\n): Promise<{\n config: CliConfig | null\n configFilePath: string | null\n}> {\n const resolvedConfigFilePath = explicitConfigFilePath == null\n ? await findNearestConfigFile(cwd)\n : (isAbsolute(explicitConfigFilePath) ? explicitConfigFilePath : resolve(cwd, explicitConfigFilePath))\n\n if (explicitConfigFilePath != null && resolvedConfigFilePath != null && !await isReadableFile(resolvedConfigFilePath)) {\n throw new Error(`Config file does not exist or is not readable: ${resolvedConfigFilePath}`)\n }\n\n if (resolvedConfigFilePath == null) {\n return {\n config: null,\n configFilePath: null,\n }\n }\n\n const loaded = await loadConfig<CliConfig>({\n configFile: resolvedConfigFilePath,\n cwd,\n dotenv: false,\n envName: false,\n extend: false,\n import: importVievalConfigModule,\n packageJson: false,\n rcFile: false,\n resolveModule: resolveConfigExport,\n })\n return {\n config: loaded.config,\n configFilePath: resolvedConfigFilePath,\n }\n}\n\nfunction isLayerMatrixDefinition(matrix: MatrixDefinition | MatrixLayer): matrix is MatrixLayer {\n const matrixKeys = Object.keys(matrix)\n return (\n matrixKeys.length > 0\n && matrixKeys.every(key => matrixLayerKeys.has(key))\n )\n}\n\nfunction assertNonAmbiguousMatrixDefinition(matrix: MatrixDefinition | MatrixLayer): void {\n const matrixKeys = Object.keys(matrix)\n const hasReservedKeys = matrixKeys.some(key => matrixLayerKeys.has(key))\n const hasAxisKeys = matrixKeys.some(key => !matrixLayerKeys.has(key))\n\n if (hasReservedKeys && hasAxisKeys) {\n throw new TypeError(ambiguousMatrixDefinitionErrorMessage)\n }\n}\n\nfunction normalizeMatrixLayerInput(matrix: MatrixDefinition | MatrixLayer | undefined): MatrixLayer | undefined {\n if (matrix == null) {\n return undefined\n }\n\n assertNonAmbiguousMatrixDefinition(matrix)\n\n if (isLayerMatrixDefinition(matrix)) {\n return matrix\n }\n\n return {\n extend: matrix,\n }\n}\n\nfunction toProjectConcurrencyDefaults(\n concurrency: CliConcurrencyConfig | undefined,\n): Omit<CliConcurrencyConfig, 'workspace'> | undefined {\n if (concurrency == null) {\n return undefined\n }\n\n return {\n attempt: concurrency.attempt,\n case: concurrency.case,\n project: concurrency.project,\n task: concurrency.task,\n }\n}\n\nfunction mergeProjectConcurrency(\n inheritedConcurrency: Omit<CliConcurrencyConfig, 'workspace'> | undefined,\n projectConcurrency: Omit<CliConcurrencyConfig, 'workspace'> | undefined,\n): Omit<CliConcurrencyConfig, 'workspace'> | undefined {\n if (inheritedConcurrency == null && projectConcurrency == null) {\n return undefined\n }\n\n return {\n attempt: projectConcurrency?.attempt ?? inheritedConcurrency?.attempt,\n case: projectConcurrency?.case ?? inheritedConcurrency?.case,\n project: projectConcurrency?.project ?? inheritedConcurrency?.project,\n task: projectConcurrency?.task ?? inheritedConcurrency?.task,\n }\n}\n\nfunction normalizeProjectConfig(\n project: CliProjectConfig,\n cwd: string,\n inheritedConcurrency: Omit<CliConcurrencyConfig, 'workspace'> | undefined,\n inheritedModels: readonly ModelDefinition[],\n inheritedReporterReferences: readonly VievalVitestCompatReporterReference[],\n): NormalizedCliProjectConfig {\n const include = project.include ?? [\n '**/*.eval.ts',\n '**/*.eval.mts',\n '**/*.eval.cts',\n '**/*.eval.js',\n '**/*.eval.mjs',\n '**/*.eval.cjs',\n ]\n const exclude = project.exclude ?? [\n '**/node_modules/**',\n '**/dist/**',\n '**/.git/**',\n ]\n const models = project.models ?? [...inheritedModels]\n const inferenceExecutors = project.inferenceExecutors ?? [{ id: 'default' }]\n const root = project.root == null\n ? cwd\n : (isAbsolute(project.root) ? project.root : resolve(cwd, project.root))\n const reporters = project.reporters ?? [...inheritedReporterReferences]\n const concurrency = mergeProjectConcurrency(inheritedConcurrency, project.concurrency)\n\n return {\n concurrency,\n exclude,\n executor: project.executor,\n include,\n evalMatrix: normalizeMatrixLayerInput(project.evalMatrix),\n models,\n name: project.name,\n inferenceExecutors,\n reporters,\n runMatrix: normalizeMatrixLayerInput(project.runMatrix),\n root,\n }\n}\n\nfunction normalizeConfig(config: CliConfig | null | undefined, cwd: string): NormalizedCliProjectConfig[] {\n if (config != null) {\n const mode = detectCliConfigMode(config)\n if (mode === 'comparisons') {\n throw new Error('vieval run requires project-mode config. Received comparison-mode config.')\n }\n if (mode === 'workspaces') {\n throw new Error('vieval run requires project-mode config. Received workspace-mode config.')\n }\n }\n\n const projects = config?.projects ?? [{ name: 'default' }]\n const inheritedConcurrency = toProjectConcurrencyDefaults(config?.concurrency)\n const inheritedModels = config?.models ?? []\n const inheritedReporterReferences = config?.reporters ?? []\n\n return projects.map(project => normalizeProjectConfig(\n project,\n cwd,\n inheritedConcurrency,\n inheritedModels,\n inheritedReporterReferences,\n ))\n}\n\nfunction normalizeReportingConfig(config: CliReportingConfig | undefined): CliReportingConfig | undefined {\n if (config == null) {\n return undefined\n }\n\n return {\n openTelemetry: config.openTelemetry == null\n ? undefined\n : {\n enabled: config.openTelemetry.enabled ?? false,\n onRunEnd: config.openTelemetry.onRunEnd,\n },\n }\n}\n\n/**\n * Detects which top-level config mode is active.\n *\n * Expects:\n * - exactly one of `projects`, `workspaces`, or `comparisons`\n *\n * Returns:\n * - active top-level mode key\n */\nexport function detectCliConfigMode(config: CliConfig): CliConfigMode {\n const declaredModes: CliConfigMode[] = []\n if (config.projects != null) {\n declaredModes.push('projects')\n }\n if (config.workspaces != null) {\n declaredModes.push('workspaces')\n }\n if (config.comparisons != null) {\n declaredModes.push('comparisons')\n }\n\n if (declaredModes.length > 1) {\n throw new Error(`Invalid vieval config: top-level keys are mutually exclusive. Found ${declaredModes.join(', ')}.`)\n }\n\n return declaredModes[0] ?? 'projects'\n}\n\n/**\n * Loads nearest `vieval.config.*` without project normalization.\n */\nexport async function loadRawVievalConfig(options: LoadVievalCliConfigOptions = {}): Promise<LoadedRawCliConfig> {\n const cwd = options.cwd ?? process.cwd()\n\n try {\n const loadedConfig = await resolveVievalConfig(cwd, options.configFilePath)\n if (loadedConfig.configFilePath == null || loadedConfig.config == null) {\n return {\n config: null,\n configFilePath: null,\n }\n }\n\n const config = await applyVievalPlugins(loadedConfig.config)\n detectCliConfigMode(config)\n\n return {\n config,\n configFilePath: loadedConfig.configFilePath,\n }\n }\n catch (error) {\n const errorMessage = errorMessageFrom(error) ?? 'Unknown config loading error.'\n const configFilePath = options.configFilePath == null\n ? 'vieval.config'\n : (isAbsolute(options.configFilePath) ? options.configFilePath : resolve(cwd, options.configFilePath))\n throw new Error(`Failed to load vieval config \"${configFilePath}\": ${errorMessage}`, { cause: error })\n }\n}\n\n/**\n * Loads nearest `vieval.config.*` and returns normalized project definitions.\n *\n * Call stack:\n *\n * {@link loadVievalCliConfig}\n * -> {@link resolveVievalConfig}\n * -> {@link normalizeConfig}\n * -> {@link NormalizedCliProjectConfig}[]\n *\n * Use when:\n * - CLI orchestration needs project includes/excludes similar to Vitest\n * - callers want config auto-discovery without manual imports in eval files\n */\nexport async function loadVievalCliConfig(options: LoadVievalCliConfigOptions = {}): Promise<LoadedCliConfig> {\n const cwd = options.cwd ?? process.cwd()\n try {\n const loadedConfig = await loadRawVievalConfig(options)\n if (loadedConfig.configFilePath == null || loadedConfig.config == null) {\n return {\n concurrency: undefined,\n configFilePath: null,\n env: {},\n projects: normalizeConfig(null, cwd),\n reporting: undefined,\n }\n }\n\n const config = loadedConfig.config\n\n return {\n concurrency: config.concurrency,\n configFilePath: loadedConfig.configFilePath,\n env: config.env ?? {},\n projects: normalizeConfig(config, dirname(loadedConfig.configFilePath)),\n reporting: normalizeReportingConfig(config.reporting),\n }\n }\n catch (error) {\n const errorMessage = errorMessageFrom(error) ?? 'Unknown config loading error.'\n const configFilePath = options.configFilePath == null\n ? 'vieval.config'\n : (isAbsolute(options.configFilePath) ? options.configFilePath : resolve(cwd, options.configFilePath))\n throw new Error(`Failed to load vieval config \"${configFilePath}\": ${errorMessage}`, { cause: error })\n }\n}\n","import type { TelemetryRuntime } from './types'\n\n/**\n * Creates the default no-op telemetry runtime.\n *\n * Use when:\n * - OpenTelemetry is not enabled by config\n * - tests need deterministic pass-through execution\n *\n * Expects:\n * - callers still wrap run/task/case boundaries with `withSpan`\n *\n * Returns:\n * - a runtime that never emits external telemetry and never changes control flow\n */\nexport function createNoopTelemetryRuntime(): TelemetryRuntime {\n return {\n async withSpan(_name, _attributes, callback) {\n return await callback()\n },\n addEvent() {},\n setAttributes() {},\n recordException() {},\n }\n}\n","import type { TelemetryAttributes, TelemetryRuntime } from './types'\n\nimport { errorMessageFrom } from '@moeru/std'\n\ntype OpenTelemetryAttributeScalar = boolean | number | string\ntype OpenTelemetryAttributeValue = OpenTelemetryAttributeScalar | readonly boolean[] | readonly number[] | readonly string[]\ntype OpenTelemetryAttributes = Record<string, OpenTelemetryAttributeValue>\n\ninterface OpenTelemetrySpan {\n addEvent: (name: string, attributes?: OpenTelemetryAttributes) => void\n end: () => void\n recordException: (error: unknown) => void\n setAttributes: (attributes: OpenTelemetryAttributes) => void\n setStatus: (status: { code: number, message?: string }) => void\n}\n\ninterface OpenTelemetryTracer {\n startActiveSpan: <T>(\n name: string,\n options: { attributes: OpenTelemetryAttributes },\n callback: (span: OpenTelemetrySpan) => Promise<T>,\n ) => Promise<T>\n}\n\ninterface OpenTelemetryApiModule {\n SpanStatusCode: { ERROR: number }\n trace: {\n getActiveSpan: () => OpenTelemetrySpan | undefined\n getTracer: (name: string) => OpenTelemetryTracer\n }\n}\n\n/**\n * Options used to construct the OpenTelemetry-backed telemetry runtime.\n */\nexport interface CreateOpenTelemetryRuntimeOptions {\n /**\n * Optional import adapter used by tests to avoid requiring a real OpenTelemetry SDK.\n *\n * @default dynamic import of `@opentelemetry/api`\n */\n importApi?: () => Promise<OpenTelemetryApiModule>\n}\n\nasync function importOpenTelemetryApi(): Promise<OpenTelemetryApiModule> {\n const moduleName = '@opentelemetry/api'\n return await import(moduleName) as unknown as OpenTelemetryApiModule\n}\n\nfunction isOpenTelemetryAttributeScalar(value: unknown): value is OpenTelemetryAttributeScalar {\n return typeof value === 'boolean' || typeof value === 'number' || typeof value === 'string'\n}\n\nfunction isHomogeneousOpenTelemetryAttributeArray(value: readonly unknown[]): value is readonly boolean[] | readonly number[] | readonly string[] {\n if (value.length === 0) {\n return true\n }\n\n const firstType = typeof value[0]\n if (firstType !== 'boolean' && firstType !== 'number' && firstType !== 'string') {\n return false\n }\n\n return value.every(item => typeof item === firstType)\n}\n\nfunction stringifyAttributeValue(value: unknown): string | undefined {\n try {\n return JSON.stringify(value)\n }\n catch {\n return String(value)\n }\n}\n\n/**\n * Normalizes JSON-compatible telemetry attributes into OpenTelemetry-safe attributes.\n *\n * Before:\n * - `{ nil: null, nested: ['a', [1, null]], scalarArray: ['a', 1, true] }`\n *\n * After:\n * - `{ nested: '[\"a\",[1,null]]', scalarArray: ['a', 1, true] }`\n */\nfunction normalizeOpenTelemetryAttributes(attributes: TelemetryAttributes | undefined): OpenTelemetryAttributes | undefined {\n if (attributes == null) {\n return undefined\n }\n\n const normalized: OpenTelemetryAttributes = {}\n\n for (const [key, value] of Object.entries(attributes)) {\n if (value == null) {\n continue\n }\n\n if (isOpenTelemetryAttributeScalar(value)) {\n normalized[key] = value\n continue\n }\n\n if (Array.isArray(value)) {\n normalized[key] = isHomogeneousOpenTelemetryAttributeArray(value)\n ? value\n : stringifyAttributeValue(value) ?? ''\n continue\n }\n\n const stringified = stringifyAttributeValue(value)\n\n if (stringified != null) {\n normalized[key] = stringified\n }\n }\n\n return normalized\n}\n\n/**\n * Creates an OpenTelemetry-backed runtime using active spans.\n *\n * Use when:\n * - `reporting.openTelemetry.enabled` is true\n * - the user's config has initialized an OpenTelemetry SDK or intentionally relies on the API no-op provider\n *\n * Expects:\n * - `@opentelemetry/api` is resolvable when enabled\n * - SDK lifecycle is managed by user config and `reporting.openTelemetry.onRunEnd`\n *\n * Returns:\n * - a runtime that starts active spans and forwards events to the current active span\n */\nexport function createOpenTelemetryRuntime(options: CreateOpenTelemetryRuntimeOptions = {}): TelemetryRuntime {\n const importApi = options.importApi ?? importOpenTelemetryApi\n let apiPromise: Promise<OpenTelemetryApiModule> | undefined\n let loadedApi: OpenTelemetryApiModule | undefined\n\n async function getApi(): Promise<OpenTelemetryApiModule> {\n apiPromise ??= importApi().then((api) => {\n loadedApi = api\n return api\n })\n return await apiPromise\n }\n\n return {\n async withSpan(name, attributes, callback) {\n const api = await getApi()\n const tracer = api.trace.getTracer('vieval')\n\n return await tracer.startActiveSpan(name, { attributes: normalizeOpenTelemetryAttributes(attributes) ?? {} }, async (span) => {\n try {\n return await callback()\n }\n catch (error) {\n span.recordException(error)\n span.setStatus({ code: api.SpanStatusCode.ERROR, message: errorMessageFrom(error) ?? 'Unknown error' })\n throw error\n }\n finally {\n span.end()\n }\n })\n },\n addEvent(name, attributes) {\n loadedApi?.trace.getActiveSpan()?.addEvent(name, normalizeOpenTelemetryAttributes(attributes))\n },\n setAttributes(attributes) {\n loadedApi?.trace.getActiveSpan()?.setAttributes(normalizeOpenTelemetryAttributes(attributes) ?? {})\n },\n recordException(error) {\n loadedApi?.trace.getActiveSpan()?.recordException(error)\n },\n }\n}\n","import type { EvalDefinition } from '../config'\n\nimport process from 'node:process'\n\ninterface EvalDefinitionRegistryStore {\n activeModuleHref: string | null\n registeredDefinitionsByModule: Map<string, EvalDefinition[]>\n}\n\nconst registryStoreSymbol = Symbol.for('vieval.dsl.registry.store')\n\nfunction getRegistryStore(): EvalDefinitionRegistryStore {\n const processWithStore = process as NodeJS.Process & {\n [registryStoreSymbol]?: EvalDefinitionRegistryStore\n }\n\n processWithStore[registryStoreSymbol] ??= {\n activeModuleHref: null,\n registeredDefinitionsByModule: new Map<string, EvalDefinition[]>(),\n }\n\n return processWithStore[registryStoreSymbol]\n}\n\n/**\n * Starts module-scoped eval registration collection.\n */\nexport function beginModuleRegistration(moduleHref: string): void {\n const store = getRegistryStore()\n store.activeModuleHref = moduleHref\n}\n\n/**\n * Ends module-scoped eval registration collection.\n */\nexport function endModuleRegistration(): void {\n const store = getRegistryStore()\n store.activeModuleHref = null\n}\n\n/**\n * Registers one eval definition against the currently active module.\n */\nexport function registerEvalDefinition(definition: EvalDefinition): void {\n const store = getRegistryStore()\n\n if (store.activeModuleHref == null) {\n return\n }\n\n const existing = store.registeredDefinitionsByModule.get(store.activeModuleHref) ?? []\n existing.push(definition)\n store.registeredDefinitionsByModule.set(store.activeModuleHref, existing)\n}\n\n/**\n * Consumes registered definitions for one module and clears stored state.\n */\nexport function consumeModuleRegistrations(moduleHref: string): EvalDefinition[] {\n const store = getRegistryStore()\n const definitions = store.registeredDefinitionsByModule.get(moduleHref) ?? []\n store.registeredDefinitionsByModule.delete(moduleHref)\n return definitions\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vieval",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.8",
|
|
5
5
|
"description": "Vitest-based evaluation framework for agents, models, and more.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Vieval Team",
|
|
@@ -73,6 +73,7 @@
|
|
|
73
73
|
"dependencies": {
|
|
74
74
|
"@henrygd/queue": "^1.2.0",
|
|
75
75
|
"@moeru/std": "0.1.0-beta.17",
|
|
76
|
+
"@opentelemetry/api": "^1.9.0",
|
|
76
77
|
"@pnpm/find-workspace-dir": "^1000.1.5",
|
|
77
78
|
"@vitest/expect": "^4.1.4",
|
|
78
79
|
"@vitest/runner": "^4.1.4",
|