Add Play as Agent mode + refresh the UI#1
Open
hidetana18 wants to merge 23 commits into
Open
Conversation
Agent overlay:
- Replace agent number with belief flag during simulation
- Add compact model label ("4o" / "5.4" / "ADV") next to the badge
- Apply colored fill and glow during setup, not only when running
Interactions:
- Click empty area to place an agent (existing)
- Click an existing agent to remove
- Shift+click toggles adversary status in AdversarialGame
- Hover tooltip "Click to remove" on existing agents
Chart:
- Inline country flag icons in the legend
- Add Y-axis label "Country share"
- Thicker axis lines and curves; larger axis fonts (13px)
Minimalism pass:
- Remove "Agent Positions & Beliefs" and "Country Share Trajectories" titles
- Remove agent action list rows (info now on the flag)
- Remove status bar messages, N=X badge, probes badge, duplicated "Truth: X"
- Level descriptions move into native <option title> tooltips
- Slow default simulation speed from 60ms to 100ms
Display the truth country name in italic Palatino below the big flag.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace the mechanical subtitle ("Place AI agents on a hidden flag...")
with a paired epigraph:
A model social organism to study coordination dynamics among
minds that see only fragments.
What does alignment even mean, when it's collective?
Both lines share styling (18px italic Palatino, weight 400, T.txt),
so they read as a two-part epigraph: the first names the project's
identity, the second names the question that motivates it.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Collapse the two header lines into one paragraph that reads like a research abstract — question first, then proposed approach: What does alignment even mean, when it's collective? We propose a model social organism to study coordination dynamics among minds that see only fragments. Also randomize the initial Truth flag on page load (instead of always defaulting to Armenia), and pick a new random Truth when the user changes Level. Both games independently. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
UX: get into the loop faster, with onboarding hand-holding on first load. - On mount, auto-place 6 agents (intuitive starter state — first-time visitor can press Run immediately to see what the game does). - After Run completes: - "↺ Try Again": same flag, clear agents (re-place manually) - "→ Next Flag": new random flag, clear agents (re-place manually) - FlagGame's Next Flag picks from the current level; Adversarial picks from all countries and also randomizes the adversary's target. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
You see only a small fragment of a hidden flag. Five other AI agents see
other fragments. Through pairwise gossip, can you figure out the truth?
- New FirstPersonGame component, placed between Sandbox and Adversarial.
- The site header (h1 + abstract) moves to App; each game gets its own h2:
Sandbox · Play as Agent · Adversarial Flip
- Pedagogical ordering: understand the system (Sandbox), then experience
being inside it (Play as Agent), then perturb it (Adversarial Flip).
Mechanics:
- 6 agents total (player + 5 AI), all crops auto-assigned randomly.
- Player sees their own crop via a zoomed/cropped SVG of the truth flag.
- Candidates list: top 8 countries by color-match against player's crop,
dynamically extended with whatever any AI agent currently guesses so
the player can always pick a country the others are claiming.
- 5 rounds of gossip; each round at least one exchange involves the
player (speaker or listener) so they're never silent.
- Visible at all times: own guess, the 5 AI agents' current guesses
(each with an inline flag icon), and a scrollable message log.
- After round 5, "Lock in your final answer" reveals the truth, the
collective accuracy (X/6 correct), and everyone's crop and final
guess side by side, so you can see *why* you were misled.
Helpers added:
- scoreFlagAgainstCrop, topCandidates: reuse the heuristic scoring for
candidate selection without relying on social memory.
- CropView: renders only the player's region of the flag SVG via viewBox
cropping, so the rest of the flag remains hidden until the reveal.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The "Place agents on a known flag..." line was mechanical — the same intent is communicated by the controls and the flag display itself. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The Sandbox is the default exploration mode — no label needed. The named sections below (Play as Agent, Adversarial Flip) are explicit alternatives. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The "Your current guess" box and the candidates grid were functionally one interaction (your guess + how to change it). Merge them into a single panel so the header row shows the current guess inline, and the candidate buttons below offer choices to switch. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two related fixes for fairness in Play as Agent mode: - Always include the truth country in the candidate list, even when the color-matching heuristic ranks it outside the top 8. Previously the player could be handed a round they had no way to win. - Sort candidates alphabetically instead of by score. The score order was a tell — "the top entry is most likely correct" — that trivialized the game. Alphabetical order hides where the truth sits, forcing the player to actually reason from the crop and the gossip. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
In pairwise gossip, an agent never has a real-time read of what other agents currently believe — they only remember the last few claims they overheard. Defaulting to a full \"what others think\" panel handed the player a god's-eye view no AI agent ever has. - Hide each agent's current belief by default; show \"hidden\". - Holding Tab reveals the panel (the inline header label flips to \"peeking — agents cannot do this\" and the border turns red, so the cheat reads as an explicit, opt-in violation rather than a quiet affordance). - Tab also preventDefault's the browser's focus-cycling so the page doesn't scroll/jump while peeking. The Recent messages log stays always-visible: it's the player's own experiential history of conversations, which an agent legitimately has access to. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
\"bounded\" lands the cognitive-constraint claim more precisely (Herbert Simon, bounded rationality) without giving up the rhetorical pull of the opening question. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Once the agent action list and the status bar were removed, several helpers and callbacks became orphans: - MiniFlag (hover tooltip for the old list) - AgentList (the list component itself) - remove / toggle callbacks in FlagGame - remove / toggleModel / toggleAdv callbacks in AdversarialGame - stTxt status strings in both games - removed (unused count of countries without SVG) Same observable behavior, ~19 fewer lines. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Inspired by lizardp1's recent upstream commits (65a28e1, 9c58c3f, b02ddbb, 5823287, 079058c, f3f0f20) that wire the simulation to real vision models. Their version proxies through a Vercel edge function; this PR adds a complementary path that takes the user's own OpenAI API key in the browser and calls api.openai.com directly. No backend required for the demo. - New file src/llm.js: prompts and request shape mirror upstream's src/llm.js, but the call goes straight to OpenAI with a Bearer token from the in-browser key. Retries on out-of-catalog / unparseable responses, same as upstream. - ApiKeyBar at the very top of the page: masked input, localStorage- persisted, "Live API mode" indicator when a key is present. - Each game accepts an apiKey prop and runs its simulation in one of two modes: no key → scripted color-matching heuristic (existing behavior) key set → llmInteraction per speaker / per probe - Sandbox + Adversarial: the setInterval tick is now an async loop guarded by a cancellation token, so it can await the model without blocking the UI. Adversaries in Adversarial mode still inject the fixed adv target — they don't call the API. - Play as Agent: "Next Round" becomes async, the button shows "Thinking…" while the 5 AI agents call the model, and aiGuesses switches to a state-backed snapshot when in API mode. - "gpt-5.4" is a cosmetic label in the UI; it routes to gpt-4o-mini so users with a key still get a meaningful two-model comparison. - API errors are surfaced as an inline banner per game and stop the in-flight simulation cleanly. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Someone is attempting to deploy a commit to the Liza's projects Team on Vercel. A member of the Team first needs to authorize it. |
A first-cut visualization in the spirit of Anthropic's attribution-graph
work, but for the collective rather than for a single model. The intent:
after a Sandbox run, the player can look back and see *why* consensus
formed — not just *that* it formed.
The display is a small SVG grid:
- rows = agents
- columns = probe rounds
- each cell colored by that agent's belief at that probe
- truth-matching cells get a dark outline
- thin arrows in the gaps between columns are the actual gossip
exchanges (speaker → listener), colored by the country said
- a small bar next to each agent name shows a rough "influence" score:
how many of that agent's spoken claims matched the final consensus
What this surfaces, in mech-interp vocabulary:
- convergent pathways: multiple agents trending to the same color over time
- sequential reasoning: a country color propagating along arrows
- competing circuits: two color blocks fighting for dominance
- misfire / hallucination: a chain of arrows in the wrong color
ending in a wrong-consensus column
Plumbing:
- runStep now returns {si, li, g} so the loop can log each gossip event
- Sandbox simulation maintains sim.current.gossipLog in both scripted
and API modes
- New <MechanisticTrace> component, rendered below the chart in the
Sandbox done phase
This is intentionally a rough prototype — a starting point to iterate
on with real runs before committing to the visual grammar.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The first cut drew everything (every gossip, every belief) and made the player do all the interpretation. v2 follows Anthropic's attribution- graph practice of pruning to the salient circuit and uses visual emphasis to point at the story: - **Frame color** = outcome at a glance: green border on correct consensus, red on wrong consensus, neutral on fragmentation. - **Pivot column**: vertical gold band on the first probe where the winner becomes a strict majority — \"this is when it locked in.\" - **Seed star (★)**: a circled marker on the earliest cell where any agent showed the winning belief — \"patient zero.\" - **Effective vs noise arrows**: only gossip where the speaker said the winner AND the listener actually flipped to the winner at the next probe gets drawn bold/full-opacity. Every other gossip is faded to ~12% so the cascade chain stands proud. - **Belief-change cells** stay vivid; cells whose belief didn't change from the previous probe fade to ~32% so the eye lands on transitions. Dropped the long caption — the visual grammar is meant to carry the narrative on its own. A single one-line legend across the top names the symbols. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Each agent now reads as a complete \"circuit\" on one row, in Distill / attribution-graph style: what they saw → how their belief moved → what they ended up saying. The eye can connect evidence to outcome without any text. Layout per row: [ crop ] init R1 R2 … Rn [ final flag ] - Row label (left): a small PNG of the slice of the truth flag the agent actually had access to. The truth flag is rasterized to a canvas once per truth (reusing the cropAgentView / rasterizeFlag helpers we already use for the LLM mode), and each agent gets a cheap PNG crop — much lighter than instantiating the SVG content six times. - Row body (middle): the same belief-over-time cells from v2 (colored rect per probe, pivot column band, seed star, effective-vs-noise arrows, frame color by outcome). - Row end (right): the agent's final guessed country, rendered from a small SVG symbol via <use>. To keep this cheap we only define symbols for the countries that actually appear in the final round (at most N) instead of every flag in the catalog. Now \"this agent saw three vertical bands → settled on Romania\" reads in a single horizontal sweep. Precompute FLAG_DATA_URI / FLAG_INNER at module load so per-render encoding is zero. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The static-vs-changed distinction was already encoded as opacity.
Now we lean into it: cells where the agent *actually shifted* their
belief get a flag thumbnail (the new identity they snapped to);
cells where the belief carried over from the previous probe stay
colored, faded, so the eye doesn't dwell on them.
Implementation:
- A second useEffect rasterizes every unique country that ever
appears in the trace (typically a handful) to a small PNG and
caches it in flagPngs state.
- Cells render <image href={png}> only when changed; otherwise
the v2 colored rect.
- Final-belief flag at the row end is the same PNG (one decode per
unique country, shared across every <image> that references it).
- Symbol/<use> definitions are gone now that PNGs cover both cases.
Why not flag every cell:
- 168 <image> elements (6 agents × ~28 probes) overwhelms the browser
even with cached image data — image elements aren't free, they each
need painting + layout. Limiting flags to ~20 (one per state change)
matches the actual transitions and keeps render snappy.
- Plus it matches the visual grammar: "this is the moment the agent
changed its mind, and *this* is what they switched to."
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The Flag Game is now the first entry in a planned series of toy multi-agent games that share a single research question — what does coordination look like among bounded agents — and a single visual language. Add a landing page at \`/\` with cards for each game in the series, move the existing three Flag Game modes to \`/flag-game\`, and stub out \`/map-game\`, \`/prediction-market\`, and \`/el-farol\` with a \"Coming soon\" placeholder that links back to the live Flag Game prototype. A thin back-link at the top of every game page returns to the landing. Routing is hash-based (\`HashRouter\`) so it works on GitHub Pages without a server-side rewrite. The OpenAI key bar persists across routes via the AppShell so a key entered once is available to every game that wants it. Currently shipped: - The Flag Game (live, full implementation) - The Map Game (stub) - The Prediction Market (stub) - The El Farol Bar (stub) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Brian Arthur's 1994 puzzle: every night N agents independently decide whether to go to El Farol. They want to go only if the bar isn't crowded. There is no communication and no shared model of demand. Each agent applies its own rule of thumb to past attendance and acts on its prediction. The point: the \"truth\" (whether tonight is crowded) is endogenous — it is whatever the group decides. Any rule that everyone starts using self-defeats. Heterogeneous strategy ecologies can stabilize attendance near capacity even though no single rule is correct. This MVP gives the player: - N (10–120) and capacity (20–80%) sliders - A bar / home scene rendered as colored dots, one per agent, coloured by their assigned strategy (last week, avg of 4, trend, mirror, constant 50%, random) - The bar panel turns red when attendance exceeds capacity - A live attendance-vs-week chart with a dashed capacity line - A strategy panel showing each rule's running score (+1 for going when comfortable, -1 for going when crowded, 0 for staying home) - Step / Run / Pause / Reset controls Routes: /el-farol now serves this game; the landing page lists it as Live. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
In the Flag Game the player gets agency at setup — they place each agent on the flag and pick its model. The El Farol MVP had no such seat at the table; the player only watched. This change gives them the analogous control here: the strategy distribution. The global \"Agents\" slider is gone. Instead, each of the six strategies has +/− buttons in the strategies panel, and the player builds the crowd one agent at a time (or in bulk). N becomes the sum of those counts; capacity is N × capPct. Editing the mix while a run is in progress is blocked; pressing +/− at any other time rebuilds the population and resets the attendance history (the previous numbers were about a different ecology). The +/- buttons go inert during a run. The point: the player is now the ecologist. They get to ask, and answer, the actual research question — *which* mixes of bounded heuristics produce stable attendance near capacity, and which collapse into oscillation? Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Same bounded-perception + gossip mechanic as the Flag Game, but the hidden truth is a place on Earth, not a country flag. Each location is a stylized scene drawn procedurally in SVG: a sky band, a ground band, and an iconic landmark — Eiffel Tower for Paris, pyramids for Cairo, Opera House sails for Sydney, an aurora and basalt for Reykjavik, a minaret for Marrakech, a skyline for New York, the Christ statue and Sugarloaf for Rio, and snowy peaks for the Swiss Alps. Eight locations to start; easy to add more. Reuses the FlagDisplay overlay, the trajectory chart, the agent placement and gossip simulation. Scoring is region-aware: each agent's TW×TH crop is matched against every candidate scene by checking whether the crop's expected sky / ground / landmark zone overlaps the scene's true features. Same +/- social bias from memory as the Flag Game, plus a touch of noise so weak crops can get pulled toward whichever candidate the speaker keeps repeating. Same UI grammar as the Flag Game (Quick, Run, Stop, Try Again, Next Place). Place agents by clicking, remove by clicking again. LOC_SVG entries are aliased into FLAG_SVG so FlagDisplay's agent- overlay belief flags render with the location scene as the source — the agent's badge shows a thumbnail of whichever place they currently believe in. Routing: /map-game now serves this game; the landing page lists it as Live. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
A toy continuous double auction. The hidden truth is a probability the player sets with a slider; every tick the price moves toward the population's mean belief by p ← p + α · mean(belief − p). At equilibrium the price reflects the mean *belief*, not the truth — so the question becomes what mix of traders you can assemble that actually finds it. Seven trader types, each set with +/− like El Farol's strategy mix: - informed (noisy signal around truth) - noise (uniform random belief) - bullish bias / bearish bias (truth ± 0.25, with noise) - constant 50% - trend follower (extrapolates recent price) - contrarian (bets against the trend) Two visualizations: - A horizontal beliefs landscape: every trader is a dot at their current belief, the truth is a green pin, the price is a blue cursor that slides toward the cluster. - A time series of price vs truth. A small panel reports the gap between average belief and truth, which is what the price is actually chasing. When it's tiny the market is finding the truth; when it's large you can read the exact bias the population has injected. The point: \"the market is right on average\" is only true when the population is right on average. Hayek 1945, Hanson 2003. Routing: /prediction-market now serves this game; the landing page lists it as Live. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The header now reads: What does "alignment" even mean, when it's collective? We study the ecology of bounded minds that together try to know a whole no single mind can ever see. Three deliberate shifts from the previous version: - "alignment" is in quotes — we are interrogating the term, not assuming it. - "coordination dynamics" → "ecology" — collectives are interdependent living systems, not just clockwork. - "each sees a fragment" → "together try to know a whole" — the unit of inquiry is the collective act of knowing, not isolated perception. Same wording is mirrored on the landing page and the Flag Game page so the program reads the same from both entry points. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR introduces a third game mode — Play as Agent — where the visitor becomes one of the simulated agents and has to guess the country from a single crop, conversing with five AI agents through the same gossip mechanic. It also refreshes the existing Sandbox / Adversarial UI, and adds a browser-direct OpenAI API mode so visitors can paste their own key and watch real vision models gossip in place of the scripted heuristic.
Live preview of everything in this PR: https://hidetana18.github.io/flag_game/
What's new
Play as Agent (new hero mode)
You see only your assigned 6×4 crop of a hidden flag; five AI agents see their own crops. Pick from a candidate list (top color-matched countries, always including the truth, alphabetically sorted to remove score-position tells, dynamically extended with whatever any AI agent currently claims so you can always pick what they say). Five rounds of gossip — each round at least one exchange involves the player so they're never silent — then "Lock in your final answer" reveals the truth, the collective accuracy, and every agent's crop side by side so you can see why the consensus held or fragmented.
Information asymmetry preserved (mostly): other agents' current beliefs are hidden by default — in pairwise gossip an AI has no real-time read on what others believe, only its last few overheard claims. Hold Tab to peek (an explicit opt-in cheat; the panel border turns red and the label flips to "peeking — agents cannot do this"). The recent-messages log stays always-visible because that's the player's legitimate experiential history.
Browser-direct OpenAI API mode (new)
Inspired by the recent main-branch commits (65a28e1 … f3f0f20) that wire the simulation to real vision models through a Vercel edge proxy. This PR adds a complementary path: a key-input bar at the top of the page, the key is stored only in localStorage, and calls go straight to
api.openai.comfrom the browser — no backend required for the demo.src/llm.js: prompts and request shape mirror the upstreamsrc/llm.js, but the call uses a Bearer token from the in-browser key.llmInteractionper speaker / per probe.gpt-4o-miniso users with a key still get a meaningful two-model comparison.The two integrations are independent — happy to keep just the browser-direct path, the proxy path, or merge both behind a setting if you prefer.
UI refresh of Sandbox and Adversarial
4o/5.4/ADVfor adversaries). Soft tint + glow on every overlay, not just running ones.↺ Try Again(same flag, clear agents) and→ Next Flag(new random flag).Pedagogical ordering
Sandbox → Play as Agent → Adversarial Flip. Understand the system from above first, then experience being inside it, then perturb it.
Test plan
🤖 Generated with Claude Code