ibm-watsonx-orchestrate 1.6.3__tar.gz → 1.6.4__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 (129) hide show
  1. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/PKG-INFO +3 -7
  2. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/pyproject.toml +4 -6
  3. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/__init__.py +2 -1
  4. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/agent_builder/agents/agent.py +3 -3
  5. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/agent_builder/agents/assistant_agent.py +3 -2
  6. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/agent_builder/agents/external_agent.py +3 -2
  7. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/agent_builder/agents/types.py +38 -9
  8. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/agent_builder/connections/connections.py +4 -3
  9. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/agent_builder/connections/types.py +14 -2
  10. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/agent_builder/knowledge_bases/knowledge_base_requests.py +1 -22
  11. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/agent_builder/knowledge_bases/types.py +1 -17
  12. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/agent_builder/tools/base_tool.py +2 -1
  13. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/agent_builder/tools/openapi_tool.py +75 -24
  14. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/agent_builder/tools/python_tool.py +136 -92
  15. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/agent_builder/tools/types.py +17 -11
  16. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/cli/commands/agents/agents_command.py +7 -7
  17. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/cli/commands/agents/agents_controller.py +7 -6
  18. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/cli/commands/channels/types.py +3 -2
  19. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/cli/commands/channels/webchat/channels_webchat_controller.py +1 -2
  20. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/cli/commands/connections/connections_command.py +14 -6
  21. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/cli/commands/connections/connections_controller.py +6 -8
  22. ibm_watsonx_orchestrate-1.6.4/src/ibm_watsonx_orchestrate/cli/commands/copilot/copilot_command.py +65 -0
  23. ibm_watsonx_orchestrate-1.6.4/src/ibm_watsonx_orchestrate/cli/commands/copilot/copilot_controller.py +368 -0
  24. ibm_watsonx_orchestrate-1.6.4/src/ibm_watsonx_orchestrate/cli/commands/copilot/copilot_server_controller.py +170 -0
  25. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/cli/commands/environment/environment_controller.py +5 -5
  26. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/cli/commands/environment/types.py +2 -0
  27. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/cli/commands/evaluations/evaluations_command.py +102 -37
  28. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/cli/commands/evaluations/evaluations_controller.py +20 -2
  29. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/cli/commands/knowledge_bases/knowledge_bases_command.py +0 -18
  30. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/cli/commands/knowledge_bases/knowledge_bases_controller.py +36 -20
  31. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/cli/commands/models/models_command.py +1 -1
  32. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/cli/commands/server/server_command.py +94 -36
  33. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/cli/commands/toolkit/toolkit_command.py +1 -1
  34. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/cli/commands/tools/tools_controller.py +11 -4
  35. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/cli/config.py +3 -3
  36. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/cli/init_helper.py +10 -1
  37. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/cli/main.py +5 -0
  38. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/client/base_api_client.py +12 -0
  39. ibm_watsonx_orchestrate-1.6.4/src/ibm_watsonx_orchestrate/client/copilot/cpe/copilot_cpe_client.py +67 -0
  40. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/client/knowledge_bases/knowledge_base_client.py +1 -1
  41. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/client/local_service_instance.py +3 -1
  42. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/client/service_instance.py +33 -7
  43. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/client/utils.py +15 -13
  44. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/docker/compose-lite.yml +198 -6
  45. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/docker/default.env +36 -12
  46. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/flow_builder/flows/__init__.py +9 -4
  47. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/flow_builder/flows/decorators.py +4 -2
  48. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/flow_builder/flows/events.py +10 -9
  49. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/flow_builder/flows/flow.py +131 -20
  50. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/flow_builder/node.py +18 -1
  51. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/flow_builder/types.py +271 -16
  52. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/flow_builder/utils.py +120 -6
  53. ibm_watsonx_orchestrate-1.6.4/src/ibm_watsonx_orchestrate/utils/exceptions.py +23 -0
  54. ibm_watsonx_orchestrate-1.6.3/src/ibm_watsonx_orchestrate/agent_builder/utils/pydantic_utils.py +0 -149
  55. ibm_watsonx_orchestrate-1.6.3/src/ibm_watsonx_orchestrate/flow_builder/resources/flow_status.openapi.yml +0 -66
  56. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/.gitignore +0 -0
  57. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/LICENSE +0 -0
  58. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/agent_builder/__init__.py +0 -0
  59. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/agent_builder/agents/__init__.py +0 -0
  60. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/agent_builder/agents/webchat_customizations/__init__.py +0 -0
  61. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/agent_builder/agents/webchat_customizations/prompts.py +0 -0
  62. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/agent_builder/agents/webchat_customizations/welcome_content.py +0 -0
  63. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/agent_builder/connections/__init__.py +0 -0
  64. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/agent_builder/knowledge_bases/knowledge_base.py +0 -0
  65. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/agent_builder/model_policies/__init__.py +0 -0
  66. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/agent_builder/model_policies/types.py +0 -0
  67. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/agent_builder/models/__init__.py +0 -0
  68. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/agent_builder/models/types.py +0 -0
  69. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/agent_builder/toolkits/base_toolkit.py +0 -0
  70. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/agent_builder/toolkits/types.py +0 -0
  71. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/agent_builder/tools/__init__.py +0 -0
  72. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/agent_builder/tools/flow_tool.py +0 -0
  73. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/agent_builder/utils/__init__.py +0 -0
  74. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/cli/__init__.py +0 -0
  75. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/cli/commands/__init__.py +0 -0
  76. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/cli/commands/channels/channels_command.py +0 -0
  77. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/cli/commands/channels/channels_controller.py +0 -0
  78. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/cli/commands/channels/webchat/channels_webchat_command.py +0 -0
  79. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/cli/commands/chat/chat_command.py +0 -0
  80. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/cli/commands/environment/environment_command.py +0 -0
  81. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/cli/commands/login/login_command.py +0 -0
  82. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/cli/commands/models/model_provider_mapper.py +0 -0
  83. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/cli/commands/models/models_controller.py +0 -0
  84. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/cli/commands/server/types.py +0 -0
  85. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/cli/commands/settings/__init__.py +0 -0
  86. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/cli/commands/settings/observability/__init__.py +0 -0
  87. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/cli/commands/settings/observability/langfuse/__init__.py +0 -0
  88. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/cli/commands/settings/observability/langfuse/langfuse_command.py +0 -0
  89. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/cli/commands/settings/observability/observability_command.py +0 -0
  90. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/cli/commands/settings/settings_command.py +0 -0
  91. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/cli/commands/toolkit/toolkit_controller.py +0 -0
  92. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/cli/commands/tools/tools_command.py +0 -0
  93. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/cli/commands/tools/types.py +0 -0
  94. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/client/__init__.py +0 -0
  95. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/client/agents/agent_client.py +0 -0
  96. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/client/agents/assistant_agent_client.py +0 -0
  97. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/client/agents/external_agent_client.py +0 -0
  98. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/client/analytics/__init__.py +0 -0
  99. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/client/analytics/llm/__init__.py +0 -0
  100. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/client/analytics/llm/analytics_llm_client.py +0 -0
  101. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/client/base_service_instance.py +0 -0
  102. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/client/client.py +0 -0
  103. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/client/client_errors.py +0 -0
  104. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/client/connections/__init__.py +0 -0
  105. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/client/connections/connections_client.py +0 -0
  106. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/client/connections/utils.py +0 -0
  107. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/client/credentials.py +0 -0
  108. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/client/model_policies/__init__.py +0 -0
  109. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/client/model_policies/model_policies_client.py +0 -0
  110. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/client/models/__init__.py +0 -0
  111. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/client/models/models_client.py +0 -0
  112. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/client/toolkit/toolkit_client.py +0 -0
  113. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/client/tools/tempus_client.py +0 -0
  114. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/client/tools/tool_client.py +0 -0
  115. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/docker/proxy-config-single.yaml +0 -0
  116. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/docker/sdk/ibm_watsonx_orchestrate-0.6.0-py3-none-any.whl +0 -0
  117. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/docker/sdk/ibm_watsonx_orchestrate-0.6.0.tar.gz +0 -0
  118. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/docker/start-up.sh +0 -0
  119. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/docker/tempus/common-config.yaml +0 -0
  120. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/flow_builder/__init__.py +0 -0
  121. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/flow_builder/data_map.py +0 -0
  122. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/flow_builder/flows/constants.py +0 -0
  123. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/run/__init__.py +0 -0
  124. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/run/connections.py +0 -0
  125. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/utils/__init__.py +0 -0
  126. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/utils/logging/__init__.py +0 -0
  127. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/utils/logging/logger.py +0 -0
  128. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/utils/logging/logging.yaml +0 -0
  129. {ibm_watsonx_orchestrate-1.6.3 → ibm_watsonx_orchestrate-1.6.4}/src/ibm_watsonx_orchestrate/utils/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ibm-watsonx-orchestrate
