AI Weekly: Google Reshapes the Coding Stack, Claude Pulls Ahead, and the Agent Protocol Stack Hardens (Week of May 13-20, 2026)

This week the AI industry served up one of its busiest Google I/O keynotes in years, a meaningful shift in business spending between the two top model vendors, and steady consolidation in how agents talk to tools and to each other. The center of gravity moved away from raw model launches and toward the plumbing around the models. That is good news for anyone trying to plan a real product roadmap rather than chase the next benchmark.

There was no flashy new frontier model release in the past seven days. What landed instead were platform changes that will shape how teams build, deploy, and pay for AI for the rest of 2026. Google rebuilt its agentic coding tool, shipped a stable command-line interface for Android development driven by AI agents, and proposed a new open web standard. Anthropic crossed a business adoption milestone that would have been hard to predict a year ago. And the protocol layer that lets agents reach into tools and into each other kept maturing in the background.

The thread connecting all of it is straightforward. The interesting work is happening at the seams between agents, between coding tools, between models and the real world. Below is what changed and why it matters.

AI Coding Tools: Google Bets the Stack on Antigravity 2.0

Google held its annual I/O developer keynote on May 19 in Mountain View. The headline announcement for anyone who writes code for a living was Antigravity 2.0, a complete rebuild of the agentic coding platform Google launched in November 2025.

The original Antigravity shipped as a VS Code fork tuned for AI-assisted development. It looked a lot like Cursor, just with Gemini in the driver seat. The new version goes much further. Google now treats Antigravity as a brand for an entire family of tools rather than a single editor. Version 2.0 includes a redesigned desktop app focused on running multiple agents in parallel, a brand-new command-line tool written in Go, an SDK for building custom agents, and a Managed Agents service inside the Gemini API for cloud execution. TechCrunch reported that the new desktop application lets developers orchestrate parallel subagents, design custom workflows, and schedule tasks that run in the background.

The most dramatic demo came during the keynote itself. Google claimed Antigravity 2.0 built the core framework of a working operating system in about 12 hours, as reported by Digit. According to the company, the platform spawned 93 separate subagents during the task, processed billions of tokens, and finished the project for under $1,000 in compute. To prove the result worked, Google ran the classic game Doom on the AI-built OS during the keynote. Doom failed to launch at first because keyboard drivers were missing, so Google asked Antigravity to write the drivers live on stage. The game then ran.

That story is half marketing theater and half a real data point. The marketing part is obvious. The data point is the cost figure. A working OS framework for under a thousand dollars in compute, even with caveats, is a different unit economics conversation than building software was two years ago.

Google also signaled where its older free tool is heading. The Next Web reported that consumer access to Gemini CLI and the Gemini Code Assist IDE extensions will end on June 18, 2026, for AI Pro, AI Ultra, and free-tier users. Enterprise customers on Gemini Code Assist Standard or Enterprise licenses keep access. The message to consumer developers is direct. Move to Antigravity.

For Android developers specifically, Google released Android CLI 1.0 at the same event. TechCrunch’s coverage of Android CLI 1.0 explained that the toolset gives AI agents direct programmatic access to Android Studio’s capabilities from the terminal. The first version supports Claude Code, OpenAI Codex, and Antigravity. Agents can run semantic code analysis, render Jetpack Compose previews, detect warnings, and run automated UI tests without ever opening the IDE. Google also bundled Android CLI support directly into Antigravity 2.0 so the platform can take a project from creation through deployment to a virtual Android device.

This is a quiet but important admission. Google built its own coding platform but openly designed the Android tooling to work with competitors. The Android team apparently looked at what developers actually use day-to-day and decided to meet them where they were. That is a different posture than the one major platforms typically take when they ship developer tools.

The rest of the I/O coding lineup filled out the picture. Google launched the Gemini 3.5 Flash model as the engine behind its managed agents in the Gemini API. The company shipped native Android app creation inside AI Studio, where you can describe an app in plain language and preview it inside an integrated emulator. Google also debuted Android Bench, a benchmarking leaderboard that ranks AI coding models on Android-specific development tasks, with support for open-weight models like Gemma 4.

Now zoom out from Google for a moment. The competitive picture for AI coding tools looks different than it did six months ago. The New Stack reported that Cursor, Claude Code, and OpenAI Codex are converging into a layered stack rather than picking a single winner. A survey by the Pragmatic Engineer in February 2026 found that Claude Code had the highest “most loved” rating among 906 software engineers, with 46% naming it their favorite. SemiAnalysis estimated that Claude Code accounted for roughly 4% of all public GitHub commits as of March 2026, with projections suggesting that number could hit 20% by year-end.

Cursor still leads on the inline editing experience inside the IDE. Claude Code dominates the terminal and the agentic surface. Codex is gaining traction for asynchronous, long-running tasks that run in a cloud sandbox without developer attention. Codex passed 3 million weekly active users in March 2026, up from 2 million a month earlier. JetBrains research published in April 2026 showed that 90% of developers used at least one AI tool at work as of January 2026, with 74% using specialized AI development tools beyond chat. GitHub Copilot remained the most adopted at 29% workplace usage, with Cursor and Claude Code tied at 18%.

The takeaway for engineering leaders is practical. There is no single AI coding tool to standardize on. Teams are running two or three in different contexts. A typical setup might pair Claude Code in the terminal for agentic work, Copilot or Cursor inside the IDE for autocomplete and inline edits, and a chat interface for thinking through architecture. That setup did not exist as a recommendation last year. It is the default now.

AI Processing: TPUs, Custom Silicon, and the Cost Question Behind Antigravity’s Doom Demo

The hardware story this week was less about new chips and more about the math behind the demos. When Google said it built an operating system for under $1,000 in compute, the implicit follow-up question is what was running underneath.

That answer comes back to Google’s eighth-generation Tensor Processing Unit family. TechCrunch reported at Google Cloud Next in April that Google announced TPU 8t and TPU 8i, with the 8t built for training and the 8i for inference. The company claimed up to 3x faster AI model training versus previous generations, 80% better performance per dollar for inference, and the ability to link more than 1 million TPUs into a single cluster.

According to Google’s own AI infrastructure announcement, TPU 8i triples on-chip SRAM to 384 MB and increases high-bandwidth memory to 288 GB per chip. The chip doubles inter-chip interconnect bandwidth to 19.2 Tb/s and includes a dedicated Collectives Acceleration Engine that reduces on-chip latency by up to 5x. Those specs matter for one reason. They are tuned for the workload Antigravity 2.0 demonstrated on stage. Many agents running in parallel, each holding a large context window, calling tools, and emitting tokens fast enough to feel interactive.

The shift toward custom silicon is now the defining story in AI hardware. According to TrendForce data summarized by AIMultiple, custom ASIC shipments from cloud providers are projected to grow 44.6% in 2026, while GPU shipments are expected to grow 16.1%. The same report tracks the projection that ASICs will make up 40% of the AI inference market in 2026, up from 15% in 2024. Hyperscalers are no longer just buying NVIDIA. They are designing their own chips for their own workloads and using NVIDIA in parallel.

Anthropic illustrates the multi-platform pattern more clearly than any other model vendor. Anthropic announced plans to expand its use of Google Cloud technologies up to one million TPUs, an expansion worth tens of billions of dollars that should bring over a gigawatt of capacity online during 2026. Anthropic also remains committed to Amazon Trainium as its primary training partner and continues to use NVIDIA GPUs. The company is one of the few customers running serious workloads on all three platforms simultaneously.

There was a quiet hardware story tucked inside the Anthropic news this week as well. Digitimes reported on May 20 that Anthropic hired a high-profile AI researcher with a background at OpenAI and Tesla to accelerate Claude pretraining research. The same article noted a fresh compute rental agreement to support the work. Tying that to the May 6 Anthropic announcement of a compute deal with SpaceX and the earlier $200 million Gates Foundation partnership announced on May 14, the pattern is clear. Anthropic is locking in compute capacity across multiple vendors and multiple physical sites as fast as it can sign deals.

The cost question that follows from all of this is the one every engineering organization is now wrestling with. AI workloads have lost their flat-rate pricing tier. InfoWorld reported on May 14 that Anthropic will separate programmatic Claude usage from standard chat subscription limits beginning June 15. The new policy creates a dedicated monthly credit pool for tools like the Agent SDK, GitHub Actions, and third-party frameworks such as OpenClaw. Pro users get $20 in programmatic credits, Max 5x users get $100, and Max 20x users get $200, billed at API-style rates.

Greyhound Research Chief Analyst Sanchit Vir Gogia, quoted in the InfoWorld piece, called this a broader industry transition rather than an Anthropic-specific move. GitHub is moving Copilot toward a token and credit system. OpenAI has always charged usage-based pricing for API access. The era of unlimited agentic AI on a flat $20 subscription is ending. That has real implications for how teams budget. A coding agent that runs tests continuously, browses the web, and calls models recursively can burn through token budgets in ways that human prompting never did. Two large companies, ServiceNow and Uber, reportedly burned through their AI token budgets for the entire year before the year was even half over.

Standards and Protocols: WebMCP, A2A v1.2, and the Layer Cake

The most consequential announcement at I/O for the long-term shape of the web may have been the one that got the least attention. Google introduced a proposed open standard called WebMCP, short for Web Model Context Protocol.

WebMCP was originally announced as a W3C Draft Community Group Report on February 10, 2026, co-developed by Google and Microsoft. Discovered Labs explained that WebMCP is a browser-native standard that lets AI agents interact with websites through structured tools rather than screen scraping. Until now, AI agents had two ways to interact with a website. They could take screenshots and read the text visually, which is slow and brittle. Or they could call backend APIs through the original Model Context Protocol, which requires server-side cooperation that most websites do not provide.

WebMCP adds a third path. Websites publish a structured list of actions, called a Tool Contract, that the page can perform. An AI agent reads the list and calls the actions directly. There is no guessing, no clicking around blindly. A travel booking site might expose a searchFlights tool. A real-estate site might expose a filterListings tool. The protocol is exposed through navigator.modelContext in the browser, with both a declarative HTML-attribute version for static content and an imperative JavaScript version for dynamic interactions.

The reason this matters more than it might look on the surface is what it implies about how AI traffic will flow on the web. Search Engine Land’s 2026 SEO predictions, quoted in the same Discovered Labs analysis, put it plainly. “In 2026, SEO becomes two jobs: driving clicks from humans and supplying clean, trusted inputs for AI agents that may never visit your site.” That changes the calculus for every business that depends on web traffic. If your site cannot be parsed by an AI agent, your pricing, features, and availability become invisible to buyers researching vendors through Gemini, Claude, or ChatGPT.

Chrome 146 Canary is the only browser supporting WebMCP behind a flag as of writing. Stable Chrome support is expected around March 2026 according to industry reporting, though Google has not officially confirmed the timeline. Microsoft Edge support is expected. Firefox and Safari have not announced plans.

The other half of the agent protocol story moved forward this week as well. The Agent2Agent protocol, the open standard for getting agents from different vendors to talk to each other, kept gaining traction. According to The Next Web’s coverage of Google Cloud Next 2026 in April, A2A has reached production deployment at 150 organizations, including Microsoft, AWS, Salesforce, SAP, and ServiceNow. The protocol is now governed by the Linux Foundation’s Agentic AI Foundation and is at version 1.2, with cryptographically signed agent cards for domain verification.

A2A and MCP are complementary, not competing. MCP handles the connection between an agent and the tools or data sources it needs. A2A handles the conversation between two agents that might be running on completely different platforms. A Salesforce agent built on Agentforce can hand off a task to a Google Vertex AI agent, which can query a ServiceNow agent for IT asset data, all through A2A. None of the three systems needs to understand the others’ internal architecture. They just need to speak the same wire protocol.

Native A2A support is now built into Google’s Agent Development Kit, LangGraph, CrewAI, LlamaIndex Agents, Semantic Kernel, and AutoGen. The Agent Development Kit hit stable 1.0 across Python, Go, and Java, with TypeScript also available. The active GitHub repositories tell the story. The Java SDK, JavaScript SDK, and Python SDK all had commits as recently as May 18-19 of this week.

