ibm-watsonx-orchestrate 1.6.0b0__py3-none-any.whl → 1.7.0a0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. ibm_watsonx_orchestrate/__init__.py +1 -1
  2. ibm_watsonx_orchestrate/agent_builder/agents/agent.py +1 -0
  3. ibm_watsonx_orchestrate/agent_builder/agents/types.py +5 -1
  4. ibm_watsonx_orchestrate/agent_builder/agents/webchat_customizations/__init__.py +2 -0
  5. ibm_watsonx_orchestrate/agent_builder/agents/webchat_customizations/prompts.py +33 -0
  6. ibm_watsonx_orchestrate/agent_builder/agents/webchat_customizations/welcome_content.py +20 -0
  7. ibm_watsonx_orchestrate/agent_builder/connections/__init__.py +2 -2
  8. ibm_watsonx_orchestrate/agent_builder/connections/types.py +38 -31
  9. ibm_watsonx_orchestrate/agent_builder/tools/flow_tool.py +83 -0
  10. ibm_watsonx_orchestrate/agent_builder/tools/types.py +7 -1
  11. ibm_watsonx_orchestrate/cli/commands/agents/agents_controller.py +25 -14
  12. ibm_watsonx_orchestrate/cli/commands/channels/webchat/channels_webchat_controller.py +104 -21
  13. ibm_watsonx_orchestrate/cli/commands/connections/connections_command.py +26 -18
  14. ibm_watsonx_orchestrate/cli/commands/connections/connections_controller.py +55 -57
  15. ibm_watsonx_orchestrate/cli/commands/knowledge_bases/knowledge_bases_controller.py +2 -2
  16. ibm_watsonx_orchestrate/cli/commands/server/server_command.py +137 -10
  17. ibm_watsonx_orchestrate/cli/commands/toolkit/toolkit_controller.py +9 -3
  18. ibm_watsonx_orchestrate/cli/commands/tools/tools_controller.py +25 -12
  19. ibm_watsonx_orchestrate/client/agents/agent_client.py +74 -6
  20. ibm_watsonx_orchestrate/client/base_api_client.py +2 -1
  21. ibm_watsonx_orchestrate/client/connections/connections_client.py +18 -9
  22. ibm_watsonx_orchestrate/client/connections/utils.py +4 -2
  23. ibm_watsonx_orchestrate/client/local_service_instance.py +1 -1
  24. ibm_watsonx_orchestrate/client/service_instance.py +3 -3
  25. ibm_watsonx_orchestrate/client/tools/tempus_client.py +8 -3
  26. ibm_watsonx_orchestrate/client/utils.py +10 -0
  27. ibm_watsonx_orchestrate/docker/compose-lite.yml +400 -66
  28. ibm_watsonx_orchestrate/docker/default.env +44 -12
  29. ibm_watsonx_orchestrate/docker/proxy-config-single.yaml +12 -0
  30. ibm_watsonx_orchestrate/flow_builder/flows/flow.py +15 -5
  31. ibm_watsonx_orchestrate/flow_builder/utils.py +78 -48
  32. ibm_watsonx_orchestrate/run/connections.py +4 -4
  33. {ibm_watsonx_orchestrate-1.6.0b0.dist-info → ibm_watsonx_orchestrate-1.7.0a0.dist-info}/METADATA +1 -1
  34. {ibm_watsonx_orchestrate-1.6.0b0.dist-info → ibm_watsonx_orchestrate-1.7.0a0.dist-info}/RECORD +37 -32
  35. {ibm_watsonx_orchestrate-1.6.0b0.dist-info → ibm_watsonx_orchestrate-1.7.0a0.dist-info}/WHEEL +0 -0
  36. {ibm_watsonx_orchestrate-1.6.0b0.dist-info → ibm_watsonx_orchestrate-1.7.0a0.dist-info}/entry_points.txt +0 -0
  37. {ibm_watsonx_orchestrate-1.6.0b0.dist-info → ibm_watsonx_orchestrate-1.7.0a0.dist-info}/licenses/LICENSE +0 -0
@@ -1,9 +1,10 @@
1
1
  import logging
2
2
  import rich
3
3
  import jwt
4
+ import sys
4
5
 
5
6
  from ibm_watsonx_orchestrate.cli.config import Config, ENV_WXO_URL_OPT, ENVIRONMENTS_SECTION_HEADER, CONTEXT_SECTION_HEADER, CONTEXT_ACTIVE_ENV_OPT, CHAT_UI_PORT
6
- from ibm_watsonx_orchestrate.client.utils import is_local_dev, AUTH_CONFIG_FILE_FOLDER, AUTH_SECTION_HEADER, AUTH_MCSP_TOKEN_OPT, AUTH_CONFIG_FILE
7
+ from ibm_watsonx_orchestrate.client.utils import is_local_dev, is_ibm_cloud, AUTH_CONFIG_FILE_FOLDER, AUTH_SECTION_HEADER, AUTH_MCSP_TOKEN_OPT, AUTH_CONFIG_FILE
7
8
 
8
9
  from ibm_watsonx_orchestrate.client.agents.agent_client import AgentClient
9
10
 
@@ -19,7 +20,41 @@ class ChannelsWebchatController:
19
20
  def get_native_client(self):
20
21
  self.native_client = instantiate_client(AgentClient)
21
22
  return self.native_client
22
-
23
+
24
+ def extract_tenant_id_from_crn(self, crn: str) -> str:
25
+ is_ibm_cloud_env = is_ibm_cloud()
26
+ if is_ibm_cloud_env:
27
+ try:
28
+ parts = crn.split("a/")[1].split(":")
29
+ account_part = parts[0]
30
+ instance_part = parts[1]
31
+ tenant_id = f"{account_part}_{instance_part}"
32
+ return tenant_id
33
+ except (IndexError, AttributeError):
34
+ raise ValueError(f"Invalid CRN format: {crn}")
35
+ else:
36
+ try:
37
+ parts = crn.split("sub/")[1].split(":")
38
+ account_part = parts[0]
39
+ instance_part = parts[1]
40
+ tenant_id = f"{account_part}_{instance_part}"
41
+ return tenant_id
42
+ except (IndexError, AttributeError):
43
+ raise ValueError(f"Invalid CRN format: {crn}")
44
+
45
+
46
+
47
+ def check_crn_is_correct(self, crn: str):
48
+ parts = crn.split("a/")[1].split(":")
49
+ instance_part_crn = parts[1]
50
+ cfg = Config()
51
+ active_env = cfg.read(CONTEXT_SECTION_HEADER, CONTEXT_ACTIVE_ENV_OPT)
52
+ url = cfg.get(ENVIRONMENTS_SECTION_HEADER, active_env, ENV_WXO_URL_OPT)
53
+ instance_part_url = url.rstrip("/").split("/")[-1]
54
+ if instance_part_crn == instance_part_url:
55
+ return True
56
+ else:
57
+ return False
23
58
 
24
59
  def get_agent_id(self, agent_name: str):
25
60
  native_client = self.get_native_client()
@@ -39,7 +74,7 @@ class ChannelsWebchatController:
39
74
  raise ValueError(f"No agent found with the name '{agent_name}'")
40
75
 
41
76
  agent = existing_native_agents[0]
42
- agent_environments = agent.get("environments", [])
77
+ agent_environments = agent.get("environments", [])
43
78
 
44
79
  is_local = is_local_dev()
45
80
  target_env = env or 'draft'
@@ -56,15 +91,37 @@ class ChannelsWebchatController:
56
91
  logger.error(f'This agent does not exist in the {env} environment. You need to deploy it to {env} before you can embed the agent')
57
92
  exit(1)
58
93
 
59
- return filtered_environments[0].get("id")
94
+ if target_env == 'draft' and is_local == False:
95
+ logger.error(f'For SAAS, please ensure this agent exists in a Live Environment')
96
+ exit(1)
97
+
60
98
 
61
99
 
100
+ return filtered_environments[0].get("id")
101
+
62
102
  def get_tennent_id(self):
63
103
  auth_cfg = Config(AUTH_CONFIG_FILE_FOLDER, AUTH_CONFIG_FILE)
64
104
 
65
105
  cfg = Config()
66
106
  active_env = cfg.read(CONTEXT_SECTION_HEADER, CONTEXT_ACTIVE_ENV_OPT)
67
- is_local = is_local_dev()
107
+
108
+ existing_auth_config = auth_cfg.get(AUTH_SECTION_HEADER).get(active_env, {})
109
+
110
+ existing_token = existing_auth_config.get(AUTH_MCSP_TOKEN_OPT) if existing_auth_config else None
111
+ token = jwt.decode(existing_token, options={"verify_signature": False})
112
+ crn = ""
113
+ crn = token.get('aud', None)
114
+
115
+ tenant_id = self.extract_tenant_id_from_crn(crn)
116
+ return tenant_id
117
+
118
+
119
+
120
+ def get_tenant_id_local(self):
121
+ auth_cfg = Config(AUTH_CONFIG_FILE_FOLDER, AUTH_CONFIG_FILE)
122
+
123
+ cfg = Config()
124
+ active_env = cfg.read(CONTEXT_SECTION_HEADER, CONTEXT_ACTIVE_ENV_OPT)
68
125
 
69
126
  existing_auth_config = auth_cfg.get(AUTH_SECTION_HEADER).get(active_env, {})
70
127
 
@@ -72,10 +129,7 @@ class ChannelsWebchatController:
72
129
 
73
130
  token = jwt.decode(existing_token, options={"verify_signature": False})
74
131
  tenant_id = ""
75
- if is_local:
76
- tenant_id = token.get('woTenantId', None)
77
- else:
78
- tenant_id = token.get('tenantId', None)
132
+ tenant_id = token.get('woTenantId', None)
79
133
 
80
134
  return tenant_id
81
135
 
@@ -99,41 +153,70 @@ class ChannelsWebchatController:
99
153
 
100
154
 
101
155
  def create_webchat_embed_code(self):
102
- tenant_id = self.get_tennent_id()
156
+ crn = None
157
+ is_ibm_cloud_env = is_ibm_cloud()
158
+ is_local = is_local_dev()
159
+ if is_ibm_cloud_env is True:
160
+ crn = input("Please enter your CRN which can be gotten from the IBM Cloud UI: ")
161
+ if crn == "":
162
+ logger.error("You must enter your CRN for IBM Cloud instances")
163
+ sys.exit(1)
164
+ is_crn_correct = self.check_crn_is_correct(crn)
165
+ if is_crn_correct == False:
166
+ logger.error("Invalid CRN format provided.")
167
+
168
+ if is_ibm_cloud_env and crn is not None:
169
+ tenant_id = self.extract_tenant_id_from_crn(crn)
170
+ elif is_ibm_cloud_env is False and is_local is False:
171
+ tenant_id = self.get_tennent_id()
172
+ elif is_local:
173
+ tenant_id = self.get_tenant_id_local()
103
174
  host_url = self.get_host_url()
104
175
  agent_id = self.get_agent_id(self.agent_name)
105
176
  agent_env_id = self.get_environment_id(self.agent_name, self.env)
106
177
 
107
- is_local = is_local_dev()
108
178
  script_path = (
109
179
  "/wxoLoader.js?embed=true"
110
180
  if is_local
111
181
  else "/wxochat/wxoLoader.js?embed=true"
112
182
  )
113
183
 
184
+ config_lines = [
185
+ f'orchestrationID: "{tenant_id}"',
186
+ f'hostURL: "{host_url}"',
187
+ 'rootElementID: "root"',
188
+ 'showLauncher: true',
189
+ ]
190
+
191
+ # Conditional fields for IBM Cloud
192
+ if is_ibm_cloud_env:
193
+ config_lines.append(f'crn: "{crn}"')
194
+ if is_ibm_cloud_env:
195
+ config_lines.append(f'deploymentPlatform: "ibmcloud"')
196
+
197
+ config_lines.append(f"""chatOptions: {{
198
+ agentId: "{agent_id}",
199
+ agentEnvironmentId: "{agent_env_id}"
200
+ }}""")
201
+
202
+ config_body = ",\n ".join(config_lines)
203
+
114
204
  script = f"""
115
205
  <script>
116
206
  window.wxOConfiguration = {{
117
- orchestrationID: "{tenant_id}",
118
- hostURL: "{host_url}",
119
- rootElementID: "root",
120
- showLauncher: true,
121
- chatOptions: {{
122
- agentId: "{agent_id}",
123
- agentEnvironmentId: "{agent_env_id}"
124
- }},
207
+ {config_body}
125
208
  }};
126
209
 
127
210
  setTimeout(function () {{
128
211
  const script = document.createElement('script');
129
212
  script.src = `${{window.wxOConfiguration.hostURL}}{script_path}`;
130
213
  script.addEventListener('load', function () {{
131
- wxoLoader.init();
214
+ wxoLoader.init();
132
215
  }});
133
216
  document.head.appendChild(script);
134
217
  }}, 0);
135
218
  </script>
136
- """
219
+ """
137
220
 
138
221
  rich.print(script)
139
222
  return script
@@ -191,31 +191,31 @@ def set_credentials_connection_command(
191
191
  typer.Option(
192
192
  '--client-id',
193
193
  # help='For oauth_auth_on_behalf_of_flow, oauth_auth_code_flow, oauth_auth_implicit_flow, oauth_auth_password_flow and oauth_auth_client_credentials_flow, the client_id to authenticate against the application token server'
194
- help='For oauth_auth_on_behalf_of_flow, the client_id to authenticate against the application token server'
194
+ help='For oauth_auth_on_behalf_of_flow and oauth_auth_client_credentials_flow, the client_id to authenticate against the application token server'
195
+ )
196
+ ] = None,
197
+ client_secret: Annotated[
198
+ str,
199
+ typer.Option(
200
+ '--client-secret',
201
+ help='For oauth_auth_client_credentials_flow, the client_secret to authenticate with'
195
202
  )
196
203
  ] = None,
197
- # client_secret: Annotated[
198
- # str,
199
- # typer.Option(
200
- # '--client-secret',
201
- # help='For oauth_auth_code_flow, oauth_auth_password_flow and oauth_auth_client_credentials_flow, the client_secret to authenticate with'
202
- # )
203
- # ] = None,
204
204
  token_url: Annotated[
205
205
  str,
206
206
  typer.Option(
207
207
  '--token-url',
208
208
  # help='For oauth_auth_on_behalf_of_flow, oauth_auth_code_flow, oauth_auth_password_flow and oauth_auth_client_credentials_flow, the url of the application token server'
209
- help='For oauth_auth_on_behalf_of_flow, the url of the application token server'
209
+ help='For oauth_auth_on_behalf_of_flow and oauth_auth_client_credentials_flow, the url of the application token server'
210
+ )
211
+ ] = None,
212
+ auth_url: Annotated[
213
+ str,
214
+ typer.Option(
215
+ '--auth-url',
216
+ help='For oauth_auth_code_flow, the url of the application token server'
210
217
  )
211
218
  ] = None,
212
- # auth_url: Annotated[
213
- # str,
214
- # typer.Option(
215
- # '--auth-url',
216
- # help='For oauth_auth_code_flow, oauth_auth_implicit_flow and oauth_auth_password_flow, the url of the application token server'
217
- # )
218
- # ] = None,
219
219
  grant_type: Annotated[
220
220
  str,
221
221
  typer.Option(
@@ -223,6 +223,13 @@ def set_credentials_connection_command(
223
223
  help='For oauth_auth_on_behalf_of_flow, the grant type used by the application token server'
224
224
  )
225
225
  ] = None,
226
+ scopes: Annotated[
227
+ List[str],
228
+ typer.Option(
229
+ '--scopes',
230
+ help='For oauth_auth_code_flow and oauth_auth_client_credentials_flow, the optional scopes used by the application token server'
231
+ )
232
+ ] = None,
226
233
  entries: Annotated[
227
234
  List[str],
228
235
  typer.Option(
@@ -239,10 +246,11 @@ def set_credentials_connection_command(
239
246
  token=token,
240
247
  api_key=api_key,
241
248
  client_id=client_id,
242
- # client_secret=client_secret,
249
+ client_secret=client_secret,
243
250
  token_url=token_url,
244
- # auth_url=auth_url,
251
+ auth_url=auth_url,
245
252
  grant_type=grant_type,
253
+ scopes=scopes,
246
254
  entries=entries
247
255
  )
248
256
 
@@ -15,19 +15,19 @@ from ibm_watsonx_orchestrate.agent_builder.connections.types import (
15
15
  ConnectionType,
16
16
  IdpConfigData,
17
17
  IdpConfigDataBody,
18
- AppConfigData,
18
+ AppConfigData,
19
19
  BasicAuthCredentials,
20
20
  BearerTokenAuthCredentials,
21
21
  APIKeyAuthCredentials,
22
22
  # OAuth2AuthCodeCredentials,
23
- # OAuth2ClientCredentials,
23
+ OAuth2ClientCredentials,
24
24
  # OAuth2ImplicitCredentials,
25
25
  # OAuth2PasswordCredentials,
26
26
  OAuthOnBehalfOfCredentials,
27
27
  KeyValueConnectionCredentials,
28
28
  CREDENTIALS,
29
29
  IdentityProviderCredentials,
30
- OAUTH_CONNECTION_TYPES
30
+ OAUTH_CONNECTION_TYPES, OAuth2AuthCodeCredentials
31
31
 
32
32
  )
33
33
 
@@ -136,40 +136,31 @@ def _validate_connection_params(type: ConnectionType, **args) -> None:
136
136
  f"Missing flags --api-key is required for type {type}"
137
137
  )
138
138
 
139
- # if type in OAUTH_CONNECTION_TYPES and args.get('client_id') is None:
140
- # raise typer.BadParameter(
141
- # f"Missing flags --client-id is required for type {type}"
142
- # )
143
-
144
- # if type in (OAUTH_CONNECTION_TYPES.difference({ConnectionType.OAUTH2_IMPLICIT, ConnectionType.OAUTH_ON_BEHALF_OF_FLOW})) and args.get('client_secret') is None:
145
- # raise typer.BadParameter(
146
- # f"Missing flags --client-secret is required for type {type}"
147
- # )
148
-
149
- # if type in (OAUTH_CONNECTION_TYPES.difference({ConnectionType.OAUTH2_IMPLICIT})) and args.get('token_url') is None:
150
- # raise typer.BadParameter(
151
- # f"Missing flags --token-url is required for type {type}"
152
- # )
139
+ if type in {ConnectionType.OAUTH2_CLIENT_CREDS, ConnectionType.OAUTH2_AUTH_CODE} and args.get('client_secret') is None:
140
+ raise typer.BadParameter(
141
+ f"Missing flags --client-secret is required for type {type}"
142
+ )
153
143
 
154
- # if type in (OAUTH_CONNECTION_TYPES.difference({ConnectionType.OAUTH2_CLIENT_CREDS, ConnectionType.OAUTH_ON_BEHALF_OF_FLOW})) and args.get('auth_url') is None:
155
- # raise typer.BadParameter(
156
- # f"Missing flags --auth-url is required for type {type}"
157
- # )
144
+ if type in {ConnectionType.OAUTH2_AUTH_CODE} and args.get('auth_url') is None:
145
+ raise typer.BadParameter(
146
+ f"Missing flags --auth-url is required for type {type}"
147
+ )
158
148
 
159
- if type == ConnectionType.OAUTH_ON_BEHALF_OF_FLOW and (
149
+ if type in {ConnectionType.OAUTH_ON_BEHALF_OF_FLOW, ConnectionType.OAUTH2_CLIENT_CREDS, ConnectionType.OAUTH2_AUTH_CODE} and (
160
150
  args.get('client_id') is None
161
151
  ):
162
152
  raise typer.BadParameter(
163
153
  f"Missing flags --client-id is required for type {type}"
164
154
  )
165
155
 
166
- if type == ConnectionType.OAUTH_ON_BEHALF_OF_FLOW and (
156
+ if type in {ConnectionType.OAUTH_ON_BEHALF_OF_FLOW, ConnectionType.OAUTH2_CLIENT_CREDS, ConnectionType.OAUTH2_AUTH_CODE} and (
167
157
  args.get('token_url') is None
168
158
  ):
169
159
  raise typer.BadParameter(
170
160
  f"Missing flags --token-url is required for type {type}"
171
161
  )
172
162
 
163
+
173
164
  if type == ConnectionType.OAUTH_ON_BEHALF_OF_FLOW and (
174
165
  args.get('grant_type') is None
175
166
  ):
@@ -200,19 +191,21 @@ def _get_credentials(type: ConnectionType, **kwargs):
200
191
  return APIKeyAuthCredentials(
201
192
  api_key=kwargs.get("api_key")
202
193
  )
203
- # case ConnectionType.OAUTH2_AUTH_CODE:
204
- # return OAuth2AuthCodeCredentials(
205
- # authorization_url=kwargs.get("auth_url"),
206
- # client_id=kwargs.get("client_id"),
207
- # client_secret=kwargs.get("client_secret"),
208
- # token_url=kwargs.get("token_url")
209
- # )
210
- # case ConnectionType.OAUTH2_CLIENT_CREDS:
211
- # return OAuth2ClientCredentials(
212
- # client_id=kwargs.get("client_id"),
213
- # client_secret=kwargs.get("client_secret"),
214
- # token_url=kwargs.get("token_url")
215
- # )
194
+ case ConnectionType.OAUTH2_AUTH_CODE:
195
+ return OAuth2AuthCodeCredentials(
196
+ authorization_url=kwargs.get("auth_url"),
197
+ client_id=kwargs.get("client_id"),
198
+ client_secret=kwargs.get("client_secret"),
199
+ token_url=kwargs.get("token_url"),
200
+ scopes=kwargs.get("scopes")
201
+ )
202
+ case ConnectionType.OAUTH2_CLIENT_CREDS:
203
+ return OAuth2ClientCredentials(
204
+ client_id=kwargs.get("client_id"),
205
+ client_secret=kwargs.get("client_secret"),
206
+ token_url=kwargs.get("token_url"),
207
+ scopes=kwargs.get("scopes")
208
+ )
216
209
  # case ConnectionType.OAUTH2_IMPLICIT:
217
210
  # return OAuth2ImplicitCredentials(
218
211
  # authorization_url=kwargs.get("auth_url"),
@@ -267,11 +260,14 @@ def add_configuration(config: ConnectionConfiguration) -> None:
267
260
  logger.warning(f"Detected a change in sso from '{existing_configuration.sso}' to '{config.sso}'. The associated credentials will be removed.")
268
261
  should_delete_credentials = True
269
262
 
263
+ existing_conn_type = get_connection_type(security_scheme=existing_configuration.security_scheme, auth_type=existing_configuration.auth_type)
264
+ use_app_credentials = existing_conn_type in OAUTH_CONNECTION_TYPES
265
+
270
266
  if should_delete_credentials:
271
267
  try:
272
- existing_credentials = client.get_credentials(app_id=app_id, env=environment, use_sso=existing_configuration.sso)
268
+ existing_credentials = client.get_credentials(app_id=app_id, env=environment, use_app_credentials=use_app_credentials)
273
269
  if existing_credentials:
274
- client.delete_credentials(app_id=app_id, env=environment, use_sso=existing_configuration.sso)
270
+ client.delete_credentials(app_id=app_id, env=environment, use_app_credentials=use_app_credentials)
275
271
  except:
276
272
  logger.error(f"Error removing credentials for connection '{app_id}' in environment '{environment}'. No changes have been made to the configuration.")
277
273
  sys.exit(1)
@@ -289,11 +285,11 @@ def add_configuration(config: ConnectionConfiguration) -> None:
289
285
  logger.error(response_text)
290
286
  exit(1)
291
287
 
292
- def add_credentials(app_id: str, environment: ConnectionEnvironment, use_sso: bool, credentials: CREDENTIALS) -> None:
288
+ def add_credentials(app_id: str, environment: ConnectionEnvironment, use_app_credentials: bool, credentials: CREDENTIALS) -> None:
293
289
  client = get_connections_client()
294
290
  try:
295
- existing_credentials = client.get_credentials(app_id=app_id, env=environment, use_sso=use_sso)
296
- if use_sso:
291
+ existing_credentials = client.get_credentials(app_id=app_id, env=environment, use_app_credentials=use_app_credentials)
292
+ if use_app_credentials:
297
293
  payload = {
298
294
  "app_credentials": credentials.model_dump(exclude_none=True)
299
295
  }
@@ -304,9 +300,9 @@ def add_credentials(app_id: str, environment: ConnectionEnvironment, use_sso: bo
304
300
 
305
301
  logger.info(f"Setting credentials for environment '{environment}' on connection '{app_id}'")
306
302
  if existing_credentials:
307
- client.update_credentials(app_id=app_id, env=environment, use_sso=use_sso, payload=payload)
303
+ client.update_credentials(app_id=app_id, env=environment, use_app_credentials=use_app_credentials, payload=payload)
308
304
  else:
309
- client.create_credentials(app_id=app_id,env=environment, use_sso=use_sso, payload=payload)
305
+ client.create_credentials(app_id=app_id,env=environment, use_app_credentials=use_app_credentials, payload=payload)
310
306
  logger.info(f"Credentials successfully set for '{environment}' environment of connection '{app_id}'")
311
307
  except requests.HTTPError as e:
312
308
  response = e.response
@@ -318,7 +314,7 @@ def add_identity_provider(app_id: str, environment: ConnectionEnvironment, idp:
318
314
  client = get_connections_client()
319
315
 
320
316
  try:
321
- existing_credentials = client.get_credentials(app_id=app_id, env=environment, use_sso=True)
317
+ existing_credentials = client.get_credentials(app_id=app_id, env=environment, use_app_credentials=True)
322
318
 
323
319
  payload = {
324
320
  "idp_credentials": idp.model_dump()
@@ -326,9 +322,9 @@ def add_identity_provider(app_id: str, environment: ConnectionEnvironment, idp:
326
322
 
327
323
  logger.info(f"Setting identity provider for environment '{environment}' on connection '{app_id}'")
328
324
  if existing_credentials:
329
- client.update_credentials(app_id=app_id, env=environment, use_sso=True, payload=payload)
325
+ client.update_credentials(app_id=app_id, env=environment, use_app_credentials=True, payload=payload)
330
326
  else:
331
- client.create_credentials(app_id=app_id,env=environment, use_sso=True, payload=payload)
327
+ client.create_credentials(app_id=app_id,env=environment, use_app_credentials=True, payload=payload)
332
328
  logger.info(f"Identity provider successfully set for '{environment}' environment of connection '{app_id}'")
333
329
  except requests.HTTPError as e:
334
330
  response = e.response
@@ -387,11 +383,17 @@ def list_connections(environment: ConnectionEnvironment | None, verbose: bool =
387
383
  non_configured_table = rich.table.Table(show_header=True, header_style="bold white", show_lines=True, title="*Non-Configured")
388
384
  draft_table = rich.table.Table(show_header=True, header_style="bold white", show_lines=True, title="Draft")
389
385
  live_table = rich.table.Table(show_header=True, header_style="bold white", show_lines=True, title="Live")
390
- columns = ["App ID", "Auth Type", "Type", "Credentials Set"]
391
- for column in columns:
392
- draft_table.add_column(column, justify='center', no_wrap=True)
393
- live_table.add_column(column, justify='center', no_wrap=True)
394
- non_configured_table.add_column(column, justify='center', no_wrap=True)
386
+ default_args = {"justify": "center", "no_wrap": True}
387
+ column_args = {
388
+ "App ID": {"overflow": "fold"},
389
+ "Auth Type": {},
390
+ "Type": {},
391
+ "Credentials Set/ Connected": {}
392
+ }
393
+ for column in column_args:
394
+ draft_table.add_column(column,**default_args, **column_args[column])
395
+ live_table.add_column(column,**default_args, **column_args[column])
396
+ non_configured_table.add_column(column,**default_args, **column_args[column])
395
397
 
396
398
  for conn in connections:
397
399
  if conn.environment is None:
@@ -463,11 +465,6 @@ def configure_connection(**kwargs) -> None:
463
465
 
464
466
  config = ConnectionConfiguration.model_validate(kwargs)
465
467
 
466
- # TODO: Remove once Oauth is supported on local
467
- if config.security_scheme == ConnectionSecurityScheme.OAUTH2 and is_local_dev():
468
- logger.error("Use of OAuth connections unsupported for local development at this time.")
469
- sys.exit(1)
470
-
471
468
  add_configuration(config)
472
469
 
473
470
  def set_credentials_connection(
@@ -484,11 +481,12 @@ def set_credentials_connection(
484
481
 
485
482
  sso_enabled = config.sso
486
483
  conn_type = get_connection_type(security_scheme=config.security_scheme, auth_type=config.auth_type)
484
+ use_app_credentials = conn_type in OAUTH_CONNECTION_TYPES
487
485
 
488
486
  _validate_connection_params(type=conn_type, **kwargs)
489
487
  credentials = _get_credentials(type=conn_type, **kwargs)
490
488
 
491
- add_credentials(app_id=app_id, environment=environment, use_sso=sso_enabled, credentials=credentials)
489
+ add_credentials(app_id=app_id, environment=environment, use_app_credentials=use_app_credentials, credentials=credentials)
492
490
 
493
491
  def set_identity_provider_connection(
494
492
  app_id: str,
@@ -197,10 +197,10 @@ class KnowledgeBaseController:
197
197
  )
198
198
 
199
199
  column_args = {
200
- "Name": {},
200
+ "Name": {"overflow": "fold"},
201
201
  "Description": {},
202
202
  "App ID": {},
203
- "ID": {}
203
+ "ID": {"overflow": "fold"}
204
204
  }
205
205
 
206
206
  for column in column_args: