spb/worthdoing Public
Autonomous investigation agent that discovers, challenges, and ranks things genuinely worth doing — Claude + Firecrawl, Next.js 16, PostgreSQL
TypeScript 91.5%
SQL 5.8%
CSS 2.2%
1/**2 * WorthDoing.ai3 * Author: Simon-Pierre Boucher4 * Contact: contact@spboucher.ai5 * File: src/lib/anthropic/client.ts6 * Description: Anthropic adapter — singleton client and model configuration for the agent.7 */8import Anthropic from "@anthropic-ai/sdk";9import { env } from "@/lib/env";1011const globalForAnthropic = globalThis as unknown as { __wdAnthropic?: Anthropic };1213export function anthropic(): Anthropic {14 if (!globalForAnthropic.__wdAnthropic) {15 globalForAnthropic.__wdAnthropic = new Anthropic({16 apiKey: env().ANTHROPIC_API_KEY,17 maxRetries: 3,18 });19 }20 return globalForAnthropic.__wdAnthropic;21}2223export function agentModel(): string {24 return env().CLAUDE_AGENT_MODEL;25}2627export function synthesisModel(): string {28 return env().CLAUDE_SYNTHESIS_MODEL;29}3031/** Approximate USD cost for a request, for observability (list prices, claude-opus-5). */32export function estimateCostUsd(model: string, inputTokens: number, outputTokens: number): number {33 // Per-million-token list prices; fall back to Opus-tier if unknown.34 const prices: Record<string, { in: number; out: number }> = {35 "claude-opus-5": { in: 5, out: 25 },36 "claude-sonnet-5": { in: 3, out: 15 },37 "claude-haiku-4-5": { in: 1, out: 5 },38 };39 const p = prices[model] ?? { in: 5, out: 25 };40 return (inputTokens * p.in + outputTokens * p.out) / 1_000_000;41}42