ibm-watsonx-orchestrate 1.8.0b0__py3-none-any.whl → 1.8.0b1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ibm_watsonx_orchestrate/__init__.py +1 -1
- ibm_watsonx_orchestrate/agent_builder/agents/types.py +12 -0
- ibm_watsonx_orchestrate/agent_builder/connections/types.py +14 -2
- ibm_watsonx_orchestrate/cli/commands/channels/types.py +15 -2
- ibm_watsonx_orchestrate/cli/commands/channels/webchat/channels_webchat_controller.py +5 -4
- ibm_watsonx_orchestrate/cli/commands/connections/connections_command.py +14 -6
- ibm_watsonx_orchestrate/cli/commands/connections/connections_controller.py +6 -8
- ibm_watsonx_orchestrate/cli/commands/copilot/copilot_controller.py +111 -36
- ibm_watsonx_orchestrate/cli/commands/copilot/copilot_server_controller.py +23 -7
- ibm_watsonx_orchestrate/cli/commands/environment/types.py +1 -1
- ibm_watsonx_orchestrate/cli/commands/evaluations/evaluations_command.py +16 -6
- ibm_watsonx_orchestrate/cli/commands/evaluations/evaluations_controller.py +20 -2
- ibm_watsonx_orchestrate/cli/commands/knowledge_bases/knowledge_bases_controller.py +10 -8
- ibm_watsonx_orchestrate/cli/commands/server/server_command.py +1 -9
- ibm_watsonx_orchestrate/client/copilot/cpe/copilot_cpe_client.py +2 -1
- ibm_watsonx_orchestrate/client/utils.py +5 -4
- ibm_watsonx_orchestrate/docker/compose-lite.yml +9 -2
- ibm_watsonx_orchestrate/docker/default.env +6 -5
- ibm_watsonx_orchestrate/flow_builder/flows/__init__.py +8 -5
- ibm_watsonx_orchestrate/flow_builder/flows/flow.py +47 -7
- ibm_watsonx_orchestrate/flow_builder/node.py +7 -1
- ibm_watsonx_orchestrate/flow_builder/types.py +168 -65
- {ibm_watsonx_orchestrate-1.8.0b0.dist-info → ibm_watsonx_orchestrate-1.8.0b1.dist-info}/METADATA +2 -2
- {ibm_watsonx_orchestrate-1.8.0b0.dist-info → ibm_watsonx_orchestrate-1.8.0b1.dist-info}/RECORD +27 -27
- {ibm_watsonx_orchestrate-1.8.0b0.dist-info → ibm_watsonx_orchestrate-1.8.0b1.dist-info}/WHEEL +0 -0
- {ibm_watsonx_orchestrate-1.8.0b0.dist-info → ibm_watsonx_orchestrate-1.8.0b1.dist-info}/entry_points.txt +0 -0
- {ibm_watsonx_orchestrate-1.8.0b0.dist-info → ibm_watsonx_orchestrate-1.8.0b1.dist-info}/licenses/LICENSE +0 -0
@@ -3,12 +3,12 @@ import os.path
|
|
3
3
|
from typing import List, Dict, Optional, Tuple
|
4
4
|
import csv
|
5
5
|
from pathlib import Path
|
6
|
-
import
|
6
|
+
import sys
|
7
7
|
from wxo_agentic_evaluation import main as evaluate
|
8
8
|
from wxo_agentic_evaluation.tool_planner import build_snapshot
|
9
9
|
from wxo_agentic_evaluation.analyze_run import analyze
|
10
10
|
from wxo_agentic_evaluation.batch_annotate import generate_test_cases_from_stories
|
11
|
-
from wxo_agentic_evaluation.arg_configs import TestConfig, AuthConfig, LLMUserConfig, ChatRecordingConfig, AnalyzeConfig
|
11
|
+
from wxo_agentic_evaluation.arg_configs import TestConfig, AuthConfig, LLMUserConfig, ChatRecordingConfig, AnalyzeConfig, ProviderConfig
|
12
12
|
from wxo_agentic_evaluation.record_chat import record_chats
|
13
13
|
from wxo_agentic_evaluation.external_agent.external_validate import ExternalAgentValidation
|
14
14
|
from wxo_agentic_evaluation.external_agent.performance_test import ExternalAgentPerformanceTest
|
@@ -41,12 +41,26 @@ class EvaluationsController:
|
|
41
41
|
def evaluate(self, config_file: Optional[str] = None, test_paths: Optional[str] = None, output_dir: Optional[str] = None) -> None:
|
42
42
|
url, tenant_name, token = self._get_env_config()
|
43
43
|
|
44
|
+
if "WATSONX_SPACE_ID" in os.environ and "WATSONX_APIKEY" in os.environ:
|
45
|
+
provider = "watsonx"
|
46
|
+
elif "WO_INSTANCE" in os.environ and "WO_API_KEY" in os.environ:
|
47
|
+
provider = "model_proxy"
|
48
|
+
else:
|
49
|
+
logger.error(
|
50
|
+
"No provider found. Please either provide a config_file or set either WATSONX_SPACE_ID and WATSONX_APIKEY or WO_INSTANCE and WO_API_KEY in your system environment variables."
|
51
|
+
)
|
52
|
+
sys.exit(1)
|
53
|
+
|
44
54
|
config_data = {
|
45
55
|
"wxo_lite_version": __version__,
|
46
56
|
"auth_config": AuthConfig(
|
47
57
|
url=url,
|
48
58
|
tenant_name=tenant_name,
|
49
59
|
token=token
|
60
|
+
),
|
61
|
+
"provider_config": ProviderConfig(
|
62
|
+
provider=provider,
|
63
|
+
model_id="meta-llama/llama-3-405b-instruct",
|
50
64
|
)
|
51
65
|
}
|
52
66
|
|
@@ -62,6 +76,10 @@ class EvaluationsController:
|
|
62
76
|
if "llm_user_config" in file_config:
|
63
77
|
llm_config_data = file_config.pop("llm_user_config")
|
64
78
|
config_data["llm_user_config"] = LLMUserConfig(**llm_config_data)
|
79
|
+
|
80
|
+
if "provider_config" in file_config:
|
81
|
+
provider_config_data = file_config.pop("provider_config")
|
82
|
+
config_data["provider_config"] = ProviderConfig(**provider_config_data)
|
65
83
|
|
66
84
|
config_data.update(file_config)
|
67
85
|
|
@@ -71,6 +71,7 @@ class KnowledgeBaseController:
|
|
71
71
|
client = self.get_client()
|
72
72
|
|
73
73
|
knowledge_bases = parse_file(file=file)
|
74
|
+
|
74
75
|
existing_knowledge_bases = client.get_by_names([kb.name for kb in knowledge_bases])
|
75
76
|
|
76
77
|
for kb in knowledge_bases:
|
@@ -137,23 +138,24 @@ class KnowledgeBaseController:
|
|
137
138
|
|
138
139
|
def update_knowledge_base(
|
139
140
|
self, knowledge_base_id: str, kb: KnowledgeBase, file_dir: str
|
140
|
-
) -> None:
|
141
|
-
filtered_files = []
|
142
|
-
|
141
|
+
) -> None:
|
143
142
|
if kb.documents:
|
144
143
|
status = self.get_client().status(knowledge_base_id)
|
145
144
|
existing_docs = [doc.get("metadata", {}).get("original_file_name", "") for doc in status.get("documents", [])]
|
146
145
|
|
146
|
+
removed_docs = existing_docs[:]
|
147
147
|
for filepath in kb.documents:
|
148
148
|
filename = get_file_name(filepath)
|
149
149
|
|
150
150
|
if filename in existing_docs:
|
151
|
-
logger.warning(f'Document \"{filename}\" already exists in knowledge base
|
152
|
-
|
153
|
-
|
151
|
+
logger.warning(f'Document \"{filename}\" already exists in knowledge base. Updating...')
|
152
|
+
removed_docs.remove(filename)
|
153
|
+
|
154
|
+
for filename in removed_docs:
|
155
|
+
logger.warning(f'Document \"{filename}\" removed from knowledge base.')
|
156
|
+
|
154
157
|
|
155
|
-
|
156
|
-
files = [('files', (get_file_name(file_path), open(get_relative_file_path(file_path, file_dir), 'rb'))) for file_path in filtered_files]
|
158
|
+
files = [('files', (get_file_name(file_path), open(get_relative_file_path(file_path, file_dir), 'rb'))) for file_path in kb.documents]
|
157
159
|
|
158
160
|
kb.prioritize_built_in_index = True
|
159
161
|
payload = kb.model_dump(exclude_none=True);
|
@@ -46,15 +46,7 @@ _ALWAYS_UNSET: set[str] = {
|
|
46
46
|
|
47
47
|
def define_saas_wdu_runtime(value: str = "none") -> None:
|
48
48
|
cfg = Config()
|
49
|
-
|
50
|
-
current_config_file_values = cfg.get(USER_ENV_CACHE_HEADER)
|
51
|
-
current_config_file_values["SAAS_WDU_RUNTIME"] = value
|
52
|
-
|
53
|
-
cfg.save(
|
54
|
-
{
|
55
|
-
USER_ENV_CACHE_HEADER: current_config_file_values
|
56
|
-
}
|
57
|
-
)
|
49
|
+
cfg.write(USER_ENV_CACHE_HEADER,"SAAS_WDU_RUNTIME",value)
|
58
50
|
|
59
51
|
def ensure_docker_installed() -> None:
|
60
52
|
try:
|
@@ -21,10 +21,11 @@ class CPEClient(BaseAPIClient):
|
|
21
21
|
}
|
22
22
|
|
23
23
|
|
24
|
-
def submit_pre_cpe_chat(self, user_message: str | None =None, tools: Dict[str, Any] = None) -> dict:
|
24
|
+
def submit_pre_cpe_chat(self, user_message: str | None =None, tools: Dict[str, Any] = None, agents: Dict[str, Any] = None) -> dict:
|
25
25
|
payload = {
|
26
26
|
"message": user_message,
|
27
27
|
"tools": tools,
|
28
|
+
"agents": agents,
|
28
29
|
"chat_id": self.chat_id,
|
29
30
|
"chat_model_name": self.chat_model_name
|
30
31
|
}
|
@@ -16,6 +16,7 @@ from ibm_watsonx_orchestrate.cli.config import (
|
|
16
16
|
from threading import Lock
|
17
17
|
from ibm_watsonx_orchestrate.client.base_api_client import BaseAPIClient
|
18
18
|
from ibm_watsonx_orchestrate.utils.utils import yaml_safe_load
|
19
|
+
from ibm_watsonx_orchestrate.cli.commands.channels.types import RuntimeEnvironmentType
|
19
20
|
import logging
|
20
21
|
from typing import TypeVar
|
21
22
|
import os
|
@@ -92,13 +93,13 @@ def is_ga_platform(url: str | None = None) -> bool:
|
|
92
93
|
|
93
94
|
def get_environment() -> str:
|
94
95
|
if is_local_dev():
|
95
|
-
return
|
96
|
+
return RuntimeEnvironmentType.LOCAL
|
96
97
|
if is_cpd_env():
|
97
|
-
return
|
98
|
+
return RuntimeEnvironmentType.CPD
|
98
99
|
if is_ibm_cloud_platform():
|
99
|
-
return
|
100
|
+
return RuntimeEnvironmentType.IBM_CLOUD
|
100
101
|
if is_ga_platform():
|
101
|
-
return
|
102
|
+
return RuntimeEnvironmentType.AWS
|
102
103
|
return None
|
103
104
|
|
104
105
|
def check_token_validity(token: str) -> bool:
|
@@ -46,7 +46,7 @@ services:
|
|
46
46
|
WXO_SERVER_URL: http://wxo-server:4321
|
47
47
|
MAX_POOL: 60
|
48
48
|
DEPLOYMENT_MODE: laptop
|
49
|
-
SUFFIXLIST:
|
49
|
+
SUFFIXLIST: ${CM_SUFFIXLIST:-[]}
|
50
50
|
ports:
|
51
51
|
- 3001:3001
|
52
52
|
|
@@ -804,6 +804,13 @@ services:
|
|
804
804
|
environment:
|
805
805
|
WATSONX_APIKEY: ${WATSONX_APIKEY}
|
806
806
|
WATSONX_SPACE_ID: ${WATSONX_SPACE_ID}
|
807
|
+
WO_API_KEY: ${WO_API_KEY}
|
808
|
+
WO_USERNAME: ${WO_USERNAME}
|
809
|
+
WO_PASSWORD: ${WO_PASSWORD}
|
810
|
+
WO_INSTANCE: ${WO_INSTANCE}
|
811
|
+
USE_SAAS_ML_TOOLS_RUNTIME: ${USE_SAAS_ML_TOOLS_RUNTIME}
|
812
|
+
WO_AUTH_TYPE: ${WO_AUTH_TYPE}
|
813
|
+
AUTHORIZATION_URL: ${AUTHORIZATION_URL}
|
807
814
|
ports:
|
808
815
|
- 8081:8080
|
809
816
|
|
@@ -909,7 +916,7 @@ services:
|
|
909
916
|
ENRICHMENT_BATCH_SIZE: "1000"
|
910
917
|
CIPHER_AES_REALM_KEY: "dGVzdHRlc3R0ZXN0dGVzdA=="
|
911
918
|
SIDECAR_METERED_ENABLED: "false"
|
912
|
-
DPI_DEBUG:
|
919
|
+
DPI_DEBUG: "false"
|
913
920
|
DPI_WO_WDU_SERVER_ENDPOINT: https://wxo-doc-processing-service:8080
|
914
921
|
# DPI_RAG_SERVER_ENDPOINT: https://wxo-doc-processing-llm-service:8083
|
915
922
|
DISABLE_TLS: true
|
@@ -53,10 +53,10 @@ EVENT_BROKER_TTL="-1"
|
|
53
53
|
REGISTRY_URL=
|
54
54
|
|
55
55
|
|
56
|
-
SERVER_TAG=
|
56
|
+
SERVER_TAG=10-07-2025-beb40a3a
|
57
57
|
SERVER_REGISTRY=
|
58
58
|
|
59
|
-
WORKER_TAG=
|
59
|
+
WORKER_TAG=10-07-2025-beb40a3a
|
60
60
|
WORKER_REGISTRY=
|
61
61
|
|
62
62
|
AI_GATEWAY_TAG=01-07-2025
|
@@ -84,10 +84,10 @@ TRM_REGISTRY=
|
|
84
84
|
TR_TAG=08-07-2025
|
85
85
|
TR_REGISTRY=
|
86
86
|
|
87
|
-
BUILDER_TAG=
|
87
|
+
BUILDER_TAG=15-07-2025
|
88
88
|
BUILDER_REGISTRY=
|
89
89
|
|
90
|
-
FLOW_RUNTIME_TAG=
|
90
|
+
FLOW_RUNTIME_TAG=15-07-2025
|
91
91
|
FLOW_RUMTIME_REGISTRY=
|
92
92
|
|
93
93
|
|
@@ -100,7 +100,7 @@ JAEGER_PROXY_REGISTRY=
|
|
100
100
|
SOCKET_HANDLER_TAG=29-05-2025
|
101
101
|
SOCKET_HANDLER_REGISTRY=
|
102
102
|
|
103
|
-
CPE_TAG=
|
103
|
+
CPE_TAG=17-07-2025
|
104
104
|
CPE_REGISTRY=
|
105
105
|
|
106
106
|
# IBM Document Processing
|
@@ -171,6 +171,7 @@ WO_INSTANCE=
|
|
171
171
|
AUTHORIZATION_URL=
|
172
172
|
WO_AUTH_TYPE=
|
173
173
|
PYTHONPATH=
|
174
|
+
CM_SUFFIXLIST=
|
174
175
|
|
175
176
|
# Use your machine's local IP address for external async tool communication.
|
176
177
|
CALLBACK_HOST_URL=
|
@@ -1,6 +1,8 @@
|
|
1
1
|
from .constants import START, END, RESERVED
|
2
|
-
|
3
|
-
from ..
|
2
|
+
|
3
|
+
from ..types import FlowContext, TaskData, TaskEventType, File, DecisionsCondition, DecisionsRule
|
4
|
+
from ..node import UserNode, AgentNode, StartNode, EndNode, PromptNode, ToolNode, DecisionsNode
|
5
|
+
|
4
6
|
from .flow import Flow, CompiledFlow, FlowRun, FlowEvent, FlowEventType, FlowFactory, MatchPolicy, WaitPolicy, ForeachPolicy, Branch, Foreach, Loop
|
5
7
|
from .decorators import flow
|
6
8
|
from ..data_map import Assignment, DataMap
|
@@ -14,7 +16,7 @@ __all__ = [
|
|
14
16
|
"FlowContext",
|
15
17
|
"TaskData",
|
16
18
|
"TaskEventType",
|
17
|
-
"
|
19
|
+
"File",
|
18
20
|
|
19
21
|
"DocProcNode",
|
20
22
|
"UserNode",
|
@@ -23,6 +25,7 @@ __all__ = [
|
|
23
25
|
"EndNode",
|
24
26
|
"PromptNode",
|
25
27
|
"ToolNode",
|
28
|
+
"DecisionsNode",
|
26
29
|
"Assignment",
|
27
30
|
"DataMap",
|
28
31
|
|
@@ -38,8 +41,8 @@ __all__ = [
|
|
38
41
|
"Branch",
|
39
42
|
"Foreach",
|
40
43
|
"Loop",
|
44
|
+
"DecisionsCondition",
|
45
|
+
"DecisionsRule",
|
41
46
|
|
42
|
-
"user",
|
43
|
-
"flow_spec",
|
44
47
|
"flow"
|
45
48
|
]
|
@@ -27,12 +27,11 @@ from ibm_watsonx_orchestrate.client.utils import instantiate_client
|
|
27
27
|
from ..types import (
|
28
28
|
EndNodeSpec, Expression, ForeachPolicy, ForeachSpec, LoopSpec, BranchNodeSpec, MatchPolicy, PromptLLMParameters, PromptNodeSpec,
|
29
29
|
StartNodeSpec, ToolSpec, JsonSchemaObject, ToolRequestBody, ToolResponseBody, UserFieldKind, UserFieldOption, UserFlowSpec, UserNodeSpec, WaitPolicy,
|
30
|
-
DocProcSpec, TextExtractionResponse,
|
31
|
-
DocumentContent
|
30
|
+
DocProcSpec, TextExtractionResponse, File, DecisionsNodeSpec, DecisionsRule
|
32
31
|
)
|
33
32
|
from .constants import CURRENT_USER, START, END, ANY_USER
|
34
33
|
from ..node import (
|
35
|
-
EndNode, Node, PromptNode, StartNode, UserNode, AgentNode, DataMap, ToolNode, DocProcNode
|
34
|
+
EndNode, Node, PromptNode, StartNode, UserNode, AgentNode, DataMap, ToolNode, DocProcNode, DecisionsNode
|
36
35
|
)
|
37
36
|
from ..types import (
|
38
37
|
AgentNodeSpec, extract_node_spec, FlowContext, FlowEventType, FlowEvent, FlowSpec,
|
@@ -434,6 +433,49 @@ class Flow(Node):
|
|
434
433
|
node = self._add_node(node)
|
435
434
|
return cast(PromptNode, node)
|
436
435
|
|
436
|
+
def decisions(self,
|
437
|
+
name: str,
|
438
|
+
display_name: str|None=None,
|
439
|
+
rules: list[DecisionsRule] | None = None,
|
440
|
+
default_actions: dict[str, Any] = None,
|
441
|
+
locale: str | None = None,
|
442
|
+
description: str | None = None,
|
443
|
+
input_schema: type[BaseModel]|None = None,
|
444
|
+
output_schema: type[BaseModel]|None=None,
|
445
|
+
input_map: DataMap = None) -> PromptNode:
|
446
|
+
|
447
|
+
if name is None:
|
448
|
+
raise ValueError("name must be provided.")
|
449
|
+
|
450
|
+
if rules is None:
|
451
|
+
raise ValueError("rules must be specified.")
|
452
|
+
|
453
|
+
# create input spec
|
454
|
+
input_schema_obj = _get_json_schema_obj(parameter_name = "input", type_def = input_schema)
|
455
|
+
output_schema_obj = _get_json_schema_obj("output", output_schema)
|
456
|
+
|
457
|
+
# Create the tool spec
|
458
|
+
task_spec = DecisionsNodeSpec(
|
459
|
+
name=name,
|
460
|
+
display_name=display_name if display_name is not None else name,
|
461
|
+
description=description,
|
462
|
+
rules=rules,
|
463
|
+
default_actions=default_actions,
|
464
|
+
locale=locale,
|
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
|
+
)
|
469
|
+
|
470
|
+
node = DecisionsNode(spec=task_spec)
|
471
|
+
# setup input map
|
472
|
+
if input_map:
|
473
|
+
node.input_map = self._get_data_map(input_map)
|
474
|
+
|
475
|
+
# add the node to the list of node
|
476
|
+
node = self._add_node(node)
|
477
|
+
return cast(DecisionsNode, node)
|
478
|
+
|
437
479
|
def docproc(self,
|
438
480
|
name: str,
|
439
481
|
task: str,
|
@@ -448,12 +490,10 @@ class Flow(Node):
|
|
448
490
|
raise ValueError("task must be provided.")
|
449
491
|
|
450
492
|
output_schema_dict = {
|
451
|
-
"text_extraction" : TextExtractionResponse
|
452
|
-
"kvp_invoices_extraction" : KVPInvoicesExtractionResponse,
|
453
|
-
"kvp_utility_bills_extraction" : KVPUtilityBillsExtractionResponse
|
493
|
+
"text_extraction" : TextExtractionResponse
|
454
494
|
}
|
455
495
|
# create input spec
|
456
|
-
input_schema_obj = _get_json_schema_obj(parameter_name = "input", type_def =
|
496
|
+
input_schema_obj = _get_json_schema_obj(parameter_name = "input", type_def = File)
|
457
497
|
output_schema_obj = _get_json_schema_obj("output", output_schema_dict[task])
|
458
498
|
if "$defs" in output_schema_obj.model_extra:
|
459
499
|
output_schema_obj.model_extra.pop("$defs")
|
@@ -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, DocProcSpec
|
8
|
+
from .types import EndNodeSpec, NodeSpec, AgentNodeSpec, PromptNodeSpec, StartNodeSpec, ToolNodeSpec, UserFieldKind, UserFieldOption, UserNodeSpec, DocProcSpec, DecisionsNodeSpec
|
9
9
|
from .data_map import DataMap
|
10
10
|
|
11
11
|
class Node(BaseModel):
|
@@ -116,7 +116,13 @@ class DocProcNode(Node):
|
|
116
116
|
|
117
117
|
def get_spec(self) -> DocProcSpec:
|
118
118
|
return cast(DocProcSpec, self.spec)
|
119
|
+
class DecisionsNode(Node):
|
120
|
+
def __repr__(self):
|
121
|
+
return f"DecisionsNode(name='{self.spec.name}', description='{self.spec.description}')"
|
119
122
|
|
123
|
+
def get_spec(self) -> DecisionsNodeSpec:
|
124
|
+
return cast(DecisionsNodeSpec, self.spec)
|
125
|
+
|
120
126
|
class NodeInstance(BaseModel):
|
121
127
|
node: Node
|
122
128
|
id: str # unique id of this task instance
|
@@ -1,5 +1,7 @@
|
|
1
1
|
from dataclasses import dataclass
|
2
2
|
from enum import Enum, StrEnum, auto
|
3
|
+
from datetime import date
|
4
|
+
import numbers
|
3
5
|
import inspect
|
4
6
|
import logging
|
5
7
|
from typing import (
|
@@ -167,8 +169,6 @@ class DocProcTask(StrEnum):
|
|
167
169
|
Possible names for the Document processing task parameter
|
168
170
|
'''
|
169
171
|
text_extraction = auto()
|
170
|
-
kvp_invoices_extraction = auto()
|
171
|
-
kvp_utility_bills_extraction = auto()
|
172
172
|
|
173
173
|
class DocProcSpec(NodeSpec):
|
174
174
|
task: DocProcTask = Field(description='The document processing operation name', default=DocProcTask.text_extraction)
|
@@ -515,6 +515,7 @@ class PromptNodeSpec(NodeSpec):
|
|
515
515
|
model_spec["llm_parameters"] = self.llm_parameters.to_json()
|
516
516
|
|
517
517
|
return model_spec
|
518
|
+
|
518
519
|
|
519
520
|
class Expression(BaseModel):
|
520
521
|
'''An expression could return a boolean or a value'''
|
@@ -743,7 +744,7 @@ class LanguageCode(StrEnum):
|
|
743
744
|
fr = auto()
|
744
745
|
en_hw = auto()
|
745
746
|
|
746
|
-
class
|
747
|
+
class File(BaseModel):
|
747
748
|
'''
|
748
749
|
This class represents the input of a Document processing task.
|
749
750
|
|
@@ -752,7 +753,7 @@ class DocumentContent(BaseModel):
|
|
752
753
|
language (LanguageCode): Optional language code used when processing the input document
|
753
754
|
'''
|
754
755
|
# This is declared as bytes but the runtime will understand if a URL is send in as input.
|
755
|
-
# We need to use bytes here for Chat-with-doc to recognize the input as a
|
756
|
+
# We need to use bytes here for Chat-with-doc to recognize the input as a File.
|
756
757
|
document_ref: bytes | str = Field(
|
757
758
|
description="Either an ID or a URL identifying the document to be used.",
|
758
759
|
title='Document reference',
|
@@ -779,73 +780,175 @@ class TextExtractionResponse(BaseModel):
|
|
779
780
|
'''
|
780
781
|
output: TextExtraction = Field(description='The text extraction response')
|
781
782
|
|
782
|
-
class Invoice(BaseModel):
|
783
|
-
'''
|
784
|
-
This class represents the fields extracted by the "kvp_invoices_extraction" document processing (docproc) operation.
|
785
|
-
'''
|
786
|
-
bank_account_number: Optional[str] = Field(title='Bank account number', default=None)
|
787
|
-
bank_name: Optional[str] = Field(title='Bank name', default=None)
|
788
|
-
bill_to_address: Optional[str] = Field(title='Bill-to address', default=None)
|
789
|
-
bill_to_name: Optional[str] = Field(title='Bill-to name', default=None)
|
790
|
-
invoice_date: Optional[str] = Field(title='Invoice date', format='date', default=None)
|
791
|
-
invoice_number: Optional[str] = Field(title='Invoice number', default=None)
|
792
|
-
invoice_total: Optional[float] = Field(title='Invoice total', default=None)
|
793
|
-
payment_due_date: Optional[str] = Field(title='Payment due date', format='date', default=None)
|
794
|
-
payment_terms: Optional[str] = Field(title='Payment terms', default=None)
|
795
|
-
purchase_order_number: Optional[str] = Field(title='Purchase order number', default=None)
|
796
|
-
ship_to_address: Optional[str] = Field(title='Ship-to address', default=None)
|
797
|
-
ship_to_name: Optional[str] = Field(title='Ship-to name', default=None)
|
798
|
-
shipping_amount: Optional[float] = Field(title='Shipping amount', default=None)
|
799
|
-
subtotal: Optional[float] = Field(title='Subtotal', default=None)
|
800
|
-
tax_amount: Optional[float] = Field(title='Tax amount', default=None)
|
801
|
-
tax_rate: Optional[float] = Field(title='Tax rate', default=None)
|
802
|
-
tax_type: Optional[str] = Field(title='Tax type', default=None)
|
803
|
-
vendor_address: Optional[str] = Field(title='Vendor address', default=None)
|
804
|
-
vendor_name: Optional[str] = Field(title='Vendor name', default=None)
|
805
|
-
|
806
|
-
|
807
|
-
class KVPInvoicesExtractionResponse(BaseModel):
|
808
|
-
'''
|
809
|
-
The response of a "kvp_invoices_extraction" document processing (docproc) operation.
|
810
|
-
Attributes:
|
811
|
-
invoice: an object with the fields extracted from the input invoice document
|
812
|
-
'''
|
813
|
-
output: Invoice = Field(
|
814
|
-
title='Invoice',
|
815
|
-
description='The fields extracted from an invoice document'
|
816
|
-
)
|
817
783
|
|
784
|
+
class DecisionsCondition(BaseModel):
|
785
|
+
_condition: str | None = None
|
786
|
+
|
787
|
+
def greater_than(self, value: Union[numbers.Number, date, str]) -> Self:
|
788
|
+
self._check_type_is_number_or_date_or_str(value)
|
789
|
+
self._condition = f"> {self._format_value(value)}"
|
790
|
+
return self
|
791
|
+
|
792
|
+
def greater_than_or_equal(self, value: Union[numbers.Number, date, str]) -> Self:
|
793
|
+
self._check_type_is_number_or_date_or_str(value)
|
794
|
+
self._condition = f">= {self._format_value(value)}"
|
795
|
+
return self
|
796
|
+
|
797
|
+
def less_than(self, value: Union[numbers.Number, date, str]) -> Self:
|
798
|
+
self._check_type_is_number_or_date_or_str(value)
|
799
|
+
self._condition = f"< {self._format_value(value)}"
|
800
|
+
return self
|
801
|
+
|
802
|
+
def less_than_or_equal(self, value: Union[numbers.Number, date, str]) -> Self:
|
803
|
+
self._check_type_is_number_or_date_or_str(value)
|
804
|
+
self._condition = f"<= {self._format_value(value)}"
|
805
|
+
return self
|
818
806
|
|
819
|
-
|
807
|
+
def equal(self, value: Union[numbers.Number, date, str]) -> Self:
|
808
|
+
self._check_type_is_number_or_date_or_str(value)
|
809
|
+
self._condition = f"== {self._format_value(value)}"
|
810
|
+
return self
|
811
|
+
|
812
|
+
def not_equal(self, value: Union[numbers.Number, date, str]) -> Self:
|
813
|
+
self._check_type_is_number_or_date_or_str(value)
|
814
|
+
self._condition = f"== {self._format_value(value)}"
|
815
|
+
return self
|
816
|
+
|
817
|
+
def contains(self, value: str) -> Self:
|
818
|
+
self._check_type_is_str(value)
|
819
|
+
self._condition = f"contains {self._format_value(value)}"
|
820
|
+
return self
|
821
|
+
|
822
|
+
def not_contains(self, value: str) -> Self:
|
823
|
+
self._check_type_is_str(value)
|
824
|
+
self._condition = f"doesNotContain {self._format_value(value)}"
|
825
|
+
return self
|
826
|
+
|
827
|
+
def is_in(self, value: str) -> Self:
|
828
|
+
self._check_type_is_str(value)
|
829
|
+
self._condition = f"in {self._format_value(value)}"
|
830
|
+
return self
|
831
|
+
|
832
|
+
def is_not_in(self, value: str) -> Self:
|
833
|
+
self._check_type_is_str(value)
|
834
|
+
self._condition = f"notIn {self._format_value(value)}"
|
835
|
+
return self
|
836
|
+
|
837
|
+
def startswith(self, value: str) -> Self:
|
838
|
+
self._check_type_is_str(value)
|
839
|
+
self._condition = f"startsWith {self._format_value(value)}"
|
840
|
+
return self
|
841
|
+
|
842
|
+
def endswith(self, value: str) -> Self:
|
843
|
+
self._check_type_is_str(value)
|
844
|
+
self._condition = f"endsWith {self._format_value(value)}"
|
845
|
+
return self
|
846
|
+
|
847
|
+
|
848
|
+
def in_range(self, startValue: Union[numbers.Number, date], endValue: Union[numbers.Number, date],
|
849
|
+
startsInclusive: bool = False, endsInclusive: bool = False) -> Self:
|
850
|
+
self._check_type_is_number_or_date_or_str(startValue)
|
851
|
+
self._check_type_is_number_or_date_or_str(endValue)
|
852
|
+
if type(startValue) is not type(endValue):
|
853
|
+
raise TypeError("startValue and endValue must be of the same type")
|
854
|
+
start_op = "[" if startsInclusive else "(" # [ is inclusive, ( is exclusive
|
855
|
+
end_op = "]" if endsInclusive else ")"
|
856
|
+
self._condition = f"{start_op}{self._format_value(startValue)}:{self._format_value(endValue)}{end_op}"
|
857
|
+
return self
|
858
|
+
|
859
|
+
def _check_type_is_number_or_date(self, value: Union[numbers.Number, date]):
|
860
|
+
if not isinstance(value, (numbers.Number, date)):
|
861
|
+
raise TypeError("Value must be a number or a date")
|
862
|
+
|
863
|
+
def _check_type_is_number_or_date_or_str(self, value: Union[numbers.Number, date, str]):
|
864
|
+
if not isinstance(value, (numbers.Number, date, str)):
|
865
|
+
raise TypeError("Value must be a number or a date or a string")
|
866
|
+
|
867
|
+
def _check_type_is_str(self, value: str):
|
868
|
+
if not isinstance(value, str):
|
869
|
+
raise TypeError("Value must be a string")
|
870
|
+
|
871
|
+
@staticmethod
|
872
|
+
def _format_value(value: Union[numbers.Number, date, str]):
|
873
|
+
if isinstance(value, numbers.Number):
|
874
|
+
return f"{value}"
|
875
|
+
if isinstance(value, date):
|
876
|
+
return f"\"{value.strftime('%B %d, %Y')}\""
|
877
|
+
return f"\"{value}\""
|
878
|
+
|
879
|
+
def condition(self):
|
880
|
+
return self._condition
|
881
|
+
|
882
|
+
|
883
|
+
|
884
|
+
class DecisionsRule(BaseModel):
|
820
885
|
'''
|
821
|
-
|
886
|
+
A set of decisions rules.
|
822
887
|
'''
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
888
|
+
_conditions: dict[str, str]
|
889
|
+
_actions: dict[str, Union[numbers.Number, str]]
|
890
|
+
|
891
|
+
def __init__(self, **data):
|
892
|
+
super().__init__(**data)
|
893
|
+
self._conditions = {}
|
894
|
+
self._actions = {}
|
895
|
+
|
896
|
+
def condition(self, key: str, cond: DecisionsCondition) -> Self:
|
897
|
+
self._conditions[key] = cond.condition()
|
898
|
+
return self
|
899
|
+
|
900
|
+
def action(self, key: str, value: Union[numbers.Number, date, str]) -> Self:
|
901
|
+
if isinstance(value, date):
|
902
|
+
self._actions[key] = value.strftime("%B %d, %Y")
|
903
|
+
return self
|
904
|
+
self._actions[key] = value
|
905
|
+
return self
|
906
|
+
|
907
|
+
def to_json(self) -> dict[str, Any]:
|
908
|
+
'''
|
909
|
+
Serialize the rules into JSON object
|
910
|
+
'''
|
911
|
+
model_spec = {}
|
912
|
+
if self._conditions:
|
913
|
+
model_spec["conditions"] = self._conditions
|
914
|
+
if self._actions:
|
915
|
+
model_spec["actions"] = self._actions
|
916
|
+
return model_spec
|
917
|
+
|
918
|
+
|
919
|
+
class DecisionsNodeSpec(NodeSpec):
|
840
920
|
'''
|
841
|
-
|
842
|
-
Attributes:
|
843
|
-
utility_bull: an object with the fields extracted from the input utility bill document
|
921
|
+
Node specification for Decision Table
|
844
922
|
'''
|
845
|
-
|
846
|
-
|
847
|
-
|
848
|
-
|
923
|
+
locale: str | None = None
|
924
|
+
rules: list[DecisionsRule]
|
925
|
+
default_actions: dict[str, Union[int, float, complex, str]] | None
|
926
|
+
|
927
|
+
def __init__(self, **data):
|
928
|
+
super().__init__(**data)
|
929
|
+
self.kind = "decisions"
|
930
|
+
|
931
|
+
def default_action(self, key: str, value: Union[int, float, complex, date, str]) -> Self:
|
932
|
+
'''
|
933
|
+
create a new default action
|
934
|
+
'''
|
935
|
+
if isinstance(value, date):
|
936
|
+
self.default_actions[key] = value.strftime("%B %d, %Y")
|
937
|
+
return self
|
938
|
+
self.default_actions[key] = value
|
939
|
+
return self
|
940
|
+
|
941
|
+
def to_json(self) -> dict[str, Any]:
|
942
|
+
model_spec = super().to_json()
|
943
|
+
if self.locale:
|
944
|
+
model_spec["locale"] = self.locale
|
945
|
+
if self.rules:
|
946
|
+
model_spec["rules"] = [rule.to_json() for rule in self.rules]
|
947
|
+
if self.default_actions:
|
948
|
+
model_spec["default_actions"] = self.default_actions
|
949
|
+
|
950
|
+
return model_spec
|
951
|
+
|
849
952
|
|
850
953
|
def extract_node_spec(
|
851
954
|
fn: Callable | PythonTool,
|
{ibm_watsonx_orchestrate-1.8.0b0.dist-info → ibm_watsonx_orchestrate-1.8.0b1.dist-info}/METADATA
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: ibm-watsonx-orchestrate
|
3
|
-
Version: 1.8.
|
3
|
+
Version: 1.8.0b1
|
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.0.
|
14
|
+
Requires-Dist: ibm-watsonx-orchestrate-evaluation-framework==1.0.8
|
15
15
|
Requires-Dist: jsonref==1.1.0
|
16
16
|
Requires-Dist: jsonschema<5.0.0,>=4.23.0
|
17
17
|
Requires-Dist: langchain-core<=0.3.63
|