VARAHI TECHNOLOGIES · PUNE
AI-FIRST BUILDER SERIES · SESSION 01 · RECAP
← Original brochure
Field report / Saturday, 25 April 2026

Anatomy
of an Agent.

A morning of chai, code and quiet conviction — fifteen builders sat down with two agentic codebases, one Mario Zechner video, and the question that's quietly redefining how software is written: what makes an agent harness, a harness?

Who made it happen

The contributors

PP
Parth Pandya Host · founder demo
View
AN
Anuj Nalawade pi-mono walkthrough
View
DS
Dattatray Salunkhe pi-mono walkthrough
View
AJ
Avanish Jain Claude Code walkthrough
View
S
Suryabhan Claude Code walkthrough
AC
Amit Chavan Spec-driven dev · closing
View
NM
Nilesh Miskin Pre-meeting input
View
SD
Sucheta Dhere Pre-meeting input
View
MB
Milind Bhinge Pre-meeting input
View
JP
Janhavi Pandya Operations & venue
View
VT
The Varahi team Hospitality, AV, coordination
View
Plus fifteen builders in the room and an open online cohort, who turned a planned session into a real working morning.

If you walked into Varahi's office at 305, Delta Square last Saturday morning at ten o'clock, you would have found the kind of room India's AI scene rarely produces: fifteen serious builders, no panel, no powerpoint, just a long table, two agentic codebases on a screen, and a kettle that didn't stop steaming for the next three hours. This is what happened.

The room had no obvious centre of gravity. There were consultants who'd spent the last decade architecting enterprise software, cybersecurity engineers who think about agents the way locksmiths think about doors, full-stack developers shipping AI features into production, and a few founders quietly nursing larger plans. What pulled them into the same conversation wasn't a job title — it was a shared, unfinished question.

Everyone is shipping "agents." Very few people have actually read how a production-grade agentic system is wired.

The session was built around closing exactly that gap. Not with a lecture, not with a tutorial, but by reading two real agentic coding CLIs side by side — pi-mono, the open-source MIT-licensed monorepo by Mario Zechner, and Claude Code, Anthropic's official CLI assistant whose archived source has been the subject of much architectural curiosity in the AI engineering community. We didn't compare them to crown a winner. We compared them to extract the patterns that any serious agentic system has to solve.

§ 01 · 10:00 — 10:30

The half-hour before.

The thirty minutes from 10:00 to 10:30 turned out to be the most underrated part of the morning. Builders walked in with chai and small plates of sandwiches, traded one-line introductions, and quickly found the people in the room they'd been Twitter-mutuals with for years. The crowd skewed senior and skewed honest — most introductions started with "I've been struggling with…" rather than "I've been building…", which set a tone of mutual problem-pooling that lasted right through to one o'clock.

Networking and chai at the Varahi office, Pirangut
Networking · 10:15 IST · Varahi office, Pirangut

By the time the first slide went up — well, the first video — every laptop in the room was already open and most attendees had cloned at least one of the two repos.

§ 02 · 10:30 — 11:00

Mario's video, watched the way it deserved to be watched.

The session opened with Mario Zechner's "I Hated Every Coding Agent, So I Built My Own" — a thirty-minute talk that doubles as the design rationale for pi-mono. Zechner is the kind of engineer who'd rather show you a 200-line tool loop than tell you about agentic architecture, and the talk is structured exactly that way: here's what's broken with existing agents, here's the smallest thing that fixes it, here's the next-smallest thing.

The video wasn't there to be watched in the way a webinar gets watched — passively, in silence, with chat reactions. It was there to be discussed. Whenever someone in the room had a point worth making, the video paused and the conversation took over for a few minutes before it resumed. By the end of the half-hour, we'd covered the talk's core ideas with our own examples layered on top, which is exactly how a piece of source material should be used in a working session.

The phrase that anchored the rest of the day came out of one of these discussions:

