ibm-watsonx-orchestrate 1.7.0a0__py3-none-any.whl → 1.8.0b0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. ibm_watsonx_orchestrate/__init__.py +1 -1
  2. ibm_watsonx_orchestrate/agent_builder/agents/agent.py +3 -3
  3. ibm_watsonx_orchestrate/agent_builder/agents/assistant_agent.py +3 -2
  4. ibm_watsonx_orchestrate/agent_builder/agents/external_agent.py +3 -2
  5. ibm_watsonx_orchestrate/agent_builder/agents/types.py +26 -9
  6. ibm_watsonx_orchestrate/agent_builder/agents/webchat_customizations/prompts.py +1 -0
  7. ibm_watsonx_orchestrate/agent_builder/connections/connections.py +25 -10
  8. ibm_watsonx_orchestrate/agent_builder/connections/types.py +5 -9
  9. ibm_watsonx_orchestrate/agent_builder/knowledge_bases/knowledge_base_requests.py +1 -22
  10. ibm_watsonx_orchestrate/agent_builder/knowledge_bases/types.py +1 -17
  11. ibm_watsonx_orchestrate/agent_builder/tools/base_tool.py +2 -1
  12. ibm_watsonx_orchestrate/agent_builder/tools/openapi_tool.py +14 -13
  13. ibm_watsonx_orchestrate/agent_builder/tools/python_tool.py +136 -92
  14. ibm_watsonx_orchestrate/agent_builder/tools/types.py +10 -9
  15. ibm_watsonx_orchestrate/cli/commands/agents/agents_command.py +7 -7
  16. ibm_watsonx_orchestrate/cli/commands/agents/agents_controller.py +35 -7
  17. ibm_watsonx_orchestrate/cli/commands/channels/webchat/channels_webchat_controller.py +33 -23
  18. ibm_watsonx_orchestrate/cli/commands/chat/chat_command.py +2 -0
  19. ibm_watsonx_orchestrate/cli/commands/connections/connections_controller.py +6 -4
  20. ibm_watsonx_orchestrate/cli/commands/copilot/copilot_command.py +65 -0
  21. ibm_watsonx_orchestrate/cli/commands/copilot/copilot_controller.py +293 -0
  22. ibm_watsonx_orchestrate/cli/commands/copilot/copilot_server_controller.py +154 -0
  23. ibm_watsonx_orchestrate/cli/commands/environment/environment_controller.py +6 -6
  24. ibm_watsonx_orchestrate/cli/commands/environment/types.py +2 -0
  25. ibm_watsonx_orchestrate/cli/commands/evaluations/evaluations_command.py +118 -30
  26. ibm_watsonx_orchestrate/cli/commands/evaluations/evaluations_controller.py +22 -9
  27. ibm_watsonx_orchestrate/cli/commands/knowledge_bases/knowledge_bases_command.py +0 -18
  28. ibm_watsonx_orchestrate/cli/commands/knowledge_bases/knowledge_bases_controller.py +33 -19
  29. ibm_watsonx_orchestrate/cli/commands/models/models_command.py +1 -1
  30. ibm_watsonx_orchestrate/cli/commands/server/server_command.py +66 -9
  31. ibm_watsonx_orchestrate/cli/commands/toolkit/toolkit_command.py +1 -1
  32. ibm_watsonx_orchestrate/cli/commands/tools/tools_controller.py +93 -14
  33. ibm_watsonx_orchestrate/cli/config.py +3 -3
  34. ibm_watsonx_orchestrate/cli/init_helper.py +10 -1
  35. ibm_watsonx_orchestrate/cli/main.py +5 -0
  36. ibm_watsonx_orchestrate/client/base_api_client.py +12 -0
  37. ibm_watsonx_orchestrate/client/copilot/cpe/copilot_cpe_client.py +66 -0
  38. ibm_watsonx_orchestrate/client/knowledge_bases/knowledge_base_client.py +1 -1
  39. ibm_watsonx_orchestrate/client/local_service_instance.py +3 -1
  40. ibm_watsonx_orchestrate/client/service_instance.py +33 -7
  41. ibm_watsonx_orchestrate/client/utils.py +48 -9
  42. ibm_watsonx_orchestrate/docker/compose-lite.yml +16 -4
  43. ibm_watsonx_orchestrate/docker/default.env +25 -15
  44. ibm_watsonx_orchestrate/flow_builder/flows/__init__.py +3 -1
  45. ibm_watsonx_orchestrate/flow_builder/flows/decorators.py +4 -2
  46. ibm_watsonx_orchestrate/flow_builder/flows/events.py +10 -9
  47. ibm_watsonx_orchestrate/flow_builder/flows/flow.py +91 -20
  48. ibm_watsonx_orchestrate/flow_builder/node.py +12 -1
  49. ibm_watsonx_orchestrate/flow_builder/types.py +169 -16
  50. ibm_watsonx_orchestrate/flow_builder/utils.py +121 -6
  51. ibm_watsonx_orchestrate/utils/exceptions.py +23 -0
  52. {ibm_watsonx_orchestrate-1.7.0a0.dist-info → ibm_watsonx_orchestrate-1.8.0b0.dist-info}/METADATA +5 -5
  53. {ibm_watsonx_orchestrate-1.7.0a0.dist-info → ibm_watsonx_orchestrate-1.8.0b0.dist-info}/RECORD +56 -52
  54. ibm_watsonx_orchestrate/flow_builder/resources/flow_status.openapi.yml +0 -66
  55. {ibm_watsonx_orchestrate-1.7.0a0.dist-info → ibm_watsonx_orchestrate-1.8.0b0.dist-info}/WHEEL +0 -0
  56. {ibm_watsonx_orchestrate-1.7.0a0.dist-info → ibm_watsonx_orchestrate-1.8.0b0.dist-info}/entry_points.txt +0 -0
  57. {ibm_watsonx_orchestrate-1.7.0a0.dist-info → ibm_watsonx_orchestrate-1.8.0b0.dist-info}/licenses/LICENSE +0 -0
@@ -53,16 +53,16 @@ EVENT_BROKER_TTL="-1"
53
53
  REGISTRY_URL=
54
54
 
55
55
 
56
- SERVER_TAG=26-06-2025
56
+ SERVER_TAG=02-07-2025
57
57
  SERVER_REGISTRY=
58
58
 
59
- WORKER_TAG=26-06-2025
59
+ WORKER_TAG=02-07-2025
60
60
  WORKER_REGISTRY=
61
61
 
62
- AI_GATEWAY_TAG=23-06-2025
62
+ AI_GATEWAY_TAG=01-07-2025
63
63
  AI_GATEWAY_REGISTRY=
64
64
 
65
- AGENT_GATEWAY_TAG=23-06-2025
65
+ AGENT_GATEWAY_TAG=07-07-2025
66
66
  AGENT_GATEWAY_REGISTRY=
67
67
 
68
68
  DB_REGISTRY=
@@ -73,41 +73,44 @@ AMDDBTAG=24-06-2025-v1
73
73
  ARM64DBTAG=24-06-2025-v1
74
74
 
75
75
  UI_REGISTRY=
76
- UITAG=26-06-2025
76
+ UITAG=27-06-2025
77
77
 
78
78
  CM_REGISTRY=
79
- CM_TAG=18-06-2025
79
+ CM_TAG=27-06-2025
80
80
 
81
- TRM_TAG=25-06-2025
81
+ TRM_TAG=08-07-2025
82
82
  TRM_REGISTRY=
83
83
 
84
- TR_TAG=25-06-2025
84
+ TR_TAG=08-07-2025
85
85
  TR_REGISTRY=
86
86
 
87
- BUILDER_TAG=26-06-2025-a
87
+ BUILDER_TAG=02-07-2025
88
88
  BUILDER_REGISTRY=
89
89
 
90
- FLOW_RUNTIME_TAG=23-06-2025
90
+ FLOW_RUNTIME_TAG=10-07-2025
91
91
  FLOW_RUMTIME_REGISTRY=
92
92
 
93
93
 
94
- AGENT_ANALYTICS_TAG=24-06-2025
94
+ AGENT_ANALYTICS_TAG=02-07-2025-v1
95
95
  AGENT_ANALYTICS_REGISTRY=
96
96
 
97
- JAEGER_PROXY_TAG=24-06-2025
97
+ JAEGER_PROXY_TAG=01-07-2025
98
98
  JAEGER_PROXY_REGISTRY=
99
99
 
100
100
  SOCKET_HANDLER_TAG=29-05-2025
101
101
  SOCKET_HANDLER_REGISTRY=
102
102
 
103
+ CPE_TAG=08-07-2025
104
+ CPE_REGISTRY=
105
+
103
106
  # IBM Document Processing
104
- WDU_TAG=2.5.0-rc.2
107
+ WDU_TAG=2.5.0
105
108
  WDU_REGISTRY=
106
109
 
107
110
  DOCPROC_DPS_TAG=20250610-183301-248-865fbc1
108
111
  DOCPROC_LLMSERVICE_TAG=20250604-192056-107-e1d4d66
109
112
  DOCPROC_CACHE_TAG=20250610-214940-68-f3258f4
110
- DOCPROC_DPI_TAG=20250624-155521-230-48b7f28b
113
+ DOCPROC_DPI_TAG=20250702-000808-237-7b1e424d
111
114
  DOCPROC_REGISTRY=
112
115
 
113
116
  # END -- IMAGE REGISTRIES AND TAGS
@@ -161,6 +164,13 @@ DB_CONN_LIFE=
161
164
  DB_MAX_IDLE_CONN=
162
165
  DB_MAX_CONN=
163
166
  SERVER_HOST=
167
+ WO_API_KEY=
168
+ WO_PASSWORD=
169
+ WO_USERNAME=
170
+ WO_INSTANCE=
171
+ AUTHORIZATION_URL=
172
+ WO_AUTH_TYPE=
173
+ PYTHONPATH=
164
174
 
165
175
  # Use your machine's local IP address for external async tool communication.
166
176
  CALLBACK_HOST_URL=
@@ -172,4 +182,4 @@ RUNTIME_MANAGER_API_KEY=example
172
182
 
173
183
 
174
184
  # IBM Document Processing
175
- SERVICE_URL=https://wxo-doc-processing-cache:8080
185
+ SERVICE_URL=https://wxo-doc-processing-cache:8080
@@ -1,5 +1,5 @@
1
1
  from .constants import START, END, RESERVED
2
- from ..types import FlowContext, TaskData, TaskEventType
2
+ from ..types import FlowContext, TaskData, TaskEventType, DocumentContent
3
3
  from ..node import UserNode, AgentNode, StartNode, EndNode, PromptNode, ToolNode
4
4
  from .flow import Flow, CompiledFlow, FlowRun, FlowEvent, FlowEventType, FlowFactory, MatchPolicy, WaitPolicy, ForeachPolicy, Branch, Foreach, Loop
5
5
  from .decorators import flow
@@ -14,7 +14,9 @@ __all__ = [
14
14
  "FlowContext",
15
15
  "TaskData",
16
16
  "TaskEventType",
17
+ "DocumentContent",
17
18
 
19
+ "DocProcNode",
18
20
  "UserNode",
19
21
  "AgentNode",
20
22
  "StartNode",
@@ -33,7 +33,8 @@ def flow(*args,
33
33
  description: str|None=None,
34
34
  input_schema: type[BaseModel] | None = None,
35
35
  output_schema: type[BaseModel] | None = None,
36
- initiators: Sequence[str] = ()):
36
+ initiators: Sequence[str] = (),
37
+ schedulable: bool = False):
37
38
  """Decorator to mark a function as a flow model builder."""
38
39
 
39
40
  def decorator(func: Callable):
@@ -58,7 +59,8 @@ def flow(*args,
58
59
  description = node_spec.description,
59
60
  input_schema = input_schema,
60
61
  output_schema = output_schema,
61
- initiators = initiators)
62
+ initiators = initiators,
63
+ schedulable = schedulable)
62
64
 
63
65
  # logger.info("Creating flow model: %s", a_model.spec.name)
64
66
 
@@ -5,9 +5,11 @@ from dotenv import load_dotenv
5
5
  import os
6
6
 
7
7
  from typing import (
8
- AsyncIterator, Union
8
+ AsyncIterator, TypeVar, Union
9
9
  )
10
10
 
