ibm-watsonx-orchestrate 1.2.0__tar.gz → 1.3.0__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 (92) hide show
  1. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/PKG-INFO +3 -2
  2. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/pyproject.toml +2 -1
  3. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/__init__.py +1 -1
  4. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/agent_builder/agents/types.py +4 -1
  5. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/agent_builder/knowledge_bases/knowledge_base.py +16 -3
  6. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/agent_builder/knowledge_bases/knowledge_base_requests.py +4 -20
  7. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/agent_builder/knowledge_bases/types.py +4 -13
  8. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/agent_builder/tools/openapi_tool.py +4 -12
  9. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/agents/agents_controller.py +2 -0
  10. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/knowledge_bases/knowledge_bases_command.py +2 -2
  11. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/knowledge_bases/knowledge_bases_controller.py +63 -38
  12. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/tools/tools_controller.py +13 -14
  13. ibm_watsonx_orchestrate-1.3.0/src/ibm_watsonx_orchestrate/cli/init_helper.py +43 -0
  14. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/main.py +3 -1
  15. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/client/connections/connections_client.py +13 -13
  16. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/docker/default.env +2 -2
  17. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/.gitignore +0 -0
  18. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/LICENSE +0 -0
  19. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/agent_builder/__init__.py +0 -0
  20. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/agent_builder/agents/__init__.py +0 -0
  21. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/agent_builder/agents/agent.py +0 -0
  22. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/agent_builder/agents/assistant_agent.py +0 -0
  23. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/agent_builder/agents/external_agent.py +0 -0
  24. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/agent_builder/connections/__init__.py +0 -0
  25. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/agent_builder/connections/connections.py +0 -0
  26. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/agent_builder/connections/types.py +0 -0
  27. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/agent_builder/tools/__init__.py +0 -0
  28. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/agent_builder/tools/base_tool.py +0 -0
  29. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/agent_builder/tools/python_tool.py +0 -0
  30. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/agent_builder/tools/types.py +0 -0
  31. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/agent_builder/utils/__init__.py +0 -0
  32. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/agent_builder/utils/pydantic_utils.py +0 -0
  33. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/__init__.py +0 -0
  34. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/__init__.py +0 -0
  35. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/agents/agents_command.py +0 -0
  36. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/channels/channels_command.py +0 -0
  37. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/channels/channels_controller.py +0 -0
  38. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/channels/types.py +0 -0
  39. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/channels/webchat/channels_webchat_command.py +0 -0
  40. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/channels/webchat/channels_webchat_controller.py +0 -0
  41. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/chat/chat_command.py +0 -0
  42. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/connections/connections_command.py +0 -0
  43. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/connections/connections_controller.py +0 -0
  44. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/environment/environment_command.py +0 -0
  45. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/environment/environment_controller.py +0 -0
  46. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/environment/types.py +0 -0
  47. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/login/login_command.py +0 -0
  48. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/models/models_command.py +0 -0
  49. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/server/server_command.py +0 -0
  50. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/settings/__init__.py +0 -0
  51. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/settings/observability/__init__.py +0 -0
  52. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/settings/observability/langfuse/__init__.py +0 -0
  53. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/settings/observability/langfuse/langfuse_command.py +0 -0
  54. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/settings/observability/observability_command.py +0 -0
  55. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/settings/settings_command.py +0 -0
  56. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/toolkit/toolkit_command.py +0 -0
  57. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/toolkit/toolkit_controller.py +0 -0
  58. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/tools/tools_command.py +0 -0
  59. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/tools/types.py +0 -0
  60. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/config.py +0 -0
  61. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/client/__init__.py +0 -0
  62. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/client/agents/agent_client.py +0 -0
  63. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/client/agents/assistant_agent_client.py +0 -0
  64. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/client/agents/external_agent_client.py +0 -0
  65. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/client/analytics/__init__.py +0 -0
  66. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/client/analytics/llm/__init__.py +0 -0
  67. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/client/analytics/llm/analytics_llm_client.py +0 -0
  68. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/client/base_api_client.py +0 -0
  69. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/client/base_service_instance.py +0 -0
  70. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/client/client.py +0 -0
  71. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/client/client_errors.py +0 -0
  72. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/client/connections/__init__.py +0 -0
  73. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/client/connections/utils.py +0 -0
  74. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/client/credentials.py +0 -0
  75. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/client/knowledge_bases/knowledge_base_client.py +0 -0
  76. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/client/local_service_instance.py +0 -0
  77. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/client/service_instance.py +0 -0
  78. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/client/toolkit/toolkit_client.py +0 -0
  79. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/client/tools/tool_client.py +0 -0
  80. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/client/utils.py +0 -0
  81. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/docker/compose-lite.yml +0 -0
  82. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/docker/sdk/ibm_watsonx_orchestrate-0.6.0-py3-none-any.whl +0 -0
  83. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/docker/sdk/ibm_watsonx_orchestrate-0.6.0.tar.gz +0 -0
  84. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/docker/start-up.sh +0 -0
  85. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/docker/tempus/common-config.yaml +0 -0
  86. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/run/__init__.py +0 -0
  87. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/run/connections.py +0 -0
  88. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/utils/__init__.py +0 -0
  89. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/utils/logging/__init__.py +0 -0
  90. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/utils/logging/logger.py +0 -0
  91. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/utils/logging/logging.yaml +0 -0
  92. {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/utils/utils.py +0 -0
@@ -1,12 +1,13 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ibm-watsonx-orchestrate
3
- Version: 1.2.0
3
+ Version: 1.3.0
4
4
  Summary: IBM watsonx.orchestrate SDK
5
5
  Author-email: IBM <support@ibm.com>
6
6
  License: MIT License
7
7
  License-File: LICENSE
8
8
  Requires-Python: <3.14,>=3.11
9
9
  Requires-Dist: certifi>=2024.8.30
10
+ Requires-Dist: click<8.2.0,>=8.0.0
10
11
  Requires-Dist: docstring-parser<1.0,>=0.16
11
12
  Requires-Dist: httpx<1.0.0,>=0.28.1
12
13
  Requires-Dist: ibm-cloud-sdk-core>=3.22.0
@@ -19,7 +20,7 @@ Requires-Dist: pydantic<3.0.0,>=2.10.3
19
20
  Requires-Dist: pyjwt<3.0.0,>=2.10.1
20
21
  Requires-Dist: python-dotenv>=1.0.0
21
22
  Requires-Dist: pyyaml<7.0.0,>=6.0.2
22
- Requires-Dist: requests>=2.32.3
23
+ Requires-Dist: requests>=2.32.0
23
24
  Requires-Dist: rich<14.0.0,>=13.9.4
24
25
  Requires-Dist: typer<1.0.0,>=0.15.1
25
26
  Requires-Dist: urllib3>=2.2.3
@@ -17,6 +17,7 @@ requires-python = ">=3.11, <3.14"
17
17
  classifiers = []
18
18
  dependencies = [
19
19
  "certifi>=2024.8.30",
20
+ "click>=8.0.0,<8.2.0",
20
21
  "docstring-parser>=0.16,<1.0",
21
22
  "httpx>=0.28.1,<1.0.0",
22
23
  "ibm-cloud-sdk-core>=3.22.0",
@@ -29,7 +30,7 @@ dependencies = [
29
30
  "pyjwt>=2.10.1,<3.0.0",
30
31
  "python-dotenv>=1.0.0",
31
32
  "pyyaml>=6.0.2,<7.0.0",
32
- "requests>=2.32.3",
33
+ "requests>=2.32.0",
33
34
  "rich>=13.9.4,<14.0.0",
34
35
  "typer>=0.15.1,<1.0.0",
35
36
  "urllib3>=2.2.3"
@@ -5,7 +5,7 @@
5
5
 
6
6
  pkg_name = "ibm-watsonx-orchestrate"
7
7
 
8
- __version__ = "1.2.0"
8
+ __version__ = "1.3.0"
9
9
 
10
10
 
11
11
 
@@ -5,6 +5,7 @@ from typing import List, Optional, Dict
5
5
  from pydantic import BaseModel, model_validator, ConfigDict
6
6
  from ibm_watsonx_orchestrate.agent_builder.tools import BaseTool
7
7
  from ibm_watsonx_orchestrate.agent_builder.knowledge_bases.types import KnowledgeBaseSpec
8
+ from ibm_watsonx_orchestrate.agent_builder.knowledge_bases.knowledge_base import KnowledgeBase
8
9
  from pydantic import Field, AliasChoices
9
10
  from typing import Annotated
10
11
 
@@ -85,6 +86,8 @@ class AgentSpec(BaseAgentSpec):
85
86
  def __init__(self, *args, **kwargs):
86
87
  if "tools" in kwargs and kwargs["tools"]:
87
88
  kwargs["tools"] = [x.__tool_spec__.name if isinstance(x, BaseTool) else x for x in kwargs["tools"]]
89
+ if "knowledge_base" in kwargs and kwargs["knowledge_base"]:
90
+ kwargs["knowledge_base"] = [x.name if isinstance(x, KnowledgeBase) else x for x in kwargs["knowledge_base"]]
88
91
  if "collaborators" in kwargs and kwargs["collaborators"]:
89
92
  kwargs["collaborators"] = [x.name if isinstance(x, BaseAgentSpec) else x for x in kwargs["collaborators"]]
90
93
  super().__init__(*args, **kwargs)
@@ -101,7 +104,7 @@ class AgentSpec(BaseAgentSpec):
101
104
 
102
105
  def validate_agent_fields(values: dict) -> dict:
103
106
  # Check for empty strings or whitespace
104
- for field in ["id", "name", "kind", "description", "collaborators", "tools"]:
107
+ for field in ["id", "name", "kind", "description", "collaborators", "tools", "knowledge_base"]:
105
108
  value = values.get(field)
106
109
  if value and not str(value).strip():
107
110
  raise ValueError(f"{field} cannot be empty or just whitespace")
@@ -1,7 +1,7 @@
1
1
  import json
2
2
  from ibm_watsonx_orchestrate.utils.utils import yaml_safe_load
3
- from .types import KnowledgeBaseSpec
4
-
3
+ from .types import KnowledgeBaseSpec, KnowledgeBaseKind
4
+ from pydantic import model_validator
5
5
 
6
6
  class KnowledgeBase(KnowledgeBaseSpec):
7
7
 
@@ -24,4 +24,17 @@ class KnowledgeBase(KnowledgeBaseSpec):
24
24
  return f"KnowledgeBase(id='{self.id}', name='{self.name}', description='{self.description}')"
25
25
 
26
26
  def __str__(self):
27
- return self.__repr__()
27
+ return self.__repr__()
28
+
29
+ # Not a model validator since we only want to validate this on import
30
+ def validate_documents_or_index_exists(self):
31
+ if self.documents and self.conversational_search_tool and self.conversational_search_tool.index_config or \
32
+ (not self.documents and (not self.conversational_search_tool or not self.conversational_search_tool.index_config)):
33
+ raise ValueError("Must provide either \"documents\" or \"conversational_search_tool.index_config\", but not both")
34
+ return self
35
+
36
+ @model_validator(mode="after")
37
+ def validate_kind(self):
38
+ if self.kind != KnowledgeBaseKind.KNOWLEDGE_BASE:
39
+ raise ValueError(f"The specified kind '{self.kind}' cannot be used to create a knowledge base")
40
+ return self
@@ -1,12 +1,12 @@
1
1
  import json
2
2
  from ibm_watsonx_orchestrate.utils.utils import yaml_safe_load
3
- from .types import CreateKnowledgeBase, PatchKnowledgeBase, KnowledgeBaseKind
3
+ from .types import KnowledgeBaseSpec, PatchKnowledgeBase, KnowledgeBaseKind
4
4
 
5
5
 
6
- class KnowledgeBaseCreateRequest(CreateKnowledgeBase):
6
+ class KnowledgeBaseCreateRequest(KnowledgeBaseSpec):
7
7
 
8
8
  @staticmethod
9
- def from_spec(file: str) -> 'CreateKnowledgeBase':
9
+ def from_spec(file: str) -> 'KnowledgeBaseSpec':
10
10
  with open(file, 'r') as f:
11
11
  if file.endswith('.yaml') or file.endswith('.yml'):
12
12
  content = yaml_safe_load(f)
@@ -15,20 +15,10 @@ class KnowledgeBaseCreateRequest(CreateKnowledgeBase):
15
15
  else:
16
16
  raise ValueError('file must end in .json, .yaml, or .yml')
17
17
 
18
- if (content.get('documents') and content.get("conversational_search_tool", {}).get("index_config")) or \
19
- (not content.get('documents') and not content.get("conversational_search_tool", {}).get("index_config")):
20
- raise ValueError("Must provide either \"documents\" or \"conversational_search_tool.index_config\", but not both")
21
-
22
18
  if not content.get("spec_version"):
23
19
  raise ValueError(f"Field 'spec_version' not provided. Please ensure provided spec conforms to a valid spec format")
24
20
 
25
- if not content.get("kind"):
26
- raise ValueError(f"Field 'kind' not provided. Should be 'knowledge_base'")
27
-
28
- if content.get("kind") != KnowledgeBaseKind.KNOWLEDGE_BASE:
29
- raise ValueError(f"Field 'kind' should be 'knowledge_base', but is set to '{content.get('kind')}'")
30
-
31
- knowledge_base = CreateKnowledgeBase.model_validate(content)
21
+ knowledge_base = KnowledgeBaseSpec.model_validate(content)
32
22
 
33
23
  return knowledge_base
34
24
 
@@ -48,12 +38,6 @@ class KnowledgeBaseUpdateRequest(PatchKnowledgeBase):
48
38
  if not content.get("spec_version"):
49
39
  raise ValueError(f"Field 'spec_version' not provided. Please ensure provided spec conforms to a valid spec format")
50
40
 
51
- if not content.get("kind"):
52
- raise ValueError(f"Field 'kind' not provided. Should be 'knowledge_base'")
53
-
54
- if content.get("kind") != KnowledgeBaseKind.KNOWLEDGE_BASE:
55
- raise ValueError(f"Field 'kind' should be 'knowledge_base', but is set to '{content.get('kind')}'")
56
-
57
41
  patch = PatchKnowledgeBase.model_validate(content)
58
42
 
59
43
  return patch
@@ -206,16 +206,6 @@ class KnowledgeBaseBuiltInVectorIndexConfig(BaseModel):
206
206
  chunk_overlap: Optional[int] = None
207
207
  limit: Optional[int] = None
208
208
 
209
- class CreateKnowledgeBase(BaseModel):
210
- """request payload schema"""
211
- name: Optional[str] = None
212
- description: Optional[str] = None
213
- documents: list[str] = None
214
- vector_index: Optional[KnowledgeBaseBuiltInVectorIndexConfig] = None
215
- conversational_search_tool: Optional[ConversationalSearchConfig] = None
216
- prioritize_built_in_index: Optional[bool] = None
217
-
218
-
219
209
  class PatchKnowledgeBase(BaseModel):
220
210
  """request payload schema"""
221
211
  description: Optional[str] = None
@@ -224,20 +214,21 @@ class PatchKnowledgeBase(BaseModel):
224
214
  prioritize_built_in_index: Optional[bool] = None
225
215
  representation: Optional[KnowledgeBaseRepresentation] = None
226
216
 
227
-
228
217
  class KnowledgeBaseSpec(BaseModel):
229
218
  """Schema for a complete knowledge-base."""
230
219
  spec_version: SpecVersion = None
231
220
  kind: KnowledgeBaseKind = KnowledgeBaseKind.KNOWLEDGE_BASE
232
221
  id: Optional[UUID] = None
233
222
  tenant_id: Optional[str] = None
234
- name: Optional[str] = None
223
+ name: str
235
224
  description: Optional[str] = None
236
225
  vector_index: Optional[KnowledgeBaseBuiltInVectorIndexConfig] = None
237
226
  conversational_search_tool: Optional[ConversationalSearchConfig] | Optional[UUID] = None
238
227
  prioritize_built_in_index: Optional[bool] = None
228
+ representation: Optional[KnowledgeBaseRepresentation] = None
239
229
  vector_index_id: Optional[UUID] = None
240
230
  created_by: Optional[str] = None
241
231
  created_on: Optional[datetime] = None
242
232
  updated_at: Optional[datetime] = None
243
-
233
+ # For import/update
234
+ documents: list[str] = None
@@ -115,17 +115,9 @@ def create_openapi_json_tool(
115
115
  raise ValueError(
116
116
  f"Path {http_path} did not have an http_method {http_method}. Available methods are {list(route.keys())}")
117
117
 
118
- operation_id = (
119
- re.sub(
120
- '_+',
121
- '_',
122
- re.sub(
123
- r'[^a-zA-Z_]',
124
- '_',
125
- route_spec.get('operationId', None)
126
- )
127
- )
128
- ) if route_spec.get('operationId', None) is not None else None
118
+ operation_id = re.sub( r'(\W|_)+', '_', route_spec.get('operationId') ) \
119
+ if route_spec.get('operationId', None) else None
120
+
129
121
  spec_name = name or operation_id
130
122
  spec_permission = permission or _action_to_perm(route_spec.get('x-ibm-operation', {}).get('action'))
131
123
  if spec_name is None:
@@ -142,7 +134,7 @@ def create_openapi_json_tool(
142
134
  description=spec_description,
143
135
  permission=spec_permission
144
136
  )
145
-
137
+
146
138
  spec.input_schema = input_schema or ToolRequestBody(
147
139
  type='object',
148
140
  properties={},
@@ -11,6 +11,7 @@ from copy import deepcopy
11
11
 
12
12
  from typing import Iterable, List
13
13
  from ibm_watsonx_orchestrate.cli.commands.tools.tools_controller import import_python_tool
14
+ from ibm_watsonx_orchestrate.cli.commands.knowledge_bases.knowledge_bases_controller import import_python_knowledge_base
14
15
 
15
16
  from ibm_watsonx_orchestrate.agent_builder.agents import (
16
17
  Agent,
@@ -33,6 +34,7 @@ logger = logging.getLogger(__name__)
33
34
  def import_python_agent(file: str) -> List[Agent | ExternalAgent | AssistantAgent]:
34
35
  # Import tools
35
36
  import_python_tool(file)
37
+ import_python_knowledge_base(file)
36
38
 
37
39
  file_path = Path(file)
38
40
  file_directory = file_path.parent
@@ -9,7 +9,7 @@ knowledge_bases_app = typer.Typer(no_args_is_help=True)
9
9
  def knowledge_base_import(
10
10
  file: Annotated[
11
11
  str,
12
- typer.Option("--file", "-f", help="YAML file with knowledge base definition"),
12
+ typer.Option("--file", "-f", help="YAML, JSON or Python file with knowledge base definition(s)"),
13
13
  ],
14
14
  app_id: Annotated[
15
15
  str, typer.Option(
@@ -25,7 +25,7 @@ def knowledge_base_import(
25
25
  def knowledge_base_patch(
26
26
  file: Annotated[
27
27
  str,
28
- typer.Option("--file", "-f", help="YAML file with knowledge base definition"),
28
+ typer.Option("--file", "-f", help="YAML or JSON file with knowledge base definition"),
29
29
  ],
30
30
  name: Annotated[
31
31
  str,
@@ -3,17 +3,44 @@ import json
3
3
  import rich
4
4
  import requests
5
5
  import logging
6
+ import importlib
7
+ import inspect
8
+ from pathlib import Path
9
+ from typing import List
6
10
 
7
- from ibm_watsonx_orchestrate.agent_builder.knowledge_bases.knowledge_base_requests import KnowledgeBaseCreateRequest, KnowledgeBaseUpdateRequest
11
+ from ibm_watsonx_orchestrate.agent_builder.knowledge_bases.knowledge_base_requests import KnowledgeBaseUpdateRequest
8
12
  from ibm_watsonx_orchestrate.agent_builder.knowledge_bases.knowledge_base import KnowledgeBase
9
13
  from ibm_watsonx_orchestrate.client.knowledge_bases.knowledge_base_client import KnowledgeBaseClient
10
14
  from ibm_watsonx_orchestrate.client.base_api_client import ClientAPIException
11
15
  from ibm_watsonx_orchestrate.client.connections import get_connections_client
12
-
13
16
  from ibm_watsonx_orchestrate.client.utils import instantiate_client
14
17
 
15
18
  logger = logging.getLogger(__name__)
16
19
 
20
+ def import_python_knowledge_base(file: str) -> List[KnowledgeBase]:
21
+ file_path = Path(file)
22
+ file_directory = file_path.parent
23
+ file_name = file_path.stem
24
+ sys.path.append(str(file_directory))
25
+ module = importlib.import_module(file_name)
26
+ del sys.path[-1]
27
+
28
+ knowledge_bases = []
29
+ for _, obj in inspect.getmembers(module):
30
+ if isinstance(obj, KnowledgeBase):
31
+ knowledge_bases.append(obj)
32
+ return knowledge_bases
33
+
34
+ def parse_file(file: str) -> List[KnowledgeBase]:
35
+ if file.endswith('.yaml') or file.endswith('.yml') or file.endswith(".json"):
36
+ knowledge_base = KnowledgeBase.from_spec(file=file)
37
+ return [knowledge_base]
38
+ elif file.endswith('.py'):
39
+ knowledge_bases = import_python_knowledge_base(file)
40
+ return knowledge_bases
41
+ else:
42
+ raise ValueError("file must end in .json, .yaml, .yml or .py")
43
+
17
44
  def to_column_name(col: str):
18
45
  return " ".join([word.capitalize() if not word[0].isupper() else word for word in col.split("_")])
19
46
 
@@ -34,45 +61,43 @@ class KnowledgeBaseController:
34
61
 
35
62
  def import_knowledge_base(self, file: str, app_id: str):
36
63
  client = self.get_client()
37
- create_request = KnowledgeBaseCreateRequest.from_spec(file=file)
38
64
 
39
- try:
40
- if create_request.documents:
41
- try:
65
+ knowledge_bases = parse_file(file=file)
66
+ for kb in knowledge_bases:
67
+ try:
68
+ kb.validate_documents_or_index_exists()
69
+ if kb.documents:
42
70
  file_dir = "/".join(file.split("/")[:-1])
43
- files = [('files', (get_file_name(file_path), open(file_path if file_path.startswith("/") else f"{file_dir}/{file_path}", 'rb'))) for file_path in create_request.documents]
44
- except Exception as e:
45
- logger.error(f"Error importing knowledge base: {str(e).replace('[Errno 2] ', '')}")
46
- sys.exit(1);
47
-
48
- payload = create_request.model_dump(exclude_none=True);
49
- payload.pop('documents');
50
-
51
- client.create_built_in(payload=payload, files=files)
52
- else:
53
- if len(create_request.conversational_search_tool.index_config) != 1:
54
- raise ValueError(f"Must provide exactly one conversational_search_tool.index_config. Provided {len(create_request.conversational_search_tool.index_config)}.")
71
+ files = [('files', (get_file_name(file_path), open(file_path if file_path.startswith("/") else (file_path if not file_dir else f"{file_dir}/{file_path}"), 'rb'))) for file_path in kb.documents]
72
+
73
+ payload = kb.model_dump(exclude_none=True);
74
+ payload.pop('documents');
75
+
76
+ client.create_built_in(payload=payload, files=files)
77
+ else:
78
+ if len(kb.conversational_search_tool.index_config) != 1:
79
+ raise ValueError(f"Must provide exactly one conversational_search_tool.index_config. Provided {len(kb.conversational_search_tool.index_config)}.")
80
+
81
+ if app_id:
82
+ connections_client = get_connections_client()
83
+ connection_id = None
84
+ if app_id is not None:
85
+ connections = connections_client.get_draft_by_app_id(app_id=app_id)
86
+ if not connections:
87
+ logger.error(f"No connection exists with the app-id '{app_id}'")
88
+ exit(1)
89
+
90
+ connection_id = connections.connection_id
91
+ kb.conversational_search_tool.index_config[0].connection_id = connection_id
92
+
93
+ client.create(payload=kb.model_dump(exclude_none=True))
55
94
 
56
- if app_id:
57
- connections_client = get_connections_client()
58
- connection_id = None
59
- if app_id is not None:
60
- connections = connections_client.get_draft_by_app_id(app_id=app_id)
61
- if not connections:
62
- logger.error(f"No connection exists with the app-id '{app_id}'")
63
- exit(1)
64
-
65
- connection_id = connections.connection_id
66
- create_request.conversational_search_tool.index_config[0].connection_id = connection_id
67
-
68
- client.create(payload=create_request.model_dump(exclude_none=True))
69
-
70
- logger.info(f"Successfully imported knowledge base '{create_request.name}'")
71
- except ClientAPIException as e:
72
- if "duplicate key value violates unique constraint" in e.response.text:
73
- logger.error(f"A knowledge base with the name '{create_request.name}' already exists. Failed to import knowledge base")
74
- else:
75
- logger.error(f"Error importing knowledge base '{create_request.name}\n' {e.response.text}")
95
+ logger.info(f"Successfully imported knowledge base '{kb.name}'")
96
+ except ClientAPIException as e:
97
+ if "duplicate key value violates unique constraint" in e.response.text:
98
+ logger.error(f"A knowledge base with the name '{kb.name}' already exists. Failed to import knowledge base")
99
+ else:
100
+ logger.error(f"Error importing knowledge base '{kb.name}\n' {e.response.text}")
76
101
 
77
102
  def get_id(
78
103
  self, id: str, name: str
@@ -49,13 +49,13 @@ def validate_app_ids(kind: ToolKind, **args) -> None:
49
49
  app_ids = args.get("app_id")
50
50
  if not app_ids:
51
51
  return
52
-
52
+
53
53
  if kind == ToolKind.openapi:
54
54
  if app_ids and len(app_ids) > 1:
55
55
  raise typer.BadParameter(
56
56
  "Kind 'openapi' can only take one app-id"
57
57
  )
58
-
58
+
59
59
  connections_client = get_connections_client()
60
60
 
61
61
  imported_connections_list = connections_client.list()
@@ -115,7 +115,7 @@ def get_connection_id(app_id: str) -> str:
115
115
 
116
116
  def parse_python_app_ids(app_ids: List[str]) -> dict[str,str]:
117
117
  app_id_dict = {}
118
- for app_id in app_ids:
118
+ for app_id in app_ids:
119
119
  # Split on = but not on \=
120
120
  split_pattern = re.compile(r"(?<!\\)=")
121
121
  split_id = re.split(split_pattern, app_id)
@@ -139,7 +139,7 @@ def parse_python_app_ids(app_ids: List[str]) -> dict[str,str]:
139
139
  def validate_python_connections(tool: BaseTool):
140
140
  if not tool.expected_credentials:
141
141
  return
142
-
142
+
143
143
  connections_client = get_connections_client()
144
144
  connections = tool.__tool_spec__.binding.python.connections
145
145
 
@@ -158,13 +158,13 @@ def validate_python_connections(tool: BaseTool):
158
158
  expected_tool_conn_types = expected_cred.type
159
159
  else:
160
160
  expected_tool_conn_types = [expected_cred.type]
161
-
161
+
162
162
  sanatized_expected_tool_app_id = sanatize_app_id(expected_tool_app_id)
163
163
  if sanatized_expected_tool_app_id in existing_sanatized_expected_tool_app_ids:
164
164
  logger.error(f"Duplicate App ID found '{expected_tool_app_id}'. Multiple expected app ids in the tool '{tool.__tool_spec__.name}' collide after sanaitization to '{sanatized_expected_tool_app_id}'. Please rename the offending app id in your tool.")
165
165
  sys.exit(1)
166
166
  existing_sanatized_expected_tool_app_ids.add(sanatized_expected_tool_app_id)
167
-
167
+
168
168
  if sanatized_expected_tool_app_id not in provided_connections:
169
169
  logger.error(f"The tool '{tool.__tool_spec__.name}' requires an app-id '{expected_tool_app_id}'. Please use the `--app-id` flag to provide the required app-id")
170
170
  validation_failed = True
@@ -173,7 +173,7 @@ def validate_python_connections(tool: BaseTool):
173
173
  continue
174
174
 
175
175
  connection_id = connections.get(sanatized_expected_tool_app_id)
176
-
176
+
177
177
  imported_connection = imported_connections.get(connection_id)
178
178
  imported_connection_auth_type = get_connection_type(security_scheme=imported_connection.security_scheme, auth_type=imported_connection.auth_type)
179
179
 
@@ -184,7 +184,7 @@ def validate_python_connections(tool: BaseTool):
184
184
  if imported_connection and len(expected_tool_conn_types) and imported_connection_auth_type not in expected_tool_conn_types:
185
185
  logger.error(f"The app-id '{imported_connection.app_id}' is of type '{imported_connection_auth_type.value}'. The tool '{tool.__tool_spec__.name}' accepts connections of the following types '{', '.join(expected_tool_conn_types)}'. Use `orchestrate connections list` to view current connections and use `orchestrate connections add` to create the relevent connection")
186
186
  validation_failed = True
187
-
187
+
188
188
  if validation_failed:
189
189
  exit(1)
190
190
 
@@ -311,7 +311,7 @@ def import_python_tool(file: str, requirements_file: str = None, app_id: List[st
311
311
 
312
312
  validate_python_connections(obj)
313
313
  tools.append(obj)
314
-
314
+
315
315
  return tools
316
316
 
317
317
  async def import_openapi_tool(file: str, connection_id: str) -> List[BaseTool]:
@@ -335,7 +335,7 @@ class ToolsController:
335
335
  # Ensure app_id is a list
336
336
  if args.get("app_id") and isinstance(args.get("app_id"), str):
337
337
  args["app_id"] = [args.get("app_id")]
338
-
338
+
339
339
  validate_params(kind=kind, **args)
340
340
 
341
341
  match kind:
@@ -390,7 +390,7 @@ class ToolsController:
390
390
 
391
391
  for tool in tools:
392
392
  tool_binding = tool.__tool_spec__.binding
393
-
393
+
394
394
  connection_ids = []
395
395
 
396
396
  if tool_binding is not None:
@@ -403,7 +403,6 @@ class ToolsController:
403
403
  for conn in tool_binding.mcp.connections:
404
404
  connection_ids.append(tool_binding.mcp.connections[conn])
405
405
 
406
-
407
406
  app_ids = []
408
407
  for connection_id in connection_ids:
409
408
  connection = connections_dict.get(connection_id)
@@ -463,7 +462,7 @@ class ToolsController:
463
462
  if len(existing_tools) > 1:
464
463
  logger.error(f"Multiple existing tools found with name '{tool.__tool_spec__.name}'. Failed to update tool")
465
464
  sys.exit(1)
466
-
465
+
467
466
  if len(existing_tools) > 0:
468
467
  existing_tool = existing_tools[0]
469
468
  exist = True
@@ -569,7 +568,7 @@ class ToolsController:
569
568
  self.get_client().upload_tools_artifact(tool_id=tool_id, file_path=tool_artifact)
570
569
 
571
570
  logger.info(f"Tool '{tool.__tool_spec__.name}' updated successfully")
572
-
571
+
573
572
  def remove_tool(self, name: str):
574
573
  try:
575
574
  client = self.get_client()
@@ -0,0 +1,43 @@
1
+ import importlib.metadata
2
+ from importlib import resources
3
+ from typing import Optional
4
+ from rich import print as pprint
5
+ from dotenv import dotenv_values
6
+ import typer
7
+
8
+ from ibm_watsonx_orchestrate.cli.config import Config, PYTHON_REGISTRY_HEADER, \
9
+ PYTHON_REGISTRY_TEST_PACKAGE_VERSION_OVERRIDE_OPT
10
+
11
+
12
+ def version_callback(checkVersion: bool=True):
13
+ if checkVersion:
14
+ __version__ = importlib.metadata.version('ibm-watsonx-orchestrate')
15
+ default_env = dotenv_values(resources.files("ibm_watsonx_orchestrate.docker").joinpath("default.env"))
16
+ cfg = Config()
17
+ pypi_override = cfg.read(PYTHON_REGISTRY_HEADER, PYTHON_REGISTRY_TEST_PACKAGE_VERSION_OVERRIDE_OPT)
18
+
19
+ adk_version_str = f"[bold]ADK Version[/bold]: {__version__}"
20
+ if pypi_override is not None:
21
+ adk_version_str += f" [red bold](override: {pypi_override})[/red bold]"
22
+ pprint(adk_version_str)
23
+
24
+
25
+ pprint("[bold]Developer Edition Image Tags[/bold] [italic](if not overridden in env file)[/italic]")
26
+ for key, value in default_env.items():
27
+ if key.endswith('_TAG') or key == 'DBTAG':
28
+ pprint(f" [bold]{key}[/bold]: {value}")
29
+
30
+ raise typer.Exit()
31
+
32
+
33
+
34
+ def init_callback(
35
+ ctx: typer.Context,
36
+ version: Optional[bool] = typer.Option(
37
+ None,
38
+ "--version",
39
+ help="Show the installed version of the ADK and Developer Edition Tags",
40
+ callback=version_callback
41
+ )
42
+ ):
43
+ pass
@@ -12,10 +12,12 @@ from ibm_watsonx_orchestrate.cli.commands.environment.environment_command import
12
12
  from ibm_watsonx_orchestrate.cli.commands.channels.channels_command import channel_app
13
13
  from ibm_watsonx_orchestrate.cli.commands.knowledge_bases.knowledge_bases_command import knowledge_bases_app
14
14
  from ibm_watsonx_orchestrate.cli.commands.toolkit.toolkit_command import toolkits_app
15
+ from ibm_watsonx_orchestrate.cli.init_helper import init_callback
15
16
 
16
17
  app = typer.Typer(
17
18
  no_args_is_help=True,
18
- pretty_exceptions_enable=False
19
+ pretty_exceptions_enable=False,
20
+ callback=init_callback
19
21
  )
20
22
  app.add_typer(login_app)
21
23
  app.add_typer(environment_app, name="env", help='Add, remove, or select the activate env other commands will interact with (either your local server or a production instance)')
@@ -51,7 +51,7 @@ class ConnectionsClient(BaseAPIClient):
51
51
  # DELETE api/v1/connections/applications/{app_id}
52
52
  def delete(self, app_id: str) -> dict:
53
53
  return self._delete(f"/connections/applications/{app_id}")
54
-
54
+
55
55
  # GET /api/v1/connections/applications/{app_id}
56
56
  def get(self, app_id: str) -> GetConnectionResponse:
57
57
  try:
@@ -60,7 +60,7 @@ class ConnectionsClient(BaseAPIClient):
60
60
  if e.response.status_code == 404:
61
61
  return None
62
62
  raise e
63
-
63
+
64
64
 
65
65
  # GET api/v1/connections/applications
66
66
  def list(self) -> List[ListConfigsResponse]:
@@ -75,15 +75,15 @@ class ConnectionsClient(BaseAPIClient):
75
75
  return []
76
76
  raise e
77
77
 
78
-
78
+
79
79
  # POST /api/v1/connections/applications/{app_id}/configurations
80
80
  def create_config(self, app_id: str, payload: dict) -> None:
81
81
  self._post(f"/connections/applications/{app_id}/configurations", data=payload)
82
-
82
+
83
83
  # PATCH /api/v1/connections/applications/{app_id}/configurations/{env}
84
84
  def update_config(self, app_id: str, env: ConnectionEnvironment, payload: dict) -> None:
85
85
  self._patch(f"/connections/applications/{app_id}/configurations/{env}", data=payload)
86
-
86
+
87
87
  # `GET /api/v1/connections/applications/{app_id}/configurations/{env}'
88
88
  def get_config(self, app_id: str, env: ConnectionEnvironment) -> GetConfigResponse:
89
89
  try:
@@ -93,7 +93,7 @@ class ConnectionsClient(BaseAPIClient):
93
93
  if e.response.status_code == 404:
94
94
  return None
95
95
  raise e
96
-
96
+
97
97
  # POST /api/v1/connections/applications/{app_id}/configs/{env}/credentials
98
98
  # POST /api/v1/connections/applications/{app_id}/configs/{env}/runtime_credentials
99
99
  def create_credentials(self, app_id: str, env: ConnectionEnvironment, payload: dict, use_sso: bool) -> None:
@@ -101,7 +101,7 @@ class ConnectionsClient(BaseAPIClient):
101
101
  self._post(f"/connections/applications/{app_id}/configs/{env}/credentials", data=payload)
102
102
  else:
103
103
  self._post(f"/connections/applications/{app_id}/configs/{env}/runtime_credentials", data=payload)
104
-
104
+
105
105
  # PATCH /api/v1/connections/applications/{app_id}/configs/{env}/credentials
106
106
  # PATCH /api/v1/connections/applications/{app_id}/configs/{env}/runtime_credentials
107
107
  def update_credentials(self, app_id: str, env: ConnectionEnvironment, payload: dict, use_sso: bool) -> None:
@@ -109,7 +109,7 @@ class ConnectionsClient(BaseAPIClient):
109
109
  self._patch(f"/connections/applications/{app_id}/configs/{env}/credentials", data=payload)
110
110
  else:
111
111
  self._patch(f"/connections/applications/{app_id}/configs/{env}/runtime_credentials", data=payload)
112
-
112
+
113
113
  # GET /api/v1/connections/applications/{app_id}/configs/credentials?env={env}
114
114
  # GET /api/v1/connections/applications/{app_id}/configs/runtime_credentials?env={env}
115
115
  def get_credentials(self, app_id: str, env: ConnectionEnvironment, use_sso: bool) -> dict:
@@ -122,7 +122,7 @@ class ConnectionsClient(BaseAPIClient):
122
122
  if e.response.status_code == 404:
123
123
  return None
124
124
  raise e
125
-
125
+
126
126
  # DELETE /api/v1/connections/applications/{app_id}/configs/{env}/credentials
127
127
  # DELETE /api/v1/connections/applications/{app_id}/configs/{env}/runtime_credentials
128
128
  def delete_credentials(self, app_id: str, env: ConnectionEnvironment, use_sso: bool) -> None:
@@ -130,7 +130,7 @@ class ConnectionsClient(BaseAPIClient):
130
130
  self._delete(f"/connections/applications/{app_id}/configs/{env}/credentials")
131
131
  else:
132
132
  self._delete(f"/connections/applications/{app_id}/configs/{env}/runtime_credentials")
133
-
133
+
134
134
  def get_draft_by_app_id(self, app_id: str) -> GetConnectionResponse:
135
135
  return self.get(app_id=app_id)
136
136
 
@@ -141,7 +141,7 @@ class ConnectionsClient(BaseAPIClient):
141
141
  if connection:
142
142
  connections += connection
143
143
  return connections
144
-
144
+
145
145
  def get_draft_by_id(self, conn_id) -> str:
146
146
  """Retrieve the app ID for a given connection ID."""
147
147
  if conn_id is None:
@@ -151,12 +151,12 @@ class ConnectionsClient(BaseAPIClient):
151
151
  except ClientAPIException as e:
152
152
  if e.response.status_code == 404:
153
153
  logger.warning(f"Connections not found. Returning connection ID: {conn_id}")
154
- return conn_id
154
+ return conn_id
155
155
  raise
156
156
 
157
157
  app_id = next((conn.app_id for conn in connections if conn.connection_id == conn_id), None)
158
158
 
159
159
  if app_id is None:
160
160
  logger.warning(f"Connection with ID {conn_id} not found. Returning connection ID.")
161
- return conn_id
161
+ return conn_id
162
162
  return app_id
@@ -49,10 +49,10 @@ EVENT_BROKER_TTL="-1"
49
49
  # THE VALUES FOR REGISTRY_URL AND *_REGISTRY ARE NOT SET HERE; THEY ARE EITHER PROVIDED BY THE USER OR DETERMINED AT RUNTIME BASED ON WO_DEVELOPER_EDITION_SOURCE.
50
50
  REGISTRY_URL=
51
51
 
52
- SERVER_TAG=03-05-2025
52
+ SERVER_TAG=06-05-2025
53
53
  SERVER_REGISTRY=
54
54
 
55
- WORKER_TAG=03-05-2025
55
+ WORKER_TAG=06-05-2025
56
56
  WORKER_REGISTRY=
57
57
 
58
58
  DB_REGISTRY=