openhands-sdk 1.49.3__tar.gz → 1.49.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 (306) hide show
  1. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/PKG-INFO +3 -3
  2. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/agent/acp_agent.py +62 -18
  3. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/context/view/properties/tool_call_matching.py +4 -9
  4. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/conversation/secret_registry.py +64 -10
  5. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/extensions/installation/metadata.py +2 -2
  6. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/llm/message.py +3 -2
  7. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/llm/utils/model_features.py +7 -0
  8. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/llm/utils/telemetry.py +127 -126
  9. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/mcp/tool.py +60 -2
  10. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/secret/__init__.py +6 -0
  11. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/secret/secrets.py +48 -0
  12. openhands_sdk-1.49.5/openhands/sdk/utils/masking.py +13 -0
  13. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands_sdk.egg-info/PKG-INFO +3 -3
  14. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands_sdk.egg-info/SOURCES.txt +2 -0
  15. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands_sdk.egg-info/requires.txt +2 -2
  16. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/pyproject.toml +3 -3
  17. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/__init__.py +0 -0
  18. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/agent/__init__.py +0 -0
  19. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/agent/acp_file_credentials.py +0 -0
  20. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/agent/acp_models.py +0 -0
  21. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/agent/acp_tracing.py +0 -0
  22. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/agent/agent.py +0 -0
  23. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/agent/base.py +0 -0
  24. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/agent/critic_mixin.py +0 -0
  25. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/agent/parallel_executor.py +0 -0
  26. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/agent/response_dispatch.py +0 -0
  27. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/agent/stream_context.py +0 -0
  28. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/agent/utils.py +0 -0
  29. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/banner.py +0 -0
  30. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/context/__init__.py +0 -0
  31. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/context/agent_context.py +0 -0
  32. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/context/condenser/__init__.py +0 -0
  33. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/context/condenser/base.py +0 -0
  34. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/context/condenser/llm_summarizing_condenser.py +0 -0
  35. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/context/condenser/no_op_condenser.py +0 -0
  36. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/context/condenser/pipeline_condenser.py +0 -0
  37. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/context/condenser/prompts/summarizing_prompt.j2 +0 -0
  38. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/context/condenser/utils.py +0 -0
  39. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/context/memory.py +0 -0
  40. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/context/prompts/__init__.py +0 -0
  41. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/context/prompts/presets.py +0 -0
  42. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/context/prompts/prompt.py +0 -0
  43. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/context/prompts/registry.py +0 -0
  44. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/context/prompts/section.py +0 -0
  45. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/context/prompts/sections/__init__.py +0 -0
  46. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/context/prompts/sections/dynamic.py +0 -0
  47. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/context/prompts/sections/planning.py +0 -0
  48. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/context/prompts/sections/static.py +0 -0
  49. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/context/prompts/templates/ask_agent_template.j2 +0 -0
  50. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/context/prompts/templates/skill_knowledge_info.j2 +0 -0
  51. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/context/view/__init__.py +0 -0
  52. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/context/view/manipulation_indices.py +0 -0
  53. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/context/view/properties/__init__.py +0 -0
  54. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/context/view/properties/base.py +0 -0
  55. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/context/view/properties/batch_atomicity.py +0 -0
  56. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/context/view/properties/observation_uniqueness.py +0 -0
  57. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/context/view/properties/tool_loop_atomicity.py +0 -0
  58. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/context/view/view.py +0 -0
  59. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/conversation/__init__.py +0 -0
  60. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/conversation/base.py +0 -0
  61. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/conversation/cancellation.py +0 -0
  62. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/conversation/conversation.py +0 -0
  63. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/conversation/conversation_stats.py +0 -0
  64. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/conversation/event_store.py +0 -0
  65. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/conversation/events_list_base.py +0 -0
  66. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/conversation/exceptions.py +0 -0
  67. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/conversation/fifo_lock.py +0 -0
  68. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/conversation/goal/__init__.py +0 -0
  69. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/conversation/goal/controller.py +0 -0
  70. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/conversation/goal/judge.py +0 -0
  71. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/conversation/goal/prompts.py +0 -0
  72. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/conversation/goal/runner.py +0 -0
  73. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/conversation/impl/__init__.py +0 -0
  74. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/conversation/impl/local_conversation.py +0 -0
  75. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/conversation/impl/remote_conversation.py +0 -0
  76. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/conversation/persistence_const.py +0 -0
  77. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/conversation/request.py +0 -0
  78. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/conversation/resource_lock_manager.py +0 -0
  79. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/conversation/response_utils.py +0 -0
  80. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/conversation/state.py +0 -0
  81. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/conversation/stuck_detector.py +0 -0
  82. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/conversation/title_utils.py +0 -0
  83. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/conversation/types.py +0 -0
  84. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/conversation/visualizer/__init__.py +0 -0
  85. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/conversation/visualizer/base.py +0 -0
  86. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/conversation/visualizer/default.py +0 -0
  87. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/credential.py +0 -0
  88. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/critic/__init__.py +0 -0
  89. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/critic/base.py +0 -0
  90. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/critic/impl/__init__.py +0 -0
  91. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/critic/impl/agent_finished.py +0 -0
  92. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/critic/impl/api/__init__.py +0 -0
  93. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/critic/impl/api/chat_template.py +0 -0
  94. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/critic/impl/api/client.py +0 -0
  95. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/critic/impl/api/critic.py +0 -0
  96. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/critic/impl/api/taxonomy.py +0 -0
  97. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/critic/impl/empty_patch.py +0 -0
  98. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/critic/impl/pass_critic.py +0 -0
  99. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/critic/result.py +0 -0
  100. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/event/__init__.py +0 -0
  101. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/event/acp_tool_call.py +0 -0
  102. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/event/base.py +0 -0
  103. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/event/condenser.py +0 -0
  104. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/event/conversation_error.py +0 -0
  105. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/event/conversation_state.py +0 -0
  106. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/event/error_classification.py +0 -0
  107. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/event/hook_execution.py +0 -0
  108. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/event/llm_completion_log.py +0 -0
  109. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/event/llm_convertible/__init__.py +0 -0
  110. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/event/llm_convertible/action.py +0 -0
  111. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/event/llm_convertible/message.py +0 -0
  112. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/event/llm_convertible/observation.py +0 -0
  113. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/event/llm_convertible/reasoning_utils.py +0 -0
  114. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/event/llm_convertible/system.py +0 -0
  115. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/event/resume_transcript.py +0 -0
  116. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/event/streaming_delta.py +0 -0
  117. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/event/token.py +0 -0
  118. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/event/types.py +0 -0
  119. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/event/user_action.py +0 -0
  120. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/extensions/__init__.py +0 -0
  121. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/extensions/fetch.py +0 -0
  122. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/extensions/installation/__init__.py +0 -0
  123. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/extensions/installation/info.py +0 -0
  124. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/extensions/installation/interface.py +0 -0
  125. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/extensions/installation/manager.py +0 -0
  126. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/extensions/installation/utils.py +0 -0
  127. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/git/cached_repo.py +0 -0
  128. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/git/exceptions.py +0 -0
  129. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/git/git_changes.py +0 -0
  130. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/git/git_commits.py +0 -0
  131. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/git/git_diff.py +0 -0
  132. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/git/models.py +0 -0
  133. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/git/utils.py +0 -0
  134. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/hooks/__init__.py +0 -0
  135. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/hooks/config.py +0 -0
  136. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/hooks/conversation_hooks.py +0 -0
  137. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/hooks/executor.py +0 -0
  138. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/hooks/manager.py +0 -0
  139. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/hooks/types.py +0 -0
  140. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/io/__init__.py +0 -0
  141. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/io/base.py +0 -0
  142. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/io/cache.py +0 -0
  143. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/io/local.py +0 -0
  144. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/io/memory.py +0 -0
  145. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/llm/__init__.py +0 -0
  146. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/llm/auth/__init__.py +0 -0
  147. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/llm/auth/credentials.py +0 -0
  148. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/llm/auth/openai.py +0 -0
  149. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/llm/cleanup_profile.py +0 -0
  150. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/llm/exceptions/__init__.py +0 -0
  151. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/llm/exceptions/classifier.py +0 -0
  152. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/llm/exceptions/mapping.py +0 -0
  153. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/llm/exceptions/types.py +0 -0
  154. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/llm/fallback_strategy.py +0 -0
  155. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/llm/llm.py +0 -0
  156. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/llm/llm_profile_store.py +0 -0
  157. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/llm/llm_registry.py +0 -0
  158. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/llm/llm_response.py +0 -0
  159. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/llm/mixins/fn_call_converter.py +0 -0
  160. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/llm/mixins/fn_call_examples.py +0 -0
  161. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/llm/mixins/non_native_fc.py +0 -0
  162. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/llm/options/__init__.py +0 -0
  163. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/llm/options/chat_options.py +0 -0
  164. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/llm/options/common.py +0 -0
  165. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/llm/options/responses_options.py +0 -0
  166. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/llm/provider_connection_store.py +0 -0
  167. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/llm/router/__init__.py +0 -0
  168. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/llm/router/base.py +0 -0
  169. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/llm/router/impl/multimodal.py +0 -0
  170. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/llm/router/impl/random.py +0 -0
  171. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/llm/streaming.py +0 -0
  172. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/llm/utils/image_inline.py +0 -0
  173. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/llm/utils/image_resize.py +0 -0
  174. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/llm/utils/litellm_provider.py +0 -0
  175. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/llm/utils/metrics.py +0 -0
  176. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/llm/utils/model_info.py +0 -0
  177. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/llm/utils/model_prompt_spec.py +0 -0
  178. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/llm/utils/openhands_provider.py +0 -0
  179. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/llm/utils/providers/__init__.py +0 -0
  180. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/llm/utils/providers/openrouter.py +0 -0
  181. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/llm/utils/responses_serialization.py +0 -0
  182. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/llm/utils/retry_mixin.py +0 -0
  183. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/llm/utils/runtime_metadata.py +0 -0
  184. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/llm/utils/unverified_models.py +0 -0
  185. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/llm/utils/verified_models.py +0 -0
  186. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/llm/utils/vertex_preflight.py +0 -0
  187. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/logger/__init__.py +0 -0
  188. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/logger/logger.py +0 -0
  189. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/logger/rolling.py +0 -0
  190. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/marketplace/__init__.py +0 -0
  191. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/marketplace/registration.py +0 -0
  192. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/marketplace/registry.py +0 -0
  193. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/marketplace/types.py +0 -0
  194. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/mcp/__init__.py +0 -0
  195. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/mcp/client.py +0 -0
  196. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/mcp/config.py +0 -0
  197. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/mcp/definition.py +0 -0
  198. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/mcp/exceptions.py +0 -0
  199. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/mcp/utils.py +0 -0
  200. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/observability/__init__.py +0 -0
  201. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/observability/laminar.py +0 -0
  202. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/observability/utils.py +0 -0
  203. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/plugin/__init__.py +0 -0
  204. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/plugin/discovery.py +0 -0
  205. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/plugin/fetch.py +0 -0
  206. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/plugin/format/__init__.py +0 -0
  207. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/plugin/format/agent_plugins.py +0 -0
  208. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/plugin/format/agent_plugins_mcp.py +0 -0
  209. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/plugin/format/base.py +0 -0
  210. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/plugin/format/claude_code.py +0 -0
  211. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/plugin/format/schemas/mcp-1.0.0.schema.json +0 -0
  212. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/plugin/format/schemas/plugin-1.0.0.schema.json +0 -0
  213. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/plugin/installed.py +0 -0
  214. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/plugin/loader.py +0 -0
  215. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/plugin/plugin.py +0 -0
  216. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/plugin/source.py +0 -0
  217. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/plugin/types.py +0 -0
  218. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/profiles/__init__.py +0 -0
  219. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/profiles/agent_profile.py +0 -0
  220. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/profiles/agent_profile_store.py +0 -0
  221. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/profiles/profile_refs.py +0 -0
  222. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/profiles/resolver.py +0 -0
  223. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/profiles/seed.py +0 -0
  224. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/py.typed +0 -0
  225. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/security/__init__.py +0 -0
  226. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/security/_shell_ast.py +0 -0
  227. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/security/analyzer.py +0 -0
  228. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/security/confirmation_policy.py +0 -0
  229. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/security/defense_in_depth/__init__.py +0 -0
  230. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/security/defense_in_depth/pattern.py +0 -0
  231. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/security/defense_in_depth/policy_rails.py +0 -0
  232. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/security/defense_in_depth/shell_semantics.py +0 -0
  233. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/security/defense_in_depth/utils.py +0 -0
  234. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/security/ensemble.py +0 -0
  235. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/security/grayswan/__init__.py +0 -0
  236. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/security/grayswan/analyzer.py +0 -0
  237. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/security/grayswan/utils.py +0 -0
  238. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/security/llm_analyzer.py +0 -0
  239. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/security/risk.py +0 -0
  240. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/security/shell_parser.py +0 -0
  241. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/security/toolshield_helpers.py +0 -0
  242. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/security/toolshield_llm_analyzer.py +0 -0
  243. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/settings/__init__.py +0 -0
  244. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/settings/acp_install_catalog.py +0 -0
  245. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/settings/acp_providers.py +0 -0
  246. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/settings/api_models.py +0 -0
  247. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/settings/metadata.py +0 -0
  248. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/settings/model.py +0 -0
  249. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/skills/__init__.py +0 -0
  250. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/skills/exceptions.py +0 -0
  251. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/skills/execute.py +0 -0
  252. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/skills/fetch.py +0 -0
  253. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/skills/installed.py +0 -0
  254. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/skills/skill.py +0 -0
  255. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/skills/trigger.py +0 -0
  256. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/skills/types.py +0 -0
  257. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/skills/utils.py +0 -0
  258. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/subagent/__init__.py +0 -0
  259. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/subagent/load.py +0 -0
  260. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/subagent/registry.py +0 -0
  261. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/subagent/schema.py +0 -0
  262. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/testing/__init__.py +0 -0
  263. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/testing/test_llm.py +0 -0
  264. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/tool/__init__.py +0 -0
  265. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/tool/builtins/__init__.py +0 -0
  266. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/tool/builtins/finish.py +0 -0
  267. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/tool/builtins/invoke_skill.py +0 -0
  268. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/tool/builtins/switch_llm.py +0 -0
  269. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/tool/builtins/think.py +0 -0
  270. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/tool/builtins/vision_inspect.py +0 -0
  271. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/tool/client_tool.py +0 -0
  272. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/tool/defaults.py +0 -0
  273. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/tool/registry.py +0 -0
  274. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/tool/schema.py +0 -0
  275. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/tool/spec.py +0 -0
  276. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/tool/tool.py +0 -0
  277. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/utils/__init__.py +0 -0
  278. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/utils/async_executor.py +0 -0
  279. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/utils/async_utils.py +0 -0
  280. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/utils/cipher.py +0 -0
  281. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/utils/command.py +0 -0
  282. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/utils/datetime.py +0 -0
  283. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/utils/deprecation.py +0 -0
  284. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/utils/files.py +0 -0
  285. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/utils/github.py +0 -0
  286. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/utils/json.py +0 -0
  287. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/utils/models.py +0 -0
  288. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/utils/paging.py +0 -0
  289. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/utils/path.py +0 -0
  290. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/utils/pydantic_secrets.py +0 -0
  291. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/utils/redact.py +0 -0
  292. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/utils/truncate.py +0 -0
  293. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/utils/visualize.py +0 -0
  294. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/workspace/__init__.py +0 -0
  295. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/workspace/base.py +0 -0
  296. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/workspace/local.py +0 -0
  297. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/workspace/models.py +0 -0
  298. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/workspace/remote/__init__.py +0 -0
  299. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/workspace/remote/async_remote_workspace.py +0 -0
  300. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/workspace/remote/base.py +0 -0
  301. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/workspace/remote/remote_workspace_mixin.py +0 -0
  302. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/workspace/repo.py +0 -0
  303. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands/sdk/workspace/workspace.py +0 -0
  304. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands_sdk.egg-info/dependency_links.txt +0 -0
  305. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/openhands_sdk.egg-info/top_level.txt +0 -0
  306. {openhands_sdk-1.49.3 → openhands_sdk-1.49.5}/setup.cfg +0 -0
