@artemiskit/core 0.5.0 → 0.5.2
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/CHANGELOG.md +16 -0
- package/dist/artifacts/manifest.d.ts +5 -1
- package/dist/artifacts/manifest.d.ts.map +1 -1
- package/dist/artifacts/types.d.ts +87 -0
- package/dist/artifacts/types.d.ts.map +1 -1
- package/dist/index.js +622 -400
- package/dist/provenance/execution-provenance.d.ts +11 -0
- package/dist/provenance/execution-provenance.d.ts.map +1 -0
- package/dist/provenance/index.d.ts +1 -0
- package/dist/provenance/index.d.ts.map +1 -1
- package/dist/runner/executor.d.ts.map +1 -1
- package/dist/runner/runner.d.ts.map +1 -1
- package/dist/runner/types.d.ts +15 -1
- package/dist/runner/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/artifacts/manifest.test.ts +123 -1
- package/src/artifacts/manifest.ts +25 -29
- package/src/artifacts/types.ts +262 -0
- package/src/provenance/execution-provenance.test.ts +59 -0
- package/src/provenance/execution-provenance.ts +53 -0
- package/src/provenance/index.ts +1 -0
- package/src/runner/executor.test.ts +60 -0
- package/src/runner/executor.ts +145 -11
- package/src/runner/release-validation.test.ts +36 -0
- package/src/runner/runner.ts +31 -1
- package/src/runner/types.ts +9 -1
- package/src/scenario/schema.ts +1 -1
package/dist/index.js
CHANGED
|
@@ -19824,7 +19824,7 @@ var TestCaseSchema = objectType({
|
|
|
19824
19824
|
tags: arrayType(stringType()).optional().default([]),
|
|
19825
19825
|
metadata: recordType(unknownType()).optional().default({}),
|
|
19826
19826
|
timeout: numberType().optional(),
|
|
19827
|
-
retries: numberType().optional().default(0),
|
|
19827
|
+
retries: numberType().int().min(0).max(99).optional().default(0),
|
|
19828
19828
|
provider: ProviderSchema.optional(),
|
|
19829
19829
|
model: stringType().optional(),
|
|
19830
19830
|
variables: VariablesSchema.optional(),
|
|
@@ -20524,16 +20524,48 @@ function mergeRedactionConfig(scenarioConfig, caseConfig, cliConfig) {
|
|
|
20524
20524
|
}
|
|
20525
20525
|
async function executeCase(testCase, context) {
|
|
20526
20526
|
const { timeout, retries = 0 } = context;
|
|
20527
|
+
if (!Number.isSafeInteger(retries) || retries < 0 || retries > 99) {
|
|
20528
|
+
throw new RangeError("retries must be a whole number between 0 and 99");
|
|
20529
|
+
}
|
|
20527
20530
|
const caseStartTime = Date.now();
|
|
20531
|
+
const requestedModel = testCase.model || context.requestedModel || context.scenario.model;
|
|
20532
|
+
const retryChainId = `${context.runId ?? "untracked"}:${testCase.id}`;
|
|
20533
|
+
const repetitionIndex = context.repetition?.index ?? 1;
|
|
20534
|
+
const attemptEvidence = [];
|
|
20528
20535
|
let lastError = null;
|
|
20529
20536
|
for (let attempt = 0;attempt <= retries; attempt++) {
|
|
20537
|
+
const attemptStartTime = Date.now();
|
|
20530
20538
|
try {
|
|
20531
20539
|
const result = await executeCaseAttempt(testCase, context, timeout);
|
|
20532
|
-
return
|
|
20540
|
+
return withAttemptEvidence(result, attemptEvidence, {
|
|
20541
|
+
retryChainId,
|
|
20542
|
+
repetitionIndex,
|
|
20543
|
+
attemptNumber: attempt + 1,
|
|
20544
|
+
includedInOutcome: true,
|
|
20545
|
+
latencyMs: result.latencyMs
|
|
20546
|
+
});
|
|
20533
20547
|
} catch (error) {
|
|
20534
20548
|
lastError = error;
|
|
20535
|
-
if (error instanceof ToolLoopError)
|
|
20536
|
-
return
|
|
20549
|
+
if (error instanceof ToolLoopError) {
|
|
20550
|
+
return withAttemptEvidence(error.caseResult, attemptEvidence, {
|
|
20551
|
+
retryChainId,
|
|
20552
|
+
repetitionIndex,
|
|
20553
|
+
attemptNumber: attempt + 1,
|
|
20554
|
+
includedInOutcome: true,
|
|
20555
|
+
latencyMs: error.caseResult.latencyMs,
|
|
20556
|
+
errorCode: "tool_error"
|
|
20557
|
+
});
|
|
20558
|
+
}
|
|
20559
|
+
attemptEvidence.push({
|
|
20560
|
+
attempt_id: `${retryChainId}:${attempt + 1}`,
|
|
20561
|
+
retry_chain_id: retryChainId,
|
|
20562
|
+
repetition_index: repetitionIndex,
|
|
20563
|
+
attempt_number: attempt + 1,
|
|
20564
|
+
status: "error",
|
|
20565
|
+
included_in_outcome: false,
|
|
20566
|
+
latency_ms: Date.now() - attemptStartTime,
|
|
20567
|
+
error_code: error instanceof TimeoutError ? "timeout" : "target_error"
|
|
20568
|
+
});
|
|
20537
20569
|
if (attempt < retries) {
|
|
20538
20570
|
await sleep(2 ** attempt * 1000);
|
|
20539
20571
|
}
|
|
@@ -20546,6 +20578,10 @@ async function executeCase(testCase, context) {
|
|
|
20546
20578
|
ok: false,
|
|
20547
20579
|
status: "error",
|
|
20548
20580
|
attempts: retries + 1,
|
|
20581
|
+
attempt_evidence: attemptEvidence.map((entry, index) => ({
|
|
20582
|
+
...entry,
|
|
20583
|
+
included_in_outcome: index === attemptEvidence.length - 1
|
|
20584
|
+
})),
|
|
20549
20585
|
score: 0,
|
|
20550
20586
|
matcherType: testCase.expected.type,
|
|
20551
20587
|
reason: `Failed after ${retries + 1} attempts: ${lastError?.message}`,
|
|
@@ -20555,11 +20591,34 @@ async function executeCase(testCase, context) {
|
|
|
20555
20591
|
response: "",
|
|
20556
20592
|
expected: testCase.expected,
|
|
20557
20593
|
tags: testCase.tags,
|
|
20558
|
-
error: lastError?.message
|
|
20594
|
+
error: lastError?.message,
|
|
20595
|
+
target: targetEvidence(context.client.provider, requestedModel)
|
|
20596
|
+
};
|
|
20597
|
+
}
|
|
20598
|
+
function withAttemptEvidence(result, priorAttempts, input) {
|
|
20599
|
+
return {
|
|
20600
|
+
...result,
|
|
20601
|
+
attempts: input.attemptNumber,
|
|
20602
|
+
attempt_evidence: [
|
|
20603
|
+
...priorAttempts,
|
|
20604
|
+
{
|
|
20605
|
+
attempt_id: `${input.retryChainId}:${input.attemptNumber}`,
|
|
20606
|
+
retry_chain_id: input.retryChainId,
|
|
20607
|
+
repetition_index: input.repetitionIndex,
|
|
20608
|
+
attempt_number: input.attemptNumber,
|
|
20609
|
+
status: getTerminalStatus(result),
|
|
20610
|
+
included_in_outcome: input.includedInOutcome,
|
|
20611
|
+
latency_ms: input.latencyMs,
|
|
20612
|
+
...input.errorCode ? { error_code: input.errorCode } : {}
|
|
20613
|
+
}
|
|
20614
|
+
]
|
|
20559
20615
|
};
|
|
20560
20616
|
}
|
|
20617
|
+
function getTerminalStatus(result) {
|
|
20618
|
+
return result.status ?? (result.ok ? "passed" : result.error ? "error" : "failed");
|
|
20619
|
+
}
|
|
20561
20620
|
async function executeCaseAttempt(testCase, context, timeout) {
|
|
20562
|
-
const { client, scenario, redaction: cliRedaction, toolExecutor } = context;
|
|
20621
|
+
const { client, scenario, requestedModel, redaction: cliRedaction, toolExecutor } = context;
|
|
20563
20622
|
const variables = mergeVariables(scenario.variables, testCase.variables);
|
|
20564
20623
|
let prompt = substituteVariables(testCase.prompt, variables);
|
|
20565
20624
|
if (scenario.setup?.systemPrompt && typeof prompt === "string") {
|
|
@@ -20577,7 +20636,7 @@ async function executeCaseAttempt(testCase, context, timeout) {
|
|
|
20577
20636
|
const loopPrompt = typeof prompt === "string" ? [{ role: "user", content: prompt }] : prompt;
|
|
20578
20637
|
const generate = () => client.generate({
|
|
20579
20638
|
prompt: loopPrompt,
|
|
20580
|
-
model: testCase.model || scenario.model,
|
|
20639
|
+
model: testCase.model || requestedModel || scenario.model,
|
|
20581
20640
|
temperature: scenario.temperature,
|
|
20582
20641
|
maxTokens: scenario.maxTokens,
|
|
20583
20642
|
seed: scenario.seed,
|
|
@@ -20585,6 +20644,7 @@ async function executeCaseAttempt(testCase, context, timeout) {
|
|
|
20585
20644
|
});
|
|
20586
20645
|
const generatePromise = generate();
|
|
20587
20646
|
let result = timeout ? await Promise.race([generatePromise, createTimeout(timeout)]) : await generatePromise;
|
|
20647
|
+
const observedModels = [result.model];
|
|
20588
20648
|
const generationMetrics = {
|
|
20589
20649
|
latencyMs: result.latencyMs,
|
|
20590
20650
|
tokens: { ...result.tokens }
|
|
@@ -20595,7 +20655,7 @@ async function executeCaseAttempt(testCase, context, timeout) {
|
|
|
20595
20655
|
status: "error",
|
|
20596
20656
|
steps: 0,
|
|
20597
20657
|
terminationReason: "tool_error"
|
|
20598
|
-
}, generationMetrics, "TOOL_EXECUTOR_REQUIRED");
|
|
20658
|
+
}, generationMetrics, "TOOL_EXECUTOR_REQUIRED", targetEvidence(client.provider, testCase.model || requestedModel || scenario.model, observedModels));
|
|
20599
20659
|
}
|
|
20600
20660
|
const executor = toolExecutor ?? new FixtureToolExecutor({
|
|
20601
20661
|
tools,
|
|
@@ -20614,7 +20674,7 @@ async function executeCaseAttempt(testCase, context, timeout) {
|
|
|
20614
20674
|
status: "error",
|
|
20615
20675
|
steps: step,
|
|
20616
20676
|
terminationReason: "duplicate_call"
|
|
20617
|
-
}, generationMetrics, "TOOL_DUPLICATE_CALL");
|
|
20677
|
+
}, generationMetrics, "TOOL_DUPLICATE_CALL", targetEvidence(client.provider, testCase.model || requestedModel || scenario.model, observedModels));
|
|
20618
20678
|
}
|
|
20619
20679
|
seenCalls.add(fingerprint);
|
|
20620
20680
|
const toolStart = Date.now();
|
|
@@ -20641,7 +20701,7 @@ async function executeCaseAttempt(testCase, context, timeout) {
|
|
|
20641
20701
|
status: "error",
|
|
20642
20702
|
steps: step + 1,
|
|
20643
20703
|
terminationReason: execution.error?.code === "TOOL_UNKNOWN" ? "unknown_tool" : execution.error?.code?.startsWith("TOOL_ARGUMENTS") ? "invalid_arguments" : "tool_error"
|
|
20644
|
-
}, generationMetrics, execution.error?.code ?? "TOOL_EXECUTION_FAILED");
|
|
20704
|
+
}, generationMetrics, execution.error?.code ?? "TOOL_EXECUTION_FAILED", targetEvidence(client.provider, testCase.model || requestedModel || scenario.model, observedModels));
|
|
20645
20705
|
}
|
|
20646
20706
|
const content = JSON.stringify(execution.result ?? {});
|
|
20647
20707
|
loopPrompt.push({
|
|
@@ -20653,7 +20713,7 @@ async function executeCaseAttempt(testCase, context, timeout) {
|
|
|
20653
20713
|
}
|
|
20654
20714
|
const remainingLoopTime = policy.timeoutMs - (Date.now() - loopStartedAt);
|
|
20655
20715
|
if (remainingLoopTime <= 0) {
|
|
20656
|
-
throw createToolLoopError(testCase, toolTrace, { status: "error", steps: step + 1, terminationReason: "timeout" }, generationMetrics, "TOOL_LOOP_TIMEOUT");
|
|
20716
|
+
throw createToolLoopError(testCase, toolTrace, { status: "error", steps: step + 1, terminationReason: "timeout" }, generationMetrics, "TOOL_LOOP_TIMEOUT", targetEvidence(client.provider, testCase.model || requestedModel || scenario.model, observedModels));
|
|
20657
20717
|
}
|
|
20658
20718
|
const requestTimeout = timeout ? Math.min(timeout, remainingLoopTime) : remainingLoopTime;
|
|
20659
20719
|
try {
|
|
@@ -20664,8 +20724,9 @@ async function executeCaseAttempt(testCase, context, timeout) {
|
|
|
20664
20724
|
status: "error",
|
|
20665
20725
|
steps: step + 1,
|
|
20666
20726
|
terminationReason: timedOut ? "timeout" : "tool_error"
|
|
20667
|
-
}, generationMetrics, timedOut ? "TOOL_LOOP_TIMEOUT" : "TOOL_GENERATION_FAILED");
|
|
20727
|
+
}, generationMetrics, timedOut ? "TOOL_LOOP_TIMEOUT" : "TOOL_GENERATION_FAILED", targetEvidence(client.provider, testCase.model || requestedModel || scenario.model, observedModels));
|
|
20668
20728
|
}
|
|
20729
|
+
observedModels.push(result.model);
|
|
20669
20730
|
generationMetrics.latencyMs += result.latencyMs;
|
|
20670
20731
|
generationMetrics.tokens.prompt += result.tokens.prompt;
|
|
20671
20732
|
generationMetrics.tokens.completion += result.tokens.completion;
|
|
@@ -20676,7 +20737,7 @@ async function executeCaseAttempt(testCase, context, timeout) {
|
|
|
20676
20737
|
status: "error",
|
|
20677
20738
|
steps: policy.maxSteps,
|
|
20678
20739
|
terminationReason: "max_steps"
|
|
20679
|
-
}, generationMetrics, "TOOL_LOOP_MAX_STEPS");
|
|
20740
|
+
}, generationMetrics, "TOOL_LOOP_MAX_STEPS", targetEvidence(client.provider, testCase.model || requestedModel || scenario.model, observedModels));
|
|
20680
20741
|
}
|
|
20681
20742
|
toolLoop = { status: "completed", steps: toolTrace.length, terminationReason: "completed" };
|
|
20682
20743
|
}
|
|
@@ -20772,11 +20833,22 @@ async function executeCaseAttempt(testCase, context, timeout) {
|
|
|
20772
20833
|
tags: testCase.tags,
|
|
20773
20834
|
redaction: redactionInfo,
|
|
20774
20835
|
evidence: finalEvidence,
|
|
20836
|
+
target: targetEvidence(client.provider, testCase.model || requestedModel || scenario.model, observedModels),
|
|
20775
20837
|
toolTrace: toolTrace.length ? toolTrace : undefined,
|
|
20776
20838
|
toolLoop
|
|
20777
20839
|
};
|
|
20778
20840
|
}
|
|
20779
|
-
function
|
|
20841
|
+
function targetEvidence(provider, requestedModel, observedModels) {
|
|
20842
|
+
const observed = [
|
|
20843
|
+
...new Set((observedModels ?? []).filter((model) => typeof model === "string" && model.length > 0))
|
|
20844
|
+
].map((model) => sanitizeArtifactText(model, 200)).filter((model) => Boolean(model));
|
|
20845
|
+
return {
|
|
20846
|
+
provider: sanitizeArtifactText(provider, 100) ?? "unknown",
|
|
20847
|
+
...requestedModel ? { requested_model: sanitizeArtifactText(requestedModel, 200) } : {},
|
|
20848
|
+
...observed.length ? { observed_models: observed } : {}
|
|
20849
|
+
};
|
|
20850
|
+
}
|
|
20851
|
+
function createToolLoopError(testCase, toolTrace, toolLoop, generationMetrics, code, target) {
|
|
20780
20852
|
return new ToolLoopError(code, {
|
|
20781
20853
|
id: testCase.id,
|
|
20782
20854
|
name: testCase.name,
|
|
@@ -20792,6 +20864,7 @@ function createToolLoopError(testCase, toolTrace, toolLoop, generationMetrics, c
|
|
|
20792
20864
|
expected: testCase.expected,
|
|
20793
20865
|
tags: testCase.tags,
|
|
20794
20866
|
error: code,
|
|
20867
|
+
target,
|
|
20795
20868
|
toolTrace,
|
|
20796
20869
|
toolLoop
|
|
20797
20870
|
});
|
|
@@ -20912,374 +20985,61 @@ function nanoid(size = 21) {
|
|
|
20912
20985
|
return id;
|
|
20913
20986
|
}
|
|
20914
20987
|
|
|
20915
|
-
// src/
|
|
20916
|
-
|
|
20917
|
-
|
|
20918
|
-
|
|
20919
|
-
|
|
20920
|
-
|
|
20921
|
-
|
|
20922
|
-
|
|
20923
|
-
|
|
20924
|
-
|
|
20925
|
-
|
|
20926
|
-
|
|
20927
|
-
|
|
20928
|
-
|
|
20929
|
-
|
|
20930
|
-
|
|
20931
|
-
|
|
20932
|
-
|
|
20933
|
-
|
|
20934
|
-
|
|
20935
|
-
|
|
20936
|
-
|
|
20937
|
-
|
|
20938
|
-
|
|
20939
|
-
|
|
20940
|
-
|
|
20941
|
-
|
|
20942
|
-
|
|
20943
|
-
|
|
20944
|
-
promptPer1K: 0.002,
|
|
20945
|
-
completionPer1K: 0.008,
|
|
20946
|
-
lastUpdated: "2026-01",
|
|
20947
|
-
notes: "1M context window"
|
|
20948
|
-
},
|
|
20949
|
-
"gpt-4.1-mini": {
|
|
20950
|
-
promptPer1K: 0.0004,
|
|
20951
|
-
completionPer1K: 0.0016,
|
|
20952
|
-
lastUpdated: "2026-01"
|
|
20953
|
-
},
|
|
20954
|
-
"gpt-4.1-nano": {
|
|
20955
|
-
promptPer1K: 0.0001,
|
|
20956
|
-
completionPer1K: 0.0004,
|
|
20957
|
-
lastUpdated: "2026-01"
|
|
20958
|
-
},
|
|
20959
|
-
"gpt-4o": {
|
|
20960
|
-
promptPer1K: 0.0025,
|
|
20961
|
-
completionPer1K: 0.01,
|
|
20962
|
-
lastUpdated: "2026-01",
|
|
20963
|
-
notes: "128K context window"
|
|
20964
|
-
},
|
|
20965
|
-
"gpt-4o-mini": {
|
|
20966
|
-
promptPer1K: 0.00015,
|
|
20967
|
-
completionPer1K: 0.0006,
|
|
20968
|
-
lastUpdated: "2026-01",
|
|
20969
|
-
notes: "128K context window"
|
|
20970
|
-
},
|
|
20971
|
-
o1: {
|
|
20972
|
-
promptPer1K: 0.015,
|
|
20973
|
-
completionPer1K: 0.06,
|
|
20974
|
-
lastUpdated: "2026-01",
|
|
20975
|
-
notes: "Reasoning model - internal thinking tokens billed as output"
|
|
20976
|
-
},
|
|
20977
|
-
o3: {
|
|
20978
|
-
promptPer1K: 0.002,
|
|
20979
|
-
completionPer1K: 0.008,
|
|
20980
|
-
lastUpdated: "2026-01"
|
|
20981
|
-
},
|
|
20982
|
-
"o3-mini": {
|
|
20983
|
-
promptPer1K: 0.0011,
|
|
20984
|
-
completionPer1K: 0.0044,
|
|
20985
|
-
lastUpdated: "2026-01"
|
|
20986
|
-
},
|
|
20987
|
-
"o4-mini": {
|
|
20988
|
-
promptPer1K: 0.0011,
|
|
20989
|
-
completionPer1K: 0.0044,
|
|
20990
|
-
lastUpdated: "2026-01"
|
|
20991
|
-
},
|
|
20992
|
-
"gpt-4-turbo": {
|
|
20993
|
-
promptPer1K: 0.01,
|
|
20994
|
-
completionPer1K: 0.03,
|
|
20995
|
-
lastUpdated: "2026-01"
|
|
20996
|
-
},
|
|
20997
|
-
"gpt-4": {
|
|
20998
|
-
promptPer1K: 0.03,
|
|
20999
|
-
completionPer1K: 0.06,
|
|
21000
|
-
lastUpdated: "2026-01"
|
|
21001
|
-
},
|
|
21002
|
-
"gpt-3.5-turbo": {
|
|
21003
|
-
promptPer1K: 0.0005,
|
|
21004
|
-
completionPer1K: 0.0015,
|
|
21005
|
-
lastUpdated: "2026-01"
|
|
21006
|
-
},
|
|
21007
|
-
"claude-opus-4.5": {
|
|
21008
|
-
promptPer1K: 0.005,
|
|
21009
|
-
completionPer1K: 0.025,
|
|
21010
|
-
lastUpdated: "2026-01",
|
|
21011
|
-
notes: "Most capable Claude model"
|
|
21012
|
-
},
|
|
21013
|
-
"claude-sonnet-4.5": {
|
|
21014
|
-
promptPer1K: 0.003,
|
|
21015
|
-
completionPer1K: 0.015,
|
|
21016
|
-
lastUpdated: "2026-01",
|
|
21017
|
-
notes: "Balanced performance and cost"
|
|
21018
|
-
},
|
|
21019
|
-
"claude-haiku-4.5": {
|
|
21020
|
-
promptPer1K: 0.001,
|
|
21021
|
-
completionPer1K: 0.005,
|
|
21022
|
-
lastUpdated: "2026-01",
|
|
21023
|
-
notes: "Fastest Claude model"
|
|
21024
|
-
},
|
|
21025
|
-
"claude-opus-4": {
|
|
21026
|
-
promptPer1K: 0.015,
|
|
21027
|
-
completionPer1K: 0.075,
|
|
21028
|
-
lastUpdated: "2026-01"
|
|
21029
|
-
},
|
|
21030
|
-
"claude-opus-4.1": {
|
|
21031
|
-
promptPer1K: 0.015,
|
|
21032
|
-
completionPer1K: 0.075,
|
|
21033
|
-
lastUpdated: "2026-01"
|
|
21034
|
-
},
|
|
21035
|
-
"claude-sonnet-4": {
|
|
21036
|
-
promptPer1K: 0.003,
|
|
21037
|
-
completionPer1K: 0.015,
|
|
21038
|
-
lastUpdated: "2026-01"
|
|
21039
|
-
},
|
|
21040
|
-
"claude-sonnet-3.7": {
|
|
21041
|
-
promptPer1K: 0.003,
|
|
21042
|
-
completionPer1K: 0.015,
|
|
21043
|
-
lastUpdated: "2026-01"
|
|
21044
|
-
},
|
|
21045
|
-
"claude-3-7-sonnet": {
|
|
21046
|
-
promptPer1K: 0.003,
|
|
21047
|
-
completionPer1K: 0.015,
|
|
21048
|
-
lastUpdated: "2026-01"
|
|
21049
|
-
},
|
|
21050
|
-
"claude-3-5-sonnet-20241022": {
|
|
21051
|
-
promptPer1K: 0.003,
|
|
21052
|
-
completionPer1K: 0.015,
|
|
21053
|
-
lastUpdated: "2026-01"
|
|
21054
|
-
},
|
|
21055
|
-
"claude-3-5-haiku-20241022": {
|
|
21056
|
-
promptPer1K: 0.0008,
|
|
21057
|
-
completionPer1K: 0.004,
|
|
21058
|
-
lastUpdated: "2026-01"
|
|
21059
|
-
},
|
|
21060
|
-
"claude-haiku-3.5": {
|
|
21061
|
-
promptPer1K: 0.0008,
|
|
21062
|
-
completionPer1K: 0.004,
|
|
21063
|
-
lastUpdated: "2026-01"
|
|
21064
|
-
},
|
|
21065
|
-
"claude-3-opus": {
|
|
21066
|
-
promptPer1K: 0.015,
|
|
21067
|
-
completionPer1K: 0.075,
|
|
21068
|
-
lastUpdated: "2026-01"
|
|
21069
|
-
},
|
|
21070
|
-
"claude-3-sonnet": {
|
|
21071
|
-
promptPer1K: 0.003,
|
|
21072
|
-
completionPer1K: 0.015,
|
|
21073
|
-
lastUpdated: "2026-01"
|
|
21074
|
-
},
|
|
21075
|
-
"claude-3-haiku": {
|
|
21076
|
-
promptPer1K: 0.00025,
|
|
21077
|
-
completionPer1K: 0.00125,
|
|
21078
|
-
lastUpdated: "2026-01"
|
|
21079
|
-
},
|
|
21080
|
-
"claude-3.5-sonnet": {
|
|
21081
|
-
promptPer1K: 0.003,
|
|
21082
|
-
completionPer1K: 0.015,
|
|
21083
|
-
lastUpdated: "2026-01"
|
|
21084
|
-
},
|
|
21085
|
-
"claude-3.5-haiku": {
|
|
21086
|
-
promptPer1K: 0.0008,
|
|
21087
|
-
completionPer1K: 0.004,
|
|
21088
|
-
lastUpdated: "2026-01"
|
|
21089
|
-
}
|
|
21090
|
-
};
|
|
21091
|
-
var DEFAULT_PRICING = {
|
|
21092
|
-
promptPer1K: 0.003,
|
|
21093
|
-
completionPer1K: 0.015,
|
|
21094
|
-
lastUpdated: "2026-01",
|
|
21095
|
-
notes: "Default pricing - verify with provider"
|
|
21096
|
-
};
|
|
21097
|
-
function getModelPricing(model) {
|
|
21098
|
-
if (MODEL_PRICING[model]) {
|
|
21099
|
-
return MODEL_PRICING[model];
|
|
20988
|
+
// src/provenance/environment.ts
|
|
20989
|
+
function getEnvironmentInfo() {
|
|
20990
|
+
return {
|
|
20991
|
+
node_version: process.version,
|
|
20992
|
+
platform: process.platform,
|
|
20993
|
+
arch: process.arch
|
|
20994
|
+
};
|
|
20995
|
+
}
|
|
20996
|
+
|
|
20997
|
+
// src/provenance/git.ts
|
|
20998
|
+
import { execSync } from "child_process";
|
|
20999
|
+
function getGitInfo() {
|
|
21000
|
+
try {
|
|
21001
|
+
const commit = execGit("rev-parse HEAD");
|
|
21002
|
+
const branch = execGit("rev-parse --abbrev-ref HEAD");
|
|
21003
|
+
const dirty = execGit("status --porcelain").length > 0;
|
|
21004
|
+
const remote = execGit("remote get-url origin", true);
|
|
21005
|
+
return {
|
|
21006
|
+
commit,
|
|
21007
|
+
branch,
|
|
21008
|
+
dirty,
|
|
21009
|
+
remote: remote || undefined
|
|
21010
|
+
};
|
|
21011
|
+
} catch {
|
|
21012
|
+
return {
|
|
21013
|
+
commit: "unknown",
|
|
21014
|
+
branch: "unknown",
|
|
21015
|
+
dirty: false
|
|
21016
|
+
};
|
|
21100
21017
|
}
|
|
21101
|
-
|
|
21102
|
-
|
|
21103
|
-
|
|
21104
|
-
|
|
21018
|
+
}
|
|
21019
|
+
function execGit(command, allowFailure = false) {
|
|
21020
|
+
try {
|
|
21021
|
+
return execSync(`git ${command}`, {
|
|
21022
|
+
encoding: "utf-8",
|
|
21023
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
21024
|
+
}).trim();
|
|
21025
|
+
} catch {
|
|
21026
|
+
if (allowFailure) {
|
|
21027
|
+
return "";
|
|
21105
21028
|
}
|
|
21029
|
+
throw new Error(`Git command failed: ${command}`);
|
|
21106
21030
|
}
|
|
21107
|
-
|
|
21108
|
-
|
|
21109
|
-
|
|
21110
|
-
|
|
21111
|
-
|
|
21112
|
-
|
|
21113
|
-
|
|
21114
|
-
|
|
21115
|
-
|
|
21116
|
-
|
|
21117
|
-
|
|
21118
|
-
|
|
21119
|
-
if (lowerModel.includes("gpt-5")) {
|
|
21120
|
-
return MODEL_PRICING["gpt-5"];
|
|
21121
|
-
}
|
|
21122
|
-
if (lowerModel.includes("gpt-4.1-mini")) {
|
|
21123
|
-
return MODEL_PRICING["gpt-4.1-mini"];
|
|
21124
|
-
}
|
|
21125
|
-
if (lowerModel.includes("gpt-4.1-nano")) {
|
|
21126
|
-
return MODEL_PRICING["gpt-4.1-nano"];
|
|
21127
|
-
}
|
|
21128
|
-
if (lowerModel.includes("gpt-4.1")) {
|
|
21129
|
-
return MODEL_PRICING["gpt-4.1"];
|
|
21130
|
-
}
|
|
21131
|
-
if (lowerModel.includes("gpt-4o-mini")) {
|
|
21132
|
-
return MODEL_PRICING["gpt-4o-mini"];
|
|
21133
|
-
}
|
|
21134
|
-
if (lowerModel.includes("gpt-4o")) {
|
|
21135
|
-
return MODEL_PRICING["gpt-4o"];
|
|
21136
|
-
}
|
|
21137
|
-
if (lowerModel.includes("o4-mini")) {
|
|
21138
|
-
return MODEL_PRICING["o4-mini"];
|
|
21139
|
-
}
|
|
21140
|
-
if (lowerModel.includes("o3-mini")) {
|
|
21141
|
-
return MODEL_PRICING["o3-mini"];
|
|
21142
|
-
}
|
|
21143
|
-
if (lowerModel.includes("o3")) {
|
|
21144
|
-
return MODEL_PRICING.o3;
|
|
21145
|
-
}
|
|
21146
|
-
if (lowerModel.includes("o1")) {
|
|
21147
|
-
return MODEL_PRICING.o1;
|
|
21148
|
-
}
|
|
21149
|
-
if (lowerModel.includes("gpt-4-turbo")) {
|
|
21150
|
-
return MODEL_PRICING["gpt-4-turbo"];
|
|
21151
|
-
}
|
|
21152
|
-
if (lowerModel.includes("gpt-4")) {
|
|
21153
|
-
return MODEL_PRICING["gpt-4"];
|
|
21154
|
-
}
|
|
21155
|
-
if (lowerModel.includes("gpt-3.5")) {
|
|
21156
|
-
return MODEL_PRICING["gpt-3.5-turbo"];
|
|
21157
|
-
}
|
|
21158
|
-
if (lowerModel.includes("opus-4.5") || lowerModel.includes("opus-4-5")) {
|
|
21159
|
-
return MODEL_PRICING["claude-opus-4.5"];
|
|
21160
|
-
}
|
|
21161
|
-
if (lowerModel.includes("sonnet-4.5") || lowerModel.includes("sonnet-4-5")) {
|
|
21162
|
-
return MODEL_PRICING["claude-sonnet-4.5"];
|
|
21163
|
-
}
|
|
21164
|
-
if (lowerModel.includes("haiku-4.5") || lowerModel.includes("haiku-4-5")) {
|
|
21165
|
-
return MODEL_PRICING["claude-haiku-4.5"];
|
|
21166
|
-
}
|
|
21167
|
-
if (lowerModel.includes("opus-4.1") || lowerModel.includes("opus-4-1")) {
|
|
21168
|
-
return MODEL_PRICING["claude-opus-4.1"];
|
|
21169
|
-
}
|
|
21170
|
-
if (lowerModel.includes("opus-4")) {
|
|
21171
|
-
return MODEL_PRICING["claude-opus-4"];
|
|
21172
|
-
}
|
|
21173
|
-
if (lowerModel.includes("sonnet-4")) {
|
|
21174
|
-
return MODEL_PRICING["claude-sonnet-4"];
|
|
21175
|
-
}
|
|
21176
|
-
if (lowerModel.includes("sonnet-3.7") || lowerModel.includes("sonnet-3-7")) {
|
|
21177
|
-
return MODEL_PRICING["claude-sonnet-3.7"];
|
|
21178
|
-
}
|
|
21179
|
-
if (lowerModel.includes("claude-3-5-sonnet") || lowerModel.includes("claude-3.5-sonnet")) {
|
|
21180
|
-
return MODEL_PRICING["claude-3.5-sonnet"];
|
|
21181
|
-
}
|
|
21182
|
-
if (lowerModel.includes("claude-3-5-haiku") || lowerModel.includes("claude-3.5-haiku")) {
|
|
21183
|
-
return MODEL_PRICING["claude-3.5-haiku"];
|
|
21184
|
-
}
|
|
21185
|
-
if (lowerModel.includes("claude-3-opus")) {
|
|
21186
|
-
return MODEL_PRICING["claude-3-opus"];
|
|
21187
|
-
}
|
|
21188
|
-
if (lowerModel.includes("claude-3-sonnet")) {
|
|
21189
|
-
return MODEL_PRICING["claude-3-sonnet"];
|
|
21190
|
-
}
|
|
21191
|
-
if (lowerModel.includes("claude-3-haiku")) {
|
|
21192
|
-
return MODEL_PRICING["claude-3-haiku"];
|
|
21193
|
-
}
|
|
21194
|
-
if (lowerModel.includes("claude")) {
|
|
21195
|
-
return MODEL_PRICING["claude-sonnet-4.5"];
|
|
21196
|
-
}
|
|
21197
|
-
return DEFAULT_PRICING;
|
|
21198
|
-
}
|
|
21199
|
-
function estimateCost(promptTokens, completionTokens, model) {
|
|
21200
|
-
const pricing = getModelPricing(model);
|
|
21201
|
-
const promptCostUsd = promptTokens / 1000 * pricing.promptPer1K;
|
|
21202
|
-
const completionCostUsd = completionTokens / 1000 * pricing.completionPer1K;
|
|
21203
|
-
const totalUsd = promptCostUsd + completionCostUsd;
|
|
21204
|
-
return {
|
|
21205
|
-
totalUsd,
|
|
21206
|
-
promptCostUsd,
|
|
21207
|
-
completionCostUsd,
|
|
21208
|
-
model,
|
|
21209
|
-
pricing
|
|
21210
|
-
};
|
|
21211
|
-
}
|
|
21212
|
-
function formatCost(costUsd) {
|
|
21213
|
-
if (costUsd < 0.01) {
|
|
21214
|
-
return `$${(costUsd * 100).toFixed(4)} cents`;
|
|
21215
|
-
}
|
|
21216
|
-
if (costUsd < 1) {
|
|
21217
|
-
return `$${costUsd.toFixed(4)}`;
|
|
21218
|
-
}
|
|
21219
|
-
return `$${costUsd.toFixed(2)}`;
|
|
21220
|
-
}
|
|
21221
|
-
function listKnownModels() {
|
|
21222
|
-
return Object.entries(MODEL_PRICING).map(([model, pricing]) => ({
|
|
21223
|
-
model,
|
|
21224
|
-
pricing
|
|
21225
|
-
}));
|
|
21226
|
-
}
|
|
21227
|
-
|
|
21228
|
-
// src/provenance/environment.ts
|
|
21229
|
-
function getEnvironmentInfo() {
|
|
21230
|
-
return {
|
|
21231
|
-
node_version: process.version,
|
|
21232
|
-
platform: process.platform,
|
|
21233
|
-
arch: process.arch
|
|
21234
|
-
};
|
|
21235
|
-
}
|
|
21236
|
-
|
|
21237
|
-
// src/provenance/git.ts
|
|
21238
|
-
import { execSync } from "child_process";
|
|
21239
|
-
function getGitInfo() {
|
|
21240
|
-
try {
|
|
21241
|
-
const commit = execGit("rev-parse HEAD");
|
|
21242
|
-
const branch = execGit("rev-parse --abbrev-ref HEAD");
|
|
21243
|
-
const dirty = execGit("status --porcelain").length > 0;
|
|
21244
|
-
const remote = execGit("remote get-url origin", true);
|
|
21245
|
-
return {
|
|
21246
|
-
commit,
|
|
21247
|
-
branch,
|
|
21248
|
-
dirty,
|
|
21249
|
-
remote: remote || undefined
|
|
21250
|
-
};
|
|
21251
|
-
} catch {
|
|
21252
|
-
return {
|
|
21253
|
-
commit: "unknown",
|
|
21254
|
-
branch: "unknown",
|
|
21255
|
-
dirty: false
|
|
21256
|
-
};
|
|
21257
|
-
}
|
|
21258
|
-
}
|
|
21259
|
-
function execGit(command, allowFailure = false) {
|
|
21260
|
-
try {
|
|
21261
|
-
return execSync(`git ${command}`, {
|
|
21262
|
-
encoding: "utf-8",
|
|
21263
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
21264
|
-
}).trim();
|
|
21265
|
-
} catch {
|
|
21266
|
-
if (allowFailure) {
|
|
21267
|
-
return "";
|
|
21268
|
-
}
|
|
21269
|
-
throw new Error(`Git command failed: ${command}`);
|
|
21270
|
-
}
|
|
21271
|
-
}
|
|
21272
|
-
|
|
21273
|
-
// src/artifacts/types.ts
|
|
21274
|
-
var CASE_EVALUATION_STATUS_LABELS = {
|
|
21275
|
-
passed: "Passed",
|
|
21276
|
-
failed: "Failed criteria",
|
|
21277
|
-
invalid: "Invalid measurement",
|
|
21278
|
-
error: "Execution error"
|
|
21279
|
-
};
|
|
21280
|
-
function getCaseEvaluationStatus(caseResult) {
|
|
21281
|
-
if (caseResult.status === "passed" || caseResult.status === "failed" || caseResult.status === "invalid" || caseResult.status === "error") {
|
|
21282
|
-
return caseResult.status;
|
|
21031
|
+
}
|
|
21032
|
+
|
|
21033
|
+
// src/artifacts/types.ts
|
|
21034
|
+
var CASE_EVALUATION_STATUS_LABELS = {
|
|
21035
|
+
passed: "Passed",
|
|
21036
|
+
failed: "Failed criteria",
|
|
21037
|
+
invalid: "Invalid measurement",
|
|
21038
|
+
error: "Execution error"
|
|
21039
|
+
};
|
|
21040
|
+
function getCaseEvaluationStatus(caseResult) {
|
|
21041
|
+
if (caseResult.status === "passed" || caseResult.status === "failed" || caseResult.status === "invalid" || caseResult.status === "error") {
|
|
21042
|
+
return caseResult.status;
|
|
21283
21043
|
}
|
|
21284
21044
|
if (caseResult.ok)
|
|
21285
21045
|
return "passed";
|
|
@@ -21295,6 +21055,15 @@ function assertRunManifestIntegrity(manifest) {
|
|
|
21295
21055
|
if (manifest.workload_identity !== undefined) {
|
|
21296
21056
|
assertWorkloadIdentity(manifest.workload_identity);
|
|
21297
21057
|
}
|
|
21058
|
+
if (manifest.execution_provenance !== undefined) {
|
|
21059
|
+
assertExecutionProvenance(manifest.execution_provenance);
|
|
21060
|
+
}
|
|
21061
|
+
if (manifest.attempt_evidence !== undefined) {
|
|
21062
|
+
assertRunAttemptEvidence(manifest.attempt_evidence);
|
|
21063
|
+
}
|
|
21064
|
+
if (isRecord2(manifest.metrics) && manifest.metrics.cost_provenance !== undefined) {
|
|
21065
|
+
assertCostProvenance(manifest.metrics.cost_provenance);
|
|
21066
|
+
}
|
|
21298
21067
|
for (const [index, caseResult] of manifest.cases.entries()) {
|
|
21299
21068
|
if (!isRecord2(caseResult)) {
|
|
21300
21069
|
throw new Error(`Invalid run manifest: case ${index} is not an object`);
|
|
@@ -21305,8 +21074,91 @@ function assertRunManifestIntegrity(manifest) {
|
|
|
21305
21074
|
if (caseResult.evidence !== undefined) {
|
|
21306
21075
|
assertCaseEvaluationEvidence(caseResult.evidence, index);
|
|
21307
21076
|
}
|
|
21077
|
+
if (caseResult.target !== undefined) {
|
|
21078
|
+
assertCaseTargetEvidence(caseResult.target);
|
|
21079
|
+
}
|
|
21080
|
+
if (caseResult.attempt_evidence !== undefined) {
|
|
21081
|
+
assertCaseAttemptEvidence(caseResult.attempt_evidence, index);
|
|
21082
|
+
}
|
|
21083
|
+
}
|
|
21084
|
+
}
|
|
21085
|
+
function assertRunAttemptEvidence(evidence) {
|
|
21086
|
+
if (!isRecord2(evidence) || evidence.schema_version !== "1" || !isRecord2(evidence.repetition) || !isPositiveSafeInteger(evidence.repetition.index) || !isPositiveSafeInteger(evidence.repetition.total) || evidence.repetition.index > evidence.repetition.total || !isRecord2(evidence.retry_policy) || !isNonnegativeSafeInteger(evidence.retry_policy.default_max_retries) || evidence.retry_policy.backoff !== "exponential" || !isNonnegativeFiniteNumber(evidence.retry_policy.initial_delay_ms) || evidence.timeout !== undefined && (!isRecord2(evidence.timeout) || !isPositiveFiniteNumber(evidence.timeout.default_ms))) {
|
|
21087
|
+
throw new Error("Invalid run manifest: malformed attempt evidence");
|
|
21088
|
+
}
|
|
21089
|
+
}
|
|
21090
|
+
function assertCaseAttemptEvidence(evidence, index) {
|
|
21091
|
+
if (!Array.isArray(evidence) || evidence.length === 0 || evidence.length > 100) {
|
|
21092
|
+
throw new Error(`Invalid run manifest: case ${index} has malformed attempt evidence`);
|
|
21093
|
+
}
|
|
21094
|
+
for (const attempt of evidence) {
|
|
21095
|
+
if (!isRecord2(attempt) || !isBoundedNonemptyString(attempt.attempt_id, 200) || !isBoundedNonemptyString(attempt.retry_chain_id, 200) || !isPositiveSafeInteger(attempt.repetition_index) || !isPositiveSafeInteger(attempt.attempt_number) || !isCaseEvaluationStatus(attempt.status) || typeof attempt.included_in_outcome !== "boolean" || !isNonnegativeFiniteNumber(attempt.latency_ms) || attempt.error_code !== undefined && attempt.error_code !== "timeout" && attempt.error_code !== "target_error" && attempt.error_code !== "tool_error") {
|
|
21096
|
+
throw new Error(`Invalid run manifest: case ${index} has malformed attempt evidence`);
|
|
21097
|
+
}
|
|
21098
|
+
}
|
|
21099
|
+
}
|
|
21100
|
+
function assertCostProvenance(cost) {
|
|
21101
|
+
if (!isRecord2(cost) || cost.schema_version !== "1") {
|
|
21102
|
+
throw new Error("Invalid run manifest: malformed cost provenance");
|
|
21103
|
+
}
|
|
21104
|
+
if (cost.status === "unavailable") {
|
|
21105
|
+
if (cost.amount !== undefined || cost.currency !== undefined || cost.source !== undefined || cost.recorded_at !== undefined || cost.unavailable_reason !== "provider_billing_not_recorded" && cost.unavailable_reason !== "unsupported_provider" && cost.unavailable_reason !== "not_requested") {
|
|
21106
|
+
throw new Error("Invalid run manifest: malformed cost provenance");
|
|
21107
|
+
}
|
|
21108
|
+
return;
|
|
21109
|
+
}
|
|
21110
|
+
if (cost.status !== "known" && cost.status !== "user_supplied" || !isNonnegativeFiniteNumber(cost.amount) || !isBoundedNonemptyString(cost.currency, 3) || cost.status === "known" && cost.source !== "provider_billing" || cost.status === "user_supplied" && cost.source !== "operator_input" || !isIsoTimestamp(cost.recorded_at) || cost.unavailable_reason !== undefined) {
|
|
21111
|
+
throw new Error("Invalid run manifest: malformed cost provenance");
|
|
21112
|
+
}
|
|
21113
|
+
}
|
|
21114
|
+
function isCaseEvaluationStatus(value) {
|
|
21115
|
+
return value === "passed" || value === "failed" || value === "invalid" || value === "error";
|
|
21116
|
+
}
|
|
21117
|
+
function isBoundedNonemptyString(value, maxLength) {
|
|
21118
|
+
return typeof value === "string" && value.length > 0 && value.length <= maxLength;
|
|
21119
|
+
}
|
|
21120
|
+
function isNonnegativeFiniteNumber(value) {
|
|
21121
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0;
|
|
21122
|
+
}
|
|
21123
|
+
function isPositiveFiniteNumber(value) {
|
|
21124
|
+
return isNonnegativeFiniteNumber(value) && value > 0;
|
|
21125
|
+
}
|
|
21126
|
+
function isNonnegativeSafeInteger(value) {
|
|
21127
|
+
return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
|
|
21128
|
+
}
|
|
21129
|
+
function isPositiveSafeInteger(value) {
|
|
21130
|
+
return isNonnegativeSafeInteger(value) && value > 0;
|
|
21131
|
+
}
|
|
21132
|
+
function isIsoTimestamp(value) {
|
|
21133
|
+
return typeof value === "string" && Number.isFinite(Date.parse(value));
|
|
21134
|
+
}
|
|
21135
|
+
function assertCaseTargetEvidence(target) {
|
|
21136
|
+
if (!isRecord2(target) || typeof target.provider !== "string" || target.provider.length === 0 || target.provider.length > 100 || target.requested_model !== undefined && (typeof target.requested_model !== "string" || target.requested_model.length > 200) || !isBoundedStringList(target.observed_models)) {
|
|
21137
|
+
throw new Error("Invalid run manifest: malformed target evidence");
|
|
21138
|
+
}
|
|
21139
|
+
}
|
|
21140
|
+
function assertExecutionProvenance(provenance) {
|
|
21141
|
+
if (!isRecord2(provenance) || provenance.schema_version !== "1" || !isRecord2(provenance.target)) {
|
|
21142
|
+
throw new Error("Invalid run manifest: malformed execution provenance");
|
|
21143
|
+
}
|
|
21144
|
+
const target = provenance.target;
|
|
21145
|
+
if (typeof target.provider !== "string" || target.provider.length === 0 || target.provider.length > 100 || !isBoundedStringList(target.requested_models) || !isBoundedStringList(target.observed_models) || target.generation !== undefined && !isGenerationConfig(target.generation)) {
|
|
21146
|
+
throw new Error("Invalid run manifest: malformed execution provenance");
|
|
21147
|
+
}
|
|
21148
|
+
if (provenance.evaluator !== undefined) {
|
|
21149
|
+
if (!isRecord2(provenance.evaluator) || !isBoundedStringList(provenance.evaluator.models)) {
|
|
21150
|
+
throw new Error("Invalid run manifest: malformed execution provenance");
|
|
21151
|
+
}
|
|
21308
21152
|
}
|
|
21309
21153
|
}
|
|
21154
|
+
function isBoundedStringList(value) {
|
|
21155
|
+
return value === undefined || Array.isArray(value) && value.length <= 100 && value.every((item) => typeof item === "string" && item.length > 0 && item.length <= 200);
|
|
21156
|
+
}
|
|
21157
|
+
function isGenerationConfig(value) {
|
|
21158
|
+
if (!isRecord2(value))
|
|
21159
|
+
return false;
|
|
21160
|
+
return [value.temperature, value.max_tokens, value.seed].every((item) => item === undefined || typeof item === "number" && Number.isFinite(item));
|
|
21161
|
+
}
|
|
21310
21162
|
function assertWorkloadIdentity(identity) {
|
|
21311
21163
|
if (!isRecord2(identity) || identity.schema_version !== "1" || !isContentIdentity(identity.workload) || !isContentIdentity(identity.rubric)) {
|
|
21312
21164
|
throw new Error("Invalid run manifest: malformed workload identity");
|
|
@@ -21357,6 +21209,10 @@ function createRunManifest(options) {
|
|
|
21357
21209
|
config,
|
|
21358
21210
|
resolvedConfig,
|
|
21359
21211
|
workloadIdentity,
|
|
21212
|
+
executionProvenance,
|
|
21213
|
+
attemptEvidence,
|
|
21214
|
+
costProvenance,
|
|
21215
|
+
runId,
|
|
21360
21216
|
cases,
|
|
21361
21217
|
startTime,
|
|
21362
21218
|
endTime,
|
|
@@ -21364,13 +21220,12 @@ function createRunManifest(options) {
|
|
|
21364
21220
|
runReason,
|
|
21365
21221
|
redaction
|
|
21366
21222
|
} = options;
|
|
21367
|
-
const
|
|
21368
|
-
const metrics = calculateMetrics(cases, modelForCost);
|
|
21223
|
+
const metrics = calculateMetrics(cases, costProvenance);
|
|
21369
21224
|
const git = getGitInfo();
|
|
21370
21225
|
const environment = getEnvironmentInfo();
|
|
21371
21226
|
return {
|
|
21372
|
-
version: "1.
|
|
21373
|
-
run_id: nanoid(12),
|
|
21227
|
+
version: "1.4",
|
|
21228
|
+
run_id: runId ?? nanoid(12),
|
|
21374
21229
|
project,
|
|
21375
21230
|
start_time: startTime.toISOString(),
|
|
21376
21231
|
end_time: endTime.toISOString(),
|
|
@@ -21378,6 +21233,8 @@ function createRunManifest(options) {
|
|
|
21378
21233
|
config,
|
|
21379
21234
|
resolved_config: resolvedConfig,
|
|
21380
21235
|
workload_identity: workloadIdentity,
|
|
21236
|
+
execution_provenance: executionProvenance,
|
|
21237
|
+
attempt_evidence: attemptEvidence,
|
|
21381
21238
|
metrics,
|
|
21382
21239
|
git,
|
|
21383
21240
|
provenance: {
|
|
@@ -21390,7 +21247,7 @@ function createRunManifest(options) {
|
|
|
21390
21247
|
redaction
|
|
21391
21248
|
};
|
|
21392
21249
|
}
|
|
21393
|
-
function calculateMetrics(cases,
|
|
21250
|
+
function calculateMetrics(cases, costProvenance) {
|
|
21394
21251
|
const passedCases = cases.filter((c) => getCaseEvaluationStatus(c) === "passed");
|
|
21395
21252
|
const validCases = cases.filter((c) => {
|
|
21396
21253
|
const status = getCaseEvaluationStatus(c);
|
|
@@ -21402,21 +21259,11 @@ function calculateMetrics(cases, model) {
|
|
|
21402
21259
|
const p95Latency = latencies.length > 0 ? latencies[p95Index] : 0;
|
|
21403
21260
|
const totalPromptTokens = cases.reduce((sum, c) => sum + c.tokens.prompt, 0);
|
|
21404
21261
|
const totalCompletionTokens = cases.reduce((sum, c) => sum + c.tokens.completion, 0);
|
|
21405
|
-
|
|
21406
|
-
|
|
21407
|
-
|
|
21408
|
-
|
|
21409
|
-
|
|
21410
|
-
total_usd: costEstimate.totalUsd,
|
|
21411
|
-
prompt_cost_usd: costEstimate.promptCostUsd,
|
|
21412
|
-
completion_cost_usd: costEstimate.completionCostUsd,
|
|
21413
|
-
model: costEstimate.model,
|
|
21414
|
-
pricing: {
|
|
21415
|
-
prompt_per_1k: pricing.promptPer1K,
|
|
21416
|
-
completion_per_1k: pricing.completionPer1K
|
|
21417
|
-
}
|
|
21418
|
-
};
|
|
21419
|
-
}
|
|
21262
|
+
const cost_provenance = costProvenance ?? {
|
|
21263
|
+
schema_version: "1",
|
|
21264
|
+
status: "unavailable",
|
|
21265
|
+
unavailable_reason: "provider_billing_not_recorded"
|
|
21266
|
+
};
|
|
21420
21267
|
return {
|
|
21421
21268
|
success_rate: validCases.length > 0 ? passedCases.length / validCases.length : 0,
|
|
21422
21269
|
total_attempts: cases.reduce((sum, c) => sum + (c.attempts ?? 1), 0),
|
|
@@ -21431,7 +21278,7 @@ function calculateMetrics(cases, model) {
|
|
|
21431
21278
|
total_tokens: totalPromptTokens + totalCompletionTokens,
|
|
21432
21279
|
total_prompt_tokens: totalPromptTokens,
|
|
21433
21280
|
total_completion_tokens: totalCompletionTokens,
|
|
21434
|
-
|
|
21281
|
+
cost_provenance
|
|
21435
21282
|
};
|
|
21436
21283
|
}
|
|
21437
21284
|
function detectCIEnvironment() {
|
|
@@ -21530,6 +21377,39 @@ function canonicalize(value, patterns, key) {
|
|
|
21530
21377
|
}
|
|
21531
21378
|
return value;
|
|
21532
21379
|
}
|
|
21380
|
+
// src/provenance/execution-provenance.ts
|
|
21381
|
+
function createExecutionProvenance(options) {
|
|
21382
|
+
const requestedModels = uniqueStrings([
|
|
21383
|
+
options.requestedModel,
|
|
21384
|
+
...options.cases.map((caseResult) => caseResult.target?.requested_model)
|
|
21385
|
+
]);
|
|
21386
|
+
const observedModels = uniqueStrings(options.cases.flatMap((caseResult) => caseResult.target?.observed_models ?? []));
|
|
21387
|
+
const evaluatorModels = uniqueStrings(options.cases.map((caseResult) => caseResult.evidence?.model));
|
|
21388
|
+
const generation = omitUndefined({
|
|
21389
|
+
temperature: options.temperature,
|
|
21390
|
+
max_tokens: options.maxTokens,
|
|
21391
|
+
seed: options.seed
|
|
21392
|
+
});
|
|
21393
|
+
return {
|
|
21394
|
+
schema_version: "1",
|
|
21395
|
+
target: {
|
|
21396
|
+
provider: boundedString(options.provider, 100) ?? "unknown",
|
|
21397
|
+
...requestedModels.length ? { requested_models: requestedModels } : {},
|
|
21398
|
+
...observedModels.length ? { observed_models: observedModels } : {},
|
|
21399
|
+
...Object.keys(generation).length ? { generation } : {}
|
|
21400
|
+
},
|
|
21401
|
+
...evaluatorModels.length ? { evaluator: { models: evaluatorModels } } : {}
|
|
21402
|
+
};
|
|
21403
|
+
}
|
|
21404
|
+
function uniqueStrings(values) {
|
|
21405
|
+
return [...new Set(values.map((value) => boundedString(value, 200)).filter(Boolean))];
|
|
21406
|
+
}
|
|
21407
|
+
function boundedString(value, maxLength) {
|
|
21408
|
+
return typeof value === "string" && value.length > 0 ? value.slice(0, maxLength) : undefined;
|
|
21409
|
+
}
|
|
21410
|
+
function omitUndefined(value) {
|
|
21411
|
+
return Object.fromEntries(Object.entries(value).filter(([, item]) => item !== undefined));
|
|
21412
|
+
}
|
|
21533
21413
|
// src/runner/runner.ts
|
|
21534
21414
|
async function runScenario(options) {
|
|
21535
21415
|
const {
|
|
@@ -21541,6 +21421,8 @@ async function runScenario(options) {
|
|
|
21541
21421
|
concurrency = 1,
|
|
21542
21422
|
timeout,
|
|
21543
21423
|
retries,
|
|
21424
|
+
repetition = { index: 1, total: 1 },
|
|
21425
|
+
costProvenance,
|
|
21544
21426
|
redaction,
|
|
21545
21427
|
toolExecutor,
|
|
21546
21428
|
onCaseComplete,
|
|
@@ -21556,6 +21438,7 @@ async function runScenario(options) {
|
|
|
21556
21438
|
}
|
|
21557
21439
|
onProgress?.(`Running ${cases.length} test cases...`);
|
|
21558
21440
|
const startTime = new Date;
|
|
21441
|
+
const runId = nanoid(12);
|
|
21559
21442
|
const results = [];
|
|
21560
21443
|
if (concurrency === 1) {
|
|
21561
21444
|
for (let i = 0;i < cases.length; i++) {
|
|
@@ -21563,8 +21446,11 @@ async function runScenario(options) {
|
|
|
21563
21446
|
const result = await executeCase(testCase, {
|
|
21564
21447
|
client,
|
|
21565
21448
|
scenario,
|
|
21449
|
+
requestedModel: resolvedConfig?.model,
|
|
21566
21450
|
timeout: testCase.timeout || timeout,
|
|
21567
21451
|
retries: testCase.retries ?? retries,
|
|
21452
|
+
runId,
|
|
21453
|
+
repetition,
|
|
21568
21454
|
redaction,
|
|
21569
21455
|
toolExecutor
|
|
21570
21456
|
});
|
|
@@ -21579,8 +21465,11 @@ async function runScenario(options) {
|
|
|
21579
21465
|
const result = await executeCase(testCase, {
|
|
21580
21466
|
client,
|
|
21581
21467
|
scenario,
|
|
21468
|
+
requestedModel: resolvedConfig?.model,
|
|
21582
21469
|
timeout: testCase.timeout || timeout,
|
|
21583
21470
|
retries: testCase.retries ?? retries,
|
|
21471
|
+
runId,
|
|
21472
|
+
repetition,
|
|
21584
21473
|
redaction,
|
|
21585
21474
|
toolExecutor
|
|
21586
21475
|
});
|
|
@@ -21623,9 +21512,29 @@ async function runScenario(options) {
|
|
|
21623
21512
|
},
|
|
21624
21513
|
resolvedConfig,
|
|
21625
21514
|
workloadIdentity: createWorkloadIdentity(scenario),
|
|
21515
|
+
executionProvenance: createExecutionProvenance({
|
|
21516
|
+
provider: client.provider,
|
|
21517
|
+
requestedModel: resolvedConfig?.model || scenario.model,
|
|
21518
|
+
temperature: resolvedConfig?.temperature ?? scenario.temperature,
|
|
21519
|
+
maxTokens: resolvedConfig?.max_tokens ?? scenario.maxTokens,
|
|
21520
|
+
seed: scenario.seed,
|
|
21521
|
+
cases: results
|
|
21522
|
+
}),
|
|
21523
|
+
attemptEvidence: {
|
|
21524
|
+
schema_version: "1",
|
|
21525
|
+
repetition,
|
|
21526
|
+
retry_policy: {
|
|
21527
|
+
default_max_retries: retries ?? 0,
|
|
21528
|
+
backoff: "exponential",
|
|
21529
|
+
initial_delay_ms: 1000
|
|
21530
|
+
},
|
|
21531
|
+
...timeout ? { timeout: { default_ms: timeout } } : {}
|
|
21532
|
+
},
|
|
21533
|
+
costProvenance,
|
|
21626
21534
|
cases: results,
|
|
21627
21535
|
startTime,
|
|
21628
21536
|
endTime,
|
|
21537
|
+
runId,
|
|
21629
21538
|
redaction: redactionInfo
|
|
21630
21539
|
});
|
|
21631
21540
|
const success = manifest.metrics.failed_cases === 0 && (manifest.metrics.invalid_evaluations ?? 0) === 0;
|
|
@@ -32007,6 +31916,318 @@ class Logger {
|
|
|
32007
31916
|
}
|
|
32008
31917
|
}
|
|
32009
31918
|
var logger = new Logger("artemis");
|
|
31919
|
+
// src/cost/pricing.ts
|
|
31920
|
+
var MODEL_PRICING = {
|
|
31921
|
+
"gpt-5": {
|
|
31922
|
+
promptPer1K: 0.00125,
|
|
31923
|
+
completionPer1K: 0.01,
|
|
31924
|
+
lastUpdated: "2026-01",
|
|
31925
|
+
notes: "400K context window"
|
|
31926
|
+
},
|
|
31927
|
+
"gpt-5.1": {
|
|
31928
|
+
promptPer1K: 0.00125,
|
|
31929
|
+
completionPer1K: 0.01,
|
|
31930
|
+
lastUpdated: "2026-01"
|
|
31931
|
+
},
|
|
31932
|
+
"gpt-5.2": {
|
|
31933
|
+
promptPer1K: 0.00175,
|
|
31934
|
+
completionPer1K: 0.014,
|
|
31935
|
+
lastUpdated: "2026-01"
|
|
31936
|
+
},
|
|
31937
|
+
"gpt-5-mini": {
|
|
31938
|
+
promptPer1K: 0.00025,
|
|
31939
|
+
completionPer1K: 0.002,
|
|
31940
|
+
lastUpdated: "2026-01"
|
|
31941
|
+
},
|
|
31942
|
+
"gpt-5-nano": {
|
|
31943
|
+
promptPer1K: 0.00005,
|
|
31944
|
+
completionPer1K: 0.0004,
|
|
31945
|
+
lastUpdated: "2026-01"
|
|
31946
|
+
},
|
|
31947
|
+
"gpt-4.1": {
|
|
31948
|
+
promptPer1K: 0.002,
|
|
31949
|
+
completionPer1K: 0.008,
|
|
31950
|
+
lastUpdated: "2026-01",
|
|
31951
|
+
notes: "1M context window"
|
|
31952
|
+
},
|
|
31953
|
+
"gpt-4.1-mini": {
|
|
31954
|
+
promptPer1K: 0.0004,
|
|
31955
|
+
completionPer1K: 0.0016,
|
|
31956
|
+
lastUpdated: "2026-01"
|
|
31957
|
+
},
|
|
31958
|
+
"gpt-4.1-nano": {
|
|
31959
|
+
promptPer1K: 0.0001,
|
|
31960
|
+
completionPer1K: 0.0004,
|
|
31961
|
+
lastUpdated: "2026-01"
|
|
31962
|
+
},
|
|
31963
|
+
"gpt-4o": {
|
|
31964
|
+
promptPer1K: 0.0025,
|
|
31965
|
+
completionPer1K: 0.01,
|
|
31966
|
+
lastUpdated: "2026-01",
|
|
31967
|
+
notes: "128K context window"
|
|
31968
|
+
},
|
|
31969
|
+
"gpt-4o-mini": {
|
|
31970
|
+
promptPer1K: 0.00015,
|
|
31971
|
+
completionPer1K: 0.0006,
|
|
31972
|
+
lastUpdated: "2026-01",
|
|
31973
|
+
notes: "128K context window"
|
|
31974
|
+
},
|
|
31975
|
+
o1: {
|
|
31976
|
+
promptPer1K: 0.015,
|
|
31977
|
+
completionPer1K: 0.06,
|
|
31978
|
+
lastUpdated: "2026-01",
|
|
31979
|
+
notes: "Reasoning model - internal thinking tokens billed as output"
|
|
31980
|
+
},
|
|
31981
|
+
o3: {
|
|
31982
|
+
promptPer1K: 0.002,
|
|
31983
|
+
completionPer1K: 0.008,
|
|
31984
|
+
lastUpdated: "2026-01"
|
|
31985
|
+
},
|
|
31986
|
+
"o3-mini": {
|
|
31987
|
+
promptPer1K: 0.0011,
|
|
31988
|
+
completionPer1K: 0.0044,
|
|
31989
|
+
lastUpdated: "2026-01"
|
|
31990
|
+
},
|
|
31991
|
+
"o4-mini": {
|
|
31992
|
+
promptPer1K: 0.0011,
|
|
31993
|
+
completionPer1K: 0.0044,
|
|
31994
|
+
lastUpdated: "2026-01"
|
|
31995
|
+
},
|
|
31996
|
+
"gpt-4-turbo": {
|
|
31997
|
+
promptPer1K: 0.01,
|
|
31998
|
+
completionPer1K: 0.03,
|
|
31999
|
+
lastUpdated: "2026-01"
|
|
32000
|
+
},
|
|
32001
|
+
"gpt-4": {
|
|
32002
|
+
promptPer1K: 0.03,
|
|
32003
|
+
completionPer1K: 0.06,
|
|
32004
|
+
lastUpdated: "2026-01"
|
|
32005
|
+
},
|
|
32006
|
+
"gpt-3.5-turbo": {
|
|
32007
|
+
promptPer1K: 0.0005,
|
|
32008
|
+
completionPer1K: 0.0015,
|
|
32009
|
+
lastUpdated: "2026-01"
|
|
32010
|
+
},
|
|
32011
|
+
"claude-opus-4.5": {
|
|
32012
|
+
promptPer1K: 0.005,
|
|
32013
|
+
completionPer1K: 0.025,
|
|
32014
|
+
lastUpdated: "2026-01",
|
|
32015
|
+
notes: "Most capable Claude model"
|
|
32016
|
+
},
|
|
32017
|
+
"claude-sonnet-4.5": {
|
|
32018
|
+
promptPer1K: 0.003,
|
|
32019
|
+
completionPer1K: 0.015,
|
|
32020
|
+
lastUpdated: "2026-01",
|
|
32021
|
+
notes: "Balanced performance and cost"
|
|
32022
|
+
},
|
|
32023
|
+
"claude-haiku-4.5": {
|
|
32024
|
+
promptPer1K: 0.001,
|
|
32025
|
+
completionPer1K: 0.005,
|
|
32026
|
+
lastUpdated: "2026-01",
|
|
32027
|
+
notes: "Fastest Claude model"
|
|
32028
|
+
},
|
|
32029
|
+
"claude-opus-4": {
|
|
32030
|
+
promptPer1K: 0.015,
|
|
32031
|
+
completionPer1K: 0.075,
|
|
32032
|
+
lastUpdated: "2026-01"
|
|
32033
|
+
},
|
|
32034
|
+
"claude-opus-4.1": {
|
|
32035
|
+
promptPer1K: 0.015,
|
|
32036
|
+
completionPer1K: 0.075,
|
|
32037
|
+
lastUpdated: "2026-01"
|
|
32038
|
+
},
|
|
32039
|
+
"claude-sonnet-4": {
|
|
32040
|
+
promptPer1K: 0.003,
|
|
32041
|
+
completionPer1K: 0.015,
|
|
32042
|
+
lastUpdated: "2026-01"
|
|
32043
|
+
},
|
|
32044
|
+
"claude-sonnet-3.7": {
|
|
32045
|
+
promptPer1K: 0.003,
|
|
32046
|
+
completionPer1K: 0.015,
|
|
32047
|
+
lastUpdated: "2026-01"
|
|
32048
|
+
},
|
|
32049
|
+
"claude-3-7-sonnet": {
|
|
32050
|
+
promptPer1K: 0.003,
|
|
32051
|
+
completionPer1K: 0.015,
|
|
32052
|
+
lastUpdated: "2026-01"
|
|
32053
|
+
},
|
|
32054
|
+
"claude-3-5-sonnet-20241022": {
|
|
32055
|
+
promptPer1K: 0.003,
|
|
32056
|
+
completionPer1K: 0.015,
|
|
32057
|
+
lastUpdated: "2026-01"
|
|
32058
|
+
},
|
|
32059
|
+
"claude-3-5-haiku-20241022": {
|
|
32060
|
+
promptPer1K: 0.0008,
|
|
32061
|
+
completionPer1K: 0.004,
|
|
32062
|
+
lastUpdated: "2026-01"
|
|
32063
|
+
},
|
|
32064
|
+
"claude-haiku-3.5": {
|
|
32065
|
+
promptPer1K: 0.0008,
|
|
32066
|
+
completionPer1K: 0.004,
|
|
32067
|
+
lastUpdated: "2026-01"
|
|
32068
|
+
},
|
|
32069
|
+
"claude-3-opus": {
|
|
32070
|
+
promptPer1K: 0.015,
|
|
32071
|
+
completionPer1K: 0.075,
|
|
32072
|
+
lastUpdated: "2026-01"
|
|
32073
|
+
},
|
|
32074
|
+
"claude-3-sonnet": {
|
|
32075
|
+
promptPer1K: 0.003,
|
|
32076
|
+
completionPer1K: 0.015,
|
|
32077
|
+
lastUpdated: "2026-01"
|
|
32078
|
+
},
|
|
32079
|
+
"claude-3-haiku": {
|
|
32080
|
+
promptPer1K: 0.00025,
|
|
32081
|
+
completionPer1K: 0.00125,
|
|
32082
|
+
lastUpdated: "2026-01"
|
|
32083
|
+
},
|
|
32084
|
+
"claude-3.5-sonnet": {
|
|
32085
|
+
promptPer1K: 0.003,
|
|
32086
|
+
completionPer1K: 0.015,
|
|
32087
|
+
lastUpdated: "2026-01"
|
|
32088
|
+
},
|
|
32089
|
+
"claude-3.5-haiku": {
|
|
32090
|
+
promptPer1K: 0.0008,
|
|
32091
|
+
completionPer1K: 0.004,
|
|
32092
|
+
lastUpdated: "2026-01"
|
|
32093
|
+
}
|
|
32094
|
+
};
|
|
32095
|
+
var DEFAULT_PRICING = {
|
|
32096
|
+
promptPer1K: 0.003,
|
|
32097
|
+
completionPer1K: 0.015,
|
|
32098
|
+
lastUpdated: "2026-01",
|
|
32099
|
+
notes: "Default pricing - verify with provider"
|
|
32100
|
+
};
|
|
32101
|
+
function getModelPricing(model) {
|
|
32102
|
+
if (MODEL_PRICING[model]) {
|
|
32103
|
+
return MODEL_PRICING[model];
|
|
32104
|
+
}
|
|
32105
|
+
const lowerModel = model.toLowerCase();
|
|
32106
|
+
for (const [key, pricing] of Object.entries(MODEL_PRICING)) {
|
|
32107
|
+
if (key.toLowerCase() === lowerModel) {
|
|
32108
|
+
return pricing;
|
|
32109
|
+
}
|
|
32110
|
+
}
|
|
32111
|
+
if (lowerModel.includes("gpt-5.2")) {
|
|
32112
|
+
return MODEL_PRICING["gpt-5.2"];
|
|
32113
|
+
}
|
|
32114
|
+
if (lowerModel.includes("gpt-5.1")) {
|
|
32115
|
+
return MODEL_PRICING["gpt-5.1"];
|
|
32116
|
+
}
|
|
32117
|
+
if (lowerModel.includes("gpt-5-mini")) {
|
|
32118
|
+
return MODEL_PRICING["gpt-5-mini"];
|
|
32119
|
+
}
|
|
32120
|
+
if (lowerModel.includes("gpt-5-nano")) {
|
|
32121
|
+
return MODEL_PRICING["gpt-5-nano"];
|
|
32122
|
+
}
|
|
32123
|
+
if (lowerModel.includes("gpt-5")) {
|
|
32124
|
+
return MODEL_PRICING["gpt-5"];
|
|
32125
|
+
}
|
|
32126
|
+
if (lowerModel.includes("gpt-4.1-mini")) {
|
|
32127
|
+
return MODEL_PRICING["gpt-4.1-mini"];
|
|
32128
|
+
}
|
|
32129
|
+
if (lowerModel.includes("gpt-4.1-nano")) {
|
|
32130
|
+
return MODEL_PRICING["gpt-4.1-nano"];
|
|
32131
|
+
}
|
|
32132
|
+
if (lowerModel.includes("gpt-4.1")) {
|
|
32133
|
+
return MODEL_PRICING["gpt-4.1"];
|
|
32134
|
+
}
|
|
32135
|
+
if (lowerModel.includes("gpt-4o-mini")) {
|
|
32136
|
+
return MODEL_PRICING["gpt-4o-mini"];
|
|
32137
|
+
}
|
|
32138
|
+
if (lowerModel.includes("gpt-4o")) {
|
|
32139
|
+
return MODEL_PRICING["gpt-4o"];
|
|
32140
|
+
}
|
|
32141
|
+
if (lowerModel.includes("o4-mini")) {
|
|
32142
|
+
return MODEL_PRICING["o4-mini"];
|
|
32143
|
+
}
|
|
32144
|
+
if (lowerModel.includes("o3-mini")) {
|
|
32145
|
+
return MODEL_PRICING["o3-mini"];
|
|
32146
|
+
}
|
|
32147
|
+
if (lowerModel.includes("o3")) {
|
|
32148
|
+
return MODEL_PRICING.o3;
|
|
32149
|
+
}
|
|
32150
|
+
if (lowerModel.includes("o1")) {
|
|
32151
|
+
return MODEL_PRICING.o1;
|
|
32152
|
+
}
|
|
32153
|
+
if (lowerModel.includes("gpt-4-turbo")) {
|
|
32154
|
+
return MODEL_PRICING["gpt-4-turbo"];
|
|
32155
|
+
}
|
|
32156
|
+
if (lowerModel.includes("gpt-4")) {
|
|
32157
|
+
return MODEL_PRICING["gpt-4"];
|
|
32158
|
+
}
|
|
32159
|
+
if (lowerModel.includes("gpt-3.5")) {
|
|
32160
|
+
return MODEL_PRICING["gpt-3.5-turbo"];
|
|
32161
|
+
}
|
|
32162
|
+
if (lowerModel.includes("opus-4.5") || lowerModel.includes("opus-4-5")) {
|
|
32163
|
+
return MODEL_PRICING["claude-opus-4.5"];
|
|
32164
|
+
}
|
|
32165
|
+
if (lowerModel.includes("sonnet-4.5") || lowerModel.includes("sonnet-4-5")) {
|
|
32166
|
+
return MODEL_PRICING["claude-sonnet-4.5"];
|
|
32167
|
+
}
|
|
32168
|
+
if (lowerModel.includes("haiku-4.5") || lowerModel.includes("haiku-4-5")) {
|
|
32169
|
+
return MODEL_PRICING["claude-haiku-4.5"];
|
|
32170
|
+
}
|
|
32171
|
+
if (lowerModel.includes("opus-4.1") || lowerModel.includes("opus-4-1")) {
|
|
32172
|
+
return MODEL_PRICING["claude-opus-4.1"];
|
|
32173
|
+
}
|
|
32174
|
+
if (lowerModel.includes("opus-4")) {
|
|
32175
|
+
return MODEL_PRICING["claude-opus-4"];
|
|
32176
|
+
}
|
|
32177
|
+
if (lowerModel.includes("sonnet-4")) {
|
|
32178
|
+
return MODEL_PRICING["claude-sonnet-4"];
|
|
32179
|
+
}
|
|
32180
|
+
if (lowerModel.includes("sonnet-3.7") || lowerModel.includes("sonnet-3-7")) {
|
|
32181
|
+
return MODEL_PRICING["claude-sonnet-3.7"];
|
|
32182
|
+
}
|
|
32183
|
+
if (lowerModel.includes("claude-3-5-sonnet") || lowerModel.includes("claude-3.5-sonnet")) {
|
|
32184
|
+
return MODEL_PRICING["claude-3.5-sonnet"];
|
|
32185
|
+
}
|
|
32186
|
+
if (lowerModel.includes("claude-3-5-haiku") || lowerModel.includes("claude-3.5-haiku")) {
|
|
32187
|
+
return MODEL_PRICING["claude-3.5-haiku"];
|
|
32188
|
+
}
|
|
32189
|
+
if (lowerModel.includes("claude-3-opus")) {
|
|
32190
|
+
return MODEL_PRICING["claude-3-opus"];
|
|
32191
|
+
}
|
|
32192
|
+
if (lowerModel.includes("claude-3-sonnet")) {
|
|
32193
|
+
return MODEL_PRICING["claude-3-sonnet"];
|
|
32194
|
+
}
|
|
32195
|
+
if (lowerModel.includes("claude-3-haiku")) {
|
|
32196
|
+
return MODEL_PRICING["claude-3-haiku"];
|
|
32197
|
+
}
|
|
32198
|
+
if (lowerModel.includes("claude")) {
|
|
32199
|
+
return MODEL_PRICING["claude-sonnet-4.5"];
|
|
32200
|
+
}
|
|
32201
|
+
return DEFAULT_PRICING;
|
|
32202
|
+
}
|
|
32203
|
+
function estimateCost(promptTokens, completionTokens, model) {
|
|
32204
|
+
const pricing = getModelPricing(model);
|
|
32205
|
+
const promptCostUsd = promptTokens / 1000 * pricing.promptPer1K;
|
|
32206
|
+
const completionCostUsd = completionTokens / 1000 * pricing.completionPer1K;
|
|
32207
|
+
const totalUsd = promptCostUsd + completionCostUsd;
|
|
32208
|
+
return {
|
|
32209
|
+
totalUsd,
|
|
32210
|
+
promptCostUsd,
|
|
32211
|
+
completionCostUsd,
|
|
32212
|
+
model,
|
|
32213
|
+
pricing
|
|
32214
|
+
};
|
|
32215
|
+
}
|
|
32216
|
+
function formatCost(costUsd) {
|
|
32217
|
+
if (costUsd < 0.01) {
|
|
32218
|
+
return `$${(costUsd * 100).toFixed(4)} cents`;
|
|
32219
|
+
}
|
|
32220
|
+
if (costUsd < 1) {
|
|
32221
|
+
return `$${costUsd.toFixed(4)}`;
|
|
32222
|
+
}
|
|
32223
|
+
return `$${costUsd.toFixed(2)}`;
|
|
32224
|
+
}
|
|
32225
|
+
function listKnownModels() {
|
|
32226
|
+
return Object.entries(MODEL_PRICING).map(([model, pricing]) => ({
|
|
32227
|
+
model,
|
|
32228
|
+
pricing
|
|
32229
|
+
}));
|
|
32230
|
+
}
|
|
32010
32231
|
// src/agent-evaluation/types.ts
|
|
32011
32232
|
function actionBudgetExceeded(task, trace) {
|
|
32012
32233
|
return trace.actions.length > task.maxActions;
|
|
@@ -32705,6 +32926,7 @@ export {
|
|
|
32705
32926
|
assertRunManifestIntegrity,
|
|
32706
32927
|
createAdapter,
|
|
32707
32928
|
createDefaultRedactor,
|
|
32929
|
+
createExecutionProvenance,
|
|
32708
32930
|
createNoOpRedactor,
|
|
32709
32931
|
createRedactionOptions,
|
|
32710
32932
|
createRunManifest,
|