ibm-watsonx-orchestrate 1.9.0b2__py3-none-any.whl → 1.10.0b0__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 +2 -1
- ibm_watsonx_orchestrate/agent_builder/agents/types.py +2 -0
- ibm_watsonx_orchestrate/agent_builder/tools/python_tool.py +19 -7
- ibm_watsonx_orchestrate/agent_builder/voice_configurations/__init__.py +1 -0
- ibm_watsonx_orchestrate/agent_builder/voice_configurations/types.py +98 -0
- ibm_watsonx_orchestrate/cli/commands/agents/agents_command.py +20 -0
- ibm_watsonx_orchestrate/cli/commands/agents/agents_controller.py +170 -1
- ibm_watsonx_orchestrate/cli/commands/knowledge_bases/knowledge_bases_controller.py +19 -12
- ibm_watsonx_orchestrate/cli/commands/server/server_command.py +17 -4
- ibm_watsonx_orchestrate/cli/commands/tools/tools_controller.py +5 -0
- ibm_watsonx_orchestrate/cli/commands/voice_configurations/voice_configurations_command.py +58 -0
- ibm_watsonx_orchestrate/cli/commands/voice_configurations/voice_configurations_controller.py +173 -0
- ibm_watsonx_orchestrate/cli/main.py +2 -0
- ibm_watsonx_orchestrate/client/agents/agent_client.py +64 -1
- ibm_watsonx_orchestrate/client/voice_configurations/voice_configurations_client.py +75 -0
- ibm_watsonx_orchestrate/docker/compose-lite.yml +15 -1
- ibm_watsonx_orchestrate/docker/default.env +9 -6
- ibm_watsonx_orchestrate/flow_builder/flows/flow.py +24 -19
- {ibm_watsonx_orchestrate-1.9.0b2.dist-info → ibm_watsonx_orchestrate-1.10.0b0.dist-info}/METADATA +1 -1
- {ibm_watsonx_orchestrate-1.9.0b2.dist-info → ibm_watsonx_orchestrate-1.10.0b0.dist-info}/RECORD +23 -18
- {ibm_watsonx_orchestrate-1.9.0b2.dist-info → ibm_watsonx_orchestrate-1.10.0b0.dist-info}/WHEEL +0 -0
- {ibm_watsonx_orchestrate-1.9.0b2.dist-info → ibm_watsonx_orchestrate-1.10.0b0.dist-info}/entry_points.txt +0 -0
- {ibm_watsonx_orchestrate-1.9.0b2.dist-info → ibm_watsonx_orchestrate-1.10.0b0.dist-info}/licenses/LICENSE +0 -0
@@ -77,6 +77,8 @@ class BaseAgentSpec(BaseModel):
|
|
77
77
|
description: Annotated[str, Field(json_schema_extra={"min_length_str":1})]
|
78
78
|
context_access_enabled: bool = True
|
79
79
|
context_variables: Optional[List[str]] = []
|
80
|
+
voice_configuration_id: Optional[str] = None
|
81
|
+
voice_configuration: Optional[str] = None
|
80
82
|
|
81
83
|
def dump_spec(self, file: str) -> None:
|
82
84
|
dumped = self.model_dump(mode='json', exclude_unset=True, exclude_none=True)
|
@@ -187,15 +187,27 @@ def _fix_optional(schema):
|
|
187
187
|
replacements = {}
|
188
188
|
if schema.required is None:
|
189
189
|
schema.required = []
|
190
|
-
|
191
190
|
for k, v in schema.properties.items():
|
191
|
+
# Simple null type & required -> not required
|
192
192
|
if v.type == 'null' and k in schema.required:
|
193
193
|
not_required.append(k)
|
194
|
-
|
195
|
-
|
196
|
-
if
|
197
|
-
|
198
|
-
|
194
|
+
# Optional with null & required
|
195
|
+
if v.anyOf is not None and [x for x in v.anyOf if x.type == 'null']:
|
196
|
+
if k in schema.required:
|
197
|
+
# required with default -> not required
|
198
|
+
# required without default -> required & remove null from union
|
199
|
+
if v.default:
|
200
|
+
not_required.append(k)
|
201
|
+
else:
|
202
|
+
v.anyOf = list(filter(lambda x: x.type != 'null', v.anyOf))
|
203
|
+
if len(v.anyOf) == 1:
|
204
|
+
replacements[k] = v.anyOf[0]
|
205
|
+
else:
|
206
|
+
# not required with default -> no change
|
207
|
+
# not required without default -> means default input is 'None'
|
208
|
+
v.default = v.default if v.default else 'null'
|
209
|
+
|
210
|
+
|
199
211
|
schema.required = list(filter(lambda x: x not in not_required, schema.required if schema.required is not None else []))
|
200
212
|
for k, v in replacements.items():
|
201
213
|
combined = {
|
@@ -204,7 +216,7 @@ def _fix_optional(schema):
|
|
204
216
|
}
|
205
217
|
schema.properties[k] = JsonSchemaObject(**combined)
|
206
218
|
schema.properties[k].anyOf = None
|
207
|
-
|
219
|
+
|
208
220
|
for k in schema.properties.keys():
|
209
221
|
if schema.properties[k].type == 'object':
|
210
222
|
schema.properties[k] = _fix_optional(schema.properties[k])
|
@@ -0,0 +1 @@
|
|
1
|
+
from .types import VoiceConfiguration
|
@@ -0,0 +1,98 @@
|
|
1
|
+
import json
|
2
|
+
from typing import Annotated, Optional, List, Dict
|
3
|
+
from pydantic import BaseModel, Field, model_validator
|
4
|
+
|
5
|
+
def _validate_exactly_one_of_fields(object: BaseModel, object_name: str, fields: list[str]):
|
6
|
+
present_fields = [getattr(object,field) for field in fields if getattr(object,field) is not None]
|
7
|
+
|
8
|
+
if len(present_fields) != 1:
|
9
|
+
raise ValueError(f"{object_name} requires exactly one of {','.join(fields)}")
|
10
|
+
|
11
|
+
|
12
|
+
def _validate_language_uniqueness(config: BaseModel):
|
13
|
+
if hasattr(config,'language') and hasattr(config,'additional_languages'):
|
14
|
+
if config.language and config.additional_languages and config.language in config.additional_languages:
|
15
|
+
raise ValueError(f"Language '{config.language}' cannot be in both the default language and additional_languages")
|
16
|
+
|
17
|
+
|
18
|
+
class WatsonSTTConfig(BaseModel):
|
19
|
+
api_url: Annotated[str, Field(min_length=1,max_length=2048)]
|
20
|
+
api_key: Optional[Annotated[str, Field(min_length=1,max_length=2048)]] = None
|
21
|
+
bearer_token: Optional[Annotated[str, Field(min_length=1,max_length=2048)]] = None
|
22
|
+
model: Annotated[str, Field(min_length=1,max_length=256)]
|
23
|
+
|
24
|
+
class EmotechSTTConfig(BaseModel):
|
25
|
+
api_key: Annotated[str,Field(min_length=1,max_length=2048)]
|
26
|
+
api_url: Annotated[str,Field(min_length=1,max_length=2048)]
|
27
|
+
|
28
|
+
|
29
|
+
class SpeechToTextConfig(BaseModel):
|
30
|
+
provider: Annotated[str, Field(min_length=1,max_length=128)]
|
31
|
+
watson_stt_config: Optional[WatsonSTTConfig] = None
|
32
|
+
emotech_stt_config: Optional[EmotechSTTConfig] = None
|
33
|
+
|
34
|
+
@model_validator(mode='after')
|
35
|
+
def validate_providers(self):
|
36
|
+
_validate_exactly_one_of_fields(self,'SpeechToTextConfig',['watson_stt_config','emotech_stt_config'])
|
37
|
+
return self
|
38
|
+
|
39
|
+
class WatsonTTSConfig(BaseModel):
|
40
|
+
api_url: Annotated[str, Field(min_length=1,max_length=2048)]
|
41
|
+
api_key: Optional[Annotated[str, Field(min_length=1,max_length=2048)]] = None
|
42
|
+
bearer_token: Optional[Annotated[str, Field(min_length=1,max_length=2048)]] = None
|
43
|
+
voice: Annotated[str, Field(min_length=1,max_length=128)]
|
44
|
+
rate_percentage: Optional[int] = None
|
45
|
+
pitch_percentage: Optional[int] = None
|
46
|
+
language: Optional[str] = None
|
47
|
+
|
48
|
+
class EmotechTTSConfig(BaseModel):
|
49
|
+
api_url: Annotated[str, Field(min_length=1,max_length=2048)]
|
50
|
+
api_key: Annotated[str, Field(min_length=1,max_length=2048)]
|
51
|
+
voice: Optional[Annotated[str, Field(min_length=1,max_length=128)]]
|
52
|
+
|
53
|
+
class TextToSpeechConfig(BaseModel):
|
54
|
+
provider: Annotated[str, Field(min_length=1,max_length=128)]
|
55
|
+
watson_tts_config: Optional[WatsonTTSConfig] = None
|
56
|
+
emotech_tts_config: Optional[EmotechTTSConfig] = None
|
57
|
+
|
58
|
+
@model_validator(mode='after')
|
59
|
+
def validate_providers(self):
|
60
|
+
_validate_exactly_one_of_fields(self,'TextToSpeechConfig',['watson_tts_config','emotech_tts_config'])
|
61
|
+
return self
|
62
|
+
|
63
|
+
class AdditionalProperties(BaseModel):
|
64
|
+
speech_to_text: Optional[SpeechToTextConfig] = None
|
65
|
+
text_to_speech: Optional[TextToSpeechConfig] = None
|
66
|
+
|
67
|
+
class DTMFInput(BaseModel):
|
68
|
+
inter_digit_timeout_ms: Optional[int] = None
|
69
|
+
termination_key: Optional[str] = None
|
70
|
+
maximum_count: Optional[int] = None
|
71
|
+
ignore_speech: Optional[bool] = None
|
72
|
+
|
73
|
+
class AttachedAgent(BaseModel):
|
74
|
+
id: str
|
75
|
+
name: Optional[str] = None
|
76
|
+
display_name: Optional[str] = None
|
77
|
+
|
78
|
+
class VoiceConfiguration(BaseModel):
|
79
|
+
name: Annotated[str, Field(min_length=1,max_length=128)]
|
80
|
+
speech_to_text: SpeechToTextConfig
|
81
|
+
text_to_speech: TextToSpeechConfig
|
82
|
+
language: Optional[Annotated[str,Field(min_length=2,max_length=16)]] = None
|
83
|
+
additional_languages: Optional[dict[str,AdditionalProperties]] = None
|
84
|
+
dtmf_input: Optional[DTMFInput] = None
|
85
|
+
voice_configuration_id: Optional[str] = None
|
86
|
+
tenant_id: Optional[Annotated[str, Field(min_length=1,max_length=128)]] = None
|
87
|
+
attached_agents: Optional[list[AttachedAgent]] = None
|
88
|
+
|
89
|
+
@model_validator(mode='after')
|
90
|
+
def validate_language(self):
|
91
|
+
_validate_language_uniqueness(self)
|
92
|
+
return self
|
93
|
+
|
94
|
+
def dumps_spec(self) -> str:
|
95
|
+
dumped = self.model_dump(mode='json', exclude_none=True)
|
96
|
+
return json.dumps(dumped, indent=2)
|
97
|
+
|
98
|
+
|
@@ -253,3 +253,23 @@ def export_agent(
|
|
253
253
|
):
|
254
254
|
agents_controller = AgentsController()
|
255
255
|
agents_controller.export_agent(name=name, kind=kind, output_path=output_file, agent_only_flag=agent_only_flag)
|
256
|
+
|
257
|
+
@agents_app.command(name="deploy", help="Deploy Agent")
|
258
|
+
def deploy_agent(
|
259
|
+
name: Annotated[
|
260
|
+
str,
|
261
|
+
typer.Option("--name", "-n", help="Name of the agent you wish to deploy"),
|
262
|
+
]
|
263
|
+
):
|
264
|
+
agents_controller = AgentsController()
|
265
|
+
agents_controller.deploy_agent(name=name)
|
266
|
+
|
267
|
+
@agents_app.command(name="undeploy", help="Undeploy Agent")
|
268
|
+
def undeploy_agent(
|
269
|
+
name: Annotated[
|
270
|
+
str,
|
271
|
+
typer.Option("--name", "-n", help="Name of the agent you wish to undeploy"),
|
272
|
+
]
|
273
|
+
):
|
274
|
+
agents_controller = AgentsController()
|
275
|
+
agents_controller.undeploy_agent(name=name)
|
@@ -29,13 +29,17 @@ from ibm_watsonx_orchestrate.client.agents.agent_client import AgentClient, Agen
|
|
29
29
|
from ibm_watsonx_orchestrate.client.agents.external_agent_client import ExternalAgentClient
|
30
30
|
from ibm_watsonx_orchestrate.client.agents.assistant_agent_client import AssistantAgentClient
|
31
31
|
from ibm_watsonx_orchestrate.client.tools.tool_client import ToolClient
|
32
|
+
from ibm_watsonx_orchestrate.client.voice_configurations.voice_configurations_client import VoiceConfigurationsClient
|
32
33
|
from ibm_watsonx_orchestrate.utils.exceptions import BadRequest
|
33
34
|
from ibm_watsonx_orchestrate.client.connections import get_connections_client
|
34
35
|
from ibm_watsonx_orchestrate.client.knowledge_bases.knowledge_base_client import KnowledgeBaseClient
|
35
36
|
|
36
|
-
from ibm_watsonx_orchestrate.client.utils import instantiate_client
|
37
|
+
from ibm_watsonx_orchestrate.client.utils import instantiate_client, is_local_dev
|
37
38
|
from ibm_watsonx_orchestrate.utils.utils import check_file_in_zip
|
38
39
|
|
40
|
+
from rich.console import Console
|
41
|
+
from rich.progress import Progress, SpinnerColumn, TextColumn
|
42
|
+
|
39
43
|
logger = logging.getLogger(__name__)
|
40
44
|
|
41
45
|
# Helper generic type for any agent
|
@@ -197,6 +201,7 @@ def get_app_id_from_conn_id(conn_id: str) -> str:
|
|
197
201
|
exit(1)
|
198
202
|
return app_id
|
199
203
|
|
204
|
+
|
200
205
|
def get_agent_details(name: str, client: AgentClient | ExternalAgentClient | AssistantAgentClient) -> dict:
|
201
206
|
agent_specs = client.get_draft_by_name(name)
|
202
207
|
if len(agent_specs) > 1:
|
@@ -219,6 +224,7 @@ class AgentsController:
|
|
219
224
|
self.assistant_client = None
|
220
225
|
self.tool_client = None
|
221
226
|
self.knowledge_base_client = None
|
227
|
+
self.voice_configuration_client = None
|
222
228
|
|
223
229
|
def get_native_client(self):
|
224
230
|
if not self.native_client:
|
@@ -245,6 +251,11 @@ class AgentsController:
|
|
245
251
|
self.knowledge_base_client = instantiate_client(KnowledgeBaseClient)
|
246
252
|
return self.knowledge_base_client
|
247
253
|
|
254
|
+
def get_voice_configuration_client(self):
|
255
|
+
if not self.voice_configuration_client:
|
256
|
+
self.voice_configuration_client = instantiate_client(VoiceConfigurationsClient)
|
257
|
+
return self.voice_configuration_client
|
258
|
+
|
248
259
|
@staticmethod
|
249
260
|
def import_agent(file: str, app_id: str) -> List[Agent | ExternalAgent | AssistantAgent]:
|
250
261
|
agents = parse_file(file)
|
@@ -520,6 +531,38 @@ class AgentsController:
|
|
520
531
|
guideline.tool = name
|
521
532
|
|
522
533
|
return ref_agent
|
534
|
+
|
535
|
+
def get_voice_config_name_from_id(self, voice_config_id: str) -> str | None:
|
536
|
+
client = self.get_voice_configuration_client()
|
537
|
+
config = client.get_by_id(voice_config_id)
|
538
|
+
return config.name if config else None
|
539
|
+
|
540
|
+
def get_voice_config_id_from_name(self, voice_config_name: str) -> str | None:
|
541
|
+
client = self.get_voice_configuration_client()
|
542
|
+
configs = client.get_by_name(voice_config_name)
|
543
|
+
|
544
|
+
if len(configs) == 0:
|
545
|
+
logger.error(f"No voice_configs with the name '{voice_config_name}' found. Failed to get config")
|
546
|
+
sys.exit(1)
|
547
|
+
|
548
|
+
if len(configs) > 1:
|
549
|
+
logger.error(f"Multiple voice_configs with the name '{voice_config_name}' found. Failed to get config")
|
550
|
+
sys.exit(1)
|
551
|
+
|
552
|
+
return configs[0].voice_configuration_id
|
553
|
+
|
554
|
+
|
555
|
+
def reference_voice_config(self,agent: Agent):
|
556
|
+
deref_agent = deepcopy(agent)
|
557
|
+
deref_agent.voice_configuration = self.get_voice_config_name_from_id(agent.voice_configuration_id)
|
558
|
+
del deref_agent.voice_configuration_id
|
559
|
+
return deref_agent
|
560
|
+
|
561
|
+
def dereference_voice_config(self,agent: Agent):
|
562
|
+
ref_agent = deepcopy(agent)
|
563
|
+
ref_agent.voice_configuration_id = self.get_voice_config_id_from_name(agent.voice_configuration)
|
564
|
+
del ref_agent.voice_configuration
|
565
|
+
return ref_agent
|
523
566
|
|
524
567
|
@staticmethod
|
525
568
|
def dereference_app_id(agent: ExternalAgent | AssistantAgent) -> ExternalAgent | AssistantAgent:
|
@@ -540,7 +583,18 @@ class AgentsController:
|
|
540
583
|
agent.config.connection_id = None
|
541
584
|
|
542
585
|
return agent
|
586
|
+
|
587
|
+
def dereference_common_agent_dependencies(self, agent: AnyAgentT) -> AnyAgentT:
|
588
|
+
if agent.voice_configuration:
|
589
|
+
agent = self.dereference_voice_config(agent)
|
590
|
+
|
591
|
+
return agent
|
592
|
+
|
593
|
+
def reference_common_agent_dependencies(self, agent: AnyAgentT) -> AnyAgentT:
|
594
|
+
if agent.voice_configuration_id:
|
595
|
+
agent = self.reference_voice_config(agent)
|
543
596
|
|
597
|
+
return agent
|
544
598
|
|
545
599
|
def dereference_native_agent_dependencies(self, agent: Agent) -> Agent:
|
546
600
|
if agent.collaborators and len(agent.collaborators):
|
@@ -584,6 +638,8 @@ class AgentsController:
|
|
584
638
|
|
585
639
|
# Convert all names used in an agent to the corresponding ids
|
586
640
|
def dereference_agent_dependencies(self, agent: AnyAgentT) -> AnyAgentT:
|
641
|
+
|
642
|
+
agent = self.dereference_common_agent_dependencies(agent)
|
587
643
|
if isinstance(agent, Agent):
|
588
644
|
return self.dereference_native_agent_dependencies(agent)
|
589
645
|
if isinstance(agent, ExternalAgent) or isinstance(agent, AssistantAgent):
|
@@ -591,6 +647,8 @@ class AgentsController:
|
|
591
647
|
|
592
648
|
# Convert all ids used in an agent to the corresponding names
|
593
649
|
def reference_agent_dependencies(self, agent: AnyAgentT) -> AnyAgentT:
|
650
|
+
|
651
|
+
agent = self.reference_common_agent_dependencies(agent)
|
594
652
|
if isinstance(agent, Agent):
|
595
653
|
return self.reference_native_agent_dependencies(agent)
|
596
654
|
if isinstance(agent, ExternalAgent) or isinstance(agent, AssistantAgent):
|
@@ -1111,3 +1169,114 @@ class AgentsController:
|
|
1111
1169
|
logger.info(f"Successfully wrote agents and tools to '{output_path}'")
|
1112
1170
|
zip_file_out.close()
|
1113
1171
|
|
1172
|
+
|
1173
|
+
def deploy_agent(self, name: str):
|
1174
|
+
if is_local_dev():
|
1175
|
+
logger.error("Agents cannot be deployed in Developer Edition")
|
1176
|
+
sys.exit(1)
|
1177
|
+
native_client = self.get_native_client()
|
1178
|
+
external_client = self.get_external_client()
|
1179
|
+
assistant_client = self.get_assistant_client()
|
1180
|
+
|
1181
|
+
existing_native_agents = native_client.get_draft_by_name(name)
|
1182
|
+
existing_external_agents = external_client.get_draft_by_name(name)
|
1183
|
+
existing_assistant_agents = assistant_client.get_draft_by_name(name)
|
1184
|
+
|
1185
|
+
if len(existing_native_agents) == 0 and (len(existing_external_agents) >= 1 or len(existing_assistant_agents) >= 1):
|
1186
|
+
logger.error(f"No native agent found with name '{name}'. Only Native Agents can be deployed to a Live Environment")
|
1187
|
+
sys.exit(1)
|
1188
|
+
if len(existing_native_agents) > 1:
|
1189
|
+
logger.error(f"Multiple native agents with the name '{name}' found. Failed to get agent")
|
1190
|
+
sys.exit(1)
|
1191
|
+
if len(existing_native_agents) == 0:
|
1192
|
+
logger.error(f"No native agents with the name '{name}' found. Failed to get agent")
|
1193
|
+
sys.exit(1)
|
1194
|
+
|
1195
|
+
|
1196
|
+
agent_details = existing_native_agents[0]
|
1197
|
+
agent_id = agent_details.get("id")
|
1198
|
+
|
1199
|
+
environments = native_client.get_environments_for_agent(agent_id)
|
1200
|
+
|
1201
|
+
live_environment = [env for env in environments if env.get("name") == "live"]
|
1202
|
+
if live_environment is None:
|
1203
|
+
logger.error("No live environment found for this tenant")
|
1204
|
+
sys.exit(1)
|
1205
|
+
|
1206
|
+
live_env_id = live_environment[0].get("id")
|
1207
|
+
|
1208
|
+
console = Console()
|
1209
|
+
with Progress(
|
1210
|
+
SpinnerColumn(spinner_name="dots"),
|
1211
|
+
TextColumn("[progress.description]{task.description}"),
|
1212
|
+
transient=True,
|
1213
|
+
console=console,
|
1214
|
+
) as progress:
|
1215
|
+
progress.add_task(description="Deploying agent to Live envrionment", total=None)
|
1216
|
+
|
1217
|
+
status = native_client.deploy(agent_id, live_env_id)
|
1218
|
+
|
1219
|
+
if status:
|
1220
|
+
logger.info(f"Successfully deployed agent {name}")
|
1221
|
+
else:
|
1222
|
+
logger.error(f"Error deploying agent {name}")
|
1223
|
+
|
1224
|
+
def undeploy_agent(self, name: str):
|
1225
|
+
if is_local_dev():
|
1226
|
+
logger.error("Agents cannot be undeployed in Developer Edition")
|
1227
|
+
sys.exit(1)
|
1228
|
+
|
1229
|
+
native_client = self.get_native_client()
|
1230
|
+
external_client = self.get_external_client()
|
1231
|
+
assistant_client = self.get_assistant_client()
|
1232
|
+
|
1233
|
+
existing_native_agents = native_client.get_draft_by_name(name)
|
1234
|
+
existing_external_agents = external_client.get_draft_by_name(name)
|
1235
|
+
existing_assistant_agents = assistant_client.get_draft_by_name(name)
|
1236
|
+
|
1237
|
+
if len(existing_native_agents) == 0 and (len(existing_external_agents) >= 1 or len(existing_assistant_agents) >= 1):
|
1238
|
+
logger.error(f"No native agent found with name '{name}'. Only Native Agents can be undeployed from a Live Environment")
|
1239
|
+
sys.exit(1)
|
1240
|
+
if len(existing_native_agents) > 1:
|
1241
|
+
logger.error(f"Multiple native agents with the name '{name}' found. Failed to get agent")
|
1242
|
+
sys.exit(1)
|
1243
|
+
if len(existing_native_agents) == 0:
|
1244
|
+
logger.error(f"No native agents with the name '{name}' found. Failed to get agent")
|
1245
|
+
sys.exit(1)
|
1246
|
+
|
1247
|
+
agent_details = existing_native_agents[0]
|
1248
|
+
agent_id = agent_details.get("id")
|
1249
|
+
|
1250
|
+
environments = native_client.get_environments_for_agent(agent_id)
|
1251
|
+
live_environment = [env for env in environments if env.get("name") == "live"]
|
1252
|
+
if live_environment is None:
|
1253
|
+
logger.error("No live environment found for this tenant")
|
1254
|
+
sys.exit(1)
|
1255
|
+
version_id = live_environment[0].get("current_version")
|
1256
|
+
|
1257
|
+
if version_id is None:
|
1258
|
+
agent_name = agent_details.get("name")
|
1259
|
+
logger.error(f"Agent {agent_name} does not exist in a Live environment")
|
1260
|
+
sys.exit(1)
|
1261
|
+
|
1262
|
+
draft_environment = [env for env in environments if env.get("name") == "draft"]
|
1263
|
+
if draft_environment is None:
|
1264
|
+
logger.error("No draft environment found for this tenant")
|
1265
|
+
sys.exit(1)
|
1266
|
+
draft_env_id = draft_environment[0].get("id")
|
1267
|
+
|
1268
|
+
console = Console()
|
1269
|
+
with Progress(
|
1270
|
+
SpinnerColumn(spinner_name="dots"),
|
1271
|
+
TextColumn("[progress.description]{task.description}"),
|
1272
|
+
transient=True,
|
1273
|
+
console=console,
|
1274
|
+
) as progress:
|
1275
|
+
progress.add_task(description="Undeploying agent to Draft envrionment", total=None)
|
1276
|
+
|
1277
|
+
status = native_client.undeploy(agent_id, version_id, draft_env_id)
|
1278
|
+
if status:
|
1279
|
+
logger.info(f"Successfully undeployed agent {name}")
|
1280
|
+
else:
|
1281
|
+
logger.error(f"Error undeploying agent {name}")
|
1282
|
+
|
@@ -72,6 +72,21 @@ class KnowledgeBaseController:
|
|
72
72
|
|
73
73
|
knowledge_bases = parse_file(file=file)
|
74
74
|
|
75
|
+
if app_id:
|
76
|
+
connections_client = get_connections_client()
|
77
|
+
connection_id = None
|
78
|
+
|
79
|
+
connections = connections_client.get_draft_by_app_id(app_id=app_id)
|
80
|
+
if not connections:
|
81
|
+
logger.error(f"No connection exists with the app-id '{app_id}'")
|
82
|
+
exit(1)
|
83
|
+
|
84
|
+
connection_id = connections.connection_id
|
85
|
+
|
86
|
+
for kb in knowledge_bases:
|
87
|
+
if kb.conversational_search_tool and kb.conversational_search_tool.index_config and len(kb.conversational_search_tool.index_config) > 0:
|
88
|
+
kb.conversational_search_tool.index_config[0].connection_id = connection_id
|
89
|
+
|
75
90
|
existing_knowledge_bases = client.get_by_names([kb.name for kb in knowledge_bases])
|
76
91
|
|
77
92
|
for kb in knowledge_bases:
|
@@ -97,18 +112,10 @@ class KnowledgeBaseController:
|
|
97
112
|
if len(kb.conversational_search_tool.index_config) != 1:
|
98
113
|
raise ValueError(f"Must provide exactly one conversational_search_tool.index_config. Provided {len(kb.conversational_search_tool.index_config)}.")
|
99
114
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
if app_id is not None:
|
105
|
-
connections = connections_client.get_draft_by_app_id(app_id=app_id)
|
106
|
-
if not connections:
|
107
|
-
logger.error(f"No connection exists with the app-id '{app_id}'")
|
108
|
-
exit(1)
|
109
|
-
|
110
|
-
connection_id = connections.connection_id
|
111
|
-
kb.conversational_search_tool.index_config[0].connection_id = connection_id
|
115
|
+
if (kb.conversational_search_tool.index_config[0].milvus or \
|
116
|
+
kb.conversational_search_tool.index_config[0].elastic_search) and \
|
117
|
+
not kb.conversational_search_tool.index_config[0].connection_id:
|
118
|
+
raise ValueError(f"Must provide credentials (via --app-id) when using milvus or elastic_search.")
|
112
119
|
|
113
120
|
kb.prioritize_built_in_index = False
|
114
121
|
client.create(payload=kb.model_dump(exclude_none=True))
|
@@ -370,9 +370,13 @@ def get_persisted_user_env() -> dict | None:
|
|
370
370
|
user_env = cfg.get(USER_ENV_CACHE_HEADER) if cfg.get(USER_ENV_CACHE_HEADER) else None
|
371
371
|
return user_env
|
372
372
|
|
373
|
-
def run_compose_lite(
|
374
|
-
|
375
|
-
|
373
|
+
def run_compose_lite(
|
374
|
+
final_env_file: Path,
|
375
|
+
experimental_with_langfuse=False,
|
376
|
+
experimental_with_ibm_telemetry=False,
|
377
|
+
with_doc_processing=False,
|
378
|
+
with_voice=False
|
379
|
+
) -> None:
|
376
380
|
compose_path = get_compose_file()
|
377
381
|
|
378
382
|
compose_command = ensure_docker_compose_installed()
|
@@ -408,6 +412,8 @@ def run_compose_lite(final_env_file: Path, experimental_with_langfuse=False, exp
|
|
408
412
|
profiles.append("ibm-telemetry")
|
409
413
|
if with_doc_processing:
|
410
414
|
profiles.append("docproc")
|
415
|
+
if with_voice:
|
416
|
+
profiles.append("voice")
|
411
417
|
|
412
418
|
command = compose_command[:]
|
413
419
|
for profile in profiles:
|
@@ -855,6 +861,11 @@ def server_start(
|
|
855
861
|
'--compose-file', '-f',
|
856
862
|
help='Provide the path to a custom docker-compose file to use instead of the default compose file'
|
857
863
|
),
|
864
|
+
with_voice: bool = typer.Option(
|
865
|
+
False,
|
866
|
+
'--with-voice', '-v',
|
867
|
+
help='Enable voice controller to interact with the chat via voice channels'
|
868
|
+
),
|
858
869
|
):
|
859
870
|
confirm_accepts_license_agreement(accept_terms_and_conditions)
|
860
871
|
|
@@ -896,6 +907,7 @@ def server_start(
|
|
896
907
|
if experimental_with_ibm_telemetry:
|
897
908
|
merged_env_dict['USE_IBM_TELEMETRY'] = 'true'
|
898
909
|
|
910
|
+
|
899
911
|
try:
|
900
912
|
dev_edition_source = get_dev_edition_source(merged_env_dict)
|
901
913
|
docker_login_by_dev_edition_source(merged_env_dict, dev_edition_source)
|
@@ -908,7 +920,8 @@ def server_start(
|
|
908
920
|
run_compose_lite(final_env_file=final_env_file,
|
909
921
|
experimental_with_langfuse=experimental_with_langfuse,
|
910
922
|
experimental_with_ibm_telemetry=experimental_with_ibm_telemetry,
|
911
|
-
with_doc_processing=with_doc_processing
|
923
|
+
with_doc_processing=with_doc_processing,
|
924
|
+
with_voice=with_voice)
|
912
925
|
|
913
926
|
run_db_migration()
|
914
927
|
|
@@ -464,6 +464,11 @@ The [bold]flow tool[/bold] is being imported from [green]`{file}`[/green].
|
|
464
464
|
continue
|
465
465
|
|
466
466
|
model = obj().to_json()
|
467
|
+
# Ensure metadata exists and is correct
|
468
|
+
if "metadata" not in model or not isinstance(model["metadata"], dict):
|
469
|
+
model["metadata"] = {}
|
470
|
+
if "source_kind" not in model["metadata"]:
|
471
|
+
model["metadata"]["source_kind"] = "adk/python"
|
467
472
|
break
|
468
473
|
|
469
474
|
elif file_path.suffix.lower() == ".json":
|
@@ -0,0 +1,58 @@
|
|
1
|
+
import sys
|
2
|
+
from typing import Annotated
|
3
|
+
import typer
|
4
|
+
import logging
|
5
|
+
|
6
|
+
from ibm_watsonx_orchestrate.cli.commands.voice_configurations.voice_configurations_controller import VoiceConfigurationsController
|
7
|
+
|
8
|
+
logger = logging.getLogger(__name__)
|
9
|
+
|
10
|
+
voice_configurations_app = typer.Typer(no_args_is_help=True)
|
11
|
+
|
12
|
+
@voice_configurations_app.command(name="import", help="Import a voice configuration into the active environment from a file")
|
13
|
+
def import_voice_config(
|
14
|
+
file: Annotated[
|
15
|
+
str,
|
16
|
+
typer.Option(
|
17
|
+
"--file",
|
18
|
+
"-f",
|
19
|
+
help="YAML file with voice configuraton definition"
|
20
|
+
)
|
21
|
+
],
|
22
|
+
):
|
23
|
+
voice_config_controller = VoiceConfigurationsController()
|
24
|
+
imported_config = voice_config_controller.import_voice_config(file)
|
25
|
+
voice_config_controller.publish_or_update_voice_config(imported_config)
|
26
|
+
|
27
|
+
@voice_configurations_app.command(name="remove", help="Remove a voice configuration from the active environment")
|
28
|
+
def remove_voice_config(
|
29
|
+
voice_config_name: Annotated[
|
30
|
+
str,
|
31
|
+
typer.Option(
|
32
|
+
"--name",
|
33
|
+
"-n",
|
34
|
+
help="name of the voice configuration to remove"
|
35
|
+
)
|
36
|
+
] = None,
|
37
|
+
):
|
38
|
+
voice_config_controller = VoiceConfigurationsController()
|
39
|
+
if voice_config_name:
|
40
|
+
voice_config_controller.remove_voice_config_by_name(voice_config_name)
|
41
|
+
else:
|
42
|
+
raise TypeError("You must specify the name of a voice configuration")
|
43
|
+
|
44
|
+
|
45
|
+
|
46
|
+
@voice_configurations_app.command(name="list", help="List all voice configurations in the active environment")
|
47
|
+
def list_voice_configs(
|
48
|
+
verbose: Annotated[
|
49
|
+
bool,
|
50
|
+
typer.Option(
|
51
|
+
"--verbose",
|
52
|
+
"-v",
|
53
|
+
help="List full details of all voice configurations in json format"
|
54
|
+
)
|
55
|
+
] = False,
|
56
|
+
):
|
57
|
+
voice_config_controller = VoiceConfigurationsController()
|
58
|
+
voice_config_controller.list_voice_configs(verbose)
|
@@ -0,0 +1,173 @@
|
|
1
|
+
import json
|
2
|
+
import sys
|
3
|
+
import rich
|
4
|
+
import yaml
|
5
|
+
import logging
|
6
|
+
from ibm_watsonx_orchestrate.agent_builder.voice_configurations import VoiceConfiguration
|
7
|
+
from ibm_watsonx_orchestrate.client.utils import instantiate_client
|
8
|
+
from ibm_watsonx_orchestrate.client.voice_configurations.voice_configurations_client import VoiceConfigurationsClient
|
9
|
+
from ibm_watsonx_orchestrate.utils.exceptions import BadRequest
|
10
|
+
|
11
|
+
logger = logging.getLogger(__name__)
|
12
|
+
|
13
|
+
class VoiceConfigurationsController:
|
14
|
+
|
15
|
+
def __init__(self):
|
16
|
+
self.voice_configs_client = None
|
17
|
+
|
18
|
+
def get_voice_configurations_client(self):
|
19
|
+
if not self.voice_configs_client:
|
20
|
+
self.voice_configs_client = instantiate_client(VoiceConfigurationsClient)
|
21
|
+
return self.voice_configs_client
|
22
|
+
|
23
|
+
|
24
|
+
def import_voice_config(self, file: str) -> VoiceConfiguration:
|
25
|
+
|
26
|
+
if file.endswith('.yaml') or file.endswith('.yml'):
|
27
|
+
with open(file, 'r') as f:
|
28
|
+
content = yaml.load(f, Loader=yaml.SafeLoader)
|
29
|
+
|
30
|
+
elif file.endswith(".json"):
|
31
|
+
with open(file, 'r') as f:
|
32
|
+
content = json.load(f)
|
33
|
+
|
34
|
+
else:
|
35
|
+
raise BadRequest("file must end in .yaml, .yml or .json")
|
36
|
+
|
37
|
+
return VoiceConfiguration.model_validate(content)
|
38
|
+
|
39
|
+
|
40
|
+
def fetch_voice_configs(self) -> list[VoiceConfiguration]:
|
41
|
+
client = self.get_voice_configurations_client()
|
42
|
+
res = client.list()
|
43
|
+
|
44
|
+
voice_configs = []
|
45
|
+
|
46
|
+
for config in res:
|
47
|
+
try:
|
48
|
+
voice_configs.append(VoiceConfiguration.model_validate(config))
|
49
|
+
except:
|
50
|
+
name = config.get('name', None)
|
51
|
+
logger.error(f"Config '{name}' could not be parsed")
|
52
|
+
|
53
|
+
return voice_configs
|
54
|
+
|
55
|
+
def get_voice_config(self, voice_config_id: str) -> VoiceConfiguration | None:
|
56
|
+
client = self.get_voice_configurations_client()
|
57
|
+
return client.get(voice_config_id)
|
58
|
+
|
59
|
+
def get_voice_config_by_name(self, voice_config_name: str) -> VoiceConfiguration | None:
|
60
|
+
client = self.get_voice_configurations_client()
|
61
|
+
configs = client.get_by_name(voice_config_name)
|
62
|
+
if len(configs) == 0:
|
63
|
+
logger.error(f"No voice_configs with the name '{voice_config_name}' found. Failed to get config")
|
64
|
+
sys.exit(1)
|
65
|
+
|
66
|
+
if len(configs) > 1:
|
67
|
+
logger.error(f"Multiple voice_configs with the name '{voice_config_name}' found. Failed to get config")
|
68
|
+
sys.exit(1)
|
69
|
+
|
70
|
+
return configs[0]
|
71
|
+
|
72
|
+
def list_voice_configs(self, verbose: bool) -> None:
|
73
|
+
voice_configs = self.fetch_voice_configs()
|
74
|
+
|
75
|
+
if verbose:
|
76
|
+
json_configs = [json.loads(x.dumps_spec()) for x in voice_configs]
|
77
|
+
rich.print_json(json.dumps(json_configs, indent=4))
|
78
|
+
else:
|
79
|
+
config_table = rich.table.Table(
|
80
|
+
show_header=True,
|
81
|
+
header_style="bold white",
|
82
|
+
title="Voice Configurations",
|
83
|
+
show_lines=True
|
84
|
+
)
|
85
|
+
|
86
|
+
column_args={
|
87
|
+
"Name" : {"overflow": "fold"},
|
88
|
+
"ID" : {"overflow": "fold"},
|
89
|
+
"STT Provider" : {"overflow": "fold"},
|
90
|
+
"TTS Provider" : {"overflow": "fold"},
|
91
|
+
"Attached Agents" : {}
|
92
|
+
}
|
93
|
+
|
94
|
+
for column in column_args:
|
95
|
+
config_table.add_column(column, **column_args[column])
|
96
|
+
|
97
|
+
for config in voice_configs:
|
98
|
+
attached_agents = [x.display_name or x.name or x.id for x in config.attached_agents]
|
99
|
+
config_table.add_row(
|
100
|
+
config.name,
|
101
|
+
config.voice_configuration_id,
|
102
|
+
config.speech_to_text.provider,
|
103
|
+
config.text_to_speech.provider,
|
104
|
+
",".join(attached_agents)
|
105
|
+
)
|
106
|
+
|
107
|
+
rich.print(config_table)
|
108
|
+
|
109
|
+
|
110
|
+
def create_voice_config(self, voice_config: VoiceConfiguration) -> str | None:
|
111
|
+
client = self.get_voice_configurations_client()
|
112
|
+
res = client.create(voice_config)
|
113
|
+
config_id = res.get("id",None)
|
114
|
+
if config_id:
|
115
|
+
logger.info(f"Sucessfully created voice config '{voice_config['name']}'. id: '{config_id}'")
|
116
|
+
|
117
|
+
return config_id
|
118
|
+
|
119
|
+
|
120
|
+
def update_voice_config_by_id(self, voice_config_id: str, voice_config: VoiceConfiguration) -> str | None:
|
121
|
+
client = self.get_voice_configurations_client()
|
122
|
+
res = client.update(voice_config_id,voice_config)
|
123
|
+
config_id = res.get("id",None)
|
124
|
+
if config_id:
|
125
|
+
logger.info(f"Sucessfully updated voice config '{voice_config['name']}'. id: '{config_id}'")
|
126
|
+
|
127
|
+
return config_id
|
128
|
+
|
129
|
+
def update_voice_config_by_name(self, voice_config_name: str, voice_config: VoiceConfiguration) -> str | None:
|
130
|
+
client = self.get_voice_configurations_client()
|
131
|
+
existing_config = client.get_by_name(voice_config_name)
|
132
|
+
|
133
|
+
if existing_config and len(existing_config) > 0:
|
134
|
+
config_id = existing_config[0].voice_configuration_id
|
135
|
+
client.update(config_id,voice_config)
|
136
|
+
else:
|
137
|
+
logger.warning(f"Voice config '{voice_config_name}' not found, creating new config instead")
|
138
|
+
config_id = self.create_voice_config(voice_config)
|
139
|
+
|
140
|
+
return config_id
|
141
|
+
|
142
|
+
def publish_or_update_voice_config(self, voice_config: VoiceConfiguration) -> str | None:
|
143
|
+
client = self.get_voice_configurations_client()
|
144
|
+
voice_config_name = voice_config.name
|
145
|
+
existing_config = client.get_by_name(voice_config_name)
|
146
|
+
|
147
|
+
if existing_config and len(existing_config) > 0:
|
148
|
+
config_id = existing_config[0].voice_configuration_id
|
149
|
+
client.update(config_id,voice_config)
|
150
|
+
else:
|
151
|
+
client.create(voice_config)
|
152
|
+
|
153
|
+
def remove_voice_config_by_id(self, voice_config_id: str) -> None:
|
154
|
+
client = self.get_voice_configurations_client()
|
155
|
+
client.delete(voice_config_id)
|
156
|
+
logger.info(f"Sucessfully deleted voice config '{voice_config_id}'")
|
157
|
+
|
158
|
+
def remove_voice_config_by_name(self, voice_config_name: str) -> None:
|
159
|
+
client = self.get_voice_configurations_client()
|
160
|
+
voice_config = self.get_voice_config_by_name(voice_config_name)
|
161
|
+
if voice_config:
|
162
|
+
client.delete(voice_config.voice_configuration_id)
|
163
|
+
logger.info(f"Sucessfully deleted voice config '{voice_config_name}'")
|
164
|
+
else:
|
165
|
+
logger.info(f"Voice config '{voice_config_name}' not found")
|
166
|
+
|
167
|
+
|
168
|
+
|
169
|
+
|
170
|
+
|
171
|
+
|
172
|
+
|
173
|
+
|
@@ -16,6 +16,7 @@ from ibm_watsonx_orchestrate.cli.commands.knowledge_bases.knowledge_bases_comman
|
|
16
16
|
from ibm_watsonx_orchestrate.cli.commands.toolkit.toolkit_command import toolkits_app
|
17
17
|
from ibm_watsonx_orchestrate.cli.commands.evaluations.evaluations_command import evaluation_app
|
18
18
|
from ibm_watsonx_orchestrate.cli.commands.copilot.copilot_command import copilot_app
|
19
|
+
from ibm_watsonx_orchestrate.cli.commands.voice_configurations.voice_configurations_command import voice_configurations_app
|
19
20
|
from ibm_watsonx_orchestrate.cli.init_helper import init_callback
|
20
21
|
|
21
22
|
import urllib3
|
@@ -35,6 +36,7 @@ app.add_typer(tools_app, name="tools", help='Interact with the tools in your act
|
|
35
36
|
app.add_typer(toolkits_app, name="toolkits", help="Interact with the toolkits in your active env")
|
36
37
|
app.add_typer(knowledge_bases_app, name="knowledge-bases", help="Upload knowledge your agents can search through to your active env")
|
37
38
|
app.add_typer(connections_app, name="connections", help='Interact with the agents in your active env')
|
39
|
+
app.add_typer(voice_configurations_app, name="voice-configs", help="Configure voice providers to enable voice interaction with your agents")
|
38
40
|
app.add_typer(server_app, name="server", help='Manipulate your local Orchestrate Developer Edition server [requires entitlement]')
|
39
41
|
app.add_typer(chat_app, name="chat", help='Launch the chat ui for your local Developer Edition server [requires entitlement]')
|
40
42
|
app.add_typer(models_app, name="models", help='List the available large language models (llms) that can be used in your agent definitions')
|
@@ -1,7 +1,26 @@
|
|
1
1
|
from ibm_watsonx_orchestrate.client.base_api_client import BaseAPIClient, ClientAPIException
|
2
2
|
from typing_extensions import List, Optional
|
3
|
+
from enum import Enum
|
4
|
+
|
3
5
|
from ibm_watsonx_orchestrate.client.utils import is_local_dev
|
4
6
|
from pydantic import BaseModel
|
7
|
+
import time
|
8
|
+
import logging
|
9
|
+
|
10
|
+
logger = logging.getLogger(__name__)
|
11
|
+
|
12
|
+
POLL_INTERVAL = 2
|
13
|
+
MAX_RETRIES = 10
|
14
|
+
|
15
|
+
class ReleaseMode(str, Enum):
|
16
|
+
DEPLOY = "deploy"
|
17
|
+
UNDEPLOY = "undeploy"
|
18
|
+
|
19
|
+
class ReleaseStatus(str, Enum):
|
20
|
+
SUCCESS = "success"
|
21
|
+
NONE = "none"
|
22
|
+
FAILED = "failed"
|
23
|
+
IN_PROGRESS = "in_progress"
|
5
24
|
|
6
25
|
def transform_agents_from_flat_agent_spec(agents: dict | list[dict] ) -> dict | list[dict]:
|
7
26
|
if isinstance(agents,list):
|
@@ -83,7 +102,6 @@ class AgentClient(BaseAPIClient):
|
|
83
102
|
super().__init__(*args, **kwargs)
|
84
103
|
self.base_endpoint = "/orchestrate/agents" if is_local_dev(self.base_url) else "/agents"
|
85
104
|
|
86
|
-
|
87
105
|
def create(self, payload: dict) -> AgentUpsertResponse:
|
88
106
|
response = self._post(self.base_endpoint, data=transform_agents_from_flat_agent_spec(payload))
|
89
107
|
return AgentUpsertResponse.model_validate(response)
|
@@ -120,4 +138,49 @@ class AgentClient(BaseAPIClient):
|
|
120
138
|
def get_drafts_by_ids(self, agent_ids: List[str]) -> List[dict]:
|
121
139
|
formatted_agent_ids = [f"ids={x}" for x in agent_ids]
|
122
140
|
return transform_agents_to_flat_agent_spec(self._get(f"{self.base_endpoint}?{'&'.join(formatted_agent_ids)}&include_hidden=true"))
|
141
|
+
|
142
|
+
def poll_release_status(self, agent_id: str, environment_id: str, mode: str = "deploy") -> bool:
|
143
|
+
expected_status = {
|
144
|
+
ReleaseMode.DEPLOY: ReleaseStatus.SUCCESS,
|
145
|
+
ReleaseMode.UNDEPLOY: ReleaseStatus.NONE
|
146
|
+
}[mode]
|
147
|
+
|
148
|
+
for attempt in range(MAX_RETRIES):
|
149
|
+
try:
|
150
|
+
response = self._get(
|
151
|
+
f"{self.base_endpoint}/{agent_id}/releases/status?environment_id={environment_id}"
|
152
|
+
)
|
153
|
+
except Exception as e:
|
154
|
+
logger.error(f"Polling for Deployment/Undeployment failed on attempt {attempt + 1}: {e}")
|
155
|
+
return False
|
156
|
+
|
157
|
+
if not isinstance(response, dict):
|
158
|
+
logger.warning(f"Invalid response format: {response}")
|
159
|
+
return False
|
160
|
+
|
161
|
+
status = response.get("deployment_status")
|
162
|
+
|
163
|
+
if status == expected_status:
|
164
|
+
return True
|
165
|
+
elif status == "failed":
|
166
|
+
return False
|
167
|
+
elif status == "in_progress":
|
168
|
+
pass
|
169
|
+
|
170
|
+
time.sleep(POLL_INTERVAL)
|
171
|
+
|
172
|
+
logger.warning(f"{mode.capitalize()} status polling timed out")
|
173
|
+
return False
|
174
|
+
|
175
|
+
def deploy(self, agent_id: str, environment_id: str) -> bool:
|
176
|
+
self._post(f"{self.base_endpoint}/{agent_id}/releases", data={"environment_id": environment_id})
|
177
|
+
return self.poll_release_status(agent_id, environment_id, mode=ReleaseMode.DEPLOY)
|
178
|
+
|
179
|
+
def undeploy(self, agent_id: str, version: str, environment_id: str) -> bool:
|
180
|
+
self._post(f"{self.base_endpoint}/{agent_id}/releases/{version}/undeploy")
|
181
|
+
return self.poll_release_status(agent_id, environment_id, mode=ReleaseMode.UNDEPLOY)
|
182
|
+
|
183
|
+
def get_environments_for_agent(self, agent_id: str):
|
184
|
+
return self._get(f"{self.base_endpoint}/{agent_id}/environment")
|
185
|
+
|
123
186
|
|
@@ -0,0 +1,75 @@
|
|
1
|
+
from pydantic import ValidationError
|
2
|
+
from ibm_watsonx_orchestrate.agent_builder.voice_configurations import VoiceConfiguration
|
3
|
+
from ibm_watsonx_orchestrate.client.base_api_client import BaseAPIClient, ClientAPIException
|
4
|
+
from ibm_watsonx_orchestrate.client.client_errors import MissingArgument
|
5
|
+
|
6
|
+
import logging
|
7
|
+
logger = logging.getLogger(__name__)
|
8
|
+
|
9
|
+
class VoiceConfigurationsClient(BaseAPIClient):
|
10
|
+
|
11
|
+
def create(self, voice_config: VoiceConfiguration) -> dict:
|
12
|
+
return self._post("/voice_configurations", data=voice_config.model_dump(exclude_none=True))
|
13
|
+
|
14
|
+
|
15
|
+
def update(self, voice_config_id: str, voice_config: VoiceConfiguration) -> dict:
|
16
|
+
if voice_config_id in [None,""]:
|
17
|
+
raise MissingArgument("voice_config_id")
|
18
|
+
return self._patch(f"/voice_configurations/{voice_config_id}", data=voice_config.model_dump(exclude_none=True))
|
19
|
+
|
20
|
+
|
21
|
+
def get_by_id(self, voice_config_id: str) -> dict | None:
|
22
|
+
if voice_config_id in [None,""]:
|
23
|
+
raise MissingArgument("voice_config_id")
|
24
|
+
|
25
|
+
try:
|
26
|
+
response = self._get(f"/voice_configurations/{voice_config_id}")
|
27
|
+
return VoiceConfiguration.model_validate(response)
|
28
|
+
|
29
|
+
except ClientAPIException as e:
|
30
|
+
if e.response.status_code == 404:
|
31
|
+
return None
|
32
|
+
raise e
|
33
|
+
|
34
|
+
except ValidationError as e:
|
35
|
+
logger.error("Recieved unexpected response from server")
|
36
|
+
raise e
|
37
|
+
|
38
|
+
def get_by_name(self, name: str) -> list[VoiceConfiguration]:
|
39
|
+
return self.get_by_names([name])
|
40
|
+
|
41
|
+
def get_by_names(self, names: list[str]) -> list[VoiceConfiguration]:
|
42
|
+
# server will implement query by name, below can be uncommented then
|
43
|
+
# formatted_config_names = [f"names={n}" for n in names]
|
44
|
+
# return self._get(f"/voice_configurations?{"&".join(formatted_config_names)}")
|
45
|
+
config_list = self.list()
|
46
|
+
filtered_list = [cfg for cfg in config_list if cfg.name in names]
|
47
|
+
|
48
|
+
try:
|
49
|
+
return [ VoiceConfiguration.model_validate(cfg) for cfg in filtered_list ]
|
50
|
+
except ValidationError as e:
|
51
|
+
logger.error("Recieved unexpected response from server")
|
52
|
+
raise e
|
53
|
+
|
54
|
+
|
55
|
+
|
56
|
+
|
57
|
+
def delete(self, voice_config_id: str) -> None:
|
58
|
+
if voice_config_id in [None,""]:
|
59
|
+
raise MissingArgument("voice_config_id")
|
60
|
+
self._delete(f"/voice_configurations/{voice_config_id}")
|
61
|
+
|
62
|
+
|
63
|
+
def list(self) -> list[dict]:
|
64
|
+
try:
|
65
|
+
response = self._get("/voice_configurations")
|
66
|
+
return [VoiceConfiguration.model_validate(x) for x in response.get('voice_configurations',[])]
|
67
|
+
|
68
|
+
except ClientAPIException as e:
|
69
|
+
if e.response.status_code == 404:
|
70
|
+
return []
|
71
|
+
raise e
|
72
|
+
|
73
|
+
except ValidationError as e:
|
74
|
+
logger.error("Recieved unexpected response from server")
|
75
|
+
raise e
|
@@ -102,6 +102,7 @@ services:
|
|
102
102
|
DISMISS_NOTIFICATION_TIMEOUT: 10000
|
103
103
|
STANDALONE: "true"
|
104
104
|
STREAM_TIMEOUT: ${STREAM_TIMEOUT:-120000}
|
105
|
+
WXO_VOICE_URL: http://localhost:9876/v1
|
105
106
|
command: "./StartServer.sh"
|
106
107
|
ports:
|
107
108
|
- "3000:4002"
|
@@ -342,6 +343,7 @@ services:
|
|
342
343
|
AGENTOPS_API_KEY_AUTH_ENABLED: ${AGENTOPS_API_KEY_AUTH_ENABLED:-false}
|
343
344
|
AGENTOPS_API_KEY: ${AGENTOPS_API_KEY}
|
344
345
|
ES_HOST: http://elasticsearch:9200
|
346
|
+
ORIGIN_HEADER: "internal"
|
345
347
|
|
346
348
|
wxo-server-worker:
|
347
349
|
image: ${WORKER_REGISTRY:-us.icr.io/watson-orchestrate-private}/wxo-server-conversation_controller:${WORKER_TAG:-latest}
|
@@ -517,7 +519,7 @@ services:
|
|
517
519
|
# IBM AGENT-OPS
|
518
520
|
########################
|
519
521
|
elasticsearch:
|
520
|
-
image: docker.elastic.co/elasticsearch/elasticsearch:8.
|
522
|
+
image: docker.elastic.co/elasticsearch/elasticsearch:8.19.0
|
521
523
|
profiles: [ibm-telemetry]
|
522
524
|
environment:
|
523
525
|
- discovery.type=single-node
|
@@ -794,6 +796,7 @@ services:
|
|
794
796
|
WO_INSTANCE: ${WO_INSTANCE}
|
795
797
|
AUTHORIZATION_URL: ${AUTHORIZATION_URL}
|
796
798
|
WO_AUTH_TYPE: ${WO_AUTH_TYPE}
|
799
|
+
FLOW_CALLBACK_REQUEST_RETRIES: "1"
|
797
800
|
healthcheck:
|
798
801
|
test: curl -k http://localhost:9044/readiness --fail
|
799
802
|
interval: 30s
|
@@ -1092,6 +1095,17 @@ services:
|
|
1092
1095
|
exit 0;
|
1093
1096
|
"
|
1094
1097
|
|
1098
|
+
wxo-server-voice:
|
1099
|
+
image: ${VOICE_CONTROLLER_REGISTRY:-us.icr.io/watson-orchestrate-private}/wxo-server-voice:${VOICE_CONTROLLER_TAG:-latest}
|
1100
|
+
profiles: [voice]
|
1101
|
+
restart: unless-stopped
|
1102
|
+
ports:
|
1103
|
+
- 9876:8765
|
1104
|
+
environment:
|
1105
|
+
WXO_BASE_DOMAIN_URL: "http://wxo-server:4321"
|
1106
|
+
AI_GATEWAY_URL: "http://ai-gateway:8787"
|
1107
|
+
WXO_ORIGIN_HEADER: "internal"
|
1108
|
+
|
1095
1109
|
volumes:
|
1096
1110
|
tools:
|
1097
1111
|
driver: local
|
@@ -57,10 +57,10 @@ EVENT_BROKER_TTL="3600"
|
|
57
57
|
REGISTRY_URL=
|
58
58
|
|
59
59
|
|
60
|
-
SERVER_TAG=
|
60
|
+
SERVER_TAG=13-08-2025-b01e43e00a7c900f92057d63520be08f965b6b24
|
61
61
|
SERVER_REGISTRY=
|
62
62
|
|
63
|
-
WORKER_TAG=
|
63
|
+
WORKER_TAG=13-08-2025-b01e43e00a7c900f92057d63520be08f965b6b24
|
64
64
|
WORKER_REGISTRY=
|
65
65
|
|
66
66
|
AI_GATEWAY_TAG=01-08-2025-v1
|
@@ -82,16 +82,16 @@ UITAG=31-07-2025
|
|
82
82
|
CM_REGISTRY=
|
83
83
|
CM_TAG=24-07-2025
|
84
84
|
|
85
|
-
TRM_TAG=
|
85
|
+
TRM_TAG=12-08-2025-5f816b3d5981afdd65fa55401d70e5aa5f734fc4
|
86
86
|
TRM_REGISTRY=
|
87
87
|
|
88
|
-
TR_TAG=
|
88
|
+
TR_TAG=14-08-2025-7b2f9c9
|
89
89
|
TR_REGISTRY=
|
90
90
|
|
91
|
-
BUILDER_TAG=
|
91
|
+
BUILDER_TAG=12-08-2025-8f00997
|
92
92
|
BUILDER_REGISTRY=
|
93
93
|
|
94
|
-
FLOW_RUNTIME_TAG=
|
94
|
+
FLOW_RUNTIME_TAG=11-08-2025
|
95
95
|
FLOW_RUMTIME_REGISTRY=
|
96
96
|
|
97
97
|
|
@@ -107,6 +107,9 @@ SOCKET_HANDLER_REGISTRY=
|
|
107
107
|
CPE_TAG=06-08-2025-b0a20ad
|
108
108
|
CPE_REGISTRY=
|
109
109
|
|
110
|
+
VOICE_CONTROLLER_TAG=12-08-2025
|
111
|
+
VOICE_CONTROLLER_REGISTRY=
|
112
|
+
|
110
113
|
# IBM Document Processing
|
111
114
|
WDU_TAG=2.5.0
|
112
115
|
WDU_REGISTRY=
|
@@ -115,6 +115,10 @@ class Flow(Node):
|
|
115
115
|
# we need a deep compare if the incoming schema and existing_schema is the same
|
116
116
|
# pydantic suppport nested comparison by default
|
117
117
|
|
118
|
+
if isinstance(schema, dict):
|
119
|
+
# recast schema to support direct access
|
120
|
+
schema = JsonSchemaObject.model_validate(schema)
|
121
|
+
|
118
122
|
schema.title = title
|
119
123
|
|
120
124
|
if schema == existing_schema:
|
@@ -199,30 +203,31 @@ class Flow(Node):
|
|
199
203
|
self._refactor_spec_to_schemaref(node.spec)
|
200
204
|
|
201
205
|
def _refactor_spec_to_schemaref(self, spec: NodeSpec):
|
202
|
-
if spec.input_schema and (spec.input_schema.type == "object" or spec.input_schema.type == "array") :
|
206
|
+
if spec.input_schema and not isinstance(spec.input_schema, SchemaRef) and (spec.input_schema.type == "object" or spec.input_schema.type == "array") :
|
203
207
|
if isinstance(spec.input_schema, ToolRequestBody):
|
204
208
|
spec.input_schema = self._add_schema_ref(JsonSchemaObject(type = spec.input_schema.type,
|
205
209
|
properties= spec.input_schema.properties,
|
206
210
|
required= spec.input_schema.required),
|
207
211
|
f"{spec.name}_input")
|
208
|
-
if
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
if spec.output_schema
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
212
|
+
if not isinstance(spec.output_schema, SchemaRef):
|
213
|
+
if spec.output_schema_object is not None and spec.output_schema_object.type == "object":
|
214
|
+
spec.output_schema = self._add_schema_ref(spec.output_schema_object, spec.output_schema_object.title)
|
215
|
+
spec.output_schema_object = None
|
216
|
+
elif spec.output_schema is not None:
|
217
|
+
if isinstance(spec.output_schema, ToolResponseBody):
|
218
|
+
if spec.output_schema.type == "object":
|
219
|
+
json_obj = JsonSchemaObject(type = spec.output_schema.type,
|
220
|
+
description=spec.output_schema.description,
|
221
|
+
properties= spec.output_schema.properties,
|
222
|
+
items = spec.output_schema.items,
|
223
|
+
uniqueItems=spec.output_schema.uniqueItems,
|
224
|
+
anyOf=spec.output_schema.anyOf,
|
225
|
+
required= spec.output_schema.required)
|
226
|
+
spec.output_schema = self._add_schema_ref(json_obj, f"{spec.name}_output")
|
227
|
+
elif spec.output_schema.type == "array":
|
228
|
+
if hasattr(spec.output_schema, "items") and hasattr(spec.output_schema.items, "type") and spec.output_schema.items.type == "object":
|
229
|
+
schema_ref = self._add_schema_ref(spec.output_schema.items)
|
230
|
+
spec.output_schema.items = JsonSchemaObjectRef(ref=f"{schema_ref.ref}")
|
226
231
|
|
227
232
|
# def refactor_datamap_spec_to_schemaref(self, spec: FnDataMapSpec):
|
228
233
|
# '''TODO'''
|
{ibm_watsonx_orchestrate-1.9.0b2.dist-info → ibm_watsonx_orchestrate-1.10.0b0.dist-info}/RECORD
RENAMED
@@ -1,10 +1,10 @@
|
|
1
|
-
ibm_watsonx_orchestrate/__init__.py,sha256=
|
1
|
+
ibm_watsonx_orchestrate/__init__.py,sha256=CE0F2w_9jm2X8mCofA2JwrXdBnhedrW0zMrgrGnZNy8,429
|
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
|
5
5
|
ibm_watsonx_orchestrate/agent_builder/agents/assistant_agent.py,sha256=NnWThJ2N8HUOD9IDL6ZhtTKyLMHSacJCpxDNityRmgY,1051
|
6
6
|
ibm_watsonx_orchestrate/agent_builder/agents/external_agent.py,sha256=7HzEFjd7JiiRTgvA1RVA3M0-Mr42FTQnOtGMII5ufk0,1045
|
7
|
-
ibm_watsonx_orchestrate/agent_builder/agents/types.py,sha256=
|
7
|
+
ibm_watsonx_orchestrate/agent_builder/agents/types.py,sha256=al_nz27cPqD1QLnamMgd8mkgUiATECaEptKttlkf0wU,13108
|
8
8
|
ibm_watsonx_orchestrate/agent_builder/agents/webchat_customizations/__init__.py,sha256=5TXa8UqKUAlDo4hTbE5S9OPEkQhxXhPJHJC4pEe8U00,92
|
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
|
@@ -24,16 +24,18 @@ ibm_watsonx_orchestrate/agent_builder/tools/__init__.py,sha256=adkYX0wgB-RKFCUBw
|
|
24
24
|
ibm_watsonx_orchestrate/agent_builder/tools/base_tool.py,sha256=0vwMIAyKyB8v1QmNrubLy8Al58g3qT78EUgrmOjegoI,1220
|
25
25
|
ibm_watsonx_orchestrate/agent_builder/tools/flow_tool.py,sha256=DJWYVmIjw1O_cbzPpwU0a_vIZGvo0mj8UsjW9zkKMlA,2589
|
26
26
|
ibm_watsonx_orchestrate/agent_builder/tools/openapi_tool.py,sha256=h9ma18GUQHt88UIakd6QZHic822bAXzYokh6sfqAMZk,19410
|
27
|
-
ibm_watsonx_orchestrate/agent_builder/tools/python_tool.py,sha256=
|
27
|
+
ibm_watsonx_orchestrate/agent_builder/tools/python_tool.py,sha256=cdgu-v1oRR9RUbMNKEklOzO1z3nNZpDZPSMwnJEvuIY,12533
|
28
28
|
ibm_watsonx_orchestrate/agent_builder/tools/types.py,sha256=m2t4uXNp0DVwVFzd0Jf_se8tz6V8FzM5fYgFs7AlvHU,8251
|
29
29
|
ibm_watsonx_orchestrate/agent_builder/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
30
|
+
ibm_watsonx_orchestrate/agent_builder/voice_configurations/__init__.py,sha256=W3-T8PH_KuONsCQPILQAvW2Nz25p7dp9AZbWHWGJXhA,37
|
31
|
+
ibm_watsonx_orchestrate/agent_builder/voice_configurations/types.py,sha256=lSS1yiDzVAMkEdOwcI4_1DUuRnu_6oc8XupQtoE4Fvs,3989
|
30
32
|
ibm_watsonx_orchestrate/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
31
33
|
ibm_watsonx_orchestrate/cli/config.py,sha256=iXjDxymWhAmLSUu6eh7zJR20dYZDzbxcU5VoBdh3VIw,8318
|
32
34
|
ibm_watsonx_orchestrate/cli/init_helper.py,sha256=qxnKdFcPtGsV_6RqP_IuLshRxgB004SxzDAkBTExA-4,1675
|
33
|
-
ibm_watsonx_orchestrate/cli/main.py,sha256=
|
35
|
+
ibm_watsonx_orchestrate/cli/main.py,sha256=Jrp0d40-RAtpzsGnf45dpPxJi3d7snod5BCnFMh4foU,3384
|
34
36
|
ibm_watsonx_orchestrate/cli/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
35
|
-
ibm_watsonx_orchestrate/cli/commands/agents/agents_command.py,sha256=
|
36
|
-
ibm_watsonx_orchestrate/cli/commands/agents/agents_controller.py,sha256=
|
37
|
+
ibm_watsonx_orchestrate/cli/commands/agents/agents_command.py,sha256=sC3kRKO5ZvDGUSy5CBnS3C-qU6bG9kxG-u42KcpVYuQ,9574
|
38
|
+
ibm_watsonx_orchestrate/cli/commands/agents/agents_controller.py,sha256=W1xeg4UQZ5fEudlvYfppw9PyfwTcQq-woWpHPZorUPc,55704
|
37
39
|
ibm_watsonx_orchestrate/cli/commands/channels/channels_command.py,sha256=fVIFhPUTPdxsxIE10nWL-W5wvBR-BS8V8D6r__J8R98,822
|
38
40
|
ibm_watsonx_orchestrate/cli/commands/channels/channels_controller.py,sha256=WjQxwJujvo28SsWgfJSXIpkcgniKcskJ2arL4MOz0Ys,455
|
39
41
|
ibm_watsonx_orchestrate/cli/commands/channels/types.py,sha256=hMFvWPr7tAmDrhBqtzfkCsrubX3lsU6lapTSOFsUbHM,475
|
@@ -51,12 +53,12 @@ ibm_watsonx_orchestrate/cli/commands/environment/types.py,sha256=X6jEnyBdxakromA
|
|
51
53
|
ibm_watsonx_orchestrate/cli/commands/evaluations/evaluations_command.py,sha256=nOVxeZSTp1bfV_l_06B6x6wfNeusNAr5KImJYkwGWx8,14298
|
52
54
|
ibm_watsonx_orchestrate/cli/commands/evaluations/evaluations_controller.py,sha256=dZEAD0rIS9DQjWD2-i6367RjNd2PWB3Fm_DDk25toBg,7855
|
53
55
|
ibm_watsonx_orchestrate/cli/commands/knowledge_bases/knowledge_bases_command.py,sha256=hOzRcGVoqq7dTc4bSregKxH-kYbrVqaFdhBLawqnRNo,2668
|
54
|
-
ibm_watsonx_orchestrate/cli/commands/knowledge_bases/knowledge_bases_controller.py,sha256=
|
56
|
+
ibm_watsonx_orchestrate/cli/commands/knowledge_bases/knowledge_bases_controller.py,sha256=AyGc2JudpHaSf0ktHSVRkPVsaejWL8KH7Dv0XgEGZ1U,10531
|
55
57
|
ibm_watsonx_orchestrate/cli/commands/login/login_command.py,sha256=xArMiojoozg7Exn6HTpbTcjDO2idZRA-y0WV-_Ic1Sk,651
|
56
58
|
ibm_watsonx_orchestrate/cli/commands/models/model_provider_mapper.py,sha256=mbvBR5o9M7W6OpTZyd6TtSEOIXq07dPYz4hv5zDrsd0,8129
|
57
59
|
ibm_watsonx_orchestrate/cli/commands/models/models_command.py,sha256=PW-PIM5Nq0qdCopWjANGBWEuEoA3NLTFThYrN8ggGCI,6425
|
58
60
|
ibm_watsonx_orchestrate/cli/commands/models/models_controller.py,sha256=eZSYQUg9TL_-8lgcPVpKIx7MtOE7K_NCvZW9Y9YsFA0,18466
|
59
|
-
ibm_watsonx_orchestrate/cli/commands/server/server_command.py,sha256=
|
61
|
+
ibm_watsonx_orchestrate/cli/commands/server/server_command.py,sha256=VhNfBPVXtTjMt-wKLtlXhWu5YB9TQ7BTnBrxWUDZdU4,43636
|
60
62
|
ibm_watsonx_orchestrate/cli/commands/server/types.py,sha256=UCrgGErbSVBnOzesfjrIii4tTCuVfWemYz5AKGZX0oA,4213
|
61
63
|
ibm_watsonx_orchestrate/cli/commands/settings/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
62
64
|
ibm_watsonx_orchestrate/cli/commands/settings/settings_command.py,sha256=CzXRkd-97jXyS6LtaaNtMah-aZu0919dYl-mDwzGThc,344
|
@@ -67,8 +69,10 @@ ibm_watsonx_orchestrate/cli/commands/settings/observability/langfuse/langfuse_co
|
|
67
69
|
ibm_watsonx_orchestrate/cli/commands/toolkit/toolkit_command.py,sha256=KI96Yexq4ZkM-VxcW88oMszjnOxbdU7quSxFtvf_ry4,4367
|
68
70
|
ibm_watsonx_orchestrate/cli/commands/toolkit/toolkit_controller.py,sha256=3Jykp5-DzMM_At8kYJto171V6LesaqKdsk2nfg1TRpk,11949
|
69
71
|
ibm_watsonx_orchestrate/cli/commands/tools/tools_command.py,sha256=Cuo1ZvlfsymojqbadCqdwwS0HUjaWpe2XQrV70g61_s,3943
|
70
|
-
ibm_watsonx_orchestrate/cli/commands/tools/tools_controller.py,sha256=
|
72
|
+
ibm_watsonx_orchestrate/cli/commands/tools/tools_controller.py,sha256=_iXQx_Ycno4bpgI0HuJNsf2yYNP_8o6AOCUlBavBHEE,40720
|
71
73
|
ibm_watsonx_orchestrate/cli/commands/tools/types.py,sha256=_md0GEa_cTH17NO_moWDY_LNdFvyEFQ1UVB9_FltYiA,173
|
74
|
+
ibm_watsonx_orchestrate/cli/commands/voice_configurations/voice_configurations_command.py,sha256=q4KHWQ-LZbp31e2ytihX1OuyAPS4-nRinmc-eMXC0l0,1783
|
75
|
+
ibm_watsonx_orchestrate/cli/commands/voice_configurations/voice_configurations_controller.py,sha256=JbAc_CY0woHY8u7qrnOcb9O2FgECzkzeMirxFhRoep8,5884
|
72
76
|
ibm_watsonx_orchestrate/client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
73
77
|
ibm_watsonx_orchestrate/client/base_api_client.py,sha256=cSbQb7-K9KoMeFLEIiYGho4cQqf8TcPyYklju9X4cC4,5214
|
74
78
|
ibm_watsonx_orchestrate/client/base_service_instance.py,sha256=sM_r7bln9BpgEOhaJMdFI9-je3T7GLQxLduk-in0oRY,235
|
@@ -78,7 +82,7 @@ ibm_watsonx_orchestrate/client/credentials.py,sha256=gDVeeQZDdbbjJiO1EI61yx2oRgT
|
|
78
82
|
ibm_watsonx_orchestrate/client/local_service_instance.py,sha256=dt7vfLnjgt7mT8wSq8SJZndNTwsPzhb0XDhcnPUPFpU,3524
|
79
83
|
ibm_watsonx_orchestrate/client/service_instance.py,sha256=fp3Lc4yQf4zTkxVS5WnIAkrHT0xG_a5i44qcLeQkaa4,6600
|
80
84
|
ibm_watsonx_orchestrate/client/utils.py,sha256=MUw11r0_wYv3RdF6-1BmSxcwYNF6q2_Urte7tMYTKVA,5836
|
81
|
-
ibm_watsonx_orchestrate/client/agents/agent_client.py,sha256=
|
85
|
+
ibm_watsonx_orchestrate/client/agents/agent_client.py,sha256=ObAoh5g4zvB1mZiA6xotvs4b1FGE1r92kkb2C7juGn8,6890
|
82
86
|
ibm_watsonx_orchestrate/client/agents/assistant_agent_client.py,sha256=1JQN0E4T_uz5V0LM-LD1ahNu2KCeFBjXAr8WCiP9mkE,1745
|
83
87
|
ibm_watsonx_orchestrate/client/agents/external_agent_client.py,sha256=iQ44XBdC4rYfS-zFn4St1xC5y5gf5SNqKHzMNQcFDZc,1808
|
84
88
|
ibm_watsonx_orchestrate/client/analytics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -96,8 +100,9 @@ ibm_watsonx_orchestrate/client/models/models_client.py,sha256=ZvP3iPgUFw_SXp41kJ
|
|
96
100
|
ibm_watsonx_orchestrate/client/toolkit/toolkit_client.py,sha256=TLFNS39EeBD_t4Y-rX9sGp4sWBDr--mE5qVtHq8Q2hk,3121
|
97
101
|
ibm_watsonx_orchestrate/client/tools/tempus_client.py,sha256=24fKDZUOVHBW-Vj4mubnpnUmab5LgGn8u5hOVyJaozI,1804
|
98
102
|
ibm_watsonx_orchestrate/client/tools/tool_client.py,sha256=d3i3alVwa0TCN72w9sWOrM20GCbNmnpTnqEOJVbBIFM,1994
|
99
|
-
ibm_watsonx_orchestrate/
|
100
|
-
ibm_watsonx_orchestrate/docker/
|
103
|
+
ibm_watsonx_orchestrate/client/voice_configurations/voice_configurations_client.py,sha256=M5xIPLiVNpP-zxQw8CTNT9AiBjeXXmJiNaE142e2A3E,2682
|
104
|
+
ibm_watsonx_orchestrate/docker/compose-lite.yml,sha256=LdAwhDdslZ5SHxV5CGRjJliEeAfuk6N8a_Xv-4QWSNc,44133
|
105
|
+
ibm_watsonx_orchestrate/docker/default.env,sha256=13lliXku5OQsZo2vRPEv6ev0k6GpVRErRQKWNY_o6IY,6234
|
101
106
|
ibm_watsonx_orchestrate/docker/proxy-config-single.yaml,sha256=WEbK4ENFuTCYhzRu_QblWp1_GMARgZnx5vReQafkIG8,308
|
102
107
|
ibm_watsonx_orchestrate/docker/start-up.sh,sha256=LTtwHp0AidVgjohis2LXGvZnkFQStOiUAxgGABOyeUI,1811
|
103
108
|
ibm_watsonx_orchestrate/docker/sdk/ibm_watsonx_orchestrate-0.6.0-py3-none-any.whl,sha256=Hi3-owh5OM0Jz2ihX9nLoojnr7Ky1TV-GelyqLcewLE,2047417
|
@@ -112,7 +117,7 @@ ibm_watsonx_orchestrate/flow_builder/flows/__init__.py,sha256=jbCklY7l08KG8cbFih
|
|
112
117
|
ibm_watsonx_orchestrate/flow_builder/flows/constants.py,sha256=-TGneZyjA4YiAtJJK7OmmjDHYQC4mw2e98MPAZqiB50,324
|
113
118
|
ibm_watsonx_orchestrate/flow_builder/flows/decorators.py,sha256=lr4qSWq5PWqlGFf4fzUQZCVQDHBYflrYwZ24S89Aq80,2794
|
114
119
|
ibm_watsonx_orchestrate/flow_builder/flows/events.py,sha256=VyaBm0sADwr15LWfKbcBQS1M80NKqzYDj3UlW3OpOf4,2984
|
115
|
-
ibm_watsonx_orchestrate/flow_builder/flows/flow.py,sha256=
|
120
|
+
ibm_watsonx_orchestrate/flow_builder/flows/flow.py,sha256=WPAdXML0o9RuHZE0ajBBOrorS6YmJd8RhV3-FMbDifM,57304
|
116
121
|
ibm_watsonx_orchestrate/run/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
117
122
|
ibm_watsonx_orchestrate/run/connections.py,sha256=K-65GXPA8GEsVmRdPfMe_LB2G9RfXQUr95wvRUOhkS4,1828
|
118
123
|
ibm_watsonx_orchestrate/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -121,8 +126,8 @@ ibm_watsonx_orchestrate/utils/utils.py,sha256=U7z_2iASoFiZ2zM0a_2Mc2Y-P5oOT7hOwu
|
|
121
126
|
ibm_watsonx_orchestrate/utils/logging/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
122
127
|
ibm_watsonx_orchestrate/utils/logging/logger.py,sha256=FzeGnidXAjC7yHrvIaj4KZPeaBBSCniZFlwgr5yV3oA,1037
|
123
128
|
ibm_watsonx_orchestrate/utils/logging/logging.yaml,sha256=9_TKfuFr1barnOKP0fZT5D6MhddiwsXVTFjtRbcOO5w,314
|
124
|
-
ibm_watsonx_orchestrate-1.
|
125
|
-
ibm_watsonx_orchestrate-1.
|
126
|
-
ibm_watsonx_orchestrate-1.
|
127
|
-
ibm_watsonx_orchestrate-1.
|
128
|
-
ibm_watsonx_orchestrate-1.
|
129
|
+
ibm_watsonx_orchestrate-1.10.0b0.dist-info/METADATA,sha256=j9LQ4nwtXYKwZJGT48LSfws9sC84DZ9tHXHki4E-a9s,1363
|
130
|
+
ibm_watsonx_orchestrate-1.10.0b0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
131
|
+
ibm_watsonx_orchestrate-1.10.0b0.dist-info/entry_points.txt,sha256=SfIT02-Jen5e99OcLhzbcM9Bdyf8SGVOCtnSplgZdQI,69
|
132
|
+
ibm_watsonx_orchestrate-1.10.0b0.dist-info/licenses/LICENSE,sha256=Shgxx7hTdCOkiVRmfGgp_1ISISrwQD7m2f0y8Hsapl4,1083
|
133
|
+
ibm_watsonx_orchestrate-1.10.0b0.dist-info/RECORD,,
|
{ibm_watsonx_orchestrate-1.9.0b2.dist-info → ibm_watsonx_orchestrate-1.10.0b0.dist-info}/WHEEL
RENAMED
File without changes
|
File without changes
|
File without changes
|