agentic-blocks 0.1.10__tar.gz → 0.1.11__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentic-blocks
3
- Version: 0.1.10
3
+ Version: 0.1.11
4
4
  Summary: Simple building blocks for agentic AI systems with MCP client and conversation management
5
5
  Author-email: Magnus Bjelkenhed <bjelkenhed@gmail.com>
6
6
  License: MIT
@@ -14,7 +14,7 @@ agentic_blocks = []
14
14
 
15
15
  [project]
16
16
  name = "agentic-blocks"
17
- version = "0.1.10"
17
+ version = "0.1.11"
18
18
  description = "Simple building blocks for agentic AI systems with MCP client and conversation management"
19
19
  readme = "README.md"
20
20
  requires-python = ">=3.11"
@@ -0,0 +1,176 @@
1
+ """
2
+ Utilities for working with tools across different formats.
3
+ """
4
+
5
+ from typing import Dict, Any, List
6
+
7
+
8
+ def langchain_tool_to_openai_format(tool) -> Dict[str, Any]:
9
+ """
10
+ Convert a LangChain StructuredTool to OpenAI function calling format.
11
+
12
+ Args:
13
+ tool: A langchain_core.tools.structured.StructuredTool instance
14
+
15
+ Returns:
16
+ Dictionary in OpenAI function calling format, compatible with
17
+ MCPClient.list_tools() output and call_llm() tools parameter
18
+ """
19
+ schema = tool.args_schema.model_json_schema()
20
+
21
+ return {
22
+ "type": "function",
23
+ "function": {
24
+ "name": schema.get("title", tool.name),
25
+ "description": schema.get("description", ""),
26
+ "parameters": {
27
+ "type": "object",
28
+ "properties": schema.get("properties", {}),
29
+ "required": schema.get("required", [])
30
+ }
31
+ }
32
+ }
33
+
34
+
35
+ def langchain_tools_to_openai_format(tools: List) -> List[Dict[str, Any]]:
36
+ """
37
+ Convert a list of LangChain StructuredTools to OpenAI function calling format.
38
+
39
+ Args:
40
+ tools: List of langchain_core.tools.structured.StructuredTool instances
41
+
42
+ Returns:
43
+ List of dictionaries in OpenAI function calling format, compatible with
44
+ MCPClient.list_tools() output and call_llm() tools parameter
45
+ """
46
+ return [langchain_tool_to_openai_format(tool) for tool in tools]
47
+
48
+
49
+ def create_tool_registry(tools: List) -> Dict[str, Any]:
50
+ """
51
+ Create a registry mapping tool names to LangChain tool instances.
52
+
53
+ Args:
54
+ tools: List of langchain_core.tools.structured.StructuredTool instances
55
+
56
+ Returns:
57
+ Dictionary mapping tool names to tool instances
58
+ """
59
+ return {tool.name: tool for tool in tools}
60
+
61
+
62
+ def execute_tool_call(tool_call: Dict[str, Any], tool_registry: Dict[str, Any]) -> Dict[str, Any]:
63
+ """
64
+ Execute a single tool call using LangChain tool registry.
65
+
66
+ Args:
67
+ tool_call: Dictionary with 'tool_name', 'arguments', and 'tool_call_id' keys
68
+ tool_registry: Registry mapping tool names to tool instances
69
+
70
+ Returns:
71
+ Dictionary with 'tool_call_id', 'result', and 'is_error' keys
72
+ """
73
+ tool_name = tool_call.get('tool_name')
74
+ arguments = tool_call.get('arguments', {})
75
+ tool_call_id = tool_call.get('tool_call_id')
76
+
77
+ try:
78
+ if tool_name not in tool_registry:
79
+ raise ValueError(f"Tool '{tool_name}' not found in registry")
80
+
81
+ tool = tool_registry[tool_name]
82
+ result = tool.invoke(arguments)
83
+
84
+ return {
85
+ 'tool_call_id': tool_call_id,
86
+ 'result': result,
87
+ 'is_error': False
88
+ }
89
+ except Exception as e:
90
+ return {
91
+ 'tool_call_id': tool_call_id,
92
+ 'result': f"Error executing tool '{tool_name}': {str(e)}",
93
+ 'is_error': True
94
+ }
95
+
96
+
97
+ def execute_pending_tool_calls(messages, tool_registry: Dict[str, Any]) -> List[Dict[str, Any]]:
98
+ """
99
+ Execute all pending tool calls from a Messages instance and add responses back.
100
+
101
+ Args:
102
+ messages: Messages instance with pending tool calls
103
+ tool_registry: Registry mapping tool names to tool instances
104
+
105
+ Returns:
106
+ List of execution results compatible with Messages.add_tool_responses format
107
+ """
108
+ pending_tool_calls = messages.get_pending_tool_calls()
109
+ results = []
110
+
111
+ for tool_call in pending_tool_calls:
112
+ result = execute_tool_call(tool_call, tool_registry)
113
+
114
+ # Convert to format expected by Messages.add_tool_responses
115
+ if result['is_error']:
116
+ tool_response = {
117
+ 'tool_call_id': result['tool_call_id'],
118
+ 'is_error': True,
119
+ 'error': result['result']
120
+ }
121
+ else:
122
+ tool_response = {
123
+ 'tool_call_id': result['tool_call_id'],
124
+ 'is_error': False,
125
+ 'tool_response': result['result']
126
+ }
127
+
128
+ results.append(tool_response)
129
+
130
+ # Add tool response back to messages using individual method
131
+ if result['is_error']:
132
+ messages.add_tool_response(result['tool_call_id'], result['result'])
133
+ else:
134
+ messages.add_tool_response(result['tool_call_id'], str(result['result']))
135
+
136
+ return results
137
+
138
+
139
+ def execute_and_add_tool_responses(messages, tool_registry: Dict[str, Any]) -> List[Dict[str, Any]]:
140
+ """
141
+ Execute all pending tool calls and add them using Messages.add_tool_responses batch method.
142
+
143
+ Args:
144
+ messages: Messages instance with pending tool calls
145
+ tool_registry: Registry mapping tool names to tool instances
146
+
147
+ Returns:
148
+ List of execution results compatible with Messages.add_tool_responses format
149
+ """
150
+ pending_tool_calls = messages.get_pending_tool_calls()
151
+ results = []
152
+
153
+ for tool_call in pending_tool_calls:
154
+ result = execute_tool_call(tool_call, tool_registry)
155
+
156
+ # Convert to format expected by Messages.add_tool_responses
157
+ if result['is_error']:
158
+ tool_response = {
159
+ 'tool_call_id': result['tool_call_id'],
160
+ 'is_error': True,
161
+ 'error': result['result']
162
+ }
163
+ else:
164
+ tool_response = {
165
+ 'tool_call_id': result['tool_call_id'],
166
+ 'is_error': False,
167
+ 'tool_response': result['result']
168
+ }
169
+
170
+ results.append(tool_response)
171
+
172
+ # Add all responses at once using the batch method
173
+ if results:
174
+ messages.add_tool_responses(results)
175
+
176
+ return results
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentic-blocks
3
- Version: 0.1.10
3
+ Version: 0.1.11
4
4
  Summary: Simple building blocks for agentic AI systems with MCP client and conversation management
