fix: run Surplus seller continuously

This commit is contained in:
david
2026-08-28 09:27:53 +02:00
parent 41820b11bb
commit cd3ea734e3
4 changed files with 29 additions and 13 deletions

View File

@@ -145,9 +145,10 @@ OPENROUTER_CAPACITY_BASE_URL=https://openrouter.ai/api
SURPLUS_SELLER_WALLET=0x0000000000000000000000000000000000000000 SURPLUS_SELLER_WALLET=0x0000000000000000000000000000000000000000
SURPLUS_PAYOUT_ADDRESS=0x0000000000000000000000000000000000000000 SURPLUS_PAYOUT_ADDRESS=0x0000000000000000000000000000000000000000
# The controller discovers all fixed-price text models and selects one by # The controller discovers all fixed-price text models and selects one by
# current demand. It keeps only one active proof offer. # current demand. It keeps only one active offer. At the default 490 bps
SURPLUS_PER_OFFER_CAP_USD=1.00 # recovery floor, a $0.05 seller cap bounds upstream spend near $1.02 per day.
SURPLUS_AGGREGATE_CAP_USD=1.00 SURPLUS_PER_OFFER_CAP_USD=0.05
SURPLUS_AGGREGATE_CAP_USD=0.05
SURPLUS_OPENROUTER_RESERVE_USD=1.00 SURPLUS_OPENROUTER_RESERVE_USD=1.00
SURPLUS_OPENROUTER_MAX_LIMIT_USD=20.00 SURPLUS_OPENROUTER_MAX_LIMIT_USD=20.00
SURPLUS_MIN_RECOVERY_BPS=490 SURPLUS_MIN_RECOVERY_BPS=490

View File