3
- Version: 1.6.3
3
+ Version: 1.6.4
4
4
  Summary: IBM watsonx.orchestrate SDK
5
5
  Author-email: IBM <support@ibm.com>
6
6
  License: MIT License
@@ -10,15 +10,11 @@ Requires-Dist: certifi>=2024.8.30
10
10
  Requires-Dist: click<8.2.0,>=8.0.0
11
11
  Requires-Dist: docstring-parser<1.0,>=0.16
12
12
  Requires-Dist: httpx<1.0.0,>=0.28.1
13
- Requires-Dist: ibm-cloud-sdk-core>=3.22.0
14
- Requires-Dist: ibm-watsonx-orchestrate-evaluation-framework==1.0.6
13
+ Requires-Dist: ibm-cloud-sdk-core>=3.24.2
14
+ Requires-Dist: ibm-watsonx-orchestrate-evaluation-framework==1.0.8
15
15
  Requires-Dist: jsonref==1.1.0
16
- Requires-Dist: jsonschema<5.0.0,>=4.23.0
17
- Requires-Dist: langchain-community<=0.3.25,>=0.3.12
18
16
  Requires-Dist: langchain-core<=0.3.63
19
17
  Requires-Dist: langsmith<=0.3.45
20
- Requires-Dist: munch>=4.0.0
21
- Requires-Dist: numpy>=1.26.0
22
18
  Requires-Dist: packaging>=24.2
23
19
  Requires-Dist: pydantic<3.0.0,>=2.10.3
24
20
  Requires-Dist: pyjwt<3.0.0,>=2.10.1
@@ -20,13 +20,10 @@ dependencies = [
20
20
  "click>=8.0.0,<8.2.0",
21
21
  "docstring-parser>=0.16,<1.0",
22
22
  "httpx>=0.28.1,<1.0.0",
23
- "ibm-cloud-sdk-core>=3.22.0",
23
+ "ibm-cloud-sdk-core>=3.24.2",
24
24
  "jsonref==1.1.0",
25
- "jsonschema>=4.23.0,<5.0.0",
26
- "langchain-community>=0.3.12,<=0.3.25",
27
25
  "langchain-core<=0.3.63",
28
26
  "langsmith<=0.3.45",
29
- "numpy>=1.26.0",
30
27
  "packaging>=24.2",
31
28
  "pydantic>=2.10.3,<3.0.0",
32
29
  "pyjwt>=2.10.1,<3.0.0",
@@ -36,10 +33,9 @@ dependencies = [
36
33
  "rich>=13.9.4,<14.0.0",
37
34
  "typer>=0.15.1,<1.0.0",
38
35
  "urllib3>=2.2.3",
39
- "munch>=4.0.0",
40
36
  "pytz>=2025.2",
41
37
  "redis>=6.0.0",
42
- "ibm_watsonx_orchestrate_evaluation_framework==1.0.6"
38
+ "ibm_watsonx_orchestrate_evaluation_framework==1.0.8"
43
39
  ]
44
40
 
45
41
  [project.optional-dependencies]
@@ -53,6 +49,8 @@ dev = [
53
49
  "black~=22.3.0",
54
50
  "pylint~=2.16.4",
55
51
  ]
52
+ [tool.pytest.ini_options]
53
+ pythonpath = "src"
56
54
 
57
55
  [tool.hatch.envs.default]
58
56
  dependencies = [
@@ -5,7 +5,8 @@
5
5
 
6
6
  pkg_name = "ibm-watsonx-orchestrate"
7
7
 
8
- __version__ = "1.6.3"
8
+ __version__ = "1.6.4"
9
+
9
10
 
10
11
 
11
12
 
@@ -1,6 +1,7 @@
1
1
  import json
2
2
  from ibm_watsonx_orchestrate.utils.utils import yaml_safe_load
3
3
  from .types import AgentSpec
4
+ from ibm_watsonx_orchestrate.utils.exceptions import BadRequest
4
5
 
5
6
 
6
7
  class Agent(AgentSpec):
@@ -13,10 +14,9 @@ class Agent(AgentSpec):
13
14
  elif file.endswith('.json'):
14
15
  content = json.load(f)
15
16
  else:
16
- raise ValueError('file must end in .json, .yaml, or .yml')
17
-
17
+ raise BadRequest('file must end in .json, .yaml, or .yml')
18
18
  if not content.get("spec_version"):
19
- raise ValueError(f"Field 'spec_version' not provided. Please ensure provided spec conforms to a valid spec format")
19
+ raise BadRequest(f"Field 'spec_version' not provided. Please ensure provided spec conforms to a valid spec format")
20
20
  agent = Agent.model_validate(content)
21
21
 
22
22
  return agent
@@ -1,6 +1,7 @@
1
1
  import json
2
2
  from ibm_watsonx_orchestrate.utils.utils import yaml_safe_load
3
3
  from .types import AssistantAgentSpec
4
+ from ibm_watsonx_orchestrate.utils.exceptions import BadRequest
4
5
 
5
6
 
6
7
  class AssistantAgent(AssistantAgentSpec):
@@ -13,10 +14,10 @@ class AssistantAgent(AssistantAgentSpec):
13
14
  elif file.endswith('.json'):
14
15
  content = json.load(f)
15
16
  else:
16
- raise ValueError('file must end in .json, .yaml, or .yml')
17
+ raise BadRequest('file must end in .json, .yaml, or .yml')
17
18
 
18
19
  if not content.get("spec_version"):
19
- raise ValueError(f"Field 'spec_version' not provided. Please ensure provided spec conforms to a valid spec format")
20
+ raise BadRequest(f"Field 'spec_version' not provided. Please ensure provided spec conforms to a valid spec format")
20
21
  agent = AssistantAgent.model_validate(content)
21
22
 
22
23
  return agent
@@ -1,6 +1,7 @@
1
1
  import json
2
2
  from ibm_watsonx_orchestrate.utils.utils import yaml_safe_load
3
3
  from .types import ExternalAgentSpec
4
+ from ibm_watsonx_orchestrate.utils.exceptions import BadRequest
4
5
 
5
6
 
6
7
  class ExternalAgent(ExternalAgentSpec):
@@ -13,10 +14,10 @@ class ExternalAgent(ExternalAgentSpec):
13
14
  elif file.endswith('.json'):
14
15
  content = json.load(f)
15
16
  else:
16
- raise ValueError('file must end in .json, .yaml, or .yml')
17
+ raise BadRequest('file must end in .json, .yaml, or .yml')
17
18
 
18
19
  if not content.get("spec_version"):
19
- raise ValueError(f"Field 'spec_version' not provided. Please ensure provided spec conforms to a valid spec format")
20
+ raise BadRequest(f"Field 'spec_version' not provided. Please ensure provided spec conforms to a valid spec format")
20
21
  agent = ExternalAgent.model_validate(content)
21
22
 
22
23
  return agent
@@ -9,21 +9,44 @@ from ibm_watsonx_orchestrate.agent_builder.knowledge_bases.knowledge_base import
9
9
  from ibm_watsonx_orchestrate.agent_builder.agents.webchat_customizations import StarterPrompts, WelcomeContent
10
10
  from pydantic import Field, AliasChoices
11
11
  from typing import Annotated
12
+ from ibm_watsonx_orchestrate.utils.exceptions import BadRequest
12
13
 
13
14
  from ibm_watsonx_orchestrate.agent_builder.tools.types import JsonSchemaObject
14
15
 
15
16
  # TO-DO: this is just a placeholder. Will update this later to align with backend
16
- DEFAULT_LLM = "watsonx/meta-llama/llama-3-1-70b-instruct"
17
+ DEFAULT_LLM = "watsonx/meta-llama/llama-3-2-90b-vision-instruct"
18
+
19
+ # Handles yaml formatting for multiline strings to improve readability
20
+ def str_presenter(dumper, data):
21
+ if len(data.splitlines()) > 1: # check for multiline string
22
+ data = "\n".join([line.rstrip() for line in data.splitlines()])
23
+ return dumper.represent_scalar('tag:yaml.org,2002:str', data, style='|')
24
+ return dumper.represent_scalar('tag:yaml.org,2002:str', data)
25
+
26
+ yaml.add_representer(str, str_presenter)
27
+ yaml.representer.SafeRepresenter.add_representer(str, str_presenter) # to use with safe_dum
17
28
 
18
29
  class SpecVersion(str, Enum):
19
30
  V1 = "v1"
20
31
 
32
+ def __str__(self):
33
+ return self.value
34
+
35
+ def __repr__(self):
36
+ return repr(self.value)
37
+
21
38
 
22
39
  class AgentKind(str, Enum):
23
40
  NATIVE = "native"
24
41
  EXTERNAL = "external"
25
42
  ASSISTANT = "assistant"
26
43
 
44
+ def __str__(self):
45
+ return self.value
46
+
47
+ def __repr__(self):
48
+ return repr(self.value)
49
+
27
50
  class ExternalAgentAuthScheme(str, Enum):
28
51
  BEARER_TOKEN = 'BEARER_TOKEN'
29
52
  API_KEY = "API_KEY"
@@ -63,7 +86,7 @@ class BaseAgentSpec(BaseModel):
63
86
  elif file.endswith('.json'):
64
87
  json.dump(dumped, f, indent=2)
65
88
  else:
66
- raise ValueError('file must end in .json, .yaml, or .yml')
89
+ raise BadRequest('file must end in .json, .yaml, or .yml')
67
90
 
68
91
  def dumps_spec(self) -> str:
69
92
  dumped = self.model_dump(mode='json', exclude_none=True)
@@ -87,6 +110,12 @@ class AgentStyle(str, Enum):
87
110
  REACT = "react"
88
111
  PLANNER = "planner"
89
112
 
113
+ def __str__(self):
114
+ return self.value
115
+
116
+ def __repr__(self):
117
+ return repr(self.value)
118
+
90
119
  class AgentGuideline(BaseModel):
91
120
  model_config = ConfigDict(arbitrary_types_allowed=True)
92
121
 
@@ -136,7 +165,7 @@ class AgentSpec(BaseAgentSpec):
136
165
  @model_validator(mode="after")
137
166
  def validate_kind(self):
138
167
  if self.kind != AgentKind.NATIVE:
139
- raise ValueError(f"The specified kind '{self.kind}' cannot be used to create a native agent.")
168
+ raise BadRequest(f"The specified kind '{self.kind}' cannot be used to create a native agent.")
140
169
  return self
141
170
 
142
171
  def validate_agent_fields(values: dict) -> dict:
@@ -144,13 +173,13 @@ def validate_agent_fields(values: dict) -> dict:
144
173
  for field in ["id", "name", "kind", "description", "collaborators", "tools", "knowledge_base"]:
145
174
  value = values.get(field)
146
175
  if value and not str(value).strip():
147
- raise ValueError(f"{field} cannot be empty or just whitespace")
176
+ raise BadRequest(f"{field} cannot be empty or just whitespace")
148
177
 
149
178
  name = values.get("name")
150
179
  collaborators = values.get("collaborators", []) if values.get("collaborators", []) else []
151
180
  for collaborator in collaborators:
152
181
  if collaborator == name:
153
- raise ValueError(f"Circular reference detected. The agent '{name}' cannot contain itself as a collaborator")
182
+ raise BadRequest(f"Circular reference detected. The agent '{name}' cannot contain itself as a collaborator")
154
183
 
155
184
  if values.get("style") == AgentStyle.PLANNER:
156
185
  if values.get("custom_join_tool") and values.get("structured_output"):
@@ -197,7 +226,7 @@ class ExternalAgentSpec(BaseAgentSpec):
197
226
  @model_validator(mode="after")
198
227
  def validate_kind_for_external(self):
199
228
  if self.kind != AgentKind.EXTERNAL:
200
- raise ValueError(f"The specified kind '{self.kind}' cannot be used to create an external agent.")
229
+ raise BadRequest(f"The specified kind '{self.kind}' cannot be used to create an external agent.")
201
230
  return self
202
231
 
203
232
  def validate_external_agent_fields(values: dict) -> dict:
@@ -205,7 +234,7 @@ def validate_external_agent_fields(values: dict) -> dict:
205
234
  for field in ["name", "kind", "description", "title", "tags", "api_url", "chat_params", "nickname", "app_id"]:
206
235
  value = values.get(field)
207
236
  if value and not str(value).strip():
208
- raise ValueError(f"{field} cannot be empty or just whitespace")
237
+ raise BadRequest(f"{field} cannot be empty or just whitespace")
209
238
 
210
239
  context_variables = values.get("context_variables")
211
240
  if context_variables is not None:
@@ -250,7 +279,7 @@ class AssistantAgentSpec(BaseAgentSpec):
250
279
  @model_validator(mode="after")
251
280
  def validate_kind_for_external(self):
252
281
  if self.kind != AgentKind.ASSISTANT:
253
- raise ValueError(f"The specified kind '{self.kind}' cannot be used to create an assistant agent.")
282
+ raise BadRequest(f"The specified kind '{self.kind}' cannot be used to create an assistant agent.")
254
283
  return self
255
284
 
256
285
  def validate_assistant_agent_fields(values: dict) -> dict:
@@ -258,7 +287,7 @@ def validate_assistant_agent_fields(values: dict) -> dict:
258
287
  for field in ["name", "kind", "description", "title", "tags", "nickname", "app_id"]:
259
288
  value = values.get(field)
260
289
  if value and not str(value).strip():
261
- raise ValueError(f"{field} cannot be empty or just whitespace")
290
+ raise BadRequest(f"{field} cannot be empty or just whitespace")
262
291
 
263
292
  # Validate context_variables if provided
264
293
  context_variables = values.get("context_variables")
@@ -14,6 +14,7 @@ from ibm_watsonx_orchestrate.agent_builder.connections.types import (
14
14
  )
15
15
 
16
16
  from ibm_watsonx_orchestrate.utils.utils import sanatize_app_id
17
+ from ibm_watsonx_orchestrate.utils.exceptions import BadRequest
17
18
 
18
19
  logger = logging.getLogger(__name__)
19
20
 
@@ -61,7 +62,7 @@ def _clean_env_vars(vars: dict[str:str], requirements: List[str], app_id: str) -
61
62
  missing_requirements_str = ", ".join(missing_requirements)
62
63
  message = f"Missing requirement environment variables '{missing_requirements_str}' for connection '{app_id}'"
63
64
  logger.error(message)
64
- raise ValueError(message)
65
+ raise BadRequest(message)
65
66
 
66
67
  return required_env_vars
67
68
 
@@ -114,7 +115,7 @@ def get_connection_type(app_id: str) -> ConnectionSecurityScheme:
114
115
  if not expected_schema:
115
116
  message = f"No credentials found for connections '{app_id}'"
116
117
  logger.error(message)
117
- raise ValueError(message)
118
+ raise BadRequest(message)
118
119
 
119
120
  auth_types = {e.value for e in ConnectionSecurityScheme}
120
121
  if expected_schema not in auth_types:
@@ -132,6 +133,6 @@ def get_application_connection_credentials(type: ConnectionType, app_id: str) ->
132
133
  if not _validate_schema_type(requested_type=requested_schema, expected_type=expected_schema):
133
134
  message = f"The requested type '{requested_schema}' does not match the type '{expected_schema}' for the connection '{app_id}'"
134
135
  logger.error(message)
135
- raise ValueError(message)
136
+ raise BadRequest(message)
136
137
 
137
138
  return _get_credentials_model(connection_type=requested_schema, app_id=sanitized_app_id)
@@ -75,6 +75,16 @@ class ConnectionType(str, Enum):
75
75
 
76
76
  def __repr__(self):
77
77
  return repr(self.value)
78
+
79
+ class ConnectionSendVia(str,Enum):
80
+ HEADER = 'header'
81
+ BODY = 'body'
82
+
83
+ def __str__(self):
84
+ return self.value
85
+
86
+ def __repr__(self):
87
+ return repr(self.value)
78
88
 
79
89
  OAUTH_CONNECTION_TYPES = {
80
90
  ConnectionType.OAUTH2_AUTH_CODE,
@@ -177,7 +187,7 @@ class OAuth2AuthCodeCredentials(BaseModel):
177
187
  client_secret: str
178
188
  token_url: str
179
189
  authorization_url: str
180
- scopes : Optional[List[str]] = None
190
+ scope : Optional[str] = None
181
191
 
182
192
  # class OAuth2ImplicitCredentials(BaseModel):
183
193
  # client_id: str
@@ -193,7 +203,9 @@ class OAuth2ClientCredentials(BaseModel):
193
203
  client_id: str
194
204
  client_secret: str
195
205
  token_url: str
196
- scopes : Optional[List[str]] = None
206
+ scope : Optional[str] = None
207
+ send_via: ConnectionSendVia = ConnectionSendVia.HEADER
208
+ grant_type: str = "client_credentials"
197
209
 
198
210
  class OAuthOnBehalfOfCredentials(BaseModel):
199
211
  client_id: str
@@ -1,7 +1,6 @@
1
1
  import json
2
2
  from ibm_watsonx_orchestrate.utils.utils import yaml_safe_load
3
- from .types import KnowledgeBaseSpec, PatchKnowledgeBase, KnowledgeBaseKind
4
-
3
+ from .types import KnowledgeBaseSpec
5
4
 
6
5
  class KnowledgeBaseCreateRequest(KnowledgeBaseSpec):
7
6
 
@@ -21,23 +20,3 @@ class KnowledgeBaseCreateRequest(KnowledgeBaseSpec):
21
20
  knowledge_base = KnowledgeBaseSpec.model_validate(content)
22
21
 
23
22
  return knowledge_base
24
-
25
-
26
- class KnowledgeBaseUpdateRequest(PatchKnowledgeBase):
27
-
28
- @staticmethod
29
- def from_spec(file: str) -> 'PatchKnowledgeBase':
30
- with open(file, 'r') as f:
31
- if file.endswith('.yaml') or file.endswith('.yml'):
32
- content = yaml_safe_load(f)
33
- elif file.endswith('.json'):
34
- content = json.load(f)
35
- else:
36
- raise ValueError('file must end in .json, .yaml, or .yml')
37
-
38
- if not content.get("spec_version"):
39
- raise ValueError(f"Field 'spec_version' not provided. Please ensure provided spec conforms to a valid spec format")
40
-
41
- patch = PatchKnowledgeBase.model_validate(content)
42
-
43
- return patch
@@ -3,7 +3,7 @@ from datetime import datetime
3
3
  from uuid import UUID
4
4
  from enum import Enum
5
5
 
6
- from pydantic import BaseModel, model_validator
6
+ from pydantic import BaseModel
7
7
 
8
8
  class SpecVersion(str, Enum):
9
9
  V1 = "v1"
@@ -219,22 +219,6 @@ class KnowledgeBaseBuiltInVectorIndexConfig(BaseModel):
219
219
  chunk_overlap: Optional[int] = None
220
220
  limit: Optional[int] = None
221
221
 
222
- class PatchKnowledgeBase(BaseModel):
223
- """request payload schema"""
224
- description: Optional[str] = None
225
- documents: list[str] = None
226
- conversational_search_tool: Optional[ConversationalSearchConfig] = None
227
- prioritize_built_in_index: Optional[bool] = None
228
- representation: Optional[KnowledgeBaseRepresentation] = None
229
-
230
- @model_validator(mode="after")
231
- def validate_fields(self):
232
- if self.documents and self.conversational_search_tool and self.conversational_search_tool.index_config:
233
- raise ValueError("Must not provide both \"documents\" or \"conversational_search_tool.index_config\"")
234
- if self.conversational_search_tool and self.conversational_search_tool.index_config and len(self.conversational_search_tool.index_config) != 1:
235
- raise ValueError(f"Must provide exactly one conversational_search_tool.index_config. Provided {len(self.conversational_search_tool.index_config)}.")
236
- return self
237
-
238
222
  class KnowledgeBaseSpec(BaseModel):
239
223
  """Schema for a complete knowledge-base."""
240
224
  spec_version: SpecVersion = None
@@ -4,6 +4,7 @@ import yaml
4
4
 
5
5
  from .types import ToolSpec
6
6
 
7
+ from ibm_watsonx_orchestrate.utils.exceptions import BadRequest
7
8
 
8
9
  class BaseTool:
9
10
  __tool_spec__: ToolSpec
@@ -22,7 +23,7 @@ class BaseTool:
22
23
  elif file.endswith('.json'):
23
24
  json.dump(dumped, f, indent=2)
24
25
  else:
25
- raise ValueError('file must end in .json, .yaml, or .yml')
26
+ raise BadRequest('file must end in .json, .yaml, or .yml')
26
27
 
27
28
  def dumps_spec(self) -> str:
28
29
  dumped = self.__tool_spec__.model_dump(mode='json', exclude_unset=True, exclude_none=True, by_alias=True)
@@ -3,6 +3,7 @@ import json
3
3
  import os.path
4
4
  import logging
5
5
  from typing import Dict, Any, List
6
+ from ibm_watsonx_orchestrate.utils.exceptions import BadRequest
6
7
 
7
8
  import yaml
8
9
  import yaml.constructor
@@ -13,7 +14,7 @@ from ibm_watsonx_orchestrate.utils.utils import yaml_safe_load
13
14
  from .types import ToolSpec
14
15
  from .base_tool import BaseTool
15
16
  from .types import HTTP_METHOD, ToolPermission, ToolRequestBody, ToolResponseBody, \
16
- OpenApiToolBinding, \
17
+ OpenApiToolBinding, AcknowledgementBinding, \
17
18
  JsonSchemaObject, ToolBinding, OpenApiSecurityScheme, CallbackBinding
18
19
 
19
20
  import json
@@ -40,7 +41,7 @@ class OpenAPITool(BaseTool):
40
41
  BaseTool.__init__(self, spec=spec)
41
42
 
42
43
  if self.__tool_spec__.binding.openapi is None:
43
- raise ValueError('Missing openapi binding')
44
+ raise BadRequest('Missing openapi binding')
44
45
 
45
46
  async def __call__(self, **kwargs):
46
47
  raise RuntimeError('OpenAPI Tools are only available when deployed onto watson orchestrate or the watson '
@@ -54,10 +55,10 @@ class OpenAPITool(BaseTool):
54
55
  elif file.endswith('.json'):
55
56
  spec = ToolSpec.model_validate(json.load(f))
56
57
  else:
57
- raise ValueError('file must end in .json, .yaml, or .yml')
58
+ raise BadRequest('file must end in .json, .yaml, or .yml')
58
59
 
59
60
  if spec.binding.openapi is None or spec.binding.openapi is None:
60
- raise ValueError('failed to load python tool as the tool had no openapi binding')
61
+ raise BadRequest('failed to load python tool as the tool had no openapi binding')
61
62
 
62
63
  return OpenAPITool(spec=spec)
63
64
 
@@ -108,11 +109,11 @@ def create_openapi_json_tool(
108
109
  paths = openapi_contents.get('paths', {})
109
110
  route = paths.get(http_path)
110
111
  if route is None:
111
- raise ValueError(f"Path {http_path} not found in paths. Available endpoints are: {list(paths.keys())}")
112
+ raise BadRequest(f"Path {http_path} not found in paths. Available endpoints are: {list(paths.keys())}")
112
113
 
113
114
  route_spec = route.get(http_method.lower(), route.get(http_method.upper()))
114
115
  if route_spec is None:
115
- raise ValueError(
116
+ raise BadRequest(
116
117
  f"Path {http_path} did not have an http_method {http_method}. Available methods are {list(route.keys())}")
117
118
 
118
119
  operation_id = re.sub( r'(\W|_)+', '_', route_spec.get('operationId') ) \
@@ -121,12 +122,12 @@ def create_openapi_json_tool(
121
122
  spec_name = name or operation_id
122
123
  spec_permission = permission or _action_to_perm(route_spec.get('x-ibm-operation', {}).get('action'))
123
124
  if spec_name is None:
124
- raise ValueError(
125
- f"No name provided for tool. {http_method}: {http_path} did not specify an operationId, and no name was provided")
125
+ raise BadRequest(
126
+ f"Failed to import tool from endpoint {http_method}: {http_path} as no operationId was provided. An operationId must be provided to generate the name of the tool.")
126
127
 
127
128
  spec_description = description or route_spec.get('description')
128
129
  if spec_description is None:
129
- raise ValueError(
130
+ raise BadRequest(
130
131
  f"No description provided for tool. {http_method}: {http_path} did not specify a description field, and no description was provided")
131
132
 
132
133
  spec = ToolSpec(
@@ -199,42 +200,89 @@ def create_openapi_json_tool(
199
200
  for needed_security in route_spec.get('security', []) + openapi_spec.get('security', []):
200
201
  name = next(iter(needed_security.keys()), None)
201
202
  if name is None or name not in security_schemes_map:
202
- raise ValueError(f"Invalid openapi spec, {HTTP_METHOD} {http_path} asks for a security scheme of {name}, "
203
+ raise BadRequest(f"Invalid openapi spec, {HTTP_METHOD} {http_path} asks for a security scheme of {name}, "
203
204
  f"but no such security scheme was configured in the .security section of the spec")
204
205
 
205
206
  security.append(security_schemes_map[name])
206
207
 
207
208
  # If it's an async tool, add callback binding
208
209
  if spec.is_async:
209
-
210
-
211
210
  callbacks = route_spec.get('callbacks', {})
212
211
  callback_name = next(iter(callbacks.keys()))
213
212
  callback_spec = callbacks[callback_name]
214
213
  callback_path = next(iter(callback_spec.keys()))
215
214
  callback_method = next(iter(callback_spec[callback_path].keys()))
215
+ callback_operation = callback_spec[callback_path][callback_method]
216
216
 
217
- # Phase 1: Create a separate input schema for callback that excludes callbackUrl
218
- # Note: Currently assuming the callback URL parameter will be named 'callbackUrl' in the OpenAPI spec
219
- # Future phases will handle other naming conventions
217
+ # Extract callback input schema from the callback requestBody
220
218
  callback_input_schema = ToolRequestBody(
219
+ type='object',
220
+ properties={},
221
+ required=[]
222
+ )
223
+
224
+ # Handle callback parameters (query, path, header params)
225
+ callback_parameters = callback_operation.get('parameters') or []
226
+ for parameter in callback_parameters:
227
+ name = f"{parameter['in']}_{parameter['name']}"
228
+ if parameter.get('required'):
229
+ callback_input_schema.required.append(name)
230
+ parameter['schema']['title'] = parameter['name']
231
+ parameter['schema']['description'] = parameter.get('description', None)
232
+ callback_input_schema.properties[name] = JsonSchemaObject.model_validate(parameter['schema'])
233
+ callback_input_schema.properties[name].in_field = parameter['in']
234
+ callback_input_schema.properties[name].aliasName = parameter['name']
235
+
236
+ # Handle callback request body
237
+ callback_request_body_params = callback_operation.get('requestBody', {}).get('content', {}).get(http_response_content_type, {}).get('schema', None)
238
+ if callback_request_body_params is not None:
239
+ callback_input_schema.required.append('__requestBody__')
240
+ callback_request_body_params = copy.deepcopy(callback_request_body_params)
241
+ callback_request_body_params['in'] = 'body'
242
+ if callback_request_body_params.get('title') is None:
243
+ callback_request_body_params['title'] = 'CallbackRequestBody'
244
+ if callback_request_body_params.get('description') is None:
245
+ callback_request_body_params['description'] = 'The callback request body used for this async operation.'
246
+
247
+ callback_input_schema.properties['__requestBody__'] = JsonSchemaObject.model_validate(callback_request_body_params)
248
+
249
+ # Extract callback output schema
250
+ callback_responses = callback_operation.get('responses', {})
251
+ callback_response = callback_responses.get(str(http_success_response_code), {})
252
+ callback_response_description = callback_response.get('description')
253
+ callback_response_schema = callback_response.get('content', {}).get(http_response_content_type, {}).get('schema', {})
254
+
255
+ callback_response_schema['required'] = []
256
+ callback_output_schema = ToolResponseBody.model_validate(callback_response_schema)
257
+ callback_output_schema.description = callback_response_description
258
+
259
+ # Remove callbackUrl parameter from main tool input schema
260
+ original_input_schema = ToolRequestBody(
221
261
  type='object',
222
262
  properties={k: v for k, v in spec.input_schema.properties.items() if not k.endswith('_callbackUrl')},
223
263
  required=[r for r in spec.input_schema.required if not r.endswith('_callbackUrl')]
224
264
  )
265
+ spec.input_schema = original_input_schema
225
266
 
226
- if callback_input_schema:
227
- spec.input_schema = callback_input_schema
228
-
267
+ original_response_schema = spec.output_schema
268
+
229
269
  callback_binding = CallbackBinding(
230
270
  callback_url=callback_path,
231
271
  method=callback_method.upper(),
232
- input_schema=callback_input_schema,
233
- output_schema=spec.output_schema
272
+ output_schema=callback_output_schema
234
273
  )
235
274
 
275
+ # Create acknowledgement binding with the original response schema
276
+ acknowledgement_binding = AcknowledgementBinding(
277
+ output_schema=original_response_schema
278
+ )
279
+
280
+ # For async tools, set the main tool's output_schema to the callback's input_schema
281
+ spec.output_schema = callback_input_schema
282
+
236
283
  else:
237
284
  callback_binding = None
285
+ acknowledgement_binding = None
238
286
 
239
287
  openapi_binding = OpenApiToolBinding(
240
288
  http_path=http_path,
@@ -247,6 +295,9 @@ def create_openapi_json_tool(
247
295
  if callback_binding is not None:
248
296
  openapi_binding.callback = callback_binding
249
297
 
298
+ if acknowledgement_binding is not None:
299
+ openapi_binding.acknowledgement = acknowledgement_binding
300
+
250
301
  spec.binding = ToolBinding(openapi=openapi_binding)
251
302
 
252
303
  return OpenAPITool(spec=spec)
@@ -260,23 +311,23 @@ async def _get_openapi_spec_from_uri(openapi_uri: str) -> Dict[str, Any]:
260
311
  elif openapi_uri.endswith('.yaml') or openapi_uri.endswith('.yml'):
261
312
  openapi_contents = yaml_safe_load(fp)
262
313
  else:
263
- raise ValueError(
314
+ raise BadRequest(
264
315
  f"Unexpected file extension for file {openapi_uri}, expected one of [.json, .yaml, .yml]")
265
316
  elif openapi_uri.endswith('.json'):
266
317
  async with httpx.AsyncClient() as client:
267
318
  r = await client.get(openapi_uri)
268
319
  if r.status_code != 200:
269
- raise ValueError(f"Failed to fetch an openapi spec from {openapi_uri}, status code: {r.status_code}")
320
+ raise BadRequest(f"Failed to fetch an openapi spec from {openapi_uri}, status code: {r.status_code}")
270
321
  openapi_contents = r.json()
271
322
  elif openapi_uri.endswith('.yaml'):
272
323
  async with httpx.AsyncClient() as client:
273
324
  r = await client.get(openapi_uri)
274
325
  if r.status_code != 200:
275
- raise ValueError(f"Failed to fetch an openapi spec from {openapi_uri}, status code: {r.status_code}")
326
+ raise BadRequest(f"Failed to fetch an openapi spec from {openapi_uri}, status code: {r.status_code}")
276
327
  openapi_contents = yaml_safe_load(r.text)
277
328
 
278
329
  if openapi_contents is None:
279
- raise ValueError(f"Unrecognized path or uri {openapi_uri}")
330
+ raise BadRequest(f"Unrecognized path or uri {openapi_uri}")
280
331
 
281
332
  return openapi_contents
282
333