Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 22 additions & 22 deletions docs/developers/sdk-python.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,28 +139,28 @@ with query_sync(

### `QueryOptions`

| Option | Type / values | Description |
| -------------------------- | ---------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| `cwd` | `str` | Working directory for the CLI process. |
| `model` | `str` | Model override for this SDK session. |
| `path_to_qwen_executable` | `str` | `qwen`, an explicit binary path, or a `.js` CLI bundle. |
| `permission_mode` | `default`, `plan`, `auto-edit`, `yolo` | Tool execution approval mode. `yolo` auto-approves all tools; use it only in trusted or sandboxed environments. |
| `can_use_tool` | async callback | Custom permission callback for tool requests. |
| `env` | `dict[str, str]` | Extra environment variables passed to the CLI process. |
| `system_prompt` | `str` | Override the system prompt. |
| `append_system_prompt` | `str` | Append extra instructions to the system prompt. |
| `debug` | `bool` | Forward CLI stderr to stderr when no `stderr` hook exists. |
| `max_session_turns` | `int` | Maximum turns before the CLI ends the session. |
| `core_tools` | `list[str]` | Restrict the available tool set. |
| `exclude_tools` | `list[str]` | Exclude matching tools. |
| `allowed_tools` | `list[str]` | Allow matching tools without callback approval. |
| `auth_type` | `openai`, `anthropic`, `qwen-oauth`, `gemini`, `vertex-ai` | Authentication mode passed to the CLI. |
| `include_partial_messages` | `bool` | Emit partial assistant stream events. |
| `resume` | UUID string | Resume a known session id. |
| `continue_session` | `bool` | Continue the latest CLI session. |
| `session_id` | UUID string | Start or correlate a session with a known id. |
| `timeout` | mapping | Timeouts in seconds. |
| `stderr` | callable | Receives CLI stderr lines. |
| Option | Type / values | Description |
| -------------------------- | ---------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `cwd` | `str` | Working directory for the CLI process. |
| `model` | `str` | Model override for this SDK session. |
| `path_to_qwen_executable` | `str` | `qwen`, an explicit binary path, or a `.js` CLI bundle. |
| `permission_mode` | `default`, `plan`, `auto-edit`, `auto`, `yolo` | Tool execution approval mode. `auto` lets an LLM classifier approve tool calls; `yolo` auto-approves all tools; use it only in trusted or sandboxed environments. |
| `can_use_tool` | async callback | Custom permission callback for tool requests. |
| `env` | `dict[str, str]` | Extra environment variables passed to the CLI process. |
| `system_prompt` | `str` | Override the system prompt. |
| `append_system_prompt` | `str` | Append extra instructions to the system prompt. |
| `debug` | `bool` | Forward CLI stderr to stderr when no `stderr` hook exists. |
| `max_session_turns` | `int` | Maximum turns before the CLI ends the session. |
| `core_tools` | `list[str]` | Restrict the available tool set. |
| `exclude_tools` | `list[str]` | Exclude matching tools. |
| `allowed_tools` | `list[str]` | Allow matching tools without callback approval. |
| `auth_type` | `openai`, `anthropic`, `qwen-oauth`, `gemini`, `vertex-ai` | Authentication mode passed to the CLI. |
| `include_partial_messages` | `bool` | Emit partial assistant stream events. |
| `resume` | UUID string | Resume a known session id. |
| `continue_session` | `bool` | Continue the latest CLI session. |
| `session_id` | UUID string | Start or correlate a session with a known id. |
| `timeout` | mapping | Timeouts in seconds. |
| `stderr` | callable | Receives CLI stderr lines. |

Use only one of `resume`, `continue_session`, or `session_id` in a request. The
SDK raises `ValidationError` if these session options are combined.
Expand Down
1 change: 1 addition & 0 deletions packages/sdk-java/qwencode/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ The SDK supports different permission modes for controlling tool execution:
- **`default`**: Write tools are denied unless approved via `canUseTool` callback or in `allowedTools`. Read-only tools execute without confirmation.
- **`plan`**: Blocks all write tools, instructing AI to present a plan first.
- **`auto-edit`**: Auto-approve edit tools (`edit`, `write_file`, `notebook_edit`) while other tools require confirmation.
- **`auto`**: An LLM classifier approves tool calls.
- **`yolo`**: All tools execute automatically without confirmation.

### Session Event Consumers and Assistant Content Consumers
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ public enum PermissionMode {
* Auto-edit permission mode.
*/
AUTO_EDIT("auto-edit"),
/**
* Auto permission mode.
*/
AUTO("auto"),
/**
* YOLO permission mode.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ export interface SDKPartialAssistantMessage {
parent_tool_use_id: string | null;
}

export type PermissionMode = 'default' | 'plan' | 'auto-edit' | 'yolo';
export type PermissionMode = 'default' | 'plan' | 'auto-edit' | 'auto' | 'yolo';

/**
* TODO: Align with `ToolCallConfirmationDetails`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public void shouldBeReturnQwenPermissionModeValue() {
assertEquals("default", PermissionMode.DEFAULT.getValue());
assertEquals("plan", PermissionMode.PLAN.getValue());
assertEquals("auto-edit", PermissionMode.AUTO_EDIT.getValue());
assertEquals("auto", PermissionMode.AUTO.getValue());
assertEquals("yolo", PermissionMode.YOLO.getValue());
}

Expand Down
5 changes: 3 additions & 2 deletions packages/sdk-python/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,9 @@ Common fields:
- `path_to_qwen_executable`: `qwen`, an absolute binary path, or a `.js` CLI
bundle
- `model`: model override for this session
- `permission_mode`: one of `default`, `plan`, `auto-edit`, or `yolo`; `yolo`
auto-approves all tools, so use it only in trusted or sandboxed environments
- `permission_mode`: one of `default`, `plan`, `auto-edit`, `auto`, or `yolo`;
`auto` lets an LLM classifier approve tool calls; `yolo` auto-approves all
tools, so use it only in trusted or sandboxed environments
- `env`: extra environment variables passed to the CLI process
- `system_prompt` / `append_system_prompt`: override or extend the system
prompt
Expand Down
2 changes: 1 addition & 1 deletion packages/sdk-python/src/qwen_code_sdk/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

from typing_extensions import NotRequired

PermissionMode: TypeAlias = Literal["default", "plan", "auto-edit", "yolo"]
PermissionMode: TypeAlias = Literal["default", "plan", "auto-edit", "auto", "yolo"]
AuthType: TypeAlias = Literal[
"openai",
"anthropic",
Expand Down
16 changes: 10 additions & 6 deletions packages/sdk-python/src/qwen_code_sdk/validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,22 @@
from __future__ import annotations

from collections.abc import Callable
from typing import get_args
from uuid import RFC_4122, UUID

from .errors import ValidationError
from .types import (
AuthType,
Effort,
PermissionMode,
QueryOptions,
_validate_can_use_tool_callable,
_validate_stderr_callable,
)

_VALID_PERMISSION_MODES = {"default", "plan", "auto-edit", "yolo"}
_VALID_AUTH_TYPES = {"openai", "anthropic", "qwen-oauth", "gemini", "vertex-ai"}
_VALID_EFFORTS = {"low", "medium", "high", "xhigh", "max"}
_VALID_PERMISSION_MODES = set(get_args(PermissionMode))
_VALID_AUTH_TYPES = set(get_args(AuthType))
_VALID_EFFORTS = set(get_args(Effort))


_RESERVED_CLI_FLAGS = frozenset(
Expand Down Expand Up @@ -87,19 +91,19 @@ def validate_query_options(options: QueryOptions) -> None:
):
raise ValidationError(
f"Invalid permission_mode: {options.permission_mode!r}. "
"Expected one of: default, plan, auto-edit, yolo."
f"Expected one of: {', '.join(get_args(PermissionMode))}."
)

if options.auth_type and options.auth_type not in _VALID_AUTH_TYPES:
raise ValidationError(
f"Invalid auth_type: {options.auth_type!r}. "
"Expected one of: openai, anthropic, qwen-oauth, gemini, vertex-ai."
f"Expected one of: {', '.join(get_args(AuthType))}."
)

if options.effort and options.effort not in _VALID_EFFORTS:
raise ValidationError(
f"Invalid effort: {options.effort!r}. "
"Expected one of: low, medium, high, xhigh, max."
f"Expected one of: {', '.join(get_args(Effort))}."
)

_validate_optional_callable(options.can_use_tool, _validate_can_use_tool_callable)
Expand Down
17 changes: 16 additions & 1 deletion packages/sdk-python/tests/unit/test_validation.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from __future__ import annotations

import re
from typing import Any, cast

import pytest
Expand Down Expand Up @@ -74,8 +75,22 @@ def test_accepts_canonical_session_id_in_either_case() -> None:
validate_query_options(QueryOptions(session_id=VALID_UUID.upper()))


@pytest.mark.parametrize(
"mode",
["default", "plan", "auto-edit", "auto", "yolo"],
)
def test_accepts_valid_permission_modes(mode: str) -> None:
validate_query_options(QueryOptions.from_mapping({"permission_mode": mode}))


def test_rejects_invalid_permission_mode() -> None:
with pytest.raises(ValidationError, match="Invalid permission_mode"):
with pytest.raises(
ValidationError,
match=re.escape(
"Invalid permission_mode: 'unsafe-mode'. "
"Expected one of: default, plan, auto-edit, auto, yolo."
),
):
validate_query_options(
QueryOptions.from_mapping({"permission_mode": "unsafe-mode"})
)
Expand Down
Loading