@routstr/sdk 0.3.10 → 0.3.11

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.
Files changed (63) hide show
  1. package/dist/browser.d.mts +2 -2
  2. package/dist/browser.d.ts +2 -2
  3. package/dist/browser.js +201 -66
  4. package/dist/browser.js.map +1 -1
  5. package/dist/browser.mjs +198 -67
  6. package/dist/browser.mjs.map +1 -1
  7. package/dist/bun.d.mts +5 -5
  8. package/dist/bun.d.ts +5 -5
  9. package/dist/bun.js +271 -66
  10. package/dist/bun.js.map +1 -1
  11. package/dist/bun.mjs +268 -67
  12. package/dist/bun.mjs.map +1 -1
  13. package/dist/{bunSqlite-BMTseLIz.d.ts → bunSqlite-BmXWNc25.d.ts} +1 -1
  14. package/dist/{bunSqlite-D6AreVE2.d.mts → bunSqlite-Bro9efsl.d.mts} +1 -1
  15. package/dist/client/index.d.mts +31 -10
  16. package/dist/client/index.d.ts +31 -10
  17. package/dist/client/index.js +185 -36
  18. package/dist/client/index.js.map +1 -1
  19. package/dist/client/index.mjs +182 -37
  20. package/dist/client/index.mjs.map +1 -1
  21. package/dist/discovery/index.d.mts +3 -3
  22. package/dist/discovery/index.d.ts +3 -3
  23. package/dist/discovery/index.js +12 -20
  24. package/dist/discovery/index.js.map +1 -1
  25. package/dist/discovery/index.mjs +12 -20
  26. package/dist/discovery/index.mjs.map +1 -1
  27. package/dist/index.d.mts +8 -6
  28. package/dist/index.d.ts +8 -6
  29. package/dist/index.js +201 -66
  30. package/dist/index.js.map +1 -1
  31. package/dist/index.mjs +198 -67
  32. package/dist/index.mjs.map +1 -1
  33. package/dist/node.d.mts +2 -2
  34. package/dist/node.d.ts +2 -2
  35. package/dist/node.js +272 -66
  36. package/dist/node.js.map +1 -1
  37. package/dist/node.mjs +269 -67
  38. package/dist/node.mjs.map +1 -1
  39. package/dist/storage/bun.d.mts +4 -4
  40. package/dist/storage/bun.d.ts +4 -4
  41. package/dist/storage/bun.js +169 -0
  42. package/dist/storage/bun.js.map +1 -1
  43. package/dist/storage/bun.mjs +169 -0
  44. package/dist/storage/bun.mjs.map +1 -1
  45. package/dist/storage/index.d.mts +2 -2
  46. package/dist/storage/index.d.ts +2 -2
  47. package/dist/storage/index.js +99 -0
  48. package/dist/storage/index.js.map +1 -1
  49. package/dist/storage/index.mjs +99 -0
  50. package/dist/storage/index.mjs.map +1 -1
  51. package/dist/storage/node.d.mts +2 -2
  52. package/dist/storage/node.d.ts +2 -2
  53. package/dist/storage/node.js +170 -0
  54. package/dist/storage/node.js.map +1 -1
  55. package/dist/storage/node.mjs +170 -0
  56. package/dist/storage/node.mjs.map +1 -1
  57. package/dist/{store-C8MZlfuz.d.ts → store-CAQLSbEj.d.ts} +38 -1
  58. package/dist/{store-BiuM2V9N.d.mts → store-CuXwe5Rg.d.mts} +38 -1
  59. package/dist/wallet/index.js +38 -24
  60. package/dist/wallet/index.js.map +1 -1
  61. package/dist/wallet/index.mjs +38 -24
  62. package/dist/wallet/index.mjs.map +1 -1
  63. package/package.json +1 -1
@@ -40,14 +40,51 @@ interface ListUsageTrackingOptions {
40
40
  baseUrl?: string;
41
41
  sessionId?: string;
42
42
  client?: string;
43
+ /** Match any of these client ids (SQL `client IN (...)`). Complements `client`. */
44
+ clients?: string[];
43
45
  provider?: string;
44
46
  }
47
+ /** Dimension to group usage aggregates by. `day`/`hour` are timezone-aware. */
48
+ type UsageGroupBy = "modelId" | "baseUrl" | "client" | "sessionId" | "provider" | "day" | "hour";
49
+ interface AggregateUsageOptions extends Omit<ListUsageTrackingOptions, "limit"> {
50
+ /** Group rows by this dimension. Omit for a single grand-total row. */
51
+ groupBy?: UsageGroupBy;
52
+ /**
53
+ * Minutes to subtract from each timestamp before `day`/`hour` bucketing,
54
+ * e.g. `new Date().getTimezoneOffset()`. Ignored for other groupings.
55
+ * Defaults to 0 (UTC).
56
+ */
57
+ tzOffsetMinutes?: number;
58
+ }
59
+ interface UsageAggregateRow {
60
+ /**
61
+ * The group key: the dimension value, "YYYY-MM-DD" (day) or "00".."23"
62
+ * (hour). `null` when `groupBy` is omitted or the grouped column is null.
63
+ */
64
+ group: string | null;
65
+ requests: number;
66
+ promptTokens: number;
67
+ completionTokens: number;
68
+ totalTokens: number;
69
+ cost: number;
70
+ satsCost: number;
71
+ baseMsats: number;
72
+ inputMsats: number;
73
+ outputMsats: number;
74
+ totalMsats: number;
75
+ totalUsd: number;
76
+ cacheReadInputTokens: number;
77
+ cacheCreationInputTokens: number;
78
+ cacheReadMsats: number;
79
+ cacheCreationMsats: number;
80
+ }
45
81
  interface UsageTrackingDriver {
46
82
  migrate(): Promise<void>;
47
83
  append(entry: UsageTrackingEntry): Promise<void>;
48
84
  appendMany(entries: UsageTrackingEntry[]): Promise<void>;
49
85
  list(options?: ListUsageTrackingOptions): Promise<UsageTrackingEntry[]>;
50
86
  count(options?: Omit<ListUsageTrackingOptions, "limit">): Promise<number>;
87
+ aggregate(options?: AggregateUsageOptions): Promise<UsageAggregateRow[]>;
51
88
  deleteOlderThan(timestamp: number): Promise<number>;
52
89
  clear(): Promise<void>;
53
90
  }
@@ -183,4 +220,4 @@ declare const createDiscoveryAdapterFromStore: (store: SdkStore) => DiscoveryAda
183
220
  declare const createStorageAdapterFromStore: (store: SdkStore) => StorageAdapter;
184
221
  declare const createProviderRegistryFromStore: (store: SdkStore, logger?: SdkLogger) => ProviderRegistry;
185
222
 
186
- export { type ListUsageTrackingOptions as L, type SdkStore as S, type UsageTrackingDriver as U, type StorageDriver as a, type UsageTrackingEntry as b, createDiscoveryAdapterFromStore as c, createProviderRegistryFromStore as d, createSdkStore as e, createStorageAdapterFromStore as f };
223
+ export { type AggregateUsageOptions as A, type ListUsageTrackingOptions as L, type SdkStore as S, type UsageAggregateRow as U, type StorageDriver as a, type UsageGroupBy as b, type UsageTrackingDriver as c, type UsageTrackingEntry as d, createDiscoveryAdapterFromStore as e, createProviderRegistryFromStore as f, createSdkStore as g, createStorageAdapterFromStore as h };
@@ -40,14 +40,51 @@ interface ListUsageTrackingOptions {
40
40
  baseUrl?: string;
41
41
  sessionId?: string;
42
42
  client?: string;
43
+ /** Match any of these client ids (SQL `client IN (...)`). Complements `client`. */
44
+ clients?: string[];
43
45
  provider?: string;
44
46
  }
47
+ /** Dimension to group usage aggregates by. `day`/`hour` are timezone-aware. */
48
+ type UsageGroupBy = "modelId" | "baseUrl" | "client" | "sessionId" | "provider" | "day" | "hour";
49
+ interface AggregateUsageOptions extends Omit<ListUsageTrackingOptions, "limit"> {
50
+ /** Group rows by this dimension. Omit for a single grand-total row. */
51
+ groupBy?: UsageGroupBy;
52
+ /**
53
+ * Minutes to subtract from each timestamp before `day`/`hour` bucketing,
54
+ * e.g. `new Date().getTimezoneOffset()`. Ignored for other groupings.
55
+ * Defaults to 0 (UTC).
56
+ */
57
+ tzOffsetMinutes?: number;
58
+ }
59
+ interface UsageAggregateRow {
60
+ /**
61
+ * The group key: the dimension value, "YYYY-MM-DD" (day) or "00".."23"
62
+ * (hour). `null` when `groupBy` is omitted or the grouped column is null.
63
+ */
64
+ group: string | null;
65
+ requests: number;
66
+ promptTokens: number;
67
+ completionTokens: number;
68
+ totalTokens: number;
69
+ cost: number;
70
+ satsCost: number;
71
+ baseMsats: number;
72
+ inputMsats: number;
73
+ outputMsats: number;
74
+ totalMsats: number;
75
+ totalUsd: number;
76
+ cacheReadInputTokens: number;
77
+ cacheCreationInputTokens: number;
78
+ cacheReadMsats: number;
79
+ cacheCreationMsats: number;
80
+ }
45
81
  interface UsageTrackingDriver {
46
82
  migrate(): Promise<void>;
47
83
  append(entry: UsageTrackingEntry): Promise<void>;
48
84
  appendMany(entries: UsageTrackingEntry[]): Promise<void>;
49
85
  list(options?: ListUsageTrackingOptions): Promise<UsageTrackingEntry[]>;
50
86
  count(options?: Omit<ListUsageTrackingOptions, "limit">): Promise<number>;
87
+ aggregate(options?: AggregateUsageOptions): Promise<UsageAggregateRow[]>;
51
88
  deleteOlderThan(timestamp: number): Promise<number>;
52
89
  clear(): Promise<void>;
53
90
  }
@@ -183,4 +220,4 @@ declare const createDiscoveryAdapterFromStore: (store: SdkStore) => DiscoveryAda
183
220
  declare const createStorageAdapterFromStore: (store: SdkStore) => StorageAdapter;
184
221
  declare const createProviderRegistryFromStore: (store: SdkStore, logger?: SdkLogger) => ProviderRegistry;
185
222
 
186
- export { type ListUsageTrackingOptions as L, type SdkStore as S, type UsageTrackingDriver as U, type StorageDriver as a, type UsageTrackingEntry as b, createDiscoveryAdapterFromStore as c, createProviderRegistryFromStore as d, createSdkStore as e, createStorageAdapterFromStore as f };
223
+ export { type AggregateUsageOptions as A, type ListUsageTrackingOptions as L, type SdkStore as S, type UsageAggregateRow as U, type StorageDriver as a, type UsageGroupBy as b, type UsageTrackingDriver as c, type UsageTrackingEntry as d, createDiscoveryAdapterFromStore as e, createProviderRegistryFromStore as f, createSdkStore as g, createStorageAdapterFromStore as h };
@@ -1032,8 +1032,8 @@ var BalanceManager = class _BalanceManager {
1032
1032
  const refundableProviderBalance = Object.entries(
1033
1033
  balanceState.providerBalances
1034
1034
  ).filter(([providerBaseUrl]) => providerBaseUrl !== baseUrl).reduce((sum, [, value]) => sum + value, 0);
1035
- if (totalMintBalance + targetProviderBalance < adjustedAmount && totalMintBalance + targetProviderBalance + refundableProviderBalance >= adjustedAmount && retryCount < 2) {
1036
- await this._refundOtherProvidersForTopUp(baseUrl, mintUrl, retryCount);
1035
+ if (totalMintBalance + targetProviderBalance < adjustedAmount && totalMintBalance + targetProviderBalance + refundableProviderBalance >= adjustedAmount && retryCount < 3) {
1036
+ await this._refundOtherProvidersForTopUp(baseUrl, mintUrl, retryCount, adjustedAmount);
1037
1037
  return this.createProviderToken({
1038
1038
  ...options,
1039
1039
  retryCount: retryCount + 1
@@ -1172,33 +1172,47 @@ var BalanceManager = class _BalanceManager {
1172
1172
  }
1173
1173
  return candidates;
1174
1174
  }
1175
- async _refundOtherProvidersForTopUp(baseUrl, mintUrl, retryCount) {
1175
+ async _refundOtherProvidersForTopUp(baseUrl, mintUrl, retryCount, requiredAmount) {
1176
1176
  const apiKeyDistribution = this.storageAdapter.getApiKeyDistribution();
1177
1177
  const forceRefund = retryCount >= 2;
1178
- const apiKeysToRefund = apiKeyDistribution.filter(
1179
- (apiKey) => apiKey.baseUrl !== baseUrl && apiKey.amount > 0
1180
- );
1181
- const apiKeyRefundResults = await Promise.allSettled(
1182
- apiKeysToRefund.map(async (apiKeyEntry) => {
1183
- const fullApiKeyEntry = this.storageAdapter.getApiKey(
1184
- apiKeyEntry.baseUrl
1185
- );
1186
- if (!fullApiKeyEntry) {
1187
- return { baseUrl: apiKeyEntry.baseUrl, success: false };
1188
- }
1189
- const result = await this.refundApiKey({
1178
+ const candidates = apiKeyDistribution.filter((apiKey) => apiKey.baseUrl !== baseUrl && apiKey.amount > 0).map((apiKey) => {
1179
+ const full = this.storageAdapter.getApiKey(apiKey.baseUrl);
1180
+ return {
1181
+ baseUrl: apiKey.baseUrl,
1182
+ amount: apiKey.amount,
1183
+ lastUsed: full?.lastUsed ?? 0,
1184
+ key: full?.key
1185
+ };
1186
+ }).filter((c) => c.key != null).sort((a, b) => a.lastUsed - b.lastUsed);
1187
+ if (candidates.length === 0) return;
1188
+ if (forceRefund) {
1189
+ for (const candidate of candidates) {
1190
+ await this.refundApiKey({
1190
1191
  mintUrl,
1191
- baseUrl: apiKeyEntry.baseUrl,
1192
- apiKey: fullApiKeyEntry.key,
1193
- forceRefund
1192
+ baseUrl: candidate.baseUrl,
1193
+ apiKey: candidate.key,
1194
+ forceRefund: true
1194
1195
  });
1195
- return { baseUrl: apiKeyEntry.baseUrl, success: result.success };
1196
- })
1197
- );
1198
- for (const result of apiKeyRefundResults) {
1199
- if (result.status === "fulfilled" && result.value.success) {
1200
- this.storageAdapter.updateApiKeyBalance(result.value.baseUrl, 0);
1196
+ const newState = await this.getBalanceState();
1197
+ const newAvailable = (newState.mintBalances[mintUrl] || 0) + (newState.providerBalances[baseUrl] || 0);
1198
+ if (newAvailable >= requiredAmount) {
1199
+ this.logger.log(
1200
+ `_refundOtherProvidersForTopUp: freed enough balance (${newAvailable} >= ${requiredAmount}), stopping early`
1201
+ );
1202
+ return;
1203
+ }
1201
1204
  }
1205
+ } else {
1206
+ await Promise.allSettled(
1207
+ candidates.map(
1208
+ (candidate) => this.refundApiKey({
1209
+ mintUrl,
1210
+ baseUrl: candidate.baseUrl,
1211
+ apiKey: candidate.key,
1212
+ forceRefund: false
1213
+ })
1214
+ )
1215
+ );
1202
1216
  }
1203
1217
  }
1204
1218
  /**