Repository navigation
feat(claude-agents)!: accept trusted cwd and settingSources options, and load no host settings by default - #135
Conversation
…tions
`createClaudeAgentsHandler({ cwd, settingSources })` passes each option
given to every `query()` call, on the blocking and streaming paths. They
configure the host process the Agent SDK starts, so they come from the
application: they are spread after `model.parameters`, which already drops
both, and a config can neither set nor override them. An option not given
is not sent, so defaults are unchanged; `settingSources: []` is sent as an
empty list, which is the Agent SDK's isolation setting.
The README now says that, with `settingSources` unset, a run loads the
host's user, project and local Claude Code settings, including their
plugins, skills, hooks and permission rules. Measured on Agent SDK 0.3.220,
an unconfigured handler on a developer machine reported that machine's
plugins and 26 skills in its `init` message.
Also pins the existing `tools: []` rule with tests: a config with no
native tools sends an explicit empty list (every built-in off), and
user-defined tools stay reachable through MCP.
Spec: TESTING.md §2.x "Claude Agents Handler — host options and built-in
tool set" and A.17 in launchdarkly/ai-sdks-monorepo.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t-options # Conflicts: # packages/claude-agents/src/handler.ts
…p opts in `settingSources` not given now sends `[]` instead of leaving the Agent SDK default, which loads every source: user, project and local settings, including the host's plugins, skills, hooks, permission rules and `CLAUDE.md` (AIC-3584 saw 22 of 52 requests carry a developer's `~/.claude/CLAUDE.md`). Applications that want host settings name them, e.g. `settingSources: ['user', 'project', 'local']`. `cwd` is still sent only when given. `[]` still lets the SDK read the managed-settings policy tier; the README and agents.md say so. Requested in review of launchdarkly/ai-sdks-monorepo#59. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 2ed8df5. Configure here.
jeffdupont
left a comment
There was a problem hiding this comment.
Core handler change looks right — I checked against Agent SDK 0.3.220 that [] maps to an empty --setting-sources= (only undefined keeps the all-sources default), and that cwd/settingSources can't be injected via model.parameters on either path. A few gaps before this delivers "no host settings by default" everywhere:
1. toClaudeAgents still loads all host settings (native-graph.ts:115-127)
+1 to the Bugbot comment. The native-graph query() (root and every sub-agent node) passes no settingSources, so it still gets the SDK default and picks up ~/.claude/CLAUDE.md, plugins, skills, hooks and permission rules — the same AIC-3584 leak this PR fixes for the handler. agents.md:108 only says the adapter "doesn't take these options", which reads as if the safe default applies. Please default it to settingSources: [] (ideally via the same host-options helper) with a test, or accept the host options there too.
2. claudeAgents() / claudeGraph() wrappers can't opt back in (handler.ts:1311, graph.ts:12)
Both now default to [] (good), but neither accepts cwd/settingSources. Existing wrapper users who relied on project CLAUDE.md/skills silently lose them with no way back except rewriting to config({ handler: createClaudeAgentsHandler({...}) }). Either pass the options through (they're trusted call-site options like captureContent) or document that migration.
3. Breaking-change notes should cover auth/provider/env
README "Handler options" and the JSDoc (handler.ts:963-985) list plugins/skills/hooks/permissions/CLAUDE.md, but not that settings-file env (ANTHROPIC_BASE_URL, CLAUDE_CODE_USE_BEDROCK/Vertex, proxy vars), apiKeyHelper and model also stop applying. A Bedrock/gateway deployment configured via ~/.claude/settings.json will start failing auth after upgrade. A short "Migrating" note (pass settingSources: ['user'] or move config into process env) would help.
4. Tests
The new block only covers createClaudeAgentsHandler; please add assertions that claudeAgents, claudeGraph and toClaudeAgents send [].
Addresses review on #135. `toClaudeAgents` still sent no `settingSources`, so every Anthropic node in a native graph, root and sub-agents, loaded the host's user, project and local settings: the AIC-3584 leak the handler no longer has. It now takes `cwd` and `settingSources` in `opts` and sends `hostQueryOptions(opts)` to every node's `query()`, after that node's `model.parameters`, so it defaults to `[]` like the handler. `claudeAgents()` and `claudeGraph()` already defaulted to `[]`, but had no way to opt back in. Both now accept `cwd` and `settingSources` and build the handler with them; neither reaches `config()` or `graph()`. The README gains a migration note: `[]` also drops settings-file `env` (`ANTHROPIC_BASE_URL`, `CLAUDE_CODE_USE_BEDROCK` / `_VERTEX`, proxy variables), `apiKeyHelper` and `model`, so a Bedrock, Vertex or gateway deployment configured through `~/.claude/settings.json` fails to authenticate until it sets those in the process environment or passes `settingSources: ['user']`. Tests assert the `[]` default and the opt-in through `claudeAgents`, `claudeGraph` and `toClaudeAgents` (both graph nodes). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…native adapter Matches launchdarkly/js-ai-sdk#135. claude_agents(), claude_graph() and to_claude_agents() hard-coded setting_sources=[], so a wrapper user could not opt back in to host settings, and these signatures freeze at 1.0. - claude_agents and claude_graph take cwd / setting_sources keyword-only, build the handler with them, and pass neither on to config() / graph(). - to_claude_agents reads both from opts and sends _host_query_options(...) to every node's query(), root and sub-agents, in place of the hard-coded []. - The README gains a migration note: [] also drops the settings-file env (ANTHROPIC_BASE_URL, CLAUDE_CODE_USE_BEDROCK / _VERTEX, proxies), apiKeyHelper and model, so a Bedrock, Vertex or gateway deployment configured through ~/.claude/settings.json stops authenticating. - agents.md §2a describes the model-parameter allowlist from main instead of "forwards none of model.parameters". - API report regenerated for the new signatures. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…160) #135 added `cwd` and `settingSources` to `createClaudeAgentsHandler`, `claudeAgents`, `claudeGraph` and `toClaudeAgents`, but did not update `etc/ai-claude-agents.api.md`. Since it merged (6acd53d), the "Check API reports" step has failed on `main` and on every open PR (for example #155). This commits the report `yarn api:update` generates, nothing else. `yarn api:check` passes for all 13 packages locally. The report shows `ClaudeAgentsHostOptions` as an `ae-forgotten-export`: the type is used in public signatures but not exported. That matches how the other reports already treat unexported types (18 such warnings on main), so exporting it is left for a separate decision. 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Overview** > Regenerates the `@launchdarkly/ai-claude-agents` API Extractor report so it matches the public surface after #135. The report now reflects **`ClaudeAgentsHostOptions`** on `claudeAgents`, `claudeGraph`, `createClaudeAgentsHandler`, and `toClaudeAgents`, and adds the **`SettingSource`** import from `@anthropic-ai/claude-agent-sdk`. > > This is a generated-only change (`yarn api:update`) to fix failing **`yarn api:check`** on `main`; it does not alter runtime code. The report includes the existing **`ae-forgotten-export`** warning for `ClaudeAgentsHostOptions` (used in public signatures but not re-exported from the package entry). > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 369505e. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…host settings (#201) ## Summary This is the Python side of the core half of launchdarkly/ai-sdks-monorepo#59 (TESTING.md §2.x "Claude Agents Handler — host options and built-in tool set"). The TypeScript side is launchdarkly/js-ai-sdk#135. - **`tools=[]` when a config attaches no `NativeTool`** (§2.x.2). This reverses 50e82fd. With the key omitted, every Python run got the full Claude Code built-in set (`Read`, `Bash`, `Skill` and the rest), and the read-only tools in it need no permission. A config now turns a built-in on by attaching its sentinel, which is what TypeScript has always done. User-defined tools still go through the in-process MCP server and `allowed_tools`, whatever `tools` holds. - **`create_claude_agents_handler(*, capture_content=None, cwd=None, setting_sources=None)`** (§2.x.1). Both options are forwarded to every `query()` on the blocking and streaming paths. - `setting_sources` not given sends `[]`. The Agent SDK reads `None` as "load every source", which put the host's plugins, skills, hooks, permission rules and `CLAUDE.md` into every run (AIC-3584). - `cwd` is sent only when given. - `capture_content=None` still follows `configure()`. - A config can't set or override either option: since #107 the handler forwards only allowlisted `model.parameters`, and both keys are on the excluded list. A test pins that. - **The wrappers and the native adapter take both options too**, matching launchdarkly/js-ai-sdk#135: - `claude_agents()` and `claude_graph()` take `cwd` / `setting_sources` keyword-only and build the handler with them. Neither reaches `config()` / `graph()`. - `to_claude_agents()` reads them from `opts` and sends `_host_query_options(...)` to every node's `query()`, root and sub-agents. It already sent `tools=[]` with no native tools, and a test now pins that too. - All four entry points default to `setting_sources=[]` and no `cwd`. - **The README has a migration note.** `[]` also drops the settings-file `env` (`ANTHROPIC_BASE_URL`, `CLAUDE_CODE_USE_BEDROCK` / `_VERTEX`, proxy variables), `apiKeyHelper` and `model`. A deployment that reaches Bedrock, Vertex or a gateway through `~/.claude/settings.json` needs `setting_sources=["user"]` or those variables in the process environment. ## Breaking Two changes in runtime behaviour: - A run has no Claude Code built-ins unless its config attaches them. - A run loads no host Claude Code settings unless the application passes `setting_sources`. This needs to land before the 1.0 freeze, because changing either default after 1.0 would be breaking. ## Tests - `TestBuiltinsSurviveAnEmptyToolList` is replaced. Its "omits the key" test asserted the behaviour this PR reverses. - `TestHostOptionsAndBuiltinToolSet` adds nine tests, each run on both the invoke and stream paths. - `TestToClaudeAgentsHostIsolation` adds four, including root and leaf for the default and for given values. - `TestConvenienceExportHostOptions` and `TestClaudeGraphHostOptions` add two each: the default, and given values reaching `query()` but not `config()` / `graph()`. - The API report is regenerated for the three new signatures. Checks: - `uv run pytest`: every claude-agents test passes. The one failure in the full suite is `opencode-agents` `test_a_fake_opencode_is_started_spoken_to_and_stopped`, a macOS `/private/var` vs `/var` temp-path mismatch already on `main`. - `make lint`, `make format-check` and `make typecheck` are clean. 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Overview** > **Breaking:** Python Claude agent runs no longer inherit the Agent SDK’s implicit defaults for built-in tools or host Claude Code settings. > > Runs now pass **`tools=[]`** when the flag config attaches no `NativeTool` sentinel, which turns off Claude Code built-ins (`Read`, `Bash`, etc.) unless you explicitly enable them via `ClaudeRead`, `ClaudeBash`, and similar in `tool_handlers`. User-defined tools still use the in-process MCP server unchanged. > > **Host isolation:** `create_claude_agents_handler`, `claude_agents`, `claude_graph`, and `to_claude_agents` gain app-only **`cwd`** and **`setting_sources`** (via `_host_query_options`), forwarded on every `query()` (invoke, stream, and graph nodes). Default **`setting_sources=[]`** stops loading `~/.claude/settings.json`, project `CLAUDE.md`, plugins, hooks, and settings-file `env` (Bedrock/Vertex gateways may break until you opt in or set process env). Flag **`model.parameters` cannot override** these options. > > README/agents.md document migration; tests replace the old “omit `tools`” expectation and add coverage for host options and built-in tool sets across invoke/stream/graph paths. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit bcbde98. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

createClaudeAgentsHandler({ cwd, settingSources })takes two trusted, app-supplied options and passes each one given to everyquery()call, on both the blocking and the streaming path.model.parameters. The allowlist inmodel-parameters.tsalready drops both, so a config can neither set nor override them.settingSourcesnot given now sends[]rather than leaving the Agent SDK default, which loads every source (AIC-3584). Apps that want host settings passsettingSources: ['user', 'project', 'local'].cwdnot given still isn't sent.[]doesn't stop the SDK from reading the managed-settings policy tier.settingSourcesunset, on a developer machine, reported that machine's own plugins and 26 skills in itsinitmessage. The README documents the opt-in.tools: []rule is pinned with tests. A config with no native tools sends an explicit[], which turns every built-in off, and user-defined tools stay reachable through MCP. Python omits the key today; the spec now settles on[]for both languages, and the Python fix will follow asfix(claude-agents)!.No new exported names. The option type is inline in the signature, so the package root's approved name list doesn't change.
Spec: TESTING.md §2.x "Claude Agents Handler — host options and built-in tool set" and A.18, in launchdarkly/ai-sdks-monorepo#59.
Stacked on top of this: the experimental skills integration, #136.
CI on
mainis already red: the client package's root-export snapshot is missingmakeGraphTrackData(#101). That failure shows up here too, and is being fixed separately.🤖 Generated with Claude Code
Note
Overview
Breaking: Runs no longer load the host machine’s Claude Code settings unless the app opts in. The handler always passes
settingSources: []to the Agent SDK (instead of leaving the SDK default that loads user/project/local plugins, skills, hooks,CLAUDE.md, and settings-fileenv). Deployments that relied on~/.claude/settings.jsonfor Bedrock/Vertex/gateway auth need process env vars orsettingSources: ['user'](documented in the README migration section).Trusted host options —
cwdandsettingSourcesare added tocreateClaudeAgentsHandler,claudeAgents,claudeGraph, andtoClaudeAgentsvia sharedhostQueryOptions(). They are applied on everyquery()call (invoke, stream, and all graph nodes) aftermodel.parameters, so flag config cannot set or override them.Built-in tools — When no
NativeToolsentinels are attached, the handler sendstools: []so Claude Code built-ins stay off; user-defined tools remain available through MCP.Tests cover defaults, forwarding, config isolation, and graph paths.
Reviewed by Cursor Bugbot for commit a829919. Bugbot is set up for automated code reviews on this repo. Configure here.