braintrust 3.16.0 → 3.18.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/bin/bt +41 -0
- package/dev/dist/index.d.mts +13 -0
- package/dev/dist/index.d.ts +13 -0
- package/dev/dist/index.js +4300 -2199
- package/dev/dist/index.mjs +2211 -110
- package/dist/apply-auto-instrumentation.js +238 -186
- package/dist/apply-auto-instrumentation.mjs +68 -16
- package/dist/auto-instrumentations/bundler/esbuild.cjs +90 -15
- package/dist/auto-instrumentations/bundler/esbuild.mjs +2 -2
- package/dist/auto-instrumentations/bundler/next.cjs +90 -15
- package/dist/auto-instrumentations/bundler/next.mjs +3 -3
- package/dist/auto-instrumentations/bundler/rollup.cjs +90 -15
- package/dist/auto-instrumentations/bundler/rollup.mjs +2 -2
- package/dist/auto-instrumentations/bundler/vite.cjs +90 -15
- package/dist/auto-instrumentations/bundler/vite.mjs +2 -2
- package/dist/auto-instrumentations/bundler/webpack-loader.cjs +89 -14
- package/dist/auto-instrumentations/bundler/webpack.cjs +90 -15
- package/dist/auto-instrumentations/bundler/webpack.mjs +3 -3
- package/dist/auto-instrumentations/{chunk-VXJONZVX.mjs → chunk-GNUEZ2PE.mjs} +13 -3
- package/dist/auto-instrumentations/{chunk-CNQ7BUKN.mjs → chunk-MYCHHXOE.mjs} +1 -1
- package/dist/auto-instrumentations/{chunk-E5DUYJWK.mjs → chunk-ZYKZEMRT.mjs} +82 -15
- package/dist/auto-instrumentations/hook.mjs +102 -15
- package/dist/auto-instrumentations/index.cjs +84 -16
- package/dist/auto-instrumentations/index.d.mts +3 -1
- package/dist/auto-instrumentations/index.d.ts +3 -1
- package/dist/auto-instrumentations/index.mjs +5 -3
- package/dist/auto-instrumentations/loader/cjs-patch.cjs +1 -1
- package/dist/auto-instrumentations/loader/cjs-patch.mjs +1 -1
- package/dist/auto-instrumentations/loader/esm-hook.mjs +1 -1
- package/dist/browser.d.mts +177 -11
- package/dist/browser.d.ts +177 -11
- package/dist/browser.js +2296 -104
- package/dist/browser.mjs +2455 -263
- package/dist/{chunk-VMBQETG3.js → chunk-73IYIIOL.js} +28 -2
- package/dist/{chunk-O4ZIWXO3.mjs → chunk-BYFADLEZ.mjs} +27 -1
- package/dist/cli.js +2228 -113
- package/dist/edge-light.d.mts +1 -1
- package/dist/edge-light.d.ts +1 -1
- package/dist/edge-light.js +2296 -104
- package/dist/edge-light.mjs +2455 -263
- package/dist/index.d.mts +177 -11
- package/dist/index.d.ts +177 -11
- package/dist/index.js +3296 -1128
- package/dist/index.mjs +2272 -104
- package/dist/instrumentation/index.d.mts +3 -0
- package/dist/instrumentation/index.d.ts +3 -0
- package/dist/instrumentation/index.js +2171 -105
- package/dist/instrumentation/index.mjs +2171 -105
- package/dist/workerd.d.mts +1 -1
- package/dist/workerd.d.ts +1 -1
- package/dist/workerd.js +2296 -104
- package/dist/workerd.mjs +2455 -263
- package/package.json +19 -5
- package/scripts/bt-helper.js +139 -0
- package/scripts/install.js +153 -0
package/dist/browser.js
CHANGED
|
@@ -86,6 +86,7 @@ __export(browser_exports, {
|
|
|
86
86
|
_internalIso: () => isomorph_default,
|
|
87
87
|
_internalSetInitialState: () => _internalSetInitialState,
|
|
88
88
|
addAzureBlobHeaders: () => addAzureBlobHeaders,
|
|
89
|
+
braintrustAISDKTelemetry: () => braintrustAISDKTelemetry,
|
|
89
90
|
braintrustFlueObserver: () => braintrustFlueObserver,
|
|
90
91
|
braintrustStreamChunkSchema: () => braintrustStreamChunkSchema,
|
|
91
92
|
buildLocalSummary: () => buildLocalSummary,
|
|
@@ -179,6 +180,7 @@ __export(browser_exports, {
|
|
|
179
180
|
wrapOpenAIv4: () => wrapOpenAIv4,
|
|
180
181
|
wrapOpenRouter: () => wrapOpenRouter,
|
|
181
182
|
wrapOpenRouterAgent: () => wrapOpenRouterAgent,
|
|
183
|
+
wrapPiCodingAgentSDK: () => wrapPiCodingAgentSDK,
|
|
182
184
|
wrapTraced: () => wrapTraced,
|
|
183
185
|
wrapVitest: () => wrapVitest
|
|
184
186
|
});
|
|
@@ -5135,14 +5137,18 @@ function useTestBackgroundLogger() {
|
|
|
5135
5137
|
function clearTestBackgroundLogger() {
|
|
5136
5138
|
_internalGetGlobalState()?.setOverrideBgLogger(null);
|
|
5137
5139
|
}
|
|
5138
|
-
function initTestExperiment(experimentName, projectName) {
|
|
5140
|
+
function initTestExperiment(experimentName, projectName, experimentFullInfo = {}) {
|
|
5139
5141
|
setInitialTestState();
|
|
5140
5142
|
const state = _internalGetGlobalState();
|
|
5141
5143
|
const project = projectName ?? experimentName;
|
|
5142
5144
|
const lazyMetadata = new LazyValue(
|
|
5143
5145
|
async () => ({
|
|
5144
5146
|
project: { id: project, name: project, fullInfo: {} },
|
|
5145
|
-
experiment: {
|
|
5147
|
+
experiment: {
|
|
5148
|
+
id: experimentName,
|
|
5149
|
+
name: experimentName,
|
|
5150
|
+
fullInfo: experimentFullInfo
|
|
5151
|
+
}
|
|
5146
5152
|
})
|
|
5147
5153
|
);
|
|
5148
5154
|
return new Experiment2(state, lazyMetadata);
|
|
@@ -8507,6 +8513,10 @@ var Experiment2 = class extends ObjectFetcher {
|
|
|
8507
8513
|
return (await this.lazyMetadata.get()).project;
|
|
8508
8514
|
})();
|
|
8509
8515
|
}
|
|
8516
|
+
async _getBaseExperimentId() {
|
|
8517
|
+
const baseExperimentId = (await this.lazyMetadata.get()).experiment.fullInfo["base_exp_id"];
|
|
8518
|
+
return typeof baseExperimentId === "string" && baseExperimentId ? baseExperimentId : void 0;
|
|
8519
|
+
}
|
|
8510
8520
|
parentObjectType() {
|
|
8511
8521
|
return 1 /* EXPERIMENT */;
|
|
8512
8522
|
}
|
|
@@ -8647,6 +8657,14 @@ var Experiment2 = class extends ObjectFetcher {
|
|
|
8647
8657
|
comparisonExperimentId = baseExperiment.id;
|
|
8648
8658
|
comparisonExperimentName = baseExperiment.name;
|
|
8649
8659
|
}
|
|
8660
|
+
} else {
|
|
8661
|
+
try {
|
|
8662
|
+
const comparisonExperiment = await state.apiConn().get_json(`v1/experiment/${comparisonExperimentId}`);
|
|
8663
|
+
if (typeof comparisonExperiment["name"] === "string") {
|
|
8664
|
+
comparisonExperimentName = comparisonExperiment["name"];
|
|
8665
|
+
}
|
|
8666
|
+
} catch {
|
|
8667
|
+
}
|
|
8650
8668
|
}
|
|
8651
8669
|
try {
|
|
8652
8670
|
const results = await state.apiConn().get_json(
|
|
@@ -10688,6 +10706,64 @@ var BasePlugin = class {
|
|
|
10688
10706
|
}
|
|
10689
10707
|
};
|
|
10690
10708
|
|
|
10709
|
+
// src/instrumentation/auto-instrumentation-suppression.ts
|
|
10710
|
+
var autoInstrumentationSuppressionStore;
|
|
10711
|
+
function suppressionStore() {
|
|
10712
|
+
autoInstrumentationSuppressionStore ??= isomorph_default.newAsyncLocalStorage();
|
|
10713
|
+
return autoInstrumentationSuppressionStore;
|
|
10714
|
+
}
|
|
10715
|
+
function currentFrames() {
|
|
10716
|
+
return suppressionStore().getStore()?.frames ?? [];
|
|
10717
|
+
}
|
|
10718
|
+
function isAutoInstrumentationSuppressed() {
|
|
10719
|
+
const frames = currentFrames();
|
|
10720
|
+
return frames[frames.length - 1]?.mode === "suppress";
|
|
10721
|
+
}
|
|
10722
|
+
function runWithAutoInstrumentationSuppressed(callback) {
|
|
10723
|
+
const frame = {
|
|
10724
|
+
id: /* @__PURE__ */ Symbol("braintrust.auto-instrumentation-suppress"),
|
|
10725
|
+
mode: "suppress"
|
|
10726
|
+
};
|
|
10727
|
+
return suppressionStore().run(
|
|
10728
|
+
{ frames: [...currentFrames(), frame] },
|
|
10729
|
+
callback
|
|
10730
|
+
);
|
|
10731
|
+
}
|
|
10732
|
+
function bindAutoInstrumentationSuppressionToStart(tracingChannel2) {
|
|
10733
|
+
const startChannel = tracingChannel2.start;
|
|
10734
|
+
if (!startChannel) {
|
|
10735
|
+
return void 0;
|
|
10736
|
+
}
|
|
10737
|
+
const store = suppressionStore();
|
|
10738
|
+
startChannel.bindStore(store, () => ({
|
|
10739
|
+
frames: [
|
|
10740
|
+
...currentFrames(),
|
|
10741
|
+
{
|
|
10742
|
+
id: /* @__PURE__ */ Symbol("braintrust.auto-instrumentation-suppress"),
|
|
10743
|
+
mode: "suppress"
|
|
10744
|
+
}
|
|
10745
|
+
]
|
|
10746
|
+
}));
|
|
10747
|
+
return () => {
|
|
10748
|
+
startChannel.unbindStore(store);
|
|
10749
|
+
};
|
|
10750
|
+
}
|
|
10751
|
+
function enterAutoInstrumentationAllowed() {
|
|
10752
|
+
const frame = {
|
|
10753
|
+
id: /* @__PURE__ */ Symbol("braintrust.auto-instrumentation-allow"),
|
|
10754
|
+
mode: "allow"
|
|
10755
|
+
};
|
|
10756
|
+
suppressionStore().enterWith({
|
|
10757
|
+
frames: [...currentFrames(), frame]
|
|
10758
|
+
});
|
|
10759
|
+
return () => {
|
|
10760
|
+
const frames = currentFrames().filter(
|
|
10761
|
+
(candidate) => candidate.id !== frame.id
|
|
10762
|
+
);
|
|
10763
|
+
suppressionStore().enterWith(frames.length > 0 ? { frames } : void 0);
|
|
10764
|
+
};
|
|
10765
|
+
}
|
|
10766
|
+
|
|
10691
10767
|
// src/instrumentation/core/channel-tracing.ts
|
|
10692
10768
|
function isSyncStreamLike(value) {
|
|
10693
10769
|
return !!value && typeof value === "object" && typeof value.on === "function";
|
|
@@ -10719,16 +10795,33 @@ function startSpanForEvent(config, event, channelName) {
|
|
|
10719
10795
|
metadata: mergeInputMetadata(metadata, spanInfoMetadata)
|
|
10720
10796
|
});
|
|
10721
10797
|
} catch (error) {
|
|
10722
|
-
|
|
10798
|
+
debugLogger.error(`Error extracting input for ${channelName}:`, error);
|
|
10723
10799
|
}
|
|
10724
10800
|
return { span, startTime };
|
|
10725
10801
|
}
|
|
10802
|
+
function shouldTraceEvent(config, event, channelName) {
|
|
10803
|
+
if (!config.shouldTrace) {
|
|
10804
|
+
return true;
|
|
10805
|
+
}
|
|
10806
|
+
try {
|
|
10807
|
+
return config.shouldTrace(event.arguments, event);
|
|
10808
|
+
} catch (error) {
|
|
10809
|
+
debugLogger.error(
|
|
10810
|
+
`Error checking trace predicate for ${channelName}:`,
|
|
10811
|
+
error
|
|
10812
|
+
);
|
|
10813
|
+
return true;
|
|
10814
|
+
}
|
|
10815
|
+
}
|
|
10726
10816
|
function ensureSpanStateForEvent(states, config, event, channelName) {
|
|
10727
10817
|
const key = event;
|
|
10728
10818
|
const existing = states.get(key);
|
|
10729
10819
|
if (existing) {
|
|
10730
10820
|
return existing;
|
|
10731
10821
|
}
|
|
10822
|
+
if (!shouldTraceEvent(config, event, channelName)) {
|
|
10823
|
+
return void 0;
|
|
10824
|
+
}
|
|
10732
10825
|
const created = startSpanForEvent(config, event, channelName);
|
|
10733
10826
|
states.set(key, created);
|
|
10734
10827
|
return created;
|
|
@@ -10744,13 +10837,16 @@ function bindCurrentSpanStoreToStart(tracingChannel2, states, config, channelNam
|
|
|
10744
10837
|
startChannel.bindStore(
|
|
10745
10838
|
currentSpanStore,
|
|
10746
10839
|
(event) => {
|
|
10747
|
-
|
|
10840
|
+
if (isAutoInstrumentationSuppressed()) {
|
|
10841
|
+
return currentSpanStore.getStore();
|
|
10842
|
+
}
|
|
10843
|
+
const spanState = ensureSpanStateForEvent(
|
|
10748
10844
|
states,
|
|
10749
10845
|
config,
|
|
10750
10846
|
event,
|
|
10751
10847
|
channelName
|
|
10752
|
-
)
|
|
10753
|
-
return contextManager.wrapSpanForStore(span);
|
|
10848
|
+
);
|
|
10849
|
+
return spanState ? contextManager.wrapSpanForStore(spanState.span) : currentSpanStore.getStore();
|
|
10754
10850
|
}
|
|
10755
10851
|
);
|
|
10756
10852
|
return () => {
|
|
@@ -10785,7 +10881,10 @@ function runStreamingCompletionHook(args) {
|
|
|
10785
10881
|
startTime: args.startTime
|
|
10786
10882
|
});
|
|
10787
10883
|
} catch (error) {
|
|
10788
|
-
|
|
10884
|
+
debugLogger.error(
|
|
10885
|
+
`Error in onComplete hook for ${args.channelName}:`,
|
|
10886
|
+
error
|
|
10887
|
+
);
|
|
10789
10888
|
}
|
|
10790
10889
|
}
|
|
10791
10890
|
function traceAsyncChannel(channel2, config) {
|
|
@@ -10800,6 +10899,9 @@ function traceAsyncChannel(channel2, config) {
|
|
|
10800
10899
|
);
|
|
10801
10900
|
const handlers = {
|
|
10802
10901
|
start: (event) => {
|
|
10902
|
+
if (isAutoInstrumentationSuppressed()) {
|
|
10903
|
+
return;
|
|
10904
|
+
}
|
|
10803
10905
|
ensureSpanStateForEvent(
|
|
10804
10906
|
states,
|
|
10805
10907
|
config,
|
|
@@ -10834,7 +10936,7 @@ function traceAsyncChannel(channel2, config) {
|
|
|
10834
10936
|
metrics
|
|
10835
10937
|
});
|
|
10836
10938
|
} catch (error) {
|
|
10837
|
-
|
|
10939
|
+
debugLogger.error(`Error extracting output for ${channelName}:`, error);
|
|
10838
10940
|
} finally {
|
|
10839
10941
|
span.end();
|
|
10840
10942
|
states.delete(event);
|
|
@@ -10862,6 +10964,9 @@ function traceStreamingChannel(channel2, config) {
|
|
|
10862
10964
|
);
|
|
10863
10965
|
const handlers = {
|
|
10864
10966
|
start: (event) => {
|
|
10967
|
+
if (isAutoInstrumentationSuppressed()) {
|
|
10968
|
+
return;
|
|
10969
|
+
}
|
|
10865
10970
|
ensureSpanStateForEvent(
|
|
10866
10971
|
states,
|
|
10867
10972
|
config,
|
|
@@ -10933,7 +11038,7 @@ function traceStreamingChannel(channel2, config) {
|
|
|
10933
11038
|
metrics
|
|
10934
11039
|
});
|
|
10935
11040
|
} catch (error) {
|
|
10936
|
-
|
|
11041
|
+
debugLogger.error(
|
|
10937
11042
|
`Error extracting output for ${channelName}:`,
|
|
10938
11043
|
error
|
|
10939
11044
|
);
|
|
@@ -10993,7 +11098,7 @@ function traceStreamingChannel(channel2, config) {
|
|
|
10993
11098
|
metrics
|
|
10994
11099
|
});
|
|
10995
11100
|
} catch (error) {
|
|
10996
|
-
|
|
11101
|
+
debugLogger.error(`Error extracting output for ${channelName}:`, error);
|
|
10997
11102
|
} finally {
|
|
10998
11103
|
span.end();
|
|
10999
11104
|
states.delete(event);
|
|
@@ -11021,6 +11126,9 @@ function traceSyncStreamChannel(channel2, config) {
|
|
|
11021
11126
|
);
|
|
11022
11127
|
const handlers = {
|
|
11023
11128
|
start: (event) => {
|
|
11129
|
+
if (isAutoInstrumentationSuppressed()) {
|
|
11130
|
+
return;
|
|
11131
|
+
}
|
|
11024
11132
|
ensureSpanStateForEvent(
|
|
11025
11133
|
states,
|
|
11026
11134
|
config,
|
|
@@ -11074,7 +11182,7 @@ function traceSyncStreamChannel(channel2, config) {
|
|
|
11074
11182
|
});
|
|
11075
11183
|
}
|
|
11076
11184
|
} catch (error) {
|
|
11077
|
-
|
|
11185
|
+
debugLogger.error(
|
|
11078
11186
|
`Error extracting chatCompletion for ${channelName}:`,
|
|
11079
11187
|
error
|
|
11080
11188
|
);
|
|
@@ -11098,7 +11206,10 @@ function traceSyncStreamChannel(channel2, config) {
|
|
|
11098
11206
|
span.log(extracted);
|
|
11099
11207
|
}
|
|
11100
11208
|
} catch (error) {
|
|
11101
|
-
|
|
11209
|
+
debugLogger.error(
|
|
11210
|
+
`Error extracting event for ${channelName}:`,
|
|
11211
|
+
error
|
|
11212
|
+
);
|
|
11102
11213
|
}
|
|
11103
11214
|
});
|
|
11104
11215
|
stream.on("end", () => {
|
|
@@ -12627,6 +12738,9 @@ var AnthropicPlugin = class extends BasePlugin {
|
|
|
12627
12738
|
const states = /* @__PURE__ */ new WeakMap();
|
|
12628
12739
|
const handlers = {
|
|
12629
12740
|
start: (event) => {
|
|
12741
|
+
if (isAutoInstrumentationSuppressed()) {
|
|
12742
|
+
return;
|
|
12743
|
+
}
|
|
12630
12744
|
const params = event.arguments[0] ?? {};
|
|
12631
12745
|
const span = startSpan({
|
|
12632
12746
|
name: "anthropic.beta.messages.toolRunner",
|
|
@@ -13356,6 +13470,520 @@ function serializeAISDKToolsForLogging(tools) {
|
|
|
13356
13470
|
return serialized;
|
|
13357
13471
|
}
|
|
13358
13472
|
|
|
13473
|
+
// src/wrappers/ai-sdk/telemetry.ts
|
|
13474
|
+
function braintrustAISDKTelemetry() {
|
|
13475
|
+
const operations = /* @__PURE__ */ new Map();
|
|
13476
|
+
const modelSpans = /* @__PURE__ */ new Map();
|
|
13477
|
+
const objectSpans = /* @__PURE__ */ new Map();
|
|
13478
|
+
const embedSpans = /* @__PURE__ */ new Map();
|
|
13479
|
+
const rerankSpans = /* @__PURE__ */ new Map();
|
|
13480
|
+
const toolSpans = /* @__PURE__ */ new Map();
|
|
13481
|
+
const runSafely = (name, callback) => {
|
|
13482
|
+
try {
|
|
13483
|
+
callback();
|
|
13484
|
+
} catch (error) {
|
|
13485
|
+
console.error(`Error in Braintrust AI SDK telemetry ${name}:`, error);
|
|
13486
|
+
}
|
|
13487
|
+
};
|
|
13488
|
+
const startChildSpan = (callId, name, type, event) => {
|
|
13489
|
+
const parent = operations.get(callId)?.span;
|
|
13490
|
+
const spanArgs = {
|
|
13491
|
+
name,
|
|
13492
|
+
spanAttributes: { type },
|
|
13493
|
+
...event ? { event } : {}
|
|
13494
|
+
};
|
|
13495
|
+
const span = parent ? parent.startSpan(spanArgs) : startSpan(spanArgs);
|
|
13496
|
+
const state = operations.get(callId);
|
|
13497
|
+
if (state && type === "llm" /* LLM */) {
|
|
13498
|
+
state.hadModelChild = true;
|
|
13499
|
+
}
|
|
13500
|
+
return span;
|
|
13501
|
+
};
|
|
13502
|
+
return {
|
|
13503
|
+
onStart(event) {
|
|
13504
|
+
runSafely("onStart", () => {
|
|
13505
|
+
const operationName = operationNameFromId(event.operationId);
|
|
13506
|
+
const span = startSpan({
|
|
13507
|
+
name: operationName,
|
|
13508
|
+
spanAttributes: { type: "function" /* FUNCTION */ }
|
|
13509
|
+
});
|
|
13510
|
+
operations.set(event.callId, {
|
|
13511
|
+
hadModelChild: false,
|
|
13512
|
+
operationName,
|
|
13513
|
+
span,
|
|
13514
|
+
startTime: getCurrentUnixTimestamp()
|
|
13515
|
+
});
|
|
13516
|
+
const metadata = metadataFromEvent(event);
|
|
13517
|
+
const logPayload = { metadata };
|
|
13518
|
+
if (shouldRecordInputs(event)) {
|
|
13519
|
+
const { input, outputPromise } = processAISDKCallInput(
|
|
13520
|
+
operationInput(event, operationName)
|
|
13521
|
+
);
|
|
13522
|
+
logPayload.input = input;
|
|
13523
|
+
if (outputPromise && input && typeof input === "object") {
|
|
13524
|
+
outputPromise.then((resolvedData) => {
|
|
13525
|
+
span.log({
|
|
13526
|
+
input: {
|
|
13527
|
+
...input,
|
|
13528
|
+
...resolvedData
|
|
13529
|
+
}
|
|
13530
|
+
});
|
|
13531
|
+
}).catch(() => {
|
|
13532
|
+
});
|
|
13533
|
+
}
|
|
13534
|
+
}
|
|
13535
|
+
span.log(logPayload);
|
|
13536
|
+
});
|
|
13537
|
+
},
|
|
13538
|
+
onLanguageModelCallStart(event) {
|
|
13539
|
+
runSafely("onLanguageModelCallStart", () => {
|
|
13540
|
+
const state = operations.get(event.callId);
|
|
13541
|
+
const openSpans = modelSpans.get(event.callId);
|
|
13542
|
+
if (openSpans) {
|
|
13543
|
+
for (const span2 of openSpans) {
|
|
13544
|
+
span2.end();
|
|
13545
|
+
}
|
|
13546
|
+
modelSpans.delete(event.callId);
|
|
13547
|
+
}
|
|
13548
|
+
const span = startChildSpan(
|
|
13549
|
+
event.callId,
|
|
13550
|
+
state?.operationName === "streamText" ? "doStream" : "doGenerate",
|
|
13551
|
+
"llm" /* LLM */,
|
|
13552
|
+
{
|
|
13553
|
+
...shouldRecordInputs(event) ? {
|
|
13554
|
+
input: processAISDKCallInput(
|
|
13555
|
+
operationInput(
|
|
13556
|
+
event,
|
|
13557
|
+
state?.operationName ?? "generateText"
|
|
13558
|
+
)
|
|
13559
|
+
).input
|
|
13560
|
+
} : {},
|
|
13561
|
+
metadata: metadataFromEvent(event)
|
|
13562
|
+
}
|
|
13563
|
+
);
|
|
13564
|
+
const spans = modelSpans.get(event.callId) ?? [];
|
|
13565
|
+
spans.push(span);
|
|
13566
|
+
modelSpans.set(event.callId, spans);
|
|
13567
|
+
});
|
|
13568
|
+
},
|
|
13569
|
+
onLanguageModelCallEnd(event) {
|
|
13570
|
+
runSafely("onLanguageModelCallEnd", () => {
|
|
13571
|
+
const span = shiftModelSpan(modelSpans, event.callId);
|
|
13572
|
+
if (!span) {
|
|
13573
|
+
return;
|
|
13574
|
+
}
|
|
13575
|
+
const result = {
|
|
13576
|
+
...event,
|
|
13577
|
+
response: event.responseId ? { id: event.responseId } : void 0
|
|
13578
|
+
};
|
|
13579
|
+
span.log({
|
|
13580
|
+
...shouldRecordOutputs(event) ? {
|
|
13581
|
+
output: processAISDKOutput(result, DEFAULT_DENY_OUTPUT_PATHS)
|
|
13582
|
+
} : {},
|
|
13583
|
+
metrics: extractTokenMetrics(result)
|
|
13584
|
+
});
|
|
13585
|
+
span.end();
|
|
13586
|
+
});
|
|
13587
|
+
},
|
|
13588
|
+
onObjectStepStart(event) {
|
|
13589
|
+
runSafely("onObjectStepStart", () => {
|
|
13590
|
+
const state = operations.get(event.callId);
|
|
13591
|
+
const openSpan = objectSpans.get(event.callId);
|
|
13592
|
+
if (openSpan) {
|
|
13593
|
+
openSpan.end();
|
|
13594
|
+
objectSpans.delete(event.callId);
|
|
13595
|
+
}
|
|
13596
|
+
const span = startChildSpan(
|
|
13597
|
+
event.callId,
|
|
13598
|
+
state?.operationName === "streamObject" ? "doStream" : "doGenerate",
|
|
13599
|
+
"llm" /* LLM */,
|
|
13600
|
+
{
|
|
13601
|
+
...shouldRecordInputs(event) ? {
|
|
13602
|
+
input: {
|
|
13603
|
+
prompt: event.promptMessages
|
|
13604
|
+
}
|
|
13605
|
+
} : {},
|
|
13606
|
+
metadata: metadataFromEvent(event)
|
|
13607
|
+
}
|
|
13608
|
+
);
|
|
13609
|
+
objectSpans.set(event.callId, span);
|
|
13610
|
+
});
|
|
13611
|
+
},
|
|
13612
|
+
onObjectStepFinish(event) {
|
|
13613
|
+
runSafely("onObjectStepFinish", () => {
|
|
13614
|
+
const span = objectSpans.get(event.callId);
|
|
13615
|
+
if (!span) {
|
|
13616
|
+
return;
|
|
13617
|
+
}
|
|
13618
|
+
const result = {
|
|
13619
|
+
...event,
|
|
13620
|
+
text: event.objectText
|
|
13621
|
+
};
|
|
13622
|
+
span.log({
|
|
13623
|
+
...shouldRecordOutputs(event) ? {
|
|
13624
|
+
output: processAISDKOutput(result, DEFAULT_DENY_OUTPUT_PATHS)
|
|
13625
|
+
} : {},
|
|
13626
|
+
metrics: extractTokenMetrics(result)
|
|
13627
|
+
});
|
|
13628
|
+
span.end();
|
|
13629
|
+
objectSpans.delete(event.callId);
|
|
13630
|
+
});
|
|
13631
|
+
},
|
|
13632
|
+
onEmbedStart(event) {
|
|
13633
|
+
runSafely("onEmbedStart", () => {
|
|
13634
|
+
const state = operations.get(event.callId);
|
|
13635
|
+
for (const [embedCallId, embedState] of embedSpans) {
|
|
13636
|
+
if (embedState.callId === event.callId && (state?.operationName === "embed" || embedState.values === event.values)) {
|
|
13637
|
+
embedState.span.end();
|
|
13638
|
+
embedSpans.delete(embedCallId);
|
|
13639
|
+
}
|
|
13640
|
+
}
|
|
13641
|
+
const span = startChildSpan(
|
|
13642
|
+
event.callId,
|
|
13643
|
+
"doEmbed",
|
|
13644
|
+
"llm" /* LLM */,
|
|
13645
|
+
{
|
|
13646
|
+
...shouldRecordInputs(event) ? {
|
|
13647
|
+
input: {
|
|
13648
|
+
values: event.values
|
|
13649
|
+
}
|
|
13650
|
+
} : {},
|
|
13651
|
+
metadata: metadataFromEvent(event)
|
|
13652
|
+
}
|
|
13653
|
+
);
|
|
13654
|
+
embedSpans.set(event.embedCallId, {
|
|
13655
|
+
callId: event.callId,
|
|
13656
|
+
span,
|
|
13657
|
+
values: event.values
|
|
13658
|
+
});
|
|
13659
|
+
});
|
|
13660
|
+
},
|
|
13661
|
+
onEmbedFinish(event) {
|
|
13662
|
+
runSafely("onEmbedFinish", () => {
|
|
13663
|
+
const state = embedSpans.get(event.embedCallId);
|
|
13664
|
+
if (!state) {
|
|
13665
|
+
return;
|
|
13666
|
+
}
|
|
13667
|
+
const result = {
|
|
13668
|
+
...event,
|
|
13669
|
+
embeddings: event.embeddings
|
|
13670
|
+
};
|
|
13671
|
+
state.span.log({
|
|
13672
|
+
...shouldRecordOutputs(event) ? {
|
|
13673
|
+
output: processAISDKEmbeddingOutput(
|
|
13674
|
+
result,
|
|
13675
|
+
DEFAULT_DENY_OUTPUT_PATHS
|
|
13676
|
+
)
|
|
13677
|
+
} : {},
|
|
13678
|
+
metrics: extractTokenMetrics(result)
|
|
13679
|
+
});
|
|
13680
|
+
state.span.end();
|
|
13681
|
+
embedSpans.delete(event.embedCallId);
|
|
13682
|
+
});
|
|
13683
|
+
},
|
|
13684
|
+
onRerankStart(event) {
|
|
13685
|
+
runSafely("onRerankStart", () => {
|
|
13686
|
+
const openSpan = rerankSpans.get(event.callId);
|
|
13687
|
+
if (openSpan) {
|
|
13688
|
+
openSpan.end();
|
|
13689
|
+
rerankSpans.delete(event.callId);
|
|
13690
|
+
}
|
|
13691
|
+
const span = startChildSpan(
|
|
13692
|
+
event.callId,
|
|
13693
|
+
"doRerank",
|
|
13694
|
+
"llm" /* LLM */,
|
|
13695
|
+
{
|
|
13696
|
+
...shouldRecordInputs(event) ? {
|
|
13697
|
+
input: {
|
|
13698
|
+
documents: event.documents,
|
|
13699
|
+
query: event.query,
|
|
13700
|
+
topN: event.topN
|
|
13701
|
+
}
|
|
13702
|
+
} : {},
|
|
13703
|
+
metadata: metadataFromEvent(event)
|
|
13704
|
+
}
|
|
13705
|
+
);
|
|
13706
|
+
rerankSpans.set(event.callId, span);
|
|
13707
|
+
});
|
|
13708
|
+
},
|
|
13709
|
+
onRerankFinish(event) {
|
|
13710
|
+
runSafely("onRerankFinish", () => {
|
|
13711
|
+
const span = rerankSpans.get(event.callId);
|
|
13712
|
+
if (!span) {
|
|
13713
|
+
return;
|
|
13714
|
+
}
|
|
13715
|
+
const result = {
|
|
13716
|
+
ranking: event.ranking?.map((entry) => ({
|
|
13717
|
+
originalIndex: entry.index,
|
|
13718
|
+
score: entry.relevanceScore
|
|
13719
|
+
}))
|
|
13720
|
+
};
|
|
13721
|
+
span.log({
|
|
13722
|
+
...shouldRecordOutputs(event) ? {
|
|
13723
|
+
output: processAISDKRerankOutput(
|
|
13724
|
+
result,
|
|
13725
|
+
DEFAULT_DENY_OUTPUT_PATHS
|
|
13726
|
+
)
|
|
13727
|
+
} : {}
|
|
13728
|
+
});
|
|
13729
|
+
span.end();
|
|
13730
|
+
rerankSpans.delete(event.callId);
|
|
13731
|
+
});
|
|
13732
|
+
},
|
|
13733
|
+
onToolExecutionStart(event) {
|
|
13734
|
+
runSafely("onToolExecutionStart", () => {
|
|
13735
|
+
const toolCallId = event.toolCall.toolCallId;
|
|
13736
|
+
if (!toolCallId) {
|
|
13737
|
+
return;
|
|
13738
|
+
}
|
|
13739
|
+
const span = startChildSpan(
|
|
13740
|
+
event.callId,
|
|
13741
|
+
event.toolCall.toolName || "tool",
|
|
13742
|
+
"tool" /* TOOL */,
|
|
13743
|
+
{
|
|
13744
|
+
...shouldRecordInputs(event) ? {
|
|
13745
|
+
input: event.toolCall.input
|
|
13746
|
+
} : {},
|
|
13747
|
+
metadata: {
|
|
13748
|
+
...createAISDKIntegrationMetadata(),
|
|
13749
|
+
toolCallId,
|
|
13750
|
+
...typeof event.toolCall.toolName === "string" ? { toolName: event.toolCall.toolName } : {}
|
|
13751
|
+
}
|
|
13752
|
+
}
|
|
13753
|
+
);
|
|
13754
|
+
toolSpans.set(toolCallId, { callId: event.callId, span });
|
|
13755
|
+
});
|
|
13756
|
+
},
|
|
13757
|
+
onToolExecutionEnd(event) {
|
|
13758
|
+
runSafely("onToolExecutionEnd", () => {
|
|
13759
|
+
const toolCallId = event.toolCall.toolCallId;
|
|
13760
|
+
const state = toolCallId ? toolSpans.get(toolCallId) : void 0;
|
|
13761
|
+
if (!toolCallId || !state) {
|
|
13762
|
+
return;
|
|
13763
|
+
}
|
|
13764
|
+
const toolOutput = event.toolOutput;
|
|
13765
|
+
if (toolOutput?.type === "tool-error") {
|
|
13766
|
+
state.span.log({
|
|
13767
|
+
error: toolOutput.error instanceof Error ? toolOutput.error.message : String(toolOutput?.error),
|
|
13768
|
+
metrics: typeof event.durationMs === "number" ? { duration_ms: event.durationMs } : {}
|
|
13769
|
+
});
|
|
13770
|
+
} else {
|
|
13771
|
+
state.span.log({
|
|
13772
|
+
...shouldRecordOutputs(event) ? { output: toolOutput?.output } : {},
|
|
13773
|
+
metrics: typeof event.durationMs === "number" ? { duration_ms: event.durationMs } : {}
|
|
13774
|
+
});
|
|
13775
|
+
}
|
|
13776
|
+
state.span.end();
|
|
13777
|
+
toolSpans.delete(toolCallId);
|
|
13778
|
+
});
|
|
13779
|
+
},
|
|
13780
|
+
onChunk(event) {
|
|
13781
|
+
runSafely("onChunk", () => {
|
|
13782
|
+
const callId = event.chunk?.callId;
|
|
13783
|
+
if (!callId) {
|
|
13784
|
+
return;
|
|
13785
|
+
}
|
|
13786
|
+
const state = operations.get(callId);
|
|
13787
|
+
if (!state || state.firstChunkTime !== void 0) {
|
|
13788
|
+
return;
|
|
13789
|
+
}
|
|
13790
|
+
state.firstChunkTime = getCurrentUnixTimestamp();
|
|
13791
|
+
});
|
|
13792
|
+
},
|
|
13793
|
+
onFinish(event) {
|
|
13794
|
+
runSafely("onFinish", () => {
|
|
13795
|
+
const state = operations.get(event.callId);
|
|
13796
|
+
if (!state) {
|
|
13797
|
+
return;
|
|
13798
|
+
}
|
|
13799
|
+
const result = finishResult(event, state.operationName);
|
|
13800
|
+
const metrics = state.hadModelChild ? {} : extractTokenMetrics(result);
|
|
13801
|
+
if (state.firstChunkTime !== void 0) {
|
|
13802
|
+
metrics.time_to_first_token = state.firstChunkTime - state.startTime;
|
|
13803
|
+
}
|
|
13804
|
+
state.span.log({
|
|
13805
|
+
...shouldRecordOutputs(event) ? {
|
|
13806
|
+
output: finishOutput(result, state.operationName)
|
|
13807
|
+
} : {},
|
|
13808
|
+
metrics
|
|
13809
|
+
});
|
|
13810
|
+
state.span.end();
|
|
13811
|
+
operations.delete(event.callId);
|
|
13812
|
+
});
|
|
13813
|
+
},
|
|
13814
|
+
onError(event) {
|
|
13815
|
+
runSafely("onError", () => {
|
|
13816
|
+
const errorEvent = isObject(event) ? event : {};
|
|
13817
|
+
const callId = typeof errorEvent.callId === "string" ? errorEvent.callId : void 0;
|
|
13818
|
+
if (!callId) {
|
|
13819
|
+
return;
|
|
13820
|
+
}
|
|
13821
|
+
const state = operations.get(callId);
|
|
13822
|
+
if (!state) {
|
|
13823
|
+
return;
|
|
13824
|
+
}
|
|
13825
|
+
const error = errorEvent.error ?? event;
|
|
13826
|
+
const openModelSpans = modelSpans.get(callId);
|
|
13827
|
+
if (openModelSpans) {
|
|
13828
|
+
for (const span of openModelSpans) {
|
|
13829
|
+
logError(span, error);
|
|
13830
|
+
span.end();
|
|
13831
|
+
}
|
|
13832
|
+
modelSpans.delete(callId);
|
|
13833
|
+
}
|
|
13834
|
+
const openObjectSpan = objectSpans.get(callId);
|
|
13835
|
+
if (openObjectSpan) {
|
|
13836
|
+
logError(openObjectSpan, error);
|
|
13837
|
+
openObjectSpan.end();
|
|
13838
|
+
objectSpans.delete(callId);
|
|
13839
|
+
}
|
|
13840
|
+
for (const [embedCallId, embedState] of embedSpans) {
|
|
13841
|
+
if (embedState.callId === callId) {
|
|
13842
|
+
logError(embedState.span, error);
|
|
13843
|
+
embedState.span.end();
|
|
13844
|
+
embedSpans.delete(embedCallId);
|
|
13845
|
+
}
|
|
13846
|
+
}
|
|
13847
|
+
const openRerankSpan = rerankSpans.get(callId);
|
|
13848
|
+
if (openRerankSpan) {
|
|
13849
|
+
logError(openRerankSpan, error);
|
|
13850
|
+
openRerankSpan.end();
|
|
13851
|
+
rerankSpans.delete(callId);
|
|
13852
|
+
}
|
|
13853
|
+
for (const [toolCallId, toolState] of toolSpans) {
|
|
13854
|
+
if (toolState.callId === callId) {
|
|
13855
|
+
logError(toolState.span, error);
|
|
13856
|
+
toolState.span.end();
|
|
13857
|
+
toolSpans.delete(toolCallId);
|
|
13858
|
+
}
|
|
13859
|
+
}
|
|
13860
|
+
logError(state.span, error);
|
|
13861
|
+
state.span.end();
|
|
13862
|
+
operations.delete(callId);
|
|
13863
|
+
});
|
|
13864
|
+
},
|
|
13865
|
+
executeTool({ toolCallId, execute }) {
|
|
13866
|
+
const state = toolSpans.get(toolCallId);
|
|
13867
|
+
return state ? withCurrent(state.span, () => execute()) : execute();
|
|
13868
|
+
}
|
|
13869
|
+
};
|
|
13870
|
+
}
|
|
13871
|
+
function shouldRecordInputs(event) {
|
|
13872
|
+
return event.recordInputs !== false;
|
|
13873
|
+
}
|
|
13874
|
+
function shouldRecordOutputs(event) {
|
|
13875
|
+
return event.recordOutputs !== false;
|
|
13876
|
+
}
|
|
13877
|
+
function operationNameFromId(operationId) {
|
|
13878
|
+
return operationId?.startsWith("ai.") ? operationId.slice("ai.".length) : operationId || "ai-sdk";
|
|
13879
|
+
}
|
|
13880
|
+
function modelFromEvent(event) {
|
|
13881
|
+
return event.modelId ? {
|
|
13882
|
+
modelId: event.modelId,
|
|
13883
|
+
...event.provider ? { provider: event.provider } : {}
|
|
13884
|
+
} : void 0;
|
|
13885
|
+
}
|
|
13886
|
+
function metadataFromEvent(event) {
|
|
13887
|
+
const metadata = createAISDKIntegrationMetadata();
|
|
13888
|
+
const { model, provider } = serializeModelWithProvider(modelFromEvent(event));
|
|
13889
|
+
if (model) {
|
|
13890
|
+
metadata.model = model;
|
|
13891
|
+
}
|
|
13892
|
+
if (provider) {
|
|
13893
|
+
metadata.provider = provider;
|
|
13894
|
+
}
|
|
13895
|
+
if (typeof event.functionId === "string") {
|
|
13896
|
+
metadata.functionId = event.functionId;
|
|
13897
|
+
}
|
|
13898
|
+
return metadata;
|
|
13899
|
+
}
|
|
13900
|
+
function operationInput(event, operationName) {
|
|
13901
|
+
if (operationName === "embed") {
|
|
13902
|
+
return {
|
|
13903
|
+
model: modelFromEvent(event),
|
|
13904
|
+
value: event.value
|
|
13905
|
+
};
|
|
13906
|
+
}
|
|
13907
|
+
if (operationName === "embedMany") {
|
|
13908
|
+
return {
|
|
13909
|
+
model: modelFromEvent(event),
|
|
13910
|
+
values: Array.isArray(event.value) ? event.value ?? [] : void 0
|
|
13911
|
+
};
|
|
13912
|
+
}
|
|
13913
|
+
if (operationName === "rerank") {
|
|
13914
|
+
return {
|
|
13915
|
+
model: modelFromEvent(event),
|
|
13916
|
+
documents: event.documents,
|
|
13917
|
+
query: event.query,
|
|
13918
|
+
topN: event.topN
|
|
13919
|
+
};
|
|
13920
|
+
}
|
|
13921
|
+
return {
|
|
13922
|
+
model: modelFromEvent(event),
|
|
13923
|
+
system: event.system,
|
|
13924
|
+
prompt: event.prompt,
|
|
13925
|
+
messages: event.messages,
|
|
13926
|
+
tools: event.tools,
|
|
13927
|
+
toolChoice: event.toolChoice,
|
|
13928
|
+
activeTools: event.activeTools,
|
|
13929
|
+
output: event.output,
|
|
13930
|
+
schema: event.schema,
|
|
13931
|
+
schemaName: event.schemaName,
|
|
13932
|
+
schemaDescription: event.schemaDescription,
|
|
13933
|
+
maxOutputTokens: event.maxOutputTokens,
|
|
13934
|
+
temperature: event.temperature,
|
|
13935
|
+
topP: event.topP,
|
|
13936
|
+
topK: event.topK,
|
|
13937
|
+
presencePenalty: event.presencePenalty,
|
|
13938
|
+
frequencyPenalty: event.frequencyPenalty,
|
|
13939
|
+
seed: event.seed,
|
|
13940
|
+
maxRetries: event.maxRetries,
|
|
13941
|
+
headers: event.headers,
|
|
13942
|
+
providerOptions: event.providerOptions
|
|
13943
|
+
};
|
|
13944
|
+
}
|
|
13945
|
+
function shiftModelSpan(modelSpans, callId) {
|
|
13946
|
+
const spans = modelSpans.get(callId);
|
|
13947
|
+
const span = spans?.shift();
|
|
13948
|
+
if (spans && spans.length === 0) {
|
|
13949
|
+
modelSpans.delete(callId);
|
|
13950
|
+
}
|
|
13951
|
+
return span;
|
|
13952
|
+
}
|
|
13953
|
+
function finishResult(event, operationName) {
|
|
13954
|
+
if (operationName === "embed") {
|
|
13955
|
+
return {
|
|
13956
|
+
...event,
|
|
13957
|
+
embedding: event.embedding
|
|
13958
|
+
};
|
|
13959
|
+
}
|
|
13960
|
+
if (operationName === "embedMany") {
|
|
13961
|
+
return {
|
|
13962
|
+
...event,
|
|
13963
|
+
embeddings: event.embedding
|
|
13964
|
+
};
|
|
13965
|
+
}
|
|
13966
|
+
if (operationName === "rerank") {
|
|
13967
|
+
return event;
|
|
13968
|
+
}
|
|
13969
|
+
return event;
|
|
13970
|
+
}
|
|
13971
|
+
function finishOutput(result, operationName) {
|
|
13972
|
+
if (operationName === "embed" || operationName === "embedMany") {
|
|
13973
|
+
return processAISDKEmbeddingOutput(
|
|
13974
|
+
result,
|
|
13975
|
+
DEFAULT_DENY_OUTPUT_PATHS
|
|
13976
|
+
);
|
|
13977
|
+
}
|
|
13978
|
+
if (operationName === "rerank") {
|
|
13979
|
+
return processAISDKRerankOutput(
|
|
13980
|
+
result,
|
|
13981
|
+
DEFAULT_DENY_OUTPUT_PATHS
|
|
13982
|
+
);
|
|
13983
|
+
}
|
|
13984
|
+
return processAISDKOutput(result, DEFAULT_DENY_OUTPUT_PATHS);
|
|
13985
|
+
}
|
|
13986
|
+
|
|
13359
13987
|
// src/instrumentation/plugins/ai-sdk-channels.ts
|
|
13360
13988
|
var aiSDKChannels = defineChannels("ai", {
|
|
13361
13989
|
generateText: channel({
|
|
@@ -13415,6 +14043,10 @@ var aiSDKChannels = defineChannels("ai", {
|
|
|
13415
14043
|
toolLoopAgentStream: channel({
|
|
13416
14044
|
channelName: "ToolLoopAgent.stream",
|
|
13417
14045
|
kind: "async"
|
|
14046
|
+
}),
|
|
14047
|
+
v7CreateTelemetryDispatcher: channel({
|
|
14048
|
+
channelName: "createTelemetryDispatcher",
|
|
14049
|
+
kind: "sync-stream"
|
|
13418
14050
|
})
|
|
13419
14051
|
});
|
|
13420
14052
|
|
|
@@ -13435,9 +14067,30 @@ var DEFAULT_DENY_OUTPUT_PATHS = [
|
|
|
13435
14067
|
];
|
|
13436
14068
|
var AUTO_PATCHED_MODEL = /* @__PURE__ */ Symbol.for("braintrust.ai-sdk.auto-patched-model");
|
|
13437
14069
|
var AUTO_PATCHED_TOOL = /* @__PURE__ */ Symbol.for("braintrust.ai-sdk.auto-patched-tool");
|
|
14070
|
+
var AUTO_PATCHED_V7_TELEMETRY_DISPATCHER = /* @__PURE__ */ Symbol.for(
|
|
14071
|
+
"braintrust.ai-sdk.v7.auto-patched-telemetry-dispatcher"
|
|
14072
|
+
);
|
|
13438
14073
|
var RUNTIME_DENY_OUTPUT_PATHS = /* @__PURE__ */ Symbol.for(
|
|
13439
14074
|
"braintrust.ai-sdk.deny-output-paths"
|
|
13440
14075
|
);
|
|
14076
|
+
var AI_SDK_V7_TELEMETRY_CALLBACKS = [
|
|
14077
|
+
"onStart",
|
|
14078
|
+
"onStepStart",
|
|
14079
|
+
"onLanguageModelCallStart",
|
|
14080
|
+
"onLanguageModelCallEnd",
|
|
14081
|
+
"onToolExecutionStart",
|
|
14082
|
+
"onToolExecutionEnd",
|
|
14083
|
+
"onChunk",
|
|
14084
|
+
"onStepFinish",
|
|
14085
|
+
"onObjectStepStart",
|
|
14086
|
+
"onObjectStepFinish",
|
|
14087
|
+
"onEmbedStart",
|
|
14088
|
+
"onEmbedFinish",
|
|
14089
|
+
"onRerankStart",
|
|
14090
|
+
"onRerankFinish",
|
|
14091
|
+
"onFinish",
|
|
14092
|
+
"onError"
|
|
14093
|
+
];
|
|
13441
14094
|
var AISDKPlugin = class extends BasePlugin {
|
|
13442
14095
|
config;
|
|
13443
14096
|
constructor(config = {}) {
|
|
@@ -13452,6 +14105,7 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
13452
14105
|
}
|
|
13453
14106
|
subscribeToAISDK() {
|
|
13454
14107
|
const denyOutputPaths = this.config.denyOutputPaths || DEFAULT_DENY_OUTPUT_PATHS;
|
|
14108
|
+
this.unsubscribers.push(subscribeToAISDKV7TelemetryDispatcher());
|
|
13455
14109
|
this.unsubscribers.push(
|
|
13456
14110
|
traceStreamingChannel(aiSDKChannels.generateText, {
|
|
13457
14111
|
name: "generateText",
|
|
@@ -13676,6 +14330,57 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
13676
14330
|
);
|
|
13677
14331
|
}
|
|
13678
14332
|
};
|
|
14333
|
+
function subscribeToAISDKV7TelemetryDispatcher() {
|
|
14334
|
+
const channel2 = aiSDKChannels.v7CreateTelemetryDispatcher.tracingChannel();
|
|
14335
|
+
const telemetry = braintrustAISDKTelemetry();
|
|
14336
|
+
const handlers = {
|
|
14337
|
+
end: (event) => {
|
|
14338
|
+
const telemetryOptions = event.arguments?.[0]?.telemetry;
|
|
14339
|
+
if (telemetryOptions?.isEnabled === false) {
|
|
14340
|
+
return;
|
|
14341
|
+
}
|
|
14342
|
+
patchAISDKV7TelemetryDispatcher(event.result, telemetry);
|
|
14343
|
+
}
|
|
14344
|
+
};
|
|
14345
|
+
channel2.subscribe(handlers);
|
|
14346
|
+
return () => {
|
|
14347
|
+
channel2.unsubscribe(handlers);
|
|
14348
|
+
};
|
|
14349
|
+
}
|
|
14350
|
+
function patchAISDKV7TelemetryDispatcher(dispatcher, telemetry) {
|
|
14351
|
+
if (!isObject(dispatcher)) {
|
|
14352
|
+
return;
|
|
14353
|
+
}
|
|
14354
|
+
const dispatcherRecord = dispatcher;
|
|
14355
|
+
if (dispatcherRecord[AUTO_PATCHED_V7_TELEMETRY_DISPATCHER]) {
|
|
14356
|
+
return;
|
|
14357
|
+
}
|
|
14358
|
+
dispatcherRecord[AUTO_PATCHED_V7_TELEMETRY_DISPATCHER] = true;
|
|
14359
|
+
for (const key of AI_SDK_V7_TELEMETRY_CALLBACKS) {
|
|
14360
|
+
const braintrustCallback = telemetry[key];
|
|
14361
|
+
if (typeof braintrustCallback !== "function") {
|
|
14362
|
+
continue;
|
|
14363
|
+
}
|
|
14364
|
+
const existingCallback = dispatcherRecord[key];
|
|
14365
|
+
dispatcherRecord[key] = (event) => {
|
|
14366
|
+
const existingResult = typeof existingCallback === "function" ? existingCallback.call(dispatcher, event) : void 0;
|
|
14367
|
+
const braintrustResult = braintrustCallback.call(telemetry, event);
|
|
14368
|
+
const pending = [existingResult, braintrustResult].filter(isPromiseLike);
|
|
14369
|
+
if (pending.length > 0) {
|
|
14370
|
+
return Promise.allSettled(pending).then(() => void 0);
|
|
14371
|
+
}
|
|
14372
|
+
};
|
|
14373
|
+
}
|
|
14374
|
+
const braintrustExecuteTool = telemetry.executeTool;
|
|
14375
|
+
if (typeof braintrustExecuteTool !== "function") {
|
|
14376
|
+
return;
|
|
14377
|
+
}
|
|
14378
|
+
const existingExecuteTool = dispatcherRecord.executeTool;
|
|
14379
|
+
dispatcherRecord.executeTool = (args) => braintrustExecuteTool.call(telemetry, {
|
|
14380
|
+
...args,
|
|
14381
|
+
execute: () => typeof existingExecuteTool === "function" ? existingExecuteTool.call(dispatcher, args) : args.execute()
|
|
14382
|
+
});
|
|
14383
|
+
}
|
|
13679
14384
|
function resolveDenyOutputPaths(event, defaultDenyOutputPaths) {
|
|
13680
14385
|
if (Array.isArray(event?.denyOutputPaths)) {
|
|
13681
14386
|
return event.denyOutputPaths;
|
|
@@ -14127,11 +14832,11 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
|
|
|
14127
14832
|
metadata: baseMetadata
|
|
14128
14833
|
}
|
|
14129
14834
|
});
|
|
14835
|
+
const streamStartTime = getCurrentUnixTimestamp();
|
|
14130
14836
|
const result = await withCurrent(
|
|
14131
14837
|
span,
|
|
14132
14838
|
() => Reflect.apply(originalDoStream, resolvedModel, [options])
|
|
14133
14839
|
);
|
|
14134
|
-
const streamStartTime = getCurrentUnixTimestamp();
|
|
14135
14840
|
let firstChunkTime;
|
|
14136
14841
|
const output = {};
|
|
14137
14842
|
let text = "";
|
|
@@ -14140,7 +14845,7 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
|
|
|
14140
14845
|
let object = void 0;
|
|
14141
14846
|
const transformStream = new TransformStream({
|
|
14142
14847
|
transform(chunk, controller) {
|
|
14143
|
-
if (firstChunkTime === void 0) {
|
|
14848
|
+
if (firstChunkTime === void 0 && isAISDKContentStreamChunk(chunk)) {
|
|
14144
14849
|
firstChunkTime = getCurrentUnixTimestamp();
|
|
14145
14850
|
}
|
|
14146
14851
|
switch (chunk.type) {
|
|
@@ -14332,6 +15037,78 @@ function finalizeAISDKChildTracing(event) {
|
|
|
14332
15037
|
delete event.__braintrust_ai_sdk_cleanup;
|
|
14333
15038
|
}
|
|
14334
15039
|
}
|
|
15040
|
+
function extractAISDKStreamPart(chunk) {
|
|
15041
|
+
if (!isObject(chunk) || !isObject(chunk.part)) {
|
|
15042
|
+
return chunk;
|
|
15043
|
+
}
|
|
15044
|
+
return chunk.part;
|
|
15045
|
+
}
|
|
15046
|
+
function stringContent(value) {
|
|
15047
|
+
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
15048
|
+
}
|
|
15049
|
+
function rawValueHasAISDKContent(value) {
|
|
15050
|
+
if (value === void 0 || value === null) {
|
|
15051
|
+
return false;
|
|
15052
|
+
}
|
|
15053
|
+
if (typeof value === "string") {
|
|
15054
|
+
return value.length > 0;
|
|
15055
|
+
}
|
|
15056
|
+
if (!isObject(value)) {
|
|
15057
|
+
return true;
|
|
15058
|
+
}
|
|
15059
|
+
const delta = value.delta;
|
|
15060
|
+
if (stringContent(value.content) || stringContent(value.text) || stringContent(value.delta) || stringContent(value.arguments) || stringContent(value.partial_json) || isObject(delta) && (stringContent(delta.content) || stringContent(delta.text) || stringContent(delta.arguments) || stringContent(delta.partial_json) || stringContent(delta.thinking)) || Array.isArray(value.choices) && value.choices.some((choice) => {
|
|
15061
|
+
if (!isObject(choice) || !isObject(choice.delta)) {
|
|
15062
|
+
return false;
|
|
15063
|
+
}
|
|
15064
|
+
const choiceDelta = choice.delta;
|
|
15065
|
+
if (stringContent(choiceDelta.content) || stringContent(choiceDelta.text)) {
|
|
15066
|
+
return true;
|
|
15067
|
+
}
|
|
15068
|
+
if (isObject(choiceDelta.function_call) && stringContent(choiceDelta.function_call.arguments)) {
|
|
15069
|
+
return true;
|
|
15070
|
+
}
|
|
15071
|
+
return Array.isArray(choiceDelta.tool_calls) && choiceDelta.tool_calls.some(
|
|
15072
|
+
(toolCall) => isObject(toolCall) && isObject(toolCall.function) && stringContent(toolCall.function.arguments)
|
|
15073
|
+
);
|
|
15074
|
+
})) {
|
|
15075
|
+
return true;
|
|
15076
|
+
}
|
|
15077
|
+
return false;
|
|
15078
|
+
}
|
|
15079
|
+
function isAISDKContentStreamChunk(chunk) {
|
|
15080
|
+
const part = extractAISDKStreamPart(chunk);
|
|
15081
|
+
if (typeof part === "string") {
|
|
15082
|
+
return part.length > 0;
|
|
15083
|
+
}
|
|
15084
|
+
if (!isObject(part) || typeof part.type !== "string") {
|
|
15085
|
+
return false;
|
|
15086
|
+
}
|
|
15087
|
+
switch (part.type) {
|
|
15088
|
+
case "text-delta":
|
|
15089
|
+
return stringContent(part.textDelta) !== void 0 || stringContent(part.delta) !== void 0 || stringContent(part.text) !== void 0 || stringContent(part.content) !== void 0;
|
|
15090
|
+
case "reasoning-delta":
|
|
15091
|
+
return stringContent(part.delta) !== void 0 || stringContent(part.text) !== void 0 || stringContent(part.content) !== void 0;
|
|
15092
|
+
case "tool-call":
|
|
15093
|
+
case "object":
|
|
15094
|
+
case "file":
|
|
15095
|
+
return true;
|
|
15096
|
+
case "tool-input-delta":
|
|
15097
|
+
case "tool-call-delta":
|
|
15098
|
+
return stringContent(part.argsTextDelta) !== void 0 || stringContent(part.inputTextDelta) !== void 0 || stringContent(part.delta) !== void 0 || stringContent(part.text) !== void 0 || stringContent(part.content) !== void 0;
|
|
15099
|
+
case "raw":
|
|
15100
|
+
return rawValueHasAISDKContent(part.rawValue);
|
|
15101
|
+
default:
|
|
15102
|
+
return false;
|
|
15103
|
+
}
|
|
15104
|
+
}
|
|
15105
|
+
function isAISDKContentAsyncIterableChunk(chunk) {
|
|
15106
|
+
if (isAISDKContentStreamChunk(chunk)) {
|
|
15107
|
+
return true;
|
|
15108
|
+
}
|
|
15109
|
+
const part = extractAISDKStreamPart(chunk);
|
|
15110
|
+
return isObject(part) && typeof part.type !== "string";
|
|
15111
|
+
}
|
|
14335
15112
|
function patchAISDKStreamingResult(args) {
|
|
14336
15113
|
const { defaultDenyOutputPaths, endEvent, result, span, startTime } = args;
|
|
14337
15114
|
if (!result || typeof result !== "object") {
|
|
@@ -14344,7 +15121,7 @@ function patchAISDKStreamingResult(args) {
|
|
|
14344
15121
|
const wrappedBaseStream = resultRecord.baseStream.pipeThrough(
|
|
14345
15122
|
new TransformStream({
|
|
14346
15123
|
transform(chunk, controller) {
|
|
14347
|
-
if (firstChunkTime2 === void 0) {
|
|
15124
|
+
if (firstChunkTime2 === void 0 && isAISDKContentStreamChunk(chunk)) {
|
|
14348
15125
|
firstChunkTime2 = getCurrentUnixTimestamp();
|
|
14349
15126
|
}
|
|
14350
15127
|
controller.enqueue(chunk);
|
|
@@ -14388,8 +15165,8 @@ function patchAISDKStreamingResult(args) {
|
|
|
14388
15165
|
}
|
|
14389
15166
|
let firstChunkTime;
|
|
14390
15167
|
const wrappedStream = createPatchedAsyncIterable(streamField.stream, {
|
|
14391
|
-
onChunk: () => {
|
|
14392
|
-
if (firstChunkTime === void 0) {
|
|
15168
|
+
onChunk: (chunk) => {
|
|
15169
|
+
if (firstChunkTime === void 0 && isAISDKContentAsyncIterableChunk(chunk)) {
|
|
14393
15170
|
firstChunkTime = getCurrentUnixTimestamp();
|
|
14394
15171
|
}
|
|
14395
15172
|
},
|
|
@@ -15361,15 +16138,17 @@ function collectLocalMcpServerToolHookNames(serverName, serverConfig) {
|
|
|
15361
16138
|
|
|
15362
16139
|
// src/instrumentation/plugins/claude-agent-sdk-plugin.ts
|
|
15363
16140
|
var ROOT_LLM_PARENT_KEY = "__root__";
|
|
16141
|
+
var SUB_AGENT_PROMPT_SOURCE_PRIORITY = {
|
|
16142
|
+
delegation: 0,
|
|
16143
|
+
lifecycle: 1,
|
|
16144
|
+
sidechain: 2
|
|
16145
|
+
};
|
|
15364
16146
|
function llmParentKey(parentToolUseId) {
|
|
15365
16147
|
return parentToolUseId ?? ROOT_LLM_PARENT_KEY;
|
|
15366
16148
|
}
|
|
15367
16149
|
function isSubAgentDelegationToolName(toolName) {
|
|
15368
16150
|
return toolName === "Agent" || toolName === "Task";
|
|
15369
16151
|
}
|
|
15370
|
-
function shouldParentToolAsTaskSibling(toolName) {
|
|
15371
|
-
return toolName === "Agent" || toolName === "Task" || toolName === "Bash";
|
|
15372
|
-
}
|
|
15373
16152
|
function filterSerializableOptions(options) {
|
|
15374
16153
|
const allowedKeys = [
|
|
15375
16154
|
"model",
|
|
@@ -15506,26 +16285,39 @@ function extractUsageFromMessage(message) {
|
|
|
15506
16285
|
}
|
|
15507
16286
|
return metrics;
|
|
15508
16287
|
}
|
|
15509
|
-
function buildLLMInput(
|
|
15510
|
-
const promptMessages = [];
|
|
15511
|
-
if (typeof prompt === "string") {
|
|
15512
|
-
promptMessages.push({ content: prompt, role: "user" });
|
|
15513
|
-
} else if (capturedPromptMessages && capturedPromptMessages.length > 0) {
|
|
15514
|
-
for (const msg of capturedPromptMessages) {
|
|
15515
|
-
const role = msg.message?.role;
|
|
15516
|
-
const content = msg.message?.content;
|
|
15517
|
-
if (role && content !== void 0) {
|
|
15518
|
-
promptMessages.push({ content, role });
|
|
15519
|
-
}
|
|
15520
|
-
}
|
|
15521
|
-
}
|
|
16288
|
+
function buildLLMInput(promptMessages, conversationHistory) {
|
|
15522
16289
|
const inputParts = [...promptMessages, ...conversationHistory];
|
|
15523
16290
|
return inputParts.length > 0 ? inputParts : void 0;
|
|
15524
16291
|
}
|
|
16292
|
+
function conversationMessageFromSDKMessage(message) {
|
|
16293
|
+
const role = message.message?.role;
|
|
16294
|
+
const content = message.message?.content;
|
|
16295
|
+
if (role && content !== void 0) {
|
|
16296
|
+
return { content, role };
|
|
16297
|
+
}
|
|
16298
|
+
return void 0;
|
|
16299
|
+
}
|
|
16300
|
+
function messageContentHasBlockType(message, blockType) {
|
|
16301
|
+
const content = message.message?.content;
|
|
16302
|
+
return Array.isArray(content) && content.some(
|
|
16303
|
+
(block) => typeof block === "object" && block !== null && "type" in block && block.type === blockType
|
|
16304
|
+
);
|
|
16305
|
+
}
|
|
16306
|
+
function buildRootPromptMessages(prompt, capturedPromptMessages) {
|
|
16307
|
+
if (typeof prompt === "string") {
|
|
16308
|
+
return [{ content: prompt, role: "user" }];
|
|
16309
|
+
}
|
|
16310
|
+
if (!capturedPromptMessages || capturedPromptMessages.length === 0) {
|
|
16311
|
+
return [];
|
|
16312
|
+
}
|
|
16313
|
+
return capturedPromptMessages.map(conversationMessageFromSDKMessage).filter(
|
|
16314
|
+
(message) => message !== void 0
|
|
16315
|
+
);
|
|
16316
|
+
}
|
|
15525
16317
|
function formatCapturedMessages(messages) {
|
|
15526
16318
|
return messages.length > 0 ? messages : [];
|
|
15527
16319
|
}
|
|
15528
|
-
async function createLLMSpanForMessages(messages,
|
|
16320
|
+
async function createLLMSpanForMessages(messages, promptMessages, conversationHistory, options, startTime, parentSpan, existingSpan) {
|
|
15529
16321
|
if (messages.length === 0) {
|
|
15530
16322
|
return void 0;
|
|
15531
16323
|
}
|
|
@@ -15535,11 +16327,7 @@ async function createLLMSpanForMessages(messages, prompt, conversationHistory, o
|
|
|
15535
16327
|
}
|
|
15536
16328
|
const model = lastMessage.message.model || options.model;
|
|
15537
16329
|
const usage = extractUsageFromMessage(lastMessage);
|
|
15538
|
-
const input = buildLLMInput(
|
|
15539
|
-
prompt,
|
|
15540
|
-
conversationHistory,
|
|
15541
|
-
capturedPromptMessages
|
|
15542
|
-
);
|
|
16330
|
+
const input = buildLLMInput(promptMessages, conversationHistory);
|
|
15543
16331
|
const outputs = messages.map(
|
|
15544
16332
|
(m) => m.message?.content && m.message?.role ? { content: m.message.content, role: m.message.role } : void 0
|
|
15545
16333
|
).filter(
|
|
@@ -15670,8 +16458,7 @@ function createToolTracingHooks(resolveParentSpan, activeToolSpans, mcpServers,
|
|
|
15670
16458
|
},
|
|
15671
16459
|
name: parsed.displayName,
|
|
15672
16460
|
parent: await resolveParentSpan(toolUseID, {
|
|
15673
|
-
agentId: input.agent_id
|
|
15674
|
-
preferTaskSiblingParent: shouldParentToolAsTaskSibling(parsed.toolName)
|
|
16461
|
+
agentId: input.agent_id
|
|
15675
16462
|
}),
|
|
15676
16463
|
spanAttributes: { type: "tool" /* TOOL */ }
|
|
15677
16464
|
});
|
|
@@ -15917,12 +16704,37 @@ function injectTracingHooks(options, resolveParentSpan, activeToolSpans, localTo
|
|
|
15917
16704
|
}
|
|
15918
16705
|
};
|
|
15919
16706
|
}
|
|
16707
|
+
function setSubAgentPromptMessages(state, parentToolUseId, promptMessages, source) {
|
|
16708
|
+
if (promptMessages.length === 0) {
|
|
16709
|
+
return;
|
|
16710
|
+
}
|
|
16711
|
+
const parentKey = llmParentKey(parentToolUseId);
|
|
16712
|
+
const sourcePriority = SUB_AGENT_PROMPT_SOURCE_PRIORITY[source];
|
|
16713
|
+
const currentPriority = state.promptSourcePriorityByParentKey.get(parentKey) ?? -1;
|
|
16714
|
+
if (sourcePriority > currentPriority) {
|
|
16715
|
+
state.promptMessagesByParentKey.set(parentKey, promptMessages);
|
|
16716
|
+
state.promptSourcePriorityByParentKey.set(parentKey, sourcePriority);
|
|
16717
|
+
}
|
|
16718
|
+
}
|
|
16719
|
+
function getConversationHistory(state, parentKey) {
|
|
16720
|
+
let conversationHistory = state.conversationHistoryByParentKey.get(parentKey);
|
|
16721
|
+
if (!conversationHistory) {
|
|
16722
|
+
conversationHistory = [];
|
|
16723
|
+
state.conversationHistoryByParentKey.set(parentKey, conversationHistory);
|
|
16724
|
+
}
|
|
16725
|
+
return conversationHistory;
|
|
16726
|
+
}
|
|
15920
16727
|
async function finalizeCurrentMessageGroup(state) {
|
|
15921
16728
|
if (state.currentMessages.length === 0) {
|
|
15922
16729
|
return;
|
|
15923
16730
|
}
|
|
15924
16731
|
const parentToolUseId = state.currentMessages[0]?.parent_tool_use_id ?? null;
|
|
15925
16732
|
const parentKey = llmParentKey(parentToolUseId);
|
|
16733
|
+
const conversationHistory = getConversationHistory(state, parentKey);
|
|
16734
|
+
const promptMessages = parentToolUseId ? state.promptMessagesByParentKey.get(parentKey) ?? [] : buildRootPromptMessages(
|
|
16735
|
+
state.originalPrompt,
|
|
16736
|
+
state.capturedPromptMessages
|
|
16737
|
+
);
|
|
15926
16738
|
let parentSpan = await state.span.export();
|
|
15927
16739
|
if (parentToolUseId) {
|
|
15928
16740
|
const subAgentSpan = state.subAgentSpans.get(parentToolUseId);
|
|
@@ -15933,11 +16745,10 @@ async function finalizeCurrentMessageGroup(state) {
|
|
|
15933
16745
|
const existingLlmSpan = state.activeLlmSpansByParentToolUse.get(parentKey);
|
|
15934
16746
|
const llmSpanResult = await createLLMSpanForMessages(
|
|
15935
16747
|
state.currentMessages,
|
|
15936
|
-
|
|
15937
|
-
|
|
16748
|
+
promptMessages,
|
|
16749
|
+
conversationHistory,
|
|
15938
16750
|
state.options,
|
|
15939
16751
|
state.currentMessageStartTime,
|
|
15940
|
-
state.capturedPromptMessages,
|
|
15941
16752
|
parentSpan,
|
|
15942
16753
|
existingLlmSpan
|
|
15943
16754
|
);
|
|
@@ -15951,6 +16762,7 @@ async function finalizeCurrentMessageGroup(state) {
|
|
|
15951
16762
|
state.latestRootLlmParentRef.value = llmSpanResult.spanExport;
|
|
15952
16763
|
}
|
|
15953
16764
|
if (llmSpanResult.finalMessage) {
|
|
16765
|
+
conversationHistory.push(llmSpanResult.finalMessage);
|
|
15954
16766
|
state.finalResults.push(llmSpanResult.finalMessage);
|
|
15955
16767
|
}
|
|
15956
16768
|
}
|
|
@@ -15978,6 +16790,15 @@ function maybeTrackToolUseContext(state, message) {
|
|
|
15978
16790
|
description: getStringProperty(block.input, "description"),
|
|
15979
16791
|
toolUseId: block.id
|
|
15980
16792
|
});
|
|
16793
|
+
const prompt = getStringProperty(block.input, "prompt");
|
|
16794
|
+
if (prompt) {
|
|
16795
|
+
setSubAgentPromptMessages(
|
|
16796
|
+
state,
|
|
16797
|
+
block.id,
|
|
16798
|
+
[{ content: prompt, role: "user" }],
|
|
16799
|
+
"delegation"
|
|
16800
|
+
);
|
|
16801
|
+
}
|
|
15981
16802
|
}
|
|
15982
16803
|
}
|
|
15983
16804
|
}
|
|
@@ -16096,6 +16917,14 @@ async function maybeHandleTaskLifecycleMessage(state, message) {
|
|
|
16096
16917
|
};
|
|
16097
16918
|
if (message.subtype === "task_started") {
|
|
16098
16919
|
const prompt = getStringProperty(message, "prompt");
|
|
16920
|
+
if (prompt) {
|
|
16921
|
+
setSubAgentPromptMessages(
|
|
16922
|
+
state,
|
|
16923
|
+
toolUseId,
|
|
16924
|
+
[{ content: prompt, role: "user" }],
|
|
16925
|
+
"lifecycle"
|
|
16926
|
+
);
|
|
16927
|
+
}
|
|
16099
16928
|
subAgentSpan.log({
|
|
16100
16929
|
input: prompt,
|
|
16101
16930
|
metadata
|
|
@@ -16146,6 +16975,28 @@ async function handleStreamMessage(state, message) {
|
|
|
16146
16975
|
return;
|
|
16147
16976
|
}
|
|
16148
16977
|
await maybeStartSubAgentSpan(state, message);
|
|
16978
|
+
const messageParentToolUseId = message.parent_tool_use_id;
|
|
16979
|
+
if (messageParentToolUseId && message.type === "user") {
|
|
16980
|
+
const conversationMessage = conversationMessageFromSDKMessage(message);
|
|
16981
|
+
if (conversationMessage?.role === "user") {
|
|
16982
|
+
await finalizeCurrentMessageGroup(state);
|
|
16983
|
+
const parentKey = llmParentKey(messageParentToolUseId);
|
|
16984
|
+
const conversationHistory = getConversationHistory(state, parentKey);
|
|
16985
|
+
const currentPromptSourcePriority = state.promptSourcePriorityByParentKey.get(parentKey) ?? -1;
|
|
16986
|
+
const canUseAsInitialSidechainPrompt = conversationHistory.length === 0 && currentPromptSourcePriority < SUB_AGENT_PROMPT_SOURCE_PRIORITY.sidechain && !messageContentHasBlockType(message, "tool_result");
|
|
16987
|
+
if (!canUseAsInitialSidechainPrompt) {
|
|
16988
|
+
conversationHistory.push(conversationMessage);
|
|
16989
|
+
return;
|
|
16990
|
+
}
|
|
16991
|
+
setSubAgentPromptMessages(
|
|
16992
|
+
state,
|
|
16993
|
+
messageParentToolUseId,
|
|
16994
|
+
[conversationMessage],
|
|
16995
|
+
"sidechain"
|
|
16996
|
+
);
|
|
16997
|
+
return;
|
|
16998
|
+
}
|
|
16999
|
+
}
|
|
16149
17000
|
const messageId = message.message?.id;
|
|
16150
17001
|
if (messageId && messageId !== state.currentMessageId) {
|
|
16151
17002
|
await finalizeCurrentMessageGroup(state);
|
|
@@ -16297,6 +17148,7 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
16297
17148
|
}
|
|
16298
17149
|
const activeToolSpans = /* @__PURE__ */ new Map();
|
|
16299
17150
|
const activeLlmSpansByParentToolUse = /* @__PURE__ */ new Map();
|
|
17151
|
+
const conversationHistoryByParentKey = /* @__PURE__ */ new Map();
|
|
16300
17152
|
const subAgentSpans = /* @__PURE__ */ new Map();
|
|
16301
17153
|
const endedSubAgentSpans = /* @__PURE__ */ new Set();
|
|
16302
17154
|
const toolUseToParent = /* @__PURE__ */ new Map();
|
|
@@ -16306,6 +17158,8 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
16306
17158
|
};
|
|
16307
17159
|
const subAgentDetailsByToolUseId = /* @__PURE__ */ new Map();
|
|
16308
17160
|
const taskIdToToolUseId = /* @__PURE__ */ new Map();
|
|
17161
|
+
const promptMessagesByParentKey = /* @__PURE__ */ new Map();
|
|
17162
|
+
const promptSourcePriorityByParentKey = /* @__PURE__ */ new Map();
|
|
16309
17163
|
const localToolContext = createClaudeLocalToolContext();
|
|
16310
17164
|
const { hasLocalToolHandlers, localToolHookNames } = prepareLocalToolHandlersInMcpServers(options.mcpServers);
|
|
16311
17165
|
const skipLocalToolHooks = options[CLAUDE_AGENT_SDK_SKIP_LOCAL_TOOL_HOOKS_OPTION] === true || hasLocalToolHandlers;
|
|
@@ -16314,38 +17168,19 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
16314
17168
|
const parentToolUseId = trackedParentToolUseId ?? (context?.agentId ? taskIdToToolUseId.get(context.agentId) ?? null : null);
|
|
16315
17169
|
const parentKey = llmParentKey(parentToolUseId);
|
|
16316
17170
|
const activeLlmSpan = activeLlmSpansByParentToolUse.get(parentKey);
|
|
16317
|
-
|
|
16318
|
-
|
|
16319
|
-
|
|
16320
|
-
|
|
16321
|
-
|
|
16322
|
-
|
|
16323
|
-
|
|
16324
|
-
|
|
16325
|
-
|
|
16326
|
-
|
|
16327
|
-
|
|
16328
|
-
}
|
|
16329
|
-
if (parentToolUseId) {
|
|
16330
|
-
const subAgentSpan = await ensureSubAgentSpan(
|
|
16331
|
-
subAgentDetailsByToolUseId,
|
|
16332
|
-
span,
|
|
16333
|
-
activeToolSpans,
|
|
16334
|
-
subAgentSpans,
|
|
16335
|
-
parentToolUseId
|
|
16336
|
-
);
|
|
16337
|
-
return subAgentSpan.export();
|
|
16338
|
-
}
|
|
16339
|
-
return span.export();
|
|
16340
|
-
}
|
|
16341
|
-
if (activeLlmSpan) {
|
|
16342
|
-
return activeLlmSpan.export();
|
|
17171
|
+
const latestLlmParent = parentToolUseId ? latestLlmParentBySubAgentToolUse.get(parentToolUseId) : latestRootLlmParentRef.value;
|
|
17172
|
+
if (!activeLlmSpan && !latestLlmParent) {
|
|
17173
|
+
await ensureActiveLlmSpanForParentToolUse(
|
|
17174
|
+
span,
|
|
17175
|
+
activeLlmSpansByParentToolUse,
|
|
17176
|
+
subAgentDetailsByToolUseId,
|
|
17177
|
+
activeToolSpans,
|
|
17178
|
+
subAgentSpans,
|
|
17179
|
+
parentToolUseId,
|
|
17180
|
+
getCurrentUnixTimestamp()
|
|
17181
|
+
);
|
|
16343
17182
|
}
|
|
16344
17183
|
if (parentToolUseId) {
|
|
16345
|
-
const parentLlm = latestLlmParentBySubAgentToolUse.get(parentToolUseId);
|
|
16346
|
-
if (parentLlm) {
|
|
16347
|
-
return parentLlm;
|
|
16348
|
-
}
|
|
16349
17184
|
const subAgentSpan = await ensureSubAgentSpan(
|
|
16350
17185
|
subAgentDetailsByToolUseId,
|
|
16351
17186
|
span,
|
|
@@ -16355,9 +17190,6 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
16355
17190
|
);
|
|
16356
17191
|
return subAgentSpan.export();
|
|
16357
17192
|
}
|
|
16358
|
-
if (latestRootLlmParentRef.value) {
|
|
16359
|
-
return latestRootLlmParentRef.value;
|
|
16360
|
-
}
|
|
16361
17193
|
return span.export();
|
|
16362
17194
|
};
|
|
16363
17195
|
localToolContext.resolveLocalToolParent = resolveToolUseParentSpan;
|
|
@@ -16378,6 +17210,7 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
16378
17210
|
accumulatedOutputTokens: 0,
|
|
16379
17211
|
activeLlmSpansByParentToolUse,
|
|
16380
17212
|
activeToolSpans,
|
|
17213
|
+
conversationHistoryByParentKey,
|
|
16381
17214
|
capturedPromptMessages,
|
|
16382
17215
|
currentMessageId: void 0,
|
|
16383
17216
|
currentMessageStartTime: startTime,
|
|
@@ -16388,7 +17221,9 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
16388
17221
|
originalPrompt,
|
|
16389
17222
|
processing: Promise.resolve(),
|
|
16390
17223
|
promptDone,
|
|
17224
|
+
promptMessagesByParentKey,
|
|
16391
17225
|
promptStarted: () => promptStarted,
|
|
17226
|
+
promptSourcePriorityByParentKey,
|
|
16392
17227
|
span,
|
|
16393
17228
|
subAgentDetailsByToolUseId,
|
|
16394
17229
|
subAgentSpans,
|
|
@@ -17817,6 +18652,10 @@ var googleGenAIChannels = defineChannels("@google/genai", {
|
|
|
17817
18652
|
embedContent: channel({
|
|
17818
18653
|
channelName: "models.embedContent",
|
|
17819
18654
|
kind: "async"
|
|
18655
|
+
}),
|
|
18656
|
+
interactionsCreate: channel({
|
|
18657
|
+
channelName: "interactions.create",
|
|
18658
|
+
kind: "async"
|
|
17820
18659
|
})
|
|
17821
18660
|
});
|
|
17822
18661
|
|
|
@@ -17844,6 +18683,7 @@ var GoogleGenAIPlugin = class extends BasePlugin {
|
|
|
17844
18683
|
this.subscribeToGenerateContentChannel();
|
|
17845
18684
|
this.subscribeToGenerateContentStreamChannel();
|
|
17846
18685
|
this.subscribeToEmbedContentChannel();
|
|
18686
|
+
this.subscribeToInteractionsCreateChannel();
|
|
17847
18687
|
}
|
|
17848
18688
|
subscribeToGenerateContentChannel() {
|
|
17849
18689
|
const tracingChannel2 = googleGenAIChannels.generateContent.tracingChannel();
|
|
@@ -18016,7 +18856,30 @@ var GoogleGenAIPlugin = class extends BasePlugin {
|
|
|
18016
18856
|
tracingChannel2.unsubscribe(handlers);
|
|
18017
18857
|
});
|
|
18018
18858
|
}
|
|
18859
|
+
subscribeToInteractionsCreateChannel() {
|
|
18860
|
+
this.unsubscribers.push(
|
|
18861
|
+
traceStreamingChannel(
|
|
18862
|
+
googleGenAIChannels.interactionsCreate,
|
|
18863
|
+
{
|
|
18864
|
+
name: "create_interaction",
|
|
18865
|
+
shouldTrace: ([params]) => !isBackgroundInteractionCreate(params),
|
|
18866
|
+
type: "llm" /* LLM */,
|
|
18867
|
+
extractInput: ([params]) => ({
|
|
18868
|
+
input: serializeInteractionInput(params),
|
|
18869
|
+
metadata: extractInteractionMetadata(params)
|
|
18870
|
+
}),
|
|
18871
|
+
extractOutput: (result) => serializeInteractionValue(result),
|
|
18872
|
+
extractMetadata: (result) => extractInteractionResponseMetadata(result),
|
|
18873
|
+
extractMetrics: (result, startTime) => cleanMetrics3(extractInteractionMetrics(result, startTime)),
|
|
18874
|
+
aggregateChunks: (chunks, _result, _event, startTime) => aggregateInteractionEvents(chunks, startTime)
|
|
18875
|
+
}
|
|
18876
|
+
)
|
|
18877
|
+
);
|
|
18878
|
+
}
|
|
18019
18879
|
};
|
|
18880
|
+
function isBackgroundInteractionCreate(params) {
|
|
18881
|
+
return tryToDict(params)?.background === true;
|
|
18882
|
+
}
|
|
18020
18883
|
function ensureSpanState(states, event, create) {
|
|
18021
18884
|
const existing = states.get(event);
|
|
18022
18885
|
if (existing) {
|
|
@@ -18224,6 +19087,60 @@ function serializeEmbedContentInput(params) {
|
|
|
18224
19087
|
}
|
|
18225
19088
|
return input;
|
|
18226
19089
|
}
|
|
19090
|
+
function serializeInteractionInput(params) {
|
|
19091
|
+
const input = {
|
|
19092
|
+
input: serializeInteractionValue(params.input)
|
|
19093
|
+
};
|
|
19094
|
+
for (const key of [
|
|
19095
|
+
"model",
|
|
19096
|
+
"agent",
|
|
19097
|
+
"agent_config",
|
|
19098
|
+
"api_version",
|
|
19099
|
+
"background",
|
|
19100
|
+
"environment",
|
|
19101
|
+
"generation_config",
|
|
19102
|
+
"previous_interaction_id",
|
|
19103
|
+
"response_format",
|
|
19104
|
+
"response_mime_type",
|
|
19105
|
+
"response_modalities",
|
|
19106
|
+
"service_tier",
|
|
19107
|
+
"store",
|
|
19108
|
+
"stream",
|
|
19109
|
+
"system_instruction",
|
|
19110
|
+
"webhook_config"
|
|
19111
|
+
]) {
|
|
19112
|
+
const value = params[key];
|
|
19113
|
+
if (value !== void 0) {
|
|
19114
|
+
input[key] = serializeInteractionValue(value);
|
|
19115
|
+
}
|
|
19116
|
+
}
|
|
19117
|
+
return input;
|
|
19118
|
+
}
|
|
19119
|
+
function extractInteractionMetadata(params) {
|
|
19120
|
+
const metadata = {};
|
|
19121
|
+
for (const key of [
|
|
19122
|
+
"model",
|
|
19123
|
+
"agent",
|
|
19124
|
+
"agent_config",
|
|
19125
|
+
"generation_config",
|
|
19126
|
+
"system_instruction",
|
|
19127
|
+
"response_format",
|
|
19128
|
+
"response_mime_type",
|
|
19129
|
+
"response_modalities",
|
|
19130
|
+
"service_tier"
|
|
19131
|
+
]) {
|
|
19132
|
+
const value = params[key];
|
|
19133
|
+
if (value !== void 0) {
|
|
19134
|
+
metadata[key] = serializeInteractionValue(value);
|
|
19135
|
+
}
|
|
19136
|
+
}
|
|
19137
|
+
if (Array.isArray(params.tools)) {
|
|
19138
|
+
metadata.tools = params.tools.map(
|
|
19139
|
+
(tool) => serializeInteractionValue(tool)
|
|
19140
|
+
);
|
|
19141
|
+
}
|
|
19142
|
+
return metadata;
|
|
19143
|
+
}
|
|
18227
19144
|
function serializeContentCollection(contents) {
|
|
18228
19145
|
if (contents === null || contents === void 0) {
|
|
18229
19146
|
return null;
|
|
@@ -18254,21 +19171,8 @@ function serializePart(part) {
|
|
|
18254
19171
|
}
|
|
18255
19172
|
if (part.inlineData && part.inlineData.data) {
|
|
18256
19173
|
const { data, mimeType } = part.inlineData;
|
|
18257
|
-
|
|
18258
|
-
|
|
18259
|
-
const filename = `file.${extension}`;
|
|
18260
|
-
const buffer = typeof data === "string" ? typeof Buffer !== "undefined" ? Buffer.from(data, "base64") : new Uint8Array(
|
|
18261
|
-
atob(data).split("").map((c) => c.charCodeAt(0))
|
|
18262
|
-
) : typeof Buffer !== "undefined" ? Buffer.from(data) : new Uint8Array(data);
|
|
18263
|
-
const arrayBuffer = buffer instanceof Uint8Array ? buffer.buffer.slice(
|
|
18264
|
-
buffer.byteOffset,
|
|
18265
|
-
buffer.byteOffset + buffer.byteLength
|
|
18266
|
-
) : buffer;
|
|
18267
|
-
const attachment = new Attachment({
|
|
18268
|
-
data: arrayBuffer,
|
|
18269
|
-
filename,
|
|
18270
|
-
contentType: mimeType || "application/octet-stream"
|
|
18271
|
-
});
|
|
19174
|
+
const attachment = createAttachmentFromInlineData(data, mimeType);
|
|
19175
|
+
if (attachment) {
|
|
18272
19176
|
return {
|
|
18273
19177
|
image_url: { url: attachment }
|
|
18274
19178
|
};
|
|
@@ -18276,6 +19180,59 @@ function serializePart(part) {
|
|
|
18276
19180
|
}
|
|
18277
19181
|
return part;
|
|
18278
19182
|
}
|
|
19183
|
+
function serializeInteractionValue(value, seen = /* @__PURE__ */ new WeakSet()) {
|
|
19184
|
+
if (value === null || value === void 0 || typeof value !== "object") {
|
|
19185
|
+
return value;
|
|
19186
|
+
}
|
|
19187
|
+
if (Array.isArray(value)) {
|
|
19188
|
+
return value.map((item) => serializeInteractionValue(item, seen));
|
|
19189
|
+
}
|
|
19190
|
+
const dict = tryToDict(value);
|
|
19191
|
+
if (dict === null || dict === void 0 || typeof dict !== "object") {
|
|
19192
|
+
return dict;
|
|
19193
|
+
}
|
|
19194
|
+
if (Array.isArray(dict)) {
|
|
19195
|
+
return dict.map((item) => serializeInteractionValue(item, seen));
|
|
19196
|
+
}
|
|
19197
|
+
if (seen.has(dict)) {
|
|
19198
|
+
return "[Circular]";
|
|
19199
|
+
}
|
|
19200
|
+
seen.add(dict);
|
|
19201
|
+
try {
|
|
19202
|
+
const serialized = {};
|
|
19203
|
+
const mimeType = "mime_type" in dict && typeof dict.mime_type === "string" ? dict.mime_type : "mimeType" in dict && typeof dict.mimeType === "string" ? dict.mimeType : void 0;
|
|
19204
|
+
const attachment = mimeType && "data" in dict && dict.data !== void 0 ? createAttachmentFromInlineData(dict.data, mimeType) : null;
|
|
19205
|
+
for (const [key, entry] of Object.entries(dict)) {
|
|
19206
|
+
if (key === "data" && attachment) {
|
|
19207
|
+
serialized[key] = attachment;
|
|
19208
|
+
} else {
|
|
19209
|
+
serialized[key] = serializeInteractionValue(entry, seen);
|
|
19210
|
+
}
|
|
19211
|
+
}
|
|
19212
|
+
return serialized;
|
|
19213
|
+
} finally {
|
|
19214
|
+
seen.delete(dict);
|
|
19215
|
+
}
|
|
19216
|
+
}
|
|
19217
|
+
function createAttachmentFromInlineData(data, mimeType) {
|
|
19218
|
+
if (!(data instanceof Uint8Array || typeof Buffer !== "undefined" && Buffer.isBuffer(data) || typeof data === "string")) {
|
|
19219
|
+
return null;
|
|
19220
|
+
}
|
|
19221
|
+
const extension = mimeType ? mimeType.split("/")[1] : "bin";
|
|
19222
|
+
const filename = `file.${extension}`;
|
|
19223
|
+
const buffer = typeof data === "string" ? typeof Buffer !== "undefined" ? Buffer.from(data, "base64") : new Uint8Array(
|
|
19224
|
+
atob(data).split("").map((c) => c.charCodeAt(0))
|
|
19225
|
+
) : typeof Buffer !== "undefined" ? Buffer.from(data) : new Uint8Array(data);
|
|
19226
|
+
const arrayBuffer = buffer instanceof Uint8Array ? buffer.buffer.slice(
|
|
19227
|
+
buffer.byteOffset,
|
|
19228
|
+
buffer.byteOffset + buffer.byteLength
|
|
19229
|
+
) : buffer;
|
|
19230
|
+
return new Attachment({
|
|
19231
|
+
data: arrayBuffer,
|
|
19232
|
+
filename,
|
|
19233
|
+
contentType: mimeType || "application/octet-stream"
|
|
19234
|
+
});
|
|
19235
|
+
}
|
|
18279
19236
|
function serializeGenerateContentTools(params) {
|
|
18280
19237
|
const config = params.config ? tryToDict(params.config) : null;
|
|
18281
19238
|
const tools = config?.tools;
|
|
@@ -18360,6 +19317,33 @@ function extractEmbedContentMetrics(response, startTime) {
|
|
|
18360
19317
|
}
|
|
18361
19318
|
return metrics;
|
|
18362
19319
|
}
|
|
19320
|
+
function extractInteractionMetrics(response, startTime) {
|
|
19321
|
+
const metrics = {};
|
|
19322
|
+
if (startTime !== void 0) {
|
|
19323
|
+
const end = getCurrentUnixTimestamp();
|
|
19324
|
+
metrics.start = startTime;
|
|
19325
|
+
metrics.end = end;
|
|
19326
|
+
metrics.duration = end - startTime;
|
|
19327
|
+
}
|
|
19328
|
+
if (response?.usage) {
|
|
19329
|
+
populateInteractionUsageMetrics(metrics, response.usage);
|
|
19330
|
+
}
|
|
19331
|
+
return metrics;
|
|
19332
|
+
}
|
|
19333
|
+
function extractInteractionResponseMetadata(response) {
|
|
19334
|
+
const responseDict = tryToDict(response);
|
|
19335
|
+
if (!responseDict) {
|
|
19336
|
+
return void 0;
|
|
19337
|
+
}
|
|
19338
|
+
const metadata = {};
|
|
19339
|
+
if (typeof responseDict.id === "string") {
|
|
19340
|
+
metadata.interaction_id = responseDict.id;
|
|
19341
|
+
}
|
|
19342
|
+
if (typeof responseDict.status === "string") {
|
|
19343
|
+
metadata.status = responseDict.status;
|
|
19344
|
+
}
|
|
19345
|
+
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
19346
|
+
}
|
|
18363
19347
|
function extractEmbedPromptTokenCount(response) {
|
|
18364
19348
|
if (!response) {
|
|
18365
19349
|
return void 0;
|
|
@@ -18422,6 +19406,23 @@ function populateUsageMetrics(metrics, usage) {
|
|
|
18422
19406
|
metrics.completion_reasoning_tokens = usage.thoughtsTokenCount;
|
|
18423
19407
|
}
|
|
18424
19408
|
}
|
|
19409
|
+
function populateInteractionUsageMetrics(metrics, usage) {
|
|
19410
|
+
if (typeof usage.total_input_tokens === "number") {
|
|
19411
|
+
metrics.prompt_tokens = usage.total_input_tokens;
|
|
19412
|
+
}
|
|
19413
|
+
if (typeof usage.total_output_tokens === "number") {
|
|
19414
|
+
metrics.completion_tokens = usage.total_output_tokens;
|
|
19415
|
+
}
|
|
19416
|
+
if (typeof usage.total_tokens === "number") {
|
|
19417
|
+
metrics.tokens = usage.total_tokens;
|
|
19418
|
+
}
|
|
19419
|
+
if (typeof usage.total_cached_tokens === "number") {
|
|
19420
|
+
metrics.prompt_cached_tokens = usage.total_cached_tokens;
|
|
19421
|
+
}
|
|
19422
|
+
if (typeof usage.total_thought_tokens === "number") {
|
|
19423
|
+
metrics.completion_reasoning_tokens = usage.total_thought_tokens;
|
|
19424
|
+
}
|
|
19425
|
+
}
|
|
18425
19426
|
function aggregateGenerateContentChunks(chunks, startTime, firstTokenTime) {
|
|
18426
19427
|
const end = getCurrentUnixTimestamp();
|
|
18427
19428
|
const metrics = {
|
|
@@ -18519,6 +19520,146 @@ function aggregateGenerateContentChunks(chunks, startTime, firstTokenTime) {
|
|
|
18519
19520
|
}
|
|
18520
19521
|
return { aggregated, metrics };
|
|
18521
19522
|
}
|
|
19523
|
+
function aggregateInteractionEvents(chunks, startTime) {
|
|
19524
|
+
const end = getCurrentUnixTimestamp();
|
|
19525
|
+
const metrics = {};
|
|
19526
|
+
if (startTime !== void 0) {
|
|
19527
|
+
metrics.start = startTime;
|
|
19528
|
+
metrics.end = end;
|
|
19529
|
+
metrics.duration = end - startTime;
|
|
19530
|
+
}
|
|
19531
|
+
let latestInteraction;
|
|
19532
|
+
let latestUsage;
|
|
19533
|
+
let status;
|
|
19534
|
+
let outputText = "";
|
|
19535
|
+
const steps = /* @__PURE__ */ new Map();
|
|
19536
|
+
for (const chunk of chunks) {
|
|
19537
|
+
const event = tryToDict(chunk);
|
|
19538
|
+
if (!event) {
|
|
19539
|
+
continue;
|
|
19540
|
+
}
|
|
19541
|
+
const usage = extractInteractionUsageFromEvent(event);
|
|
19542
|
+
if (usage) {
|
|
19543
|
+
latestUsage = usage;
|
|
19544
|
+
}
|
|
19545
|
+
const interaction = tryToDict(event.interaction);
|
|
19546
|
+
if (interaction) {
|
|
19547
|
+
latestInteraction = serializeInteractionValue(interaction);
|
|
19548
|
+
if (typeof interaction.status === "string") {
|
|
19549
|
+
status = interaction.status;
|
|
19550
|
+
}
|
|
19551
|
+
}
|
|
19552
|
+
if (typeof event.status === "string") {
|
|
19553
|
+
status = event.status;
|
|
19554
|
+
}
|
|
19555
|
+
const index = typeof event.index === "number" ? event.index : void 0;
|
|
19556
|
+
if (index === void 0) {
|
|
19557
|
+
continue;
|
|
19558
|
+
}
|
|
19559
|
+
if (event.event_type === "step.start") {
|
|
19560
|
+
const compact = compactInteractionStep(event.step);
|
|
19561
|
+
compact.index = index;
|
|
19562
|
+
steps.set(index, compact);
|
|
19563
|
+
continue;
|
|
19564
|
+
}
|
|
19565
|
+
if (event.event_type === "step.delta") {
|
|
19566
|
+
const step = steps.get(index) ?? { index };
|
|
19567
|
+
const textDelta = applyInteractionDelta(step, event.delta);
|
|
19568
|
+
if (textDelta) {
|
|
19569
|
+
outputText += textDelta;
|
|
19570
|
+
}
|
|
19571
|
+
steps.set(index, step);
|
|
19572
|
+
}
|
|
19573
|
+
}
|
|
19574
|
+
if (latestUsage) {
|
|
19575
|
+
populateInteractionUsageMetrics(metrics, latestUsage);
|
|
19576
|
+
}
|
|
19577
|
+
const output = latestInteraction ? { ...latestInteraction } : {};
|
|
19578
|
+
if (status) {
|
|
19579
|
+
output.status = status;
|
|
19580
|
+
}
|
|
19581
|
+
if (outputText) {
|
|
19582
|
+
output.output_text = outputText;
|
|
19583
|
+
}
|
|
19584
|
+
if (latestUsage) {
|
|
19585
|
+
output.usage = serializeInteractionValue(latestUsage);
|
|
19586
|
+
}
|
|
19587
|
+
const compactSteps = Array.from(steps.values()).sort(
|
|
19588
|
+
(left, right) => Number(left.index ?? 0) - Number(right.index ?? 0)
|
|
19589
|
+
);
|
|
19590
|
+
if (compactSteps.length > 0) {
|
|
19591
|
+
output.steps = compactSteps;
|
|
19592
|
+
}
|
|
19593
|
+
const metadata = {};
|
|
19594
|
+
if (typeof output.id === "string") {
|
|
19595
|
+
metadata.interaction_id = output.id;
|
|
19596
|
+
}
|
|
19597
|
+
if (typeof output.status === "string") {
|
|
19598
|
+
metadata.status = output.status;
|
|
19599
|
+
}
|
|
19600
|
+
return {
|
|
19601
|
+
output,
|
|
19602
|
+
metrics: cleanMetrics3(metrics),
|
|
19603
|
+
...Object.keys(metadata).length > 0 ? { metadata } : {}
|
|
19604
|
+
};
|
|
19605
|
+
}
|
|
19606
|
+
function extractInteractionUsageFromEvent(event) {
|
|
19607
|
+
const metadata = tryToDict(event.metadata);
|
|
19608
|
+
const metadataUsage = tryToDict(metadata?.usage);
|
|
19609
|
+
if (metadataUsage) {
|
|
19610
|
+
return metadataUsage;
|
|
19611
|
+
}
|
|
19612
|
+
const metadataTotalUsage = tryToDict(metadata?.total_usage);
|
|
19613
|
+
if (metadataTotalUsage) {
|
|
19614
|
+
return metadataTotalUsage;
|
|
19615
|
+
}
|
|
19616
|
+
const interaction = tryToDict(event.interaction);
|
|
19617
|
+
const interactionUsage = tryToDict(interaction?.usage);
|
|
19618
|
+
return interactionUsage ? interactionUsage : void 0;
|
|
19619
|
+
}
|
|
19620
|
+
function compactInteractionStep(step) {
|
|
19621
|
+
const stepDict = tryToDict(step);
|
|
19622
|
+
if (!stepDict) {
|
|
19623
|
+
return {};
|
|
19624
|
+
}
|
|
19625
|
+
const compact = {};
|
|
19626
|
+
for (const key of [
|
|
19627
|
+
"type",
|
|
19628
|
+
"content",
|
|
19629
|
+
"name",
|
|
19630
|
+
"server_name",
|
|
19631
|
+
"arguments",
|
|
19632
|
+
"result",
|
|
19633
|
+
"is_error"
|
|
19634
|
+
]) {
|
|
19635
|
+
if (stepDict[key] !== void 0) {
|
|
19636
|
+
compact[key] = serializeInteractionValue(stepDict[key]);
|
|
19637
|
+
}
|
|
19638
|
+
}
|
|
19639
|
+
return Object.keys(compact).length > 0 ? compact : serializeInteractionValue(stepDict);
|
|
19640
|
+
}
|
|
19641
|
+
function applyInteractionDelta(step, delta) {
|
|
19642
|
+
const deltaDict = tryToDict(delta);
|
|
19643
|
+
if (!deltaDict) {
|
|
19644
|
+
return void 0;
|
|
19645
|
+
}
|
|
19646
|
+
const deltaType = deltaDict.type;
|
|
19647
|
+
if (typeof deltaType === "string" && typeof step.type !== "string") {
|
|
19648
|
+
step.type = deltaType === "text" ? "model_output" : deltaType;
|
|
19649
|
+
}
|
|
19650
|
+
if (deltaType === "text" && typeof deltaDict.text === "string") {
|
|
19651
|
+
step.text = `${typeof step.text === "string" ? step.text : ""}${deltaDict.text}`;
|
|
19652
|
+
return deltaDict.text;
|
|
19653
|
+
}
|
|
19654
|
+
if (deltaType === "arguments_delta" && typeof deltaDict.arguments === "string") {
|
|
19655
|
+
step.arguments = `${typeof step.arguments === "string" ? step.arguments : ""}${deltaDict.arguments}`;
|
|
19656
|
+
return void 0;
|
|
19657
|
+
}
|
|
19658
|
+
const deltas = Array.isArray(step.deltas) ? step.deltas : [];
|
|
19659
|
+
deltas.push(serializeInteractionValue(deltaDict));
|
|
19660
|
+
step.deltas = deltas;
|
|
19661
|
+
return void 0;
|
|
19662
|
+
}
|
|
18522
19663
|
function cleanMetrics3(metrics) {
|
|
18523
19664
|
const cleaned = {};
|
|
18524
19665
|
for (const [key, value] of Object.entries(metrics)) {
|
|
@@ -24345,7 +25486,8 @@ var FlueObserveBridge = class {
|
|
|
24345
25486
|
metadata
|
|
24346
25487
|
}
|
|
24347
25488
|
});
|
|
24348
|
-
|
|
25489
|
+
const activeContext = enterCurrentFlueSpan(span);
|
|
25490
|
+
this.runsById.set(event.runId, { activeContext, metadata, span });
|
|
24349
25491
|
}
|
|
24350
25492
|
handleRunEnd(event) {
|
|
24351
25493
|
const state = this.runsById.get(event.runId);
|
|
@@ -24363,6 +25505,7 @@ var FlueObserveBridge = class {
|
|
|
24363
25505
|
});
|
|
24364
25506
|
safeEnd(state.span, eventTime(event.timestamp));
|
|
24365
25507
|
this.runsById.delete(event.runId);
|
|
25508
|
+
restoreCurrentFlueSpan(state.activeContext);
|
|
24366
25509
|
}
|
|
24367
25510
|
void flush().catch((error) => {
|
|
24368
25511
|
logInstrumentationError3("Flue flush", error);
|
|
@@ -24489,7 +25632,8 @@ var FlueObserveBridge = class {
|
|
|
24489
25632
|
metadata
|
|
24490
25633
|
}
|
|
24491
25634
|
});
|
|
24492
|
-
|
|
25635
|
+
const activeContext = enterCurrentFlueSpan(span);
|
|
25636
|
+
this.toolsByKey.set(toolKey(event), { activeContext, metadata, span });
|
|
24493
25637
|
}
|
|
24494
25638
|
handleToolCall(event) {
|
|
24495
25639
|
if (!event.toolCallId) {
|
|
@@ -24512,6 +25656,7 @@ var FlueObserveBridge = class {
|
|
|
24512
25656
|
});
|
|
24513
25657
|
safeEnd(state.span, eventTime(event.timestamp));
|
|
24514
25658
|
this.toolsByKey.delete(key);
|
|
25659
|
+
restoreCurrentFlueSpan(state.activeContext);
|
|
24515
25660
|
}
|
|
24516
25661
|
handleTaskStart(event) {
|
|
24517
25662
|
if (!event.taskId) {
|
|
@@ -24916,6 +26061,34 @@ function stateMatchesRun(state, runId) {
|
|
|
24916
26061
|
function startFlueSpan(parent, args) {
|
|
24917
26062
|
return parent ? withCurrent(parent, () => startSpan(args)) : startSpan(args);
|
|
24918
26063
|
}
|
|
26064
|
+
function enterCurrentFlueSpan(span) {
|
|
26065
|
+
const contextManager = _internalGetGlobalState()?.contextManager;
|
|
26066
|
+
const store = contextManager ? Reflect.get(contextManager, BRAINTRUST_CURRENT_SPAN_STORE) : void 0;
|
|
26067
|
+
if (!contextManager || !isCurrentSpanStore(store)) {
|
|
26068
|
+
return void 0;
|
|
26069
|
+
}
|
|
26070
|
+
const previous = store.getStore();
|
|
26071
|
+
try {
|
|
26072
|
+
store.enterWith(contextManager.wrapSpanForStore(span));
|
|
26073
|
+
return { previous, store };
|
|
26074
|
+
} catch (error) {
|
|
26075
|
+
logInstrumentationError3("Flue context propagation", error);
|
|
26076
|
+
return void 0;
|
|
26077
|
+
}
|
|
26078
|
+
}
|
|
26079
|
+
function isCurrentSpanStore(value) {
|
|
26080
|
+
return isObjectLike(value) && typeof Reflect.get(value, "enterWith") === "function" && typeof Reflect.get(value, "getStore") === "function";
|
|
26081
|
+
}
|
|
26082
|
+
function restoreCurrentFlueSpan(activeContext) {
|
|
26083
|
+
if (!activeContext) {
|
|
26084
|
+
return;
|
|
26085
|
+
}
|
|
26086
|
+
try {
|
|
26087
|
+
activeContext.store.enterWith(activeContext.previous);
|
|
26088
|
+
} catch (error) {
|
|
26089
|
+
logInstrumentationError3("Flue context restoration", error);
|
|
26090
|
+
}
|
|
26091
|
+
}
|
|
24919
26092
|
function safeLog3(span, event) {
|
|
24920
26093
|
try {
|
|
24921
26094
|
span.log(event);
|
|
@@ -25393,6 +26566,890 @@ function isBraintrustHandler(handler) {
|
|
|
25393
26566
|
return Reflect.get(handler, "name") === BRAINTRUST_LANGCHAIN_CALLBACK_HANDLER_NAME;
|
|
25394
26567
|
}
|
|
25395
26568
|
|
|
26569
|
+
// src/instrumentation/plugins/pi-coding-agent-channels.ts
|
|
26570
|
+
var piCodingAgentChannels = defineChannels(
|
|
26571
|
+
"@earendil-works/pi-coding-agent",
|
|
26572
|
+
{
|
|
26573
|
+
prompt: channel({
|
|
26574
|
+
channelName: "AgentSession.prompt",
|
|
26575
|
+
kind: "async"
|
|
26576
|
+
})
|
|
26577
|
+
}
|
|
26578
|
+
);
|
|
26579
|
+
|
|
26580
|
+
// src/instrumentation/plugins/pi-coding-agent-plugin.ts
|
|
26581
|
+
var piStreamPatchStates = /* @__PURE__ */ new WeakMap();
|
|
26582
|
+
var piPromptContextStore;
|
|
26583
|
+
var PiCodingAgentPlugin = class extends BasePlugin {
|
|
26584
|
+
activePromptStates = /* @__PURE__ */ new Set();
|
|
26585
|
+
onEnable() {
|
|
26586
|
+
this.subscribeToPrompt();
|
|
26587
|
+
}
|
|
26588
|
+
onDisable() {
|
|
26589
|
+
for (const unsubscribe of this.unsubscribers) {
|
|
26590
|
+
unsubscribe();
|
|
26591
|
+
}
|
|
26592
|
+
this.unsubscribers = [];
|
|
26593
|
+
for (const state of [...this.activePromptStates]) {
|
|
26594
|
+
void finalizePiPromptRun(state).catch((error) => {
|
|
26595
|
+
logInstrumentationError4("Pi Coding Agent disable cleanup", error);
|
|
26596
|
+
});
|
|
26597
|
+
}
|
|
26598
|
+
}
|
|
26599
|
+
subscribeToPrompt() {
|
|
26600
|
+
const channel2 = piCodingAgentChannels.prompt.tracingChannel();
|
|
26601
|
+
const states = /* @__PURE__ */ new WeakMap();
|
|
26602
|
+
const unbindAutoInstrumentationSuppression = bindAutoInstrumentationSuppressionToStart(channel2);
|
|
26603
|
+
const handlers = {
|
|
26604
|
+
start: (event) => {
|
|
26605
|
+
const state = startPiPromptRun(event, (state2) => {
|
|
26606
|
+
this.activePromptStates.delete(state2);
|
|
26607
|
+
});
|
|
26608
|
+
if (state) {
|
|
26609
|
+
this.activePromptStates.add(state);
|
|
26610
|
+
states.set(event, state);
|
|
26611
|
+
}
|
|
26612
|
+
},
|
|
26613
|
+
asyncEnd: async (event) => {
|
|
26614
|
+
const state = states.get(event);
|
|
26615
|
+
if (!state) {
|
|
26616
|
+
return;
|
|
26617
|
+
}
|
|
26618
|
+
states.delete(event);
|
|
26619
|
+
state.promptCallEnded = true;
|
|
26620
|
+
if (!state.finalized && state.deferCompletionUntilTurnEnd && !state.turnEnded) {
|
|
26621
|
+
if (!state.sawStreamFn) {
|
|
26622
|
+
state.queued = true;
|
|
26623
|
+
if (!state.streamPatchState.queuedPromptStates.includes(state)) {
|
|
26624
|
+
state.streamPatchState.queuedPromptStates.push(state);
|
|
26625
|
+
}
|
|
26626
|
+
}
|
|
26627
|
+
return;
|
|
26628
|
+
}
|
|
26629
|
+
await finalizePiPromptRun(state);
|
|
26630
|
+
},
|
|
26631
|
+
error: async (event) => {
|
|
26632
|
+
const state = states.get(event);
|
|
26633
|
+
if (!state) {
|
|
26634
|
+
return;
|
|
26635
|
+
}
|
|
26636
|
+
states.delete(event);
|
|
26637
|
+
await finalizePiPromptRun(state, event.error);
|
|
26638
|
+
}
|
|
26639
|
+
};
|
|
26640
|
+
channel2.subscribe(handlers);
|
|
26641
|
+
this.unsubscribers.push(() => {
|
|
26642
|
+
unbindAutoInstrumentationSuppression?.();
|
|
26643
|
+
channel2.unsubscribe(handlers);
|
|
26644
|
+
});
|
|
26645
|
+
}
|
|
26646
|
+
};
|
|
26647
|
+
function startPiPromptRun(event, onFinalize) {
|
|
26648
|
+
const session = extractSession(event);
|
|
26649
|
+
const agent = session?.agent;
|
|
26650
|
+
if (!session || !isPiAgent(agent)) {
|
|
26651
|
+
return void 0;
|
|
26652
|
+
}
|
|
26653
|
+
const metadata = {
|
|
26654
|
+
...extractSessionMetadata(session),
|
|
26655
|
+
...extractPromptOptionsMetadata(event.arguments[1]),
|
|
26656
|
+
"pi_coding_agent.operation": "AgentSession.prompt",
|
|
26657
|
+
provider: session.model?.provider ?? agent.state?.model?.provider ?? "pi",
|
|
26658
|
+
...session.model?.id || agent.state?.model?.id ? { model: session.model?.id ?? agent.state?.model?.id } : {},
|
|
26659
|
+
...event.moduleVersion ? { "pi_coding_agent.version": event.moduleVersion } : {}
|
|
26660
|
+
};
|
|
26661
|
+
const span = startSpan({
|
|
26662
|
+
event: {
|
|
26663
|
+
input: extractPromptInput(event.arguments[0], event.arguments[1]),
|
|
26664
|
+
metadata
|
|
26665
|
+
},
|
|
26666
|
+
name: "AgentSession.prompt",
|
|
26667
|
+
spanAttributes: { type: "task" /* TASK */ }
|
|
26668
|
+
});
|
|
26669
|
+
const streamPatchState = installPiStreamPatch(agent);
|
|
26670
|
+
const options = event.arguments[1];
|
|
26671
|
+
const promptText = event.arguments[0];
|
|
26672
|
+
const state = {
|
|
26673
|
+
activeLlmSpans: /* @__PURE__ */ new Set(),
|
|
26674
|
+
activeToolSpans: /* @__PURE__ */ new Map(),
|
|
26675
|
+
agent,
|
|
26676
|
+
collectedLlmUsageMetrics: false,
|
|
26677
|
+
deferCompletionUntilTurnEnd: options?.streamingBehavior === "followUp" || options?.streamingBehavior === "steer",
|
|
26678
|
+
finalized: false,
|
|
26679
|
+
metadata,
|
|
26680
|
+
metrics: {},
|
|
26681
|
+
onFinalize,
|
|
26682
|
+
promptCallEnded: false,
|
|
26683
|
+
...typeof promptText === "string" ? { promptText } : {},
|
|
26684
|
+
queued: false,
|
|
26685
|
+
span,
|
|
26686
|
+
sawStreamFn: false,
|
|
26687
|
+
startTime: getCurrentUnixTimestamp(),
|
|
26688
|
+
streamPatchState,
|
|
26689
|
+
turnEnded: false
|
|
26690
|
+
};
|
|
26691
|
+
state.restorePromptContext = enterPiPromptContext(state);
|
|
26692
|
+
streamPatchState.activePromptStates.add(state);
|
|
26693
|
+
try {
|
|
26694
|
+
state.unsubscribeAgent = agent.subscribe(async (agentEvent) => {
|
|
26695
|
+
try {
|
|
26696
|
+
await runWithAutoInstrumentationSuppressed(
|
|
26697
|
+
() => handlePiAgentEvent(state, agentEvent)
|
|
26698
|
+
);
|
|
26699
|
+
} catch (error) {
|
|
26700
|
+
logInstrumentationError4("Pi Coding Agent event", error);
|
|
26701
|
+
}
|
|
26702
|
+
});
|
|
26703
|
+
} catch (error) {
|
|
26704
|
+
logInstrumentationError4("Pi Coding Agent event subscription", error);
|
|
26705
|
+
}
|
|
26706
|
+
return state;
|
|
26707
|
+
}
|
|
26708
|
+
function extractSession(event) {
|
|
26709
|
+
const candidate = event.session ?? event.self;
|
|
26710
|
+
return isObject(candidate) && typeof candidate.prompt === "function" ? candidate : void 0;
|
|
26711
|
+
}
|
|
26712
|
+
function isPiAgent(value) {
|
|
26713
|
+
return isObject(value) && typeof value.streamFn === "function" && typeof value.subscribe === "function";
|
|
26714
|
+
}
|
|
26715
|
+
function promptContextStore() {
|
|
26716
|
+
piPromptContextStore ??= isomorph_default.newAsyncLocalStorage();
|
|
26717
|
+
return piPromptContextStore;
|
|
26718
|
+
}
|
|
26719
|
+
function currentPromptContextFrames() {
|
|
26720
|
+
return promptContextStore().getStore()?.frames ?? [];
|
|
26721
|
+
}
|
|
26722
|
+
function currentPiPromptState() {
|
|
26723
|
+
const frames = currentPromptContextFrames();
|
|
26724
|
+
return frames[frames.length - 1]?.state;
|
|
26725
|
+
}
|
|
26726
|
+
function enterPiPromptContext(state) {
|
|
26727
|
+
const frame = {
|
|
26728
|
+
id: /* @__PURE__ */ Symbol("braintrust.pi-coding-agent.prompt"),
|
|
26729
|
+
state
|
|
26730
|
+
};
|
|
26731
|
+
promptContextStore().enterWith({
|
|
26732
|
+
frames: [...currentPromptContextFrames(), frame]
|
|
26733
|
+
});
|
|
26734
|
+
return () => {
|
|
26735
|
+
const frames = currentPromptContextFrames().filter(
|
|
26736
|
+
(candidate) => candidate.id !== frame.id
|
|
26737
|
+
);
|
|
26738
|
+
promptContextStore().enterWith(frames.length > 0 ? { frames } : void 0);
|
|
26739
|
+
};
|
|
26740
|
+
}
|
|
26741
|
+
function installPiStreamPatch(agent) {
|
|
26742
|
+
const existing = piStreamPatchStates.get(agent);
|
|
26743
|
+
if (existing) {
|
|
26744
|
+
if (agent.streamFn !== existing.wrappedStreamFn) {
|
|
26745
|
+
debugLogger.debug(
|
|
26746
|
+
"Pi Coding Agent streamFn changed while Braintrust instrumentation was active; preserving existing patch state."
|
|
26747
|
+
);
|
|
26748
|
+
}
|
|
26749
|
+
return existing;
|
|
26750
|
+
}
|
|
26751
|
+
const patchState = {
|
|
26752
|
+
activePromptStates: /* @__PURE__ */ new Set(),
|
|
26753
|
+
agent,
|
|
26754
|
+
originalStreamFn: agent.streamFn,
|
|
26755
|
+
queuedPromptStates: [],
|
|
26756
|
+
wrappedStreamFn: agent.streamFn
|
|
26757
|
+
};
|
|
26758
|
+
patchState.wrappedStreamFn = makeSharedInstrumentedStreamFn(patchState);
|
|
26759
|
+
agent.streamFn = patchState.wrappedStreamFn;
|
|
26760
|
+
piStreamPatchStates.set(agent, patchState);
|
|
26761
|
+
return patchState;
|
|
26762
|
+
}
|
|
26763
|
+
function resolveStreamPromptState(patchState, context) {
|
|
26764
|
+
let lastUserText;
|
|
26765
|
+
if (Array.isArray(context.messages)) {
|
|
26766
|
+
for (let i = context.messages.length - 1; i >= 0; i--) {
|
|
26767
|
+
const message = context.messages[i];
|
|
26768
|
+
if (isPiUserMessage(message)) {
|
|
26769
|
+
if (typeof message.content === "string") {
|
|
26770
|
+
lastUserText = message.content;
|
|
26771
|
+
} else {
|
|
26772
|
+
lastUserText = message.content.flatMap((part) => part.type === "text" ? [part.text] : []).join("");
|
|
26773
|
+
}
|
|
26774
|
+
break;
|
|
26775
|
+
}
|
|
26776
|
+
}
|
|
26777
|
+
}
|
|
26778
|
+
if (lastUserText !== void 0) {
|
|
26779
|
+
const queuedMatch = patchState.queuedPromptStates.find(
|
|
26780
|
+
(state) => state.promptText === lastUserText
|
|
26781
|
+
);
|
|
26782
|
+
if (queuedMatch) {
|
|
26783
|
+
return queuedMatch;
|
|
26784
|
+
}
|
|
26785
|
+
const matches = [...patchState.activePromptStates].filter(
|
|
26786
|
+
(state) => state.promptText === lastUserText
|
|
26787
|
+
);
|
|
26788
|
+
if (matches.length === 1) {
|
|
26789
|
+
return matches[0];
|
|
26790
|
+
}
|
|
26791
|
+
}
|
|
26792
|
+
const contextState = currentPiPromptState();
|
|
26793
|
+
if (contextState && patchState.activePromptStates.has(contextState) && (!contextState.queued || lastUserText !== void 0 && contextState.promptText === lastUserText)) {
|
|
26794
|
+
return contextState;
|
|
26795
|
+
}
|
|
26796
|
+
if (patchState.activePromptStates.size === 1) {
|
|
26797
|
+
return [...patchState.activePromptStates][0];
|
|
26798
|
+
}
|
|
26799
|
+
return void 0;
|
|
26800
|
+
}
|
|
26801
|
+
function makeSharedInstrumentedStreamFn(patchState) {
|
|
26802
|
+
return async function instrumentedPiStreamFn(model, context, options) {
|
|
26803
|
+
const state = resolveStreamPromptState(patchState, context);
|
|
26804
|
+
if (!state) {
|
|
26805
|
+
const invokeOriginal = () => Reflect.apply(patchState.originalStreamFn, this, [
|
|
26806
|
+
model,
|
|
26807
|
+
context,
|
|
26808
|
+
options
|
|
26809
|
+
]);
|
|
26810
|
+
return patchState.activePromptStates.size > 0 ? runWithAutoInstrumentationSuppressed(invokeOriginal) : invokeOriginal();
|
|
26811
|
+
}
|
|
26812
|
+
state.sawStreamFn = true;
|
|
26813
|
+
removeQueuedPromptState(state);
|
|
26814
|
+
state.streamPatchState.eventPromptState = state;
|
|
26815
|
+
const llmState = await startPiLlmSpan(state, model, context, options);
|
|
26816
|
+
try {
|
|
26817
|
+
const stream = await runWithAutoInstrumentationSuppressed(
|
|
26818
|
+
() => Reflect.apply(patchState.originalStreamFn, this, [
|
|
26819
|
+
model,
|
|
26820
|
+
context,
|
|
26821
|
+
options
|
|
26822
|
+
])
|
|
26823
|
+
);
|
|
26824
|
+
return patchAssistantMessageStream(stream, state, llmState);
|
|
26825
|
+
} catch (error) {
|
|
26826
|
+
finishPiLlmSpan(state, llmState, void 0, error);
|
|
26827
|
+
throw error;
|
|
26828
|
+
}
|
|
26829
|
+
};
|
|
26830
|
+
}
|
|
26831
|
+
async function startPiLlmSpan(state, model, context, options) {
|
|
26832
|
+
const metadata = {
|
|
26833
|
+
...extractModelMetadata2(model),
|
|
26834
|
+
...extractStreamOptionsMetadata(options),
|
|
26835
|
+
...extractToolMetadata(context.tools),
|
|
26836
|
+
"pi_coding_agent.operation": "agent.streamFn"
|
|
26837
|
+
};
|
|
26838
|
+
const span = startSpan({
|
|
26839
|
+
event: {
|
|
26840
|
+
input: processInputAttachments(normalizePiContextInput(context)),
|
|
26841
|
+
metadata
|
|
26842
|
+
},
|
|
26843
|
+
name: getLlmSpanName(model),
|
|
26844
|
+
parent: await state.span.export(),
|
|
26845
|
+
spanAttributes: { type: "llm" /* LLM */ }
|
|
26846
|
+
});
|
|
26847
|
+
const llmState = {
|
|
26848
|
+
finalized: false,
|
|
26849
|
+
metadata,
|
|
26850
|
+
metrics: {},
|
|
26851
|
+
span,
|
|
26852
|
+
startTime: getCurrentUnixTimestamp()
|
|
26853
|
+
};
|
|
26854
|
+
state.activeLlmSpans.add(llmState);
|
|
26855
|
+
return llmState;
|
|
26856
|
+
}
|
|
26857
|
+
function patchAssistantMessageStream(stream, promptState, llmState) {
|
|
26858
|
+
if (!isObject(stream)) {
|
|
26859
|
+
return stream;
|
|
26860
|
+
}
|
|
26861
|
+
const streamRecord = stream;
|
|
26862
|
+
const originalResult = stream.result;
|
|
26863
|
+
if (typeof originalResult === "function") {
|
|
26864
|
+
streamRecord.result = function patchedPiResult() {
|
|
26865
|
+
return Promise.resolve(Reflect.apply(originalResult, this, [])).then(
|
|
26866
|
+
(message) => {
|
|
26867
|
+
finishPiLlmSpan(promptState, llmState, message);
|
|
26868
|
+
return message;
|
|
26869
|
+
},
|
|
26870
|
+
(error) => {
|
|
26871
|
+
finishPiLlmSpan(promptState, llmState, void 0, error);
|
|
26872
|
+
throw error;
|
|
26873
|
+
}
|
|
26874
|
+
);
|
|
26875
|
+
};
|
|
26876
|
+
}
|
|
26877
|
+
const originalIterator = stream[Symbol.asyncIterator];
|
|
26878
|
+
if (typeof originalIterator === "function") {
|
|
26879
|
+
streamRecord[Symbol.asyncIterator] = function patchedPiIterator() {
|
|
26880
|
+
const iterator = Reflect.apply(
|
|
26881
|
+
originalIterator,
|
|
26882
|
+
this,
|
|
26883
|
+
[]
|
|
26884
|
+
);
|
|
26885
|
+
return {
|
|
26886
|
+
async next() {
|
|
26887
|
+
try {
|
|
26888
|
+
const result = await iterator.next();
|
|
26889
|
+
if (result.done) {
|
|
26890
|
+
finishPiLlmSpan(promptState, llmState);
|
|
26891
|
+
return result;
|
|
26892
|
+
}
|
|
26893
|
+
recordPiAssistantMessageEvent(promptState, llmState, result.value);
|
|
26894
|
+
return result;
|
|
26895
|
+
} catch (error) {
|
|
26896
|
+
finishPiLlmSpan(promptState, llmState, void 0, error);
|
|
26897
|
+
if (typeof iterator.return === "function") {
|
|
26898
|
+
try {
|
|
26899
|
+
await iterator.return();
|
|
26900
|
+
} catch (cleanupError) {
|
|
26901
|
+
logInstrumentationError4(
|
|
26902
|
+
"Pi Coding Agent stream cleanup",
|
|
26903
|
+
cleanupError
|
|
26904
|
+
);
|
|
26905
|
+
}
|
|
26906
|
+
}
|
|
26907
|
+
throw error;
|
|
26908
|
+
}
|
|
26909
|
+
},
|
|
26910
|
+
async return(value) {
|
|
26911
|
+
try {
|
|
26912
|
+
if (typeof iterator.return === "function") {
|
|
26913
|
+
return await iterator.return(value);
|
|
26914
|
+
}
|
|
26915
|
+
return {
|
|
26916
|
+
done: true,
|
|
26917
|
+
value
|
|
26918
|
+
};
|
|
26919
|
+
} catch (error) {
|
|
26920
|
+
finishPiLlmSpan(promptState, llmState, void 0, error);
|
|
26921
|
+
throw error;
|
|
26922
|
+
} finally {
|
|
26923
|
+
finishPiLlmSpan(promptState, llmState);
|
|
26924
|
+
}
|
|
26925
|
+
},
|
|
26926
|
+
async throw(error) {
|
|
26927
|
+
try {
|
|
26928
|
+
if (typeof iterator.throw === "function") {
|
|
26929
|
+
return await iterator.throw(error);
|
|
26930
|
+
}
|
|
26931
|
+
throw error;
|
|
26932
|
+
} catch (thrownError) {
|
|
26933
|
+
finishPiLlmSpan(promptState, llmState, void 0, thrownError);
|
|
26934
|
+
throw thrownError;
|
|
26935
|
+
}
|
|
26936
|
+
},
|
|
26937
|
+
[Symbol.asyncIterator]() {
|
|
26938
|
+
return this;
|
|
26939
|
+
}
|
|
26940
|
+
};
|
|
26941
|
+
};
|
|
26942
|
+
}
|
|
26943
|
+
return stream;
|
|
26944
|
+
}
|
|
26945
|
+
function recordPiAssistantMessageEvent(promptState, llmState, event) {
|
|
26946
|
+
recordFirstTokenMetric(llmState, event);
|
|
26947
|
+
const message = "message" in event ? event.message : void 0;
|
|
26948
|
+
const errorMessage2 = "error" in event ? event.error : void 0;
|
|
26949
|
+
if (event.type === "done" && isPiAssistantMessage(message)) {
|
|
26950
|
+
finishPiLlmSpan(promptState, llmState, message);
|
|
26951
|
+
} else if (event.type === "error" && isPiAssistantMessage(errorMessage2)) {
|
|
26952
|
+
finishPiLlmSpan(promptState, llmState, errorMessage2);
|
|
26953
|
+
}
|
|
26954
|
+
}
|
|
26955
|
+
function recordFirstTokenMetric(state, event) {
|
|
26956
|
+
if (state.metrics.time_to_first_token !== void 0 || event.type === "start") {
|
|
26957
|
+
return;
|
|
26958
|
+
}
|
|
26959
|
+
state.metrics.time_to_first_token = getCurrentUnixTimestamp() - state.startTime;
|
|
26960
|
+
}
|
|
26961
|
+
async function handlePiAgentEvent(state, event) {
|
|
26962
|
+
if (state.finalized) {
|
|
26963
|
+
return;
|
|
26964
|
+
}
|
|
26965
|
+
const eventPromptState = state.streamPatchState.eventPromptState;
|
|
26966
|
+
if (eventPromptState && eventPromptState !== state) {
|
|
26967
|
+
return;
|
|
26968
|
+
}
|
|
26969
|
+
if (!eventPromptState && (state.queued || state.streamPatchState.activePromptStates.size > 1 && currentPiPromptState() !== state)) {
|
|
26970
|
+
return;
|
|
26971
|
+
}
|
|
26972
|
+
switch (event.type) {
|
|
26973
|
+
case "message_end":
|
|
26974
|
+
if (isPiAssistantMessage(event.message)) {
|
|
26975
|
+
state.output = extractAssistantOutput(event.message);
|
|
26976
|
+
}
|
|
26977
|
+
return;
|
|
26978
|
+
case "turn_end":
|
|
26979
|
+
state.turnEnded = true;
|
|
26980
|
+
if (isPiAssistantMessage(event.message)) {
|
|
26981
|
+
state.output = extractAssistantOutput(event.message);
|
|
26982
|
+
if (!state.collectedLlmUsageMetrics) {
|
|
26983
|
+
addMetrics(state.metrics, extractUsageMetrics2(event.message.usage));
|
|
26984
|
+
}
|
|
26985
|
+
}
|
|
26986
|
+
if (state.streamPatchState.eventPromptState === state) {
|
|
26987
|
+
state.streamPatchState.eventPromptState = void 0;
|
|
26988
|
+
}
|
|
26989
|
+
if (state.promptCallEnded && state.deferCompletionUntilTurnEnd) {
|
|
26990
|
+
await finalizePiPromptRun(state);
|
|
26991
|
+
}
|
|
26992
|
+
return;
|
|
26993
|
+
case "tool_execution_start":
|
|
26994
|
+
await startPiToolSpan(state, event);
|
|
26995
|
+
return;
|
|
26996
|
+
case "tool_execution_end":
|
|
26997
|
+
finishPiToolSpan(state, event);
|
|
26998
|
+
return;
|
|
26999
|
+
default:
|
|
27000
|
+
return;
|
|
27001
|
+
}
|
|
27002
|
+
}
|
|
27003
|
+
async function startPiToolSpan(state, event) {
|
|
27004
|
+
if (!event.toolCallId || state.activeToolSpans.has(event.toolCallId)) {
|
|
27005
|
+
return;
|
|
27006
|
+
}
|
|
27007
|
+
const restoreAutoInstrumentation = enterAutoInstrumentationAllowed();
|
|
27008
|
+
const metadata = {
|
|
27009
|
+
"gen_ai.tool.call.id": event.toolCallId,
|
|
27010
|
+
"gen_ai.tool.name": event.toolName,
|
|
27011
|
+
"pi_coding_agent.tool.name": event.toolName
|
|
27012
|
+
};
|
|
27013
|
+
try {
|
|
27014
|
+
const span = startSpan({
|
|
27015
|
+
event: {
|
|
27016
|
+
input: event.args,
|
|
27017
|
+
metadata
|
|
27018
|
+
},
|
|
27019
|
+
name: event.toolName || "tool",
|
|
27020
|
+
parent: await state.span.export(),
|
|
27021
|
+
spanAttributes: { type: "tool" /* TOOL */ }
|
|
27022
|
+
});
|
|
27023
|
+
state.activeToolSpans.set(event.toolCallId, {
|
|
27024
|
+
restoreAutoInstrumentation,
|
|
27025
|
+
span
|
|
27026
|
+
});
|
|
27027
|
+
} catch (error) {
|
|
27028
|
+
restoreAutoInstrumentation();
|
|
27029
|
+
throw error;
|
|
27030
|
+
}
|
|
27031
|
+
}
|
|
27032
|
+
function finishPiToolSpan(state, event) {
|
|
27033
|
+
const toolState = state.activeToolSpans.get(event.toolCallId);
|
|
27034
|
+
if (!toolState) {
|
|
27035
|
+
return;
|
|
27036
|
+
}
|
|
27037
|
+
state.activeToolSpans.delete(event.toolCallId);
|
|
27038
|
+
const metadata = {
|
|
27039
|
+
"gen_ai.tool.call.id": event.toolCallId,
|
|
27040
|
+
"gen_ai.tool.name": event.toolName,
|
|
27041
|
+
"pi_coding_agent.tool.name": event.toolName,
|
|
27042
|
+
"pi_coding_agent.tool.is_error": event.isError
|
|
27043
|
+
};
|
|
27044
|
+
try {
|
|
27045
|
+
safeLog4(toolState.span, {
|
|
27046
|
+
...event.isError ? { error: stringifyUnknown2(event.result) } : {},
|
|
27047
|
+
metadata,
|
|
27048
|
+
output: event.result
|
|
27049
|
+
});
|
|
27050
|
+
} finally {
|
|
27051
|
+
try {
|
|
27052
|
+
toolState.span.end();
|
|
27053
|
+
} finally {
|
|
27054
|
+
toolState.restoreAutoInstrumentation?.();
|
|
27055
|
+
}
|
|
27056
|
+
}
|
|
27057
|
+
}
|
|
27058
|
+
async function finalizePiPromptRun(state, error) {
|
|
27059
|
+
if (state.finalized) {
|
|
27060
|
+
return;
|
|
27061
|
+
}
|
|
27062
|
+
state.finalized = true;
|
|
27063
|
+
state.onFinalize?.(state);
|
|
27064
|
+
restorePiStreamFn(state);
|
|
27065
|
+
try {
|
|
27066
|
+
state.unsubscribeAgent?.();
|
|
27067
|
+
} catch (unsubscribeError) {
|
|
27068
|
+
logInstrumentationError4("Pi Coding Agent unsubscribe", unsubscribeError);
|
|
27069
|
+
}
|
|
27070
|
+
await finishOpenLlmSpans(state, error);
|
|
27071
|
+
finishOpenToolSpans(state, error);
|
|
27072
|
+
const metadata = {
|
|
27073
|
+
...state.metadata,
|
|
27074
|
+
...extractModelMetadata2(state.agent.state?.model)
|
|
27075
|
+
};
|
|
27076
|
+
try {
|
|
27077
|
+
safeLog4(state.span, {
|
|
27078
|
+
...error ? { error: stringifyUnknown2(error) } : {},
|
|
27079
|
+
metadata,
|
|
27080
|
+
metrics: {
|
|
27081
|
+
...cleanMetrics5(state.metrics),
|
|
27082
|
+
...buildDurationMetrics3(state.startTime)
|
|
27083
|
+
},
|
|
27084
|
+
output: state.output
|
|
27085
|
+
});
|
|
27086
|
+
} finally {
|
|
27087
|
+
state.span.end();
|
|
27088
|
+
}
|
|
27089
|
+
}
|
|
27090
|
+
function restorePiStreamFn(state) {
|
|
27091
|
+
const patchState = state.streamPatchState;
|
|
27092
|
+
patchState.activePromptStates.delete(state);
|
|
27093
|
+
removeQueuedPromptState(state);
|
|
27094
|
+
if (patchState.eventPromptState === state) {
|
|
27095
|
+
patchState.eventPromptState = void 0;
|
|
27096
|
+
}
|
|
27097
|
+
state.restorePromptContext?.();
|
|
27098
|
+
if (patchState.activePromptStates.size > 0) {
|
|
27099
|
+
return;
|
|
27100
|
+
}
|
|
27101
|
+
if (patchState.agent.streamFn === patchState.wrappedStreamFn) {
|
|
27102
|
+
patchState.agent.streamFn = patchState.originalStreamFn;
|
|
27103
|
+
}
|
|
27104
|
+
piStreamPatchStates.delete(patchState.agent);
|
|
27105
|
+
}
|
|
27106
|
+
function removeQueuedPromptState(state) {
|
|
27107
|
+
state.queued = false;
|
|
27108
|
+
const queuedPromptStates = state.streamPatchState.queuedPromptStates;
|
|
27109
|
+
const index = queuedPromptStates.indexOf(state);
|
|
27110
|
+
if (index >= 0) {
|
|
27111
|
+
queuedPromptStates.splice(index, 1);
|
|
27112
|
+
}
|
|
27113
|
+
}
|
|
27114
|
+
async function finishOpenLlmSpans(state, error) {
|
|
27115
|
+
for (const llmState of [...state.activeLlmSpans]) {
|
|
27116
|
+
finishPiLlmSpan(state, llmState, void 0, error);
|
|
27117
|
+
}
|
|
27118
|
+
}
|
|
27119
|
+
function finishPiLlmSpan(promptState, llmState, message, error) {
|
|
27120
|
+
if (llmState.finalized) {
|
|
27121
|
+
return;
|
|
27122
|
+
}
|
|
27123
|
+
llmState.finalized = true;
|
|
27124
|
+
promptState.activeLlmSpans.delete(llmState);
|
|
27125
|
+
const messageError = message?.stopReason === "error" && message.errorMessage;
|
|
27126
|
+
const metrics = {
|
|
27127
|
+
...extractUsageMetrics2(message?.usage),
|
|
27128
|
+
...cleanMetrics5(llmState.metrics),
|
|
27129
|
+
...buildDurationMetrics3(llmState.startTime)
|
|
27130
|
+
};
|
|
27131
|
+
const usageMetrics = extractUsageMetrics2(message?.usage);
|
|
27132
|
+
if (Object.keys(usageMetrics).length > 0) {
|
|
27133
|
+
promptState.collectedLlmUsageMetrics = true;
|
|
27134
|
+
addMetrics(promptState.metrics, usageMetrics);
|
|
27135
|
+
}
|
|
27136
|
+
try {
|
|
27137
|
+
safeLog4(llmState.span, {
|
|
27138
|
+
...error || messageError ? { error: stringifyUnknown2(error ?? messageError) } : {},
|
|
27139
|
+
metadata: {
|
|
27140
|
+
...llmState.metadata,
|
|
27141
|
+
...message ? extractAssistantMetadata(message) : {}
|
|
27142
|
+
},
|
|
27143
|
+
metrics,
|
|
27144
|
+
...message ? { output: extractAssistantOutput(message) } : {}
|
|
27145
|
+
});
|
|
27146
|
+
} finally {
|
|
27147
|
+
llmState.span.end();
|
|
27148
|
+
}
|
|
27149
|
+
}
|
|
27150
|
+
function finishOpenToolSpans(state, error) {
|
|
27151
|
+
for (const [, toolState] of state.activeToolSpans) {
|
|
27152
|
+
try {
|
|
27153
|
+
safeLog4(toolState.span, {
|
|
27154
|
+
error: error ? stringifyUnknown2(error) : "Pi tool did not complete"
|
|
27155
|
+
});
|
|
27156
|
+
toolState.span.end();
|
|
27157
|
+
} finally {
|
|
27158
|
+
toolState.restoreAutoInstrumentation?.();
|
|
27159
|
+
}
|
|
27160
|
+
}
|
|
27161
|
+
state.activeToolSpans.clear();
|
|
27162
|
+
}
|
|
27163
|
+
function normalizePiContextInput(context) {
|
|
27164
|
+
const messages = context.messages.flatMap(
|
|
27165
|
+
(message) => normalizePiMessage(message)
|
|
27166
|
+
);
|
|
27167
|
+
if (context.systemPrompt) {
|
|
27168
|
+
return [{ role: "system", content: context.systemPrompt }, ...messages];
|
|
27169
|
+
}
|
|
27170
|
+
return messages;
|
|
27171
|
+
}
|
|
27172
|
+
function normalizePiMessage(message) {
|
|
27173
|
+
if (isPiUserMessage(message)) {
|
|
27174
|
+
return [
|
|
27175
|
+
{
|
|
27176
|
+
role: "user",
|
|
27177
|
+
content: normalizeUserContent(message.content)
|
|
27178
|
+
}
|
|
27179
|
+
];
|
|
27180
|
+
}
|
|
27181
|
+
if (isPiAssistantMessage(message)) {
|
|
27182
|
+
return [normalizeAssistantMessage(message)];
|
|
27183
|
+
}
|
|
27184
|
+
if (isPiToolResultMessage(message)) {
|
|
27185
|
+
return [normalizeToolResultMessage(message)];
|
|
27186
|
+
}
|
|
27187
|
+
return [];
|
|
27188
|
+
}
|
|
27189
|
+
function normalizeAssistantMessage(message) {
|
|
27190
|
+
const text = message.content.flatMap((part) => part.type === "text" ? [part.text] : []).join("");
|
|
27191
|
+
const thinking = message.content.flatMap(
|
|
27192
|
+
(part) => part.type === "thinking" && !part.redacted ? [part.thinking] : []
|
|
27193
|
+
).join("");
|
|
27194
|
+
const toolCalls = message.content.flatMap(
|
|
27195
|
+
(part) => part.type === "toolCall" ? [normalizeToolCall(part)] : []
|
|
27196
|
+
);
|
|
27197
|
+
return {
|
|
27198
|
+
role: "assistant",
|
|
27199
|
+
content: text || (toolCalls.length > 0 ? null : ""),
|
|
27200
|
+
...thinking ? { reasoning: thinking } : {},
|
|
27201
|
+
...toolCalls.length > 0 ? { tool_calls: toolCalls } : {}
|
|
27202
|
+
};
|
|
27203
|
+
}
|
|
27204
|
+
function normalizeToolResultMessage(message) {
|
|
27205
|
+
return {
|
|
27206
|
+
role: "tool",
|
|
27207
|
+
tool_call_id: message.toolCallId,
|
|
27208
|
+
content: normalizeUserContent(message.content)
|
|
27209
|
+
};
|
|
27210
|
+
}
|
|
27211
|
+
function normalizeUserContent(content) {
|
|
27212
|
+
if (typeof content === "string") {
|
|
27213
|
+
return content;
|
|
27214
|
+
}
|
|
27215
|
+
return content.map((part) => {
|
|
27216
|
+
if (part.type === "text") {
|
|
27217
|
+
return { type: "text", text: part.text };
|
|
27218
|
+
}
|
|
27219
|
+
if (part.type === "image") {
|
|
27220
|
+
return {
|
|
27221
|
+
type: "image_url",
|
|
27222
|
+
image_url: {
|
|
27223
|
+
url: `data:${part.mimeType};base64,${part.data}`
|
|
27224
|
+
}
|
|
27225
|
+
};
|
|
27226
|
+
}
|
|
27227
|
+
return part;
|
|
27228
|
+
});
|
|
27229
|
+
}
|
|
27230
|
+
function normalizeToolCall(toolCall) {
|
|
27231
|
+
return {
|
|
27232
|
+
id: toolCall.id,
|
|
27233
|
+
type: "function",
|
|
27234
|
+
function: {
|
|
27235
|
+
name: toolCall.name,
|
|
27236
|
+
arguments: stringifyArguments(toolCall.arguments)
|
|
27237
|
+
}
|
|
27238
|
+
};
|
|
27239
|
+
}
|
|
27240
|
+
function extractAssistantOutput(message) {
|
|
27241
|
+
return processInputAttachments([
|
|
27242
|
+
{
|
|
27243
|
+
finish_reason: normalizeStopReason(message.stopReason),
|
|
27244
|
+
index: 0,
|
|
27245
|
+
message: normalizeAssistantMessage(message)
|
|
27246
|
+
}
|
|
27247
|
+
]);
|
|
27248
|
+
}
|
|
27249
|
+
function isPiUserMessage(message) {
|
|
27250
|
+
return message.role === "user" && "content" in message;
|
|
27251
|
+
}
|
|
27252
|
+
function isPiAssistantMessage(message) {
|
|
27253
|
+
return isObject(message) && message.role === "assistant" && Array.isArray(message.content);
|
|
27254
|
+
}
|
|
27255
|
+
function isPiToolResultMessage(message) {
|
|
27256
|
+
return message.role === "toolResult" && Array.isArray(message.content);
|
|
27257
|
+
}
|
|
27258
|
+
function normalizeStopReason(reason) {
|
|
27259
|
+
switch (reason) {
|
|
27260
|
+
case "toolUse":
|
|
27261
|
+
return "tool_calls";
|
|
27262
|
+
case "length":
|
|
27263
|
+
case "stop":
|
|
27264
|
+
return reason;
|
|
27265
|
+
default:
|
|
27266
|
+
return reason ?? "stop";
|
|
27267
|
+
}
|
|
27268
|
+
}
|
|
27269
|
+
function extractPromptInput(text, options) {
|
|
27270
|
+
const images = options?.images;
|
|
27271
|
+
if (!images || images.length === 0) {
|
|
27272
|
+
return text;
|
|
27273
|
+
}
|
|
27274
|
+
return processInputAttachments([
|
|
27275
|
+
{
|
|
27276
|
+
role: "user",
|
|
27277
|
+
content: [
|
|
27278
|
+
{ type: "text", text: text ?? "" },
|
|
27279
|
+
...images.map((image) => ({
|
|
27280
|
+
type: "image_url",
|
|
27281
|
+
image_url: {
|
|
27282
|
+
url: `data:${image.mimeType};base64,${image.data}`
|
|
27283
|
+
}
|
|
27284
|
+
}))
|
|
27285
|
+
]
|
|
27286
|
+
}
|
|
27287
|
+
]);
|
|
27288
|
+
}
|
|
27289
|
+
function extractToolMetadata(tools) {
|
|
27290
|
+
if (!tools || tools.length === 0) {
|
|
27291
|
+
return {};
|
|
27292
|
+
}
|
|
27293
|
+
return {
|
|
27294
|
+
tools: tools.map((tool) => ({
|
|
27295
|
+
type: "function",
|
|
27296
|
+
function: {
|
|
27297
|
+
name: tool.name,
|
|
27298
|
+
...tool.description ? { description: tool.description } : {},
|
|
27299
|
+
...tool.parameters ? { parameters: tool.parameters } : {}
|
|
27300
|
+
}
|
|
27301
|
+
}))
|
|
27302
|
+
};
|
|
27303
|
+
}
|
|
27304
|
+
function extractModelMetadata2(model) {
|
|
27305
|
+
if (!model) {
|
|
27306
|
+
return {};
|
|
27307
|
+
}
|
|
27308
|
+
return {
|
|
27309
|
+
...model.provider ? { provider: model.provider } : {},
|
|
27310
|
+
...model.id ? { model: model.id, "pi_coding_agent.model": model.id } : {},
|
|
27311
|
+
...model.api ? { "pi_coding_agent.api": model.api } : {},
|
|
27312
|
+
...model.name ? { "pi_coding_agent.model_name": model.name } : {}
|
|
27313
|
+
};
|
|
27314
|
+
}
|
|
27315
|
+
function extractAssistantMetadata(message) {
|
|
27316
|
+
return {
|
|
27317
|
+
...message.provider ? { provider: message.provider } : {},
|
|
27318
|
+
...message.responseModel || message.model ? { model: message.responseModel ?? message.model } : {},
|
|
27319
|
+
...message.api ? { "pi_coding_agent.api": message.api } : {},
|
|
27320
|
+
...message.model ? { "pi_coding_agent.model": message.model } : {},
|
|
27321
|
+
...message.responseModel ? { "pi_coding_agent.response_model": message.responseModel } : {},
|
|
27322
|
+
...message.responseId ? { "pi_coding_agent.response_id": message.responseId } : {},
|
|
27323
|
+
...message.stopReason ? { "pi_coding_agent.stop_reason": message.stopReason } : {}
|
|
27324
|
+
};
|
|
27325
|
+
}
|
|
27326
|
+
function extractSessionMetadata(session) {
|
|
27327
|
+
return {
|
|
27328
|
+
...extractModelMetadata2(session.model),
|
|
27329
|
+
...session.sessionId ? { "pi_coding_agent.session_id": session.sessionId } : {},
|
|
27330
|
+
...session.sessionName ? { "pi_coding_agent.session_name": session.sessionName } : {},
|
|
27331
|
+
...session.thinkingLevel ? { "pi_coding_agent.thinking_level": session.thinkingLevel } : {},
|
|
27332
|
+
...typeof session.getActiveToolNames === "function" ? { "pi_coding_agent.active_tools": session.getActiveToolNames() } : {}
|
|
27333
|
+
};
|
|
27334
|
+
}
|
|
27335
|
+
function extractPromptOptionsMetadata(options) {
|
|
27336
|
+
if (!options) {
|
|
27337
|
+
return {};
|
|
27338
|
+
}
|
|
27339
|
+
return {
|
|
27340
|
+
...options.source ? { "pi_coding_agent.source": options.source } : {},
|
|
27341
|
+
...options.streamingBehavior ? { "pi_coding_agent.streaming_behavior": options.streamingBehavior } : {},
|
|
27342
|
+
...options.expandPromptTemplates !== void 0 ? {
|
|
27343
|
+
"pi_coding_agent.expand_prompt_templates": options.expandPromptTemplates
|
|
27344
|
+
} : {}
|
|
27345
|
+
};
|
|
27346
|
+
}
|
|
27347
|
+
function extractStreamOptionsMetadata(options) {
|
|
27348
|
+
if (!options) {
|
|
27349
|
+
return {};
|
|
27350
|
+
}
|
|
27351
|
+
return {
|
|
27352
|
+
...options.temperature !== void 0 ? { temperature: options.temperature } : {},
|
|
27353
|
+
...options.maxTokens !== void 0 ? { max_tokens: options.maxTokens } : {},
|
|
27354
|
+
...options.reasoning ? { "pi_coding_agent.reasoning": options.reasoning } : {},
|
|
27355
|
+
...options.transport ? { "pi_coding_agent.transport": options.transport } : {},
|
|
27356
|
+
...options.cacheRetention ? { "pi_coding_agent.cache_retention": options.cacheRetention } : {},
|
|
27357
|
+
...options.sessionId ? { "pi_coding_agent.session_id": options.sessionId } : {},
|
|
27358
|
+
...options.timeoutMs !== void 0 ? { "pi_coding_agent.timeout_ms": options.timeoutMs } : {},
|
|
27359
|
+
...options.maxRetries !== void 0 ? { "pi_coding_agent.max_retries": options.maxRetries } : {},
|
|
27360
|
+
...options.maxRetryDelayMs !== void 0 ? { "pi_coding_agent.max_retry_delay_ms": options.maxRetryDelayMs } : {},
|
|
27361
|
+
...options.metadata ? { "pi_coding_agent.metadata": options.metadata } : {}
|
|
27362
|
+
};
|
|
27363
|
+
}
|
|
27364
|
+
function getLlmSpanName(model) {
|
|
27365
|
+
switch (model.api) {
|
|
27366
|
+
case "anthropic-messages":
|
|
27367
|
+
return "anthropic.messages.create";
|
|
27368
|
+
case "openai-completions":
|
|
27369
|
+
return "Chat Completion";
|
|
27370
|
+
case "openai-responses":
|
|
27371
|
+
case "azure-openai-responses":
|
|
27372
|
+
case "openai-codex-responses":
|
|
27373
|
+
return "openai.responses.create";
|
|
27374
|
+
case "google-generative-ai":
|
|
27375
|
+
case "google-vertex":
|
|
27376
|
+
return "generate_content";
|
|
27377
|
+
case "mistral-conversations":
|
|
27378
|
+
return "mistral.chat.stream";
|
|
27379
|
+
case "bedrock-converse-stream":
|
|
27380
|
+
return "bedrock.converse_stream";
|
|
27381
|
+
default:
|
|
27382
|
+
return "pi_ai.streamSimple";
|
|
27383
|
+
}
|
|
27384
|
+
}
|
|
27385
|
+
function extractUsageMetrics2(usage) {
|
|
27386
|
+
if (!usage) {
|
|
27387
|
+
return {};
|
|
27388
|
+
}
|
|
27389
|
+
return cleanMetrics5({
|
|
27390
|
+
completion_tokens: usage.output,
|
|
27391
|
+
prompt_cache_creation_tokens: usage.cacheWrite,
|
|
27392
|
+
prompt_cached_tokens: usage.cacheRead,
|
|
27393
|
+
prompt_tokens: usage.input,
|
|
27394
|
+
tokens: usage.totalTokens ?? usage.tokens
|
|
27395
|
+
});
|
|
27396
|
+
}
|
|
27397
|
+
function addMetrics(target, source) {
|
|
27398
|
+
for (const [key, value] of Object.entries(source)) {
|
|
27399
|
+
target[key] = (target[key] ?? 0) + value;
|
|
27400
|
+
}
|
|
27401
|
+
}
|
|
27402
|
+
function buildDurationMetrics3(startTime) {
|
|
27403
|
+
const end = getCurrentUnixTimestamp();
|
|
27404
|
+
return {
|
|
27405
|
+
duration: end - startTime,
|
|
27406
|
+
end,
|
|
27407
|
+
start: startTime
|
|
27408
|
+
};
|
|
27409
|
+
}
|
|
27410
|
+
function cleanMetrics5(metrics) {
|
|
27411
|
+
const cleaned = {};
|
|
27412
|
+
for (const [key, value] of Object.entries(metrics)) {
|
|
27413
|
+
if (typeof value === "number" && Number.isFinite(value) && value >= 0) {
|
|
27414
|
+
cleaned[key] = value;
|
|
27415
|
+
}
|
|
27416
|
+
}
|
|
27417
|
+
return cleaned;
|
|
27418
|
+
}
|
|
27419
|
+
function stringifyArguments(value) {
|
|
27420
|
+
if (typeof value === "string") {
|
|
27421
|
+
return value;
|
|
27422
|
+
}
|
|
27423
|
+
try {
|
|
27424
|
+
return JSON.stringify(value);
|
|
27425
|
+
} catch {
|
|
27426
|
+
return stringifyUnknown2(value);
|
|
27427
|
+
}
|
|
27428
|
+
}
|
|
27429
|
+
function stringifyUnknown2(value) {
|
|
27430
|
+
if (value instanceof Error) {
|
|
27431
|
+
return value.message;
|
|
27432
|
+
}
|
|
27433
|
+
if (typeof value === "string") {
|
|
27434
|
+
return value;
|
|
27435
|
+
}
|
|
27436
|
+
try {
|
|
27437
|
+
return JSON.stringify(value);
|
|
27438
|
+
} catch {
|
|
27439
|
+
return String(value);
|
|
27440
|
+
}
|
|
27441
|
+
}
|
|
27442
|
+
function safeLog4(span, event) {
|
|
27443
|
+
try {
|
|
27444
|
+
span.log(event);
|
|
27445
|
+
} catch (error) {
|
|
27446
|
+
logInstrumentationError4("Pi Coding Agent span log", error);
|
|
27447
|
+
}
|
|
27448
|
+
}
|
|
27449
|
+
function logInstrumentationError4(context, error) {
|
|
27450
|
+
debugLogger.debug(`${context}:`, error);
|
|
27451
|
+
}
|
|
27452
|
+
|
|
25396
27453
|
// src/instrumentation/braintrust-plugin.ts
|
|
25397
27454
|
function getIntegrationConfig(integrations, key) {
|
|
25398
27455
|
return integrations[key];
|
|
@@ -25418,6 +27475,7 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
25418
27475
|
gitHubCopilotPlugin = null;
|
|
25419
27476
|
fluePlugin = null;
|
|
25420
27477
|
langChainPlugin = null;
|
|
27478
|
+
piCodingAgentPlugin = null;
|
|
25421
27479
|
constructor(config = {}) {
|
|
25422
27480
|
super();
|
|
25423
27481
|
this.config = config;
|
|
@@ -25492,6 +27550,10 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
25492
27550
|
this.gitHubCopilotPlugin = new GitHubCopilotPlugin();
|
|
25493
27551
|
this.gitHubCopilotPlugin.enable();
|
|
25494
27552
|
}
|
|
27553
|
+
if (integrations.piCodingAgent !== false) {
|
|
27554
|
+
this.piCodingAgentPlugin = new PiCodingAgentPlugin();
|
|
27555
|
+
this.piCodingAgentPlugin.enable();
|
|
27556
|
+
}
|
|
25495
27557
|
if (getIntegrationConfig(integrations, "flue") !== false) {
|
|
25496
27558
|
this.fluePlugin = new FluePlugin();
|
|
25497
27559
|
this.fluePlugin.enable();
|
|
@@ -25570,6 +27632,10 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
25570
27632
|
this.gitHubCopilotPlugin.disable();
|
|
25571
27633
|
this.gitHubCopilotPlugin = null;
|
|
25572
27634
|
}
|
|
27635
|
+
if (this.piCodingAgentPlugin) {
|
|
27636
|
+
this.piCodingAgentPlugin.disable();
|
|
27637
|
+
this.piCodingAgentPlugin = null;
|
|
27638
|
+
}
|
|
25573
27639
|
if (this.fluePlugin) {
|
|
25574
27640
|
this.fluePlugin.disable();
|
|
25575
27641
|
this.fluePlugin = null;
|
|
@@ -25589,6 +27655,11 @@ var envIntegrationAliases = {
|
|
|
25589
27655
|
openaicodexsdk: "openaiCodexSDK",
|
|
25590
27656
|
codex: "openaiCodexSDK",
|
|
25591
27657
|
"codex-sdk": "openaiCodexSDK",
|
|
27658
|
+
"pi-coding-agent": "piCodingAgent",
|
|
27659
|
+
"pi-coding-agent-sdk": "piCodingAgent",
|
|
27660
|
+
picodingagent: "piCodingAgent",
|
|
27661
|
+
picodingagentsdk: "piCodingAgent",
|
|
27662
|
+
"@earendil-works/pi-coding-agent": "piCodingAgent",
|
|
25592
27663
|
anthropic: "anthropic",
|
|
25593
27664
|
aisdk: "aisdk",
|
|
25594
27665
|
"ai-sdk": "aisdk",
|
|
@@ -25654,7 +27725,8 @@ function getDefaultInstrumentationIntegrations() {
|
|
|
25654
27725
|
genkit: true,
|
|
25655
27726
|
gitHubCopilot: true,
|
|
25656
27727
|
langchain: true,
|
|
25657
|
-
langgraph: true
|
|
27728
|
+
langgraph: true,
|
|
27729
|
+
piCodingAgent: true
|
|
25658
27730
|
};
|
|
25659
27731
|
}
|
|
25660
27732
|
function readDisabledInstrumentationEnvConfig(disabledList) {
|
|
@@ -25950,6 +28022,7 @@ __export(exports_exports, {
|
|
|
25950
28022
|
_internalIso: () => isomorph_default,
|
|
25951
28023
|
_internalSetInitialState: () => _internalSetInitialState,
|
|
25952
28024
|
addAzureBlobHeaders: () => addAzureBlobHeaders,
|
|
28025
|
+
braintrustAISDKTelemetry: () => braintrustAISDKTelemetry,
|
|
25953
28026
|
braintrustFlueObserver: () => braintrustFlueObserver,
|
|
25954
28027
|
braintrustStreamChunkSchema: () => braintrustStreamChunkSchema,
|
|
25955
28028
|
buildLocalSummary: () => buildLocalSummary,
|
|
@@ -26042,6 +28115,7 @@ __export(exports_exports, {
|
|
|
26042
28115
|
wrapOpenAIv4: () => wrapOpenAIv4,
|
|
26043
28116
|
wrapOpenRouter: () => wrapOpenRouter,
|
|
26044
28117
|
wrapOpenRouterAgent: () => wrapOpenRouterAgent,
|
|
28118
|
+
wrapPiCodingAgentSDK: () => wrapPiCodingAgentSDK,
|
|
26045
28119
|
wrapTraced: () => wrapTraced,
|
|
26046
28120
|
wrapVitest: () => wrapVitest
|
|
26047
28121
|
});
|
|
@@ -28102,6 +30176,54 @@ function wrapCursorAgent(agent) {
|
|
|
28102
30176
|
return proxy;
|
|
28103
30177
|
}
|
|
28104
30178
|
|
|
30179
|
+
// src/wrappers/pi-coding-agent.ts
|
|
30180
|
+
var WRAPPED_PROMPT = /* @__PURE__ */ Symbol.for("braintrust.pi-coding-agent.wrapped-prompt");
|
|
30181
|
+
function wrapPiCodingAgentSDK(sdk) {
|
|
30182
|
+
if (!sdk || typeof sdk !== "object") {
|
|
30183
|
+
return sdk;
|
|
30184
|
+
}
|
|
30185
|
+
const maybeSDK = sdk;
|
|
30186
|
+
if (!maybeSDK.AgentSession || typeof maybeSDK.AgentSession !== "function") {
|
|
30187
|
+
console.warn("Unsupported Pi Coding Agent SDK. Not wrapping.");
|
|
30188
|
+
return sdk;
|
|
30189
|
+
}
|
|
30190
|
+
patchAgentSessionClass(
|
|
30191
|
+
maybeSDK.AgentSession
|
|
30192
|
+
);
|
|
30193
|
+
return sdk;
|
|
30194
|
+
}
|
|
30195
|
+
function patchAgentSessionClass(AgentSession) {
|
|
30196
|
+
const prototype = AgentSession.prototype;
|
|
30197
|
+
if (!prototype || prototype[WRAPPED_PROMPT]) {
|
|
30198
|
+
return;
|
|
30199
|
+
}
|
|
30200
|
+
const descriptor = Object.getOwnPropertyDescriptor(prototype, "prompt");
|
|
30201
|
+
if (!descriptor || typeof descriptor.value !== "function") {
|
|
30202
|
+
console.warn("Unsupported Pi Coding Agent SDK. Not wrapping.");
|
|
30203
|
+
return;
|
|
30204
|
+
}
|
|
30205
|
+
const originalPrompt = descriptor.value;
|
|
30206
|
+
Object.defineProperty(prototype, "prompt", {
|
|
30207
|
+
...descriptor,
|
|
30208
|
+
value: function wrappedPiCodingAgentPrompt(text, options) {
|
|
30209
|
+
const args = [text, options];
|
|
30210
|
+
return piCodingAgentChannels.prompt.tracePromise(
|
|
30211
|
+
() => Reflect.apply(originalPrompt, this, args),
|
|
30212
|
+
{
|
|
30213
|
+
arguments: args,
|
|
30214
|
+
self: this,
|
|
30215
|
+
session: this
|
|
30216
|
+
}
|
|
30217
|
+
);
|
|
30218
|
+
}
|
|
30219
|
+
});
|
|
30220
|
+
Object.defineProperty(prototype, WRAPPED_PROMPT, {
|
|
30221
|
+
configurable: false,
|
|
30222
|
+
enumerable: false,
|
|
30223
|
+
value: true
|
|
30224
|
+
});
|
|
30225
|
+
}
|
|
30226
|
+
|
|
28105
30227
|
// src/wrappers/google-genai.ts
|
|
28106
30228
|
function wrapGoogleGenAI(googleGenAI) {
|
|
28107
30229
|
if (!googleGenAI || typeof googleGenAI !== "object") {
|
|
@@ -28138,12 +30260,25 @@ function wrapGoogleGenAIClass(OriginalGoogleGenAI) {
|
|
|
28138
30260
|
}
|
|
28139
30261
|
function wrapGoogleGenAIInstance(instance) {
|
|
28140
30262
|
const wrappedModels = wrapModels(instance.models);
|
|
30263
|
+
let originalInteractions;
|
|
30264
|
+
let wrappedInteractions;
|
|
28141
30265
|
patchGoogleGenAIChats(instance, wrappedModels);
|
|
28142
30266
|
return new Proxy(instance, {
|
|
28143
30267
|
get(target, prop, receiver) {
|
|
28144
30268
|
if (prop === "models") {
|
|
28145
30269
|
return wrappedModels;
|
|
28146
30270
|
}
|
|
30271
|
+
if (prop === "interactions") {
|
|
30272
|
+
const interactions = Reflect.get(target, prop, receiver);
|
|
30273
|
+
if (!isObject(interactions) || typeof interactions.create !== "function") {
|
|
30274
|
+
return interactions;
|
|
30275
|
+
}
|
|
30276
|
+
if (interactions !== originalInteractions) {
|
|
30277
|
+
originalInteractions = interactions;
|
|
30278
|
+
wrappedInteractions = wrapInteractions(interactions);
|
|
30279
|
+
}
|
|
30280
|
+
return wrappedInteractions;
|
|
30281
|
+
}
|
|
28147
30282
|
return Reflect.get(target, prop, receiver);
|
|
28148
30283
|
}
|
|
28149
30284
|
});
|
|
@@ -28170,6 +30305,16 @@ function wrapModels(models) {
|
|
|
28170
30305
|
}
|
|
28171
30306
|
});
|
|
28172
30307
|
}
|
|
30308
|
+
function wrapInteractions(interactions) {
|
|
30309
|
+
return new Proxy(interactions, {
|
|
30310
|
+
get(target, prop, receiver) {
|
|
30311
|
+
if (prop === "create") {
|
|
30312
|
+
return wrapInteractionCreate(target.create.bind(target));
|
|
30313
|
+
}
|
|
30314
|
+
return Reflect.get(target, prop, receiver);
|
|
30315
|
+
}
|
|
30316
|
+
});
|
|
30317
|
+
}
|
|
28173
30318
|
function wrapGenerateContent(original) {
|
|
28174
30319
|
return function(params) {
|
|
28175
30320
|
return googleGenAIChannels.generateContent.tracePromise(
|
|
@@ -28194,6 +30339,18 @@ function wrapEmbedContent(original) {
|
|
|
28194
30339
|
);
|
|
28195
30340
|
};
|
|
28196
30341
|
}
|
|
30342
|
+
function wrapInteractionCreate(original) {
|
|
30343
|
+
return function(params, options) {
|
|
30344
|
+
if (params.background === true) {
|
|
30345
|
+
return options === void 0 ? original(params) : original(params, options);
|
|
30346
|
+
}
|
|
30347
|
+
const traceContext = options === void 0 ? { arguments: [params] } : { arguments: [params, options] };
|
|
30348
|
+
return googleGenAIChannels.interactionsCreate.tracePromise(
|
|
30349
|
+
() => options === void 0 ? original(params) : original(params, options),
|
|
30350
|
+
traceContext
|
|
30351
|
+
);
|
|
30352
|
+
};
|
|
30353
|
+
}
|
|
28197
30354
|
|
|
28198
30355
|
// src/wrappers/google-adk.ts
|
|
28199
30356
|
function wrapGoogleADK(adkModule) {
|
|
@@ -31711,6 +33868,13 @@ var EvalResultWithSummary = class {
|
|
|
31711
33868
|
};
|
|
31712
33869
|
}
|
|
31713
33870
|
};
|
|
33871
|
+
async function getPersistedBaseExperimentId(experiment) {
|
|
33872
|
+
try {
|
|
33873
|
+
return await experiment._getBaseExperimentId();
|
|
33874
|
+
} catch {
|
|
33875
|
+
return void 0;
|
|
33876
|
+
}
|
|
33877
|
+
}
|
|
31714
33878
|
function makeEvalName(projectName, experimentName) {
|
|
31715
33879
|
let out = projectName;
|
|
31716
33880
|
if (experimentName) {
|
|
@@ -32093,6 +34257,14 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
|
|
|
32093
34257
|
return;
|
|
32094
34258
|
}
|
|
32095
34259
|
const eventDataset = experiment ? experiment.dataset : Dataset2.isDataset(evaluator.data) ? evaluator.data : void 0;
|
|
34260
|
+
const inlineOrigin = datum.origin === void 0 ? void 0 : ObjectReference.parse(datum.origin);
|
|
34261
|
+
const origin = inlineOrigin ?? (eventDataset && datum.id && datum._xact_id ? {
|
|
34262
|
+
object_type: "dataset",
|
|
34263
|
+
object_id: await eventDataset.id,
|
|
34264
|
+
id: datum.id,
|
|
34265
|
+
created: datum.created,
|
|
34266
|
+
_xact_id: datum._xact_id
|
|
34267
|
+
} : void 0);
|
|
32096
34268
|
const baseEvent = {
|
|
32097
34269
|
name: "eval",
|
|
32098
34270
|
spanAttributes: {
|
|
@@ -32102,13 +34274,7 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
|
|
|
32102
34274
|
input: datum.input,
|
|
32103
34275
|
expected: "expected" in datum ? datum.expected : void 0,
|
|
32104
34276
|
tags: datum.tags,
|
|
32105
|
-
origin
|
|
32106
|
-
object_type: "dataset",
|
|
32107
|
-
object_id: await eventDataset.id,
|
|
32108
|
-
id: datum.id,
|
|
32109
|
-
created: datum.created,
|
|
32110
|
-
_xact_id: datum._xact_id
|
|
32111
|
-
} : void 0,
|
|
34277
|
+
origin,
|
|
32112
34278
|
...datum.upsert_id ? { id: datum.upsert_id } : {}
|
|
32113
34279
|
}
|
|
32114
34280
|
};
|
|
@@ -32465,8 +34631,10 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
|
|
|
32465
34631
|
collectedResults.length = 0;
|
|
32466
34632
|
}
|
|
32467
34633
|
}
|
|
34634
|
+
const comparisonExperimentId = experiment ? evaluator.baseExperimentId ?? await getPersistedBaseExperimentId(experiment) : void 0;
|
|
32468
34635
|
const summary = experiment ? await experiment.summarize({
|
|
32469
|
-
summarizeScores: evaluator.summarizeScores
|
|
34636
|
+
summarizeScores: evaluator.summarizeScores,
|
|
34637
|
+
...comparisonExperimentId !== void 0 ? { comparisonExperimentId } : {}
|
|
32470
34638
|
}) : buildLocalSummary(
|
|
32471
34639
|
evaluator,
|
|
32472
34640
|
collectResults ? collectedResults : [],
|
|
@@ -32695,6 +34863,7 @@ var Project2 = class {
|
|
|
32695
34863
|
prompts;
|
|
32696
34864
|
parameters;
|
|
32697
34865
|
scorers;
|
|
34866
|
+
classifiers;
|
|
32698
34867
|
_publishableCodeFunctions = [];
|
|
32699
34868
|
_publishablePrompts = [];
|
|
32700
34869
|
_publishableParameters = [];
|
|
@@ -32706,6 +34875,7 @@ var Project2 = class {
|
|
|
32706
34875
|
this.prompts = new PromptBuilder(this);
|
|
32707
34876
|
this.parameters = new ParametersBuilder(this);
|
|
32708
34877
|
this.scorers = new ScorerBuilder(this);
|
|
34878
|
+
this.classifiers = new ClassifierBuilder(this);
|
|
32709
34879
|
}
|
|
32710
34880
|
addPrompt(prompt) {
|
|
32711
34881
|
this._publishablePrompts.push(prompt);
|
|
@@ -32840,6 +35010,28 @@ var ScorerBuilder = class {
|
|
|
32840
35010
|
}
|
|
32841
35011
|
}
|
|
32842
35012
|
};
|
|
35013
|
+
var ClassifierBuilder = class {
|
|
35014
|
+
constructor(project) {
|
|
35015
|
+
this.project = project;
|
|
35016
|
+
}
|
|
35017
|
+
taskCounter = 0;
|
|
35018
|
+
create(opts) {
|
|
35019
|
+
this.taskCounter++;
|
|
35020
|
+
let resolvedName = opts.name ?? opts.handler.name;
|
|
35021
|
+
if (!resolvedName || resolvedName.trim().length === 0) {
|
|
35022
|
+
resolvedName = `Classifier ${isomorph_default.basename(currentFilename)} ${this.taskCounter}`;
|
|
35023
|
+
}
|
|
35024
|
+
const slug = opts.slug ?? slugify(resolvedName, { lower: true, strict: true });
|
|
35025
|
+
const classifier = new CodeFunction(this.project, {
|
|
35026
|
+
...opts,
|
|
35027
|
+
name: resolvedName,
|
|
35028
|
+
slug,
|
|
35029
|
+
type: "classifier"
|
|
35030
|
+
});
|
|
35031
|
+
this.project.addCodeFunction(classifier);
|
|
35032
|
+
return classifier;
|
|
35033
|
+
}
|
|
35034
|
+
};
|
|
32843
35035
|
var CodeFunction = class {
|
|
32844
35036
|
constructor(project, opts) {
|
|
32845
35037
|
this.project = project;
|
|
@@ -33189,7 +35381,7 @@ var serializedParametersContainerSchema = import_v313.z.union([
|
|
|
33189
35381
|
staticParametersSchema
|
|
33190
35382
|
]);
|
|
33191
35383
|
var evaluatorDefinitionSchema = import_v313.z.object({
|
|
33192
|
-
parameters: serializedParametersContainerSchema.
|
|
35384
|
+
parameters: serializedParametersContainerSchema.nullish(),
|
|
33193
35385
|
scores: import_v313.z.array(import_v313.z.object({ name: import_v313.z.string() })).optional(),
|
|
33194
35386
|
classifiers: import_v313.z.array(import_v313.z.object({ name: import_v313.z.string() })).optional()
|
|
33195
35387
|
});
|