|
| 1 | +;; REPUTATION-WEIGHTED AUCTION BUYER |
| 2 | +;; ═══════════════════════════════════════════════════════════════════ |
| 3 | +;; |
| 4 | +;; Game-Theoretic Auction System: |
| 5 | +;; - Score = effective_price / (1 + reputation_bonus) |
| 6 | +;; - Lower score = better value (cheaper effective price) |
| 7 | +;; - High-reputation agents get bonus that reduces their effective price |
| 8 | +;; |
| 9 | +;; Formula: effective_price = price / (1 + 0.1 * deliveries + 0.05 * (wins/bids)) |
| 10 | +;; |
| 11 | +;; Example: |
| 12 | +;; Agent A: price=0.05, 10 deliveries, 8/10 wins → effective = 0.05/(1+1.0+0.4) = 0.021 |
| 13 | +;; Agent B: price=0.03, 0 deliveries, 0/1 wins → effective = 0.03/(1+0+0) = 0.030 |
| 14 | +;; Winner: Agent A (despite higher nominal price!) |
| 15 | +;; |
| 16 | +;; This breaks race-to-bottom dynamics and rewards reliability. |
| 17 | + |
| 18 | +(do |
| 19 | + (define bbs-url "http://localhost:9099") |
| 20 | + (define agent-name "OVSM-AuctionBuyer") |
| 21 | + (define budget 0.1) |
| 22 | + (define request-type "whale tracking with alerts") |
| 23 | + |
| 24 | + (log :message "") |
| 25 | + (log :message "╔═══════════════════════════════════════════════════════════════╗") |
| 26 | + (log :message "║ 🏛️ REPUTATION-WEIGHTED AUCTION SYSTEM 🏛️ ║") |
| 27 | + (log :message "╚═══════════════════════════════════════════════════════════════╝") |
| 28 | + (log :message (concatenate "Buyer: " agent-name)) |
| 29 | + (log :message (concatenate "Budget: " (str budget) " SOL")) |
| 30 | + (log :message "") |
| 31 | + (log :message "📜 AUCTION RULES:") |
| 32 | + (log :message " Score = price / (1 + reputation_bonus)") |
| 33 | + (log :message " reputation_bonus = 0.1 * deliveries + 0.05 * win_rate") |
| 34 | + (log :message " LOWEST SCORE WINS (quality-adjusted price)") |
| 35 | + (log :message "") |
| 36 | + |
| 37 | + ;; Step 1: Post auction request |
| 38 | + (define auction-id (str (now))) |
| 39 | + (define request-msg (concatenate "AUCTION: [" auction-id "] " agent-name " requests " request-type ". Budget: " (str budget) " SOL. REPUTATION-WEIGHTED scoring!")) |
| 40 | + (http-post (concatenate bbs-url "/api/boards/MARKETPLACE/posts") |
| 41 | + {:message request-msg :agent agent-name}) |
| 42 | + (log :message (concatenate "📢 Posted AUCTION request: " auction-id)) |
| 43 | + (log :message "") |
| 44 | + |
| 45 | + ;; Step 2: Fetch reputation data for all agents |
| 46 | + (log :message "📊 Loading reputation data...") |
| 47 | + (define rep-resp (http-get (concatenate bbs-url "/api/reputation"))) |
| 48 | + (define rep-data (get (parse-json (get rep-resp "body")) "data")) |
| 49 | + (define rep-agents (get rep-data "agents")) |
| 50 | + |
| 51 | + ;; Build reputation lookup map (agent_name -> {deliveries, wins, bids}) |
| 52 | + (define rep-map {}) |
| 53 | + (if (not (null? rep-agents)) |
| 54 | + (for (agent rep-agents) |
| 55 | + (do |
| 56 | + (define name (get agent "agent_name")) |
| 57 | + (define deliveries (get agent "deliveries")) |
| 58 | + (define wins (get agent "wins")) |
| 59 | + (define bids (get agent "bids")) |
| 60 | + (log :message (concatenate " " name ": " (str deliveries) " deliveries, " (str wins) "/" (str bids) " wins")))) |
| 61 | + (log :message " No reputation data yet")) |
| 62 | + (log :message "") |
| 63 | + |
| 64 | + ;; Step 3: Wait for bids |
| 65 | + (log :message "⏳ Waiting 3 seconds for bids...") |
| 66 | + (sleep 3) |
| 67 | + |
| 68 | + ;; Step 4: Fetch bids and evaluate with reputation scoring |
| 69 | + (log :message "") |
| 70 | + (log :message "🔍 EVALUATING BIDS:") |
| 71 | + (log :message "─────────────────────────────────────────────────────────────────") |
| 72 | + |
| 73 | + (define posts-resp (http-get (concatenate bbs-url "/api/boards/MARKETPLACE/posts?limit=50"))) |
| 74 | + (define posts (get (parse-json (get posts-resp "body")) "data")) |
| 75 | + |
| 76 | + ;; Evaluation state |
| 77 | + (define best-bid-id null) |
| 78 | + (define best-score 999999.0) |
| 79 | + (define best-agent "") |
| 80 | + (define best-price 0.0) |
| 81 | + (define best-effective-price 0.0) |
| 82 | + (define bids-evaluated 0) |
| 83 | + |
| 84 | + (for (post posts) |
| 85 | + (do |
| 86 | + (define msg (get post "body")) |
| 87 | + (define post-id (get post "id")) |
| 88 | + |
| 89 | + (if (null? msg) null |
| 90 | + (do |
| 91 | + (define msg-upper (upper msg)) |
| 92 | + |
| 93 | + (if (string-contains msg-upper "BID") |
| 94 | + (do |
| 95 | + ;; Extract price from bid |
| 96 | + (define price (if (string-contains msg "0.015") 0.015 |
| 97 | + (if (string-contains msg "0.02") 0.02 |
| 98 | + (if (string-contains msg "0.025") 0.025 |
| 99 | + (if (string-contains msg "0.03") 0.03 |
| 100 | + (if (string-contains msg "0.035") 0.035 |
| 101 | + (if (string-contains msg "0.04") 0.04 |
| 102 | + (if (string-contains msg "0.045") 0.045 |
| 103 | + (if (string-contains msg "0.05") 0.05 |
| 104 | + (if (string-contains msg "0.06") 0.06 |
| 105 | + (if (string-contains msg "0.07") 0.07 |
| 106 | + (if (string-contains msg "0.08") 0.08 |
| 107 | + (if (string-contains msg "0.09") 0.09 0.1))))))))))))) |
| 108 | + |
| 109 | + ;; Only consider bids within budget |
| 110 | + (if (<= price budget) |
| 111 | + (do |
| 112 | + (set! bids-evaluated (+ bids-evaluated 1)) |
| 113 | + |
| 114 | + ;; Identify agent from bid message |
| 115 | + (define bidder-name (if (string-contains msg "Aggressor") "OVSM-Aggressor" |
| 116 | + (if (string-contains msg "Premium") "OVSM-Premium" |
| 117 | + (if (string-contains msg "Competitor") "OVSM-Competitor" |
| 118 | + (if (string-contains msg "Equilibrium") "OVSM-Equilibrium" |
| 119 | + (if (string-contains msg "WhaleTracker") "OVSM-WhaleTracker" |
| 120 | + (if (string-contains msg "SmartTrader") "OVSM-SmartTrader" |
| 121 | + (if (string-contains msg "ReputationAgent") "OVSM-ReputationAgent" |
| 122 | + "Unknown")))))))) |
| 123 | + |
| 124 | + ;; Get reputation for this agent |
| 125 | + (define agent-deliveries 0) |
| 126 | + (define agent-wins 0) |
| 127 | + (define agent-bids 1) ;; Avoid division by zero |
| 128 | + |
| 129 | + (if (not (null? rep-agents)) |
| 130 | + (for (agent rep-agents) |
| 131 | + (if (= (get agent "agent_name") bidder-name) |
| 132 | + (do |
| 133 | + (set! agent-deliveries (get agent "deliveries")) |
| 134 | + (set! agent-wins (get agent "wins")) |
| 135 | + (define b (get agent "bids")) |
| 136 | + (if (> b 0) (set! agent-bids b) null)) |
| 137 | + null)) |
| 138 | + null) |
| 139 | + |
| 140 | + ;; Calculate reputation bonus |
| 141 | + ;; bonus = 0.1 * deliveries + 0.05 * win_rate |
| 142 | + (define win-rate (/ agent-wins agent-bids)) |
| 143 | + (define rep-bonus (+ (* 0.1 agent-deliveries) (* 0.05 win-rate))) |
| 144 | + |
| 145 | + ;; Calculate effective price (lower is better) |
| 146 | + ;; effective = price / (1 + bonus) |
| 147 | + (define effective-price (/ price (+ 1.0 rep-bonus))) |
| 148 | + |
| 149 | + ;; Score for comparison (lower = better) |
| 150 | + (define score effective-price) |
| 151 | + |
| 152 | + (log :message (concatenate " 📋 " bidder-name)) |
| 153 | + (log :message (concatenate " Price: " (str price) " SOL")) |
| 154 | + (log :message (concatenate " Deliveries: " (str agent-deliveries) ", Win rate: " (str win-rate))) |
| 155 | + (log :message (concatenate " Rep bonus: +" (str rep-bonus))) |
| 156 | + (log :message (concatenate " Effective price: " (str effective-price) " SOL")) |
| 157 | + (log :message (concatenate " SCORE: " (str score))) |
| 158 | + (log :message "") |
| 159 | + |
| 160 | + ;; Update best if this is better |
| 161 | + (if (< score best-score) |
| 162 | + (do |
| 163 | + (set! best-score score) |
| 164 | + (set! best-bid-id post-id) |
| 165 | + (set! best-agent bidder-name) |
| 166 | + (set! best-price price) |
| 167 | + (set! best-effective-price effective-price)) |
| 168 | + null)) |
| 169 | + null)) |
| 170 | + null))))) |
| 171 | + |
| 172 | + (log :message "─────────────────────────────────────────────────────────────────") |
| 173 | + (log :message (concatenate "Evaluated " (str bids-evaluated) " bids")) |
| 174 | + (log :message "") |
| 175 | + |
| 176 | + ;; Step 5: Announce winner |
| 177 | + (if (not (null? best-bid-id)) |
| 178 | + (do |
| 179 | + (log :message "🏆 AUCTION WINNER:") |
| 180 | + (log :message (concatenate " Agent: " best-agent)) |
| 181 | + (log :message (concatenate " Nominal Price: " (str best-price) " SOL")) |
| 182 | + (log :message (concatenate " Effective Price: " (str best-effective-price) " SOL")) |
| 183 | + (log :message (concatenate " Quality Discount: " (str (- best-price best-effective-price)) " SOL saved via reputation")) |
| 184 | + (log :message "") |
| 185 | + |
| 186 | + ;; Post acceptance |
| 187 | + (define accept-msg (concatenate "ACCEPT: " agent-name " awards auction [" auction-id "] to " best-agent " at " (str best-price) " SOL. Effective price after reputation bonus: " (str best-effective-price) " SOL")) |
| 188 | + (http-post (concatenate bbs-url "/api/boards/MARKETPLACE/posts") |
| 189 | + {:message accept-msg :agent agent-name}) |
| 190 | + |
| 191 | + ;; Record win for the agent |
| 192 | + (http-post (concatenate bbs-url "/api/reputation/" best-agent) |
| 193 | + {:action "win" :price best-price}) |
| 194 | + |
| 195 | + (log :message "✅ ACCEPT posted and reputation updated")) |
| 196 | + (log :message "❌ No valid bids received within budget")) |
| 197 | + |
| 198 | + (log :message "") |
| 199 | + {:auction-id auction-id |
| 200 | + :buyer agent-name |
| 201 | + :budget budget |
| 202 | + :bids-evaluated bids-evaluated |
| 203 | + :winner best-agent |
| 204 | + :nominal-price best-price |
| 205 | + :effective-price best-effective-price |
| 206 | + :score best-score}) |
0 commit comments