mbxai 0.5.14__tar.gz → 0.5.15__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.
Files changed (25) hide show
  1. {mbxai-0.5.14 → mbxai-0.5.15}/PKG-INFO +1 -1
  2. {mbxai-0.5.14 → mbxai-0.5.15}/pyproject.toml +1 -1
  3. {mbxai-0.5.14 → mbxai-0.5.15}/setup.py +1 -1
  4. {mbxai-0.5.14 → mbxai-0.5.15}/src/mbxai/__init__.py +1 -1
  5. {mbxai-0.5.14 → mbxai-0.5.15}/src/mbxai/mcp/server.py +1 -1
  6. {mbxai-0.5.14 → mbxai-0.5.15}/src/mbxai/tools/client.py +18 -17
  7. {mbxai-0.5.14 → mbxai-0.5.15}/uv.lock +7 -7
  8. {mbxai-0.5.14 → mbxai-0.5.15}/.vscode/PythonImportHelper-v2-Completion.json +0 -0
  9. {mbxai-0.5.14 → mbxai-0.5.15}/LICENSE +0 -0
  10. {mbxai-0.5.14 → mbxai-0.5.15}/README.md +0 -0
  11. {mbxai-0.5.14 → mbxai-0.5.15}/src/mbxai/core.py +0 -0
  12. {mbxai-0.5.14 → mbxai-0.5.15}/src/mbxai/mcp/__init__.py +0 -0
  13. {mbxai-0.5.14 → mbxai-0.5.15}/src/mbxai/mcp/client.py +0 -0
  14. {mbxai-0.5.14 → mbxai-0.5.15}/src/mbxai/mcp/example.py +0 -0
  15. {mbxai-0.5.14 → mbxai-0.5.15}/src/mbxai/openrouter/__init__.py +0 -0
  16. {mbxai-0.5.14 → mbxai-0.5.15}/src/mbxai/openrouter/client.py +0 -0
  17. {mbxai-0.5.14 → mbxai-0.5.15}/src/mbxai/openrouter/config.py +0 -0
  18. {mbxai-0.5.14 → mbxai-0.5.15}/src/mbxai/openrouter/models.py +0 -0
  19. {mbxai-0.5.14 → mbxai-0.5.15}/src/mbxai/tools/__init__.py +0 -0
  20. {mbxai-0.5.14 → mbxai-0.5.15}/src/mbxai/tools/example.py +0 -0
  21. {mbxai-0.5.14 → mbxai-0.5.15}/src/mbxai/tools/types.py +0 -0
  22. {mbxai-0.5.14 → mbxai-0.5.15}/tests/test_core.py +0 -0
  23. {mbxai-0.5.14 → mbxai-0.5.15}/tests/test_mcp.py +0 -0
  24. {mbxai-0.5.14 → mbxai-0.5.15}/tests/test_openrouter.py +0 -0
  25. {mbxai-0.5.14 → mbxai-0.5.15}/tests/test_tools.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mbxai
3
- Version: 0.5.14
3
+ Version: 0.5.15
4
4
  Summary: MBX AI SDK
5
5
  Project-URL: Homepage, https://www.mibexx.de
6
6
  Project-URL: Documentation, https://www.mibexx.de
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "mbxai"
7
- version = "0.5.14"
7
+ version = "0.5.15"
8
8
  authors = [
9
9
  { name = "MBX AI" }
10
10
  ]
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name="mbxai",
5
- version="0.5.14",
5
+ version="0.5.15",
6
6
  author="MBX AI",
7
7
  description="MBX AI SDK",
8
8
  long_description=open("README.md").read(),
@@ -2,4 +2,4 @@
2
2
  MBX AI package.
3
3
  """
4
4
 
5
- __version__ = "0.5.14"
5
+ __version__ = "0.5.15"
@@ -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.14",
34
+ version="0.5.15",
35
35
  )
36
36
 
37
37
  # Initialize MCP server
@@ -58,6 +58,20 @@ class ToolClient:
58
58
  return content
59
59
  return content[:max_length] + "..."
60
60
 
61
+ def _truncate_dict(self, data: dict[str, Any], max_length: int = 50) -> str:
62
+ """Truncate dictionary values for logging."""
63
+ if not data:
64
+ return "{}"
65
+ truncated = {}
66
+ for k, v in data.items():
67
+ if isinstance(v, str):
68
+ truncated[k] = self._truncate_content(v, max_length)
69
+ elif isinstance(v, dict):
70
+ truncated[k] = self._truncate_dict(v, max_length)
71
+ else:
72
+ truncated[k] = str(v)[:max_length] + "..." if len(str(v)) > max_length else v
73
+ return str(truncated)
74
+
61
75
  def _log_messages(self, messages: list[dict[str, Any]]) -> None:
62
76
  """Log the messages being sent to OpenRouter."""
63
77
  logger.info("Sending messages to OpenRouter:")
@@ -167,7 +181,6 @@ class ToolClient:
167
181
  return response
168
182
 
169
183
  # Handle all tool calls before getting the next model response
170
- tool_responses = []
171
184
  for tool_call in message.tool_calls:
172
185
  tool = self._tools.get(tool_call.function.name)
173
186
  if not tool:
@@ -183,7 +196,7 @@ class ToolClient:
183
196
  raise ValueError(f"Invalid tool arguments format: {arguments}")
184
197
 
185
198
  # Call the tool
186
- logger.info(f"Calling tool: {tool.name} with args: {self._truncate_content(json.dumps(arguments))}")
199
+ logger.info(f"Calling tool: {tool.name} with args: {self._truncate_dict(arguments)}")
187
200
  if inspect.iscoroutinefunction(tool.function):
188
201
  result = await tool.function(**arguments)
189
202
  else:
@@ -193,27 +206,15 @@ class ToolClient:
193
206
  if not isinstance(result, str):
194
207
  result = json.dumps(result)
195
208
 
196
- # Create the tool response
209
+ # Create and add the tool response immediately
197
210
  tool_response = {
198
211
  "role": "tool",
199
212
  "tool_call_id": tool_call.id,
200
213
  "content": result,
201
214
  }
202
- tool_responses.append(tool_response)
215
+ messages.append(tool_response)
203
216
  logger.info(f"Tool response for call ID {tool_call.id}: {self._truncate_content(result)}")
204
217
 
205
- # Add all tool responses to the messages
206
- messages.extend(tool_responses)
207
- logger.info(f"Added {len(tool_responses)} tool responses to messages")
208
-
209
- # Validate that all tool calls have responses
210
- tool_call_ids = {tc.id for tc in message.tool_calls}
211
- tool_response_ids = {tr["tool_call_id"] for tr in tool_responses}
212
- missing_responses = tool_call_ids - tool_response_ids
213
- if missing_responses:
214
- logger.error(f"Missing tool responses for call IDs: {missing_responses}")
215
- raise ValueError(f"Missing tool responses for call IDs: {missing_responses}")
216
-
217
218
  # Get a new response from the model with all tool results
218
219
  response = self._client.chat_completion(
219
220
  messages=messages,
@@ -336,7 +337,7 @@ class ToolClient:
336
337
  raise ValueError(f"Invalid tool arguments format: {arguments}")
337
338
 
338
339
  # Call the tool
339
- logger.info(f"Calling tool: {tool.name} with args: {self._truncate_content(json.dumps(arguments))}")
340
+ logger.info(f"Calling tool: {tool.name} with args: {self._truncate_dict(arguments)}")
340
341
  if inspect.iscoroutinefunction(tool.function):
341
342
  result = await tool.function(**arguments)
342
343
  else:
@@ -292,11 +292,11 @@ wheels = [
292
292
 
293
293
  [[package]]
294
294
  name = "httpx-sse"
295
- version = "0.5.14"
295
+ version = "0.5.15"
296
296
  source = { registry = "https://pypi.org/simple" }
297
- sdist = { url = "https://files.pythonhosted.org/packages/4c/60/8f4281fa9bbf3c8034fd54c0e7412e66edbab6bc74c4996bd616f8d0406e/httpx-sse-0.5.14.tar.gz", hash = "sha256:1e81a3a3070ce322add1d3529ed42eb5f70817f45ed6ec915ab753f961139721", size = 12624 }
297
+ sdist = { url = "https://files.pythonhosted.org/packages/4c/60/8f4281fa9bbf3c8034fd54c0e7412e66edbab6bc74c4996bd616f8d0406e/httpx-sse-0.5.15.tar.gz", hash = "sha256:1e81a3a3070ce322add1d3529ed42eb5f70817f45ed6ec915ab753f961139721", size = 12624 }
298
298
  wheels = [
299
- { url = "https://files.pythonhosted.org/packages/e1/9b/a181f281f65d776426002f330c31849b86b31fc9d848db62e16f03ff739f/httpx_sse-0.5.14-py3-none-any.whl", hash = "sha256:f329af6eae57eaa2bdfd962b42524764af68075ea87370a2de920af5341e318f", size = 7819 },
299
+ { url = "https://files.pythonhosted.org/packages/e1/9b/a181f281f65d776426002f330c31849b86b31fc9d848db62e16f03ff739f/httpx_sse-0.5.15-py3-none-any.whl", hash = "sha256:f329af6eae57eaa2bdfd962b42524764af68075ea87370a2de920af5341e318f", size = 7819 },
300
300
  ]
301
301
 
302
302
  [[package]]
@@ -446,7 +446,7 @@ wheels = [
446
446
 
447
447
  [[package]]
448
448
  name = "mbxai"
449
- version = "0.5.14"
449
+ version = "0.5.15"
450
450
  source = { editable = "." }
451
451
  dependencies = [
452
452
  { name = "fastapi" },
@@ -980,14 +980,14 @@ wheels = [
980
980
 
981
981
  [[package]]
982
982
  name = "typing-inspection"
983
- version = "0.5.14"
983
+ version = "0.5.15"
984
984
  source = { registry = "https://pypi.org/simple" }
985
985
  dependencies = [
986
986
  { name = "typing-extensions" },
987
987
  ]
988
- sdist = { url = "https://files.pythonhosted.org/packages/82/5c/e6082df02e215b846b4b8c0b887a64d7d08ffaba30605502639d44c06b82/typing_inspection-0.5.14.tar.gz", hash = "sha256:9765c87de36671694a67904bf2c96e395be9c6439bb6c87b5142569dcdd65122", size = 76222 }
988
+ sdist = { url = "https://files.pythonhosted.org/packages/82/5c/e6082df02e215b846b4b8c0b887a64d7d08ffaba30605502639d44c06b82/typing_inspection-0.5.15.tar.gz", hash = "sha256:9765c87de36671694a67904bf2c96e395be9c6439bb6c87b5142569dcdd65122", size = 76222 }
989
989
  wheels = [
990
- { url = "https://files.pythonhosted.org/packages/31/08/aa4fdfb71f7de5176385bd9e90852eaf6b5d622735020ad600f2bab54385/typing_inspection-0.5.14-py3-none-any.whl", hash = "sha256:50e72559fcd2a6367a19f7a7e610e6afcb9fac940c650290eed893d61386832f", size = 14125 },
990
+ { url = "https://files.pythonhosted.org/packages/31/08/aa4fdfb71f7de5176385bd9e90852eaf6b5d622735020ad600f2bab54385/typing_inspection-0.5.15-py3-none-any.whl", hash = "sha256:50e72559fcd2a6367a19f7a7e610e6afcb9fac940c650290eed893d61386832f", size = 14125 },
991
991
  ]
992
992
 
993
993
  [[package]]
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes