@usagetap/sdk 0.1.0 → 0.2.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 +17 -1
- package/dist/adapters/openai.d.cts +1 -1
- package/dist/adapters/openai.d.ts +1 -1
- package/dist/adapters/openrouter.d.cts +1 -1
- package/dist/adapters/openrouter.d.ts +1 -1
- package/dist/index.cjs +75 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +75 -1
- package/dist/index.js.map +1 -1
- package/dist/{openai-CKyw08rB.d.cts → openai-CeptbEGH.d.cts} +23 -1
- package/dist/{openai-CKyw08rB.d.ts → openai-CeptbEGH.d.ts} +23 -1
- package/package.json +6 -4
package/README.md
CHANGED
|
@@ -385,7 +385,8 @@ const { begin, end, vendor, endUsage } = envelope.data;
|
|
|
385
385
|
|
|
386
386
|
Key exports from `@usagetap/sdk`:
|
|
387
387
|
|
|
388
|
-
- `UsageTapClient` – minimal HTTP client for `call_begin` and `
|
|
388
|
+
- `UsageTapClient` – minimal HTTP client for `call_begin`, `call_end`, and `checkUsage`.
|
|
389
|
+
- `checkUsage` – lightweight method to query current usage status without creating a call session.
|
|
389
390
|
- `wrapOpenAI` – wraps an OpenAI client instance with automatic begin/end handling.
|
|
390
391
|
- `wrapFetch` – wraps a fetch function to automatically instrument OpenAI API calls (minimal integration).
|
|
391
392
|
- `withUsage` / `withUsageMiddleware` – Express middleware for server-side usage tracking (requires `express` peer dependency).
|
|
@@ -396,6 +397,21 @@ Key exports from `@usagetap/sdk`:
|
|
|
396
397
|
|
|
397
398
|
All helpers are designed for server runtimes. Use `UsageTapClient` with `allowBrowser: true` only for sandbox/test scenarios.
|
|
398
399
|
|
|
400
|
+
### Check usage without creating a call
|
|
401
|
+
|
|
402
|
+
When you need to display current quota status, plan details, or remaining balances without tracking a vendor call, use `checkUsage()`:
|
|
403
|
+
|
|
404
|
+
```ts
|
|
405
|
+
const usageStatus = await usageTap.checkUsage({ customerId: "cust_123" });
|
|
406
|
+
|
|
407
|
+
console.log("Meters:", usageStatus.data.meters);
|
|
408
|
+
console.log("Allowed:", usageStatus.data.allowed);
|
|
409
|
+
console.log("Plan:", usageStatus.data.plan);
|
|
410
|
+
console.log("Balances:", usageStatus.data.balances);
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
This returns the same rich usage snapshot as `call_begin` (meters, entitlements, subscription details, plan info, balances) but without creating a call record. Use this for dashboard widgets, pre-flight checks, or displaying quota status to users.
|
|
414
|
+
|
|
399
415
|
## Response envelope (canonical only)
|
|
400
416
|
|
|
401
417
|
UsageTap responds exclusively with the canonical `{ result, data, correlationId }` envelope for every endpoint. The SDK automatically sends `Accept: application/vnd.usagetap.v1+json`, parses the envelope, and returns strongly typed data structures. Transitional `raw` payloads and the `normalize*` helpers have been removed—`response.data` already contains the canonical shape you should persist or render.
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import 'openai';
|
|
2
|
-
export { N as NodeResponseLike, O as OpenAIAdapter, b as OpenAIAdapterInit, d as OpenAIInvokeParams, e as OpenAIInvokeResult,
|
|
2
|
+
export { N as NodeResponseLike, O as OpenAIAdapter, b as OpenAIAdapterInit, d as OpenAIInvokeParams, e as OpenAIInvokeResult, $ as OpenAIRequestContext, a0 as OpenAIStreamCallResult, f as OpenAIStreamParams, g as OpenAIStreamResult, S as StreamMode, l as StreamOpenAIRouteOptions, h as StreamToResponseOptions, a1 as UsageTapStream, i as WrapOpenAICallOptions, W as WrapOpenAIContext, a as WrapOpenAIOptions, j as WrapOpenAIResponseCallOptions, k as WrappedOpenAI, c as createOpenAIAdapter, p as pipeToResponse, s as streamOpenAIRoute, t as toNextResponse, w as wrapOpenAI } from '../openai-CeptbEGH.cjs';
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import 'openai';
|
|
2
|
-
export { N as NodeResponseLike, O as OpenAIAdapter, b as OpenAIAdapterInit, d as OpenAIInvokeParams, e as OpenAIInvokeResult,
|
|
2
|
+
export { N as NodeResponseLike, O as OpenAIAdapter, b as OpenAIAdapterInit, d as OpenAIInvokeParams, e as OpenAIInvokeResult, $ as OpenAIRequestContext, a0 as OpenAIStreamCallResult, f as OpenAIStreamParams, g as OpenAIStreamResult, S as StreamMode, l as StreamOpenAIRouteOptions, h as StreamToResponseOptions, a1 as UsageTapStream, i as WrapOpenAICallOptions, W as WrapOpenAIContext, a as WrapOpenAIOptions, j as WrapOpenAIResponseCallOptions, k as WrappedOpenAI, c as createOpenAIAdapter, p as pipeToResponse, s as streamOpenAIRoute, t as toNextResponse, w as wrapOpenAI } from '../openai-CeptbEGH.js';
|
package/dist/index.cjs
CHANGED
|
@@ -118,6 +118,7 @@ async function runWithRetry(operation, options, shouldRetry, onSchedule, signal)
|
|
|
118
118
|
// src/client.ts
|
|
119
119
|
var CALL_BEGIN_PATH = "call_begin";
|
|
120
120
|
var CALL_END_PATH = "call_end";
|
|
121
|
+
var CHECK_USAGE_PATH = "customers/{customerId}/usage";
|
|
121
122
|
var AUTH_HEADER = "authorization";
|
|
122
123
|
var API_KEY_HEADER = "x-api-key";
|
|
123
124
|
var CORRELATION_HEADER = "x-usage-correlation-id";
|
|
@@ -125,7 +126,7 @@ var IDEMPOTENCY_HEADER = "idempotency-key";
|
|
|
125
126
|
var SDK_HEADER = "x-usage-sdk";
|
|
126
127
|
var USER_AGENT = "UsageTapClient";
|
|
127
128
|
var CANONICAL_MEDIA_TYPE = "application/vnd.usagetap.v1+json";
|
|
128
|
-
var SDK_VERSION = "0.
|
|
129
|
+
var SDK_VERSION = "0.2.0" ;
|
|
129
130
|
var HAS_WINDOW = typeof globalThis !== "undefined" && typeof globalThis.window !== "undefined";
|
|
130
131
|
var UsageTapClient = class {
|
|
131
132
|
apiKey;
|
|
@@ -219,6 +220,23 @@ var UsageTapClient = class {
|
|
|
219
220
|
);
|
|
220
221
|
return response;
|
|
221
222
|
}
|
|
223
|
+
async checkUsage(request, options = {}) {
|
|
224
|
+
if (!request?.customerId) {
|
|
225
|
+
throw new UsageTapError(
|
|
226
|
+
"USAGETAP_BAD_REQUEST",
|
|
227
|
+
"checkUsage requires customerId"
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
const path = CHECK_USAGE_PATH.replace(
|
|
231
|
+
"{customerId}",
|
|
232
|
+
encodeURIComponent(request.customerId)
|
|
233
|
+
);
|
|
234
|
+
const response = await this.requestGet(
|
|
235
|
+
path,
|
|
236
|
+
options
|
|
237
|
+
);
|
|
238
|
+
return response;
|
|
239
|
+
}
|
|
222
240
|
async withUsage(beginRequest, handler, options = {}) {
|
|
223
241
|
const idempotencyKey = beginRequest.idempotency ?? (this.autoIdempotency ? this.idempotencyGenerator() : void 0);
|
|
224
242
|
const beginPayload = idempotencyKey ? { ...beginRequest, idempotency: idempotencyKey } : { ...beginRequest };
|
|
@@ -338,6 +356,62 @@ var UsageTapClient = class {
|
|
|
338
356
|
throw error;
|
|
339
357
|
});
|
|
340
358
|
}
|
|
359
|
+
async requestGet(path, options) {
|
|
360
|
+
const url = new URL(path, this.baseUrl).toString();
|
|
361
|
+
const headers = this.composeHeaders(void 0, options);
|
|
362
|
+
const resolvedRetry = resolveRetryOptions(
|
|
363
|
+
this.retryDefaults,
|
|
364
|
+
options.retries
|
|
365
|
+
);
|
|
366
|
+
const startTime = () => typeof performance !== "undefined" ? performance.now() : Date.now();
|
|
367
|
+
return runWithRetry(
|
|
368
|
+
async (attempt) => {
|
|
369
|
+
const startedAt = startTime();
|
|
370
|
+
this.log({
|
|
371
|
+
event: "request:start",
|
|
372
|
+
path,
|
|
373
|
+
attempt,
|
|
374
|
+
correlationId: options.correlationId
|
|
375
|
+
});
|
|
376
|
+
const response = await this.performFetch({
|
|
377
|
+
url,
|
|
378
|
+
method: "GET",
|
|
379
|
+
headers,
|
|
380
|
+
signal: options.signal
|
|
381
|
+
});
|
|
382
|
+
this.log({
|
|
383
|
+
event: "request:success",
|
|
384
|
+
path,
|
|
385
|
+
attempt,
|
|
386
|
+
correlationId: response.correlationId,
|
|
387
|
+
elapsedMs: startTime() - startedAt
|
|
388
|
+
});
|
|
389
|
+
return response;
|
|
390
|
+
},
|
|
391
|
+
resolvedRetry,
|
|
392
|
+
(error) => this.shouldRetry(error),
|
|
393
|
+
(attempt, delayMs, error) => {
|
|
394
|
+
this.log({
|
|
395
|
+
event: "retry:scheduled",
|
|
396
|
+
path,
|
|
397
|
+
attempt,
|
|
398
|
+
correlationId: options.correlationId,
|
|
399
|
+
error,
|
|
400
|
+
elapsedMs: delayMs
|
|
401
|
+
});
|
|
402
|
+
},
|
|
403
|
+
options.signal
|
|
404
|
+
).catch((error) => {
|
|
405
|
+
this.log({
|
|
406
|
+
event: "retry:exhausted",
|
|
407
|
+
path,
|
|
408
|
+
attempt: resolvedRetry.maxAttempts,
|
|
409
|
+
correlationId: options.correlationId,
|
|
410
|
+
error
|
|
411
|
+
});
|
|
412
|
+
throw error;
|
|
413
|
+
});
|
|
414
|
+
}
|
|
341
415
|
async performFetch(init) {
|
|
342
416
|
let response;
|
|
343
417
|
try {
|