deputy keeps a provider-agnostic R runtime at its core and layers an opt-in Agent SDK-compatible facade on top. This vignette shows what is covered by the compatibility layer, how the Anthropic-style entrypoints map to deputy, and where the current boundary remains intentionally narrower than Anthropic’s full ecosystem surface.
Compatibility Matrix
| Surface | Status | deputy mapping |
|---|---|---|
agent_sdk_query() / claude_sdk_query() /
query()
|
Covered |
agent_sdk_query(), claude_sdk_query(), and
AgentSDKClient$query()
|
| Session ids, resume, fork | Covered | Persisted snapshots plus resume() / CLI flags |
| Permission modes | Covered |
default, acceptEdits,
readonly, plan,
bypassPermissions
|
| Hook events | Covered | Existing hook system plus Notification
|
| Claude settings | Covered |
CLAUDE.md, .claude/skills,
.claude/commands, .claude/agents, tool policy
keys |
| Anthropic-style built-in tool names | Covered |
Read, Write, Edit,
MultiEdit, Glob, Grep,
LS, TodoRead, TodoWrite,
WebFetch, WebSearch, Agent,
Task
|
| Native deputy runtime | Canonical |
Agent, LeadAgent,
Permissions, HookMatcher
|
| Plugin discovery / marketplace execution | Not in this wave | Track separately from the core compat facade |
| MCP resource subscriptions | Not in this wave | deputy exposes MCP tools, not Anthropic-specific resource flows |
Entry Points
Use agent_sdk_options() to express Anthropic-shaped
options and translate them into deputy internals. The Claude-named
aliases remain fully supported.
library(deputy)
options <- agent_sdk_options(
chat = ellmer::chat_anthropic(model = "claude-sonnet-4-5-20250929"),
setting_sources = c("user", "project", "local"),
permission_mode = "plan",
allowed_tools = c("Read", "Grep", "LS"),
max_turns = 15
)
result <- agent_sdk_query("Summarize the package structure", options = options)
result$session_idFor a stateful client:
client <- AgentSDKClient$new(options)
client$query("Inspect the R/ directory")Sessions, Resume, and Fork
The compatibility layer persists snapshots to:
tools::R_user_dir("deputy", "cache")Snapshots are enabled by default for the compatibility APIs. Each
completed turn writes a new snapshot, and the latest snapshot path is
attached to AgentResult$snapshot_path.
result <- client$query("Create a high-level summary")
# Restore the latest snapshot for a session id
client$resume(result$session_id)
# Restore the newest snapshot at or before a point in time
client$resume(result$session_id, at = "2026-03-07 10:30:00")
# Clone the restored state into a new session id
client$resume(result$session_id, fork = TRUE)The CLI exposes the same behavior:
Permissions and Hooks
Anthropic’s planning behavior maps to deputy’s plan
mode:
plan allows only tools annotated with
read_only_hint = TRUE plus the approval tool named by
permission_prompt_tool_name (default:
"AskUserQuestion"). Write, execution, and unannotated tools
are denied by default.
Informational runtime events now use the existing hook system via
Notification:
hook <- HookMatcher$new(
event = "Notification",
callback = function(message, context) {
cli::cli_alert_info("[{context$code}] {message}")
NULL
}
)deputy emits Notification for cases such as session
restore or fork notices, permission-denied guidance, compaction
fallbacks, and cost warnings.
Settings, Agents, and Tool Aliases
claude_settings_load() and
claude_settings_apply() now understand:
-
CLAUDE.mdmemory blocks .claude/skills.claude/commands.claude/agents- Tool policy keys such as
allowedTools,disallowedTools, andpermissionPromptToolName
setting_sources precedence is fixed as
user, then project, then local.
The local source only loads
.claude/settings.local.json, so it can override settings
keys without pulling in extra memory, commands, skills, or agents.
Custom agents from .claude/agents are converted to
AgentDefinition objects and registered automatically when
you use LeadAgent or AgentSDKClient.
Unsupported frontmatter fields are warned on and ignored so
compatibility stays resilient when files include metadata deputy does
not map.
Anthropic-style tool names resolve through the compatibility layer rather than changing deputy’s native tool names:
compat_tools <- agent_sdk_options(
custom_tools = list(),
allowed_tools = c("Read", "Edit", "TodoWrite", "Agent")
)This keeps read_file, edit_file,
todo_write, and the rest of deputy’s snake_case tool
surface intact for native R users.
Design Boundary
deputy aims for behavioral compatibility, not a literal language-port of the Node or Python SDKs. The runtime model is intentionally R-native:
- R6 objects instead of Python or TypeScript classes
-
corogenerators for streaming - Base lists and data frames for snapshots and session indexes
- Existing deputy hooks and permissions reused by the compat facade
That boundary keeps the Anthropic surface available without making the rest of the package Anthropic-specific. Plugins and marketplace execution remain deferred until the settings and agent surface is more mature.