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/edge-light.js
CHANGED
|
@@ -86,6 +86,7 @@ __export(edge_light_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(edge_light_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
|
});
|
|
@@ -5132,14 +5134,18 @@ function useTestBackgroundLogger() {
|
|
|
5132
5134
|
function clearTestBackgroundLogger() {
|
|
5133
5135
|
_internalGetGlobalState()?.setOverrideBgLogger(null);
|
|
5134
5136
|
}
|
|
5135
|
-
function initTestExperiment(experimentName, projectName) {
|
|
5137
|
+
function initTestExperiment(experimentName, projectName, experimentFullInfo = {}) {
|
|
5136
5138
|
setInitialTestState();
|
|
5137
5139
|
const state = _internalGetGlobalState();
|
|
5138
5140
|
const project = projectName ?? experimentName;
|
|
5139
5141
|
const lazyMetadata = new LazyValue(
|
|
5140
5142
|
async () => ({
|
|
5141
5143
|
project: { id: project, name: project, fullInfo: {} },
|
|
5142
|
-
experiment: {
|
|
5144
|
+
experiment: {
|
|
5145
|
+
id: experimentName,
|
|
5146
|
+
name: experimentName,
|
|
5147
|
+
fullInfo: experimentFullInfo
|
|
5148
|
+
}
|
|
5143
5149
|
})
|
|
5144
5150
|
);
|
|
5145
5151
|
return new Experiment2(state, lazyMetadata);
|
|
@@ -8504,6 +8510,10 @@ var Experiment2 = class extends ObjectFetcher {
|
|
|
8504
8510
|
return (await this.lazyMetadata.get()).project;
|
|
8505
8511
|
})();
|
|
8506
8512
|
}
|
|
8513
|
+
async _getBaseExperimentId() {
|
|
8514
|
+
const baseExperimentId = (await this.lazyMetadata.get()).experiment.fullInfo["base_exp_id"];
|
|
8515
|
+
return typeof baseExperimentId === "string" && baseExperimentId ? baseExperimentId : void 0;
|
|
8516
|
+
}
|
|
8507
8517
|
parentObjectType() {
|
|
8508
8518
|
return 1 /* EXPERIMENT */;
|
|
8509
8519
|
}
|
|
@@ -8644,6 +8654,14 @@ var Experiment2 = class extends ObjectFetcher {
|
|
|
8644
8654
|
comparisonExperimentId = baseExperiment.id;
|
|
8645
8655
|
comparisonExperimentName = baseExperiment.name;
|
|
8646
8656
|
}
|
|
8657
|
+
} else {
|
|
8658
|
+
try {
|
|
8659
|
+
const comparisonExperiment = await state.apiConn().get_json(`v1/experiment/${comparisonExperimentId}`);
|
|
8660
|
+
if (typeof comparisonExperiment["name"] === "string") {
|
|
8661
|
+
comparisonExperimentName = comparisonExperiment["name"];
|
|
8662
|
+
}
|
|
8663
|
+
} catch {
|
|
8664
|
+
}
|
|
8647
8665
|
}
|
|
8648
8666
|
try {
|
|
8649
8667
|
const results = await state.apiConn().get_json(
|
|
@@ -10808,6 +10826,64 @@ var BasePlugin = class {
|
|
|
10808
10826
|
}
|
|
10809
10827
|
};
|
|
10810
10828
|
|
|
10829
|
+
// src/instrumentation/auto-instrumentation-suppression.ts
|
|
10830
|
+
var autoInstrumentationSuppressionStore;
|
|
10831
|
+
function suppressionStore() {
|
|
10832
|
+
autoInstrumentationSuppressionStore ??= isomorph_default.newAsyncLocalStorage();
|
|
10833
|
+
return autoInstrumentationSuppressionStore;
|
|
10834
|
+
}
|
|
10835
|
+
function currentFrames() {
|
|
10836
|
+
return suppressionStore().getStore()?.frames ?? [];
|
|
10837
|
+
}
|
|
10838
|
+
function isAutoInstrumentationSuppressed() {
|
|
10839
|
+
const frames = currentFrames();
|
|
10840
|
+
return frames[frames.length - 1]?.mode === "suppress";
|
|
10841
|
+
}
|
|
10842
|
+
function runWithAutoInstrumentationSuppressed(callback) {
|
|
10843
|
+
const frame = {
|
|
10844
|
+
id: /* @__PURE__ */ Symbol("braintrust.auto-instrumentation-suppress"),
|
|
10845
|
+
mode: "suppress"
|
|
10846
|
+
};
|
|
10847
|
+
return suppressionStore().run(
|
|
10848
|
+
{ frames: [...currentFrames(), frame] },
|
|
10849
|
+
callback
|
|
10850
|
+
);
|
|
10851
|
+
}
|
|
10852
|
+
function bindAutoInstrumentationSuppressionToStart(tracingChannel2) {
|
|
10853
|
+
const startChannel = tracingChannel2.start;
|
|
10854
|
+
if (!startChannel) {
|
|
10855
|
+
return void 0;
|
|
10856
|
+
}
|
|
10857
|
+
const store = suppressionStore();
|
|
10858
|
+
startChannel.bindStore(store, () => ({
|
|
10859
|
+
frames: [
|
|
10860
|
+
...currentFrames(),
|
|
10861
|
+
{
|
|
10862
|
+
id: /* @__PURE__ */ Symbol("braintrust.auto-instrumentation-suppress"),
|
|
10863
|
+
mode: "suppress"
|
|
10864
|
+
}
|
|
10865
|
+
]
|
|
10866
|
+
}));
|
|
10867
|
+
return () => {
|
|
10868
|
+
startChannel.unbindStore(store);
|
|
10869
|
+
};
|
|
10870
|
+
}
|
|
10871
|
+
function enterAutoInstrumentationAllowed() {
|
|
10872
|
+
const frame = {
|
|
10873
|
+
id: /* @__PURE__ */ Symbol("braintrust.auto-instrumentation-allow"),
|
|
10874
|
+
mode: "allow"
|
|
10875
|
+
};
|
|
10876
|
+
suppressionStore().enterWith({
|
|
10877
|
+
frames: [...currentFrames(), frame]
|
|
10878
|
+
});
|
|
10879
|
+
return () => {
|
|
10880
|
+
const frames = currentFrames().filter(
|
|
10881
|
+
(candidate) => candidate.id !== frame.id
|
|
10882
|
+
);
|
|
10883
|
+
suppressionStore().enterWith(frames.length > 0 ? { frames } : void 0);
|
|
10884
|
+
};
|
|
10885
|
+
}
|
|
10886
|
+
|
|
10811
10887
|
// src/instrumentation/core/channel-tracing.ts
|
|
10812
10888
|
function isSyncStreamLike(value) {
|
|
10813
10889
|
return !!value && typeof value === "object" && typeof value.on === "function";
|
|
@@ -10839,16 +10915,33 @@ function startSpanForEvent(config, event, channelName) {
|
|
|
10839
10915
|
metadata: mergeInputMetadata(metadata, spanInfoMetadata)
|
|
10840
10916
|
});
|
|
10841
10917
|
} catch (error) {
|
|
10842
|
-
|
|
10918
|
+
debugLogger.error(`Error extracting input for ${channelName}:`, error);
|
|
10843
10919
|
}
|
|
10844
10920
|
return { span, startTime };
|
|
10845
10921
|
}
|
|
10922
|
+
function shouldTraceEvent(config, event, channelName) {
|
|
10923
|
+
if (!config.shouldTrace) {
|
|
10924
|
+
return true;
|
|
10925
|
+
}
|
|
10926
|
+
try {
|
|
10927
|
+
return config.shouldTrace(event.arguments, event);
|
|
10928
|
+
} catch (error) {
|
|
10929
|
+
debugLogger.error(
|
|
10930
|
+
`Error checking trace predicate for ${channelName}:`,
|
|
10931
|
+
error
|
|
10932
|
+
);
|
|
10933
|
+
return true;
|
|
10934
|
+
}
|
|
10935
|
+
}
|
|
10846
10936
|
function ensureSpanStateForEvent(states, config, event, channelName) {
|
|
10847
10937
|
const key = event;
|
|
10848
10938
|
const existing = states.get(key);
|
|
10849
10939
|
if (existing) {
|
|
10850
10940
|
return existing;
|
|
10851
10941
|
}
|
|
10942
|
+
if (!shouldTraceEvent(config, event, channelName)) {
|
|
10943
|
+
return void 0;
|
|
10944
|
+
}
|
|
10852
10945
|
const created = startSpanForEvent(config, event, channelName);
|
|
10853
10946
|
states.set(key, created);
|
|
10854
10947
|
return created;
|
|
@@ -10864,13 +10957,16 @@ function bindCurrentSpanStoreToStart(tracingChannel2, states, config, channelNam
|
|
|
10864
10957
|
startChannel.bindStore(
|
|
10865
10958
|
currentSpanStore,
|
|
10866
10959
|
(event) => {
|
|
10867
|
-
|
|
10960
|
+
if (isAutoInstrumentationSuppressed()) {
|
|
10961
|
+
return currentSpanStore.getStore();
|
|
10962
|
+
}
|
|
10963
|
+
const spanState = ensureSpanStateForEvent(
|
|
10868
10964
|
states,
|
|
10869
10965
|
config,
|
|
10870
10966
|
event,
|
|
10871
10967
|
channelName
|
|
10872
|
-
)
|
|
10873
|
-
return contextManager.wrapSpanForStore(span);
|
|
10968
|
+
);
|
|
10969
|
+
return spanState ? contextManager.wrapSpanForStore(spanState.span) : currentSpanStore.getStore();
|
|
10874
10970
|
}
|
|
10875
10971
|
);
|
|
10876
10972
|
return () => {
|
|
@@ -10905,7 +11001,10 @@ function runStreamingCompletionHook(args) {
|
|
|
10905
11001
|
startTime: args.startTime
|
|
10906
11002
|
});
|
|
10907
11003
|
} catch (error) {
|
|
10908
|
-
|
|
11004
|
+
debugLogger.error(
|
|
11005
|
+
`Error in onComplete hook for ${args.channelName}:`,
|
|
11006
|
+
error
|
|
11007
|
+
);
|
|
10909
11008
|
}
|
|
10910
11009
|
}
|
|
10911
11010
|
function traceAsyncChannel(channel2, config) {
|
|
@@ -10920,6 +11019,9 @@ function traceAsyncChannel(channel2, config) {
|
|
|
10920
11019
|
);
|
|
10921
11020
|
const handlers = {
|
|
10922
11021
|
start: (event) => {
|
|
11022
|
+
if (isAutoInstrumentationSuppressed()) {
|
|
11023
|
+
return;
|
|
11024
|
+
}
|
|
10923
11025
|
ensureSpanStateForEvent(
|
|
10924
11026
|
states,
|
|
10925
11027
|
config,
|
|
@@ -10954,7 +11056,7 @@ function traceAsyncChannel(channel2, config) {
|
|
|
10954
11056
|
metrics
|
|
10955
11057
|
});
|
|
10956
11058
|
} catch (error) {
|
|
10957
|
-
|
|
11059
|
+
debugLogger.error(`Error extracting output for ${channelName}:`, error);
|
|
10958
11060
|
} finally {
|
|
10959
11061
|
span.end();
|
|
10960
11062
|
states.delete(event);
|
|
@@ -10982,6 +11084,9 @@ function traceStreamingChannel(channel2, config) {
|
|
|
10982
11084
|
);
|
|
10983
11085
|
const handlers = {
|
|
10984
11086
|
start: (event) => {
|
|
11087
|
+
if (isAutoInstrumentationSuppressed()) {
|
|
11088
|
+
return;
|
|
11089
|
+
}
|
|
10985
11090
|
ensureSpanStateForEvent(
|
|
10986
11091
|
states,
|
|
10987
11092
|
config,
|
|
@@ -11053,7 +11158,7 @@ function traceStreamingChannel(channel2, config) {
|
|
|
11053
11158
|
metrics
|
|
11054
11159
|
});
|
|
11055
11160
|
} catch (error) {
|
|
11056
|
-
|
|
11161
|
+
debugLogger.error(
|
|
11057
11162
|
`Error extracting output for ${channelName}:`,
|
|
11058
11163
|
error
|
|
11059
11164
|
);
|
|
@@ -11113,7 +11218,7 @@ function traceStreamingChannel(channel2, config) {
|
|
|
11113
11218
|
metrics
|
|
11114
11219
|
});
|
|
11115
11220
|
} catch (error) {
|
|
11116
|
-
|
|
11221
|
+
debugLogger.error(`Error extracting output for ${channelName}:`, error);
|
|
11117
11222
|
} finally {
|
|
11118
11223
|
span.end();
|
|
11119
11224
|
states.delete(event);
|
|
@@ -11141,6 +11246,9 @@ function traceSyncStreamChannel(channel2, config) {
|
|
|
11141
11246
|
);
|
|
11142
11247
|
const handlers = {
|
|
11143
11248
|
start: (event) => {
|
|
11249
|
+
if (isAutoInstrumentationSuppressed()) {
|
|
11250
|
+
return;
|
|
11251
|
+
}
|
|
11144
11252
|
ensureSpanStateForEvent(
|
|
11145
11253
|
states,
|
|
11146
11254
|
config,
|
|
@@ -11194,7 +11302,7 @@ function traceSyncStreamChannel(channel2, config) {
|
|
|
11194
11302
|
});
|
|
11195
11303
|
}
|
|
11196
11304
|
} catch (error) {
|
|
11197
|
-
|
|
11305
|
+
debugLogger.error(
|
|
11198
11306
|
`Error extracting chatCompletion for ${channelName}:`,
|
|
11199
11307
|
error
|
|
11200
11308
|
);
|
|
@@ -11218,7 +11326,10 @@ function traceSyncStreamChannel(channel2, config) {
|
|
|
11218
11326
|
span.log(extracted);
|
|
11219
11327
|
}
|
|
11220
11328
|
} catch (error) {
|
|
11221
|
-
|
|
11329
|
+
debugLogger.error(
|
|
11330
|
+
`Error extracting event for ${channelName}:`,
|
|
11331
|
+
error
|
|
11332
|
+
);
|
|
11222
11333
|
}
|
|
11223
11334
|
});
|
|
11224
11335
|
stream.on("end", () => {
|
|
@@ -12747,6 +12858,9 @@ var AnthropicPlugin = class extends BasePlugin {
|
|
|
12747
12858
|
const states = /* @__PURE__ */ new WeakMap();
|
|
12748
12859
|
const handlers = {
|
|
12749
12860
|
start: (event) => {
|
|
12861
|
+
if (isAutoInstrumentationSuppressed()) {
|
|
12862
|
+
return;
|
|
12863
|
+
}
|
|
12750
12864
|
const params = event.arguments[0] ?? {};
|
|
12751
12865
|
const span = startSpan({
|
|
12752
12866
|
name: "anthropic.beta.messages.toolRunner",
|
|
@@ -13476,6 +13590,520 @@ function serializeAISDKToolsForLogging(tools) {
|
|
|
13476
13590
|
return serialized;
|
|
13477
13591
|
}
|
|
13478
13592
|
|
|
13593
|
+
// src/wrappers/ai-sdk/telemetry.ts
|
|
13594
|
+
function braintrustAISDKTelemetry() {
|
|
13595
|
+
const operations = /* @__PURE__ */ new Map();
|
|
13596
|
+
const modelSpans = /* @__PURE__ */ new Map();
|
|
13597
|
+
const objectSpans = /* @__PURE__ */ new Map();
|
|
13598
|
+
const embedSpans = /* @__PURE__ */ new Map();
|
|
13599
|
+
const rerankSpans = /* @__PURE__ */ new Map();
|
|
13600
|
+
const toolSpans = /* @__PURE__ */ new Map();
|
|
13601
|
+
const runSafely = (name, callback) => {
|
|
13602
|
+
try {
|
|
13603
|
+
callback();
|
|
13604
|
+
} catch (error) {
|
|
13605
|
+
console.error(`Error in Braintrust AI SDK telemetry ${name}:`, error);
|
|
13606
|
+
}
|
|
13607
|
+
};
|
|
13608
|
+
const startChildSpan = (callId, name, type, event) => {
|
|
13609
|
+
const parent = operations.get(callId)?.span;
|
|
13610
|
+
const spanArgs = {
|
|
13611
|
+
name,
|
|
13612
|
+
spanAttributes: { type },
|
|
13613
|
+
...event ? { event } : {}
|
|
13614
|
+
};
|
|
13615
|
+
const span = parent ? parent.startSpan(spanArgs) : startSpan(spanArgs);
|
|
13616
|
+
const state = operations.get(callId);
|
|
13617
|
+
if (state && type === "llm" /* LLM */) {
|
|
13618
|
+
state.hadModelChild = true;
|
|
13619
|
+
}
|
|
13620
|
+
return span;
|
|
13621
|
+
};
|
|
13622
|
+
return {
|
|
13623
|
+
onStart(event) {
|
|
13624
|
+
runSafely("onStart", () => {
|
|
13625
|
+
const operationName = operationNameFromId(event.operationId);
|
|
13626
|
+
const span = startSpan({
|
|
13627
|
+
name: operationName,
|
|
13628
|
+
spanAttributes: { type: "function" /* FUNCTION */ }
|
|
13629
|
+
});
|
|
13630
|
+
operations.set(event.callId, {
|
|
13631
|
+
hadModelChild: false,
|
|
13632
|
+
operationName,
|
|
13633
|
+
span,
|
|
13634
|
+
startTime: getCurrentUnixTimestamp()
|
|
13635
|
+
});
|
|
13636
|
+
const metadata = metadataFromEvent(event);
|
|
13637
|
+
const logPayload = { metadata };
|
|
13638
|
+
if (shouldRecordInputs(event)) {
|
|
13639
|
+
const { input, outputPromise } = processAISDKCallInput(
|
|
13640
|
+
operationInput(event, operationName)
|
|
13641
|
+
);
|
|
13642
|
+
logPayload.input = input;
|
|
13643
|
+
if (outputPromise && input && typeof input === "object") {
|
|
13644
|
+
outputPromise.then((resolvedData) => {
|
|
13645
|
+
span.log({
|
|
13646
|
+
input: {
|
|
13647
|
+
...input,
|
|
13648
|
+
...resolvedData
|
|
13649
|
+
}
|
|
13650
|
+
});
|
|
13651
|
+
}).catch(() => {
|
|
13652
|
+
});
|
|
13653
|
+
}
|
|
13654
|
+
}
|
|
13655
|
+
span.log(logPayload);
|
|
13656
|
+
});
|
|
13657
|
+
},
|
|
13658
|
+
onLanguageModelCallStart(event) {
|
|
13659
|
+
runSafely("onLanguageModelCallStart", () => {
|
|
13660
|
+
const state = operations.get(event.callId);
|
|
13661
|
+
const openSpans = modelSpans.get(event.callId);
|
|
13662
|
+
if (openSpans) {
|
|
13663
|
+
for (const span2 of openSpans) {
|
|
13664
|
+
span2.end();
|
|
13665
|
+
}
|
|
13666
|
+
modelSpans.delete(event.callId);
|
|
13667
|
+
}
|
|
13668
|
+
const span = startChildSpan(
|
|
13669
|
+
event.callId,
|
|
13670
|
+
state?.operationName === "streamText" ? "doStream" : "doGenerate",
|
|
13671
|
+
"llm" /* LLM */,
|
|
13672
|
+
{
|
|
13673
|
+
...shouldRecordInputs(event) ? {
|
|
13674
|
+
input: processAISDKCallInput(
|
|
13675
|
+
operationInput(
|
|
13676
|
+
event,
|
|
13677
|
+
state?.operationName ?? "generateText"
|
|
13678
|
+
)
|
|
13679
|
+
).input
|
|
13680
|
+
} : {},
|
|
13681
|
+
metadata: metadataFromEvent(event)
|
|
13682
|
+
}
|
|
13683
|
+
);
|
|
13684
|
+
const spans = modelSpans.get(event.callId) ?? [];
|
|
13685
|
+
spans.push(span);
|
|
13686
|
+
modelSpans.set(event.callId, spans);
|
|
13687
|
+
});
|
|
13688
|
+
},
|
|
13689
|
+
onLanguageModelCallEnd(event) {
|
|
13690
|
+
runSafely("onLanguageModelCallEnd", () => {
|
|
13691
|
+
const span = shiftModelSpan(modelSpans, event.callId);
|
|
13692
|
+
if (!span) {
|
|
13693
|
+
return;
|
|
13694
|
+
}
|
|
13695
|
+
const result = {
|
|
13696
|
+
...event,
|
|
13697
|
+
response: event.responseId ? { id: event.responseId } : void 0
|
|
13698
|
+
};
|
|
13699
|
+
span.log({
|
|
13700
|
+
...shouldRecordOutputs(event) ? {
|
|
13701
|
+
output: processAISDKOutput(result, DEFAULT_DENY_OUTPUT_PATHS)
|
|
13702
|
+
} : {},
|
|
13703
|
+
metrics: extractTokenMetrics(result)
|
|
13704
|
+
});
|
|
13705
|
+
span.end();
|
|
13706
|
+
});
|
|
13707
|
+
},
|
|
13708
|
+
onObjectStepStart(event) {
|
|
13709
|
+
runSafely("onObjectStepStart", () => {
|
|
13710
|
+
const state = operations.get(event.callId);
|
|
13711
|
+
const openSpan = objectSpans.get(event.callId);
|
|
13712
|
+
if (openSpan) {
|
|
13713
|
+
openSpan.end();
|
|
13714
|
+
objectSpans.delete(event.callId);
|
|
13715
|
+
}
|
|
13716
|
+
const span = startChildSpan(
|
|
13717
|
+
event.callId,
|
|
13718
|
+
state?.operationName === "streamObject" ? "doStream" : "doGenerate",
|
|
13719
|
+
"llm" /* LLM */,
|
|
13720
|
+
{
|
|
13721
|
+
...shouldRecordInputs(event) ? {
|
|
13722
|
+
input: {
|
|
13723
|
+
prompt: event.promptMessages
|
|
13724
|
+
}
|
|
13725
|
+
} : {},
|
|
13726
|
+
metadata: metadataFromEvent(event)
|
|
13727
|
+
}
|
|
13728
|
+
);
|
|
13729
|
+
objectSpans.set(event.callId, span);
|
|
13730
|
+
});
|
|
13731
|
+
},
|
|
13732
|
+
onObjectStepFinish(event) {
|
|
13733
|
+
runSafely("onObjectStepFinish", () => {
|
|
13734
|
+
const span = objectSpans.get(event.callId);
|
|
13735
|
+
if (!span) {
|
|
13736
|
+
return;
|
|
13737
|
+
}
|
|
13738
|
+
const result = {
|
|
13739
|
+
...event,
|
|
13740
|
+
text: event.objectText
|
|
13741
|
+
};
|
|
13742
|
+
span.log({
|
|
13743
|
+
...shouldRecordOutputs(event) ? {
|
|
13744
|
+
output: processAISDKOutput(result, DEFAULT_DENY_OUTPUT_PATHS)
|
|
13745
|
+
} : {},
|
|
13746
|
+
metrics: extractTokenMetrics(result)
|
|
13747
|
+
});
|
|
13748
|
+
span.end();
|
|
13749
|
+
objectSpans.delete(event.callId);
|
|
13750
|
+
});
|
|
13751
|
+
},
|
|
13752
|
+
onEmbedStart(event) {
|
|
13753
|
+
runSafely("onEmbedStart", () => {
|
|
13754
|
+
const state = operations.get(event.callId);
|
|
13755
|
+
for (const [embedCallId, embedState] of embedSpans) {
|
|
13756
|
+
if (embedState.callId === event.callId && (state?.operationName === "embed" || embedState.values === event.values)) {
|
|
13757
|
+
embedState.span.end();
|
|
13758
|
+
embedSpans.delete(embedCallId);
|
|
13759
|
+
}
|
|
13760
|
+
}
|
|
13761
|
+
const span = startChildSpan(
|
|
13762
|
+
event.callId,
|
|
13763
|
+
"doEmbed",
|
|
13764
|
+
"llm" /* LLM */,
|
|
13765
|
+
{
|
|
13766
|
+
...shouldRecordInputs(event) ? {
|
|
13767
|
+
input: {
|
|
13768
|
+
values: event.values
|
|
13769
|
+
}
|
|
13770
|
+
} : {},
|
|
13771
|
+
metadata: metadataFromEvent(event)
|
|
13772
|
+
}
|
|
13773
|
+
);
|
|
13774
|
+
embedSpans.set(event.embedCallId, {
|
|
13775
|
+
callId: event.callId,
|
|
13776
|
+
span,
|
|
13777
|
+
values: event.values
|
|
13778
|
+
});
|
|
13779
|
+
});
|
|
13780
|
+
},
|
|
13781
|
+
onEmbedFinish(event) {
|
|
13782
|
+
runSafely("onEmbedFinish", () => {
|
|
13783
|
+
const state = embedSpans.get(event.embedCallId);
|
|
13784
|
+
if (!state) {
|
|
13785
|
+
return;
|
|
13786
|
+
}
|
|
13787
|
+
const result = {
|
|
13788
|
+
...event,
|
|
13789
|
+
embeddings: event.embeddings
|
|
13790
|
+
};
|
|
13791
|
+
state.span.log({
|
|
13792
|
+
...shouldRecordOutputs(event) ? {
|
|
13793
|
+
output: processAISDKEmbeddingOutput(
|
|
13794
|
+
result,
|
|
13795
|
+
DEFAULT_DENY_OUTPUT_PATHS
|
|
13796
|
+
)
|
|
13797
|
+
} : {},
|
|
13798
|
+
metrics: extractTokenMetrics(result)
|
|
13799
|
+
});
|
|
13800
|
+
state.span.end();
|
|
13801
|
+
embedSpans.delete(event.embedCallId);
|
|
13802
|
+
});
|
|
13803
|
+
},
|
|
13804
|
+
onRerankStart(event) {
|
|
13805
|
+
runSafely("onRerankStart", () => {
|
|
13806
|
+
const openSpan = rerankSpans.get(event.callId);
|
|
13807
|
+
if (openSpan) {
|
|
13808
|
+
openSpan.end();
|
|
13809
|
+
rerankSpans.delete(event.callId);
|
|
13810
|
+
}
|
|
13811
|
+
const span = startChildSpan(
|
|
13812
|
+
event.callId,
|
|
13813
|
+
"doRerank",
|
|
13814
|
+
"llm" /* LLM */,
|
|
13815
|
+
{
|
|
13816
|
+
...shouldRecordInputs(event) ? {
|
|
13817
|
+
input: {
|
|
13818
|
+
documents: event.documents,
|
|
13819
|
+
query: event.query,
|
|
13820
|
+
topN: event.topN
|
|
13821
|
+
}
|
|
13822
|
+
} : {},
|
|
13823
|
+
metadata: metadataFromEvent(event)
|
|
13824
|
+
}
|
|
13825
|
+
);
|
|
13826
|
+
rerankSpans.set(event.callId, span);
|
|
13827
|
+
});
|
|
13828
|
+
},
|
|
13829
|
+
onRerankFinish(event) {
|
|
13830
|
+
runSafely("onRerankFinish", () => {
|
|
13831
|
+
const span = rerankSpans.get(event.callId);
|
|
13832
|
+
if (!span) {
|
|
13833
|
+
return;
|
|
13834
|
+
}
|
|
13835
|
+
const result = {
|
|
13836
|
+
ranking: event.ranking?.map((entry) => ({
|
|
13837
|
+
originalIndex: entry.index,
|
|
13838
|
+
score: entry.relevanceScore
|
|
13839
|
+
}))
|
|
13840
|
+
};
|
|
13841
|
+
span.log({
|
|
13842
|
+
...shouldRecordOutputs(event) ? {
|
|
13843
|
+
output: processAISDKRerankOutput(
|
|
13844
|
+
result,
|
|
13845
|
+
DEFAULT_DENY_OUTPUT_PATHS
|
|
13846
|
+
)
|
|
13847
|
+
} : {}
|
|
13848
|
+
});
|
|
13849
|
+
span.end();
|
|
13850
|
+
rerankSpans.delete(event.callId);
|
|
13851
|
+
});
|
|
13852
|
+
},
|
|
13853
|
+
onToolExecutionStart(event) {
|
|
13854
|
+
runSafely("onToolExecutionStart", () => {
|
|
13855
|
+
const toolCallId = event.toolCall.toolCallId;
|
|
13856
|
+
if (!toolCallId) {
|
|
13857
|
+
return;
|
|
13858
|
+
}
|
|
13859
|
+
const span = startChildSpan(
|
|
13860
|
+
event.callId,
|
|
13861
|
+
event.toolCall.toolName || "tool",
|
|
13862
|
+
"tool" /* TOOL */,
|
|
13863
|
+
{
|
|
13864
|
+
...shouldRecordInputs(event) ? {
|
|
13865
|
+
input: event.toolCall.input
|
|
13866
|
+
} : {},
|
|
13867
|
+
metadata: {
|
|
13868
|
+
...createAISDKIntegrationMetadata(),
|
|
13869
|
+
toolCallId,
|
|
13870
|
+
...typeof event.toolCall.toolName === "string" ? { toolName: event.toolCall.toolName } : {}
|
|
13871
|
+
}
|
|
13872
|
+
}
|
|
13873
|
+
);
|
|
13874
|
+
toolSpans.set(toolCallId, { callId: event.callId, span });
|
|
13875
|
+
});
|
|
13876
|
+
},
|
|
13877
|
+
onToolExecutionEnd(event) {
|
|
13878
|
+
runSafely("onToolExecutionEnd", () => {
|
|
13879
|
+
const toolCallId = event.toolCall.toolCallId;
|
|
13880
|
+
const state = toolCallId ? toolSpans.get(toolCallId) : void 0;
|
|
13881
|
+
if (!toolCallId || !state) {
|
|
13882
|
+
return;
|
|
13883
|
+
}
|
|
13884
|
+
const toolOutput = event.toolOutput;
|
|
13885
|
+
if (toolOutput?.type === "tool-error") {
|
|
13886
|
+
state.span.log({
|
|
13887
|
+
error: toolOutput.error instanceof Error ? toolOutput.error.message : String(toolOutput?.error),
|
|
13888
|
+
metrics: typeof event.durationMs === "number" ? { duration_ms: event.durationMs } : {}
|
|
13889
|
+
});
|
|
13890
|
+
} else {
|
|
13891
|
+
state.span.log({
|
|
13892
|
+
...shouldRecordOutputs(event) ? { output: toolOutput?.output } : {},
|
|
13893
|
+
metrics: typeof event.durationMs === "number" ? { duration_ms: event.durationMs } : {}
|
|
13894
|
+
});
|
|
13895
|
+
}
|
|
13896
|
+
state.span.end();
|
|
13897
|
+
toolSpans.delete(toolCallId);
|
|
13898
|
+
});
|
|
13899
|
+
},
|
|
13900
|
+
onChunk(event) {
|
|
13901
|
+
runSafely("onChunk", () => {
|
|
13902
|
+
const callId = event.chunk?.callId;
|
|
13903
|
+
if (!callId) {
|
|
13904
|
+
return;
|
|
13905
|
+
}
|
|
13906
|
+
const state = operations.get(callId);
|
|
13907
|
+
if (!state || state.firstChunkTime !== void 0) {
|
|
13908
|
+
return;
|
|
13909
|
+
}
|
|
13910
|
+
state.firstChunkTime = getCurrentUnixTimestamp();
|
|
13911
|
+
});
|
|
13912
|
+
},
|
|
13913
|
+
onFinish(event) {
|
|
13914
|
+
runSafely("onFinish", () => {
|
|
13915
|
+
const state = operations.get(event.callId);
|
|
13916
|
+
if (!state) {
|
|
13917
|
+
return;
|
|
13918
|
+
}
|
|
13919
|
+
const result = finishResult(event, state.operationName);
|
|
13920
|
+
const metrics = state.hadModelChild ? {} : extractTokenMetrics(result);
|
|
13921
|
+
if (state.firstChunkTime !== void 0) {
|
|
13922
|
+
metrics.time_to_first_token = state.firstChunkTime - state.startTime;
|
|
13923
|
+
}
|
|
13924
|
+
state.span.log({
|
|
13925
|
+
...shouldRecordOutputs(event) ? {
|
|
13926
|
+
output: finishOutput(result, state.operationName)
|
|
13927
|
+
} : {},
|
|
13928
|
+
metrics
|
|
13929
|
+
});
|
|
13930
|
+
state.span.end();
|
|
13931
|
+
operations.delete(event.callId);
|
|
13932
|
+
});
|
|
13933
|
+
},
|
|
13934
|
+
onError(event) {
|
|
13935
|
+
runSafely("onError", () => {
|
|
13936
|
+
const errorEvent = isObject(event) ? event : {};
|
|
13937
|
+
const callId = typeof errorEvent.callId === "string" ? errorEvent.callId : void 0;
|
|
13938
|
+
if (!callId) {
|
|
13939
|
+
return;
|
|
13940
|
+
}
|
|
13941
|
+
const state = operations.get(callId);
|
|
13942
|
+
if (!state) {
|
|
13943
|
+
return;
|
|
13944
|
+
}
|
|
13945
|
+
const error = errorEvent.error ?? event;
|
|
13946
|
+
const openModelSpans = modelSpans.get(callId);
|
|
13947
|
+
if (openModelSpans) {
|
|
13948
|
+
for (const span of openModelSpans) {
|
|
13949
|
+
logError(span, error);
|
|
13950
|
+
span.end();
|
|
13951
|
+
}
|
|
13952
|
+
modelSpans.delete(callId);
|
|
13953
|
+
}
|
|
13954
|
+
const openObjectSpan = objectSpans.get(callId);
|
|
13955
|
+
if (openObjectSpan) {
|
|
13956
|
+
logError(openObjectSpan, error);
|
|
13957
|
+
openObjectSpan.end();
|
|
13958
|
+
objectSpans.delete(callId);
|
|
13959
|
+
}
|
|
13960
|
+
for (const [embedCallId, embedState] of embedSpans) {
|
|
13961
|
+
if (embedState.callId === callId) {
|
|
13962
|
+
logError(embedState.span, error);
|
|
13963
|
+
embedState.span.end();
|
|
13964
|
+
embedSpans.delete(embedCallId);
|
|
13965
|
+
}
|
|
13966
|
+
}
|
|
13967
|
+
const openRerankSpan = rerankSpans.get(callId);
|
|
13968
|
+
if (openRerankSpan) {
|
|
13969
|
+
logError(openRerankSpan, error);
|
|
13970
|
+
openRerankSpan.end();
|
|
13971
|
+
rerankSpans.delete(callId);
|
|
13972
|
+
}
|
|
13973
|
+
for (const [toolCallId, toolState] of toolSpans) {
|
|
13974
|
+
if (toolState.callId === callId) {
|
|
13975
|
+
logError(toolState.span, error);
|
|
13976
|
+
toolState.span.end();
|
|
13977
|
+
toolSpans.delete(toolCallId);
|
|
13978
|
+
}
|
|
13979
|
+
}
|
|
13980
|
+
logError(state.span, error);
|
|
13981
|
+
state.span.end();
|
|
13982
|
+
operations.delete(callId);
|
|
13983
|
+
});
|
|
13984
|
+
},
|
|
13985
|
+
executeTool({ toolCallId, execute }) {
|
|
13986
|
+
const state = toolSpans.get(toolCallId);
|
|
13987
|
+
return state ? withCurrent(state.span, () => execute()) : execute();
|
|
13988
|
+
}
|
|
13989
|
+
};
|
|
13990
|
+
}
|
|
13991
|
+
function shouldRecordInputs(event) {
|
|
13992
|
+
return event.recordInputs !== false;
|
|
13993
|
+
}
|
|
13994
|
+
function shouldRecordOutputs(event) {
|
|
13995
|
+
return event.recordOutputs !== false;
|
|
13996
|
+
}
|
|
13997
|
+
function operationNameFromId(operationId) {
|
|
13998
|
+
return operationId?.startsWith("ai.") ? operationId.slice("ai.".length) : operationId || "ai-sdk";
|
|
13999
|
+
}
|
|
14000
|
+
function modelFromEvent(event) {
|
|
14001
|
+
return event.modelId ? {
|
|
14002
|
+
modelId: event.modelId,
|
|
14003
|
+
...event.provider ? { provider: event.provider } : {}
|
|
14004
|
+
} : void 0;
|
|
14005
|
+
}
|
|
14006
|
+
function metadataFromEvent(event) {
|
|
14007
|
+
const metadata = createAISDKIntegrationMetadata();
|
|
14008
|
+
const { model, provider } = serializeModelWithProvider(modelFromEvent(event));
|
|
14009
|
+
if (model) {
|
|
14010
|
+
metadata.model = model;
|
|
14011
|
+
}
|
|
14012
|
+
if (provider) {
|
|
14013
|
+
metadata.provider = provider;
|
|
14014
|
+
}
|
|
14015
|
+
if (typeof event.functionId === "string") {
|
|
14016
|
+
metadata.functionId = event.functionId;
|
|
14017
|
+
}
|
|
14018
|
+
return metadata;
|
|
14019
|
+
}
|
|
14020
|
+
function operationInput(event, operationName) {
|
|
14021
|
+
if (operationName === "embed") {
|
|
14022
|
+
return {
|
|
14023
|
+
model: modelFromEvent(event),
|
|
14024
|
+
value: event.value
|
|
14025
|
+
};
|
|
14026
|
+
}
|
|
14027
|
+
if (operationName === "embedMany") {
|
|
14028
|
+
return {
|
|
14029
|
+
model: modelFromEvent(event),
|
|
14030
|
+
values: Array.isArray(event.value) ? event.value ?? [] : void 0
|
|
14031
|
+
};
|
|
14032
|
+
}
|
|
14033
|
+
if (operationName === "rerank") {
|
|
14034
|
+
return {
|
|
14035
|
+
model: modelFromEvent(event),
|
|
14036
|
+
documents: event.documents,
|
|
14037
|
+
query: event.query,
|
|
14038
|
+
topN: event.topN
|
|
14039
|
+
};
|
|
14040
|
+
}
|
|
14041
|
+
return {
|
|
14042
|
+
model: modelFromEvent(event),
|
|
14043
|
+
system: event.system,
|
|
14044
|
+
prompt: event.prompt,
|
|
14045
|
+
messages: event.messages,
|
|
14046
|
+
tools: event.tools,
|
|
14047
|
+
toolChoice: event.toolChoice,
|
|
14048
|
+
activeTools: event.activeTools,
|
|
14049
|
+
output: event.output,
|
|
14050
|
+
schema: event.schema,
|
|
14051
|
+
schemaName: event.schemaName,
|
|
14052
|
+
schemaDescription: event.schemaDescription,
|
|
14053
|
+
maxOutputTokens: event.maxOutputTokens,
|
|
14054
|
+
temperature: event.temperature,
|
|
14055
|
+
topP: event.topP,
|
|
14056
|
+
topK: event.topK,
|
|
14057
|
+
presencePenalty: event.presencePenalty,
|
|
14058
|
+
frequencyPenalty: event.frequencyPenalty,
|
|
14059
|
+
seed: event.seed,
|
|
14060
|
+
maxRetries: event.maxRetries,
|
|
14061
|
+
headers: event.headers,
|
|
14062
|
+
providerOptions: event.providerOptions
|
|
14063
|
+
};
|
|
14064
|
+
}
|
|
14065
|
+
function shiftModelSpan(modelSpans, callId) {
|
|
14066
|
+
const spans = modelSpans.get(callId);
|
|
14067
|
+
const span = spans?.shift();
|
|
14068
|
+
if (spans && spans.length === 0) {
|
|
14069
|
+
modelSpans.delete(callId);
|
|
14070
|
+
}
|
|
14071
|
+
return span;
|
|
14072
|
+
}
|
|
14073
|
+
function finishResult(event, operationName) {
|
|
14074
|
+
if (operationName === "embed") {
|
|
14075
|
+
return {
|
|
14076
|
+
...event,
|
|
14077
|
+
embedding: event.embedding
|
|
14078
|
+
};
|
|
14079
|
+
}
|
|
14080
|
+
if (operationName === "embedMany") {
|
|
14081
|
+
return {
|
|
14082
|
+
...event,
|
|
14083
|
+
embeddings: event.embedding
|
|
14084
|
+
};
|
|
14085
|
+
}
|
|
14086
|
+
if (operationName === "rerank") {
|
|
14087
|
+
return event;
|
|
14088
|
+
}
|
|
14089
|
+
return event;
|
|
14090
|
+
}
|
|
14091
|
+
function finishOutput(result, operationName) {
|
|
14092
|
+
if (operationName === "embed" || operationName === "embedMany") {
|
|
14093
|
+
return processAISDKEmbeddingOutput(
|
|
14094
|
+
result,
|
|
14095
|
+
DEFAULT_DENY_OUTPUT_PATHS
|
|
14096
|
+
);
|
|
14097
|
+
}
|
|
14098
|
+
if (operationName === "rerank") {
|
|
14099
|
+
return processAISDKRerankOutput(
|
|
14100
|
+
result,
|
|
14101
|
+
DEFAULT_DENY_OUTPUT_PATHS
|
|
14102
|
+
);
|
|
14103
|
+
}
|
|
14104
|
+
return processAISDKOutput(result, DEFAULT_DENY_OUTPUT_PATHS);
|
|
14105
|
+
}
|
|
14106
|
+
|
|
13479
14107
|
// src/instrumentation/plugins/ai-sdk-channels.ts
|
|
13480
14108
|
var aiSDKChannels = defineChannels("ai", {
|
|
13481
14109
|
generateText: channel({
|
|
@@ -13535,6 +14163,10 @@ var aiSDKChannels = defineChannels("ai", {
|
|
|
13535
14163
|
toolLoopAgentStream: channel({
|
|
13536
14164
|
channelName: "ToolLoopAgent.stream",
|
|
13537
14165
|
kind: "async"
|
|
14166
|
+
}),
|
|
14167
|
+
v7CreateTelemetryDispatcher: channel({
|
|
14168
|
+
channelName: "createTelemetryDispatcher",
|
|
14169
|
+
kind: "sync-stream"
|
|
13538
14170
|
})
|
|
13539
14171
|
});
|
|
13540
14172
|
|
|
@@ -13555,9 +14187,30 @@ var DEFAULT_DENY_OUTPUT_PATHS = [
|
|
|
13555
14187
|
];
|
|
13556
14188
|
var AUTO_PATCHED_MODEL = /* @__PURE__ */ Symbol.for("braintrust.ai-sdk.auto-patched-model");
|
|
13557
14189
|
var AUTO_PATCHED_TOOL = /* @__PURE__ */ Symbol.for("braintrust.ai-sdk.auto-patched-tool");
|
|
14190
|
+
var AUTO_PATCHED_V7_TELEMETRY_DISPATCHER = /* @__PURE__ */ Symbol.for(
|
|
14191
|
+
"braintrust.ai-sdk.v7.auto-patched-telemetry-dispatcher"
|
|
14192
|
+
);
|
|
13558
14193
|
var RUNTIME_DENY_OUTPUT_PATHS = /* @__PURE__ */ Symbol.for(
|
|
13559
14194
|
"braintrust.ai-sdk.deny-output-paths"
|
|
13560
14195
|
);
|
|
14196
|
+
var AI_SDK_V7_TELEMETRY_CALLBACKS = [
|
|
14197
|
+
"onStart",
|
|
14198
|
+
"onStepStart",
|
|
14199
|
+
"onLanguageModelCallStart",
|
|
14200
|
+
"onLanguageModelCallEnd",
|
|
14201
|
+
"onToolExecutionStart",
|
|
14202
|
+
"onToolExecutionEnd",
|
|
14203
|
+
"onChunk",
|
|
14204
|
+
"onStepFinish",
|
|
14205
|
+
"onObjectStepStart",
|
|
14206
|
+
"onObjectStepFinish",
|
|
14207
|
+
"onEmbedStart",
|
|
14208
|
+
"onEmbedFinish",
|
|
14209
|
+
"onRerankStart",
|
|
14210
|
+
"onRerankFinish",
|
|
14211
|
+
"onFinish",
|
|
14212
|
+
"onError"
|
|
14213
|
+
];
|
|
13561
14214
|
var AISDKPlugin = class extends BasePlugin {
|
|
13562
14215
|
config;
|
|
13563
14216
|
constructor(config = {}) {
|
|
@@ -13572,6 +14225,7 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
13572
14225
|
}
|
|
13573
14226
|
subscribeToAISDK() {
|
|
13574
14227
|
const denyOutputPaths = this.config.denyOutputPaths || DEFAULT_DENY_OUTPUT_PATHS;
|
|
14228
|
+
this.unsubscribers.push(subscribeToAISDKV7TelemetryDispatcher());
|
|
13575
14229
|
this.unsubscribers.push(
|
|
13576
14230
|
traceStreamingChannel(aiSDKChannels.generateText, {
|
|
13577
14231
|
name: "generateText",
|
|
@@ -13796,6 +14450,57 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
13796
14450
|
);
|
|
13797
14451
|
}
|
|
13798
14452
|
};
|
|
14453
|
+
function subscribeToAISDKV7TelemetryDispatcher() {
|
|
14454
|
+
const channel2 = aiSDKChannels.v7CreateTelemetryDispatcher.tracingChannel();
|
|
14455
|
+
const telemetry = braintrustAISDKTelemetry();
|
|
14456
|
+
const handlers = {
|
|
14457
|
+
end: (event) => {
|
|
14458
|
+
const telemetryOptions = event.arguments?.[0]?.telemetry;
|
|
14459
|
+
if (telemetryOptions?.isEnabled === false) {
|
|
14460
|
+
return;
|
|
14461
|
+
}
|
|
14462
|
+
patchAISDKV7TelemetryDispatcher(event.result, telemetry);
|
|
14463
|
+
}
|
|
14464
|
+
};
|
|
14465
|
+
channel2.subscribe(handlers);
|
|
14466
|
+
return () => {
|
|
14467
|
+
channel2.unsubscribe(handlers);
|
|
14468
|
+
};
|
|
14469
|
+
}
|
|
14470
|
+
function patchAISDKV7TelemetryDispatcher(dispatcher, telemetry) {
|
|
14471
|
+
if (!isObject(dispatcher)) {
|
|
14472
|
+
return;
|
|
14473
|
+
}
|
|
14474
|
+
const dispatcherRecord = dispatcher;
|
|
14475
|
+
if (dispatcherRecord[AUTO_PATCHED_V7_TELEMETRY_DISPATCHER]) {
|
|
14476
|
+
return;
|
|
14477
|
+
}
|
|
14478
|
+
dispatcherRecord[AUTO_PATCHED_V7_TELEMETRY_DISPATCHER] = true;
|
|
14479
|
+
for (const key of AI_SDK_V7_TELEMETRY_CALLBACKS) {
|
|
14480
|
+
const braintrustCallback = telemetry[key];
|
|
14481
|
+
if (typeof braintrustCallback !== "function") {
|
|
14482
|
+
continue;
|
|
14483
|
+
}
|
|
14484
|
+
const existingCallback = dispatcherRecord[key];
|
|
14485
|
+
dispatcherRecord[key] = (event) => {
|
|
14486
|
+
const existingResult = typeof existingCallback === "function" ? existingCallback.call(dispatcher, event) : void 0;
|
|
14487
|
+
const braintrustResult = braintrustCallback.call(telemetry, event);
|
|
14488
|
+
const pending = [existingResult, braintrustResult].filter(isPromiseLike);
|
|
14489
|
+
if (pending.length > 0) {
|
|
14490
|
+
return Promise.allSettled(pending).then(() => void 0);
|
|
14491
|
+
}
|
|
14492
|
+
};
|
|
14493
|
+
}
|
|
14494
|
+
const braintrustExecuteTool = telemetry.executeTool;
|
|
14495
|
+
if (typeof braintrustExecuteTool !== "function") {
|
|
14496
|
+
return;
|
|
14497
|
+
}
|
|
14498
|
+
const existingExecuteTool = dispatcherRecord.executeTool;
|
|
14499
|
+
dispatcherRecord.executeTool = (args) => braintrustExecuteTool.call(telemetry, {
|
|
14500
|
+
...args,
|
|
14501
|
+
execute: () => typeof existingExecuteTool === "function" ? existingExecuteTool.call(dispatcher, args) : args.execute()
|
|
14502
|
+
});
|
|
14503
|
+
}
|
|
13799
14504
|
function resolveDenyOutputPaths(event, defaultDenyOutputPaths) {
|
|
13800
14505
|
if (Array.isArray(event?.denyOutputPaths)) {
|
|
13801
14506
|
return event.denyOutputPaths;
|
|
@@ -14247,11 +14952,11 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
|
|
|
14247
14952
|
metadata: baseMetadata
|
|
14248
14953
|
}
|
|
14249
14954
|
});
|
|
14955
|
+
const streamStartTime = getCurrentUnixTimestamp();
|
|
14250
14956
|
const result = await withCurrent(
|
|
14251
14957
|
span,
|
|
14252
14958
|
() => Reflect.apply(originalDoStream, resolvedModel, [options])
|
|
14253
14959
|
);
|
|
14254
|
-
const streamStartTime = getCurrentUnixTimestamp();
|
|
14255
14960
|
let firstChunkTime;
|
|
14256
14961
|
const output = {};
|
|
14257
14962
|
let text = "";
|
|
@@ -14260,7 +14965,7 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
|
|
|
14260
14965
|
let object = void 0;
|
|
14261
14966
|
const transformStream = new TransformStream({
|
|
14262
14967
|
transform(chunk, controller) {
|
|
14263
|
-
if (firstChunkTime === void 0) {
|
|
14968
|
+
if (firstChunkTime === void 0 && isAISDKContentStreamChunk(chunk)) {
|
|
14264
14969
|
firstChunkTime = getCurrentUnixTimestamp();
|
|
14265
14970
|
}
|
|
14266
14971
|
switch (chunk.type) {
|
|
@@ -14452,6 +15157,78 @@ function finalizeAISDKChildTracing(event) {
|
|
|
14452
15157
|
delete event.__braintrust_ai_sdk_cleanup;
|
|
14453
15158
|
}
|
|
14454
15159
|
}
|
|
15160
|
+
function extractAISDKStreamPart(chunk) {
|
|
15161
|
+
if (!isObject(chunk) || !isObject(chunk.part)) {
|
|
15162
|
+
return chunk;
|
|
15163
|
+
}
|
|
15164
|
+
return chunk.part;
|
|
15165
|
+
}
|
|
15166
|
+
function stringContent(value) {
|
|
15167
|
+
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
15168
|
+
}
|
|
15169
|
+
function rawValueHasAISDKContent(value) {
|
|
15170
|
+
if (value === void 0 || value === null) {
|
|
15171
|
+
return false;
|
|
15172
|
+
}
|
|
15173
|
+
if (typeof value === "string") {
|
|
15174
|
+
return value.length > 0;
|
|
15175
|
+
}
|
|
15176
|
+
if (!isObject(value)) {
|
|
15177
|
+
return true;
|
|
15178
|
+
}
|
|
15179
|
+
const delta = value.delta;
|
|
15180
|
+
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) => {
|
|
15181
|
+
if (!isObject(choice) || !isObject(choice.delta)) {
|
|
15182
|
+
return false;
|
|
15183
|
+
}
|
|
15184
|
+
const choiceDelta = choice.delta;
|
|
15185
|
+
if (stringContent(choiceDelta.content) || stringContent(choiceDelta.text)) {
|
|
15186
|
+
return true;
|
|
15187
|
+
}
|
|
15188
|
+
if (isObject(choiceDelta.function_call) && stringContent(choiceDelta.function_call.arguments)) {
|
|
15189
|
+
return true;
|
|
15190
|
+
}
|
|
15191
|
+
return Array.isArray(choiceDelta.tool_calls) && choiceDelta.tool_calls.some(
|
|
15192
|
+
(toolCall) => isObject(toolCall) && isObject(toolCall.function) && stringContent(toolCall.function.arguments)
|
|
15193
|
+
);
|
|
15194
|
+
})) {
|
|
15195
|
+
return true;
|
|
15196
|
+
}
|
|
15197
|
+
return false;
|
|
15198
|
+
}
|
|
15199
|
+
function isAISDKContentStreamChunk(chunk) {
|
|
15200
|
+
const part = extractAISDKStreamPart(chunk);
|
|
15201
|
+
if (typeof part === "string") {
|
|
15202
|
+
return part.length > 0;
|
|
15203
|
+
}
|
|
15204
|
+
if (!isObject(part) || typeof part.type !== "string") {
|
|
15205
|
+
return false;
|
|
15206
|
+
}
|
|
15207
|
+
switch (part.type) {
|
|
15208
|
+
case "text-delta":
|
|
15209
|
+
return stringContent(part.textDelta) !== void 0 || stringContent(part.delta) !== void 0 || stringContent(part.text) !== void 0 || stringContent(part.content) !== void 0;
|
|
15210
|
+
case "reasoning-delta":
|
|
15211
|
+
return stringContent(part.delta) !== void 0 || stringContent(part.text) !== void 0 || stringContent(part.content) !== void 0;
|
|
15212
|
+
case "tool-call":
|
|
15213
|
+
case "object":
|
|
15214
|
+
case "file":
|
|
15215
|
+
return true;
|
|
15216
|
+
case "tool-input-delta":
|
|
15217
|
+
case "tool-call-delta":
|
|
15218
|
+
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;
|
|
15219
|
+
case "raw":
|
|
15220
|
+
return rawValueHasAISDKContent(part.rawValue);
|
|
15221
|
+
default:
|
|
15222
|
+
return false;
|
|
15223
|
+
}
|
|
15224
|
+
}
|
|
15225
|
+
function isAISDKContentAsyncIterableChunk(chunk) {
|
|
15226
|
+
if (isAISDKContentStreamChunk(chunk)) {
|
|
15227
|
+
return true;
|
|
15228
|
+
}
|
|
15229
|
+
const part = extractAISDKStreamPart(chunk);
|
|
15230
|
+
return isObject(part) && typeof part.type !== "string";
|
|
15231
|
+
}
|
|
14455
15232
|
function patchAISDKStreamingResult(args) {
|
|
14456
15233
|
const { defaultDenyOutputPaths, endEvent, result, span, startTime } = args;
|
|
14457
15234
|
if (!result || typeof result !== "object") {
|
|
@@ -14464,7 +15241,7 @@ function patchAISDKStreamingResult(args) {
|
|
|
14464
15241
|
const wrappedBaseStream = resultRecord.baseStream.pipeThrough(
|
|
14465
15242
|
new TransformStream({
|
|
14466
15243
|
transform(chunk, controller) {
|
|
14467
|
-
if (firstChunkTime2 === void 0) {
|
|
15244
|
+
if (firstChunkTime2 === void 0 && isAISDKContentStreamChunk(chunk)) {
|
|
14468
15245
|
firstChunkTime2 = getCurrentUnixTimestamp();
|
|
14469
15246
|
}
|
|
14470
15247
|
controller.enqueue(chunk);
|
|
@@ -14508,8 +15285,8 @@ function patchAISDKStreamingResult(args) {
|
|
|
14508
15285
|
}
|
|
14509
15286
|
let firstChunkTime;
|
|
14510
15287
|
const wrappedStream = createPatchedAsyncIterable(streamField.stream, {
|
|
14511
|
-
onChunk: () => {
|
|
14512
|
-
if (firstChunkTime === void 0) {
|
|
15288
|
+
onChunk: (chunk) => {
|
|
15289
|
+
if (firstChunkTime === void 0 && isAISDKContentAsyncIterableChunk(chunk)) {
|
|
14513
15290
|
firstChunkTime = getCurrentUnixTimestamp();
|
|
14514
15291
|
}
|
|
14515
15292
|
},
|
|
@@ -15481,15 +16258,17 @@ function collectLocalMcpServerToolHookNames(serverName, serverConfig) {
|
|
|
15481
16258
|
|
|
15482
16259
|
// src/instrumentation/plugins/claude-agent-sdk-plugin.ts
|
|
15483
16260
|
var ROOT_LLM_PARENT_KEY = "__root__";
|
|
16261
|
+
var SUB_AGENT_PROMPT_SOURCE_PRIORITY = {
|
|
16262
|
+
delegation: 0,
|
|
16263
|
+
lifecycle: 1,
|
|
16264
|
+
sidechain: 2
|
|
16265
|
+
};
|
|
15484
16266
|
function llmParentKey(parentToolUseId) {
|
|
15485
16267
|
return parentToolUseId ?? ROOT_LLM_PARENT_KEY;
|
|
15486
16268
|
}
|
|
15487
16269
|
function isSubAgentDelegationToolName(toolName) {
|
|
15488
16270
|
return toolName === "Agent" || toolName === "Task";
|
|
15489
16271
|
}
|
|
15490
|
-
function shouldParentToolAsTaskSibling(toolName) {
|
|
15491
|
-
return toolName === "Agent" || toolName === "Task" || toolName === "Bash";
|
|
15492
|
-
}
|
|
15493
16272
|
function filterSerializableOptions(options) {
|
|
15494
16273
|
const allowedKeys = [
|
|
15495
16274
|
"model",
|
|
@@ -15626,26 +16405,39 @@ function extractUsageFromMessage(message) {
|
|
|
15626
16405
|
}
|
|
15627
16406
|
return metrics;
|
|
15628
16407
|
}
|
|
15629
|
-
function buildLLMInput(
|
|
15630
|
-
const promptMessages = [];
|
|
15631
|
-
if (typeof prompt === "string") {
|
|
15632
|
-
promptMessages.push({ content: prompt, role: "user" });
|
|
15633
|
-
} else if (capturedPromptMessages && capturedPromptMessages.length > 0) {
|
|
15634
|
-
for (const msg of capturedPromptMessages) {
|
|
15635
|
-
const role = msg.message?.role;
|
|
15636
|
-
const content = msg.message?.content;
|
|
15637
|
-
if (role && content !== void 0) {
|
|
15638
|
-
promptMessages.push({ content, role });
|
|
15639
|
-
}
|
|
15640
|
-
}
|
|
15641
|
-
}
|
|
16408
|
+
function buildLLMInput(promptMessages, conversationHistory) {
|
|
15642
16409
|
const inputParts = [...promptMessages, ...conversationHistory];
|
|
15643
16410
|
return inputParts.length > 0 ? inputParts : void 0;
|
|
15644
16411
|
}
|
|
16412
|
+
function conversationMessageFromSDKMessage(message) {
|
|
16413
|
+
const role = message.message?.role;
|
|
16414
|
+
const content = message.message?.content;
|
|
16415
|
+
if (role && content !== void 0) {
|
|
16416
|
+
return { content, role };
|
|
16417
|
+
}
|
|
16418
|
+
return void 0;
|
|
16419
|
+
}
|
|
16420
|
+
function messageContentHasBlockType(message, blockType) {
|
|
16421
|
+
const content = message.message?.content;
|
|
16422
|
+
return Array.isArray(content) && content.some(
|
|
16423
|
+
(block) => typeof block === "object" && block !== null && "type" in block && block.type === blockType
|
|
16424
|
+
);
|
|
16425
|
+
}
|
|
16426
|
+
function buildRootPromptMessages(prompt, capturedPromptMessages) {
|
|
16427
|
+
if (typeof prompt === "string") {
|
|
16428
|
+
return [{ content: prompt, role: "user" }];
|
|
16429
|
+
}
|
|
16430
|
+
if (!capturedPromptMessages || capturedPromptMessages.length === 0) {
|
|
16431
|
+
return [];
|
|
16432
|
+
}
|
|
16433
|
+
return capturedPromptMessages.map(conversationMessageFromSDKMessage).filter(
|
|
16434
|
+
(message) => message !== void 0
|
|
16435
|
+
);
|
|
16436
|
+
}
|
|
15645
16437
|
function formatCapturedMessages(messages) {
|
|
15646
16438
|
return messages.length > 0 ? messages : [];
|
|
15647
16439
|
}
|
|
15648
|
-
async function createLLMSpanForMessages(messages,
|
|
16440
|
+
async function createLLMSpanForMessages(messages, promptMessages, conversationHistory, options, startTime, parentSpan, existingSpan) {
|
|
15649
16441
|
if (messages.length === 0) {
|
|
15650
16442
|
return void 0;
|
|
15651
16443
|
}
|
|
@@ -15655,11 +16447,7 @@ async function createLLMSpanForMessages(messages, prompt, conversationHistory, o
|
|
|
15655
16447
|
}
|
|
15656
16448
|
const model = lastMessage.message.model || options.model;
|
|
15657
16449
|
const usage = extractUsageFromMessage(lastMessage);
|
|
15658
|
-
const input = buildLLMInput(
|
|
15659
|
-
prompt,
|
|
15660
|
-
conversationHistory,
|
|
15661
|
-
capturedPromptMessages
|
|
15662
|
-
);
|
|
16450
|
+
const input = buildLLMInput(promptMessages, conversationHistory);
|
|
15663
16451
|
const outputs = messages.map(
|
|
15664
16452
|
(m) => m.message?.content && m.message?.role ? { content: m.message.content, role: m.message.role } : void 0
|
|
15665
16453
|
).filter(
|
|
@@ -15790,8 +16578,7 @@ function createToolTracingHooks(resolveParentSpan, activeToolSpans, mcpServers,
|
|
|
15790
16578
|
},
|
|
15791
16579
|
name: parsed.displayName,
|
|
15792
16580
|
parent: await resolveParentSpan(toolUseID, {
|
|
15793
|
-
agentId: input.agent_id
|
|
15794
|
-
preferTaskSiblingParent: shouldParentToolAsTaskSibling(parsed.toolName)
|
|
16581
|
+
agentId: input.agent_id
|
|
15795
16582
|
}),
|
|
15796
16583
|
spanAttributes: { type: "tool" /* TOOL */ }
|
|
15797
16584
|
});
|
|
@@ -16037,12 +16824,37 @@ function injectTracingHooks(options, resolveParentSpan, activeToolSpans, localTo
|
|
|
16037
16824
|
}
|
|
16038
16825
|
};
|
|
16039
16826
|
}
|
|
16827
|
+
function setSubAgentPromptMessages(state, parentToolUseId, promptMessages, source) {
|
|
16828
|
+
if (promptMessages.length === 0) {
|
|
16829
|
+
return;
|
|
16830
|
+
}
|
|
16831
|
+
const parentKey = llmParentKey(parentToolUseId);
|
|
16832
|
+
const sourcePriority = SUB_AGENT_PROMPT_SOURCE_PRIORITY[source];
|
|
16833
|
+
const currentPriority = state.promptSourcePriorityByParentKey.get(parentKey) ?? -1;
|
|
16834
|
+
if (sourcePriority > currentPriority) {
|
|
16835
|
+
state.promptMessagesByParentKey.set(parentKey, promptMessages);
|
|
16836
|
+
state.promptSourcePriorityByParentKey.set(parentKey, sourcePriority);
|
|
16837
|
+
}
|
|
16838
|
+
}
|
|
16839
|
+
function getConversationHistory(state, parentKey) {
|
|
16840
|
+
let conversationHistory = state.conversationHistoryByParentKey.get(parentKey);
|
|
16841
|
+
if (!conversationHistory) {
|
|
16842
|
+
conversationHistory = [];
|
|
16843
|
+
state.conversationHistoryByParentKey.set(parentKey, conversationHistory);
|
|
16844
|
+
}
|
|
16845
|
+
return conversationHistory;
|
|
16846
|
+
}
|
|
16040
16847
|
async function finalizeCurrentMessageGroup(state) {
|
|
16041
16848
|
if (state.currentMessages.length === 0) {
|
|
16042
16849
|
return;
|
|
16043
16850
|
}
|
|
16044
16851
|
const parentToolUseId = state.currentMessages[0]?.parent_tool_use_id ?? null;
|
|
16045
16852
|
const parentKey = llmParentKey(parentToolUseId);
|
|
16853
|
+
const conversationHistory = getConversationHistory(state, parentKey);
|
|
16854
|
+
const promptMessages = parentToolUseId ? state.promptMessagesByParentKey.get(parentKey) ?? [] : buildRootPromptMessages(
|
|
16855
|
+
state.originalPrompt,
|
|
16856
|
+
state.capturedPromptMessages
|
|
16857
|
+
);
|
|
16046
16858
|
let parentSpan = await state.span.export();
|
|
16047
16859
|
if (parentToolUseId) {
|
|
16048
16860
|
const subAgentSpan = state.subAgentSpans.get(parentToolUseId);
|
|
@@ -16053,11 +16865,10 @@ async function finalizeCurrentMessageGroup(state) {
|
|
|
16053
16865
|
const existingLlmSpan = state.activeLlmSpansByParentToolUse.get(parentKey);
|
|
16054
16866
|
const llmSpanResult = await createLLMSpanForMessages(
|
|
16055
16867
|
state.currentMessages,
|
|
16056
|
-
|
|
16057
|
-
|
|
16868
|
+
promptMessages,
|
|
16869
|
+
conversationHistory,
|
|
16058
16870
|
state.options,
|
|
16059
16871
|
state.currentMessageStartTime,
|
|
16060
|
-
state.capturedPromptMessages,
|
|
16061
16872
|
parentSpan,
|
|
16062
16873
|
existingLlmSpan
|
|
16063
16874
|
);
|
|
@@ -16071,6 +16882,7 @@ async function finalizeCurrentMessageGroup(state) {
|
|
|
16071
16882
|
state.latestRootLlmParentRef.value = llmSpanResult.spanExport;
|
|
16072
16883
|
}
|
|
16073
16884
|
if (llmSpanResult.finalMessage) {
|
|
16885
|
+
conversationHistory.push(llmSpanResult.finalMessage);
|
|
16074
16886
|
state.finalResults.push(llmSpanResult.finalMessage);
|
|
16075
16887
|
}
|
|
16076
16888
|
}
|
|
@@ -16098,6 +16910,15 @@ function maybeTrackToolUseContext(state, message) {
|
|
|
16098
16910
|
description: getStringProperty(block.input, "description"),
|
|
16099
16911
|
toolUseId: block.id
|
|
16100
16912
|
});
|
|
16913
|
+
const prompt = getStringProperty(block.input, "prompt");
|
|
16914
|
+
if (prompt) {
|
|
16915
|
+
setSubAgentPromptMessages(
|
|
16916
|
+
state,
|
|
16917
|
+
block.id,
|
|
16918
|
+
[{ content: prompt, role: "user" }],
|
|
16919
|
+
"delegation"
|
|
16920
|
+
);
|
|
16921
|
+
}
|
|
16101
16922
|
}
|
|
16102
16923
|
}
|
|
16103
16924
|
}
|
|
@@ -16216,6 +17037,14 @@ async function maybeHandleTaskLifecycleMessage(state, message) {
|
|
|
16216
17037
|
};
|
|
16217
17038
|
if (message.subtype === "task_started") {
|
|
16218
17039
|
const prompt = getStringProperty(message, "prompt");
|
|
17040
|
+
if (prompt) {
|
|
17041
|
+
setSubAgentPromptMessages(
|
|
17042
|
+
state,
|
|
17043
|
+
toolUseId,
|
|
17044
|
+
[{ content: prompt, role: "user" }],
|
|
17045
|
+
"lifecycle"
|
|
17046
|
+
);
|
|
17047
|
+
}
|
|
16219
17048
|
subAgentSpan.log({
|
|
16220
17049
|
input: prompt,
|
|
16221
17050
|
metadata
|
|
@@ -16266,6 +17095,28 @@ async function handleStreamMessage(state, message) {
|
|
|
16266
17095
|
return;
|
|
16267
17096
|
}
|
|
16268
17097
|
await maybeStartSubAgentSpan(state, message);
|
|
17098
|
+
const messageParentToolUseId = message.parent_tool_use_id;
|
|
17099
|
+
if (messageParentToolUseId && message.type === "user") {
|
|
17100
|
+
const conversationMessage = conversationMessageFromSDKMessage(message);
|
|
17101
|
+
if (conversationMessage?.role === "user") {
|
|
17102
|
+
await finalizeCurrentMessageGroup(state);
|
|
17103
|
+
const parentKey = llmParentKey(messageParentToolUseId);
|
|
17104
|
+
const conversationHistory = getConversationHistory(state, parentKey);
|
|
17105
|
+
const currentPromptSourcePriority = state.promptSourcePriorityByParentKey.get(parentKey) ?? -1;
|
|
17106
|
+
const canUseAsInitialSidechainPrompt = conversationHistory.length === 0 && currentPromptSourcePriority < SUB_AGENT_PROMPT_SOURCE_PRIORITY.sidechain && !messageContentHasBlockType(message, "tool_result");
|
|
17107
|
+
if (!canUseAsInitialSidechainPrompt) {
|
|
17108
|
+
conversationHistory.push(conversationMessage);
|
|
17109
|
+
return;
|
|
17110
|
+
}
|
|
17111
|
+
setSubAgentPromptMessages(
|
|
17112
|
+
state,
|
|
17113
|
+
messageParentToolUseId,
|
|
17114
|
+
[conversationMessage],
|
|
17115
|
+
"sidechain"
|
|
17116
|
+
);
|
|
17117
|
+
return;
|
|
17118
|
+
}
|
|
17119
|
+
}
|
|
16269
17120
|
const messageId = message.message?.id;
|
|
16270
17121
|
if (messageId && messageId !== state.currentMessageId) {
|
|
16271
17122
|
await finalizeCurrentMessageGroup(state);
|
|
@@ -16417,6 +17268,7 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
16417
17268
|
}
|
|
16418
17269
|
const activeToolSpans = /* @__PURE__ */ new Map();
|
|
16419
17270
|
const activeLlmSpansByParentToolUse = /* @__PURE__ */ new Map();
|
|
17271
|
+
const conversationHistoryByParentKey = /* @__PURE__ */ new Map();
|
|
16420
17272
|
const subAgentSpans = /* @__PURE__ */ new Map();
|
|
16421
17273
|
const endedSubAgentSpans = /* @__PURE__ */ new Set();
|
|
16422
17274
|
const toolUseToParent = /* @__PURE__ */ new Map();
|
|
@@ -16426,6 +17278,8 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
16426
17278
|
};
|
|
16427
17279
|
const subAgentDetailsByToolUseId = /* @__PURE__ */ new Map();
|
|
16428
17280
|
const taskIdToToolUseId = /* @__PURE__ */ new Map();
|
|
17281
|
+
const promptMessagesByParentKey = /* @__PURE__ */ new Map();
|
|
17282
|
+
const promptSourcePriorityByParentKey = /* @__PURE__ */ new Map();
|
|
16429
17283
|
const localToolContext = createClaudeLocalToolContext();
|
|
16430
17284
|
const { hasLocalToolHandlers, localToolHookNames } = prepareLocalToolHandlersInMcpServers(options.mcpServers);
|
|
16431
17285
|
const skipLocalToolHooks = options[CLAUDE_AGENT_SDK_SKIP_LOCAL_TOOL_HOOKS_OPTION] === true || hasLocalToolHandlers;
|
|
@@ -16434,38 +17288,19 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
16434
17288
|
const parentToolUseId = trackedParentToolUseId ?? (context?.agentId ? taskIdToToolUseId.get(context.agentId) ?? null : null);
|
|
16435
17289
|
const parentKey = llmParentKey(parentToolUseId);
|
|
16436
17290
|
const activeLlmSpan = activeLlmSpansByParentToolUse.get(parentKey);
|
|
16437
|
-
|
|
16438
|
-
|
|
16439
|
-
|
|
16440
|
-
|
|
16441
|
-
|
|
16442
|
-
|
|
16443
|
-
|
|
16444
|
-
|
|
16445
|
-
|
|
16446
|
-
|
|
16447
|
-
|
|
16448
|
-
}
|
|
16449
|
-
if (parentToolUseId) {
|
|
16450
|
-
const subAgentSpan = await ensureSubAgentSpan(
|
|
16451
|
-
subAgentDetailsByToolUseId,
|
|
16452
|
-
span,
|
|
16453
|
-
activeToolSpans,
|
|
16454
|
-
subAgentSpans,
|
|
16455
|
-
parentToolUseId
|
|
16456
|
-
);
|
|
16457
|
-
return subAgentSpan.export();
|
|
16458
|
-
}
|
|
16459
|
-
return span.export();
|
|
16460
|
-
}
|
|
16461
|
-
if (activeLlmSpan) {
|
|
16462
|
-
return activeLlmSpan.export();
|
|
17291
|
+
const latestLlmParent = parentToolUseId ? latestLlmParentBySubAgentToolUse.get(parentToolUseId) : latestRootLlmParentRef.value;
|
|
17292
|
+
if (!activeLlmSpan && !latestLlmParent) {
|
|
17293
|
+
await ensureActiveLlmSpanForParentToolUse(
|
|
17294
|
+
span,
|
|
17295
|
+
activeLlmSpansByParentToolUse,
|
|
17296
|
+
subAgentDetailsByToolUseId,
|
|
17297
|
+
activeToolSpans,
|
|
17298
|
+
subAgentSpans,
|
|
17299
|
+
parentToolUseId,
|
|
17300
|
+
getCurrentUnixTimestamp()
|
|
17301
|
+
);
|
|
16463
17302
|
}
|
|
16464
17303
|
if (parentToolUseId) {
|
|
16465
|
-
const parentLlm = latestLlmParentBySubAgentToolUse.get(parentToolUseId);
|
|
16466
|
-
if (parentLlm) {
|
|
16467
|
-
return parentLlm;
|
|
16468
|
-
}
|
|
16469
17304
|
const subAgentSpan = await ensureSubAgentSpan(
|
|
16470
17305
|
subAgentDetailsByToolUseId,
|
|
16471
17306
|
span,
|
|
@@ -16475,9 +17310,6 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
16475
17310
|
);
|
|
16476
17311
|
return subAgentSpan.export();
|
|
16477
17312
|
}
|
|
16478
|
-
if (latestRootLlmParentRef.value) {
|
|
16479
|
-
return latestRootLlmParentRef.value;
|
|
16480
|
-
}
|
|
16481
17313
|
return span.export();
|
|
16482
17314
|
};
|
|
16483
17315
|
localToolContext.resolveLocalToolParent = resolveToolUseParentSpan;
|
|
@@ -16498,6 +17330,7 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
16498
17330
|
accumulatedOutputTokens: 0,
|
|
16499
17331
|
activeLlmSpansByParentToolUse,
|
|
16500
17332
|
activeToolSpans,
|
|
17333
|
+
conversationHistoryByParentKey,
|
|
16501
17334
|
capturedPromptMessages,
|
|
16502
17335
|
currentMessageId: void 0,
|
|
16503
17336
|
currentMessageStartTime: startTime,
|
|
@@ -16508,7 +17341,9 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
16508
17341
|
originalPrompt,
|
|
16509
17342
|
processing: Promise.resolve(),
|
|
16510
17343
|
promptDone,
|
|
17344
|
+
promptMessagesByParentKey,
|
|
16511
17345
|
promptStarted: () => promptStarted,
|
|
17346
|
+
promptSourcePriorityByParentKey,
|
|
16512
17347
|
span,
|
|
16513
17348
|
subAgentDetailsByToolUseId,
|
|
16514
17349
|
subAgentSpans,
|
|
@@ -17937,6 +18772,10 @@ var googleGenAIChannels = defineChannels("@google/genai", {
|
|
|
17937
18772
|
embedContent: channel({
|
|
17938
18773
|
channelName: "models.embedContent",
|
|
17939
18774
|
kind: "async"
|
|
18775
|
+
}),
|
|
18776
|
+
interactionsCreate: channel({
|
|
18777
|
+
channelName: "interactions.create",
|
|
18778
|
+
kind: "async"
|
|
17940
18779
|
})
|
|
17941
18780
|
});
|
|
17942
18781
|
|
|
@@ -17964,6 +18803,7 @@ var GoogleGenAIPlugin = class extends BasePlugin {
|
|
|
17964
18803
|
this.subscribeToGenerateContentChannel();
|
|
17965
18804
|
this.subscribeToGenerateContentStreamChannel();
|
|
17966
18805
|
this.subscribeToEmbedContentChannel();
|
|
18806
|
+
this.subscribeToInteractionsCreateChannel();
|
|
17967
18807
|
}
|
|
17968
18808
|
subscribeToGenerateContentChannel() {
|
|
17969
18809
|
const tracingChannel2 = googleGenAIChannels.generateContent.tracingChannel();
|
|
@@ -18136,7 +18976,30 @@ var GoogleGenAIPlugin = class extends BasePlugin {
|
|
|
18136
18976
|
tracingChannel2.unsubscribe(handlers);
|
|
18137
18977
|
});
|
|
18138
18978
|
}
|
|
18979
|
+
subscribeToInteractionsCreateChannel() {
|
|
18980
|
+
this.unsubscribers.push(
|
|
18981
|
+
traceStreamingChannel(
|
|
18982
|
+
googleGenAIChannels.interactionsCreate,
|
|
18983
|
+
{
|
|
18984
|
+
name: "create_interaction",
|
|
18985
|
+
shouldTrace: ([params]) => !isBackgroundInteractionCreate(params),
|
|
18986
|
+
type: "llm" /* LLM */,
|
|
18987
|
+
extractInput: ([params]) => ({
|
|
18988
|
+
input: serializeInteractionInput(params),
|
|
18989
|
+
metadata: extractInteractionMetadata(params)
|
|
18990
|
+
}),
|
|
18991
|
+
extractOutput: (result) => serializeInteractionValue(result),
|
|
18992
|
+
extractMetadata: (result) => extractInteractionResponseMetadata(result),
|
|
18993
|
+
extractMetrics: (result, startTime) => cleanMetrics3(extractInteractionMetrics(result, startTime)),
|
|
18994
|
+
aggregateChunks: (chunks, _result, _event, startTime) => aggregateInteractionEvents(chunks, startTime)
|
|
18995
|
+
}
|
|
18996
|
+
)
|
|
18997
|
+
);
|
|
18998
|
+
}
|
|
18139
18999
|
};
|
|
19000
|
+
function isBackgroundInteractionCreate(params) {
|
|
19001
|
+
return tryToDict(params)?.background === true;
|
|
19002
|
+
}
|
|
18140
19003
|
function ensureSpanState(states, event, create) {
|
|
18141
19004
|
const existing = states.get(event);
|
|
18142
19005
|
if (existing) {
|
|
@@ -18344,6 +19207,60 @@ function serializeEmbedContentInput(params) {
|
|
|
18344
19207
|
}
|
|
18345
19208
|
return input;
|
|
18346
19209
|
}
|
|
19210
|
+
function serializeInteractionInput(params) {
|
|
19211
|
+
const input = {
|
|
19212
|
+
input: serializeInteractionValue(params.input)
|
|
19213
|
+
};
|
|
19214
|
+
for (const key of [
|
|
19215
|
+
"model",
|
|
19216
|
+
"agent",
|
|
19217
|
+
"agent_config",
|
|
19218
|
+
"api_version",
|
|
19219
|
+
"background",
|
|
19220
|
+
"environment",
|
|
19221
|
+
"generation_config",
|
|
19222
|
+
"previous_interaction_id",
|
|
19223
|
+
"response_format",
|
|
19224
|
+
"response_mime_type",
|
|
19225
|
+
"response_modalities",
|
|
19226
|
+
"service_tier",
|
|
19227
|
+
"store",
|
|
19228
|
+
"stream",
|
|
19229
|
+
"system_instruction",
|
|
19230
|
+
"webhook_config"
|
|
19231
|
+
]) {
|
|
19232
|
+
const value = params[key];
|
|
19233
|
+
if (value !== void 0) {
|
|
19234
|
+
input[key] = serializeInteractionValue(value);
|
|
19235
|
+
}
|
|
19236
|
+
}
|
|
19237
|
+
return input;
|
|
19238
|
+
}
|
|
19239
|
+
function extractInteractionMetadata(params) {
|
|
19240
|
+
const metadata = {};
|
|
19241
|
+
for (const key of [
|
|
19242
|
+
"model",
|
|
19243
|
+
"agent",
|
|
19244
|
+
"agent_config",
|
|
19245
|
+
"generation_config",
|
|
19246
|
+
"system_instruction",
|
|
19247
|
+
"response_format",
|
|
19248
|
+
"response_mime_type",
|
|
19249
|
+
"response_modalities",
|
|
19250
|
+
"service_tier"
|
|
19251
|
+
]) {
|
|
19252
|
+
const value = params[key];
|
|
19253
|
+
if (value !== void 0) {
|
|
19254
|
+
metadata[key] = serializeInteractionValue(value);
|
|
19255
|
+
}
|
|
19256
|
+
}
|
|
19257
|
+
if (Array.isArray(params.tools)) {
|
|
19258
|
+
metadata.tools = params.tools.map(
|
|
19259
|
+
(tool) => serializeInteractionValue(tool)
|
|
19260
|
+
);
|
|
19261
|
+
}
|
|
19262
|
+
return metadata;
|
|
19263
|
+
}
|
|
18347
19264
|
function serializeContentCollection(contents) {
|
|
18348
19265
|
if (contents === null || contents === void 0) {
|
|
18349
19266
|
return null;
|
|
@@ -18374,21 +19291,8 @@ function serializePart(part) {
|
|
|
18374
19291
|
}
|
|
18375
19292
|
if (part.inlineData && part.inlineData.data) {
|
|
18376
19293
|
const { data, mimeType } = part.inlineData;
|
|
18377
|
-
|
|
18378
|
-
|
|
18379
|
-
const filename = `file.${extension}`;
|
|
18380
|
-
const buffer = typeof data === "string" ? typeof Buffer !== "undefined" ? Buffer.from(data, "base64") : new Uint8Array(
|
|
18381
|
-
atob(data).split("").map((c) => c.charCodeAt(0))
|
|
18382
|
-
) : typeof Buffer !== "undefined" ? Buffer.from(data) : new Uint8Array(data);
|
|
18383
|
-
const arrayBuffer = buffer instanceof Uint8Array ? buffer.buffer.slice(
|
|
18384
|
-
buffer.byteOffset,
|
|
18385
|
-
buffer.byteOffset + buffer.byteLength
|
|
18386
|
-
) : buffer;
|
|
18387
|
-
const attachment = new Attachment({
|
|
18388
|
-
data: arrayBuffer,
|
|
18389
|
-
filename,
|
|
18390
|
-
contentType: mimeType || "application/octet-stream"
|
|
18391
|
-
});
|
|
19294
|
+
const attachment = createAttachmentFromInlineData(data, mimeType);
|
|
19295
|
+
if (attachment) {
|
|
18392
19296
|
return {
|
|
18393
19297
|
image_url: { url: attachment }
|
|
18394
19298
|
};
|
|
@@ -18396,6 +19300,59 @@ function serializePart(part) {
|
|
|
18396
19300
|
}
|
|
18397
19301
|
return part;
|
|
18398
19302
|
}
|
|
19303
|
+
function serializeInteractionValue(value, seen = /* @__PURE__ */ new WeakSet()) {
|
|
19304
|
+
if (value === null || value === void 0 || typeof value !== "object") {
|
|
19305
|
+
return value;
|
|
19306
|
+
}
|
|
19307
|
+
if (Array.isArray(value)) {
|
|
19308
|
+
return value.map((item) => serializeInteractionValue(item, seen));
|
|
19309
|
+
}
|
|
19310
|
+
const dict = tryToDict(value);
|
|
19311
|
+
if (dict === null || dict === void 0 || typeof dict !== "object") {
|
|
19312
|
+
return dict;
|
|
19313
|
+
}
|
|
19314
|
+
if (Array.isArray(dict)) {
|
|
19315
|
+
return dict.map((item) => serializeInteractionValue(item, seen));
|
|
19316
|
+
}
|
|
19317
|
+
if (seen.has(dict)) {
|
|
19318
|
+
return "[Circular]";
|
|
19319
|
+
}
|
|
19320
|
+
seen.add(dict);
|
|
19321
|
+
try {
|
|
19322
|
+
const serialized = {};
|
|
19323
|
+
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;
|
|
19324
|
+
const attachment = mimeType && "data" in dict && dict.data !== void 0 ? createAttachmentFromInlineData(dict.data, mimeType) : null;
|
|
19325
|
+
for (const [key, entry] of Object.entries(dict)) {
|
|
19326
|
+
if (key === "data" && attachment) {
|
|
19327
|
+
serialized[key] = attachment;
|
|
19328
|
+
} else {
|
|
19329
|
+
serialized[key] = serializeInteractionValue(entry, seen);
|
|
19330
|
+
}
|
|
19331
|
+
}
|
|
19332
|
+
return serialized;
|
|
19333
|
+
} finally {
|
|
19334
|
+
seen.delete(dict);
|
|
19335
|
+
}
|
|
19336
|
+
}
|
|
19337
|
+
function createAttachmentFromInlineData(data, mimeType) {
|
|
19338
|
+
if (!(data instanceof Uint8Array || typeof Buffer !== "undefined" && Buffer.isBuffer(data) || typeof data === "string")) {
|
|
19339
|
+
return null;
|
|
19340
|
+
}
|
|
19341
|
+
const extension = mimeType ? mimeType.split("/")[1] : "bin";
|
|
19342
|
+
const filename = `file.${extension}`;
|
|
19343
|
+
const buffer = typeof data === "string" ? typeof Buffer !== "undefined" ? Buffer.from(data, "base64") : new Uint8Array(
|
|
19344
|
+
atob(data).split("").map((c) => c.charCodeAt(0))
|
|
19345
|
+
) : typeof Buffer !== "undefined" ? Buffer.from(data) : new Uint8Array(data);
|
|
19346
|
+
const arrayBuffer = buffer instanceof Uint8Array ? buffer.buffer.slice(
|
|
19347
|
+
buffer.byteOffset,
|
|
19348
|
+
buffer.byteOffset + buffer.byteLength
|
|
19349
|
+
) : buffer;
|
|
19350
|
+
return new Attachment({
|
|
19351
|
+
data: arrayBuffer,
|
|
19352
|
+
filename,
|
|
19353
|
+
contentType: mimeType || "application/octet-stream"
|
|
19354
|
+
});
|
|
19355
|
+
}
|
|
18399
19356
|
function serializeGenerateContentTools(params) {
|
|
18400
19357
|
const config = params.config ? tryToDict(params.config) : null;
|
|
18401
19358
|
const tools = config?.tools;
|
|
@@ -18480,6 +19437,33 @@ function extractEmbedContentMetrics(response, startTime) {
|
|
|
18480
19437
|
}
|
|
18481
19438
|
return metrics;
|
|
18482
19439
|
}
|
|
19440
|
+
function extractInteractionMetrics(response, startTime) {
|
|
19441
|
+
const metrics = {};
|
|
19442
|
+
if (startTime !== void 0) {
|
|
19443
|
+
const end = getCurrentUnixTimestamp();
|
|
19444
|
+
metrics.start = startTime;
|
|
19445
|
+
metrics.end = end;
|
|
19446
|
+
metrics.duration = end - startTime;
|
|
19447
|
+
}
|
|
19448
|
+
if (response?.usage) {
|
|
19449
|
+
populateInteractionUsageMetrics(metrics, response.usage);
|
|
19450
|
+
}
|
|
19451
|
+
return metrics;
|
|
19452
|
+
}
|
|
19453
|
+
function extractInteractionResponseMetadata(response) {
|
|
19454
|
+
const responseDict = tryToDict(response);
|
|
19455
|
+
if (!responseDict) {
|
|
19456
|
+
return void 0;
|
|
19457
|
+
}
|
|
19458
|
+
const metadata = {};
|
|
19459
|
+
if (typeof responseDict.id === "string") {
|
|
19460
|
+
metadata.interaction_id = responseDict.id;
|
|
19461
|
+
}
|
|
19462
|
+
if (typeof responseDict.status === "string") {
|
|
19463
|
+
metadata.status = responseDict.status;
|
|
19464
|
+
}
|
|
19465
|
+
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
19466
|
+
}
|
|
18483
19467
|
function extractEmbedPromptTokenCount(response) {
|
|
18484
19468
|
if (!response) {
|
|
18485
19469
|
return void 0;
|
|
@@ -18542,6 +19526,23 @@ function populateUsageMetrics(metrics, usage) {
|
|
|
18542
19526
|
metrics.completion_reasoning_tokens = usage.thoughtsTokenCount;
|
|
18543
19527
|
}
|
|
18544
19528
|
}
|
|
19529
|
+
function populateInteractionUsageMetrics(metrics, usage) {
|
|
19530
|
+
if (typeof usage.total_input_tokens === "number") {
|
|
19531
|
+
metrics.prompt_tokens = usage.total_input_tokens;
|
|
19532
|
+
}
|
|
19533
|
+
if (typeof usage.total_output_tokens === "number") {
|
|
19534
|
+
metrics.completion_tokens = usage.total_output_tokens;
|
|
19535
|
+
}
|
|
19536
|
+
if (typeof usage.total_tokens === "number") {
|
|
19537
|
+
metrics.tokens = usage.total_tokens;
|
|
19538
|
+
}
|
|
19539
|
+
if (typeof usage.total_cached_tokens === "number") {
|
|
19540
|
+
metrics.prompt_cached_tokens = usage.total_cached_tokens;
|
|
19541
|
+
}
|
|
19542
|
+
if (typeof usage.total_thought_tokens === "number") {
|
|
19543
|
+
metrics.completion_reasoning_tokens = usage.total_thought_tokens;
|
|
19544
|
+
}
|
|
19545
|
+
}
|
|
18545
19546
|
function aggregateGenerateContentChunks(chunks, startTime, firstTokenTime) {
|
|
18546
19547
|
const end = getCurrentUnixTimestamp();
|
|
18547
19548
|
const metrics = {
|
|
@@ -18639,6 +19640,146 @@ function aggregateGenerateContentChunks(chunks, startTime, firstTokenTime) {
|
|
|
18639
19640
|
}
|
|
18640
19641
|
return { aggregated, metrics };
|
|
18641
19642
|
}
|
|
19643
|
+
function aggregateInteractionEvents(chunks, startTime) {
|
|
19644
|
+
const end = getCurrentUnixTimestamp();
|
|
19645
|
+
const metrics = {};
|
|
19646
|
+
if (startTime !== void 0) {
|
|
19647
|
+
metrics.start = startTime;
|
|
19648
|
+
metrics.end = end;
|
|
19649
|
+
metrics.duration = end - startTime;
|
|
19650
|
+
}
|
|
19651
|
+
let latestInteraction;
|
|
19652
|
+
let latestUsage;
|
|
19653
|
+
let status;
|
|
19654
|
+
let outputText = "";
|
|
19655
|
+
const steps = /* @__PURE__ */ new Map();
|
|
19656
|
+
for (const chunk of chunks) {
|
|
19657
|
+
const event = tryToDict(chunk);
|
|
19658
|
+
if (!event) {
|
|
19659
|
+
continue;
|
|
19660
|
+
}
|
|
19661
|
+
const usage = extractInteractionUsageFromEvent(event);
|
|
19662
|
+
if (usage) {
|
|
19663
|
+
latestUsage = usage;
|
|
19664
|
+
}
|
|
19665
|
+
const interaction = tryToDict(event.interaction);
|
|
19666
|
+
if (interaction) {
|
|
19667
|
+
latestInteraction = serializeInteractionValue(interaction);
|
|
19668
|
+
if (typeof interaction.status === "string") {
|
|
19669
|
+
status = interaction.status;
|
|
19670
|
+
}
|
|
19671
|
+
}
|
|
19672
|
+
if (typeof event.status === "string") {
|
|
19673
|
+
status = event.status;
|
|
19674
|
+
}
|
|
19675
|
+
const index = typeof event.index === "number" ? event.index : void 0;
|
|
19676
|
+
if (index === void 0) {
|
|
19677
|
+
continue;
|
|
19678
|
+
}
|
|
19679
|
+
if (event.event_type === "step.start") {
|
|
19680
|
+
const compact = compactInteractionStep(event.step);
|
|
19681
|
+
compact.index = index;
|
|
19682
|
+
steps.set(index, compact);
|
|
19683
|
+
continue;
|
|
19684
|
+
}
|
|
19685
|
+
if (event.event_type === "step.delta") {
|
|
19686
|
+
const step = steps.get(index) ?? { index };
|
|
19687
|
+
const textDelta = applyInteractionDelta(step, event.delta);
|
|
19688
|
+
if (textDelta) {
|
|
19689
|
+
outputText += textDelta;
|
|
19690
|
+
}
|
|
19691
|
+
steps.set(index, step);
|
|
19692
|
+
}
|
|
19693
|
+
}
|
|
19694
|
+
if (latestUsage) {
|
|
19695
|
+
populateInteractionUsageMetrics(metrics, latestUsage);
|
|
19696
|
+
}
|
|
19697
|
+
const output = latestInteraction ? { ...latestInteraction } : {};
|
|
19698
|
+
if (status) {
|
|
19699
|
+
output.status = status;
|
|
19700
|
+
}
|
|
19701
|
+
if (outputText) {
|
|
19702
|
+
output.output_text = outputText;
|
|
19703
|
+
}
|
|
19704
|
+
if (latestUsage) {
|
|
19705
|
+
output.usage = serializeInteractionValue(latestUsage);
|
|
19706
|
+
}
|
|
19707
|
+
const compactSteps = Array.from(steps.values()).sort(
|
|
19708
|
+
(left, right) => Number(left.index ?? 0) - Number(right.index ?? 0)
|
|
19709
|
+
);
|
|
19710
|
+
if (compactSteps.length > 0) {
|
|
19711
|
+
output.steps = compactSteps;
|
|
19712
|
+
}
|
|
19713
|
+
const metadata = {};
|
|
19714
|
+
if (typeof output.id === "string") {
|
|
19715
|
+
metadata.interaction_id = output.id;
|
|
19716
|
+
}
|
|
19717
|
+
if (typeof output.status === "string") {
|
|
19718
|
+
metadata.status = output.status;
|
|
19719
|
+
}
|
|
19720
|
+
return {
|
|
19721
|
+
output,
|
|
19722
|
+
metrics: cleanMetrics3(metrics),
|
|
19723
|
+
...Object.keys(metadata).length > 0 ? { metadata } : {}
|
|
19724
|
+
};
|
|
19725
|
+
}
|
|
19726
|
+
function extractInteractionUsageFromEvent(event) {
|
|
19727
|
+
const metadata = tryToDict(event.metadata);
|
|
19728
|
+
const metadataUsage = tryToDict(metadata?.usage);
|
|
19729
|
+
if (metadataUsage) {
|
|
19730
|
+
return metadataUsage;
|
|
19731
|
+
}
|
|
19732
|
+
const metadataTotalUsage = tryToDict(metadata?.total_usage);
|
|
19733
|
+
if (metadataTotalUsage) {
|
|
19734
|
+
return metadataTotalUsage;
|
|
19735
|
+
}
|
|
19736
|
+
const interaction = tryToDict(event.interaction);
|
|
19737
|
+
const interactionUsage = tryToDict(interaction?.usage);
|
|
19738
|
+
return interactionUsage ? interactionUsage : void 0;
|
|
19739
|
+
}
|
|
19740
|
+
function compactInteractionStep(step) {
|
|
19741
|
+
const stepDict = tryToDict(step);
|
|
19742
|
+
if (!stepDict) {
|
|
19743
|
+
return {};
|
|
19744
|
+
}
|
|
19745
|
+
const compact = {};
|
|
19746
|
+
for (const key of [
|
|
19747
|
+
"type",
|
|
19748
|
+
"content",
|
|
19749
|
+
"name",
|
|
19750
|
+
"server_name",
|
|
19751
|
+
"arguments",
|
|
19752
|
+
"result",
|
|
19753
|
+
"is_error"
|
|
19754
|
+
]) {
|
|
19755
|
+
if (stepDict[key] !== void 0) {
|
|
19756
|
+
compact[key] = serializeInteractionValue(stepDict[key]);
|
|
19757
|
+
}
|
|
19758
|
+
}
|
|
19759
|
+
return Object.keys(compact).length > 0 ? compact : serializeInteractionValue(stepDict);
|
|
19760
|
+
}
|
|
19761
|
+
function applyInteractionDelta(step, delta) {
|
|
19762
|
+
const deltaDict = tryToDict(delta);
|
|
19763
|
+
if (!deltaDict) {
|
|
19764
|
+
return void 0;
|
|
19765
|
+
}
|
|
19766
|
+
const deltaType = deltaDict.type;
|
|
19767
|
+
if (typeof deltaType === "string" && typeof step.type !== "string") {
|
|
19768
|
+
step.type = deltaType === "text" ? "model_output" : deltaType;
|
|
19769
|
+
}
|
|
19770
|
+
if (deltaType === "text" && typeof deltaDict.text === "string") {
|
|
19771
|
+
step.text = `${typeof step.text === "string" ? step.text : ""}${deltaDict.text}`;
|
|
19772
|
+
return deltaDict.text;
|
|
19773
|
+
}
|
|
19774
|
+
if (deltaType === "arguments_delta" && typeof deltaDict.arguments === "string") {
|
|
19775
|
+
step.arguments = `${typeof step.arguments === "string" ? step.arguments : ""}${deltaDict.arguments}`;
|
|
19776
|
+
return void 0;
|
|
19777
|
+
}
|
|
19778
|
+
const deltas = Array.isArray(step.deltas) ? step.deltas : [];
|
|
19779
|
+
deltas.push(serializeInteractionValue(deltaDict));
|
|
19780
|
+
step.deltas = deltas;
|
|
19781
|
+
return void 0;
|
|
19782
|
+
}
|
|
18642
19783
|
function cleanMetrics3(metrics) {
|
|
18643
19784
|
const cleaned = {};
|
|
18644
19785
|
for (const [key, value] of Object.entries(metrics)) {
|
|
@@ -24465,7 +25606,8 @@ var FlueObserveBridge = class {
|
|
|
24465
25606
|
metadata
|
|
24466
25607
|
}
|
|
24467
25608
|
});
|
|
24468
|
-
|
|
25609
|
+
const activeContext = enterCurrentFlueSpan(span);
|
|
25610
|
+
this.runsById.set(event.runId, { activeContext, metadata, span });
|
|
24469
25611
|
}
|
|
24470
25612
|
handleRunEnd(event) {
|
|
24471
25613
|
const state = this.runsById.get(event.runId);
|
|
@@ -24483,6 +25625,7 @@ var FlueObserveBridge = class {
|
|
|
24483
25625
|
});
|
|
24484
25626
|
safeEnd(state.span, eventTime(event.timestamp));
|
|
24485
25627
|
this.runsById.delete(event.runId);
|
|
25628
|
+
restoreCurrentFlueSpan(state.activeContext);
|
|
24486
25629
|
}
|
|
24487
25630
|
void flush().catch((error) => {
|
|
24488
25631
|
logInstrumentationError3("Flue flush", error);
|
|
@@ -24609,7 +25752,8 @@ var FlueObserveBridge = class {
|
|
|
24609
25752
|
metadata
|
|
24610
25753
|
}
|
|
24611
25754
|
});
|
|
24612
|
-
|
|
25755
|
+
const activeContext = enterCurrentFlueSpan(span);
|
|
25756
|
+
this.toolsByKey.set(toolKey(event), { activeContext, metadata, span });
|
|
24613
25757
|
}
|
|
24614
25758
|
handleToolCall(event) {
|
|
24615
25759
|
if (!event.toolCallId) {
|
|
@@ -24632,6 +25776,7 @@ var FlueObserveBridge = class {
|
|
|
24632
25776
|
});
|
|
24633
25777
|
safeEnd(state.span, eventTime(event.timestamp));
|
|
24634
25778
|
this.toolsByKey.delete(key);
|
|
25779
|
+
restoreCurrentFlueSpan(state.activeContext);
|
|
24635
25780
|
}
|
|
24636
25781
|
handleTaskStart(event) {
|
|
24637
25782
|
if (!event.taskId) {
|
|
@@ -25036,6 +26181,34 @@ function stateMatchesRun(state, runId) {
|
|
|
25036
26181
|
function startFlueSpan(parent, args) {
|
|
25037
26182
|
return parent ? withCurrent(parent, () => startSpan(args)) : startSpan(args);
|
|
25038
26183
|
}
|
|
26184
|
+
function enterCurrentFlueSpan(span) {
|
|
26185
|
+
const contextManager = _internalGetGlobalState()?.contextManager;
|
|
26186
|
+
const store = contextManager ? Reflect.get(contextManager, BRAINTRUST_CURRENT_SPAN_STORE) : void 0;
|
|
26187
|
+
if (!contextManager || !isCurrentSpanStore(store)) {
|
|
26188
|
+
return void 0;
|
|
26189
|
+
}
|
|
26190
|
+
const previous = store.getStore();
|
|
26191
|
+
try {
|
|
26192
|
+
store.enterWith(contextManager.wrapSpanForStore(span));
|
|
26193
|
+
return { previous, store };
|
|
26194
|
+
} catch (error) {
|
|
26195
|
+
logInstrumentationError3("Flue context propagation", error);
|
|
26196
|
+
return void 0;
|
|
26197
|
+
}
|
|
26198
|
+
}
|
|
26199
|
+
function isCurrentSpanStore(value) {
|
|
26200
|
+
return isObjectLike(value) && typeof Reflect.get(value, "enterWith") === "function" && typeof Reflect.get(value, "getStore") === "function";
|
|
26201
|
+
}
|
|
26202
|
+
function restoreCurrentFlueSpan(activeContext) {
|
|
26203
|
+
if (!activeContext) {
|
|
26204
|
+
return;
|
|
26205
|
+
}
|
|
26206
|
+
try {
|
|
26207
|
+
activeContext.store.enterWith(activeContext.previous);
|
|
26208
|
+
} catch (error) {
|
|
26209
|
+
logInstrumentationError3("Flue context restoration", error);
|
|
26210
|
+
}
|
|
26211
|
+
}
|
|
25039
26212
|
function safeLog3(span, event) {
|
|
25040
26213
|
try {
|
|
25041
26214
|
span.log(event);
|
|
@@ -25513,6 +26686,890 @@ function isBraintrustHandler(handler) {
|
|
|
25513
26686
|
return Reflect.get(handler, "name") === BRAINTRUST_LANGCHAIN_CALLBACK_HANDLER_NAME;
|
|
25514
26687
|
}
|
|
25515
26688
|
|
|
26689
|
+
// src/instrumentation/plugins/pi-coding-agent-channels.ts
|
|
26690
|
+
var piCodingAgentChannels = defineChannels(
|
|
26691
|
+
"@earendil-works/pi-coding-agent",
|
|
26692
|
+
{
|
|
26693
|
+
prompt: channel({
|
|
26694
|
+
channelName: "AgentSession.prompt",
|
|
26695
|
+
kind: "async"
|
|
26696
|
+
})
|
|
26697
|
+
}
|
|
26698
|
+
);
|
|
26699
|
+
|
|
26700
|
+
// src/instrumentation/plugins/pi-coding-agent-plugin.ts
|
|
26701
|
+
var piStreamPatchStates = /* @__PURE__ */ new WeakMap();
|
|
26702
|
+
var piPromptContextStore;
|
|
26703
|
+
var PiCodingAgentPlugin = class extends BasePlugin {
|
|
26704
|
+
activePromptStates = /* @__PURE__ */ new Set();
|
|
26705
|
+
onEnable() {
|
|
26706
|
+
this.subscribeToPrompt();
|
|
26707
|
+
}
|
|
26708
|
+
onDisable() {
|
|
26709
|
+
for (const unsubscribe of this.unsubscribers) {
|
|
26710
|
+
unsubscribe();
|
|
26711
|
+
}
|
|
26712
|
+
this.unsubscribers = [];
|
|
26713
|
+
for (const state of [...this.activePromptStates]) {
|
|
26714
|
+
void finalizePiPromptRun(state).catch((error) => {
|
|
26715
|
+
logInstrumentationError4("Pi Coding Agent disable cleanup", error);
|
|
26716
|
+
});
|
|
26717
|
+
}
|
|
26718
|
+
}
|
|
26719
|
+
subscribeToPrompt() {
|
|
26720
|
+
const channel2 = piCodingAgentChannels.prompt.tracingChannel();
|
|
26721
|
+
const states = /* @__PURE__ */ new WeakMap();
|
|
26722
|
+
const unbindAutoInstrumentationSuppression = bindAutoInstrumentationSuppressionToStart(channel2);
|
|
26723
|
+
const handlers = {
|
|
26724
|
+
start: (event) => {
|
|
26725
|
+
const state = startPiPromptRun(event, (state2) => {
|
|
26726
|
+
this.activePromptStates.delete(state2);
|
|
26727
|
+
});
|
|
26728
|
+
if (state) {
|
|
26729
|
+
this.activePromptStates.add(state);
|
|
26730
|
+
states.set(event, state);
|
|
26731
|
+
}
|
|
26732
|
+
},
|
|
26733
|
+
asyncEnd: async (event) => {
|
|
26734
|
+
const state = states.get(event);
|
|
26735
|
+
if (!state) {
|
|
26736
|
+
return;
|
|
26737
|
+
}
|
|
26738
|
+
states.delete(event);
|
|
26739
|
+
state.promptCallEnded = true;
|
|
26740
|
+
if (!state.finalized && state.deferCompletionUntilTurnEnd && !state.turnEnded) {
|
|
26741
|
+
if (!state.sawStreamFn) {
|
|
26742
|
+
state.queued = true;
|
|
26743
|
+
if (!state.streamPatchState.queuedPromptStates.includes(state)) {
|
|
26744
|
+
state.streamPatchState.queuedPromptStates.push(state);
|
|
26745
|
+
}
|
|
26746
|
+
}
|
|
26747
|
+
return;
|
|
26748
|
+
}
|
|
26749
|
+
await finalizePiPromptRun(state);
|
|
26750
|
+
},
|
|
26751
|
+
error: async (event) => {
|
|
26752
|
+
const state = states.get(event);
|
|
26753
|
+
if (!state) {
|
|
26754
|
+
return;
|
|
26755
|
+
}
|
|
26756
|
+
states.delete(event);
|
|
26757
|
+
await finalizePiPromptRun(state, event.error);
|
|
26758
|
+
}
|
|
26759
|
+
};
|
|
26760
|
+
channel2.subscribe(handlers);
|
|
26761
|
+
this.unsubscribers.push(() => {
|
|
26762
|
+
unbindAutoInstrumentationSuppression?.();
|
|
26763
|
+
channel2.unsubscribe(handlers);
|
|
26764
|
+
});
|
|
26765
|
+
}
|
|
26766
|
+
};
|
|
26767
|
+
function startPiPromptRun(event, onFinalize) {
|
|
26768
|
+
const session = extractSession(event);
|
|
26769
|
+
const agent = session?.agent;
|
|
26770
|
+
if (!session || !isPiAgent(agent)) {
|
|
26771
|
+
return void 0;
|
|
26772
|
+
}
|
|
26773
|
+
const metadata = {
|
|
26774
|
+
...extractSessionMetadata(session),
|
|
26775
|
+
...extractPromptOptionsMetadata(event.arguments[1]),
|
|
26776
|
+
"pi_coding_agent.operation": "AgentSession.prompt",
|
|
26777
|
+
provider: session.model?.provider ?? agent.state?.model?.provider ?? "pi",
|
|
26778
|
+
...session.model?.id || agent.state?.model?.id ? { model: session.model?.id ?? agent.state?.model?.id } : {},
|
|
26779
|
+
...event.moduleVersion ? { "pi_coding_agent.version": event.moduleVersion } : {}
|
|
26780
|
+
};
|
|
26781
|
+
const span = startSpan({
|
|
26782
|
+
event: {
|
|
26783
|
+
input: extractPromptInput(event.arguments[0], event.arguments[1]),
|
|
26784
|
+
metadata
|
|
26785
|
+
},
|
|
26786
|
+
name: "AgentSession.prompt",
|
|
26787
|
+
spanAttributes: { type: "task" /* TASK */ }
|
|
26788
|
+
});
|
|
26789
|
+
const streamPatchState = installPiStreamPatch(agent);
|
|
26790
|
+
const options = event.arguments[1];
|
|
26791
|
+
const promptText = event.arguments[0];
|
|
26792
|
+
const state = {
|
|
26793
|
+
activeLlmSpans: /* @__PURE__ */ new Set(),
|
|
26794
|
+
activeToolSpans: /* @__PURE__ */ new Map(),
|
|
26795
|
+
agent,
|
|
26796
|
+
collectedLlmUsageMetrics: false,
|
|
26797
|
+
deferCompletionUntilTurnEnd: options?.streamingBehavior === "followUp" || options?.streamingBehavior === "steer",
|
|
26798
|
+
finalized: false,
|
|
26799
|
+
metadata,
|
|
26800
|
+
metrics: {},
|
|
26801
|
+
onFinalize,
|
|
26802
|
+
promptCallEnded: false,
|
|
26803
|
+
...typeof promptText === "string" ? { promptText } : {},
|
|
26804
|
+
queued: false,
|
|
26805
|
+
span,
|
|
26806
|
+
sawStreamFn: false,
|
|
26807
|
+
startTime: getCurrentUnixTimestamp(),
|
|
26808
|
+
streamPatchState,
|
|
26809
|
+
turnEnded: false
|
|
26810
|
+
};
|
|
26811
|
+
state.restorePromptContext = enterPiPromptContext(state);
|
|
26812
|
+
streamPatchState.activePromptStates.add(state);
|
|
26813
|
+
try {
|
|
26814
|
+
state.unsubscribeAgent = agent.subscribe(async (agentEvent) => {
|
|
26815
|
+
try {
|
|
26816
|
+
await runWithAutoInstrumentationSuppressed(
|
|
26817
|
+
() => handlePiAgentEvent(state, agentEvent)
|
|
26818
|
+
);
|
|
26819
|
+
} catch (error) {
|
|
26820
|
+
logInstrumentationError4("Pi Coding Agent event", error);
|
|
26821
|
+
}
|
|
26822
|
+
});
|
|
26823
|
+
} catch (error) {
|
|
26824
|
+
logInstrumentationError4("Pi Coding Agent event subscription", error);
|
|
26825
|
+
}
|
|
26826
|
+
return state;
|
|
26827
|
+
}
|
|
26828
|
+
function extractSession(event) {
|
|
26829
|
+
const candidate = event.session ?? event.self;
|
|
26830
|
+
return isObject(candidate) && typeof candidate.prompt === "function" ? candidate : void 0;
|
|
26831
|
+
}
|
|
26832
|
+
function isPiAgent(value) {
|
|
26833
|
+
return isObject(value) && typeof value.streamFn === "function" && typeof value.subscribe === "function";
|
|
26834
|
+
}
|
|
26835
|
+
function promptContextStore() {
|
|
26836
|
+
piPromptContextStore ??= isomorph_default.newAsyncLocalStorage();
|
|
26837
|
+
return piPromptContextStore;
|
|
26838
|
+
}
|
|
26839
|
+
function currentPromptContextFrames() {
|
|
26840
|
+
return promptContextStore().getStore()?.frames ?? [];
|
|
26841
|
+
}
|
|
26842
|
+
function currentPiPromptState() {
|
|
26843
|
+
const frames = currentPromptContextFrames();
|
|
26844
|
+
return frames[frames.length - 1]?.state;
|
|
26845
|
+
}
|
|
26846
|
+
function enterPiPromptContext(state) {
|
|
26847
|
+
const frame = {
|
|
26848
|
+
id: /* @__PURE__ */ Symbol("braintrust.pi-coding-agent.prompt"),
|
|
26849
|
+
state
|
|
26850
|
+
};
|
|
26851
|
+
promptContextStore().enterWith({
|
|
26852
|
+
frames: [...currentPromptContextFrames(), frame]
|
|
26853
|
+
});
|
|
26854
|
+
return () => {
|
|
26855
|
+
const frames = currentPromptContextFrames().filter(
|
|
26856
|
+
(candidate) => candidate.id !== frame.id
|
|
26857
|
+
);
|
|
26858
|
+
promptContextStore().enterWith(frames.length > 0 ? { frames } : void 0);
|
|
26859
|
+
};
|
|
26860
|
+
}
|
|
26861
|
+
function installPiStreamPatch(agent) {
|
|
26862
|
+
const existing = piStreamPatchStates.get(agent);
|
|
26863
|
+
if (existing) {
|
|
26864
|
+
if (agent.streamFn !== existing.wrappedStreamFn) {
|
|
26865
|
+
debugLogger.debug(
|
|
26866
|
+
"Pi Coding Agent streamFn changed while Braintrust instrumentation was active; preserving existing patch state."
|
|
26867
|
+
);
|
|
26868
|
+
}
|
|
26869
|
+
return existing;
|
|
26870
|
+
}
|
|
26871
|
+
const patchState = {
|
|
26872
|
+
activePromptStates: /* @__PURE__ */ new Set(),
|
|
26873
|
+
agent,
|
|
26874
|
+
originalStreamFn: agent.streamFn,
|
|
26875
|
+
queuedPromptStates: [],
|
|
26876
|
+
wrappedStreamFn: agent.streamFn
|
|
26877
|
+
};
|
|
26878
|
+
patchState.wrappedStreamFn = makeSharedInstrumentedStreamFn(patchState);
|
|
26879
|
+
agent.streamFn = patchState.wrappedStreamFn;
|
|
26880
|
+
piStreamPatchStates.set(agent, patchState);
|
|
26881
|
+
return patchState;
|
|
26882
|
+
}
|
|
26883
|
+
function resolveStreamPromptState(patchState, context) {
|
|
26884
|
+
let lastUserText;
|
|
26885
|
+
if (Array.isArray(context.messages)) {
|
|
26886
|
+
for (let i = context.messages.length - 1; i >= 0; i--) {
|
|
26887
|
+
const message = context.messages[i];
|
|
26888
|
+
if (isPiUserMessage(message)) {
|
|
26889
|
+
if (typeof message.content === "string") {
|
|
26890
|
+
lastUserText = message.content;
|
|
26891
|
+
} else {
|
|
26892
|
+
lastUserText = message.content.flatMap((part) => part.type === "text" ? [part.text] : []).join("");
|
|
26893
|
+
}
|
|
26894
|
+
break;
|
|
26895
|
+
}
|
|
26896
|
+
}
|
|
26897
|
+
}
|
|
26898
|
+
if (lastUserText !== void 0) {
|
|
26899
|
+
const queuedMatch = patchState.queuedPromptStates.find(
|
|
26900
|
+
(state) => state.promptText === lastUserText
|
|
26901
|
+
);
|
|
26902
|
+
if (queuedMatch) {
|
|
26903
|
+
return queuedMatch;
|
|
26904
|
+
}
|
|
26905
|
+
const matches = [...patchState.activePromptStates].filter(
|
|
26906
|
+
(state) => state.promptText === lastUserText
|
|
26907
|
+
);
|
|
26908
|
+
if (matches.length === 1) {
|
|
26909
|
+
return matches[0];
|
|
26910
|
+
}
|
|
26911
|
+
}
|
|
26912
|
+
const contextState = currentPiPromptState();
|
|
26913
|
+
if (contextState && patchState.activePromptStates.has(contextState) && (!contextState.queued || lastUserText !== void 0 && contextState.promptText === lastUserText)) {
|
|
26914
|
+
return contextState;
|
|
26915
|
+
}
|
|
26916
|
+
if (patchState.activePromptStates.size === 1) {
|
|
26917
|
+
return [...patchState.activePromptStates][0];
|
|
26918
|
+
}
|
|
26919
|
+
return void 0;
|
|
26920
|
+
}
|
|
26921
|
+
function makeSharedInstrumentedStreamFn(patchState) {
|
|
26922
|
+
return async function instrumentedPiStreamFn(model, context, options) {
|
|
26923
|
+
const state = resolveStreamPromptState(patchState, context);
|
|
26924
|
+
if (!state) {
|
|
26925
|
+
const invokeOriginal = () => Reflect.apply(patchState.originalStreamFn, this, [
|
|
26926
|
+
model,
|
|
26927
|
+
context,
|
|
26928
|
+
options
|
|
26929
|
+
]);
|
|
26930
|
+
return patchState.activePromptStates.size > 0 ? runWithAutoInstrumentationSuppressed(invokeOriginal) : invokeOriginal();
|
|
26931
|
+
}
|
|
26932
|
+
state.sawStreamFn = true;
|
|
26933
|
+
removeQueuedPromptState(state);
|
|
26934
|
+
state.streamPatchState.eventPromptState = state;
|
|
26935
|
+
const llmState = await startPiLlmSpan(state, model, context, options);
|
|
26936
|
+
try {
|
|
26937
|
+
const stream = await runWithAutoInstrumentationSuppressed(
|
|
26938
|
+
() => Reflect.apply(patchState.originalStreamFn, this, [
|
|
26939
|
+
model,
|
|
26940
|
+
context,
|
|
26941
|
+
options
|
|
26942
|
+
])
|
|
26943
|
+
);
|
|
26944
|
+
return patchAssistantMessageStream(stream, state, llmState);
|
|
26945
|
+
} catch (error) {
|
|
26946
|
+
finishPiLlmSpan(state, llmState, void 0, error);
|
|
26947
|
+
throw error;
|
|
26948
|
+
}
|
|
26949
|
+
};
|
|
26950
|
+
}
|
|
26951
|
+
async function startPiLlmSpan(state, model, context, options) {
|
|
26952
|
+
const metadata = {
|
|
26953
|
+
...extractModelMetadata2(model),
|
|
26954
|
+
...extractStreamOptionsMetadata(options),
|
|
26955
|
+
...extractToolMetadata(context.tools),
|
|
26956
|
+
"pi_coding_agent.operation": "agent.streamFn"
|
|
26957
|
+
};
|
|
26958
|
+
const span = startSpan({
|
|
26959
|
+
event: {
|
|
26960
|
+
input: processInputAttachments(normalizePiContextInput(context)),
|
|
26961
|
+
metadata
|
|
26962
|
+
},
|
|
26963
|
+
name: getLlmSpanName(model),
|
|
26964
|
+
parent: await state.span.export(),
|
|
26965
|
+
spanAttributes: { type: "llm" /* LLM */ }
|
|
26966
|
+
});
|
|
26967
|
+
const llmState = {
|
|
26968
|
+
finalized: false,
|
|
26969
|
+
metadata,
|
|
26970
|
+
metrics: {},
|
|
26971
|
+
span,
|
|
26972
|
+
startTime: getCurrentUnixTimestamp()
|
|
26973
|
+
};
|
|
26974
|
+
state.activeLlmSpans.add(llmState);
|
|
26975
|
+
return llmState;
|
|
26976
|
+
}
|
|
26977
|
+
function patchAssistantMessageStream(stream, promptState, llmState) {
|
|
26978
|
+
if (!isObject(stream)) {
|
|
26979
|
+
return stream;
|
|
26980
|
+
}
|
|
26981
|
+
const streamRecord = stream;
|
|
26982
|
+
const originalResult = stream.result;
|
|
26983
|
+
if (typeof originalResult === "function") {
|
|
26984
|
+
streamRecord.result = function patchedPiResult() {
|
|
26985
|
+
return Promise.resolve(Reflect.apply(originalResult, this, [])).then(
|
|
26986
|
+
(message) => {
|
|
26987
|
+
finishPiLlmSpan(promptState, llmState, message);
|
|
26988
|
+
return message;
|
|
26989
|
+
},
|
|
26990
|
+
(error) => {
|
|
26991
|
+
finishPiLlmSpan(promptState, llmState, void 0, error);
|
|
26992
|
+
throw error;
|
|
26993
|
+
}
|
|
26994
|
+
);
|
|
26995
|
+
};
|
|
26996
|
+
}
|
|
26997
|
+
const originalIterator = stream[Symbol.asyncIterator];
|
|
26998
|
+
if (typeof originalIterator === "function") {
|
|
26999
|
+
streamRecord[Symbol.asyncIterator] = function patchedPiIterator() {
|
|
27000
|
+
const iterator = Reflect.apply(
|
|
27001
|
+
originalIterator,
|
|
27002
|
+
this,
|
|
27003
|
+
[]
|
|
27004
|
+
);
|
|
27005
|
+
return {
|
|
27006
|
+
async next() {
|
|
27007
|
+
try {
|
|
27008
|
+
const result = await iterator.next();
|
|
27009
|
+
if (result.done) {
|
|
27010
|
+
finishPiLlmSpan(promptState, llmState);
|
|
27011
|
+
return result;
|
|
27012
|
+
}
|
|
27013
|
+
recordPiAssistantMessageEvent(promptState, llmState, result.value);
|
|
27014
|
+
return result;
|
|
27015
|
+
} catch (error) {
|
|
27016
|
+
finishPiLlmSpan(promptState, llmState, void 0, error);
|
|
27017
|
+
if (typeof iterator.return === "function") {
|
|
27018
|
+
try {
|
|
27019
|
+
await iterator.return();
|
|
27020
|
+
} catch (cleanupError) {
|
|
27021
|
+
logInstrumentationError4(
|
|
27022
|
+
"Pi Coding Agent stream cleanup",
|
|
27023
|
+
cleanupError
|
|
27024
|
+
);
|
|
27025
|
+
}
|
|
27026
|
+
}
|
|
27027
|
+
throw error;
|
|
27028
|
+
}
|
|
27029
|
+
},
|
|
27030
|
+
async return(value) {
|
|
27031
|
+
try {
|
|
27032
|
+
if (typeof iterator.return === "function") {
|
|
27033
|
+
return await iterator.return(value);
|
|
27034
|
+
}
|
|
27035
|
+
return {
|
|
27036
|
+
done: true,
|
|
27037
|
+
value
|
|
27038
|
+
};
|
|
27039
|
+
} catch (error) {
|
|
27040
|
+
finishPiLlmSpan(promptState, llmState, void 0, error);
|
|
27041
|
+
throw error;
|
|
27042
|
+
} finally {
|
|
27043
|
+
finishPiLlmSpan(promptState, llmState);
|
|
27044
|
+
}
|
|
27045
|
+
},
|
|
27046
|
+
async throw(error) {
|
|
27047
|
+
try {
|
|
27048
|
+
if (typeof iterator.throw === "function") {
|
|
27049
|
+
return await iterator.throw(error);
|
|
27050
|
+
}
|
|
27051
|
+
throw error;
|
|
27052
|
+
} catch (thrownError) {
|
|
27053
|
+
finishPiLlmSpan(promptState, llmState, void 0, thrownError);
|
|
27054
|
+
throw thrownError;
|
|
27055
|
+
}
|
|
27056
|
+
},
|
|
27057
|
+
[Symbol.asyncIterator]() {
|
|
27058
|
+
return this;
|
|
27059
|
+
}
|
|
27060
|
+
};
|
|
27061
|
+
};
|
|
27062
|
+
}
|
|
27063
|
+
return stream;
|
|
27064
|
+
}
|
|
27065
|
+
function recordPiAssistantMessageEvent(promptState, llmState, event) {
|
|
27066
|
+
recordFirstTokenMetric(llmState, event);
|
|
27067
|
+
const message = "message" in event ? event.message : void 0;
|
|
27068
|
+
const errorMessage2 = "error" in event ? event.error : void 0;
|
|
27069
|
+
if (event.type === "done" && isPiAssistantMessage(message)) {
|
|
27070
|
+
finishPiLlmSpan(promptState, llmState, message);
|
|
27071
|
+
} else if (event.type === "error" && isPiAssistantMessage(errorMessage2)) {
|
|
27072
|
+
finishPiLlmSpan(promptState, llmState, errorMessage2);
|
|
27073
|
+
}
|
|
27074
|
+
}
|
|
27075
|
+
function recordFirstTokenMetric(state, event) {
|
|
27076
|
+
if (state.metrics.time_to_first_token !== void 0 || event.type === "start") {
|
|
27077
|
+
return;
|
|
27078
|
+
}
|
|
27079
|
+
state.metrics.time_to_first_token = getCurrentUnixTimestamp() - state.startTime;
|
|
27080
|
+
}
|
|
27081
|
+
async function handlePiAgentEvent(state, event) {
|
|
27082
|
+
if (state.finalized) {
|
|
27083
|
+
return;
|
|
27084
|
+
}
|
|
27085
|
+
const eventPromptState = state.streamPatchState.eventPromptState;
|
|
27086
|
+
if (eventPromptState && eventPromptState !== state) {
|
|
27087
|
+
return;
|
|
27088
|
+
}
|
|
27089
|
+
if (!eventPromptState && (state.queued || state.streamPatchState.activePromptStates.size > 1 && currentPiPromptState() !== state)) {
|
|
27090
|
+
return;
|
|
27091
|
+
}
|
|
27092
|
+
switch (event.type) {
|
|
27093
|
+
case "message_end":
|
|
27094
|
+
if (isPiAssistantMessage(event.message)) {
|
|
27095
|
+
state.output = extractAssistantOutput(event.message);
|
|
27096
|
+
}
|
|
27097
|
+
return;
|
|
27098
|
+
case "turn_end":
|
|
27099
|
+
state.turnEnded = true;
|
|
27100
|
+
if (isPiAssistantMessage(event.message)) {
|
|
27101
|
+
state.output = extractAssistantOutput(event.message);
|
|
27102
|
+
if (!state.collectedLlmUsageMetrics) {
|
|
27103
|
+
addMetrics(state.metrics, extractUsageMetrics2(event.message.usage));
|
|
27104
|
+
}
|
|
27105
|
+
}
|
|
27106
|
+
if (state.streamPatchState.eventPromptState === state) {
|
|
27107
|
+
state.streamPatchState.eventPromptState = void 0;
|
|
27108
|
+
}
|
|
27109
|
+
if (state.promptCallEnded && state.deferCompletionUntilTurnEnd) {
|
|
27110
|
+
await finalizePiPromptRun(state);
|
|
27111
|
+
}
|
|
27112
|
+
return;
|
|
27113
|
+
case "tool_execution_start":
|
|
27114
|
+
await startPiToolSpan(state, event);
|
|
27115
|
+
return;
|
|
27116
|
+
case "tool_execution_end":
|
|
27117
|
+
finishPiToolSpan(state, event);
|
|
27118
|
+
return;
|
|
27119
|
+
default:
|
|
27120
|
+
return;
|
|
27121
|
+
}
|
|
27122
|
+
}
|
|
27123
|
+
async function startPiToolSpan(state, event) {
|
|
27124
|
+
if (!event.toolCallId || state.activeToolSpans.has(event.toolCallId)) {
|
|
27125
|
+
return;
|
|
27126
|
+
}
|
|
27127
|
+
const restoreAutoInstrumentation = enterAutoInstrumentationAllowed();
|
|
27128
|
+
const metadata = {
|
|
27129
|
+
"gen_ai.tool.call.id": event.toolCallId,
|
|
27130
|
+
"gen_ai.tool.name": event.toolName,
|
|
27131
|
+
"pi_coding_agent.tool.name": event.toolName
|
|
27132
|
+
};
|
|
27133
|
+
try {
|
|
27134
|
+
const span = startSpan({
|
|
27135
|
+
event: {
|
|
27136
|
+
input: event.args,
|
|
27137
|
+
metadata
|
|
27138
|
+
},
|
|
27139
|
+
name: event.toolName || "tool",
|
|
27140
|
+
parent: await state.span.export(),
|
|
27141
|
+
spanAttributes: { type: "tool" /* TOOL */ }
|
|
27142
|
+
});
|
|
27143
|
+
state.activeToolSpans.set(event.toolCallId, {
|
|
27144
|
+
restoreAutoInstrumentation,
|
|
27145
|
+
span
|
|
27146
|
+
});
|
|
27147
|
+
} catch (error) {
|
|
27148
|
+
restoreAutoInstrumentation();
|
|
27149
|
+
throw error;
|
|
27150
|
+
}
|
|
27151
|
+
}
|
|
27152
|
+
function finishPiToolSpan(state, event) {
|
|
27153
|
+
const toolState = state.activeToolSpans.get(event.toolCallId);
|
|
27154
|
+
if (!toolState) {
|
|
27155
|
+
return;
|
|
27156
|
+
}
|
|
27157
|
+
state.activeToolSpans.delete(event.toolCallId);
|
|
27158
|
+
const metadata = {
|
|
27159
|
+
"gen_ai.tool.call.id": event.toolCallId,
|
|
27160
|
+
"gen_ai.tool.name": event.toolName,
|
|
27161
|
+
"pi_coding_agent.tool.name": event.toolName,
|
|
27162
|
+
"pi_coding_agent.tool.is_error": event.isError
|
|
27163
|
+
};
|
|
27164
|
+
try {
|
|
27165
|
+
safeLog4(toolState.span, {
|
|
27166
|
+
...event.isError ? { error: stringifyUnknown2(event.result) } : {},
|
|
27167
|
+
metadata,
|
|
27168
|
+
output: event.result
|
|
27169
|
+
});
|
|
27170
|
+
} finally {
|
|
27171
|
+
try {
|
|
27172
|
+
toolState.span.end();
|
|
27173
|
+
} finally {
|
|
27174
|
+
toolState.restoreAutoInstrumentation?.();
|
|
27175
|
+
}
|
|
27176
|
+
}
|
|
27177
|
+
}
|
|
27178
|
+
async function finalizePiPromptRun(state, error) {
|
|
27179
|
+
if (state.finalized) {
|
|
27180
|
+
return;
|
|
27181
|
+
}
|
|
27182
|
+
state.finalized = true;
|
|
27183
|
+
state.onFinalize?.(state);
|
|
27184
|
+
restorePiStreamFn(state);
|
|
27185
|
+
try {
|
|
27186
|
+
state.unsubscribeAgent?.();
|
|
27187
|
+
} catch (unsubscribeError) {
|
|
27188
|
+
logInstrumentationError4("Pi Coding Agent unsubscribe", unsubscribeError);
|
|
27189
|
+
}
|
|
27190
|
+
await finishOpenLlmSpans(state, error);
|
|
27191
|
+
finishOpenToolSpans(state, error);
|
|
27192
|
+
const metadata = {
|
|
27193
|
+
...state.metadata,
|
|
27194
|
+
...extractModelMetadata2(state.agent.state?.model)
|
|
27195
|
+
};
|
|
27196
|
+
try {
|
|
27197
|
+
safeLog4(state.span, {
|
|
27198
|
+
...error ? { error: stringifyUnknown2(error) } : {},
|
|
27199
|
+
metadata,
|
|
27200
|
+
metrics: {
|
|
27201
|
+
...cleanMetrics5(state.metrics),
|
|
27202
|
+
...buildDurationMetrics3(state.startTime)
|
|
27203
|
+
},
|
|
27204
|
+
output: state.output
|
|
27205
|
+
});
|
|
27206
|
+
} finally {
|
|
27207
|
+
state.span.end();
|
|
27208
|
+
}
|
|
27209
|
+
}
|
|
27210
|
+
function restorePiStreamFn(state) {
|
|
27211
|
+
const patchState = state.streamPatchState;
|
|
27212
|
+
patchState.activePromptStates.delete(state);
|
|
27213
|
+
removeQueuedPromptState(state);
|
|
27214
|
+
if (patchState.eventPromptState === state) {
|
|
27215
|
+
patchState.eventPromptState = void 0;
|
|
27216
|
+
}
|
|
27217
|
+
state.restorePromptContext?.();
|
|
27218
|
+
if (patchState.activePromptStates.size > 0) {
|
|
27219
|
+
return;
|
|
27220
|
+
}
|
|
27221
|
+
if (patchState.agent.streamFn === patchState.wrappedStreamFn) {
|
|
27222
|
+
patchState.agent.streamFn = patchState.originalStreamFn;
|
|
27223
|
+
}
|
|
27224
|
+
piStreamPatchStates.delete(patchState.agent);
|
|
27225
|
+
}
|
|
27226
|
+
function removeQueuedPromptState(state) {
|
|
27227
|
+
state.queued = false;
|
|
27228
|
+
const queuedPromptStates = state.streamPatchState.queuedPromptStates;
|
|
27229
|
+
const index = queuedPromptStates.indexOf(state);
|
|
27230
|
+
if (index >= 0) {
|
|
27231
|
+
queuedPromptStates.splice(index, 1);
|
|
27232
|
+
}
|
|
27233
|
+
}
|
|
27234
|
+
async function finishOpenLlmSpans(state, error) {
|
|
27235
|
+
for (const llmState of [...state.activeLlmSpans]) {
|
|
27236
|
+
finishPiLlmSpan(state, llmState, void 0, error);
|
|
27237
|
+
}
|
|
27238
|
+
}
|
|
27239
|
+
function finishPiLlmSpan(promptState, llmState, message, error) {
|
|
27240
|
+
if (llmState.finalized) {
|
|
27241
|
+
return;
|
|
27242
|
+
}
|
|
27243
|
+
llmState.finalized = true;
|
|
27244
|
+
promptState.activeLlmSpans.delete(llmState);
|
|
27245
|
+
const messageError = message?.stopReason === "error" && message.errorMessage;
|
|
27246
|
+
const metrics = {
|
|
27247
|
+
...extractUsageMetrics2(message?.usage),
|
|
27248
|
+
...cleanMetrics5(llmState.metrics),
|
|
27249
|
+
...buildDurationMetrics3(llmState.startTime)
|
|
27250
|
+
};
|
|
27251
|
+
const usageMetrics = extractUsageMetrics2(message?.usage);
|
|
27252
|
+
if (Object.keys(usageMetrics).length > 0) {
|
|
27253
|
+
promptState.collectedLlmUsageMetrics = true;
|
|
27254
|
+
addMetrics(promptState.metrics, usageMetrics);
|
|
27255
|
+
}
|
|
27256
|
+
try {
|
|
27257
|
+
safeLog4(llmState.span, {
|
|
27258
|
+
...error || messageError ? { error: stringifyUnknown2(error ?? messageError) } : {},
|
|
27259
|
+
metadata: {
|
|
27260
|
+
...llmState.metadata,
|
|
27261
|
+
...message ? extractAssistantMetadata(message) : {}
|
|
27262
|
+
},
|
|
27263
|
+
metrics,
|
|
27264
|
+
...message ? { output: extractAssistantOutput(message) } : {}
|
|
27265
|
+
});
|
|
27266
|
+
} finally {
|
|
27267
|
+
llmState.span.end();
|
|
27268
|
+
}
|
|
27269
|
+
}
|
|
27270
|
+
function finishOpenToolSpans(state, error) {
|
|
27271
|
+
for (const [, toolState] of state.activeToolSpans) {
|
|
27272
|
+
try {
|
|
27273
|
+
safeLog4(toolState.span, {
|
|
27274
|
+
error: error ? stringifyUnknown2(error) : "Pi tool did not complete"
|
|
27275
|
+
});
|
|
27276
|
+
toolState.span.end();
|
|
27277
|
+
} finally {
|
|
27278
|
+
toolState.restoreAutoInstrumentation?.();
|
|
27279
|
+
}
|
|
27280
|
+
}
|
|
27281
|
+
state.activeToolSpans.clear();
|
|
27282
|
+
}
|
|
27283
|
+
function normalizePiContextInput(context) {
|
|
27284
|
+
const messages = context.messages.flatMap(
|
|
27285
|
+
(message) => normalizePiMessage(message)
|
|
27286
|
+
);
|
|
27287
|
+
if (context.systemPrompt) {
|
|
27288
|
+
return [{ role: "system", content: context.systemPrompt }, ...messages];
|
|
27289
|
+
}
|
|
27290
|
+
return messages;
|
|
27291
|
+
}
|
|
27292
|
+
function normalizePiMessage(message) {
|
|
27293
|
+
if (isPiUserMessage(message)) {
|
|
27294
|
+
return [
|
|
27295
|
+
{
|
|
27296
|
+
role: "user",
|
|
27297
|
+
content: normalizeUserContent(message.content)
|
|
27298
|
+
}
|
|
27299
|
+
];
|
|
27300
|
+
}
|
|
27301
|
+
if (isPiAssistantMessage(message)) {
|
|
27302
|
+
return [normalizeAssistantMessage(message)];
|
|
27303
|
+
}
|
|
27304
|
+
if (isPiToolResultMessage(message)) {
|
|
27305
|
+
return [normalizeToolResultMessage(message)];
|
|
27306
|
+
}
|
|
27307
|
+
return [];
|
|
27308
|
+
}
|
|
27309
|
+
function normalizeAssistantMessage(message) {
|
|
27310
|
+
const text = message.content.flatMap((part) => part.type === "text" ? [part.text] : []).join("");
|
|
27311
|
+
const thinking = message.content.flatMap(
|
|
27312
|
+
(part) => part.type === "thinking" && !part.redacted ? [part.thinking] : []
|
|
27313
|
+
).join("");
|
|
27314
|
+
const toolCalls = message.content.flatMap(
|
|
27315
|
+
(part) => part.type === "toolCall" ? [normalizeToolCall(part)] : []
|
|
27316
|
+
);
|
|
27317
|
+
return {
|
|
27318
|
+
role: "assistant",
|
|
27319
|
+
content: text || (toolCalls.length > 0 ? null : ""),
|
|
27320
|
+
...thinking ? { reasoning: thinking } : {},
|
|
27321
|
+
...toolCalls.length > 0 ? { tool_calls: toolCalls } : {}
|
|
27322
|
+
};
|
|
27323
|
+
}
|
|
27324
|
+
function normalizeToolResultMessage(message) {
|
|
27325
|
+
return {
|
|
27326
|
+
role: "tool",
|
|
27327
|
+
tool_call_id: message.toolCallId,
|
|
27328
|
+
content: normalizeUserContent(message.content)
|
|
27329
|
+
};
|
|
27330
|
+
}
|
|
27331
|
+
function normalizeUserContent(content) {
|
|
27332
|
+
if (typeof content === "string") {
|
|
27333
|
+
return content;
|
|
27334
|
+
}
|
|
27335
|
+
return content.map((part) => {
|
|
27336
|
+
if (part.type === "text") {
|
|
27337
|
+
return { type: "text", text: part.text };
|
|
27338
|
+
}
|
|
27339
|
+
if (part.type === "image") {
|
|
27340
|
+
return {
|
|
27341
|
+
type: "image_url",
|
|
27342
|
+
image_url: {
|
|
27343
|
+
url: `data:${part.mimeType};base64,${part.data}`
|
|
27344
|
+
}
|
|
27345
|
+
};
|
|
27346
|
+
}
|
|
27347
|
+
return part;
|
|
27348
|
+
});
|
|
27349
|
+
}
|
|
27350
|
+
function normalizeToolCall(toolCall) {
|
|
27351
|
+
return {
|
|
27352
|
+
id: toolCall.id,
|
|
27353
|
+
type: "function",
|
|
27354
|
+
function: {
|
|
27355
|
+
name: toolCall.name,
|
|
27356
|
+
arguments: stringifyArguments(toolCall.arguments)
|
|
27357
|
+
}
|
|
27358
|
+
};
|
|
27359
|
+
}
|
|
27360
|
+
function extractAssistantOutput(message) {
|
|
27361
|
+
return processInputAttachments([
|
|
27362
|
+
{
|
|
27363
|
+
finish_reason: normalizeStopReason(message.stopReason),
|
|
27364
|
+
index: 0,
|
|
27365
|
+
message: normalizeAssistantMessage(message)
|
|
27366
|
+
}
|
|
27367
|
+
]);
|
|
27368
|
+
}
|
|
27369
|
+
function isPiUserMessage(message) {
|
|
27370
|
+
return message.role === "user" && "content" in message;
|
|
27371
|
+
}
|
|
27372
|
+
function isPiAssistantMessage(message) {
|
|
27373
|
+
return isObject(message) && message.role === "assistant" && Array.isArray(message.content);
|
|
27374
|
+
}
|
|
27375
|
+
function isPiToolResultMessage(message) {
|
|
27376
|
+
return message.role === "toolResult" && Array.isArray(message.content);
|
|
27377
|
+
}
|
|
27378
|
+
function normalizeStopReason(reason) {
|
|
27379
|
+
switch (reason) {
|
|
27380
|
+
case "toolUse":
|
|
27381
|
+
return "tool_calls";
|
|
27382
|
+
case "length":
|
|
27383
|
+
case "stop":
|
|
27384
|
+
return reason;
|
|
27385
|
+
default:
|
|
27386
|
+
return reason ?? "stop";
|
|
27387
|
+
}
|
|
27388
|
+
}
|
|
27389
|
+
function extractPromptInput(text, options) {
|
|
27390
|
+
const images = options?.images;
|
|
27391
|
+
if (!images || images.length === 0) {
|
|
27392
|
+
return text;
|
|
27393
|
+
}
|
|
27394
|
+
return processInputAttachments([
|
|
27395
|
+
{
|
|
27396
|
+
role: "user",
|
|
27397
|
+
content: [
|
|
27398
|
+
{ type: "text", text: text ?? "" },
|
|
27399
|
+
...images.map((image) => ({
|
|
27400
|
+
type: "image_url",
|
|
27401
|
+
image_url: {
|
|
27402
|
+
url: `data:${image.mimeType};base64,${image.data}`
|
|
27403
|
+
}
|
|
27404
|
+
}))
|
|
27405
|
+
]
|
|
27406
|
+
}
|
|
27407
|
+
]);
|
|
27408
|
+
}
|
|
27409
|
+
function extractToolMetadata(tools) {
|
|
27410
|
+
if (!tools || tools.length === 0) {
|
|
27411
|
+
return {};
|
|
27412
|
+
}
|
|
27413
|
+
return {
|
|
27414
|
+
tools: tools.map((tool) => ({
|
|
27415
|
+
type: "function",
|
|
27416
|
+
function: {
|
|
27417
|
+
name: tool.name,
|
|
27418
|
+
...tool.description ? { description: tool.description } : {},
|
|
27419
|
+
...tool.parameters ? { parameters: tool.parameters } : {}
|
|
27420
|
+
}
|
|
27421
|
+
}))
|
|
27422
|
+
};
|
|
27423
|
+
}
|
|
27424
|
+
function extractModelMetadata2(model) {
|
|
27425
|
+
if (!model) {
|
|
27426
|
+
return {};
|
|
27427
|
+
}
|
|
27428
|
+
return {
|
|
27429
|
+
...model.provider ? { provider: model.provider } : {},
|
|
27430
|
+
...model.id ? { model: model.id, "pi_coding_agent.model": model.id } : {},
|
|
27431
|
+
...model.api ? { "pi_coding_agent.api": model.api } : {},
|
|
27432
|
+
...model.name ? { "pi_coding_agent.model_name": model.name } : {}
|
|
27433
|
+
};
|
|
27434
|
+
}
|
|
27435
|
+
function extractAssistantMetadata(message) {
|
|
27436
|
+
return {
|
|
27437
|
+
...message.provider ? { provider: message.provider } : {},
|
|
27438
|
+
...message.responseModel || message.model ? { model: message.responseModel ?? message.model } : {},
|
|
27439
|
+
...message.api ? { "pi_coding_agent.api": message.api } : {},
|
|
27440
|
+
...message.model ? { "pi_coding_agent.model": message.model } : {},
|
|
27441
|
+
...message.responseModel ? { "pi_coding_agent.response_model": message.responseModel } : {},
|
|
27442
|
+
...message.responseId ? { "pi_coding_agent.response_id": message.responseId } : {},
|
|
27443
|
+
...message.stopReason ? { "pi_coding_agent.stop_reason": message.stopReason } : {}
|
|
27444
|
+
};
|
|
27445
|
+
}
|
|
27446
|
+
function extractSessionMetadata(session) {
|
|
27447
|
+
return {
|
|
27448
|
+
...extractModelMetadata2(session.model),
|
|
27449
|
+
...session.sessionId ? { "pi_coding_agent.session_id": session.sessionId } : {},
|
|
27450
|
+
...session.sessionName ? { "pi_coding_agent.session_name": session.sessionName } : {},
|
|
27451
|
+
...session.thinkingLevel ? { "pi_coding_agent.thinking_level": session.thinkingLevel } : {},
|
|
27452
|
+
...typeof session.getActiveToolNames === "function" ? { "pi_coding_agent.active_tools": session.getActiveToolNames() } : {}
|
|
27453
|
+
};
|
|
27454
|
+
}
|
|
27455
|
+
function extractPromptOptionsMetadata(options) {
|
|
27456
|
+
if (!options) {
|
|
27457
|
+
return {};
|
|
27458
|
+
}
|
|
27459
|
+
return {
|
|
27460
|
+
...options.source ? { "pi_coding_agent.source": options.source } : {},
|
|
27461
|
+
...options.streamingBehavior ? { "pi_coding_agent.streaming_behavior": options.streamingBehavior } : {},
|
|
27462
|
+
...options.expandPromptTemplates !== void 0 ? {
|
|
27463
|
+
"pi_coding_agent.expand_prompt_templates": options.expandPromptTemplates
|
|
27464
|
+
} : {}
|
|
27465
|
+
};
|
|
27466
|
+
}
|
|
27467
|
+
function extractStreamOptionsMetadata(options) {
|
|
27468
|
+
if (!options) {
|
|
27469
|
+
return {};
|
|
27470
|
+
}
|
|
27471
|
+
return {
|
|
27472
|
+
...options.temperature !== void 0 ? { temperature: options.temperature } : {},
|
|
27473
|
+
...options.maxTokens !== void 0 ? { max_tokens: options.maxTokens } : {},
|
|
27474
|
+
...options.reasoning ? { "pi_coding_agent.reasoning": options.reasoning } : {},
|
|
27475
|
+
...options.transport ? { "pi_coding_agent.transport": options.transport } : {},
|
|
27476
|
+
...options.cacheRetention ? { "pi_coding_agent.cache_retention": options.cacheRetention } : {},
|
|
27477
|
+
...options.sessionId ? { "pi_coding_agent.session_id": options.sessionId } : {},
|
|
27478
|
+
...options.timeoutMs !== void 0 ? { "pi_coding_agent.timeout_ms": options.timeoutMs } : {},
|
|
27479
|
+
...options.maxRetries !== void 0 ? { "pi_coding_agent.max_retries": options.maxRetries } : {},
|
|
27480
|
+
...options.maxRetryDelayMs !== void 0 ? { "pi_coding_agent.max_retry_delay_ms": options.maxRetryDelayMs } : {},
|
|
27481
|
+
...options.metadata ? { "pi_coding_agent.metadata": options.metadata } : {}
|
|
27482
|
+
};
|
|
27483
|
+
}
|
|
27484
|
+
function getLlmSpanName(model) {
|
|
27485
|
+
switch (model.api) {
|
|
27486
|
+
case "anthropic-messages":
|
|
27487
|
+
return "anthropic.messages.create";
|
|
27488
|
+
case "openai-completions":
|
|
27489
|
+
return "Chat Completion";
|
|
27490
|
+
case "openai-responses":
|
|
27491
|
+
case "azure-openai-responses":
|
|
27492
|
+
case "openai-codex-responses":
|
|
27493
|
+
return "openai.responses.create";
|
|
27494
|
+
case "google-generative-ai":
|
|
27495
|
+
case "google-vertex":
|
|
27496
|
+
return "generate_content";
|
|
27497
|
+
case "mistral-conversations":
|
|
27498
|
+
return "mistral.chat.stream";
|
|
27499
|
+
case "bedrock-converse-stream":
|
|
27500
|
+
return "bedrock.converse_stream";
|
|
27501
|
+
default:
|
|
27502
|
+
return "pi_ai.streamSimple";
|
|
27503
|
+
}
|
|
27504
|
+
}
|
|
27505
|
+
function extractUsageMetrics2(usage) {
|
|
27506
|
+
if (!usage) {
|
|
27507
|
+
return {};
|
|
27508
|
+
}
|
|
27509
|
+
return cleanMetrics5({
|
|
27510
|
+
completion_tokens: usage.output,
|
|
27511
|
+
prompt_cache_creation_tokens: usage.cacheWrite,
|
|
27512
|
+
prompt_cached_tokens: usage.cacheRead,
|
|
27513
|
+
prompt_tokens: usage.input,
|
|
27514
|
+
tokens: usage.totalTokens ?? usage.tokens
|
|
27515
|
+
});
|
|
27516
|
+
}
|
|
27517
|
+
function addMetrics(target, source) {
|
|
27518
|
+
for (const [key, value] of Object.entries(source)) {
|
|
27519
|
+
target[key] = (target[key] ?? 0) + value;
|
|
27520
|
+
}
|
|
27521
|
+
}
|
|
27522
|
+
function buildDurationMetrics3(startTime) {
|
|
27523
|
+
const end = getCurrentUnixTimestamp();
|
|
27524
|
+
return {
|
|
27525
|
+
duration: end - startTime,
|
|
27526
|
+
end,
|
|
27527
|
+
start: startTime
|
|
27528
|
+
};
|
|
27529
|
+
}
|
|
27530
|
+
function cleanMetrics5(metrics) {
|
|
27531
|
+
const cleaned = {};
|
|
27532
|
+
for (const [key, value] of Object.entries(metrics)) {
|
|
27533
|
+
if (typeof value === "number" && Number.isFinite(value) && value >= 0) {
|
|
27534
|
+
cleaned[key] = value;
|
|
27535
|
+
}
|
|
27536
|
+
}
|
|
27537
|
+
return cleaned;
|
|
27538
|
+
}
|
|
27539
|
+
function stringifyArguments(value) {
|
|
27540
|
+
if (typeof value === "string") {
|
|
27541
|
+
return value;
|
|
27542
|
+
}
|
|
27543
|
+
try {
|
|
27544
|
+
return JSON.stringify(value);
|
|
27545
|
+
} catch {
|
|
27546
|
+
return stringifyUnknown2(value);
|
|
27547
|
+
}
|
|
27548
|
+
}
|
|
27549
|
+
function stringifyUnknown2(value) {
|
|
27550
|
+
if (value instanceof Error) {
|
|
27551
|
+
return value.message;
|
|
27552
|
+
}
|
|
27553
|
+
if (typeof value === "string") {
|
|
27554
|
+
return value;
|
|
27555
|
+
}
|
|
27556
|
+
try {
|
|
27557
|
+
return JSON.stringify(value);
|
|
27558
|
+
} catch {
|
|
27559
|
+
return String(value);
|
|
27560
|
+
}
|
|
27561
|
+
}
|
|
27562
|
+
function safeLog4(span, event) {
|
|
27563
|
+
try {
|
|
27564
|
+
span.log(event);
|
|
27565
|
+
} catch (error) {
|
|
27566
|
+
logInstrumentationError4("Pi Coding Agent span log", error);
|
|
27567
|
+
}
|
|
27568
|
+
}
|
|
27569
|
+
function logInstrumentationError4(context, error) {
|
|
27570
|
+
debugLogger.debug(`${context}:`, error);
|
|
27571
|
+
}
|
|
27572
|
+
|
|
25516
27573
|
// src/instrumentation/braintrust-plugin.ts
|
|
25517
27574
|
function getIntegrationConfig(integrations, key) {
|
|
25518
27575
|
return integrations[key];
|
|
@@ -25538,6 +27595,7 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
25538
27595
|
gitHubCopilotPlugin = null;
|
|
25539
27596
|
fluePlugin = null;
|
|
25540
27597
|
langChainPlugin = null;
|
|
27598
|
+
piCodingAgentPlugin = null;
|
|
25541
27599
|
constructor(config = {}) {
|
|
25542
27600
|
super();
|
|
25543
27601
|
this.config = config;
|
|
@@ -25612,6 +27670,10 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
25612
27670
|
this.gitHubCopilotPlugin = new GitHubCopilotPlugin();
|
|
25613
27671
|
this.gitHubCopilotPlugin.enable();
|
|
25614
27672
|
}
|
|
27673
|
+
if (integrations.piCodingAgent !== false) {
|
|
27674
|
+
this.piCodingAgentPlugin = new PiCodingAgentPlugin();
|
|
27675
|
+
this.piCodingAgentPlugin.enable();
|
|
27676
|
+
}
|
|
25615
27677
|
if (getIntegrationConfig(integrations, "flue") !== false) {
|
|
25616
27678
|
this.fluePlugin = new FluePlugin();
|
|
25617
27679
|
this.fluePlugin.enable();
|
|
@@ -25690,6 +27752,10 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
25690
27752
|
this.gitHubCopilotPlugin.disable();
|
|
25691
27753
|
this.gitHubCopilotPlugin = null;
|
|
25692
27754
|
}
|
|
27755
|
+
if (this.piCodingAgentPlugin) {
|
|
27756
|
+
this.piCodingAgentPlugin.disable();
|
|
27757
|
+
this.piCodingAgentPlugin = null;
|
|
27758
|
+
}
|
|
25693
27759
|
if (this.fluePlugin) {
|
|
25694
27760
|
this.fluePlugin.disable();
|
|
25695
27761
|
this.fluePlugin = null;
|
|
@@ -25709,6 +27775,11 @@ var envIntegrationAliases = {
|
|
|
25709
27775
|
openaicodexsdk: "openaiCodexSDK",
|
|
25710
27776
|
codex: "openaiCodexSDK",
|
|
25711
27777
|
"codex-sdk": "openaiCodexSDK",
|
|
27778
|
+
"pi-coding-agent": "piCodingAgent",
|
|
27779
|
+
"pi-coding-agent-sdk": "piCodingAgent",
|
|
27780
|
+
picodingagent: "piCodingAgent",
|
|
27781
|
+
picodingagentsdk: "piCodingAgent",
|
|
27782
|
+
"@earendil-works/pi-coding-agent": "piCodingAgent",
|
|
25712
27783
|
anthropic: "anthropic",
|
|
25713
27784
|
aisdk: "aisdk",
|
|
25714
27785
|
"ai-sdk": "aisdk",
|
|
@@ -25774,7 +27845,8 @@ function getDefaultInstrumentationIntegrations() {
|
|
|
25774
27845
|
genkit: true,
|
|
25775
27846
|
gitHubCopilot: true,
|
|
25776
27847
|
langchain: true,
|
|
25777
|
-
langgraph: true
|
|
27848
|
+
langgraph: true,
|
|
27849
|
+
piCodingAgent: true
|
|
25778
27850
|
};
|
|
25779
27851
|
}
|
|
25780
27852
|
function readDisabledInstrumentationEnvConfig(disabledList) {
|
|
@@ -25985,6 +28057,7 @@ __export(exports_exports, {
|
|
|
25985
28057
|
_internalIso: () => isomorph_default,
|
|
25986
28058
|
_internalSetInitialState: () => _internalSetInitialState,
|
|
25987
28059
|
addAzureBlobHeaders: () => addAzureBlobHeaders,
|
|
28060
|
+
braintrustAISDKTelemetry: () => braintrustAISDKTelemetry,
|
|
25988
28061
|
braintrustFlueObserver: () => braintrustFlueObserver,
|
|
25989
28062
|
braintrustStreamChunkSchema: () => braintrustStreamChunkSchema,
|
|
25990
28063
|
buildLocalSummary: () => buildLocalSummary,
|
|
@@ -26077,6 +28150,7 @@ __export(exports_exports, {
|
|
|
26077
28150
|
wrapOpenAIv4: () => wrapOpenAIv4,
|
|
26078
28151
|
wrapOpenRouter: () => wrapOpenRouter,
|
|
26079
28152
|
wrapOpenRouterAgent: () => wrapOpenRouterAgent,
|
|
28153
|
+
wrapPiCodingAgentSDK: () => wrapPiCodingAgentSDK,
|
|
26080
28154
|
wrapTraced: () => wrapTraced,
|
|
26081
28155
|
wrapVitest: () => wrapVitest
|
|
26082
28156
|
});
|
|
@@ -28137,6 +30211,54 @@ function wrapCursorAgent(agent) {
|
|
|
28137
30211
|
return proxy;
|
|
28138
30212
|
}
|
|
28139
30213
|
|
|
30214
|
+
// src/wrappers/pi-coding-agent.ts
|
|
30215
|
+
var WRAPPED_PROMPT = /* @__PURE__ */ Symbol.for("braintrust.pi-coding-agent.wrapped-prompt");
|
|
30216
|
+
function wrapPiCodingAgentSDK(sdk) {
|
|
30217
|
+
if (!sdk || typeof sdk !== "object") {
|
|
30218
|
+
return sdk;
|
|
30219
|
+
}
|
|
30220
|
+
const maybeSDK = sdk;
|
|
30221
|
+
if (!maybeSDK.AgentSession || typeof maybeSDK.AgentSession !== "function") {
|
|
30222
|
+
console.warn("Unsupported Pi Coding Agent SDK. Not wrapping.");
|
|
30223
|
+
return sdk;
|
|
30224
|
+
}
|
|
30225
|
+
patchAgentSessionClass(
|
|
30226
|
+
maybeSDK.AgentSession
|
|
30227
|
+
);
|
|
30228
|
+
return sdk;
|
|
30229
|
+
}
|
|
30230
|
+
function patchAgentSessionClass(AgentSession) {
|
|
30231
|
+
const prototype = AgentSession.prototype;
|
|
30232
|
+
if (!prototype || prototype[WRAPPED_PROMPT]) {
|
|
30233
|
+
return;
|
|
30234
|
+
}
|
|
30235
|
+
const descriptor = Object.getOwnPropertyDescriptor(prototype, "prompt");
|
|
30236
|
+
if (!descriptor || typeof descriptor.value !== "function") {
|
|
30237
|
+
console.warn("Unsupported Pi Coding Agent SDK. Not wrapping.");
|
|
30238
|
+
return;
|
|
30239
|
+
}
|
|
30240
|
+
const originalPrompt = descriptor.value;
|
|
30241
|
+
Object.defineProperty(prototype, "prompt", {
|
|
30242
|
+
...descriptor,
|
|
30243
|
+
value: function wrappedPiCodingAgentPrompt(text, options) {
|
|
30244
|
+
const args = [text, options];
|
|
30245
|
+
return piCodingAgentChannels.prompt.tracePromise(
|
|
30246
|
+
() => Reflect.apply(originalPrompt, this, args),
|
|
30247
|
+
{
|
|
30248
|
+
arguments: args,
|
|
30249
|
+
self: this,
|
|
30250
|
+
session: this
|
|
30251
|
+
}
|
|
30252
|
+
);
|
|
30253
|
+
}
|
|
30254
|
+
});
|
|
30255
|
+
Object.defineProperty(prototype, WRAPPED_PROMPT, {
|
|
30256
|
+
configurable: false,
|
|
30257
|
+
enumerable: false,
|
|
30258
|
+
value: true
|
|
30259
|
+
});
|
|
30260
|
+
}
|
|
30261
|
+
|
|
28140
30262
|
// src/wrappers/google-genai.ts
|
|
28141
30263
|
function wrapGoogleGenAI(googleGenAI) {
|
|
28142
30264
|
if (!googleGenAI || typeof googleGenAI !== "object") {
|
|
@@ -28173,12 +30295,25 @@ function wrapGoogleGenAIClass(OriginalGoogleGenAI) {
|
|
|
28173
30295
|
}
|
|
28174
30296
|
function wrapGoogleGenAIInstance(instance) {
|
|
28175
30297
|
const wrappedModels = wrapModels(instance.models);
|
|
30298
|
+
let originalInteractions;
|
|
30299
|
+
let wrappedInteractions;
|
|
28176
30300
|
patchGoogleGenAIChats(instance, wrappedModels);
|
|
28177
30301
|
return new Proxy(instance, {
|
|
28178
30302
|
get(target, prop, receiver) {
|
|
28179
30303
|
if (prop === "models") {
|
|
28180
30304
|
return wrappedModels;
|
|
28181
30305
|
}
|
|
30306
|
+
if (prop === "interactions") {
|
|
30307
|
+
const interactions = Reflect.get(target, prop, receiver);
|
|
30308
|
+
if (!isObject(interactions) || typeof interactions.create !== "function") {
|
|
30309
|
+
return interactions;
|
|
30310
|
+
}
|
|
30311
|
+
if (interactions !== originalInteractions) {
|
|
30312
|
+
originalInteractions = interactions;
|
|
30313
|
+
wrappedInteractions = wrapInteractions(interactions);
|
|
30314
|
+
}
|
|
30315
|
+
return wrappedInteractions;
|
|
30316
|
+
}
|
|
28182
30317
|
return Reflect.get(target, prop, receiver);
|
|
28183
30318
|
}
|
|
28184
30319
|
});
|
|
@@ -28205,6 +30340,16 @@ function wrapModels(models) {
|
|
|
28205
30340
|
}
|
|
28206
30341
|
});
|
|
28207
30342
|
}
|
|
30343
|
+
function wrapInteractions(interactions) {
|
|
30344
|
+
return new Proxy(interactions, {
|
|
30345
|
+
get(target, prop, receiver) {
|
|
30346
|
+
if (prop === "create") {
|
|
30347
|
+
return wrapInteractionCreate(target.create.bind(target));
|
|
30348
|
+
}
|
|
30349
|
+
return Reflect.get(target, prop, receiver);
|
|
30350
|
+
}
|
|
30351
|
+
});
|
|
30352
|
+
}
|
|
28208
30353
|
function wrapGenerateContent(original) {
|
|
28209
30354
|
return function(params) {
|
|
28210
30355
|
return googleGenAIChannels.generateContent.tracePromise(
|
|
@@ -28229,6 +30374,18 @@ function wrapEmbedContent(original) {
|
|
|
28229
30374
|
);
|
|
28230
30375
|
};
|
|
28231
30376
|
}
|
|
30377
|
+
function wrapInteractionCreate(original) {
|
|
30378
|
+
return function(params, options) {
|
|
30379
|
+
if (params.background === true) {
|
|
30380
|
+
return options === void 0 ? original(params) : original(params, options);
|
|
30381
|
+
}
|
|
30382
|
+
const traceContext = options === void 0 ? { arguments: [params] } : { arguments: [params, options] };
|
|
30383
|
+
return googleGenAIChannels.interactionsCreate.tracePromise(
|
|
30384
|
+
() => options === void 0 ? original(params) : original(params, options),
|
|
30385
|
+
traceContext
|
|
30386
|
+
);
|
|
30387
|
+
};
|
|
30388
|
+
}
|
|
28232
30389
|
|
|
28233
30390
|
// src/wrappers/google-adk.ts
|
|
28234
30391
|
function wrapGoogleADK(adkModule) {
|
|
@@ -31746,6 +33903,13 @@ var EvalResultWithSummary = class {
|
|
|
31746
33903
|
};
|
|
31747
33904
|
}
|
|
31748
33905
|
};
|
|
33906
|
+
async function getPersistedBaseExperimentId(experiment) {
|
|
33907
|
+
try {
|
|
33908
|
+
return await experiment._getBaseExperimentId();
|
|
33909
|
+
} catch {
|
|
33910
|
+
return void 0;
|
|
33911
|
+
}
|
|
33912
|
+
}
|
|
31749
33913
|
function makeEvalName(projectName, experimentName) {
|
|
31750
33914
|
let out = projectName;
|
|
31751
33915
|
if (experimentName) {
|
|
@@ -32128,6 +34292,14 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
|
|
|
32128
34292
|
return;
|
|
32129
34293
|
}
|
|
32130
34294
|
const eventDataset = experiment ? experiment.dataset : Dataset2.isDataset(evaluator.data) ? evaluator.data : void 0;
|
|
34295
|
+
const inlineOrigin = datum.origin === void 0 ? void 0 : ObjectReference.parse(datum.origin);
|
|
34296
|
+
const origin = inlineOrigin ?? (eventDataset && datum.id && datum._xact_id ? {
|
|
34297
|
+
object_type: "dataset",
|
|
34298
|
+
object_id: await eventDataset.id,
|
|
34299
|
+
id: datum.id,
|
|
34300
|
+
created: datum.created,
|
|
34301
|
+
_xact_id: datum._xact_id
|
|
34302
|
+
} : void 0);
|
|
32131
34303
|
const baseEvent = {
|
|
32132
34304
|
name: "eval",
|
|
32133
34305
|
spanAttributes: {
|
|
@@ -32137,13 +34309,7 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
|
|
|
32137
34309
|
input: datum.input,
|
|
32138
34310
|
expected: "expected" in datum ? datum.expected : void 0,
|
|
32139
34311
|
tags: datum.tags,
|
|
32140
|
-
origin
|
|
32141
|
-
object_type: "dataset",
|
|
32142
|
-
object_id: await eventDataset.id,
|
|
32143
|
-
id: datum.id,
|
|
32144
|
-
created: datum.created,
|
|
32145
|
-
_xact_id: datum._xact_id
|
|
32146
|
-
} : void 0,
|
|
34312
|
+
origin,
|
|
32147
34313
|
...datum.upsert_id ? { id: datum.upsert_id } : {}
|
|
32148
34314
|
}
|
|
32149
34315
|
};
|
|
@@ -32500,8 +34666,10 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
|
|
|
32500
34666
|
collectedResults.length = 0;
|
|
32501
34667
|
}
|
|
32502
34668
|
}
|
|
34669
|
+
const comparisonExperimentId = experiment ? evaluator.baseExperimentId ?? await getPersistedBaseExperimentId(experiment) : void 0;
|
|
32503
34670
|
const summary = experiment ? await experiment.summarize({
|
|
32504
|
-
summarizeScores: evaluator.summarizeScores
|
|
34671
|
+
summarizeScores: evaluator.summarizeScores,
|
|
34672
|
+
...comparisonExperimentId !== void 0 ? { comparisonExperimentId } : {}
|
|
32505
34673
|
}) : buildLocalSummary(
|
|
32506
34674
|
evaluator,
|
|
32507
34675
|
collectResults ? collectedResults : [],
|
|
@@ -32730,6 +34898,7 @@ var Project2 = class {
|
|
|
32730
34898
|
prompts;
|
|
32731
34899
|
parameters;
|
|
32732
34900
|
scorers;
|
|
34901
|
+
classifiers;
|
|
32733
34902
|
_publishableCodeFunctions = [];
|
|
32734
34903
|
_publishablePrompts = [];
|
|
32735
34904
|
_publishableParameters = [];
|
|
@@ -32741,6 +34910,7 @@ var Project2 = class {
|
|
|
32741
34910
|
this.prompts = new PromptBuilder(this);
|
|
32742
34911
|
this.parameters = new ParametersBuilder(this);
|
|
32743
34912
|
this.scorers = new ScorerBuilder(this);
|
|
34913
|
+
this.classifiers = new ClassifierBuilder(this);
|
|
32744
34914
|
}
|
|
32745
34915
|
addPrompt(prompt) {
|
|
32746
34916
|
this._publishablePrompts.push(prompt);
|
|
@@ -32875,6 +35045,28 @@ var ScorerBuilder = class {
|
|
|
32875
35045
|
}
|
|
32876
35046
|
}
|
|
32877
35047
|
};
|
|
35048
|
+
var ClassifierBuilder = class {
|
|
35049
|
+
constructor(project) {
|
|
35050
|
+
this.project = project;
|
|
35051
|
+
}
|
|
35052
|
+
taskCounter = 0;
|
|
35053
|
+
create(opts) {
|
|
35054
|
+
this.taskCounter++;
|
|
35055
|
+
let resolvedName = opts.name ?? opts.handler.name;
|
|
35056
|
+
if (!resolvedName || resolvedName.trim().length === 0) {
|
|
35057
|
+
resolvedName = `Classifier ${isomorph_default.basename(currentFilename)} ${this.taskCounter}`;
|
|
35058
|
+
}
|
|
35059
|
+
const slug = opts.slug ?? slugify(resolvedName, { lower: true, strict: true });
|
|
35060
|
+
const classifier = new CodeFunction(this.project, {
|
|
35061
|
+
...opts,
|
|
35062
|
+
name: resolvedName,
|
|
35063
|
+
slug,
|
|
35064
|
+
type: "classifier"
|
|
35065
|
+
});
|
|
35066
|
+
this.project.addCodeFunction(classifier);
|
|
35067
|
+
return classifier;
|
|
35068
|
+
}
|
|
35069
|
+
};
|
|
32878
35070
|
var CodeFunction = class {
|
|
32879
35071
|
constructor(project, opts) {
|
|
32880
35072
|
this.project = project;
|
|
@@ -33224,7 +35416,7 @@ var serializedParametersContainerSchema = import_v313.z.union([
|
|
|
33224
35416
|
staticParametersSchema
|
|
33225
35417
|
]);
|
|
33226
35418
|
var evaluatorDefinitionSchema = import_v313.z.object({
|
|
33227
|
-
parameters: serializedParametersContainerSchema.
|
|
35419
|
+
parameters: serializedParametersContainerSchema.nullish(),
|
|
33228
35420
|
scores: import_v313.z.array(import_v313.z.object({ name: import_v313.z.string() })).optional(),
|
|
33229
35421
|
classifiers: import_v313.z.array(import_v313.z.object({ name: import_v313.z.string() })).optional()
|
|
33230
35422
|
});
|