The protocol stack for agents is starting to look stable enough to build against. MCP for tool access. A2A for inter-agent collaboration. WebMCP for browser-based agent action. Each handles a different layer of the problem, and each is governed by an open foundation rather than a single vendor. That last point is the one to pay attention to. The protocols that won past internet platform shifts were the ones that no single company controlled.

Anthropic Crosses Over: A Quiet Inflection in Enterprise AI

One of the most significant signals of the week was a number rather than a product launch. TechTimes reported on May 15 that more US businesses paid for Anthropic’s Claude than for OpenAI’s ChatGPT in April 2026, according to the May 2026 Ramp AI Index. It was the first time in the AI industry’s short history that Anthropic held the top position by paid business subscriptions.

The Ramp data has methodological caveats worth noting. The sample skews toward tech-forward, venture-backed companies that lean toward Anthropic’s developer-first products. The index measures paid subscriptions, not usage intensity, and likely undercounts free-tier and enterprise-contract use. An OpenAI spokesperson told Axios that the Ramp methodology may underweight invoiced six- and seven-figure enterprise contracts where customers do not pay with a credit card. OpenAI has said it expects to generate more revenue than Anthropic in 2026.

That said, two pieces of evidence corroborate the trend. OpenRouter’s leaderboard, which samples a different population of users, last ranked OpenAI above Anthropic in December 2025. And Anthropic’s own business numbers have been growing fast enough that the company projected 10x revenue growth over a recent period and instead saw annualized growth of roughly 80x in a single quarter, according to CEO Dario Amodei’s remarks at the company’s May 5 financial services briefing.

The engine behind the climb has a single name. Claude Code. The product accounts for a meaningful share of Anthropic’s revenue and growth, with SemiAnalysis estimating $2.5 billion in annualized run rate as of February 2026 and business subscriptions quadrupling between January 1 and the spring.

OpenAI is not standing still. On May 11, the company launched the OpenAI Deployment Company, a standalone unit backed by more than $4 billion from 19 private equity firms, consultancies, and systems integrators including TPG, Bain Capital, Goldman Sachs, Capgemini, and McKinsey. The unit will place Forward Deployed Engineers directly inside client organizations to redesign workflows around AI, borrowing the model that made Palantir successful in government and applying it to frontier AI at unprecedented scale.

Anthropic also expanded its own enterprise distribution this week and last. The company announced its acquisition of Stainless on May 18, a tooling company that builds SDKs for API providers. On May 19, Anthropic announced a strategic alliance with KPMG that integrates Claude across KPMG’s core business and workforce of more than 276,000 employees. The week before, the company announced PwC was deploying Claude to build technology, execute deals, and reinvent enterprise functions for clients.

The pattern across both vendors is the same. The center of AI revenue is moving from consumer subscriptions to enterprise contracts. Both companies are racing to lock in distribution through the largest consulting and integration firms in the world. The economics of consumer AI subscriptions are not strong enough to fund frontier model training. Enterprise contracts are.

One human-interest detail from the week is worth mentioning because of what it says about talent flows. Andrej Karpathy, the OpenAI co-founder who later founded the education startup Eureka Labs, joined Anthropic’s pretraining team. Anthropic also hired cybersecurity expert Chris Rohlf to join its frontier red team, which tests advanced AI models for potential security threats. Researchers move between frontier labs constantly. The Karpathy hire is notable because it lands at exactly the moment Anthropic crossed Ramp’s adoption threshold.

What to Watch Next Week

A few specific things to track in the coming days. The Claude Opus 4.7 Fast mode research preview, announced in late April, is rolling out to more developers. Fast mode supports significantly faster output token generation at premium pricing for the same task quality. If you have been waiting to deploy agentic workflows that need lower latency, the waitlist is open.

The June 15 transition of Claude programmatic usage to its new credit-based meter is the next big pricing inflection. Teams running CI pipelines, scheduled automations, or long-running coding agents on Claude subscriptions should benchmark their token consumption now while the current model is still in place. Forecasting becomes much harder once usage is tied directly to token consumption rather than subscription tier.

The Antigravity 2.0 enterprise rollout is the wildcard. Google priced its top tier at $100 per month, putting it in roughly the same range as Anthropic’s Max plan and OpenAI’s premium tiers. The question is whether enterprise developers actually adopt it. Google has historically struggled to displace incumbent developer tools even when its underlying technology was strong. The fact that the company is killing Gemini CLI rather than letting it coexist with Antigravity suggests Google believes the parallel-agent thesis enough to force the migration.

And on the standards side, watch for WebMCP adoption signals from publishers. Search Engine Land’s framing turns out to be the right one. If 2026 is the year SEO splits into a human track and an agent track, the sites that publish Tool Contracts first will own a disproportionate share of the agent track. That is a lot like the early days of structured data and schema.org markup, except the upside is bigger and the time window is shorter.

The thread running through every single one of these stories is integration over isolation. The most valuable work in AI right now is not building a better model in a vacuum. It is connecting the model to the tools, to the other agents, to the websites, to the codebases, and to the people who actually do the work. That is a less glamorous story than the next billion-parameter benchmark, and it is the one that will define the year.

A Few More Things Worth Flagging

A handful of smaller items from the week deserve a mention.

Anthropic published a piece this week explaining why Claude will remain ad-free. The argument is that advertising incentives are structurally incompatible with a genuinely helpful AI assistant. The post lays out how the company plans to expand access without compromising user trust. That is a deliberate stance in a market where every other consumer software category eventually monetizes through ads. The company seems to be betting that enterprise revenue will be large enough to fund frontier research without consumer ad dollars. That bet ties directly back to the Ramp adoption data.

The Anthropic acquisition of Stainless deserves more than a passing mention as well. Stainless is the tooling company behind the SDK generators that several large API providers use. Bringing that capability in-house gives Anthropic tighter control over the developer experience for Claude APIs across every major programming language. SDK quality is one of those things developers rarely talk about directly but always notice. If the Python SDK feels rough, you reach for the competitor. Anthropic just bought a moat in that specific dimension.

On the open source side, the parallel-agent pattern that Antigravity 2.0 showed off is starting to show up in other tools as well. Cursor shipped its Agents Window in early April. The Pragmatic Engineer survey showed developers running two and three AI tools side by side. The shape of the workflow is converging toward something like an air traffic controller view of multiple agents, each working on a different piece of the same project. The interesting question is which tool ends up being the controller versus which ones are the planes. Right now most teams use a terminal-native agent like Claude Code as the controller and use Codex or Cursor for specific subtasks. That pattern is not stable. It will likely change again before the year is out.

One more thing worth tracking. The Ramp index covered April 2026. May will be the first full month after the Anthropic policy change separating programmatic usage. If business adoption holds or grows after the credit-meter change goes into effect, it will be a meaningful signal that the new pricing model does not break enterprise adoption. If it drops, it tells us the price elasticity of agentic AI usage is higher than vendors think. That number will land in early July when Ramp publishes the next index. It is one of the few data points that cuts through marketing claims on both sides.

Resources to Go Further

The AI landscape changes fast. Here are tools and resources to help you keep pace.

Try Dremio Free – Experience agentic analytics and an Apache Iceberg-powered lakehouse. Start your free trial

Learn Agentic AI with Data – Dremio’s agentic analytics features let your AI agents query and act on live data. Explore Dremio Agentic AI

Join the Community – Connect with data engineers and AI practitioners building on open standards. Join the Dremio Developer Community

Book: The 2026 Guide to AI-Assisted Development – Covers prompt engineering, agent workflows, MCP, evaluation, security, and career paths. Get it on Amazon

Book: Using AI Agents for Data Engineering and Data Analysis – A practical guide to Claude Code, Google Antigravity, OpenAI Codex, and more. Get it on Amazon

Struggling with Twilio Voice Call Integration in Flutter? twilio_voice_flutter Solves It!

The twilio_voice_flutter plugin simplifies integration with Twilio’s Programmable Voice SDK, enabling VoIP calling within your Flutter apps. It supports both iOS and Android, offering an easy-to-use API for managing calls. Ideal for customer service, communication, or any app needing real-time voice, it leverages Twilio’s reliable infrastructure to deliver high-quality VoIP features.

Getting started
Add dependency to your pubspec.yaml file & run Pub get

dependencies:
  twilio_voice_flutter: ^0.0.3

And import package into your class file

import 'package:twilio_voice_flutter/twilio_voice_flutter.dart';

Important Note
⚠️ This plugin requires Firebase setup for Twilio voice calls! It uses FCM tokens for handling calls on Android 📲 and VoIP notifications for iOS 📞. Ensure both platforms are properly configured for smooth call functionality. ⚠️

Platform Setup
Android
To integrate the Twilio Voice plugin into your Android project, follow these steps:

Open your project’s AndroidManifest.xml file.
Add the following service declaration inside the tag:

<application>
    ...
    <service
        android:name="com.twilio.voice.flutter.fcm.VoiceFirebaseMessagingService"
        android:exported="false"
        android:stopWithTask="false">
        <intent-filter> 
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter> 
    </service>
    ...
</application>

iOS
To configure your iOS project to support VoIP calls, follow these steps:

Open your project in Xcode.
Select your project from the Project Navigator.
Go to the Signing & Capabilities tab.
Enable the following Background Modes:
Audio, AirPlay, and Picture in Picture: Allows your app to continue playing audio while in the background.
Voice over IP: Enables your app to receive incoming VoIP calls while in the background.
Ensure that your Info.plist file includes the required keys:

<key>UIBackgroundModes</key>
<array>
    <string>audio</string>
    <string>voip</string>
</array>

🔑 Twilio Voice Call Access Token Setup
This plugin supports Twilio voice calls for both Android and iOS. To generate the access token and enable Twilio calls, follow the steps in the official Twilio repositories:

https://github.com/twilio/voice-quickstart-android
https://github.com/twilio/voice-quickstart-ios

These repositories provide detailed instructions for generating access tokens and making voice calls through Twilio on both Android and iOS platforms. ⚡ Make sure to follow the steps outlined to successfully integrate Twilio voice functionality into your application.

Setting Up Twilio Token
The setTwilioToken function is used to register a user’s identity with Twilio Voice using the provided access token. This function handles the retrieval of the Firebase Cloud Messaging (FCM) token on Android devices and registers the user with Twilio Voice.

static Future<bool> setTwilioToken(String identity, String accessToken) async {
    try{
      String accessToken = await _getAccessToken(identity);
      if (Platform.isAndroid) {
        String? fcmToken = await FirebaseMessaging.instance.getToken() ?? "";
        await TwilioVoiceFlutter.register(
            identity: identity, accessToken: accessToken, fcmToken: fcmToken);
      } else {
        await TwilioVoiceFlutter.register(
            identity: identity, accessToken: accessToken, fcmToken: "");
      }
      return true;
    }catch(_){
      return false;
    }
}

🔗 Visit example for more info… 😊

Features
The Twilio Voice Plugin for Flutter enables seamless integration of voice-over-IP (VoIP) calling into your Flutter applications. Below are the key features supported by this plugin:

1. VoIP Call Management
Initiate Calls: Easily start a VoIP call to any recipient using the makeCall method, with the ability to pass custom call data.

Initiate Calls: Easily start a VoIP call to any recipient using the makeCall method, with the ability to pass custom call data.
Receive Incoming Calls: Handle incoming call invites via push notifications, and answer calls using built-in CallKit support on iOS.
Call Status Notifications: Stay updated on call status changes such as ringing, connecting, and disconnecting through Flutter MethodChannel callbacks.

2. In-Call Controls
Mute/Unmute Calls: Toggle the mute status of the ongoing call using the toggleMute method. Check if the call is currently muted with the isMuted method.
Speakerphone Control: Switch between the device’s built-in speaker and receiver during an ongoing call using toggleSpeaker. Verify the current audio route with isSpeaker.