11
+ from enum import Enum
12
+
11
13
  from ..types import (
12
14
  FlowEventType, TaskEventType, FlowEvent, FlowContext
13
15
  )
@@ -66,12 +68,11 @@ def deserialize_flow_event(byte_data: bytes) -> FlowEvent:
66
68
 
67
69
  return flow_event
68
70
 
71
+ def is_valid_enum_value(value: str, enum_type: type[Enum]) -> bool:
72
+ return value in (item.value for item in enum_type)
73
+
69
74
  def get_event_type(selected_event_type: str) -> Union[FlowEventType, TaskEventType]:
70
- """Selects the right event type from the corresponding enumerator"""
71
- eventKind = selected_event_type.upper()
72
- if eventKind in FlowEventType.__members__:
73
- return FlowEventType(selected_event_type)
74
- elif eventKind in TaskEventType.__members__:
75
- return TaskEventType(selected_event_type)
76
- else:
77
- raise ValueError(f"Invalid event type: {eventKind}")
75
+ for enum_type in [FlowEventType, TaskEventType]:
76
+ if is_valid_enum_value(selected_event_type, enum_type):
77
+ return enum_type(selected_event_type)
78
+ raise ValueError(f"Invalid event type: {selected_event_type}")
@@ -15,6 +15,7 @@ import logging
15
15
  import copy
16
16
  import uuid
17
17
  import pytz
18
+ import os
18
19
 
19
20
  from typing_extensions import Self
20
21
  from pydantic import BaseModel, Field, SerializeAsAny
@@ -25,11 +26,13 @@ from ibm_watsonx_orchestrate.client.tools.tempus_client import TempusClient
25
26
  from ibm_watsonx_orchestrate.client.utils import instantiate_client
26
27
  from ..types import (
27
28
  EndNodeSpec, Expression, ForeachPolicy, ForeachSpec, LoopSpec, BranchNodeSpec, MatchPolicy, PromptLLMParameters, PromptNodeSpec,
28
- StartNodeSpec, ToolSpec, JsonSchemaObject, ToolRequestBody, ToolResponseBody, UserFieldKind, UserFieldOption, UserFlowSpec, UserNodeSpec, WaitPolicy
29
+ StartNodeSpec, ToolSpec, JsonSchemaObject, ToolRequestBody, ToolResponseBody, UserFieldKind, UserFieldOption, UserFlowSpec, UserNodeSpec, WaitPolicy,
30
+ DocProcSpec, TextExtractionResponse, KVPInvoicesExtractionResponse, KVPUtilityBillsExtractionResponse,
31
+ DocumentContent
29
32
  )
30
33
  from .constants import CURRENT_USER, START, END, ANY_USER
31
34
  from ..node import (
32
- EndNode, Node, PromptNode, StartNode, UserNode, AgentNode, DataMap, ToolNode
35
+ EndNode, Node, PromptNode, StartNode, UserNode, AgentNode, DataMap, ToolNode, DocProcNode
33
36
  )