@@ -1,20 +1,20 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openhands-sdk
3
- Version: 1.49.3
3
+ Version: 1.49.5
4
4
  Summary: OpenHands SDK - Core functionality for building AI agents
5
5
  Project-URL: Source, https://github.com/OpenHands/software-agent-sdk
6
6
  Project-URL: Homepage, https://github.com/OpenHands/software-agent-sdk
7
7
  Project-URL: Documentation, https://docs.openhands.dev/sdk
8
8
  Project-URL: Bug Tracker, https://github.com/OpenHands/software-agent-sdk/issues
9
9
  Requires-Python: >=3.12
10
- Requires-Dist: agent-client-protocol<0.11.0,>=0.10.1
10
+ Requires-Dist: agent-client-protocol<0.13.0,>=0.12.1
11
11
  Requires-Dist: deprecation>=2.1.0
12
12
  Requires-Dist: fakeredis[lua]>=2.32.1
13
13
  Requires-Dist: fastmcp<4,>=3.2.0
14
14
  Requires-Dist: filelock>=3.20.1
15
15
  Requires-Dist: httpx[socks]>=0.27.0
16
16
  Requires-Dist: jsonschema>=4.23.0
17
- Requires-Dist: joserfc>=1.6.8
17
+ Requires-Dist: joserfc>=1.7.5
18
18
  Requires-Dist: litellm>=1.93.0
