@alis-build/harness-eval 0.1.0
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/LICENSE +201 -0
- package/README.md +700 -0
- package/dist/adapters/claude-code/index.d.ts +3 -0
- package/dist/adapters/claude-code/index.js +2 -0
- package/dist/build-DsVJ_UeU.js +1396 -0
- package/dist/build-DsVJ_UeU.js.map +1 -0
- package/dist/cardinality-DlE44e-4.js +31 -0
- package/dist/cardinality-DlE44e-4.js.map +1 -0
- package/dist/claude-code-ycT0JQZF.js +563 -0
- package/dist/claude-code-ycT0JQZF.js.map +1 -0
- package/dist/cli/bin.d.ts +1 -0
- package/dist/cli/bin.js +623 -0
- package/dist/cli/bin.js.map +1 -0
- package/dist/config/loader.d.ts +2 -0
- package/dist/config/loader.js +2 -0
- package/dist/index-6Z17eKZx.d.ts +72 -0
- package/dist/index.d.ts +725 -0
- package/dist/index.js +5 -0
- package/dist/loader-BCnFJ8rm.js +717 -0
- package/dist/loader-BCnFJ8rm.js.map +1 -0
- package/dist/loader-DTvoVfN0.d.ts +33 -0
- package/dist/rolldown-runtime-D7D4PA-g.js +13 -0
- package/dist/runner/suite.d.ts +2 -0
- package/dist/runner/suite.js +2 -0
- package/dist/suite-BoOvK_lq.d.ts +7 -0
- package/dist/suite-chj0j22j.js +684 -0
- package/dist/suite-chj0j22j.js.map +1 -0
- package/dist/types-B9H4IZtA.d.ts +305 -0
- package/dist/types-BQol062t.d.ts +292 -0
- package/package.json +74 -0
- package/schemas/eval-interchange-agent-trace.schema.json +322 -0
- package/schemas/eval-interchange-proto-instance.schema.json +106 -0
- package/schemas/eval-interchange.schema.json +140 -0
- package/schemas/eval-run-envelope.schema.json +2195 -0
- package/schemas/trajectory-view.schema.json +441 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-DsVJ_UeU.js","names":["parseYaml","formatJson","RESET","GREEN","RED","formatRate","normalizeToolCall"],"sources":["../src/types/eval-record.ts","../src/otel/attributes.ts","../src/otel/messages.ts","../src/otel/types.ts","../src/otel/emitter.ts","../src/grader/prompt.ts","../src/grader/parse.ts","../src/grader/claude-grader.ts","../src/grader/expectations.ts","../src/grader/transcript.ts","../src/grader/grade-report.ts","../src/grader/resolve-grade-options.ts","../src/grader/format-console.ts","../src/reporter/format-console.ts","../src/reporter/format-json.ts","../src/reporter/format-markdown.ts","../src/reporter/renderable.ts","../src/reporter/index.ts","../src/eval-interchange/build.ts","../src/metrics/trajectory.ts","../src/metrics/tool-calls.ts","../src/eval-interchange/projections.ts","../src/eval-record/build.ts"],"sourcesContent":["/**\n * Cross-harness eval record contract for storage, CI/CD, and external judges.\n *\n * Layering:\n * - {@link TrajectoryView} — canonical harness session (adapter output)\n * - {@link EvalRunEnvelope} — full run for DB / pipelines\n * - Optional artifacts — vendor-specific raw streams, OTLP traces\n *\n * @see docs/eval-record.md\n * @see schemas/eval-run-envelope.schema.json\n */\n\nimport type { AdapterDiagnostics } from \"../adapters/types\";\nimport type { GradedExpectation, GradingSummary } from \"../grader/types\";\nimport type {\n AgentTrace,\n InterchangeToolCall,\n TabularToolCall,\n ToolCallMetrics,\n TrajectoryMetrics,\n} from \"./eval-interchange\";\nimport type { AssertionResult } from \"./assertions\";\nimport type { TrajectoryView } from \"./trajectory\";\n\n/** Schema version for {@link EvalRunEnvelope} JSON documents. */\nexport const EVAL_RUN_SCHEMA_VERSION = \"1.0\";\n\n/** Schema version embedded in each {@link TrajectoryView} at export time. */\nexport const TRAJECTORY_SCHEMA_VERSION = \"1.0\";\n\n/** Link to the suite spec that produced a run. */\nexport interface SuiteReference {\n /** Absolute or repo-relative path to the suite YAML. */\n uri?: string;\n /** Stable suite identifier when known (e.g. case bundle name). */\n id?: string;\n /** SHA-256 or similar hash of suite file contents. */\n contentHash?: string;\n}\n\n/** Harness that executed the run. */\nexport interface HarnessInfo {\n /** Adapter id from suite YAML, e.g. `claude-code`. */\n adapter: string;\n /** harness-eval package version when envelope was built. */\n frameworkVersion?: string;\n /** Optional harness binary version (e.g. `claude -v`). */\n harnessVersion?: string;\n}\n\n/** CI, git, or runtime provenance for correlation in the DB. */\nexport interface EvalProvenance {\n runId?: string;\n ci?: {\n provider?: string;\n jobId?: string;\n pipelineId?: string;\n url?: string;\n };\n git?: {\n commit?: string;\n branch?: string;\n repository?: string;\n };\n pluginVersion?: string;\n triggeredBy?: string;\n [key: string]: unknown;\n}\n\n/** Aggregate behavioral summary for the run. */\nexport interface EvalRunSummary {\n cellsTotal: number;\n cellsPassed: number;\n /** All cells passed behavioral assertion thresholds. */\n behavioralPass: boolean;\n /** All graded expectations passed (when outcome layer present). */\n outcomePass?: boolean;\n}\n\n/** Identity of the judge that produced outcome grades. */\nexport interface JudgeInfo {\n id: string;\n model?: string;\n version?: string;\n}\n\n/** Outcome grades for one repetition (built-in or external judge). */\nexport interface OutcomeGrades {\n judge: JudgeInfo;\n expectations: GradedExpectation[];\n summary: GradingSummary;\n evalFeedback?: {\n suggestions: Array<{ assertion?: string; reason: string }>;\n overall: string;\n };\n error?: string;\n}\n\n/** Score from an external eval framework (LangSmith, Braintrust, custom). */\nexport interface ExternalScore {\n source: string;\n metric: string;\n value: number | boolean | string;\n metadata?: Record<string, unknown>;\n}\n\n/** Optional large or vendor-specific blobs (store by reference in DB when possible). */\nexport interface EvalArtifacts {\n /** Claude Code `stream-json` lines — debug only, not cross-harness. */\n rawStreamEvents?: unknown[];\n /** URI to OTLP JSON (S3, GCS, etc.). */\n otlpTraceUri?: string;\n /** Text transcript for judges (`trajectoryToTranscript`). */\n transcript?: string;\n}\n\n/**\n * One harness invocation — the unit external judges and trajectory queries use.\n */\nexport interface EvalRepetition {\n repetitionIndex: number;\n durationMs: number;\n\n /** Normalized harness session. Required when the harness completed with a view. */\n trajectory?: TrajectoryView & { schemaVersion: string };\n\n diagnostics?: Partial<AdapterDiagnostics>;\n assertionResults: AssertionResult[];\n\n outcomeGrades?: OutcomeGrades;\n externalScores?: ExternalScore[];\n\n artifacts?: EvalArtifacts;\n\n /** Interchange-format predicted tool-call trajectory. */\n predicted_trajectory?: InterchangeToolCall[];\n\n /** Full multi-turn agent trace in interchange format. */\n agent_trace?: AgentTrace;\n\n /** Session latency in seconds (interchange field). */\n latency_in_seconds?: number;\n\n /** 1 when the harness run failed, 0 on success (interchange field). */\n failure?: 0 | 1;\n\n /** Trajectory-level metrics when reference_trajectory is provided. */\n trajectoryMetrics?: TrajectoryMetrics;\n\n /** Tool-call-level metrics when reference_trajectory is provided. */\n toolCallMetrics?: ToolCallMetrics;\n\n error?: {\n message: string;\n diagnostics?: Partial<AdapterDiagnostics>;\n };\n}\n\n/** Behavioral stats for one assertion across repetitions in a cell. */\nexport interface EvalAssertionStat {\n description: string;\n threshold: number;\n passedCount: number;\n evaluatedCount: number;\n passRate: number;\n meetsThreshold: boolean;\n}\n\n/** One (test case × matrix cell) result. */\nexport interface EvalCellResult {\n caseId: string;\n category?: string;\n notes?: string;\n prompt?: string;\n expectations?: string[];\n cellLabel: string;\n axes?: Record<string, string>;\n /** Reference tool-call trajectory for metric computation. */\n reference_trajectory?: TabularToolCall[];\n /** Human ratings keyed by metric name for judge calibration. */\n human_ratings?: Record<string, number>;\n assertionStats: EvalAssertionStat[];\n adapterErrors: number;\n /** Passed all behavioral assertion thresholds for this cell. */\n behavioralPass: boolean;\n /** Passed all outcome expectations when graded; omitted if not graded. */\n outcomePass?: boolean;\n repetitions: EvalRepetition[];\n}\n\n/**\n * Top-level document for CI/CD pipelines, APIs, and databases.\n *\n * This is the interchange format your storage layer should target — not\n * {@link import(\"./stream\").StreamEvent} or OTLP traces.\n */\nexport interface EvalRunEnvelope {\n schemaVersion: typeof EVAL_RUN_SCHEMA_VERSION;\n runId: string;\n startedAt: string;\n durationMs: number;\n suite?: SuiteReference;\n harness: HarnessInfo;\n provenance?: EvalProvenance;\n summary: EvalRunSummary;\n cells: EvalCellResult[];\n}\n\nexport interface BuildEvalRunEnvelopeOptions {\n /** UUID for this run; generated if omitted. */\n runId?: string;\n suite?: SuiteReference;\n harness?: Partial<HarnessInfo>;\n provenance?: EvalProvenance;\n /** Merge outcome grades from `gradeReport()` or compatible structure. */\n grading?: {\n gradedAt?: string;\n sourceReport?: string;\n results: Array<{\n caseId: string;\n cellLabel: string;\n repetitionIndex: number;\n expectations: GradedExpectation[];\n summary: GradingSummary;\n evalFeedback?: OutcomeGrades[\"evalFeedback\"];\n graderError?: string;\n durationMs?: number;\n }>;\n judge?: JudgeInfo;\n };\n /** Include transcript in each repetition's artifacts. Default true. */\n includeTranscript?: boolean;\n /** Include raw stream events when adapter provides them. Default false. */\n includeRawStreamEvents?: boolean;\n}\n","/**\n * Helpers for OTLP attribute values.\n */\n\nimport type { AnyValue, KeyValue } from \"./types\";\n\nexport function strAttr(key: string, value: string): KeyValue {\n return { key, value: { stringValue: value } };\n}\n\nexport function intAttr(key: string, value: number): KeyValue {\n return { key, value: { intValue: String(value) } };\n}\n\nexport function boolAttr(key: string, value: boolean): KeyValue {\n return { key, value: { boolValue: value } };\n}\n\nexport function jsonAttr(key: string, value: unknown): KeyValue {\n return { key, value: { stringValue: JSON.stringify(value) } };\n}\n\nexport function anyValue(value: unknown): AnyValue {\n if (value === null || value === undefined) {\n return { stringValue: \"\" };\n }\n if (typeof value === \"string\") {\n return { stringValue: value };\n }\n if (typeof value === \"boolean\") {\n return { boolValue: value };\n }\n if (typeof value === \"number\") {\n if (Number.isInteger(value)) {\n return { intValue: String(value) };\n }\n return { doubleValue: value };\n }\n return { stringValue: JSON.stringify(value) };\n}\n","/**\n * Build GenAI semconv message arrays from a TrajectoryView.\n */\n\nimport type { AssistantTurn, ToolCall, TrajectoryView } from \"../types/trajectory\";\n\nexport interface GenAiMessage {\n role: string;\n parts: GenAiPart[];\n finish_reason?: string;\n}\n\nexport type GenAiPart =\n | { type: \"text\"; content: string }\n | {\n type: \"tool_call\";\n id: string;\n name: string;\n arguments: unknown;\n }\n | {\n type: \"tool_call_response\";\n id: string;\n result: unknown;\n };\n\nexport function mapStopReason(reason: string | null): string | undefined {\n if (!reason) return undefined;\n switch (reason) {\n case \"end_turn\":\n return \"stop\";\n case \"tool_use\":\n return \"tool_calls\";\n case \"max_tokens\":\n return \"length\";\n case \"stop_sequence\":\n return \"stop\";\n default:\n return reason;\n }\n}\n\nexport function toolCallPart(call: ToolCall): GenAiPart {\n return {\n type: \"tool_call\",\n id: call.callId,\n name: call.name,\n arguments: call.args ?? {},\n };\n}\n\nexport function toolResponsePart(call: ToolCall): GenAiPart {\n return {\n type: \"tool_call_response\",\n id: call.callId,\n result: call.result,\n };\n}\n\nexport function assistantMessageFromTurn(turn: AssistantTurn): GenAiMessage {\n const parts: GenAiPart[] = [];\n if (turn.text) {\n parts.push({ type: \"text\", content: turn.text });\n }\n for (const call of turn.toolCalls) {\n parts.push(toolCallPart(call));\n }\n const finish = mapStopReason(turn.stopReason);\n return {\n role: \"assistant\",\n parts,\n ...(finish ? { finish_reason: finish } : {}),\n };\n}\n\nexport function toolResultsMessage(calls: ToolCall[]): GenAiMessage | null {\n const parts = calls\n .filter((c) => c.result !== null)\n .map((c) => toolResponsePart(c));\n if (parts.length === 0) return null;\n return { role: \"tool\", parts };\n}\n\n/**\n * Input history before the assistant turn at `turnIndex`.\n */\nexport function inputMessagesBeforeTurn(\n view: TrajectoryView,\n turnIndex: number,\n prompt?: string,\n): GenAiMessage[] {\n const messages: GenAiMessage[] = [];\n\n if (prompt) {\n messages.push({\n role: \"user\",\n parts: [{ type: \"text\", content: prompt }],\n });\n }\n\n for (let i = 0; i < turnIndex; i++) {\n const turn = view.turns[i];\n if (!turn) continue;\n messages.push(assistantMessageFromTurn(turn));\n const toolMsg = toolResultsMessage(turn.toolCalls);\n if (toolMsg) messages.push(toolMsg);\n }\n\n return messages;\n}\n\nexport function finalOutputMessages(view: TrajectoryView): GenAiMessage[] {\n if (view.turns.length === 0) {\n if (!view.finalResponse) return [];\n return [\n {\n role: \"assistant\",\n parts: [{ type: \"text\", content: view.finalResponse }],\n finish_reason: mapStopReason(view.finalStopReason),\n },\n ];\n }\n\n const last = view.turns[view.turns.length - 1];\n return [assistantMessageFromTurn(last)];\n}\n","/**\n * Minimal OTLP JSON types for trace export.\n *\n * Shapes follow OTLP/HTTP JSON Protobuf encoding (lowerCamelCase field names).\n * @see https://opentelemetry.io/docs/specs/otlp/\n */\n\nexport interface ExportTraceServiceRequest {\n resourceSpans: ResourceSpans[];\n}\n\nexport interface ResourceSpans {\n resource: Resource;\n scopeSpans: ScopeSpans[];\n}\n\nexport interface Resource {\n attributes: KeyValue[];\n}\n\nexport interface ScopeSpans {\n scope: InstrumentationScope;\n spans: Span[];\n}\n\nexport interface InstrumentationScope {\n name: string;\n version?: string;\n}\n\nexport interface Span {\n traceId: string;\n spanId: string;\n parentSpanId?: string;\n name: string;\n kind: number;\n startTimeUnixNano: string;\n endTimeUnixNano: string;\n attributes: KeyValue[];\n status?: SpanStatus;\n}\n\nexport interface SpanStatus {\n code: number;\n message?: string;\n}\n\nexport interface KeyValue {\n key: string;\n value: AnyValue;\n}\n\nexport interface AnyValue {\n stringValue?: string;\n boolValue?: boolean;\n intValue?: string;\n doubleValue?: number;\n bytesValue?: string;\n arrayValue?: ArrayValue;\n kvlistValue?: KeyValueList;\n}\n\nexport interface ArrayValue {\n values: AnyValue[];\n}\n\nexport interface KeyValueList {\n values: KeyValue[];\n}\n\n/** OTLP span kinds (enum integers). */\nexport const SpanKind = {\n INTERNAL: 1,\n CLIENT: 2,\n} as const;\n\n/** OTLP status codes. */\nexport const StatusCode = {\n UNSET: 0,\n OK: 1,\n ERROR: 2,\n} as const;\n\nexport interface EmitOtelOptions {\n /** User prompt for the first `gen_ai.input.messages` entry. */\n prompt?: string;\n /** `gen_ai.agent.name` on the root span. Default: `claude-code`. */\n agentName?: string;\n /** `gen_ai.provider.name`. Default: `anthropic`. */\n providerName?: string;\n /** Resource `service.name`. Default: `harness-eval`. */\n serviceName?: string;\n /** Instrumentation scope name. Default: `@alis-build/harness-eval`. */\n instrumentationScope?: string;\n /**\n * Wall-clock end time for the trace (ms). Defaults to `Date.now()`.\n * Start is derived from `view.usage.durationMs`.\n */\n endTimeMs?: number;\n}\n","/**\n * TrajectoryView → OTLP JSON export using OpenTelemetry GenAI semantic conventions.\n *\n * Produces an `ExportTraceServiceRequest` suitable for OTLP/HTTP JSON ingestion.\n * Assertions continue to use {@link TrajectoryView} directly; this is export-only.\n */\n\nimport { createHash } from \"node:crypto\";\n\nimport type { TrajectoryView } from \"../types/trajectory\";\nimport { boolAttr, intAttr, jsonAttr, strAttr } from \"./attributes\";\nimport {\n assistantMessageFromTurn,\n inputMessagesBeforeTurn,\n mapStopReason,\n} from \"./messages\";\nimport type {\n EmitOtelOptions,\n ExportTraceServiceRequest,\n Span,\n SpanStatus,\n} from \"./types\";\nimport { SpanKind, StatusCode } from \"./types\";\n\nconst INSTRUMENTATION_VERSION = \"0.1.0\";\n\ninterface SpanTiming {\n startNs: string;\n endNs: string;\n}\n\n/**\n * Map a {@link TrajectoryView} to OTLP trace JSON.\n *\n * Span tree (siblings under `invoke_agent`, not nested):\n * ```\n * invoke_agent\n * ├── chat {model}\n * ├── execute_tool {name}\n * ├── chat {model}\n * └── ...\n * ```\n */\nexport function trajectoryToOtlp(\n view: TrajectoryView,\n options: EmitOtelOptions = {},\n): ExportTraceServiceRequest {\n const agentName = options.agentName ?? \"claude-code\";\n const providerName = options.providerName ?? \"anthropic\";\n const serviceName = options.serviceName ?? \"harness-eval\";\n const scopeName =\n options.instrumentationScope ?? \"@alis-build/harness-eval\";\n\n const traceId = traceIdFromSession(view.meta.sessionId);\n const rootSpanId = spanIdFromKey(traceId, \"invoke_agent\");\n\n const durationMs = Math.max(view.usage.durationMs, 1);\n const endMs = options.endTimeMs ?? Date.now();\n const startMs = endMs - durationMs;\n const rootStartNs = msToNs(startMs);\n const rootEndNs = msToNs(endMs);\n\n const spans: Span[] = [];\n const timings = buildSpanTimings(view, startMs, endMs);\n\n spans.push({\n traceId,\n spanId: rootSpanId,\n name: \"invoke_agent\",\n kind: SpanKind.INTERNAL,\n startTimeUnixNano: rootStartNs,\n endTimeUnixNano: rootEndNs,\n attributes: [\n strAttr(\"gen_ai.operation.name\", \"invoke_agent\"),\n strAttr(\"gen_ai.agent.name\", agentName),\n strAttr(\"gen_ai.provider.name\", providerName),\n strAttr(\"gen_ai.conversation.id\", view.meta.sessionId),\n strAttr(\"gen_ai.request.model\", view.meta.model),\n strAttr(\"gen_ai.response.model\", view.meta.model),\n intAttr(\"gen_ai.usage.input_tokens\", view.usage.inputTokens),\n intAttr(\"gen_ai.usage.output_tokens\", view.usage.outputTokens),\n boolAttr(\"harness_eval.success\", view.success),\n ],\n status: viewStatus(view),\n });\n\n let opIndex = 0;\n for (const turn of view.turns) {\n const chatTiming = timings[opIndex++];\n const chatSpanId = spanIdFromKey(traceId, `chat:${turn.turnIndex}`);\n const inputMessages = inputMessagesBeforeTurn(\n view,\n turn.turnIndex,\n options.prompt,\n );\n const outputMessages = [assistantMessageFromTurn(turn)];\n\n spans.push({\n traceId,\n spanId: chatSpanId,\n parentSpanId: rootSpanId,\n name: `chat ${view.meta.model}`,\n kind: SpanKind.CLIENT,\n startTimeUnixNano: chatTiming.startNs,\n endTimeUnixNano: chatTiming.endNs,\n attributes: [\n strAttr(\"gen_ai.operation.name\", \"chat\"),\n strAttr(\"gen_ai.provider.name\", providerName),\n strAttr(\"gen_ai.request.model\", view.meta.model),\n strAttr(\"gen_ai.response.model\", view.meta.model),\n ...(inputMessages.length > 0\n ? [jsonAttr(\"gen_ai.input.messages\", inputMessages)]\n : []),\n jsonAttr(\"gen_ai.output.messages\", outputMessages),\n ...(turn.stopReason\n ? [\n jsonAttr(\"gen_ai.response.finish_reasons\", [\n mapStopReason(turn.stopReason) ?? turn.stopReason,\n ]),\n ]\n : []),\n ],\n status: { code: StatusCode.OK },\n });\n\n if (turn.toolCalls.length === 0) continue;\n\n const toolTiming = timings[opIndex++];\n for (const call of turn.toolCalls) {\n const toolSpanId = spanIdFromKey(\n traceId,\n `tool:${call.callId}`,\n );\n\n spans.push({\n traceId,\n spanId: toolSpanId,\n parentSpanId: rootSpanId,\n name: `execute_tool ${call.name}`,\n kind: SpanKind.INTERNAL,\n startTimeUnixNano: toolTiming.startNs,\n endTimeUnixNano: toolTiming.endNs,\n attributes: [\n strAttr(\"gen_ai.operation.name\", \"execute_tool\"),\n strAttr(\"gen_ai.provider.name\", providerName),\n strAttr(\"gen_ai.tool.name\", call.name),\n strAttr(\"gen_ai.tool.call.id\", call.callId),\n jsonAttr(\"gen_ai.tool.call.arguments\", call.args ?? {}),\n ...(call.result !== null\n ? [jsonAttr(\"gen_ai.tool.call.result\", call.result)]\n : []),\n ...(call.namespace\n ? [strAttr(\"harness_eval.tool.namespace\", call.namespace)]\n : []),\n boolAttr(\"harness_eval.tool.is_error\", call.isError),\n ],\n status: call.isError\n ? { code: StatusCode.ERROR, message: \"tool reported error\" }\n : { code: StatusCode.OK },\n });\n }\n }\n\n return {\n resourceSpans: [\n {\n resource: {\n attributes: [\n strAttr(\"service.name\", serviceName),\n strAttr(\"gen_ai.agent.name\", agentName),\n ],\n },\n scopeSpans: [\n {\n scope: {\n name: scopeName,\n version: INSTRUMENTATION_VERSION,\n },\n spans,\n },\n ],\n },\n ],\n };\n}\n\n/** Alias matching the implementation plan naming. */\nexport const emitOtel = trajectoryToOtlp;\n\nfunction viewStatus(view: TrajectoryView): SpanStatus {\n if (view.success) {\n return { code: StatusCode.OK };\n }\n return {\n code: StatusCode.ERROR,\n message: \"harness run did not complete successfully\",\n };\n}\n\nfunction buildSpanTimings(\n view: TrajectoryView,\n startMs: number,\n endMs: number,\n): SpanTiming[] {\n const slots: Array<\"chat\" | \"tools\"> = [];\n for (const turn of view.turns) {\n slots.push(\"chat\");\n if (turn.toolCalls.length > 0) slots.push(\"tools\");\n }\n\n if (slots.length === 0) {\n return [];\n }\n\n const totalMs = Math.max(endMs - startMs, 1);\n const slotMs = totalMs / slots.length;\n const timings: SpanTiming[] = [];\n let offset = startMs;\n\n for (const slot of slots) {\n const slotStart = offset;\n const slotEnd = offset + slotMs;\n timings.push({\n startNs: msToNs(slotStart),\n endNs: msToNs(slotEnd),\n });\n offset = slotEnd;\n }\n\n return timings;\n}\n\nexport function traceIdFromSession(sessionId: string): string {\n return createHash(\"sha256\")\n .update(`harness-eval:trace:${sessionId}`)\n .digest(\"hex\")\n .slice(0, 32)\n .toUpperCase();\n}\n\nexport function spanIdFromKey(traceId: string, key: string): string {\n return createHash(\"sha256\")\n .update(`${traceId}:span:${key}`)\n .digest(\"hex\")\n .slice(0, 16)\n .toUpperCase();\n}\n\nfunction msToNs(ms: number): string {\n return String(Math.round(ms * 1_000_000));\n}\n","/**\n * Build the grader prompt for Claude subprocess grading.\n */\n\nimport type { GraderInput } from \"./types\";\n\nexport function buildGraderPrompt(input: GraderInput): string {\n const expectationList = input.expectations\n .map((e, i) => `${i + 1}. ${e}`)\n .join(\"\\n\");\n\n const prefix = input.systemInstruction\n ? `${input.systemInstruction.trim()}\\n\\n`\n : \"\";\n\n return `${prefix}You are an automated evaluation grader (not the agent under test). Your only job is to score expectations against the transcript below.\n\nYour job is to evaluate each expectation against the transcript and final response.\nPASS only when there is clear evidence in the transcript or final response.\nWhen uncertain, FAIL — burden of proof is on PASS.\n\nAlso critique the expectations themselves if any are trivially satisfied or miss important outcomes.\n\n## Eval prompt\n\n${input.prompt}\n\n## Execution transcript\n\n${input.transcript}\n\n## Expectations to grade\n\n${expectationList}\n\n## Output format\n\nRespond with ONLY a single JSON object (no markdown fences, no commentary) matching this schema:\n\n{\n \"expectations\": [\n { \"text\": \"<original expectation>\", \"passed\": true|false, \"evidence\": \"<quote or description>\" }\n ],\n \"summary\": { \"passed\": <int>, \"failed\": <int>, \"total\": <int>, \"pass_rate\": <0.0-1.0> },\n \"eval_feedback\": {\n \"suggestions\": [{ \"assertion\": \"<optional>\", \"reason\": \"<string>\" }],\n \"overall\": \"<brief assessment>\"\n }\n}\n\nInclude every expectation in the same order. summary must match the expectations array.`;\n}\n","/**\n * Parse grader JSON from Claude stdout / response text.\n */\n\nimport type {\n EvalFeedback,\n GradedExpectation,\n GradingSummary,\n GraderOutput,\n} from \"./types\";\n\nexport function extractClaudeResponseText(stdout: string): string {\n const trimmed = stdout.trim();\n if (!trimmed) return \"\";\n\n try {\n const data = JSON.parse(trimmed) as unknown;\n\n if (Array.isArray(data)) {\n return extractFromEventArray(data) ?? trimmed;\n }\n\n if (typeof data === \"object\" && data !== null) {\n const event = data as { type?: string; result?: string; message?: unknown };\n if (event.type === \"result\" && typeof event.result === \"string\") {\n return event.result;\n }\n if (event.type === \"assistant\" && event.message) {\n const text = textFromAssistantMessage(event.message);\n if (text) return text;\n }\n }\n } catch {\n // fall through to raw stdout\n }\n\n return trimmed;\n}\n\nfunction extractFromEventArray(events: unknown[]): string | null {\n const result = events.find(\n (e) =>\n typeof e === \"object\" &&\n e !== null &&\n (e as { type?: string }).type === \"result\",\n ) as { result?: string } | undefined;\n if (result?.result) return result.result;\n\n const assistantTexts: string[] = [];\n for (const event of events) {\n if (\n typeof event === \"object\" &&\n event !== null &&\n (event as { type?: string }).type === \"assistant\"\n ) {\n const text = textFromAssistantMessage(\n (event as { message?: unknown }).message,\n );\n if (text) assistantTexts.push(text);\n }\n }\n if (assistantTexts.length > 0) {\n return assistantTexts[assistantTexts.length - 1];\n }\n return null;\n}\n\nfunction textFromAssistantMessage(message: unknown): string | null {\n if (!message || typeof message !== \"object\") return null;\n const content = (message as { content?: unknown }).content;\n if (typeof content === \"string\") return content;\n if (!Array.isArray(content)) return null;\n\n const texts: string[] = [];\n for (const block of content) {\n if (\n typeof block === \"object\" &&\n block !== null &&\n (block as { type?: string }).type === \"text\" &&\n typeof (block as { text?: string }).text === \"string\"\n ) {\n texts.push((block as { text: string }).text);\n }\n }\n return texts.length > 0 ? texts.join(\"\\n\") : null;\n}\n\nexport function parseGraderJson(text: string): GraderOutput | null {\n const candidates = [text.trim(), extractJsonBlock(text)];\n for (const candidate of candidates) {\n if (!candidate) continue;\n try {\n const raw = JSON.parse(candidate) as RawGraderJson;\n const normalized = normalizeGraderJson(raw);\n if (normalized.expectations.length > 0) {\n return normalized;\n }\n } catch {\n continue;\n }\n }\n return null;\n}\n\ninterface RawGraderJson {\n expectations?: Array<{\n text?: string;\n passed?: boolean;\n evidence?: string;\n }>;\n summary?: {\n passed?: number;\n failed?: number;\n total?: number;\n pass_rate?: number;\n passRate?: number;\n };\n eval_feedback?: {\n suggestions?: Array<{ assertion?: string; reason?: string }>;\n overall?: string;\n };\n}\n\nfunction extractJsonBlock(text: string): string | null {\n const fence = text.match(/```(?:json)?\\s*([\\s\\S]*?)```/);\n if (fence?.[1]) return fence[1].trim();\n\n const start = text.indexOf(\"{\");\n const end = text.lastIndexOf(\"}\");\n if (start >= 0 && end > start) {\n return text.slice(start, end + 1);\n }\n return null;\n}\n\nfunction normalizeGraderJson(raw: RawGraderJson): GraderOutput {\n const expectations: GradedExpectation[] = (raw.expectations ?? []).map(\n (e) => ({\n text: e.text ?? \"\",\n passed: Boolean(e.passed),\n evidence: e.evidence ?? \"\",\n }),\n );\n\n const passed = expectations.filter((e) => e.passed).length;\n const failed = expectations.length - passed;\n const total = expectations.length;\n const passRate =\n raw.summary?.pass_rate ??\n raw.summary?.passRate ??\n (total === 0 ? 0 : passed / total);\n\n const summary: GradingSummary = {\n passed: raw.summary?.passed ?? passed,\n failed: raw.summary?.failed ?? failed,\n total: raw.summary?.total ?? total,\n passRate,\n };\n\n let evalFeedback: EvalFeedback | undefined;\n if (raw.eval_feedback) {\n evalFeedback = {\n suggestions: (raw.eval_feedback.suggestions ?? []).map((s) => ({\n assertion: s.assertion,\n reason: s.reason ?? \"\",\n })),\n overall: raw.eval_feedback.overall ?? \"\",\n };\n }\n\n return { expectations, summary, evalFeedback };\n}\n","/**\n * Grade expectations by spawning Claude as judge (skill-creator grader pattern).\n */\n\nimport { spawn } from \"node:child_process\";\n\nimport { buildJudgeArgs } from \"../adapters/claude-code/flags\";\nimport type { ClaudeCodeOptions } from \"../adapters/claude-code/types\";\nimport { buildGraderPrompt } from \"./prompt\";\nimport { extractClaudeResponseText, parseGraderJson } from \"./parse\";\nimport type { GraderFn, GraderInput, GraderOutput } from \"./types\";\n\nconst DEFAULT_TIMEOUT_MS = 300_000;\n\n/**\n * Judge subprocess defaults — grading is a single-shot JSON response, not an agent session.\n * Without these, Claude Code may load plugins/MCP and loop on tools until timeout.\n */\nexport const JUDGE_CLAUDE_DEFAULTS: ClaudeCodeOptions = {\n maxTurns: 1,\n bare: true,\n disableSlashCommands: true,\n noSessionPersistence: true,\n};\n\nexport function mergeJudgeClaudeOptions(\n claudeCode?: ClaudeCodeOptions,\n): ClaudeCodeOptions {\n return { ...JUDGE_CLAUDE_DEFAULTS, ...claudeCode };\n}\n\nexport interface ClaudeGraderOptions {\n binary?: string;\n model?: string;\n timeoutMs?: number;\n env?: Record<string, string>;\n cwd?: string;\n claudeCode?: ClaudeCodeOptions;\n}\n\nexport function createClaudeGrader(\n options: ClaudeGraderOptions = {},\n): GraderFn {\n return (input) => runClaudeGrader(input, options);\n}\n\nexport async function runClaudeGrader(\n input: GraderInput,\n options: ClaudeGraderOptions = {},\n): Promise<GraderOutput> {\n const binary = options.binary ?? options.claudeCode?.binary ?? \"claude\";\n const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n const prompt = buildGraderPrompt(input);\n const model = options.model ?? options.claudeCode?.model;\n\n const args = buildJudgeArgs(prompt, {\n ...mergeJudgeClaudeOptions(options.claudeCode),\n model,\n });\n\n const stdout = await spawnCollectStdout(\n binary,\n args,\n timeoutMs,\n options.env,\n options.cwd,\n );\n const responseText = extractClaudeResponseText(stdout);\n const parsed = parseGraderJson(responseText);\n\n if (!parsed) {\n return {\n expectations: input.expectations.map((text) => ({\n text,\n passed: false,\n evidence: \"Grader returned unparseable output\",\n })),\n summary: {\n passed: 0,\n failed: input.expectations.length,\n total: input.expectations.length,\n passRate: 0,\n },\n error: `failed to parse grader JSON from response: ${responseText.slice(0, 200)}`,\n };\n }\n\n // Align expectation text with input order when grader omits text field\n const expectations = input.expectations.map((text, i) => {\n const graded = parsed.expectations[i];\n return {\n text,\n passed: graded?.passed ?? false,\n evidence: graded?.evidence ?? \"No evidence returned\",\n };\n });\n\n const passed = expectations.filter((e) => e.passed).length;\n const total = expectations.length;\n\n return {\n expectations,\n summary: {\n passed,\n failed: total - passed,\n total,\n passRate: total === 0 ? 0 : passed / total,\n },\n evalFeedback: parsed.evalFeedback,\n };\n}\n\nfunction spawnCollectStdout(\n binary: string,\n args: string[],\n timeoutMs: number,\n extraEnv?: Record<string, string>,\n cwd?: string,\n): Promise<string> {\n return new Promise((resolve, reject) => {\n const child = spawn(binary, args, {\n env: buildChildEnv(extraEnv),\n cwd,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n\n const chunks: string[] = [];\n child.stdout?.setEncoding(\"utf8\");\n child.stdout?.on(\"data\", (c: string) => chunks.push(c));\n\n const stderrChunks: string[] = [];\n child.stderr?.setEncoding(\"utf8\");\n child.stderr?.on(\"data\", (c: string) => stderrChunks.push(c));\n\n const timer = setTimeout(() => {\n child.kill(\"SIGTERM\");\n const stderrHint = stderrChunks.join(\"\").trim().slice(0, 400);\n reject(\n new Error(\n `grader timed out after ${timeoutMs}ms` +\n (stderrHint ? ` (stderr: ${stderrHint})` : \"\"),\n ),\n );\n }, timeoutMs);\n\n const finalize = (err?: Error) => {\n clearTimeout(timer);\n if (err) reject(err);\n else resolve(chunks.join(\"\"));\n };\n\n child.on(\"error\", (err) => finalize(err));\n child.on(\"close\", (code) => {\n if (code !== 0 && chunks.length === 0) {\n finalize(\n new Error(\n `grader exited ${code}: ${stderrChunks.join(\"\").slice(0, 500)}`,\n ),\n );\n } else {\n finalize();\n }\n });\n });\n}\n\nfunction buildChildEnv(extraEnv?: Record<string, string>): Record<string, string | undefined> {\n const env = { ...process.env, ...extraEnv };\n delete env.CLAUDECODE;\n return env;\n}\n","/**\n * Load expectations sidecar (YAML or JSON).\n */\n\nimport { readFile } from \"node:fs/promises\";\n\nimport { parse as parseYaml } from \"yaml\";\n\nimport type { ExpectationsMap } from \"./types\";\n\nexport async function loadExpectationsMap(path: string): Promise<ExpectationsMap> {\n const text = await readFile(path, \"utf8\");\n const trimmed = path.trim().toLowerCase();\n\n let raw: unknown;\n if (trimmed.endsWith(\".json\")) {\n raw = JSON.parse(text);\n } else {\n raw = parseYaml(text);\n }\n\n if (!raw || typeof raw !== \"object\") {\n throw new Error(`expectations file must be an object mapping case ids to lists`);\n }\n\n const map: ExpectationsMap = {};\n for (const [caseId, value] of Object.entries(raw as Record<string, unknown>)) {\n if (!Array.isArray(value)) {\n throw new Error(`expectations for case \"${caseId}\" must be an array of strings`);\n }\n map[caseId] = value.map(String);\n }\n return map;\n}\n","/**\n * TrajectoryView → markdown transcript for LLM graders.\n */\n\nimport type { TrajectoryView } from \"../types/trajectory\";\n\nconst MAX_RESULT_CHARS = 4000;\n\nexport function trajectoryToTranscript(\n view: TrajectoryView,\n prompt?: string,\n): string {\n const lines: string[] = [];\n\n if (prompt) {\n lines.push(\"## User prompt\", \"\", prompt, \"\");\n }\n\n for (const turn of view.turns) {\n lines.push(`## Assistant turn ${turn.turnIndex + 1}`, \"\");\n if (turn.text) {\n lines.push(turn.text, \"\");\n }\n for (const call of turn.toolCalls) {\n lines.push(`[Tool call] ${call.name} (id=${call.callId})`);\n lines.push(`Arguments: ${formatJson(call.args)}`);\n if (call.result !== null) {\n lines.push(`[Tool result] ${formatResult(call.result)}`);\n if (call.isError) lines.push(\"(tool reported error)\");\n } else {\n lines.push(\"[Tool result] (none observed)\");\n }\n lines.push(\"\");\n }\n if (turn.stopReason) {\n lines.push(`Stop reason: ${turn.stopReason}`, \"\");\n }\n }\n\n const finalInTurns = view.turns.some((t) => t.text === view.finalResponse);\n if (view.finalResponse && !finalInTurns) {\n lines.push(\"## Final response\", \"\", view.finalResponse, \"\");\n }\n\n lines.push(\n \"## Session metadata\",\n `session_id: ${view.meta.sessionId}`,\n `model: ${view.meta.model}`,\n `cwd: ${view.meta.cwd}`,\n `success: ${view.success}`,\n `tool_calls: ${view.toolCalls.length}`,\n `duration_ms: ${view.usage.durationMs}`,\n `input_tokens: ${view.usage.inputTokens}`,\n `output_tokens: ${view.usage.outputTokens}`,\n );\n\n return lines.join(\"\\n\").trimEnd();\n}\n\nfunction formatJson(value: unknown): string {\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n\nfunction formatResult(result: unknown): string {\n if (typeof result === \"string\") {\n return truncate(result);\n }\n return truncate(formatJson(result));\n}\n\nfunction truncate(text: string): string {\n if (text.length <= MAX_RESULT_CHARS) return text;\n return `${text.slice(0, MAX_RESULT_CHARS)}… (truncated)`;\n}\n","/**\n * Grade a harness-eval SuiteReport with outcome expectations (LLM judge).\n */\n\nimport { readFile } from \"node:fs/promises\";\n\nimport { createClaudeGrader, type ClaudeGraderOptions } from \"./claude-grader\";\nimport { loadExpectationsMap } from \"./expectations\";\nimport { trajectoryToTranscript } from \"./transcript\";\nimport type {\n GradeReportOptions,\n GraderFn,\n RepGradingResult,\n SuiteGradingReport,\n} from \"./types\";\nimport { createLimit } from \"../runner/limit\";\nimport type { CellReport, SuiteReport } from \"../runner/types\";\n\nexport async function gradeReport(\n report: SuiteReport,\n options: GradeReportOptions = {},\n): Promise<SuiteGradingReport> {\n const expectationsMap = options.expectationsPath\n ? await loadExpectationsMap(options.expectationsPath)\n : {};\n\n const gradeFn: GraderFn =\n options.gradeFn ??\n createClaudeGrader({\n binary: options.binary,\n model: options.model,\n timeoutMs: options.timeoutMs,\n env: options.env,\n cwd: options.cwd,\n claudeCode: options.claudeCode as ClaudeGraderOptions[\"claudeCode\"],\n });\n\n const maxConcurrent = options.maxConcurrent ?? 2;\n const limit = createLimit(maxConcurrent);\n\n const tasks: Array<{\n cell: CellReport;\n rep: CellReport[\"repetitions\"][number];\n expectations: string[];\n }> = [];\n\n for (const cell of report.cells) {\n const expectations =\n cell.expectations ??\n expectationsMap[cell.caseId] ??\n [];\n\n if (expectations.length === 0) continue;\n\n for (const rep of cell.repetitions) {\n if (!rep.adapterResult) continue;\n tasks.push({ cell, rep, expectations });\n }\n }\n\n const gradeStartTs = Date.now();\n options.onProgress?.({ kind: \"grade-start\", total: tasks.length });\n\n const results: RepGradingResult[] = await Promise.all(\n tasks.map(({ cell, rep, expectations }) =>\n limit(async () => {\n const start = Date.now();\n const view = rep.adapterResult!.view;\n const prompt = cell.prompt ?? \"\";\n const transcript = trajectoryToTranscript(view, prompt);\n\n try {\n const graded = await gradeFn({\n prompt,\n transcript,\n expectations,\n systemInstruction: options.systemInstruction,\n });\n\n const result: RepGradingResult = {\n caseId: cell.caseId,\n cellLabel: cell.cell.label,\n repetitionIndex: rep.repetitionIndex,\n prompt,\n expectations: graded.expectations,\n summary: graded.summary,\n evalFeedback: graded.evalFeedback,\n graderError: graded.error,\n durationMs: Date.now() - start,\n };\n\n options.onProgress?.({\n kind: \"grade-complete\",\n caseId: result.caseId,\n cellLabel: result.cellLabel,\n repetitionIndex: result.repetitionIndex,\n passed: result.summary.passed,\n failed: result.summary.failed,\n durationMs: result.durationMs,\n graderError: result.graderError,\n });\n\n return result;\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n const result: RepGradingResult = {\n caseId: cell.caseId,\n cellLabel: cell.cell.label,\n repetitionIndex: rep.repetitionIndex,\n prompt,\n expectations: expectations.map((text) => ({\n text,\n passed: false,\n evidence: message,\n })),\n summary: {\n passed: 0,\n failed: expectations.length,\n total: expectations.length,\n passRate: 0,\n },\n graderError: message,\n durationMs: Date.now() - start,\n };\n\n options.onProgress?.({\n kind: \"grade-complete\",\n caseId: result.caseId,\n cellLabel: result.cellLabel,\n repetitionIndex: result.repetitionIndex,\n passed: 0,\n failed: expectations.length,\n durationMs: result.durationMs,\n graderError: message,\n });\n\n return result;\n }\n }),\n ),\n );\n\n results.sort((a, b) => {\n const keyA = `${a.caseId}::${a.cellLabel}::${a.repetitionIndex}`;\n const keyB = `${b.caseId}::${b.cellLabel}::${b.repetitionIndex}`;\n return keyA.localeCompare(keyB);\n });\n\n const totalExpectations = results.reduce((n, r) => n + r.summary.total, 0);\n const passedExpectations = results.reduce((n, r) => n + r.summary.passed, 0);\n\n options.onProgress?.({\n kind: \"grade-done\",\n durationMs: Date.now() - gradeStartTs,\n totalExpectations,\n passedExpectations,\n });\n\n return {\n gradedAt: new Date().toISOString(),\n sourceReport: options.sourceReport ?? \"\",\n gradingConfigPath: options.gradingConfigPath,\n results,\n summary: {\n passed: passedExpectations,\n failed: totalExpectations - passedExpectations,\n total: totalExpectations,\n passRate:\n totalExpectations === 0 ? 0 : passedExpectations / totalExpectations,\n },\n };\n}\n\nexport async function loadSuiteReport(path: string): Promise<SuiteReport> {\n const text = await readFile(path, \"utf8\");\n return JSON.parse(text) as SuiteReport;\n}\n","/**\n * Merge grading YAML with CLI overrides for `gradeReport`.\n */\n\nimport type { ClaudeCodeOptions } from \"../adapters/claude-code/types\";\nimport type { GradingConfig } from \"../config/grading-loader\";\nimport type { GradeReportOptions } from \"./types\";\n\nexport interface GradeCliOverrides {\n model?: string;\n binary?: string;\n timeoutMs?: number;\n maxConcurrent?: number;\n expectationsPath?: string;\n sourceReport?: string;\n}\n\n/**\n * Merge standalone grading YAML with CLI flags (CLI wins).\n */\nexport function resolveGradeOptions(\n fileConfig?: GradingConfig,\n cli: GradeCliOverrides = {},\n configPath?: string,\n): GradeReportOptions {\n const judge = fileConfig?.judge;\n\n const adapter = judge?.adapter ?? \"claude-code\";\n if (adapter !== \"claude-code\") {\n throw new Error(\n `unsupported grading adapter \"${adapter}\" (only claude-code today)`,\n );\n }\n\n const claudeCode = (judge?.claudeCode ?? {}) as ClaudeCodeOptions;\n const binary = cli.binary ?? claudeCode.binary;\n const model = cli.model ?? judge?.model ?? claudeCode.model;\n\n return {\n sourceReport: cli.sourceReport,\n expectationsPath: cli.expectationsPath,\n model,\n binary,\n timeoutMs: cli.timeoutMs ?? judge?.timeoutMs,\n maxConcurrent: cli.maxConcurrent ?? judge?.maxConcurrent,\n systemInstruction: judge?.system_instruction,\n env: judge?.env,\n cwd: judge?.cwd,\n claudeCode: {\n ...claudeCode,\n binary: undefined,\n model: undefined,\n },\n gradingConfigPath: configPath,\n };\n}\n","/**\n * Console formatter for suite grading reports.\n */\n\nimport type { RepGradingResult, SuiteGradingReport } from \"./types\";\n\nconst RESET = \"\\x1b[0m\";\nconst GREEN = \"\\x1b[32m\";\nconst RED = \"\\x1b[31m\";\nconst DIM = \"\\x1b[2m\";\n\nexport function formatGradingConsole(\n report: SuiteGradingReport,\n color = true,\n): string {\n const lines: string[] = [];\n\n if (report.results.length === 0) {\n lines.push(\n \"No repetitions graded. Add expectations to the suite YAML or pass --expectations.\",\n );\n return lines.join(\"\\n\");\n }\n\n for (const result of report.results) {\n const allPassed = result.summary.failed === 0 && !result.graderError;\n const status = allPassed\n ? color ? `${GREEN}PASS${RESET}` : \"PASS\"\n : color ? `${RED}FAIL${RESET}` : \"FAIL\";\n\n lines.push(\n `${result.caseId} @ ${result.cellLabel} rep${result.repetitionIndex} ${status}`,\n );\n\n if (result.graderError) {\n lines.push(\n color\n ? ` ${RED}grader error: ${result.graderError}${RESET}`\n : ` grader error: ${result.graderError}`,\n );\n }\n\n for (const exp of result.expectations) {\n const marker = exp.passed\n ? color ? `${GREEN}✓${RESET}` : \"✓\"\n : color ? `${RED}✗${RESET}` : \"✗\";\n lines.push(` ├─ ${exp.text} ${marker}`);\n if (!exp.passed || exp.evidence) {\n lines.push(\n color\n ? ` │ ${DIM}${exp.evidence}${RESET}`\n : ` │ ${exp.evidence}`,\n );\n }\n }\n\n const pct = (result.summary.passRate * 100).toFixed(0);\n lines.push(\n ` └─ ${result.summary.passed}/${result.summary.total} (${pct}%) expectations`,\n );\n lines.push(\"\");\n }\n\n const overallPct = (report.summary.passRate * 100).toFixed(0);\n lines.push(\n `Overall: ${report.summary.passed}/${report.summary.total} (${overallPct}%) expectations passed`,\n );\n\n return lines.join(\"\\n\").trimEnd();\n}\n\nexport function gradingReportPassed(report: SuiteGradingReport): boolean {\n return report.results.every(\n (r) => !r.graderError && r.summary.failed === 0 && r.summary.total > 0,\n );\n}\n","/**\n * Console (ANSI) report formatter.\n */\n\nimport type { RenderableRow } from \"./types\";\n\nconst RESET = \"\\x1b[0m\";\nconst GREEN = \"\\x1b[32m\";\nconst RED = \"\\x1b[31m\";\nconst YELLOW = \"\\x1b[33m\";\nconst DIM = \"\\x1b[2m\";\n\nexport function formatConsole(rows: RenderableRow[], color = true): string {\n const lines: string[] = [];\n\n for (const row of rows) {\n const status = row.passed\n ? color ? `${GREEN}PASS${RESET}` : \"PASS\"\n : color ? `${RED}FAIL${RESET}` : \"FAIL\";\n\n const crashNote =\n row.adapterErrors > 0\n ? ` ${color ? YELLOW : \"\"}[${row.adapterErrors} adapter errors]${color ? RESET : \"\"}`\n : \"\";\n\n lines.push(`${row.caseId} @ ${row.cellLabel} ${status}${crashNote}`);\n if (row.category) lines.push(` category: ${row.category}`);\n\n for (const stat of row.stats) {\n const marker = stat.meetsThreshold\n ? color ? `${GREEN}✓${RESET}` : \"✓\"\n : color ? `${RED}✗${RESET}` : \"✗\";\n\n const rateStr = formatRate(stat);\n const thresholdPct = (stat.threshold * 100).toFixed(0);\n let line = ` ├─ ${stat.description}: ${rateStr} [threshold ${thresholdPct}%] ${marker}`;\n\n if (stat.delta !== undefined && stat.baselinePassRate !== undefined) {\n const arrow = stat.delta >= 0 ? \"↑\" : \"↓\";\n const basePct = (stat.baselinePassRate * 100).toFixed(0);\n const curPct = (stat.passRate * 100).toFixed(0);\n const deltaPct = (stat.delta * 100).toFixed(0);\n line += ` (${basePct}% → ${curPct}% (${arrow}${deltaPct}%))`;\n }\n\n lines.push(line);\n }\n lines.push(\"\");\n }\n\n return lines.join(\"\\n\").trimEnd();\n}\n\nfunction formatRate(stat: RenderableRow[\"stats\"][number]): string {\n if (stat.evaluatedCount === 0) {\n return `0/${stat.totalReps} (all reps crashed)`;\n }\n const pct = (stat.passRate * 100).toFixed(0);\n return `${stat.passedCount}/${stat.evaluatedCount} (${pct}%)`;\n}\n","/**\n * JSON report formatter (passthrough).\n */\n\nimport type { SuiteReport } from \"../runner/types\";\n\nexport function formatJson(report: SuiteReport): string {\n return JSON.stringify(report, null, 2);\n}\n","/**\n * Markdown (GFM) report formatter.\n */\n\nimport type { RenderableRow } from \"./types\";\n\nexport function formatMarkdown(rows: RenderableRow[]): string {\n const lines: string[] = [\"# Harness Eval Report\", \"\"];\n\n for (const row of rows) {\n const status = row.passed ? \"PASS\" : \"FAIL\";\n const crashNote =\n row.adapterErrors > 0 ? ` (${row.adapterErrors} adapter errors)` : \"\";\n\n lines.push(`## ${row.caseId} @ ${row.cellLabel} — ${status}${crashNote}`);\n if (row.category) lines.push(`**Category:** ${row.category}`);\n if (row.notes) {\n lines.push(\"<details><summary>Notes</summary>\", row.notes, \"</details>\");\n }\n lines.push(\"\");\n lines.push(\"| Assertion | Result | Threshold | Status |\");\n lines.push(\"| --- | --- | --- | --- |\");\n\n for (const stat of row.stats) {\n const rateStr = formatRate(stat);\n const threshold = `${(stat.threshold * 100).toFixed(0)}%`;\n const statusCell = stat.meetsThreshold ? \"✓\" : \"✗\";\n let result = rateStr;\n if (stat.delta !== undefined && stat.baselinePassRate !== undefined) {\n const base = (stat.baselinePassRate * 100).toFixed(0);\n const cur = (stat.passRate * 100).toFixed(0);\n const d = (stat.delta * 100).toFixed(0);\n const sign = stat.delta >= 0 ? \"+\" : \"\";\n result += ` (${base}% → ${cur}%, ${sign}${d}%)`;\n }\n lines.push(`| ${stat.description} | ${result} | ${threshold} | ${statusCell} |`);\n }\n lines.push(\"\");\n }\n\n return lines.join(\"\\n\").trimEnd();\n}\n\nfunction formatRate(stat: RenderableRow[\"stats\"][number]): string {\n if (stat.evaluatedCount === 0) {\n return `0/${stat.totalReps} (all reps crashed)`;\n }\n const pct = (stat.passRate * 100).toFixed(0);\n return `${stat.passedCount}/${stat.evaluatedCount} (${pct}%)`;\n}\n","/**\n * SuiteReport → RenderableRow[] intermediate model.\n */\n\nimport type { CellReport, SuiteReport } from \"../runner/types\";\nimport type { RenderableRow, RenderableStat } from \"./types\";\n\nexport function toRenderableRows(report: SuiteReport): RenderableRow[] {\n return report.cells.map((cell) => cellToRow(cell));\n}\n\nexport function applyBaseline(\n rows: RenderableRow[],\n baseline: SuiteReport,\n): RenderableRow[] {\n const baselineMap = new Map(\n baseline.cells.map((c) => [`${c.caseId}::${c.cell.label}`, c]),\n );\n\n return rows.map((row) => {\n const baseCell = baselineMap.get(`${row.caseId}::${row.cellLabel}`);\n if (!baseCell) return row;\n\n const stats = row.stats.map((stat, i) => {\n const baseStat = baseCell.assertionStats[i];\n if (!baseStat) return stat;\n const delta = stat.passRate - baseStat.passRate;\n return {\n ...stat,\n baselinePassRate: baseStat.passRate,\n delta,\n };\n });\n\n return { ...row, stats };\n });\n}\n\nfunction cellToRow(cell: CellReport): RenderableRow {\n const totalReps = cell.repetitions.length;\n\n const stats: RenderableStat[] = cell.assertionStats.map((s) => ({\n description: s.description,\n threshold: s.threshold,\n passedCount: s.passedCount,\n evaluatedCount: s.evaluatedCount,\n totalReps,\n adapterErrors: cell.adapterErrors,\n passRate: s.passRate,\n meetsThreshold: s.meetsThreshold,\n }));\n\n return {\n caseId: cell.caseId,\n category: cell.category,\n notes: cell.notes,\n cellLabel: cell.cell.label,\n passed: cell.passed,\n adapterErrors: cell.adapterErrors,\n totalReps,\n stats,\n };\n}\n","/**\n * Reporter public API.\n */\n\nimport type { SuiteReport } from \"../runner/types\";\nimport { formatConsole } from \"./format-console\";\nimport { formatJson } from \"./format-json\";\nimport { formatMarkdown } from \"./format-markdown\";\nimport { applyBaseline, toRenderableRows } from \"./renderable\";\nimport type { ReporterOptions } from \"./types\";\n\nexport type { ReporterOptions, ReportFormat, RenderableRow } from \"./types\";\n\nexport function formatReport(\n report: SuiteReport,\n options: ReporterOptions,\n): string {\n if (options.format === \"json\") {\n return formatJson(report);\n }\n\n let rows = toRenderableRows(report);\n if (options.baseline) {\n rows = applyBaseline(rows, options.baseline);\n }\n\n const useColor =\n options.color ?? (options.format === \"console\");\n\n if (options.format === \"markdown\") {\n return formatMarkdown(rows);\n }\n\n return formatConsole(rows, useColor);\n}\n","/**\n * Build interchange output from internal {@link TrajectoryView} data.\n */\n\nimport type {\n AgentTrace,\n InterchangeToolCall,\n TabularToolCall,\n} from \"../types/eval-interchange\";\nimport type { ToolCall, TrajectoryView } from \"../types/trajectory\";\n\nconst DEFAULT_AGENT_ID = \"agent\";\n\nexport function serializeToolInput(args: unknown): string {\n return JSON.stringify(args ?? {});\n}\n\nexport function parseToolInput(toolInput: string): unknown {\n try {\n return JSON.parse(toolInput) as unknown;\n } catch {\n return toolInput;\n }\n}\n\nexport function toolCallToInterchange(toolCall: ToolCall): InterchangeToolCall {\n return {\n tool_name: toolCall.name,\n tool_input: serializeToolInput(toolCall.args),\n };\n}\n\nexport function toolCallToTabular(toolCall: ToolCall): TabularToolCall {\n return {\n tool_name: toolCall.name,\n tool_input: toolCall.args ?? {},\n };\n}\n\nexport function interchangeToTabular(\n toolCall: InterchangeToolCall,\n): TabularToolCall {\n return {\n tool_name: toolCall.tool_name,\n tool_input: parseToolInput(toolCall.tool_input),\n };\n}\n\nexport function tabularToInterchange(\n toolCall: TabularToolCall,\n): InterchangeToolCall {\n return {\n tool_name: toolCall.tool_name,\n tool_input: serializeToolInput(toolCall.tool_input),\n };\n}\n\nexport function predictedTrajectoryFromView(\n view: TrajectoryView,\n): InterchangeToolCall[] {\n return view.toolCalls.map(toolCallToInterchange);\n}\n\nexport function buildAgentTrace(\n view: TrajectoryView,\n agentId: string = DEFAULT_AGENT_ID,\n): AgentTrace {\n const agents: AgentTrace[\"agents\"] = {\n [agentId]: {\n agent_id: agentId,\n agent_type: \"assistant\",\n description: view.meta.model,\n tools: view.meta.availableTools.map((name) => ({ name })),\n },\n };\n\n const activeTools = view.meta.availableTools.map((name) => ({ name }));\n\n const turns = view.turns.map((turn) => {\n const events: AgentTrace[\"turns\"][number][\"events\"] = [];\n\n if (turn.text) {\n events.push({\n author: agentId,\n content: { parts: [{ text: turn.text }] },\n active_tools: activeTools,\n });\n }\n\n for (const toolCall of turn.toolCalls) {\n events.push({\n author: agentId,\n content: {\n parts: [\n {\n function_call: {\n name: toolCall.name,\n args: toolCall.args ?? {},\n },\n },\n ],\n },\n active_tools: activeTools,\n });\n\n if (toolCall.result !== null && toolCall.result !== undefined) {\n events.push({\n author: agentId,\n content: {\n parts: [\n {\n function_response: {\n name: toolCall.name,\n response: toolCall.result,\n },\n },\n ],\n },\n active_tools: activeTools,\n });\n }\n }\n\n return {\n turn_index: turn.turnIndex,\n events,\n };\n });\n\n return { agents, turns };\n}\n\nexport function latencyInSeconds(view: TrajectoryView): number {\n return view.usage.durationMs / 1000;\n}\n\nexport function failureFlag(view: TrajectoryView): 0 | 1 {\n return view.success ? 0 : 1;\n}\n","/**\n * Trajectory-level metrics for comparing predicted and reference tool-call sequences.\n *\n * Metric definitions align with upstream evaluation service trajectory specs.\n */\n\nimport type {\n InterchangeToolCall,\n TabularToolCall,\n TrajectoryMetrics,\n} from \"../types/eval-interchange\";\nimport { serializeToolInput } from \"../eval-interchange/build\";\n\nexport type TrajectoryInput =\n | InterchangeToolCall[]\n | TabularToolCall[]\n | Array<{ tool_name: string; tool_input: unknown }>;\n\nfunction normalizeToolCall(\n toolCall: TrajectoryInput[number],\n): InterchangeToolCall {\n if (typeof toolCall.tool_input === \"string\") {\n return {\n tool_name: toolCall.tool_name,\n tool_input: toolCall.tool_input,\n };\n }\n\n return {\n tool_name: toolCall.tool_name,\n tool_input: serializeToolInput(toolCall.tool_input),\n };\n}\n\nfunction normalizeTrajectory(trajectory: TrajectoryInput): InterchangeToolCall[] {\n return trajectory.map(normalizeToolCall);\n}\n\nfunction toolCallKey(toolCall: InterchangeToolCall): string {\n return `${toolCall.tool_name}\\0${toolCall.tool_input}`;\n}\n\nfunction multisetIntersectionSize(\n predicted: InterchangeToolCall[],\n reference: InterchangeToolCall[],\n): number {\n const refCounts = new Map<string, number>();\n for (const toolCall of reference) {\n const key = toolCallKey(toolCall);\n refCounts.set(key, (refCounts.get(key) ?? 0) + 1);\n }\n\n let matched = 0;\n for (const toolCall of predicted) {\n const key = toolCallKey(toolCall);\n const count = refCounts.get(key) ?? 0;\n if (count > 0) {\n matched += 1;\n refCounts.set(key, count - 1);\n }\n }\n\n return matched;\n}\n\nfunction isSubsequence(\n predicted: InterchangeToolCall[],\n reference: InterchangeToolCall[],\n): boolean {\n let refIndex = 0;\n for (const toolCall of predicted) {\n if (refIndex >= reference.length) break;\n if (toolCallKey(toolCall) === toolCallKey(reference[refIndex]!)) {\n refIndex += 1;\n }\n }\n return refIndex === reference.length;\n}\n\nfunction arraysEqual(\n left: InterchangeToolCall[],\n right: InterchangeToolCall[],\n): boolean {\n if (left.length !== right.length) return false;\n return left.every((toolCall, index) => {\n const other = right[index]!;\n return toolCallKey(toolCall) === toolCallKey(other);\n });\n}\n\nexport function trajectoryExactMatch(\n predicted: TrajectoryInput,\n reference: TrajectoryInput,\n): number {\n const predictedNorm = normalizeTrajectory(predicted);\n const referenceNorm = normalizeTrajectory(reference);\n return arraysEqual(predictedNorm, referenceNorm) ? 1 : 0;\n}\n\nexport function trajectoryInOrderMatch(\n predicted: TrajectoryInput,\n reference: TrajectoryInput,\n): number {\n const predictedNorm = normalizeTrajectory(predicted);\n const referenceNorm = normalizeTrajectory(reference);\n return isSubsequence(predictedNorm, referenceNorm) ? 1 : 0;\n}\n\nexport function trajectoryAnyOrderMatch(\n predicted: TrajectoryInput,\n reference: TrajectoryInput,\n): number {\n const predictedNorm = normalizeTrajectory(predicted);\n const referenceNorm = normalizeTrajectory(reference);\n if (predictedNorm.length !== referenceNorm.length) return 0;\n\n const predictedKeys = predictedNorm.map(toolCallKey).sort();\n const referenceKeys = referenceNorm.map(toolCallKey).sort();\n return predictedKeys.every((key, index) => key === referenceKeys[index])\n ? 1\n : 0;\n}\n\nexport function trajectoryPrecision(\n predicted: TrajectoryInput,\n reference: TrajectoryInput,\n): number {\n const predictedNorm = normalizeTrajectory(predicted);\n if (predictedNorm.length === 0) return reference.length === 0 ? 1 : 0;\n\n const referenceNorm = normalizeTrajectory(reference);\n return multisetIntersectionSize(predictedNorm, referenceNorm) /\n predictedNorm.length;\n}\n\nexport function trajectoryRecall(\n predicted: TrajectoryInput,\n reference: TrajectoryInput,\n): number {\n const referenceNorm = normalizeTrajectory(reference);\n if (referenceNorm.length === 0) return predicted.length === 0 ? 1 : 0;\n\n const predictedNorm = normalizeTrajectory(predicted);\n return multisetIntersectionSize(predictedNorm, referenceNorm) /\n referenceNorm.length;\n}\n\nexport function trajectorySingleToolUse(\n predicted: TrajectoryInput,\n reference: TrajectoryInput,\n): number {\n const predictedNorm = normalizeTrajectory(predicted);\n const referenceNorm = normalizeTrajectory(reference);\n if (predictedNorm.length !== 1 || referenceNorm.length !== 1) return 0;\n return toolCallKey(predictedNorm[0]!) === toolCallKey(referenceNorm[0]!)\n ? 1\n : 0;\n}\n\nexport function computeTrajectoryMetrics(\n predicted: TrajectoryInput,\n reference: TrajectoryInput,\n): TrajectoryMetrics {\n return {\n trajectory_exact_match: trajectoryExactMatch(predicted, reference),\n trajectory_in_order_match: trajectoryInOrderMatch(predicted, reference),\n trajectory_any_order_match: trajectoryAnyOrderMatch(predicted, reference),\n trajectory_precision: trajectoryPrecision(predicted, reference),\n trajectory_recall: trajectoryRecall(predicted, reference),\n trajectory_single_tool_use: trajectorySingleToolUse(predicted, reference),\n };\n}\n","/**\n * Tool-call-level metrics operating on prediction/reference tool-call pairs.\n *\n * Metric definitions align with upstream evaluation service tool-call specs.\n */\n\nimport type {\n InterchangeToolCall,\n TabularToolCall,\n ToolCallMetrics,\n} from \"../types/eval-interchange\";\nimport { parseToolInput, serializeToolInput } from \"../eval-interchange/build\";\n\nexport interface ToolCallMetricOptions {\n useStrictStringMatch?: boolean;\n}\n\ntype ToolCallInput =\n | InterchangeToolCall\n | TabularToolCall\n | { tool_name: string; tool_input: unknown };\n\nfunction normalizeToolCall(toolCall: ToolCallInput): InterchangeToolCall {\n if (typeof toolCall.tool_input === \"string\") {\n return {\n tool_name: toolCall.tool_name,\n tool_input: toolCall.tool_input,\n };\n }\n\n return {\n tool_name: toolCall.tool_name,\n tool_input: serializeToolInput(toolCall.tool_input),\n };\n}\n\nfunction parsedArgs(toolCall: InterchangeToolCall): Record<string, unknown> | null {\n const parsed = parseToolInput(toolCall.tool_input);\n if (parsed === null || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n return null;\n }\n return parsed as Record<string, unknown>;\n}\n\nexport function toolCallValid(toolCall: ToolCallInput): number {\n const normalized = normalizeToolCall(toolCall);\n if (!normalized.tool_name.trim()) return 0;\n\n try {\n JSON.parse(normalized.tool_input);\n return 1;\n } catch {\n return 0;\n }\n}\n\nexport function toolNameMatch(\n predicted: ToolCallInput,\n reference: ToolCallInput,\n): number {\n const predictedNorm = normalizeToolCall(predicted);\n const referenceNorm = normalizeToolCall(reference);\n return predictedNorm.tool_name === referenceNorm.tool_name ? 1 : 0;\n}\n\nexport function toolParameterKeyMatch(\n predicted: ToolCallInput,\n reference: ToolCallInput,\n): number {\n if (toolNameMatch(predicted, reference) === 0) return 0;\n\n const predictedArgs = parsedArgs(normalizeToolCall(predicted));\n const referenceArgs = parsedArgs(normalizeToolCall(reference));\n if (predictedArgs === null || referenceArgs === null) return 0;\n\n const predictedKeys = Object.keys(predictedArgs).sort();\n const referenceKeys = Object.keys(referenceArgs).sort();\n if (predictedKeys.length !== referenceKeys.length) return 0;\n\n return predictedKeys.every((key, index) => key === referenceKeys[index])\n ? 1\n : 0;\n}\n\nfunction valuesEqual(\n left: unknown,\n right: unknown,\n useStrictStringMatch: boolean,\n): boolean {\n if (useStrictStringMatch) {\n return JSON.stringify(left) === JSON.stringify(right);\n }\n return JSON.stringify(left) === JSON.stringify(right);\n}\n\nexport function toolParameterKvMatch(\n predicted: ToolCallInput,\n reference: ToolCallInput,\n options: ToolCallMetricOptions = {},\n): number {\n if (toolParameterKeyMatch(predicted, reference) === 0) return 0;\n\n const predictedArgs = parsedArgs(normalizeToolCall(predicted))!;\n const referenceArgs = parsedArgs(normalizeToolCall(reference))!;\n\n for (const key of Object.keys(referenceArgs)) {\n if (\n !valuesEqual(\n predictedArgs[key],\n referenceArgs[key],\n options.useStrictStringMatch ?? false,\n )\n ) {\n return 0;\n }\n }\n\n return 1;\n}\n\nexport function computeToolCallMetrics(\n predicted: ToolCallInput[],\n reference: ToolCallInput[],\n options: ToolCallMetricOptions = {},\n): ToolCallMetrics {\n const pairCount = Math.max(predicted.length, reference.length, 1);\n let valid = 0;\n let nameMatch = 0;\n let keyMatch = 0;\n let kvMatch = 0;\n\n for (let index = 0; index < pairCount; index += 1) {\n const predictedCall = predicted[index];\n const referenceCall = reference[index];\n if (!predictedCall) continue;\n\n valid += toolCallValid(predictedCall);\n if (!referenceCall) continue;\n\n nameMatch += toolNameMatch(predictedCall, referenceCall);\n keyMatch += toolParameterKeyMatch(predictedCall, referenceCall);\n kvMatch += toolParameterKvMatch(predictedCall, referenceCall, options);\n }\n\n return {\n tool_call_valid: valid / pairCount,\n tool_name_match: nameMatch / pairCount,\n tool_parameter_key_match: keyMatch / pairCount,\n tool_parameter_kv_match: kvMatch / pairCount,\n };\n}\n","/**\n * Envelope projection methods for eval interchange output.\n */\n\nimport {\n buildAgentTrace,\n interchangeToTabular,\n latencyInSeconds,\n predictedTrajectoryFromView,\n toolCallToTabular,\n} from \"./build\";\nimport type {\n AgentTrace,\n EvalDatasetRow,\n InterchangeToolCall,\n ProtoTrajectoryInstance,\n TabularToolCall,\n TrajectoryMetrics,\n} from \"../types/eval-interchange\";\nimport type {\n EvalCellResult,\n EvalRepetition,\n EvalRunEnvelope,\n} from \"../types/eval-record\";\nimport { computeTrajectoryMetrics } from \"../metrics/trajectory\";\nimport { computeToolCallMetrics } from \"../metrics/tool-calls\";\n\nfunction repetitionInterchangeFields(\n repetition: EvalRepetition,\n): {\n predicted_trajectory: InterchangeToolCall[];\n agent_trace?: AgentTrace;\n latency_in_seconds?: number;\n failure?: 0 | 1;\n} {\n if (!repetition.trajectory) {\n return { predicted_trajectory: [] };\n }\n\n return {\n predicted_trajectory: repetition.predicted_trajectory ??\n predictedTrajectoryFromView(repetition.trajectory),\n agent_trace: repetition.agent_trace ??\n buildAgentTrace(repetition.trajectory),\n latency_in_seconds: repetition.latency_in_seconds ??\n latencyInSeconds(repetition.trajectory),\n failure: repetition.failure ?? (repetition.trajectory.success ? 0 : 1),\n };\n}\n\nfunction referenceTrajectoryForCell(\n cell: EvalCellResult,\n): TabularToolCall[] | undefined {\n return cell.reference_trajectory;\n}\n\nexport function repetitionToDatasetRow(\n cell: EvalCellResult,\n repetition: EvalRepetition,\n): EvalDatasetRow | null {\n const fields = repetitionInterchangeFields(repetition);\n if (!repetition.trajectory) {\n return {\n prompt: cell.prompt,\n response: undefined,\n predicted_trajectory: [],\n reference_trajectory: referenceTrajectoryForCell(cell),\n latency_in_seconds: repetition.durationMs / 1000,\n failure: 1,\n human_ratings: cell.human_ratings,\n };\n }\n\n return {\n prompt: cell.prompt,\n response: repetition.trajectory.finalResponse,\n predicted_trajectory: fields.predicted_trajectory.map(interchangeToTabular),\n reference_trajectory: referenceTrajectoryForCell(cell),\n latency_in_seconds: fields.latency_in_seconds ?? repetition.durationMs / 1000,\n failure: fields.failure ?? 1,\n human_ratings: cell.human_ratings,\n };\n}\n\nexport function repetitionToProtoInstance(\n cell: EvalCellResult,\n repetition: EvalRepetition,\n): ProtoTrajectoryInstance | null {\n const fields = repetitionInterchangeFields(repetition);\n if (!repetition.trajectory) return null;\n\n const reference = referenceTrajectoryForCell(cell);\n return {\n prompt: cell.prompt,\n response: repetition.trajectory.finalResponse,\n predicted_trajectory: {\n tool_calls: fields.predicted_trajectory,\n },\n reference_trajectory: reference\n ? {\n tool_calls: reference.map((toolCall) => ({\n tool_name: toolCall.tool_name,\n tool_input:\n typeof toolCall.tool_input === \"string\"\n ? toolCall.tool_input\n : JSON.stringify(toolCall.tool_input ?? {}),\n })),\n }\n : undefined,\n };\n}\n\nexport function repetitionToAgentTrace(\n repetition: EvalRepetition,\n): AgentTrace | null {\n const fields = repetitionInterchangeFields(repetition);\n return fields.agent_trace ?? null;\n}\n\nexport function computeRepetitionMetrics(\n repetition: EvalRepetition,\n referenceTrajectory?: TabularToolCall[],\n): {\n trajectoryMetrics?: TrajectoryMetrics;\n toolCallMetrics?: ReturnType<typeof computeToolCallMetrics>;\n} {\n if (!referenceTrajectory?.length) {\n return {};\n }\n\n const predicted = repetition.predicted_trajectory ??\n (repetition.trajectory\n ? predictedTrajectoryFromView(repetition.trajectory)\n : []);\n\n const predictedTabular = predicted.map(interchangeToTabular);\n\n return {\n trajectoryMetrics: computeTrajectoryMetrics(\n predictedTabular,\n referenceTrajectory,\n ),\n toolCallMetrics: computeToolCallMetrics(\n predictedTabular,\n referenceTrajectory,\n ),\n };\n}\n\nexport function toTrajectory(envelope: EvalRunEnvelope): EvalDatasetRow[] {\n const rows: EvalDatasetRow[] = [];\n for (const cell of envelope.cells) {\n for (const repetition of cell.repetitions) {\n const row = repetitionToDatasetRow(cell, repetition);\n if (row) rows.push(row);\n }\n }\n return rows;\n}\n\nexport function toProtoInstances(\n envelope: EvalRunEnvelope,\n): ProtoTrajectoryInstance[] {\n const instances: ProtoTrajectoryInstance[] = [];\n for (const cell of envelope.cells) {\n for (const repetition of cell.repetitions) {\n const instance = repetitionToProtoInstance(cell, repetition);\n if (instance) instances.push(instance);\n }\n }\n return instances;\n}\n\nexport function toAgentTrace(envelope: EvalRunEnvelope): AgentTrace[] {\n const traces: AgentTrace[] = [];\n for (const cell of envelope.cells) {\n for (const repetition of cell.repetitions) {\n const trace = repetitionToAgentTrace(repetition);\n if (trace) traces.push(trace);\n }\n }\n return traces;\n}\n\nexport function enrichRepetitionWithInterchange(\n repetition: EvalRepetition,\n referenceTrajectory?: TabularToolCall[],\n): EvalRepetition {\n if (!repetition.trajectory) {\n return repetition;\n }\n\n const predicted_trajectory = predictedTrajectoryFromView(repetition.trajectory);\n const agent_trace = buildAgentTrace(repetition.trajectory);\n const latency_in_seconds = latencyInSeconds(repetition.trajectory);\n const failure = repetition.trajectory.success ? 0 : 1;\n\n const metrics = computeRepetitionMetrics(\n {\n ...repetition,\n predicted_trajectory,\n agent_trace,\n latency_in_seconds,\n failure,\n },\n referenceTrajectory,\n );\n\n return {\n ...repetition,\n predicted_trajectory,\n agent_trace,\n latency_in_seconds,\n failure,\n trajectoryMetrics: metrics.trajectoryMetrics,\n toolCallMetrics: metrics.toolCallMetrics,\n };\n}\n","/**\n * Build {@link EvalRunEnvelope} from harness-eval run and grading reports.\n */\n\nimport { randomUUID } from \"node:crypto\";\nimport { readFile } from \"node:fs/promises\";\nimport { createHash } from \"node:crypto\";\n\nimport { trajectoryToTranscript } from \"../grader/transcript\";\nimport { enrichRepetitionWithInterchange } from \"../eval-interchange/projections\";\nimport type { SuiteGradingReport } from \"../grader/types\";\nimport type {\n BuildEvalRunEnvelopeOptions,\n EvalCellResult,\n EvalRepetition,\n EvalRunEnvelope,\n} from \"../types/eval-record\";\nimport {\n EVAL_RUN_SCHEMA_VERSION,\n TRAJECTORY_SCHEMA_VERSION,\n} from \"../types/eval-record\";\nimport type { SuiteReport } from \"../runner/types\";\n\nfunction extractRawEvents(adapterResult: unknown): unknown[] | undefined {\n if (\n adapterResult !== null &&\n typeof adapterResult === \"object\" &&\n \"rawEvents\" in adapterResult &&\n Array.isArray((adapterResult as { rawEvents: unknown }).rawEvents)\n ) {\n return (adapterResult as { rawEvents: unknown[] }).rawEvents;\n }\n return undefined;\n}\n\nfunction outcomePassForCell(\n caseId: string,\n cellLabel: string,\n repetitions: EvalRepetition[],\n): boolean | undefined {\n const graded = repetitions.filter((r) => r.outcomeGrades);\n if (graded.length === 0) return undefined;\n return graded.every(\n (r) =>\n r.outcomeGrades!.error === undefined &&\n r.outcomeGrades!.summary.failed === 0,\n );\n}\n\n/**\n * Convert a {@link SuiteReport} (and optional grading) into a versioned\n * {@link EvalRunEnvelope} for storage or API handoff.\n */\nexport function buildEvalRunEnvelope(\n report: SuiteReport,\n options: BuildEvalRunEnvelopeOptions = {},\n): EvalRunEnvelope {\n const includeTranscript = options.includeTranscript !== false;\n const includeRaw = options.includeRawStreamEvents === true;\n\n const judge =\n options.grading?.judge ?? { id: \"harness-eval/claude-grader\" };\n\n const cells: EvalCellResult[] = report.cells.map((cell) => {\n const prompt = cell.prompt ?? \"\";\n const referenceTrajectory = cell.reference_trajectory;\n const repetitions: EvalRepetition[] = cell.repetitions.map((rep) => {\n const base: EvalRepetition = {\n repetitionIndex: rep.repetitionIndex,\n durationMs: rep.durationMs,\n assertionResults: rep.assertionResults,\n };\n\n if (rep.error) {\n base.error = {\n message: rep.error.message,\n diagnostics: rep.error.diagnostics,\n };\n return base;\n }\n\n if (rep.adapterResult) {\n base.trajectory = {\n ...rep.adapterResult.view,\n schemaVersion: TRAJECTORY_SCHEMA_VERSION,\n };\n base.diagnostics = rep.adapterResult.diagnostics;\n\n const artifacts: EvalRepetition[\"artifacts\"] = {};\n if (includeTranscript) {\n artifacts.transcript = trajectoryToTranscript(\n rep.adapterResult.view,\n prompt,\n );\n }\n if (includeRaw) {\n const raw = extractRawEvents(rep.adapterResult);\n if (raw) artifacts.rawStreamEvents = raw;\n }\n if (Object.keys(artifacts).length > 0) {\n base.artifacts = artifacts;\n }\n }\n\n const graded = options.grading?.results.find(\n (r) =>\n r.caseId === cell.caseId &&\n r.cellLabel === cell.cell.label &&\n r.repetitionIndex === rep.repetitionIndex,\n );\n\n if (graded) {\n base.outcomeGrades = {\n judge,\n expectations: graded.expectations,\n summary: graded.summary,\n evalFeedback: graded.evalFeedback,\n error: graded.graderError,\n };\n }\n\n return enrichRepetitionWithInterchange(base, referenceTrajectory);\n });\n\n return {\n caseId: cell.caseId,\n category: cell.category,\n notes: cell.notes,\n prompt: cell.prompt,\n expectations: cell.expectations,\n reference_trajectory: cell.reference_trajectory,\n human_ratings: cell.human_ratings,\n cellLabel: cell.cell.label,\n axes: cell.cell.axes,\n assertionStats: cell.assertionStats,\n adapterErrors: cell.adapterErrors,\n behavioralPass: cell.passed,\n outcomePass: outcomePassForCell(\n cell.caseId,\n cell.cell.label,\n repetitions,\n ),\n repetitions,\n };\n });\n\n const cellsPassed = cells.filter((c) => c.behavioralPass).length;\n const gradedCells = cells.filter((c) => c.outcomePass !== undefined);\n const outcomePass =\n gradedCells.length > 0\n ? gradedCells.every((c) => c.outcomePass === true)\n : undefined;\n\n return {\n schemaVersion: EVAL_RUN_SCHEMA_VERSION,\n runId: options.runId ?? randomUUID(),\n startedAt: report.startedAt,\n durationMs: report.durationMs,\n suite: options.suite,\n harness: {\n adapter: options.harness?.adapter ?? \"claude-code\",\n frameworkVersion: options.harness?.frameworkVersion,\n harnessVersion: options.harness?.harnessVersion,\n },\n provenance: options.provenance,\n summary: {\n cellsTotal: cells.length,\n cellsPassed,\n behavioralPass: cellsPassed === cells.length,\n outcomePass,\n },\n cells,\n };\n}\n\n/** Build envelope from on-disk report + optional grading JSON paths. */\nexport async function buildEvalRunEnvelopeFromFiles(\n reportPath: string,\n options: BuildEvalRunEnvelopeOptions & {\n gradingPath?: string;\n suitePath?: string;\n } = {},\n): Promise<EvalRunEnvelope> {\n const reportText = await readFile(reportPath, \"utf8\");\n const report = JSON.parse(reportText) as SuiteReport;\n\n let grading: BuildEvalRunEnvelopeOptions[\"grading\"] | undefined =\n options.grading;\n\n if (options.gradingPath) {\n const gradingText = await readFile(options.gradingPath, \"utf8\");\n const parsed = JSON.parse(gradingText) as SuiteGradingReport;\n grading = {\n gradedAt: parsed.gradedAt,\n sourceReport: parsed.sourceReport,\n results: parsed.results,\n judge: options.grading?.judge ?? { id: \"harness-eval/claude-grader\" },\n };\n }\n\n let suite = options.suite;\n if (options.suitePath) {\n const content = await readFile(options.suitePath, \"utf8\");\n suite = {\n ...suite,\n uri: options.suitePath,\n contentHash: createHash(\"sha256\").update(content).digest(\"hex\"),\n };\n }\n\n return buildEvalRunEnvelope(report, {\n ...options,\n suite,\n grading,\n });\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
//#region src/assertions/cardinality.ts
|
|
2
|
+
const CARDINALITY_PATTERN = /^\s*(==|!=|>=|<=|>|<)\s*(\d+)\s*$/;
|
|
3
|
+
/**
|
|
4
|
+
* Parse a cardinality spec into a check function. Throws on malformed input
|
|
5
|
+
* — at config-load time we want to fail loudly rather than silently match
|
|
6
|
+
* nothing.
|
|
7
|
+
*/
|
|
8
|
+
function parseCardinality(spec) {
|
|
9
|
+
if (spec === void 0) return (count) => count >= 1;
|
|
10
|
+
const match = CARDINALITY_PATTERN.exec(spec);
|
|
11
|
+
if (!match) throw new Error(`invalid cardinality spec: ${JSON.stringify(spec)}. Expected format: "<op> <n>" where op is one of == != >= <= > <`);
|
|
12
|
+
const op = match[1];
|
|
13
|
+
const n = parseInt(match[2], 10);
|
|
14
|
+
switch (op) {
|
|
15
|
+
case "==": return (count) => count === n;
|
|
16
|
+
case "!=": return (count) => count !== n;
|
|
17
|
+
case ">=": return (count) => count >= n;
|
|
18
|
+
case "<=": return (count) => count <= n;
|
|
19
|
+
case ">": return (count) => count > n;
|
|
20
|
+
case "<": return (count) => count < n;
|
|
21
|
+
default: throw new Error(`unreachable: ${op}`);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/** Display string for a cardinality spec; resolves the default. */
|
|
25
|
+
function describeCardinality(spec) {
|
|
26
|
+
return spec ?? ">= 1";
|
|
27
|
+
}
|
|
28
|
+
//#endregion
|
|
29
|
+
export { parseCardinality as n, describeCardinality as t };
|
|
30
|
+
|
|
31
|
+
//# sourceMappingURL=cardinality-DlE44e-4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cardinality-DlE44e-4.js","names":[],"sources":["../src/assertions/cardinality.ts"],"sourcesContent":["/**\n * Cardinality spec parser.\n *\n * A cardinality spec is a string like `\">= 1\"`, `\"== 2\"`, `\"< 5\"`. It\n * describes how many tool calls are acceptable. When omitted, the default\n * is `\">= 1\"` (at least one call).\n *\n * Why strings? They're idiomatic in YAML and read naturally in test cases:\n *\n * called: { tool: mcp__api__load_skill, times: \">= 1\" }\n *\n * The alternative — `{ op: \"gte\", n: 1 }` — is more typed but uglier and\n * forces YAML authors to learn an internal vocabulary.\n */\n\nimport type { Cardinality } from \"../types/assertions\";\n\n/** A compiled cardinality check: takes an observed count, returns pass/fail. */\nexport type CardinalityCheck = (count: number) => boolean;\n\nconst CARDINALITY_PATTERN = /^\\s*(==|!=|>=|<=|>|<)\\s*(\\d+)\\s*$/;\n\n/**\n * Parse a cardinality spec into a check function. Throws on malformed input\n * — at config-load time we want to fail loudly rather than silently match\n * nothing.\n */\nexport function parseCardinality(\n spec: Cardinality | undefined,\n): CardinalityCheck {\n if (spec === undefined) return (count) => count >= 1;\n\n const match = CARDINALITY_PATTERN.exec(spec);\n if (!match) {\n throw new Error(\n `invalid cardinality spec: ${JSON.stringify(spec)}. ` +\n `Expected format: \"<op> <n>\" where op is one of == != >= <= > <`,\n );\n }\n\n const op = match[1];\n const n = parseInt(match[2], 10);\n\n switch (op) {\n case \"==\":\n return (count) => count === n;\n case \"!=\":\n return (count) => count !== n;\n case \">=\":\n return (count) => count >= n;\n case \"<=\":\n return (count) => count <= n;\n case \">\":\n return (count) => count > n;\n case \"<\":\n return (count) => count < n;\n default:\n // Unreachable — regex guarantees op is one of the above.\n throw new Error(`unreachable: ${op}`);\n }\n}\n\n/** Display string for a cardinality spec; resolves the default. */\nexport function describeCardinality(spec: Cardinality | undefined): string {\n return spec ?? \">= 1\";\n}\n"],"mappings":";AAoBA,MAAM,sBAAsB;;;;;;AAO5B,SAAgB,iBACd,MACkB;CAClB,IAAI,SAAS,KAAA,GAAW,QAAQ,UAAU,SAAS;CAEnD,MAAM,QAAQ,oBAAoB,KAAK,IAAI;CAC3C,IAAI,CAAC,OACH,MAAM,IAAI,MACR,6BAA6B,KAAK,UAAU,IAAI,EAAE,iEAEpD;CAGF,MAAM,KAAK,MAAM;CACjB,MAAM,IAAI,SAAS,MAAM,IAAI,EAAE;CAE/B,QAAQ,IAAR;EACE,KAAK,MACH,QAAQ,UAAU,UAAU;EAC9B,KAAK,MACH,QAAQ,UAAU,UAAU;EAC9B,KAAK,MACH,QAAQ,UAAU,SAAS;EAC7B,KAAK,MACH,QAAQ,UAAU,SAAS;EAC7B,KAAK,KACH,QAAQ,UAAU,QAAQ;EAC5B,KAAK,KACH,QAAQ,UAAU,QAAQ;EAC5B,SAEE,MAAM,IAAI,MAAM,gBAAgB,IAAI;CACxC;AACF;;AAGA,SAAgB,oBAAoB,MAAuC;CACzE,OAAO,QAAQ;AACjB"}
|