qoder-agent-sdk 1.0.2__tar.gz → 1.0.8__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/PKG-INFO +1 -1
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/pyproject.toml +1 -1
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/src/qoder_agent_sdk/__init__.py +38 -7
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/src/qoder_agent_sdk/_cli_version.py +1 -1
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/src/qoder_agent_sdk/_internal/client.py +2 -7
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/src/qoder_agent_sdk/_internal/cloud_agent.py +7 -3
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/src/qoder_agent_sdk/_internal/query.py +254 -5
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/src/qoder_agent_sdk/_internal/transport/subprocess_cli.py +10 -15
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/src/qoder_agent_sdk/_version.py +1 -1
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/src/qoder_agent_sdk/client.py +47 -7
- qoder_agent_sdk-1.0.8/src/qoder_agent_sdk/plugins.py +177 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/src/qoder_agent_sdk/types.py +188 -82
- qoder_agent_sdk-1.0.8/tests/plugins_loading_control/unit/test_global_plugins.py +178 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/test_client.py +2 -2
- qoder_agent_sdk-1.0.8/tests/test_initialize_model_catalog.py +165 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/test_tool_callbacks.py +27 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/test_transport.py +53 -139
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/test_types.py +13 -0
- qoder_agent_sdk-1.0.8/tests/test_usage_info.py +263 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/.gitignore +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/LICENSE +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/README.md +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/src/qoder_agent_sdk/_bundled/.gitignore +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/src/qoder_agent_sdk/_errors.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/src/qoder_agent_sdk/_internal/__init__.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/src/qoder_agent_sdk/_internal/auth_helpers.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/src/qoder_agent_sdk/_internal/mcp_handler.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/src/qoder_agent_sdk/_internal/mcp_serialize.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/src/qoder_agent_sdk/_internal/message_parser.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/src/qoder_agent_sdk/_internal/sdk_mcp_transport.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/src/qoder_agent_sdk/_internal/session_mutations.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/src/qoder_agent_sdk/_internal/sessions.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/src/qoder_agent_sdk/_internal/transport/__init__.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/src/qoder_agent_sdk/auth.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/src/qoder_agent_sdk/py.typed +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/src/qoder_agent_sdk/query.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/src/qoder_agent_sdk/settings.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/__init__.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/_shared/__init__.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/_shared/dotenv.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/_shared/e2e.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/_shared/e2e_env.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/_shared/fake_qodercli.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/agents/__init__.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/agents/conftest.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/agents/test_agent_description.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/agents/test_agent_disallowed_tools.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/agents/test_agent_effort.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/agents/test_agent_initial_prompt.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/agents/test_agent_max_turns.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/agents/test_agent_mcp_servers.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/agents/test_agent_model.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/agents/test_agent_permission_mode.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/agents/test_agent_prompt.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/agents/test_agent_skills.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/agents/test_agent_tools.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/agents/test_boundary_disallowed_tools_empty.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/agents/test_boundary_effort_max.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/agents/test_boundary_empty_agents.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/agents/test_boundary_initial_prompt_empty.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/agents/test_boundary_many_agents.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/agents/test_boundary_max_turns_zero.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/agents/test_boundary_multi_agent_task_isolation.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/agents/test_boundary_permission_mode_default.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/agents/test_boundary_tools_empty.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/agents/test_boundary_tools_non_existent.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/agents/test_boundary_unregistered_session_agent.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/agents/test_register_custom_subagent.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/agents/test_session_agent.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/agents/test_session_agent_from_sdk_agents.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/agents/test_subagent_isolated_context.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/agents/test_subagent_tool_call_agent_selection.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/agents/test_subagent_tool_call_prompt.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/agents/test_subagent_tool_call_timeout.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/agents/test_supported_agents_list.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/auth/contract/test_subprocess_auth.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/auth/e2e/test_access_token_auth.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/auth/e2e/test_job_token_auth.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/auth/e2e/test_qodercli_auth.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/auth/unit/test_auth.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/auth/unit/test_dotenv.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/cloud_agent/__init__.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/cloud_agent/functional/__init__.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/cloud_agent/functional/_helpers.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/cloud_agent/functional/test_client_multi_turn_session.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/cloud_agent/functional/test_create_agent_session_stream.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/cloud_agent/functional/test_multi_turn_session.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/cloud_agent/test_cloud_agent_query.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/conftest.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/hooks/__init__.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/hooks/conftest.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/hooks/functional/__init__.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/hooks/functional/test_compact.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/hooks/functional/test_config_change.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/hooks/functional/test_cwd_changed.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/hooks/functional/test_decision_merge.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/hooks/functional/test_elicitation.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/hooks/functional/test_elicitation_result.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/hooks/functional/test_file_changed.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/hooks/functional/test_hooks_e2e.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/hooks/functional/test_instructions_loaded.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/hooks/functional/test_notification.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/hooks/functional/test_permission_denied.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/hooks/functional/test_permission_request.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/hooks/functional/test_post_tool_use.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/hooks/functional/test_post_tool_use_failure.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/hooks/functional/test_pre_tool_use.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/hooks/functional/test_session_end.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/hooks/functional/test_session_start.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/hooks/functional/test_setup.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/hooks/functional/test_stop.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/hooks/functional/test_stop_failure.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/hooks/functional/test_subagent.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/hooks/functional/test_task_completed.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/hooks/functional/test_task_created.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/hooks/functional/test_teammate_idle.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/hooks/functional/test_user_prompt_submit.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/hooks/functional/test_worktree.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/permissions/__init__.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/permissions/_e2e.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/permissions/test_can_use_tool.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/permissions/test_client_and_streaming.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/permissions/test_external_prompt_tool.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/permissions/test_options_and_modes.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/permissions/test_permission_modes.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/permissions/test_permission_request_hook_allow_skips_can_use_tool.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/permissions/test_permission_request_hook_deny_fires_denied.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/permissions/test_permission_updates.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/permissions/test_settings_and_mcp_policy.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/permissions/test_streaming_async_iterable_can_use_tool.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/plugins_loading_control/__init__.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/plugins_loading_control/conftest.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/plugins_loading_control/test_bogus_plugin_dir.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/plugins_loading_control/test_broken_plugin_content.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/plugins_loading_control/test_local_plugin_init.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/plugins_loading_control/test_multiple_plugin_dirs.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/plugins_loading_control/test_plugin_contributes_resources.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/plugins_loading_control/test_reload_plugins_commands.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/plugins_loading_control/test_reload_plugins_error_count.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/plugins_loading_control/test_reload_plugins_response_shape.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/plugins_loading_control/unit/__init__.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/plugins_loading_control/unit/test_plugin_dir_argv.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/plugins_loading_control/unit/test_reload_plugins_control_request.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/plugins_loading_control/unit/test_settings_passthrough.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_io/test_at_file_reference.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_io/test_client_multi_turn_io.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_io/test_compact_context.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_io/test_multimodal_content_blocks.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_io/test_partial_stream_events.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_io/test_query_stream_turns_io.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_io/test_server_output_style_info.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_io/test_stream_user_message_io.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_io/test_string_prompt_io.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_io/test_system_prompt.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/__init__.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/conftest.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/fixtures/__init__.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/fixtures/elicit_mcp_server.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/fixtures/fake_oauth_mcp_server.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/fixtures/minimal_mcp_server.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/fixtures/sse_mcp_server.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/functional/__init__.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/functional/test_allowed_mcp_server_names_exempts_sdk.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/functional/test_allowed_mcp_server_names_filters_stdio.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/functional/test_control_request_timeout_does_not_poison_runner.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/functional/test_elicitation_hook_probe.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/functional/test_elicitation_result_hook_probe.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/functional/test_elicitation_url_mode_unsupported.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/functional/test_http_server_public_deepwiki.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/functional/test_http_sse_bogus_url_not_crashing.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/functional/test_mcp_server_status_metadata_fields.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/functional/test_mcp_server_status_point_in_time_snapshot.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/functional/test_mcp_status_empty_when_no_servers.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/functional/test_mixed_inprocess_and_stdio_servers.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/functional/test_mixed_three_way_transports.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/functional/test_oauth_authenticate_custom_redirect_uri.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/functional/test_oauth_authenticate_returns_url_with_dcr.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/functional/test_oauth_authenticate_silent_refresh.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/functional/test_oauth_clear_auth_resets_to_needs_auth.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/functional/test_oauth_inject_token_connects.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/functional/test_oauth_needs_auth_status.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/functional/test_oauth_submit_callback_completes_flow.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/functional/test_oauth_token_persists_across_sessions.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/functional/test_permission_prompt_tool_probe.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/functional/test_sdk_mcp_annotations_not_echoed_in_status.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/functional/test_sdk_mcp_close_tears_down_transport.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/functional/test_sdk_mcp_multi_turn_reuse.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/functional/test_sdk_mcp_multiple_servers_isolated.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/functional/test_sdk_mcp_server_connected_status.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/functional/test_sdk_mcp_tool_description_passthrough.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/functional/test_server_name_special_chars_prefix.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/functional/test_sse_server_headers_and_connection.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/functional/test_stdio_grandchild_reclaim_on_close.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/functional/test_stdio_server_lifecycle.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/functional/test_strict_mcp_config_blocks_external_config.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/unit/__init__.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/unit/test_cli_args_allowed_mcp_server_names.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/unit/test_cli_args_mcp_config.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/unit/test_cli_args_permission_prompt_tool.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/unit/test_cli_args_strict_mcp_config.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/unit/test_create_sdk_mcp_server.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/unit/test_handler_accepts_extra_helper.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/unit/test_inbound_elicitation_callback.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/unit/test_inbound_elicitation_default_cancel.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/unit/test_inbound_get_model_policy.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/unit/test_mcp_authenticate_response_variants.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/unit/test_mcp_server_status_request.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/unit/test_mcp_server_status_timeout.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/unit/test_mcp_toggle_and_reconnect_requests.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/unit/test_sdk_mcp_handler_extra_signal.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/unit/test_sdk_mcp_handler_non_content_normalization.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_mcp/unit/test_sdk_server_split_from_process_servers.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_model_policy/__init__.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_model_policy/functional/__init__.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_model_policy/functional/conftest.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_model_policy/functional/test_list_available_models_rich_fields.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_model_policy/functional/test_model_policy_e2e.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_model_policy/functional/test_model_selection_e2e_logging.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_model_policy/functional/test_model_selection_logging.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_model_policy/unit/__init__.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_model_policy/unit/test_list_byok_providers.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/query_model_policy/unit/test_pull_suppresses_model_flag.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/rewind_api/__init__.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/rewind_api/conftest.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/rewind_api/test_capture_checkpoint_uuid_from_stream.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/rewind_api/test_enable_file_checkpointing.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/rewind_api/test_mid_stream_rewind.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/rewind_api/test_multiple_checkpoints_rewind.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/rewind_api/test_replay_user_messages_checkpoint_uuid.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/rewind_api/test_resume_session_rewind.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/rewind_api/test_rewind_bash_changes_not_tracked.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/rewind_api/test_rewind_cross_session_rejected.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/rewind_api/test_rewind_directory_ops_not_undone.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/rewind_api/test_rewind_dry_run_with_checkpoint.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/rewind_api/test_rewind_files_success.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/rewind_api/test_rewind_local_files_only.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/rewind_api/test_rewind_malformed_message_id.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/rewind_api/test_rewind_preserves_conversation.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/rewind_api/test_rewind_stats.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/rewind_api/test_rewind_unknown_message.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/rewind_api/test_rewind_without_checkpointing.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/session_control/test_continue_latest_session.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/session_control/test_fork_session.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/session_control/test_new_client_session.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/session_control/test_new_query_session.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/session_control/test_new_session_with_session_id.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/session_control/test_resume_session.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/skills_loading_control/__init__.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/skills_loading_control/conftest.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/skills_loading_control/test_agent_preloaded_skills.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/skills_loading_control/test_builtin_skills_visibility.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/skills_loading_control/test_default_skills_policy.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/skills_loading_control/test_enable_all_skills.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/skills_loading_control/test_enable_named_skills.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/skills_loading_control/test_plugin_skill_in_init.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/skills_loading_control/test_settings_skill_overrides.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/skills_loading_control/unit/__init__.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/skills_loading_control/unit/test_skills_argv.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/test_build_wheel.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/test_control_request_timeout.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/test_download_cli.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/test_errors.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/test_integration.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/test_mcp_dynamic.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/test_mcp_large_output.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/test_mcp_oauth.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/test_message_parser.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/test_permission_alignment.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/test_query.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/test_rate_limit_event_repro.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/test_sdk_mcp_integration.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/test_sdk_mcp_routing.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/test_session_mutations.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/test_sessions.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/test_streaming_client.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/test_subprocess_buffering.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/__init__.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/conftest.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_boundary_allowedTools_disallowedTools_conflict_priority.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_boundary_canUseTool_throws_error.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_boundary_concurrent_multiple_tool_uses.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_boundary_createSdkMcpServer_many_tools.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_boundary_handler_long_running_vs_controlRequestTimeoutMs.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_boundary_handler_returns_large_content.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_boundary_handler_returns_malformed_result.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_boundary_handler_returns_undefined.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_boundary_model_calls_unknown_tool_functional.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_boundary_tool_input_deeply_nested_schema.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_boundary_tool_input_many_fields.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_createSdkMcpServer_empty_tools.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_createSdkMcpServer_mcpServers_option.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_createSdkMcpServer_multiple_tools.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_createSdkMcpServer_name_routes_tool.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_createSdkMcpServer_version.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_error_handler_isError_true.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_error_handler_isError_with_structured_data.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_error_handler_throws_async_rejection.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_error_handler_throws_non_Error.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_error_handler_throws_sync_Error.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_error_isError_allows_agent_retry.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_permission_allowedTools_permits_mcp_tool.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_permission_allowedTools_server_pattern.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_permission_canUseTool_allow_passthrough.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_permission_canUseTool_conditional_on_input.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_permission_canUseTool_deny.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_permission_canUseTool_deny_with_interrupt.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_permission_canUseTool_receives_mcp_toolName_format.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_permission_canUseTool_updatedInput.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_permission_canUseTool_updatedPermissions.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_permission_disallowedTools_blocks_tool.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_permission_mode_bypassPermissions_with_mcp_tool.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_permission_postToolUse_hook_additionalContext.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_permission_preToolUse_hook_updatedInput.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_return_empty_content_array.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_return_image_content.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_return_multiple_content_blocks.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_return_text_content.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_tool_destructiveHint.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_tool_handler_receives_args_and_returns_content.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_tool_input_schema_describe.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_tool_input_schema_nested.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_tool_input_schema_zod_shape.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_tool_name_and_description.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_tool_openWorldHint.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_tool_readOnlyHint.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_unit_createSdkMcpServer.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_unit_createSdkMcpServer_duplicate_tool_name.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_unit_createSdkMcpServer_empty_server_name.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_unit_createSdkMcpServer_empty_tool_description.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_unit_createSdkMcpServer_empty_tool_name.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_unit_mcp_handler.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_unit_sdk_mcp_transport.py +0 -0
- {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/tests/tools/test_unit_tool_helper.py +0 -0
|
@@ -61,6 +61,14 @@ from .auth import (
|
|
|
61
61
|
qodercli_auth,
|
|
62
62
|
)
|
|
63
63
|
from .client import QoderSDKClient
|
|
64
|
+
from .plugins import (
|
|
65
|
+
PluginError,
|
|
66
|
+
disable_plugin,
|
|
67
|
+
enable_plugin,
|
|
68
|
+
install_plugin,
|
|
69
|
+
list_plugins,
|
|
70
|
+
uninstall_plugin,
|
|
71
|
+
)
|
|
64
72
|
from .query import query
|
|
65
73
|
from .settings import filter_escalating_default_mode
|
|
66
74
|
from .types import (
|
|
@@ -109,7 +117,9 @@ from .types import (
|
|
|
109
117
|
HookJSONOutput,
|
|
110
118
|
HookMatcher,
|
|
111
119
|
HookSpecificOutput,
|
|
120
|
+
InstallPluginResult,
|
|
112
121
|
InstructionsLoadedHookInput,
|
|
122
|
+
LocalizedModelText,
|
|
113
123
|
McpOAuthCallbackUrlResolution,
|
|
114
124
|
McpOAuthCodeResolution,
|
|
115
125
|
McpOAuthRequest,
|
|
@@ -135,6 +145,7 @@ from .types import (
|
|
|
135
145
|
ModelPolicyContext,
|
|
136
146
|
ModelPolicyProvider,
|
|
137
147
|
ModelPolicyResult,
|
|
148
|
+
ModelPromotion,
|
|
138
149
|
ModelThinkingConfig,
|
|
139
150
|
ModelThinkingDisabled,
|
|
140
151
|
ModelThinkingEnabled,
|
|
@@ -154,7 +165,9 @@ from .types import (
|
|
|
154
165
|
PermissionResultAllow,
|
|
155
166
|
PermissionResultDeny,
|
|
156
167
|
PermissionUpdate,
|
|
168
|
+
PluginDetails,
|
|
157
169
|
PluginInfo,
|
|
170
|
+
PluginResources,
|
|
158
171
|
PostCompactHookInput,
|
|
159
172
|
PostToolUseFailureHookInput,
|
|
160
173
|
PostToolUseFailureHookSpecificOutput,
|
|
@@ -174,9 +187,6 @@ from .types import (
|
|
|
174
187
|
ResolvedSettingsSource,
|
|
175
188
|
ResultMessage,
|
|
176
189
|
RewindFilesResult,
|
|
177
|
-
SandboxIgnoreViolations,
|
|
178
|
-
SandboxNetworkConfig,
|
|
179
|
-
SandboxSettings,
|
|
180
190
|
SdkBeta,
|
|
181
191
|
SDKCapabilities,
|
|
182
192
|
SDKControlGetByokConfigRequest,
|
|
@@ -187,6 +197,8 @@ from .types import (
|
|
|
187
197
|
SDKPermissionDeniedMessage,
|
|
188
198
|
SdkPluginConfig,
|
|
189
199
|
SDKSessionInfo,
|
|
200
|
+
ServerModelJson,
|
|
201
|
+
ServerModelJsonValue,
|
|
190
202
|
SessionCreateParams,
|
|
191
203
|
SessionEndHookInput,
|
|
192
204
|
SessionMessage,
|
|
@@ -217,6 +229,11 @@ from .types import (
|
|
|
217
229
|
ToolProgressMessage,
|
|
218
230
|
ToolResultBlock,
|
|
219
231
|
ToolUseBlock,
|
|
232
|
+
UninstallPluginResult,
|
|
233
|
+
UsageAddOnQuotaBucket,
|
|
234
|
+
UsageInfo,
|
|
235
|
+
UsageOrgResourcePackage,
|
|
236
|
+
UsageQuotaBucket,
|
|
220
237
|
UserMessage,
|
|
221
238
|
UserPromptSubmitHookInput,
|
|
222
239
|
UserPromptSubmitHookSpecificOutput,
|
|
@@ -823,6 +840,10 @@ __all__ = [
|
|
|
823
840
|
"ContentBlock",
|
|
824
841
|
"ContextUsageCategory",
|
|
825
842
|
"ContextUsageResponse",
|
|
843
|
+
"UsageAddOnQuotaBucket",
|
|
844
|
+
"UsageInfo",
|
|
845
|
+
"UsageOrgResourcePackage",
|
|
846
|
+
"UsageQuotaBucket",
|
|
826
847
|
# Tool callbacks
|
|
827
848
|
"CanUseTool",
|
|
828
849
|
"ToolPermissionContext",
|
|
@@ -902,7 +923,17 @@ __all__ = [
|
|
|
902
923
|
# Plugin support
|
|
903
924
|
"SdkPluginConfig",
|
|
904
925
|
"PluginInfo",
|
|
926
|
+
"PluginDetails",
|
|
927
|
+
"PluginResources",
|
|
928
|
+
"InstallPluginResult",
|
|
929
|
+
"UninstallPluginResult",
|
|
905
930
|
"ReloadPluginsResponse",
|
|
931
|
+
"list_plugins",
|
|
932
|
+
"enable_plugin",
|
|
933
|
+
"disable_plugin",
|
|
934
|
+
"install_plugin",
|
|
935
|
+
"uninstall_plugin",
|
|
936
|
+
"PluginError",
|
|
906
937
|
# File checkpointing
|
|
907
938
|
"RewindFilesResult",
|
|
908
939
|
# Session listing
|
|
@@ -919,10 +950,6 @@ __all__ = [
|
|
|
919
950
|
"ForkSessionResult",
|
|
920
951
|
# Beta support
|
|
921
952
|
"SdkBeta",
|
|
922
|
-
# Sandbox support
|
|
923
|
-
"SandboxSettings",
|
|
924
|
-
"SandboxNetworkConfig",
|
|
925
|
-
"SandboxIgnoreViolations",
|
|
926
953
|
# MCP Server Support
|
|
927
954
|
"create_sdk_mcp_server",
|
|
928
955
|
"tool",
|
|
@@ -948,6 +975,10 @@ __all__ = [
|
|
|
948
975
|
"ModelThinkingConfig",
|
|
949
976
|
"ModelThinkingDisabled",
|
|
950
977
|
"ModelThinkingEnabled",
|
|
978
|
+
"ModelPromotion",
|
|
979
|
+
"LocalizedModelText",
|
|
980
|
+
"ServerModelJson",
|
|
981
|
+
"ServerModelJsonValue",
|
|
951
982
|
"ModelPolicyContext",
|
|
952
983
|
"ModelPolicyProvider",
|
|
953
984
|
"ModelPolicyResult",
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"""Internal client implementation."""
|
|
2
2
|
|
|
3
3
|
import json
|
|
4
|
-
import os
|
|
5
4
|
from collections.abc import AsyncIterable, AsyncIterator
|
|
6
5
|
from dataclasses import asdict, replace
|
|
7
6
|
from typing import Any
|
|
@@ -14,7 +13,7 @@ from ..types import (
|
|
|
14
13
|
)
|
|
15
14
|
from .auth_helpers import get_fetch_job_token, once_callback
|
|
16
15
|
from .message_parser import parse_message
|
|
17
|
-
from .query import Query
|
|
16
|
+
from .query import Query, resolve_initialize_timeout
|
|
18
17
|
from .transport import Transport
|
|
19
18
|
from .transport.subprocess_cli import SubprocessCLITransport
|
|
20
19
|
|
|
@@ -99,11 +98,7 @@ class InternalClient:
|
|
|
99
98
|
for name, agent_def in configured_options.agents.items()
|
|
100
99
|
}
|
|
101
100
|
|
|
102
|
-
|
|
103
|
-
initialize_timeout_ms = int(
|
|
104
|
-
os.environ.get("QODER_STREAM_CLOSE_TIMEOUT", "60000")
|
|
105
|
-
)
|
|
106
|
-
initialize_timeout = max(initialize_timeout_ms / 1000.0, 60.0)
|
|
101
|
+
initialize_timeout = resolve_initialize_timeout()
|
|
107
102
|
|
|
108
103
|
# Create Query to handle control protocol
|
|
109
104
|
# Always use streaming mode internally (matching TypeScript SDK)
|
{qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.8}/src/qoder_agent_sdk/_internal/cloud_agent.py
RENAMED
|
@@ -768,9 +768,7 @@ class CloudAgentQuery:
|
|
|
768
768
|
if self._result_emitted or self._closed:
|
|
769
769
|
return
|
|
770
770
|
self._result_emitted = True
|
|
771
|
-
self._queue.put_nowait(
|
|
772
|
-
ResultMessage(**self._build_result_base(), **kwargs)
|
|
773
|
-
)
|
|
771
|
+
self._queue.put_nowait(ResultMessage(**self._build_result_base(), **kwargs))
|
|
774
772
|
|
|
775
773
|
def _build_result_base(self) -> dict[str, Any]:
|
|
776
774
|
elapsed_ms = int((time.monotonic() - self._started_at) * 1000)
|
|
@@ -936,6 +934,9 @@ class CloudAgentClientSession:
|
|
|
936
934
|
async def set_model(self, _model: str | None = None) -> None:
|
|
937
935
|
self._unsupported("set_model")
|
|
938
936
|
|
|
937
|
+
async def set_proxy(self, _proxy: str | None = None) -> None:
|
|
938
|
+
self._unsupported("set_proxy")
|
|
939
|
+
|
|
939
940
|
async def get_available_models(self) -> list[Any]:
|
|
940
941
|
self._unsupported("get_available_models")
|
|
941
942
|
|
|
@@ -987,6 +988,9 @@ class CloudAgentClientSession:
|
|
|
987
988
|
async def get_context_usage(self) -> Any:
|
|
988
989
|
self._unsupported("get_context_usage")
|
|
989
990
|
|
|
991
|
+
async def get_usage_info(self) -> None:
|
|
992
|
+
return None
|
|
993
|
+
|
|
990
994
|
async def _run_turn(self, prompt: str | AsyncIterable[dict[str, Any]]) -> None:
|
|
991
995
|
async with self._turn_lock:
|
|
992
996
|
if self._closed or self._turn_options is None:
|
|
@@ -36,11 +36,16 @@ from ..types import (
|
|
|
36
36
|
PermissionMode,
|
|
37
37
|
PermissionResultAllow,
|
|
38
38
|
PermissionResultDeny,
|
|
39
|
+
PluginDetails,
|
|
39
40
|
SDKControlPermissionRequest,
|
|
40
41
|
SDKControlRequest,
|
|
41
42
|
SDKControlResponse,
|
|
42
43
|
SDKHookCallbackRequest,
|
|
43
44
|
ToolPermissionContext,
|
|
45
|
+
UsageAddOnQuotaBucket,
|
|
46
|
+
UsageInfo,
|
|
47
|
+
UsageOrgResourcePackage,
|
|
48
|
+
UsageQuotaBucket,
|
|
44
49
|
)
|
|
45
50
|
from .mcp_serialize import serialize_mcp_servers
|
|
46
51
|
from .transport import Transport
|
|
@@ -50,6 +55,29 @@ if TYPE_CHECKING:
|
|
|
50
55
|
|
|
51
56
|
logger = logging.getLogger(__name__)
|
|
52
57
|
|
|
58
|
+
INITIALIZE_TIMEOUT_MS = 120_000
|
|
59
|
+
INITIALIZE_TIMEOUT = INITIALIZE_TIMEOUT_MS / 1000.0
|
|
60
|
+
CATALOG_READY_INITIALIZE_MIN_TIMEOUT_MS = INITIALIZE_TIMEOUT_MS
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def resolve_initialize_timeout() -> float:
|
|
64
|
+
"""Resolve the initialize timeout from env var or default.
|
|
65
|
+
|
|
66
|
+
Shared by ``QoderSDKClient.connect()`` and ``InternalClient.process_query()``
|
|
67
|
+
to avoid duplicating the env-var lookup and floor logic.
|
|
68
|
+
"""
|
|
69
|
+
_timeout_env = os.environ.get("QODER_STREAM_CLOSE_TIMEOUT")
|
|
70
|
+
initialize_timeout_ms = (
|
|
71
|
+
int(_timeout_env) if _timeout_env is not None else INITIALIZE_TIMEOUT_MS
|
|
72
|
+
)
|
|
73
|
+
return max(initialize_timeout_ms / 1000.0, 60.0)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
class ControlProtocolError(Exception):
|
|
77
|
+
def __init__(self, message: str, code: str | None = None) -> None:
|
|
78
|
+
super().__init__(message)
|
|
79
|
+
self.code = code
|
|
80
|
+
|
|
53
81
|
|
|
54
82
|
def _normalize_oauth_resolution(
|
|
55
83
|
resolution: McpOAuthResolution,
|
|
@@ -252,6 +280,174 @@ def _normalize_control_error(err: Exception) -> tuple[str, str | None]:
|
|
|
252
280
|
return message, None
|
|
253
281
|
|
|
254
282
|
|
|
283
|
+
def _error_payload_from_exception(err: Exception) -> dict[str, Any]:
|
|
284
|
+
message, code = _normalize_control_error(err)
|
|
285
|
+
payload: dict[str, Any] = {"type": "error", "error": message}
|
|
286
|
+
if code:
|
|
287
|
+
payload["code"] = code
|
|
288
|
+
return payload
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
def _exception_from_error_payload(message: dict[str, Any]) -> Exception:
|
|
292
|
+
error = message.get("error", "Unknown error")
|
|
293
|
+
code = message.get("code")
|
|
294
|
+
return ControlProtocolError(
|
|
295
|
+
error if isinstance(error, str) else str(error),
|
|
296
|
+
code if isinstance(code, str) and code else None,
|
|
297
|
+
)
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
def _record_or_none(value: Any) -> dict[str, Any] | None:
|
|
301
|
+
return value if isinstance(value, dict) else None
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
def _read_str(source: dict[str, Any] | None, key: str) -> str | None:
|
|
305
|
+
value = source.get(key) if source is not None else None
|
|
306
|
+
return value if isinstance(value, str) else None
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
def _read_bool(source: dict[str, Any] | None, key: str) -> bool | None:
|
|
310
|
+
value = source.get(key) if source is not None else None
|
|
311
|
+
return value if isinstance(value, bool) else None
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
def _read_number(source: dict[str, Any] | None, key: str) -> float | None:
|
|
315
|
+
value = source.get(key) if source is not None else None
|
|
316
|
+
if isinstance(value, bool):
|
|
317
|
+
return None
|
|
318
|
+
if isinstance(value, (int, float)):
|
|
319
|
+
return float(value)
|
|
320
|
+
if isinstance(value, str) and value.strip():
|
|
321
|
+
try:
|
|
322
|
+
return float(value)
|
|
323
|
+
except ValueError:
|
|
324
|
+
return None
|
|
325
|
+
return None
|
|
326
|
+
|
|
327
|
+
|
|
328
|
+
def _normalize_usage_quota_bucket(value: Any) -> UsageQuotaBucket | None:
|
|
329
|
+
source = _record_or_none(value)
|
|
330
|
+
if source is None:
|
|
331
|
+
return None
|
|
332
|
+
total = _read_number(source, "total")
|
|
333
|
+
used = _read_number(source, "used")
|
|
334
|
+
remaining = _read_number(source, "remaining")
|
|
335
|
+
percentage = _read_number(source, "percentage")
|
|
336
|
+
unit = _read_str(source, "unit")
|
|
337
|
+
bucket: UsageQuotaBucket = {}
|
|
338
|
+
if total is not None:
|
|
339
|
+
bucket["total"] = total
|
|
340
|
+
if used is not None:
|
|
341
|
+
bucket["used"] = used
|
|
342
|
+
if remaining is not None:
|
|
343
|
+
bucket["remaining"] = remaining
|
|
344
|
+
if percentage is not None:
|
|
345
|
+
bucket["percentage"] = percentage
|
|
346
|
+
if unit is not None:
|
|
347
|
+
bucket["unit"] = unit
|
|
348
|
+
if not bucket:
|
|
349
|
+
return None
|
|
350
|
+
return bucket
|
|
351
|
+
|
|
352
|
+
|
|
353
|
+
def _normalize_usage_add_on_quota(value: Any) -> UsageAddOnQuotaBucket | None:
|
|
354
|
+
source = _record_or_none(value)
|
|
355
|
+
if source is None:
|
|
356
|
+
return None
|
|
357
|
+
quota = _normalize_usage_quota_bucket(source)
|
|
358
|
+
result: UsageAddOnQuotaBucket = {}
|
|
359
|
+
if quota is not None:
|
|
360
|
+
if "total" in quota:
|
|
361
|
+
result["total"] = quota["total"]
|
|
362
|
+
if "used" in quota:
|
|
363
|
+
result["used"] = quota["used"]
|
|
364
|
+
if "remaining" in quota:
|
|
365
|
+
result["remaining"] = quota["remaining"]
|
|
366
|
+
if "percentage" in quota:
|
|
367
|
+
result["percentage"] = quota["percentage"]
|
|
368
|
+
if "unit" in quota:
|
|
369
|
+
result["unit"] = quota["unit"]
|
|
370
|
+
detail_url = _read_str(source, "detailUrl")
|
|
371
|
+
if detail_url is not None:
|
|
372
|
+
result["detailUrl"] = detail_url
|
|
373
|
+
if not result:
|
|
374
|
+
return None
|
|
375
|
+
return result
|
|
376
|
+
|
|
377
|
+
|
|
378
|
+
def _normalize_usage_org_resource_package(
|
|
379
|
+
value: Any,
|
|
380
|
+
) -> UsageOrgResourcePackage | None:
|
|
381
|
+
source = _record_or_none(value)
|
|
382
|
+
if source is None:
|
|
383
|
+
return None
|
|
384
|
+
used = _read_number(source, "used")
|
|
385
|
+
cap = _read_number(source, "cap")
|
|
386
|
+
remaining = _read_number(source, "remaining")
|
|
387
|
+
percentage = _read_number(source, "percentage")
|
|
388
|
+
available = _read_bool(source, "available")
|
|
389
|
+
unit = _read_str(source, "unit")
|
|
390
|
+
bucket: UsageOrgResourcePackage = {}
|
|
391
|
+
if used is not None:
|
|
392
|
+
bucket["used"] = used
|
|
393
|
+
if cap is not None:
|
|
394
|
+
bucket["cap"] = cap
|
|
395
|
+
if remaining is not None:
|
|
396
|
+
bucket["remaining"] = remaining
|
|
397
|
+
if percentage is not None:
|
|
398
|
+
bucket["percentage"] = percentage
|
|
399
|
+
if available is not None:
|
|
400
|
+
bucket["available"] = available
|
|
401
|
+
if unit is not None:
|
|
402
|
+
bucket["unit"] = unit
|
|
403
|
+
if not bucket:
|
|
404
|
+
return None
|
|
405
|
+
return bucket
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
def _normalize_usage_info(value: Any) -> UsageInfo | None:
|
|
409
|
+
source = _record_or_none(value)
|
|
410
|
+
if source is None:
|
|
411
|
+
return None
|
|
412
|
+
user_id = _read_str(source, "userId")
|
|
413
|
+
user_type = _read_str(source, "userType")
|
|
414
|
+
total_usage_percentage = _read_number(source, "totalUsagePercentage")
|
|
415
|
+
is_highest_tier = _read_bool(source, "isHighestTier")
|
|
416
|
+
expires_at = _read_number(source, "expiresAt")
|
|
417
|
+
upgrade_url = _read_str(source, "upgradeUrl")
|
|
418
|
+
user_quota = _normalize_usage_quota_bucket(source.get("userQuota"))
|
|
419
|
+
add_on_quota = _normalize_usage_add_on_quota(source.get("addOnQuota"))
|
|
420
|
+
is_quota_exceeded = _read_bool(source, "isQuotaExceeded")
|
|
421
|
+
is_plan_quota_prorated = _read_bool(source, "isPlanQuotaProrated")
|
|
422
|
+
org_resource_package = _normalize_usage_org_resource_package(
|
|
423
|
+
source.get("orgResourcePackage")
|
|
424
|
+
)
|
|
425
|
+
usage: UsageInfo = {}
|
|
426
|
+
if user_id is not None:
|
|
427
|
+
usage["userId"] = user_id
|
|
428
|
+
if user_type is not None:
|
|
429
|
+
usage["userType"] = user_type
|
|
430
|
+
if total_usage_percentage is not None:
|
|
431
|
+
usage["totalUsagePercentage"] = total_usage_percentage
|
|
432
|
+
if is_highest_tier is not None:
|
|
433
|
+
usage["isHighestTier"] = is_highest_tier
|
|
434
|
+
if expires_at is not None:
|
|
435
|
+
usage["expiresAt"] = expires_at
|
|
436
|
+
if upgrade_url is not None:
|
|
437
|
+
usage["upgradeUrl"] = upgrade_url
|
|
438
|
+
if user_quota is not None:
|
|
439
|
+
usage["userQuota"] = user_quota
|
|
440
|
+
if add_on_quota is not None:
|
|
441
|
+
usage["addOnQuota"] = add_on_quota
|
|
442
|
+
if is_quota_exceeded is not None:
|
|
443
|
+
usage["isQuotaExceeded"] = is_quota_exceeded
|
|
444
|
+
if is_plan_quota_prorated is not None:
|
|
445
|
+
usage["isPlanQuotaProrated"] = is_plan_quota_prorated
|
|
446
|
+
if org_resource_package is not None:
|
|
447
|
+
usage["orgResourcePackage"] = org_resource_package
|
|
448
|
+
return usage
|
|
449
|
+
|
|
450
|
+
|
|
255
451
|
def _resolve_exit_plan_mode_details(
|
|
256
452
|
request: SDKControlPermissionRequest,
|
|
257
453
|
) -> ExitPlanModeApprovalDetails | None:
|
|
@@ -323,7 +519,7 @@ class Query:
|
|
|
323
519
|
| None = None,
|
|
324
520
|
hooks: dict[str, list[dict[str, Any]]] | None = None,
|
|
325
521
|
sdk_mcp_servers: dict[str, "McpServer"] | None = None,
|
|
326
|
-
initialize_timeout: float =
|
|
522
|
+
initialize_timeout: float = INITIALIZE_TIMEOUT,
|
|
327
523
|
agents: dict[str, dict[str, Any]] | None = None,
|
|
328
524
|
enable_file_checkpointing: bool | None = None,
|
|
329
525
|
on_mcp_oauth_required: OnMcpOAuthRequired | None = None,
|
|
@@ -394,6 +590,7 @@ class Query:
|
|
|
394
590
|
self._initialized = False
|
|
395
591
|
self._closed = False
|
|
396
592
|
self._initialization_result: dict[str, Any] | None = None
|
|
593
|
+
self._initialization_task: asyncio.Task[dict[str, Any] | None] | None = None
|
|
397
594
|
# Query observes auth failures in stream-json messages. Keep a local
|
|
398
595
|
# guard because the transport may also observe an auth-error exit code,
|
|
399
596
|
# while the client wrapper protects the final user callback.
|
|
@@ -410,6 +607,21 @@ class Query:
|
|
|
410
607
|
"""
|
|
411
608
|
if not self.is_streaming_mode:
|
|
412
609
|
return None
|
|
610
|
+
if self._initialized:
|
|
611
|
+
return self._initialization_result
|
|
612
|
+
if self._initialization_task is not None:
|
|
613
|
+
return await self._initialization_task
|
|
614
|
+
|
|
615
|
+
loop = asyncio.get_running_loop()
|
|
616
|
+
self._initialization_task = loop.create_task(self._perform_initialize())
|
|
617
|
+
try:
|
|
618
|
+
return await self._initialization_task
|
|
619
|
+
finally:
|
|
620
|
+
if not self._initialized:
|
|
621
|
+
self._initialization_task = None
|
|
622
|
+
|
|
623
|
+
async def _perform_initialize(self) -> dict[str, Any] | None:
|
|
624
|
+
initialize_timeout_ms = int(self._initialize_timeout * 1000)
|
|
413
625
|
|
|
414
626
|
# Build hooks configuration for initialization
|
|
415
627
|
hooks_config: dict[str, Any] = {}
|
|
@@ -437,7 +649,10 @@ class Query:
|
|
|
437
649
|
"type": "initialize",
|
|
438
650
|
"subtype": "initialize",
|
|
439
651
|
"modelPolicyProvider": False,
|
|
652
|
+
"initializeTimeoutMs": initialize_timeout_ms,
|
|
440
653
|
}
|
|
654
|
+
if initialize_timeout_ms >= CATALOG_READY_INITIALIZE_MIN_TIMEOUT_MS:
|
|
655
|
+
request["supportsCatalogReadyInitialize"] = True
|
|
441
656
|
if self.resolve_model is not None:
|
|
442
657
|
request["modelPolicyProvider"] = True
|
|
443
658
|
logger.debug("initialize: pull-mode enabled (modelPolicyProvider=True)")
|
|
@@ -540,8 +755,8 @@ class Query:
|
|
|
540
755
|
if request_id in self.pending_control_responses:
|
|
541
756
|
event = self.pending_control_responses[request_id]
|
|
542
757
|
if response.get("subtype") == "error":
|
|
543
|
-
self.pending_control_results[request_id] =
|
|
544
|
-
response
|
|
758
|
+
self.pending_control_results[request_id] = (
|
|
759
|
+
_exception_from_error_payload(response)
|
|
545
760
|
)
|
|
546
761
|
else:
|
|
547
762
|
self.pending_control_results[request_id] = response
|
|
@@ -600,7 +815,7 @@ class Query:
|
|
|
600
815
|
self.pending_control_results[request_id] = e
|
|
601
816
|
event.set()
|
|
602
817
|
# Put error in stream so iterators can handle it
|
|
603
|
-
await self._message_send.send(
|
|
818
|
+
await self._message_send.send(_error_payload_from_exception(e))
|
|
604
819
|
finally:
|
|
605
820
|
# Unblock any waiters (e.g. string-prompt path waiting for first
|
|
606
821
|
# result) so they don't stall for the full timeout on early exit.
|
|
@@ -1263,6 +1478,15 @@ class Query:
|
|
|
1263
1478
|
"""Get a breakdown of current context window usage by category."""
|
|
1264
1479
|
return await self._send_control_request({"subtype": "get_context_usage"})
|
|
1265
1480
|
|
|
1481
|
+
async def get_usage_info(self) -> UsageInfo | None:
|
|
1482
|
+
"""Get account quota and usage information."""
|
|
1483
|
+
try:
|
|
1484
|
+
resp = await self._send_control_request({"subtype": "get_usage_info"})
|
|
1485
|
+
except Exception:
|
|
1486
|
+
# Compat: older CLIs reject unknown control subtypes.
|
|
1487
|
+
return None
|
|
1488
|
+
return _normalize_usage_info(resp.get("usage"))
|
|
1489
|
+
|
|
1266
1490
|
async def interrupt(self) -> None:
|
|
1267
1491
|
"""Send interrupt control request."""
|
|
1268
1492
|
await self._send_control_request({"subtype": "interrupt"})
|
|
@@ -1285,6 +1509,15 @@ class Query:
|
|
|
1285
1509
|
}
|
|
1286
1510
|
)
|
|
1287
1511
|
|
|
1512
|
+
async def set_proxy(self, proxy: str | None = None) -> None:
|
|
1513
|
+
"""Set or clear the proxy for the running CLI session."""
|
|
1514
|
+
await self._send_control_request(
|
|
1515
|
+
{
|
|
1516
|
+
"subtype": "set_proxy",
|
|
1517
|
+
"proxy": proxy,
|
|
1518
|
+
}
|
|
1519
|
+
)
|
|
1520
|
+
|
|
1288
1521
|
async def get_available_models(self) -> list[ModelInfo]:
|
|
1289
1522
|
"""Query the CLI for the list of available models.
|
|
1290
1523
|
|
|
@@ -1377,6 +1610,11 @@ class Query:
|
|
|
1377
1610
|
"""
|
|
1378
1611
|
return await self._send_control_request({"subtype": "reload_plugins"})
|
|
1379
1612
|
|
|
1613
|
+
async def list_plugins(self) -> list[PluginDetails]:
|
|
1614
|
+
"""List plugins loaded in the current session."""
|
|
1615
|
+
result = await self._send_control_request({"subtype": "list_plugins"})
|
|
1616
|
+
return cast(list[PluginDetails], result["plugins"])
|
|
1617
|
+
|
|
1380
1618
|
async def reconnect_mcp_server(self, server_name: str) -> None:
|
|
1381
1619
|
"""Reconnect a disconnected or failed MCP server.
|
|
1382
1620
|
|
|
@@ -1576,6 +1814,8 @@ class Query:
|
|
|
1576
1814
|
before closing stdin to allow bidirectional control protocol communication.
|
|
1577
1815
|
"""
|
|
1578
1816
|
try:
|
|
1817
|
+
await self.initialize()
|
|
1818
|
+
|
|
1579
1819
|
async for message in stream:
|
|
1580
1820
|
if self._closed:
|
|
1581
1821
|
break
|
|
@@ -1584,6 +1824,10 @@ class Query:
|
|
|
1584
1824
|
await self.wait_for_result_and_end_input()
|
|
1585
1825
|
except Exception as e:
|
|
1586
1826
|
logger.debug(f"Error streaming input: {e}")
|
|
1827
|
+
try:
|
|
1828
|
+
await self._message_send.send(_error_payload_from_exception(e))
|
|
1829
|
+
finally:
|
|
1830
|
+
await self.transport.end_input()
|
|
1587
1831
|
|
|
1588
1832
|
async def receive_messages(self) -> AsyncIterator[dict[str, Any]]:
|
|
1589
1833
|
"""Receive SDK messages (not control messages)."""
|
|
@@ -1592,13 +1836,18 @@ class Query:
|
|
|
1592
1836
|
if message.get("type") == "end":
|
|
1593
1837
|
break
|
|
1594
1838
|
elif message.get("type") == "error":
|
|
1595
|
-
raise
|
|
1839
|
+
raise _exception_from_error_payload(message)
|
|
1596
1840
|
|
|
1597
1841
|
yield message
|
|
1598
1842
|
|
|
1599
1843
|
async def close(self) -> None:
|
|
1600
1844
|
"""Close the query and transport."""
|
|
1601
1845
|
self._closed = True
|
|
1846
|
+
if (
|
|
1847
|
+
self._initialization_task is not None
|
|
1848
|
+
and not self._initialization_task.done()
|
|
1849
|
+
):
|
|
1850
|
+
self._initialization_task.cancel()
|
|
1602
1851
|
for task in list(self._child_tasks):
|
|
1603
1852
|
task.cancel()
|
|
1604
1853
|
if self._read_task is not None and not self._read_task.done():
|
|
@@ -44,6 +44,7 @@ logger = logging.getLogger(__name__)
|
|
|
44
44
|
_DEFAULT_MAX_BUFFER_SIZE = 1024 * 1024 # 1MB buffer limit
|
|
45
45
|
MINIMUM_RUNTIME_VERSION = "0.2.0"
|
|
46
46
|
CLI_EXIT_CODE_AUTH_ERROR = 41
|
|
47
|
+
PROXY_ENV_VARS = ("HTTPS_PROXY", "https_proxy", "HTTP_PROXY", "http_proxy")
|
|
47
48
|
|
|
48
49
|
_PERMISSION_POLICY_TO_RULE_KEY = {
|
|
49
50
|
"always_allow": "allow",
|
|
@@ -301,7 +302,6 @@ class SubprocessCLITransport(Transport):
|
|
|
301
302
|
- None if no settings are needed
|
|
302
303
|
"""
|
|
303
304
|
has_settings = self._options.settings is not None
|
|
304
|
-
has_sandbox = self._options.sandbox is not None
|
|
305
305
|
has_add_dirs = bool(self._options.add_dirs)
|
|
306
306
|
has_file_checkpointing = bool(self._options.enable_file_checkpointing)
|
|
307
307
|
mcp_policy_rules = self._collect_mcp_policy_permission_rules()
|
|
@@ -309,7 +309,6 @@ class SubprocessCLITransport(Transport):
|
|
|
309
309
|
|
|
310
310
|
if (
|
|
311
311
|
not has_settings
|
|
312
|
-
and not has_sandbox
|
|
313
312
|
and not has_add_dirs
|
|
314
313
|
and not has_file_checkpointing
|
|
315
314
|
and not has_mcp_policy_rules
|
|
@@ -319,7 +318,6 @@ class SubprocessCLITransport(Transport):
|
|
|
319
318
|
if (
|
|
320
319
|
has_settings
|
|
321
320
|
and isinstance(self._options.settings, (str, Path))
|
|
322
|
-
and not has_sandbox
|
|
323
321
|
and not has_add_dirs
|
|
324
322
|
and not has_file_checkpointing
|
|
325
323
|
and not has_mcp_policy_rules
|
|
@@ -338,9 +336,6 @@ class SubprocessCLITransport(Transport):
|
|
|
338
336
|
self._apply_additional_directories(settings_obj)
|
|
339
337
|
self._apply_mcp_policy_rules(settings_obj, mcp_policy_rules)
|
|
340
338
|
|
|
341
|
-
if has_sandbox:
|
|
342
|
-
settings_obj["sandbox"] = self._options.sandbox
|
|
343
|
-
|
|
344
339
|
if has_file_checkpointing:
|
|
345
340
|
general = settings_obj.get("general")
|
|
346
341
|
if not isinstance(general, dict):
|
|
@@ -469,7 +464,6 @@ class SubprocessCLITransport(Transport):
|
|
|
469
464
|
if self._options.session_id:
|
|
470
465
|
cmd.extend(["--session-id", self._options.session_id])
|
|
471
466
|
|
|
472
|
-
# Handle settings and sandbox: merge sandbox into settings if both are provided
|
|
473
467
|
settings_value = self._build_settings_value()
|
|
474
468
|
if settings_value:
|
|
475
469
|
cmd.extend(["--settings", settings_value])
|
|
@@ -516,14 +510,12 @@ class SubprocessCLITransport(Transport):
|
|
|
516
510
|
if self._options.agent:
|
|
517
511
|
cmd.extend(["--agent", self._options.agent])
|
|
518
512
|
|
|
519
|
-
#
|
|
520
|
-
#
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
)
|
|
526
|
-
cmd.extend(["--setting-sources", sources_value])
|
|
513
|
+
# Pass --setting-sources only when explicitly configured.
|
|
514
|
+
# None (default) = CLI uses its default behavior (loads all sources).
|
|
515
|
+
# [] (empty list) = explicitly disable all filesystem sources (isolation).
|
|
516
|
+
if self._options.setting_sources is not None:
|
|
517
|
+
sources_value = ",".join(self._options.setting_sources)
|
|
518
|
+
cmd.extend(["--setting-sources", sources_value])
|
|
527
519
|
|
|
528
520
|
# SDK mode never wants the CLI's bundled / built-in skills (simplify,
|
|
529
521
|
# debug, security-review, ...) silently joining the Skill tool surface.
|
|
@@ -683,6 +675,9 @@ class SubprocessCLITransport(Transport):
|
|
|
683
675
|
process_env[key] = value
|
|
684
676
|
else:
|
|
685
677
|
process_env.pop(key, None)
|
|
678
|
+
if self._options.proxy is not None:
|
|
679
|
+
for key in PROXY_ENV_VARS:
|
|
680
|
+
process_env[key] = self._options.proxy
|
|
686
681
|
if self._auth_payload_path is not None:
|
|
687
682
|
process_env["QODER_SDK_AUTH_PAYLOAD_FILE"] = str(
|
|
688
683
|
self._auth_payload_path
|