@routstr/sdk 0.3.10 → 0.3.12
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 +19 -6
- package/dist/browser.d.mts +2 -2
- package/dist/browser.d.ts +2 -2
- package/dist/browser.js +201 -66
- package/dist/browser.js.map +1 -1
- package/dist/browser.mjs +198 -67
- package/dist/browser.mjs.map +1 -1
- package/dist/bun.d.mts +5 -5
- package/dist/bun.d.ts +5 -5
- package/dist/bun.js +275 -66
- package/dist/bun.js.map +1 -1
- package/dist/bun.mjs +272 -67
- package/dist/bun.mjs.map +1 -1
- package/dist/{bunSqlite-BMTseLIz.d.ts → bunSqlite-BmXWNc25.d.ts} +1 -1
- package/dist/{bunSqlite-D6AreVE2.d.mts → bunSqlite-Bro9efsl.d.mts} +1 -1
- package/dist/client/index.d.mts +31 -10
- package/dist/client/index.d.ts +31 -10
- package/dist/client/index.js +185 -36
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +182 -37
- package/dist/client/index.mjs.map +1 -1
- package/dist/discovery/index.d.mts +3 -3
- package/dist/discovery/index.d.ts +3 -3
- package/dist/discovery/index.js +12 -20
- package/dist/discovery/index.js.map +1 -1
- package/dist/discovery/index.mjs +12 -20
- package/dist/discovery/index.mjs.map +1 -1
- package/dist/index.d.mts +8 -6
- package/dist/index.d.ts +8 -6
- package/dist/index.js +201 -66
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +198 -67
- package/dist/index.mjs.map +1 -1
- package/dist/node.d.mts +2 -2
- package/dist/node.d.ts +2 -2
- package/dist/node.js +276 -66
- package/dist/node.js.map +1 -1
- package/dist/node.mjs +273 -67
- package/dist/node.mjs.map +1 -1
- package/dist/storage/bun.d.mts +4 -4
- package/dist/storage/bun.d.ts +4 -4
- package/dist/storage/bun.js +173 -0
- package/dist/storage/bun.js.map +1 -1
- package/dist/storage/bun.mjs +173 -0
- package/dist/storage/bun.mjs.map +1 -1
- package/dist/storage/index.d.mts +2 -2
- package/dist/storage/index.d.ts +2 -2
- package/dist/storage/index.js +99 -0
- package/dist/storage/index.js.map +1 -1
- package/dist/storage/index.mjs +99 -0
- package/dist/storage/index.mjs.map +1 -1
- package/dist/storage/node.d.mts +2 -2
- package/dist/storage/node.d.ts +2 -2
- package/dist/storage/node.js +174 -0
- package/dist/storage/node.js.map +1 -1
- package/dist/storage/node.mjs +174 -0
- package/dist/storage/node.mjs.map +1 -1
- package/dist/{store-C8MZlfuz.d.ts → store-CAQLSbEj.d.ts} +38 -1
- package/dist/{store-BiuM2V9N.d.mts → store-CuXwe5Rg.d.mts} +38 -1
- package/dist/wallet/index.js +38 -24
- package/dist/wallet/index.js.map +1 -1
- package/dist/wallet/index.mjs +38 -24
- package/dist/wallet/index.mjs.map +1 -1
- package/package.json +7 -3
package/dist/bun.mjs
CHANGED
|
@@ -137,6 +137,11 @@ var MintDiscoveryError = class extends Error {
|
|
|
137
137
|
}
|
|
138
138
|
baseUrl;
|
|
139
139
|
};
|
|
140
|
+
var DEFAULT_NOSTR_RELAYS = [
|
|
141
|
+
"wss://relay.damus.io",
|
|
142
|
+
"wss://nos.lol",
|
|
143
|
+
"wss://relay.routstr.com"
|
|
144
|
+
];
|
|
140
145
|
var ModelManager = class _ModelManager {
|
|
141
146
|
constructor(adapter, config = {}) {
|
|
142
147
|
this.adapter = adapter;
|
|
@@ -330,11 +335,11 @@ var ModelManager = class _ModelManager {
|
|
|
330
335
|
return this.bootstrapFromHttp(torMode, forceRefresh);
|
|
331
336
|
}
|
|
332
337
|
/**
|
|
333
|
-
* Resolve Nostr relay URLs
|
|
334
|
-
* Returns user-configured relays if set, otherwise the
|
|
338
|
+
* Resolve Nostr relay URLs.
|
|
339
|
+
* Returns user-configured relays if set, otherwise the shared defaults.
|
|
335
340
|
*/
|
|
336
|
-
getNostrRelays(
|
|
337
|
-
return this.nostrRelays && this.nostrRelays.length > 0 ? this.nostrRelays :
|
|
341
|
+
getNostrRelays() {
|
|
342
|
+
return this.nostrRelays && this.nostrRelays.length > 0 ? this.nostrRelays : DEFAULT_NOSTR_RELAYS;
|
|
338
343
|
}
|
|
339
344
|
/**
|
|
340
345
|
* Bootstrap providers from Nostr network (kind 38421)
|
|
@@ -343,11 +348,7 @@ var ModelManager = class _ModelManager {
|
|
|
343
348
|
* @returns Array of provider base URLs
|
|
344
349
|
*/
|
|
345
350
|
async bootstrapFromNostr(kind, torMode, forceRefresh = false) {
|
|
346
|
-
const relays = this.getNostrRelays(
|
|
347
|
-
"wss://relay.primal.net",
|
|
348
|
-
"wss://nos.lol",
|
|
349
|
-
"wss://relay.damus.io"
|
|
350
|
-
]);
|
|
351
|
+
const relays = this.getNostrRelays();
|
|
351
352
|
const cached = await this.getCachedNostrEvents(
|
|
352
353
|
{ kinds: [kind] },
|
|
353
354
|
this.cacheTTL,
|
|
@@ -530,12 +531,7 @@ var ModelManager = class _ModelManager {
|
|
|
530
531
|
);
|
|
531
532
|
let sessionEvents = cached;
|
|
532
533
|
if (cached.length === 0) {
|
|
533
|
-
const lgtmRelays = this.getNostrRelays(
|
|
534
|
-
"wss://relay.primal.net",
|
|
535
|
-
"wss://nos.lol",
|
|
536
|
-
"wss://relay.damus.io",
|
|
537
|
-
"wss://relay.routstr.com"
|
|
538
|
-
]);
|
|
534
|
+
const lgtmRelays = this.getNostrRelays();
|
|
539
535
|
const pool = new RelayPool();
|
|
540
536
|
const timeoutMs = 5e3;
|
|
541
537
|
await new Promise((resolve) => {
|
|
@@ -781,11 +777,7 @@ var ModelManager = class _ModelManager {
|
|
|
781
777
|
return cachedModels;
|
|
782
778
|
}
|
|
783
779
|
}
|
|
784
|
-
const relays = this.getNostrRelays(
|
|
785
|
-
"wss://relay.damus.io",
|
|
786
|
-
"wss://nos.lol",
|
|
787
|
-
"wss://relay.routstr.com"
|
|
788
|
-
]);
|
|
780
|
+
const relays = this.getNostrRelays();
|
|
789
781
|
const cached = await this.getCachedNostrEvents(
|
|
790
782
|
{ kinds: [38423], "#d": ["routstr-21-models"], authors: [this.routstrPubkey] },
|
|
791
783
|
this.cacheTTL,
|
|
@@ -1997,8 +1989,8 @@ var BalanceManager = class _BalanceManager {
|
|
|
1997
1989
|
const refundableProviderBalance = Object.entries(
|
|
1998
1990
|
balanceState.providerBalances
|
|
1999
1991
|
).filter(([providerBaseUrl]) => providerBaseUrl !== baseUrl).reduce((sum, [, value]) => sum + value, 0);
|
|
2000
|
-
if (totalMintBalance + targetProviderBalance < adjustedAmount && totalMintBalance + targetProviderBalance + refundableProviderBalance >= adjustedAmount && retryCount <
|
|
2001
|
-
await this._refundOtherProvidersForTopUp(baseUrl, mintUrl, retryCount);
|
|
1992
|
+
if (totalMintBalance + targetProviderBalance < adjustedAmount && totalMintBalance + targetProviderBalance + refundableProviderBalance >= adjustedAmount && retryCount < 3) {
|
|
1993
|
+
await this._refundOtherProvidersForTopUp(baseUrl, mintUrl, retryCount, adjustedAmount);
|
|
2002
1994
|
return this.createProviderToken({
|
|
2003
1995
|
...options,
|
|
2004
1996
|
retryCount: retryCount + 1
|
|
@@ -2137,33 +2129,47 @@ var BalanceManager = class _BalanceManager {
|
|
|
2137
2129
|
}
|
|
2138
2130
|
return candidates;
|
|
2139
2131
|
}
|
|
2140
|
-
async _refundOtherProvidersForTopUp(baseUrl, mintUrl, retryCount) {
|
|
2132
|
+
async _refundOtherProvidersForTopUp(baseUrl, mintUrl, retryCount, requiredAmount) {
|
|
2141
2133
|
const apiKeyDistribution = this.storageAdapter.getApiKeyDistribution();
|
|
2142
2134
|
const forceRefund = retryCount >= 2;
|
|
2143
|
-
const
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2135
|
+
const candidates = apiKeyDistribution.filter((apiKey) => apiKey.baseUrl !== baseUrl && apiKey.amount > 0).map((apiKey) => {
|
|
2136
|
+
const full = this.storageAdapter.getApiKey(apiKey.baseUrl);
|
|
2137
|
+
return {
|
|
2138
|
+
baseUrl: apiKey.baseUrl,
|
|
2139
|
+
amount: apiKey.amount,
|
|
2140
|
+
lastUsed: full?.lastUsed ?? 0,
|
|
2141
|
+
key: full?.key
|
|
2142
|
+
};
|
|
2143
|
+
}).filter((c) => c.key != null).sort((a, b) => a.lastUsed - b.lastUsed);
|
|
2144
|
+
if (candidates.length === 0) return;
|
|
2145
|
+
if (forceRefund) {
|
|
2146
|
+
for (const candidate of candidates) {
|
|
2147
|
+
await this.refundApiKey({
|
|
2155
2148
|
mintUrl,
|
|
2156
|
-
baseUrl:
|
|
2157
|
-
apiKey:
|
|
2158
|
-
forceRefund
|
|
2149
|
+
baseUrl: candidate.baseUrl,
|
|
2150
|
+
apiKey: candidate.key,
|
|
2151
|
+
forceRefund: true
|
|
2159
2152
|
});
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2153
|
+
const newState = await this.getBalanceState();
|
|
2154
|
+
const newAvailable = (newState.mintBalances[mintUrl] || 0) + (newState.providerBalances[baseUrl] || 0);
|
|
2155
|
+
if (newAvailable >= requiredAmount) {
|
|
2156
|
+
this.logger.log(
|
|
2157
|
+
`_refundOtherProvidersForTopUp: freed enough balance (${newAvailable} >= ${requiredAmount}), stopping early`
|
|
2158
|
+
);
|
|
2159
|
+
return;
|
|
2160
|
+
}
|
|
2166
2161
|
}
|
|
2162
|
+
} else {
|
|
2163
|
+
await Promise.allSettled(
|
|
2164
|
+
candidates.map(
|
|
2165
|
+
(candidate) => this.refundApiKey({
|
|
2166
|
+
mintUrl,
|
|
2167
|
+
baseUrl: candidate.baseUrl,
|
|
2168
|
+
apiKey: candidate.key,
|
|
2169
|
+
forceRefund: false
|
|
2170
|
+
})
|
|
2171
|
+
)
|
|
2172
|
+
);
|
|
2167
2173
|
}
|
|
2168
2174
|
}
|
|
2169
2175
|
/**
|
|
@@ -3160,6 +3166,149 @@ var SDK_STORAGE_KEYS = {
|
|
|
3160
3166
|
PROVIDERS_ON_COOLDOWN: "providers_on_cooldown"
|
|
3161
3167
|
};
|
|
3162
3168
|
|
|
3169
|
+
// storage/usageTracking/aggregate.ts
|
|
3170
|
+
var pad2 = (n) => String(n).padStart(2, "0");
|
|
3171
|
+
var aggregateColumns = "COUNT(*) AS requests, COALESCE(SUM(prompt_tokens), 0) AS promptTokens, COALESCE(SUM(completion_tokens), 0) AS completionTokens, COALESCE(SUM(total_tokens), 0) AS totalTokens, COALESCE(SUM(cost), 0) AS cost, COALESCE(SUM(sats_cost), 0) AS satsCost, COALESCE(SUM(base_msats), 0) AS baseMsats, COALESCE(SUM(input_msats), 0) AS inputMsats, COALESCE(SUM(output_msats), 0) AS outputMsats, COALESCE(SUM(total_msats), 0) AS totalMsats, COALESCE(SUM(total_usd), 0) AS totalUsd, COALESCE(SUM(cache_read_input_tokens), 0) AS cacheReadInputTokens, COALESCE(SUM(cache_creation_input_tokens), 0) AS cacheCreationInputTokens, COALESCE(SUM(cache_read_msats), 0) AS cacheReadMsats, COALESCE(SUM(cache_creation_msats), 0) AS cacheCreationMsats";
|
|
3172
|
+
var sqlGroupExpr = (groupBy) => {
|
|
3173
|
+
switch (groupBy) {
|
|
3174
|
+
case "modelId":
|
|
3175
|
+
return { expr: "model_id", usesTz: false };
|
|
3176
|
+
case "baseUrl":
|
|
3177
|
+
return { expr: "base_url", usesTz: false };
|
|
3178
|
+
case "client":
|
|
3179
|
+
return { expr: "client", usesTz: false };
|
|
3180
|
+
case "sessionId":
|
|
3181
|
+
return { expr: "session_id", usesTz: false };
|
|
3182
|
+
case "provider":
|
|
3183
|
+
return { expr: "provider", usesTz: false };
|
|
3184
|
+
case "day":
|
|
3185
|
+
return {
|
|
3186
|
+
expr: "strftime('%Y-%m-%d', (timestamp - ? * 60000) / 1000, 'unixepoch')",
|
|
3187
|
+
usesTz: true
|
|
3188
|
+
};
|
|
3189
|
+
case "hour":
|
|
3190
|
+
return {
|
|
3191
|
+
expr: "strftime('%H', (timestamp - ? * 60000) / 1000, 'unixepoch')",
|
|
3192
|
+
usesTz: true
|
|
3193
|
+
};
|
|
3194
|
+
}
|
|
3195
|
+
};
|
|
3196
|
+
var buildAggregateSql = (tableName, where, options = {}) => {
|
|
3197
|
+
if (!options.groupBy) {
|
|
3198
|
+
return {
|
|
3199
|
+
sql: `SELECT NULL AS grp, ${aggregateColumns} FROM ${tableName} ${where.sql}`,
|
|
3200
|
+
params: where.params
|
|
3201
|
+
};
|
|
3202
|
+
}
|
|
3203
|
+
const { expr, usesTz } = sqlGroupExpr(options.groupBy);
|
|
3204
|
+
const tzParams = usesTz ? [options.tzOffsetMinutes ?? 0] : [];
|
|
3205
|
+
const orderBy = options.groupBy === "day" || options.groupBy === "hour" ? "ORDER BY grp ASC" : "ORDER BY satsCost DESC";
|
|
3206
|
+
return {
|
|
3207
|
+
sql: `SELECT ${expr} AS grp, ${aggregateColumns} FROM ${tableName} ${where.sql} GROUP BY grp ${orderBy}`,
|
|
3208
|
+
params: [...tzParams, ...where.params]
|
|
3209
|
+
};
|
|
3210
|
+
};
|
|
3211
|
+
var mapAggregateRow = (row) => ({
|
|
3212
|
+
group: row.grp == null ? null : String(row.grp),
|
|
3213
|
+
requests: Number(row.requests ?? 0),
|
|
3214
|
+
promptTokens: Number(row.promptTokens ?? 0),
|
|
3215
|
+
completionTokens: Number(row.completionTokens ?? 0),
|
|
3216
|
+
totalTokens: Number(row.totalTokens ?? 0),
|
|
3217
|
+
cost: Number(row.cost ?? 0),
|
|
3218
|
+
satsCost: Number(row.satsCost ?? 0),
|
|
3219
|
+
baseMsats: Number(row.baseMsats ?? 0),
|
|
3220
|
+
inputMsats: Number(row.inputMsats ?? 0),
|
|
3221
|
+
outputMsats: Number(row.outputMsats ?? 0),
|
|
3222
|
+
totalMsats: Number(row.totalMsats ?? 0),
|
|
3223
|
+
totalUsd: Number(row.totalUsd ?? 0),
|
|
3224
|
+
cacheReadInputTokens: Number(row.cacheReadInputTokens ?? 0),
|
|
3225
|
+
cacheCreationInputTokens: Number(row.cacheCreationInputTokens ?? 0),
|
|
3226
|
+
cacheReadMsats: Number(row.cacheReadMsats ?? 0),
|
|
3227
|
+
cacheCreationMsats: Number(row.cacheCreationMsats ?? 0)
|
|
3228
|
+
});
|
|
3229
|
+
var jsGroupKey = (entry, groupBy, tzOffsetMinutes) => {
|
|
3230
|
+
switch (groupBy) {
|
|
3231
|
+
case "modelId":
|
|
3232
|
+
return entry.modelId ?? null;
|
|
3233
|
+
case "baseUrl":
|
|
3234
|
+
return entry.baseUrl ?? null;
|
|
3235
|
+
case "client":
|
|
3236
|
+
return entry.client ?? null;
|
|
3237
|
+
case "sessionId":
|
|
3238
|
+
return entry.sessionId ?? null;
|
|
3239
|
+
case "provider":
|
|
3240
|
+
return entry.provider ?? null;
|
|
3241
|
+
case "day": {
|
|
3242
|
+
const d = new Date(entry.timestamp - tzOffsetMinutes * 6e4);
|
|
3243
|
+
return `${d.getUTCFullYear()}-${pad2(d.getUTCMonth() + 1)}-${pad2(d.getUTCDate())}`;
|
|
3244
|
+
}
|
|
3245
|
+
case "hour": {
|
|
3246
|
+
const d = new Date(entry.timestamp - tzOffsetMinutes * 6e4);
|
|
3247
|
+
return pad2(d.getUTCHours());
|
|
3248
|
+
}
|
|
3249
|
+
}
|
|
3250
|
+
};
|
|
3251
|
+
var reduceAggregate = (entries, options = {}) => {
|
|
3252
|
+
const emptyRow = (group) => ({
|
|
3253
|
+
group,
|
|
3254
|
+
requests: 0,
|
|
3255
|
+
promptTokens: 0,
|
|
3256
|
+
completionTokens: 0,
|
|
3257
|
+
totalTokens: 0,
|
|
3258
|
+
cost: 0,
|
|
3259
|
+
satsCost: 0,
|
|
3260
|
+
baseMsats: 0,
|
|
3261
|
+
inputMsats: 0,
|
|
3262
|
+
outputMsats: 0,
|
|
3263
|
+
totalMsats: 0,
|
|
3264
|
+
totalUsd: 0,
|
|
3265
|
+
cacheReadInputTokens: 0,
|
|
3266
|
+
cacheCreationInputTokens: 0,
|
|
3267
|
+
cacheReadMsats: 0,
|
|
3268
|
+
cacheCreationMsats: 0
|
|
3269
|
+
});
|
|
3270
|
+
const accumulate = (row, entry) => {
|
|
3271
|
+
row.requests += 1;
|
|
3272
|
+
row.promptTokens += entry.promptTokens;
|
|
3273
|
+
row.completionTokens += entry.completionTokens;
|
|
3274
|
+
row.totalTokens += entry.totalTokens;
|
|
3275
|
+
row.cost += entry.cost;
|
|
3276
|
+
row.satsCost += entry.satsCost;
|
|
3277
|
+
row.baseMsats += entry.baseMsats ?? 0;
|
|
3278
|
+
row.inputMsats += entry.inputMsats ?? 0;
|
|
3279
|
+
row.outputMsats += entry.outputMsats ?? 0;
|
|
3280
|
+
row.totalMsats += entry.totalMsats ?? 0;
|
|
3281
|
+
row.totalUsd += entry.totalUsd ?? 0;
|
|
3282
|
+
row.cacheReadInputTokens += entry.cacheReadInputTokens ?? 0;
|
|
3283
|
+
row.cacheCreationInputTokens += entry.cacheCreationInputTokens ?? 0;
|
|
3284
|
+
row.cacheReadMsats += entry.cacheReadMsats ?? 0;
|
|
3285
|
+
row.cacheCreationMsats += entry.cacheCreationMsats ?? 0;
|
|
3286
|
+
};
|
|
3287
|
+
if (!options.groupBy) {
|
|
3288
|
+
const total = emptyRow(null);
|
|
3289
|
+
for (const entry of entries) accumulate(total, entry);
|
|
3290
|
+
return [total];
|
|
3291
|
+
}
|
|
3292
|
+
const tz = options.tzOffsetMinutes ?? 0;
|
|
3293
|
+
const groups = /* @__PURE__ */ new Map();
|
|
3294
|
+
for (const entry of entries) {
|
|
3295
|
+
const key = jsGroupKey(entry, options.groupBy, tz);
|
|
3296
|
+
let row = groups.get(key);
|
|
3297
|
+
if (!row) {
|
|
3298
|
+
row = emptyRow(key);
|
|
3299
|
+
groups.set(key, row);
|
|
3300
|
+
}
|
|
3301
|
+
accumulate(row, entry);
|
|
3302
|
+
}
|
|
3303
|
+
const rows = [...groups.values()];
|
|
3304
|
+
if (options.groupBy === "day" || options.groupBy === "hour") {
|
|
3305
|
+
rows.sort((a, b) => (a.group ?? "").localeCompare(b.group ?? ""));
|
|
3306
|
+
} else {
|
|
3307
|
+
rows.sort((a, b) => b.satsCost - a.satsCost);
|
|
3308
|
+
}
|
|
3309
|
+
return rows;
|
|
3310
|
+
};
|
|
3311
|
+
|
|
3163
3312
|
// storage/usageTracking/indexedDB.ts
|
|
3164
3313
|
var DEFAULT_DB_NAME = "routstr-sdk";
|
|
3165
3314
|
var DEFAULT_STORE_NAME = "usage_tracking";
|
|
@@ -3222,6 +3371,9 @@ var matchesFilters = (entry, options = {}) => {
|
|
|
3222
3371
|
if (options.client && entry.client !== options.client) {
|
|
3223
3372
|
return false;
|
|
3224
3373
|
}
|
|
3374
|
+
if (options.clients && options.clients.length > 0 && (entry.client == null || !options.clients.includes(entry.client))) {
|
|
3375
|
+
return false;
|
|
3376
|
+
}
|
|
3225
3377
|
if (options.provider && entry.provider !== options.provider) {
|
|
3226
3378
|
return false;
|
|
3227
3379
|
}
|
|
@@ -3320,6 +3472,10 @@ var createIndexedDBUsageTrackingDriver = (options = {}) => {
|
|
|
3320
3472
|
const results = await this.list(options2);
|
|
3321
3473
|
return results.length;
|
|
3322
3474
|
},
|
|
3475
|
+
async aggregate(options2 = {}) {
|
|
3476
|
+
const entries = await this.list(options2);
|
|
3477
|
+
return reduceAggregate(entries, options2);
|
|
3478
|
+
},
|
|
3323
3479
|
async deleteOlderThan(timestamp) {
|
|
3324
3480
|
await ensureMigrated();
|
|
3325
3481
|
const db = await getDb();
|
|
@@ -3377,6 +3533,9 @@ var matchesFilters2 = (entry, options = {}) => {
|
|
|
3377
3533
|
if (options.client && entry.client !== options.client) {
|
|
3378
3534
|
return false;
|
|
3379
3535
|
}
|
|
3536
|
+
if (options.clients && options.clients.length > 0 && (entry.client == null || !options.clients.includes(entry.client))) {
|
|
3537
|
+
return false;
|
|
3538
|
+
}
|
|
3380
3539
|
if (options.provider && entry.provider !== options.provider) {
|
|
3381
3540
|
return false;
|
|
3382
3541
|
}
|
|
@@ -3409,6 +3568,10 @@ var createMemoryUsageTrackingDriver = (seed = []) => {
|
|
|
3409
3568
|
async count(options = {}) {
|
|
3410
3569
|
return (await this.list(options)).length;
|
|
3411
3570
|
},
|
|
3571
|
+
async aggregate(options = {}) {
|
|
3572
|
+
const entries = [...store.values()].filter((entry) => matchesFilters2(entry, options));
|
|
3573
|
+
return reduceAggregate(entries, options);
|
|
3574
|
+
},
|
|
3412
3575
|
async deleteOlderThan(timestamp) {
|
|
3413
3576
|
let deleted = 0;
|
|
3414
3577
|
for (const [id, entry] of store.entries()) {
|
|
@@ -4560,13 +4723,14 @@ function hasUsageChanged(previous, next) {
|
|
|
4560
4723
|
function isInspectionComplete(responseIdCaptured, usage) {
|
|
4561
4724
|
return responseIdCaptured && !!usage && usage.totalTokens > 0 && typeof usage.totalMsats === "number" && !!usage.provider;
|
|
4562
4725
|
}
|
|
4563
|
-
async function inspectSSEWebStream(stream, onUsage, onResponseId) {
|
|
4726
|
+
async function inspectSSEWebStream(stream, onUsage, onResponseId, options) {
|
|
4564
4727
|
const reader = stream.getReader();
|
|
4565
4728
|
const decoder = new TextDecoder("utf-8");
|
|
4566
4729
|
let buffer = "";
|
|
4567
4730
|
let capturedUsage = null;
|
|
4568
4731
|
let capturedResponseId;
|
|
4569
4732
|
let responseIdCaptured = false;
|
|
4733
|
+
let rawChunkSequence = 0;
|
|
4570
4734
|
const inspectDataPayload = (jsonText) => {
|
|
4571
4735
|
const trimmed = jsonText.trim();
|
|
4572
4736
|
if (!trimmed || trimmed === "[DONE]") {
|
|
@@ -4637,7 +4801,9 @@ async function inspectSSEWebStream(stream, onUsage, onResponseId) {
|
|
|
4637
4801
|
const { value, done } = await reader.read();
|
|
4638
4802
|
if (done) break;
|
|
4639
4803
|
if (value && value.byteLength > 0) {
|
|
4640
|
-
|
|
4804
|
+
const text = decoder.decode(value, { stream: true });
|
|
4805
|
+
void options?.onRawChunk?.(value, rawChunkSequence++, text);
|
|
4806
|
+
buffer += text;
|
|
4641
4807
|
drainBufferedEvents();
|
|
4642
4808
|
}
|
|
4643
4809
|
}
|
|
@@ -4782,6 +4948,7 @@ var RoutstrClient = class {
|
|
|
4782
4948
|
this.mode = mode;
|
|
4783
4949
|
this.usageTrackingDriver = options.usageTrackingDriver;
|
|
4784
4950
|
this.sdkStore = options.sdkStore;
|
|
4951
|
+
this.requestResponseLogSink = options.requestResponseLogSink;
|
|
4785
4952
|
this.providerManager = options.providerManager ?? new ProviderManager(providerRegistry, this.sdkStore, this.logger);
|
|
4786
4953
|
}
|
|
4787
4954
|
walletAdapter;
|
|
@@ -4796,6 +4963,7 @@ var RoutstrClient = class {
|
|
|
4796
4963
|
usageTrackingDriver;
|
|
4797
4964
|
sdkStore;
|
|
4798
4965
|
logger;
|
|
4966
|
+
requestResponseLogSink;
|
|
4799
4967
|
/**
|
|
4800
4968
|
* Get the current client mode
|
|
4801
4969
|
*/
|
|
@@ -4986,6 +5154,7 @@ var RoutstrClient = class {
|
|
|
4986
5154
|
let usagePromise = Promise.resolve({});
|
|
4987
5155
|
if (contentType.includes("text/event-stream") && response.body) {
|
|
4988
5156
|
const [clientStream, inspectStream] = response.body.tee();
|
|
5157
|
+
const requestResponseLogId = response.requestResponseLogId;
|
|
4989
5158
|
processedResponse = new Response(clientStream, {
|
|
4990
5159
|
status: response.status,
|
|
4991
5160
|
statusText: response.statusText,
|
|
@@ -4993,6 +5162,7 @@ var RoutstrClient = class {
|
|
|
4993
5162
|
});
|
|
4994
5163
|
processedResponse.baseUrl = response.baseUrl;
|
|
4995
5164
|
processedResponse.token = response.token;
|
|
5165
|
+
processedResponse.requestResponseLogId = requestResponseLogId;
|
|
4996
5166
|
usagePromise = inspectSSEWebStream(
|
|
4997
5167
|
inspectStream,
|
|
4998
5168
|
(usage) => {
|
|
@@ -5002,8 +5172,23 @@ var RoutstrClient = class {
|
|
|
5002
5172
|
(responseId) => {
|
|
5003
5173
|
capturedResponseId = responseId;
|
|
5004
5174
|
processedResponse.requestId = responseId;
|
|
5175
|
+
},
|
|
5176
|
+
{
|
|
5177
|
+
onRawChunk: (_chunk, sequence, text) => {
|
|
5178
|
+
void this.requestResponseLogSink?.logResponseChunk?.(
|
|
5179
|
+
requestResponseLogId,
|
|
5180
|
+
sequence,
|
|
5181
|
+
text
|
|
5182
|
+
);
|
|
5183
|
+
}
|
|
5005
5184
|
}
|
|
5006
|
-
)
|
|
5185
|
+
).then(async (result) => {
|
|
5186
|
+
await this.requestResponseLogSink?.logResponseEnd?.(requestResponseLogId);
|
|
5187
|
+
return result;
|
|
5188
|
+
}).catch(async (error) => {
|
|
5189
|
+
await this.requestResponseLogSink?.logResponseError?.(requestResponseLogId, error);
|
|
5190
|
+
throw error;
|
|
5191
|
+
});
|
|
5007
5192
|
processedResponse.usagePromise = usagePromise;
|
|
5008
5193
|
}
|
|
5009
5194
|
return {
|
|
@@ -5037,16 +5222,30 @@ var RoutstrClient = class {
|
|
|
5037
5222
|
const { path, method, body, baseUrl, token, headers } = params;
|
|
5038
5223
|
try {
|
|
5039
5224
|
const url = `${baseUrl.replace(/\/$/, "")}${path}`;
|
|
5225
|
+
const requestBodyText = body === void 0 || method === "GET" ? void 0 : JSON.stringify(body);
|
|
5226
|
+
const requestLogId = await this.requestResponseLogSink?.logRequest?.({
|
|
5227
|
+
method,
|
|
5228
|
+
url,
|
|
5229
|
+
path,
|
|
5230
|
+
baseUrl,
|
|
5231
|
+
headers,
|
|
5232
|
+
body,
|
|
5233
|
+
rawBody: requestBodyText
|
|
5234
|
+
});
|
|
5040
5235
|
if (this.mode === "xcashu") this._log("DEBUG", "HEADERS,", headers);
|
|
5041
5236
|
const response = await fetch(url, {
|
|
5042
5237
|
method,
|
|
5043
5238
|
headers,
|
|
5044
|
-
body:
|
|
5239
|
+
body: requestBodyText
|
|
5045
5240
|
});
|
|
5046
5241
|
if (this.mode === "xcashu") this._log("DEBUG", "response,", response);
|
|
5047
5242
|
response.baseUrl = baseUrl;
|
|
5048
5243
|
response.token = token;
|
|
5244
|
+
response.requestResponseLogId = requestLogId;
|
|
5245
|
+
await this.requestResponseLogSink?.logResponseStart?.(requestLogId, response);
|
|
5246
|
+
const contentType = response.headers.get("content-type") || "";
|
|
5049
5247
|
if (!response.ok) {
|
|
5248
|
+
void this.requestResponseLogSink?.logResponseBody?.(requestLogId, response.clone());
|
|
5050
5249
|
const requestId = response.headers.get("x-routstr-request-id") || void 0;
|
|
5051
5250
|
let bodyText;
|
|
5052
5251
|
try {
|
|
@@ -5064,6 +5263,9 @@ var RoutstrClient = class {
|
|
|
5064
5263
|
params.retryCount ?? 0
|
|
5065
5264
|
);
|
|
5066
5265
|
}
|
|
5266
|
+
if (!contentType.includes("text/event-stream")) {
|
|
5267
|
+
void this.requestResponseLogSink?.logResponseBody?.(requestLogId, response.clone());
|
|
5268
|
+
}
|
|
5067
5269
|
return response;
|
|
5068
5270
|
} catch (error) {
|
|
5069
5271
|
if (isNetworkErrorMessage(error?.message || "")) {
|
|
@@ -5953,15 +6155,8 @@ async function fetchAIResponse(options, callbacks, deps) {
|
|
|
5953
6155
|
const apiMessages = await convertMessages(messageHistory);
|
|
5954
6156
|
callbacks.onPaymentProcessing?.(true);
|
|
5955
6157
|
callbacks.onTokenCreated?.(deps.getPendingCashuTokenAmount?.() ?? 0);
|
|
5956
|
-
const providerInfo = await deps.providerRegistry.getProviderInfo(baseUrl);
|
|
5957
|
-
const providerVersion = providerInfo?.version ?? "";
|
|
5958
|
-
let modelIdForRequest = selectedModel.id;
|
|
5959
|
-
if (/^0\.1\./.test(providerVersion)) {
|
|
5960
|
-
const newModel = await deps.client.getProviderManager().getModelForProvider(baseUrl, selectedModel.id);
|
|
5961
|
-
modelIdForRequest = newModel?.id ?? selectedModel.id;
|
|
5962
|
-
}
|
|
5963
6158
|
const body = {
|
|
5964
|
-
model:
|
|
6159
|
+
model: selectedModel.id,
|
|
5965
6160
|
messages: apiMessages,
|
|
5966
6161
|
stream: true
|
|
5967
6162
|
};
|
|
@@ -6096,7 +6291,8 @@ async function resolveRouteRequestContext(options) {
|
|
|
6096
6291
|
usageTrackingDriver,
|
|
6097
6292
|
sdkStore,
|
|
6098
6293
|
providerManager: providedProviderManager,
|
|
6099
|
-
logger
|
|
6294
|
+
logger,
|
|
6295
|
+
requestResponseLogSink
|
|
6100
6296
|
} = options;
|
|
6101
6297
|
let modelManager;
|
|
6102
6298
|
let providers;
|
|
@@ -6145,15 +6341,8 @@ async function resolveRouteRequestContext(options) {
|
|
|
6145
6341
|
baseUrl = cheapest.baseUrl;
|
|
6146
6342
|
selectedModel = cheapest.model;
|
|
6147
6343
|
}
|
|
6148
|
-
const balances = await walletAdapter.getBalances();
|
|
6149
|
-
const totalBalance = Object.values(balances).reduce((sum, v) => sum + v, 0);
|
|
6150
|
-
if (totalBalance <= 0) {
|
|
6151
|
-
throw new Error(
|
|
6152
|
-
"Wallet balance is empty. Add a mint and fund it before making requests."
|
|
6153
|
-
);
|
|
6154
|
-
}
|
|
6155
6344
|
const providerMints = providerRegistry.getProviderMints(baseUrl);
|
|
6156
|
-
const mintUrl = walletAdapter.getActiveMintUrl() || providerMints[0] || Object.keys(
|
|
6345
|
+
const mintUrl = walletAdapter.getActiveMintUrl() || providerMints[0] || Object.keys(await walletAdapter.getBalances())[0];
|
|
6157
6346
|
if (!mintUrl) {
|
|
6158
6347
|
throw new Error("No mint configured in wallet");
|
|
6159
6348
|
}
|
|
@@ -6163,7 +6352,7 @@ async function resolveRouteRequestContext(options) {
|
|
|
6163
6352
|
providerRegistry,
|
|
6164
6353
|
"min",
|
|
6165
6354
|
mode,
|
|
6166
|
-
{ usageTrackingDriver, sdkStore, providerManager, logger }
|
|
6355
|
+
{ usageTrackingDriver, sdkStore, providerManager, logger, requestResponseLogSink }
|
|
6167
6356
|
);
|
|
6168
6357
|
const maxTokens = extractMaxTokens(requestBody);
|
|
6169
6358
|
const stream = extractStream(requestBody);
|
|
@@ -6230,6 +6419,8 @@ async function createBunSqliteDriver(dbPath, options) {
|
|
|
6230
6419
|
const logger = (options?.logger ?? consoleLogger).child("BunSqliteDriver");
|
|
6231
6420
|
const SQLite = (await import('bun:sqlite')).default;
|
|
6232
6421
|
const db = new SQLite(dbPath);
|
|
6422
|
+
db.run("PRAGMA journal_mode = WAL");
|
|
6423
|
+
db.run("PRAGMA busy_timeout = 5000");
|
|
6233
6424
|
db.run(`
|
|
6234
6425
|
CREATE TABLE IF NOT EXISTS sdk_storage (
|
|
6235
6426
|
key TEXT PRIMARY KEY,
|
|
@@ -6316,6 +6507,11 @@ var buildWhereClause = (options = {}) => {
|
|
|
6316
6507
|
clauses.push("client = ?");
|
|
6317
6508
|
params.push(options.client);
|
|
6318
6509
|
}
|
|
6510
|
+
if (options.clients && options.clients.length > 0) {
|
|
6511
|
+
const placeholders = options.clients.map(() => "?").join(", ");
|
|
6512
|
+
clauses.push(`client IN (${placeholders})`);
|
|
6513
|
+
params.push(...options.clients);
|
|
6514
|
+
}
|
|
6319
6515
|
if (options.provider) {
|
|
6320
6516
|
clauses.push("provider = ?");
|
|
6321
6517
|
params.push(options.provider);
|
|
@@ -6337,6 +6533,8 @@ var createBunSqliteUsageTrackingDriver = (options = {}) => {
|
|
|
6337
6533
|
);
|
|
6338
6534
|
}
|
|
6339
6535
|
const db = new SQLiteDatabase(dbPath);
|
|
6536
|
+
db.run("PRAGMA journal_mode = WAL");
|
|
6537
|
+
db.run("PRAGMA busy_timeout = 5000");
|
|
6340
6538
|
db.run(`
|
|
6341
6539
|
CREATE TABLE IF NOT EXISTS ${tableName} (
|
|
6342
6540
|
id TEXT PRIMARY KEY,
|
|
@@ -6489,6 +6687,13 @@ var createBunSqliteUsageTrackingDriver = (options = {}) => {
|
|
|
6489
6687
|
const row = db.query(query).get(...params);
|
|
6490
6688
|
return Number(row?.count ?? 0);
|
|
6491
6689
|
},
|
|
6690
|
+
async aggregate(options2 = {}) {
|
|
6691
|
+
await ensureMigrated();
|
|
6692
|
+
const where = buildWhereClause(options2);
|
|
6693
|
+
const { sql, params } = buildAggregateSql(tableName, where, options2);
|
|
6694
|
+
const rows = db.query(sql).all(...params);
|
|
6695
|
+
return rows.map(mapAggregateRow);
|
|
6696
|
+
},
|
|
6492
6697
|
async deleteOlderThan(timestamp) {
|
|
6493
6698
|
await ensureMigrated();
|
|
6494
6699
|
const before = timestamp;
|
|
@@ -6527,6 +6732,6 @@ async function createDefaultBunSqliteDriver(dbPath = "routstr.sqlite", options)
|
|
|
6527
6732
|
return createBunSqliteDriver(dbPath, options);
|
|
6528
6733
|
}
|
|
6529
6734
|
|
|
6530
|
-
export { BalanceManager, BunModelManager, CashuSpender, FailoverError, InsufficientBalanceError, MintDiscovery, MintDiscoveryError, MintUnreachableError, BunModelManager as ModelManager, ModelNotFoundError, NoProvidersAvailableError, ProviderBootstrapError, ProviderError, ProviderManager, RoutstrClient, SDK_STORAGE_KEYS, StreamProcessor, StreamingError, TokenOperationError, consoleLogger, createBunModelManager, createBunSqliteDriver, createBunSqliteUsageTrackingDriver2 as createBunSqliteUsageTrackingDriver, createBunSqliteUsageTrackingDriver as createBunSqliteUsageTrackingDriverWithDatabase, createDefaultBunSqliteDriver, createDiscoveryAdapterFromStore, createIndexedDBDriver, createIndexedDBUsageTrackingDriver, createMemoryDriver, createMemoryUsageTrackingDriver, createProviderRegistryFromDiscoveryAdapter, createProviderRegistryFromStore, createSSEParserTransform, createSdkStore, createShardedDiscoveryAdapter, createStorageAdapterFromStore, fetchAIResponse, filterBaseUrlsForTor, getDefaultDiscoveryAdapter, getDefaultProviderRegistry, getDefaultSdkDriver, getDefaultSdkStore, getDefaultStorageAdapter, getDefaultUsageTrackingDriver, getProviderEndpoints, inspectSSEWebStream, isOnionUrl, isTorContext, localStorageDriver, noopLogger, normalizeProviderUrl, routeRequests, setDefaultUsageTrackingDriver };
|
|
6735
|
+
export { BalanceManager, BunModelManager, CashuSpender, FailoverError, InsufficientBalanceError, MintDiscovery, MintDiscoveryError, MintUnreachableError, BunModelManager as ModelManager, ModelNotFoundError, NoProvidersAvailableError, ProviderBootstrapError, ProviderError, ProviderManager, RoutstrClient, SDK_STORAGE_KEYS, StreamProcessor, StreamingError, TokenOperationError, consoleLogger, createBunModelManager, createBunSqliteDriver, createBunSqliteUsageTrackingDriver2 as createBunSqliteUsageTrackingDriver, createBunSqliteUsageTrackingDriver as createBunSqliteUsageTrackingDriverWithDatabase, createDefaultBunSqliteDriver, createDiscoveryAdapterFromStore, createIndexedDBDriver, createIndexedDBUsageTrackingDriver, createMemoryDriver, createMemoryUsageTrackingDriver, createProviderRegistryFromDiscoveryAdapter, createProviderRegistryFromStore, createSSEParserTransform, createSdkStore, createShardedDiscoveryAdapter, createStorageAdapterFromStore, extractResponseId, extractUsageFromResponseBody, extractUsageFromSSEJson, fetchAIResponse, filterBaseUrlsForTor, getDefaultDiscoveryAdapter, getDefaultProviderRegistry, getDefaultSdkDriver, getDefaultSdkStore, getDefaultStorageAdapter, getDefaultUsageTrackingDriver, getProviderEndpoints, inspectSSEWebStream, isOnionUrl, isTorContext, localStorageDriver, noopLogger, normalizeProviderUrl, routeRequests, setDefaultUsageTrackingDriver, toUsageStats };
|
|
6531
6736
|
//# sourceMappingURL=bun.mjs.map
|
|
6532
6737
|
//# sourceMappingURL=bun.mjs.map
|