<?xml version="1.0" encoding="utf-8"?>
<feed xml:lang="en-us" xmlns="http://www.w3.org/2005/Atom"><title>Simon Willison's Weblog: anthony-shaw</title><link href="http://simonwillison.net/" rel="alternate"/><link href="http://simonwillison.net/tags/anthony-shaw.atom" rel="self"/><id>http://simonwillison.net/</id><updated>2025-08-13T05:39:07+00:00</updated><author><name>Simon Willison</name></author><entry><title>simonw/codespaces-llm</title><link href="https://simonwillison.net/2025/Aug/13/codespaces-llm/#atom-tag" rel="alternate"/><published>2025-08-13T05:39:07+00:00</published><updated>2025-08-13T05:39:07+00:00</updated><id>https://simonwillison.net/2025/Aug/13/codespaces-llm/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/simonw/codespaces-llm"&gt;simonw/codespaces-llm&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;a href="https://github.com/features/codespaces"&gt;GitHub Codespaces&lt;/a&gt; provides full development environments in your browser, and is free to use with anyone with a GitHub account. Each environment has a full Linux container and a browser-based UI using VS Code.&lt;/p&gt;
&lt;p&gt;I found out today that GitHub Codespaces come with a &lt;code&gt;GITHUB_TOKEN&lt;/code&gt; environment variable... and that token works as an API key for accessing LLMs in the &lt;a href="https://docs.github.com/en/github-models"&gt;GitHub Models&lt;/a&gt; collection, which includes &lt;a href="https://github.com/marketplace?type=models"&gt;dozens of models&lt;/a&gt; from OpenAI, Microsoft, Mistral, xAI, DeepSeek, Meta and more.&lt;/p&gt;
&lt;p&gt;Anthony Shaw's &lt;a href="https://github.com/tonybaloney/llm-github-models"&gt;llm-github-models&lt;/a&gt; plugin for my &lt;a href="https://llm.datasette.io/"&gt;LLM tool&lt;/a&gt; allows it to talk directly to GitHub Models. I filed &lt;a href="https://github.com/tonybaloney/llm-github-models/issues/49"&gt;a suggestion&lt;/a&gt; that it could pick up that &lt;code&gt;GITHUB_TOKEN&lt;/code&gt; variable automatically and Anthony &lt;a href="https://github.com/tonybaloney/llm-github-models/releases/tag/0.18.0"&gt;shipped v0.18.0&lt;/a&gt; with that feature a few hours later.&lt;/p&gt;
&lt;p&gt;... which means you can now run the following in any Python-enabled Codespaces container and get a working &lt;code&gt;llm&lt;/code&gt; command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pip install llm
llm install llm-github-models
llm models default github/gpt-4.1
llm "Fun facts about pelicans"
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Setting the default model to &lt;code&gt;github/gpt-4.1&lt;/code&gt; means you get free (albeit rate-limited) access to that OpenAI model.&lt;/p&gt;
&lt;p&gt;To save you from needing to even run that sequence of commands I've created a new GitHub repository, &lt;a href="https://github.com/simonw/codespaces-llm"&gt;simonw/codespaces-llm&lt;/a&gt;, which pre-installs and runs those commands for you.&lt;/p&gt;
&lt;p&gt;Anyone with a GitHub account can use this URL to launch a new Codespaces instance with a configured &lt;code&gt;llm&lt;/code&gt; terminal command ready to use:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://codespaces.new/simonw/codespaces-llm?quickstart=1"&gt;codespaces.new/simonw/codespaces-llm?quickstart=1&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="Screenshot of a GitHub Codespaces VS Code interface showing a README.md file for codespaces-llm repository. The file describes a GitHub Codespaces environment with LLM, Python 3.13, uv and the GitHub Copilot VS Code extension. It has a &amp;quot;Launch Codespace&amp;quot; button. Below shows a terminal tab with the command &amp;quot;llm 'Fun facts about pelicans'&amp;quot; which has generated output listing 5 pelican facts: 1. **Huge Beaks:** about their enormous beaks and throat pouches for scooping fish and water, some over a foot long; 2. **Fishing Technique:** about working together to herd fish into shallow water; 3. **Great Fliers:** about being strong fliers that migrate great distances and soar on thermals; 4. **Buoyant Bodies:** about having air sacs beneath skin and bones making them extra buoyant; 5. **Dive Bombing:** about Brown Pelicans diving dramatically from air into water to catch fish." src="https://static.simonwillison.net/static/2025/codespaces-llm.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;While putting this together I wrote up what I've learned about devcontainers so far as a TIL: &lt;a href="https://til.simonwillison.net/github/codespaces-devcontainers"&gt;Configuring GitHub Codespaces using devcontainers&lt;/a&gt;.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/github"&gt;github&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/projects"&gt;projects&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python"&gt;python&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/ai"&gt;ai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/til"&gt;til&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/openai"&gt;openai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/generative-ai"&gt;generative-ai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/llms"&gt;llms&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/llm"&gt;llm&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/github-codespaces"&gt;github-codespaces&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/anthony-shaw"&gt;anthony-shaw&lt;/a&gt;&lt;/p&gt;



</summary><category term="github"/><category term="projects"/><category term="python"/><category term="ai"/><category term="til"/><category term="openai"/><category term="generative-ai"/><category term="llms"/><category term="llm"/><category term="github-codespaces"/><category term="anthony-shaw"/></entry><entry><title>llm-github-models 0.15</title><link href="https://simonwillison.net/2025/May/29/llm-github-models-015/#atom-tag" rel="alternate"/><published>2025-05-29T04:27:15+00:00</published><updated>2025-05-29T04:27:15+00:00</updated><id>https://simonwillison.net/2025/May/29/llm-github-models-015/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/tonybaloney/llm-github-models/releases/tag/0.15"&gt;llm-github-models 0.15&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Anthony Shaw's &lt;a href="https://github.com/tonybaloney/llm-github-models"&gt;llm-github-models&lt;/a&gt; plugin just got an upgrade: it now supports &lt;a href="https://simonwillison.net/2025/May/27/llm-tools/"&gt;LLM 0.26 tool use&lt;/a&gt; for a subset of the models hosted on the &lt;a href="https://docs.github.com/en/github-models"&gt;GitHub Models API&lt;/a&gt;, contributed by &lt;a href="https://github.com/cmbrose"&gt;Caleb Brose&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The neat thing about this GitHub Models plugin is that it picks up an API key from your &lt;code&gt;GITHUB_TOKEN&lt;/code&gt; - and if you're running LLM within a GitHub Actions worker the API key provided by the worker should be enough to start executing prompts!&lt;/p&gt;
&lt;p&gt;I tried it out against &lt;a href="https://cohere.com/blog/command-a"&gt;Cohere Command A&lt;/a&gt; via GitHub Models like this (&lt;a href="https://gist.github.com/simonw/11452eb6cf4d024935419bbc541430b9"&gt;transcript here&lt;/a&gt;):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;llm install llm-github-models
llm keys set github
# Paste key here
llm -m github/cohere-command-a -T llm_time 'What time is it?' --td
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We now have seven LLM plugins that provide tool support, covering &lt;a href="https://llm.datasette.io/en/stable/openai-models.html"&gt;OpenAI&lt;/a&gt;, &lt;a href="https://github.com/simonw/llm-anthropic"&gt;Anthropic&lt;/a&gt;, &lt;a href="https://github.com/simonw/llm-gemini"&gt;Gemini&lt;/a&gt;, &lt;a href="https://github.com/simonw/llm-mistral"&gt;Mistral&lt;/a&gt;, &lt;a href="https://github.com/taketwo/llm-ollama"&gt;Ollama&lt;/a&gt;, &lt;a href="https://github.com/simonw/llm-llama-server"&gt;llama-server&lt;/a&gt; and now GitHub Models.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/github"&gt;github&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/ai"&gt;ai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/github-actions"&gt;github-actions&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/generative-ai"&gt;generative-ai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/llms"&gt;llms&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/llm"&gt;llm&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/llm-tool-use"&gt;llm-tool-use&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/anthony-shaw"&gt;anthony-shaw&lt;/a&gt;&lt;/p&gt;



</summary><category term="github"/><category term="ai"/><category term="github-actions"/><category term="generative-ai"/><category term="llms"/><category term="llm"/><category term="llm-tool-use"/><category term="anthony-shaw"/></entry><entry><title>llm -f issue:... -m echo --no-log</title><link href="https://simonwillison.net/2025/May/9/private-issues/#atom-tag" rel="alternate"/><published>2025-05-09T18:55:24+00:00</published><updated>2025-05-09T18:55:24+00:00</updated><id>https://simonwillison.net/2025/May/9/private-issues/#atom-tag</id><summary type="html">
    &lt;p&gt;I had some notes in a GitHub issue thread in a private repository that I wanted to export as Markdown. I realized that I could get them using a combination of several recent projects.&lt;/p&gt;
&lt;p&gt;Here's what I ran:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export GITHUB_TOKEN="$(llm keys get github)"                                             
llm -f issue:https://github.com/simonw/todos/issues/170 \
  -m echo --no-log | jq .prompt -r &amp;gt; notes.md
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I have a GitHub personal access token stored in my LLM keys, for use with Anthony Shaw's &lt;a href="https://github.com/tonybaloney/llm-github-models"&gt;llm-github-models&lt;/a&gt; plugin.&lt;/p&gt;
&lt;p&gt;My own &lt;a href="https://github.com/simonw/llm-fragments-github"&gt;llm-fragments-github&lt;/a&gt; plugin expects an optional &lt;code&gt;GITHUB_TOKEN&lt;/code&gt; environment variable, so I set that first - here's &lt;a href="https://github.com/simonw/llm-fragments-github/issues/11"&gt;an issue&lt;/a&gt; to have it use the &lt;code&gt;github&lt;/code&gt; key instead.&lt;/p&gt;
&lt;p&gt;With that set, the &lt;code&gt;issue:&lt;/code&gt; fragment loader can take a URL to a private GitHub issue thread and load it via the API using the token, then concatenate the comments together as Markdown. Here's &lt;a href="https://github.com/simonw/llm-fragments-github/blob/87555488805ffc973b5fb45aa51eac83be2c839f/llm_fragments_github.py#L92-L126"&gt;the code for that&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Fragments are meant to be used as input to LLMs. I built a &lt;a href="https://github.com/simonw/llm-echo"&gt;llm-echo&lt;/a&gt; plugin recently which adds a fake LLM called "echo" which simply echos its input back out again.&lt;/p&gt;
&lt;p&gt;Adding &lt;code&gt;--no-log&lt;/code&gt; prevents that junk data from being stored in my &lt;a href="https://llm.datasette.io/en/stable/logging.html"&gt;LLM log database&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The output is JSON with a &lt;code&gt;"prompt"&lt;/code&gt; key for the original prompt. I use &lt;code&gt;jq .prompt&lt;/code&gt; to extract that out, then &lt;code&gt;-r&lt;/code&gt; to get it as raw text (not a &lt;code&gt;"JSON string"&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;... and I write the result to &lt;code&gt;notes.md&lt;/code&gt;.&lt;/p&gt;

    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/github"&gt;github&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/plugins"&gt;plugins&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/projects"&gt;projects&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/jq"&gt;jq&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/llm"&gt;llm&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/anthony-shaw"&gt;anthony-shaw&lt;/a&gt;&lt;/p&gt;



</summary><category term="github"/><category term="plugins"/><category term="projects"/><category term="jq"/><category term="llm"/><category term="anthony-shaw"/></entry><entry><title>Python 3.13 gets a JIT</title><link href="https://simonwillison.net/2024/Jan/9/python-gets-a-jit/#atom-tag" rel="alternate"/><published>2024-01-09T21:25:02+00:00</published><updated>2024-01-09T21:25:02+00:00</updated><id>https://simonwillison.net/2024/Jan/9/python-gets-a-jit/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://tonybaloney.github.io/posts/python-gets-a-jit.html"&gt;Python 3.13 gets a JIT&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
“In late December 2023 (Christmas Day to be precise), CPython core developer Brandt Bucher submitted a little pull-request to the Python 3.13 branch adding a JIT compiler.”&lt;/p&gt;

&lt;p&gt;Anthony Shaw does a deep dive into this new experimental JIT, explaining how it differs from other JITs. It’s an implementation of a copy-and-patch JIT, an idea that only emerged in 2021. This makes it architecturally much simpler than a traditional JIT, allowing it to compile faster and take advantage of existing LLVM tools on different architectures.&lt;/p&gt;

&lt;p&gt;So far it’s providing a 2-9% performance improvement, but the real impact will be from the many future optimizations it enables.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/jit"&gt;jit&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/llvm"&gt;llvm&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python"&gt;python&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/anthony-shaw"&gt;anthony-shaw&lt;/a&gt;&lt;/p&gt;



</summary><category term="jit"/><category term="llvm"/><category term="python"/><category term="anthony-shaw"/></entry></feed>