11 Apr 2026

feedPlanet Python

Rodrigo Girão Serrão: Personal highlights of PyCon Lithuania 2026

In this article I share my personal highlights of PyCon Lithuania 2026.

Shout out to the organisers and volunteers

This was my second time at PyCon Lithuania and, for the second time in a row, I leave with the impression that everything was very well organised and smooth. Maybe the organisers and volunteers were stressed out all the time - organising a conference is never easy - but everything looked under control all the time and well thought-through.

Thank you for an amazing experience!

And by the way, congratulations for 15 years of PyCon Lithuania. To celebrate, they even served a gigantic cake during the first networking event. The cake was at least 80cm by 30cm:

A picture of a large rectangular cake with the PyCon Lithuania logo in the middle.The PyCon Lithuania cake.

I'll be honest with you: I didn't expect the cake to be good. The quality of food tends to degrade when it's cooked at a large scale... But even the taste was great and the cake had three coloured layers in yellow, green, and red.

Social activities

The organisers prepared two networking events, a speakers' dinner, and three city tours (one per evening) for speakers. There was always something for you to do.

The city tour is a brilliant idea and I wonder why more conferences don't do it:

I had taken the city tour last time I had been at PyCon Lithuania and taking it again was not a mistake.

The conference organisers even made sure that the city tour ended close to the location of the speakers' dinner and that the tour ended at the same time as the dinner started. Another small detail that was carefully planned.

The atmosphere of the restaurant was very pleasant and the staff there was helpful and kind, so we had a wonderful night. At some point, at our table, we noticed that the folks at the other two tables were projecting something on a big screen. There was a large curtain that partially separated our table from the other two, so we took some time to realise that an impromptu Python quiz was about to take place.

I'm (way too) competitive and immediately got up to play. After six questions, which included learning about the existence of the web framework Falcon and correctly reordering the first four sentences of the Zen of Python, I was crowned the winner:

A slanted picture of a blue screen showing the player RGS at the top of the quiz podium.The final score for the quiz.

The top three players got a free spin on the PyCon Lithuania wheel of fortune.

Egg hunt and swag

On each day of the conference there was an egg hunt running throughout the full day. You'd get stamps by talking to sponsors, which is a fun way of getting more people to talk...

11 Apr 2026 12:23pm GMT

Armin Ronacher: The Center Has a Bias

Whenever a new technology shows up, the conversation quickly splits into camps. There are the people who reject it outright, and there are the people who seem to adopt it with religious enthusiasm. For more than a year now, no topic has been more polarising than AI coding agents.

What I keep noticing is that a lot of the criticism directed at these tools is perfectly legitimate, but it often comes from people without a meaningful amount of direct experience with them. They are not necessarily wrong. In fact, many of them cite studies, polls and all kinds of sources that themselves spent time investigating and surveying. And quite legitimately they identified real issues: the output can be bad, the security implications are scary, the economics are strange and potentially unsustainable, there is an environmental impact, the social consequences are unclear, and the hype is exhausting.

But there is something important missing from that criticism when it comes from a position of non-use: it is too abstract.

There is a difference between saying "this looks flawed in principle" and saying "I used this enough to understand where it breaks, where it helps, and how it changes my work." The second type of criticism is expensive. It costs time, frustration, and a genuine willingness to engage.

The enthusiast camp consists of true believers. These are the people who have adopted the technology despite its shortcomings, sometimes even because they enjoy wrestling with them. They have already decided that the tool is worth fitting into their lives, so they naturally end up forgiving a lot. They might not even recognize the flaws because for them the benefits or excitement have already won.

But what does the center look like? I consider myself to be part of the center: cautiously excited, but also not without criticism. By my observation though that center is not neutral in the way people imagine it to be. Its bias is not towards endorsement so much as towards engagement, because the middle ground between rejecting a technology outright and embracing it fully is usually occupied by people willing to explore it seriously enough to judge it.

Bias on Both Sides

The compositions of the groups of people in the discussions about new technology are oddly shaped because one side has paid the cost of direct experience and the other has not, or not to the same degree. That alone creates an asymmetry.

Take coding agents as an example. If you do not use them, or at least not for productive work, you can still criticize them on many grounds. You can say they generate sloppy code, that they lower your skills, etc. But if you have not actually spent serious time with them, then your view of their practical reality is going to be inherited from somewhere else. You will know them through screenshots, anecdotes, the most annoying users on Twitter, conference talks, company slogans, and whatever filtered back from the people who did use them. That is not nothing, but it is not the same as contact.

The problem is not that such criticism is worthless. The problem is that people often mistake non-use for neutrality. It is not. A serious opinion on a new language, framework, device, or way of working usually has some minimum buy-in. You have to cross a threshold of use before your criticism becomes grounded in the thing itself rather than in its reputation.

That threshold is inconvenient. It asks you to spend time on something that may not pay off, and to risk finding yourself at least partially won over. It is a lot to ask of people. But because that threshold exists, the measured middle is rarely populated by people who are perfectly indifferent to change. It is populated by people who were willing to move toward it enough in order to evaluate it properly.

Simultaneously, it's important to remember that usage does not automatically create wisdom. The enthusiastic adopter might have their own distortions. They may enjoy the novelty, feel a need to justify the time they invested, or overgeneralize from the niche where the technology works wonderfully. They may simply like progress and want to be associated with it.

This is particularly visible with AI. There are clearly people who have decided that the future is here, all objections are temporary, and every workflow must now be rebuilt around agents. What makes AI weirder is that it's such a massive shift in capabilities that has triggered a tremendous injection of money, and a meaningful number of adopters have bet their future on that technology.

So if one pole is uninformed abstraction and the other is overcommitted enthusiasm, then surely the center must sit right in the middle between them?

Engagement Is Not Endorsement

The center, I would argue, naturally needs to lean towards engagement. The reason is simple: a genuinely measured opinion on a new technology requires real engagement with it.

You do not get an informed view by trying something for 15 minutes, getting annoyed once, and returning to your previous tools. You also do not get it by admiring demos, listening to podcasts or discussing on social media. You have to use it enough to get past both the first disappointment and the honeymoon phase. Seemingly with AI tools, true understanding is not a matter of hours but weeks of investment.

That means the people in the center are selected from a particular group: people who were willing to give the thing a fair chance without yet assuming it deserved a permanent place in their lives.

That willingness is already a bias towards curiosity and experimentation which makes the center look more like adopters in behavior, because exploration requires use, but it does not make the center identical to enthusiasts in judgment.

This matters because from the perspective of the outright rejecter, all of these people can look the same. If someone spent serious time with coding agents, found them useful in some areas, harmful in others, and came away with a nuanced view, they may still be thrown into the same bucket as the person who thinks agents can do no wrong.

But those are not the same position at all. It's important to recognize that engagement with those tools does not automatically imply endorsement or at the very least not blanket endorsement.

The Center Looks Suspicious

This is why discussions about new technology, and AI in particular feel so polarized. The actual center is hard to see because it does not appear visually centered. From the outside, serious exploration can look a lot like adoption.

If you map opinions onto a line, you might imagine the middle as the point equally distant from rejection and enthusiasm. But in practice that is not how it works. The middle is shifted toward the side of the people who have actually interacted with the technology enough to say something concrete about it. That does not mean the middle has accepted the adopter's conclusion. It means the middle has adopted some of the adopter's behavior, because investigation requires contact.

That creates a strange effect because the people with the most grounded criticism are often also adopters. I would argue some of the best criticism of coding agents right now comes from people who use them extensively. Take Mario: he created a coding agent, yet is also one of the most vocal voices of criticism in the space. These folks can tell you in detail how they fail and they can tell you where they waste time, where they regress code quality, where they need carefully designed tooling, where they only work well in some ecosystems, and where the whole thing falls apart.

But because those people kept using the tools long enough to learn those lessons, they can appear compromised to outsiders. And worse: if they continue to use them, contribute thoughts and criticism back, they are increasingly thrown in with the same people who are devoid of any criticism.

Failure Is Possible

This line of thinking could be seen as an inherent "pro-innovation bias". That would be wrong, as plenty of technology deserves resistance. Many people are right to resist, and sometimes the people who never gave a technology a chance saw problems earlier than everyone else. Crypto is a good reminder: plenty of projects looked every bit as exciting as coding agents do now, and still collapsed when the economics no longer worked.

What matters here is a narrower point. The center is not biased towards novelty so much as towards contact with the thing that creates potential change. The middle ground is not between use and non-use, but between refusal and commitment and the people in the center will often look more like adopters than skeptics, not because they have already made up their minds, but because getting an informed view requires exploration.

If you want to criticize a new thing well, you first have to get close enough to dislike it for the right reasons. And for some technologies, you also have to hang around long enough to understand what, exactly, deserves criticism.

11 Apr 2026 12:00am GMT

10 Apr 2026

feedPlanet Python

Talk Python to Me: #544: Wheel Next + Packaging PEPs

