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 `columns` failed to include the `columns` key in the response. - The `?_extra=private` extra on arbitrary SQL query pages now correctly reflects whether the SQL execution permission is private to the current actor - it previously always returned `false`. - The `?_extra=query` extra on query pages now reports the named parameters that were actually bound when the query executed, including parameters declared in a stored query's `params` list. Magic `_`-prefixed parameters are no longer echoed back with unbound values taken from the querystring. - Extras that exist to serve the HTML interface (`filters`, `actions`, `display_rows`) are no longer advertised or reachable through the JSON API, where requesting them previously returned a 500 serialization error. - The pre-1.0 `?_extras=` (plural) parameter on row pages has been removed - use `?_extra=foreign_key_tables` instead. ### Security fixes - Fixed a SQL injection vulnerability in `datasette.utils.escape_sqlite()`. Identifiers were wrapped in `[brackets]` without escaping any `]` characters they contained - SQLite has no mechanism for escaping `]` inside bracket quoting, so a table or column name containing `]` could break out of the identifier and inject arbitrary SQL. Identifiers containing `]` are now quoted using double quotes instead. ([#2677](https://github.com/simonw/datasette/issues/2677)) - Fixed an open redirect vulnerability. Requesting a path such as `/\example.com/` produced a redirect with a `Location: /\example.com` header - browsers normalize backslashes to forward slashes, turning that into the protocol-relative URL `//example.com` and redirecting the user off-site. Any run of leading slashes and backslashes in a redirect path is now collapsed to a single slash. ([#2680](https://github.com/simonw/datasette/issues/2680)) ### Bug fixes - `can_render()` callbacks registered by the [register_output_renderer()](https://docs.datasette.io/en/latest/plugin_hooks.html#plugin-register-output-renderer) plugin hook now receive the result `rows` and `columns` for stored queries. Previously renderers that inspect the available columns - such as [datasette-atom](https://github.com/simonw/datasette-atom) and [datasette-ics](https://github.com/simonw/datasette-ics) - never appeared as export options on stored query pages. ([#2711](https://github.com/simonw/datasette/issues/2711)) - Fixed a 500 error from the [/-/check](https://docs.datasette.io/en/latest/authentication.html#permissioncheckview) permission debugging endpoint when checking query actions such as `view-query`, `update-query` and `delete-query`. ([#2756](https://github.com/simonw/datasette/issues/2756)) - Write queries that use a named parameter called `:sql` no longer fail with an error. ([#2761](https://github.com/simonw/datasette/issues/2761)) - [db.execute_isolated_fn()](https://docs.datasette.io/en/latest/internals.html#database-execute-isolated-fn) now works against immutable databases, using a read-only connection that bypasses the write thread. It previously always attempted to open a writable connection, which would fail - breaking features built on top of it, such as the SQL analysis step used when storing a query. An exception raised while opening the connection for an isolated function no longer crashes the write thread. ([#2768](https://github.com/simonw/datasette/issues/2768)) - Facet counts are now displayed on the same line as the facet value instead of wrapping onto a second line. ([#2754](https://github.com/simonw/datasette/issues/2754)) - Datasette's pytest plugin no longer imports the rest of Datasette at pytest startup time. This means plugin test suites using `pytest-cov` now correctly record coverage of code that runs when `datasette` modules are first imported.",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 the async tool executor silently dropped calls to tools not present in `tools=` - these now return `Error: tool ""..."" does not exist` results, matching the sync executor. [#1483](https://github.com/simonw/llm/pull/1483)",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 `/?sql=...` to `//-/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 `//-/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.io/en/latest/authentication.html#actions-alter-table) or [drop-table](https://docs.datasette.io/en/latest/authentication.html#actions-drop-table) as appropriate, and row mutation statements require the full `insert-row`, `update-row` and `delete-row` permission set. SQL functions are allowed and are not separately permission-gated. ([#2748](https://github.com/simonw/datasette/issues/2748)) - User-supplied write SQL rejects both `VACUUM` operations and writes to SQLite virtual or shadow tables. These restrictions also apply to untrusted stored write queries; trusted queries in `datasette.yml` skip these filters. ([#2748](https://github.com/simonw/datasette/issues/2748)) ### Stored queries - The previous ""canned queries"" feature has been renamed and expanded into [stored queries](https://docs.datasette.io/en/latest/sql_queries.html#stored-queries). Queries configured in `datasette.yaml` are now loaded into a new `queries` table in Datasette's [internal database](https://docs.datasette.io/en/latest/internals.html#internals-internal-schema), alongside user-created stored queries. ([#2735](https://github.com/simonw/datasette/issues/2735)) - New stored query management API methods available to plugins: `datasette.add_query()`, `datasette.update_query()`, `datasette.remove_query()`, `datasette.get_query()`, `datasette.list_queries()` and `datasette.count_queries()`. These replace the removed `datasette.get_canned_query()` and `datasette.get_canned_queries()` methods. ([#2735](https://github.com/simonw/datasette/issues/2735)) - Users with [store-query](https://docs.datasette.io/en/latest/authentication.html#actions-store-query) and [execute-sql](https://docs.datasette.io/en/latest/authentication.html#actions-execute-sql) permission can create stored queries from the SQL query page or the new `GET //-/queries/store` form. ([#2735](https://github.com/simonw/datasette/issues/2735)) - The database page now shows a count and preview of stored queries, capped at five, and links to new paginated query lists at `/-/queries` and `//-/queries`. Those pages support search. ([#2735](https://github.com/simonw/datasette/issues/2735)) - Stored queries created by users default to private and untrusted. Private stored queries can only be viewed, updated or deleted by their owner, even if another actor has broad `view-query`, `update-query` or `delete-query` permission. Untrusted stored queries execute using the permissions of the actor running them. See [Stored queries](https://docs.datasette.io/en/latest/sql_queries.html#stored-queries) and [Trusted stored queries](https://docs.datasette.io/en/latest/sql_queries.html#trusted-stored-queries) for details. ([#2735](https://github.com/simonw/datasette/issues/2735)) - Configured queries from `datasette.yaml` are trusted by default, so they can execute with `view-query` permission alone. They can opt out of that behavior using `is_trusted: false` but cannot be made private; private queries are only available for user-created stored queries. ([#2735](https://github.com/simonw/datasette/issues/2735)) - New `store-query`, `update-query` and `delete-query` permissions, plus updated semantics for [view-query](https://docs.datasette.io/en/latest/authentication.html#actions-view-query). Trusted stored queries can still execute with `view-query` alone; untrusted read queries also require [execute-sql](https://docs.datasette.io/en/latest/authentication.html#actions-execute-sql) and untrusted writable queries require [execute-write-sql](https://docs.datasette.io/en/latest/authentication.html#actions-execute-write-sql) plus the relevant table-level write permissions. ([#2735](https://github.com/simonw/datasette/issues/2735)) ### Plugin API changes - The `top_canned_query()` plugin hook has been renamed to [top_stored_query()](https://docs.datasette.io/en/latest/plugin_hooks.html#plugin-hook-top-stored-query). ([#2747](https://github.com/simonw/datasette/issues/2747)) - The `canned_queries()` plugin hook has been removed. Plugins can use the new [stored query management methods](https://docs.datasette.io/en/latest/internals.html#datasette-stored-queries) together with [startup()](https://docs.datasette.io/en/latest/plugin_hooks.html#plugin-hook-startup) to register queries. ([#2735](https://github.com/simonw/datasette/issues/2735)) ### Bug fixes - Fixed a bug where visiting `//-/query` without a `?sql=` parameter returned a 500 error. ([#2743](https://github.com/simonw/datasette/issues/2743)) - The `datasette inspect` command now correctly records row counts for tables with more than 10,000 rows. ([#2712](https://github.com/simonw/datasette/issues/2712))",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 tables used by Datasette's own tests, intended for plugin test suites. - Keyboard accessibility and ARIA roles for actions menus, thanks [pintaste](https://github.com/pintaste). ([#2727](https://github.com/simonw/datasette/pull/2727))",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/pull/1442) - New `options=` dict keyword argument on `Model.prompt()`, `Conversation.prompt()`, `Response.reply()`, and their async equivalents, matching the pattern already used by `.chain()`. The previous `**kwargs` form continues to work for backwards compatibility but is no longer documented, and will be removed in the future. [#1432](https://github.com/simonw/llm/pull/1432) ### Bug fixes - `add_tool_call()` calls that were not also recorded as stream events are now correctly emitted as `ToolCallPart` objects when assembling response parts, so they survive serialization via `response.to_dict()`. [#1433](https://github.com/simonw/llm/issues/1433)",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: `await response.messages()`) returning the assembled `list[Message]` produced by the model. Calling it forces execution if the response prompt has not yet been executed. - New `response.reply(prompt=None, **kwargs)` method that continues the conversation from any `Response`, regardless of origin. When the previous response made tool calls and `tool_results=` was not passed, `reply()` automatically executes the pending tool calls and threads the results into the next turn. On async responses `reply()` is awaitable. - New `response.to_dict()` and `Response.from_dict(data, *, model=None)` for JSON-safe serialization of a full conversation turn --- model id, input chain, assembled output (including reasoning parts and provider metadata), options, and audit fields. Reasoning signatures and `thoughtSignature` values round-trip via `provider_metadata`, so multi-turn extended thinking works across process boundaries. - New `llm/serialization.py` module exposing `MessageDict`, `PartDict`, `ResponseDict`, `PromptDict`, `UsageDict`, `AttachmentDict`, and the per-Part TypedDicts. Every `to_dict()` / `from_dict()` method is annotated with the matching TypedDict. - `Response.prompt.messages` is now the canonical structured input across the entire conversation chain. `Conversation.prompt` and `AsyncConversation.prompt` pre-compute the full chain (prior input + prior output + new turn) before constructing the next `Prompt`, so `response.prompt.messages` is always exactly what the model was sent. ### CLI - `llm prompt` and `llm chat` now display visible reasoning text to stderr in a dim style while the response streams. - New `-R/--no-reasoning` flag for `llm prompt` and `llm chat` to suppress the reasoning stream. - `llm logs` now renders any visible reasoning emitted during a response under a `## Reasoning` heading above the response. - New `reasoning` column on the `responses` table populated from the visible-reasoning text.",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)) ([#2684](https://github.com/simonw/datasette/pull/2684)) - The `///-/upsert` API ([docs](https://docs.datasette.io/en/latest/json_api.html#tableupsertview)) now rejects rows with `null` primary key values. ([#1936](https://github.com/simonw/datasette/issues/1936)) - Improved example in the API explorer for the `/-/upsert` endpoint ([docs](https://docs.datasette.io/en/latest/json_api.html#tableupsertview)). ([#1936](https://github.com/simonw/datasette/issues/1936)) - The `/.json` endpoint now includes an `""ok"": true` key, for consistency with other JSON API responses. - [call_with_supported_arguments()](https://docs.datasette.io/en/latest/internals.html#internals-utils-call-with-supported-arguments) is now documented as a supported public API. ([#2678](https://github.com/simonw/datasette/pull/2678)",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 //
/-/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-sql) documentation for details. - Column actions can now be accessed in mobile view via a new ""Column actions"" button. Previously they were not available on mobile because table headers are not displayed there. ([#2669](https://github.com/simonw/datasette/issues/2669), [#2670](https://github.com/simonw/datasette/issues/2670)) - Row pages now render foreign key values as links to the referenced row. ([#1592](https://github.com/simonw/datasette/issues/1592)) - The `startup()` plugin hook now fires after metadata and internal schema tables have been populated, so plugins can reliably inspect that state during startup. ([#2666](https://github.com/simonw/datasette/issues/2666))",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. Thanks, [Daniel Bates](https://github.com/danielalanbates). ([#2646](https://github.com/simonw/datasette/pull/2646))",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 also gains `?_extra=render_cell` and `?_extra=foreign_key_tables` extras, bringing it closer to parity with the table API. The row JSON API now returns `""ok"": true` in its response, for consistency with the table API. ## `uv run pytest` with a `dev=` dependency group The recommended development environment for Datasette now uses [uv](https://github.com/astral-sh/uv). You can now set up a development environment and run the test suite with just `uv run pytest` --- no manual virtualenv or `pip install` step required. ([#2611](https://github.com/simonw/datasette/issues/2611)) ## Other changes - Plugins that raise `datasette.utils.StartupError()` during startup now display a clean error message instead of a full traceback. ([#2624](https://github.com/simonw/datasette/issues/2624)) - Schema refreshes are now throttled to at most once per second, providing a small performance increase. ([#2629](https://github.com/simonw/datasette/issues/2629)) - Minor performance improvement to `remove_infinites` --- rows without infinity values now skip the list/dict reconstruction step. ([#2629](https://github.com/simonw/datasette/issues/2629)) - Filter inputs and the search input no longer trigger unwanted zoom on iOS Safari. Thanks, [Daniel Olasubomi Sobowale](https://github.com/bowale-os). ([#2346](https://github.com/simonw/datasette/issues/2346)) - `table_names()` and `get_all_foreign_keys()` now return results in deterministic sorted order. ([#2628](https://github.com/simonw/datasette/issues/2628)) - Switched linting to [ruff](https://github.com/astral-sh/ruff) and fixed all lint errors. ([#2630](https://github.com/simonw/datasette/issues/2630))",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 when importing CSV or TSV data. Previously all columns were treated as `TEXT` unless the `--detect-types` flag was passed. Use the new `--no-detect-types` flag to restore the old behavior. The `SQLITE_UTILS_DETECT_TYPES` environment variable has been removed. ([#679](https://github.com/simonw/sqlite-utils/issues/679))",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/upgrade_guide.html#upgrade-guide-v1-a20) for further details on how to upgrade affected plugins. Plugins can now make use of two new internal methods to help resolve permission checks: - [datasette.allowed_resources()](https://docs.datasette.io/en/latest/internals.html#datasette-allowed-resources) returns a `PaginatedResources` object with a `.resources` list of `Resource` instances that an actor is allowed to access for a given action (and a `.next` token for pagination). - [datasette.allowed_resources_sql()](https://docs.datasette.io/en/latest/internals.html#datasette-allowed-resources-sql) returns the SQL and parameters that can be executed against the internal catalog tables to determine which resources an actor is allowed to access for a given action. This can be combined with further SQL to perform advanced custom filtering. Related changes: - The way `datasette --root` works has changed. Running Datasette with this flag now causes the root actor to pass *all* permission checks. ([#2521](https://github.com/simonw/datasette/issues/2521)) - Permission debugging improvements: - The `/-/allowed` endpoint shows resources the user is allowed to interact with for different actions. - `/-/rules` shows the raw allow/deny rules that apply to different permission checks. - `/-/actions` lists every available action. - `/-/check` can be used to try out different permission checks for the current actor. ### Other changes - The internal `catalog_views` table now tracks SQLite views alongside tables in the introspection database. ([#2495](https://github.com/simonw/datasette/issues/2495)) - Hitting the `/` brings up a search interface for navigating to tables that the current user can view. A new `/-/tables` endpoint supports this functionality. ([#2523](https://github.com/simonw/datasette/issues/2523)) - Datasette attempts to detect some configuration errors on startup. - Datasette now supports Python 3.14 and no longer tests against Python 3.9.",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://github.com/simonw/llm/issues/1148) - New `-l/--latest` option for `llm logs -q searchterm` for searching logs ordered by date (most recent first) instead of the default relevance search. [#1177](https://github.com/simonw/llm/issues/1177) ### Bug fixes and documentation - The `register_embedding_models` hook is [now documented](https://llm.datasette.io/en/stable/plugins/plugin-hooks.html#register-embedding-models-register). [#1049](https://github.com/simonw/llm/issues/1049) - Show visible stack trace for `llm templates show invalid-template-name`. [#1053](https://github.com/simonw/llm/issues/1053) - Handle invalid tool names more gracefully in `llm chat`. [#1104](https://github.com/simonw/llm/issues/1104) - Add a [Tool plugins](https://llm.datasette.io/en/stable/plugins/directory.html#plugin-directory-tools) section to the plugin directory. [#1110](https://github.com/simonw/llm/issues/1110) - Error on `register(Klass)` if the passed class is not a subclass of `Toolbox`. [#1114](https://github.com/simonw/llm/issues/1114) - Add `-h` for `--help` for all `llm` CLI commands. [#1134](https://github.com/simonw/llm/issues/1134) - Add missing `dataclasses` to advanced model plugins docs. [#1137](https://github.com/simonw/llm/issues/1137) - Fixed a bug where `llm logs -T llm_version ""version"" --async` incorrectly recorded just one single log entry when it should have recorded two. [#1150](https://github.com/simonw/llm/issues/1150) - All extra OpenAI model keys in `extra-openai-models.yaml` are [now documented](https://llm.datasette.io/en/stable/other-models.html#openai-compatible-models). [#1228](https://github.com/simonw/llm/issues/1228)",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 ` 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 ` 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` results by ID prefix.** * The new `--prefix` option for `llm similar` allows searching for similar items only within IDs that start with a specified string (e.g., `llm similar my-collection --prefix 'docs/'`). Thanks, [Dan Turkel](https://github.com/daturkel). ([#1052](https://github.com/simonw/llm/issues/1052)) * **Control chained tool execution limit.** * New `--chain-limit ` (or `--cl`) option for `llm prompt` and `llm chat` to specify the maximum number of consecutive tool calls allowed for a single prompt. Defaults to 5; set to 0 for unlimited. ([#1025](https://github.com/simonw/llm/issues/1025)) * **`llm plugins --hook ` option.** * Filter the list of installed plugins to only show those that implement a specific plugin hook. ([#1047](https://github.com/simonw/llm/issues/1047)) * `llm tools list` now shows toolboxes and their methods. ([#1013](https://github.com/simonw/llm/issues/1013)) * `llm prompt` and `llm chat` now automatically re-enable plugin-provided tools when continuing a conversation (`-c` or `--cid`). ([#1020](https://github.com/simonw/llm/issues/1020)) * The `--tools-debug` option now pretty-prints JSON tool results for improved readability. ([#1083](https://github.com/simonw/llm/issues/1083)) * New `LLM_TOOLS_DEBUG` environment variable to permanently enable `--tools-debug`. ([#1045](https://github.com/simonw/llm/issues/1045)) * `llm chat` sessions now correctly respect default model options configured with `llm models set-options`. Thanks, [André Arko](https://github.com/indirect). ([#985](https://github.com/simonw/llm/issues/985)) * New `--pre` option for `llm install` to allow installing pre-release packages. ([#1060](https://github.com/simonw/llm/issues/1060)) * OpenAI models (`gpt-4o`, `gpt-4o-mini`) now explicitly declare support for tools and vision. ([#1037](https://github.com/simonw/llm/issues/1037)) * The `supports_tools` parameter is now supported in `extra-openai-models.yaml`. Thanks, [Mahesh Hegde ](https://github.com/mahesh-hegde). ([#1068](https://github.com/simonw/llm/issues/1068))",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 `-d/--database` option. Thanks, [Sukhbinder Singh](https://github.com/sukhbinder). [#933](https://github.com/simonw/llm/issues/933)",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-fabric curl https://simonwillison.net/2025/Apr/6/only-miffy/ | \ llm -t f:extract_main_idea ``` Major new features: - New [fragments feature](https://llm.datasette.io/en/stable/fragments.html). Fragments can be used to assemble long prompts from multiple existing pieces - URLs, file paths or previously used fragments. These will be stored de-duplicated in the database avoiding wasting space storing multiple long context pieces. Example usage: `llm -f https://llm.datasette.io/robots.txt 'explain this file'`. [#617](https://github.com/simonw/llm/issues/617) - The `llm logs` file now accepts `-f` fragment references too, and will show just logged prompts that used those fragments. - [register_template_loaders() plugin hook](https://llm.datasette.io/en/stable/plugins/plugin-hooks.html#register-template-loaders-register) allowing plugins to register new `prefix:value` custom template loaders. [#809](https://github.com/simonw/llm/issues/809) - [register_fragment_loaders() plugin hook](https://llm.datasette.io/en/stable/plugins/plugin-hooks.html#register-fragment-loaders-register) allowing plugins to register new `prefix:value` custom fragment loaders. [#886](https://github.com/simonw/llm/issues/886) - [llm fragments](https://llm.datasette.io/en/stable/fragments.html#browsing-fragments) family of commands for browsing fragments that have been previously logged to the database. - The new [llm-openai plugin](https://github.com/simonw/llm-openai-plugin) provides support for **o1-pro** (which is not supported by the OpenAI mechanism used by LLM core). Future OpenAI features will migrate to this plugin instead of LLM core itself. Improvements to templates: - `llm -t $URL` option can now take a URL to a YAML template. [#856](https://github.com/simonw/llm/issues/856) - Templates can now store default model options. [#845](https://github.com/simonw/llm/issues/845) - Executing a template that does not use the `$input` variable no longer blocks LLM waiting for input, so prompt templates can now be used to try different models using `llm -t pelican-svg -m model_id`. [#835](https://github.com/simonw/llm/issues/835) - `llm templates` command no longer crashes if one of the listed template files contains invalid YAML. [#880](https://github.com/simonw/llm/issues/880) - Attachments can now be stored in templates. [#826](https://github.com/simonw/llm/issues/826) Other changes: - New [llm models options](https://llm.datasette.io/en/stable/usage.html#setting-default-options-for-models) family of commands for setting default options for particular models. [#829](https://github.com/simonw/llm/issues/829) - `llm logs list`, `llm schemas list` and `llm schemas show` all now take a `-d/--database` option with an optional path to a SQLite database. They used to take `-p/--path` but that was inconsistent with other commands. `-p/--path` still works but is excluded from `--help` and will be removed in a future LLM release. [#857](https://github.com/simonw/llm/issues/857) - `llm logs -e/--expand` option for expanding fragments. [#881](https://github.com/simonw/llm/issues/881) - `llm prompt -d path-to-sqlite.db` option can now be used to write logs to a custom SQLite database. [#858](https://github.com/simonw/llm/issues/858) - `llm similar -p/--plain` option providing more human-readable output than the default JSON. [#853](https://github.com/simonw/llm/issues/853) - `llm logs -s/--short` now truncates to include the end of the prompt too. Thanks, [Sukhbinder Singh](https://github.com/sukhbinder). [#759](https://github.com/simonw/llm/issues/759) - Set the `LLM_RAISE_ERRORS=1` environment variable to raise errors during prompts rather than suppressing them, which means you can run `python -i -m llm 'prompt'` and then drop into a debugger on errors with `import pdb; pdb.pm()`. [#817](https://github.com/simonw/llm/issues/817) - Improved [--help output](https://llm.datasette.io/en/stable/help.html#llm-embed-multi-help) for `llm embed-multi`. [#824](https://github.com/simonw/llm/issues/824) - `llm models -m X` option which can be passed multiple times with model IDs to see the details of just those models. [#825](https://github.com/simonw/llm/issues/825) - OpenAI models now accept PDF attachments. [#834](https://github.com/simonw/llm/issues/834) - `llm prompt -q gpt -q 4o` option - pass `-q searchterm` one or more times to execute a prompt against the first model that matches all of those strings - useful for if you can't remember the full model ID. [#841](https://github.com/simonw/llm/issues/841) - [OpenAI compatible models](https://llm.datasette.io/en/stable/other-models.html#openai-compatible-models) configured using `extra-openai-models.yaml` now support `supports_schema: true`, `vision: true` and `audio: true` options. Thanks [@adaitche](https://github.com/adaitche) and [@giuli007](https://github.com/giuli007). [#819](https://github.com/simonw/llm/pull/819), [#843](https://github.com/simonw/llm/pull/843)",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={...})` parameter for specifying a schema from Python. This accepts either a dictionary JSON schema definition or a Pydantic `BaseModel` subclass, see [schemas in the Python API docs](https://llm.datasette.io/en/stable/python-api.html#python-api-schemas). - The default OpenAI plugin now enables schemas across all supported models. Run `llm models --schemas` for a list of these. - The [llm-anthropic](https://github.com/simonw/llm-anthropic) and [llm-gemini](https://github.com/simonw/llm-gemini) plugins have been upgraded to add schema support for those models. Here's documentation on how to [add schema support to a model plugin](https://llm.datasette.io/en/stable/plugins/advanced-model-plugins.html#advanced-model-plugins-schemas). Other smaller changes: - [GPT-4.5 preview](https://openai.com/index/introducing-gpt-4-5/) is now a supported model: `llm -m gpt-4.5 'a joke about a pelican and a wolf'` [#795](https://github.com/simonw/llm/issues/795) - The prompt string is now optional when calling `model.prompt()` from the Python API, so `model.prompt(attachments=llm.Attachment(url=url)))` now works. [#784](https://github.com/simonw/llm/issues/784) - `extra-openai-models.yaml` now supports a `reasoning: true` option. Thanks, [Kasper Primdal Lauritzen](https://github.com/KPLauritzen). [#766](https://github.com/simonw/llm/pull/766) - 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.23 release,2025-02-28,strip-tags 0.6,"- Fixed a bug where `strip-tags -t meta` still removed `` tags from the `` because the entire `` element was removed first. #32 - Kept `` 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/simonw/llm/issues/742) - New plugin for macOS users: [llm-mlx](https://github.com/simonw/llm-mlx), which provides [extremely high performance access](https://simonwillison.net/2025/Feb/15/llm-mlx/) to a wide range of local models using Apple's MLX framework. - The `llm-claude-3` plugin has been renamed to [llm-anthropic](https://github.com/simonw/llm-anthropic).",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/issues/2465))",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 `
` 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://docs.datasette.io/en/latest/internals.html#database-results) that returns a list of dictionaries representing the results from a SQL query: ([#2414](https://github.com/simonw/datasette/issues/2414)) ```python rows = (await db.execute(""select * from t"")).dicts() ``` - Default Datasette core CSS that styles inputs and buttons now requires a class of `""core""` on the element or a containing element, for example `
`. ([#2415](https://github.com/simonw/datasette/issues/2415)) - Similarly, default table styles now only apply to `
`. ([#2420](https://github.com/simonw/datasette/issues/2420)) ",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-track-event) hook. ([#2319](https://github.com/simonw/datasette/issues/2319)) - Fixed some HTTPX deprecation warnings. ([#2307](https://github.com/simonw/datasette/issues/2307)) - Datasette now serves a `` attribute. Thanks, [Charles Nepote](https://github.com/CharlesNepote). ([#2348](https://github.com/simonw/datasette/issues/2348)) - Datasette's automated tests now run against the maximum and minimum supported versions of SQLite: 3.25 (from September 2018) and 3.46 (from May 2024). Thanks, Alex Garcia. ([#2352](https://github.com/simonw/datasette/pull/2352)) - Fixed an issue where clicking twice on the URL output by `datasette --root` produced a confusing error. ([#2375](https://github.com/simonw/datasette/issues/2375))",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 ` 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 can be executed using the ONNX model framework. - **[llm-cmd](https://github.com/simonw/llm-cmd)** accepts a prompt for a shell command, runs that prompt and populates the result in your shell so you can review it, edit it and then hit `` to execute or `ctrl+c` to cancel, see [this post for details](https://simonwillison.net/2024/Mar/26/llm-cmd/).",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