alita-sdk 0.3.459__py3-none-any.whl → 0.3.461__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.

Potentially problematic release.


This version of alita-sdk might be problematic. Click here for more details.

@@ -565,7 +565,7 @@ class AlitaClient:
565
565
  monitoring_meta = tasknode_task.meta.get("monitoring", {})
566
566
  return monitoring_meta["user_id"]
567
567
  except Exception as e:
568
- logger.warning(f"Error: Could not determine user ID for MCP tool: {e}")
568
+ logger.debug(f"Error: Could not determine user ID for MCP tool: {e}")
569
569
  return None
570
570
 
571
571
  def predict_agent(self, llm: ChatOpenAI, instructions: str = "You are a helpful assistant.",
@@ -890,7 +890,7 @@ class LangGraphAgentRunnable(CompiledStateGraph):
890
890
  # input['messages'] = [current_message]
891
891
 
892
892
  # Validate that input is not empty after all processing
893
- if not input.get('input'):
893
+ if not input.get('input') and not config.get("configurable", {}).get("checkpoint_id"):
894
894
  raise RuntimeError(
895
895
  "Empty input after processing. Cannot send empty string to LLM. "
896
896
  "This likely means the message contained only non-text content "
@@ -16,6 +16,18 @@ from ..langchain.utils import propagate_the_input_mapping
16
16
  logger = logging.getLogger(__name__)
17
17
 
18
18
 
19
+ def replace_escaped_newlines(data):
20
+ """
21
+ Replace \\n with \n in all string values recursively.
22
+ Required for sanitization of state variables in code node
23
+ """
24
+ if isinstance(data, dict):
25
+ return {key: replace_escaped_newlines(value) for key, value in data.items()}
26
+ elif isinstance(data, str):
27
+ return data.replace('\\n', '\n')
28
+ else:
29
+ return data
30
+
19
31
  class FunctionTool(BaseTool):
20
32
  name: str = 'FunctionalTool'
21
33
  description: str = 'This is direct call node for tools'
@@ -30,12 +42,13 @@ class FunctionTool(BaseTool):
30
42
  def _prepare_pyodide_input(self, state: Union[str, dict, ToolCall]) -> str:
31
43
  """Prepare input for PyodideSandboxTool by injecting state into the code block."""
32
44
  # add state into the code block here since it might be changed during the execution of the code
33
- state_copy = deepcopy(state)
45
+ state_copy = replace_escaped_newlines(deepcopy(state))
34
46
 
35
47
  del state_copy['messages'] # remove messages to avoid issues with pickling without langchain-core
36
48
  # inject state into the code block as alita_state variable
37
49
  state_json = json.dumps(state_copy, ensure_ascii=False)
38
- pyodide_predata = f'#state dict\nimport json\nalita_state = {repr(state_json)}\n'
50
+ pyodide_predata = f'#state dict\nimport json\nalita_state = json.loads({json.dumps(state_json)})\n'
51
+
39
52
  return pyodide_predata
40
53
 
41
54
  def _handle_pyodide_output(self, tool_result: Any) -> dict:
@@ -1,3 +1,4 @@
1
+ import asyncio
1
2
  import logging
2
3
  from traceback import format_exc
3
4
  from typing import Any, Optional, List, Union
@@ -132,7 +133,9 @@ class LLMNode(BaseTool):
132
133
  struct_model = create_pydantic_model(f"LLMOutput", struct_params)
133
134
  completion = llm_client.invoke(messages, config=config)
134
135
  if hasattr(completion, 'tool_calls') and completion.tool_calls:
135
- new_messages, _ = self.__perform_tool_calling(completion, messages, llm_client, config)
136
+ new_messages, _ = self._run_async_in_sync_context(
137
+ self.__perform_tool_calling(completion, messages, llm_client, config)
138
+ )
136
139
  llm = self.__get_struct_output_model(llm_client, struct_model)
137
140
  completion = llm.invoke(new_messages, config=config)
138
141
  result = completion.model_dump()
@@ -155,7 +158,9 @@ class LLMNode(BaseTool):
155
158
  # Handle both tool-calling and regular responses
156
159
  if hasattr(completion, 'tool_calls') and completion.tool_calls:
157
160
  # Handle iterative tool-calling and execution
158
- new_messages, current_completion = self.__perform_tool_calling(completion, messages, llm_client, config)
161
+ new_messages, current_completion = self._run_async_in_sync_context(
162
+ self.__perform_tool_calling(completion, messages, llm_client, config)
163
+ )
159
164
 
160
165
  output_msgs = {"messages": new_messages}
161
166
  if self.output_variables:
@@ -190,9 +195,53 @@ class LLMNode(BaseTool):
190
195
  def _run(self, *args, **kwargs):
191
196
  # Legacy support for old interface
192
197
  return self.invoke(kwargs, **kwargs)
198
+
199
+ def _run_async_in_sync_context(self, coro):
200
+ """Run async coroutine from sync context.
201
+
202
+ For MCP tools with persistent sessions, we reuse the same event loop
203
+ that was used to create the MCP client and sessions (set by CLI).
204
+ """
205
+ try:
206
+ loop = asyncio.get_running_loop()
207
+ # Already in async context - run in thread with new loop
208
+ import threading
209
+
210
+ result_container = []
211
+
212
+ def run_in_thread():
213
+ new_loop = asyncio.new_event_loop()
214
+ asyncio.set_event_loop(new_loop)
215
+ try:
216
+ result_container.append(new_loop.run_until_complete(coro))
217
+ finally:
218
+ new_loop.close()
219
+
220
+ thread = threading.Thread(target=run_in_thread)
221
+ thread.start()
222
+ thread.join()
223
+ return result_container[0] if result_container else None
224
+
225
+ except RuntimeError:
226
+ # No event loop running - use/create persistent loop
227
+ # This loop is shared with MCP session creation for stateful tools
228
+ if not hasattr(self.__class__, '_persistent_loop') or \
229
+ self.__class__._persistent_loop is None or \
230
+ self.__class__._persistent_loop.is_closed():
231
+ self.__class__._persistent_loop = asyncio.new_event_loop()
232
+ logger.debug("Created persistent event loop for async tools")
233
+
234
+ loop = self.__class__._persistent_loop
235
+ asyncio.set_event_loop(loop)
236
+ return loop.run_until_complete(coro)
237
+
238
+ async def _arun(self, *args, **kwargs):
239
+ # Legacy async support
240
+ return self.invoke(kwargs, **kwargs)
193
241
 
194
- def __perform_tool_calling(self, completion, messages, llm_client, config):
242
+ async def __perform_tool_calling(self, completion, messages, llm_client, config):
195
243
  # Handle iterative tool-calling and execution
244
+ logger.info(f"__perform_tool_calling called with {len(completion.tool_calls) if hasattr(completion, 'tool_calls') else 0} tool calls")
196
245
  new_messages = messages + [completion]
197
246
  iteration = 0
198
247
 
@@ -230,9 +279,16 @@ class LLMNode(BaseTool):
230
279
  if tool_to_execute:
231
280
  try:
232
281
  logger.info(f"Executing tool '{tool_name}' with args: {tool_args}")
233
- # Pass the underlying config to the tool execution invoke method
234
- # since it may be another agent, graph, etc. to see it properly in thinking steps
235
- tool_result = tool_to_execute.invoke(tool_args, config=config)
282
+
283
+ # Try async invoke first (for MCP tools), fallback to sync
284
+ tool_result = None
285
+ try:
286
+ # Try async invocation first
287
+ tool_result = await tool_to_execute.ainvoke(tool_args, config=config)
288
+ except NotImplementedError:
289
+ # Tool doesn't support async, use sync invoke
290
+ logger.debug(f"Tool '{tool_name}' doesn't support async, using sync invoke")
291
+ tool_result = tool_to_execute.invoke(tool_args, config=config)
236
292
 
237
293
  # Create tool message with result - preserve structured content
238
294
  from langchain_core.messages import ToolMessage
@@ -256,7 +312,9 @@ class LLMNode(BaseTool):
256
312
  new_messages.append(tool_message)
257
313
 
258
314
  except Exception as e:
259
- logger.error(f"Error executing tool '{tool_name}': {e}")
315
+ import traceback
316
+ error_details = traceback.format_exc()
317
+ logger.error(f"Error executing tool '{tool_name}': {e}\n{error_details}")
260
318
  # Create error tool message
261
319
  from langchain_core.messages import ToolMessage
262
320
  tool_message = ToolMessage(
@@ -381,9 +381,18 @@ class QtestApiWrapper(BaseToolApiWrapper):
381
381
  field_def = field_definitions[field_name]
382
382
  field_id = field_def['field_id']
383
383
  is_multiple = field_def.get('multiple', False)
384
+ has_allowed_values = bool(field_def.get('values')) # True = dropdown, False = text
384
385
 
385
- if is_multiple:
386
- # Multi-select/user fields: can clear using empty array "[]"
386
+ if not has_allowed_values:
387
+ # TEXT FIELD: can clear with empty string
388
+ props_dict[field_name] = {
389
+ 'field_id': field_id,
390
+ 'field_name': field_name,
391
+ 'field_value': '',
392
+ 'field_value_name': ''
393
+ }
394
+ elif is_multiple:
395
+ # MULTI-SELECT: can clear using empty array "[]"
387
396
  props_dict[field_name] = {
388
397
  'field_id': field_id,
389
398
  'field_name': field_name,
@@ -391,7 +400,7 @@ class QtestApiWrapper(BaseToolApiWrapper):
391
400
  'field_value_name': None
392
401
  }
393
402
  else:
394
- # Single-select fields: QTest API limitation - cannot clear to empty
403
+ # SINGLE-SELECT: QTest API limitation - cannot clear to empty
395
404
  # Note: Users CAN clear these fields from UI, but API doesn't expose this capability
396
405
  validation_errors.append(
397
406
  f"⚠️ Cannot clear single-select field '{field_name}' - this is a QTest API limitation "
@@ -516,14 +525,21 @@ class QtestApiWrapper(BaseToolApiWrapper):
516
525
 
517
526
  body = swagger_client.TestCaseWithCustomFieldResource(properties=props)
518
527
 
519
- # Only set fields if they are explicitly provided in the input
520
- # This prevents overwriting existing values with None during partial updates
528
+ # Handle core fields: Name, Description, Precondition
529
+ # These are set if explicitly provided in the input
530
+ # None or empty string means "clear this field" (except Name which is required)
521
531
  if 'Name' in test_case:
522
- body.name = test_case['Name']
532
+ # Name is required - use 'Untitled' as fallback if null/empty
533
+ name_value = test_case['Name']
534
+ body.name = name_value if name_value else 'Untitled'
535
+
523
536
  if 'Precondition' in test_case:
524
- body.precondition = test_case['Precondition']
537
+ # Allow clearing with None or empty string
538
+ body.precondition = test_case['Precondition'] if test_case['Precondition'] is not None else ''
539
+
525
540
  if 'Description' in test_case:
526
- body.description = test_case['Description']
541
+ # Allow clearing with None or empty string
542
+ body.description = test_case['Description'] if test_case['Description'] is not None else ''
527
543
 
528
544
  if parent_id:
529
545
  body.parent_id = parent_id
@@ -773,16 +789,30 @@ class QtestApiWrapper(BaseToolApiWrapper):
773
789
 
774
790
  for field_name, field_info in sorted(field_definitions.items()):
775
791
  required_marker = " (Required)" if field_info.get('required') else ""
776
- output.append(f"\n{field_name}{required_marker}:")
792
+ has_values = bool(field_info.get('values'))
793
+ is_multiple = field_info.get('multiple', False)
794
+
795
+ # Determine field type label
796
+ if not has_values:
797
+ type_label = "Text"
798
+ elif is_multiple:
799
+ type_label = "Multi-select"
800
+ else:
801
+ type_label = "Single-select"
802
+
803
+ output.append(f"\n{field_name} ({type_label}{required_marker}):")
777
804
 
778
- if field_info.get('values'):
805
+ if has_values:
779
806
  for value_name, value_id in sorted(field_info['values'].items()):
780
- output.append(f" - {value_name} (id: {value_id})")
807
+ output.append(f" - {value_name}")
781
808
  else:
782
- output.append(" Type: text")
809
+ output.append(" Free text input. Set to null to clear.")
783
810
 
784
- output.append("\n\nUse these exact value names when creating or updating test cases.")
785
- return ''.join(output)
811
+ output.append("\n\n--- Field Type Guide ---")
812
+ output.append("\nText fields: Use null to clear, provide string value to set.")
813
+ output.append("\nSingle-select: Provide exact value name from the list above. Cannot be cleared via API.")
814
+ output.append("\nMulti-select: Provide value as array [\"val1\", \"val2\"]. Use null to clear.")
815
+ return '\n'.join(output)
786
816
 
787
817
  def get_all_test_cases_fields_for_project(self, force_refresh: bool = False) -> str:
788
818
  """
@@ -844,6 +874,37 @@ class QtestApiWrapper(BaseToolApiWrapper):
844
874
  raise ToolException(
845
875
  f"Unable to create test case in project - {self.qtest_project_id} with the following content:\n{test_case_content}.\n\n Stacktrace was {stacktrace}") from e
846
876
 
877
+ def __format_property_value(self, prop: dict) -> Any:
878
+ """Format property value for display, detecting field type from response structure.
879
+
880
+ Detection rules based on API response patterns:
881
+ - Text field: field_value_name is empty/None
882
+ - Multi-select: field_value_name starts with '[' and ends with ']'
883
+ - Single-select: field_value_name is plain text (no brackets)
884
+
885
+ Args:
886
+ prop: Property dict from API response with field_value and field_value_name
887
+
888
+ Returns:
889
+ Formatted value: list for multi-select, string for others
890
+ """
891
+ field_value = prop.get('field_value') or ''
892
+ field_value_name = prop.get('field_value_name')
893
+
894
+ # Text field: no field_value_name, use field_value directly
895
+ if not field_value_name:
896
+ return field_value
897
+
898
+ # Multi-select: field_value_name is bracketed like '[value1, value2]'
899
+ if isinstance(field_value_name, str) and field_value_name.startswith('[') and field_value_name.endswith(']'):
900
+ inner = field_value_name[1:-1].strip() # Remove brackets
901
+ if inner:
902
+ return [v.strip() for v in inner.split(',')]
903
+ return [] # Empty multi-select
904
+
905
+ # Single-select: plain text value
906
+ return field_value_name
907
+
847
908
  def __parse_data(self, response_to_parse: dict, parsed_data: list, extract_images: bool=False, prompt: str=None):
848
909
  import html
849
910
 
@@ -870,10 +931,9 @@ class QtestApiWrapper(BaseToolApiWrapper):
870
931
  field_name = prop.get('field_name')
871
932
  if not field_name:
872
933
  continue
873
-
874
- # Use field_value_name if available (for dropdowns/users), otherwise field_value
875
- field_value = prop.get('field_value_name') or prop.get('field_value') or ''
876
- parsed_data_row[field_name] = field_value
934
+
935
+ # Format value based on field type (multi-select as array, etc.)
936
+ parsed_data_row[field_name] = self.__format_property_value(prop)
877
937
 
878
938
  parsed_data.append(parsed_data_row)
879
939
 
@@ -1743,11 +1803,14 @@ class QtestApiWrapper(BaseToolApiWrapper):
1743
1803
  field_name = prop.get('field_name')
1744
1804
  if not field_name:
1745
1805
  continue
1746
- # Use field_value_name if available (for dropdowns/users), otherwise field_value
1747
- field_value = prop.get('field_value_name') or prop.get('field_value') or ''
1748
- # Strip HTML from text fields
1806
+
1807
+ # Format value based on field type (multi-select as array, etc.)
1808
+ field_value = self.__format_property_value(prop)
1809
+
1810
+ # Strip HTML from text fields (strings only, not arrays)
1749
1811
  if isinstance(field_value, str) and ('<' in field_value or '&' in field_value):
1750
1812
  field_value = html.unescape(strip_tags(field_value))
1813
+
1751
1814
  result[field_name] = field_value
1752
1815
 
1753
1816
  return result
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: alita_sdk
3
- Version: 0.3.459
3
+ Version: 0.3.461
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
@@ -18,17 +18,13 @@ Requires-Dist: python-dotenv~=1.0.1
18
18
  Requires-Dist: jinja2~=3.1.3
19
19
  Requires-Dist: pillow~=11.1.0
20
20
  Requires-Dist: requests~=2.3
21
- Requires-Dist: pydantic~=2.10.0
21
+ Requires-Dist: pydantic~=2.12.0
22
22
  Requires-Dist: chardet==5.2.0
23
23
  Requires-Dist: fastapi==0.115.9
24
24
  Requires-Dist: httpcore==1.0.7
25
25
  Requires-Dist: urllib3>=2
26
26
  Requires-Dist: certifi==2024.8.30
27
27
  Requires-Dist: aiohttp>=3.9.0
28
- Provides-Extra: cli
29
- Requires-Dist: click>=8.1.0; extra == "cli"
30
- Requires-Dist: rich>=13.0.0; extra == "cli"
31
- Requires-Dist: pyyaml>=6.0; extra == "cli"
32
28
  Provides-Extra: runtime
33
29
  Requires-Dist: streamlit>=1.28.0; extra == "runtime"
34
30
  Requires-Dist: langchain_core<0.4.0,>=0.3.76; extra == "runtime"
@@ -142,13 +138,17 @@ Provides-Extra: all
142
138
  Requires-Dist: alita-sdk[runtime]; extra == "all"
143
139
  Requires-Dist: alita-sdk[tools]; extra == "all"
144
140
  Requires-Dist: alita-sdk[community]; extra == "all"
145
- Requires-Dist: alita-sdk[cli]; extra == "all"
146
141
  Provides-Extra: dev
147
142
  Requires-Dist: pytest; extra == "dev"
148
143
  Requires-Dist: pytest-cov; extra == "dev"
149
144
  Requires-Dist: black; extra == "dev"
150
145
  Requires-Dist: flake8; extra == "dev"
151
146
  Requires-Dist: mypy; extra == "dev"
147
+ Provides-Extra: cli
148
+ Requires-Dist: click>=8.1.0; extra == "cli"
149
+ Requires-Dist: rich>=13.0.0; extra == "cli"
150
+ Requires-Dist: pyyaml>=6.0; extra == "cli"
151
+ Requires-Dist: langchain-mcp-adapters; extra == "cli"
152
152
  Dynamic: license-file
153
153
 
154
154
  Alita SDK
@@ -1,11 +1,19 @@
1
1
  alita_sdk/__init__.py,sha256=fxeNiqiVpIFAJls31Oomifyrtd5gT9iPUTdkWjDOB2Y,656
2
2
  alita_sdk/cli/__init__.py,sha256=HiHHouMh0EHmK1qMVzvz6vfIOu8Pm6XXw0dd_hXZ288,278
3
3
  alita_sdk/cli/__main__.py,sha256=dAhgWWWEOG1ZiwCs6wQoJwnD62cFRnxiyiAoiFqU8K4,420
4
- alita_sdk/cli/agents.py,sha256=uMlKiWs85zExE7_Q6NBbw6frnUVK-Ei2KynIddMHXn0,42419
5
- alita_sdk/cli/cli.py,sha256=k8jwaTKt3At9NfopOcp-BqXitqO0jcei1ACuyoUA9eY,4812
6
- alita_sdk/cli/config.py,sha256=GiWe7K2RHC_PnH1nEUBodgi0d14oPbIdQhYl69Gbx1o,3978
4
+ alita_sdk/cli/agent_executor.py,sha256=VZZjzThaeJBSIeGYcie2nCQsrfGEkLIEXI0nu7zxTxE,5107
5
+ alita_sdk/cli/agent_loader.py,sha256=ujlnKePxGUX7_qCOhoPh7r6y0usyvuBM46McsYCdJtA,7919
6
+ alita_sdk/cli/agent_ui.py,sha256=R-VVEe4wAIXKRf-F64gAOW33EIxMDzhXsAwHQ6bcRgs,5661
7
+ alita_sdk/cli/agents.py,sha256=uWc5On1DS8uIY5SNl18IoMy8cF81JT4aHuqO5vW5vDg,44869
8
+ alita_sdk/cli/callbacks.py,sha256=LSjgGl9Q5-I96PWL3d0A9RlyqDbxDOcCeJ4eV8nlRtQ,19327
9
+ alita_sdk/cli/cli.py,sha256=UWD07iNOEJVSZXCEaF_mm3tb_nT-Ny5N8uQP4DEZiQQ,4917
10
+ alita_sdk/cli/config.py,sha256=iRYsBIA57kKuV4_qAbsbYEZnPilwF3dKnsZH72elcAk,4684
7
11
  alita_sdk/cli/formatting.py,sha256=ip95brhcFcx3Ub7PRLv1aDGniGW13RCGDgc1_8i9ZwM,6566
12
+ alita_sdk/cli/mcp_loader.py,sha256=SfdQl5RWu9Ml-guqOd9busPm1_3NksJZq1UFz9zfn7A,12364
8
13
  alita_sdk/cli/toolkit.py,sha256=IC1zCXiIRUh-swcBC5VhdREIaXGCu5-OfSWyGSUOx0Q,11693
14
+ alita_sdk/cli/toolkit_loader.py,sha256=5KoWkQEHmq32-jKGg-7W57-XjY0oZmMuv4ZHRWgS_4c,1755
15
+ alita_sdk/cli/tools/__init__.py,sha256=QofAD-gr9ydgZbFy0IiNDXVcS2oWhWYBsyV-pQli54o,153
16
+ alita_sdk/cli/tools/filesystem.py,sha256=1XKDRXammYWwmN0K_6ubF8gbBZqcBVIOvrADDY8nhKA,36771
9
17
  alita_sdk/community/__init__.py,sha256=8N7wWwPhoyOq3p8wlV3-pb3l3nJCR8TUrtV9iIPLU88,2523
10
18
  alita_sdk/community/utils.py,sha256=lvuCJaNqVPHOORJV6kIPcXJcdprVW_TJvERtYAEgpjM,249
11
19
  alita_sdk/configurations/__init__.py,sha256=3_MlzyzAi1dog6MFQD_ICOZvaPfXf2UfhSZwlF1knnw,3983
@@ -43,7 +51,7 @@ alita_sdk/configurations/zephyr_essential.py,sha256=TiZedsBlfIDroflipvoqxjJeEWPo
43
51
  alita_sdk/runtime/__init__.py,sha256=4W0UF-nl3QF2bvET5lnah4o24CoTwSoKXhuN0YnwvEE,828
44
52
  alita_sdk/runtime/clients/__init__.py,sha256=BdehU5GBztN1Qi1Wul0cqlU46FxUfMnI6Vq2Zd_oq1M,296
45
53
  alita_sdk/runtime/clients/artifact.py,sha256=b7hVuGRROt6qUcT11uAZqzJqslzmlgW-Y6oGsiwNmjI,4029
46
- alita_sdk/runtime/clients/client.py,sha256=trgvD6vzOqepn29ks0i1ALKigdVxiBinaJiOi-ejNb0,47754
54
+ alita_sdk/runtime/clients/client.py,sha256=fh6mYqPgN6GwhvaMYV9mrcQ7d04gkLaLhRf4xTLEm3M,47752
47
55
  alita_sdk/runtime/clients/datasource.py,sha256=HAZovoQN9jBg0_-lIlGBQzb4FJdczPhkHehAiVG3Wx0,1020
48
56
  alita_sdk/runtime/clients/mcp_discovery.py,sha256=aFJ0wYQ8EAmXa9qLUusHZfQXkNec1wbgkqHdVeSFX-g,11697
49
57
  alita_sdk/runtime/clients/mcp_manager.py,sha256=DRbqiO761l7UgOdv_keHbD2g0oZodtPHejpArXYZIoE,9050
@@ -54,7 +62,7 @@ alita_sdk/runtime/langchain/assistant.py,sha256=t93SNBcdki59gvW_Osl68E-x0ohcO2z3
54
62
  alita_sdk/runtime/langchain/chat_message_template.py,sha256=kPz8W2BG6IMyITFDA5oeb5BxVRkHEVZhuiGl4MBZKdc,2176
55
63
  alita_sdk/runtime/langchain/constants.py,sha256=oiEHg1h_IYUA5NE8O6nEF24hpxahi9BTvJWrkXjbVcU,3405
56
64
  alita_sdk/runtime/langchain/indexer.py,sha256=0ENHy5EOhThnAiYFc7QAsaTNp9rr8hDV_hTK8ahbatk,37592
57
- alita_sdk/runtime/langchain/langraph_agent.py,sha256=tLgZ1Z7iqN_AWkmb9lvmSEpg27ECl9JWm6HS7WtzK1U,54419
65
+ alita_sdk/runtime/langchain/langraph_agent.py,sha256=jBW5ErNWWEFhmVSZvnjXpsa-S0EbHGC1-ZKazkFSq4g,54479
58
66
  alita_sdk/runtime/langchain/mixedAgentParser.py,sha256=M256lvtsL3YtYflBCEp-rWKrKtcY1dJIyRGVv7KW9ME,2611
59
67
  alita_sdk/runtime/langchain/mixedAgentRenderes.py,sha256=asBtKqm88QhZRILditjYICwFVKF5KfO38hu2O-WrSWE,5964
60
68
  alita_sdk/runtime/langchain/store_manager.py,sha256=i8Fl11IXJhrBXq1F1ukEVln57B1IBe-tqSUvfUmBV4A,2218
@@ -121,11 +129,11 @@ alita_sdk/runtime/tools/application.py,sha256=RCGe-mRfj8372gTFkEX2xBvcYhw7IKdU1t
121
129
  alita_sdk/runtime/tools/artifact.py,sha256=u3szFwZqguHrPZ3tZJ7S_TiZl7cxlT3oHYd6zbdpRDE,13842
122
130
  alita_sdk/runtime/tools/datasource.py,sha256=pvbaSfI-ThQQnjHG-QhYNSTYRnZB0rYtZFpjCfpzxYI,2443
123
131
  alita_sdk/runtime/tools/echo.py,sha256=spw9eCweXzixJqHnZofHE1yWiSUa04L4VKycf3KCEaM,486
124
- alita_sdk/runtime/tools/function.py,sha256=0O29IFs0ZupXxqXwGa4Pmm_QdxulUR3ZDGowXDPRgv8,6557
132
+ alita_sdk/runtime/tools/function.py,sha256=1kBVMgLNjoE2yQb5rX8O6MR82rDaylJSrj2Hd-JdkN8,7002
125
133
  alita_sdk/runtime/tools/graph.py,sha256=7jImBBSEdP5Mjnn2keOiyUwdGDFhEXLUrgUiugO3mgA,3503
126
134
  alita_sdk/runtime/tools/image_generation.py,sha256=Kls9D_ke_SK7xmVr7I9SlQcAEBJc86gf66haN0qIj9k,7469
127
135
  alita_sdk/runtime/tools/indexer_tool.py,sha256=whSLPevB4WD6dhh2JDXEivDmTvbjiMV1MrPl9cz5eLA,4375
128
- alita_sdk/runtime/tools/llm.py,sha256=iRG_wU4T01LRsjEMPZe5Uah7LiMqDc-vspwkMuQtltk,16136
136
+ alita_sdk/runtime/tools/llm.py,sha256=MBFQPDY3M_lpJOZ-a6nstVI8cNH0YtBHRhzhxZ9WkP4,18743
129
137
  alita_sdk/runtime/tools/loop.py,sha256=uds0WhZvwMxDVFI6MZHrcmMle637cQfBNg682iLxoJA,8335
130
138
  alita_sdk/runtime/tools/loop_output.py,sha256=U4hO9PCQgWlXwOq6jdmCGbegtAxGAPXObSxZQ3z38uk,8069
131
139
  alita_sdk/runtime/tools/mcp_inspect_tool.py,sha256=38X8euaxDbEGjcfp6ElvExZalpZun6QEr6ZEW4nU5pQ,11496
@@ -318,7 +326,7 @@ alita_sdk/tools/postman/postman_analysis.py,sha256=ckc2BfKEop0xnmLPksVRE_Y94ixuq
318
326
  alita_sdk/tools/pptx/__init__.py,sha256=JP4523kvgcRbKevy9s7KllDbzHV9-ArKMNBuzeT97VI,3378
319
327
  alita_sdk/tools/pptx/pptx_wrapper.py,sha256=yyCYcTlIY976kJ4VfPo4dyxj4yeii9j9TWP6W8ZIpN8,29195
320
328
  alita_sdk/tools/qtest/__init__.py,sha256=IGObKF5m7vCE1Pq4cQ7iAMBckryZ5gowdBbnAey5DFQ,4384
321
- alita_sdk/tools/qtest/api_wrapper.py,sha256=1zhIOePMGYJm0NwzyXkxh39DTTu0vnCEZ1CsQQxVcIA,95498
329
+ alita_sdk/tools/qtest/api_wrapper.py,sha256=PRT_ys6xTfK4WOcd_qnZ05Qv1QZ_VnTIxP1lHL8JC9k,98361
322
330
  alita_sdk/tools/qtest/tool.py,sha256=kKzNPS4fUC76WQQttQ6kdVANViHEvKE8Kf174MQiNYU,562
323
331
  alita_sdk/tools/rally/__init__.py,sha256=VESgUY_m0lQVyoSuuCRyLgURn7vHs-JIMS_0oH4e0LQ,3347
324
332
  alita_sdk/tools/rally/api_wrapper.py,sha256=mouzU6g0KML4UNapdk0k6Q0pU3MpJuWnNo71n9PSEHM,11752
@@ -368,9 +376,9 @@ alita_sdk/tools/zephyr_scale/api_wrapper.py,sha256=kT0TbmMvuKhDUZc0i7KO18O38JM9S
368
376
  alita_sdk/tools/zephyr_squad/__init__.py,sha256=Gl1YAFaMMufTNjIpnuo_c_lbDsQkmproYdZz2ZppgJ4,3007
369
377
  alita_sdk/tools/zephyr_squad/api_wrapper.py,sha256=kmw_xol8YIYFplBLWTqP_VKPRhL_1ItDD0_vXTe_UuI,14906
370
378
  alita_sdk/tools/zephyr_squad/zephyr_squad_cloud_client.py,sha256=R371waHsms4sllHCbijKYs90C-9Yu0sSR3N4SUfQOgU,5066
371
- alita_sdk-0.3.459.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
372
- alita_sdk-0.3.459.dist-info/METADATA,sha256=7Oo76t6BYB0tv0jHbuloCQQrwMpcw7Ga_jqI1KVZeJ0,19298
373
- alita_sdk-0.3.459.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
374
- alita_sdk-0.3.459.dist-info/entry_points.txt,sha256=sSxsIZu9YjVGsgf-5mHC631FeBcT6f2vUjm0A_L9tcU,53
375
- alita_sdk-0.3.459.dist-info/top_level.txt,sha256=0vJYy5p_jK6AwVb1aqXr7Kgqgk3WDtQ6t5C-XI9zkmg,10
376
- alita_sdk-0.3.459.dist-info/RECORD,,
379
+ alita_sdk-0.3.461.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
380
+ alita_sdk-0.3.461.dist-info/METADATA,sha256=F5J4SUWNAFsqIcxCo3FpxqCZpWNGSVoQKV0VhwQmLeA,19306
381
+ alita_sdk-0.3.461.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
382
+ alita_sdk-0.3.461.dist-info/entry_points.txt,sha256=sSxsIZu9YjVGsgf-5mHC631FeBcT6f2vUjm0A_L9tcU,53
383
+ alita_sdk-0.3.461.dist-info/top_level.txt,sha256=0vJYy5p_jK6AwVb1aqXr7Kgqgk3WDtQ6t5C-XI9zkmg,10
384
+ alita_sdk-0.3.461.dist-info/RECORD,,