ibm-watsonx-orchestrate 1.12.0b1__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 (24) hide show
  1. ibm_watsonx_orchestrate/__init__.py +2 -1
  2. ibm_watsonx_orchestrate/agent_builder/tools/langflow_tool.py +61 -1
  3. ibm_watsonx_orchestrate/cli/commands/environment/environment_command.py +5 -1
  4. ibm_watsonx_orchestrate/cli/commands/environment/environment_controller.py +6 -3
  5. ibm_watsonx_orchestrate/cli/commands/evaluations/evaluations_command.py +3 -2
  6. ibm_watsonx_orchestrate/cli/commands/evaluations/evaluations_controller.py +1 -1
  7. ibm_watsonx_orchestrate/cli/commands/partners/offering/partners_offering_controller.py +21 -4
  8. ibm_watsonx_orchestrate/cli/commands/partners/offering/types.py +7 -15
  9. ibm_watsonx_orchestrate/cli/commands/tools/tools_controller.py +37 -8
  10. ibm_watsonx_orchestrate/cli/config.py +3 -1
  11. ibm_watsonx_orchestrate/docker/default.env +8 -8
  12. ibm_watsonx_orchestrate/flow_builder/flows/decorators.py +2 -0
  13. ibm_watsonx_orchestrate/flow_builder/flows/flow.py +40 -2
  14. ibm_watsonx_orchestrate/flow_builder/node.py +13 -1
  15. ibm_watsonx_orchestrate/flow_builder/types.py +18 -0
  16. ibm_watsonx_orchestrate/langflow/__init__.py +0 -0
  17. ibm_watsonx_orchestrate/langflow/langflow_utils.py +195 -0
  18. ibm_watsonx_orchestrate/langflow/lfx_deps.py +84 -0
  19. ibm_watsonx_orchestrate/utils/utils.py +6 -2
  20. {ibm_watsonx_orchestrate-1.12.0b1.dist-info → ibm_watsonx_orchestrate-1.12.1.dist-info}/METADATA +2 -2
  21. {ibm_watsonx_orchestrate-1.12.0b1.dist-info → ibm_watsonx_orchestrate-1.12.1.dist-info}/RECORD +24 -21
  22. {ibm_watsonx_orchestrate-1.12.0b1.dist-info → ibm_watsonx_orchestrate-1.12.1.dist-info}/WHEEL +0 -0
  23. {ibm_watsonx_orchestrate-1.12.0b1.dist-info → ibm_watsonx_orchestrate-1.12.1.dist-info}/entry_points.txt +0 -0
  24. {ibm_watsonx_orchestrate-1.12.0b1.dist-info → ibm_watsonx_orchestrate-1.12.1.dist-info}/licenses/LICENSE +0 -0
@@ -5,7 +5,8 @@
5
5
 
6
6
  pkg_name = "ibm-watsonx-orchestrate"
7
7
 
8
- __version__ = "1.12.0b1"
8
+
9
+ __version__ = "1.12.1"
9
10
 
10
11
 
11
12
  from ibm_watsonx_orchestrate.utils.logging.logger import setup_logging
@@ -2,8 +2,10 @@ import json
2
2
  import re
3
3
 
4
4
  from pydantic import BaseModel
5
+ import rich
5
6
 
6
7
  from ibm_watsonx_orchestrate.agent_builder.connections.types import ConnectionSecurityScheme
8
+ from ibm_watsonx_orchestrate.langflow.langflow_utils import parse_langflow_model
7
9
  from .base_tool import BaseTool
8
10
  from .types import LangflowToolBinding, ToolBinding, ToolPermission, ToolRequestBody, ToolResponseBody, ToolSpec
9
11
  from ibm_watsonx_orchestrate.utils.exceptions import BadRequest
@@ -14,6 +16,9 @@ LANGFLOW_CHAT_OUTPUT_LABEL = "ChatOutput"
14
16
  VALID_NAME_PATTERN = re.compile("^[a-zA-Z](\\w|_)+$")
15
17
 
16
18
  class LangflowTool(BaseTool):
19
+ # additional python module requirements for langflow based tools
20
+ requirements: list[str] = []
21
+
17
22
  def __init__(self,spec: ToolSpec):
18
23
  BaseTool.__init__(self,spec=spec)
19
24
 
