alita-sdk 0.3.452__py3-none-any.whl → 0.3.454__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.
@@ -476,6 +476,10 @@ def create_graph(
476
476
  tool_name = f"{clean_string(toolkit_name)}{TOOLKIT_SPLITTER}{tool_name}"
477
477
  logger.info(f"Node: {node_id} : {node_type} - {tool_name}")
478
478
  if node_type in ['function', 'toolkit', 'mcp', 'tool', 'loop', 'loop_from_tool', 'indexer', 'subgraph', 'pipeline', 'agent']:
479
+ if node_type == 'mcp' and tool_name not in [tool.name for tool in tools]:
480
+ # MCP is not connected and node cannot be added
481
+ raise ToolException(f"MCP tool '{tool_name}' not found in the provided tools. "
482
+ f"Make sure it is connected properly. Available tools: {[tool.name for tool in tools]}")
479
483
  for tool in tools:
480
484
  if tool.name == tool_name:
481
485
  if node_type in ['function', 'toolkit', 'mcp']:
@@ -814,35 +818,63 @@ class LangGraphAgentRunnable(CompiledStateGraph):
814
818
  input['messages'] = [convert_dict_to_message(msg) for msg in chat_history]
815
819
 
816
820
  # handler for LLM node: if no input (Chat perspective), then take last human message
821
+ # Track if input came from messages to handle content extraction properly
822
+ input_from_messages = False
817
823
  if not input.get('input'):
818
824
  if input.get('messages'):
819
- input['input'] = [next((msg for msg in reversed(input['messages']) if isinstance(msg, HumanMessage)),
820
- None)]
825
+ input['input'] = next((msg for msg in reversed(input['messages']) if isinstance(msg, HumanMessage)),
826
+ None)
827
+ if input['input'] is not None:
828
+ input_from_messages = True
821
829
 
822
830
  # Append current input to existing messages instead of overwriting
823
831
  if input.get('input'):
824
832
  if isinstance(input['input'], str):
825
833
  current_message = input['input']
826
834
  else:
835
+ # input can be a list of messages or a single message object
827
836
  current_message = input.get('input')[-1]
828
837
 
829
838
  # TODO: add handler after we add 2+ inputs (filterByType, etc.)
830
839
  if isinstance(current_message, HumanMessage):
831
840
  current_content = current_message.content
832
841
  if isinstance(current_content, list):
833
- text_contents = [
834
- item['text'] if isinstance(item, dict) and item.get('type') == 'text'
835
- else item if isinstance(item, str)
836
- else None
837
- for item in current_content
838
- ]
839
- text_contents = [text for text in text_contents if text is not None]
840
- input['input'] = ". ".join(text_contents)
842
+ # Extract text parts and keep non-text parts (images, etc.)
843
+ text_contents = []
844
+ non_text_parts = []
845
+
846
+ for item in current_content:
847
+ if isinstance(item, dict) and item.get('type') == 'text':
848
+ text_contents.append(item['text'])
849
+ elif isinstance(item, str):
850
+ text_contents.append(item)
851
+ else:
852
+ # Keep image_url and other non-text content
853
+ non_text_parts.append(item)
854
+
855
+ # Set input to the joined text
856
+ input['input'] = ". ".join(text_contents) if text_contents else ""
857
+
858
+ # If this message came from input['messages'], update or remove it
859
+ if input_from_messages:
860
+ if non_text_parts:
861
+ # Keep the message but only with non-text content (images, etc.)
862
+ current_message.content = non_text_parts
863
+ else:
864
+ # All content was text, remove this message from the list
865
+ input['messages'] = [msg for msg in input['messages'] if msg is not current_message]
866
+
841
867
  elif isinstance(current_content, str):
842
868
  # on regenerate case
843
869
  input['input'] = current_content
870
+ # If from messages and all content is text, remove the message
871
+ if input_from_messages:
872
+ input['messages'] = [msg for msg in input['messages'] if msg is not current_message]
844
873
  else:
845
874
  input['input'] = str(current_content)
875
+ # If from messages, remove since we extracted the content
876
+ if input_from_messages:
877
+ input['messages'] = [msg for msg in input['messages'] if msg is not current_message]
846
878
  elif isinstance(current_message, str):
847
879
  input['input'] = current_message
848
880
  else:
@@ -852,9 +884,18 @@ class LangGraphAgentRunnable(CompiledStateGraph):
852
884
  input['messages'] = [convert_dict_to_message(msg) for msg in input['messages']]
853
885
  # Append to existing messages
854
886
  # input['messages'].append(current_message)
855
- else:
856
- # No existing messages, create new list
857
- input['messages'] = [current_message]
887
+ # else:
888
+ # NOTE: Commented out to prevent duplicates with input['input']
889
+ # input['messages'] = [current_message]
890
+
891
+ # Validate that input is not empty after all processing
892
+ if not input.get('input'):
893
+ raise RuntimeError(
894
+ "Empty input after processing. Cannot send empty string to LLM. "
895
+ "This likely means the message contained only non-text content "
896
+ "with no accompanying text."
897
+ )
898
+
858
899
  logging.info(f"Input: {thread_id} - {input}")
859
900
  if self.checkpointer and self.checkpointer.get_tuple(config):
860
901
  self.update_state(config, input)
@@ -110,6 +110,7 @@ def get_tools(tools_list: list, alita_client, llm, memory_store: BaseStore = Non
110
110
  toolkit_name=tool.get('toolkit_name', ''),
111
111
  **tool['settings']).get_tools())
112
112
  elif tool['type'] == 'mcp':
113
+ # remote mcp tool initialization with token injection
113
114
  settings = dict(tool['settings'])
114
115
  url = settings.get('url')
115
116
  headers = settings.get('headers')
@@ -120,7 +120,8 @@ class FunctionTool(BaseTool):
120
120
  messages_dict = {
121
121
  "messages": [{
122
122
  "role": "assistant",
123
- "content": dumps(tool_result) if not isinstance(tool_result, ToolException)
123
+ "content": dumps(tool_result)
124
+ if not isinstance(tool_result, ToolException) and not isinstance(tool_result, str)
124
125
  else str(tool_result)
125
126
  }]
126
127
  }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: alita_sdk
3
- Version: 0.3.452
3
+ Version: 0.3.454
4
4
  Summary: SDK for building langchain agents using resources from Alita
5
5
  Author-email: Artem Rozumenko <artyom.rozumenko@gmail.com>, Mikalai Biazruchka <mikalai_biazruchka@epam.com>, Roman Mitusov <roman_mitusov@epam.com>, Ivan Krakhmaliuk <lifedj27@gmail.com>, Artem Dubrovskiy <ad13box@gmail.com>
6
6
  License-Expression: Apache-2.0
@@ -47,7 +47,7 @@ alita_sdk/runtime/langchain/assistant.py,sha256=t93SNBcdki59gvW_Osl68E-x0ohcO2z3
47
47
  alita_sdk/runtime/langchain/chat_message_template.py,sha256=kPz8W2BG6IMyITFDA5oeb5BxVRkHEVZhuiGl4MBZKdc,2176
48
48
  alita_sdk/runtime/langchain/constants.py,sha256=oiEHg1h_IYUA5NE8O6nEF24hpxahi9BTvJWrkXjbVcU,3405
49
49
  alita_sdk/runtime/langchain/indexer.py,sha256=0ENHy5EOhThnAiYFc7QAsaTNp9rr8hDV_hTK8ahbatk,37592
50
- alita_sdk/runtime/langchain/langraph_agent.py,sha256=YzL8hzXhrI8LUz_Ct6lj4EKLr27fGI5fzLOkQh_rph8,51905
50
+ alita_sdk/runtime/langchain/langraph_agent.py,sha256=Pp37H-alI63MLsxFO-y_WAF4QT4Hyv4c3mIXD-zD_-w,54392
51
51
  alita_sdk/runtime/langchain/mixedAgentParser.py,sha256=M256lvtsL3YtYflBCEp-rWKrKtcY1dJIyRGVv7KW9ME,2611
52
52
  alita_sdk/runtime/langchain/mixedAgentRenderes.py,sha256=asBtKqm88QhZRILditjYICwFVKF5KfO38hu2O-WrSWE,5964
53
53
  alita_sdk/runtime/langchain/store_manager.py,sha256=i8Fl11IXJhrBXq1F1ukEVln57B1IBe-tqSUvfUmBV4A,2218
@@ -106,7 +106,7 @@ alita_sdk/runtime/toolkits/datasource.py,sha256=qk78OdPoReYPCWwahfkKLbKc4pfsu-06
106
106
  alita_sdk/runtime/toolkits/mcp.py,sha256=wa-47obeWm8WrIiaUw5BR40dsR5sLdQKZHzG7MCRnRM,37105
107
107
  alita_sdk/runtime/toolkits/prompt.py,sha256=WIpTkkVYWqIqOWR_LlSWz3ug8uO9tm5jJ7aZYdiGRn0,1192
108
108
  alita_sdk/runtime/toolkits/subgraph.py,sha256=wwUK8JjPXkGzyVZ3tAukmvST6eGbqx_U11rpnmbrvtg,2105
