feat: add set_effort, set_max_thinking_tokens, and apply_flag_settings to ClaudeSDKClient#1076
Open
Magic-Man-us wants to merge 2 commits into
Open
Conversation
…s to ClaudeSDKClient Adds public mid-conversation setters to ClaudeSDKClient, symmetric with the existing set_model / set_permission_mode, for changing effort and thinking between turns (streaming mode only). Resolves anthropics#981. The control subtypes proposed in the issue (set_effort / set_thinking) do not exist in the CLI; this mirrors the actual surface of the TypeScript SDK's Query interface instead: - apply_flag_settings(settings) -> apply_flag_settings control request. Effort is carried as the effortLevel flag-settings key. - set_max_thinking_tokens(max_thinking_tokens, thinking_display) -> set_max_thinking_tokens control request. Preserves the omit-vs-explicit-None distinction for thinking_display via a sentinel. Marked deprecated to match the TS SDK; prefer the launch-time thinking option. - set_effort(effort) -> ergonomic wrapper over apply_flag_settings({effortLevel}). Adds typed SDKControlSetModelRequest, SDKControlSetMaxThinkingTokensRequest, and SDKControlApplyFlagSettingsRequest to the SDKControlRequest union (set_model was previously dispatched as an untyped dict), exports ThinkingDisplay, and covers the new methods with forward-shape, not-connected, and display-mode tests.
Author
|
I am doing this to mirror parity with the TS SDK as expected. |
There was a problem hiding this comment.
Pull request overview
Adds mid-conversation (streaming-mode) control setters to ClaudeSDKClient so callers can adjust effort/flag settings and thinking-token budget between turns, aligning the Python SDK surface with the currently shipping CLI control protocol.
Changes:
- Add
ClaudeSDKClient.set_effort(),set_max_thinking_tokens()(deprecated), andapply_flag_settings()forwarding to control requests. - Extend
SDKControlRequesttyping union withset_model,set_max_thinking_tokens, andapply_flag_settingsrequest shapes; exportThinkingDisplay. - Add streaming-client tests validating wire shape, not-connected guards, and omit vs explicit-null vs explicit-value behavior for
thinking_display.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/test_streaming_client.py | Adds tests and a helper to locate emitted control requests for the new client setters. |
| src/claude_agent_sdk/types.py | Introduces an omit-vs-None sentinel and adds TypedDict variants for new control request subtypes; exports ThinkingDisplay. |
| src/claude_agent_sdk/client.py | Adds the new public streaming-mode setter methods on ClaudeSDKClient. |
| src/claude_agent_sdk/_internal/query.py | Implements the new control request forwarders used by ClaudeSDKClient. |
| src/claude_agent_sdk/init.py | Re-exports ThinkingDisplay from the public package surface. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Use identity check `is not _OMIT` instead of `isinstance(_, _Omitted)` so only the singleton sentinel counts as omitted, not any _Omitted(). - Hide the internal _Omitted sentinel from the public set_max_thinking_tokens signature via @overload; callers see `thinking_display: ThinkingDisplay | None`.
Comment on lines
+411
to
+415
| async def set_max_thinking_tokens( | ||
| self, | ||
| max_thinking_tokens: int | None, | ||
| thinking_display: ThinkingDisplay | None | _Omitted = _OMIT, | ||
| ) -> None: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #981.
Adds public mid-conversation setters to
ClaudeSDKClient, symmetric with the existingset_modelandset_permission_mode, so callers can change effort and thinking between turns in streaming mode.Background
Issue #981 proposed new
set_effortandset_thinkingcontrol subtypes. Those subtypes do not exist in the bundled CLI (verified against 2.1.195: zero occurrences ofset_effortorset_thinking; the CLI exposesapply_flag_settingsandset_max_thinking_tokens). This PR mirrors the actual surface of the TypeScript SDK'sQueryinterface instead, so it works against the shipping CLI today.What changed
New public methods on
ClaudeSDKClient:apply_flag_settings(settings): forwards anapply_flag_settingscontrol request. Flag settings sit above user/project/local settings and below managed policy settings, and apply to subsequent turns.set_max_thinking_tokens(max_thinking_tokens, thinking_display): forwards aset_max_thinking_tokenscontrol request. Marked deprecated to match the TypeScript SDK; prefer the launch-timethinkingoption. Thethinking_displayargument preserves the omit vs explicitNonedistinction (omit keeps the session display mode,Noneresets to the API default).set_effort(effort): convenience wrapper overapply_flag_settings({"effortLevel": effort}).effortLevelis the real flag-settings key (verified in the CLI); passingNoneclears the override and falls back to the launch value.set_thinkingis intentionally not added: there is no single CLI subtype matching theThinkingConfigunion, andset_max_thinking_tokensis the real mechanism.Types:
SDKControlSetModelRequest,SDKControlSetMaxThinkingTokensRequest, andSDKControlApplyFlagSettingsRequestto theSDKControlRequestunion.set_modelwas previously dispatched as an untyped dict, so this also closes the parity gap the issue called out.ThinkingDisplay.Tests
Adds 9 tests in
tests/test_streaming_client.pycovering the forwarded wire shape, the not-connected guard for each method, and the omit, explicit-null, and explicit-value cases forthinking_display.Verification
python -m ruff check src/ tests/: passespython -m ruff format src/ tests/ --check: passespython -m mypy src/: passespython -m pytest tests/: 1003 passed, 5 skipped