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.
Files changed (36) hide show
  1. ibm_watsonx_orchestrate/__init__.py +2 -1
  2. ibm_watsonx_orchestrate/agent_builder/agents/types.py +5 -5
  3. ibm_watsonx_orchestrate/agent_builder/models/types.py +1 -0
  4. ibm_watsonx_orchestrate/agent_builder/toolkits/base_toolkit.py +1 -1
  5. ibm_watsonx_orchestrate/agent_builder/tools/base_tool.py +1 -1
  6. ibm_watsonx_orchestrate/agent_builder/tools/langflow_tool.py +61 -1
  7. ibm_watsonx_orchestrate/agent_builder/tools/openapi_tool.py +6 -0
  8. ibm_watsonx_orchestrate/cli/commands/agents/agents_controller.py +2 -2
  9. ibm_watsonx_orchestrate/cli/commands/connections/connections_controller.py +2 -2
  10. ibm_watsonx_orchestrate/cli/commands/environment/environment_command.py +5 -1
  11. ibm_watsonx_orchestrate/cli/commands/environment/environment_controller.py +6 -3
  12. ibm_watsonx_orchestrate/cli/commands/evaluations/evaluations_command.py +3 -2
  13. ibm_watsonx_orchestrate/cli/commands/evaluations/evaluations_controller.py +1 -1
  14. ibm_watsonx_orchestrate/cli/commands/models/model_provider_mapper.py +23 -4
  15. ibm_watsonx_orchestrate/cli/commands/partners/offering/partners_offering_controller.py +21 -4
  16. ibm_watsonx_orchestrate/cli/commands/partners/offering/types.py +7 -15
  17. ibm_watsonx_orchestrate/cli/commands/partners/partners_command.py +1 -1
  18. ibm_watsonx_orchestrate/cli/commands/server/server_command.py +11 -3
  19. ibm_watsonx_orchestrate/cli/commands/toolkit/toolkit_command.py +2 -2
  20. ibm_watsonx_orchestrate/cli/commands/tools/tools_controller.py +37 -8
  21. ibm_watsonx_orchestrate/cli/config.py +3 -1
  22. ibm_watsonx_orchestrate/docker/compose-lite.yml +56 -6
  23. ibm_watsonx_orchestrate/docker/default.env +19 -16
  24. ibm_watsonx_orchestrate/flow_builder/flows/decorators.py +10 -2
  25. ibm_watsonx_orchestrate/flow_builder/flows/flow.py +71 -9
  26. ibm_watsonx_orchestrate/flow_builder/node.py +14 -2
  27. ibm_watsonx_orchestrate/flow_builder/types.py +36 -3
  28. ibm_watsonx_orchestrate/langflow/__init__.py +0 -0
  29. ibm_watsonx_orchestrate/langflow/langflow_utils.py +195 -0
  30. ibm_watsonx_orchestrate/langflow/lfx_deps.py +84 -0
  31. ibm_watsonx_orchestrate/utils/utils.py +6 -2
  32. {ibm_watsonx_orchestrate-1.12.0b0.dist-info → ibm_watsonx_orchestrate-1.12.1.dist-info}/METADATA +2 -2
  33. {ibm_watsonx_orchestrate-1.12.0b0.dist-info → ibm_watsonx_orchestrate-1.12.1.dist-info}/RECORD +36 -33
  34. {ibm_watsonx_orchestrate-1.12.0b0.dist-info → ibm_watsonx_orchestrate-1.12.1.dist-info}/WHEEL +0 -0
  35. {ibm_watsonx_orchestrate-1.12.0b0.dist-info → ibm_watsonx_orchestrate-1.12.1.dist-info}/entry_points.txt +0 -0
  36. {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
- wheel_file = get_whl_in_registry(registry_url='https://pypi.org/simple/ibm-watsonx-orchestrate', version=version)
860
- if not wheel_file:
861
- logger.error(f"Could not find ibm-watsonx-orchestrate@{version} on https://pypi.org/project/ibm-watsonx-orchestrate")
862
- exit(1)
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 = DEFAULT_LANGFLOW_TOOL_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: https://wxo-doc-processing-cache:8080
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: "false"
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:-https://wxo-doc-processing-cache:8080}
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: https://wxo-doc-processing-cache:8080
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 https://localhost:8080/ping"]
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=09-09-2025-2164abd
61
+ SERVER_TAG=24-09-2025-17d7c67
62
62
  SERVER_REGISTRY=
63
63
 
64
- WORKER_TAG=09-09-2025-2164abd
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=29-07-2025
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=09-09-2025-fb76647
77
- AMDDBTAG=09-09-2025-fb76647
78
- ARM64DBTAG=09-09-2025-fb76647
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=29-08-2025
81
+ UITAG=22-09-2025-e35f498
82
82
 
83
83
  CM_REGISTRY=
84
- CM_TAG=24-07-2025
84
+ CM_TAG=16-09-2025-e33b344
85
85
 
86
- TRM_TAG=09-09-2025-6e9d73d
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=09-09-2025-6e9d73d
92
+ TR_TAG=24-09-2025-a515038
90
93
  TR_REGISTRY=
91
94
 
92
- BUILDER_TAG=12-09-2025-e441686
95
+ BUILDER_TAG=24-09-2025-f9b68d8
93
96
  BUILDER_REGISTRY=
94
97
 
95
- FLOW_RUNTIME_TAG=15-09-2025-2e8478c
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=20250904-181617-287-1ca2bf1
122
- DOCPROC_LLMSERVICE_TAG=20250904-main-136-b94360e
123
- DOCPROC_CACHE_TAG=20250902-master-83-748d456
124
- DOCPROC_DPI_TAG=20250905-092707-286-8c6b8f92
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) -> tuple[DocExtNode, type[BaseModel]]:
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) -> DocProcNode:
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
- schedulable: bool=False) -> Flow:
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):