@blockrun/clawrouter 0.8.7 → 0.8.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +35 -4
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +10 -1
- package/dist/index.js +36 -4
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -221,6 +221,15 @@ type ModelPricing = {
|
|
|
221
221
|
* Get the ordered fallback chain for a tier: [primary, ...fallbacks].
|
|
222
222
|
*/
|
|
223
223
|
declare function getFallbackChain(tier: Tier, tierConfigs: Record<Tier, TierConfig>): string[];
|
|
224
|
+
/**
|
|
225
|
+
* Calculate cost for a specific model (used when fallback model is used).
|
|
226
|
+
* Returns updated cost fields for RoutingDecision.
|
|
227
|
+
*/
|
|
228
|
+
declare function calculateModelCost(model: string, modelPricing: Map<string, ModelPricing>, estimatedInputTokens: number, maxOutputTokens: number): {
|
|
229
|
+
costEstimate: number;
|
|
230
|
+
baselineCost: number;
|
|
231
|
+
savings: number;
|
|
232
|
+
};
|
|
224
233
|
/**
|
|
225
234
|
* Get the fallback chain filtered by context length.
|
|
226
235
|
* Only returns models that can handle the estimated total context.
|
|
@@ -882,4 +891,4 @@ declare function formatStatsAscii(stats: AggregatedStats): string;
|
|
|
882
891
|
|
|
883
892
|
declare const plugin: OpenClawPluginDefinition;
|
|
884
893
|
|
|
885
|
-
export { type AggregatedStats, BALANCE_THRESHOLDS, BLOCKRUN_MODELS, type BalanceInfo, BalanceMonitor, type CachedPaymentParams, type CachedResponse, DEFAULT_RETRY_CONFIG, DEFAULT_ROUTING_CONFIG, DEFAULT_SESSION_CONFIG, type DailyStats, EmptyWalletError, InsufficientFundsError, type InsufficientFundsInfo, type LowBalanceInfo, MODEL_ALIASES, OPENCLAW_MODELS, PaymentCache, type PaymentFetchResult, type PreAuthParams, type ProxyHandle, type ProxyOptions, RequestDeduplicator, type RetryConfig, type RoutingConfig, type RoutingDecision, RpcError, type SessionConfig, type SessionEntry, SessionStore, type SufficiencyResult, type Tier, type UsageEntry, blockrunProvider, buildProviderModels, createPaymentFetch, plugin as default, fetchWithRetry, formatStatsAscii, getAgenticModels, getFallbackChain, getFallbackChainFiltered, getModelContextWindow, getProxyPort, getSessionId, getStats, isAgenticModel, isBalanceError, isEmptyWalletError, isInsufficientFundsError, isRetryable, isRpcError, logUsage, resolveModelAlias, route, startProxy };
|
|
894
|
+
export { type AggregatedStats, BALANCE_THRESHOLDS, BLOCKRUN_MODELS, type BalanceInfo, BalanceMonitor, type CachedPaymentParams, type CachedResponse, DEFAULT_RETRY_CONFIG, DEFAULT_ROUTING_CONFIG, DEFAULT_SESSION_CONFIG, type DailyStats, EmptyWalletError, InsufficientFundsError, type InsufficientFundsInfo, type LowBalanceInfo, MODEL_ALIASES, OPENCLAW_MODELS, PaymentCache, type PaymentFetchResult, type PreAuthParams, type ProxyHandle, type ProxyOptions, RequestDeduplicator, type RetryConfig, type RoutingConfig, type RoutingDecision, RpcError, type SessionConfig, type SessionEntry, SessionStore, type SufficiencyResult, type Tier, type UsageEntry, blockrunProvider, buildProviderModels, calculateModelCost, createPaymentFetch, plugin as default, fetchWithRetry, formatStatsAscii, getAgenticModels, getFallbackChain, getFallbackChainFiltered, getModelContextWindow, getProxyPort, getSessionId, getStats, isAgenticModel, isBalanceError, isEmptyWalletError, isInsufficientFundsError, isRetryable, isRpcError, logUsage, resolveModelAlias, route, startProxy };
|
package/dist/index.js
CHANGED
|
@@ -931,6 +931,18 @@ function getFallbackChain(tier, tierConfigs) {
|
|
|
931
931
|
const config = tierConfigs[tier];
|
|
932
932
|
return [config.primary, ...config.fallback];
|
|
933
933
|
}
|
|
934
|
+
function calculateModelCost(model, modelPricing, estimatedInputTokens, maxOutputTokens) {
|
|
935
|
+
const pricing = modelPricing.get(model);
|
|
936
|
+
const inputCost = pricing ? estimatedInputTokens / 1e6 * pricing.inputPrice : 0;
|
|
937
|
+
const outputCost = pricing ? maxOutputTokens / 1e6 * pricing.outputPrice : 0;
|
|
938
|
+
const costEstimate = inputCost + outputCost;
|
|
939
|
+
const opusPricing = modelPricing.get("anthropic/claude-opus-4");
|
|
940
|
+
const baselineInput = opusPricing ? estimatedInputTokens / 1e6 * opusPricing.inputPrice : 0;
|
|
941
|
+
const baselineOutput = opusPricing ? maxOutputTokens / 1e6 * opusPricing.outputPrice : 0;
|
|
942
|
+
const baselineCost = baselineInput + baselineOutput;
|
|
943
|
+
const savings = baselineCost > 0 ? Math.max(0, (baselineCost - costEstimate) / baselineCost) : 0;
|
|
944
|
+
return { costEstimate, baselineCost, savings };
|
|
945
|
+
}
|
|
934
946
|
function getFallbackChainFiltered(tier, tierConfigs, estimatedTotalTokens, getContextWindow) {
|
|
935
947
|
const fullChain = getFallbackChain(tier, tierConfigs);
|
|
936
948
|
const filtered = fullChain.filter((modelId) => {
|
|
@@ -3177,10 +3189,20 @@ async function proxyRequest(req, res, apiBase, payFetch, options, routerOpts, de
|
|
|
3177
3189
|
heartbeatInterval = void 0;
|
|
3178
3190
|
}
|
|
3179
3191
|
if (routingDecision && actualModelUsed !== routingDecision.model) {
|
|
3192
|
+
const estimatedInputTokens = Math.ceil(body.length / 4);
|
|
3193
|
+
const newCosts = calculateModelCost(
|
|
3194
|
+
actualModelUsed,
|
|
3195
|
+
routerOpts.modelPricing,
|
|
3196
|
+
estimatedInputTokens,
|
|
3197
|
+
maxTokens
|
|
3198
|
+
);
|
|
3180
3199
|
routingDecision = {
|
|
3181
3200
|
...routingDecision,
|
|
3182
3201
|
model: actualModelUsed,
|
|
3183
|
-
reasoning: `${routingDecision.reasoning} | fallback to ${actualModelUsed}
|
|
3202
|
+
reasoning: `${routingDecision.reasoning} | fallback to ${actualModelUsed}`,
|
|
3203
|
+
costEstimate: newCosts.costEstimate,
|
|
3204
|
+
baselineCost: newCosts.baselineCost,
|
|
3205
|
+
savings: newCosts.savings
|
|
3184
3206
|
};
|
|
3185
3207
|
options.onRouted?.(routingDecision);
|
|
3186
3208
|
}
|
|
@@ -3372,13 +3394,22 @@ async function proxyRequest(req, res, apiBase, payFetch, options, routerOpts, de
|
|
|
3372
3394
|
throw err;
|
|
3373
3395
|
}
|
|
3374
3396
|
if (routingDecision) {
|
|
3397
|
+
const estimatedInputTokens = Math.ceil(body.length / 4);
|
|
3398
|
+
const accurateCosts = calculateModelCost(
|
|
3399
|
+
routingDecision.model,
|
|
3400
|
+
routerOpts.modelPricing,
|
|
3401
|
+
estimatedInputTokens,
|
|
3402
|
+
maxTokens
|
|
3403
|
+
);
|
|
3404
|
+
const costWithBuffer = accurateCosts.costEstimate * 1.2;
|
|
3405
|
+
const baselineWithBuffer = accurateCosts.baselineCost * 1.2;
|
|
3375
3406
|
const entry = {
|
|
3376
3407
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3377
3408
|
model: routingDecision.model,
|
|
3378
3409
|
tier: routingDecision.tier,
|
|
3379
|
-
cost:
|
|
3380
|
-
baselineCost:
|
|
3381
|
-
savings:
|
|
3410
|
+
cost: costWithBuffer,
|
|
3411
|
+
baselineCost: baselineWithBuffer,
|
|
3412
|
+
savings: accurateCosts.savings,
|
|
3382
3413
|
latencyMs: Date.now() - startTime
|
|
3383
3414
|
};
|
|
3384
3415
|
logUsage(entry).catch(() => {
|
|
@@ -3965,6 +3996,7 @@ export {
|
|
|
3965
3996
|
SessionStore,
|
|
3966
3997
|
blockrunProvider,
|
|
3967
3998
|
buildProviderModels,
|
|
3999
|
+
calculateModelCost,
|
|
3968
4000
|
createPaymentFetch,
|
|
3969
4001
|
index_default as default,
|
|
3970
4002
|
fetchWithRetry,
|