Ask anything, or task an agent…
Explore inspiration
10 interesting stories served every morning and every evening.
Ask anything, or task an agent…
Explore inspiration
Today, we are introducing Kimi K3 — our most capable model. Kimi K3 is a 2.8T-parameter model built on our Kimi Delta Attention and Attention Residuals, with native vision capabilities and a 1-million-token context window. It is the world’s first open 3T-class model, designed for frontier intelligence across long-horizon coding, knowledge work, and reasoning.
While its overall performance still trails the most powerful proprietary models, Claude Fable 5 and GPT 5.6 Sol, Kimi K3 demonstrated frontier-level performance across our evaluation suite, consistently outperforming other tested models.
Kimi K3 is available today on Kimi.com, Kimi Work, Kimi Code, and the Kimi API. At launch, Kimi K3 will use max thinking effort by default, with low- and high-effort modes to be introduced in subsequent updates. We are currently working closely with inference partners and open-source maintainers to align technical details and ensure a reliable rollout across the ecosystem. The full model weights will be released by July 27, 2026. Further details on the architecture, training, and evaluations will be released alongside the Kimi K3 technical report.
An Open 3T-Class Model
Kimi K3 is the first open model to reach 2.8 trillion parameters. It marks the latest step in Kimi’s sustained push at the scaling frontier: for nine of the past twelve months, Kimi models have set the upper bound of open-model sizes.
Kimi K3 is built on Kimi Delta Attention (KDA) and Attention Residuals (AttnRes), two architectural updates designed to improve how information flows across sequence length and model depth. We have also scaled up Mixture of Experts (MoE) sparsity, effectively activating 16 out of 896 experts when paired with a Stable LatentMoE framework. Together with refined training and data recipes, these structural changes yield an approximate 2.5× improvement in overall scaling efficiency compared to Kimi K2, allowing the model to convert compute into intelligence more effectively.
Coding
Kimi K3 has strong long-horizon coding performance. Operating with minimal human oversight, it can sustain long engineering sessions, navigate massive repositories, and orchestrate terminal tools.
Kimi K3 also excels in tasks blending software engineering with visual reasoning — it leverages screenshots and visuals to optimize game dev, frontend, and CAD.
The case studies below show how Kimi K3′s coding capability translates into open-ended software creation and scientific research.
Kernel Optimization
We tested the models’ capability to optimize GPU kernels. Each model works independently in an identical sandbox, with up to 24 hours to profile, rewrite, and benchmark four tasks spanning AttnRes, KDA, and a 512-head-dimension MLA kernel across NVIDIA H200 and GPGPU from an alternative vendor. Kimi K3 performed competitively with Fable 5 (with fallback) and substantially outperformed Opus 4.8, GPT 5.6 Sol, and GPT 5.5.
Claude Fable 5 was evaluated by a third party, and its results may include fallback behavior. Across most models, some trajectories include small, acceptable precision shortcuts that remain within our numerical tolerance. GPGPU denotes general-purpose GPUs used for computation beyond graphics rendering.
In the late stages of Kimi K3 development, an early version of Kimi K3 handled the majority of the team’s kernel optimization works.
GPU Compiler Development
We further tested whether Kimi K3 could build a GPU programming system from scratch. Kimi K3 developed MiniTriton, a compact Triton-like compiler with its own tile-level IR layer over MLIR, optimization passes, and a PTX code-generation pipeline. Across supported roofline benchmarks, MiniTriton delivers performance on par with or better than Triton and torch.compile — beating Triton on certain workloads. Beyond microbenchmarks, MiniTriton sustains end-to-end nanoGPT training with stable convergence, the loss curve closely tracking the reference with only minor divergence — validating the full pipeline on a realistic workload. These results demonstrate that Kimi K3 can build a coherent end-to-end compiler — from DSL frontend and IR passes to PTX codegen and runtime — rather than isolated kernels; its from-scratch Tensor Core path already rivals Triton’s extensively optimized stack.
Game Dev and Digital Creation
Kimi K3 combines strong 3D reasoning, coding, and vision capabilities to turn concepts, images, and videos into fully playable interactive experiences. Kimi K3 achieves true “vision in the loop” by seamlessly iterating between code and live screenshots—instantly seeing and refining outputs.
Case 1: 3D Open World
Kimi K3 built a fully procedural browser-based 3D exploration game using Three.js WebGPU and GPU compute. It procedurally generated the environment, while using a 3D asset generation tool to create the rider and horse models, producing an expansive open world with forests, a log-cabin village, snowy mountains, and dynamic weather. External assets used: animated cowboy and horse models and terrain data.
Chip Design
As an early proof of concept, Kimi K3 designed a chip to serve a nano model built on its own architecture. In a single 48-hour autonomous run, K3 built, optimized, and verified the chip using open-source EDA tools on the Nangate 45nm library. Within 4 mm², the chip closes timing at 100 MHz and sustains over 8,700 tokens/s decode throughput in simulation, packing 1.46M standard cells, 0.277 MB of SRAM, and an INT4 MAC array with fused dequantization. A chip built by a model, for a model, reflects K3′s long-horizon agentic capabilities.
Coding for Research
Kimi K3 bridges scientific literature and executable code, autonomously implementing, validating, and analyzing complex computational research workflows.
In one case, Kimi K3 completed in about two hours what would typically require one to two weeks of work by an experienced researcher. To reproduce the I–Love–Q universal relations in computational astrophysics, it reviewed and cross-validated 20+ papers, implemented the full numerical pipeline, evaluated 300+ equations of state, identified inconsistencies in published formulas, generated 3,000+ lines of Python code, and produced an interactive HTML dashboard for exploring the results.
Knowledge Work
Kimi K3 advances end-to-end knowledge work. Beyond public benchmarks, Kimi K3 (max) demonstrates consistent gains across our internal evaluations, which are derived from recurring patterns and challenges observed in real-world user-agent workflows. These consistent advantages across distinct production-oriented workflows reflect a broad improvement in Kimi K3′s agentic knowledge work capabilities.
Research with Interactive Visualization
Below are a few examples of what Kimi K3 in Kimi Work can produce across financial consulting and scientific research:
Case 1: Interactive 42 years of AI ASIC industry research website
An interactive research report you can drill into: 42 years of the ASIC industry, created through 120+ rounds of recursive self-improvement. Kimi K3 transforms evidence into bespoke charts, animated diagrams, and interactive visual narratives. It pulled data via 2.8k+ web searches/fetches and 1.1k+ terminal data pulls, across 11k+ pages spanning 87 quarterly reports and 99 original PDFs.
Case 2: Fusion Industry Research
A consulting-style industry report with interactive visualizations—including timelines, Funnel Chart, Range Bar Chart, Gantt Charts, and publication-quality slides.
Case 3: GWTC-5 Gravitational-wave Analysis
An analysis of 391 gravitational-wave events using 20+ concurrent subagents, producing 7 scientific visualizations, 2 tables, and a literature synthesis from 10+ papers.
Kimi K3 is also particularly effective at producing infographic-style presentations, such as the fully editable heatmap and annual report shown below:
Widgets and Dashboard
In Kimi Work, we introduce two new features - Widgets and Dashboard - which make interactions with Kimi K3 more visual and persistent. Widgets let you generate interactive components directly within a chat, with connections to local data or external plugins for continuous updates. Dashboard brings the widgets you care about most into one persistent, personalized view organized around a topic, project, or goal.
Video Editing
Kimi K3 excels at motion design, animation, and video editing because its native multimodal architecture understands text, images, and video within the same model.
In one example, K3 created a 3Blue1Brown-style motion-graphics explainer of its own architecture, translating technical ideas into animated diagrams and transitions.
In another, Kimi K3 edited its own teaser video from 56 source clips, handling clip selection, motion-matched cuts, frame-accurate beat synchronization, audio processing, and multiple rounds of revision. A high-density short video like this would typically take an experienced editor one to two working days, or a beginner three to five.
Architecture and Infrastructure
Kimi K3 is built on Kimi Delta Attention (KDA) and Attention Residuals (AttnRes). KDA provides an efficient foundation for scaling attention, while AttnRes selectively retrieves representations across depth rather than accumulating them uniformly. Together, they form the architectural backbone of a model designed to scale well beyond the trillion-parameter regime.
Kimi K3 uses Stable LatentMoE, effectively activating 16 of 896 experts. At this level of sparsity, routing and optimization become first-order challenges. Quantile Balancing derives expert allocation directly from router-score quantiles, eliminating heuristic updates and a sensitive balancing hyperparameter, while Per-Head Muon extends Muon by optimizing attention heads independently for more adaptive learning at scale. Sigmoid Tanh Unit (SiTU) and Gated MLA improve activation control and attention selectivity respectively. Together, these advances enable stable and efficient training at the 2.8-trillion-parameter scale.
Kimi K3 applies quantization-aware training from the SFT stage onward, using MXFP4 weights with MXFP8 activations for broad hardware compatibility. To prevent expert imbalance from degrading throughput at large expert-parallel scales, we introduce a fully balanced expert-parallel training method with static shapes and no host synchronization on the critical path. Since inference efficiency likewise benefits from larger high-bandwidth communication domains, we recommend deploying Kimi K3 on supernode configurations with 64 or more accelerators. Finally, as KDA poses new challenges for conventional prefix caching, we have contributed a corresponding implementation to the vLLM community, to be released alongside the model. KDA with prefill cache allows us to serve Kimi K3 at a highly competitive token price despite its scale and long context.
More technical details will be available in our coming report.
Availability
Kimi K3 Agents: Download or update to the latest Kimi app from your mobile app store, available on iOS, Android, and HarmonyOS, or visit kimi.com.
Work with Kimi K3: Download the latest Kimi Work desktop app, version 3.1.0 or later, available for Windows and Apple silicon Macs.
Code with Kimi K3: Run Kimi Code in your terminal and select Kimi K3 using the /model command.
Build with the Kimi API: Visit the Kimi API Platform and select kimi-k3. Pricing is $0.30/MTok for cache-hit input, $3.00/MTok for cache-miss input, and $15.00/MTok for output. Powered by Mooncake’s disaggregated inference architecture, the official Kimi API achieves a cache hit rate above 90% in coding workloads.
Bring Kimi to your organization: Kimi Enterprise provides enterprise-grade data privacy and member management, with complete separation between personal and organization accounts. Visit the pricing page and select “Get Kimi Enterprise” to subscribe for your team.
Full Benchmark Table
Footnotes
All Kimi K3 results reported below are obtained with the reasoning effort set to ‘max’, setting temperature = 1.0 and top-p = 1.0. Depending on the benchmark, each model is evaluated under one of three agentic harnesses — KimiCode, Claude Code, or Codex — as specified in the notes below.
Coding benchmarks
DeepSWE. Kimi K3 is evaluated with the KimiCode harness. The GLM-5.2 score is taken from the GLM-5.2 release blog (https://z.ai/blog/glm-5.2); all remaining scores are from the official DeepSWE leaderboard (https://deepswe.datacurve.ai/), under which Kimi K3 attains 67.3 with the mini-SWE-agent harness.
Terminal-Bench 2.1. Kimi K3 is evaluated with the KimiCode harness. For all other models, we report the best score across harnesses: GLM-5.2 with Claude Code (https://z.ai/blog/glm-5.2); Claude Opus 4.8 and Claude Fable 5 with Terminus 2 (https://artificialanalysis.ai/evaluations/terminalbench-v2 – 1); GPT 5.5 and GPT 5.6 Sol with Codex (https://openai.com/index/previewing-gpt-5 – 6-sol/).
Program Bench. Kimi K3 is evaluated with the KimiCode harness. The GLM-5.2 score is from https://z.ai/blog/glm-5.2; all other scores are from https://www.vals.ai/benchmarks/programbench.
SWE Marathon. Kimi K3, Claude Opus 4.8, and Claude Fable 5 are evaluated with the Claude Code harness; GPT 5.6 Sol is evaluated with the Codex harness. The GLM-5.2 score is from https://z.ai/blog/glm-5.2.
FrontierSWE. Kimi K3 is evaluated with the KimiCode harness and GPT 5.6 Sol with the Codex harness; all other results are from https://www.frontierswe.com/. Dominance scores are recomputed from the raw scores using the official evaluation script and are current as of July 16, 2026.
PostTrain Bench. Scores for GLM-5.2, GPT 5.5, and Claude Opus 4.8 are adopted from the official PostTrainBench results. Kimi K3, Claude Fable 5, and GPT 5.6 Sol are evaluated with the official Harbor implementation at maximum reasoning effort, averaged over three runs — Kimi K3 and Claude Fable 5 with the Claude Code harness, and GPT 5.6 Sol with the Codex harness. Under the Claude Code harness, requests refused by Claude Fable 5 due to its usage policy automatically fall back to Claude Opus 4.8.
MLS Bench Lite. Kimi K3 is evaluated with the KimiCode harness; GLM-5.2 and the Claude models with the Claude Code harness; GPT 5.5 and GPT 5.6 Sol with the Codex harness.
KCB 2.0. Kimi K3 is evaluated with both the KimiCode and Claude Code harnesses; GLM-5.2, Claude Opus 4.8, and Claude Fable 5 with the Claude Code harness; GPT 5.5 and GPT 5.6 Sol with the Codex harness. All models are evaluated at maximum reasoning effort, except GPT 5.5, which uses the “xhigh” setting.
Productivity and agentic benchmarks
For OfficeQA Pro, each test case provides the agent with the entire PDF corpus, with all PDFs rendered as images and no machine-readable text available.
OfficeQA Pro and SpreadsheetBench 2. Kimi K3, GLM-5.2, Claude Opus 4.8, and Claude Fable 5 are evaluated with the Claude Code harness; GPT 5.5 and GPT 5.6 Sol are evaluated with the Codex harness.
MCP Atlas. All models are evaluated on the 500-task public subset with a 100-turn limit, using Gemini 3.1 Pro as the judge.
AutomationBench. All models are evaluated on the 600-task public subset, following the official GitHub setup in all other respects.
BrowseComp. We adopt the context-compaction strategy used in the Claude model cards, triggered at 300K tokens. When evaluated with a 1M-token context window and no context management, Kimi K3 achieves a score of 90.4. The results of Claude Fable 5, Claude Opus 4.8, GPT 5.6 Sol, and GPT 5.5 are cited from https://www.anthropic.com/news/claude-fable-5-mythos-5 and https://openai.com/index/gpt-5 – 6/.
GDPval-AA v2 and AA-Briefcase scores are cited from https://artificialanalysis.ai/.
Multimodal benchmarks
Except for ZeroBench, which follows the official setting and is run five times, all multimodal scores are averaged over three runs. MMMU-Pro is evaluated following the official protocol, preserving the original input order and prepending images to the text input.
PerceptionBench. PerceptionBench is an in-house benchmark that focuses on atomic visual perception capabilities.
Limitations
Sensitivity to thinking history. K3 was trained in the preserved thinking history mode. If the agent harness fails to pass back all the historical thinking content as required, or if an ongoing session with another model is switched over to K3, generation quality may become highly unstable. We recommend using a harness with verified compatibility, such as Kimi Code, and avoiding switching to K3 in the middle of a session.
Excessive proactiveness. K3′s training places particular emphasis on long-horizon, challenging tasks. As a result, when it encounters minor issues or ambiguous user intent during task execution, it may make unexpected decisions on the user’s behalf. If your application requires the agent to operate within well-defined boundaries and refrain from excessive improvisation, please impose more explicit behavioral constraints on K3 in the system prompt or in AGENTS.md.
Despite being a highly competitive model overall, K3 nonetheless exhibits a noticeable gap in user experience compared with Claude Fable 5 and GPT 5.6 Sol.
The chat client that brought Comic Sans to the world is now on GitHub
Today, we’re excited to announce the open-source release of Microsoft Comic Chat, the chat client that automatically turned conversations within Internet Relay Chat (IRC) into comic panels featuring illustrated characters, speech bubbles, and expressions, and helped introduce the world to a little font called Comic Sans.
Yes, that Comic Sans. Originally designed by Microsoft typographer Vincent Connare in 1994, Comic Sans found its first real home in Comic Chat, where its informal, hand-lettered feel matched the software’s speech-bubble conversations perfectly.
For many people, Comic Chat is a nostalgic artifact from the early days of the internet as we transitioned from technologies like telnet, Usenet, and IRC to the largely visual web that we enjoy today. For others, it’s a legendary piece of Microsoft history they have only heard about in stories, screenshots, and debates about typography. Now, developers, historians, retro computing enthusiasts, and anyone who appreciates a wonderfully unconventional idea can explore the source code for themselves.
A different vision for online communication
Today we’re accustomed to messaging apps with reactions, stickers, GIFs, avatars, video, and AI-generated content. But in the mid-1990s, internet chat was largely walls of scrolling text.
Rather than displaying messages as plain text, Comic Chat presented participants as illustrated characters. Conversations unfolded in comic panels, with speech bubbles, expressions, and gestures generated from what people typed. If someone wrote “I like that,” the character might point to itself. If the text suggested anger, the character might frown or cross its arms. It was quirky, ambitious, occasionally chaotic, and surprisingly forward-looking.
Many ideas we now take for granted in online communication can trace some of their spirit to experiments like Comic Chat.
The people who built it
David “DJ” Kurlander, working in the Microsoft Research Virtual Worlds Group, conceived the idea of a new visual representation of conversational histories, and started developing Comic Chat in 1995. Built in Visual C++ 4.0 and MFC, Comic Chat was released in 1996 with the Internet Explorer 3 web browser.
Under the hood, Comic Chat was more than a clever skin for IRC. It was able to interpret conversational cues in the text and choose appropriate poses, facial expressions, gestures, and panel layouts. That meant Comic Chat was not simply displaying messages but also making real-time editorial decisions about how a conversation should look and feel as a comic. DJ, Tim Skelly, and David Salesin published a paper on the technology in Comic Chat at SIGGRAPH ’96, a computer graphics conference, describing what they had built as an experiment in automatic illustration construction and layout.
The visual world of Comic Chat was the work of Jim Woodring, a highly regarded independent comic artist whose characters gave the software its distinctive look. The team would hand Jim transcripts of real chat sessions to illustrate, then use the results to figure out whether the whole idea was worth pursuing. It was.
Why open source it now?
Comic Chat represents a fascinating chapter in the evolution of online communication. It emerged during a period when the internet was still discovering what it wanted to become. Many rules had not yet been written, which gave developers permission to try bold concepts that might seem unusual even today.
By releasing Comic Chat as open source, we’re preserving an important piece of software history and giving the community an opportunity to explore, learn, and build upon it.
The source is available now for exploration, study, and experimentation. Alongside the original snapshots, we’ve included a few AI-powered modernization attempts that demonstrate what’s possible—getting this 1990s-era C++ and MFC code building with current Visual Studio tools, connecting to modern IRC servers, and running legibly on today’s high-resolution Windows machines. These are not polished re-releases, but worked examples that show Comic Chat can still come alive on modern systems. We’re excited to see what improvements, ports, experiments, and entirely new forms the community brings to it next.
A time capsule of internet optimism
Looking back, Comic Chat captures something special about the era in which it was created.
The early web was filled with experimentation. “What if chat rooms looked like comics?” That question sounds wonderfully unreasonable. And yet it was built, shipped, localized into 24 languages, and bundled with Windows 98.
That’s part of what makes Comic Chat memorable decades later. It reminds us that innovation often starts with ideas that are playful, unconventional, and creative.
One last speech bubble
Comic Chat was created during a period when software teams were willing to color outside the lines, literally and figuratively. DJ Kurlander, Tim Skelly, David Salesin, Jim Woodring, and everyone else who touched this project made something that people still remember and still run thirty years later.
Take a look at the source code, explore what they built, and use its story as inspiration to come up with new unconventionally delightful things to create.
And if you happen to read the source code in Comic Sans, we promise not to judge.
from the poof-it’s-gone dept
In all of our discussions about how the digital revolution has created a system in which people don’t actually own the things they think they’re buying, I get particularly frustrated by the lack of change in it all. We’ve spilled much ink complaining that this clearly anti-consumer practice needs to be done away with, where an unsuspecting public thinks they’re buying “a thing” only to learn months or years later that “the thing” they bought was actually a license to use/view/listen to another “thing”, and that license exists at the pleasure of the company that collected the money for it. And if you want to see the lack of change or action really honed in upon, let’s take a look at Sony’s PlayStation Store.
In 2022, due to “evolving licensing agreements” with distributor StudioCanal, German and Austrian users had hundreds of movies disappear from their PS accounts, long after buying them through Sony. Then in 2023, it happened again in America, specifically when Sony ended its licensing agreement with Discovery after the Warner Bros. merger, which, of course, has since been bought by Paramount Skydance. That resulted in customers having hundreds and hundreds of episodes of TV shows deleted from their accounts. Nowhere in any of this were there refunds, of course. No recompense at all, actually. Just a thing you thought you’d bought taken away from you by the very people you thought you bought it from.
And now it’s happening again. Due to another licensing agreement fallout with StudioCanal, hundreds of movies and TV shows are being ripped from the accounts of PS Store customers, and there appears to be fuck all that they can do about it.
This news was brought to people’s attention by X user somatyk, who posted the notification they had received from PlayStation this week. Along with the unapologetic news that the purchased movies would be deleted from their account on September 1, the message concluded with, “Click here for a full list of affected titles that will no longer be supported. Thank you.” The same warning is now reproduced in full on the PlayStation website, along with the list of 551 films and TV series that are being pulled from people’s libraries.
This news was brought to people’s attention by X user somatyk, who posted the notification they had received from PlayStation this week. Along with the unapologetic news that the purchased movies would be deleted from their account on September 1, the message concluded with, “Click here for a full list of affected titles that will no longer be supported. Thank you.” The same warning is now reproduced in full on the PlayStation website, along with the list of 551 films and TV series that are being pulled from people’s libraries.
As Kotaku notes later in their post, part of what is striking in all of this is the sheer mundanity of the announcement. Because there have been no consequences, or any action at all from the public or government, Sony treats this all as if it’s perfectly normal and no big deal. You can tell me all you want about how the Ts and Cs in these purchases do in fact note that the nature of the purchase is a temporary licensing of the content for an undetermined time period… but I can promise you that the public in general doesn’t understand that. They think they’re buying a thing, not a license.
And that’s because of the purposeful obfuscation of that fact. Sony damned well knows that the vast majority of people don’t read those Ts and Cs. It knows that the public largely doesn’t understand how these backend licensing agreements with distributors work, or that they even exist. And Sony isn’t exactly putting out a big blinking sign on its store pages informing the public of all of this. Instead, the company is only too happy to collect money from a public that is being purposefully kept ignorant of what they’re buying.
Of course, when you scroll past the endless EULAs when you first use your PlayStation, and click “Agree” the first time you load the store, you’re unwittingly agreeing that nothing you buy is really truly bought, and that it can be taken away from you at any point, and there’s nothing you can do. The same is true of your games.
Of course, when you scroll past the endless EULAs when you first use your PlayStation, and click “Agree” the first time you load the store, you’re unwittingly agreeing that nothing you buy is really truly bought, and that it can be taken away from you at any point, and there’s nothing you can do. The same is true of your games.
This, too, will probably pass without any real action. The government has done its best to gut our consumer protection agencies, so they won’t be any help. Angry customers won’t coalesce into activism or action, most likely. And I’ll probably be writing another one of these posts in a couple of years when it all happens again.
But it shouldn’t be that way. There are common sense things that can be done to better inform the public. Rules for how the store should inform people with each and every purchase. Someone just needs to demand it be done.
Filed Under: eula, ownership, playstation, playstation store, video games
Companies: sony, studiocanal
Home
Experiments
Decoy Font
A TTF font that hides what you’re typing from AI. Type a message where each letter contains a decoy.
100%
Hidden message11/48Decoy message11/48
Download Decoy Font
Decoy Font is free to use in personal, commercial, and client projects. Its letterforms are derived from DejaVu Sans Mono; see the full font license for terms.
What is Decoy Font?
Decoy font is a font that prints a decoy for every letter, making it more difficult for AI to read what you type. The font works by using separate spatial frequencies to communicate two different letters in the same space. The foreground contains thin outlines, while the background is a low-frequency mass that is blurred. When overlaid on top of each other, what you see depends on how you look at the letter. If you’re having a hard time seeing the hidden message, move your screen farther away, or try squinting to see it.
Most AI systems work by reading the pixels of an image up close. So when this type of image is pasted into an AI model like ChatGPT, even when the text is small, the llm focuses on the foreground text because that is what is most clearly outlined. However, from a slightly zoomed out distance, the text reads the actual hidden message. This simple illusion is enough to trick even more advanced LLMs like GPT Sol and Gemini 3.5 with Thinking:
Decoy Font also exists as an actual TTF font file that can be installed and used to write complete text. You can download and install the TTF font file here. The following paragraph is written in Decoy Font - you can actually copy the text and paste it into your own notepad.
This sentence is written in Decoy Font
Funnily enough, when we pass a screenshot of this font into ChatGPT, it fails to read it properly, even though it might really clear and obvious to you.
Decoy Font is constructed based on the technique behind hybrid images. This technique has been well studied for many existing optical illusions. One of the most famous is the image of Albert Einstein and Marilyn Monroe mixed together. Decoy Font applies this same idea to typography as a way to protect the words that you are typing from AI or OCR techniques.
We’ve applied this idea of spatial frequencies to create a new font that can used to obscure your writing from AI scrapers.
Anti-AI Fonts
As AI becomes more and more capable at reading text online, there’s been a rising interest in protecting information and IP from it. Anti-AI fonts can help help with obscuring text in images and ensuring that messages that are meant for humans are only read by other humans.
Decoy Font is one of the many experiments at Mixfont that explores this initiative. One of our other explorations in this vein is Ghost Font, another anti-AI font that hides a message in motion. However, where Ghost Font relies on a animation to disguise its message, Decoy Font works as a direct TTF font file and can be directly typed in projects.
Decoy Font is an interesting way to obscure messages, but it’s not a guarantee. Models with powerful agents and coding abilities may be able to see past the initial lettering, and of course with some basic prompting, certain agents should know to look for the hidden letters. However, Decoy Font still serves as a initial point of confusion for AI, which can make it very effective at deterring scraping or casual observation.
What’s next?
If you’re interested in exploring Decoy Font further, you can download the TTF font file and use it in your own projects. You can also use the playground above to test out the spatial frequency technique used by Decoy Font on different letter combinations. Then, take your creations and send them to your favorite frontier LLM to see how well it works to decipher the hidden message.
Because Decoy Font can be downloaded and used as a TTF font file, I believe this makes the idea of obscuring text with AI much more accessible to the public (compared with other techniques that require motion and video). It would be interesting to see how this could be applied to technologies like captcha, or just simpler things like sending private messages between friends.
Using Decoy Font as a benchmark of text recognition LLMs would be interesting. As the intelligence of these frontier models improve, they would more and more be able to understand the techniques behind the illusion and decode both messages.
It would be a fun project to extend Decoy Font to support more languages. I believe that character based languages like Chinese would potentially benefit even more from this technique, as the characters are all roughly the same size and shape, which would make it more easy to hide a hidden message.
At Mixfont, I’m building a frontier AI font generator and I’m always interested to explore new ways that typography and AI intersect. I would love to hear your ideas on Decoy Font and how it can be improved. You can find me on X at @ericlu. Thanks for reading!
Thanks for checking out Decoy Font
For the past year and a half, the team building Roc’s compiler has been rewriting our 300,000 lines of Rust code into Zig, for reasons I’ll recap below. We recently passed an exciting milestone: feature parity with the original compiler!
Since the Bun project recently shared an experience report of their rewrite in the other direction (from Zig to Rust, although that’s only the tip of the iceberg of differences between our rewrites), this seems like a nice time to reflect on how our move from Rust to Zig is going.
Passing Feature Parity
Hitting this milestone made it possible to update Brendan Hansknecht’s charming 2024 WASM-4 game, Rocci Bird (with art by Luke DeVault) to use the new compiler. It’s a nice example because the whole game is under a thousand lines of Roc code, and you can play it on itch.io or right here via WebAssembly:
Click or tap the game, then press Space (or tap) to flap. On mobile you don’t have a right arrow key, so refresh the page to restart the game.
Rocci Bird’s updated source code is a bit more concise than the original, and roc build –opt=size now outputs a 31KB wasm binary. (The original compiler produced a binary more than double that size.) Rocci Bird is by no means a large code base, but getting it to run at all required landing a lot of features in the new compiler. Seeing those chunky purple pixels brought a smile to my face when we finally got there!
To be clear, this is a milestone but not a formal release. (We aim to land version 0.1.0 later this year.) That said, it’s a wonderful milestone to have reached, and I’m extremely grateful to all the people who came together to make this happen! I want to thank some in particular who have been especially helpful in getting the language and compiler to this point:
Anthony Bullard and Sam Mohr for collaborating on the new parser
Jared Ramirez for the new type-checker (among many other things!)
Ayaz Hafiz for the new lambda set resolution system, plus tons of the original compiler
Aurélien Geron for hand-updating 108 (!) beginner exercises in the Roc Exercism course he originally created
Stephan for getting the compiler’s new “echo” platform running in the browser, so that anyone can now write and run basic Roc programs from the roc-lang.org homepage via a 2.5MB WebAssembly binary!
Niclas Åhdén, Roc’s most prolific production user, for patiently filing helpful bug reports and giving actionable feedback about the upgrade process
JRI98 for methodically reproducing and investigating fuzzer errors and other bugs, closing out issues that no longer reproduced, and more
Jasper Woudenberg for iterating on API designs for userspace packages using the new compiler
Folkert de Vries, Brendan Hansknecht, Brian Carroll, Josh Warner, Agus Zubiaga, and Jelle Teeuwissen for building the foundation of the original compiler, without which the new compiler never would have existed
I’ve saved the undisputed biggest contributors to the new compiler for last: Anton-4 and Luke Boswell for so many things I can’t even keep track of them all—compiler work, builtins, platforms, packages, examples, fixing bugs, helping beginners on Roc Zulip…enumerating it all could take up a whole second post! It’s been incredible seeing how much you’ve built.
Thank you all so much! I feel honored that you’ve put so much of your valuable time into this project. Also thanks to our past and present sponsors—rwx, Lambda Class, ohne-makler, martian, tweede golf, Vendr, NoRedInk, and many generous individual sponsors—who have helped get us to this point by supporting our contributors.
Speaking of time: our 487-day rewrite took 476 days longer than Bun’s 11-day rewrite from their ~500K lines of Zig into Rust. There are many reasons for this difference which have nothing to do with Rust or Zig, including the fact that theirs was a direct port whereas we’d decided to rewrite because of how much we were going to change. The techniques they used wouldn’t have worked in our case.
The laundry list of changes we made also means comparing our original Rust code base and new Zig code base won’t be apples-to-apples. Still, we’ve reached a nice point to reflect on how the rewrite has gone, both in terms of what new features it has unlocked for Roc programmers, as well as how our experiences with Rust and Zig have compared.
Let’s get into it!
Hot Code Loading + Cross-Compiled Binaries
Roc’s new compiler automatically does hot code loading during development. For example, I can run roc server.roc to start a Web server, then change some of its code while it’s running. The next time that server handles a request, it’ll automatically be handled using the new code. Here it is in action, both in a server and in a simple 2D game:
Hot loading is standard behavior for interpreted languages like Python, but not so much for high-performance compiled languages like Roc. When I’m ready to deploy, roc build server.roc gets me an LLVM-optimized, self-contained binary that I can drop onto a machine and run.
Roc also cross-compiles; building a static binary that runs on Alpine Linux is as simple as roc build –target=x64musl, and that command will produce the same output bytes (for the same input source code bytes) when run on a Mac or any other system—which not all compilers guarantee.
Pattern Matching with String Interpolation
The HTTP request-handling logic from that video looks like this:
match (verb, path) { (“GET”, “/users/${id}/${page}“) => match page { “” | “profile” => ok(id) “settings” => ok(with_default(user_agent, id)) “posts/${post_id}” => ok(“Post ID: ${post_id}“) _ => not_found }
(“GET”, “/users/${id}“) => ok(id)
(“POST”, “/posts/new”) => created(with_default(…))
_ => not_found }
This uses several features we introduced in the new compiler. For example, that “/users/${id}” syntax is not implemented with parsing template strings at runtime, but rather with a new language feature: string interpolation inside pattern matching.
Not only is this type-safe at compile time, this entire code snippet performs zero heap allocations. I’d expect the typical language that ships with hot code loading to average closer to 1 allocation per line of code here…but Roc is aiming high on ergonomics, type safety, and performance!
You can play around with this syntax on the new roc-lang.org homepage - if you scroll down a bit, there’s an WebAssembly build of the compiler right there on the page that you can use to try out the language.
By the way, if you’re interested in a post on the technical details of how we used the new compiler’s compile-time execution of pure functions to get HTTP request routing down to zero allocations, let me know on Roc Zulip.
By the way, if you’re interested in a post on the technical details of how we used the new compiler’s compile-time execution of pure functions to get HTTP request routing down to zero allocations, let me know on Roc Zulip.
Why a Scratch-Rewrite?
Unlike Rust, C, and Zig, Roc is not a systems language; it has automatic memory management (using reference counting, both to avoid tracing collector pauses and also for Perceus optimizations and opportunistic mutation like Koka’s). Roc would have way more heap allocations if it needed one heap allocation per closure capture (like most non-systems languages do), but our closure captures don’t heap-allocate because Roc is the first non-academic language to implement polymorphic defunctionalization through lambda set specialization.
This might sound like a niche optimization, but in a functional language like Roc, defunctionalization turns out to be similar to inlining in that it unlocks a treasure trove of follow-up optimizations. Although this system proved incredibly beneficial to Roc’s runtime performance, it also proved incredibly difficult for us to implement correctly. We struggled with nasty bugs in the original implementation, and only after Ayaz Hafiz prototyped a new architecture in OCaml were we able to finally get it right in the new compiler.
Ayaz’s prototype showed that the root of our problems was architectural across several compiler phases, and fixing it would require rewriting most of the compiler. This was one reason we decided to rewrite in the first place—that, and several contributors independently mentioning they planned to rewrite various parts of the compiler for other reasons. We realized we were about to rewrite almost all of the compiler anyway, so it made sense to consider a full rewrite as an alternative to the Ship of Theseus approach.
Compilers are unusual in that scratch-rewrites are the norm among successful projects. It’s often the only way to self-host, although not all compilers rewrite into their own language; see for example TypeScript’s rewrite to Go. My position has always been that Roc’s compiler should not self-host, so the idea that someday the benefits of a rewrite might seem to outweigh their notorious costs had frankly never occurred to me.
The more we talked about it, the more sense it made to do what basically every mainstream compiler today has done at some point: rewrite from scratch.
Why Zig?
Once we’d decided to scratch-rewrite, the next question was whether to choose Rust again. Based on our experiences with both Rust and Zig (we were already using Zig for a bunch of primitives in our standard library), we decided to build the entire compiler in Zig this time.
I enjoy Rust, I’ve taught a course on it, and I happily use it daily for my work at Zed. Despite what Internet comments might have us believe, it’s extremely normal for one language to be the best fit for one project, while a different language turns out to be the best fit for a different project. One size does not actually fit all!
I’ve talked in depth about our reasons for going with Zig elsewhere—in writing, on podcasts, and so on—and we only seriously considered Rust and Zig, because those were the only systems languages our team knew well enough. The biggest considerations on our minds when deciding between Rust and Zig were:
Build times. Our cargo build times were a major pain point, even for incremental builds, and getting worse as our code base grew. We expected build times in a Zig rewrite to be much faster.
Memory control. We use a variety of different memory allocators throughout compilation, especially arenas, and struct-of-arrays layouts all over the place. Rust’s ecosystem consistently assumes one global allocator, including soa_rs. Zig’s whole ecosystem assumes granular allocators, and struct-of-arrays support is standard.
Ecosystem relevance. Rust’s ecosystem is much bigger than Zig’s overall…but almost no packages in either ecosystem are relevant to our particular needs. For the niche things we wanted to get off the shelf—such as a faster way to emit LLVM bitcode than wrapping LLVM’s C++ library—more of that code existed in Zig than in Rust.
Memory-unsafety assistance. Rust is designed to isolate memory-unsafe code inside rare unsafe blocks, and use things like miri or Valgrind to vet those. Memory-unsafe code wasn’t rare for us, though (more on this later) and we ended up with about 1,200 uses of unsafe (out of our 300K lines of Rust code; compare to about 40,000 uses of unsafe in rust’s 3.5M lines, and remember that for compilers which emit machine code, like roc and rustc, doing memory-unsafe things is a big part of the job). Zig has more features than Rust for making memory-unsafe code work correctly, and that was the area where we wanted the most help.
After a year and a half of rewriting, how did our expectations of Zig’s benefits line up with the reality of what we got? And which parts of Rust did we end up missing once we no longer had access to them?
Life Without Borrow-Checking
Let’s start with memory safety. There’s a famous 2019 Microsoft presentation that says, on slide 10:
~70% of the vulnerabilities addressed through a security update each year continue to be memory safety issues.
~70% of the vulnerabilities addressed through a security update each year continue to be memory safety issues.
The presentation’s next slide has a breakdown by type of memory safety issue, which paints the following picture when it comes to Rust and Zig specifically:
83.6% of vulnerabilities addressed through a security update in 2018 would have been completely unaffected by the choice of Rust or Zig, because both languages handle all of these scenarios (out-of-bounds reads/write, unsafe casts, uninitialized reads, stack overflows, and non-memory-safety issues) in the same way.
16.4% of the vulnerabilities were specifically use-after-free errors. These could have been caught by Zig’s ReleaseSafe runtime memory-safety checks, or Rust’s borrow checker, or the checks Fil-C uses…modern languages have a variety of ways to help catch UAFs, although these CVEs from 2018 would have almost certainly been from C or C++ code instead.
ReleaseSafe catches use-after-free errors through runtime checks which panic if the program tries to use freed memory. Compared to Rust’s safe subset, Zig’s checks are less comprehensive, have a runtime cost, and can panic. That said, Zig with ReleaseSafe has worked great in practice for the TigerBeetle database, which recently underwent a legendarily meticulous Jepsen report that found only two safety bugs, neither related to memory safety.
ReleaseFast skips these checks in production builds to avoid their overhead, but keeps them in debug builds and tests to catch memory-safety issues during development. If your tests covered every possible real-world code path, ReleaseFast would give you the same safety as ReleaseSafe, but that level of test coverage is rarely practical; the real question is what slips through the coverage cracks in practice. Bun talked about their struggles with use-after-frees, but other widely-used projects building with ReleaseFast have had no CVEs caused by memory unsafety in their Zig code. Ghostty is one, and Zig’s compiler itself is another.
If you want to learn more about these projects, I’ve recorded in-depth conversations with their creators: Joran Greef on TigerBeetle, Mitchell Hashimoto on Ghostty, and Andrew Kelley on Zig.
If you want to learn more about these projects, I’ve recorded in-depth conversations with their creators: Joran Greef on TigerBeetle, Mitchell Hashimoto on Ghostty, and Andrew Kelley on Zig.
Rust code has a different source of memory-safety gaps: the unsafe sections that nearly every Rust program has somewhere in its dependencies. Unsafe Rust has all the memory unsafety risk of ReleaseFast Zig code, but none of the runtime checks to catch issues during development. The Rust ecosytsem has miri to find bugs in non-FFI unsafe code, and Valgrind can help too, but few Rust projects use either. That said, the cultural norm of using unsafe rarely, and auditing it extra carefully, has worked out well enough to earn Rust a strong reputation for memory safety in practice.
Of course, Rust memory unsafety errors can and do still slip through the cracks. Deno, a Bun competitor which is written in Rust, has had memory-unsafety CVEs including an out-of-bounds read as well as a use-after-free, both involving the use of Unsafe Rust. Rocket, a Rust Web Framework, has had a use-after-free CVE, and Actix has had a variety of memory-unsafety CVEs from a period when its use of unsafe was abnormally high.
When we were deciding between Rust and Zig for the new compiler, we were aware of all of this. We knew Rust had a well-deserved reputation for memory safety, but that memory unsafety could still happen, and we’d experienced all of that firsthand with the original compiler. We also knew we’d be using unsafe way more than typical Rust projects, and even though we were already using Valgrind, getting help with innately memory-unsafe code from Zig’s additional checks sounded appealing. We wanted the hard stuff to get easier, and we weren’t worried about use-after-free issues in a compiler where allocations would be overwhelmingly done in arenas with straightforward lifetimes.
We knew high-profile Zig projects had achieved great performance and memory safety in practice, and we decided to aim for becoming another of those success stories.
Memory Safety Post-Rewrite
It’s easy to theorize about how things will go with a particular technology choice, but where the rubber meets the road is what end users encounter in real-world usage. So how has Zig with ReleaseFast worked out for us in practice? How many memory corruption incidents—from use-after-frees or any other cause—have we seen since rewriting our compiler from Rust to Zig?
Here’s a breakdown of bug reports in Roc’s issue tracker, as classified by Claude Opus 4.8:
You might be wondering how the Rust-based compiler had any memory corruption bugs at all, let alone more than double the total count of the Zig-based one. Is it because of that pesky Unsafe Rust again?
Actually, no. None of those 21 memory corruption bugs occurred in the compiler’s logic itself, which is a testament to Rust’s borrow-checker working as intended. The reason we had memory corruption bugs in our Rust-based compiler is that it’s a compiler.
Compilers emit machine instructions. When a machine executes those instructions, they can cause memory corruption, resulting in memory corruption bug reports from the people who experienced them. Regardless of which process had the bug—the compiler or compiled program—in both cases the processor only did the bad thing because the compiler told it to. And in both cases the fix is the same: the compiler’s code must change, since that code was what caused the memory corruption.
Just like every compiler, Roc’s has had bugs, and some of those have been miscompilations that led to memory corruption. That said, while 8 of the 10 memory corruption bugs in the Zig-based compiler were also miscompilations, the remaining 2 were in the compiler itself. Both were use-after-free bugs in error reporting, with the same symptom: filenames in error messages (one in roc check and the other in roc bundle) rendered as useless question-mark-in-diamond characters. Rust’s borrow checker would have caught both.
Now let’s suppose we had instead chosen Rust for our rewrite, or Zig with ReleaseSafe. What would have been the impact in practice, holding all else equal?
After 18 months of development, hundreds of total bug reports, and hundreds of thousands of lines of code, my main takeaway from retrospecting on this table is that picking a different row would have made no appreciable difference to the project. So far our choice has gotten us the outcome we’d hoped for.
As I noted earlier, every project has different needs. When Bun rewrote in the opposite direction—from Zig to Rust—their accompanying post noted:
For Bun, correctly handling the lifetimes of garbage-collected values [from JavaScript] and manually-managed values has been a major source of stability issues - most often small memory leaks and occasionally, crashes. Every memory allocation has to be meticulously reviewed. Where do these bytes get freed? How do we ensure it only gets freed once? Did we check for JavaScript exceptions properly? Is this garbage-collected pointer visible to the conservative stack scanner? Is this garbage collected memory or manually managed memory?
For Bun, correctly handling the lifetimes of garbage-collected values [from JavaScript] and manually-managed values has been a major source of stability issues - most often small memory leaks and occasionally, crashes. Every memory allocation has to be meticulously reviewed. Where do these bytes get freed? How do we ensure it only gets freed once? Did we check for JavaScript exceptions properly? Is this garbage-collected pointer visible to the conservative stack scanner? Is this garbage collected memory or manually managed memory?
Roc’s compiler doesn’t have these particular challenges because it doesn’t interface with JavaScript or any other tracing garbage collector. For Bun, “use-after-free, double-free, and ‘forgot to free’” errors have been “a large percentage of bugs,” whereas errors like these have been a small percentage of Roc’s bugs. And of course Roc’s compiler faces other challenges that Bun doesn’t. Different projects have different needs!
In our case, I’m not sure how I could look back at what’s actually happened and conclude that what we needed was a bigger investment in tooling to prevent memory safety bugs in the compiler itself. There’s a much stronger case that we would benefit from better tooling to catch memory safety bugs in our compiled output, which has always been out of scope for the borrow checker.
Build Times
We wanted faster builds from Zig. Did we get them?
Well, the good news is that zig build –watch -fincremental can rebuild a change to our current ~450K lines of Zig code in about 35 milliseconds. That’s even faster than what we were hoping for when we considered Zig’s build speed a selling point for the rewrite!
The bad news is that Zig’s current stable 0.16.0 release has a bug that breaks -fincremental on our code base. The fix already landed, but to get it we’d have to build on a nightly 0.17.0 prerelease build (which has breaking language changes), along with vendoring and upgrading our affected dependencies to 0.17.0. We decided to wait for the next stable release instead.
As of the last commit that had Rust sources in our code base, here’s a timing comparison on my Intel desktop machine running Ubuntu 26 for building cold (no cache, but packages downloaded locally) compared to doing an incremental rebuild after making a trivial edit to our parser:
Note that our Zig build configuration as of the feature-parity commit was rebuilding rarely-changing artifacts on every build that we later decided to rebuild only on demand. That’s why today’s cold builds are faster than they were back at 300K LoC, even though our lines of code have increased by ~50% since then.
Note that our Zig build configuration as of the feature-parity commit was rebuilding rarely-changing artifacts on every build that we later decided to rebuild only on demand. That’s why today’s cold builds are faster than they were back at 300K LoC, even though our lines of code have increased by ~50% since then.
Rust 1.97 is the current stable release today, and 1.85 was the current stable release 487 days ago (the time our rewrite took to reach to feature parity). So if we’d stayed on Rust for the same duration, we could have seen our incremental build times decrease from 10 seconds to 3.4. That’s a big jump! I really appreciate all the hard work that Rust contributors have done to improve build times. Eliminating 2/3 of our incremental build times over 18 months would have been a very welcome change if we’d stayed on Rust, and it’s a bigger improvement than I would have anticipated in an 18-month period. Bravo!
As impressive as that improvement is, Zig’s 35ms is still way ahead. Not only is it 1/100th the build time of 3.4 seconds, it’s also in a different performance category—and that 35ms is on a Zig code base with ~50% more lines of code than the Rust one that got 3.4s. I expect Roc’s code base to keep growing, and for this gap to keep growing with it; I’ve never heard of any initiative on Rust’s roadmap comparable to -fincremental.
So while our decision to remain on stable 0.16.0 (plus how many of our contributors run Mac laptops with ARM processors; -fincremental only works on x86 – 64 CPUs right now) means we haven’t yet reaped the anticipated build-time rewards of choosing Zig for the rewrite, we certainly have something to look forward to in the next stable Zig release!
Memory Control: Zero-Parse Deserialization
Roc’s new on-disk caching system uses a technique I first learned about from Zig’s compiler, and which Casey Muratori told me is common practice in game programming. It relies on the happy coincidence that if you’re organizing your memory in the way that runs fastest on modern hardware anyway, you can also load it from disk directly into memory and start using it without parsing anything.
Here’s how it works:
All of our compiler data structures are represented as arrays with 32-bit indices over pointers (and often in structure-of-arrays form).
This not only saves memory and runs faster, it also means our data structures can be written directly to disk without needing to be serialized into a different format first.
The bigger benefit is that this lets us deserialize them back into memory without parsing the on-disk bytes in any way. We load the bytes into memory, do some relocations to point our existing data structures to the newly-loaded arrays, and we’re ready to go.
This means we deserialize at the speed of loading the bytes from disk into memory—so, actually I/O bound. If those bytes are already in the operating system’s disk cache, it means we load cached work from previous builds at roughly the speed of memcpy.
When you run roc check twice in a row, the first time it caches all of its outputs on disk using this strategy. The second time, if the input source code files haven’t changed, all the parsed/type-checked/etc. data structures jump straight from disk into memory. It’s extremely fast. roc test similarly caches the outcomes for tests of pure functions (which are deterministic), and all of this is done with file-level granularity, so if you change one file you’ll only be paying for redoing work of that file and any others that depend on it.
This zero-parse deserialization strategy only works because we’re following this programming without pointers style for all of our compiler data structures. If we instead used pointers everywhere (like almost all compilers do), deserialization couldn’t be zero-parse.
This approach has safety risks, however. Similarly to how a pointer in memory can point to the wrong address (e.g. leading to a use-after-free), any index can be used as a lookup into the wrong array at runtime, at which point you end up with whatever random bytes happened to be at that location. Rust’s borrow checker is designed to help with pointer lifetimes, but it doesn’t attempt to answer the question “which index goes with which array?” because that has never been in scope for its design.
Jul 16, 2026
|
We’re renaming NotebookLM to Gemini Notebook. It’s the same standalone product, now doing more across the Google ecosystem and updated with a secure cloud computer.
Your browser does not support the audio element.
Listen to article
[[duration]] minutes
This content is generated by Google AI. Generative AI is experimental
We introduced NotebookLM at Google I/O 2023 as Project Tailwind with a simple goal: help people learn. Now, more than 30 million people and over 600,000 organizations are using it to transform how they work, from business owners creating interactive onboarding materials to students converting notes into audio and video summaries.
Today, we’re renaming NotebookLM to Gemini Notebook. It remains a standalone product focused on being your premier research tool, but it will now do more across the Google ecosystem, including inside the Gemini app and Google Search.
Explore under-the-hood upgrades
To make your research more accurate and powerful, we’ve started to roll out an update that gives every notebook a secure cloud computer. This allows Gemini Notebook to write and execute code natively, helping you conduct complex data analysis grounded in your sources. This is available today for Google AI Ultra users and Workspace business customers with AI Ultra Access and AI Expanded Access. It will roll out to all Pro users on the web over the coming weeks, enabling entirely new output formats and deeper analysis.
Take your notebooks everywhere
Just like a physical notebook, your digital notebooks should go wherever you work. You can already access and create notebooks directly within the Gemini app, with full cross-app syncing between the Gemini app and the standalone Gemini Notebook experience. Soon, we’ll also bring notebooks directly into AI Mode in Search.
To everyone who has been with us since Project Tailwind in 2023, thank you. We’re excited to keep building this ecosystem with you. Try out the new features and let us know what you learn.
Get the latest news from Google in your inbox
Sign up for our newsletters with product updates, event information, special offers, and more.
Your information will be used in accordance with Google’s privacy policy. You may opt out at any time.
SpaceX stock dropped below its initial public offering price for the first time on Wednesday, signaling dwindling hype around the Elon Musk company.
Shares dipped below their IPO price of $135 on Wednesday morning for the first time since listing, a humbling loss for the stock, which had skyrocketed more than 50% in its first days of trading last month.
The shares regained some ground later in the day, closing at $135.27.
The initial offering gave the company a market cap of $2.2 trillion, making it one of the world’s most valuable public companies. For a short period, the IPO also made Musk the world’s first trillionaire, though his net worth now is about $800 billion.
On July 7, the company was added to the Nasdaq-100 after a rule change allowed companies to join 15 days after their IPOs.
SpaceX raised a total of $86 billion after underwriters exercised their right to sell additional shares, on top of the $75 billion initially raised. It was the largest IPO in history.
SpaceX, based near Austin, Texas, is the leading launch services company in the world, with its Falcon 9 rocket accounting for the vast majority of satellites launched last year.
It is also the leading satellite-based broadband provider with its Starlink service. The extraordinary interest in the IPO was driven by Musk’s plans to make the company an AI leader — including plans to launch orbiting satellite data centers powered by the sun that crunch AI data.
The company’s headquarters moved from Hawthorne to Texas in 2024, but it retains large operations in the South Bay city and blasts off regularly from Vandenberg Space Force Base in Santa Barbara County.
Since the IPO, SpaceX has used its newfound wealth to expand in the AI space.
It announced last month that it was acquiring the AI coding startup Cursor for $60 billion, with the deal expected to close in the third quarter. The San Francisco company, founded in 2022, enables engineers to instruct software in English to run coding tasks autonomously.
Musk also merged his xAI artificial intelligence company into SpaceX earlier this year. The combined entity recently announced it was leasing computing power to rivals Anthropic and Google at two terrestrial data centers it has constructed.
Since the IPO, investors have expressed concerns about the company’s spending plans and debt load.
Even with the volatility of the last month, there’s still more uncertainty to come.
The stock could fall further as locked-up shares held by current and former employees are released.
At least 20% of the shares will be released after second-quarter results are disclosed sometime in the coming months, with all the lockups expiring in December.
But Space X isn’t the only megacap stock to experience ups and downs early on.
Shares of Meta, then named Facebook, fell significantly below the IPO price of $38 before recovering. After its May 2012 launch, shares plummeted by nearly 50% and hit a record low of $19.69 in August 2012.
The company took more than 14 months to rebound, finally surpassing its $38 IPO price in July 2013.
More to Read
We built a small agentic harness with one job: hand a model a song, a hard dollar budget, and a set of tools, then get out of the way and let it produce a full music video on its own. The model researches which video models exist, generates clips, watches its own footage, edits with ffmpeg, and assembles a final cut.
A few readers of our last build-off said they wanted to see how tool use actually varies between models, so we gave frontier-level models an open-ended, long-horizon task where each model decides on its own what to research, what to generate, and how to edit. We log every tool call, so you can see exactly how each one worked (full transcripts below).
We ran two models, Claude Fable 5 and GPT-5.6 Sol, each at two budgets ($25 and $100), for four runs total. Every run got the same song (Bruno Mars and Mark Ronson’s “Uptown Funk”), a short text description, and a time-stamped lyric transcript.
The setup
Each model ran an autonomous tool-calling loop with six tools:
plan: a tool for thinking (no cost, no action).
web_search: to research generation models and their APIs and fetch information about music videos (if needed).
get_budget: to check the remaining budget.
generate_image and generate_video: the only tools that spend budget. The model can pick any FAL or Replicate model and pass its own parameters.
run_command: a local shell with ffmpeg/ffprobe available, used to analyze audio, cut and concatenate clips, and mux the final video.
Once the budget hits zero, paid generation is refused, but the model can keep editing. Every model message, tool call, charge, and error was logged. The whole harness is open source at github.com/hershalb/music-video-arena, so you can run it yourself.
The four videos
Each clip below is the model’s final, self-assembled output.mp4, full length with the original song muxed in.
The numbers
All four runs finished on their own (none hit a step or time limit) and all four produced a valid, full-length video with the original song muxed in.
“Generation spend” is the metered FAL cost, which is what the budget caps. At $25 both models nearly exhausted it. At $100 they spent $36.57 (Sol) and $48.60 (Fable), so more budget did translate into more footage. It does not include the cost of running the model itself, which we add below.
Time to finished video
What each model built with
Left to choose their own tools, the models diverged. Three of the four runs went pure text-to-video. Only GPT-5.6 Sol at $25 used an image-to-video pipeline (generating stills first, then animating them). GPT-5.6 Sol at $100 mixed three different video models in a single run.
Prices are FAL’s listed rates, shown per second of output video unless noted. Hailuo 2.3 Standard is priced per video (about $0.28 per 6s clip), and Seedance 1.0 Pro is token-priced (~$0.62 per 5s 1080p clip, shown above as its effective per-second rate). Distinct clips generated per run ranged from 46 to 80.
Tool usage
How each run spent its tool calls (this counts attempts, including failed generation calls).
Each run’s full transcript, every plan, tool call, and command, is here: Fable 5 · $25, Sol · $25, Sol · $100, Fable 5 · $100.
Errors along the way
“Failed calls” are generation requests that returned an error (mostly transient network failures to the provider). They were not charged, but the model spent steps retrying them.
Token usage
Total cost per run
The budget only meters generation (FAL) spend. Adding the LLM token cost for Claude Fable 5 ($10 / $50 per 1M input/output) and GPT-5.6 Sol ($5 / $30), gives the total cost of each run.
For Claude Fable 5, the tokens alone ran $16.99 to $25.05, about 30 – 40% of each run’s total. GPT-5.6 Sol’s token cost stayed near $3 – 4 despite similar token volume.
Method notes
Same inputs for all four runs: song, a short text description, and a time-stamped lyric transcript. Each model chose its own generation models on FAL and did its own ffmpeg editing.
Wall-clock time includes the model’s own retries and any waiting on provider queues.
Generation spend is a best-effort estimate from a per-model price table.
Try it yourself
The arena is open source: github.com/hershalb/music-video-arena. Point it at your own song and budget, swap in whichever models you want to pit against each other, and see what they build. Issues and PRs welcome, we would love feedback on the setup.
Our take
None of the music videos were great, but watching how the models got there was pretty interesting and does show where gaps still clearly exist for frontier-level models. A few things notes:
Character and story consistency was a struggle for all four. Recurring characters drift between shots, and none of the videos hold a coherent storyline from start to finish.
The models take lyrics very literally. “Make a dragon wanna retire, man” gets you an actual dragon on screen. It’s interesting for a few shots, but got a little weird after a while.
Tempo matching is weak. The cuts land on the beat (they all ran the ffmpeg beat detection), but the motion inside the clips, dancing, camera moves, rarely matches the song’s tempo, so it often feels a little off. An example line “gotta kiss myself I’m so pretty”, shows the main character making a kissing motion way too slowly.
GPT-5.6 Sol at $25 was the most inventive editor. It overlaid text and animated still images with video effects, techniques none of the other runs tried. The rest mostly just stitched generated clips together. GPT 5.6 Sol $100 also tried multiple video models instead of just sticking with one like Fable did.
Nobody really iterated on the edit. Once clips existed, the models concatenated and muxed, but rarely went back to re-cut or add effects, and none seriously probed their own clips to confirm they were any good. GPT-5.6 Sol’s $100 run shipped some genuinely low-quality AI clips, while Claude Fable 5 happened to pick a model with more coherent output. Some of this is probably a model limitation, but the lack of self-review is notable.
Neither model touched Replicate. Both FAL and Replicate keys were available, but all four runs used FAL exclusively.
Claude Fable 5 was the pricier pick. It cost more per run (and the most overall, at $73.65) despite finishing faster than GPT-5.6 Sol. Subjectively, we slightly preferred the Fable $100 video, though none blew us away.
$100 was probably too much budget. Neither model wanted to spend near the cap, and both kept their step counts modest. With that headroom they could have, for example, generated consistent character images up front and animated from those, but neither chose to.
We’ll see if models can improve on more subjective/stylistic tasks as they continue to get smarter, but for now there’s still a lot of room for improvement.
Try it yourself
Every model mentioned here is available on TryAI with one account, pay-as-you-go, no subscription.
Today, we’re taking the biggest leap forward in LM Studio’s evolution. Meet LM Studio Bionic, the AI agent made for open models.
Bionic is the AI agent for getting real work done with open models, including coding, research, and complex work with documents and files. You can use local models or switch to open-source models in the cloud for heavier tasks, all while staying in control of your privacy and AI spend.
For all LM Studio Bionic users, we commit to Zero Data Retention and never training on your data.
Bionic brings together:
A Bionic agent that excels at coding and document work
Voice input with state-of-the-art local voice transcription
Flexible model execution: run locally, connect through LM Link, or use the largest frontier open source models through LM Studio Secure Cloud
Better cost control by letting users choose the right model and compute environment for each task
Offline voice transcription
Use Bionic’s voice keyboard with local transcription to speak through ideas, prompts, and edits - all entirely locally on your device, using state-of-the-art local audio models. For launch, we are shipping Voxtral by Mistral AI. Voxtral is a performant multilingual realtime transcription model.
Use Bionic’s voice keyboard to dictate into any app with local transcription.
Start the voice keyboard from any app, and Bionic will begin transcribing where your cursor is.
Bionic for Coding
Bionic supports a wide range of coding needs without giving up privacy and control.
Bionic can inspect local codebases, explain unfamiliar code, and help you make changes.
Create a Code project and point it to a local folder. Ask Bionic to investigate, edit, or debug, and review its work as it goes. Inline diffs make every code change easy to inspect, and with agentic code search, Bionic can quickly find relevant files, trace behavior, and explain unfamiliar code.
Bionic works with powerful open models like GLM 5.2 and Kimi K2.7 Code, so you can build more while keeping costs under control.
Bionic for working with docs, slides, and sheets
Bionic is also built for general productivity and deep knowledge work.
Give Bionic documents to work with, or ask it to generate new documents, decks, spreadsheets, and more from scratch.
Use Bionic across documents, PDFs, decks, spreadsheets, and more. In a Work project, Bionic processes documents in a sandboxed environment, keeping the rest of your computer and files safe. It can organize local directories, edit files, summarize materials, and bring outside context into your workflow with native web search. Automatic checkpoints let you safely review or roll back changes, while in-app previews keep your materials and workflow in one place. We’re continuing to add preview support for more file types, so stay tuned!
Natively Local
Download and run local models in Bionic.
Download the latest local LLMs directly within the Bionic app, then use them for simple chats or advanced agentic tasks. Local models in Bionic are powered by the LM Studio runtime.
Cloud inference with Zero Data Retention by default
Bionic supports the latest frontier open models for your most complex tasks, running on the LM Studio Secure Cloud.
Bionic is built for a world where open models keep getting better. As frontier open source models improve at coding, reasoning, tool calling, and long-context tasks, Bionic gives you a way to try them in LM Studio Secure Cloud. When using cloud models, your requests are processed transiently and are not retained after the request completes.
Getting started
Download LM Studio Bionic.
Bionic is a new, separate app from LM Studio. For advanced low-level configuration, you can continue to use LM Studio alongside Bionic.
To use cloud models, create an LM Studio account to set up billing for your user.
From there, connect a project, choose a model, and start working with the Bionic agent!
What’s next
We’ll keep improving the experience as open models become more capable and as we learn from how people use Bionic in real projects.
To add this web app to your iOS home screen tap the share button and select "Add to the Home Screen".
10HN is also available as an iOS App
If you visit 10HN only rarely, check out the the best articles from the past week.
Visit pancik.com for more.