Skip to content

[wrangler] Add agent_memory binding support and namespace commands#13610

Open
petebacondarwin wants to merge 33 commits intomainfrom
pbd/agent-memory
Open

[wrangler] Add agent_memory binding support and namespace commands#13610
petebacondarwin wants to merge 33 commits intomainfrom
pbd/agent-memory

Conversation

@petebacondarwin
Copy link
Copy Markdown
Contributor

@petebacondarwin petebacondarwin commented Apr 20, 2026

Add support for Cloudflare's Agent Memory service in Wrangler and Miniflare.

This PR adds a new agent_memory binding type plus a set of wrangler agent-memory namespace commands for managing Agent Memory namespaces. The binding is remote-only — Workers always proxy to the live Cloudflare API during wrangler dev rather than being simulated locally — and Wrangler will provision missing namespaces automatically at deploy time.

What's included

agent_memory binding (wrangler + miniflare, minor)

  • New agent_memory config section in wrangler.json:
    {
      "agent_memory": [
        { "binding": "MY_MEMORY", "namespace": "my-namespace" }
      ]
    }
  • Config schema, validation, and types in workers-utils (non-inheritable).
  • New Miniflare plugin (packages/miniflare/src/plugins/agent-memory/) wires the binding through the standard remote-proxy machinery so wrangler dev reaches the live Agent Memory API.
  • startDevWorker, deploy paths, print-bindings, config-diffs, and worker-upload-form all updated to recognise the binding.
  • Automatic namespace provisioning during wrangler deploy if the named namespace doesn't exist.
  • wrangler types emits typed agent_memory_namespace bindings on the generated Env interface.

wrangler agent-memory namespace commands (wrangler, minor)

wrangler agent-memory namespace create <namespace>
wrangler agent-memory namespace list   [--json]
wrangler agent-memory namespace get    <namespace_name> [--json]
wrangler agent-memory namespace delete <namespace_name> [--force]

All commands are flagged as open beta and emit a warning on use. User-facing API errors are wrapped as UserError so they get clean output instead of stack traces.

OAuth scope

  • Adds agent-memory:write to Wrangler's default login scopes so wrangler login requests the permissions needed to provision and manage Agent Memory namespaces.

Tests

  • New e2e suite packages/wrangler/e2e/agent-memory.test.ts exercises createlist (default + --json) → getdelete.
  • New e2e remote-binding test case "Agent Memory" in miniflare-remote-resources.test.ts validates the binding works end-to-end via the remote proxy.
  • Unit tests in packages/wrangler/src/__tests__/agent-memory.test.ts cover the client, command parsing, and provisioning logic.
  • Additional tests/snapshots updated in: print-bindings, provision, deploy/bindings, whoami (new OAuth scope), and normalize-and-validate-config.

Note: the Wrangler E2E shard 3 failures on this PR are tracked in #13831 — they're caused by transient Cloudflare API 5xx during the shared beforeAll of miniflare-remote-resources.test.ts, not by anything in this PR. The most recent commit on this branch (test: retry transient API 5xx in remote-binding e2e suite) wraps startRemoteProxySession in retry() to absorb the most common flake. Broader fixes are deferred to #13831.


  • Tests
    • Tests included/updated
    • Automated tests not possible - manual testing has been completed as follows:
    • Additional testing not necessary because:
  • Public documentation

A picture of a cute animal (not mandatory, but encouraged)

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Apr 20, 2026

🦋 Changeset detected

Latest commit: 1ac68c8

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 5 packages
Name Type
miniflare Minor
wrangler Minor
@cloudflare/pages-shared Patch
@cloudflare/vite-plugin Major
@cloudflare/vitest-pool-workers Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-project-automation github-project-automation Bot moved this to Untriaged in workers-sdk Apr 20, 2026
@ask-bonk
Copy link
Copy Markdown
Contributor

ask-bonk Bot commented Apr 20, 2026

UnknownError: ProviderInitError

github run

@ask-bonk
Copy link
Copy Markdown
Contributor

ask-bonk Bot commented Apr 20, 2026

@petebacondarwin Bonk workflow failed. Check the logs for details.

View workflow run · To retry, trigger Bonk again.

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Apr 20, 2026

create-cloudflare

npm i https://pkg.pr.new/create-cloudflare@13610

@cloudflare/kv-asset-handler

npm i https://pkg.pr.new/@cloudflare/kv-asset-handler@13610

miniflare

npm i https://pkg.pr.new/miniflare@13610

@cloudflare/pages-shared

npm i https://pkg.pr.new/@cloudflare/pages-shared@13610

@cloudflare/unenv-preset

npm i https://pkg.pr.new/@cloudflare/unenv-preset@13610

@cloudflare/vite-plugin

npm i https://pkg.pr.new/@cloudflare/vite-plugin@13610

@cloudflare/vitest-pool-workers

npm i https://pkg.pr.new/@cloudflare/vitest-pool-workers@13610

@cloudflare/workers-editor-shared

npm i https://pkg.pr.new/@cloudflare/workers-editor-shared@13610

@cloudflare/workers-utils

npm i https://pkg.pr.new/@cloudflare/workers-utils@13610

wrangler

npm i https://pkg.pr.new/wrangler@13610

commit: 1ac68c8

@petebacondarwin petebacondarwin marked this pull request as ready for review April 20, 2026 17:07
@workers-devprod workers-devprod requested review from a team and ascorbic and removed request for a team April 20, 2026 17:08
@workers-devprod
Copy link
Copy Markdown
Contributor

workers-devprod commented Apr 20, 2026

Codeowners approval required for this PR:

  • @cloudflare/wrangler
Show detailed file reviewers
  • packages/miniflare/src/plugins/agent-memory/index.ts: [@cloudflare/wrangler]
  • packages/miniflare/src/plugins/index.ts: [@cloudflare/wrangler]
  • packages/workers-utils/src/config/config.ts: [@cloudflare/wrangler]
  • packages/workers-utils/src/config/environment.ts: [@cloudflare/wrangler]
  • packages/workers-utils/src/config/validation.ts: [@cloudflare/wrangler]
  • packages/workers-utils/src/map-worker-metadata-bindings.ts: [@cloudflare/wrangler]
  • packages/workers-utils/src/types.ts: [@cloudflare/wrangler]
  • packages/workers-utils/src/worker.ts: [@cloudflare/wrangler]
  • packages/workers-utils/tests/config/validation/normalize-and-validate-config.test.ts: [@cloudflare/wrangler]
  • packages/wrangler/e2e/agent-memory.test.ts: [@cloudflare/wrangler]
  • packages/wrangler/e2e/remote-binding/miniflare-remote-resources.test.ts: [@cloudflare/wrangler]
  • packages/wrangler/e2e/remote-binding/workers/agent-memory.js: [@cloudflare/wrangler]
  • packages/wrangler/src/tests/agent-memory.test.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/tests/create-worker-upload-form/bindings.test.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/tests/deploy/bindings.test.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/tests/index.test.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/tests/print-bindings.test.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/tests/provision.test.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/tests/type-generation.test.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/tests/whoami.test.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/agent-memory/client.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/agent-memory/create.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/agent-memory/delete.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/agent-memory/get.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/agent-memory/index.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/agent-memory/list.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/agent-memory/provisioning.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/api/startDevWorker/utils.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/core/teams.d.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/deploy/check-remote-secrets-override.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/deploy/config-diffs.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/deployment-bundle/bindings.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/deployment-bundle/create-worker-upload-form.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/dev/miniflare/index.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/index.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/type-generation/index.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/user/user.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/utils/print-bindings.ts: [@cloudflare/wrangler]
  • tools/e2e/common.ts: [@cloudflare/wrangler]
  • tools/e2e/e2eCleanup.ts: [@cloudflare/wrangler]

Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 4 additional findings.

Open in Devin Review

Copy link
Copy Markdown
Contributor

@penalosa penalosa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initial pass. My main concern at this stage is the agentmemory/agent_memory/agent_memory_namespace naming confusion

Comment thread packages/workers-utils/src/config/environment.ts
Comment thread packages/workers-utils/src/config/validation.ts Outdated
Comment thread packages/workers-utils/src/map-worker-metadata-bindings.ts Outdated
Comment thread packages/wrangler/e2e/agent-memory.test.ts
Comment thread packages/wrangler/src/__tests__/deploy/bindings.test.ts Outdated
Comment thread packages/wrangler/src/__tests__/index.test.ts
Comment thread packages/wrangler/src/agent-memory/client.ts
Comment thread packages/wrangler/src/agent-memory/create.ts
Comment thread packages/wrangler/src/agent-memory/create.ts Outdated
Comment thread packages/wrangler/src/agent-memory/provisioning.ts
@oliy
Copy link
Copy Markdown
Contributor

oliy commented Apr 21, 2026

Looks this doesn't include the new OAuth permissions.

@oliy
Copy link
Copy Markdown
Contributor

oliy commented Apr 21, 2026

Not completely sure how "remote" bindings are implemented, but they don't seem to work.

@oliy
Copy link
Copy Markdown
Contributor

oliy commented Apr 21, 2026

As for naming, you make good points on the consistency. Since we are not constrained by agent week deadlines, we are going to make changes to center on using "agent-memory" in the naming. (and "agent_memory", as necessary).
Unfortunately, this means numerous changes in other systems (EWC, API Gateway, etc.)

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 22, 2026

✅ All changesets look good

@petebacondarwin
Copy link
Copy Markdown
Contributor Author

Marking as draft while @oliy works through some backend updates (e.g. around the agentmemory/agent-memory/agent_memory naming etc)

@petebacondarwin petebacondarwin marked this pull request as draft April 24, 2026 13:37
@petebacondarwin petebacondarwin marked this pull request as ready for review April 30, 2026 09:10
@workers-devprod
Copy link
Copy Markdown
Contributor

workers-devprod commented Apr 30, 2026

Codeowners approval required for this PR:

  • @cloudflare/wrangler
Show detailed file reviewers
  • .changeset/agent-memory-binding-support.md: [@cloudflare/wrangler]
  • .changeset/agent-memory-namespace-commands.md: [@cloudflare/wrangler]
  • packages/miniflare/src/plugins/agent-memory/index.ts: [@cloudflare/wrangler]
  • packages/miniflare/src/plugins/index.ts: [@cloudflare/wrangler]
  • packages/workers-utils/src/config/config.ts: [@cloudflare/wrangler]
  • packages/workers-utils/src/config/environment.ts: [@cloudflare/wrangler]
  • packages/workers-utils/src/config/validation.ts: [@cloudflare/wrangler]
  • packages/workers-utils/src/map-worker-metadata-bindings.ts: [@cloudflare/wrangler]
  • packages/workers-utils/src/types.ts: [@cloudflare/wrangler]
  • packages/workers-utils/src/worker.ts: [@cloudflare/wrangler]
  • packages/workers-utils/tests/config/validation/normalize-and-validate-config.test.ts: [@cloudflare/wrangler]
  • packages/wrangler/e2e/agent-memory.test.ts: [@cloudflare/wrangler]
  • packages/wrangler/e2e/remote-binding/miniflare-remote-resources.test.ts: [@cloudflare/wrangler]
  • packages/wrangler/e2e/remote-binding/workers/agent-memory.js: [@cloudflare/wrangler]
  • packages/wrangler/src/tests/agent-memory.test.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/tests/create-worker-upload-form/bindings.test.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/tests/deploy/bindings.test.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/tests/index.test.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/tests/print-bindings.test.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/tests/provision.test.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/tests/type-generation.test.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/tests/whoami.test.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/agent-memory/client.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/agent-memory/create.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/agent-memory/delete.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/agent-memory/get.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/agent-memory/index.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/agent-memory/list.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/agent-memory/provisioning.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/api/startDevWorker/utils.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/core/teams.d.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/deploy/check-remote-secrets-override.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/deploy/config-diffs.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/deployment-bundle/bindings.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/deployment-bundle/create-worker-upload-form.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/dev/miniflare/index.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/index.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/type-generation/index.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/user/user.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/utils/print-bindings.ts: [@cloudflare/wrangler]
  • tools/e2e/common.ts: [@cloudflare/wrangler]
  • tools/e2e/e2eCleanup.ts: [@cloudflare/wrangler]

devin-ai-integration[bot]

This comment was marked as resolved.

@oliy oliy force-pushed the pbd/agent-memory branch 2 times, most recently from 779c979 to dd9bf72 Compare May 4, 2026 16:11
Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 new potential issue.

🐛 1 issue in files not directly in the diff

🐛 Missing agent_memory in pickRemoteBindings causes binding to be silently dropped during wrangler dev (packages/wrangler/src/api/remoteBindings/index.ts:42-48)

agent_memory is an always-remote binding (confirmed by the changeset description, the miniflare plugin calling warnOrError("agent_memory", memory.remote, "always-remote") at packages/wrangler/src/dev/miniflare/index.ts:637, and by the miniflare plugin only implementing remote proxy). However, the pickRemoteBindings function at packages/wrangler/src/api/remoteBindings/index.ts:18-52 does not include agent_memory in its list of always-remote types. Every other always-remote binding (ai, media, artifacts, vpc_service, vpc_network, ai_search_namespace, ai_search) is explicitly listed. Without this, an agent_memory binding will only be picked for the remote proxy session if the user explicitly sets remote: true in their config. Since remote is optional (remote?: boolean in packages/workers-utils/src/config/environment.ts:1069), most users won't set it, causing the binding to silently not work during local development.

View 19 additional findings in Devin Review.

Open in Devin Review

petebacondarwin and others added 28 commits May 8, 2026 13:29
…_memory binding

Add agent_memory to wrangler types generation so running `wrangler types`
produces typed AgentMemory bindings. Fix config-diffs to strip the remote
field when comparing local vs remote configs. Fix print-bindings to
correctly display inherited agent_memory bindings.

Add comprehensive tests: config validation (7 tests), provisioning
(3 tests), deploy binding payload (1 test), and update type generation
snapshots.
- Reformat changeset example JSONC (tabs + trailing commas, per oxfmt).
- Mark Plugin and RemoteProxyConnectionString as type-only imports in
  the miniflare agent-memory plugin to satisfy consistent-type-imports.
- Update provision tests to use agent_memory_namespace (the actual
  metadata binding type) instead of agent_memory.
The upload form emits type "agent_memory_namespace" for agent memory
bindings, but the deploy/bindings test was asserting on
"agent_memory", causing the toEqual(arrayContaining(...)) check to
fail.
- Rename emitted ambient type AgentMemory to AgentMemoryNamespace to
  match the type declared in workerd (cloudflare/workerd#6628) and
  follow the AiSearchNamespace precedent.
- Consolidate the AgentMemoryNamespace interface by importing it from
  agent-memory/client.ts in agent-memory/provisioning.ts instead of
  redeclaring a narrower shape there.
- Split agent-memory/client.ts into two layers: low-level helpers that
  take (complianceConfig, accountId, ...) and high-level wrappers that
  resolve auth via requireAuth. agent-memory/provisioning.ts now
  delegates to the low-level helpers, removing the duplicated fetch
  calls.
- Reorder the agent_memory block in deploy/config-diffs.ts so it sits
  alongside the related ai_search blocks.
Matches the dominant pattern in the wrangler codebase
(ai-search.ts, pipelines/client.ts, vectorize/client.ts, etc.);
fetchResult<null> was just a style nit. No behavior change.
- wrangler agent-memory namespace create: add --json flag and switch
  the text output to logger.table, matching the list/get commands.
- Add TODO on agent-memory/client.ts pointing at the migration to the
  Cloudflare TypeScript SDK once it exposes /agentmemory endpoints
  (same situation as ai-search).
Catch the predictable client-side API errors from the agent-memory
namespace commands and rethrow them as UserError with friendly
messages so they do not get reported to Sentry:

- get/delete on an unknown namespace (404) now explains the namespace
  was not found and suggests running `namespace list`.
- create with an invalid or duplicate name (400/409/422) now surfaces
  the server's validation message wrapped in a UserError.
Wrap startRemoteProxySession() in retry() to handle transient
Cloudflare API 5xx (most commonly edge-preview returning 500),
which has been blocking shard 3 of this PR consistently for 2+
days. Test-only change; no runtime behaviour modified.

Refs: #13831
Boot the remote proxy session in beforeAll with only the first test
case's bindings, then call updateBindings inside each `it` to install
that test case's bindings. Previously every test case's bindings were
merged into a single startRemoteProxySession call, causing the boot to
time out as the suite grew. The new flow makes the boot smaller and
attributes any per-binding boot failure to the test that owns that
binding rather than to an opaque beforeAll timeout.

Also drop the retry wrapper around startRemoteProxySession in both the
main and mTLS describe blocks.
The agent-memory worker binding API uses `getProfile()` (not
`getContext()`), and the result's text field is `profile` (not
`context`). Update the test worker and assertion to match.
DevEnv extends EventEmitter and routes events between controllers via
its internal `dispatch()` method. Re-emit `reloadComplete` events on the
EventEmitter so external callers (in the next commit,
`RemoteProxySession.updateBindings`) can wait for a remote upload to
finish. Other event types stay internal for now.
… to complete

Previously `updateBindings` resolved as soon as `worker.patchConfig`
dispatched the configUpdate event, long before the remote worker had been
re-uploaded with the new bindings and the local proxy worker had unpaused.
Callers issuing requests immediately after `updateBindings` could see
flaky failures (typically "WebSocket connection failed" for JSRPC bindings
like service bindings or dispatch namespaces) because the local proxy
worker was still in its paused state during the reload window.

`updateBindings` now subscribes to the `reloadComplete` event before
calling `patchConfig`, then awaits either that event (success) or the
DevEnv `error` event (non-recoverable failure). After reload it also
drains the local proxy worker's runtime-message mutex so the "play"
message that resumes the proxy has been delivered, mirroring what
`worker.fetch` already does.
…estart

The remote-runtime tail-logs WebSocket (`#activeTail` in
`RemoteRuntimeController`) is constructed with `signal:
this.#abortController.signal`. The `ws` package wires that signal to
the underlying HTTP upgrade request via Node's `addAbortSignal()`
helper, so when `onBundleStart` aborts the controller to cancel
in-flight preview-session operations, the WebSocket's request is
destroyed with `AbortError` and emits an `error` event.

Only a `message` listener was attached at construction, so the
`error` had no handler and propagated as an unhandled exception —
visible in e2e runs as a trailing "Unhandled Errors / Uncaught
Exception" in the test report.

Attach an `error` listener at WebSocket construction that ignores
errors (debug-logged), matching the safeguards already present on the
`terminate` paths in `#previewToken` and `teardown()`. This covers
the window between WebSocket construction and the next `terminate`,
plus any transient network errors during normal operation.
…ng events.once()

Address PR feedback to use `node:events`'s `events.once()` helper, which
resolves on the named event and rejects on `error`, instead of hand-rolling
a Promise with cross-cleanup listeners. Same behavior, fewer lines, matches
the existing convention used elsewhere in wrangler (`dev.ts`, `pages/dev.ts`,
`api/dev.ts`, `ProxyController.ts`, `check/commands.ts`).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

run-remote-tests Run remote/E2E tests that require Cloudflare API credentials

Projects

Status: In Review

Development

Successfully merging this pull request may close these issues.

4 participants