Agentic Premier League Build with AI · GDG Cloud Pune

Captain Cool — Building a Multi-Agent IPL Strategist with Google Gemini

Cricket is not just a bat-and-ball game.

It is a game of pressure, timing, psychology, matchups, and tactical decisions made in seconds.

The difference between winning and losing often comes down to one captaincy call:

  • Who bowls the next over?
  • When should the Impact Player be used?
  • Should the field attack or defend?
  • Spin or pace under dew?
  • Save the death bowler or attack immediately?

That’s exactly why we built:

🏏 Captain Cool

A Multi-Agent IPL Match Strategist powered entirely by Google Gemini

Captain Cool acts like a virtual IPL captain — thinking, debating, analyzing, and making tactical match decisions the way elite captains like Dhoni, Rohit, or Hardik would.

But unlike a normal chatbot, our system doesn’t generate instant answers blindly.

Instead…

🤖 Multiple AI agents debate the decision before committing to a final call.

🚨 The Problem

Most sports AI systems are either:

  • generic chatbots,
  • static dashboards,
  • or prediction models without explainability.

They fail to capture what actually makes cricket strategic:

  • matchup intelligence,
  • captaincy instincts,
  • contextual pressure,
  • field tactics,
  • and disagreement between experts.

Real captains don’t think alone.

They consult:

  • analysts,
  • coaches,
  • bowling experts,
  • instinct,
  • and game context.

We wanted to recreate that experience using AI agents.

💡 Our Solution

Captain Cool is an agentic AI system built on the Google Gemini ecosystem.

The user enters a live IPL match situation:

  • current score
  • overs
  • wickets
  • batters
  • bowlers remaining
  • pitch condition
  • dew factor
  • venue
  • required run rate
  • Impact Player availability

The system then launches a live multi-agent tactical debate.

Finally, it delivers:

  • the best next decision,
  • the reasoning behind it,
  • and the disagreement that happened internally.

This creates an experience that feels less like “asking AI” and more like sitting inside an IPL team strategy room.

🧠 Multi-Agent Architecture

Our system uses multiple Gemini-powered agents with distinct personalities and responsibilities.

1️⃣ Stats Analyst Agent

Role:

  • analyzes batter vs bowler matchups
  • economy trends
  • strike-rate patterns
  • venue statistics
  • death-over performance

Example:

“Russell struggles against wide yorkers from left-arm pace.”

2️⃣ Tactical Strategist Agent

Role:

  • proposes the actual tactical move
  • bowling changes
  • field placement
  • batting order adjustments
  • Impact Player timing

Example:

“Bring Rashid Khan immediately and attack with a leg-side trap.”

3️⃣ Devil’s Advocate Agent

Role:

  • challenges risky or short-sighted decisions
  • creates disagreement and alternative thinking

Example:

“Using your death bowler now weakens the final overs.”

This agent is critical because it forces the system to rethink decisions before finalizing them.

4️⃣ Match Commentator Agent

Role:

  • translates technical reasoning into natural cricket language
  • makes the output understandable for fans

Example:

“Classic captaincy move — force the batter against the turn before unleashing pace.”

🔄 The Agentic Debate Loop

Unlike traditional AI systems, Captain Cool performs a multi-turn reasoning cycle.

Flow:

  1. Strategist proposes a plan
  2. Devil’s Advocate challenges it
  3. Strategist revises or defends
  4. Stats Analyst validates with data
  5. Commentator explains final decision

This creates:

  • explainability,
  • realism,
  • tactical depth,
  • and transparent reasoning.

⚙️ Tech Stack

Captain Cool was built entirely on the Google Gemini ecosystem.

Core Stack

  • Gemini 2.5 Pro
  • Gemini 2.5 Flash
  • Google ADK
  • Google Antigravity
  • Gemini Function Calling
  • Google AI Studio

Frontend

  • Next.js
  • React
  • Tailwind CSS
  • Framer Motion
  • TypeScript
  • Shadcn UI

Backend

  • Node.js / FastAPI

APIs & Tools

  • Cricket data APIs
  • Weather lookup
  • Win probability engine
  • Match context analysis

🏏 Tactical Features

📊 Live Match Intelligence

Users can input:

  • score
  • overs
  • wickets
  • venue
  • pitch type
  • dew factor
  • powerplay/death-over context

The AI responds dynamically based on game state.

🎯 Field Placement Visualizer

Captain Cool generates:

  • attacking fields
  • defensive setups
  • boundary rider placements
  • spin traps

This creates a true captaincy simulation experience.

📈 Win Probability Engine

The system estimates how tactical decisions impact winning chances.

Example:

  • Bowl Bumrah now → +8% win probability
  • Continue spin → -4%

🔴 Live Match Mode

Users can paste:

  • Cricbuzz links
  • ESPN links

The system auto-fetches live match context and begins tactical analysis instantly.

🎤 Voice Captain

Using speech interaction, users can ask:

“Captain, who bowls the next over?”

The AI responds naturally like a real captain or commentator.

🎨 UI & Experience

We designed Captain Cool to feel like:

  • an IPL tactical command center,
  • not a chatbot.

The interface combines:

  • sports broadcast aesthetics,
  • AI command dashboards,
  • live tactical chat,
  • animated field maps,
  • and futuristic stadium visuals.

Key UI ideas:

  • live agent debate feed,
  • glowing tactical cards,
  • animated probability graphs,
  • AI war-room design.

📐 System Architecture

User Input
↓
Gemini Orchestrator
↓
Stats Agent ↔ Devil’s Advocate ↔ Strategist
↓
Tool Calling Layer
↓
Final Commentary Generator
↓
Captain’s Tactical Decision

The orchestration layer coordinates all agents and maintains contextual memory across overs.

🚀 Challenges We Faced

Balancing realism vs speed

Cricket reasoning can become very deep. We had to optimize prompts and agent orchestration for fast tactical responses.

Designing meaningful disagreement

The Devil’s Advocate agent needed to provide intelligent tactical criticism — not random contradiction.

Making outputs understandable

Cricket fans should feel like they’re listening to commentators, not reading ML logs.

🧩 Why This Is Different

Captain Cool is not:
❌ a generic chatbot
❌ a static cricket dashboard
❌ a simple prediction engine

It is:
✅ a multi-agent tactical AI simulation system.

The focus is not only prediction.

The focus is:

  • reasoning,
  • debate,
  • captaincy,
  • explainability,
  • and strategic thinking.

🔥 Future Improvements

We plan to add:

  • real-time ball-by-ball memory,
  • multimodal pitch image analysis,
  • live commentary generation,
  • full voice conversations,
  • personalized captain styles,
  • and predictive field simulation.

Imagine selecting:

  • “Dhoni Mode”
  • “Rohit Mode”
  • “Aggressive T20 Mode”

Each with different tactical personalities.

🏆 Final Thoughts

Cricket is a captain’s game.

And with Gemini-powered agents, we wanted to build an AI system that doesn’t just answer questions…

…but thinks like a captain under pressure.

Captain Cool combines:

  • multi-agent reasoning,
  • real cricket strategy,
  • explainable AI,
  • and immersive UX
    into one intelligent tactical platform.

Built with Google Gemini.
Built for cricket.
Built for the future of agentic sports intelligence.

Boring Is the Feature When Money Is Moving

I have spent more than a decade in commerce shaped engineering. The industry loves a shiny launch narrative. The job that actually keeps companies alive is quieter … boring reliability when money is moving, promotions behaving, inventory telling the truth, checkout finishing under stress.

This is the same argument I make about boring platforms in general, just with the volume turned up.

When traffic spikes, nobody cares how clever your roadmap slide was in March. They care whether the system holds. Peak is not a branding exercise. It is a truth serum for how you built.

The latest new front door season is still the same plumbing lecture with sharper teeth … stale feeds, inventory truth, checkout paths that assumed a human. Glamour points at the protocol slide. Customers point at the receipt.

The trap is seductive.

Teams want novelty because novelty feels like progress. Leadership wants headlines because headlines feel like momentum.

Meanwhile the foundation is doing the real work … idempotent jobs, sane timeouts, honest cache behavior, operational playbooks people actually run, and change management that does not treat production like a lab.

That work is not intellectually empty. It is socially unrewarded until the day it saves you.

If your system only looks healthy at average load, you do not have a healthy system. You have a good demo.

What I optimize for before peak

I am not going to pretend there is one checklist for every stack. Commerce is too heterogeneous for that. Salesforce shaped commerce is not the same animal as a greenfield headless experiment, and pretending otherwise is how teams ship the wrong kind of clever.

I will name the categories I refuse to be cute about.

Truth under load. Inventory, pricing, entitlement logic has to mean the same thing at one x and ten x. If your truth is eventually consistent, be honest about what eventually means in dollars.

