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
package/dist/cli.js
CHANGED
|
@@ -1236,7 +1236,7 @@ var require_package = __commonJS({
|
|
|
1236
1236
|
"package.json"(exports2, module2) {
|
|
1237
1237
|
module2.exports = {
|
|
1238
1238
|
name: "braintrust",
|
|
1239
|
-
version: "3.
|
|
1239
|
+
version: "3.27.0",
|
|
1240
1240
|
description: "SDK for integrating Braintrust",
|
|
1241
1241
|
repository: {
|
|
1242
1242
|
type: "git",
|
|
@@ -1528,8 +1528,10 @@ var GLOBAL_INSTRUMENTATION_HOOKS_KEY = "__braintrust_instrumentation_hooks";
|
|
|
1528
1528
|
var GLOBAL_INSTRUMENTATION_HOOKS_PROTOCOL_VERSION = 1;
|
|
1529
1529
|
var GLOBAL_INSTRUMENTATION_HOOKS_REGISTRY_BRAND = "braintrust.global-instrumentation-hooks.registry";
|
|
1530
1530
|
var GLOBAL_INSTRUMENTATION_HOOK_BRAND = "braintrust.global-instrumentation-hooks.hook";
|
|
1531
|
+
var GLOBAL_INVOCATION_HOOK_BRAND = "braintrust.global-instrumentation-hooks.invocation-hook";
|
|
1531
1532
|
var registryBrand = Symbol.for(GLOBAL_INSTRUMENTATION_HOOKS_REGISTRY_BRAND);
|
|
1532
1533
|
var hookBrand = Symbol.for(GLOBAL_INSTRUMENTATION_HOOK_BRAND);
|
|
1534
|
+
var invocationHookBrand = Symbol.for(GLOBAL_INVOCATION_HOOK_BRAND);
|
|
1533
1535
|
var errorReporter;
|
|
1534
1536
|
function setGlobalHookErrorReporter(reporter) {
|
|
1535
1537
|
const previousReporter = errorReporter;
|
|
@@ -1674,12 +1676,69 @@ var traceEvents = [
|
|
|
1674
1676
|
"asyncEnd",
|
|
1675
1677
|
"error"
|
|
1676
1678
|
];
|
|
1679
|
+
function traceInvocation(hook, operator, target, thisArg, args, additional, callbackIndex = -1) {
|
|
1680
|
+
const context2 = {
|
|
1681
|
+
...additional,
|
|
1682
|
+
arguments: args,
|
|
1683
|
+
self: thisArg
|
|
1684
|
+
};
|
|
1685
|
+
const invoke2 = () => hook.invoke(target, thisArg, args, additional);
|
|
1686
|
+
if (operator === "traceCallback") {
|
|
1687
|
+
return hook.traceCallback(invoke2, callbackIndex, context2);
|
|
1688
|
+
}
|
|
1689
|
+
if (operator === "tracePromise") {
|
|
1690
|
+
return hook.tracePromise(invoke2, context2);
|
|
1691
|
+
}
|
|
1692
|
+
return hook.traceSync(invoke2, context2);
|
|
1693
|
+
}
|
|
1694
|
+
var InvocationHook = class {
|
|
1695
|
+
interceptors = [];
|
|
1696
|
+
get hasInterceptors() {
|
|
1697
|
+
return this.interceptors.length > 0;
|
|
1698
|
+
}
|
|
1699
|
+
intercept(interceptor) {
|
|
1700
|
+
if (typeof interceptor !== "function") {
|
|
1701
|
+
throw new TypeError("interceptor must be a function");
|
|
1702
|
+
}
|
|
1703
|
+
this.interceptors = [...this.interceptors, interceptor];
|
|
1704
|
+
let active = true;
|
|
1705
|
+
return () => {
|
|
1706
|
+
if (!active) {
|
|
1707
|
+
return;
|
|
1708
|
+
}
|
|
1709
|
+
active = false;
|
|
1710
|
+
const index = this.interceptors.indexOf(interceptor);
|
|
1711
|
+
if (index !== -1) {
|
|
1712
|
+
this.interceptors = [
|
|
1713
|
+
...this.interceptors.slice(0, index),
|
|
1714
|
+
...this.interceptors.slice(index + 1)
|
|
1715
|
+
];
|
|
1716
|
+
}
|
|
1717
|
+
};
|
|
1718
|
+
}
|
|
1719
|
+
invoke(target, thisArg, args, additional) {
|
|
1720
|
+
const interceptors = this.interceptors;
|
|
1721
|
+
if (interceptors.length === 0) {
|
|
1722
|
+
return Reflect.apply(target, thisArg, args);
|
|
1723
|
+
}
|
|
1724
|
+
let next = target;
|
|
1725
|
+
for (let index = interceptors.length - 1; index >= 0; index -= 1) {
|
|
1726
|
+
const interceptor = interceptors[index];
|
|
1727
|
+
const downstream = next;
|
|
1728
|
+
next = function(...nextArgs) {
|
|
1729
|
+
return interceptor(downstream, this, nextArgs, additional);
|
|
1730
|
+
};
|
|
1731
|
+
}
|
|
1732
|
+
return Reflect.apply(next, thisArg, args);
|
|
1733
|
+
}
|
|
1734
|
+
};
|
|
1677
1735
|
var TracingHook = class {
|
|
1678
1736
|
start;
|
|
1679
1737
|
end;
|
|
1680
1738
|
asyncStart;
|
|
1681
1739
|
asyncEnd;
|
|
1682
1740
|
error;
|
|
1741
|
+
invocationHook = new InvocationHook();
|
|
1683
1742
|
constructor(nameOrChannels) {
|
|
1684
1743
|
Object.defineProperty(this, hookBrand, {
|
|
1685
1744
|
configurable: false,
|
|
@@ -1687,6 +1746,12 @@ var TracingHook = class {
|
|
|
1687
1746
|
value: GLOBAL_INSTRUMENTATION_HOOKS_PROTOCOL_VERSION,
|
|
1688
1747
|
writable: false
|
|
1689
1748
|
});
|
|
1749
|
+
Object.defineProperty(this, invocationHookBrand, {
|
|
1750
|
+
configurable: false,
|
|
1751
|
+
enumerable: false,
|
|
1752
|
+
value: GLOBAL_INSTRUMENTATION_HOOKS_PROTOCOL_VERSION,
|
|
1753
|
+
writable: false
|
|
1754
|
+
});
|
|
1690
1755
|
if (typeof nameOrChannels === "string") {
|
|
1691
1756
|
this.start = new HookChannel(`tracing:${nameOrChannels}:start`);
|
|
1692
1757
|
this.end = new HookChannel(`tracing:${nameOrChannels}:end`);
|
|
@@ -1704,6 +1769,26 @@ var TracingHook = class {
|
|
|
1704
1769
|
get hasSubscribers() {
|
|
1705
1770
|
return this.start.hasSubscribers || this.end.hasSubscribers || this.asyncStart.hasSubscribers || this.asyncEnd.hasSubscribers || this.error.hasSubscribers;
|
|
1706
1771
|
}
|
|
1772
|
+
get hasInterceptors() {
|
|
1773
|
+
return this.invocationHook.hasInterceptors;
|
|
1774
|
+
}
|
|
1775
|
+
intercept(interceptor) {
|
|
1776
|
+
return this.invocationHook.intercept(interceptor);
|
|
1777
|
+
}
|
|
1778
|
+
invoke(target, thisArg, args, additional) {
|
|
1779
|
+
return this.invocationHook.invoke(target, thisArg, args, additional);
|
|
1780
|
+
}
|
|
1781
|
+
traceInvocation(operator, target, thisArg, args, additional, callbackIndex = -1) {
|
|
1782
|
+
return traceInvocation(
|
|
1783
|
+
this,
|
|
1784
|
+
operator,
|
|
1785
|
+
target,
|
|
1786
|
+
thisArg,
|
|
1787
|
+
args,
|
|
1788
|
+
additional,
|
|
1789
|
+
callbackIndex
|
|
1790
|
+
);
|
|
1791
|
+
}
|
|
1707
1792
|
subscribe(handlers) {
|
|
1708
1793
|
for (const eventName of traceEvents) {
|
|
1709
1794
|
const handler = handlers[eventName];
|
|
@@ -1925,6 +2010,60 @@ function hasTracingHookShape(value) {
|
|
|
1925
2010
|
return false;
|
|
1926
2011
|
}
|
|
1927
2012
|
}
|
|
2013
|
+
function hasInvocationHookShape(value) {
|
|
2014
|
+
if (typeof value !== "object" && typeof value !== "function" || value === null) {
|
|
2015
|
+
return false;
|
|
2016
|
+
}
|
|
2017
|
+
try {
|
|
2018
|
+
const hook = value;
|
|
2019
|
+
return value[invocationHookBrand] === GLOBAL_INSTRUMENTATION_HOOKS_PROTOCOL_VERSION && typeof hook.hasInterceptors === "boolean" && typeof hook.intercept === "function" && typeof hook.invoke === "function";
|
|
2020
|
+
} catch {
|
|
2021
|
+
return false;
|
|
2022
|
+
}
|
|
2023
|
+
}
|
|
2024
|
+
function installInvocationHook(value) {
|
|
2025
|
+
const hasInvocationHook = hasInvocationHookShape(value);
|
|
2026
|
+
const invocationHook = new InvocationHook();
|
|
2027
|
+
try {
|
|
2028
|
+
if (!hasInvocationHook) {
|
|
2029
|
+
Object.defineProperties(value, {
|
|
2030
|
+
[invocationHookBrand]: {
|
|
2031
|
+
configurable: false,
|
|
2032
|
+
enumerable: false,
|
|
2033
|
+
value: GLOBAL_INSTRUMENTATION_HOOKS_PROTOCOL_VERSION,
|
|
2034
|
+
writable: false
|
|
2035
|
+
},
|
|
2036
|
+
hasInterceptors: {
|
|
2037
|
+
configurable: false,
|
|
2038
|
+
enumerable: false,
|
|
2039
|
+
get: () => invocationHook.hasInterceptors
|
|
2040
|
+
},
|
|
2041
|
+
intercept: {
|
|
2042
|
+
configurable: false,
|
|
2043
|
+
enumerable: false,
|
|
2044
|
+
value: invocationHook.intercept.bind(invocationHook),
|
|
2045
|
+
writable: false
|
|
2046
|
+
},
|
|
2047
|
+
invoke: {
|
|
2048
|
+
configurable: false,
|
|
2049
|
+
enumerable: false,
|
|
2050
|
+
value: invocationHook.invoke.bind(invocationHook),
|
|
2051
|
+
writable: false
|
|
2052
|
+
}
|
|
2053
|
+
});
|
|
2054
|
+
}
|
|
2055
|
+
if (typeof value.traceInvocation !== "function") {
|
|
2056
|
+
Object.defineProperty(value, "traceInvocation", {
|
|
2057
|
+
configurable: false,
|
|
2058
|
+
enumerable: false,
|
|
2059
|
+
value: traceInvocation.bind(void 0, value),
|
|
2060
|
+
writable: false
|
|
2061
|
+
});
|
|
2062
|
+
}
|
|
2063
|
+
} catch (error2) {
|
|
2064
|
+
reportError(error2);
|
|
2065
|
+
}
|
|
2066
|
+
}
|
|
1928
2067
|
function isCompatibleTracingHook(value) {
|
|
1929
2068
|
try {
|
|
1930
2069
|
return value[hookBrand] === GLOBAL_INSTRUMENTATION_HOOKS_PROTOCOL_VERSION && hasTracingHookShape(value);
|
|
@@ -2011,6 +2150,7 @@ function newGlobalTracingChannel(nameOrChannels) {
|
|
|
2011
2150
|
return inertTracingHook;
|
|
2012
2151
|
}
|
|
2013
2152
|
if (isCompatibleTracingHook(existing)) {
|
|
2153
|
+
installInvocationHook(existing);
|
|
2014
2154
|
return existing;
|
|
2015
2155
|
}
|
|
2016
2156
|
if (existing !== void 0) {
|
|
@@ -6866,6 +7006,7 @@ var INSTRUMENTATION_NAMES = {
|
|
|
6866
7006
|
CLAUDE_AGENT_SDK: "claude-agent-sdk",
|
|
6867
7007
|
CLOUDFLARE_AI_CHAT: "cloudflare-ai-chat",
|
|
6868
7008
|
CLOUDFLARE_AGENTS: "cloudflare-agents",
|
|
7009
|
+
CLOUDFLARE_THINK: "cloudflare-think",
|
|
6869
7010
|
COHERE: "cohere",
|
|
6870
7011
|
CURSOR_SDK: "cursor-sdk",
|
|
6871
7012
|
EVE: "eve",
|
|
@@ -6880,6 +7021,7 @@ var INSTRUMENTATION_NAMES = {
|
|
|
6880
7021
|
LANGSMITH: "langsmith",
|
|
6881
7022
|
MASTRA: "mastra",
|
|
6882
7023
|
MISTRAL: "mistral",
|
|
7024
|
+
OLLAMA: "ollama",
|
|
6883
7025
|
OPENAI: "openai",
|
|
6884
7026
|
OPENAI_AGENTS: "openai-agents",
|
|
6885
7027
|
OPENAI_CODEX: "openai-codex",
|
|
@@ -6891,7 +7033,7 @@ var INSTRUMENTATION_NAMES = {
|
|
|
6891
7033
|
var INTERNAL_SPAN_INSTRUMENTATION_NAME = /* @__PURE__ */ Symbol.for(
|
|
6892
7034
|
"braintrust.spanInstrumentationName"
|
|
6893
7035
|
);
|
|
6894
|
-
var SDK_VERSION = true ? "3.
|
|
7036
|
+
var SDK_VERSION = true ? "3.27.0" : "0.0.0";
|
|
6895
7037
|
function withSpanInstrumentationName(args, instrumentationName) {
|
|
6896
7038
|
return {
|
|
6897
7039
|
...args,
|
|
@@ -15222,6 +15364,34 @@ function patchStreamIfNeeded(stream, options) {
|
|
|
15222
15364
|
);
|
|
15223
15365
|
return stream;
|
|
15224
15366
|
}
|
|
15367
|
+
const chunks = [];
|
|
15368
|
+
let completed = false;
|
|
15369
|
+
const notifyCancellation = async () => {
|
|
15370
|
+
try {
|
|
15371
|
+
await (options.onCancel ?? options.onComplete)(chunks);
|
|
15372
|
+
} catch (error2) {
|
|
15373
|
+
debugLogger.error("Error in stream cancellation handler:", error2);
|
|
15374
|
+
}
|
|
15375
|
+
};
|
|
15376
|
+
const patchAbortIfPresent = () => {
|
|
15377
|
+
try {
|
|
15378
|
+
if ("abort" in stream && typeof stream.abort === "function") {
|
|
15379
|
+
const originalAbort = stream.abort.bind(stream);
|
|
15380
|
+
stream.abort = (...args) => {
|
|
15381
|
+
try {
|
|
15382
|
+
return originalAbort(...args);
|
|
15383
|
+
} finally {
|
|
15384
|
+
if (!completed) {
|
|
15385
|
+
completed = true;
|
|
15386
|
+
void notifyCancellation();
|
|
15387
|
+
}
|
|
15388
|
+
}
|
|
15389
|
+
};
|
|
15390
|
+
}
|
|
15391
|
+
} catch (error2) {
|
|
15392
|
+
debugLogger.warn("Failed to patch stream abort method:", error2);
|
|
15393
|
+
}
|
|
15394
|
+
};
|
|
15225
15395
|
if (hasAsyncIteratorMethods(stream) && isSelfAsyncIterator(stream)) {
|
|
15226
15396
|
if ("__braintrust_patched_iterator_methods" in stream) {
|
|
15227
15397
|
return stream;
|
|
@@ -15230,8 +15400,6 @@ function patchStreamIfNeeded(stream, options) {
|
|
|
15230
15400
|
const originalNext = stream.next.bind(stream);
|
|
15231
15401
|
const originalReturn = typeof stream.return === "function" ? stream.return.bind(stream) : null;
|
|
15232
15402
|
const originalThrow = typeof stream.throw === "function" ? stream.throw.bind(stream) : null;
|
|
15233
|
-
const chunks = [];
|
|
15234
|
-
let completed = false;
|
|
15235
15403
|
stream.next = async (...args) => {
|
|
15236
15404
|
try {
|
|
15237
15405
|
const result = await runNextWithWrapper(
|
|
@@ -15283,11 +15451,7 @@ function patchStreamIfNeeded(stream, options) {
|
|
|
15283
15451
|
stream.return = async (...args) => {
|
|
15284
15452
|
if (!completed) {
|
|
15285
15453
|
completed = true;
|
|
15286
|
-
|
|
15287
|
-
await options.onComplete(chunks);
|
|
15288
|
-
} catch (error2) {
|
|
15289
|
-
console.error("Error in stream onComplete handler:", error2);
|
|
15290
|
-
}
|
|
15454
|
+
await notifyCancellation();
|
|
15291
15455
|
}
|
|
15292
15456
|
return originalReturn(...args);
|
|
15293
15457
|
};
|
|
@@ -15312,6 +15476,7 @@ function patchStreamIfNeeded(stream, options) {
|
|
|
15312
15476
|
Object.defineProperty(stream, "__braintrust_patched_iterator_methods", {
|
|
15313
15477
|
value: true
|
|
15314
15478
|
});
|
|
15479
|
+
patchAbortIfPresent();
|
|
15315
15480
|
return stream;
|
|
15316
15481
|
} catch (error2) {
|
|
15317
15482
|
console.warn("Failed to patch stream iterator methods:", error2);
|
|
@@ -15325,8 +15490,6 @@ function patchStreamIfNeeded(stream, options) {
|
|
|
15325
15490
|
const patchedIteratorFn = function() {
|
|
15326
15491
|
const iterator = originalIteratorFn.call(this);
|
|
15327
15492
|
const originalNext = iterator.next.bind(iterator);
|
|
15328
|
-
const chunks = [];
|
|
15329
|
-
let completed = false;
|
|
15330
15493
|
iterator.next = async function(...args) {
|
|
15331
15494
|
try {
|
|
15332
15495
|
const result = await runNextWithWrapper(
|
|
@@ -15379,11 +15542,7 @@ function patchStreamIfNeeded(stream, options) {
|
|
|
15379
15542
|
iterator.return = async function(...args) {
|
|
15380
15543
|
if (!completed) {
|
|
15381
15544
|
completed = true;
|
|
15382
|
-
|
|
15383
|
-
await options.onComplete(chunks);
|
|
15384
|
-
} catch (error2) {
|
|
15385
|
-
console.error("Error in stream onComplete handler:", error2);
|
|
15386
|
-
}
|
|
15545
|
+
await notifyCancellation();
|
|
15387
15546
|
}
|
|
15388
15547
|
return originalReturn(...args);
|
|
15389
15548
|
};
|
|
@@ -15412,6 +15571,7 @@ function patchStreamIfNeeded(stream, options) {
|
|
|
15412
15571
|
value: true
|
|
15413
15572
|
});
|
|
15414
15573
|
stream[Symbol.asyncIterator] = patchedIteratorFn;
|
|
15574
|
+
patchAbortIfPresent();
|
|
15415
15575
|
return stream;
|
|
15416
15576
|
} catch (error2) {
|
|
15417
15577
|
console.warn("Failed to patch stream:", error2);
|
|
@@ -16160,6 +16320,33 @@ function traceStreamingChannel(channel2, config3) {
|
|
|
16160
16320
|
const { span, startTime } = spanData;
|
|
16161
16321
|
if (isAsyncIterable3(asyncEndEvent.result)) {
|
|
16162
16322
|
let firstChunkTime;
|
|
16323
|
+
const handleStreamError = (error2) => {
|
|
16324
|
+
try {
|
|
16325
|
+
span.log({ error: error2 });
|
|
16326
|
+
} catch (loggingError) {
|
|
16327
|
+
debugLogger.error(
|
|
16328
|
+
`Error logging failure for ${channelName}:`,
|
|
16329
|
+
loggingError
|
|
16330
|
+
);
|
|
16331
|
+
}
|
|
16332
|
+
try {
|
|
16333
|
+
span.end();
|
|
16334
|
+
} catch (endingError) {
|
|
16335
|
+
debugLogger.error(
|
|
16336
|
+
`Error ending span for ${channelName}:`,
|
|
16337
|
+
endingError
|
|
16338
|
+
);
|
|
16339
|
+
}
|
|
16340
|
+
states.delete(event);
|
|
16341
|
+
runStreamingErrorHook({
|
|
16342
|
+
channelName,
|
|
16343
|
+
config: config3,
|
|
16344
|
+
error: error2,
|
|
16345
|
+
event: asyncEndEvent,
|
|
16346
|
+
span,
|
|
16347
|
+
startTime
|
|
16348
|
+
});
|
|
16349
|
+
};
|
|
16163
16350
|
patchStreamIfNeeded(asyncEndEvent.result, {
|
|
16164
16351
|
onChunk: () => {
|
|
16165
16352
|
if (firstChunkTime === void 0) {
|
|
@@ -16239,33 +16426,12 @@ function traceStreamingChannel(channel2, config3) {
|
|
|
16239
16426
|
});
|
|
16240
16427
|
}
|
|
16241
16428
|
},
|
|
16242
|
-
|
|
16243
|
-
|
|
16244
|
-
|
|
16245
|
-
|
|
16246
|
-
|
|
16247
|
-
|
|
16248
|
-
loggingError
|
|
16249
|
-
);
|
|
16250
|
-
}
|
|
16251
|
-
try {
|
|
16252
|
-
span.end();
|
|
16253
|
-
} catch (endingError) {
|
|
16254
|
-
debugLogger.error(
|
|
16255
|
-
`Error ending span for ${channelName}:`,
|
|
16256
|
-
endingError
|
|
16257
|
-
);
|
|
16258
|
-
}
|
|
16259
|
-
states.delete(event);
|
|
16260
|
-
runStreamingErrorHook({
|
|
16261
|
-
channelName,
|
|
16262
|
-
config: config3,
|
|
16263
|
-
error: error2,
|
|
16264
|
-
event: asyncEndEvent,
|
|
16265
|
-
span,
|
|
16266
|
-
startTime
|
|
16267
|
-
});
|
|
16268
|
-
}
|
|
16429
|
+
onCancel: () => {
|
|
16430
|
+
const error2 = new Error("Stream cancelled before completion");
|
|
16431
|
+
error2.name = "AbortError";
|
|
16432
|
+
handleStreamError(error2);
|
|
16433
|
+
},
|
|
16434
|
+
onError: handleStreamError
|
|
16269
16435
|
});
|
|
16270
16436
|
return;
|
|
16271
16437
|
}
|
|
@@ -16653,11 +16819,21 @@ function defineChannels(pkg, channels, options) {
|
|
|
16653
16819
|
const tracingChannel2 = () => isomorph_default.newTracingChannel(
|
|
16654
16820
|
fullChannelName
|
|
16655
16821
|
);
|
|
16822
|
+
const intercept2 = (interceptor) => {
|
|
16823
|
+
const hook = tracingChannel2();
|
|
16824
|
+
return typeof hook.intercept === "function" ? hook.intercept(interceptor) : () => {
|
|
16825
|
+
};
|
|
16826
|
+
};
|
|
16656
16827
|
return [
|
|
16657
16828
|
key,
|
|
16658
16829
|
{
|
|
16659
16830
|
...asyncSpec,
|
|
16660
16831
|
instrumentationName,
|
|
16832
|
+
intercept: intercept2,
|
|
16833
|
+
invoke: (target, thisArg, args, additional) => {
|
|
16834
|
+
const hook = tracingChannel2();
|
|
16835
|
+
return typeof hook.invoke === "function" ? hook.invoke(target, thisArg, args, additional) : Reflect.apply(target, thisArg, args);
|
|
16836
|
+
},
|
|
16661
16837
|
tracingChannel: tracingChannel2,
|
|
16662
16838
|
tracePromise: (fn, context2) => tracingChannel2().tracePromise(
|
|
16663
16839
|
fn,
|
|
@@ -16671,11 +16847,21 @@ function defineChannels(pkg, channels, options) {
|
|
|
16671
16847
|
const tracingChannel = () => isomorph_default.newTracingChannel(
|
|
16672
16848
|
fullChannelName
|
|
16673
16849
|
);
|
|
16850
|
+
const intercept = (interceptor) => {
|
|
16851
|
+
const hook = tracingChannel();
|
|
16852
|
+
return typeof hook.intercept === "function" ? hook.intercept(interceptor) : () => {
|
|
16853
|
+
};
|
|
16854
|
+
};
|
|
16674
16855
|
return [
|
|
16675
16856
|
key,
|
|
16676
16857
|
{
|
|
16677
16858
|
...syncSpec,
|
|
16678
16859
|
instrumentationName,
|
|
16860
|
+
intercept,
|
|
16861
|
+
invoke: (target, thisArg, args, additional) => {
|
|
16862
|
+
const hook = tracingChannel();
|
|
16863
|
+
return typeof hook.invoke === "function" ? hook.invoke(target, thisArg, args, additional) : Reflect.apply(target, thisArg, args);
|
|
16864
|
+
},
|
|
16679
16865
|
tracingChannel,
|
|
16680
16866
|
traceSync: (fn, context2) => tracingChannel().traceSync(
|
|
16681
16867
|
fn,
|
|
@@ -17926,6 +18112,12 @@ function extractAnthropicCacheTokens(cacheReadTokens = 0, cacheCreationTokens =
|
|
|
17926
18112
|
return cacheTokens;
|
|
17927
18113
|
}
|
|
17928
18114
|
|
|
18115
|
+
// src/wrappers/anthropic-session-collector.ts
|
|
18116
|
+
var sessionStreamCollectors = /* @__PURE__ */ new WeakMap();
|
|
18117
|
+
function registerAnthropicSessionStreamCollector(stream, collector) {
|
|
18118
|
+
sessionStreamCollectors.set(stream, collector);
|
|
18119
|
+
}
|
|
18120
|
+
|
|
17929
18121
|
// src/instrumentation/plugins/anthropic-channels.ts
|
|
17930
18122
|
var anthropicChannels = defineChannels(
|
|
17931
18123
|
"@anthropic-ai/sdk",
|
|
@@ -17941,6 +18133,14 @@ var anthropicChannels = defineChannels(
|
|
|
17941
18133
|
betaMessagesToolRunner: channel({
|
|
17942
18134
|
channelName: "beta.messages.toolRunner",
|
|
17943
18135
|
kind: "sync-stream"
|
|
18136
|
+
}),
|
|
18137
|
+
betaSessionsEventsStream: channel({
|
|
18138
|
+
channelName: "beta.sessions.events.stream",
|
|
18139
|
+
kind: "async"
|
|
18140
|
+
}),
|
|
18141
|
+
betaSessionsThreadsEventsStream: channel({
|
|
18142
|
+
channelName: "beta.sessions.threads.events.stream",
|
|
18143
|
+
kind: "async"
|
|
17944
18144
|
})
|
|
17945
18145
|
},
|
|
17946
18146
|
{ instrumentationName: INSTRUMENTATION_NAMES.ANTHROPIC }
|
|
@@ -17954,6 +18154,7 @@ var AnthropicPlugin = class extends BasePlugin {
|
|
|
17954
18154
|
onEnable() {
|
|
17955
18155
|
this.subscribeToAnthropicChannels();
|
|
17956
18156
|
this.subscribeToAnthropicToolRunner();
|
|
18157
|
+
this.subscribeToAnthropicSessionStreams();
|
|
17957
18158
|
}
|
|
17958
18159
|
onDisable() {
|
|
17959
18160
|
this.unsubscribers = unsubscribeAll(this.unsubscribers);
|
|
@@ -18071,7 +18272,411 @@ var AnthropicPlugin = class extends BasePlugin {
|
|
|
18071
18272
|
tracingChannel.unsubscribe(handlers);
|
|
18072
18273
|
});
|
|
18073
18274
|
}
|
|
18275
|
+
subscribeToAnthropicSessionStreams() {
|
|
18276
|
+
this.subscribeToAnthropicSessionStream(
|
|
18277
|
+
anthropicChannels.betaSessionsEventsStream,
|
|
18278
|
+
false
|
|
18279
|
+
);
|
|
18280
|
+
this.subscribeToAnthropicSessionStream(
|
|
18281
|
+
anthropicChannels.betaSessionsThreadsEventsStream,
|
|
18282
|
+
true
|
|
18283
|
+
);
|
|
18284
|
+
}
|
|
18285
|
+
subscribeToAnthropicSessionStream(channel2, isThread) {
|
|
18286
|
+
const tracingChannel = channel2.tracingChannel();
|
|
18287
|
+
const pending = /* @__PURE__ */ new WeakSet();
|
|
18288
|
+
const handlers = {
|
|
18289
|
+
start: (event) => {
|
|
18290
|
+
if (isAutoInstrumentationSuppressed()) {
|
|
18291
|
+
return;
|
|
18292
|
+
}
|
|
18293
|
+
pending.add(event);
|
|
18294
|
+
},
|
|
18295
|
+
asyncEnd: (event) => {
|
|
18296
|
+
if (!pending.delete(event)) {
|
|
18297
|
+
return;
|
|
18298
|
+
}
|
|
18299
|
+
const stream = event.result;
|
|
18300
|
+
if (!isAsyncIterable3(stream)) {
|
|
18301
|
+
return;
|
|
18302
|
+
}
|
|
18303
|
+
registerAnthropicSessionStreamCollector(stream, () => {
|
|
18304
|
+
wrapAnthropicSessionEventStream(stream, isThread);
|
|
18305
|
+
});
|
|
18306
|
+
},
|
|
18307
|
+
error: (event) => {
|
|
18308
|
+
pending.delete(event);
|
|
18309
|
+
}
|
|
18310
|
+
};
|
|
18311
|
+
tracingChannel.subscribe(handlers);
|
|
18312
|
+
this.unsubscribers.push(() => tracingChannel.unsubscribe(handlers));
|
|
18313
|
+
}
|
|
18074
18314
|
};
|
|
18315
|
+
function wrapAnthropicSessionEventStream(stream, isThread) {
|
|
18316
|
+
const state = {
|
|
18317
|
+
history: [],
|
|
18318
|
+
isThread,
|
|
18319
|
+
pendingInput: [],
|
|
18320
|
+
seenEventIds: /* @__PURE__ */ new Set()
|
|
18321
|
+
};
|
|
18322
|
+
patchStreamIfNeeded(stream, {
|
|
18323
|
+
onChunk: (event) => handleAnthropicSessionEvent(state, event),
|
|
18324
|
+
onComplete: () => finalizeAnthropicSessionTurn(state),
|
|
18325
|
+
onError: (error2) => finalizeAnthropicSessionTurn(state, error2)
|
|
18326
|
+
});
|
|
18327
|
+
return stream;
|
|
18328
|
+
}
|
|
18329
|
+
function handleAnthropicSessionEvent(state, event) {
|
|
18330
|
+
try {
|
|
18331
|
+
if (typeof event.id === "string" && event.type !== "event_delta" && state.seenEventIds.has(event.id)) {
|
|
18332
|
+
return;
|
|
18333
|
+
}
|
|
18334
|
+
if (typeof event.id === "string" && event.type !== "event_delta") {
|
|
18335
|
+
state.seenEventIds.add(event.id);
|
|
18336
|
+
}
|
|
18337
|
+
switch (event.type) {
|
|
18338
|
+
case "user.message":
|
|
18339
|
+
case "system.message":
|
|
18340
|
+
recordAnthropicSessionInput(
|
|
18341
|
+
state,
|
|
18342
|
+
event
|
|
18343
|
+
);
|
|
18344
|
+
break;
|
|
18345
|
+
case "session.status_running":
|
|
18346
|
+
if (!state.isThread) {
|
|
18347
|
+
ensureAnthropicSessionTurn(state);
|
|
18348
|
+
}
|
|
18349
|
+
break;
|
|
18350
|
+
case "session.thread_status_running":
|
|
18351
|
+
if (state.isThread) {
|
|
18352
|
+
ensureAnthropicSessionTurn(state);
|
|
18353
|
+
}
|
|
18354
|
+
break;
|
|
18355
|
+
case "span.model_request_start":
|
|
18356
|
+
if (typeof event.id === "string") {
|
|
18357
|
+
startAnthropicSessionModel(state, event.id);
|
|
18358
|
+
}
|
|
18359
|
+
break;
|
|
18360
|
+
case "event_delta":
|
|
18361
|
+
recordAnthropicSessionFirstToken(state, event);
|
|
18362
|
+
break;
|
|
18363
|
+
case "agent.message":
|
|
18364
|
+
recordAnthropicSessionMessage(
|
|
18365
|
+
state,
|
|
18366
|
+
event
|
|
18367
|
+
);
|
|
18368
|
+
break;
|
|
18369
|
+
case "agent.custom_tool_use":
|
|
18370
|
+
case "agent.mcp_tool_use":
|
|
18371
|
+
case "agent.tool_use":
|
|
18372
|
+
startAnthropicSessionTool(state, event);
|
|
18373
|
+
break;
|
|
18374
|
+
case "user.tool_confirmation":
|
|
18375
|
+
recordAnthropicSessionToolConfirmation(state, event);
|
|
18376
|
+
break;
|
|
18377
|
+
case "agent.mcp_tool_result":
|
|
18378
|
+
case "agent.tool_result":
|
|
18379
|
+
case "user.custom_tool_result":
|
|
18380
|
+
case "user.tool_result":
|
|
18381
|
+
finalizeAnthropicSessionTool(
|
|
18382
|
+
state,
|
|
18383
|
+
event
|
|
18384
|
+
);
|
|
18385
|
+
break;
|
|
18386
|
+
case "span.model_request_end":
|
|
18387
|
+
finalizeAnthropicSessionModel(
|
|
18388
|
+
state,
|
|
18389
|
+
event
|
|
18390
|
+
);
|
|
18391
|
+
break;
|
|
18392
|
+
case "session.status_idle":
|
|
18393
|
+
case "session.thread_status_idle": {
|
|
18394
|
+
if (event.type === "session.status_idle" && state.isThread || event.type === "session.thread_status_idle" && !state.isThread) {
|
|
18395
|
+
break;
|
|
18396
|
+
}
|
|
18397
|
+
const stopReason = isObject(event.stop_reason) ? event.stop_reason.type : void 0;
|
|
18398
|
+
if (stopReason === "end_turn") {
|
|
18399
|
+
finalizeAnthropicSessionTurn(state);
|
|
18400
|
+
} else if (stopReason === "retries_exhausted") {
|
|
18401
|
+
finalizeAnthropicSessionTurn(
|
|
18402
|
+
state,
|
|
18403
|
+
"Anthropic session retries exhausted"
|
|
18404
|
+
);
|
|
18405
|
+
}
|
|
18406
|
+
break;
|
|
18407
|
+
}
|
|
18408
|
+
case "session.error":
|
|
18409
|
+
finalizeAnthropicSessionTurn(state, event.error);
|
|
18410
|
+
break;
|
|
18411
|
+
case "session.deleted":
|
|
18412
|
+
case "session.status_terminated":
|
|
18413
|
+
case "session.thread_status_terminated":
|
|
18414
|
+
if (event.type === "session.deleted" || event.type === "session.status_terminated" && !state.isThread || event.type === "session.thread_status_terminated" && state.isThread) {
|
|
18415
|
+
finalizeAnthropicSessionTurn(state);
|
|
18416
|
+
}
|
|
18417
|
+
break;
|
|
18418
|
+
default:
|
|
18419
|
+
break;
|
|
18420
|
+
}
|
|
18421
|
+
} catch (error2) {
|
|
18422
|
+
debugLogger.debug("Error processing Anthropic Sessions event:", error2);
|
|
18423
|
+
}
|
|
18424
|
+
}
|
|
18425
|
+
function ensureAnthropicSessionTurn(state) {
|
|
18426
|
+
if (state.activeTurn) {
|
|
18427
|
+
return state.activeTurn;
|
|
18428
|
+
}
|
|
18429
|
+
const input = state.pendingInput;
|
|
18430
|
+
state.pendingInput = [];
|
|
18431
|
+
const span = startSpan(
|
|
18432
|
+
withSpanInstrumentationName(
|
|
18433
|
+
{
|
|
18434
|
+
event: {
|
|
18435
|
+
...input.length > 0 ? { input } : {},
|
|
18436
|
+
metadata: { provider: "anthropic" }
|
|
18437
|
+
},
|
|
18438
|
+
name: state.isThread ? "anthropic.beta.sessions.thread.turn" : "anthropic.beta.sessions.turn",
|
|
18439
|
+
spanAttributes: { type: "task" /* TASK */ }
|
|
18440
|
+
},
|
|
18441
|
+
INSTRUMENTATION_NAMES.ANTHROPIC
|
|
18442
|
+
)
|
|
18443
|
+
);
|
|
18444
|
+
state.activeTurn = {
|
|
18445
|
+
activeTools: /* @__PURE__ */ new Map(),
|
|
18446
|
+
input: input.slice(),
|
|
18447
|
+
metrics: {},
|
|
18448
|
+
span
|
|
18449
|
+
};
|
|
18450
|
+
return state.activeTurn;
|
|
18451
|
+
}
|
|
18452
|
+
function recordAnthropicSessionInput(state, event) {
|
|
18453
|
+
const content = processAttachmentsInInput(event.content);
|
|
18454
|
+
const message = {
|
|
18455
|
+
role: event.type === "system.message" ? "system" : "user",
|
|
18456
|
+
content
|
|
18457
|
+
};
|
|
18458
|
+
state.history.push(message);
|
|
18459
|
+
if (state.activeTurn) {
|
|
18460
|
+
state.activeTurn.input.push(message);
|
|
18461
|
+
} else {
|
|
18462
|
+
state.pendingInput.push(message);
|
|
18463
|
+
}
|
|
18464
|
+
}
|
|
18465
|
+
function startAnthropicSessionModel(state, startEventId) {
|
|
18466
|
+
const turn = ensureAnthropicSessionTurn(state);
|
|
18467
|
+
if (turn.activeModel) {
|
|
18468
|
+
finalizeAnthropicSessionModelState(state, turn);
|
|
18469
|
+
}
|
|
18470
|
+
const span = withCurrent(
|
|
18471
|
+
turn.span,
|
|
18472
|
+
() => startSpan(
|
|
18473
|
+
withSpanInstrumentationName(
|
|
18474
|
+
{
|
|
18475
|
+
event: {
|
|
18476
|
+
...state.history.length > 0 ? { input: state.history.slice() } : {},
|
|
18477
|
+
metadata: { provider: "anthropic" }
|
|
18478
|
+
},
|
|
18479
|
+
name: "anthropic.messages.create",
|
|
18480
|
+
spanAttributes: { type: "llm" /* LLM */ }
|
|
18481
|
+
},
|
|
18482
|
+
INSTRUMENTATION_NAMES.ANTHROPIC
|
|
18483
|
+
)
|
|
18484
|
+
)
|
|
18485
|
+
);
|
|
18486
|
+
turn.activeModel = {
|
|
18487
|
+
output: [],
|
|
18488
|
+
span,
|
|
18489
|
+
startEventId,
|
|
18490
|
+
startTime: getCurrentUnixTimestamp()
|
|
18491
|
+
};
|
|
18492
|
+
}
|
|
18493
|
+
function recordAnthropicSessionFirstToken(state, event) {
|
|
18494
|
+
const model = state.activeTurn?.activeModel;
|
|
18495
|
+
if (!model || model.firstTokenTime !== void 0 || !isObject(event.delta) || !isObject(event.delta.content) || typeof event.delta.content.text !== "string") {
|
|
18496
|
+
return;
|
|
18497
|
+
}
|
|
18498
|
+
model.firstTokenTime = getCurrentUnixTimestamp();
|
|
18499
|
+
}
|
|
18500
|
+
function recordAnthropicSessionMessage(state, event) {
|
|
18501
|
+
const turn = ensureAnthropicSessionTurn(state);
|
|
18502
|
+
const content = processAttachmentsInInput(
|
|
18503
|
+
event.content
|
|
18504
|
+
);
|
|
18505
|
+
if (turn.activeModel) {
|
|
18506
|
+
turn.activeModel.output.push(...content);
|
|
18507
|
+
} else {
|
|
18508
|
+
const output = { role: "assistant", content };
|
|
18509
|
+
turn.lastOutput = output;
|
|
18510
|
+
state.history.push(output);
|
|
18511
|
+
}
|
|
18512
|
+
}
|
|
18513
|
+
function startAnthropicSessionTool(state, event) {
|
|
18514
|
+
const turn = ensureAnthropicSessionTurn(state);
|
|
18515
|
+
if (turn.activeModel) {
|
|
18516
|
+
turn.activeModel.output.push({
|
|
18517
|
+
type: "tool_use",
|
|
18518
|
+
id: event.id,
|
|
18519
|
+
name: event.name,
|
|
18520
|
+
input: event.input
|
|
18521
|
+
});
|
|
18522
|
+
}
|
|
18523
|
+
const existing = turn.activeTools.get(event.id);
|
|
18524
|
+
if (existing) {
|
|
18525
|
+
existing.span.end();
|
|
18526
|
+
turn.activeTools.delete(event.id);
|
|
18527
|
+
}
|
|
18528
|
+
const span = withCurrent(
|
|
18529
|
+
turn.span,
|
|
18530
|
+
() => startSpan(
|
|
18531
|
+
withSpanInstrumentationName(
|
|
18532
|
+
{
|
|
18533
|
+
event: { input: event.input },
|
|
18534
|
+
name: event.name,
|
|
18535
|
+
spanAttributes: { type: "tool" /* TOOL */ }
|
|
18536
|
+
},
|
|
18537
|
+
INSTRUMENTATION_NAMES.ANTHROPIC
|
|
18538
|
+
)
|
|
18539
|
+
)
|
|
18540
|
+
);
|
|
18541
|
+
const toolState = {
|
|
18542
|
+
approval: event.evaluated_permission === "allow" ? "approved" : event.evaluated_permission === "deny" ? "denied" : void 0,
|
|
18543
|
+
span
|
|
18544
|
+
};
|
|
18545
|
+
turn.activeTools.set(event.id, toolState);
|
|
18546
|
+
if (toolState.approval === "denied") {
|
|
18547
|
+
finalizeAnthropicSessionToolState(toolState);
|
|
18548
|
+
turn.activeTools.delete(event.id);
|
|
18549
|
+
}
|
|
18550
|
+
}
|
|
18551
|
+
function recordAnthropicSessionToolConfirmation(state, event) {
|
|
18552
|
+
if (typeof event.tool_use_id !== "string" || event.result !== "allow" && event.result !== "deny") {
|
|
18553
|
+
return;
|
|
18554
|
+
}
|
|
18555
|
+
const turn = state.activeTurn;
|
|
18556
|
+
const tool = turn?.activeTools.get(event.tool_use_id);
|
|
18557
|
+
if (!turn || !tool) {
|
|
18558
|
+
return;
|
|
18559
|
+
}
|
|
18560
|
+
tool.approval = event.result === "allow" ? "approved" : "denied";
|
|
18561
|
+
if (tool.approval === "denied") {
|
|
18562
|
+
finalizeAnthropicSessionToolState(tool);
|
|
18563
|
+
turn.activeTools.delete(event.tool_use_id);
|
|
18564
|
+
}
|
|
18565
|
+
}
|
|
18566
|
+
function finalizeAnthropicSessionTool(state, event) {
|
|
18567
|
+
const toolUseId = event.tool_use_id ?? event.mcp_tool_use_id ?? event.custom_tool_use_id;
|
|
18568
|
+
if (!toolUseId) {
|
|
18569
|
+
return;
|
|
18570
|
+
}
|
|
18571
|
+
const content = processAttachmentsInInput(event.content);
|
|
18572
|
+
const turn = state.activeTurn;
|
|
18573
|
+
const tool = turn?.activeTools.get(toolUseId);
|
|
18574
|
+
if (turn && tool) {
|
|
18575
|
+
finalizeAnthropicSessionToolState(tool, event, content);
|
|
18576
|
+
turn.activeTools.delete(toolUseId);
|
|
18577
|
+
}
|
|
18578
|
+
const toolResult = {
|
|
18579
|
+
type: "tool_result",
|
|
18580
|
+
tool_use_id: toolUseId,
|
|
18581
|
+
...content !== void 0 ? { content } : {},
|
|
18582
|
+
...event.is_error === true ? { is_error: true } : {}
|
|
18583
|
+
};
|
|
18584
|
+
state.history.push({
|
|
18585
|
+
role: "user",
|
|
18586
|
+
content: [toolResult]
|
|
18587
|
+
});
|
|
18588
|
+
}
|
|
18589
|
+
function finalizeAnthropicSessionToolState(state, event, content = event?.content) {
|
|
18590
|
+
safeAnthropicSessionLog(state.span, {
|
|
18591
|
+
...event?.is_error === true ? {
|
|
18592
|
+
error: content ?? "Anthropic session tool execution failed"
|
|
18593
|
+
} : {},
|
|
18594
|
+
...state.approval ? { metadata: { tool_approval: state.approval } } : {},
|
|
18595
|
+
...content !== void 0 ? { output: content } : {}
|
|
18596
|
+
});
|
|
18597
|
+
state.span.end();
|
|
18598
|
+
}
|
|
18599
|
+
function finalizeAnthropicSessionModel(state, event) {
|
|
18600
|
+
const turn = state.activeTurn;
|
|
18601
|
+
const model = turn?.activeModel;
|
|
18602
|
+
if (!turn || !model || model.startEventId !== event.model_request_start_id) {
|
|
18603
|
+
return;
|
|
18604
|
+
}
|
|
18605
|
+
finalizeAnthropicSessionModelState(state, turn, event);
|
|
18606
|
+
}
|
|
18607
|
+
function finalizeAnthropicSessionModelState(state, turn, event) {
|
|
18608
|
+
const model = turn.activeModel;
|
|
18609
|
+
if (!model) {
|
|
18610
|
+
return;
|
|
18611
|
+
}
|
|
18612
|
+
turn.activeModel = void 0;
|
|
18613
|
+
const metrics = event ? parseAnthropicSessionModelUsage(event.model_usage) : {};
|
|
18614
|
+
if (model.firstTokenTime !== void 0) {
|
|
18615
|
+
metrics.time_to_first_token = model.firstTokenTime - model.startTime;
|
|
18616
|
+
}
|
|
18617
|
+
const output = model.output.length > 0 ? { role: "assistant", content: model.output } : void 0;
|
|
18618
|
+
safeAnthropicSessionLog(model.span, {
|
|
18619
|
+
...event?.is_error ? { error: "Anthropic session model request failed" } : {},
|
|
18620
|
+
...Object.keys(metrics).length > 0 ? { metrics } : {},
|
|
18621
|
+
...output ? { output } : {}
|
|
18622
|
+
});
|
|
18623
|
+
model.span.end();
|
|
18624
|
+
if (output) {
|
|
18625
|
+
turn.lastOutput = output;
|
|
18626
|
+
state.history.push(output);
|
|
18627
|
+
}
|
|
18628
|
+
for (const key of [
|
|
18629
|
+
"prompt_tokens",
|
|
18630
|
+
"completion_tokens",
|
|
18631
|
+
"tokens",
|
|
18632
|
+
"prompt_cached_tokens",
|
|
18633
|
+
"prompt_cache_creation_tokens"
|
|
18634
|
+
]) {
|
|
18635
|
+
const value = metrics[key];
|
|
18636
|
+
if (typeof value === "number") {
|
|
18637
|
+
turn.metrics[key] = (turn.metrics[key] ?? 0) + value;
|
|
18638
|
+
}
|
|
18639
|
+
}
|
|
18640
|
+
}
|
|
18641
|
+
function parseAnthropicSessionModelUsage(usage) {
|
|
18642
|
+
const finalized = finalizeAnthropicTokens({
|
|
18643
|
+
completion_tokens: usage.output_tokens,
|
|
18644
|
+
prompt_cache_creation_tokens: usage.cache_creation_input_tokens,
|
|
18645
|
+
prompt_cached_tokens: usage.cache_read_input_tokens,
|
|
18646
|
+
prompt_tokens: usage.input_tokens
|
|
18647
|
+
});
|
|
18648
|
+
return Object.fromEntries(
|
|
18649
|
+
Object.entries(finalized).filter(
|
|
18650
|
+
(entry) => entry[1] !== void 0
|
|
18651
|
+
)
|
|
18652
|
+
);
|
|
18653
|
+
}
|
|
18654
|
+
function finalizeAnthropicSessionTurn(state, error2) {
|
|
18655
|
+
const turn = state.activeTurn;
|
|
18656
|
+
if (!turn) {
|
|
18657
|
+
return;
|
|
18658
|
+
}
|
|
18659
|
+
state.activeTurn = void 0;
|
|
18660
|
+
finalizeAnthropicSessionModelState(state, turn);
|
|
18661
|
+
for (const tool of turn.activeTools.values()) {
|
|
18662
|
+
finalizeAnthropicSessionToolState(tool);
|
|
18663
|
+
}
|
|
18664
|
+
turn.activeTools.clear();
|
|
18665
|
+
safeAnthropicSessionLog(turn.span, {
|
|
18666
|
+
...error2 !== void 0 ? { error: error2 instanceof Error ? error2 : toLoggedError(error2) } : {},
|
|
18667
|
+
...turn.input.length > 0 ? { input: turn.input } : {},
|
|
18668
|
+
...turn.lastOutput ? { output: turn.lastOutput } : {},
|
|
18669
|
+
...Object.keys(turn.metrics).length > 0 ? { metrics: turn.metrics } : {}
|
|
18670
|
+
});
|
|
18671
|
+
turn.span.end();
|
|
18672
|
+
}
|
|
18673
|
+
function safeAnthropicSessionLog(span, event) {
|
|
18674
|
+
try {
|
|
18675
|
+
span.log(event);
|
|
18676
|
+
} catch (error2) {
|
|
18677
|
+
debugLogger.debug("Error logging Anthropic Sessions span:", error2);
|
|
18678
|
+
}
|
|
18679
|
+
}
|
|
18075
18680
|
function parseMetricsFromUsage2(usage) {
|
|
18076
18681
|
if (!usage) {
|
|
18077
18682
|
return {};
|
|
@@ -19945,6 +20550,29 @@ var harnessAgentChannels = defineChannels(
|
|
|
19945
20550
|
{ instrumentationName: INSTRUMENTATION_NAMES.AI_SDK }
|
|
19946
20551
|
);
|
|
19947
20552
|
|
|
20553
|
+
// src/instrumentation/plugins/cloudflare-think-context.ts
|
|
20554
|
+
var cloudflareThinkSpans = /* @__PURE__ */ new Map();
|
|
20555
|
+
function registerCloudflareThinkSpan(span) {
|
|
20556
|
+
if (span.spanId) {
|
|
20557
|
+
cloudflareThinkSpans.set(span.spanId, span);
|
|
20558
|
+
}
|
|
20559
|
+
}
|
|
20560
|
+
function unregisterCloudflareThinkSpan(span) {
|
|
20561
|
+
if (span.spanId) {
|
|
20562
|
+
cloudflareThinkSpans.delete(span.spanId);
|
|
20563
|
+
}
|
|
20564
|
+
}
|
|
20565
|
+
function currentCloudflareThinkSpan() {
|
|
20566
|
+
const parentSpanIds = _internalGetGlobalState()?.contextManager.getParentSpanIds()?.spanParents ?? [];
|
|
20567
|
+
for (const parentSpanId of parentSpanIds) {
|
|
20568
|
+
const span = cloudflareThinkSpans.get(parentSpanId);
|
|
20569
|
+
if (span) {
|
|
20570
|
+
return span;
|
|
20571
|
+
}
|
|
20572
|
+
}
|
|
20573
|
+
return void 0;
|
|
20574
|
+
}
|
|
20575
|
+
|
|
19948
20576
|
// src/instrumentation/plugins/ai-sdk-plugin.ts
|
|
19949
20577
|
var DEFAULT_DENY_OUTPUT_PATHS = [
|
|
19950
20578
|
// v3
|
|
@@ -20051,6 +20679,7 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
20051
20679
|
traceStreamingChannel(aiSDKChannels.streamText, {
|
|
20052
20680
|
name: "streamText",
|
|
20053
20681
|
type: "function" /* FUNCTION */,
|
|
20682
|
+
shouldTrace: () => currentCloudflareThinkSpan() === void 0,
|
|
20054
20683
|
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
|
|
20055
20684
|
extractOutput: (result, endEvent) => processAISDKOutput(
|
|
20056
20685
|
result,
|
|
@@ -20071,6 +20700,7 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
20071
20700
|
traceSyncStreamChannel(aiSDKChannels.streamTextSync, {
|
|
20072
20701
|
name: "streamText",
|
|
20073
20702
|
type: "function" /* FUNCTION */,
|
|
20703
|
+
shouldTrace: () => currentCloudflareThinkSpan() === void 0,
|
|
20074
20704
|
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
|
|
20075
20705
|
patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
|
|
20076
20706
|
defaultDenyOutputPaths: denyOutputPaths,
|
|
@@ -21056,6 +21686,23 @@ function prepareAISDKWorkflowAgentStreamInput(params, event, span, defaultDenyOu
|
|
|
21056
21686
|
metadata
|
|
21057
21687
|
};
|
|
21058
21688
|
}
|
|
21689
|
+
function prepareAISDKAgentCallInput(params, event, span, defaultDenyOutputPaths = DEFAULT_DENY_OUTPUT_PATHS) {
|
|
21690
|
+
const { input } = processAISDKWorkflowAgentCallInput(params);
|
|
21691
|
+
const metadata = extractMetadataFromCallParams(params, event.self);
|
|
21692
|
+
const childTracing = prepareAISDKChildTracing(
|
|
21693
|
+
params,
|
|
21694
|
+
event.self,
|
|
21695
|
+
span,
|
|
21696
|
+
defaultDenyOutputPaths,
|
|
21697
|
+
event.aiSDK,
|
|
21698
|
+
{ agentOwner: true }
|
|
21699
|
+
);
|
|
21700
|
+
event.modelWrapped = childTracing.modelWrapped;
|
|
21701
|
+
if (childTracing.cleanup) {
|
|
21702
|
+
event.__braintrust_ai_sdk_cleanup = childTracing.cleanup;
|
|
21703
|
+
}
|
|
21704
|
+
return { input, metadata };
|
|
21705
|
+
}
|
|
21059
21706
|
function prepareAISDKEmbedInput(params, self) {
|
|
21060
21707
|
return {
|
|
21061
21708
|
input: { ...params },
|
|
@@ -21079,6 +21726,18 @@ function extractTopLevelAISDKMetrics(result, event, startTime) {
|
|
|
21079
21726
|
}
|
|
21080
21727
|
return metrics;
|
|
21081
21728
|
}
|
|
21729
|
+
async function extractResolvedAISDKTokenMetrics(result) {
|
|
21730
|
+
for (const field of ["totalUsage", "usage"]) {
|
|
21731
|
+
try {
|
|
21732
|
+
const usage = await Promise.resolve(result[field]);
|
|
21733
|
+
if (usage !== void 0) {
|
|
21734
|
+
return extractTokenMetrics({ [field]: usage });
|
|
21735
|
+
}
|
|
21736
|
+
} catch {
|
|
21737
|
+
}
|
|
21738
|
+
}
|
|
21739
|
+
return extractTokenMetrics(result);
|
|
21740
|
+
}
|
|
21082
21741
|
function hasModelChildTracing(event) {
|
|
21083
21742
|
return event?.modelWrapped === true || event?.__braintrust_ai_sdk_model_wrapped === true;
|
|
21084
21743
|
}
|
|
@@ -21896,13 +22555,15 @@ function patchAISDKStreamingResult(args) {
|
|
|
21896
22555
|
const {
|
|
21897
22556
|
defaultDenyOutputPaths,
|
|
21898
22557
|
endEvent,
|
|
22558
|
+
forceTopLevelMetrics,
|
|
21899
22559
|
onComplete,
|
|
21900
22560
|
onCancel,
|
|
21901
22561
|
onError,
|
|
21902
22562
|
result,
|
|
21903
22563
|
resolvePromiseUsage,
|
|
21904
22564
|
span,
|
|
21905
|
-
startTime
|
|
22565
|
+
startTime,
|
|
22566
|
+
transformOutput
|
|
21906
22567
|
} = args;
|
|
21907
22568
|
if (!result || typeof result !== "object") {
|
|
21908
22569
|
return false;
|
|
@@ -21955,8 +22616,8 @@ function patchAISDKStreamingResult(args) {
|
|
|
21955
22616
|
}
|
|
21956
22617
|
outputLogged = true;
|
|
21957
22618
|
try {
|
|
21958
|
-
const metrics = extractTopLevelAISDKMetrics(result, endEvent);
|
|
21959
|
-
if (resolvePromiseUsage) {
|
|
22619
|
+
const metrics = forceTopLevelMetrics ? await extractResolvedAISDKTokenMetrics(result) : extractTopLevelAISDKMetrics(result, endEvent);
|
|
22620
|
+
if (resolvePromiseUsage && !forceTopLevelMetrics) {
|
|
21960
22621
|
try {
|
|
21961
22622
|
const resultRecord2 = result;
|
|
21962
22623
|
const pendingUsage = resultRecord2.totalUsage ?? resultRecord2.usage;
|
|
@@ -21975,10 +22636,11 @@ function patchAISDKStreamingResult(args) {
|
|
|
21975
22636
|
if (metrics.time_to_first_token === void 0 && firstChunkTime !== void 0) {
|
|
21976
22637
|
metrics.time_to_first_token = firstChunkTime - startTime;
|
|
21977
22638
|
}
|
|
21978
|
-
const
|
|
22639
|
+
const processedOutput = await processAISDKStreamingOutput(
|
|
21979
22640
|
result,
|
|
21980
22641
|
resolveDenyOutputPaths(endEvent, defaultDenyOutputPaths)
|
|
21981
22642
|
);
|
|
22643
|
+
const output = transformOutput ? transformOutput(processedOutput) : processedOutput;
|
|
21982
22644
|
const metadata = buildResolvedMetadataPayload(result).metadata;
|
|
21983
22645
|
try {
|
|
21984
22646
|
span.log({
|
|
@@ -24400,6 +25062,295 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
24400
25062
|
}
|
|
24401
25063
|
};
|
|
24402
25064
|
|
|
25065
|
+
// src/instrumentation/plugins/cloudflare-think-channels.ts
|
|
25066
|
+
var cloudflareThinkChannels = defineChannels(
|
|
25067
|
+
"@cloudflare/think",
|
|
25068
|
+
{
|
|
25069
|
+
runInferenceLoop: channel({
|
|
25070
|
+
channelName: "Think.runInferenceLoop",
|
|
25071
|
+
kind: "async"
|
|
25072
|
+
})
|
|
25073
|
+
},
|
|
25074
|
+
{ instrumentationName: INSTRUMENTATION_NAMES.CLOUDFLARE_THINK }
|
|
25075
|
+
);
|
|
25076
|
+
|
|
25077
|
+
// src/instrumentation/plugins/cloudflare-think-plugin.ts
|
|
25078
|
+
var THINK_STATE_ID = /* @__PURE__ */ Symbol.for("braintrust.cloudflare-think.state-id");
|
|
25079
|
+
var CloudflareThinkPlugin = class extends BasePlugin {
|
|
25080
|
+
statesBySpanId = /* @__PURE__ */ new Map();
|
|
25081
|
+
onEnable() {
|
|
25082
|
+
this.subscribeToThinkRuns();
|
|
25083
|
+
this.subscribeToAISDKStreamTextSync();
|
|
25084
|
+
this.subscribeToAISDKStreamTextAsync();
|
|
25085
|
+
}
|
|
25086
|
+
onDisable() {
|
|
25087
|
+
for (const unsubscribe of this.unsubscribers) {
|
|
25088
|
+
unsubscribe();
|
|
25089
|
+
}
|
|
25090
|
+
this.unsubscribers = [];
|
|
25091
|
+
for (const state of this.statesBySpanId.values()) {
|
|
25092
|
+
this.finishState(state);
|
|
25093
|
+
}
|
|
25094
|
+
this.statesBySpanId.clear();
|
|
25095
|
+
}
|
|
25096
|
+
subscribeToThinkRuns() {
|
|
25097
|
+
const channel2 = cloudflareThinkChannels.runInferenceLoop.tracingChannel();
|
|
25098
|
+
const states = /* @__PURE__ */ new WeakMap();
|
|
25099
|
+
const state = _internalGetGlobalState();
|
|
25100
|
+
const contextManager = state?.contextManager;
|
|
25101
|
+
const currentSpanStore = contextManager ? contextManager[BRAINTRUST_CURRENT_SPAN_STORE] : void 0;
|
|
25102
|
+
const ensureState2 = (event) => {
|
|
25103
|
+
if (isAutoInstrumentationSuppressed()) {
|
|
25104
|
+
return void 0;
|
|
25105
|
+
}
|
|
25106
|
+
const existing = states.get(event);
|
|
25107
|
+
if (existing) {
|
|
25108
|
+
return existing;
|
|
25109
|
+
}
|
|
25110
|
+
const span = startSpan(
|
|
25111
|
+
withSpanInstrumentationName(
|
|
25112
|
+
{
|
|
25113
|
+
name: "Think.runTurn",
|
|
25114
|
+
spanAttributes: { type: "task" /* TASK */ }
|
|
25115
|
+
},
|
|
25116
|
+
INSTRUMENTATION_NAMES.CLOUDFLARE_THINK
|
|
25117
|
+
)
|
|
25118
|
+
);
|
|
25119
|
+
const runState = {
|
|
25120
|
+
aiResultPatched: false,
|
|
25121
|
+
fallbackInput: extractFallbackInput(event.self?.messages),
|
|
25122
|
+
finalized: false,
|
|
25123
|
+
inputLogged: false,
|
|
25124
|
+
span,
|
|
25125
|
+
startTime: getCurrentUnixTimestamp()
|
|
25126
|
+
};
|
|
25127
|
+
const metadata = {
|
|
25128
|
+
braintrust: {
|
|
25129
|
+
integration_name: "cloudflare-think",
|
|
25130
|
+
sdk_language: "typescript"
|
|
25131
|
+
}
|
|
25132
|
+
};
|
|
25133
|
+
if (typeof event.moduleVersion === "string") {
|
|
25134
|
+
metadata["cloudflare_think.version"] = event.moduleVersion;
|
|
25135
|
+
}
|
|
25136
|
+
span.log({ metadata });
|
|
25137
|
+
states.set(event, runState);
|
|
25138
|
+
if (span.spanId) {
|
|
25139
|
+
this.statesBySpanId.set(span.spanId, runState);
|
|
25140
|
+
}
|
|
25141
|
+
registerCloudflareThinkSpan(span);
|
|
25142
|
+
return runState;
|
|
25143
|
+
};
|
|
25144
|
+
if (contextManager && currentSpanStore && channel2.start) {
|
|
25145
|
+
channel2.start.bindStore(currentSpanStore, (event) => {
|
|
25146
|
+
const runState = ensureState2(event);
|
|
25147
|
+
return runState ? contextManager.wrapSpanForStore(runState.span) : currentSpanStore.getStore();
|
|
25148
|
+
});
|
|
25149
|
+
this.unsubscribers.push(
|
|
25150
|
+
() => channel2.start?.unbindStore(currentSpanStore)
|
|
25151
|
+
);
|
|
25152
|
+
}
|
|
25153
|
+
const handlers = {
|
|
25154
|
+
start: (event) => {
|
|
25155
|
+
ensureState2(event);
|
|
25156
|
+
},
|
|
25157
|
+
asyncEnd: (event) => {
|
|
25158
|
+
const runState = states.get(event);
|
|
25159
|
+
states.delete(event);
|
|
25160
|
+
if (!runState || runState.finalized || runState.aiResultPatched) {
|
|
25161
|
+
return;
|
|
25162
|
+
}
|
|
25163
|
+
this.finishState(runState, void 0, event.result);
|
|
25164
|
+
},
|
|
25165
|
+
error: (event) => {
|
|
25166
|
+
const runState = states.get(event);
|
|
25167
|
+
states.delete(event);
|
|
25168
|
+
if (runState) {
|
|
25169
|
+
this.finishState(runState, event.error);
|
|
25170
|
+
}
|
|
25171
|
+
}
|
|
25172
|
+
};
|
|
25173
|
+
channel2.subscribe(handlers);
|
|
25174
|
+
this.unsubscribers.push(() => channel2.unsubscribe(handlers));
|
|
25175
|
+
}
|
|
25176
|
+
subscribeToAISDKStreamTextSync() {
|
|
25177
|
+
const channel2 = aiSDKChannels.streamTextSync.tracingChannel();
|
|
25178
|
+
const handlers = {
|
|
25179
|
+
start: (event) => {
|
|
25180
|
+
this.startAISDKStream(event);
|
|
25181
|
+
},
|
|
25182
|
+
end: (event) => {
|
|
25183
|
+
this.endAISDKStream(event);
|
|
25184
|
+
},
|
|
25185
|
+
error: (event) => {
|
|
25186
|
+
this.errorAISDKStream(event);
|
|
25187
|
+
}
|
|
25188
|
+
};
|
|
25189
|
+
channel2.subscribe(handlers);
|
|
25190
|
+
this.unsubscribers.push(() => channel2.unsubscribe(handlers));
|
|
25191
|
+
}
|
|
25192
|
+
subscribeToAISDKStreamTextAsync() {
|
|
25193
|
+
const channel2 = aiSDKChannels.streamText.tracingChannel();
|
|
25194
|
+
const handlers = {
|
|
25195
|
+
start: (event) => {
|
|
25196
|
+
this.startAISDKStream(event);
|
|
25197
|
+
},
|
|
25198
|
+
asyncEnd: (event) => {
|
|
25199
|
+
this.endAISDKStream(event);
|
|
25200
|
+
},
|
|
25201
|
+
error: (event) => {
|
|
25202
|
+
this.errorAISDKStream(event);
|
|
25203
|
+
}
|
|
25204
|
+
};
|
|
25205
|
+
channel2.subscribe(handlers);
|
|
25206
|
+
this.unsubscribers.push(() => channel2.unsubscribe(handlers));
|
|
25207
|
+
}
|
|
25208
|
+
startAISDKStream(event) {
|
|
25209
|
+
const runState = this.currentState();
|
|
25210
|
+
if (!runState || runState.finalized) {
|
|
25211
|
+
return;
|
|
25212
|
+
}
|
|
25213
|
+
try {
|
|
25214
|
+
const prepared = prepareAISDKAgentCallInput(
|
|
25215
|
+
event.arguments[0],
|
|
25216
|
+
event,
|
|
25217
|
+
runState.span
|
|
25218
|
+
);
|
|
25219
|
+
runState.span.log({
|
|
25220
|
+
input: extractThinkTaskInput(prepared.input),
|
|
25221
|
+
metadata: {
|
|
25222
|
+
...prepared.metadata,
|
|
25223
|
+
braintrust: {
|
|
25224
|
+
integration_name: "cloudflare-think",
|
|
25225
|
+
sdk_language: "typescript"
|
|
25226
|
+
}
|
|
25227
|
+
}
|
|
25228
|
+
});
|
|
25229
|
+
runState.inputLogged = true;
|
|
25230
|
+
runState.aiEvent = event;
|
|
25231
|
+
Reflect.set(event, THINK_STATE_ID, runState.span.spanId);
|
|
25232
|
+
} catch (error2) {
|
|
25233
|
+
debugLogger.error(
|
|
25234
|
+
"Error preparing @cloudflare/think AI SDK tracing:",
|
|
25235
|
+
error2
|
|
25236
|
+
);
|
|
25237
|
+
}
|
|
25238
|
+
}
|
|
25239
|
+
endAISDKStream(event) {
|
|
25240
|
+
const runState = this.stateForAISDKEvent(event);
|
|
25241
|
+
if (!runState || runState.finalized) {
|
|
25242
|
+
return;
|
|
25243
|
+
}
|
|
25244
|
+
const patched = patchAISDKStreamingResult({
|
|
25245
|
+
defaultDenyOutputPaths: DEFAULT_DENY_OUTPUT_PATHS,
|
|
25246
|
+
endEvent: event,
|
|
25247
|
+
forceTopLevelMetrics: true,
|
|
25248
|
+
onComplete: () => this.releaseState(runState),
|
|
25249
|
+
result: event.result,
|
|
25250
|
+
span: runState.span,
|
|
25251
|
+
startTime: runState.startTime,
|
|
25252
|
+
transformOutput: extractThinkTaskOutput
|
|
25253
|
+
});
|
|
25254
|
+
runState.aiResultPatched = patched;
|
|
25255
|
+
if (!patched) {
|
|
25256
|
+
this.finishState(runState, void 0, event.result);
|
|
25257
|
+
}
|
|
25258
|
+
}
|
|
25259
|
+
errorAISDKStream(event) {
|
|
25260
|
+
const runState = this.stateForAISDKEvent(event);
|
|
25261
|
+
if (runState) {
|
|
25262
|
+
this.finishState(runState, event.error);
|
|
25263
|
+
}
|
|
25264
|
+
}
|
|
25265
|
+
currentState() {
|
|
25266
|
+
const parentIds = _internalGetGlobalState()?.contextManager.getParentSpanIds()?.spanParents ?? [];
|
|
25267
|
+
for (const parentId of parentIds) {
|
|
25268
|
+
const state = this.statesBySpanId.get(parentId);
|
|
25269
|
+
if (state) {
|
|
25270
|
+
return state;
|
|
25271
|
+
}
|
|
25272
|
+
}
|
|
25273
|
+
return void 0;
|
|
25274
|
+
}
|
|
25275
|
+
stateForAISDKEvent(event) {
|
|
25276
|
+
const spanId = Reflect.get(event, THINK_STATE_ID);
|
|
25277
|
+
return typeof spanId === "string" ? this.statesBySpanId.get(spanId) : void 0;
|
|
25278
|
+
}
|
|
25279
|
+
finishState(state, error2, output) {
|
|
25280
|
+
if (state.finalized) {
|
|
25281
|
+
return;
|
|
25282
|
+
}
|
|
25283
|
+
state.finalized = true;
|
|
25284
|
+
try {
|
|
25285
|
+
if (!state.inputLogged && state.fallbackInput !== void 0) {
|
|
25286
|
+
state.span.log({ input: state.fallbackInput });
|
|
25287
|
+
}
|
|
25288
|
+
if (error2 !== void 0) {
|
|
25289
|
+
state.span.log({ error: error2 });
|
|
25290
|
+
} else if (output !== void 0) {
|
|
25291
|
+
state.span.log({ output: extractThinkTaskOutput(output) });
|
|
25292
|
+
}
|
|
25293
|
+
finalizeAISDKChildTracing(state.aiEvent);
|
|
25294
|
+
state.span.end();
|
|
25295
|
+
} finally {
|
|
25296
|
+
this.releaseState(state);
|
|
25297
|
+
}
|
|
25298
|
+
}
|
|
25299
|
+
releaseState(state) {
|
|
25300
|
+
state.finalized = true;
|
|
25301
|
+
unregisterCloudflareThinkSpan(state.span);
|
|
25302
|
+
if (state.span.spanId) {
|
|
25303
|
+
this.statesBySpanId.delete(state.span.spanId);
|
|
25304
|
+
}
|
|
25305
|
+
}
|
|
25306
|
+
};
|
|
25307
|
+
function extractFallbackInput(messages) {
|
|
25308
|
+
if (!Array.isArray(messages) || messages.length === 0) {
|
|
25309
|
+
return void 0;
|
|
25310
|
+
}
|
|
25311
|
+
let latestUserIndex = -1;
|
|
25312
|
+
for (let index = messages.length - 1; index >= 0; index--) {
|
|
25313
|
+
if (messages[index]?.role === "user") {
|
|
25314
|
+
latestUserIndex = index;
|
|
25315
|
+
break;
|
|
25316
|
+
}
|
|
25317
|
+
}
|
|
25318
|
+
const selected = latestUserIndex >= 0 ? messages.slice(latestUserIndex) : [];
|
|
25319
|
+
return selected.map((message) => ({
|
|
25320
|
+
role: message.role,
|
|
25321
|
+
content: message.content ?? message.parts
|
|
25322
|
+
}));
|
|
25323
|
+
}
|
|
25324
|
+
function extractThinkTaskOutput(output) {
|
|
25325
|
+
if (!isObject(output)) {
|
|
25326
|
+
return output;
|
|
25327
|
+
}
|
|
25328
|
+
if (typeof output.text === "string") {
|
|
25329
|
+
return { role: "assistant", content: output.text };
|
|
25330
|
+
}
|
|
25331
|
+
if (output.object !== void 0) {
|
|
25332
|
+
return output.object;
|
|
25333
|
+
}
|
|
25334
|
+
return output;
|
|
25335
|
+
}
|
|
25336
|
+
function extractThinkTaskInput(input) {
|
|
25337
|
+
if (!isObject(input)) {
|
|
25338
|
+
return input;
|
|
25339
|
+
}
|
|
25340
|
+
const system = input.instructions ?? input.system;
|
|
25341
|
+
if (Array.isArray(input.messages)) {
|
|
25342
|
+
return system === void 0 ? input.messages : [{ role: "system", content: system }, ...input.messages];
|
|
25343
|
+
}
|
|
25344
|
+
if (Array.isArray(input.prompt)) {
|
|
25345
|
+
return system === void 0 ? input.prompt : [{ role: "system", content: system }, ...input.prompt];
|
|
25346
|
+
}
|
|
25347
|
+
if (typeof input.prompt === "string") {
|
|
25348
|
+
const messages = [{ role: "user", content: input.prompt }];
|
|
25349
|
+
return system === void 0 ? messages : [{ role: "system", content: system }, ...messages];
|
|
25350
|
+
}
|
|
25351
|
+
return input;
|
|
25352
|
+
}
|
|
25353
|
+
|
|
24403
25354
|
// src/instrumentation/plugins/cursor-sdk-channels.ts
|
|
24404
25355
|
var cursorSDKChannels = defineChannels(
|
|
24405
25356
|
"@cursor/sdk",
|
|
@@ -30165,6 +31116,470 @@ function aggregateMistralStreamChunks(chunks) {
|
|
|
30165
31116
|
};
|
|
30166
31117
|
}
|
|
30167
31118
|
|
|
31119
|
+
// src/instrumentation/plugins/ollama-channels.ts
|
|
31120
|
+
var ollamaChannels = defineChannels(
|
|
31121
|
+
"ollama",
|
|
31122
|
+
{
|
|
31123
|
+
chat: channel({
|
|
31124
|
+
channelName: "chat",
|
|
31125
|
+
kind: "async"
|
|
31126
|
+
}),
|
|
31127
|
+
generate: channel({
|
|
31128
|
+
channelName: "generate",
|
|
31129
|
+
kind: "async"
|
|
31130
|
+
}),
|
|
31131
|
+
embed: channel({
|
|
31132
|
+
channelName: "embed",
|
|
31133
|
+
kind: "async"
|
|
31134
|
+
})
|
|
31135
|
+
},
|
|
31136
|
+
{ instrumentationName: INSTRUMENTATION_NAMES.OLLAMA }
|
|
31137
|
+
);
|
|
31138
|
+
|
|
31139
|
+
// src/instrumentation/plugins/ollama-plugin.ts
|
|
31140
|
+
var OllamaPlugin = class extends BasePlugin {
|
|
31141
|
+
onEnable() {
|
|
31142
|
+
this.unsubscribers.push(
|
|
31143
|
+
traceStreamingChannel(ollamaChannels.chat, {
|
|
31144
|
+
name: "ollama.chat",
|
|
31145
|
+
type: "llm" /* LLM */,
|
|
31146
|
+
extractInput: extractOllamaChatInput,
|
|
31147
|
+
extractOutput: (result, event) => extractOllamaChatOutput(
|
|
31148
|
+
result,
|
|
31149
|
+
countOllamaToolCalls(event?.arguments?.[0]?.messages)
|
|
31150
|
+
),
|
|
31151
|
+
extractMetadata: extractOllamaResponseMetadata,
|
|
31152
|
+
extractMetrics: extractOllamaMetrics,
|
|
31153
|
+
aggregateChunks: aggregateOllamaChatChunks
|
|
31154
|
+
}),
|
|
31155
|
+
traceStreamingChannel(ollamaChannels.generate, {
|
|
31156
|
+
name: "ollama.generate",
|
|
31157
|
+
type: "llm" /* LLM */,
|
|
31158
|
+
extractInput: extractOllamaGenerateInput,
|
|
31159
|
+
extractOutput: extractOllamaGenerateOutput,
|
|
31160
|
+
extractMetadata: extractOllamaResponseMetadata,
|
|
31161
|
+
extractMetrics: extractOllamaMetrics,
|
|
31162
|
+
aggregateChunks: aggregateOllamaGenerateChunks
|
|
31163
|
+
}),
|
|
31164
|
+
traceAsyncChannel(ollamaChannels.embed, {
|
|
31165
|
+
name: "ollama.embed",
|
|
31166
|
+
type: "llm" /* LLM */,
|
|
31167
|
+
extractInput: extractOllamaEmbedInput,
|
|
31168
|
+
extractOutput: extractOllamaEmbedOutput,
|
|
31169
|
+
extractMetadata: extractOllamaResponseMetadata,
|
|
31170
|
+
extractMetrics: extractOllamaMetrics
|
|
31171
|
+
})
|
|
31172
|
+
);
|
|
31173
|
+
}
|
|
31174
|
+
onDisable() {
|
|
31175
|
+
this.unsubscribers = unsubscribeAll(this.unsubscribers);
|
|
31176
|
+
}
|
|
31177
|
+
};
|
|
31178
|
+
function isNonNegativeNumber(value) {
|
|
31179
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0;
|
|
31180
|
+
}
|
|
31181
|
+
function normalizeFinishReason(response, hasToolCalls = false) {
|
|
31182
|
+
if (hasToolCalls) {
|
|
31183
|
+
return "tool_calls";
|
|
31184
|
+
}
|
|
31185
|
+
return response?.done_reason || "stop";
|
|
31186
|
+
}
|
|
31187
|
+
function stringifyArguments(value) {
|
|
31188
|
+
if (typeof value === "string") {
|
|
31189
|
+
return value;
|
|
31190
|
+
}
|
|
31191
|
+
try {
|
|
31192
|
+
return JSON.stringify(value ?? {});
|
|
31193
|
+
} catch {
|
|
31194
|
+
return String(value);
|
|
31195
|
+
}
|
|
31196
|
+
}
|
|
31197
|
+
function syntheticToolCallId(name, index) {
|
|
31198
|
+
const normalizedName = name.replace(/[^a-zA-Z0-9_-]/g, "_") || "tool";
|
|
31199
|
+
return `ollama_call_${normalizedName}_${index}`;
|
|
31200
|
+
}
|
|
31201
|
+
function normalizeToolCall(toolCall, index) {
|
|
31202
|
+
const name = toolCall.function?.name;
|
|
31203
|
+
if (typeof name !== "string" || name.length === 0) {
|
|
31204
|
+
return void 0;
|
|
31205
|
+
}
|
|
31206
|
+
return {
|
|
31207
|
+
id: typeof toolCall.id === "string" && toolCall.id.length > 0 ? toolCall.id : syntheticToolCallId(name, index),
|
|
31208
|
+
type: "function",
|
|
31209
|
+
function: {
|
|
31210
|
+
name,
|
|
31211
|
+
arguments: stringifyArguments(toolCall.function?.arguments)
|
|
31212
|
+
}
|
|
31213
|
+
};
|
|
31214
|
+
}
|
|
31215
|
+
function normalizeToolCalls(toolCalls, syntheticIdOffset = 0) {
|
|
31216
|
+
if (!Array.isArray(toolCalls)) {
|
|
31217
|
+
return [];
|
|
31218
|
+
}
|
|
31219
|
+
return toolCalls.flatMap((toolCall, index) => {
|
|
31220
|
+
const normalized = normalizeToolCall(toolCall, syntheticIdOffset + index);
|
|
31221
|
+
return normalized ? [normalized] : [];
|
|
31222
|
+
});
|
|
31223
|
+
}
|
|
31224
|
+
function countOllamaToolCalls(messages) {
|
|
31225
|
+
if (!Array.isArray(messages)) {
|
|
31226
|
+
return 0;
|
|
31227
|
+
}
|
|
31228
|
+
return messages.reduce(
|
|
31229
|
+
(count, message) => count + (isObject(message) && Array.isArray(message.tool_calls) ? message.tool_calls.length : 0),
|
|
31230
|
+
0
|
|
31231
|
+
);
|
|
31232
|
+
}
|
|
31233
|
+
function imageBytes(value) {
|
|
31234
|
+
if (value instanceof Uint8Array) {
|
|
31235
|
+
return value;
|
|
31236
|
+
}
|
|
31237
|
+
if (value instanceof ArrayBuffer) {
|
|
31238
|
+
return new Uint8Array(value);
|
|
31239
|
+
}
|
|
31240
|
+
if (typeof value !== "string" || value.startsWith("data:")) {
|
|
31241
|
+
return void 0;
|
|
31242
|
+
}
|
|
31243
|
+
try {
|
|
31244
|
+
const decoded = atob(value.slice(0, 24));
|
|
31245
|
+
return Uint8Array.from(decoded, (character) => character.charCodeAt(0));
|
|
31246
|
+
} catch {
|
|
31247
|
+
return void 0;
|
|
31248
|
+
}
|
|
31249
|
+
}
|
|
31250
|
+
function inferImageMediaType(value) {
|
|
31251
|
+
if (typeof value === "string") {
|
|
31252
|
+
const dataUrlType = value.match(/^data:(image\/[^;]+);base64,/i)?.[1];
|
|
31253
|
+
if (dataUrlType) {
|
|
31254
|
+
return dataUrlType;
|
|
31255
|
+
}
|
|
31256
|
+
}
|
|
31257
|
+
const bytes = imageBytes(value);
|
|
31258
|
+
if (!bytes) {
|
|
31259
|
+
return void 0;
|
|
31260
|
+
}
|
|
31261
|
+
if (bytes[0] === 137 && bytes[1] === 80 && bytes[2] === 78 && bytes[3] === 71) {
|
|
31262
|
+
return "image/png";
|
|
31263
|
+
}
|
|
31264
|
+
if (bytes[0] === 255 && bytes[1] === 216 && bytes[2] === 255) {
|
|
31265
|
+
return "image/jpeg";
|
|
31266
|
+
}
|
|
31267
|
+
const signature = String.fromCharCode(...bytes.slice(0, 12));
|
|
31268
|
+
if (signature.startsWith("GIF87a") || signature.startsWith("GIF89a")) {
|
|
31269
|
+
return "image/gif";
|
|
31270
|
+
}
|
|
31271
|
+
if (signature.startsWith("RIFF") && signature.slice(8, 12) === "WEBP") {
|
|
31272
|
+
return "image/webp";
|
|
31273
|
+
}
|
|
31274
|
+
return void 0;
|
|
31275
|
+
}
|
|
31276
|
+
function normalizeTextAndImages(content, images) {
|
|
31277
|
+
if (!images || images.length === 0) {
|
|
31278
|
+
return { content };
|
|
31279
|
+
}
|
|
31280
|
+
const imageParts = [];
|
|
31281
|
+
const unrecognizedImages = [];
|
|
31282
|
+
for (const image of images) {
|
|
31283
|
+
let localImagePath;
|
|
31284
|
+
let localPathMediaType;
|
|
31285
|
+
if (typeof image === "string" && !/^data:/i.test(image) && !/^https?:\/\//i.test(image)) {
|
|
31286
|
+
const extension = image.match(/\.([a-z0-9]+)$/i)?.[1]?.toLowerCase();
|
|
31287
|
+
const extensionMediaType = {
|
|
31288
|
+
png: "image/png",
|
|
31289
|
+
jpg: "image/jpeg",
|
|
31290
|
+
jpeg: "image/jpeg",
|
|
31291
|
+
gif: "image/gif",
|
|
31292
|
+
webp: "image/webp"
|
|
31293
|
+
}[extension ?? ""];
|
|
31294
|
+
if (extensionMediaType && isomorph_default.statSync) {
|
|
31295
|
+
try {
|
|
31296
|
+
if (isomorph_default.statSync(image).isFile()) {
|
|
31297
|
+
localImagePath = image;
|
|
31298
|
+
localPathMediaType = extensionMediaType;
|
|
31299
|
+
}
|
|
31300
|
+
} catch {
|
|
31301
|
+
}
|
|
31302
|
+
}
|
|
31303
|
+
}
|
|
31304
|
+
const mediaType = localPathMediaType ?? inferImageMediaType(image);
|
|
31305
|
+
if (!mediaType) {
|
|
31306
|
+
unrecognizedImages.push(image);
|
|
31307
|
+
continue;
|
|
31308
|
+
}
|
|
31309
|
+
const processedImage = localImagePath ? new Attachment({
|
|
31310
|
+
data: localImagePath,
|
|
31311
|
+
filename: localImagePath.split(/[\\/]/).at(-1) ?? "image",
|
|
31312
|
+
contentType: mediaType
|
|
31313
|
+
}) : processInputAttachments({
|
|
31314
|
+
type: "image",
|
|
31315
|
+
image,
|
|
31316
|
+
mediaType
|
|
31317
|
+
}).image;
|
|
31318
|
+
imageParts.push({
|
|
31319
|
+
type: "image_url",
|
|
31320
|
+
image_url: { url: processedImage }
|
|
31321
|
+
});
|
|
31322
|
+
}
|
|
31323
|
+
return {
|
|
31324
|
+
content: imageParts.length > 0 ? [...content ? [{ type: "text", text: content }] : [], ...imageParts] : content,
|
|
31325
|
+
...unrecognizedImages.length > 0 ? { unrecognizedImages } : {}
|
|
31326
|
+
};
|
|
31327
|
+
}
|
|
31328
|
+
function normalizeMessage(message, toolCallId, syntheticToolCallIdOffset = 0) {
|
|
31329
|
+
if (typeof message.role !== "string") {
|
|
31330
|
+
return void 0;
|
|
31331
|
+
}
|
|
31332
|
+
const toolCalls = normalizeToolCalls(
|
|
31333
|
+
message.tool_calls,
|
|
31334
|
+
syntheticToolCallIdOffset
|
|
31335
|
+
);
|
|
31336
|
+
if (message.role === "tool") {
|
|
31337
|
+
const toolName = typeof message.tool_name === "string" && message.tool_name.length > 0 ? message.tool_name : "tool";
|
|
31338
|
+
return {
|
|
31339
|
+
role: "tool",
|
|
31340
|
+
tool_call_id: toolCallId ?? syntheticToolCallId(toolName, 0),
|
|
31341
|
+
content: typeof message.content === "string" ? message.content : ""
|
|
31342
|
+
};
|
|
31343
|
+
}
|
|
31344
|
+
const normalizedContent = normalizeTextAndImages(
|
|
31345
|
+
typeof message.content === "string" ? message.content || (toolCalls.length > 0 ? null : "") : toolCalls.length > 0 ? null : "",
|
|
31346
|
+
message.images
|
|
31347
|
+
);
|
|
31348
|
+
return {
|
|
31349
|
+
role: message.role,
|
|
31350
|
+
content: normalizedContent.content,
|
|
31351
|
+
...typeof message.thinking === "string" && message.thinking.length > 0 ? { reasoning: message.thinking } : {},
|
|
31352
|
+
...toolCalls.length > 0 ? { tool_calls: toolCalls } : {},
|
|
31353
|
+
...normalizedContent.unrecognizedImages ? { images: normalizedContent.unrecognizedImages } : {}
|
|
31354
|
+
};
|
|
31355
|
+
}
|
|
31356
|
+
function normalizeMessages(messages) {
|
|
31357
|
+
if (!Array.isArray(messages)) {
|
|
31358
|
+
return [];
|
|
31359
|
+
}
|
|
31360
|
+
const pendingToolCallIds = /* @__PURE__ */ new Map();
|
|
31361
|
+
let syntheticToolCallIdOffset = 0;
|
|
31362
|
+
return messages.flatMap((message) => {
|
|
31363
|
+
if (!isObject(message)) {
|
|
31364
|
+
return [];
|
|
31365
|
+
}
|
|
31366
|
+
const ollamaMessage = message;
|
|
31367
|
+
let toolCallId;
|
|
31368
|
+
if (ollamaMessage.role === "tool") {
|
|
31369
|
+
const toolName = ollamaMessage.tool_name;
|
|
31370
|
+
if (typeof toolName === "string") {
|
|
31371
|
+
toolCallId = pendingToolCallIds.get(toolName)?.shift();
|
|
31372
|
+
}
|
|
31373
|
+
}
|
|
31374
|
+
const normalized = normalizeMessage(
|
|
31375
|
+
ollamaMessage,
|
|
31376
|
+
toolCallId,
|
|
31377
|
+
syntheticToolCallIdOffset
|
|
31378
|
+
);
|
|
31379
|
+
if (Array.isArray(ollamaMessage.tool_calls)) {
|
|
31380
|
+
syntheticToolCallIdOffset += ollamaMessage.tool_calls.length;
|
|
31381
|
+
}
|
|
31382
|
+
if (ollamaMessage.role === "assistant" && normalized) {
|
|
31383
|
+
const toolCalls = Array.isArray(normalized.tool_calls) ? normalized.tool_calls : [];
|
|
31384
|
+
for (const toolCall of toolCalls) {
|
|
31385
|
+
if (!isObject(toolCall) || !isObject(toolCall.function)) {
|
|
31386
|
+
continue;
|
|
31387
|
+
}
|
|
31388
|
+
const name = toolCall.function.name;
|
|
31389
|
+
const id = toolCall.id;
|
|
31390
|
+
if (typeof name === "string" && typeof id === "string") {
|
|
31391
|
+
const ids = pendingToolCallIds.get(name) ?? [];
|
|
31392
|
+
ids.push(id);
|
|
31393
|
+
pendingToolCallIds.set(name, ids);
|
|
31394
|
+
}
|
|
31395
|
+
}
|
|
31396
|
+
}
|
|
31397
|
+
return normalized ? [normalized] : [];
|
|
31398
|
+
});
|
|
31399
|
+
}
|
|
31400
|
+
function normalizeToolDefinition(tool) {
|
|
31401
|
+
const fn = tool.function;
|
|
31402
|
+
if (!fn || typeof fn.name !== "string" || fn.name.length === 0) {
|
|
31403
|
+
return void 0;
|
|
31404
|
+
}
|
|
31405
|
+
return {
|
|
31406
|
+
type: "function",
|
|
31407
|
+
function: {
|
|
31408
|
+
name: fn.name,
|
|
31409
|
+
...typeof fn.description === "string" ? { description: fn.description } : {},
|
|
31410
|
+
...isObject(fn.parameters) ? { parameters: fn.parameters } : {}
|
|
31411
|
+
}
|
|
31412
|
+
};
|
|
31413
|
+
}
|
|
31414
|
+
function extractToolsMetadata(tools) {
|
|
31415
|
+
if (!Array.isArray(tools)) {
|
|
31416
|
+
return {};
|
|
31417
|
+
}
|
|
31418
|
+
const normalized = tools.flatMap((tool) => {
|
|
31419
|
+
if (!isObject(tool)) {
|
|
31420
|
+
return [];
|
|
31421
|
+
}
|
|
31422
|
+
const definition = normalizeToolDefinition(tool);
|
|
31423
|
+
return definition ? [definition] : [];
|
|
31424
|
+
});
|
|
31425
|
+
return normalized.length > 0 ? { tools: normalized } : {};
|
|
31426
|
+
}
|
|
31427
|
+
function extractOptionsMetadata(options) {
|
|
31428
|
+
if (!isObject(options)) {
|
|
31429
|
+
return {};
|
|
31430
|
+
}
|
|
31431
|
+
const metadata = {};
|
|
31432
|
+
const mappings = [
|
|
31433
|
+
["temperature", "temperature"],
|
|
31434
|
+
["top_p", "top_p"],
|
|
31435
|
+
["num_predict", "max_tokens"],
|
|
31436
|
+
["frequency_penalty", "frequency_penalty"],
|
|
31437
|
+
["presence_penalty", "presence_penalty"],
|
|
31438
|
+
["stop", "stop"]
|
|
31439
|
+
];
|
|
31440
|
+
for (const [source, target] of mappings) {
|
|
31441
|
+
if (options[source] !== void 0) {
|
|
31442
|
+
metadata[target] = options[source];
|
|
31443
|
+
}
|
|
31444
|
+
}
|
|
31445
|
+
return metadata;
|
|
31446
|
+
}
|
|
31447
|
+
function extractRequestMetadata(request) {
|
|
31448
|
+
return {
|
|
31449
|
+
provider: "ollama",
|
|
31450
|
+
...typeof request?.model === "string" ? { model: request.model } : {},
|
|
31451
|
+
...extractOptionsMetadata(request?.options),
|
|
31452
|
+
...request?.format !== void 0 ? { response_format: request.format } : {}
|
|
31453
|
+
};
|
|
31454
|
+
}
|
|
31455
|
+
function extractOllamaChatInput([request]) {
|
|
31456
|
+
return {
|
|
31457
|
+
input: normalizeMessages(request.messages),
|
|
31458
|
+
metadata: {
|
|
31459
|
+
...extractRequestMetadata(request),
|
|
31460
|
+
...extractToolsMetadata(request.tools)
|
|
31461
|
+
}
|
|
31462
|
+
};
|
|
31463
|
+
}
|
|
31464
|
+
function extractOllamaGenerateInput([request]) {
|
|
31465
|
+
const normalizedPrompt = normalizeTextAndImages(
|
|
31466
|
+
typeof request.prompt === "string" ? request.prompt : "",
|
|
31467
|
+
Array.isArray(request.images) ? request.images : void 0
|
|
31468
|
+
);
|
|
31469
|
+
const input = [
|
|
31470
|
+
...typeof request.system === "string" ? [{ role: "system", content: request.system }] : [],
|
|
31471
|
+
{
|
|
31472
|
+
role: "user",
|
|
31473
|
+
content: normalizedPrompt.content,
|
|
31474
|
+
...typeof request.suffix === "string" ? { suffix: request.suffix } : {},
|
|
31475
|
+
...normalizedPrompt.unrecognizedImages ? { images: normalizedPrompt.unrecognizedImages } : {}
|
|
31476
|
+
}
|
|
31477
|
+
];
|
|
31478
|
+
return {
|
|
31479
|
+
input,
|
|
31480
|
+
metadata: extractRequestMetadata(request)
|
|
31481
|
+
};
|
|
31482
|
+
}
|
|
31483
|
+
function extractOllamaEmbedInput([request]) {
|
|
31484
|
+
return {
|
|
31485
|
+
input: request.input,
|
|
31486
|
+
metadata: extractRequestMetadata(request)
|
|
31487
|
+
};
|
|
31488
|
+
}
|
|
31489
|
+
function extractOllamaChatOutput(result, syntheticToolCallIdOffset = 0) {
|
|
31490
|
+
if (!isObject(result) || !isObject(result.message)) {
|
|
31491
|
+
return void 0;
|
|
31492
|
+
}
|
|
31493
|
+
const message = normalizeMessage(
|
|
31494
|
+
result.message,
|
|
31495
|
+
void 0,
|
|
31496
|
+
syntheticToolCallIdOffset
|
|
31497
|
+
);
|
|
31498
|
+
if (!message) {
|
|
31499
|
+
return void 0;
|
|
31500
|
+
}
|
|
31501
|
+
const toolCalls = Array.isArray(message.tool_calls) ? message.tool_calls : [];
|
|
31502
|
+
return [
|
|
31503
|
+
{
|
|
31504
|
+
index: 0,
|
|
31505
|
+
finish_reason: normalizeFinishReason(result, toolCalls.length > 0),
|
|
31506
|
+
message
|
|
31507
|
+
}
|
|
31508
|
+
];
|
|
31509
|
+
}
|
|
31510
|
+
function extractOllamaGenerateOutput(result) {
|
|
31511
|
+
if (!isObject(result) || typeof result.response !== "string") {
|
|
31512
|
+
return void 0;
|
|
31513
|
+
}
|
|
31514
|
+
return [
|
|
31515
|
+
{
|
|
31516
|
+
index: 0,
|
|
31517
|
+
finish_reason: normalizeFinishReason(result),
|
|
31518
|
+
message: {
|
|
31519
|
+
role: "assistant",
|
|
31520
|
+
content: result.response,
|
|
31521
|
+
...typeof result.thinking === "string" && result.thinking.length > 0 ? { reasoning: result.thinking } : {}
|
|
31522
|
+
}
|
|
31523
|
+
}
|
|
31524
|
+
];
|
|
31525
|
+
}
|
|
31526
|
+
function extractOllamaEmbedOutput(result) {
|
|
31527
|
+
const embedding = Array.isArray(result?.embeddings) ? result.embeddings[0] : void 0;
|
|
31528
|
+
return Array.isArray(embedding) ? { embedding_length: embedding.length } : void 0;
|
|
31529
|
+
}
|
|
31530
|
+
function extractOllamaResponseMetadata(result) {
|
|
31531
|
+
return typeof result?.model === "string" ? { model: result.model } : void 0;
|
|
31532
|
+
}
|
|
31533
|
+
function extractOllamaMetrics(result) {
|
|
31534
|
+
const metrics = {};
|
|
31535
|
+
const promptTokens = result?.prompt_eval_count;
|
|
31536
|
+
const completionTokens = result?.eval_count;
|
|
31537
|
+
if (isNonNegativeNumber(promptTokens)) {
|
|
31538
|
+
metrics.prompt_tokens = promptTokens;
|
|
31539
|
+
}
|
|
31540
|
+
if (isNonNegativeNumber(completionTokens)) {
|
|
31541
|
+
metrics.completion_tokens = completionTokens;
|
|
31542
|
+
}
|
|
31543
|
+
if (isNonNegativeNumber(promptTokens) || isNonNegativeNumber(completionTokens)) {
|
|
31544
|
+
metrics.tokens = (isNonNegativeNumber(promptTokens) ? promptTokens : 0) + (isNonNegativeNumber(completionTokens) ? completionTokens : 0);
|
|
31545
|
+
}
|
|
31546
|
+
return metrics;
|
|
31547
|
+
}
|
|
31548
|
+
function aggregateOllamaChatChunks(chunks, _result, event, _startTime) {
|
|
31549
|
+
const last = chunks.at(-1);
|
|
31550
|
+
const message = {
|
|
31551
|
+
role: "assistant",
|
|
31552
|
+
content: chunks.map((chunk) => chunk.message?.content ?? "").join(""),
|
|
31553
|
+
thinking: chunks.map((chunk) => chunk.message?.thinking ?? "").join(""),
|
|
31554
|
+
tool_calls: chunks.flatMap((chunk) => chunk.message?.tool_calls ?? [])
|
|
31555
|
+
};
|
|
31556
|
+
const response = {
|
|
31557
|
+
...last,
|
|
31558
|
+
message
|
|
31559
|
+
};
|
|
31560
|
+
return {
|
|
31561
|
+
output: extractOllamaChatOutput(
|
|
31562
|
+
response,
|
|
31563
|
+
countOllamaToolCalls(event?.arguments?.[0]?.messages)
|
|
31564
|
+
),
|
|
31565
|
+
metrics: extractOllamaMetrics(last ?? {}),
|
|
31566
|
+
metadata: extractOllamaResponseMetadata(last ?? {})
|
|
31567
|
+
};
|
|
31568
|
+
}
|
|
31569
|
+
function aggregateOllamaGenerateChunks(chunks, _result, _event, _startTime) {
|
|
31570
|
+
const last = chunks.at(-1);
|
|
31571
|
+
const response = {
|
|
31572
|
+
...last,
|
|
31573
|
+
response: chunks.map((chunk) => chunk.response ?? "").join(""),
|
|
31574
|
+
thinking: chunks.map((chunk) => chunk.thinking ?? "").join("")
|
|
31575
|
+
};
|
|
31576
|
+
return {
|
|
31577
|
+
output: extractOllamaGenerateOutput(response),
|
|
31578
|
+
metrics: extractOllamaMetrics(last ?? {}),
|
|
31579
|
+
metadata: extractOllamaResponseMetadata(last ?? {})
|
|
31580
|
+
};
|
|
31581
|
+
}
|
|
31582
|
+
|
|
30168
31583
|
// src/instrumentation/plugins/google-adk-channels.ts
|
|
30169
31584
|
var googleADKChannels = defineChannels(
|
|
30170
31585
|
"@google/adk",
|
|
@@ -33918,7 +35333,7 @@ var FlueObserveBridge = class {
|
|
|
33918
35333
|
return;
|
|
33919
35334
|
}
|
|
33920
35335
|
const state = this.operationsById.get(event.operationId) ?? this.startSyntheticOperation(event);
|
|
33921
|
-
const output = operationOutput(event);
|
|
35336
|
+
const output = operationOutput(event) ?? outputFromAgentTurn(state.latestAgentOutput);
|
|
33922
35337
|
const metadata = {
|
|
33923
35338
|
...state.metadata,
|
|
33924
35339
|
...extractEventMetadata(event),
|
|
@@ -33927,7 +35342,7 @@ var FlueObserveBridge = class {
|
|
|
33927
35342
|
};
|
|
33928
35343
|
this.finishPendingChildrenForOperation(event, output);
|
|
33929
35344
|
safeLog3(state.span, {
|
|
33930
|
-
...event.isError ? { error: toLoggedError(event.error) } : {},
|
|
35345
|
+
...event.isError ? { error: toLoggedError(event.errorInfo ?? event.error) } : {},
|
|
33931
35346
|
metadata,
|
|
33932
35347
|
metrics: durationMetrics2(event.durationMs),
|
|
33933
35348
|
output
|
|
@@ -33958,7 +35373,7 @@ var FlueObserveBridge = class {
|
|
|
33958
35373
|
};
|
|
33959
35374
|
const parent = this.parentSpanForTurn(event);
|
|
33960
35375
|
const span = startFlueSpan(parent, {
|
|
33961
|
-
name:
|
|
35376
|
+
name: "flue.turn",
|
|
33962
35377
|
spanAttributes: { type: "llm" /* LLM */ },
|
|
33963
35378
|
startTime: eventTime(event.timestamp),
|
|
33964
35379
|
event: {
|
|
@@ -34002,6 +35417,12 @@ var FlueObserveBridge = class {
|
|
|
34002
35417
|
},
|
|
34003
35418
|
output
|
|
34004
35419
|
});
|
|
35420
|
+
if (event.purpose === "agent" && event.operationId) {
|
|
35421
|
+
const operation = this.operationsById.get(event.operationId);
|
|
35422
|
+
if (operation) {
|
|
35423
|
+
operation.latestAgentOutput = output;
|
|
35424
|
+
}
|
|
35425
|
+
}
|
|
34005
35426
|
safeEnd(state.span, eventTime(event.timestamp));
|
|
34006
35427
|
this.turnsByKey.delete(key);
|
|
34007
35428
|
}
|
|
@@ -34081,7 +35502,7 @@ var FlueObserveBridge = class {
|
|
|
34081
35502
|
return;
|
|
34082
35503
|
}
|
|
34083
35504
|
safeLog3(state.span, {
|
|
34084
|
-
...event.isError ? { error: toLoggedError(event.result) } : {},
|
|
35505
|
+
...event.isError ? { error: toLoggedError(event.errorInfo ?? event.result) } : {},
|
|
34085
35506
|
metadata: {
|
|
34086
35507
|
...state.metadata,
|
|
34087
35508
|
...extractEventMetadata(event),
|
|
@@ -34127,6 +35548,7 @@ var FlueObserveBridge = class {
|
|
|
34127
35548
|
...event.usage ? { "flue.usage": event.usage } : {}
|
|
34128
35549
|
};
|
|
34129
35550
|
safeLog3(state.span, {
|
|
35551
|
+
...event.isError ? { error: toLoggedError(event.errorInfo ?? event.error) } : {},
|
|
34130
35552
|
metadata,
|
|
34131
35553
|
metrics: {
|
|
34132
35554
|
...durationMetrics2(event.durationMs),
|
|
@@ -34231,7 +35653,7 @@ var FlueObserveBridge = class {
|
|
|
34231
35653
|
...event.purpose ? { "flue.turn_purpose": event.purpose } : {}
|
|
34232
35654
|
};
|
|
34233
35655
|
const span = startFlueSpan(this.parentSpanForEvent(event), {
|
|
34234
|
-
name:
|
|
35656
|
+
name: "flue.turn",
|
|
34235
35657
|
spanAttributes: { type: "llm" /* LLM */ },
|
|
34236
35658
|
startTime: eventTime(event.timestamp),
|
|
34237
35659
|
event: { metadata }
|
|
@@ -34363,7 +35785,10 @@ function extractEventMetadata(event, ctx) {
|
|
|
34363
35785
|
return {
|
|
34364
35786
|
...event.runId ? { "flue.run_id": event.runId } : {},
|
|
34365
35787
|
...event.instanceId ? { "flue.instance_id": event.instanceId } : {},
|
|
35788
|
+
...event.submissionId ? { "flue.submission_id": event.submissionId } : {},
|
|
34366
35789
|
...event.dispatchId ? { "flue.dispatch_id": event.dispatchId } : {},
|
|
35790
|
+
...event.agentName ? { "flue.agent_name": event.agentName } : {},
|
|
35791
|
+
...event.conversationId ? { "flue.conversation_id": event.conversationId } : {},
|
|
34367
35792
|
...typeof event.eventIndex === "number" ? { "flue.event_index": event.eventIndex } : {},
|
|
34368
35793
|
...event.session ? { "flue.session": event.session } : {},
|
|
34369
35794
|
...event.parentSession ? { "flue.parent_session": event.parentSession } : {},
|
|
@@ -34392,7 +35817,7 @@ function flueTurnRequestInput(event) {
|
|
|
34392
35817
|
return event.request?.input ?? event.input;
|
|
34393
35818
|
}
|
|
34394
35819
|
function flueTurnRequestModel(event) {
|
|
34395
|
-
return event.request?.model ?? event.model;
|
|
35820
|
+
return event.request?.requestedModel ?? event.request?.model ?? event.model;
|
|
34396
35821
|
}
|
|
34397
35822
|
function flueTurnRequestProvider(event) {
|
|
34398
35823
|
return event.request?.providerName ?? event.provider ?? event.request?.providerId;
|
|
@@ -34401,10 +35826,10 @@ function flueTurnRequestApi(event) {
|
|
|
34401
35826
|
return event.request?.api ?? event.api;
|
|
34402
35827
|
}
|
|
34403
35828
|
function flueTurnRequestReasoning(event) {
|
|
34404
|
-
return event.request?.reasoning ?? event.reasoning;
|
|
35829
|
+
return event.request?.reasoningLevel ?? event.request?.reasoning ?? event.reasoning;
|
|
34405
35830
|
}
|
|
34406
35831
|
function flueTurnModel(event) {
|
|
34407
|
-
return event.request?.model ?? event.model;
|
|
35832
|
+
return event.response?.responseModel ?? event.request?.requestedModel ?? event.request?.model ?? event.model;
|
|
34408
35833
|
}
|
|
34409
35834
|
function flueTurnProvider(event) {
|
|
34410
35835
|
return event.request?.providerName ?? event.provider ?? event.request?.providerId;
|
|
@@ -34419,7 +35844,7 @@ function flueTurnOutput(event) {
|
|
|
34419
35844
|
return event.response?.output ?? event.output;
|
|
34420
35845
|
}
|
|
34421
35846
|
function flueTurnStopReason(event) {
|
|
34422
|
-
return event.response?.stopReason ?? event.stopReason;
|
|
35847
|
+
return event.response?.finishReason ?? event.response?.stopReason ?? event.stopReason;
|
|
34423
35848
|
}
|
|
34424
35849
|
function flueTurnError(event) {
|
|
34425
35850
|
return event.response?.error ?? event.response?.errorInfo?.message ?? event.error;
|
|
@@ -34434,6 +35859,9 @@ function flueToolInput(event) {
|
|
|
34434
35859
|
return event.input;
|
|
34435
35860
|
}
|
|
34436
35861
|
function flueToolOutput(event) {
|
|
35862
|
+
if (Object.hasOwn(event, "effectiveResult")) {
|
|
35863
|
+
return event.effectiveResult;
|
|
35864
|
+
}
|
|
34437
35865
|
return event.output !== void 0 ? event.output : event.result;
|
|
34438
35866
|
}
|
|
34439
35867
|
function flueToolError(event) {
|
|
@@ -34441,10 +35869,36 @@ function flueToolError(event) {
|
|
|
34441
35869
|
}
|
|
34442
35870
|
function operationOutput(event) {
|
|
34443
35871
|
if (event.operationKind === "prompt" || event.operationKind === "skill") {
|
|
34444
|
-
return llmResultFromOperationResult(event.result);
|
|
35872
|
+
return outputFromAgentInvocation(event.agentOutput) ?? llmResultFromOperationResult(event.result);
|
|
34445
35873
|
}
|
|
34446
35874
|
return event.result ?? (event.operationKind === "compact" ? { completed: true } : void 0);
|
|
34447
35875
|
}
|
|
35876
|
+
function outputFromAgentInvocation(output) {
|
|
35877
|
+
if (output?.type === "text") {
|
|
35878
|
+
return output.text;
|
|
35879
|
+
}
|
|
35880
|
+
if (output?.type === "data") {
|
|
35881
|
+
return output.data;
|
|
35882
|
+
}
|
|
35883
|
+
return void 0;
|
|
35884
|
+
}
|
|
35885
|
+
function outputFromAgentTurn(output) {
|
|
35886
|
+
if (!isObjectLike(output)) {
|
|
35887
|
+
return output;
|
|
35888
|
+
}
|
|
35889
|
+
const content = Reflect.get(output, "content");
|
|
35890
|
+
if (!Array.isArray(content)) {
|
|
35891
|
+
return output;
|
|
35892
|
+
}
|
|
35893
|
+
const text = content.flatMap((part) => {
|
|
35894
|
+
if (!isObjectLike(part) || Reflect.get(part, "type") !== "text") {
|
|
35895
|
+
return [];
|
|
35896
|
+
}
|
|
35897
|
+
const value = Reflect.get(part, "text");
|
|
35898
|
+
return typeof value === "string" ? [value] : [];
|
|
35899
|
+
});
|
|
35900
|
+
return text.length > 0 ? text.join("") : output;
|
|
35901
|
+
}
|
|
34448
35902
|
function llmResultFromOperationResult(result) {
|
|
34449
35903
|
if (!isObjectLike(result)) {
|
|
34450
35904
|
return result;
|
|
@@ -34543,7 +35997,7 @@ function safeEnd(span, endTime) {
|
|
|
34543
35997
|
}
|
|
34544
35998
|
}
|
|
34545
35999
|
function logInstrumentationError3(label, error2) {
|
|
34546
|
-
|
|
36000
|
+
debugLogger.debug(`Error in ${label} instrumentation:`, error2);
|
|
34547
36001
|
}
|
|
34548
36002
|
|
|
34549
36003
|
// src/wrappers/langchain/callback-handler.ts
|
|
@@ -35472,12 +36926,13 @@ var piCodingAgentChannels = defineChannels(
|
|
|
35472
36926
|
);
|
|
35473
36927
|
|
|
35474
36928
|
// src/instrumentation/plugins/pi-coding-agent-plugin.ts
|
|
35475
|
-
var
|
|
36929
|
+
var piAgentPatchStates = /* @__PURE__ */ new WeakMap();
|
|
36930
|
+
var piAgentEventSubscriptions = /* @__PURE__ */ new WeakSet();
|
|
35476
36931
|
var piPromptContextStore;
|
|
35477
36932
|
var PiCodingAgentPlugin = class extends BasePlugin {
|
|
35478
36933
|
activePromptStates = /* @__PURE__ */ new Set();
|
|
35479
36934
|
onEnable() {
|
|
35480
|
-
this.
|
|
36935
|
+
this.interceptPrompt();
|
|
35481
36936
|
}
|
|
35482
36937
|
onDisable() {
|
|
35483
36938
|
for (const unsubscribe of this.unsubscribers) {
|
|
@@ -35485,65 +36940,74 @@ var PiCodingAgentPlugin = class extends BasePlugin {
|
|
|
35485
36940
|
}
|
|
35486
36941
|
this.unsubscribers = [];
|
|
35487
36942
|
for (const state of [...this.activePromptStates]) {
|
|
35488
|
-
|
|
35489
|
-
logInstrumentationError4("Pi Coding Agent disable cleanup", error2);
|
|
35490
|
-
});
|
|
36943
|
+
finishPiPromptRun(state);
|
|
35491
36944
|
}
|
|
35492
36945
|
}
|
|
35493
|
-
|
|
35494
|
-
|
|
35495
|
-
|
|
35496
|
-
|
|
35497
|
-
|
|
35498
|
-
|
|
35499
|
-
|
|
35500
|
-
|
|
35501
|
-
|
|
35502
|
-
|
|
35503
|
-
|
|
35504
|
-
|
|
35505
|
-
|
|
35506
|
-
|
|
35507
|
-
|
|
35508
|
-
|
|
35509
|
-
|
|
35510
|
-
|
|
35511
|
-
|
|
35512
|
-
states.delete(event);
|
|
35513
|
-
state.promptCallEnded = true;
|
|
35514
|
-
if (!state.finalized && state.deferCompletionUntilTurnEnd && !state.turnEnded) {
|
|
35515
|
-
if (!state.sawStreamFn) {
|
|
35516
|
-
state.queued = true;
|
|
35517
|
-
if (!state.streamPatchState.queuedPromptStates.includes(state)) {
|
|
35518
|
-
state.streamPatchState.queuedPromptStates.push(state);
|
|
35519
|
-
}
|
|
36946
|
+
interceptPrompt() {
|
|
36947
|
+
this.unsubscribers.push(
|
|
36948
|
+
piCodingAgentChannels.prompt.intercept(
|
|
36949
|
+
(target, thisArg, args, additional) => {
|
|
36950
|
+
const invokeTarget = () => Reflect.apply(target, thisArg, args);
|
|
36951
|
+
let state;
|
|
36952
|
+
try {
|
|
36953
|
+
state = startPiPromptRun(
|
|
36954
|
+
{
|
|
36955
|
+
...additional,
|
|
36956
|
+
arguments: args,
|
|
36957
|
+
self: thisArg
|
|
36958
|
+
},
|
|
36959
|
+
(finalizedState) => {
|
|
36960
|
+
this.activePromptStates.delete(finalizedState);
|
|
36961
|
+
}
|
|
36962
|
+
);
|
|
36963
|
+
} catch (error2) {
|
|
36964
|
+
logInstrumentationError4("Pi Coding Agent prompt start", error2);
|
|
35520
36965
|
}
|
|
35521
|
-
|
|
35522
|
-
|
|
35523
|
-
|
|
35524
|
-
|
|
35525
|
-
|
|
35526
|
-
|
|
35527
|
-
|
|
35528
|
-
|
|
36966
|
+
if (!state) {
|
|
36967
|
+
return runWithAutoInstrumentationSuppressed(invokeTarget);
|
|
36968
|
+
}
|
|
36969
|
+
this.activePromptStates.add(state);
|
|
36970
|
+
return promptContextStore().run(
|
|
36971
|
+
state,
|
|
36972
|
+
() => runWithAutoInstrumentationSuppressed(() => {
|
|
36973
|
+
let result;
|
|
36974
|
+
try {
|
|
36975
|
+
result = invokeTarget();
|
|
36976
|
+
} catch (error2) {
|
|
36977
|
+
finishPiPromptRun(state, error2);
|
|
36978
|
+
throw error2;
|
|
36979
|
+
}
|
|
36980
|
+
return Promise.resolve(result).then(
|
|
36981
|
+
(value) => {
|
|
36982
|
+
finishPiPromptCall(state);
|
|
36983
|
+
return value;
|
|
36984
|
+
},
|
|
36985
|
+
(error2) => {
|
|
36986
|
+
finishPiPromptRun(state, error2);
|
|
36987
|
+
throw error2;
|
|
36988
|
+
}
|
|
36989
|
+
);
|
|
36990
|
+
})
|
|
36991
|
+
);
|
|
35529
36992
|
}
|
|
35530
|
-
|
|
35531
|
-
|
|
35532
|
-
}
|
|
35533
|
-
};
|
|
35534
|
-
channel2.subscribe(handlers);
|
|
35535
|
-
this.unsubscribers.push(() => {
|
|
35536
|
-
unbindAutoInstrumentationSuppression?.();
|
|
35537
|
-
channel2.unsubscribe(handlers);
|
|
35538
|
-
});
|
|
36993
|
+
)
|
|
36994
|
+
);
|
|
35539
36995
|
}
|
|
35540
36996
|
};
|
|
36997
|
+
function finishPiPromptCall(state) {
|
|
36998
|
+
state.promptCallEnded = true;
|
|
36999
|
+
if (state.deferCompletionUntilTurnEnd && !state.turnEnded) {
|
|
37000
|
+
return;
|
|
37001
|
+
}
|
|
37002
|
+
finishPiPromptRun(state);
|
|
37003
|
+
}
|
|
35541
37004
|
function startPiPromptRun(event, onFinalize) {
|
|
35542
37005
|
const session = extractSession(event);
|
|
35543
37006
|
const agent = session?.agent;
|
|
35544
37007
|
if (!session || !isPiAgent(agent)) {
|
|
35545
37008
|
return void 0;
|
|
35546
37009
|
}
|
|
37010
|
+
installPiAgentInstrumentation(agent);
|
|
35547
37011
|
const metadata = {
|
|
35548
37012
|
...extractSessionMetadata(session),
|
|
35549
37013
|
...extractPromptOptionsMetadata(event.arguments[1]),
|
|
@@ -35565,9 +37029,7 @@ function startPiPromptRun(event, onFinalize) {
|
|
|
35565
37029
|
INSTRUMENTATION_NAMES.PI_CODING_AGENT
|
|
35566
37030
|
)
|
|
35567
37031
|
);
|
|
35568
|
-
const streamPatchState = installPiStreamPatch(agent);
|
|
35569
37032
|
const options = event.arguments[1];
|
|
35570
|
-
const promptText = event.arguments[0];
|
|
35571
37033
|
const state = {
|
|
35572
37034
|
activeLlmSpans: /* @__PURE__ */ new Set(),
|
|
35573
37035
|
activeToolSpans: /* @__PURE__ */ new Map(),
|
|
@@ -35579,29 +37041,10 @@ function startPiPromptRun(event, onFinalize) {
|
|
|
35579
37041
|
metrics: {},
|
|
35580
37042
|
onFinalize,
|
|
35581
37043
|
promptCallEnded: false,
|
|
35582
|
-
...typeof promptText === "string" ? { promptText } : {},
|
|
35583
|
-
queued: false,
|
|
35584
37044
|
span,
|
|
35585
|
-
sawStreamFn: false,
|
|
35586
37045
|
startTime: getCurrentUnixTimestamp(),
|
|
35587
|
-
streamPatchState,
|
|
35588
37046
|
turnEnded: false
|
|
35589
37047
|
};
|
|
35590
|
-
state.restorePromptContext = enterPiPromptContext(state);
|
|
35591
|
-
streamPatchState.activePromptStates.add(state);
|
|
35592
|
-
try {
|
|
35593
|
-
state.unsubscribeAgent = agent.subscribe(async (agentEvent) => {
|
|
35594
|
-
try {
|
|
35595
|
-
await runWithAutoInstrumentationSuppressed(
|
|
35596
|
-
() => handlePiAgentEvent(state, agentEvent)
|
|
35597
|
-
);
|
|
35598
|
-
} catch (error2) {
|
|
35599
|
-
logInstrumentationError4("Pi Coding Agent event", error2);
|
|
35600
|
-
}
|
|
35601
|
-
});
|
|
35602
|
-
} catch (error2) {
|
|
35603
|
-
logInstrumentationError4("Pi Coding Agent event subscription", error2);
|
|
35604
|
-
}
|
|
35605
37048
|
return state;
|
|
35606
37049
|
}
|
|
35607
37050
|
function extractSession(event) {
|
|
@@ -35615,111 +37058,55 @@ function promptContextStore() {
|
|
|
35615
37058
|
piPromptContextStore ??= isomorph_default.newAsyncLocalStorage();
|
|
35616
37059
|
return piPromptContextStore;
|
|
35617
37060
|
}
|
|
35618
|
-
function currentPromptContextFrames() {
|
|
35619
|
-
return promptContextStore().getStore()?.frames ?? [];
|
|
35620
|
-
}
|
|
35621
37061
|
function currentPiPromptState() {
|
|
35622
|
-
|
|
35623
|
-
|
|
35624
|
-
|
|
35625
|
-
|
|
35626
|
-
|
|
35627
|
-
|
|
35628
|
-
|
|
35629
|
-
|
|
35630
|
-
|
|
35631
|
-
|
|
35632
|
-
|
|
35633
|
-
|
|
35634
|
-
const frames = currentPromptContextFrames().filter(
|
|
35635
|
-
(candidate) => candidate.id !== frame.id
|
|
35636
|
-
);
|
|
35637
|
-
promptContextStore().enterWith(frames.length > 0 ? { frames } : void 0);
|
|
35638
|
-
};
|
|
35639
|
-
}
|
|
35640
|
-
function installPiStreamPatch(agent) {
|
|
35641
|
-
const existing = piStreamPatchStates.get(agent);
|
|
35642
|
-
if (existing) {
|
|
35643
|
-
if (agent.streamFn !== existing.wrappedStreamFn) {
|
|
35644
|
-
debugLogger.debug(
|
|
35645
|
-
"Pi Coding Agent streamFn changed while Braintrust instrumentation was active; preserving existing patch state."
|
|
35646
|
-
);
|
|
35647
|
-
}
|
|
35648
|
-
return existing;
|
|
35649
|
-
}
|
|
35650
|
-
const patchState = {
|
|
35651
|
-
activePromptStates: /* @__PURE__ */ new Set(),
|
|
35652
|
-
agent,
|
|
35653
|
-
originalStreamFn: agent.streamFn,
|
|
35654
|
-
queuedPromptStates: [],
|
|
35655
|
-
wrappedStreamFn: agent.streamFn
|
|
35656
|
-
};
|
|
35657
|
-
patchState.wrappedStreamFn = makeSharedInstrumentedStreamFn(patchState);
|
|
35658
|
-
agent.streamFn = patchState.wrappedStreamFn;
|
|
35659
|
-
piStreamPatchStates.set(agent, patchState);
|
|
35660
|
-
return patchState;
|
|
35661
|
-
}
|
|
35662
|
-
function resolveStreamPromptState(patchState, context2) {
|
|
35663
|
-
let lastUserText;
|
|
35664
|
-
if (Array.isArray(context2.messages)) {
|
|
35665
|
-
for (let i = context2.messages.length - 1; i >= 0; i--) {
|
|
35666
|
-
const message = context2.messages[i];
|
|
35667
|
-
if (isPiUserMessage(message)) {
|
|
35668
|
-
if (typeof message.content === "string") {
|
|
35669
|
-
lastUserText = message.content;
|
|
35670
|
-
} else {
|
|
35671
|
-
lastUserText = message.content.flatMap((part) => part.type === "text" ? [part.text] : []).join("");
|
|
35672
|
-
}
|
|
35673
|
-
break;
|
|
35674
|
-
}
|
|
35675
|
-
}
|
|
35676
|
-
}
|
|
35677
|
-
if (lastUserText !== void 0) {
|
|
35678
|
-
const queuedMatch = patchState.queuedPromptStates.find(
|
|
35679
|
-
(state) => state.promptText === lastUserText
|
|
35680
|
-
);
|
|
35681
|
-
if (queuedMatch) {
|
|
35682
|
-
return queuedMatch;
|
|
35683
|
-
}
|
|
35684
|
-
const matches = [...patchState.activePromptStates].filter(
|
|
35685
|
-
(state) => state.promptText === lastUserText
|
|
37062
|
+
return promptContextStore().getStore();
|
|
37063
|
+
}
|
|
37064
|
+
function installPiAgentInstrumentation(agent) {
|
|
37065
|
+
const existing = piAgentPatchStates.get(agent);
|
|
37066
|
+
if (!existing || agent.streamFn !== existing.wrappedStreamFn) {
|
|
37067
|
+
const patchState = {
|
|
37068
|
+
originalStreamFn: agent.streamFn,
|
|
37069
|
+
wrappedStreamFn: agent.streamFn
|
|
37070
|
+
};
|
|
37071
|
+
patchState.wrappedStreamFn = makeInstrumentedStreamFn(
|
|
37072
|
+
agent,
|
|
37073
|
+
patchState.originalStreamFn
|
|
35686
37074
|
);
|
|
35687
|
-
|
|
35688
|
-
|
|
35689
|
-
}
|
|
37075
|
+
agent.streamFn = patchState.wrappedStreamFn;
|
|
37076
|
+
piAgentPatchStates.set(agent, patchState);
|
|
35690
37077
|
}
|
|
35691
|
-
|
|
35692
|
-
|
|
35693
|
-
return contextState;
|
|
37078
|
+
if (piAgentEventSubscriptions.has(agent)) {
|
|
37079
|
+
return;
|
|
35694
37080
|
}
|
|
35695
|
-
|
|
35696
|
-
|
|
37081
|
+
try {
|
|
37082
|
+
agent.subscribe(async (event) => {
|
|
37083
|
+
const state = currentPiPromptState();
|
|
37084
|
+
if (!state || state.agent !== agent || state.finalized) {
|
|
37085
|
+
return;
|
|
37086
|
+
}
|
|
37087
|
+
try {
|
|
37088
|
+
await runWithAutoInstrumentationSuppressed(
|
|
37089
|
+
() => handlePiAgentEvent(state, event)
|
|
37090
|
+
);
|
|
37091
|
+
} catch (error2) {
|
|
37092
|
+
logInstrumentationError4("Pi Coding Agent event", error2);
|
|
37093
|
+
}
|
|
37094
|
+
});
|
|
37095
|
+
piAgentEventSubscriptions.add(agent);
|
|
37096
|
+
} catch (error2) {
|
|
37097
|
+
logInstrumentationError4("Pi Coding Agent event subscription", error2);
|
|
35697
37098
|
}
|
|
35698
|
-
return void 0;
|
|
35699
37099
|
}
|
|
35700
|
-
function
|
|
37100
|
+
function makeInstrumentedStreamFn(agent, originalStreamFn) {
|
|
35701
37101
|
return async function instrumentedPiStreamFn(model, context2, options) {
|
|
35702
|
-
const
|
|
35703
|
-
|
|
35704
|
-
|
|
35705
|
-
|
|
35706
|
-
context2,
|
|
35707
|
-
options
|
|
35708
|
-
]);
|
|
35709
|
-
return patchState.activePromptStates.size > 0 ? runWithAutoInstrumentationSuppressed(invokeOriginal) : invokeOriginal();
|
|
37102
|
+
const invokeOriginal = () => Reflect.apply(originalStreamFn, this, [model, context2, options]);
|
|
37103
|
+
const state = currentPiPromptState();
|
|
37104
|
+
if (!state || state.agent !== agent || state.finalized) {
|
|
37105
|
+
return invokeOriginal();
|
|
35710
37106
|
}
|
|
35711
|
-
state.sawStreamFn = true;
|
|
35712
|
-
removeQueuedPromptState(state);
|
|
35713
|
-
state.streamPatchState.eventPromptState = state;
|
|
35714
37107
|
const llmState = await startPiLlmSpan(state, model, context2, options);
|
|
35715
37108
|
try {
|
|
35716
|
-
const stream = await runWithAutoInstrumentationSuppressed(
|
|
35717
|
-
() => Reflect.apply(patchState.originalStreamFn, this, [
|
|
35718
|
-
model,
|
|
35719
|
-
context2,
|
|
35720
|
-
options
|
|
35721
|
-
])
|
|
35722
|
-
);
|
|
37109
|
+
const stream = await runWithAutoInstrumentationSuppressed(invokeOriginal);
|
|
35723
37110
|
return patchAssistantMessageStream(stream, state, llmState);
|
|
35724
37111
|
} catch (error2) {
|
|
35725
37112
|
finishPiLlmSpan(state, llmState, void 0, error2);
|
|
@@ -35866,13 +37253,6 @@ async function handlePiAgentEvent(state, event) {
|
|
|
35866
37253
|
if (state.finalized) {
|
|
35867
37254
|
return;
|
|
35868
37255
|
}
|
|
35869
|
-
const eventPromptState = state.streamPatchState.eventPromptState;
|
|
35870
|
-
if (eventPromptState && eventPromptState !== state) {
|
|
35871
|
-
return;
|
|
35872
|
-
}
|
|
35873
|
-
if (!eventPromptState && (state.queued || state.streamPatchState.activePromptStates.size > 1 && currentPiPromptState() !== state)) {
|
|
35874
|
-
return;
|
|
35875
|
-
}
|
|
35876
37256
|
switch (event.type) {
|
|
35877
37257
|
case "message_end":
|
|
35878
37258
|
if (isPiAssistantMessage(event.message)) {
|
|
@@ -35887,11 +37267,8 @@ async function handlePiAgentEvent(state, event) {
|
|
|
35887
37267
|
addMetrics(state.metrics, extractUsageMetrics2(event.message.usage));
|
|
35888
37268
|
}
|
|
35889
37269
|
}
|
|
35890
|
-
if (state.streamPatchState.eventPromptState === state) {
|
|
35891
|
-
state.streamPatchState.eventPromptState = void 0;
|
|
35892
|
-
}
|
|
35893
37270
|
if (state.promptCallEnded && state.deferCompletionUntilTurnEnd) {
|
|
35894
|
-
|
|
37271
|
+
finishPiPromptRun(state);
|
|
35895
37272
|
}
|
|
35896
37273
|
return;
|
|
35897
37274
|
case "tool_execution_start":
|
|
@@ -35964,19 +37341,13 @@ function finishPiToolSpan(state, event) {
|
|
|
35964
37341
|
}
|
|
35965
37342
|
}
|
|
35966
37343
|
}
|
|
35967
|
-
|
|
37344
|
+
function finishPiPromptRun(state, error2) {
|
|
35968
37345
|
if (state.finalized) {
|
|
35969
37346
|
return;
|
|
35970
37347
|
}
|
|
35971
37348
|
state.finalized = true;
|
|
35972
37349
|
state.onFinalize?.(state);
|
|
35973
|
-
|
|
35974
|
-
try {
|
|
35975
|
-
state.unsubscribeAgent?.();
|
|
35976
|
-
} catch (unsubscribeError) {
|
|
35977
|
-
logInstrumentationError4("Pi Coding Agent unsubscribe", unsubscribeError);
|
|
35978
|
-
}
|
|
35979
|
-
await finishOpenLlmSpans(state, error2);
|
|
37350
|
+
finishOpenLlmSpans(state, error2);
|
|
35980
37351
|
finishOpenToolSpans(state, error2);
|
|
35981
37352
|
const metadata = {
|
|
35982
37353
|
...state.metadata,
|
|
@@ -35993,34 +37364,14 @@ async function finalizePiPromptRun(state, error2) {
|
|
|
35993
37364
|
output: state.output
|
|
35994
37365
|
});
|
|
35995
37366
|
} finally {
|
|
35996
|
-
|
|
35997
|
-
|
|
35998
|
-
}
|
|
35999
|
-
|
|
36000
|
-
|
|
36001
|
-
patchState.activePromptStates.delete(state);
|
|
36002
|
-
removeQueuedPromptState(state);
|
|
36003
|
-
if (patchState.eventPromptState === state) {
|
|
36004
|
-
patchState.eventPromptState = void 0;
|
|
36005
|
-
}
|
|
36006
|
-
state.restorePromptContext?.();
|
|
36007
|
-
if (patchState.activePromptStates.size > 0) {
|
|
36008
|
-
return;
|
|
36009
|
-
}
|
|
36010
|
-
if (patchState.agent.streamFn === patchState.wrappedStreamFn) {
|
|
36011
|
-
patchState.agent.streamFn = patchState.originalStreamFn;
|
|
36012
|
-
}
|
|
36013
|
-
piStreamPatchStates.delete(patchState.agent);
|
|
36014
|
-
}
|
|
36015
|
-
function removeQueuedPromptState(state) {
|
|
36016
|
-
state.queued = false;
|
|
36017
|
-
const queuedPromptStates = state.streamPatchState.queuedPromptStates;
|
|
36018
|
-
const index = queuedPromptStates.indexOf(state);
|
|
36019
|
-
if (index >= 0) {
|
|
36020
|
-
queuedPromptStates.splice(index, 1);
|
|
37367
|
+
try {
|
|
37368
|
+
state.span.end();
|
|
37369
|
+
} catch (endError) {
|
|
37370
|
+
logInstrumentationError4("Pi Coding Agent prompt end", endError);
|
|
37371
|
+
}
|
|
36021
37372
|
}
|
|
36022
37373
|
}
|
|
36023
|
-
|
|
37374
|
+
function finishOpenLlmSpans(state, error2) {
|
|
36024
37375
|
for (const llmState of [...state.activeLlmSpans]) {
|
|
36025
37376
|
finishPiLlmSpan(state, llmState, void 0, error2);
|
|
36026
37377
|
}
|
|
@@ -36101,7 +37452,7 @@ function normalizeAssistantMessage(message) {
|
|
|
36101
37452
|
(part) => part.type === "thinking" && !part.redacted ? [part.thinking] : []
|
|
36102
37453
|
).join("");
|
|
36103
37454
|
const toolCalls = message.content.flatMap(
|
|
36104
|
-
(part) => part.type === "toolCall" ? [
|
|
37455
|
+
(part) => part.type === "toolCall" ? [normalizeToolCall2(part)] : []
|
|
36105
37456
|
);
|
|
36106
37457
|
return {
|
|
36107
37458
|
role: "assistant",
|
|
@@ -36136,13 +37487,13 @@ function normalizeUserContent(content) {
|
|
|
36136
37487
|
return part;
|
|
36137
37488
|
});
|
|
36138
37489
|
}
|
|
36139
|
-
function
|
|
37490
|
+
function normalizeToolCall2(toolCall) {
|
|
36140
37491
|
return {
|
|
36141
37492
|
id: toolCall.id,
|
|
36142
37493
|
type: "function",
|
|
36143
37494
|
function: {
|
|
36144
37495
|
name: toolCall.name,
|
|
36145
|
-
arguments:
|
|
37496
|
+
arguments: stringifyArguments2(toolCall.arguments)
|
|
36146
37497
|
}
|
|
36147
37498
|
};
|
|
36148
37499
|
}
|
|
@@ -36325,7 +37676,7 @@ function cleanMetrics5(metrics) {
|
|
|
36325
37676
|
}
|
|
36326
37677
|
return cleaned;
|
|
36327
37678
|
}
|
|
36328
|
-
function
|
|
37679
|
+
function stringifyArguments2(value) {
|
|
36329
37680
|
if (typeof value === "string") {
|
|
36330
37681
|
return value;
|
|
36331
37682
|
}
|
|
@@ -37893,6 +39244,7 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
37893
39244
|
anthropicPlugin = null;
|
|
37894
39245
|
aiSDKPlugin = null;
|
|
37895
39246
|
claudeAgentSDKPlugin = null;
|
|
39247
|
+
cloudflareThinkPlugin = null;
|
|
37896
39248
|
cursorSDKPlugin = null;
|
|
37897
39249
|
openAIAgentsPlugin = null;
|
|
37898
39250
|
googleGenAIPlugin = null;
|
|
@@ -37901,6 +39253,7 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
37901
39253
|
openRouterPlugin = null;
|
|
37902
39254
|
openRouterAgentPlugin = null;
|
|
37903
39255
|
mistralPlugin = null;
|
|
39256
|
+
ollamaPlugin = null;
|
|
37904
39257
|
googleADKPlugin = null;
|
|
37905
39258
|
coherePlugin = null;
|
|
37906
39259
|
groqPlugin = null;
|
|
@@ -37940,6 +39293,10 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
37940
39293
|
this.claudeAgentSDKPlugin = new ClaudeAgentSDKPlugin();
|
|
37941
39294
|
this.claudeAgentSDKPlugin.enable();
|
|
37942
39295
|
}
|
|
39296
|
+
if (integrations.cloudflareThink !== false) {
|
|
39297
|
+
this.cloudflareThinkPlugin = new CloudflareThinkPlugin();
|
|
39298
|
+
this.cloudflareThinkPlugin.enable();
|
|
39299
|
+
}
|
|
37943
39300
|
if (integrations.cursorSDK !== false && integrations.cursor !== false) {
|
|
37944
39301
|
this.cursorSDKPlugin = new CursorSDKPlugin();
|
|
37945
39302
|
this.cursorSDKPlugin.enable();
|
|
@@ -37970,6 +39327,10 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
37970
39327
|
this.mistralPlugin = new MistralPlugin();
|
|
37971
39328
|
this.mistralPlugin.enable();
|
|
37972
39329
|
}
|
|
39330
|
+
if (integrations.ollama !== false) {
|
|
39331
|
+
this.ollamaPlugin = new OllamaPlugin();
|
|
39332
|
+
this.ollamaPlugin.enable();
|
|
39333
|
+
}
|
|
37973
39334
|
if (integrations.googleADK !== false) {
|
|
37974
39335
|
this.googleADKPlugin = new GoogleADKPlugin();
|
|
37975
39336
|
this.googleADKPlugin.enable();
|
|
@@ -38046,6 +39407,10 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
38046
39407
|
this.claudeAgentSDKPlugin.disable();
|
|
38047
39408
|
this.claudeAgentSDKPlugin = null;
|
|
38048
39409
|
}
|
|
39410
|
+
if (this.cloudflareThinkPlugin) {
|
|
39411
|
+
this.cloudflareThinkPlugin.disable();
|
|
39412
|
+
this.cloudflareThinkPlugin = null;
|
|
39413
|
+
}
|
|
38049
39414
|
if (this.cursorSDKPlugin) {
|
|
38050
39415
|
this.cursorSDKPlugin.disable();
|
|
38051
39416
|
this.cursorSDKPlugin = null;
|
|
@@ -38078,6 +39443,10 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
38078
39443
|
this.mistralPlugin.disable();
|
|
38079
39444
|
this.mistralPlugin = null;
|
|
38080
39445
|
}
|
|
39446
|
+
if (this.ollamaPlugin) {
|
|
39447
|
+
this.ollamaPlugin.disable();
|
|
39448
|
+
this.ollamaPlugin = null;
|
|
39449
|
+
}
|
|
38081
39450
|
if (this.googleADKPlugin) {
|
|
38082
39451
|
this.googleADKPlugin.disable();
|
|
38083
39452
|
this.googleADKPlugin = null;
|
|
@@ -38163,6 +39532,7 @@ var envIntegrationAliases = {
|
|
|
38163
39532
|
cloudflareaichat: "cloudflareAIChat",
|
|
38164
39533
|
"cloudflare-ai-chat": "cloudflareAIChat",
|
|
38165
39534
|
"@cloudflare/ai-chat": "cloudflareAIChat",
|
|
39535
|
+
cloudflarethink: "cloudflareThink",
|
|
38166
39536
|
cursor: "cursor",
|
|
38167
39537
|
"cursor-sdk": "cursorSDK",
|
|
38168
39538
|
cursorsdk: "cursorSDK",
|
|
@@ -38183,6 +39553,7 @@ var envIntegrationAliases = {
|
|
|
38183
39553
|
openrouteragent: "openrouterAgent",
|
|
38184
39554
|
"openrouter-agent": "openrouterAgent",
|
|
38185
39555
|
mistral: "mistral",
|
|
39556
|
+
ollama: "ollama",
|
|
38186
39557
|
googleadk: "googleADK",
|
|
38187
39558
|
"google-adk": "googleADK",
|
|
38188
39559
|
cohere: "cohere",
|
|
@@ -38218,6 +39589,7 @@ function getDefaultInstrumentationIntegrations() {
|
|
|
38218
39589
|
huggingface: true,
|
|
38219
39590
|
claudeAgentSDK: true,
|
|
38220
39591
|
cloudflareAIChat: true,
|
|
39592
|
+
cloudflareThink: true,
|
|
38221
39593
|
cursor: true,
|
|
38222
39594
|
cursorSDK: true,
|
|
38223
39595
|
flue: true,
|
|
@@ -38226,6 +39598,7 @@ function getDefaultInstrumentationIntegrations() {
|
|
|
38226
39598
|
openrouter: true,
|
|
38227
39599
|
openrouterAgent: true,
|
|
38228
39600
|
mistral: true,
|
|
39601
|
+
ollama: true,
|
|
38229
39602
|
cohere: true,
|
|
38230
39603
|
groq: true,
|
|
38231
39604
|
bedrock: true,
|