An agent harness isn't the model. It's everything around the model that decides what the model gets to see, do, and remember.

Once that framing landed, the room had a shared vocabulary. The harness — the LLM client, tool loop, permission gate, context manager, event bus, UI layer, persistence — became the lens through which we looked at every line of code for the next two hours.

Clip · 10:45 IST · the video, paused for discussion
Clip · 10:52 IST · the room talking back to the screen
§ 03 · 11:00 — 11:20

Parth Pandya's workspace.

Parth Pandya walked us through his personal AI workspace — built on Obsidian, with a custom pi-driven CLI handling the agent layer, and a hybrid setup that uses local LLMs alongside an OpenAI Codex subscription for daily operations.

The setup runs a mix of personal and small company-level automations — note-taking, content workflows, a few internal task automations. What made the walkthrough useful for the room wasn't any single feature; it was the underlying philosophy the demo demonstrated:

Don't build agents to replace your work. Build a harness that makes your existing work compoundable.

PP
Founder demo · 11:00 Parth Pandya Walked the room through a personal AI workspace built on Obsidian and a custom pi-driven CLI, with a local-LLM-plus-Codex hybrid for day-to-day operations. LinkedIn

A few patterns from the setup made it onto laptops in the room: Obsidian as the canonical knowledge surface; pi as the agent that reads and writes that surface; local models (running through pi's vLLM integration) for cheap, private, latency-sensitive operations; and a Codex subscription reserved for workloads that genuinely need frontier-model reasoning. That tiering — local for volume, frontier for depth — was a useful framing for anyone who'd been treating "the model" as a single-tier decision.

Parth Pandya walking the room through his AI workspace
Demo of a working agent harness · Obsidian + pi + local LLMs + Codex
§ 04 · 11:20 — 12:05

Inside pi-mono.

The first deep-read was led jointly by Anuj Nalawade and Dattatray Salunkhe, who walked the room through the pi-mono codebase from our session fork. They opened with the layered dependency graph and didn't move on until the room agreed on what each layer was for.

AN
pi-mono walkthrough Anuj Nalawade Led the layered architecture walkthrough — pi-ai, pi-agent-core, pi-tui, and how pi-coding-agent composes them. Strong on the event-bus design and stream/tool-call interleaving. LinkedIn
DS
pi-mono walkthrough Dattatray Salunkhe Walked the room through the AgentMessage extensibility, declaration merging, and the run-mode matrix (interactive · print · json · rpc · SDK). LinkedIn

The four-layer stack

Anuj's framing of pi-mono's architecture was the clearest summary of the morning. The codebase is a monorepo of seven npm packages, but conceptually it's four layers, each with one job and one rule about what it doesn't know:

// pi-mono · the layered stack

pi-coding-agent  // composition root — the "pi" CLI
       
       
pi-agent-core    // Agent class, tool loop, event bus, AgentMessage
                 // has NO UI knowledge
       
pi-ai            // unified LLM API · 10+ providers
                  // has NO agent concepts

pi-tui           // generic terminal toolkit, used in parallel
                  // has NO LLM knowledge

The discipline of those negative constraints — pi-ai doesn't know what an agent is, pi-agent-core doesn't know what a UI is, pi-tui doesn't know what an LLM is — is what makes the codebase teachable. You can ship pi-ai inside any TypeScript project that just wants multi-provider LLM access. You can ship pi-agent-core inside a Slack bot, a web UI, or a CLI without rewriting it. The composition is what changes; the layers don't.

CLI vs TUI — the distinction we kept coming back to

One of the longer side-discussions started here. The room's reflex assumption was that "CLI" and "TUI" were the same thing. They aren't, and pi-mono's separation makes the difference operational rather than semantic.

CLI

Command-line interface

  • One-shot, scriptable, pipe-friendly
  • Output is plain text or structured JSON
  • Lives at --print, --mode json, --mode rpc
  • What you reach for in a shell pipeline or CI script

TUI

Terminal user interface

  • Interactive, full-screen, stateful
  • Diff-rendered with synchronized output (CSI-2026)
  • Lives in pi-tui · separate package, no LLM dependency
  • What you reach for as a daily driver

This matters because pi treats them as output modalities of the same engine, not as separate products. The same Agent and event bus drives both — the only thing that changes is who consumes the event stream. InteractiveMode renders deltas through pi-tui; runPrintMode converts them to stdout; runRpcMode serialises them as JSON-RPC. One core, four faces.

Agent context — what the model actually sees

The most consequential conversation in the pi-mono walkthrough was about context. The room had been (politely) using "context" to mean three different things: the conversation history, the system prompt, and everything pi-coding-agent stitches into the LLM call before it goes out. Once Dattatray pulled that apart on the screen, the architecture clicked.

The takeaway most builders wrote down: "context" is not a thing — it's an assembly process. Understanding which strategy assembles which slice of context is half the battle of building a serious agent harness.

Code on screen · 11:35 Anuj walking through the AgentSession boot sequence in main.ts

The pi advantage — said carefully

By the time we'd been inside pi-mono for forty-five minutes, the room had a clear picture of what pi gets right. We took pains to frame this as pi's advantages for a particular kind of builder, not as "pi beats Claude Code" — which would be both unfair and untrue depending on the use-case.

Where pi shinesWhy
Multi-providerSame agent runs against Anthropic, OpenAI, Google, Vertex, Bedrock, Ollama, vLLM. Switch with a flag, mid-session if needed.
Open source · MITYou can fork it, ship it, embed it. You can read every line.
Minimal harnessNo sub-agents, no plan mode — by design. Smaller surface, easier to reason about. Add only what you need.
Embedding-friendlyFive run modes: interactive, print, json, rpc, SDK-embed. Drop pi inside any TypeScript program.
First-party web UIpi-web-ui ships in the same monorepo, with IndexedDB session storage and provider-key handling.
Sibling toolingpi-pods for vLLM ops, pi-mom for Slack — same repo, same conventions.
Extensions in TypeScriptLoaded with jiti at runtime — register tools, slash commands, flags, UI components without recompilation.

The rough consensus by 12:05 was that pi is the harness you build a product on top of. Claude Code is the product you reach for when you want everything wired up already. Both choices are legitimate; they're just different decisions about where the seams should be.

§ 05 · 12:05 — 12:35

Inside Claude Code.

The Claude Code walkthrough was led by Avanish Jain and Suryabhan, who'd done the painstaking work of mapping a 1,900-file, 512,000-line codebase down to a teachable shape. The framing they opened with set the tone perfectly:

Claude Code is a React app in your terminal. Every piece of UI is a React component with hooks — it's just rendered to characters instead of pixels.

AJ
Claude Code walkthrough Avanish Jain Mapped the 1,900-file Claude Code archive down to four key files and one pipeline. Walked the room through QueryEngine, Tool.ts, the buildTool factory, and the permission gate. LinkedIn
S
Claude Code walkthrough Suryabhan Co-led the Claude Code session, with focus on MCP integration (client and server), the bridge layer for IDE integration, and the build-time feature-flag system that ships variant binaries from one codebase.

Four files do most of the work

The architecture brief Avanish brought to the room is worth quoting in full because it's a small marvel of compression. A 512,000-line codebase reduced to four files:

FileLinesRole
QueryEngine.ts~46,000LLM streaming + tool-call loop · the only component that talks to the Anthropic API directly
Tool.ts~29,000Tool abstraction · the buildTool() factory every tool is constructed through
commands.ts~25,000Slash-command registry · 85+ commands across three types (prompt / local / JSX)
main.tsxCLI parser + startup orchestration · parallel prefetch, init, REPL launch

If you only have an hour to understand Claude Code, those four files are the hour. Everything else — the 40 tools, the 85 commands, the 80 hooks, the bridge layer, the coordinator, the skills — is layered around them.

The buildTool factory · uniformity as a discipline

The single design pattern that landed hardest with the room was the buildTool() factory. Every Claude Code tool — from BashTool to WebSearchTool to the multi-agent AgentTool — conforms to one shape:

export const MyTool = buildTool({
  name: 'MyTool',
  aliases: ['my_tool'],
  description: 'What this tool does',
  inputSchema: z.object({ param: z.string() }),

  // the work
  async call(args, context, canUseTool, parentMessage, onProgress) {
    return { data: result, newMessages: [...] }
  },

  // safety
  async checkPermissions(input, context) { /* … */ },
  isConcurrencySafe(input) { /* parallel-safe? */ },
  isReadOnly(input) { /* non-destructive? */ },

  // presentation
  prompt(options) { /* system-prompt injection */ },
  renderToolUseMessage(input, options) { /* UI for invocation */ },
  renderToolResultMessage(content, progress, options) { /* UI for result */ },
})

This is the discipline that lets the QueryEngine stay agnostic. The engine doesn't care what BashTool does or what WebFetchTool does — it dispatches every tool through the same shape, validates inputs against the same Zod schemas, runs them through the same permission gate, and renders results through the same UI hook. One factory, forty tools, zero special cases in the core loop.

Permissions as a first-class subsystem

The room spent ten minutes on src/hooks/toolPermission/ — the centralised gate that every tool call passes through before execution. Four modes:

Combined with a wildcard rule language (Bash(git *), FileEdit(/src/*), FileRead(*)), this gives you a permission system that's expressive enough for a senior engineer and conservative enough for an enterprise rollout. Suryabhan made the point that this is one of the most under-discussed parts of Claude Code's design — most agent harnesses bolt permissions on as a guard rail; Claude Code treats them as first-class subsystem.

MCP, twice over

Claude Code is both an MCP client (consumes external tools) and an MCP server (exposes its own). This bidirectional posture is the architectural choice that makes it interoperable with the broader agent ecosystem — Cursor, Claude Desktop, custom orchestrators. Few harnesses are this honest about being part of a larger graph.

The build-time trick · feature flags that strip code

The detail that made the room laugh and then take notes was Bun's bun:bundle feature flag system. When VOICE_MODE is disabled at build time, the entire voice subsystem — every component, every hook, every dependency — is physically removed from the bundle. One codebase, many shipped variants.

import { feature } from 'bun:bundle'

if (feature('VOICE_MODE')) {
  // this entire block — and everything it imports —
  // is stripped from the binary when VOICE_MODE is off
  const voiceCommand = require('./commands/voice/index.js').default
}

This is how Anthropic ships a single source tree that compiles to internal-only builds, enterprise builds, public builds, and IDE-bridge-enabled builds. Most teams reach for monorepos to solve this. Claude Code reaches for compiler flags.

§ 06 · 12:35 — 12:45

What both converge on.

The compare-and-extract block was where the morning's reading paid off. Stripped of marketing and stripped of style, the two systems converge on a remarkably similar set of decisions:

ConcernHow both solve itWhere they differ
Tool contractBoth use a uniform factory shape with a typed input schema (Zod), an async call(), and an opt-in permission check.Claude Code adds isReadOnly/isConcurrencySafe; pi keeps it minimal.
Tool loopStream-from-LLM → detect tool_use → permission gate → execute → feed tool_result back → loop until stop. Same algorithm.Claude Code threads thinking-mode budgets and prompt caching; pi treats those as provider-level concerns inside pi-ai.
Permission gateCentralised, runs before every tool call, supports rule-based auto-approval.Claude Code has 4 explicit modes + wildcard rule language; pi delegates more to the embedding application.
StreamingToken deltas, tool-call deltas, and lifecycle events on a single normalized event stream.Claude Code's stream lives inside QueryEngine; pi exposes it on a subscribable bus that any UI can read.
Context assemblySystem prompt + project rules + active tools + history + cwd state — assembled per turn, not stored.Claude Code: context.ts + memdir/. pi: layered template + compaction/ strategies.
Multi-agentBoth treat sub-agents as a tool the top-level agent can call.Claude Code ships AgentTool + coordinator/ + TeamCreateTool. pi deliberately omits this.
PersistenceSessions on disk, portable, exportable.Claude Code: history.ts. pi: JSONL per cwd, --fork to clone, --export to HTML.

The agent harness is settling. The seven concerns above are now standard. What's still open is which seams you expose to your application — and that's where the philosophical fork between pi and Claude Code matters most.

§ 07 · 12:45 — 13:00

Why spec-driven development is the next frontier.

The session closed with Amit Chavan walking the room through spec-driven development — and specifically, why GitHub's spec-kit represents the right operating system for vibe coding in an agentic AI world.

AC
Closing deep-dive · 12:45 Amit Chavan Took the room through GitHub spec-kit's core concepts and made the case for spec-driven development as the foundation for serious agentic AI workflows. The closing segment of the morning, and quietly the most consequential. LinkedIn

The argument Amit made, distilled, was this: vibe coding — where you describe what you want and an agent builds it — fails the moment your codebase or your team grows beyond a certain threshold. Not because the agent gets worse at coding, but because the agent has no shared specification of what "right" means. Without a spec, every agent run is a re-discovery of intent. Spec-kit fixes this by making the spec a first-class, version-controlled artifact that the agent reads before it writes.

The four core concepts

01

Specs as code

Specifications live in your repo as markdown, not in tickets. They're versioned, diffable, and reviewable. The agent reads them like it reads any other source.

02

Plan before patch

Every change starts with a plan derived from the spec. The agent generates the plan; a human reviews and approves it before any code is written. The plan becomes part of the audit trail.

03

Constitution layer

Project-wide invariants — coding standards, security rules, architecture decisions — live in a "constitution" file that's loaded into every agent context. The constitution is the team's collective taste, codified.

04

Spec-aligned tasks

Every task gets traced back to a spec section. If you can't point to the spec that justifies a change, you don't make the change. Drift becomes detectable.

Why this matters for agentic AI · the long view

The single most useful thing Amit said — the line a few people in the room wrote down verbatim — was about the relationship between specifications and trust:

An agent without a spec is an intern with confidence. An agent with a spec is a colleague with constraints. The specification is what turns "useful tool" into "trustworthy collaborator."

Spec-driven development matters for agentic AI for four reasons that compounded over the rest of the discussion:

  1. 01 → Reproducibility. The same spec + the same model + the same constitution should produce equivalent outputs. Without specs, every agent run is non-deterministic in the worst way.
  2. 02 → Reviewability. A reviewer can check "does this change match the spec" much faster than they can check "is this change correct in the absolute." Specs are the unit of code review when agents are involved.
  3. 03 → Compoundability. Specs persist across agent runs and across model upgrades. When GPT-6 arrives, your specs still apply. Your prompt-engineered context-stuffing does not.
  4. 04 → Multi-agent coordination. When two agents work on the same codebase, the spec is the only artifact they can both reference. Without it, you don't have collaboration — you have collision.

If pi-mono and Claude Code answer the question of how to build an agentic system, spec-kit and the spec-driven philosophy answer the question of what to build with one. The room's consensus by the close of the morning was that anyone shipping agentic AI to production in 2026 without a spec layer is shipping debt by another name.

Photo · 12:55 Amit's spec-kit walkthrough · the closing segment of the morning
§ 08 · Tangent

And the question of local deployment on a phone.

One of the side-conversations — the kind that only happens in rooms small enough to interrupt — was about deploying AI models locally on mobile devices. Two surprisingly practical tools came up. Termux, the Android terminal emulator that's quietly become a serious mobile development environment, was the first; you can run pi-mono inside Termux on a sufficiently capable phone, with local Ollama models providing inference. Google's AI Edge Gallery was the second, alongside NVIDIA's catalog of optimized AI models for edge deployment. The combination — Termux for the harness, on-device inference for the model — is genuinely usable today for small agentic workflows that don't want to leave the phone.

None of this made the agenda. All of it ended up in three or four laptops by the end of the morning.

§ 09 · Hands-on

Build your own CLI.

Reading is one thing. Building is the other. Here's the work to do — at your own pace, in your own week, before Session 02. The repos you'll need:

Repos

Clone these and read along

The session fork — start here. Includes both architecture briefs in the /docs folder:

github.com/parthpandya1729/aifirst-session01-anatomy-of-an-agent

The originals:

github.com/badlogic/pi-mono github.com/codeaashu/claude-code

And for spec-driven development:

github.com/github/spec-kit

The exercise we sent everyone home with was deliberately small, because the point isn't to ship a product — it's to feel where the seams are.

The take-home

Build a 100-line agentic CLI that does one thing well.

Pick one of pi-mono or Claude Code as your reference. Pick one task — file summarisation, log triage, git commit message generation, a personal journal compactor, anything. Wire up one LLM call, one tool, one permission check, and one rendering loop. Get it under 200 lines. Ship the gist.

The point: after you've done this once, you will never again look at an agentic system the same way. You'll see the harness everywhere — and you'll see what's missing.

Bring your gist to Session 02. We'll read each other's harnesses and trade notes.

# Quick-start scaffold (TypeScript + pi-ai)

mkdir my-agent && cd my-agent
npm init -y
npm install @mariozechner/pi-ai zod

# Then write ~100 lines that:
#  1. Define one tool with a Zod input schema
#  2. Stream a chat completion from any provider via pi-ai
#  3. Handle one tool_use → tool_result round-trip
#  4. Print streamed deltas to stdout
#  5. Loop until the model stops calling tools

# Reference: pi-mono/packages/pods/src/agent/main.ts
# That's a working ~150-line agent in one file.
Acknowledgments

The morning worked because of these people.

Sessions like this don't run themselves. A few notes of genuine thanks before we close.

The session leadsAnuj Nalawade and Dattatray Salunkhe for the pi-mono walkthrough; Avanish Jain and Suryabhan for Claude Code; Parth Pandya for the founder-workspace demo; Amit Chavan for the spec-driven development closer. Each of you turned what could have been a passive viewing party into an actual working session.

The inputs that shaped the agendaNilesh Miskin, Sucheta Dhere, and Milind Bhinge, whose pre-meeting conversations sharpened both the framing of the session and the choice of what we'd actually walk through. The shape of the morning came directly from those discussions.

And on the operations side — a notable mention to Janhavi Pandya and the Varahi Technologies team, who handled venue, chai, sandwiches, AV, attendee coordination and the hundred small things nobody sees but everybody depends on. The session ran on time, on tone, and on hospitality because of you.

If you were in the room — thank you. If you joined online — thank you. If you weren't there but read this far — we'll see you next time.

Session 02 · Confirmed

The next one is on 9 May 2026.

Session 02 of The AI-First Builder Series is locked in for Saturday, 9 May 2026, from 10:00 AM to 1:00 PM IST, at Varahi's office in Pirangut. Same format, same room, same kind of room — fifteen builders in person, plus an open livestream.

The agenda is being shaped now. If there's a topic you'd like the room to read through next, or a codebase you want to walk us through, the easiest way to get on the agenda is to drop a note. The shape of these sessions comes from what attendees bring to them.

In the meantime — build the take-home CLI. Read the repos. Try spec-kit on a real project. Bring your harness on the 9th and we'll read each other's code.

SAT · 9 MAY 2026 · 10:00 — 13:00 · VARAHI · PIRANGUT