Timeline Filtered
| item_type | item_date | title | body | url |
|---|---|---|---|---|
| blog | 2026-06-11 | Datasette 1.0a33 with JSON extras in the API | The stable release of Datasette 1.0 has been in the pipeline for a long time. Today's release of 1.0a33 incorporates significant progress on one of the key blockers for that release: providing a stable, fully documented JSON API for accessing data hosted in Datasette. | https://datasette.io/blog/2026/api-extras/ |
| release | 2026-06-11 | datasette 1.0a33 | Stored queries can now be edited and deleted through the web interface, and the JSON API `?_extra=` mechanism has been extended to cover row and query pages in addition to tables. This release also fixes two security issues: a SQL injection vulnerability involving table and column names that contain `]`, and an open redirect. ### Editing and deleting stored queries The stored query page gained a "Query actions" menu with Edit this query and Delete this querylinks for actors with the necessary permissions. The owner of a query can always edit or delete it; for queries that are not private, any actor with the [update-query](https://docs.datasette.io/en/latest/authentication.html#actions-update-query) or [delete-query](https://docs.datasette.io/en/latest/authentication.html#actions-delete-query) permission can do so too. Private queries remain editable and deletable only by their owner. See [Stored queries](https://docs.datasette.io/en/latest/sql_queries.html#stored-queries) for details. ([#2735](https://github.com/simonw/datasette/issues/2735)) ### `?_extra=` support for row and query pages Row and query JSON pages now support the same `?_extra=` mechanism as table pages. Row pages can request extras such as `foreign_key_tables`, `query`, `metadata` and `database_color`; arbitrary SQL and stored query pages can request extras such as `columns`, `query`, `metadata` and `private`. The implementation was refactored into a registry of extra classes shared by all three page types. New generated reference documentation describes every `?_extra=` parameter available on table, row and query JSON pages, with example output captured from a live Datasette instance at documentation build time. See [Expanding JSON responses](https://docs.datasette.io/en/latest/json_api.html#json-api-extra) for the full list. Other improvements and fixes to the extras mechanism: - `?_extra=` values can be separated by commas as well as repeated, e.g. `?_extra=count,next_url`. Previously a comma-separated value that included … | https://github.com/simonw/datasette/releases/tag/1.0a33 |
| release | 2026-06-09 | llm 0.32a3 | Driven by the needs of [Datasette Agent](https://github.com/datasette/datasette-agent)'s human-in-the-loop `ask_user()` feature, made the following improvements to how tool calls work: - Tool implementations can declare a parameter named `llm_tool_call` in order to be passed the `llm.ToolCall` object for the current invocation. This allows them to access the current `llm_tool_call.tool_call_id`. See [Accessing the tool call from inside a tool](https://llm.datasette.io/en/latest/python-api.html#python-api-tools-llm-tool-call). [#1480](https://github.com/simonw/llm/pull/1480) - Every tool call is now guaranteed a unique `tool_call_id` - providers that do not supply one get a synthesized `tc_`-prefixed ULID. [#1481](https://github.com/simonw/llm/pull/1481) - Tools can raise a `llm.PauseChain` exception to cleanly pause the tool chain, useful for things like waiting for human approval. The exception propagates to the caller with `.tool_call` and `.tool_results` (completed sibling results) attached, and no model call is made with a placeholder result. See [Pausing a chain from inside a tool](https://llm.datasette.io/en/latest/python-api.html#python-api-tools-pause). [#1482](https://github.com/simonw/llm/pull/1482) - Failure semantics for concurrent tool execution: async sibling tool calls always run to completion before a pause or hook exception propagates. [#1482](https://github.com/simonw/llm/pull/1482) - Chains can now resume from a `messages=` history ending in unresolved tool calls: the calls are executed through the normal `before_call`/`after_call` machinery before the first model call, skipping any that already have results. The `execute_tool_calls()` method also accepts a new optional `tool_calls_list=` argument for executing an explicit list of `ToolCall` objects in place of the calls requested by the response. See [Resuming a chain with pending tool calls](https://llm.datasette.io/en/latest/python-api.html#python-api-tools-resume). [#1482](https://github.com/simonw/llm/pull/1482) - Fixed a bug where… | https://github.com/simonw/llm/releases/tag/0.32a3 |
| release | 2026-05-31 | datasette 1.0a32 | SQLite INSERT ... RETURNING clauses are now supported by `/db/-/execute-write`, plus several fixes relating to the [base_url setting](https://docs.datasette.io/en/latest/settings.html#setting-base-url). - `INSERT`/`UPDATE`/`DELETE` statements that use SQLite's `RETURNING` clause now work correctly in the new `/db/-/execute-write` interface. Datasette fetches returned rows before committing the write transaction, displays them in the HTML UI and includes them in the `"rows"` key for the JSON API response. ([#2762](https://github.com/simonw/datasette/issues/2762), [#2763](https://github.com/simonw/datasette/pull/2763)) - `Database.execute_write()` now returns an `ExecuteWriteResult` object instead of the raw `sqlite3.Cursor` returned by `conn.execute()`. The new object exposes `.rowcount`, `.lastrowid`, `.description`, `.truncated` and `.fetchall()`, and adds `return_all=` and `returning_limit=`options for controlling how rows from `RETURNING` statements are buffered. ([#2763](https://github.com/simonw/datasette/pull/2763)) - Fixed the `/-/jump` navigation search endpoint when Datasette is served with a configured `base_url`. ([#2757](https://github.com/simonw/datasette/issues/2757)) - Fixed JSON and CSV export links, plus `Link:` alternate headers, on table, row and query pages when `base_url` is configured. These could previously be prefixed twice. ([#2759](https://github.com/simonw/datasette/issues/2759)) - Fixed several other `base_url` handling bugs, including the API explorer form actions and share links, the `/-/patterns` development page, permanent redirects such as `/-` to `/-/` and database query redirects from `/<database>?sql=...` to `/<database>/-/query?sql=...`. | https://github.com/simonw/datasette/releases/tag/1.0a32 |
| blog | 2026-05-29 | SQL write queries and stored queries in Datasette 1.0a31 | With Datasette 1.0a31, Datasette now offers users with the necessary permissions the ability to both execute write queries against their database and save stored queries (renamed from "canned queries"), either privately and shared with other members of their Datasette instance. | https://datasette.io/blog/2026/sql-write-queries/ |
| release | 2026-05-29 | datasette 1.0a31 | Datasette now offers users with the necessary permissions the ability to both **execute write queries** against their database and to **save stored queries** (renamed from "canned queries") both privately and for use by other members of their Datasette instance. The ability to write is controlled by the new `execute-write-sql` permission, but the user also needs the relevant `insert-row`/`update-row`/`delete-row`/`create-table`/etc permissions for the query they are trying to execute. ### Write SQL UI - New "Write to this database" interface at `/<database>/-/execute-write` for running arbitrary writable SQL against mutable databases. The form extracts named parameters, analyzes the SQL, shows the table operations that will be attempted, includes starter templates for `INSERT`, `UPDATE` and `DELETE` statements and links to a newly inserted row when a single-row insert succeeds. This is also available as a [JSON API](https://docs.datasette.io/en/latest/json_api.html#executewriteview). ([#2742](https://github.com/simonw/datasette/issues/2742)) - Added the new [execute-write-sql](https://docs.datasette.io/en/latest/authentication.html#actions-execute-write-sql) permission for running arbitrary writable SQL. Execution is also gated by table-level permissions such as [insert-row](https://docs.datasette.io/en/latest/authentication.html#actions-insert-row), [update-row](https://docs.datasette.io/en/latest/authentication.html#actions-update-row) and [delete-row](https://docs.datasette.io/en/latest/authentication.html#actions-delete-row), and writes to attached databases are rejected. ([#2742](https://github.com/simonw/datasette/issues/2742)) - The write SQL analyzer now uses a deny-by-default model for unsupported operations. Reads from source tables require [view-table](https://docs.datasette.io/en/latest/authentication.html#actions-view-table) permission, schema changes require [create-table](https://docs.datasette.io/en/latest/authentication.html#actions-create-table), [alter-table](https://docs.datasette.i… | https://github.com/simonw/datasette/releases/tag/1.0a31 |
| blog | 2026-05-24 | The extensible "Jump to" menu in Datasette 1.0a30 | Datasette 1.0a30, released today, provides a new "Jump menu" for quickly navigating your Datasette instance, plus mechanisms for plugins to extend and customize that menu to incorporate their own custom features. | https://datasette.io/blog/2026/jump-menu/ |
| release | 2026-05-24 | datasette 1.0a30 | The "Jump to" menu, activated by hitting `/` or through the application menu, can now be extended by plugins. - New "Jump to..." menu item, always visible, for triggering the previously undocumented `/` menu. ([#2725](https://github.com/simonw/datasette/issues/2725)) - The `/` jump-to search interface now covers databases, views, canned queries and plugin-provided items in addition to tables. The endpoint backing it has been renamed from `/-/tables` to `/-/jump`. - New [jump_items_sql(datasette, actor, request)](https://docs.datasette.io/en/latest/plugin_hooks.html#plugin-hook-jump-items-sql) plugin hook, allowing plugins to contribute additional items to the jump-to menu by returning SQL. `JumpSQL` queries run against Datasette's internal database by default, or can target another database using the optional `database=`argument. ([#2731](https://github.com/simonw/datasette/issues/2731)) - `datasette.jump.JumpSQL.menu_item()` is a shortcut for adding individual jump menu items that are not backed by resources in the internal catalog. - New [makeJumpSections()](https://docs.datasette.io/en/latest/javascript_plugins.html#javascript-plugins-makejumpsections) JavaScript plugin hook, allowing plugins to add custom blank-state sections to the jump-to menu before the user has typed a query. - Debug menu links now appear in the jump-to menu instead of the top-right app menu, with descriptions for each debug item. - Dropped Janus as a dependency, previously used to manage the write queue. This should not have any impact on plugin developers or end-users. ([#1752](https://github.com/simonw/datasette/issues/1752)) - Fixed a bug where stale tables and other related resources were not removed from `catalog_*`tables when a database was removed. ([#2723](https://github.com/simonw/datasette/issues/2723)) - New documented [datasette.fixtures.populate_fixture_database(conn)](https://docs.datasette.io/en/latest/testing_plugins.html#datasette-fixtures-populate-fixture-database) helper for creating the fixture database tab… | https://github.com/simonw/datasette/releases/tag/1.0a30 |
| blog | 2026-05-21 | Datasette Agent, an extensible AI assistant for Datasette | Today we are releasing Datasette Agent, an open source plugin for Datasette that provides an extensible AI assistant for interacting with your SQLite databases. | https://datasette.io/blog/2026/datasette-agent/ |
| blog | 2026-05-13 | Welcome to the Datasette blog | It's about time the Datasette project had its own blog. | https://datasette.io/blog/2026/new-blog/ |
| release | 2026-05-13 | datasette-comments 0.1.2.a6 | https://github.com/datasette/datasette-comments/releases/tag/0.1.2.a6 | |
| release | 2026-05-12 | llm 0.32a2 | ### Support for the OpenAI Responses API Most reasoning-capable OpenAI models now use the [`/v1/responses`](https://developers.openai.com/api/reference/responses/overview) endpoint instead of `/v1/chat/completions`. This enables interleaved reasoning across tool calls for GPT-5 class models. [#1435](https://github.com/simonw/llm/pull/1435) - New `Responses` and `AsyncResponses` model classes driving the OpenAI Responses API. The existing `Chat` and `AsyncChat` classes are unchanged so other plugins that import them keep working. - The following models now use the Responses API by default: `o1`, `o3-mini`, `o3`, `o4-mini`, `gpt-5`, `gpt-5-mini`, `gpt-5-nano`, `gpt-5.1`, `gpt-5.2`, `gpt-5.4`, `gpt-5.4-mini`, `gpt-5.4-nano`, `gpt-5.5` (and their pinned date variants). - Use `-o chat_completions 1` to fall back to the older `/v1/chat/completions` code path for any of these models. - Encrypted reasoning items are captured as `provider_metadata` on `ReasoningPart` objects and round-tripped back to OpenAI on subsequent turns. - Reasoning summaries are now requested with `"summary": "auto"` so visible reasoning text is streamed back where the model produces it, unless `--hide-reasoning` or `hide_reasoning=` is set. - This means OpenAI prompts run using `llm prompt` that return reasoning tokens will display those on standard error. ### CLI - New `llm -m model --options` flag to list the options supported by a given model. [#1441](https://github.com/simonw/llm/pull/1441) - The `-R/--no-reasoning` option has been renamed to `-R/--hide-reasoning`. ### Python API - New `hide_reasoning=True` keyword argument on `model.prompt()`, `conversation.prompt()`, `model.chain()`, `conversation.chain()`, and their async counterparts, exposed to model plugins as `prompt.hide_reasoning`. Model plugins can [use this to decide](https://llm.datasette.io/en/latest/plugins/advanced-model-plugins.html#advanced-model-plugins-reasoning-tokens) if they should request visible reasoning summaries from their providers. [#1442](… | https://github.com/simonw/llm/releases/tag/0.32a2 |
| release | 2026-05-12 | datasette 1.0a29 | - New `TokenRestrictions.abbreviated(datasette)` [utility method](https://docs.datasette.io/en/latest/internals.html#tokenrestrictions) for creating `"_r"` dictionaries. #2695 - Table headers and column options are now visible even if a table contains zero rows. #2701 - Fixed bug with display of column actions dialog on Mobile Safari. #2708 - Fixed bug where tests could crash with a segfault due to a race condition between `Datasette.close()` and `Datasette.close()`. #2709 | https://github.com/simonw/datasette/releases/tag/1.0a29 |
| release | 2026-04-29 | llm 0.32a0 | This alpha introduces a major backwards-compatible refactor. Models can now be prompted with a list of messages, OpenAI Chat Completions style, and the response can now be iterated over as a sequence of mixed types of content, for example reasoning tokens mixed with text tokens mixed with tool calls. For more background on this release take a look at [the annotated release notes](https://simonwillison.net/2026/Apr/29/llm/) on my blog. Prompt inputs and response outputs are now expressed as a list of `Message` objects, each containing typed `Part` objects (text, reasoning, tool calls, tool results, attachments). The `llm` CLI tool can now display reasoning tokens while executing a prompt. Plugin authors should read the expanded [Advanced model plugins](https://llm.datasette.io/en/stable/plugins/advanced-model-plugins.html#advanced-model-plugins) documentation, which now covers `StreamEvent`, consuming `prompt.messages`, and round-tripping opaque provider metadata such as Anthropic extended-thinking signatures and Gemini `thoughtSignature` values. ### Structured messages and streaming events - New `llm.Message` value type and constructor helpers `llm.user()`, `llm.assistant()`, `llm.system()`, and `llm.tool_message()` for building structured prompt inputs. The helpers accept strings, `Attachment` instances, or nested `Part` lists. - New `messages=` keyword argument on `model.prompt()`, `conversation.prompt()`, `model.chain()`, `conversation.chain()`, and their async counterparts. The `prompt=`, `system=`, `attachments=`, and `tool_results=` keywords still work and synthesize into the same `Message` list internally. - New `response.stream_events()` and `response.astream_events()` methods yielding typed `StreamEvent` objects (`type` is one of `"text"`, `"reasoning"`, `"tool_call_name"`, `"tool_call_args"`, `"tool_result"`, plus a `redacted=True` marker for opaque reasoning). Iterating against `response` directly continues to yield only text strings. - New `response.messages()` method (async: `awa… | https://github.com/simonw/llm/releases/tag/0.32a0 |
| release | 2026-04-29 | llm 0.32a1 | - Fixed a bug in 0.32a0 where tool-calling conversations were not correctly reinflated from SQLite. [#1426](https://github.com/simonw/llm/issues/1426) | https://github.com/simonw/llm/releases/tag/0.32a1 |
| release | 2026-04-24 | llm 0.31 | - New GPT-5.5 OpenAI model: `llm -m gpt-5.5`. [#1418](https://github.com/simonw/llm/issues/1418) - New option to set the [text verbosity level](https://developers.openai.com/cookbook/examples/gpt-5/gpt-5_new_params_and_tools#1-verbosity-parameter) for GPT-5+ OpenAI models: `-o verbosity low`. Values are `low`, `medium`, `high`. - New option for setting the [image detail level](https://developers.openai.com/api/docs/guides/images-vision#choose-an-image-detail-level) used for image attachments to OpenAI models: `-o image_detail low` - values are `low`, `high` and `auto`, and GPT-5.4 and 5.5 also accept `original`. - Models listed in `extra-openai-models.yaml` are now also registered as asynchronous. [#1395](https://github.com/simonw/llm/issues/1395) | https://github.com/simonw/llm/releases/tag/0.31 |
| news | 2026-04-19 | Here's a new TIL on [using SQL functions in Google Sheets to fetch data from Datasette](https://til.simonwillison.net/google-sheets/datasette-sql). | https://datasette.io/news/2026-04-19 | |
| release | 2026-04-17 | datasette-comments 0.1.2.a1 | https://github.com/datasette/datasette-comments/releases/tag/0.1.2.a1 | |
| release | 2026-04-17 | datasette-comments 0.1.2.a2 | https://github.com/datasette/datasette-comments/releases/tag/0.1.2.a2 | |
| release | 2026-04-17 | datasette-comments 0.1.2.a3 | https://github.com/datasette/datasette-comments/releases/tag/0.1.2.a3 | |
| release | 2026-04-17 | datasette-comments 0.1.2.a4 | https://github.com/datasette/datasette-comments/releases/tag/0.1.2.a4 | |
| release | 2026-04-17 | datasette 1.0a28 | - Fixed a compatibility bug introduced in 1.0a27 where `execute_write_fn()` callbacks with a parameter name other than `conn` were seeing errors. ([#2691](https://github.com/simonw/datasette/issues/2691)) - The [database.close()](https://docs.datasette.io/en/latest/internals.html#database-close) method now also shuts down the write connection for that database. - New [datasette.close()](https://docs.datasette.io/en/latest/internals.html#datasette-close) method for closing down all databases and resources associated with a Datasette instance. This is called automatically when the server shuts down. ([#2693](https://github.com/simonw/datasette/pull/2693)) - Datasette now includes a pytest plugin which automatically calls `datasette.close()` on temporary instances created in function-scoped fixtures and during tests. See [Automatic cleanup of Datasette instances](https://docs.datasette.io/en/latest/testing_plugins.html#testing-plugins-autoclose) for details. This helps avoid running out of file descriptors in plugin test suites that were written before the `Database(is_temp_disk=True)` feature introduced in Datasette 1.0a27. ([#2692](https://github.com/simonw/datasette/issues/2692)) | https://github.com/simonw/datasette/releases/tag/1.0a28 |
| release | 2026-04-17 | datasette-public 0.4a1 | - Upgraded for compatibility with [Datasette 1.0a28](https://docs.datasette.io/en/latest/changelog.html#a28-2026-04-16). - Fixed `'duplicate column name: query_name'` warning on startup. | https://github.com/datasette/datasette-public/releases/tag/0.4a1 |
| news | 2026-04-15 | [Datasette 1.0a27](https://docs.datasette.io/en/latest/changelog.html#a27-2026-04-15) changes how CSRF protection works in a way that simplifies form and API integration, and introduces a new `RenameTableEvent` for when a table is renamed by a SQL query. | https://datasette.io/news/2026-04-15 | |
| release | 2026-04-15 | datasette 1.0a27 | ### CSRF protection no longer uses CSRF tokens Datasette's token-based CSRF protection has been replaced with a mechanism based on the `Sec-Fetch-Site` and `Origin` request headers, which are [supported by all modern browsers](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Sec-Fetch-Site). See [this article by Filippo Valsorda](https://words.filippo.io/csrf/) for more details of this approach. This removes the need for CSRF tokens in forms and AJAX requests. ([#2689](https://github.com/simonw/datasette/pull/2689)) ### `RenameTableEvent` when a table is renamed Renaming a table within Datasette will now fire a new [`RenameTableEvent`](https://docs.datasette.io/en/latest/events.html#datasette.events.RenameTableEvent "datasette.events.RenameTableEvent"), which plugins can use to react by updating ACL records or re-assigning comments or other associated records to the new table name. ([#2681](https://github.com/simonw/datasette/issues/2681)) This event will not be fired if the table is renamed by SQL running in some other process. The `datasette.track_event()` method can now be called from within a write operation (using [database.execute_write()](https://docs.datasette.io/en/latest/internals.html#database-execute-write) and related methods) and the event will be fired after the write transaction has successfully committed. ([#2682](https://github.com/simonw/datasette/pull/2682)) ### Other changes - New [actor= parameter](https://docs.datasette.io/en/latest/internals.html#internals-datasette-client-actor) for `datasette.client` methods, allowing internal requests to be made as a specific actor. This is particularly useful for writing automated tests. ([#2688](https://github.com/simonw/datasette/pull/2688)) - New `Database(is_temp_disk=True)` option, used internally for the internal database. This helps resolve intermittent database locked errors caused by the internal database being in-memory as opposed to on-disk. ([#2683](https://github.com/simonw/datasette/issues/2683)) (… | https://github.com/simonw/datasette/releases/tag/1.0a27 |
| release | 2026-04-15 | datasette-export-database 0.3a1 | - Upgraded for compatibility with [Datasette 1.0a27](https://docs.datasette.io/en/latest/changelog.html#a27-2026-04-15). | https://github.com/datasette/datasette-export-database/releases/tag/0.3a1 |
| release | 2026-04-09 | datasette-gzip 0.3 | - Depend on [asgi-gzip >= 0.3](https://github.com/simonw/asgi-gzip/releases/0.3) to avoid compressing `text/event-stream`. | https://github.com/simonw/datasette-gzip/releases/tag/0.3 |
| release | 2026-04-08 | datasette-template-sql 1.0.3 | - Upgraded for compatibility with Datasette 1.0a26+ | https://github.com/simonw/datasette-template-sql/releases/tag/1.0.3 |
| release | 2026-04-08 | dogsheep-beta 0.11 | - Upgrade for compatibility with Datasette 1.0 alphas. | https://github.com/dogsheep/dogsheep-beta/releases/tag/0.11 |
| release | 2026-04-08 | datasette-atom 0.10a0 | - Compatible with Datasette 1.0 alphas. | https://github.com/simonw/datasette-atom/releases/tag/0.10a0 |
| release | 2026-04-08 | datasette-graphql 3.0a1 | - Upgrade for compatibility with `datasette>=1.0a20`. #102, #103 | https://github.com/simonw/datasette-graphql/releases/tag/3.0a1 |
| release | 2026-04-01 | datasette-extract 0.3a0 | - Now uses [datasette-llm](https://github.com/datasette/datasette-llm) to manage model configuration, which means you can control which models are available for extraction tasks using the `extract` purpose and [LLM model configuration](https://github.com/datasette/datasette-llm/blob/main/README.md#configuration). #38 | https://github.com/datasette/datasette-extract/releases/tag/0.3a0 |
| release | 2026-03-31 | llm 0.30 | - The [register_models() plugin hook](http://llm.datasette.io/en/stable/plugins/plugin-hooks.html#plugin-hooks-register-models) now takes an optional `model_aliases` parameter listing all of the models, async models and aliases that have been registered so far by other plugins. A plugin with `@hookimpl(trylast=True)` can use this to take previously registered models into account. #1389 - Added docstrings to public classes and methods and included those directly in the documentation. | https://github.com/simonw/llm/releases/tag/0.30 |
| news | 2026-03-18 | [Datasette 1.0a26](https://docs.datasette.io/en/latest/changelog.html#a26-2026-03-18) adds a `column_types` system allowing columns to carry additional type information such as `email` or `url`, or extra types defined by plugins. This alpha also adds a UI for selecting and sorting visible columns on a table page. | https://datasette.io/news/2026-03-18 | |
| release | 2026-03-18 | datasette 1.0a26 | ### New `column_types` system Table columns can now have custom column types assigned to them, using the new `column_types` table configuration option or at runtime using a new UI and `POST /<database>/<table>/-/set-column-type` JSON API. Built-in column types include `url`, `email`, and `json`, and plugins can register additional types using the new [register_column_types()](https://docs.datasette.io/en/latest/plugin_hooks.html#plugin-register-column-types) plugin hook. ([#2664](https://github.com/simonw/datasette/issues/2664), [#2671](https://github.com/simonw/datasette/issues/2671)) Column types can customize HTML rendering, validate values written through the insert, update, and upsert APIs, and transform values returned by the JSON API. They can optionally restrict themselves to specific SQLite column types using `sqlite_types`. This feature also introduces a new [set-column-type](https://docs.datasette.io/en/latest/authentication.html#actions-set-column-type) permission for assigning column types to a table. ([#2672](https://github.com/simonw/datasette/issues/2672)) The [render_cell()](https://docs.datasette.io/en/latest/plugin_hooks.html#plugin-hook-render-cell) plugin hook now receives a `column_type` argument containing the assigned type instance, and a column type's own `render_cell()` method takes priority over the plugin hook chain. The [datasette-files](https://github.com/datasette/datasette-files) plugin will be the first to use this new feature. ### UI for selecting columns and their order Table and view pages now include a dialog for selecting and re-ordering visible columns. ([#2661](https://github.com/simonw/datasette/issues/2661)) ### Other changes - Fixed `allowed_resources("view-query", actor)` so actor-specific canned queries are returned correctly. Any plugin that defines a `resources_sql()` method on a `Resource` subclass needs to update to the new signature, see [the resources_sql() method](https://docs.datasette.io/en/latest/plugin_hooks.html#plugin-resources-s… | https://github.com/simonw/datasette/releases/tag/1.0a26 |
| release | 2026-03-17 | llm 0.29 | - The `-t/--template` option now works correctly with the `-x/--extract` and `--xl/--extract-last` flags. - `llm logs` now shows any additional model options in the Markdown output. #1322 - New OpenAI models: `gpt-5.4`, `gpt-5.4-mini`, `gpt-5.4-nano`. #1376 | https://github.com/simonw/llm/releases/tag/0.29 |
| release | 2026-02-26 | datasette 1.0a25 | ### `write_wrapper()` plugin hook for intercepting write operations A new [write_wrapper()](https://docs.datasette.io/en/latest/plugin_hooks.html#plugin-hook-write-wrapper) plugin hook allows plugins to intercept and wrap database write operations. ([#2636](https://github.com/simonw/datasette/pull/2636)) Plugins implement the hook as a generator-based context manager: ```python @hookimpl def write_wrapper(datasette, database, request): def wrapper(conn): # Setup code runs before the write yield # Cleanup code runs after the write return wrapper ``` ### `register_token_handler()` plugin hook for custom API token backends A new [register_token_handler()](https://docs.datasette.io/en/latest/plugin_hooks.html#plugin-hook-register-token-handler) plugin hook allows plugins to provide custom token backends for API authentication. ([#2650](https://github.com/simonw/datasette/pull/2650)) This includes a **backwards incompatible change**: the `datasette.create_token()` internal method is now an `async` method. Consult the [upgrade guide](https://docs.datasette.io/en/latest/upgrade_guide.html#upgrade-guide-v1-a25) for details on how to update your code. ### `render_cell()` now receives a `pks` parameter The [render_cell()](https://docs.datasette.io/en/latest/plugin_hooks.html#plugin-hook-render-cell) plugin hook now receives a `pks` parameter containing the list of primary key column names for the table being rendered. This avoids plugins needing to make redundant async calls to look up primary keys. ([#2641](https://github.com/simonw/datasette/pull/2641)) ### Other changes - Facets defined in metadata now preserve their configured order, instead of being sorted by result count. Request-based facets added via the `_facet` parameter are still sorted by result count and appear after metadata-defined facets. ([#2647](https://github.com/simonw/datasette/issues/2647)) - Fixed `--reload` incorrectly interpreting the `serve` command as a file argument. Than… | https://github.com/simonw/datasette/releases/tag/1.0a25 |
| release | 2026-02-26 | datasette-auth-tokens 0.4a12 | - Compatible with [Datasette 1.0a25](https://docs.datasette.io/en/latest/changelog.html#a25-2026-02-25). #38 - Switched to `pyproject.toml` and `uv`. #39 | https://github.com/simonw/datasette-auth-tokens/releases/tag/0.4a12 |
| news | 2026-02-25 | [Datasette 1.0a25](https://docs.datasette.io/en/latest/changelog.html#a25-2026-02-25) adds [write_wrapper()](https://docs.datasette.io/en/latest/plugin_hooks.html#plugin-hook-write-wrapper) and [register_token_handler()](https://docs.datasette.io/en/latest/plugin_hooks.html#plugin-hook-register-token-handler) plugin hooks. | https://datasette.io/news/2026-02-25 | |
| release | 2026-02-08 | datasette-packages 0.3 | - `/-/packages` page now links each package to a new package details page showing metadata and the README. #7 - Now recommends `uv` for the development environment. | https://github.com/simonw/datasette-packages/releases/tag/0.3 |
| release | 2026-02-08 | datasette-pretty-traces 0.7 | - Now intercepts `fetch()` calls and adds those to the visible traces on the page. #10 - `uv run pytest` can now run the tests on a fresh checkout. | https://github.com/simonw/datasette-pretty-traces/releases/tag/0.7 |
| release | 2026-02-04 | datasette-youtube-embed 0.2 | - Update `lite-youtube-embed` to latest version from upstream. Thanks, [Agustin Bacigalup V](https://github.com/redraw). #3 | https://github.com/simonw/datasette-youtube-embed/releases/tag/0.2 |
| release | 2026-02-01 | shot-scraper 1.9.1 | - Fix for a bug where Playwright 1.58 and higher threw an error. #189 - Recommended development environment now uses `uv`. | https://github.com/simonw/shot-scraper/releases/tag/1.9.1 |
| news | 2026-01-29 | [Datasette 1.0a24](https://docs.datasette.io/en/latest/changelog.html#a24-2026-01-29) introduces a new `await request.form(files=True)` method for accepting file uploads, plus various other changes. | https://datasette.io/news/2026-01-29 | |
| release | 2026-01-29 | datasette 1.0a24 | ## `request.form()` method for POST data and file uploads Datasette now includes a `request.form()` method for parsing form submissions, including handling file uploads. ([#2626](https://github.com/simonw/datasette/pull/2626)) This supports both `application/x-www-form-urlencoded` and `multipart/form-data` content types, and uses a new streaming multipart parser that processes uploads without buffering entire request bodies in memory. ```python # Parse form fields (files are discarded by default) form = await request.form() username = form["username"] # Parse form fields AND file uploads form = await request.form(files=True) uploaded = form["avatar"] content = await uploaded.read() ``` The returned [FormData](https://docs.datasette.io/en/latest/internals.html#internals-formdata) object provides dictionary-style access with support for multiple values per key via `form.getlist("key")`. Uploaded files are represented as [UploadedFile](https://docs.datasette.io/en/latest/internals.html#internals-uploadedfile) objects with `filename`, `content_type`, `size` properties and async `read()` and `seek()` methods. Files smaller than 1MB are held in memory; larger files automatically spill to temporary files on disk. Configurable limits control maximum file size, request size, field counts and more. Several internal views (permissions debug, messages debug, create token) now use `request.form()` instead of `request.post_vars()`. `request.post_vars()` remains available for backwards compatibility but is no longer the recommended API for handling POST data. ## `render_cell` and `foreign_key_tables` extras for the JSON API The table JSON API now supports `?_extra=render_cell`, which returns the rendered HTML for each cell as produced by the [render_cell plugin hook](https://docs.datasette.io/en/latest/plugin_hooks.html#plugin-hook-render-cell). Only columns whose rendered output differs from the default are included. ([#2619](https://github.com/simonw/datasette/issues/2619)) The row JSON API… | https://github.com/simonw/datasette/releases/tag/1.0a24 |
| release | 2026-01-26 | datasette-visible-internal-db 0.1.1a2 | - Relax pinned version of Datasette. | https://github.com/datasette/datasette-visible-internal-db/releases/tag/0.1.1a2 |
| release | 2026-01-19 | datasette-scale-to-zero 0.3.2 | - Upgraded to `pyproject.toml`. - Dropped support for Python <3.10. - Clarified how to disable the plugin. | https://github.com/simonw/datasette-scale-to-zero/releases/tag/0.3.2 |
| release | 2026-01-06 | datasette-public 0.4a0 | - Now requires [Datasette 1.0a22](https://docs.datasette.io/en/latest/changelog.html#a22-2025-11-13) or higher running in `--default-deny` mode. #19 - Making a database public makes all tables in that database public. - Canned queries still stay private unless toggled even if their database is public. | https://github.com/datasette/datasette-public/releases/tag/0.4a0 |
| release | 2025-12-29 | shot-scraper 1.9 | - The `shot-scraper har` command has a new `-x/--extract` option which extracts all of the resources loaded by the page out to a set of files. This location can be controlled by the `-o dir/` option. #184 - Fixed the `shot-scraper accessibility` command for compatibility with the latest Playwright. #185 | https://github.com/simonw/shot-scraper/releases/tag/1.9 |
| release | 2025-12-21 | git-history 0.7 | - The `--repo` option now supports repository URLs like `https://github.com/user/repo` or `git@github.com:user/repo`. [#67](https://github.com/simonw/git-history/issues/67) - New `--encoding` option for reading CSV files with different character encodings. [#68](https://github.com/simonw/git-history/pull/68) - Fixed bug where the item table did not correctly link to the commits using a foreign key. [#59](https://github.com/simonw/git-history/issues/59) - Fixed bug where some repositories would not process correctly due to data from older versions not being successfully loaded from the commit history. [#64](https://github.com/simonw/git-history/issues/64) | https://github.com/simonw/git-history/releases/tag/0.7 |
| release | 2025-12-16 | s3-credentials 0.17 | - New commands `get-bucket-policy` and `set-bucket-policy`. #91 - New commands `get-public-access-block` and `set-public-access-block`. #92 - New `localserver` command for starting a web server that makes time limited credentials accessible via a JSON API. #93 | https://github.com/simonw/s3-credentials/releases/tag/0.17 |
| release | 2025-12-12 | llm 0.28 | - New OpenAI models: `gpt-5.1`, `gpt-5.1-chat-latest`, `gpt-5.2` and `gpt-5.2-chat-latest`. [#1300](https://github.com/simonw/llm/issues/1300), [#1317](https://github.com/simonw/llm/issues/1317) - LLM now requires Python 3.10 or higher. Python 3.14 is now covered by the tests. - When fetching URLs as fragments using `llm -f URL`, the request now includes a custom user-agent header: `llm/VERSION (https://llm.datasette.io/)`. [#1309](https://github.com/simonw/llm/issues/1309) - Fixed a bug where fragments were not correctly registered with their source when using `llm chat`. Thanks, [Giuseppe Rota](https://github.com/grota). [#1316](https://github.com/simonw/llm/pull/1316) - Fixed some file descriptor leak warnings. Thanks, [Eric Bloch](https://github.com/eedeebee). [#1313](https://github.com/simonw/llm/issues/1313) - Fixed a deprecation warning for `asyncio.iscoroutinefunction`. - Type annotations for the OpenAI Chat, AsyncChat and Completion `execute()` methods. Thanks, [Arjan Mossel](https://github.com/ar-jan). [#1315](https://github.com/simonw/llm/pull/1315) - The project now uses `uv` and dependency groups for development. See the updated [contributing documentation](https://llm.datasette.io/en/stable/contributing.html). [#1318](https://github.com/simonw/llm/issues/1318) | https://github.com/simonw/llm/releases/tag/0.28 |
| release | 2025-12-03 | datasette 1.0a23 | - Fix for bug where a stale database entry in `internal.db` could cause a 500 error on the homepage. #2605 - Cosmetic improvement to `/-/actions` page. #2599 | https://github.com/simonw/datasette/releases/tag/1.0a23 |
| release | 2025-12-03 | datasette-extract 0.2a1 | - Fixed a bug where the `tests/` where included in the released wheel. #37 | https://github.com/datasette/datasette-extract/releases/tag/0.2a1 |
| release | 2025-11-26 | datasette-extract 0.2a0 | - Integration with [datasette-llm-accountant](https://github.com/datasette/datasette-llm-accountant). #36 | https://github.com/datasette/datasette-extract/releases/tag/0.2a0 |
| release | 2025-11-24 | sqlite-utils 4.0a1 | - **Breaking change**: The `db.table(table_name)` method now only works with tables. To access a SQL view use `db.view(view_name)` instead. ([#657](https://github.com/simonw/sqlite-utils/issues/657)) - The `table.insert_all()` and `table.upsert_all()` methods can now accept an iterator of lists or tuples as an alternative to dictionaries. The first item should be a list/tuple of column names. See [Inserting data from a list or tuple iterator](https://sqlite-utils.datasette.io/en/stable/python-api.html#python-api-insert-lists) for details. ([#672](https://github.com/simonw/sqlite-utils/issues/672)) - **Breaking change**: The default floating point column type has been changed from `FLOAT` to `REAL`, which is the correct SQLite type for floating point values. This affects auto-detected columns when inserting data. ([#645](https://github.com/simonw/sqlite-utils/issues/645)) - Now uses `pyproject.toml` in place of `setup.py` for packaging. ([#675](https://github.com/simonw/sqlite-utils/issues/675)) - Tables in the Python API now do a much better job of remembering the primary key and other schema details from when they were first created. ([#655](https://github.com/simonw/sqlite-utils/issues/655)) - **Breaking change**: The `table.convert()` and `sqlite-utils convert` mechanisms no longer skip values that evaluate to `False`. Previously the `--skip-false` option was needed, this has been removed. ([#542](https://github.com/simonw/sqlite-utils/issues/542)) - **Breaking change**: Tables created by this library now wrap table and column names in `"double-quotes"` in the schema. Previously they would use `[square-braces]`. ([#677](https://github.com/simonw/sqlite-utils/issues/677)) - The `--functions` CLI argument now accepts a path to a Python file in addition to accepting a string full of Python code. It can also now be specified multiple times. ([#659](https://github.com/simonw/sqlite-utils/issues/659)) - **Breaking change:** Type detection is now the default behavior for the `insert` and `upsert` CLI commands… | https://github.com/simonw/sqlite-utils/releases/tag/4.0a1 |
| release | 2025-11-24 | sqlite-utils 3.39 | * Fixed a bug with `sqlite-utils install` when the tool had been installed using `uv`. (#687) * The `--functions` argument now optionally accepts a path to a Python file as an alternative to a string full of code, and can be specified multiple times – see [Defining custom SQL functions](https://sqlite-utils.datasette.io/en/stable/cli.html#cli-query-functions). (#659) * `sqlite-utils` now requires Python 3.10 or higher. [sqlite-utils 4.0a1](https://sqlite-utils.datasette.io/en/latest/changelog.html#a1-2025-11-23) is now available as an alpha with some [minor breaking changes](https://simonwillison.net/2025/Nov/24/sqlite-utils-40a1/). | https://github.com/simonw/sqlite-utils/releases/tag/3.39 |
| release | 2025-11-16 | datasette-auth-github 0.14 | - Added support for GitHub Enterprise. Thanks, [Steffen Uhlig](https://github.com/suhlig). #75 - Now correctly handles `base_url` setting. Thanks, [Michal Porebski](https://github.com/michal-porebski). #76 - Actors now include an `"id"` key of `"github:ID"`. Thanks, [Brendan Samek](https://github.com/xrendan). #77 | https://github.com/simonw/datasette-auth-github/releases/tag/0.14 |
| release | 2025-11-13 | datasette 1.0a22 | - `datasette serve --default-deny` option for running Datasette configured to [deny all permissions by default](https://docs.datasette.io/en/latest/authentication.html#authentication-default-deny). ([#2592](https://github.com/simonw/datasette/issues/2592)) - `datasette.is_client()` method for detecting if code is [executing inside a datasette.client request](https://docs.datasette.io/en/latest/internals.html#internals-datasette-is-client). ([#2594](https://github.com/simonw/datasette/issues/2594)) - `datasette.pm` property can now be used to [register and unregister plugins in tests](https://docs.datasette.io/en/latest/testing_plugins.html#testing-plugins-register-in-test). ([#2595](https://github.com/simonw/datasette/issues/2595)) | https://github.com/simonw/datasette/releases/tag/1.0a22 |
| release | 2025-11-12 | datasette-enrichments-opencage 0.1.2a0 | https://github.com/datasette/datasette-enrichments-opencage/releases/tag/0.1.2a0 | |
| release | 2025-11-12 | datasette-enrichments-opencage 0.1.2a1 | https://github.com/datasette/datasette-enrichments-opencage/releases/tag/0.1.2a1 | |
| release | 2025-11-12 | datasette-public 0.3a5 | - Fix for error on non-canned-query page. #17 | https://github.com/datasette/datasette-public/releases/tag/0.3a5 |
| release | 2025-11-11 | datasette-export-database 0.3a0 | - Upgraded for compatibility with [Datasette 1.0a20](https://docs.datasette.io/en/latest/changelog.html#a20-2025-11-03). | https://github.com/datasette/datasette-export-database/releases/tag/0.3a0 |
| release | 2025-11-11 | datasette-write 0.5a0 | - Upgraded for compatibility with [Datasette 1.0a20](https://docs.datasette.io/en/latest/changelog.html#a20-2025-11-03). | https://github.com/simonw/datasette-write/releases/tag/0.5a0 |
| release | 2025-11-11 | datasette-create-view 0.2a0 | - Upgraded for compatibility with [Datasette 1.0a20](https://docs.datasette.io/en/latest/changelog.html#a20-2025-11-03). | https://github.com/datasette/datasette-create-view/releases/tag/0.2a0 |
| release | 2025-11-11 | datasette-secrets 0.3a0 | - Upgraded for compatibility with [Datasette 1.0a20](https://docs.datasette.io/en/latest/changelog.html#a20-2025-11-03). | https://github.com/datasette/datasette-secrets/releases/tag/0.3a0 |
| release | 2025-11-11 | datasette-extract 0.1a12 | - Upgraded for compatibility with [Datasette 1.0a20](https://docs.datasette.io/en/latest/changelog.html#a20-2025-11-03). | https://github.com/datasette/datasette-extract/releases/tag/0.1a12 |
| release | 2025-11-11 | datasette-ripgrep 0.9a0 | - Upgraded for compatibility with [Datasette 1.0a20](https://docs.datasette.io/en/latest/changelog.html#a20-2025-11-03). | https://github.com/simonw/datasette-ripgrep/releases/tag/0.9a0 |
| release | 2025-11-11 | datasette-comments 0.1.1.a3 | - Upgraded for compatibility with [Datasette 1.0a20](https://docs.datasette.io/en/latest/changelog.html#a20-2025-11-03). | https://github.com/datasette/datasette-comments/releases/tag/0.1.1.a3 |
| release | 2025-11-10 | datasette-upload-csvs 0.10a0 | - Upgraded for compatibility with [Datasette 1.0a20](https://docs.datasette.io/en/latest/changelog.html#a20-2025-11-03). | https://github.com/simonw/datasette-upload-csvs/releases/tag/0.10a0 |
| release | 2025-11-10 | datasette-edit-templates 0.5a0 | - Upgraded for compatibility with [Datasette 1.0a20](https://docs.datasette.io/en/latest/changelog.html#a20-2025-11-03). | https://github.com/simonw/datasette-edit-templates/releases/tag/0.5a0 |
| release | 2025-11-10 | datasette-configure-fts 1.2a0 | - Upgraded for compatibility with [Datasette 1.0a20](https://docs.datasette.io/en/latest/changelog.html#a20-2025-11-03). | https://github.com/simonw/datasette-configure-fts/releases/tag/1.2a0 |
| release | 2025-11-10 | datasette-upload-dbs 0.4a0 | - Upgraded for compatibility with [Datasette 1.0a20](https://docs.datasette.io/en/latest/changelog.html#a20-2025-11-03). | https://github.com/simonw/datasette-upload-dbs/releases/tag/0.4a0 |
| release | 2025-11-10 | datasette-auth-tokens 0.4a11 | - Upgraded for compatibility with [Datasette 1.0a20](https://docs.datasette.io/en/latest/changelog.html#a20-2025-11-03). | https://github.com/simonw/datasette-auth-tokens/releases/tag/0.4a11 |
| release | 2025-11-10 | datasette-edit-schema 0.8a5 | - Upgraded for compatibility with [Datasette 1.0a20](https://docs.datasette.io/en/latest/changelog.html#a20-2025-11-03). | https://github.com/simonw/datasette-edit-schema/releases/tag/0.8a5 |
| release | 2025-11-10 | datasette-events-forward 0.1a4 | - Fix an issue where multiple copies of this plugin could cause warnings in tests. #5 | https://github.com/datasette/datasette-events-forward/releases/tag/0.1a4 |
| release | 2025-11-09 | datasette-ephemeral-tables 0.2.3 | - Fix for flash of pink bar with no text. #6 | https://github.com/simonw/datasette-ephemeral-tables/releases/tag/0.2.3 |
| release | 2025-11-08 | datasette-events-db 0.1a2 | - Upgraded for compatibility with [Datasette 1.0a20](https://docs.datasette.io/en/latest/changelog.html#a20-2025-11-03). | https://github.com/datasette/datasette-events-db/releases/tag/0.1a2 |
| release | 2025-11-08 | datasette-write-ui 0.0.1a14 | - Upgraded for compatibility with [Datasette 1.0a20](https://docs.datasette.io/en/latest/changelog.html#a20-2025-11-03). | https://github.com/datasette/datasette-write-ui/releases/tag/0.0.1a14 |
| release | 2025-11-08 | datasette-query-assistant 0.1a5 | - Upgraded for compatibility with [Datasette 1.0a20](https://docs.datasette.io/en/latest/changelog.html#a20-2025-11-03). | https://github.com/datasette/datasette-query-assistant/releases/tag/0.1a5 |
| release | 2025-11-06 | datasette-enrichments 0.6a0 | * Add `actor_id` parameter to `enrich_batch()` method. #59 * Upgrade for Datasette 1.0a21. #61 | https://github.com/datasette/datasette-enrichments/releases/tag/0.6a0 |
| release | 2025-11-06 | datasette-checkbox 0.1a4 | - Upgraded for compatibility with [Datasette 1.0a20](https://docs.datasette.io/en/latest/changelog.html#a20-2025-11-03). | https://github.com/datasette/datasette-checkbox/releases/tag/0.1a4 |
| news | 2025-11-05 | [Datasette 0.65.2](https://docs.datasette.io/en/stable/changelog.html#v0-65-2) and [Datasette 1.0a21](https://docs.datasette.io/en/latest/changelog.html#a21-2025-11-05) have been released with a **security fix** for an open redirect error, see [this advisory](https://github.com/simonw/datasette/security/advisories/GHSA-w832-gg5g-x44m). The latest Datasette alphas also include a breaking change to Datasette's permission system, described in detail in [A new SQL-powered permissions system in Datasette 1.0a20](https://simonwillison.net/2025/Nov/4/datasette-10a20/). | https://datasette.io/news/2025-11-05 | |
| release | 2025-11-05 | datasette 0.65.2 | - Fixes an **open redirect** security issue: Datasette instances would redirect to `example.com/foo/bar` if you accessed the path `//example.com/foo/bar`. Thanks to [James Jefferies](https://github.com/jamesjefferies) for the fix. [#2429](https://github.com/simonw/datasette/issues/2429) - Upgraded for compatibility with Python 3.14. - Fixed `datasette publish cloudrun` to work with changes to the underlying Cloud Run architecture. [#2511](https://github.com/simonw/datasette/issues/2511) - Minor upgrades to fix warnings, including `pkg_resources` deprecation. | https://github.com/simonw/datasette/releases/tag/0.65.2 |
| release | 2025-11-05 | datasette 1.0a21 | - Fixes an **open redirect** security issue: Datasette instances would redirect to `example.com/foo/bar` if you accessed the path `//example.com/foo/bar`. Thanks to [James Jefferies](https://github.com/jamesjefferies) for the fix. ([#2429](https://github.com/simonw/datasette/issues/2429)) - Fixed `datasette publish cloudrun` to work with changes to the underlying Cloud Run architecture. ([#2511](https://github.com/simonw/datasette/issues/2511)) - New `datasette --get /path --headers` option for inspecting the headers returned by a path. ([#2578](https://github.com/simonw/datasette/issues/2578)) - New `datasette.client.get(..., skip_permission_checks=True)` parameter to bypass permission checks when making requests using the internal client. ([#2583](https://github.com/simonw/datasette/issues/2583)) | https://github.com/simonw/datasette/releases/tag/1.0a21 |
| release | 2025-11-04 | datasette-tail 0.1a2 | - Upgraded for compatibility with [Datasette 1.0a20](https://docs.datasette.io/en/latest/changelog.html#a20-2025-11-03). | https://github.com/datasette/datasette-tail/releases/tag/0.1a2 |
| release | 2025-11-04 | datasette-events-forward 0.1a3 | - Upgraded for compatibility with [Datasette 1.0a20](https://docs.datasette.io/en/latest/changelog.html#a20-2025-11-03). | https://github.com/datasette/datasette-events-forward/releases/tag/0.1a3 |
| release | 2025-11-03 | datasette 1.0a20 | This alpha introduces a major breaking change prior to the 1.0 release of Datasette concerning how Datasette's permission system works. ### Permission system redesign Previously the permission system worked using `datasette.permission_allowed()` checks which consulted all available plugins in turn to determine whether a given actor was allowed to perform a given action on a given resource. This approach could become prohibitively expensive for large lists of items - for example to determine the list of tables that a user could view in a large Datasette instance each plugin implementation of that hook would be fired for every table. The new design uses SQL queries against Datasette's internal [catalog tables](https://docs.datasette.io/en/latest/internals.html#internals-internal) to derive the list of resources for which an actor has permission for a given action. This turns an N x M problem (N resources, M plugins) into a single SQL query. Plugins can use the new [permission_resources_sql(datasette, actor, action)](https://docs.datasette.io/en/latest/plugin_hooks.html#plugin-hook-permission-resources-sql) hook to return SQL fragments which will be used as part of that query. Plugins that use any of the following features will need to be updated to work with this and following alphas (and Datasette 1.0 stable itself): - Checking permissions with `datasette.permission_allowed()` - this method has been replaced with [datasette.allowed()](https://docs.datasette.io/en/latest/internals.html#datasette-allowed). - Implementing the `permission_allowed()` plugin hook - this hook has been removed in favor of [permission_resources_sql()](https://docs.datasette.io/en/latest/plugin_hooks.html#plugin-hook-permission-resources-sql). - Using `register_permissions()` to register permissions - this hook has been removed in favor of [register_actions()](https://docs.datasette.io/en/latest/plugin_hooks.html#plugin-register-actions). Consult the [v1.0a20 upgrade guide](https://docs.datasette.io/en/latest… | https://github.com/simonw/datasette/releases/tag/1.0a20 |
| release | 2025-11-03 | datasette-search-all 1.1.5a0 | - Upgraded for compatibility with [Datasette 1.0a20](https://docs.datasette.io/en/latest/changelog.html#a20-2025-11-03). #22 | https://github.com/simonw/datasette-search-all/releases/tag/1.1.5a0 |
| release | 2025-10-24 | datasette-pretty-traces 0.6 | - Add total request time, total SQL time and number of SQL queries to trace display. #9 | https://github.com/simonw/datasette-pretty-traces/releases/tag/0.6 |
| release | 2025-10-21 | datasette-tail 0.1a1 | - Pin to datasette==1.0a19. [datasette/#2516](https://github.com/simonw/datasette/issues/2516) | https://github.com/datasette/datasette-tail/releases/tag/0.1a1 |
| release | 2025-10-21 | datasette-column-sum 0.1a1 | - Pin to datasette==1.0a19. [datasette/#2516](https://github.com/simonw/datasette/issues/2516) | https://github.com/datasette/datasette-column-sum/releases/tag/0.1a1 |
| release | 2025-10-21 | datasette-checkbox 0.1a3 | - Pin to datasette==1.0a19. [datasette/#2516](https://github.com/simonw/datasette/issues/2516) | https://github.com/datasette/datasette-checkbox/releases/tag/0.1a3 |
| release | 2025-10-21 | datasette-extract 0.1a11 | - Pin to datasette==1.0a19. [datasette/#2516](https://github.com/simonw/datasette/issues/2516) | https://github.com/datasette/datasette-extract/releases/tag/0.1a11 |
| release | 2025-10-21 | datasette-query-assistant 0.1a4 | - Pin to datasette==1.0a19. [datasette/#2516](https://github.com/simonw/datasette/issues/2516) | https://github.com/datasette/datasette-query-assistant/releases/tag/0.1a4 |
| release | 2025-10-21 | datasette-edit-schema 0.8a4 | - Pin to datasette==1.0a19. [datasette/#2516](https://github.com/simonw/datasette/issues/2516) | https://github.com/simonw/datasette-edit-schema/releases/tag/0.8a4 |
| release | 2025-10-21 | datasette-events-db 0.1a1 | - Pin to datasette==1.0a19. [datasette/#2516](https://github.com/simonw/datasette/issues/2516) | https://github.com/datasette/datasette-events-db/releases/tag/0.1a1 |
| release | 2025-10-21 | datasette-public 0.3a4 | - Pin to datasette==1.0a19. [datasette/#2516](https://github.com/simonw/datasette/issues/2516) | https://github.com/datasette/datasette-public/releases/tag/0.3a4 |
| release | 2025-10-21 | datasette-import 0.1a6 | - Pin to datasette==1.0a19. [datasette/#2516](https://github.com/simonw/datasette/issues/2516) | https://github.com/datasette/datasette-import/releases/tag/0.1a6 |
| release | 2025-10-21 | datasette-plot 0.1.0a1 | - Pin to datasette==1.0a19. [datasette/#2516](https://github.com/simonw/datasette/issues/2516) | https://github.com/datasette/datasette-plot/releases/tag/0.1.0a1 |
| release | 2025-10-21 | datasette-write-ui 0.0.1a13 | - Pin to datasette==1.0a19. [datasette/#2516](https://github.com/simonw/datasette/issues/2516) | https://github.com/datasette/datasette-write-ui/releases/tag/0.0.1a13 |
| release | 2025-10-21 | datasette-create-view 0.1a1 | - Pin to datasette==1.0a19. [datasette/#2516](https://github.com/simonw/datasette/issues/2516) | https://github.com/datasette/datasette-create-view/releases/tag/0.1a1 |
| release | 2025-10-21 | datasette-visible-internal-db 0.1.1a1 | - Pin to datasette==1.0a19. [datasette/#2516](https://github.com/simonw/datasette/issues/2516) | https://github.com/datasette/datasette-visible-internal-db/releases/tag/0.1.1a1 |
| release | 2025-10-21 | datasette-events-forward 0.1a2 | - Pin to datasette==1.0a19. [datasette/#2516](https://github.com/simonw/datasette/issues/2516) | https://github.com/datasette/datasette-events-forward/releases/tag/0.1a2 |
| release | 2025-08-12 | llm 0.27.1 | - `llm chat -t template` now correctly loads any tools that are included in that template. [#1239](https://github.com/simonw/llm/issues/1239) - Fixed a bug where `llm -m gpt5 -o reasoning_effort minimal --save gm` saved a template containing invalid YAML. [#1237](https://github.com/simonw/llm/issues/1237) - Fixed a bug where running `llm chat -t template` could cause prompts to be duplicated. [#1240](https://github.com/simonw/llm/issues/1240) - Less confusing error message if a requested toolbox class is unavailable. [#1238](https://github.com/simonw/llm/issues/1238) | https://github.com/simonw/llm/releases/tag/0.27.1 |
| release | 2025-08-11 | llm 0.27 | This release adds support for the new **GPT-5 family** of models from OpenAI. It also enhances tool calling in a number of ways, including allowing [templates](https://llm.datasette.io/en/stable/templates.html#prompt-templates) to bundle pre-configured tools. ### New features - New models: `gpt-5`, `gpt-5-mini` and `gpt-5-nano`. [#1229](https://github.com/simonw/llm/issues/1229) - LLM [templates](https://llm.datasette.io/en/stable/templates.html#prompt-templates) can now include a list of tools. These can be named tools from plugins or arbitrary Python function blocks, see [Tools in templates](https://llm.datasette.io/en/stable/templates.html#prompt-templates-tools). [#1009](https://github.com/simonw/llm/issues/1009) - Tools [can now return attachments](https://llm.datasette.io/en/stable/python-api.html#python-api-tools-attachments), for models that support features such as image input. [#1014](https://github.com/simonw/llm/issues/1014) - New methods on the `Toolbox` class: `.add_tool()`, `.prepare()` and `.prepare_async()`, described in [Dynamic toolboxes](https://llm.datasette.io/en/stable/python-api.html#python-api-tools-dynamic). [#1111](https://github.com/simonw/llm/issues/1111) - New `model.conversation(before_call=x, after_call=y)` attributes for registering callback functions to run before and after tool calls. See [tool debugging hooks](https://llm.datasette.io/en/stable/python-api.html#python-api-tools-debug-hooks) for details. [#1088](https://github.com/simonw/llm/issues/1088) - Some model providers can serve different models from the same configured URL - [llm-llama-server](https://github.com/simonw/llm-llama-server) for example. Plugins for these providers can now record the resolved model ID of the model that was used to the LLM logs using the `response.set_resolved_model(model_id)` method. [#1117](https://github.com/simonw/llm/issues/1117) - Raising `llm.CancelToolCall` now only cancels the current tool call, passing an error back to the model and allowing it to continue. [#1148](https:… | https://github.com/simonw/llm/releases/tag/0.27 |
| release | 2025-07-22 | datasette-public 0.3a3 | - Ability to make canned queries public or private. #14 | https://github.com/datasette/datasette-public/releases/tag/0.3a3 |
| release | 2025-05-27 | llm 0.26 | **Tool support** is finally here! This release adds support exposing [tools](https://llm.datasette.io/en/stable/tools.html#tools) to LLMs, previously described in the release notes for [0.26a0](https://llm.datasette.io/en/stable/changelog.html#v0-26-a0) and [0.26a1](https://llm.datasette.io/en/stable/changelog.html#v0-26-a1). Read **[Large Language Models can run tools in your terminal with LLM 0.26](https://simonwillison.net/2025/May/27/llm-tools/)** for a detailed overview of the new features. Also in this release: - Two new [default tools](https://llm.datasette.io/en/stable/tools.html#tools-default): `llm_version()` and `llm_time()`. [#1096](https://github.com/simonw/llm/issues/1096), [#1103](https://github.com/simonw/llm/issues/1103) - Documentation on [how to add tool supports to a model plugin](https://llm.datasette.io/en/stable/plugins/advanced-model-plugins.html#advanced-model-plugins-tools). [#1000](https://github.com/simonw/llm/issues/1000) - Added a [prominent warning](https://llm.datasette.io/en/stable/tools.html#tools-warning) about the risk of prompt injection when using tools. [#1097](https://github.com/simonw/llm/issues/1097) - Switched to using monotonic ULIDs for the response IDs in the logs, fixing some intermittent test failures. [#1099](https://github.com/simonw/llm/issues/1099) - New `tool_instances` table records details of Toolbox instances created while executing a prompt. [#1089](https://github.com/simonw/llm/issues/1089) - `llm.get_key()` is now a [documented utility function](https://llm.datasette.io/en/stable/plugins/plugin-utilities.html#plugin-utilities-get-key). [#1094](https://github.com/simonw/llm/issues/1094) | https://github.com/simonw/llm/releases/tag/0.26 |
| release | 2025-05-26 | llm 0.26a1 | Hopefully the last alpha before a stable release that includes tool support. ### Features * **Plugin-provided tools can now be grouped into "Toolboxes".** * Toolboxes (`llm.Toolbox` classes) allow plugins to expose multiple related tools that share state or configuration, enhancing modularity and reusability (e.g., a `Memory` tool or `Filesystem` tool). ([#1059](https://github.com/simonw/llm/issues/1059), [#1086](https://github.com/simonw/llm/issues/1086)) * **Tool support for `llm chat`.** * The `llm chat` command now accepts `--tool` and `--functions` arguments, allowing interactive chat sessions to use tools. ([#1004](https://github.com/simonw/llm/issues/1004), [#1062](https://github.com/simonw/llm/issues/1062)) * **Tools can now execute asynchronously.** * Models that implement `AsyncModel` can now run tools, including tool functions defined as `async def`. This enables non-blocking tool calls for potentially long-running operations. ([#1063](https://github.com/simonw/llm/issues/1063)) * **`llm chat` now supports adding fragments during a session.** * Use the new `!fragment <id>` command while chatting to insert content from a fragment. Initial fragments can also be passed to `llm chat` using `-f` or `--sf`. Thanks, [Dan Turkel](https://github.com/daturkel). ([#1044](https://github.com/simonw/llm/issues/1044), [#1048](https://github.com/simonw/llm/issues/1048)) * **Filter `llm logs` by tools.** * New `--tool <name>` option to filter logs to show only responses that involved a specific tool (e.g., `--tool simple_eval`). * The `--tools` flag shows all responses that used any tool. ([#1013](https://github.com/simonw/llm/issues/1013), [#1072](https://github.com/simonw/llm/issues/1072)) * **`llm schemas list` can output JSON.** * Added `--json` and `--nl` (newline-delimited JSON) options to `llm schemas list` for programmatic access to saved schema definitions. ([#1070](https://github.com/simonw/llm/issues/1070)) * **Filter `llm similar` re… | https://github.com/simonw/llm/releases/tag/0.26a1 |
| release | 2025-05-14 | llm 0.26a0 | This is the first alpha to introduce [support for tools](https://llm.datasette.io/en/latest/tools.html#tools)! Models with tool capability (which includes the default OpenAI model family) can now be granted access to execute Python functions as part of responding to a prompt. Tools are supported by [the command-line interface](https://llm.datasette.io/en/latest/usage.html#usage-tools): ```bash llm --functions ' def multiply(x: int, y: int) -> int: """Multiply two numbers.""" return x * y ' 'what is 34234 * 213345' ``` And in [the Python API](https://llm.datasette.io/en/latest/python-api.html#python-api-tools), using a new `model.chain()` method for executing multiple prompts in a sequence: ```python import llm def multiply(x: int, y: int) -> int: """Multiply two numbers.""" return x * y model = llm.get_model("gpt-4.1-mini") response = model.chain( "What is 34234 * 213345?", tools=[multiply] ) print(response.text()) ``` New tools can also be defined using the [register_tools() plugin hook](https://llm.datasette.io/en/latest/plugins/plugin-hooks.html#plugin-hooks-register-tools). They can then be called by name from the command-line like this: ```bash llm -T multiply 'What is 34234 * 213345?' ``` Tool support is currently under **active development**. Consult [this milestone](https://github.com/simonw/llm/milestone/12) for the latest status. | https://github.com/simonw/llm/releases/tag/0.26a0 |
| release | 2025-05-13 | datasette-chronicle 0.3 | - New trigger design, using [sqlite-chronicle 0.4](https://github.com/simonw/sqlite-chronicle/releases/tag/0.4). #4 - Existing chronicle tables are automatically upgraded to the new design, maintaining version and timestamp data. - Now uses the text "Enable row version tracking for this table" in the UI. #5 | https://github.com/datasette/datasette-chronicle/releases/tag/0.3 |
| release | 2025-05-09 | sqlite-utils 4.0a0 | - Upsert operations now use SQLite's `INSERT ... ON CONFLICT SET` syntax on all SQLite versions later than 3.23.1. This is a very slight breaking change for apps that depend on the previous `INSERT OR IGNORE` followed by `UPDATE` behavior. ([#652](https://github.com/simonw/sqlite-utils/issues/652)) - Python library users can opt-in to the previous implementation by passing `use_old_upsert=True` to the `Database()` constructor, see [Alternative upserts using INSERT OR IGNORE](https://sqlite-utils.datasette.io/en/latest/python-api.html#python-api-old-upsert). - Dropped support for Python 3.8, added support for Python 3.13. ([#646](https://github.com/simonw/sqlite-utils/issues/646)) - `sqlite-utils tui` is now provided by the [sqlite-utils-tui](https://github.com/simonw/sqlite-utils-tui) plugin. ([#648](https://github.com/simonw/sqlite-utils/issues/648)) - Test suite now also runs against SQLite 3.23.1, the last version (from 2018-04-10) before the new `INSERT ... ON CONFLICT SET` syntax was added. ([#654](https://github.com/simonw/sqlite-utils/issues/654)) | https://github.com/simonw/sqlite-utils/releases/tag/4.0a0 |
| release | 2025-05-05 | llm 0.25 | - New plugin feature: [register_fragment_loaders(register)](https://llm.datasette.io/en/stable/plugins/plugin-hooks.html#plugin-hooks-register-fragment-loaders) plugins can now return a mixture of fragments and attachments. The [llm-video-frames](https://github.com/simonw/llm-video-frames) plugin is the first to take advantage of this mechanism. [#972](https://github.com/simonw/llm/issues/972) - New OpenAI models: `gpt-4.1`, `gpt-4.1-mini`, `gpt-41-nano`, `o3`, `o4-mini`. [#945](https://github.com/simonw/llm/issues/945), [#965](https://github.com/simonw/llm/issues/965), [#976](https://github.com/simonw/llm/issues/976). - New environment variables: `LLM_MODEL` and `LLM_EMBEDDING_MODEL` for setting the model to use without needing to specify `-m model_id` every time. [#932](https://github.com/simonw/llm/issues/932) - New command: `llm fragments loaders`, to list all currently available fragment loader prefixes provided by plugins. [#941](https://github.com/simonw/llm/issues/941) - `llm fragments` command now shows fragments ordered by the date they were first used. [#973](https://github.com/simonw/llm/issues/973) - `llm chat` now includes a `!edit` command for editing a prompt using your default terminal text editor. Thanks, [Benedikt Willi](https://github.com/Hopiu). [#969](https://github.com/simonw/llm/pull/969) - Allow `-t` and `--system` to be used at the same time. [#916](https://github.com/simonw/llm/issues/916) - Fixed a bug where accessing a model via its alias would fail to respect any default options set for that model. [#968](https://github.com/simonw/llm/issues/968) - Improved documentation for [extra-openai-models.yaml](https://llm.datasette.io/en/stable/other-models.html#openai-compatible-models). Thanks, [Rahim Nathwani](https://github.com/rahimnathwani) and [Dan Guido](https://github.com/dguido). [#950](https://github.com/simonw/llm/pull/950), [#957](https://github.com/simonw/llm/pull/957) - `llm -c/--continue` now works correctly with the `-d/--database` option. `llm chat` now accepts that… | https://github.com/simonw/llm/releases/tag/0.25 |
| release | 2025-05-05 | sqlite-diffable 0.6 | - New feature: `--all --exclude name_of_table` lets you import all tables but exclude one or more by name. Thanks, [giuli007](https://github.com/giuli007). #11 - Migrated from `setup.py` to `pyproject.toml`. | https://github.com/simonw/sqlite-diffable/releases/tag/0.6 |
| release | 2025-05-05 | datasette-enrichments 0.5.1 | - Fixed error about a missing table on server startup for some environments. #58 | https://github.com/datasette/datasette-enrichments/releases/tag/0.5.1 |
| release | 2025-05-01 | datasette-query-assistant 0.1a3 | - Now depends on [LLM](https://llm.datasette.io/) to support multiple models, not just Anthropic. #13 | https://github.com/datasette/datasette-query-assistant/releases/tag/0.1a3 |
| release | 2025-04-22 | datasette 1.0a19 | - Tiny cosmetic bug fix for mobile display of table rows. [#2479](https://github.com/simonw/datasette/issues/2479) | https://github.com/simonw/datasette/releases/tag/1.0a19 |
| release | 2025-04-21 | datasette-comments 0.1.1.a2 | - Update plugin to work with latest Datasette 1.0 alpha - Various UI improvements for comment icon on table view, bug fixes | https://github.com/datasette/datasette-comments/releases/tag/0.1.1.a2 |
| release | 2025-04-17 | datasette 1.0a18 | - Fix for incorrect foreign key references in the internal database schema. [#2466](https://github.com/simonw/datasette/issues/2466) - The ``prepare_connection()`` hook no longer runs for the internal database. [#2468](https://github.com/simonw/datasette/issues/2468) - Fixed bug where ``link:`` HTTP headers used invalid syntax. [#2470](https://github.com/simonw/datasette/issues/2470) - No longer tested against Python 3.8. Now tests against Python 3.13. - FTS tables are now hidden by default if they correspond to a content table. [#2477](https://github.com/simonw/datasette/issues/2477) - Fixed bug with foreign key links to rows in databases with filenames containing a special character. Thanks, [Jack Stratton](https://github.com/phroa). [#2476](https://github.com/simonw/datasette/pull/2476) | https://github.com/simonw/datasette/releases/tag/1.0a18 |
| release | 2025-04-17 | datasette-extract 0.1a10 | - Fixed bugs with floating point columns. #34 - Now strips unicode null characters entirely (GPT-4.1-mini returned these for an image). #35 | https://github.com/datasette/datasette-extract/releases/tag/0.1a10 |
| release | 2025-04-16 | datasette-extract 0.1a9 | - Now depends on [LLM](https://llm.datasette.io/) and supports any model that has both async and schema support. You can also limit it to a subset of models using the new `plugins.datasette-extract.models` configuration list. [#27](https://github.com/datasette/datasette-extract/issues/27) | https://github.com/datasette/datasette-extract/releases/tag/0.1a9 |
| release | 2025-04-11 | llm 0.25a0 | - `llm models --options` now shows keys and environment variables for models that use API keys. Thanks, [Steve Morin](https://github.com/smorin). [#903](https://github.com/simonw/llm/issues/903) - Added `py.typed` marker file so LLM can now be used as a dependency in projects that use `mypy` without a warning. [#887](https://github.com/simonw/llm/issues/887) - `$` characters can now be used in templates by escaping them as `$$`. Thanks, [@guspix](https://github.com/guspix). [#904](https://github.com/simonw/llm/issues/904) - LLM now uses `pyproject.toml` instead of `setup.py`. [#908](https://github.com/simonw/llm/issues/908) | https://github.com/simonw/llm/releases/tag/0.25a0 |
| release | 2025-04-10 | csvs-to-sqlite 1.3.1 | - Upgraded for compatibility with recent Pandas and Click libraries. Thanks, [Luighi Viton-Zorrilla](https://github.com/LuighiV). #99 | https://github.com/simonw/csvs-to-sqlite/releases/tag/1.3.1 |
| release | 2025-04-09 | llm 0.24.2 | - Fixed a bug on Windows with the new `llm -t path/to/file.yaml` feature. [#901](https://github.com/simonw/llm/issues/901) | https://github.com/simonw/llm/releases/tag/0.24.2 |
| release | 2025-04-08 | llm 0.24.1 | - Templates can now be specified as a path to a file on disk, using `llm -t path/to/file.yaml`. This makes them consistent with how `-f` fragments are loaded. [#897](https://github.com/simonw/llm/issues/897) - `llm logs backup /tmp/backup.db` command for [backing up your](https://llm.datasette.io/en/stable/logging.html#backing-up-your-database) `logs.db` database. [#879](https://github.com/simonw/llm/issues/879) | https://github.com/simonw/llm/releases/tag/0.24.1 |
| release | 2025-04-07 | llm 0.24a1 | - New Fragments feature. [#617](https://github.com/simonw/llm/issues/617) - `register_fragment_loaders()` plugin hook. [#809](https://github.com/simonw/llm/issues/886) | https://github.com/simonw/llm/releases/tag/0.24a1 |
| release | 2025-04-07 | llm 0.24 | Support for **fragments** to help assemble prompts for long context models. Improved support for **templates** to support attachments and fragments. New plugin hooks for providing custom loaders for both templates and fragments. See [Long context support in LLM 0.24 using fragments and template plugins](https://simonwillison.net/2025/Apr/7/long-context-llm/) for more on this release. The new [llm-docs](https://github.com/simonw/llm-docs) plugin demonstrates these new features. Install it like this: ```bash llm install llm-docs ``` Now you can ask questions of the LLM documentation like this: ```bash llm -f docs: 'How do I save a new template?' ``` The `docs:` prefix is registered by the plugin. The plugin fetches the LLM documentation for your installed version (from the [docs-for-llms](https://github.com/simonw/docs-for-llms) repository) and uses that as a prompt fragment to help answer your question. Two more new plugins are [llm-templates-github](https://github.com/simonw/llm-templates-github) and [llm-templates-fabric](https://github.com/simonw/llm-templates-fabric). `llm-templates-github` lets you share and use templates on GitHub. You can run my [Pelican riding a bicycle](https://simonwillison.net/tags/pelican-riding-a-bicycle/) benchmark against a model like this: ```bash llm install llm-templates-github llm -t gh:simonw/pelican-svg -m o3-mini ``` This executes [this pelican-svg.yaml](https://github.com/simonw/llm-templates/blob/main/pelican-svg.yaml) template stored in my [simonw/llm-templates](https://github.com/simonw/llm-templates) repository, using a new repository naming convention. To share your own templates, create a repository on GitHub under your user account called `llm-templates` and start saving `.yaml` files to it. [llm-templates-fabric](https://github.com/simonw/llm-templates-fabric) provides a similar mechanism for loading templates from Daniel Miessler's [fabric collection](https://github.com/danielmiessler/fabric): ```bash llm install llm-templates-… | https://github.com/simonw/llm/releases/tag/0.24 |
| release | 2025-03-28 | datasette-auth-existing-cookies 1.0a2 | - Fix some warnings. - Drop support for Python versions prior to 3.9. | https://github.com/simonw/datasette-auth-existing-cookies/releases/tag/1.0a2 |
| release | 2025-03-25 | shot-scraper 1.8 | - `shot-scraper javascript` can now optionally [load scripts hosted on GitHub](https://shot-scraper.datasette.io/en/stable/javascript.html#running-javascript-from-github) via the new `gh:` prefix to the `shot-scraper javascript -i/--input` option. #173 Scripts can be referenced as `gh:username/repo/path/to/script.js` or, if the GitHub user has created a dedicated `shot-scraper-scripts` repository and placed scripts in the root of it, using `gh:username/name-of-script`. For example, to run this [readability.js](https://github.com/simonw/shot-scraper-scripts/blob/main/readability.js) script against any web page you can use the following: ```bash shot-scraper javascript -i gh:simonw/readability \ https://simonwillison.net/2025/Mar/24/qwen25-vl-32b/ ``` | https://github.com/simonw/shot-scraper/releases/tag/1.8 |
| release | 2025-03-20 | datasette-public 0.3a2 | - Fix for compatibility with `datasette-extract`. #13 | https://github.com/datasette/datasette-public/releases/tag/0.3a2 |
| release | 2025-03-01 | llm 0.24a0 | - Alpha release with experimental `register_template_loaders()` plugin hook. [#809](https://github.com/simonw/llm/issues/809) | https://github.com/simonw/llm/releases/tag/0.24a0 |
| release | 2025-02-28 | llm 0.23 | Support for **schemas**, for getting supported models to output JSON that matches a specified JSON schema. See also [Structured data extraction from unstructured content using LLM schemas](https://simonwillison.net/2025/Feb/28/llm-schemas/) for background on this feature. [#776](https://github.com/simonw/llm/issues/776) - New `llm prompt --schema '{JSON schema goes here}` option for specifying a schema that should be used for the output from the model. The [schemas documentation](https://llm.datasette.io/en/stable/schemas.html#schemas) has more details and a tutorial. - Schemas can also be defined using a [concise schema specification](https://llm.datasette.io/en/stable/schemas.html#schemas-dsl), for example `llm prompt --schema 'name, bio, age int'`. [#790](https://github.com/simonw/llm/issues/790) - Schemas can also be specified by passing a filename and through [several other methods](https://llm.datasette.io/en/stable/schemas.html#schemas-specify). [#780](https://github.com/simonw/llm/issues/780) - New [llm schemas family of commands](https://llm.datasette.io/en/stable/help.html#help-schemas): `llm schemas list`, `llm schemas show`, and `llm schemas dsl` for debugging the new concise schema language. [#781](https://github.com/simonw/llm/issues/781) - Schemas can now be saved to templates using `llm --schema X --save template-name` or through modifying the [template YAML](https://llm.datasette.io/en/stable/templates.html#prompt-templates-yaml). [#778](https://github.com/simonw/llm/issues/778) - The [llm logs](https://llm.datasette.io/en/stable/logging.html#logging) command now has new options for extracting data collected using schemas: `--data`, `--data-key`, `--data-array`, `--data-ids`. [#782](https://github.com/simonw/llm/issues/782) - New `llm logs --id-gt X` and `--id-gte X` options. [#801](https://github.com/simonw/llm/issues/801) - New `llm models --schemas` option for listing models that support schemas. [#797](https://github.com/simonw/llm/issues/797) - `model.prompt(..., schema={...})` pa… | https://github.com/simonw/llm/releases/tag/0.23 |
| release | 2025-02-28 | strip-tags 0.6 | - Fixed a bug where `strip-tags -t meta` still removed `<meta>` tags from the `<head>` because the entire `<head>` element was removed first. #32 - Kept `<meta>` tags now default to keeping their `content` and `property` attributes. - The CLI `-m/--minify` option now also removes any remaining blank lines. #33 - A new `strip_tags(remove_blank_lines=True)` option can be used to achieve the same thing with the Python library function. | https://github.com/simonw/strip-tags/releases/tag/0.6 |
| release | 2025-02-27 | llm 0.23a0 | Alpha release adding support for **schemas**, for getting supported models to output JSON that matches a specified JSON schema. [#776](https://github.com/simonw/llm/issues/776) - `llm prompt --schema '{JSON schema goes here}` option for specifying a schema that should be used for the output from the model, see [schemas in the CLI docs](https://llm.datasette.io/en/latest/usage.html#usage-schemas). - `model.prompt(..., schema={...})` parameter for specifying a schema from Python. This accepts either a dictionary JSON schema definition of a Pydantic `BaseModel` subclass, see [schemas in the Python API docs](https://llm.datasette.io/en/latest/python-api.html#python-api-schemas). - The default OpenAI plugin now supports schemas across all models. - Documentation on how to [add schema support to a model plugin](https://llm.datasette.io/en/latest/plugins/advanced-model-plugins.html#advanced-model-plugins-schemas). - LLM now depends on Pydantic v2 or higher. Pydantic v1 is no longer supported. [#520](https://github.com/simonw/llm/issues/520) | https://github.com/simonw/llm/releases/tag/0.23a0 |
| release | 2025-02-20 | shot-scraper 1.7 | - New options for the `shot-scraper har` command: `--wait`, `--wait-for` and `--javascript` - similar to those same options on `shot-scraper shot`. #171 - Documentation now recommends using `shot-scraper multi --har-zip` for larger collections of files to avoid a Playwright crash if the `.har` JSON grows too large. #170 | https://github.com/simonw/shot-scraper/releases/tag/1.7 |
| release | 2025-02-17 | llm 0.22 | See also [LLM 0.22, the annotated release notes](https://simonwillison.net/2025/Feb/17/llm/). - Plugins that provide models that use API keys can now subclass the new `llm.KeyModel` and `llm.AsyncKeyModel` classes. This results in the API key being passed as a new `key` parameter to their `.execute()` methods, and means that Python users can pass a key as the `model.prompt(..., key=)` - see [Passing an API key](https://llm.datasette.io/en/stable/python-api.html#python-api-models-api-keys). Plugin developers should consult the new documentation on writing [Models that accept API keys](https://llm.datasette.io/en/stable/plugins/advanced-model-plugins.html#advanced-model-plugins-api-keys). [#744](https://github.com/simonw/llm/issues/744) - New OpenAI model: `chatgpt-4o-latest`. This model ID accesses the current model being used to power ChatGPT, which can change without warning. [#752](https://github.com/simonw/llm/issues/752) - New `llm logs -s/--short` flag, which returns a greatly shortened version of the matching log entries in YAML format with a truncated prompt and without including the response. [#737](https://github.com/simonw/llm/issues/737) - Both `llm models` and `llm embed-models` now take multiple `-q` search fragments. You can now search for all models matching "gemini" and "exp" using `llm models -q gemini -q exp`. [#748](https://github.com/simonw/llm/issues/748) - New `llm embed-multi --prepend X` option for prepending a string to each value before it is embedded - useful for models such as [nomic-embed-text-v2-moe](https://huggingface.co/nomic-ai/nomic-embed-text-v2-moe) that require passages to start with a string like `"search_document: "`. [#745](https://github.com/simonw/llm/issues/745) - The `response.json()` and `response.usage()` methods are [now documented](https://llm.datasette.io/en/stable/python-api.html#python-api-underlying-json). - Fixed a bug where conversations that were loaded from the database could not be continued using `asyncio` prompts. [#742](https://github.com/simon… | https://github.com/simonw/llm/releases/tag/0.22 |
| release | 2025-02-14 | datasette-public 0.3a1 | - Changes are now recorded to a `public_audit_log` table, which is visible on the table and database permission editing pages. [#11](https://github.com/datasette/datasette-public/issues/11) | https://github.com/datasette/datasette-public/releases/tag/0.3a1 |
| release | 2025-02-13 | shot-scraper 1.6 | - New `shot-scraper har URL` command for [creating an HTML Archive](https://shot-scraper.datasette.io/en/stable/har.html) of a page. #146 - `shot-scraper multi --har` and `--har-zip` and `--har-file` options for [creating an HTML Archive of multiple pages](https://shot-scraper.datasette.io/en/stable/multi.html#multi-har). #166 - `shot-scraper pdf` now has `--wait-for` and `--timeout` options. Thanks, [miccou](https://github.com/miccou). #161 | https://github.com/simonw/shot-scraper/releases/tag/1.6 |
| news | 2025-02-06 | [Datasette 1.0a17](https://docs.datasette.io/en/latest/changelog.html#a17-2025-02-06) is the latest Datasette 1.0 alpha release, with bug fixes and small feature improvements from the last few months. | https://datasette.io/news/2025-02-06 | |
| release | 2025-02-06 | datasette 1.0a17 | - `DATASETTE_SSL_KEYFILE` and `DATASETTE_SSL_CERTFILE` environment variables as alternatives to `--ssl-keyfile` and `--ssl-certfile`. Thanks, Alex Garcia. ([#2422](https://github.com/simonw/datasette/issues/2422)) - `SQLITE_EXTENSIONS` environment variable has been renamed to `DATASETTE_LOAD_EXTENSION`. ([#2424](https://github.com/simonw/datasette/issues/2424)) - `datasette serve` environment variables are now [documented here](https://docs.datasette.io/en/latest/cli-reference.html#cli-datasette-serve-env). - The [register_magic_parameters(datasette)](https://docs.datasette.io/en/latest/plugin_hooks.html#plugin-hook-register-magic-parameters) plugin hook can now register async functions. ([#2441](https://github.com/simonw/datasette/issues/2441)) - Datasette is now tested against Python 3.13. - Breadcrumbs on database and table pages now include a consistent self-link for resetting query string parameters. ([#2454](https://github.com/simonw/datasette/issues/2454)) - Fixed issue where Datasette could crash on `metadata.json` with nested values. ([#2455](https://github.com/simonw/datasette/issues/2455)) - New internal methods `datasette.set_actor_cookie()` and `datasette.delete_actor_cookie()`, [described here](https://docs.datasette.io/en/latest/authentication.html#authentication-ds-actor). ([#1690](https://github.com/simonw/datasette/issues/1690)) - `/-/permissions` page now shows a list of all permissions registered by plugins. ([#1943](https://github.com/simonw/datasette/issues/1943)) - If a table has a single unique text column Datasette now detects that as the foreign key label for that table. ([#2458](https://github.com/simonw/datasette/issues/2458)) - The `/-/permissions` page now includes options for filtering or exclude permission checks recorded against the current user. ([#2460](https://github.com/simonw/datasette/issues/2460)) - Fixed a bug where replacing a database with a new one with the same name did not pick up the new database correctly. ([#2465](https://github.com/simonw/datasette/issu… | https://github.com/simonw/datasette/releases/tag/1.0a17 |
| release | 2025-02-06 | datasette-public 0.3a0 | - Added the ability to make full databases public, including setting if users can execute SQL or not. [#9](https://github.com/datasette/datasette-public/issues/9) - Now depends on Datasette 1.0a and uses the new `internal` database. [#6](https://github.com/datasette/datasette-public/issues/6) | https://github.com/datasette/datasette-public/releases/tag/0.3a0 |
| release | 2025-01-31 | llm 0.21 | - New model: `o3-mini`. [#728](https://github.com/simonw/llm/issues/728) - The `o3-mini` and `o1` models now support a `reasoning_effort` option which can be set to `low`, `medium` or `high`. - `llm prompt` and `llm logs` now have a `--xl/--extract-last` option for extracting the last fenced code block in the response - a complement to the existing `--x/--extract` option. [#717](https://github.com/simonw/llm/issues/717) | https://github.com/simonw/llm/releases/tag/0.21 |
| release | 2025-01-23 | llm 0.20 | - New model, `o1`. This model does not yet support streaming. [#676](https://github.com/simonw/llm/issues/676) - `o1-preview` and `o1-mini` models now support streaming. - New models, `gpt-4o-audio-preview` and `gpt-4o-mini-audio-preview`. [#677](https://github.com/simonw/llm/issues/677) - `llm prompt -x/--extract` option, which returns just the content of the first fenced code block in the response. Try `llm prompt -x 'Python function to reverse a string'`. [#681](https://github.com/simonw/llm/issues/681) - Creating a template using `llm ... --save x` now supports the `-x/--extract` option, which is saved to the template. YAML templates can set this option using `extract: true`. - New `llm logs -x/--extract` option extracts the first fenced code block from matching logged responses. - New `llm models -q 'search'` option returning models that case-insensitively match the search query. [#700](https://github.com/simonw/llm/issues/700) - Installation documentation now also includes `uv`. Thanks, [Ariel Marcus](https://github.com/ajmarcus). [#690](https://github.com/simonw/llm/pull/690) and [#702](https://github.com/simonw/llm/issues/702) - `llm models` command now shows the current default model at the bottom of the listing. Thanks, [Amjith Ramanujam](https://github.com/amjith). [#688](https://github.com/simonw/llm/pull/688) - [Plugin directory](https://llm.datasette.io/en/stable/plugins/directory.html) now includes `llm-venice`, `llm-bedrock`, `llm-deepseek` and `llm-cmd-comp`. - Fixed bug where some dependency version combinations could cause a `Client.__init__() got an unexpected keyword argument 'proxies'` error. [#709](https://github.com/simonw/llm/issues/709) - OpenAI embedding models are now available using their full names of `text-embedding-ada-002`, `text-embedding-3-small` and `text-embedding-3-large` - the previous names are still supported as aliases. Thanks, [web-sst](https://github.com/web-sst). [#654](https://github.com/simonw/llm/pull/654) | https://github.com/simonw/llm/releases/tag/0.20 |
| release | 2025-01-15 | datasette-enrichments 0.5a1 | - Pause, resume, cancel buttons for jobs. [#17](https://github.com/datasette/datasette-enrichments/issues/17) - Enrichments can raise `self.Pause("message")` or `self.Cancel("message")` exceptions inside their `enrich_batch()` methods. [#56](https://github.com/datasette/datasette-enrichments/issues/56) | https://github.com/datasette/datasette-enrichments/releases/tag/0.5a1 |
| release | 2025-01-15 | datasette-enrichments 0.5 | - UI for viewing status of enrichment jobs. [#51](https://github.com/datasette/datasette-enrichments/issues/51) - Pause, resume and cancel buttons. [#17](https://github.com/datasette/datasette-enrichments/issues/17) - Visible progress bar on table with running enrichments. [#52](https://github.com/datasette/datasette-enrichments/issues/52) - Table and database action menu items for viewing enrichment runs. [#53](https://github.com/datasette/datasette-enrichments/issues/53) - Enrichments continue running after a server restart. [#54](https://github.com/datasette/datasette-enrichments/issues/54) - An `enrichment` permission is now correctly registered with Datasette 1.0a+. [#55](https://github.com/datasette/datasette-enrichments/issues/55) - Enrichments can pause or cancel themselves by raising the new `self.Pause(reason)` and `self.Cancel(reason)` exceptions. [#56](https://github.com/datasette/datasette-enrichments/issues/56) | https://github.com/datasette/datasette-enrichments/releases/tag/0.5 |
| release | 2025-01-14 | datasette-write-ui 0.0.1a12 | https://github.com/datasette/datasette-write-ui/releases/tag/0.0.1a12 | |
| release | 2025-01-14 | datasette-enrichments 0.5a0 | - New `/-/enrich/databasename/-/jobs` listing page `/-/enrich/databasename/-/jobs/123` detail page. [#51](https://github.com/datasette/datasette-enrichments/issues/51) - Visible progress bar on tables that have enrichments running. [#52](https://github.com/datasette/datasette-enrichments/issues/52) - Table and database action menu items to view previous runs. [#53](https://github.com/datasette/datasette-enrichments/issues/53) - Continue any enrichment runs after a server restart. [#54](https://github.com/datasette/datasette-enrichments/issues/54) | https://github.com/datasette/datasette-enrichments/releases/tag/0.5a0 |
| release | 2024-12-05 | llm 0.19.1 | - FIxed bug where `llm.get_models()` and `llm.get_async_models()` returned the same model multiple times. [#667](https://github.com/simonw/llm/issues/667) | https://github.com/simonw/llm/releases/tag/0.19.1 |
| release | 2024-12-01 | llm 0.19 | - Tokens used by a response are now logged to new `input_tokens` and `output_tokens` integer columns and a `token_details` JSON string column, for the default OpenAI models and models from other plugins that [implement this feature](https://llm.datasette.io/en/stable/plugins/advanced-model-plugins.html#advanced-model-plugins-usage). [#610](https://github.com/simonw/llm/issues/610) - `llm prompt` now takes a `-u/--usage` flag to display token usage at the end of the response. - `llm logs -u/--usage` shows token usage information for logged responses. - `llm prompt ... --async` responses are now logged to the database. [#641](https://github.com/simonw/llm/issues/641) - `llm.get_models()` and `llm.get_async_models()` functions, [documented here](https://llm.datasette.io/en/stable/python-api.html#python-api-listing-models). [#640](https://github.com/simonw/llm/issues/640) - `response.usage()` and async response `await response.usage()` methods, returning a `Usage(input=2, output=1, details=None)` dataclass. [#644](https://github.com/simonw/llm/issues/644) - `response.on_done(callback)` and `await response.on_done(callback)` methods for specifying a callback to be executed when a response has completed, [documented here](https://llm.datasette.io/en/stable/python-api.html#python-api-response-on-done). [#653](https://github.com/simonw/llm/issues/653) - Fix for bug running `llm chat` on Windows 11. Thanks, [Sukhbinder Singh](https://github.com/sukhbinder). [#495](https://github.com/simonw/llm/issues/495) | https://github.com/simonw/llm/releases/tag/0.19 |
| release | 2024-11-29 | datasette 0.65.1 | - Fixed bug with upgraded HTTPX 0.28.0 dependency. [#2443](https://github.com/simonw/datasette/issues/2443) | https://github.com/simonw/datasette/releases/tag/0.65.1 |
| release | 2024-11-23 | sqlite-utils 3.38 | - Plugins can now reuse the implementation of the `sqlite-utils memory` CLI command with the new `return_db=True` parameter. ([#643](https://github.com/simonw/sqlite-utils/issues/643)) - `table.transform()` now recreates indexes after transforming a table. A new `sqlite_utils.db.TransformError` exception is raised if these indexes cannot be recreated due to conflicting changes to the table such as a column rename. Thanks, [Mat Miller](https://github.com/matdmiller). ([#633](https://github.com/simonw/sqlite-utils/issues/633)) - `table.search()` now accepts a `include_rank=True` parameter, causing the resulting rows to have a `rank` column showing the calculated relevance score. Thanks, [liunux4odoo](https://github.com/liunux4odoo). ([#628](https://github.com/simonw/sqlite-utils/pull/628)) - Fixed an error that occurred when creating a strict table with at least one floating point column. These `FLOAT` columns are now correctly created as `REAL` as well, but only for strict tables. ([#644](https://github.com/simonw/sqlite-utils/issues/644)) | https://github.com/simonw/sqlite-utils/releases/tag/3.38 |
| release | 2024-11-21 | llm 0.19a2 | - `llm.get_models()` and `llm.get_async_models()` functions, [documented here](https://llm.datasette.io/en/latest/python-api.html#python-api-listing-models). [#640](https://github.com/simonw/llm/issues/640) | https://github.com/simonw/llm/releases/tag/0.19a2 |
| release | 2024-11-20 | llm 0.19a0 | - Tokens used by a response are now logged to new `input_tokens` and `output_tokens` integer columns and a `token_details` JSON string column, for the default OpenAI models and models from other plugins that [implement this feature](https://llm.datasette.io/en/latest/plugins/advanced-model-plugins.html#advanced-model-plugins-usage). [#610](https://github.com/simonw/llm/issues/610) - `llm prompt` now takes a `-u/--usage` flag to display token usage at the end of the response. - `llm logs -u/--usage` shows token usage information for logged responses. - `llm prompt ... --async` responses are now logged to the database. [#641](https://github.com/simonw/llm/issues/641) | https://github.com/simonw/llm/releases/tag/0.19a0 |
| release | 2024-11-20 | llm 0.19a1 | - `response.usage()` and async response `await response.usage()` methods, returning a `Usage(input=2, output=1, details=None)` dataclass. [#644](https://github.com/simonw/llm/issues/644) | https://github.com/simonw/llm/releases/tag/0.19a1 |
| release | 2024-11-17 | llm 0.18 | - Initial support for async models. Plugins can now provide an `AsyncModel` subclass that can be accessed in the Python API using the new `llm.get_async_model(model_id)` method. See [async models in the Python API docs](https://llm.datasette.io/en/stable/python-api.html#python-api-async) and [implementing async models in plugins](https://llm.datasette.io/en/stable/plugins/advanced-model-plugins.html#advanced-model-plugins-async). [#507](https://github.com/simonw/llm/issues/507) - OpenAI models all now include async models, so function calls such as `llm.get_async_model("gpt-4o-mini")` will return an async model. - `gpt-4o-audio-preview` model can be used to send audio attachments to the GPT-4o audio model. [#608](https://github.com/simonw/llm/issues/608) - Attachments can now be sent without requiring a prompt. [#611](https://github.com/simonw/llm/issues/611) - `llm models --options` now includes information on whether a model supports attachments. [#612](https://github.com/simonw/llm/issues/612) - `llm models --async` shows available async models. - Custom OpenAI-compatible models can now be marked as `can_stream: false` in the YAML if they do not support streaming. Thanks, [Chris Mungall](https://github.com/cmugall). [#600](https://github.com/simonw/llm/pull/600) - Fixed bug where OpenAI usage data was incorrectly serialized to JSON. [#614](https://github.com/simonw/llm/issues/614) - Standardized on `audio/wav` MIME type for audio attachments rather than `audio/wave`. [#603](https://github.com/simonw/llm/issues/603 | https://github.com/simonw/llm/releases/tag/0.18 |
| release | 2024-11-14 | llm 0.18a0 | Alpha support for **async models**. [#507](https://github.com/simonw/llm/issues/507) Multiple [smaller changes](https://github.com/simonw/llm/compare/0.17.1...0.18a0). | https://github.com/simonw/llm/releases/tag/0.18a0 |
| release | 2024-11-14 | datasette-write-ui 0.0.1a11 | https://github.com/datasette/datasette-write-ui/releases/tag/0.0.1a11 | |
| release | 2024-11-14 | llm 0.18a1 | - Fixed bug where conversations did not work for async OpenAI models. [#632](https://github.com/simonw/llm/issues/632) - `__repr__` methods for `Response` and `AsyncResponse`. | https://github.com/simonw/llm/releases/tag/0.18a1 |
| release | 2024-11-08 | sqlite-utils 3.38a0 | - Plugins can now reuse the `sqlite-utils memory` command with the new `return_db=True` parameter. [#643](https://github.com/simonw/sqlite-utils/issues/643) | https://github.com/simonw/sqlite-utils/releases/tag/3.38a0 |
| release | 2024-11-01 | llm 0.17.1 | - Fixed a bug where `llm chat` crashes if a follow-up prompt is provided. [#601](https://github.com/simonw/llm/issues/601) | https://github.com/simonw/llm/releases/tag/0.17.1 |
| release | 2024-10-29 | llm 0.17 | Support for **attachments**, allowing multi-modal models to accept images, audio, video and other formats. [#587](https://github.com/simonw/llm/issues/587) The default OpenAI `gpt-4o` and `gpt-4o-mini` models can both now be prompted with JPEG, GIF, PNG and WEBP images. Attachments [in the CLI](https://llm.datasette.io/en/stable/usage.html#attachments) can be URLs: ```bash llm -m gpt-4o "describe this image" \ -a https://static.simonwillison.net/static/2024/pelicans.jpg ``` Or file paths: ```bash llm -m gpt-4o-mini "extract text" -a image1.jpg -a image2.jpg ``` Or binary data, which may need to use `--attachment-type` to specify the MIME type: ```bash cat image | llm -m gpt-4o-mini "extract text" --attachment-type - image/jpeg ``` Attachments are also available [in the Python API](https://llm.datasette.io/en/stable/python-api.html#attachments): ```python model = llm.get_model("gpt-4o-mini") response = model.prompt( "Describe these images", attachments=[ llm.Attachment(path="pelican.jpg"), llm.Attachment(url="https://static.simonwillison.net/static/2024/pelicans.jpg"), ] ) ``` Plugins that provide alternative models can support attachments, see [Attachments for multi-modal models](https://llm.datasette.io/en/stable/plugins/advanced-model-plugins.html) for details. The latest **[llm-claude-3](https://github.com/simonw/llm-claude-3)** plugin now supports attachments for Anthropic's Claude 3 and 3.5 models. The **[llm-gemini](https://github.com/simonw/llm-gemini)** plugin supports attachments for Google's Gemini 1.5 models. Also in this release: OpenAI models now record their `"usage"` data in the database even when the response was streamed. These records can be viewed using `llm logs --json`. [#591](https://github.com/simonw/llm/issues/591) | https://github.com/simonw/llm/releases/tag/0.17 |
| release | 2024-10-28 | llm 0.17a0 | Alpha support for **attachments**, allowing multi-modal models to accept images, audio, video and other formats. [#578](https://github.com/simonw/llm/issues/578) Attachments [in the CLI](https://llm.datasette.io/en/latest/usage.html#usage-attachments) can be URLs: ```bash llm "describe this image" \ -a https://static.simonwillison.net/static/2024/pelicans.jpg ``` Or file paths: ```bash llm "extract text" -a image1.jpg -a image2.jpg ``` Or binary data, which may need to use `--attachment-type` to specify the MIME type: ```bash cat image | llm "extract text" --attachment-type - image/jpeg ``` Attachments are also available [in the Python API](https://llm.datasette.io/en/latest/python-api.html#python-api-attachments): ```python model = llm.get_model("gpt-4o-mini") response = model.prompt( "Describe these images", attachments=[ llm.Attachment(path="pelican.jpg"), llm.Attachment(url="https://static.simonwillison.net/static/2024/pelicans.jpg"), ] ) ``` Plugins that provide alternative models can support attachments, see [Attachments for multi-modal models](https://llm.datasette.io/en/latest/plugins/advanced-model-plugins.html#advanced-model-plugins-attachments) for details. | https://github.com/simonw/llm/releases/tag/0.17a0 |
| news | 2024-10-07 | [Python 3.13](https://docs.python.org/3.13/whatsnew/3.13.html) was released today. [Datasette 1.0a16](https://docs.datasette.io/en/latest/changelog.html#a16-2024-09-05) is compatible with Python 3.13, but Datasette 0.64.8 was not. The new [Datasette 0.65](https://docs.datasette.io/en/stable/changelog.html#v0-65) release fixes compatibility with the new version of Python. | https://datasette.io/news/2024-10-07 | |
| release | 2024-10-07 | datasette 0.65 | - Upgrade for compatibility with Python 3.13 (by vendoring Pint dependency). ([#2434](https://github.com/simonw/datasette/issues/2434)) - Dropped support for Python 3.8. | https://github.com/simonw/datasette/releases/tag/0.65 |
| release | 2024-09-27 | shot-scraper 1.5 | - Several new features for the YAML configuration used by [shot-scraper multi](https://shot-scraper.datasette.io/en/stable/multi.html): - You can now add a `- server: python -m http.server 8003` block to [start a server running](https://shot-scraper.datasette.io/en/stable/multi.html#running-a-server-for-the-duration-of-the-session) before screenshots are taken. The PID for this server will be recorded and the server automatically terminated when the command completes, unless you specify the `--leave-server` option in which case it will be left running, useful for debugging. #156 - The `sh: shell command` or `python: python code` blocks can [specify Python or shell commands](https://shot-scraper.datasette.io/en/stable/multi.html#running-custom-code-between-steps) to run before a screenshot is taken. This means a YAML script can make modifications to the environment in between screenshots, useful for things like progressive tutorials. #155 - Fixed a bug that occurred if a `max-width` was accidentally applied to the `<div>` used for region screenshots. Thanks, [Johann Klähn](https://github.com/kljohann). #143 - Documented that `shot-scraper` will quit with an error if a `--wait-for` expression has not resolved in 30s. | https://github.com/simonw/shot-scraper/releases/tag/1.5 |
| release | 2024-09-12 | llm 0.16 | - OpenAI models now use the internal `self.get_key()` mechanism, which means they can be used from Python code in a way that will pick up keys that have been configured using `llm keys set` or the `OPENAI_API_KEY` environment variable. [#552](https://github.com/simonw/llm/issues/552). This code now works correctly: ```python import llm print(llm.get_model("gpt-4o-mini").prompt("hi")) ``` - New documented API methods: `llm.get_default_model()`, `llm.set_default_model(alias)`, `llm.get_default_embedding_model(alias)`, `llm.set_default_embedding_model()`. [#553](https://github.com/simonw/llm/issues/553) - Support for OpenAI's new [o1 family](https://openai.com/o1/) of preview models, `llm -m o1-preview "prompt"` and `llm -m o1-mini "prompt"`. These models are currently only available to [tier 5](https://platform.openai.com/docs/guides/rate-limits/usage-tiers?context=tier-five) OpenAI API users, though this may change in the future. [#570](https://github.com/simonw/llm/issues/570) | https://github.com/simonw/llm/releases/tag/0.16 |
| release | 2024-09-06 | datasette-search-all 1.1.4 | - More CSS compatibility with future Datasette alpha releases. [#21](https://github.com/simonw/datasette-search-all/issues/21) | https://github.com/simonw/datasette-search-all/releases/tag/1.1.4 |
| release | 2024-09-06 | datasette 1.0a16 | This release focuses on performance, in particular against large tables, and introduces some minor breaking changes for CSS styling in Datasette plugins. - Removed the unit conversions feature and its dependency, Pint. This means Datasette is now compatible with the upcoming Python 3.13. ([#2400](https://github.com/simonw/datasette/issues/2400), [#2320](https://github.com/simonw/datasette/issues/2320)) - The `datasette --pdb` option now uses the [ipdb](https://github.com/gotcha/ipdb) debugger if it is installed. You can install it using `datasette install ipdb`. Thanks, [Tiago Ilieve](https://github.com/myhro). ([#2342](https://github.com/simonw/datasette/pull/2342)) - Fixed a confusing error that occurred if `metadata.json` contained nested objects. ([#2403](https://github.com/simonw/datasette/issues/2403)) - Fixed a bug with `?_trace=1` where it returned a blank page if the response was larger than 256KB. ([#2404](https://github.com/simonw/datasette/issues/2404)) - Tracing mechanism now also displays SQL queries that returned errors or ran out of time. [datasette-pretty-traces 0.5](https://github.com/simonw/datasette-pretty-traces/releases/tag/0.5) includes support for displaying this new type of trace. ([#2405](https://github.com/simonw/datasette/issues/2405)) - Fixed a text spacing with table descriptions on the homepage. ([#2399](https://github.com/simonw/datasette/issues/2399)) - Performance improvements for large tables: - Suggested facets now only consider the first 1000 rows. ([#2406](https://github.com/simonw/datasette/issues/2406)) - Improved performance of date facet suggestion against large tables. ([#2407](https://github.com/simonw/datasette/issues/2407)) - Row counts stop at 10,000 rows when listing tables. ([#2398](https://github.com/simonw/datasette/issues/2398)) - On table page the count stops at 10,000 rows too, with a "count all" button to execute the full count. ([#2408](https://github.com/simonw/datasette/issues/2408)) - New `.dicts()` internal method on [Results]… | https://github.com/simonw/datasette/releases/tag/1.0a16 |
| release | 2024-09-06 | csv-diff 1.2 | - New feature: `--extra key "python format string"`, for adding additional output keys to the human-readable version of the diff. [#38](https://github.com/simonw/csv-diff/issues/38) - Don't crash in JSON format mode if some JSON keys are missing. [#13](https://github.com/simonw/csv-diff/issues/13) - Now includes a `Dockerfile` and instructions for building and running it that way. Thanks, [@gourk](https://github.com/gourk). [#11](https://github.com/simonw/csv-diff/issues/11) | https://github.com/simonw/csv-diff/releases/tag/1.2 |
| release | 2024-09-04 | datasette-write 0.4 | - Database write page URLs are now `/db/-/write`, the old `/-/write?database=db` page redirects to the new location. [#12](https://github.com/simonw/datasette-write/issues/12) - Removed the application menu item so as not to duplicate the database action item. - New row action menu item (on Datasette 1.0a13 and higher) linking to a SQL query to edit the current values of that row. [#10](https://github.com/simonw/datasette-write/issues/10) - Fixed CSS for compatibility with upcoming Datasette 1.0 alpha. [datasette#2417](https://github.com/simonw/datasette/issues/2417) | https://github.com/simonw/datasette-write/releases/tag/0.4 |
| release | 2024-09-04 | datasette-search-all 1.1.3 | - Now skips tables ending in `_fts` to avoid duplicate search results in most recent Datasette alphas. - Fixed CSS for compatibility with upcoming Datasette 1.0 alpha. [#20](https://github.com/simonw/datasette-search-all/issues/20), [datasette#2417](https://github.com/simonw/datasette/issues/2417) | https://github.com/simonw/datasette-search-all/releases/tag/1.1.3 |
| release | 2024-09-04 | datasette-import 0.1a5 | - Fixed CSS for compatibility with upcoming Datasette 1.0 alpha. [datasette#2417](https://github.com/simonw/datasette/issues/2417) | https://github.com/datasette/datasette-import/releases/tag/0.1a5 |
| release | 2024-09-03 | datasette-edit-schema 0.8a3 | - Fixed CSS for compatibility with upcoming Datasette 1.0 alpha. [datasette#2417](https://github.com/simonw/datasette/issues/2417) | https://github.com/simonw/datasette-edit-schema/releases/tag/0.8a3 |
| release | 2024-09-03 | datasette-auth-tokens 0.4a10 | - Fixed CSS for compatibility with upcoming Datasette 1.0 alpha. [datasette#2417](https://github.com/simonw/datasette/issues/2417) | https://github.com/simonw/datasette-auth-tokens/releases/tag/0.4a10 |
| release | 2024-09-03 | datasette-configure-fts 1.1.4 | - Fixed CSS for compatibility with upcoming Datasette 1.0 alpha. [datasette#2417](https://github.com/simonw/datasette/issues/2417) | https://github.com/simonw/datasette-configure-fts/releases/tag/1.1.4 |
| release | 2024-09-03 | datasette-enrichments 0.4.3 | - Fixed CSS for compatibility with upcoming Datasette 1.0 alpha. [datasette#2417](https://github.com/simonw/datasette/issues/2417) | https://github.com/datasette/datasette-enrichments/releases/tag/0.4.3 |
| release | 2024-09-03 | datasette-auth-passwords 1.1.1 | - Fix for compatibility with the `base_url` setting. Thanks, [@meowcat](https://github.com/meowcat) [#25](https://github.com/simonw/datasette-auth-passwords/issues/25) - `autocomplete="off"` on password field. Thanks, [@brandonrobertz](https://github.com/brandonrobertz) [#24](https://github.com/simonw/datasette-auth-passwords/pull/24) - Fixed CSS for compatibility with upcoming Datasette 1.0 alpha. [datasette#2417](https://github.com/simonw/datasette/issues/2417) | https://github.com/simonw/datasette-auth-passwords/releases/tag/1.1.1 |
| release | 2024-08-21 | datasette-pretty-traces 0.5 | - Display errors differently, depending on [this new Datasette feature](https://github.com/simonw/datasette/issues/2405). [#8](https://github.com/simonw/datasette-pretty-traces/issues/8) | https://github.com/simonw/datasette-pretty-traces/releases/tag/0.5 |
| release | 2024-08-16 | datasette 1.0a15 | - Datasette now defaults to hiding SQLite "shadow" tables, as seen in extensions such as SQLite FTS and [sqlite-vec](https://github.com/asg017/sqlite-vec). Virtual tables that it makes sense to display, such as FTS core tables, are no longer hidden. Thanks, [Alex Garcia](https://github.com/asg017). ([#2296](https://github.com/simonw/datasette/issues/2296)) - Fixed bug where running Datasette with one or more `-s/--setting` options could over-ride settings that were present in `datasette.yml`. ([#2389](https://github.com/simonw/datasette/issues/2389)) - The Datasette homepage is now duplicated at `/-/`, using the default `index.html` template. This ensures that the information on that page is still accessible even if the Datasette homepage has been customized using a custom `index.html` template, for example on sites like [datasette.io](https://datasette.io/). ([#2393](https://github.com/simonw/datasette/issues/2393)) - Failed CSRF checks now display a more user-friendly error page. ([#2390](https://github.com/simonw/datasette/issues/2390)) - Fixed a bug where the `json1` extension was not correctly detected on the `/-/versions` page. Thanks, [Seb Bacon](https://github.com/sebbacon). ([#2326](https://github.com/simonw/datasette/issues/2326)) - Fixed a bug where the Datasette write API did not correctly accept `Content-Type: application/json; charset=utf-8`. ([#2384](https://github.com/simonw/datasette/issues/2384)) - Fixed a bug where Datasette would fail to start if `metadata.yml` contained a `queries` block. ([#2386](https://github.com/simonw/datasette/pull/2386)) | https://github.com/simonw/datasette/releases/tag/1.0a15 |
| release | 2024-08-16 | datasette-checkbox 0.1a0 | - Initial release. Adds interactive checkbox widgets to any integer column with a `is_*` or `should_*` name, provided the current user has `update-row` permissions. [#1](https://github.com/datasette/datasette-checkbox/issues/1) | https://github.com/datasette/datasette-checkbox/releases/tag/0.1a0 |
| release | 2024-08-16 | datasette-checkbox 0.1a1 | - Fixed compatibility issue with `datasette-write-ui` and `datasette-comments`. [#2](https://github.com/datasette/datasette-checkbox/issues/2) | https://github.com/datasette/datasette-checkbox/releases/tag/0.1a1 |
| release | 2024-08-16 | datasette-checkbox 0.1a2 | - Now supports `has_*` columns in addition to `is_*` and `should_*`. [#3](https://github.com/datasette/datasette-checkbox/issues/3) | https://github.com/datasette/datasette-checkbox/releases/tag/0.1a2 |
| release | 2024-08-10 | datasette-geojson-map v0.5.0 | ## What's Changed * Use a full URL to reference the image by @simonw in https://github.com/eyeseast/datasette-geojson-map/pull/20 * Fix marker images and demo by @eyeseast in https://github.com/eyeseast/datasette-geojson-map/pull/29 ## New Contributors * @simonw made their first contribution in https://github.com/eyeseast/datasette-geojson-map/pull/20 **Full Changelog**: https://github.com/eyeseast/datasette-geojson-map/compare/v0.4.0...v0.5.0 | https://github.com/eyeseast/datasette-geojson-map/releases/tag/v0.5.0 |
| news | 2024-08-05 | [Datasette 1.0a14](https://docs.datasette.io/en/latest/changelog.html#a14-2024-08-05) includes some breaking changes to how metadata works for plugins, described in detail in the new [upgrade guide](https://docs.datasette.io/en/latest/upgrade_guide.html). See also the [annotated release notes](https://simonwillison.net/2024/Aug/5/datasette-1a14/) that accompany this release. | https://datasette.io/news/2024-08-05 | |
| release | 2024-08-05 | datasette 1.0a14 | This alpha introduces significant changes to Datasette's [Metadata](https://docs.datasette.io/en/latest/metadata.html#metadata) system, some of which represent breaking changes in advance of the full 1.0 release. The new [Upgrade guide](https://docs.datasette.io/en/latest/upgrade_guide.html#upgrade-guide) document provides detailed coverage of those breaking changes and how they affect plugin authors and Datasette API consumers. - The `/databasename?sql=` interface and JSON API for executing arbitrary SQL queries can now be found at `/databasename/-/query?sql=`. Requests with a `?sql=` parameter to the old endpoints will be redirected. Thanks, [Alex Garcia](https://github.com/asg017). ([#2360](https://github.com/simonw/datasette/issues/2360)) - Metadata about tables, databases, instances and columns is now stored in [Datasette's internal database](https://docs.datasette.io/en/latest/internals.html#internals-internal). Thanks, Alex Garcia. ([#2341](https://github.com/simonw/datasette/issues/2341)) - Database write connections now execute using the `IMMEDIATE` isolation level for SQLite. This should help avoid a rare `SQLITE_BUSY` error that could occur when a transaction upgraded to a write mid-flight. ([#2358](https://github.com/simonw/datasette/issues/2358)) - Fix for a bug where canned queries with named parameters could fail against SQLite 3.46. ([#2353](https://github.com/simonw/datasette/issues/2353)) - Datasette now serves `E-Tag` headers for static files. Thanks, [Agustin Bacigalup](https://github.com/redraw). ([#2306](https://github.com/simonw/datasette/pull/2306)) - Dropdown menus now use a `z-index` that should avoid them being hidden by plugins. ([#2311](https://github.com/simonw/datasette/issues/2311)) - Incorrect table and row names are no longer reflected back on the resulting 404 page. ([#2359](https://github.com/simonw/datasette/issues/2359)) - Improved documentation for async usage of the [track_event(datasette, event)](https://docs.datasette.io/en/latest/plugin_hooks.html#plugin-hook-t… | https://github.com/simonw/datasette/releases/tag/1.0a14 |
| release | 2024-08-05 | datasette-remote-metadata 0.2a0 | - Updated for compatibility with [Datasette 1.0a14](https://docs.datasette.io/en/1.0a14/changelog.html#a14-2024-08-05). [#4](https://github.com/simonw/datasette-remote-metadata/issues/4) | https://github.com/simonw/datasette-remote-metadata/releases/tag/0.2a0 |
| release | 2024-07-26 | datasette-extract 0.1a8 | - Now uses GPT-4o mini, which is around 30 times cheaper than GPT-4o for text tasks, though the same price for image tasks. [#30](https://github.com/datasette/datasette-extract/issues/30) - New feature: on the "Extract data into this table" page there is now a link to "Duplicate these columns to a new table" which pre-fills the create table form with the same columns and hints. [#29](https://github.com/datasette/datasette-extract/issues/29) | https://github.com/datasette/datasette-extract/releases/tag/0.1a8 |
| release | 2024-07-18 | sqlite-utils 3.37 | - The `create-table` and `insert-files` commands all now accept multiple `--pk` options for compound primary keys. ([#620](https://github.com/simonw/sqlite-utils/issues/620)) - Now tested against Python 3.13 pre-release. ([#619](https://github.com/simonw/sqlite-utils/pull/619)) - Fixed a crash that can occur in environments with a broken `numpy` installation, producing a `module 'numpy' has no attribute 'int8'`. ([#632](https://github.com/simonw/sqlite-utils/issues/632)) | https://github.com/simonw/sqlite-utils/releases/tag/3.37 |
| release | 2024-07-18 | llm 0.15 | - Support for OpenAI's [new GPT-4o mini](https://openai.com/index/gpt-4o-mini-advancing-cost-efficient-intelligence/) model: `llm -m gpt-4o-mini 'rave about pelicans in French'` [#536](https://github.com/simonw/llm/issues/536) - `gpt-4o-mini` is now the default model if you do not [specify your own default](https://llm.datasette.io/en/stable/setup.html#setting-a-custom-default-model), replacing GPT-3.5 Turbo. GPT-4o mini is both cheaper and better than GPT-3.5 Turbo. - Fixed a bug where `llm logs -q 'flourish' -m haiku` could not combine both the `-q` search query and the `-m` model specifier. [#515](https://github.com/simonw/llm/issues/515) | https://github.com/simonw/llm/releases/tag/0.15 |
| release | 2024-06-21 | datasette 0.64.8 | - Security improvement: 404 pages used to reflect content from the URL path, which could be used to display misleading information to Datasette users. 404 errors no longer display additional information from the URL. ([#2359](https://github.com/simonw/datasette/issues/2359)) - Backported a better fix for correctly extracting named parameters from canned query SQL against SQLite 3.46.0. ([#2353](https://github.com/simonw/datasette/issues/2353)) | https://github.com/simonw/datasette/releases/tag/0.64.8 |
| release | 2024-06-17 | datasette-faiss 0.2.1 | - Pin to NumPy 1.x - the `faiss-cpu` library this depends on is not yet compatible with NumPy 2. [#4](https://github.com/simonw/datasette-faiss/issues/4) | https://github.com/simonw/datasette-faiss/releases/tag/0.2.1 |
| release | 2024-06-13 | datasette-cluster-map 0.18.2 | - Fixed bug where default tiles were displayed at retina resolution in a way that caused the map labels to be illegibly small. [#48](https://github.com/simonw/datasette-cluster-map/issues/48) | https://github.com/simonw/datasette-cluster-map/releases/tag/0.18.2 |
| release | 2024-06-12 | datasette 0.64.7 | - Fixed a bug where canned queries with named parameters threw an error when run against SQLite 3.46.0. ([#2353](https://github.com/simonw/datasette/issues/2353)) | https://github.com/simonw/datasette/releases/tag/0.64.7 |
| release | 2024-05-15 | datasette-extract 0.1a7 | - Now uses GPT-4o instead of GPT-4 Turbo - the new model is cheaper, faster and likely a little bit better too. [#28](https://github.com/datasette/datasette-extract/issues/28) | https://github.com/datasette/datasette-extract/releases/tag/0.1a7 |
| release | 2024-05-15 | datasette-enrichments-gpt 0.5 | - Now uses [datasette-secrets](https://github.com/datasette/datasette-secrets) for configuration. If you were previously using the environment variable `OPENAI_API_KEY` you should change that to `DATASETTE_SECRETS_OPENAI_API_KEY`. [#9](https://github.com/datasette/datasette-extract/issues/9) - Switched from using GPT-4 Turbo to the new [GPT-4o](https://openai.com/index/hello-gpt-4o/), which is half the price and should provide better results. [#14](https://github.com/datasette/datasette-enrichments-gpt/issues/14) | https://github.com/datasette/datasette-enrichments-gpt/releases/tag/0.5 |
| release | 2024-05-13 | llm 0.14 | - Support for OpenAI's [new GPT-4o](https://openai.com/index/hello-gpt-4o/) model: `llm -m gpt-4o 'say hi in Spanish'` [#490](https://github.com/simonw/llm/issues/490) - The `gpt-4-turbo` alias is now a model ID, which indicates the latest version of OpenAI's GPT-4 Turbo text and image model. Your existing `logs.db` database may contain records under the previous model ID of `gpt-4-turbo-preview`. [#493](https://github.com/simonw/llm/issues/493) - New `llm logs -r/--response` option for outputting just the last captured response, without wrapping it in Markdown and accompanying it with the prompt. [#431](https://github.com/simonw/llm/issues/431) - Nine new {ref}`plugins <plugin-directory>` since version 0.13: - **[llm-claude-3](https://github.com/simonw/llm-claude-3)** supporting Anthropic's [Claude 3 family](https://www.anthropic.com/news/claude-3-family) of models. - **[llm-command-r](https://github.com/simonw/llm-command-r)** supporting Cohere's Command R and [Command R Plus](https://txt.cohere.com/command-r-plus-microsoft-azure/) API models. - **[llm-reka](https://github.com/simonw/llm-reka)** supports the [Reka](https://www.reka.ai/) family of models via their API. - **[llm-perplexity](https://github.com/hex/llm-perplexity)** by Alexandru Geana supporting the [Perplexity Labs](https://docs.perplexity.ai/) API models, including `llama-3-sonar-large-32k-online` which can search for things online and `llama-3-70b-instruct`. - **[llm-groq](https://github.com/angerman/llm-groq)** by Moritz Angermann providing access to fast models hosted by [Groq](https://console.groq.com/docs/models). - **[llm-fireworks](https://github.com/simonw/llm-fireworks)** supporting models hosted by [Fireworks AI](https://fireworks.ai/). - **[llm-together](https://github.com/wearedevx/llm-together)** adds support for the [Together AI](https://www.together.ai/) extensive family of hosted openly licensed models. - **[llm-embed-onnx](https://github.com/simonw/llm-embed-onnx)** provides seven embedding models that … | https://github.com/simonw/llm/releases/tag/0.14 |
| release | 2024-05-03 | datasette-upload-dbs 0.3.2 | - Tweak to the margins on the progress bar. | https://github.com/simonw/datasette-upload-dbs/releases/tag/0.3.2 |
| release | 2024-05-02 | ttok 0.3 | - New `--allow-special` option for allowing special tokens: `ttok '<|endoftext|>' --encode --allow-special` [#13](https://github.com/simonw/ttok/issues/13) | https://github.com/simonw/ttok/releases/tag/0.3 |
| release | 2024-04-27 | datasette-enrichments 0.4 | - New utilities for developing enrichments that need to be [configured with secrets](https://enrichments.datasette.io/en/stable/developing.html#enrichments-that-use-secrets-such-as-api-keys) such as API keys, taking advantage of the [datasette-secrets](https://datasette.io/plugins/datasette-secrets) plugin. [#46](https://github.com/datasette/datasette-enrichments/issues/46) | https://github.com/datasette/datasette-enrichments/releases/tag/0.4 |
| release | 2024-04-27 | datasette-enrichments 0.4.1 | - Removed `breakpoint()` calls in an error path that should not have been released. [#49](https://github.com/datasette/datasette-enrichments/issues/49) | https://github.com/datasette/datasette-enrichments/releases/tag/0.4.1 |