* Initial marketplace draft
* Update language
* Add logos to cards
* Redesign cards
* Update adapter-card.tsx
* Update adapter-card.tsx
* Migrate marketplace to adapters
* Update meta.json
* Split adapters into new three groups
* Add iMessage
* Move adapter docs to READMEs
* Cleanup docs
* Add more logos, implement shadcn ui components
* Update adapters.json
* Add Streamdown
* Fetch vercel readmes from workspace
* Update readme-content.tsx
* Upgrade Streamdown
* Update global.css
* Update adapters.json
* Update adapters.json
* Add links to docs
* List upcoming official adapters
* Update adapters.json
* Fix adapters links
* Fix typo
* Misc fixes
* Update adapters.json
* Update adapters.json
* Migrate new info
* Update pnpm-lock.yaml
* Update adapter-card.tsx
* Add postgres to adapters page
* Update adapter-card.tsx
* Migrate postgres docs
* Add pg to valid README imports
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Move feature matrices from docs to package READMEs
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Remove packages tables from adapter/state docs
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Genericize adapter/state doc descriptions
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: improve adapters page accessibility and empty state handling
* Add custom adapter building section to SKILL.md
* Use currentColor for GitHub, Linear, and Memory icons
* Use GitHub API for README fetch, add heading to fallback state
Use the GitHub REST API instead of raw.githubusercontent.com to
automatically resolve the repo's default branch, so community
adapters using master or other branch names work correctly.
* Update adapters-grid.tsx
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com>
Several docs pages only referenced Redis as the production state
adapter. Add PostgreSQL mentions to usage page, guide "Next steps"
sections, adapters overview, SKILL.md, and package README.
Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com>
* feat: add forceReleaseLock and onLockConflict for steerability
Amp-Thread-ID: https://ampcode.com/threads/T-019cc675-20e8-73db-b852-5690bafe0008
Co-authored-by: Amp <amp@ampcode.com>
* fix: add forceReleaseLock to mock state adapter
Implements the new StateAdapter.forceReleaseLock method in the mock
adapter so tests using createMockState() don't break.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: support async onLockConflict callbacks
Allow the onLockConflict callback to return a Promise, enabling
users to check external state (e.g. DB queries) before deciding
whether to force-release or drop.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* test: add tests for forceReleaseLock and onLockConflict
Covers: default drop behavior, force mode, sync/async callbacks
returning force/drop, and forceReleaseLock on memory adapter.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore: add changeset for forceReleaseLock and onLockConflict
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: alphabetize interface members, add forceReleaseLock to ioredis adapter
Biome enforces alphabetical ordering on interface members. Also adds
the missing forceReleaseLock implementation to the ioredis state adapter.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: add missing @chat-adapter/state-ioredis to changeset
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: add comment noting race window after force-release
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* test: add forceReleaseLock tests for ioredis adapter
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* test: assert lock re-acquisition after force-release
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* test: add forceReleaseLock tests for state-redis adapter
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* test: replace fragile acquireLock call count with last-call assertion
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs: document concurrent handler execution after force-release
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: use .at(-1) and single-line format for biome compliance
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add forceReleaseLock to state-pg adapter
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs: document onLockConflict and forceReleaseLock
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Amp <amp@ampcode.com>
Co-authored-by: Hayden Bleasel <hello@haydenbleasel.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Initial work on postgres state store
* Run fix
* Replace pre-written CHANGELOG with proper changeset
The CHANGELOG was manually written with a version entry. This repo uses
Changesets to manage versioning, so add a proper changeset file instead.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add missing @vitest/coverage-v8 dev dependency
The vitest config specifies coverage provider "v8" but the package
was missing from devDependencies.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Drop drizzle-orm, use raw postgres queries
The adapter only needs 3 simple tables with basic CRUD. drizzle-orm is
a full ORM that adds significant dependency weight for no real benefit
here. The ensureSchema() method was already using raw queries. This
halves the dependency surface to just the postgres driver.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add comprehensive unit tests for postgres state adapter
Test factory function edge cases (missing URL, env var fallbacks,
custom keyPrefix) and ensureConnected guard for all state operations.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Document expired row cleanup limitation for postgres adapter
Unlike Redis, Postgres doesn't auto-delete expired rows. Document the
opportunistic cleanup behavior and provide SQL for periodic cleanup.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Remove stale drizzle keyword from package.json
drizzle-orm was removed in a prior commit but the keyword remained.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix expiresAt parsing in acquireLock
The postgres library returns timestamptz columns as JavaScript Date
objects, not strings. Wrapping in new Date() was unnecessary overhead.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Document lock atomicity difference vs Redis adapters
The Postgres ON CONFLICT approach relies on row-level locking rather
than a single atomic SET NX PX like Redis. Note this for users who
need high-contention distributed locking.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Use crypto.randomUUID() for lock token generation
Math.random() is not cryptographically secure and has a higher
collision risk in distributed environments. crypto.randomUUID() is
available in Node 16+ and provides better uniqueness guarantees.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Delete CHANGELOG.md
* Add comprehensive unit tests for postgres state adapter
Mock the postgres module and SQL client to achieve 100% coverage
across statements, branches, functions, and lines. Tests cover
factory function, connection lifecycle, subscriptions, locking,
cache operations, and the owned-client disconnect path.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add setIfNotExists method and merge with main
Implement the setIfNotExists method added to the StateAdapter
interface since this branch diverged. Uses INSERT ... ON CONFLICT
DO NOTHING with RETURNING to atomically check-and-set.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add postgres to state docs navigation and memory adapter callout
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Migrate postgres state adapter from postgres to pg (node-postgres)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Rename state-postgres to state-pg and align version to 4.17.0
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Hayden Bleasel <hello@haydenbleasel.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Add Telegram auto mode polling and init username fallback
* Expose Telegram resetWebhook API
* Refine Telegram API to longPolling and safer auto mode
* Fix: Environment variable cleanup sets `process.env.VERCEL` to the string `"undefined"` (truthy) instead of removing it, leaking a truthy VERCEL env var into subsequent tests.
This commit fixes the issue reported at packages/adapter-telegram/src/index.test.ts:661
**Bug explanation:**
In the test "auto mode stays in webhook mode on serverless runtime" (line 622), the cleanup code in the `finally` block at line 662 uses `process.env.VERCEL = undefined` when the env var wasn't previously set. In Node.js, `process.env` coerces all values to strings, so `process.env.VERCEL = undefined` actually sets `process.env.VERCEL` to the string `"undefined"`. This is truthy (`Boolean("undefined")` === `true`).
This was verified empirically:
```
process.env.TEST_VAR = undefined;
typeof process.env.TEST_VAR // "string"
process.env.TEST_VAR // "undefined"
Boolean(process.env.TEST_VAR) // true
```
The consequence is that after this test runs, `process.env.VERCEL` remains set to the truthy string `"undefined"`, causing `isLikelyServerlessRuntime()` to return `true` for all subsequent tests that run in the same process. This could cause any auto-mode tests that follow to incorrectly detect a serverless runtime and behave differently than expected.
**Fix explanation:**
Changed `process.env.VERCEL = undefined` to `delete process.env.VERCEL`, which properly removes the environment variable from `process.env`. After `delete`, `process.env.VERCEL` is `undefined` (the actual undefined value, not the string), and `Boolean(process.env.VERCEL)` correctly returns `false`. This matches the standard pattern for cleaning up environment variables in Node.js tests.
Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com>
Co-authored-by: timolins <me@timo.sh>
* Fix lint: replace delete env cleanup with Reflect.deleteProperty
* Harden Telegram polling tests and polish polling docs
* Improve Telegram polling docs with clearer motivation and examples
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(chat): allow disabling fallback streaming placeholder
Add ChatConfig options to delay initial post+edit placeholder and wait for real text before creating the streamed message. Improves ordering for Telegram and other fallback-streaming adapters.
Made-with: Cursor
* fix(chat): simplify fallback streaming placeholder
* Create fallback-streaming-placeholder.md
* Improve test
* Add new test
* Run fix
* Update streaming.mdx
---------
Co-authored-by: Hayden Bleasel <hello@haydenbleasel.com>
* Add support for telegram bot
* Add support for action buttons in telegram
* Use markdown parse mode
* Add more tests
* Fix linting issues
* Fixes
* Fixes
* Don't reverse order messages for AI and always answer for telegram
* Add telegram integration test
* Update telegram.json