Skip to content

Instantly share code, notes, and snippets.

@simonw
Created May 21, 2026 19:09
Show Gist options
  • Select an option

  • Save simonw/a46d17b69659a4866adb1d868280091d to your computer and use it in GitHub Desktop.

Select an option

Save simonw/a46d17b69659a4866adb1d868280091d to your computer and use it in GitHub Desktop.

tell me about the databases

User

tell me about the databases

Tool call: list_databases_and_tables
{}
{
  "databases": [
    {
      "database_name": "legislators",
      "table_names": [
        "executive_terms",
        "executives",
        "legislator_terms",
        "legislators",
        "offices",
        "social_media"
      ]
    },
    {
      "database_name": "global-power-plants",
      "table_names": [
        "global-power-plants",
        "global-power-plants_fts",
        "global-power-plants_fts_config",
        "global-power-plants_fts_data",
        "global-power-plants_fts_docsize",
        "global-power-plants_fts_idx"
      ]
    },
    {
      "database_name": "simonwillisonblog",
      "table_names": [
        "auth_permission",
        "auth_user",
        "blog_beat",
        "blog_beat_tags",
        "blog_blogmark",
        "blog_blogmark_fts",
        "blog_blogmark_fts_config",
        "blog_blogmark_fts_data",
        "blog_blogmark_fts_docsize",
        "blog_blogmark_fts_idx",
        "blog_blogmark_tags",
        "blog_chapter",
        "blog_entry",
        "blog_entry_comprehend_entities",
        "blog_entry_comprehend_entities_done",
        "blog_entry_embeddings",
        "blog_entry_fts",
        "blog_entry_fts_config",
        "blog_entry_fts_data",
        "blog_entry_fts_docsize",
        "blog_entry_fts_idx",
        "blog_entry_tags",
        "blog_guide",
        "blog_guidesection",
        "blog_note",
        "blog_note_tags",
        "blog_previoustagname",
        "blog_quotation",
        "blog_quotation_fts",
        "blog_quotation_fts_config",
        "blog_quotation_fts_data",
        "blog_quotation_fts_docsize",
        "blog_quotation_fts_idx",
        "blog_quotation_tags",
        "blog_series",
        "blog_series_fts",
        "blog_series_fts_config",
        "blog_series_fts_data",
        "blog_series_fts_docsize",
        "blog_series_fts_idx",
        "blog_tag",
        "blog_tag_fts",
        "blog_tag_fts_config",
        "blog_tag_fts_data",
        "blog_tag_fts_docsize",
        "blog_tag_fts_idx",
        "comprehend_entities",
        "comprehend_entity_types",
        "django_content_type",
        "guides_chapter",
        "guides_guide",
        "guides_guidesection",
        "redirects_redirect",
        "til"
      ]
    }
  ]
}

Agent

There are three databases available:

1. legislators

This database contains records related to government officials.

  • Tables: executive_terms, executives, legislator_terms, legislators, offices, social_media

2. global-power-plants

This database tracks information about power plants worldwide, including supplementary tables for full-text search.

  • Tables: global-power-plants, global-power-plants_fts, global-power-plants_fts_config, global-power-plants_fts_data, global-power-plants_fts_docsize, global-power-plants_fts_idx

3. simonwillisonblog

This is a comprehensive database powering Simon Willison's blog, including content (entries, notes, quotations), metadata (tags, series, guides), and underlying Django framework structures.

  • Tables: auth_permission, auth_user, blog_beat, blog_beat_tags, blog_blogmark, blog_blogmark_fts, blog_blogmark_fts_config, blog_blogmark_fts_data, blog_blogmark_fts_docsize, blog_blogmark_fts_idx, blog_blogmark_tags, blog_chapter, blog_entry, blog_entry_comprehend_entities, blog_entry_comprehend_entities_done, blog_entry_embeddings, blog_entry_fts, blog_entry_fts_config, blog_entry_fts_data, blog_entry_fts_docsize, blog_entry_fts_idx, blog_entry_tags, blog_guide, blog_guidesection, blog_note, blog_note_tags, blog_previoustagname, blog_quotation, blog_quotation_fts, blog_quotation_fts_config, blog_quotation_fts_data, blog_quotation_fts_docsize, blog_quotation_fts_idx, blog_quotation_tags, blog_series, blog_series_fts, blog_series_fts_config, blog_series_fts_data, blog_series_fts_docsize, blog_series_fts_idx, blog_tag, blog_tag_fts, blog_tag_fts_config, blog_tag_fts_data, blog_tag_fts_docsize, blog_tag_fts_idx, comprehend_entities, comprehend_entity_types, django_content_type, guides_chapter, guides_guide, guides_guidesection, redirects_redirect, til

User

how many power plants in USA?

Tool call: describe_table
{
  "table": "global-power-plants",
  "database": "global-power-plants"
}
{
  "database": "global-power-plants",
  "table": "global-power-plants",
  "columns": [
    {
      "name": "country",
      "type": "TEXT",
      "notnull": 0
    },
    {
      "name": "country_long",
      "type": "TEXT",
      "notnull": 0
    },
    {
      "name": "name",
      "type": "TEXT",
      "notnull": 0
    },
    {
      "name": "gppd_idnr",
      "type": "TEXT",
      "notnull": 0
    },
    {
      "name": "capacity_mw",
      "type": "REAL",
      "notnull": 0
    },
    {
      "name": "latitude",
      "type": "REAL",
      "notnull": 0
    },
    {
      "name": "longitude",
      "type": "REAL",
      "notnull": 0
    },
    {
      "name": "primary_fuel",
      "type": "TEXT",
      "notnull": 0
    },
    {
      "name": "other_fuel1",
      "type": "TEXT",
      "notnull": 0
    },
    {
      "name": "other_fuel2",
      "type": "TEXT",
      "notnull": 0
    },
    {
      "name": "other_fuel3",
      "type": "TEXT",
      "notnull": 0
    },
    {
      "name": "commissioning_year",
      "type": "REAL",
      "notnull": 0
    },
    {
      "name": "owner",
      "type": "TEXT",
      "notnull": 0
    },
    {
      "name": "source",
      "type": "TEXT",
      "notnull": 0
    },
    {
      "name": "url",
      "type": "TEXT",
      "notnull": 0
    },
    {
      "name": "geolocation_source",
      "type": "TEXT",
      "notnull": 0
    },
    {
      "name": "wepp_id",
      "type": "TEXT",
      "notnull": 0
    },
    {
      "name": "year_of_capacity_data",
      "type": "INTEGER",
      "notnull": 0
    },
    {
      "name": "generation_gwh_2013",
      "type": "REAL",
      "notnull": 0
    },
    {
      "name": "generation_gwh_2014",
      "type": "REAL",
      "notnull": 0
    },
    {
      "name": "generation_gwh_2015",
      "type": "REAL",
      "notnull": 0
    },
    {
      "name": "generation_gwh_2016",
      "type": "REAL",
      "notnull": 0
    },
    {
      "name": "generation_gwh_2017",
      "type": "REAL",
      "notnull": 0
    },
    {
      "name": "generation_data_source",
      "type": "TEXT",
      "notnull": 0
    },
    {
      "name": "estimated_generation_gwh",
      "type": "REAL",
      "notnull": 0
    }
  ],
  "foreign_keys": []
}
Tool call: sql_query
{
  "sql": "SELECT COUNT(*) FROM \"global-power-plants\" WHERE country_long = 'United States of America'",
  "display": "both",
  "database": "global-power-plants"
}
{
  "columns": [
    "COUNT(*)"
  ],
  "rows": [
    {
      "COUNT(*)": 8688
    }
  ],
  "truncated": false,
  "_edit_sql_url": "/global-power-plants/-/query?sql=SELECT+COUNT%28%2A%29+FROM+%22global-power-plants%22+WHERE+country_long+%3D+%27United+States+of+America%27"
}
HTML widget: sql_query
<div class="agent-sql-result-scroll"><table class="agent-sql-result"><thead><tr><th>COUNT(*)</th></tr></thead><tbody><tr><td>8688</td></tr></tbody></table></div>

Agent

There are 8,688 power plants listed in the database for the United States of America.

User

list the largest

Tool call: sql_query
{
  "database": "global-power-plants",
  "display": "both",
  "sql": "SELECT name, capacity_mw, primary_fuel FROM \"global-power-plants\" WHERE country_long = 'United States of America' ORDER BY capacity_mw DESC LIMIT 10"
}
{
  "columns": [
    "name",
    "capacity_mw",
    "primary_fuel"
  ],
  "rows": [
    {
      "name": "Grand Coulee",
      "capacity_mw": 6809.0,
      "primary_fuel": "Hydro"
    },
    {
      "name": "Martin",
      "capacity_mw": 4317.499999999999,
      "primary_fuel": "Gas"
    },
    {
      "name": "West County Energy Center",
      "capacity_mw": 4263.0,
      "primary_fuel": "Gas"
    },
    {
      "name": "Palo Verde",
      "capacity_mw": 4209.6,
      "primary_fuel": "Nuclear"
    },
    {
      "name": "W A Parish",
      "capacity_mw": 4008.4,
      "primary_fuel": "Coal"
    },
    {
      "name": "Scherer",
      "capacity_mw": 3564.0,
      "primary_fuel": "Coal"
    },
    {
      "name": "Bowen",
      "capacity_mw": 3498.6,
      "primary_fuel": "Coal"
    },
    {
      "name": "Browns Ferry",
      "capacity_mw": 3494.0,
      "primary_fuel": "Nuclear"
    },
    {
      "name": "Gibson",
      "capacity_mw": 3339.5,
      "primary_fuel": "Coal"
    },
    {
      "name": "Monroe (MI)",
      "capacity_mw": 3293.0999999999995,
      "primary_fuel": "Coal"
    }
  ],
  "truncated": false,
  "_edit_sql_url": "/global-power-plants/-/query?sql=SELECT+name%2C+capacity_mw%2C+primary_fuel+FROM+%22global-power-plants%22+WHERE+country_long+%3D+%27United+States+of+America%27+ORDER+BY+capacity_mw+DESC+LIMIT+10"
}
HTML widget: sql_query
<div class="agent-sql-result-scroll"><table class="agent-sql-result"><thead><tr><th>name</th><th>capacity_mw</th><th>primary_fuel</th></tr></thead><tbody><tr><td>Grand Coulee</td><td>6809.0</td><td>Hydro</td></tr><tr><td>Martin</td><td>4317.499999999999</td><td>Gas</td></tr><tr><td>West County Energy Center</td><td>4263.0</td><td>Gas</td></tr><tr><td>Palo Verde</td><td>4209.6</td><td>Nuclear</td></tr><tr><td>W A Parish</td><td>4008.4</td><td>Coal</td></tr><tr><td>Scherer</td><td>3564.0</td><td>Coal</td></tr><tr><td>Bowen</td><td>3498.6</td><td>Coal</td></tr><tr><td>Browns Ferry</td><td>3494.0</td><td>Nuclear</td></tr><tr><td>Gibson</td><td>3339.5</td><td>Coal</td></tr><tr><td>Monroe (MI)</td><td>3293.0999999999995</td><td>Coal</td></tr></tbody></table></div>

Agent

Here are the 10 largest power plants in the United States by capacity (in MW):

Name Capacity (MW) Primary Fuel
Grand Coulee 6809.0 Hydro
Martin 4317.5 Gas
West County Energy Center 4263.0 Gas
Palo Verde 4209.6 Nuclear
W A Parish 4008.4 Coal
Scherer 3564.0 Coal
Bowen 3498.6 Coal
Browns Ferry 3494.0 Nuclear
Gibson 3339.5 Coal
Monroe (MI) 3293.1 Coal

User

top ten nuclear?

Tool call: sql_query
{
  "database": "global-power-plants",
  "sql": "SELECT name, capacity_mw FROM \"global-power-plants\" WHERE country_long = 'United States of America' AND primary_fuel = 'Nuclear' ORDER BY capacity_mw DESC LIMIT 10",
  "display": "both"
}
{
  "columns": [
    "name",
    "capacity_mw"
  ],
  "rows": [
    {
      "name": "Palo Verde",
      "capacity_mw": 4209.6
    },
    {
      "name": "Browns Ferry",
      "capacity_mw": 3494.0
    },
    {
      "name": "Turkey Point",
      "capacity_mw": 2861.2
    },
    {
      "name": "Peach Bottom",
      "capacity_mw": 2784.6
    },
    {
      "name": "South Texas Project",
      "capacity_mw": 2708.6
    },
    {
      "name": "Oconee",
      "capacity_mw": 2666.7
    },
    {
      "name": "TalenEnergy Susquehanna",
      "capacity_mw": 2596.0
    },
    {
      "name": "Watts Bar Nuclear Plant",
      "capacity_mw": 2539.8
    },
    {
      "name": "Braidwood Generation Station",
      "capacity_mw": 2449.8
    },
    {
      "name": "Byron Generating Station",
      "capacity_mw": 2449.8
    }
  ],
  "truncated": false,
  "_edit_sql_url": "/global-power-plants/-/query?sql=SELECT+name%2C+capacity_mw+FROM+%22global-power-plants%22+WHERE+country_long+%3D+%27United+States+of+America%27+AND+primary_fuel+%3D+%27Nuclear%27+ORDER+BY+capacity_mw+DESC+LIMIT+10"
}
HTML widget: sql_query
<div class="agent-sql-result-scroll"><table class="agent-sql-result"><thead><tr><th>name</th><th>capacity_mw</th></tr></thead><tbody><tr><td>Palo Verde</td><td>4209.6</td></tr><tr><td>Browns Ferry</td><td>3494.0</td></tr><tr><td>Turkey Point</td><td>2861.2</td></tr><tr><td>Peach Bottom</td><td>2784.6</td></tr><tr><td>South Texas Project</td><td>2708.6</td></tr><tr><td>Oconee</td><td>2666.7</td></tr><tr><td>TalenEnergy Susquehanna</td><td>2596.0</td></tr><tr><td>Watts Bar Nuclear Plant</td><td>2539.8</td></tr><tr><td>Braidwood Generation Station</td><td>2449.8</td></tr><tr><td>Byron Generating Station</td><td>2449.8</td></tr></tbody></table></div>

Agent

These are the 10 largest nuclear power plants in the United States by capacity:

Name Capacity (MW)
Palo Verde 4209.6
Browns Ferry 3494.0
Turkey Point 2861.2
Peach Bottom 2784.6
South Texas Project 2708.6
Oconee 2666.7
TalenEnergy Susquehanna 2596.0
Watts Bar Nuclear Plant 2539.8
Braidwood Generation Station 2449.8
Byron Generating Station 2449.8

User

chart that

Tool call: render_chart
{
  "sql": "SELECT name, capacity_mw FROM \"global-power-plants\" WHERE country_long = 'United States of America' AND primary_fuel = 'Nuclear' ORDER BY capacity_mw DESC LIMIT 10",
  "y_label": "Power Plant Name",
  "chart_type": "barX",
  "x_label": "Capacity (MW)",
  "title": "Top 10 Nuclear Power Plants in the USA by Capacity (MW)",
  "x": "capacity_mw",
  "database": "global-power-plants",
  "y": "name"
}
{
  "chart_type": "barX",
  "database": "global-power-plants",
  "sql": "SELECT name, capacity_mw FROM \"global-power-plants\" WHERE country_long = 'United States of America' AND primary_fuel = 'Nuclear' ORDER BY capacity_mw DESC LIMIT 10"
}
HTML widget: render_chart
<script src="/-/static-plugins/datasette-agent-charts/datasette-chart.js" type="module"></script>
<datasette-chart>
<script type="application/json">{"type": "barX", "database": "global-power-plants", "sql": "SELECT name, capacity_mw FROM \"global-power-plants\" WHERE country_long = 'United States of America' AND primary_fuel = 'Nuclear' ORDER BY capacity_mw DESC LIMIT 10", "queryUrl": "/global-power-plants/-/query", "x": "capacity_mw", "y": "name", "title": "Top 10 Nuclear Power Plants in the USA by Capacity (MW)", "xLabel": "Capacity (MW)", "yLabel": "Power Plant Name"}</script>
</datasette-chart>

Agent

The chart above displays the capacity (in MW) for the 10 largest nuclear power plants in the United States, allowing for an easy visual comparison of their relative sizes.

User

tell me about Simon's blog

Tool call: describe_table
{
  "table": "blog_entry",
  "database": "simonwillisonblog"
}
{
  "database": "simonwillisonblog",
  "table": "blog_entry",
  "columns": [
    {
      "name": "id",
      "type": "INTEGER",
      "notnull": 0
    },
    {
      "name": "title",
      "type": "TEXT",
      "notnull": 0
    },
    {
      "name": "slug",
      "type": "TEXT",
      "notnull": 0
    },
    {
      "name": "body",
      "type": "TEXT",
      "notnull": 0
    },
    {
      "name": "created",
      "type": "TEXT",
      "notnull": 0
    },
    {
      "name": "metadata",
      "type": "TEXT",
      "notnull": 0
    },
    {
      "name": "tweet_html",
      "type": "TEXT",
      "notnull": 0
    },
    {
      "name": "import_ref",
      "type": "TEXT",
      "notnull": 0
    },
    {
      "name": "extra_head_html",
      "type": "TEXT",
      "notnull": 0
    },
    {
      "name": "card_image",
      "type": "TEXT",
      "notnull": 0
    },
    {
      "name": "custom_template",
      "type": "TEXT",
      "notnull": 0
    },
    {
      "name": "series_id",
      "type": "INTEGER",
      "notnull": 0
    },
    {
      "name": "is_draft",
      "type": "INTEGER",
      "notnull": 0
    },
    {
      "name": "live_timezone",
      "type": "TEXT",
      "notnull": 0
    }
  ],
  "foreign_keys": [
    {
      "column": "series_id",
      "other_table": "blog_series",
      "other_column": "id"
    }
  ]
}
Tool call: describe_table
{
  "table": "til",
  "database": "simonwillisonblog"
}
{
  "database": "simonwillisonblog",
  "table": "til",
  "columns": [
    {
      "name": "path",
      "type": "TEXT",
      "notnull": 0
    },
    {
      "name": "topic",
      "type": "TEXT",
      "notnull": 0
    },
    {
      "name": "title",
      "type": "TEXT",
      "notnull": 0
    },
    {
      "name": "url",
      "type": "TEXT",
      "notnull": 0
    },
    {
      "name": "body",
      "type": "TEXT",
      "notnull": 0
    },
    {
      "name": "html",
      "type": "TEXT",
      "notnull": 0
    },
    {
      "name": "created",
      "type": "TEXT",
      "notnull": 0
    },
    {
      "name": "created_utc",
      "type": "TEXT",
      "notnull": 0
    },
    {
      "name": "updated",
      "type": "TEXT",
      "notnull": 0
    },
    {
      "name": "updated_utc",
      "type": "TEXT",
      "notnull": 0
    },
    {
      "name": "shot_hash",
      "type": "TEXT",
      "notnull": 0
    },
    {
      "name": "slug",
      "type": "TEXT",
      "notnull": 0
    },
    {
      "name": "summary",
      "type": "TEXT",
      "notnull": 0
    }
  ],
  "foreign_keys": []
}

Agent

The simonwillisonblog database is a comprehensive archive of Simon Willison's website. It is structured to manage various types of content beyond just standard blog posts, reflecting a rich and long-running online presence.

Key aspects of the content it holds include:

  • Blog Entries (blog_entry): The core articles, including titles, bodies, and metadata like publication dates and series associations.
  • Today I Learned (til): A dedicated table for "TIL" posts—shorter, bite-sized learning notes.
  • Other Content: Tables for notes (blog_note), quotations (blog_quotation), and "blogmarks" (likely bookmarks or link collections).
  • Organization: Extensive support for tagging (blog_tag) and series (blog_series) to categorize and link related content.
  • Infrastructure: The database also contains metadata for the Django framework, which powers the site, including user authentication and permissions.

It is a well-structured repository designed not just for displaying articles, but for organizing, searching, and managing a large collection of diverse web content.

User

give me -some numbers

Tool call: sql_query
{
  "display": "model",
  "sql": "SELECT \n    (SELECT COUNT(*) FROM blog_entry) AS entry_count,\n    (SELECT COUNT(*) FROM til) AS til_count,\n    (SELECT COUNT(*) FROM blog_note) AS note_count,\n    (SELECT COUNT(*) FROM blog_quotation) AS quotation_count,\n    (SELECT MIN(created) FROM blog_entry) AS first_entry,\n    (SELECT MAX(created) FROM blog_entry) AS last_entry\n",
  "database": "simonwillisonblog"
}
{
  "columns": [
    "entry_count",
    "til_count",
    "note_count",
    "quotation_count",
    "first_entry",
    "last_entry"
  ],
  "rows": [
    {
      "entry_count": 3299,
      "til_count": 577,
      "note_count": 136,
      "quotation_count": 1391,
      "first_entry": "2002-06-12T01:44:12+00:00",
      "last_entry": "2026-05-19T22:40:25+00:00"
    }
  ],
  "truncated": false,
  "_edit_sql_url": "/simonwillisonblog/-/query?sql=SELECT+%0A++++%28SELECT+COUNT%28%2A%29+FROM+blog_entry%29+AS+entry_count%2C%0A++++%28SELECT+COUNT%28%2A%29+FROM+til%29+AS+til_count%2C%0A++++%28SELECT+COUNT%28%2A%29+FROM+blog_note%29+AS+note_count%2C%0A++++%28SELECT+COUNT%28%2A%29+FROM+blog_quotation%29+AS+quotation_count%2C%0A++++%28SELECT+MIN%28created%29+FROM+blog_entry%29+AS+first_entry%2C%0A++++%28SELECT+MAX%28created%29+FROM+blog_entry%29+AS+last_entry%0A"
}

Agent

Here are some key statistics from the simonwillisonblog database, illustrating the scale and duration of the content:

Content Counts

  • Blog Entries: 3,299
  • Today I Learned (TIL) Posts: 577
  • Quotations: 1,391
  • Notes: 136

Timeline

The blog has a long history, with entries spanning from June 12, 2002, to May 19, 2026.

User

what about beats?

Tool call: sql_query
{
  "database": "simonwillisonblog",
  "sql": "SELECT * FROM blog_beat LIMIT 5",
  "display": "both"
}
{
  "columns": [
    "id",
    "created",
    "slug",
    "metadata",
    "search_document",
    "import_ref",
    "card_image",
    "is_draft",
    "beat_type",
    "title",
    "url",
    "commentary",
    "series_id",
    "image_alt",
    "image_url",
    "note"
  ],
  "rows": [
    {
      "id": 280,
      "created": "2020-04-19T14:50:03+00:00",
      "slug": "dump-context",
      "metadata": "{}",
      "search_document": "'/en/actions/reference/context-and-expression-syntax-for-github-actions)).':23C 'actions':5A 'all':3A 'and':18C 'available':12C 'conditions':15C 'context':6A,17C 'dump':1A 'expression':19C 'for':8C,13C 'github':4A 'help.github.com':22C 'help.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions)).':21C 'if':14C 'out':2A 's':11C 'see':16C 'seeing':9C 'syntax':20C 'useful':7C 'what':10C",
      "import_ref": "til:github-actions/dump-context",
      "card_image": null,
      "is_draft": 0,
      "beat_type": "til",
      "title": "Dump out all GitHub Actions context",
      "url": "https://til.simonwillison.net/github-actions/dump-context",
      "commentary": "Useful for seeing what's available for `if: ` conditions (see [context and expression syntax](https://help.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions)).",
      "series_id": null,
      "image_alt": null,
      "image_url": "https://s3.amazonaws.com/til.simonwillison.net/2e26e87949692d153d8e637bfb55b700.jpg",
      "note": ""
    },
    {
      "id": 282,
      "created": "2020-04-19T14:55:08+00:00",
      "slug": "set-environment-for-all-steps",
      "metadata": "{}",
      "search_document": "'/googlecloudplatform/github-actions/blob/20c294aabd5331f9f7b8a26e6075d41c31ce5e0d/example-workflows/cloud-run/.github/workflows/cloud-run.yml)':16C 'a':8A,39C 'action':10A 'all':5A,32C 'at':35C 'available':30C 'be':29C 'can':21C 'environment':2A,23C 'example':13C 'for':4A 'from':11C 'github':9A 'github.com':15C 'github.com/googlecloudplatform/github-actions/blob/20c294aabd5331f9f7b8a26e6075d41c31ce5e0d/example-workflows/cloud-run/.github/workflows/cloud-run.yml)':14C 'i':17C 'in':7A,31C 'jobs':33C 'learned':18C 'of':38C 'once':34C 'set':1A,22C 'steps':6A 'such':25C 'that':19C,26C 'the':36C 'they':27C 'this':12C 'top':37C 'variables':3A,24C 'will':28C 'workflow':40C 'you':20C",
      "import_ref": "til:github-actions/set-environment-for-all-steps",
      "card_image": null,
      "is_draft": 0,
      "beat_type": "til",
      "title": "Set environment variables for all steps in a GitHub Action",
      "url": "https://til.simonwillison.net/github-actions/set-environment-for-all-steps",
      "commentary": "From [this example](https://github.com/GoogleCloudPlatform/github-actions/blob/20c294aabd5331f9f7b8a26e6075d41c31ce5e0d/example-workflows/cloud-run/.github/workflows/cloud-run.yml) I learned that you can set environment variables such that they will be available in ALL jobs once at the top of a workflow:",
      "series_id": null,
      "image_alt": null,
      "image_url": "https://s3.amazonaws.com/til.simonwillison.net/6460dc3791006e9171e07e892e9c76a2.jpg",
      "note": ""
    },
    {
      "id": 284,
      "created": "2020-04-19T16:02:23+00:00",
      "slug": "convert-to-utc-without-pytz",
      "metadata": "{}",
      "search_document": "'a':2A,14C 'adding':22C 'convert':1A,13C 'datetime':3A,15C 'dependency':25C 'from':17C 'gitpython':18C 'i':10C 'object':4A,16C 'pytz':9A,24C 'the':23C 'to':5A,12C,19C 'using':8A 'utc':6A,20C 'wanted':11C 'without':7A,21C",
      "import_ref": "til:python/convert-to-utc-without-pytz",
      "card_image": null,
      "is_draft": 0,
      "beat_type": "til",
      "title": "Convert a datetime object to UTC without using pytz",
      "url": "https://til.simonwillison.net/python/convert-to-utc-without-pytz",
      "commentary": "I wanted to convert a datetime object (from GitPython) to UTC without adding the `pytz` dependency.",
      "series_id": null,
      "image_alt": null,
      "image_url": "https://s3.amazonaws.com/til.simonwillison.net/c23125822a22bf690bb5943b6c2b6f36.jpg",
      "note": ""
    },
    {
      "id": 286,
      "created": "2020-04-19T23:23:04+00:00",
      "slug": "lag-window-function",
      "metadata": "{}",
      "search_document": "'a':11C 'function':3A 'here':6C 'how':8C 'in':4A 'lag':1A,12C 's':7C 'sqlite':5A 'to':9C 'use':10C 'window':2A,13C",
      "import_ref": "til:sqlite/lag-window-function",
      "card_image": null,
      "is_draft": 0,
      "beat_type": "til",
      "title": "Lag window function in SQLite",
      "url": "https://til.simonwillison.net/sqlite/lag-window-function",
      "commentary": "Here's [how to use a lag window\u2026",
      "series_id": null,
      "image_alt": null,
      "image_url": "https://s3.amazonaws.com/til.simonwillison.net/35056d9914367dc8774a4f0a21e5d045.jpg",
      "note": ""
    },
    {
      "id": 288,
      "created": "2020-04-20T14:39:39+00:00",
      "slug": "different-steps-on-a-schedule",
      "metadata": "{}",
      "search_document": "'a':5A,10C,17C 'but':15C 'day':18C 'different':2A 'differently':26C 'duplicating':28C 'entire':30C 'have':9C 'hourly':14C 'on':4A 'once':16C 'run':24C 'running':1A 'runs':13C 'say':7C 'schedule':6A 'slightly':25C 'steps':3A 'that':12C 'the':21C,29C 'to':23C 'want':20C 'without':27C 'workflow':11C,22C,31C 'you':8C,19C",
      "import_ref": "til:github-actions/different-steps-on-a-schedule",
      "card_image": null,
      "is_draft": 0,
      "beat_type": "til",
      "title": "Running different steps on a schedule",
      "url": "https://til.simonwillison.net/github-actions/different-steps-on-a-schedule",
      "commentary": "Say you have a workflow that runs hourly, but once a day you want the workflow to run slightly differently - without duplicating the entire workflow.",
      "series_id": null,
      "image_alt": null,
      "image_url": "https://s3.amazonaws.com/til.simonwillison.net/d9818026878c9398ce7e84f273ad365c.jpg",
      "note": ""
    }
  ],
  "truncated": false,
  "_edit_sql_url": "/simonwillisonblog/-/query?sql=SELECT+%2A+FROM+blog_beat+LIMIT+5"
}
HTML widget: sql_query
<div class="agent-sql-result-scroll"><table class="agent-sql-result"><thead><tr><th>id</th><th>created</th><th>slug</th><th>metadata</th><th>search_document</th><th>import_ref</th><th>card_image</th><th>is_draft</th><th>beat_type</th><th>title</th><th>url</th><th>commentary</th><th>series_id</th><th>image_alt</th><th>image_url</th><th>note</th></tr></thead><tbody><tr><td>280</td><td>2020-04-19T14:50:03+00:00</td><td>dump-context</td><td>{}</td><td>&#x27;/en/actions/reference/context-and-expression-syntax-for-github-actions)).&#x27;:23C &#x27;actions&#x27;:5A &#x27;all&#x27;:3A &#x27;and&#x27;:18C &#x27;available&#x27;:12C &#x27;conditions&#x27;:15C &#x27;context&#x27;:6A,17C &#x27;dump&#x27;:1A &#x27;expression&#x27;:19C &#x27;for&#x27;:8C,13C &#x27;github&#x27;:4A &#x27;help.github.com&#x27;:22C &#x27;help.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions)).&#x27;:21C &#x27;if&#x27;:14C &#x27;out&#x27;:2A &#x27;s&#x27;:11C &#x27;see&#x27;:16C &#x27;seeing&#x27;:9C &#x27;syntax&#x27;:20C &#x27;useful&#x27;:7C &#x27;what&#x27;:10C</td><td>til:github-actions/dump-context</td><td>None</td><td>0</td><td>til</td><td>Dump out all GitHub Actions context</td><td>https://til.simonwillison.net/github-actions/dump-context</td><td>Useful for seeing what&#x27;s available for `if: ` conditions (see [context and expression syntax](https://help.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions)).</td><td>None</td><td>None</td><td>https://s3.amazonaws.com/til.simonwillison.net/2e26e87949692d153d8e637bfb55b700.jpg</td><td></td></tr><tr><td>282</td><td>2020-04-19T14:55:08+00:00</td><td>set-environment-for-all-steps</td><td>{}</td><td>&#x27;/googlecloudplatform/github-actions/blob/20c294aabd5331f9f7b8a26e6075d41c31ce5e0d/example-workflows/cloud-run/.github/workflows/cloud-run.yml)&#x27;:16C &#x27;a&#x27;:8A,39C &#x27;action&#x27;:10A &#x27;all&#x27;:5A,32C &#x27;at&#x27;:35C &#x27;available&#x27;:30C &#x27;be&#x27;:29C &#x27;can&#x27;:21C &#x27;environment&#x27;:2A,23C &#x27;example&#x27;:13C &#x27;for&#x27;:4A &#x27;from&#x27;:11C &#x27;github&#x27;:9A &#x27;github.com&#x27;:15C &#x27;github.com/googlecloudplatform/github-actions/blob/20c294aabd5331f9f7b8a26e6075d41c31ce5e0d/example-workflows/cloud-run/.github/workflows/cloud-run.yml)&#x27;:14C &#x27;i&#x27;:17C &#x27;in&#x27;:7A,31C &#x27;jobs&#x27;:33C &#x27;learned&#x27;:18C &#x27;of&#x27;:38C &#x27;once&#x27;:34C &#x27;set&#x27;:1A,22C &#x27;steps&#x27;:6A &#x27;such&#x27;:25C &#x27;that&#x27;:19C,26C &#x27;the&#x27;:36C &#x27;they&#x27;:27C &#x27;this&#x27;:12C &#x27;top&#x27;:37C &#x27;variables&#x27;:3A,24C &#x27;will&#x27;:28C &#x27;workflow&#x27;:40C &#x27;you&#x27;:20C</td><td>til:github-actions/set-environment-for-all-steps</td><td>None</td><td>0</td><td>til</td><td>Set environment variables for all steps in a GitHub Action</td><td>https://til.simonwillison.net/github-actions/set-environment-for-all-steps</td><td>From [this example](https://github.com/GoogleCloudPlatform/github-actions/blob/20c294aabd5331f9f7b8a26e6075d41c31ce5e0d/example-workflows/cloud-run/.github/workflows/cloud-run.yml) I learned that you can set environment variables such that they will be available in ALL jobs once at the top of a workflow:</td><td>None</td><td>None</td><td>https://s3.amazonaws.com/til.simonwillison.net/6460dc3791006e9171e07e892e9c76a2.jpg</td><td></td></tr><tr><td>284</td><td>2020-04-19T16:02:23+00:00</td><td>convert-to-utc-without-pytz</td><td>{}</td><td>&#x27;a&#x27;:2A,14C &#x27;adding&#x27;:22C &#x27;convert&#x27;:1A,13C &#x27;datetime&#x27;:3A,15C &#x27;dependency&#x27;:25C &#x27;from&#x27;:17C &#x27;gitpython&#x27;:18C &#x27;i&#x27;:10C &#x27;object&#x27;:4A,16C &#x27;pytz&#x27;:9A,24C &#x27;the&#x27;:23C &#x27;to&#x27;:5A,12C,19C &#x27;using&#x27;:8A &#x27;utc&#x27;:6A,20C &#x27;wanted&#x27;:11C &#x27;without&#x27;:7A,21C</td><td>til:python/convert-to-utc-without-pytz</td><td>None</td><td>0</td><td>til</td><td>Convert a datetime object to UTC without using pytz</td><td>https://til.simonwillison.net/python/convert-to-utc-without-pytz</td><td>I wanted to convert a datetime object (from GitPython) to UTC without adding the `pytz` dependency.</td><td>None</td><td>None</td><td>https://s3.amazonaws.com/til.simonwillison.net/c23125822a22bf690bb5943b6c2b6f36.jpg</td><td></td></tr><tr><td>286</td><td>2020-04-19T23:23:04+00:00</td><td>lag-window-function</td><td>{}</td><td>&#x27;a&#x27;:11C &#x27;function&#x27;:3A &#x27;here&#x27;:6C &#x27;how&#x27;:8C &#x27;in&#x27;:4A &#x27;lag&#x27;:1A,12C &#x27;s&#x27;:7C &#x27;sqlite&#x27;:5A &#x27;to&#x27;:9C &#x27;use&#x27;:10C &#x27;window&#x27;:2A,13C</td><td>til:sqlite/lag-window-function</td><td>None</td><td>0</td><td>til</td><td>Lag window function in SQLite</td><td>https://til.simonwillison.net/sqlite/lag-window-function</td><td>Here&#x27;s [how to use a lag window…</td><td>None</td><td>None</td><td>https://s3.amazonaws.com/til.simonwillison.net/35056d9914367dc8774a4f0a21e5d045.jpg</td><td></td></tr><tr><td>288</td><td>2020-04-20T14:39:39+00:00</td><td>different-steps-on-a-schedule</td><td>{}</td><td>&#x27;a&#x27;:5A,10C,17C &#x27;but&#x27;:15C &#x27;day&#x27;:18C &#x27;different&#x27;:2A &#x27;differently&#x27;:26C &#x27;duplicating&#x27;:28C &#x27;entire&#x27;:30C &#x27;have&#x27;:9C &#x27;hourly&#x27;:14C &#x27;on&#x27;:4A &#x27;once&#x27;:16C &#x27;run&#x27;:24C &#x27;running&#x27;:1A &#x27;runs&#x27;:13C &#x27;say&#x27;:7C &#x27;schedule&#x27;:6A &#x27;slightly&#x27;:25C &#x27;steps&#x27;:3A &#x27;that&#x27;:12C &#x27;the&#x27;:21C,29C &#x27;to&#x27;:23C &#x27;want&#x27;:20C &#x27;without&#x27;:27C &#x27;workflow&#x27;:11C,22C,31C &#x27;you&#x27;:8C,19C</td><td>til:github-actions/different-steps-on-a-schedule</td><td>None</td><td>0</td><td>til</td><td>Running different steps on a schedule</td><td>https://til.simonwillison.net/github-actions/different-steps-on-a-schedule</td><td>Say you have a workflow that runs hourly, but once a day you want the workflow to run slightly differently - without duplicating the entire workflow.</td><td>None</td><td>None</td><td>https://s3.amazonaws.com/til.simonwillison.net/d9818026878c9398ce7e84f273ad365c.jpg</td><td></td></tr></tbody></table></div>

Agent

In the simonwillisonblog database, "beats" function as curated feeds or thematic aggregators of content.

Looking at the structure of the blog_beat table, it acts as a central repository that maps different types of content—such as TILs (Today I Learned) posts—into specific streams or "beats."

Key characteristics include:

  • Aggregator Role: It references content from other areas (like the til table) via an import_ref.
  • Metadata and Curation: Each beat entry includes titles, commentary, and URLs, allowing for the presentation of specific topics or themes even if the underlying content lives elsewhere.
  • Flexibility: The beat_type column (e.g., 'til') indicates that this system is flexible enough to manage different kinds of content entries under this unified "beat" structure.

Essentially, it's a way for the site to organize and present collections of posts around specific topics, projects, or categories to make them easier to follow.

User

beat type counts?

Tool call: sql_query
{
  "sql": "SELECT beat_type, COUNT(*) as count FROM blog_beat GROUP BY beat_type ORDER BY count DESC",
  "display": "both",
  "database": "simonwillisonblog"
}
{
  "columns": [
    "beat_type",
    "count"
  ],
  "rows": [
    {
      "beat_type": "release",
      "count": 2153
    },
    {
      "beat_type": "til",
      "count": 577
    },
    {
      "beat_type": "sighting",
      "count": 221
    },
    {
      "beat_type": "tool",
      "count": 211
    },
    {
      "beat_type": "museum",
      "count": 117
    },
    {
      "beat_type": "research",
      "count": 86
    }
  ],
  "truncated": false,
  "_edit_sql_url": "/simonwillisonblog/-/query?sql=SELECT+beat_type%2C+COUNT%28%2A%29+as+count+FROM+blog_beat+GROUP+BY+beat_type+ORDER+BY+count+DESC"
}
HTML widget: sql_query
<div class="agent-sql-result-scroll"><table class="agent-sql-result"><thead><tr><th>beat_type</th><th>count</th></tr></thead><tbody><tr><td>release</td><td>2153</td></tr><tr><td>til</td><td>577</td></tr><tr><td>sighting</td><td>221</td></tr><tr><td>tool</td><td>211</td></tr><tr><td>museum</td><td>117</td></tr><tr><td>research</td><td>86</td></tr></tbody></table></div>

Agent

The blog_beat table categorizes content into several distinct types. The "release" type is by far the most frequent, suggesting a strong focus on tracking project or software updates.

Here is the breakdown by count:

Beat Type Count
release 2153
til 577
sighting 221
tool 211
museum 117
research 86

User

what is a sighting?

Tool call: sql_query
{
  "database": "simonwillisonblog",
  "display": "both",
  "sql": "SELECT title, commentary, url FROM blog_beat WHERE beat_type = 'sighting' LIMIT 5"
}
{
  "columns": [
    "title",
    "commentary",
    "url"
  ],
  "rows": [
    {
      "title": "Side-striped palm pit viper",
      "commentary": "Side-striped palm pit viper",
      "url": "https://www.inaturalist.org/observations/9687475"
    },
    {
      "title": "Southern Sea Otter",
      "commentary": "Southern Sea Otter",
      "url": "https://www.inaturalist.org/observations/9768340"
    },
    {
      "title": "Eurasian Red Squirrel",
      "commentary": "Eurasian Red Squirrel",
      "url": "https://www.inaturalist.org/observations/9687117"
    },
    {
      "title": "Common Raccoon",
      "commentary": "Common Raccoon",
      "url": "https://www.inaturalist.org/observations/9687162"
    },
    {
      "title": "Coyote",
      "commentary": "Coyote",
      "url": "https://www.inaturalist.org/observations/9688291"
    }
  ],
  "truncated": false,
  "_edit_sql_url": "/simonwillisonblog/-/query?sql=SELECT+title%2C+commentary%2C+url+FROM+blog_beat+WHERE+beat_type+%3D+%27sighting%27+LIMIT+5"
}
HTML widget: sql_query
<div class="agent-sql-result-scroll"><table class="agent-sql-result"><thead><tr><th>title</th><th>commentary</th><th>url</th></tr></thead><tbody><tr><td>Side-striped palm pit viper</td><td>Side-striped palm pit viper</td><td>https://www.inaturalist.org/observations/9687475</td></tr><tr><td>Southern Sea Otter</td><td>Southern Sea Otter</td><td>https://www.inaturalist.org/observations/9768340</td></tr><tr><td>Eurasian Red Squirrel</td><td>Eurasian Red Squirrel</td><td>https://www.inaturalist.org/observations/9687117</td></tr><tr><td>Common Raccoon</td><td>Common Raccoon</td><td>https://www.inaturalist.org/observations/9687162</td></tr><tr><td>Coyote</td><td>Coyote</td><td>https://www.inaturalist.org/observations/9688291</td></tr></tbody></table></div>

Agent

Based on the data, a "sighting" in Simon's blog appears to be a record of a wildlife or animal observation.

The examples show titles and commentary corresponding to specific animal species (e.g., "Side-striped palm pit viper", "Coyote"), and the URLs point directly to observations on iNaturalist, a popular platform for recording and sharing nature sightings.

User

when did Simon most recently see a pelican?

Tool call: sql_query
{
  "sql": "SELECT title, commentary, created FROM blog_beat WHERE beat_type = 'sighting' AND (title LIKE '%pelican%' OR commentary LIKE '%pelican%') ORDER BY created DESC LIMIT 5",
  "display": "both",
  "database": "simonwillisonblog"
}
{
  "columns": [
    "title",
    "commentary",
    "created"
  ],
  "rows": [
    {
      "title": "Common Loon, Canada Goose, Striped Shore Crab, California Brown Pelican, California Sea Lion",
      "commentary": "Common Loon, Canada Goose, Striped Shore Crab, California Brown Pelican, California Sea Lion",
      "created": "2026-05-20T16:20:00+00:00"
    },
    {
      "title": "Glaucous-winged Gull, Brown Pelican, Snowy Egret, Canada Goose",
      "commentary": "Glaucous-winged Gull, Brown Pelican, Snowy Egret, Canada Goose",
      "created": "2026-05-18T14:51:00+00:00"
    },
    {
      "title": "California Brown Pelican",
      "commentary": "California Brown Pelican",
      "created": "2026-04-25T19:33:05+00:00"
    },
    {
      "title": "California Brown Pelican",
      "commentary": "California Brown Pelican",
      "created": "2026-04-09T01:37:42+00:00"
    },
    {
      "title": "California Brown Pelican",
      "commentary": "California Brown Pelican",
      "created": "2025-07-17T00:13:28+00:00"
    }
  ],
  "truncated": false,
  "_edit_sql_url": "/simonwillisonblog/-/query?sql=SELECT+title%2C+commentary%2C+created+FROM+blog_beat+WHERE+beat_type+%3D+%27sighting%27+AND+%28title+LIKE+%27%25pelican%25%27+OR+commentary+LIKE+%27%25pelican%25%27%29+ORDER+BY+created+DESC+LIMIT+5"
}
HTML widget: sql_query
<div class="agent-sql-result-scroll"><table class="agent-sql-result"><thead><tr><th>title</th><th>commentary</th><th>created</th></tr></thead><tbody><tr><td>Common Loon, Canada Goose, Striped Shore Crab, California Brown Pelican, California Sea Lion</td><td>Common Loon, Canada Goose, Striped Shore Crab, California Brown Pelican, California Sea Lion</td><td>2026-05-20T16:20:00+00:00</td></tr><tr><td>Glaucous-winged Gull, Brown Pelican, Snowy Egret, Canada Goose</td><td>Glaucous-winged Gull, Brown Pelican, Snowy Egret, Canada Goose</td><td>2026-05-18T14:51:00+00:00</td></tr><tr><td>California Brown Pelican</td><td>California Brown Pelican</td><td>2026-04-25T19:33:05+00:00</td></tr><tr><td>California Brown Pelican</td><td>California Brown Pelican</td><td>2026-04-09T01:37:42+00:00</td></tr><tr><td>California Brown Pelican</td><td>California Brown Pelican</td><td>2025-07-17T00:13:28+00:00</td></tr></tbody></table></div>

Agent

The most recent sighting of a pelican by Simon was recorded on May 20, 2026.

The observation included a California Brown Pelican, along with a Common Loon, Canada Goose, Striped Shore Crab, and a California Sea Lion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment