@bitfab/sdk 0.18.0 → 0.18.2
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/dist/{chunk-QT7HWOKU.js → chunk-PY6V4FE3.js} +1 -1
- package/dist/chunk-PY6V4FE3.js.map +1 -0
- package/dist/{chunk-S3YLZ47O.js → chunk-UTVFKV2Z.js} +171 -18
- package/dist/chunk-UTVFKV2Z.js.map +1 -0
- package/dist/index.cjs +168 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +12 -4
- package/dist/index.d.ts +12 -4
- package/dist/index.js +2 -2
- package/dist/node.cjs +168 -15
- package/dist/node.cjs.map +1 -1
- package/dist/node.js +2 -2
- package/dist/{replay-BIPIDXX6.js → replay-P3QXRLOC.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-QT7HWOKU.js.map +0 -1
- package/dist/chunk-S3YLZ47O.js.map +0 -1
- /package/dist/{replay-BIPIDXX6.js.map → replay-P3QXRLOC.js.map} +0 -0
package/dist/index.d.cts
CHANGED
|
@@ -225,7 +225,7 @@ interface CodeChangeFile {
|
|
|
225
225
|
* LangGraph/LangChain callback handler for Bitfab tracing.
|
|
226
226
|
*
|
|
227
227
|
* Hooks into LangGraph's callback system to capture graph node execution,
|
|
228
|
-
* LLM calls, and tool invocations as Bitfab spans
|
|
228
|
+
* LLM calls, and tool invocations as Bitfab spans, without requiring users
|
|
229
229
|
* to wrap their functions with withSpan (which fails on non-serializable args).
|
|
230
230
|
*
|
|
231
231
|
* Duck-typed to match LangChain.js's BaseCallbackHandler interface.
|
|
@@ -238,8 +238,8 @@ interface ActiveSpanContext$1 {
|
|
|
238
238
|
/**
|
|
239
239
|
* LangChain/LangGraph callback handler that sends traces to Bitfab.
|
|
240
240
|
*
|
|
241
|
-
* Duck-typed to match LangChain.js's BaseCallbackHandler
|
|
242
|
-
* `@langchain/core` dependency required. Pass as a callback:
|
|
241
|
+
* Duck-typed to match LangChain.js's BaseCallbackHandler, so no
|
|
242
|
+
* `@langchain/core` dependency is required. Pass as a callback:
|
|
243
243
|
*
|
|
244
244
|
* ```typescript
|
|
245
245
|
* const handler = bitfab.getLangGraphCallbackHandler("my-agent");
|
|
@@ -335,6 +335,14 @@ declare class ReplayEnvironment {
|
|
|
335
335
|
get active(): boolean;
|
|
336
336
|
/** Non-throwing variant for callers that handle the inactive case. */
|
|
337
337
|
snapshot(): ReplayEnvironmentSnapshot | null;
|
|
338
|
+
/**
|
|
339
|
+
* Record on the replay context that customer code obtained the branch
|
|
340
|
+
* URL. Only `databaseUrl` and `snapshot()` count — `active`, `readOnly`
|
|
341
|
+
* and friends inspect the lease without exposing the connection string,
|
|
342
|
+
* so they don't prove the replayed code could have connected to the
|
|
343
|
+
* branch.
|
|
344
|
+
*/
|
|
345
|
+
private markAccessed;
|
|
338
346
|
private read;
|
|
339
347
|
private require;
|
|
340
348
|
}
|
|
@@ -1055,7 +1063,7 @@ declare class BitfabFunction {
|
|
|
1055
1063
|
/**
|
|
1056
1064
|
* SDK version from package.json (injected at build time)
|
|
1057
1065
|
*/
|
|
1058
|
-
declare const __version__ = "0.18.
|
|
1066
|
+
declare const __version__ = "0.18.2";
|
|
1059
1067
|
|
|
1060
1068
|
/**
|
|
1061
1069
|
* Constants for the Bitfab SDK.
|
package/dist/index.d.ts
CHANGED
|
@@ -225,7 +225,7 @@ interface CodeChangeFile {
|
|
|
225
225
|
* LangGraph/LangChain callback handler for Bitfab tracing.
|
|
226
226
|
*
|
|
227
227
|
* Hooks into LangGraph's callback system to capture graph node execution,
|
|
228
|
-
* LLM calls, and tool invocations as Bitfab spans
|
|
228
|
+
* LLM calls, and tool invocations as Bitfab spans, without requiring users
|
|
229
229
|
* to wrap their functions with withSpan (which fails on non-serializable args).
|
|
230
230
|
*
|
|
231
231
|
* Duck-typed to match LangChain.js's BaseCallbackHandler interface.
|
|
@@ -238,8 +238,8 @@ interface ActiveSpanContext$1 {
|
|
|
238
238
|
/**
|
|
239
239
|
* LangChain/LangGraph callback handler that sends traces to Bitfab.
|
|
240
240
|
*
|
|
241
|
-
* Duck-typed to match LangChain.js's BaseCallbackHandler
|
|
242
|
-
* `@langchain/core` dependency required. Pass as a callback:
|
|
241
|
+
* Duck-typed to match LangChain.js's BaseCallbackHandler, so no
|
|
242
|
+
* `@langchain/core` dependency is required. Pass as a callback:
|
|
243
243
|
*
|
|
244
244
|
* ```typescript
|
|
245
245
|
* const handler = bitfab.getLangGraphCallbackHandler("my-agent");
|
|
@@ -335,6 +335,14 @@ declare class ReplayEnvironment {
|
|
|
335
335
|
get active(): boolean;
|
|
336
336
|
/** Non-throwing variant for callers that handle the inactive case. */
|
|
337
337
|
snapshot(): ReplayEnvironmentSnapshot | null;
|
|
338
|
+
/**
|
|
339
|
+
* Record on the replay context that customer code obtained the branch
|
|
340
|
+
* URL. Only `databaseUrl` and `snapshot()` count — `active`, `readOnly`
|
|
341
|
+
* and friends inspect the lease without exposing the connection string,
|
|
342
|
+
* so they don't prove the replayed code could have connected to the
|
|
343
|
+
* branch.
|
|
344
|
+
*/
|
|
345
|
+
private markAccessed;
|
|
338
346
|
private read;
|
|
339
347
|
private require;
|
|
340
348
|
}
|
|
@@ -1055,7 +1063,7 @@ declare class BitfabFunction {
|
|
|
1055
1063
|
/**
|
|
1056
1064
|
* SDK version from package.json (injected at build time)
|
|
1057
1065
|
*/
|
|
1058
|
-
declare const __version__ = "0.18.
|
|
1066
|
+
declare const __version__ = "0.18.2";
|
|
1059
1067
|
|
|
1060
1068
|
/**
|
|
1061
1069
|
* Constants for the Bitfab SDK.
|
package/dist/index.js
CHANGED
|
@@ -11,10 +11,10 @@ import {
|
|
|
11
11
|
flushTraces,
|
|
12
12
|
getCurrentSpan,
|
|
13
13
|
getCurrentTrace
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-UTVFKV2Z.js";
|
|
15
15
|
import {
|
|
16
16
|
BitfabError
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-PY6V4FE3.js";
|
|
18
18
|
export {
|
|
19
19
|
Bitfab,
|
|
20
20
|
BitfabClaudeAgentHandler,
|
package/dist/node.cjs
CHANGED
|
@@ -447,7 +447,7 @@ registerAsyncLocalStorageClass(
|
|
|
447
447
|
);
|
|
448
448
|
|
|
449
449
|
// src/version.generated.ts
|
|
450
|
-
var __version__ = "0.18.
|
|
450
|
+
var __version__ = "0.18.2";
|
|
451
451
|
|
|
452
452
|
// src/constants.ts
|
|
453
453
|
var DEFAULT_SERVICE_URL = "https://bitfab.ai";
|
|
@@ -1677,21 +1677,131 @@ function extractModelName(serialized, metadata) {
|
|
|
1677
1677
|
}
|
|
1678
1678
|
return void 0;
|
|
1679
1679
|
}
|
|
1680
|
+
function asTokenCount(value) {
|
|
1681
|
+
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
1682
|
+
}
|
|
1683
|
+
function normalizeTokenUsage(raw) {
|
|
1684
|
+
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
|
|
1685
|
+
return null;
|
|
1686
|
+
}
|
|
1687
|
+
const u = raw;
|
|
1688
|
+
if ("cache_read_input_tokens" in u || "cache_creation_input_tokens" in u) {
|
|
1689
|
+
const cacheRead = asTokenCount(u.cache_read_input_tokens);
|
|
1690
|
+
const cacheCreation = asTokenCount(u.cache_creation_input_tokens);
|
|
1691
|
+
const baseInput = asTokenCount(u.input_tokens);
|
|
1692
|
+
const outputTokens = asTokenCount(u.output_tokens);
|
|
1693
|
+
if (cacheRead === null && cacheCreation === null && baseInput === null && outputTokens === null) {
|
|
1694
|
+
return null;
|
|
1695
|
+
}
|
|
1696
|
+
const inputTokens = (baseInput ?? 0) + (cacheRead ?? 0) + (cacheCreation ?? 0);
|
|
1697
|
+
return {
|
|
1698
|
+
inputTokens,
|
|
1699
|
+
outputTokens,
|
|
1700
|
+
totalTokens: inputTokens + (outputTokens ?? 0),
|
|
1701
|
+
cachedInputTokens: cacheRead
|
|
1702
|
+
};
|
|
1703
|
+
}
|
|
1704
|
+
if ("prompt_tokens" in u || "completion_tokens" in u || "promptTokens" in u || "completionTokens" in u) {
|
|
1705
|
+
const promptDetails = u.prompt_tokens_details ?? {};
|
|
1706
|
+
return withAnyTokenCount({
|
|
1707
|
+
inputTokens: asTokenCount(u.prompt_tokens) ?? asTokenCount(u.promptTokens),
|
|
1708
|
+
outputTokens: asTokenCount(u.completion_tokens) ?? asTokenCount(u.completionTokens),
|
|
1709
|
+
totalTokens: asTokenCount(u.total_tokens) ?? asTokenCount(u.totalTokens),
|
|
1710
|
+
cachedInputTokens: asTokenCount(promptDetails.cached_tokens)
|
|
1711
|
+
});
|
|
1712
|
+
}
|
|
1713
|
+
if ("prompt_token_count" in u || "candidates_token_count" in u) {
|
|
1714
|
+
return withAnyTokenCount({
|
|
1715
|
+
inputTokens: asTokenCount(u.prompt_token_count),
|
|
1716
|
+
outputTokens: asTokenCount(u.candidates_token_count),
|
|
1717
|
+
totalTokens: asTokenCount(u.total_token_count),
|
|
1718
|
+
cachedInputTokens: asTokenCount(u.cached_content_token_count)
|
|
1719
|
+
});
|
|
1720
|
+
}
|
|
1721
|
+
if ("input_tokens" in u || "output_tokens" in u) {
|
|
1722
|
+
const inputDetails = u.input_token_details ?? {};
|
|
1723
|
+
const inputTokens = asTokenCount(u.input_tokens);
|
|
1724
|
+
const outputTokens = asTokenCount(u.output_tokens);
|
|
1725
|
+
let totalTokens = asTokenCount(u.total_tokens);
|
|
1726
|
+
if (totalTokens === null && inputTokens !== null && outputTokens !== null) {
|
|
1727
|
+
totalTokens = inputTokens + outputTokens;
|
|
1728
|
+
}
|
|
1729
|
+
return withAnyTokenCount({
|
|
1730
|
+
inputTokens,
|
|
1731
|
+
outputTokens,
|
|
1732
|
+
totalTokens,
|
|
1733
|
+
cachedInputTokens: asTokenCount(inputDetails.cache_read)
|
|
1734
|
+
});
|
|
1735
|
+
}
|
|
1736
|
+
return null;
|
|
1737
|
+
}
|
|
1738
|
+
function withAnyTokenCount(usage) {
|
|
1739
|
+
const hasCount = usage.inputTokens !== null || usage.outputTokens !== null || usage.totalTokens !== null || usage.cachedInputTokens !== null;
|
|
1740
|
+
return hasCount ? usage : null;
|
|
1741
|
+
}
|
|
1742
|
+
function addUsage(totals, usage) {
|
|
1743
|
+
for (const key of [
|
|
1744
|
+
"inputTokens",
|
|
1745
|
+
"outputTokens",
|
|
1746
|
+
"totalTokens",
|
|
1747
|
+
"cachedInputTokens"
|
|
1748
|
+
]) {
|
|
1749
|
+
const value = usage[key];
|
|
1750
|
+
if (value !== null) {
|
|
1751
|
+
totals[key] = (totals[key] ?? 0) + value;
|
|
1752
|
+
}
|
|
1753
|
+
}
|
|
1754
|
+
}
|
|
1755
|
+
function usageFromGenerations(generations) {
|
|
1756
|
+
if (!generations?.length) {
|
|
1757
|
+
return null;
|
|
1758
|
+
}
|
|
1759
|
+
const totals = {
|
|
1760
|
+
inputTokens: null,
|
|
1761
|
+
outputTokens: null,
|
|
1762
|
+
totalTokens: null,
|
|
1763
|
+
cachedInputTokens: null
|
|
1764
|
+
};
|
|
1765
|
+
let found = false;
|
|
1766
|
+
for (const batch of generations) {
|
|
1767
|
+
if (!Array.isArray(batch)) {
|
|
1768
|
+
continue;
|
|
1769
|
+
}
|
|
1770
|
+
for (const gen of batch) {
|
|
1771
|
+
const msg = gen?.message;
|
|
1772
|
+
if (!msg || typeof msg !== "object") {
|
|
1773
|
+
continue;
|
|
1774
|
+
}
|
|
1775
|
+
const responseMetadata = msg.response_metadata;
|
|
1776
|
+
const usage = normalizeTokenUsage(msg.usage_metadata) ?? normalizeTokenUsage(responseMetadata?.token_usage) ?? normalizeTokenUsage(responseMetadata?.usage) ?? normalizeTokenUsage(responseMetadata?.tokenUsage);
|
|
1777
|
+
if (!usage) {
|
|
1778
|
+
continue;
|
|
1779
|
+
}
|
|
1780
|
+
found = true;
|
|
1781
|
+
addUsage(totals, usage);
|
|
1782
|
+
}
|
|
1783
|
+
}
|
|
1784
|
+
return found ? totals : null;
|
|
1785
|
+
}
|
|
1680
1786
|
function extractUsage2(output) {
|
|
1787
|
+
const generations = output.generations;
|
|
1788
|
+
const llmOutput = output.llmOutput ?? output.llm_output;
|
|
1789
|
+
const normalized = usageFromGenerations(generations) ?? normalizeTokenUsage(llmOutput?.tokenUsage) ?? normalizeTokenUsage(llmOutput?.token_usage) ?? normalizeTokenUsage(llmOutput?.usage);
|
|
1681
1790
|
const usage = {};
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
if (inputTokens !== void 0 && inputTokens !== null) {
|
|
1688
|
-
usage.inputTokens = inputTokens;
|
|
1791
|
+
if (!normalized) {
|
|
1792
|
+
return usage;
|
|
1793
|
+
}
|
|
1794
|
+
if (normalized.inputTokens !== null) {
|
|
1795
|
+
usage.inputTokens = normalized.inputTokens;
|
|
1689
1796
|
}
|
|
1690
|
-
if (outputTokens !==
|
|
1691
|
-
usage.outputTokens = outputTokens;
|
|
1797
|
+
if (normalized.outputTokens !== null) {
|
|
1798
|
+
usage.outputTokens = normalized.outputTokens;
|
|
1692
1799
|
}
|
|
1693
|
-
if (totalTokens !==
|
|
1694
|
-
usage.totalTokens = totalTokens;
|
|
1800
|
+
if (normalized.totalTokens !== null) {
|
|
1801
|
+
usage.totalTokens = normalized.totalTokens;
|
|
1802
|
+
}
|
|
1803
|
+
if (normalized.cachedInputTokens !== null) {
|
|
1804
|
+
usage.cachedInputTokens = normalized.cachedInputTokens;
|
|
1695
1805
|
}
|
|
1696
1806
|
return usage;
|
|
1697
1807
|
}
|
|
@@ -2052,7 +2162,9 @@ var ReplayEnvironment = class {
|
|
|
2052
2162
|
* Throws if read outside a replay item.
|
|
2053
2163
|
*/
|
|
2054
2164
|
get databaseUrl() {
|
|
2055
|
-
|
|
2165
|
+
const snapshot = this.require();
|
|
2166
|
+
this.markAccessed();
|
|
2167
|
+
return snapshot.databaseUrl;
|
|
2056
2168
|
}
|
|
2057
2169
|
/** When the per-trace branch URL stops being valid. ISO-8601. */
|
|
2058
2170
|
get expiresAt() {
|
|
@@ -2080,7 +2192,24 @@ var ReplayEnvironment = class {
|
|
|
2080
2192
|
}
|
|
2081
2193
|
/** Non-throwing variant for callers that handle the inactive case. */
|
|
2082
2194
|
snapshot() {
|
|
2083
|
-
|
|
2195
|
+
const snapshot = this.read();
|
|
2196
|
+
if (snapshot) {
|
|
2197
|
+
this.markAccessed();
|
|
2198
|
+
}
|
|
2199
|
+
return snapshot;
|
|
2200
|
+
}
|
|
2201
|
+
/**
|
|
2202
|
+
* Record on the replay context that customer code obtained the branch
|
|
2203
|
+
* URL. Only `databaseUrl` and `snapshot()` count — `active`, `readOnly`
|
|
2204
|
+
* and friends inspect the lease without exposing the connection string,
|
|
2205
|
+
* so they don't prove the replayed code could have connected to the
|
|
2206
|
+
* branch.
|
|
2207
|
+
*/
|
|
2208
|
+
markAccessed() {
|
|
2209
|
+
const ctx = getReplayContext();
|
|
2210
|
+
if (ctx?.dbBranchLease) {
|
|
2211
|
+
ctx.dbSnapshotAccessed = true;
|
|
2212
|
+
}
|
|
2084
2213
|
}
|
|
2085
2214
|
read() {
|
|
2086
2215
|
const ctx = getReplayContext();
|
|
@@ -3012,7 +3141,19 @@ var Bitfab = class {
|
|
|
3012
3141
|
contexts: traceState?.contexts ?? [],
|
|
3013
3142
|
testRunId: traceState?.testRunId,
|
|
3014
3143
|
inputSourceTraceId: traceState?.inputSourceTraceId,
|
|
3015
|
-
dbSnapshotRef: traceState?.dbSnapshotRef
|
|
3144
|
+
dbSnapshotRef: traceState?.dbSnapshotRef,
|
|
3145
|
+
// Built AFTER the wrapped fn finished, so `accessed` reflects
|
|
3146
|
+
// whether customer code obtained the branch URL during this
|
|
3147
|
+
// item. Omitted entirely when no lease was attached, so the
|
|
3148
|
+
// server can distinguish "no branch" from "branch ignored".
|
|
3149
|
+
...replayCtx?.dbBranchLease && {
|
|
3150
|
+
dbSnapshotUsage: {
|
|
3151
|
+
neonBranchId: replayCtx.dbBranchLease.neonBranchId,
|
|
3152
|
+
snapshotTimestamp: replayCtx.dbBranchLease.snapshotTimestamp,
|
|
3153
|
+
sourceTraceId: replayCtx.sourceBitfabTraceId,
|
|
3154
|
+
accessed: replayCtx.dbSnapshotAccessed === true
|
|
3155
|
+
}
|
|
3156
|
+
}
|
|
3016
3157
|
});
|
|
3017
3158
|
activeTraceStates.delete(traceId);
|
|
3018
3159
|
if (persistenceCollector) {
|
|
@@ -3184,6 +3325,18 @@ var Bitfab = class {
|
|
|
3184
3325
|
if (params.dbSnapshotRef) {
|
|
3185
3326
|
rawTrace.db_snapshot_ref = params.dbSnapshotRef;
|
|
3186
3327
|
}
|
|
3328
|
+
if (params.dbSnapshotUsage) {
|
|
3329
|
+
rawTrace.db_snapshot_usage = {
|
|
3330
|
+
neon_branch_id: params.dbSnapshotUsage.neonBranchId,
|
|
3331
|
+
...params.dbSnapshotUsage.snapshotTimestamp && {
|
|
3332
|
+
snapshot_timestamp: params.dbSnapshotUsage.snapshotTimestamp
|
|
3333
|
+
},
|
|
3334
|
+
...params.dbSnapshotUsage.sourceTraceId && {
|
|
3335
|
+
source_trace_id: params.dbSnapshotUsage.sourceTraceId
|
|
3336
|
+
},
|
|
3337
|
+
accessed: params.dbSnapshotUsage.accessed
|
|
3338
|
+
};
|
|
3339
|
+
}
|
|
3187
3340
|
return this.httpClient.sendExternalTrace({
|
|
3188
3341
|
type: "sdk-function",
|
|
3189
3342
|
source: "typescript-sdk-function",
|