qoder-agent-sdk 1.0.2__tar.gz → 1.0.5__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.
Files changed (332) hide show
  1. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/PKG-INFO +1 -1
  2. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/pyproject.toml +1 -1
  3. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/src/qoder_agent_sdk/__init__.py +17 -0
  4. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/src/qoder_agent_sdk/_cli_version.py +1 -1
  5. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/src/qoder_agent_sdk/_internal/client.py +2 -7
  6. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/src/qoder_agent_sdk/_internal/cloud_agent.py +7 -3
  7. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/src/qoder_agent_sdk/_internal/query.py +241 -5
  8. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/src/qoder_agent_sdk/_internal/transport/subprocess_cli.py +4 -0
  9. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/src/qoder_agent_sdk/_version.py +1 -1
  10. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/src/qoder_agent_sdk/client.py +47 -7
  11. qoder_agent_sdk-1.0.5/src/qoder_agent_sdk/plugins.py +126 -0
  12. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/src/qoder_agent_sdk/types.py +120 -0
  13. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/test_client.py +2 -2
  14. qoder_agent_sdk-1.0.5/tests/test_initialize_model_catalog.py +165 -0
  15. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/test_tool_callbacks.py +27 -0
  16. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/test_transport.py +48 -0
  17. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/test_types.py +13 -0
  18. qoder_agent_sdk-1.0.5/tests/test_usage_info.py +138 -0
  19. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/.gitignore +0 -0
  20. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/LICENSE +0 -0
  21. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/README.md +0 -0
  22. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/src/qoder_agent_sdk/_bundled/.gitignore +0 -0
  23. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/src/qoder_agent_sdk/_errors.py +0 -0
  24. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/src/qoder_agent_sdk/_internal/__init__.py +0 -0
  25. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/src/qoder_agent_sdk/_internal/auth_helpers.py +0 -0
  26. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/src/qoder_agent_sdk/_internal/mcp_handler.py +0 -0
  27. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/src/qoder_agent_sdk/_internal/mcp_serialize.py +0 -0
  28. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/src/qoder_agent_sdk/_internal/message_parser.py +0 -0
  29. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/src/qoder_agent_sdk/_internal/sdk_mcp_transport.py +0 -0
  30. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/src/qoder_agent_sdk/_internal/session_mutations.py +0 -0
  31. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/src/qoder_agent_sdk/_internal/sessions.py +0 -0
  32. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/src/qoder_agent_sdk/_internal/transport/__init__.py +0 -0
  33. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/src/qoder_agent_sdk/auth.py +0 -0
  34. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/src/qoder_agent_sdk/py.typed +0 -0
  35. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/src/qoder_agent_sdk/query.py +0 -0
  36. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/src/qoder_agent_sdk/settings.py +0 -0
  37. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/__init__.py +0 -0
  38. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/_shared/__init__.py +0 -0
  39. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/_shared/dotenv.py +0 -0
  40. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/_shared/e2e.py +0 -0
  41. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/_shared/e2e_env.py +0 -0
  42. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/_shared/fake_qodercli.py +0 -0
  43. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/agents/__init__.py +0 -0
  44. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/agents/conftest.py +0 -0
  45. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/agents/test_agent_description.py +0 -0
  46. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/agents/test_agent_disallowed_tools.py +0 -0
  47. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/agents/test_agent_effort.py +0 -0
  48. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/agents/test_agent_initial_prompt.py +0 -0
  49. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/agents/test_agent_max_turns.py +0 -0
  50. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/agents/test_agent_mcp_servers.py +0 -0
  51. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/agents/test_agent_model.py +0 -0
  52. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/agents/test_agent_permission_mode.py +0 -0
  53. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/agents/test_agent_prompt.py +0 -0
  54. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/agents/test_agent_skills.py +0 -0
  55. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/agents/test_agent_tools.py +0 -0
  56. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/agents/test_boundary_disallowed_tools_empty.py +0 -0
  57. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/agents/test_boundary_effort_max.py +0 -0
  58. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/agents/test_boundary_empty_agents.py +0 -0
  59. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/agents/test_boundary_initial_prompt_empty.py +0 -0
  60. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/agents/test_boundary_many_agents.py +0 -0
  61. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/agents/test_boundary_max_turns_zero.py +0 -0
  62. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/agents/test_boundary_multi_agent_task_isolation.py +0 -0
  63. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/agents/test_boundary_permission_mode_default.py +0 -0
  64. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/agents/test_boundary_tools_empty.py +0 -0
  65. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/agents/test_boundary_tools_non_existent.py +0 -0
  66. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/agents/test_boundary_unregistered_session_agent.py +0 -0
  67. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/agents/test_register_custom_subagent.py +0 -0
  68. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/agents/test_session_agent.py +0 -0
  69. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/agents/test_session_agent_from_sdk_agents.py +0 -0
  70. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/agents/test_subagent_isolated_context.py +0 -0
  71. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/agents/test_subagent_tool_call_agent_selection.py +0 -0
  72. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/agents/test_subagent_tool_call_prompt.py +0 -0
  73. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/agents/test_subagent_tool_call_timeout.py +0 -0
  74. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/agents/test_supported_agents_list.py +0 -0
  75. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/auth/contract/test_subprocess_auth.py +0 -0
  76. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/auth/e2e/test_access_token_auth.py +0 -0
  77. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/auth/e2e/test_job_token_auth.py +0 -0
  78. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/auth/e2e/test_qodercli_auth.py +0 -0
  79. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/auth/unit/test_auth.py +0 -0
  80. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/auth/unit/test_dotenv.py +0 -0
  81. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/cloud_agent/__init__.py +0 -0
  82. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/cloud_agent/functional/__init__.py +0 -0
  83. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/cloud_agent/functional/_helpers.py +0 -0
  84. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/cloud_agent/functional/test_client_multi_turn_session.py +0 -0
  85. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/cloud_agent/functional/test_create_agent_session_stream.py +0 -0
  86. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/cloud_agent/functional/test_multi_turn_session.py +0 -0
  87. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/cloud_agent/test_cloud_agent_query.py +0 -0
  88. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/conftest.py +0 -0
  89. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/hooks/__init__.py +0 -0
  90. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/hooks/conftest.py +0 -0
  91. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/hooks/functional/__init__.py +0 -0
  92. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/hooks/functional/test_compact.py +0 -0
  93. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/hooks/functional/test_config_change.py +0 -0
  94. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/hooks/functional/test_cwd_changed.py +0 -0
  95. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/hooks/functional/test_decision_merge.py +0 -0
  96. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/hooks/functional/test_elicitation.py +0 -0
  97. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/hooks/functional/test_elicitation_result.py +0 -0
  98. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/hooks/functional/test_file_changed.py +0 -0
  99. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/hooks/functional/test_hooks_e2e.py +0 -0
  100. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/hooks/functional/test_instructions_loaded.py +0 -0
  101. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/hooks/functional/test_notification.py +0 -0
  102. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/hooks/functional/test_permission_denied.py +0 -0
  103. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/hooks/functional/test_permission_request.py +0 -0
  104. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/hooks/functional/test_post_tool_use.py +0 -0
  105. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/hooks/functional/test_post_tool_use_failure.py +0 -0
  106. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/hooks/functional/test_pre_tool_use.py +0 -0
  107. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/hooks/functional/test_session_end.py +0 -0
  108. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/hooks/functional/test_session_start.py +0 -0
  109. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/hooks/functional/test_setup.py +0 -0
  110. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/hooks/functional/test_stop.py +0 -0
  111. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/hooks/functional/test_stop_failure.py +0 -0
  112. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/hooks/functional/test_subagent.py +0 -0
  113. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/hooks/functional/test_task_completed.py +0 -0
  114. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/hooks/functional/test_task_created.py +0 -0
  115. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/hooks/functional/test_teammate_idle.py +0 -0
  116. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/hooks/functional/test_user_prompt_submit.py +0 -0
  117. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/hooks/functional/test_worktree.py +0 -0
  118. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/permissions/__init__.py +0 -0
  119. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/permissions/_e2e.py +0 -0
  120. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/permissions/test_can_use_tool.py +0 -0
  121. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/permissions/test_client_and_streaming.py +0 -0
  122. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/permissions/test_external_prompt_tool.py +0 -0
  123. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/permissions/test_options_and_modes.py +0 -0
  124. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/permissions/test_permission_modes.py +0 -0
  125. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/permissions/test_permission_request_hook_allow_skips_can_use_tool.py +0 -0
  126. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/permissions/test_permission_request_hook_deny_fires_denied.py +0 -0
  127. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/permissions/test_permission_updates.py +0 -0
  128. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/permissions/test_settings_and_mcp_policy.py +0 -0
  129. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/permissions/test_streaming_async_iterable_can_use_tool.py +0 -0
  130. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/plugins_loading_control/__init__.py +0 -0
  131. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/plugins_loading_control/conftest.py +0 -0
  132. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/plugins_loading_control/test_bogus_plugin_dir.py +0 -0
  133. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/plugins_loading_control/test_broken_plugin_content.py +0 -0
  134. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/plugins_loading_control/test_local_plugin_init.py +0 -0
  135. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/plugins_loading_control/test_multiple_plugin_dirs.py +0 -0
  136. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/plugins_loading_control/test_plugin_contributes_resources.py +0 -0
  137. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/plugins_loading_control/test_reload_plugins_commands.py +0 -0
  138. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/plugins_loading_control/test_reload_plugins_error_count.py +0 -0
  139. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/plugins_loading_control/test_reload_plugins_response_shape.py +0 -0
  140. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/plugins_loading_control/unit/__init__.py +0 -0
  141. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/plugins_loading_control/unit/test_plugin_dir_argv.py +0 -0
  142. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/plugins_loading_control/unit/test_reload_plugins_control_request.py +0 -0
  143. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/plugins_loading_control/unit/test_settings_passthrough.py +0 -0
  144. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_io/test_at_file_reference.py +0 -0
  145. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_io/test_client_multi_turn_io.py +0 -0
  146. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_io/test_compact_context.py +0 -0
  147. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_io/test_multimodal_content_blocks.py +0 -0
  148. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_io/test_partial_stream_events.py +0 -0
  149. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_io/test_query_stream_turns_io.py +0 -0
  150. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_io/test_server_output_style_info.py +0 -0
  151. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_io/test_stream_user_message_io.py +0 -0
  152. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_io/test_string_prompt_io.py +0 -0
  153. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_io/test_system_prompt.py +0 -0
  154. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/__init__.py +0 -0
  155. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/conftest.py +0 -0
  156. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/fixtures/__init__.py +0 -0
  157. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/fixtures/elicit_mcp_server.py +0 -0
  158. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/fixtures/fake_oauth_mcp_server.py +0 -0
  159. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/fixtures/minimal_mcp_server.py +0 -0
  160. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/fixtures/sse_mcp_server.py +0 -0
  161. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/functional/__init__.py +0 -0
  162. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/functional/test_allowed_mcp_server_names_exempts_sdk.py +0 -0
  163. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/functional/test_allowed_mcp_server_names_filters_stdio.py +0 -0
  164. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/functional/test_control_request_timeout_does_not_poison_runner.py +0 -0
  165. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/functional/test_elicitation_hook_probe.py +0 -0
  166. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/functional/test_elicitation_result_hook_probe.py +0 -0
  167. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/functional/test_elicitation_url_mode_unsupported.py +0 -0
  168. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/functional/test_http_server_public_deepwiki.py +0 -0
  169. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/functional/test_http_sse_bogus_url_not_crashing.py +0 -0
  170. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/functional/test_mcp_server_status_metadata_fields.py +0 -0
  171. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/functional/test_mcp_server_status_point_in_time_snapshot.py +0 -0
  172. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/functional/test_mcp_status_empty_when_no_servers.py +0 -0
  173. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/functional/test_mixed_inprocess_and_stdio_servers.py +0 -0
  174. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/functional/test_mixed_three_way_transports.py +0 -0
  175. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/functional/test_oauth_authenticate_custom_redirect_uri.py +0 -0
  176. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/functional/test_oauth_authenticate_returns_url_with_dcr.py +0 -0
  177. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/functional/test_oauth_authenticate_silent_refresh.py +0 -0
  178. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/functional/test_oauth_clear_auth_resets_to_needs_auth.py +0 -0
  179. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/functional/test_oauth_inject_token_connects.py +0 -0
  180. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/functional/test_oauth_needs_auth_status.py +0 -0
  181. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/functional/test_oauth_submit_callback_completes_flow.py +0 -0
  182. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/functional/test_oauth_token_persists_across_sessions.py +0 -0
  183. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/functional/test_permission_prompt_tool_probe.py +0 -0
  184. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/functional/test_sdk_mcp_annotations_not_echoed_in_status.py +0 -0
  185. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/functional/test_sdk_mcp_close_tears_down_transport.py +0 -0
  186. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/functional/test_sdk_mcp_multi_turn_reuse.py +0 -0
  187. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/functional/test_sdk_mcp_multiple_servers_isolated.py +0 -0
  188. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/functional/test_sdk_mcp_server_connected_status.py +0 -0
  189. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/functional/test_sdk_mcp_tool_description_passthrough.py +0 -0
  190. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/functional/test_server_name_special_chars_prefix.py +0 -0
  191. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/functional/test_sse_server_headers_and_connection.py +0 -0
  192. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/functional/test_stdio_grandchild_reclaim_on_close.py +0 -0
  193. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/functional/test_stdio_server_lifecycle.py +0 -0
  194. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/functional/test_strict_mcp_config_blocks_external_config.py +0 -0
  195. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/unit/__init__.py +0 -0
  196. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/unit/test_cli_args_allowed_mcp_server_names.py +0 -0
  197. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/unit/test_cli_args_mcp_config.py +0 -0
  198. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/unit/test_cli_args_permission_prompt_tool.py +0 -0
  199. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/unit/test_cli_args_strict_mcp_config.py +0 -0
  200. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/unit/test_create_sdk_mcp_server.py +0 -0
  201. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/unit/test_handler_accepts_extra_helper.py +0 -0
  202. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/unit/test_inbound_elicitation_callback.py +0 -0
  203. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/unit/test_inbound_elicitation_default_cancel.py +0 -0
  204. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/unit/test_inbound_get_model_policy.py +0 -0
  205. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/unit/test_mcp_authenticate_response_variants.py +0 -0
  206. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/unit/test_mcp_server_status_request.py +0 -0
  207. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/unit/test_mcp_server_status_timeout.py +0 -0
  208. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/unit/test_mcp_toggle_and_reconnect_requests.py +0 -0
  209. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/unit/test_sdk_mcp_handler_extra_signal.py +0 -0
  210. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/unit/test_sdk_mcp_handler_non_content_normalization.py +0 -0
  211. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_mcp/unit/test_sdk_server_split_from_process_servers.py +0 -0
  212. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_model_policy/__init__.py +0 -0
  213. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_model_policy/functional/__init__.py +0 -0
  214. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_model_policy/functional/conftest.py +0 -0
  215. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_model_policy/functional/test_list_available_models_rich_fields.py +0 -0
  216. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_model_policy/functional/test_model_policy_e2e.py +0 -0
  217. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_model_policy/functional/test_model_selection_e2e_logging.py +0 -0
  218. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_model_policy/functional/test_model_selection_logging.py +0 -0
  219. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_model_policy/unit/__init__.py +0 -0
  220. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_model_policy/unit/test_list_byok_providers.py +0 -0
  221. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/query_model_policy/unit/test_pull_suppresses_model_flag.py +0 -0
  222. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/rewind_api/__init__.py +0 -0
  223. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/rewind_api/conftest.py +0 -0
  224. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/rewind_api/test_capture_checkpoint_uuid_from_stream.py +0 -0
  225. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/rewind_api/test_enable_file_checkpointing.py +0 -0
  226. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/rewind_api/test_mid_stream_rewind.py +0 -0
  227. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/rewind_api/test_multiple_checkpoints_rewind.py +0 -0
  228. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/rewind_api/test_replay_user_messages_checkpoint_uuid.py +0 -0
  229. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/rewind_api/test_resume_session_rewind.py +0 -0
  230. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/rewind_api/test_rewind_bash_changes_not_tracked.py +0 -0
  231. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/rewind_api/test_rewind_cross_session_rejected.py +0 -0
  232. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/rewind_api/test_rewind_directory_ops_not_undone.py +0 -0
  233. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/rewind_api/test_rewind_dry_run_with_checkpoint.py +0 -0
  234. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/rewind_api/test_rewind_files_success.py +0 -0
  235. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/rewind_api/test_rewind_local_files_only.py +0 -0
  236. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/rewind_api/test_rewind_malformed_message_id.py +0 -0
  237. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/rewind_api/test_rewind_preserves_conversation.py +0 -0
  238. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/rewind_api/test_rewind_stats.py +0 -0
  239. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/rewind_api/test_rewind_unknown_message.py +0 -0
  240. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/rewind_api/test_rewind_without_checkpointing.py +0 -0
  241. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/session_control/test_continue_latest_session.py +0 -0
  242. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/session_control/test_fork_session.py +0 -0
  243. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/session_control/test_new_client_session.py +0 -0
  244. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/session_control/test_new_query_session.py +0 -0
  245. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/session_control/test_new_session_with_session_id.py +0 -0
  246. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/session_control/test_resume_session.py +0 -0
  247. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/skills_loading_control/__init__.py +0 -0
  248. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/skills_loading_control/conftest.py +0 -0
  249. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/skills_loading_control/test_agent_preloaded_skills.py +0 -0
  250. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/skills_loading_control/test_builtin_skills_visibility.py +0 -0
  251. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/skills_loading_control/test_default_skills_policy.py +0 -0
  252. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/skills_loading_control/test_enable_all_skills.py +0 -0
  253. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/skills_loading_control/test_enable_named_skills.py +0 -0
  254. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/skills_loading_control/test_plugin_skill_in_init.py +0 -0
  255. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/skills_loading_control/test_settings_skill_overrides.py +0 -0
  256. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/skills_loading_control/unit/__init__.py +0 -0
  257. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/skills_loading_control/unit/test_skills_argv.py +0 -0
  258. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/test_build_wheel.py +0 -0
  259. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/test_control_request_timeout.py +0 -0
  260. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/test_download_cli.py +0 -0
  261. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/test_errors.py +0 -0
  262. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/test_integration.py +0 -0
  263. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/test_mcp_dynamic.py +0 -0
  264. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/test_mcp_large_output.py +0 -0
  265. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/test_mcp_oauth.py +0 -0
  266. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/test_message_parser.py +0 -0
  267. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/test_permission_alignment.py +0 -0
  268. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/test_query.py +0 -0
  269. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/test_rate_limit_event_repro.py +0 -0
  270. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/test_sdk_mcp_integration.py +0 -0
  271. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/test_sdk_mcp_routing.py +0 -0
  272. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/test_session_mutations.py +0 -0
  273. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/test_sessions.py +0 -0
  274. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/test_streaming_client.py +0 -0
  275. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/test_subprocess_buffering.py +0 -0
  276. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/__init__.py +0 -0
  277. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/conftest.py +0 -0
  278. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_boundary_allowedTools_disallowedTools_conflict_priority.py +0 -0
  279. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_boundary_canUseTool_throws_error.py +0 -0
  280. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_boundary_concurrent_multiple_tool_uses.py +0 -0
  281. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_boundary_createSdkMcpServer_many_tools.py +0 -0
  282. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_boundary_handler_long_running_vs_controlRequestTimeoutMs.py +0 -0
  283. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_boundary_handler_returns_large_content.py +0 -0
  284. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_boundary_handler_returns_malformed_result.py +0 -0
  285. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_boundary_handler_returns_undefined.py +0 -0
  286. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_boundary_model_calls_unknown_tool_functional.py +0 -0
  287. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_boundary_tool_input_deeply_nested_schema.py +0 -0
  288. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_boundary_tool_input_many_fields.py +0 -0
  289. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_createSdkMcpServer_empty_tools.py +0 -0
  290. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_createSdkMcpServer_mcpServers_option.py +0 -0
  291. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_createSdkMcpServer_multiple_tools.py +0 -0
  292. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_createSdkMcpServer_name_routes_tool.py +0 -0
  293. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_createSdkMcpServer_version.py +0 -0
  294. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_error_handler_isError_true.py +0 -0
  295. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_error_handler_isError_with_structured_data.py +0 -0
  296. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_error_handler_throws_async_rejection.py +0 -0
  297. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_error_handler_throws_non_Error.py +0 -0
  298. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_error_handler_throws_sync_Error.py +0 -0
  299. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_error_isError_allows_agent_retry.py +0 -0
  300. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_permission_allowedTools_permits_mcp_tool.py +0 -0
  301. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_permission_allowedTools_server_pattern.py +0 -0
  302. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_permission_canUseTool_allow_passthrough.py +0 -0
  303. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_permission_canUseTool_conditional_on_input.py +0 -0
  304. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_permission_canUseTool_deny.py +0 -0
  305. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_permission_canUseTool_deny_with_interrupt.py +0 -0
  306. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_permission_canUseTool_receives_mcp_toolName_format.py +0 -0
  307. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_permission_canUseTool_updatedInput.py +0 -0
  308. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_permission_canUseTool_updatedPermissions.py +0 -0
  309. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_permission_disallowedTools_blocks_tool.py +0 -0
  310. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_permission_mode_bypassPermissions_with_mcp_tool.py +0 -0
  311. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_permission_postToolUse_hook_additionalContext.py +0 -0
  312. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_permission_preToolUse_hook_updatedInput.py +0 -0
  313. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_return_empty_content_array.py +0 -0
  314. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_return_image_content.py +0 -0
  315. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_return_multiple_content_blocks.py +0 -0
  316. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_return_text_content.py +0 -0
  317. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_tool_destructiveHint.py +0 -0
  318. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_tool_handler_receives_args_and_returns_content.py +0 -0
  319. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_tool_input_schema_describe.py +0 -0
  320. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_tool_input_schema_nested.py +0 -0
  321. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_tool_input_schema_zod_shape.py +0 -0
  322. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_tool_name_and_description.py +0 -0
  323. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_tool_openWorldHint.py +0 -0
  324. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_tool_readOnlyHint.py +0 -0
  325. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_unit_createSdkMcpServer.py +0 -0
  326. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_unit_createSdkMcpServer_duplicate_tool_name.py +0 -0
  327. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_unit_createSdkMcpServer_empty_server_name.py +0 -0
  328. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_unit_createSdkMcpServer_empty_tool_description.py +0 -0
  329. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_unit_createSdkMcpServer_empty_tool_name.py +0 -0
  330. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_unit_mcp_handler.py +0 -0
  331. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_unit_sdk_mcp_transport.py +0 -0
  332. {qoder_agent_sdk-1.0.2 → qoder_agent_sdk-1.0.5}/tests/tools/test_unit_tool_helper.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: qoder-agent-sdk
3
- Version: 1.0.2
3
+ Version: 1.0.5
4
4
  Summary: Python SDK for Qoder Agent
5
5
  Author: Qoder
6
6
  License: Copyright (c) 2026 Qoder
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "qoder-agent-sdk"
7
- version = "1.0.2"
7
+ version = "1.0.5"
8
8
  description = "Python SDK for Qoder Agent"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -61,6 +61,7 @@ from .auth import (
61
61
  qodercli_auth,
62
62
  )
63
63
  from .client import QoderSDKClient
64
+ from .plugins import PluginError, disable_plugin, enable_plugin, list_plugins
64
65
  from .query import query
65
66
  from .settings import filter_escalating_default_mode
66
67
  from .types import (
@@ -154,7 +155,9 @@ from .types import (
154
155
  PermissionResultAllow,
155
156
  PermissionResultDeny,
156
157
  PermissionUpdate,
158
+ PluginDetails,
157
159
  PluginInfo,
160
+ PluginResources,
158
161
  PostCompactHookInput,
159
162
  PostToolUseFailureHookInput,
160
163
  PostToolUseFailureHookSpecificOutput,
@@ -217,6 +220,10 @@ from .types import (
217
220
  ToolProgressMessage,
218
221
  ToolResultBlock,
219
222
  ToolUseBlock,
223
+ UsageAddOnQuotaBucket,
224
+ UsageInfo,
225
+ UsageOrgResourcePackage,
226
+ UsageQuotaBucket,
220
227
  UserMessage,
221
228
  UserPromptSubmitHookInput,
222
229
  UserPromptSubmitHookSpecificOutput,
@@ -823,6 +830,10 @@ __all__ = [
823
830
  "ContentBlock",
824
831
  "ContextUsageCategory",
825
832
  "ContextUsageResponse",
833
+ "UsageAddOnQuotaBucket",
834
+ "UsageInfo",
835
+ "UsageOrgResourcePackage",
836
+ "UsageQuotaBucket",
826
837
  # Tool callbacks
827
838
  "CanUseTool",
828
839
  "ToolPermissionContext",
@@ -902,7 +913,13 @@ __all__ = [
902
913
  # Plugin support
903
914
  "SdkPluginConfig",
904
915
  "PluginInfo",
916
+ "PluginDetails",
917
+ "PluginResources",
905
918
  "ReloadPluginsResponse",
919
+ "list_plugins",
920
+ "enable_plugin",
921
+ "disable_plugin",
922
+ "PluginError",
906
923
  # File checkpointing
907
924
  "RewindFilesResult",
908
925
  # Session listing
@@ -1,3 +1,3 @@
1
1
  """Bundled runtime CLI version."""
2
2
 
3
- __cli_version__ = "1.0.3"
3
+ __cli_version__ = "1.0.23"
@@ -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
- # Match QoderSDKClient.connect().
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)
@@ -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,161 @@ 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
+ total = _read_number(source, "total")
331
+ used = _read_number(source, "used")
332
+ remaining = _read_number(source, "remaining")
333
+ percentage = _read_number(source, "percentage")
334
+ unit = _read_str(source, "unit")
335
+ if (
336
+ total is None
337
+ or used is None
338
+ or remaining is None
339
+ or percentage is None
340
+ or unit is None
341
+ ):
342
+ return None
343
+ return {
344
+ "total": total,
345
+ "used": used,
346
+ "remaining": remaining,
347
+ "percentage": percentage,
348
+ "unit": unit,
349
+ }
350
+
351
+
352
+ def _normalize_usage_add_on_quota(value: Any) -> UsageAddOnQuotaBucket | None:
353
+ source = _record_or_none(value)
354
+ quota = _normalize_usage_quota_bucket(source)
355
+ detail_url = _read_str(source, "detailUrl")
356
+ if quota is None or detail_url is None:
357
+ return None
358
+ return {**quota, "detailUrl": detail_url}
359
+
360
+
361
+ def _normalize_usage_org_resource_package(
362
+ value: Any,
363
+ ) -> UsageOrgResourcePackage | None:
364
+ source = _record_or_none(value)
365
+ used = _read_number(source, "used")
366
+ cap = _read_number(source, "cap")
367
+ remaining = _read_number(source, "remaining")
368
+ percentage = _read_number(source, "percentage")
369
+ available = _read_bool(source, "available")
370
+ unit = _read_str(source, "unit")
371
+ if (
372
+ used is None
373
+ or cap is None
374
+ or remaining is None
375
+ or percentage is None
376
+ or available is None
377
+ or unit is None
378
+ ):
379
+ return None
380
+ return {
381
+ "used": used,
382
+ "cap": cap,
383
+ "remaining": remaining,
384
+ "percentage": percentage,
385
+ "available": available,
386
+ "unit": unit,
387
+ }
388
+
389
+
390
+ def _normalize_usage_info(value: Any) -> UsageInfo | None:
391
+ source = _record_or_none(value)
392
+ user_id = _read_str(source, "userId")
393
+ user_type = _read_str(source, "userType")
394
+ total_usage_percentage = _read_number(source, "totalUsagePercentage")
395
+ is_highest_tier = _read_bool(source, "isHighestTier")
396
+ expires_at = _read_number(source, "expiresAt")
397
+ upgrade_url = _read_str(source, "upgradeUrl")
398
+ user_quota = _normalize_usage_quota_bucket(
399
+ source.get("userQuota") if source is not None else None
400
+ )
401
+ add_on_quota = _normalize_usage_add_on_quota(
402
+ source.get("addOnQuota") if source is not None else None
403
+ )
404
+ is_quota_exceeded = _read_bool(source, "isQuotaExceeded")
405
+ is_plan_quota_prorated = _read_bool(source, "isPlanQuotaProrated")
406
+ org_resource_package = _normalize_usage_org_resource_package(
407
+ source.get("orgResourcePackage") if source is not None else None
408
+ )
409
+ if (
410
+ user_id is None
411
+ or user_type is None
412
+ or total_usage_percentage is None
413
+ or is_highest_tier is None
414
+ or expires_at is None
415
+ or upgrade_url is None
416
+ or user_quota is None
417
+ or add_on_quota is None
418
+ or is_quota_exceeded is None
419
+ or is_plan_quota_prorated is None
420
+ or org_resource_package is None
421
+ ):
422
+ return None
423
+ return {
424
+ "userId": user_id,
425
+ "userType": user_type,
426
+ "totalUsagePercentage": total_usage_percentage,
427
+ "isHighestTier": is_highest_tier,
428
+ "expiresAt": expires_at,
429
+ "upgradeUrl": upgrade_url,
430
+ "userQuota": user_quota,
431
+ "addOnQuota": add_on_quota,
432
+ "isQuotaExceeded": is_quota_exceeded,
433
+ "isPlanQuotaProrated": is_plan_quota_prorated,
434
+ "orgResourcePackage": org_resource_package,
435
+ }
436
+
437
+
255
438
  def _resolve_exit_plan_mode_details(
256
439
  request: SDKControlPermissionRequest,
257
440
  ) -> ExitPlanModeApprovalDetails | None:
@@ -323,7 +506,7 @@ class Query:
323
506
  | None = None,
324
507
  hooks: dict[str, list[dict[str, Any]]] | None = None,
325
508
  sdk_mcp_servers: dict[str, "McpServer"] | None = None,
326
- initialize_timeout: float = 60.0,
509
+ initialize_timeout: float = INITIALIZE_TIMEOUT,
327
510
  agents: dict[str, dict[str, Any]] | None = None,
328
511
  enable_file_checkpointing: bool | None = None,
329
512
  on_mcp_oauth_required: OnMcpOAuthRequired | None = None,
@@ -394,6 +577,7 @@ class Query:
394
577
  self._initialized = False
395
578
  self._closed = False
396
579
  self._initialization_result: dict[str, Any] | None = None
580
+ self._initialization_task: asyncio.Task[dict[str, Any] | None] | None = None
397
581
  # Query observes auth failures in stream-json messages. Keep a local
398
582
  # guard because the transport may also observe an auth-error exit code,
399
583
  # while the client wrapper protects the final user callback.
@@ -410,6 +594,21 @@ class Query:
410
594
  """
411
595
  if not self.is_streaming_mode:
412
596
  return None
597
+ if self._initialized:
598
+ return self._initialization_result
599
+ if self._initialization_task is not None:
600
+ return await self._initialization_task
601
+
602
+ loop = asyncio.get_running_loop()
603
+ self._initialization_task = loop.create_task(self._perform_initialize())
604
+ try:
605
+ return await self._initialization_task
606
+ finally:
607
+ if not self._initialized:
608
+ self._initialization_task = None
609
+
610
+ async def _perform_initialize(self) -> dict[str, Any] | None:
611
+ initialize_timeout_ms = int(self._initialize_timeout * 1000)
413
612
 
414
613
  # Build hooks configuration for initialization
415
614
  hooks_config: dict[str, Any] = {}
@@ -437,7 +636,10 @@ class Query:
437
636
  "type": "initialize",
438
637
  "subtype": "initialize",
439
638
  "modelPolicyProvider": False,
639
+ "initializeTimeoutMs": initialize_timeout_ms,
440
640
  }
641
+ if initialize_timeout_ms >= CATALOG_READY_INITIALIZE_MIN_TIMEOUT_MS:
642
+ request["supportsCatalogReadyInitialize"] = True
441
643
  if self.resolve_model is not None:
442
644
  request["modelPolicyProvider"] = True
443
645
  logger.debug("initialize: pull-mode enabled (modelPolicyProvider=True)")
@@ -540,8 +742,8 @@ class Query:
540
742
  if request_id in self.pending_control_responses:
541
743
  event = self.pending_control_responses[request_id]
542
744
  if response.get("subtype") == "error":
543
- self.pending_control_results[request_id] = Exception(
544
- response.get("error", "Unknown error")
745
+ self.pending_control_results[request_id] = (
746
+ _exception_from_error_payload(response)
545
747
  )
546
748
  else:
547
749
  self.pending_control_results[request_id] = response
@@ -600,7 +802,7 @@ class Query:
600
802
  self.pending_control_results[request_id] = e
601
803
  event.set()
602
804
  # Put error in stream so iterators can handle it
603
- await self._message_send.send({"type": "error", "error": str(e)})
805
+ await self._message_send.send(_error_payload_from_exception(e))
604
806
  finally:
605
807
  # Unblock any waiters (e.g. string-prompt path waiting for first
606
808
  # result) so they don't stall for the full timeout on early exit.
@@ -1263,6 +1465,15 @@ class Query:
1263
1465
  """Get a breakdown of current context window usage by category."""
1264
1466
  return await self._send_control_request({"subtype": "get_context_usage"})
1265
1467
 
1468
+ async def get_usage_info(self) -> UsageInfo | None:
1469
+ """Get account quota and usage information."""
1470
+ try:
1471
+ resp = await self._send_control_request({"subtype": "get_usage_info"})
1472
+ except Exception:
1473
+ # Compat: older CLIs reject unknown control subtypes.
1474
+ return None
1475
+ return _normalize_usage_info(resp.get("usage"))
1476
+
1266
1477
  async def interrupt(self) -> None:
1267
1478
  """Send interrupt control request."""
1268
1479
  await self._send_control_request({"subtype": "interrupt"})
@@ -1285,6 +1496,15 @@ class Query:
1285
1496
  }
1286
1497
  )
1287
1498
 
1499
+ async def set_proxy(self, proxy: str | None = None) -> None:
1500
+ """Set or clear the proxy for the running CLI session."""
1501
+ await self._send_control_request(
1502
+ {
1503
+ "subtype": "set_proxy",
1504
+ "proxy": proxy,
1505
+ }
1506
+ )
1507
+
1288
1508
  async def get_available_models(self) -> list[ModelInfo]:
1289
1509
  """Query the CLI for the list of available models.
1290
1510
 
@@ -1377,6 +1597,11 @@ class Query:
1377
1597
  """
1378
1598
  return await self._send_control_request({"subtype": "reload_plugins"})
1379
1599
 
1600
+ async def list_plugins(self) -> list[PluginDetails]:
1601
+ """List plugins loaded in the current session."""
1602
+ result = await self._send_control_request({"subtype": "list_plugins"})
1603
+ return cast(list[PluginDetails], result["plugins"])
1604
+
1380
1605
  async def reconnect_mcp_server(self, server_name: str) -> None:
1381
1606
  """Reconnect a disconnected or failed MCP server.
1382
1607
 
@@ -1576,6 +1801,8 @@ class Query:
1576
1801
  before closing stdin to allow bidirectional control protocol communication.
1577
1802
  """
1578
1803
  try:
1804
+ await self.initialize()
1805
+
1579
1806
  async for message in stream:
1580
1807
  if self._closed:
1581
1808
  break
@@ -1584,6 +1811,10 @@ class Query:
1584
1811
  await self.wait_for_result_and_end_input()
1585
1812
  except Exception as e:
1586
1813
  logger.debug(f"Error streaming input: {e}")
1814
+ try:
1815
+ await self._message_send.send(_error_payload_from_exception(e))
1816
+ finally:
1817
+ await self.transport.end_input()
1587
1818
 
1588
1819
  async def receive_messages(self) -> AsyncIterator[dict[str, Any]]:
1589
1820
  """Receive SDK messages (not control messages)."""
@@ -1592,13 +1823,18 @@ class Query:
1592
1823
  if message.get("type") == "end":
1593
1824
  break
1594
1825
  elif message.get("type") == "error":
1595
- raise Exception(message.get("error", "Unknown error"))
1826
+ raise _exception_from_error_payload(message)
1596
1827
 
1597
1828
  yield message
1598
1829
 
1599
1830
  async def close(self) -> None:
1600
1831
  """Close the query and transport."""
1601
1832
  self._closed = True
1833
+ if (
1834
+ self._initialization_task is not None
1835
+ and not self._initialization_task.done()
1836
+ ):
1837
+ self._initialization_task.cancel()
1602
1838
  for task in list(self._child_tasks):
1603
1839
  task.cancel()
1604
1840
  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",
@@ -683,6 +684,9 @@ class SubprocessCLITransport(Transport):
683
684
  process_env[key] = value
684
685
  else:
685
686
  process_env.pop(key, None)
687
+ if self._options.proxy is not None:
688
+ for key in PROXY_ENV_VARS:
689
+ process_env[key] = self._options.proxy
686
690
  if self._auth_payload_path is not None:
687
691
  process_env["QODER_SDK_AUTH_PAYLOAD_FILE"] = str(
688
692
  self._auth_payload_path
@@ -1,3 +1,3 @@
1
1
  """Version information for qoder-agent-sdk."""
2
2
 
3
- __version__ = "1.0.2"
3
+ __version__ = "1.0.5"
@@ -1,7 +1,6 @@
1
1
  """Qoder SDK client for interactive agent sessions."""
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, cast
@@ -20,10 +19,12 @@ from .types import (
20
19
  ModelInfo,
21
20
  OAuthToken,
22
21
  PermissionMode,
22
+ PluginDetails,
23
23
  QoderAgentOptions,
24
24
  ReloadPluginsResponse,
25
25
  ResultMessage,
26
26
  RewindFilesResult,
27
+ UsageInfo,
27
28
  )
28
29
 
29
30
 
@@ -98,7 +99,7 @@ class QoderSDKClient:
98
99
  await self._query.connect(prompt=prompt)
99
100
  return
100
101
 
101
- from ._internal.query import Query
102
+ from ._internal.query import Query, resolve_initialize_timeout
102
103
  from ._internal.transport.subprocess_cli import SubprocessCLITransport
103
104
 
104
105
  # Auto-connect with empty async iterable if no prompt is provided
@@ -148,11 +149,7 @@ class QoderSDKClient:
148
149
  if isinstance(config, dict) and config.get("type") == "sdk":
149
150
  sdk_mcp_servers[name] = config["instance"] # type: ignore[typeddict-item]
150
151
 
151
- # QODER_STREAM_CLOSE_TIMEOUT is the SDK env var for initialize timeout.
152
- initialize_timeout_ms = int(
153
- os.environ.get("QODER_STREAM_CLOSE_TIMEOUT", "60000")
154
- )
155
- initialize_timeout = max(initialize_timeout_ms / 1000.0, 60.0)
152
+ initialize_timeout = resolve_initialize_timeout()
156
153
 
157
154
  # Convert agents to dict format for initialize request
158
155
  agents_dict: dict[str, dict[str, Any]] | None = None
@@ -313,6 +310,18 @@ class QoderSDKClient:
313
310
  raise CLIConnectionError("Not connected. Call connect() first.")
314
311
  await self._query.set_model(model)
315
312
 
313
+ async def set_proxy(self, proxy: str | None = None) -> None:
314
+ """Set or clear the proxy during conversation.
315
+
316
+ Args:
317
+ proxy: Proxy URL for the running qodercli session. Supports
318
+ ``http://``, ``https://``, ``socks5://``, and ``socks://``.
319
+ Pass ``None`` or an empty string to clear the proxy.
320
+ """
321
+ if not self._query:
322
+ raise CLIConnectionError("Not connected. Call connect() first.")
323
+ await self._query.set_proxy(proxy)
324
+
316
325
  async def get_available_models(self) -> list[ModelInfo]:
317
326
  """Query the CLI for the list of available models.
318
327
 
@@ -461,6 +470,13 @@ class QoderSDKClient:
461
470
  result = await self._query.reload_plugins()
462
471
  return cast(ReloadPluginsResponse, result)
463
472
 
473
+ async def list_plugins(self) -> list[PluginDetails]:
474
+ """List plugins loaded in the current session."""
475
+ if not self._query:
476
+ raise CLIConnectionError("Not connected. Call connect() first.")
477
+ result: list[PluginDetails] = await self._query.list_plugins()
478
+ return result
479
+
464
480
  async def reconnect_mcp_server(self, server_name: str) -> None:
465
481
  """Reconnect a disconnected or failed MCP server (only works with streaming mode).
466
482
 
@@ -696,6 +712,30 @@ class QoderSDKClient:
696
712
  result: ContextUsageResponse = await self._query.get_context_usage()
697
713
  return result
698
714
 
715
+ async def get_usage_info(self) -> UsageInfo | None:
716
+ """Get current account quota and usage information.
717
+
718
+ Returns the same account usage payload exposed by the CLI's usage API.
719
+ Missing required fields are not synthesized by the SDK; when the
720
+ running CLI cannot provide a complete usage payload this returns
721
+ ``None``.
722
+
723
+ Returns:
724
+ UsageInfo dictionary, or ``None`` when unavailable.
725
+
726
+ Example:
727
+ ```python
728
+ async with QoderSDKClient() as client:
729
+ usage = await client.get_usage_info()
730
+ if usage is not None:
731
+ print(usage["totalUsagePercentage"])
732
+ ```
733
+ """
734
+ if not self._query:
735
+ raise CLIConnectionError("Not connected. Call connect() first.")
736
+ result = await self._query.get_usage_info()
737
+ return cast(UsageInfo | None, result)
738
+
699
739
  async def get_server_info(self) -> dict[str, Any] | None:
700
740
  """Get server initialization info including available commands and output styles.
701
741