Task #6: Cost-based work fee pricing with BTC oracle
- btc-oracle.ts: CoinGecko BTC/USD fetch (60s cache), usdToSats() helper, fallback to BTC_PRICE_USD_FALLBACK env var (default $100k), 5s abort timeout - pricing.ts: Full rewrite — per-model token rates (Haiku/Sonnet, env-var overridable), DO infra amortisation, originator margin %, estimateInputTokens(), estimateOutputTokens() by request tier, calculateActualCostUsd() for post-work ledger, async calculateWorkFeeSats() → WorkFeeBreakdown - agent.ts: WorkResult now includes inputTokens + outputTokens from Anthropic usage; workModel/evalModel exposed as readonly public; EVAL_MODEL/WORK_MODEL env var support - jobs.ts: Work invoice creation calls pricingService.calculateWorkFeeSats() async; stores estimatedCostUsd/marginPct/btcPriceUsd on job; after executeWork stores actualInputTokens/actualOutputTokens/actualCostUsd; GET response includes pricingBreakdown (awaiting_work_payment) and costLedger (complete) - lib/db/src/schema/jobs.ts: 6 new real/integer columns for cost tracking; schema pushed - openapi.yaml: PricingBreakdown + CostLedger schemas added to JobStatusResponse - replit.md: 17 new env vars documented in Cost-based work fee pricing section
This commit is contained in:
@@ -7,6 +7,8 @@ export interface EvalResult {
|
||||
|
||||
export interface WorkResult {
|
||||
result: string;
|
||||
inputTokens: number;
|
||||
outputTokens: number;
|
||||
}
|
||||
|
||||
export interface AgentConfig {
|
||||
@@ -15,12 +17,12 @@ export interface AgentConfig {
|
||||
}
|
||||
|
||||
export class AgentService {
|
||||
private readonly evalModel: string;
|
||||
private readonly workModel: string;
|
||||
readonly evalModel: string;
|
||||
readonly workModel: string;
|
||||
|
||||
constructor(config?: AgentConfig) {
|
||||
this.evalModel = config?.evalModel ?? "claude-haiku-4-5";
|
||||
this.workModel = config?.workModel ?? "claude-sonnet-4-6";
|
||||
this.evalModel = config?.evalModel ?? process.env.EVAL_MODEL ?? "claude-haiku-4-5";
|
||||
this.workModel = config?.workModel ?? process.env.WORK_MODEL ?? "claude-sonnet-4-6";
|
||||
}
|
||||
|
||||
async evaluateRequest(requestText: string): Promise<EvalResult> {
|
||||
@@ -64,7 +66,11 @@ Fulfill it thoroughly and helpfully. Be concise yet complete.`,
|
||||
throw new Error("Unexpected non-text response from work model");
|
||||
}
|
||||
|
||||
return { result: block.text };
|
||||
return {
|
||||
result: block.text,
|
||||
inputTokens: message.usage.input_tokens,
|
||||
outputTokens: message.usage.output_tokens,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user