ibm-watsonx-orchestrate 1.10.0b1__py3-none-any.whl → 1.10.1__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.
- ibm_watsonx_orchestrate/__init__.py +1 -2
- ibm_watsonx_orchestrate/agent_builder/connections/connections.py +5 -2
- ibm_watsonx_orchestrate/agent_builder/connections/types.py +53 -6
- ibm_watsonx_orchestrate/cli/commands/connections/connections_command.py +33 -4
- ibm_watsonx_orchestrate/cli/commands/connections/connections_controller.py +62 -6
- ibm_watsonx_orchestrate/cli/commands/server/server_command.py +0 -3
- ibm_watsonx_orchestrate/cli/commands/server/types.py +14 -6
- ibm_watsonx_orchestrate/docker/compose-lite.yml +4 -0
- ibm_watsonx_orchestrate/docker/default.env +8 -6
- ibm_watsonx_orchestrate/flow_builder/data_map.py +4 -1
- ibm_watsonx_orchestrate/flow_builder/flows/flow.py +114 -6
- ibm_watsonx_orchestrate/flow_builder/node.py +76 -5
- ibm_watsonx_orchestrate/flow_builder/types.py +92 -9
- {ibm_watsonx_orchestrate-1.10.0b1.dist-info → ibm_watsonx_orchestrate-1.10.1.dist-info}/METADATA +1 -1
- {ibm_watsonx_orchestrate-1.10.0b1.dist-info → ibm_watsonx_orchestrate-1.10.1.dist-info}/RECORD +18 -18
- {ibm_watsonx_orchestrate-1.10.0b1.dist-info → ibm_watsonx_orchestrate-1.10.1.dist-info}/WHEEL +0 -0
- {ibm_watsonx_orchestrate-1.10.0b1.dist-info → ibm_watsonx_orchestrate-1.10.1.dist-info}/entry_points.txt +0 -0
- {ibm_watsonx_orchestrate-1.10.0b1.dist-info → ibm_watsonx_orchestrate-1.10.1.dist-info}/licenses/LICENSE +0 -0
@@ -1,5 +1,6 @@
|
|
1
1
|
import os
|
2
2
|
import logging
|
3
|
+
from copy import deepcopy
|
3
4
|
from typing import List
|
4
5
|
from ibm_watsonx_orchestrate.agent_builder.connections.types import (
|
5
6
|
BasicAuthCredentials,
|
@@ -67,7 +68,8 @@ def _clean_env_vars(vars: dict[str:str], requirements: List[str], app_id: str) -
|
|
67
68
|
return required_env_vars
|
68
69
|
|
69
70
|
def _build_credentials_model(credentials_type: type[CREDENTIALS], vars: dict[str,str], base_prefix: str) -> type[CREDENTIALS]:
|
70
|
-
|
71
|
+
requirements_lut = deepcopy(connection_type_requirements_mapping)
|
72
|
+
requirements = requirements_lut[credentials_type]
|
71
73
|
|
72
74
|
if requirements:
|
73
75
|
requirements.append("url")
|
@@ -101,7 +103,8 @@ def _get_credentials_model(connection_type: ConnectionSecurityScheme, app_id: st
|
|
101
103
|
|
102
104
|
credentials_type = CONNECTION_TYPE_CREDENTIAL_MAPPING[connection_type]
|
103
105
|
|
104
|
-
|
106
|
+
requirements_lut = deepcopy(connection_type_requirements_mapping)
|
107
|
+
requirements = requirements_lut.get(credentials_type)
|
105
108
|
if requirements:
|
106
109
|
variables = _clean_env_vars(vars=variables, requirements=requirements, app_id=app_id)
|
107
110
|
|
@@ -165,6 +165,53 @@ class ConnectionConfiguration(BaseModel):
|
|
165
165
|
raise ValueError("Connection of type 'key_value' cannot be configured at the 'member' level. Key value connections must be of type 'team'")
|
166
166
|
return self
|
167
167
|
|
168
|
+
class ConnectionCredentialsEntryLocation(str, Enum):
|
169
|
+
BODY = 'body'
|
170
|
+
HEADER = 'header',
|
171
|
+
QUERY = 'query'
|
172
|
+
|
173
|
+
def __str__(self):
|
174
|
+
return self.value
|
175
|
+
|
176
|
+
class ConnectionCredentialsEntry(BaseModel):
|
177
|
+
key: str
|
178
|
+
value: str
|
179
|
+
location: ConnectionCredentialsEntryLocation
|
180
|
+
|
181
|
+
def __str__(self):
|
182
|
+
return f"<ConnectionCredentialsEntry: {self.location}:{self.key}={self.value}>"
|
183
|
+
|
184
|
+
class BaseOAuthCredentials(BaseModel):
|
185
|
+
custom_token_query: Optional[dict] = None
|
186
|
+
custom_token_header: Optional[dict] = None
|
187
|
+
custom_token_body: Optional[dict] = None
|
188
|
+
custom_auth_query: Optional[dict] = None
|
189
|
+
|
190
|
+
class ConnectionCredentialsCustomFields(BaseOAuthCredentials):
|
191
|
+
def add_field(self, entry: ConnectionCredentialsEntry, is_token:bool=True) -> None:
|
192
|
+
match entry.location:
|
193
|
+
case ConnectionCredentialsEntryLocation.HEADER:
|
194
|
+
if not is_token:
|
195
|
+
return
|
196
|
+
attribute = "custom_token_header"
|
197
|
+
case ConnectionCredentialsEntryLocation.BODY:
|
198
|
+
if not is_token:
|
199
|
+
return
|
200
|
+
attribute = "custom_token_body"
|
201
|
+
case ConnectionCredentialsEntryLocation.QUERY:
|
202
|
+
if is_token:
|
203
|
+
attribute = "custom_token_query"
|
204
|
+
else:
|
205
|
+
attribute = "custom_auth_query"
|
206
|
+
case _:
|
207
|
+
return
|
208
|
+
|
209
|
+
fields = getattr(self, attribute)
|
210
|
+
if not fields:
|
211
|
+
setattr(self, attribute, {})
|
212
|
+
fields = getattr(self, attribute)
|
213
|
+
fields[entry.key] = entry.value
|
214
|
+
|
168
215
|
class BasicAuthCredentials(BaseModel):
|
169
216
|
username: str
|
170
217
|
password: str
|
@@ -182,7 +229,7 @@ class OAuth2TokenCredentials(BaseModel):
|
|
182
229
|
access_token: str
|
183
230
|
url: Optional[str] = None
|
184
231
|
|
185
|
-
class OAuth2AuthCodeCredentials(
|
232
|
+
class OAuth2AuthCodeCredentials(BaseOAuthCredentials):
|
186
233
|
client_id: str
|
187
234
|
client_secret: str
|
188
235
|
token_url: str
|
@@ -193,7 +240,7 @@ class OAuth2AuthCodeCredentials(BaseModel):
|
|
193
240
|
# client_id: str
|
194
241
|
# authorization_url: str
|
195
242
|
|
196
|
-
class OAuth2PasswordCredentials(
|
243
|
+
class OAuth2PasswordCredentials(BaseOAuthCredentials):
|
197
244
|
username: str
|
198
245
|
password: str
|
199
246
|
client_id: str
|
@@ -203,7 +250,7 @@ class OAuth2PasswordCredentials(BaseModel):
|
|
203
250
|
grant_type: str = "password"
|
204
251
|
|
205
252
|
|
206
|
-
class OAuth2ClientCredentials(
|
253
|
+
class OAuth2ClientCredentials(BaseOAuthCredentials):
|
207
254
|
client_id: str
|
208
255
|
client_secret: str
|
209
256
|
token_url: str
|
@@ -211,7 +258,7 @@ class OAuth2ClientCredentials(BaseModel):
|
|
211
258
|
send_via: ConnectionSendVia = ConnectionSendVia.HEADER
|
212
259
|
grant_type: str = "client_credentials"
|
213
260
|
|
214
|
-
class OAuthOnBehalfOfCredentials(
|
261
|
+
class OAuthOnBehalfOfCredentials(BaseOAuthCredentials):
|
215
262
|
client_id: str
|
216
263
|
access_token_url: str
|
217
264
|
grant_type: str
|
@@ -267,7 +314,7 @@ CONNECTION_TYPE_CREDENTIAL_MAPPING = {
|
|
267
314
|
ConnectionSecurityScheme.KEY_VALUE: KeyValueConnectionCredentials,
|
268
315
|
}
|
269
316
|
|
270
|
-
class IdentityProviderCredentials(
|
317
|
+
class IdentityProviderCredentials(BaseOAuthCredentials):
|
271
318
|
idp_url: str = Field(validation_alias=AliasChoices('idp_url', 'url'), serialization_alias='idp_url')
|
272
319
|
client_id: str
|
273
320
|
client_secret: str
|
@@ -276,4 +323,4 @@ class IdentityProviderCredentials(BaseModel):
|
|
276
323
|
|
277
324
|
class ExpectedCredentials(BaseModel):
|
278
325
|
app_id: str
|
279
|
-
type: ConnectionType | List[ConnectionType]
|
326
|
+
type: ConnectionType | List[ConnectionType]
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import typer
|
2
2
|
from typing_extensions import Annotated, List
|
3
|
-
from ibm_watsonx_orchestrate.agent_builder.connections.types import ConnectionEnvironment, ConnectionPreference, ConnectionKind
|
3
|
+
from ibm_watsonx_orchestrate.agent_builder.connections.types import ConnectionEnvironment, ConnectionPreference, ConnectionKind, ConnectionCredentialsEntry
|
4
4
|
from ibm_watsonx_orchestrate.cli.commands.connections.connections_controller import (
|
5
5
|
add_connection,
|
6
6
|
remove_connection,
|
@@ -8,7 +8,9 @@ from ibm_watsonx_orchestrate.cli.commands.connections.connections_controller imp
|
|
8
8
|
import_connection,
|
9
9
|
configure_connection,
|
10
10
|
set_credentials_connection,
|
11
|
-
set_identity_provider_connection
|
11
|
+
set_identity_provider_connection,
|
12
|
+
token_entry_connection_credentials_parse,
|
13
|
+
auth_entry_connection_credentials_parse
|
12
14
|
)
|
13
15
|
|
14
16
|
connections_app = typer.Typer(no_args_is_help=True)
|
@@ -244,6 +246,22 @@ def set_credentials_connection_command(
|
|
244
246
|
help="For key_value, a key value pair in the form '<key>=<value>'. Multiple values can be passed using `-e key1=value1 -e key2=value2`"
|
245
247
|
)
|
246
248
|
] = None,
|
249
|
+
token_entries: Annotated[
|
250
|
+
List[ConnectionCredentialsEntry],
|
251
|
+
typer.Option(
|
252
|
+
'--token-entries', "-t",
|
253
|
+
parser=token_entry_connection_credentials_parse,
|
254
|
+
help="Custom field options for oauth types token request, a key value location option in the form 'location:<key>=<value>' or '<key>=<value>' with location defaulting to 'header'. Multiple values can be passed using `-t key1=value1 -t location:key2=value2`"
|
255
|
+
)
|
256
|
+
] = None,
|
257
|
+
auth_entries: Annotated[
|
258
|
+
List[ConnectionCredentialsEntry],
|
259
|
+
typer.Option(
|
260
|
+
'--auth-entries',
|
261
|
+
parser=auth_entry_connection_credentials_parse,
|
262
|
+
help="Custom field options for oauth_auth_code_flow auth server request, a key value location option in the form 'location:<key>=<value>' or '<key>=<value>' with location defaulting to 'query'. Note only 'query' is a valid location. Multiple values can be passed using `--auth-entries key1=value1 --auth-entries location:key2=value2`"
|
263
|
+
)
|
264
|
+
] = None,
|
247
265
|
):
|
248
266
|
set_credentials_connection(
|
249
267
|
app_id=app_id,
|
@@ -259,7 +277,9 @@ def set_credentials_connection_command(
|
|
259
277
|
auth_url=auth_url,
|
260
278
|
grant_type=grant_type,
|
261
279
|
scope=scope,
|
262
|
-
entries=entries
|
280
|
+
entries=entries,
|
281
|
+
token_entries=token_entries,
|
282
|
+
auth_entries=auth_entries
|
263
283
|
)
|
264
284
|
|
265
285
|
@connections_app.command(name="set-identity-provider")
|
@@ -311,6 +331,14 @@ def set_identity_provider_connection_command(
|
|
311
331
|
help='The grant-type of the the identity provider'
|
312
332
|
)
|
313
333
|
],
|
334
|
+
token_entries: Annotated[
|
335
|
+
List[ConnectionCredentialsEntry],
|
336
|
+
typer.Option(
|
337
|
+
'--token-entries', "-t",
|
338
|
+
parser=token_entry_connection_credentials_parse,
|
339
|
+
help="Custom field options for oauth types token request, a key value location option in the form 'location:<key>=<value>' or '<key>=<value>' with location defaulting to 'header'. Multiple values can be passed using `-t key1=value1 -t location:key2=value2`"
|
340
|
+
)
|
341
|
+
] = None,
|
314
342
|
):
|
315
343
|
set_identity_provider_connection(
|
316
344
|
app_id=app_id,
|
@@ -319,5 +347,6 @@ def set_identity_provider_connection_command(
|
|
319
347
|
client_id=client_id,
|
320
348
|
client_secret=client_secret,
|
321
349
|
scope=scope,
|
322
|
-
grant_type=grant_type
|
350
|
+
grant_type=grant_type,
|
351
|
+
token_entries=token_entries
|
323
352
|
)
|
@@ -27,7 +27,10 @@ from ibm_watsonx_orchestrate.agent_builder.connections.types import (
|
|
27
27
|
KeyValueConnectionCredentials,
|
28
28
|
CREDENTIALS,
|
29
29
|
IdentityProviderCredentials,
|
30
|
-
OAUTH_CONNECTION_TYPES
|
30
|
+
OAUTH_CONNECTION_TYPES,
|
31
|
+
ConnectionCredentialsEntryLocation,
|
32
|
+
ConnectionCredentialsEntry,
|
33
|
+
ConnectionCredentialsCustomFields
|
31
34
|
|
32
35
|
)
|
33
36
|
|
@@ -167,6 +170,13 @@ def _validate_connection_params(type: ConnectionType, **args) -> None:
|
|
167
170
|
f"Missing flags --grant-type is required for type {type}"
|
168
171
|
)
|
169
172
|
|
173
|
+
if type != ConnectionType.OAUTH2_AUTH_CODE and (
|
174
|
+
args.get('auth_entries')
|
175
|
+
):
|
176
|
+
raise typer.BadParameter(
|
177
|
+
f"The flag --auth-entries is only supported by type {type}"
|
178
|
+
)
|
179
|
+
|
170
180
|
|
171
181
|
def _parse_entry(entry: str) -> dict[str,str]:
|
172
182
|
split_entry = entry.split('=', 1)
|
@@ -176,6 +186,19 @@ def _parse_entry(entry: str) -> dict[str,str]:
|
|
176
186
|
exit(1)
|
177
187
|
return {split_entry[0]: split_entry[1]}
|
178
188
|
|
189
|
+
def _get_oauth_custom_fields(token_entries: List[ConnectionCredentialsEntry] | None, auth_entries: List[ConnectionCredentialsEntry] | None) -> dict:
|
190
|
+
custom_fields = ConnectionCredentialsCustomFields()
|
191
|
+
|
192
|
+
if token_entries:
|
193
|
+
for entry in token_entries:
|
194
|
+
custom_fields.add_field(entry, is_token=True)
|
195
|
+
|
196
|
+
if auth_entries:
|
197
|
+
for entry in auth_entries:
|
198
|
+
custom_fields.add_field(entry, is_token=False)
|
199
|
+
|
200
|
+
return custom_fields.model_dump(exclude_none=True)
|
201
|
+
|
179
202
|
def _get_credentials(type: ConnectionType, **kwargs):
|
180
203
|
match type:
|
181
204
|
case ConnectionType.BASIC_AUTH:
|
@@ -192,18 +215,21 @@ def _get_credentials(type: ConnectionType, **kwargs):
|
|
192
215
|
api_key=kwargs.get("api_key")
|
193
216
|
)
|
194
217
|
case ConnectionType.OAUTH2_AUTH_CODE:
|
218
|
+
custom_fields = _get_oauth_custom_fields(kwargs.get("token_entries"), kwargs.get("auth_entries"))
|
195
219
|
return OAuth2AuthCodeCredentials(
|
196
220
|
authorization_url=kwargs.get("auth_url"),
|
197
221
|
client_id=kwargs.get("client_id"),
|
198
222
|
client_secret=kwargs.get("client_secret"),
|
199
223
|
token_url=kwargs.get("token_url"),
|
200
|
-
scope=kwargs.get("scope")
|
224
|
+
scope=kwargs.get("scope"),
|
225
|
+
**custom_fields
|
201
226
|
)
|
202
227
|
case ConnectionType.OAUTH2_CLIENT_CREDS:
|
203
228
|
# using filtered args as default values will not be set if 'None' is passed, causing validation errors
|
204
229
|
keys = ["client_id","client_secret","token_url","grant_type","send_via", "scope"]
|
205
230
|
filtered_args = { key_name: kwargs[key_name] for key_name in keys if kwargs.get(key_name) }
|
206
|
-
|
231
|
+
custom_fields = _get_oauth_custom_fields(kwargs.get("token_entries"), kwargs.get("auth_entries"))
|
232
|
+
return OAuth2ClientCredentials(**filtered_args, **custom_fields)
|
207
233
|
# case ConnectionType.OAUTH2_IMPLICIT:
|
208
234
|
# return OAuth2ImplicitCredentials(
|
209
235
|
# authorization_url=kwargs.get("auth_url"),
|
@@ -212,13 +238,16 @@ def _get_credentials(type: ConnectionType, **kwargs):
|
|
212
238
|
case ConnectionType.OAUTH2_PASSWORD:
|
213
239
|
keys = ["username", "password", "client_id","client_secret","token_url","grant_type", "scope"]
|
214
240
|
filtered_args = { key_name: kwargs[key_name] for key_name in keys if kwargs.get(key_name) }
|
215
|
-
|
241
|
+
custom_fields = _get_oauth_custom_fields(kwargs.get("token_entries"), kwargs.get("auth_entries"))
|
242
|
+
return OAuth2PasswordCredentials(**filtered_args, **custom_fields)
|
216
243
|
|
217
244
|
case ConnectionType.OAUTH_ON_BEHALF_OF_FLOW:
|
245
|
+
custom_fields = _get_oauth_custom_fields(kwargs.get("token_entries"), kwargs.get("auth_entries"))
|
218
246
|
return OAuthOnBehalfOfCredentials(
|
219
247
|
client_id=kwargs.get("client_id"),
|
220
248
|
access_token_url=kwargs.get("token_url"),
|
221
|
-
grant_type=kwargs.get("grant_type")
|
249
|
+
grant_type=kwargs.get("grant_type"),
|
250
|
+
**custom_fields
|
222
251
|
)
|
223
252
|
case ConnectionType.KEY_VALUE:
|
224
253
|
env = {}
|
@@ -231,6 +260,23 @@ def _get_credentials(type: ConnectionType, **kwargs):
|
|
231
260
|
case _:
|
232
261
|
raise ValueError(f"Invalid type '{type}' selected")
|
233
262
|
|
263
|
+
def _connection_credentials_parse_entry(text: str, default_location: ConnectionCredentialsEntryLocation) -> ConnectionCredentialsEntry:
|
264
|
+
location_kv_pair = text.split(":", 1)
|
265
|
+
key_value = location_kv_pair[-1]
|
266
|
+
location = location_kv_pair[0] if len(location_kv_pair)>1 else default_location
|
267
|
+
|
268
|
+
valid_locations = [item.value for item in ConnectionCredentialsEntryLocation]
|
269
|
+
if location not in valid_locations:
|
270
|
+
raise typer.BadParameter(f"The provided location '{location}' is not in the allowed values {valid_locations}.")
|
271
|
+
|
272
|
+
key_value_pair = key_value.split('=', 1)
|
273
|
+
if len(key_value_pair) != 2:
|
274
|
+
message = f"The entry '{text}' is not in the expected form '<location>:<key>=<value>' or '<key>=<value>'"
|
275
|
+
raise typer.BadParameter(message)
|
276
|
+
key, value = key_value_pair[0], key_value_pair[1]
|
277
|
+
|
278
|
+
return ConnectionCredentialsEntry(key=key, value=value, location=location)
|
279
|
+
|
234
280
|
|
235
281
|
def add_configuration(config: ConnectionConfiguration) -> None:
|
236
282
|
client = get_connections_client()
|
@@ -524,5 +570,15 @@ def set_identity_provider_connection(
|
|
524
570
|
logger.error(f"Cannot set Identity Provider when 'sso' is false in configuration. Please enable sso for connection '{app_id}' in environment '{environment}' and try again.")
|
525
571
|
sys.exit(1)
|
526
572
|
|
527
|
-
|
573
|
+
custom_fields = _get_oauth_custom_fields(token_entries=kwargs.get("token_entries"), auth_entries=None)
|
574
|
+
idp = IdentityProviderCredentials(**kwargs, **custom_fields)
|
528
575
|
add_identity_provider(app_id=app_id, environment=environment, idp=idp)
|
576
|
+
|
577
|
+
def token_entry_connection_credentials_parse(text: str) -> ConnectionCredentialsEntry:
|
578
|
+
return _connection_credentials_parse_entry(text=text, default_location=ConnectionCredentialsEntryLocation.HEADER)
|
579
|
+
|
580
|
+
def auth_entry_connection_credentials_parse(text: str) -> ConnectionCredentialsEntry:
|
581
|
+
entry = _connection_credentials_parse_entry(text=text, default_location=ConnectionCredentialsEntryLocation.QUERY)
|
582
|
+
if entry.location != ConnectionCredentialsEntryLocation.QUERY:
|
583
|
+
raise typer.BadParameter(f"Only location '{ConnectionCredentialsEntryLocation.QUERY}' is supported for --auth-entry")
|
584
|
+
return entry
|
@@ -191,9 +191,6 @@ def get_default_registry_env_vars_by_dev_edition_source(default_env: dict, user_
|
|
191
191
|
parsed = urlparse(wo_url)
|
192
192
|
hostname = parsed.hostname
|
193
193
|
|
194
|
-
if not hostname or not hostname.startswith("api."):
|
195
|
-
raise ValueError(f"Invalid WO_INSTANCE URL: '{wo_url}'. It should starts with 'api.'")
|
196
|
-
|
197
194
|
registry_url = f"registry.{hostname[4:]}/cp/wxo-lite"
|
198
195
|
else:
|
199
196
|
raise ValueError(f"Unknown value for developer edition source: {source}. Must be one of ['internal', 'myibm', 'orchestrate'].")
|
@@ -1,5 +1,6 @@
|
|
1
1
|
import logging
|
2
2
|
import sys
|
3
|
+
import uuid
|
3
4
|
from enum import Enum
|
4
5
|
from pydantic import BaseModel, model_validator, ConfigDict
|
5
6
|
|
@@ -43,9 +44,6 @@ class WatsonXAIEnvConfig(BaseModel):
|
|
43
44
|
if not config.get("WATSONX_SPACE_ID") and not config.get("WATSONX_APIKEY"):
|
44
45
|
raise ValueError("Missing configuration requirements 'WATSONX_SPACE_ID' and 'WATSONX_APIKEY'")
|
45
46
|
|
46
|
-
if config.get("WATSONX_SPACE_ID") and not config.get("WATSONX_APIKEY"):
|
47
|
-
logger.error("Cannot use env var 'WATSONX_SPACE_ID' without setting the corresponding 'WATSONX_APIKEY'")
|
48
|
-
sys.exit(1)
|
49
47
|
|
50
48
|
if not config.get("WATSONX_SPACE_ID") and config.get("WATSONX_APIKEY"):
|
51
49
|
logger.error("Cannot use env var 'WATSONX_APIKEY' without setting the corresponding 'WATSONX_SPACE_ID'")
|
@@ -54,6 +52,12 @@ class WatsonXAIEnvConfig(BaseModel):
|
|
54
52
|
config["USE_SAAS_ML_TOOLS_RUNTIME"] = False
|
55
53
|
return config
|
56
54
|
|
55
|
+
def is_valid_uuid(value) -> bool:
|
56
|
+
try:
|
57
|
+
uuid.UUID(str(value))
|
58
|
+
return True
|
59
|
+
except (ValueError, TypeError, AttributeError):
|
60
|
+
return False
|
57
61
|
|
58
62
|
class ModelGatewayEnvConfig(BaseModel):
|
59
63
|
WO_API_KEY: str | None = None
|
@@ -84,7 +88,10 @@ class ModelGatewayEnvConfig(BaseModel):
|
|
84
88
|
if not config.get("AUTHORIZATION_URL"):
|
85
89
|
inferred_auth_url = AUTH_TYPE_DEFAULT_URL_MAPPING.get(auth_type)
|
86
90
|
if not inferred_auth_url:
|
87
|
-
|
91
|
+
if auth_type == WoAuthType.CPD:
|
92
|
+
inferred_auth_url = config.get("WO_INSTANCE") + '/icp4d-api/v1/authorize'
|
93
|
+
else:
|
94
|
+
logger.error(f"No 'AUTHORIZATION_URL' found. Auth type '{auth_type}' does not support defaulting. Please set the 'AUTHORIZATION_URL' explictly")
|
88
95
|
sys.exit(1)
|
89
96
|
config["AUTHORIZATION_URL"] = inferred_auth_url
|
90
97
|
|
@@ -101,6 +108,7 @@ class ModelGatewayEnvConfig(BaseModel):
|
|
101
108
|
sys.exit(1)
|
102
109
|
|
103
110
|
config["USE_SAAS_ML_TOOLS_RUNTIME"] = True
|
104
|
-
|
105
|
-
|
111
|
+
if not is_valid_uuid(config.get("WATSONX_SPACE_ID")):
|
112
|
+
# Fake (but valid) UUIDv4 for knowledgebase check
|
113
|
+
config["WATSONX_SPACE_ID"] = "aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa"
|
106
114
|
return config
|
@@ -62,6 +62,7 @@ services:
|
|
62
62
|
WATSONX_API_KEY: ${WATSONX_APIKEY}
|
63
63
|
WATSONX_URL: ${WATSONX_URL}
|
64
64
|
WATSONX_SPACE_ID: ${WATSONX_SPACE_ID}
|
65
|
+
NODE_TLS_REJECT_UNAUTHORIZED: ${AI_GATEWAY_TLS_REJECT_UNAUTHORIZED}
|
65
66
|
|
66
67
|
wxo-agent-gateway:
|
67
68
|
image: ${AGENT_GATEWAY_REGISTRY:-us.icr.io/watson-orchestrate-private}/wxo-agent-gateway:${AGENT_GATEWAY_TAG:-latest}
|
@@ -327,6 +328,7 @@ services:
|
|
327
328
|
ENABLE_WEBHOOKS: false
|
328
329
|
DISABLE_JSON_LOG_CELERY: true
|
329
330
|
WXO_DEPLOYMENT_PLATFORM: saas
|
331
|
+
CPD_VERIFY: ${CPD_VERIFY}
|
330
332
|
CONNECTION_MANAGER_URL: http://wxo-server-connection-manager:3001
|
331
333
|
CHANNEL_SESSION_REDIS_URL: redis://wxo-server-redis:6379/5
|
332
334
|
WXO_MILVUS_URI: http://wxo-milvus-standalone:19530
|
@@ -446,6 +448,7 @@ services:
|
|
446
448
|
IBM_TELEMETRY_TRACER_ENDPOINT: http://jaeger:4318/v1/traces
|
447
449
|
USE_IBM_TELEMETRY: ${USE_IBM_TELEMETRY:-false}
|
448
450
|
WXO_DEPLOYMENT_PLATFORM: saas
|
451
|
+
CPD_VERIFY: ${CPD_VERIFY}
|
449
452
|
CALLBACK_HOST_URL: ${CALLBACK_HOST_URL:-http://wxo-server:4321}
|
450
453
|
LANGFLOW_ENABLED: ${LANGFLOW_ENABLED:-false}
|
451
454
|
|
@@ -653,6 +656,7 @@ services:
|
|
653
656
|
- WATSONX_URL=${WATSONX_URL}
|
654
657
|
- PROXY_SERVER_URL=http://jaeger-proxy:9201
|
655
658
|
- WXO_DEPLOYMENT_PLATFORM=saas
|
659
|
+
- CPD_VERIFY=${CPD_VERIFY}
|
656
660
|
- TENANT_API_KEY=${AGENTOPS_API_KEY}
|
657
661
|
- TENANT_CONFIG_URL=http://wxo-server:4321
|
658
662
|
- TENANT_DEFAULT_USERNAME=${ES_USERNAME}
|
@@ -58,10 +58,10 @@ REGISTRY_URL=
|
|
58
58
|
|
59
59
|
|
60
60
|
|
61
|
-
SERVER_TAG=
|
61
|
+
SERVER_TAG=29-08-2025-59ef405
|
62
62
|
SERVER_REGISTRY=
|
63
63
|
|
64
|
-
WORKER_TAG=
|
64
|
+
WORKER_TAG=29-08-2025-cf32b2d
|
65
65
|
WORKER_REGISTRY=
|
66
66
|
|
67
67
|
AI_GATEWAY_TAG=20-08-2025-9ed6d40
|
@@ -78,7 +78,7 @@ AMDDBTAG=29-07-2025-9f3661b
|
|
78
78
|
ARM64DBTAG=29-07-2025-9f3661b
|
79
79
|
|
80
80
|
UI_REGISTRY=
|
81
|
-
UITAG=
|
81
|
+
UITAG=29-08-2025
|
82
82
|
|
83
83
|
CM_REGISTRY=
|
84
84
|
CM_TAG=24-07-2025
|
@@ -86,13 +86,13 @@ CM_TAG=24-07-2025
|
|
86
86
|
TRM_TAG=19-08-2025-fe105eb0b950ff304f712a1a5b9fa3cba92d09da
|
87
87
|
TRM_REGISTRY=
|
88
88
|
|
89
|
-
TR_TAG=
|
89
|
+
TR_TAG=25-08-2025-58ae475
|
90
90
|
TR_REGISTRY=
|
91
91
|
|
92
|
-
BUILDER_TAG=
|
92
|
+
BUILDER_TAG=27-08-2025-7432aca
|
93
93
|
BUILDER_REGISTRY=
|
94
94
|
|
95
|
-
FLOW_RUNTIME_TAG=
|
95
|
+
FLOW_RUNTIME_TAG=26-08-2025-3b7f19e
|
96
96
|
FLOW_RUMTIME_REGISTRY=
|
97
97
|
|
98
98
|
|
@@ -126,6 +126,8 @@ DOCPROC_REGISTRY=
|
|
126
126
|
|
127
127
|
# END -- IMAGE REGISTRIES AND TAGS
|
128
128
|
|
129
|
+
CPD_VERIFY=true
|
130
|
+
AI_GATEWAY_TLS_REJECT_UNAUTHORIZED=1
|
129
131
|
TAVILY_API_KEY=dummy_tavily_api_key
|
130
132
|
PREFERRED_MODELS=meta-llama/llama-3-2-90b-vision-instruct,meta-llama/llama-3-405b-instruct
|
131
133
|
INCOMPATIBLE_MODELS=flan,embedding,cross-encoder,tinytimemixers
|
@@ -12,7 +12,10 @@ class DataMap(BaseModel):
|
|
12
12
|
def to_json(self) -> dict[str, Any]:
|
13
13
|
model_spec = {}
|
14
14
|
if self.maps and len(self.maps) > 0:
|
15
|
-
model_spec["maps"] = [
|
15
|
+
model_spec["maps"] = []
|
16
|
+
for assignment in self.maps:
|
17
|
+
model_spec["maps"].append(assignment.model_dump())
|
18
|
+
return model_spec
|
16
19
|
|
17
20
|
def add(self, line: Assignment) -> Self:
|
18
21
|
self.maps.append(line)
|
@@ -25,7 +25,7 @@ from ibm_watsonx_orchestrate.client.tools.tool_client import ToolClient
|
|
25
25
|
from ibm_watsonx_orchestrate.client.tools.tempus_client import TempusClient
|
26
26
|
from ibm_watsonx_orchestrate.client.utils import instantiate_client
|
27
27
|
from ..types import (
|
28
|
-
DocProcKVPSchema, EndNodeSpec, Expression, ForeachPolicy, ForeachSpec, LoopSpec, BranchNodeSpec, MatchPolicy, PlainTextReadingOrder, PromptLLMParameters, PromptNodeSpec, TimerNodeSpec,
|
28
|
+
DocProcKVPSchema, Assignment, Conditions, EndNodeSpec, Expression, ForeachPolicy, ForeachSpec, LoopSpec, BranchNodeSpec, MatchPolicy, NodeIdCondition, PlainTextReadingOrder, PromptExample, PromptLLMParameters, PromptNodeSpec, TimerNodeSpec,
|
29
29
|
StartNodeSpec, ToolSpec, JsonSchemaObject, ToolRequestBody, ToolResponseBody, UserFieldKind, UserFieldOption, UserFlowSpec, UserNodeSpec, WaitPolicy,
|
30
30
|
DocProcSpec, TextExtractionResponse, DocProcInput, DecisionsNodeSpec, DecisionsRule, DocExtSpec, File, DocumentClassificationResponse, DocClassifierSpec, DocumentProcessingCommonInput
|
31
31
|
)
|
@@ -64,7 +64,7 @@ class FlowEdge(BaseModel):
|
|
64
64
|
|
65
65
|
class Flow(Node):
|
66
66
|
'''Flow represents a flow that will be run by wxO Flow engine.'''
|
67
|
-
output_map: DataMap | None = None
|
67
|
+
output_map: dict[str, DataMap] | None = None
|
68
68
|
nodes: dict[str, SerializeAsAny[Node]] = {}
|
69
69
|
edges: List[FlowEdge] = []
|
70
70
|
schemas: dict[str, JsonSchemaObject] = {}
|
@@ -401,6 +401,7 @@ class Flow(Node):
|
|
401
401
|
display_name: str|None=None,
|
402
402
|
system_prompt: str | list[str] | None = None,
|
403
403
|
user_prompt: str | list[str] | None = None,
|
404
|
+
prompt_examples: list[PromptExample] | None = None,
|
404
405
|
llm: str | None = None,
|
405
406
|
llm_parameters: PromptLLMParameters | None = None,
|
406
407
|
description: str | None = None,
|
@@ -422,6 +423,7 @@ class Flow(Node):
|
|
422
423
|
description=description,
|
423
424
|
system_prompt=system_prompt,
|
424
425
|
user_prompt=user_prompt,
|
426
|
+
prompt_examples=prompt_examples,
|
425
427
|
llm=llm,
|
426
428
|
llm_parameters=llm_parameters,
|
427
429
|
input_schema=_get_tool_request_body(input_schema_obj),
|
@@ -721,7 +723,7 @@ class Flow(Node):
|
|
721
723
|
'''Create a single node flow with an automatic START and END node.'''
|
722
724
|
return self.sequence(START, node, END)
|
723
725
|
|
724
|
-
def branch(self, evaluator: Union[Callable, Expression]) ->
|
726
|
+
def branch(self, evaluator: Union[Callable, Expression, Conditions]) -> 'Branch':
|
725
727
|
'''Create a BRANCH node'''
|
726
728
|
e = evaluator
|
727
729
|
if isinstance(evaluator, Callable):
|
@@ -735,11 +737,19 @@ class Flow(Node):
|
|
735
737
|
# e = new_script_spec
|
736
738
|
elif isinstance(evaluator, str):
|
737
739
|
e = Expression(expression=evaluator)
|
740
|
+
elif isinstance(evaluator, list):
|
741
|
+
e = Conditions(conditions=evaluator)
|
738
742
|
|
739
743
|
spec = BranchNodeSpec(name = "branch_" + str(self._next_sequence_id()), evaluator=e)
|
740
744
|
branch_node = Branch(spec = spec, containing_flow=self)
|
741
745
|
return cast(Branch, self._add_node(branch_node))
|
742
746
|
|
747
|
+
def conditions(self) -> 'Branch':
|
748
|
+
'''Create a Branch node with empty Conditions evaluator (if-else)'''
|
749
|
+
spec = BranchNodeSpec(name = "branch_" + str(self._next_sequence_id()), evaluator=Conditions(conditions=[]))
|
750
|
+
branch_conditions_node = Branch(spec = spec, containing_flow=self)
|
751
|
+
return cast(Branch, self._add_node(branch_conditions_node))
|
752
|
+
|
743
753
|
def wait_for(self, *args) -> "Wait":
|
744
754
|
'''Wait for all incoming nodes to complete.'''
|
745
755
|
raise ValueError("Not implemented yet.")
|
@@ -754,6 +764,77 @@ class Flow(Node):
|
|
754
764
|
|
755
765
|
# return cast(Wait, self.node(wait_node))
|
756
766
|
|
767
|
+
def map_flow_output_with_variable(self, target_output_variable: str, variable: str, default_value: str = None) -> Self:
|
768
|
+
if self.output_map and "spec" in self.output_map:
|
769
|
+
maps = self.output_map["spec"].maps or []
|
770
|
+
else:
|
771
|
+
maps = []
|
772
|
+
|
773
|
+
curr_map_metadata = {
|
774
|
+
"assignmentType": "variable"
|
775
|
+
}
|
776
|
+
|
777
|
+
target_variable = "flow.output." + target_output_variable
|
778
|
+
value_expression = "flow." + variable
|
779
|
+
|
780
|
+
if default_value:
|
781
|
+
maps.append(Assignment(target_variable=target_variable, value_expression=value_expression, default_value=default_value, metadata=curr_map_metadata))
|
782
|
+
else:
|
783
|
+
maps.append(Assignment(target_variable=target_variable, value_expression=value_expression, metadata=curr_map_metadata))
|
784
|
+
|
785
|
+
flow_output_map_spec = DataMap(maps=maps)
|
786
|
+
|
787
|
+
if self.output_map and "spec" in self.output_map:
|
788
|
+
self.output_map["spec"] = flow_output_map_spec
|
789
|
+
else:
|
790
|
+
self.output_map = {"spec": flow_output_map_spec}
|
791
|
+
return self
|
792
|
+
|
793
|
+
def map_output(self, output_variable: str, expression: str, default_value: str = None) -> Self:
|
794
|
+
if self.output_map and "spec" in self.output_map:
|
795
|
+
maps = self.output_map["spec"].maps or []
|
796
|
+
else:
|
797
|
+
maps = []
|
798
|
+
|
799
|
+
curr_map_metadata = {
|
800
|
+
"assignmentType": "pyExpression"
|
801
|
+
}
|
802
|
+
|
803
|
+
target_variable = "flow.output." + output_variable
|
804
|
+
value_expression = expression
|
805
|
+
|
806
|
+
if default_value:
|
807
|
+
maps.append(Assignment(target_variable=target_variable, value_expression=value_expression, default_value=default_value, metadata=curr_map_metadata))
|
808
|
+
else:
|
809
|
+
maps.append(Assignment(target_variable=target_variable, value_expression=value_expression, metadata=curr_map_metadata))
|
810
|
+
|
811
|
+
flow_output_map_spec = DataMap(maps=maps)
|
812
|
+
|
813
|
+
if self.output_map and "spec" in self.output_map:
|
814
|
+
self.output_map["spec"] = flow_output_map_spec
|
815
|
+
else:
|
816
|
+
self.output_map = {"spec": flow_output_map_spec}
|
817
|
+
return self
|
818
|
+
|
819
|
+
def map_flow_output_with_none(self, target_output_variable: str) -> Self:
|
820
|
+
if self.output_map and "spec" in self.output_map:
|
821
|
+
maps = self.output_map["spec"].maps or []
|
822
|
+
else:
|
823
|
+
maps = []
|
824
|
+
|
825
|
+
|
826
|
+
target_variable = "flow.output." + target_output_variable
|
827
|
+
|
828
|
+
maps.append(Assignment(target_variable=target_variable, value_expression=None))
|
829
|
+
|
830
|
+
flow_output_map_spec = DataMap(maps=maps)
|
831
|
+
|
832
|
+
if self.output_map and "spec" in self.output_map:
|
833
|
+
self.output_map["spec"] = flow_output_map_spec
|
834
|
+
else:
|
835
|
+
self.output_map = {"spec": flow_output_map_spec}
|
836
|
+
return self
|
837
|
+
|
757
838
|
|
758
839
|
def foreach(self, item_schema: type[BaseModel],
|
759
840
|
input_schema: type[BaseModel] |None=None,
|
@@ -814,8 +895,6 @@ class Flow(Node):
|
|
814
895
|
input_schema: type[BaseModel] |None=None,
|
815
896
|
output_schema: type[BaseModel] |None=None) -> "UserFlow": # return a UserFlow object
|
816
897
|
|
817
|
-
raise ValueError("userflow is NOT supported yet and it's interface will change.")
|
818
|
-
|
819
898
|
output_schema_obj = _get_json_schema_obj("output", output_schema)
|
820
899
|
input_schema_obj = _get_json_schema_obj("input", input_schema)
|
821
900
|
|
@@ -917,6 +996,11 @@ class Flow(Node):
|
|
917
996
|
for key, value in self.metadata.items():
|
918
997
|
metadata_dict[key] = value
|
919
998
|
flow_dict["metadata"] = metadata_dict
|
999
|
+
|
1000
|
+
if self.output_map and "spec" in self.output_map:
|
1001
|
+
flow_dict["output_map"] = {
|
1002
|
+
"spec": self.output_map["spec"].to_json()
|
1003
|
+
}
|
920
1004
|
return flow_dict
|
921
1005
|
|
922
1006
|
def _get_node_id(self, node: Union[str, Node]) -> str:
|
@@ -1226,6 +1310,27 @@ class Branch(FlowControl):
|
|
1226
1310
|
raise ValueError("Cannot have custom label __default__. Use default() instead.")
|
1227
1311
|
|
1228
1312
|
return self._add_case(label, node)
|
1313
|
+
|
1314
|
+
def condition(self, to_node: Node, expression: str="", default: bool=False) -> Self:
|
1315
|
+
'''
|
1316
|
+
Add a condition to this branch node.
|
1317
|
+
|
1318
|
+
Parameters:
|
1319
|
+
expression (str): The expression of this condition.
|
1320
|
+
to_node (Node): The node to go to when expression is evaluated to true.
|
1321
|
+
default (bool): The condition is the default (else) case.
|
1322
|
+
'''
|
1323
|
+
|
1324
|
+
node_id = self.containing_flow._get_node_id(to_node)
|
1325
|
+
if default:
|
1326
|
+
condition = NodeIdCondition(node_id=node_id, default=default)
|
1327
|
+
else:
|
1328
|
+
condition = NodeIdCondition(expression=expression, node_id=node_id, default=default)
|
1329
|
+
|
1330
|
+
self.spec.evaluator.conditions.append(condition)
|
1331
|
+
self.containing_flow.edge(self, to_node)
|
1332
|
+
|
1333
|
+
return self
|
1229
1334
|
|
1230
1335
|
def default(self, node: Node) -> Self:
|
1231
1336
|
'''
|
@@ -1445,13 +1550,14 @@ class UserFlow(Flow):
|
|
1445
1550
|
kind: UserFieldKind = UserFieldKind.Text,
|
1446
1551
|
display_name: str | None = None,
|
1447
1552
|
description: str | None = None,
|
1553
|
+
direction: str | None = None,
|
1448
1554
|
default: Any | None = None,
|
1449
1555
|
text: str = None, # The text used to ask question to the user, e.g. 'what is your name?'
|
1450
1556
|
option: UserFieldOption | None = None,
|
1451
1557
|
is_list: bool = False,
|
1452
1558
|
min: Any | None = None,
|
1453
1559
|
max: Any | None = None,
|
1454
|
-
input_map: DataMap = None,
|
1560
|
+
input_map: DataMap | None= None,
|
1455
1561
|
custom: dict[str, Any] = {}) -> UserNode:
|
1456
1562
|
'''create a node in the flow'''
|
1457
1563
|
# create a json schema object based on the single field
|
@@ -1483,6 +1589,8 @@ class UserFlow(Flow):
|
|
1483
1589
|
description = description,
|
1484
1590
|
default = default,
|
1485
1591
|
text = text,
|
1592
|
+
direction = direction,
|
1593
|
+
input_map = input_map,
|
1486
1594
|
option = option,
|
1487
1595
|
is_list = is_list,
|
1488
1596
|
min = min,
|
@@ -6,14 +6,14 @@ import yaml
|
|
6
6
|
from pydantic import BaseModel, Field, SerializeAsAny, create_model
|
7
7
|
from enum import Enum
|
8
8
|
|
9
|
-
from .types import DocExtConfigField, EndNodeSpec, NodeSpec, AgentNodeSpec, PromptNodeSpec, TimerNodeSpec, StartNodeSpec, ToolNodeSpec, UserFieldKind, UserFieldOption, UserNodeSpec, DocProcSpec, \
|
9
|
+
from .types import Assignment, DocExtConfigField, EndNodeSpec, NodeSpec, AgentNodeSpec, PromptNodeSpec, TimerNodeSpec, StartNodeSpec, ToolNodeSpec, UserFieldKind, UserFieldOption, UserNodeSpec, DocProcSpec, \
|
10
10
|
DocExtSpec, DocExtConfig, DocClassifierSpec, DecisionsNodeSpec, DocClassifierConfig
|
11
11
|
|
12
12
|
from .data_map import DataMap
|
13
13
|
|
14
14
|
class Node(BaseModel):
|
15
15
|
spec: SerializeAsAny[NodeSpec]
|
16
|
-
input_map: DataMap | None = None
|
16
|
+
input_map: dict[str, DataMap] | None = None
|
17
17
|
|
18
18
|
def __call__(self, **kwargs):
|
19
19
|
pass
|
@@ -40,10 +40,77 @@ class Node(BaseModel):
|
|
40
40
|
def to_json(self) -> dict[str, Any]:
|
41
41
|
model_spec = {}
|
42
42
|
model_spec["spec"] = self.spec.to_json()
|
43
|
-
if self.input_map is not None:
|
44
|
-
model_spec['input_map'] =
|
43
|
+
if self.input_map is not None and "spec" in self.input_map:
|
44
|
+
model_spec['input_map'] = {
|
45
|
+
"spec": self.input_map["spec"].to_json()
|
46
|
+
}
|
45
47
|
|
46
48
|
return model_spec
|
49
|
+
|
50
|
+
def map_node_input_with_variable(self, target_input_variable: str, variable: str, default_value: str = None) -> None:
|
51
|
+
if self.input_map and "spec" in self.input_map:
|
52
|
+
maps = self.input_map["spec"].maps or []
|
53
|
+
else:
|
54
|
+
maps = []
|
55
|
+
|
56
|
+
curr_map_metadata = {
|
57
|
+
"assignmentType": "variable"
|
58
|
+
}
|
59
|
+
|
60
|
+
target_variable = "self.input." + target_input_variable
|
61
|
+
value_expression = "flow." + variable
|
62
|
+
|
63
|
+
if default_value:
|
64
|
+
maps.append(Assignment(target_variable=target_variable, value_expression=value_expression, default_value=default_value, metadata=curr_map_metadata))
|
65
|
+
else:
|
66
|
+
maps.append(Assignment(target_variable=target_variable, value_expression=value_expression, metadata=curr_map_metadata))
|
67
|
+
|
68
|
+
node_input_map_spec = DataMap(maps=maps)
|
69
|
+
if self.input_map and "spec" in self.input_map:
|
70
|
+
self.input_map["spec"] = node_input_map_spec
|
71
|
+
else:
|
72
|
+
self.input_map = {"spec": node_input_map_spec}
|
73
|
+
|
74
|
+
def map_input(self, input_variable: str, expression: str, default_value: str = None) -> None:
|
75
|
+
if self.input_map and "spec" in self.input_map:
|
76
|
+
maps = self.input_map["spec"].maps or []
|
77
|
+
else:
|
78
|
+
maps = []
|
79
|
+
|
80
|
+
curr_map_metadata = {
|
81
|
+
"assignmentType": "pyExpression"
|
82
|
+
}
|
83
|
+
|
84
|
+
target_variable = "self.input." + input_variable
|
85
|
+
value_expression = expression
|
86
|
+
|
87
|
+
if default_value:
|
88
|
+
maps.append(Assignment(target_variable=target_variable, value_expression=value_expression, default_value=default_value, metadata=curr_map_metadata))
|
89
|
+
else:
|
90
|
+
maps.append(Assignment(target_variable=target_variable, value_expression=value_expression, metadata=curr_map_metadata))
|
91
|
+
|
92
|
+
node_input_map_spec = DataMap(maps=maps)
|
93
|
+
if self.input_map and "spec" in self.input_map:
|
94
|
+
self.input_map["spec"] = node_input_map_spec
|
95
|
+
else:
|
96
|
+
self.input_map = {"spec": node_input_map_spec}
|
97
|
+
|
98
|
+
def map_node_input_with_none(self, target_input_variable: str) -> None:
|
99
|
+
if self.input_map and "spec" in self.input_map:
|
100
|
+
maps = self.input_map["spec"].maps or []
|
101
|
+
else:
|
102
|
+
maps = []
|
103
|
+
|
104
|
+
|
105
|
+
target_variable = "self.input." + target_input_variable
|
106
|
+
|
107
|
+
maps.append(Assignment(target_variable=target_variable, value_expression=None))
|
108
|
+
|
109
|
+
node_input_map_spec = DataMap(maps=maps)
|
110
|
+
if self.input_map and "spec" in self.input_map:
|
111
|
+
self.input_map["spec"] = node_input_map_spec
|
112
|
+
else:
|
113
|
+
self.input_map = {"spec": node_input_map_spec}
|
47
114
|
|
48
115
|
class StartNode(Node):
|
49
116
|
def __repr__(self):
|
@@ -83,6 +150,8 @@ class UserNode(Node):
|
|
83
150
|
option: UserFieldOption | None = None,
|
84
151
|
min: Any | None = None,
|
85
152
|
max: Any | None = None,
|
153
|
+
direction: str | None = None,
|
154
|
+
input_map: DataMap | None = None,
|
86
155
|
is_list: bool = False,
|
87
156
|
custom: dict[str, Any] | None = None,
|
88
157
|
widget: str | None = None):
|
@@ -97,7 +166,9 @@ class UserNode(Node):
|
|
97
166
|
max=max,
|
98
167
|
is_list=is_list,
|
99
168
|
custom=custom,
|
100
|
-
widget=widget
|
169
|
+
widget=widget,
|
170
|
+
direction=direction,
|
171
|
+
input_map=input_map)
|
101
172
|
|
102
173
|
class AgentNode(Node):
|
103
174
|
def __repr__(self):
|
@@ -28,6 +28,7 @@ from ibm_watsonx_orchestrate.agent_builder.tools.types import (
|
|
28
28
|
)
|
29
29
|
from .utils import get_valid_name
|
30
30
|
|
31
|
+
|
31
32
|
logger = logging.getLogger(__name__)
|
32
33
|
|
33
34
|
class JsonSchemaObjectRef(JsonSchemaObject):
|
@@ -360,7 +361,6 @@ class EndNodeSpec(NodeSpec):
|
|
360
361
|
def __init__(self, **data):
|
361
362
|
super().__init__(**data)
|
362
363
|
self.kind = "end"
|
363
|
-
|
364
364
|
class ToolNodeSpec(NodeSpec):
|
365
365
|
tool: Union[str, ToolSpec] = Field(default = None, description="the tool to use")
|
366
366
|
|
@@ -421,9 +421,10 @@ class UserFieldKind(str, Enum):
|
|
421
421
|
DateTime: str = "datetime"
|
422
422
|
Time: str = "time"
|
423
423
|
Number: str = "number"
|
424
|
-
|
424
|
+
File: str = "file"
|
425
425
|
Boolean: str = "boolean"
|
426
426
|
Object: str = "object"
|
427
|
+
Choice: str = "any"
|
427
428
|
|
428
429
|
def convert_python_type_to_kind(python_type: type) -> "UserFieldKind":
|
429
430
|
if inspect.isclass(python_type):
|
@@ -463,8 +464,8 @@ class UserFieldKind(str, Enum):
|
|
463
464
|
model_spec["format"] = "number"
|
464
465
|
elif kind == UserFieldKind.Boolean:
|
465
466
|
model_spec["type"] = "boolean"
|
466
|
-
elif kind == UserFieldKind.
|
467
|
-
model_spec["format"] = "
|
467
|
+
elif kind == UserFieldKind.File:
|
468
|
+
model_spec["format"] = "wxo-file"
|
468
469
|
elif kind == UserFieldKind.Object:
|
469
470
|
raise ValueError("Object user fields are not supported.")
|
470
471
|
|
@@ -483,6 +484,8 @@ class UserField(BaseModel):
|
|
483
484
|
text: str | None = Field(default=None, description="A descriptive text that can be used to ask user about this field.")
|
484
485
|
display_name: str | None = None
|
485
486
|
description: str | None = None
|
487
|
+
direction: str | None = None
|
488
|
+
input_map: Any | None = None,
|
486
489
|
default: Any | None = None
|
487
490
|
option: UserFieldOption | None = None
|
488
491
|
min: Any | None = None,
|
@@ -497,6 +500,15 @@ class UserField(BaseModel):
|
|
497
500
|
model_spec["name"] = self.name
|
498
501
|
if self.kind:
|
499
502
|
model_spec["kind"] = self.kind.value
|
503
|
+
if self.direction:
|
504
|
+
model_spec["direction"] = self.direction
|
505
|
+
if self.input_map:
|
506
|
+
# workaround for circular dependency related to Assigments in the Datamap module
|
507
|
+
from .data_map import DataMap
|
508
|
+
if self.input_map and not isinstance(self.input_map, DataMap):
|
509
|
+
raise TypeError("input_map must be an instance of DataMap")
|
510
|
+
#model_spec["input_map"] = self.input_map.to_json()
|
511
|
+
model_spec["input_map"] = {"spec": self.input_map.to_json()}
|
500
512
|
if self.text:
|
501
513
|
model_spec["text"] = self.text
|
502
514
|
if self.display_name:
|
@@ -556,7 +568,15 @@ class UserNodeSpec(NodeSpec):
|
|
556
568
|
max: Any | None = None,
|
557
569
|
is_list: bool = False,
|
558
570
|
custom: dict[str, Any] | None = None,
|
559
|
-
widget: str | None = None
|
571
|
+
widget: str | None = None,
|
572
|
+
input_map: Any | None = None,
|
573
|
+
direction: str | None = None):
|
574
|
+
|
575
|
+
# workaround for circular dependency related to Assigments in the Datamap module
|
576
|
+
from .data_map import DataMap
|
577
|
+
if input_map and not isinstance(input_map, DataMap):
|
578
|
+
raise TypeError("input_map must be an instance of DataMap")
|
579
|
+
|
560
580
|
userfield = UserField(name=name,
|
561
581
|
kind=kind,
|
562
582
|
text=text,
|
@@ -568,7 +588,9 @@ class UserNodeSpec(NodeSpec):
|
|
568
588
|
max=max,
|
569
589
|
is_list=is_list,
|
570
590
|
custom=custom,
|
571
|
-
widget=widget
|
591
|
+
widget=widget,
|
592
|
+
direction=direction,
|
593
|
+
input_map=input_map)
|
572
594
|
|
573
595
|
# find the index of the field
|
574
596
|
i = 0
|
@@ -660,11 +682,28 @@ class PromptLLMParameters(BaseModel):
|
|
660
682
|
if self.stop_sequences:
|
661
683
|
model_spec["stop_sequences"] = self.stop_sequences
|
662
684
|
return model_spec
|
685
|
+
|
686
|
+
class PromptExample(BaseModel):
|
687
|
+
input: Optional[str] = None
|
688
|
+
expected_output: Optional[str] = None
|
689
|
+
enabled: bool
|
690
|
+
|
691
|
+
def to_json(self) -> dict[str, Any]:
|
692
|
+
model_spec = {}
|
693
|
+
if self.input:
|
694
|
+
model_spec["input"] = self.input
|
695
|
+
if self.expected_output:
|
696
|
+
model_spec["expected_output"] = self.expected_output
|
697
|
+
if self.enabled:
|
698
|
+
model_spec["enabled"] = self.enabled
|
699
|
+
return model_spec
|
700
|
+
|
663
701
|
|
664
702
|
|
665
703
|
class PromptNodeSpec(NodeSpec):
|
666
704
|
system_prompt: str | list[str]
|
667
705
|
user_prompt: str | list[str]
|
706
|
+
prompt_examples: Optional[list[PromptExample]]
|
668
707
|
llm: Optional[str]
|
669
708
|
llm_parameters: Optional[PromptLLMParameters]
|
670
709
|
|
@@ -682,7 +721,10 @@ class PromptNodeSpec(NodeSpec):
|
|
682
721
|
model_spec["llm"] = self.llm
|
683
722
|
if self.llm_parameters:
|
684
723
|
model_spec["llm_parameters"] = self.llm_parameters.to_json()
|
685
|
-
|
724
|
+
if self.prompt_examples:
|
725
|
+
model_spec["prompt_examples"] = []
|
726
|
+
for example in self.prompt_examples:
|
727
|
+
model_spec["prompt_examples"].append(example.to_json())
|
686
728
|
return model_spec
|
687
729
|
|
688
730
|
class TimerNodeSpec(NodeSpec):
|
@@ -707,6 +749,47 @@ class Expression(BaseModel):
|
|
707
749
|
model_spec["expression"] = self.expression;
|
708
750
|
return model_spec
|
709
751
|
|
752
|
+
class NodeIdCondition(BaseModel):
|
753
|
+
'''One Condition contains an expression, a node_id that branch should go to when expression is true, and a default indicator. '''
|
754
|
+
expression: Optional[str] = Field(description="A python expression to be run by the flow engine", default=None)
|
755
|
+
node_id: str = Field(description="ID of the node in the flow that branch node should go to")
|
756
|
+
default: bool = Field(description="Boolean indicating if the condition is default case")
|
757
|
+
|
758
|
+
def to_json(self) -> dict[str, Any]:
|
759
|
+
model_spec = {}
|
760
|
+
if self.expression:
|
761
|
+
model_spec["expression"] = self.expression
|
762
|
+
model_spec["node_id"] = self.node_id
|
763
|
+
model_spec["default"] = self.default
|
764
|
+
return model_spec
|
765
|
+
|
766
|
+
|
767
|
+
class EdgeIdCondition(BaseModel):
|
768
|
+
'''One Condition contains an expression, an edge_id that branch should go to when expression is true, and a default indicator. '''
|
769
|
+
expression: Optional[str] = Field(description="A python expression to be run by the flow engine")
|
770
|
+
edge_id: str = Field(description="ID of the edge in the flow that branch node should go to")
|
771
|
+
default: bool = Field(description="Boolean indicating if the condition is default case")
|
772
|
+
|
773
|
+
def to_json(self) -> dict[str, Any]:
|
774
|
+
model_spec = {}
|
775
|
+
if self.expression:
|
776
|
+
model_spec["expression"] = self.expression
|
777
|
+
model_spec["edge_id"] = self.edge_id
|
778
|
+
model_spec["default"] = self.default
|
779
|
+
return model_spec
|
780
|
+
|
781
|
+
class Conditions(BaseModel):
|
782
|
+
'''One Conditions is an array represents the if-else conditions of a complex branch'''
|
783
|
+
conditions: list = List[Union[NodeIdCondition, EdgeIdCondition]]
|
784
|
+
|
785
|
+
def to_json(self) -> dict[str, Any]:
|
786
|
+
model_spec = {}
|
787
|
+
condition_list = []
|
788
|
+
for condition in self.conditions:
|
789
|
+
condition_list.append(NodeIdCondition.model_validate(condition).to_json())
|
790
|
+
model_spec["conditions"] = condition_list
|
791
|
+
return model_spec
|
792
|
+
|
710
793
|
class MatchPolicy(Enum):
|
711
794
|
|
712
795
|
FIRST_MATCH = 1
|
@@ -724,7 +807,7 @@ class BranchNodeSpec(FlowControlNodeSpec):
|
|
724
807
|
cases (dict[str | bool, str]): A dictionary of labels to node names. The keys can be strings or booleans.
|
725
808
|
match_policy (MatchPolicy): The policy to use when evaluating the expression.
|
726
809
|
'''
|
727
|
-
evaluator: Expression
|
810
|
+
evaluator: Expression | Conditions
|
728
811
|
cases: dict[str | bool, str] = Field(default = {},
|
729
812
|
description="A dictionary of labels to node names.")
|
730
813
|
match_policy: MatchPolicy = Field(default = MatchPolicy.FIRST_MATCH)
|
@@ -808,7 +891,7 @@ class UserFlowSpec(FlowSpec):
|
|
808
891
|
|
809
892
|
def __init__(self, **kwargs):
|
810
893
|
super().__init__(**kwargs)
|
811
|
-
self.kind = "
|
894
|
+
self.kind = "user_flow"
|
812
895
|
|
813
896
|
def to_json(self) -> dict[str, Any]:
|
814
897
|
model_spec = super().to_json()
|
{ibm_watsonx_orchestrate-1.10.0b1.dist-info → ibm_watsonx_orchestrate-1.10.1.dist-info}/RECORD
RENAMED
@@ -1,4 +1,4 @@
|
|
1
|
-
ibm_watsonx_orchestrate/__init__.py,sha256=
|
1
|
+
ibm_watsonx_orchestrate/__init__.py,sha256=PRy6NfSG4mSt4yawB2bLg9gwssVrWTF8ssncV9sp0vU,426
|
2
2
|
ibm_watsonx_orchestrate/agent_builder/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
3
3
|
ibm_watsonx_orchestrate/agent_builder/agents/__init__.py,sha256=lmZwaiWXD4Ea19nrMwZXaqCxFMG29xNS8vUoZtK3yI4,392
|
4
4
|
ibm_watsonx_orchestrate/agent_builder/agents/agent.py,sha256=W0uya81fQPrYZFaO_tlsxBL56Bfpw0xrqdxQJhAZ6XI,983
|
@@ -9,8 +9,8 @@ ibm_watsonx_orchestrate/agent_builder/agents/webchat_customizations/__init__.py,
|
|
9
9
|
ibm_watsonx_orchestrate/agent_builder/agents/webchat_customizations/prompts.py,sha256=jNVF_jgz1Dmt7-RxAceAS0XWXk_fx9h3sS_fGrvZT28,941
|
10
10
|
ibm_watsonx_orchestrate/agent_builder/agents/webchat_customizations/welcome_content.py,sha256=U76wZrblSXx4qv7phcPYs3l8SiFzwZ5cJ74u8Y2iYhU,608
|
11
11
|
ibm_watsonx_orchestrate/agent_builder/connections/__init__.py,sha256=B9FwmBbdJxFj3KmJ87Fc78TbzxOr1MIVhaHPJePOGSQ,716
|
12
|
-
ibm_watsonx_orchestrate/agent_builder/connections/connections.py,sha256=
|
13
|
-
ibm_watsonx_orchestrate/agent_builder/connections/types.py,sha256=
|
12
|
+
ibm_watsonx_orchestrate/agent_builder/connections/connections.py,sha256=ozRTZ1Y10YbipE6oegI8QIP31fWqUaBUFoHAo-WTY3g,5547
|
13
|
+
ibm_watsonx_orchestrate/agent_builder/connections/types.py,sha256=cfM2L4VscC-0muDwqq5EhCKKQxwWyHmA-rQBE9LE7r0,11244
|
14
14
|
ibm_watsonx_orchestrate/agent_builder/knowledge_bases/knowledge_base.py,sha256=_KuGF0RZpKpwdt31rzjlTjrhGRFz2RtLzleNkhMNX4k,1831
|
15
15
|
ibm_watsonx_orchestrate/agent_builder/knowledge_bases/knowledge_base_requests.py,sha256=3xTfFMZR17EN8eYRhsVyBfOEzlTqyi0eYaMXyv0_ZtQ,862
|
16
16
|
ibm_watsonx_orchestrate/agent_builder/knowledge_bases/types.py,sha256=2MP3_c6V3OdbwrdDDffGtrBoAhoa3q-YoUXj_RsMG_M,8340
|
@@ -42,8 +42,8 @@ ibm_watsonx_orchestrate/cli/commands/channels/types.py,sha256=hMFvWPr7tAmDrhBqtz
|
|
42
42
|
ibm_watsonx_orchestrate/cli/commands/channels/webchat/channels_webchat_command.py,sha256=vPCr6z1n1yzGDjTlM4f3_9MiuVRzNmXbvUifm6XyQi8,1103
|
43
43
|
ibm_watsonx_orchestrate/cli/commands/channels/webchat/channels_webchat_controller.py,sha256=CGfmKsCBX4E3HMZ8C0IXD-DHQNwe96V1Y_BxUZM2us0,8557
|
44
44
|
ibm_watsonx_orchestrate/cli/commands/chat/chat_command.py,sha256=Q9vg2Z5Fsunu6GQFY_TIsNRhUCa0SSGSPnK4jxSGK34,1581
|
45
|
-
ibm_watsonx_orchestrate/cli/commands/connections/connections_command.py,sha256=
|
46
|
-
ibm_watsonx_orchestrate/cli/commands/connections/connections_controller.py,sha256=
|
45
|
+
ibm_watsonx_orchestrate/cli/commands/connections/connections_command.py,sha256=lwPhDPemDvFU-j7QUj8E07hsnzLBUJDNcyhQDzxs3S8,12442
|
46
|
+
ibm_watsonx_orchestrate/cli/commands/connections/connections_controller.py,sha256=_i1gaR2Nuy9gPLJZTJWoVnRvg9vKcwyg2UoiK5Azsw4,26390
|
47
47
|
ibm_watsonx_orchestrate/cli/commands/copilot/copilot_command.py,sha256=IxasApIyQYWRMKPXKa38ZPVkUvOc4chggSmSGjgQGXc,2345
|
48
48
|
ibm_watsonx_orchestrate/cli/commands/copilot/copilot_controller.py,sha256=SC2Tjq6r-tHIiyPBMajsxdMIY3BQpRWpkYGZS2XbJyU,18981
|
49
49
|
ibm_watsonx_orchestrate/cli/commands/copilot/copilot_server_controller.py,sha256=AcBE97qNYsRN0ftY_E-AAjKFyVea4fHtU5eB2HsB42I,5619
|
@@ -58,8 +58,8 @@ ibm_watsonx_orchestrate/cli/commands/login/login_command.py,sha256=xArMiojoozg7E
|
|
58
58
|
ibm_watsonx_orchestrate/cli/commands/models/model_provider_mapper.py,sha256=mbvBR5o9M7W6OpTZyd6TtSEOIXq07dPYz4hv5zDrsd0,8129
|
59
59
|
ibm_watsonx_orchestrate/cli/commands/models/models_command.py,sha256=PW-PIM5Nq0qdCopWjANGBWEuEoA3NLTFThYrN8ggGCI,6425
|
60
60
|
ibm_watsonx_orchestrate/cli/commands/models/models_controller.py,sha256=eZSYQUg9TL_-8lgcPVpKIx7MtOE7K_NCvZW9Y9YsFA0,18466
|
61
|
-
ibm_watsonx_orchestrate/cli/commands/server/server_command.py,sha256=
|
62
|
-
ibm_watsonx_orchestrate/cli/commands/server/types.py,sha256=
|
61
|
+
ibm_watsonx_orchestrate/cli/commands/server/server_command.py,sha256=cMy_GGYXbug5A6IGoddUzBUCmunySCI8BC-ebRL6p4A,46489
|
62
|
+
ibm_watsonx_orchestrate/cli/commands/server/types.py,sha256=lOrPLzadXJ3pVnIVsQRb0keXckFBGMDD3Holjfge9GI,4412
|
63
63
|
ibm_watsonx_orchestrate/cli/commands/settings/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
64
64
|
ibm_watsonx_orchestrate/cli/commands/settings/settings_command.py,sha256=CzXRkd-97jXyS6LtaaNtMah-aZu0919dYl-mDwzGThc,344
|
65
65
|
ibm_watsonx_orchestrate/cli/commands/settings/observability/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -101,23 +101,23 @@ ibm_watsonx_orchestrate/client/toolkit/toolkit_client.py,sha256=TLFNS39EeBD_t4Y-
|
|
101
101
|
ibm_watsonx_orchestrate/client/tools/tempus_client.py,sha256=24fKDZUOVHBW-Vj4mubnpnUmab5LgGn8u5hOVyJaozI,1804
|
102
102
|
ibm_watsonx_orchestrate/client/tools/tool_client.py,sha256=d3i3alVwa0TCN72w9sWOrM20GCbNmnpTnqEOJVbBIFM,1994
|
103
103
|
ibm_watsonx_orchestrate/client/voice_configurations/voice_configurations_client.py,sha256=M5xIPLiVNpP-zxQw8CTNT9AiBjeXXmJiNaE142e2A3E,2682
|
104
|
-
ibm_watsonx_orchestrate/docker/compose-lite.yml,sha256=
|
105
|
-
ibm_watsonx_orchestrate/docker/default.env,sha256=
|
104
|
+
ibm_watsonx_orchestrate/docker/compose-lite.yml,sha256=iFk3JcGUs4aanAzTZkgG1EcsunWp_awkuIphpjLmeX8,45848
|
105
|
+
ibm_watsonx_orchestrate/docker/default.env,sha256=jz6MNLTvVIVTUOY8AYLOLy589nMs_v0nzQM5rKYACwg,6293
|
106
106
|
ibm_watsonx_orchestrate/docker/proxy-config-single.yaml,sha256=WEbK4ENFuTCYhzRu_QblWp1_GMARgZnx5vReQafkIG8,308
|
107
107
|
ibm_watsonx_orchestrate/docker/start-up.sh,sha256=LTtwHp0AidVgjohis2LXGvZnkFQStOiUAxgGABOyeUI,1811
|
108
108
|
ibm_watsonx_orchestrate/docker/sdk/ibm_watsonx_orchestrate-0.6.0-py3-none-any.whl,sha256=Hi3-owh5OM0Jz2ihX9nLoojnr7Ky1TV-GelyqLcewLE,2047417
|
109
109
|
ibm_watsonx_orchestrate/docker/sdk/ibm_watsonx_orchestrate-0.6.0.tar.gz,sha256=e5T-q7XPAtiCyQljwZp6kk3Q_4Tg6y5sijHTkscmqqQ,2025466
|
110
110
|
ibm_watsonx_orchestrate/docker/tempus/common-config.yaml,sha256=Zo3F36F5DV4VO_vUg1RG-r4WhcukVh79J2fXhGl6j0A,22
|
111
111
|
ibm_watsonx_orchestrate/flow_builder/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
112
|
-
ibm_watsonx_orchestrate/flow_builder/data_map.py,sha256=
|
113
|
-
ibm_watsonx_orchestrate/flow_builder/node.py,sha256=
|
114
|
-
ibm_watsonx_orchestrate/flow_builder/types.py,sha256=
|
112
|
+
ibm_watsonx_orchestrate/flow_builder/data_map.py,sha256=LinePFgb5mBnrvNmPkFe3rq5oYJZSjcgmaEGpE6dVwc,586
|
113
|
+
ibm_watsonx_orchestrate/flow_builder/node.py,sha256=U7-cYYhe7Gj_j6U0dw1ufaPROvXmFo30ZI8s7eTXZlk,9940
|
114
|
+
ibm_watsonx_orchestrate/flow_builder/types.py,sha256=FJw9pvXag9paNtwH1p9pnva0bvLMJ-ISFemyDJe7WXY,51392
|
115
115
|
ibm_watsonx_orchestrate/flow_builder/utils.py,sha256=8q1jr5i_TzoJpoQxmLiO0g5Uv03BLbTUaRfw8_0VWIY,11931
|
116
116
|
ibm_watsonx_orchestrate/flow_builder/flows/__init__.py,sha256=iRYV0_eXgBBGhuNnvg-mUyPUyCIw5BiallPOp27bzYM,1083
|
117
117
|
ibm_watsonx_orchestrate/flow_builder/flows/constants.py,sha256=-TGneZyjA4YiAtJJK7OmmjDHYQC4mw2e98MPAZqiB50,324
|
118
118
|
ibm_watsonx_orchestrate/flow_builder/flows/decorators.py,sha256=lr4qSWq5PWqlGFf4fzUQZCVQDHBYflrYwZ24S89Aq80,2794
|
119
119
|
ibm_watsonx_orchestrate/flow_builder/flows/events.py,sha256=VyaBm0sADwr15LWfKbcBQS1M80NKqzYDj3UlW3OpOf4,2984
|
120
|
-
ibm_watsonx_orchestrate/flow_builder/flows/flow.py,sha256=
|
120
|
+
ibm_watsonx_orchestrate/flow_builder/flows/flow.py,sha256=UqFgGxYM9EIXk6pZjMMI5s6r1C11Gb9kRN5NVbJChoc,64824
|
121
121
|
ibm_watsonx_orchestrate/run/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
122
122
|
ibm_watsonx_orchestrate/run/connections.py,sha256=9twXkNeUx83fP_qYUbJRtumE-wzPPNN2v-IY_8hGndM,1820
|
123
123
|
ibm_watsonx_orchestrate/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -126,8 +126,8 @@ ibm_watsonx_orchestrate/utils/utils.py,sha256=U7z_2iASoFiZ2zM0a_2Mc2Y-P5oOT7hOwu
|
|
126
126
|
ibm_watsonx_orchestrate/utils/logging/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
127
127
|
ibm_watsonx_orchestrate/utils/logging/logger.py,sha256=FzeGnidXAjC7yHrvIaj4KZPeaBBSCniZFlwgr5yV3oA,1037
|
128
128
|
ibm_watsonx_orchestrate/utils/logging/logging.yaml,sha256=9_TKfuFr1barnOKP0fZT5D6MhddiwsXVTFjtRbcOO5w,314
|
129
|
-
ibm_watsonx_orchestrate-1.10.
|
130
|
-
ibm_watsonx_orchestrate-1.10.
|
131
|
-
ibm_watsonx_orchestrate-1.10.
|
132
|
-
ibm_watsonx_orchestrate-1.10.
|
133
|
-
ibm_watsonx_orchestrate-1.10.
|
129
|
+
ibm_watsonx_orchestrate-1.10.1.dist-info/METADATA,sha256=a2z_4K9IvBH1Elg31ecfkyAuPEIS4j5mHYn29boz2eg,1361
|
130
|
+
ibm_watsonx_orchestrate-1.10.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
131
|
+
ibm_watsonx_orchestrate-1.10.1.dist-info/entry_points.txt,sha256=SfIT02-Jen5e99OcLhzbcM9Bdyf8SGVOCtnSplgZdQI,69
|
132
|
+
ibm_watsonx_orchestrate-1.10.1.dist-info/licenses/LICENSE,sha256=Shgxx7hTdCOkiVRmfGgp_1ISISrwQD7m2f0y8Hsapl4,1083
|
133
|
+
ibm_watsonx_orchestrate-1.10.1.dist-info/RECORD,,
|
{ibm_watsonx_orchestrate-1.10.0b1.dist-info → ibm_watsonx_orchestrate-1.10.1.dist-info}/WHEEL
RENAMED
File without changes
|
File without changes
|
File without changes
|