Skip to content

Add 'auto' to PermissionMode type#785

Open
qing-ant wants to merge 2 commits intomainfrom
add-auto-permission-mode
Open

Add 'auto' to PermissionMode type#785
qing-ant wants to merge 2 commits intomainfrom
add-auto-permission-mode

Conversation

@qing-ant
Copy link
Copy Markdown
Contributor

@qing-ant qing-ant commented Apr 4, 2026

Summary

Adds "auto" to the PermissionMode Literal type, bringing the Python SDK to parity with the TypeScript SDK (v0.2.91) and the CLI's EXTERNAL_PERMISSION_MODES.

Problem

The CLI binary (v2.1.90+) and the TypeScript SDK (v0.2.91) both support "auto" as a valid permission mode, but the Python SDK's PermissionMode type doesn't include it. Users who set permission_mode="auto" get a type error even though the underlying CLI accepts it.

Changes

  • src/claude_agent_sdk/types.py: Added "auto" to PermissionMode = Literal[...]
  • tests/test_types.py: Added test case for permission_mode="auto" in test_claude_code_options_with_permission_mode

Verification

  • Confirmed 'auto' is in EXTERNAL_PERMISSION_MODES in the CLI source (src/types/permissions.ts)
  • Confirmed TypeScript SDK v0.2.91 already added 'auto' to its public PermissionMode type
  • The Python SDK passes permission_mode as --permission-mode <value> to the CLI subprocess with no SDK-side validation — this is purely a type annotation fix

Copy link
Copy Markdown
Contributor Author

qing-ant commented Apr 4, 2026

E2E Verification

CLI source verification (src/types/permissions.ts at cli-internal HEAD):

export const EXTERNAL_PERMISSION_MODES = [
  'acceptEdits',
  'auto',
  'bypassPermissions',
  'default',
  'dontAsk',
  'plan',
] as const

auto is in the CLI's external permission modes and is validated server-side. The Python SDK passes permission_mode as --permission-mode <value> directly to the CLI subprocess (subprocess_cli.py), so this is a type-annotation-only fix with no behavioral change.

TS SDK parity: TypeScript SDK v0.2.91 already added 'auto' to its public PermissionMode type.

Note: Live e2e test with ANTHROPIC_API_KEY was not possible in this environment (DNS blocks pip/network). The fix is a type annotation change only — the CLI already accepts auto at runtime.


Generated by Claude Code

Copy link
Copy Markdown
Contributor Author

qing-ant commented Apr 4, 2026

E2E Test Results

Test: CLI validation of --permission-mode auto

# The Python SDK passes permission_mode directly as --permission-mode <value>
# to the CLI subprocess (subprocess_cli.py:L~130).
# This test verifies the CLI accepts 'auto' as a valid permission mode.

import subprocess

# Test 1: Invalid mode is rejected
result = subprocess.run(
    ['claude', '--permission-mode', 'invalid_mode', '-p', 'test', '--output-format', 'stream-json'],
    capture_output=True, text=True, timeout=5
)
print(f"Invalid mode exit code: {result.returncode}")
print(f"Error: {result.stderr.strip()}")
# Expected: error listing valid choices including 'auto'

# Test 2: 'auto' is accepted (no validation error)
# The CLI would proceed to authenticate and run — the key point is
# it doesn't reject 'auto' like it rejects 'invalid_mode'

Terminal output

$ claude --permission-mode invalid_mode -p 'test' --output-format stream-json --max-turns 1
error: option '--permission-mode <mode>' argument 'invalid_mode' is invalid. Allowed choices are acceptEdits, auto, bypassPermissions, default, dontAsk, plan, bubble.

$ claude --version
2.1.93-dev.20260404.t004057.sha6ac73e5 (Claude Code)

The CLI explicitly lists auto as a valid choice. The Python SDK's PermissionMode type is purely a type annotation — the value is passed through to the CLI as --permission-mode auto with no SDK-side validation.

Summary: auto is a valid CLI permission mode (confirmed by CLI argument parser). This PR adds it to the Python SDK's type annotation to match.


Generated by Claude Code

Copy link
Copy Markdown
Contributor

@claude claude bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM — simple type annotation fix to sync Python SDK with CLI and TypeScript SDK parity.

Extended reasoning...

Overview\nThis PR modifies two files: adds to the Literal type in and adds a corresponding test case in . The change is purely additive and type-annotation-only — the SDK passes directly to the CLI subprocess without SDK-side validation.\n\n### Security risks\nNone. This is a type annotation change only. The CLI already accepts at runtime and validates it server-side. No auth, crypto, or permission logic is modified.\n\n### Level of scrutiny\nMinimal scrutiny required. The change is mechanical — it adds one string literal to a type and one test assertion. It's verified against the CLI source () and the TypeScript SDK which already has parity. The only bug found is a documentation nit (docstrings in and not updated), which is already captured as inline comments.\n\n### Other factors\nThe test coverage is updated to include the new value. The PR description provides thorough verification. The nit about missing docstring updates is minor and doesn't affect correctness.

Copy link
Copy Markdown
Contributor

@claude claude bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM — both docstrings have been updated to include 'auto', addressing my prior feedback.

Extended reasoning...

Overview

This PR adds 'auto' to the PermissionMode Literal type in types.py, updates the docstrings in query.py and client.py to enumerate all six valid modes, and adds a test case. Four files are touched; all changes are documentation/type annotation only — no runtime logic is modified.

Security risks

None. This is a type annotation fix; the value is passed through unchanged to the CLI subprocess. No auth, crypto, or permissions logic is altered.

Level of scrutiny

Low. The change is purely additive (one new string literal, two docstring additions, one test assertion) and mirrors an existing TS SDK change. My previous review flagged the missing docstring updates; those have been addressed in the current diff.

Other factors

My prior inline comment flagged the docstring gap; the PR diff shows both query.py and client.py now include the 'auto' bullet. The test coverage is adequate. No outstanding concerns remain.

Copy link
Copy Markdown
Contributor Author

qing-ant commented Apr 5, 2026

Live E2E proof (real API call)

import anyio
from claude_agent_sdk import query, ClaudeAgentOptions, ResultMessage, SystemMessage

async def main():
    opts = ClaudeAgentOptions(
        model="claude-haiku-4-5",
        permission_mode="auto",
        max_turns=1,
    )
    async for msg in query(prompt="Reply with exactly: auto-mode-ok", options=opts):
        if isinstance(msg, SystemMessage) and msg.subtype == "init":
            print(f"init: permissionMode={msg.data.get('permissionMode')}")
        if isinstance(msg, ResultMessage):
            print(f"result: subtype={msg.subtype} is_error={msg.is_error} text={msg.result!r}")

anyio.run(main)

Output (this branch, CLI 2.1.93):

init: permissionMode=auto
result: subtype=success is_error=False text='auto-mode-ok'

Before (main): mypy/pyright reject permission_mode="auto":

Argument of type "Literal['auto']" cannot be assigned to parameter "permission_mode"
of type "PermissionMode | None"

After (this branch): type checks pass; --permission-mode auto is accepted by the CLI subprocess and the query round-trips successfully through the real API.


Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant