ibm-watsonx-orchestrate 1.10.1__py3-none-any.whl → 1.10.2__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/types.py +6 -53
- ibm_watsonx_orchestrate/cli/commands/connections/connections_command.py +4 -33
- ibm_watsonx_orchestrate/cli/commands/connections/connections_controller.py +6 -62
- ibm_watsonx_orchestrate/cli/commands/server/server_command.py +3 -0
- ibm_watsonx_orchestrate/cli/commands/server/types.py +6 -14
- ibm_watsonx_orchestrate/docker/compose-lite.yml +0 -4
- ibm_watsonx_orchestrate/docker/default.env +1 -3
- ibm_watsonx_orchestrate/flow_builder/data_map.py +1 -4
- ibm_watsonx_orchestrate/flow_builder/flows/flow.py +6 -114
- ibm_watsonx_orchestrate/flow_builder/node.py +5 -76
- ibm_watsonx_orchestrate/flow_builder/types.py +9 -92
- {ibm_watsonx_orchestrate-1.10.1.dist-info → ibm_watsonx_orchestrate-1.10.2.dist-info}/METADATA +1 -1
- {ibm_watsonx_orchestrate-1.10.1.dist-info → ibm_watsonx_orchestrate-1.10.2.dist-info}/RECORD +17 -17
- {ibm_watsonx_orchestrate-1.10.1.dist-info → ibm_watsonx_orchestrate-1.10.2.dist-info}/WHEEL +0 -0
- {ibm_watsonx_orchestrate-1.10.1.dist-info → ibm_watsonx_orchestrate-1.10.2.dist-info}/entry_points.txt +0 -0
- {ibm_watsonx_orchestrate-1.10.1.dist-info → ibm_watsonx_orchestrate-1.10.2.dist-info}/licenses/LICENSE +0 -0
@@ -165,53 +165,6 @@ 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
|
-
|
215
168
|
class BasicAuthCredentials(BaseModel):
|
216
169
|
username: str
|
217
170
|
password: str
|
@@ -229,7 +182,7 @@ class OAuth2TokenCredentials(BaseModel):
|
|
229
182
|
access_token: str
|
230
183
|
url: Optional[str] = None
|
231
184
|
|
232
|
-
class OAuth2AuthCodeCredentials(
|
185
|
+
class OAuth2AuthCodeCredentials(BaseModel):
|
233
186
|
client_id: str
|
234
187
|
client_secret: str
|
235
188
|
token_url: str
|
@@ -240,7 +193,7 @@ class OAuth2AuthCodeCredentials(BaseOAuthCredentials):
|
|
240
193
|
# client_id: str
|
241
194
|
# authorization_url: str
|
242
195
|
|
243
|
-
class OAuth2PasswordCredentials(
|
196
|
+
class OAuth2PasswordCredentials(BaseModel):
|
244
197
|
username: str
|
245
198
|
password: str
|
246
199
|
client_id: str
|
@@ -250,7 +203,7 @@ class OAuth2PasswordCredentials(BaseOAuthCredentials):
|
|
250
203
|
grant_type: str = "password"
|
251
204
|
|
252
205
|
|
253
|
-
class OAuth2ClientCredentials(
|
206
|
+
class OAuth2ClientCredentials(BaseModel):
|
254
207
|
client_id: str
|
255
208
|
client_secret: str
|
256
209
|
token_url: str
|
@@ -258,7 +211,7 @@ class OAuth2ClientCredentials(BaseOAuthCredentials):
|
|
258
211
|
send_via: ConnectionSendVia = ConnectionSendVia.HEADER
|
259
212
|
grant_type: str = "client_credentials"
|
260
213
|
|
261
|
-
class OAuthOnBehalfOfCredentials(
|
214
|
+
class OAuthOnBehalfOfCredentials(BaseModel):
|
262
215
|
client_id: str
|
263
216
|
access_token_url: str
|
264
217
|
grant_type: str
|
@@ -314,7 +267,7 @@ CONNECTION_TYPE_CREDENTIAL_MAPPING = {
|
|
314
267
|
ConnectionSecurityScheme.KEY_VALUE: KeyValueConnectionCredentials,
|
315
268
|
}
|
316
269
|
|
317
|
-
class IdentityProviderCredentials(
|
270
|
+
class IdentityProviderCredentials(BaseModel):
|
318
271
|
idp_url: str = Field(validation_alias=AliasChoices('idp_url', 'url'), serialization_alias='idp_url')
|
319
272
|
client_id: str
|
320
273
|
client_secret: str
|
@@ -323,4 +276,4 @@ class IdentityProviderCredentials(BaseOAuthCredentials):
|
|
323
276
|
|
324
277
|
class ExpectedCredentials(BaseModel):
|
325
278
|
app_id: str
|
326
|
-
type: ConnectionType | List[ConnectionType]
|
279
|
+
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
|
4
4
|
from ibm_watsonx_orchestrate.cli.commands.connections.connections_controller import (
|
5
5
|
add_connection,
|
6
6
|
remove_connection,
|
@@ -8,9 +8,7 @@ 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
|
12
|
-
token_entry_connection_credentials_parse,
|
13
|
-
auth_entry_connection_credentials_parse
|
11
|
+
set_identity_provider_connection
|
14
12
|
)
|
15
13
|
|
16
14
|
connections_app = typer.Typer(no_args_is_help=True)
|
@@ -246,22 +244,6 @@ def set_credentials_connection_command(
|
|
246
244
|
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`"
|
247
245
|
)
|
248
246
|
] = 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,
|
265
247
|
):
|
266
248
|
set_credentials_connection(
|
267
249
|
app_id=app_id,
|
@@ -277,9 +259,7 @@ def set_credentials_connection_command(
|
|
277
259
|
auth_url=auth_url,
|
278
260
|
grant_type=grant_type,
|
279
261
|
scope=scope,
|
280
|
-
entries=entries
|
281
|
-
token_entries=token_entries,
|
282
|
-
auth_entries=auth_entries
|
262
|
+
entries=entries
|
283
263
|
)
|
284
264
|
|
285
265
|
@connections_app.command(name="set-identity-provider")
|
@@ -331,14 +311,6 @@ def set_identity_provider_connection_command(
|
|
331
311
|
help='The grant-type of the the identity provider'
|
332
312
|
)
|
333
313
|
],
|
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,
|
342
314
|
):
|
343
315
|
set_identity_provider_connection(
|
344
316
|
app_id=app_id,
|
@@ -347,6 +319,5 @@ def set_identity_provider_connection_command(
|
|
347
319
|
client_id=client_id,
|
348
320
|
client_secret=client_secret,
|
349
321
|
scope=scope,
|
350
|
-
grant_type=grant_type
|
351
|
-
token_entries=token_entries
|
322
|
+
grant_type=grant_type
|
352
323
|
)
|
@@ -27,10 +27,7 @@ from ibm_watsonx_orchestrate.agent_builder.connections.types import (
|
|
27
27
|
KeyValueConnectionCredentials,
|
28
28
|
CREDENTIALS,
|
29
29
|
IdentityProviderCredentials,
|
30
|
-
OAUTH_CONNECTION_TYPES
|
31
|
-
ConnectionCredentialsEntryLocation,
|
32
|
-
ConnectionCredentialsEntry,
|
33
|
-
ConnectionCredentialsCustomFields
|
30
|
+
OAUTH_CONNECTION_TYPES
|
34
31
|
|
35
32
|
)
|
36
33
|
|
@@ -170,13 +167,6 @@ def _validate_connection_params(type: ConnectionType, **args) -> None:
|
|
170
167
|
f"Missing flags --grant-type is required for type {type}"
|
171
168
|
)
|
172
169
|
|
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
|
-
|
180
170
|
|
181
171
|
def _parse_entry(entry: str) -> dict[str,str]:
|
182
172
|
split_entry = entry.split('=', 1)
|
@@ -186,19 +176,6 @@ def _parse_entry(entry: str) -> dict[str,str]:
|
|
186
176
|
exit(1)
|
187
177
|
return {split_entry[0]: split_entry[1]}
|
188
178
|
|
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
|
-
|
202
179
|
def _get_credentials(type: ConnectionType, **kwargs):
|
203
180
|
match type:
|
204
181
|
case ConnectionType.BASIC_AUTH:
|
@@ -215,21 +192,18 @@ def _get_credentials(type: ConnectionType, **kwargs):
|
|
215
192
|
api_key=kwargs.get("api_key")
|
216
193
|
)
|
217
194
|
case ConnectionType.OAUTH2_AUTH_CODE:
|
218
|
-
custom_fields = _get_oauth_custom_fields(kwargs.get("token_entries"), kwargs.get("auth_entries"))
|
219
195
|
return OAuth2AuthCodeCredentials(
|
220
196
|
authorization_url=kwargs.get("auth_url"),
|
221
197
|
client_id=kwargs.get("client_id"),
|
222
198
|
client_secret=kwargs.get("client_secret"),
|
223
199
|
token_url=kwargs.get("token_url"),
|
224
|
-
scope=kwargs.get("scope")
|
225
|
-
**custom_fields
|
200
|
+
scope=kwargs.get("scope")
|
226
201
|
)
|
227
202
|
case ConnectionType.OAUTH2_CLIENT_CREDS:
|
228
203
|
# using filtered args as default values will not be set if 'None' is passed, causing validation errors
|
229
204
|
keys = ["client_id","client_secret","token_url","grant_type","send_via", "scope"]
|
230
205
|
filtered_args = { key_name: kwargs[key_name] for key_name in keys if kwargs.get(key_name) }
|
231
|
-
|
232
|
-
return OAuth2ClientCredentials(**filtered_args, **custom_fields)
|
206
|
+
return OAuth2ClientCredentials(**filtered_args)
|
233
207
|
# case ConnectionType.OAUTH2_IMPLICIT:
|
234
208
|
# return OAuth2ImplicitCredentials(
|
235
209
|
# authorization_url=kwargs.get("auth_url"),
|
@@ -238,16 +212,13 @@ def _get_credentials(type: ConnectionType, **kwargs):
|
|
238
212
|
case ConnectionType.OAUTH2_PASSWORD:
|
239
213
|
keys = ["username", "password", "client_id","client_secret","token_url","grant_type", "scope"]
|
240
214
|
filtered_args = { key_name: kwargs[key_name] for key_name in keys if kwargs.get(key_name) }
|
241
|
-
|
242
|
-
return OAuth2PasswordCredentials(**filtered_args, **custom_fields)
|
215
|
+
return OAuth2PasswordCredentials(**filtered_args)
|
243
216
|
|
244
217
|
case ConnectionType.OAUTH_ON_BEHALF_OF_FLOW:
|
245
|
-
custom_fields = _get_oauth_custom_fields(kwargs.get("token_entries"), kwargs.get("auth_entries"))
|
246
218
|
return OAuthOnBehalfOfCredentials(
|
247
219
|
client_id=kwargs.get("client_id"),
|
248
220
|
access_token_url=kwargs.get("token_url"),
|
249
|
-
grant_type=kwargs.get("grant_type")
|
250
|
-
**custom_fields
|
221
|
+
grant_type=kwargs.get("grant_type")
|
251
222
|
)
|
252
223
|
case ConnectionType.KEY_VALUE:
|
253
224
|
env = {}
|
@@ -260,23 +231,6 @@ def _get_credentials(type: ConnectionType, **kwargs):
|
|
260
231
|
case _:
|
261
232
|
raise ValueError(f"Invalid type '{type}' selected")
|
262
233
|
|
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
|
-
|
280
234
|
|
281
235
|
def add_configuration(config: ConnectionConfiguration) -> None:
|
282
236
|
client = get_connections_client()
|
@@ -570,15 +524,5 @@ def set_identity_provider_connection(
|
|
570
524
|
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.")
|
571
525
|
sys.exit(1)
|
572
526
|
|
573
|
-
|
574
|
-
idp = IdentityProviderCredentials(**kwargs, **custom_fields)
|
527
|
+
idp = IdentityProviderCredentials.model_validate(kwargs)
|
575
528
|
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,6 +191,9 @@ 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
|
+
|
194
197
|
registry_url = f"registry.{hostname[4:]}/cp/wxo-lite"
|
195
198
|
else:
|
196
199
|
raise ValueError(f"Unknown value for developer edition source: {source}. Must be one of ['internal', 'myibm', 'orchestrate'].")
|
@@ -1,6 +1,5 @@
|
|
1
1
|
import logging
|
2
2
|
import sys
|
3
|
-
import uuid
|
4
3
|
from enum import Enum
|
5
4
|
from pydantic import BaseModel, model_validator, ConfigDict
|
6
5
|
|
@@ -44,6 +43,9 @@ class WatsonXAIEnvConfig(BaseModel):
|
|
44
43
|
if not config.get("WATSONX_SPACE_ID") and not config.get("WATSONX_APIKEY"):
|
45
44
|
raise ValueError("Missing configuration requirements 'WATSONX_SPACE_ID' and 'WATSONX_APIKEY'")
|
46
45
|
|
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)
|
47
49
|
|
48
50
|
if not config.get("WATSONX_SPACE_ID") and config.get("WATSONX_APIKEY"):
|
49
51
|
logger.error("Cannot use env var 'WATSONX_APIKEY' without setting the corresponding 'WATSONX_SPACE_ID'")
|
@@ -52,12 +54,6 @@ class WatsonXAIEnvConfig(BaseModel):
|
|
52
54
|
config["USE_SAAS_ML_TOOLS_RUNTIME"] = False
|
53
55
|
return config
|
54
56
|
|
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
|
61
57
|
|
62
58
|
class ModelGatewayEnvConfig(BaseModel):
|
63
59
|
WO_API_KEY: str | None = None
|
@@ -88,10 +84,7 @@ class ModelGatewayEnvConfig(BaseModel):
|
|
88
84
|
if not config.get("AUTHORIZATION_URL"):
|
89
85
|
inferred_auth_url = AUTH_TYPE_DEFAULT_URL_MAPPING.get(auth_type)
|
90
86
|
if not inferred_auth_url:
|
91
|
-
|
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")
|
87
|
+
logger.error(f"No 'AUTHORIZATION_URL' found. Auth type '{auth_type}' does not support defaulting. Please set the 'AUTHORIZATION_URL' explictly")
|
95
88
|
sys.exit(1)
|
96
89
|
config["AUTHORIZATION_URL"] = inferred_auth_url
|
97
90
|
|
@@ -108,7 +101,6 @@ class ModelGatewayEnvConfig(BaseModel):
|
|
108
101
|
sys.exit(1)
|
109
102
|
|
110
103
|
config["USE_SAAS_ML_TOOLS_RUNTIME"] = True
|
111
|
-
|
112
|
-
|
113
|
-
config["WATSONX_SPACE_ID"] = "aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa"
|
104
|
+
# Fake (but valid) UUIDv4 for knowledgebase check
|
105
|
+
config["WATSONX_SPACE_ID"] = "aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa"
|
114
106
|
return config
|
@@ -62,7 +62,6 @@ 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}
|
66
65
|
|
67
66
|
wxo-agent-gateway:
|
68
67
|
image: ${AGENT_GATEWAY_REGISTRY:-us.icr.io/watson-orchestrate-private}/wxo-agent-gateway:${AGENT_GATEWAY_TAG:-latest}
|
@@ -328,7 +327,6 @@ services:
|
|
328
327
|
ENABLE_WEBHOOKS: false
|
329
328
|
DISABLE_JSON_LOG_CELERY: true
|
330
329
|
WXO_DEPLOYMENT_PLATFORM: saas
|
331
|
-
CPD_VERIFY: ${CPD_VERIFY}
|
332
330
|
CONNECTION_MANAGER_URL: http://wxo-server-connection-manager:3001
|
333
331
|
CHANNEL_SESSION_REDIS_URL: redis://wxo-server-redis:6379/5
|
334
332
|
WXO_MILVUS_URI: http://wxo-milvus-standalone:19530
|
@@ -448,7 +446,6 @@ services:
|
|
448
446
|
IBM_TELEMETRY_TRACER_ENDPOINT: http://jaeger:4318/v1/traces
|
449
447
|
USE_IBM_TELEMETRY: ${USE_IBM_TELEMETRY:-false}
|
450
448
|
WXO_DEPLOYMENT_PLATFORM: saas
|
451
|
-
CPD_VERIFY: ${CPD_VERIFY}
|
452
449
|
CALLBACK_HOST_URL: ${CALLBACK_HOST_URL:-http://wxo-server:4321}
|
453
450
|
LANGFLOW_ENABLED: ${LANGFLOW_ENABLED:-false}
|
454
451
|
|
@@ -656,7 +653,6 @@ services:
|
|
656
653
|
- WATSONX_URL=${WATSONX_URL}
|
657
654
|
- PROXY_SERVER_URL=http://jaeger-proxy:9201
|
658
655
|
- WXO_DEPLOYMENT_PLATFORM=saas
|
659
|
-
- CPD_VERIFY=${CPD_VERIFY}
|
660
656
|
- TENANT_API_KEY=${AGENTOPS_API_KEY}
|
661
657
|
- TENANT_CONFIG_URL=http://wxo-server:4321
|
662
658
|
- TENANT_DEFAULT_USERNAME=${ES_USERNAME}
|
@@ -92,7 +92,7 @@ TR_REGISTRY=
|
|
92
92
|
BUILDER_TAG=27-08-2025-7432aca
|
93
93
|
BUILDER_REGISTRY=
|
94
94
|
|
95
|
-
FLOW_RUNTIME_TAG=
|
95
|
+
FLOW_RUNTIME_TAG=18-08-2025-v3
|
96
96
|
FLOW_RUMTIME_REGISTRY=
|
97
97
|
|
98
98
|
|
@@ -126,8 +126,6 @@ DOCPROC_REGISTRY=
|
|
126
126
|
|
127
127
|
# END -- IMAGE REGISTRIES AND TAGS
|
128
128
|
|
129
|
-
CPD_VERIFY=true
|
130
|
-
AI_GATEWAY_TLS_REJECT_UNAUTHORIZED=1
|
131
129
|
TAVILY_API_KEY=dummy_tavily_api_key
|
132
130
|
PREFERRED_MODELS=meta-llama/llama-3-2-90b-vision-instruct,meta-llama/llama-3-405b-instruct
|
133
131
|
INCOMPATIBLE_MODELS=flan,embedding,cross-encoder,tinytimemixers
|
@@ -12,10 +12,7 @@ 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"] = []
|
16
|
-
for assignment in self.maps:
|
17
|
-
model_spec["maps"].append(assignment.model_dump())
|
18
|
-
return model_spec
|
15
|
+
model_spec["maps"] = [assignment.model_dump() for assignment in self.maps]
|
19
16
|
|
20
17
|
def add(self, line: Assignment) -> Self:
|
21
18
|
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,
|
28
|
+
DocProcKVPSchema, EndNodeSpec, Expression, ForeachPolicy, ForeachSpec, LoopSpec, BranchNodeSpec, MatchPolicy, PlainTextReadingOrder, 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:
|
67
|
+
output_map: DataMap | None = None
|
68
68
|
nodes: dict[str, SerializeAsAny[Node]] = {}
|
69
69
|
edges: List[FlowEdge] = []
|
70
70
|
schemas: dict[str, JsonSchemaObject] = {}
|
@@ -401,7 +401,6 @@ 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,
|
405
404
|
llm: str | None = None,
|
406
405
|
llm_parameters: PromptLLMParameters | None = None,
|
407
406
|
description: str | None = None,
|
@@ -423,7 +422,6 @@ class Flow(Node):
|
|
423
422
|
description=description,
|
424
423
|
system_prompt=system_prompt,
|
425
424
|
user_prompt=user_prompt,
|
426
|
-
prompt_examples=prompt_examples,
|
427
425
|
llm=llm,
|
428
426
|
llm_parameters=llm_parameters,
|
429
427
|
input_schema=_get_tool_request_body(input_schema_obj),
|
@@ -723,7 +721,7 @@ class Flow(Node):
|
|
723
721
|
'''Create a single node flow with an automatic START and END node.'''
|
724
722
|
return self.sequence(START, node, END)
|
725
723
|
|
726
|
-
def branch(self, evaluator: Union[Callable, Expression
|
724
|
+
def branch(self, evaluator: Union[Callable, Expression]) -> "Branch":
|
727
725
|
'''Create a BRANCH node'''
|
728
726
|
e = evaluator
|
729
727
|
if isinstance(evaluator, Callable):
|
@@ -737,19 +735,11 @@ class Flow(Node):
|
|
737
735
|
# e = new_script_spec
|
738
736
|
elif isinstance(evaluator, str):
|
739
737
|
e = Expression(expression=evaluator)
|
740
|
-
elif isinstance(evaluator, list):
|
741
|
-
e = Conditions(conditions=evaluator)
|
742
738
|
|
743
739
|
spec = BranchNodeSpec(name = "branch_" + str(self._next_sequence_id()), evaluator=e)
|
744
740
|
branch_node = Branch(spec = spec, containing_flow=self)
|
745
741
|
return cast(Branch, self._add_node(branch_node))
|
746
742
|
|
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
|
-
|
753
743
|
def wait_for(self, *args) -> "Wait":
|
754
744
|
'''Wait for all incoming nodes to complete.'''
|
755
745
|
raise ValueError("Not implemented yet.")
|
@@ -764,77 +754,6 @@ class Flow(Node):
|
|
764
754
|
|
765
755
|
# return cast(Wait, self.node(wait_node))
|
766
756
|
|
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
|
-
|
838
757
|
|
839
758
|
def foreach(self, item_schema: type[BaseModel],
|
840
759
|
input_schema: type[BaseModel] |None=None,
|
@@ -895,6 +814,8 @@ class Flow(Node):
|
|
895
814
|
input_schema: type[BaseModel] |None=None,
|
896
815
|
output_schema: type[BaseModel] |None=None) -> "UserFlow": # return a UserFlow object
|
897
816
|
|
817
|
+
raise ValueError("userflow is NOT supported yet and it's interface will change.")
|
818
|
+
|
898
819
|
output_schema_obj = _get_json_schema_obj("output", output_schema)
|
899
820
|
input_schema_obj = _get_json_schema_obj("input", input_schema)
|
900
821
|
|
@@ -996,11 +917,6 @@ class Flow(Node):
|
|
996
917
|
for key, value in self.metadata.items():
|
997
918
|
metadata_dict[key] = value
|
998
919
|
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
|
-
}
|
1004
920
|
return flow_dict
|
1005
921
|
|
1006
922
|
def _get_node_id(self, node: Union[str, Node]) -> str:
|
@@ -1310,27 +1226,6 @@ class Branch(FlowControl):
|
|
1310
1226
|
raise ValueError("Cannot have custom label __default__. Use default() instead.")
|
1311
1227
|
|
1312
1228
|
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
|
1334
1229
|
|
1335
1230
|
def default(self, node: Node) -> Self:
|
1336
1231
|
'''
|
@@ -1550,14 +1445,13 @@ class UserFlow(Flow):
|
|
1550
1445
|
kind: UserFieldKind = UserFieldKind.Text,
|
1551
1446
|
display_name: str | None = None,
|
1552
1447
|
description: str | None = None,
|
1553
|
-
direction: str | None = None,
|
1554
1448
|
default: Any | None = None,
|
1555
1449
|
text: str = None, # The text used to ask question to the user, e.g. 'what is your name?'
|
1556
1450
|
option: UserFieldOption | None = None,
|
1557
1451
|
is_list: bool = False,
|
1558
1452
|
min: Any | None = None,
|
1559
1453
|
max: Any | None = None,
|
1560
|
-
input_map: DataMap
|
1454
|
+
input_map: DataMap = None,
|
1561
1455
|
custom: dict[str, Any] = {}) -> UserNode:
|
1562
1456
|
'''create a node in the flow'''
|
1563
1457
|
# create a json schema object based on the single field
|
@@ -1589,8 +1483,6 @@ class UserFlow(Flow):
|
|
1589
1483
|
description = description,
|
1590
1484
|
default = default,
|
1591
1485
|
text = text,
|
1592
|
-
direction = direction,
|
1593
|
-
input_map = input_map,
|
1594
1486
|
option = option,
|
1595
1487
|
is_list = is_list,
|
1596
1488
|
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
|
9
|
+
from .types import 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:
|
16
|
+
input_map: DataMap | None = None
|
17
17
|
|
18
18
|
def __call__(self, **kwargs):
|
19
19
|
pass
|
@@ -40,77 +40,10 @@ 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'] =
|
45
|
-
"spec": self.input_map["spec"].to_json()
|
46
|
-
}
|
43
|
+
if self.input_map is not None:
|
44
|
+
model_spec['input_map'] = self.input_map.to_json()
|
47
45
|
|
48
46
|
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}
|
114
47
|
|
115
48
|
class StartNode(Node):
|
116
49
|
def __repr__(self):
|
@@ -150,8 +83,6 @@ class UserNode(Node):
|
|
150
83
|
option: UserFieldOption | None = None,
|
151
84
|
min: Any | None = None,
|
152
85
|
max: Any | None = None,
|
153
|
-
direction: str | None = None,
|
154
|
-
input_map: DataMap | None = None,
|
155
86
|
is_list: bool = False,
|
156
87
|
custom: dict[str, Any] | None = None,
|
157
88
|
widget: str | None = None):
|
@@ -166,9 +97,7 @@ class UserNode(Node):
|
|
166
97
|
max=max,
|
167
98
|
is_list=is_list,
|
168
99
|
custom=custom,
|
169
|
-
widget=widget
|
170
|
-
direction=direction,
|
171
|
-
input_map=input_map)
|
100
|
+
widget=widget)
|
172
101
|
|
173
102
|
class AgentNode(Node):
|
174
103
|
def __repr__(self):
|
@@ -28,7 +28,6 @@ from ibm_watsonx_orchestrate.agent_builder.tools.types import (
|
|
28
28
|
)
|
29
29
|
from .utils import get_valid_name
|
30
30
|
|
31
|
-
|
32
31
|
logger = logging.getLogger(__name__)
|
33
32
|
|
34
33
|
class JsonSchemaObjectRef(JsonSchemaObject):
|
@@ -361,6 +360,7 @@ class EndNodeSpec(NodeSpec):
|
|
361
360
|
def __init__(self, **data):
|
362
361
|
super().__init__(**data)
|
363
362
|
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,10 +421,9 @@ class UserFieldKind(str, Enum):
|
|
421
421
|
DateTime: str = "datetime"
|
422
422
|
Time: str = "time"
|
423
423
|
Number: str = "number"
|
424
|
-
|
424
|
+
Document: str = "document"
|
425
425
|
Boolean: str = "boolean"
|
426
426
|
Object: str = "object"
|
427
|
-
Choice: str = "any"
|
428
427
|
|
429
428
|
def convert_python_type_to_kind(python_type: type) -> "UserFieldKind":
|
430
429
|
if inspect.isclass(python_type):
|
@@ -464,8 +463,8 @@ class UserFieldKind(str, Enum):
|
|
464
463
|
model_spec["format"] = "number"
|
465
464
|
elif kind == UserFieldKind.Boolean:
|
466
465
|
model_spec["type"] = "boolean"
|
467
|
-
elif kind == UserFieldKind.
|
468
|
-
model_spec["format"] = "
|
466
|
+
elif kind == UserFieldKind.Document:
|
467
|
+
model_spec["format"] = "uri"
|
469
468
|
elif kind == UserFieldKind.Object:
|
470
469
|
raise ValueError("Object user fields are not supported.")
|
471
470
|
|
@@ -484,8 +483,6 @@ class UserField(BaseModel):
|
|
484
483
|
text: str | None = Field(default=None, description="A descriptive text that can be used to ask user about this field.")
|
485
484
|
display_name: str | None = None
|
486
485
|
description: str | None = None
|
487
|
-
direction: str | None = None
|
488
|
-
input_map: Any | None = None,
|
489
486
|
default: Any | None = None
|
490
487
|
option: UserFieldOption | None = None
|
491
488
|
min: Any | None = None,
|
@@ -500,15 +497,6 @@ class UserField(BaseModel):
|
|
500
497
|
model_spec["name"] = self.name
|
501
498
|
if self.kind:
|
502
499
|
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()}
|
512
500
|
if self.text:
|
513
501
|
model_spec["text"] = self.text
|
514
502
|
if self.display_name:
|
@@ -568,15 +556,7 @@ class UserNodeSpec(NodeSpec):
|
|
568
556
|
max: Any | None = None,
|
569
557
|
is_list: bool = False,
|
570
558
|
custom: dict[str, Any] | 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
|
-
|
559
|
+
widget: str | None = None):
|
580
560
|
userfield = UserField(name=name,
|
581
561
|
kind=kind,
|
582
562
|
text=text,
|
@@ -588,9 +568,7 @@ class UserNodeSpec(NodeSpec):
|
|
588
568
|
max=max,
|
589
569
|
is_list=is_list,
|
590
570
|
custom=custom,
|
591
|
-
widget=widget
|
592
|
-
direction=direction,
|
593
|
-
input_map=input_map)
|
571
|
+
widget=widget)
|
594
572
|
|
595
573
|
# find the index of the field
|
596
574
|
i = 0
|
@@ -682,28 +660,11 @@ class PromptLLMParameters(BaseModel):
|
|
682
660
|
if self.stop_sequences:
|
683
661
|
model_spec["stop_sequences"] = self.stop_sequences
|
684
662
|
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
|
-
|
701
663
|
|
702
664
|
|
703
665
|
class PromptNodeSpec(NodeSpec):
|
704
666
|
system_prompt: str | list[str]
|
705
667
|
user_prompt: str | list[str]
|
706
|
-
prompt_examples: Optional[list[PromptExample]]
|
707
668
|
llm: Optional[str]
|
708
669
|
llm_parameters: Optional[PromptLLMParameters]
|
709
670
|
|
@@ -721,10 +682,7 @@ class PromptNodeSpec(NodeSpec):
|
|
721
682
|
model_spec["llm"] = self.llm
|
722
683
|
if self.llm_parameters:
|
723
684
|
model_spec["llm_parameters"] = self.llm_parameters.to_json()
|
724
|
-
|
725
|
-
model_spec["prompt_examples"] = []
|
726
|
-
for example in self.prompt_examples:
|
727
|
-
model_spec["prompt_examples"].append(example.to_json())
|
685
|
+
|
728
686
|
return model_spec
|
729
687
|
|
730
688
|
class TimerNodeSpec(NodeSpec):
|
@@ -749,47 +707,6 @@ class Expression(BaseModel):
|
|
749
707
|
model_spec["expression"] = self.expression;
|
750
708
|
return model_spec
|
751
709
|
|
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
|
-
|
793
710
|
class MatchPolicy(Enum):
|
794
711
|
|
795
712
|
FIRST_MATCH = 1
|
@@ -807,7 +724,7 @@ class BranchNodeSpec(FlowControlNodeSpec):
|
|
807
724
|
cases (dict[str | bool, str]): A dictionary of labels to node names. The keys can be strings or booleans.
|
808
725
|
match_policy (MatchPolicy): The policy to use when evaluating the expression.
|
809
726
|
'''
|
810
|
-
evaluator: Expression
|
727
|
+
evaluator: Expression
|
811
728
|
cases: dict[str | bool, str] = Field(default = {},
|
812
729
|
description="A dictionary of labels to node names.")
|
813
730
|
match_policy: MatchPolicy = Field(default = MatchPolicy.FIRST_MATCH)
|
@@ -891,7 +808,7 @@ class UserFlowSpec(FlowSpec):
|
|
891
808
|
|
892
809
|
def __init__(self, **kwargs):
|
893
810
|
super().__init__(**kwargs)
|
894
|
-
self.kind = "
|
811
|
+
self.kind = "userflow"
|
895
812
|
|
896
813
|
def to_json(self) -> dict[str, Any]:
|
897
814
|
model_spec = super().to_json()
|
{ibm_watsonx_orchestrate-1.10.1.dist-info → ibm_watsonx_orchestrate-1.10.2.dist-info}/RECORD
RENAMED
@@ -1,4 +1,4 @@
|
|
1
|
-
ibm_watsonx_orchestrate/__init__.py,sha256=
|
1
|
+
ibm_watsonx_orchestrate/__init__.py,sha256=Yw6V_GiiZzezrqa6CMFIeF1aBRVLiIyWocIwdhygDf8,425
|
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
|
@@ -10,7 +10,7 @@ ibm_watsonx_orchestrate/agent_builder/agents/webchat_customizations/prompts.py,s
|
|
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
12
|
ibm_watsonx_orchestrate/agent_builder/connections/connections.py,sha256=ozRTZ1Y10YbipE6oegI8QIP31fWqUaBUFoHAo-WTY3g,5547
|
13
|
-
ibm_watsonx_orchestrate/agent_builder/connections/types.py,sha256=
|
13
|
+
ibm_watsonx_orchestrate/agent_builder/connections/types.py,sha256=OGuFEQhc1dj8GVjHuT_V3coCC_YtBGqQ68qGy96m6EQ,9587
|
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=bYn9Z4DDDdoaAYkUddgrQas8H7h7h7hbO4fle5Ovdmo,10688
|
46
|
+
ibm_watsonx_orchestrate/cli/commands/connections/connections_controller.py,sha256=XpcJBAzJHczZcJttH7kzfIgZUidj_aW86mmQ5qk_T8c,23367
|
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=RBGH3ssDDhrcvmGpvpVtvqpWIhJm_odH4kqf4UQMRrI,46669
|
62
|
+
ibm_watsonx_orchestrate/cli/commands/server/types.py,sha256=UCrgGErbSVBnOzesfjrIii4tTCuVfWemYz5AKGZX0oA,4213
|
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=wylLRS6iGEfMitfoXuT2tVuSiWej0HLAE5k-6Onl-kI,45671
|
105
|
+
ibm_watsonx_orchestrate/docker/default.env,sha256=3YsCo8vWsI0jte2d86OOWegFB37WGT_xWnRoZjvabfQ,6235
|
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=1brmWWFERDsNG2XGais-5-r58LKUUwBtqwdaLQIFRhE,503
|
113
|
+
ibm_watsonx_orchestrate/flow_builder/node.py,sha256=2b4BL64tt1isvA5O_uFvXZG5qqvDYrAVSYyeW6wyk0U,6978
|
114
|
+
ibm_watsonx_orchestrate/flow_builder/types.py,sha256=ohtfMFneFtK7KOEEEdYpD5hmiRwfyTnkHLkOr4zNhGs,47611
|
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=P-MazfKiQr8BLiFAqOxqKlFHM2KyY7Dgp8O6xdCxIjk,60388
|
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.2.dist-info/METADATA,sha256=VMkkqqfSLDuOKILngVu8E37vHUNobCf5dk73Fc4Smdc,1361
|
130
|
+
ibm_watsonx_orchestrate-1.10.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
131
|
+
ibm_watsonx_orchestrate-1.10.2.dist-info/entry_points.txt,sha256=SfIT02-Jen5e99OcLhzbcM9Bdyf8SGVOCtnSplgZdQI,69
|
132
|
+
ibm_watsonx_orchestrate-1.10.2.dist-info/licenses/LICENSE,sha256=Shgxx7hTdCOkiVRmfGgp_1ISISrwQD7m2f0y8Hsapl4,1083
|
133
|
+
ibm_watsonx_orchestrate-1.10.2.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|