mbxai 0.5.7__py3-none-any.whl → 0.5.9__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.
mbxai/__init__.py CHANGED
@@ -2,4 +2,4 @@
2
2
  MBX AI package.
3
3
  """
4
4
 
5
- __version__ = "0.5.7"
5
+ __version__ = "0.5.9"
mbxai/mcp/client.py CHANGED
@@ -94,29 +94,7 @@ class MCPClient(ToolClient):
94
94
  )
95
95
  return response.json()
96
96
 
97
- # Create a sync wrapper for the async function
98
- def sync_tool_function(**kwargs: Any) -> Any:
99
- try:
100
- # Try to get the current event loop
101
- loop = asyncio.get_event_loop()
102
- except RuntimeError:
103
- # If no event loop exists, create a new one
104
- loop = asyncio.new_event_loop()
105
- asyncio.set_event_loop(loop)
106
-
107
- # Check if we're already in an event loop
108
- if loop.is_running():
109
- # Create a new event loop for this call
110
- new_loop = asyncio.new_event_loop()
111
- try:
112
- return new_loop.run_until_complete(tool_function(**kwargs))
113
- finally:
114
- new_loop.close()
115
- else:
116
- # Use the existing event loop
117
- return loop.run_until_complete(tool_function(**kwargs))
118
-
119
- return sync_tool_function
97
+ return tool_function
120
98
 
121
99
  async def register_mcp_server(self, name: str, base_url: str) -> None:
122
100
  """Register an MCP server and load its tools."""
mbxai/mcp/server.py CHANGED
@@ -31,7 +31,7 @@ class MCPServer:
31
31
  self.app = FastAPI(
32
32
  title=self.name,
33
33
  description=self.description,
34
- version="0.5.7",
34
+ version="0.5.9",
35
35
  )
36
36
 
37
37
  # Initialize MCP server
mbxai/tools/client.py CHANGED
@@ -4,6 +4,7 @@ ToolClient implementation for MBX AI.
4
4
 
5
5
  from typing import Any, Callable, TypeVar, cast
6
6
  import logging
7
+ import inspect
7
8
  from pydantic import BaseModel
8
9
  from ..openrouter import OpenRouterClient
9
10
  from .types import Tool, ToolCall
@@ -48,7 +49,7 @@ class ToolClient:
48
49
  self._tools[name] = tool
49
50
  logger.debug(f"Registered tool: {name}")
50
51
 
51
- def chat(
52
+ async def chat(
52
53
  self,
53
54
  messages: list[dict[str, Any]],
54
55
  *,
@@ -120,18 +121,41 @@ class ToolClient:
120
121
 
121
122
  # Call the tool
122
123
  logger.debug(f"Calling tool {tool.name} with arguments: {arguments}")
123
- result = tool.function(**arguments)
124
+ if inspect.iscoroutinefunction(tool.function):
125
+ result = await tool.function(**arguments)
126
+ else:
127
+ result = tool.function(**arguments)
124
128
  logger.debug(f"Tool result: {result}")
125
129
 
126
130
  # Add the tool response to the messages
127
- messages.append({
131
+ tool_response = {
128
132
  "role": "tool",
129
133
  "tool_call_id": tool_call.id,
130
134
  "name": tool_call.function.name,
131
135
  "content": str(result),
132
- })
136
+ }
137
+ messages.append(tool_response)
138
+ logger.debug(f"Added tool response to messages: {tool_response}")
133
139
 
134
- def parse(
140
+ # Get a new response from the model with the tool results
141
+ response = self._client.chat_completion(
142
+ messages=messages,
143
+ model=model,
144
+ stream=stream,
145
+ **kwargs,
146
+ )
147
+
148
+ if stream:
149
+ return response
150
+
151
+ message = response.choices[0].message
152
+ messages.append({"role": "assistant", "content": message.content})
153
+
154
+ # If there are no more tool calls, we're done
155
+ if not message.tool_calls:
156
+ return response
157
+
158
+ async def parse(
135
159
  self,
136
160
  messages: list[dict[str, Any]],
137
161
  response_format: type[T],
@@ -206,13 +230,37 @@ class ToolClient:
206
230
 
207
231
  # Call the tool
208
232
  logger.debug(f"Calling tool {tool.name} with arguments: {arguments}")
209
- result = tool.function(**arguments)
233
+ if inspect.iscoroutinefunction(tool.function):
234
+ result = await tool.function(**arguments)
235
+ else:
236
+ result = tool.function(**arguments)
210
237
  logger.debug(f"Tool result: {result}")
211
238
 
212
239
  # Add the tool response to the messages
213
- messages.append({
240
+ tool_response = {
214
241
  "role": "tool",
215
242
  "tool_call_id": tool_call.id,
216
243
  "name": tool_call.function.name,
217
244
  "content": str(result),
218
- })
245
+ }
246
+ messages.append(tool_response)
247
+ logger.debug(f"Added tool response to messages: {tool_response}")
248
+
249
+ # Get a new response from the model with the tool results
250
+ response = self._client.chat_completion_parse(
251
+ messages=messages,
252
+ response_format=response_format,
253
+ model=model,
254
+ stream=stream,
255
+ **kwargs,
256
+ )
257
+
258
+ if stream:
259
+ return response
260
+
261
+ message = response.choices[0].message
262
+ messages.append({"role": "assistant", "content": message.content})
263
+
264
+ # If there are no more tool calls, we're done
265
+ if not message.tool_calls:
266
+ return response
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mbxai
3
- Version: 0.5.7
3
+ Version: 0.5.9
4
4
  Summary: MBX AI SDK
5
5
  Project-URL: Homepage, https://www.mibexx.de
6
6
  Project-URL: Documentation, https://www.mibexx.de
@@ -1,18 +1,18 @@
1
- mbxai/__init__.py,sha256=jvqll5TM8QPQNLg3ReLmexr8D4C_VjvwJvoBki68cck,47
1
+ mbxai/__init__.py,sha256=EGmcQW8yIqs35vLXZTkb_1ZtjO2cYytVbPOV3aHyX2c,47
2
2
  mbxai/core.py,sha256=WMvmU9TTa7M_m-qWsUew4xH8Ul6xseCZ2iBCXJTW-Bs,196
3
3
  mbxai/mcp/__init__.py,sha256=_ek9iYdYqW5saKetj4qDci11jxesQDiHPJRpHMKkxgU,175
4
- mbxai/mcp/client.py,sha256=q2YmtvUlmrkv0tA50DmeX9-wsDJy_-NVkkc69wSsGaY,6277
4
+ mbxai/mcp/client.py,sha256=hEAVWIrIq758C1zm9aWGf-FiITB3LxtuxZEZ0CcjJ4s,5343
5
5
  mbxai/mcp/example.py,sha256=oaol7AvvZnX86JWNz64KvPjab5gg1VjVN3G8eFSzuaE,2350
6
- mbxai/mcp/server.py,sha256=3brJK6NNjnLZgIajPF8CGbc_fwekkV5cxpieF9o4P5I,3462
6
+ mbxai/mcp/server.py,sha256=yHzkHwL41vR4st4A0wx1bGuPFoGewDEa5KwVJ5nhSUI,3462
7
7
  mbxai/openrouter/__init__.py,sha256=Ito9Qp_B6q-RLGAQcYyTJVWwR2YAZvNqE-HIYXxhtD8,298
8
8
  mbxai/openrouter/client.py,sha256=XLRMRNRJH96Jl6_af0KkzRDdLJnixh8I3RvEEcFuXyg,10840
9
9
  mbxai/openrouter/config.py,sha256=MTX_YHsFrM7JYqovJSkEF6JzVyIdajeI5Dja2CALH58,2874
10
10
  mbxai/openrouter/models.py,sha256=b3IjjtZAjeGOf2rLsdnCD1HacjTnS8jmv_ZXorc-KJQ,2604
11
11
  mbxai/tools/__init__.py,sha256=QUFaXhDm-UKcuAtT1rbKzhBkvyRBVokcQIOf9cxIuwc,160
12
- mbxai/tools/client.py,sha256=f4i4lyLWeI81NPwnV8Rz1cO5bGh6kLHcxahNijUrTxw,7718
12
+ mbxai/tools/client.py,sha256=tqOJARnBvmW5Hpjy4RAN45D1RPPT76neltbYHxT0Zt0,9508
13
13
  mbxai/tools/example.py,sha256=1HgKK39zzUuwFbnp3f0ThyWVfA_8P28PZcTwaUw5K78,2232
14
14
  mbxai/tools/types.py,sha256=fo5t9UbsHGynhA88vD_ecgDqL8iLvt2E1h1ym43Rrgk,745
15
- mbxai-0.5.7.dist-info/METADATA,sha256=nc8Rk_zETLzbOpPxSEw0nWEa_TROtALd7Z3qa7ZOT0E,4107
16
- mbxai-0.5.7.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
17
- mbxai-0.5.7.dist-info/licenses/LICENSE,sha256=hEyhc4FxwYo3NQ40yNgZ7STqwVk-1_XcTXOnAPbGJAw,1069
18
- mbxai-0.5.7.dist-info/RECORD,,
15
+ mbxai-0.5.9.dist-info/METADATA,sha256=-9DzHsxUcnL7x9afsWKUnF8OOmqZLi-aE7lmnXUx7_A,4107
16
+ mbxai-0.5.9.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
17
+ mbxai-0.5.9.dist-info/licenses/LICENSE,sha256=hEyhc4FxwYo3NQ40yNgZ7STqwVk-1_XcTXOnAPbGJAw,1069
18
+ mbxai-0.5.9.dist-info/RECORD,,
File without changes