pub struct DuplexOptions { /* private fields */ }Expand description
Configuration for DuplexSession::spawn.
Builder methods cover the spawn-time options shared with
QueryCommand; the flag emission lives on a
common internal SharedSpawnArgs, so the oneshot and duplex paths
cannot drift on how a knob is rendered. The spawn call always
includes
--print --verbose --input-format stream-json --output-format stream-json
regardless of these options.
A few QueryCommand knobs are intentionally not surfaced here
because they only make sense for a oneshot run or are owned by the
duplex transport itself:
- Transport is fixed:
output_format,input_format,include_partial_messages,verbose, andprompt_via_stdinare pinned by the duplex spawn and not configurable. retry_policyreruns a whole oneshot invocation; a duplex session holds one child open across turns, so there is nothing to retry at this layer.briefandfrom_prshape a single oneshot run (SendUserMessage for one-turn agent-to-user replies, resume-from-PR startup); a duplex host drives turns and session selection itself.prompt_suggestionsandreplay_user_messagesshape stdin/stream echoing; the duplex layer owns its own stream plumbing.
Use Self::arg if you need one of these on a duplex spawn anyway.
Implementations§
Source§impl DuplexOptions
impl DuplexOptions
Sourcepub fn system_prompt(self, prompt: impl Into<String>) -> Self
pub fn system_prompt(self, prompt: impl Into<String>) -> Self
Set the system prompt for this session (--system-prompt).
Sourcepub fn append_system_prompt(self, prompt: impl Into<String>) -> Self
pub fn append_system_prompt(self, prompt: impl Into<String>) -> Self
Append to the default system prompt (--append-system-prompt).
Sourcepub fn resume(self, session_id: impl Into<String>) -> Self
pub fn resume(self, session_id: impl Into<String>) -> Self
Resume a prior session by id (--resume <session_id>).
Mirrors QueryCommand::resume
for the duplex path. The spawned claude process picks up the
conversation that produced session_id and continues it; turns
sent through DuplexSession::send append to the existing
history rather than starting fresh.
Use case: a host (IDE, MCP server, agent backend) wants to
upgrade a passive on-disk session to a live duplex one –
pulls the session_id out of the existing JSONL log, opens a
duplex session here, and the next turn extends the same
conversation.
resume and Self::continue_session are mutually exclusive
at the CLI; passing both lets the CLI decide (it errors today).
Sourcepub fn continue_session(self) -> Self
pub fn continue_session(self) -> Self
Continue the most recent session in the current working
directory (--continue).
Mirrors QueryCommand::continue_session
for the duplex path. Use Self::resume to pick a specific
session id; use this when “the last one” is what you want.
Sourcepub fn worktree(self, name: Option<impl Into<String>>) -> Self
pub fn worktree(self, name: Option<impl Into<String>>) -> Self
Run this session in a fresh git worktree (--worktree [name]).
name is the optional worktree name (the CLI auto-generates
one if omitted). Calling this method always enables the
worktree flag, with or without a name.
Use case: an agent host wants the chat’s writes isolated from the current working tree – the chat opens with a fresh worktree, mutations land there, and the host can inspect or merge later.
Sourcepub fn agent(self, name: impl Into<String>) -> Self
pub fn agent(self, name: impl Into<String>) -> Self
Pin the session to a named subagent (--agent <name>).
name is resolved by the CLI in this order: inline
definitions from Self::agents_json, then user-level
~/.claude/agents/<name>.md files, then project-level dirs
loaded by the active --setting-sources.
Caveat: as of Claude Code 2.1.143, the CLI silently
ignores an unknown name and falls back to the default
behavior – no warning, no error. Callers that want a hard
“agent must exist” semantics should validate the name out of
band (e.g. via crate::artifacts::AgentsRoot::get) before
passing it here.
Sourcepub fn agents_json(self, json: impl Into<String>) -> Self
pub fn agents_json(self, json: impl Into<String>) -> Self
Inline subagent definitions for this session
(--agents <json>).
json is a JSON object keyed by agent name, with each value
carrying at least description and prompt. Inline
definitions take precedence over on-disk
~/.claude/agents/*.md of the same name. Pass Self::agent
to select which one to use as the session’s persona.
Example: {"reviewer": {"description": "Reviews code", "prompt": "You are a code reviewer"}}.
Sourcepub fn permission_mode(self, mode: PermissionMode) -> Self
pub fn permission_mode(self, mode: PermissionMode) -> Self
Set the permission mode for this session
(--permission-mode <mode>).
Mirrors QueryCommand::permission_mode
for the duplex path. The default mode (when this method isn’t
called) drops to the CLI’s interactive prompt for every
tool-use approval, which is broken for non-interactive duplex
sessions – nothing answers the prompts and the session stalls
or fails. Call this with PermissionMode::AcceptEdits for
the “edit files autonomously” pattern, PermissionMode::Plan
for read-only planning, etc.
Bypass mode is a footgun; reach for Self::dangerously_skip_permissions
(or, for stricter discipline, crate::dangerous::DangerousClient)
when you really need it.
Sourcepub fn dangerously_skip_permissions(self) -> Self
pub fn dangerously_skip_permissions(self) -> Self
Pass --dangerously-skip-permissions to the spawned session.
Bypasses ALL permission checks – file edits, bash, network,
the lot. Use only when you know the session runs in a trusted
sandbox (a fresh worktree, a container, etc.). For most “run
autonomously” cases you want Self::permission_mode with
PermissionMode::AcceptEdits instead.
Sourcepub fn session_id(self, id: impl Into<String>) -> Self
pub fn session_id(self, id: impl Into<String>) -> Self
Start a new session under a caller-chosen id
(--session-id <uuid>).
Mirrors QueryCommand::session_id
for the duplex path. Unlike Self::resume (pick up an
existing session) or Self::continue_session (pick up the
most recent one), this mints a fresh session whose id the host
knows up front – useful when the host indexes sessions
externally before the first turn completes.
Sourcepub fn json_schema(self, schema: impl Into<String>) -> Self
pub fn json_schema(self, schema: impl Into<String>) -> Self
Set a JSON schema for structured output validation
(--json-schema <schema>).
Mirrors QueryCommand::json_schema
for the duplex path. schema is the inline JSON of the schema;
the turn’s closing result message carries the validated
structured_output.
Sourcepub fn allowed_tools<I, T>(self, tools: I) -> Self
pub fn allowed_tools<I, T>(self, tools: I) -> Self
Add allowed tool patterns (--allowed-tools).
Mirrors QueryCommand::allowed_tools
for the duplex path: accepts anything convertible into
ToolPattern, including bare strings (e.g. "Bash",
"Bash(git log:*)", "mcp__my-server__*"), and joins them
into the comma-separated form the CLI expects.
Sourcepub fn allowed_tool(self, tool: impl Into<ToolPattern>) -> Self
pub fn allowed_tool(self, tool: impl Into<ToolPattern>) -> Self
Add a single allowed tool pattern.
Sourcepub fn disallowed_tools<I, T>(self, tools: I) -> Self
pub fn disallowed_tools<I, T>(self, tools: I) -> Self
Add disallowed tool patterns (--disallowed-tools).
Sourcepub fn disallowed_tool(self, tool: impl Into<ToolPattern>) -> Self
pub fn disallowed_tool(self, tool: impl Into<ToolPattern>) -> Self
Add a single disallowed tool pattern.
Sourcepub fn max_turns(self, turns: u32) -> Self
pub fn max_turns(self, turns: u32) -> Self
Cap the number of agentic turns (--max-turns <n>).
The cap applies per turn sent through DuplexSession::send;
a turn that exhausts it closes with an error_max_turns
result rather than an assistant reply.
Sourcepub fn max_budget_usd(self, budget: f64) -> Self
pub fn max_budget_usd(self, budget: f64) -> Self
Cap claude’s own spend for the session
(--max-budget-usd <usd>).
This is the CLI’s cap, checked post-hoc after each API call,
so a session can overspend before tripping. It is distinct
from the wrapper’s BudgetTracker
ceiling, which gates dispatch host-side – attach one via
Conversation::with_budget
to stop a duplex conversation before the next turn is sent.
Sourcepub fn fallback_model(self, model: impl Into<String>) -> Self
pub fn fallback_model(self, model: impl Into<String>) -> Self
Set a fallback model for when the primary is overloaded
(--fallback-model <model>).
Sourcepub fn add_dir(self, dir: impl Into<String>) -> Self
pub fn add_dir(self, dir: impl Into<String>) -> Self
Add an additional directory for tool access
(--add-dir <dir>, repeatable).
Sourcepub fn mcp_config(self, path: impl Into<String>) -> Self
pub fn mcp_config(self, path: impl Into<String>) -> Self
Add an MCP config file path (--mcp-config <path>,
repeatable).
Pair with crate::McpConfigBuilder to generate the file.
Sourcepub fn strict_mcp_config(self) -> Self
pub fn strict_mcp_config(self) -> Self
Only use MCP servers from --mcp-config files, ignoring the
user- and project-level MCP configuration
(--strict-mcp-config).
Sourcepub fn setting_sources(self, sources: impl Into<String>) -> Self
pub fn setting_sources(self, sources: impl Into<String>) -> Self
Comma-separated list of setting sources the CLI loads, for example
"user,project,local" (--setting-sources). Pass an empty string to
load none, sealing the session’s promptspace against ambient project
config (agents, skills, CLAUDE.md). Mirrors
QueryCommand::setting_sources.
Sourcepub fn hermetic(self) -> Self
pub fn hermetic(self) -> Self
Seal the ambient ~/.claude config for a reproducible session
(HermeticScope::Full).
Sets --setting-sources "", --strict-mcp-config, and
--exclude-dynamic-system-prompt-sections. This gives a warm
duplex session a clean seal without the Self::arg escape
hatch. Mirrors
QueryCommand::hermetic.
This is not Self::bare: a hermetic seal leaves OAuth and
keychain auth working, whereas --bare forces API-key billing.
A later Self::setting_sources call overrides the seal scope.
Sourcepub fn hermetic_scoped(self, scope: HermeticScope) -> Self
pub fn hermetic_scoped(self, scope: HermeticScope) -> Self
Seal the ambient ~/.claude config at an explicit
HermeticScope.
See Self::hermetic for the flag set. Mirrors
QueryCommand::hermetic_scoped.
Sourcepub fn no_session_persistence(self) -> Self
pub fn no_session_persistence(self) -> Self
Do not persist the session to on-disk history
(--no-session-persistence).
Sourcepub fn tools(self, tools: impl IntoIterator<Item = impl Into<String>>) -> Self
pub fn tools(self, tools: impl IntoIterator<Item = impl Into<String>>) -> Self
Set the list of available built-in tools (--tools).
Use "" to disable all tools, "default" for all tools, or
specific tool names like ["Bash", "Edit", "Read"]. This is
distinct from Self::allowed_tools, which controls tool
permissions rather than which built-ins load. Mirrors
QueryCommand::tools.
Sourcepub fn file(self, spec: impl Into<String>) -> Self
pub fn file(self, spec: impl Into<String>) -> Self
Add a file resource to download at startup (--file).
Format: file_id:relative_path (e.g. file_abc:doc.txt).
Repeatable. Mirrors QueryCommand::file.
Sourcepub fn settings(self, settings: impl Into<String>) -> Self
pub fn settings(self, settings: impl Into<String>) -> Self
Path to a settings JSON file or a JSON string (--settings).
Mirrors QueryCommand::settings.
Sourcepub fn fork_session(self) -> Self
pub fn fork_session(self) -> Self
When resuming, create a new session id instead of reusing the
original (--fork-session).
Only meaningful alongside Self::resume or
Self::continue_session. Mirrors
QueryCommand::fork_session.
Sourcepub fn debug_filter(self, filter: impl Into<String>) -> Self
pub fn debug_filter(self, filter: impl Into<String>) -> Self
Enable debug logging with an optional filter, e.g. "api,hooks"
(--debug). Mirrors
QueryCommand::debug_filter.
Sourcepub fn debug_file(self, path: impl Into<String>) -> Self
pub fn debug_file(self, path: impl Into<String>) -> Self
Write debug logs to the given file path (--debug-file).
Mirrors QueryCommand::debug_file.
Sourcepub fn betas(self, betas: impl Into<String>) -> Self
pub fn betas(self, betas: impl Into<String>) -> Self
Beta feature headers for API key authentication (--betas).
Mirrors QueryCommand::betas.
Sourcepub fn plugin_dir(self, dir: impl Into<String>) -> Self
pub fn plugin_dir(self, dir: impl Into<String>) -> Self
Load plugins from the given directory for this session
(--plugin-dir). Repeatable. Mirrors
QueryCommand::plugin_dir.
Sourcepub fn plugin_url(self, url: impl Into<String>) -> Self
pub fn plugin_url(self, url: impl Into<String>) -> Self
Fetch a plugin .zip from a URL for this session only
(--plugin-url). Repeatable. Mirrors
QueryCommand::plugin_url.
Sourcepub fn tmux(self) -> Self
pub fn tmux(self) -> Self
Create a tmux session for the worktree (--tmux).
Mirrors QueryCommand::tmux.
Sourcepub fn bare(self) -> Self
pub fn bare(self) -> Self
Run in minimal mode (--bare).
Skips hooks, LSP, plugin sync, attribution, auto-memory,
background prefetches, keychain reads, and CLAUDE.md
auto-discovery. Anthropic auth is restricted to
ANTHROPIC_API_KEY or apiKeyHelper; OAuth and keychain are
never read. Mirrors QueryCommand::bare.
Sourcepub fn safe_mode(self) -> Self
pub fn safe_mode(self) -> Self
Start with all customizations disabled (--safe-mode).
Disables CLAUDE.md, skills, plugins, hooks, MCP servers,
custom commands and agents, and output styles for
troubleshooting. Mirrors
QueryCommand::safe_mode.
Sourcepub fn disable_slash_commands(self) -> Self
pub fn disable_slash_commands(self) -> Self
Disable all slash-command skills (--disable-slash-commands).
Mirrors
QueryCommand::disable_slash_commands.
Sourcepub fn include_hook_events(self) -> Self
pub fn include_hook_events(self) -> Self
Include every hook lifecycle event in the stream-json output
(--include-hook-events).
Duplex sessions always run in stream-json, so this takes effect
without extra configuration. Mirrors
QueryCommand::include_hook_events.
Sourcepub fn exclude_dynamic_system_prompt_sections(self) -> Self
pub fn exclude_dynamic_system_prompt_sections(self) -> Self
Move per-machine sections (cwd, env info, memory paths, git
status) out of the system prompt and into the first user
message (--exclude-dynamic-system-prompt-sections).
Improves cross-user prompt-cache reuse. Only applies with the
default system prompt; ignored with Self::system_prompt.
Mirrors
QueryCommand::exclude_dynamic_system_prompt_sections.
Sourcepub fn name(self, name: impl Into<String>) -> Self
pub fn name(self, name: impl Into<String>) -> Self
Set a display name for this session (--name). Shown in the
/resume picker and terminal title. Mirrors
QueryCommand::name.
Sourcepub fn arg(self, arg: impl Into<String>) -> Self
pub fn arg(self, arg: impl Into<String>) -> Self
Add a raw argument to the spawn command line.
Escape hatch for flags not covered by the dedicated builder methods.
Sourcepub fn subscriber_capacity(self, capacity: usize) -> Self
pub fn subscriber_capacity(self, capacity: usize) -> Self
Set the per-session broadcast::Sender capacity backing
DuplexSession::subscribe.
Defaults to DEFAULT_SUBSCRIBER_CAPACITY (256). Larger
values give slow subscribers more room before they
Lagged;
smaller values reclaim memory if you do not subscribe.
Sourcepub fn on_permission(self, handler: PermissionHandler) -> Self
pub fn on_permission(self, handler: PermissionHandler) -> Self
Register a PermissionHandler to answer the CLI’s tool-use
permission prompts in-flight.
When set, the spawn command line includes
--permission-prompt-tool stdio, which configures the CLI to
emit control_request messages for tool use over the duplex
channel rather than blocking on a TUI prompt.
Without a handler, the session does not pass
--permission-prompt-tool and the CLI applies its default
permission policy (driven by --permission-mode).
Known limitation: as of claude CLI 2.1.x the CLI does not
emit control_request {subtype: "can_use_tool"} in stream-json
print mode, so this handler will not be invoked end-to-end until
an upstream fix lands. The wire handling is correct; see
https://github.com/anthropics/claude-agent-sdk-python/issues/469.
Sourcepub fn to_command_string(&self, claude: &Claude) -> String
pub fn to_command_string(&self, claude: &Claude) -> String
Return the full spawn command as a string that could be run in a shell.
The duplex analog of
QueryCommand::to_command_string:
the binary path from the Claude client plus the exact
arguments DuplexSession::spawn would pass for these
options, including the client’s global args. Both share one
args-assembly path, so this preview always matches the real
spawn. Arguments containing spaces or special shell characters
are shell-quoted.
§Example
use claude_wrapper::{Claude, DuplexOptions};
let claude = Claude::builder().build()?;
let opts = DuplexOptions::default()
.agent("reviewer")
.setting_sources("project");
println!("Would spawn: {}", opts.to_command_string(&claude));Trait Implementations§
Source§impl Clone for DuplexOptions
impl Clone for DuplexOptions
Source§fn clone(&self) -> DuplexOptions
fn clone(&self) -> DuplexOptions
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more