34
37
  from ..types import (
35
38
  AgentNodeSpec, extract_node_spec, FlowContext, FlowEventType, FlowEvent, FlowSpec,
@@ -114,7 +117,7 @@ class Flow(Node):
114
117
  # pydantic suppport nested comparison by default
115
118
 
116
119
  schema.title = title
117
-
120
+
118
121
  if schema == existing_schema:
119
122
  return existing_schema
120
123
  # we need to do a deep compare
@@ -354,6 +357,7 @@ class Flow(Node):
354
357
  name: str,
355
358
  agent: str,
356
359
  display_name: str|None=None,
360
+ title: str | None = None,
357
361
  message: str | None = "Follow the agent instructions.",
358
362
  description: str | None = None,
359
363
  input_schema: type[BaseModel]|None = None,
@@ -371,6 +375,7 @@ class Flow(Node):
371
375
  display_name=display_name,
372
376
  description=description,
373
377
  agent=agent,
378
+ title=title,
374
379
  message=message,
375
380
  guidelines=guidelines,
376
381
  input_schema=_get_tool_request_body(input_schema_obj),
@@ -428,6 +433,50 @@ class Flow(Node):
428
433
  # add the node to the list of node
429
434
  node = self._add_node(node)
430
435
  return cast(PromptNode, node)
436
+
437
+ def docproc(self,
438
+ name: str,
439
+ task: str,
440
+ display_name: str|None=None,
441
+ description: str | None = None,
442
+ input_map: DataMap = None) -> DocProcNode:
443
+
444
+ if name is None :
445
+ raise ValueError("name must be provided.")
446
+
447
+ if task is None:
448
+ raise ValueError("task must be provided.")
449
+
450
+ output_schema_dict = {
451
+ "text_extraction" : TextExtractionResponse,
452
+ "kvp_invoices_extraction" : KVPInvoicesExtractionResponse,
453
+ "kvp_utility_bills_extraction" : KVPUtilityBillsExtractionResponse
454
+ }
455
+ # create input spec
456
+ input_schema_obj = _get_json_schema_obj(parameter_name = "input", type_def = DocumentContent)
457
+ output_schema_obj = _get_json_schema_obj("output", output_schema_dict[task])
458
+ if "$defs" in output_schema_obj.model_extra:
459
+ output_schema_obj.model_extra.pop("$defs")
460
+ # Create the docproc spec
461
+ task_spec = DocProcSpec(
462
+ name=name,
463
+ display_name=display_name if display_name is not None else name,
464
+ description=description,
465
+ input_schema=_get_tool_request_body(input_schema_obj),
466
+ output_schema=_get_tool_response_body(output_schema_obj),
467
+ output_schema_object = output_schema_obj,
468
+ task=task
469
+ )
470
+
471
+ node = DocProcNode(spec=task_spec)
472
+ # setup input map
473
+ if input_map:
474
+ node.input_map = self._get_data_map(input_map)
475
+
476
+ # add the node to the list of node
477
+ node = self._add_node(node)
478
+ return cast(DocProcNode, node)
479
+
431
480
 
432
481
  def node_exists(self, node: Union[str, Node]):
433
482
 
@@ -921,7 +970,8 @@ class FlowFactory(BaseModel):
921
970
  description: str|None=None,
922
971
  initiators: Sequence[str]|None=None,
923
972
  input_schema: type[BaseModel]|None=None,
924
- output_schema: type[BaseModel]|None=None) -> Flow:
973
+ output_schema: type[BaseModel]|None=None,
974
+ schedulable: bool=False) -> Flow:
925
975
  if isinstance(name, Callable):
926
976
  flow_spec = getattr(name, "__flow_spec__", None)
927
977
  if not flow_spec:
@@ -942,7 +992,8 @@ class FlowFactory(BaseModel):
942
992
  initiators=initiators,
943
993
  input_schema=_get_tool_request_body(input_schema_obj),
944
994
  output_schema=_get_tool_response_body(output_schema_obj),
945
- output_schema_object = output_schema_obj
995
+ output_schema_object = output_schema_obj,
996
+ schedulable=schedulable,
946
997
  )
947
998
 
948
999
  return Flow(spec = flow_spec)
@@ -1228,10 +1279,12 @@ class UserFlow(Flow):
1228
1279
  kind: UserFieldKind = UserFieldKind.Text,
1229
1280
  display_name: str | None = None,
1230
1281
  description: str | None = None,
1231
- owners: list[str] = [],
1232
1282
  default: Any | None = None,
1233
- text: str = None,
1283
+ text: str = None, # The text used to ask question to the user, e.g. 'what is your name?'
1234
1284
  option: UserFieldOption | None = None,
1285
+ is_list: bool = False,
1286
+ min: Any | None = None,
1287
+ max: Any | None = None,
1235
1288
  input_map: DataMap = None,
1236
1289
  custom: dict[str, Any] = {}) -> UserNode:
1237
1290
  '''create a node in the flow'''
@@ -1246,20 +1299,42 @@ class UserFlow(Flow):
1246
1299
  schema_obj.properties = {}
1247
1300
  schema_obj.properties[name] = UserFieldKind.convert_kind_to_schema_property(kind, name, description, default, option, custom)
1248
1301
 
1249
- return self.user(name,
1250
- display_name=display_name,
1251
- description=description,
1252
- owners=owners,
1253
- text=text,
1254
- output_schema=schema_obj,
1255
- input_map=input_map)
1302
+ task_spec = UserNodeSpec(
1303
+ name=name,
1304
+ display_name=display_name,
1305
+ description=description,
1306
+ owners=[CURRENT_USER],
1307
+ input_schema=_get_tool_request_body(schema_obj),
1308
+ output_schema=_get_tool_response_body(schema_obj),
1309
+ text=text,
1310
+ output_schema_object = schema_obj
1311
+ )
1312
+
1313
+ node = UserNode(spec = task_spec)
1314
+ node.field(name = name,
1315
+ kind = kind,
1316
+ display_name = display_name,
1317
+ description = description,
1318
+ default = default,
1319
+ text = text,
1320
+ option = option,
1321
+ is_list = is_list,
1322
+ min = min,
1323
+ max = max,
1324
+ custom = custom)
1325
+
1326
+ # setup input map
1327
+ if input_map:
1328
+ node.input_map = self._get_data_map(input_map)
1329
+
1330
+ node = self._add_node(node)
1331
+ return cast(UserNode, node)
1256
1332
 
1257
1333
  def user(
1258
1334
  self,
1259
1335
  name: str | None = None,
1260
1336
  display_name: str | None = None,
1261
1337
  description: str | None = None,
1262
- owners: list[str] = [],
1263
1338
  text: str | None = None,
1264
1339
  output_schema: type[BaseModel] | JsonSchemaObject| None = None,
1265
1340
  input_map: DataMap = None,
@@ -1273,16 +1348,12 @@ class UserFlow(Flow):
1273
1348
  # input and output is always the same in an user node
1274
1349
  output_schema_obj = output_schema_obj
1275
1350
 
1276
- # identify owner
1277
- if not owners:
1278
- owners = [ANY_USER]
1279
-
1280
1351
  # Create the tool spec
1281
1352
  task_spec = UserNodeSpec(
1282
1353
  name=name,
1283
1354
  display_name=display_name,
1284
1355
  description=description,
1285
- owners=owners,
1356
+ owners=[CURRENT_USER],
1286
1357
  input_schema=_get_tool_request_body(output_schema_obj),
1287
1358
  output_schema=_get_tool_response_body(output_schema_obj),
1288
1359
  text=text,
@@ -5,7 +5,7 @@ import uuid
5
5
  import yaml
6
6
  from pydantic import BaseModel, Field, SerializeAsAny
7
7
 
8
- from .types import EndNodeSpec, NodeSpec, AgentNodeSpec, PromptNodeSpec, StartNodeSpec, ToolNodeSpec, UserFieldKind, UserFieldOption, UserNodeSpec
8
+ from .types import EndNodeSpec, NodeSpec, AgentNodeSpec, PromptNodeSpec, StartNodeSpec, ToolNodeSpec, UserFieldKind, UserFieldOption, UserNodeSpec, DocProcSpec
9
9
  from .data_map import DataMap
10
10
 
11
11
  class Node(BaseModel):
@@ -78,6 +78,8 @@ class UserNode(Node):
78
78
  description: str | None = None,
79
79
  default: Any | None = None,
80
80
  option: UserFieldOption | None = None,
81
+ min: Any | None = None,
82
+ max: Any | None = None,
81
83
  is_list: bool = False,
82
84
  custom: dict[str, Any] | None = None,
83
85
  widget: str | None = None):
@@ -88,6 +90,8 @@ class UserNode(Node):
88
90
  description=description,
89
91
  default=default,
90
92
  option=option,
93
+ min=min,
94
+ max=max,
91
95
  is_list=is_list,
92
96
  custom=custom,
93
97
  widget=widget)
@@ -105,6 +109,13 @@ class PromptNode(Node):
105
109
 
106
110
  def get_spec(self) -> PromptNodeSpec:
107
111
  return cast(PromptNodeSpec, self.spec)
112
+
113
+ class DocProcNode(Node):
114
+ def __repr__(self):
115
+ return f"DocProcNode(name='{self.spec.name}', description='{self.spec.description}')"
116
+
117
+ def get_spec(self) -> DocProcSpec:
118
+ return cast(DocProcSpec, self.spec)
108
119
 
109
120
  class NodeInstance(BaseModel):
110
121
  node: Node