ibm-watsonx-orchestrate 1.10.2__py3-none-any.whl → 1.11.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ibm_watsonx_orchestrate/__init__.py +2 -1
- ibm_watsonx_orchestrate/agent_builder/agents/types.py +13 -0
- ibm_watsonx_orchestrate/agent_builder/connections/types.py +53 -6
- ibm_watsonx_orchestrate/agent_builder/knowledge_bases/types.py +25 -10
- ibm_watsonx_orchestrate/cli/commands/agents/agents_command.py +10 -2
- ibm_watsonx_orchestrate/cli/commands/agents/agents_controller.py +404 -173
- ibm_watsonx_orchestrate/cli/commands/connections/connections_command.py +33 -4
- ibm_watsonx_orchestrate/cli/commands/connections/connections_controller.py +62 -6
- ibm_watsonx_orchestrate/cli/commands/copilot/copilot_controller.py +6 -2
- ibm_watsonx_orchestrate/cli/commands/environment/environment_command.py +1 -1
- ibm_watsonx_orchestrate/cli/commands/evaluations/evaluations_command.py +174 -2
- ibm_watsonx_orchestrate/cli/commands/evaluations/evaluations_controller.py +93 -9
- ibm_watsonx_orchestrate/cli/commands/server/server_command.py +0 -3
- ibm_watsonx_orchestrate/cli/commands/server/types.py +15 -7
- ibm_watsonx_orchestrate/client/base_api_client.py +31 -10
- ibm_watsonx_orchestrate/client/connections/connections_client.py +14 -0
- ibm_watsonx_orchestrate/client/service_instance.py +19 -34
- ibm_watsonx_orchestrate/client/utils.py +3 -1
- ibm_watsonx_orchestrate/docker/compose-lite.yml +16 -11
- ibm_watsonx_orchestrate/docker/default.env +15 -13
- ibm_watsonx_orchestrate/flow_builder/data_map.py +4 -1
- ibm_watsonx_orchestrate/flow_builder/flows/flow.py +117 -7
- ibm_watsonx_orchestrate/flow_builder/node.py +76 -5
- ibm_watsonx_orchestrate/flow_builder/types.py +344 -10
- {ibm_watsonx_orchestrate-1.10.2.dist-info → ibm_watsonx_orchestrate-1.11.0.dist-info}/METADATA +2 -2
- {ibm_watsonx_orchestrate-1.10.2.dist-info → ibm_watsonx_orchestrate-1.11.0.dist-info}/RECORD +29 -29
- {ibm_watsonx_orchestrate-1.10.2.dist-info → ibm_watsonx_orchestrate-1.11.0.dist-info}/WHEEL +0 -0
- {ibm_watsonx_orchestrate-1.10.2.dist-info → ibm_watsonx_orchestrate-1.11.0.dist-info}/entry_points.txt +0 -0
- {ibm_watsonx_orchestrate-1.10.2.dist-info → ibm_watsonx_orchestrate-1.11.0.dist-info}/licenses/LICENSE +0 -0
@@ -12,6 +12,7 @@ from pathlib import Path
|
|
12
12
|
from copy import deepcopy
|
13
13
|
|
14
14
|
from typing import Iterable, List, TypeVar
|
15
|
+
from pydantic import BaseModel
|
15
16
|
from ibm_watsonx_orchestrate.agent_builder.agents.types import AgentStyle
|
16
17
|
from ibm_watsonx_orchestrate.agent_builder.tools.types import ToolSpec
|
17
18
|
from ibm_watsonx_orchestrate.cli.commands.tools.tools_controller import import_python_tool, ToolsController
|
@@ -40,11 +41,24 @@ from ibm_watsonx_orchestrate.utils.utils import check_file_in_zip
|
|
40
41
|
from rich.console import Console
|
41
42
|
from rich.progress import Progress, SpinnerColumn, TextColumn
|
42
43
|
|
44
|
+
from enum import Enum
|
45
|
+
|
43
46
|
logger = logging.getLogger(__name__)
|
44
47
|
|
45
48
|
# Helper generic type for any agent
|
46
49
|
AnyAgentT = TypeVar("AnyAgentT", bound=Agent | ExternalAgent | AssistantAgent)
|
47
50
|
|
51
|
+
class AgentListFormats(str, Enum):
|
52
|
+
Table = "table"
|
53
|
+
JSON = "json"
|
54
|
+
|
55
|
+
def __str__(self):
|
56
|
+
return self.value
|
57
|
+
|
58
|
+
def __repr__(self):
|
59
|
+
return repr(self.value)
|
60
|
+
|
61
|
+
|
48
62
|
def import_python_agent(file: str) -> List[Agent | ExternalAgent | AssistantAgent]:
|
49
63
|
# Import tools
|
50
64
|
import_python_tool(file)
|
@@ -100,6 +114,7 @@ def parse_create_native_args(name: str, kind: AgentKind, description: str | None
|
|
100
114
|
"name": name,
|
101
115
|
"kind": kind,
|
102
116
|
"description": description,
|
117
|
+
"instructions": args.get("instructions"),
|
103
118
|
"llm": args.get("llm"),
|
104
119
|
"style": args.get("style"),
|
105
120
|
"custom_join_tool": args.get("custom_join_tool"),
|
@@ -804,213 +819,429 @@ class AgentsController:
|
|
804
819
|
logger.warning(f"Knowledge base with ID {id} not found. Returning Tool ID")
|
805
820
|
knowledge_bases.append(id)
|
806
821
|
return knowledge_bases
|
807
|
-
|
808
|
-
def
|
822
|
+
|
823
|
+
def _fetch_and_parse_agents(self, target_agent_kind: AgentKind) -> tuple[List[Agent] | List[ExternalAgent] | List[AssistantAgent], List[List[str]]]:
|
809
824
|
parse_errors = []
|
825
|
+
target_kind_display_name = None
|
826
|
+
target_kind_class = None
|
827
|
+
agent_client = None
|
810
828
|
|
811
|
-
|
812
|
-
|
813
|
-
"
|
814
|
-
|
815
|
-
|
816
|
-
|
829
|
+
match(target_agent_kind):
|
830
|
+
case AgentKind.NATIVE:
|
831
|
+
target_kind_display_name = "Agent"
|
832
|
+
target_kind_class = Agent
|
833
|
+
agent_client = self.get_native_client()
|
834
|
+
case AgentKind.EXTERNAL:
|
835
|
+
target_kind_display_name = "External Agent"
|
836
|
+
target_kind_class = ExternalAgent
|
837
|
+
agent_client = self.get_external_client()
|
838
|
+
case AgentKind.ASSISTANT:
|
839
|
+
target_kind_display_name = "Assistant Agent"
|
840
|
+
target_kind_class = AssistantAgent
|
841
|
+
agent_client = self.get_assistant_client()
|
842
|
+
case _:
|
843
|
+
return ([], [[f"Invalid Agent kind '{target_agent_kind}'"]])
|
844
|
+
|
845
|
+
response = agent_client.get()
|
846
|
+
agents = []
|
847
|
+
for agent in response:
|
848
|
+
try:
|
849
|
+
agents.append(target_kind_class.model_validate(agent))
|
850
|
+
except Exception as e:
|
851
|
+
name = agent.get('name', None)
|
852
|
+
parse_errors.append([
|
853
|
+
f"{target_kind_display_name} '{name}' could not be parsed",
|
854
|
+
json.dumps(agent),
|
855
|
+
e
|
856
|
+
])
|
857
|
+
return (agents, parse_errors)
|
858
|
+
|
859
|
+
def _get_all_unique_agent_resources(self, agents: List[Agent], target_attr: str) -> List[str]:
|
860
|
+
"""
|
861
|
+
Given a list if agents get all the unique values of a certain field
|
862
|
+
Example: agent1.tools = [1 ,2 ,3] and agent2.tools = [2, 4, 5] then return [1, 2, 3, 4, 5]
|
863
|
+
Example: agent1.id = "123" and agent2.id = "456" then return ["123", "456"]
|
864
|
+
|
865
|
+
Args:
|
866
|
+
agents: List of agents
|
867
|
+
target_attr: The name of the field to access and get unique elements
|
868
|
+
|
869
|
+
Returns:
|
870
|
+
A list of unique elements from across all agents
|
871
|
+
"""
|
872
|
+
all_ids = set()
|
873
|
+
for agent in agents:
|
874
|
+
attr_value = getattr(agent, target_attr, None)
|
875
|
+
if attr_value:
|
876
|
+
if isinstance(attr_value, list):
|
877
|
+
all_ids.update(attr_value)
|
878
|
+
else:
|
879
|
+
all_ids.add(attr_value)
|
880
|
+
return list(all_ids)
|
881
|
+
|
882
|
+
def _construct_lut_agent_resource(self, resource_list: List[dict], key_attr: str, value_attr) -> dict:
|
883
|
+
"""
|
884
|
+
Given a list of dictionaries build a key -> value look up table
|
885
|
+
Example [{id: 1, name: obj1}, {id: 2, name: obj2}] return {1: obj1, 2: obj2}
|
886
|
+
|
887
|
+
Args:
|
888
|
+
resource_list: A list of dictionries from which to build the lookup table from
|
889
|
+
key_attr: The name of the field whose value will form the key of the lookup table
|
890
|
+
value_attrL The name of the field whose value will form the value of the lookup table
|
891
|
+
|
892
|
+
Returns:
|
893
|
+
A lookup table
|
894
|
+
"""
|
895
|
+
lut = {}
|
896
|
+
for resource in resource_list:
|
897
|
+
if isinstance(resource, BaseModel):
|
898
|
+
resource = resource.model_dump()
|
899
|
+
lut[resource.get(key_attr, None)] = resource.get(value_attr, None)
|
900
|
+
return lut
|
901
|
+
|
902
|
+
def _lookup_agent_resource_value(
|
903
|
+
self,
|
904
|
+
agent: Agent,
|
905
|
+
lookup_table: dict[str, str],
|
906
|
+
target_attr: str,
|
907
|
+
target_attr_display_name: str
|
908
|
+
) -> List[str] | str | None:
|
909
|
+
"""
|
910
|
+
Using a lookup table convert all the strings in a given field of an agent into their equivalent in the lookup table
|
911
|
+
Example: lookup_table={1: obj1, 2: obj2} agent=Agent(tools=[1,2]) return. [obj1, obj2]
|
912
|
+
|
913
|
+
Args:
|
914
|
+
agent: An agent
|
915
|
+
lookup_table: A dictionary that maps one value to another
|
916
|
+
target_attr: The field to convert on the provided agent
|
917
|
+
target_attr_display_name: The name of the field to be displayed in the event of an error
|
918
|
+
"""
|
919
|
+
attr_value = getattr(agent, target_attr, None)
|
920
|
+
if not attr_value:
|
921
|
+
return
|
922
|
+
|
923
|
+
if isinstance(attr_value, list):
|
924
|
+
new_resource_list=[]
|
925
|
+
for value in attr_value:
|
926
|
+
if value in lookup_table:
|
927
|
+
new_resource_list.append(lookup_table[value])
|
928
|
+
else:
|
929
|
+
logger.warning(f"{target_attr_display_name} with ID '{value}' not found. Returning {target_attr_display_name} ID")
|
930
|
+
new_resource_list.append(value)
|
931
|
+
return new_resource_list
|
932
|
+
else:
|
933
|
+
if attr_value in lookup_table:
|
934
|
+
return lookup_table[attr_value]
|
935
|
+
else:
|
936
|
+
logger.warning(f"{target_attr_display_name} with ID '{attr_value}' not found. Returning {target_attr_display_name} ID")
|
937
|
+
return attr_value
|
938
|
+
|
939
|
+
def _batch_request_resource(self, client_fn, ids, batch_size=50) -> List[dict]:
|
940
|
+
resources = []
|
941
|
+
for i in range(0, len(ids), batch_size):
|
942
|
+
chunk = ids[i:i + batch_size]
|
943
|
+
resources += (client_fn(chunk))
|
944
|
+
return resources
|
945
|
+
|
946
|
+
|
947
|
+
def _bulk_resolve_agent_tools(self, agents: List[Agent]) -> List[Agent]:
|
948
|
+
new_agents = agents.copy()
|
949
|
+
all_tools_ids = self._get_all_unique_agent_resources(new_agents, "tools")
|
950
|
+
if not all_tools_ids:
|
951
|
+
return new_agents
|
952
|
+
|
953
|
+
all_tools = self._batch_request_resource(self.get_tool_client().get_drafts_by_ids, all_tools_ids)
|
954
|
+
|
955
|
+
tool_lut = self._construct_lut_agent_resource(all_tools, "id", "name")
|
956
|
+
|
957
|
+
for agent in new_agents:
|
958
|
+
tool_names = self._lookup_agent_resource_value(agent, tool_lut, "tools", "Tool")
|
959
|
+
if tool_names:
|
960
|
+
agent.tools = tool_names
|
961
|
+
return new_agents
|
962
|
+
|
963
|
+
# TODO: Once bulk knowledge base is added create a generaic fucntion as opposed to 3 seperate ones
|
964
|
+
def _bulk_resolve_agent_knowledge_bases(self, agents: List[Agent]) -> List[Agent]:
|
965
|
+
new_agents = agents.copy()
|
966
|
+
all_kb_ids = self._get_all_unique_agent_resources(new_agents, "knowledge_base")
|
967
|
+
|
968
|
+
all_kbs = []
|
969
|
+
for id in all_kb_ids:
|
970
|
+
try:
|
971
|
+
all_kbs.append(self.get_knowledge_base_client().get_by_id(id))
|
972
|
+
except:
|
973
|
+
continue
|
974
|
+
|
975
|
+
kb_lut = self._construct_lut_agent_resource(all_kbs, "id", "name")
|
976
|
+
|
977
|
+
for agent in new_agents:
|
978
|
+
kb_names = self._lookup_agent_resource_value(agent, kb_lut, "knowledge_base", "Knowledge Base")
|
979
|
+
if kb_names:
|
980
|
+
agent.knowledge_base = kb_names
|
981
|
+
return new_agents
|
982
|
+
|
983
|
+
def _bulk_resolve_agent_collaborators(self, agents: List[Agent]) -> List[Agent]:
|
984
|
+
new_agents = agents.copy()
|
985
|
+
all_collab_ids = self._get_all_unique_agent_resources(new_agents, "collaborators")
|
986
|
+
if not all_collab_ids:
|
987
|
+
return new_agents
|
988
|
+
|
989
|
+
native_agents = self._batch_request_resource(self.get_native_client().get_drafts_by_ids, all_collab_ids)
|
990
|
+
external_agents = self._batch_request_resource(self.get_external_client().get_drafts_by_ids, all_collab_ids)
|
991
|
+
assitant_agents = self._batch_request_resource(self.get_assistant_client().get_drafts_by_ids, all_collab_ids)
|
992
|
+
|
993
|
+
all_collabs = native_agents + external_agents + assitant_agents
|
994
|
+
|
995
|
+
collab_lut = self._construct_lut_agent_resource(all_collabs, "id", "name")
|
996
|
+
|
997
|
+
for agent in new_agents:
|
998
|
+
collab_names = self._lookup_agent_resource_value(agent, collab_lut, "collaborators", "Collaborator")
|
999
|
+
if collab_names:
|
1000
|
+
agent.collaborators = collab_names
|
1001
|
+
return new_agents
|
1002
|
+
|
1003
|
+
def _bulk_resolve_agent_app_ids(self , agents: List[ExternalAgent]) -> List[ExternalAgent]:
|
1004
|
+
new_agents = agents.copy()
|
1005
|
+
all_conn_ids = self._get_all_unique_agent_resources(new_agents, "connection_id")
|
1006
|
+
if not all_conn_ids:
|
1007
|
+
return new_agents
|
1008
|
+
|
1009
|
+
all_connections = self._batch_request_resource(get_connections_client().get_drafts_by_ids, all_conn_ids)
|
1010
|
+
|
1011
|
+
connection_lut = self._construct_lut_agent_resource(all_connections, "connection_id", "app_id")
|
1012
|
+
|
1013
|
+
for agent in new_agents:
|
1014
|
+
app_id = self._lookup_agent_resource_value(agent, connection_lut, "connection_id", "Connection")
|
1015
|
+
if app_id:
|
1016
|
+
agent.app_id = app_id
|
1017
|
+
return new_agents
|
1018
|
+
|
1019
|
+
# TODO: Make a shared util
|
1020
|
+
def _rich_table_to_markdown(self, table: rich.table.Table) -> str:
|
1021
|
+
headers = [column.header for column in table.columns]
|
1022
|
+
cols = [[cell for cell in col.cells] for col in table.columns]
|
1023
|
+
rows = list(map(list, zip(*cols)))
|
1024
|
+
|
1025
|
+
# Header row
|
1026
|
+
md = "| " + " | ".join(headers) + " |\n"
|
1027
|
+
# Separator row
|
1028
|
+
md += "| " + " | ".join(["---"] * len(headers)) + " |\n"
|
1029
|
+
# # Data rows
|
1030
|
+
for row in rows:
|
1031
|
+
md += "| " + " | ".join(row) + " |\n"
|
1032
|
+
return md
|
1033
|
+
|
1034
|
+
|
1035
|
+
|
1036
|
+
def list_agents(self, kind: AgentKind=None, verbose: bool=False, format: AgentListFormats | None = None) -> dict[str, dict] | None:
|
1037
|
+
"""
|
1038
|
+
List agents in the active wxo environment
|
1039
|
+
|
1040
|
+
Args:
|
1041
|
+
kind: Filter to only list a certain kind of agent. Allowed values "native", "assistant", "external"
|
1042
|
+
verbose: Show raw json output without table formatting or id to name resolution
|
1043
|
+
format: Optional value. If provided print nothing and return a string containing the agents in the requested format. Allowed values "table", "json"
|
1044
|
+
"""
|
1045
|
+
if verbose and format:
|
1046
|
+
logger.error("For agents list, `--verbose` and `--format` are mutually exclusive options")
|
1047
|
+
sys.exit(1)
|
1048
|
+
|
1049
|
+
parse_errors = []
|
1050
|
+
output_dictionary = {
|
1051
|
+
"native": None,
|
1052
|
+
"assistant": None,
|
1053
|
+
"external": None
|
1054
|
+
}
|
817
1055
|
|
818
1056
|
if kind == AgentKind.NATIVE or kind is None:
|
819
|
-
|
820
|
-
|
821
|
-
for agent in response:
|
822
|
-
try:
|
823
|
-
native_agents.append(Agent.model_validate(agent))
|
824
|
-
except Exception as e:
|
825
|
-
name = agent.get('name', None)
|
826
|
-
parse_errors.append([
|
827
|
-
f"Agent '{name}' could not be parsed",
|
828
|
-
json.dumps(agent),
|
829
|
-
e
|
830
|
-
])
|
1057
|
+
native_agents, new_parse_errors = self._fetch_and_parse_agents(AgentKind.NATIVE)
|
1058
|
+
parse_errors += new_parse_errors
|
831
1059
|
|
832
1060
|
if verbose:
|
833
1061
|
agents_list = []
|
834
1062
|
for agent in native_agents:
|
835
1063
|
agents_list.append(json.loads(agent.dumps_spec()))
|
836
1064
|
|
837
|
-
|
1065
|
+
output_dictionary["native"] = agents_list
|
838
1066
|
else:
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
|
848
|
-
"
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
for column in column_args:
|
856
|
-
native_table.add_column(column, **column_args[column])
|
857
|
-
|
858
|
-
for agent in native_agents:
|
859
|
-
tool_names = self.get_agent_tool_names(agent.tools)
|
860
|
-
knowledge_base_names = self.get_agent_knowledge_base_names(agent.knowledge_base)
|
861
|
-
collaborator_names = self.get_agent_collaborator_names(agent.collaborators)
|
862
|
-
|
863
|
-
native_table.add_row(
|
864
|
-
agent.name,
|
865
|
-
agent.description,
|
866
|
-
agent.llm,
|
867
|
-
agent.style,
|
868
|
-
", ".join(collaborator_names),
|
869
|
-
", ".join(tool_names),
|
870
|
-
", ".join(knowledge_base_names),
|
871
|
-
agent.id,
|
1067
|
+
resolved_native_agents = self._bulk_resolve_agent_tools(native_agents)
|
1068
|
+
resolved_native_agents = self._bulk_resolve_agent_knowledge_bases(resolved_native_agents)
|
1069
|
+
resolved_native_agents = self._bulk_resolve_agent_collaborators(resolved_native_agents)
|
1070
|
+
|
1071
|
+
if format and format == AgentListFormats.JSON:
|
1072
|
+
agents_list = []
|
1073
|
+
for agent in resolved_native_agents:
|
1074
|
+
agents_list.append(json.loads(agent.dumps_spec()))
|
1075
|
+
|
1076
|
+
output_dictionary["native"] = agents_list
|
1077
|
+
else:
|
1078
|
+
native_table = rich.table.Table(
|
1079
|
+
show_header=True,
|
1080
|
+
header_style="bold white",
|
1081
|
+
title="Agents",
|
1082
|
+
show_lines=True
|
872
1083
|
)
|
873
|
-
rich.print(native_table)
|
874
1084
|
|
1085
|
+
column_args = {
|
1086
|
+
"Name": {"overflow": "fold"},
|
1087
|
+
"Description": {},
|
1088
|
+
"LLM": {"overflow": "fold"},
|
1089
|
+
"Style": {},
|
1090
|
+
"Collaborators": {},
|
1091
|
+
"Tools": {},
|
1092
|
+
"Knowledge Base": {},
|
1093
|
+
"ID": {"overflow": "fold"},
|
1094
|
+
}
|
1095
|
+
for column in column_args:
|
1096
|
+
native_table.add_column(column, **column_args[column])
|
1097
|
+
|
1098
|
+
for agent in resolved_native_agents:
|
1099
|
+
native_table.add_row(
|
1100
|
+
agent.name,
|
1101
|
+
agent.description,
|
1102
|
+
agent.llm,
|
1103
|
+
agent.style,
|
1104
|
+
", ".join(agent.collaborators),
|
1105
|
+
", ".join(agent.tools),
|
1106
|
+
", ".join(agent.knowledge_base),
|
1107
|
+
agent.id,
|
1108
|
+
)
|
1109
|
+
if format == AgentListFormats.Table:
|
1110
|
+
output_dictionary["native"] = self._rich_table_to_markdown(native_table)
|
1111
|
+
else:
|
1112
|
+
rich.print(native_table)
|
875
1113
|
|
876
1114
|
if kind == AgentKind.EXTERNAL or kind is None:
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
for agent in response:
|
881
|
-
try:
|
882
|
-
external_agents.append(ExternalAgent.model_validate(agent))
|
883
|
-
except Exception as e:
|
884
|
-
name = agent.get('name', None)
|
885
|
-
parse_errors.append([f"External Agent {name} could not be parsed", e])
|
886
|
-
|
887
|
-
response_dict = {agent["id"]: agent for agent in response}
|
888
|
-
|
889
|
-
# Insert config values into config as config object is not retruned from api
|
890
|
-
for external_agent in external_agents:
|
891
|
-
if external_agent.id in response_dict:
|
892
|
-
response_data = response_dict[external_agent.id]
|
893
|
-
external_agent.config.enable_cot = response_data.get("enable_cot", external_agent.config.enable_cot)
|
894
|
-
external_agent.config.hidden = response_data.get("hidden", external_agent.config.hidden)
|
895
|
-
|
896
|
-
external_agents_list = []
|
1115
|
+
external_agents, new_parse_errors = self._fetch_and_parse_agents(AgentKind.EXTERNAL)
|
1116
|
+
parse_errors += new_parse_errors
|
1117
|
+
|
897
1118
|
if verbose:
|
1119
|
+
external_agents_list = []
|
898
1120
|
for agent in external_agents:
|
899
1121
|
external_agents_list.append(json.loads(agent.dumps_spec()))
|
900
|
-
|
1122
|
+
output_dictionary["external"] = external_agents_list
|
901
1123
|
else:
|
902
|
-
|
903
|
-
show_header=True,
|
904
|
-
header_style="bold white",
|
905
|
-
title="External Agents",
|
906
|
-
show_lines=True
|
907
|
-
)
|
908
|
-
column_args = {
|
909
|
-
"Name": {"overflow": "fold"},
|
910
|
-
"Title": {},
|
911
|
-
"Description": {},
|
912
|
-
"Tags": {},
|
913
|
-
"API URL": {"overflow": "fold"},
|
914
|
-
"Chat Params": {},
|
915
|
-
"Config": {},
|
916
|
-
"Nickname": {},
|
917
|
-
"App ID": {"overflow": "fold"},
|
918
|
-
"ID": {"overflow": "fold"}
|
919
|
-
}
|
920
|
-
|
921
|
-
for column in column_args:
|
922
|
-
external_table.add_column(column, **column_args[column])
|
1124
|
+
resolved_external_agents = self._bulk_resolve_agent_app_ids(external_agents)
|
923
1125
|
|
924
|
-
|
925
|
-
|
926
|
-
|
927
|
-
|
928
|
-
|
929
|
-
|
930
|
-
|
931
|
-
|
932
|
-
|
933
|
-
|
934
|
-
|
935
|
-
|
936
|
-
agent.nickname,
|
937
|
-
app_id,
|
938
|
-
agent.id
|
1126
|
+
if format and format == AgentListFormats.JSON:
|
1127
|
+
external_agents_list = []
|
1128
|
+
for agent in resolved_external_agents:
|
1129
|
+
external_agents_list.append(json.loads(agent.dumps_spec()))
|
1130
|
+
|
1131
|
+
output_dictionary["external"] = external_agents_list
|
1132
|
+
else:
|
1133
|
+
external_table = rich.table.Table(
|
1134
|
+
show_header=True,
|
1135
|
+
header_style="bold white",
|
1136
|
+
title="External Agents",
|
1137
|
+
show_lines=True
|
939
1138
|
)
|
940
|
-
|
1139
|
+
column_args = {
|
1140
|
+
"Name": {"overflow": "fold"},
|
1141
|
+
"Title": {},
|
1142
|
+
"Description": {},
|
1143
|
+
"Tags": {},
|
1144
|
+
"API URL": {"overflow": "fold"},
|
1145
|
+
"Chat Params": {},
|
1146
|
+
"Config": {},
|
1147
|
+
"Nickname": {},
|
1148
|
+
"App ID": {"overflow": "fold"},
|
1149
|
+
"ID": {"overflow": "fold"}
|
1150
|
+
}
|
1151
|
+
|
1152
|
+
for column in column_args:
|
1153
|
+
external_table.add_column(column, **column_args[column])
|
1154
|
+
|
1155
|
+
for agent in external_agents:
|
1156
|
+
connections_client = get_connections_client()
|
1157
|
+
app_id = connections_client.get_draft_by_id(agent.connection_id)
|
1158
|
+
resolved_native_agents = self._bulk_resolve_agent_app_ids(external_agents)
|
1159
|
+
|
1160
|
+
external_table.add_row(
|
1161
|
+
agent.name,
|
1162
|
+
agent.title,
|
1163
|
+
agent.description,
|
1164
|
+
", ".join(agent.tags or []),
|
1165
|
+
agent.api_url,
|
1166
|
+
json.dumps(agent.chat_params),
|
1167
|
+
str(agent.config),
|
1168
|
+
agent.nickname,
|
1169
|
+
app_id,
|
1170
|
+
agent.id
|
1171
|
+
)
|
1172
|
+
if format == AgentListFormats.Table:
|
1173
|
+
output_dictionary["external"] = self._rich_table_to_markdown(external_table)
|
1174
|
+
else:
|
1175
|
+
rich.print(external_table)
|
941
1176
|
|
942
1177
|
if kind == AgentKind.ASSISTANT or kind is None:
|
943
|
-
|
944
|
-
|
945
|
-
assistant_agents = []
|
946
|
-
for agent in response:
|
947
|
-
try:
|
948
|
-
assistant_agents.append(AssistantAgent.model_validate(agent))
|
949
|
-
except Exception as e:
|
950
|
-
name = agent.get('name', None)
|
951
|
-
parse_errors.append([f"Assistant Agent {name} could not be parsed", e])
|
952
|
-
|
953
|
-
response_dict = {agent["id"]: agent for agent in response}
|
954
|
-
|
955
|
-
# Insert config values into config as config object is not retruned from api
|
956
|
-
for assistant_agent in assistant_agents:
|
957
|
-
if assistant_agent.id in response_dict:
|
958
|
-
response_data = response_dict[assistant_agent.id]
|
959
|
-
assistant_agent.config.api_version = response_data.get("api_version", assistant_agent.config.api_version)
|
960
|
-
assistant_agent.config.assistant_id = response_data.get("assistant_id", assistant_agent.config.assistant_id)
|
961
|
-
assistant_agent.config.crn = response_data.get("crn", assistant_agent.config.crn)
|
962
|
-
assistant_agent.config.service_instance_url = response_data.get("service_instance_url", assistant_agent.config.service_instance_url)
|
963
|
-
assistant_agent.config.environment_id = response_data.get("environment_id", assistant_agent.config.environment_id)
|
964
|
-
assistant_agent.config.authorization_url = response_data.get("authorization_url", assistant_agent.config.authorization_url)
|
1178
|
+
assistant_agents, new_parse_errors = self._fetch_and_parse_agents(AgentKind.ASSISTANT)
|
1179
|
+
parse_errors += new_parse_errors
|
965
1180
|
|
966
1181
|
if verbose:
|
967
|
-
|
1182
|
+
assistant_agents_list = []
|
968
1183
|
for agent in assistant_agents:
|
969
|
-
|
970
|
-
|
1184
|
+
assistant_agents_list.append(json.loads(agent.dumps_spec()))
|
1185
|
+
output_dictionary["assistant"] = assistant_agents_list
|
971
1186
|
else:
|
972
|
-
|
973
|
-
show_header=True,
|
974
|
-
header_style="bold white",
|
975
|
-
title="Assistant Agents",
|
976
|
-
show_lines=True)
|
977
|
-
column_args = {
|
978
|
-
"Name": {"overflow": "fold"},
|
979
|
-
"Title": {},
|
980
|
-
"Description": {},
|
981
|
-
"Tags": {},
|
982
|
-
"Nickname": {},
|
983
|
-
"CRN": {},
|
984
|
-
"Instance URL": {},
|
985
|
-
"Assistant ID": {"overflow": "fold"},
|
986
|
-
"Environment ID": {"overflow": "fold"},
|
987
|
-
"ID": {"overflow": "fold"}
|
988
|
-
}
|
989
|
-
|
990
|
-
for column in column_args:
|
991
|
-
assistants_table.add_column(column, **column_args[column])
|
1187
|
+
resolved_external_agents = self._bulk_resolve_agent_app_ids(assistant_agents)
|
992
1188
|
|
993
|
-
|
994
|
-
|
995
|
-
|
996
|
-
agent.
|
997
|
-
|
998
|
-
|
999
|
-
|
1000
|
-
|
1001
|
-
|
1002
|
-
|
1003
|
-
|
1004
|
-
|
1005
|
-
|
1006
|
-
|
1189
|
+
if format and format == AgentListFormats.JSON:
|
1190
|
+
assistant_agents_list = []
|
1191
|
+
for agent in resolved_external_agents:
|
1192
|
+
assistant_agents_list.append(json.loads(agent.dumps_spec()))
|
1193
|
+
|
1194
|
+
output_dictionary["assistant"] = assistant_agents_list
|
1195
|
+
else:
|
1196
|
+
assistants_table = rich.table.Table(
|
1197
|
+
show_header=True,
|
1198
|
+
header_style="bold white",
|
1199
|
+
title="Assistant Agents",
|
1200
|
+
show_lines=True)
|
1201
|
+
column_args = {
|
1202
|
+
"Name": {"overflow": "fold"},
|
1203
|
+
"Title": {},
|
1204
|
+
"Description": {},
|
1205
|
+
"Tags": {},
|
1206
|
+
"Nickname": {},
|
1207
|
+
"CRN": {},
|
1208
|
+
"Instance URL": {},
|
1209
|
+
"Assistant ID": {"overflow": "fold"},
|
1210
|
+
"Environment ID": {"overflow": "fold"},
|
1211
|
+
"ID": {"overflow": "fold"}
|
1212
|
+
}
|
1213
|
+
|
1214
|
+
for column in column_args:
|
1215
|
+
assistants_table.add_column(column, **column_args[column])
|
1216
|
+
|
1217
|
+
for agent in assistant_agents:
|
1218
|
+
assistants_table.add_row(
|
1219
|
+
agent.name,
|
1220
|
+
agent.title,
|
1221
|
+
agent.description,
|
1222
|
+
", ".join(agent.tags or []),
|
1223
|
+
agent.nickname,
|
1224
|
+
agent.config.crn,
|
1225
|
+
agent.config.service_instance_url,
|
1226
|
+
agent.config.assistant_id,
|
1227
|
+
agent.config.environment_id,
|
1228
|
+
agent.id
|
1229
|
+
)
|
1230
|
+
if format == AgentListFormats.Table:
|
1231
|
+
output_dictionary["assistant"] = self._rich_table_to_markdown(assistants_table)
|
1232
|
+
else:
|
1233
|
+
rich.print(assistants_table)
|
1007
1234
|
|
1008
1235
|
if verbose:
|
1009
|
-
rich.print_json(data=
|
1236
|
+
rich.print_json(data=output_dictionary)
|
1010
1237
|
|
1011
1238
|
for error in parse_errors:
|
1012
1239
|
for l in error:
|
1013
1240
|
logger.error(l)
|
1241
|
+
|
1242
|
+
if verbose or format:
|
1243
|
+
return output_dictionary
|
1244
|
+
|
1014
1245
|
|
1015
1246
|
def remove_agent(self, name: str, kind: AgentKind):
|
1016
1247
|
try:
|