19
19
  Requires-Dist: pillow>=12.3.0
20
20
  Requires-Dist: pydantic>=2.12.5
@@ -43,21 +43,34 @@ from acp.client.connection import ClientSideConnection
43
43
  from acp.exceptions import RequestError as ACPRequestError
44
44
  from acp.helpers import image_block, text_block
45
45
  from acp.schema import (
46
+ AcpMcpServer,
46
47
  AgentMessageChunk,
47
48
  AgentThoughtChunk,
48
49
  AllowedOutcome,
50
+ CreateElicitationResponse,
51
+ CreateTerminalResponse,
52
+ DeclineElicitationResponse,
53
+ ElicitationMode,
49
54
  EnvVariable,
50
55
  HttpHeader,
51
56
  HttpMcpServer,
52
57
  ImageContentBlock,
58
+ KillTerminalResponse,
53
59
  McpServerStdio,
60
+ PermissionOption,
54
61
  PromptResponse,
62
+ ReadTextFileResponse,
63
+ ReleaseTerminalResponse,
55
64
  RequestPermissionResponse,
56
65
  SseMcpServer,
66
+ TerminalOutputResponse,
57
67
  TextContentBlock,
58
68
  ToolCallProgress,
59
69
  ToolCallStart,
70
+ ToolCallUpdate,
60
71
  UsageUpdate,
72
+ WaitForTerminalExitResponse,
73
+ WriteTextFileResponse,
61
74
  )
