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/workerd.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() {
|
|
@@ -13052,6 +13204,22 @@ function processInputAttachments(input) {
|
|
|
13052
13204
|
};
|
|
13053
13205
|
}
|
|
13054
13206
|
}
|
|
13207
|
+
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;
|
|
13208
|
+
const voyageBase64Value = voyageBase64Key ? node[voyageBase64Key] : void 0;
|
|
13209
|
+
if (voyageBase64Key && typeof voyageBase64Value === "string" && voyageBase64Value.startsWith("data:")) {
|
|
13210
|
+
const mediaType = inferMediaTypeFromDataUrl(
|
|
13211
|
+
voyageBase64Value,
|
|
13212
|
+
node.type === "video_base64" ? "video/mp4" : "image/png"
|
|
13213
|
+
);
|
|
13214
|
+
const filename = `${node.type === "video_base64" ? "video" : "image"}.${getExtensionFromMediaType(mediaType)}`;
|
|
13215
|
+
const attachment = toAttachment(voyageBase64Value, mediaType, filename);
|
|
13216
|
+
if (attachment) {
|
|
13217
|
+
return {
|
|
13218
|
+
...node,
|
|
13219
|
+
[voyageBase64Key]: attachment
|
|
13220
|
+
};
|
|
13221
|
+
}
|
|
13222
|
+
}
|
|
13055
13223
|
if (node.type === "file" && node.file && typeof node.file === "object" && typeof node.file.file_data === "string" && node.file.file_data.startsWith("data:")) {
|
|
13056
13224
|
const mediaType = inferMediaTypeFromDataUrl(
|
|
13057
13225
|
node.file.file_data,
|
|
@@ -14399,12 +14567,30 @@ function logInstrumentationError(context, error) {
|
|
|
14399
14567
|
|
|
14400
14568
|
// src/wrappers/anthropic-tokens-util.ts
|
|
14401
14569
|
function finalizeAnthropicTokens(metrics) {
|
|
14402
|
-
const
|
|
14403
|
-
|
|
14570
|
+
const hasSplitCacheCreationTokens = metrics.prompt_cache_creation_5m_tokens !== void 0 || metrics.prompt_cache_creation_1h_tokens !== void 0;
|
|
14571
|
+
const splitCacheCreationTokens = (metrics.prompt_cache_creation_5m_tokens || 0) + (metrics.prompt_cache_creation_1h_tokens || 0);
|
|
14572
|
+
const aggregateCacheCreationTokens = metrics.prompt_cache_creation_tokens || 0;
|
|
14573
|
+
const effectiveCacheCreationTokens = Math.max(
|
|
14574
|
+
aggregateCacheCreationTokens,
|
|
14575
|
+
splitCacheCreationTokens
|
|
14576
|
+
);
|
|
14577
|
+
const prompt_tokens = (metrics.prompt_tokens || 0) + (metrics.prompt_cached_tokens || 0) + effectiveCacheCreationTokens;
|
|
14578
|
+
const finalized = {
|
|
14404
14579
|
...metrics,
|
|
14405
14580
|
prompt_tokens,
|
|
14406
14581
|
tokens: prompt_tokens + (metrics.completion_tokens || 0)
|
|
14407
14582
|
};
|
|
14583
|
+
if (hasSplitCacheCreationTokens && splitCacheCreationTokens >= aggregateCacheCreationTokens) {
|
|
14584
|
+
delete finalized.prompt_cache_creation_tokens;
|
|
14585
|
+
}
|
|
14586
|
+
return finalized;
|
|
14587
|
+
}
|
|
14588
|
+
function toNumericMetrics(metrics) {
|
|
14589
|
+
return Object.fromEntries(
|
|
14590
|
+
Object.entries(metrics).filter(
|
|
14591
|
+
(entry) => entry[1] !== void 0
|
|
14592
|
+
)
|
|
14593
|
+
);
|
|
14408
14594
|
}
|
|
14409
14595
|
function extractAnthropicCacheTokens(cacheReadTokens = 0, cacheCreationTokens = 0) {
|
|
14410
14596
|
const cacheTokens = {};
|
|
@@ -15010,6 +15196,18 @@ function parseMetricsFromUsage2(usage) {
|
|
|
15010
15196
|
saveIfExistsTo("output_tokens", "completion_tokens");
|
|
15011
15197
|
saveIfExistsTo("cache_read_input_tokens", "prompt_cached_tokens");
|
|
15012
15198
|
saveIfExistsTo("cache_creation_input_tokens", "prompt_cache_creation_tokens");
|
|
15199
|
+
if (isObject(usage.cache_creation)) {
|
|
15200
|
+
const cacheCreation = usage.cache_creation;
|
|
15201
|
+
for (const [source, target] of [
|
|
15202
|
+
["ephemeral_5m_input_tokens", "prompt_cache_creation_5m_tokens"],
|
|
15203
|
+
["ephemeral_1h_input_tokens", "prompt_cache_creation_1h_tokens"]
|
|
15204
|
+
]) {
|
|
15205
|
+
const value = cacheCreation[source];
|
|
15206
|
+
if (typeof value === "number") {
|
|
15207
|
+
metrics[target] = value;
|
|
15208
|
+
}
|
|
15209
|
+
}
|
|
15210
|
+
}
|
|
15013
15211
|
if (isObject(usage.server_tool_use)) {
|
|
15014
15212
|
for (const [name, value] of Object.entries(usage.server_tool_use)) {
|
|
15015
15213
|
if (typeof value === "number") {
|
|
@@ -20308,37 +20506,97 @@ function seedTaskToolUseIdMapping(taskIdToToolUseId, message) {
|
|
|
20308
20506
|
taskIdToToolUseId.set(message.task_id, message.tool_use_id);
|
|
20309
20507
|
}
|
|
20310
20508
|
}
|
|
20311
|
-
function
|
|
20312
|
-
|
|
20313
|
-
|
|
20314
|
-
|
|
20315
|
-
usage = message.message?.usage;
|
|
20316
|
-
} else if (message.type === "result") {
|
|
20317
|
-
usage = message.usage;
|
|
20318
|
-
}
|
|
20509
|
+
function tokenCount(value) {
|
|
20510
|
+
return typeof value === "number" && Number.isFinite(value) && Number.isInteger(value) && value >= 0 ? value : void 0;
|
|
20511
|
+
}
|
|
20512
|
+
function copyUsage(usage) {
|
|
20319
20513
|
if (!usage || typeof usage !== "object") {
|
|
20320
|
-
return
|
|
20514
|
+
return void 0;
|
|
20515
|
+
}
|
|
20516
|
+
const copy = {};
|
|
20517
|
+
for (const key of [
|
|
20518
|
+
"input_tokens",
|
|
20519
|
+
"output_tokens",
|
|
20520
|
+
"cache_read_input_tokens",
|
|
20521
|
+
"cache_creation_input_tokens"
|
|
20522
|
+
]) {
|
|
20523
|
+
const value = tokenCount(Reflect.get(usage, key));
|
|
20524
|
+
if (value !== void 0) {
|
|
20525
|
+
copy[key] = value;
|
|
20526
|
+
}
|
|
20527
|
+
}
|
|
20528
|
+
const cacheCreation = Reflect.get(usage, "cache_creation");
|
|
20529
|
+
if (cacheCreation && typeof cacheCreation === "object") {
|
|
20530
|
+
const cacheCreationCopy = {};
|
|
20531
|
+
for (const key of [
|
|
20532
|
+
"ephemeral_5m_input_tokens",
|
|
20533
|
+
"ephemeral_1h_input_tokens"
|
|
20534
|
+
]) {
|
|
20535
|
+
const value = tokenCount(Reflect.get(cacheCreation, key));
|
|
20536
|
+
if (value !== void 0) {
|
|
20537
|
+
cacheCreationCopy[key] = value;
|
|
20538
|
+
}
|
|
20539
|
+
}
|
|
20540
|
+
if (Object.keys(cacheCreationCopy).length > 0) {
|
|
20541
|
+
copy.cache_creation = cacheCreationCopy;
|
|
20542
|
+
}
|
|
20543
|
+
}
|
|
20544
|
+
return Object.keys(copy).length > 0 ? copy : void 0;
|
|
20545
|
+
}
|
|
20546
|
+
function mergeUsage(base, override) {
|
|
20547
|
+
if (!base || !override) {
|
|
20548
|
+
return override ?? base;
|
|
20549
|
+
}
|
|
20550
|
+
const cacheCreation = base.cache_creation || override.cache_creation ? { ...base.cache_creation, ...override.cache_creation } : void 0;
|
|
20551
|
+
return {
|
|
20552
|
+
...base,
|
|
20553
|
+
...override,
|
|
20554
|
+
...cacheCreation && { cache_creation: cacheCreation }
|
|
20555
|
+
};
|
|
20556
|
+
}
|
|
20557
|
+
function extractUsage(usage, includeOutput) {
|
|
20558
|
+
const metrics = {};
|
|
20559
|
+
if (!usage) {
|
|
20560
|
+
return {};
|
|
20321
20561
|
}
|
|
20322
20562
|
const inputTokens = getNumberProperty(usage, "input_tokens");
|
|
20323
20563
|
if (inputTokens !== void 0) {
|
|
20324
20564
|
metrics.prompt_tokens = inputTokens;
|
|
20325
20565
|
}
|
|
20326
|
-
|
|
20327
|
-
|
|
20328
|
-
|
|
20566
|
+
if (includeOutput) {
|
|
20567
|
+
const outputTokens = getNumberProperty(usage, "output_tokens");
|
|
20568
|
+
if (outputTokens !== void 0) {
|
|
20569
|
+
metrics.completion_tokens = outputTokens;
|
|
20570
|
+
}
|
|
20329
20571
|
}
|
|
20330
20572
|
const cacheReadTokens = getNumberProperty(usage, "cache_read_input_tokens") || 0;
|
|
20331
20573
|
const cacheCreationTokens = getNumberProperty(usage, "cache_creation_input_tokens") || 0;
|
|
20332
|
-
|
|
20333
|
-
|
|
20334
|
-
|
|
20335
|
-
|
|
20336
|
-
|
|
20574
|
+
Object.assign(
|
|
20575
|
+
metrics,
|
|
20576
|
+
extractAnthropicCacheTokens(cacheReadTokens, cacheCreationTokens)
|
|
20577
|
+
);
|
|
20578
|
+
const cacheCreation5mTokens = getNumberProperty(
|
|
20579
|
+
usage.cache_creation,
|
|
20580
|
+
"ephemeral_5m_input_tokens"
|
|
20581
|
+
);
|
|
20582
|
+
const cacheCreation1hTokens = getNumberProperty(
|
|
20583
|
+
usage.cache_creation,
|
|
20584
|
+
"ephemeral_1h_input_tokens"
|
|
20585
|
+
);
|
|
20586
|
+
if (cacheCreation5mTokens !== void 0) {
|
|
20587
|
+
metrics.prompt_cache_creation_5m_tokens = cacheCreation5mTokens;
|
|
20337
20588
|
}
|
|
20338
|
-
if (
|
|
20339
|
-
|
|
20589
|
+
if (cacheCreation1hTokens !== void 0) {
|
|
20590
|
+
metrics.prompt_cache_creation_1h_tokens = cacheCreation1hTokens;
|
|
20340
20591
|
}
|
|
20341
|
-
|
|
20592
|
+
if (Object.keys(metrics).length === 0) {
|
|
20593
|
+
return {};
|
|
20594
|
+
}
|
|
20595
|
+
const finalized = finalizeAnthropicTokens(metrics);
|
|
20596
|
+
if (metrics.completion_tokens === void 0) {
|
|
20597
|
+
delete finalized.tokens;
|
|
20598
|
+
}
|
|
20599
|
+
return toNumericMetrics(finalized);
|
|
20342
20600
|
}
|
|
20343
20601
|
function buildLLMInput(promptMessages, conversationHistory) {
|
|
20344
20602
|
const inputParts = [...promptMessages, ...conversationHistory];
|
|
@@ -20372,16 +20630,16 @@ function buildRootPromptMessages(prompt, capturedPromptMessages) {
|
|
|
20372
20630
|
function formatCapturedMessages(messages) {
|
|
20373
20631
|
return messages.length > 0 ? messages : [];
|
|
20374
20632
|
}
|
|
20375
|
-
async function createLLMSpanForMessages(messages, promptMessages, conversationHistory, options, startTime, parentSpan, existingSpan) {
|
|
20633
|
+
async function createLLMSpanForMessages(messages, promptMessages, conversationHistory, options, startTime, parentSpan, usage, hasFinalOutputUsage, existingSpan) {
|
|
20376
20634
|
if (messages.length === 0) {
|
|
20377
20635
|
return void 0;
|
|
20378
20636
|
}
|
|
20379
20637
|
const lastMessage = messages[messages.length - 1];
|
|
20380
|
-
if (lastMessage.type !== "assistant"
|
|
20638
|
+
if (lastMessage.type !== "assistant") {
|
|
20381
20639
|
return void 0;
|
|
20382
20640
|
}
|
|
20383
|
-
const model = lastMessage.message
|
|
20384
|
-
const
|
|
20641
|
+
const model = lastMessage.message?.model || options.model;
|
|
20642
|
+
const metrics = options.includePartialMessages ? extractUsage(usage, hasFinalOutputUsage) : {};
|
|
20385
20643
|
const input = buildLLMInput(promptMessages, conversationHistory);
|
|
20386
20644
|
const outputs = messages.map(
|
|
20387
20645
|
(m) => m.message?.content && m.message?.role ? { content: m.message.content, role: m.message.role } : void 0
|
|
@@ -20403,8 +20661,8 @@ async function createLLMSpanForMessages(messages, promptMessages, conversationHi
|
|
|
20403
20661
|
);
|
|
20404
20662
|
span.log({
|
|
20405
20663
|
input,
|
|
20406
|
-
metadata: model
|
|
20407
|
-
metrics:
|
|
20664
|
+
metadata: { ...model && { model }, provider: "anthropic" },
|
|
20665
|
+
...Object.keys(metrics).length > 0 ? { metrics } : {},
|
|
20408
20666
|
output: outputs
|
|
20409
20667
|
});
|
|
20410
20668
|
const spanExport = await span.export();
|
|
@@ -20494,11 +20752,17 @@ function prepareLocalToolHandlersInMcpServers(mcpServers) {
|
|
|
20494
20752
|
}
|
|
20495
20753
|
return { hasLocalToolHandlers, localToolHookNames };
|
|
20496
20754
|
}
|
|
20497
|
-
function createToolTracingHooks(resolveParentSpan, activeToolSpans, mcpServers, localToolHookNames, skipLocalToolHooks, subAgentDetailsByToolUseId, subAgentSpans, endedSubAgentSpans) {
|
|
20755
|
+
function createToolTracingHooks(resolveParentSpan, taskIdToToolUseId, toolUseToParent, activeToolSpans, mcpServers, localToolHookNames, skipLocalToolHooks, subAgentDetailsByToolUseId, subAgentSpans, endedSubAgentSpans) {
|
|
20498
20756
|
const preToolUse = async (input, toolUseID) => {
|
|
20499
20757
|
if (input.hook_event_name !== "PreToolUse" || !toolUseID) {
|
|
20500
20758
|
return {};
|
|
20501
20759
|
}
|
|
20760
|
+
if (!toolUseToParent.has(toolUseID) && input.agent_id) {
|
|
20761
|
+
const parentToolUseId = taskIdToToolUseId.get(input.agent_id);
|
|
20762
|
+
if (parentToolUseId) {
|
|
20763
|
+
toolUseToParent.set(toolUseID, parentToolUseId);
|
|
20764
|
+
}
|
|
20765
|
+
}
|
|
20502
20766
|
if (skipLocalToolHooks && (isLocalToolUse(input.tool_name, mcpServers) || localToolHookNames.has(input.tool_name))) {
|
|
20503
20767
|
return {};
|
|
20504
20768
|
}
|
|
@@ -20694,9 +20958,6 @@ function createToolTracingHooks(resolveParentSpan, activeToolSpans, mcpServers,
|
|
|
20694
20958
|
}
|
|
20695
20959
|
const metadata = {
|
|
20696
20960
|
...subAgentDetailsToMetadata(details),
|
|
20697
|
-
...input.agent_transcript_path && {
|
|
20698
|
-
"claude_agent_sdk.agent_transcript_path": input.agent_transcript_path
|
|
20699
|
-
},
|
|
20700
20961
|
"claude_agent_sdk.stop_hook_active": input.stop_hook_active
|
|
20701
20962
|
};
|
|
20702
20963
|
try {
|
|
@@ -20718,7 +20979,7 @@ function createToolTracingHooks(resolveParentSpan, activeToolSpans, mcpServers,
|
|
|
20718
20979
|
subagentStop
|
|
20719
20980
|
};
|
|
20720
20981
|
}
|
|
20721
|
-
function injectTracingHooks(options, resolveParentSpan, activeToolSpans, localToolHookNames, skipLocalToolHooks, subAgentDetailsByToolUseId, subAgentSpans, endedSubAgentSpans) {
|
|
20982
|
+
function injectTracingHooks(options, resolveParentSpan, taskIdToToolUseId, toolUseToParent, activeToolSpans, localToolHookNames, skipLocalToolHooks, subAgentDetailsByToolUseId, subAgentSpans, endedSubAgentSpans) {
|
|
20722
20983
|
const {
|
|
20723
20984
|
preToolUse,
|
|
20724
20985
|
postToolUse,
|
|
@@ -20727,6 +20988,8 @@ function injectTracingHooks(options, resolveParentSpan, activeToolSpans, localTo
|
|
|
20727
20988
|
subagentStop
|
|
20728
20989
|
} = createToolTracingHooks(
|
|
20729
20990
|
resolveParentSpan,
|
|
20991
|
+
taskIdToToolUseId,
|
|
20992
|
+
toolUseToParent,
|
|
20730
20993
|
activeToolSpans,
|
|
20731
20994
|
options.mcpServers,
|
|
20732
20995
|
localToolHookNames,
|
|
@@ -20808,6 +21071,13 @@ async function finalizeCurrentMessageGroup(state) {
|
|
|
20808
21071
|
}
|
|
20809
21072
|
}
|
|
20810
21073
|
const existingLlmSpan = state.activeLlmSpansByParentToolUse.get(parentKey);
|
|
21074
|
+
const lastMessage = state.currentMessages[state.currentMessages.length - 1];
|
|
21075
|
+
const messageId = lastMessage?.message?.id;
|
|
21076
|
+
const usage = state.options.includePartialMessages ? mergeUsage(
|
|
21077
|
+
copyUsage(lastMessage?.message?.usage),
|
|
21078
|
+
messageId ? state.usageByMessageId.get(messageId) : void 0
|
|
21079
|
+
) : void 0;
|
|
21080
|
+
const hasFinalOutputUsage = messageId !== void 0 && state.finalOutputUsageMessageIds.has(messageId);
|
|
20811
21081
|
const llmSpanResult = await createLLMSpanForMessages(
|
|
20812
21082
|
state.currentMessages,
|
|
20813
21083
|
promptMessages,
|
|
@@ -20815,6 +21085,8 @@ async function finalizeCurrentMessageGroup(state) {
|
|
|
20815
21085
|
state.options,
|
|
20816
21086
|
state.currentMessageStartTime,
|
|
20817
21087
|
parentSpan,
|
|
21088
|
+
usage,
|
|
21089
|
+
hasFinalOutputUsage,
|
|
20818
21090
|
existingLlmSpan
|
|
20819
21091
|
);
|
|
20820
21092
|
if (llmSpanResult) {
|
|
@@ -20832,9 +21104,17 @@ async function finalizeCurrentMessageGroup(state) {
|
|
|
20832
21104
|
}
|
|
20833
21105
|
}
|
|
20834
21106
|
state.activeLlmSpansByParentToolUse.delete(parentKey);
|
|
20835
|
-
|
|
20836
|
-
|
|
20837
|
-
state.
|
|
21107
|
+
if (messageId) {
|
|
21108
|
+
state.usageByMessageId.delete(messageId);
|
|
21109
|
+
state.finalOutputUsageMessageIds.delete(messageId);
|
|
21110
|
+
for (const [
|
|
21111
|
+
parent,
|
|
21112
|
+
activeMessageId
|
|
21113
|
+
] of state.activePartialMessageIdByParentKey) {
|
|
21114
|
+
if (activeMessageId === messageId) {
|
|
21115
|
+
state.activePartialMessageIdByParentKey.delete(parent);
|
|
21116
|
+
}
|
|
21117
|
+
}
|
|
20838
21118
|
}
|
|
20839
21119
|
state.currentMessages.length = 0;
|
|
20840
21120
|
}
|
|
@@ -20925,6 +21205,10 @@ async function ensureActiveLlmSpanForParentToolUse(rootSpan, activeLlmSpansByPar
|
|
|
20925
21205
|
);
|
|
20926
21206
|
llmParentSpan = await subAgentSpan.export();
|
|
20927
21207
|
}
|
|
21208
|
+
const racedLlmSpan = activeLlmSpansByParentToolUse.get(parentKey);
|
|
21209
|
+
if (racedLlmSpan) {
|
|
21210
|
+
return racedLlmSpan;
|
|
21211
|
+
}
|
|
20928
21212
|
const llmSpan = startSpan(
|
|
20929
21213
|
withSpanInstrumentationName(
|
|
20930
21214
|
{
|
|
@@ -21044,7 +21328,49 @@ async function maybeHandleTaskLifecycleMessage(state, message) {
|
|
|
21044
21328
|
}
|
|
21045
21329
|
return true;
|
|
21046
21330
|
}
|
|
21331
|
+
function handlePartialUsageMessage(state, message) {
|
|
21332
|
+
if (message.type !== "stream_event") {
|
|
21333
|
+
return false;
|
|
21334
|
+
}
|
|
21335
|
+
const event = message.event;
|
|
21336
|
+
if (!event || typeof event !== "object") {
|
|
21337
|
+
return true;
|
|
21338
|
+
}
|
|
21339
|
+
const parentKey = llmParentKey(message.parent_tool_use_id ?? null);
|
|
21340
|
+
if (event.type === "message_start") {
|
|
21341
|
+
const messageId2 = event.message?.id;
|
|
21342
|
+
const usage = copyUsage(event.message?.usage);
|
|
21343
|
+
if (messageId2) {
|
|
21344
|
+
state.activePartialMessageIdByParentKey.set(parentKey, messageId2);
|
|
21345
|
+
if (usage) {
|
|
21346
|
+
state.usageByMessageId.set(messageId2, usage);
|
|
21347
|
+
}
|
|
21348
|
+
}
|
|
21349
|
+
return true;
|
|
21350
|
+
}
|
|
21351
|
+
const messageId = state.activePartialMessageIdByParentKey.get(parentKey);
|
|
21352
|
+
if (!messageId) {
|
|
21353
|
+
return true;
|
|
21354
|
+
}
|
|
21355
|
+
if (event.type === "message_delta") {
|
|
21356
|
+
const update = copyUsage(event.usage);
|
|
21357
|
+
if (update) {
|
|
21358
|
+
const usage = state.usageByMessageId.get(messageId) ?? {};
|
|
21359
|
+
Object.assign(usage, update);
|
|
21360
|
+
state.usageByMessageId.set(messageId, usage);
|
|
21361
|
+
if (update.output_tokens !== void 0) {
|
|
21362
|
+
state.finalOutputUsageMessageIds.add(messageId);
|
|
21363
|
+
}
|
|
21364
|
+
}
|
|
21365
|
+
} else if (event.type === "message_stop") {
|
|
21366
|
+
state.activePartialMessageIdByParentKey.delete(parentKey);
|
|
21367
|
+
}
|
|
21368
|
+
return true;
|
|
21369
|
+
}
|
|
21047
21370
|
async function handleStreamMessage(state, message) {
|
|
21371
|
+
if (handlePartialUsageMessage(state, message)) {
|
|
21372
|
+
return;
|
|
21373
|
+
}
|
|
21048
21374
|
maybeTrackToolUseContext(state, message);
|
|
21049
21375
|
if (await maybeHandleTaskLifecycleMessage(state, message)) {
|
|
21050
21376
|
return;
|
|
@@ -21091,36 +21417,9 @@ async function handleStreamMessage(state, message) {
|
|
|
21091
21417
|
);
|
|
21092
21418
|
state.currentMessages.push(message);
|
|
21093
21419
|
}
|
|
21094
|
-
if (message.type !== "result"
|
|
21420
|
+
if (message.type !== "result") {
|
|
21095
21421
|
return;
|
|
21096
21422
|
}
|
|
21097
|
-
const finalUsageMetrics = extractUsageFromMessage(message);
|
|
21098
|
-
if (state.currentMessages.length > 0 && finalUsageMetrics.completion_tokens !== void 0) {
|
|
21099
|
-
const lastMessage = state.currentMessages[state.currentMessages.length - 1];
|
|
21100
|
-
if (lastMessage?.message?.usage) {
|
|
21101
|
-
const adjustedTokens = finalUsageMetrics.completion_tokens - state.accumulatedOutputTokens;
|
|
21102
|
-
if (adjustedTokens >= 0) {
|
|
21103
|
-
lastMessage.message.usage.output_tokens = adjustedTokens;
|
|
21104
|
-
}
|
|
21105
|
-
const resultUsage = message.usage;
|
|
21106
|
-
if (resultUsage && typeof resultUsage === "object") {
|
|
21107
|
-
const cacheReadTokens = getNumberProperty(
|
|
21108
|
-
resultUsage,
|
|
21109
|
-
"cache_read_input_tokens"
|
|
21110
|
-
);
|
|
21111
|
-
if (cacheReadTokens !== void 0) {
|
|
21112
|
-
lastMessage.message.usage.cache_read_input_tokens = cacheReadTokens;
|
|
21113
|
-
}
|
|
21114
|
-
const cacheCreationTokens = getNumberProperty(
|
|
21115
|
-
resultUsage,
|
|
21116
|
-
"cache_creation_input_tokens"
|
|
21117
|
-
);
|
|
21118
|
-
if (cacheCreationTokens !== void 0) {
|
|
21119
|
-
lastMessage.message.usage.cache_creation_input_tokens = cacheCreationTokens;
|
|
21120
|
-
}
|
|
21121
|
-
}
|
|
21122
|
-
}
|
|
21123
|
-
}
|
|
21124
21423
|
const metadata = {};
|
|
21125
21424
|
if (message.num_turns !== void 0) {
|
|
21126
21425
|
metadata.num_turns = message.num_turns;
|
|
@@ -21128,8 +21427,12 @@ async function handleStreamMessage(state, message) {
|
|
|
21128
21427
|
if (message.session_id !== void 0) {
|
|
21129
21428
|
metadata.session_id = message.session_id;
|
|
21130
21429
|
}
|
|
21131
|
-
|
|
21132
|
-
|
|
21430
|
+
const metrics = state.options.includePartialMessages ? {} : extractUsage(copyUsage(message.usage), true);
|
|
21431
|
+
if (Object.keys(metadata).length > 0 || Object.keys(metrics).length > 0) {
|
|
21432
|
+
state.span.log({
|
|
21433
|
+
...Object.keys(metadata).length > 0 ? { metadata } : {},
|
|
21434
|
+
...Object.keys(metrics).length > 0 ? { metrics } : {}
|
|
21435
|
+
});
|
|
21133
21436
|
}
|
|
21134
21437
|
}
|
|
21135
21438
|
async function finalizeQuerySpan(state) {
|
|
@@ -21153,6 +21456,9 @@ async function finalizeQuerySpan(state) {
|
|
|
21153
21456
|
llmSpan.end();
|
|
21154
21457
|
}
|
|
21155
21458
|
state.activeLlmSpansByParentToolUse.clear();
|
|
21459
|
+
state.activePartialMessageIdByParentKey.clear();
|
|
21460
|
+
state.finalOutputUsageMessageIds.clear();
|
|
21461
|
+
state.usageByMessageId.clear();
|
|
21156
21462
|
for (const toolSpan of state.activeToolSpans.values()) {
|
|
21157
21463
|
toolSpan.end();
|
|
21158
21464
|
}
|
|
@@ -21277,6 +21583,8 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
21277
21583
|
const optionsWithHooks = injectTracingHooks(
|
|
21278
21584
|
options,
|
|
21279
21585
|
resolveToolUseParentSpan,
|
|
21586
|
+
taskIdToToolUseId,
|
|
21587
|
+
toolUseToParent,
|
|
21280
21588
|
activeToolSpans,
|
|
21281
21589
|
localToolHookNames,
|
|
21282
21590
|
skipLocalToolHooks,
|
|
@@ -21287,8 +21595,8 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
21287
21595
|
params.options = optionsWithHooks;
|
|
21288
21596
|
event.arguments[0] = params;
|
|
21289
21597
|
spans.set(event, {
|
|
21290
|
-
accumulatedOutputTokens: 0,
|
|
21291
21598
|
activeLlmSpansByParentToolUse,
|
|
21599
|
+
activePartialMessageIdByParentKey: /* @__PURE__ */ new Map(),
|
|
21292
21600
|
activeToolSpans,
|
|
21293
21601
|
conversationHistoryByParentKey,
|
|
21294
21602
|
capturedPromptMessages,
|
|
@@ -21296,6 +21604,7 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
21296
21604
|
currentMessageStartTime: startTime,
|
|
21297
21605
|
currentMessages: [],
|
|
21298
21606
|
endedSubAgentSpans,
|
|
21607
|
+
finalOutputUsageMessageIds: /* @__PURE__ */ new Set(),
|
|
21299
21608
|
finalResults: [],
|
|
21300
21609
|
options: optionsWithHooks,
|
|
21301
21610
|
originalPrompt,
|
|
@@ -21311,6 +21620,7 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
21311
21620
|
latestLlmParentBySubAgentToolUse,
|
|
21312
21621
|
latestRootLlmParentRef,
|
|
21313
21622
|
toolUseToParent,
|
|
21623
|
+
usageByMessageId: /* @__PURE__ */ new Map(),
|
|
21314
21624
|
localToolContext
|
|
21315
21625
|
});
|
|
21316
21626
|
},
|
|
@@ -23785,9 +24095,9 @@ function extractEmbedPromptTokenCount(response) {
|
|
|
23785
24095
|
let sawAny = false;
|
|
23786
24096
|
for (const embedding of embeddings) {
|
|
23787
24097
|
const embeddingStats = tryToDict(tryToDict(embedding)?.statistics);
|
|
23788
|
-
const
|
|
23789
|
-
if (typeof
|
|
23790
|
-
total +=
|
|
24098
|
+
const tokenCount2 = embeddingStats?.tokenCount;
|
|
24099
|
+
if (typeof tokenCount2 === "number" && Number.isFinite(tokenCount2)) {
|
|
24100
|
+
total += tokenCount2;
|
|
23791
24101
|
sawAny = true;
|
|
23792
24102
|
}
|
|
23793
24103
|
}
|
|
@@ -30682,7 +30992,7 @@ function getStringProperty2(obj, key) {
|
|
|
30682
30992
|
return typeof value === "string" ? value : void 0;
|
|
30683
30993
|
}
|
|
30684
30994
|
function extractMetricsFromUsage(usage) {
|
|
30685
|
-
const
|
|
30995
|
+
const rawMetrics = {
|
|
30686
30996
|
prompt_tokens: usage.inputTokens,
|
|
30687
30997
|
completion_tokens: usage.outputTokens,
|
|
30688
30998
|
...extractAnthropicCacheTokens(
|
|
@@ -30691,10 +31001,10 @@ function extractMetricsFromUsage(usage) {
|
|
|
30691
31001
|
)
|
|
30692
31002
|
};
|
|
30693
31003
|
if (usage.reasoningTokens !== void 0) {
|
|
30694
|
-
|
|
30695
|
-
|
|
31004
|
+
rawMetrics.completion_reasoning_tokens = usage.reasoningTokens;
|
|
31005
|
+
rawMetrics.reasoning_tokens = usage.reasoningTokens;
|
|
30696
31006
|
}
|
|
30697
|
-
|
|
31007
|
+
const metrics = finalizeAnthropicTokens(rawMetrics);
|
|
30698
31008
|
const metadata = {
|
|
30699
31009
|
model: usage.model
|
|
30700
31010
|
};
|
|
@@ -31633,17 +31943,20 @@ var FlueObserveBridge = class {
|
|
|
31633
31943
|
return;
|
|
31634
31944
|
}
|
|
31635
31945
|
const metadata = {
|
|
31946
|
+
...event.runId ? this.runsById.get(event.runId)?.metadata : {},
|
|
31636
31947
|
...extractEventMetadata(event),
|
|
31637
31948
|
"flue.operation": event.operationKind,
|
|
31638
31949
|
provider: "flue"
|
|
31639
31950
|
};
|
|
31640
31951
|
const parent = this.parentSpanForEvent(event);
|
|
31641
|
-
const
|
|
31952
|
+
const args = {
|
|
31642
31953
|
name: `flue.${event.operationKind}`,
|
|
31643
31954
|
spanAttributes: { type: "task" /* TASK */ },
|
|
31644
31955
|
startTime: eventTime(event.timestamp),
|
|
31645
31956
|
event: { metadata }
|
|
31646
|
-
}
|
|
31957
|
+
};
|
|
31958
|
+
const runSpan = event.runId ? this.runsById.get(event.runId)?.span : void 0;
|
|
31959
|
+
const span = event.operationKind === "prompt" && (!parent || parent === runSpan) ? startFlueRootSpan(args) : startFlueSpan(parent, args);
|
|
31647
31960
|
this.operationsById.set(event.operationId, { metadata, span });
|
|
31648
31961
|
}
|
|
31649
31962
|
handleOperation(event) {
|
|
@@ -31658,6 +31971,11 @@ var FlueObserveBridge = class {
|
|
|
31658
31971
|
...event.isError !== void 0 ? { "flue.is_error": event.isError } : {},
|
|
31659
31972
|
...event.usage ? { "flue.usage": event.usage } : {}
|
|
31660
31973
|
};
|
|
31974
|
+
const input = flueOperationInput(event);
|
|
31975
|
+
if (!state.loggedInput && input !== void 0) {
|
|
31976
|
+
safeLog3(state.span, { input });
|
|
31977
|
+
state.loggedInput = true;
|
|
31978
|
+
}
|
|
31661
31979
|
this.finishPendingChildrenForOperation(event, output);
|
|
31662
31980
|
safeLog3(state.span, {
|
|
31663
31981
|
...event.isError ? { error: toLoggedError(event.errorInfo ?? event.error) } : {},
|
|
@@ -31674,6 +31992,8 @@ var FlueObserveBridge = class {
|
|
|
31674
31992
|
return;
|
|
31675
31993
|
}
|
|
31676
31994
|
const input = flueTurnRequestInput(event);
|
|
31995
|
+
const operation = event.operationId ? this.operationsById.get(event.operationId) : void 0;
|
|
31996
|
+
const turnInput = prepareFlueTurnInput(event, input, operation);
|
|
31677
31997
|
const model = flueTurnRequestModel(event);
|
|
31678
31998
|
const provider = flueTurnRequestProvider(event);
|
|
31679
31999
|
const api = flueTurnRequestApi(event);
|
|
@@ -31686,8 +32006,7 @@ var FlueObserveBridge = class {
|
|
|
31686
32006
|
...provider ? { "flue.provider": provider } : {},
|
|
31687
32007
|
...event.purpose ? { "flue.turn_purpose": event.purpose } : {},
|
|
31688
32008
|
...reasoning ? { reasoning } : {},
|
|
31689
|
-
...
|
|
31690
|
-
...input?.tools ? { tools: input.tools } : {}
|
|
32009
|
+
...turnInput.metadata
|
|
31691
32010
|
};
|
|
31692
32011
|
const parent = this.parentSpanForTurn(event);
|
|
31693
32012
|
const span = startFlueSpan(parent, {
|
|
@@ -31695,11 +32014,14 @@ var FlueObserveBridge = class {
|
|
|
31695
32014
|
spanAttributes: { type: "llm" /* LLM */ },
|
|
31696
32015
|
startTime: eventTime(event.timestamp),
|
|
31697
32016
|
event: {
|
|
31698
|
-
input:
|
|
32017
|
+
input: turnInput.messages,
|
|
31699
32018
|
metadata
|
|
31700
32019
|
}
|
|
31701
32020
|
});
|
|
31702
|
-
this.logOperationInput(
|
|
32021
|
+
this.logOperationInput(
|
|
32022
|
+
event.operationId,
|
|
32023
|
+
latestUserMessageInput(input?.messages)
|
|
32024
|
+
);
|
|
31703
32025
|
this.turnsByKey.set(key, { metadata, span });
|
|
31704
32026
|
}
|
|
31705
32027
|
handleTurn(event) {
|
|
@@ -31946,16 +32268,20 @@ var FlueObserveBridge = class {
|
|
|
31946
32268
|
}
|
|
31947
32269
|
startSyntheticOperation(event) {
|
|
31948
32270
|
const metadata = {
|
|
32271
|
+
...event.runId ? this.runsById.get(event.runId)?.metadata : {},
|
|
31949
32272
|
...extractEventMetadata(event),
|
|
31950
32273
|
"flue.operation": event.operationKind,
|
|
31951
32274
|
provider: "flue"
|
|
31952
32275
|
};
|
|
31953
|
-
const
|
|
32276
|
+
const args = {
|
|
31954
32277
|
name: `flue.${event.operationKind}`,
|
|
31955
32278
|
spanAttributes: { type: "task" /* TASK */ },
|
|
31956
32279
|
startTime: eventTime(event.timestamp),
|
|
31957
32280
|
event: { metadata }
|
|
31958
|
-
}
|
|
32281
|
+
};
|
|
32282
|
+
const parent = this.parentSpanForEvent(event);
|
|
32283
|
+
const runSpan = event.runId ? this.runsById.get(event.runId)?.span : void 0;
|
|
32284
|
+
const span = event.operationKind === "prompt" && (!parent || parent === runSpan) ? startFlueRootSpan(args) : startFlueSpan(parent, args);
|
|
31959
32285
|
return { metadata, span };
|
|
31960
32286
|
}
|
|
31961
32287
|
startSyntheticTurn(event) {
|
|
@@ -32134,6 +32460,71 @@ function flueRunInput(event) {
|
|
|
32134
32460
|
function flueTurnRequestInput(event) {
|
|
32135
32461
|
return event.request?.input ?? event.input;
|
|
32136
32462
|
}
|
|
32463
|
+
function prepareFlueTurnInput(event, input, operation) {
|
|
32464
|
+
const messages = input?.messages;
|
|
32465
|
+
const tracksUserTurn = event.purpose === "agent" && operation?.metadata["flue.operation"] === "prompt" && Array.isArray(messages);
|
|
32466
|
+
if (!tracksUserTurn) {
|
|
32467
|
+
return {
|
|
32468
|
+
messages,
|
|
32469
|
+
metadata: {
|
|
32470
|
+
...input?.systemPrompt ? { "flue.system_prompt": input.systemPrompt } : {},
|
|
32471
|
+
...input?.tools ? { tools: input.tools } : {}
|
|
32472
|
+
}
|
|
32473
|
+
};
|
|
32474
|
+
}
|
|
32475
|
+
const previous = operation.turnInputState;
|
|
32476
|
+
const previousMessageCount = previous?.messageCount ?? 0;
|
|
32477
|
+
const boundaryFingerprint = messages.length > 0 ? fingerprintJsonValue(messages[messages.length - 1]) : void 0;
|
|
32478
|
+
const continuesPreviousInput = previous !== void 0 && messages.length >= previousMessageCount && (previousMessageCount === 0 || previous.boundaryFingerprint !== void 0 && previous.boundaryFingerprint === fingerprintJsonValue(messages[previousMessageCount - 1]));
|
|
32479
|
+
const inputMode = previous === void 0 ? "full" : continuesPreviousInput ? "delta" : "reset";
|
|
32480
|
+
const systemPromptFingerprint = fingerprintJsonValue(input?.systemPrompt);
|
|
32481
|
+
const toolsFingerprint = fingerprintJsonValue(input?.tools);
|
|
32482
|
+
operation.turnInputState = {
|
|
32483
|
+
...boundaryFingerprint !== void 0 ? { boundaryFingerprint } : {},
|
|
32484
|
+
messageCount: messages.length,
|
|
32485
|
+
...systemPromptFingerprint !== void 0 ? { systemPromptFingerprint } : {},
|
|
32486
|
+
...toolsFingerprint !== void 0 ? { toolsFingerprint } : {}
|
|
32487
|
+
};
|
|
32488
|
+
return {
|
|
32489
|
+
messages: continuesPreviousInput ? messages.slice(previousMessageCount) : messages,
|
|
32490
|
+
metadata: {
|
|
32491
|
+
"flue.input_mode": inputMode,
|
|
32492
|
+
...continuesPreviousInput ? { "flue.input_message_offset": previousMessageCount } : {},
|
|
32493
|
+
...input?.systemPrompt && (!continuesPreviousInput || systemPromptFingerprint !== previous?.systemPromptFingerprint) ? { "flue.system_prompt": input.systemPrompt } : {},
|
|
32494
|
+
...input?.tools && (!continuesPreviousInput || toolsFingerprint !== previous?.toolsFingerprint) ? { tools: input.tools } : {}
|
|
32495
|
+
}
|
|
32496
|
+
};
|
|
32497
|
+
}
|
|
32498
|
+
function fingerprintJsonValue(value) {
|
|
32499
|
+
try {
|
|
32500
|
+
const serialized = JSON.stringify(value);
|
|
32501
|
+
if (serialized === void 0) {
|
|
32502
|
+
return void 0;
|
|
32503
|
+
}
|
|
32504
|
+
let hash = 2166136261;
|
|
32505
|
+
for (let i = 0; i < serialized.length; i++) {
|
|
32506
|
+
hash = Math.imul(hash ^ serialized.charCodeAt(i), 16777619);
|
|
32507
|
+
}
|
|
32508
|
+
return `${serialized.length}:${hash >>> 0}`;
|
|
32509
|
+
} catch {
|
|
32510
|
+
return void 0;
|
|
32511
|
+
}
|
|
32512
|
+
}
|
|
32513
|
+
function latestUserMessageInput(messages) {
|
|
32514
|
+
if (!messages) {
|
|
32515
|
+
return void 0;
|
|
32516
|
+
}
|
|
32517
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
32518
|
+
const message = messages[i];
|
|
32519
|
+
if (isObjectLike(message) && Reflect.get(message, "role") === "user") {
|
|
32520
|
+
return [message];
|
|
32521
|
+
}
|
|
32522
|
+
}
|
|
32523
|
+
return void 0;
|
|
32524
|
+
}
|
|
32525
|
+
function flueOperationInput(event) {
|
|
32526
|
+
return typeof event.agentInput?.text === "string" ? [{ content: event.agentInput.text, role: "user" }] : void 0;
|
|
32527
|
+
}
|
|
32137
32528
|
function flueTurnRequestModel(event) {
|
|
32138
32529
|
return event.request?.requestedModel ?? event.request?.model ?? event.model;
|
|
32139
32530
|
}
|
|
@@ -32291,6 +32682,21 @@ function startFlueSpan(parent, args) {
|
|
|
32291
32682
|
withSpanInstrumentationName(args, INSTRUMENTATION_NAMES.FLUE)
|
|
32292
32683
|
);
|
|
32293
32684
|
}
|
|
32685
|
+
function startFlueRootSpan(args) {
|
|
32686
|
+
const state = _internalGetGlobalState();
|
|
32687
|
+
const spanId = state.idGenerator.getSpanId();
|
|
32688
|
+
const rootSpanId = state.idGenerator.shareRootSpanId() ? spanId : state.idGenerator.getTraceId();
|
|
32689
|
+
return withCurrent(
|
|
32690
|
+
NOOP_SPAN,
|
|
32691
|
+
() => startSpan({
|
|
32692
|
+
...withSpanInstrumentationName(args, INSTRUMENTATION_NAMES.FLUE),
|
|
32693
|
+
parentSpanIds: { parentSpanIds: [], rootSpanId },
|
|
32694
|
+
spanId,
|
|
32695
|
+
state
|
|
32696
|
+
}),
|
|
32697
|
+
state
|
|
32698
|
+
);
|
|
32699
|
+
}
|
|
32294
32700
|
function runWithCurrentSpanStore(span, next) {
|
|
32295
32701
|
const state = _internalGetGlobalState();
|
|
32296
32702
|
const contextManager = state?.contextManager;
|
|
@@ -34190,8 +34596,7 @@ function startAgentStream(event, activeChildParents) {
|
|
|
34190
34596
|
...extractAgentMetadata2(agent),
|
|
34191
34597
|
...extractModelMetadata3(model),
|
|
34192
34598
|
"strands.operation": "Agent.stream",
|
|
34193
|
-
provider: extractProvider(model)
|
|
34194
|
-
...event.moduleVersion ? { "strands_agent_sdk.version": event.moduleVersion } : {}
|
|
34599
|
+
provider: extractProvider(model)
|
|
34195
34600
|
};
|
|
34196
34601
|
const parentSpan = agent ? getOnlyChildParent(activeChildParents, agent) : void 0;
|
|
34197
34602
|
const attachmentCache = createStrandsAttachmentCache();
|
|
@@ -34241,8 +34646,7 @@ function startMultiAgentStream(event, operation, activeChildParents) {
|
|
|
34241
34646
|
const metadata = {
|
|
34242
34647
|
"strands.operation": operation,
|
|
34243
34648
|
provider: "strands",
|
|
34244
|
-
...orchestrator?.id ? { "strands.orchestrator.id": orchestrator.id } : {}
|
|
34245
|
-
...event.moduleVersion ? { "strands_agent_sdk.version": event.moduleVersion } : {}
|
|
34649
|
+
...orchestrator?.id ? { "strands.orchestrator.id": orchestrator.id } : {}
|
|
34246
34650
|
};
|
|
34247
34651
|
const parentSpan = orchestrator ? getOnlyChildParent(activeChildParents, orchestrator) : void 0;
|
|
34248
34652
|
const input = processStrandsInputAttachments(event.arguments[0]);
|
|
@@ -35028,6 +35432,320 @@ function logInstrumentationError5(context, error) {
|
|
|
35028
35432
|
debugLogger.debug(`${context}:`, error);
|
|
35029
35433
|
}
|
|
35030
35434
|
|
|
35435
|
+
// src/instrumentation/plugins/voyageai-channels.ts
|
|
35436
|
+
var voyageAIChannels = defineChannels(
|
|
35437
|
+
"voyageai",
|
|
35438
|
+
{
|
|
35439
|
+
embed: channel({
|
|
35440
|
+
channelName: "embed",
|
|
35441
|
+
kind: "async"
|
|
35442
|
+
}),
|
|
35443
|
+
multimodalEmbed: channel({
|
|
35444
|
+
channelName: "multimodalEmbed",
|
|
35445
|
+
kind: "async"
|
|
35446
|
+
}),
|
|
35447
|
+
rerank: channel({
|
|
35448
|
+
channelName: "rerank",
|
|
35449
|
+
kind: "async"
|
|
35450
|
+
}),
|
|
35451
|
+
contextualizedEmbed: channel({
|
|
35452
|
+
channelName: "contextualizedEmbed",
|
|
35453
|
+
kind: "async"
|
|
35454
|
+
})
|
|
35455
|
+
},
|
|
35456
|
+
{ instrumentationName: INSTRUMENTATION_NAMES.VOYAGEAI }
|
|
35457
|
+
);
|
|
35458
|
+
|
|
35459
|
+
// src/instrumentation/plugins/voyageai-plugin.ts
|
|
35460
|
+
var RERANK_METADATA_ALLOWLIST = /* @__PURE__ */ new Set([
|
|
35461
|
+
"model",
|
|
35462
|
+
"returnDocuments",
|
|
35463
|
+
"topK",
|
|
35464
|
+
"truncation"
|
|
35465
|
+
]);
|
|
35466
|
+
var VoyageAIPlugin = class extends BasePlugin {
|
|
35467
|
+
onEnable() {
|
|
35468
|
+
this.unsubscribers.push(
|
|
35469
|
+
interceptVoyageAICall(
|
|
35470
|
+
voyageAIChannels.embed,
|
|
35471
|
+
"voyageai.embed",
|
|
35472
|
+
extractTextEmbeddingInput,
|
|
35473
|
+
summarizeEmbeddingOutput,
|
|
35474
|
+
extractEmbeddingUsageMetrics
|
|
35475
|
+
),
|
|
35476
|
+
interceptVoyageAICall(
|
|
35477
|
+
voyageAIChannels.multimodalEmbed,
|
|
35478
|
+
"voyageai.multimodalEmbed",
|
|
35479
|
+
extractMultimodalEmbeddingInput,
|
|
35480
|
+
summarizeEmbeddingOutput,
|
|
35481
|
+
extractEmbeddingUsageMetrics
|
|
35482
|
+
),
|
|
35483
|
+
interceptVoyageAICall(
|
|
35484
|
+
voyageAIChannels.rerank,
|
|
35485
|
+
"voyageai.rerank",
|
|
35486
|
+
extractRerankInput,
|
|
35487
|
+
summarizeRerankOutput
|
|
35488
|
+
),
|
|
35489
|
+
interceptVoyageAICall(
|
|
35490
|
+
voyageAIChannels.contextualizedEmbed,
|
|
35491
|
+
"voyageai.contextualizedEmbed",
|
|
35492
|
+
extractContextualizedEmbeddingInput,
|
|
35493
|
+
summarizeContextualizedEmbeddingOutput,
|
|
35494
|
+
extractEmbeddingUsageMetrics
|
|
35495
|
+
)
|
|
35496
|
+
);
|
|
35497
|
+
}
|
|
35498
|
+
onDisable() {
|
|
35499
|
+
this.unsubscribers = unsubscribeAll(this.unsubscribers);
|
|
35500
|
+
}
|
|
35501
|
+
};
|
|
35502
|
+
function interceptVoyageAICall(channel2, name, extractInput3, extractOutput2, extractMetrics2 = extractUsageMetrics3) {
|
|
35503
|
+
return channel2.intercept((target, thisArg, args) => {
|
|
35504
|
+
const invokeTarget = () => Reflect.apply(target, thisArg, args);
|
|
35505
|
+
if (isAutoInstrumentationSuppressed()) {
|
|
35506
|
+
return invokeTarget();
|
|
35507
|
+
}
|
|
35508
|
+
let span;
|
|
35509
|
+
try {
|
|
35510
|
+
const { input, metadata } = extractInput3(args);
|
|
35511
|
+
span = startSpan(
|
|
35512
|
+
withSpanInstrumentationName(
|
|
35513
|
+
{
|
|
35514
|
+
event: { input, metadata },
|
|
35515
|
+
name,
|
|
35516
|
+
spanAttributes: { type: "llm" /* LLM */ }
|
|
35517
|
+
},
|
|
35518
|
+
INSTRUMENTATION_NAMES.VOYAGEAI
|
|
35519
|
+
)
|
|
35520
|
+
);
|
|
35521
|
+
} catch (error) {
|
|
35522
|
+
debugLogger.error(`Error starting span for ${name}:`, error);
|
|
35523
|
+
return invokeTarget();
|
|
35524
|
+
}
|
|
35525
|
+
let result;
|
|
35526
|
+
try {
|
|
35527
|
+
result = withCurrent(
|
|
35528
|
+
span,
|
|
35529
|
+
() => runWithAutoInstrumentationSuppressed(invokeTarget)
|
|
35530
|
+
);
|
|
35531
|
+
} catch (error) {
|
|
35532
|
+
finishVoyageAISpan(span, name, () => span.log({ error }));
|
|
35533
|
+
throw error;
|
|
35534
|
+
}
|
|
35535
|
+
void Promise.resolve(result).then(
|
|
35536
|
+
(value) => finishVoyageAISpan(span, name, () => {
|
|
35537
|
+
const metadata = extractResponseMetadata3(value);
|
|
35538
|
+
span.log({
|
|
35539
|
+
output: extractOutput2(value),
|
|
35540
|
+
...metadata ? { metadata } : {},
|
|
35541
|
+
metrics: extractMetrics2(value)
|
|
35542
|
+
});
|
|
35543
|
+
}),
|
|
35544
|
+
(error) => finishVoyageAISpan(span, name, () => span.log({ error }))
|
|
35545
|
+
);
|
|
35546
|
+
return result;
|
|
35547
|
+
});
|
|
35548
|
+
}
|
|
35549
|
+
function finishVoyageAISpan(span, name, log3) {
|
|
35550
|
+
try {
|
|
35551
|
+
log3();
|
|
35552
|
+
} catch (error) {
|
|
35553
|
+
debugLogger.error(`Error logging span for ${name}:`, error);
|
|
35554
|
+
}
|
|
35555
|
+
try {
|
|
35556
|
+
span.end();
|
|
35557
|
+
} catch (error) {
|
|
35558
|
+
debugLogger.error(`Error ending span for ${name}:`, error);
|
|
35559
|
+
}
|
|
35560
|
+
}
|
|
35561
|
+
function getRequestArg2(args) {
|
|
35562
|
+
if (Array.isArray(args)) {
|
|
35563
|
+
return isObject(args[0]) ? args[0] : void 0;
|
|
35564
|
+
}
|
|
35565
|
+
if (!isObject(args)) {
|
|
35566
|
+
return void 0;
|
|
35567
|
+
}
|
|
35568
|
+
const firstArg = Reflect.get(args, "0");
|
|
35569
|
+
return isObject(firstArg) ? firstArg : void 0;
|
|
35570
|
+
}
|
|
35571
|
+
function pickMetadata(request, allowlist) {
|
|
35572
|
+
const metadata = {};
|
|
35573
|
+
if (request) {
|
|
35574
|
+
for (const key of allowlist) {
|
|
35575
|
+
if (!Object.hasOwn(request, key)) {
|
|
35576
|
+
continue;
|
|
35577
|
+
}
|
|
35578
|
+
const value = request[key];
|
|
35579
|
+
if (value !== void 0) {
|
|
35580
|
+
metadata[key] = value;
|
|
35581
|
+
}
|
|
35582
|
+
}
|
|
35583
|
+
}
|
|
35584
|
+
return {
|
|
35585
|
+
...metadata,
|
|
35586
|
+
provider: "voyage"
|
|
35587
|
+
};
|
|
35588
|
+
}
|
|
35589
|
+
function buildEmbeddingInput(inputs, request) {
|
|
35590
|
+
const outputDimensions = request?.outputDimension;
|
|
35591
|
+
return {
|
|
35592
|
+
inputs,
|
|
35593
|
+
...typeof outputDimensions === "number" && Number.isFinite(outputDimensions) ? { output_dimensions: outputDimensions } : {}
|
|
35594
|
+
};
|
|
35595
|
+
}
|
|
35596
|
+
function embeddingMetadata(request) {
|
|
35597
|
+
return {
|
|
35598
|
+
...typeof request?.model === "string" ? { model: request.model } : {},
|
|
35599
|
+
provider: "voyage"
|
|
35600
|
+
};
|
|
35601
|
+
}
|
|
35602
|
+
function extractTextEmbeddingInput(args) {
|
|
35603
|
+
const request = getRequestArg2(args);
|
|
35604
|
+
const rawInput = request?.input;
|
|
35605
|
+
const values = Array.isArray(rawInput) ? rawInput : [rawInput];
|
|
35606
|
+
return {
|
|
35607
|
+
input: buildEmbeddingInput(
|
|
35608
|
+
values.flatMap(
|
|
35609
|
+
(value) => typeof value === "string" ? [{ content: value }] : []
|
|
35610
|
+
),
|
|
35611
|
+
request
|
|
35612
|
+
),
|
|
35613
|
+
metadata: embeddingMetadata(request)
|
|
35614
|
+
};
|
|
35615
|
+
}
|
|
35616
|
+
function extractContextualizedEmbeddingInput(args) {
|
|
35617
|
+
const request = getRequestArg2(args);
|
|
35618
|
+
const rawInputs = request?.inputs;
|
|
35619
|
+
const values = Array.isArray(rawInputs) ? rawInputs.flatMap((value) => Array.isArray(value) ? value : [value]) : [];
|
|
35620
|
+
return {
|
|
35621
|
+
input: buildEmbeddingInput(
|
|
35622
|
+
values.flatMap(
|
|
35623
|
+
(value) => typeof value === "string" ? [{ content: value }] : []
|
|
35624
|
+
),
|
|
35625
|
+
request
|
|
35626
|
+
),
|
|
35627
|
+
metadata: embeddingMetadata(request)
|
|
35628
|
+
};
|
|
35629
|
+
}
|
|
35630
|
+
function extractMultimodalEmbeddingInput(args) {
|
|
35631
|
+
const request = getRequestArg2(args);
|
|
35632
|
+
const rawInputs = request?.inputs;
|
|
35633
|
+
const inputs = Array.isArray(rawInputs) ? rawInputs.map((rawInput) => {
|
|
35634
|
+
const rawContent = isObject(rawInput) ? rawInput.content : void 0;
|
|
35635
|
+
return {
|
|
35636
|
+
content: Array.isArray(rawContent) ? rawContent.flatMap(normalizeMultimodalContentPart) : []
|
|
35637
|
+
};
|
|
35638
|
+
}) : [];
|
|
35639
|
+
const input = buildEmbeddingInput(inputs, request);
|
|
35640
|
+
const processedInput = processInputAttachments(input);
|
|
35641
|
+
return {
|
|
35642
|
+
input: hasInlineEmbeddingMedia(processedInput) ? input : processedInput,
|
|
35643
|
+
metadata: embeddingMetadata(request)
|
|
35644
|
+
};
|
|
35645
|
+
}
|
|
35646
|
+
function normalizeMultimodalContentPart(part) {
|
|
35647
|
+
if (!isObject(part) || typeof part.type !== "string") {
|
|
35648
|
+
return [];
|
|
35649
|
+
}
|
|
35650
|
+
if (part.type === "text") {
|
|
35651
|
+
return typeof part.text === "string" ? [{ type: "text", text: part.text }] : [];
|
|
35652
|
+
}
|
|
35653
|
+
const camelCaseField = {
|
|
35654
|
+
image_base64: "imageBase64",
|
|
35655
|
+
image_url: "imageUrl",
|
|
35656
|
+
video_base64: "videoBase64",
|
|
35657
|
+
video_url: "videoUrl"
|
|
35658
|
+
};
|
|
35659
|
+
const field = camelCaseField[part.type];
|
|
35660
|
+
if (!field) {
|
|
35661
|
+
return [];
|
|
35662
|
+
}
|
|
35663
|
+
const data = typeof part[field] === "string" ? part[field] : part[part.type];
|
|
35664
|
+
if (typeof data !== "string") {
|
|
35665
|
+
return [];
|
|
35666
|
+
}
|
|
35667
|
+
return part.type.startsWith("image_") ? [{ type: "image_url", image_url: { url: data } }] : [{ type: "file", file: { file_data: data } }];
|
|
35668
|
+
}
|
|
35669
|
+
function hasInlineEmbeddingMedia(input) {
|
|
35670
|
+
return input.inputs.some(
|
|
35671
|
+
({ content }) => Array.isArray(content) ? content.some((part) => {
|
|
35672
|
+
const value = part.type === "image_url" ? part.image_url.url : part.type === "file" ? part.file.file_data : void 0;
|
|
35673
|
+
return typeof value === "string" && value.startsWith("data:");
|
|
35674
|
+
}) : false
|
|
35675
|
+
);
|
|
35676
|
+
}
|
|
35677
|
+
function extractRerankInput(args) {
|
|
35678
|
+
const request = getRequestArg2(args);
|
|
35679
|
+
const documents = request?.documents;
|
|
35680
|
+
return {
|
|
35681
|
+
input: {
|
|
35682
|
+
documents,
|
|
35683
|
+
query: request?.query
|
|
35684
|
+
},
|
|
35685
|
+
metadata: {
|
|
35686
|
+
...pickMetadata(request, RERANK_METADATA_ALLOWLIST),
|
|
35687
|
+
...Array.isArray(documents) ? { document_count: documents.length } : {}
|
|
35688
|
+
}
|
|
35689
|
+
};
|
|
35690
|
+
}
|
|
35691
|
+
function extractResponseMetadata3(result) {
|
|
35692
|
+
if (!isObject(result)) {
|
|
35693
|
+
return void 0;
|
|
35694
|
+
}
|
|
35695
|
+
const rawResponse = isObject(result.rawResponse) ? result.rawResponse : void 0;
|
|
35696
|
+
const model = typeof result.model === "string" ? result.model : typeof rawResponse?.model === "string" ? rawResponse.model : void 0;
|
|
35697
|
+
return model ? { model } : void 0;
|
|
35698
|
+
}
|
|
35699
|
+
function summarizeEmbeddingOutput(result) {
|
|
35700
|
+
return {
|
|
35701
|
+
count: isObject(result) && Array.isArray(result.data) ? result.data.length : 0
|
|
35702
|
+
};
|
|
35703
|
+
}
|
|
35704
|
+
function summarizeRerankOutput(result) {
|
|
35705
|
+
if (!isObject(result) || !Array.isArray(result.data)) {
|
|
35706
|
+
return void 0;
|
|
35707
|
+
}
|
|
35708
|
+
return result.data.slice(0, 100).map((item) => ({
|
|
35709
|
+
index: isObject(item) ? item.index : void 0,
|
|
35710
|
+
relevance_score: isObject(item) ? (typeof item.relevanceScore === "number" ? item.relevanceScore : item.relevance_score) ?? null : null
|
|
35711
|
+
}));
|
|
35712
|
+
}
|
|
35713
|
+
function summarizeContextualizedEmbeddingOutput(result) {
|
|
35714
|
+
if (!isObject(result)) {
|
|
35715
|
+
return { count: 0 };
|
|
35716
|
+
}
|
|
35717
|
+
if (Array.isArray(result.results)) {
|
|
35718
|
+
return {
|
|
35719
|
+
count: result.results.reduce(
|
|
35720
|
+
(count, item) => count + (isObject(item) && Array.isArray(item.embeddings) ? item.embeddings.length : 0),
|
|
35721
|
+
0
|
|
35722
|
+
)
|
|
35723
|
+
};
|
|
35724
|
+
}
|
|
35725
|
+
if (!Array.isArray(result.data)) {
|
|
35726
|
+
return { count: 0 };
|
|
35727
|
+
}
|
|
35728
|
+
return {
|
|
35729
|
+
count: result.data.reduce(
|
|
35730
|
+
(count, item) => count + (isObject(item) && Array.isArray(item.data) ? item.data.length : 0),
|
|
35731
|
+
0
|
|
35732
|
+
)
|
|
35733
|
+
};
|
|
35734
|
+
}
|
|
35735
|
+
function extractEmbeddingUsageMetrics(result) {
|
|
35736
|
+
const metrics = extractUsageMetrics3(result);
|
|
35737
|
+
return typeof metrics.tokens === "number" ? { prompt_tokens: metrics.tokens, tokens: metrics.tokens } : {};
|
|
35738
|
+
}
|
|
35739
|
+
function extractUsageMetrics3(result) {
|
|
35740
|
+
if (!isObject(result)) {
|
|
35741
|
+
return {};
|
|
35742
|
+
}
|
|
35743
|
+
const rawResponse = isObject(result.rawResponse) ? result.rawResponse : void 0;
|
|
35744
|
+
const usage = isObject(result.usage) ? result.usage : isObject(rawResponse?.usage) ? rawResponse.usage : void 0;
|
|
35745
|
+
const tokens = typeof result.totalTokens === "number" ? result.totalTokens : usage?.totalTokens ?? usage?.total_tokens;
|
|
35746
|
+
return typeof tokens === "number" && Number.isFinite(tokens) && tokens >= 0 ? { tokens } : {};
|
|
35747
|
+
}
|
|
35748
|
+
|
|
35031
35749
|
// src/instrumentation/plugins/cloudflare-ai-chat-channels.ts
|
|
35032
35750
|
var cloudflareAIChatChannels = defineChannels(
|
|
35033
35751
|
"@cloudflare/ai-chat",
|
|
@@ -35606,6 +36324,7 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
35606
36324
|
langSmithPlugin = null;
|
|
35607
36325
|
piCodingAgentPlugin = null;
|
|
35608
36326
|
strandsAgentSDKPlugin = null;
|
|
36327
|
+
voyageAIPlugin = null;
|
|
35609
36328
|
cloudflareAIChatPlugin = null;
|
|
35610
36329
|
cloudflareAgentsPlugin = null;
|
|
35611
36330
|
constructor(config = {}) {
|
|
@@ -35680,6 +36399,10 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
35680
36399
|
this.coherePlugin = new CoherePlugin();
|
|
35681
36400
|
this.coherePlugin.enable();
|
|
35682
36401
|
}
|
|
36402
|
+
if (integrations.voyageai !== false) {
|
|
36403
|
+
this.voyageAIPlugin = new VoyageAIPlugin();
|
|
36404
|
+
this.voyageAIPlugin.enable();
|
|
36405
|
+
}
|
|
35683
36406
|
if (integrations.groq !== false) {
|
|
35684
36407
|
this.groqPlugin = new GroqPlugin();
|
|
35685
36408
|
this.groqPlugin.enable();
|
|
@@ -35796,6 +36519,10 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
35796
36519
|
this.coherePlugin.disable();
|
|
35797
36520
|
this.coherePlugin = null;
|
|
35798
36521
|
}
|
|
36522
|
+
if (this.voyageAIPlugin) {
|
|
36523
|
+
this.voyageAIPlugin.disable();
|
|
36524
|
+
this.voyageAIPlugin = null;
|
|
36525
|
+
}
|
|
35799
36526
|
if (this.groqPlugin) {
|
|
35800
36527
|
this.groqPlugin.disable();
|
|
35801
36528
|
this.groqPlugin = null;
|
|
@@ -35915,7 +36642,10 @@ var envIntegrationAliases = {
|
|
|
35915
36642
|
"langchain-js": "langchain",
|
|
35916
36643
|
"@langchain": "langchain",
|
|
35917
36644
|
langgraph: "langgraph",
|
|
35918
|
-
langsmith: "langsmith"
|
|
36645
|
+
langsmith: "langsmith",
|
|
36646
|
+
voyage: "voyageai",
|
|
36647
|
+
"voyage-ai": "voyageai",
|
|
36648
|
+
voyageai: "voyageai"
|
|
35919
36649
|
};
|
|
35920
36650
|
function getDefaultInstrumentationIntegrations() {
|
|
35921
36651
|
return {
|
|
@@ -35950,6 +36680,7 @@ function getDefaultInstrumentationIntegrations() {
|
|
|
35950
36680
|
langchain: true,
|
|
35951
36681
|
langgraph: true,
|
|
35952
36682
|
langsmith: true,
|
|
36683
|
+
voyageai: true,
|
|
35953
36684
|
piCodingAgent: true,
|
|
35954
36685
|
strandsAgentSDK: true,
|
|
35955
36686
|
cloudflareAgents: true
|
|
@@ -36113,6 +36844,8 @@ __export(exports_exports, {
|
|
|
36113
36844
|
BRAINTRUST_PARENT_KEY: () => BRAINTRUST_PARENT_KEY,
|
|
36114
36845
|
BaseAttachment: () => BaseAttachment,
|
|
36115
36846
|
BaseExperiment: () => BaseExperiment,
|
|
36847
|
+
BatchScorer: () => BatchScorer,
|
|
36848
|
+
BatchTask: () => BatchTask,
|
|
36116
36849
|
BraintrustLangChainCallbackHandler: () => BraintrustLangChainCallbackHandler,
|
|
36117
36850
|
BraintrustMiddleware: () => BraintrustMiddleware,
|
|
36118
36851
|
BraintrustObservabilityExporter: () => BraintrustObservabilityExporter,
|
|
@@ -36126,6 +36859,8 @@ __export(exports_exports, {
|
|
|
36126
36859
|
DEFAULT_MAX_REQUEST_SIZE: () => DEFAULT_MAX_REQUEST_SIZE,
|
|
36127
36860
|
Dataset: () => Dataset2,
|
|
36128
36861
|
DatasetPipeline: () => DatasetPipeline,
|
|
36862
|
+
DurableEvalMemoryStore: () => DurableEvalMemoryStore,
|
|
36863
|
+
DurableEvalRedisStore: () => DurableEvalRedisStore,
|
|
36129
36864
|
ERR_PERMALINK: () => ERR_PERMALINK,
|
|
36130
36865
|
Eval: () => Eval,
|
|
36131
36866
|
EvalResultWithSummary: () => EvalResultWithSummary,
|
|
@@ -36183,6 +36918,7 @@ __export(exports_exports, {
|
|
|
36183
36918
|
currentSpan: () => currentSpan,
|
|
36184
36919
|
deepCopyEvent: () => deepCopyEvent,
|
|
36185
36920
|
defaultErrorScoreHandler: () => defaultErrorScoreHandler,
|
|
36921
|
+
defineDurableEval: () => defineDurableEval,
|
|
36186
36922
|
deserializePlainStringAsJSON: () => deserializePlainStringAsJSON,
|
|
36187
36923
|
devNullWritableStream: () => devNullWritableStream,
|
|
36188
36924
|
evaluatorDefinitionSchema: () => evaluatorDefinitionSchema,
|
|
@@ -36278,7 +37014,8 @@ __export(exports_exports, {
|
|
|
36278
37014
|
wrapPiCodingAgentSDK: () => wrapPiCodingAgentSDK,
|
|
36279
37015
|
wrapStrandsAgentSDK: () => wrapStrandsAgentSDK,
|
|
36280
37016
|
wrapTraced: () => wrapTraced,
|
|
36281
|
-
wrapVitest: () => wrapVitest
|
|
37017
|
+
wrapVitest: () => wrapVitest,
|
|
37018
|
+
wrapVoyageAI: () => wrapVoyageAI
|
|
36282
37019
|
});
|
|
36283
37020
|
|
|
36284
37021
|
// src/sandbox.ts
|
|
@@ -37539,7 +38276,7 @@ function normalizeUsageMetrics(usage, provider, providerMetadata) {
|
|
|
37539
38276
|
cacheCreationTokens
|
|
37540
38277
|
);
|
|
37541
38278
|
Object.assign(metrics, cacheTokens);
|
|
37542
|
-
|
|
38279
|
+
return toNumericMetrics(finalizeAnthropicTokens(metrics));
|
|
37543
38280
|
}
|
|
37544
38281
|
}
|
|
37545
38282
|
return metrics;
|
|
@@ -41872,6 +42609,84 @@ function wrapRerank3(rerank) {
|
|
|
41872
42609
|
});
|
|
41873
42610
|
}
|
|
41874
42611
|
|
|
42612
|
+
// src/wrappers/voyageai.ts
|
|
42613
|
+
function wrapVoyageAI(client) {
|
|
42614
|
+
if (!isSupportedVoyageAIClient(client)) {
|
|
42615
|
+
console.warn("Unsupported Voyage AI library. Not wrapping.");
|
|
42616
|
+
return client;
|
|
42617
|
+
}
|
|
42618
|
+
return voyageAIProxy(client);
|
|
42619
|
+
}
|
|
42620
|
+
var voyageAIProxyCache = /* @__PURE__ */ new WeakMap();
|
|
42621
|
+
function isObject3(value) {
|
|
42622
|
+
return typeof value === "object" && value !== null;
|
|
42623
|
+
}
|
|
42624
|
+
function hasFunction5(value, name) {
|
|
42625
|
+
return typeof Reflect.get(value, name) === "function";
|
|
42626
|
+
}
|
|
42627
|
+
function isSupportedVoyageAIClient(value) {
|
|
42628
|
+
if (!isObject3(value)) {
|
|
42629
|
+
return false;
|
|
42630
|
+
}
|
|
42631
|
+
return hasFunction5(value, "embed") || hasFunction5(value, "multimodalEmbed") || hasFunction5(value, "rerank") || hasFunction5(value, "contextualizedEmbed");
|
|
42632
|
+
}
|
|
42633
|
+
function voyageAIProxy(client) {
|
|
42634
|
+
const cached = voyageAIProxyCache.get(client);
|
|
42635
|
+
if (cached) {
|
|
42636
|
+
return cached;
|
|
42637
|
+
}
|
|
42638
|
+
const proxy = new Proxy(client, {
|
|
42639
|
+
get(target, prop, receiver) {
|
|
42640
|
+
switch (prop) {
|
|
42641
|
+
case "embed":
|
|
42642
|
+
if (typeof target.embed !== "function") {
|
|
42643
|
+
return target.embed;
|
|
42644
|
+
}
|
|
42645
|
+
return (request, options) => voyageAIChannels.embed.invoke(
|
|
42646
|
+
target.embed,
|
|
42647
|
+
target,
|
|
42648
|
+
[request, options],
|
|
42649
|
+
{}
|
|
42650
|
+
);
|
|
42651
|
+
case "multimodalEmbed":
|
|
42652
|
+
if (typeof target.multimodalEmbed !== "function") {
|
|
42653
|
+
return target.multimodalEmbed;
|
|
42654
|
+
}
|
|
42655
|
+
return (request, options) => voyageAIChannels.multimodalEmbed.invoke(
|
|
42656
|
+
target.multimodalEmbed,
|
|
42657
|
+
target,
|
|
42658
|
+
[request, options],
|
|
42659
|
+
{}
|
|
42660
|
+
);
|
|
42661
|
+
case "rerank":
|
|
42662
|
+
if (typeof target.rerank !== "function") {
|
|
42663
|
+
return target.rerank;
|
|
42664
|
+
}
|
|
42665
|
+
return (request, options) => voyageAIChannels.rerank.invoke(
|
|
42666
|
+
target.rerank,
|
|
42667
|
+
target,
|
|
42668
|
+
[request, options],
|
|
42669
|
+
{}
|
|
42670
|
+
);
|
|
42671
|
+
case "contextualizedEmbed":
|
|
42672
|
+
if (typeof target.contextualizedEmbed !== "function") {
|
|
42673
|
+
return target.contextualizedEmbed;
|
|
42674
|
+
}
|
|
42675
|
+
return (request, options) => voyageAIChannels.contextualizedEmbed.invoke(
|
|
42676
|
+
target.contextualizedEmbed,
|
|
42677
|
+
target,
|
|
42678
|
+
[request, options],
|
|
42679
|
+
{}
|
|
42680
|
+
);
|
|
42681
|
+
default:
|
|
42682
|
+
return Reflect.get(target, prop, receiver);
|
|
42683
|
+
}
|
|
42684
|
+
}
|
|
42685
|
+
});
|
|
42686
|
+
voyageAIProxyCache.set(client, proxy);
|
|
42687
|
+
return proxy;
|
|
42688
|
+
}
|
|
42689
|
+
|
|
41875
42690
|
// src/wrappers/groq.ts
|
|
41876
42691
|
function wrapGroq(groq) {
|
|
41877
42692
|
if (isSupportedGroqClient(groq)) {
|
|
@@ -41883,14 +42698,14 @@ function wrapGroq(groq) {
|
|
|
41883
42698
|
function isRecord6(value) {
|
|
41884
42699
|
return typeof value === "object" && value !== null;
|
|
41885
42700
|
}
|
|
41886
|
-
function
|
|
42701
|
+
function hasFunction6(value, methodName) {
|
|
41887
42702
|
return isRecord6(value) && methodName in value && typeof value[methodName] === "function";
|
|
41888
42703
|
}
|
|
41889
42704
|
function hasChat2(value) {
|
|
41890
|
-
return isRecord6(value) && isRecord6(value.completions) &&
|
|
42705
|
+
return isRecord6(value) && isRecord6(value.completions) && hasFunction6(value.completions, "create");
|
|
41891
42706
|
}
|
|
41892
42707
|
function hasEmbeddings2(value) {
|
|
41893
|
-
return
|
|
42708
|
+
return hasFunction6(value, "create");
|
|
41894
42709
|
}
|
|
41895
42710
|
function isSupportedGroqClient(value) {
|
|
41896
42711
|
return isRecord6(value) && (value.chat !== void 0 && hasChat2(value.chat) || value.embeddings !== void 0 && hasEmbeddings2(value.embeddings));
|
|
@@ -42473,7 +43288,7 @@ async function flushExperimentWithSync(context, config) {
|
|
|
42473
43288
|
// src/wrappers/shared/scorers.ts
|
|
42474
43289
|
async function runScorers(args) {
|
|
42475
43290
|
const { scorers, output, expected, input, metadata, span } = args;
|
|
42476
|
-
const
|
|
43291
|
+
const scorerArgs2 = {
|
|
42477
43292
|
output,
|
|
42478
43293
|
expected,
|
|
42479
43294
|
input,
|
|
@@ -42482,7 +43297,7 @@ async function runScorers(args) {
|
|
|
42482
43297
|
await Promise.all(
|
|
42483
43298
|
scorers.map(async (scorer) => {
|
|
42484
43299
|
try {
|
|
42485
|
-
const result = await scorer(
|
|
43300
|
+
const result = await scorer(scorerArgs2);
|
|
42486
43301
|
const scores = normalizeScores(result);
|
|
42487
43302
|
if (scores.length > 0) {
|
|
42488
43303
|
const accScores = {};
|
|
@@ -44841,6 +45656,26 @@ async function getExperimentParametersRef(parameters) {
|
|
|
44841
45656
|
version: resolvedParameters.version
|
|
44842
45657
|
};
|
|
44843
45658
|
}
|
|
45659
|
+
async function _internalInitEvaluatorExperiment(projectName, evaluator, data, options = {}) {
|
|
45660
|
+
if (options.disabled) return null;
|
|
45661
|
+
const { baseExperiment } = callEvaluatorData(data);
|
|
45662
|
+
const parameters = await getExperimentParametersRef(evaluator.parameters);
|
|
45663
|
+
return initExperiment2(evaluator.state, {
|
|
45664
|
+
...evaluator.projectId ? { projectId: evaluator.projectId } : { project: projectName },
|
|
45665
|
+
experiment: options.experimentName ?? evaluator.experimentName,
|
|
45666
|
+
description: evaluator.description,
|
|
45667
|
+
metadata: evaluator.metadata,
|
|
45668
|
+
tags: evaluator.tags,
|
|
45669
|
+
isPublic: evaluator.isPublic,
|
|
45670
|
+
update: options.update ?? evaluator.update,
|
|
45671
|
+
baseExperiment: evaluator.baseExperimentName ?? baseExperiment,
|
|
45672
|
+
baseExperimentId: evaluator.baseExperimentId,
|
|
45673
|
+
gitMetadataSettings: evaluator.gitMetadataSettings,
|
|
45674
|
+
repoInfo: evaluator.repoInfo,
|
|
45675
|
+
dataset: Dataset2.isDataset(data) ? data : void 0,
|
|
45676
|
+
parameters
|
|
45677
|
+
});
|
|
45678
|
+
}
|
|
44844
45679
|
function callEvaluatorData(data) {
|
|
44845
45680
|
const dataResult = typeof data === "function" ? data() : data;
|
|
44846
45681
|
let baseExperiment = void 0;
|
|
@@ -44858,6 +45693,48 @@ function isAsyncIterable7(value) {
|
|
|
44858
45693
|
function isIterable(value) {
|
|
44859
45694
|
return typeof value === "object" && value !== null && Symbol.iterator in value && typeof value[Symbol.iterator] === "function";
|
|
44860
45695
|
}
|
|
45696
|
+
async function _internalResolveEvaluatorData(evaluator, experiment) {
|
|
45697
|
+
if (typeof evaluator.data === "string") {
|
|
45698
|
+
throw new Error("Unimplemented: string data paths");
|
|
45699
|
+
}
|
|
45700
|
+
let dataResult = typeof evaluator.data === "function" ? evaluator.data() : evaluator.data;
|
|
45701
|
+
if ("_type" in dataResult) {
|
|
45702
|
+
if (dataResult._type !== "BaseExperiment") {
|
|
45703
|
+
throw new Error("Invalid _type");
|
|
45704
|
+
}
|
|
45705
|
+
if (!experiment) {
|
|
45706
|
+
throw new Error(
|
|
45707
|
+
"Cannot use BaseExperiment() without connecting to Braintrust (you most likely set --no-send-logs)"
|
|
45708
|
+
);
|
|
45709
|
+
}
|
|
45710
|
+
let name = dataResult.name;
|
|
45711
|
+
if (isEmpty2(name)) {
|
|
45712
|
+
const baseExperiment = await experiment.fetchBaseExperiment();
|
|
45713
|
+
if (!baseExperiment) {
|
|
45714
|
+
throw new Error("BaseExperiment() failed to fetch base experiment");
|
|
45715
|
+
}
|
|
45716
|
+
name = baseExperiment.name;
|
|
45717
|
+
}
|
|
45718
|
+
dataResult = initExperiment2(evaluator.state, {
|
|
45719
|
+
...evaluator.projectId ? { projectId: evaluator.projectId } : { project: evaluator.projectName },
|
|
45720
|
+
experiment: name,
|
|
45721
|
+
open: true
|
|
45722
|
+
}).asDataset();
|
|
45723
|
+
}
|
|
45724
|
+
const resolvedDataResult = dataResult instanceof Promise ? await dataResult : dataResult;
|
|
45725
|
+
if (isAsyncIterable7(resolvedDataResult)) {
|
|
45726
|
+
return resolvedDataResult;
|
|
45727
|
+
}
|
|
45728
|
+
if (Array.isArray(resolvedDataResult) || isIterable(resolvedDataResult)) {
|
|
45729
|
+
const iterable = resolvedDataResult;
|
|
45730
|
+
return (async function* () {
|
|
45731
|
+
for (const datum of iterable) yield datum;
|
|
45732
|
+
})();
|
|
45733
|
+
}
|
|
45734
|
+
throw new Error(
|
|
45735
|
+
"Evaluator data must be an array, iterable, or async iterable"
|
|
45736
|
+
);
|
|
45737
|
+
}
|
|
44861
45738
|
globalThis._evals = {
|
|
44862
45739
|
functions: [],
|
|
44863
45740
|
prompts: [],
|
|
@@ -44904,25 +45781,13 @@ async function Eval(name, evaluator, reporterOrOpts) {
|
|
|
44904
45781
|
}
|
|
44905
45782
|
const resolvedReporter = options.reporter || defaultReporter;
|
|
44906
45783
|
try {
|
|
44907
|
-
const { data
|
|
44908
|
-
|
|
44909
|
-
|
|
44910
|
-
|
|
44911
|
-
|
|
44912
|
-
|
|
44913
|
-
|
|
44914
|
-
description: evaluator.description,
|
|
44915
|
-
metadata: evaluator.metadata,
|
|
44916
|
-
tags: evaluator.tags,
|
|
44917
|
-
isPublic: evaluator.isPublic,
|
|
44918
|
-
update: evaluator.update,
|
|
44919
|
-
baseExperiment: evaluator.baseExperimentName ?? defaultBaseExperiment,
|
|
44920
|
-
baseExperimentId: evaluator.baseExperimentId,
|
|
44921
|
-
gitMetadataSettings: evaluator.gitMetadataSettings,
|
|
44922
|
-
repoInfo: evaluator.repoInfo,
|
|
44923
|
-
dataset: Dataset2.isDataset(data) ? data : void 0,
|
|
44924
|
-
parameters
|
|
44925
|
-
});
|
|
45784
|
+
const { data } = callEvaluatorData(evaluator.data);
|
|
45785
|
+
const experiment = await _internalInitEvaluatorExperiment(
|
|
45786
|
+
name,
|
|
45787
|
+
evaluator,
|
|
45788
|
+
data,
|
|
45789
|
+
{ disabled: Boolean(options.parent || options.noSendLogs) }
|
|
45790
|
+
);
|
|
44926
45791
|
if (experiment && typeof process !== "undefined" && globalThis.BRAINTRUST_CONTEXT_MANAGER !== void 0) {
|
|
44927
45792
|
await experiment._waitForId();
|
|
44928
45793
|
}
|
|
@@ -45020,19 +45885,74 @@ function scorerName(scorer, scorer_idx) {
|
|
|
45020
45885
|
function classifierName(classifier, classifier_idx) {
|
|
45021
45886
|
return classifier.name || `classifier_${classifier_idx}`;
|
|
45022
45887
|
}
|
|
45888
|
+
async function _internalRunEvaluatorTask(task, datum, trialIndex, parameters, span, reportProgress = () => void 0) {
|
|
45889
|
+
const metadata = {
|
|
45890
|
+
..."metadata" in datum ? datum.metadata : {}
|
|
45891
|
+
};
|
|
45892
|
+
const hooks = {
|
|
45893
|
+
meta(value) {
|
|
45894
|
+
Object.assign(metadata, value);
|
|
45895
|
+
},
|
|
45896
|
+
metadata,
|
|
45897
|
+
expected: "expected" in datum ? datum.expected : void 0,
|
|
45898
|
+
span,
|
|
45899
|
+
parameters,
|
|
45900
|
+
reportProgress,
|
|
45901
|
+
trialIndex,
|
|
45902
|
+
tags: [...datum.tags ?? []]
|
|
45903
|
+
};
|
|
45904
|
+
const output = await task(datum.input, hooks);
|
|
45905
|
+
span.log({ output });
|
|
45906
|
+
return {
|
|
45907
|
+
output,
|
|
45908
|
+
metadata: hooks.metadata,
|
|
45909
|
+
tags: hooks.tags ?? []
|
|
45910
|
+
};
|
|
45911
|
+
}
|
|
45023
45912
|
function buildSpanMetadata(results) {
|
|
45024
|
-
return results.length === 1 ? results[0].metadata :
|
|
45025
|
-
(
|
|
45026
|
-
{}
|
|
45913
|
+
return results.length === 1 ? results[0].metadata : Object.fromEntries(
|
|
45914
|
+
results.map((result) => [result.name, result.metadata])
|
|
45027
45915
|
);
|
|
45028
45916
|
}
|
|
45029
45917
|
function buildSpanScores(results) {
|
|
45030
|
-
const scoresRecord =
|
|
45031
|
-
(
|
|
45032
|
-
{}
|
|
45918
|
+
const scoresRecord = Object.fromEntries(
|
|
45919
|
+
results.map((result) => [result.name, result.score])
|
|
45033
45920
|
);
|
|
45034
45921
|
return { resultMetadata: buildSpanMetadata(results), scoresRecord };
|
|
45035
45922
|
}
|
|
45923
|
+
function _internalPrepareEvaluatorScore(scoreValue, name) {
|
|
45924
|
+
if (scoreValue === null) return { results: null };
|
|
45925
|
+
if (Array.isArray(scoreValue)) {
|
|
45926
|
+
for (const score of scoreValue) {
|
|
45927
|
+
if (!(typeof score === "object" && !isEmpty2(score))) {
|
|
45928
|
+
throw new Error(
|
|
45929
|
+
`When returning an array of scores, each score must be a non-empty object. Got: ${JSON.stringify(score)}`
|
|
45930
|
+
);
|
|
45931
|
+
}
|
|
45932
|
+
}
|
|
45933
|
+
}
|
|
45934
|
+
let results;
|
|
45935
|
+
if (Array.isArray(scoreValue)) {
|
|
45936
|
+
results = scoreValue;
|
|
45937
|
+
} else if (typeof scoreValue === "object" && !isEmpty2(scoreValue)) {
|
|
45938
|
+
results = [scoreValue];
|
|
45939
|
+
} else {
|
|
45940
|
+
results = [{ name, score: scoreValue }];
|
|
45941
|
+
}
|
|
45942
|
+
const { resultMetadata, scoresRecord } = buildSpanScores(results);
|
|
45943
|
+
const fields = (score) => {
|
|
45944
|
+
const { metadata: _metadata, name: _name, ...rest } = score;
|
|
45945
|
+
return rest;
|
|
45946
|
+
};
|
|
45947
|
+
return {
|
|
45948
|
+
results,
|
|
45949
|
+
output: results.length === 1 ? fields(results[0]) : Object.fromEntries(
|
|
45950
|
+
results.map((score) => [score.name ?? name, fields(score)])
|
|
45951
|
+
),
|
|
45952
|
+
metadata: resultMetadata,
|
|
45953
|
+
scores: scoresRecord
|
|
45954
|
+
};
|
|
45955
|
+
}
|
|
45036
45956
|
async function runInScorerSpan(rootSpan, spanName, spanType, propagatedEvent, eventInput, fn) {
|
|
45037
45957
|
try {
|
|
45038
45958
|
const value = await rootSpan.traced(fn, {
|
|
@@ -45077,6 +45997,27 @@ function toClassificationItem(c) {
|
|
|
45077
45997
|
...c.metadata !== void 0 ? { metadata: c.metadata } : {}
|
|
45078
45998
|
};
|
|
45079
45999
|
}
|
|
46000
|
+
function _internalPrepareEvaluatorClassification(value, name) {
|
|
46001
|
+
if (value === null) return { results: null };
|
|
46002
|
+
const results = (Array.isArray(value) ? value : [value]).map(
|
|
46003
|
+
(result) => validateClassificationResult(result, name)
|
|
46004
|
+
);
|
|
46005
|
+
const classifications = /* @__PURE__ */ Object.create(null);
|
|
46006
|
+
for (const result of results) {
|
|
46007
|
+
(classifications[result.name] ??= []).push(toClassificationItem(result));
|
|
46008
|
+
}
|
|
46009
|
+
return {
|
|
46010
|
+
results,
|
|
46011
|
+
output: results.length === 1 ? toClassificationItem(results[0]) : Object.fromEntries(
|
|
46012
|
+
results.map((result) => [
|
|
46013
|
+
result.name,
|
|
46014
|
+
toClassificationItem(result)
|
|
46015
|
+
])
|
|
46016
|
+
),
|
|
46017
|
+
metadata: buildSpanMetadata(results),
|
|
46018
|
+
classifications
|
|
46019
|
+
};
|
|
46020
|
+
}
|
|
45080
46021
|
function logScoringFailures(kind, failures, metadata, rootSpan, state) {
|
|
45081
46022
|
if (!failures.length) return [];
|
|
45082
46023
|
const errorMap = Object.fromEntries(
|
|
@@ -45124,54 +46065,14 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
|
|
|
45124
46065
|
(evaluator.state ?? _internalGetGlobalState())?.spanCache?.start();
|
|
45125
46066
|
}
|
|
45126
46067
|
try {
|
|
45127
|
-
if (typeof evaluator.data === "string") {
|
|
45128
|
-
throw new Error("Unimplemented: string data paths");
|
|
45129
|
-
}
|
|
45130
|
-
let dataResult = typeof evaluator.data === "function" ? evaluator.data() : evaluator.data;
|
|
45131
46068
|
parameters = await validateParameters(
|
|
45132
46069
|
parameters ?? {},
|
|
45133
46070
|
evaluator.parameters
|
|
45134
46071
|
);
|
|
45135
|
-
|
|
45136
|
-
|
|
45137
|
-
|
|
45138
|
-
|
|
45139
|
-
if (!experiment) {
|
|
45140
|
-
throw new Error(
|
|
45141
|
-
"Cannot use BaseExperiment() without connecting to Braintrust (you most likely set --no-send-logs)"
|
|
45142
|
-
);
|
|
45143
|
-
}
|
|
45144
|
-
let name = dataResult.name;
|
|
45145
|
-
if (isEmpty2(name)) {
|
|
45146
|
-
const baseExperiment = await experiment.fetchBaseExperiment();
|
|
45147
|
-
if (!baseExperiment) {
|
|
45148
|
-
throw new Error("BaseExperiment() failed to fetch base experiment");
|
|
45149
|
-
}
|
|
45150
|
-
name = baseExperiment.name;
|
|
45151
|
-
}
|
|
45152
|
-
dataResult = initExperiment2(evaluator.state, {
|
|
45153
|
-
...evaluator.projectId ? { projectId: evaluator.projectId } : { project: evaluator.projectName },
|
|
45154
|
-
experiment: name,
|
|
45155
|
-
open: true
|
|
45156
|
-
}).asDataset();
|
|
45157
|
-
}
|
|
45158
|
-
const resolvedDataResult = dataResult instanceof Promise ? await dataResult : dataResult;
|
|
45159
|
-
const dataIterable = (() => {
|
|
45160
|
-
if (isAsyncIterable7(resolvedDataResult)) {
|
|
45161
|
-
return resolvedDataResult;
|
|
45162
|
-
}
|
|
45163
|
-
if (Array.isArray(resolvedDataResult) || isIterable(resolvedDataResult)) {
|
|
45164
|
-
const iterable = resolvedDataResult;
|
|
45165
|
-
return (async function* () {
|
|
45166
|
-
for (const datum of iterable) {
|
|
45167
|
-
yield datum;
|
|
45168
|
-
}
|
|
45169
|
-
})();
|
|
45170
|
-
}
|
|
45171
|
-
throw new Error(
|
|
45172
|
-
"Evaluator data must be an array, iterable, or async iterable"
|
|
45173
|
-
);
|
|
45174
|
-
})();
|
|
46072
|
+
const dataIterable = await _internalResolveEvaluatorData(
|
|
46073
|
+
evaluator,
|
|
46074
|
+
experiment
|
|
46075
|
+
);
|
|
45175
46076
|
progressReporter.start(evaluator.evalName, 0);
|
|
45176
46077
|
const experimentIdPromise = experiment ? (async () => {
|
|
45177
46078
|
try {
|
|
@@ -45240,57 +46141,45 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
|
|
|
45240
46141
|
ensureSpansFlushed,
|
|
45241
46142
|
state
|
|
45242
46143
|
}) : void 0;
|
|
45243
|
-
let metadata = {
|
|
45244
|
-
..."metadata" in datum ? datum.metadata : {}
|
|
45245
|
-
};
|
|
46144
|
+
let metadata = {};
|
|
45246
46145
|
const expected = "expected" in datum ? datum.expected : void 0;
|
|
45247
46146
|
let output = void 0;
|
|
45248
46147
|
let error = void 0;
|
|
45249
|
-
let tags = [
|
|
45250
|
-
const scores =
|
|
45251
|
-
const classifications =
|
|
46148
|
+
let tags = [];
|
|
46149
|
+
const scores = /* @__PURE__ */ Object.create(null);
|
|
46150
|
+
const classifications = /* @__PURE__ */ Object.create(null);
|
|
45252
46151
|
const scorerNames = (evaluator.scores ?? []).map(scorerName);
|
|
45253
46152
|
const classifierNames = (evaluator.classifiers ?? []).map(
|
|
45254
46153
|
classifierName
|
|
45255
46154
|
);
|
|
45256
46155
|
let unhandledScores = scorerNames;
|
|
45257
46156
|
try {
|
|
45258
|
-
const
|
|
45259
|
-
|
|
45260
|
-
|
|
45261
|
-
|
|
45262
|
-
|
|
45263
|
-
|
|
45264
|
-
|
|
45265
|
-
|
|
45266
|
-
|
|
45267
|
-
|
|
45268
|
-
|
|
45269
|
-
|
|
45270
|
-
|
|
45271
|
-
|
|
45272
|
-
|
|
45273
|
-
object_type: "task"
|
|
45274
|
-
});
|
|
45275
|
-
},
|
|
45276
|
-
trialIndex,
|
|
45277
|
-
tags
|
|
45278
|
-
};
|
|
45279
|
-
const outputResult = evaluator.task(datum.input, hooksForTask);
|
|
45280
|
-
if (outputResult instanceof Promise) {
|
|
45281
|
-
output = await outputResult;
|
|
45282
|
-
} else {
|
|
45283
|
-
output = outputResult;
|
|
46157
|
+
const taskResult = await rootSpan.traced(
|
|
46158
|
+
(span) => _internalRunEvaluatorTask(
|
|
46159
|
+
evaluator.task,
|
|
46160
|
+
datum,
|
|
46161
|
+
trialIndex,
|
|
46162
|
+
parameters ?? {},
|
|
46163
|
+
span,
|
|
46164
|
+
(event) => {
|
|
46165
|
+
stream?.({
|
|
46166
|
+
...event,
|
|
46167
|
+
id: rootSpan.id,
|
|
46168
|
+
origin: baseEvent.event?.origin,
|
|
46169
|
+
name: evaluator.evalName,
|
|
46170
|
+
object_type: "task"
|
|
46171
|
+
});
|
|
45284
46172
|
}
|
|
45285
|
-
|
|
45286
|
-
span.log({ output });
|
|
45287
|
-
},
|
|
46173
|
+
),
|
|
45288
46174
|
{
|
|
45289
46175
|
name: "task",
|
|
45290
46176
|
spanAttributes: { type: "task" /* TASK */ },
|
|
45291
46177
|
event: { input: datum.input }
|
|
45292
46178
|
}
|
|
45293
46179
|
);
|
|
46180
|
+
output = taskResult.output;
|
|
46181
|
+
metadata = taskResult.metadata;
|
|
46182
|
+
tags = taskResult.tags;
|
|
45294
46183
|
if (tags.length) {
|
|
45295
46184
|
rootSpan.log({ output, metadata, expected, tags });
|
|
45296
46185
|
} else {
|
|
@@ -45300,20 +46189,18 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
|
|
|
45300
46189
|
await rootSpan.flush();
|
|
45301
46190
|
}
|
|
45302
46191
|
const scoringArgs = {
|
|
46192
|
+
id: datum.id,
|
|
45303
46193
|
input: datum.input,
|
|
45304
46194
|
expected: "expected" in datum ? datum.expected : void 0,
|
|
45305
46195
|
metadata,
|
|
45306
46196
|
output,
|
|
46197
|
+
tags,
|
|
45307
46198
|
trace
|
|
45308
46199
|
};
|
|
45309
46200
|
const { trace: _trace, ...scoringArgsForLogging } = scoringArgs;
|
|
45310
46201
|
const propagatedEvent = makeScorerPropagatedEvent(
|
|
45311
46202
|
await rootSpan.export()
|
|
45312
46203
|
);
|
|
45313
|
-
const getOtherFields = (s) => {
|
|
45314
|
-
const { metadata: _metadata, name: _name, ...rest } = s;
|
|
45315
|
-
return rest;
|
|
45316
|
-
};
|
|
45317
46204
|
const [scoreResults, classificationResults] = await Promise.all([
|
|
45318
46205
|
Promise.all(
|
|
45319
46206
|
(evaluator.scores ?? []).map(
|
|
@@ -45327,35 +46214,17 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
|
|
|
45327
46214
|
const scoreValue = await Promise.resolve(
|
|
45328
46215
|
score(scoringArgs)
|
|
45329
46216
|
);
|
|
45330
|
-
|
|
45331
|
-
|
|
45332
|
-
|
|
45333
|
-
if (!(typeof s === "object" && !isEmpty2(s))) {
|
|
45334
|
-
throw new Error(
|
|
45335
|
-
`When returning an array of scores, each score must be a non-empty object. Got: ${JSON.stringify(s)}`
|
|
45336
|
-
);
|
|
45337
|
-
}
|
|
45338
|
-
}
|
|
45339
|
-
}
|
|
45340
|
-
const results = Array.isArray(scoreValue) ? scoreValue : typeof scoreValue === "object" && !isEmpty2(scoreValue) ? [scoreValue] : [
|
|
45341
|
-
{
|
|
45342
|
-
name: scorerNames[score_idx],
|
|
45343
|
-
score: scoreValue
|
|
45344
|
-
}
|
|
45345
|
-
];
|
|
45346
|
-
const { resultMetadata, scoresRecord } = buildSpanScores(results);
|
|
45347
|
-
const resultOutput = results.length === 1 ? getOtherFields(results[0]) : results.reduce(
|
|
45348
|
-
(prev, s) => mergeDicts(prev, {
|
|
45349
|
-
[s.name]: getOtherFields(s)
|
|
45350
|
-
}),
|
|
45351
|
-
{}
|
|
46217
|
+
const prepared = _internalPrepareEvaluatorScore(
|
|
46218
|
+
scoreValue,
|
|
46219
|
+
scorerNames[score_idx]
|
|
45352
46220
|
);
|
|
46221
|
+
if (prepared.results === null) return null;
|
|
45353
46222
|
span.log({
|
|
45354
|
-
output:
|
|
45355
|
-
metadata:
|
|
45356
|
-
scores:
|
|
46223
|
+
output: prepared.output,
|
|
46224
|
+
metadata: prepared.metadata,
|
|
46225
|
+
scores: prepared.scores
|
|
45357
46226
|
});
|
|
45358
|
-
return results;
|
|
46227
|
+
return prepared.results;
|
|
45359
46228
|
}
|
|
45360
46229
|
)
|
|
45361
46230
|
)
|
|
@@ -45372,24 +46241,16 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
|
|
|
45372
46241
|
const classifierValue = await Promise.resolve(
|
|
45373
46242
|
classifier(scoringArgs)
|
|
45374
46243
|
);
|
|
45375
|
-
|
|
45376
|
-
|
|
45377
|
-
|
|
45378
|
-
result,
|
|
45379
|
-
classifierNames[idx]
|
|
45380
|
-
)
|
|
45381
|
-
);
|
|
45382
|
-
const resultOutput = rawResults.length === 1 ? toClassificationItem(rawResults[0]) : rawResults.reduce(
|
|
45383
|
-
(prev, r) => mergeDicts(prev, {
|
|
45384
|
-
[r.name]: toClassificationItem(r)
|
|
45385
|
-
}),
|
|
45386
|
-
{}
|
|
46244
|
+
const prepared = _internalPrepareEvaluatorClassification(
|
|
46245
|
+
classifierValue,
|
|
46246
|
+
classifierNames[idx]
|
|
45387
46247
|
);
|
|
46248
|
+
if (prepared.results === null) return null;
|
|
45388
46249
|
span.log({
|
|
45389
|
-
output:
|
|
45390
|
-
metadata:
|
|
46250
|
+
output: prepared.output,
|
|
46251
|
+
metadata: prepared.metadata
|
|
45391
46252
|
});
|
|
45392
|
-
return
|
|
46253
|
+
return prepared.results;
|
|
45393
46254
|
}
|
|
45394
46255
|
)
|
|
45395
46256
|
)
|
|
@@ -45618,7 +46479,7 @@ function accumulateScores(accumulator, scores) {
|
|
|
45618
46479
|
}
|
|
45619
46480
|
}
|
|
45620
46481
|
function ensureScoreAccumulator(results) {
|
|
45621
|
-
const accumulator =
|
|
46482
|
+
const accumulator = /* @__PURE__ */ Object.create(null);
|
|
45622
46483
|
for (const result of results) {
|
|
45623
46484
|
accumulateScores(accumulator, result.scores);
|
|
45624
46485
|
}
|
|
@@ -45761,6 +46622,1156 @@ var defaultReporter = {
|
|
|
45761
46622
|
}
|
|
45762
46623
|
};
|
|
45763
46624
|
|
|
46625
|
+
// src/durable-eval.ts
|
|
46626
|
+
var encoder = new TextEncoder();
|
|
46627
|
+
var decoder = new TextDecoder();
|
|
46628
|
+
var BATCH_TASK_KIND = "braintrust.durable.batch-task";
|
|
46629
|
+
var BATCH_SCORER_KIND = "braintrust.durable.batch-scorer";
|
|
46630
|
+
var DEFAULT_BATCH_SIZE = 1e3;
|
|
46631
|
+
var DurableEvalMemoryStore = class {
|
|
46632
|
+
values = /* @__PURE__ */ new Map();
|
|
46633
|
+
async read(key) {
|
|
46634
|
+
return this.values.get(key)?.slice();
|
|
46635
|
+
}
|
|
46636
|
+
async write(key, value) {
|
|
46637
|
+
this.values.set(key, value.slice());
|
|
46638
|
+
}
|
|
46639
|
+
async getOrSet(key, value) {
|
|
46640
|
+
const existing = this.values.get(key);
|
|
46641
|
+
if (existing) return { value: existing.slice(), created: false };
|
|
46642
|
+
this.values.set(key, value.slice());
|
|
46643
|
+
return { value: value.slice(), created: true };
|
|
46644
|
+
}
|
|
46645
|
+
};
|
|
46646
|
+
var DurableEvalRedisStore = class {
|
|
46647
|
+
client;
|
|
46648
|
+
keyPrefix;
|
|
46649
|
+
ttlMs;
|
|
46650
|
+
constructor(options) {
|
|
46651
|
+
this.client = options.client;
|
|
46652
|
+
this.keyPrefix = options.keyPrefix ?? "braintrust-eval:";
|
|
46653
|
+
this.ttlMs = options.ttlMs ?? 1e3 * 60 * 60 * 24 * 7;
|
|
46654
|
+
if (!Number.isInteger(this.ttlMs) || this.ttlMs < 1) {
|
|
46655
|
+
throw new Error("DurableEvalRedisStore ttlMs must be a positive integer");
|
|
46656
|
+
}
|
|
46657
|
+
}
|
|
46658
|
+
async read(key) {
|
|
46659
|
+
const value = await this.client.get(`${this.keyPrefix}${key}`);
|
|
46660
|
+
if (value == null) return void 0;
|
|
46661
|
+
if (typeof value !== "string") {
|
|
46662
|
+
throw new Error("DurableEvalRedisStore expected GET to return a string");
|
|
46663
|
+
}
|
|
46664
|
+
return base64ToUint8Array(value);
|
|
46665
|
+
}
|
|
46666
|
+
async write(key, value) {
|
|
46667
|
+
const client = this.client;
|
|
46668
|
+
const set = client.set;
|
|
46669
|
+
const redisKey = `${this.keyPrefix}${key}`;
|
|
46670
|
+
const encoded = uint8ArrayToBase64(value);
|
|
46671
|
+
if (typeof client.defineCommand === "function") {
|
|
46672
|
+
await set.call(client, redisKey, encoded, "PX", this.ttlMs);
|
|
46673
|
+
} else if (typeof client.sendCommand === "function") {
|
|
46674
|
+
await set.call(client, redisKey, encoded, { PX: this.ttlMs });
|
|
46675
|
+
} else if (typeof client.createScript === "function") {
|
|
46676
|
+
await set.call(client, redisKey, encoded, { px: this.ttlMs });
|
|
46677
|
+
} else {
|
|
46678
|
+
throw new Error(
|
|
46679
|
+
"DurableEvalRedisStore requires a node-redis, ioredis, or @upstash/redis client"
|
|
46680
|
+
);
|
|
46681
|
+
}
|
|
46682
|
+
}
|
|
46683
|
+
async getOrSet(key, value) {
|
|
46684
|
+
const redisKey = `${this.keyPrefix}${key}`;
|
|
46685
|
+
const encoded = uint8ArrayToBase64(value);
|
|
46686
|
+
const client = this.client;
|
|
46687
|
+
const set = client.set;
|
|
46688
|
+
let setOptions;
|
|
46689
|
+
if (typeof client.defineCommand === "function") {
|
|
46690
|
+
setOptions = ["PX", this.ttlMs, "NX", "GET"];
|
|
46691
|
+
} else if (typeof client.sendCommand === "function") {
|
|
46692
|
+
setOptions = [{ PX: this.ttlMs, NX: true, GET: true }];
|
|
46693
|
+
} else if (typeof client.createScript === "function") {
|
|
46694
|
+
setOptions = [{ px: this.ttlMs, nx: true, get: true }];
|
|
46695
|
+
} else {
|
|
46696
|
+
throw new Error(
|
|
46697
|
+
"DurableEvalRedisStore getOrSet requires a node-redis, ioredis, or @upstash/redis client"
|
|
46698
|
+
);
|
|
46699
|
+
}
|
|
46700
|
+
const existing = await set.call(client, redisKey, encoded, ...setOptions);
|
|
46701
|
+
if (existing === null) return { value: value.slice(), created: true };
|
|
46702
|
+
if (typeof existing !== "string") {
|
|
46703
|
+
throw new Error(
|
|
46704
|
+
"DurableEvalRedisStore expected atomic SET to return a string or null"
|
|
46705
|
+
);
|
|
46706
|
+
}
|
|
46707
|
+
return { value: base64ToUint8Array(existing), created: false };
|
|
46708
|
+
}
|
|
46709
|
+
};
|
|
46710
|
+
var BatchTask = class {
|
|
46711
|
+
constructor(processor) {
|
|
46712
|
+
this.processor = processor;
|
|
46713
|
+
}
|
|
46714
|
+
processor;
|
|
46715
|
+
kind = BATCH_TASK_KIND;
|
|
46716
|
+
};
|
|
46717
|
+
var BatchScorer = class {
|
|
46718
|
+
constructor(processor) {
|
|
46719
|
+
this.processor = processor;
|
|
46720
|
+
this.name = processor.name;
|
|
46721
|
+
}
|
|
46722
|
+
processor;
|
|
46723
|
+
kind = BATCH_SCORER_KIND;
|
|
46724
|
+
name;
|
|
46725
|
+
};
|
|
46726
|
+
function defineDurableEval(projectName, evaluator) {
|
|
46727
|
+
const definition = {
|
|
46728
|
+
projectName,
|
|
46729
|
+
evalName: evaluator.experimentName ?? projectName,
|
|
46730
|
+
evaluator
|
|
46731
|
+
};
|
|
46732
|
+
return {
|
|
46733
|
+
start: (options = {}) => startDurableEval(definition, options),
|
|
46734
|
+
status: (options) => getDurableEvalStatus(definition, options),
|
|
46735
|
+
poll: (options) => pollDurableEval(definition, options),
|
|
46736
|
+
processBatchResult: (result) => processDurableBatchResult(definition, result)
|
|
46737
|
+
};
|
|
46738
|
+
}
|
|
46739
|
+
async function startDurableEval(definition, options) {
|
|
46740
|
+
const store = definition.evaluator.store;
|
|
46741
|
+
const runId = newId();
|
|
46742
|
+
const key = runKey(definition.projectName, definition.evalName, runId);
|
|
46743
|
+
const { data } = callEvaluatorData(definition.evaluator.data);
|
|
46744
|
+
const parameters = await validateParameters(
|
|
46745
|
+
options.parameters ?? {},
|
|
46746
|
+
definition.evaluator.parameters
|
|
46747
|
+
);
|
|
46748
|
+
const experimentName = definition.evaluator.experimentName ?? `${definition.evalName}-${runId}`;
|
|
46749
|
+
const experiment = await _internalInitEvaluatorExperiment(
|
|
46750
|
+
definition.projectName,
|
|
46751
|
+
{ ...definition.evaluator, data },
|
|
46752
|
+
data,
|
|
46753
|
+
{
|
|
46754
|
+
disabled: options.noSendLogs ?? false,
|
|
46755
|
+
experimentName,
|
|
46756
|
+
update: true
|
|
46757
|
+
}
|
|
46758
|
+
);
|
|
46759
|
+
if (!isBatchTask(definition.evaluator.task) && !(definition.evaluator.scores ?? []).some(isBatchScorer)) {
|
|
46760
|
+
const result = await runEvaluator(
|
|
46761
|
+
experiment,
|
|
46762
|
+
{
|
|
46763
|
+
...definition.evaluator,
|
|
46764
|
+
projectName: definition.projectName,
|
|
46765
|
+
evalName: definition.evalName,
|
|
46766
|
+
data
|
|
46767
|
+
},
|
|
46768
|
+
{
|
|
46769
|
+
start: () => void 0,
|
|
46770
|
+
stop: () => void 0,
|
|
46771
|
+
increment: () => void 0
|
|
46772
|
+
},
|
|
46773
|
+
[],
|
|
46774
|
+
void 0,
|
|
46775
|
+
parameters,
|
|
46776
|
+
true,
|
|
46777
|
+
true
|
|
46778
|
+
);
|
|
46779
|
+
const state2 = {
|
|
46780
|
+
runId,
|
|
46781
|
+
experimentName,
|
|
46782
|
+
noSendLogs: options.noSendLogs ?? false,
|
|
46783
|
+
parameters: assertJsonValue(parameters, "eval parameters"),
|
|
46784
|
+
status: "completed",
|
|
46785
|
+
summary: result.summary,
|
|
46786
|
+
cases: [],
|
|
46787
|
+
batches: []
|
|
46788
|
+
};
|
|
46789
|
+
await experiment?.flush();
|
|
46790
|
+
await writeRunRecord(store, key, state2);
|
|
46791
|
+
return currentStatus(definition, state2);
|
|
46792
|
+
}
|
|
46793
|
+
const state = {
|
|
46794
|
+
runId,
|
|
46795
|
+
experimentName,
|
|
46796
|
+
noSendLogs: options.noSendLogs ?? false,
|
|
46797
|
+
parameters: assertJsonValue(parameters, "eval parameters"),
|
|
46798
|
+
status: "running",
|
|
46799
|
+
cases: await materializeCases(definition, data, experiment),
|
|
46800
|
+
batches: []
|
|
46801
|
+
};
|
|
46802
|
+
await writeCaseBaseRecords(store, key, state.cases);
|
|
46803
|
+
await writeRunRecord(store, key, state);
|
|
46804
|
+
return advanceDurableEval(definition, state, store, key, experiment);
|
|
46805
|
+
}
|
|
46806
|
+
async function getDurableEvalStatus(definition, options) {
|
|
46807
|
+
const store = definition.evaluator.store;
|
|
46808
|
+
const state = await readRunState(
|
|
46809
|
+
definition,
|
|
46810
|
+
store,
|
|
46811
|
+
runKey(definition.projectName, definition.evalName, options.runId)
|
|
46812
|
+
);
|
|
46813
|
+
if (!state) throw new Error(`Durable eval run ${options.runId} is missing`);
|
|
46814
|
+
return currentStatus(definition, state);
|
|
46815
|
+
}
|
|
46816
|
+
async function processDurableBatchResult(definition, result) {
|
|
46817
|
+
if (!result.batchId && !result.externalId) {
|
|
46818
|
+
throw new Error("Batch results require batchId or externalId");
|
|
46819
|
+
}
|
|
46820
|
+
const store = definition.evaluator.store;
|
|
46821
|
+
const key = runKey(definition.projectName, definition.evalName, result.runId);
|
|
46822
|
+
const state = await readRunState(definition, store, key);
|
|
46823
|
+
if (!state) throw new Error(`Durable eval run ${result.runId} is missing`);
|
|
46824
|
+
const byBatch = result.batchId ? state.batches.find((candidate) => candidate.id === result.batchId) : void 0;
|
|
46825
|
+
const byExternal = result.externalId ? state.batches.find(
|
|
46826
|
+
(candidate) => candidate.externalId === result.externalId
|
|
46827
|
+
) : void 0;
|
|
46828
|
+
if (byBatch && byExternal && byBatch.id !== byExternal.id) {
|
|
46829
|
+
throw new Error("batchId and externalId identify different batches");
|
|
46830
|
+
}
|
|
46831
|
+
const batch = byBatch ?? byExternal;
|
|
46832
|
+
if (!batch) throw new Error("No submitted batch matches this result");
|
|
46833
|
+
if (batch.status !== "complete") {
|
|
46834
|
+
const records = await collectBatch(definition, state, batch);
|
|
46835
|
+
batch.status = "complete";
|
|
46836
|
+
await writeCaseRecords(store, key, records);
|
|
46837
|
+
await writeBatchRecords(store, key, [batch]);
|
|
46838
|
+
}
|
|
46839
|
+
return advanceDurableEval(
|
|
46840
|
+
definition,
|
|
46841
|
+
await readRunState(definition, store, key),
|
|
46842
|
+
store,
|
|
46843
|
+
key
|
|
46844
|
+
);
|
|
46845
|
+
}
|
|
46846
|
+
async function pollDurableEval(definition, options) {
|
|
46847
|
+
const store = definition.evaluator.store;
|
|
46848
|
+
const key = runKey(
|
|
46849
|
+
definition.projectName,
|
|
46850
|
+
definition.evalName,
|
|
46851
|
+
options.runId
|
|
46852
|
+
);
|
|
46853
|
+
const state = await readRunState(definition, store, key);
|
|
46854
|
+
if (!state) throw new Error(`Durable eval run ${options.runId} is missing`);
|
|
46855
|
+
const batches = state.batches.filter((batch) => {
|
|
46856
|
+
if (batch.status === "complete") return false;
|
|
46857
|
+
return processorForStage(definition, batch.kind, batch.scorerName).completion.mode === "poll";
|
|
46858
|
+
});
|
|
46859
|
+
const results = await Promise.all(
|
|
46860
|
+
batches.map(async (batch) => ({
|
|
46861
|
+
batch,
|
|
46862
|
+
result: await processorForStage(definition, batch.kind, batch.scorerName).completion.poll(batch.submissionData, {
|
|
46863
|
+
runId: state.runId,
|
|
46864
|
+
batchId: batch.id
|
|
46865
|
+
})
|
|
46866
|
+
}))
|
|
46867
|
+
);
|
|
46868
|
+
const changedCases = /* @__PURE__ */ new Map();
|
|
46869
|
+
const changedBatches = [];
|
|
46870
|
+
for (const { batch, result } of results) {
|
|
46871
|
+
if (result.status === "failed") throw asError(result.error);
|
|
46872
|
+
if (result.status !== "complete") continue;
|
|
46873
|
+
for (const record of await collectBatch(definition, state, batch)) {
|
|
46874
|
+
changedCases.set(record.id, record);
|
|
46875
|
+
}
|
|
46876
|
+
batch.status = "complete";
|
|
46877
|
+
changedBatches.push(batch);
|
|
46878
|
+
}
|
|
46879
|
+
if (changedBatches.length > 0) {
|
|
46880
|
+
await writeCaseRecords(store, key, [...changedCases.values()]);
|
|
46881
|
+
await writeBatchRecords(store, key, changedBatches);
|
|
46882
|
+
}
|
|
46883
|
+
const currentState = changedBatches.length > 0 ? await readRunState(definition, store, key) : state;
|
|
46884
|
+
return advanceDurableEval(definition, currentState, store, key);
|
|
46885
|
+
}
|
|
46886
|
+
async function openDurableExperiment(definition, state) {
|
|
46887
|
+
const data = [];
|
|
46888
|
+
return await _internalInitEvaluatorExperiment(
|
|
46889
|
+
definition.projectName,
|
|
46890
|
+
{ ...definition.evaluator, data },
|
|
46891
|
+
data,
|
|
46892
|
+
{
|
|
46893
|
+
disabled: state.noSendLogs,
|
|
46894
|
+
experimentName: state.experimentName,
|
|
46895
|
+
update: true
|
|
46896
|
+
}
|
|
46897
|
+
);
|
|
46898
|
+
}
|
|
46899
|
+
async function advanceDurableEval(definition, state, store, key, existingExperiment) {
|
|
46900
|
+
if (state.status === "completed") return currentStatus(definition, state);
|
|
46901
|
+
const experiment = existingExperiment === void 0 ? await openDurableExperiment(definition, state) : existingExperiment;
|
|
46902
|
+
await runTaskStage(definition, state, store, key, experiment);
|
|
46903
|
+
await logCompletedTasks(definition, state, store, key, experiment);
|
|
46904
|
+
state = await readRunState(definition, store, key) ?? state;
|
|
46905
|
+
if (state.cases.some((record) => !record.taskComplete || !record.taskLogged)) {
|
|
46906
|
+
return currentStatus(definition, state);
|
|
46907
|
+
}
|
|
46908
|
+
await runScoreStages(definition, state, store, key, experiment);
|
|
46909
|
+
state = await readRunState(definition, store, key) ?? state;
|
|
46910
|
+
const scorerNames = resolveScorers(definition.evaluator.scores ?? []).map(
|
|
46911
|
+
({ name }) => name
|
|
46912
|
+
);
|
|
46913
|
+
const classifierNames = (definition.evaluator.classifiers ?? []).map(
|
|
46914
|
+
classifierName
|
|
46915
|
+
);
|
|
46916
|
+
if (state.cases.some(
|
|
46917
|
+
(record) => scorerNames.some(
|
|
46918
|
+
(name) => !Object.hasOwn(record.scores, name) || !Object.hasOwn(record.loggedScores, name)
|
|
46919
|
+
) || classifierNames.some(
|
|
46920
|
+
(name) => !Object.hasOwn(record.loggedClassifications, name)
|
|
46921
|
+
)
|
|
46922
|
+
)) {
|
|
46923
|
+
return currentStatus(definition, state);
|
|
46924
|
+
}
|
|
46925
|
+
if (!await claimAction(store, key, "finish")) {
|
|
46926
|
+
const latest = await readRunState(definition, store, key);
|
|
46927
|
+
return currentStatus(definition, latest ?? state);
|
|
46928
|
+
}
|
|
46929
|
+
state.summary = await finishExperiment(definition, state, experiment);
|
|
46930
|
+
state.status = "completed";
|
|
46931
|
+
await writeRunRecord(store, key, state);
|
|
46932
|
+
return currentStatus(definition, state);
|
|
46933
|
+
}
|
|
46934
|
+
function currentStatus(definition, state) {
|
|
46935
|
+
if (state.status === "completed") {
|
|
46936
|
+
if (!state.summary) {
|
|
46937
|
+
throw new Error(`Durable eval run ${state.runId} has no saved summary`);
|
|
46938
|
+
}
|
|
46939
|
+
return {
|
|
46940
|
+
status: "completed",
|
|
46941
|
+
runId: state.runId,
|
|
46942
|
+
pending: { poll: 0, webhook: 0 },
|
|
46943
|
+
summary: state.summary
|
|
46944
|
+
};
|
|
46945
|
+
}
|
|
46946
|
+
const pending = { poll: 0, webhook: 0 };
|
|
46947
|
+
for (const batch of state.batches) {
|
|
46948
|
+
if (batch.status === "complete") continue;
|
|
46949
|
+
pending[processorForStage(definition, batch.kind, batch.scorerName).completion.mode]++;
|
|
46950
|
+
}
|
|
46951
|
+
return { status: "waiting", runId: state.runId, pending };
|
|
46952
|
+
}
|
|
46953
|
+
async function startCaseRoot(definition, state, record, experiment) {
|
|
46954
|
+
if (!experiment) return NOOP_SPAN;
|
|
46955
|
+
const datum = record.datum;
|
|
46956
|
+
return _internalStartSpanWithInitialMerge({
|
|
46957
|
+
...definition.evaluator.state ? { state: definition.evaluator.state } : {},
|
|
46958
|
+
parent: await experiment.export(),
|
|
46959
|
+
name: "eval",
|
|
46960
|
+
spanId: deterministicId(`${state.runId}:${record.id}:span`),
|
|
46961
|
+
spanAttributes: { type: "eval" /* EVAL */ },
|
|
46962
|
+
event: {
|
|
46963
|
+
id: deterministicId(`${state.runId}:${record.id}:row`),
|
|
46964
|
+
input: datum.input,
|
|
46965
|
+
expected: "expected" in datum ? datum.expected : void 0,
|
|
46966
|
+
tags: datum.tags,
|
|
46967
|
+
origin: datum.origin
|
|
46968
|
+
}
|
|
46969
|
+
});
|
|
46970
|
+
}
|
|
46971
|
+
async function logTaskResult(definition, state, record, experiment, task) {
|
|
46972
|
+
const datum = record.datum;
|
|
46973
|
+
const root = await startCaseRoot(definition, state, record, experiment);
|
|
46974
|
+
try {
|
|
46975
|
+
if (task) {
|
|
46976
|
+
const result = await root.traced(
|
|
46977
|
+
(span) => _internalRunEvaluatorTask(
|
|
46978
|
+
task,
|
|
46979
|
+
datum,
|
|
46980
|
+
record.trialIndex,
|
|
46981
|
+
state.parameters,
|
|
46982
|
+
span
|
|
46983
|
+
),
|
|
46984
|
+
{
|
|
46985
|
+
name: "task",
|
|
46986
|
+
spanId: deterministicId(`${state.runId}:${record.id}:task`),
|
|
46987
|
+
spanAttributes: { type: "task" /* TASK */ },
|
|
46988
|
+
event: { input: datum.input }
|
|
46989
|
+
}
|
|
46990
|
+
);
|
|
46991
|
+
record.output = assertJsonValue(
|
|
46992
|
+
result.output,
|
|
46993
|
+
`task output for ${record.caseId}`
|
|
46994
|
+
);
|
|
46995
|
+
record.metadata = assertJsonValue(result.metadata, "task metadata");
|
|
46996
|
+
record.tags = result.tags;
|
|
46997
|
+
record.taskComplete = true;
|
|
46998
|
+
} else {
|
|
46999
|
+
await root.traced((span) => span.log({ output: record.output }), {
|
|
47000
|
+
name: "task",
|
|
47001
|
+
spanId: deterministicId(`${state.runId}:${record.id}:task`),
|
|
47002
|
+
spanAttributes: { type: "task" /* TASK */ },
|
|
47003
|
+
event: { input: datum.input }
|
|
47004
|
+
});
|
|
47005
|
+
}
|
|
47006
|
+
root.log({
|
|
47007
|
+
output: record.output,
|
|
47008
|
+
expected: "expected" in datum ? datum.expected : void 0,
|
|
47009
|
+
metadata: {
|
|
47010
|
+
...record.metadata,
|
|
47011
|
+
durable_eval: {
|
|
47012
|
+
run_id: state.runId,
|
|
47013
|
+
case_id: record.caseId,
|
|
47014
|
+
trial_index: record.trialIndex
|
|
47015
|
+
}
|
|
47016
|
+
},
|
|
47017
|
+
tags: record.tags
|
|
47018
|
+
});
|
|
47019
|
+
record.rootSpan = await root.export();
|
|
47020
|
+
record.taskLogged = true;
|
|
47021
|
+
} catch (error) {
|
|
47022
|
+
logError(root, error);
|
|
47023
|
+
throw error;
|
|
47024
|
+
} finally {
|
|
47025
|
+
root.end();
|
|
47026
|
+
}
|
|
47027
|
+
}
|
|
47028
|
+
async function logCompletedTasks(definition, state, store, key, experiment) {
|
|
47029
|
+
const changed = [];
|
|
47030
|
+
for (const record of state.cases) {
|
|
47031
|
+
if (!record.taskComplete || record.taskLogged) continue;
|
|
47032
|
+
if (!await claimAction(store, key, "task-log", record.id)) continue;
|
|
47033
|
+
await logTaskResult(definition, state, record, experiment);
|
|
47034
|
+
changed.push(record);
|
|
47035
|
+
}
|
|
47036
|
+
if (changed.length > 0) {
|
|
47037
|
+
await experiment?.flush();
|
|
47038
|
+
await writeCaseRecords(store, key, changed);
|
|
47039
|
+
}
|
|
47040
|
+
}
|
|
47041
|
+
async function runTaskStage(definition, state, store, key, experiment) {
|
|
47042
|
+
if (isBatchTask(definition.evaluator.task)) {
|
|
47043
|
+
await ensureBatches(definition, state, store, key, "task");
|
|
47044
|
+
return;
|
|
47045
|
+
}
|
|
47046
|
+
const task = definition.evaluator.task;
|
|
47047
|
+
const changed = [];
|
|
47048
|
+
for (const record of state.cases) {
|
|
47049
|
+
if (record.taskComplete) continue;
|
|
47050
|
+
if (!await claimAction(store, key, "task", record.id)) continue;
|
|
47051
|
+
await logTaskResult(definition, state, record, experiment, task);
|
|
47052
|
+
changed.push(record);
|
|
47053
|
+
}
|
|
47054
|
+
if (changed.length > 0) {
|
|
47055
|
+
await experiment?.flush();
|
|
47056
|
+
await writeCaseRecords(store, key, changed);
|
|
47057
|
+
}
|
|
47058
|
+
}
|
|
47059
|
+
async function runScoreStages(definition, state, store, key, experiment) {
|
|
47060
|
+
const scorers = resolveScorers(definition.evaluator.scores ?? []);
|
|
47061
|
+
const changed = /* @__PURE__ */ new Map();
|
|
47062
|
+
const persistChangedCases = async () => {
|
|
47063
|
+
if (changed.size === 0) return;
|
|
47064
|
+
await experiment?.flush();
|
|
47065
|
+
await writeCaseRecords(store, key, [...changed.values()]);
|
|
47066
|
+
changed.clear();
|
|
47067
|
+
};
|
|
47068
|
+
for (const { name, scorer } of scorers) {
|
|
47069
|
+
if (isBatchScorer(scorer)) {
|
|
47070
|
+
for (const record of state.cases) {
|
|
47071
|
+
if (Object.hasOwn(record.scores, name) && !Object.hasOwn(record.loggedScores, name)) {
|
|
47072
|
+
if (!await claimAction(store, key, "score-log", record.id, name)) {
|
|
47073
|
+
continue;
|
|
47074
|
+
}
|
|
47075
|
+
await evaluateAndLogScore(
|
|
47076
|
+
definition,
|
|
47077
|
+
state,
|
|
47078
|
+
record,
|
|
47079
|
+
name,
|
|
47080
|
+
experiment
|
|
47081
|
+
);
|
|
47082
|
+
changed.set(record.id, record);
|
|
47083
|
+
}
|
|
47084
|
+
}
|
|
47085
|
+
await persistChangedCases();
|
|
47086
|
+
await ensureBatches(definition, state, store, key, "score", name);
|
|
47087
|
+
continue;
|
|
47088
|
+
}
|
|
47089
|
+
for (const record of state.cases) {
|
|
47090
|
+
if (Object.hasOwn(record.loggedScores, name)) continue;
|
|
47091
|
+
if (!await claimAction(store, key, "score", record.id, name)) continue;
|
|
47092
|
+
await evaluateAndLogScore(
|
|
47093
|
+
definition,
|
|
47094
|
+
state,
|
|
47095
|
+
record,
|
|
47096
|
+
name,
|
|
47097
|
+
experiment,
|
|
47098
|
+
scorer
|
|
47099
|
+
);
|
|
47100
|
+
changed.set(record.id, record);
|
|
47101
|
+
}
|
|
47102
|
+
}
|
|
47103
|
+
for (const [index, classifier] of (definition.evaluator.classifiers ?? []).entries()) {
|
|
47104
|
+
const name = classifierName(classifier, index);
|
|
47105
|
+
for (const record of state.cases) {
|
|
47106
|
+
if (Object.hasOwn(record.loggedClassifications, name)) continue;
|
|
47107
|
+
if (!await claimAction(store, key, "classification", record.id, name)) {
|
|
47108
|
+
continue;
|
|
47109
|
+
}
|
|
47110
|
+
await evaluateAndLogClassification(
|
|
47111
|
+
definition,
|
|
47112
|
+
state,
|
|
47113
|
+
record,
|
|
47114
|
+
name,
|
|
47115
|
+
classifier,
|
|
47116
|
+
experiment
|
|
47117
|
+
);
|
|
47118
|
+
changed.set(record.id, record);
|
|
47119
|
+
}
|
|
47120
|
+
}
|
|
47121
|
+
await persistChangedCases();
|
|
47122
|
+
}
|
|
47123
|
+
function scorerArgs(record) {
|
|
47124
|
+
const datum = record.datum;
|
|
47125
|
+
return {
|
|
47126
|
+
...datum,
|
|
47127
|
+
metadata: record.metadata,
|
|
47128
|
+
output: record.output
|
|
47129
|
+
};
|
|
47130
|
+
}
|
|
47131
|
+
function resumeCaseRoot(definition, record, experiment) {
|
|
47132
|
+
if (!experiment) return NOOP_SPAN;
|
|
47133
|
+
if (!record.rootSpan) {
|
|
47134
|
+
throw new Error(`Durable eval case ${record.caseId} has no root span`);
|
|
47135
|
+
}
|
|
47136
|
+
return _internalResumeSpan({
|
|
47137
|
+
exported: record.rootSpan,
|
|
47138
|
+
state: definition.evaluator.state
|
|
47139
|
+
});
|
|
47140
|
+
}
|
|
47141
|
+
async function evaluateAndLogScore(definition, state, record, name, experiment, scorer) {
|
|
47142
|
+
const root = resumeCaseRoot(definition, record, experiment);
|
|
47143
|
+
try {
|
|
47144
|
+
const rootExport = await root.export();
|
|
47145
|
+
const prepared = await root.traced(
|
|
47146
|
+
async (span) => {
|
|
47147
|
+
const value = scorer ? await scorer(scorerArgs(record)) : record.scores[name];
|
|
47148
|
+
if (scorer) {
|
|
47149
|
+
record.scores[name] = assertJsonValue(value, `scorer ${name} output`);
|
|
47150
|
+
}
|
|
47151
|
+
const result = _internalPrepareEvaluatorScore(value, name);
|
|
47152
|
+
if (result.results !== null) {
|
|
47153
|
+
span.log({
|
|
47154
|
+
output: result.output,
|
|
47155
|
+
metadata: result.metadata,
|
|
47156
|
+
scores: result.scores
|
|
47157
|
+
});
|
|
47158
|
+
}
|
|
47159
|
+
return result;
|
|
47160
|
+
},
|
|
47161
|
+
{
|
|
47162
|
+
name,
|
|
47163
|
+
spanId: deterministicId(`${state.runId}:${record.id}:score:${name}`),
|
|
47164
|
+
spanAttributes: {
|
|
47165
|
+
type: "score" /* SCORE */,
|
|
47166
|
+
purpose: "scorer"
|
|
47167
|
+
},
|
|
47168
|
+
propagatedEvent: makeScorerPropagatedEvent(rootExport || void 0),
|
|
47169
|
+
event: { input: scorerArgs(record) }
|
|
47170
|
+
}
|
|
47171
|
+
);
|
|
47172
|
+
if (prepared.scores) root.log({ scores: prepared.scores });
|
|
47173
|
+
record.loggedScores[name] = true;
|
|
47174
|
+
} catch (error) {
|
|
47175
|
+
logError(root, error);
|
|
47176
|
+
throw error;
|
|
47177
|
+
} finally {
|
|
47178
|
+
root.end();
|
|
47179
|
+
}
|
|
47180
|
+
}
|
|
47181
|
+
async function evaluateAndLogClassification(definition, state, record, name, classifier, experiment) {
|
|
47182
|
+
const root = resumeCaseRoot(definition, record, experiment);
|
|
47183
|
+
try {
|
|
47184
|
+
const rootExport = await root.export();
|
|
47185
|
+
const prepared = await root.traced(
|
|
47186
|
+
async (span) => {
|
|
47187
|
+
const value = await classifier(scorerArgs(record));
|
|
47188
|
+
record.classifications[name] = assertJsonValue(
|
|
47189
|
+
value,
|
|
47190
|
+
`classifier ${name} output`
|
|
47191
|
+
);
|
|
47192
|
+
const result = _internalPrepareEvaluatorClassification(value, name);
|
|
47193
|
+
if (result.results !== null) {
|
|
47194
|
+
span.log({ output: result.output, metadata: result.metadata });
|
|
47195
|
+
}
|
|
47196
|
+
return result;
|
|
47197
|
+
},
|
|
47198
|
+
{
|
|
47199
|
+
name,
|
|
47200
|
+
spanId: deterministicId(
|
|
47201
|
+
`${state.runId}:${record.id}:classification:${name}`
|
|
47202
|
+
),
|
|
47203
|
+
spanAttributes: {
|
|
47204
|
+
type: "classifier" /* CLASSIFIER */,
|
|
47205
|
+
purpose: "scorer"
|
|
47206
|
+
},
|
|
47207
|
+
propagatedEvent: makeScorerPropagatedEvent(rootExport || void 0),
|
|
47208
|
+
event: { input: scorerArgs(record) }
|
|
47209
|
+
}
|
|
47210
|
+
);
|
|
47211
|
+
if (prepared.classifications) {
|
|
47212
|
+
root.log({ classifications: prepared.classifications });
|
|
47213
|
+
}
|
|
47214
|
+
record.loggedClassifications[name] = true;
|
|
47215
|
+
} catch (error) {
|
|
47216
|
+
logError(root, error);
|
|
47217
|
+
throw error;
|
|
47218
|
+
} finally {
|
|
47219
|
+
root.end();
|
|
47220
|
+
}
|
|
47221
|
+
}
|
|
47222
|
+
async function ensureBatches(definition, state, store, key, kind, scorerName2) {
|
|
47223
|
+
const processor = processorForStage(definition, kind, scorerName2);
|
|
47224
|
+
const plans = plannedBatches(
|
|
47225
|
+
definition,
|
|
47226
|
+
state.runId,
|
|
47227
|
+
state.cases.map(({ id }) => id)
|
|
47228
|
+
);
|
|
47229
|
+
const casesById = new Map(state.cases.map((record) => [record.id, record]));
|
|
47230
|
+
for (const plan of plans) {
|
|
47231
|
+
if (plan.kind !== kind || plan.scorerName !== scorerName2) continue;
|
|
47232
|
+
if (state.batches.some(({ id }) => id === plan.id)) continue;
|
|
47233
|
+
const records = plan.itemIds.map((id) => casesById.get(id));
|
|
47234
|
+
const ready = records.every(
|
|
47235
|
+
(record) => kind === "task" ? !record.taskComplete : !Object.hasOwn(record.scores, scorerName2)
|
|
47236
|
+
);
|
|
47237
|
+
if (!ready) continue;
|
|
47238
|
+
const batchId = plan.id;
|
|
47239
|
+
const claim = await store.getOrSet(
|
|
47240
|
+
claimRecordKey(key, "batch", batchId),
|
|
47241
|
+
encoder.encode(batchId)
|
|
47242
|
+
);
|
|
47243
|
+
if (!claim.created) continue;
|
|
47244
|
+
const context = { runId: state.runId, batchId };
|
|
47245
|
+
const items = records.map(
|
|
47246
|
+
(record) => kind === "task" ? taskBatchItem(record, state.parameters) : scorerBatchItem(record)
|
|
47247
|
+
);
|
|
47248
|
+
const submissionData = assertJsonValue(
|
|
47249
|
+
await processor.submit(items, context),
|
|
47250
|
+
`submission data for batch ${batchId}`
|
|
47251
|
+
);
|
|
47252
|
+
const externalId = processor.completion.mode === "webhook" ? processor.completion.getExternalId(submissionData, context) : void 0;
|
|
47253
|
+
if (externalId !== void 0 && !externalId.trim()) {
|
|
47254
|
+
throw new Error(`Batch ${batchId} produced an empty externalId`);
|
|
47255
|
+
}
|
|
47256
|
+
const batch = {
|
|
47257
|
+
id: batchId,
|
|
47258
|
+
kind,
|
|
47259
|
+
scorerName: scorerName2,
|
|
47260
|
+
itemIds: records.map((record) => record.id),
|
|
47261
|
+
submissionData,
|
|
47262
|
+
externalId,
|
|
47263
|
+
status: "submitted"
|
|
47264
|
+
};
|
|
47265
|
+
state.batches.push(batch);
|
|
47266
|
+
await writeBatchRecords(store, key, [batch]);
|
|
47267
|
+
}
|
|
47268
|
+
}
|
|
47269
|
+
async function collectBatch(definition, state, batch) {
|
|
47270
|
+
const processor = processorForStage(definition, batch.kind, batch.scorerName);
|
|
47271
|
+
const context = { runId: state.runId, batchId: batch.id };
|
|
47272
|
+
const results = await processor.collect(batch.submissionData, context);
|
|
47273
|
+
if (!Array.isArray(results)) {
|
|
47274
|
+
throw new Error(`collect for batch ${batch.id} must return an array`);
|
|
47275
|
+
}
|
|
47276
|
+
const expectedIds = new Set(batch.itemIds);
|
|
47277
|
+
const seen = /* @__PURE__ */ new Set();
|
|
47278
|
+
const records = [];
|
|
47279
|
+
for (const result of results) {
|
|
47280
|
+
const id = resultItemId(result);
|
|
47281
|
+
if (!expectedIds.has(id)) {
|
|
47282
|
+
throw new Error(`Batch ${batch.id} returned unknown item ${id}`);
|
|
47283
|
+
}
|
|
47284
|
+
if (seen.has(id)) {
|
|
47285
|
+
throw new Error(`Batch ${batch.id} returned item ${id} more than once`);
|
|
47286
|
+
}
|
|
47287
|
+
seen.add(id);
|
|
47288
|
+
const record = state.cases.find((candidate) => candidate.id === id);
|
|
47289
|
+
records.push(record);
|
|
47290
|
+
if (batch.kind === "task") {
|
|
47291
|
+
record.output = assertJsonValue(
|
|
47292
|
+
result.output,
|
|
47293
|
+
`task output for item ${id}`
|
|
47294
|
+
);
|
|
47295
|
+
if ("metadata" in result && result.metadata !== void 0) {
|
|
47296
|
+
record.metadata = assertJsonValue(
|
|
47297
|
+
{
|
|
47298
|
+
...record.metadata,
|
|
47299
|
+
...result.metadata
|
|
47300
|
+
},
|
|
47301
|
+
`metadata for ${id}`
|
|
47302
|
+
);
|
|
47303
|
+
}
|
|
47304
|
+
if ("tags" in result && result.tags !== void 0)
|
|
47305
|
+
record.tags = result.tags;
|
|
47306
|
+
record.taskComplete = true;
|
|
47307
|
+
} else {
|
|
47308
|
+
record.scores[batch.scorerName] = assertJsonValue(
|
|
47309
|
+
result.score,
|
|
47310
|
+
`score output for item ${id}`
|
|
47311
|
+
);
|
|
47312
|
+
}
|
|
47313
|
+
}
|
|
47314
|
+
const missing = batch.itemIds.filter((id) => !seen.has(id));
|
|
47315
|
+
if (missing.length > 0) {
|
|
47316
|
+
throw new Error(
|
|
47317
|
+
`Batch ${batch.id} did not return results for: ${missing.join(", ")}`
|
|
47318
|
+
);
|
|
47319
|
+
}
|
|
47320
|
+
return records;
|
|
47321
|
+
}
|
|
47322
|
+
function processorForStage(definition, kind, scorerName2) {
|
|
47323
|
+
if (kind === "task") {
|
|
47324
|
+
if (!isBatchTask(definition.evaluator.task)) {
|
|
47325
|
+
throw new Error("Definition no longer contains the batch task");
|
|
47326
|
+
}
|
|
47327
|
+
return definition.evaluator.task.processor;
|
|
47328
|
+
}
|
|
47329
|
+
const scorer = resolveScorers(definition.evaluator.scores ?? []).find(
|
|
47330
|
+
({ name }) => name === scorerName2
|
|
47331
|
+
)?.scorer;
|
|
47332
|
+
if (!isBatchScorer(scorer)) {
|
|
47333
|
+
throw new Error(`Definition no longer contains scorer ${scorerName2}`);
|
|
47334
|
+
}
|
|
47335
|
+
return scorer.processor;
|
|
47336
|
+
}
|
|
47337
|
+
async function materializeCases(definition, data, experiment) {
|
|
47338
|
+
const evaluator = definition.evaluator;
|
|
47339
|
+
const iterable = await _internalResolveEvaluatorData(
|
|
47340
|
+
{
|
|
47341
|
+
data,
|
|
47342
|
+
projectName: definition.projectName,
|
|
47343
|
+
projectId: evaluator.projectId,
|
|
47344
|
+
state: evaluator.state
|
|
47345
|
+
},
|
|
47346
|
+
experiment
|
|
47347
|
+
);
|
|
47348
|
+
const records = [];
|
|
47349
|
+
const seen = /* @__PURE__ */ new Set();
|
|
47350
|
+
for await (const datum of iterable) {
|
|
47351
|
+
const caseId = datum.id ?? datum.upsert_id ?? (evaluator.caseId ? await evaluator.caseId(datum) : void 0);
|
|
47352
|
+
if (!caseId) {
|
|
47353
|
+
throw new Error(
|
|
47354
|
+
"Every durable eval case requires id, upsert_id, or caseId"
|
|
47355
|
+
);
|
|
47356
|
+
}
|
|
47357
|
+
if (seen.has(caseId))
|
|
47358
|
+
throw new Error(`Duplicate durable eval case id: ${caseId}`);
|
|
47359
|
+
seen.add(caseId);
|
|
47360
|
+
const trialCount = datum.trialCount ?? evaluator.trialCount ?? 1;
|
|
47361
|
+
if (!Number.isInteger(trialCount) || trialCount < 1) {
|
|
47362
|
+
throw new Error(`Invalid trialCount for durable eval case ${caseId}`);
|
|
47363
|
+
}
|
|
47364
|
+
for (let trialIndex = 0; trialIndex < trialCount; trialIndex++) {
|
|
47365
|
+
records.push({
|
|
47366
|
+
id: `${caseId}:trial:${trialIndex}`,
|
|
47367
|
+
caseId,
|
|
47368
|
+
trialIndex,
|
|
47369
|
+
datum: assertJsonValue(datum, `case ${caseId}`),
|
|
47370
|
+
metadata: assertJsonValue(
|
|
47371
|
+
"metadata" in datum ? datum.metadata : {},
|
|
47372
|
+
`metadata for ${caseId}`
|
|
47373
|
+
),
|
|
47374
|
+
tags: datum.tags,
|
|
47375
|
+
taskComplete: false,
|
|
47376
|
+
taskLogged: false,
|
|
47377
|
+
scores: /* @__PURE__ */ Object.create(null),
|
|
47378
|
+
loggedScores: /* @__PURE__ */ Object.create(null),
|
|
47379
|
+
classifications: /* @__PURE__ */ Object.create(null),
|
|
47380
|
+
loggedClassifications: /* @__PURE__ */ Object.create(null)
|
|
47381
|
+
});
|
|
47382
|
+
}
|
|
47383
|
+
}
|
|
47384
|
+
return records;
|
|
47385
|
+
}
|
|
47386
|
+
function taskBatchItem(record, parameters) {
|
|
47387
|
+
const datum = record.datum;
|
|
47388
|
+
return {
|
|
47389
|
+
id: record.id,
|
|
47390
|
+
input: datum.input,
|
|
47391
|
+
expected: "expected" in datum ? datum.expected : void 0,
|
|
47392
|
+
metadata: record.metadata,
|
|
47393
|
+
tags: record.tags,
|
|
47394
|
+
parameters,
|
|
47395
|
+
trialIndex: record.trialIndex
|
|
47396
|
+
};
|
|
47397
|
+
}
|
|
47398
|
+
function scorerBatchItem(record) {
|
|
47399
|
+
const datum = record.datum;
|
|
47400
|
+
return {
|
|
47401
|
+
id: record.id,
|
|
47402
|
+
input: datum.input,
|
|
47403
|
+
output: record.output,
|
|
47404
|
+
expected: "expected" in datum ? datum.expected : void 0,
|
|
47405
|
+
metadata: record.metadata,
|
|
47406
|
+
tags: record.tags,
|
|
47407
|
+
trialIndex: record.trialIndex
|
|
47408
|
+
};
|
|
47409
|
+
}
|
|
47410
|
+
async function finishExperiment(definition, state, experiment) {
|
|
47411
|
+
const scorerNames = resolveScorers(definition.evaluator.scores ?? []).map(
|
|
47412
|
+
({ name }) => name
|
|
47413
|
+
);
|
|
47414
|
+
const results = state.cases.map((record) => {
|
|
47415
|
+
const datum = record.datum;
|
|
47416
|
+
const scores = Object.fromEntries(
|
|
47417
|
+
scorerNames.flatMap(
|
|
47418
|
+
(name) => Object.entries(
|
|
47419
|
+
_internalPrepareEvaluatorScore(
|
|
47420
|
+
record.scores[name],
|
|
47421
|
+
name
|
|
47422
|
+
).scores ?? {}
|
|
47423
|
+
)
|
|
47424
|
+
)
|
|
47425
|
+
);
|
|
47426
|
+
const classifications = Object.fromEntries(
|
|
47427
|
+
Object.entries(record.classifications).flatMap(
|
|
47428
|
+
([name, value]) => Object.entries(
|
|
47429
|
+
_internalPrepareEvaluatorClassification(value, name).classifications ?? {}
|
|
47430
|
+
)
|
|
47431
|
+
)
|
|
47432
|
+
);
|
|
47433
|
+
return {
|
|
47434
|
+
...datum,
|
|
47435
|
+
output: record.output,
|
|
47436
|
+
metadata: record.metadata,
|
|
47437
|
+
tags: record.tags,
|
|
47438
|
+
scores,
|
|
47439
|
+
error: void 0,
|
|
47440
|
+
...Object.keys(classifications).length > 0 ? { classifications } : {}
|
|
47441
|
+
};
|
|
47442
|
+
});
|
|
47443
|
+
if (!experiment) {
|
|
47444
|
+
return buildLocalSummary(
|
|
47445
|
+
{
|
|
47446
|
+
...definition.evaluator,
|
|
47447
|
+
projectName: definition.projectName,
|
|
47448
|
+
evalName: state.experimentName
|
|
47449
|
+
},
|
|
47450
|
+
results
|
|
47451
|
+
);
|
|
47452
|
+
}
|
|
47453
|
+
await experiment.flush();
|
|
47454
|
+
let comparisonExperimentId = definition.evaluator.baseExperimentId;
|
|
47455
|
+
if (!comparisonExperimentId) {
|
|
47456
|
+
try {
|
|
47457
|
+
comparisonExperimentId = await experiment._getBaseExperimentId();
|
|
47458
|
+
} catch {
|
|
47459
|
+
comparisonExperimentId = void 0;
|
|
47460
|
+
}
|
|
47461
|
+
}
|
|
47462
|
+
return await experiment.summarize({
|
|
47463
|
+
summarizeScores: definition.evaluator.summarizeScores,
|
|
47464
|
+
...comparisonExperimentId ? { comparisonExperimentId } : {}
|
|
47465
|
+
});
|
|
47466
|
+
}
|
|
47467
|
+
function resolveScorers(scorers) {
|
|
47468
|
+
return scorers.map((scorer, index) => ({
|
|
47469
|
+
name: isBatchScorer(scorer) ? scorer.name : scorer.name || `scorer_${index}`,
|
|
47470
|
+
scorer
|
|
47471
|
+
}));
|
|
47472
|
+
}
|
|
47473
|
+
function runKey(projectName, evalName, runId) {
|
|
47474
|
+
return `durable-eval/v1/runs/${contentVersion(encoder.encode(`${projectName}\0${evalName}\0${runId}`))}`;
|
|
47475
|
+
}
|
|
47476
|
+
function encodedKeyPart(value) {
|
|
47477
|
+
return uint8ArrayToBase64(encoder.encode(value)).replaceAll("+", "-").replaceAll("/", "_").replace(/=+$/, "");
|
|
47478
|
+
}
|
|
47479
|
+
function caseRecordKey(key, caseId, kind, ...names) {
|
|
47480
|
+
const suffix = names.map(encodedKeyPart).join("/");
|
|
47481
|
+
return `${key}/cases/${encodedKeyPart(caseId)}/${kind}${suffix ? `/${suffix}` : ""}`;
|
|
47482
|
+
}
|
|
47483
|
+
function batchRecordKey(key, batchId) {
|
|
47484
|
+
return `${key}/batches/${encodedKeyPart(batchId)}`;
|
|
47485
|
+
}
|
|
47486
|
+
function claimRecordKey(key, kind, ...parts) {
|
|
47487
|
+
const identity = stableStringify([kind, parts]);
|
|
47488
|
+
return `${key}/claims/${contentVersion(encoder.encode(identity))}`;
|
|
47489
|
+
}
|
|
47490
|
+
async function claimAction(store, key, kind, ...parts) {
|
|
47491
|
+
return (await store.getOrSet(
|
|
47492
|
+
claimRecordKey(key, kind, ...parts),
|
|
47493
|
+
encoder.encode("claimed")
|
|
47494
|
+
)).created;
|
|
47495
|
+
}
|
|
47496
|
+
function plannedBatches(definition, runId, caseIds) {
|
|
47497
|
+
const stages = [];
|
|
47498
|
+
if (isBatchTask(definition.evaluator.task)) stages.push({ kind: "task" });
|
|
47499
|
+
for (const { name, scorer } of resolveScorers(
|
|
47500
|
+
definition.evaluator.scores ?? []
|
|
47501
|
+
)) {
|
|
47502
|
+
if (isBatchScorer(scorer)) {
|
|
47503
|
+
stages.push({ kind: "score", scorerName: name });
|
|
47504
|
+
}
|
|
47505
|
+
}
|
|
47506
|
+
const plans = [];
|
|
47507
|
+
for (const { kind, scorerName: scorerName2 } of stages) {
|
|
47508
|
+
const batchSize = processorForStage(definition, kind, scorerName2).batchSize ?? DEFAULT_BATCH_SIZE;
|
|
47509
|
+
if (!Number.isInteger(batchSize) || batchSize < 1) {
|
|
47510
|
+
throw new Error(
|
|
47511
|
+
`Invalid batchSize for ${scorerName2 ?? "task"}: ${batchSize}`
|
|
47512
|
+
);
|
|
47513
|
+
}
|
|
47514
|
+
for (let offset = 0; offset < caseIds.length; offset += batchSize) {
|
|
47515
|
+
const itemIds = caseIds.slice(offset, offset + batchSize);
|
|
47516
|
+
plans.push({
|
|
47517
|
+
id: deterministicId(
|
|
47518
|
+
stableStringify([runId, kind, scorerName2, itemIds])
|
|
47519
|
+
),
|
|
47520
|
+
kind,
|
|
47521
|
+
scorerName: scorerName2,
|
|
47522
|
+
itemIds
|
|
47523
|
+
});
|
|
47524
|
+
}
|
|
47525
|
+
}
|
|
47526
|
+
return plans;
|
|
47527
|
+
}
|
|
47528
|
+
async function readCaseRecord(definition, store, key, id) {
|
|
47529
|
+
const scorers = resolveScorers(definition.evaluator.scores ?? []);
|
|
47530
|
+
const classifiers = (definition.evaluator.classifiers ?? []).map(
|
|
47531
|
+
classifierName
|
|
47532
|
+
);
|
|
47533
|
+
const [
|
|
47534
|
+
base,
|
|
47535
|
+
task,
|
|
47536
|
+
taskLog,
|
|
47537
|
+
scoreValues,
|
|
47538
|
+
scoreLogValues,
|
|
47539
|
+
classificationValues,
|
|
47540
|
+
classificationLogValues
|
|
47541
|
+
] = await Promise.all([
|
|
47542
|
+
readJson(store, caseRecordKey(key, id, "base")),
|
|
47543
|
+
readJson(store, caseRecordKey(key, id, "task")),
|
|
47544
|
+
readJson(store, caseRecordKey(key, id, "task-log")),
|
|
47545
|
+
Promise.all(
|
|
47546
|
+
scorers.map(async ({ name }) => ({
|
|
47547
|
+
name,
|
|
47548
|
+
value: await readJson(
|
|
47549
|
+
store,
|
|
47550
|
+
caseRecordKey(key, id, "score", name)
|
|
47551
|
+
)
|
|
47552
|
+
}))
|
|
47553
|
+
),
|
|
47554
|
+
Promise.all(
|
|
47555
|
+
scorers.map(async ({ name }) => ({
|
|
47556
|
+
name,
|
|
47557
|
+
value: await readJson(
|
|
47558
|
+
store,
|
|
47559
|
+
caseRecordKey(key, id, "score-log", name)
|
|
47560
|
+
)
|
|
47561
|
+
}))
|
|
47562
|
+
),
|
|
47563
|
+
Promise.all(
|
|
47564
|
+
classifiers.map(async (name) => ({
|
|
47565
|
+
name,
|
|
47566
|
+
value: await readJson(
|
|
47567
|
+
store,
|
|
47568
|
+
caseRecordKey(key, id, "classification", name)
|
|
47569
|
+
)
|
|
47570
|
+
}))
|
|
47571
|
+
),
|
|
47572
|
+
Promise.all(
|
|
47573
|
+
classifiers.map(async (name) => ({
|
|
47574
|
+
name,
|
|
47575
|
+
value: await readJson(
|
|
47576
|
+
store,
|
|
47577
|
+
caseRecordKey(key, id, "classification-log", name)
|
|
47578
|
+
)
|
|
47579
|
+
}))
|
|
47580
|
+
)
|
|
47581
|
+
]);
|
|
47582
|
+
if (!base) throw new Error(`Durable eval case ${id} is missing`);
|
|
47583
|
+
const scores = /* @__PURE__ */ Object.create(null);
|
|
47584
|
+
for (const { name, value } of scoreValues) {
|
|
47585
|
+
if (value !== void 0) scores[name] = value;
|
|
47586
|
+
}
|
|
47587
|
+
const loggedScores = /* @__PURE__ */ Object.create(null);
|
|
47588
|
+
for (const { name, value } of scoreLogValues) {
|
|
47589
|
+
if (value) loggedScores[name] = true;
|
|
47590
|
+
}
|
|
47591
|
+
const classifications = /* @__PURE__ */ Object.create(null);
|
|
47592
|
+
for (const { name, value } of classificationValues) {
|
|
47593
|
+
if (value !== void 0) classifications[name] = value;
|
|
47594
|
+
}
|
|
47595
|
+
const loggedClassifications = /* @__PURE__ */ Object.create(null);
|
|
47596
|
+
for (const { name, value } of classificationLogValues) {
|
|
47597
|
+
if (value) loggedClassifications[name] = true;
|
|
47598
|
+
}
|
|
47599
|
+
return {
|
|
47600
|
+
...base,
|
|
47601
|
+
metadata: task?.metadata ?? base.metadata,
|
|
47602
|
+
tags: task ? task.tags : base.tags,
|
|
47603
|
+
taskComplete: task !== void 0,
|
|
47604
|
+
taskLogged: taskLog !== void 0,
|
|
47605
|
+
output: task?.output,
|
|
47606
|
+
rootSpan: taskLog?.rootSpan,
|
|
47607
|
+
scores,
|
|
47608
|
+
loggedScores,
|
|
47609
|
+
classifications,
|
|
47610
|
+
loggedClassifications
|
|
47611
|
+
};
|
|
47612
|
+
}
|
|
47613
|
+
async function readRunState(definition, store, key) {
|
|
47614
|
+
const record = await readJson(store, key);
|
|
47615
|
+
if (!record) return void 0;
|
|
47616
|
+
const plans = plannedBatches(definition, record.runId, record.caseIds);
|
|
47617
|
+
const [cases, batchRecords] = await Promise.all([
|
|
47618
|
+
Promise.all(
|
|
47619
|
+
record.caseIds.map((id) => readCaseRecord(definition, store, key, id))
|
|
47620
|
+
),
|
|
47621
|
+
Promise.all(
|
|
47622
|
+
plans.map(async ({ id }) => {
|
|
47623
|
+
return readJson(store, batchRecordKey(key, id));
|
|
47624
|
+
})
|
|
47625
|
+
)
|
|
47626
|
+
]);
|
|
47627
|
+
const batches = batchRecords.filter(
|
|
47628
|
+
(value) => value !== void 0
|
|
47629
|
+
);
|
|
47630
|
+
const { caseIds: _caseIds, ...state } = record;
|
|
47631
|
+
return { ...state, cases, batches };
|
|
47632
|
+
}
|
|
47633
|
+
async function writeRunRecord(store, key, state) {
|
|
47634
|
+
const { cases, batches: _batches, ...record } = state;
|
|
47635
|
+
await writeJson(store, key, {
|
|
47636
|
+
...record,
|
|
47637
|
+
caseIds: cases.map(({ id }) => id)
|
|
47638
|
+
});
|
|
47639
|
+
}
|
|
47640
|
+
async function writeCaseBaseRecords(store, key, records) {
|
|
47641
|
+
await Promise.all(
|
|
47642
|
+
records.map(
|
|
47643
|
+
({ id, caseId, trialIndex, datum, metadata, tags }) => writeJson(store, caseRecordKey(key, id, "base"), {
|
|
47644
|
+
id,
|
|
47645
|
+
caseId,
|
|
47646
|
+
trialIndex,
|
|
47647
|
+
datum,
|
|
47648
|
+
metadata,
|
|
47649
|
+
tags
|
|
47650
|
+
})
|
|
47651
|
+
)
|
|
47652
|
+
);
|
|
47653
|
+
}
|
|
47654
|
+
async function writeCaseRecords(store, key, records) {
|
|
47655
|
+
const writes = [];
|
|
47656
|
+
for (const record of records) {
|
|
47657
|
+
if (record.taskComplete) {
|
|
47658
|
+
writes.push(
|
|
47659
|
+
writeJson(store, caseRecordKey(key, record.id, "task"), {
|
|
47660
|
+
output: record.output,
|
|
47661
|
+
metadata: record.metadata,
|
|
47662
|
+
tags: record.tags,
|
|
47663
|
+
taskComplete: true
|
|
47664
|
+
})
|
|
47665
|
+
);
|
|
47666
|
+
}
|
|
47667
|
+
if (record.taskLogged) {
|
|
47668
|
+
writes.push(
|
|
47669
|
+
writeJson(store, caseRecordKey(key, record.id, "task-log"), {
|
|
47670
|
+
rootSpan: record.rootSpan,
|
|
47671
|
+
taskLogged: true
|
|
47672
|
+
})
|
|
47673
|
+
);
|
|
47674
|
+
}
|
|
47675
|
+
for (const [name, value] of Object.entries(record.scores)) {
|
|
47676
|
+
writes.push(
|
|
47677
|
+
writeJson(store, caseRecordKey(key, record.id, "score", name), value)
|
|
47678
|
+
);
|
|
47679
|
+
}
|
|
47680
|
+
for (const name of Object.keys(record.loggedScores)) {
|
|
47681
|
+
writes.push(
|
|
47682
|
+
writeJson(
|
|
47683
|
+
store,
|
|
47684
|
+
caseRecordKey(key, record.id, "score-log", name),
|
|
47685
|
+
true
|
|
47686
|
+
)
|
|
47687
|
+
);
|
|
47688
|
+
}
|
|
47689
|
+
for (const [name, value] of Object.entries(record.classifications)) {
|
|
47690
|
+
writes.push(
|
|
47691
|
+
writeJson(
|
|
47692
|
+
store,
|
|
47693
|
+
caseRecordKey(key, record.id, "classification", name),
|
|
47694
|
+
value
|
|
47695
|
+
)
|
|
47696
|
+
);
|
|
47697
|
+
}
|
|
47698
|
+
for (const name of Object.keys(record.loggedClassifications)) {
|
|
47699
|
+
writes.push(
|
|
47700
|
+
writeJson(
|
|
47701
|
+
store,
|
|
47702
|
+
caseRecordKey(key, record.id, "classification-log", name),
|
|
47703
|
+
true
|
|
47704
|
+
)
|
|
47705
|
+
);
|
|
47706
|
+
}
|
|
47707
|
+
}
|
|
47708
|
+
await Promise.all(writes);
|
|
47709
|
+
}
|
|
47710
|
+
async function writeBatchRecords(store, key, records) {
|
|
47711
|
+
await Promise.all(
|
|
47712
|
+
records.map(
|
|
47713
|
+
(record) => writeJson(store, batchRecordKey(key, record.id), record)
|
|
47714
|
+
)
|
|
47715
|
+
);
|
|
47716
|
+
}
|
|
47717
|
+
function deterministicId(value) {
|
|
47718
|
+
const hex = contentVersion(encoder.encode(value)).padEnd(32, "0").slice(0, 32);
|
|
47719
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-5${hex.slice(13, 16)}-a${hex.slice(17, 20)}-${hex.slice(20, 32)}`;
|
|
47720
|
+
}
|
|
47721
|
+
function contentVersion(value) {
|
|
47722
|
+
if (isomorph_default.hash) return isomorph_default.hash(decoder.decode(value));
|
|
47723
|
+
let hash = 2166136261;
|
|
47724
|
+
for (const byte of value) {
|
|
47725
|
+
hash ^= byte;
|
|
47726
|
+
hash = Math.imul(hash, 16777619);
|
|
47727
|
+
}
|
|
47728
|
+
return (hash >>> 0).toString(16).padStart(8, "0");
|
|
47729
|
+
}
|
|
47730
|
+
async function readJson(store, key) {
|
|
47731
|
+
const value = await store.read(key);
|
|
47732
|
+
return value ? JSON.parse(decoder.decode(value)) : void 0;
|
|
47733
|
+
}
|
|
47734
|
+
async function writeJson(store, key, value) {
|
|
47735
|
+
await store.write(key, encoder.encode(stableStringify(value)));
|
|
47736
|
+
}
|
|
47737
|
+
function stableStringify(value) {
|
|
47738
|
+
return JSON.stringify(value, (_key, nested) => {
|
|
47739
|
+
if (nested && typeof nested === "object" && !Array.isArray(nested)) {
|
|
47740
|
+
return Object.fromEntries(
|
|
47741
|
+
Object.entries(nested).sort(
|
|
47742
|
+
([left], [right]) => left.localeCompare(right)
|
|
47743
|
+
)
|
|
47744
|
+
);
|
|
47745
|
+
}
|
|
47746
|
+
return nested;
|
|
47747
|
+
});
|
|
47748
|
+
}
|
|
47749
|
+
function assertJsonValue(value, label) {
|
|
47750
|
+
try {
|
|
47751
|
+
const serialized = JSON.stringify(value);
|
|
47752
|
+
if (serialized === void 0)
|
|
47753
|
+
throw new Error("value serializes to undefined");
|
|
47754
|
+
return JSON.parse(serialized);
|
|
47755
|
+
} catch (error) {
|
|
47756
|
+
throw new Error(`${label} must be JSON serializable`, { cause: error });
|
|
47757
|
+
}
|
|
47758
|
+
}
|
|
47759
|
+
function resultItemId(value) {
|
|
47760
|
+
if (typeof value !== "object" || value === null || !("id" in value) || typeof value.id !== "string") {
|
|
47761
|
+
throw new Error("Batch results must contain a string id");
|
|
47762
|
+
}
|
|
47763
|
+
return value.id;
|
|
47764
|
+
}
|
|
47765
|
+
function isBatchTask(value) {
|
|
47766
|
+
return typeof value === "object" && value !== null && "kind" in value && value.kind === BATCH_TASK_KIND;
|
|
47767
|
+
}
|
|
47768
|
+
function isBatchScorer(value) {
|
|
47769
|
+
return typeof value === "object" && value !== null && "kind" in value && value.kind === BATCH_SCORER_KIND;
|
|
47770
|
+
}
|
|
47771
|
+
function asError(error) {
|
|
47772
|
+
return error instanceof Error ? error : new Error(String(error));
|
|
47773
|
+
}
|
|
47774
|
+
|
|
45764
47775
|
// src/agent-assertions.ts
|
|
45765
47776
|
function agentAssertionScorer(callback, options = {}) {
|
|
45766
47777
|
return async (args) => {
|
|
@@ -46693,6 +48704,8 @@ export {
|
|
|
46693
48704
|
BRAINTRUST_PARENT_KEY,
|
|
46694
48705
|
BaseAttachment,
|
|
46695
48706
|
BaseExperiment,
|
|
48707
|
+
BatchScorer,
|
|
48708
|
+
BatchTask,
|
|
46696
48709
|
BraintrustLangChainCallbackHandler,
|
|
46697
48710
|
BraintrustMiddleware,
|
|
46698
48711
|
BraintrustObservabilityExporter,
|
|
@@ -46706,6 +48719,8 @@ export {
|
|
|
46706
48719
|
DEFAULT_MAX_REQUEST_SIZE,
|
|
46707
48720
|
Dataset2 as Dataset,
|
|
46708
48721
|
DatasetPipeline,
|
|
48722
|
+
DurableEvalMemoryStore,
|
|
48723
|
+
DurableEvalRedisStore,
|
|
46709
48724
|
ERR_PERMALINK,
|
|
46710
48725
|
Eval,
|
|
46711
48726
|
EvalResultWithSummary,
|
|
@@ -46764,6 +48779,7 @@ export {
|
|
|
46764
48779
|
deepCopyEvent,
|
|
46765
48780
|
exports_exports as default,
|
|
46766
48781
|
defaultErrorScoreHandler,
|
|
48782
|
+
defineDurableEval,
|
|
46767
48783
|
deserializePlainStringAsJSON,
|
|
46768
48784
|
devNullWritableStream,
|
|
46769
48785
|
evaluatorDefinitionSchema,
|
|
@@ -46859,5 +48875,6 @@ export {
|
|
|
46859
48875
|
wrapPiCodingAgentSDK,
|
|
46860
48876
|
wrapStrandsAgentSDK,
|
|
46861
48877
|
wrapTraced,
|
|
46862
|
-
wrapVitest
|
|
48878
|
+
wrapVitest,
|
|
48879
|
+
wrapVoyageAI
|
|
46863
48880
|
};
|