fix: run Surplus seller continuously
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
Reference in New Issue
Block a user