bitfab 0.27.2 → 0.28.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/dist/{chunk-DW246LVL.js → chunk-RS5Z6YXY.js} +87 -25
- package/dist/chunk-RS5Z6YXY.js.map +1 -0
- package/dist/index.cjs +86 -24
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +143 -85
- package/dist/index.d.ts +143 -85
- package/dist/index.js +1 -1
- package/dist/node.cjs +86 -24
- package/dist/node.cjs.map +1 -1
- package/dist/node.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-DW246LVL.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -645,7 +645,7 @@ __export(index_exports, {
|
|
|
645
645
|
module.exports = __toCommonJS(index_exports);
|
|
646
646
|
|
|
647
647
|
// src/version.generated.ts
|
|
648
|
-
var __version__ = "0.
|
|
648
|
+
var __version__ = "0.28.0";
|
|
649
649
|
|
|
650
650
|
// src/constants.ts
|
|
651
651
|
var DEFAULT_SERVICE_URL = "https://bitfab.ai";
|
|
@@ -804,6 +804,13 @@ var HttpClient = class {
|
|
|
804
804
|
this.serviceUrl = config.serviceUrl;
|
|
805
805
|
this.timeout = config.timeout ?? 12e4;
|
|
806
806
|
}
|
|
807
|
+
/**
|
|
808
|
+
* Resolve the API key at the moment it is needed (request time), invoking
|
|
809
|
+
* the function form if one was supplied. Never read at construction.
|
|
810
|
+
*/
|
|
811
|
+
resolveApiKey() {
|
|
812
|
+
return typeof this.apiKey === "function" ? this.apiKey() : this.apiKey;
|
|
813
|
+
}
|
|
807
814
|
/**
|
|
808
815
|
* Make an HTTP request to the Bitfab API. Defaults to POST; pass
|
|
809
816
|
* `options.method` to use a different verb (e.g. "PATCH").
|
|
@@ -834,7 +841,7 @@ var HttpClient = class {
|
|
|
834
841
|
method,
|
|
835
842
|
headers: {
|
|
836
843
|
"Content-Type": "application/json",
|
|
837
|
-
Authorization: `Bearer ${this.
|
|
844
|
+
Authorization: `Bearer ${this.resolveApiKey() ?? ""}`
|
|
838
845
|
},
|
|
839
846
|
body,
|
|
840
847
|
signal: controller.signal
|
|
@@ -995,7 +1002,7 @@ var HttpClient = class {
|
|
|
995
1002
|
try {
|
|
996
1003
|
const response = await fetch(url, {
|
|
997
1004
|
method: "GET",
|
|
998
|
-
headers: { Authorization: `Bearer ${this.
|
|
1005
|
+
headers: { Authorization: `Bearer ${this.resolveApiKey() ?? ""}` },
|
|
999
1006
|
signal: controller.signal
|
|
1000
1007
|
});
|
|
1001
1008
|
if (!response.ok) {
|
|
@@ -1031,7 +1038,7 @@ var HttpClient = class {
|
|
|
1031
1038
|
try {
|
|
1032
1039
|
const response = await fetch(url, {
|
|
1033
1040
|
method: "GET",
|
|
1034
|
-
headers: { Authorization: `Bearer ${this.
|
|
1041
|
+
headers: { Authorization: `Bearer ${this.resolveApiKey() ?? ""}` },
|
|
1035
1042
|
signal: controller.signal
|
|
1036
1043
|
});
|
|
1037
1044
|
if (!response.ok) {
|
|
@@ -3361,6 +3368,12 @@ function getCurrentTrace() {
|
|
|
3361
3368
|
}
|
|
3362
3369
|
};
|
|
3363
3370
|
}
|
|
3371
|
+
function readEnv(name) {
|
|
3372
|
+
if (typeof process !== "undefined" && process.env) {
|
|
3373
|
+
return process.env[name];
|
|
3374
|
+
}
|
|
3375
|
+
return void 0;
|
|
3376
|
+
}
|
|
3364
3377
|
var Bitfab = class {
|
|
3365
3378
|
/**
|
|
3366
3379
|
* Initialize the Bitfab client.
|
|
@@ -3368,30 +3381,75 @@ var Bitfab = class {
|
|
|
3368
3381
|
* @param config - Configuration options for the client
|
|
3369
3382
|
*/
|
|
3370
3383
|
constructor(config) {
|
|
3371
|
-
|
|
3384
|
+
/** Gate the empty-key warning to fire at most once. */
|
|
3385
|
+
this.apiKeyWarned = false;
|
|
3386
|
+
this.apiKeyConfig = config.apiKey;
|
|
3372
3387
|
this.serviceUrl = config.serviceUrl ?? DEFAULT_SERVICE_URL;
|
|
3373
3388
|
this.timeout = config.timeout ?? 12e4;
|
|
3374
3389
|
this.envVars = config.envVars ?? {};
|
|
3375
|
-
|
|
3376
|
-
|
|
3377
|
-
console.warn(
|
|
3378
|
-
"Bitfab: apiKey is empty \u2014 tracing is disabled. Provide a valid API key to enable tracing."
|
|
3379
|
-
);
|
|
3380
|
-
this.enabled = false;
|
|
3381
|
-
} else {
|
|
3382
|
-
this.enabled = enabled;
|
|
3383
|
-
}
|
|
3390
|
+
this.explicitlyEnabled = config.enabled ?? true;
|
|
3391
|
+
this.strict = config.strict ?? false;
|
|
3384
3392
|
this.bamlClient = config.bamlClient ?? null;
|
|
3385
3393
|
if (config.dbSnapshot) {
|
|
3386
3394
|
validateDbSnapshotConfig(config.dbSnapshot);
|
|
3387
3395
|
}
|
|
3388
3396
|
this.dbSnapshot = config.dbSnapshot;
|
|
3389
3397
|
this.httpClient = new HttpClient({
|
|
3390
|
-
apiKey: this.
|
|
3398
|
+
apiKey: () => this.resolveApiKey(),
|
|
3391
3399
|
serviceUrl: this.serviceUrl,
|
|
3392
3400
|
timeout: this.timeout
|
|
3393
3401
|
});
|
|
3394
3402
|
}
|
|
3403
|
+
/**
|
|
3404
|
+
* Resolve the API key lazily, the first time a span actually needs it.
|
|
3405
|
+
*
|
|
3406
|
+
* The key is intentionally NOT read at construction. In ESM, a shim that
|
|
3407
|
+
* does `new Bitfab({ apiKey: process.env.BITFAB_API_KEY })` is hoisted and
|
|
3408
|
+
* evaluated before the importing script's body runs `dotenv.config()`, so
|
|
3409
|
+
* the key would be empty at construction even though it is set moments
|
|
3410
|
+
* later. Resolving here (at first `withSpan` call / first request) reads
|
|
3411
|
+
* the key after env loading has run.
|
|
3412
|
+
*
|
|
3413
|
+
* Resolution order: the configured value (string, or function called each
|
|
3414
|
+
* time it is still unresolved), then a fallback read of `BITFAB_API_KEY`
|
|
3415
|
+
* from the environment. Once a non-empty key is found it is cached, so an
|
|
3416
|
+
* early resolve that found nothing never poisons a later one.
|
|
3417
|
+
*/
|
|
3418
|
+
resolveApiKey() {
|
|
3419
|
+
if (this.resolvedApiKey !== void 0) {
|
|
3420
|
+
return this.resolvedApiKey;
|
|
3421
|
+
}
|
|
3422
|
+
const fromConfig = typeof this.apiKeyConfig === "function" ? this.apiKeyConfig() : this.apiKeyConfig;
|
|
3423
|
+
const candidate = fromConfig && fromConfig.trim() !== "" ? fromConfig : readEnv("BITFAB_API_KEY");
|
|
3424
|
+
const key = candidate && candidate.trim() !== "" ? candidate : void 0;
|
|
3425
|
+
if (key) {
|
|
3426
|
+
this.resolvedApiKey = key;
|
|
3427
|
+
return key;
|
|
3428
|
+
}
|
|
3429
|
+
if (this.strict) {
|
|
3430
|
+
throw new BitfabError(
|
|
3431
|
+
"Bitfab: no API key resolved. Set BITFAB_API_KEY or pass apiKey to new Bitfab(). If a script loads env with dotenv, load it before the module that constructs the client is imported (e.g. `node --env-file=.env script.ts`), or pass `apiKey: () => process.env.BITFAB_API_KEY`."
|
|
3432
|
+
);
|
|
3433
|
+
}
|
|
3434
|
+
if (this.explicitlyEnabled && !this.apiKeyWarned) {
|
|
3435
|
+
this.apiKeyWarned = true;
|
|
3436
|
+
console.warn(
|
|
3437
|
+
"Bitfab: apiKey is empty \u2014 tracing is disabled. Provide a valid API key to enable tracing."
|
|
3438
|
+
);
|
|
3439
|
+
}
|
|
3440
|
+
return void 0;
|
|
3441
|
+
}
|
|
3442
|
+
/**
|
|
3443
|
+
* Whether tracing should run, decided lazily at call time (not frozen at
|
|
3444
|
+
* construction). An explicit `enabled: false` short-circuits without ever
|
|
3445
|
+
* touching the key.
|
|
3446
|
+
*/
|
|
3447
|
+
isTracingEnabled() {
|
|
3448
|
+
if (!this.explicitlyEnabled) {
|
|
3449
|
+
return false;
|
|
3450
|
+
}
|
|
3451
|
+
return this.resolveApiKey() !== void 0;
|
|
3452
|
+
}
|
|
3395
3453
|
/**
|
|
3396
3454
|
* Fetch the function with its current version and BAML prompt from the server.
|
|
3397
3455
|
*
|
|
@@ -3484,7 +3542,9 @@ var Bitfab = class {
|
|
|
3484
3542
|
*/
|
|
3485
3543
|
getOpenAiTracingProcessor() {
|
|
3486
3544
|
return new BitfabOpenAITracingProcessor({
|
|
3487
|
-
|
|
3545
|
+
// Resolved at getter-call time (framework handlers are set up after env
|
|
3546
|
+
// loads); the withSpan path stays lazy via the constructor HttpClient thunk.
|
|
3547
|
+
apiKey: this.resolveApiKey(),
|
|
3488
3548
|
serviceUrl: this.serviceUrl,
|
|
3489
3549
|
getActiveSpanContext: () => {
|
|
3490
3550
|
const stack = getSpanStack();
|
|
@@ -3543,7 +3603,7 @@ var Bitfab = class {
|
|
|
3543
3603
|
*/
|
|
3544
3604
|
getLangGraphCallbackHandler(traceFunctionKey) {
|
|
3545
3605
|
return new BitfabLangGraphCallbackHandler({
|
|
3546
|
-
apiKey: this.
|
|
3606
|
+
apiKey: this.resolveApiKey(),
|
|
3547
3607
|
traceFunctionKey,
|
|
3548
3608
|
serviceUrl: this.serviceUrl,
|
|
3549
3609
|
getActiveSpanContext: () => {
|
|
@@ -3595,7 +3655,7 @@ var Bitfab = class {
|
|
|
3595
3655
|
*/
|
|
3596
3656
|
getClaudeAgentHandler(traceFunctionKey) {
|
|
3597
3657
|
return new BitfabClaudeAgentHandler({
|
|
3598
|
-
apiKey: this.
|
|
3658
|
+
apiKey: this.resolveApiKey(),
|
|
3599
3659
|
traceFunctionKey,
|
|
3600
3660
|
serviceUrl: this.serviceUrl,
|
|
3601
3661
|
getActiveSpanContext: () => {
|
|
@@ -3767,9 +3827,8 @@ var Bitfab = class {
|
|
|
3767
3827
|
* @returns A wrapped function with the same signature that creates spans for inputs and outputs
|
|
3768
3828
|
*/
|
|
3769
3829
|
withSpan(traceFunctionKey, optionsOrFn, maybeFn) {
|
|
3770
|
-
if (!this.
|
|
3771
|
-
|
|
3772
|
-
return fn2;
|
|
3830
|
+
if (!this.explicitlyEnabled) {
|
|
3831
|
+
return typeof optionsOrFn === "function" ? optionsOrFn : maybeFn;
|
|
3773
3832
|
}
|
|
3774
3833
|
const options = typeof optionsOrFn === "function" ? {} : optionsOrFn;
|
|
3775
3834
|
const fn = typeof optionsOrFn === "function" ? optionsOrFn : maybeFn;
|
|
@@ -3784,6 +3843,9 @@ var Bitfab = class {
|
|
|
3784
3843
|
}
|
|
3785
3844
|
})();
|
|
3786
3845
|
const wrappedFn = function(...args) {
|
|
3846
|
+
if (!self.isTracingEnabled()) {
|
|
3847
|
+
return fn.apply(this, args);
|
|
3848
|
+
}
|
|
3787
3849
|
if (!asyncLocalStorage && !isAsyncStorageInitDone()) {
|
|
3788
3850
|
return asyncLocalStorageReady.then(
|
|
3789
3851
|
() => wrappedFn.apply(this, args)
|
|
@@ -4044,7 +4106,7 @@ var Bitfab = class {
|
|
|
4044
4106
|
return {
|
|
4045
4107
|
traceId,
|
|
4046
4108
|
addContext: (context) => {
|
|
4047
|
-
if (!this.
|
|
4109
|
+
if (!this.isTracingEnabled()) {
|
|
4048
4110
|
return Promise.resolve();
|
|
4049
4111
|
}
|
|
4050
4112
|
if (typeof context !== "object" || context === null) {
|
|
@@ -4055,7 +4117,7 @@ var Bitfab = class {
|
|
|
4055
4117
|
});
|
|
4056
4118
|
},
|
|
4057
4119
|
setMetadata: (metadata) => {
|
|
4058
|
-
if (!this.
|
|
4120
|
+
if (!this.isTracingEnabled()) {
|
|
4059
4121
|
return Promise.resolve();
|
|
4060
4122
|
}
|
|
4061
4123
|
if (typeof metadata !== "object" || metadata === null) {
|
|
@@ -4064,7 +4126,7 @@ var Bitfab = class {
|
|
|
4064
4126
|
return this.httpClient.patchTrace(traceId, { mergeMetadata: metadata });
|
|
4065
4127
|
},
|
|
4066
4128
|
setSessionId: (sessionId) => {
|
|
4067
|
-
if (!this.
|
|
4129
|
+
if (!this.isTracingEnabled()) {
|
|
4068
4130
|
return Promise.resolve();
|
|
4069
4131
|
}
|
|
4070
4132
|
if (typeof sessionId !== "string" || sessionId.length === 0) {
|