alita-sdk 0.3.183__py3-none-any.whl → 0.3.185__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.
@@ -432,3 +432,41 @@ class AlitaClient:
432
432
  except Exception as e:
433
433
  logger.warning(f"Error: Could not determine user ID for MCP tool: {e}")
434
434
  return None
435
+
436
+ def predict_agent(self, client: Any, instructions: str = "You are a helpful assistant.",
437
+ tools: Optional[list] = None, chat_history: Optional[List[Any]] = None,
438
+ memory=None, runtime='langchain', variables: Optional[list] = None,
439
+ store: Optional[BaseStore] = None):
440
+ """
441
+ Create a predict-type agent with minimal configuration.
442
+
443
+ Args:
444
+ client: The LLM client to use
445
+ instructions: System instructions for the agent
446
+ tools: Optional list of tools to provide to the agent
447
+ chat_history: Optional chat history
448
+ memory: Optional memory/checkpointer
449
+ runtime: Runtime type (default: 'langchain')
450
+ variables: Optional list of variables for the agent
451
+ store: Optional store for memory
452
+
453
+ Returns:
454
+ Runnable agent ready for execution
455
+ """
456
+ if tools is None:
457
+ tools = []
458
+ if chat_history is None:
459
+ chat_history = []
460
+ if variables is None:
461
+ variables = []
462
+
463
+ # Create a minimal data structure for predict agent
464
+ # All LLM settings are taken from the passed client instance
465
+ agent_data = {
466
+ 'instructions': instructions,
467
+ 'tools': tools, # Tools are handled separately in predict agents
468
+ 'variables': variables
469
+ }
470
+ return LangChainAssistant(self, agent_data, client,
471
+ chat_history, "predict", memory=memory, store=store).runnable()
472
+
@@ -30,14 +30,6 @@ class Assistant:
30
30
  memory: Optional[Any] = None,
31
31
  store: Optional[BaseStore] = None):
32
32
 
33
- self.client = copy(client)
34
- self.client.max_tokens = data['llm_settings']['max_tokens']
35
- self.client.temperature = data['llm_settings']['temperature']
36
- self.client.top_p = data['llm_settings']['top_p']
37
- self.client.top_k = data['llm_settings']['top_k']
38
- self.client.model_name = data['llm_settings']['model_name']
39
- self.client.integration_uid = data['llm_settings']['integration_uid']
40
-
41
33
  self.app_type = app_type
42
34
  self.memory = memory
43
35
  self.store = store
@@ -45,33 +37,53 @@ class Assistant:
45
37
  logger.debug("Data for agent creation: %s", data)
46
38
  logger.info("App type: %s", app_type)
47
39
 
48
- model_type = data["llm_settings"]["indexer_config"]["ai_model"]
49
- model_params = data["llm_settings"]["indexer_config"]["ai_model_params"]
50
- #
51
- target_pkg, target_name = model_type.rsplit(".", 1)
52
- target_cls = getattr(
53
- importlib.import_module(target_pkg),
54
- target_name
55
- )
56
- self.client = target_cls(**model_params)
40
+ # For predict agents, use the client as-is since it's already configured
41
+ if app_type == "predict":
42
+ self.client = client
43
+ else:
44
+ # For other agent types, configure client from llm_settings
45
+ self.client = copy(client)
46
+ self.client.max_tokens = data['llm_settings']['max_tokens']
47
+ self.client.temperature = data['llm_settings']['temperature']
48
+ self.client.top_p = data['llm_settings']['top_p']
49
+ self.client.top_k = data['llm_settings']['top_k']
50
+ self.client.model_name = data['llm_settings']['model_name']
51
+ self.client.integration_uid = data['llm_settings']['integration_uid']
52
+
53
+ model_type = data["llm_settings"]["indexer_config"]["ai_model"]
54
+ model_params = data["llm_settings"]["indexer_config"]["ai_model_params"]
55
+ #
56
+ target_pkg, target_name = model_type.rsplit(".", 1)
57
+ target_cls = getattr(
58
+ importlib.import_module(target_pkg),
59
+ target_name
60
+ )
61
+ self.client = target_cls(**model_params)
57
62
  # validate agents compatibility: non-pipeline agents cannot have pipelines as toolkits
58
- if app_type != "pipeline" and any(tool['agent_type'] == 'pipeline' for tool in data['tools']):
59
- raise ToolException("Non-pipeline agents cannot have pipelines as a toolkits. "
60
- "Review toolkits configuration or use pipeline as master agent.")
63
+ if app_type not in ["pipeline", "predict"]:
64
+ tools_to_check = data.get('tools', [])
65
+ if any(tool['agent_type'] == 'pipeline' for tool in tools_to_check):
66
+ raise ToolException("Non-pipeline agents cannot have pipelines as a toolkits. "
67
+ "Review toolkits configuration or use pipeline as master agent.")
61
68
 
