ibm-watsonx-orchestrate 1.0.0__py3-none-any.whl

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 (89) hide show
  1. ibm_watsonx_orchestrate/__init__.py +28 -0
  2. ibm_watsonx_orchestrate/agent_builder/__init__.py +0 -0
  3. ibm_watsonx_orchestrate/agent_builder/agents/__init__.py +5 -0
  4. ibm_watsonx_orchestrate/agent_builder/agents/agent.py +27 -0
  5. ibm_watsonx_orchestrate/agent_builder/agents/assistant_agent.py +28 -0
  6. ibm_watsonx_orchestrate/agent_builder/agents/external_agent.py +28 -0
  7. ibm_watsonx_orchestrate/agent_builder/agents/types.py +204 -0
  8. ibm_watsonx_orchestrate/agent_builder/connections/__init__.py +27 -0
  9. ibm_watsonx_orchestrate/agent_builder/connections/connections.py +123 -0
  10. ibm_watsonx_orchestrate/agent_builder/connections/types.py +260 -0
  11. ibm_watsonx_orchestrate/agent_builder/knowledge_bases/knowledge_base.py +27 -0
  12. ibm_watsonx_orchestrate/agent_builder/knowledge_bases/knowledge_base_requests.py +59 -0
  13. ibm_watsonx_orchestrate/agent_builder/knowledge_bases/types.py +243 -0
  14. ibm_watsonx_orchestrate/agent_builder/tools/__init__.py +4 -0
  15. ibm_watsonx_orchestrate/agent_builder/tools/base_tool.py +36 -0
  16. ibm_watsonx_orchestrate/agent_builder/tools/openapi_tool.py +332 -0
  17. ibm_watsonx_orchestrate/agent_builder/tools/python_tool.py +195 -0
  18. ibm_watsonx_orchestrate/agent_builder/tools/types.py +162 -0
  19. ibm_watsonx_orchestrate/agent_builder/utils/__init__.py +0 -0
  20. ibm_watsonx_orchestrate/agent_builder/utils/pydantic_utils.py +149 -0
  21. ibm_watsonx_orchestrate/cli/__init__.py +0 -0
  22. ibm_watsonx_orchestrate/cli/commands/__init__.py +0 -0
  23. ibm_watsonx_orchestrate/cli/commands/agents/agents_command.py +192 -0
  24. ibm_watsonx_orchestrate/cli/commands/agents/agents_controller.py +660 -0
  25. ibm_watsonx_orchestrate/cli/commands/channels/channels_command.py +15 -0
  26. ibm_watsonx_orchestrate/cli/commands/channels/channels_controller.py +16 -0
  27. ibm_watsonx_orchestrate/cli/commands/channels/types.py +15 -0
  28. ibm_watsonx_orchestrate/cli/commands/channels/webchat/channels_webchat_command.py +32 -0
  29. ibm_watsonx_orchestrate/cli/commands/channels/webchat/channels_webchat_controller.py +141 -0
  30. ibm_watsonx_orchestrate/cli/commands/chat/chat_command.py +43 -0
  31. ibm_watsonx_orchestrate/cli/commands/connections/connections_command.py +307 -0
  32. ibm_watsonx_orchestrate/cli/commands/connections/connections_controller.py +517 -0
  33. ibm_watsonx_orchestrate/cli/commands/environment/environment_command.py +78 -0
  34. ibm_watsonx_orchestrate/cli/commands/environment/environment_controller.py +189 -0
  35. ibm_watsonx_orchestrate/cli/commands/environment/types.py +9 -0
  36. ibm_watsonx_orchestrate/cli/commands/knowledge_bases/knowledge_bases_command.py +79 -0
  37. ibm_watsonx_orchestrate/cli/commands/knowledge_bases/knowledge_bases_controller.py +201 -0
  38. ibm_watsonx_orchestrate/cli/commands/login/login_command.py +17 -0
  39. ibm_watsonx_orchestrate/cli/commands/models/models_command.py +128 -0
  40. ibm_watsonx_orchestrate/cli/commands/server/server_command.py +623 -0
  41. ibm_watsonx_orchestrate/cli/commands/settings/__init__.py +0 -0
  42. ibm_watsonx_orchestrate/cli/commands/settings/observability/__init__.py +0 -0
  43. ibm_watsonx_orchestrate/cli/commands/settings/observability/langfuse/__init__.py +0 -0
  44. ibm_watsonx_orchestrate/cli/commands/settings/observability/langfuse/langfuse_command.py +175 -0
  45. ibm_watsonx_orchestrate/cli/commands/settings/observability/observability_command.py +11 -0
  46. ibm_watsonx_orchestrate/cli/commands/settings/settings_command.py +10 -0
  47. ibm_watsonx_orchestrate/cli/commands/tools/tools_command.py +85 -0
  48. ibm_watsonx_orchestrate/cli/commands/tools/tools_controller.py +564 -0
  49. ibm_watsonx_orchestrate/cli/commands/tools/types.py +10 -0
  50. ibm_watsonx_orchestrate/cli/config.py +226 -0
  51. ibm_watsonx_orchestrate/cli/main.py +32 -0
  52. ibm_watsonx_orchestrate/client/__init__.py +0 -0
  53. ibm_watsonx_orchestrate/client/agents/agent_client.py +46 -0
  54. ibm_watsonx_orchestrate/client/agents/assistant_agent_client.py +38 -0
  55. ibm_watsonx_orchestrate/client/agents/external_agent_client.py +38 -0
  56. ibm_watsonx_orchestrate/client/analytics/__init__.py +0 -0
  57. ibm_watsonx_orchestrate/client/analytics/llm/__init__.py +0 -0
  58. ibm_watsonx_orchestrate/client/analytics/llm/analytics_llm_client.py +50 -0
  59. ibm_watsonx_orchestrate/client/base_api_client.py +113 -0
  60. ibm_watsonx_orchestrate/client/base_service_instance.py +10 -0
  61. ibm_watsonx_orchestrate/client/client.py +71 -0
  62. ibm_watsonx_orchestrate/client/client_errors.py +359 -0
  63. ibm_watsonx_orchestrate/client/connections/__init__.py +10 -0
  64. ibm_watsonx_orchestrate/client/connections/connections_client.py +162 -0
  65. ibm_watsonx_orchestrate/client/connections/utils.py +27 -0
  66. ibm_watsonx_orchestrate/client/credentials.py +123 -0
  67. ibm_watsonx_orchestrate/client/knowledge_bases/knowledge_base_client.py +46 -0
  68. ibm_watsonx_orchestrate/client/local_service_instance.py +91 -0
  69. ibm_watsonx_orchestrate/client/service_instance.py +73 -0
  70. ibm_watsonx_orchestrate/client/tools/tool_client.py +41 -0
  71. ibm_watsonx_orchestrate/client/utils.py +95 -0
  72. ibm_watsonx_orchestrate/docker/compose-lite.yml +595 -0
  73. ibm_watsonx_orchestrate/docker/default.env +125 -0
  74. ibm_watsonx_orchestrate/docker/sdk/ibm_watsonx_orchestrate-0.6.0-py3-none-any.whl +0 -0
  75. ibm_watsonx_orchestrate/docker/sdk/ibm_watsonx_orchestrate-0.6.0.tar.gz +0 -0
  76. ibm_watsonx_orchestrate/docker/start-up.sh +61 -0
  77. ibm_watsonx_orchestrate/docker/tempus/common-config.yaml +1 -0
  78. ibm_watsonx_orchestrate/run/__init__.py +0 -0
  79. ibm_watsonx_orchestrate/run/connections.py +40 -0
  80. ibm_watsonx_orchestrate/utils/__init__.py +0 -0
  81. ibm_watsonx_orchestrate/utils/logging/__init__.py +0 -0
  82. ibm_watsonx_orchestrate/utils/logging/logger.py +26 -0
  83. ibm_watsonx_orchestrate/utils/logging/logging.yaml +18 -0
  84. ibm_watsonx_orchestrate/utils/utils.py +15 -0
  85. ibm_watsonx_orchestrate-1.0.0.dist-info/METADATA +34 -0
  86. ibm_watsonx_orchestrate-1.0.0.dist-info/RECORD +89 -0
  87. ibm_watsonx_orchestrate-1.0.0.dist-info/WHEEL +4 -0
  88. ibm_watsonx_orchestrate-1.0.0.dist-info/entry_points.txt +2 -0
  89. ibm_watsonx_orchestrate-1.0.0.dist-info/licenses/LICENSE +22 -0
@@ -0,0 +1,260 @@
1
+ from pydantic import BaseModel, Field, AliasChoices, model_validator
2
+ from typing import Optional, Union, TypeVar, List
3
+ from enum import Enum
4
+
5
+ class ConnectionKind(str, Enum):
6
+ basic = 'basic'
7
+ bearer = 'bearer'
8
+ api_key = 'api_key'
9
+ # oauth_auth_code_flow = 'oauth_auth_code_flow'
10
+ # oauth_auth_implicit_flow = 'oauth_auth_implicit_flow'
11
+ # oauth_auth_password_flow = 'oauth_auth_password_flow'
12
+ # oauth_auth_client_credentials_flow = 'oauth_auth_client_credentials_flow'
13
+ oauth_auth_on_behalf_of_flow = 'oauth_auth_on_behalf_of_flow'
14
+ key_value = 'key_value'
15
+ kv = 'kv'
16
+
17
+ def __str__(self):
18
+ return self.value
19
+
20
+ class ConnectionEnvironment(str, Enum):
21
+ DRAFT = 'draft'
22
+ LIVE = 'live'
23
+
24
+ def __str__(self):
25
+ return self.value
26
+
27
+ class ConnectionPreference(str, Enum):
28
+ MEMBER = 'member'
29
+ TEAM = 'team'
30
+
31
+ def __str__(self):
32
+ return self.value
33
+
34
+ class ConnectionAuthType(str, Enum):
35
+ # OAUTH2_AUTH_CODE = 'oauth2_auth_code'
36
+ # OAUTH2_IMPLICIT = 'oauth2_implicit'
37
+ # OAUTH2_PASSWORD = 'oauth2_password'
38
+ # OAUTH2_CLIENT_CREDS = 'oauth2_client_creds'
39
+ OAUTH_ON_BEHALF_OF_FLOW = 'oauth_on_behalf_of_flow'
40
+
41
+ def __str__(self):
42
+ return self.value
43
+
44
+ def __repr__(self):
45
+ return repr(self.value)
46
+
47
+ class ConnectionSecurityScheme(str, Enum):
48
+ BASIC_AUTH = 'basic_auth'
49
+ BEARER_TOKEN = 'bearer_token'
50
+ API_KEY_AUTH = 'api_key_auth'
51
+ OAUTH2 = 'oauth2'
52
+ KEY_VALUE = 'key_value_creds'
53
+
54
+ def __str__(self):
55
+ return self.value
56
+
57
+ def __repr__(self):
58
+ return repr(self.value)
59
+
60
+ # Values for python tool expected credentials
61
+ # Line up with what the Security_Schema env var is
62
+ class ConnectionType(str, Enum):
63
+ BASIC_AUTH = ConnectionSecurityScheme.BASIC_AUTH.value
64
+ BEARER_TOKEN = ConnectionSecurityScheme.BEARER_TOKEN.value
65
+ API_KEY_AUTH = ConnectionSecurityScheme.API_KEY_AUTH.value
66
+ # OAUTH2_AUTH_CODE = ConnectionAuthType.OAUTH2_AUTH_CODE.value
67
+ # OAUTH2_IMPLICIT = ConnectionAuthType.OAUTH2_IMPLICIT.value
68
+ # OAUTH2_PASSWORD = ConnectionAuthType.OAUTH2_PASSWORD.value
69
+ # OAUTH2_CLIENT_CREDS = ConnectionAuthType.OAUTH2_CLIENT_CREDS.value
70
+ OAUTH_ON_BEHALF_OF_FLOW = ConnectionAuthType.OAUTH_ON_BEHALF_OF_FLOW.value
71
+ KEY_VALUE = ConnectionSecurityScheme.KEY_VALUE.value
72
+
73
+ def __str__(self):
74
+ return self.value
75
+
76
+ def __repr__(self):
77
+ return repr(self.value)
78
+
79
+ OAUTH_CONNECTION_TYPES = {
80
+ # ConnectionType.OAUTH2_AUTH_CODE,
81
+ # ConnectionType.OAUTH2_CLIENT_CREDS,
82
+ # ConnectionType.OAUTH2_IMPLICIT,
83
+ # ConnectionType.OAUTH2_PASSWORD,
84
+ ConnectionType.OAUTH_ON_BEHALF_OF_FLOW,
85
+ }
86
+
87
+ class IdpConfigDataBody(BaseModel):
88
+ requested_token_use: str
89
+ requested_token_type: str
90
+
91
+ class IdpConfigData(BaseModel):
92
+ header: Optional[dict] = None
93
+ body: IdpConfigDataBody
94
+
95
+ @model_validator(mode="after")
96
+ def set_default_values(self):
97
+ self.header = self.header or {
98
+ "content-type": "application/x-www-form-urlencoded"
99
+ }
100
+ return self
101
+
102
+ class AppConfigData(BaseModel):
103
+ header: Optional[dict] = None
104
+
105
+ @model_validator(mode="after")
106
+ def set_default_values(self):
107
+ self.header = self.header or {
108
+ "content-type": "application/x-www-form-urlencoded"
109
+ }
110
+ return self
111
+
112
+
113
+ class ConnectionConfiguration(BaseModel):
114
+ app_id: str
115
+ environment: ConnectionEnvironment
116
+ preference: ConnectionPreference = Field(validation_alias=AliasChoices('preference', 'type'), serialization_alias='preference')
117
+ security_scheme: ConnectionSecurityScheme
118
+ auth_type: Optional[ConnectionAuthType] = None
119
+ sso: bool = False
120
+ server_url: str | None = None
121
+ idp_config_data: Optional[IdpConfigData] = Field(None, validation_alias=AliasChoices('idp_config_data', 'idp_config'), serialization_alias='idp_config_data')
122
+ app_config_data: Optional[AppConfigData] = Field(None, validation_alias=AliasChoices('app_config_data', 'app_config'), serialization_alias='app_config_data')
123
+ config_id: str = None
124
+ tenant_id: str = None
125
+
126
+ def __init__(self, *args, **kwargs):
127
+ kind = kwargs.get("kind")
128
+
129
+ if kind:
130
+ if not kwargs.get("auth_type"):
131
+ kwargs["auth_type"] = CONNECTION_KIND_OAUTH_TYPE_MAPPING.get(kind)
132
+
133
+ if not kwargs.get("security_scheme"):
134
+ kwargs["security_scheme"] = CONNECTION_KIND_SCHEME_MAPPING.get(kind)
135
+
136
+ super().__init__(*args, **kwargs)
137
+
138
+ @model_validator(mode="after")
139
+ def validate_config(self):
140
+ if self.sso and self.security_scheme != ConnectionSecurityScheme.OAUTH2:
141
+ raise ValueError(f"SSO not supported for auth scheme '{self.security_scheme}'. SSO can only be used with OAuth auth types")
142
+ if not self.sso and self.security_scheme == ConnectionSecurityScheme.OAUTH2:
143
+ raise ValueError(f"SSO required for OAuth auth schemes. Please enable SSO.")
144
+ if self.sso:
145
+ if not self.idp_config_data:
146
+ raise ValueError("For SSO auth 'idp_config_data' is a required field")
147
+ if not self.app_config_data:
148
+ self.app_config_data = AppConfigData()
149
+ if self.security_scheme == ConnectionSecurityScheme.KEY_VALUE and self.preference == ConnectionPreference.MEMBER:
150
+ raise ValueError("Connection of type 'key_value' cannot be configured at the 'member' level. Key value connections must be of type 'team'")
151
+ return self
152
+
153
+ class BasicAuthCredentials(BaseModel):
154
+ username: str
155
+ password: str
156
+ url: Optional[str] = None
157
+
158
+ class BearerTokenAuthCredentials(BaseModel):
159
+ token: str
160
+ url: Optional[str] = None
161
+
162
+ class APIKeyAuthCredentials(BaseModel):
163
+ api_key: str
164
+ url: Optional[str] = None
165
+
166
+ class OAuth2TokenCredentials(BaseModel):
167
+ access_token: str
168
+ url: Optional[str] = None
169
+
170
+ # class OAuth2AuthCodeCredentials(BaseModel):
171
+ # client_id: str
172
+ # client_secret: str
173
+ # token_url: str
174
+ # authorization_url: str
175
+
176
+ # class OAuth2ImplicitCredentials(BaseModel):
177
+ # client_id: str
178
+ # authorization_url: str
179
+
180
+ # class OAuth2PasswordCredentials(BaseModel):
181
+ # client_id: str
182
+ # client_secret: str
183
+ # token_url: str
184
+ # authorization_url: str
185
+
186
+ # class OAuth2ClientCredentials(BaseModel):
187
+ # client_id: str
188
+ # client_secret: str
189
+ # token_url: str
190
+
191
+ class OAuthOnBehalfOfCredentials(BaseModel):
192
+ client_id: str
193
+ access_token_url: str
194
+ grant_type: str
195
+
196
+ # KeyValue is just an alias of dictionary
197
+ class KeyValueConnectionCredentials(dict):
198
+ def __init__(self, *args, **kwargs):
199
+ super().__init__(*args, **kwargs)
200
+
201
+ def model_dump(self, *args, **kwargs):
202
+ return self
203
+
204
+ CREDENTIALS_SET = Union[
205
+ BasicAuthCredentials,
206
+ BearerTokenAuthCredentials,
207
+ APIKeyAuthCredentials,
208
+ # OAuth2AuthCodeCredentials,
209
+ # OAuth2ImplicitCredentials,
210
+ # OAuth2PasswordCredentials,
211
+ # OAuth2ClientCredentials,
212
+ OAuthOnBehalfOfCredentials,
213
+ KeyValueConnectionCredentials
214
+ ]
215
+
216
+ CREDENTIALS = TypeVar("CREDENTIALS", bound=CREDENTIALS_SET)
217
+
218
+ CONNECTION_KIND_SCHEME_MAPPING = {
219
+ ConnectionKind.basic: ConnectionSecurityScheme.BASIC_AUTH,
220
+ ConnectionKind.bearer: ConnectionSecurityScheme.BEARER_TOKEN,
221
+ ConnectionKind.api_key: ConnectionSecurityScheme.API_KEY_AUTH,
222
+ # ConnectionKind.oauth_auth_code_flow: ConnectionSecurityScheme.OAUTH2,
223
+ # ConnectionKind.oauth_auth_implicit_flow: ConnectionSecurityScheme.OAUTH2,
224
+ # ConnectionKind.oauth_auth_password_flow: ConnectionSecurityScheme.OAUTH2,
225
+ # ConnectionKind.oauth_auth_client_credentials_flow: ConnectionSecurityScheme.OAUTH2,
226
+ ConnectionKind.oauth_auth_on_behalf_of_flow: ConnectionSecurityScheme.OAUTH2,
227
+ ConnectionKind.key_value: ConnectionSecurityScheme.KEY_VALUE,
228
+ ConnectionKind.kv: ConnectionSecurityScheme.KEY_VALUE,
229
+ }
230
+
231
+ CONNECTION_KIND_OAUTH_TYPE_MAPPING = {
232
+ # ConnectionKind.oauth_auth_code_flow: ConnectionAuthType.OAUTH2_AUTH_CODE,
233
+ # ConnectionKind.oauth_auth_implicit_flow: ConnectionAuthType.OAUTH2_IMPLICIT,
234
+ # ConnectionKind.oauth_auth_password_flow: ConnectionAuthType.OAUTH2_PASSWORD,
235
+ # ConnectionKind.oauth_auth_client_credentials_flow: ConnectionAuthType.OAUTH2_CLIENT_CREDS,
236
+ ConnectionKind.oauth_auth_on_behalf_of_flow: ConnectionAuthType.OAUTH_ON_BEHALF_OF_FLOW,
237
+ }
238
+
239
+ CONNECTION_TYPE_CREDENTIAL_MAPPING = {
240
+ ConnectionType.BASIC_AUTH: BasicAuthCredentials,
241
+ ConnectionType.BEARER_TOKEN: BearerTokenAuthCredentials,
242
+ ConnectionType.API_KEY_AUTH: APIKeyAuthCredentials,
243
+ # ConnectionType.OAUTH2_AUTH_CODE: BearerTokenAuthCredentials,
244
+ # ConnectionType.OAUTH2_IMPLICIT: BearerTokenAuthCredentials,
245
+ # ConnectionType.OAUTH2_PASSWORD: BearerTokenAuthCredentials,
246
+ # ConnectionType.OAUTH2_CLIENT_CREDS: BearerTokenAuthCredentials,
247
+ ConnectionType.OAUTH_ON_BEHALF_OF_FLOW: OAuth2TokenCredentials,
248
+ ConnectionType.KEY_VALUE: KeyValueConnectionCredentials,
249
+ }
250
+
251
+ class IdentityProviderCredentials(BaseModel):
252
+ idp_url: str = Field(validation_alias=AliasChoices('idp_url', 'url'), serialization_alias='idp_url')
253
+ client_id: str
254
+ client_secret: str
255
+ scope: str
256
+ grant_type: str
257
+
258
+ class ExpectedCredentials(BaseModel):
259
+ app_id: str
260
+ type: ConnectionType | List[ConnectionType]
@@ -0,0 +1,27 @@
1
+ import json
2
+ from ibm_watsonx_orchestrate.utils.utils import yaml_safe_load
3
+ from .types import KnowledgeBaseSpec
4
+
5
+
6
+ class KnowledgeBase(KnowledgeBaseSpec):
7
+
8
+ @staticmethod
9
+ def from_spec(file: str) -> 'KnowledgeBase':
10
+ with open(file, 'r') as f:
11
+ if file.endswith('.yaml') or file.endswith('.yml'):
12
+ content = yaml_safe_load(f)
13
+ elif file.endswith('.json'):
14
+ content = json.load(f)
15
+ else:
16
+ raise ValueError('file must end in .json, .yaml, or .yml')
17
+ if not content.get("spec_version"):
18
+ raise ValueError(f"Field 'spec_version' not provided. Please ensure provided spec conforms to a valid spec format")
19
+ knowledge_base = KnowledgeBase.model_validate(content)
20
+
21
+ return knowledge_base
22
+
23
+ def __repr__(self):
24
+ return f"KnowledgeBase(id='{self.id}', name='{self.name}', description='{self.description}')"
25
+
26
+ def __str__(self):
27
+ return self.__repr__()
@@ -0,0 +1,59 @@
1
+ import json
2
+ from ibm_watsonx_orchestrate.utils.utils import yaml_safe_load
3
+ from .types import CreateKnowledgeBase, PatchKnowledgeBase, KnowledgeBaseKind
4
+
5
+
6
+ class KnowledgeBaseCreateRequest(CreateKnowledgeBase):
7
+
8
+ @staticmethod
9
+ def from_spec(file: str) -> 'CreateKnowledgeBase':
10
+ with open(file, 'r') as f:
11
+ if file.endswith('.yaml') or file.endswith('.yml'):
12
+ content = yaml_safe_load(f)
13
+ elif file.endswith('.json'):
14
+ content = json.load(f)
15
+ else:
16
+ raise ValueError('file must end in .json, .yaml, or .yml')
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
+ if not content.get("spec_version"):
23
+ raise ValueError(f"Field 'spec_version' not provided. Please ensure provided spec conforms to a valid spec format")
24
+
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)
32
+
33
+ return knowledge_base
34
+
35
+
36
+ class KnowledgeBaseUpdateRequest(PatchKnowledgeBase):
37
+
38
+ @staticmethod
39
+ def from_spec(file: str) -> 'PatchKnowledgeBase':
40
+ with open(file, 'r') as f:
41
+ if file.endswith('.yaml') or file.endswith('.yml'):
42
+ content = yaml_safe_load(f)
43
+ elif file.endswith('.json'):
44
+ content = json.load(f)
45
+ else:
46
+ raise ValueError('file must end in .json, .yaml, or .yml')
47
+
48
+ if not content.get("spec_version"):
49
+ raise ValueError(f"Field 'spec_version' not provided. Please ensure provided spec conforms to a valid spec format")
50
+
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
+ patch = PatchKnowledgeBase.model_validate(content)
58
+
59
+ return patch
@@ -0,0 +1,243 @@
1
+ from typing import Optional
2
+ from datetime import datetime
3
+ from uuid import UUID
4
+ from enum import Enum
5
+
6
+ from pydantic import BaseModel, Field
7
+
8
+
9
+ class SpecVersion(str, Enum):
10
+ V1 = "v1"
11
+
12
+ class KnowledgeBaseKind(str, Enum):
13
+ KNOWLEDGE_BASE = "knowledge_base"
14
+ class RetrievalConfidenceThreshold(str, Enum):
15
+ Lowest = "Lowest"
16
+ Low = "Low"
17
+ High = "High"
18
+ Highest = "Highest"
19
+
20
+
21
+ class GeneratedResponseLength(str, Enum):
22
+ Concise = "Concise"
23
+ Moderate = "Moderate"
24
+ Verbose = "Verbose"
25
+
26
+
27
+ class ResponseConfidenceThreshold(str, Enum):
28
+ Lowest = "Lowest"
29
+ Low = "Low"
30
+ High = "High"
31
+ Highest = "Highest"
32
+
33
+ class KnowledgeBaseRepresentation(str, Enum):
34
+ auto = "auto"
35
+ tool = "tool"
36
+
37
+ class ConfidenceThresholds(BaseModel):
38
+ retrieval_confidence_threshold: Optional[RetrievalConfidenceThreshold] = None
39
+ response_confidence_threshold: Optional[ResponseConfidenceThreshold] = None
40
+
41
+ class CitationsConfig(BaseModel):
42
+ """
43
+ example:
44
+ {
45
+ "citation_title": "how do i know",
46
+ "citations_shown": 5,
47
+ }
48
+ """
49
+ citation_title: Optional[str] = None
50
+ citations_shown: Optional[int] = None
51
+
52
+
53
+ class HAPFilteringConfig(BaseModel):
54
+ enabled: Optional[bool] = None
55
+ threshold: Optional[float] = None
56
+
57
+
58
+ class HAPFiltering(BaseModel):
59
+ """
60
+ example
61
+ {
62
+ "output": {
63
+ "enabled": True,
64
+ "threshold": 0.7,
65
+ }
66
+ }
67
+
68
+ """
69
+ output: Optional[HAPFilteringConfig] = None
70
+
71
+ class QueryRewriteConfig(BaseModel):
72
+ """
73
+ example
74
+
75
+ {
76
+ "enabled": True,
77
+ "model_id": "meta-llama/llama-3-1-70b-instruct"
78
+ }
79
+
80
+ """
81
+ enabled: Optional[bool] = None
82
+ model_id: Optional[str] = None
83
+
84
+ class GenerationConfiguration(BaseModel):
85
+ """
86
+ example
87
+ {
88
+ "model_id": "meta-llama/llama-3-1-70b-instruct",
89
+ "prompt_instruction": "When the documents are in different languages, you should respond in english.",
90
+ "retrieval_confidence_threshold": "Lowest",
91
+ "generated_response_length": "Moderate",
92
+ "response_confidence_threshold": "Low",
93
+ "display_text_no_results_found": "no docs found",
94
+ "display_text_connectivity_issue": "conn failed",
95
+ }
96
+ """
97
+
98
+ model_id: Optional[str] = None
99
+ prompt_instruction: Optional[str] = None
100
+ generated_response_length: Optional[GeneratedResponseLength] = None
101
+ display_text_no_results_found: Optional[str] = None
102
+ display_text_connectivity_issue: Optional[str] = None
103
+
104
+ class FieldMapping(BaseModel):
105
+ """
106
+ example
107
+
108
+ {
109
+ "title": "title",
110
+ "body": "text",
111
+ "url": "some-url"
112
+ }
113
+ """
114
+ title: Optional[str] = None
115
+ body: Optional[str] = None
116
+ url: Optional[str] = None
117
+
118
+ class MilvusConnection(BaseModel):
119
+ """
120
+ example:
121
+ {
122
+ "grpc_host": "https://xxxx.lakehouse.appdomain.cloud",
123
+ "database": "test_db",
124
+ "collection": "search_wa_docs",
125
+ "index": "dense",
126
+ "embedding_model_id": "sentence-transformers/all-minilm-l12-v2",
127
+ "grpc_port": "30564",
128
+ "filter": "title like \"%action%\"",
129
+ "limit": 10,
130
+ "field_mapping": {
131
+ "title": "title",
132
+ "body": "text",
133
+ "url": "some-url"
134
+ }
135
+ }
136
+ """
137
+ grpc_host: Optional[str] = None
138
+ database: Optional[str] = None
139
+ collection: Optional[str] = None
140
+ index: Optional[str] = None
141
+ embedding_model_id: Optional[str] = None
142
+ limit : Optional[int] = None
143
+ grpc_port: Optional[str] = None
144
+ filter: Optional[str] = None
145
+ field_mapping: Optional[FieldMapping] = None
146
+
147
+
148
+ class ElasticSearchConnection(BaseModel):
149
+ """
150
+ example:
151
+
152
+ {
153
+ "url": "https://xxxx.databases.appdomain.cloud",
154
+ "index": "search-wa-docs",
155
+ "port": "31871",
156
+ "query_body": {"size":5,"query":{"text_expansion":{"ml.tokens":{"model_id":".elser_model_2_linux-x86_64","model_text": "$QUERY"}}}},
157
+ "result_filter": [
158
+ {
159
+ "match": {
160
+ "title": "A_keyword_in_title"
161
+ }
162
+ },
163
+ {
164
+ "match": {
165
+ "text": "A_keyword_in_text"
166
+ }
167
+ },
168
+ {
169
+ "match": {
170
+ "id": "A_specific_ID"
171
+ }
172
+ }
173
+ ] = None,
174
+ "field_mapping": {
175
+ "title": "title",
176
+ "body": "text",
177
+ "url": "some-url"
178
+ }
179
+ }
180
+ """
181
+ url: Optional[str] = None
182
+ index: Optional[str] = None
183
+ port: Optional[str] = None
184
+ query_body: Optional[dict] = None
185
+ result_filter: Optional[list] = None
186
+ field_mapping: Optional[FieldMapping] = None
187
+
188
+
189
+ class IndexConnection(BaseModel):
190
+ connection_id: Optional[str] = None
191
+ milvus: Optional[MilvusConnection] = None
192
+ elastic_search: Optional[ElasticSearchConnection] = None
193
+
194
+
195
+ class ConversationalSearchConfig(BaseModel):
196
+ language: Optional[str] = None
197
+ index_config: list[IndexConnection] = None
198
+ generation: Optional[GenerationConfiguration] = None
199
+ query_rewrite: Optional[QueryRewriteConfig] = None
200
+ citations: Optional[CitationsConfig] = None
201
+ hap_filtering: Optional[HAPFiltering] = None
202
+ confidence_thresholds: Optional[ConfidenceThresholds] = None
203
+
204
+ class KnowledgeBaseBuiltInVectorIndexConfig(BaseModel):
205
+ chunk_size: Optional[int] = None
206
+ chunk_overlap: Optional[int] = None
207
+ limit: Optional[int] = None
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
+ class PatchKnowledgeBase(BaseModel):
220
+ """request payload schema"""
221
+ description: Optional[str] = None
222
+ documents: list[str] = None
223
+ conversational_search_tool: Optional[ConversationalSearchConfig] = None
224
+ prioritize_built_in_index: Optional[bool] = None
225
+ representation: Optional[KnowledgeBaseRepresentation] = None
226
+
227
+
228
+ class KnowledgeBaseSpec(BaseModel):
229
+ """Schema for a complete knowledge-base."""
230
+ spec_version: SpecVersion = None
231
+ kind: KnowledgeBaseKind = KnowledgeBaseKind.KNOWLEDGE_BASE
232
+ id: Optional[UUID] = None
233
+ tenant_id: Optional[str] = None
234
+ name: Optional[str] = None
235
+ description: Optional[str] = None
236
+ vector_index: Optional[KnowledgeBaseBuiltInVectorIndexConfig] = None
237
+ conversational_search_tool: Optional[ConversationalSearchConfig] | Optional[UUID] = None
238
+ prioritize_built_in_index: Optional[bool] = None
239
+ vector_index_id: Optional[UUID] = None
240
+ created_by: Optional[str] = None
241
+ created_on: Optional[datetime] = None
242
+ updated_at: Optional[datetime] = None
243
+
@@ -0,0 +1,4 @@
1
+ from .base_tool import BaseTool
2
+ from .python_tool import tool, PythonTool, get_all_python_tools
3
+ from .openapi_tool import create_openapi_json_tool, create_openapi_json_tool_from_uri, create_openapi_json_tools_from_uri, OpenAPITool, HTTPException
4
+ from .types import ToolPermission, JsonSchemaObject, ToolRequestBody, ToolResponseBody, OpenApiSecurityScheme, OpenApiToolBinding, PythonToolBinding, WxFlowsToolBinding, SkillToolBinding, ClientSideToolBinding, ToolBinding, ToolSpec
@@ -0,0 +1,36 @@
1
+ import json
2
+
3
+ import yaml
4
+
5
+ from .types import ToolSpec
6
+
7
+
8
+ class BaseTool:
9
+ __tool_spec__: ToolSpec
10
+
11
+ def __init__(self, spec: ToolSpec):
12
+ self.__tool_spec__ = spec
13
+
14
+ def __call__(self, **kwargs):
15
+ pass
16
+
17
+ def dump_spec(self, file: str) -> None:
18
+ dumped = self.__tool_spec__.model_dump(mode='json', exclude_unset=True, exclude_none=True, by_alias=True)
19
+ with open(file, 'w') as f:
20
+ if file.endswith('.yaml') or file.endswith('.yml'):
21
+ yaml.dump(dumped, f)
22
+ elif file.endswith('.json'):
23
+ json.dump(dumped, f, indent=2)
24
+ else:
25
+ raise ValueError('file must end in .json, .yaml, or .yml')
26
+
27
+ def dumps_spec(self) -> str:
28
+ dumped = self.__tool_spec__.model_dump(mode='json', exclude_unset=True, exclude_none=True, by_alias=True)
29
+ return json.dumps(dumped, indent=2)
30
+
31
+ def to_langchain_tool(self):
32
+ from .integrations.langchain import as_langchain_tool
33
+ return as_langchain_tool(self)
34
+
35
+ def __repr__(self):
36
+ return f"Tool(name='{self.__tool_spec__.name}', description='{self.__tool_spec__.description}')"