Flue 2 hooks per turn, Willison ships CORS Chat, Morris the gannet turns 14
Flue 2 mounts agent capabilities per turn, Willison's CORS Chat exposes LM Studio's auth gap, and a lone Pacific gannet clocks 14 years.
Flue 2 hooks per turn, Willison ships CORS Chat, Morris the gannet turns 14
TL;DR
- Flue 2 re-renders the agent function each turn so
useToolanduseSubagentmount capabilities dynamically. - Box pilots Flue 2 hooks against ACL checks, exposing tools only after per-turn auth passes.
- Simon Willison built CORS Chat in a day against LM Studio’s unauthenticated
--corsflag. - Qwen 3.8 27B on a DGX Spark hits 12–20 tok/s, bottlenecked by 273 GB/s LPDDR5x memory.
- Morris the gannet marks 14 years at Pillar Point, the only Northern Gannet ever verified in the Pacific.
Today’s tech pool doesn’t cohere into a single frame, so treat it as three separate reads. The substantive AI item is Flue 2, which ports React’s hooks model into an agent harness: the agent function re-renders before every model call, and useTool / useModel / useSubagent mount capabilities turn-by-turn. Schott is pitching the harness as the programmable surface between Anthropic’s managed SDK and Vercel’s bare primitives, with Box already wiring per-turn hooks into ACL checks. Critics counter that a tight prompt plus one API call still ships 80% of production agents without any of this.
The second drop is Simon Willison’s one-day CORS Chat — a disposable browser UI for OpenAI-compatible endpoints that doubles as a warning about LM Studio’s --cors flag shipping without auth. The closer is off-topic on purpose: Morris, the only Northern Gannet ever verified in the Pacific, has now spent 14 years courting indifferent Brandt’s cormorants at Pillar Point Harbor, likely arrived via a Northwest Passage that thinning Arctic ice reopened for the first time in ~100,000 years.
Flue 2 adds React-style hooks to its agent harness
Source: latent-space · published 2026-08-15
TL;DR
- Flue 2 re-renders the agent function before every model call, letting
useTool,useModel, anduseSubagentmount capabilities turn-by-turn. - Schott positions the harness itself as the programmable surface — between Claude’s managed SDK and Vercel’s bare primitives.
- Early enterprise pilot at Box maps per-turn hooks onto ACL checks, so tools only appear after auth passes.
- Critics flag churning persistence APIs and call early Flue apps “vibe coding” rather than production engineering.
- The sharper counter: a tight prompt plus one API call still beats every abstraction for 80% of shipped agents.
The render loop, applied to agents
Fred Schott’s pitch for Flue 2 is a straight lift from React: the agent function re-executes before every model call, and hooks like useModel(), useSkill(), useTool(), useSubagent(), and usePersistentState() decide what capabilities are mounted for this turn 1. His load-bearing example is an account-management tool that only appears after the user’s identity is verified — the kind of conditional wiring that file-per-agent routing (which Schott now openly calls an antipattern) forces you to fake with router logic.
The mental model matters. In most SDKs, tools are a static registry declared at agent construction. In Flue, the tool list is a function of session state, recomputed every turn. That’s a genuinely different shape, not just new syntax over the same loop.
Where Flue sits in the harness landscape
Independent comparisons place Flue between two poles 2:
| Framework | Philosophy | What ships |
|---|---|---|
| Claude Agent SDK | Managed worker | Shell, file, web tools + full loop |
| Vercel AI SDK | Bare primitives | ToolLoopAgent, assemble yourself |
| Flue 2 | Programmable harness | Hooks + render loop, tools you mount |
The bet is that the harness — not the tools, not the loop — is the surface developers actually want to program. Box’s engineering team says the per-turn hook lifecycle maps cleanly onto request-scoped authorization: tools materialize only after the session’s ACL check passes, without threading permissions through every tool definition 3. That’s a non-obvious benefit of the render-pass design and probably the strongest argument for the abstraction in an enterprise setting.
Cross-language pickup is the other signal. A Python-native port, PyFlue, already exists and explicitly credits Flue’s harness-first philosophy 4 — fast enough that “React for agents” is starting to look like a pattern the ecosystem is converging on, not a one-framework quirk.
The pushback
Not everyone is buying it. Developers Digest notes that recent beta releases have introduced breaking changes to persistence contracts, and echoes the HN charge that early Flue apps read more like “vibe coding” than production engineering 5. The React analogy also inherits React’s known pain points — stale closures, memory bloat in long-lived sessions — which nobody has stress-tested at Flue scale yet.
The sharper critique is architectural. From an r/AI_Agents thread:
The most reliable production agents I’ve shipped are offensively simple — a tight prompt and a plain API call solves 80% of problems. Every added abstraction layer is a new failure point I have to debug at 3am. 6
That’s the real fault line. If your agent is a customer-support bot with three tools, hooks are overkill. If it’s a multi-turn workspace agent whose tool surface depends on identity, org role, and connector state, static registries start to hurt and something like Flue’s render loop earns its keep.
The takeaway
Flue 2 is the clearest articulation yet of a specific bet: that agents are defined by their harnesses, and harnesses want a component model. Whether the React abstraction pays for itself outside complex, stateful agents is the open question — but with Cloudflare backing Schott, Box shipping on it, and a Python port already in the wild, the pattern has enough momentum that the SDK vendors will have to respond.
CORS Chat rides LM Studio’s unauthenticated —cors flag
Source: simon-willison · published 2026-08-15
TL;DR
- Simon Willison shipped CORS Chat, a browser UI for OpenAI-compatible endpoints, coded in a day with GPT-5.6-Sol xhigh.
- LM Studio’s
--corsflag has no built-in auth, so any tab you visit can reach your local model. - Its test target, Qwen 3.8 27B on a DGX Spark, runs at 12–20 tok/s, bottlenecked by 273 GB/s LPDDR5x memory.
- No auth, no RAG, no plugins — fits Willison’s disposable “HTML tools” pattern, not an Open WebUI competitor.
What actually shipped
CORS Chat is a single-page web app that talks to any OpenAI-Responses-compatible endpoint from the browser. Conversations persist in localStorage, exports are copy-pasted JSON, and — the one novel flourish — it parses streamed tokens for SVG tags and progressively renders them as the model is still writing. Willison built it to exercise Qwen 3.8 27B running in LM Studio on both an M5 MacBook Pro and an NVIDIA DGX Spark, plus OpenRouter as a cloud control.
Taken at face value it’s a weekend utility. The interesting story is the stack it sits on.
The --cors flag is the whole security model
CORS Chat is hosted at tools.simonwillison.net and calls localhost. That only works because LM Studio’s --cors flag disables the browser’s same-origin protection wholesale. Practitioner guides are blunt about the tradeoff: enabling CORS “exposes the loaded model to any website the user happens to visit,” and the lms CLI still lacks a built-in mechanism to enforce API keys alongside the flag 7. For a solo developer testing their own machine this is fine. For anyone leaving --cors on while browsing, it’s a drive-by prompt-injection surface — a hostile tab can enumerate models, drain context windows, or poison local RAG stores without any credential.
flowchart LR
A[tools.simonwillison.net<br/>CORS Chat] -->|fetch| B[localhost:1234<br/>LM Studio --cors]
C[Any other tab<br/>you happen to visit] -.->|same fetch works| B
B --> D[Loaded model +<br/>local context]
Willison’s tool doesn’t create the hole. It’s a clean demonstration that the hole is trivial to reach.
The hardware being probed
The DGX Spark half of the test bed matters more than the MacBook. Independent benchmarking pegs dense 27B-class Qwen models at 12–20 tok/s on Spark, with the 273 GB/s LPDDR5x memory bandwidth as the ceiling — an RTX 4090 is 3–4× faster on smaller models 8. Spark’s pitch is capacity (128 GB unified memory, long context) rather than raw throughput. Qwen 3.8 27B itself needs roughly 56 GB VRAM at BF16, with 4-bit quants squeezing into 24 GB, and third-party leaderboard confirmation of Alibaba’s headline claims is still pending 9. CORS Chat is, in effect, a probe pointed at a vendor benchmark the community hasn’t yet reproduced.
Why not just use Open WebUI
The local-chat-UI space is crowded. Open WebUI has passed 140k GitHub stars as the de-facto local model manager; LibreChat is the go-to pixel-perfect ChatGPT clone with deeper multi-provider support 10. CORS Chat competes on none of those axes — no auth, no plugin marketplace, no RAG. That’s consistent with Willison’s documented “HTML tools” pattern: single-file utilities published with full LLM transcripts and Git history in the colophon, meant to be read, forked, and thrown away 11.
The co-author caveat
The “built with GPT-5.6-Sol xhigh” credit is itself worth flagging. Addy Osmani’s notes describe xhigh as OpenAI’s long-horizon coding tier for multi-file work, but with a known weakness where it can be “half-hearted” on frontend, prematurely claiming to be done while leaving subtle bugs 12. Which is precisely the risk profile of a browser tool doing streaming SVG parsing against an endpoint with no auth.
Morris the gannet marks 14 years stranded in the Pacific
Source: simon-willison · published 2026-08-15
TL;DR
- Morris is the only Northern Gannet ever verified in the Pacific Ocean, resident at Pillar Point Harbor for 14 years.
- First identified at Southeast Farallon Island on April 25, 2012 by Point Blue researcher Peter Warzybok.
- Thinning Arctic sea ice likely opened a Northwest Passage corridor closed to diving seabirds for ~100,000 years.
- Every spring he performs full gannet courtship displays to Brandt’s cormorants that ignore him entirely.
The bird in the wrong ocean
Simon Willison’s photo from Pillar Point Harbor is a short local-wildlife post, but the bird in it is a first-of-its-kind record. On April 25, 2012, Point Blue Conservation Science researcher Peter Warzybok photographed a Northern Gannet at Southeast Farallon Island — the first verified Morus bassanus anywhere in the Pacific basin, and a first state record for California 13. The nickname “Morris” is a pun on the genus. He has since relocated inshore to Half Moon Bay’s commercial pier, where he is trivially spotted: the only white-bodied, yellow-headed bird in a raft of small black Brandt’s cormorants.
Fourteen years of continuous residency is the part that matters. This isn’t a one-off vagrant blown off course; it’s evidence that the Pacific can sustain the species year-round, even if it can’t reproduce there.
The climate corridor
The mechanism is the interesting claim. Bay Nature’s 2017 feature argues that thinning summer sea ice creates the open leads diving seabirds need to forage and surface, effectively reopening an Arctic corridor between the Atlantic and Pacific for the first time in ~100,000 years 14. Morris may not have been alone in transit either: two unconfirmed Northern Gannet sightings off Barrow, Alaska in 2010 hint that several birds used the same route around the same time, though only Morris established persistent residency on the other side 15.
That reframes the sighting. A single misplaced seabird is a novelty; a documented Atlantic-to-Pacific faunal exchange with a plausible mechanism and corroborating waypoints is a minor climate data point.
The unanswered dance
The behavioral detail from independent coverage is what gives the story its edge. Every spring Morris reportedly performs the full Northern Gannet courtship repertoire — the ritualized bill-fencing and sky-pointing displays gannets use at Atlantic breeding colonies — directed at his cormorant companions, who remain “entirely unresponsive” 16. It is a clean illustration of reproductive dead-end vagrancy: the bird made it across, but there is nothing on this side of the Arctic for him to breed with.
The supporting flock is itself precarious. Brandt’s cormorants are a “boom-or-bust” forage-fish specialist whose reproductive success swings hard with anchovy and rockfish availability, and warm-water years trigger early nest abandonment 17. Central-California mainland colonies have grown since the 1990s under better breeding-site protection 18, which is presumably why Pillar Point has a reliable cormorant aggregation for Morris to attach to at all. Break the upwelling, and you break the social scaffold holding the Pacific’s only gannet in place.
Fourteen years in, he is still there. For now.
Footnotes
-
Flue Framework blog — ‘Introducing Flue 2’ — https://flueframework.com/blog/flue-2/
↩The agent function re-renders before every model call. Hooks like useModel(), useSkill(), useTool(), useSubagent() and usePersistentState() compose capabilities that can change turn-by-turn — for example, only mounting an account-management tool after the user’s identity is verified.
-
Berto Mill on Medium — ‘Managed Agents vs Agent Primitives’ — https://bertomill.medium.com/managed-agents-vs-agent-primitives-comparing-claudes-agent-sdk-and-vercel-s-ai-sdk-fb99d6b2af5f
↩Claude’s Agent SDK is a ‘managed worker’ that ships with file, shell and web tools built-in, while Vercel’s AI SDK exposes agents as primitives you assemble yourself with a ToolLoopAgent — Flue sits between them by making the harness itself the programmable surface.
-
Box Engineering blog — ‘Flue and Box: a customizable agent harness for enterprise content’ — https://blog.box.com/flue-and-box-customizable-agent-harness-enterprise-content
↩Flue’s harness model let us wire Box’s permissioning and content APIs into an agent loop where tools only appear after the session’s ACL check passes — the hook lifecycle maps cleanly onto our per-turn authorization model.
-
Shashikant Jagtap — ‘Introducing PyFlue’ — https://shashikantjagtap.net/introducing-pyflue-the-python-native-agent-harness-framework-inspired-by-flue/
↩PyFlue is a Python-native port that replicates Flue’s harness-first philosophy and hooks API for the Python ecosystem, signalling how quickly the ‘React for agents’ pattern is being picked up outside TypeScript.
-
Developers Digest — ‘Flue agent harness framework: different or just shiny?’ — https://www.developersdigest.tech/blog/flue-agent-harness-framework-different-or-just-shiny
↩Recent beta releases introduced significant breaking changes to persistence contracts, and some early users on HN have described the development style as ‘vibe coding’ rather than production-grade software engineering.
-
r/AI_Agents thread — ‘Where’s the line between agent framework helping vs hurting?’ — https://www.reddit.com/r/AI_Agents/comments/1tps2wh/wheres_the_line_between_agent_framework_helping/
↩The most reliable production agents I’ve shipped are offensively simple — a tight prompt and a plain API call solves 80% of problems. Every added abstraction layer is a new failure point I have to debug at 3am.
-
cohorte.co — LM Studio production guide — https://cohorte.co/blog/lm-studio-production-grade-local-llm-server
↩Enabling CORS without an accompanying authentication layer exposes the loaded model to any website the user happens to visit; the lms CLI still lacks a robust built-in mechanism to enforce API keys alongside the —cors flag.
-
Exxact — Benchmarking Local AI Agents on NVIDIA DGX Spark — https://www.exxactcorp.com/blog/benchmarks/benchmarking-local-ai-agents-on-nvidia-dgx-spark
↩Dense models like Qwen 3.6 27B typically achieve between 12 and 20 tokens per second on Spark… the LPDDR5x memory bandwidth (~273 GB/s) is a significant bottleneck versus consumer GPUs like the RTX 4090, which can be 3–4x faster for smaller models.
-
kingy.ai — Qwen 3.8 27B review — https://kingy.ai/blog/qwen3-8-27b-specs-benchmarks-local-hardware/
↩The model requires roughly 56GB of VRAM for BF16 weights, though 4-bit quantized versions (GGUF/EXL2) can fit into consumer-grade hardware with 24GB VRAM… verified third-party leaderboard results from LMSYS or the Open LLM Leaderboard are still pending.
-
Onyx — Open WebUI vs LibreChat vs Onyx — https://onyx.app/insights/openwebui-vs-librechat-vs-onyx
↩Open WebUI has become the de-facto standard for local model management with over 140,000 GitHub stars… LibreChat is preferred by organizations seeking a pixel-perfect ChatGPT clone with deeper multi-provider support.
-
Simon Willison — HTML tools pattern post — https://simonwillison.net/2025/Dec/10/html-tools/
↩Every tool is accompanied by a colophon that links to the original Git commit history and the full LLM transcript used to create it… enabling aggressive nit-picking reviews before code reaches production.
-
Addy Osmani — Notes on GPT-5.6-Sol — https://addyosmani.com/notes/gpt-5-6-sol/
↩The xhigh setting is specifically designed for long-horizon coding and multi-file implementations… but developers report it can be ‘half-hearted’ on frontend work, prematurely claiming to be finished while leaving subtle bugs.
-
Oceanic Society — Farallon Islands guide — https://www.oceanicsociety.org/learn/farallon-islands-the-ultimate-guide/
↩On April 25, 2012, researcher Peter Warzybok of Point Blue Conservation Science identified a Northern Gannet at Southeast Farallon Island — the first verified record of this North Atlantic species in the Pacific Ocean.
-
Bay Nature (Spring 2017) — https://baynature.org/magazine/spring2017/atlantic-bird-makes-home-california-maybe-melting-arctic-ice/
↩Researchers hypothesize that as sea ice retreats, it creates expansive areas of open water that allow diving seabirds — which require open leads for foraging and surface access — to traverse the Arctic from the Atlantic to the Pacific.
-
SFGate / Point Blue biologists (Facebook video) — https://www.facebook.com/fb-answers/farallon-island-wildlife/
↩Two undocumented sightings of Northern Gannets off the coast of Barrow, Alaska, in 2010 suggest that several individuals may have utilized melting Arctic corridors to enter the Pacific.
-
SFGate video (Tietz & Hoffman footage) — https://www.facebook.com/SFGate/videos/footage-captured-by-biologists-jim-tietz-and-nick-hoffman-in-late-november-shows/842801281697828/
↩Every spring, Morris reportedly performs traditional gannet mating calls and dances, though his cormorant companions remain entirely unresponsive.
-
Oikonos — Brandt’s cormorant ecosystem study — https://www.oikonos.org/es/publicaciones-archivo/ecosystem-based-management-affecting-brandts-cormorant-resources-and-populations-in-the-central-california-current-region
↩Brandt’s cormorants are a ‘boom-or-bust’ species whose reproductive success fluctuates dramatically based on the availability of prey like anchovies and rockfish; warmer ocean temperatures can cause early nest abandonment.
-
US National Park Service — Brandt’s Cormorant — https://www.nps.gov/articles/000/brandt-s-cormorant.htm
↩Since the 1990s there has been a notable shift toward larger mainland colonies in central California due to improved breeding site protection and shifting fishery management.