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.
9.8 KiB
Managed Agents — Memory Stores
Public beta. Memory stores ship under the
managed-agents-2026-04-01beta header; the SDK sets it automatically on allclient.beta.memory_stores.*calls. Ifclient.beta.memory_storesis 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_variablecredentials 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; operation ∈ created / 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 only — sessions.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 type ∈ session_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.