xpander-sdk 2.0.396__tar.gz → 2.0.397__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 (164) hide show
  1. {xpander_sdk-2.0.396/src/xpander_sdk.egg-info → xpander_sdk-2.0.397}/PKG-INFO +1 -1
  2. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/setup.py +1 -1
  3. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/__init__.py +1 -1
  4. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/core/context_optimizer/constants.py +14 -0
  5. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/core/context_optimizer/finalize_mode.py +2 -0
  6. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/models/action_ledger.py +2 -0
  7. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/backend/frameworks/agno.py +110 -0
  8. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397/src/xpander_sdk.egg-info}/PKG-INFO +1 -1
  9. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/LICENSE +0 -0
  10. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/README.md +0 -0
  11. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/pyproject.toml +0 -0
  12. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/setup.cfg +0 -0
  13. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/consts/__init__.py +0 -0
  14. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/consts/api_routes.py +0 -0
  15. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/core/__init__.py +0 -0
  16. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/core/context_optimizer/__init__.py +0 -0
  17. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/core/context_optimizer/action_ledger.py +0 -0
  18. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/core/context_optimizer/compact_retry_result.py +0 -0
  19. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/core/context_optimizer/completion_evidence.py +0 -0
  20. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/core/context_optimizer/context_optimizer.py +0 -0
  21. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/core/context_optimizer/encryption.py +0 -0
  22. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/core/context_optimizer/error_patterns.py +0 -0
  23. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/core/context_optimizer/helpers/__init__.py +0 -0
  24. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/core/context_optimizer/helpers/chunking.py +0 -0
  25. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/core/context_optimizer/helpers/recent_actions.py +0 -0
  26. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/core/context_optimizer/helpers/secrets.py +0 -0
  27. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/core/context_optimizer/helpers/tool_result.py +0 -0
  28. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/core/context_optimizer/helpers/xml_safety.py +0 -0
  29. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/core/context_optimizer/mixins/__init__.py +0 -0
  30. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/core/context_optimizer/mixins/map_reduce.py +0 -0
  31. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/core/context_optimizer/multimodal_error_patterns.py +0 -0
  32. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/core/context_optimizer/prompts.py +0 -0
  33. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/core/context_optimizer/search.py +0 -0
  34. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/core/context_optimizer/workspace_cache.py +0 -0
  35. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/core/module_base.py +0 -0
  36. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/core/state.py +0 -0
  37. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/core/xpander_api_client.py +0 -0
  38. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/exceptions/__init__.py +0 -0
  39. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/exceptions/module_exception.py +0 -0
  40. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/models/__init__.py +0 -0
  41. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/models/activity.py +0 -0
  42. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/models/compactization.py +0 -0
  43. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/models/configuration.py +0 -0
  44. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/models/context_status.py +0 -0
  45. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/models/deep_planning.py +0 -0
  46. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/models/events.py +0 -0
  47. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/models/frameworks.py +0 -0
  48. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/models/generic.py +0 -0
  49. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/models/notifications.py +0 -0
  50. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/models/orchestrations.py +0 -0
  51. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/models/shared.py +0 -0
  52. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/models/user.py +0 -0
  53. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/__init__.py +0 -0
  54. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/agents/__init__.py +0 -0
  55. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/agents/agents_module.py +0 -0
  56. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/agents/models/__init__.py +0 -0
  57. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/agents/models/agent.py +0 -0
  58. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/agents/models/agent_list.py +0 -0
  59. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/agents/models/knowledge_bases.py +0 -0
  60. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/agents/sub_modules/__init__.py +0 -0
  61. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/agents/sub_modules/agent.py +0 -0
  62. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/agents/utils/__init__.py +0 -0
  63. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/agents/utils/generic.py +0 -0
  64. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/backend/__init__.py +0 -0
  65. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/backend/backend_module.py +0 -0
  66. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/backend/decorators/__init__.py +0 -0
  67. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/backend/decorators/on_auth_event.py +0 -0
  68. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/backend/events_registry.py +0 -0
  69. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/backend/frameworks/__init__.py +0 -0
  70. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/backend/frameworks/_anthropic_cache.py +0 -0
  71. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/backend/frameworks/_bedrock_cache.py +0 -0
  72. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/backend/frameworks/dispatch.py +0 -0
  73. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/backend/utils/__init__.py +0 -0
  74. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/backend/utils/extra_headers.py +0 -0
  75. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/backend/utils/mcp_connect.py +0 -0
  76. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/backend/utils/mcp_oauth.py +0 -0
  77. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/backend/utils/tool_call_events.py +0 -0
  78. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/events/__init__.py +0 -0
  79. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/events/decorators/__init__.py +0 -0
  80. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/events/decorators/on_boot.py +0 -0
  81. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/events/decorators/on_shutdown.py +0 -0
  82. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/events/decorators/on_task.py +0 -0
  83. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/events/decorators/on_tool.py +0 -0
  84. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/events/events_module.py +0 -0
  85. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/events/models/__init__.py +0 -0
  86. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/events/models/deployments.py +0 -0
  87. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/events/models/events.py +0 -0
  88. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/events/streaming_server.py +0 -0
  89. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/events/utils/__init__.py +0 -0
  90. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/events/utils/generic.py +0 -0
  91. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/events/utils/git_init.py +0 -0
  92. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/knowledge_bases/__init__.py +0 -0
  93. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/knowledge_bases/knowledge_bases_module.py +0 -0
  94. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/knowledge_bases/models/__init__.py +0 -0
  95. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/knowledge_bases/models/knowledge_bases.py +0 -0
  96. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/knowledge_bases/sub_modules/__init__.py +0 -0
  97. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/knowledge_bases/sub_modules/knowledge_base.py +0 -0
  98. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/knowledge_bases/sub_modules/knowledge_base_document_item.py +0 -0
  99. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/knowledge_bases/utils/__init__.py +0 -0
  100. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/tasks/__init__.py +0 -0
  101. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/tasks/models/__init__.py +0 -0
  102. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/tasks/models/task.py +0 -0
  103. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/tasks/models/tasks_list.py +0 -0
  104. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/tasks/sub_modules/__init__.py +0 -0
  105. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/tasks/sub_modules/task.py +0 -0
  106. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/tasks/tasks_module.py +0 -0
  107. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/tasks/utils/__init__.py +0 -0
  108. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/tasks/utils/files.py +0 -0
  109. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/tasks/utils/media.py +0 -0
  110. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/tasks/utils/model_capabilities.py +0 -0
  111. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/tools_repository/__init__.py +0 -0
  112. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/tools_repository/decorators/__init__.py +0 -0
  113. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/tools_repository/decorators/register_tool.py +0 -0
  114. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/tools_repository/models/__init__.py +0 -0
  115. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/tools_repository/models/mcp.py +0 -0
  116. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/tools_repository/models/tool_invocation_result.py +0 -0
  117. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/tools_repository/sub_modules/__init__.py +0 -0
  118. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/tools_repository/sub_modules/dynamic_tools.py +0 -0
  119. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/tools_repository/sub_modules/tool.py +0 -0
  120. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/tools_repository/tools_repository_module.py +0 -0
  121. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/tools_repository/utils/__init__.py +0 -0
  122. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/tools_repository/utils/generic.py +0 -0
  123. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/tools_repository/utils/local_tools.py +0 -0
  124. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/tools_repository/utils/schemas.py +0 -0
  125. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/modules/tools_repository/utils/workspace_payload.py +0 -0
  126. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/utils/__init__.py +0 -0
  127. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/utils/agents/__init__.py +0 -0
  128. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/utils/cache.py +0 -0
  129. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/utils/env.py +0 -0
  130. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/utils/event_loop.py +0 -0
  131. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/utils/generic.py +0 -0
  132. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk/utils/tools.py +0 -0
  133. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk.egg-info/SOURCES.txt +0 -0
  134. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk.egg-info/dependency_links.txt +0 -0
  135. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk.egg-info/requires.txt +0 -0
  136. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/src/xpander_sdk.egg-info/top_level.txt +0 -0
  137. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/tests/test_action_ledger_dedup.py +0 -0
  138. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/tests/test_anthropic_prompt_cache.py +0 -0
  139. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/tests/test_auto_context_management_toggle.py +0 -0
  140. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/tests/test_bedrock_prompt_cache.py +0 -0
  141. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/tests/test_boot_shutdown_handlers.py +0 -0
  142. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/tests/test_context_optimizer_chunked.py +0 -0
  143. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/tests/test_context_optimizer_perf.py +0 -0
  144. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/tests/test_context_optimizer_recent_actions.py +0 -0
  145. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/tests/test_context_optimizer_status_events.py +0 -0
  146. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/tests/test_context_optimizer_unwrap.py +0 -0
  147. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/tests/test_context_optimizer_window.py +0 -0
  148. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/tests/test_context_retrieve_reoffload.py +0 -0
  149. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/tests/test_context_search.py +0 -0
  150. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/tests/test_context_window_detection.py +0 -0
  151. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/tests/test_cross_subexec_decrypt.py +0 -0
  152. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/tests/test_headroom_l0.py +0 -0
  153. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/tests/test_layer_1_cache_integration.py +0 -0
  154. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/tests/test_mcp_connect_probe.py +0 -0
  155. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/tests/test_parent_update_deep_planning.py +0 -0
  156. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/tests/test_planning_tools_visibility.py +0 -0
  157. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/tests/test_reasoning_inline_gateway.py +0 -0
  158. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/tests/test_reasoning_plan_task_id.py +0 -0
  159. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/tests/test_skills_instructions.py +0 -0
  160. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/tests/test_spawn_bg.py +0 -0
  161. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/tests/test_tool_call_events.py +0 -0
  162. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/tests/test_weak_model_reasoning.py +0 -0
  163. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/tests/test_workspace_cache.py +0 -0
  164. {xpander_sdk-2.0.396 → xpander_sdk-2.0.397}/tests/test_workspace_tools_toggle.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: xpander-sdk
3
- Version: 2.0.396
3
+ Version: 2.0.397
4
4
  Summary: xpander.ai Backend-as-a-service for AI Agents - SDK
5
5
  Home-page: https://www.xpander.ai
6
6
  Author: xpanderAI
@@ -5,7 +5,7 @@ with open("README.md", "r", encoding="utf-8") as fh:
5
5
 
6
6
  setup(
7
7
  name="xpander-sdk",
8
- version="2.0.396",
8
+ version="2.0.397",
9
9
  author="xpanderAI",
10
10
  author_email="dev@xpander.ai",
11
11
  description="xpander.ai Backend-as-a-service for AI Agents - SDK",
@@ -15,7 +15,7 @@ Main Components:
15
15
  For more information, visit: https://xpander.ai
16
16
  """
17
17
 
18
- __version__ = "2.0.396"
18
+ __version__ = "2.0.397"
19
19
 
20
20
  # Backend-related imports
21
21
  from .modules.backend.backend_module import Backend
@@ -248,3 +248,17 @@ PLAN_BLOCK_LABEL = "Execution plan steps"
248
248
  # the tool with empty args. 32K covers any realistic single tool call
249
249
  # while modern Claude models allow far more.
250
250
  LLM_MAX_OUTPUT_TOKENS = _env_int("XPANDER_LLM_MAX_OUTPUT_TOKENS", 32_000)
251
+
252
+ # Args-agnostic per-tool volume ceiling. Pagination runaways vary the cursor
253
+ # on every call and alternating-tool loops reset the consecutive counters, so
254
+ # neither the identical-args detector nor the error-streak breaker ever fires
255
+ # on them. This counts TOTAL calls of one tool across the task (xp* exempt).
256
+ TOTAL_TOOL_CALLS_WARN_AT = _env_int("XPANDER_TOTAL_TOOL_CALLS_WARN_AT", 15)
257
+ MAX_TOTAL_TOOL_CALLS_PER_TOOL = _env_int("XPANDER_MAX_TOTAL_TOOL_CALLS_PER_TOOL", 25)
258
+
259
+ # Plan-churn breaker. Planning/reasoning tools are exempt from stuck detection
260
+ # (they legitimately repeat), so a pure plan/think loop - re-emitting the same
261
+ # decision step with no real tool call in between - previously ran unbounded.
262
+ # Counts consecutive planning/reasoning calls; any other tool resets it.
263
+ PLAN_CHURN_WARN_AT = _env_int("XPANDER_PLAN_CHURN_WARN_AT", 10)
264
+ MAX_PLAN_CHURN = _env_int("XPANDER_MAX_PLAN_CHURN", 16)
@@ -40,6 +40,8 @@ FinalizeReason = Literal[
40
40
  "stagnant_compactions",
41
41
  "repeated_tool_call",
42
42
  "error_streak",
43
+ "tool_overuse",
44
+ "plan_churn",
43
45
  ]
44
46
 
45
47
  # System-prompt override appended to the agent's instructions while
@@ -141,6 +141,8 @@ class FinalizeOnlyState(XPanderSharedModel):
141
141
  "stagnant_compactions",
142
142
  "repeated_tool_call",
143
143
  "error_streak",
144
+ "tool_overuse",
145
+ "plan_churn",
144
146
  ]
145
147
  ] = None
146
148
 
@@ -26,10 +26,14 @@ from xpander_sdk.core.context_optimizer.constants import (
26
26
  FINALIZE_MODE_ENABLED,
27
27
  LEDGER_ENABLED,
28
28
  LLM_MAX_OUTPUT_TOKENS,
29
+ MAX_PLAN_CHURN,
30
+ MAX_TOTAL_TOOL_CALLS_PER_TOOL,
29
31
  PLAN_BLOCK_LABEL,
32
+ PLAN_CHURN_WARN_AT,
30
33
  MANUAL_COMPACT_TOOL_ENABLED,
31
34
  MAX_REPEATED_TOOL_CALLS,
32
35
  REPEATED_TOOL_CALL_WARN_AT,
36
+ TOTAL_TOOL_CALLS_WARN_AT,
33
37
  TRUNCATED_TOOL_CALL_MESSAGE,
34
38
  )
35
39
  from xpander_sdk.core.context_optimizer.context_optimizer import (
@@ -75,6 +79,8 @@ from xpander_sdk.modules.backend.utils.tool_call_events import (
75
79
  get_tool_call_summary,
76
80
  is_agent_gateway_task,
77
81
  is_reasoning_tool,
82
+ PLANNING_TOOLS,
83
+ REASONING_TOOLS,
78
84
  report_reasoning_event,
79
85
  report_tool_call_request,
80
86
  report_tool_call_result,
@@ -667,6 +673,36 @@ def _bump_error_streak(
667
673
  return streak
668
674
 
669
675
 
676
+ def _bump_total_calls(task, function_name: str) -> int:
677
+ """Task-scoped args-agnostic total call count for one tool (0 when no task to pin state on)."""
678
+ if task is None:
679
+ return 0
680
+ counts = getattr(task, "_xp_tool_total_calls", None)
681
+ if not isinstance(counts, dict):
682
+ counts = {}
683
+ try:
684
+ object.__setattr__(task, "_xp_tool_total_calls", counts)
685
+ except Exception:
686
+ return 0
687
+ counts[function_name] = counts.get(function_name, 0) + 1
688
+ return counts[function_name]
689
+
690
+
691
+ _PLAN_CHURN_TOOLS = PLANNING_TOOLS | REASONING_TOOLS
692
+
693
+
694
+ def _bump_plan_churn(task, function_name: str) -> int:
695
+ """Consecutive planning/reasoning calls with no real tool in between; any other tool resets."""
696
+ if task is None:
697
+ return 0
698
+ streak = (getattr(task, "_xp_plan_churn_streak", 0) + 1) if function_name in _PLAN_CHURN_TOOLS else 0
699
+ try:
700
+ object.__setattr__(task, "_xp_plan_churn_streak", streak)
701
+ except Exception:
702
+ return 0
703
+ return streak
704
+
705
+
670
706
  def _schema_satisfiable_by_empty(prop_schema: Any) -> bool:
671
707
  """True when ``{}`` (or omission) validates against *prop_schema*.
672
708
 
@@ -1364,6 +1400,80 @@ async def build_agent_args(
1364
1400
  except Exception:
1365
1401
  pass
1366
1402
 
1403
+ # Args-agnostic per-tool volume guard: pagination varies the cursor every
1404
+ # call and alternating-tool loops reset the consecutive counters, so the
1405
+ # detectors above never fire on those runaway shapes.
1406
+ try:
1407
+ if not function_name.startswith("xp"):
1408
+ total_calls = _bump_total_calls(task, function_name)
1409
+ if total_calls >= MAX_TOTAL_TOOL_CALLS_PER_TOOL:
1410
+ optimizer_for_volume = args.get("compression_manager")
1411
+ if isinstance(optimizer_for_volume, XPanderContextOptimizer):
1412
+ try:
1413
+ enter_finalize_mode(optimizer_for_volume, reason="tool_overuse")
1414
+ except Exception as exc:
1415
+ logger.warning(
1416
+ f"[tool-volume] failed to enter finalize mode after "
1417
+ f"{total_calls}x '{function_name}': {exc}"
1418
+ )
1419
+ logger.warning(
1420
+ f"[tool-volume] aborting tool '{function_name}' for agent "
1421
+ f"{xpander_agent.id}: {total_calls} total calls this task "
1422
+ f"(cap {MAX_TOTAL_TOOL_CALLS_PER_TOOL}); entering finalize mode"
1423
+ )
1424
+ return TOOL_GATE_REJECTION_MESSAGE
1425
+ if total_calls >= TOTAL_TOOL_CALLS_WARN_AT and not stuck_warning:
1426
+ stuck_warning = (
1427
+ f"⚠️ TOOL VOLUME: '{function_name}' has been called {total_calls} times in "
1428
+ f"this task (hard cap {MAX_TOTAL_TOOL_CALLS_PER_TOOL}). Stop paginating or "
1429
+ f"re-querying - work with the data you already have, or report the task as "
1430
+ f"blocked with a short status."
1431
+ )
1432
+ logger.warning(
1433
+ f"[tool-volume] '{function_name}' at {total_calls} total calls for "
1434
+ f"agent {xpander_agent.id}"
1435
+ )
1436
+ except Exception:
1437
+ pass
1438
+
1439
+ # Plan-churn breaker: planning/reasoning tools are exempt from the guards
1440
+ # above, so a pure plan/think loop (re-adding the same decision step with
1441
+ # no real tool call in between) previously ran unbounded.
1442
+ try:
1443
+ optimizer_for_churn = args.get("compression_manager")
1444
+ # finalize mode's allowed read tools (xpget_agent_plan) must not re-trip the breaker
1445
+ finalize_already_active = isinstance(
1446
+ optimizer_for_churn, XPanderContextOptimizer
1447
+ ) and is_finalize_active(optimizer_for_churn)
1448
+ plan_churn = 0 if finalize_already_active else _bump_plan_churn(task, function_name)
1449
+ if plan_churn >= MAX_PLAN_CHURN:
1450
+ if isinstance(optimizer_for_churn, XPanderContextOptimizer):
1451
+ try:
1452
+ enter_finalize_mode(optimizer_for_churn, reason="plan_churn")
1453
+ except Exception as exc:
1454
+ logger.warning(
1455
+ f"[plan-churn] failed to enter finalize mode after "
1456
+ f"{plan_churn} consecutive plan/reasoning calls: {exc}"
1457
+ )
1458
+ logger.warning(
1459
+ f"[plan-churn] aborting tool '{function_name}' for agent "
1460
+ f"{xpander_agent.id}: {plan_churn} consecutive planning/reasoning "
1461
+ f"calls with no real work (cap {MAX_PLAN_CHURN}); entering finalize mode"
1462
+ )
1463
+ return TOOL_GATE_REJECTION_MESSAGE
1464
+ if plan_churn >= PLAN_CHURN_WARN_AT and not stuck_warning:
1465
+ stuck_warning = (
1466
+ f"⚠️ PLAN CHURN: {plan_churn} consecutive planning/reasoning calls with no "
1467
+ f"real tool call in between (hard cap {MAX_PLAN_CHURN}). Stop re-planning - "
1468
+ f"execute the next plan step with an actual tool, or report the task as blocked."
1469
+ )
1470
+ logger.warning(
1471
+ f"[plan-churn] {plan_churn} consecutive plan/reasoning calls for "
1472
+ f"agent {xpander_agent.id} (latest '{function_name}')"
1473
+ )
1474
+ except Exception:
1475
+ pass
1476
+
1367
1477
  # Generate a fresh request_id for this tool invocation so multiple
1368
1478
  # calls to the same tool remain distinct in the activity thread.
1369
1479
  # Deep-planning tools are excluded from activity reporting.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: xpander-sdk
3
- Version: 2.0.396
3
+ Version: 2.0.397
4
4
  Summary: xpander.ai Backend-as-a-service for AI Agents - SDK
5
5
  Home-page: https://www.xpander.ai
6
6
  Author: xpanderAI
File without changes
File without changes
File without changes