alita-sdk 0.3.127__py3-none-any.whl → 0.3.129__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.
@@ -348,7 +348,7 @@ class AlitaClient:
348
348
  response_data = response.json()
349
349
  response_messages = []
350
350
  for message in response_data['messages']:
351
- if message.get('type') == 'user':
351
+ if message.get('role') == 'user':
352
352
  response_messages.append(HumanMessage(content=message['content']))
353
353
  else:
354
354
  response_messages.append(AIMessage(content=message['content']))
@@ -387,7 +387,7 @@ def create_graph(
387
387
  if toolkit_name:
388
388
  tool_name = f"{clean_string(toolkit_name)}{TOOLKIT_SPLITTER}{tool_name}"
389
389
  logger.info(f"Node: {node_id} : {node_type} - {tool_name}")
390
- if node_type in ['function', 'tool', 'loop', 'loop_from_tool', 'indexer', 'subgraph']:
390
+ if node_type in ['function', 'tool', 'loop', 'loop_from_tool', 'indexer', 'subgraph', 'pipeline', 'agent']:
391
391
  for tool in tools:
392
392
  if tool.name == tool_name:
393
393
  if node_type == 'function':
@@ -397,14 +397,31 @@ def create_graph(
397
397
  input_mapping=node.get('input_mapping',
398
398
  {'messages': {'type': 'variable', 'value': 'messages'}}),
399
399
  input_variables=node.get('input', ['messages'])))
400
- elif node_type == 'subgraph':
400
+ elif node_type == 'agent':
401
+ input_params = node.get('input', ['messages'])
402
+ input_mapping = {'task': {'type': 'fstring', 'value': f"{node.get('task', '')}"},
403
+ 'chat_history': {'type': 'fixed', 'value': []}}
404
+ # Add 'chat_history' to input_mapping only if 'messages' is in input_params
405
+ if 'messages' in input_params:
406
+ input_mapping['chat_history'] = {'type': 'variable', 'value': 'messages'}
407
+ lg_builder.add_node(node_id, FunctionTool(
408
+ client=client, tool=tool,
409
+ name=node['id'], return_type='dict',
410
+ output_variables=node.get('output', []),
411
+ input_variables=input_params,
412
+ input_mapping= input_mapping
413
+ ))
414
+ elif node_type == 'subgraph' or node_type == 'pipeline':
401
415
  # assign parent memory/store
402
416
  # tool.checkpointer = memory
403
417
  # tool.store = store
404
418
  # wrap with mappings
419
+ pipeline_name = node.get('tool', None)
420
+ if not pipeline_name:
421
+ raise ValueError("Subgraph must have a 'tool' node: add required tool to the subgraph node")
405
422
  node_fn = SubgraphRunnable(
406
423
  inner=tool,
407
- name=node['id'],
424
+ name=pipeline_name,
408
425
  input_mapping=node.get('input_mapping', {}),
409
426
  output_mapping=node.get('output_mapping', {}),
410
427
  )
@@ -419,6 +436,15 @@ def create_graph(
419
436
  structured_output=node.get('structured_output', False),
420
437
  task=node.get('task')
421
438
  ))
439
+ # TODO: decide on struct output for agent nodes
440
+ # elif node_type == 'agent':
441
+ # lg_builder.add_node(node_id, AgentNode(
442
+ # client=client, tool=tool,
443
+ # name=node['id'], return_type='dict',
444
+ # output_variables=node.get('output', []),
445
+ # input_variables=node.get('input', ['messages']),
446
+ # task=node.get('task')
447
+ # ))
422
448
  elif node_type == 'loop':
423
449
  lg_builder.add_node(node_id, LoopNode(
424
450
  client=client, tool=tool,
alita_sdk/llms/alita.py CHANGED
@@ -150,14 +150,33 @@ class AlitaChatModel(BaseChatModel):
150
150
  logger.debug(f"message before getting to ChatGenerationChunk: {message}")
151
151
  yield ChatGenerationChunk(message=message, generation_info=generation_info)
152
152
 
153
- async def _astrem(
153
+ async def _astream(
154
154
  self,
155
155
  messages: List[BaseMessage],
156
156
  stop: Optional[List[str]] = None,
157
- run_manager: Optional[CallbackManagerForLLMRun] = None,
157
+ run_manager: Optional[AsyncCallbackManagerForLLMRun] = None,
158
158
  **kwargs: Any,
159
159
  ) -> AsyncIterator[ChatGenerationChunk]:
160
- raise NotImplementedError("Streaming is not implemented")
160
+ iterator = await run_in_executor(
161
+ None,
162
+ self._stream,
163
+ messages,
164
+ stop,
165
+ run_manager.get_sync() if run_manager else None,
166
+ **kwargs,
167
+ )
168
+ done = object()
169
+ while True:
170
+ item: ChatGenerationChunk | object = await run_in_executor(
171
+ None,
172
+ next,
173
+ iterator,
174
+ done,
175
+ )
176
+ if item is done:
177
+ break
178
+ if isinstance(item, ChatGenerationChunk):
179
+ yield item
161
180
 
162
181
  def _create_chat_result(self, response: list[BaseMessage]) -> ChatResult:
163
182
  token_usage = 0
@@ -52,7 +52,7 @@ def get_tools(tools_list: list, alita_client, llm) -> list:
52
52
  selected_tools=tool['settings']['selected_tools'],
53
53
  toolkit_name=tool.get('toolkit_name', '') or tool.get('name', '')
54
54
  ).get_tools())
55
- elif tool['type'] == 'application':
55
+ elif tool['type'] == 'application' and tool.get('agent_type', '') != 'pipeline' :
56
56
  tools.extend(ApplicationToolkit.get_toolkit(
57
57
  alita_client,
58
58
  application_id=int(tool['settings']['application_id']),
@@ -60,7 +60,7 @@ def get_tools(tools_list: list, alita_client, llm) -> list:
60
60
  app_api_key=alita_client.auth_token,
61
61
  selected_tools=[]
62
62
  ).get_tools())
63
- elif tool['type'] == 'subgraph':
63
+ elif tool['type'] == 'application' and tool.get('agent_type', '') == 'pipeline':
64
64
  # static get_toolkit returns a list of CompiledStateGraph stubs
65
65
  tools.extend(SubgraphToolkit.get_toolkit(
66
66
  alita_client,
@@ -0,0 +1,74 @@
1
+ import logging
2
+ from json import dumps
3
+ from traceback import format_exc
4
+ from typing import Any, Optional, Union
5
+
6
+ from langchain_core.callbacks import dispatch_custom_event
7
+ from langchain_core.messages import ToolCall
8
+ from langchain_core.runnables import RunnableConfig
9
+ from langchain_core.tools import BaseTool
10
+ from langchain_core.utils.function_calling import convert_to_openai_tool
11
+ from pydantic import ValidationError
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+
16
+ class AgentNode(BaseTool):
17
+ name: str = 'AgentNode'
18
+ description: str = 'This is agent node for tools'
19
+ client: Any = None
20
+ tool: BaseTool = None
21
+ return_type: str = "str"
22
+ input_variables: Optional[list[str]] = None
23
+ output_variables: Optional[list[str]] = None
24
+ structured_output: Optional[bool] = False
25
+ task: Optional[str] = None
26
+
27
+ def invoke(
28
+ self,
29
+ state: Union[str, dict, ToolCall],
30
+ config: Optional[RunnableConfig] = None,
31
+ **kwargs: Any,
32
+ ) -> Any:
33
+ params = convert_to_openai_tool(self.tool).get(
34
+ 'function', {'parameters': {}}).get(
35
+ 'parameters', {'properties': {}}).get('properties', {})
36
+ input_ = []
37
+ last_message = {}
38
+ logger.debug(f"AgentNode input: {self.input_variables}")
39
+ logger.debug(f"Output variables: {self.output_variables}")
40
+ for var in self.input_variables:
41
+ if var != 'messages':
42
+ last_message[var] = state[var]
43
+ if self.task:
44
+ task = self.task.format(**last_message, last_message=dumps(last_message))
45
+ else:
46
+ task = 'Input from user: {last_message}'.format(last_message=dumps(last_message))
47
+ try:
48
+ agent_input = {'task': task, 'chat_history': state.get('messages', [])[:] if 'messages' in self.input_variables else None}
49
+ tool_result = self.tool.invoke(agent_input, config=config, kwargs=kwargs)
50
+ dispatch_custom_event(
51
+ "on_tool_node", {
52
+ "input_variables": self.input_variables,
53
+ "tool_result": tool_result,
54
+ "state": state,
55
+ }, config=config
56
+ )
57
+ message_result = tool_result
58
+ if isinstance(tool_result, dict) or isinstance(tool_result, list):
59
+ message_result = dumps(tool_result)
60
+ logger.info(f"AgentNode response: {tool_result}")
61
+ if not self.output_variables:
62
+ return {"messages": [{"role": "assistant", "content": message_result}]}
63
+ else:
64
+ return {self.output_variables[0]: tool_result,
65
+ "messages": [{"role": "assistant", "content": message_result}]}
66
+ except ValidationError:
67
+ logger.error(f"ValidationError: {format_exc()}")
68
+ return {
69
+ "messages": [{"role": "assistant", "content": f"""Tool input to the {self.tool.name} with value {agent_input} raised ValidationError.
70
+ \n\nTool schema is {dumps(params)} \n\nand the input to LLM was
71
+ {input_[-1].content}"""}]}
72
+
73
+ def _run(self, *args, **kwargs):
74
+ return self.invoke(**kwargs)
@@ -39,8 +39,8 @@ Tool arguments schema:
39
39
  """
40
40
  unstructured_output: str = """Expected output is JSON that to be used as a KWARGS for the tool call like {{"key": "value"}}
41
41
  in case your key is "chat_history" value should be a list of messages with roles like {{"chat_history": [{{"role": "user", "content": "input"}}, {{"role": "assistant", "content": "output"}}]}}.
42
- Tool won't have access to convesation so all keys and values need to be actual and independant.
43
- Anwer must be JSON only extractable by JSON.LOADS."""
42
+ Tool won't have access to conversation so all keys and values need to be actual and independent.
43
+ Answer must be JSON only extractable by JSON.LOADS."""
44
44
 
45
45
  def invoke(
46
46
  self,
alita_sdk/tools/tool.py CHANGED
@@ -37,8 +37,8 @@ Tool arguments schema:
37
37
  """
38
38
  unstructured_output: str = """Expected output is JSON that to be used as a KWARGS for the tool call like {{"key": "value"}}
39
39
  in case your key is "chat_history" value should be a list of messages with roles like {{"chat_history": [{{"role": "user", "content": "input"}}, {{"role": "assistant", "content": "output"}}]}}.
40
- Tool won't have access to convesation so all keys and values need to be actual and independant.
41
- Anwer must be JSON only extractable by JSON.LOADS."""
40
+ Tool won't have access to conversation so all keys and values need to be actual and independent.
41
+ Answer must be JSON only extractable by JSON.LOADS."""
42
42
 
43
43
  def invoke(
44
44
  self,
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: alita_sdk
3
- Version: 0.3.127
4
- Summary: SDK for building langchain agents using resouces from Alita
3
+ Version: 0.3.129
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 <lifedjik@gmail.com>
6
6
  Project-URL: Homepage, https://projectalita.ai
7
7
  Project-URL: Issues, https://github.com/ProjectAlita/alita-sdk/issues
@@ -4,7 +4,7 @@ alita_sdk/agents/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,
4
4
  alita_sdk/agents/llamaAgentParser.py,sha256=N_Nw6WJ8xrNX3fr_JFwjUIg_Urai9lLU3poMgZz0Cyk,1701
5
5
  alita_sdk/clients/__init__.py,sha256=5O_7WsZmvg5z5uZf_Jkx-f8j5C6yKIuSwQR6AQ-TM84,31
6
6
  alita_sdk/clients/artifact.py,sha256=W6oLlthtsUHfUWjhihaDdhLZdRVqj1D2j7oHHELxJfs,2639
7
- alita_sdk/clients/client.py,sha256=aBVoT9rX5D9vF2iGPywmjAi2CPM0m43NnHiKmKlTmPA,18475
7
+ alita_sdk/clients/client.py,sha256=egrBkmuNh79WTaCLO2sBiTHA1YBT6R4pif-nWZbnSNw,18475
8
8
  alita_sdk/clients/datasource.py,sha256=HAZovoQN9jBg0_-lIlGBQzb4FJdczPhkHehAiVG3Wx0,1020
9
9
  alita_sdk/clients/prompt.py,sha256=li1RG9eBwgNK_Qf0qUaZ8QNTmsncFrAL2pv3kbxZRZg,1447
10
10
  alita_sdk/community/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -19,7 +19,7 @@ alita_sdk/langchain/assistant.py,sha256=J_xhwbNl934BgDKSpAMC9a1u6v03DZQcTYaamCzt
19
19
  alita_sdk/langchain/chat_message_template.py,sha256=kPz8W2BG6IMyITFDA5oeb5BxVRkHEVZhuiGl4MBZKdc,2176
20
20
  alita_sdk/langchain/constants.py,sha256=eHVJ_beJNTf1WJo4yq7KMK64fxsRvs3lKc34QCXSbpk,3319
21
21
  alita_sdk/langchain/indexer.py,sha256=0ENHy5EOhThnAiYFc7QAsaTNp9rr8hDV_hTK8ahbatk,37592
22
- alita_sdk/langchain/langraph_agent.py,sha256=PrD_9XEX7_LDOT_SuohW_nhqLMlzc14xmByHPrO0V6E,37951
22
+ alita_sdk/langchain/langraph_agent.py,sha256=mPoyC2fJWf8F29lEZfhjh6_Cx_TQNXqmikBy6zQxqVI,39849
23
23
  alita_sdk/langchain/mixedAgentParser.py,sha256=M256lvtsL3YtYflBCEp-rWKrKtcY1dJIyRGVv7KW9ME,2611
24
24
  alita_sdk/langchain/mixedAgentRenderes.py,sha256=asBtKqm88QhZRILditjYICwFVKF5KfO38hu2O-WrSWE,5964
25
25
  alita_sdk/langchain/utils.py,sha256=Npferkn10dvdksnKzLJLBI5bNGQyVWTBwqp3vQtUqmY,6631
@@ -61,7 +61,7 @@ alita_sdk/langchain/tools/bdd_parser/feature_types.py,sha256=l3AdjSQnNv1CE1NuHi7
61
61
  alita_sdk/langchain/tools/bdd_parser/parser.py,sha256=1H1Nd_OH5Wx8A5YV1zUghBxo613yPptZ7fqNo8Eg48M,17289
62
62
  alita_sdk/llamaindex/assistant.py,sha256=P0gisfQG9NJMJZTmCOL22AN96lrwoajN_29tzrkX0RU,21
63
63
  alita_sdk/llms/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
64
- alita_sdk/llms/alita.py,sha256=yp6d46cxfrWgtu2wxOQqY5eBhiD7PA9j2vnbB2yUMv0,9606
64
+ alita_sdk/llms/alita.py,sha256=oAALCyrTbQ8gygJO7xzZLjOowpUnTbh8R363argRUVs,10119
65
65
  alita_sdk/llms/preloaded.py,sha256=TFdoScswWI5vMkqFwEyQn_yW3mIoebWLxjciz_Ars3w,11222
66
66
  alita_sdk/toolkits/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
67
67
  alita_sdk/toolkits/application.py,sha256=LrxbBV05lkRP3_WtKGBKtMdoQHXVY-_AtFr1cUuHz40,2341
@@ -69,9 +69,10 @@ alita_sdk/toolkits/artifact.py,sha256=7zb17vhJ3CigeTqvzQ4VNBsU5UOCJqAwz7fOJGMYqX
69
69
  alita_sdk/toolkits/datasource.py,sha256=v3FQu8Gmvq7gAGAnFEbA8qofyUhh98rxgIjY6GHBfyI,2494
70
70
  alita_sdk/toolkits/prompt.py,sha256=WIpTkkVYWqIqOWR_LlSWz3ug8uO9tm5jJ7aZYdiGRn0,1192
71
71
  alita_sdk/toolkits/subgraph.py,sha256=ZYqI4yVLbEPAjCR8dpXbjbL2ipX598Hk3fL6AgaqFD4,1758
72
- alita_sdk/toolkits/tools.py,sha256=gk3nvQBdab3QM8v93ff2nrN4ZfcT779yae2RygkTl8s,5834
72
+ alita_sdk/toolkits/tools.py,sha256=eb4UFaSky0N42cTXHiJ9KojaReivcRNr2RM4UABQf8o,5928
73
73
  alita_sdk/toolkits/vectorstore.py,sha256=di08-CRl0KJ9xSZ8_24VVnPZy58iLqHtXW8vuF29P64,2893
74
74
  alita_sdk/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
75
+ alita_sdk/tools/agent.py,sha256=m98QxOHwnCRTT9j18Olbb5UPS8-ZGeQaGiUyZJSyFck,3162
75
76
  alita_sdk/tools/application.py,sha256=UJlYd3Sub10LpAoKkKEpvd4miWyrS-yYE5NKyqx-H4Q,2194
76
77
  alita_sdk/tools/artifact.py,sha256=uTa6K5d-NCDRnuLJVd6vA5TNIPH39onyPIyW5Thz4C0,6160
77
78
  alita_sdk/tools/datasource.py,sha256=pvbaSfI-ThQQnjHG-QhYNSTYRnZB0rYtZFpjCfpzxYI,2443
@@ -80,12 +81,12 @@ alita_sdk/tools/function.py,sha256=wzPS5Y8ScmsXspmn73MQnkCcAghsllAg7BLh61ZNuVw,2
80
81
  alita_sdk/tools/indexer_tool.py,sha256=P9S_omk5TZkizb6UXyxMO87Pzj4UCaye0CuXBgCnhTU,4258
81
82
  alita_sdk/tools/llm.py,sha256=JA0OnSU13CLdkS5NFv6iRk8P7k-B47L-oPjk8xrzk48,3223
82
83
  alita_sdk/tools/loop.py,sha256=uds0WhZvwMxDVFI6MZHrcmMle637cQfBNg682iLxoJA,8335
83
- alita_sdk/tools/loop_output.py,sha256=NoGIGYc42wY3NNcWRijYzRnUVXcCn5cRVd8QmuIpoHU,8068
84
+ alita_sdk/tools/loop_output.py,sha256=U4hO9PCQgWlXwOq6jdmCGbegtAxGAPXObSxZQ3z38uk,8069
84
85
  alita_sdk/tools/mcp_server_tool.py,sha256=xcH9AiqfR2TYrwJ3Ixw-_A7XDodtJCnwmq1SsikXpYk,1930
85
86
  alita_sdk/tools/pgvector_search.py,sha256=NN2BGAnq4SsDHIhUcFZ8d_dbEOM8QwB0UwpsWCYruXU,11692
86
87
  alita_sdk/tools/prompt.py,sha256=nJafb_e5aOM1Rr3qGFCR-SKziU9uCsiP2okIMs9PppM,741
87
88
  alita_sdk/tools/router.py,sha256=wCvZjVkdXK9dMMeEerrgKf5M790RudH68pDortnHSz0,1517
88
- alita_sdk/tools/tool.py,sha256=f2ULDU4PU4PlLgygT_lsInLgNROJeWUNXLe0i0uOcqI,5419
89
+ alita_sdk/tools/tool.py,sha256=nhmJGyIzkNxSSdZk8OkJ8vAsiMZ8tsdTFcX4dXWql5s,5420
89
90
  alita_sdk/tools/vectorstore.py,sha256=F-DoHxPa4UVsKB-FEd-wWa59QGQifKMwcSNcZ5WZOKc,23496
90
91
  alita_sdk/utils/AlitaCallback.py,sha256=cvpDhR4QLVCNQci6CO6TEUrUVDZU9_CRSwzcHGm3SGw,7356
91
92
  alita_sdk/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -93,10 +94,10 @@ alita_sdk/utils/evaluate.py,sha256=iM1P8gzBLHTuSCe85_Ng_h30m52hFuGuhNXJ7kB1tgI,1
93
94
  alita_sdk/utils/logging.py,sha256=hBE3qAzmcLMdamMp2YRXwOOK9P4lmNaNhM76kntVljs,3124
94
95
  alita_sdk/utils/streamlit.py,sha256=zp8owZwHI3HZplhcExJf6R3-APtWx-z6s5jznT2hY_k,29124
95
96
  alita_sdk/utils/utils.py,sha256=dM8whOJAuFJFe19qJ69-FLzrUp6d2G-G6L7d4ss2XqM,346
96
- alita_sdk-0.3.127.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
97
+ alita_sdk-0.3.129.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
97
98
  tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
98
99
  tests/test_jira_analysis.py,sha256=I0cErH5R_dHVyutpXrM1QEo7jfBuKWTmDQvJBPjx18I,3281
99
- alita_sdk-0.3.127.dist-info/METADATA,sha256=Ox_VkvvGHqTNfe_wFqkVXU0etHQmW92EziEoEM5D158,7075
100
- alita_sdk-0.3.127.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
101
- alita_sdk-0.3.127.dist-info/top_level.txt,sha256=SWRhxB7Et3cOy3RkE5hR7OIRnHoo3K8EXzoiNlkfOmc,25
102
- alita_sdk-0.3.127.dist-info/RECORD,,
100
+ alita_sdk-0.3.129.dist-info/METADATA,sha256=HRyKs3QA8Q-vF56MHtzey9Jq7veAPj5a5j93s1Jv5AQ,7076
101
+ alita_sdk-0.3.129.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
102
+ alita_sdk-0.3.129.dist-info/top_level.txt,sha256=SWRhxB7Et3cOy3RkE5hR7OIRnHoo3K8EXzoiNlkfOmc,25
103
+ alita_sdk-0.3.129.dist-info/RECORD,,