62
- # configure memory store if memory tool is defined
63
- memory_tool = next((tool for tool in data['tools'] if tool['type'] == 'memory'), None)
64
- self._configure_store(memory_tool)
69
+ # configure memory store if memory tool is defined (not needed for predict agents)
70
+ if app_type != "predict":
71
+ memory_tool = next((tool for tool in data.get('tools', []) if tool['type'] == 'memory'), None)
72
+ self._configure_store(memory_tool)
73
+ else:
74
+ # For predict agents, initialize memory store to None since they don't use memory
75
+ self.store = None
65
76
 
66
77
  # Lazy import to avoid circular dependency
67
78
  from ..toolkits.tools import get_tools
79
+
68
80
  self.tools = get_tools(data['tools'], alita_client=alita, llm=self.client, memory_store=self.store)
81
+ if tools:
82
+ self.tools += tools
83
+ # Handle prompt setup
69
84
  if app_type in ["pipeline", "predict", "react"]:
70
85
  self.prompt = data['instructions']
71
- if tools:
72
- self.tools += tools
73
86
  else:
74
- self.tools += tools
75
87
  messages = [SystemMessage(content=data['instructions'])]
76
88
  messages.append(MessagesPlaceholder("chat_history"))
77
89
  if app_type == "react":
@@ -99,9 +99,57 @@ def get_tools(tools_list: list, alita_client, llm, memory_store: BaseStore = Non
99
99
  # Add MCP tools
100
100
  tools += _mcp_tools(tools_list, alita_client)
101
101
 
102
+ # Sanitize tool names to meet OpenAI's function naming requirements
103
+ # tools = _sanitize_tool_names(tools)
104
+
102
105
  return tools
103
106
 
104
107
 
108
+ def _sanitize_tool_names(tools: list) -> list:
109
+ """
110
+ Sanitize tool names to meet OpenAI's function naming requirements.
111
+ OpenAI function names must match pattern ^[a-zA-Z0-9_\\.-]+$
112
+ """
113
+ import re
114
+ from langchain_core.tools import BaseTool
115
+
116
+ def sanitize_name(name):
117
+ """Sanitize a single tool name"""
118
+ # Replace spaces and other invalid characters with underscores
119
+ sanitized = re.sub(r'[^a-zA-Z0-9_.-]', '_', name)
120
+ # Remove multiple consecutive underscores
121
+ sanitized = re.sub(r'_{2,}', '_', sanitized)
122
+ # Remove leading/trailing underscores
123
+ sanitized = sanitized.strip('_')
124
+ return sanitized
125
+
126
+ sanitized_tools = []
127
+ name_mapping = {}
128
+
129
+ for tool in tools:
130
+ if isinstance(tool, BaseTool):
131
+ original_name = tool.name
132
+ sanitized_name = sanitize_name(original_name)
133
+
134
+ # Only update if the name actually changed
135
+ if original_name != sanitized_name:
136
+ logger.info(f"Sanitizing tool name: '{original_name}' -> '{sanitized_name}'")
137
+ # Create a new tool instance with the sanitized name
138
+ # We need to be careful here to preserve all other tool properties
139
+ tool.name = sanitized_name
140
+ name_mapping[original_name] = sanitized_name
141
+
142
+ sanitized_tools.append(tool)
143
+ else:
144
+ # For non-BaseTool objects (like CompiledStateGraph), just pass through
145
+ sanitized_tools.append(tool)
146
+
147
+ if name_mapping:
148
+ logger.info(f"Tool name sanitization complete. Mapped {len(name_mapping)} tool names.")
149
+
150
+ return sanitized_tools
151
+
152
+
105
153
  def _mcp_tools(tools_list, alita):
106
154
  try:
107
155
  all_available_toolkits = alita.get_mcp_toolkits()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: alita_sdk
3
- Version: 0.3.183
3
+ Version: 0.3.185
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 <lifedjik@gmail.com>, Artem Dubrovskiy <ad13box@gmail.com>
6
6
  License-Expression: Apache-2.0
@@ -13,11 +13,11 @@ alita_sdk/community/analysis/jira_analyse/api_wrapper.py,sha256=Ui1GBWizIFGFOi98
13
13
  alita_sdk/runtime/__init__.py,sha256=4W0UF-nl3QF2bvET5lnah4o24CoTwSoKXhuN0YnwvEE,828
14
14
  alita_sdk/runtime/clients/__init__.py,sha256=BdehU5GBztN1Qi1Wul0cqlU46FxUfMnI6Vq2Zd_oq1M,296
15
15
  alita_sdk/runtime/clients/artifact.py,sha256=4N2t5x3GibyXLq3Fvrv2o_VA7Z000yNfc-UN4eGsHZg,2679
16
- alita_sdk/runtime/clients/client.py,sha256=6ezOJ92CSw6b2PVs4uFMQKQdp40uT1awoFEqWAfBH_A,20029
16
+ alita_sdk/runtime/clients/client.py,sha256=hppbxdpliAdF-BucacLSONP1p8qZjQ-xP5rZfnRx3ug,21650
17
17
  alita_sdk/runtime/clients/datasource.py,sha256=HAZovoQN9jBg0_-lIlGBQzb4FJdczPhkHehAiVG3Wx0,1020
18
18
  alita_sdk/runtime/clients/prompt.py,sha256=li1RG9eBwgNK_Qf0qUaZ8QNTmsncFrAL2pv3kbxZRZg,1447
19
19
  alita_sdk/runtime/langchain/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
- alita_sdk/runtime/langchain/assistant.py,sha256=8HbMMPsTFx7ZIP0IVzDsmbreghjVhnIHfjgSy9m7Yjo,12705
20
+ alita_sdk/runtime/langchain/assistant.py,sha256=wvRVnEXmh15QP_sIcex-6zwm4GNBP7z581GVzDfc8hw,13311
21
21
  alita_sdk/runtime/langchain/chat_message_template.py,sha256=kPz8W2BG6IMyITFDA5oeb5BxVRkHEVZhuiGl4MBZKdc,2176
22
22
  alita_sdk/runtime/langchain/constants.py,sha256=eHVJ_beJNTf1WJo4yq7KMK64fxsRvs3lKc34QCXSbpk,3319
23
23
  alita_sdk/runtime/langchain/indexer.py,sha256=0ENHy5EOhThnAiYFc7QAsaTNp9rr8hDV_hTK8ahbatk,37592
@@ -71,7 +71,7 @@ alita_sdk/runtime/toolkits/artifact.py,sha256=7fTr9VpGd2zwCB3EwW4aqWa5jVKRTunqV3
71
71
  alita_sdk/runtime/toolkits/datasource.py,sha256=qk78OdPoReYPCWwahfkKLbKc4pfsu-061oXRryFLP6I,2498
72
72
  alita_sdk/runtime/toolkits/prompt.py,sha256=WIpTkkVYWqIqOWR_LlSWz3ug8uO9tm5jJ7aZYdiGRn0,1192
73
73
  alita_sdk/runtime/toolkits/subgraph.py,sha256=ZYqI4yVLbEPAjCR8dpXbjbL2ipX598Hk3fL6AgaqFD4,1758
74
- alita_sdk/runtime/toolkits/tools.py,sha256=NjGzuP8wxk8SHIZFj6CLFufGIbHYG6dLctxJFkOLxRU,6176
74
+ alita_sdk/runtime/toolkits/tools.py,sha256=ENR0T7833S4AiE6_Tg-xfsYHFanXMjsus_pzj-DDTnE,8004
75
75
  alita_sdk/runtime/toolkits/vectorstore.py,sha256=BGppQADa1ZiLO17fC0uCACTTEvPHlodEDYEzUcBRbAA,2901
76
76
  alita_sdk/runtime/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
77
77
  alita_sdk/runtime/tools/agent.py,sha256=m98QxOHwnCRTT9j18Olbb5UPS8-ZGeQaGiUyZJSyFck,3162
@@ -297,8 +297,8 @@ alita_sdk/tools/zephyr_scale/api_wrapper.py,sha256=UHVQUVqcBc3SZvDfO78HSuBzwAsRw
297
297
  alita_sdk/tools/zephyr_squad/__init__.py,sha256=rq4jOb3lRW2GXvAguk4H1KinO5f-zpygzhBJf-E1Ucw,2773
298
298
  alita_sdk/tools/zephyr_squad/api_wrapper.py,sha256=iOMxyE7vOc_LwFB_nBMiSFXkNtvbptA4i-BrTlo7M0A,5854
299
299
  alita_sdk/tools/zephyr_squad/zephyr_squad_cloud_client.py,sha256=IYUJoMFOMA70knLhLtAnuGoy3OK80RuqeQZ710oyIxE,3631
300
- alita_sdk-0.3.183.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
301
- alita_sdk-0.3.183.dist-info/METADATA,sha256=RGW4Mjq7G8LuOV4Aj7Uvi3xzcY68h6_HT7B84QZW9pA,18804
302
- alita_sdk-0.3.183.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
303
- alita_sdk-0.3.183.dist-info/top_level.txt,sha256=0vJYy5p_jK6AwVb1aqXr7Kgqgk3WDtQ6t5C-XI9zkmg,10
304
- alita_sdk-0.3.183.dist-info/RECORD,,
300
+ alita_sdk-0.3.185.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
301
+ alita_sdk-0.3.185.dist-info/METADATA,sha256=ykeiaikEmMf9_bKO-qDkpfN1-7HsGN491BMp165QjSg,18804
302
+ alita_sdk-0.3.185.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
303
+ alita_sdk-0.3.185.dist-info/top_level.txt,sha256=0vJYy5p_jK6AwVb1aqXr7Kgqgk3WDtQ6t5C-XI9zkmg,10
304
+ alita_sdk-0.3.185.dist-info/RECORD,,