5
5
  Author-email: Magnus Bjelkenhed <bjelkenhed@gmail.com>
6
6
  License: MIT
@@ -1,46 +0,0 @@
1
- """
2
- Utilities for working with tools across different formats.
3
- """
4
-
5
- from typing import Dict, Any, List
6
-
7
-
8
- def langchain_tool_to_openai_format(tool) -> Dict[str, Any]:
9
- """
10
- Convert a LangChain StructuredTool to OpenAI function calling format.
11
-
12
- Args:
13
- tool: A langchain_core.tools.structured.StructuredTool instance
14
-
15
- Returns:
16
- Dictionary in OpenAI function calling format, compatible with
17
- MCPClient.list_tools() output and call_llm() tools parameter
18
- """
19
- schema = tool.args_schema.model_json_schema()
20
-
21
- return {
22
- "type": "function",
23
- "function": {
24
- "name": schema.get("title", tool.name),
25
- "description": schema.get("description", ""),
26
- "parameters": {
27
- "type": "object",
28
- "properties": schema.get("properties", {}),
29
- "required": schema.get("required", [])
30
- }
31
- }
32
- }
33
-
34
-
35
- def langchain_tools_to_openai_format(tools: List) -> List[Dict[str, Any]]:
36
- """
37
- Convert a list of LangChain StructuredTools to OpenAI function calling format.
38
-
39
- Args:
40
- tools: List of langchain_core.tools.structured.StructuredTool instances
41
-
42
- Returns:
43
- List of dictionaries in OpenAI function calling format, compatible with
44
- MCPClient.list_tools() output and call_llm() tools parameter
45
- """
46
- return [langchain_tool_to_openai_format(tool) for tool in tools]
File without changes