When you pip install a package with compiled code, the wheel you get is built for CPU features from 2009. Want newer optimizations like AVX2? Your installer has no way to ask for them. GPU support? You're on your own configuring special index URLs. The result is fat binaries, nearly gigabyte-sized wheels, and install pages that read like puzzle books. A coalition from NVIDIA, Astral, and QuantSight has been working on Wheel Next: A set of PEPs that let packages declare what hardware they need and let installers like uv pick the right build automatically. Just uv pip install torch and it works. I sit down with Jonathan Dekhtiar from NVIDIA, Ralf Gommers from QuantSight and the NumPy and SciPy teams, and Charlie Marsh, founder of Astral and creator of uv, to dig into all of it.<br/> <br/> <strong>Episode sponsors</strong><br/> <br/> <a href='https://talkpython.fm/sentry'>Sentry Error Monitoring, Code talkpython26</a><br> <a href='https://talkpython.fm/temporal'>Temporal</a><br> <a href='https://talkpython.fm/training'>Talk Python Courses</a><br/> <br/> <h2 class="links-heading mb-4">Links from the show</h2> <div><strong>Guests</strong><br/> <strong>Charlie Marsh</strong>: <a href="https://github.com/charliermarsh?featured_on=talkpython" target="_blank" >github.com</a><br/> <strong>Ralf Gommers</strong>: <a href="https://github.com/rgommers?featured_on=talkpython" target="_blank" >github.com</a><br/> <strong>Jonathan Dekhtiar</strong>: <a href="https://github.com/DEKHTIARJonathan?featured_on=talkpython" target="_blank" >github.com</a><br/> <br/> <strong>CPU dispatcher</strong>: <a href="https://numpy.org/doc/stable/reference/simd/how-it-works.html?featured_on=talkpython" target="_blank" >numpy.org</a><br/> <strong>build options</strong>: <a href="https://numpy.org/doc/stable/reference/simd/build-options.html?featured_on=talkpython" target="_blank" >numpy.org</a><br/> <strong>Red Hat RHEL</strong>: <a href="https://www.redhat.com/en/technologies/linux-platforms/enterprise-linux?featured_on=talkpython" target="_blank" >www.redhat.com</a><br/> <strong>Red Hat RHEL AI</strong>: <a href="https://www.redhat.com/en/products/ai?featured_on=talkpython" target="_blank" >www.redhat.com</a><br/> <strong>RedHats presentation</strong>: <a href="https://wheelnext.dev/summits/2025_03/assets/WheelNext%20Community%20Summit%20-%2006%20-%20Red%20Hat.pdf?featured_on=talkpython" target="_blank" >wheelnext.dev</a><br/> <strong>CUDA release</strong>: <a href="https://developer.nvidia.com/cuda/toolkit?featured_on=talkpython" target="_blank" >developer.nvidia.com</a><br/> <strong>requires a PEP</strong>: <a href="https://discuss.python.org/t/pep-proposal-platform-aware-gpu-packaging-and-installation-for-python/91910?featured_on=talkpython" target="_blank" >discuss.python.org</a><br/> <strong>WheelNext</strong>: <a href="https://wheelnext.dev/?featured_on=talkpython" target="_blank" >wheelnext.dev</a><br/> <strong>Github repo</strong>: <a href="https://github.com/wheelnext?featured_on=talkpython" target="_blank" >github.com</a><br/> <strong>PEP 817</strong>: <a href="https://peps.python.org/pep-0817/?featured_on=talkpython" target="_blank" >peps.python.org</a><br/> <strong>PEP 825</strong>: <a href="https://discuss.python.org/t/pep-825-wheel-variants-package-format-split-from-pep-817/106196?featured_on=talkpython" target="_blank" >discuss.python.org</a><br/> <strong>uv</strong>: <a href="https://docs.astral.sh/uv/?featured_on=talkpython" target="_blank" >docs.astral.sh</a><br/> <strong>A variant-enabled build of uv</strong>: <a href="https://astral.sh/blog/wheel-variants?featured_on=talkpython" target="_blank" >astral.sh</a><br/> <strong>pyx</strong>: <a href="https://astral.sh/blog/introducing-pyx?featured_on=talkpython" target="_blank" >astral.sh</a><br/> <strong>pypackaging-native</strong>: <a href="https://pypackaging-native.github.io?featured_on=talkpython" target="_blank" >pypackaging-native.github.io</a><br/> <strong>PEP 784</strong>: <a href="https://peps.python.org/pep-0784/?featured_on=talkpython" target="_blank" >peps.python.org</a><br/> <br/> <strong>Watch this episode on YouTube</strong>: <a href="https://www.youtube.com/watch?v=761htncGZpU" target="_blank" >youtube.com</a><br/> <strong>Episode #544 deep-dive</strong>: <a href="https://talkpython.fm/episodes/show/544/wheel-next-packaging-peps#takeaways-anchor" target="_blank" >talkpython.fm/544</a><br/> <strong>Episode transcripts</strong>: <a href="https://talkpython.fm/episodes/transcript/544/wheel-next-packaging-peps" target="_blank" >talkpython.fm</a><br/> <br/> <strong>Theme Song: Developer Rap</strong><br/> <strong>🥁 Served in a Flask 🎸</strong>: <a href="https://talkpython.fm/flasksong" target="_blank" >talkpython.fm/flasksong</a><br/> <br/> <strong>---== Don't be a stranger ==---</strong><br/> <strong>YouTube</strong>: <a href="https://talkpython.fm/youtube" target="_blank" ><i class="fa-brands fa-youtube"></i> youtube.com/@talkpython</a><br/> <br/> <strong>Bluesky</strong>: <a href="https://bsky.app/profile/talkpython.fm" target="_blank" >@talkpython.fm</a><br/> <strong>Mastodon</strong>: <a href="https://fosstodon.org/web/@talkpython" target="_blank" ><i class="fa-brands fa-mastodon"></i> @talkpython@fosstodon.org</a><br/> <strong>X.com</strong>: <a href="https://x.com/talkpython" target="_blank" ><i class="fa-brands fa-twitter"></i> @talkpython</a><br/> <br/> <strong>Michael on Bluesky</strong>: <a href="https://bsky.app/profile/mkennedy.codes?featured_on=talkpython" target="_blank" >@mkennedy.codes</a><br/> <strong>Michael on Mastodon</strong>: <a href="https://fosstodon.org/web/@mkennedy" target="_blank" ><i class="fa-brands fa-mastodon"></i> @mkennedy@fosstodon.org</a><br/> <strong>Michael on X.com</strong>: <a href="https://x.com/mkennedy?featured_on=talkpython" target="_blank" ><i class="fa-brands fa-twitter"></i> @mkennedy</a><br/></div>

10 Apr 2026 4:56pm GMT

feedDjango community aggregator: Community blog posts

Django News - DjangoCon Europe Next Week! - Apr 10th 2026

Introduction

Hi everyone, sorry for the late send of Issue #331.

Last week, our provider, Curated, which is owned by Buttondown, went down and wasn't able to send our newsletter for six days. You might have received it yesterday, but not everyone did. It's the first time in several years we haven't been able to land in your inbox.

We've been in touch with their support all week and appreciate your patience while this gets sorted out.

In the meantime, Will and I are looking at other provider options. If this shows up next week looking a little different, that's probably why.

If you missed it, please check out last week's Issue 331: https://django-news.com/issues/331#start

Django Newsletter

News

Django security releases issued: 6.0.4, 5.2.13, and 4.2.30

Django 4.2 has reached the end of extended support. Five CVEs (security vulnerabilities) fixed in this latest update.

djangoproject.com

DjangoCon Europe is next week!

April 15-19 in Athens, Greece. There is a Django.Social event the night before, April 14th, 6-10pm, at Ipitou The Bar, organized by Jon Gould of Foxley Talent and Andrew Miller.

djangocon.eu

Updates to Django

Today, "Updates to Django" is presented by Pradhvan from Djangonaut Space! 🚀

