braintrust 3.26.0 → 3.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dev/dist/index.js +2440 -1067
- package/dev/dist/index.mjs +1644 -271
- package/dist/apply-auto-instrumentation.js +320 -261
- package/dist/apply-auto-instrumentation.mjs +118 -59
- package/dist/auto-instrumentations/bundler/esbuild.cjs +377 -59
- package/dist/auto-instrumentations/bundler/esbuild.mjs +5 -4
- package/dist/auto-instrumentations/bundler/next.cjs +379 -61
- package/dist/auto-instrumentations/bundler/next.mjs +6 -5
- package/dist/auto-instrumentations/bundler/rollup.cjs +377 -59
- package/dist/auto-instrumentations/bundler/rollup.mjs +5 -4
- package/dist/auto-instrumentations/bundler/vite.cjs +406 -60
- package/dist/auto-instrumentations/bundler/vite.mjs +34 -5
- package/dist/auto-instrumentations/bundler/webpack-loader.cjs +363 -59
- package/dist/auto-instrumentations/bundler/webpack.cjs +377 -59
- package/dist/auto-instrumentations/bundler/webpack.mjs +6 -5
- package/dist/auto-instrumentations/{chunk-AKKPLXTP.mjs → chunk-2AMDGD65.mjs} +160 -57
- package/dist/auto-instrumentations/{chunk-V5LEODRX.mjs → chunk-BW33ULMW.mjs} +1 -1
- package/dist/auto-instrumentations/{chunk-XYN63IG5.mjs → chunk-I55G56ZL.mjs} +21 -58
- package/dist/auto-instrumentations/{chunk-NRE4QUQR.mjs → chunk-JPUFNW7X.mjs} +140 -0
- package/dist/auto-instrumentations/{chunk-6E22MYSW.mjs → chunk-XEYKUBLY.mjs} +30 -4
- package/dist/auto-instrumentations/{chunk-XZHHE4Y3.mjs → chunk-ZNHTSSGI.mjs} +155 -2
- package/dist/auto-instrumentations/hook.mjs +161 -3
- package/dist/auto-instrumentations/index.cjs +296 -1
- package/dist/auto-instrumentations/index.d.mts +5 -1
- package/dist/auto-instrumentations/index.d.ts +5 -1
- package/dist/auto-instrumentations/index.mjs +6 -2
- package/dist/auto-instrumentations/loader/cjs-patch.cjs +105 -57
- package/dist/auto-instrumentations/loader/cjs-patch.mjs +2 -2
- package/dist/auto-instrumentations/loader/esm-hook.mjs +1 -1
- package/dist/browser.d.mts +57 -5
- package/dist/browser.d.ts +57 -5
- package/dist/browser.js +1855 -285
- package/dist/browser.mjs +1855 -285
- package/dist/{chunk-PN7EWK66.mjs → chunk-CZM5JIQL.mjs} +209 -1
- package/dist/{chunk-VYNNEKSA.js → chunk-MF7NU6BT.js} +216 -8
- package/dist/{chunk-VRZZQPAA.js → chunk-QRHGVBKU.js} +2403 -1220
- package/dist/{chunk-XIZOM2HO.mjs → chunk-YKD22IMR.mjs} +1454 -271
- package/dist/cli.js +1645 -272
- package/dist/edge-light.d.mts +1 -1
- package/dist/edge-light.d.ts +1 -1
- package/dist/edge-light.js +1855 -285
- package/dist/edge-light.mjs +1855 -285
- package/dist/index.d.mts +57 -5
- package/dist/index.d.ts +57 -5
- package/dist/index.js +600 -413
- package/dist/index.mjs +201 -14
- package/dist/instrumentation/index.d.mts +8 -0
- package/dist/instrumentation/index.d.ts +8 -0
- package/dist/instrumentation/index.js +1839 -466
- package/dist/instrumentation/index.mjs +1839 -466
- package/dist/vitest-evals-reporter.js +45 -43
- package/dist/vitest-evals-reporter.mjs +5 -3
- package/dist/workerd.d.mts +1 -1
- package/dist/workerd.d.ts +1 -1
- package/dist/workerd.js +1855 -285
- package/dist/workerd.mjs +1855 -285
- package/package.json +1 -1
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
claudeAgentSDKChannels,
|
|
8
8
|
cloudflareAIChatChannels,
|
|
9
9
|
cloudflareAgentsChannels,
|
|
10
|
+
cloudflareThinkChannels,
|
|
10
11
|
cohereChannels,
|
|
11
12
|
cursorSDKChannels,
|
|
12
13
|
detectSpanOriginEnvironment,
|
|
@@ -31,6 +32,7 @@ import {
|
|
|
31
32
|
langSmithChannels,
|
|
32
33
|
mergeSpanOriginContext,
|
|
33
34
|
mistralChannels,
|
|
35
|
+
ollamaChannels,
|
|
34
36
|
openAIAgentsCoreChannels,
|
|
35
37
|
openAIChannels,
|
|
36
38
|
openAICodexChannels,
|
|
@@ -44,7 +46,7 @@ import {
|
|
|
44
46
|
smithyCoreChannels,
|
|
45
47
|
strandsAgentSDKChannels,
|
|
46
48
|
withSpanInstrumentationName
|
|
47
|
-
} from "./chunk-
|
|
49
|
+
} from "./chunk-CZM5JIQL.mjs";
|
|
48
50
|
|
|
49
51
|
// src/id-gen.ts
|
|
50
52
|
import { v4 as uuidv4 } from "uuid";
|
|
@@ -10883,6 +10885,25 @@ function getCachedMetricFromHeaders(headers) {
|
|
|
10883
10885
|
return parseCachedHeader(headers.get(LEGACY_CACHED_HEADER));
|
|
10884
10886
|
}
|
|
10885
10887
|
|
|
10888
|
+
// src/wrappers/anthropic-session-collector.ts
|
|
10889
|
+
var sessionStreamCollectors = /* @__PURE__ */ new WeakMap();
|
|
10890
|
+
function registerAnthropicSessionStreamCollector(stream, collector) {
|
|
10891
|
+
sessionStreamCollectors.set(stream, collector);
|
|
10892
|
+
}
|
|
10893
|
+
function collectAnthropicSession(stream) {
|
|
10894
|
+
const collector = sessionStreamCollectors.get(stream);
|
|
10895
|
+
if (!collector) {
|
|
10896
|
+
return stream;
|
|
10897
|
+
}
|
|
10898
|
+
sessionStreamCollectors.delete(stream);
|
|
10899
|
+
try {
|
|
10900
|
+
collector();
|
|
10901
|
+
} catch (error) {
|
|
10902
|
+
debugLogger.error("Failed to collect Anthropic Sessions stream:", error);
|
|
10903
|
+
}
|
|
10904
|
+
return stream;
|
|
10905
|
+
}
|
|
10906
|
+
|
|
10886
10907
|
// src/instrumentation/core/stream-patcher.ts
|
|
10887
10908
|
function isAsyncIterable(value) {
|
|
10888
10909
|
return value !== null && typeof value === "object" && Symbol.asyncIterator in value && typeof value[Symbol.asyncIterator] === "function";
|
|
@@ -10907,6 +10928,34 @@ function patchStreamIfNeeded(stream, options) {
|
|
|
10907
10928
|
);
|
|
10908
10929
|
return stream;
|
|
10909
10930
|
}
|
|
10931
|
+
const chunks = [];
|
|
10932
|
+
let completed = false;
|
|
10933
|
+
const notifyCancellation = async () => {
|
|
10934
|
+
try {
|
|
10935
|
+
await (options.onCancel ?? options.onComplete)(chunks);
|
|
10936
|
+
} catch (error) {
|
|
10937
|
+
debugLogger.error("Error in stream cancellation handler:", error);
|
|
10938
|
+
}
|
|
10939
|
+
};
|
|
10940
|
+
const patchAbortIfPresent = () => {
|
|
10941
|
+
try {
|
|
10942
|
+
if ("abort" in stream && typeof stream.abort === "function") {
|
|
10943
|
+
const originalAbort = stream.abort.bind(stream);
|
|
10944
|
+
stream.abort = (...args) => {
|
|
10945
|
+
try {
|
|
10946
|
+
return originalAbort(...args);
|
|
10947
|
+
} finally {
|
|
10948
|
+
if (!completed) {
|
|
10949
|
+
completed = true;
|
|
10950
|
+
void notifyCancellation();
|
|
10951
|
+
}
|
|
10952
|
+
}
|
|
10953
|
+
};
|
|
10954
|
+
}
|
|
10955
|
+
} catch (error) {
|
|
10956
|
+
debugLogger.warn("Failed to patch stream abort method:", error);
|
|
10957
|
+
}
|
|
10958
|
+
};
|
|
10910
10959
|
if (hasAsyncIteratorMethods(stream) && isSelfAsyncIterator(stream)) {
|
|
10911
10960
|
if ("__braintrust_patched_iterator_methods" in stream) {
|
|
10912
10961
|
return stream;
|
|
@@ -10915,8 +10964,6 @@ function patchStreamIfNeeded(stream, options) {
|
|
|
10915
10964
|
const originalNext = stream.next.bind(stream);
|
|
10916
10965
|
const originalReturn = typeof stream.return === "function" ? stream.return.bind(stream) : null;
|
|
10917
10966
|
const originalThrow = typeof stream.throw === "function" ? stream.throw.bind(stream) : null;
|
|
10918
|
-
const chunks = [];
|
|
10919
|
-
let completed = false;
|
|
10920
10967
|
stream.next = async (...args) => {
|
|
10921
10968
|
try {
|
|
10922
10969
|
const result = await runNextWithWrapper(
|
|
@@ -10968,11 +11015,7 @@ function patchStreamIfNeeded(stream, options) {
|
|
|
10968
11015
|
stream.return = async (...args) => {
|
|
10969
11016
|
if (!completed) {
|
|
10970
11017
|
completed = true;
|
|
10971
|
-
|
|
10972
|
-
await options.onComplete(chunks);
|
|
10973
|
-
} catch (error) {
|
|
10974
|
-
console.error("Error in stream onComplete handler:", error);
|
|
10975
|
-
}
|
|
11018
|
+
await notifyCancellation();
|
|
10976
11019
|
}
|
|
10977
11020
|
return originalReturn(...args);
|
|
10978
11021
|
};
|
|
@@ -10997,6 +11040,7 @@ function patchStreamIfNeeded(stream, options) {
|
|
|
10997
11040
|
Object.defineProperty(stream, "__braintrust_patched_iterator_methods", {
|
|
10998
11041
|
value: true
|
|
10999
11042
|
});
|
|
11043
|
+
patchAbortIfPresent();
|
|
11000
11044
|
return stream;
|
|
11001
11045
|
} catch (error) {
|
|
11002
11046
|
console.warn("Failed to patch stream iterator methods:", error);
|
|
@@ -11010,8 +11054,6 @@ function patchStreamIfNeeded(stream, options) {
|
|
|
11010
11054
|
const patchedIteratorFn = function() {
|
|
11011
11055
|
const iterator = originalIteratorFn.call(this);
|
|
11012
11056
|
const originalNext = iterator.next.bind(iterator);
|
|
11013
|
-
const chunks = [];
|
|
11014
|
-
let completed = false;
|
|
11015
11057
|
iterator.next = async function(...args) {
|
|
11016
11058
|
try {
|
|
11017
11059
|
const result = await runNextWithWrapper(
|
|
@@ -11064,11 +11106,7 @@ function patchStreamIfNeeded(stream, options) {
|
|
|
11064
11106
|
iterator.return = async function(...args) {
|
|
11065
11107
|
if (!completed) {
|
|
11066
11108
|
completed = true;
|
|
11067
|
-
|
|
11068
|
-
await options.onComplete(chunks);
|
|
11069
|
-
} catch (error) {
|
|
11070
|
-
console.error("Error in stream onComplete handler:", error);
|
|
11071
|
-
}
|
|
11109
|
+
await notifyCancellation();
|
|
11072
11110
|
}
|
|
11073
11111
|
return originalReturn(...args);
|
|
11074
11112
|
};
|
|
@@ -11097,6 +11135,7 @@ function patchStreamIfNeeded(stream, options) {
|
|
|
11097
11135
|
value: true
|
|
11098
11136
|
});
|
|
11099
11137
|
stream[Symbol.asyncIterator] = patchedIteratorFn;
|
|
11138
|
+
patchAbortIfPresent();
|
|
11100
11139
|
return stream;
|
|
11101
11140
|
} catch (error) {
|
|
11102
11141
|
console.warn("Failed to patch stream:", error);
|
|
@@ -11845,6 +11884,33 @@ function traceStreamingChannel(channel, config) {
|
|
|
11845
11884
|
const { span, startTime } = spanData;
|
|
11846
11885
|
if (isAsyncIterable(asyncEndEvent.result)) {
|
|
11847
11886
|
let firstChunkTime;
|
|
11887
|
+
const handleStreamError = (error) => {
|
|
11888
|
+
try {
|
|
11889
|
+
span.log({ error });
|
|
11890
|
+
} catch (loggingError) {
|
|
11891
|
+
debugLogger.error(
|
|
11892
|
+
`Error logging failure for ${channelName}:`,
|
|
11893
|
+
loggingError
|
|
11894
|
+
);
|
|
11895
|
+
}
|
|
11896
|
+
try {
|
|
11897
|
+
span.end();
|
|
11898
|
+
} catch (endingError) {
|
|
11899
|
+
debugLogger.error(
|
|
11900
|
+
`Error ending span for ${channelName}:`,
|
|
11901
|
+
endingError
|
|
11902
|
+
);
|
|
11903
|
+
}
|
|
11904
|
+
states.delete(event);
|
|
11905
|
+
runStreamingErrorHook({
|
|
11906
|
+
channelName,
|
|
11907
|
+
config,
|
|
11908
|
+
error,
|
|
11909
|
+
event: asyncEndEvent,
|
|
11910
|
+
span,
|
|
11911
|
+
startTime
|
|
11912
|
+
});
|
|
11913
|
+
};
|
|
11848
11914
|
patchStreamIfNeeded(asyncEndEvent.result, {
|
|
11849
11915
|
onChunk: () => {
|
|
11850
11916
|
if (firstChunkTime === void 0) {
|
|
@@ -11924,33 +11990,12 @@ function traceStreamingChannel(channel, config) {
|
|
|
11924
11990
|
});
|
|
11925
11991
|
}
|
|
11926
11992
|
},
|
|
11927
|
-
|
|
11928
|
-
|
|
11929
|
-
|
|
11930
|
-
|
|
11931
|
-
|
|
11932
|
-
|
|
11933
|
-
loggingError
|
|
11934
|
-
);
|
|
11935
|
-
}
|
|
11936
|
-
try {
|
|
11937
|
-
span.end();
|
|
11938
|
-
} catch (endingError) {
|
|
11939
|
-
debugLogger.error(
|
|
11940
|
-
`Error ending span for ${channelName}:`,
|
|
11941
|
-
endingError
|
|
11942
|
-
);
|
|
11943
|
-
}
|
|
11944
|
-
states.delete(event);
|
|
11945
|
-
runStreamingErrorHook({
|
|
11946
|
-
channelName,
|
|
11947
|
-
config,
|
|
11948
|
-
error,
|
|
11949
|
-
event: asyncEndEvent,
|
|
11950
|
-
span,
|
|
11951
|
-
startTime
|
|
11952
|
-
});
|
|
11953
|
-
}
|
|
11993
|
+
onCancel: () => {
|
|
11994
|
+
const error = new Error("Stream cancelled before completion");
|
|
11995
|
+
error.name = "AbortError";
|
|
11996
|
+
handleStreamError(error);
|
|
11997
|
+
},
|
|
11998
|
+
onError: handleStreamError
|
|
11954
11999
|
});
|
|
11955
12000
|
return;
|
|
11956
12001
|
}
|
|
@@ -12710,6 +12755,29 @@ function currentWorkflowAgentWrapperSpan() {
|
|
|
12710
12755
|
return void 0;
|
|
12711
12756
|
}
|
|
12712
12757
|
|
|
12758
|
+
// src/instrumentation/plugins/cloudflare-think-context.ts
|
|
12759
|
+
var cloudflareThinkSpans = /* @__PURE__ */ new Map();
|
|
12760
|
+
function registerCloudflareThinkSpan(span) {
|
|
12761
|
+
if (span.spanId) {
|
|
12762
|
+
cloudflareThinkSpans.set(span.spanId, span);
|
|
12763
|
+
}
|
|
12764
|
+
}
|
|
12765
|
+
function unregisterCloudflareThinkSpan(span) {
|
|
12766
|
+
if (span.spanId) {
|
|
12767
|
+
cloudflareThinkSpans.delete(span.spanId);
|
|
12768
|
+
}
|
|
12769
|
+
}
|
|
12770
|
+
function currentCloudflareThinkSpan() {
|
|
12771
|
+
const parentSpanIds = _internalGetGlobalState()?.contextManager.getParentSpanIds()?.spanParents ?? [];
|
|
12772
|
+
for (const parentSpanId of parentSpanIds) {
|
|
12773
|
+
const span = cloudflareThinkSpans.get(parentSpanId);
|
|
12774
|
+
if (span) {
|
|
12775
|
+
return span;
|
|
12776
|
+
}
|
|
12777
|
+
}
|
|
12778
|
+
return void 0;
|
|
12779
|
+
}
|
|
12780
|
+
|
|
12713
12781
|
// src/vendor-sdk-types/ai-sdk-v7-telemetry.ts
|
|
12714
12782
|
var BRAINTRUST_AI_SDK_V7_OPERATION_KEY = /* @__PURE__ */ Symbol.for(
|
|
12715
12783
|
"braintrust.ai-sdk.v7.telemetry-operation-key"
|
|
@@ -12821,6 +12889,7 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
12821
12889
|
traceStreamingChannel(aiSDKChannels.streamText, {
|
|
12822
12890
|
name: "streamText",
|
|
12823
12891
|
type: "function" /* FUNCTION */,
|
|
12892
|
+
shouldTrace: () => currentCloudflareThinkSpan() === void 0,
|
|
12824
12893
|
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
|
|
12825
12894
|
extractOutput: (result, endEvent) => processAISDKOutput(
|
|
12826
12895
|
result,
|
|
@@ -12841,6 +12910,7 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
12841
12910
|
traceSyncStreamChannel(aiSDKChannels.streamTextSync, {
|
|
12842
12911
|
name: "streamText",
|
|
12843
12912
|
type: "function" /* FUNCTION */,
|
|
12913
|
+
shouldTrace: () => currentCloudflareThinkSpan() === void 0,
|
|
12844
12914
|
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
|
|
12845
12915
|
patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
|
|
12846
12916
|
defaultDenyOutputPaths: denyOutputPaths,
|
|
@@ -13826,6 +13896,23 @@ function prepareAISDKWorkflowAgentStreamInput(params, event, span, defaultDenyOu
|
|
|
13826
13896
|
metadata
|
|
13827
13897
|
};
|
|
13828
13898
|
}
|
|
13899
|
+
function prepareAISDKAgentCallInput(params, event, span, defaultDenyOutputPaths = DEFAULT_DENY_OUTPUT_PATHS) {
|
|
13900
|
+
const { input } = processAISDKWorkflowAgentCallInput(params);
|
|
13901
|
+
const metadata = extractMetadataFromCallParams(params, event.self);
|
|
13902
|
+
const childTracing = prepareAISDKChildTracing(
|
|
13903
|
+
params,
|
|
13904
|
+
event.self,
|
|
13905
|
+
span,
|
|
13906
|
+
defaultDenyOutputPaths,
|
|
13907
|
+
event.aiSDK,
|
|
13908
|
+
{ agentOwner: true }
|
|
13909
|
+
);
|
|
13910
|
+
event.modelWrapped = childTracing.modelWrapped;
|
|
13911
|
+
if (childTracing.cleanup) {
|
|
13912
|
+
event.__braintrust_ai_sdk_cleanup = childTracing.cleanup;
|
|
13913
|
+
}
|
|
13914
|
+
return { input, metadata };
|
|
13915
|
+
}
|
|
13829
13916
|
function prepareAISDKEmbedInput(params, self) {
|
|
13830
13917
|
return {
|
|
13831
13918
|
input: { ...params },
|
|
@@ -13849,6 +13936,18 @@ function extractTopLevelAISDKMetrics(result, event, startTime) {
|
|
|
13849
13936
|
}
|
|
13850
13937
|
return metrics;
|
|
13851
13938
|
}
|
|
13939
|
+
async function extractResolvedAISDKTokenMetrics(result) {
|
|
13940
|
+
for (const field of ["totalUsage", "usage"]) {
|
|
13941
|
+
try {
|
|
13942
|
+
const usage = await Promise.resolve(result[field]);
|
|
13943
|
+
if (usage !== void 0) {
|
|
13944
|
+
return extractTokenMetrics({ [field]: usage });
|
|
13945
|
+
}
|
|
13946
|
+
} catch {
|
|
13947
|
+
}
|
|
13948
|
+
}
|
|
13949
|
+
return extractTokenMetrics(result);
|
|
13950
|
+
}
|
|
13852
13951
|
function hasModelChildTracing(event) {
|
|
13853
13952
|
return event?.modelWrapped === true || event?.__braintrust_ai_sdk_model_wrapped === true;
|
|
13854
13953
|
}
|
|
@@ -14666,13 +14765,15 @@ function patchAISDKStreamingResult(args) {
|
|
|
14666
14765
|
const {
|
|
14667
14766
|
defaultDenyOutputPaths,
|
|
14668
14767
|
endEvent,
|
|
14768
|
+
forceTopLevelMetrics,
|
|
14669
14769
|
onComplete,
|
|
14670
14770
|
onCancel,
|
|
14671
14771
|
onError,
|
|
14672
14772
|
result,
|
|
14673
14773
|
resolvePromiseUsage,
|
|
14674
14774
|
span,
|
|
14675
|
-
startTime
|
|
14775
|
+
startTime,
|
|
14776
|
+
transformOutput
|
|
14676
14777
|
} = args;
|
|
14677
14778
|
if (!result || typeof result !== "object") {
|
|
14678
14779
|
return false;
|
|
@@ -14725,8 +14826,8 @@ function patchAISDKStreamingResult(args) {
|
|
|
14725
14826
|
}
|
|
14726
14827
|
outputLogged = true;
|
|
14727
14828
|
try {
|
|
14728
|
-
const metrics = extractTopLevelAISDKMetrics(result, endEvent);
|
|
14729
|
-
if (resolvePromiseUsage) {
|
|
14829
|
+
const metrics = forceTopLevelMetrics ? await extractResolvedAISDKTokenMetrics(result) : extractTopLevelAISDKMetrics(result, endEvent);
|
|
14830
|
+
if (resolvePromiseUsage && !forceTopLevelMetrics) {
|
|
14730
14831
|
try {
|
|
14731
14832
|
const resultRecord2 = result;
|
|
14732
14833
|
const pendingUsage = resultRecord2.totalUsage ?? resultRecord2.usage;
|
|
@@ -14745,10 +14846,11 @@ function patchAISDKStreamingResult(args) {
|
|
|
14745
14846
|
if (metrics.time_to_first_token === void 0 && firstChunkTime !== void 0) {
|
|
14746
14847
|
metrics.time_to_first_token = firstChunkTime - startTime;
|
|
14747
14848
|
}
|
|
14748
|
-
const
|
|
14849
|
+
const processedOutput = await processAISDKStreamingOutput(
|
|
14749
14850
|
result,
|
|
14750
14851
|
resolveDenyOutputPaths(endEvent, defaultDenyOutputPaths)
|
|
14751
14852
|
);
|
|
14853
|
+
const output = transformOutput ? transformOutput(processedOutput) : processedOutput;
|
|
14752
14854
|
const metadata = buildResolvedMetadataPayload(result).metadata;
|
|
14753
14855
|
try {
|
|
14754
14856
|
span.log({
|
|
@@ -16915,7 +17017,7 @@ var FlueObserveBridge = class {
|
|
|
16915
17017
|
return;
|
|
16916
17018
|
}
|
|
16917
17019
|
const state = this.operationsById.get(event.operationId) ?? this.startSyntheticOperation(event);
|
|
16918
|
-
const output = operationOutput(event);
|
|
17020
|
+
const output = operationOutput(event) ?? outputFromAgentTurn(state.latestAgentOutput);
|
|
16919
17021
|
const metadata = {
|
|
16920
17022
|
...state.metadata,
|
|
16921
17023
|
...extractEventMetadata(event),
|
|
@@ -16924,7 +17026,7 @@ var FlueObserveBridge = class {
|
|
|
16924
17026
|
};
|
|
16925
17027
|
this.finishPendingChildrenForOperation(event, output);
|
|
16926
17028
|
safeLog(state.span, {
|
|
16927
|
-
...event.isError ? { error: toLoggedError(event.error) } : {},
|
|
17029
|
+
...event.isError ? { error: toLoggedError(event.errorInfo ?? event.error) } : {},
|
|
16928
17030
|
metadata,
|
|
16929
17031
|
metrics: durationMetrics(event.durationMs),
|
|
16930
17032
|
output
|
|
@@ -16955,7 +17057,7 @@ var FlueObserveBridge = class {
|
|
|
16955
17057
|
};
|
|
16956
17058
|
const parent = this.parentSpanForTurn(event);
|
|
16957
17059
|
const span = startFlueSpan(parent, {
|
|
16958
|
-
name:
|
|
17060
|
+
name: "flue.turn",
|
|
16959
17061
|
spanAttributes: { type: "llm" /* LLM */ },
|
|
16960
17062
|
startTime: eventTime(event.timestamp),
|
|
16961
17063
|
event: {
|
|
@@ -16999,6 +17101,12 @@ var FlueObserveBridge = class {
|
|
|
16999
17101
|
},
|
|
17000
17102
|
output
|
|
17001
17103
|
});
|
|
17104
|
+
if (event.purpose === "agent" && event.operationId) {
|
|
17105
|
+
const operation = this.operationsById.get(event.operationId);
|
|
17106
|
+
if (operation) {
|
|
17107
|
+
operation.latestAgentOutput = output;
|
|
17108
|
+
}
|
|
17109
|
+
}
|
|
17002
17110
|
safeEnd(state.span, eventTime(event.timestamp));
|
|
17003
17111
|
this.turnsByKey.delete(key);
|
|
17004
17112
|
}
|
|
@@ -17078,7 +17186,7 @@ var FlueObserveBridge = class {
|
|
|
17078
17186
|
return;
|
|
17079
17187
|
}
|
|
17080
17188
|
safeLog(state.span, {
|
|
17081
|
-
...event.isError ? { error: toLoggedError(event.result) } : {},
|
|
17189
|
+
...event.isError ? { error: toLoggedError(event.errorInfo ?? event.result) } : {},
|
|
17082
17190
|
metadata: {
|
|
17083
17191
|
...state.metadata,
|
|
17084
17192
|
...extractEventMetadata(event),
|
|
@@ -17124,6 +17232,7 @@ var FlueObserveBridge = class {
|
|
|
17124
17232
|
...event.usage ? { "flue.usage": event.usage } : {}
|
|
17125
17233
|
};
|
|
17126
17234
|
safeLog(state.span, {
|
|
17235
|
+
...event.isError ? { error: toLoggedError(event.errorInfo ?? event.error) } : {},
|
|
17127
17236
|
metadata,
|
|
17128
17237
|
metrics: {
|
|
17129
17238
|
...durationMetrics(event.durationMs),
|
|
@@ -17228,7 +17337,7 @@ var FlueObserveBridge = class {
|
|
|
17228
17337
|
...event.purpose ? { "flue.turn_purpose": event.purpose } : {}
|
|
17229
17338
|
};
|
|
17230
17339
|
const span = startFlueSpan(this.parentSpanForEvent(event), {
|
|
17231
|
-
name:
|
|
17340
|
+
name: "flue.turn",
|
|
17232
17341
|
spanAttributes: { type: "llm" /* LLM */ },
|
|
17233
17342
|
startTime: eventTime(event.timestamp),
|
|
17234
17343
|
event: { metadata }
|
|
@@ -17360,7 +17469,10 @@ function extractEventMetadata(event, ctx) {
|
|
|
17360
17469
|
return {
|
|
17361
17470
|
...event.runId ? { "flue.run_id": event.runId } : {},
|
|
17362
17471
|
...event.instanceId ? { "flue.instance_id": event.instanceId } : {},
|
|
17472
|
+
...event.submissionId ? { "flue.submission_id": event.submissionId } : {},
|
|
17363
17473
|
...event.dispatchId ? { "flue.dispatch_id": event.dispatchId } : {},
|
|
17474
|
+
...event.agentName ? { "flue.agent_name": event.agentName } : {},
|
|
17475
|
+
...event.conversationId ? { "flue.conversation_id": event.conversationId } : {},
|
|
17364
17476
|
...typeof event.eventIndex === "number" ? { "flue.event_index": event.eventIndex } : {},
|
|
17365
17477
|
...event.session ? { "flue.session": event.session } : {},
|
|
17366
17478
|
...event.parentSession ? { "flue.parent_session": event.parentSession } : {},
|
|
@@ -17389,7 +17501,7 @@ function flueTurnRequestInput(event) {
|
|
|
17389
17501
|
return event.request?.input ?? event.input;
|
|
17390
17502
|
}
|
|
17391
17503
|
function flueTurnRequestModel(event) {
|
|
17392
|
-
return event.request?.model ?? event.model;
|
|
17504
|
+
return event.request?.requestedModel ?? event.request?.model ?? event.model;
|
|
17393
17505
|
}
|
|
17394
17506
|
function flueTurnRequestProvider(event) {
|
|
17395
17507
|
return event.request?.providerName ?? event.provider ?? event.request?.providerId;
|
|
@@ -17398,10 +17510,10 @@ function flueTurnRequestApi(event) {
|
|
|
17398
17510
|
return event.request?.api ?? event.api;
|
|
17399
17511
|
}
|
|
17400
17512
|
function flueTurnRequestReasoning(event) {
|
|
17401
|
-
return event.request?.reasoning ?? event.reasoning;
|
|
17513
|
+
return event.request?.reasoningLevel ?? event.request?.reasoning ?? event.reasoning;
|
|
17402
17514
|
}
|
|
17403
17515
|
function flueTurnModel(event) {
|
|
17404
|
-
return event.request?.model ?? event.model;
|
|
17516
|
+
return event.response?.responseModel ?? event.request?.requestedModel ?? event.request?.model ?? event.model;
|
|
17405
17517
|
}
|
|
17406
17518
|
function flueTurnProvider(event) {
|
|
17407
17519
|
return event.request?.providerName ?? event.provider ?? event.request?.providerId;
|
|
@@ -17416,7 +17528,7 @@ function flueTurnOutput(event) {
|
|
|
17416
17528
|
return event.response?.output ?? event.output;
|
|
17417
17529
|
}
|
|
17418
17530
|
function flueTurnStopReason(event) {
|
|
17419
|
-
return event.response?.stopReason ?? event.stopReason;
|
|
17531
|
+
return event.response?.finishReason ?? event.response?.stopReason ?? event.stopReason;
|
|
17420
17532
|
}
|
|
17421
17533
|
function flueTurnError(event) {
|
|
17422
17534
|
return event.response?.error ?? event.response?.errorInfo?.message ?? event.error;
|
|
@@ -17431,6 +17543,9 @@ function flueToolInput(event) {
|
|
|
17431
17543
|
return event.input;
|
|
17432
17544
|
}
|
|
17433
17545
|
function flueToolOutput(event) {
|
|
17546
|
+
if (Object.hasOwn(event, "effectiveResult")) {
|
|
17547
|
+
return event.effectiveResult;
|
|
17548
|
+
}
|
|
17434
17549
|
return event.output !== void 0 ? event.output : event.result;
|
|
17435
17550
|
}
|
|
17436
17551
|
function flueToolError(event) {
|
|
@@ -17438,10 +17553,36 @@ function flueToolError(event) {
|
|
|
17438
17553
|
}
|
|
17439
17554
|
function operationOutput(event) {
|
|
17440
17555
|
if (event.operationKind === "prompt" || event.operationKind === "skill") {
|
|
17441
|
-
return llmResultFromOperationResult(event.result);
|
|
17556
|
+
return outputFromAgentInvocation(event.agentOutput) ?? llmResultFromOperationResult(event.result);
|
|
17442
17557
|
}
|
|
17443
17558
|
return event.result ?? (event.operationKind === "compact" ? { completed: true } : void 0);
|
|
17444
17559
|
}
|
|
17560
|
+
function outputFromAgentInvocation(output) {
|
|
17561
|
+
if (output?.type === "text") {
|
|
17562
|
+
return output.text;
|
|
17563
|
+
}
|
|
17564
|
+
if (output?.type === "data") {
|
|
17565
|
+
return output.data;
|
|
17566
|
+
}
|
|
17567
|
+
return void 0;
|
|
17568
|
+
}
|
|
17569
|
+
function outputFromAgentTurn(output) {
|
|
17570
|
+
if (!isObjectLike(output)) {
|
|
17571
|
+
return output;
|
|
17572
|
+
}
|
|
17573
|
+
const content = Reflect.get(output, "content");
|
|
17574
|
+
if (!Array.isArray(content)) {
|
|
17575
|
+
return output;
|
|
17576
|
+
}
|
|
17577
|
+
const text = content.flatMap((part) => {
|
|
17578
|
+
if (!isObjectLike(part) || Reflect.get(part, "type") !== "text") {
|
|
17579
|
+
return [];
|
|
17580
|
+
}
|
|
17581
|
+
const value = Reflect.get(part, "text");
|
|
17582
|
+
return typeof value === "string" ? [value] : [];
|
|
17583
|
+
});
|
|
17584
|
+
return text.length > 0 ? text.join("") : output;
|
|
17585
|
+
}
|
|
17445
17586
|
function llmResultFromOperationResult(result) {
|
|
17446
17587
|
if (!isObjectLike(result)) {
|
|
17447
17588
|
return result;
|
|
@@ -17540,7 +17681,7 @@ function safeEnd(span, endTime) {
|
|
|
17540
17681
|
}
|
|
17541
17682
|
}
|
|
17542
17683
|
function logInstrumentationError(label, error) {
|
|
17543
|
-
|
|
17684
|
+
debugLogger.debug(`Error in ${label} instrumentation:`, error);
|
|
17544
17685
|
}
|
|
17545
17686
|
|
|
17546
17687
|
// src/wrappers/langchain/callback-handler.ts
|
|
@@ -19037,6 +19178,7 @@ var AnthropicPlugin = class extends BasePlugin {
|
|
|
19037
19178
|
onEnable() {
|
|
19038
19179
|
this.subscribeToAnthropicChannels();
|
|
19039
19180
|
this.subscribeToAnthropicToolRunner();
|
|
19181
|
+
this.subscribeToAnthropicSessionStreams();
|
|
19040
19182
|
}
|
|
19041
19183
|
onDisable() {
|
|
19042
19184
|
this.unsubscribers = unsubscribeAll(this.unsubscribers);
|
|
@@ -19154,7 +19296,411 @@ var AnthropicPlugin = class extends BasePlugin {
|
|
|
19154
19296
|
tracingChannel.unsubscribe(handlers);
|
|
19155
19297
|
});
|
|
19156
19298
|
}
|
|
19299
|
+
subscribeToAnthropicSessionStreams() {
|
|
19300
|
+
this.subscribeToAnthropicSessionStream(
|
|
19301
|
+
anthropicChannels.betaSessionsEventsStream,
|
|
19302
|
+
false
|
|
19303
|
+
);
|
|
19304
|
+
this.subscribeToAnthropicSessionStream(
|
|
19305
|
+
anthropicChannels.betaSessionsThreadsEventsStream,
|
|
19306
|
+
true
|
|
19307
|
+
);
|
|
19308
|
+
}
|
|
19309
|
+
subscribeToAnthropicSessionStream(channel, isThread) {
|
|
19310
|
+
const tracingChannel = channel.tracingChannel();
|
|
19311
|
+
const pending = /* @__PURE__ */ new WeakSet();
|
|
19312
|
+
const handlers = {
|
|
19313
|
+
start: (event) => {
|
|
19314
|
+
if (isAutoInstrumentationSuppressed()) {
|
|
19315
|
+
return;
|
|
19316
|
+
}
|
|
19317
|
+
pending.add(event);
|
|
19318
|
+
},
|
|
19319
|
+
asyncEnd: (event) => {
|
|
19320
|
+
if (!pending.delete(event)) {
|
|
19321
|
+
return;
|
|
19322
|
+
}
|
|
19323
|
+
const stream = event.result;
|
|
19324
|
+
if (!isAsyncIterable(stream)) {
|
|
19325
|
+
return;
|
|
19326
|
+
}
|
|
19327
|
+
registerAnthropicSessionStreamCollector(stream, () => {
|
|
19328
|
+
wrapAnthropicSessionEventStream(stream, isThread);
|
|
19329
|
+
});
|
|
19330
|
+
},
|
|
19331
|
+
error: (event) => {
|
|
19332
|
+
pending.delete(event);
|
|
19333
|
+
}
|
|
19334
|
+
};
|
|
19335
|
+
tracingChannel.subscribe(handlers);
|
|
19336
|
+
this.unsubscribers.push(() => tracingChannel.unsubscribe(handlers));
|
|
19337
|
+
}
|
|
19157
19338
|
};
|
|
19339
|
+
function wrapAnthropicSessionEventStream(stream, isThread) {
|
|
19340
|
+
const state = {
|
|
19341
|
+
history: [],
|
|
19342
|
+
isThread,
|
|
19343
|
+
pendingInput: [],
|
|
19344
|
+
seenEventIds: /* @__PURE__ */ new Set()
|
|
19345
|
+
};
|
|
19346
|
+
patchStreamIfNeeded(stream, {
|
|
19347
|
+
onChunk: (event) => handleAnthropicSessionEvent(state, event),
|
|
19348
|
+
onComplete: () => finalizeAnthropicSessionTurn(state),
|
|
19349
|
+
onError: (error) => finalizeAnthropicSessionTurn(state, error)
|
|
19350
|
+
});
|
|
19351
|
+
return stream;
|
|
19352
|
+
}
|
|
19353
|
+
function handleAnthropicSessionEvent(state, event) {
|
|
19354
|
+
try {
|
|
19355
|
+
if (typeof event.id === "string" && event.type !== "event_delta" && state.seenEventIds.has(event.id)) {
|
|
19356
|
+
return;
|
|
19357
|
+
}
|
|
19358
|
+
if (typeof event.id === "string" && event.type !== "event_delta") {
|
|
19359
|
+
state.seenEventIds.add(event.id);
|
|
19360
|
+
}
|
|
19361
|
+
switch (event.type) {
|
|
19362
|
+
case "user.message":
|
|
19363
|
+
case "system.message":
|
|
19364
|
+
recordAnthropicSessionInput(
|
|
19365
|
+
state,
|
|
19366
|
+
event
|
|
19367
|
+
);
|
|
19368
|
+
break;
|
|
19369
|
+
case "session.status_running":
|
|
19370
|
+
if (!state.isThread) {
|
|
19371
|
+
ensureAnthropicSessionTurn(state);
|
|
19372
|
+
}
|
|
19373
|
+
break;
|
|
19374
|
+
case "session.thread_status_running":
|
|
19375
|
+
if (state.isThread) {
|
|
19376
|
+
ensureAnthropicSessionTurn(state);
|
|
19377
|
+
}
|
|
19378
|
+
break;
|
|
19379
|
+
case "span.model_request_start":
|
|
19380
|
+
if (typeof event.id === "string") {
|
|
19381
|
+
startAnthropicSessionModel(state, event.id);
|
|
19382
|
+
}
|
|
19383
|
+
break;
|
|
19384
|
+
case "event_delta":
|
|
19385
|
+
recordAnthropicSessionFirstToken(state, event);
|
|
19386
|
+
break;
|
|
19387
|
+
case "agent.message":
|
|
19388
|
+
recordAnthropicSessionMessage(
|
|
19389
|
+
state,
|
|
19390
|
+
event
|
|
19391
|
+
);
|
|
19392
|
+
break;
|
|
19393
|
+
case "agent.custom_tool_use":
|
|
19394
|
+
case "agent.mcp_tool_use":
|
|
19395
|
+
case "agent.tool_use":
|
|
19396
|
+
startAnthropicSessionTool(state, event);
|
|
19397
|
+
break;
|
|
19398
|
+
case "user.tool_confirmation":
|
|
19399
|
+
recordAnthropicSessionToolConfirmation(state, event);
|
|
19400
|
+
break;
|
|
19401
|
+
case "agent.mcp_tool_result":
|
|
19402
|
+
case "agent.tool_result":
|
|
19403
|
+
case "user.custom_tool_result":
|
|
19404
|
+
case "user.tool_result":
|
|
19405
|
+
finalizeAnthropicSessionTool(
|
|
19406
|
+
state,
|
|
19407
|
+
event
|
|
19408
|
+
);
|
|
19409
|
+
break;
|
|
19410
|
+
case "span.model_request_end":
|
|
19411
|
+
finalizeAnthropicSessionModel(
|
|
19412
|
+
state,
|
|
19413
|
+
event
|
|
19414
|
+
);
|
|
19415
|
+
break;
|
|
19416
|
+
case "session.status_idle":
|
|
19417
|
+
case "session.thread_status_idle": {
|
|
19418
|
+
if (event.type === "session.status_idle" && state.isThread || event.type === "session.thread_status_idle" && !state.isThread) {
|
|
19419
|
+
break;
|
|
19420
|
+
}
|
|
19421
|
+
const stopReason = isObject(event.stop_reason) ? event.stop_reason.type : void 0;
|
|
19422
|
+
if (stopReason === "end_turn") {
|
|
19423
|
+
finalizeAnthropicSessionTurn(state);
|
|
19424
|
+
} else if (stopReason === "retries_exhausted") {
|
|
19425
|
+
finalizeAnthropicSessionTurn(
|
|
19426
|
+
state,
|
|
19427
|
+
"Anthropic session retries exhausted"
|
|
19428
|
+
);
|
|
19429
|
+
}
|
|
19430
|
+
break;
|
|
19431
|
+
}
|
|
19432
|
+
case "session.error":
|
|
19433
|
+
finalizeAnthropicSessionTurn(state, event.error);
|
|
19434
|
+
break;
|
|
19435
|
+
case "session.deleted":
|
|
19436
|
+
case "session.status_terminated":
|
|
19437
|
+
case "session.thread_status_terminated":
|
|
19438
|
+
if (event.type === "session.deleted" || event.type === "session.status_terminated" && !state.isThread || event.type === "session.thread_status_terminated" && state.isThread) {
|
|
19439
|
+
finalizeAnthropicSessionTurn(state);
|
|
19440
|
+
}
|
|
19441
|
+
break;
|
|
19442
|
+
default:
|
|
19443
|
+
break;
|
|
19444
|
+
}
|
|
19445
|
+
} catch (error) {
|
|
19446
|
+
debugLogger.debug("Error processing Anthropic Sessions event:", error);
|
|
19447
|
+
}
|
|
19448
|
+
}
|
|
19449
|
+
function ensureAnthropicSessionTurn(state) {
|
|
19450
|
+
if (state.activeTurn) {
|
|
19451
|
+
return state.activeTurn;
|
|
19452
|
+
}
|
|
19453
|
+
const input = state.pendingInput;
|
|
19454
|
+
state.pendingInput = [];
|
|
19455
|
+
const span = startSpan(
|
|
19456
|
+
withSpanInstrumentationName(
|
|
19457
|
+
{
|
|
19458
|
+
event: {
|
|
19459
|
+
...input.length > 0 ? { input } : {},
|
|
19460
|
+
metadata: { provider: "anthropic" }
|
|
19461
|
+
},
|
|
19462
|
+
name: state.isThread ? "anthropic.beta.sessions.thread.turn" : "anthropic.beta.sessions.turn",
|
|
19463
|
+
spanAttributes: { type: "task" /* TASK */ }
|
|
19464
|
+
},
|
|
19465
|
+
INSTRUMENTATION_NAMES.ANTHROPIC
|
|
19466
|
+
)
|
|
19467
|
+
);
|
|
19468
|
+
state.activeTurn = {
|
|
19469
|
+
activeTools: /* @__PURE__ */ new Map(),
|
|
19470
|
+
input: input.slice(),
|
|
19471
|
+
metrics: {},
|
|
19472
|
+
span
|
|
19473
|
+
};
|
|
19474
|
+
return state.activeTurn;
|
|
19475
|
+
}
|
|
19476
|
+
function recordAnthropicSessionInput(state, event) {
|
|
19477
|
+
const content = processAttachmentsInInput(event.content);
|
|
19478
|
+
const message = {
|
|
19479
|
+
role: event.type === "system.message" ? "system" : "user",
|
|
19480
|
+
content
|
|
19481
|
+
};
|
|
19482
|
+
state.history.push(message);
|
|
19483
|
+
if (state.activeTurn) {
|
|
19484
|
+
state.activeTurn.input.push(message);
|
|
19485
|
+
} else {
|
|
19486
|
+
state.pendingInput.push(message);
|
|
19487
|
+
}
|
|
19488
|
+
}
|
|
19489
|
+
function startAnthropicSessionModel(state, startEventId) {
|
|
19490
|
+
const turn = ensureAnthropicSessionTurn(state);
|
|
19491
|
+
if (turn.activeModel) {
|
|
19492
|
+
finalizeAnthropicSessionModelState(state, turn);
|
|
19493
|
+
}
|
|
19494
|
+
const span = withCurrent(
|
|
19495
|
+
turn.span,
|
|
19496
|
+
() => startSpan(
|
|
19497
|
+
withSpanInstrumentationName(
|
|
19498
|
+
{
|
|
19499
|
+
event: {
|
|
19500
|
+
...state.history.length > 0 ? { input: state.history.slice() } : {},
|
|
19501
|
+
metadata: { provider: "anthropic" }
|
|
19502
|
+
},
|
|
19503
|
+
name: "anthropic.messages.create",
|
|
19504
|
+
spanAttributes: { type: "llm" /* LLM */ }
|
|
19505
|
+
},
|
|
19506
|
+
INSTRUMENTATION_NAMES.ANTHROPIC
|
|
19507
|
+
)
|
|
19508
|
+
)
|
|
19509
|
+
);
|
|
19510
|
+
turn.activeModel = {
|
|
19511
|
+
output: [],
|
|
19512
|
+
span,
|
|
19513
|
+
startEventId,
|
|
19514
|
+
startTime: getCurrentUnixTimestamp()
|
|
19515
|
+
};
|
|
19516
|
+
}
|
|
19517
|
+
function recordAnthropicSessionFirstToken(state, event) {
|
|
19518
|
+
const model = state.activeTurn?.activeModel;
|
|
19519
|
+
if (!model || model.firstTokenTime !== void 0 || !isObject(event.delta) || !isObject(event.delta.content) || typeof event.delta.content.text !== "string") {
|
|
19520
|
+
return;
|
|
19521
|
+
}
|
|
19522
|
+
model.firstTokenTime = getCurrentUnixTimestamp();
|
|
19523
|
+
}
|
|
19524
|
+
function recordAnthropicSessionMessage(state, event) {
|
|
19525
|
+
const turn = ensureAnthropicSessionTurn(state);
|
|
19526
|
+
const content = processAttachmentsInInput(
|
|
19527
|
+
event.content
|
|
19528
|
+
);
|
|
19529
|
+
if (turn.activeModel) {
|
|
19530
|
+
turn.activeModel.output.push(...content);
|
|
19531
|
+
} else {
|
|
19532
|
+
const output = { role: "assistant", content };
|
|
19533
|
+
turn.lastOutput = output;
|
|
19534
|
+
state.history.push(output);
|
|
19535
|
+
}
|
|
19536
|
+
}
|
|
19537
|
+
function startAnthropicSessionTool(state, event) {
|
|
19538
|
+
const turn = ensureAnthropicSessionTurn(state);
|
|
19539
|
+
if (turn.activeModel) {
|
|
19540
|
+
turn.activeModel.output.push({
|
|
19541
|
+
type: "tool_use",
|
|
19542
|
+
id: event.id,
|
|
19543
|
+
name: event.name,
|
|
19544
|
+
input: event.input
|
|
19545
|
+
});
|
|
19546
|
+
}
|
|
19547
|
+
const existing = turn.activeTools.get(event.id);
|
|
19548
|
+
if (existing) {
|
|
19549
|
+
existing.span.end();
|
|
19550
|
+
turn.activeTools.delete(event.id);
|
|
19551
|
+
}
|
|
19552
|
+
const span = withCurrent(
|
|
19553
|
+
turn.span,
|
|
19554
|
+
() => startSpan(
|
|
19555
|
+
withSpanInstrumentationName(
|
|
19556
|
+
{
|
|
19557
|
+
event: { input: event.input },
|
|
19558
|
+
name: event.name,
|
|
19559
|
+
spanAttributes: { type: "tool" /* TOOL */ }
|
|
19560
|
+
},
|
|
19561
|
+
INSTRUMENTATION_NAMES.ANTHROPIC
|
|
19562
|
+
)
|
|
19563
|
+
)
|
|
19564
|
+
);
|
|
19565
|
+
const toolState = {
|
|
19566
|
+
approval: event.evaluated_permission === "allow" ? "approved" : event.evaluated_permission === "deny" ? "denied" : void 0,
|
|
19567
|
+
span
|
|
19568
|
+
};
|
|
19569
|
+
turn.activeTools.set(event.id, toolState);
|
|
19570
|
+
if (toolState.approval === "denied") {
|
|
19571
|
+
finalizeAnthropicSessionToolState(toolState);
|
|
19572
|
+
turn.activeTools.delete(event.id);
|
|
19573
|
+
}
|
|
19574
|
+
}
|
|
19575
|
+
function recordAnthropicSessionToolConfirmation(state, event) {
|
|
19576
|
+
if (typeof event.tool_use_id !== "string" || event.result !== "allow" && event.result !== "deny") {
|
|
19577
|
+
return;
|
|
19578
|
+
}
|
|
19579
|
+
const turn = state.activeTurn;
|
|
19580
|
+
const tool = turn?.activeTools.get(event.tool_use_id);
|
|
19581
|
+
if (!turn || !tool) {
|
|
19582
|
+
return;
|
|
19583
|
+
}
|
|
19584
|
+
tool.approval = event.result === "allow" ? "approved" : "denied";
|
|
19585
|
+
if (tool.approval === "denied") {
|
|
19586
|
+
finalizeAnthropicSessionToolState(tool);
|
|
19587
|
+
turn.activeTools.delete(event.tool_use_id);
|
|
19588
|
+
}
|
|
19589
|
+
}
|
|
19590
|
+
function finalizeAnthropicSessionTool(state, event) {
|
|
19591
|
+
const toolUseId = event.tool_use_id ?? event.mcp_tool_use_id ?? event.custom_tool_use_id;
|
|
19592
|
+
if (!toolUseId) {
|
|
19593
|
+
return;
|
|
19594
|
+
}
|
|
19595
|
+
const content = processAttachmentsInInput(event.content);
|
|
19596
|
+
const turn = state.activeTurn;
|
|
19597
|
+
const tool = turn?.activeTools.get(toolUseId);
|
|
19598
|
+
if (turn && tool) {
|
|
19599
|
+
finalizeAnthropicSessionToolState(tool, event, content);
|
|
19600
|
+
turn.activeTools.delete(toolUseId);
|
|
19601
|
+
}
|
|
19602
|
+
const toolResult = {
|
|
19603
|
+
type: "tool_result",
|
|
19604
|
+
tool_use_id: toolUseId,
|
|
19605
|
+
...content !== void 0 ? { content } : {},
|
|
19606
|
+
...event.is_error === true ? { is_error: true } : {}
|
|
19607
|
+
};
|
|
19608
|
+
state.history.push({
|
|
19609
|
+
role: "user",
|
|
19610
|
+
content: [toolResult]
|
|
19611
|
+
});
|
|
19612
|
+
}
|
|
19613
|
+
function finalizeAnthropicSessionToolState(state, event, content = event?.content) {
|
|
19614
|
+
safeAnthropicSessionLog(state.span, {
|
|
19615
|
+
...event?.is_error === true ? {
|
|
19616
|
+
error: content ?? "Anthropic session tool execution failed"
|
|
19617
|
+
} : {},
|
|
19618
|
+
...state.approval ? { metadata: { tool_approval: state.approval } } : {},
|
|
19619
|
+
...content !== void 0 ? { output: content } : {}
|
|
19620
|
+
});
|
|
19621
|
+
state.span.end();
|
|
19622
|
+
}
|
|
19623
|
+
function finalizeAnthropicSessionModel(state, event) {
|
|
19624
|
+
const turn = state.activeTurn;
|
|
19625
|
+
const model = turn?.activeModel;
|
|
19626
|
+
if (!turn || !model || model.startEventId !== event.model_request_start_id) {
|
|
19627
|
+
return;
|
|
19628
|
+
}
|
|
19629
|
+
finalizeAnthropicSessionModelState(state, turn, event);
|
|
19630
|
+
}
|
|
19631
|
+
function finalizeAnthropicSessionModelState(state, turn, event) {
|
|
19632
|
+
const model = turn.activeModel;
|
|
19633
|
+
if (!model) {
|
|
19634
|
+
return;
|
|
19635
|
+
}
|
|
19636
|
+
turn.activeModel = void 0;
|
|
19637
|
+
const metrics = event ? parseAnthropicSessionModelUsage(event.model_usage) : {};
|
|
19638
|
+
if (model.firstTokenTime !== void 0) {
|
|
19639
|
+
metrics.time_to_first_token = model.firstTokenTime - model.startTime;
|
|
19640
|
+
}
|
|
19641
|
+
const output = model.output.length > 0 ? { role: "assistant", content: model.output } : void 0;
|
|
19642
|
+
safeAnthropicSessionLog(model.span, {
|
|
19643
|
+
...event?.is_error ? { error: "Anthropic session model request failed" } : {},
|
|
19644
|
+
...Object.keys(metrics).length > 0 ? { metrics } : {},
|
|
19645
|
+
...output ? { output } : {}
|
|
19646
|
+
});
|
|
19647
|
+
model.span.end();
|
|
19648
|
+
if (output) {
|
|
19649
|
+
turn.lastOutput = output;
|
|
19650
|
+
state.history.push(output);
|
|
19651
|
+
}
|
|
19652
|
+
for (const key of [
|
|
19653
|
+
"prompt_tokens",
|
|
19654
|
+
"completion_tokens",
|
|
19655
|
+
"tokens",
|
|
19656
|
+
"prompt_cached_tokens",
|
|
19657
|
+
"prompt_cache_creation_tokens"
|
|
19658
|
+
]) {
|
|
19659
|
+
const value = metrics[key];
|
|
19660
|
+
if (typeof value === "number") {
|
|
19661
|
+
turn.metrics[key] = (turn.metrics[key] ?? 0) + value;
|
|
19662
|
+
}
|
|
19663
|
+
}
|
|
19664
|
+
}
|
|
19665
|
+
function parseAnthropicSessionModelUsage(usage) {
|
|
19666
|
+
const finalized = finalizeAnthropicTokens({
|
|
19667
|
+
completion_tokens: usage.output_tokens,
|
|
19668
|
+
prompt_cache_creation_tokens: usage.cache_creation_input_tokens,
|
|
19669
|
+
prompt_cached_tokens: usage.cache_read_input_tokens,
|
|
19670
|
+
prompt_tokens: usage.input_tokens
|
|
19671
|
+
});
|
|
19672
|
+
return Object.fromEntries(
|
|
19673
|
+
Object.entries(finalized).filter(
|
|
19674
|
+
(entry) => entry[1] !== void 0
|
|
19675
|
+
)
|
|
19676
|
+
);
|
|
19677
|
+
}
|
|
19678
|
+
function finalizeAnthropicSessionTurn(state, error) {
|
|
19679
|
+
const turn = state.activeTurn;
|
|
19680
|
+
if (!turn) {
|
|
19681
|
+
return;
|
|
19682
|
+
}
|
|
19683
|
+
state.activeTurn = void 0;
|
|
19684
|
+
finalizeAnthropicSessionModelState(state, turn);
|
|
19685
|
+
for (const tool of turn.activeTools.values()) {
|
|
19686
|
+
finalizeAnthropicSessionToolState(tool);
|
|
19687
|
+
}
|
|
19688
|
+
turn.activeTools.clear();
|
|
19689
|
+
safeAnthropicSessionLog(turn.span, {
|
|
19690
|
+
...error !== void 0 ? { error: error instanceof Error ? error : toLoggedError(error) } : {},
|
|
19691
|
+
...turn.input.length > 0 ? { input: turn.input } : {},
|
|
19692
|
+
...turn.lastOutput ? { output: turn.lastOutput } : {},
|
|
19693
|
+
...Object.keys(turn.metrics).length > 0 ? { metrics: turn.metrics } : {}
|
|
19694
|
+
});
|
|
19695
|
+
turn.span.end();
|
|
19696
|
+
}
|
|
19697
|
+
function safeAnthropicSessionLog(span, event) {
|
|
19698
|
+
try {
|
|
19699
|
+
span.log(event);
|
|
19700
|
+
} catch (error) {
|
|
19701
|
+
debugLogger.debug("Error logging Anthropic Sessions span:", error);
|
|
19702
|
+
}
|
|
19703
|
+
}
|
|
19158
19704
|
function parseMetricsFromUsage2(usage) {
|
|
19159
19705
|
if (!usage) {
|
|
19160
19706
|
return {};
|
|
@@ -21213,6 +21759,283 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
21213
21759
|
}
|
|
21214
21760
|
};
|
|
21215
21761
|
|
|
21762
|
+
// src/instrumentation/plugins/cloudflare-think-plugin.ts
|
|
21763
|
+
var THINK_STATE_ID = /* @__PURE__ */ Symbol.for("braintrust.cloudflare-think.state-id");
|
|
21764
|
+
var CloudflareThinkPlugin = class extends BasePlugin {
|
|
21765
|
+
statesBySpanId = /* @__PURE__ */ new Map();
|
|
21766
|
+
onEnable() {
|
|
21767
|
+
this.subscribeToThinkRuns();
|
|
21768
|
+
this.subscribeToAISDKStreamTextSync();
|
|
21769
|
+
this.subscribeToAISDKStreamTextAsync();
|
|
21770
|
+
}
|
|
21771
|
+
onDisable() {
|
|
21772
|
+
for (const unsubscribe of this.unsubscribers) {
|
|
21773
|
+
unsubscribe();
|
|
21774
|
+
}
|
|
21775
|
+
this.unsubscribers = [];
|
|
21776
|
+
for (const state of this.statesBySpanId.values()) {
|
|
21777
|
+
this.finishState(state);
|
|
21778
|
+
}
|
|
21779
|
+
this.statesBySpanId.clear();
|
|
21780
|
+
}
|
|
21781
|
+
subscribeToThinkRuns() {
|
|
21782
|
+
const channel = cloudflareThinkChannels.runInferenceLoop.tracingChannel();
|
|
21783
|
+
const states = /* @__PURE__ */ new WeakMap();
|
|
21784
|
+
const state = _internalGetGlobalState();
|
|
21785
|
+
const contextManager = state?.contextManager;
|
|
21786
|
+
const currentSpanStore = contextManager ? contextManager[BRAINTRUST_CURRENT_SPAN_STORE] : void 0;
|
|
21787
|
+
const ensureState2 = (event) => {
|
|
21788
|
+
if (isAutoInstrumentationSuppressed()) {
|
|
21789
|
+
return void 0;
|
|
21790
|
+
}
|
|
21791
|
+
const existing = states.get(event);
|
|
21792
|
+
if (existing) {
|
|
21793
|
+
return existing;
|
|
21794
|
+
}
|
|
21795
|
+
const span = startSpan(
|
|
21796
|
+
withSpanInstrumentationName(
|
|
21797
|
+
{
|
|
21798
|
+
name: "Think.runTurn",
|
|
21799
|
+
spanAttributes: { type: "task" /* TASK */ }
|
|
21800
|
+
},
|
|
21801
|
+
INSTRUMENTATION_NAMES.CLOUDFLARE_THINK
|
|
21802
|
+
)
|
|
21803
|
+
);
|
|
21804
|
+
const runState = {
|
|
21805
|
+
aiResultPatched: false,
|
|
21806
|
+
fallbackInput: extractFallbackInput(event.self?.messages),
|
|
21807
|
+
finalized: false,
|
|
21808
|
+
inputLogged: false,
|
|
21809
|
+
span,
|
|
21810
|
+
startTime: getCurrentUnixTimestamp()
|
|
21811
|
+
};
|
|
21812
|
+
const metadata = {
|
|
21813
|
+
braintrust: {
|
|
21814
|
+
integration_name: "cloudflare-think",
|
|
21815
|
+
sdk_language: "typescript"
|
|
21816
|
+
}
|
|
21817
|
+
};
|
|
21818
|
+
if (typeof event.moduleVersion === "string") {
|
|
21819
|
+
metadata["cloudflare_think.version"] = event.moduleVersion;
|
|
21820
|
+
}
|
|
21821
|
+
span.log({ metadata });
|
|
21822
|
+
states.set(event, runState);
|
|
21823
|
+
if (span.spanId) {
|
|
21824
|
+
this.statesBySpanId.set(span.spanId, runState);
|
|
21825
|
+
}
|
|
21826
|
+
registerCloudflareThinkSpan(span);
|
|
21827
|
+
return runState;
|
|
21828
|
+
};
|
|
21829
|
+
if (contextManager && currentSpanStore && channel.start) {
|
|
21830
|
+
channel.start.bindStore(currentSpanStore, (event) => {
|
|
21831
|
+
const runState = ensureState2(event);
|
|
21832
|
+
return runState ? contextManager.wrapSpanForStore(runState.span) : currentSpanStore.getStore();
|
|
21833
|
+
});
|
|
21834
|
+
this.unsubscribers.push(
|
|
21835
|
+
() => channel.start?.unbindStore(currentSpanStore)
|
|
21836
|
+
);
|
|
21837
|
+
}
|
|
21838
|
+
const handlers = {
|
|
21839
|
+
start: (event) => {
|
|
21840
|
+
ensureState2(event);
|
|
21841
|
+
},
|
|
21842
|
+
asyncEnd: (event) => {
|
|
21843
|
+
const runState = states.get(event);
|
|
21844
|
+
states.delete(event);
|
|
21845
|
+
if (!runState || runState.finalized || runState.aiResultPatched) {
|
|
21846
|
+
return;
|
|
21847
|
+
}
|
|
21848
|
+
this.finishState(runState, void 0, event.result);
|
|
21849
|
+
},
|
|
21850
|
+
error: (event) => {
|
|
21851
|
+
const runState = states.get(event);
|
|
21852
|
+
states.delete(event);
|
|
21853
|
+
if (runState) {
|
|
21854
|
+
this.finishState(runState, event.error);
|
|
21855
|
+
}
|
|
21856
|
+
}
|
|
21857
|
+
};
|
|
21858
|
+
channel.subscribe(handlers);
|
|
21859
|
+
this.unsubscribers.push(() => channel.unsubscribe(handlers));
|
|
21860
|
+
}
|
|
21861
|
+
subscribeToAISDKStreamTextSync() {
|
|
21862
|
+
const channel = aiSDKChannels.streamTextSync.tracingChannel();
|
|
21863
|
+
const handlers = {
|
|
21864
|
+
start: (event) => {
|
|
21865
|
+
this.startAISDKStream(event);
|
|
21866
|
+
},
|
|
21867
|
+
end: (event) => {
|
|
21868
|
+
this.endAISDKStream(event);
|
|
21869
|
+
},
|
|
21870
|
+
error: (event) => {
|
|
21871
|
+
this.errorAISDKStream(event);
|
|
21872
|
+
}
|
|
21873
|
+
};
|
|
21874
|
+
channel.subscribe(handlers);
|
|
21875
|
+
this.unsubscribers.push(() => channel.unsubscribe(handlers));
|
|
21876
|
+
}
|
|
21877
|
+
subscribeToAISDKStreamTextAsync() {
|
|
21878
|
+
const channel = aiSDKChannels.streamText.tracingChannel();
|
|
21879
|
+
const handlers = {
|
|
21880
|
+
start: (event) => {
|
|
21881
|
+
this.startAISDKStream(event);
|
|
21882
|
+
},
|
|
21883
|
+
asyncEnd: (event) => {
|
|
21884
|
+
this.endAISDKStream(event);
|
|
21885
|
+
},
|
|
21886
|
+
error: (event) => {
|
|
21887
|
+
this.errorAISDKStream(event);
|
|
21888
|
+
}
|
|
21889
|
+
};
|
|
21890
|
+
channel.subscribe(handlers);
|
|
21891
|
+
this.unsubscribers.push(() => channel.unsubscribe(handlers));
|
|
21892
|
+
}
|
|
21893
|
+
startAISDKStream(event) {
|
|
21894
|
+
const runState = this.currentState();
|
|
21895
|
+
if (!runState || runState.finalized) {
|
|
21896
|
+
return;
|
|
21897
|
+
}
|
|
21898
|
+
try {
|
|
21899
|
+
const prepared = prepareAISDKAgentCallInput(
|
|
21900
|
+
event.arguments[0],
|
|
21901
|
+
event,
|
|
21902
|
+
runState.span
|
|
21903
|
+
);
|
|
21904
|
+
runState.span.log({
|
|
21905
|
+
input: extractThinkTaskInput(prepared.input),
|
|
21906
|
+
metadata: {
|
|
21907
|
+
...prepared.metadata,
|
|
21908
|
+
braintrust: {
|
|
21909
|
+
integration_name: "cloudflare-think",
|
|
21910
|
+
sdk_language: "typescript"
|
|
21911
|
+
}
|
|
21912
|
+
}
|
|
21913
|
+
});
|
|
21914
|
+
runState.inputLogged = true;
|
|
21915
|
+
runState.aiEvent = event;
|
|
21916
|
+
Reflect.set(event, THINK_STATE_ID, runState.span.spanId);
|
|
21917
|
+
} catch (error) {
|
|
21918
|
+
debugLogger.error(
|
|
21919
|
+
"Error preparing @cloudflare/think AI SDK tracing:",
|
|
21920
|
+
error
|
|
21921
|
+
);
|
|
21922
|
+
}
|
|
21923
|
+
}
|
|
21924
|
+
endAISDKStream(event) {
|
|
21925
|
+
const runState = this.stateForAISDKEvent(event);
|
|
21926
|
+
if (!runState || runState.finalized) {
|
|
21927
|
+
return;
|
|
21928
|
+
}
|
|
21929
|
+
const patched = patchAISDKStreamingResult({
|
|
21930
|
+
defaultDenyOutputPaths: DEFAULT_DENY_OUTPUT_PATHS,
|
|
21931
|
+
endEvent: event,
|
|
21932
|
+
forceTopLevelMetrics: true,
|
|
21933
|
+
onComplete: () => this.releaseState(runState),
|
|
21934
|
+
result: event.result,
|
|
21935
|
+
span: runState.span,
|
|
21936
|
+
startTime: runState.startTime,
|
|
21937
|
+
transformOutput: extractThinkTaskOutput
|
|
21938
|
+
});
|
|
21939
|
+
runState.aiResultPatched = patched;
|
|
21940
|
+
if (!patched) {
|
|
21941
|
+
this.finishState(runState, void 0, event.result);
|
|
21942
|
+
}
|
|
21943
|
+
}
|
|
21944
|
+
errorAISDKStream(event) {
|
|
21945
|
+
const runState = this.stateForAISDKEvent(event);
|
|
21946
|
+
if (runState) {
|
|
21947
|
+
this.finishState(runState, event.error);
|
|
21948
|
+
}
|
|
21949
|
+
}
|
|
21950
|
+
currentState() {
|
|
21951
|
+
const parentIds = _internalGetGlobalState()?.contextManager.getParentSpanIds()?.spanParents ?? [];
|
|
21952
|
+
for (const parentId of parentIds) {
|
|
21953
|
+
const state = this.statesBySpanId.get(parentId);
|
|
21954
|
+
if (state) {
|
|
21955
|
+
return state;
|
|
21956
|
+
}
|
|
21957
|
+
}
|
|
21958
|
+
return void 0;
|
|
21959
|
+
}
|
|
21960
|
+
stateForAISDKEvent(event) {
|
|
21961
|
+
const spanId = Reflect.get(event, THINK_STATE_ID);
|
|
21962
|
+
return typeof spanId === "string" ? this.statesBySpanId.get(spanId) : void 0;
|
|
21963
|
+
}
|
|
21964
|
+
finishState(state, error, output) {
|
|
21965
|
+
if (state.finalized) {
|
|
21966
|
+
return;
|
|
21967
|
+
}
|
|
21968
|
+
state.finalized = true;
|
|
21969
|
+
try {
|
|
21970
|
+
if (!state.inputLogged && state.fallbackInput !== void 0) {
|
|
21971
|
+
state.span.log({ input: state.fallbackInput });
|
|
21972
|
+
}
|
|
21973
|
+
if (error !== void 0) {
|
|
21974
|
+
state.span.log({ error });
|
|
21975
|
+
} else if (output !== void 0) {
|
|
21976
|
+
state.span.log({ output: extractThinkTaskOutput(output) });
|
|
21977
|
+
}
|
|
21978
|
+
finalizeAISDKChildTracing(state.aiEvent);
|
|
21979
|
+
state.span.end();
|
|
21980
|
+
} finally {
|
|
21981
|
+
this.releaseState(state);
|
|
21982
|
+
}
|
|
21983
|
+
}
|
|
21984
|
+
releaseState(state) {
|
|
21985
|
+
state.finalized = true;
|
|
21986
|
+
unregisterCloudflareThinkSpan(state.span);
|
|
21987
|
+
if (state.span.spanId) {
|
|
21988
|
+
this.statesBySpanId.delete(state.span.spanId);
|
|
21989
|
+
}
|
|
21990
|
+
}
|
|
21991
|
+
};
|
|
21992
|
+
function extractFallbackInput(messages) {
|
|
21993
|
+
if (!Array.isArray(messages) || messages.length === 0) {
|
|
21994
|
+
return void 0;
|
|
21995
|
+
}
|
|
21996
|
+
let latestUserIndex = -1;
|
|
21997
|
+
for (let index = messages.length - 1; index >= 0; index--) {
|
|
21998
|
+
if (messages[index]?.role === "user") {
|
|
21999
|
+
latestUserIndex = index;
|
|
22000
|
+
break;
|
|
22001
|
+
}
|
|
22002
|
+
}
|
|
22003
|
+
const selected = latestUserIndex >= 0 ? messages.slice(latestUserIndex) : [];
|
|
22004
|
+
return selected.map((message) => ({
|
|
22005
|
+
role: message.role,
|
|
22006
|
+
content: message.content ?? message.parts
|
|
22007
|
+
}));
|
|
22008
|
+
}
|
|
22009
|
+
function extractThinkTaskOutput(output) {
|
|
22010
|
+
if (!isObject(output)) {
|
|
22011
|
+
return output;
|
|
22012
|
+
}
|
|
22013
|
+
if (typeof output.text === "string") {
|
|
22014
|
+
return { role: "assistant", content: output.text };
|
|
22015
|
+
}
|
|
22016
|
+
if (output.object !== void 0) {
|
|
22017
|
+
return output.object;
|
|
22018
|
+
}
|
|
22019
|
+
return output;
|
|
22020
|
+
}
|
|
22021
|
+
function extractThinkTaskInput(input) {
|
|
22022
|
+
if (!isObject(input)) {
|
|
22023
|
+
return input;
|
|
22024
|
+
}
|
|
22025
|
+
const system = input.instructions ?? input.system;
|
|
22026
|
+
if (Array.isArray(input.messages)) {
|
|
22027
|
+
return system === void 0 ? input.messages : [{ role: "system", content: system }, ...input.messages];
|
|
22028
|
+
}
|
|
22029
|
+
if (Array.isArray(input.prompt)) {
|
|
22030
|
+
return system === void 0 ? input.prompt : [{ role: "system", content: system }, ...input.prompt];
|
|
22031
|
+
}
|
|
22032
|
+
if (typeof input.prompt === "string") {
|
|
22033
|
+
const messages = [{ role: "user", content: input.prompt }];
|
|
22034
|
+
return system === void 0 ? messages : [{ role: "system", content: system }, ...messages];
|
|
22035
|
+
}
|
|
22036
|
+
return input;
|
|
22037
|
+
}
|
|
22038
|
+
|
|
21216
22039
|
// src/instrumentation/plugins/cursor-sdk-plugin.ts
|
|
21217
22040
|
var PATCHED_AGENT = /* @__PURE__ */ Symbol.for("braintrust.cursor-sdk.auto-patched-agent");
|
|
21218
22041
|
var PATCHED_RUN = /* @__PURE__ */ Symbol.for("braintrust.cursor-sdk.patched-run");
|
|
@@ -26730,6 +27553,450 @@ function aggregateMistralStreamChunks(chunks) {
|
|
|
26730
27553
|
};
|
|
26731
27554
|
}
|
|
26732
27555
|
|
|
27556
|
+
// src/instrumentation/plugins/ollama-plugin.ts
|
|
27557
|
+
var OllamaPlugin = class extends BasePlugin {
|
|
27558
|
+
onEnable() {
|
|
27559
|
+
this.unsubscribers.push(
|
|
27560
|
+
traceStreamingChannel(ollamaChannels.chat, {
|
|
27561
|
+
name: "ollama.chat",
|
|
27562
|
+
type: "llm" /* LLM */,
|
|
27563
|
+
extractInput: extractOllamaChatInput,
|
|
27564
|
+
extractOutput: (result, event) => extractOllamaChatOutput(
|
|
27565
|
+
result,
|
|
27566
|
+
countOllamaToolCalls(event?.arguments?.[0]?.messages)
|
|
27567
|
+
),
|
|
27568
|
+
extractMetadata: extractOllamaResponseMetadata,
|
|
27569
|
+
extractMetrics: extractOllamaMetrics,
|
|
27570
|
+
aggregateChunks: aggregateOllamaChatChunks
|
|
27571
|
+
}),
|
|
27572
|
+
traceStreamingChannel(ollamaChannels.generate, {
|
|
27573
|
+
name: "ollama.generate",
|
|
27574
|
+
type: "llm" /* LLM */,
|
|
27575
|
+
extractInput: extractOllamaGenerateInput,
|
|
27576
|
+
extractOutput: extractOllamaGenerateOutput,
|
|
27577
|
+
extractMetadata: extractOllamaResponseMetadata,
|
|
27578
|
+
extractMetrics: extractOllamaMetrics,
|
|
27579
|
+
aggregateChunks: aggregateOllamaGenerateChunks
|
|
27580
|
+
}),
|
|
27581
|
+
traceAsyncChannel(ollamaChannels.embed, {
|
|
27582
|
+
name: "ollama.embed",
|
|
27583
|
+
type: "llm" /* LLM */,
|
|
27584
|
+
extractInput: extractOllamaEmbedInput,
|
|
27585
|
+
extractOutput: extractOllamaEmbedOutput,
|
|
27586
|
+
extractMetadata: extractOllamaResponseMetadata,
|
|
27587
|
+
extractMetrics: extractOllamaMetrics
|
|
27588
|
+
})
|
|
27589
|
+
);
|
|
27590
|
+
}
|
|
27591
|
+
onDisable() {
|
|
27592
|
+
this.unsubscribers = unsubscribeAll(this.unsubscribers);
|
|
27593
|
+
}
|
|
27594
|
+
};
|
|
27595
|
+
function isNonNegativeNumber(value) {
|
|
27596
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0;
|
|
27597
|
+
}
|
|
27598
|
+
function normalizeFinishReason(response, hasToolCalls = false) {
|
|
27599
|
+
if (hasToolCalls) {
|
|
27600
|
+
return "tool_calls";
|
|
27601
|
+
}
|
|
27602
|
+
return response?.done_reason || "stop";
|
|
27603
|
+
}
|
|
27604
|
+
function stringifyArguments(value) {
|
|
27605
|
+
if (typeof value === "string") {
|
|
27606
|
+
return value;
|
|
27607
|
+
}
|
|
27608
|
+
try {
|
|
27609
|
+
return JSON.stringify(value ?? {});
|
|
27610
|
+
} catch {
|
|
27611
|
+
return String(value);
|
|
27612
|
+
}
|
|
27613
|
+
}
|
|
27614
|
+
function syntheticToolCallId(name, index) {
|
|
27615
|
+
const normalizedName = name.replace(/[^a-zA-Z0-9_-]/g, "_") || "tool";
|
|
27616
|
+
return `ollama_call_${normalizedName}_${index}`;
|
|
27617
|
+
}
|
|
27618
|
+
function normalizeToolCall(toolCall, index) {
|
|
27619
|
+
const name = toolCall.function?.name;
|
|
27620
|
+
if (typeof name !== "string" || name.length === 0) {
|
|
27621
|
+
return void 0;
|
|
27622
|
+
}
|
|
27623
|
+
return {
|
|
27624
|
+
id: typeof toolCall.id === "string" && toolCall.id.length > 0 ? toolCall.id : syntheticToolCallId(name, index),
|
|
27625
|
+
type: "function",
|
|
27626
|
+
function: {
|
|
27627
|
+
name,
|
|
27628
|
+
arguments: stringifyArguments(toolCall.function?.arguments)
|
|
27629
|
+
}
|
|
27630
|
+
};
|
|
27631
|
+
}
|
|
27632
|
+
function normalizeToolCalls(toolCalls, syntheticIdOffset = 0) {
|
|
27633
|
+
if (!Array.isArray(toolCalls)) {
|
|
27634
|
+
return [];
|
|
27635
|
+
}
|
|
27636
|
+
return toolCalls.flatMap((toolCall, index) => {
|
|
27637
|
+
const normalized = normalizeToolCall(toolCall, syntheticIdOffset + index);
|
|
27638
|
+
return normalized ? [normalized] : [];
|
|
27639
|
+
});
|
|
27640
|
+
}
|
|
27641
|
+
function countOllamaToolCalls(messages) {
|
|
27642
|
+
if (!Array.isArray(messages)) {
|
|
27643
|
+
return 0;
|
|
27644
|
+
}
|
|
27645
|
+
return messages.reduce(
|
|
27646
|
+
(count, message) => count + (isObject(message) && Array.isArray(message.tool_calls) ? message.tool_calls.length : 0),
|
|
27647
|
+
0
|
|
27648
|
+
);
|
|
27649
|
+
}
|
|
27650
|
+
function imageBytes(value) {
|
|
27651
|
+
if (value instanceof Uint8Array) {
|
|
27652
|
+
return value;
|
|
27653
|
+
}
|
|
27654
|
+
if (value instanceof ArrayBuffer) {
|
|
27655
|
+
return new Uint8Array(value);
|
|
27656
|
+
}
|
|
27657
|
+
if (typeof value !== "string" || value.startsWith("data:")) {
|
|
27658
|
+
return void 0;
|
|
27659
|
+
}
|
|
27660
|
+
try {
|
|
27661
|
+
const decoded = atob(value.slice(0, 24));
|
|
27662
|
+
return Uint8Array.from(decoded, (character) => character.charCodeAt(0));
|
|
27663
|
+
} catch {
|
|
27664
|
+
return void 0;
|
|
27665
|
+
}
|
|
27666
|
+
}
|
|
27667
|
+
function inferImageMediaType(value) {
|
|
27668
|
+
if (typeof value === "string") {
|
|
27669
|
+
const dataUrlType = value.match(/^data:(image\/[^;]+);base64,/i)?.[1];
|
|
27670
|
+
if (dataUrlType) {
|
|
27671
|
+
return dataUrlType;
|
|
27672
|
+
}
|
|
27673
|
+
}
|
|
27674
|
+
const bytes = imageBytes(value);
|
|
27675
|
+
if (!bytes) {
|
|
27676
|
+
return void 0;
|
|
27677
|
+
}
|
|
27678
|
+
if (bytes[0] === 137 && bytes[1] === 80 && bytes[2] === 78 && bytes[3] === 71) {
|
|
27679
|
+
return "image/png";
|
|
27680
|
+
}
|
|
27681
|
+
if (bytes[0] === 255 && bytes[1] === 216 && bytes[2] === 255) {
|
|
27682
|
+
return "image/jpeg";
|
|
27683
|
+
}
|
|
27684
|
+
const signature = String.fromCharCode(...bytes.slice(0, 12));
|
|
27685
|
+
if (signature.startsWith("GIF87a") || signature.startsWith("GIF89a")) {
|
|
27686
|
+
return "image/gif";
|
|
27687
|
+
}
|
|
27688
|
+
if (signature.startsWith("RIFF") && signature.slice(8, 12) === "WEBP") {
|
|
27689
|
+
return "image/webp";
|
|
27690
|
+
}
|
|
27691
|
+
return void 0;
|
|
27692
|
+
}
|
|
27693
|
+
function normalizeTextAndImages(content, images) {
|
|
27694
|
+
if (!images || images.length === 0) {
|
|
27695
|
+
return { content };
|
|
27696
|
+
}
|
|
27697
|
+
const imageParts = [];
|
|
27698
|
+
const unrecognizedImages = [];
|
|
27699
|
+
for (const image of images) {
|
|
27700
|
+
let localImagePath;
|
|
27701
|
+
let localPathMediaType;
|
|
27702
|
+
if (typeof image === "string" && !/^data:/i.test(image) && !/^https?:\/\//i.test(image)) {
|
|
27703
|
+
const extension = image.match(/\.([a-z0-9]+)$/i)?.[1]?.toLowerCase();
|
|
27704
|
+
const extensionMediaType = {
|
|
27705
|
+
png: "image/png",
|
|
27706
|
+
jpg: "image/jpeg",
|
|
27707
|
+
jpeg: "image/jpeg",
|
|
27708
|
+
gif: "image/gif",
|
|
27709
|
+
webp: "image/webp"
|
|
27710
|
+
}[extension ?? ""];
|
|
27711
|
+
if (extensionMediaType && isomorph_default.statSync) {
|
|
27712
|
+
try {
|
|
27713
|
+
if (isomorph_default.statSync(image).isFile()) {
|
|
27714
|
+
localImagePath = image;
|
|
27715
|
+
localPathMediaType = extensionMediaType;
|
|
27716
|
+
}
|
|
27717
|
+
} catch {
|
|
27718
|
+
}
|
|
27719
|
+
}
|
|
27720
|
+
}
|
|
27721
|
+
const mediaType = localPathMediaType ?? inferImageMediaType(image);
|
|
27722
|
+
if (!mediaType) {
|
|
27723
|
+
unrecognizedImages.push(image);
|
|
27724
|
+
continue;
|
|
27725
|
+
}
|
|
27726
|
+
const processedImage = localImagePath ? new Attachment({
|
|
27727
|
+
data: localImagePath,
|
|
27728
|
+
filename: localImagePath.split(/[\\/]/).at(-1) ?? "image",
|
|
27729
|
+
contentType: mediaType
|
|
27730
|
+
}) : processInputAttachments({
|
|
27731
|
+
type: "image",
|
|
27732
|
+
image,
|
|
27733
|
+
mediaType
|
|
27734
|
+
}).image;
|
|
27735
|
+
imageParts.push({
|
|
27736
|
+
type: "image_url",
|
|
27737
|
+
image_url: { url: processedImage }
|
|
27738
|
+
});
|
|
27739
|
+
}
|
|
27740
|
+
return {
|
|
27741
|
+
content: imageParts.length > 0 ? [...content ? [{ type: "text", text: content }] : [], ...imageParts] : content,
|
|
27742
|
+
...unrecognizedImages.length > 0 ? { unrecognizedImages } : {}
|
|
27743
|
+
};
|
|
27744
|
+
}
|
|
27745
|
+
function normalizeMessage(message, toolCallId, syntheticToolCallIdOffset = 0) {
|
|
27746
|
+
if (typeof message.role !== "string") {
|
|
27747
|
+
return void 0;
|
|
27748
|
+
}
|
|
27749
|
+
const toolCalls = normalizeToolCalls(
|
|
27750
|
+
message.tool_calls,
|
|
27751
|
+
syntheticToolCallIdOffset
|
|
27752
|
+
);
|
|
27753
|
+
if (message.role === "tool") {
|
|
27754
|
+
const toolName = typeof message.tool_name === "string" && message.tool_name.length > 0 ? message.tool_name : "tool";
|
|
27755
|
+
return {
|
|
27756
|
+
role: "tool",
|
|
27757
|
+
tool_call_id: toolCallId ?? syntheticToolCallId(toolName, 0),
|
|
27758
|
+
content: typeof message.content === "string" ? message.content : ""
|
|
27759
|
+
};
|
|
27760
|
+
}
|
|
27761
|
+
const normalizedContent = normalizeTextAndImages(
|
|
27762
|
+
typeof message.content === "string" ? message.content || (toolCalls.length > 0 ? null : "") : toolCalls.length > 0 ? null : "",
|
|
27763
|
+
message.images
|
|
27764
|
+
);
|
|
27765
|
+
return {
|
|
27766
|
+
role: message.role,
|
|
27767
|
+
content: normalizedContent.content,
|
|
27768
|
+
...typeof message.thinking === "string" && message.thinking.length > 0 ? { reasoning: message.thinking } : {},
|
|
27769
|
+
...toolCalls.length > 0 ? { tool_calls: toolCalls } : {},
|
|
27770
|
+
...normalizedContent.unrecognizedImages ? { images: normalizedContent.unrecognizedImages } : {}
|
|
27771
|
+
};
|
|
27772
|
+
}
|
|
27773
|
+
function normalizeMessages(messages) {
|
|
27774
|
+
if (!Array.isArray(messages)) {
|
|
27775
|
+
return [];
|
|
27776
|
+
}
|
|
27777
|
+
const pendingToolCallIds = /* @__PURE__ */ new Map();
|
|
27778
|
+
let syntheticToolCallIdOffset = 0;
|
|
27779
|
+
return messages.flatMap((message) => {
|
|
27780
|
+
if (!isObject(message)) {
|
|
27781
|
+
return [];
|
|
27782
|
+
}
|
|
27783
|
+
const ollamaMessage = message;
|
|
27784
|
+
let toolCallId;
|
|
27785
|
+
if (ollamaMessage.role === "tool") {
|
|
27786
|
+
const toolName = ollamaMessage.tool_name;
|
|
27787
|
+
if (typeof toolName === "string") {
|
|
27788
|
+
toolCallId = pendingToolCallIds.get(toolName)?.shift();
|
|
27789
|
+
}
|
|
27790
|
+
}
|
|
27791
|
+
const normalized = normalizeMessage(
|
|
27792
|
+
ollamaMessage,
|
|
27793
|
+
toolCallId,
|
|
27794
|
+
syntheticToolCallIdOffset
|
|
27795
|
+
);
|
|
27796
|
+
if (Array.isArray(ollamaMessage.tool_calls)) {
|
|
27797
|
+
syntheticToolCallIdOffset += ollamaMessage.tool_calls.length;
|
|
27798
|
+
}
|
|
27799
|
+
if (ollamaMessage.role === "assistant" && normalized) {
|
|
27800
|
+
const toolCalls = Array.isArray(normalized.tool_calls) ? normalized.tool_calls : [];
|
|
27801
|
+
for (const toolCall of toolCalls) {
|
|
27802
|
+
if (!isObject(toolCall) || !isObject(toolCall.function)) {
|
|
27803
|
+
continue;
|
|
27804
|
+
}
|
|
27805
|
+
const name = toolCall.function.name;
|
|
27806
|
+
const id = toolCall.id;
|
|
27807
|
+
if (typeof name === "string" && typeof id === "string") {
|
|
27808
|
+
const ids = pendingToolCallIds.get(name) ?? [];
|
|
27809
|
+
ids.push(id);
|
|
27810
|
+
pendingToolCallIds.set(name, ids);
|
|
27811
|
+
}
|
|
27812
|
+
}
|
|
27813
|
+
}
|
|
27814
|
+
return normalized ? [normalized] : [];
|
|
27815
|
+
});
|
|
27816
|
+
}
|
|
27817
|
+
function normalizeToolDefinition(tool) {
|
|
27818
|
+
const fn = tool.function;
|
|
27819
|
+
if (!fn || typeof fn.name !== "string" || fn.name.length === 0) {
|
|
27820
|
+
return void 0;
|
|
27821
|
+
}
|
|
27822
|
+
return {
|
|
27823
|
+
type: "function",
|
|
27824
|
+
function: {
|
|
27825
|
+
name: fn.name,
|
|
27826
|
+
...typeof fn.description === "string" ? { description: fn.description } : {},
|
|
27827
|
+
...isObject(fn.parameters) ? { parameters: fn.parameters } : {}
|
|
27828
|
+
}
|
|
27829
|
+
};
|
|
27830
|
+
}
|
|
27831
|
+
function extractToolsMetadata(tools) {
|
|
27832
|
+
if (!Array.isArray(tools)) {
|
|
27833
|
+
return {};
|
|
27834
|
+
}
|
|
27835
|
+
const normalized = tools.flatMap((tool) => {
|
|
27836
|
+
if (!isObject(tool)) {
|
|
27837
|
+
return [];
|
|
27838
|
+
}
|
|
27839
|
+
const definition = normalizeToolDefinition(tool);
|
|
27840
|
+
return definition ? [definition] : [];
|
|
27841
|
+
});
|
|
27842
|
+
return normalized.length > 0 ? { tools: normalized } : {};
|
|
27843
|
+
}
|
|
27844
|
+
function extractOptionsMetadata(options) {
|
|
27845
|
+
if (!isObject(options)) {
|
|
27846
|
+
return {};
|
|
27847
|
+
}
|
|
27848
|
+
const metadata = {};
|
|
27849
|
+
const mappings = [
|
|
27850
|
+
["temperature", "temperature"],
|
|
27851
|
+
["top_p", "top_p"],
|
|
27852
|
+
["num_predict", "max_tokens"],
|
|
27853
|
+
["frequency_penalty", "frequency_penalty"],
|
|
27854
|
+
["presence_penalty", "presence_penalty"],
|
|
27855
|
+
["stop", "stop"]
|
|
27856
|
+
];
|
|
27857
|
+
for (const [source, target] of mappings) {
|
|
27858
|
+
if (options[source] !== void 0) {
|
|
27859
|
+
metadata[target] = options[source];
|
|
27860
|
+
}
|
|
27861
|
+
}
|
|
27862
|
+
return metadata;
|
|
27863
|
+
}
|
|
27864
|
+
function extractRequestMetadata(request) {
|
|
27865
|
+
return {
|
|
27866
|
+
provider: "ollama",
|
|
27867
|
+
...typeof request?.model === "string" ? { model: request.model } : {},
|
|
27868
|
+
...extractOptionsMetadata(request?.options),
|
|
27869
|
+
...request?.format !== void 0 ? { response_format: request.format } : {}
|
|
27870
|
+
};
|
|
27871
|
+
}
|
|
27872
|
+
function extractOllamaChatInput([request]) {
|
|
27873
|
+
return {
|
|
27874
|
+
input: normalizeMessages(request.messages),
|
|
27875
|
+
metadata: {
|
|
27876
|
+
...extractRequestMetadata(request),
|
|
27877
|
+
...extractToolsMetadata(request.tools)
|
|
27878
|
+
}
|
|
27879
|
+
};
|
|
27880
|
+
}
|
|
27881
|
+
function extractOllamaGenerateInput([request]) {
|
|
27882
|
+
const normalizedPrompt = normalizeTextAndImages(
|
|
27883
|
+
typeof request.prompt === "string" ? request.prompt : "",
|
|
27884
|
+
Array.isArray(request.images) ? request.images : void 0
|
|
27885
|
+
);
|
|
27886
|
+
const input = [
|
|
27887
|
+
...typeof request.system === "string" ? [{ role: "system", content: request.system }] : [],
|
|
27888
|
+
{
|
|
27889
|
+
role: "user",
|
|
27890
|
+
content: normalizedPrompt.content,
|
|
27891
|
+
...typeof request.suffix === "string" ? { suffix: request.suffix } : {},
|
|
27892
|
+
...normalizedPrompt.unrecognizedImages ? { images: normalizedPrompt.unrecognizedImages } : {}
|
|
27893
|
+
}
|
|
27894
|
+
];
|
|
27895
|
+
return {
|
|
27896
|
+
input,
|
|
27897
|
+
metadata: extractRequestMetadata(request)
|
|
27898
|
+
};
|
|
27899
|
+
}
|
|
27900
|
+
function extractOllamaEmbedInput([request]) {
|
|
27901
|
+
return {
|
|
27902
|
+
input: request.input,
|
|
27903
|
+
metadata: extractRequestMetadata(request)
|
|
27904
|
+
};
|
|
27905
|
+
}
|
|
27906
|
+
function extractOllamaChatOutput(result, syntheticToolCallIdOffset = 0) {
|
|
27907
|
+
if (!isObject(result) || !isObject(result.message)) {
|
|
27908
|
+
return void 0;
|
|
27909
|
+
}
|
|
27910
|
+
const message = normalizeMessage(
|
|
27911
|
+
result.message,
|
|
27912
|
+
void 0,
|
|
27913
|
+
syntheticToolCallIdOffset
|
|
27914
|
+
);
|
|
27915
|
+
if (!message) {
|
|
27916
|
+
return void 0;
|
|
27917
|
+
}
|
|
27918
|
+
const toolCalls = Array.isArray(message.tool_calls) ? message.tool_calls : [];
|
|
27919
|
+
return [
|
|
27920
|
+
{
|
|
27921
|
+
index: 0,
|
|
27922
|
+
finish_reason: normalizeFinishReason(result, toolCalls.length > 0),
|
|
27923
|
+
message
|
|
27924
|
+
}
|
|
27925
|
+
];
|
|
27926
|
+
}
|
|
27927
|
+
function extractOllamaGenerateOutput(result) {
|
|
27928
|
+
if (!isObject(result) || typeof result.response !== "string") {
|
|
27929
|
+
return void 0;
|
|
27930
|
+
}
|
|
27931
|
+
return [
|
|
27932
|
+
{
|
|
27933
|
+
index: 0,
|
|
27934
|
+
finish_reason: normalizeFinishReason(result),
|
|
27935
|
+
message: {
|
|
27936
|
+
role: "assistant",
|
|
27937
|
+
content: result.response,
|
|
27938
|
+
...typeof result.thinking === "string" && result.thinking.length > 0 ? { reasoning: result.thinking } : {}
|
|
27939
|
+
}
|
|
27940
|
+
}
|
|
27941
|
+
];
|
|
27942
|
+
}
|
|
27943
|
+
function extractOllamaEmbedOutput(result) {
|
|
27944
|
+
const embedding = Array.isArray(result?.embeddings) ? result.embeddings[0] : void 0;
|
|
27945
|
+
return Array.isArray(embedding) ? { embedding_length: embedding.length } : void 0;
|
|
27946
|
+
}
|
|
27947
|
+
function extractOllamaResponseMetadata(result) {
|
|
27948
|
+
return typeof result?.model === "string" ? { model: result.model } : void 0;
|
|
27949
|
+
}
|
|
27950
|
+
function extractOllamaMetrics(result) {
|
|
27951
|
+
const metrics = {};
|
|
27952
|
+
const promptTokens = result?.prompt_eval_count;
|
|
27953
|
+
const completionTokens = result?.eval_count;
|
|
27954
|
+
if (isNonNegativeNumber(promptTokens)) {
|
|
27955
|
+
metrics.prompt_tokens = promptTokens;
|
|
27956
|
+
}
|
|
27957
|
+
if (isNonNegativeNumber(completionTokens)) {
|
|
27958
|
+
metrics.completion_tokens = completionTokens;
|
|
27959
|
+
}
|
|
27960
|
+
if (isNonNegativeNumber(promptTokens) || isNonNegativeNumber(completionTokens)) {
|
|
27961
|
+
metrics.tokens = (isNonNegativeNumber(promptTokens) ? promptTokens : 0) + (isNonNegativeNumber(completionTokens) ? completionTokens : 0);
|
|
27962
|
+
}
|
|
27963
|
+
return metrics;
|
|
27964
|
+
}
|
|
27965
|
+
function aggregateOllamaChatChunks(chunks, _result, event, _startTime) {
|
|
27966
|
+
const last = chunks.at(-1);
|
|
27967
|
+
const message = {
|
|
27968
|
+
role: "assistant",
|
|
27969
|
+
content: chunks.map((chunk) => chunk.message?.content ?? "").join(""),
|
|
27970
|
+
thinking: chunks.map((chunk) => chunk.message?.thinking ?? "").join(""),
|
|
27971
|
+
tool_calls: chunks.flatMap((chunk) => chunk.message?.tool_calls ?? [])
|
|
27972
|
+
};
|
|
27973
|
+
const response = {
|
|
27974
|
+
...last,
|
|
27975
|
+
message
|
|
27976
|
+
};
|
|
27977
|
+
return {
|
|
27978
|
+
output: extractOllamaChatOutput(
|
|
27979
|
+
response,
|
|
27980
|
+
countOllamaToolCalls(event?.arguments?.[0]?.messages)
|
|
27981
|
+
),
|
|
27982
|
+
metrics: extractOllamaMetrics(last ?? {}),
|
|
27983
|
+
metadata: extractOllamaResponseMetadata(last ?? {})
|
|
27984
|
+
};
|
|
27985
|
+
}
|
|
27986
|
+
function aggregateOllamaGenerateChunks(chunks, _result, _event, _startTime) {
|
|
27987
|
+
const last = chunks.at(-1);
|
|
27988
|
+
const response = {
|
|
27989
|
+
...last,
|
|
27990
|
+
response: chunks.map((chunk) => chunk.response ?? "").join(""),
|
|
27991
|
+
thinking: chunks.map((chunk) => chunk.thinking ?? "").join("")
|
|
27992
|
+
};
|
|
27993
|
+
return {
|
|
27994
|
+
output: extractOllamaGenerateOutput(response),
|
|
27995
|
+
metrics: extractOllamaMetrics(last ?? {}),
|
|
27996
|
+
metadata: extractOllamaResponseMetadata(last ?? {})
|
|
27997
|
+
};
|
|
27998
|
+
}
|
|
27999
|
+
|
|
26733
28000
|
// src/instrumentation/plugins/google-adk-plugin.ts
|
|
26734
28001
|
var GoogleADKPlugin = class extends BasePlugin {
|
|
26735
28002
|
activeRunnerSpans = /* @__PURE__ */ new Map();
|
|
@@ -30406,12 +31673,13 @@ function sanitizeLoggedValue(value, seen = /* @__PURE__ */ new WeakSet(), depth
|
|
|
30406
31673
|
}
|
|
30407
31674
|
|
|
30408
31675
|
// src/instrumentation/plugins/pi-coding-agent-plugin.ts
|
|
30409
|
-
var
|
|
31676
|
+
var piAgentPatchStates = /* @__PURE__ */ new WeakMap();
|
|
31677
|
+
var piAgentEventSubscriptions = /* @__PURE__ */ new WeakSet();
|
|
30410
31678
|
var piPromptContextStore;
|
|
30411
31679
|
var PiCodingAgentPlugin = class extends BasePlugin {
|
|
30412
31680
|
activePromptStates = /* @__PURE__ */ new Set();
|
|
30413
31681
|
onEnable() {
|
|
30414
|
-
this.
|
|
31682
|
+
this.interceptPrompt();
|
|
30415
31683
|
}
|
|
30416
31684
|
onDisable() {
|
|
30417
31685
|
for (const unsubscribe of this.unsubscribers) {
|
|
@@ -30419,65 +31687,74 @@ var PiCodingAgentPlugin = class extends BasePlugin {
|
|
|
30419
31687
|
}
|
|
30420
31688
|
this.unsubscribers = [];
|
|
30421
31689
|
for (const state of [...this.activePromptStates]) {
|
|
30422
|
-
|
|
30423
|
-
logInstrumentationError4("Pi Coding Agent disable cleanup", error);
|
|
30424
|
-
});
|
|
31690
|
+
finishPiPromptRun(state);
|
|
30425
31691
|
}
|
|
30426
31692
|
}
|
|
30427
|
-
|
|
30428
|
-
|
|
30429
|
-
|
|
30430
|
-
|
|
30431
|
-
|
|
30432
|
-
|
|
30433
|
-
|
|
30434
|
-
|
|
30435
|
-
|
|
30436
|
-
|
|
30437
|
-
|
|
30438
|
-
|
|
30439
|
-
|
|
30440
|
-
|
|
30441
|
-
|
|
30442
|
-
|
|
30443
|
-
|
|
30444
|
-
|
|
30445
|
-
|
|
30446
|
-
states.delete(event);
|
|
30447
|
-
state.promptCallEnded = true;
|
|
30448
|
-
if (!state.finalized && state.deferCompletionUntilTurnEnd && !state.turnEnded) {
|
|
30449
|
-
if (!state.sawStreamFn) {
|
|
30450
|
-
state.queued = true;
|
|
30451
|
-
if (!state.streamPatchState.queuedPromptStates.includes(state)) {
|
|
30452
|
-
state.streamPatchState.queuedPromptStates.push(state);
|
|
30453
|
-
}
|
|
31693
|
+
interceptPrompt() {
|
|
31694
|
+
this.unsubscribers.push(
|
|
31695
|
+
piCodingAgentChannels.prompt.intercept(
|
|
31696
|
+
(target, thisArg, args, additional) => {
|
|
31697
|
+
const invokeTarget = () => Reflect.apply(target, thisArg, args);
|
|
31698
|
+
let state;
|
|
31699
|
+
try {
|
|
31700
|
+
state = startPiPromptRun(
|
|
31701
|
+
{
|
|
31702
|
+
...additional,
|
|
31703
|
+
arguments: args,
|
|
31704
|
+
self: thisArg
|
|
31705
|
+
},
|
|
31706
|
+
(finalizedState) => {
|
|
31707
|
+
this.activePromptStates.delete(finalizedState);
|
|
31708
|
+
}
|
|
31709
|
+
);
|
|
31710
|
+
} catch (error) {
|
|
31711
|
+
logInstrumentationError4("Pi Coding Agent prompt start", error);
|
|
30454
31712
|
}
|
|
30455
|
-
|
|
30456
|
-
|
|
30457
|
-
|
|
30458
|
-
|
|
30459
|
-
|
|
30460
|
-
|
|
30461
|
-
|
|
30462
|
-
|
|
31713
|
+
if (!state) {
|
|
31714
|
+
return runWithAutoInstrumentationSuppressed(invokeTarget);
|
|
31715
|
+
}
|
|
31716
|
+
this.activePromptStates.add(state);
|
|
31717
|
+
return promptContextStore().run(
|
|
31718
|
+
state,
|
|
31719
|
+
() => runWithAutoInstrumentationSuppressed(() => {
|
|
31720
|
+
let result;
|
|
31721
|
+
try {
|
|
31722
|
+
result = invokeTarget();
|
|
31723
|
+
} catch (error) {
|
|
31724
|
+
finishPiPromptRun(state, error);
|
|
31725
|
+
throw error;
|
|
31726
|
+
}
|
|
31727
|
+
return Promise.resolve(result).then(
|
|
31728
|
+
(value) => {
|
|
31729
|
+
finishPiPromptCall(state);
|
|
31730
|
+
return value;
|
|
31731
|
+
},
|
|
31732
|
+
(error) => {
|
|
31733
|
+
finishPiPromptRun(state, error);
|
|
31734
|
+
throw error;
|
|
31735
|
+
}
|
|
31736
|
+
);
|
|
31737
|
+
})
|
|
31738
|
+
);
|
|
30463
31739
|
}
|
|
30464
|
-
|
|
30465
|
-
|
|
30466
|
-
}
|
|
30467
|
-
};
|
|
30468
|
-
channel.subscribe(handlers);
|
|
30469
|
-
this.unsubscribers.push(() => {
|
|
30470
|
-
unbindAutoInstrumentationSuppression?.();
|
|
30471
|
-
channel.unsubscribe(handlers);
|
|
30472
|
-
});
|
|
31740
|
+
)
|
|
31741
|
+
);
|
|
30473
31742
|
}
|
|
30474
31743
|
};
|
|
31744
|
+
function finishPiPromptCall(state) {
|
|
31745
|
+
state.promptCallEnded = true;
|
|
31746
|
+
if (state.deferCompletionUntilTurnEnd && !state.turnEnded) {
|
|
31747
|
+
return;
|
|
31748
|
+
}
|
|
31749
|
+
finishPiPromptRun(state);
|
|
31750
|
+
}
|
|
30475
31751
|
function startPiPromptRun(event, onFinalize) {
|
|
30476
31752
|
const session = extractSession(event);
|
|
30477
31753
|
const agent = session?.agent;
|
|
30478
31754
|
if (!session || !isPiAgent(agent)) {
|
|
30479
31755
|
return void 0;
|
|
30480
31756
|
}
|
|
31757
|
+
installPiAgentInstrumentation(agent);
|
|
30481
31758
|
const metadata = {
|
|
30482
31759
|
...extractSessionMetadata(session),
|
|
30483
31760
|
...extractPromptOptionsMetadata(event.arguments[1]),
|
|
@@ -30499,9 +31776,7 @@ function startPiPromptRun(event, onFinalize) {
|
|
|
30499
31776
|
INSTRUMENTATION_NAMES.PI_CODING_AGENT
|
|
30500
31777
|
)
|
|
30501
31778
|
);
|
|
30502
|
-
const streamPatchState = installPiStreamPatch(agent);
|
|
30503
31779
|
const options = event.arguments[1];
|
|
30504
|
-
const promptText = event.arguments[0];
|
|
30505
31780
|
const state = {
|
|
30506
31781
|
activeLlmSpans: /* @__PURE__ */ new Set(),
|
|
30507
31782
|
activeToolSpans: /* @__PURE__ */ new Map(),
|
|
@@ -30513,29 +31788,10 @@ function startPiPromptRun(event, onFinalize) {
|
|
|
30513
31788
|
metrics: {},
|
|
30514
31789
|
onFinalize,
|
|
30515
31790
|
promptCallEnded: false,
|
|
30516
|
-
...typeof promptText === "string" ? { promptText } : {},
|
|
30517
|
-
queued: false,
|
|
30518
31791
|
span,
|
|
30519
|
-
sawStreamFn: false,
|
|
30520
31792
|
startTime: getCurrentUnixTimestamp(),
|
|
30521
|
-
streamPatchState,
|
|
30522
31793
|
turnEnded: false
|
|
30523
31794
|
};
|
|
30524
|
-
state.restorePromptContext = enterPiPromptContext(state);
|
|
30525
|
-
streamPatchState.activePromptStates.add(state);
|
|
30526
|
-
try {
|
|
30527
|
-
state.unsubscribeAgent = agent.subscribe(async (agentEvent) => {
|
|
30528
|
-
try {
|
|
30529
|
-
await runWithAutoInstrumentationSuppressed(
|
|
30530
|
-
() => handlePiAgentEvent(state, agentEvent)
|
|
30531
|
-
);
|
|
30532
|
-
} catch (error) {
|
|
30533
|
-
logInstrumentationError4("Pi Coding Agent event", error);
|
|
30534
|
-
}
|
|
30535
|
-
});
|
|
30536
|
-
} catch (error) {
|
|
30537
|
-
logInstrumentationError4("Pi Coding Agent event subscription", error);
|
|
30538
|
-
}
|
|
30539
31795
|
return state;
|
|
30540
31796
|
}
|
|
30541
31797
|
function extractSession(event) {
|
|
@@ -30549,111 +31805,55 @@ function promptContextStore() {
|
|
|
30549
31805
|
piPromptContextStore ??= isomorph_default.newAsyncLocalStorage();
|
|
30550
31806
|
return piPromptContextStore;
|
|
30551
31807
|
}
|
|
30552
|
-
function currentPromptContextFrames() {
|
|
30553
|
-
return promptContextStore().getStore()?.frames ?? [];
|
|
30554
|
-
}
|
|
30555
31808
|
function currentPiPromptState() {
|
|
30556
|
-
|
|
30557
|
-
|
|
30558
|
-
|
|
30559
|
-
|
|
30560
|
-
|
|
30561
|
-
|
|
30562
|
-
|
|
30563
|
-
|
|
30564
|
-
|
|
30565
|
-
|
|
30566
|
-
|
|
30567
|
-
|
|
30568
|
-
const frames = currentPromptContextFrames().filter(
|
|
30569
|
-
(candidate) => candidate.id !== frame.id
|
|
30570
|
-
);
|
|
30571
|
-
promptContextStore().enterWith(frames.length > 0 ? { frames } : void 0);
|
|
30572
|
-
};
|
|
30573
|
-
}
|
|
30574
|
-
function installPiStreamPatch(agent) {
|
|
30575
|
-
const existing = piStreamPatchStates.get(agent);
|
|
30576
|
-
if (existing) {
|
|
30577
|
-
if (agent.streamFn !== existing.wrappedStreamFn) {
|
|
30578
|
-
debugLogger.debug(
|
|
30579
|
-
"Pi Coding Agent streamFn changed while Braintrust instrumentation was active; preserving existing patch state."
|
|
30580
|
-
);
|
|
30581
|
-
}
|
|
30582
|
-
return existing;
|
|
30583
|
-
}
|
|
30584
|
-
const patchState = {
|
|
30585
|
-
activePromptStates: /* @__PURE__ */ new Set(),
|
|
30586
|
-
agent,
|
|
30587
|
-
originalStreamFn: agent.streamFn,
|
|
30588
|
-
queuedPromptStates: [],
|
|
30589
|
-
wrappedStreamFn: agent.streamFn
|
|
30590
|
-
};
|
|
30591
|
-
patchState.wrappedStreamFn = makeSharedInstrumentedStreamFn(patchState);
|
|
30592
|
-
agent.streamFn = patchState.wrappedStreamFn;
|
|
30593
|
-
piStreamPatchStates.set(agent, patchState);
|
|
30594
|
-
return patchState;
|
|
30595
|
-
}
|
|
30596
|
-
function resolveStreamPromptState(patchState, context) {
|
|
30597
|
-
let lastUserText;
|
|
30598
|
-
if (Array.isArray(context.messages)) {
|
|
30599
|
-
for (let i = context.messages.length - 1; i >= 0; i--) {
|
|
30600
|
-
const message = context.messages[i];
|
|
30601
|
-
if (isPiUserMessage(message)) {
|
|
30602
|
-
if (typeof message.content === "string") {
|
|
30603
|
-
lastUserText = message.content;
|
|
30604
|
-
} else {
|
|
30605
|
-
lastUserText = message.content.flatMap((part) => part.type === "text" ? [part.text] : []).join("");
|
|
30606
|
-
}
|
|
30607
|
-
break;
|
|
30608
|
-
}
|
|
30609
|
-
}
|
|
30610
|
-
}
|
|
30611
|
-
if (lastUserText !== void 0) {
|
|
30612
|
-
const queuedMatch = patchState.queuedPromptStates.find(
|
|
30613
|
-
(state) => state.promptText === lastUserText
|
|
30614
|
-
);
|
|
30615
|
-
if (queuedMatch) {
|
|
30616
|
-
return queuedMatch;
|
|
30617
|
-
}
|
|
30618
|
-
const matches = [...patchState.activePromptStates].filter(
|
|
30619
|
-
(state) => state.promptText === lastUserText
|
|
31809
|
+
return promptContextStore().getStore();
|
|
31810
|
+
}
|
|
31811
|
+
function installPiAgentInstrumentation(agent) {
|
|
31812
|
+
const existing = piAgentPatchStates.get(agent);
|
|
31813
|
+
if (!existing || agent.streamFn !== existing.wrappedStreamFn) {
|
|
31814
|
+
const patchState = {
|
|
31815
|
+
originalStreamFn: agent.streamFn,
|
|
31816
|
+
wrappedStreamFn: agent.streamFn
|
|
31817
|
+
};
|
|
31818
|
+
patchState.wrappedStreamFn = makeInstrumentedStreamFn(
|
|
31819
|
+
agent,
|
|
31820
|
+
patchState.originalStreamFn
|
|
30620
31821
|
);
|
|
30621
|
-
|
|
30622
|
-
|
|
30623
|
-
}
|
|
31822
|
+
agent.streamFn = patchState.wrappedStreamFn;
|
|
31823
|
+
piAgentPatchStates.set(agent, patchState);
|
|
30624
31824
|
}
|
|
30625
|
-
|
|
30626
|
-
|
|
30627
|
-
return contextState;
|
|
31825
|
+
if (piAgentEventSubscriptions.has(agent)) {
|
|
31826
|
+
return;
|
|
30628
31827
|
}
|
|
30629
|
-
|
|
30630
|
-
|
|
31828
|
+
try {
|
|
31829
|
+
agent.subscribe(async (event) => {
|
|
31830
|
+
const state = currentPiPromptState();
|
|
31831
|
+
if (!state || state.agent !== agent || state.finalized) {
|
|
31832
|
+
return;
|
|
31833
|
+
}
|
|
31834
|
+
try {
|
|
31835
|
+
await runWithAutoInstrumentationSuppressed(
|
|
31836
|
+
() => handlePiAgentEvent(state, event)
|
|
31837
|
+
);
|
|
31838
|
+
} catch (error) {
|
|
31839
|
+
logInstrumentationError4("Pi Coding Agent event", error);
|
|
31840
|
+
}
|
|
31841
|
+
});
|
|
31842
|
+
piAgentEventSubscriptions.add(agent);
|
|
31843
|
+
} catch (error) {
|
|
31844
|
+
logInstrumentationError4("Pi Coding Agent event subscription", error);
|
|
30631
31845
|
}
|
|
30632
|
-
return void 0;
|
|
30633
31846
|
}
|
|
30634
|
-
function
|
|
31847
|
+
function makeInstrumentedStreamFn(agent, originalStreamFn) {
|
|
30635
31848
|
return async function instrumentedPiStreamFn(model, context, options) {
|
|
30636
|
-
const
|
|
30637
|
-
|
|
30638
|
-
|
|
30639
|
-
|
|
30640
|
-
context,
|
|
30641
|
-
options
|
|
30642
|
-
]);
|
|
30643
|
-
return patchState.activePromptStates.size > 0 ? runWithAutoInstrumentationSuppressed(invokeOriginal) : invokeOriginal();
|
|
31849
|
+
const invokeOriginal = () => Reflect.apply(originalStreamFn, this, [model, context, options]);
|
|
31850
|
+
const state = currentPiPromptState();
|
|
31851
|
+
if (!state || state.agent !== agent || state.finalized) {
|
|
31852
|
+
return invokeOriginal();
|
|
30644
31853
|
}
|
|
30645
|
-
state.sawStreamFn = true;
|
|
30646
|
-
removeQueuedPromptState(state);
|
|
30647
|
-
state.streamPatchState.eventPromptState = state;
|
|
30648
31854
|
const llmState = await startPiLlmSpan(state, model, context, options);
|
|
30649
31855
|
try {
|
|
30650
|
-
const stream = await runWithAutoInstrumentationSuppressed(
|
|
30651
|
-
() => Reflect.apply(patchState.originalStreamFn, this, [
|
|
30652
|
-
model,
|
|
30653
|
-
context,
|
|
30654
|
-
options
|
|
30655
|
-
])
|
|
30656
|
-
);
|
|
31856
|
+
const stream = await runWithAutoInstrumentationSuppressed(invokeOriginal);
|
|
30657
31857
|
return patchAssistantMessageStream(stream, state, llmState);
|
|
30658
31858
|
} catch (error) {
|
|
30659
31859
|
finishPiLlmSpan(state, llmState, void 0, error);
|
|
@@ -30800,13 +32000,6 @@ async function handlePiAgentEvent(state, event) {
|
|
|
30800
32000
|
if (state.finalized) {
|
|
30801
32001
|
return;
|
|
30802
32002
|
}
|
|
30803
|
-
const eventPromptState = state.streamPatchState.eventPromptState;
|
|
30804
|
-
if (eventPromptState && eventPromptState !== state) {
|
|
30805
|
-
return;
|
|
30806
|
-
}
|
|
30807
|
-
if (!eventPromptState && (state.queued || state.streamPatchState.activePromptStates.size > 1 && currentPiPromptState() !== state)) {
|
|
30808
|
-
return;
|
|
30809
|
-
}
|
|
30810
32003
|
switch (event.type) {
|
|
30811
32004
|
case "message_end":
|
|
30812
32005
|
if (isPiAssistantMessage(event.message)) {
|
|
@@ -30821,11 +32014,8 @@ async function handlePiAgentEvent(state, event) {
|
|
|
30821
32014
|
addMetrics(state.metrics, extractUsageMetrics2(event.message.usage));
|
|
30822
32015
|
}
|
|
30823
32016
|
}
|
|
30824
|
-
if (state.streamPatchState.eventPromptState === state) {
|
|
30825
|
-
state.streamPatchState.eventPromptState = void 0;
|
|
30826
|
-
}
|
|
30827
32017
|
if (state.promptCallEnded && state.deferCompletionUntilTurnEnd) {
|
|
30828
|
-
|
|
32018
|
+
finishPiPromptRun(state);
|
|
30829
32019
|
}
|
|
30830
32020
|
return;
|
|
30831
32021
|
case "tool_execution_start":
|
|
@@ -30898,19 +32088,13 @@ function finishPiToolSpan(state, event) {
|
|
|
30898
32088
|
}
|
|
30899
32089
|
}
|
|
30900
32090
|
}
|
|
30901
|
-
|
|
32091
|
+
function finishPiPromptRun(state, error) {
|
|
30902
32092
|
if (state.finalized) {
|
|
30903
32093
|
return;
|
|
30904
32094
|
}
|
|
30905
32095
|
state.finalized = true;
|
|
30906
32096
|
state.onFinalize?.(state);
|
|
30907
|
-
|
|
30908
|
-
try {
|
|
30909
|
-
state.unsubscribeAgent?.();
|
|
30910
|
-
} catch (unsubscribeError) {
|
|
30911
|
-
logInstrumentationError4("Pi Coding Agent unsubscribe", unsubscribeError);
|
|
30912
|
-
}
|
|
30913
|
-
await finishOpenLlmSpans(state, error);
|
|
32097
|
+
finishOpenLlmSpans(state, error);
|
|
30914
32098
|
finishOpenToolSpans(state, error);
|
|
30915
32099
|
const metadata = {
|
|
30916
32100
|
...state.metadata,
|
|
@@ -30927,34 +32111,14 @@ async function finalizePiPromptRun(state, error) {
|
|
|
30927
32111
|
output: state.output
|
|
30928
32112
|
});
|
|
30929
32113
|
} finally {
|
|
30930
|
-
|
|
30931
|
-
|
|
30932
|
-
}
|
|
30933
|
-
|
|
30934
|
-
|
|
30935
|
-
patchState.activePromptStates.delete(state);
|
|
30936
|
-
removeQueuedPromptState(state);
|
|
30937
|
-
if (patchState.eventPromptState === state) {
|
|
30938
|
-
patchState.eventPromptState = void 0;
|
|
30939
|
-
}
|
|
30940
|
-
state.restorePromptContext?.();
|
|
30941
|
-
if (patchState.activePromptStates.size > 0) {
|
|
30942
|
-
return;
|
|
30943
|
-
}
|
|
30944
|
-
if (patchState.agent.streamFn === patchState.wrappedStreamFn) {
|
|
30945
|
-
patchState.agent.streamFn = patchState.originalStreamFn;
|
|
30946
|
-
}
|
|
30947
|
-
piStreamPatchStates.delete(patchState.agent);
|
|
30948
|
-
}
|
|
30949
|
-
function removeQueuedPromptState(state) {
|
|
30950
|
-
state.queued = false;
|
|
30951
|
-
const queuedPromptStates = state.streamPatchState.queuedPromptStates;
|
|
30952
|
-
const index = queuedPromptStates.indexOf(state);
|
|
30953
|
-
if (index >= 0) {
|
|
30954
|
-
queuedPromptStates.splice(index, 1);
|
|
32114
|
+
try {
|
|
32115
|
+
state.span.end();
|
|
32116
|
+
} catch (endError) {
|
|
32117
|
+
logInstrumentationError4("Pi Coding Agent prompt end", endError);
|
|
32118
|
+
}
|
|
30955
32119
|
}
|
|
30956
32120
|
}
|
|
30957
|
-
|
|
32121
|
+
function finishOpenLlmSpans(state, error) {
|
|
30958
32122
|
for (const llmState of [...state.activeLlmSpans]) {
|
|
30959
32123
|
finishPiLlmSpan(state, llmState, void 0, error);
|
|
30960
32124
|
}
|
|
@@ -31035,7 +32199,7 @@ function normalizeAssistantMessage(message) {
|
|
|
31035
32199
|
(part) => part.type === "thinking" && !part.redacted ? [part.thinking] : []
|
|
31036
32200
|
).join("");
|
|
31037
32201
|
const toolCalls = message.content.flatMap(
|
|
31038
|
-
(part) => part.type === "toolCall" ? [
|
|
32202
|
+
(part) => part.type === "toolCall" ? [normalizeToolCall2(part)] : []
|
|
31039
32203
|
);
|
|
31040
32204
|
return {
|
|
31041
32205
|
role: "assistant",
|
|
@@ -31070,13 +32234,13 @@ function normalizeUserContent(content) {
|
|
|
31070
32234
|
return part;
|
|
31071
32235
|
});
|
|
31072
32236
|
}
|
|
31073
|
-
function
|
|
32237
|
+
function normalizeToolCall2(toolCall) {
|
|
31074
32238
|
return {
|
|
31075
32239
|
id: toolCall.id,
|
|
31076
32240
|
type: "function",
|
|
31077
32241
|
function: {
|
|
31078
32242
|
name: toolCall.name,
|
|
31079
|
-
arguments:
|
|
32243
|
+
arguments: stringifyArguments2(toolCall.arguments)
|
|
31080
32244
|
}
|
|
31081
32245
|
};
|
|
31082
32246
|
}
|
|
@@ -31259,7 +32423,7 @@ function cleanMetrics5(metrics) {
|
|
|
31259
32423
|
}
|
|
31260
32424
|
return cleaned;
|
|
31261
32425
|
}
|
|
31262
|
-
function
|
|
32426
|
+
function stringifyArguments2(value) {
|
|
31263
32427
|
if (typeof value === "string") {
|
|
31264
32428
|
return value;
|
|
31265
32429
|
}
|
|
@@ -32802,6 +33966,7 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
32802
33966
|
anthropicPlugin = null;
|
|
32803
33967
|
aiSDKPlugin = null;
|
|
32804
33968
|
claudeAgentSDKPlugin = null;
|
|
33969
|
+
cloudflareThinkPlugin = null;
|
|
32805
33970
|
cursorSDKPlugin = null;
|
|
32806
33971
|
openAIAgentsPlugin = null;
|
|
32807
33972
|
googleGenAIPlugin = null;
|
|
@@ -32810,6 +33975,7 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
32810
33975
|
openRouterPlugin = null;
|
|
32811
33976
|
openRouterAgentPlugin = null;
|
|
32812
33977
|
mistralPlugin = null;
|
|
33978
|
+
ollamaPlugin = null;
|
|
32813
33979
|
googleADKPlugin = null;
|
|
32814
33980
|
coherePlugin = null;
|
|
32815
33981
|
groqPlugin = null;
|
|
@@ -32849,6 +34015,10 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
32849
34015
|
this.claudeAgentSDKPlugin = new ClaudeAgentSDKPlugin();
|
|
32850
34016
|
this.claudeAgentSDKPlugin.enable();
|
|
32851
34017
|
}
|
|
34018
|
+
if (integrations.cloudflareThink !== false) {
|
|
34019
|
+
this.cloudflareThinkPlugin = new CloudflareThinkPlugin();
|
|
34020
|
+
this.cloudflareThinkPlugin.enable();
|
|
34021
|
+
}
|
|
32852
34022
|
if (integrations.cursorSDK !== false && integrations.cursor !== false) {
|
|
32853
34023
|
this.cursorSDKPlugin = new CursorSDKPlugin();
|
|
32854
34024
|
this.cursorSDKPlugin.enable();
|
|
@@ -32879,6 +34049,10 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
32879
34049
|
this.mistralPlugin = new MistralPlugin();
|
|
32880
34050
|
this.mistralPlugin.enable();
|
|
32881
34051
|
}
|
|
34052
|
+
if (integrations.ollama !== false) {
|
|
34053
|
+
this.ollamaPlugin = new OllamaPlugin();
|
|
34054
|
+
this.ollamaPlugin.enable();
|
|
34055
|
+
}
|
|
32882
34056
|
if (integrations.googleADK !== false) {
|
|
32883
34057
|
this.googleADKPlugin = new GoogleADKPlugin();
|
|
32884
34058
|
this.googleADKPlugin.enable();
|
|
@@ -32955,6 +34129,10 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
32955
34129
|
this.claudeAgentSDKPlugin.disable();
|
|
32956
34130
|
this.claudeAgentSDKPlugin = null;
|
|
32957
34131
|
}
|
|
34132
|
+
if (this.cloudflareThinkPlugin) {
|
|
34133
|
+
this.cloudflareThinkPlugin.disable();
|
|
34134
|
+
this.cloudflareThinkPlugin = null;
|
|
34135
|
+
}
|
|
32958
34136
|
if (this.cursorSDKPlugin) {
|
|
32959
34137
|
this.cursorSDKPlugin.disable();
|
|
32960
34138
|
this.cursorSDKPlugin = null;
|
|
@@ -32987,6 +34165,10 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
32987
34165
|
this.mistralPlugin.disable();
|
|
32988
34166
|
this.mistralPlugin = null;
|
|
32989
34167
|
}
|
|
34168
|
+
if (this.ollamaPlugin) {
|
|
34169
|
+
this.ollamaPlugin.disable();
|
|
34170
|
+
this.ollamaPlugin = null;
|
|
34171
|
+
}
|
|
32990
34172
|
if (this.googleADKPlugin) {
|
|
32991
34173
|
this.googleADKPlugin.disable();
|
|
32992
34174
|
this.googleADKPlugin = null;
|
|
@@ -33872,6 +35054,7 @@ export {
|
|
|
33872
35054
|
parseCachedHeader,
|
|
33873
35055
|
finalizeAnthropicTokens,
|
|
33874
35056
|
extractAnthropicCacheTokens,
|
|
35057
|
+
collectAnthropicSession,
|
|
33875
35058
|
zodToJsonSchema,
|
|
33876
35059
|
currentWorkflowAgentWrapperSpan,
|
|
33877
35060
|
braintrustAISDKTelemetry,
|