Releases: cacheplane/b4run
Release list
Dawn v0.8.26
Dawn v0.8.26
Candidate commit: 470c871f258f5cd248904208bff6a89acbf3a56c
Controller phase: AUDIT_VERIFIED
Packages
| Tarball | SHA-256 |
|---|---|
dawn-ai-ag-ui-0.8.26.tgz |
4566060e5c31ce6d94c7011af79ae58476ca95f829977168f04abacf37b7e730 |
dawn-ai-config-biome-0.8.26.tgz |
6cd4632c862aef2d1a5d76af5b76a0582d48b01e60ea751fda43fdf9e4adc0b1 |
dawn-ai-config-typescript-0.8.26.tgz |
fad64e684d02d2ae9aa55d16fc225f6e385501cde5a5c412579b7fa0f1095471 |
dawn-ai-devkit-0.8.26.tgz |
b74fc1a79ba7460e0071dd6535c0cfa9fe4038d9e44842affc330ab603d0b0b6 |
dawn-ai-sdk-0.8.26.tgz |
95dfe589cb1a608e2c3cc56f836c2adc6e8b89c02c30bca951f1f9628cd271d6 |
dawn-ai-langgraph-0.8.26.tgz |
edfcbbfffd38a2f5912ac8cfa5e68742d4253f84448af2d63d658776cff0ad3a |
dawn-ai-permissions-0.8.26.tgz |
cabcd53fd5f71577591e10179c718ba1e01aca6d52b4202139a8ecb114b2e8f3 |
dawn-ai-postgres-storage-0.8.26.tgz |
f4fdd04114a144785c1bc9f60e5e9a852ada73d958452476b474d9d6b9658785 |
dawn-ai-sqlite-storage-0.8.26.tgz |
b19edf0a199febd83e093b5cece66917c4a1bc6b6b4c3f461e9ddd8eb4928fd5 |
dawn-ai-memory-0.8.26.tgz |
92b30705e5f0c92a57a543fefb2bc1c37fb2d0ab1b68eb5e0804674cc39e3c80 |
dawn-ai-memory-pgvector-0.8.26.tgz |
2d627bf11e5f67f142c51996c49042f101da8ce59962cf07c8c5c0c34dde6c70 |
dawn-ai-workspace-0.8.26.tgz |
2c127165a51927db187c6c7a4a5d4056fbfa4b38945fcebac6b7e9963e39211a |
dawn-ai-core-0.8.26.tgz |
2640f29418544f5510516bddc6460a0db5603efa6bdf763a4f5f9dc0e8e3a219 |
dawn-ai-inspector-0.8.26.tgz |
69d62f4e5fdaf950e0f13ed74ffcec98d47bb8e5045353128d599d84b0bc9cf8 |
dawn-ai-langchain-0.8.26.tgz |
0d9841309be8e58b85cb12a2e8af1014f076e175cea2495c94a7ed4c09c13813 |
dawn-ai-cli-0.8.26.tgz |
ca5ecceeea13ad112e731a16e9d9654e53956df716df31d5151185d680f62171 |
dawn-ai-sandbox-0.8.26.tgz |
5fd0ca257dde844c127f241d1dcc85f80f5157afb3fb33fc45f66adc6c239cf5 |
dawn-ai-testing-0.8.26.tgz |
c0f7bf4d2d3c838a55804fbc06a122668cc280ebc84091c86f02402dd2353e96 |
dawn-ai-evals-0.8.26.tgz |
1a555049bf1405984d520b36cd54d8781ab133f9ab51fdba5ad17eddd5a76cd1 |
dawn-ai-vite-plugin-0.8.26.tgz |
39bdbf33ef7da32bd47771ef694bb5aac69fd8f3737640137f7a252df19f8fe7 |
create-dawn-ai-app-0.8.26.tgz |
c51b0c5aa10bdf086a56526f5c1dc38ec7630df1450bcd694e28f5ea61eaa660 |
Evidence
- Manifest:
15c3afa7eea9e552d83c10e0e8bdd8ec6d9d4a6ac0b2a87e8e4ac09f5511306b - npm evidence:
dcb11970f5371995736685e5a0336e4a98f560ca2c5731ab365d85207c6bec13 - Smoke aggregate:
2b4c1287d06721e2f99c886c0a977168aff81af104cfd972b60e4843a3515933
Smoke evidence
Smoke workflow run: 34067305637 attempt 6
Retained attempt-scoped receipts: 5
| Lane | Actions artifact | Service digest | Durable Release receipt | Receipt SHA-256 |
|---|---|---|---|---|
metadata |
smoke-result-metadata-34067305637-6 (ID 9999841374) |
sha256:0bb6b7d920ae97fe16bd35cbf06578990674f60a654a9251ac53c0761e14b20a |
smoke-result-metadata-34067305637-6.json (ID 547859385) |
35f18b9f23252963096a14c6095f12bc8a40be689b207ac8e02912a7327f0e58 |
published-harness |
smoke-result-published-harness-34067305637-6 (ID 9999847052) |
sha256:a0f849a675aae732fe5e87170969f12a1df0045b21d80b09e26b96ed1a18dee7 |
smoke-result-published-harness-34067305637-6.json (ID 547859401) |
5eb06e1e966bf1243a4c4a22d2146ff9e8eff99a29f5ece3e74de37dec795242 |
runtime-targets |
smoke-result-runtime-targets-34067305637-6 (ID 9999834123) |
sha256:ecd579305113343c6fe5c3c9c1658e156848c9fe6353902ee5231f43f8e9dd3c |
smoke-result-runtime-targets-34067305637-6.json (ID 547859445) |
d0e0def8eeabe9360f9f2b7273e18c315fed51f6356182e4e870c4b7a08e72c0 |
scaffold |
smoke-result-scaffold-34067305637-6 (ID 9999840316) |
sha256:d241414bf6161907e2168e9e1654c143d34c4edc86262e818616c7e0cab2177a |
smoke-result-scaffold-34067305637-6.json (ID 547859459) |
5af48a6af759251bfea7eb255d38050610f302a91f0e0a28ff507afa17729de2 |
storage |
smoke-result-storage-34067305637-6 (ID 9999838089) |
sha256:8247883cb93f570d3736b70c2d1bb5c3d3cf7540f44158a49ae4ac17437b5d97 |
smoke-result-storage-34067305637-6.json (ID 547859482) |
30e270d982b6a7f833df84351a3f431017df527d7ce7fd433f78e25d2b8b6bd4 |
Dawn v0.8.24
Post-publication recovery for v0.8.24. Original release notes are preserved in recovery-v2-legacy-0.8.24-58d169be163a6036d15e8b5121442fe37fb2231088c22cf0ac8f17b98bf620a9.txt.
create-dawn-ai-app@0.8.21
Patch Changes
- @dawn-ai/devkit@0.8.21
@dawn-ai/workspace@0.8.21
@dawn-ai/vite-plugin@0.8.21
@dawn-ai/testing@0.8.21
Patch Changes
@dawn-ai/sqlite-storage@0.8.21
What's Changed
- ci(release): use RELEASE_GITHUB_TOKEN for the Version PR by @blove in #419
- fix(postgres-storage): republish with the pool error handler by @blove in #420
- fix(inspector): pick up the pretable 0.0.8 header theme fixes by @blove in #421
- Version Packages (0.8.20) by @blove in #422
- feat(cli): the hono build target — Dawn runs on Cloudflare Workers (deploy-anywhere B3, PR 3) by @blove in #423
- Version Packages (0.8.21) by @blove in #424
Full Changelog: https://github.com/cacheplane/dawnai/compare/@dawn-ai/ag-ui@0.8.19...@dawn-ai/sqlite-storage@0.8.21
@dawn-ai/sdk@0.8.21
Patch Changes
-
c2c19da: New
honobuild target — a Dawn app that deploys to Cloudflare Workers.build: { targets: ["node", "hono"] }makesdawn buildemit an edge deploy
alongside the usual ones:.dawn/build/app.mjs(a Hono app whose single
catch-all hands every request to Dawn's web-standard fetch handler,
export defaulted — the shape Workers, Vercel and Bun all accept),
modules.edge.mjs(the static module manifest, free of node builtins),
stores.mjs(a per-request Postgres store factory), and awrangler.toml
scaffold at the app root.wrangler deployis how you ship it; a gated CI lane
boots those same artifacts under local workerd and shows them serving Agent
Protocol and AG-UI with durable state in Postgres. No deploy to Cloudflare's
platform has been exercised — see the caveats at the end of this note.The scaffold carries a bare
name/main/compatibility_dateand no
nodejs_compat: the bundle links zeronode:specifiers, so the flag would
buy nothing, and setting it would mask a regression in the work that made the
bundle node-free. A gatededge-workerdCI lane boots the emitted artifacts
under real workerd — the same binary Cloudflare runs — with thatwrangler.toml
untouched, and drives four sequential AG-UI turns against Postgres over a
@neondatabase/serverlessWebSocket pool.The target is opt-in and never a default, because the edge serves a subset
of Dawn rather than all of it.- The stores are built per request, and that is not stylistic. A pool held at
module scope hands request N+1 an idle WebSocket bound to request N's dead I/O
context; the request then hangs until workerd cancels it, in an alternating
pattern that fails about half of all requests with nothing thrown. So
stores.mjsbuilds the pool and all three stores inside the factory and ends
the pool on dispose, with a module-scope flag recording that this isolate has
already migrated so per-request instances do not re-run three migration
transactions each time. That pool also gets an'error'listener:
@neondatabase/serverlessvendorspg-pooland theeventspolyfill, so an
idle client's failure re-emits on the pool and the shim throws when nothing is
listening — the same uncaught-exception hazard nodepghas, and one that
nodejs_compatbeing off does nothing to remove. A per-request pool is still
exposed: a client sits idle between every pair of store queries, and pg-pool's
idle listener outlivesend(). requestStores, a new option oncreateRuntimeFetchHandler, is the seam
that makes that possible: a(request) => RequestStoresfactory whose every
field is optional and falls through to the boot-resolved store when omitted.
RequestStoresis exported from@dawn-ai/cli/fetch.- The build fails, by name, on anything the edge cannot serve — with the new
DAWN_E1005, and reporting every offending feature at once rather than one
build at a time:sandbox,backends.filesystem/backends.exec, a
config-suppliedcheckpointer/threadsStore/permissions.store/
memory.store, aworkspace/directory, route skills, and route-level
long-term memory. The store cases matter most: those handles cannot cross a
build boundary, so before the gate the generated Postgres store quietly took
their place.dawn checkapplies the identical gate wheneverhonois a
configured target. - The provider import map is exhaustive or the build fails. A bundler cannot
follow a variable import specifier, soapp.mjsemits a staticswitchover
the model packages the app can reach; whatever is missing from it is missing
from the bundle. A route that will not import, or an agent whose provider
cannot be inferred, is therefore an error rather than a silently narrower map,
andsummarization.modelis included. dawn buildwarns on stderr when@dawn-ai/cli,@dawn-ai/postgres-storage,
@neondatabase/serverlessorhonois missing from the app'spackage.json.
None of them is a dependency of@dawn-ai/cli, deliberately: the CLI does not
import them, the app it generates does.- Your config is inlined into
app.mjsat build time, minus every field that
cannot survive a build boundary, rather than loaded fromdawn.config.tsat
runtime as thenodetarget does. Keep secrets in bindings, not in config.
Also new, both in service of the emitted entry:
seedModelImporterand
providerPackagesfrom@dawn-ai/langchain(re-exported from
@dawn-ai/cli/fetch), andDAWN_E5301on a runtime that reaches a store no
layer supplied.Full walkthrough, the supported subset, and an explicit list of what the CI lane
does not settle — no real Cloudflare deploy, Hyperdrive, production
connection limits, per-query latency, cross-isolate cold starts, and the bundle
size and startup CPU thatwrangler deployenforces andwrangler dev --local
does not — are in the Deployment docs under Edge runtimes. - The stores are built per request, and that is not stylistic. A pool held at
-
c2c19da: Per-request stores are now disposed only after BOTH the response body has
settled and the run that request started has released its slot. Route work
outlives its response on three paths — an aborted AG-UI stream, an abandoned
/runs/wait, a cancelled AP stream — and all three keep writing through the
stores a response-triggered teardown would have closed.close()also waits
for in-flight disposals, so a host awaiting shutdown knows the pools are shut.A runtime that reaches a store no layer supplied now answers with a 500 that
names the missing store and carries the newDAWN_E5301code, instead of a
generic failure with nothing to diagnose.
@dawn-ai/sandbox@0.8.21
@dawn-ai/postgres-storage@0.8.21
Patch Changes
-
c2c19da:
@dawn-ai/postgres-storage:assumeMigrated— a new opt-out on every store
option type.ready()resolves immediately instead of opening a transaction,
takingpg_advisory_xact_lockand re-running theCREATE … IF NOT EXISTSpass.
Set it only when the same process has already migrated that database to the
store's current version. It exists for per-request store lifetimes: a store
memoizes its migration on the instance, so a factory that rebuilds stores every
request paid three migration transactions per request — and the three advisory
locks serialized concurrent requests on the same component key. The lock itself
is unchanged; what is skipped is a pass already known to have completed.honobuild target fixes.- The generated
stores.mjsnow migrates once per isolate behind a module-scope
flag and passesassumeMigratedthereafter. wrangler.toml: the generated marker is read back, so a rebuild recognizes
its own scaffold instead of warning about it, writing a duplicate into
.dawn/build/, and reporting that duplicate as the artifact. A marked file is
still never overwritten.- The build now fails, naming the config key, when
checkpointer,
threadsStore,permissions.storeormemory.storeis configured: the
handle cannot cross the build boundary, and the emitted Postgres store was
taking its place with nothing said. - The provider import map is exhaustive or the build fails. A route that cannot
be imported, or an agent whose provider cannot be inferred, is an error rather
than a silently narrower map;summarization.modelis included, so an app
with openai routes and an anthropic summarization model no longer builds green
and fails at request time on a package that was never bundled. - All validation now runs before the first artifact is written.
- The emitted entry throws, naming the cause, when no Workers env is bound to a
request orDATABASE_URLis unset, rather than building a pool with no
connection string. - Worker names generated from a package name now start with a letter, which
Cloudflare requires. honois no longer a dependency of@dawn-ai/cli, which does not import it.
The generated app does, and the build's dependency notice names it along with
@dawn-ai/postgres-storageand@neondatabase/serverless.
- The generated
-
c2c19da: Breaking (shipped as a patch):
poolis now required on
@dawn-ai/postgres-storage's main entry, andconnectionStringhas moved to
@dawn-ai/postgres-storage/node.In
0.8.19the main entry accepted either, and built its ownpgpool from a
connectionStringwhen you passed one. It no longer does: the main entry
importspgfor types only, so it links on a runtime where a raw TCP driver
cannot be bundled at all — which is what makes Cloudflare Workers possible.
connectionStringis no longer part of the main entry's option type, so passing
it there is a type error, and the factory throws at construction naming the
missing pool and pointing at the/nodesubpath. It does not fail silently or
later.Two ways to migrate, both mechanical:
// 1. Change the import. Same three factories, connectionString still works, // the store still builds and owns its pool. import { createPostgresPermissionsStore, createPostgresThreadsStore, postgresCheckpointer, } from "@dawn-ai/postgres-storage/node"; // 2. Or build the pool yourself and keep the main entry — which is what you // want anyway if you are sharing one pool across all three stores. import { Pool } from "pg"; const pool = new Pool({ connectionString: process.env.DATABASE_URL }); // Do not skip this. See below. pool.on("error", (error) => { console.error("postgres pool client error (connection dropped):", error); }); postgresCheckpointer({ pool });
If you take option 2, attach an
'error'listener to the pool you build.
0.8.19shipped that listener as a fix, and it attached it to the pool it built
for you; now that you own the pool, you own its error handling, and these stores
deliberately do not attach one to a pool you passed in —pgputs that
responsibility on the pool owner, and attaching one silently would mask it.
pgemits'error'on the pool when an idle client fails, and an
EventEmitter'error'with no listener is an uncaught exception that ends the
process. Idle connections are dropped as a matter of course (server restart,
failover,idle_session_timeout), so a pool without one turns a routine
Postgres blip into an outage. The/nodeentry in option 1 still attaches it to
pools it builds.The
/nodeentry is the same three factories with theconnectionString
convenience layered on, and it re-exports everything the main entry does, so
option 1 is usually a one-line change. Pool ownership is unchanged in both
shapes: a pool the store built is ended byclose(), an injected pool is left
alone (ownsPool, defaultfalse).This is a breaking change against a published version, and it is going out as a
patch deliberately: the packages are in a fixed0.xgroup, where a minor
bump would move the entire group to1.0.0. -
c2c19da:
@dawn-ai/postgres-storageruns on Cloudflare Workers. That was an open
question when the package shipped in0.8.19, and its README said so: workerd
provides no raw TCP socket, sopgis unusable there.What changed is the main entry's typing. The pool is now structural —
SqlPool = { query, connect, end }— which bothpg.Pooland a
@neondatabase/serverlessWebSocketPoolsatisfy with no driver abstraction in
between. Injecting the latter runs the full contract, transactions included. The
narrowness is itself the guard:neon()'s transaction-incapable HTTP query
function fails to satisfySqlPoolat compile time, correctly, because the
checkpointer needs realBEGIN/COMMIT.dawn build'shonotarget generates
that wiring for you. Hyperdrive should also work but is untested — it needs a
Cloudflare account.Three separate pieces of evidence back this, and they are worth keeping apart:
- A throwaway spike ran this package's built
distinside real workerd
againstpostgres:16-alpineplus awsproxy. It is the only thing that has
checked the driver's transaction semantics there:BEGIN/COMMIT/ROLLBACK
are genuine session transactions,pg_advisory_xact_lockreally blocks a
second session, and eight concurrent cold-start migrations converged. The spike
was not retained; its findings are recorded in
docs/superpowers/specs/2026-08-05-edge-targets-design.md. - The package's own suite is the standing regression guard for the migration
behavior — concurrent cold starts against a virgin database, for all three
stores — but it runs on Node withpgand Testcontainers, gated on
DAWN_TEST_PGSTORAGE, not inside workerd. - The gated
edge-workerdCI lane is what runs continuously inside workerd,
and it asserts at the application level rather than the SQL level: four
sequential AG-UI turns each carrying the model's reply, identical event shapes
across turns,/healthz, and out-of-bandpsqlchecks that the thread,
checkpoint, and pending-write rows are really in Postgres. It exercises the
stores through the runtime; it does not assert on transactions, the advisory
lock, or concurrent cold starts.
One rule that lane settled the hard way: on workerd, build the pool and the
stores per request. A connection is bound to the I/O context of the request
that opened it, so a module-scope pool hands the next request a dead socket and
hangs rather than erroring.assumeMigratedexists for exactly that lifetime —
it lets a per-request store skip the migration pass that a module-scope boolean
has already completed for the isolate.Correcting one line of
0.8.19's entry while it is fresh: migrations are
memoized on the store instance, not per process. That distinction did not
matter when a process built its stores once; it is the whole reason
assumeMigratedhad to exist once stores are per request.- @dawn-ai/permissions@0.8.21
- A throwaway spike ran this package's built