ibm-watsonx-orchestrate 1.9.0b1__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/knowledge_bases/types.py +2 -2
- ibm_watsonx_orchestrate/agent_builder/models/types.py +5 -0
- ibm_watsonx_orchestrate/agent_builder/tools/python_tool.py +19 -7
- ibm_watsonx_orchestrate/agent_builder/tools/types.py +5 -3
- 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/connections/connections_controller.py +5 -2
- ibm_watsonx_orchestrate/cli/commands/copilot/copilot_controller.py +103 -20
- ibm_watsonx_orchestrate/cli/commands/knowledge_bases/knowledge_bases_controller.py +19 -12
- ibm_watsonx_orchestrate/cli/commands/models/model_provider_mapper.py +17 -13
- ibm_watsonx_orchestrate/cli/commands/server/server_command.py +17 -4
- ibm_watsonx_orchestrate/cli/commands/tools/tools_controller.py +6 -1
- 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/connections/connections_client.py +14 -2
- ibm_watsonx_orchestrate/client/copilot/cpe/copilot_cpe_client.py +5 -3
- ibm_watsonx_orchestrate/client/voice_configurations/voice_configurations_client.py +75 -0
- ibm_watsonx_orchestrate/docker/compose-lite.yml +23 -2
- ibm_watsonx_orchestrate/docker/default.env +16 -12
- ibm_watsonx_orchestrate/flow_builder/flows/__init__.py +2 -2
- ibm_watsonx_orchestrate/flow_builder/flows/flow.py +29 -24
- ibm_watsonx_orchestrate/flow_builder/types.py +109 -17
- ibm_watsonx_orchestrate/flow_builder/utils.py +7 -3
- {ibm_watsonx_orchestrate-1.9.0b1.dist-info → ibm_watsonx_orchestrate-1.10.0b0.dist-info}/METADATA +1 -1
- {ibm_watsonx_orchestrate-1.9.0b1.dist-info → ibm_watsonx_orchestrate-1.10.0b0.dist-info}/RECORD +34 -29
- {ibm_watsonx_orchestrate-1.9.0b1.dist-info → ibm_watsonx_orchestrate-1.10.0b0.dist-info}/WHEEL +0 -0
- {ibm_watsonx_orchestrate-1.9.0b1.dist-info → ibm_watsonx_orchestrate-1.10.0b0.dist-info}/entry_points.txt +0 -0
- {ibm_watsonx_orchestrate-1.9.0b1.dist-info → ibm_watsonx_orchestrate-1.10.0b0.dist-info}/licenses/LICENSE +0 -0
@@ -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
|
|
@@ -3,6 +3,7 @@ from typing import List
|
|
3
3
|
from ibm_cloud_sdk_core.authenticators import MCSPAuthenticator
|
4
4
|
from pydantic import BaseModel, ValidationError
|
5
5
|
from typing import Optional
|
6
|
+
from enum import Enum
|
6
7
|
|
7
8
|
from ibm_watsonx_orchestrate.client.base_api_client import BaseAPIClient, ClientAPIException
|
8
9
|
from ibm_watsonx_orchestrate.agent_builder.connections.types import ConnectionEnvironment, ConnectionPreference, ConnectionAuthType, ConnectionSecurityScheme, IdpConfigData, AppConfigData, ConnectionType
|
@@ -12,12 +13,23 @@ import logging
|
|
12
13
|
logger = logging.getLogger(__name__)
|
13
14
|
|
14
15
|
|
16
|
+
class FetchConfigAuthTypes(str, Enum):
|
17
|
+
BASIC_AUTH = ConnectionType.BASIC_AUTH.value
|
18
|
+
BEARER_TOKEN = ConnectionType.BEARER_TOKEN.value
|
19
|
+
API_KEY_AUTH = ConnectionType.API_KEY_AUTH.value
|
20
|
+
OAUTH2_AUTH_CODE = ConnectionType.OAUTH2_AUTH_CODE.value
|
21
|
+
OAUTH2_IMPLICIT = 'oauth2_implicit'
|
22
|
+
OAUTH2_PASSWORD = 'oauth2_password'
|
23
|
+
OAUTH2_CLIENT_CREDS = ConnectionType.OAUTH2_CLIENT_CREDS.value
|
24
|
+
OAUTH_ON_BEHALF_OF_FLOW = ConnectionType.OAUTH_ON_BEHALF_OF_FLOW.value
|
25
|
+
KEY_VALUE = ConnectionType.KEY_VALUE.value
|
26
|
+
|
15
27
|
class ListConfigsResponse(BaseModel):
|
16
28
|
connection_id: str = None,
|
17
29
|
app_id: str = None
|
18
30
|
name: str = None
|
19
31
|
security_scheme: ConnectionSecurityScheme | None = None,
|
20
|
-
auth_type:
|
32
|
+
auth_type: FetchConfigAuthTypes | None = None,
|
21
33
|
environment: ConnectionEnvironment | None = None,
|
22
34
|
preference: ConnectionPreference | None = None,
|
23
35
|
credentials_entered: bool | None = False
|
@@ -28,7 +40,7 @@ class GetConfigResponse(BaseModel):
|
|
28
40
|
app_id: str = None
|
29
41
|
environment: ConnectionEnvironment = None
|
30
42
|
preference: ConnectionPreference = None
|
31
|
-
auth_type:
|
43
|
+
auth_type: FetchConfigAuthTypes | None = None
|
32
44
|
sso: bool = None
|
33
45
|
security_scheme: ConnectionSecurityScheme = None
|
34
46
|
server_url: str | None = None
|
@@ -21,13 +21,15 @@ class CPEClient(BaseAPIClient):
|
|
21
21
|
}
|
22
22
|
|
23
23
|
|
24
|
-
def submit_pre_cpe_chat(self, user_message: str | None =None, tools: Dict[str, Any] = None,
|
24
|
+
def submit_pre_cpe_chat(self, user_message: str | None =None, tools: Dict[str, Any] = None, collaborators: Dict[str, Any] = None, knowledge_bases: Dict[str, Any] = None, selected:bool=False) -> dict:
|
25
25
|
payload = {
|
26
26
|
"message": user_message,
|
27
27
|
"tools": tools,
|
28
|
-
"
|
28
|
+
"collaborators": collaborators,
|
29
|
+
"knowledge_bases": knowledge_bases,
|
29
30
|
"chat_id": self.chat_id,
|
30
|
-
"chat_model_name": self.chat_model_name
|
31
|
+
"chat_model_name": self.chat_model_name,
|
32
|
+
'selected':selected
|
31
33
|
}
|
32
34
|
|
33
35
|
response = self._post_nd_json("/wxo-cpe/create-agent", data=payload)
|
@@ -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"
|
@@ -122,6 +123,11 @@ services:
|
|
122
123
|
CONNECTIONS_MANAGER_ENDPOINT: http://wxo-server-connection-manager:3001
|
123
124
|
AGENT_OPS_API_KEY: ${AGENTOPS_API_KEY}
|
124
125
|
AGENTS_OPS_RUNTIME_ENDPOINT: https://frontend-server:443
|
126
|
+
DPI_WO_WDU_SERVER_ENDPOINT: https://wxo-doc-processing-service:8080
|
127
|
+
DPI_RAG_SERVER_ENDPOINT: https://wxo-doc-processing-llm-service:8083
|
128
|
+
IBM_DPS_CACHE_SERVICE: https://wxo-doc-processing-cache:8080
|
129
|
+
DOCPROC_BASE_URL: http://wxo-doc-processing-infra-standalone:9080
|
130
|
+
BUILDER_ASYNC_CALLBACK_ENDPOINT: http://wxo-builder:4025
|
125
131
|
IS_OBSERVABILITY_FEATURE_ENABLED: "true"
|
126
132
|
ALLOW_INSECURE_TLS: "true"
|
127
133
|
command: 'npm start'
|
@@ -165,7 +171,7 @@ services:
|
|
165
171
|
"
|
166
172
|
|
167
173
|
wxo-milvus-standalone:
|
168
|
-
image: ${OPENSOURCE_REGISTRY_PROXY:-docker.io}/milvusdb/milvus:v2.5.
|
174
|
+
image: ${OPENSOURCE_REGISTRY_PROXY:-docker.io}/milvusdb/milvus:v2.5.15
|
169
175
|
command: ["milvus", "run", "standalone"]
|
170
176
|
security_opt:
|
171
177
|
- seccomp:unconfined
|
@@ -337,6 +343,7 @@ services:
|
|
337
343
|
AGENTOPS_API_KEY_AUTH_ENABLED: ${AGENTOPS_API_KEY_AUTH_ENABLED:-false}
|
338
344
|
AGENTOPS_API_KEY: ${AGENTOPS_API_KEY}
|
339
345
|
ES_HOST: http://elasticsearch:9200
|
346
|
+
ORIGIN_HEADER: "internal"
|
340
347
|
|
341
348
|
wxo-server-worker:
|
342
349
|
image: ${WORKER_REGISTRY:-us.icr.io/watson-orchestrate-private}/wxo-server-conversation_controller:${WORKER_TAG:-latest}
|
@@ -512,7 +519,7 @@ services:
|
|
512
519
|
# IBM AGENT-OPS
|
513
520
|
########################
|
514
521
|
elasticsearch:
|
515
|
-
image: docker.elastic.co/elasticsearch/elasticsearch:8.
|
522
|
+
image: docker.elastic.co/elasticsearch/elasticsearch:8.19.0
|
516
523
|
profiles: [ibm-telemetry]
|
517
524
|
environment:
|
518
525
|
- discovery.type=single-node
|
@@ -549,6 +556,7 @@ services:
|
|
549
556
|
- TENANT_DEFAULT_PASSWORD=${ES_PASSWORD}
|
550
557
|
- TENANT_DEFAULT_HOSTNAME=http://elasticsearch:9200
|
551
558
|
- DEFAULT_TENANT_ID=${DEFAULT_TENANT_ID}
|
559
|
+
- FORCE_SINGLE_TENANT=${FORCE_SINGLE_TENANT:-true}
|
552
560
|
ports:
|
553
561
|
- "9202:9201" # Expose proxy on host port 9202
|
554
562
|
networks:
|
@@ -644,6 +652,7 @@ services:
|
|
644
652
|
- INBOUND_API_KEY=${AGENTOPS_API_KEY}
|
645
653
|
- DEFAULT_TENANT_ID=${DEFAULT_TENANT_ID}
|
646
654
|
- TENANT_DEFAULT_HOSTNAME=http://elasticsearch:9200
|
655
|
+
- FORCE_SINGLE_TENANT=${FORCE_SINGLE_TENANT:-true}
|
647
656
|
ports:
|
648
657
|
- "8765:443"
|
649
658
|
networks:
|
@@ -787,6 +796,7 @@ services:
|
|
787
796
|
WO_INSTANCE: ${WO_INSTANCE}
|
788
797
|
AUTHORIZATION_URL: ${AUTHORIZATION_URL}
|
789
798
|
WO_AUTH_TYPE: ${WO_AUTH_TYPE}
|
799
|
+
FLOW_CALLBACK_REQUEST_RETRIES: "1"
|
790
800
|
healthcheck:
|
791
801
|
test: curl -k http://localhost:9044/readiness --fail
|
792
802
|
interval: 30s
|
@@ -1085,6 +1095,17 @@ services:
|
|
1085
1095
|
exit 0;
|
1086
1096
|
"
|
1087
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
|
+
|
1088
1109
|
volumes:
|
1089
1110
|
tools:
|
1090
1111
|
driver: local
|
@@ -57,13 +57,13 @@ 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
|
-
AI_GATEWAY_TAG=
|
66
|
+
AI_GATEWAY_TAG=01-08-2025-v1
|
67
67
|
AI_GATEWAY_REGISTRY=
|
68
68
|
|
69
69
|
AGENT_GATEWAY_TAG=29-07-2025
|
@@ -77,36 +77,39 @@ AMDDBTAG=29-07-2025-9f3661b
|
|
77
77
|
ARM64DBTAG=29-07-2025-9f3661b
|
78
78
|
|
79
79
|
UI_REGISTRY=
|
80
|
-
UITAG=
|
80
|
+
UITAG=31-07-2025
|
81
81
|
|
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
|
|
98
|
-
AGENT_ANALYTICS_TAG=
|
98
|
+
AGENT_ANALYTICS_TAG=05-08-2025
|
99
99
|
AGENT_ANALYTICS_REGISTRY=
|
100
100
|
|
101
|
-
JAEGER_PROXY_TAG=
|
101
|
+
JAEGER_PROXY_TAG=23-07-2025
|
102
102
|
JAEGER_PROXY_REGISTRY=
|
103
103
|
|
104
104
|
SOCKET_HANDLER_TAG=29-05-2025
|
105
105
|
SOCKET_HANDLER_REGISTRY=
|
106
106
|
|
107
|
-
CPE_TAG=
|
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=
|
@@ -114,7 +117,7 @@ WDU_REGISTRY=
|
|
114
117
|
DOCPROC_DPS_TAG=20250721-164412-250-503756a
|
115
118
|
DOCPROC_LLMSERVICE_TAG=20250725-100249-111-51d3e51
|
116
119
|
DOCPROC_CACHE_TAG=20250723-100852-70-9edc1ab
|
117
|
-
DOCPROC_DPI_TAG=
|
120
|
+
DOCPROC_DPI_TAG=20250731-155328-257-06879e86
|
118
121
|
DOCPROC_REGISTRY=
|
119
122
|
|
120
123
|
# END -- IMAGE REGISTRIES AND TAGS
|
@@ -182,6 +185,7 @@ CALLBACK_HOST_URL=
|
|
182
185
|
|
183
186
|
AGENTOPS_API_KEY_AUTH_ENABLED=true
|
184
187
|
AGENTOPS_API_KEY=qwertyuiop
|
188
|
+
FORCE_SINGLE_TENANT=true
|
185
189
|
|
186
190
|
RUNTIME_MANAGER_API_KEY=example
|
187
191
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
from .constants import START, END, RESERVED
|
2
2
|
|
3
|
-
from ..types import FlowContext, TaskData, TaskEventType,
|
3
|
+
from ..types import FlowContext, TaskData, TaskEventType, DocProcInput, DecisionsCondition, DecisionsRule
|
4
4
|
from ..node import UserNode, AgentNode, StartNode, EndNode, PromptNode, ToolNode, DecisionsNode
|
5
5
|
|
6
6
|
from .flow import Flow, CompiledFlow, FlowRun, FlowEvent, FlowEventType, FlowFactory, MatchPolicy, WaitPolicy, ForeachPolicy, Branch, Foreach, Loop
|
@@ -16,7 +16,7 @@ __all__ = [
|
|
16
16
|
"FlowContext",
|
17
17
|
"TaskData",
|
18
18
|
"TaskEventType",
|
19
|
-
"
|
19
|
+
"DocProcInput",
|
20
20
|
|
21
21
|
"DocProcNode",
|
22
22
|
"UserNode",
|
@@ -18,7 +18,7 @@ import pytz
|
|
18
18
|
import os
|
19
19
|
|
20
20
|
from typing_extensions import Self
|
21
|
-
from pydantic import BaseModel, Field, SerializeAsAny, create_model
|
21
|
+
from pydantic import BaseModel, Field, SerializeAsAny, create_model, TypeAdapter
|
22
22
|
import yaml
|
23
23
|
from ibm_watsonx_orchestrate.agent_builder.tools.python_tool import PythonTool
|
24
24
|
from ibm_watsonx_orchestrate.client.tools.tool_client import ToolClient
|
@@ -27,7 +27,7 @@ from ibm_watsonx_orchestrate.client.utils import instantiate_client
|
|
27
27
|
from ..types import (
|
28
28
|
EndNodeSpec, Expression, ForeachPolicy, ForeachSpec, LoopSpec, BranchNodeSpec, MatchPolicy, PromptLLMParameters, PromptNodeSpec,
|
29
29
|
StartNodeSpec, ToolSpec, JsonSchemaObject, ToolRequestBody, ToolResponseBody, UserFieldKind, UserFieldOption, UserFlowSpec, UserNodeSpec, WaitPolicy,
|
30
|
-
DocProcSpec, TextExtractionResponse,
|
30
|
+
DocProcSpec, TextExtractionResponse, DocProcInput, DecisionsNodeSpec, DecisionsRule, DocExtSpec, File
|
31
31
|
)
|
32
32
|
from .constants import CURRENT_USER, START, END, ANY_USER
|
33
33
|
from ..node import (
|
@@ -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:
|
@@ -190,7 +194,7 @@ class Flow(Node):
|
|
190
194
|
|
191
195
|
def _add_schema_ref(self, schema: JsonSchemaObject, title: str = None) -> SchemaRef:
|
192
196
|
'''Create a schema reference'''
|
193
|
-
if schema and (schema.type == "object" or schema.type == "array"):
|
197
|
+
if schema and (schema.type == "object" or schema.type == "array" or schema.type == "string"):
|
194
198
|
new_schema = self._add_schema(schema, title)
|
195
199
|
return SchemaRef(ref=f"#/schemas/{new_schema.title}")
|
196
200
|
raise AssertionError(f"schema is not a complex object: {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:
|
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'''
|
@@ -535,7 +540,7 @@ class Flow(Node):
|
|
535
540
|
"text_extraction" : TextExtractionResponse
|
536
541
|
}
|
537
542
|
# create input spec
|
538
|
-
input_schema_obj = _get_json_schema_obj(parameter_name = "input", type_def =
|
543
|
+
input_schema_obj = _get_json_schema_obj(parameter_name = "input", type_def = DocProcInput)
|
539
544
|
output_schema_obj = _get_json_schema_obj("output", output_schema_dict[task])
|
540
545
|
if "$defs" in output_schema_obj.model_extra:
|
541
546
|
output_schema_obj.model_extra.pop("$defs")
|
@@ -1060,8 +1065,8 @@ class FlowFactory(BaseModel):
|
|
1060
1065
|
raise ValueError("Only functions with @flow_spec can be used to create a Flow specification.")
|
1061
1066
|
return Flow(spec = flow_spec)
|
1062
1067
|
|
1063
|
-
# create input spec
|
1064
1068
|
input_schema_obj = _get_json_schema_obj(parameter_name = "input", type_def = input_schema)
|
1069
|
+
# create input spec
|
1065
1070
|
output_schema_obj = _get_json_schema_obj("output", output_schema)
|
1066
1071
|
if initiators is None:
|
1067
1072
|
initiators = []
|