vieval 0.0.9 → 0.0.11
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 +27 -2
- package/dist/bin/vieval.mjs +1 -1
- package/dist/bin/vieval.mjs.map +1 -1
- package/dist/cli/index.mjs +1 -1
- package/dist/{cli-Dao25VxV.mjs → cli-CHFCF8UR.mjs} +670 -600
- package/dist/cli-CHFCF8UR.mjs.map +1 -0
- package/dist/config.d.mts +1 -1
- package/dist/config.mjs +1 -1
- package/dist/config.mjs.map +1 -1
- package/dist/core/assertions/index.d.mts +1 -1
- package/dist/core/assertions/index.mjs.map +1 -1
- package/dist/core/inference-executors/index.d.mts +1 -1
- package/dist/core/inference-executors/index.mjs +3 -3
- package/dist/core/inference-executors/index.mjs.map +1 -1
- package/dist/core/processors/results/index.d.mts +1 -1
- package/dist/core/processors/results/index.mjs.map +1 -1
- package/dist/core/runner/index.d.mts +2 -2
- package/dist/core/runner/index.mjs +4 -4
- package/dist/core/runner/index.mjs.map +1 -1
- package/dist/core/scheduler/index.d.mts +1 -1
- package/dist/core/scheduler/index.mjs +3 -3
- package/dist/core/scheduler/index.mjs.map +1 -1
- package/dist/{env-nV5rVErX.mjs → env-BVYeJhGA.mjs} +1 -1
- package/dist/{env-nV5rVErX.mjs.map → env-BVYeJhGA.mjs.map} +1 -1
- package/dist/{env-DfWZy_n4.d.mts → env-bRH0K6fU.d.mts} +1 -1
- package/dist/{expect-extensions-DCSqlneN.mjs → expect-extensions-Mf1sMNBv.mjs} +1 -1
- package/dist/{expect-extensions-DCSqlneN.mjs.map → expect-extensions-Mf1sMNBv.mjs.map} +1 -1
- package/dist/expect.d.mts +1 -3
- package/dist/expect.mjs +1 -1
- package/dist/expect.mjs.map +1 -1
- package/dist/{index-fakXoZEe.d.mts → index-Be5I1ZJL.d.mts} +4 -3
- package/dist/{index-BkjyCInx.d.mts → index-CwKBlCG9.d.mts} +2 -2
- package/dist/index.d.mts +3 -4
- package/dist/index.mjs +22 -27
- package/dist/index.mjs.map +1 -1
- package/dist/{models-pBSRUZhY.mjs → models-CaCOUPZw.mjs} +1 -1
- package/dist/{models-pBSRUZhY.mjs.map → models-CaCOUPZw.mjs.map} +1 -1
- package/dist/plugins/chat-models/index.d.mts +1 -1
- package/dist/plugins/chat-models/index.mjs +2 -2
- package/dist/plugins/chat-models/index.mjs.map +1 -1
- package/dist/{queue-DsZQkZO_.mjs → queue-BL86z2W_.mjs} +1 -1
- package/dist/{queue-DsZQkZO_.mjs.map → queue-BL86z2W_.mjs.map} +1 -1
- package/dist/{registry-BHGMxjpA.mjs → registry-BSyjwZFx.mjs} +55 -11
- package/dist/registry-BSyjwZFx.mjs.map +1 -0
- package/dist/testing/expect-extensions.mjs +1 -1
- package/package.json +10 -10
- package/dist/cli-Dao25VxV.mjs.map +0 -1
- package/dist/registry-BHGMxjpA.mjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../../src/core/scheduler/runtime.ts"],"sourcesContent":["import type {\n CreateSchedulerRuntimeOptions,\n SchedulerConcurrencyConfig,\n SchedulerMiddleware,\n SchedulerRuntime,\n SchedulerScope,\n SchedulerScopeContext,\n} from './types'\n\nimport { createSchedulerQueue } from './queue'\n\nconst schedulerScopeOrder: SchedulerScope[] = [\n 'workspace',\n 'project',\n 'task',\n 'attempt',\n 'case',\n]\n\n/**\n * Creates the core scheduler runtime used to serialize work by scope.\n *\n * Call stack:\n *\n * {@link createSchedulerRuntime}\n * -> `createRuntimeQueues`\n * -> `runtime.runCase(context, execute)`\n * -> `runWithQueues`\n * -> `runAcquireMiddleware`\n * -> `execute`\n * -> `runReleaseMiddleware`\n *\n * Use when:\n * - runner code needs concurrency caps for queued case execution\n * - middleware should wrap work with acquire/release lifecycle hooks\n *\n * Expects:\n * - middleware is ordered from outermost to innermost concern\n * - concurrency caps are positive integers when provided\n *\n * Returns:\n * - a scheduler runtime with case execution support\n */\nexport function createSchedulerRuntime(\n options: CreateSchedulerRuntimeOptions = {},\n): SchedulerRuntime {\n const middleware = options.middleware ?? []\n const queues = createRuntimeQueues(options.concurrency ?? {})\n\n return {\n runCase<T>(context: SchedulerScopeContext, execute: () => Promise<T>) {\n const activeScopes = getActiveScopes(context)\n\n return runWithQueues(activeScopes, context, queues, () => {\n if (middleware.length === 0) {\n return execute()\n }\n\n return runWithMiddlewareEnvelope(middleware, context, execute)\n })\n },\n }\n}\n\n/**\n * Resolves the scheduler scopes that apply to a context.\n *\n * Before:\n * - `{ scope: 'case', workspaceId: 'ws', experimentId: 'exp', caseId: 'case-1' }`\n *\n * After:\n * - `['workspace', 'project', 'task', 'attempt', 'case']` up to the requested scope\n */\nexport function getActiveScopes(context: SchedulerScopeContext): SchedulerScope[] {\n const targetScopeIndex = schedulerScopeOrder.indexOf(context.scope)\n\n if (targetScopeIndex < 0) {\n return []\n }\n\n return schedulerScopeOrder.slice(0, targetScopeIndex + 1)\n}\n\nfunction createRuntimeQueues(concurrency: SchedulerConcurrencyConfig) {\n const queues = new Map<SchedulerScope, SchedulerScopeQueueRegistry>()\n\n for (const scope of schedulerScopeOrder) {\n const scopeConcurrency = concurrency[scope]\n\n if (scopeConcurrency === undefined) {\n continue\n }\n\n validateSchedulerConcurrency(scope, scopeConcurrency)\n\n queues.set(scope, {\n concurrency: scopeConcurrency,\n instances: new Map<string, ReturnType<typeof createSchedulerQueue>>(),\n })\n }\n\n return queues\n}\n\nasync function runWithQueues<T>(\n scopes: SchedulerScope[],\n context: SchedulerScopeContext,\n queues: Map<SchedulerScope, SchedulerScopeQueueRegistry>,\n execute: () => Promise<T>,\n index = 0,\n): Promise<T> {\n const scope = scopes[index]\n\n if (scope === undefined) {\n return execute()\n }\n\n const queue = getScopeQueue(scope, context, queues)\n\n if (queue === undefined) {\n return runWithQueues(scopes, context, queues, execute, index + 1)\n }\n\n return queue.run(() => runWithQueues(scopes, context, queues, execute, index + 1))\n}\n\ninterface SchedulerScopeQueueRegistry {\n concurrency: number\n instances: Map<string, ReturnType<typeof createSchedulerQueue>>\n}\n\ninterface SchedulerEnvelopeResult<T> {\n releaseStack: SchedulerMiddleware[]\n outcome: SchedulerExecutionOutcome<T>\n}\n\ninterface SchedulerExecutionFailure {\n error: unknown\n status: 'failed'\n}\n\ninterface SchedulerExecutionSkipped {\n status: 'skipped'\n}\n\ninterface SchedulerExecutionSuccess<T> {\n status: 'succeeded'\n value: T\n}\n\ntype SchedulerExecutionOutcome<T>\n = | SchedulerExecutionFailure\n | SchedulerExecutionSkipped\n | SchedulerExecutionSuccess<T>\n\nfunction getScopeQueue(\n scope: SchedulerScope,\n context: SchedulerScopeContext,\n queues: Map<SchedulerScope, SchedulerScopeQueueRegistry>,\n) {\n const queueRegistry = queues.get(scope)\n\n if (queueRegistry === undefined) {\n return undefined\n }\n\n const scopeKey = getSchedulerScopeInstanceKey(scope, context)\n const existingQueue = queueRegistry.instances.get(scopeKey)\n\n if (existingQueue !== undefined) {\n return existingQueue\n }\n\n const queue = createSchedulerQueue(queueRegistry.concurrency)\n queueRegistry.instances.set(scopeKey, queue)\n return queue\n}\n\nfunction getSchedulerScopeInstanceKey(\n scope: SchedulerScope,\n context: SchedulerScopeContext,\n): string {\n const workspaceKey = `workspace:${context.workspaceId}:experiment:${context.experimentId}`\n const projectKey = `${workspaceKey}:project:${context.projectName ?? '(missing-project)'}`\n const taskKey = `${projectKey}:task:${context.taskId ?? '(missing-task)'}`\n const attemptKey = `${taskKey}:attempt:${context.attemptIndex ?? '(missing-attempt)'}`\n\n switch (scope) {\n case 'workspace':\n return workspaceKey\n case 'project':\n return projectKey\n case 'task':\n return taskKey\n case 'attempt':\n return attemptKey\n case 'case':\n return attemptKey\n }\n}\n\nasync function runWithMiddlewareEnvelope<T>(\n middleware: SchedulerMiddleware[],\n context: SchedulerScopeContext,\n execute: () => Promise<T>,\n): Promise<T> {\n const result = await runAcquireMiddleware(middleware, context, execute, 0)\n\n try {\n switch (result.outcome.status) {\n case 'succeeded':\n return result.outcome.value\n case 'failed':\n throw result.outcome.error\n case 'skipped':\n throw createSchedulerShortCircuitError()\n }\n }\n finally {\n await runReleaseMiddleware(result.releaseStack, context, result.releaseStack.length - 1)\n }\n}\n\nasync function runAcquireMiddleware<T>(\n middleware: SchedulerMiddleware[],\n context: SchedulerScopeContext,\n execute: () => Promise<T>,\n index: number,\n): Promise<SchedulerEnvelopeResult<T>> {\n const currentMiddleware = middleware[index]\n\n if (currentMiddleware === undefined) {\n return createSchedulerExecutionResult([], execute)\n }\n\n let nextResult = createSchedulerShortCircuitResult<T>()\n let didCallNext = false\n\n const next = async () => {\n didCallNext = true\n nextResult = await runAcquireMiddleware(middleware, context, execute, index + 1)\n }\n\n try {\n if (currentMiddleware.onAcquire === undefined) {\n await next()\n }\n else {\n await currentMiddleware.onAcquire(context, next)\n }\n }\n catch (error) {\n if (!didCallNext) {\n return createSchedulerFailureResult([], error)\n }\n\n return createSchedulerFailureResult(\n [currentMiddleware, ...nextResult.releaseStack],\n error,\n )\n }\n\n return {\n releaseStack: [currentMiddleware, ...nextResult.releaseStack],\n outcome: nextResult.outcome,\n }\n}\n\nasync function runReleaseMiddleware(\n releaseStack: SchedulerMiddleware[],\n context: SchedulerScopeContext,\n index: number,\n): Promise<void> {\n const currentMiddleware = releaseStack[index]\n\n if (currentMiddleware === undefined) {\n return\n }\n\n if (currentMiddleware.onRelease === undefined) {\n await runReleaseMiddleware(releaseStack, context, index - 1)\n return\n }\n\n await currentMiddleware.onRelease(context, async () => {\n await runReleaseMiddleware(releaseStack, context, index - 1)\n })\n}\n\nasync function createSchedulerExecutionResult<T>(\n releaseStack: SchedulerMiddleware[],\n execute: () => Promise<T>,\n): Promise<SchedulerEnvelopeResult<T>> {\n try {\n return {\n releaseStack,\n outcome: {\n status: 'succeeded',\n value: await execute(),\n },\n }\n }\n catch (error) {\n return {\n releaseStack,\n outcome: {\n status: 'failed',\n error,\n },\n }\n }\n}\n\nfunction createSchedulerFailureResult<T>(\n releaseStack: SchedulerMiddleware[],\n error: unknown,\n): SchedulerEnvelopeResult<T> {\n return {\n releaseStack,\n outcome: {\n status: 'failed',\n error,\n },\n }\n}\n\nfunction createSchedulerShortCircuitResult<T>(): SchedulerEnvelopeResult<T> {\n return {\n releaseStack: [],\n outcome: {\n status: 'skipped',\n },\n }\n}\n\nfunction validateSchedulerConcurrency(scope: SchedulerScope, concurrency: number): void {\n if (!Number.isFinite(concurrency) || !Number.isInteger(concurrency) || concurrency <= 0) {\n throw new Error(`Invalid scheduler concurrency for \"${scope}\": ${String(concurrency)}`)\n }\n}\n\nfunction createSchedulerShortCircuitError(): Error {\n return new Error('Scheduler middleware short-circuited execution.')\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../../src/core/scheduler/runtime.ts"],"sourcesContent":["import type {\n CreateSchedulerRuntimeOptions,\n SchedulerConcurrencyConfig,\n SchedulerMiddleware,\n SchedulerRuntime,\n SchedulerScope,\n SchedulerScopeContext,\n} from './types'\n\nimport { createSchedulerQueue } from './queue'\n\nconst schedulerScopeOrder: SchedulerScope[] = [\n 'workspace',\n 'project',\n 'task',\n 'attempt',\n 'case',\n]\n\n/**\n * Creates the core scheduler runtime used to serialize work by scope.\n *\n * Call stack:\n *\n * {@link createSchedulerRuntime}\n * -> `createRuntimeQueues`\n * -> `runtime.runCase(context, execute)`\n * -> `runWithQueues`\n * -> `runAcquireMiddleware`\n * -> `execute`\n * -> `runReleaseMiddleware`\n *\n * Use when:\n * - runner code needs concurrency caps for queued case execution\n * - middleware should wrap work with acquire/release lifecycle hooks\n *\n * Expects:\n * - middleware is ordered from outermost to innermost concern\n * - concurrency caps are positive integers when provided\n *\n * Returns:\n * - a scheduler runtime with case execution support\n */\nexport function createSchedulerRuntime(\n options: CreateSchedulerRuntimeOptions = {},\n): SchedulerRuntime {\n const middleware = options.middleware ?? []\n const queues = createRuntimeQueues(options.concurrency ?? {})\n\n return {\n runCase<T>(context: SchedulerScopeContext, execute: () => Promise<T>) {\n const activeScopes = getActiveScopes(context)\n\n return runWithQueues(activeScopes, context, queues, () => {\n if (middleware.length === 0) {\n return execute()\n }\n\n return runWithMiddlewareEnvelope(middleware, context, execute)\n })\n },\n }\n}\n\n/**\n * Resolves the scheduler scopes that apply to a context.\n *\n * Before:\n * - `{ scope: 'case', workspaceId: 'ws', projectName: 'project', caseId: 'case-1' }`\n *\n * After:\n * - `['workspace', 'project', 'task', 'attempt', 'case']` up to the requested scope\n */\nexport function getActiveScopes(context: SchedulerScopeContext): SchedulerScope[] {\n const targetScopeIndex = schedulerScopeOrder.indexOf(context.scope)\n\n if (targetScopeIndex < 0) {\n return []\n }\n\n return schedulerScopeOrder.slice(0, targetScopeIndex + 1)\n}\n\nfunction createRuntimeQueues(concurrency: SchedulerConcurrencyConfig) {\n const queues = new Map<SchedulerScope, SchedulerScopeQueueRegistry>()\n\n for (const scope of schedulerScopeOrder) {\n const scopeConcurrency = concurrency[scope]\n\n if (scopeConcurrency === undefined) {\n continue\n }\n\n validateSchedulerConcurrency(scope, scopeConcurrency)\n\n queues.set(scope, {\n concurrency: scopeConcurrency,\n instances: new Map<string, ReturnType<typeof createSchedulerQueue>>(),\n })\n }\n\n return queues\n}\n\nasync function runWithQueues<T>(\n scopes: SchedulerScope[],\n context: SchedulerScopeContext,\n queues: Map<SchedulerScope, SchedulerScopeQueueRegistry>,\n execute: () => Promise<T>,\n index = 0,\n): Promise<T> {\n const scope = scopes[index]\n\n if (scope === undefined) {\n return execute()\n }\n\n const queue = getScopeQueue(scope, context, queues)\n\n if (queue === undefined) {\n return runWithQueues(scopes, context, queues, execute, index + 1)\n }\n\n return queue.run(() => runWithQueues(scopes, context, queues, execute, index + 1))\n}\n\ninterface SchedulerScopeQueueRegistry {\n concurrency: number\n instances: Map<string, ReturnType<typeof createSchedulerQueue>>\n}\n\ninterface SchedulerEnvelopeResult<T> {\n releaseStack: SchedulerMiddleware[]\n outcome: SchedulerExecutionOutcome<T>\n}\n\ninterface SchedulerExecutionFailure {\n error: unknown\n status: 'failed'\n}\n\ninterface SchedulerExecutionSkipped {\n status: 'skipped'\n}\n\ninterface SchedulerExecutionSuccess<T> {\n status: 'succeeded'\n value: T\n}\n\ntype SchedulerExecutionOutcome<T>\n = | SchedulerExecutionFailure\n | SchedulerExecutionSkipped\n | SchedulerExecutionSuccess<T>\n\nfunction getScopeQueue(\n scope: SchedulerScope,\n context: SchedulerScopeContext,\n queues: Map<SchedulerScope, SchedulerScopeQueueRegistry>,\n) {\n const queueRegistry = queues.get(scope)\n\n if (queueRegistry === undefined) {\n return undefined\n }\n\n const scopeKey = getSchedulerScopeInstanceKey(scope, context)\n const existingQueue = queueRegistry.instances.get(scopeKey)\n\n if (existingQueue !== undefined) {\n return existingQueue\n }\n\n const queue = createSchedulerQueue(queueRegistry.concurrency)\n queueRegistry.instances.set(scopeKey, queue)\n return queue\n}\n\nfunction getSchedulerScopeInstanceKey(\n scope: SchedulerScope,\n context: SchedulerScopeContext,\n): string {\n const workspaceKey = `workspace:${context.workspaceId}`\n const projectKey = `${workspaceKey}:project:${context.projectName ?? '(missing-project)'}`\n const taskKey = `${projectKey}:task:${context.taskId ?? '(missing-task)'}`\n const attemptKey = `${taskKey}:attempt:${context.attemptIndex ?? '(missing-attempt)'}`\n\n switch (scope) {\n case 'workspace':\n return workspaceKey\n case 'project':\n return projectKey\n case 'task':\n return taskKey\n case 'attempt':\n return attemptKey\n case 'case':\n return attemptKey\n }\n}\n\nasync function runWithMiddlewareEnvelope<T>(\n middleware: SchedulerMiddleware[],\n context: SchedulerScopeContext,\n execute: () => Promise<T>,\n): Promise<T> {\n const result = await runAcquireMiddleware(middleware, context, execute, 0)\n\n try {\n switch (result.outcome.status) {\n case 'succeeded':\n return result.outcome.value\n case 'failed':\n throw result.outcome.error\n case 'skipped':\n throw createSchedulerShortCircuitError()\n }\n }\n finally {\n await runReleaseMiddleware(result.releaseStack, context, result.releaseStack.length - 1)\n }\n}\n\nasync function runAcquireMiddleware<T>(\n middleware: SchedulerMiddleware[],\n context: SchedulerScopeContext,\n execute: () => Promise<T>,\n index: number,\n): Promise<SchedulerEnvelopeResult<T>> {\n const currentMiddleware = middleware[index]\n\n if (currentMiddleware === undefined) {\n return createSchedulerExecutionResult([], execute)\n }\n\n let nextResult = createSchedulerShortCircuitResult<T>()\n let didCallNext = false\n\n const next = async () => {\n didCallNext = true\n nextResult = await runAcquireMiddleware(middleware, context, execute, index + 1)\n }\n\n try {\n if (currentMiddleware.onAcquire === undefined) {\n await next()\n }\n else {\n await currentMiddleware.onAcquire(context, next)\n }\n }\n catch (error) {\n if (!didCallNext) {\n return createSchedulerFailureResult([], error)\n }\n\n return createSchedulerFailureResult(\n [currentMiddleware, ...nextResult.releaseStack],\n error,\n )\n }\n\n return {\n releaseStack: [currentMiddleware, ...nextResult.releaseStack],\n outcome: nextResult.outcome,\n }\n}\n\nasync function runReleaseMiddleware(\n releaseStack: SchedulerMiddleware[],\n context: SchedulerScopeContext,\n index: number,\n): Promise<void> {\n const currentMiddleware = releaseStack[index]\n\n if (currentMiddleware === undefined) {\n return\n }\n\n if (currentMiddleware.onRelease === undefined) {\n await runReleaseMiddleware(releaseStack, context, index - 1)\n return\n }\n\n await currentMiddleware.onRelease(context, async () => {\n await runReleaseMiddleware(releaseStack, context, index - 1)\n })\n}\n\nasync function createSchedulerExecutionResult<T>(\n releaseStack: SchedulerMiddleware[],\n execute: () => Promise<T>,\n): Promise<SchedulerEnvelopeResult<T>> {\n try {\n return {\n releaseStack,\n outcome: {\n status: 'succeeded',\n value: await execute(),\n },\n }\n }\n catch (error) {\n return {\n releaseStack,\n outcome: {\n status: 'failed',\n error,\n },\n }\n }\n}\n\nfunction createSchedulerFailureResult<T>(\n releaseStack: SchedulerMiddleware[],\n error: unknown,\n): SchedulerEnvelopeResult<T> {\n return {\n releaseStack,\n outcome: {\n status: 'failed',\n error,\n },\n }\n}\n\nfunction createSchedulerShortCircuitResult<T>(): SchedulerEnvelopeResult<T> {\n return {\n releaseStack: [],\n outcome: {\n status: 'skipped',\n },\n }\n}\n\nfunction validateSchedulerConcurrency(scope: SchedulerScope, concurrency: number): void {\n if (!Number.isFinite(concurrency) || !Number.isInteger(concurrency) || concurrency <= 0) {\n throw new Error(`Invalid scheduler concurrency for \"${scope}\": ${String(concurrency)}`)\n }\n}\n\nfunction createSchedulerShortCircuitError(): Error {\n return new Error('Scheduler middleware short-circuited execution.')\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"env-
|
|
1
|
+
{"version":3,"file":"env-BVYeJhGA.mjs","names":[],"sources":["../src/core/inference-executors/env.ts"],"sourcesContent":["/**\n * Supported env value coercion types.\n */\nexport type EnvValueType = 'string'\n\n/**\n * Common options for env readers.\n */\nexport interface EnvFromOptions {\n /**\n * Env key to read and use in error messages.\n */\n name: string\n /**\n * Expected env value type.\n */\n type: EnvValueType\n /**\n * Whether an empty or missing value should throw.\n *\n * @default false\n */\n required?: boolean\n}\n\n/**\n * Env options used by the required helper.\n *\n * `required` is intentionally omitted because this helper is always required.\n */\nexport type RequiredEnvFromOptions = Omit<EnvFromOptions, 'required'>\n\ntype EnvSource = Record<string, string | undefined>\n\nfunction assertNonEmptyString(value: string | undefined, options: EnvFromOptions): string | undefined {\n if (value == null || value.trim().length === 0) {\n if (options.required === true) {\n throw new Error(`Missing required ${options.name}.`)\n }\n\n return undefined\n }\n\n return value\n}\n\n/**\n * Parses one env value with optional required behavior.\n *\n * Example:\n * `const apiKey = envFrom(process.env, { type: 'string', required: true, name: 'OPENAI_API_KEY' })`\n */\nexport function envFrom<TEnv extends EnvSource>(\n env: TEnv,\n options: EnvFromOptions & { name: keyof TEnv & string },\n): string | undefined {\n if (options.type === 'string') {\n return assertNonEmptyString(env[options.name], options)\n }\n\n return undefined\n}\n\n/**\n * Parses one required env value.\n *\n * Example:\n * `const apiKey = requiredEnvFrom(process.env, { type: 'string', name: 'OPENAI_API_KEY' })`\n */\nexport function requiredEnvFrom<TEnv extends EnvSource>(\n env: TEnv,\n options: RequiredEnvFromOptions & { name: keyof TEnv & string },\n): string {\n const parsed = envFrom(env, {\n ...options,\n required: true,\n })\n\n if (parsed == null) {\n throw new Error(`Missing required ${options.name}.`)\n }\n\n return parsed\n}\n"],"mappings":";AAkCA,SAAS,qBAAqB,OAA2B,SAA6C;CACpG,IAAI,SAAS,QAAQ,MAAM,KAAK,CAAC,CAAC,WAAW,GAAG;EAC9C,IAAI,QAAQ,aAAa,MACvB,MAAM,IAAI,MAAM,oBAAoB,QAAQ,KAAK,EAAE;EAGrD;CACF;CAEA,OAAO;AACT;;;;;;;AAQA,SAAgB,QACd,KACA,SACoB;CACpB,IAAI,QAAQ,SAAS,UACnB,OAAO,qBAAqB,IAAI,QAAQ,OAAO,OAAO;AAI1D;;;;;;;AAQA,SAAgB,gBACd,KACA,SACQ;CACR,MAAM,SAAS,QAAQ,KAAK;EAC1B,GAAG;EACH,UAAU;CACZ,CAAC;CAED,IAAI,UAAU,MACZ,MAAM,IAAI,MAAM,oBAAoB,QAAQ,KAAK,EAAE;CAGrD,OAAO;AACT"}
|
|
@@ -49,4 +49,4 @@ declare function requiredEnvFrom<TEnv extends EnvSource>(env: TEnv, options: Req
|
|
|
49
49
|
}): string;
|
|
50
50
|
//#endregion
|
|
51
51
|
export { requiredEnvFrom as a, envFrom as i, EnvValueType as n, RequiredEnvFromOptions as r, EnvFromOptions as t };
|
|
52
|
-
//# sourceMappingURL=env-
|
|
52
|
+
//# sourceMappingURL=env-bRH0K6fU.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"expect-extensions-DCSqlneN.mjs","names":[],"sources":["../src/testing/runtime-expect.ts","../src/testing/expect-extensions.ts"],"sourcesContent":["import type { ExpectStatic, MatchersObject, MatcherState, Tester } from '@vitest/expect'\n\nimport {\n addCustomEqualityTesters,\n ASYMMETRIC_MATCHERS_OBJECT,\n chai,\n ChaiStyleAssertions,\n customMatchers,\n getState,\n GLOBAL_EXPECT,\n JestAsymmetricMatchers,\n JestChaiExpect,\n JestExtend,\n setState,\n} from '@vitest/expect'\n\nlet isPluginInstalled = false\nlet runtimeExpectInstance: ExpectStatic | undefined\n\n/**\n * Installs Vitest expect plugins once for process-local runtime assertions.\n *\n * Use when:\n * - running eval tasks outside Vitest worker runtime\n * - building an `expect` instance that does not rely on Vitest internal state\n *\n * Expects:\n * - `@vitest/expect` is available in runtime dependencies\n *\n * Returns:\n * - nothing; side-effects are applied to `chai`\n */\nfunction ensureRuntimeExpectPluginsInstalled(): void {\n if (isPluginInstalled) {\n return\n }\n\n chai.use(JestExtend)\n chai.use(JestChaiExpect)\n chai.use(ChaiStyleAssertions)\n chai.use(JestAsymmetricMatchers)\n isPluginInstalled = true\n}\n\n/**\n * Creates a Vitest-compatible `expect` instance without worker-state coupling.\n *\n * Use when:\n * - CLI runtime needs assertion helpers from `vieval/expect`\n * - code is executed outside `vitest run`\n *\n * Expects:\n * - plugins from {@link ensureRuntimeExpectPluginsInstalled} are installed\n * - callers do not depend on Vitest worker-only features (snapshot/poll internals)\n *\n * Returns:\n * - standalone expect instance with core matcher APIs and `extend`\n */\nfunction createRuntimeExpect(): ExpectStatic {\n ensureRuntimeExpectPluginsInstalled()\n\n const runtimeExpect = ((value: unknown, message?: string) => {\n const currentState = getState(runtimeExpect)\n setState({ assertionCalls: currentState.assertionCalls + 1 }, runtimeExpect)\n return chai.expect(value, message)\n }) as unknown as ExpectStatic\n\n Object.assign(runtimeExpect, chai.expect)\n Object.assign(runtimeExpect, (globalThis as Record<PropertyKey, unknown>)[ASYMMETRIC_MATCHERS_OBJECT] as object)\n\n runtimeExpect.getState = () => getState(runtimeExpect)\n runtimeExpect.setState = (state: Partial<MatcherState>) => setState(state, runtimeExpect)\n runtimeExpect.assert = chai.assert\n // NOTICE:\n // Chai's public `ExpectStatic` type does not expose Vitest's plugin-added `extend`.\n // Runtime `chai.expect.extend` exists after `JestExtend` plugin installation.\n // Source/context: `@vitest/expect` plugin pipeline in `dist/index.js`.\n // Removal condition: remove this cast if upstream exposes `extend` on Chai expect types.\n const chaiExpectWithExtend = chai.expect as unknown as {\n extend: (expect: ExpectStatic, matchers: MatchersObject) => void\n }\n runtimeExpect.extend = (matchers: MatchersObject) => chaiExpectWithExtend.extend(runtimeExpect, matchers)\n runtimeExpect.addEqualityTesters = (customTesters: Tester[]) => addCustomEqualityTesters(customTesters)\n runtimeExpect.unreachable = (message?: string) => {\n chai.assert.fail(`expected${message ? ` \"${message}\" ` : ' '}not to be reached`)\n }\n\n runtimeExpect.setState({\n assertionCalls: 0,\n currentTestName: '',\n expectedAssertionsNumber: null,\n expectedAssertionsNumberErrorGen: null,\n isExpectingAssertions: false,\n isExpectingAssertionsError: null,\n })\n\n runtimeExpect.extend(customMatchers)\n\n return runtimeExpect\n}\n\n/**\n * Returns process-local runtime `expect` instance used by Vieval.\n *\n * Use when:\n * - you need matcher assertions in eval files and CLI runtime\n * - importing from `vitest` would crash outside Vitest worker contexts\n *\n * Expects:\n * - single-process usage (instance is memoized per process)\n *\n * Returns:\n * - memoized runtime `expect` instance\n */\nexport function getRuntimeExpect(): ExpectStatic {\n if (runtimeExpectInstance != null) {\n return runtimeExpectInstance\n }\n\n runtimeExpectInstance = createRuntimeExpect()\n Object.defineProperty(globalThis, GLOBAL_EXPECT, {\n configurable: true,\n value: runtimeExpectInstance,\n writable: true,\n })\n\n return runtimeExpectInstance\n}\n","import type { RubricJudgeResult, ToolCall } from '../core/assertions'\n\nimport { normalizeMatchText } from '../core/assertions'\nimport { getRuntimeExpect } from './runtime-expect'\n\n/**\n * Options for keyword-based matcher behavior.\n */\nexport interface KeywordMatcherOptions {\n /**\n * Case-sensitive matching toggle.\n *\n * @default false\n */\n caseSensitive?: boolean\n /**\n * Match mode.\n *\n * @default 'all'\n */\n mode?: 'all' | 'any'\n}\n\n/**\n * Shape used by tool-call matchers.\n */\nexport interface ToolCallContainer {\n /**\n * Tool calls to inspect.\n */\n toolCalls?: readonly ToolCall[]\n}\n\nfunction toKeywordArray(keywords: string | readonly string[]): readonly string[] {\n if (typeof keywords === 'string') {\n return [keywords]\n }\n\n return keywords\n}\n\n/**\n * Registers vieval custom matchers on Vitest `expect`.\n *\n * Call stack:\n *\n * {@link installVievalExpectMatchers}\n * -> `expect.extend(...)`\n * -> `expect(received).toMustInclude(...)`\n * -> `expect(received).toScoreRubricGreaterThan(...)`\n *\n * Use when:\n * - eval suites need domain assertions while preserving native Vitest ergonomics\n * - callers want native `.not` chaining with the same matchers\n */\nexport function installVievalExpectMatchers(): void {\n const expect = getRuntimeExpect()\n\n expect.extend({\n toMustExclude(received: unknown, keywords: string | readonly string[], options: KeywordMatcherOptions = {}) {\n const keywordList = toKeywordArray(keywords)\n\n if (typeof received !== 'string') {\n return {\n message: () => 'Expected received value to be a string.',\n pass: false,\n }\n }\n\n const normalizedText = normalizeMatchText(received, options.caseSensitive ?? false)\n const forbiddenMatches = keywordList.filter((keyword) => {\n return normalizedText.includes(normalizeMatchText(keyword, options.caseSensitive ?? false))\n })\n\n const pass = forbiddenMatches.length === 0\n\n return {\n message: () => {\n if (pass) {\n return `Expected text to include forbidden keywords: ${keywordList.join(', ')}`\n }\n\n return `Expected text not to include forbidden keywords, but matched: ${forbiddenMatches.join(', ')}`\n },\n pass,\n }\n },\n\n toMustInclude(received: unknown, keywords: string | readonly string[], options: KeywordMatcherOptions = {}) {\n const keywordList = toKeywordArray(keywords)\n\n if (typeof received !== 'string') {\n return {\n message: () => 'Expected received value to be a string.',\n pass: false,\n }\n }\n\n const normalizedText = normalizeMatchText(received, options.caseSensitive ?? false)\n const matches = keywordList.filter((keyword) => {\n return normalizedText.includes(normalizeMatchText(keyword, options.caseSensitive ?? false))\n })\n\n const mode = options.mode ?? 'all'\n const pass = mode === 'all' ? matches.length === keywordList.length : matches.length > 0\n\n return {\n message: () => {\n if (pass) {\n return `Expected text not to match required keywords, but matched: ${matches.join(', ')}`\n }\n\n return `Expected text to match required keywords (${mode}), but matched ${matches.length}/${keywordList.length}.`\n },\n pass,\n }\n },\n\n toScoreRubricGreaterThan(received: unknown, threshold: number) {\n const score = typeof received === 'number'\n ? received\n : (received as RubricJudgeResult | null)?.score\n\n if (typeof score !== 'number') {\n return {\n message: () => 'Expected received value to be a number or RubricJudgeResult.',\n pass: false,\n }\n }\n\n const pass = score > threshold\n\n return {\n message: () => {\n if (pass) {\n return `Expected rubric score ${score} to be less than or equal to ${threshold}.`\n }\n\n return `Expected rubric score ${score} to be greater than ${threshold}.`\n },\n pass,\n }\n },\n\n toSatisfyStructuredOutput<T>(received: unknown, validator: (value: unknown) => value is T) {\n const pass = validator(received)\n\n return {\n message: () => pass\n ? 'Expected structured output validator to fail.'\n : 'Expected structured output validator to pass.',\n pass,\n }\n },\n\n toSatisfyToolCallArgs(\n received: unknown,\n toolName: string,\n validator: (args: unknown) => boolean,\n ) {\n const toolCalls = (received as ToolCallContainer | null)?.toolCalls\n\n if (toolCalls == null) {\n return {\n message: () => 'Expected received value to provide toolCalls array.',\n pass: false,\n }\n }\n\n const targetCall = toolCalls.find(call => call.name === toolName)\n if (targetCall == null) {\n return {\n message: () => `Expected tool call ${toolName} to exist.`,\n pass: false,\n }\n }\n\n const pass = validator(targetCall.args)\n\n return {\n message: () => pass\n ? `Expected tool call args for ${toolName} to fail validation.`\n : `Expected tool call args for ${toolName} to pass validation.`,\n pass,\n }\n },\n })\n}\n\ninterface VievalCustomMatchers {\n /**\n * Asserts that text includes required keywords.\n *\n * Example:\n * `expect('calm answer').toMustInclude(['calm'])`\n */\n toMustInclude: (keywords: string | readonly string[], options?: KeywordMatcherOptions) => void\n /**\n * Asserts that text excludes forbidden keywords.\n *\n * Example:\n * `expect('calm answer').toMustExclude(['bestmove'])`\n */\n toMustExclude: (keywords: string | readonly string[], options?: KeywordMatcherOptions) => void\n /**\n * Asserts rubric score is greater than a threshold.\n *\n * Example:\n * `expect({ score: 0.91 }).toScoreRubricGreaterThan(0.8)`\n */\n toScoreRubricGreaterThan: (threshold: number) => void\n /**\n * Asserts structured output satisfies a validator.\n *\n * Example:\n * `expect(value).toSatisfyStructuredOutput(isMyShape)`\n */\n toSatisfyStructuredOutput: <TValue>(validator: (value: unknown) => value is TValue) => void\n /**\n * Asserts selected tool-call args satisfy validator.\n *\n * Example:\n * `expect({ toolCalls }).toSatisfyToolCallArgs('builtIn_sparkCommand', isSparkArgs)`\n */\n toSatisfyToolCallArgs: (toolName: string, validator: (args: unknown) => boolean) => void\n}\n\n/* eslint-disable unused-imports/no-unused-vars */\ndeclare module '@vitest/expect' {\n interface Matchers<T = any> extends VievalCustomMatchers {}\n interface Assertion<T = any> extends VievalCustomMatchers {}\n}\n\ndeclare module 'vitest' {\n interface Assertion extends VievalCustomMatchers {}\n interface Matchers<T = any> extends VievalCustomMatchers {}\n}\n/* eslint-enable unused-imports/no-unused-vars */\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"expect-extensions-Mf1sMNBv.mjs","names":[],"sources":["../src/testing/runtime-expect.ts","../src/testing/expect-extensions.ts"],"sourcesContent":["import type { ExpectStatic, MatchersObject, MatcherState, Tester } from '@vitest/expect'\n\nimport {\n addCustomEqualityTesters,\n ASYMMETRIC_MATCHERS_OBJECT,\n chai,\n ChaiStyleAssertions,\n customMatchers,\n getState,\n GLOBAL_EXPECT,\n JestAsymmetricMatchers,\n JestChaiExpect,\n JestExtend,\n setState,\n} from '@vitest/expect'\n\nlet isPluginInstalled = false\nlet runtimeExpectInstance: ExpectStatic | undefined\n\n/**\n * Installs Vitest expect plugins once for process-local runtime assertions.\n *\n * Use when:\n * - running eval tasks outside Vitest worker runtime\n * - building an `expect` instance that does not rely on Vitest internal state\n *\n * Expects:\n * - `@vitest/expect` is available in runtime dependencies\n *\n * Returns:\n * - nothing; side-effects are applied to `chai`\n */\nfunction ensureRuntimeExpectPluginsInstalled(): void {\n if (isPluginInstalled) {\n return\n }\n\n chai.use(JestExtend)\n chai.use(JestChaiExpect)\n chai.use(ChaiStyleAssertions)\n chai.use(JestAsymmetricMatchers)\n isPluginInstalled = true\n}\n\n/**\n * Creates a Vitest-compatible `expect` instance without worker-state coupling.\n *\n * Use when:\n * - CLI runtime needs assertion helpers from `vieval/expect`\n * - code is executed outside `vitest run`\n *\n * Expects:\n * - plugins from {@link ensureRuntimeExpectPluginsInstalled} are installed\n * - callers do not depend on Vitest worker-only features (snapshot/poll internals)\n *\n * Returns:\n * - standalone expect instance with core matcher APIs and `extend`\n */\nfunction createRuntimeExpect(): ExpectStatic {\n ensureRuntimeExpectPluginsInstalled()\n\n const runtimeExpect = ((value: unknown, message?: string) => {\n const currentState = getState(runtimeExpect)\n setState({ assertionCalls: currentState.assertionCalls + 1 }, runtimeExpect)\n return chai.expect(value, message)\n }) as unknown as ExpectStatic\n\n Object.assign(runtimeExpect, chai.expect)\n Object.assign(runtimeExpect, (globalThis as Record<PropertyKey, unknown>)[ASYMMETRIC_MATCHERS_OBJECT] as object)\n\n runtimeExpect.getState = () => getState(runtimeExpect)\n runtimeExpect.setState = (state: Partial<MatcherState>) => setState(state, runtimeExpect)\n runtimeExpect.assert = chai.assert\n // NOTICE:\n // Chai's public `ExpectStatic` type does not expose Vitest's plugin-added `extend`.\n // Runtime `chai.expect.extend` exists after `JestExtend` plugin installation.\n // Source/context: `@vitest/expect` plugin pipeline in `dist/index.js`.\n // Removal condition: remove this cast if upstream exposes `extend` on Chai expect types.\n const chaiExpectWithExtend = chai.expect as unknown as {\n extend: (expect: ExpectStatic, matchers: MatchersObject) => void\n }\n runtimeExpect.extend = (matchers: MatchersObject) => chaiExpectWithExtend.extend(runtimeExpect, matchers)\n runtimeExpect.addEqualityTesters = (customTesters: Tester[]) => addCustomEqualityTesters(customTesters)\n runtimeExpect.unreachable = (message?: string) => {\n chai.assert.fail(`expected${message ? ` \"${message}\" ` : ' '}not to be reached`)\n }\n\n runtimeExpect.setState({\n assertionCalls: 0,\n currentTestName: '',\n expectedAssertionsNumber: null,\n expectedAssertionsNumberErrorGen: null,\n isExpectingAssertions: false,\n isExpectingAssertionsError: null,\n })\n\n runtimeExpect.extend(customMatchers)\n\n return runtimeExpect\n}\n\n/**\n * Returns process-local runtime `expect` instance used by Vieval.\n *\n * Use when:\n * - you need matcher assertions in eval files and CLI runtime\n * - importing from `vitest` would crash outside Vitest worker contexts\n *\n * Expects:\n * - single-process usage (instance is memoized per process)\n *\n * Returns:\n * - memoized runtime `expect` instance\n */\nexport function getRuntimeExpect(): ExpectStatic {\n if (runtimeExpectInstance != null) {\n return runtimeExpectInstance\n }\n\n runtimeExpectInstance = createRuntimeExpect()\n Object.defineProperty(globalThis, GLOBAL_EXPECT, {\n configurable: true,\n value: runtimeExpectInstance,\n writable: true,\n })\n\n return runtimeExpectInstance\n}\n","import type { RubricJudgeResult, ToolCall } from '../core/assertions'\n\nimport { normalizeMatchText } from '../core/assertions'\nimport { getRuntimeExpect } from './runtime-expect'\n\n/**\n * Options for keyword-based matcher behavior.\n */\nexport interface KeywordMatcherOptions {\n /**\n * Case-sensitive matching toggle.\n *\n * @default false\n */\n caseSensitive?: boolean\n /**\n * Match mode.\n *\n * @default 'all'\n */\n mode?: 'all' | 'any'\n}\n\n/**\n * Shape used by tool-call matchers.\n */\nexport interface ToolCallContainer {\n /**\n * Tool calls to inspect.\n */\n toolCalls?: readonly ToolCall[]\n}\n\nfunction toKeywordArray(keywords: string | readonly string[]): readonly string[] {\n if (typeof keywords === 'string') {\n return [keywords]\n }\n\n return keywords\n}\n\n/**\n * Registers vieval custom matchers on Vitest `expect`.\n *\n * Call stack:\n *\n * {@link installVievalExpectMatchers}\n * -> `expect.extend(...)`\n * -> `expect(received).toMustInclude(...)`\n * -> `expect(received).toScoreRubricGreaterThan(...)`\n *\n * Use when:\n * - eval suites need domain assertions while preserving native Vitest ergonomics\n * - callers want native `.not` chaining with the same matchers\n */\nexport function installVievalExpectMatchers(): void {\n const expect = getRuntimeExpect()\n\n expect.extend({\n toMustExclude(received: unknown, keywords: string | readonly string[], options: KeywordMatcherOptions = {}) {\n const keywordList = toKeywordArray(keywords)\n\n if (typeof received !== 'string') {\n return {\n message: () => 'Expected received value to be a string.',\n pass: false,\n }\n }\n\n const normalizedText = normalizeMatchText(received, options.caseSensitive ?? false)\n const forbiddenMatches = keywordList.filter((keyword) => {\n return normalizedText.includes(normalizeMatchText(keyword, options.caseSensitive ?? false))\n })\n\n const pass = forbiddenMatches.length === 0\n\n return {\n message: () => {\n if (pass) {\n return `Expected text to include forbidden keywords: ${keywordList.join(', ')}`\n }\n\n return `Expected text not to include forbidden keywords, but matched: ${forbiddenMatches.join(', ')}`\n },\n pass,\n }\n },\n\n toMustInclude(received: unknown, keywords: string | readonly string[], options: KeywordMatcherOptions = {}) {\n const keywordList = toKeywordArray(keywords)\n\n if (typeof received !== 'string') {\n return {\n message: () => 'Expected received value to be a string.',\n pass: false,\n }\n }\n\n const normalizedText = normalizeMatchText(received, options.caseSensitive ?? false)\n const matches = keywordList.filter((keyword) => {\n return normalizedText.includes(normalizeMatchText(keyword, options.caseSensitive ?? false))\n })\n\n const mode = options.mode ?? 'all'\n const pass = mode === 'all' ? matches.length === keywordList.length : matches.length > 0\n\n return {\n message: () => {\n if (pass) {\n return `Expected text not to match required keywords, but matched: ${matches.join(', ')}`\n }\n\n return `Expected text to match required keywords (${mode}), but matched ${matches.length}/${keywordList.length}.`\n },\n pass,\n }\n },\n\n toScoreRubricGreaterThan(received: unknown, threshold: number) {\n const score = typeof received === 'number'\n ? received\n : (received as RubricJudgeResult | null)?.score\n\n if (typeof score !== 'number') {\n return {\n message: () => 'Expected received value to be a number or RubricJudgeResult.',\n pass: false,\n }\n }\n\n const pass = score > threshold\n\n return {\n message: () => {\n if (pass) {\n return `Expected rubric score ${score} to be less than or equal to ${threshold}.`\n }\n\n return `Expected rubric score ${score} to be greater than ${threshold}.`\n },\n pass,\n }\n },\n\n toSatisfyStructuredOutput<T>(received: unknown, validator: (value: unknown) => value is T) {\n const pass = validator(received)\n\n return {\n message: () => pass\n ? 'Expected structured output validator to fail.'\n : 'Expected structured output validator to pass.',\n pass,\n }\n },\n\n toSatisfyToolCallArgs(\n received: unknown,\n toolName: string,\n validator: (args: unknown) => boolean,\n ) {\n const toolCalls = (received as ToolCallContainer | null)?.toolCalls\n\n if (toolCalls == null) {\n return {\n message: () => 'Expected received value to provide toolCalls array.',\n pass: false,\n }\n }\n\n const targetCall = toolCalls.find(call => call.name === toolName)\n if (targetCall == null) {\n return {\n message: () => `Expected tool call ${toolName} to exist.`,\n pass: false,\n }\n }\n\n const pass = validator(targetCall.args)\n\n return {\n message: () => pass\n ? `Expected tool call args for ${toolName} to fail validation.`\n : `Expected tool call args for ${toolName} to pass validation.`,\n pass,\n }\n },\n })\n}\n\ninterface VievalCustomMatchers {\n /**\n * Asserts that text includes required keywords.\n *\n * Example:\n * `expect('calm answer').toMustInclude(['calm'])`\n */\n toMustInclude: (keywords: string | readonly string[], options?: KeywordMatcherOptions) => void\n /**\n * Asserts that text excludes forbidden keywords.\n *\n * Example:\n * `expect('calm answer').toMustExclude(['bestmove'])`\n */\n toMustExclude: (keywords: string | readonly string[], options?: KeywordMatcherOptions) => void\n /**\n * Asserts rubric score is greater than a threshold.\n *\n * Example:\n * `expect({ score: 0.91 }).toScoreRubricGreaterThan(0.8)`\n */\n toScoreRubricGreaterThan: (threshold: number) => void\n /**\n * Asserts structured output satisfies a validator.\n *\n * Example:\n * `expect(value).toSatisfyStructuredOutput(isMyShape)`\n */\n toSatisfyStructuredOutput: <TValue>(validator: (value: unknown) => value is TValue) => void\n /**\n * Asserts selected tool-call args satisfy validator.\n *\n * Example:\n * `expect({ toolCalls }).toSatisfyToolCallArgs('builtIn_sparkCommand', isSparkArgs)`\n */\n toSatisfyToolCallArgs: (toolName: string, validator: (args: unknown) => boolean) => void\n}\n\n/* eslint-disable unused-imports/no-unused-vars */\ndeclare module '@vitest/expect' {\n interface Matchers<T = any> extends VievalCustomMatchers {}\n interface Assertion<T = any> extends VievalCustomMatchers {}\n}\n\ndeclare module 'vitest' {\n interface Assertion extends VievalCustomMatchers {}\n interface Matchers<T = any> extends VievalCustomMatchers {}\n}\n/* eslint-enable unused-imports/no-unused-vars */\n"],"mappings":"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"}
|
package/dist/expect.d.mts
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import * as _$vitest from "vitest";
|
|
2
|
-
|
|
3
1
|
//#region src/expect.d.ts
|
|
4
2
|
/**
|
|
5
3
|
* Re-exported expect with vieval custom matchers pre-installed.
|
|
6
4
|
*/
|
|
7
|
-
declare const expect:
|
|
5
|
+
declare const expect: import("vitest").ExpectStatic;
|
|
8
6
|
//#endregion
|
|
9
7
|
export { expect };
|
|
10
8
|
//# sourceMappingURL=expect.d.mts.map
|
package/dist/expect.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as getRuntimeExpect, t as installVievalExpectMatchers } from "./expect-extensions-
|
|
1
|
+
import { n as getRuntimeExpect, t as installVievalExpectMatchers } from "./expect-extensions-Mf1sMNBv.mjs";
|
|
2
2
|
//#region src/expect.ts
|
|
3
3
|
let isInstalled = false;
|
|
4
4
|
function ensureExpectMatchersInstalled() {
|
package/dist/expect.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"expect.mjs","names":[],"sources":["../src/expect.ts"],"sourcesContent":["import { installVievalExpectMatchers } from './testing/expect-extensions'\nimport { getRuntimeExpect } from './testing/runtime-expect'\n\nlet isInstalled = false\n\nfunction ensureExpectMatchersInstalled(): void {\n if (isInstalled) {\n return\n }\n\n installVievalExpectMatchers()\n isInstalled = true\n}\n\nensureExpectMatchersInstalled()\n\n/**\n * Re-exported expect with vieval custom matchers pre-installed.\n */\nexport const expect = getRuntimeExpect()\n"],"mappings":";;AAGA,IAAI,cAAc;AAElB,SAAS,gCAAsC;
|
|
1
|
+
{"version":3,"file":"expect.mjs","names":[],"sources":["../src/expect.ts"],"sourcesContent":["import { installVievalExpectMatchers } from './testing/expect-extensions'\nimport { getRuntimeExpect } from './testing/runtime-expect'\n\nlet isInstalled = false\n\nfunction ensureExpectMatchersInstalled(): void {\n if (isInstalled) {\n return\n }\n\n installVievalExpectMatchers()\n isInstalled = true\n}\n\nensureExpectMatchersInstalled()\n\n/**\n * Re-exported expect with vieval custom matchers pre-installed.\n */\nexport const expect = getRuntimeExpect()\n"],"mappings":";;AAGA,IAAI,cAAc;AAElB,SAAS,gCAAsC;CAC7C,IAAI,aACF;CAGF,4BAA4B;CAC5B,cAAc;AAChB;AAEA,8BAA8B;;;;AAK9B,MAAa,SAAS,iBAAiB"}
|
|
@@ -22,7 +22,8 @@ type SchedulerScope = 'workspace' | 'project' | 'task' | 'attempt' | 'case';
|
|
|
22
22
|
* - runtime helpers need to know which hierarchical scope is being executed
|
|
23
23
|
*
|
|
24
24
|
* Expects:
|
|
25
|
-
* - `workspaceId`
|
|
25
|
+
* - `workspaceId` is always present
|
|
26
|
+
* - `experimentId` is metadata for middleware and logging, not queue partitioning
|
|
26
27
|
* - narrower ids are only provided when the selected scope requires them
|
|
27
28
|
*
|
|
28
29
|
* Returns:
|
|
@@ -136,7 +137,7 @@ declare function createSchedulerRuntime(options?: CreateSchedulerRuntimeOptions)
|
|
|
136
137
|
* Resolves the scheduler scopes that apply to a context.
|
|
137
138
|
*
|
|
138
139
|
* Before:
|
|
139
|
-
* - `{ scope: 'case', workspaceId: 'ws',
|
|
140
|
+
* - `{ scope: 'case', workspaceId: 'ws', projectName: 'project', caseId: 'case-1' }`
|
|
140
141
|
*
|
|
141
142
|
* After:
|
|
142
143
|
* - `['workspace', 'project', 'task', 'attempt', 'case']` up to the requested scope
|
|
@@ -144,4 +145,4 @@ declare function createSchedulerRuntime(options?: CreateSchedulerRuntimeOptions)
|
|
|
144
145
|
declare function getActiveScopes(context: SchedulerScopeContext): SchedulerScope[];
|
|
145
146
|
//#endregion
|
|
146
147
|
export { SchedulerMiddleware as a, SchedulerScopeContext as c, SchedulerConcurrencyConfig as i, getActiveScopes as n, SchedulerRuntime as o, CreateSchedulerRuntimeOptions as r, SchedulerScope as s, createSchedulerRuntime as t };
|
|
147
|
-
//# sourceMappingURL=index-
|
|
148
|
+
//# sourceMappingURL=index-Be5I1ZJL.d.mts.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Buffer } from "node:buffer";
|
|
2
1
|
import { ReadStream, WriteStream } from "node:fs";
|
|
2
|
+
import { Buffer } from "node:buffer";
|
|
3
3
|
|
|
4
4
|
//#region src/core/cache/types.d.ts
|
|
5
5
|
/**
|
|
@@ -1354,4 +1354,4 @@ interface ConfigHookPlugin<TConfig> {
|
|
|
1354
1354
|
}
|
|
1355
1355
|
//#endregion
|
|
1356
1356
|
export { InferenceExecutor as $, RunScheduledTasksOptions as A, asProjectRelativePath as B, TaskDefinition as C, TaskRunContext as D, TaskReporterHooks as E, CreateTaskExecutionContextOptions as F, AggregatedProviderSummary as G, CreateVievalRunnerRuntimeContextOptions as H, TaskExecutionContext as I, RunResult as J, AggregatedRunResults as K, createTaskExecutionContext as L, RunnerTaskState as M, ScheduledTaskExecutor as N, TaskRunOutput as O, runScheduledTasks as P, CreateRunnerScheduleOptions as Q, ModelDefinition as R, TaskConcurrencyConfig as S, TaskReporterEventPayload as T, RunnerRuntimeContext as U, collectEvalEntries as V, createRunnerRuntimeContext as W, RunScoreKind as X, RunScore as Y, aggregateRunResults as Z, ScopedMatrices as _, CliOpenTelemetryReportingConfig as a, ScheduledTaskMatrixMeta as at, TaskCaseReporterPayload as b, EvalDefinition as c, createFilesystemTaskCacheRuntime as ct, MatrixAxisValues as d, CacheFileOptions as dt, RunnerMatrixDefinition as et, MatrixDefinition as f, CacheNamespace as ft, MatrixValue as g, MatrixRow as h, Awaitable as i, ScheduledTaskMatrix as it, RunnerExecutionError as j, TelemetryAttributeValue as k, EvalModule as l, normalizeCacheFilePathSegments as lt, MatrixPrimitive as m, defineEval as n, RunnerMatrixSelection as nt, CliReportingConfig as o, createRunnerSchedule as ot, MatrixLayer as p, TaskCacheRuntime as pt, AggregatedRunSummary as q, defineTask as r, ScheduledTask as rt, CollectedEvalEntry as s, CreateFilesystemTaskCacheRuntimeOptions as st, ConfigHookPlugin as t, RunnerMatrixInput as tt, EvalModuleMap as u, CacheFileHandle as ut, TaskAutoRetryDelay as v, TaskExecutionPolicy as w, TaskCaseState as x, TaskCaseReporterEndPayload as y, resolveModelByName as z };
|
|
1357
|
-
//# sourceMappingURL=index-
|
|
1357
|
+
//# sourceMappingURL=index-CwKBlCG9.d.mts.map
|
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { $ as InferenceExecutor, D as TaskRunContext, I as TaskExecutionContext, J as RunResult, O as TaskRunOutput, R as ModelDefinition, S as TaskConcurrencyConfig, X as RunScoreKind, f as MatrixDefinition, k as TelemetryAttributeValue, o as CliReportingConfig, p as MatrixLayer, rt as ScheduledTask, t as ConfigHookPlugin, w as TaskExecutionPolicy } from "./index-
|
|
2
|
-
import { a as requiredEnvFrom } from "./env-
|
|
1
|
+
import { $ as InferenceExecutor, D as TaskRunContext, I as TaskExecutionContext, J as RunResult, O as TaskRunOutput, R as ModelDefinition, S as TaskConcurrencyConfig, X as RunScoreKind, f as MatrixDefinition, k as TelemetryAttributeValue, o as CliReportingConfig, p as MatrixLayer, rt as ScheduledTask, t as ConfigHookPlugin, w as TaskExecutionPolicy } from "./index-CwKBlCG9.mjs";
|
|
2
|
+
import { a as requiredEnvFrom } from "./env-bRH0K6fU.mjs";
|
|
3
3
|
import { expect } from "./expect.mjs";
|
|
4
|
-
import * as _$c12 from "c12";
|
|
5
4
|
|
|
6
5
|
//#region src/cli/reporters/vitest-compat-reporter.d.ts
|
|
7
6
|
type Awaitable<T> = T | Promise<T>;
|
|
@@ -360,7 +359,7 @@ type CliConfig = CliProjectModeConfig | CliWorkspaceModeConfig | CliComparisonMo
|
|
|
360
359
|
/**
|
|
361
360
|
* Helper used by `vieval.config.*` for better type inference.
|
|
362
361
|
*/
|
|
363
|
-
declare const defineConfig:
|
|
362
|
+
declare const defineConfig: import("c12").DefineConfig<CliConfig, import("c12").ConfigLayerMeta>;
|
|
364
363
|
/**
|
|
365
364
|
* Loads `.env*` files using Vite's env resolution behavior.
|
|
366
365
|
*
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { i as registerEvalDefinition, l as loadEnv, o as createNoopTelemetryRuntime, s as defineConfig } from "./registry-
|
|
2
|
-
import { t as createSchedulerQueue } from "./queue-
|
|
3
|
-
import { n as requiredEnvFrom } from "./env-
|
|
1
|
+
import { i as registerEvalDefinition, l as loadEnv, o as createNoopTelemetryRuntime, s as defineConfig } from "./registry-BSyjwZFx.mjs";
|
|
2
|
+
import { t as createSchedulerQueue } from "./queue-BL86z2W_.mjs";
|
|
3
|
+
import { n as requiredEnvFrom } from "./env-BVYeJhGA.mjs";
|
|
4
4
|
import { defineEval, defineTask } from "./config.mjs";
|
|
5
5
|
import { expect } from "./expect.mjs";
|
|
6
6
|
import { errorMessageFrom, sleep } from "@moeru/std";
|
|
@@ -219,6 +219,16 @@ function collectCaseOutcomeScores(outcome, scoreBucketsByKind) {
|
|
|
219
219
|
const judgeScore = outcome.scoresByKind.get("judge");
|
|
220
220
|
if (judgeScore != null) scoreBucketsByKind.judge.push(judgeScore);
|
|
221
221
|
}
|
|
222
|
+
function emitCaseOutcome(context, taskCase, outcome, index, totalCases) {
|
|
223
|
+
emitCaseEnd(context.reporterHooks, {
|
|
224
|
+
...outcome.errorMessage == null ? {} : { errorMessage: outcome.errorMessage },
|
|
225
|
+
index,
|
|
226
|
+
...outcome.output === void 0 ? {} : { output: outcome.output },
|
|
227
|
+
state: outcome.state,
|
|
228
|
+
name: taskCase.name,
|
|
229
|
+
total: totalCases
|
|
230
|
+
});
|
|
231
|
+
}
|
|
222
232
|
function createCaseBuilder(registeredCases) {
|
|
223
233
|
function registerCase(name, run, options) {
|
|
224
234
|
registeredCases.push({
|
|
@@ -346,14 +356,7 @@ function describeTask(name, build, options = {}) {
|
|
|
346
356
|
if (!hasAutoAttempt) await Promise.all(registeredCases.map(async (taskCase, index) => {
|
|
347
357
|
const executeCase = async () => {
|
|
348
358
|
const outcome = await executeRegisteredCase(context, taskCase, index, totalCases, taskExecutionPolicy);
|
|
349
|
-
|
|
350
|
-
...outcome.errorMessage == null ? {} : { errorMessage: outcome.errorMessage },
|
|
351
|
-
index,
|
|
352
|
-
...outcome.output === void 0 ? {} : { output: outcome.output },
|
|
353
|
-
state: outcome.state,
|
|
354
|
-
name: taskCase.name,
|
|
355
|
-
total: totalCases
|
|
356
|
-
});
|
|
359
|
+
emitCaseOutcome(context, taskCase, outcome, index, totalCases);
|
|
357
360
|
collectCaseOutcomeScores(outcome, scoreBucketsByKind);
|
|
358
361
|
};
|
|
359
362
|
const concurrency = resolveCaseConcurrency(taskCase, runtimeTaskConcurrency, context.runtimeConcurrency);
|
|
@@ -367,10 +370,9 @@ function describeTask(name, build, options = {}) {
|
|
|
367
370
|
await queue.run(executeCase);
|
|
368
371
|
}));
|
|
369
372
|
else {
|
|
370
|
-
let finalOutcomes = [];
|
|
371
373
|
let attemptIndex = 0;
|
|
372
374
|
for (;;) {
|
|
373
|
-
|
|
375
|
+
const attemptOutcomes = await Promise.all(registeredCases.map(async (taskCase, index) => {
|
|
374
376
|
const executeCase = async () => await executeRegisteredCase(context, taskCase, index, totalCases, taskExecutionPolicy);
|
|
375
377
|
const concurrency = resolveCaseConcurrency(taskCase, runtimeTaskConcurrency, context.runtimeConcurrency);
|
|
376
378
|
if (concurrency == null) return await executeCase();
|
|
@@ -379,7 +381,13 @@ function describeTask(name, build, options = {}) {
|
|
|
379
381
|
caseQueues.set(queueKey, queue);
|
|
380
382
|
return await queue.run(executeCase);
|
|
381
383
|
}));
|
|
382
|
-
|
|
384
|
+
attemptOutcomes.forEach((outcome, index) => {
|
|
385
|
+
const taskCase = registeredCases[index];
|
|
386
|
+
if (taskCase == null) return;
|
|
387
|
+
emitCaseOutcome(context, taskCase, outcome, index, totalCases);
|
|
388
|
+
collectCaseOutcomeScores(outcome, scoreBucketsByKind);
|
|
389
|
+
});
|
|
390
|
+
if (!attemptOutcomes.some((outcome, index) => {
|
|
383
391
|
if (outcome.state === "passed") return false;
|
|
384
392
|
const taskCase = registeredCases[index];
|
|
385
393
|
if (taskCase == null) return false;
|
|
@@ -387,19 +395,6 @@ function describeTask(name, build, options = {}) {
|
|
|
387
395
|
})) break;
|
|
388
396
|
attemptIndex += 1;
|
|
389
397
|
}
|
|
390
|
-
finalOutcomes.forEach((outcome, index) => {
|
|
391
|
-
const taskCase = registeredCases[index];
|
|
392
|
-
if (taskCase == null) return;
|
|
393
|
-
emitCaseEnd(context.reporterHooks, {
|
|
394
|
-
...outcome.errorMessage == null ? {} : { errorMessage: outcome.errorMessage },
|
|
395
|
-
index,
|
|
396
|
-
...outcome.output === void 0 ? {} : { output: outcome.output },
|
|
397
|
-
state: outcome.state,
|
|
398
|
-
name: taskCase.name,
|
|
399
|
-
total: totalCases
|
|
400
|
-
});
|
|
401
|
-
collectCaseOutcomeScores(outcome, scoreBucketsByKind);
|
|
402
|
-
});
|
|
403
398
|
}
|
|
404
399
|
return { scores: Object.keys(scoreBucketsByKind).filter((kind) => scoreBucketsByKind[kind].length > 0).map((kind) => {
|
|
405
400
|
const values = scoreBucketsByKind[kind];
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../src/dsl/task.ts"],"sourcesContent":["import type { TaskConcurrencyConfig, TaskExecutionPolicy, TaskReporterEventPayload, TaskRunContext, TaskRunOutput } from '../config'\nimport type { RunScoreKind } from '../core/runner'\nimport type { TelemetryAttributeValue } from '../core/telemetry'\n\nimport { errorMessageFrom, sleep } from '@moeru/std'\n\nimport { defineEval, defineTask } from '../config'\nimport { createSchedulerQueue } from '../core/scheduler/queue'\nimport { createNoopTelemetryRuntime } from '../core/telemetry'\nimport { registerEvalDefinition } from './registry'\n\n/**\n * Runtime context provided to a task case callback.\n */\nexport interface CaseRunContext<TInput> extends TaskRunContext {\n /**\n * Case-scoped matrix payload.\n */\n matrix: TaskRunContext['task']['matrix'] & { inputs: TInput }\n /**\n * Overrides one case score family with a custom normalized value.\n *\n * Use when:\n * - one case computes a benchmark-native score that should flow into run aggregation\n *\n * Expects:\n * - `score` to stay in the `0..1` range\n */\n score: (score: number, kind?: RunScoreKind) => void\n /**\n * Emits one custom case metric into report events.\n *\n * Use when:\n * - tasks need structured benchmark metadata beyond exact/judge score families\n *\n * Expects:\n * - `name` to be a stable metric identifier\n * - `value` to be JSON-serializable\n */\n metric: (name: string, value: TelemetryAttributeValue) => void\n /**\n * Cooperative abort signal for the current case execution.\n */\n signal: AbortSignal\n}\n\n/**\n * Callback for one task case.\n */\nexport type CaseRunner<TInput> = (context: CaseRunContext<TInput>) => Promise<unknown> | unknown\n\ninterface RegisteredCase<TInput> {\n concurrency?: number\n executionPolicy?: TaskExecutionPolicy\n input: TInput\n name: string\n queueKey?: object\n run: CaseRunner<TInput>\n}\n\n/**\n * Per-group options for `casesFromInputs`.\n *\n * Use when:\n * - one generated case group should run with a lower case concurrency than the task default\n * - a task should keep a broader task-level cap while one expensive case family stays bounded\n *\n * Expects:\n * - `concurrency` to be a positive integer when provided\n *\n * Returns:\n * - one partial case-group execution descriptor\n */\nexport interface CasesFromInputsOptions extends TaskExecutionPolicy {\n /**\n * Case-level concurrency cap for cases registered by one `casesFromInputs(...)` call.\n */\n concurrency?: number\n}\n\n/**\n * Per-case registration options for `caseOf`.\n */\nexport interface CaseRegistrationOptions<TInput> extends TaskExecutionPolicy {\n /**\n * Optional case input payload.\n */\n input: TInput\n}\n\ninterface CaseExecutionOutcome {\n errorMessage?: string\n output?: unknown\n scoresByKind: Map<RunScoreKind, number>\n state: 'failed' | 'passed' | 'timeout'\n}\n\nfunction cloneCaseMatrix(matrix: TaskRunContext['task']['matrix']): TaskRunContext['task']['matrix'] {\n return {\n eval: {\n ...matrix.eval,\n },\n meta: {\n ...matrix.meta,\n },\n run: {\n ...matrix.run,\n },\n }\n}\n\nfunction createTaskCaseReporterId(index: number, name: string): string {\n return `${index}:${encodeURIComponent(name)}`\n}\n\nfunction isTelemetryAttributeScalar(value: unknown): value is boolean | number | string {\n return typeof value === 'boolean' || typeof value === 'number' || typeof value === 'string'\n}\n\nfunction isTelemetryAttributeArray(value: readonly TelemetryAttributeValue[]): value is readonly boolean[] | readonly number[] | readonly string[] {\n return value.every(isTelemetryAttributeScalar)\n}\n\nfunction canAttachMetricAsAttribute(value: TelemetryAttributeValue): value is boolean | number | string | readonly boolean[] | readonly number[] | readonly string[] {\n if (isTelemetryAttributeScalar(value)) {\n return true\n }\n\n return Array.isArray(value) && isTelemetryAttributeArray(value)\n}\n\nfunction assertValidScore(score: number): void {\n if (!Number.isFinite(score) || score < 0 || score > 1) {\n throw new Error(`Case score must be a finite number in range 0..1, got \"${score}\".`)\n }\n}\n\nfunction assertNonNegativeInteger(value: number, label: string): void {\n if (!Number.isFinite(value) || !Number.isInteger(value) || value < 0) {\n throw new Error(`Invalid ${label}: ${String(value)}`)\n }\n}\n\nfunction assertNonNegativeNumber(value: number, label: string): void {\n if (!Number.isFinite(value) || value < 0) {\n throw new Error(`Invalid ${label}: ${String(value)}`)\n }\n}\n\nfunction assertPositiveInteger(value: number, label: string): void {\n if (!Number.isFinite(value) || !Number.isInteger(value) || value <= 0) {\n throw new Error(`Invalid ${label}: ${String(value)}`)\n }\n}\n\nfunction autoRetryDelayMs(retryIndex: number): number {\n // Retry index 1 is the first retry after the initial case failure.\n return 500 * 2 ** (retryIndex - 1)\n}\n\nfunction resolveAutoRetryDelay(policy: TaskExecutionPolicy, retryIndex: number): number {\n const delay = policy.autoRetryDelay\n\n if (delay == null) {\n return autoRetryDelayMs(retryIndex)\n }\n\n return typeof delay === 'number' ? delay : delay(retryIndex)\n}\n\nfunction emitCaseStart(\n hooks: TaskRunContext['reporterHooks'] | undefined,\n payload: {\n autoRetry?: number\n index: number\n input?: unknown\n name: string\n retryIndex?: number\n total: number\n },\n): void {\n try {\n hooks?.onCaseStart?.(payload)\n }\n catch {\n // Reporter hooks must never affect task scoring.\n }\n}\n\nfunction emitCaseEnd(\n hooks: TaskRunContext['reporterHooks'] | undefined,\n payload: {\n index: number\n output?: unknown\n state: 'passed' | 'failed' | 'timeout'\n name: string\n total: number\n errorMessage?: string\n },\n): void {\n try {\n hooks?.onCaseEnd?.(payload)\n }\n catch {\n // Reporter hooks must never affect task scoring.\n }\n}\n\nfunction emitReporterEvent(\n hooks: TaskRunContext['reporterHooks'] | undefined,\n payload: TaskReporterEventPayload,\n): void {\n try {\n hooks?.onEvent?.(payload)\n }\n catch {\n // Reporter hooks must never affect task scoring.\n }\n}\n\nfunction createCaseTimeoutError(timeout: number): Error {\n const error = new Error(`Case timed out after ${timeout}ms.`)\n error.name = 'TimeoutError'\n return error\n}\n\nfunction normalizeExecutionPolicy(policy: TaskExecutionPolicy | undefined, label: string): TaskExecutionPolicy | undefined {\n if (policy == null) {\n return undefined\n }\n\n if (policy.autoAttempt != null) {\n assertNonNegativeInteger(policy.autoAttempt, `${label} autoAttempt`)\n }\n\n if (policy.autoRetry != null) {\n assertNonNegativeInteger(policy.autoRetry, `${label} autoRetry`)\n }\n\n if (typeof policy.autoRetryDelay === 'number') {\n assertNonNegativeNumber(policy.autoRetryDelay, `${label} autoRetryDelay`)\n }\n\n if (policy.timeout != null) {\n assertPositiveInteger(policy.timeout, `${label} timeout`)\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 resolveCaseExecutionPolicy(\n taskCase: RegisteredCase<unknown>,\n taskExecutionPolicy: TaskExecutionPolicy | undefined,\n): Required<Pick<TaskExecutionPolicy, 'autoAttempt' | 'autoRetry'>> & Pick<TaskExecutionPolicy, 'autoRetryDelay' | 'timeout'> {\n return {\n autoAttempt: taskCase.executionPolicy?.autoAttempt ?? taskExecutionPolicy?.autoAttempt ?? 0,\n autoRetry: taskCase.executionPolicy?.autoRetry ?? taskExecutionPolicy?.autoRetry ?? 0,\n autoRetryDelay: taskCase.executionPolicy?.autoRetryDelay ?? taskExecutionPolicy?.autoRetryDelay,\n timeout: taskCase.executionPolicy?.timeout ?? taskExecutionPolicy?.timeout,\n }\n}\n\nasync function runCaseOnce(\n context: TaskRunContext,\n taskCase: RegisteredCase<unknown>,\n index: number,\n timeout: number | undefined,\n): Promise<CaseExecutionOutcome> {\n const customScoresByKind = new Map<RunScoreKind, number>()\n const abortController = new AbortController()\n const telemetry = context.telemetry ?? createNoopTelemetryRuntime()\n const caseId = createTaskCaseReporterId(index, taskCase.name)\n let timeoutHandle: ReturnType<typeof setTimeout> | undefined\n let timedOut = false\n let settled = false\n\n try {\n return await telemetry.withSpan('vieval.case', {\n 'vieval.case.id': caseId,\n 'vieval.case.name': taskCase.name,\n 'vieval.task.id': context.task.id,\n 'vieval.task.name': context.task.entry.name,\n }, async () => {\n const runPromise = Promise.resolve(taskCase.run({\n ...context,\n matrix: {\n ...cloneCaseMatrix(context.task.matrix),\n inputs: taskCase.input,\n },\n metric(name, value) {\n if (abortController.signal.aborted || settled) {\n return\n }\n\n emitReporterEvent(context.reporterHooks, {\n caseId,\n data: {\n name,\n value,\n },\n event: 'task.case.metric',\n })\n telemetry.addEvent('vieval.case.metric', { name, value })\n if (canAttachMetricAsAttribute(value)) {\n telemetry.setAttributes({ [name]: value })\n }\n },\n score(score, kind = 'exact') {\n if (abortController.signal.aborted || settled) {\n return\n }\n\n assertValidScore(score)\n customScoresByKind.set(kind, score)\n telemetry.addEvent('vieval.case.score', {\n 'vieval.score.kind': kind,\n 'vieval.score.value': score,\n })\n emitReporterEvent(context.reporterHooks, {\n caseId,\n data: { kind, score },\n event: 'task.case.score',\n })\n },\n signal: abortController.signal,\n }))\n\n if (timeout != null) {\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutHandle = setTimeout(() => {\n timedOut = true\n abortController.abort(createCaseTimeoutError(timeout))\n reject(createCaseTimeoutError(timeout))\n }, timeout)\n })\n\n const output = await Promise.race([runPromise, timeoutPromise])\n settled = true\n return {\n output,\n scoresByKind: customScoresByKind,\n state: 'passed',\n }\n }\n\n const output = await runPromise\n settled = true\n return {\n output,\n scoresByKind: customScoresByKind,\n state: 'passed',\n }\n })\n }\n catch (error) {\n settled = true\n return {\n errorMessage: errorMessageFrom(error) ?? (timedOut && timeout != null ? `Case timed out after ${timeout}ms.` : 'Unknown case failure.'),\n scoresByKind: customScoresByKind,\n state: timedOut ? 'timeout' : 'failed',\n }\n }\n finally {\n if (timeoutHandle != null) {\n clearTimeout(timeoutHandle)\n }\n }\n}\n\nasync function executeRegisteredCase(\n context: TaskRunContext,\n taskCase: RegisteredCase<unknown>,\n index: number,\n totalCases: number,\n taskExecutionPolicy: TaskExecutionPolicy | undefined,\n): Promise<CaseExecutionOutcome> {\n const resolvedPolicy = resolveCaseExecutionPolicy(taskCase, taskExecutionPolicy)\n let lastOutcome: CaseExecutionOutcome | undefined\n\n for (let retryIndex = 0; retryIndex <= resolvedPolicy.autoRetry; retryIndex += 1) {\n if (retryIndex > 0) {\n const retryDelayMs = resolveAutoRetryDelay(resolvedPolicy, retryIndex)\n assertNonNegativeNumber(retryDelayMs, 'autoRetryDelay result')\n\n if (retryDelayMs > 0) {\n await sleep(retryDelayMs)\n }\n }\n\n emitCaseStart(context.reporterHooks, {\n ...(resolvedPolicy.autoRetry > 0\n ? {\n autoRetry: resolvedPolicy.autoRetry,\n retryIndex,\n }\n : {}),\n index,\n ...(taskCase.input === undefined ? {} : { input: taskCase.input }),\n name: taskCase.name,\n total: totalCases,\n })\n lastOutcome = await runCaseOnce(context, taskCase, index, resolvedPolicy.timeout)\n if (lastOutcome.state === 'passed') {\n return lastOutcome\n }\n }\n\n return lastOutcome ?? {\n errorMessage: 'Unknown case failure.',\n scoresByKind: new Map(),\n state: 'failed',\n }\n}\n\nfunction collectCaseOutcomeScores(\n outcome: CaseExecutionOutcome,\n scoreBucketsByKind: Record<RunScoreKind, number[]>,\n): void {\n if (outcome.state !== 'passed') {\n scoreBucketsByKind.exact.push(0)\n return\n }\n\n if (outcome.scoresByKind.size === 0) {\n scoreBucketsByKind.exact.push(1)\n return\n }\n\n scoreBucketsByKind.exact.push(outcome.scoresByKind.get('exact') ?? 1)\n const judgeScore = outcome.scoresByKind.get('judge')\n if (judgeScore != null) {\n scoreBucketsByKind.judge.push(judgeScore)\n }\n}\n\n/**\n * Builder callbacks passed into `describeTask`.\n */\nexport interface DescribeTaskBuilder {\n /**\n * Registers one explicit case.\n */\n caseOf: {\n (name: string, run: CaseRunner<undefined>): void\n <TInput>(name: string, run: CaseRunner<TInput>, options: CaseRegistrationOptions<TInput>): void\n }\n /**\n * Registers multiple cases from input list.\n */\n casesFromInputs: <TInput>(\n namePrefix: string,\n inputs: readonly TInput[],\n run: CaseRunner<TInput>,\n options?: CasesFromInputsOptions,\n ) => void\n}\n\n/**\n * Options for `describeTask`.\n */\nexport interface DescribeTaskOptions extends TaskExecutionPolicy {\n /**\n * Optional description override.\n */\n description?: string\n /**\n * Optional task-local concurrency overrides.\n *\n * Use when:\n * - one task should cap attempt fan-out independently from the surrounding project\n * - one task should cap case fan-out without changing global scheduling defaults\n *\n * Expects:\n * - each provided value to be a positive integer\n *\n * @default inherited from project or CLI concurrency settings\n */\n concurrency?: TaskConcurrencyConfig\n}\n\nfunction createCaseBuilder(registeredCases: RegisteredCase<unknown>[]): DescribeTaskBuilder {\n function registerCase(name: string, run: CaseRunner<undefined>): void\n function registerCase<TInput>(name: string, run: CaseRunner<TInput>, options: CaseRegistrationOptions<TInput>): void\n function registerCase<TInput>(\n name: string,\n run: CaseRunner<TInput> | CaseRunner<undefined>,\n options?: CaseRegistrationOptions<TInput>,\n ): void {\n registeredCases.push({\n executionPolicy: normalizeExecutionPolicy(options, 'task case'),\n input: options?.input,\n name,\n run: run as CaseRunner<unknown>,\n })\n }\n\n return {\n caseOf: registerCase,\n casesFromInputs(namePrefix, inputs, run, options) {\n const queueKey = options?.concurrency == null ? undefined : {}\n\n inputs.forEach((input, index) => {\n registeredCases.push({\n concurrency: options?.concurrency,\n executionPolicy: normalizeExecutionPolicy(options, 'casesFromInputs'),\n input,\n name: `${namePrefix} #${index + 1}`,\n queueKey,\n run: run as CaseRunner<unknown>,\n })\n })\n },\n }\n}\n\nlet activeCasesStack: RegisteredCase<unknown>[][] = []\n\nfunction withActiveCases<T>(cases: RegisteredCase<unknown>[], callback: () => T): T {\n activeCasesStack = [...activeCasesStack, cases]\n\n try {\n return callback()\n }\n finally {\n activeCasesStack = activeCasesStack.slice(0, -1)\n }\n}\n\nfunction getActiveCases(): RegisteredCase<unknown>[] {\n const active = activeCasesStack.at(-1)\n if (active == null) {\n throw new Error('caseOf/casesFromInputs must be called inside describeTask/describeEval.')\n }\n\n return active\n}\n\n/**\n * Registers one case in the currently active task scope.\n */\nexport function caseOf(\n name: string,\n run: CaseRunner<undefined>,\n): void\n\nexport function caseOf<TInput>(\n name: string,\n run: CaseRunner<TInput>,\n options: CaseRegistrationOptions<TInput>,\n): void\n\nexport function caseOf<TInput>(\n name: string,\n run: CaseRunner<TInput> | CaseRunner<undefined>,\n options?: CaseRegistrationOptions<TInput>,\n): void {\n getActiveCases().push({\n executionPolicy: normalizeExecutionPolicy(options, 'task case'),\n input: options?.input,\n name,\n run: run as CaseRunner<unknown>,\n })\n}\n\n/**\n * Registers multiple cases in the currently active task scope.\n */\nexport function casesFromInputs<TInput>(\n namePrefix: string,\n inputs: readonly TInput[],\n run: CaseRunner<TInput>,\n options?: CasesFromInputsOptions,\n): void {\n const queueKey = options?.concurrency == null ? undefined : {}\n\n inputs.forEach((input, index) => {\n getActiveCases().push({\n concurrency: options?.concurrency,\n executionPolicy: normalizeExecutionPolicy(options, 'casesFromInputs'),\n input,\n name: `${namePrefix} #${index + 1}`,\n queueKey,\n run: run as CaseRunner<unknown>,\n })\n })\n}\n\n/**\n * Resolves the effective case concurrency for one registered task case.\n *\n * Before:\n * - registered case override `2`, task default `4`\n * - registered case override `undefined`, task default `3`\n *\n * After:\n * - `2`\n * - `3`\n */\nfunction resolveCaseConcurrency(\n taskCase: RegisteredCase<unknown>,\n taskConcurrency: TaskConcurrencyConfig | undefined,\n runtimeConcurrency: TaskConcurrencyConfig | undefined,\n): number | undefined {\n const concurrency = runtimeConcurrency?.case ?? taskCase.concurrency ?? taskConcurrency?.case\n if (concurrency == null) {\n return undefined\n }\n\n if (!Number.isFinite(concurrency) || !Number.isInteger(concurrency) || concurrency <= 0) {\n throw new Error(`Invalid task case concurrency: ${String(concurrency)}`)\n }\n\n return concurrency\n}\n\nfunction resolveCaseQueueKey(taskCase: RegisteredCase<unknown>, defaultQueueKey: object): object {\n return taskCase.queueKey ?? defaultQueueKey\n}\n\n/**\n * Defines one eval task with task/case semantics similar to Vitest.\n *\n * Use when:\n * - task behavior should be declared with `caseOf` and `casesFromInputs`\n * - business agent code should be imported and run from eval task files\n */\nexport function describeTask(\n name: string,\n build: ((builder: DescribeTaskBuilder) => void) | (() => void),\n options: DescribeTaskOptions = {},\n) {\n const registeredCases: RegisteredCase<unknown>[] = []\n const builder = createCaseBuilder(registeredCases)\n withActiveCases(registeredCases, () => {\n if (build.length > 0) {\n (build as (builder: DescribeTaskBuilder) => void)(builder)\n return\n }\n\n ;(build as () => void)()\n })\n\n const description = options.description ?? name\n const taskExecutionPolicy = normalizeExecutionPolicy(options, 'describeTask')\n\n const definition = defineEval({\n description,\n name,\n task: defineTask({\n concurrency: options.concurrency,\n executionPolicy: taskExecutionPolicy,\n id: name,\n async run(context): Promise<TaskRunOutput> {\n if (registeredCases.length === 0) {\n return {\n scores: [{ kind: 'exact', score: 1 }],\n }\n }\n\n const totalCases = registeredCases.length\n const scoreBucketsByKind: Record<RunScoreKind, number[]> = {\n exact: [],\n judge: [],\n }\n const defaultCaseQueueKey = {}\n const caseQueues = new Map<object, ReturnType<typeof createSchedulerQueue>>()\n const hasAutoAttempt = registeredCases.some(taskCase => resolveCaseExecutionPolicy(taskCase, taskExecutionPolicy).autoAttempt > 0)\n const runtimeTaskConcurrency = context.task.entry.task?.concurrency ?? options.concurrency\n\n if (!hasAutoAttempt) {\n await Promise.all(\n registeredCases.map(async (taskCase, index) => {\n const executeCase = async () => {\n const outcome = await executeRegisteredCase(context, taskCase, index, totalCases, taskExecutionPolicy)\n emitCaseEnd(context.reporterHooks, {\n ...(outcome.errorMessage == null ? {} : { errorMessage: outcome.errorMessage }),\n index,\n ...(outcome.output === undefined ? {} : { output: outcome.output }),\n state: outcome.state,\n name: taskCase.name,\n total: totalCases,\n })\n collectCaseOutcomeScores(outcome, scoreBucketsByKind)\n }\n\n const concurrency = resolveCaseConcurrency(taskCase, runtimeTaskConcurrency, context.runtimeConcurrency)\n if (concurrency == null) {\n await executeCase()\n return\n }\n\n const queueKey = resolveCaseQueueKey(taskCase, defaultCaseQueueKey)\n const queue = caseQueues.get(queueKey) ?? createSchedulerQueue(concurrency)\n caseQueues.set(queueKey, queue)\n await queue.run(executeCase)\n }),\n )\n }\n else {\n let finalOutcomes: CaseExecutionOutcome[] = []\n let attemptIndex = 0\n\n for (;;) {\n finalOutcomes = await Promise.all(\n registeredCases.map(async (taskCase, index) => {\n const executeCase = async () => await executeRegisteredCase(context, taskCase, index, totalCases, taskExecutionPolicy)\n const concurrency = resolveCaseConcurrency(taskCase, runtimeTaskConcurrency, context.runtimeConcurrency)\n if (concurrency == null) {\n return await executeCase()\n }\n\n const queueKey = resolveCaseQueueKey(taskCase, defaultCaseQueueKey)\n const queue = caseQueues.get(queueKey) ?? createSchedulerQueue(concurrency)\n caseQueues.set(queueKey, queue)\n return await queue.run(executeCase)\n }),\n )\n\n const shouldContinue = finalOutcomes.some((outcome, index) => {\n if (outcome.state === 'passed') {\n return false\n }\n\n const taskCase = registeredCases[index]\n if (taskCase == null) {\n return false\n }\n\n return attemptIndex < resolveCaseExecutionPolicy(taskCase, taskExecutionPolicy).autoAttempt\n })\n\n if (!shouldContinue) {\n break\n }\n\n attemptIndex += 1\n }\n\n finalOutcomes.forEach((outcome, index) => {\n const taskCase = registeredCases[index]\n if (taskCase == null) {\n return\n }\n\n emitCaseEnd(context.reporterHooks, {\n ...(outcome.errorMessage == null ? {} : { errorMessage: outcome.errorMessage }),\n index,\n ...(outcome.output === undefined ? {} : { output: outcome.output }),\n state: outcome.state,\n name: taskCase.name,\n total: totalCases,\n })\n collectCaseOutcomeScores(outcome, scoreBucketsByKind)\n })\n }\n\n const scores = (Object.keys(scoreBucketsByKind) as RunScoreKind[])\n .filter(kind => scoreBucketsByKind[kind].length > 0)\n .map((kind) => {\n const values = scoreBucketsByKind[kind]\n const total = values.reduce((sum, value) => sum + value, 0)\n return {\n kind,\n score: total / values.length,\n }\n })\n\n return {\n scores,\n }\n },\n }),\n })\n\n registerEvalDefinition(definition)\n\n return definition\n}\n\n/**\n * Alias of `describeTask` for eval-centric naming.\n */\nexport const describeEval = describeTask\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/dsl/task.ts"],"sourcesContent":["import type { TaskConcurrencyConfig, TaskExecutionPolicy, TaskReporterEventPayload, TaskRunContext, TaskRunOutput } from '../config'\nimport type { RunScoreKind } from '../core/runner'\nimport type { TelemetryAttributeValue } from '../core/telemetry'\n\nimport { errorMessageFrom, sleep } from '@moeru/std'\n\nimport { defineEval, defineTask } from '../config'\nimport { createSchedulerQueue } from '../core/scheduler/queue'\nimport { createNoopTelemetryRuntime } from '../core/telemetry'\nimport { registerEvalDefinition } from './registry'\n\n/**\n * Runtime context provided to a task case callback.\n */\nexport interface CaseRunContext<TInput> extends TaskRunContext {\n /**\n * Case-scoped matrix payload.\n */\n matrix: TaskRunContext['task']['matrix'] & { inputs: TInput }\n /**\n * Overrides one case score family with a custom normalized value.\n *\n * Use when:\n * - one case computes a benchmark-native score that should flow into run aggregation\n *\n * Expects:\n * - `score` to stay in the `0..1` range\n */\n score: (score: number, kind?: RunScoreKind) => void\n /**\n * Emits one custom case metric into report events.\n *\n * Use when:\n * - tasks need structured benchmark metadata beyond exact/judge score families\n *\n * Expects:\n * - `name` to be a stable metric identifier\n * - `value` to be JSON-serializable\n */\n metric: (name: string, value: TelemetryAttributeValue) => void\n /**\n * Cooperative abort signal for the current case execution.\n */\n signal: AbortSignal\n}\n\n/**\n * Callback for one task case.\n */\nexport type CaseRunner<TInput> = (context: CaseRunContext<TInput>) => Promise<unknown> | unknown\n\ninterface RegisteredCase<TInput> {\n concurrency?: number\n executionPolicy?: TaskExecutionPolicy\n input: TInput\n name: string\n queueKey?: object\n run: CaseRunner<TInput>\n}\n\n/**\n * Per-group options for `casesFromInputs`.\n *\n * Use when:\n * - one generated case group should run with a lower case concurrency than the task default\n * - a task should keep a broader task-level cap while one expensive case family stays bounded\n *\n * Expects:\n * - `concurrency` to be a positive integer when provided\n *\n * Returns:\n * - one partial case-group execution descriptor\n */\nexport interface CasesFromInputsOptions extends TaskExecutionPolicy {\n /**\n * Case-level concurrency cap for cases registered by one `casesFromInputs(...)` call.\n */\n concurrency?: number\n}\n\n/**\n * Per-case registration options for `caseOf`.\n */\nexport interface CaseRegistrationOptions<TInput> extends TaskExecutionPolicy {\n /**\n * Optional case input payload.\n */\n input: TInput\n}\n\ninterface CaseExecutionOutcome {\n errorMessage?: string\n output?: unknown\n scoresByKind: Map<RunScoreKind, number>\n state: 'failed' | 'passed' | 'timeout'\n}\n\nfunction cloneCaseMatrix(matrix: TaskRunContext['task']['matrix']): TaskRunContext['task']['matrix'] {\n return {\n eval: {\n ...matrix.eval,\n },\n meta: {\n ...matrix.meta,\n },\n run: {\n ...matrix.run,\n },\n }\n}\n\nfunction createTaskCaseReporterId(index: number, name: string): string {\n return `${index}:${encodeURIComponent(name)}`\n}\n\nfunction isTelemetryAttributeScalar(value: unknown): value is boolean | number | string {\n return typeof value === 'boolean' || typeof value === 'number' || typeof value === 'string'\n}\n\nfunction isTelemetryAttributeArray(value: readonly TelemetryAttributeValue[]): value is readonly boolean[] | readonly number[] | readonly string[] {\n return value.every(isTelemetryAttributeScalar)\n}\n\nfunction canAttachMetricAsAttribute(value: TelemetryAttributeValue): value is boolean | number | string | readonly boolean[] | readonly number[] | readonly string[] {\n if (isTelemetryAttributeScalar(value)) {\n return true\n }\n\n return Array.isArray(value) && isTelemetryAttributeArray(value)\n}\n\nfunction assertValidScore(score: number): void {\n if (!Number.isFinite(score) || score < 0 || score > 1) {\n throw new Error(`Case score must be a finite number in range 0..1, got \"${score}\".`)\n }\n}\n\nfunction assertNonNegativeInteger(value: number, label: string): void {\n if (!Number.isFinite(value) || !Number.isInteger(value) || value < 0) {\n throw new Error(`Invalid ${label}: ${String(value)}`)\n }\n}\n\nfunction assertNonNegativeNumber(value: number, label: string): void {\n if (!Number.isFinite(value) || value < 0) {\n throw new Error(`Invalid ${label}: ${String(value)}`)\n }\n}\n\nfunction assertPositiveInteger(value: number, label: string): void {\n if (!Number.isFinite(value) || !Number.isInteger(value) || value <= 0) {\n throw new Error(`Invalid ${label}: ${String(value)}`)\n }\n}\n\nfunction autoRetryDelayMs(retryIndex: number): number {\n // Retry index 1 is the first retry after the initial case failure.\n return 500 * 2 ** (retryIndex - 1)\n}\n\nfunction resolveAutoRetryDelay(policy: TaskExecutionPolicy, retryIndex: number): number {\n const delay = policy.autoRetryDelay\n\n if (delay == null) {\n return autoRetryDelayMs(retryIndex)\n }\n\n return typeof delay === 'number' ? delay : delay(retryIndex)\n}\n\nfunction emitCaseStart(\n hooks: TaskRunContext['reporterHooks'] | undefined,\n payload: {\n autoRetry?: number\n index: number\n input?: unknown\n name: string\n retryIndex?: number\n total: number\n },\n): void {\n try {\n hooks?.onCaseStart?.(payload)\n }\n catch {\n // Reporter hooks must never affect task scoring.\n }\n}\n\nfunction emitCaseEnd(\n hooks: TaskRunContext['reporterHooks'] | undefined,\n payload: {\n index: number\n output?: unknown\n state: 'passed' | 'failed' | 'timeout'\n name: string\n total: number\n errorMessage?: string\n },\n): void {\n try {\n hooks?.onCaseEnd?.(payload)\n }\n catch {\n // Reporter hooks must never affect task scoring.\n }\n}\n\nfunction emitReporterEvent(\n hooks: TaskRunContext['reporterHooks'] | undefined,\n payload: TaskReporterEventPayload,\n): void {\n try {\n hooks?.onEvent?.(payload)\n }\n catch {\n // Reporter hooks must never affect task scoring.\n }\n}\n\nfunction createCaseTimeoutError(timeout: number): Error {\n const error = new Error(`Case timed out after ${timeout}ms.`)\n error.name = 'TimeoutError'\n return error\n}\n\nfunction normalizeExecutionPolicy(policy: TaskExecutionPolicy | undefined, label: string): TaskExecutionPolicy | undefined {\n if (policy == null) {\n return undefined\n }\n\n if (policy.autoAttempt != null) {\n assertNonNegativeInteger(policy.autoAttempt, `${label} autoAttempt`)\n }\n\n if (policy.autoRetry != null) {\n assertNonNegativeInteger(policy.autoRetry, `${label} autoRetry`)\n }\n\n if (typeof policy.autoRetryDelay === 'number') {\n assertNonNegativeNumber(policy.autoRetryDelay, `${label} autoRetryDelay`)\n }\n\n if (policy.timeout != null) {\n assertPositiveInteger(policy.timeout, `${label} timeout`)\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 resolveCaseExecutionPolicy(\n taskCase: RegisteredCase<unknown>,\n taskExecutionPolicy: TaskExecutionPolicy | undefined,\n): Required<Pick<TaskExecutionPolicy, 'autoAttempt' | 'autoRetry'>> & Pick<TaskExecutionPolicy, 'autoRetryDelay' | 'timeout'> {\n return {\n autoAttempt: taskCase.executionPolicy?.autoAttempt ?? taskExecutionPolicy?.autoAttempt ?? 0,\n autoRetry: taskCase.executionPolicy?.autoRetry ?? taskExecutionPolicy?.autoRetry ?? 0,\n autoRetryDelay: taskCase.executionPolicy?.autoRetryDelay ?? taskExecutionPolicy?.autoRetryDelay,\n timeout: taskCase.executionPolicy?.timeout ?? taskExecutionPolicy?.timeout,\n }\n}\n\nasync function runCaseOnce(\n context: TaskRunContext,\n taskCase: RegisteredCase<unknown>,\n index: number,\n timeout: number | undefined,\n): Promise<CaseExecutionOutcome> {\n const customScoresByKind = new Map<RunScoreKind, number>()\n const abortController = new AbortController()\n const telemetry = context.telemetry ?? createNoopTelemetryRuntime()\n const caseId = createTaskCaseReporterId(index, taskCase.name)\n let timeoutHandle: ReturnType<typeof setTimeout> | undefined\n let timedOut = false\n let settled = false\n\n try {\n return await telemetry.withSpan('vieval.case', {\n 'vieval.case.id': caseId,\n 'vieval.case.name': taskCase.name,\n 'vieval.task.id': context.task.id,\n 'vieval.task.name': context.task.entry.name,\n }, async () => {\n const runPromise = Promise.resolve(taskCase.run({\n ...context,\n matrix: {\n ...cloneCaseMatrix(context.task.matrix),\n inputs: taskCase.input,\n },\n metric(name, value) {\n if (abortController.signal.aborted || settled) {\n return\n }\n\n emitReporterEvent(context.reporterHooks, {\n caseId,\n data: {\n name,\n value,\n },\n event: 'task.case.metric',\n })\n telemetry.addEvent('vieval.case.metric', { name, value })\n if (canAttachMetricAsAttribute(value)) {\n telemetry.setAttributes({ [name]: value })\n }\n },\n score(score, kind = 'exact') {\n if (abortController.signal.aborted || settled) {\n return\n }\n\n assertValidScore(score)\n customScoresByKind.set(kind, score)\n telemetry.addEvent('vieval.case.score', {\n 'vieval.score.kind': kind,\n 'vieval.score.value': score,\n })\n emitReporterEvent(context.reporterHooks, {\n caseId,\n data: { kind, score },\n event: 'task.case.score',\n })\n },\n signal: abortController.signal,\n }))\n\n if (timeout != null) {\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutHandle = setTimeout(() => {\n timedOut = true\n abortController.abort(createCaseTimeoutError(timeout))\n reject(createCaseTimeoutError(timeout))\n }, timeout)\n })\n\n const output = await Promise.race([runPromise, timeoutPromise])\n settled = true\n return {\n output,\n scoresByKind: customScoresByKind,\n state: 'passed',\n }\n }\n\n const output = await runPromise\n settled = true\n return {\n output,\n scoresByKind: customScoresByKind,\n state: 'passed',\n }\n })\n }\n catch (error) {\n settled = true\n return {\n errorMessage: errorMessageFrom(error) ?? (timedOut && timeout != null ? `Case timed out after ${timeout}ms.` : 'Unknown case failure.'),\n scoresByKind: customScoresByKind,\n state: timedOut ? 'timeout' : 'failed',\n }\n }\n finally {\n if (timeoutHandle != null) {\n clearTimeout(timeoutHandle)\n }\n }\n}\n\nasync function executeRegisteredCase(\n context: TaskRunContext,\n taskCase: RegisteredCase<unknown>,\n index: number,\n totalCases: number,\n taskExecutionPolicy: TaskExecutionPolicy | undefined,\n): Promise<CaseExecutionOutcome> {\n const resolvedPolicy = resolveCaseExecutionPolicy(taskCase, taskExecutionPolicy)\n let lastOutcome: CaseExecutionOutcome | undefined\n\n for (let retryIndex = 0; retryIndex <= resolvedPolicy.autoRetry; retryIndex += 1) {\n if (retryIndex > 0) {\n const retryDelayMs = resolveAutoRetryDelay(resolvedPolicy, retryIndex)\n assertNonNegativeNumber(retryDelayMs, 'autoRetryDelay result')\n\n if (retryDelayMs > 0) {\n await sleep(retryDelayMs)\n }\n }\n\n emitCaseStart(context.reporterHooks, {\n ...(resolvedPolicy.autoRetry > 0\n ? {\n autoRetry: resolvedPolicy.autoRetry,\n retryIndex,\n }\n : {}),\n index,\n ...(taskCase.input === undefined ? {} : { input: taskCase.input }),\n name: taskCase.name,\n total: totalCases,\n })\n lastOutcome = await runCaseOnce(context, taskCase, index, resolvedPolicy.timeout)\n if (lastOutcome.state === 'passed') {\n return lastOutcome\n }\n }\n\n return lastOutcome ?? {\n errorMessage: 'Unknown case failure.',\n scoresByKind: new Map(),\n state: 'failed',\n }\n}\n\nfunction collectCaseOutcomeScores(\n outcome: CaseExecutionOutcome,\n scoreBucketsByKind: Record<RunScoreKind, number[]>,\n): void {\n if (outcome.state !== 'passed') {\n scoreBucketsByKind.exact.push(0)\n return\n }\n\n if (outcome.scoresByKind.size === 0) {\n scoreBucketsByKind.exact.push(1)\n return\n }\n\n scoreBucketsByKind.exact.push(outcome.scoresByKind.get('exact') ?? 1)\n const judgeScore = outcome.scoresByKind.get('judge')\n if (judgeScore != null) {\n scoreBucketsByKind.judge.push(judgeScore)\n }\n}\n\nfunction emitCaseOutcome(\n context: TaskRunContext,\n taskCase: RegisteredCase<unknown>,\n outcome: CaseExecutionOutcome,\n index: number,\n totalCases: number,\n): void {\n emitCaseEnd(context.reporterHooks, {\n ...(outcome.errorMessage == null ? {} : { errorMessage: outcome.errorMessage }),\n index,\n ...(outcome.output === undefined ? {} : { output: outcome.output }),\n state: outcome.state,\n name: taskCase.name,\n total: totalCases,\n })\n}\n\n/**\n * Builder callbacks passed into `describeTask`.\n */\nexport interface DescribeTaskBuilder {\n /**\n * Registers one explicit case.\n */\n caseOf: {\n (name: string, run: CaseRunner<undefined>): void\n <TInput>(name: string, run: CaseRunner<TInput>, options: CaseRegistrationOptions<TInput>): void\n }\n /**\n * Registers multiple cases from input list.\n */\n casesFromInputs: <TInput>(\n namePrefix: string,\n inputs: readonly TInput[],\n run: CaseRunner<TInput>,\n options?: CasesFromInputsOptions,\n ) => void\n}\n\n/**\n * Options for `describeTask`.\n */\nexport interface DescribeTaskOptions extends TaskExecutionPolicy {\n /**\n * Optional description override.\n */\n description?: string\n /**\n * Optional task-local concurrency overrides.\n *\n * Use when:\n * - one task should cap attempt fan-out independently from the surrounding project\n * - one task should cap case fan-out without changing global scheduling defaults\n *\n * Expects:\n * - each provided value to be a positive integer\n *\n * @default inherited from project or CLI concurrency settings\n */\n concurrency?: TaskConcurrencyConfig\n}\n\nfunction createCaseBuilder(registeredCases: RegisteredCase<unknown>[]): DescribeTaskBuilder {\n function registerCase(name: string, run: CaseRunner<undefined>): void\n function registerCase<TInput>(name: string, run: CaseRunner<TInput>, options: CaseRegistrationOptions<TInput>): void\n function registerCase<TInput>(\n name: string,\n run: CaseRunner<TInput> | CaseRunner<undefined>,\n options?: CaseRegistrationOptions<TInput>,\n ): void {\n registeredCases.push({\n executionPolicy: normalizeExecutionPolicy(options, 'task case'),\n input: options?.input,\n name,\n run: run as CaseRunner<unknown>,\n })\n }\n\n return {\n caseOf: registerCase,\n casesFromInputs(namePrefix, inputs, run, options) {\n const queueKey = options?.concurrency == null ? undefined : {}\n\n inputs.forEach((input, index) => {\n registeredCases.push({\n concurrency: options?.concurrency,\n executionPolicy: normalizeExecutionPolicy(options, 'casesFromInputs'),\n input,\n name: `${namePrefix} #${index + 1}`,\n queueKey,\n run: run as CaseRunner<unknown>,\n })\n })\n },\n }\n}\n\nlet activeCasesStack: RegisteredCase<unknown>[][] = []\n\nfunction withActiveCases<T>(cases: RegisteredCase<unknown>[], callback: () => T): T {\n activeCasesStack = [...activeCasesStack, cases]\n\n try {\n return callback()\n }\n finally {\n activeCasesStack = activeCasesStack.slice(0, -1)\n }\n}\n\nfunction getActiveCases(): RegisteredCase<unknown>[] {\n const active = activeCasesStack.at(-1)\n if (active == null) {\n throw new Error('caseOf/casesFromInputs must be called inside describeTask/describeEval.')\n }\n\n return active\n}\n\n/**\n * Registers one case in the currently active task scope.\n */\nexport function caseOf(\n name: string,\n run: CaseRunner<undefined>,\n): void\n\nexport function caseOf<TInput>(\n name: string,\n run: CaseRunner<TInput>,\n options: CaseRegistrationOptions<TInput>,\n): void\n\nexport function caseOf<TInput>(\n name: string,\n run: CaseRunner<TInput> | CaseRunner<undefined>,\n options?: CaseRegistrationOptions<TInput>,\n): void {\n getActiveCases().push({\n executionPolicy: normalizeExecutionPolicy(options, 'task case'),\n input: options?.input,\n name,\n run: run as CaseRunner<unknown>,\n })\n}\n\n/**\n * Registers multiple cases in the currently active task scope.\n */\nexport function casesFromInputs<TInput>(\n namePrefix: string,\n inputs: readonly TInput[],\n run: CaseRunner<TInput>,\n options?: CasesFromInputsOptions,\n): void {\n const queueKey = options?.concurrency == null ? undefined : {}\n\n inputs.forEach((input, index) => {\n getActiveCases().push({\n concurrency: options?.concurrency,\n executionPolicy: normalizeExecutionPolicy(options, 'casesFromInputs'),\n input,\n name: `${namePrefix} #${index + 1}`,\n queueKey,\n run: run as CaseRunner<unknown>,\n })\n })\n}\n\n/**\n * Resolves the effective case concurrency for one registered task case.\n *\n * Before:\n * - registered case override `2`, task default `4`\n * - registered case override `undefined`, task default `3`\n *\n * After:\n * - `2`\n * - `3`\n */\nfunction resolveCaseConcurrency(\n taskCase: RegisteredCase<unknown>,\n taskConcurrency: TaskConcurrencyConfig | undefined,\n runtimeConcurrency: TaskConcurrencyConfig | undefined,\n): number | undefined {\n const concurrency = runtimeConcurrency?.case ?? taskCase.concurrency ?? taskConcurrency?.case\n if (concurrency == null) {\n return undefined\n }\n\n if (!Number.isFinite(concurrency) || !Number.isInteger(concurrency) || concurrency <= 0) {\n throw new Error(`Invalid task case concurrency: ${String(concurrency)}`)\n }\n\n return concurrency\n}\n\nfunction resolveCaseQueueKey(taskCase: RegisteredCase<unknown>, defaultQueueKey: object): object {\n return taskCase.queueKey ?? defaultQueueKey\n}\n\n/**\n * Defines one eval task with task/case semantics similar to Vitest.\n *\n * Use when:\n * - task behavior should be declared with `caseOf` and `casesFromInputs`\n * - business agent code should be imported and run from eval task files\n */\nexport function describeTask(\n name: string,\n build: ((builder: DescribeTaskBuilder) => void) | (() => void),\n options: DescribeTaskOptions = {},\n) {\n const registeredCases: RegisteredCase<unknown>[] = []\n const builder = createCaseBuilder(registeredCases)\n withActiveCases(registeredCases, () => {\n if (build.length > 0) {\n (build as (builder: DescribeTaskBuilder) => void)(builder)\n return\n }\n\n ;(build as () => void)()\n })\n\n const description = options.description ?? name\n const taskExecutionPolicy = normalizeExecutionPolicy(options, 'describeTask')\n\n const definition = defineEval({\n description,\n name,\n task: defineTask({\n concurrency: options.concurrency,\n executionPolicy: taskExecutionPolicy,\n id: name,\n async run(context): Promise<TaskRunOutput> {\n if (registeredCases.length === 0) {\n return {\n scores: [{ kind: 'exact', score: 1 }],\n }\n }\n\n const totalCases = registeredCases.length\n const scoreBucketsByKind: Record<RunScoreKind, number[]> = {\n exact: [],\n judge: [],\n }\n const defaultCaseQueueKey = {}\n const caseQueues = new Map<object, ReturnType<typeof createSchedulerQueue>>()\n const hasAutoAttempt = registeredCases.some(taskCase => resolveCaseExecutionPolicy(taskCase, taskExecutionPolicy).autoAttempt > 0)\n const runtimeTaskConcurrency = context.task.entry.task?.concurrency ?? options.concurrency\n\n if (!hasAutoAttempt) {\n await Promise.all(\n registeredCases.map(async (taskCase, index) => {\n const executeCase = async () => {\n const outcome = await executeRegisteredCase(context, taskCase, index, totalCases, taskExecutionPolicy)\n emitCaseOutcome(context, taskCase, outcome, index, totalCases)\n collectCaseOutcomeScores(outcome, scoreBucketsByKind)\n }\n\n const concurrency = resolveCaseConcurrency(taskCase, runtimeTaskConcurrency, context.runtimeConcurrency)\n if (concurrency == null) {\n await executeCase()\n return\n }\n\n const queueKey = resolveCaseQueueKey(taskCase, defaultCaseQueueKey)\n const queue = caseQueues.get(queueKey) ?? createSchedulerQueue(concurrency)\n caseQueues.set(queueKey, queue)\n await queue.run(executeCase)\n }),\n )\n }\n else {\n let attemptIndex = 0\n\n for (;;) {\n const attemptOutcomes = await Promise.all(\n registeredCases.map(async (taskCase, index) => {\n const executeCase = async () => await executeRegisteredCase(context, taskCase, index, totalCases, taskExecutionPolicy)\n const concurrency = resolveCaseConcurrency(taskCase, runtimeTaskConcurrency, context.runtimeConcurrency)\n if (concurrency == null) {\n return await executeCase()\n }\n\n const queueKey = resolveCaseQueueKey(taskCase, defaultCaseQueueKey)\n const queue = caseQueues.get(queueKey) ?? createSchedulerQueue(concurrency)\n caseQueues.set(queueKey, queue)\n return await queue.run(executeCase)\n }),\n )\n\n attemptOutcomes.forEach((outcome, index) => {\n const taskCase = registeredCases[index]\n if (taskCase == null) {\n return\n }\n\n emitCaseOutcome(context, taskCase, outcome, index, totalCases)\n collectCaseOutcomeScores(outcome, scoreBucketsByKind)\n })\n\n const shouldContinue = attemptOutcomes.some((outcome, index) => {\n if (outcome.state === 'passed') {\n return false\n }\n\n const taskCase = registeredCases[index]\n if (taskCase == null) {\n return false\n }\n\n return attemptIndex < resolveCaseExecutionPolicy(taskCase, taskExecutionPolicy).autoAttempt\n })\n\n if (!shouldContinue) {\n break\n }\n\n attemptIndex += 1\n }\n }\n\n const scores = (Object.keys(scoreBucketsByKind) as RunScoreKind[])\n .filter(kind => scoreBucketsByKind[kind].length > 0)\n .map((kind) => {\n const values = scoreBucketsByKind[kind]\n const total = values.reduce((sum, value) => sum + value, 0)\n return {\n kind,\n score: total / values.length,\n }\n })\n\n return {\n scores,\n }\n },\n }),\n })\n\n registerEvalDefinition(definition)\n\n return definition\n}\n\n/**\n * Alias of `describeTask` for eval-centric naming.\n */\nexport const describeEval = describeTask\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"models-
|
|
1
|
+
{"version":3,"file":"models-CaCOUPZw.mjs","names":[],"sources":["../src/config/models.ts"],"sourcesContent":["import type { TaskExecutionPolicy } from './types'\n\n/**\n * Canonical model definition consumed by vieval runtime and config.\n *\n * Use when:\n * - declaring models in `vieval.config.*`\n * - resolving task runtime models by id, alias, or concrete model name\n *\n * Expects:\n * - `id` to be stable and unique within one config\n * - `inferenceExecutorId` to match scheduler/executor identifiers\n *\n * Returns:\n * - one normalized model registration record\n */\nexport interface ModelDefinition {\n /**\n * Stable model id.\n */\n id: string\n /**\n * Inference-executor id used for matching and reporting.\n */\n inferenceExecutorId: string\n /**\n * Executor reference passed through config.\n *\n * `vieval` core treats this as opaque runtime metadata. Builder plugins can\n * narrow this field with plugin-specific executor input types.\n */\n inferenceExecutor: unknown\n /**\n * Concrete model name passed to the inference executor.\n */\n model: string\n /**\n * Alias names that can resolve this model.\n */\n aliases: string[]\n /**\n * Optional execution policy hints attached to this model.\n */\n executionPolicy?: TaskExecutionPolicy\n /**\n * Optional model-level call parameters.\n */\n parameters?: Record<string, unknown>\n}\n\n/**\n * Resolves one model by id, model name, or alias in registration order.\n *\n * Returns:\n * - the first matching model, or `undefined` when no match exists\n */\nexport function resolveModelByName(\n models: readonly ModelDefinition[],\n name: string,\n): ModelDefinition | undefined {\n return models.find(model => model.id === name || model.model === name || model.aliases.includes(name))\n}\n"],"mappings":";;;;;;;AAwDA,SAAgB,mBACd,QACA,MAC6B;CAC7B,OAAO,OAAO,MAAK,UAAS,MAAM,OAAO,QAAQ,MAAM,UAAU,QAAQ,MAAM,QAAQ,SAAS,IAAI,CAAC;AACvG"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { D as TaskRunContext, R as ModelDefinition, f as MatrixDefinition, t as ConfigHookPlugin, w as TaskExecutionPolicy } from "../../index-
|
|
1
|
+
import { D as TaskRunContext, R as ModelDefinition, f as MatrixDefinition, t as ConfigHookPlugin, w as TaskExecutionPolicy } from "../../index-CwKBlCG9.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/plugins/chat-models/runtime-config.d.ts
|
|
4
4
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { n as requiredEnvFrom, t as envFrom } from "../../env-
|
|
2
|
-
import { t as resolveModelByName } from "../../models-
|
|
1
|
+
import { n as requiredEnvFrom, t as envFrom } from "../../env-BVYeJhGA.mjs";
|
|
2
|
+
import { t as resolveModelByName } from "../../models-CaCOUPZw.mjs";
|
|
3
3
|
import process from "node:process";
|
|
4
4
|
import { errorMessageFrom } from "@moeru/std";
|
|
5
5
|
//#region src/plugins/chat-models/runtime-config.ts
|