@@ -103,6 +108,59 @@ def create_langflow_tool(
103
108
  if not validate_langflow_version(langflow_version):
104
109
  raise ValueError(f"Langflow version is below minimum requirements, found '{langflow_version}', miniumum required version '{'.'.join(map(str,MIN_LANGFLOW_VERSION))}'")
105
110
 
111
+ # find all the component in Langflow and display its credential
112
+ langflow_spec = parse_langflow_model(tool_definition)
113
+ if langflow_spec:
114
+ rich.print(f"[bold white]Langflow version used: {langflow_version}[/bold white]")
115
+ rich.print("Please ensure this flow is compatible with the Langflow version bundled in ADK.")
116
+ rich.print("\nLangflow components:")
117
+
118
+ table = rich.table.Table(show_header=True, header_style="bold white", show_lines=True)
119
+ column_args = {
120
+ "ID": {},
121
+ "Name": {},
122
+ "Credentials": {},
123
+ "Requirements": {}
124
+ }
125
+ for column in column_args:
126
+ table.add_column(column,**column_args[column])
127
+
128
+ requirements = set()
129
+ api_key_not_set = False
130
+ for component in langflow_spec.components:
131
+ if component.credentials and len(component.credentials) > 0:
132
+ # create a command separated list with newline
133
+ component_creds = None
134
+ for k, v in component.credentials.items():
135
+ if v is None or v == "":
136
+ v = 'NOT SET'
137
+ api_key_not_set = True
138
+ if component_creds is None:
139
+ component_creds = f"{k} {v}"
140
+ else:
141
+ component_creds += "\n" + f"{k} {v}"
142
+ else:
143
+ component_creds = "N/A"
144
+
145
+ if component.requirements and len(component.requirements) > 0:
146
+ # create a command separated list with newline
147
+ component_req = "\n".join([f"{k}" for k in component.requirements])
148
+ for r in component.requirements:
149
+ requirements.add(r)
150
+ else:
151
+ component_req = "N/A"
152
+ table.add_row(component.id,component.name,component_creds,component_req)
153
+ rich.print(table)
154
+
155
+ rich.print("[bold yellow]Tip:[/bold yellow] Langflow tool might require additional python modules. Identified requirements will be added.")
156
+ rich.print("[bold yellow]Tip:[/bold yellow] Avoid hardcoding sensitive values. Use Orchestrate connections to manage secrets securely.")
157
+ if api_key_not_set:
158
+ rich.print("[bold yellow]Warning:[/bold yellow] Some required api key(s) were not set in the flow. Please adjust the flow to include them.")
159
+ rich.print("Ensure each credential follows the <app-id>_<variable> naming convention within the Langflow model.")
160
+
161
+ for connection in connections:
162
+ rich.print(f"* Connection: {connection} → Suggested naming: {connection}_<variable>")
163
+
106
164
  spec = ToolSpec(
107
165
  name=name,
108
166
  description=description,
@@ -121,4 +179,6 @@ def create_langflow_tool(
121
179
  )
122
180
  )
123
181
 
124
- return LangflowTool(spec)
182
+ tool = LangflowTool(spec=spec)
183
+ tool.requirements = requirements
184
+ return tool
@@ -43,9 +43,13 @@ def activate_env(
43
43
  test_package_version_override: Annotated[
44
44
  str,
45
45
  typer.Option("--test-package-version-override", help="Which prereleased package version to reference when using --registry testpypi", hidden=True),
46
+ ] = None,
47
+ skip_version_check: Annotated[
48
+ bool,
49
+ typer.Option('--skip-version-check/--enable-version-check', help='Use this flag to skip validating that adk version in use exists in pypi (for clients who mirror the ADK to a local registry and do not have local access to pypi).')
46
50
  ] = None
47
51
  ):
48
- environment_controller.activate(name=name, apikey=apikey,username=username, password=password, registry=registry, test_package_version_override=test_package_version_override)
52
+ environment_controller.activate(name=name, apikey=apikey, username=username, password=password, registry=registry, test_package_version_override=test_package_version_override, skip_version_check=skip_version_check)
49
53
 
50
54
 
51
55
  @environment_app.command(name="add")
@@ -18,8 +18,9 @@ from ibm_watsonx_orchestrate.cli.config import (
18
18
  ENV_IAM_URL_OPT,
19
19
  ENVIRONMENTS_SECTION_HEADER,
20
20
  PROTECTED_ENV_NAME,
21
- ENV_AUTH_TYPE, PYTHON_REGISTRY_HEADER, PYTHON_REGISTRY_TYPE_OPT, PYTHON_REGISTRY_TEST_PACKAGE_VERSION_OVERRIDE_OPT, BYPASS_SSL, VERIFY,
22
- DEFAULT_CONFIG_FILE_CONTENT
21
+ ENV_AUTH_TYPE, PYTHON_REGISTRY_HEADER, PYTHON_REGISTRY_TYPE_OPT, PYTHON_REGISTRY_TEST_PACKAGE_VERSION_OVERRIDE_OPT,
22
+ BYPASS_SSL, VERIFY,
23
+ DEFAULT_CONFIG_FILE_CONTENT, PYTHON_REGISTRY_SKIP_VERSION_CHECK_OPT
23
24
  )
24
25
  from ibm_watsonx_orchestrate.client.client import Client
25
26
  from ibm_watsonx_orchestrate.client.client_errors import ClientError
@@ -131,7 +132,7 @@ def _login(name: str, apikey: str = None, username: str = None, password: str =
131
132
  except ClientError as e:
132
133
  raise ClientError(e)
133
134
 
134
- def activate(name: str, apikey: str=None, username: str=None, password: str=None, registry: RegistryType=None, test_package_version_override=None) -> None:
135
+ def activate(name: str, apikey: str=None, username: str=None, password: str=None, registry: RegistryType=None, test_package_version_override=None, skip_version_check=None) -> None:
135
136
  cfg = Config()
136
137
  auth_cfg = Config(AUTH_CONFIG_FILE_FOLDER, AUTH_CONFIG_FILE)
137
138
  env_cfg = cfg.read(ENVIRONMENTS_SECTION_HEADER, name)
@@ -159,6 +160,8 @@ def activate(name: str, apikey: str=None, username: str=None, password: str=None
159
160
  elif cfg.read(PYTHON_REGISTRY_HEADER, PYTHON_REGISTRY_TYPE_OPT) is None:
160
161
  cfg.write(PYTHON_REGISTRY_HEADER, PYTHON_REGISTRY_TYPE_OPT, DEFAULT_CONFIG_FILE_CONTENT[PYTHON_REGISTRY_HEADER][PYTHON_REGISTRY_TYPE_OPT])
161
162
  cfg.write(PYTHON_REGISTRY_HEADER, PYTHON_REGISTRY_TEST_PACKAGE_VERSION_OVERRIDE_OPT, test_package_version_override)
163
+ if skip_version_check is not None:
164
+ cfg.write(PYTHON_REGISTRY_HEADER, PYTHON_REGISTRY_SKIP_VERSION_CHECK_OPT, skip_version_check)
162
165
 
163
166
  logger.info(f"Environment '{name}' is now active")
164
167
  is_cpd = is_cpd_env(url)
@@ -54,7 +54,8 @@ def read_env_file(env_path: Path|str) -> dict:
54
54
  def validate_watsonx_credentials(user_env_file: str) -> bool:
55
55
  required_sets = [
56
56
  ["WATSONX_SPACE_ID", "WATSONX_APIKEY"],
57
- ["WO_INSTANCE", "WO_API_KEY"]
57
+ ["WO_INSTANCE", "WO_API_KEY"],
58
+ ["WO_INSTANCE", "WO_PASSWORD", "WO_USERNAME"]
58
59
  ]
59
60
 
60
61
  def has_valid_keys(env: dict) -> bool:
@@ -75,7 +76,7 @@ def validate_watsonx_credentials(user_env_file: str) -> bool:
75
76
  user_env = read_env_file(user_env_file)
76
77
 
77
78
  if not has_valid_keys(user_env):
78
- logger.error("Error: The environment file does not contain the required keys: either WATSONX_SPACE_ID and WATSONX_APIKEY or WO_INSTANCE and WO_API_KEY.")
79
+ logger.error("Error: The environment file does not contain the required keys: either WATSONX_SPACE_ID and WATSONX_APIKEY or WO_INSTANCE and WO_API_KEY or WO_INSTANCE and WO_USERNAME and WO_PASSWORD.")
79
80
  sys.exit(1)
80
81
 
81
82
  # Update os.environ with whichever set is present
@@ -52,7 +52,7 @@ class EvaluationsController:
52
52
 
53
53
  if "WATSONX_SPACE_ID" in os.environ and "WATSONX_APIKEY" in os.environ:
54
54
  provider = "watsonx"
55
- elif "WO_INSTANCE" in os.environ and "WO_API_KEY" in os.environ:
55
+ elif "WO_INSTANCE" in os.environ and ("WO_API_KEY" in os.environ or "WO_PASSWORD" in os.environ):
56
56
  provider = "model_proxy"
57
57
  else:
58
58
  logger.error(
@@ -23,6 +23,7 @@ from ibm_watsonx_orchestrate.client.connections import get_connections_client
23
23
  from ibm_watsonx_orchestrate.agent_builder.connections.types import ConnectionEnvironment
24
24
  from ibm_watsonx_orchestrate.cli.commands.connections.connections_controller import export_connection
25
25
  from ibm_watsonx_orchestrate.cli.commands.tools.tools_controller import ToolsController
26
+ from ibm_watsonx_orchestrate.utils.utils import sanitize_catalog_label
26
27
  from .types import *
27
28
 
28
29
  APPLICATIONS_FILE_VERSION = '1.16.0'
@@ -54,7 +55,7 @@ def get_tool_bindings(tool_names: list[str]) -> dict[str, dict]:
54
55
 
55
56
  return results
56
57
 
57
- def _patch_agent_yamls(project_root: Path, publisher_name: str):
58
+ def _patch_agent_yamls(project_root: Path, publisher_name: str, parent_agent_name: str):
58
59
  agents_dir = project_root / "agents"
59
60
  if not agents_dir.exists():
60
61
  return
@@ -70,15 +71,18 @@ def _patch_agent_yamls(project_root: Path, publisher_name: str):
70
71
  if "language_support" not in agent_data:
71
72
  agent_data["language_support"] = ["English"]
72
73
  if "icon" not in agent_data:
73
- agent_data["icon"] = "inline-svg-of-icon"
74
+ agent_data["icon"] = AGENT_CATALOG_ONLY_PLACEHOLDERS['icon']
74
75
  if "category" not in agent_data:
75
76
  agent_data["category"] = "agent"
76
77
  if "supported_apps" not in agent_data:
77
78
  agent_data["supported_apps"] = []
79
+ if "agent_role" not in agent_data:
80
+ agent_data["agent_role"] = "manager" if agent_data.get("name") == parent_agent_name else "collaborator"
78
81
 
79
82
  with open(agent_yaml, "w") as f:
80
83
  yaml.safe_dump(agent_data, f, sort_keys=False)
81
84
 
85
+
82
86
  def _create_applications_entry(connection_config: dict) -> dict:
83
87
  return {
84
88
  'app_id': connection_config.get('app_id'),
@@ -116,6 +120,15 @@ class PartnersOfferingController:
116
120
  sys.exit(1)
117
121
 
118
122
  def create(self, offering: str, publisher_name: str, agent_type: str, agent_name: str):
123
+
124
+ # Sanitize offering name
125
+ original_offering = offering
126
+ offering = sanitize_catalog_label(offering)
127
+
128
+ if offering != original_offering:
129
+ logger.warning("Offering name must contain only alpahnumeric characters or underscore")
130
+ logger.info(f"Offering '{original_offering}' has been updated to '{offering}'")
131
+
119
132
  # Create parent project folder
120
133
  project_root = self.root / offering
121
134
 
@@ -179,7 +192,7 @@ class PartnersOfferingController:
179
192
  output_zip.unlink(missing_ok=True)
180
193
 
181
194
  # Patch the agent yamls with publisher, tags, icon, etc.
182
- _patch_agent_yamls(project_root, publisher_name)
195
+ _patch_agent_yamls(project_root=project_root, publisher_name=publisher_name, parent_agent_name=agent_name)
183
196
 
184
197
 
185
198
  # Create offering.yaml file -------------------------------------------------------
@@ -337,12 +350,16 @@ class PartnersOfferingController:
337
350
  **agent_data
338
351
  )
339
352
  agent = Agent.model_validate(agent_details)
340
- AgentsController().persist_record(agent=agent)
341
353
  case AgentKind.EXTERNAL:
342
354
  agent_details = parse_create_external_args(
343
355
  **agent_data
344
356
  )
345
357
  agent = ExternalAgent.model_validate(agent_details)
358
+
359
+ # Placeholder detection
360
+ for label,placeholder in AGENT_CATALOG_ONLY_PLACEHOLDERS.items():
361
+ if agent_data.get(label) == placeholder:
362
+ logger.warning(f"Placeholder '{label}' detected for agent '{agent_name}', please ensure '{label}' is correct before packaging.")
346
363
 
347
364
  agent_json_path = f"{top_level_folder}/agents/{agent_name}/config.json"
348
365
  zf.writestr(agent_json_path, json.dumps(agent_data, indent=2))
@@ -24,6 +24,10 @@ CATALOG_ONLY_FIELDS = [
24
24
  'supported_apps'
25
25
  ]
26
26
 
27
+ AGENT_CATALOG_ONLY_PLACEHOLDERS = {
28
+ 'icon': "inline-svg-of-icon",
29
+ }
30
+
27
31
  class AgentKind(str, Enum):
28
32
  NATIVE = "native"
29
33
  EXTERNAL = "external"
@@ -87,21 +91,9 @@ class Offering(BaseModel):
87
91
  return values
88
92
 
89
93
  def validate_ready_for_packaging(self):
90
- self.test_for_placeholder_values()
91
-
92
- def test_for_placeholder_values(self):
93
- placholders = False
94
- # part numbers
95
- if not self.part_number:
96
- raise ValueError(f"Offering '{self.name}' does not have valid part numbers")
97
-
98
- for (k,v) in self.part_number.model_dump().items():
99
- if v == CATALOG_PLACEHOLDERS['part_number']:
100
- logger.warning(f"Placeholder part number detected for platform '{k}', please ensure valid part numbers are entered before packaging.")
101
- placholders = True
102
-
103
- if placholders:
104
- raise ValueError(f"Offering '{self.name}' cannot be packaged with placeholder values")
94
+ # Leaving this fn here in case we want to reintroduce validation
95
+ pass
96
+
105
97
 
106
98
 
107
99
 
@@ -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: {
@@ -58,16 +58,16 @@ REGISTRY_URL=
58
58
 
59
59
 
60
60
 
61
- SERVER_TAG=17-10-2025-8a9aff2
61
+ SERVER_TAG=24-09-2025-17d7c67
62
62
  SERVER_REGISTRY=
63
63
 
64
- WORKER_TAG=17-10-2025-8a9aff2
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=16-09-2025-115ef29
70
+ AGENT_GATEWAY_TAG=19-10-2025-e48ad3a
71
71
  AGENT_GATEWAY_REGISTRY=
72
72
 
73
73
  DB_REGISTRY=
@@ -78,7 +78,7 @@ AMDDBTAG=17-09-2025-8a9aff2
78
78
  ARM64DBTAG=17-09-2025-8a9aff2
79
79
 
80
80
  UI_REGISTRY=
81
- UITAG=19-09-2025-188b5fe
81
+ UITAG=22-09-2025-e35f498
82
82
 
83
83
  CM_REGISTRY=
84
84
  CM_TAG=16-09-2025-e33b344
@@ -86,16 +86,16 @@ CM_TAG=16-09-2025-e33b344
86
86
  CONNECTIONS_UI_REGISTRY=
87
87
  CONNECTIONS_UI_TAG=15-09-2025-98aa9da
88
88
 
89
- TRM_TAG=15-09-2025-228f397
89
+ TRM_TAG=16-09-2025-cb6b9df
90
90
  TRM_REGISTRY=
91
91
 
92
- TR_TAG=15-09-2025-228f397
92
+ TR_TAG=24-09-2025-a515038
93
93
  TR_REGISTRY=
94
94
 
95
- BUILDER_TAG=19-09-2025-4ab5c88
95
+ BUILDER_TAG=24-09-2025-f9b68d8
96
96
  BUILDER_REGISTRY=
97
97
 
98
- FLOW_RUNTIME_TAG=15-09-2025-c208dc5
98
+ FLOW_RUNTIME_TAG=22-09-2025-0bd3f58
99
99
  FLOW_RUMTIME_REGISTRY=
100
100
 
101
101
 
@@ -35,6 +35,7 @@ def flow(*args,
35
35
  description: str|None=None,
36
36
  input_schema: type[BaseModel] | None = None,
37
37
  output_schema: type[BaseModel] | None = None,
38
+ private_schema: type[BaseModel] | None = None,
38
39
  initiators: Sequence[str] = (),
39
40
  schedulable: bool = False,
40
41
  llm_model: str|ListVirtualModel|None=None,
@@ -63,6 +64,7 @@ def flow(*args,
63
64
  description = node_spec.description,
64
65
  input_schema = input_schema,
65
66
  output_schema = output_schema,
67
+ private_schema = private_schema,
66
68
  initiators = initiators,
67
69
  schedulable = schedulable,
68
70
  llm_model = llm_model,
@@ -26,13 +26,13 @@ from ibm_watsonx_orchestrate.client.tools.tool_client import ToolClient
26
26
  from ibm_watsonx_orchestrate.client.tools.tempus_client import TempusClient
27
27
  from ibm_watsonx_orchestrate.client.utils import instantiate_client
28
28
  from ..types import (
29
- 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,
30
30
  StartNodeSpec, ToolSpec, JsonSchemaObject, ToolRequestBody, ToolResponseBody, UserFieldKind, UserFieldOption, UserFlowSpec, UserNodeSpec, WaitPolicy,
31
31
  DocProcSpec, TextExtractionResponse, DocProcInput, DecisionsNodeSpec, DecisionsRule, DocExtSpec, File, DocumentClassificationResponse, DocClassifierSpec, DocumentProcessingCommonInput
32
32
  )
33
33
  from .constants import CURRENT_USER, START, END, ANY_USER
34
34
  from ..node import (
35
- 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
36
36
  )
37
37
  from ..types import (
38
38
  AgentNodeSpec, extract_node_spec, FlowContext, FlowEventType, FlowEvent, FlowSpec,
@@ -357,6 +357,41 @@ class Flow(Node):
357
357
 
358
358
  node = self._add_node(node)
359
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)
360
395
 
361
396
 
362
397
  def _add_node(self, node: Node) -> Node:
@@ -1245,6 +1280,7 @@ class FlowFactory(BaseModel):
1245
1280
  initiators: Sequence[str]|None=None,
1246
1281
  input_schema: type[BaseModel]|None=None,
1247
1282
  output_schema: type[BaseModel]|None=None,
1283
+ private_schema: type[BaseModel]|None=None,
1248
1284
  schedulable: bool=False,
1249
1285
  llm_model: str|ListVirtualModel|None=None,
1250
1286
  agent_conversation_memory_turns_limit: int|None = None) -> Flow:
@@ -1257,6 +1293,7 @@ class FlowFactory(BaseModel):
1257
1293
  input_schema_obj = _get_json_schema_obj(parameter_name = "input", type_def = input_schema)
1258
1294
  # create input spec
1259
1295
  output_schema_obj = _get_json_schema_obj("output", output_schema)
1296
+ private_schema_obj = _get_json_schema_obj("private", private_schema)
1260
1297
  if initiators is None:
1261
1298
  initiators = []
1262
1299
 
@@ -1268,6 +1305,7 @@ class FlowFactory(BaseModel):
1268
1305
  initiators=initiators,
1269
1306
  input_schema=_get_tool_request_body(input_schema_obj),
1270
1307
  output_schema=_get_tool_response_body(output_schema_obj),
1308
+ private_schema = private_schema_obj,
1271
1309
  output_schema_object = output_schema_obj,
1272
1310
  schedulable=schedulable,
1273
1311
  )
@@ -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
@@ -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):
@@ -389,6 +389,19 @@ class ToolNodeSpec(NodeSpec):
389
389
  else:
390
390
  model_spec["tool"] = self.tool
391
391
  return model_spec
392
+
393
+ class ScriptNodeSpec(NodeSpec):
394
+ fn: str = Field(default = None, description="the script to execute")
395
+
396
+ def __init__(self, **data):
397
+ super().__init__(**data)
398
+ self.kind = "script"
399
+
400
+ def to_json(self) -> dict[str, Any]:
401
+ model_spec = super().to_json()
402
+ if self.fn:
403
+ model_spec["fn"] = self.fn
404
+ return model_spec
392
405
 
393
406
 
394
407
  class UserFieldValue(BaseModel):
@@ -871,6 +884,9 @@ class FlowSpec(NodeSpec):
871
884
  initiators: Sequence[str] = [ANY_USER]
872
885
  schedulable: bool = False
873
886
 
887
+ # flow can have private schema
888
+ private_schema: JsonSchemaObject | SchemaRef | None = None
889
+
874
890
  def __init__(self, **kwargs):
875
891
  super().__init__(**kwargs)
876
892
  self.kind = "flow"
@@ -879,6 +895,8 @@ class FlowSpec(NodeSpec):
879
895
  model_spec = super().to_json()
880
896
  if self.initiators:
881
897
  model_spec["initiators"] = self.initiators
898
+ if self.private_schema:
899
+ model_spec["private_schema"] = _to_json_from_json_schema(self.private_schema)
882
900
 
883
901
  model_spec["schedulable"] = self.schedulable
884
902
 
File without changes
@@ -0,0 +1,195 @@
1
+ import logging
2
+ import ast
3
+ import sys
4
+ from pathlib import Path
5
+ import importlib.util
6
+
7
+ from pydantic import BaseModel
8
+
9
+ from .lfx_deps import LFX_DEPENDENCIES
10
+
11
+ logger = logging.getLogger(__name__)
12
+
13
+ class LangflowComponent(BaseModel):
14
+ id: str
15
+ name: str
16
+ credentials: dict
17
+ requirements: list[str] = []
18
+
19
+ class LangflowModelSpec(BaseModel):
20
+ version: str
21
+ components: list[LangflowComponent]
22
+
23
+ _MODULE_MAP = {
24
+ "mem0":"mem0ai",
25
+ }
26
+
27
+ import math
28
+ from collections import Counter
29
+
30
+ def _calculate_entropy(s):
31
+ """
32
+ Calculates the Shannon entropy of a string.
33
+
34
+ Parameters:
35
+ s (str): Input string.
36
+
37
+ Returns:
38
+ float: Shannon entropy value.
39
+ """
40
+ if not s:
41
+ return 0.0
42
+
43
+ freq = Counter(s)
44
+ length = len(s)
45
+
46
+ entropy = -sum((count / length) * math.log2(count / length) for count in freq.values())
47
+ return entropy
48
+
49
+ def _mask_api_key(key):
50
+ """
51
+ Masks an API key by keeping the first 5 characters visible,
52
+ masking the rest with asterisks, and truncating the result to a maximum of 25 characters.
53
+
54
+ Parameters:
55
+ key (str): The API key string.
56
+
57
+ Returns:
58
+ str: Masked and truncated API key.
59
+ """
60
+ if not isinstance(key, str):
61
+ return key
62
+
63
+ # if this is a potential real API key -- mask it
64
+ if _calculate_entropy(key) > 4.1:
65
+ visible_part = key[:5]
66
+ masked_part = '*' * (len(key) - 5)
67
+ masked_key = visible_part + masked_part
68
+
69
+ return masked_key[:25]
70
+ elif len(key) > 25:
71
+ # if the key is longer than 25 characters, truncates it anyway
72
+ return key[:22] + '...'
73
+
74
+ return key
75
+
76
+ def _extract_imports(source_code) -> list[str]:
77
+ tree = ast.parse(source_code)
78
+ imports = set()
79
+ for node in ast.walk(tree):
80
+ if isinstance(node, ast.Import):
81
+ for alias in node.names:
82
+ # we only need the module name, not sub-module
83
+ imports.add(alias.name.split('.')[0])
84
+ elif isinstance(node, ast.ImportFrom):
85
+ if node.module:
86
+ # we only need the module name, not sub-module
87
+ imports.add(node.module.split('.')[0])
88
+ return sorted(imports)
89
+
90
+
91
+
92
+ def _is_builtin_module(module_name: str) -> bool:
93
+ underscore_module_name = f"_{module_name}"
94
+
95
+ # Check against the list of standard modules
96
+ if module_name in sys.stdlib_module_names:
97
+ return True
98
+
99
+ if underscore_module_name in sys.stdlib_module_names:
100
+ return True
101
+
102
+ # Check against the list of built-in module names
103
+ if module_name in sys.builtin_module_names:
104
+ return True
105
+
106
+ if underscore_module_name in sys.builtin_module_names:
107
+ return True
108
+
109
+ # Use importlib to find the module spec
110
+ spec = importlib.util.find_spec(module_name)
111
+ if spec is None:
112
+ return False # Module not found
113
+
114
+ # Check if the loader is a BuiltinImporter
115
+ return isinstance(spec.loader, importlib.machinery.BuiltinImporter)
116
+
117
+
118
+ def _find_missing_requirements(imported_modules, requirements_modules: list[str]) -> list[str]:
119
+ """
120
+ Compare imported modules with requirements.txt and return missing ones.
121
+
122
+ Parameters:
123
+ imported_modules (list): List of module names used in the code.
124
+ requirements_file_path (str): Path to the requirements.txt file.
125
+
126
+ Returns:
127
+ list: Modules that are imported but not listed in requirements.txt.
128
+ """
129
+ def normalize_module_name(name):
130
+ module_name = name.split('.')[0].lower()
131
+ # sometimes the module name in pipy is different than the real name
132
+ if module_name in _MODULE_MAP:
133
+ module_name = _MODULE_MAP[module_name]
134
+ return module_name
135
+
136
+ # Normalize imported module names
137
+ normalized_imports = [normalize_module_name(mod) for mod in imported_modules]
138
+
139
+ # filter out all built-ins
140
+ filtered_imports = [
141
+ module for module in normalized_imports
142
+ if _is_builtin_module(module) is False
143
+ ]
144
+
145
+ # Compare and find missing modules
146
+ missing_modules = [
147
+ module for module in filtered_imports
148
+ if module not in requirements_modules
149
+ ]
150
+
151
+ return missing_modules
152
+
153
+
154
+
155
+ def parse_langflow_model(model) -> LangflowModelSpec:
156
+ """
157
+ Extracts component details and Langflow version from a Langflow JSON object.
158
+
159
+ Parameters:
160
+ model (dict): The Langflow JSON object.
161
+
162
+ Returns:
163
+ LangflowModelSpec: A LangflowModelSpec object containing the extracted version and component information.
164
+ """
165
+ version = model.get("last_tested_version", "Unknown")
166
+ components = []
167
+ data = model.get('data', {} )
168
+
169
+ # get the list of available modules
170
+ requirements_modules = LFX_DEPENDENCIES
171
+
172
+ for node in data.get("nodes", []):
173
+ node_data = node.get("data", {})
174
+ node_info = node_data.get("node", {})
175
+ template = node_info.get("template", {})
176
+ code = template.get("code")
177
+ credentials = {}
178
+
179
+ missing_imports = []
180
+ for field_name, field_info in template.items():
181
+ if isinstance(field_info, dict) and field_info.get("password", False) == True:
182
+ credentials[field_name] = _mask_api_key(field_info.get("value"))
183
+
184
+ if code and code.get("value") != None:
185
+ imports = _extract_imports(code.get("value"))
186
+ if len(imports) > 0:
187
+ missing_imports = _find_missing_requirements(imports, requirements_modules)
188
+
189
+ component_info = LangflowComponent(name=node_info.get("display_name", "Unknown"), id=node_data.get("id", "Unknown"),
190
+ credentials=credentials, requirements=missing_imports)
191
+
192
+ components.append(component_info)
193
+
194
+ return LangflowModelSpec(version=version, components=components)
195
+
@@ -0,0 +1,84 @@
1
+ LFX_DEPENDENCIES = [
2
+ "aiofile",
3
+ "aiofiles",
4
+ "annotated-types",
5
+ "anyio",
6
+ "asyncer",
7
+ "cachetools",
8
+ "caio",
9
+ "certifi",
10
+ "chardet",
11
+ "charset-normalizer",
12
+ "click",
13
+ "defusedxml",
14
+ "docstring_parser",
15
+ "emoji",
16
+ "fastapi",
17
+ "h11",
18
+ "h2",
19
+ "hpack",
20
+ "httpcore",
21
+ "httpx",
22
+ "hyperframe",
23
+ "idna",
24
+ "json_repair",
25
+ "jsonpatch",
26
+ "jsonpointer",
27
+ "langchain",
28
+ "langchain-core",
29
+ "langchain-text-splitters",
30
+ "langsmith",
31
+ "lfx-nightly",
32
+ "loguru",
33
+ "markdown-it-py",
34
+ "mdurl",
35
+ "nanoid",
36
+ "networkx",
37
+ "numpy",
38
+ "orjson",
39
+ "packaging",
40
+ "pandas",
41
+ "passlib",
42
+ "pillow",
43
+ "platformdirs",
44
+ "pydantic",
45
+ "pydantic-settings",
46
+ "pydantic_core",
47
+ "Pygments",
48
+ "python-dateutil",
49
+ "python-dotenv",
50
+ "pytz",
51
+ "PyYAML",
52
+ "requests",
53
+ "requests-toolbelt",
54
+ "rich",
55
+ "shellingham",
56
+ "six",
57
+ "sniffio",
58
+ "SQLAlchemy",
59
+ "starlette",
60
+ "structlog",
61
+ "tenacity",
62
+ "tomli",
63
+ "typer",
64
+ "typing-inspection",
65
+ "typing_extensions",
66
+ "tzdata",
67
+ "urllib3",
68
+ "uvicorn",
69
+ "validators",
70
+ "zstandard",
71
+ "langflow",
72
+ "langchain_openai",
73
+ "langchain_core",
74
+ "langchain_text_splitters",
75
+ "collections",
76
+ "typing",
77
+ "datetime",
78
+ "zoneinfo",
79
+ "or",
80
+ "re",
81
+ "os",
82
+ "copy",
83
+ "json"
84
+ ]
@@ -11,8 +11,12 @@ def yaml_safe_load(file : BinaryIO) -> dict:
11
11
  return yaml.safe_load(file)
12
12
 
13
13
  def sanitize_app_id(app_id: str) -> str:
14
- sanatize_pattern = re.compile(r"[^a-zA-Z0-9]+")
15
- return re.sub(sanatize_pattern,'_', app_id)
14
+ sanitize_pattern = re.compile(r"[^a-zA-Z0-9]+")
15
+ return re.sub(sanitize_pattern,'_', app_id)
16
+
17
+ def sanitize_catalog_label(label: str) -> str:
18
+ sanitize_pattern = re.compile(r"[^a-zA-Z0-9]+")
19
+ return re.sub(sanitize_pattern,'_', label)
16
20
 
17
21
  def check_file_in_zip(file_path: str, zip_file: zipfile.ZipFile) -> bool:
18
22
  return any(x.startswith("%s/" % file_path.rstrip("/")) for x in zip_file.namelist())
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ibm-watsonx-orchestrate
3
- Version: 1.12.0b1
3
+ Version: 1.12.1
4
4
  Summary: IBM watsonx.orchestrate SDK
5
5
  Author-email: IBM <support@ibm.com>
6
6
  License: MIT License
@@ -11,7 +11,7 @@ Requires-Dist: click<8.2.0,>=8.0.0
11
11
  Requires-Dist: docstring-parser<1.0,>=0.16
12
12
  Requires-Dist: httpx<1.0.0,>=0.28.1
13
13
  Requires-Dist: ibm-cloud-sdk-core>=3.24.2
14
- Requires-Dist: ibm-watsonx-orchestrate-evaluation-framework==1.1.2
14
+ Requires-Dist: ibm-watsonx-orchestrate-evaluation-framework==1.1.3
15
15
  Requires-Dist: jsonref==1.1.0
16
16
  Requires-Dist: langchain-core<=0.3.63
17
17
  Requires-Dist: langsmith<=0.3.45
@@ -1,4 +1,4 @@
1
- ibm_watsonx_orchestrate/__init__.py,sha256=rt1KcSzKVydKqrDL4jMLsj3SqC4D4KxFkrjnHfXBsmU,427
1
+ ibm_watsonx_orchestrate/__init__.py,sha256=f3ba5wWbOhu85odqw41PZ_43Yy6-yhTc1WglmHJGkLU,426
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
@@ -23,7 +23,7 @@ ibm_watsonx_orchestrate/agent_builder/toolkits/types.py,sha256=RGkS01_fqbs-7YFFZ
23
23
  ibm_watsonx_orchestrate/agent_builder/tools/__init__.py,sha256=R07j4zERCBX22ILsGBl3qRw0poaVSONPnMZ_69bAFDw,519
24
24
  ibm_watsonx_orchestrate/agent_builder/tools/base_tool.py,sha256=qiVHqLN-S9AuJlsvVaV_kNN5oNi4kk6177Hi9KpEdaI,1240
25
25
  ibm_watsonx_orchestrate/agent_builder/tools/flow_tool.py,sha256=DJWYVmIjw1O_cbzPpwU0a_vIZGvo0mj8UsjW9zkKMlA,2589
26
- ibm_watsonx_orchestrate/agent_builder/tools/langflow_tool.py,sha256=kB_wjGPXkkldbwdeD6dZFGicIMQ4REMH_ADu6l6Xb2c,4229
26
+ ibm_watsonx_orchestrate/agent_builder/tools/langflow_tool.py,sha256=beozS44KQkjy3hjUn17Sy1xoPZyviu7o3_ez4KGtJgU,6843
27
27
  ibm_watsonx_orchestrate/agent_builder/tools/openapi_tool.py,sha256=haAN5t4YMGrVM788UdMxfMWUctOe6_3szGxsRF3KPr8,19730
28
28
  ibm_watsonx_orchestrate/agent_builder/tools/python_tool.py,sha256=cdgu-v1oRR9RUbMNKEklOzO1z3nNZpDZPSMwnJEvuIY,12533
29
29
  ibm_watsonx_orchestrate/agent_builder/tools/types.py,sha256=8Esn77LZSBNTiKOpvRXF35LUFnfydyvZ-oxAQJyt1wE,8931
@@ -31,7 +31,7 @@ ibm_watsonx_orchestrate/agent_builder/utils/__init__.py,sha256=47DEQpj8HBSa-_TIm
31
31
  ibm_watsonx_orchestrate/agent_builder/voice_configurations/__init__.py,sha256=W3-T8PH_KuONsCQPILQAvW2Nz25p7dp9AZbWHWGJXhA,37
32
32
  ibm_watsonx_orchestrate/agent_builder/voice_configurations/types.py,sha256=lSS1yiDzVAMkEdOwcI4_1DUuRnu_6oc8XupQtoE4Fvs,3989
33
33
  ibm_watsonx_orchestrate/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
- ibm_watsonx_orchestrate/cli/config.py,sha256=iXjDxymWhAmLSUu6eh7zJR20dYZDzbxcU5VoBdh3VIw,8318
34
+ ibm_watsonx_orchestrate/cli/config.py,sha256=ZcuOhd-zXZQ6N0yMM3DLpz9SKHywiB1djk6SrAqGDOk,8435
35
35
  ibm_watsonx_orchestrate/cli/init_helper.py,sha256=qxnKdFcPtGsV_6RqP_IuLshRxgB004SxzDAkBTExA-4,1675
36
36
  ibm_watsonx_orchestrate/cli/main.py,sha256=5AuoVVDHzgNZ6Y2ZR4bSF1cs7AhQRyd8n7S41o8lK4w,3618
37
37
  ibm_watsonx_orchestrate/cli/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -48,11 +48,11 @@ ibm_watsonx_orchestrate/cli/commands/connections/connections_controller.py,sha25
48
48
  ibm_watsonx_orchestrate/cli/commands/copilot/copilot_command.py,sha256=IxasApIyQYWRMKPXKa38ZPVkUvOc4chggSmSGjgQGXc,2345
49
49
  ibm_watsonx_orchestrate/cli/commands/copilot/copilot_controller.py,sha256=SC2Tjq6r-tHIiyPBMajsxdMIY3BQpRWpkYGZS2XbJyU,18981
50
50
  ibm_watsonx_orchestrate/cli/commands/copilot/copilot_server_controller.py,sha256=9MXS5uE3esKp3IYILVty7COFcr9iJ90axkAqPVaJ1NE,3874
51
- ibm_watsonx_orchestrate/cli/commands/environment/environment_command.py,sha256=SUyz2RJoh5dToXRkXRwkUMjT_3OmrxSJFb-osiF2Tw4,3828
52
- ibm_watsonx_orchestrate/cli/commands/environment/environment_controller.py,sha256=oHZ7LONtPg3-SSnU_rRZryLi8N2mplz5h-LGg4XjzD4,10261
51
+ ibm_watsonx_orchestrate/cli/commands/environment/environment_command.py,sha256=1CO0UfxSem0NafNGNCBXswC-P93MVYIA-YJewjKgdNc,4186
52
+ ibm_watsonx_orchestrate/cli/commands/environment/environment_controller.py,sha256=z3m4khZfHNpv1dRsDfRW0cteLvhAeDEbxh-fOZduSpQ,10479
53
53
  ibm_watsonx_orchestrate/cli/commands/environment/types.py,sha256=X6jEnyBdxakromA7FhQ5btZMj9kwGcwRSFz8vpD65jA,224
54
- ibm_watsonx_orchestrate/cli/commands/evaluations/evaluations_command.py,sha256=aTiD8HMg1a6m8XZotHejWNw-h8K5sNT6VJyFzO2HXhY,21828
55
- ibm_watsonx_orchestrate/cli/commands/evaluations/evaluations_controller.py,sha256=c4dw2ckiO689Zh9jXkrQe4GisJStEhAZoTBbdlOzRyE,11315
54
+ ibm_watsonx_orchestrate/cli/commands/evaluations/evaluations_command.py,sha256=0ET6tXMkeupT8K5hNGQBgLOhlV8YAshqH3bp9A8vgDk,21930
55
+ ibm_watsonx_orchestrate/cli/commands/evaluations/evaluations_controller.py,sha256=avA5Guyyhqw9x0IAp-I9vVyEaS3X5U77Ag4xBw1k8l0,11348
56
56
  ibm_watsonx_orchestrate/cli/commands/knowledge_bases/knowledge_bases_command.py,sha256=hOzRcGVoqq7dTc4bSregKxH-kYbrVqaFdhBLawqnRNo,2668
57
57
  ibm_watsonx_orchestrate/cli/commands/knowledge_bases/knowledge_bases_controller.py,sha256=d9RSBy2S2nn8vWrghovGb1owe7Zu8LywOm0nIdzlXiU,11567
58
58
  ibm_watsonx_orchestrate/cli/commands/login/login_command.py,sha256=xArMiojoozg7Exn6HTpbTcjDO2idZRA-y0WV-_Ic1Sk,651
@@ -62,8 +62,8 @@ ibm_watsonx_orchestrate/cli/commands/models/models_controller.py,sha256=wcy16LPZ
62
62
  ibm_watsonx_orchestrate/cli/commands/partners/partners_command.py,sha256=YpTlKKinQw1QdM4yXYjSrMtoAcwc1b9GoO6Wv1NmgKc,385
63
63
  ibm_watsonx_orchestrate/cli/commands/partners/partners_controller.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
64
64
  ibm_watsonx_orchestrate/cli/commands/partners/offering/partners_offering_command.py,sha256=X6u5zGwKYY1Uc2szaVHCIyMlFJBzp8o8JgVZUxcZPd8,1727
65
- ibm_watsonx_orchestrate/cli/commands/partners/offering/partners_offering_controller.py,sha256=RX0DDdpZ07mEtURF_-4uCY4lgCidbYnK4x1Y62bqvLw,18256
66
- ibm_watsonx_orchestrate/cli/commands/partners/offering/types.py,sha256=y69q4w9Kz9_n8KmvGhZa_SNyTdm_qjwhbRSlm02qPio,3352
65
+ ibm_watsonx_orchestrate/cli/commands/partners/offering/partners_offering_controller.py,sha256=4qIaMwUHcSsPDDqXHS0vuwktyFD18sQyFabbBhr8vjY,19229
66
+ ibm_watsonx_orchestrate/cli/commands/partners/offering/types.py,sha256=Wc7YyY3dQobx5P5-as45WmTiZiuiSzvSSSDZP-5vj-g,2804
67
67
  ibm_watsonx_orchestrate/cli/commands/server/server_command.py,sha256=cMjaAXEPMN-OkenqIbckPisPV093rabOxkLKmNiyxTc,28956
68
68
  ibm_watsonx_orchestrate/cli/commands/server/types.py,sha256=DGLopPbLFf5yH5-hzsFf5Uaw158QHwkTAcwydbUmZ3Q,4416
69
69
  ibm_watsonx_orchestrate/cli/commands/settings/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -75,7 +75,7 @@ ibm_watsonx_orchestrate/cli/commands/settings/observability/langfuse/langfuse_co
75
75
  ibm_watsonx_orchestrate/cli/commands/toolkit/toolkit_command.py,sha256=dgmfI3PA04By3W526BEOZp0jJE5eVoxEUMbPG0JxUlE,5653
76
76
  ibm_watsonx_orchestrate/cli/commands/toolkit/toolkit_controller.py,sha256=lo9xahKQiPhm4xh97O_twkzLO0GhXDzAi1rZT0ybQpA,13027
77
77
  ibm_watsonx_orchestrate/cli/commands/tools/tools_command.py,sha256=1RXndNL8Ztl6YEVl4rW6sg0m0hE9d0RhT2Oac45ui2M,3945
78
- ibm_watsonx_orchestrate/cli/commands/tools/tools_controller.py,sha256=Q5ZqS5j7FXcVdnuQXcOUTACPJchBEBxrYWh9NM0RLaQ,47593
78
+ ibm_watsonx_orchestrate/cli/commands/tools/tools_controller.py,sha256=nq-cmGfwqscOwtaUlm1feI-eUp1kIDG96XcABX1a3QU,49492
79
79
  ibm_watsonx_orchestrate/cli/commands/tools/types.py,sha256=_md0GEa_cTH17NO_moWDY_LNdFvyEFQ1UVB9_FltYiA,173
80
80
  ibm_watsonx_orchestrate/cli/commands/voice_configurations/voice_configurations_command.py,sha256=q4KHWQ-LZbp31e2ytihX1OuyAPS4-nRinmc-eMXC0l0,1783
81
81
  ibm_watsonx_orchestrate/cli/commands/voice_configurations/voice_configurations_controller.py,sha256=JbAc_CY0woHY8u7qrnOcb9O2FgECzkzeMirxFhRoep8,5884
@@ -108,7 +108,7 @@ ibm_watsonx_orchestrate/client/tools/tempus_client.py,sha256=iD7Hkzn_LdnFivAzGSV
108
108
  ibm_watsonx_orchestrate/client/tools/tool_client.py,sha256=kYwQp-ym9dYQDOFSTnXNyeh8wzl39LpBJqHSNT9EKT0,2113
109
109
  ibm_watsonx_orchestrate/client/voice_configurations/voice_configurations_client.py,sha256=M5xIPLiVNpP-zxQw8CTNT9AiBjeXXmJiNaE142e2A3E,2682
110
110
  ibm_watsonx_orchestrate/docker/compose-lite.yml,sha256=niF_ir68D_YdjrZWGUOy8eNLV-K5PX_xVWhdZEC2Crk,48041
111
- ibm_watsonx_orchestrate/docker/default.env,sha256=n5dKgNpnKpA-bsJqlrg17K7UqutFGk1bBvtyReCaZpw,6372
111
+ ibm_watsonx_orchestrate/docker/default.env,sha256=eR-j22xztFZV4pEpXFupbNTUXd4nv2z8B6rKbAUkR50,6372
112
112
  ibm_watsonx_orchestrate/docker/proxy-config-single.yaml,sha256=WEbK4ENFuTCYhzRu_QblWp1_GMARgZnx5vReQafkIG8,308
113
113
  ibm_watsonx_orchestrate/docker/start-up.sh,sha256=LTtwHp0AidVgjohis2LXGvZnkFQStOiUAxgGABOyeUI,1811
114
114
  ibm_watsonx_orchestrate/docker/sdk/ibm_watsonx_orchestrate-0.6.0-py3-none-any.whl,sha256=Hi3-owh5OM0Jz2ihX9nLoojnr7Ky1TV-GelyqLcewLE,2047417
@@ -116,26 +116,29 @@ ibm_watsonx_orchestrate/docker/sdk/ibm_watsonx_orchestrate-0.6.0.tar.gz,sha256=e
116
116
  ibm_watsonx_orchestrate/docker/tempus/common-config.yaml,sha256=Zo3F36F5DV4VO_vUg1RG-r4WhcukVh79J2fXhGl6j0A,22
117
117
  ibm_watsonx_orchestrate/flow_builder/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
118
118
  ibm_watsonx_orchestrate/flow_builder/data_map.py,sha256=LinePFgb5mBnrvNmPkFe3rq5oYJZSjcgmaEGpE6dVwc,586
119
- ibm_watsonx_orchestrate/flow_builder/node.py,sha256=ON1A3bhNVfB4Bxns6eUmL2Z1JPNi4bv21AjAE3m0ApU,9960
120
- ibm_watsonx_orchestrate/flow_builder/types.py,sha256=Gb8YoNCF7i9Fph2999EO9ERikv0kANitTCLEZp732Es,70004
119
+ ibm_watsonx_orchestrate/flow_builder/node.py,sha256=Y5hzVkbWNWaYp6zSbLW4Qbg4r1deLAs-X3HEFoZ9vzk,10338
120
+ ibm_watsonx_orchestrate/flow_builder/types.py,sha256=3mpLKOVgQBwWBVJAfF7GQF2wPZKYwDniJCUnaJypYTA,70606
121
121
  ibm_watsonx_orchestrate/flow_builder/utils.py,sha256=8q1jr5i_TzoJpoQxmLiO0g5Uv03BLbTUaRfw8_0VWIY,11931
122
122
  ibm_watsonx_orchestrate/flow_builder/flows/__init__.py,sha256=iRYV0_eXgBBGhuNnvg-mUyPUyCIw5BiallPOp27bzYM,1083
123
123
  ibm_watsonx_orchestrate/flow_builder/flows/constants.py,sha256=-TGneZyjA4YiAtJJK7OmmjDHYQC4mw2e98MPAZqiB50,324
124
- ibm_watsonx_orchestrate/flow_builder/flows/decorators.py,sha256=uNoWIwFTfLQ134SoJQqPvIpZ14LuLFNsUVAxgBRqBBA,3129
124
+ ibm_watsonx_orchestrate/flow_builder/flows/decorators.py,sha256=07yaaDXLrwmj0v9lhZli8UmnKVpIuF6x1t3JbPVj0F8,3247
125
125
  ibm_watsonx_orchestrate/flow_builder/flows/events.py,sha256=VyaBm0sADwr15LWfKbcBQS1M80NKqzYDj3UlW3OpOf4,2984
126
- ibm_watsonx_orchestrate/flow_builder/flows/flow.py,sha256=9n4KMi4YNAua-qGQIjn3jPi0IqnmBEDT15C-PaU81ug,66373
126
+ ibm_watsonx_orchestrate/flow_builder/flows/flow.py,sha256=wPCpDT-RFJZsiDYNPLteWQRpSQl86urEbCi6UurCqfg,67946
127
+ ibm_watsonx_orchestrate/langflow/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
128
+ ibm_watsonx_orchestrate/langflow/langflow_utils.py,sha256=UIWN28WvaYNhV-Ph_x0HSqV7jbL8lQlaUBdYeELqXJo,5765
129
+ ibm_watsonx_orchestrate/langflow/lfx_deps.py,sha256=Bgbo8IQEX_TblGLmw1tnA0DP7Xm4SFRncPp4TGbqY1o,1396
127
130
  ibm_watsonx_orchestrate/run/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
128
131
  ibm_watsonx_orchestrate/run/connections.py,sha256=9twXkNeUx83fP_qYUbJRtumE-wzPPNN2v-IY_8hGndM,1820
129
132
  ibm_watsonx_orchestrate/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
130
133
  ibm_watsonx_orchestrate/utils/docker_utils.py,sha256=yDaeMToD7PSptuzCguEN8zPDyvPlwDR3ORutffldbuM,11355
131
134
  ibm_watsonx_orchestrate/utils/environment.py,sha256=MBNhZsGuhL7-9HL-0ln6RwgiqfXXZqvSCyHcIQypuc8,14549
132
135
  ibm_watsonx_orchestrate/utils/exceptions.py,sha256=MjpoGuk7lMziPT2Zo7X-jgGlm0M22mTZF4Y8EHb3KPM,631
133
- ibm_watsonx_orchestrate/utils/utils.py,sha256=FUSIig8owxN0p9xTpWiTG-VIQKky4cwO52hI1h6R5xc,721
136
+ ibm_watsonx_orchestrate/utils/utils.py,sha256=X7kV4VgLEA82IdD5QNY90gdk_BZ6WcxqLLe6X8Q6DQU,868
134
137
  ibm_watsonx_orchestrate/utils/logging/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
135
138
  ibm_watsonx_orchestrate/utils/logging/logger.py,sha256=FzeGnidXAjC7yHrvIaj4KZPeaBBSCniZFlwgr5yV3oA,1037
136
139
  ibm_watsonx_orchestrate/utils/logging/logging.yaml,sha256=9_TKfuFr1barnOKP0fZT5D6MhddiwsXVTFjtRbcOO5w,314
137
- ibm_watsonx_orchestrate-1.12.0b1.dist-info/METADATA,sha256=HdxUlECeuTZ6ItU5o4SZPuje-s2Rw1GPiokHl8iOnW0,1363
138
- ibm_watsonx_orchestrate-1.12.0b1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
139
- ibm_watsonx_orchestrate-1.12.0b1.dist-info/entry_points.txt,sha256=SfIT02-Jen5e99OcLhzbcM9Bdyf8SGVOCtnSplgZdQI,69
140
- ibm_watsonx_orchestrate-1.12.0b1.dist-info/licenses/LICENSE,sha256=Shgxx7hTdCOkiVRmfGgp_1ISISrwQD7m2f0y8Hsapl4,1083
141
- ibm_watsonx_orchestrate-1.12.0b1.dist-info/RECORD,,
140
+ ibm_watsonx_orchestrate-1.12.1.dist-info/METADATA,sha256=JuOchl70FsR2MBshmh_rutVDS8lEs9kkChhMXInbgso,1361
141
+ ibm_watsonx_orchestrate-1.12.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
142
+ ibm_watsonx_orchestrate-1.12.1.dist-info/entry_points.txt,sha256=SfIT02-Jen5e99OcLhzbcM9Bdyf8SGVOCtnSplgZdQI,69
143
+ ibm_watsonx_orchestrate-1.12.1.dist-info/licenses/LICENSE,sha256=Shgxx7hTdCOkiVRmfGgp_1ISISrwQD7m2f0y8Hsapl4,1083
144
+ ibm_watsonx_orchestrate-1.12.1.dist-info/RECORD,,