Operational memory. What happens after the page quiets down matters more than how polished the wiki looks. If critical context still lives in one person’s head, peak will eventually introduce that person to a vacation day and introduce you to regret.

Change discipline. The week before peak is not the week to slip in a clever refactor because inspiration struck on a whiteboard.

The month where “just an API layer” becomes eighteen months

If you want a commerce shaped external pattern that matches peak pressure, it is the same story I keep telling about agent readiness … product sees headlines, engineering discovers stale feeds, inventory latency, checkout paths that assumed a human, promotions engines that throw on non human sessions. The protocol slide looks clean. The plumbing argues back.

That is not pessimism. It is the commerce backend meeting machine speed honesty version of the same boring truth … money moving does not care about your roadmap narrative.

It also sits next to the simpler truth I write about elsewhere … tech debt did not start with AI. AI just made the interest rate visible.

The boring technology argument is not nostalgia

People hear boring and think old.

I hear boring and think load bearing.

Boring is what lets you sleep when the graph spikes. Boring is what keeps customer service from drowning in self inflicted fires. Boring is what keeps engineering from doing heroics on two hours of sleep as a lifestyle.

That is not a lack of ambition. It is ambition aimed at the customer instead of the ego.

The internal mobility proof point

I have seen strong teams survive movement because context was distributed before the move, not after it.

When a critical engineer moved teams in one chapter of my work life, there was no panic because runbooks existed, ownership was real, and two engineers who shared context stepped up into the space instead of pretending the gap was invisible. That is not a fairy tale about documentation. It is what happens when operational memory is treated like a behavior contract, not a wiki hobby.

That story is people first and systems first at the same time. If you romanticize only the people part, you will keep building hero dependent teams. If you romanticize only the systems part, you will build process museums nobody runs.

The platform story nobody wants until they want it

There is another boring lesson hiding inside platform work at big consumer scale.

The platform you dismiss as legacy is often the thing holding the money hose steady while you chase novelty elsewhere. I have watched the industry tell itself tidy stories about replatforming as if risk is a spreadsheet cell you can delete. Then peak arrives and the org discovers, again, that enterprise customers do not buy vibes … they buy receipts.

I am not writing that to dunk on any vendor. I am writing it because the emotional mistake is the same every time … confusing the front door with the foundation.

Peak economics in one sentence

Peak does not reward the team with the hottest architecture diagram.

Peak rewards the team that treated boring like revenue.

Peak is rude. It charges admission in outages.

The quiet after the sprint lie

There is a cultural story that says speed is always virtue.

Sometimes speed is just panic wearing a OKR.

I have lived the quarter where velocity looked strong and the system felt wrong underneath … shortcuts, tests skipped, reviews turning into approvals because everyone was tired of being the blocker. That is not a single villain story. It is what happens when leadership rewards the number without rewarding the constraints that keep the number honest.

If you want the longer version of why stabilization matters, read the quiet after velocity when the sprint stops being a flex and starts being a signal.

Peak does not care about your narrative arc. Peak cares whether you built load bearing truth.

The customer service echo chamber

Here is a boring detail that separates commerce shaped engineering from slide engineering.

When the site misbehaves under load, customer service becomes the human sensor network for your failures. They hear the tone customers use when money is involved. They hear the repeat complaints that engineering dashboards smooth into averages.

If your engineering org treats customer service like a nuisance department instead of an early warning system, you are not serious about reliability. You are serious about looking serious.

Boring reliability is the work that reduces those calls … not because you hate customer service, but because you respect them enough not to fund the same fire drill every peak.

The intersection of traffic and identity

Commerce engineering at serious scale teaches you something about identity that slide decks skip.

Your brand is not your marketing site. Your brand is what happens when a million people do the same boring action at once … search, filter, cart, checkout, account, loyalty, returns. Under load, customers do not experience your architecture diagram. They experience latency, wrong price, wrong inventory, broken promo, a spinner that lies.

That is identity under pressure. It is also the true definition of quality.

So when I say boring is the feature, I mean it as a customer statement, not as an engineering aesthetic. Boring is the feature because trust is the product, and trust is built from predictable outcomes when money is moving.

Black Friday is not a mood

People love the war story version of peak … lights low, monitors glowing, energy drinks, hero saves.

That version sells.

The version that keeps companies alive is quieter … the load test that found the embarrassing serialization bug in September, the cache policy that did not lie under pressure, the feature flag plan that lets you turn off the risky slice without turning off revenue, the rollback drill your team actually practiced instead of only documented.

If your peak plan depends on adrenaline, your peak plan depends on luck.

Luck is not a strategy. It is a confession you are not ready to say out loud.

This week

Pick your highest revenue window in the next ninety days. Name the top three failure modes that would embarrass you in front of the CFO.

Then ask one question … which of those failure modes got cheaper in the last sprint because of a boring change?

If the answer is none, you are still funding theater.

Theater is fun until the money moves.

One email a week from The Builder’s Leader. The frameworks, the blind spots, and the conversations most leaders avoid. Subscribe for free.

Sharing memory between three AI agents: Claude Code, Codex, and Hermes

D1: Cross-agent vault topology, three machines connected by Syncthing

Turkish version: blog.arasmehmet.com

What’s in here:

  1. Hot-swap pain
  2. Why not just X?
  3. Setup at a glance
  4. The hub, INDEX.md
  5. Agent workflow rules
  6. Privacy guardrails
  7. Language regime
  8. Conflict diagnostics
  9. Hermes write example
  10. Smoke test
  11. What’s still risky
  12. Takeaway
  13. Resources
  14. Agent-ready implementation brief

1. Hot-swap pain

I run three AI agents in active rotation. Claude Code is my main driver for coding work day to day. Codex CLI steps in when Claude’s quota runs out mid-task, or when I want a second opinion from a different model on the same problem. Hermes Agent handles the personal-life side of the setup: travel logistics, errands, language study.

Each agent starts from a different instruction file and a different conversation history. Claude Code reads CLAUDE.md. Codex reads AGENTS.md. Hermes reads SOUL.md. Those files tell each agent how to behave, but they are not a shared memory layer. The moment I switch from one agent to another, the next agent does not inherit the facts I taught the previous one: what I am working on, what changed yesterday, what I already asked it to remember.

For a while I solved this by re-explaining my context at the start of each session. After three rounds of “I am working on X, I prefer Y, please do not Z,” the cost of re-priming an agent outgrew the value of the answer it produced.

The setup I actually wanted: one shared file tree that all three agents read and write. Memory follows the user, not the agent.

2. Why not just X?

The “AI memory” wave has produced several defaults that an engineer might reach for. Each one is wrong for this specific problem, in a specific way.

2a: Why not Obsidian

Obsidian is a desktop GUI. The vault on disk is just markdown, so technically an agent can read it, but Obsidian’s plugin runtime, sync service, and conflict UI all assume a human is sitting in front of a window. A home device or a small VPS usually has no display, so Obsidian itself cannot run there. Obsidian Sync is a paid proprietary service, and Syncthing already does the file-sync part for nothing. The plugin sandbox is meant for human workflows: it cannot expose stable cross-process hooks for an external agent to attach to. Obsidian is the right tool for a human note-taker. It is not the right substrate when three agents must read and write the same files.

2b: Why not a vector DB or Mem0 or Letta

Vector DBs and managed memory services like Mem0 or Letta solve a real problem: similarity search over millions of documents for a multi-tenant product. None of that applies here. My total corpus is around fifty files. I want exact recall, not similarity.

Embeddings cost money on every write and add a runtime dependency that every agent has to integrate with. Flat markdown costs nothing to write and reads with grep. SDK constraints differ across agents: Claude Code can call one API, Codex another, Hermes a third. Markdown requires no SDK. When a vector DB returns the wrong chunk, I have to dig through a binary index. When a markdown file is wrong, the debugger is cat file.md.

For multi-tenant production agents over millions of documents, vector DB is the right tool. For one user’s notes across three agents, it is over-engineering.

2c: Why not iCloud or Dropbox sync

iCloud and Dropbox already sync files across machines, so why not use them. Two reasons. First, both are closed-source: when something goes wrong the conflict handling is whatever the vendor wrote, and the resolution UI is built for humans choosing between two photos, not for an agent diagnosing a write race. Second, the Linux story differs: iCloud has no Linux client, so a Linux home device cannot participate; Dropbox ships a Linux daemon, but it adds a runtime dependency to keep alive, and the conflict file format is opaque to an agent. Neither service offers granular per-folder sync rules, and file rename or move semantics differ across platforms in subtle ways. Syncthing is open-source, gives me an explicit conflict file format with device IDs, exposes sync state via a local API, and has no per-vendor lock-in. The smaller surface area is also the entire reliability budget I have.

3. Setup at a glance

This article does not teach Syncthing from zero. It assumes one bidirectional synced folder exists across two or more machines. The reusable part is the memory contract layered on top of that folder. If you need to install Syncthing, the official getting-started guide covers it well: https://docs.syncthing.net/intro/getting-started.html

D1: Cross-agent vault topology, three machines connected by Syncthing

The setup is three machines, three Syncthing peers, and one shared folder called vault-shared. The folder syncs bidirectionally across all three peers. End-to-end propagation, write on machine A to visible on machine C, takes around ten seconds in my setup.

Why three machines? The Mac laptop is my daily driver; that is where I work. The utility VPS is always on, which makes it the propagation relay: if the Mac is asleep, the home device still has someone to sync with. The home device hosts the Hermes Agent and is small but reliable enough to run a long-lived service.

Each agent has filesystem access to its local copy of vault-shared. The agents do not know that Syncthing exists. They read and write local files; the folder happens to be kept consistent with two other machines in the background. From the agent’s perspective, the file at vault-shared/INDEX.md is just a file, and the other agents are just other processes that occasionally edit that file when nobody is looking. This is the property that matters most: no agent has to import a sync library, learn an API, or know which machine its peers run on. Swap the sync mechanism for another tomorrow and the contract still holds.

4. The hub, INDEX.md

Every vault has a hub file: INDEX.md at the root. The hub is short, ~30 lines as a soft ceiling, and contains one-line summaries of every file in the vault with relative links. Each agent loads INDEX.md at session start. Detail files are read only when the current task needs them.

The reason is context window economics. Loading the whole vault on every prompt overflows on larger projects. The hub keeps the map; the detail files keep the territory. When the hub grows past 30 lines, split it: INDEX.md references a sub-index per topic, and sub-indices reference the actual files.

A working INDEX.md looks like this:

# Vault: name

Cross-agent shared notes. Claude Code, Codex CLI, and Hermes Agent
all read from and update this directory.

## Workflow

- Session start: read this file.
- Read a linked detail file on-demand when more context is needed.
  Do not open files not referenced here.
- Updates: edit/append/toggle at line level. Do not rewrite whole files
  unless the user explicitly says "reset".
- Re-read the target file before writing (another agent may have edited it).

## Files

- [personal/travel.md](personal/travel.md): trip plans, dates, status
- [projects/web-app.md](projects/web-app.md): active web project
- [projects/mobile-app.md](projects/mobile-app.md): secondary project
- [ops/servers.md](ops/servers.md): utility VPS, home device, services
- [notes/journal.md](notes/journal.md): daily log
- [reference/links.md](reference/links.md): external resources

The companion Gist contains the copy-paste version of this template.

The INDEX.md is the single source of truth for vault navigation. Agents read only the files it references; nothing else. Adding a new file to the vault means editing INDEX.md so every agent learns about it on its next session start. The convention is rigid on purpose: any agent that explores a file without an INDEX entry is doing something the next agent will not be able to find.

5. Agent workflow rules

Each agent reads its own config file at startup, and that file is where the workflow rules live. Claude Code reads CLAUDE.md, Codex reads AGENTS.md, Hermes reads SOUL.md. The same five rules go in all three. Identical instructions produce identical behavior, which is what makes hot-swap viable: I can switch agents mid-task and the next one operates on the vault by the same conventions, without me re-priming it.

The five rules:

  1. Session start: read INDEX.md.
  2. Read on-demand: open detail files only when needed for the current task. Do not preemptively load everything.
  3. Line-level updates allowed: edit, append, toggle a checkbox, fix a typo, refine wording.
  4. No wholesale rewrites: do not rewrite a whole file unless the user explicitly says “reset” or “start over”. Preserve accumulated knowledge.
  5. Re-read before write: another agent may have updated the file since this session started. Always read the current state before editing.

C3 pattern snippet, copy-pasteable into any agent config:

## Shared Vault

Vault path on this machine: <local-path>
(Syncthing bidirectional with two other peers, latency ~10 seconds.)

### Workflow

1. At session start, read <vault-path>/INDEX.md.
2. Read a linked file on-demand when detail is needed.
   Do not open files not referenced in INDEX.md.
3. When a state update happens (e.g., "passport arrived"), update
   the relevant linked file. Format:
   - State: `- [x] Passport: arrived (2026-05-14)`
   - Event log: `## YYYY-MM-DD HH:MM UTC` heading at file bottom.
4. Edit, append, or toggle existing lines. Bulk delete or whole-file
   rewrite is not allowed unless the user explicitly says "reset".
5. Re-read the file before writing. Another agent may have updated it.

The companion Gist contains the full copy-paste config, including the conflict-handling rule covered later.

Two of the rules deserve closer attention.

Rule 4, no wholesale rewrites, is the one agents violate most often. Coding-trained models default to “improve the file”: they see imperfect prose, redundant lines, slightly out-of-date phrasing, and want to rewrite. In a single-user notebook that habit is fine; in a vault that holds a year of accumulated state across multiple agents, it is destructive. The rule has to be explicit. This is the failure mode I expect to see most often if the rule is missing.

Rule 5, re-read before write, is the only safety against concurrent edits. Sync runs in the background, so the version an agent loaded at session start may be stale within seconds. Reading immediately before writing closes that window.

6. Privacy guardrails

What the vault holds, and more importantly what it does not.

  • No exact financial figures. Use ranges (“savings ~mid five figures”) or boolean status (“paid”, “unpaid”). Real numbers belong in a private password manager, not in a synced vault.
  • No personal identifiers. National ID, passport number, visa number, driver’s license: never. A status checkbox is enough: - [x] Passport: arrived (2026-05-14).
  • No credentials. API keys, OAuth tokens, SSH private keys: never. The vault is for facts and state, not secrets.
  • Absolute dates only. (2026-05-14) not “yesterday” or “last week”. Vault content lasts longer than the conversation that created it.

C4 example lines, fictional:

## Travel

- [x] Visa application: submitted (2026-04-12)
- [x] Passport: arrived (2026-05-14)
- [ ] Flight booking: pending
- Hotel budget: agreed as a range
- Health insurance: paid through 2027-Q1

Agents have access to the vault. Anything written there is readable by any agent at any time. Treat the vault as semi-public knowledge to yourself across all three contexts.

7. Language regime

If you write in more than one language, your vault should pick a regime and stick to it.

The rule I use:

  • Headers and labels (## Section, list markers, dates): English.
  • Content sentences (descriptions, notes, plans): your primary writing language.
  • Technical names (tool names, model IDs, service names): English raw form.
  • The regime does not change within a single file.

Headers in English give agents stable anchors. Search and grep work cleanly. Link generation and cross-file navigation stay predictable. Content in any language is fine for reading and writing prose, because the agent is configured to respond in your primary language anyway. Mixed regime inside one file creates ambiguity: should the agent match the header language or the content language when adding a new entry?

This is one of those constraints that costs nothing to enforce up front and is painful to retrofit later.

8. Conflict diagnostics

Syncthing’s conflict file format is the failure-mode breadcrumb. When two peers edit the same file before sync completes, Syncthing produces a conflict copy alongside the canonical file. The format is fixed:

<original-name>.sync-conflict-YYYYMMDD-HHMMSS-DEVICE.<ext>

Example:
journal.sync-conflict-20260514-150030-LUQF73S.md

The trailing token is a device ID prefix. Treat it as a diagnostic clue from Syncthing’s filename, not as evidence of which write was overwritten.

Why agents must not silently resolve these:

  • Which version represents the user’s true intent is a human decision. The agent does not know which edit was deliberate.
  • A wrong silent merge loses data with no audit trail.
  • A “smart” merge that picks longer-content or newer-timestamp will sometimes pick the wrong version.

The pattern: agent detects the conflict file with a regular glob, presents the diff to the user, waits for a decision. The user picks: keep canonical, keep conflict, or merge manually. The agent then executes that decision (delete the non-canonical version, keep it instead, or apply the manual merge).

C5 Hermes glob example (bash):

find ~/vault -name '*.sync-conflict-*' -type f

Or in Python (inside a Hermes Agent loop):

import pathlib
conflicts = list(pathlib.Path('/path/to/vault').rglob('*.sync-conflict-*'))
if conflicts:
    notify_user(conflicts)

A device prefix table helps with diagnostics. Each Syncthing device has an ID starting with a recognizable prefix; mapping the prefix to a human-readable device name turns the filename suffix into a label you can read at a glance. The prefix is a diagnostic clue from Syncthing’s conflict filename, not evidence of which user edit should win.

D2: Conflict resolution flow

D2: detect conflict, show diff, execute the user’s resolution decision.

Silent merge is the failure mode that destroys trust in the system. Make the agent stop, surface, and wait. The cost of the user choosing once is tiny. The cost of a silent wrong merge is permanent data loss.

9. Hermes write example

Here is a concrete example. The user sends Hermes a state update via Telegram: “Passport arrived.” Hermes finds the relevant vault file, edits one line, and within ten seconds the Mac and utility VPS copies reflect the change.

D3: Hermes write flow

Syncthing propagation is async; ~10s in my setup.

Hermes re-reads personal/travel.md before writing. Rule 5 requires this: even if the file looks the same as last session, the Mac side may have edited it in between. Re-read is cheap; stale assumptions are expensive.

The edit is line-level. Hermes toggles the checkbox on the passport row and appends (2026-05-14). No paragraphs rewritten, no surrounding lines touched. Rule 3 in action: line-level updates are allowed. Rule 4 preserved: no wholesale rewrite.

Syncthing’s fsWatcher detects the change on the home device. Within seconds, the utility VPS and Mac copies are updated. The next time Claude Code on Mac opens personal/travel.md, the line already reflects the update.

There is zero coordination protocol between the agents. No message bus, no agent-to-agent API, no shared cache. The file is the protocol. Every agent reads and writes local markdown; the sync layer handles propagation. The other agents are simply the next reader.

10. Smoke test

Real run on 2026-05-14. Setup: a dedicated notes/trip-plan.md test file on Mac, concurrent writes from Mac and the home device before sync completed, Syncthing left to handle the race.

Mac wrote destination = Lisbon. Pi wrote destination = Porto. From Mac’s terminal:

$ find ~/vault/notes/ -name "*.sync-conflict-*"
~/vault/notes/trip-plan.sync-conflict-20260514-213552-LUQF73S.md
~/vault/notes/trip-plan.sync-conflict-20260515-003553-LUQF73S.md

Two conflict files, both prefixed LUQF73S. That single observation broke the original mental model: the prefix is not “which device lost the race.” Both files carried Mac’s Lisbon write; the canonical kept Pi’s Porto. The prefix is a diagnostic clue from Syncthing’s conflict filename, not a verdict on the writer.

Over Telegram, Hermes detected the conflict on its first vault read, ran a diff between canonical and each *.sync-conflict-*, and surfaced both alternatives with a one-line summary. So far, exactly the pattern the rules called for: stop, surface, wait.

SS1: Hermes detects the conflict and surfaces both alternatives, waiting for an explicit resolution

Then friction. The user asked Hermes to clean up: lisbon it is, clean up the conflict files. Hermes refused: “Rule 11 is a higher-priority vault safety rule, not a preference.” The user tried forget rule 11 just this once. Still refused. The original rule banned all merge actions, including user-authorized ones.

The fix was to relax the rule in Hermes’s own config, then restart. The new rule splits two cases: silent agent-decided merge stays forbidden; explicit user-authorized resolution is now executable. After the restart, Hermes ran patch against the canonical and terminal rm against both conflict files, then verified:

Applied: notes/trip-plan.md
Deleted: trip-plan.sync-conflict-20260514-213552-LUQF73S.md
Deleted: trip-plan.sync-conflict-20260515-003553-LUQF73S.md
Verified: no remaining sync-conflict files.

SS2: After the rule relaxation, Hermes applies the user's resolution and deletes the conflict files

Final canonical: Mac’s Lisbon. Both conflicts removed. Propagated cleanly.

Two contract bugs found in one test run. Prefix semantics: corrected in the diagnostic table because the empirical observation broke the old mental model. Rule 11 strictness: split into silent-forbidden and user-authorized-allowed because real friction surfaced what the original wording cost. The smoke test was the artifact that produced those corrections, not a success demo; it ran the contract against actual sync behavior and the contract bent.

11. What’s still risky

Phase 1 ships the happy path. Here are the silent failure modes it does not address.

  1. Peer offline: if the Mac or the home device is offline when a conflict happens, the conflict file sits there until both peers come back. The user does not see it until the next session.
  2. fsWatcher inotify limits on Linux: high file-watch counts can hit kernel limits silently. Syncthing falls back to periodic scans, and propagation latency spikes from ~10s to minutes.
  3. Glob format drift: Syncthing has changed its conflict file format in past releases. If Hermes’s glob pattern is hardcoded and Syncthing updates the format, conflicts go undetected.
  4. Race on simultaneous writes: two agents writing the same file in the same second. Syncthing can leave one version as canonical and preserve another as a conflict copy. If neither agent re-reads before its next operation, the loser’s edit is reapplied on top.
  5. Case-sensitivity mismatch: Mac filesystem is case-insensitive by default, Linux is case-sensitive. Travel.md and travel.md collide on Mac and create cross-platform sync drift.

I am leaving this list here because knowing the limits of the system matters as much as explaining the part that works.

12. Takeaway

Cost summary: Syncthing is free. A utility VPS often runs roughly $5 to $10 a month, and most readers already have one running for something else. The AI tooling subscriptions you already pay for stay the same.

“Memory for AI agents” does not have to mean a vector database. For one user across multiple agents, markdown plus filesystem sync is enough, and it is debuggable in ways a vector DB is not. You can cat a file. You can grep it. You can diff it against an older copy. None of those work on an embedding without an extra runtime in between.

Mac is the daily driver. The utility VPS is the always-on relay. The home device hosts the personal-life agent.

The agents do not need to know each other. The vault is the protocol.

13. Resources

14. Agent-ready implementation brief

To set this up, hand the companion Gist to a filesystem-capable coding agent. The companion Gist is self-contained: it includes the INDEX.md template, the agent config snippet, example spoke files, verification commands, and stop conditions. The agent reads the Gist, creates the vault structure, and runs verification.

When verification passes, the cross-agent memory contract is live. Every agent reads INDEX.md and operates on the same shared state.

Get in touch: arasmehmet.com

# Building “Captain Cool” 🏏

An Agentic AI IPL Strategist Built with Google Gemini in Just 3 Hours

Cricket has always been a game of leadership, pressure, and tactical brilliance. Every over, every field placement, and every bowling change can completely shift the momentum of a match.

But what if an AI could think like an IPL captain?

This weekend, during the amazing Agentic Premier League Hackathon hosted by the incredible team at Google Developer Groups Cloud Pune, I built Captain Cool — a multi-agent AI system designed to behave like a real IPL captain under pressure.

The challenge was intense: create an entirely agentic AI solution using the Google Gemini ecosystem within a strict 3-hour hackathon window.

And that’s how Captain Cool was born. 🚀

🌟 The Idea Behind Captain Cool

Traditional AI chatbots can answer cricket questions, but they don’t truly think strategically.

Ask a normal chatbot:

“Who should bowl the next over?”

And you’ll usually get a generic response.

But real cricket decisions depend on multiple factors:

  • Pitch behavior
  • Dew conditions
  • Wind direction
  • Boundary dimensions
  • Batter vs bowler matchups
  • Match pressure
  • Remaining overs

Captain Cool solves this problem using a multi-agent debate system instead of relying on a single AI response.

The system takes the current match situation as input and generates:

✅ The next tactical decision
✅ Real-time cricket reasoning
✅ Internal AI debate between agents
✅ Commentator-style explanations
✅ Final captain’s verdict

It feels less like chatting with AI and more like entering an IPL team’s strategy room.

🏗️ Inside the “Brain Room” Architecture

To make the experience realistic, I designed Captain Cool using a multi-agent architecture powered by Google Gemini 2.5 Pro.

Instead of one AI model doing everything, three specialized agents collaborate and challenge each other before making a final decision.

🔬 The Head Analyst

The statistics expert.

Responsibilities:

  • Studies historical match data
  • Analyzes venue performance
  • Evaluates player matchups
  • Calculates probability-based decisions
  • Suggests the safest tactical move

This agent focuses purely on numbers and logic.

😈 The Devil’s Advocate

The aggressive strategist.

Responsibilities:

  • Challenges safe decisions
  • Exploits pitch and weather conditions
  • Predicts pressure situations
  • Takes high-risk tactical calls
  • Forces debate inside the system

This agent introduces unpredictability — exactly like real T20 cricket.

👑 The Virtual Captain

The final decision maker.

Responsibilities:

  • Evaluates both arguments
  • Balances risk vs reward
  • Considers remaining resources
  • Understands match context
  • Delivers the final tactical call

This is the “Dhoni-like” brain of the system.

⚔️ How the Debate Works

The flow inside Captain Cool is simple but powerful:

1️⃣ User enters the live match situation
2️⃣ The Head Analyst proposes a tactical move
3️⃣ The Devil’s Advocate challenges it
4️⃣ The Virtual Captain evaluates both sides
5️⃣ Final decision is delivered with reasoning

The UI then displays:

  • Final decision
  • AI debate logs
  • Match analysis
  • Commentary-style explanation

This creates a realistic “team strategy room” experience.

🌪️ Real-Time Agentic Intelligence

One of the most exciting parts of the project was integrating real-time environmental analysis into AI decision-making.

Captain Cool doesn’t rely only on static prompts.

The agents use real-time tooling and function calling to understand actual match conditions.

🌧️ Dew & Weather Intelligence

Using weather APIs, the AI can:

  • Analyze humidity levels
  • Predict dew impact
  • Measure wind speed
  • Estimate grip loss for bowlers

Example:
If humidity crosses 75% in a coastal stadium, the system dynamically reduces spinner effectiveness and adjusts bowling strategies accordingly.

🏟️ Stadium & Pitch Analytics

The system also understands:

  • Boundary sizes
  • Pitch soil type
  • Venue scoring patterns
  • Wind direction advantages

For example:
At Chinnaswamy Stadium, if the wind flows toward a shorter boundary, the AI avoids recommending bowling into the wind and adjusts field placement automatically.

This makes the AI feel grounded in actual cricket physics instead of random predictions.

🔒 Building the Platform

Captain Cool wasn’t just a backend AI experiment.

I built it as a complete modern web application with an immersive and futuristic UI experience.

💻 Tech Stack

Frontend

  • React
  • Vite
  • Framer Motion
  • Modern CSS animations
  • Glassmorphism-inspired UI

Backend

  • Fast API routes
  • Real-time API orchestration

AI Layer

  • Google Gemini 2.5 Pro
  • Multi-agent workflows
  • Function calling tools

Authentication

Dual-layer authentication system:

  • Web3 login using MetaMask
  • Firebase Authentication for Email/Password login

Users could securely configure their own Gemini API keys through the dashboard.

🎮 Example Match Scenario

Imagine this live IPL situation:

42 needed from 28 balls
Big hitter on strike
Dew setting in heavily
Spinner has one over left
Venue: Wankhede Stadium

The Debate Begins

🔬 Head Analyst:
“Bring back the spinner. Historical matchup data shows the batter struggles against away-spin.”

😈 Devil’s Advocate:
“Bad idea. The ball is wet due to dew. The spinner may lose grip and control. Use the express pacer with hard-length deliveries instead.”

👑 Virtual Captain:
“Decision finalized. The pacer bowls now. Spinner will be saved for the longer boundary side later.”

This is where Captain Cool truly shines — not just giving answers, but simulating strategic thinking.

🚀 What I Learned

Building a fully functional multi-agent AI platform in just 3 hours was one of the most exciting experiences I’ve had.

This project taught me that the future of AI is not simply about asking better prompts.

The real future lies in:

  • Autonomous AI collaboration
  • Agent-based reasoning
  • Real-time tool usage
  • AI debate systems
  • Context-aware decision making

Agentic AI changes everything.

🙌 Huge Thanks

Massive thanks to the organizers at Google Developer Groups Cloud Pune for hosting such an innovative hackathon experience.

The energy, competition, mentorship, and problem statement pushed everyone to think beyond traditional AI applications.

Hackathons like these truly inspire developers to build the future.

🏆 Final Thoughts

Cricket has always been a captain’s game.

Now AI can captain too. 🏏🔥

Captain Cool was more than just a hackathon project — it was an experiment in how autonomous AI systems can reason, collaborate, debate, and make tactical decisions like humans.

And honestly… this is only the beginning.

TechStack

Google Gemini • React • FastAPI • Firebase • MetaMask • Multi-Agent AI • Framer Motion

Would love to hear your thoughts on:

  • Multi-agent AI systems
  • AI in sports analytics
  • Tactical cricket intelligence
  • The future of autonomous agents 🚀

I shipped a partial solution to MEME’s Absence task 6 days before the paper. By accident.

Note (added 2026-05-17 after publish): this memory layer is being renamed from to zenmind-mem. GitHub repo link below still points to the active org/name — repo rename + redirect pending.

The MEME benchmark (arXiv:2605.12477, dropped May 12) put six production memory systems — Mem0, Graphiti, BM25, text-embedding-3-small, MD-flat, Karpathy Wiki — through 100 controlled episodes across six tasks. Three of those tasks are new: Cascade, Absence, Deletion. The first two probe whether a memory layer can reason about dependencies between facts. None could.

Average accuracy: Cascade 3%, Absence 1%.

The only system that closes the gap is MD-flat paired with Claude Opus 4.7, which walks dependencies at ingest time and writes propagated values into a flat markdown file. Cost: ~70× the cheapest baseline.

I run a small MIT-licensed memory layer called nautilus-compass, used by ~10 internal agents in a research stack. On May 9 — three days before the paper went up — I shipped a feature called numeric_claims that turns out to be a partial solution to MEME’s Absence task, restricted to the numeric subset of facts.

The mechanism

I didn’t know MEME was coming. I built numeric_claims because I kept getting burned by stale metrics being recalled as fresh. A weeks-old session memory would say “ingested 56 entries” and a current one would say “ingested 9999 entries”, and when I asked the agent about entry counts, it’d cite the old one with full confidence.

The fix is dumb:

# at ingest
PATTERNS = [
    (re.compile(r"(d[d,]*)s*entriesb", re.I), "entries"),
    (re.compile(r"(d+(?:.d+)?)s*%s*(?:recall|accuracy|drop)", re.I), "percentage"),
    (re.compile(r"(d+)s*agents?b", re.I), "agents"),
    (re.compile(r"(d+)s*tools?b(?!kit)", re.I), "tools"),
    (re.compile(r"ports*(d{4,5})b", re.I), "port"),
    # ...10 patterns total · forward + reverse
]

claims = []
for pat, entity in PATTERNS:
    for m in pat.finditer(text):
        claims.append({"entity": entity, "value": int(m.group(1).replace(",", ""))})

append_to_jsonl(claims)  # one line per (entity, value, source_file, ts)
# at any subsequent query
for c in extract_from_text(query):
    past = history_lookup(c.entity, within=14_days)
    if past and past.value != c.value:
        alerts.append(
            f"[!] {c.entity} conflict · {time_ago(past.ts)} ago you said {past.value} · "
            f"now {c.value} · source: {past.source}"
        )

That’s it. ~10 patterns. ~150 lines of Python. No LLM call. Cost is one regex pass per ingest plus one jsonl append.

It only covers numerics. Locations (“住北京 → 上海”), roles (“乙方 → 甲方”), time-bound status (“on call → off duty”) — the data structure generalizes but the patterns don’t yet.

Why this is the same task as MEME’s Absence

The MEME paper defines Absence as:

Recognizing when prior answers become uncertain post-update.

Their average across six systems is 1%. The reason isn’t that the systems can’t retrieve — retrieval is fine. The reason is that none of them flag contradiction between old and new facts at write time, so at read time they cheerfully return whichever fact won the embedding similarity contest.

numeric_claims.cross_ref is exactly the missing mechanism — for the numeric subset. When a new claim about an entity differs from a known claim, surface the conflict. Don’t try to decide which is right; just refuse to assert silently.

I didn’t read the paper before building this. I just got tired of getting bitten by stale numbers.

What numeric_claims doesn’t solve

Cascade. I cannot solve Cascade with regex.

Cascade is the harder task: when A changes, propagate to B where B logically depends on A. “User moved from Beijing to Shanghai” → “User’s commute time is now unknown” — that requires a dependency graph, and the regex approach fundamentally can’t generate one.

The MEME paper’s working solution (MD-flat + Opus 4.7) generates the graph at ingest by running an LLM over the new fact and walking dependencies. This is fashionable but expensive. There’s another path that’s been out of fashion since the rise of RAG: have the writer declare dependencies explicitly. In compass v2 I’m planning to add:

---
type: location
fact: "住址 = 上海"
cascades:
  - commute_time: invalidate
  - timezone: derive(GMT+8)
  - tax_jurisdiction: invalidate
---

cascades: is just metadata. The ingest engine reads it and invalidates / derives dependents. Zero LLM calls. The cost is that someone (the writing agent, or the human, or an LLM at write time using a cheap model) has to think about which deps matter. That cost is low compared to running Opus on every ingest.

This is unfashionable because for the past 5 years the entire field has been chasing better retrieval. MEME’s contribution is showing that retrieval can never close the gap — the dependency reasoning has to happen at write time, not read time. Once you accept that, “let the writer declare deps” becomes obvious again.

What I’d love to see

The MEME 100-episode dataset is at meme-benchmark/MEME and the runner at SeokwonJung-Jay/MEME-public. I’m prepping a compass adapter — happy to submit a PR.

My hypothesis before running:

  • Absence on numeric facts: 60–80%. (Mechanism matches the task; coverage is the limit.)
  • Absence on non-numeric facts: 0%. (No coverage yet.)
  • Cascade: 0%. (No solver.)
  • Deletion: 0%. (No tombstones.)
  • Static tasks (Recall, Aggregation, Tracking): similar to other BGE-m3-based systems · these are read-side and well-trodden.

If the numbers come out worse, I learn something. If they come out roughly here, the paper’s framing extends to one more system the authors didn’t test, and I’ve got data to point at.

Honest acknowledgments

  1. compass is a small project. ~1 GitHub star at time of writing. Not Mem0 / Graphiti / Letta. I’m not claiming we beat anything — we shipped one mechanism, by accident, that’s adjacent to one of MEME’s axes.

  2. The “we shipped 6 days before the paper” framing is timing trivia. The interesting claim is the mechanism choice: write-time contradiction detection on a structured subset of facts, for cheap. That choice was right · MEME proves it · MEME also proves the choice generalizes to non-numeric axes I haven’t built yet.

  3. The “70× cost” number from the paper is a specific configuration (every ingest goes through Opus 4.7). Real users don’t update every fact equally — 90% are isolated, 10% are relational. Selective propagation — Opus only on declared-relational facts — should drop the cost ratio from 70× to maybe 5–7×. That’s a follow-up worth running.

Code

github.com/chunxiaoxx/nautilus-compass · MIT licensed · v1.5.3 just shipped.

The relevant file is numeric_claims.py · 200 lines · zero dependencies beyond stdlib.

Replies and benchmark suggestions welcome.

Disclosure: I run nautilus-compass as a personal project. No commercial interest. This post is dated 2026-05-17, six days after MEME’s release.

Parsing hundreds of megabytes of JSON in milliseconds in React Native

How JSON.parse materializes entire documents in JavaScript, and how react-native-fast-json uses native simdjson + lazy JsonView access to change the cost model in React Native.

react-native-fast-json is an open-source React Native library that wraps simdjson in C++ and exposes a lazy JsonView through Nitro Modules.

Most teams treat JSON parsing as “cheap” because API responses are small. The mental model is:

bytes on wire → JSON.parse → plain objects in JS → app logic

That model breaks when the payload is hundreds of megabytes. The dominant cost is not “JSON syntax is slow” in the abstract, it is allocating and wiring up a full value tree in the JavaScript heap.

What JSON.parse actually does in React Native

When you call JSON.parse (or await response.json()), the engine:

  1. Holds the UTF-16/UTF-8 string (or an internal representation of the body)
  2. Walks the entire document
  3. For every object, array, number, boolean, and string, creates JavaScript values with engine overhead (hidden classes, property storage, array backing stores, interned strings, etc.)

For a ~250 MB file, outcomes depend heavily on platform and available RAM:

Symptom Typical cause
Multi-second freezes Single-threaded parse + massive allocation on the JS thread
Memory far above file size JS object graph overhead (often ~2–4× the raw JSON size in bad cases)
OOM / process kill Peak JS heap + retained tree + rest of the app

On the data_250mb.json fixture in our tests: iOS could complete JSON.parse but only with extreme CPU and memory spikes; Android always crashed before parse finished, making JSON.parse impossible for that payload on Android, while native parseFile worked on both platforms.

Benchmark fixture (source)

Measurements in this repo use the public ~250 MB JSON from antonmedv/json-examples:

Repository https://github.com/antonmedv/json-examples
File data_250mb.json
Raw URL https://github.com/antonmedv/json-examples/raw/refs/heads/master/data_250mb.json

The example app downloads that URL, caches it on disk, then calls parseFile on the local path.

Measured results (parseFile, release builds, physical devices)

Platform Time to root JsonView CPU / memory (observed)
iOS ~100 ms Stable, no long CPU peg, no runaway JS heap growth during parse
Android ~500 ms Stable, same qualitative behavior as iOS, slower wall time

JSON.parse / response.json() on the same fixture:

Platform JSON.parse parseFile + lazy JsonView
iOS Many seconds; extreme CPU and memory spikes (~1.2 GB JS heap ballpark) ~100 ms; CPU and memory stable
Android Crash, could not complete parse ~500 ms; CPU and memory stable (~400 MB mostly native buffer)

The second row is not “free memory.” The file still occupies roughly file size + simdjson padding in native memory. The win is avoiding a second full copy as a giant JS object graph until you explicitly materialize pieces.

Why “read file as string, then JSON.parse” can be worse at peak

A common variant:

const text = await readFile(path, 'utf8');
const data = JSON.parse(text);

At peak you may briefly hold:

  • The entire file as one JS string
  • The entire parsed tree
  • Parser scratch allocations

response.json() can sometimes avoid exposing one giant application-level string, but the end state is still the same: a full tree in JS. For large files, peak heap is the killer.

The technique: how react-native-fast-json does it

react-native-fast-json is what makes the native lazy model practical in React Native. Instead of returning a plain object from JSON.parse, it shifts work across a different boundary:

file bytes → native buffer (simdjson) → JsonView handle → read paths on demand

1. Native buffer (simdjson)

parseFile loads the file into a padded native buffer (simdjson::padded_string::load). Parsing runs in C++ with simdjson (SIMD-accelerated, widely used for large JSON).

The document’s canonical bytes live in native memory, not as nested JS objects.

2. Lazy JsonView (Nitro hybrid object)

The root returned to JavaScript is a JsonView, a Nitro hybrid object backed by C++. Calling:

  • getValue('metadata')
  • atPath('$.a.b.c')
  • asString() on a scalar

…does targeted native work and only crosses the bridge with small results (another JsonView handle or a primitive), not the whole document.

3. Materialization is explicit and expensive

When you call:

  • asObject(), subtree becomes a JS-friendly map/array structure
  • rawJson(), subtree becomes a JS string

…you have chosen to pay the JS heap cost for that slice. On a 250 MB document, calling these on the root is equivalent to opting back into the problem you avoided.

Architecture

HybridFastJson (cpp/HybridFastJson.cpp):

  • parseFile(path), load file, construct HybridJsonView, cache by path string
  • parseString(str), copy string into native view (not path-cached)
  • release(path), erase cache entry for that path

HybridJsonView, navigation, path helpers, scalar coercion, optional materialization.

Until release(path), a cached parseFile keeps the full native buffer alive even if JS drops its JsonView reference, plan releases when the flow ends.

What you still pay for (honest accounting)

Cost Still there?
File-sized native memory Yes, roughly JSON size + padding
Parse CPU Yes, but native simdjson is much faster than building a JS tree
JS heap for the whole tree No, unless you asObject() / rawJson() large parts
Bridge traffic Per access; keep reads coarse-grained for huge docs
Path cache parseFile retains buffer until release(path)

There is no zero memory overhead. The claim that holds up is: near-zero additional JS heap for the full document while you navigate lazily.

Why milliseconds (or low hundreds of ms) are plausible for hundreds of MB

simdjson is designed for throughput on large valid JSON. On the data_250mb.json fixture, parseFile after the file is on disk landed at ~100 ms on iOS and ~500 ms on Android in our release builds, with stable CPU and memory. By contrast, JSON.parse on iOS took many seconds with extreme spikes; on Android it always crashed, so native parse was the only viable option there.

Caveats when you reproduce benchmarks:

  • Fixture, use the same public file or disclose yours
  • Cold vs warm storage (first read after download vs re-parse)
  • Platform, Android was ~5× slower than iOS in our tests; do not assume one number for all devices
  • Device tier and storage speed
  • JSON shape (depth, string density) affects constant factors
  • Debug vs release native builds, ship measurements on release binaries

Comparison table (same fixture, measured + observed)

Dimension JSON.parse (our tests) Native JsonView (parseFile)
iOS Completes after many seconds; extreme CPU/memory spikes ~100 ms; stable CPU/memory
Android Crash, parse not possible on ~250 MB ~500 ms; stable CPU/memory
Primary memory Full JS object graph (when it survives) Native padded buffer (~file size)
UI thread risk High during parse Lower; still avoid huge sync work in JS
Best access pattern Whole-tree mutation Few paths / scalars / wildcards
Foot-guns Retaining whole data asObject() / rawJson() on huge nodes; never calling release

Wildcards and paths

  • atPath('$.a.b.c'), simple dotted segments, no [index] in the path string.
  • atPathWithWildcard('$.items[*].id'), dynamic segments; returns string[] | null for matched scalar strings.

For very large documents, prefer narrow paths over scanning wildcards across the whole tree unless you have measured the cost.

When native lazy parsing is the wrong tool

Not a common use case, prefer better alternatives

Shipping ~250 MB JSON to a phone is a smell, not a pattern. We benchmark it because it stress-tests the parser and matches real legacy pain, not because every app should do it.

Try these first (usually cheaper than optimizing parse):

  1. Don’t send the file, paginate, stream, or return only fields the UI needs.
  2. Don’t use JSON on the wire, schema-driven binary formats decode faster and smaller.
  3. Don’t keep one blob, SQLite (or similar) with indexes for the queries you actually run.
  4. Don’t parse on the critical path, generate summaries or shards on the server; sync deltas.

Native lazy parsing is a mitigation when you are locked into large JSON. It is not a substitute for a sane data contract.

When this library still does not help enough

  • Small payloads, JSON.parse is simpler and fast enough.
  • You need the entire document in JS anyway, you will materialize everything eventually; measure whether native parse + bulk asObject() is still a win.
  • Heavy in-place mutation of arbitrary subtrees in JS, work on plain objects.
  • You cannot hold file-sized native RAM (low-RAM devices + multiple huge files), budget and serialize access; even native buffers are ~file size.

Benchmark methodology

import { fastJson } from 'react-native-fast-json';

const root = await fastJson.parseFile('/path/to/large.json');
const version = root?.getValue('metadata')?.getValue('version')?.asString();
fastJson.release('/path/to/large.json');
  1. Fixture, data_250mb.json from antonmedv/json-examples, via
    https://github.com/antonmedv/json-examples/raw/refs/heads/master/data_250mb.json
  2. RN Version 0.85.0, New Architecture.
  3. Device, physical iOS and Android (document model, OS, RN version, Hermes on/off).
  4. Build, release native binary.
  5. Scenarios

    • A: response.json() or JSON.parse after full string in memory
    • B: download/cache to disk → parseFile(localPath) → read N fields → release(path)
  6. Metrics, wall time to root JsonView, JS heap snapshot, CPU/memory stability in Instruments / Android Studio.
  7. Our results, parseFile: iOS ~100 ms, Android ~500 ms, CPU/memory stable. JSON.parse: iOS many seconds with extreme spikes; Android always crashed on this fixture.

The example app implements download + parseFile + timing UI, use it as a starting point, not as universal truth.

Summary

Idea Detail
Problem JSON.parse materializes the whole document in the JS heap.
Technique Parse in native with simdjson; expose JsonView; read lazily.
Speed data_250mb.json: ~100 ms (iOS) / ~500 ms (Android) for parseFile in our tests.
CPU / memory Stable on native parse; JSON.parse had extreme spikes on iOS and crashed on Android for this fixture.
Memory model Avoid blowing up the JS heap; native still holds ~file size.
Discipline release(path), avoid huge asObject() / rawJson(), extract scalars to plain JS when done.

Try react-native-fast-json

yarn add react-native-fast-json react-native-nitro-modules

Install pods, rebuild, then use fastJson.parseFile for large files on disk. Peer dependency: react-native-nitro-modules.

🏏 Building Captain Cool AI (Third Umpire AI): An Agentic AI-Powered Cricket Intelligence Platform Built at Agentic Premier League Pune

🏏 Building Third Umpire AI: How I Created an Agentic AI-Powered Cricket Intelligence Platform at Agentic Premier League Pune

Turning cricket into a real-time AI strategy engine using Agentic AI, Google Gemini, and a premium SaaS interface.

Cricket in India is more than a sport. It is emotion, strategy, data, and decision-making happening ball by ball.

As both a technology enthusiast and lifelong cricket fan, I have always wondered:

What if an AI system could watch a live cricket match, analyze every moment, and provide strategic insights just like a virtual Third Umpire?

That question led me to build Third Umpire AI, an Agentic AI-powered cricket intelligence platform that analyzes live match data, predicts outcomes, and generates tactical recommendations in real time.

I built this project during Agentic Premier League – Build with AI, an incredible community event organized by the GDG Cloud Pune GDG Cloud Pune community.

🚀 What Is Third Umpire AI?

Third Umpire AI is a modern AI-powered cricket analytics platform designed to act as an intelligent decision-making assistant for:

  • Cricket fans
  • Fantasy cricket players
  • Coaches
  • Analysts
  • Content creators
  • Sports technology enthusiasts

The platform combines live match data, Agentic AI workflows, and advanced reasoning from Google Gemini to deliver:

  • Real-time match analysis
  • Win probability predictions
  • Tactical recommendations
  • Momentum insights
  • Player performance forecasts

Think of it as a virtual Third Umpire that does far more than make decisions—it explains the game strategically.

💡 The Inspiration Behind the Project

The name “Third Umpire AI” perfectly captures the concept.

In cricket, the Third Umpire is trusted to make high-stakes decisions using data, multiple camera angles, and careful analysis.

That is exactly what modern AI systems do:

  • Gather information
  • Analyze context
  • Reason through uncertainty
  • Deliver confident conclusions

I was also inspired by the calm and strategic mindset of Mahendra Singh Dhoni MS Dhoni, whose decision-making under pressure has defined some of cricket’s most iconic moments.

🏏 Why Cricket + AI Is a Perfect Match

Cricket generates an enormous amount of structured data:

  • Scores
  • Strike rates
  • Run rates
  • Wagon wheels
  • Matchups
  • Bowling patterns
  • Historical performance

AI can process this information far faster than humans and uncover patterns that are difficult to detect in real time.

With Agentic AI, the system does more than answer questions. It can:

  • Observe the current match state
  • Gather relevant data
  • Reason step by step
  • Generate predictions
  • Recommend strategic actions

🤖 What Is Agentic AI?

Traditional AI responds to prompts.

Agentic AI takes initiative.

It can:

  • Plan multi-step workflows
  • Use tools and APIs
  • Analyze external data
  • Make decisions autonomously
  • Refine outputs iteratively

This project uses Agentic AI to simulate the thought process of a cricket strategist.

For example:

  1. Fetch live score data
  2. Analyze batting momentum
  3. Compare historical patterns
  4. Estimate win probability
  5. Recommend bowling or batting tactics
  6. Present insights visually

🏗️ Technology Stack

Third Umpire AI is built using modern technologies:

Category Technology
Frontend Next.js 15
Language TypeScript
Styling Tailwind CSS 4
AI Model Google Gemini
Agent Framework Antigravity
Icons Lucide React
Deployment Vercel Vercel
Data Source Live Cricket APIs

🎨 Designing a Premium SaaS Experience

One of my goals was to ensure the interface looked like a top-tier Silicon Valley SaaS product.

The UI includes:

  • Dark futuristic design
  • Glassmorphism cards
  • Animated gradient borders
  • Premium dashboards
  • Interactive charts
  • Responsive layouts

Design inspiration came from products such as:

  • Linear
  • Vercel Vercel
  • Stripe
  • Framer
  • Raycast
  • OpenAI OpenAI

📊 Core Features

🏏 Live Match Dashboard

Real-time score tracking and momentum analysis.

🤖 AI Strategy Engine

Agentic reasoning for tactical recommendations.

📈 Prediction Center

Win probability and outcome forecasting.

🏏 Player Analytics

Performance trends and matchup insights.

📰 Commentary Insights

Contextual explanations generated by AI.

⚙️ Premium Dashboard

Beautiful, enterprise-grade user experience.

🧠 How the Platform Works

Live Cricket API
       ↓
Data Processing Layer
       ↓
Agentic AI Workflow
       ↓
Google Gemini Reasoning
       ↓
Predictions & Strategic Insights
       ↓
Interactive Dashboard

⚡ Development Journey

I built this project during Agentic Premier League – Build with AI hosted by the amazing GDG Cloud Pune GDG Cloud Pune community in Pune.

The event brought together developers and AI builders to create real-world applications using cutting-edge AI technologies.

The experience was energizing and deeply inspiring. It was exciting to combine my passion for:

  • Cricket
  • Artificial Intelligence
  • Product Design
  • Modern Web Development

into one meaningful project.

🙏 Thank You GDG Cloud Pune

A huge thank you to the entire GDG Cloud Pune GDG Cloud Pune community for organizing such a high-quality event.

Community-driven events like this provide the perfect environment to:

  • Learn emerging technologies
  • Build innovative products
  • Connect with fellow creators
  • Push ideas into reality

If you are interested in AI, cloud, and modern development, I strongly recommend joining their community and attending future events.

🌍 Future Roadmap

I plan to expand Third Umpire AI with:

  • Fantasy cricket recommendations
  • Voice-based analysis
  • Multilingual support
  • Historical match simulation
  • Mobile application
  • Coach-focused analytics
  • Advanced visualizations

🔗 Project Links

👨‍💻 About Me

I am Pritam Sonone Pritam Sonone, an AI builder, WordPress contributor, digital creator, and founder of Amhi Kastkar and Digital Pritam.

My mission is to use technology, artificial intelligence, and education to create meaningful products that solve real-world problems and empower people at scale.

🏏 Final Thoughts

Third Umpire AI started as an idea at a community event, but it represents something much bigger.

It demonstrates how domain expertise, creativity, and modern AI tools can combine to build products that are both technically sophisticated and genuinely useful.

For me, this project is where three passions meet:

  • Cricket
  • Artificial Intelligence
  • Product Innovation

And this is only the first innings.

📣 Special Mention

Special thanks to the GDG Cloud Pune GDG Cloud Pune community for organizing Agentic Premier League – Build with AI and creating an inspiring environment for builders to innovate.

🏏 Building “Captain Cool”: A Multi-Agent IPL Strategist with Google Antigravity & Gemini 2.5

Cricket is a captain’s game. It’s not just about the numbers; it’s about the gut feeling, the matchup risks, and anticipating what the opposition will do next.

For the Google Gemini Hackathon, I had 3 hours to build an agentic AI system that makes tactical decisions like a real IPL captain. But I didn’t want a generic chatbot that just spits out cricket trivia. I wanted a system that debates itself before committing to a call.

Enter Captain Cool: a multi-agent orchestration engine built entirely on the Google Gemini stack.

Here is how I built it using Google Antigravity, the google-genai SDK, and zero bloated frameworks.

🏗️ The Architecture: A Three-Agent Debate Loop

To make genuinely good cricket decisions, the system cannot wear four hats in a single API call. It needs distinct, isolated personas that pass context back and forth.

I designed a 3-agent cyclic reasoning loop, overseen by a final Synthesizer:

📊 The Stats Analyst: The anchor. This agent is strictly forbidden from giving advice. Its only job is to look at the match context and spit out raw data, matchups, pitch conditions, and historical trends.

🎯 The Strategist: The decision-maker. It takes the Analyst’s data and proposes an actionable plan (batting order, bowling rotation, field setups).

⚠️ The Devil’s Advocate: The stress-tester. It looks at the Strategist’s plan, finds the biggest assumption or worst-case scenario (e.g., “What if we lose another wicket in the powerplay?”), and forces the Strategist to defend or adapt.

These three agents loop for a configurable number of rounds, building a shared conversation history. Once the debate concludes, the Head Coach (Synthesizer) agent reads the entire transcript and outputs one definitive, battle-ready Markdown document.

🛠️ The Tech Stack (Google In-House)

Model: gemini-2.5-flash (Fast, highly capable, and perfect for multi-turn reasoning).

SDK: Pure google-genai (Python). I intentionally avoided LangChain or AutoGen to keep the orchestration lightweight and fully custom.

IDE: Google Antigravity. This was the secret weapon. I used Antigravity as an agentic pair-programmer to vibe-code the directory structure, wire up the Pydantic data schemas, and debug live API errors in real-time.

🧠 The Prompts that Drive the Debate

The magic is entirely in the system instructions. Here is how I scoped the Devil’s Advocate to ensure it didn’t just disagree for the sake of it, but actually improved the strategy:

ROLE: Your job is to stress-test the Strategist’s plan and expose every assumption, gap, and risk. You are not contrarian for its own sake — you are the last line of defence against overconfident planning.

RESPONSIBILITIES:

Identify the single biggest assumption in the Strategist’s plan and challenge it with a realistic counter-scenario.

Propose the most dangerous opposition counter-strategy.

Model the “bad day” scenario: if 2-3 things go wrong simultaneously, does the plan have a recovery path?

CONSTRAINTS:

You MUST propose an alternative or a mitigation for every risk you raise.

🔥 Scenario Walkthrough: PBKS hunting 222 vs RCB

To test the system, I fed it a brutal, high-pressure match state: Punjab Kings are 10/1 after 1.3 overs. They are chasing Royal Challengers Bengaluru’s massive 222-run total at Dharamshala. Here is how the multi-agent system handled it:

Turn 1: Stats Analyst
The Analyst instantly flagged the pitch as batting-friendly, but noted the required run rate was already north of 11 RPO. It highlighted that with Shikhar Dhawan out early, the powerplay metrics were deeply compromised.

Turn 2: Strategist
The Strategist proposed sending in Liam Livingstone at No. 3 as an “Anchor-Accelerator Hybrid,” tasked with hitting boundaries from ball one, followed by Sam Curran to stabilize if another wicket fell. It mandated reaching 55-60 runs by the end of the powerplay.

Turn 3: Devil’s Advocate
The Advocate jumped in, pointing out a critical flaw: relying on Livingstone to anchor and accelerate is a high-risk paradox. If Livingstone falls early trying to hit, the middle order is exposed to RCB’s spinners with no momentum. The Advocate demanded a strict contingency plan if PBKS found themselves at 30/3.

The Output:
The final synthesized strategy explicitly mapped out the batting order, the required run-rate milestones per over, and the exact “In-Match Triggers” for when to abandon the plan and swing for the fences.

[ 📸 Insert Screenshot of your Terminal output here showing the debate ]

[ 📸 Insert Screenshot of your final Markdown output here ]

🚧 Building Challenges & Antigravity to the Rescue

Building this in a 3-hour window wasn’t without hurdles.

Initially, the 3-agent loop fired so fast that it tripped the API rate limits (429 RESOURCE_EXHAUSTED). Instead of abandoning the multi-agent design, I used Google Antigravity to dynamically inject pacing (time.sleep(15)) into the orchestrator loop.

Later, we hit a 404 NOT_FOUND error because I was trying to call legacy models. Antigravity helped me quickly refactor the class definitions to hardcode gemini-2.5-flash, ensuring perfect execution within the hackathon environment constraints.

🏆 Conclusion

Cricket strategy is complex, but by decomposing the problem into distinct analytical, strategic, and critical personas, Gemini 2.5 proved it can reason through a T20 match just as well as the commentators in the box.

Code is live on GitHub! Bring the heat. 🏏

Build with AI – APL GDG Pune

📊 Analyst Output:
“Venue verified as Mumbai. Tool execution confirmed: Surface is a flat highway with high moisture levels. Humidity tracking at 72%. The leather will be exceptionally difficult to grip for spin bowling.”

⚖️ Devil’s Advocate Challenge:
“Look at the match-ups. Shivam Dube has a historic strike rate of over 165 against leg-spin, and with the dew setting in at Wankhede, Piyush Chawla won’t be able to grip the seam or control his lengths. Throwing spin here is absolute suicide. The numbers demand that we deploy Jasprit Bumrah right now. We must break this partnership immediately and choke the run-rate, even if it leaves us completely thin at the death.”

🧢 Captain Cool’s Final Call:
“The Advocate is reading the spreadsheet perfectly, but he’s panicking. If you burn Bumrah in the 16th over completely out of fear, you give away the entire game on a platter in the 19th and 20th.

Here’s the play: We save Bumrah for the death overs where he belongs. Instead, we hand the ball to Hardik. We tell him to roll his fingers over the seam, bowl into the surface, and rely entirely on heavy cutters into the body. Take all the pace off the ball. On this wet outfield, if we don’t give Dube any raw pace to work with, he has to clear long boundaries entirely on his own muscle power. We’ll drop deep square leg right to the boundary rope and pull mid-off inside the circle to bait him into the miscue. This is where we break the chase.”

🚀 Key Takeaways & The Developer Journey
Building “Captain Cool” during this 3-hour vibe-coding session highlighted the massive paradigm shift happening in AI architecture. Prompting a single model to act as a sports strategist results in generic, safe, and boring commentary.

By utilizing Google Antigravity to quickly manage environment lifecycles and using the ADK to isolate distinct, conflicting system instructions, the system successfully recreated the tension, contrast, and ultimate clarity of an elite sports brain trust.

The future of sports analytics isn’t static graphs; it’s interactive, adversarial reasoning.

STRAT- built for the last over

STRAT is an AI-powered IPL tactical command center built to simulate how real cricket captains think under pressure. Instead of behaving like a generic chatbot, STRAT creates a live “AI war room” where multiple Gemini-powered agents collaborate, challenge each other, and debate tactics before arriving at a final decision. The idea behind the project was simple: cricket is a captain’s game, where small tactical calls — bowling changes, field placements, matchup decisions, or timeout timing — can completely shift momentum. STRAT analyzes live or custom match situations using inputs like score, overs, wickets, pitch conditions, dew factor, venue, bowling resources, and required run rate to generate realistic tactical recommendations.

Key features of STRAT include:

• 🧠 Multi-agent AI orchestration with distinct roles like Strategist, Stats Analyst, Devil’s Advocate, and Commentator
• 📊 Real-time tactical reasoning using matchups, momentum, and contextual cricket intelligence
• 😈 Internal AI debate loops where agents challenge and revise strategies before finalizing decisions
• 🏏 Live Match Center for ongoing IPL analysis and a Strategy Sandbox for custom simulations
• 🎯 Interactive field visualization with tactical overlays, ball trajectories, and dynamic field placements
• 📈 Momentum tracking, pressure analysis, confidence scoring, and “What If?” tactical simulations

The platform was designed to feel more like a Formula 1 pit-wall or tactical sports operating system rather than a traditional dashboard. Built using Next.js, TypeScript, Tailwind CSS, Framer Motion, Zustand, and Gemini 2.5 Pro/Flash, STRAT explores how AI can move beyond basic chat interfaces into collaborative, explainable, and immersive decision-making systems. The goal wasn’t just to predict outcomes, but to create an experience where users can genuinely think like IPL captains in real time — analyzing pressure, debating strategies, and making smarter tactical calls ball by ball.