@@ -72,11 +72,11 @@ export function loadSurplusManagerConfig(
providerBaseUrl, providerBaseUrl,
capacityBaseUrl, capacityBaseUrl,
perOfferCapUsd: usd( perOfferCapUsd: usd(
env.SURPLUS_PER_OFFER_CAP_USD ?? "1.00", env.SURPLUS_PER_OFFER_CAP_USD ?? "0.05",
"SURPLUS_PER_OFFER_CAP_USD", "SURPLUS_PER_OFFER_CAP_USD",
), ),
aggregateCapUsd: usd( aggregateCapUsd: usd(
env.SURPLUS_AGGREGATE_CAP_USD ?? "1.00", env.SURPLUS_AGGREGATE_CAP_USD ?? "0.05",
"SURPLUS_AGGREGATE_CAP_USD", "SURPLUS_AGGREGATE_CAP_USD",
), ),
sellerWallet, sellerWallet,

View File

@@ -212,7 +212,12 @@ export class SurplusSellerController {
} }
const allowance = await this.allowance.readAllowance(); const allowance = await this.allowance.readAllowance();
this.assertAllowance(allowance, parseUsdDecimal(this.config.aggregateCapUsd, "ceil")); this.assertAllowance(
allowance,
this.providerExposureUsdNanos(
parseUsdDecimal(this.config.aggregateCapUsd, "ceil"),
),
);
const [discovered, markets] = await Promise.all([ const [discovered, markets] = await Promise.all([
this.client.discoverModels( this.client.discoverModels(
this.config.providerApiKey, this.config.providerApiKey,
@@ -444,7 +449,9 @@ export class SurplusSellerController {
const allowance = await this.allowance.readAllowance(); const allowance = await this.allowance.readAllowance();
this.assertAllowance( this.assertAllowance(
allowance, allowance,
this.providerExposureUsdNanos(
parseUsdDecimal(this.config.perOfferCapUsd, "ceil"), parseUsdDecimal(this.config.perOfferCapUsd, "ceil"),
),
); );
const baselineAllowance = BigInt( const baselineAllowance = BigInt(
currentState.intent.baselineRemainingUsdNanos, currentState.intent.baselineRemainingUsdNanos,
@@ -452,7 +459,9 @@ export class SurplusSellerController {
const providerSpend = baselineAllowance > allowance.remainingUsdNanos const providerSpend = baselineAllowance > allowance.remainingUsdNanos
? baselineAllowance - allowance.remainingUsdNanos ? baselineAllowance - allowance.remainingUsdNanos
: 0n; : 0n;
const spendCap = parseUsdDecimal(this.config.perOfferCapUsd, "ceil"); const spendCap = this.providerExposureUsdNanos(
parseUsdDecimal(this.config.perOfferCapUsd, "ceil"),
);
if (this.config.stopAfterTrades > 0 && providerSpend >= spendCap) { if (this.config.stopAfterTrades > 0 && providerSpend >= spendCap) {
const stopping: SurplusControllerState = { const stopping: SurplusControllerState = {
version: 1, version: 1,
@@ -684,6 +693,12 @@ export class SurplusSellerController {
} }
} }
private providerExposureUsdNanos(sellerCapUsdNanos: bigint): bigint {
const numerator = sellerCapUsdNanos * 10_000n;
const denominator = BigInt(this.config.recoveryBps);
return (numerator + denominator - 1n) / denominator;
}
private assertAllowance( private assertAllowance(
allowance: OpenRouterKeyAllowance, allowance: OpenRouterKeyAllowance,
exposureUsdNanos: bigint, exposureUsdNanos: bigint,

View File

@@ -27,8 +27,8 @@ function config(): SurplusManagerConfig {
providerApiKey: "sk-or-v1-test", providerApiKey: "sk-or-v1-test",
providerBaseUrl: "https://openrouter.ai/api/v1", providerBaseUrl: "https://openrouter.ai/api/v1",
capacityBaseUrl: "https://openrouter.ai/api", capacityBaseUrl: "https://openrouter.ai/api",
perOfferCapUsd: "1.00", perOfferCapUsd: "0.05",
aggregateCapUsd: "1.00", aggregateCapUsd: "0.05",
sellerWallet: SELLER_WALLET, sellerWallet: SELLER_WALLET,
payoutAddress: SELLER_WALLET, payoutAddress: SELLER_WALLET,
maxCandidateOrderBooks: 10, maxCandidateOrderBooks: 10,
@@ -236,7 +236,7 @@ describe("SurplusSellerController", () => {
expect(client.createdPayload).toMatchObject({ expect(client.createdPayload).toMatchObject({
model: "beta-model", model: "beta-model",
costMultiplier: 0.04995, costMultiplier: 0.04995,
dailyCapUsd: 1, dailyCapUsd: 0.05,
payoutAddress: SELLER_WALLET, payoutAddress: SELLER_WALLET,
}); });
expect(store.state.phase).toBe("active"); expect(store.state.phase).toBe("active");
@@ -316,7 +316,7 @@ describe("SurplusSellerController", () => {
model: "beta-model", model: "beta-model",
sellerBaseUrl: "https://openrouter.ai/api/v1", sellerBaseUrl: "https://openrouter.ai/api/v1",
status: "inactive", status: "inactive",
capDailyUsd: 1, capDailyUsd: 0.05,
costMultiplierPpm: 49_950, costMultiplierPpm: 49_950,
inputMicroUsdPer1m: 3_972, inputMicroUsdPer1m: 3_972,
outputMicroUsdPer1m: 7_944, outputMicroUsdPer1m: 7_944,
@@ -331,7 +331,7 @@ describe("SurplusSellerController", () => {
costMultiplierPpm: 49_950, costMultiplierPpm: 49_950,
inputMicroUsdPer1m: 3_972, inputMicroUsdPer1m: 3_972,
outputMicroUsdPer1m: 7_944, outputMicroUsdPer1m: 7_944,
dailyCapUsd: 1, dailyCapUsd: 0.05,
baselineRemainingUsdNanos: "20000000000", baselineRemainingUsdNanos: "20000000000",
idempotencyKey: "create-1", idempotencyKey: "create-1",
createdAt: "2026-08-27T10:00:00.000Z", createdAt: "2026-08-27T10:00:00.000Z",