109
- alita_sdk/runtime/toolkits/tools.py,sha256=74R0SadMiUJFUe3U5_PJcxzw5m1KMMBiVfVeiowZK6I,13434
109
+ alita_sdk/runtime/toolkits/tools.py,sha256=sSI4NTCp4-h-NeWaEDAiUQzvRv8gi_I6Xf5OCK2DorE,13504
110
110
  alita_sdk/runtime/toolkits/vectorstore.py,sha256=BGppQADa1ZiLO17fC0uCACTTEvPHlodEDYEzUcBRbAA,2901
111
111
  alita_sdk/runtime/tools/__init__.py,sha256=Fx7iHqkzA90-KfjdcUUzMUI_7kDarjuTsSpSzOW2pN0,568
112
112
  alita_sdk/runtime/tools/agent.py,sha256=m98QxOHwnCRTT9j18Olbb5UPS8-ZGeQaGiUyZJSyFck,3162
@@ -114,7 +114,7 @@ alita_sdk/runtime/tools/application.py,sha256=RCGe-mRfj8372gTFkEX2xBvcYhw7IKdU1t
114
114
  alita_sdk/runtime/tools/artifact.py,sha256=u3szFwZqguHrPZ3tZJ7S_TiZl7cxlT3oHYd6zbdpRDE,13842
115
115
  alita_sdk/runtime/tools/datasource.py,sha256=pvbaSfI-ThQQnjHG-QhYNSTYRnZB0rYtZFpjCfpzxYI,2443
116
116
  alita_sdk/runtime/tools/echo.py,sha256=spw9eCweXzixJqHnZofHE1yWiSUa04L4VKycf3KCEaM,486
117
- alita_sdk/runtime/tools/function.py,sha256=VOgcCjsDfyH2kBbX4k3DtwpsW7aX0JETahC26dwYsuA,6540
117
+ alita_sdk/runtime/tools/function.py,sha256=8KTMwut7BnruaVhgO2zFn9YvCU5bT7REQdpPV-SbHh8,6605
118
118
  alita_sdk/runtime/tools/graph.py,sha256=7jImBBSEdP5Mjnn2keOiyUwdGDFhEXLUrgUiugO3mgA,3503
119
119
  alita_sdk/runtime/tools/image_generation.py,sha256=Kls9D_ke_SK7xmVr7I9SlQcAEBJc86gf66haN0qIj9k,7469
120
120
  alita_sdk/runtime/tools/indexer_tool.py,sha256=whSLPevB4WD6dhh2JDXEivDmTvbjiMV1MrPl9cz5eLA,4375
@@ -361,8 +361,8 @@ alita_sdk/tools/zephyr_scale/api_wrapper.py,sha256=kT0TbmMvuKhDUZc0i7KO18O38JM9S
361
361
  alita_sdk/tools/zephyr_squad/__init__.py,sha256=0ne8XLJEQSLOWfzd2HdnqOYmQlUliKHbBED5kW_Vias,2895
362
362
  alita_sdk/tools/zephyr_squad/api_wrapper.py,sha256=kmw_xol8YIYFplBLWTqP_VKPRhL_1ItDD0_vXTe_UuI,14906
363
363
  alita_sdk/tools/zephyr_squad/zephyr_squad_cloud_client.py,sha256=R371waHsms4sllHCbijKYs90C-9Yu0sSR3N4SUfQOgU,5066
364
- alita_sdk-0.3.452.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
365
- alita_sdk-0.3.452.dist-info/METADATA,sha256=PSg0IHeE1PKWRfGipZFSBkugH5dg3eXnyOpcYTghQOc,19101
366
- alita_sdk-0.3.452.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
367
- alita_sdk-0.3.452.dist-info/top_level.txt,sha256=0vJYy5p_jK6AwVb1aqXr7Kgqgk3WDtQ6t5C-XI9zkmg,10
368
- alita_sdk-0.3.452.dist-info/RECORD,,
364
+ alita_sdk-0.3.454.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
365
+ alita_sdk-0.3.454.dist-info/METADATA,sha256=xjLmYvQTl4oMUTQBsZ0Qn8VnqbrnU6iI4Kha2mERLyQ,19101
366
+ alita_sdk-0.3.454.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
367
+ alita_sdk-0.3.454.dist-info/top_level.txt,sha256=0vJYy5p_jK6AwVb1aqXr7Kgqgk3WDtQ6t5C-XI9zkmg,10
368
+ alita_sdk-0.3.454.dist-info/RECORD,,