3. CallKit Integration for iOS
CallKit Support: Utilize native CallKit functionality on iOS for managing incoming and outgoing VoIP calls, ensuring a familiar user experience.
Incoming Call Handling: Report incoming calls to CallKit, allowing the system to display the native call UI and handle interruptions correctly.
Background VoIP Support: Ensure your app can receive VoIP calls while in the background by enabling the necessary background modes and configuring the Info.plist accordingly.

4. Push Notification Support
VoIP Push Notifications: Register and handle VoIP push notifications via Firebase Cloud Messaging (FCM) on Android and Apple Push Notification service (APNs) on iOS.
Push Credential Management: Manage device and access tokens required for receiving VoIP push notifications, ensuring reliable communication.

5. DTMF (Dual-tone Multi-frequency) Signaling
Send DTMF Digits: During an active call, send DTMF tones (e.g., for interacting with automated phone systems) using the sendDigits method.

6. Contact Management
Custom Contact Data: Store and retrieve custom contact data (like display names and photo URLs) to enhance the calling experience with personalized information.

7. Persistent Data Storage
Token and Contact Data Persistence: Securely store and retrieve access tokens and contact data using UserDefaults on iOS to maintain state across app sessions.

8. Call Handling with Error Management
Graceful Error Handling: Comprehensive error handling ensures that issues like token expiration or failed call connections are managed and reported to the user effectively.
With these features, the Twilio Voice Plugin provides a robust foundation for integrating voice communication into your Flutter applications, supporting a wide range of use cases from customer support to in-app

Function Overview
registerTwilio(): Registers the device with Twilio using the access token and device token for VoIP push notifications.
unregisterTwilio(): Unregisters the device from Twilio VoIP push notifications, removing the access token and device token.
makeCall(String to): Initiates a voice call to the specified recipient. If an active call exists, it returns an error.
toggleMute(): Toggles the mute status of the ongoing call. Notifies the Flutter side of the change.
isMuted(): Returns the current mute status of the ongoing call.
toggleSpeaker(): Toggles the speaker mode during an ongoing call. Notifies the Flutter side of the change.
isSpeaker() -> Bool: Checks if the speaker mode is currently active.
hangUp(): Ends the current call. If no active call exists, it clears the call-related data.
activeCall(): Returns details of the active call if one exists.
sendDigits(String digits): Sends DTMF digits during an active call.
For more information, check out the below link

twilio_voice_flutter | Flutter package


twilio_voice_flutter | Flutter package

Voice SDK to allow adding voice-over-IP (VoIP) calling into your Flutter applications.

favicon
pub.dev

Thanks for reading! If this post was helpful, feel free to share it and follow for more Flutter tips and tutorials. Keep coding and stay awesome!

Curing ‘Blank Canvas Paralysis’ with 1-Click Templates (DeskFlow Update)

I’m building DeskFlow, a visual canvas tool for planning desk setups and routing cables.

Recently, I noticed a huge UX friction point: Blank Canvas Paralysis. When users first open the app and stare at a massive, empty dark grid, it’s intimidating. Dragging out nodes one by one, connecting the ports, and organizing the layout from scratch requires too much upfront cognitive load.

To fix this, I just shipped a Setup Templates feature.

The Solution: Starter Kits

Instead of forcing users to start from zero, I built a feature that instantly loads fully wired, highly realistic desk configurations with a single click.

Users can access this via the grid icon in the top right.

I launched with 3 core templates:

1. Home Office
The classic clean setup. A MacBook Air connected to a Thunderbolt Hub, routing out to a 4K monitor, mechanical keyboard, and an MX Master mouse. It shows users exactly how a single-cable hub setup should look.

2. Gaming Station
For the console hoarders. This template wires a PS5, Xbox Series X, Steam Deck, and Nintendo Switch into a single OLED TV, perfectly managing the HDMI port distribution.

3. Creator Studio
A heavy-duty layout featuring a Mac Studio, 4K monitors, Cam Link, a Blue Yeti mic, and a Stream Deck.

Why this works

It turns a daunting creation task into a simple editing task. Users load a template that closely resembles their goal, and then simply tweak it—swapping out a mouse, deleting a monitor, or adding a docking station.

As a bonus, loading a template instantly auto-populates the Shopping List panel with all the necessary cables and estimated costs.

🔗 Try loading a template here: https://deskflow-gold.vercel.app

If you are building a canvas or whiteboard-based app, I highly recommend adding pre-built templates early on. It dramatically improves the “Aha!” moment for new users.

Apache Data Lakehouse Weekly: May 13-20, 2026

This was a release-heavy week across the lakehouse projects. Iceberg pushed 1.11.0 through a fourth release candidate while shipping a 1.10.2 patch in parallel. The V4 spec discussion accelerated with two simultaneous votes on content stats and relative paths. The Iceberg Go client kicked off a 0.6.0 vote. Parquet held a vote on format changes for IEEE 754 total order semantics and stood up a brand-new Footer Working Group. Arrow released ADBC 23 and Arrow 24.0.0, and the community spent serious time debating donation of an Erlang implementation and dictionary-encoded extension types. Polaris was relatively quiet on the dev list after its 1.4.1 patch went out on May 1, but the community continued discussions around catalog federation and the path to 1.5.0.

The connecting theme this week was format evolution under pressure. Iceberg V4 is no longer a far-off design exercise. Specific votes are landing. Parquet is restructuring how the format committee handles its most fundamental data structure, the footer. Arrow is grappling with whether to expand its extension type system to handle increasingly complex use cases coming from the engines that depend on it. These projects are all making decisions now that engines and storage providers will have to live with for years.

Apache Iceberg

The big story on the Iceberg dev list this week was the simultaneous push on three different release tracks and two V4 spec votes that ran in parallel. The community is moving fast.

Aihua Xu opened the Iceberg 1.11.0 RC4 vote after several prior release candidates surfaced issues that needed fixes. Binding +1 votes came in from Russell Spitzer, Eduard Tudenhöfner, Amogh Jahagirdar, and Kevin Liu, along with non-binding +1s from Steven Wu, huaxin gao, Yufei Gu, Jean-Baptiste Onofré, Yuya Ebihara, Neelesh Salian, Andrei Tserakhau, and Bryan Keller. The discussion threaded through environment-specific test failures and a few late patches that had to be cherry-picked to the release branch. Aihua handled multiple status updates and the eventual successful close. Going from RC1 in late April to RC4 in mid-May suggests this release had more friction than the team would have liked, but the spread of binding voters across companies is the right signal for a healthy major release.

While 1.11.0 was working through its final candidate, Amogh Jahagirdar shepherded the 1.10.2 patch release. He kicked off the Apache Iceberg 1.10.2 RC1 vote and collected +1s from Russell Spitzer, Kevin Liu, Yufei Gu, huaxin gao, Yuya Ebihara, Aihua Xu, Neelesh Salian, roryqi, and Eduard Tudenhöfner before announcing the release of 1.10.2 midweek. Kevin Liu confirmed the announcement. The fact that the project can run a 1.10.x patch release and a 1.11.0 major release in parallel reflects the maturity of the release infrastructure that the community has built over the past year. Two years ago, a parallel release would have been hard to coordinate. Now it is routine.

The V4 spec is where the more consequential work happened. Daniel Weeks opened the vote on relative paths in v4, drawing immediate engagement from Amogh Jahagirdar, Anoop Johnson, Anurag Mantripragada, Alex Stephen, Gang Wu, roryqi, Fokko Driesprong, Andrei Tserakhau, and Junwang Zhao. Relative paths are one of those structural changes that look small in the spec but have major implications for portability. Tables written with relative paths can be moved between buckets, regions, or storage backends without rewriting every manifest. For organizations running disaster recovery or migrating clouds, this is a real operational improvement. The volume of votes in the first few days of the thread suggests broad community support.

Running in parallel, Eduard Tudenhöfner opened the vote on Content Stats representation in v4. Russell Spitzer, Talat Uyarer, Wing Yew Poon, Steven Wu, Amogh Jahagirdar, and Daniel Weeks all participated, and Eduard followed up with two additional status messages. Content stats matter because they directly affect query planning. Better stats let engines prune more aggressively, which means lower scan costs and faster queries. Getting the representation right in the format means every engine that supports v4 gets the same benefit.

Ryan Blue stepped back into the dev list with a proposal to add an unregister table endpoint to the REST spec. The thread drew responses from Russell Spitzer, Ajantha Bhat, Péter Váry, Jean-Baptiste Onofré, Yufei Gu, Amogh Jahagirdar, Steven Wu, Neelesh Salian, Daniel Weeks, and Steve Loughran. Today, removing a table from a catalog without dropping the data is awkward. Some catalogs treat it as drop with delete-data-false. Others have custom endpoints. Adding a standard unregister operation to the REST spec means every Iceberg client gets the same behavior regardless of catalog implementation. That is the kind of cleanup work that does not generate headlines but pays off for every operator who has ever had to migrate tables between catalogs.

Prashant Singh proposed a closely related change with the addition of an X-Iceberg-Client-Capabilities header to the REST spec. Sung Yun and Daniel Weeks weighed in. Client capability negotiation is the kind of protocol detail that becomes critical as the ecosystem grows. A REST catalog needs to know what features a calling client supports before deciding which response shape to return. Without a header like this, the catalog ends up either returning the lowest common denominator or breaking older clients. The Iceberg REST spec is starting to look a lot like the HTTP spec did in its early years, with each iteration filling in the practical details that come up only in production deployments.

On the language client side, Matt Topol opened the Iceberg Go 0.6.0 RC0 vote. Andrei Tserakhau, Neelesh Salian, Kevin Liu (three messages), Tanmay Rauth, and Gang Wu joined the thread. Iceberg Go has been quietly building up steady momentum as a serious alternative for tools that do not want a JVM dependency. The release cadence is consistent. Each version closes more of the gap with the Java reference implementation. The number of new contributors voting on releases is one of the better signals of a healthy language client community.

Anurag Mantripragada continued his work on column-level updates with a new proposal for column update file representation. Gang Wu replied with feedback. Efficient column updates are one of the few remaining gaps in Iceberg’s update story. The V4 design work is reportedly opening up new possibilities for handling updates without rewriting entire data files. This thread is one to watch closely as V4 work continues.

A few other discussions worth flagging. Kevin Liu raised a spec ambiguity question on the Avro schema for the day partition transform fields in manifests. These ambiguity threads tend to come from someone trying to implement Iceberg in a new language and running into edge cases the original Java implementation glossed over. Resolving them in the spec means every future implementation gets the same answer.

Steven Wu’s vote on adding the CatalogObjectIdentifier schema to OpenAPI drew responses from Yufei Gu, Russell Spitzer, huaxin gao, Christian Thiel, Alexandre Dutra, Jean-Baptiste Onofré, Steve, Ajantha Bhat, Daniel Weeks, Renjie Liu, and Péter Váry. Long thread, many committers engaged. The Iceberg REST OpenAPI specification is where a lot of the standardization work between catalog implementations actually happens. When Polaris, Lakekeeper, and other REST catalogs all agree on the same OpenAPI shape, multi-engine interoperability gets easier for everyone.

Henry Haiying Cai posted a Kafka Connect discussion thread on worker coordinator progress detection. Kafka Connect remains an under-discussed but heavily used piece of the Iceberg ecosystem, and ongoing reliability work there matters for streaming ingestion pipelines.

The bottom line on Iceberg this week. The project shipped a patch release, drove a major release through a final candidate, opened two V4 spec votes, ran a Go client release vote, and discussed standards-level REST changes. That is a sustained pace of work that very few open source data projects can match.

Apache Polaris

Polaris had a quieter week on the dev list than usual, which is the expected pattern after a release. Apache Polaris 1.4.1 shipped on May 1 as a patch release on the 1.4.0 line that came out April 21. The 1.4.1 patch addressed storage URI handling and a few smaller fixes. The release cadence for the Polaris community has settled into a roughly monthly minor or patch release with quarterly major versions, which is a sustainable pace for a project that graduated from the Apache Incubator only in February.

The graduation context is worth keeping in mind when looking at this week’s activity. Polaris is now an Apache Top-Level Project rather than a podling. That means the project’s governance and infrastructure operate under the full Apache umbrella, with its own PMC and direct relationship with the Apache board. The transition has not changed the day-to-day cadence on the dev list, but it has changed what kinds of discussions happen. Release voting no longer needs IPMC approval. PMC member additions and committer promotions happen through the project’s own process. The community has fewer process gates to work through. That tends to translate into faster feature iteration over time.

The 1.4.0 release that landed in late April was substantive. It introduced granular control over how Polaris interacts with cloud storage, enabling multi-tenancy with support for separate encryption keys and IAM identities across catalogs. Iceberg metrics persistence to the Polaris database moved from preview to stable, giving operators a way to capture ScanReports and CommitReports directly without piping them through an external metrics system. The Helm chart picked up a JSON schema for validation of values files, which is the kind of detail that turns out to matter a lot when you are trying to operationalize the catalog at scale.

Catalog federation continues to be one of the most-discussed areas of the Polaris codebase even when there is not a specific dev list thread driving it. Federation lets a single Polaris instance act as a routing layer for tables that live in other Iceberg REST catalogs, Hive Metastores, or other systems. For organizations consolidating multiple catalog sources without forcing a big-bang migration, federation is the answer. The 1.4 release built on the federation work from 1.1 and 1.2, adding extension points that make it easier to add new catalog types without rewriting the core federation logic.

The path to Polaris 1.5.0 is starting to take shape based on signals from the broader community. Generic tables, which let Polaris manage non-Iceberg formats like Delta Lake and Hudi through a unified catalog interface, are likely to see additional polish in the next release. Open Policy Agent integration for external authorization will continue to mature. And the work on persisting events to multiple backends, which arrived in preview form in 1.2 and was expanded in 1.4, is one of those features that turns the catalog into a real source of operational truth for governance teams.

Worth noting for Polaris watchers. The Snowflake engineering blog published a detailed analysis of the 1.4 release that covers the security and metrics work in more depth. The Dremio blog also covered Polaris’s positioning as the catalog standard for Iceberg lakehouses and agentic analytics, framing how the catalog layer connects to AI agents that need to query and act on lakehouse data.

The pattern across both pieces is that Polaris is being positioned not just as an Iceberg catalog but as the governance and discovery layer for the lakehouse as a whole. That framing has implications for what gets prioritized in the next release. Features that help AI agents discover tables, understand schemas, and reason about data quality become first-class citizens. Features that help human governance teams manage policy, audit access, and trace data lineage become equally important. The dev list has not yet had the formal proposal threads for these features, but the trajectory is clear from the community discussions and from how vendors building on Polaris are talking about the project.

Apache Arrow

The Arrow dev list was as busy as it usually is. Arrow handles releases on a different cadence than Iceberg or Polaris, with multiple sub-projects releasing on their own schedules under the same project umbrella. This week saw release votes on multiple Rust crates, .NET, Go, and the main monorepo.

Andrew Lamb opened the Arrow Rust 58.3.0 RC1 vote, the Arrow Rust 57.3.1 RC1 vote, and the Arrow Rust 56.2.1 RC1 vote within a few days of each other. Three concurrent patch and minor releases across three different version lines is unusual even for arrow-rs, which has a famously fast release cadence. Ed Seidl, Bryce Mecum, Raúl Cumplido, and L. C. Hsieh voted on multiple of the threads. All three votes passed and the releases shipped. Arrow Rust is now on a release cycle measured in days rather than weeks, which means downstream projects that depend on it have to think harder about how aggressively they pin versions.

The DataFusion Python Bindings 31.0.0 vote also closed earlier in the period, continuing the steady release pace on the DataFusion side of the Arrow project. DataFusion is increasingly the engine of choice for new analytical tools built in Rust, and its release cadence reflects that. Every release pulls more contributors in and adds more SQL surface area.

The donation discussions on the dev list this week were the most interesting strategic signals. Sutou Kouhei opened the vote to donate Apache Arrow Erlang, drawing responses from Benjamin Philip, Curt Hagenlocher, Matt Topol, and David Li. Erlang is a language used heavily in telecom, distributed systems, and high-availability backend services. Adding an official Arrow implementation for Erlang opens up zero-copy data exchange for systems built on the BEAM virtual machine. The discussion was constructive, with Benjamin Philip following up on grant document specifics over several messages.

In parallel, Rok Mihevc opened the vote to donate pyarrow-stubs to Apache Arrow. Antoine Pitrou, Dewey Dunnington, Matt Topol, Raúl Cumplido, Nic Crane, Adam Reeve, Ian Cook, David Li, Sutou Kouhei, Alenka Frim, Jacob Wujciak, Joris Van den Bossche, wish maple, and L. C. Hsieh all participated. PyArrow stubs are the Python type annotations that IDEs and type checkers use to give developers autocomplete and error checking when they write code against pyarrow. The fact that this was a community project being formally donated to Arrow shows how much the broader Python ecosystem depends on these stubs, and how the community has stepped up to maintain them.

Dewey Dunnington opened an IPC representation discussion for dictionary-encoded extension types. Antoine Pitrou and Matt Topol joined. Extension types are one of those features that look niche on the surface but matter enormously in practice. They let Arrow carry domain-specific type information like geographic coordinates, UUIDs, or fixed-precision decimals without breaking interoperability with consumers that do not understand the extension. Combining extension types with dictionary encoding is technically tricky, and getting the IPC representation right means downstream engines can handle these types correctly when they cross network or process boundaries.

Antoine Pitrou opened a similarly foundational discussion with the question of whether to restrict field, schema, and custom metadata to UTF-8. Rusty Conover, Raphael Taylor-Davies, and Dewey Dunnington responded. This is the kind of spec question that has to be answered very carefully because the answer affects every existing Arrow implementation. Most production code already treats this metadata as UTF-8 in practice, but the format does not explicitly require it. Tightening the spec to match practice is good cleanup work.

Raúl Cumplido announced Apache Arrow 24.0.0 after passing the vote. The release includes work across the C++, Python, R, and Java implementations. The Arrow monorepo has slowed its release cadence to roughly once per quarter while the language-specific implementations like Rust, Go, and .NET release on their own schedules. The split-cadence approach lets the fast-moving language implementations ship features without being held back by the rest of the project, while the monorepo releases provide stable points for the C++ ecosystem to build against.

David Li announced Apache Arrow ADBC 23. ADBC, the Arrow Database Connectivity standard, continues to gain traction as an Arrow-native alternative to ODBC and JDBC. The release notes were not detailed in the announcement but the steady cadence speaks for itself. ADBC drivers exist for an increasing number of databases, and the API is stabilizing.

A few smaller items rounded out the week. Curt Hagenlocher announced Apache Arrow .NET 23.0.0 after the RC0 vote passed. Matt Topol announced Apache Arrow Go 18.6.0. Tornike Gurgenidze opened a thoughtful discussion thread on an ADBC Partitioned Bulk Ingest API with a response from Curt Hagenlocher. Dan Mattheiss proposed AVX2 optimization work for the parquet bloom filter with responses from Antoine Pitrou and wish maple. Antoine Pitrou announced an in-person Arrow and Parquet meetup in Paris. And Jarek Potiuk opened a discussion about Arrow involvement in the Community Over Code Glasgow 2026 hackathon, with positive responses from Nic Crane, Antoine Pitrou, Raúl Cumplido, and Jean-Baptiste Onofré.

The state of Arrow remains strong. The project has the broadest contributor base of any of the four projects covered here, with regular contributions across roughly a dozen languages and multiple sub-projects. The release management work that Raúl Cumplido and Sutou Kouhei handle quarter after quarter is the unsung infrastructure that makes the whole ecosystem function.

Apache Parquet

Parquet had the most consequential governance moment of the week. Jiayi Wang announced the kickoff of the Parquet Footer Working Group. Raúl Cumplido joined the discussion, and Jiayi followed up. The Parquet footer is the central metadata structure in every Parquet file. It tells readers what columns exist, what their types are, where the row groups live, what statistics are available, and how the data is encoded. Anything that changes the footer changes Parquet itself.

Standing up a formal working group for the footer signals that the community sees a need for structured discussion on what the footer should evolve into. Recent threads on the dev list reinforce this. Divjot Arora opened a discussion on Parquet Footer Options. Daniel Weeks proposed support for non-contiguous pages in Parquet, drawing extensive responses from Andrew Bell, Adrian Garcia Badaracco, Micah Kornfield, Will Edwards, and Andrew Lamb. Steve Loughran raised concerns about hardening variant readers, and Antoine Pitrou responded. Each of these threads touches the footer in some way. A working group with a defined scope and charter is a reasonable way to handle a body of work that big.

Gang Wu opened the vote on PARQUET-2249, the format change for IEEE 754 total order and NaN counts. Micah Kornfield, Steve Loughran, and Ed Seidl voted. Total order and NaN handling are exactly the kind of numerical correctness issues that lurk in floating-point data for years until they cause a query to silently produce wrong answers. Resolving them at the format level means engines do not have to invent their own conventions, and means data that crosses engine boundaries behaves predictably.

Russell Spitzer opened an automated release discussion for Parquet. Arnav Balyan, Gang Wu, and Fokko Driesprong all joined. Release automation is the kind of internal project that pays off every release cycle. Polaris went through a similar automation push last year and now releases on a much more predictable cadence as a result. The Parquet project handling its own automation thread suggests the community is ready to move from the artisanal release model to something more repeatable.

Gang Wu announced the release of Apache Parquet Java 1.17.1 after the RC0 vote passed. The release passed binding votes from Steve Loughran, Fokko Driesprong, Russell Spitzer, Daniel Weeks, and Xinli shang. Manu Zhang had earlier kicked off the discussion on the next parquet-java release, with input from Steve Loughran, Aaron Niskode-Dossett, Fokko Driesprong, Julien Le Dem, Gang Wu, and Rahil C. That kind of thread, where multiple committers weigh in on scope before the actual release work begins, is exactly the right governance pattern for a format-defining library.

Micah Kornfield announced Ed Seidl as a new Parquet committer. Andrew Lamb, Gang Wu, and Raúl Cumplido offered congratulations. Ed has been a steady contributor across both Parquet and Arrow for some time. The promotion to committer reflects the work he has put in across a number of release votes and discussion threads.

Arnav Balyan opened two discussion threads that point to where the Parquet community is thinking about AI-assisted contribution. The first was a discussion on AI tooling policy for Parquet, drawing a response from Fokko Driesprong. The second was a discussion on adding AGENTS.md to parquet-java, with input from Aaron Niskode-Dossett, Andrew Lamb, and Micah Kornfield. AGENTS.md is the emerging convention for documenting how AI coding agents should interact with a codebase. The fact that an Apache format project is having this conversation openly on its dev list, rather than letting individual contributors quietly use AI tools without disclosure, is the right approach. It is also a topic the Iceberg community has been working through for several months.

Micah Kornfield opened a discussion on remaining open spec-level questions for ALP. Andrew Lamb engaged. ALP is the adaptive lossless floating-point compression scheme that has been making its way through Parquet for the past year. It promises significant compression improvements on floating-point data versus the existing compression schemes. Getting the spec right matters because once ALP is in the format, every reader has to be able to decode it.

Other threads of note. Andrew Lamb opened a discussion on where the VariantJsonParser should live. Ed Seidl opened a discussion on making path_in_schema optional. Ismaël Mejía requested code reviews on Java performance optimization work, with engagement from Steve Loughran and Fokko Driesprong. Andrew Bell opened a discussion on wide schemas in Parquet. Each of these is the kind of practical improvement work that compounds over time.

Parquet is at an interesting point in its life cycle. The format is mature enough that nobody questions whether it should exist. The community is now wrestling with how to handle format evolution carefully, how to bring in new contributors at scale, and how to balance the needs of the established Java reference implementation against the growing number of native implementations in Rust, Go, and other languages. The Footer Working Group is the most visible sign of this maturation. The AI tooling policy discussion is another.