62
75
  from acp.transports import default_environment
63
76
  from pydantic import (
@@ -617,14 +630,23 @@ async def _apply_acp_model(
617
630
  Codex, callers may still pass a combined Canvas id such as ``gpt-5.5/high``;
618
631
  codex-acp exposes reasoning effort as a separate config option, so split it
619
632
  only on the config-options mechanism.
633
+
634
+ agent-client-protocol 0.12.1 dropped the UNSTABLE ``models`` extension from
635
+ the ACP schema and removed ``ClientSideConnection.set_session_model``. A live
636
+ 0.12 connection therefore has no legacy RPC to call, so the ``else`` branch
637
+ only invokes it when the connection actually exposes the method (test
638
+ doubles do; real 0.12 connections do not) and otherwise no-ops rather than
639
+ raising ``AttributeError``.
620
640
  """
621
641
  if via_config_option:
622
642
  for config_id, value in _model_config_options(agent_name, model):
623
643
  await conn.set_config_option(
624
644
  config_id=config_id, value=value, session_id=session_id
625
645
  )
626
- else:
627
- await conn.set_session_model(model_id=model, session_id=session_id)
646
+ elif hasattr(conn, "set_session_model"):
647
+ await conn.set_session_model( # type: ignore[attr-defined]
648
+ model_id=model, session_id=session_id
649
+ )
628
650
 
629
651
 
630
652
  def _usable_models(infos: Iterable[ACPModelInfo]) -> list[ACPModelInfo]:
@@ -689,7 +711,7 @@ def _extract_session_models(
689
711
 
690
712
 
691
713
  # The ACP MCP server union accepted by new_session() / load_session().
692
- _ACPMcpServer = HttpMcpServer | SseMcpServer | McpServerStdio
714
+ _ACPMcpServer = HttpMcpServer | SseMcpServer | McpServerStdio | AcpMcpServer
693
715
 
694
716
 
695
717
  def _remote_mcp_headers(server: MCPServer, name: str) -> list[HttpHeader]:
@@ -1579,11 +1601,11 @@ class _OpenHandsACPBridge:
1579
1601
 
1580
1602
  async def request_permission(
1581
1603
  self,
1582
- options: list[Any],
1583
1604
  session_id: str, # noqa: ARG002
1584
- tool_call: Any,
1605
+ tool_call: ToolCallUpdate,
1606
+ options: list[PermissionOption],
1585
1607
  **kwargs: Any, # noqa: ARG002
1586
- ) -> Any:
1608
+ ) -> RequestPermissionResponse:
1587
1609
  """Auto-approve all permission requests from the ACP server."""
1588
1610
  # Pick the first option (usually "allow once")
1589
1611
  option_id = options[0].option_id if options else "allow_once"
@@ -1596,52 +1618,74 @@ class _OpenHandsACPBridge:
1596
1618
  outcome=AllowedOutcome(outcome="selected", option_id=option_id),
1597
1619
  )
1598
1620
 
1621
+ async def create_elicitation(
1622
+ self,
1623
+ message: str, # noqa: ARG002
1624
+ mode: ElicitationMode, # noqa: ARG002
1625
+ **kwargs: Any, # noqa: ARG002
1626
+ ) -> CreateElicitationResponse:
1627
+ """Decline elicitation requests; the headless bridge has no user to ask.
1628
+
1629
+ Added to the ``Client`` protocol in agent-client-protocol 0.12.x. None
1630
+ of the pinned ACP providers elicit during a headless turn, so this is a
1631
+ defensive default rather than an exercised code path.
1632
+ """
1633
+ return DeclineElicitationResponse(action="decline")
1634
+
1635
+ async def complete_elicitation(
1636
+ self,
1637
+ elicitation_id: str, # noqa: ARG002
1638
+ **kwargs: Any, # noqa: ARG002
1639
+ ) -> None:
1640
+ """No-op completion for an elicitation the bridge always declines."""
1641
+ return None
1642
+
1599
1643
  # fs/terminal methods — raise NotImplementedError; ACP server handles its own
1600
1644
  async def write_text_file(
1601
- self, content: str, path: str, session_id: str, **kwargs: Any
1602
- ) -> None:
1645
+ self, session_id: str, path: str, content: str, **kwargs: Any
1646
+ ) -> WriteTextFileResponse | None:
1603
1647
  raise NotImplementedError("ACP server handles file operations")
1604
1648
 
1605
1649
  async def read_text_file(
1606
1650
  self,
1607
- path: str,
1608
1651
  session_id: str,
1609
- limit: int | None = None,
1652
+ path: str,
1610
1653
  line: int | None = None,
1654
+ limit: int | None = None,
1611
1655
  **kwargs: Any,
1612
- ) -> Any:
1656
+ ) -> ReadTextFileResponse:
1613
1657
  raise NotImplementedError("ACP server handles file operations")
1614
1658
 
1615
1659
  async def create_terminal(
1616
1660
  self,
1617
- command: str,
1618
1661
  session_id: str,
1662
+ command: str,
1619
1663
  args: list[str] | None = None,
1664
+ env: list[EnvVariable] | None = None,
1620
1665
  cwd: str | None = None,
1621
- env: Any = None,
1622
1666
  output_byte_limit: int | None = None,
1623
1667
  **kwargs: Any,
1624
- ) -> Any:
1668
+ ) -> CreateTerminalResponse:
1625
1669
  raise NotImplementedError("ACP server handles terminal operations")
1626
1670
 
1627
1671
  async def terminal_output(
1628
1672
  self, session_id: str, terminal_id: str, **kwargs: Any
1629
- ) -> Any:
1673
+ ) -> TerminalOutputResponse:
1630
1674
  raise NotImplementedError("ACP server handles terminal operations")
1631
1675
 
1632
1676
  async def release_terminal(
1633
1677
  self, session_id: str, terminal_id: str, **kwargs: Any
1634
- ) -> None:
1678
+ ) -> ReleaseTerminalResponse | None:
1635
1679
  raise NotImplementedError("ACP server handles terminal operations")
1636
1680
 
1637
1681
  async def wait_for_terminal_exit(
1638
1682
  self, session_id: str, terminal_id: str, **kwargs: Any
1639
- ) -> Any:
1683
+ ) -> WaitForTerminalExitResponse:
1640
1684
  raise NotImplementedError("ACP server handles terminal operations")
1641
1685
 
1642
1686
  async def kill_terminal(
1643
1687
  self, session_id: str, terminal_id: str, **kwargs: Any
1644
- ) -> None:
1688
+ ) -> KillTerminalResponse | None:
1645
1689
  raise NotImplementedError("ACP server handles terminal operations")
1646
1690
 
1647
1691
  async def ext_method(
@@ -64,8 +64,9 @@ class ToolCallMatchingProperty(ViewPropertyBase):
64
64
  ) -> ManipulationIndices:
65
65
  """Calculate manipulation indices for tool call matching.
66
66
 
67
- This property is maintained by ensuring there are no manipulation indices
68
- between action events and their paired observation event.
67
+ Indices between an action and its matching observation are protected.
68
+ Observation-like events without a pending action do not affect boundaries;
69
+ property enforcement separately removes orphaned and duplicate observations.
69
70
  """
70
71
  # Start with a complete set of manipulation indices, then we'll remove those
71
72
  # between actions and their paired observations.
@@ -84,13 +85,7 @@ class ToolCallMatchingProperty(ViewPropertyBase):
84
85
  case ActionEvent():
85
86
  pending_tool_call_ids.add(event.tool_call_id)
86
87
  case ObservationBaseEvent():
87
- # Intentionally use remove(), not discard(): a second
88
- # observation-like event for the same tool_call_id means the
89
- # view has already violated the 1 action -> 1 result
90
- # invariant that downstream LLM APIs expect. That case must
91
- # be fixed by de-duplicating the view before serialization,
92
- # not by silently tolerating it here.
93
- pending_tool_call_ids.remove(event.tool_call_id)
88
+ pending_tool_call_ids.discard(event.tool_call_id)
94
89
 
95
90
  if pending_tool_call_ids:
96
91
  # The enumeration index corresponds to the position of the event, but we
@@ -11,6 +11,7 @@ from pydantic import BaseModel, Field, PrivateAttr, SecretStr
11
11
 
12
12
  from openhands.sdk.logger import get_logger
13
13
  from openhands.sdk.secret import SecretSource, SecretValue, StaticSecret
14
+ from openhands.sdk.utils.masking import PreserveDataUrls, SkipSecretMasking
14
15
  from openhands.sdk.utils.models import OpenHandsModel
15
16
 
16
17
 
@@ -20,8 +21,14 @@ logger = get_logger(__name__)
20
21
  FAILED_LOOKUP_RETRY_SECONDS: Final[float] = 60.0
21
22
 
22
23
 
23
- def _mask_value(value: Any, mask: Callable[[str], str]) -> Any:
24
- """Recursively mask every ``str`` reachable from ``value``."""
24
+ def _mask_value(
25
+ value: Any,
26
+ mask: Callable[[str], str],
27
+ *,
28
+ skip_secret_masking: bool = False,
29
+ preserve_data_urls: bool = False,
30
+ ) -> Any:
31
+ """Recursively mask strings, respecting opaque payload field metadata."""
25
32
  match value:
26
33
  case Enum():
27
34
  # A str-subclass enum is a str, but masking it would downgrade the
@@ -29,20 +36,56 @@ def _mask_value(value: Any, mask: Callable[[str], str]) -> Any:
29
36
  # vocabulary is fixed, so it can never hold a secret anyway.
30
37
  return value
31
38
  case str():
39
+ if skip_secret_masking:
40
+ return value
41
+ if preserve_data_urls and value.startswith("data:") and ";base64," in value:
42
+ return value
32
43
  return mask(value)
33
44
  case BaseModel():
34
45
  return _mask_model(value, mask)
35
46
  case list():
36
- return [_mask_value(item, mask) for item in value]
47
+ return [
48
+ _mask_value(
49
+ item,
50
+ mask,
51
+ skip_secret_masking=skip_secret_masking,
52
+ preserve_data_urls=preserve_data_urls,
53
+ )
54
+ for item in value
55
+ ]
37
56
  case tuple():
38
- items = [_mask_value(item, mask) for item in value]
57
+ items = [
58
+ _mask_value(
59
+ item,
60
+ mask,
61
+ skip_secret_masking=skip_secret_masking,
62
+ preserve_data_urls=preserve_data_urls,
63
+ )
64
+ for item in value
65
+ ]
39
66
  # Rebuild a NamedTuple through its own constructor; tuple(items)
40
67
  # would downgrade it the same way masking an Enum member does.
41
68
  return type(value)(*items) if hasattr(value, "_fields") else tuple(items)
42
69
  case set() | frozenset():
43
- return type(value)(_mask_value(item, mask) for item in value)
70
+ return type(value)(
71
+ _mask_value(
72
+ item,
73
+ mask,
74
+ skip_secret_masking=skip_secret_masking,
75
+ preserve_data_urls=preserve_data_urls,
76
+ )
77
+ for item in value
78
+ )
44
79
  case dict():
45
- return {key: _mask_value(item, mask) for key, item in value.items()}
80
+ return {
81
+ key: _mask_value(
82
+ item,
83
+ mask,
84
+ skip_secret_masking=skip_secret_masking,
85
+ preserve_data_urls=preserve_data_urls,
86
+ )
87
+ for key, item in value.items()
88
+ }
46
89
  case _:
47
90
  return value
48
91
 
@@ -53,10 +96,21 @@ def _mask_model[ModelT: BaseModel](model: ModelT, mask: Callable[[str], str]) ->
53
96
  ``model_copy`` is used rather than a validate round-trip so private
54
97
  attributes survive and no field is re-coerced.
55
98
  """
56
- updates = {
57
- name: _mask_value(getattr(model, name), mask)
58
- for name in type(model).model_fields
59
- }
99
+ updates = {}
100
+ for name, field in type(model).model_fields.items():
101
+ metadata = field.metadata
102
+ skip_secret_masking = any(
103
+ isinstance(item, SkipSecretMasking) for item in metadata
104
+ )
105
+ preserve_data_urls = any(
106
+ isinstance(item, PreserveDataUrls) for item in metadata
107
+ )
108
+ updates[name] = _mask_value(
109
+ getattr(model, name),
110
+ mask,
111
+ skip_secret_masking=skip_secret_masking,
112
+ preserve_data_urls=preserve_data_urls,
113
+ )
60
114
  return model.model_copy(update=updates)
61
115
 
62
116
 
@@ -150,7 +150,7 @@ class InstallationMetadata(BaseModel):
150
150
  return cls()
151
151
 
152
152
  try:
153
- return cls.model_validate_json(metadata_path.read_text())
153
+ return cls.model_validate_json(metadata_path.read_text(encoding="utf-8"))
154
154
  except Exception as e:
155
155
  logger.warning(f"Failed to load installed extension metadata: {e}")
156
156
  return cls()
@@ -159,7 +159,7 @@ class InstallationMetadata(BaseModel):
159
159
  """Save metadata to the installed extensions directory."""
160
160
  metadata_path = self.get_metadata_path(installed_dir)
161
161
  metadata_path.parent.mkdir(parents=True, exist_ok=True)
162
- metadata_path.write_text(self.model_dump_json(indent=2))
162
+ metadata_path.write_text(self.model_dump_json(indent=2), encoding="utf-8")
163
163
 
164
164
  def validate_tracked(self, installed_dir: Path) -> list[InstallationInfo]:
165
165
  """Validate tracked extensions exist on disk.
@@ -1,7 +1,7 @@
1
1
  import json
2
2
  from abc import abstractmethod
3
3
  from collections.abc import Sequence
4
- from typing import Any, ClassVar, Literal
4
+ from typing import Annotated, Any, ClassVar, Literal
5
5
 
6
6
  from litellm import ChatCompletionMessageToolCall, ResponseFunctionToolCall
7
7
  from litellm.types.responses.main import (
@@ -16,6 +16,7 @@ from pydantic import BaseModel, ConfigDict, Field, field_validator, model_valida
16
16
  from openhands.sdk.logger import get_logger
17
17
  from openhands.sdk.utils import DEFAULT_TEXT_CONTENT_LIMIT, maybe_truncate
18
18
  from openhands.sdk.utils.deprecation import handle_deprecated_model_fields
19
+ from openhands.sdk.utils.masking import PreserveDataUrls
19
20
 
20
21
 
21
22
  logger = get_logger(__name__)
@@ -203,7 +204,7 @@ class TextContent(BaseContent):
203
204
 
204
205
  class ImageContent(BaseContent):
205
206
  type: Literal["image"] = "image"
206
- image_urls: list[str]
207
+ image_urls: Annotated[list[str], PreserveDataUrls()]
207
208
 
208
209
  def to_llm_dict(self) -> list[dict[str, str | dict[str, str]]]:
209
210
  """Convert to LLM API format."""
@@ -109,6 +109,7 @@ def _normalized_supported_openai_params(model: str | None) -> frozenset[str]:
109
109
 
110
110
 
111
111
  REASONING_EFFORT_MODEL_OVERRIDES = {
112
+ "gpt-5.2-codex": "gpt-5.2-codex",
112
113
  "kimi-k3": "moonshot/kimi-k3",
113
114
  }
114
115
 
@@ -188,9 +189,15 @@ SUPPORTS_STOP_WORDS_FALSE_MODELS: list[str] = [
188
189
  ]
189
190
 
190
191
  # Models that should use the OpenAI Responses API path by default
192
+ # NOTE: model_matches uses case-insensitive substring matching, so a bare family
193
+ # token like "gpt-5" / "gpt-6" covers all variants (mini, sol, luna, astra, ...).
191
194
  RESPONSES_API_MODELS: list[str] = [
192
195
  # OpenAI GPT-5 family (includes mini variants)
193
196
  "gpt-5",
197
+ # OpenAI GPT-6 family (gpt-6-sol, gpt-6-luna, gpt-6-astra, ...). These reject
198
+ # function tools + reasoning_effort on /v1/chat/completions; /v1/responses
199
+ # supports both. See saas-deploy #1144.
200
+ "gpt-6",
194
201
  # OpenAI Codex (uses Responses API)
195
202
  "codex-mini-latest",
196
203
  ]