ibm-watsonx-orchestrate 1.12.0b0__py3-none-any.whl → 1.12.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ibm_watsonx_orchestrate/__init__.py +2 -1
- ibm_watsonx_orchestrate/agent_builder/agents/types.py +5 -5
- ibm_watsonx_orchestrate/agent_builder/models/types.py +1 -0
- ibm_watsonx_orchestrate/agent_builder/toolkits/base_toolkit.py +1 -1
- ibm_watsonx_orchestrate/agent_builder/tools/base_tool.py +1 -1
- ibm_watsonx_orchestrate/agent_builder/tools/langflow_tool.py +61 -1
- ibm_watsonx_orchestrate/agent_builder/tools/openapi_tool.py +6 -0
- ibm_watsonx_orchestrate/cli/commands/agents/agents_controller.py +2 -2
- ibm_watsonx_orchestrate/cli/commands/connections/connections_controller.py +2 -2
- ibm_watsonx_orchestrate/cli/commands/environment/environment_command.py +5 -1
- ibm_watsonx_orchestrate/cli/commands/environment/environment_controller.py +6 -3
- ibm_watsonx_orchestrate/cli/commands/evaluations/evaluations_command.py +3 -2
- ibm_watsonx_orchestrate/cli/commands/evaluations/evaluations_controller.py +1 -1
- ibm_watsonx_orchestrate/cli/commands/models/model_provider_mapper.py +23 -4
- ibm_watsonx_orchestrate/cli/commands/partners/offering/partners_offering_controller.py +21 -4
- ibm_watsonx_orchestrate/cli/commands/partners/offering/types.py +7 -15
- ibm_watsonx_orchestrate/cli/commands/partners/partners_command.py +1 -1
- ibm_watsonx_orchestrate/cli/commands/server/server_command.py +11 -3
- ibm_watsonx_orchestrate/cli/commands/toolkit/toolkit_command.py +2 -2
- ibm_watsonx_orchestrate/cli/commands/tools/tools_controller.py +37 -8
- ibm_watsonx_orchestrate/cli/config.py +3 -1
- ibm_watsonx_orchestrate/docker/compose-lite.yml +56 -6
- ibm_watsonx_orchestrate/docker/default.env +19 -16
- ibm_watsonx_orchestrate/flow_builder/flows/decorators.py +10 -2
- ibm_watsonx_orchestrate/flow_builder/flows/flow.py +71 -9
- ibm_watsonx_orchestrate/flow_builder/node.py +14 -2
- ibm_watsonx_orchestrate/flow_builder/types.py +36 -3
- ibm_watsonx_orchestrate/langflow/__init__.py +0 -0
- ibm_watsonx_orchestrate/langflow/langflow_utils.py +195 -0
- ibm_watsonx_orchestrate/langflow/lfx_deps.py +84 -0
- ibm_watsonx_orchestrate/utils/utils.py +6 -2
- {ibm_watsonx_orchestrate-1.12.0b0.dist-info → ibm_watsonx_orchestrate-1.12.1.dist-info}/METADATA +2 -2
- {ibm_watsonx_orchestrate-1.12.0b0.dist-info → ibm_watsonx_orchestrate-1.12.1.dist-info}/RECORD +36 -33
- {ibm_watsonx_orchestrate-1.12.0b0.dist-info → ibm_watsonx_orchestrate-1.12.1.dist-info}/WHEEL +0 -0
- {ibm_watsonx_orchestrate-1.12.0b0.dist-info → ibm_watsonx_orchestrate-1.12.1.dist-info}/entry_points.txt +0 -0
- {ibm_watsonx_orchestrate-1.12.0b0.dist-info → ibm_watsonx_orchestrate-1.12.1.dist-info}/licenses/LICENSE +0 -0
@@ -11,7 +11,7 @@ import zipfile
|
|
11
11
|
from enum import Enum
|
12
12
|
from os import path
|
13
13
|
from pathlib import Path
|
14
|
-
from typing import Iterable, List
|
14
|
+
from typing import Iterable, List, cast
|
15
15
|
import rich
|
16
16
|
import json
|
17
17
|
from rich.json import JSON
|
@@ -25,7 +25,7 @@ from rich.panel import Panel
|
|
25
25
|
|
26
26
|
from ibm_watsonx_orchestrate.agent_builder.tools import BaseTool, ToolSpec
|
27
27
|
from ibm_watsonx_orchestrate.agent_builder.tools.flow_tool import create_flow_json_tool
|
28
|
-
from ibm_watsonx_orchestrate.agent_builder.tools.langflow_tool import create_langflow_tool
|
28
|
+
from ibm_watsonx_orchestrate.agent_builder.tools.langflow_tool import LangflowTool, create_langflow_tool
|
29
29
|
from ibm_watsonx_orchestrate.agent_builder.tools.openapi_tool import create_openapi_json_tools_from_uri,create_openapi_json_tools_from_content
|
30
30
|
from ibm_watsonx_orchestrate.cli.commands.models.models_controller import ModelHighlighter
|
31
31
|
from ibm_watsonx_orchestrate.cli.commands.tools.types import RegistryType
|
@@ -33,7 +33,7 @@ from ibm_watsonx_orchestrate.cli.commands.connections.connections_controller imp
|
|
33
33
|
from ibm_watsonx_orchestrate.agent_builder.connections.types import ConnectionType, ConnectionEnvironment, ConnectionPreference
|
34
34
|
from ibm_watsonx_orchestrate.cli.config import Config, CONTEXT_SECTION_HEADER, CONTEXT_ACTIVE_ENV_OPT, \
|
35
35
|
PYTHON_REGISTRY_HEADER, PYTHON_REGISTRY_TYPE_OPT, PYTHON_REGISTRY_TEST_PACKAGE_VERSION_OVERRIDE_OPT, \
|
36
|
-
DEFAULT_CONFIG_FILE_CONTENT
|
36
|
+
DEFAULT_CONFIG_FILE_CONTENT, PYTHON_REGISTRY_SKIP_VERSION_CHECK_OPT
|
37
37
|
from ibm_watsonx_orchestrate.agent_builder.connections import ConnectionSecurityScheme, ExpectedCredentials
|
38
38
|
from ibm_watsonx_orchestrate.flow_builder.flows.decorators import FlowWrapper
|
39
39
|
from ibm_watsonx_orchestrate.client.tools.tool_client import ToolClient
|
@@ -56,6 +56,11 @@ DEFAULT_LANGFLOW_TOOL_REQUIREMENTS = [
|
|
56
56
|
"lfx==0.1.8"
|
57
57
|
]
|
58
58
|
|
59
|
+
DEFAULT_LANGFLOW_RUNNER_MODULES = [
|
60
|
+
"lfx",
|
61
|
+
"lfx-nightly"
|
62
|
+
]
|
63
|
+
|
59
64
|
class ToolKind(str, Enum):
|
60
65
|
openapi = "openapi"
|
61
66
|
python = "python"
|
@@ -851,15 +856,18 @@ class ToolsController:
|
|
851
856
|
|
852
857
|
cfg = Config()
|
853
858
|
registry_type = cfg.read(PYTHON_REGISTRY_HEADER, PYTHON_REGISTRY_TYPE_OPT) or DEFAULT_CONFIG_FILE_CONTENT[PYTHON_REGISTRY_HEADER][PYTHON_REGISTRY_TYPE_OPT]
|
859
|
+
skip_version_check = cfg.read(PYTHON_REGISTRY_HEADER, PYTHON_REGISTRY_SKIP_VERSION_CHECK_OPT) or DEFAULT_CONFIG_FILE_CONTENT[PYTHON_REGISTRY_HEADER][PYTHON_REGISTRY_SKIP_VERSION_CHECK_OPT]
|
854
860
|
|
855
861
|
version = __version__
|
856
862
|
if registry_type == RegistryType.LOCAL:
|
863
|
+
logger.warning(f"Using a local registry which is for development purposes only")
|
857
864
|
requirements.append(f"/packages/ibm_watsonx_orchestrate-0.6.0-py3-none-any.whl\n")
|
858
865
|
elif registry_type == RegistryType.PYPI:
|
859
|
-
|
860
|
-
|
861
|
-
|
862
|
-
|
866
|
+
if not skip_version_check:
|
867
|
+
wheel_file = get_whl_in_registry(registry_url='https://pypi.org/simple/ibm-watsonx-orchestrate', version=version)
|
868
|
+
if not wheel_file:
|
869
|
+
logger.error(f"Could not find ibm-watsonx-orchestrate@{version} on https://pypi.org/project/ibm-watsonx-orchestrate")
|
870
|
+
exit(1)
|
863
871
|
requirements.append(f"ibm-watsonx-orchestrate=={version}\n")
|
864
872
|
elif registry_type == RegistryType.TESTPYPI:
|
865
873
|
override_version = cfg.get(PYTHON_REGISTRY_HEADER, PYTHON_REGISTRY_TEST_PACKAGE_VERSION_OVERRIDE_OPT) or version
|
@@ -890,13 +898,34 @@ class ToolsController:
|
|
890
898
|
tool_path = Path(self.file)
|
891
899
|
zip_tool_artifacts.write(tool_path, arcname=f"{tool_path.stem}.json")
|
892
900
|
|
893
|
-
requirements =
|
901
|
+
requirements = []
|
894
902
|
|
895
903
|
if self.requirements_file:
|
896
904
|
requirements_file_path = Path(self.requirements_file)
|
897
905
|
requirements.extend(
|
898
906
|
get_requirement_lines(requirements_file=requirements_file_path, remove_trailing_newlines=False)
|
899
907
|
)
|
908
|
+
|
909
|
+
langflowTool = cast(LangflowTool, tool)
|
910
|
+
# if there are additional requriements from the langflow model, we should add it to the requirement set
|
911
|
+
if langflowTool.requirements and len(langflowTool.requirements) > 0:
|
912
|
+
requirements.extend(langflowTool.requirements)
|
913
|
+
|
914
|
+
# now check if the requirements contain modules listed in DEFAULT_LANGFLOW_RUNNER_MODULES
|
915
|
+
# if it is needed, we are assuming the user wants to override the default langflow module
|
916
|
+
# with a specific version
|
917
|
+
runner_overridden = False
|
918
|
+
for r in requirements:
|
919
|
+
# get the module name from the requirements
|
920
|
+
module_name = r.strip().split('==')[0].split('=')[0].split('>=')[0].split('<=')[0].split('~=')[0].lower()
|
921
|
+
if not module_name.startswith('#'):
|
922
|
+
if module_name in DEFAULT_LANGFLOW_RUNNER_MODULES:
|
923
|
+
runner_overridden = True
|
924
|
+
|
925
|
+
if not runner_overridden:
|
926
|
+
# add the default runner to the top of requirement list
|
927
|
+
requirements = DEFAULT_LANGFLOW_TOOL_REQUIREMENTS + list(requirements)
|
928
|
+
|
900
929
|
requirements_content = '\n'.join(requirements) + '\n'
|
901
930
|
zip_tool_artifacts.writestr("requirements.txt",requirements_content)
|
902
931
|
zip_tool_artifacts.writestr("bundle-format", "2.0.0\n")
|
@@ -22,6 +22,7 @@ AUTH_MCSP_TOKEN_OPT = "wxo_mcsp_token"
|
|
22
22
|
AUTH_MCSP_TOKEN_EXPIRY_OPT = "wxo_mcsp_token_expiry"
|
23
23
|
CONTEXT_ACTIVE_ENV_OPT = "active_environment"
|
24
24
|
PYTHON_REGISTRY_TYPE_OPT = "type"
|
25
|
+
PYTHON_REGISTRY_SKIP_VERSION_CHECK_OPT = "skip_version_check"
|
25
26
|
PYTHON_REGISTRY_TEST_PACKAGE_VERSION_OVERRIDE_OPT = "test_package_version_override"
|
26
27
|
ENV_WXO_URL_OPT = "wxo_url"
|
27
28
|
ENV_IAM_URL_OPT = "iam_url"
|
@@ -40,7 +41,8 @@ DEFAULT_CONFIG_FILE_CONTENT = {
|
|
40
41
|
CONTEXT_SECTION_HEADER: {CONTEXT_ACTIVE_ENV_OPT: None},
|
41
42
|
PYTHON_REGISTRY_HEADER: {
|
42
43
|
PYTHON_REGISTRY_TYPE_OPT: str(RegistryType.PYPI),
|
43
|
-
PYTHON_REGISTRY_TEST_PACKAGE_VERSION_OVERRIDE_OPT: None
|
44
|
+
PYTHON_REGISTRY_TEST_PACKAGE_VERSION_OVERRIDE_OPT: None,
|
45
|
+
PYTHON_REGISTRY_SKIP_VERSION_CHECK_OPT: False
|
44
46
|
},
|
45
47
|
ENVIRONMENTS_SECTION_HEADER: {
|
46
48
|
PROTECTED_ENV_NAME: {
|
@@ -49,8 +49,28 @@ services:
|
|
49
49
|
MAX_POOL: 60
|
50
50
|
DEPLOYMENT_MODE: laptop
|
51
51
|
SUFFIXLIST: ${CM_SUFFIXLIST:-[]}
|
52
|
+
BACKEND_BASE_URL: http://localhost:3001
|
53
|
+
CALLBACK_URL: http://localhost:3001/auth/oauth2/callback
|
52
54
|
ports:
|
53
55
|
- 3001:3001
|
56
|
+
|
57
|
+
wxo-server-connections-ui:
|
58
|
+
image: ${CONNECTIONS_UI_REGISTRY:-us.icr.io/watson-orchestrate-private}/wxo-connections-ui:${CONNECTIONS_UI_TAG:-latest}
|
59
|
+
platform: linux/amd64
|
60
|
+
profiles: [connections-ui]
|
61
|
+
environment:
|
62
|
+
PORT: 3412
|
63
|
+
WXO_CONNECTIONS_URL: http://wxo-server-connection-manager:3001
|
64
|
+
DEPLOYMENT_MODE: laptop
|
65
|
+
WXO_URL: http://localhost:3412
|
66
|
+
ENV: production
|
67
|
+
WXO_SERVER_URL: http://localhost:4321
|
68
|
+
TENANT_ID: ${REACT_APP_TENANT_ID}
|
69
|
+
WXO_CHAT_URL: http://localhost:3000
|
70
|
+
ports:
|
71
|
+
- "3412:3412"
|
72
|
+
networks:
|
73
|
+
- default
|
54
74
|
|
55
75
|
ai-gateway:
|
56
76
|
image: ${AI_GATEWAY_REGISTRY:-us.icr.io/watson-orchestrate-private}/ai-gateway:${AI_GATEWAY_TAG:-latest}
|
@@ -73,6 +93,24 @@ services:
|
|
73
93
|
environment:
|
74
94
|
JWT_SECRET: ${JWT_SECRET}
|
75
95
|
DEPLOYMENT_PLATFORM: laptop-lite
|
96
|
+
CALLBACK_HOST_URL: ${CALLBACK_HOST_URL:-}
|
97
|
+
REDIS_URL: redis://wxo-server-redis:6379/0
|
98
|
+
entrypoint: >
|
99
|
+
sh -c '
|
100
|
+
if [ ! -z "$$CALLBACK_HOST_URL" ]; then
|
101
|
+
GATEWAY_IP=$$(echo "$$CALLBACK_HOST_URL" | sed "s|http://||" | cut -d: -f1)
|
102
|
+
export CALL_BACK_URL="http://$$GATEWAY_IP:8989"
|
103
|
+
echo "Auto-configured CALL_BACK_URL: $$CALL_BACK_URL"
|
104
|
+
else
|
105
|
+
export CALL_BACK_URL="http://wxo-agent-gateway:8989"
|
106
|
+
echo "Using fallback CALL_BACK_URL: $$CALL_BACK_URL"
|
107
|
+
fi
|
108
|
+
if [ $$# -eq 0 ]; then
|
109
|
+
exec ./conditional_script.sh
|
110
|
+
else
|
111
|
+
exec "$$@"
|
112
|
+
fi
|
113
|
+
'
|
76
114
|
|
77
115
|
ui:
|
78
116
|
image: ${UI_REGISTRY:-us.icr.io/watson-orchestrate-private}/wxo-chat:${UITAG:-latest}
|
@@ -105,6 +143,7 @@ services:
|
|
105
143
|
STANDALONE: "true"
|
106
144
|
STREAM_TIMEOUT: ${STREAM_TIMEOUT:-120000}
|
107
145
|
WXO_VOICE_URL: http://localhost:9876/v1
|
146
|
+
DPS_CACHE_URL: http://localhost:18083
|
108
147
|
command: "./StartServer.sh"
|
109
148
|
ports:
|
110
149
|
- "3000:4002"
|
@@ -127,13 +166,13 @@ services:
|
|
127
166
|
AGENTS_OPS_RUNTIME_ENDPOINT: https://frontend-server:443
|
128
167
|
DPI_WO_WDU_SERVER_ENDPOINT: https://wxo-doc-processing-service:8080
|
129
168
|
DPI_RAG_SERVER_ENDPOINT: https://wxo-doc-processing-llm-service:8083
|
130
|
-
IBM_DPS_CACHE_SERVICE:
|
169
|
+
IBM_DPS_CACHE_SERVICE: http://wxo-doc-processing-cache:8080
|
131
170
|
DOCPROC_BASE_URL: http://wxo-doc-processing-infra-standalone:9080
|
132
171
|
BUILDER_ASYNC_CALLBACK_ENDPOINT: http://wxo-builder:4025
|
133
172
|
DOCPROC_ENABLED: ${DOCPROC_ENABLED:-false}
|
134
173
|
IS_OBSERVABILITY_FEATURE_ENABLED: "true"
|
135
174
|
ALLOW_INSECURE_TLS: "true"
|
136
|
-
ENABLE_EDIT_PROMPTS: "
|
175
|
+
ENABLE_EDIT_PROMPTS: "true"
|
137
176
|
LANGFLOW_ENABLED: ${LANGFLOW_ENABLED:-false}
|
138
177
|
ENABLE_EMBED_SCRIPT: "true"
|
139
178
|
command: 'npm start'
|
@@ -353,6 +392,10 @@ services:
|
|
353
392
|
ES_HOST: http://elasticsearch:9200
|
354
393
|
ORIGIN_HEADER: "internal"
|
355
394
|
LANGFLOW_ENABLED: ${LANGFLOW_ENABLED:-false}
|
395
|
+
WATSONX_SERVER: WXO
|
396
|
+
EVALUATION_PLATFORM: lite-local
|
397
|
+
AGENTOPS_BACKEND_URL: https://frontend-server:443
|
398
|
+
OBSERVABILITY_POSTGRES_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-postgres}@wxo-server-db:5432/wxo_observability
|
356
399
|
|
357
400
|
wxo-server-worker:
|
358
401
|
image: ${WORKER_REGISTRY:-us.icr.io/watson-orchestrate-private}/wxo-server-conversation_controller:${WORKER_TAG:-latest}
|
@@ -453,6 +496,10 @@ services:
|
|
453
496
|
CPD_VERIFY: ${CPD_VERIFY}
|
454
497
|
CALLBACK_HOST_URL: ${CALLBACK_HOST_URL:-http://wxo-server:4321}
|
455
498
|
LANGFLOW_ENABLED: ${LANGFLOW_ENABLED:-false}
|
499
|
+
WATSONX_SERVER: WXO
|
500
|
+
EVALUATION_PLATFORM: lite-local
|
501
|
+
AGENTOPS_BACKEND_URL: https://frontend-server:443
|
502
|
+
OBSERVABILITY_POSTGRES_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-postgres}@wxo-server-db:5432/wxo_observability
|
456
503
|
|
457
504
|
tools-runtime-manager:
|
458
505
|
image: ${TRM_REGISTRY:-us.icr.io/watson-orchestrate-private}/tools-runtime-manager:${TRM_TAG:-latest}
|
@@ -813,6 +860,7 @@ services:
|
|
813
860
|
AUTHORIZATION_URL: ${AUTHORIZATION_URL}
|
814
861
|
WO_AUTH_TYPE: ${WO_AUTH_TYPE}
|
815
862
|
FLOW_CALLBACK_REQUEST_RETRIES: "1"
|
863
|
+
DOCPROC_CACHE_SERVER_URL: http://wxo-doc-processing-cache:8080
|
816
864
|
healthcheck:
|
817
865
|
test: curl -k http://localhost:9044/readiness --fail
|
818
866
|
interval: 30s
|
@@ -858,13 +906,13 @@ services:
|
|
858
906
|
SERVICE_NAME: wxo-doc-processing-service
|
859
907
|
LOG_LEVEL: info
|
860
908
|
VERIFY_CLIENT_CERT: 0
|
861
|
-
SERVICE_URL: ${SERVICE_URL:-
|
909
|
+
SERVICE_URL: ${SERVICE_URL:-http://wxo-doc-processing-cache:8080}
|
862
910
|
RATE_LIMITING_ENABLED: "false"
|
863
911
|
SHOULD_CACHE_IMAGES: "false"
|
864
912
|
HANDWRITING_ENABLED: "true"
|
865
913
|
WDU_RUNTIME_URL: wdu-runtime:8080
|
866
914
|
WDU_TIMEOUT_SECS: "180"
|
867
|
-
IBM_DPS_CACHE_SERVICE:
|
915
|
+
IBM_DPS_CACHE_SERVICE: http://wxo-doc-processing-cache:8080
|
868
916
|
profiles:
|
869
917
|
- docproc
|
870
918
|
depends_on:
|
@@ -959,6 +1007,8 @@ services:
|
|
959
1007
|
VERIFY_CLIENT_CERT: 1
|
960
1008
|
# S3_USE_SSL: false
|
961
1009
|
# S3_VERIFY_CERT: false
|
1010
|
+
ISTIO_ENABLED: true
|
1011
|
+
IS_ADK_ENV: true
|
962
1012
|
profiles:
|
963
1013
|
- docproc
|
964
1014
|
depends_on:
|
@@ -971,7 +1021,7 @@ services:
|
|
971
1021
|
# volumes:
|
972
1022
|
# - ./docker/wo_doc_processing_rag_base/etc/certs:/etc/certs
|
973
1023
|
healthcheck:
|
974
|
-
test: ["CMD-SHELL", "curl -fk
|
1024
|
+
test: ["CMD-SHELL", "curl -fk http://localhost:8080/ping"]
|
975
1025
|
interval: 30s
|
976
1026
|
timeout: 30s
|
977
1027
|
retries: 10
|
@@ -1030,7 +1080,7 @@ services:
|
|
1030
1080
|
LOG_LEVEL: info
|
1031
1081
|
WATSONX_API_ENDPOINT: ${WATSONX_URL:-https://us-south.ml.cloud.ibm.com}
|
1032
1082
|
WXO_SERVER_BASE_URL : http://wxo-server:4321
|
1033
|
-
IBM_DPS_CACHE_SERVICE: 'wxo-doc-processing-cache:8080'
|
1083
|
+
IBM_DPS_CACHE_SERVICE: 'http://wxo-doc-processing-cache:8080'
|
1034
1084
|
profiles:
|
1035
1085
|
- docproc
|
1036
1086
|
depends_on:
|
@@ -58,41 +58,44 @@ REGISTRY_URL=
|
|
58
58
|
|
59
59
|
|
60
60
|
|
61
|
-
SERVER_TAG=
|
61
|
+
SERVER_TAG=24-09-2025-17d7c67
|
62
62
|
SERVER_REGISTRY=
|
63
63
|
|
64
|
-
WORKER_TAG=
|
64
|
+
WORKER_TAG=24-09-2025-17d7c67
|
65
65
|
WORKER_REGISTRY=
|
66
66
|
|
67
67
|
AI_GATEWAY_TAG=20-08-2025-9ed6d40
|
68
68
|
AI_GATEWAY_REGISTRY=
|
69
69
|
|
70
|
-
AGENT_GATEWAY_TAG=
|
70
|
+
AGENT_GATEWAY_TAG=19-10-2025-e48ad3a
|
71
71
|
AGENT_GATEWAY_REGISTRY=
|
72
72
|
|
73
73
|
DB_REGISTRY=
|
74
74
|
# If you build multiarch set all three of these to the same, we have a pr against main
|
75
75
|
# to not have this separation, but we can merge it later
|
76
|
-
DBTAG=
|
77
|
-
AMDDBTAG=
|
78
|
-
ARM64DBTAG=
|
76
|
+
DBTAG=17-09-2025-8a9aff2
|
77
|
+
AMDDBTAG=17-09-2025-8a9aff2
|
78
|
+
ARM64DBTAG=17-09-2025-8a9aff2
|
79
79
|
|
80
80
|
UI_REGISTRY=
|
81
|
-
UITAG=
|
81
|
+
UITAG=22-09-2025-e35f498
|
82
82
|
|
83
83
|
CM_REGISTRY=
|
84
|
-
CM_TAG=
|
84
|
+
CM_TAG=16-09-2025-e33b344
|
85
85
|
|
86
|
-
|
86
|
+
CONNECTIONS_UI_REGISTRY=
|
87
|
+
CONNECTIONS_UI_TAG=15-09-2025-98aa9da
|
88
|
+
|
89
|
+
TRM_TAG=16-09-2025-cb6b9df
|
87
90
|
TRM_REGISTRY=
|
88
91
|
|
89
|
-
TR_TAG=
|
92
|
+
TR_TAG=24-09-2025-a515038
|
90
93
|
TR_REGISTRY=
|
91
94
|
|
92
|
-
BUILDER_TAG=
|
95
|
+
BUILDER_TAG=24-09-2025-f9b68d8
|
93
96
|
BUILDER_REGISTRY=
|
94
97
|
|
95
|
-
FLOW_RUNTIME_TAG=
|
98
|
+
FLOW_RUNTIME_TAG=22-09-2025-0bd3f58
|
96
99
|
FLOW_RUMTIME_REGISTRY=
|
97
100
|
|
98
101
|
|
@@ -118,10 +121,10 @@ LANGFLOW_IMAGE=
|
|
118
121
|
WDU_TAG=2.7.0
|
119
122
|
WDU_REGISTRY=
|
120
123
|
|
121
|
-
DOCPROC_DPS_TAG=
|
122
|
-
DOCPROC_LLMSERVICE_TAG=
|
123
|
-
DOCPROC_CACHE_TAG=
|
124
|
-
DOCPROC_DPI_TAG=
|
124
|
+
DOCPROC_DPS_TAG=20250910-165658-290-c566031
|
125
|
+
DOCPROC_LLMSERVICE_TAG=20250915-main-139-7a36ad3
|
126
|
+
DOCPROC_CACHE_TAG=20250916-master-86-454157f
|
127
|
+
DOCPROC_DPI_TAG=20250910-214413-288-a348dfd9
|
125
128
|
DOCPROC_REGISTRY=
|
126
129
|
|
127
130
|
# END -- IMAGE REGISTRIES AND TAGS
|
@@ -8,6 +8,8 @@ import logging
|
|
8
8
|
import inspect
|
9
9
|
from typing import Callable, Optional, Sequence
|
10
10
|
from pydantic import BaseModel
|
11
|
+
|
12
|
+
from ...agent_builder.models.types import ListVirtualModel
|
11
13
|
from ..types import extract_node_spec, UserNodeSpec, FlowSpec
|
12
14
|
|
13
15
|
from .flow import FlowFactory, Flow
|
@@ -33,8 +35,11 @@ def flow(*args,
|
|
33
35
|
description: str|None=None,
|
34
36
|
input_schema: type[BaseModel] | None = None,
|
35
37
|
output_schema: type[BaseModel] | None = None,
|
38
|
+
private_schema: type[BaseModel] | None = None,
|
36
39
|
initiators: Sequence[str] = (),
|
37
|
-
schedulable: bool = False
|
40
|
+
schedulable: bool = False,
|
41
|
+
llm_model: str|ListVirtualModel|None=None,
|
42
|
+
agent_conversation_memory_turns_limit: int|None=None):
|
38
43
|
"""Decorator to mark a function as a flow model builder."""
|
39
44
|
|
40
45
|
def decorator(func: Callable):
|
@@ -59,8 +64,11 @@ def flow(*args,
|
|
59
64
|
description = node_spec.description,
|
60
65
|
input_schema = input_schema,
|
61
66
|
output_schema = output_schema,
|
67
|
+
private_schema = private_schema,
|
62
68
|
initiators = initiators,
|
63
|
-
schedulable = schedulable
|
69
|
+
schedulable = schedulable,
|
70
|
+
llm_model = llm_model,
|
71
|
+
agent_conversation_memory_turns_limit = agent_conversation_memory_turns_limit)
|
64
72
|
|
65
73
|
# logger.info("Creating flow model: %s", a_model.spec.name)
|
66
74
|
|
@@ -21,17 +21,18 @@ from typing_extensions import Self
|
|
21
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
|
+
from ibm_watsonx_orchestrate.agent_builder.models.types import ListVirtualModel
|
24
25
|
from ibm_watsonx_orchestrate.client.tools.tool_client import ToolClient
|
25
26
|
from ibm_watsonx_orchestrate.client.tools.tempus_client import TempusClient
|
26
27
|
from ibm_watsonx_orchestrate.client.utils import instantiate_client
|
27
28
|
from ..types import (
|
28
|
-
DocProcKVPSchema, Assignment, Conditions, EndNodeSpec, Expression, ForeachPolicy, ForeachSpec, LoopSpec, BranchNodeSpec, MatchPolicy, NodeIdCondition, PlainTextReadingOrder, PromptExample, PromptLLMParameters, PromptNodeSpec, TimerNodeSpec,
|
29
|
+
DocProcKVPSchema, Assignment, Conditions, EndNodeSpec, Expression, ForeachPolicy, ForeachSpec, LoopSpec, BranchNodeSpec, MatchPolicy, NodeIdCondition, PlainTextReadingOrder, PromptExample, PromptLLMParameters, PromptNodeSpec, ScriptNodeSpec, TimerNodeSpec,
|
29
30
|
StartNodeSpec, ToolSpec, JsonSchemaObject, ToolRequestBody, ToolResponseBody, UserFieldKind, UserFieldOption, UserFlowSpec, UserNodeSpec, WaitPolicy,
|
30
31
|
DocProcSpec, TextExtractionResponse, DocProcInput, DecisionsNodeSpec, DecisionsRule, DocExtSpec, File, DocumentClassificationResponse, DocClassifierSpec, DocumentProcessingCommonInput
|
31
32
|
)
|
32
33
|
from .constants import CURRENT_USER, START, END, ANY_USER
|
33
34
|
from ..node import (
|
34
|
-
EndNode, Node, PromptNode, StartNode, UserNode, AgentNode, DataMap, ToolNode, DocProcNode, DecisionsNode, DocExtNode, DocClassifierNode
|
35
|
+
EndNode, Node, PromptNode, ScriptNode, StartNode, UserNode, AgentNode, DataMap, ToolNode, DocProcNode, DecisionsNode, DocExtNode, DocClassifierNode
|
35
36
|
)
|
36
37
|
from ..types import (
|
37
38
|
AgentNodeSpec, extract_node_spec, FlowContext, FlowEventType, FlowEvent, FlowSpec,
|
@@ -84,6 +85,21 @@ class Flow(Node):
|
|
84
85
|
# get Tool Client
|
85
86
|
self._tool_client = instantiate_client(ToolClient)
|
86
87
|
|
88
|
+
# set llm_model to use for the flow if any
|
89
|
+
llm_model = kwargs.get("llm_model")
|
90
|
+
if llm_model:
|
91
|
+
if isinstance(llm_model, ListVirtualModel):
|
92
|
+
self.metadata["llm_model"] = llm_model.name
|
93
|
+
elif isinstance(llm_model, str):
|
94
|
+
self.metadata["llm_model"] = llm_model
|
95
|
+
else:
|
96
|
+
raise AssertionError(f"flow llm_model should be either a str or ListVirtualModel")
|
97
|
+
|
98
|
+
# set agent_conversation_memory_turns_limit for the flow if any
|
99
|
+
agent_conversation_memory_turns_limit = kwargs.get("agent_conversation_memory_turns_limit")
|
100
|
+
if agent_conversation_memory_turns_limit:
|
101
|
+
self.metadata["agent_conversation_memory_turns_limit"] = agent_conversation_memory_turns_limit
|
102
|
+
|
87
103
|
def _find_topmost_flow(self) -> Self:
|
88
104
|
if self.parent:
|
89
105
|
return self.parent._find_topmost_flow()
|
@@ -341,6 +357,41 @@ class Flow(Node):
|
|
341
357
|
|
342
358
|
node = self._add_node(node)
|
343
359
|
return cast(ToolNode, node)
|
360
|
+
|
361
|
+
|
362
|
+
def script(
|
363
|
+
self,
|
364
|
+
script: str | None = "",
|
365
|
+
name: str | None = None,
|
366
|
+
display_name: str | None = None,
|
367
|
+
description: str | None = None,
|
368
|
+
input_schema: type[BaseModel] | None = None,
|
369
|
+
output_schema: type[BaseModel] | None = None,
|
370
|
+
input_map: DataMap = None
|
371
|
+
) -> ScriptNode:
|
372
|
+
'''create a script node in the flow'''
|
373
|
+
name = name if name is not None and name != "" else ""
|
374
|
+
|
375
|
+
input_schema_obj = _get_json_schema_obj("input", input_schema)
|
376
|
+
output_schema_obj = _get_json_schema_obj("output", output_schema)
|
377
|
+
|
378
|
+
script_node_spec = ScriptNodeSpec(
|
379
|
+
name = name,
|
380
|
+
display_name = display_name,
|
381
|
+
description = description,
|
382
|
+
input_schema= _get_tool_request_body(input_schema_obj),
|
383
|
+
output_schema= _get_tool_response_body(output_schema_obj),
|
384
|
+
output_schema_object = output_schema_obj,
|
385
|
+
fn = script)
|
386
|
+
|
387
|
+
node = ScriptNode(spec=script_node_spec)
|
388
|
+
|
389
|
+
# setup input and output map
|
390
|
+
if input_map:
|
391
|
+
node.input_map = self._get_data_map(input_map)
|
392
|
+
|
393
|
+
node = self._add_node(node)
|
394
|
+
return cast(ScriptNode, node)
|
344
395
|
|
345
396
|
|
346
397
|
def _add_node(self, node: Node) -> Node:
|
@@ -519,7 +570,9 @@ class Flow(Node):
|
|
519
570
|
fields: type[BaseModel]| None = None,
|
520
571
|
description: str | None = None,
|
521
572
|
input_map: DataMap = None,
|
522
|
-
enable_hw: bool = False
|
573
|
+
enable_hw: bool = False,
|
574
|
+
min_confidence: float = 0, # Setting a small value because htil is not supported for pro code.
|
575
|
+
review_fields: List[str] = []) -> tuple[DocExtNode, type[BaseModel]]:
|
523
576
|
|
524
577
|
if name is None :
|
525
578
|
raise ValueError("name must be provided.")
|
@@ -544,7 +597,9 @@ class Flow(Node):
|
|
544
597
|
output_schema_object = output_schema_obj,
|
545
598
|
config=doc_ext_config,
|
546
599
|
version=version,
|
547
|
-
enable_hw=enable_hw
|
600
|
+
enable_hw=enable_hw,
|
601
|
+
min_confidence=min_confidence,
|
602
|
+
review_fields=review_fields
|
548
603
|
)
|
549
604
|
node = DocExtNode(spec=task_spec)
|
550
605
|
|
@@ -609,7 +664,8 @@ class Flow(Node):
|
|
609
664
|
input_map: DataMap = None,
|
610
665
|
document_structure: bool = False,
|
611
666
|
kvp_schemas: list[DocProcKVPSchema] = None,
|
612
|
-
enable_hw: bool = False
|
667
|
+
enable_hw: bool = False,
|
668
|
+
kvp_model_name: str | None = None) -> DocProcNode:
|
613
669
|
|
614
670
|
if name is None :
|
615
671
|
raise ValueError("name must be provided.")
|
@@ -635,7 +691,8 @@ class Flow(Node):
|
|
635
691
|
document_structure=document_structure,
|
636
692
|
plain_text_reading_order=plain_text_reading_order,
|
637
693
|
enable_hw=enable_hw,
|
638
|
-
kvp_schemas=kvp_schemas
|
694
|
+
kvp_schemas=kvp_schemas,
|
695
|
+
kvp_model_name=kvp_model_name
|
639
696
|
)
|
640
697
|
|
641
698
|
node = DocProcNode(spec=task_spec)
|
@@ -1201,7 +1258,7 @@ class CompiledFlow(BaseModel):
|
|
1201
1258
|
dumped = self.flow.to_json()
|
1202
1259
|
with open(file, 'w') as f:
|
1203
1260
|
if file.endswith(".yaml") or file.endswith(".yml"):
|
1204
|
-
yaml.dump(dumped, f)
|
1261
|
+
yaml.dump(dumped, f, allow_unicode=True)
|
1205
1262
|
elif file.endswith(".json"):
|
1206
1263
|
json.dump(dumped, f, indent=2)
|
1207
1264
|
else:
|
@@ -1223,7 +1280,10 @@ class FlowFactory(BaseModel):
|
|
1223
1280
|
initiators: Sequence[str]|None=None,
|
1224
1281
|
input_schema: type[BaseModel]|None=None,
|
1225
1282
|
output_schema: type[BaseModel]|None=None,
|
1226
|
-
|
1283
|
+
private_schema: type[BaseModel]|None=None,
|
1284
|
+
schedulable: bool=False,
|
1285
|
+
llm_model: str|ListVirtualModel|None=None,
|
1286
|
+
agent_conversation_memory_turns_limit: int|None = None) -> Flow:
|
1227
1287
|
if isinstance(name, Callable):
|
1228
1288
|
flow_spec = getattr(name, "__flow_spec__", None)
|
1229
1289
|
if not flow_spec:
|
@@ -1233,6 +1293,7 @@ class FlowFactory(BaseModel):
|
|
1233
1293
|
input_schema_obj = _get_json_schema_obj(parameter_name = "input", type_def = input_schema)
|
1234
1294
|
# create input spec
|
1235
1295
|
output_schema_obj = _get_json_schema_obj("output", output_schema)
|
1296
|
+
private_schema_obj = _get_json_schema_obj("private", private_schema)
|
1236
1297
|
if initiators is None:
|
1237
1298
|
initiators = []
|
1238
1299
|
|
@@ -1244,11 +1305,12 @@ class FlowFactory(BaseModel):
|
|
1244
1305
|
initiators=initiators,
|
1245
1306
|
input_schema=_get_tool_request_body(input_schema_obj),
|
1246
1307
|
output_schema=_get_tool_response_body(output_schema_obj),
|
1308
|
+
private_schema = private_schema_obj,
|
1247
1309
|
output_schema_object = output_schema_obj,
|
1248
1310
|
schedulable=schedulable,
|
1249
1311
|
)
|
1250
1312
|
|
1251
|
-
return Flow(spec = flow_spec)
|
1313
|
+
return Flow(spec = flow_spec, llm_model=llm_model, agent_conversation_memory_turns_limit=agent_conversation_memory_turns_limit)
|
1252
1314
|
|
1253
1315
|
|
1254
1316
|
class FlowControl(Node):
|
@@ -6,7 +6,7 @@ import yaml
|
|
6
6
|
from pydantic import BaseModel, Field, SerializeAsAny, create_model
|
7
7
|
from enum import Enum
|
8
8
|
|
9
|
-
from .types import Assignment, DocExtConfigField, EndNodeSpec, NodeSpec, AgentNodeSpec, PromptNodeSpec, TimerNodeSpec, StartNodeSpec, ToolNodeSpec, UserFieldKind, UserFieldOption, UserNodeSpec, DocProcSpec, \
|
9
|
+
from .types import Assignment, DocExtConfigField, EndNodeSpec, NodeSpec, AgentNodeSpec, PromptNodeSpec, ScriptNodeSpec, TimerNodeSpec, StartNodeSpec, ToolNodeSpec, UserFieldKind, UserFieldOption, UserNodeSpec, DocProcSpec, \
|
10
10
|
DocExtSpec, DocExtConfig, DocClassifierSpec, DecisionsNodeSpec, DocClassifierConfig
|
11
11
|
|
12
12
|
from .data_map import DataMap
|
@@ -23,7 +23,7 @@ class Node(BaseModel):
|
|
23
23
|
exclude_unset=True, exclude_none=True, by_alias=True)
|
24
24
|
with open(file, 'w', encoding="utf-8") as f:
|
25
25
|
if file.endswith('.yaml') or file.endswith('.yml'):
|
26
|
-
yaml.dump(dumped, f)
|
26
|
+
yaml.dump(dumped, f, allow_unicode=True)
|
27
27
|
elif file.endswith('.json'):
|
28
28
|
json.dump(dumped, f, indent=2)
|
29
29
|
else:
|
@@ -132,6 +132,18 @@ class ToolNode(Node):
|
|
132
132
|
|
133
133
|
def get_spec(self) -> ToolNodeSpec:
|
134
134
|
return cast(ToolNodeSpec, self.spec)
|
135
|
+
|
136
|
+
|
137
|
+
class ScriptNode(Node):
|
138
|
+
def __repr__(self):
|
139
|
+
return f"ScriptNode(name='{self.spec.name}', description='{self.spec.description}')"
|
140
|
+
|
141
|
+
def get_spec(self) -> ScriptNodeSpec:
|
142
|
+
return cast(ScriptNodeSpec, self.spec)
|
143
|
+
|
144
|
+
def updateScript(self, script: str):
|
145
|
+
'''Update the script of a script node'''
|
146
|
+
self.spec.fn = script
|
135
147
|
|
136
148
|
class UserNode(Node):
|
137
149
|
def __repr__(self):
|