Cross-Project Themes

Three patterns connect the work across all four projects this week.

The first is format evolution under load. Iceberg V4 votes ran this week on relative paths and content stats. Parquet stood up a Footer Working Group and held a vote on IEEE 754 total order. Arrow discussed restricting metadata to UTF-8 and resolving IPC representation for dictionary-encoded extension types. These are all spec-level changes that ripple through the ecosystem. The fact that all three formats are evolving at the same time is not coincidental. The lakehouse architecture has matured to the point where the gaps between the formats are now visible in production. Each project is addressing the issues it can address, and the changes need to compose cleanly with each other.

The second is the rise of formal working groups and process discipline. Parquet now has a Footer Working Group. Iceberg has been running working groups on Kafka Connect, partition stats, and Python bindings for months. Polaris has clear schedule-driven release cadence and graduated to TLP. Arrow has multiple parallel release tracks managed by different committers. These projects are not just shipping features. They are building the institutional infrastructure that lets large communities collaborate without stepping on each other. That kind of process work is invisible from the outside but essential to long-term project health.

The third is the open conversation about AI tooling and disclosure. Parquet’s discussion this week on AI tooling policy and AGENTS.md echoes similar discussions in Iceberg earlier this year. The community is figuring out how to handle AI-assisted contributions in a way that is transparent, that preserves the chain of provenance for the code, and that does not slow down legitimate contributors. The fact that these discussions are happening openly on dev lists rather than being handled through informal back channels is the right approach. The decisions made over the next few months will set the pattern for how Apache projects handle AI-assisted development for years.

Looking Ahead

Next week should bring the close of the Iceberg 1.11.0 release if RC4 holds up, which would be a meaningful milestone for the project’s 2026 release cadence. The Iceberg V4 votes on relative paths and content stats are likely to close and move into implementation. The Parquet Footer Working Group will likely publish a charter and meeting schedule. Polaris watchers should expect early signals on what is heading into 1.5.0. Arrow has multiple smaller release votes likely to land in the next seven days, and the Erlang donation vote will close.

The bigger picture is that the lakehouse stack is maturing in step with the AI demand pulling on it. Every one of these format and protocol decisions affects how AI agents will be able to query, update, and reason about lakehouse data in the years ahead. The community is doing the unglamorous work now so the platforms can do the headline work later.

Resources and Further Learning

Get Started with Dremio

Free Downloads

Books by Alex Merced

The Request-Response Cycle: How Web Applications Communicate

A complete flow of the request response cycle

A fundamental software application operates on a client-server architecture, driven by a request-response cycle. The client (typically a web browser or mobile application) initiates a request, and the server processes it to return a response.

1. How the Client Finds the Server (DNS)

Every client and server on the internet is assigned a unique identifier called an Internet Protocol (IP) address (e.g., 192.0.2.1). Because memorizing strings of numbers is impractical for humans, the internet relies on Uniform Resource Locators (URLs) like www.example.com.

To translate a human-readable domain name into an IP address, the client queries the Domain Name System (DNS). The DNS acts as the phonebook of the internet, resolving the domain name and returning the correct IP address so the client can route its traffic to the target server.

2. Communicating via HTTP

Once the IP address is known, the client communicates with the server using the Hypertext Transfer Protocol (HTTP)—a standardized set of rules for transferring data across the web.

HTTP utilizes specific methods to define the nature of the request:

  • GET: Retrieves a specified resource from the server.
  • POST: Submits data to create a new resource.
  • PUT: Updates an entire existing resource, replacing it completely.
  • PATCH: Applies partial modifications to a resource.
  • DELETE: Removes the specified resource.

3. Data Exchange Formats

Data transmitted via HTTP must follow a mutually understood structure. The industry standard for modern web applications is JSON (JavaScript Object Notation) due to its lightweight and human-readable format.

When fetching data, a server response might look like this:

{
  "id": 123,
  "name": "David",
  "age": 27,
  "purchases": ["bread", "cake"]
}

4. Moving Data to a Dedicated Database

In enterprise applications, storing persistent data directly on the application server is highly discouraged. Doing so creates a stateful server, making scaling and maintenance incredibly difficult. Instead, state is offloaded to a dedicated database server designed for efficient data storage, retrieval, and processing.

Databases generally fall into two major categories:

  • Relational Database Management Systems (RDBMS): Data is organized into strict tables consisting of rows and columns. These systems utilize Structured Query Language (SQL) and allow complex relational mapping via joins. Examples include PostgreSQL, MySQL, and SQLite.

  • Non-Relational Databases (NoSQL): These systems abandon the rigid tabular model in favor of flexible schemas optimized for specific access patterns. They are categorized into document stores (MongoDB), key-value stores (Redis), graph databases (Neo4j), and wide-column stores (Cassandra).

Summary of the Lifecycle

When a user interacts with a website, the browser resolves the domain via DNS, formats an HTTP request containing necessary parameters or JSON payloads, and hits the server. The server processes the business logic, queries the database to read or write data, and returns the final payload back to the client as an HTTP response.

A complete flow of the request response cycle

Thanks for reading!

I’d genuinely appreciate your feedback. If there’s anything I missed or something you’d like to add about the request-response cycle, feel free to share it in the comments below.

If you found this post helpful, consider liking and sharing. It motivates me to keep documenting and sharing my learning journey.

I Built a New Programming Language for the Browser. Here Is What It Is and Why It Had to Exist.

Published by SAGEWORKS AI — Maun, Botswana

There are moments when you are building something and you realize the tool you need does not exist. Not a library. Not a framework. Not a configuration layer. The language itself is missing.

That is what happened with WebScript.

The Problem That Started This

The browser is a spatial environment. Every element has a position. Every transition has a curve. Every layout is a geometric relationship between objects in space.

And yet every language we use to program the browser is either document-oriented (HTML), cascade-oriented (CSS), imperative and procedural (JavaScript), or a type system overlay (TypeScript). Not one of them treats the browser as what it actually is: a spatial field where entities exist in geometric relationship to each other.

You want a panel that orbits the cursor with a harmonic depth transition? You write 40 lines of JavaScript. You want three cards positioned at phi-distributed angles on a circle? You calculate the trigonometry by hand, write the DOM manipulation, wire the animation frame, and manage the state.

The gap between what you mean and what you have to write is enormous.

WebScript closes that gap. It is the language that should have existed for the spatial web from the beginning.

What WebScript Is

WebScript is a declarative constraint-based spatial DSL that compiles simultaneously to HTML, CSS, SVG, JavaScript, TypeScript, and SQL.

Not a framework. Not a library. Not a preprocessor. A compiled language with its own grammar, type system, compiler pipeline, and browser runtime.

Four properties define it:

Declarative — you describe spatial relationships, not procedures.

Constraint-based — properties are bound to live equations, not static values. When an input changes, every dependent property updates automatically.

Spatial — geometry and position are first-class citizens of the language. orbit, distance, harmonic, phi are not imported utilities. They are primitives.

Relational — entities know each other. A panel knows its viewport. A card knows its cursor. A node knows its cluster. The language graph is a live relational system.

The Grammar — Six Constructs, No More

WebScript has exactly six sentence patterns. This is the complete language:

Construct 1 — Entity Declaration

card {
  depth    : 300
  rotate   : harmonic(0.5)
  position : orbit(cursor)
}

Construct 2 — Relational Binding

The of particle comes from Mandarin topic-comment grammar. It declares ownership, containment, and membership.

panel of viewport {
  sync    : parent.rhythm
  opacity : field(0.85)
  depth   : phi * 300
}

Particles available: of · at · as · by · through · into · from

Construct 3 — Equation Constraint

A live reactive binding. Re-evaluates whenever its inputs change.

card.rotation = cursor.angle * harmonic(0.4)
card.scale    = distance(origin) ^ 0.5

Construct 4 — Classifier Generation

From Mandarin measure words. Declares batch spatial generation.

7 orbital nodes
3 harmonic layers
1 depth field

7 orbital nodes generates seven positioned entities distributed on an orbital path. The mathematics of the distribution is handled by the language.

Construct 5 — Fetch Declaration (WSQL)

Declares a data retrieval that simultaneously generates a SQL query and a spatial layout.

fetch nodes from sales_data {
  where  : revenue > harmonic(0.5)
  order  : spatial(distance(origin))
  limit  : fibonacci(6)[5]
  map    : orbital(result.count)
  radius : phi^i * 40
  color  : hue(revenue.normalized)
}

One declaration. One SQL query. One spatial layout. They are the same thing.

Construct 6 — Page Boundary

Redefines the coordinate origin and containment boundary of a spatial environment.

page {
  boundary : circle(phi * viewport.width)
  origin   : viewport.center
}

The Compilation Model

Every WebScript declaration compiles to all six targets simultaneously from a single relational graph.

Take one declaration:

panel of viewport {
  depth    : phi * 300
  rotation : harmonic(cursor.angle * 0.4)
  position : orbit(cursor, phi * 80)
}

This produces:

HTML

<div class="ws-panel" data-ws-depth="485.4" data-ws-orbit="cursor">

CSS

.ws-panel {
  perspective: 485.4px;
  transform: rotate(var(--ws-panel-rotation));
}

SVG

<circle data-entity="panel" />

positioned at dynamically calculated orbit coordinates.

JavaScript

document.addEventListener('mousemove', e => {
  const angle = Math.atan2(e.clientY - cy, e.clientX - cx);
  panel.style.setProperty('--ws-panel-rotation',
    (0.5 - Math.cos(Math.PI * (angle * 0.4)) / 2) + 'rad');
});

TypeScript

interface WSPanel extends WSEntity {
  depth    : number;
  rotation : WSHarmonic;
  position : WSOrbit;
}

SQL

SELECT *, atan2(cursor_y - panel_y, cursor_x - panel_x) AS orbital_angle
FROM panels

One source. Six manifestations. All mathematically coherent because they all derive from the same relational constraint graph.

The Type System

WebScript has a spatial type system. Every value belongs to one of these types:

WSScalar      → a number, possibly equation-derived
WSEquation    → a live expression that resolves to a scalar
WSEntity      → a named spatial object in the graph
WSParticle    → a relational operator
WSClassifier  → a spatial type qualifier (orbital, harmonic, depth, fibonacci)
WSFunction    → a built-in spatial function
WSBoundary    → a page boundary equation
WSField       → a spatial influence area
WSConstraint  → a reactive binding between entity.property and expression
WSNode        → a data-carrying spatial entity (from WSQL)

The Built-in Function Library

These are the only built-in functions in v0.1. Every one is a spatial or mathematical primitive:

harmonic(t)          0.5 − cos(π·t) / 2
                     Easing. Maps [0,1] to [0,1] with smooth curve.

orbit(target, r)     Position on circle of radius r around target

distance(a, b)       Euclidean distance between two entities

field(value)         Spatially typed scalar wrapper

phi                  1.618033988749895

pi                   3.14159265358979

fibonacci(n)         First n Fibonacci numbers as array

hue(angle)           HSL color derived from spatial angle

decay(rate)          Trail fade multiplier for motion history

harmonic_scale(n)    Distortion scale from polygon side count

No bloat. No utility sprawl. A closed set of spatial primitives that compose into everything else.

The Compiler Pipeline

Five stages. Clear build path.

Stage 1 — Lexer: Reads WebScript source. Produces a token stream. The six grammar constructs are the complete token set.

Stage 2 — Parser: Takes tokens. Produces the Abstract Syntax Tree as a JSON-native structure. Every WS declaration maps 1:1 to a JSON node. This is the bidirectional bridge — the AST is simultaneously the JSON API and the AI-generatable format.

Stage 3 — Graph Resolver: Takes the AST. Builds the relational constraint graph. Resolves entity references, particle relationships, and equation dependencies.

Stage 4 — Target Compilers: Six separate compilers, each consuming the runtime graph simultaneously.

Stage 5 — Runtime Engine: The browser-injected webscript.js. Approximately 8-12kb minified. Executes constraint equations reactively. Maintains the spatial index. Updates CSS custom properties when inputs change.

What WebScript Is Not

These boundaries are permanent:

WebScript does not replace JavaScript’s control flow. No if, for, while, function in WebScript. JavaScript handles all procedural logic.

WebScript does not handle data validation, authentication, business logic, or server-side operations. These remain in their own layers.

WebScript does not transform HTML into geometry. HTML keeps its rectangular document model. WebScript projects geometry inside it.

WebScript does not replace CSS’s cascade, specificity, or responsive design system. It generates mathematically coherent values for CSS to apply.

WebScript does not attempt to be general-purpose. It is a domain-specific language for one domain: spatial relational computation in the browser.

The Intellectual Lineage

WebScript draws from four sources and is none of them:

CSS — the declarative model, the property-value syntax, the idea that you describe what you want rather than how to achieve it.

GLSL — mathematical spatial thinking as a first-class mode. The browser as a field of values rather than a document of nodes.

GraphQL — the unified query philosophy. One declaration surfaces in multiple layers simultaneously. The query and the presentation are the same expression.

Mandarin grammar — the topic-comment structure and classifier system. panel of viewport reads as a topicalized statement: “speaking of the viewport, here is the panel.” 7 orbital nodes uses measure-word logic — a spatial classifier before a noun.

The result is something none of those are: a language that treats the browser as a spatial field and programs it as a relational mathematical system.

Where It Goes

WebScript is one language with many native communities. The grammar does not change between them. The demonstrations do.

For web game developers: a declarative spatial layer for entity positions, collision constraints, camera following, and particle systems. The first language where game spatial logic is declared rather than procedurally written.

For data visualization engineers: a single declaration that simultaneously produces a SQL query and a spatial layout. The gap between data and geometry, closed.

For creative coders: the mental model of p5.js — fields, forces, particles, harmonics — expressed as a constraint grammar rather than a procedural script. Browser-native. No wrapper required.

For TypeScript developers: generated typed interfaces for every spatial entity. The mathematical coherence of the layout enforced at compile time.

For spatial / XR web: a declarative syntax for scene graphs, proximity constraints, and gaze-reactive positioning that reads as clearly as CSS but reasons in three dimensions.

For educators: the first programming language where spatial mathematics and visual output are the same syntax. A geometry class and a programming class simultaneously.

The Repository

The v0.1 implementation is live.

The repository contains the full language specification, compiler architecture, type system, runtime engine, standard library, WSQL bridge, CLI, playground, and test suite.

Source, specification, and build path: https://github.com/PEACEBINFLOW/webscript

The implementation is MIT licensed. The specification is Creative Commons Attribution 4.0 — anyone may implement WebScript, but Peace Thabiwa must be credited as the language designer.

The name WEBSCRIPT and the ⟁ symbol are trademarks of SAGEWORKS AI.

The Statement

The browser has been a spatial environment for thirty years.

It has never had a spatial language.

WebScript is that language.

Peace Thabiwa
SAGEWORKS AI — Maun, Botswana
https://github.com/PEACEBINFLOW/webscript

From editor to agent management — Google Antigravity 2.0 marks the arrival of the Agent OS

FIG.0 — AGENT OS STACK

This piece is mirrored from my blog. Canonical:
https://okikusan-public.pages.dev/antigravity-agent-os.en

FIG.0 — AGENT OS STACK

Antigravity 2.0 is not an AI-IDE update. It is the moment the centre of gravity in developer experience shifts from “the editor” to “agent management.” The Desktop / CLI / SDK / integration funnel together stop being a “specialist worker” like Claude Code / Codex / Grok Build, and start looking like an Agent OS.

The old axis — “which model is smarter” — is no longer enough. Harness design, permission boundaries, context, scheduled execution, and human review — these five decide developer productivity now. The next battlefield of AI coding, laid out.

▍ SOURCES

▍ TERMS — definitions and premises

Agent harness — the runtime that wraps a model. By Karpathy’s definition, Agent = Model + Harness. Concretely it binds:

  • System prompts / role definitions
  • Tools (file ops, Bash, web fetch, MCP external calls, etc.)
  • Memory / state
  • Permissions and guardrails
  • Feedback loop (retries, verification, sub-agent spawn)

Real examples:

  • Claude Code’s harness = CLI agent loop + tool set + project permissions
  • Cursor’s harness = editor integration + Apply machinery + codebase index
  • Antigravity’s harness = local app server + runtime + Skill pack attachment

Same model + different harness → drastically different behaviour. The harness is the part that determines how the agent actually acts.

Agent OS layer / Specialist worker layer

  • Agent OS layer = shares one harness across multiple UIs, permissions, scheduler, agent orchestration (Antigravity / Hermes / Copilot Studio)
  • Specialist worker layer = invoked to do the work (Claude Code / Codex CLI / Grok Build)

“Agent OS” is not Google’s official term — community framing and this article’s editorial lens.

Subagent — a child agent spawned dynamically by a parent. Antigravity 2.0’s launch demo built an OS with 93 parallel subagents.

Skill — pluggable capability pack you attach to an agent. Android Skills / Firebase Skills add a specific domain’s APIs and conventions to the harness.

App server — shared local backend inside the Antigravity install. Both Desktop UI and CLI binary call this same app server.

The five comparison axes — (1) harness design / (2) permission boundaries / (3) context / (4) scheduled execution / (5) human review.

TL;DR

  • Antigravity 2.0 is Desktop / CLI / SDK / AI Studio×Android×Firebase integration — not a bundle of scattered features, but one agent harness shared across four UIs.
  • Claude Code / Codex / Grok Build sit at the specialist worker layer; Antigravity 2.0 sits at the Agent OS layer binding them. A “VS” framing collapses across layers.
  • The axes that matter: (1) which harness / (2) what permission boundary / (3) what context / (4) what scheduled execution / (5) what human review.
  • For individuals: pair Hermes (OSS) with Antigravity-native. For enterprises: Copilot Studio / Workspace Studio / Antigravity, cross-cutting selection. Editor-only comparison is now a generation behind.

§ 01 SHIFT — from editor to agent management

Two years of AI coding tools have been narrated through the editor: Copilot, Cursor, Claude Code, Codex CLI, Grok Build. They all evolved on the premise of “AI writes code inside the editor.”

Antigravity 2.0 breaks that frame. This is not an AI-IDE update. It assembles Desktop / CLI / SDK / AI Studio integration all at once, and what it produces is a platform for managing agents — a single agent harness shared across four UIs.

§ 02 PILLARS — Desktop / CLI / SDK / integration funnel

2-1 Desktop app — the command center

A command bridge for running many agents in parallel. Dynamic subagents (spawn and retire children on the fly), scheduled tasks (cron-style runs), and per-project permission scopes. The feel shifts from “one task in one editor” to “many tasks running at once, all in view.”

2-2 Antigravity CLI — different UI, same harness

Successor to Gemini CLI. A lightweight UI for terminal people, but the key is that it shares the same agent harness as Desktop. The CLI isn’t a separate product — it’s a different interface to the same base.

FIG.2-2 — SHARED HARNESS

▍ “Sharing the same harness” — what it actually means
Not two competing apps. A single local install bundles Desktop UI / CLI binary / a shared app server (the agent harness itself). Per @karthickdotxyz: “Same tools and app server as Antigravity 2.0.”

  • No need to run both at once — Desktop or CLI, either path completes
  • Configs, agent definitions, permissions, scheduled tasks are all shared — a job composed in Desktop can be invoked from CLI as-is
  • Natural split: CI / headless server work via CLI, interactive development via Desktop

2-3 SDK — embed the harness into your own product

Google’s agent harness is now something you embed into your own workflow or product. This stops being “a tool that makes AI write code” and starts being “a platform for building and operating AI agents.” SDK code runs on your own PC, your servers, your CI runners — Google doesn’t host the runtime; it lives inside your process. Antigravity could become a component that runs inside other companies’ products, not just Google’s IDE.

FIG.2-3 — SDK EMBED

▍ CLI vs SDK — what’s the actual difference?
Both run on local machines or on servers. The real distinction is the primary use case each is designed for:

  • CLI = an interactive front designed for a human (or shell script) to drive an agent directly
  • SDK = a library designed for your program to drive the agent via function calls

Strictly, you can also call the CLI from a program by shelling out. But shelling out comes with costs: (a) process startup overhead / (b) brittle text-output parsing / (c) no types / (d) streaming and structured events are awkward. The SDK assumes that use case from the start. Same shape as AWS CLI vs boto3.

2-4 AI Studio × Android × Firebase integration

Less “three products wired together at the UI layer,” more “Antigravity sits in the middle as the harness, with AI Studio (entry) and Android / Firebase (exit) bolted on via a shared harness and Skills.”

  • AI Studio → Antigravity (“Export to Antigravity”): AI Studio Build now runs on the same agent harness as Antigravity. A dedicated Export to Antigravity button hands off the full agent conversation (chat history, configuration, generated code) into the local Antigravity environment.
  • Antigravity → Android: Equip the agent with the official Android Skills — Android SDK / Gradle / manifests become part of the agent’s context. Going further, the studio command in Android CLI 1.0 lets the agent connect to a running Android Studio instance and borrow its deep codebase understanding.
  • Antigravity → Firebase: Firebase Skills teach the agent Firestore / Functions / Hosting / Auth conventions, configuration and deployment included.

FIG.3 — INTEGRATION BRIDGES

So Google’s “vertical integration” play is re-engineered not at the UI layer but at the harness and Skill (attachable capability packs) layer.

Official launch video: https://www.youtube.com/watch?v=6C0FjHoN3qE

§ 03 LAYER — not a “specialist worker”

▍ Terminology note on “Agent OS”
The phrase “Agent OS” used throughout this piece is not Google’s official terminology. Right after launch, @grok called it “the emerging Agent OS category” and @arsh_goyal framed it as a “centralized Agent Manager.” This article borrows that framing to describe a structural pattern: a single harness shared across multiple UIs, with permissions, scheduling, and sub-agent orchestration unified at one layer.

Lining up Antigravity 2.0 with Claude Code / Codex CLI / Grok Build and asking “which one’s best” misses the point. They live at different layers.

3-1 Specialist worker layer vs Agent OS layer

Specialist worker layer Agent OS layer
Role Called to do the work Orchestrates and supervises
Examples Claude Code / Codex CLI / Grok Build / Cursor Agent Hermes (OSS) / Microsoft Copilot Studio / Google Antigravity 2.0
Strengths Instant reasoning, code generation, file ops Multiple UIs / parallel execution / permissions / shared harness

3-2 “VS” framing breaks across layers

“Antigravity 2.0 vs Claude Code” is a layer violation. As Antigravity expands via the SDK inside other companies’ products, the natural composition becomes “Antigravity-on-top, calling Claude Code / Codex CLI / Grok Build as workers.” The right peers to compare with are Hermes / Copilot Studio — same Agent OS layer.

FIG.4 — LAYER STACK

▍ Direct comparison with Hermes / Copilot Studio

  • Hermes = OSS / individual-tilted / multi-model / 22 gateways / Obsidian integration / domain-agnostic (works outside coding too)
  • Microsoft Copilot Studio = M365 territory / enterprise permissions / Power Platform integration / business-workflow focused
  • Google Antigravity 2.0 = Google-native / AI Studio × Android × Firebase vertical integration / software-engineering specialised

The scope difference matters: sitting at the same Agent OS layer does not mean the same role. Hermes is a domain-agnostic general harness; Copilot Studio is for business workflows; Antigravity is purpose-built for software-engineering work.

§ 04 AXIS — renewing the comparison axes

Re-reading §02’s four pillars as a structure, each contains a design choice that the old “model IQ axis” cannot capture:

  • Desktop’s dynamic subagents + scheduled tasks → which harness, when to fire automatically
  • CLI sharing the app server with Desktop → same harness called from different UIs
  • SDK running in your own process → what permission boundary, what environment
  • AI Studio / Android / Firebase Skills → what context to feed the agent
  • The agentic IDE’s review surface → how humans review

So if you unpack the structure of Antigravity 2.0 honestly, the five axes — harness / permission boundary / context / timing / review — surface naturally.

▍ This is my own view — why these 5 axes
The five design axes are not a standard framework published by Google, IDC, Forrester, or anyone else — they are my editorial synthesis of what I think actually matters. My reasoning for picking these specific 5:

  • harness — with model IQ commoditising, harness design determines actual behaviour
  • permission boundary — when agents act autonomously, permission scope decides blast radius
  • context — same model + same IQ produces wildly different output depending on context given
  • timing — manual / hook / cron agents are different beasts. Antigravity 2.0 making scheduled tasks first-class is evidence this matters
  • review — human-in-the-loop verification load is the productivity bottleneck

Individual terms have currency across the industry, but bundling these 5 as “the evaluation axes that matter” is my judgement.

FIG.1 — AXIS MAP

Side-by-side, what changes per axis between the editor era and the Agent OS era:

Axis Editor era (~2025) Agent OS era (2026 →)
harness Editor’s completion speed / UX Which tools, memory, permissions, feedback loops you wrap around the model
permission Largely a non-question — manual control Autonomous agents → Project / User / Agent-scoped permissions define blast radius
context Context window size (a “quantity” axis) What you pull in and hand the agent (a “quality” axis, plus Skill packs)
timing Completion as the human is typing Manual / hook / cron / scheduled — async / parallel / 24-7 included
review Humans read before and after writing code How far do you trust auto-executed agent output, and where does a human gate it?

Footnote: the old axis “which model is smartest” no longer stands on its own — same model with different harness and context produces wildly different output.

These five decide developer productivity itself. Smarter models with sloppy harnesses just automate Slop.

§ 05 BATTLEFIELD — the next battlefield is not inside the editor

The next battlefield is no longer inside the editor — it is in Agent OS orchestration design.

FIG.2 — BATTLEFIELD TIMELINE

  • 2023: Prompt engineering (single model calls)
  • 2024: Context assembly (RAG + memory)
  • 2025: AI in the editor (Copilot + inline suggestions)
  • 2026+: Orchestrate agents (Agent OS) — compose / supervise / continuous execution

▍ VOICES — use cases that surfaced in the first 48 hours

Snapshots from X in the 48 hours since launch. The chatter is visibly shifting from “a specialist worker writes code” toward “a fleet of agents gets orchestrated.”

  • @andreasawires: “93 parallel sub-agents, 12 hours, 15K+ model requests, 2.6 billion tokens, under $1K in API credits” — built a full OS from scratch
  • @andyzhang (Antigravity team): “Antigravity 2.0, a desktop application to manage all of your agents” — official launch post
  • @mirrokni (Vahab Mirrokni, Google): Antigravity /teamwork agents recreated the AlphaZero paper end-to-end (RL + TPU + Web app)
  • @SHT4BHARAT: “We are officially out of the chatbot era and deep into production-scale autonomous workflows”
  • @karthickdotxyz: Antigravity CLI official launch — Go binary, async workflows, “Same tools and app server as Antigravity 2.0”
  • @neuecc (Yoshifumi Kawai): on adopting Antigravity 2.0 + IDE separated workflow over Cursor 3 for complex projects
  • @gptzone_net: “Antigravity 2.0 no se debería evaluar como un autocompletado más agresivo. Se debería evaluar como un cambio de workflow”
  • @BeamManP: Gemini 3.5 Flash can now do structural music analysis — same engine that powers Antigravity

§ 06 FIT — how individuals and enterprises choose

▍ This section is opinion
The “if you’re an individual, pick X / if you’re an org, pick Y” framing in this section is my personal recommendation, not an official guide from Google / Microsoft / Nous Research.

Facts: Hermes = OSS / multi-model / Obsidian integration / domain-agnostic. Antigravity 2.0 = vertically integrated into Google’s ecosystem / software-engineering specialised. Microsoft Copilot Studio = M365 territory / business-workflow focused.

Opinion: “Individuals should pair Hermes with Antigravity” is what I think makes sense — others reaching the opposite conclusion (“standardise on Copilot Studio for simpler ops” / “go all-OSS on Hermes for transparency”) would be perfectly reasonable.

Individual vs team/org evaluation per the 5 axes of §04:

Axis Individual use Team / org use
harness Each developer installs their preferred harness locally Standardise one harness org-wide / custom harness embedded via Antigravity SDK in internal products
permission Read/write on personal Mac / personal repos Hierarchical Project / User / Role ACL, segregation across internal systems
context Personal Obsidian / personal git / personal Slack DMs Internal Confluence / shared GitHub org / company Slack / Linear・Jira / on-call runbooks
timing Interactive on personal PC or light personal cron Shared server / CI runner / 24-7 environment — embed agents via SDK
review Personal self-check Code review / PR approval flow / audit logs / compliance checks

Footnote: “harness” itself is neutral. Team-readiness depends on the implementation — Claude Code / Hermes / Cursor assume “personal local”; Antigravity 2.0 covers both with Project permissions + SDK + Enterprise framing; Copilot Studio is “team / business” from the start.

▍ For team-shared harness, SDK is the only path
Antigravity’s standalone Desktop / CLI structure assumes “a local app server on a personal machine.” Trying to share that harness across a team — git-syncing the config doesn’t help, the instances are still separate.

If you want a team to share one harness, the only realistic path is embedding the SDK in an internal backend / shared server / CI runner, so multiple users hit a single harness instance you operate yourself. Google does not offer a hosted “Managed harness,” so “team harness as a Service” has to be built in-house as of today.

6-1 Individuals — Hermes and Antigravity in combination

OSS-leaning individuals still get great value from Hermes. Obsidian integration, multi-model routing, the gateway pack (Telegram / Discord / LINE / Slack) are Hermes-only as of now.

Google-ecosystem individuals get the most from Antigravity. Prototype in AI Studio, hand it to Antigravity Desktop, ship to Firebase — that vertical funnel Hermes can’t reproduce.

The practical answer is both at once. Use Hermes to orchestrate the personal tacit-thought pool, and use Antigravity for heavy lifting inside the Google ecosystem.

6-2 Enterprises — three Agent OSes across contexts

For enterprises, the picture is three Agent OSes mapped to three contexts:

  • Business context = Microsoft Copilot Studio (M365 / expense / calendar / doc review)
  • Dev context = Google Antigravity 2.0 (coding / Android / Firebase / GCP)
  • Personal context = Hermes-class OSS (personal tacit-thought pools / Obsidian / custom gateways)

Centring procurement on a standalone editor (Claude Code / Codex CLI / Cursor) is now a generation behind.

✦ Summary

Claude Code / Codex / Grok Build are specialist workers. Antigravity 2.0 / Hermes / Copilot Studio / Workspace Studio are Agent OSes. A “VS” framing across these layers no longer holds. The conversation must shift to within-layer comparison and across-layer composition.

The axes that count are harness design / permission boundaries / context / scheduled execution / human review. “Which model is smarter” no longer covers it.

For individuals: pair Hermes with Antigravity. For enterprises: use Copilot Studio, Workspace Studio, and Antigravity across business / dev / personal axes. Productivity now lives in Agent OS design, not inside the editor.

Full canonical version (with interactive figures):
https://okikusan-public.pages.dev/antigravity-agent-os.en

Related posts:

Elektrikli Audi A2 e-tron için kamuflajlı test görüntüleri paylaşıldı [Video]

Audi A2 e-tron

Audi A2 e-tronElektrikli Audi A2 e-tron için resmi duyuru, ikonik rozeti geleceğe taşıyacak aracın gövde hatlarını gösteren bir görselle birlikte yapılmıştı. Resmi olarak yıl sonunda tanıtılması ve 2027’de satışa sunulması beklenen araç, bu sefer kamuflajlı test görüntüleriyle gündeme geldi. Merak uyandıran model Audi’nin daha önce yaptığı açıklamaya göre elektrikli Volkswagen ID.3 ile aynı platformu temel alacak. En üst versiyonda 300 beygire yakın güç ve 600 km’ye yakın menzil sunması beklenen araç, eğer planlarda bir değişiklik olmazsa Audi’nin en ucuz tamamen elektriklisi olacak. Bu açıdan satış konusunda büyük beklentilerin bulunduğu 400V temelli Audi A2 e-tron, 2027 yılında Türkiye’de de satışa sunulabilir.

Elektrikli Audi A2 e-tron için kamuflajlı test görüntüleri paylaşıldı [Video] yazısı ilk olarak Teknoloji haberleri – LOG üzerinde yayınlandı.

Shipping on Gemma 4: chain-of-thought leakage, MoE-vs-Dense, and on-device pragmatism

This is a submission for the Gemma 4 Challenge: Write About Gemma 4

Shipping on Gemma 4: chain-of-thought leakage, MoE-vs-Dense, and on-device pragmatism

I built and shipped Curio Kid, a kid-safe multimodal Android app where my 6-year-old asks Luna (a Gemma-4-powered tutor) anything by text, voice, or camera. The product story is in my other submission. This post is the engineering writeup — three things about Gemma 4 that I had to actually work around in production, with the code and reasoning behind each fix.

If you’re about to ship a Gemma 4 app, these are the three traps I’d want to know about on day one.

1. Chain-of-thought leakage is real, and it hits the user

Gemma 4 is good at following structured system prompts. Too good, sometimes. Give it a strict persona spec and it will occasionally show you the rubric while answering. In my testing, a meaningful slice of responses came back like this:

**Intent:** child wants to know why the sky is blue
**Tone check:** warm, age-5 vocabulary, no jargon
**Final Polish:**

Great question! The sky is blue because…

The “Final Polish:” line is the give-away — Gemma is narrating its own polishing step before giving the answer. For a chatbot aimed at a 6-year-old, that’s not a quirk; it’s a UX bug.

The naïve fix doesn’t work

The obvious instinct is “tell the model not to do this in the system prompt.” I tried. My prompt now contains a half-page of “never write section labels like ‘Final Polish’, ‘Self-Correction’, ‘Reasoning’, ‘Plan’… your very first word must be part of the actual answer”. It helps. It doesn’t eliminate.

The reason it can’t eliminate the issue: instruction-following is a soft constraint. The same model that’s smart enough to follow a 50-line persona spec is also smart enough to think about how to follow it — and sometimes the thinking ends up on the wire.

The real fix: a two-stage cleaner that knows the difference between meta and content

I ended up with a 100-line response sanitiser (LunaAI.kt) that does three things in order:

Stage 1 — Anchor detection. Look for “final answer” / “polished response” / “answer:” anchors on their own line. If present, throw away everything before the last one and keep only what follows. This handles the dominant failure mode (model planned out loud, then gave the real answer at the bottom).

val finalAnchorLine = Regex(
    "(?im)^\s*\*{0,2}\s*" +
        "(?:final(?:\s+(?:polish|answer|response|reply|draft|version))?" +
        "|polished(?:\s+(?:answer|reply|response))?" +
        "|the\s+answer|answer|response|reply)" +
        "\s*\*{0,2}\s*:\s*$",
)
val afterAnchor = finalAnchorLine.findAll(raw).lastOrNull()
    ?.let { raw.substring(it.range.last + 1) } ?: raw

Stage 2 — Paragraph-level meta filter. Split by blank lines, drop any paragraph that contains chain-of-thought prose cues — phrases like “the prompt says…”, “I’ll treat the question as…”, “drafting…”, “let me revise…”. This catches the case where the model narrates its process in prose instead of with labels.

Stage 3 — Line-level scrub. A safety net for leaks embedded inside an otherwise-good paragraph: bullet/label lines like * Intent: … or **Tone check:** ….

The non-obvious part: what not to filter

