braintrust 3.27.0 → 3.28.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/dev/dist/index.d.mts +519 -186
- package/dev/dist/index.d.ts +519 -186
- package/dev/dist/index.js +1837 -1009
- package/dev/dist/index.mjs +1172 -344
- package/dist/apply-auto-instrumentation.js +262 -210
- package/dist/apply-auto-instrumentation.mjs +54 -2
- package/dist/auto-instrumentations/bundler/esbuild.cjs +81 -2
- package/dist/auto-instrumentations/bundler/esbuild.mjs +2 -2
- package/dist/auto-instrumentations/bundler/next.cjs +81 -2
- package/dist/auto-instrumentations/bundler/next.mjs +3 -3
- package/dist/auto-instrumentations/bundler/rollup.cjs +81 -2
- package/dist/auto-instrumentations/bundler/rollup.mjs +2 -2
- package/dist/auto-instrumentations/bundler/vite.cjs +81 -2
- package/dist/auto-instrumentations/bundler/vite.mjs +2 -2
- package/dist/auto-instrumentations/bundler/webpack-loader.cjs +81 -2
- package/dist/auto-instrumentations/bundler/webpack.cjs +81 -2
- package/dist/auto-instrumentations/bundler/webpack.mjs +3 -3
- package/dist/auto-instrumentations/{chunk-XEYKUBLY.mjs → chunk-26PKVUKB.mjs} +80 -2
- package/dist/auto-instrumentations/{chunk-BW33ULMW.mjs → chunk-HD35AM3M.mjs} +1 -1
- package/dist/auto-instrumentations/{chunk-ZNHTSSGI.mjs → chunk-NP7V4XB2.mjs} +2 -1
- package/dist/auto-instrumentations/hook.mjs +236 -30
- package/dist/auto-instrumentations/index.cjs +2 -1
- package/dist/auto-instrumentations/index.mjs +1 -1
- package/dist/browser.d.mts +628 -53
- package/dist/browser.d.ts +628 -53
- package/dist/browser.js +2301 -284
- package/dist/browser.mjs +2301 -284
- package/dist/{chunk-MF7NU6BT.js → chunk-BBE7SNRV.js} +34 -4
- package/dist/{chunk-QRHGVBKU.js → chunk-OBBWQW6K.js} +1799 -1023
- package/dist/{chunk-YKD22IMR.mjs → chunk-UPFNQCGB.mjs} +966 -190
- package/dist/{chunk-CZM5JIQL.mjs → chunk-ZHUHZWFY.mjs} +33 -3
- package/dist/cli.js +1224 -398
- package/dist/edge-light.d.mts +1 -1
- package/dist/edge-light.d.ts +1 -1
- package/dist/edge-light.js +2301 -284
- package/dist/edge-light.mjs +2301 -284
- package/dist/index.d.mts +1212 -637
- package/dist/index.d.ts +1212 -637
- package/dist/index.js +1880 -590
- package/dist/index.mjs +1450 -160
- package/dist/instrumentation/index.d.mts +190 -6
- package/dist/instrumentation/index.d.ts +190 -6
- package/dist/instrumentation/index.js +823 -116
- package/dist/instrumentation/index.mjs +823 -116
- package/dist/vitest-evals-reporter.js +16 -16
- package/dist/vitest-evals-reporter.mjs +2 -2
- package/dist/workerd.d.mts +1 -1
- package/dist/workerd.d.ts +1 -1
- package/dist/workerd.js +2301 -284
- package/dist/workerd.mjs +2301 -284
- package/package.json +2 -3
- package/util/dist/index.d.mts +1545 -100
- package/util/dist/index.d.ts +1545 -100
package/dist/browser.mjs
CHANGED
|
@@ -1567,12 +1567,12 @@ function base64ToUint8Array(base64) {
|
|
|
1567
1567
|
return uint8Array;
|
|
1568
1568
|
}
|
|
1569
1569
|
function uint8ArrayToString(uint8Array) {
|
|
1570
|
-
const
|
|
1571
|
-
return
|
|
1570
|
+
const decoder2 = new TextDecoder("utf-8");
|
|
1571
|
+
return decoder2.decode(uint8Array);
|
|
1572
1572
|
}
|
|
1573
1573
|
function stringToUint8Array(str) {
|
|
1574
|
-
const
|
|
1575
|
-
return
|
|
1574
|
+
const encoder2 = new TextEncoder();
|
|
1575
|
+
return encoder2.encode(str);
|
|
1576
1576
|
}
|
|
1577
1577
|
|
|
1578
1578
|
// util/span_identifier_v3.ts
|
|
@@ -2476,7 +2476,8 @@ var AclObjectType = z6.union([
|
|
|
2476
2476
|
"org_member",
|
|
2477
2477
|
"project_log",
|
|
2478
2478
|
"org_project",
|
|
2479
|
-
"org_audit_logs"
|
|
2479
|
+
"org_audit_logs",
|
|
2480
|
+
"project_group"
|
|
2480
2481
|
]),
|
|
2481
2482
|
z6.null()
|
|
2482
2483
|
]);
|
|
@@ -2605,7 +2606,8 @@ var AsyncScoringState = z6.union([
|
|
|
2605
2606
|
token: z6.string(),
|
|
2606
2607
|
function_ids: z6.array(z6.unknown()),
|
|
2607
2608
|
skip_logging: z6.union([z6.boolean(), z6.null()]).optional(),
|
|
2608
|
-
triggered_functions: z6.union([z6.record(TriggeredFunctionState), z6.null()]).optional()
|
|
2609
|
+
triggered_functions: z6.union([z6.record(TriggeredFunctionState), z6.null()]).optional(),
|
|
2610
|
+
last_triggered_xact_id: z6.union([z6.string(), z6.number(), z6.null()]).optional()
|
|
2609
2611
|
}),
|
|
2610
2612
|
z6.object({ status: z6.literal("disabled") }),
|
|
2611
2613
|
z6.null(),
|
|
@@ -2674,7 +2676,7 @@ var FunctionTypeEnum = z6.enum([
|
|
|
2674
2676
|
"parameters",
|
|
2675
2677
|
"sandbox"
|
|
2676
2678
|
]);
|
|
2677
|
-
var
|
|
2679
|
+
var FacetPreprocessorId = z6.union([
|
|
2678
2680
|
z6.object({
|
|
2679
2681
|
type: z6.literal("function"),
|
|
2680
2682
|
id: z6.string(),
|
|
@@ -2685,10 +2687,23 @@ var NullableSavedFunctionId = z6.union([
|
|
|
2685
2687
|
name: z6.string(),
|
|
2686
2688
|
function_type: FunctionTypeEnum.optional().default("scorer")
|
|
2687
2689
|
}),
|
|
2690
|
+
z6.object({ type: z6.literal("inline"), code: z6.string().min(1) }),
|
|
2688
2691
|
z6.null()
|
|
2689
2692
|
]);
|
|
2693
|
+
var SavedFunctionId = z6.union([
|
|
2694
|
+
z6.object({
|
|
2695
|
+
type: z6.literal("function"),
|
|
2696
|
+
id: z6.string(),
|
|
2697
|
+
version: z6.string().optional()
|
|
2698
|
+
}),
|
|
2699
|
+
z6.object({
|
|
2700
|
+
type: z6.literal("global"),
|
|
2701
|
+
name: z6.string(),
|
|
2702
|
+
function_type: FunctionTypeEnum.optional().default("scorer")
|
|
2703
|
+
})
|
|
2704
|
+
]);
|
|
2690
2705
|
var TopicMapGenerationSettings = z6.object({
|
|
2691
|
-
algorithm: z6.enum(["hdbscan", "kmeans"]),
|
|
2706
|
+
algorithm: z6.enum(["hdbscan", "kmeans", "community"]),
|
|
2692
2707
|
dimension_reduction: z6.enum(["umap", "pca", "none"]),
|
|
2693
2708
|
sample_size: z6.number().int().gt(0).optional(),
|
|
2694
2709
|
n_clusters: z6.number().int().gt(0).optional(),
|
|
@@ -2700,6 +2715,7 @@ var TopicMapGenerationSettings = z6.object({
|
|
|
2700
2715
|
var TopicMapData = z6.object({
|
|
2701
2716
|
type: z6.literal("topic_map"),
|
|
2702
2717
|
source_facet: z6.string(),
|
|
2718
|
+
source_facet_function: SavedFunctionId.and(z6.unknown()).optional(),
|
|
2703
2719
|
embedding_model: z6.string(),
|
|
2704
2720
|
bundle_key: z6.string().optional(),
|
|
2705
2721
|
report_key: z6.string().optional(),
|
|
@@ -2713,7 +2729,7 @@ var TopicMapData = z6.object({
|
|
|
2713
2729
|
});
|
|
2714
2730
|
var BatchedFacetData = z6.object({
|
|
2715
2731
|
type: z6.literal("batched_facet"),
|
|
2716
|
-
preprocessor:
|
|
2732
|
+
preprocessor: FacetPreprocessorId.optional(),
|
|
2717
2733
|
facets: z6.array(
|
|
2718
2734
|
z6.object({
|
|
2719
2735
|
name: z6.string(),
|
|
@@ -2974,18 +2990,6 @@ var ObjectReferenceNullish = z6.union([
|
|
|
2974
2990
|
}),
|
|
2975
2991
|
z6.null()
|
|
2976
2992
|
]);
|
|
2977
|
-
var SavedFunctionId = z6.union([
|
|
2978
|
-
z6.object({
|
|
2979
|
-
type: z6.literal("function"),
|
|
2980
|
-
id: z6.string(),
|
|
2981
|
-
version: z6.string().optional()
|
|
2982
|
-
}),
|
|
2983
|
-
z6.object({
|
|
2984
|
-
type: z6.literal("global"),
|
|
2985
|
-
name: z6.string(),
|
|
2986
|
-
function_type: FunctionTypeEnum.optional().default("scorer")
|
|
2987
|
-
})
|
|
2988
|
-
]);
|
|
2989
2993
|
var DatasetEvent = z6.object({
|
|
2990
2994
|
id: z6.string(),
|
|
2991
2995
|
_xact_id: z6.string(),
|
|
@@ -3207,7 +3211,7 @@ var ExtendedSavedFunctionId = z6.union([
|
|
|
3207
3211
|
]);
|
|
3208
3212
|
var FacetData = z6.object({
|
|
3209
3213
|
type: z6.literal("facet"),
|
|
3210
|
-
preprocessor:
|
|
3214
|
+
preprocessor: FacetPreprocessorId.optional(),
|
|
3211
3215
|
prompt: z6.string(),
|
|
3212
3216
|
model: z6.string().optional(),
|
|
3213
3217
|
embedding_model: z6.string().optional(),
|
|
@@ -3712,6 +3716,19 @@ var MessageRole = z6.enum([
|
|
|
3712
3716
|
"model",
|
|
3713
3717
|
"developer"
|
|
3714
3718
|
]);
|
|
3719
|
+
var NullableSavedFunctionId = z6.union([
|
|
3720
|
+
z6.object({
|
|
3721
|
+
type: z6.literal("function"),
|
|
3722
|
+
id: z6.string(),
|
|
3723
|
+
version: z6.string().optional()
|
|
3724
|
+
}),
|
|
3725
|
+
z6.object({
|
|
3726
|
+
type: z6.literal("global"),
|
|
3727
|
+
name: z6.string(),
|
|
3728
|
+
function_type: FunctionTypeEnum.optional().default("scorer")
|
|
3729
|
+
}),
|
|
3730
|
+
z6.null()
|
|
3731
|
+
]);
|
|
3715
3732
|
var ObjectReference = z6.object({
|
|
3716
3733
|
object_type: z6.enum([
|
|
3717
3734
|
"project_logs",
|
|
@@ -3733,6 +3750,7 @@ var TraceScope = z6.object({
|
|
|
3733
3750
|
});
|
|
3734
3751
|
var OnlineScoreConfig = z6.union([
|
|
3735
3752
|
z6.object({
|
|
3753
|
+
status: AutomationStatus.optional(),
|
|
3736
3754
|
sampling_rate: z6.number().gte(0).lte(1),
|
|
3737
3755
|
scorers: z6.array(SavedFunctionId),
|
|
3738
3756
|
btql_filter: z6.union([z6.string(), z6.null()]).optional(),
|
|
@@ -3813,6 +3831,72 @@ var Project = z6.object({
|
|
|
3813
3831
|
user_id: z6.union([z6.string(), z6.null()]).optional(),
|
|
3814
3832
|
settings: ProjectSettings.optional()
|
|
3815
3833
|
});
|
|
3834
|
+
var WindowedAutomationConfig = z6.object({
|
|
3835
|
+
event_type: z6.literal("windowed"),
|
|
3836
|
+
product_origin: z6.union([z6.literal("patterns"), z6.null()]).optional(),
|
|
3837
|
+
status: AutomationStatus.optional(),
|
|
3838
|
+
threshold: z6.object({
|
|
3839
|
+
calculation: z6.object({
|
|
3840
|
+
type: z6.literal("btql"),
|
|
3841
|
+
btql_query: z6.string().min(1),
|
|
3842
|
+
output: z6.object({
|
|
3843
|
+
type: z6.literal("scalar"),
|
|
3844
|
+
value_column: z6.string().min(1)
|
|
3845
|
+
})
|
|
3846
|
+
}),
|
|
3847
|
+
policy: z6.object({
|
|
3848
|
+
condition: z6.object({
|
|
3849
|
+
type: z6.literal("threshold"),
|
|
3850
|
+
operator: z6.enum(["lt", "lte", "gt", "gte", "eq", "neq"]),
|
|
3851
|
+
threshold: z6.number()
|
|
3852
|
+
}),
|
|
3853
|
+
pending_seconds: z6.number().int().gte(0).lte(2592e3),
|
|
3854
|
+
no_data_behavior: z6.enum(["keep_last", "resolve", "alert"]),
|
|
3855
|
+
renotify_interval_seconds: z6.union([z6.number(), z6.null()]).optional(),
|
|
3856
|
+
notify_on_recovery: z6.boolean().optional().default(true)
|
|
3857
|
+
})
|
|
3858
|
+
}).optional(),
|
|
3859
|
+
window: z6.object({
|
|
3860
|
+
window_seconds: z6.number().int().gte(1).lte(2592e3),
|
|
3861
|
+
schedule: z6.union([
|
|
3862
|
+
z6.object({
|
|
3863
|
+
type: z6.literal("interval"),
|
|
3864
|
+
evaluation_interval_seconds: z6.number().int().gte(1).lte(2592e3)
|
|
3865
|
+
}),
|
|
3866
|
+
z6.object({
|
|
3867
|
+
type: z6.literal("cron"),
|
|
3868
|
+
cron_expression: z6.string().min(1),
|
|
3869
|
+
timezone: z6.union([z6.string(), z6.null()]).optional()
|
|
3870
|
+
})
|
|
3871
|
+
]),
|
|
3872
|
+
evaluation_delay_seconds: z6.number().int().gte(0).lte(2592e3)
|
|
3873
|
+
}),
|
|
3874
|
+
loop: z6.object({
|
|
3875
|
+
prompt: z6.string().min(1).max(1e4),
|
|
3876
|
+
include_trigger_input: z6.boolean().optional().default(false),
|
|
3877
|
+
agent_slug: z6.string().min(1),
|
|
3878
|
+
auto_approve_tools: z6.array(z6.string().min(1)).optional().default([]),
|
|
3879
|
+
harness: z6.enum(["native", "codex", "claude-code"]).optional(),
|
|
3880
|
+
model: z6.string().min(1).optional(),
|
|
3881
|
+
reasoning_effort: z6.enum(["none", "minimal", "low", "medium", "high", "xhigh", "max"]).optional()
|
|
3882
|
+
}).optional(),
|
|
3883
|
+
actions: z6.array(
|
|
3884
|
+
z6.union([
|
|
3885
|
+
z6.object({
|
|
3886
|
+
type: z6.literal("webhook"),
|
|
3887
|
+
url: z6.string(),
|
|
3888
|
+
formatting_prompt: z6.string().min(1).max(1e4).optional()
|
|
3889
|
+
}),
|
|
3890
|
+
z6.object({
|
|
3891
|
+
type: z6.literal("slack"),
|
|
3892
|
+
workspace_id: z6.string(),
|
|
3893
|
+
channel: z6.string(),
|
|
3894
|
+
message_template: z6.string().optional(),
|
|
3895
|
+
formatting_prompt: z6.string().min(1).max(1e4).optional()
|
|
3896
|
+
})
|
|
3897
|
+
])
|
|
3898
|
+
).max(20).optional().default([])
|
|
3899
|
+
});
|
|
3816
3900
|
var TopicAutomationFacetModel = z6.union([
|
|
3817
3901
|
z6.enum(["brain-facet-latest", "brain-facet-1", "brain-facet-2"]),
|
|
3818
3902
|
z6.null()
|
|
@@ -3854,7 +3938,8 @@ var TopicDigestAutomationConfig = z6.object({
|
|
|
3854
3938
|
type: z6.literal("slack"),
|
|
3855
3939
|
workspace_id: z6.string(),
|
|
3856
3940
|
channel: z6.string(),
|
|
3857
|
-
message_template: z6.string().optional()
|
|
3941
|
+
message_template: z6.string().optional(),
|
|
3942
|
+
formatting_prompt: z6.string().min(1).max(1e4).optional()
|
|
3858
3943
|
}),
|
|
3859
3944
|
topic_map_function_ids: z6.array(z6.string()).max(10).optional()
|
|
3860
3945
|
});
|
|
@@ -3868,15 +3953,21 @@ var ProjectAutomation = z6.object({
|
|
|
3868
3953
|
config: z6.union([
|
|
3869
3954
|
z6.object({
|
|
3870
3955
|
event_type: z6.literal("logs"),
|
|
3956
|
+
status: AutomationStatus.optional(),
|
|
3871
3957
|
btql_filter: z6.string(),
|
|
3872
3958
|
interval_seconds: z6.number().gte(1).lte(2592e3),
|
|
3873
3959
|
action: z6.union([
|
|
3874
|
-
z6.object({
|
|
3960
|
+
z6.object({
|
|
3961
|
+
type: z6.literal("webhook"),
|
|
3962
|
+
url: z6.string(),
|
|
3963
|
+
formatting_prompt: z6.string().min(1).max(1e4).optional()
|
|
3964
|
+
}),
|
|
3875
3965
|
z6.object({
|
|
3876
3966
|
type: z6.literal("slack"),
|
|
3877
3967
|
workspace_id: z6.string(),
|
|
3878
3968
|
channel: z6.string(),
|
|
3879
|
-
message_template: z6.string().optional()
|
|
3969
|
+
message_template: z6.string().optional(),
|
|
3970
|
+
formatting_prompt: z6.string().min(1).max(1e4).optional()
|
|
3880
3971
|
})
|
|
3881
3972
|
])
|
|
3882
3973
|
}),
|
|
@@ -3927,21 +4018,38 @@ var ProjectAutomation = z6.object({
|
|
|
3927
4018
|
}),
|
|
3928
4019
|
z6.object({
|
|
3929
4020
|
event_type: z6.literal("environment_update"),
|
|
4021
|
+
status: AutomationStatus.optional(),
|
|
3930
4022
|
environment_filter: z6.array(z6.string()).optional(),
|
|
3931
4023
|
action: z6.union([
|
|
3932
|
-
z6.object({
|
|
4024
|
+
z6.object({
|
|
4025
|
+
type: z6.literal("webhook"),
|
|
4026
|
+
url: z6.string(),
|
|
4027
|
+
formatting_prompt: z6.string().min(1).max(1e4).optional()
|
|
4028
|
+
}),
|
|
3933
4029
|
z6.object({
|
|
3934
4030
|
type: z6.literal("slack"),
|
|
3935
4031
|
workspace_id: z6.string(),
|
|
3936
4032
|
channel: z6.string(),
|
|
3937
|
-
message_template: z6.string().optional()
|
|
4033
|
+
message_template: z6.string().optional(),
|
|
4034
|
+
formatting_prompt: z6.string().min(1).max(1e4).optional()
|
|
3938
4035
|
})
|
|
3939
4036
|
])
|
|
3940
4037
|
}),
|
|
4038
|
+
WindowedAutomationConfig,
|
|
3941
4039
|
TopicAutomationConfig,
|
|
3942
4040
|
TopicDigestAutomationConfig
|
|
3943
4041
|
])
|
|
3944
4042
|
});
|
|
4043
|
+
var ProjectGroup = z6.object({
|
|
4044
|
+
id: z6.string().uuid(),
|
|
4045
|
+
org_id: z6.string().uuid(),
|
|
4046
|
+
user_id: z6.union([z6.string(), z6.null()]).optional(),
|
|
4047
|
+
created: z6.union([z6.string(), z6.null()]).optional(),
|
|
4048
|
+
name: z6.string(),
|
|
4049
|
+
description: z6.union([z6.string(), z6.null()]).optional(),
|
|
4050
|
+
deleted_at: z6.union([z6.string(), z6.null()]).optional(),
|
|
4051
|
+
member_projects: z6.array(z6.string().uuid()).max(1e4)
|
|
4052
|
+
});
|
|
3945
4053
|
var ProjectLogsEvent = z6.object({
|
|
3946
4054
|
id: z6.string(),
|
|
3947
4055
|
_xact_id: z6.string(),
|
|
@@ -4159,7 +4267,8 @@ var RunEval = z6.object({
|
|
|
4159
4267
|
dataset_environment: z6.union([z6.string(), z6.null()]).optional(),
|
|
4160
4268
|
_internal_btql: z6.union([z6.object({}).partial().passthrough(), z6.null()]).optional()
|
|
4161
4269
|
}),
|
|
4162
|
-
z6.object({ data: z6.array(z6.unknown()) })
|
|
4270
|
+
z6.object({ data: z6.array(z6.unknown()) }),
|
|
4271
|
+
z6.object({ experiment_name: z6.string() })
|
|
4163
4272
|
]),
|
|
4164
4273
|
name: z6.string().optional(),
|
|
4165
4274
|
parameters: z6.object({}).partial().passthrough().optional(),
|
|
@@ -4364,7 +4473,9 @@ var View = z6.object({
|
|
|
4364
4473
|
"for_review_datasets"
|
|
4365
4474
|
]),
|
|
4366
4475
|
name: z6.string(),
|
|
4476
|
+
description: z6.union([z6.string(), z6.null()]).optional(),
|
|
4367
4477
|
created: z6.union([z6.string(), z6.null()]).optional(),
|
|
4478
|
+
updated_at: z6.union([z6.string(), z6.null()]).optional(),
|
|
4368
4479
|
view_data: ViewData.optional(),
|
|
4369
4480
|
options: ViewOptions.optional(),
|
|
4370
4481
|
user_id: z6.union([z6.string(), z6.null()]).optional(),
|
|
@@ -4700,7 +4811,7 @@ var BraintrustStream = class _BraintrustStream {
|
|
|
4700
4811
|
}
|
|
4701
4812
|
};
|
|
4702
4813
|
function btStreamParser() {
|
|
4703
|
-
const
|
|
4814
|
+
const decoder2 = new TextDecoder();
|
|
4704
4815
|
let parser;
|
|
4705
4816
|
return new TransformStream({
|
|
4706
4817
|
async start(controller) {
|
|
@@ -4717,7 +4828,7 @@ function btStreamParser() {
|
|
|
4717
4828
|
},
|
|
4718
4829
|
async transform(chunk, controller) {
|
|
4719
4830
|
if (chunk instanceof Uint8Array) {
|
|
4720
|
-
parser.feed(
|
|
4831
|
+
parser.feed(decoder2.decode(chunk, { stream: true }));
|
|
4721
4832
|
} else if (typeof chunk === "string") {
|
|
4722
4833
|
parser.feed(chunk);
|
|
4723
4834
|
} else {
|
|
@@ -4725,7 +4836,7 @@ function btStreamParser() {
|
|
|
4725
4836
|
}
|
|
4726
4837
|
},
|
|
4727
4838
|
async flush(controller) {
|
|
4728
|
-
const tail =
|
|
4839
|
+
const tail = decoder2.decode();
|
|
4729
4840
|
if (tail) {
|
|
4730
4841
|
parser.feed(tail);
|
|
4731
4842
|
}
|
|
@@ -4734,7 +4845,7 @@ function btStreamParser() {
|
|
|
4734
4845
|
});
|
|
4735
4846
|
}
|
|
4736
4847
|
function createFinalValuePassThroughStream(onFinal, onError) {
|
|
4737
|
-
const
|
|
4848
|
+
const decoder2 = new TextDecoder();
|
|
4738
4849
|
const textChunks = [];
|
|
4739
4850
|
const jsonChunks = [];
|
|
4740
4851
|
const reasoningChunks = [];
|
|
@@ -4747,10 +4858,10 @@ function createFinalValuePassThroughStream(onFinal, onError) {
|
|
|
4747
4858
|
data: chunk
|
|
4748
4859
|
});
|
|
4749
4860
|
} else if (chunk instanceof Uint8Array) {
|
|
4750
|
-
textChunks.push(
|
|
4861
|
+
textChunks.push(decoder2.decode(chunk));
|
|
4751
4862
|
controller.enqueue({
|
|
4752
4863
|
type: "text_delta",
|
|
4753
|
-
data:
|
|
4864
|
+
data: decoder2.decode(chunk)
|
|
4754
4865
|
});
|
|
4755
4866
|
} else if (braintrustStreamChunkSchema.safeParse(chunk).success) {
|
|
4756
4867
|
const chunkType = chunk.type;
|
|
@@ -5491,12 +5602,13 @@ var INSTRUMENTATION_NAMES = {
|
|
|
5491
5602
|
OPENROUTER: "openrouter",
|
|
5492
5603
|
OPENROUTER_AGENT: "openrouter-agent",
|
|
5493
5604
|
PI_CODING_AGENT: "pi-coding-agent",
|
|
5494
|
-
STRANDS_AGENT_SDK: "strands-agent-sdk"
|
|
5605
|
+
STRANDS_AGENT_SDK: "strands-agent-sdk",
|
|
5606
|
+
VOYAGEAI: "voyageai"
|
|
5495
5607
|
};
|
|
5496
5608
|
var INTERNAL_SPAN_INSTRUMENTATION_NAME = /* @__PURE__ */ Symbol.for(
|
|
5497
5609
|
"braintrust.spanInstrumentationName"
|
|
5498
5610
|
);
|
|
5499
|
-
var SDK_VERSION = true ? "3.
|
|
5611
|
+
var SDK_VERSION = true ? "3.28.0" : "0.0.0";
|
|
5500
5612
|
function withSpanInstrumentationName(args, instrumentationName) {
|
|
5501
5613
|
return {
|
|
5502
5614
|
...args,
|
|
@@ -5691,6 +5803,9 @@ function applyMaskingToField(maskingFunction, data, fieldName) {
|
|
|
5691
5803
|
var INITIAL_SPAN_WRITE_AS_MERGE = /* @__PURE__ */ Symbol(
|
|
5692
5804
|
"braintrust.initial-span-write-as-merge"
|
|
5693
5805
|
);
|
|
5806
|
+
var RESUME_SPAN_WITHOUT_INITIAL_WRITE = /* @__PURE__ */ Symbol(
|
|
5807
|
+
"braintrust.resume-span-without-initial-write"
|
|
5808
|
+
);
|
|
5694
5809
|
var INTERNAL_SPAN_CONTEXT = /* @__PURE__ */ Symbol("braintrust.internal-span-context");
|
|
5695
5810
|
var BRAINTRUST_CURRENT_SPAN_STORE = /* @__PURE__ */ Symbol.for(
|
|
5696
5811
|
"braintrust.currentSpanStore"
|
|
@@ -6914,6 +7029,30 @@ function updateSpan({
|
|
|
6914
7029
|
event
|
|
6915
7030
|
});
|
|
6916
7031
|
}
|
|
7032
|
+
function _internalResumeSpan({
|
|
7033
|
+
exported,
|
|
7034
|
+
state
|
|
7035
|
+
}) {
|
|
7036
|
+
const resolvedState = state ?? _globalState;
|
|
7037
|
+
const components = SpanComponentsV4.fromStr(exported);
|
|
7038
|
+
const { row_id, root_span_id, span_id } = components.data;
|
|
7039
|
+
if (!row_id || !root_span_id || !span_id) {
|
|
7040
|
+
throw new Error("Only exported root spans can be resumed");
|
|
7041
|
+
}
|
|
7042
|
+
return new SpanImpl({
|
|
7043
|
+
state: resolvedState,
|
|
7044
|
+
parentObjectType: components.data.object_type,
|
|
7045
|
+
parentObjectId: new LazyValue(
|
|
7046
|
+
spanComponentsToObjectIdLambda(resolvedState, components)
|
|
7047
|
+
),
|
|
7048
|
+
parentComputeObjectMetadataArgs: void 0,
|
|
7049
|
+
parentSpanIds: { parentSpanIds: [], rootSpanId: root_span_id },
|
|
7050
|
+
spanId: span_id,
|
|
7051
|
+
event: { id: row_id },
|
|
7052
|
+
propagatedEvent: components.data.propagated_event ?? void 0,
|
|
7053
|
+
[RESUME_SPAN_WITHOUT_INITIAL_WRITE]: true
|
|
7054
|
+
});
|
|
7055
|
+
}
|
|
6917
7056
|
function spanComponentsToObjectIdLambda(state, components) {
|
|
6918
7057
|
if (components.data.object_id) {
|
|
6919
7058
|
const ret = components.data.object_id;
|
|
@@ -9794,7 +9933,7 @@ var ObjectFetcher = class {
|
|
|
9794
9933
|
const objectId = await this.id;
|
|
9795
9934
|
const batchLimit = batchSize ?? DEFAULT_FETCH_BATCH_SIZE;
|
|
9796
9935
|
const internalLimit = getInternalBtqlLimit(this._internal_btql);
|
|
9797
|
-
|
|
9936
|
+
let remainingLimit = internalLimit;
|
|
9798
9937
|
const internalBtqlWithoutReservedQueryKeys = Object.fromEntries(
|
|
9799
9938
|
Object.entries(this._internal_btql ?? {}).filter(
|
|
9800
9939
|
([key]) => key !== "cursor" && key !== "limit" && key !== "select" && key !== "from"
|
|
@@ -9803,6 +9942,10 @@ var ObjectFetcher = class {
|
|
|
9803
9942
|
let cursor = void 0;
|
|
9804
9943
|
let iterations = 0;
|
|
9805
9944
|
while (true) {
|
|
9945
|
+
if (remainingLimit !== void 0 && remainingLimit <= 0) {
|
|
9946
|
+
return;
|
|
9947
|
+
}
|
|
9948
|
+
const limit = remainingLimit === void 0 ? batchLimit : Math.min(batchLimit, remainingLimit);
|
|
9806
9949
|
const resp = await state.apiConn().post(
|
|
9807
9950
|
`btql`,
|
|
9808
9951
|
{
|
|
@@ -9842,7 +9985,14 @@ var ObjectFetcher = class {
|
|
|
9842
9985
|
const respJson = await resp.json();
|
|
9843
9986
|
const mutate = this.mutateRecord;
|
|
9844
9987
|
for (const record of respJson.data ?? []) {
|
|
9845
|
-
|
|
9988
|
+
if (remainingLimit !== void 0 && remainingLimit <= 0) {
|
|
9989
|
+
return;
|
|
9990
|
+
}
|
|
9991
|
+
const mutatedRecord = mutate ? mutate(record) : record;
|
|
9992
|
+
if (remainingLimit !== void 0) {
|
|
9993
|
+
remainingLimit--;
|
|
9994
|
+
}
|
|
9995
|
+
yield mutatedRecord;
|
|
9846
9996
|
}
|
|
9847
9997
|
if (!respJson.cursor) {
|
|
9848
9998
|
break;
|
|
@@ -10362,7 +10512,9 @@ var SpanImpl = class _SpanImpl {
|
|
|
10362
10512
|
this._rootSpanId = resolvedIds.rootSpanId;
|
|
10363
10513
|
this._spanParents = resolvedIds.spanParents;
|
|
10364
10514
|
this.isMerge = args[INITIAL_SPAN_WRITE_AS_MERGE] === true;
|
|
10365
|
-
|
|
10515
|
+
if (!args[RESUME_SPAN_WITHOUT_INITIAL_WRITE]) {
|
|
10516
|
+
this.logInternal({ event, internalData });
|
|
10517
|
+
}
|
|
10366
10518
|
this.isMerge = true;
|
|
10367
10519
|
}
|
|
10368
10520
|
getParentInfo() {
|
|
@@ -13018,6 +13170,22 @@ function processInputAttachments(input) {
|
|
|
13018
13170
|
};
|
|
13019
13171
|
}
|
|
13020
13172
|
}
|
|
13173
|
+
const voyageBase64Key = node.type === "image_base64" ? Object.hasOwn(node, "imageBase64") ? "imageBase64" : "image_base64" : node.type === "video_base64" ? Object.hasOwn(node, "videoBase64") ? "videoBase64" : "video_base64" : void 0;
|
|
13174
|
+
const voyageBase64Value = voyageBase64Key ? node[voyageBase64Key] : void 0;
|
|
13175
|
+
if (voyageBase64Key && typeof voyageBase64Value === "string" && voyageBase64Value.startsWith("data:")) {
|
|
13176
|
+
const mediaType = inferMediaTypeFromDataUrl(
|
|
13177
|
+
voyageBase64Value,
|
|
13178
|
+
node.type === "video_base64" ? "video/mp4" : "image/png"
|
|
13179
|
+
);
|
|
13180
|
+
const filename = `${node.type === "video_base64" ? "video" : "image"}.${getExtensionFromMediaType(mediaType)}`;
|
|
13181
|
+
const attachment = toAttachment(voyageBase64Value, mediaType, filename);
|
|
13182
|
+
if (attachment) {
|
|
13183
|
+
return {
|
|
13184
|
+
...node,
|
|
13185
|
+
[voyageBase64Key]: attachment
|
|
13186
|
+
};
|
|
13187
|
+
}
|
|
13188
|
+
}
|
|
13021
13189
|
if (node.type === "file" && node.file && typeof node.file === "object" && typeof node.file.file_data === "string" && node.file.file_data.startsWith("data:")) {
|
|
13022
13190
|
const mediaType = inferMediaTypeFromDataUrl(
|
|
13023
13191
|
node.file.file_data,
|
|
@@ -14365,12 +14533,30 @@ function logInstrumentationError(context, error) {
|
|
|
14365
14533
|
|
|
14366
14534
|
// src/wrappers/anthropic-tokens-util.ts
|
|
14367
14535
|
function finalizeAnthropicTokens(metrics) {
|
|
14368
|
-
const
|
|
14369
|
-
|
|
14536
|
+
const hasSplitCacheCreationTokens = metrics.prompt_cache_creation_5m_tokens !== void 0 || metrics.prompt_cache_creation_1h_tokens !== void 0;
|
|
14537
|
+
const splitCacheCreationTokens = (metrics.prompt_cache_creation_5m_tokens || 0) + (metrics.prompt_cache_creation_1h_tokens || 0);
|
|
14538
|
+
const aggregateCacheCreationTokens = metrics.prompt_cache_creation_tokens || 0;
|
|
14539
|
+
const effectiveCacheCreationTokens = Math.max(
|
|
14540
|
+
aggregateCacheCreationTokens,
|
|
14541
|
+
splitCacheCreationTokens
|
|
14542
|
+
);
|
|
14543
|
+
const prompt_tokens = (metrics.prompt_tokens || 0) + (metrics.prompt_cached_tokens || 0) + effectiveCacheCreationTokens;
|
|
14544
|
+
const finalized = {
|
|
14370
14545
|
...metrics,
|
|
14371
14546
|
prompt_tokens,
|
|
14372
14547
|
tokens: prompt_tokens + (metrics.completion_tokens || 0)
|
|
14373
14548
|
};
|
|
14549
|
+
if (hasSplitCacheCreationTokens && splitCacheCreationTokens >= aggregateCacheCreationTokens) {
|
|
14550
|
+
delete finalized.prompt_cache_creation_tokens;
|
|
14551
|
+
}
|
|
14552
|
+
return finalized;
|
|
14553
|
+
}
|
|
14554
|
+
function toNumericMetrics(metrics) {
|
|
14555
|
+
return Object.fromEntries(
|
|
14556
|
+
Object.entries(metrics).filter(
|
|
14557
|
+
(entry) => entry[1] !== void 0
|
|
14558
|
+
)
|
|
14559
|
+
);
|
|
14374
14560
|
}
|
|
14375
14561
|
function extractAnthropicCacheTokens(cacheReadTokens = 0, cacheCreationTokens = 0) {
|
|
14376
14562
|
const cacheTokens = {};
|
|
@@ -14976,6 +15162,18 @@ function parseMetricsFromUsage2(usage) {
|
|
|
14976
15162
|
saveIfExistsTo("output_tokens", "completion_tokens");
|
|
14977
15163
|
saveIfExistsTo("cache_read_input_tokens", "prompt_cached_tokens");
|
|
14978
15164
|
saveIfExistsTo("cache_creation_input_tokens", "prompt_cache_creation_tokens");
|
|
15165
|
+
if (isObject(usage.cache_creation)) {
|
|
15166
|
+
const cacheCreation = usage.cache_creation;
|
|
15167
|
+
for (const [source, target] of [
|
|
15168
|
+
["ephemeral_5m_input_tokens", "prompt_cache_creation_5m_tokens"],
|
|
15169
|
+
["ephemeral_1h_input_tokens", "prompt_cache_creation_1h_tokens"]
|
|
15170
|
+
]) {
|
|
15171
|
+
const value = cacheCreation[source];
|
|
15172
|
+
if (typeof value === "number") {
|
|
15173
|
+
metrics[target] = value;
|
|
15174
|
+
}
|
|
15175
|
+
}
|
|
15176
|
+
}
|
|
14979
15177
|
if (isObject(usage.server_tool_use)) {
|
|
14980
15178
|
for (const [name, value] of Object.entries(usage.server_tool_use)) {
|
|
14981
15179
|
if (typeof value === "number") {
|
|
@@ -20274,37 +20472,97 @@ function seedTaskToolUseIdMapping(taskIdToToolUseId, message) {
|
|
|
20274
20472
|
taskIdToToolUseId.set(message.task_id, message.tool_use_id);
|
|
20275
20473
|
}
|
|
20276
20474
|
}
|
|
20277
|
-
function
|
|
20278
|
-
|
|
20279
|
-
|
|
20280
|
-
|
|
20281
|
-
usage = message.message?.usage;
|
|
20282
|
-
} else if (message.type === "result") {
|
|
20283
|
-
usage = message.usage;
|
|
20284
|
-
}
|
|
20475
|
+
function tokenCount(value) {
|
|
20476
|
+
return typeof value === "number" && Number.isFinite(value) && Number.isInteger(value) && value >= 0 ? value : void 0;
|
|
20477
|
+
}
|
|
20478
|
+
function copyUsage(usage) {
|
|
20285
20479
|
if (!usage || typeof usage !== "object") {
|
|
20286
|
-
return
|
|
20480
|
+
return void 0;
|
|
20481
|
+
}
|
|
20482
|
+
const copy = {};
|
|
20483
|
+
for (const key of [
|
|
20484
|
+
"input_tokens",
|
|
20485
|
+
"output_tokens",
|
|
20486
|
+
"cache_read_input_tokens",
|
|
20487
|
+
"cache_creation_input_tokens"
|
|
20488
|
+
]) {
|
|
20489
|
+
const value = tokenCount(Reflect.get(usage, key));
|
|
20490
|
+
if (value !== void 0) {
|
|
20491
|
+
copy[key] = value;
|
|
20492
|
+
}
|
|
20493
|
+
}
|
|
20494
|
+
const cacheCreation = Reflect.get(usage, "cache_creation");
|
|
20495
|
+
if (cacheCreation && typeof cacheCreation === "object") {
|
|
20496
|
+
const cacheCreationCopy = {};
|
|
20497
|
+
for (const key of [
|
|
20498
|
+
"ephemeral_5m_input_tokens",
|
|
20499
|
+
"ephemeral_1h_input_tokens"
|
|
20500
|
+
]) {
|
|
20501
|
+
const value = tokenCount(Reflect.get(cacheCreation, key));
|
|
20502
|
+
if (value !== void 0) {
|
|
20503
|
+
cacheCreationCopy[key] = value;
|
|
20504
|
+
}
|
|
20505
|
+
}
|
|
20506
|
+
if (Object.keys(cacheCreationCopy).length > 0) {
|
|
20507
|
+
copy.cache_creation = cacheCreationCopy;
|
|
20508
|
+
}
|
|
20509
|
+
}
|
|
20510
|
+
return Object.keys(copy).length > 0 ? copy : void 0;
|
|
20511
|
+
}
|
|
20512
|
+
function mergeUsage(base, override) {
|
|
20513
|
+
if (!base || !override) {
|
|
20514
|
+
return override ?? base;
|
|
20515
|
+
}
|
|
20516
|
+
const cacheCreation = base.cache_creation || override.cache_creation ? { ...base.cache_creation, ...override.cache_creation } : void 0;
|
|
20517
|
+
return {
|
|
20518
|
+
...base,
|
|
20519
|
+
...override,
|
|
20520
|
+
...cacheCreation && { cache_creation: cacheCreation }
|
|
20521
|
+
};
|
|
20522
|
+
}
|
|
20523
|
+
function extractUsage(usage, includeOutput) {
|
|
20524
|
+
const metrics = {};
|
|
20525
|
+
if (!usage) {
|
|
20526
|
+
return {};
|
|
20287
20527
|
}
|
|
20288
20528
|
const inputTokens = getNumberProperty(usage, "input_tokens");
|
|
20289
20529
|
if (inputTokens !== void 0) {
|
|
20290
20530
|
metrics.prompt_tokens = inputTokens;
|
|
20291
20531
|
}
|
|
20292
|
-
|
|
20293
|
-
|
|
20294
|
-
|
|
20532
|
+
if (includeOutput) {
|
|
20533
|
+
const outputTokens = getNumberProperty(usage, "output_tokens");
|
|
20534
|
+
if (outputTokens !== void 0) {
|
|
20535
|
+
metrics.completion_tokens = outputTokens;
|
|
20536
|
+
}
|
|
20295
20537
|
}
|
|
20296
20538
|
const cacheReadTokens = getNumberProperty(usage, "cache_read_input_tokens") || 0;
|
|
20297
20539
|
const cacheCreationTokens = getNumberProperty(usage, "cache_creation_input_tokens") || 0;
|
|
20298
|
-
|
|
20299
|
-
|
|
20300
|
-
|
|
20301
|
-
|
|
20302
|
-
|
|
20540
|
+
Object.assign(
|
|
20541
|
+
metrics,
|
|
20542
|
+
extractAnthropicCacheTokens(cacheReadTokens, cacheCreationTokens)
|
|
20543
|
+
);
|
|
20544
|
+
const cacheCreation5mTokens = getNumberProperty(
|
|
20545
|
+
usage.cache_creation,
|
|
20546
|
+
"ephemeral_5m_input_tokens"
|
|
20547
|
+
);
|
|
20548
|
+
const cacheCreation1hTokens = getNumberProperty(
|
|
20549
|
+
usage.cache_creation,
|
|
20550
|
+
"ephemeral_1h_input_tokens"
|
|
20551
|
+
);
|
|
20552
|
+
if (cacheCreation5mTokens !== void 0) {
|
|
20553
|
+
metrics.prompt_cache_creation_5m_tokens = cacheCreation5mTokens;
|
|
20303
20554
|
}
|
|
20304
|
-
if (
|
|
20305
|
-
|
|
20555
|
+
if (cacheCreation1hTokens !== void 0) {
|
|
20556
|
+
metrics.prompt_cache_creation_1h_tokens = cacheCreation1hTokens;
|
|
20306
20557
|
}
|
|
20307
|
-
|
|
20558
|
+
if (Object.keys(metrics).length === 0) {
|
|
20559
|
+
return {};
|
|
20560
|
+
}
|
|
20561
|
+
const finalized = finalizeAnthropicTokens(metrics);
|
|
20562
|
+
if (metrics.completion_tokens === void 0) {
|
|
20563
|
+
delete finalized.tokens;
|
|
20564
|
+
}
|
|
20565
|
+
return toNumericMetrics(finalized);
|
|
20308
20566
|
}
|
|
20309
20567
|
function buildLLMInput(promptMessages, conversationHistory) {
|
|
20310
20568
|
const inputParts = [...promptMessages, ...conversationHistory];
|
|
@@ -20338,16 +20596,16 @@ function buildRootPromptMessages(prompt, capturedPromptMessages) {
|
|
|
20338
20596
|
function formatCapturedMessages(messages) {
|
|
20339
20597
|
return messages.length > 0 ? messages : [];
|
|
20340
20598
|
}
|
|
20341
|
-
async function createLLMSpanForMessages(messages, promptMessages, conversationHistory, options, startTime, parentSpan, existingSpan) {
|
|
20599
|
+
async function createLLMSpanForMessages(messages, promptMessages, conversationHistory, options, startTime, parentSpan, usage, hasFinalOutputUsage, existingSpan) {
|
|
20342
20600
|
if (messages.length === 0) {
|
|
20343
20601
|
return void 0;
|
|
20344
20602
|
}
|
|
20345
20603
|
const lastMessage = messages[messages.length - 1];
|
|
20346
|
-
if (lastMessage.type !== "assistant"
|
|
20604
|
+
if (lastMessage.type !== "assistant") {
|
|
20347
20605
|
return void 0;
|
|
20348
20606
|
}
|
|
20349
|
-
const model = lastMessage.message
|
|
20350
|
-
const
|
|
20607
|
+
const model = lastMessage.message?.model || options.model;
|
|
20608
|
+
const metrics = options.includePartialMessages ? extractUsage(usage, hasFinalOutputUsage) : {};
|
|
20351
20609
|
const input = buildLLMInput(promptMessages, conversationHistory);
|
|
20352
20610
|
const outputs = messages.map(
|
|
20353
20611
|
(m) => m.message?.content && m.message?.role ? { content: m.message.content, role: m.message.role } : void 0
|
|
@@ -20369,8 +20627,8 @@ async function createLLMSpanForMessages(messages, promptMessages, conversationHi
|
|
|
20369
20627
|
);
|
|
20370
20628
|
span.log({
|
|
20371
20629
|
input,
|
|
20372
|
-
metadata: model
|
|
20373
|
-
metrics:
|
|
20630
|
+
metadata: { ...model && { model }, provider: "anthropic" },
|
|
20631
|
+
...Object.keys(metrics).length > 0 ? { metrics } : {},
|
|
20374
20632
|
output: outputs
|
|
20375
20633
|
});
|
|
20376
20634
|
const spanExport = await span.export();
|
|
@@ -20460,11 +20718,17 @@ function prepareLocalToolHandlersInMcpServers(mcpServers) {
|
|
|
20460
20718
|
}
|
|
20461
20719
|
return { hasLocalToolHandlers, localToolHookNames };
|
|
20462
20720
|
}
|
|
20463
|
-
function createToolTracingHooks(resolveParentSpan, activeToolSpans, mcpServers, localToolHookNames, skipLocalToolHooks, subAgentDetailsByToolUseId, subAgentSpans, endedSubAgentSpans) {
|
|
20721
|
+
function createToolTracingHooks(resolveParentSpan, taskIdToToolUseId, toolUseToParent, activeToolSpans, mcpServers, localToolHookNames, skipLocalToolHooks, subAgentDetailsByToolUseId, subAgentSpans, endedSubAgentSpans) {
|
|
20464
20722
|
const preToolUse = async (input, toolUseID) => {
|
|
20465
20723
|
if (input.hook_event_name !== "PreToolUse" || !toolUseID) {
|
|
20466
20724
|
return {};
|
|
20467
20725
|
}
|
|
20726
|
+
if (!toolUseToParent.has(toolUseID) && input.agent_id) {
|
|
20727
|
+
const parentToolUseId = taskIdToToolUseId.get(input.agent_id);
|
|
20728
|
+
if (parentToolUseId) {
|
|
20729
|
+
toolUseToParent.set(toolUseID, parentToolUseId);
|
|
20730
|
+
}
|
|
20731
|
+
}
|
|
20468
20732
|
if (skipLocalToolHooks && (isLocalToolUse(input.tool_name, mcpServers) || localToolHookNames.has(input.tool_name))) {
|
|
20469
20733
|
return {};
|
|
20470
20734
|
}
|
|
@@ -20660,9 +20924,6 @@ function createToolTracingHooks(resolveParentSpan, activeToolSpans, mcpServers,
|
|
|
20660
20924
|
}
|
|
20661
20925
|
const metadata = {
|
|
20662
20926
|
...subAgentDetailsToMetadata(details),
|
|
20663
|
-
...input.agent_transcript_path && {
|
|
20664
|
-
"claude_agent_sdk.agent_transcript_path": input.agent_transcript_path
|
|
20665
|
-
},
|
|
20666
20927
|
"claude_agent_sdk.stop_hook_active": input.stop_hook_active
|
|
20667
20928
|
};
|
|
20668
20929
|
try {
|
|
@@ -20684,7 +20945,7 @@ function createToolTracingHooks(resolveParentSpan, activeToolSpans, mcpServers,
|
|
|
20684
20945
|
subagentStop
|
|
20685
20946
|
};
|
|
20686
20947
|
}
|
|
20687
|
-
function injectTracingHooks(options, resolveParentSpan, activeToolSpans, localToolHookNames, skipLocalToolHooks, subAgentDetailsByToolUseId, subAgentSpans, endedSubAgentSpans) {
|
|
20948
|
+
function injectTracingHooks(options, resolveParentSpan, taskIdToToolUseId, toolUseToParent, activeToolSpans, localToolHookNames, skipLocalToolHooks, subAgentDetailsByToolUseId, subAgentSpans, endedSubAgentSpans) {
|
|
20688
20949
|
const {
|
|
20689
20950
|
preToolUse,
|
|
20690
20951
|
postToolUse,
|
|
@@ -20693,6 +20954,8 @@ function injectTracingHooks(options, resolveParentSpan, activeToolSpans, localTo
|
|
|
20693
20954
|
subagentStop
|
|
20694
20955
|
} = createToolTracingHooks(
|
|
20695
20956
|
resolveParentSpan,
|
|
20957
|
+
taskIdToToolUseId,
|
|
20958
|
+
toolUseToParent,
|
|
20696
20959
|
activeToolSpans,
|
|
20697
20960
|
options.mcpServers,
|
|
20698
20961
|
localToolHookNames,
|
|
@@ -20774,6 +21037,13 @@ async function finalizeCurrentMessageGroup(state) {
|
|
|
20774
21037
|
}
|
|
20775
21038
|
}
|
|
20776
21039
|
const existingLlmSpan = state.activeLlmSpansByParentToolUse.get(parentKey);
|
|
21040
|
+
const lastMessage = state.currentMessages[state.currentMessages.length - 1];
|
|
21041
|
+
const messageId = lastMessage?.message?.id;
|
|
21042
|
+
const usage = state.options.includePartialMessages ? mergeUsage(
|
|
21043
|
+
copyUsage(lastMessage?.message?.usage),
|
|
21044
|
+
messageId ? state.usageByMessageId.get(messageId) : void 0
|
|
21045
|
+
) : void 0;
|
|
21046
|
+
const hasFinalOutputUsage = messageId !== void 0 && state.finalOutputUsageMessageIds.has(messageId);
|
|
20777
21047
|
const llmSpanResult = await createLLMSpanForMessages(
|
|
20778
21048
|
state.currentMessages,
|
|
20779
21049
|
promptMessages,
|
|
@@ -20781,6 +21051,8 @@ async function finalizeCurrentMessageGroup(state) {
|
|
|
20781
21051
|
state.options,
|
|
20782
21052
|
state.currentMessageStartTime,
|
|
20783
21053
|
parentSpan,
|
|
21054
|
+
usage,
|
|
21055
|
+
hasFinalOutputUsage,
|
|
20784
21056
|
existingLlmSpan
|
|
20785
21057
|
);
|
|
20786
21058
|
if (llmSpanResult) {
|
|
@@ -20798,9 +21070,17 @@ async function finalizeCurrentMessageGroup(state) {
|
|
|
20798
21070
|
}
|
|
20799
21071
|
}
|
|
20800
21072
|
state.activeLlmSpansByParentToolUse.delete(parentKey);
|
|
20801
|
-
|
|
20802
|
-
|
|
20803
|
-
state.
|
|
21073
|
+
if (messageId) {
|
|
21074
|
+
state.usageByMessageId.delete(messageId);
|
|
21075
|
+
state.finalOutputUsageMessageIds.delete(messageId);
|
|
21076
|
+
for (const [
|
|
21077
|
+
parent,
|
|
21078
|
+
activeMessageId
|
|
21079
|
+
] of state.activePartialMessageIdByParentKey) {
|
|
21080
|
+
if (activeMessageId === messageId) {
|
|
21081
|
+
state.activePartialMessageIdByParentKey.delete(parent);
|
|
21082
|
+
}
|
|
21083
|
+
}
|
|
20804
21084
|
}
|
|
20805
21085
|
state.currentMessages.length = 0;
|
|
20806
21086
|
}
|
|
@@ -20891,6 +21171,10 @@ async function ensureActiveLlmSpanForParentToolUse(rootSpan, activeLlmSpansByPar
|
|
|
20891
21171
|
);
|
|
20892
21172
|
llmParentSpan = await subAgentSpan.export();
|
|
20893
21173
|
}
|
|
21174
|
+
const racedLlmSpan = activeLlmSpansByParentToolUse.get(parentKey);
|
|
21175
|
+
if (racedLlmSpan) {
|
|
21176
|
+
return racedLlmSpan;
|
|
21177
|
+
}
|
|
20894
21178
|
const llmSpan = startSpan(
|
|
20895
21179
|
withSpanInstrumentationName(
|
|
20896
21180
|
{
|
|
@@ -21010,7 +21294,49 @@ async function maybeHandleTaskLifecycleMessage(state, message) {
|
|
|
21010
21294
|
}
|
|
21011
21295
|
return true;
|
|
21012
21296
|
}
|
|
21297
|
+
function handlePartialUsageMessage(state, message) {
|
|
21298
|
+
if (message.type !== "stream_event") {
|
|
21299
|
+
return false;
|
|
21300
|
+
}
|
|
21301
|
+
const event = message.event;
|
|
21302
|
+
if (!event || typeof event !== "object") {
|
|
21303
|
+
return true;
|
|
21304
|
+
}
|
|
21305
|
+
const parentKey = llmParentKey(message.parent_tool_use_id ?? null);
|
|
21306
|
+
if (event.type === "message_start") {
|
|
21307
|
+
const messageId2 = event.message?.id;
|
|
21308
|
+
const usage = copyUsage(event.message?.usage);
|
|
21309
|
+
if (messageId2) {
|
|
21310
|
+
state.activePartialMessageIdByParentKey.set(parentKey, messageId2);
|
|
21311
|
+
if (usage) {
|
|
21312
|
+
state.usageByMessageId.set(messageId2, usage);
|
|
21313
|
+
}
|
|
21314
|
+
}
|
|
21315
|
+
return true;
|
|
21316
|
+
}
|
|
21317
|
+
const messageId = state.activePartialMessageIdByParentKey.get(parentKey);
|
|
21318
|
+
if (!messageId) {
|
|
21319
|
+
return true;
|
|
21320
|
+
}
|
|
21321
|
+
if (event.type === "message_delta") {
|
|
21322
|
+
const update = copyUsage(event.usage);
|
|
21323
|
+
if (update) {
|
|
21324
|
+
const usage = state.usageByMessageId.get(messageId) ?? {};
|
|
21325
|
+
Object.assign(usage, update);
|
|
21326
|
+
state.usageByMessageId.set(messageId, usage);
|
|
21327
|
+
if (update.output_tokens !== void 0) {
|
|
21328
|
+
state.finalOutputUsageMessageIds.add(messageId);
|
|
21329
|
+
}
|
|
21330
|
+
}
|
|
21331
|
+
} else if (event.type === "message_stop") {
|
|
21332
|
+
state.activePartialMessageIdByParentKey.delete(parentKey);
|
|
21333
|
+
}
|
|
21334
|
+
return true;
|
|
21335
|
+
}
|
|
21013
21336
|
async function handleStreamMessage(state, message) {
|
|
21337
|
+
if (handlePartialUsageMessage(state, message)) {
|
|
21338
|
+
return;
|
|
21339
|
+
}
|
|
21014
21340
|
maybeTrackToolUseContext(state, message);
|
|
21015
21341
|
if (await maybeHandleTaskLifecycleMessage(state, message)) {
|
|
21016
21342
|
return;
|
|
@@ -21057,36 +21383,9 @@ async function handleStreamMessage(state, message) {
|
|
|
21057
21383
|
);
|
|
21058
21384
|
state.currentMessages.push(message);
|
|
21059
21385
|
}
|
|
21060
|
-
if (message.type !== "result"
|
|
21386
|
+
if (message.type !== "result") {
|
|
21061
21387
|
return;
|
|
21062
21388
|
}
|
|
21063
|
-
const finalUsageMetrics = extractUsageFromMessage(message);
|
|
21064
|
-
if (state.currentMessages.length > 0 && finalUsageMetrics.completion_tokens !== void 0) {
|
|
21065
|
-
const lastMessage = state.currentMessages[state.currentMessages.length - 1];
|
|
21066
|
-
if (lastMessage?.message?.usage) {
|
|
21067
|
-
const adjustedTokens = finalUsageMetrics.completion_tokens - state.accumulatedOutputTokens;
|
|
21068
|
-
if (adjustedTokens >= 0) {
|
|
21069
|
-
lastMessage.message.usage.output_tokens = adjustedTokens;
|
|
21070
|
-
}
|
|
21071
|
-
const resultUsage = message.usage;
|
|
21072
|
-
if (resultUsage && typeof resultUsage === "object") {
|
|
21073
|
-
const cacheReadTokens = getNumberProperty(
|
|
21074
|
-
resultUsage,
|
|
21075
|
-
"cache_read_input_tokens"
|
|
21076
|
-
);
|
|
21077
|
-
if (cacheReadTokens !== void 0) {
|
|
21078
|
-
lastMessage.message.usage.cache_read_input_tokens = cacheReadTokens;
|
|
21079
|
-
}
|
|
21080
|
-
const cacheCreationTokens = getNumberProperty(
|
|
21081
|
-
resultUsage,
|
|
21082
|
-
"cache_creation_input_tokens"
|
|
21083
|
-
);
|
|
21084
|
-
if (cacheCreationTokens !== void 0) {
|
|
21085
|
-
lastMessage.message.usage.cache_creation_input_tokens = cacheCreationTokens;
|
|
21086
|
-
}
|
|
21087
|
-
}
|
|
21088
|
-
}
|
|
21089
|
-
}
|
|
21090
21389
|
const metadata = {};
|
|
21091
21390
|
if (message.num_turns !== void 0) {
|
|
21092
21391
|
metadata.num_turns = message.num_turns;
|
|
@@ -21094,8 +21393,12 @@ async function handleStreamMessage(state, message) {
|
|
|
21094
21393
|
if (message.session_id !== void 0) {
|
|
21095
21394
|
metadata.session_id = message.session_id;
|
|
21096
21395
|
}
|
|
21097
|
-
|
|
21098
|
-
|
|
21396
|
+
const metrics = state.options.includePartialMessages ? {} : extractUsage(copyUsage(message.usage), true);
|
|
21397
|
+
if (Object.keys(metadata).length > 0 || Object.keys(metrics).length > 0) {
|
|
21398
|
+
state.span.log({
|
|
21399
|
+
...Object.keys(metadata).length > 0 ? { metadata } : {},
|
|
21400
|
+
...Object.keys(metrics).length > 0 ? { metrics } : {}
|
|
21401
|
+
});
|
|
21099
21402
|
}
|
|
21100
21403
|
}
|
|
21101
21404
|
async function finalizeQuerySpan(state) {
|
|
@@ -21119,6 +21422,9 @@ async function finalizeQuerySpan(state) {
|
|
|
21119
21422
|
llmSpan.end();
|
|
21120
21423
|
}
|
|
21121
21424
|
state.activeLlmSpansByParentToolUse.clear();
|
|
21425
|
+
state.activePartialMessageIdByParentKey.clear();
|
|
21426
|
+
state.finalOutputUsageMessageIds.clear();
|
|
21427
|
+
state.usageByMessageId.clear();
|
|
21122
21428
|
for (const toolSpan of state.activeToolSpans.values()) {
|
|
21123
21429
|
toolSpan.end();
|
|
21124
21430
|
}
|
|
@@ -21243,6 +21549,8 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
21243
21549
|
const optionsWithHooks = injectTracingHooks(
|
|
21244
21550
|
options,
|
|
21245
21551
|
resolveToolUseParentSpan,
|
|
21552
|
+
taskIdToToolUseId,
|
|
21553
|
+
toolUseToParent,
|
|
21246
21554
|
activeToolSpans,
|
|
21247
21555
|
localToolHookNames,
|
|
21248
21556
|
skipLocalToolHooks,
|
|
@@ -21253,8 +21561,8 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
21253
21561
|
params.options = optionsWithHooks;
|
|
21254
21562
|
event.arguments[0] = params;
|
|
21255
21563
|
spans.set(event, {
|
|
21256
|
-
accumulatedOutputTokens: 0,
|
|
21257
21564
|
activeLlmSpansByParentToolUse,
|
|
21565
|
+
activePartialMessageIdByParentKey: /* @__PURE__ */ new Map(),
|
|
21258
21566
|
activeToolSpans,
|
|
21259
21567
|
conversationHistoryByParentKey,
|
|
21260
21568
|
capturedPromptMessages,
|
|
@@ -21262,6 +21570,7 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
21262
21570
|
currentMessageStartTime: startTime,
|
|
21263
21571
|
currentMessages: [],
|
|
21264
21572
|
endedSubAgentSpans,
|
|
21573
|
+
finalOutputUsageMessageIds: /* @__PURE__ */ new Set(),
|
|
21265
21574
|
finalResults: [],
|
|
21266
21575
|
options: optionsWithHooks,
|
|
21267
21576
|
originalPrompt,
|
|
@@ -21277,6 +21586,7 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
21277
21586
|
latestLlmParentBySubAgentToolUse,
|
|
21278
21587
|
latestRootLlmParentRef,
|
|
21279
21588
|
toolUseToParent,
|
|
21589
|
+
usageByMessageId: /* @__PURE__ */ new Map(),
|
|
21280
21590
|
localToolContext
|
|
21281
21591
|
});
|
|
21282
21592
|
},
|
|
@@ -23751,9 +24061,9 @@ function extractEmbedPromptTokenCount(response) {
|
|
|
23751
24061
|
let sawAny = false;
|
|
23752
24062
|
for (const embedding of embeddings) {
|
|
23753
24063
|
const embeddingStats = tryToDict(tryToDict(embedding)?.statistics);
|
|
23754
|
-
const
|
|
23755
|
-
if (typeof
|
|
23756
|
-
total +=
|
|
24064
|
+
const tokenCount2 = embeddingStats?.tokenCount;
|
|
24065
|
+
if (typeof tokenCount2 === "number" && Number.isFinite(tokenCount2)) {
|
|
24066
|
+
total += tokenCount2;
|
|
23757
24067
|
sawAny = true;
|
|
23758
24068
|
}
|
|
23759
24069
|
}
|
|
@@ -30648,7 +30958,7 @@ function getStringProperty2(obj, key) {
|
|
|
30648
30958
|
return typeof value === "string" ? value : void 0;
|
|
30649
30959
|
}
|
|
30650
30960
|
function extractMetricsFromUsage(usage) {
|
|
30651
|
-
const
|
|
30961
|
+
const rawMetrics = {
|
|
30652
30962
|
prompt_tokens: usage.inputTokens,
|
|
30653
30963
|
completion_tokens: usage.outputTokens,
|
|
30654
30964
|
...extractAnthropicCacheTokens(
|
|
@@ -30657,10 +30967,10 @@ function extractMetricsFromUsage(usage) {
|
|
|
30657
30967
|
)
|
|
30658
30968
|
};
|
|
30659
30969
|
if (usage.reasoningTokens !== void 0) {
|
|
30660
|
-
|
|
30661
|
-
|
|
30970
|
+
rawMetrics.completion_reasoning_tokens = usage.reasoningTokens;
|
|
30971
|
+
rawMetrics.reasoning_tokens = usage.reasoningTokens;
|
|
30662
30972
|
}
|
|
30663
|
-
|
|
30973
|
+
const metrics = finalizeAnthropicTokens(rawMetrics);
|
|
30664
30974
|
const metadata = {
|
|
30665
30975
|
model: usage.model
|
|
30666
30976
|
};
|
|
@@ -31599,17 +31909,20 @@ var FlueObserveBridge = class {
|
|
|
31599
31909
|
return;
|
|
31600
31910
|
}
|
|
31601
31911
|
const metadata = {
|
|
31912
|
+
...event.runId ? this.runsById.get(event.runId)?.metadata : {},
|
|
31602
31913
|
...extractEventMetadata(event),
|
|
31603
31914
|
"flue.operation": event.operationKind,
|
|
31604
31915
|
provider: "flue"
|
|
31605
31916
|
};
|
|
31606
31917
|
const parent = this.parentSpanForEvent(event);
|
|
31607
|
-
const
|
|
31918
|
+
const args = {
|
|
31608
31919
|
name: `flue.${event.operationKind}`,
|
|
31609
31920
|
spanAttributes: { type: "task" /* TASK */ },
|
|
31610
31921
|
startTime: eventTime(event.timestamp),
|
|
31611
31922
|
event: { metadata }
|
|
31612
|
-
}
|
|
31923
|
+
};
|
|
31924
|
+
const runSpan = event.runId ? this.runsById.get(event.runId)?.span : void 0;
|
|
31925
|
+
const span = event.operationKind === "prompt" && (!parent || parent === runSpan) ? startFlueRootSpan(args) : startFlueSpan(parent, args);
|
|
31613
31926
|
this.operationsById.set(event.operationId, { metadata, span });
|
|
31614
31927
|
}
|
|
31615
31928
|
handleOperation(event) {
|
|
@@ -31624,6 +31937,11 @@ var FlueObserveBridge = class {
|
|
|
31624
31937
|
...event.isError !== void 0 ? { "flue.is_error": event.isError } : {},
|
|
31625
31938
|
...event.usage ? { "flue.usage": event.usage } : {}
|
|
31626
31939
|
};
|
|
31940
|
+
const input = flueOperationInput(event);
|
|
31941
|
+
if (!state.loggedInput && input !== void 0) {
|
|
31942
|
+
safeLog3(state.span, { input });
|
|
31943
|
+
state.loggedInput = true;
|
|
31944
|
+
}
|
|
31627
31945
|
this.finishPendingChildrenForOperation(event, output);
|
|
31628
31946
|
safeLog3(state.span, {
|
|
31629
31947
|
...event.isError ? { error: toLoggedError(event.errorInfo ?? event.error) } : {},
|
|
@@ -31640,6 +31958,8 @@ var FlueObserveBridge = class {
|
|
|
31640
31958
|
return;
|
|
31641
31959
|
}
|
|
31642
31960
|
const input = flueTurnRequestInput(event);
|
|
31961
|
+
const operation = event.operationId ? this.operationsById.get(event.operationId) : void 0;
|
|
31962
|
+
const turnInput = prepareFlueTurnInput(event, input, operation);
|
|
31643
31963
|
const model = flueTurnRequestModel(event);
|
|
31644
31964
|
const provider = flueTurnRequestProvider(event);
|
|
31645
31965
|
const api = flueTurnRequestApi(event);
|
|
@@ -31652,8 +31972,7 @@ var FlueObserveBridge = class {
|
|
|
31652
31972
|
...provider ? { "flue.provider": provider } : {},
|
|
31653
31973
|
...event.purpose ? { "flue.turn_purpose": event.purpose } : {},
|
|
31654
31974
|
...reasoning ? { reasoning } : {},
|
|
31655
|
-
...
|
|
31656
|
-
...input?.tools ? { tools: input.tools } : {}
|
|
31975
|
+
...turnInput.metadata
|
|
31657
31976
|
};
|
|
31658
31977
|
const parent = this.parentSpanForTurn(event);
|
|
31659
31978
|
const span = startFlueSpan(parent, {
|
|
@@ -31661,11 +31980,14 @@ var FlueObserveBridge = class {
|
|
|
31661
31980
|
spanAttributes: { type: "llm" /* LLM */ },
|
|
31662
31981
|
startTime: eventTime(event.timestamp),
|
|
31663
31982
|
event: {
|
|
31664
|
-
input:
|
|
31983
|
+
input: turnInput.messages,
|
|
31665
31984
|
metadata
|
|
31666
31985
|
}
|
|
31667
31986
|
});
|
|
31668
|
-
this.logOperationInput(
|
|
31987
|
+
this.logOperationInput(
|
|
31988
|
+
event.operationId,
|
|
31989
|
+
latestUserMessageInput(input?.messages)
|
|
31990
|
+
);
|
|
31669
31991
|
this.turnsByKey.set(key, { metadata, span });
|
|
31670
31992
|
}
|
|
31671
31993
|
handleTurn(event) {
|
|
@@ -31912,16 +32234,20 @@ var FlueObserveBridge = class {
|
|
|
31912
32234
|
}
|
|
31913
32235
|
startSyntheticOperation(event) {
|
|
31914
32236
|
const metadata = {
|
|
32237
|
+
...event.runId ? this.runsById.get(event.runId)?.metadata : {},
|
|
31915
32238
|
...extractEventMetadata(event),
|
|
31916
32239
|
"flue.operation": event.operationKind,
|
|
31917
32240
|
provider: "flue"
|
|
31918
32241
|
};
|
|
31919
|
-
const
|
|
32242
|
+
const args = {
|
|
31920
32243
|
name: `flue.${event.operationKind}`,
|
|
31921
32244
|
spanAttributes: { type: "task" /* TASK */ },
|
|
31922
32245
|
startTime: eventTime(event.timestamp),
|
|
31923
32246
|
event: { metadata }
|
|
31924
|
-
}
|
|
32247
|
+
};
|
|
32248
|
+
const parent = this.parentSpanForEvent(event);
|
|
32249
|
+
const runSpan = event.runId ? this.runsById.get(event.runId)?.span : void 0;
|
|
32250
|
+
const span = event.operationKind === "prompt" && (!parent || parent === runSpan) ? startFlueRootSpan(args) : startFlueSpan(parent, args);
|
|
31925
32251
|
return { metadata, span };
|
|
31926
32252
|
}
|
|
31927
32253
|
startSyntheticTurn(event) {
|
|
@@ -32100,6 +32426,71 @@ function flueRunInput(event) {
|
|
|
32100
32426
|
function flueTurnRequestInput(event) {
|
|
32101
32427
|
return event.request?.input ?? event.input;
|
|
32102
32428
|
}
|
|
32429
|
+
function prepareFlueTurnInput(event, input, operation) {
|
|
32430
|
+
const messages = input?.messages;
|
|
32431
|
+
const tracksUserTurn = event.purpose === "agent" && operation?.metadata["flue.operation"] === "prompt" && Array.isArray(messages);
|
|
32432
|
+
if (!tracksUserTurn) {
|
|
32433
|
+
return {
|
|
32434
|
+
messages,
|
|
32435
|
+
metadata: {
|
|
32436
|
+
...input?.systemPrompt ? { "flue.system_prompt": input.systemPrompt } : {},
|
|
32437
|
+
...input?.tools ? { tools: input.tools } : {}
|
|
32438
|
+
}
|
|
32439
|
+
};
|
|
32440
|
+
}
|
|
32441
|
+
const previous = operation.turnInputState;
|
|
32442
|
+
const previousMessageCount = previous?.messageCount ?? 0;
|
|
32443
|
+
const boundaryFingerprint = messages.length > 0 ? fingerprintJsonValue(messages[messages.length - 1]) : void 0;
|
|
32444
|
+
const continuesPreviousInput = previous !== void 0 && messages.length >= previousMessageCount && (previousMessageCount === 0 || previous.boundaryFingerprint !== void 0 && previous.boundaryFingerprint === fingerprintJsonValue(messages[previousMessageCount - 1]));
|
|
32445
|
+
const inputMode = previous === void 0 ? "full" : continuesPreviousInput ? "delta" : "reset";
|
|
32446
|
+
const systemPromptFingerprint = fingerprintJsonValue(input?.systemPrompt);
|
|
32447
|
+
const toolsFingerprint = fingerprintJsonValue(input?.tools);
|
|
32448
|
+
operation.turnInputState = {
|
|
32449
|
+
...boundaryFingerprint !== void 0 ? { boundaryFingerprint } : {},
|
|
32450
|
+
messageCount: messages.length,
|
|
32451
|
+
...systemPromptFingerprint !== void 0 ? { systemPromptFingerprint } : {},
|
|
32452
|
+
...toolsFingerprint !== void 0 ? { toolsFingerprint } : {}
|
|
32453
|
+
};
|
|
32454
|
+
return {
|
|
32455
|
+
messages: continuesPreviousInput ? messages.slice(previousMessageCount) : messages,
|
|
32456
|
+
metadata: {
|
|
32457
|
+
"flue.input_mode": inputMode,
|
|
32458
|
+
...continuesPreviousInput ? { "flue.input_message_offset": previousMessageCount } : {},
|
|
32459
|
+
...input?.systemPrompt && (!continuesPreviousInput || systemPromptFingerprint !== previous?.systemPromptFingerprint) ? { "flue.system_prompt": input.systemPrompt } : {},
|
|
32460
|
+
...input?.tools && (!continuesPreviousInput || toolsFingerprint !== previous?.toolsFingerprint) ? { tools: input.tools } : {}
|
|
32461
|
+
}
|
|
32462
|
+
};
|
|
32463
|
+
}
|
|
32464
|
+
function fingerprintJsonValue(value) {
|
|
32465
|
+
try {
|
|
32466
|
+
const serialized = JSON.stringify(value);
|
|
32467
|
+
if (serialized === void 0) {
|
|
32468
|
+
return void 0;
|
|
32469
|
+
}
|
|
32470
|
+
let hash = 2166136261;
|
|
32471
|
+
for (let i = 0; i < serialized.length; i++) {
|
|
32472
|
+
hash = Math.imul(hash ^ serialized.charCodeAt(i), 16777619);
|
|
32473
|
+
}
|
|
32474
|
+
return `${serialized.length}:${hash >>> 0}`;
|
|
32475
|
+
} catch {
|
|
32476
|
+
return void 0;
|
|
32477
|
+
}
|
|
32478
|
+
}
|
|
32479
|
+
function latestUserMessageInput(messages) {
|
|
32480
|
+
if (!messages) {
|
|
32481
|
+
return void 0;
|
|
32482
|
+
}
|
|
32483
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
32484
|
+
const message = messages[i];
|
|
32485
|
+
if (isObjectLike(message) && Reflect.get(message, "role") === "user") {
|
|
32486
|
+
return [message];
|
|
32487
|
+
}
|
|
32488
|
+
}
|
|
32489
|
+
return void 0;
|
|
32490
|
+
}
|
|
32491
|
+
function flueOperationInput(event) {
|
|
32492
|
+
return typeof event.agentInput?.text === "string" ? [{ content: event.agentInput.text, role: "user" }] : void 0;
|
|
32493
|
+
}
|
|
32103
32494
|
function flueTurnRequestModel(event) {
|
|
32104
32495
|
return event.request?.requestedModel ?? event.request?.model ?? event.model;
|
|
32105
32496
|
}
|
|
@@ -32257,6 +32648,21 @@ function startFlueSpan(parent, args) {
|
|
|
32257
32648
|
withSpanInstrumentationName(args, INSTRUMENTATION_NAMES.FLUE)
|
|
32258
32649
|
);
|
|
32259
32650
|
}
|
|
32651
|
+
function startFlueRootSpan(args) {
|
|
32652
|
+
const state = _internalGetGlobalState();
|
|
32653
|
+
const spanId = state.idGenerator.getSpanId();
|
|
32654
|
+
const rootSpanId = state.idGenerator.shareRootSpanId() ? spanId : state.idGenerator.getTraceId();
|
|
32655
|
+
return withCurrent(
|
|
32656
|
+
NOOP_SPAN,
|
|
32657
|
+
() => startSpan({
|
|
32658
|
+
...withSpanInstrumentationName(args, INSTRUMENTATION_NAMES.FLUE),
|
|
32659
|
+
parentSpanIds: { parentSpanIds: [], rootSpanId },
|
|
32660
|
+
spanId,
|
|
32661
|
+
state
|
|
32662
|
+
}),
|
|
32663
|
+
state
|
|
32664
|
+
);
|
|
32665
|
+
}
|
|
32260
32666
|
function runWithCurrentSpanStore(span, next) {
|
|
32261
32667
|
const state = _internalGetGlobalState();
|
|
32262
32668
|
const contextManager = state?.contextManager;
|
|
@@ -34156,8 +34562,7 @@ function startAgentStream(event, activeChildParents) {
|
|
|
34156
34562
|
...extractAgentMetadata2(agent),
|
|
34157
34563
|
...extractModelMetadata3(model),
|
|
34158
34564
|
"strands.operation": "Agent.stream",
|
|
34159
|
-
provider: extractProvider(model)
|
|
34160
|
-
...event.moduleVersion ? { "strands_agent_sdk.version": event.moduleVersion } : {}
|
|
34565
|
+
provider: extractProvider(model)
|
|
34161
34566
|
};
|
|
34162
34567
|
const parentSpan = agent ? getOnlyChildParent(activeChildParents, agent) : void 0;
|
|
34163
34568
|
const attachmentCache = createStrandsAttachmentCache();
|
|
@@ -34207,8 +34612,7 @@ function startMultiAgentStream(event, operation, activeChildParents) {
|
|
|
34207
34612
|
const metadata = {
|
|
34208
34613
|
"strands.operation": operation,
|
|
34209
34614
|
provider: "strands",
|
|
34210
|
-
...orchestrator?.id ? { "strands.orchestrator.id": orchestrator.id } : {}
|
|
34211
|
-
...event.moduleVersion ? { "strands_agent_sdk.version": event.moduleVersion } : {}
|
|
34615
|
+
...orchestrator?.id ? { "strands.orchestrator.id": orchestrator.id } : {}
|
|
34212
34616
|
};
|
|
34213
34617
|
const parentSpan = orchestrator ? getOnlyChildParent(activeChildParents, orchestrator) : void 0;
|
|
34214
34618
|
const input = processStrandsInputAttachments(event.arguments[0]);
|
|
@@ -34994,6 +35398,320 @@ function logInstrumentationError5(context, error) {
|
|
|
34994
35398
|
debugLogger.debug(`${context}:`, error);
|
|
34995
35399
|
}
|
|
34996
35400
|
|
|
35401
|
+
// src/instrumentation/plugins/voyageai-channels.ts
|
|
35402
|
+
var voyageAIChannels = defineChannels(
|
|
35403
|
+
"voyageai",
|
|
35404
|
+
{
|
|
35405
|
+
embed: channel({
|
|
35406
|
+
channelName: "embed",
|
|
35407
|
+
kind: "async"
|
|
35408
|
+
}),
|
|
35409
|
+
multimodalEmbed: channel({
|
|
35410
|
+
channelName: "multimodalEmbed",
|
|
35411
|
+
kind: "async"
|
|
35412
|
+
}),
|
|
35413
|
+
rerank: channel({
|
|
35414
|
+
channelName: "rerank",
|
|
35415
|
+
kind: "async"
|
|
35416
|
+
}),
|
|
35417
|
+
contextualizedEmbed: channel({
|
|
35418
|
+
channelName: "contextualizedEmbed",
|
|
35419
|
+
kind: "async"
|
|
35420
|
+
})
|
|
35421
|
+
},
|
|
35422
|
+
{ instrumentationName: INSTRUMENTATION_NAMES.VOYAGEAI }
|
|
35423
|
+
);
|
|
35424
|
+
|
|
35425
|
+
// src/instrumentation/plugins/voyageai-plugin.ts
|
|
35426
|
+
var RERANK_METADATA_ALLOWLIST = /* @__PURE__ */ new Set([
|
|
35427
|
+
"model",
|
|
35428
|
+
"returnDocuments",
|
|
35429
|
+
"topK",
|
|
35430
|
+
"truncation"
|
|
35431
|
+
]);
|
|
35432
|
+
var VoyageAIPlugin = class extends BasePlugin {
|
|
35433
|
+
onEnable() {
|
|
35434
|
+
this.unsubscribers.push(
|
|
35435
|
+
interceptVoyageAICall(
|
|
35436
|
+
voyageAIChannels.embed,
|
|
35437
|
+
"voyageai.embed",
|
|
35438
|
+
extractTextEmbeddingInput,
|
|
35439
|
+
summarizeEmbeddingOutput,
|
|
35440
|
+
extractEmbeddingUsageMetrics
|
|
35441
|
+
),
|
|
35442
|
+
interceptVoyageAICall(
|
|
35443
|
+
voyageAIChannels.multimodalEmbed,
|
|
35444
|
+
"voyageai.multimodalEmbed",
|
|
35445
|
+
extractMultimodalEmbeddingInput,
|
|
35446
|
+
summarizeEmbeddingOutput,
|
|
35447
|
+
extractEmbeddingUsageMetrics
|
|
35448
|
+
),
|
|
35449
|
+
interceptVoyageAICall(
|
|
35450
|
+
voyageAIChannels.rerank,
|
|
35451
|
+
"voyageai.rerank",
|
|
35452
|
+
extractRerankInput,
|
|
35453
|
+
summarizeRerankOutput
|
|
35454
|
+
),
|
|
35455
|
+
interceptVoyageAICall(
|
|
35456
|
+
voyageAIChannels.contextualizedEmbed,
|
|
35457
|
+
"voyageai.contextualizedEmbed",
|
|
35458
|
+
extractContextualizedEmbeddingInput,
|
|
35459
|
+
summarizeContextualizedEmbeddingOutput,
|
|
35460
|
+
extractEmbeddingUsageMetrics
|
|
35461
|
+
)
|
|
35462
|
+
);
|
|
35463
|
+
}
|
|
35464
|
+
onDisable() {
|
|
35465
|
+
this.unsubscribers = unsubscribeAll(this.unsubscribers);
|
|
35466
|
+
}
|
|
35467
|
+
};
|
|
35468
|
+
function interceptVoyageAICall(channel2, name, extractInput3, extractOutput2, extractMetrics2 = extractUsageMetrics3) {
|
|
35469
|
+
return channel2.intercept((target, thisArg, args) => {
|
|
35470
|
+
const invokeTarget = () => Reflect.apply(target, thisArg, args);
|
|
35471
|
+
if (isAutoInstrumentationSuppressed()) {
|
|
35472
|
+
return invokeTarget();
|
|
35473
|
+
}
|
|
35474
|
+
let span;
|
|
35475
|
+
try {
|
|
35476
|
+
const { input, metadata } = extractInput3(args);
|
|
35477
|
+
span = startSpan(
|
|
35478
|
+
withSpanInstrumentationName(
|
|
35479
|
+
{
|
|
35480
|
+
event: { input, metadata },
|
|
35481
|
+
name,
|
|
35482
|
+
spanAttributes: { type: "llm" /* LLM */ }
|
|
35483
|
+
},
|
|
35484
|
+
INSTRUMENTATION_NAMES.VOYAGEAI
|
|
35485
|
+
)
|
|
35486
|
+
);
|
|
35487
|
+
} catch (error) {
|
|
35488
|
+
debugLogger.error(`Error starting span for ${name}:`, error);
|
|
35489
|
+
return invokeTarget();
|
|
35490
|
+
}
|
|
35491
|
+
let result;
|
|
35492
|
+
try {
|
|
35493
|
+
result = withCurrent(
|
|
35494
|
+
span,
|
|
35495
|
+
() => runWithAutoInstrumentationSuppressed(invokeTarget)
|
|
35496
|
+
);
|
|
35497
|
+
} catch (error) {
|
|
35498
|
+
finishVoyageAISpan(span, name, () => span.log({ error }));
|
|
35499
|
+
throw error;
|
|
35500
|
+
}
|
|
35501
|
+
void Promise.resolve(result).then(
|
|
35502
|
+
(value) => finishVoyageAISpan(span, name, () => {
|
|
35503
|
+
const metadata = extractResponseMetadata3(value);
|
|
35504
|
+
span.log({
|
|
35505
|
+
output: extractOutput2(value),
|
|
35506
|
+
...metadata ? { metadata } : {},
|
|
35507
|
+
metrics: extractMetrics2(value)
|
|
35508
|
+
});
|
|
35509
|
+
}),
|
|
35510
|
+
(error) => finishVoyageAISpan(span, name, () => span.log({ error }))
|
|
35511
|
+
);
|
|
35512
|
+
return result;
|
|
35513
|
+
});
|
|
35514
|
+
}
|
|
35515
|
+
function finishVoyageAISpan(span, name, log3) {
|
|
35516
|
+
try {
|
|
35517
|
+
log3();
|
|
35518
|
+
} catch (error) {
|
|
35519
|
+
debugLogger.error(`Error logging span for ${name}:`, error);
|
|
35520
|
+
}
|
|
35521
|
+
try {
|
|
35522
|
+
span.end();
|
|
35523
|
+
} catch (error) {
|
|
35524
|
+
debugLogger.error(`Error ending span for ${name}:`, error);
|
|
35525
|
+
}
|
|
35526
|
+
}
|
|
35527
|
+
function getRequestArg2(args) {
|
|
35528
|
+
if (Array.isArray(args)) {
|
|
35529
|
+
return isObject(args[0]) ? args[0] : void 0;
|
|
35530
|
+
}
|
|
35531
|
+
if (!isObject(args)) {
|
|
35532
|
+
return void 0;
|
|
35533
|
+
}
|
|
35534
|
+
const firstArg = Reflect.get(args, "0");
|
|
35535
|
+
return isObject(firstArg) ? firstArg : void 0;
|
|
35536
|
+
}
|
|
35537
|
+
function pickMetadata(request, allowlist) {
|
|
35538
|
+
const metadata = {};
|
|
35539
|
+
if (request) {
|
|
35540
|
+
for (const key of allowlist) {
|
|
35541
|
+
if (!Object.hasOwn(request, key)) {
|
|
35542
|
+
continue;
|
|
35543
|
+
}
|
|
35544
|
+
const value = request[key];
|
|
35545
|
+
if (value !== void 0) {
|
|
35546
|
+
metadata[key] = value;
|
|
35547
|
+
}
|
|
35548
|
+
}
|
|
35549
|
+
}
|
|
35550
|
+
return {
|
|
35551
|
+
...metadata,
|
|
35552
|
+
provider: "voyage"
|
|
35553
|
+
};
|
|
35554
|
+
}
|
|
35555
|
+
function buildEmbeddingInput(inputs, request) {
|
|
35556
|
+
const outputDimensions = request?.outputDimension;
|
|
35557
|
+
return {
|
|
35558
|
+
inputs,
|
|
35559
|
+
...typeof outputDimensions === "number" && Number.isFinite(outputDimensions) ? { output_dimensions: outputDimensions } : {}
|
|
35560
|
+
};
|
|
35561
|
+
}
|
|
35562
|
+
function embeddingMetadata(request) {
|
|
35563
|
+
return {
|
|
35564
|
+
...typeof request?.model === "string" ? { model: request.model } : {},
|
|
35565
|
+
provider: "voyage"
|
|
35566
|
+
};
|
|
35567
|
+
}
|
|
35568
|
+
function extractTextEmbeddingInput(args) {
|
|
35569
|
+
const request = getRequestArg2(args);
|
|
35570
|
+
const rawInput = request?.input;
|
|
35571
|
+
const values = Array.isArray(rawInput) ? rawInput : [rawInput];
|
|
35572
|
+
return {
|
|
35573
|
+
input: buildEmbeddingInput(
|
|
35574
|
+
values.flatMap(
|
|
35575
|
+
(value) => typeof value === "string" ? [{ content: value }] : []
|
|
35576
|
+
),
|
|
35577
|
+
request
|
|
35578
|
+
),
|
|
35579
|
+
metadata: embeddingMetadata(request)
|
|
35580
|
+
};
|
|
35581
|
+
}
|
|
35582
|
+
function extractContextualizedEmbeddingInput(args) {
|
|
35583
|
+
const request = getRequestArg2(args);
|
|
35584
|
+
const rawInputs = request?.inputs;
|
|
35585
|
+
const values = Array.isArray(rawInputs) ? rawInputs.flatMap((value) => Array.isArray(value) ? value : [value]) : [];
|
|
35586
|
+
return {
|
|
35587
|
+
input: buildEmbeddingInput(
|
|
35588
|
+
values.flatMap(
|
|
35589
|
+
(value) => typeof value === "string" ? [{ content: value }] : []
|
|
35590
|
+
),
|
|
35591
|
+
request
|
|
35592
|
+
),
|
|
35593
|
+
metadata: embeddingMetadata(request)
|
|
35594
|
+
};
|
|
35595
|
+
}
|
|
35596
|
+
function extractMultimodalEmbeddingInput(args) {
|
|
35597
|
+
const request = getRequestArg2(args);
|
|
35598
|
+
const rawInputs = request?.inputs;
|
|
35599
|
+
const inputs = Array.isArray(rawInputs) ? rawInputs.map((rawInput) => {
|
|
35600
|
+
const rawContent = isObject(rawInput) ? rawInput.content : void 0;
|
|
35601
|
+
return {
|
|
35602
|
+
content: Array.isArray(rawContent) ? rawContent.flatMap(normalizeMultimodalContentPart) : []
|
|
35603
|
+
};
|
|
35604
|
+
}) : [];
|
|
35605
|
+
const input = buildEmbeddingInput(inputs, request);
|
|
35606
|
+
const processedInput = processInputAttachments(input);
|
|
35607
|
+
return {
|
|
35608
|
+
input: hasInlineEmbeddingMedia(processedInput) ? input : processedInput,
|
|
35609
|
+
metadata: embeddingMetadata(request)
|
|
35610
|
+
};
|
|
35611
|
+
}
|
|
35612
|
+
function normalizeMultimodalContentPart(part) {
|
|
35613
|
+
if (!isObject(part) || typeof part.type !== "string") {
|
|
35614
|
+
return [];
|
|
35615
|
+
}
|
|
35616
|
+
if (part.type === "text") {
|
|
35617
|
+
return typeof part.text === "string" ? [{ type: "text", text: part.text }] : [];
|
|
35618
|
+
}
|
|
35619
|
+
const camelCaseField = {
|
|
35620
|
+
image_base64: "imageBase64",
|
|
35621
|
+
image_url: "imageUrl",
|
|
35622
|
+
video_base64: "videoBase64",
|
|
35623
|
+
video_url: "videoUrl"
|
|
35624
|
+
};
|
|
35625
|
+
const field = camelCaseField[part.type];
|
|
35626
|
+
if (!field) {
|
|
35627
|
+
return [];
|
|
35628
|
+
}
|
|
35629
|
+
const data = typeof part[field] === "string" ? part[field] : part[part.type];
|
|
35630
|
+
if (typeof data !== "string") {
|
|
35631
|
+
return [];
|
|
35632
|
+
}
|
|
35633
|
+
return part.type.startsWith("image_") ? [{ type: "image_url", image_url: { url: data } }] : [{ type: "file", file: { file_data: data } }];
|
|
35634
|
+
}
|
|
35635
|
+
function hasInlineEmbeddingMedia(input) {
|
|
35636
|
+
return input.inputs.some(
|
|
35637
|
+
({ content }) => Array.isArray(content) ? content.some((part) => {
|
|
35638
|
+
const value = part.type === "image_url" ? part.image_url.url : part.type === "file" ? part.file.file_data : void 0;
|
|
35639
|
+
return typeof value === "string" && value.startsWith("data:");
|
|
35640
|
+
}) : false
|
|
35641
|
+
);
|
|
35642
|
+
}
|
|
35643
|
+
function extractRerankInput(args) {
|
|
35644
|
+
const request = getRequestArg2(args);
|
|
35645
|
+
const documents = request?.documents;
|
|
35646
|
+
return {
|
|
35647
|
+
input: {
|
|
35648
|
+
documents,
|
|
35649
|
+
query: request?.query
|
|
35650
|
+
},
|
|
35651
|
+
metadata: {
|
|
35652
|
+
...pickMetadata(request, RERANK_METADATA_ALLOWLIST),
|
|
35653
|
+
...Array.isArray(documents) ? { document_count: documents.length } : {}
|
|
35654
|
+
}
|
|
35655
|
+
};
|
|
35656
|
+
}
|
|
35657
|
+
function extractResponseMetadata3(result) {
|
|
35658
|
+
if (!isObject(result)) {
|
|
35659
|
+
return void 0;
|
|
35660
|
+
}
|
|
35661
|
+
const rawResponse = isObject(result.rawResponse) ? result.rawResponse : void 0;
|
|
35662
|
+
const model = typeof result.model === "string" ? result.model : typeof rawResponse?.model === "string" ? rawResponse.model : void 0;
|
|
35663
|
+
return model ? { model } : void 0;
|
|
35664
|
+
}
|
|
35665
|
+
function summarizeEmbeddingOutput(result) {
|
|
35666
|
+
return {
|
|
35667
|
+
count: isObject(result) && Array.isArray(result.data) ? result.data.length : 0
|
|
35668
|
+
};
|
|
35669
|
+
}
|
|
35670
|
+
function summarizeRerankOutput(result) {
|
|
35671
|
+
if (!isObject(result) || !Array.isArray(result.data)) {
|
|
35672
|
+
return void 0;
|
|
35673
|
+
}
|
|
35674
|
+
return result.data.slice(0, 100).map((item) => ({
|
|
35675
|
+
index: isObject(item) ? item.index : void 0,
|
|
35676
|
+
relevance_score: isObject(item) ? (typeof item.relevanceScore === "number" ? item.relevanceScore : item.relevance_score) ?? null : null
|
|
35677
|
+
}));
|
|
35678
|
+
}
|
|
35679
|
+
function summarizeContextualizedEmbeddingOutput(result) {
|
|
35680
|
+
if (!isObject(result)) {
|
|
35681
|
+
return { count: 0 };
|
|
35682
|
+
}
|
|
35683
|
+
if (Array.isArray(result.results)) {
|
|
35684
|
+
return {
|
|
35685
|
+
count: result.results.reduce(
|
|
35686
|
+
(count, item) => count + (isObject(item) && Array.isArray(item.embeddings) ? item.embeddings.length : 0),
|
|
35687
|
+
0
|
|
35688
|
+
)
|
|
35689
|
+
};
|
|
35690
|
+
}
|
|
35691
|
+
if (!Array.isArray(result.data)) {
|
|
35692
|
+
return { count: 0 };
|
|
35693
|
+
}
|
|
35694
|
+
return {
|
|
35695
|
+
count: result.data.reduce(
|
|
35696
|
+
(count, item) => count + (isObject(item) && Array.isArray(item.data) ? item.data.length : 0),
|
|
35697
|
+
0
|
|
35698
|
+
)
|
|
35699
|
+
};
|
|
35700
|
+
}
|
|
35701
|
+
function extractEmbeddingUsageMetrics(result) {
|
|
35702
|
+
const metrics = extractUsageMetrics3(result);
|
|
35703
|
+
return typeof metrics.tokens === "number" ? { prompt_tokens: metrics.tokens, tokens: metrics.tokens } : {};
|
|
35704
|
+
}
|
|
35705
|
+
function extractUsageMetrics3(result) {
|
|
35706
|
+
if (!isObject(result)) {
|
|
35707
|
+
return {};
|
|
35708
|
+
}
|
|
35709
|
+
const rawResponse = isObject(result.rawResponse) ? result.rawResponse : void 0;
|
|
35710
|
+
const usage = isObject(result.usage) ? result.usage : isObject(rawResponse?.usage) ? rawResponse.usage : void 0;
|
|
35711
|
+
const tokens = typeof result.totalTokens === "number" ? result.totalTokens : usage?.totalTokens ?? usage?.total_tokens;
|
|
35712
|
+
return typeof tokens === "number" && Number.isFinite(tokens) && tokens >= 0 ? { tokens } : {};
|
|
35713
|
+
}
|
|
35714
|
+
|
|
34997
35715
|
// src/instrumentation/plugins/cloudflare-ai-chat-channels.ts
|
|
34998
35716
|
var cloudflareAIChatChannels = defineChannels(
|
|
34999
35717
|
"@cloudflare/ai-chat",
|
|
@@ -35572,6 +36290,7 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
35572
36290
|
langSmithPlugin = null;
|
|
35573
36291
|
piCodingAgentPlugin = null;
|
|
35574
36292
|
strandsAgentSDKPlugin = null;
|
|
36293
|
+
voyageAIPlugin = null;
|
|
35575
36294
|
cloudflareAIChatPlugin = null;
|
|
35576
36295
|
cloudflareAgentsPlugin = null;
|
|
35577
36296
|
constructor(config = {}) {
|
|
@@ -35646,6 +36365,10 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
35646
36365
|
this.coherePlugin = new CoherePlugin();
|
|
35647
36366
|
this.coherePlugin.enable();
|
|
35648
36367
|
}
|
|
36368
|
+
if (integrations.voyageai !== false) {
|
|
36369
|
+
this.voyageAIPlugin = new VoyageAIPlugin();
|
|
36370
|
+
this.voyageAIPlugin.enable();
|
|
36371
|
+
}
|
|
35649
36372
|
if (integrations.groq !== false) {
|
|
35650
36373
|
this.groqPlugin = new GroqPlugin();
|
|
35651
36374
|
this.groqPlugin.enable();
|
|
@@ -35762,6 +36485,10 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
35762
36485
|
this.coherePlugin.disable();
|
|
35763
36486
|
this.coherePlugin = null;
|
|
35764
36487
|
}
|
|
36488
|
+
if (this.voyageAIPlugin) {
|
|
36489
|
+
this.voyageAIPlugin.disable();
|
|
36490
|
+
this.voyageAIPlugin = null;
|
|
36491
|
+
}
|
|
35765
36492
|
if (this.groqPlugin) {
|
|
35766
36493
|
this.groqPlugin.disable();
|
|
35767
36494
|
this.groqPlugin = null;
|
|
@@ -35881,7 +36608,10 @@ var envIntegrationAliases = {
|
|
|
35881
36608
|
"langchain-js": "langchain",
|
|
35882
36609
|
"@langchain": "langchain",
|
|
35883
36610
|
langgraph: "langgraph",
|
|
35884
|
-
langsmith: "langsmith"
|
|
36611
|
+
langsmith: "langsmith",
|
|
36612
|
+
voyage: "voyageai",
|
|
36613
|
+
"voyage-ai": "voyageai",
|
|
36614
|
+
voyageai: "voyageai"
|
|
35885
36615
|
};
|
|
35886
36616
|
function getDefaultInstrumentationIntegrations() {
|
|
35887
36617
|
return {
|
|
@@ -35916,6 +36646,7 @@ function getDefaultInstrumentationIntegrations() {
|
|
|
35916
36646
|
langchain: true,
|
|
35917
36647
|
langgraph: true,
|
|
35918
36648
|
langsmith: true,
|
|
36649
|
+
voyageai: true,
|
|
35919
36650
|
piCodingAgent: true,
|
|
35920
36651
|
strandsAgentSDK: true,
|
|
35921
36652
|
cloudflareAgents: true
|
|
@@ -36081,6 +36812,8 @@ __export(exports_exports, {
|
|
|
36081
36812
|
BRAINTRUST_PARENT_KEY: () => BRAINTRUST_PARENT_KEY,
|
|
36082
36813
|
BaseAttachment: () => BaseAttachment,
|
|
36083
36814
|
BaseExperiment: () => BaseExperiment,
|
|
36815
|
+
BatchScorer: () => BatchScorer,
|
|
36816
|
+
BatchTask: () => BatchTask,
|
|
36084
36817
|
BraintrustLangChainCallbackHandler: () => BraintrustLangChainCallbackHandler,
|
|
36085
36818
|
BraintrustMiddleware: () => BraintrustMiddleware,
|
|
36086
36819
|
BraintrustObservabilityExporter: () => BraintrustObservabilityExporter,
|
|
@@ -36094,6 +36827,8 @@ __export(exports_exports, {
|
|
|
36094
36827
|
DEFAULT_MAX_REQUEST_SIZE: () => DEFAULT_MAX_REQUEST_SIZE,
|
|
36095
36828
|
Dataset: () => Dataset2,
|
|
36096
36829
|
DatasetPipeline: () => DatasetPipeline,
|
|
36830
|
+
DurableEvalMemoryStore: () => DurableEvalMemoryStore,
|
|
36831
|
+
DurableEvalRedisStore: () => DurableEvalRedisStore,
|
|
36097
36832
|
ERR_PERMALINK: () => ERR_PERMALINK,
|
|
36098
36833
|
Eval: () => Eval,
|
|
36099
36834
|
EvalResultWithSummary: () => EvalResultWithSummary,
|
|
@@ -36151,6 +36886,7 @@ __export(exports_exports, {
|
|
|
36151
36886
|
currentSpan: () => currentSpan,
|
|
36152
36887
|
deepCopyEvent: () => deepCopyEvent,
|
|
36153
36888
|
defaultErrorScoreHandler: () => defaultErrorScoreHandler,
|
|
36889
|
+
defineDurableEval: () => defineDurableEval,
|
|
36154
36890
|
deserializePlainStringAsJSON: () => deserializePlainStringAsJSON,
|
|
36155
36891
|
devNullWritableStream: () => devNullWritableStream,
|
|
36156
36892
|
evaluatorDefinitionSchema: () => evaluatorDefinitionSchema,
|
|
@@ -36246,7 +36982,8 @@ __export(exports_exports, {
|
|
|
36246
36982
|
wrapPiCodingAgentSDK: () => wrapPiCodingAgentSDK,
|
|
36247
36983
|
wrapStrandsAgentSDK: () => wrapStrandsAgentSDK,
|
|
36248
36984
|
wrapTraced: () => wrapTraced,
|
|
36249
|
-
wrapVitest: () => wrapVitest
|
|
36985
|
+
wrapVitest: () => wrapVitest,
|
|
36986
|
+
wrapVoyageAI: () => wrapVoyageAI
|
|
36250
36987
|
});
|
|
36251
36988
|
|
|
36252
36989
|
// src/sandbox.ts
|
|
@@ -37507,7 +38244,7 @@ function normalizeUsageMetrics(usage, provider, providerMetadata) {
|
|
|
37507
38244
|
cacheCreationTokens
|
|
37508
38245
|
);
|
|
37509
38246
|
Object.assign(metrics, cacheTokens);
|
|
37510
|
-
|
|
38247
|
+
return toNumericMetrics(finalizeAnthropicTokens(metrics));
|
|
37511
38248
|
}
|
|
37512
38249
|
}
|
|
37513
38250
|
return metrics;
|
|
@@ -41840,6 +42577,84 @@ function wrapRerank3(rerank) {
|
|
|
41840
42577
|
});
|
|
41841
42578
|
}
|
|
41842
42579
|
|
|
42580
|
+
// src/wrappers/voyageai.ts
|
|
42581
|
+
function wrapVoyageAI(client) {
|
|
42582
|
+
if (!isSupportedVoyageAIClient(client)) {
|
|
42583
|
+
console.warn("Unsupported Voyage AI library. Not wrapping.");
|
|
42584
|
+
return client;
|
|
42585
|
+
}
|
|
42586
|
+
return voyageAIProxy(client);
|
|
42587
|
+
}
|
|
42588
|
+
var voyageAIProxyCache = /* @__PURE__ */ new WeakMap();
|
|
42589
|
+
function isObject3(value) {
|
|
42590
|
+
return typeof value === "object" && value !== null;
|
|
42591
|
+
}
|
|
42592
|
+
function hasFunction5(value, name) {
|
|
42593
|
+
return typeof Reflect.get(value, name) === "function";
|
|
42594
|
+
}
|
|
42595
|
+
function isSupportedVoyageAIClient(value) {
|
|
42596
|
+
if (!isObject3(value)) {
|
|
42597
|
+
return false;
|
|
42598
|
+
}
|
|
42599
|
+
return hasFunction5(value, "embed") || hasFunction5(value, "multimodalEmbed") || hasFunction5(value, "rerank") || hasFunction5(value, "contextualizedEmbed");
|
|
42600
|
+
}
|
|
42601
|
+
function voyageAIProxy(client) {
|
|
42602
|
+
const cached = voyageAIProxyCache.get(client);
|
|
42603
|
+
if (cached) {
|
|
42604
|
+
return cached;
|
|
42605
|
+
}
|
|
42606
|
+
const proxy = new Proxy(client, {
|
|
42607
|
+
get(target, prop, receiver) {
|
|
42608
|
+
switch (prop) {
|
|
42609
|
+
case "embed":
|
|
42610
|
+
if (typeof target.embed !== "function") {
|
|
42611
|
+
return target.embed;
|
|
42612
|
+
}
|
|
42613
|
+
return (request, options) => voyageAIChannels.embed.invoke(
|
|
42614
|
+
target.embed,
|
|
42615
|
+
target,
|
|
42616
|
+
[request, options],
|
|
42617
|
+
{}
|
|
42618
|
+
);
|
|
42619
|
+
case "multimodalEmbed":
|
|
42620
|
+
if (typeof target.multimodalEmbed !== "function") {
|
|
42621
|
+
return target.multimodalEmbed;
|
|
42622
|
+
}
|
|
42623
|
+
return (request, options) => voyageAIChannels.multimodalEmbed.invoke(
|
|
42624
|
+
target.multimodalEmbed,
|
|
42625
|
+
target,
|
|
42626
|
+
[request, options],
|
|
42627
|
+
{}
|
|
42628
|
+
);
|
|
42629
|
+
case "rerank":
|
|
42630
|
+
if (typeof target.rerank !== "function") {
|
|
42631
|
+
return target.rerank;
|
|
42632
|
+
}
|
|
42633
|
+
return (request, options) => voyageAIChannels.rerank.invoke(
|
|
42634
|
+
target.rerank,
|
|
42635
|
+
target,
|
|
42636
|
+
[request, options],
|
|
42637
|
+
{}
|
|
42638
|
+
);
|
|
42639
|
+
case "contextualizedEmbed":
|
|
42640
|
+
if (typeof target.contextualizedEmbed !== "function") {
|
|
42641
|
+
return target.contextualizedEmbed;
|
|
42642
|
+
}
|
|
42643
|
+
return (request, options) => voyageAIChannels.contextualizedEmbed.invoke(
|
|
42644
|
+
target.contextualizedEmbed,
|
|
42645
|
+
target,
|
|
42646
|
+
[request, options],
|
|
42647
|
+
{}
|
|
42648
|
+
);
|
|
42649
|
+
default:
|
|
42650
|
+
return Reflect.get(target, prop, receiver);
|
|
42651
|
+
}
|
|
42652
|
+
}
|
|
42653
|
+
});
|
|
42654
|
+
voyageAIProxyCache.set(client, proxy);
|
|
42655
|
+
return proxy;
|
|
42656
|
+
}
|
|
42657
|
+
|
|
41843
42658
|
// src/wrappers/groq.ts
|
|
41844
42659
|
function wrapGroq(groq) {
|
|
41845
42660
|
if (isSupportedGroqClient(groq)) {
|
|
@@ -41851,14 +42666,14 @@ function wrapGroq(groq) {
|
|
|
41851
42666
|
function isRecord6(value) {
|
|
41852
42667
|
return typeof value === "object" && value !== null;
|
|
41853
42668
|
}
|
|
41854
|
-
function
|
|
42669
|
+
function hasFunction6(value, methodName) {
|
|
41855
42670
|
return isRecord6(value) && methodName in value && typeof value[methodName] === "function";
|
|
41856
42671
|
}
|
|
41857
42672
|
function hasChat2(value) {
|
|
41858
|
-
return isRecord6(value) && isRecord6(value.completions) &&
|
|
42673
|
+
return isRecord6(value) && isRecord6(value.completions) && hasFunction6(value.completions, "create");
|
|
41859
42674
|
}
|
|
41860
42675
|
function hasEmbeddings2(value) {
|
|
41861
|
-
return
|
|
42676
|
+
return hasFunction6(value, "create");
|
|
41862
42677
|
}
|
|
41863
42678
|
function isSupportedGroqClient(value) {
|
|
41864
42679
|
return isRecord6(value) && (value.chat !== void 0 && hasChat2(value.chat) || value.embeddings !== void 0 && hasEmbeddings2(value.embeddings));
|
|
@@ -42441,7 +43256,7 @@ async function flushExperimentWithSync(context, config) {
|
|
|
42441
43256
|
// src/wrappers/shared/scorers.ts
|
|
42442
43257
|
async function runScorers(args) {
|
|
42443
43258
|
const { scorers, output, expected, input, metadata, span } = args;
|
|
42444
|
-
const
|
|
43259
|
+
const scorerArgs2 = {
|
|
42445
43260
|
output,
|
|
42446
43261
|
expected,
|
|
42447
43262
|
input,
|
|
@@ -42450,7 +43265,7 @@ async function runScorers(args) {
|
|
|
42450
43265
|
await Promise.all(
|
|
42451
43266
|
scorers.map(async (scorer) => {
|
|
42452
43267
|
try {
|
|
42453
|
-
const result = await scorer(
|
|
43268
|
+
const result = await scorer(scorerArgs2);
|
|
42454
43269
|
const scores = normalizeScores(result);
|
|
42455
43270
|
if (scores.length > 0) {
|
|
42456
43271
|
const accScores = {};
|
|
@@ -44809,6 +45624,26 @@ async function getExperimentParametersRef(parameters) {
|
|
|
44809
45624
|
version: resolvedParameters.version
|
|
44810
45625
|
};
|
|
44811
45626
|
}
|
|
45627
|
+
async function _internalInitEvaluatorExperiment(projectName, evaluator, data, options = {}) {
|
|
45628
|
+
if (options.disabled) return null;
|
|
45629
|
+
const { baseExperiment } = callEvaluatorData(data);
|
|
45630
|
+
const parameters = await getExperimentParametersRef(evaluator.parameters);
|
|
45631
|
+
return initExperiment2(evaluator.state, {
|
|
45632
|
+
...evaluator.projectId ? { projectId: evaluator.projectId } : { project: projectName },
|
|
45633
|
+
experiment: options.experimentName ?? evaluator.experimentName,
|
|
45634
|
+
description: evaluator.description,
|
|
45635
|
+
metadata: evaluator.metadata,
|
|
45636
|
+
tags: evaluator.tags,
|
|
45637
|
+
isPublic: evaluator.isPublic,
|
|
45638
|
+
update: options.update ?? evaluator.update,
|
|
45639
|
+
baseExperiment: evaluator.baseExperimentName ?? baseExperiment,
|
|
45640
|
+
baseExperimentId: evaluator.baseExperimentId,
|
|
45641
|
+
gitMetadataSettings: evaluator.gitMetadataSettings,
|
|
45642
|
+
repoInfo: evaluator.repoInfo,
|
|
45643
|
+
dataset: Dataset2.isDataset(data) ? data : void 0,
|
|
45644
|
+
parameters
|
|
45645
|
+
});
|
|
45646
|
+
}
|
|
44812
45647
|
function callEvaluatorData(data) {
|
|
44813
45648
|
const dataResult = typeof data === "function" ? data() : data;
|
|
44814
45649
|
let baseExperiment = void 0;
|
|
@@ -44826,6 +45661,48 @@ function isAsyncIterable7(value) {
|
|
|
44826
45661
|
function isIterable(value) {
|
|
44827
45662
|
return typeof value === "object" && value !== null && Symbol.iterator in value && typeof value[Symbol.iterator] === "function";
|
|
44828
45663
|
}
|
|
45664
|
+
async function _internalResolveEvaluatorData(evaluator, experiment) {
|
|
45665
|
+
if (typeof evaluator.data === "string") {
|
|
45666
|
+
throw new Error("Unimplemented: string data paths");
|
|
45667
|
+
}
|
|
45668
|
+
let dataResult = typeof evaluator.data === "function" ? evaluator.data() : evaluator.data;
|
|
45669
|
+
if ("_type" in dataResult) {
|
|
45670
|
+
if (dataResult._type !== "BaseExperiment") {
|
|
45671
|
+
throw new Error("Invalid _type");
|
|
45672
|
+
}
|
|
45673
|
+
if (!experiment) {
|
|
45674
|
+
throw new Error(
|
|
45675
|
+
"Cannot use BaseExperiment() without connecting to Braintrust (you most likely set --no-send-logs)"
|
|
45676
|
+
);
|
|
45677
|
+
}
|
|
45678
|
+
let name = dataResult.name;
|
|
45679
|
+
if (isEmpty2(name)) {
|
|
45680
|
+
const baseExperiment = await experiment.fetchBaseExperiment();
|
|
45681
|
+
if (!baseExperiment) {
|
|
45682
|
+
throw new Error("BaseExperiment() failed to fetch base experiment");
|
|
45683
|
+
}
|
|
45684
|
+
name = baseExperiment.name;
|
|
45685
|
+
}
|
|
45686
|
+
dataResult = initExperiment2(evaluator.state, {
|
|
45687
|
+
...evaluator.projectId ? { projectId: evaluator.projectId } : { project: evaluator.projectName },
|
|
45688
|
+
experiment: name,
|
|
45689
|
+
open: true
|
|
45690
|
+
}).asDataset();
|
|
45691
|
+
}
|
|
45692
|
+
const resolvedDataResult = dataResult instanceof Promise ? await dataResult : dataResult;
|
|
45693
|
+
if (isAsyncIterable7(resolvedDataResult)) {
|
|
45694
|
+
return resolvedDataResult;
|
|
45695
|
+
}
|
|
45696
|
+
if (Array.isArray(resolvedDataResult) || isIterable(resolvedDataResult)) {
|
|
45697
|
+
const iterable = resolvedDataResult;
|
|
45698
|
+
return (async function* () {
|
|
45699
|
+
for (const datum of iterable) yield datum;
|
|
45700
|
+
})();
|
|
45701
|
+
}
|
|
45702
|
+
throw new Error(
|
|
45703
|
+
"Evaluator data must be an array, iterable, or async iterable"
|
|
45704
|
+
);
|
|
45705
|
+
}
|
|
44829
45706
|
globalThis._evals = {
|
|
44830
45707
|
functions: [],
|
|
44831
45708
|
prompts: [],
|
|
@@ -44872,25 +45749,13 @@ async function Eval(name, evaluator, reporterOrOpts) {
|
|
|
44872
45749
|
}
|
|
44873
45750
|
const resolvedReporter = options.reporter || defaultReporter;
|
|
44874
45751
|
try {
|
|
44875
|
-
const { data
|
|
44876
|
-
|
|
44877
|
-
|
|
44878
|
-
|
|
44879
|
-
|
|
44880
|
-
|
|
44881
|
-
|
|
44882
|
-
description: evaluator.description,
|
|
44883
|
-
metadata: evaluator.metadata,
|
|
44884
|
-
tags: evaluator.tags,
|
|
44885
|
-
isPublic: evaluator.isPublic,
|
|
44886
|
-
update: evaluator.update,
|
|
44887
|
-
baseExperiment: evaluator.baseExperimentName ?? defaultBaseExperiment,
|
|
44888
|
-
baseExperimentId: evaluator.baseExperimentId,
|
|
44889
|
-
gitMetadataSettings: evaluator.gitMetadataSettings,
|
|
44890
|
-
repoInfo: evaluator.repoInfo,
|
|
44891
|
-
dataset: Dataset2.isDataset(data) ? data : void 0,
|
|
44892
|
-
parameters
|
|
44893
|
-
});
|
|
45752
|
+
const { data } = callEvaluatorData(evaluator.data);
|
|
45753
|
+
const experiment = await _internalInitEvaluatorExperiment(
|
|
45754
|
+
name,
|
|
45755
|
+
evaluator,
|
|
45756
|
+
data,
|
|
45757
|
+
{ disabled: Boolean(options.parent || options.noSendLogs) }
|
|
45758
|
+
);
|
|
44894
45759
|
if (experiment && typeof process !== "undefined" && globalThis.BRAINTRUST_CONTEXT_MANAGER !== void 0) {
|
|
44895
45760
|
await experiment._waitForId();
|
|
44896
45761
|
}
|
|
@@ -44988,19 +45853,74 @@ function scorerName(scorer, scorer_idx) {
|
|
|
44988
45853
|
function classifierName(classifier, classifier_idx) {
|
|
44989
45854
|
return classifier.name || `classifier_${classifier_idx}`;
|
|
44990
45855
|
}
|
|
45856
|
+
async function _internalRunEvaluatorTask(task, datum, trialIndex, parameters, span, reportProgress = () => void 0) {
|
|
45857
|
+
const metadata = {
|
|
45858
|
+
..."metadata" in datum ? datum.metadata : {}
|
|
45859
|
+
};
|
|
45860
|
+
const hooks = {
|
|
45861
|
+
meta(value) {
|
|
45862
|
+
Object.assign(metadata, value);
|
|
45863
|
+
},
|
|
45864
|
+
metadata,
|
|
45865
|
+
expected: "expected" in datum ? datum.expected : void 0,
|
|
45866
|
+
span,
|
|
45867
|
+
parameters,
|
|
45868
|
+
reportProgress,
|
|
45869
|
+
trialIndex,
|
|
45870
|
+
tags: [...datum.tags ?? []]
|
|
45871
|
+
};
|
|
45872
|
+
const output = await task(datum.input, hooks);
|
|
45873
|
+
span.log({ output });
|
|
45874
|
+
return {
|
|
45875
|
+
output,
|
|
45876
|
+
metadata: hooks.metadata,
|
|
45877
|
+
tags: hooks.tags ?? []
|
|
45878
|
+
};
|
|
45879
|
+
}
|
|
44991
45880
|
function buildSpanMetadata(results) {
|
|
44992
|
-
return results.length === 1 ? results[0].metadata :
|
|
44993
|
-
(
|
|
44994
|
-
{}
|
|
45881
|
+
return results.length === 1 ? results[0].metadata : Object.fromEntries(
|
|
45882
|
+
results.map((result) => [result.name, result.metadata])
|
|
44995
45883
|
);
|
|
44996
45884
|
}
|
|
44997
45885
|
function buildSpanScores(results) {
|
|
44998
|
-
const scoresRecord =
|
|
44999
|
-
(
|
|
45000
|
-
{}
|
|
45886
|
+
const scoresRecord = Object.fromEntries(
|
|
45887
|
+
results.map((result) => [result.name, result.score])
|
|
45001
45888
|
);
|
|
45002
45889
|
return { resultMetadata: buildSpanMetadata(results), scoresRecord };
|
|
45003
45890
|
}
|
|
45891
|
+
function _internalPrepareEvaluatorScore(scoreValue, name) {
|
|
45892
|
+
if (scoreValue === null) return { results: null };
|
|
45893
|
+
if (Array.isArray(scoreValue)) {
|
|
45894
|
+
for (const score of scoreValue) {
|
|
45895
|
+
if (!(typeof score === "object" && !isEmpty2(score))) {
|
|
45896
|
+
throw new Error(
|
|
45897
|
+
`When returning an array of scores, each score must be a non-empty object. Got: ${JSON.stringify(score)}`
|
|
45898
|
+
);
|
|
45899
|
+
}
|
|
45900
|
+
}
|
|
45901
|
+
}
|
|
45902
|
+
let results;
|
|
45903
|
+
if (Array.isArray(scoreValue)) {
|
|
45904
|
+
results = scoreValue;
|
|
45905
|
+
} else if (typeof scoreValue === "object" && !isEmpty2(scoreValue)) {
|
|
45906
|
+
results = [scoreValue];
|
|
45907
|
+
} else {
|
|
45908
|
+
results = [{ name, score: scoreValue }];
|
|
45909
|
+
}
|
|
45910
|
+
const { resultMetadata, scoresRecord } = buildSpanScores(results);
|
|
45911
|
+
const fields = (score) => {
|
|
45912
|
+
const { metadata: _metadata, name: _name, ...rest } = score;
|
|
45913
|
+
return rest;
|
|
45914
|
+
};
|
|
45915
|
+
return {
|
|
45916
|
+
results,
|
|
45917
|
+
output: results.length === 1 ? fields(results[0]) : Object.fromEntries(
|
|
45918
|
+
results.map((score) => [score.name ?? name, fields(score)])
|
|
45919
|
+
),
|
|
45920
|
+
metadata: resultMetadata,
|
|
45921
|
+
scores: scoresRecord
|
|
45922
|
+
};
|
|
45923
|
+
}
|
|
45004
45924
|
async function runInScorerSpan(rootSpan, spanName, spanType, propagatedEvent, eventInput, fn) {
|
|
45005
45925
|
try {
|
|
45006
45926
|
const value = await rootSpan.traced(fn, {
|
|
@@ -45045,6 +45965,27 @@ function toClassificationItem(c) {
|
|
|
45045
45965
|
...c.metadata !== void 0 ? { metadata: c.metadata } : {}
|
|
45046
45966
|
};
|
|
45047
45967
|
}
|
|
45968
|
+
function _internalPrepareEvaluatorClassification(value, name) {
|
|
45969
|
+
if (value === null) return { results: null };
|
|
45970
|
+
const results = (Array.isArray(value) ? value : [value]).map(
|
|
45971
|
+
(result) => validateClassificationResult(result, name)
|
|
45972
|
+
);
|
|
45973
|
+
const classifications = /* @__PURE__ */ Object.create(null);
|
|
45974
|
+
for (const result of results) {
|
|
45975
|
+
(classifications[result.name] ??= []).push(toClassificationItem(result));
|
|
45976
|
+
}
|
|
45977
|
+
return {
|
|
45978
|
+
results,
|
|
45979
|
+
output: results.length === 1 ? toClassificationItem(results[0]) : Object.fromEntries(
|
|
45980
|
+
results.map((result) => [
|
|
45981
|
+
result.name,
|
|
45982
|
+
toClassificationItem(result)
|
|
45983
|
+
])
|
|
45984
|
+
),
|
|
45985
|
+
metadata: buildSpanMetadata(results),
|
|
45986
|
+
classifications
|
|
45987
|
+
};
|
|
45988
|
+
}
|
|
45048
45989
|
function logScoringFailures(kind, failures, metadata, rootSpan, state) {
|
|
45049
45990
|
if (!failures.length) return [];
|
|
45050
45991
|
const errorMap = Object.fromEntries(
|
|
@@ -45092,54 +46033,14 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
|
|
|
45092
46033
|
(evaluator.state ?? _internalGetGlobalState())?.spanCache?.start();
|
|
45093
46034
|
}
|
|
45094
46035
|
try {
|
|
45095
|
-
if (typeof evaluator.data === "string") {
|
|
45096
|
-
throw new Error("Unimplemented: string data paths");
|
|
45097
|
-
}
|
|
45098
|
-
let dataResult = typeof evaluator.data === "function" ? evaluator.data() : evaluator.data;
|
|
45099
46036
|
parameters = await validateParameters(
|
|
45100
46037
|
parameters ?? {},
|
|
45101
46038
|
evaluator.parameters
|
|
45102
46039
|
);
|
|
45103
|
-
|
|
45104
|
-
|
|
45105
|
-
|
|
45106
|
-
|
|
45107
|
-
if (!experiment) {
|
|
45108
|
-
throw new Error(
|
|
45109
|
-
"Cannot use BaseExperiment() without connecting to Braintrust (you most likely set --no-send-logs)"
|
|
45110
|
-
);
|
|
45111
|
-
}
|
|
45112
|
-
let name = dataResult.name;
|
|
45113
|
-
if (isEmpty2(name)) {
|
|
45114
|
-
const baseExperiment = await experiment.fetchBaseExperiment();
|
|
45115
|
-
if (!baseExperiment) {
|
|
45116
|
-
throw new Error("BaseExperiment() failed to fetch base experiment");
|
|
45117
|
-
}
|
|
45118
|
-
name = baseExperiment.name;
|
|
45119
|
-
}
|
|
45120
|
-
dataResult = initExperiment2(evaluator.state, {
|
|
45121
|
-
...evaluator.projectId ? { projectId: evaluator.projectId } : { project: evaluator.projectName },
|
|
45122
|
-
experiment: name,
|
|
45123
|
-
open: true
|
|
45124
|
-
}).asDataset();
|
|
45125
|
-
}
|
|
45126
|
-
const resolvedDataResult = dataResult instanceof Promise ? await dataResult : dataResult;
|
|
45127
|
-
const dataIterable = (() => {
|
|
45128
|
-
if (isAsyncIterable7(resolvedDataResult)) {
|
|
45129
|
-
return resolvedDataResult;
|
|
45130
|
-
}
|
|
45131
|
-
if (Array.isArray(resolvedDataResult) || isIterable(resolvedDataResult)) {
|
|
45132
|
-
const iterable = resolvedDataResult;
|
|
45133
|
-
return (async function* () {
|
|
45134
|
-
for (const datum of iterable) {
|
|
45135
|
-
yield datum;
|
|
45136
|
-
}
|
|
45137
|
-
})();
|
|
45138
|
-
}
|
|
45139
|
-
throw new Error(
|
|
45140
|
-
"Evaluator data must be an array, iterable, or async iterable"
|
|
45141
|
-
);
|
|
45142
|
-
})();
|
|
46040
|
+
const dataIterable = await _internalResolveEvaluatorData(
|
|
46041
|
+
evaluator,
|
|
46042
|
+
experiment
|
|
46043
|
+
);
|
|
45143
46044
|
progressReporter.start(evaluator.evalName, 0);
|
|
45144
46045
|
const experimentIdPromise = experiment ? (async () => {
|
|
45145
46046
|
try {
|
|
@@ -45208,57 +46109,45 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
|
|
|
45208
46109
|
ensureSpansFlushed,
|
|
45209
46110
|
state
|
|
45210
46111
|
}) : void 0;
|
|
45211
|
-
let metadata = {
|
|
45212
|
-
..."metadata" in datum ? datum.metadata : {}
|
|
45213
|
-
};
|
|
46112
|
+
let metadata = {};
|
|
45214
46113
|
const expected = "expected" in datum ? datum.expected : void 0;
|
|
45215
46114
|
let output = void 0;
|
|
45216
46115
|
let error = void 0;
|
|
45217
|
-
let tags = [
|
|
45218
|
-
const scores =
|
|
45219
|
-
const classifications =
|
|
46116
|
+
let tags = [];
|
|
46117
|
+
const scores = /* @__PURE__ */ Object.create(null);
|
|
46118
|
+
const classifications = /* @__PURE__ */ Object.create(null);
|
|
45220
46119
|
const scorerNames = (evaluator.scores ?? []).map(scorerName);
|
|
45221
46120
|
const classifierNames = (evaluator.classifiers ?? []).map(
|
|
45222
46121
|
classifierName
|
|
45223
46122
|
);
|
|
45224
46123
|
let unhandledScores = scorerNames;
|
|
45225
46124
|
try {
|
|
45226
|
-
const
|
|
45227
|
-
|
|
45228
|
-
|
|
45229
|
-
|
|
45230
|
-
|
|
45231
|
-
|
|
45232
|
-
|
|
45233
|
-
|
|
45234
|
-
|
|
45235
|
-
|
|
45236
|
-
|
|
45237
|
-
|
|
45238
|
-
|
|
45239
|
-
|
|
45240
|
-
|
|
45241
|
-
object_type: "task"
|
|
45242
|
-
});
|
|
45243
|
-
},
|
|
45244
|
-
trialIndex,
|
|
45245
|
-
tags
|
|
45246
|
-
};
|
|
45247
|
-
const outputResult = evaluator.task(datum.input, hooksForTask);
|
|
45248
|
-
if (outputResult instanceof Promise) {
|
|
45249
|
-
output = await outputResult;
|
|
45250
|
-
} else {
|
|
45251
|
-
output = outputResult;
|
|
46125
|
+
const taskResult = await rootSpan.traced(
|
|
46126
|
+
(span) => _internalRunEvaluatorTask(
|
|
46127
|
+
evaluator.task,
|
|
46128
|
+
datum,
|
|
46129
|
+
trialIndex,
|
|
46130
|
+
parameters ?? {},
|
|
46131
|
+
span,
|
|
46132
|
+
(event) => {
|
|
46133
|
+
stream?.({
|
|
46134
|
+
...event,
|
|
46135
|
+
id: rootSpan.id,
|
|
46136
|
+
origin: baseEvent.event?.origin,
|
|
46137
|
+
name: evaluator.evalName,
|
|
46138
|
+
object_type: "task"
|
|
46139
|
+
});
|
|
45252
46140
|
}
|
|
45253
|
-
|
|
45254
|
-
span.log({ output });
|
|
45255
|
-
},
|
|
46141
|
+
),
|
|
45256
46142
|
{
|
|
45257
46143
|
name: "task",
|
|
45258
46144
|
spanAttributes: { type: "task" /* TASK */ },
|
|
45259
46145
|
event: { input: datum.input }
|
|
45260
46146
|
}
|
|
45261
46147
|
);
|
|
46148
|
+
output = taskResult.output;
|
|
46149
|
+
metadata = taskResult.metadata;
|
|
46150
|
+
tags = taskResult.tags;
|
|
45262
46151
|
if (tags.length) {
|
|
45263
46152
|
rootSpan.log({ output, metadata, expected, tags });
|
|
45264
46153
|
} else {
|
|
@@ -45268,20 +46157,18 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
|
|
|
45268
46157
|
await rootSpan.flush();
|
|
45269
46158
|
}
|
|
45270
46159
|
const scoringArgs = {
|
|
46160
|
+
id: datum.id,
|
|
45271
46161
|
input: datum.input,
|
|
45272
46162
|
expected: "expected" in datum ? datum.expected : void 0,
|
|
45273
46163
|
metadata,
|
|
45274
46164
|
output,
|
|
46165
|
+
tags,
|
|
45275
46166
|
trace
|
|
45276
46167
|
};
|
|
45277
46168
|
const { trace: _trace, ...scoringArgsForLogging } = scoringArgs;
|
|
45278
46169
|
const propagatedEvent = makeScorerPropagatedEvent(
|
|
45279
46170
|
await rootSpan.export()
|
|
45280
46171
|
);
|
|
45281
|
-
const getOtherFields = (s) => {
|
|
45282
|
-
const { metadata: _metadata, name: _name, ...rest } = s;
|
|
45283
|
-
return rest;
|
|
45284
|
-
};
|
|
45285
46172
|
const [scoreResults, classificationResults] = await Promise.all([
|
|
45286
46173
|
Promise.all(
|
|
45287
46174
|
(evaluator.scores ?? []).map(
|
|
@@ -45295,35 +46182,17 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
|
|
|
45295
46182
|
const scoreValue = await Promise.resolve(
|
|
45296
46183
|
score(scoringArgs)
|
|
45297
46184
|
);
|
|
45298
|
-
|
|
45299
|
-
|
|
45300
|
-
|
|
45301
|
-
if (!(typeof s === "object" && !isEmpty2(s))) {
|
|
45302
|
-
throw new Error(
|
|
45303
|
-
`When returning an array of scores, each score must be a non-empty object. Got: ${JSON.stringify(s)}`
|
|
45304
|
-
);
|
|
45305
|
-
}
|
|
45306
|
-
}
|
|
45307
|
-
}
|
|
45308
|
-
const results = Array.isArray(scoreValue) ? scoreValue : typeof scoreValue === "object" && !isEmpty2(scoreValue) ? [scoreValue] : [
|
|
45309
|
-
{
|
|
45310
|
-
name: scorerNames[score_idx],
|
|
45311
|
-
score: scoreValue
|
|
45312
|
-
}
|
|
45313
|
-
];
|
|
45314
|
-
const { resultMetadata, scoresRecord } = buildSpanScores(results);
|
|
45315
|
-
const resultOutput = results.length === 1 ? getOtherFields(results[0]) : results.reduce(
|
|
45316
|
-
(prev, s) => mergeDicts(prev, {
|
|
45317
|
-
[s.name]: getOtherFields(s)
|
|
45318
|
-
}),
|
|
45319
|
-
{}
|
|
46185
|
+
const prepared = _internalPrepareEvaluatorScore(
|
|
46186
|
+
scoreValue,
|
|
46187
|
+
scorerNames[score_idx]
|
|
45320
46188
|
);
|
|
46189
|
+
if (prepared.results === null) return null;
|
|
45321
46190
|
span.log({
|
|
45322
|
-
output:
|
|
45323
|
-
metadata:
|
|
45324
|
-
scores:
|
|
46191
|
+
output: prepared.output,
|
|
46192
|
+
metadata: prepared.metadata,
|
|
46193
|
+
scores: prepared.scores
|
|
45325
46194
|
});
|
|
45326
|
-
return results;
|
|
46195
|
+
return prepared.results;
|
|
45327
46196
|
}
|
|
45328
46197
|
)
|
|
45329
46198
|
)
|
|
@@ -45340,24 +46209,16 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
|
|
|
45340
46209
|
const classifierValue = await Promise.resolve(
|
|
45341
46210
|
classifier(scoringArgs)
|
|
45342
46211
|
);
|
|
45343
|
-
|
|
45344
|
-
|
|
45345
|
-
|
|
45346
|
-
result,
|
|
45347
|
-
classifierNames[idx]
|
|
45348
|
-
)
|
|
45349
|
-
);
|
|
45350
|
-
const resultOutput = rawResults.length === 1 ? toClassificationItem(rawResults[0]) : rawResults.reduce(
|
|
45351
|
-
(prev, r) => mergeDicts(prev, {
|
|
45352
|
-
[r.name]: toClassificationItem(r)
|
|
45353
|
-
}),
|
|
45354
|
-
{}
|
|
46212
|
+
const prepared = _internalPrepareEvaluatorClassification(
|
|
46213
|
+
classifierValue,
|
|
46214
|
+
classifierNames[idx]
|
|
45355
46215
|
);
|
|
46216
|
+
if (prepared.results === null) return null;
|
|
45356
46217
|
span.log({
|
|
45357
|
-
output:
|
|
45358
|
-
metadata:
|
|
46218
|
+
output: prepared.output,
|
|
46219
|
+
metadata: prepared.metadata
|
|
45359
46220
|
});
|
|
45360
|
-
return
|
|
46221
|
+
return prepared.results;
|
|
45361
46222
|
}
|
|
45362
46223
|
)
|
|
45363
46224
|
)
|
|
@@ -45586,7 +46447,7 @@ function accumulateScores(accumulator, scores) {
|
|
|
45586
46447
|
}
|
|
45587
46448
|
}
|
|
45588
46449
|
function ensureScoreAccumulator(results) {
|
|
45589
|
-
const accumulator =
|
|
46450
|
+
const accumulator = /* @__PURE__ */ Object.create(null);
|
|
45590
46451
|
for (const result of results) {
|
|
45591
46452
|
accumulateScores(accumulator, result.scores);
|
|
45592
46453
|
}
|
|
@@ -45729,6 +46590,1156 @@ var defaultReporter = {
|
|
|
45729
46590
|
}
|
|
45730
46591
|
};
|
|
45731
46592
|
|
|
46593
|
+
// src/durable-eval.ts
|
|
46594
|
+
var encoder = new TextEncoder();
|
|
46595
|
+
var decoder = new TextDecoder();
|
|
46596
|
+
var BATCH_TASK_KIND = "braintrust.durable.batch-task";
|
|
46597
|
+
var BATCH_SCORER_KIND = "braintrust.durable.batch-scorer";
|
|
46598
|
+
var DEFAULT_BATCH_SIZE = 1e3;
|
|
46599
|
+
var DurableEvalMemoryStore = class {
|
|
46600
|
+
values = /* @__PURE__ */ new Map();
|
|
46601
|
+
async read(key) {
|
|
46602
|
+
return this.values.get(key)?.slice();
|
|
46603
|
+
}
|
|
46604
|
+
async write(key, value) {
|
|
46605
|
+
this.values.set(key, value.slice());
|
|
46606
|
+
}
|
|
46607
|
+
async getOrSet(key, value) {
|
|
46608
|
+
const existing = this.values.get(key);
|
|
46609
|
+
if (existing) return { value: existing.slice(), created: false };
|
|
46610
|
+
this.values.set(key, value.slice());
|
|
46611
|
+
return { value: value.slice(), created: true };
|
|
46612
|
+
}
|
|
46613
|
+
};
|
|
46614
|
+
var DurableEvalRedisStore = class {
|
|
46615
|
+
client;
|
|
46616
|
+
keyPrefix;
|
|
46617
|
+
ttlMs;
|
|
46618
|
+
constructor(options) {
|
|
46619
|
+
this.client = options.client;
|
|
46620
|
+
this.keyPrefix = options.keyPrefix ?? "braintrust-eval:";
|
|
46621
|
+
this.ttlMs = options.ttlMs ?? 1e3 * 60 * 60 * 24 * 7;
|
|
46622
|
+
if (!Number.isInteger(this.ttlMs) || this.ttlMs < 1) {
|
|
46623
|
+
throw new Error("DurableEvalRedisStore ttlMs must be a positive integer");
|
|
46624
|
+
}
|
|
46625
|
+
}
|
|
46626
|
+
async read(key) {
|
|
46627
|
+
const value = await this.client.get(`${this.keyPrefix}${key}`);
|
|
46628
|
+
if (value == null) return void 0;
|
|
46629
|
+
if (typeof value !== "string") {
|
|
46630
|
+
throw new Error("DurableEvalRedisStore expected GET to return a string");
|
|
46631
|
+
}
|
|
46632
|
+
return base64ToUint8Array(value);
|
|
46633
|
+
}
|
|
46634
|
+
async write(key, value) {
|
|
46635
|
+
const client = this.client;
|
|
46636
|
+
const set = client.set;
|
|
46637
|
+
const redisKey = `${this.keyPrefix}${key}`;
|
|
46638
|
+
const encoded = uint8ArrayToBase64(value);
|
|
46639
|
+
if (typeof client.defineCommand === "function") {
|
|
46640
|
+
await set.call(client, redisKey, encoded, "PX", this.ttlMs);
|
|
46641
|
+
} else if (typeof client.sendCommand === "function") {
|
|
46642
|
+
await set.call(client, redisKey, encoded, { PX: this.ttlMs });
|
|
46643
|
+
} else if (typeof client.createScript === "function") {
|
|
46644
|
+
await set.call(client, redisKey, encoded, { px: this.ttlMs });
|
|
46645
|
+
} else {
|
|
46646
|
+
throw new Error(
|
|
46647
|
+
"DurableEvalRedisStore requires a node-redis, ioredis, or @upstash/redis client"
|
|
46648
|
+
);
|
|
46649
|
+
}
|
|
46650
|
+
}
|
|
46651
|
+
async getOrSet(key, value) {
|
|
46652
|
+
const redisKey = `${this.keyPrefix}${key}`;
|
|
46653
|
+
const encoded = uint8ArrayToBase64(value);
|
|
46654
|
+
const client = this.client;
|
|
46655
|
+
const set = client.set;
|
|
46656
|
+
let setOptions;
|
|
46657
|
+
if (typeof client.defineCommand === "function") {
|
|
46658
|
+
setOptions = ["PX", this.ttlMs, "NX", "GET"];
|
|
46659
|
+
} else if (typeof client.sendCommand === "function") {
|
|
46660
|
+
setOptions = [{ PX: this.ttlMs, NX: true, GET: true }];
|
|
46661
|
+
} else if (typeof client.createScript === "function") {
|
|
46662
|
+
setOptions = [{ px: this.ttlMs, nx: true, get: true }];
|
|
46663
|
+
} else {
|
|
46664
|
+
throw new Error(
|
|
46665
|
+
"DurableEvalRedisStore getOrSet requires a node-redis, ioredis, or @upstash/redis client"
|
|
46666
|
+
);
|
|
46667
|
+
}
|
|
46668
|
+
const existing = await set.call(client, redisKey, encoded, ...setOptions);
|
|
46669
|
+
if (existing === null) return { value: value.slice(), created: true };
|
|
46670
|
+
if (typeof existing !== "string") {
|
|
46671
|
+
throw new Error(
|
|
46672
|
+
"DurableEvalRedisStore expected atomic SET to return a string or null"
|
|
46673
|
+
);
|
|
46674
|
+
}
|
|
46675
|
+
return { value: base64ToUint8Array(existing), created: false };
|
|
46676
|
+
}
|
|
46677
|
+
};
|
|
46678
|
+
var BatchTask = class {
|
|
46679
|
+
constructor(processor) {
|
|
46680
|
+
this.processor = processor;
|
|
46681
|
+
}
|
|
46682
|
+
processor;
|
|
46683
|
+
kind = BATCH_TASK_KIND;
|
|
46684
|
+
};
|
|
46685
|
+
var BatchScorer = class {
|
|
46686
|
+
constructor(processor) {
|
|
46687
|
+
this.processor = processor;
|
|
46688
|
+
this.name = processor.name;
|
|
46689
|
+
}
|
|
46690
|
+
processor;
|
|
46691
|
+
kind = BATCH_SCORER_KIND;
|
|
46692
|
+
name;
|
|
46693
|
+
};
|
|
46694
|
+
function defineDurableEval(projectName, evaluator) {
|
|
46695
|
+
const definition = {
|
|
46696
|
+
projectName,
|
|
46697
|
+
evalName: evaluator.experimentName ?? projectName,
|
|
46698
|
+
evaluator
|
|
46699
|
+
};
|
|
46700
|
+
return {
|
|
46701
|
+
start: (options = {}) => startDurableEval(definition, options),
|
|
46702
|
+
status: (options) => getDurableEvalStatus(definition, options),
|
|
46703
|
+
poll: (options) => pollDurableEval(definition, options),
|
|
46704
|
+
processBatchResult: (result) => processDurableBatchResult(definition, result)
|
|
46705
|
+
};
|
|
46706
|
+
}
|
|
46707
|
+
async function startDurableEval(definition, options) {
|
|
46708
|
+
const store = definition.evaluator.store;
|
|
46709
|
+
const runId = newId();
|
|
46710
|
+
const key = runKey(definition.projectName, definition.evalName, runId);
|
|
46711
|
+
const { data } = callEvaluatorData(definition.evaluator.data);
|
|
46712
|
+
const parameters = await validateParameters(
|
|
46713
|
+
options.parameters ?? {},
|
|
46714
|
+
definition.evaluator.parameters
|
|
46715
|
+
);
|
|
46716
|
+
const experimentName = definition.evaluator.experimentName ?? `${definition.evalName}-${runId}`;
|
|
46717
|
+
const experiment = await _internalInitEvaluatorExperiment(
|
|
46718
|
+
definition.projectName,
|
|
46719
|
+
{ ...definition.evaluator, data },
|
|
46720
|
+
data,
|
|
46721
|
+
{
|
|
46722
|
+
disabled: options.noSendLogs ?? false,
|
|
46723
|
+
experimentName,
|
|
46724
|
+
update: true
|
|
46725
|
+
}
|
|
46726
|
+
);
|
|
46727
|
+
if (!isBatchTask(definition.evaluator.task) && !(definition.evaluator.scores ?? []).some(isBatchScorer)) {
|
|
46728
|
+
const result = await runEvaluator(
|
|
46729
|
+
experiment,
|
|
46730
|
+
{
|
|
46731
|
+
...definition.evaluator,
|
|
46732
|
+
projectName: definition.projectName,
|
|
46733
|
+
evalName: definition.evalName,
|
|
46734
|
+
data
|
|
46735
|
+
},
|
|
46736
|
+
{
|
|
46737
|
+
start: () => void 0,
|
|
46738
|
+
stop: () => void 0,
|
|
46739
|
+
increment: () => void 0
|
|
46740
|
+
},
|
|
46741
|
+
[],
|
|
46742
|
+
void 0,
|
|
46743
|
+
parameters,
|
|
46744
|
+
true,
|
|
46745
|
+
true
|
|
46746
|
+
);
|
|
46747
|
+
const state2 = {
|
|
46748
|
+
runId,
|
|
46749
|
+
experimentName,
|
|
46750
|
+
noSendLogs: options.noSendLogs ?? false,
|
|
46751
|
+
parameters: assertJsonValue(parameters, "eval parameters"),
|
|
46752
|
+
status: "completed",
|
|
46753
|
+
summary: result.summary,
|
|
46754
|
+
cases: [],
|
|
46755
|
+
batches: []
|
|
46756
|
+
};
|
|
46757
|
+
await experiment?.flush();
|
|
46758
|
+
await writeRunRecord(store, key, state2);
|
|
46759
|
+
return currentStatus(definition, state2);
|
|
46760
|
+
}
|
|
46761
|
+
const state = {
|
|
46762
|
+
runId,
|
|
46763
|
+
experimentName,
|
|
46764
|
+
noSendLogs: options.noSendLogs ?? false,
|
|
46765
|
+
parameters: assertJsonValue(parameters, "eval parameters"),
|
|
46766
|
+
status: "running",
|
|
46767
|
+
cases: await materializeCases(definition, data, experiment),
|
|
46768
|
+
batches: []
|
|
46769
|
+
};
|
|
46770
|
+
await writeCaseBaseRecords(store, key, state.cases);
|
|
46771
|
+
await writeRunRecord(store, key, state);
|
|
46772
|
+
return advanceDurableEval(definition, state, store, key, experiment);
|
|
46773
|
+
}
|
|
46774
|
+
async function getDurableEvalStatus(definition, options) {
|
|
46775
|
+
const store = definition.evaluator.store;
|
|
46776
|
+
const state = await readRunState(
|
|
46777
|
+
definition,
|
|
46778
|
+
store,
|
|
46779
|
+
runKey(definition.projectName, definition.evalName, options.runId)
|
|
46780
|
+
);
|
|
46781
|
+
if (!state) throw new Error(`Durable eval run ${options.runId} is missing`);
|
|
46782
|
+
return currentStatus(definition, state);
|
|
46783
|
+
}
|
|
46784
|
+
async function processDurableBatchResult(definition, result) {
|
|
46785
|
+
if (!result.batchId && !result.externalId) {
|
|
46786
|
+
throw new Error("Batch results require batchId or externalId");
|
|
46787
|
+
}
|
|
46788
|
+
const store = definition.evaluator.store;
|
|
46789
|
+
const key = runKey(definition.projectName, definition.evalName, result.runId);
|
|
46790
|
+
const state = await readRunState(definition, store, key);
|
|
46791
|
+
if (!state) throw new Error(`Durable eval run ${result.runId} is missing`);
|
|
46792
|
+
const byBatch = result.batchId ? state.batches.find((candidate) => candidate.id === result.batchId) : void 0;
|
|
46793
|
+
const byExternal = result.externalId ? state.batches.find(
|
|
46794
|
+
(candidate) => candidate.externalId === result.externalId
|
|
46795
|
+
) : void 0;
|
|
46796
|
+
if (byBatch && byExternal && byBatch.id !== byExternal.id) {
|
|
46797
|
+
throw new Error("batchId and externalId identify different batches");
|
|
46798
|
+
}
|
|
46799
|
+
const batch = byBatch ?? byExternal;
|
|
46800
|
+
if (!batch) throw new Error("No submitted batch matches this result");
|
|
46801
|
+
if (batch.status !== "complete") {
|
|
46802
|
+
const records = await collectBatch(definition, state, batch);
|
|
46803
|
+
batch.status = "complete";
|
|
46804
|
+
await writeCaseRecords(store, key, records);
|
|
46805
|
+
await writeBatchRecords(store, key, [batch]);
|
|
46806
|
+
}
|
|
46807
|
+
return advanceDurableEval(
|
|
46808
|
+
definition,
|
|
46809
|
+
await readRunState(definition, store, key),
|
|
46810
|
+
store,
|
|
46811
|
+
key
|
|
46812
|
+
);
|
|
46813
|
+
}
|
|
46814
|
+
async function pollDurableEval(definition, options) {
|
|
46815
|
+
const store = definition.evaluator.store;
|
|
46816
|
+
const key = runKey(
|
|
46817
|
+
definition.projectName,
|
|
46818
|
+
definition.evalName,
|
|
46819
|
+
options.runId
|
|
46820
|
+
);
|
|
46821
|
+
const state = await readRunState(definition, store, key);
|
|
46822
|
+
if (!state) throw new Error(`Durable eval run ${options.runId} is missing`);
|
|
46823
|
+
const batches = state.batches.filter((batch) => {
|
|
46824
|
+
if (batch.status === "complete") return false;
|
|
46825
|
+
return processorForStage(definition, batch.kind, batch.scorerName).completion.mode === "poll";
|
|
46826
|
+
});
|
|
46827
|
+
const results = await Promise.all(
|
|
46828
|
+
batches.map(async (batch) => ({
|
|
46829
|
+
batch,
|
|
46830
|
+
result: await processorForStage(definition, batch.kind, batch.scorerName).completion.poll(batch.submissionData, {
|
|
46831
|
+
runId: state.runId,
|
|
46832
|
+
batchId: batch.id
|
|
46833
|
+
})
|
|
46834
|
+
}))
|
|
46835
|
+
);
|
|
46836
|
+
const changedCases = /* @__PURE__ */ new Map();
|
|
46837
|
+
const changedBatches = [];
|
|
46838
|
+
for (const { batch, result } of results) {
|
|
46839
|
+
if (result.status === "failed") throw asError(result.error);
|
|
46840
|
+
if (result.status !== "complete") continue;
|
|
46841
|
+
for (const record of await collectBatch(definition, state, batch)) {
|
|
46842
|
+
changedCases.set(record.id, record);
|
|
46843
|
+
}
|
|
46844
|
+
batch.status = "complete";
|
|
46845
|
+
changedBatches.push(batch);
|
|
46846
|
+
}
|
|
46847
|
+
if (changedBatches.length > 0) {
|
|
46848
|
+
await writeCaseRecords(store, key, [...changedCases.values()]);
|
|
46849
|
+
await writeBatchRecords(store, key, changedBatches);
|
|
46850
|
+
}
|
|
46851
|
+
const currentState = changedBatches.length > 0 ? await readRunState(definition, store, key) : state;
|
|
46852
|
+
return advanceDurableEval(definition, currentState, store, key);
|
|
46853
|
+
}
|
|
46854
|
+
async function openDurableExperiment(definition, state) {
|
|
46855
|
+
const data = [];
|
|
46856
|
+
return await _internalInitEvaluatorExperiment(
|
|
46857
|
+
definition.projectName,
|
|
46858
|
+
{ ...definition.evaluator, data },
|
|
46859
|
+
data,
|
|
46860
|
+
{
|
|
46861
|
+
disabled: state.noSendLogs,
|
|
46862
|
+
experimentName: state.experimentName,
|
|
46863
|
+
update: true
|
|
46864
|
+
}
|
|
46865
|
+
);
|
|
46866
|
+
}
|
|
46867
|
+
async function advanceDurableEval(definition, state, store, key, existingExperiment) {
|
|
46868
|
+
if (state.status === "completed") return currentStatus(definition, state);
|
|
46869
|
+
const experiment = existingExperiment === void 0 ? await openDurableExperiment(definition, state) : existingExperiment;
|
|
46870
|
+
await runTaskStage(definition, state, store, key, experiment);
|
|
46871
|
+
await logCompletedTasks(definition, state, store, key, experiment);
|
|
46872
|
+
state = await readRunState(definition, store, key) ?? state;
|
|
46873
|
+
if (state.cases.some((record) => !record.taskComplete || !record.taskLogged)) {
|
|
46874
|
+
return currentStatus(definition, state);
|
|
46875
|
+
}
|
|
46876
|
+
await runScoreStages(definition, state, store, key, experiment);
|
|
46877
|
+
state = await readRunState(definition, store, key) ?? state;
|
|
46878
|
+
const scorerNames = resolveScorers(definition.evaluator.scores ?? []).map(
|
|
46879
|
+
({ name }) => name
|
|
46880
|
+
);
|
|
46881
|
+
const classifierNames = (definition.evaluator.classifiers ?? []).map(
|
|
46882
|
+
classifierName
|
|
46883
|
+
);
|
|
46884
|
+
if (state.cases.some(
|
|
46885
|
+
(record) => scorerNames.some(
|
|
46886
|
+
(name) => !Object.hasOwn(record.scores, name) || !Object.hasOwn(record.loggedScores, name)
|
|
46887
|
+
) || classifierNames.some(
|
|
46888
|
+
(name) => !Object.hasOwn(record.loggedClassifications, name)
|
|
46889
|
+
)
|
|
46890
|
+
)) {
|
|
46891
|
+
return currentStatus(definition, state);
|
|
46892
|
+
}
|
|
46893
|
+
if (!await claimAction(store, key, "finish")) {
|
|
46894
|
+
const latest = await readRunState(definition, store, key);
|
|
46895
|
+
return currentStatus(definition, latest ?? state);
|
|
46896
|
+
}
|
|
46897
|
+
state.summary = await finishExperiment(definition, state, experiment);
|
|
46898
|
+
state.status = "completed";
|
|
46899
|
+
await writeRunRecord(store, key, state);
|
|
46900
|
+
return currentStatus(definition, state);
|
|
46901
|
+
}
|
|
46902
|
+
function currentStatus(definition, state) {
|
|
46903
|
+
if (state.status === "completed") {
|
|
46904
|
+
if (!state.summary) {
|
|
46905
|
+
throw new Error(`Durable eval run ${state.runId} has no saved summary`);
|
|
46906
|
+
}
|
|
46907
|
+
return {
|
|
46908
|
+
status: "completed",
|
|
46909
|
+
runId: state.runId,
|
|
46910
|
+
pending: { poll: 0, webhook: 0 },
|
|
46911
|
+
summary: state.summary
|
|
46912
|
+
};
|
|
46913
|
+
}
|
|
46914
|
+
const pending = { poll: 0, webhook: 0 };
|
|
46915
|
+
for (const batch of state.batches) {
|
|
46916
|
+
if (batch.status === "complete") continue;
|
|
46917
|
+
pending[processorForStage(definition, batch.kind, batch.scorerName).completion.mode]++;
|
|
46918
|
+
}
|
|
46919
|
+
return { status: "waiting", runId: state.runId, pending };
|
|
46920
|
+
}
|
|
46921
|
+
async function startCaseRoot(definition, state, record, experiment) {
|
|
46922
|
+
if (!experiment) return NOOP_SPAN;
|
|
46923
|
+
const datum = record.datum;
|
|
46924
|
+
return _internalStartSpanWithInitialMerge({
|
|
46925
|
+
...definition.evaluator.state ? { state: definition.evaluator.state } : {},
|
|
46926
|
+
parent: await experiment.export(),
|
|
46927
|
+
name: "eval",
|
|
46928
|
+
spanId: deterministicId(`${state.runId}:${record.id}:span`),
|
|
46929
|
+
spanAttributes: { type: "eval" /* EVAL */ },
|
|
46930
|
+
event: {
|
|
46931
|
+
id: deterministicId(`${state.runId}:${record.id}:row`),
|
|
46932
|
+
input: datum.input,
|
|
46933
|
+
expected: "expected" in datum ? datum.expected : void 0,
|
|
46934
|
+
tags: datum.tags,
|
|
46935
|
+
origin: datum.origin
|
|
46936
|
+
}
|
|
46937
|
+
});
|
|
46938
|
+
}
|
|
46939
|
+
async function logTaskResult(definition, state, record, experiment, task) {
|
|
46940
|
+
const datum = record.datum;
|
|
46941
|
+
const root = await startCaseRoot(definition, state, record, experiment);
|
|
46942
|
+
try {
|
|
46943
|
+
if (task) {
|
|
46944
|
+
const result = await root.traced(
|
|
46945
|
+
(span) => _internalRunEvaluatorTask(
|
|
46946
|
+
task,
|
|
46947
|
+
datum,
|
|
46948
|
+
record.trialIndex,
|
|
46949
|
+
state.parameters,
|
|
46950
|
+
span
|
|
46951
|
+
),
|
|
46952
|
+
{
|
|
46953
|
+
name: "task",
|
|
46954
|
+
spanId: deterministicId(`${state.runId}:${record.id}:task`),
|
|
46955
|
+
spanAttributes: { type: "task" /* TASK */ },
|
|
46956
|
+
event: { input: datum.input }
|
|
46957
|
+
}
|
|
46958
|
+
);
|
|
46959
|
+
record.output = assertJsonValue(
|
|
46960
|
+
result.output,
|
|
46961
|
+
`task output for ${record.caseId}`
|
|
46962
|
+
);
|
|
46963
|
+
record.metadata = assertJsonValue(result.metadata, "task metadata");
|
|
46964
|
+
record.tags = result.tags;
|
|
46965
|
+
record.taskComplete = true;
|
|
46966
|
+
} else {
|
|
46967
|
+
await root.traced((span) => span.log({ output: record.output }), {
|
|
46968
|
+
name: "task",
|
|
46969
|
+
spanId: deterministicId(`${state.runId}:${record.id}:task`),
|
|
46970
|
+
spanAttributes: { type: "task" /* TASK */ },
|
|
46971
|
+
event: { input: datum.input }
|
|
46972
|
+
});
|
|
46973
|
+
}
|
|
46974
|
+
root.log({
|
|
46975
|
+
output: record.output,
|
|
46976
|
+
expected: "expected" in datum ? datum.expected : void 0,
|
|
46977
|
+
metadata: {
|
|
46978
|
+
...record.metadata,
|
|
46979
|
+
durable_eval: {
|
|
46980
|
+
run_id: state.runId,
|
|
46981
|
+
case_id: record.caseId,
|
|
46982
|
+
trial_index: record.trialIndex
|
|
46983
|
+
}
|
|
46984
|
+
},
|
|
46985
|
+
tags: record.tags
|
|
46986
|
+
});
|
|
46987
|
+
record.rootSpan = await root.export();
|
|
46988
|
+
record.taskLogged = true;
|
|
46989
|
+
} catch (error) {
|
|
46990
|
+
logError(root, error);
|
|
46991
|
+
throw error;
|
|
46992
|
+
} finally {
|
|
46993
|
+
root.end();
|
|
46994
|
+
}
|
|
46995
|
+
}
|
|
46996
|
+
async function logCompletedTasks(definition, state, store, key, experiment) {
|
|
46997
|
+
const changed = [];
|
|
46998
|
+
for (const record of state.cases) {
|
|
46999
|
+
if (!record.taskComplete || record.taskLogged) continue;
|
|
47000
|
+
if (!await claimAction(store, key, "task-log", record.id)) continue;
|
|
47001
|
+
await logTaskResult(definition, state, record, experiment);
|
|
47002
|
+
changed.push(record);
|
|
47003
|
+
}
|
|
47004
|
+
if (changed.length > 0) {
|
|
47005
|
+
await experiment?.flush();
|
|
47006
|
+
await writeCaseRecords(store, key, changed);
|
|
47007
|
+
}
|
|
47008
|
+
}
|
|
47009
|
+
async function runTaskStage(definition, state, store, key, experiment) {
|
|
47010
|
+
if (isBatchTask(definition.evaluator.task)) {
|
|
47011
|
+
await ensureBatches(definition, state, store, key, "task");
|
|
47012
|
+
return;
|
|
47013
|
+
}
|
|
47014
|
+
const task = definition.evaluator.task;
|
|
47015
|
+
const changed = [];
|
|
47016
|
+
for (const record of state.cases) {
|
|
47017
|
+
if (record.taskComplete) continue;
|
|
47018
|
+
if (!await claimAction(store, key, "task", record.id)) continue;
|
|
47019
|
+
await logTaskResult(definition, state, record, experiment, task);
|
|
47020
|
+
changed.push(record);
|
|
47021
|
+
}
|
|
47022
|
+
if (changed.length > 0) {
|
|
47023
|
+
await experiment?.flush();
|
|
47024
|
+
await writeCaseRecords(store, key, changed);
|
|
47025
|
+
}
|
|
47026
|
+
}
|
|
47027
|
+
async function runScoreStages(definition, state, store, key, experiment) {
|
|
47028
|
+
const scorers = resolveScorers(definition.evaluator.scores ?? []);
|
|
47029
|
+
const changed = /* @__PURE__ */ new Map();
|
|
47030
|
+
const persistChangedCases = async () => {
|
|
47031
|
+
if (changed.size === 0) return;
|
|
47032
|
+
await experiment?.flush();
|
|
47033
|
+
await writeCaseRecords(store, key, [...changed.values()]);
|
|
47034
|
+
changed.clear();
|
|
47035
|
+
};
|
|
47036
|
+
for (const { name, scorer } of scorers) {
|
|
47037
|
+
if (isBatchScorer(scorer)) {
|
|
47038
|
+
for (const record of state.cases) {
|
|
47039
|
+
if (Object.hasOwn(record.scores, name) && !Object.hasOwn(record.loggedScores, name)) {
|
|
47040
|
+
if (!await claimAction(store, key, "score-log", record.id, name)) {
|
|
47041
|
+
continue;
|
|
47042
|
+
}
|
|
47043
|
+
await evaluateAndLogScore(
|
|
47044
|
+
definition,
|
|
47045
|
+
state,
|
|
47046
|
+
record,
|
|
47047
|
+
name,
|
|
47048
|
+
experiment
|
|
47049
|
+
);
|
|
47050
|
+
changed.set(record.id, record);
|
|
47051
|
+
}
|
|
47052
|
+
}
|
|
47053
|
+
await persistChangedCases();
|
|
47054
|
+
await ensureBatches(definition, state, store, key, "score", name);
|
|
47055
|
+
continue;
|
|
47056
|
+
}
|
|
47057
|
+
for (const record of state.cases) {
|
|
47058
|
+
if (Object.hasOwn(record.loggedScores, name)) continue;
|
|
47059
|
+
if (!await claimAction(store, key, "score", record.id, name)) continue;
|
|
47060
|
+
await evaluateAndLogScore(
|
|
47061
|
+
definition,
|
|
47062
|
+
state,
|
|
47063
|
+
record,
|
|
47064
|
+
name,
|
|
47065
|
+
experiment,
|
|
47066
|
+
scorer
|
|
47067
|
+
);
|
|
47068
|
+
changed.set(record.id, record);
|
|
47069
|
+
}
|
|
47070
|
+
}
|
|
47071
|
+
for (const [index, classifier] of (definition.evaluator.classifiers ?? []).entries()) {
|
|
47072
|
+
const name = classifierName(classifier, index);
|
|
47073
|
+
for (const record of state.cases) {
|
|
47074
|
+
if (Object.hasOwn(record.loggedClassifications, name)) continue;
|
|
47075
|
+
if (!await claimAction(store, key, "classification", record.id, name)) {
|
|
47076
|
+
continue;
|
|
47077
|
+
}
|
|
47078
|
+
await evaluateAndLogClassification(
|
|
47079
|
+
definition,
|
|
47080
|
+
state,
|
|
47081
|
+
record,
|
|
47082
|
+
name,
|
|
47083
|
+
classifier,
|
|
47084
|
+
experiment
|
|
47085
|
+
);
|
|
47086
|
+
changed.set(record.id, record);
|
|
47087
|
+
}
|
|
47088
|
+
}
|
|
47089
|
+
await persistChangedCases();
|
|
47090
|
+
}
|
|
47091
|
+
function scorerArgs(record) {
|
|
47092
|
+
const datum = record.datum;
|
|
47093
|
+
return {
|
|
47094
|
+
...datum,
|
|
47095
|
+
metadata: record.metadata,
|
|
47096
|
+
output: record.output
|
|
47097
|
+
};
|
|
47098
|
+
}
|
|
47099
|
+
function resumeCaseRoot(definition, record, experiment) {
|
|
47100
|
+
if (!experiment) return NOOP_SPAN;
|
|
47101
|
+
if (!record.rootSpan) {
|
|
47102
|
+
throw new Error(`Durable eval case ${record.caseId} has no root span`);
|
|
47103
|
+
}
|
|
47104
|
+
return _internalResumeSpan({
|
|
47105
|
+
exported: record.rootSpan,
|
|
47106
|
+
state: definition.evaluator.state
|
|
47107
|
+
});
|
|
47108
|
+
}
|
|
47109
|
+
async function evaluateAndLogScore(definition, state, record, name, experiment, scorer) {
|
|
47110
|
+
const root = resumeCaseRoot(definition, record, experiment);
|
|
47111
|
+
try {
|
|
47112
|
+
const rootExport = await root.export();
|
|
47113
|
+
const prepared = await root.traced(
|
|
47114
|
+
async (span) => {
|
|
47115
|
+
const value = scorer ? await scorer(scorerArgs(record)) : record.scores[name];
|
|
47116
|
+
if (scorer) {
|
|
47117
|
+
record.scores[name] = assertJsonValue(value, `scorer ${name} output`);
|
|
47118
|
+
}
|
|
47119
|
+
const result = _internalPrepareEvaluatorScore(value, name);
|
|
47120
|
+
if (result.results !== null) {
|
|
47121
|
+
span.log({
|
|
47122
|
+
output: result.output,
|
|
47123
|
+
metadata: result.metadata,
|
|
47124
|
+
scores: result.scores
|
|
47125
|
+
});
|
|
47126
|
+
}
|
|
47127
|
+
return result;
|
|
47128
|
+
},
|
|
47129
|
+
{
|
|
47130
|
+
name,
|
|
47131
|
+
spanId: deterministicId(`${state.runId}:${record.id}:score:${name}`),
|
|
47132
|
+
spanAttributes: {
|
|
47133
|
+
type: "score" /* SCORE */,
|
|
47134
|
+
purpose: "scorer"
|
|
47135
|
+
},
|
|
47136
|
+
propagatedEvent: makeScorerPropagatedEvent(rootExport || void 0),
|
|
47137
|
+
event: { input: scorerArgs(record) }
|
|
47138
|
+
}
|
|
47139
|
+
);
|
|
47140
|
+
if (prepared.scores) root.log({ scores: prepared.scores });
|
|
47141
|
+
record.loggedScores[name] = true;
|
|
47142
|
+
} catch (error) {
|
|
47143
|
+
logError(root, error);
|
|
47144
|
+
throw error;
|
|
47145
|
+
} finally {
|
|
47146
|
+
root.end();
|
|
47147
|
+
}
|
|
47148
|
+
}
|
|
47149
|
+
async function evaluateAndLogClassification(definition, state, record, name, classifier, experiment) {
|
|
47150
|
+
const root = resumeCaseRoot(definition, record, experiment);
|
|
47151
|
+
try {
|
|
47152
|
+
const rootExport = await root.export();
|
|
47153
|
+
const prepared = await root.traced(
|
|
47154
|
+
async (span) => {
|
|
47155
|
+
const value = await classifier(scorerArgs(record));
|
|
47156
|
+
record.classifications[name] = assertJsonValue(
|
|
47157
|
+
value,
|
|
47158
|
+
`classifier ${name} output`
|
|
47159
|
+
);
|
|
47160
|
+
const result = _internalPrepareEvaluatorClassification(value, name);
|
|
47161
|
+
if (result.results !== null) {
|
|
47162
|
+
span.log({ output: result.output, metadata: result.metadata });
|
|
47163
|
+
}
|
|
47164
|
+
return result;
|
|
47165
|
+
},
|
|
47166
|
+
{
|
|
47167
|
+
name,
|
|
47168
|
+
spanId: deterministicId(
|
|
47169
|
+
`${state.runId}:${record.id}:classification:${name}`
|
|
47170
|
+
),
|
|
47171
|
+
spanAttributes: {
|
|
47172
|
+
type: "classifier" /* CLASSIFIER */,
|
|
47173
|
+
purpose: "scorer"
|
|
47174
|
+
},
|
|
47175
|
+
propagatedEvent: makeScorerPropagatedEvent(rootExport || void 0),
|
|
47176
|
+
event: { input: scorerArgs(record) }
|
|
47177
|
+
}
|
|
47178
|
+
);
|
|
47179
|
+
if (prepared.classifications) {
|
|
47180
|
+
root.log({ classifications: prepared.classifications });
|
|
47181
|
+
}
|
|
47182
|
+
record.loggedClassifications[name] = true;
|
|
47183
|
+
} catch (error) {
|
|
47184
|
+
logError(root, error);
|
|
47185
|
+
throw error;
|
|
47186
|
+
} finally {
|
|
47187
|
+
root.end();
|
|
47188
|
+
}
|
|
47189
|
+
}
|
|
47190
|
+
async function ensureBatches(definition, state, store, key, kind, scorerName2) {
|
|
47191
|
+
const processor = processorForStage(definition, kind, scorerName2);
|
|
47192
|
+
const plans = plannedBatches(
|
|
47193
|
+
definition,
|
|
47194
|
+
state.runId,
|
|
47195
|
+
state.cases.map(({ id }) => id)
|
|
47196
|
+
);
|
|
47197
|
+
const casesById = new Map(state.cases.map((record) => [record.id, record]));
|
|
47198
|
+
for (const plan of plans) {
|
|
47199
|
+
if (plan.kind !== kind || plan.scorerName !== scorerName2) continue;
|
|
47200
|
+
if (state.batches.some(({ id }) => id === plan.id)) continue;
|
|
47201
|
+
const records = plan.itemIds.map((id) => casesById.get(id));
|
|
47202
|
+
const ready = records.every(
|
|
47203
|
+
(record) => kind === "task" ? !record.taskComplete : !Object.hasOwn(record.scores, scorerName2)
|
|
47204
|
+
);
|
|
47205
|
+
if (!ready) continue;
|
|
47206
|
+
const batchId = plan.id;
|
|
47207
|
+
const claim = await store.getOrSet(
|
|
47208
|
+
claimRecordKey(key, "batch", batchId),
|
|
47209
|
+
encoder.encode(batchId)
|
|
47210
|
+
);
|
|
47211
|
+
if (!claim.created) continue;
|
|
47212
|
+
const context = { runId: state.runId, batchId };
|
|
47213
|
+
const items = records.map(
|
|
47214
|
+
(record) => kind === "task" ? taskBatchItem(record, state.parameters) : scorerBatchItem(record)
|
|
47215
|
+
);
|
|
47216
|
+
const submissionData = assertJsonValue(
|
|
47217
|
+
await processor.submit(items, context),
|
|
47218
|
+
`submission data for batch ${batchId}`
|
|
47219
|
+
);
|
|
47220
|
+
const externalId = processor.completion.mode === "webhook" ? processor.completion.getExternalId(submissionData, context) : void 0;
|
|
47221
|
+
if (externalId !== void 0 && !externalId.trim()) {
|
|
47222
|
+
throw new Error(`Batch ${batchId} produced an empty externalId`);
|
|
47223
|
+
}
|
|
47224
|
+
const batch = {
|
|
47225
|
+
id: batchId,
|
|
47226
|
+
kind,
|
|
47227
|
+
scorerName: scorerName2,
|
|
47228
|
+
itemIds: records.map((record) => record.id),
|
|
47229
|
+
submissionData,
|
|
47230
|
+
externalId,
|
|
47231
|
+
status: "submitted"
|
|
47232
|
+
};
|
|
47233
|
+
state.batches.push(batch);
|
|
47234
|
+
await writeBatchRecords(store, key, [batch]);
|
|
47235
|
+
}
|
|
47236
|
+
}
|
|
47237
|
+
async function collectBatch(definition, state, batch) {
|
|
47238
|
+
const processor = processorForStage(definition, batch.kind, batch.scorerName);
|
|
47239
|
+
const context = { runId: state.runId, batchId: batch.id };
|
|
47240
|
+
const results = await processor.collect(batch.submissionData, context);
|
|
47241
|
+
if (!Array.isArray(results)) {
|
|
47242
|
+
throw new Error(`collect for batch ${batch.id} must return an array`);
|
|
47243
|
+
}
|
|
47244
|
+
const expectedIds = new Set(batch.itemIds);
|
|
47245
|
+
const seen = /* @__PURE__ */ new Set();
|
|
47246
|
+
const records = [];
|
|
47247
|
+
for (const result of results) {
|
|
47248
|
+
const id = resultItemId(result);
|
|
47249
|
+
if (!expectedIds.has(id)) {
|
|
47250
|
+
throw new Error(`Batch ${batch.id} returned unknown item ${id}`);
|
|
47251
|
+
}
|
|
47252
|
+
if (seen.has(id)) {
|
|
47253
|
+
throw new Error(`Batch ${batch.id} returned item ${id} more than once`);
|
|
47254
|
+
}
|
|
47255
|
+
seen.add(id);
|
|
47256
|
+
const record = state.cases.find((candidate) => candidate.id === id);
|
|
47257
|
+
records.push(record);
|
|
47258
|
+
if (batch.kind === "task") {
|
|
47259
|
+
record.output = assertJsonValue(
|
|
47260
|
+
result.output,
|
|
47261
|
+
`task output for item ${id}`
|
|
47262
|
+
);
|
|
47263
|
+
if ("metadata" in result && result.metadata !== void 0) {
|
|
47264
|
+
record.metadata = assertJsonValue(
|
|
47265
|
+
{
|
|
47266
|
+
...record.metadata,
|
|
47267
|
+
...result.metadata
|
|
47268
|
+
},
|
|
47269
|
+
`metadata for ${id}`
|
|
47270
|
+
);
|
|
47271
|
+
}
|
|
47272
|
+
if ("tags" in result && result.tags !== void 0)
|
|
47273
|
+
record.tags = result.tags;
|
|
47274
|
+
record.taskComplete = true;
|
|
47275
|
+
} else {
|
|
47276
|
+
record.scores[batch.scorerName] = assertJsonValue(
|
|
47277
|
+
result.score,
|
|
47278
|
+
`score output for item ${id}`
|
|
47279
|
+
);
|
|
47280
|
+
}
|
|
47281
|
+
}
|
|
47282
|
+
const missing = batch.itemIds.filter((id) => !seen.has(id));
|
|
47283
|
+
if (missing.length > 0) {
|
|
47284
|
+
throw new Error(
|
|
47285
|
+
`Batch ${batch.id} did not return results for: ${missing.join(", ")}`
|
|
47286
|
+
);
|
|
47287
|
+
}
|
|
47288
|
+
return records;
|
|
47289
|
+
}
|
|
47290
|
+
function processorForStage(definition, kind, scorerName2) {
|
|
47291
|
+
if (kind === "task") {
|
|
47292
|
+
if (!isBatchTask(definition.evaluator.task)) {
|
|
47293
|
+
throw new Error("Definition no longer contains the batch task");
|
|
47294
|
+
}
|
|
47295
|
+
return definition.evaluator.task.processor;
|
|
47296
|
+
}
|
|
47297
|
+
const scorer = resolveScorers(definition.evaluator.scores ?? []).find(
|
|
47298
|
+
({ name }) => name === scorerName2
|
|
47299
|
+
)?.scorer;
|
|
47300
|
+
if (!isBatchScorer(scorer)) {
|
|
47301
|
+
throw new Error(`Definition no longer contains scorer ${scorerName2}`);
|
|
47302
|
+
}
|
|
47303
|
+
return scorer.processor;
|
|
47304
|
+
}
|
|
47305
|
+
async function materializeCases(definition, data, experiment) {
|
|
47306
|
+
const evaluator = definition.evaluator;
|
|
47307
|
+
const iterable = await _internalResolveEvaluatorData(
|
|
47308
|
+
{
|
|
47309
|
+
data,
|
|
47310
|
+
projectName: definition.projectName,
|
|
47311
|
+
projectId: evaluator.projectId,
|
|
47312
|
+
state: evaluator.state
|
|
47313
|
+
},
|
|
47314
|
+
experiment
|
|
47315
|
+
);
|
|
47316
|
+
const records = [];
|
|
47317
|
+
const seen = /* @__PURE__ */ new Set();
|
|
47318
|
+
for await (const datum of iterable) {
|
|
47319
|
+
const caseId = datum.id ?? datum.upsert_id ?? (evaluator.caseId ? await evaluator.caseId(datum) : void 0);
|
|
47320
|
+
if (!caseId) {
|
|
47321
|
+
throw new Error(
|
|
47322
|
+
"Every durable eval case requires id, upsert_id, or caseId"
|
|
47323
|
+
);
|
|
47324
|
+
}
|
|
47325
|
+
if (seen.has(caseId))
|
|
47326
|
+
throw new Error(`Duplicate durable eval case id: ${caseId}`);
|
|
47327
|
+
seen.add(caseId);
|
|
47328
|
+
const trialCount = datum.trialCount ?? evaluator.trialCount ?? 1;
|
|
47329
|
+
if (!Number.isInteger(trialCount) || trialCount < 1) {
|
|
47330
|
+
throw new Error(`Invalid trialCount for durable eval case ${caseId}`);
|
|
47331
|
+
}
|
|
47332
|
+
for (let trialIndex = 0; trialIndex < trialCount; trialIndex++) {
|
|
47333
|
+
records.push({
|
|
47334
|
+
id: `${caseId}:trial:${trialIndex}`,
|
|
47335
|
+
caseId,
|
|
47336
|
+
trialIndex,
|
|
47337
|
+
datum: assertJsonValue(datum, `case ${caseId}`),
|
|
47338
|
+
metadata: assertJsonValue(
|
|
47339
|
+
"metadata" in datum ? datum.metadata : {},
|
|
47340
|
+
`metadata for ${caseId}`
|
|
47341
|
+
),
|
|
47342
|
+
tags: datum.tags,
|
|
47343
|
+
taskComplete: false,
|
|
47344
|
+
taskLogged: false,
|
|
47345
|
+
scores: /* @__PURE__ */ Object.create(null),
|
|
47346
|
+
loggedScores: /* @__PURE__ */ Object.create(null),
|
|
47347
|
+
classifications: /* @__PURE__ */ Object.create(null),
|
|
47348
|
+
loggedClassifications: /* @__PURE__ */ Object.create(null)
|
|
47349
|
+
});
|
|
47350
|
+
}
|
|
47351
|
+
}
|
|
47352
|
+
return records;
|
|
47353
|
+
}
|
|
47354
|
+
function taskBatchItem(record, parameters) {
|
|
47355
|
+
const datum = record.datum;
|
|
47356
|
+
return {
|
|
47357
|
+
id: record.id,
|
|
47358
|
+
input: datum.input,
|
|
47359
|
+
expected: "expected" in datum ? datum.expected : void 0,
|
|
47360
|
+
metadata: record.metadata,
|
|
47361
|
+
tags: record.tags,
|
|
47362
|
+
parameters,
|
|
47363
|
+
trialIndex: record.trialIndex
|
|
47364
|
+
};
|
|
47365
|
+
}
|
|
47366
|
+
function scorerBatchItem(record) {
|
|
47367
|
+
const datum = record.datum;
|
|
47368
|
+
return {
|
|
47369
|
+
id: record.id,
|
|
47370
|
+
input: datum.input,
|
|
47371
|
+
output: record.output,
|
|
47372
|
+
expected: "expected" in datum ? datum.expected : void 0,
|
|
47373
|
+
metadata: record.metadata,
|
|
47374
|
+
tags: record.tags,
|
|
47375
|
+
trialIndex: record.trialIndex
|
|
47376
|
+
};
|
|
47377
|
+
}
|
|
47378
|
+
async function finishExperiment(definition, state, experiment) {
|
|
47379
|
+
const scorerNames = resolveScorers(definition.evaluator.scores ?? []).map(
|
|
47380
|
+
({ name }) => name
|
|
47381
|
+
);
|
|
47382
|
+
const results = state.cases.map((record) => {
|
|
47383
|
+
const datum = record.datum;
|
|
47384
|
+
const scores = Object.fromEntries(
|
|
47385
|
+
scorerNames.flatMap(
|
|
47386
|
+
(name) => Object.entries(
|
|
47387
|
+
_internalPrepareEvaluatorScore(
|
|
47388
|
+
record.scores[name],
|
|
47389
|
+
name
|
|
47390
|
+
).scores ?? {}
|
|
47391
|
+
)
|
|
47392
|
+
)
|
|
47393
|
+
);
|
|
47394
|
+
const classifications = Object.fromEntries(
|
|
47395
|
+
Object.entries(record.classifications).flatMap(
|
|
47396
|
+
([name, value]) => Object.entries(
|
|
47397
|
+
_internalPrepareEvaluatorClassification(value, name).classifications ?? {}
|
|
47398
|
+
)
|
|
47399
|
+
)
|
|
47400
|
+
);
|
|
47401
|
+
return {
|
|
47402
|
+
...datum,
|
|
47403
|
+
output: record.output,
|
|
47404
|
+
metadata: record.metadata,
|
|
47405
|
+
tags: record.tags,
|
|
47406
|
+
scores,
|
|
47407
|
+
error: void 0,
|
|
47408
|
+
...Object.keys(classifications).length > 0 ? { classifications } : {}
|
|
47409
|
+
};
|
|
47410
|
+
});
|
|
47411
|
+
if (!experiment) {
|
|
47412
|
+
return buildLocalSummary(
|
|
47413
|
+
{
|
|
47414
|
+
...definition.evaluator,
|
|
47415
|
+
projectName: definition.projectName,
|
|
47416
|
+
evalName: state.experimentName
|
|
47417
|
+
},
|
|
47418
|
+
results
|
|
47419
|
+
);
|
|
47420
|
+
}
|
|
47421
|
+
await experiment.flush();
|
|
47422
|
+
let comparisonExperimentId = definition.evaluator.baseExperimentId;
|
|
47423
|
+
if (!comparisonExperimentId) {
|
|
47424
|
+
try {
|
|
47425
|
+
comparisonExperimentId = await experiment._getBaseExperimentId();
|
|
47426
|
+
} catch {
|
|
47427
|
+
comparisonExperimentId = void 0;
|
|
47428
|
+
}
|
|
47429
|
+
}
|
|
47430
|
+
return await experiment.summarize({
|
|
47431
|
+
summarizeScores: definition.evaluator.summarizeScores,
|
|
47432
|
+
...comparisonExperimentId ? { comparisonExperimentId } : {}
|
|
47433
|
+
});
|
|
47434
|
+
}
|
|
47435
|
+
function resolveScorers(scorers) {
|
|
47436
|
+
return scorers.map((scorer, index) => ({
|
|
47437
|
+
name: isBatchScorer(scorer) ? scorer.name : scorer.name || `scorer_${index}`,
|
|
47438
|
+
scorer
|
|
47439
|
+
}));
|
|
47440
|
+
}
|
|
47441
|
+
function runKey(projectName, evalName, runId) {
|
|
47442
|
+
return `durable-eval/v1/runs/${contentVersion(encoder.encode(`${projectName}\0${evalName}\0${runId}`))}`;
|
|
47443
|
+
}
|
|
47444
|
+
function encodedKeyPart(value) {
|
|
47445
|
+
return uint8ArrayToBase64(encoder.encode(value)).replaceAll("+", "-").replaceAll("/", "_").replace(/=+$/, "");
|
|
47446
|
+
}
|
|
47447
|
+
function caseRecordKey(key, caseId, kind, ...names) {
|
|
47448
|
+
const suffix = names.map(encodedKeyPart).join("/");
|
|
47449
|
+
return `${key}/cases/${encodedKeyPart(caseId)}/${kind}${suffix ? `/${suffix}` : ""}`;
|
|
47450
|
+
}
|
|
47451
|
+
function batchRecordKey(key, batchId) {
|
|
47452
|
+
return `${key}/batches/${encodedKeyPart(batchId)}`;
|
|
47453
|
+
}
|
|
47454
|
+
function claimRecordKey(key, kind, ...parts) {
|
|
47455
|
+
const identity = stableStringify([kind, parts]);
|
|
47456
|
+
return `${key}/claims/${contentVersion(encoder.encode(identity))}`;
|
|
47457
|
+
}
|
|
47458
|
+
async function claimAction(store, key, kind, ...parts) {
|
|
47459
|
+
return (await store.getOrSet(
|
|
47460
|
+
claimRecordKey(key, kind, ...parts),
|
|
47461
|
+
encoder.encode("claimed")
|
|
47462
|
+
)).created;
|
|
47463
|
+
}
|
|
47464
|
+
function plannedBatches(definition, runId, caseIds) {
|
|
47465
|
+
const stages = [];
|
|
47466
|
+
if (isBatchTask(definition.evaluator.task)) stages.push({ kind: "task" });
|
|
47467
|
+
for (const { name, scorer } of resolveScorers(
|
|
47468
|
+
definition.evaluator.scores ?? []
|
|
47469
|
+
)) {
|
|
47470
|
+
if (isBatchScorer(scorer)) {
|
|
47471
|
+
stages.push({ kind: "score", scorerName: name });
|
|
47472
|
+
}
|
|
47473
|
+
}
|
|
47474
|
+
const plans = [];
|
|
47475
|
+
for (const { kind, scorerName: scorerName2 } of stages) {
|
|
47476
|
+
const batchSize = processorForStage(definition, kind, scorerName2).batchSize ?? DEFAULT_BATCH_SIZE;
|
|
47477
|
+
if (!Number.isInteger(batchSize) || batchSize < 1) {
|
|
47478
|
+
throw new Error(
|
|
47479
|
+
`Invalid batchSize for ${scorerName2 ?? "task"}: ${batchSize}`
|
|
47480
|
+
);
|
|
47481
|
+
}
|
|
47482
|
+
for (let offset = 0; offset < caseIds.length; offset += batchSize) {
|
|
47483
|
+
const itemIds = caseIds.slice(offset, offset + batchSize);
|
|
47484
|
+
plans.push({
|
|
47485
|
+
id: deterministicId(
|
|
47486
|
+
stableStringify([runId, kind, scorerName2, itemIds])
|
|
47487
|
+
),
|
|
47488
|
+
kind,
|
|
47489
|
+
scorerName: scorerName2,
|
|
47490
|
+
itemIds
|
|
47491
|
+
});
|
|
47492
|
+
}
|
|
47493
|
+
}
|
|
47494
|
+
return plans;
|
|
47495
|
+
}
|
|
47496
|
+
async function readCaseRecord(definition, store, key, id) {
|
|
47497
|
+
const scorers = resolveScorers(definition.evaluator.scores ?? []);
|
|
47498
|
+
const classifiers = (definition.evaluator.classifiers ?? []).map(
|
|
47499
|
+
classifierName
|
|
47500
|
+
);
|
|
47501
|
+
const [
|
|
47502
|
+
base,
|
|
47503
|
+
task,
|
|
47504
|
+
taskLog,
|
|
47505
|
+
scoreValues,
|
|
47506
|
+
scoreLogValues,
|
|
47507
|
+
classificationValues,
|
|
47508
|
+
classificationLogValues
|
|
47509
|
+
] = await Promise.all([
|
|
47510
|
+
readJson(store, caseRecordKey(key, id, "base")),
|
|
47511
|
+
readJson(store, caseRecordKey(key, id, "task")),
|
|
47512
|
+
readJson(store, caseRecordKey(key, id, "task-log")),
|
|
47513
|
+
Promise.all(
|
|
47514
|
+
scorers.map(async ({ name }) => ({
|
|
47515
|
+
name,
|
|
47516
|
+
value: await readJson(
|
|
47517
|
+
store,
|
|
47518
|
+
caseRecordKey(key, id, "score", name)
|
|
47519
|
+
)
|
|
47520
|
+
}))
|
|
47521
|
+
),
|
|
47522
|
+
Promise.all(
|
|
47523
|
+
scorers.map(async ({ name }) => ({
|
|
47524
|
+
name,
|
|
47525
|
+
value: await readJson(
|
|
47526
|
+
store,
|
|
47527
|
+
caseRecordKey(key, id, "score-log", name)
|
|
47528
|
+
)
|
|
47529
|
+
}))
|
|
47530
|
+
),
|
|
47531
|
+
Promise.all(
|
|
47532
|
+
classifiers.map(async (name) => ({
|
|
47533
|
+
name,
|
|
47534
|
+
value: await readJson(
|
|
47535
|
+
store,
|
|
47536
|
+
caseRecordKey(key, id, "classification", name)
|
|
47537
|
+
)
|
|
47538
|
+
}))
|
|
47539
|
+
),
|
|
47540
|
+
Promise.all(
|
|
47541
|
+
classifiers.map(async (name) => ({
|
|
47542
|
+
name,
|
|
47543
|
+
value: await readJson(
|
|
47544
|
+
store,
|
|
47545
|
+
caseRecordKey(key, id, "classification-log", name)
|
|
47546
|
+
)
|
|
47547
|
+
}))
|
|
47548
|
+
)
|
|
47549
|
+
]);
|
|
47550
|
+
if (!base) throw new Error(`Durable eval case ${id} is missing`);
|
|
47551
|
+
const scores = /* @__PURE__ */ Object.create(null);
|
|
47552
|
+
for (const { name, value } of scoreValues) {
|
|
47553
|
+
if (value !== void 0) scores[name] = value;
|
|
47554
|
+
}
|
|
47555
|
+
const loggedScores = /* @__PURE__ */ Object.create(null);
|
|
47556
|
+
for (const { name, value } of scoreLogValues) {
|
|
47557
|
+
if (value) loggedScores[name] = true;
|
|
47558
|
+
}
|
|
47559
|
+
const classifications = /* @__PURE__ */ Object.create(null);
|
|
47560
|
+
for (const { name, value } of classificationValues) {
|
|
47561
|
+
if (value !== void 0) classifications[name] = value;
|
|
47562
|
+
}
|
|
47563
|
+
const loggedClassifications = /* @__PURE__ */ Object.create(null);
|
|
47564
|
+
for (const { name, value } of classificationLogValues) {
|
|
47565
|
+
if (value) loggedClassifications[name] = true;
|
|
47566
|
+
}
|
|
47567
|
+
return {
|
|
47568
|
+
...base,
|
|
47569
|
+
metadata: task?.metadata ?? base.metadata,
|
|
47570
|
+
tags: task ? task.tags : base.tags,
|
|
47571
|
+
taskComplete: task !== void 0,
|
|
47572
|
+
taskLogged: taskLog !== void 0,
|
|
47573
|
+
output: task?.output,
|
|
47574
|
+
rootSpan: taskLog?.rootSpan,
|
|
47575
|
+
scores,
|
|
47576
|
+
loggedScores,
|
|
47577
|
+
classifications,
|
|
47578
|
+
loggedClassifications
|
|
47579
|
+
};
|
|
47580
|
+
}
|
|
47581
|
+
async function readRunState(definition, store, key) {
|
|
47582
|
+
const record = await readJson(store, key);
|
|
47583
|
+
if (!record) return void 0;
|
|
47584
|
+
const plans = plannedBatches(definition, record.runId, record.caseIds);
|
|
47585
|
+
const [cases, batchRecords] = await Promise.all([
|
|
47586
|
+
Promise.all(
|
|
47587
|
+
record.caseIds.map((id) => readCaseRecord(definition, store, key, id))
|
|
47588
|
+
),
|
|
47589
|
+
Promise.all(
|
|
47590
|
+
plans.map(async ({ id }) => {
|
|
47591
|
+
return readJson(store, batchRecordKey(key, id));
|
|
47592
|
+
})
|
|
47593
|
+
)
|
|
47594
|
+
]);
|
|
47595
|
+
const batches = batchRecords.filter(
|
|
47596
|
+
(value) => value !== void 0
|
|
47597
|
+
);
|
|
47598
|
+
const { caseIds: _caseIds, ...state } = record;
|
|
47599
|
+
return { ...state, cases, batches };
|
|
47600
|
+
}
|
|
47601
|
+
async function writeRunRecord(store, key, state) {
|
|
47602
|
+
const { cases, batches: _batches, ...record } = state;
|
|
47603
|
+
await writeJson(store, key, {
|
|
47604
|
+
...record,
|
|
47605
|
+
caseIds: cases.map(({ id }) => id)
|
|
47606
|
+
});
|
|
47607
|
+
}
|
|
47608
|
+
async function writeCaseBaseRecords(store, key, records) {
|
|
47609
|
+
await Promise.all(
|
|
47610
|
+
records.map(
|
|
47611
|
+
({ id, caseId, trialIndex, datum, metadata, tags }) => writeJson(store, caseRecordKey(key, id, "base"), {
|
|
47612
|
+
id,
|
|
47613
|
+
caseId,
|
|
47614
|
+
trialIndex,
|
|
47615
|
+
datum,
|
|
47616
|
+
metadata,
|
|
47617
|
+
tags
|
|
47618
|
+
})
|
|
47619
|
+
)
|
|
47620
|
+
);
|
|
47621
|
+
}
|
|
47622
|
+
async function writeCaseRecords(store, key, records) {
|
|
47623
|
+
const writes = [];
|
|
47624
|
+
for (const record of records) {
|
|
47625
|
+
if (record.taskComplete) {
|
|
47626
|
+
writes.push(
|
|
47627
|
+
writeJson(store, caseRecordKey(key, record.id, "task"), {
|
|
47628
|
+
output: record.output,
|
|
47629
|
+
metadata: record.metadata,
|
|
47630
|
+
tags: record.tags,
|
|
47631
|
+
taskComplete: true
|
|
47632
|
+
})
|
|
47633
|
+
);
|
|
47634
|
+
}
|
|
47635
|
+
if (record.taskLogged) {
|
|
47636
|
+
writes.push(
|
|
47637
|
+
writeJson(store, caseRecordKey(key, record.id, "task-log"), {
|
|
47638
|
+
rootSpan: record.rootSpan,
|
|
47639
|
+
taskLogged: true
|
|
47640
|
+
})
|
|
47641
|
+
);
|
|
47642
|
+
}
|
|
47643
|
+
for (const [name, value] of Object.entries(record.scores)) {
|
|
47644
|
+
writes.push(
|
|
47645
|
+
writeJson(store, caseRecordKey(key, record.id, "score", name), value)
|
|
47646
|
+
);
|
|
47647
|
+
}
|
|
47648
|
+
for (const name of Object.keys(record.loggedScores)) {
|
|
47649
|
+
writes.push(
|
|
47650
|
+
writeJson(
|
|
47651
|
+
store,
|
|
47652
|
+
caseRecordKey(key, record.id, "score-log", name),
|
|
47653
|
+
true
|
|
47654
|
+
)
|
|
47655
|
+
);
|
|
47656
|
+
}
|
|
47657
|
+
for (const [name, value] of Object.entries(record.classifications)) {
|
|
47658
|
+
writes.push(
|
|
47659
|
+
writeJson(
|
|
47660
|
+
store,
|
|
47661
|
+
caseRecordKey(key, record.id, "classification", name),
|
|
47662
|
+
value
|
|
47663
|
+
)
|
|
47664
|
+
);
|
|
47665
|
+
}
|
|
47666
|
+
for (const name of Object.keys(record.loggedClassifications)) {
|
|
47667
|
+
writes.push(
|
|
47668
|
+
writeJson(
|
|
47669
|
+
store,
|
|
47670
|
+
caseRecordKey(key, record.id, "classification-log", name),
|
|
47671
|
+
true
|
|
47672
|
+
)
|
|
47673
|
+
);
|
|
47674
|
+
}
|
|
47675
|
+
}
|
|
47676
|
+
await Promise.all(writes);
|
|
47677
|
+
}
|
|
47678
|
+
async function writeBatchRecords(store, key, records) {
|
|
47679
|
+
await Promise.all(
|
|
47680
|
+
records.map(
|
|
47681
|
+
(record) => writeJson(store, batchRecordKey(key, record.id), record)
|
|
47682
|
+
)
|
|
47683
|
+
);
|
|
47684
|
+
}
|
|
47685
|
+
function deterministicId(value) {
|
|
47686
|
+
const hex = contentVersion(encoder.encode(value)).padEnd(32, "0").slice(0, 32);
|
|
47687
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-5${hex.slice(13, 16)}-a${hex.slice(17, 20)}-${hex.slice(20, 32)}`;
|
|
47688
|
+
}
|
|
47689
|
+
function contentVersion(value) {
|
|
47690
|
+
if (isomorph_default.hash) return isomorph_default.hash(decoder.decode(value));
|
|
47691
|
+
let hash = 2166136261;
|
|
47692
|
+
for (const byte of value) {
|
|
47693
|
+
hash ^= byte;
|
|
47694
|
+
hash = Math.imul(hash, 16777619);
|
|
47695
|
+
}
|
|
47696
|
+
return (hash >>> 0).toString(16).padStart(8, "0");
|
|
47697
|
+
}
|
|
47698
|
+
async function readJson(store, key) {
|
|
47699
|
+
const value = await store.read(key);
|
|
47700
|
+
return value ? JSON.parse(decoder.decode(value)) : void 0;
|
|
47701
|
+
}
|
|
47702
|
+
async function writeJson(store, key, value) {
|
|
47703
|
+
await store.write(key, encoder.encode(stableStringify(value)));
|
|
47704
|
+
}
|
|
47705
|
+
function stableStringify(value) {
|
|
47706
|
+
return JSON.stringify(value, (_key, nested) => {
|
|
47707
|
+
if (nested && typeof nested === "object" && !Array.isArray(nested)) {
|
|
47708
|
+
return Object.fromEntries(
|
|
47709
|
+
Object.entries(nested).sort(
|
|
47710
|
+
([left], [right]) => left.localeCompare(right)
|
|
47711
|
+
)
|
|
47712
|
+
);
|
|
47713
|
+
}
|
|
47714
|
+
return nested;
|
|
47715
|
+
});
|
|
47716
|
+
}
|
|
47717
|
+
function assertJsonValue(value, label) {
|
|
47718
|
+
try {
|
|
47719
|
+
const serialized = JSON.stringify(value);
|
|
47720
|
+
if (serialized === void 0)
|
|
47721
|
+
throw new Error("value serializes to undefined");
|
|
47722
|
+
return JSON.parse(serialized);
|
|
47723
|
+
} catch (error) {
|
|
47724
|
+
throw new Error(`${label} must be JSON serializable`, { cause: error });
|
|
47725
|
+
}
|
|
47726
|
+
}
|
|
47727
|
+
function resultItemId(value) {
|
|
47728
|
+
if (typeof value !== "object" || value === null || !("id" in value) || typeof value.id !== "string") {
|
|
47729
|
+
throw new Error("Batch results must contain a string id");
|
|
47730
|
+
}
|
|
47731
|
+
return value.id;
|
|
47732
|
+
}
|
|
47733
|
+
function isBatchTask(value) {
|
|
47734
|
+
return typeof value === "object" && value !== null && "kind" in value && value.kind === BATCH_TASK_KIND;
|
|
47735
|
+
}
|
|
47736
|
+
function isBatchScorer(value) {
|
|
47737
|
+
return typeof value === "object" && value !== null && "kind" in value && value.kind === BATCH_SCORER_KIND;
|
|
47738
|
+
}
|
|
47739
|
+
function asError(error) {
|
|
47740
|
+
return error instanceof Error ? error : new Error(String(error));
|
|
47741
|
+
}
|
|
47742
|
+
|
|
45732
47743
|
// src/agent-assertions.ts
|
|
45733
47744
|
function agentAssertionScorer(callback, options = {}) {
|
|
45734
47745
|
return async (args) => {
|
|
@@ -46661,6 +48672,8 @@ export {
|
|
|
46661
48672
|
BRAINTRUST_PARENT_KEY,
|
|
46662
48673
|
BaseAttachment,
|
|
46663
48674
|
BaseExperiment,
|
|
48675
|
+
BatchScorer,
|
|
48676
|
+
BatchTask,
|
|
46664
48677
|
BraintrustLangChainCallbackHandler,
|
|
46665
48678
|
BraintrustMiddleware,
|
|
46666
48679
|
BraintrustObservabilityExporter,
|
|
@@ -46674,6 +48687,8 @@ export {
|
|
|
46674
48687
|
DEFAULT_MAX_REQUEST_SIZE,
|
|
46675
48688
|
Dataset2 as Dataset,
|
|
46676
48689
|
DatasetPipeline,
|
|
48690
|
+
DurableEvalMemoryStore,
|
|
48691
|
+
DurableEvalRedisStore,
|
|
46677
48692
|
ERR_PERMALINK,
|
|
46678
48693
|
Eval,
|
|
46679
48694
|
EvalResultWithSummary,
|
|
@@ -46732,6 +48747,7 @@ export {
|
|
|
46732
48747
|
deepCopyEvent,
|
|
46733
48748
|
exports_exports as default,
|
|
46734
48749
|
defaultErrorScoreHandler,
|
|
48750
|
+
defineDurableEval,
|
|
46735
48751
|
deserializePlainStringAsJSON,
|
|
46736
48752
|
devNullWritableStream,
|
|
46737
48753
|
evaluatorDefinitionSchema,
|
|
@@ -46827,5 +48843,6 @@ export {
|
|
|
46827
48843
|
wrapPiCodingAgentSDK,
|
|
46828
48844
|
wrapStrandsAgentSDK,
|
|
46829
48845
|
wrapTraced,
|
|
46830
|
-
wrapVitest
|
|
48846
|
+
wrapVitest,
|
|
48847
|
+
wrapVoyageAI
|
|
46831
48848
|
};
|