Last week we had 14 pull requests merged into Django by 9 different contributors - including 2 first-time contributors! Congratulations to Eddy ADEGNANDJOU and Rodrigo Vieira 🚀 for having their first commits merged into Django - welcome on board! 🥳

This week's Django highlights: 🦄

Django Newsletter

Django Fellow Reports

Fellow Report - Jacob

In addition to advancing work on pending security issues, reviewed some improvements around accessibility and performance. 3 tickets triaged, 16 reviewed, 12 authored, and more.

djangoproject.com

Fellow Report - Natalia

I was traveling this week so I was less available than usual. My main priority was to support Jacob with anything needed for the upcoming security release, helping keep things on track during a critical phase. I also made an effort to stay on top of inbox and notifications, though seeing my current unread count I can confirm I have failed miserably.

djangoproject.com

Sponsored Link 1

The deployment service for developers and teams.

appliku.com

Articles

Contributing to the Django community

There are a lot of ways to get involved in the Django community; this post goes in-depth to highlight all the various opportunities.

better-simple.com

Switching all of my Python packages to PyPI trusted publishing

How and why the maintainer of django-debug-toolbar and other tools is switching due to recent malicious uploads.

406.ch

A Claude Code Plugin for Triaging Django Issues

django-triage is a Claude Code plugin that searches CVEs, Trac tickets, and Django forum discussions, then scaffolds a structured triage workspace with its findings.

manfre.me

Events

Django Day Copenhagen - Call for Proposals

The third edition will be held on Friday, October 2nd 2026, a full day of talks, followed by an evening of social events.

djangoday.dk

PyOhio 2026 CFP

PyOhio will take place on Saturday & Sunday July 25-26, 2026, at the Cleveland State University Student Center in Cleveland, OH.

pretalx.com

Design Articles

Why frontends fail when you approach them like a backend

A thoughtful exploration of why frontend development is harder than most backend work, covering UX context, accessibility pitfalls, and why "just hacking together HTML and CSS" kills quality.

marijkeluttekes.dev

Sponsored Link 2

You know @login_required. Now meet @app.reasoner(). AgentField turns Python functions into production AI agents, structured output, async execution, agent discovery. Every decorator becomes a REST endpoint. Open source, Apache 2.0. Python, Go & TypeScript SDKs.

agentfield.ai

Django Job Board

Python Developer at Open Data Services

Django Newsletter

Projects

efe/django-root-secret

Django package for managing one root encryption key and decrypting encrypted secrets at runtime.

github.com

danjac/django-studio

Django project generator for rapid, opinionated full stack development.

github.com


This RSS feed is published on https://django-news.com/. You can also subscribe via email.

10 Apr 2026 3:00pm GMT

08 Apr 2026

feedDjango community aggregator: Community blog posts

Switching all of my Python packages to PyPI trusted publishing

Switching all of my Python packages to PyPI trusted publishing

As I have teased on Mastodon, I'm switching all of my packages to PyPI trusted publishing. I have been using it to release the django-debug-toolbar a few times but never set it up myself. The process seemed tedious.

The malicious releases uploaded to PyPI two weeks ago and the blog post about digital attestations in pylock.toml finally pushed me to make the switch. All of my PyPI tokens have been revoked so there is no quick shortcut.

Note

I'm also looking at other code hosting platforms. I have been using git before GitHub existed and I'll probably still use git when GitHub has completed its enshittification. For now the cost/benefit ratio of staying on GitHub is still positive for me. Trusted publishing isn't available everywhere, so for now it is GitHub anyway.

In the end, switching an existing project was easier than expected. I have completed the process for django-prose-editor and feincms3-cookiecontrol.

For my future benefit, here are the step by step instructions I have to follow:

  1. Have a package which is buildable using e.g. uvx build

  2. On PyPI add a trusted publisher in the project's publishing settings:

    • Owner: matthiask, feincms, feinheit, whatever the user or organization's name is.
    • Repository: django-prose-editor
    • Workflow name: publish.yml
    • Environment: release
  3. In the GitHub repository, create a release environment in Settings / Environments. Add myself and potentially also other releasers as a required reviewer. I allow self-review and disallow administrators to bypass the protection rules.

  4. Run git tag x.y.z and git push, no more uvx twine or hatch publish.

  5. Approve the release in the actions tab on the repository.

  6. Either enjoy or swear and repeat the steps.

I'm happy with testing the release process in production. The older I get the less I care if people think I'm stupid. That's also why feincms3-cookiecontrol 1.7.0 doesn't exist, only 1.7.1 - the process failed and I had to bump the patch version and try again. Copy the publish.yml from a known good place, for example from the django-prose-editor repository. I have added the if: github.repository == 'feincms/django-prose-editor' statement which ensures that the workflow only runs in the main repository, but that's optional if you don't care about failing workflows.

08 Apr 2026 5:00pm GMT

How I configured OpenClaw's multi-model setup (so you don't have to)


A heads up before we start: over 95% of this blog post was written by my OpenClaw bot running GLM-5. I reviewed, edited, and approved everything, but credit where it's due: Tepui ⛰️ (yes, I named my AI) did most of the heavy lifting.


I need to vent, but in a good way this time.

Last week I vented about Anthropic pushing away paying customers. After that third-party ban hit, I had to rip out Claude Opus 4.6 from my OpenClaw setup and find alternatives. So I rebuilt the whole thing from scratch.

This time, I did it right.

What I wanted

I use OpenClaw as my personal AI assistant. It connects to my Telegram, manages my calendar, runs cron jobs, helps with research, and generally makes my life easier. Before the ban, it was running Claude Opus 4.6. After the ban, I needed alternatives.

My requirements were simple:

What I got was so much more.

The journey

The whole process took about two hours. I started with a simple question: "What's the best model to use with OpenClaw?"

First thing I did was pull the model catalog from models.dev. If you're not familiar, it's a JSON file maintained by the OpenAI-compatible API community that lists every model from every provider with their specs: context window, token limits, pricing, capabilities, everything. I pulled it to /tmp/models.dev.json and started digging.

curl -s https://models.dev/api.json > /tmp/models.dev.json

Then I checked the Lazer proxy to see what models were actually available. Lazer Technologies (where I work) gives employees free access to a curated set of models through their LiteLLM proxy. The API is OpenAI-compatible, so you just query /v1/models:

curl -s https://llm.lazertechnologies.com/v1/models \
 -H "Authorization: Bearer $LAZER_API_KEY"

The big ones available through Lazer:

These are all free for Lazer employees. If you don't have that luxury, the same models are available through DeepInfra or OpenRouter at reasonable prices.

The problem with my existing setup

My OpenClaw config was bare. I had:

And the MiniMax model was timing out on my cron jobs. The Montevideo Events Report job was failing because MiniMax M2.7 was too slow for complex reasoning tasks. I needed something faster, and free through Lazer.

The realization about model slots

This is where I learned something new. OpenClaw doesn't just have one "model" config. It has six:

  1. agents.defaults.model : Primary text model (plus fallbacks)
  2. agents.defaults.imageModel : For image input (when primary can't accept images)
  3. agents.defaults.pdfModel : For PDF parsing (falls back to imageModel)
  4. agents.defaults.imageGenerationModel : For creating images (not just viewing them)
  5. agents.defaults.musicGenerationModel : For music generation
  6. agents.defaults.videoGenerationModel : For video generation

I was only using slot #1. No wonder images weren't working right.

What I configured

After some back-and-forth with Tepui (yes, I named my AI), here's what we landed on:

Role Model Provider Cost (per 1M tokens)
Primary text GLM-5 Lazer $0.80 / $2.56
Fallback GLM-5 OpenRouter $0.80 / $2.56
Image/PDF input GLM-4.6V Lazer $0.30 / $0.90
Image generation Gemini 3.1 Flash Image OpenRouter $0.50 / $3.00
Quick tasks (reserve) GPT-OSS-120b-Turbo Lazer $0.15 / $0.60
Video-capable (reserve) Kimi-K2.5-Turbo Lazer $0.60 / $3.00

I'm putting actual prices in because Lazer's proxy is free for me, but I want to track costs as if I were paying. That way I know the real value of what I'm using.

Why these choices?

GLM-5 for text. It's the best open-source reasoning model available. 200K context window, MIT licensed, competitive with GPT-4 on agentic tasks. I tested it with quick prompts and it's snappy.

GLM-5 via OpenRouter as fallback. Same model, different provider. If the Lazer proxy goes down, OpenClaw keeps working through OpenRouter with the exact same model. No quality drop, just a different route. I also kept MiniMax M2.7 in the allowlist so I can switch to it manually if I ever need to.

GLM-4.6V for images and PDFs. This was the key insight. GLM-5 is text-only. For images and PDFs, I needed a vision model. GLM-4.6V handles both, and it's on the same Lazer proxy. This means my cron jobs can parse images (like parking receipts) without hitting paid APIs.

Fun fact: I actually added the GLM-4.6V model to my config from my car while waiting for my girlfriend to finish her driving classes. I was using my OpenCode server running at home, connected through WireGuard on my phone. Pulled the model specs from models.dev, updated the config, tested it with a screenshot. All from the car. That's the beauty of having your tools always running and always accessible.

Gemini 3.1 Flash Image for generation. I didn't have any image generation set up. Tepui suggested Flux.2 Pro (free on OpenRouter) but I wanted something more capable. Gemini 3.1 Flash Image generates high-quality images for about $3 per million output tokens. Worth it for occasional use.

The config changes

Here's what I actually changed in ~/.openclaw/openclaw.json:

// Primary model with fallback
agents.defaults.model: {
 primary: "lazer/deepinfra/zai-org/GLM-5",
 fallbacks: ["openrouter/zai-org/GLM-5"]
}

// Vision for images and PDFs
agents.defaults.imageModel: {
 primary: "lazer/deepinfra/zai-org/GLM-4.6V"
}
agents.defaults.pdfModel: {
 primary: "lazer/deepinfra/zai-org/GLM-4.6V"
}

// Image generation
agents.defaults.imageGenerationModel: {
 primary: "openrouter/google/gemini-3.1-flash-image-preview"
}

I also added all the models to the allowlist with aliases so I can switch easily:

agents.defaults.models: {
 "openrouter/minimax/minimax-m2.7": { alias: "MiniMax" },
 "openrouter/zai-org/GLM-5": { alias: "GLM-5-OR" },
 "lazer/deepinfra/zai-org/GLM-5": { alias: "GLM-5" },
 "lazer/deepinfra/zai-org/GLM-4.6V": { alias: "GLM-4.6V" },
 "lazer/deepinfra/openai/gpt-oss-120b-Turbo": { alias: "GPT-OSS" },
 "lazer/deepinfra/moonshotai/Kimi-K2.5-Turbo": { alias: "Kimi" },
 "openrouter/google/gemini-3.1-flash-image-preview": { alias: "Gemini-Image" }
}

The aliases make it easy to switch with /model commands in chat.

Testing it

I tested everything:

The vision model works. The text model works. The fallback is there if something breaks.

What I learned

GLM-5 doesn't support images. The model name sounds like it should be the successor to GLM-4.6V, but it's text-only. For vision, you need GLM-4.6V specifically.

Model config fields are strict. OpenClaw's schema only accepts certain fields: id, name, input, contextWindow, maxTokens, reasoning, cost, api. Things like tool_call and temperature get rejected.

models.dev is the source of truth. Don't rely on memory or provider docs. Pull the JSON and check the specs yourself.

OpenClaw model slots matter. If you're only configuring one model, you're missing out on image parsing, PDF reading, and image generation. Set up all six slots.

Pricing matters even when free. I have free access through Lazer, but I still track prices. It helps me understand the cost of what I'm doing and compare alternatives.

The result

My OpenClaw setup is now:

And the cron jobs that were timing out? They're running fine now. The Montevideo Events Report takes 23 seconds instead of timing out at 75 seconds.

Not bad for two hours of work.

What's next

I kept GPT-OSS-120b-Turbo and Kimi-K2.5-Turbo in reserve. GPT-OSS is cheaper than GLM-5 for quick tasks, so I might use it as a second fallback. Kimi has video support, which could be useful if I ever need to analyze video frames.

But for now, this setup covers everything I need. Text, images, PDFs, generation, fallbacks. All configured properly with the right models in the right slots.

If you're running OpenClaw (or any AI assistant), do yourself a favor: check your model config. Make sure you're using the right slots. Pull the specs from models.dev. Track your actual costs. And test everything with real inputs.

It's worth the two hours.

See you in the next one!

08 Apr 2026 5:00am GMT

04 Apr 2026

feedPlanet Twisted

Donovan Preston: Using osascript with terminal agents on macOS

Here is a useful trick that is unreasonably effective for simple computer use goals using modern terminal agents. On macOS, there has been a terminal osascript command since the original release of Mac OS X. All you have to do is suggest your agent use it and it can perform any application control action available in any AppleScript dictionary for any Mac app. No MCP set up or tools required at all. Agents are much more adapt at using rod terminal commands, especially ones that haven't changed in 30 years. Having a computer control interface that hasn't changed in 30 years and has extensive examples in the Internet corpus makes modern models understand how to use these tools basically Effortlessly. macOS locks down these permissions pretty heavily nowadays though, so you will have to grant the application control permission to terminal. But once you have done that, the range of possibilities for commanding applications using natural language is quite extensive. Also, for both Safari and chrome on Mac, you are going to want to turn on JavaScript over AppleScript permission. This basically allows claude or another agent to debug your web applications live for you as you are using them.In chrome, go to the view menu, developer submenu, and choose "Allow JavaScript from Apple events". In Safari, it's under the safari menu, settings, developer, "Allow JavaScript from Apple events". Then you can do something like "Hey Claude, would you Please use osascript to navigate the front chrome tab to hacker news". Once you suggest using OSA script in a session it will figure out pretty quickly what it can do with it. Of course you can ask it to do casual things like open your mail app or whatever. Then you can figure out what other things will work like please click around my web app or check the JavaScript Console for errors. Another very important tips for using modern agents is to try to practice using speech to text. I think speaking might be something like five times faster than typing. It takes a lot of time to get used to, especially after a lifetime of programming by typing, but it's a very interesting and a different experience and once you have a lot of practice It starts to to feel effortless.

04 Apr 2026 1:31pm GMT

16 Mar 2026

feedPlanet Twisted

Donovan Preston: "Start Drag" and "Drop" to select text with macOS Voice Control

I have been using macOS voice control for about three years. First it was a way to reduce pain from excessive computer use. It has been a real struggle. Decades of computer use habits with typing and the mouse are hard to overcome! Text selection manipulation commands work quite well on macOS native apps like apps written in swift or safari with an accessibly tagged webpage. However, many webpages and electron apps (Visual Studio Code) have serious problems manipulating the selection, not working at all when using "select foo" where foo is a word in the text box to select, or off by one errors when manipulating the cursor position or extending the selection. I only recently expanded my repertoire with the "start drag" and "drop" commands, previously having used "Click and hold mouse", "move cursor to x", and "release mouse". Well, now I have discovered that using "start drag x" and "drop x" makes a fantastic text selection method! This is really going to improve my speed. In the long run, I believe computer voice control in general is going to end up being faster than WIMP, but for now the awkwardly rigid command phrasing and the amount of times it misses commands or misunderstands commands still really holds it back. I've been learning the macOS Voice Control specific command set for years now and I still reach for the keyboard and mouse way too often.

16 Mar 2026 11:04am GMT

04 Mar 2026

feedPlanet Twisted

Glyph Lefkowitz: What Is Code Review For?

Humans Are Bad At Perceiving

Humans are not particularly good at catching bugs. For one thing, we get tired easily. There is some science on this, indicating that humans can't even maintain enough concentration to review more than about 400 lines of code at a time..

We have existing terms of art, in various fields, for the ways in which the human perceptual system fails to register stimuli. Perception fails when humans are distracted, tired, overloaded, or merely improperly engaged.

Each of these has implications for the fundamental limitations of code review as an engineering practice:

Never Send A Human To Do A Machine's Job

When you need to catch a category of error in your code reliably, you will need a deterministic tool to evaluate - and, thanks to our old friend "alert fatigue" above - ideally, to also remedy that type of error. These tools will relieve the need for a human to make the same repetitive checks over and over. None of them are perfect, but:

Don't blame reviewers for missing these things.

Code review should not be how you catch bugs.

What Is Code Review For, Then?

Code review is for three things.

First, code review is for catching process failures. If a reviewer has noticed a few bugs of the same type in code review, that's a sign that that type of bug is probably getting through review more often than it's getting caught. Which means it's time to figure out a way to deploy a tool or a test into CI that will reliably prevent that class of error, without requiring reviewers to be vigilant to it any more.

Second - and this is actually its more important purpose - code review is a tool for acculturation. Even if you already have good tools, good processes, and good documentation, new members of the team won't necessarily know about those things. Code review is an opportunity for older members of the team to introduce newer ones to existing tools, patterns, or areas of responsibility. If you're building an observer pattern, you might not realize that the codebase you're working in already has an existing idiom for doing that, so you wouldn't even think to search for it, but someone else who has worked more with the code might know about it and help you avoid repetition.

You will notice that I carefully avoided saying "junior" or "senior" in that paragraph. Sometimes the newer team member is actually more senior. But also, the acculturation goes both ways. This is the third thing that code review is for: disrupting your team's culture and avoiding stagnation. If you have new talent, a fresh perspective can also be an extremely valuable tool for building a healthy culture. If you're new to a team and trying to build something with an observer pattern, and this codebase has no tools for that, but your last job did, and it used one from an open source library, that is a good thing to point out in a review as well. It's an opportunity to spot areas for improvement to culture, as much as it is to spot areas for improvement to process.

Thus, code review should be as hierarchically flat as possible. If the goal of code review were to spot bugs, it would make sense to reserve the ability to review code to only the most senior, detail-oriented, rigorous engineers in the organization. But most teams already know that that's a recipe for brittleness, stagnation and bottlenecks. Thus, even though we know that not everyone on the team will be equally good at spotting bugs, it is very common in most teams to allow anyone past some fairly low minimum seniority bar to do reviews, often as low as "everyone on the team who has finished onboarding".

Oops, Surprise, This Post Is Actually About LLMs Again

Sigh. I'm as disappointed as you are, but there are no two ways about it: LLM code generators are everywhere now, and we need to talk about how to deal with them. Thus, an important corollary of this understanding that code review is a social activity, is that LLMs are not social actors, thus you cannot rely on code review to inspect their output.

My own personal preference would be to eschew their use entirely, but in the spirit of harm reduction, if you're going to use LLMs to generate code, you need to remember the ways in which LLMs are not like human beings.

When you relate to a human colleague, you will expect that:

  1. you can make decisions about what to focus on based on their level of experience and areas of expertise to know what problems to focus on; from a late-career colleague you might be looking for bad habits held over from legacy programming languages; from an earlier-career colleague you might be focused more on logical test-coverage gaps,
  2. and, they will learn from repeated interactions so that you can gradually focus less on a specific type of problem once you have seen that they've learned how to address it,

With an LLM, by contrast, while errors can certainly be biased a bit by the prompt from the engineer and pre-prompts that might exist in the repository, the types of errors that the LLM will make are somewhat more uniformly distributed across the experience range.

You will still find supposedly extremely sophisticated LLMs making extremely common mistakes, specifically because they are common, and thus appear frequently in the training data.

The LLM also can't really learn. An intuitive response to this problem is to simply continue adding more and more instructions to its pre-prompt, treating that text file as its "memory", but that just doesn't work, and probably never will. The problem - "context rot" is somewhat fundamental to the nature of the technology.

Thus, code-generators must be treated more adversarially than you would a human code review partner. When you notice it making errors, you always have to add tests to a mechanical, deterministic harness that will evaluates the code, because the LLM cannot meaningfully learn from its mistakes outside a very small context window in the way that a human would, so giving it feedback is unhelpful. Asking it to just generate the code again still requires you to review it all again, and as we have previously learned, you, a human, cannot review more than 400 lines at once.

To Sum Up

Code review is a social process, and you should treat it as such. When you're reviewing code from humans, share knowledge and encouragement as much as you share bugs or unmet technical requirements.

If you must reviewing code from an LLM, strengthen your automated code-quality verification tooling and make sure that its agentic loop will fail on its own when those quality checks fail immediately next time. Do not fall into the trap of appealing to its feelings, knowledge, or experience, because it doesn't have any of those things.

But for both humans and LLMs, do not fall into the trap of thinking that your code review process is catching your bugs. That's not its job.

Acknowledgments

Thank you to my patrons who are supporting my writing on this blog. If you like what you've read here and you'd like to read more of it, or you'd like to support my various open-source endeavors, you can support my work as a sponsor!

04 Mar 2026 5:24am GMT

22 Jan 2026

feedPlanet Plone - Where Developers And Integrators Write

Maurits van Rees: Mikel Larreategi: How we deploy cookieplone based projects.

We saw that cookieplone was coming up, and Docker, and as game changer uv making the installation of Python packages much faster.

With cookieplone you get a monorepo, with folders for backend, frontend, and devops. devops contains scripts to setup the server and deploy to it. Our sysadmins already had some other scripts. So we needed to integrate that.

First idea: let's fork it. Create our own copy of cookieplone. I explained this in my World Plone Day talk earlier this year. But cookieplone was changing a lot, so it was hard to keep our copy updated.

Maik Derstappen showed me copier, yet another templating language. Our idea: create a cookieplone project, and then use copier to modify it.

What about the deployment? We are on GitLab. We host our runners. We use the docker-in-docker service. We develop on a branch and create a merge request (pull request in GitHub terms). This activates a piple to check-test-and-build. When it is merged, bump the version, use release-it.

Then we create deploy keys and tokens. We give these access to private GitLab repositories. We need some changes to SSH key management in pipelines, according to our sysadmins.

For deployment on the server: we do not yet have automatic deployments. We did not want to go too fast. We are testing the current pipelines and process, see if they work properly. In the future we can think about automating deployment. We just ssh to the server, and perform some commands there with docker.

Future improvements:

  • Start the docker containers and curl/wget the /ok endpoint.
  • lock files for the backend, with pip/uv.

22 Jan 2026 9:43am GMT

Maurits van Rees: Jakob Kahl and Erico Andrei: Flying from one Plone version to another

This is a talk about migrating from Plone 4 to 6 with the newest toolset.

There are several challenges when doing Plone migrations:

  • Highly customized source instances: custom workflow, add-ons, not all of them with versions that worked on Plone 6.
  • Complex data structures. For example a Folder with a Link as default page, with pointed to some other content which meanwhile had been moved.
  • Migrating Classic UI to Volto
  • Also, you might be migrating from a completely different CMS to Plone.

How do we do migrations in Plone in general?

  • In place migrations. Run migration steps on the source instance itself. Use the standard upgrade steps from Plone. Suitable for smaller sites with not so much complexity. Especially suitable if you do only a small Plone version update.
  • Export - import migrations. You extract data from the source, transform it, and load the structure in the new site. You transform the data outside of the source instance. Suitable for all kinds of migrations. Very safe approach: only once you are sure everything is fine, do you switch over to the newly migrated site. Can be more time consuming.

Let's look at export/import, which has three parts:

  • Extraction: you had collective.jsonify, transmogrifier, and now collective.exportimport and plone.exportimport.
  • Transformation: transmogrifier, collective.exportimport, and new: collective.transmute.
  • Load: Transmogrifier, collective.exportimport, plone.exportimport.

Transmogrifier is old, we won't talk about it now. collective.exportimport: written by Philip Bauer mostly. There is an @@export_all view, and then @@import_all to import it.

collective.transmute is a new tool. This is made to transform data from collective.exportimport to the plone.exportimport format. Potentially it can be used for other migrations as well. Highly customizable and extensible. Tested by pytest. It is standalone software with a nice CLI. No dependency on Plone packages.

Another tool: collective.html2blocks. This is a lightweight Python replacement for the JavaScript Blocks conversion tool. This is extensible and tested.

Lastly plone.exportimport. This is a stripped down version of collective.exportimport. This focuses on extract and load. No transforms. So this is best suited for importing to a Plone site with the same version.

collective.transmute is in alpha, probably a 1.0.0 release in the next weeks. Still missing quite some documentation. Test coverage needs some improvements. You can contribute with PRs, issues, docs.

22 Jan 2026 9:43am GMT

Maurits van Rees: Fred van Dijk: Behind the screens: the state and direction of Plone community IT

This is a talk I did not want to give.

I am team lead of the Plone Admin team, and work at kitconcept.

The current state: see the keynotes, lots happening on the frontend. Good.

The current state of our IT: very troubling and daunting.

This is not a 'blame game'. But focussing on resources and people this conference should be a first priority. We are a real volunteer organisation, nobody is pushing anybody around. That is a strength, but also a weakness. We also see that in the Admin team.

The Admin team is 4 senior Plonistas as allround admin, 2 release managers, 2 CI/CD experts. 3 former board members, everyone overburdened with work. We had all kinds of plans for this year, but we have mostly been putting out fires.

We are a volunteer organisation, and don't have a big company behind us that can throw money at the problems. Strength and weakness. In all society it is a problem that volunteers are decreasing.

Root causes:

  • We failed to scale down in time in our IT landscape and usage.
  • We have no clean role descriptions, team descriptions, we can't ask a minimum effort per week or month.
  • The trend is more communication channels, platforms to join and promote yourself, apps to use.

Overview of what have have to keep running as admin team:

  • Support main development process: github, CI/CD, Jenkins main and runners, dist.plone.org.
  • Main communication, documentation: pone.org, docs.plone.org, training.plone.org, conf and country sites, Matomo.
  • Community office automation: Google docds, workspacae, Quaive, Signal, Slack
  • Broader: Discourse and Discord

The first two are really needed, the second we already have some problems with.

Some services are self hosted, but also a lot of SAAS services/platforms. In all, it is quite a bit.

The Admin team does not officially support all of these, but it does provide fallback support. It is too much for the current team.

There are plans for what we can improve in the short term. Thank you to a lot of people that I have already talked to about this. 3 areas: GitHub setup and config, Google Workspace, user management.

On GitHub we have a sponsored OSS plan. So we have extra features for free, but it not enough by far. User management: hard to get people out. You can't contact your members directly. E-mail has been removed, for privacy. Features get added on GitHub, and no complete changelog.

Challenge on GitHub: we have public repositories, but we also have our deployments in there. Only really secure would be private repositories, otherwise the danger is that credentials or secret could get stolen. Every developer with access becomes an attack vector. Auditing is available for only 6 months. A simple question like: who has been active for the last 2 years? No, can't do.

Some actionable items on GitHub:

  • We will separate the contributor agreement check from the organisation membership. We create a hidden team for those who signed, and use that in the check.
  • Cleanup users, use Contributors team, Developers
  • Active members: check who has contributed the last years.
  • There have been security incidents. Someone accidentally removed a few repositories. Someone's account got hacked, luckily discovered within a few hours, and some actions had already been taken.
  • More fine grained teams to control repository access.
  • Use of GitHub Discussions for some central communication of changes.
  • Use project management better.
  • The elephant in the room that we have practice on this year, and ongoing: the Collective organisation. This was free for all, very nice, but the development world is not a nice and safe place anymore. So we already needed to lock down some things there.
  • Keep deployments and the secrets all out of GitHub, so no secrets can be stolen.

Google Workspace:

  • We are dependent on this.
  • No user management. Admins have had access because they were on the board, but they kept access after leaving the board. So remove most inactive users.
  • Spam and moderation issues
  • We could move to Google docs for all kinds of things. Use Google workspace drives for all things. But the Drive UI is a mess, so docs can be in your personal account without you realizing it.

User management:

  • We need separate standalone user management, but implementation is not clear.
  • We cannot contact our members one on one.

Oh yes, Plone websites:

  • upgrade plone.org
  • self preservation: I know what needs to be done, and can do it, but have no time, focusing on the previous points instead.

22 Jan 2026 9:43am GMT