The interesting design problem isn’t writing the regex; it’s making sure you don’t kill legitimate content. Three rules I learned the hard way:

  • Never filter on the word “think” alone. Phrases like “Let me think of a fun example!” are exactly the warm tone you want from a kid’s tutor. My meta-regex matches “let me / I’ll / I will / I should” only when followed by a planning verb (plan, draft, rewrite, revise, polish, reconsider, interpret). “Let me think of” slips through. Good.
  • Only apply bullet-stripping when a leak is detected nearby. Gemma sometimes does legitimately produce a bulleted list when the kid asks “give me three facts about pandas”. You don’t want to scrub bullets unconditionally; you want to scrub them only when other meta-leakage is already visible on the page.
  • Have a fallback for “scrubbed to nothing”. If filtering empties the response, return “Hmm, let me think about that another way — could you ask me again?” — not a blank bubble.

Takeaway

If you’re building a user-facing app on Gemma 4 — especially with kids, customer support, or anywhere “the model thinking out loud is bad UX” — assume CoT leakage will happen and ship a sanitiser. A sanitiser is also dramatically cheaper than fine-tuning, and it composes with whichever model variant you swap in next month.

2. MoE vs Dense: how I actually chose between gemma-4-26b-a4b-it and gemma-4-31b-it

The Gemma 4 family ships three architectures for very different deployment targets:

Variant Effective params Architecture Where it shines
E2B / E4B 2B / 4B Small dense Ultra-mobile, edge, browser
gemma-4-26b-a4b-it 26B (~4B active) Mixture-of-Experts Server-grade chat, multimodal, low-latency
gemma-4-31b-it 31B Dense Hardest reasoning, multi-step problems

For a kid-facing multimodal chat app I shipped the 26B MoE as the default and the 31B Dense as an opt-in “thinker” mode. Both have the 256K context window and Apache-2.0 licence, so the choice is purely about latency vs. depth.

Why MoE wins the default slot

The MoE’s superpower isn’t raw size — it’s that only a slice of experts is activated per token. You pay ~4B of compute per token while keeping 26B of capacity available across the network. For my workload that translated into three concrete wins:

  1. First-token latency that feels like chat, not like batch inference. Streaming starts in well under a second on Google AI Studio. A 6-year-old’s patience is shorter than the inverse of his curiosity rate, so this matters more than benchmark scores.
  2. Multimodal in the same model. No separate vision pass, no second API call for the image. “What kind of bug is this?” with a photo attached is one request.
  3. 256K context lets the Curiosity Digest be a one-shot. End of the day, I cat the whole transcript into a single prompt and ask Gemma to produce a structured digest. No RAG, no map-reduce summarisation. The whole “parent dashboard” feature is ~30 lines of glue because of this.

Why Dense earns its own button

For the questions that are genuinely hard — “why do mirrors flip left-and-right but not up-and-down?” is the canonical kid-stumper — the 31B Dense produces noticeably better multi-step reasoning. It’s slower and pricier per call, so it’s not the right default for “explain photosynthesis in three sentences”, but it’s the right tool when the kid trips into something philosophical.

The mental model I’d suggest for picking

Forget the parameter count for a second and ask three questions about your workload:

  • Is latency-to-first-token a UX requirement? → MoE.
  • Are you doing multimodal in the same call? → MoE (with image input).
  • Do you measurably gain on the hardest 10% of your prompts when you swap to Dense? → ship both, give users a toggle.

Don’t pick on price; pick on what your prompts actually need. The MoE is the right answer for most chat workloads. The Dense is the right answer when you can articulate the reasoning gap.

3. On-device pragmatism: cloud-first isn’t a cop-out

The most photogenic Gemma 4 demos run E2B on a Pixel or a Raspberry Pi. They’re amazing. They’re also not the right default for a consumer Android app you want real families to use.

Two realities pushed me cloud-first:

  1. Not every phone can run Gemma 4 locally. A multi-gigabyte model needs the RAM, the storage, and the NPU/GPU to be worth the wait. Older flagships, mid-range phones, and the hand-me-down tablet a kid actually gets to use aren’t there yet. Gating an app on “must own a current flagship” defeats the point of an accessible kids’ app.
  2. Quality matters more than offline-ness for a 6-year-old. A child being confidently told “the moon is made of cheese” by an under-cooked tiny model is a worse experience than a 2-second wait over Wi-Fi for the 26B MoE.

The architecture trick that lets you defer the choice

What I’d recommend for anyone shipping today: don’t pick between cloud and on-device. Pick a backend interface and write three implementations.

interface LlmBackend {
    suspend fun ask(
        systemPrompt: String,
        history: List<ChatTurn>,
        userText: String,
        image: Bitmap?,
        modelName: String,
    ): String

    suspend fun summarise(
        systemPrompt: String,
        rawHistoryText: String,
        modelName: String,
    ): String
}

In Curio Kid that interface has three implementations: GoogleAiStudioBackend, OpenRouterBackend, and a LocalGemmaBackend stub that throws a friendly “on-device Gemma 4 isn’t installed on this phone yet” until a MediaPipe .task file is wired in. Same system prompt, same response cleaner, same UI for all three. The provider is a single enum in EncryptedSharedPreferences and a one-tap toggle in Settings.

The pay-off: when E2B becomes the right default — when phones catch up, when multimodal lands in MediaPipe, when battery cost makes sense — I change one factory method. The persona, the safety prompt, the digest pipeline, the cleaner all carry over. The same kid talking to the same Luna; the model just moved into the phone.

That’s the on-device pragmatism: don’t bet on offline-first when your users can’t run it, but don’t lock yourself out of it either. Bet on the abstraction.

Three small SDK gotchas I’d want to have known on day one

While I’m here: three concrete Gemini-SDK-on-Android landmines that cost me an evening each.

  • The 80-second socket timeout is hard-coded. RequestOptions doesn’t expose a knob to change it. If Gemma 4 takes longer than 80 seconds to start emitting tokens, you’ll get a SocketTimeoutException even though the model is fine. Fix: use generateContentStream instead of generateContent. The read timer resets on each chunk, so as long as tokens are flowing you never trip the cap.
  • MAX_TOKENS throws, it doesn’t return the partial text. The Kotlin SDK raises ResponseStoppedException from the .text convenience getter when finish reason ≠ STOP. You have to catch it and walk candidates[0].content.parts for TextParts yourself to recover the 90%-complete answer the user nearly got.
  • A 500 from the upstream model often surfaces as MissingFieldException from kotlinx-serialization. When the Gemini backend has a hiccup it returns JSON that the SDK’s strict deserialiser doesn’t recognise, and the exception you see is the serialisation failure, not the underlying 500. Worth normalising every error class through a single friendlyError() mapper that walks the cause chain — the real problem is usually two layers down.

TL;DR

Three lessons from shipping on Gemma 4:

  1. CoT leakage is a UX problem, not a prompt problem. Ship a sanitiser. Be careful what you scrub.
  2. MoE is the right default for chat; Dense is the right tool for hard reasoning. Give users the toggle, pick by latency-and-multimodal vs. reasoning-on-the-hardest-10%.
  3. Cloud-first isn’t a cop-out, but architecting for on-device later is non-negotiable. A LlmBackend interface with three implementations buys you the option.

The Gemma 4 family is the first open-model release where I genuinely had to think about which member to ship for which job — that’s a great problem to have. If you’re building on it, I hope these save you a weekend each.

Code is at github.com/sann3/curio-kid if you want to read the cleaner, the backend interface, or the friendly-error mapper in full. Happy to answer questions in the comments.

Thanks to the DEV team and Google for the challenge!

How DropZap Handles Instagram and TikTok Downloads: A Technical Walkthrough

How DropZap Handles Instagram and TikTok Downloads: A Technical Walkthrough

DropZap is a free social media video downloader built with Next.js 14. It handles Instagram, TikTok, Twitter/X, Facebook, Reddit, Pinterest, and Threads — all from one interface. I want to walk through the technical approach behind the two most complex platforms: Instagram and TikTok.

Stack Overview

  • Framework: Next.js 14 (App Router)
  • Language: TypeScript
  • Download engine: yt-dlp via Node child process
  • Audio merging: ffmpeg (for Reddit, and some formats)
  • UI: Tailwind CSS + shadcn/ui
  • Hosting: Render / Railway (Docker container)

Instagram Download Flow

Instagram is complex because it serves three distinct content types that require different handling:

1. Reels and Video Posts

The API route /api/stream receives the Instagram post URL from the client. The server spawns yt-dlp with the URL and --format bestvideo+bestaudio/best flags.

// Simplified — actual route handles cookies + proxies
const result = await execa('yt-dlp', [
  '--format', 'bestvideo+bestaudio/best',
  '--merge-output-format', 'mp4',
  '--output', '-',  // pipe to stdout
  instagramUrl
]);

The raw bytes are streamed back to the client via a ReadableStream. This avoids writing temp files to disk on the server, keeping the container stateless.

2. Photos (Single Image Posts)

For photo posts, yt-dlp extracts the direct CDN URL of the JPEG. We then proxy the CDN response to the client with Content-Disposition: attachment headers so the browser triggers a download instead of navigating to the image.

3. Carousels (Multi-Slide Posts)

Carousels are the trickiest. A single Instagram carousel URL can contain 2–20 slides. yt-dlp returns them as a playlist of individual entries.

The server:

  1. Runs yt-dlp --dump-json to get the manifest of all slide URLs
  2. Fetches each slide in parallel using Promise.all
  3. Packages them into a ZIP using the archiver npm package
  4. Streams the ZIP to the client
import archiver from 'archiver';

const archive = archiver('zip', { zlib: { level: 5 } });
// pipe archive to response
res.setHeader('Content-Type', 'application/zip');
archive.pipe(res);

for (const [i, slideUrl] of slides.entries()) {
  const imageStream = await fetch(slideUrl).then(r => r.body);
  archive.append(imageStream, { name: `slide-${i + 1}.jpg` });
}

await archive.finalize();

TikTok Download Flow

TikTok is more aggressive about blocking programmatic access than Instagram. The key challenges:

Watermark Removal

TikTok serves two versions of each video:

  • A “watermarked” version (with the floating TikTok logo + username)
  • A “no-watermark” version accessible via a different CDN path

yt-dlp knows which endpoint to hit for the no-watermark version because it parses TikTok’s internal API response, which includes a play_addr_h264 field pointing to the clean copy. This is the same mechanism that tools like ssstik and SnapTik use.

Rate Limiting and Anti-Bot

TikTok’s API endpoints rotate and require specific request headers (User-Agent, Referer, and a session token derived from the device signature). yt-dlp maintains an updater that tracks these header requirements and patches them when TikTok changes their scheme — which happens roughly every 2–4 weeks.

This is why keeping yt-dlp updated is critical. In the Dockerfile:

# Always pull the latest yt-dlp binary at build time
RUN pip install --upgrade yt-dlp

On production, a weekly cron job runs yt-dlp --update-to nightly to stay ahead of TikTok API changes.

Rate Limiting on the DropZap Side

The app applies a server-side rate limiter (1 request per 5 seconds per IP) using an in-memory Map to track timestamps. No Redis needed for the traffic levels a free tool receives — if this ever needed to scale horizontally, swapping to Redis would be a one-line change.

// lib/rate-limit.ts
const requests = new Map<string, number>();

export function checkRateLimit(ip: string): boolean {
  const last = requests.get(ip) ?? 0;
  const now = Date.now();
  if (now - last < 5000) return false; // 5 second window
  requests.set(ip, now);
  return true;
}

Performance Decisions

Code splitting: Every downloader tab is loaded via next/dynamic with ssr: false. Only Instagram (the default tab) is statically bundled. This cut unused-JS budget by ~317 KiB in a PageSpeed audit.

Streaming responses: Video bytes are streamed from yt-dlp‘s stdout directly to the HTTP response. The server never writes a temp file to disk. This matters both for latency and for running on containers with limited ephemeral storage.

No client-side state persistence: The download history feature was removed after user feedback that it confused people. localStorage had a habit of showing stale “pending” entries. Simpler is better.

Try It

The live tool is at dropzap.digital. Instagram is the default tab; TikTok is next. Paste any public post URL, hit Download.

If you’re building something similar and have questions about any specific part of the architecture — cookie handling, the archiver pipeline, the yt-dlp subprocess management — ask in the comments.