@usagetap/sdk 0.4.0 → 0.7.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/README.md +50 -11
- package/dist/adapters/openai.d.cts +135 -2
- package/dist/adapters/openai.d.ts +135 -2
- package/dist/adapters/{openai.js → openai.mjs} +2 -2
- package/dist/adapters/openai.mjs.map +1 -0
- package/dist/adapters/openrouter.d.cts +2 -1
- package/dist/adapters/openrouter.d.ts +2 -1
- package/dist/adapters/{openrouter.js → openrouter.mjs} +2 -2
- package/dist/adapters/openrouter.mjs.map +1 -0
- package/dist/{openai-Ch7hN2vD.d.cts → client-nU5xk2pN.d.cts} +16 -134
- package/dist/{openai-Ch7hN2vD.d.ts → client-nU5xk2pN.d.ts} +16 -134
- package/dist/express/index.cjs +691 -0
- package/dist/express/index.cjs.map +1 -0
- package/dist/express/index.d.cts +93 -0
- package/dist/express/index.d.ts +93 -0
- package/dist/express/index.mjs +688 -0
- package/dist/express/index.mjs.map +1 -0
- package/dist/index.cjs +39 -779
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -94
- package/dist/index.d.ts +3 -94
- package/dist/{index.js → index.mjs} +42 -774
- package/dist/index.mjs.map +1 -0
- package/dist/openai/index.cjs +775 -0
- package/dist/openai/index.cjs.map +1 -0
- package/dist/openai/index.d.cts +4 -0
- package/dist/openai/index.d.ts +4 -0
- package/dist/openai/index.mjs +768 -0
- package/dist/openai/index.mjs.map +1 -0
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +1 -1
- package/dist/react/index.d.ts +1 -1
- package/dist/react/{index.js → index.mjs} +2 -2
- package/dist/react/index.mjs.map +1 -0
- package/package.json +23 -1
- package/dist/adapters/openai.js.map +0 -1
- package/dist/adapters/openrouter.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/react/index.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -120,6 +120,7 @@ var CALL_BEGIN_PATH = "call_begin";
|
|
|
120
120
|
var CALL_END_PATH = "call_end";
|
|
121
121
|
var CHECK_USAGE_PATH = "customers/{customerId}/usage";
|
|
122
122
|
var CREATE_CUSTOMER_PATH = "customers";
|
|
123
|
+
var CHANGE_PLAN_PATH = "customers/{customerId}/change_plan";
|
|
123
124
|
var AUTH_HEADER = "authorization";
|
|
124
125
|
var API_KEY_HEADER = "x-api-key";
|
|
125
126
|
var CORRELATION_HEADER = "x-usage-correlation-id";
|
|
@@ -127,7 +128,7 @@ var IDEMPOTENCY_HEADER = "idempotency-key";
|
|
|
127
128
|
var SDK_HEADER = "x-usage-sdk";
|
|
128
129
|
var USER_AGENT = "UsageTapClient";
|
|
129
130
|
var CANONICAL_MEDIA_TYPE = "application/vnd.usagetap.v1+json";
|
|
130
|
-
var SDK_VERSION = "0.
|
|
131
|
+
var SDK_VERSION = "0.7.0" ;
|
|
131
132
|
var HAS_WINDOW = typeof globalThis !== "undefined" && typeof globalThis.window !== "undefined";
|
|
132
133
|
var UsageTapClient = class {
|
|
133
134
|
apiKey;
|
|
@@ -176,7 +177,7 @@ var UsageTapClient = class {
|
|
|
176
177
|
const normalizedBaseUrl = normalizeBaseUrl(options.baseUrl);
|
|
177
178
|
this.baseUrl = new URL(normalizedBaseUrl);
|
|
178
179
|
this.apiKey = options.apiKey;
|
|
179
|
-
this.fetchImpl = fetchCandidate;
|
|
180
|
+
this.fetchImpl = wrapFetchImplementation(fetchCandidate, !options.fetchImpl);
|
|
180
181
|
this.defaultFeature = options.defaultFeature;
|
|
181
182
|
this.defaultTags = options.defaultTags?.length ? dedupeStrings(options.defaultTags) : void 0;
|
|
182
183
|
this.defaultHeaders = options.headers ? normalizeHeaderDictionary(options.headers) : {};
|
|
@@ -256,6 +257,38 @@ var UsageTapClient = class {
|
|
|
256
257
|
);
|
|
257
258
|
return response;
|
|
258
259
|
}
|
|
260
|
+
async changePlan(request, options = {}) {
|
|
261
|
+
if (!request?.customerId) {
|
|
262
|
+
throw new UsageTapError(
|
|
263
|
+
"USAGETAP_BAD_REQUEST",
|
|
264
|
+
"changePlan requires customerId"
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
if (!request?.planId) {
|
|
268
|
+
throw new UsageTapError(
|
|
269
|
+
"USAGETAP_BAD_REQUEST",
|
|
270
|
+
"changePlan requires planId"
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
const path = CHANGE_PLAN_PATH.replace(
|
|
274
|
+
"{customerId}",
|
|
275
|
+
encodeURIComponent(request.customerId)
|
|
276
|
+
);
|
|
277
|
+
const idempotencyKey = options.idempotencyKey ?? (this.autoIdempotency ? this.idempotencyGenerator() : void 0);
|
|
278
|
+
const payload = {
|
|
279
|
+
planId: request.planId,
|
|
280
|
+
strategy: request.strategy ?? "IMMEDIATE_RESET"
|
|
281
|
+
};
|
|
282
|
+
const response = await this.request(
|
|
283
|
+
path,
|
|
284
|
+
payload,
|
|
285
|
+
{
|
|
286
|
+
...options,
|
|
287
|
+
idempotencyKey
|
|
288
|
+
}
|
|
289
|
+
);
|
|
290
|
+
return response;
|
|
291
|
+
}
|
|
259
292
|
async withUsage(beginRequest, handler, options = {}) {
|
|
260
293
|
const idempotencyKey = beginRequest.idempotency ?? (this.autoIdempotency ? this.idempotencyGenerator() : void 0);
|
|
261
294
|
const beginPayload = idempotencyKey ? { ...beginRequest, idempotency: idempotencyKey } : { ...beginRequest };
|
|
@@ -621,6 +654,10 @@ function dedupeStrings(values) {
|
|
|
621
654
|
new Set(values.map((value) => value.trim()).filter(Boolean))
|
|
622
655
|
);
|
|
623
656
|
}
|
|
657
|
+
function wrapFetchImplementation(fetchCandidate, preferGlobalContext) {
|
|
658
|
+
const target = preferGlobalContext ? globalThis : void 0;
|
|
659
|
+
return ((...args) => target ? Reflect.apply(fetchCandidate, target, args) : fetchCandidate(...args));
|
|
660
|
+
}
|
|
624
661
|
function wrapEndCallError(error, correlationId) {
|
|
625
662
|
if (isUsageTapError(error)) {
|
|
626
663
|
return new UsageTapError("USAGETAP_END_CALL_ERROR", error.message, {
|
|
@@ -639,742 +676,6 @@ function wrapEndCallError(error, correlationId) {
|
|
|
639
676
|
);
|
|
640
677
|
}
|
|
641
678
|
|
|
642
|
-
// src/adapters/openai.ts
|
|
643
|
-
function createOpenAIAdapter(init) {
|
|
644
|
-
const { client, usageTap } = init;
|
|
645
|
-
return {
|
|
646
|
-
async invoke(params) {
|
|
647
|
-
const result = await usageTap.withUsage(
|
|
648
|
-
params.begin,
|
|
649
|
-
async (ctx) => {
|
|
650
|
-
const response = await params.call(client, {
|
|
651
|
-
hints: ctx.begin.data.vendorHints,
|
|
652
|
-
begin: ctx.begin
|
|
653
|
-
});
|
|
654
|
-
tryInferUsage(response, ctx.begin.data.vendorHints, params.extractUsage, ctx);
|
|
655
|
-
return {
|
|
656
|
-
data: response,
|
|
657
|
-
begin: ctx.begin
|
|
658
|
-
};
|
|
659
|
-
},
|
|
660
|
-
params.withUsageOptions
|
|
661
|
-
);
|
|
662
|
-
return result;
|
|
663
|
-
},
|
|
664
|
-
async invokeStream(params) {
|
|
665
|
-
const result = await usageTap.withUsage(
|
|
666
|
-
params.begin,
|
|
667
|
-
async (ctx) => {
|
|
668
|
-
const { stream, onComplete } = await params.call(client, {
|
|
669
|
-
hints: ctx.begin.data.vendorHints,
|
|
670
|
-
begin: ctx.begin
|
|
671
|
-
});
|
|
672
|
-
const wrapped = wrapStreamForUsageTap(stream, async () => {
|
|
673
|
-
if (!onComplete) return;
|
|
674
|
-
try {
|
|
675
|
-
const maybeUsage = await onComplete();
|
|
676
|
-
if (maybeUsage) {
|
|
677
|
-
ctx.setUsage(maybeUsage);
|
|
678
|
-
}
|
|
679
|
-
} catch (error) {
|
|
680
|
-
ctx.setError({
|
|
681
|
-
code: "USAGE_FINALIZE_ERROR",
|
|
682
|
-
message: error instanceof Error ? error.message : String(error)
|
|
683
|
-
});
|
|
684
|
-
throw error;
|
|
685
|
-
}
|
|
686
|
-
}, ctx);
|
|
687
|
-
const finalize = async () => {
|
|
688
|
-
await wrapped.__usageTapFinalize?.();
|
|
689
|
-
};
|
|
690
|
-
return {
|
|
691
|
-
stream: wrapped,
|
|
692
|
-
begin: ctx.begin,
|
|
693
|
-
finalize
|
|
694
|
-
};
|
|
695
|
-
},
|
|
696
|
-
params.withUsageOptions
|
|
697
|
-
);
|
|
698
|
-
return result;
|
|
699
|
-
}
|
|
700
|
-
};
|
|
701
|
-
}
|
|
702
|
-
function toNextResponse(stream, options = {}) {
|
|
703
|
-
const mode = options.mode ?? "text";
|
|
704
|
-
const headers = new Headers(options.headers ?? {});
|
|
705
|
-
if (mode === "sse") {
|
|
706
|
-
headers.set("content-type", "text/event-stream; charset=utf-8");
|
|
707
|
-
headers.set("cache-control", "no-cache, no-transform");
|
|
708
|
-
headers.set("connection", "keep-alive");
|
|
709
|
-
headers.set("x-accel-buffering", "no");
|
|
710
|
-
} else {
|
|
711
|
-
headers.set("content-type", options.contentType ?? "text/plain; charset=utf-8");
|
|
712
|
-
}
|
|
713
|
-
const encoder = new TextEncoder();
|
|
714
|
-
let iterator;
|
|
715
|
-
const body = new ReadableStream({
|
|
716
|
-
async start(controller) {
|
|
717
|
-
try {
|
|
718
|
-
const getIterator = stream[Symbol.asyncIterator];
|
|
719
|
-
if (typeof getIterator !== "function") {
|
|
720
|
-
controller.close();
|
|
721
|
-
return;
|
|
722
|
-
}
|
|
723
|
-
iterator = getIterator.call(stream);
|
|
724
|
-
while (true) {
|
|
725
|
-
const result = await iterator.next();
|
|
726
|
-
if (result.done) {
|
|
727
|
-
break;
|
|
728
|
-
}
|
|
729
|
-
const text = chunkToText(result.value);
|
|
730
|
-
if (!text) {
|
|
731
|
-
continue;
|
|
732
|
-
}
|
|
733
|
-
if (mode === "sse") {
|
|
734
|
-
controller.enqueue(encoder.encode(formatSsePayload(text, options.sse)));
|
|
735
|
-
} else {
|
|
736
|
-
controller.enqueue(encoder.encode(text));
|
|
737
|
-
}
|
|
738
|
-
}
|
|
739
|
-
controller.close();
|
|
740
|
-
} catch (error) {
|
|
741
|
-
controller.error(error);
|
|
742
|
-
} finally {
|
|
743
|
-
await stream.__usageTapFinalize?.();
|
|
744
|
-
}
|
|
745
|
-
},
|
|
746
|
-
async cancel() {
|
|
747
|
-
if (!iterator) {
|
|
748
|
-
const getIterator = stream[Symbol.asyncIterator];
|
|
749
|
-
if (typeof getIterator === "function") {
|
|
750
|
-
iterator = getIterator.call(stream);
|
|
751
|
-
}
|
|
752
|
-
}
|
|
753
|
-
if (iterator && typeof iterator.return === "function") {
|
|
754
|
-
await iterator.return();
|
|
755
|
-
}
|
|
756
|
-
await stream.__usageTapFinalize?.();
|
|
757
|
-
}
|
|
758
|
-
});
|
|
759
|
-
return new Response(body, { headers });
|
|
760
|
-
}
|
|
761
|
-
async function pipeToResponse(stream, res, options = {}) {
|
|
762
|
-
const mode = options.mode ?? "text";
|
|
763
|
-
if (mode === "sse") {
|
|
764
|
-
setHeaderIfPossible(res, "Content-Type", "text/event-stream; charset=utf-8");
|
|
765
|
-
setHeaderIfPossible(res, "Cache-Control", "no-cache, no-transform");
|
|
766
|
-
setHeaderIfPossible(res, "Connection", "keep-alive");
|
|
767
|
-
setHeaderIfPossible(res, "X-Accel-Buffering", "no");
|
|
768
|
-
} else {
|
|
769
|
-
setHeaderIfPossible(res, "Content-Type", options.contentType ?? "text/plain; charset=utf-8");
|
|
770
|
-
}
|
|
771
|
-
const encoder = new TextEncoder();
|
|
772
|
-
const iterator = stream[Symbol.asyncIterator]();
|
|
773
|
-
try {
|
|
774
|
-
while (true) {
|
|
775
|
-
const result = await iterator.next();
|
|
776
|
-
if (result.done) {
|
|
777
|
-
break;
|
|
778
|
-
}
|
|
779
|
-
const text = chunkToText(result.value);
|
|
780
|
-
if (!text) {
|
|
781
|
-
continue;
|
|
782
|
-
}
|
|
783
|
-
const payload = mode === "sse" ? formatSsePayload(text, options.sse) : text;
|
|
784
|
-
res.write(Buffer.from(encoder.encode(payload)));
|
|
785
|
-
res.flush?.();
|
|
786
|
-
}
|
|
787
|
-
} finally {
|
|
788
|
-
res.end();
|
|
789
|
-
await stream.__usageTapFinalize?.();
|
|
790
|
-
}
|
|
791
|
-
}
|
|
792
|
-
var USAGETAP_CORRELATION_HEADER = "x-usage-correlation-id";
|
|
793
|
-
function wrapOpenAI(client, usageTap, options = {}) {
|
|
794
|
-
if (!client) {
|
|
795
|
-
throw new UsageTapError("USAGETAP_BAD_REQUEST", "wrapOpenAI requires an OpenAI client instance");
|
|
796
|
-
}
|
|
797
|
-
const defaultContext = options.defaultContext;
|
|
798
|
-
const applyVendorHints = options.applyVendorHints !== false;
|
|
799
|
-
const proxiedChat = client.chat ? createChatProxy(client.chat, usageTap, defaultContext, applyVendorHints) : void 0;
|
|
800
|
-
const proxiedResponses = typeof client.responses !== "undefined" ? createResponsesProxy(client.responses, usageTap, defaultContext, applyVendorHints) : void 0;
|
|
801
|
-
const handler = {
|
|
802
|
-
get(target, prop, receiver) {
|
|
803
|
-
if (prop === "chat" && proxiedChat) {
|
|
804
|
-
return proxiedChat;
|
|
805
|
-
}
|
|
806
|
-
if (prop === "responses" && typeof target.responses !== "undefined") {
|
|
807
|
-
return proxiedResponses ?? Reflect.get(target, prop, receiver);
|
|
808
|
-
}
|
|
809
|
-
if (prop === "toNextResponse") {
|
|
810
|
-
return toNextResponse;
|
|
811
|
-
}
|
|
812
|
-
if (prop === "pipeToResponse") {
|
|
813
|
-
return pipeToResponse;
|
|
814
|
-
}
|
|
815
|
-
if (prop === "unwrap") {
|
|
816
|
-
return () => target;
|
|
817
|
-
}
|
|
818
|
-
return Reflect.get(target, prop, receiver);
|
|
819
|
-
}
|
|
820
|
-
};
|
|
821
|
-
return new Proxy(client, handler);
|
|
822
|
-
}
|
|
823
|
-
function streamOpenAIRoute(usageTap, openai, options) {
|
|
824
|
-
if (!options?.getRequest) {
|
|
825
|
-
throw new UsageTapError("USAGETAP_BAD_REQUEST", "streamOpenAIRoute requires a getRequest function");
|
|
826
|
-
}
|
|
827
|
-
const wrapConfig = options.wrapOptions || options.defaultContext ? {
|
|
828
|
-
...options.wrapOptions ?? {},
|
|
829
|
-
defaultContext: options.defaultContext ?? options.wrapOptions?.defaultContext
|
|
830
|
-
} : void 0;
|
|
831
|
-
const wrappedClient = wrapConfig ? wrapOpenAI(openai, usageTap, wrapConfig) : wrapOpenAI(openai, usageTap);
|
|
832
|
-
return async (req) => {
|
|
833
|
-
const requestConfig = await options.getRequest(req);
|
|
834
|
-
const mergedParams = {
|
|
835
|
-
...requestConfig.params,
|
|
836
|
-
stream: true
|
|
837
|
-
};
|
|
838
|
-
const callOptions = {};
|
|
839
|
-
if (requestConfig.usageTap) {
|
|
840
|
-
callOptions.usageTap = requestConfig.usageTap;
|
|
841
|
-
}
|
|
842
|
-
if (requestConfig.withUsage) {
|
|
843
|
-
callOptions.withUsage = requestConfig.withUsage;
|
|
844
|
-
}
|
|
845
|
-
const stream = await wrappedClient.chat.completions.create(
|
|
846
|
-
mergedParams,
|
|
847
|
-
Object.keys(callOptions).length ? callOptions : void 0
|
|
848
|
-
);
|
|
849
|
-
const baseResponse = toNextResponse(stream, {
|
|
850
|
-
mode: options.stream?.mode ?? "sse",
|
|
851
|
-
headers: options.stream?.headers
|
|
852
|
-
});
|
|
853
|
-
const init = options.stream?.responseInit;
|
|
854
|
-
if (!init) {
|
|
855
|
-
return baseResponse;
|
|
856
|
-
}
|
|
857
|
-
const mergedHeaders = new Headers(baseResponse.headers);
|
|
858
|
-
if (init.headers) {
|
|
859
|
-
const extra = normalizeHeaders(init.headers);
|
|
860
|
-
for (const [key, value] of Object.entries(extra)) {
|
|
861
|
-
mergedHeaders.set(key, value);
|
|
862
|
-
}
|
|
863
|
-
}
|
|
864
|
-
return new Response(baseResponse.body, {
|
|
865
|
-
status: init.status ?? baseResponse.status,
|
|
866
|
-
statusText: init.statusText ?? baseResponse.statusText,
|
|
867
|
-
headers: mergedHeaders
|
|
868
|
-
});
|
|
869
|
-
};
|
|
870
|
-
}
|
|
871
|
-
function createChatProxy(resource, usageTap, defaultContext, applyVendorHints) {
|
|
872
|
-
const completions = createChatCompletionsProxy(
|
|
873
|
-
resource.completions,
|
|
874
|
-
usageTap,
|
|
875
|
-
defaultContext,
|
|
876
|
-
applyVendorHints
|
|
877
|
-
);
|
|
878
|
-
const handler = {
|
|
879
|
-
get(target, prop, receiver) {
|
|
880
|
-
if (prop === "completions") {
|
|
881
|
-
return completions;
|
|
882
|
-
}
|
|
883
|
-
return Reflect.get(target, prop, receiver);
|
|
884
|
-
}
|
|
885
|
-
};
|
|
886
|
-
return new Proxy(resource, handler);
|
|
887
|
-
}
|
|
888
|
-
function createResponsesProxy(resource, usageTap, defaultContext, applyVendorHints) {
|
|
889
|
-
if (!resource || typeof resource !== "object") {
|
|
890
|
-
return void 0;
|
|
891
|
-
}
|
|
892
|
-
if (!("create" in resource) || typeof resource.create !== "function") {
|
|
893
|
-
return resource;
|
|
894
|
-
}
|
|
895
|
-
const originalCreate = resource.create.bind(resource);
|
|
896
|
-
const wrappedCreate = (params, options) => {
|
|
897
|
-
const { requestOptions, usageContext, withUsage: withUsage2 } = splitUsageOptions(options);
|
|
898
|
-
const beginRequest = resolveBeginRequest(defaultContext, usageContext);
|
|
899
|
-
const wantsStream = isStreamingRequest(params);
|
|
900
|
-
return usageTap.withUsage(beginRequest, (ctx) => {
|
|
901
|
-
const finalParams = applyVendorHints ? applyResponsesVendorHints(params, ctx.begin.data.vendorHints) : params;
|
|
902
|
-
const request = attachCorrelationHeader(requestOptions, ctx.begin.correlationId);
|
|
903
|
-
if (wantsStream) {
|
|
904
|
-
const apiPromise2 = originalCreate(finalParams, request);
|
|
905
|
-
const wrappedPromise2 = transformApiPromise(apiPromise2, (rawStream) => {
|
|
906
|
-
ensureAsyncIterable(rawStream, "responses.create");
|
|
907
|
-
const wrappedStream = wrapStreamForUsageTap(rawStream, async () => {
|
|
908
|
-
const usage = await extractUsageFromStream(rawStream, ctx.begin.data.vendorHints);
|
|
909
|
-
if (usage) {
|
|
910
|
-
ctx.setUsage(usage);
|
|
911
|
-
}
|
|
912
|
-
}, ctx);
|
|
913
|
-
return wrappedStream;
|
|
914
|
-
});
|
|
915
|
-
return wrappedPromise2;
|
|
916
|
-
}
|
|
917
|
-
const apiPromise = originalCreate(finalParams, request);
|
|
918
|
-
const wrappedPromise = transformApiPromise(apiPromise, (response) => {
|
|
919
|
-
tryInferUsage(response, ctx.begin.data.vendorHints, void 0, ctx);
|
|
920
|
-
return response;
|
|
921
|
-
});
|
|
922
|
-
return wrappedPromise;
|
|
923
|
-
}, withUsage2);
|
|
924
|
-
};
|
|
925
|
-
const handler = {
|
|
926
|
-
get(target, prop, receiver) {
|
|
927
|
-
if (prop === "create") {
|
|
928
|
-
return wrappedCreate;
|
|
929
|
-
}
|
|
930
|
-
return Reflect.get(target, prop, receiver);
|
|
931
|
-
}
|
|
932
|
-
};
|
|
933
|
-
return new Proxy(resource, handler);
|
|
934
|
-
}
|
|
935
|
-
function createChatCompletionsProxy(resource, usageTap, defaultContext, applyVendorHints) {
|
|
936
|
-
const originalCreate = resource.create.bind(resource);
|
|
937
|
-
const streamCandidate = resource.stream;
|
|
938
|
-
const originalStream = typeof streamCandidate === "function" ? streamCandidate.bind(resource) : void 0;
|
|
939
|
-
const wrappedCreate = (params, options) => {
|
|
940
|
-
const { requestOptions, usageContext, withUsage: withUsage2 } = splitUsageOptions(options);
|
|
941
|
-
const beginRequest = resolveBeginRequest(defaultContext, usageContext);
|
|
942
|
-
const wantsStream = isStreamingRequest(params);
|
|
943
|
-
return usageTap.withUsage(beginRequest, (ctx) => {
|
|
944
|
-
const finalParams = applyVendorHints ? applyChatVendorHints(params, ctx.begin.data.vendorHints) : params;
|
|
945
|
-
const request = attachCorrelationHeader(requestOptions, ctx.begin.correlationId);
|
|
946
|
-
if (wantsStream) {
|
|
947
|
-
const apiPromise2 = originalCreate(finalParams, request);
|
|
948
|
-
const wrappedPromise2 = transformApiPromise(apiPromise2, (rawStream) => {
|
|
949
|
-
ensureAsyncIterable(rawStream, "chat.completions.create");
|
|
950
|
-
const wrappedStream2 = wrapStreamForUsageTap(rawStream, async () => {
|
|
951
|
-
const usage = await extractUsageFromStream(rawStream, ctx.begin.data.vendorHints);
|
|
952
|
-
if (usage) {
|
|
953
|
-
ctx.setUsage(usage);
|
|
954
|
-
}
|
|
955
|
-
}, ctx);
|
|
956
|
-
return wrappedStream2;
|
|
957
|
-
});
|
|
958
|
-
return wrappedPromise2;
|
|
959
|
-
}
|
|
960
|
-
const apiPromise = originalCreate(finalParams, request);
|
|
961
|
-
const wrappedPromise = transformApiPromise(apiPromise, (response) => {
|
|
962
|
-
tryInferUsage(response, ctx.begin.data.vendorHints, void 0, ctx);
|
|
963
|
-
return response;
|
|
964
|
-
});
|
|
965
|
-
return wrappedPromise;
|
|
966
|
-
}, withUsage2);
|
|
967
|
-
};
|
|
968
|
-
const wrappedStream = originalStream ? (params, options) => {
|
|
969
|
-
const { requestOptions, usageContext, withUsage: withUsage2 } = splitUsageOptions(options);
|
|
970
|
-
const beginRequest = resolveBeginRequest(defaultContext, usageContext);
|
|
971
|
-
return usageTap.withUsage(beginRequest, (ctx) => {
|
|
972
|
-
const finalParams = applyVendorHints ? applyChatVendorHints(params, ctx.begin.data.vendorHints) : params;
|
|
973
|
-
const request = attachCorrelationHeader(requestOptions, ctx.begin.correlationId);
|
|
974
|
-
const apiPromise = originalStream(finalParams, request);
|
|
975
|
-
const wrappedPromise = transformApiPromise(apiPromise, (rawStream) => {
|
|
976
|
-
ensureAsyncIterable(rawStream, "chat.completions.stream");
|
|
977
|
-
const wrappedStreamInner = wrapStreamForUsageTap(rawStream, async () => {
|
|
978
|
-
const usage = await extractUsageFromStream(rawStream, ctx.begin.data.vendorHints);
|
|
979
|
-
if (usage) {
|
|
980
|
-
ctx.setUsage(usage);
|
|
981
|
-
}
|
|
982
|
-
}, ctx);
|
|
983
|
-
return wrappedStreamInner;
|
|
984
|
-
});
|
|
985
|
-
return wrappedPromise;
|
|
986
|
-
}, withUsage2);
|
|
987
|
-
} : void 0;
|
|
988
|
-
const handler = {
|
|
989
|
-
get(target, prop, receiver) {
|
|
990
|
-
if (prop === "create") {
|
|
991
|
-
return wrappedCreate;
|
|
992
|
-
}
|
|
993
|
-
if (prop === "stream" && wrappedStream) {
|
|
994
|
-
return wrappedStream;
|
|
995
|
-
}
|
|
996
|
-
return Reflect.get(target, prop, receiver);
|
|
997
|
-
}
|
|
998
|
-
};
|
|
999
|
-
return new Proxy(resource, handler);
|
|
1000
|
-
}
|
|
1001
|
-
function splitUsageOptions(options) {
|
|
1002
|
-
if (!options || typeof options !== "object") {
|
|
1003
|
-
return {};
|
|
1004
|
-
}
|
|
1005
|
-
const { usageTap, withUsage: withUsage2, ...rest } = options;
|
|
1006
|
-
const requestOptions = Object.keys(rest).length ? cloneRequestOptions(rest) : void 0;
|
|
1007
|
-
return {
|
|
1008
|
-
requestOptions,
|
|
1009
|
-
usageContext: usageTap,
|
|
1010
|
-
withUsage: withUsage2
|
|
1011
|
-
};
|
|
1012
|
-
}
|
|
1013
|
-
function resolveBeginRequest(defaults, override) {
|
|
1014
|
-
const base = defaults ?? {};
|
|
1015
|
-
const current = override ?? {};
|
|
1016
|
-
const customerId = current.customerId ?? base.customerId;
|
|
1017
|
-
if (!customerId) {
|
|
1018
|
-
throw new UsageTapError(
|
|
1019
|
-
"USAGETAP_BAD_REQUEST",
|
|
1020
|
-
"wrapOpenAI requires usageTap.customerId (provide defaultContext or options.usageTap)"
|
|
1021
|
-
);
|
|
1022
|
-
}
|
|
1023
|
-
const tags = mergeTags(base.tags, current.tags);
|
|
1024
|
-
const begin = { customerId };
|
|
1025
|
-
const requested = current.requested ?? base.requested;
|
|
1026
|
-
if (requested) begin.requested = requested;
|
|
1027
|
-
const feature = current.feature ?? base.feature;
|
|
1028
|
-
if (feature) begin.feature = feature;
|
|
1029
|
-
const idempotency = current.idempotency ?? base.idempotency;
|
|
1030
|
-
if (idempotency) begin.idempotency = idempotency;
|
|
1031
|
-
const customerName = current.customerName ?? base.customerName;
|
|
1032
|
-
if (customerName) begin.customerName = customerName;
|
|
1033
|
-
const customerEmail = current.customerEmail ?? base.customerEmail;
|
|
1034
|
-
if (customerEmail) begin.customerEmail = customerEmail;
|
|
1035
|
-
if (tags?.length) {
|
|
1036
|
-
begin.tags = tags;
|
|
1037
|
-
}
|
|
1038
|
-
return begin;
|
|
1039
|
-
}
|
|
1040
|
-
function transformApiPromise(apiPromise, onResolve) {
|
|
1041
|
-
const resolvedPromise = Promise.resolve(apiPromise).then(onResolve);
|
|
1042
|
-
if (isObjectRecord(apiPromise)) {
|
|
1043
|
-
const proto = Object.getPrototypeOf(apiPromise);
|
|
1044
|
-
if (proto) {
|
|
1045
|
-
Object.setPrototypeOf(resolvedPromise, proto);
|
|
1046
|
-
}
|
|
1047
|
-
for (const key of Reflect.ownKeys(apiPromise)) {
|
|
1048
|
-
if (key === "then" || key === "catch" || key === "finally") {
|
|
1049
|
-
continue;
|
|
1050
|
-
}
|
|
1051
|
-
try {
|
|
1052
|
-
const descriptor = Object.getOwnPropertyDescriptor(apiPromise, key);
|
|
1053
|
-
if (descriptor) {
|
|
1054
|
-
Reflect.defineProperty(resolvedPromise, key, descriptor);
|
|
1055
|
-
}
|
|
1056
|
-
} catch {
|
|
1057
|
-
}
|
|
1058
|
-
}
|
|
1059
|
-
}
|
|
1060
|
-
return resolvedPromise;
|
|
1061
|
-
}
|
|
1062
|
-
function isObjectRecord(value) {
|
|
1063
|
-
return typeof value === "object" && value !== null;
|
|
1064
|
-
}
|
|
1065
|
-
function cloneRecord(value) {
|
|
1066
|
-
return isObjectRecord(value) ? { ...value } : {};
|
|
1067
|
-
}
|
|
1068
|
-
function isStringTuple(value) {
|
|
1069
|
-
return Array.isArray(value) && value.length >= 2 && typeof value[0] === "string" && typeof value[1] === "string";
|
|
1070
|
-
}
|
|
1071
|
-
function cloneRequestOptions(source) {
|
|
1072
|
-
const clone = { ...source };
|
|
1073
|
-
if ("headers" in clone) {
|
|
1074
|
-
clone.headers = normalizeHeaders(clone.headers);
|
|
1075
|
-
}
|
|
1076
|
-
return clone;
|
|
1077
|
-
}
|
|
1078
|
-
function attachCorrelationHeader(options, correlationId) {
|
|
1079
|
-
const normalized = normalizeHeaders(options?.headers);
|
|
1080
|
-
if (correlationId && !normalized[USAGETAP_CORRELATION_HEADER]) {
|
|
1081
|
-
normalized[USAGETAP_CORRELATION_HEADER] = correlationId;
|
|
1082
|
-
}
|
|
1083
|
-
if (!options) {
|
|
1084
|
-
return Object.keys(normalized).length ? { headers: normalized } : void 0;
|
|
1085
|
-
}
|
|
1086
|
-
const next = { ...options };
|
|
1087
|
-
if (Object.keys(normalized).length) {
|
|
1088
|
-
next.headers = normalized;
|
|
1089
|
-
}
|
|
1090
|
-
return next;
|
|
1091
|
-
}
|
|
1092
|
-
function normalizeHeaders(headers) {
|
|
1093
|
-
if (!headers) {
|
|
1094
|
-
return {};
|
|
1095
|
-
}
|
|
1096
|
-
if (headers instanceof Headers) {
|
|
1097
|
-
const result = {};
|
|
1098
|
-
headers.forEach((value, key) => {
|
|
1099
|
-
result[key.toLowerCase()] = value;
|
|
1100
|
-
});
|
|
1101
|
-
return result;
|
|
1102
|
-
}
|
|
1103
|
-
if (Array.isArray(headers)) {
|
|
1104
|
-
const result = {};
|
|
1105
|
-
for (const entry of headers) {
|
|
1106
|
-
if (!isStringTuple(entry)) {
|
|
1107
|
-
continue;
|
|
1108
|
-
}
|
|
1109
|
-
const [key, value] = entry;
|
|
1110
|
-
result[key.toLowerCase()] = value;
|
|
1111
|
-
}
|
|
1112
|
-
return result;
|
|
1113
|
-
}
|
|
1114
|
-
if (isObjectRecord(headers)) {
|
|
1115
|
-
const result = {};
|
|
1116
|
-
const record = headers;
|
|
1117
|
-
for (const key of Object.keys(record)) {
|
|
1118
|
-
const value = record[key];
|
|
1119
|
-
if (value !== void 0 && value !== null) {
|
|
1120
|
-
result[key.toLowerCase()] = String(value);
|
|
1121
|
-
}
|
|
1122
|
-
}
|
|
1123
|
-
return result;
|
|
1124
|
-
}
|
|
1125
|
-
return {};
|
|
1126
|
-
}
|
|
1127
|
-
function mergeTags(a, b) {
|
|
1128
|
-
const values = [...a ?? [], ...b ?? []].map((value) => typeof value === "string" ? value.trim() : "").filter(Boolean);
|
|
1129
|
-
if (!values.length) {
|
|
1130
|
-
return void 0;
|
|
1131
|
-
}
|
|
1132
|
-
return dedupeStrings2(values);
|
|
1133
|
-
}
|
|
1134
|
-
function dedupeStrings2(values) {
|
|
1135
|
-
return Array.from(new Set(values));
|
|
1136
|
-
}
|
|
1137
|
-
function isStreamingRequest(params) {
|
|
1138
|
-
if (!params || typeof params !== "object") {
|
|
1139
|
-
return false;
|
|
1140
|
-
}
|
|
1141
|
-
const stream = params.stream;
|
|
1142
|
-
if (typeof stream === "boolean") {
|
|
1143
|
-
return stream;
|
|
1144
|
-
}
|
|
1145
|
-
return stream != null;
|
|
1146
|
-
}
|
|
1147
|
-
function applyChatVendorHints(params, hints) {
|
|
1148
|
-
if (!hints) {
|
|
1149
|
-
return params;
|
|
1150
|
-
}
|
|
1151
|
-
const next = cloneRecord(params);
|
|
1152
|
-
if (hints.preferredModel && (next.model === void 0 || next.model === null)) {
|
|
1153
|
-
next.model = hints.preferredModel;
|
|
1154
|
-
}
|
|
1155
|
-
if (typeof hints.maxResponseTokens === "number" && next.max_tokens == null) {
|
|
1156
|
-
next.max_tokens = hints.maxResponseTokens;
|
|
1157
|
-
}
|
|
1158
|
-
if (typeof hints.maxInputTokens === "number" && next.max_input_tokens == null) {
|
|
1159
|
-
next.max_input_tokens = hints.maxInputTokens;
|
|
1160
|
-
}
|
|
1161
|
-
return next;
|
|
1162
|
-
}
|
|
1163
|
-
function applyResponsesVendorHints(params, hints) {
|
|
1164
|
-
if (!hints) {
|
|
1165
|
-
return params;
|
|
1166
|
-
}
|
|
1167
|
-
const next = cloneRecord(params);
|
|
1168
|
-
if (hints.preferredModel && (next.model === void 0 || next.model === null)) {
|
|
1169
|
-
next.model = hints.preferredModel;
|
|
1170
|
-
}
|
|
1171
|
-
if (typeof hints.maxResponseTokens === "number" && next.max_output_tokens == null) {
|
|
1172
|
-
next.max_output_tokens = hints.maxResponseTokens;
|
|
1173
|
-
}
|
|
1174
|
-
return next;
|
|
1175
|
-
}
|
|
1176
|
-
async function extractUsageFromStream(stream, hints) {
|
|
1177
|
-
const finalPayload = await resolveStreamFinalPayload(stream);
|
|
1178
|
-
if (!finalPayload) {
|
|
1179
|
-
return void 0;
|
|
1180
|
-
}
|
|
1181
|
-
return inferUsageFromResponse(finalPayload, hints);
|
|
1182
|
-
}
|
|
1183
|
-
async function resolveStreamFinalPayload(stream) {
|
|
1184
|
-
if (!stream || typeof stream !== "object") {
|
|
1185
|
-
return void 0;
|
|
1186
|
-
}
|
|
1187
|
-
const candidate = stream;
|
|
1188
|
-
if (typeof candidate.finalChatCompletion === "function") {
|
|
1189
|
-
return candidate.finalChatCompletion();
|
|
1190
|
-
}
|
|
1191
|
-
if (typeof candidate.finalResponse === "function") {
|
|
1192
|
-
return candidate.finalResponse();
|
|
1193
|
-
}
|
|
1194
|
-
if (typeof candidate.finalCompletion === "function") {
|
|
1195
|
-
return candidate.finalCompletion();
|
|
1196
|
-
}
|
|
1197
|
-
if (typeof candidate.finalContent === "function") {
|
|
1198
|
-
return candidate.finalContent();
|
|
1199
|
-
}
|
|
1200
|
-
return void 0;
|
|
1201
|
-
}
|
|
1202
|
-
function ensureAsyncIterable(value, label) {
|
|
1203
|
-
if (!value || typeof value !== "object" || typeof value[Symbol.asyncIterator] !== "function") {
|
|
1204
|
-
throw new UsageTapError(
|
|
1205
|
-
"USAGETAP_BAD_REQUEST",
|
|
1206
|
-
`${label} expected an async iterable stream but received ${typeof value}`
|
|
1207
|
-
);
|
|
1208
|
-
}
|
|
1209
|
-
}
|
|
1210
|
-
function chunkToText(chunk) {
|
|
1211
|
-
if (chunk === void 0 || chunk === null) {
|
|
1212
|
-
return "";
|
|
1213
|
-
}
|
|
1214
|
-
if (typeof chunk === "string") {
|
|
1215
|
-
return chunk;
|
|
1216
|
-
}
|
|
1217
|
-
if (typeof chunk === "object") {
|
|
1218
|
-
const candidate = chunk;
|
|
1219
|
-
const delta = candidate.choices?.[0]?.delta;
|
|
1220
|
-
const content = delta?.content ?? candidate.content;
|
|
1221
|
-
if (typeof content === "string") {
|
|
1222
|
-
return content;
|
|
1223
|
-
}
|
|
1224
|
-
if (Array.isArray(content)) {
|
|
1225
|
-
return content.map((entry) => {
|
|
1226
|
-
if (!entry) return "";
|
|
1227
|
-
if (typeof entry === "string") return entry;
|
|
1228
|
-
if (typeof entry.text === "string") return entry.text;
|
|
1229
|
-
return "";
|
|
1230
|
-
}).join("");
|
|
1231
|
-
}
|
|
1232
|
-
}
|
|
1233
|
-
return String(chunk);
|
|
1234
|
-
}
|
|
1235
|
-
function formatSsePayload(text, options) {
|
|
1236
|
-
if (!text) {
|
|
1237
|
-
return "";
|
|
1238
|
-
}
|
|
1239
|
-
const lines = text.split(/\r?\n/);
|
|
1240
|
-
const eventLine = options?.event ? `event: ${options.event}
|
|
1241
|
-
` : "";
|
|
1242
|
-
const retryLine = options?.retry ? `retry: ${options.retry}
|
|
1243
|
-
` : "";
|
|
1244
|
-
const dataLines = lines.map((line) => `data: ${line}`).join("\n");
|
|
1245
|
-
return `${eventLine}${retryLine}${dataLines}
|
|
1246
|
-
|
|
1247
|
-
`;
|
|
1248
|
-
}
|
|
1249
|
-
function setHeaderIfPossible(res, key, value) {
|
|
1250
|
-
if (typeof res.setHeader === "function" && res.headersSent !== true) {
|
|
1251
|
-
res.setHeader(key, value);
|
|
1252
|
-
}
|
|
1253
|
-
}
|
|
1254
|
-
function tryInferUsage(response, hints, extractor, ctx) {
|
|
1255
|
-
const explicit = extractor?.(response);
|
|
1256
|
-
const inferred = explicit ?? inferUsageFromResponse(response, hints);
|
|
1257
|
-
if (inferred) {
|
|
1258
|
-
ctx.setUsage(inferred);
|
|
1259
|
-
}
|
|
1260
|
-
}
|
|
1261
|
-
function inferUsageFromResponse(response, hints) {
|
|
1262
|
-
if (!response || typeof response !== "object") {
|
|
1263
|
-
return void 0;
|
|
1264
|
-
}
|
|
1265
|
-
const candidate = response;
|
|
1266
|
-
if (!candidate.usage) {
|
|
1267
|
-
return void 0;
|
|
1268
|
-
}
|
|
1269
|
-
return {
|
|
1270
|
-
modelUsed: candidate.model ?? hints?.preferredModel,
|
|
1271
|
-
inputTokens: candidate.usage.prompt_tokens,
|
|
1272
|
-
responseTokens: candidate.usage.completion_tokens,
|
|
1273
|
-
cachedTokens: candidate.usage.cached_tokens
|
|
1274
|
-
};
|
|
1275
|
-
}
|
|
1276
|
-
function wrapStreamForUsageTap(source, finalize, ctx) {
|
|
1277
|
-
const getIterator = source[Symbol.asyncIterator];
|
|
1278
|
-
if (typeof getIterator !== "function") {
|
|
1279
|
-
throw new TypeError("Stream is not async iterable");
|
|
1280
|
-
}
|
|
1281
|
-
const iterator = getIterator.call(source);
|
|
1282
|
-
let completed = false;
|
|
1283
|
-
const invokeFinalize = async () => {
|
|
1284
|
-
if (completed) return;
|
|
1285
|
-
completed = true;
|
|
1286
|
-
try {
|
|
1287
|
-
await finalize();
|
|
1288
|
-
} catch (error) {
|
|
1289
|
-
ctx.setError({
|
|
1290
|
-
code: "USAGE_FINALIZE_ERROR",
|
|
1291
|
-
message: error instanceof Error ? error.message : String(error)
|
|
1292
|
-
});
|
|
1293
|
-
throw error;
|
|
1294
|
-
}
|
|
1295
|
-
};
|
|
1296
|
-
const prototype = Object.getPrototypeOf(source) ?? Object.prototype;
|
|
1297
|
-
const wrapped = Object.create(prototype);
|
|
1298
|
-
for (const key of Reflect.ownKeys(source)) {
|
|
1299
|
-
try {
|
|
1300
|
-
const descriptor = Object.getOwnPropertyDescriptor(source, key);
|
|
1301
|
-
if (descriptor) {
|
|
1302
|
-
Object.defineProperty(wrapped, key, descriptor);
|
|
1303
|
-
}
|
|
1304
|
-
} catch {
|
|
1305
|
-
}
|
|
1306
|
-
}
|
|
1307
|
-
Object.defineProperty(wrapped, Symbol.asyncIterator, {
|
|
1308
|
-
value() {
|
|
1309
|
-
return this;
|
|
1310
|
-
},
|
|
1311
|
-
configurable: true
|
|
1312
|
-
});
|
|
1313
|
-
Object.defineProperty(wrapped, "next", {
|
|
1314
|
-
value: async (...args) => {
|
|
1315
|
-
try {
|
|
1316
|
-
const result = await iterator.next(...args);
|
|
1317
|
-
if (result.done) {
|
|
1318
|
-
await invokeFinalize();
|
|
1319
|
-
}
|
|
1320
|
-
return result;
|
|
1321
|
-
} catch (error) {
|
|
1322
|
-
await invokeFinalize().catch(() => void 0);
|
|
1323
|
-
throw error;
|
|
1324
|
-
}
|
|
1325
|
-
},
|
|
1326
|
-
configurable: true,
|
|
1327
|
-
writable: true
|
|
1328
|
-
});
|
|
1329
|
-
Object.defineProperty(wrapped, "return", {
|
|
1330
|
-
value: async (value) => {
|
|
1331
|
-
if (typeof iterator.return === "function") {
|
|
1332
|
-
const rawResult = await iterator.return(value);
|
|
1333
|
-
if (!isIteratorResult(rawResult)) {
|
|
1334
|
-
throw new TypeError("Iterator.return() returned an invalid result");
|
|
1335
|
-
}
|
|
1336
|
-
await invokeFinalize();
|
|
1337
|
-
return rawResult;
|
|
1338
|
-
}
|
|
1339
|
-
await invokeFinalize();
|
|
1340
|
-
return { done: true, value };
|
|
1341
|
-
},
|
|
1342
|
-
configurable: true,
|
|
1343
|
-
writable: true
|
|
1344
|
-
});
|
|
1345
|
-
Object.defineProperty(wrapped, "throw", {
|
|
1346
|
-
value: async (error) => {
|
|
1347
|
-
if (typeof iterator.throw === "function") {
|
|
1348
|
-
const rawResult = await iterator.throw(error);
|
|
1349
|
-
if (!isIteratorResult(rawResult)) {
|
|
1350
|
-
throw new TypeError("Iterator.throw() returned an invalid result");
|
|
1351
|
-
}
|
|
1352
|
-
await invokeFinalize();
|
|
1353
|
-
return rawResult;
|
|
1354
|
-
}
|
|
1355
|
-
await invokeFinalize();
|
|
1356
|
-
throw error;
|
|
1357
|
-
},
|
|
1358
|
-
configurable: true,
|
|
1359
|
-
writable: true
|
|
1360
|
-
});
|
|
1361
|
-
Object.defineProperty(wrapped, "__usageTapFinalize", {
|
|
1362
|
-
value: async () => {
|
|
1363
|
-
await invokeFinalize();
|
|
1364
|
-
},
|
|
1365
|
-
configurable: true
|
|
1366
|
-
});
|
|
1367
|
-
return wrapped;
|
|
1368
|
-
}
|
|
1369
|
-
function isIteratorResult(value) {
|
|
1370
|
-
return isObjectRecord(value) && "done" in value;
|
|
1371
|
-
}
|
|
1372
|
-
|
|
1373
|
-
// src/adapters/openrouter.ts
|
|
1374
|
-
function createOpenRouterAdapter(init) {
|
|
1375
|
-
return createOpenAIAdapter(init);
|
|
1376
|
-
}
|
|
1377
|
-
|
|
1378
679
|
// src/adapters/fetch-wrapper.ts
|
|
1379
680
|
function isJsonRecord(value) {
|
|
1380
681
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -1618,51 +919,10 @@ async function finalizeCall(callState, usageTap, error, usage) {
|
|
|
1618
919
|
}
|
|
1619
920
|
}
|
|
1620
921
|
|
|
1621
|
-
// src/adapters/express-middleware.ts
|
|
1622
|
-
function withUsageMiddleware(usageTap, options) {
|
|
1623
|
-
return async (req, res, next) => {
|
|
1624
|
-
try {
|
|
1625
|
-
const customerId = await options.getCustomerId(req);
|
|
1626
|
-
const feature = options.getFeature ? await options.getFeature(req) : void 0;
|
|
1627
|
-
const tags = options.getTags ? await options.getTags(req) : void 0;
|
|
1628
|
-
const baseContext = {
|
|
1629
|
-
customerId,
|
|
1630
|
-
feature,
|
|
1631
|
-
tags,
|
|
1632
|
-
...options.defaultContext
|
|
1633
|
-
};
|
|
1634
|
-
req.usageTap = {
|
|
1635
|
-
openai: (client, contextOverride, wrapOptions) => {
|
|
1636
|
-
const mergedContext = { ...baseContext, ...contextOverride };
|
|
1637
|
-
return wrapOpenAI(client, usageTap, {
|
|
1638
|
-
...wrapOptions,
|
|
1639
|
-
defaultContext: mergedContext
|
|
1640
|
-
});
|
|
1641
|
-
},
|
|
1642
|
-
pipeToResponse
|
|
1643
|
-
};
|
|
1644
|
-
next();
|
|
1645
|
-
} catch (error) {
|
|
1646
|
-
next(error);
|
|
1647
|
-
}
|
|
1648
|
-
};
|
|
1649
|
-
}
|
|
1650
|
-
function withUsage(usageTap, getCustomerId) {
|
|
1651
|
-
return withUsageMiddleware(usageTap, { getCustomerId });
|
|
1652
|
-
}
|
|
1653
|
-
|
|
1654
922
|
exports.UsageTapClient = UsageTapClient;
|
|
1655
923
|
exports.UsageTapError = UsageTapError;
|
|
1656
924
|
exports.createIdempotencyKey = createIdempotencyKey;
|
|
1657
|
-
exports.createOpenAIAdapter = createOpenAIAdapter;
|
|
1658
|
-
exports.createOpenRouterAdapter = createOpenRouterAdapter;
|
|
1659
925
|
exports.isUsageTapError = isUsageTapError;
|
|
1660
|
-
exports.pipeToResponse = pipeToResponse;
|
|
1661
|
-
exports.streamOpenAIRoute = streamOpenAIRoute;
|
|
1662
|
-
exports.toNextResponse = toNextResponse;
|
|
1663
|
-
exports.withUsage = withUsage;
|
|
1664
|
-
exports.withUsageMiddleware = withUsageMiddleware;
|
|
1665
926
|
exports.wrapFetch = wrapFetch;
|
|
1666
|
-
exports.wrapOpenAI = wrapOpenAI;
|
|
1667
927
|
//# sourceMappingURL=index.cjs.map
|
|
1668
928
|
//# sourceMappingURL=index.cjs.map
|