Files
anthropics_skills/skills/claude-api/shared/managed-agents-memory.md
T
Lance Martin 1f630fdf92 Update claude-api skill: Managed Agents July launch wave, partner pricing, tool-runner corrections (#1463)
Syncs the claude-api skill with the current upstream source.

## Managed Agents — five new features

- `effort` on the agent's `model` object (a level string or `{"type": "<level>"}`).
  It is agent-configuration only: setting it in a per-session `model` override is
  silently ignored.
- Optional `version` on agent update, for optimistic concurrency. Omit it for
  last-write-wins.
- `initial_events` on session create, collapsing create plus first send into one
  call. Validation is all-or-nothing and only `user.message` and
  `user.define_outcome` are accepted.
- Environment and memory-store webhooks: four `environment.*` events and three
  `memory_store.*` events.
- Event deltas on per-thread streams. Previews are thread-scoped, so a child
  thread's previews never reach the session-level stream.

## Corrections to behavior the skill already documented

- Tool output offload triggers at 100,000 characters (~25k tokens), not 100K
  tokens, and covers built-in tools rather than MCP alone.
- `system.message` works on four models, checks only the primary model, appends
  system context instead of replacing the prompt, and is accepted during a
  `requires_action` idle when it trails a tool result in the same request.
- Vault-to-MCP credential matching is normalized (scheme and host lowercased,
  default ports and trailing slashes stripped), not byte-exact.
- Multiagent depth greater than 1 is a validation error, not silently ignored.
- Outcome `interrupted` fires even when evaluation never started, and then
  carries an empty-string `outcome_evaluation_start_id`.
- Deployment jitter is 15% of the run interval, floor 5s, cap 9 minutes.
- Webhooks retry three times with jittered 5-120s backoff, then drop silently.
  Auto-disable is duration-based with three named triggers.
- `session.status_terminated` means completion or error.
- `agent.thinking` is a progress signal and carries no thinking content.
- `processed_at` is already populated on first sighting for
  `user.define_outcome`, `user.custom_tool_result`, and `user.tool_result`.
- Session creation does not provision the sandbox.
- Skill `version` applies to Anthropic-authored skills too.
- Console-created vault credentials are header-injection only, and vault
  environment-variable substitution skips secrets in URL paths.
- Console trace URLs need the real workspace ID when the API key is not in the
  Default workspace.

## Elsewhere in the skill

- Note partner pricing under the first-party price table: Microsoft Foundry
  bills at standard API rates, while Amazon Bedrock and Vertex AI are
  partner-operated with separate pricing.
- Correct the tool-runner human-in-the-loop guidance, which previously pointed
  readers at the manual loop for approval gates the runner's per-turn hooks
  already cover.
- Repoint links away from the retired documentation hosts.
- Dedupe eagerly loaded SKILL.md content that the per-section files already
  cover.
2026-07-22 14:20:09 -04:00

9.8 KiB

Managed Agents — Memory Stores

Public beta. Memory stores ship under the managed-agents-2026-04-01 beta header; the SDK sets it automatically on all client.beta.memory_stores.* calls. If client.beta.memory_stores is missing, upgrade to the latest SDK release.

Sessions are ephemeral by default — when one ends, anything the agent learned is gone. A memory store is a workspace-scoped collection of small text documents that persists across sessions. When a store is attached to a session (via resources[]), it is mounted into the container as a filesystem directory; the agent reads and writes it with the ordinary file tools, and a system-prompt note tells it the mount is there.

Every mutation to a memory produces an immutable memory version (memver_...), giving you an audit trail and point-in-time rollback/redact.

⚠️ Never store credentials, API keys, or tokens in memory stores. Memories persist across sessions and are returned verbatim into future contexts — a key written once is replayed into every later session that mounts the store. Use vault environment_variable credentials instead (shared/managed-agents-tools.md → Vaults). If a secret has already been written, delete the memory and redact the affected versions (see "Redact a version" below).

Object model

Object ID prefix Scope Notes
Memory store memstore_... Workspace Attach to sessions via resources[]
Memory mem_... Store One text file, addressed by path (≤ 100KB each — prefer many small files)
Memory version memver_... Memory Immutable snapshot per mutation; operationcreated / modified / deleted

Create a store

description is passed to the agent so it knows what the store contains — write it for the model, not for humans.

store = client.beta.memory_stores.create(
    name="User Preferences",
    description="Per-user preferences and project context.",
)
print(store.id)  # memstore_01Hx...

Other SDKs: TypeScript client.beta.memoryStores.create({...}); Go client.Beta.MemoryStores.New(ctx, ...). See shared/managed-agents-api-reference.md → SDK Method Reference for the full per-language table.

Stores support retrieve / update / list (with include_archived, created_at_{gte,lte} filters) / delete / archive. Archive makes the store read-only — existing session attachments continue, new sessions cannot reference it; no unarchive.

Seed with content (optional)

Pre-load reference material before any session runs. memories.create creates a memory at the given path; if a memory already exists there the call returns 409 (memory_path_conflict_error, with the conflicting_memory_id). The store ID is the first positional argument.

client.beta.memory_stores.memories.create(
    store.id,
    path="/formatting_standards.md",
    content="All reports use GAAP formatting. Dates are ISO-8601...",
)

Attach to a session

Memory stores go in the session's resources[] array alongside file and github_repository resources (see shared/managed-agents-environments.md → Resources). Memory stores attach at session create time onlysessions.resources.add() does not accept memory_store.

session = client.beta.sessions.create(
    agent=agent.id,
    environment_id=environment.id,
    resources=[
        {
            "type": "memory_store",
            "memory_store_id": store.id,
            "access": "read_write",  # or "read_only"; default is "read_write"
            "instructions": "User preferences and project context. Check before starting any task.",
        }
    ],
)
Field Required Notes
type "memory_store"
memory_store_id memstore_...
access "read_write" (default) or "read_only" — enforced at the filesystem level on the mount
instructions Session-specific guidance for this store, in addition to the store's name/description. ≤ 4,096 chars.

Max 8 memory stores per session. Attach multiple when different slices of memory have different owners or lifecycles — e.g. one read-only shared-reference store plus one read-write per-user store, or one store per end-user/team/project sharing a single agent config.

How the agent sees it (FUSE mount)

Each attached store is mounted in the session container at /mnt/memory/<store-name>/. The agent interacts with it using the standard file tools (bash, read, write, edit, glob, grep) — there are no dedicated memory tools. access: "read_only" makes the mount read-only at the filesystem level; "read_write" allows the agent to create, edit, and delete files under it. A short description of each mount (name, path, instructions, access) is automatically injected into the system prompt so the agent knows the store exists without you having to mention it.

Writes the agent makes under the mount are persisted back to the store and produce memory versions just like host-side memories.update calls.

Manage memories directly (host-side)

Use these for review workflows, correcting bad memories, or seeding stores out-of-band.

List

Returns Memory | MemoryPrefix entries — a MemoryPrefix (type: "memory_prefix", just a path) is a directory-like node when listing hierarchically. Use path_prefix to scope (include a trailing slash: "/notes/" matches /notes/a.md but not /notes_backup/old.md) and depth to bound the tree walk. order_by / order sort the result. Pass view="full" to include content in each item; the default "basic" returns metadata only.

for m in client.beta.memory_stores.memories.list(store.id, path_prefix="/"):
    if m.type == "memory":
        print(f"{m.path}  ({m.content_size_bytes} bytes, sha={m.content_sha256[:8]})")
    else:  # "memory_prefix"
        print(f"{m.path}/")

Read

mem = client.beta.memory_stores.memories.retrieve(memory_id, memory_store_id=store.id)
print(mem.content)

retrieve defaults to view="full" (content included); view matters mainly on list endpoints.

Create vs. update

Operation Addressed by Semantics
memories.create(store_id, path=..., content=...) Path Create at path. 409 (memory_path_conflict_error, includes conflicting_memory_id) if the path is already occupied.
memories.update(mem_id, memory_store_id=..., path=..., content=...) mem_... ID Mutate existing memory. Change content, path (rename), or both. Renaming onto an occupied path returns the same 409 memory_path_conflict_error.
mem = client.beta.memory_stores.memories.create(
    store.id,
    path="/preferences/formatting.md",
    content="Always use tabs, not spaces.",
)

client.beta.memory_stores.memories.update(
    mem.id,
    memory_store_id=store.id,
    path="/archive/2026_q1_formatting.md",  # rename
)

Optimistic concurrency (precondition on update)

memories.update accepts a precondition so you can read → modify → write back without clobbering a concurrent writer. The only supported type is content_sha256. On mismatch the API returns 409 (memory_precondition_failed_error) — re-read and retry against fresh state.

client.beta.memory_stores.memories.update(
    mem.id,
    memory_store_id=store.id,
    content="CORRECTED: Always use 2-space indentation.",
    precondition={"type": "content_sha256", "content_sha256": mem.content_sha256},
)

Delete

client.beta.memory_stores.memories.delete(mem.id, memory_store_id=store.id)

Pass expected_content_sha256 for a conditional delete.

Audit and rollback — memory versions

Every mutation creates an immutable memver_... snapshot. Versions accumulate for the lifetime of the parent memory; memories.retrieve always returns the current head, the version endpoints give you history.

Operation that triggers it operation field on the version
memories.create at a new path "created"
memories.update changing content, path, or both (or an agent-side write to the mount) "modified"
memories.delete "deleted"

Each version also records created_by — an actor object with typesession_actor / api_actor / user_actor — and, after redaction, redacted_at + redacted_by.

List versions

Newest-first, paginated. Filter by memory_id, operation, session_id, api_key_id, or created_at_gte / created_at_lte. Pass view="full" to include content; default is metadata-only.

for v in client.beta.memory_stores.memory_versions.list(store.id, memory_id=mem.id):
    print(f"{v.id}: {v.operation}")

Retrieve a version

version = client.beta.memory_stores.memory_versions.retrieve(
    version_id, memory_store_id=store.id
)
print(version.content)

Redact a version

Scrubs content from a historical version while preserving the audit trail (actor + timestamps). Clears content, content_sha256, content_size_bytes, and path; everything else stays. Use for leaked secrets, PII, or user-deletion requests.

client.beta.memory_stores.memory_versions.redact(version_id, memory_store_id=store.id)

Endpoint reference

See shared/managed-agents-api-reference.md → Memory Stores / Memories / Memory Versions for the full HTTP method/path tables. Raw HTTP base path:

POST   /v1/memory_stores
POST   /v1/memory_stores/{memory_store_id}/archive
GET    /v1/memory_stores/{memory_store_id}/memories
PATCH  /v1/memory_stores/{memory_store_id}/memories/{memory_id}
GET    /v1/memory_stores/{memory_store_id}/memory_versions
POST   /v1/memory_stores/{memory_store_id}/memory_versions/{version_id}/redact

For cURL examples and the CLI (ant beta:memory-stores ...), WebFetch the Memory URL in shared/live-sources.md → Managed Agents.