Skip to content

[pull] develop from baserow:develop - #454

Merged
pull[bot] merged 4 commits into
code:developfrom
baserow:develop
Sep 18, 2026
Merged

pull[bot] merged 4 commits into
code:developfrom
baserow:develop

Conversation

@pull

@pull pull Bot commented Sep 18, 2026

Copy link
Copy Markdown

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

silvestrid and others added 4 commits September 18, 2026 09:12
* fix: contain assistant failures and harden formulas

Contain recoverable tool, formula, and provider failures without ending the assistant turn. Keep formula documentation safe to interpolate and cover the production paths with focused regressions.

* fix: preserve assistant recovery and validated formula targets

* fix: preserve assistant row action updates and verify recovery

* fix: report only saved assistant form inputs

* fix: refresh assistant row tools when a table's fields change

Row tools bake the table schema into their pydantic signature when
load_row_tools builds them, so adding, renaming or deleting a field left
the already-registered create_rows_in_table_<id> tool rejecting the new
column ("Extra inputs are not permitted"). The model could only recover
by guessing that a reload was needed, which is what produced the fatal
duplicate-tool crash in production.

Every tool that changes a table's fields now rebuilds the loaded row
tools in place from the current schema, so the next row call just works:
create_fields, update_fields, delete_fields, create_tables (a link_row
or lookup adds a reverse field to an existing table) and generate_formula
(saving over a non-formula field trashes it). The whole registry is
rebuilt rather than only the mutated table, because a link_row field also
changes the table it points at. A rebuild failure is logged and leaves
the previous tool in place, so it can never fail a field change that
already succeeded.

load_row_tools' docstring no longer tells the model to avoid reloading;
it now says a reload after a schema change is safe and is the recovery
path if a row tool still rejects a new field.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: record why an assistant run ended without an answer

A run that produced no answer was reported to PostHog as
$ai_is_error=false with a null $ai_output_state, so it was invisible to
every error dashboard. Over 28 days that hid 315 traces (1.3% of all
runs) which had executed tool calls and run for tens of seconds before
returning nothing.

Only a BaseException can reach that state, since set_trace_output runs
on every normal exit of the traced block, so in practice these are user
cancellations and dropped connections rather than silent failures.
Lumping them in with exceptions would have inflated the tracked error
rate with ordinary user behaviour.

Every run is now classified into an explicit AssistantTraceOutcome
(answered, error, cancelled, interrupted, no_answer) recorded on the
trace. $ai_is_error stays true only for error, and is now also true for
no_answer: a run that ended normally with nothing to show is a real
defect. Cancelled and interrupted stay non-errors but are finally
distinguishable, and the three no-answer outcomes carry a {"status": ...}
output state instead of a bare null.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: stop destroying assistant stream events at chunk boundaries

The custom XHR adapter treated `buffer` as a high-water mark of everything
received rather than as a pending buffer. Every progress event advanced it
to the full responseText, so the incomplete trailing fragment of the chunk
was JSON.parse'd into a swallowed console.trace and then dropped: it could
never be rejoined with its continuation. Any streamed record split across a
network read was lost, which is what produced the reported
"Unexpected token 'b', \"ber 1, Num\"..." in the browser console.

The reader now keeps the unconsumed tail, splits only on whole delimiters
and dispatches complete records through a promise chain, so ordering holds
across progress events even if the consumer becomes async. onload flushes
the remainder: a final record that merely lost its trailing delimiter is
delivered, a truncated one is reported instead of silently dropped. That
also fixes responses small enough to arrive without a usable progress
event, which previously delivered nothing at all.

Resolving now waits for the flush, so the store's post-send check no longer
races the last record and reports "The assistant did not provide a
response." for a run that actually answered.

The spec drives the real adapter through a fake XHR and asserts every
record is delivered exactly once, in order, for every possible one- and
two-cut split of the body.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* docs: explain the ModelRetry passthrough in generate_formula

Review read `except ModelRetry: raise` as dead code. It is unreachable
today, but only because agent.run() converts every ModelRetry from tools
and output validators into retry prompts internally. Without the guard, a
ModelRetry that did escape would be caught by the blanket handler below,
rewritten into a generic failure message and logged as an exception —
turning a retry signal into an error. A reviewer misreading it is reason
enough to say so in the code.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Bumps [devalue](https://github.com/sveltejs/devalue) from 5.9.0 to 5.9.2.
- [Release notes](https://github.com/sveltejs/devalue/releases)
- [Changelog](https://github.com/sveltejs/devalue/blob/main/CHANGELOG.md)
- [Commits](sveltejs/devalue@v5.9.0...v5.9.2)

---
updated-dependencies:
- dependency-name: devalue
  dependency-version: 5.9.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…#5988)

Bumps [uvicorn[standard]](https://github.com/Kludex/uvicorn) from 0.40.0 to 0.52.4.
- [Release notes](https://github.com/Kludex/uvicorn/releases)
- [Changelog](https://github.com/Kludex/uvicorn/blob/main/docs/release-notes.md)
- [Commits](Kludex/uvicorn@0.40.0...0.52.4)

---
updated-dependencies:
- dependency-name: uvicorn[standard]
  dependency-version: 0.52.4
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…6000)

* chore(deps): bump @faker-js/faker from 7.6.0 to 10.5.0 in /e2e-tests

Bumps [@faker-js/faker](https://github.com/faker-js/faker) from 7.6.0 to 10.5.0.
- [Release notes](https://github.com/faker-js/faker/releases)
- [Changelog](https://github.com/faker-js/faker/blob/next/CHANGELOG.md)
- [Commits](faker-js/faker@v7.6.0...v10.5.0)

---
updated-dependencies:
- dependency-name: "@faker-js/faker"
  dependency-version: 10.5.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

* fix: use faker.person after the faker 10 upgrade

faker removed the name module in v9; faker.name is now undefined, so
createUser threw and took every e2e test with it.

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Davide Silvestri <silvestri.eng@gmail.com>
@pull pull Bot locked and limited conversation to collaborators Sep 18, 2026
@pull pull Bot added the ⤵️ pull label Sep 18, 2026
@pull
pull Bot merged commit 7e22595 into code:develop Sep 18, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant