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.
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/PKG-INFO +3 -2
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/pyproject.toml +2 -1
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/__init__.py +1 -1
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/agent_builder/agents/types.py +4 -1
- {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
- {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
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/agent_builder/knowledge_bases/types.py +4 -13
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/agent_builder/tools/openapi_tool.py +4 -12
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/agents/agents_controller.py +2 -0
- {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
- {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
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/tools/tools_controller.py +13 -14
- ibm_watsonx_orchestrate-1.3.0/src/ibm_watsonx_orchestrate/cli/init_helper.py +43 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/main.py +3 -1
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/client/connections/connections_client.py +13 -13
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/docker/default.env +2 -2
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/.gitignore +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/LICENSE +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/agent_builder/__init__.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/agent_builder/agents/__init__.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/agent_builder/agents/agent.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/agent_builder/agents/assistant_agent.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/agent_builder/agents/external_agent.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/agent_builder/connections/__init__.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/agent_builder/connections/connections.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/agent_builder/connections/types.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/agent_builder/tools/__init__.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/agent_builder/tools/base_tool.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/agent_builder/tools/python_tool.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/agent_builder/tools/types.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/agent_builder/utils/__init__.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/agent_builder/utils/pydantic_utils.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/__init__.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/__init__.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/agents/agents_command.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/channels/channels_command.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/channels/channels_controller.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/channels/types.py +0 -0
- {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
- {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
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/chat/chat_command.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/connections/connections_command.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/connections/connections_controller.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/environment/environment_command.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/environment/environment_controller.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/environment/types.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/login/login_command.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/models/models_command.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/server/server_command.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/settings/__init__.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/settings/observability/__init__.py +0 -0
- {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
- {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
- {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
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/settings/settings_command.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/toolkit/toolkit_command.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/toolkit/toolkit_controller.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/tools/tools_command.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/commands/tools/types.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/cli/config.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/client/__init__.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/client/agents/agent_client.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/client/agents/assistant_agent_client.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/client/agents/external_agent_client.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/client/analytics/__init__.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/client/analytics/llm/__init__.py +0 -0
- {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
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/client/base_api_client.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/client/base_service_instance.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/client/client.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/client/client_errors.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/client/connections/__init__.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/client/connections/utils.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/client/credentials.py +0 -0
- {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
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/client/local_service_instance.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/client/service_instance.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/client/toolkit/toolkit_client.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/client/tools/tool_client.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/client/utils.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/docker/compose-lite.yml +0 -0
- {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
- {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
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/docker/start-up.sh +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/docker/tempus/common-config.yaml +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/run/__init__.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/run/connections.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/utils/__init__.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/utils/logging/__init__.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/utils/logging/logger.py +0 -0
- {ibm_watsonx_orchestrate-1.2.0 → ibm_watsonx_orchestrate-1.3.0}/src/ibm_watsonx_orchestrate/utils/logging/logging.yaml +0 -0
- {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.
|
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.
|
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.
|
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,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
|
3
|
+
from .types import KnowledgeBaseSpec, PatchKnowledgeBase, KnowledgeBaseKind
|
4
4
|
|
5
5
|
|
6
|
-
class KnowledgeBaseCreateRequest(
|
6
|
+
class KnowledgeBaseCreateRequest(KnowledgeBaseSpec):
|
7
7
|
|
8
8
|
@staticmethod
|
9
|
-
def from_spec(file: str) -> '
|
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
|
-
|
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:
|
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
|
-
|
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
|
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
|
-
|
40
|
-
|
41
|
-
|
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
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
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
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
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=
|
52
|
+
SERVER_TAG=06-05-2025
|
53
53
|
SERVER_REGISTRY=
|
54
54
|
|
55
|
-
WORKER_TAG=
|
55
|
+
WORKER_TAG=06-05-2025
|
56
56
|
WORKER_REGISTRY=
|
57
57
|
|
58
58
|
DB_REGISTRY=
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|