mbxai 0.4.0__tar.gz → 0.5.1__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.
- {mbxai-0.4.0 → mbxai-0.5.1}/.vscode/PythonImportHelper-v2-Completion.json +20 -2
- {mbxai-0.4.0 → mbxai-0.5.1}/PKG-INFO +1 -1
- {mbxai-0.4.0 → mbxai-0.5.1}/pyproject.toml +1 -1
- {mbxai-0.4.0 → mbxai-0.5.1}/setup.py +1 -1
- {mbxai-0.4.0 → mbxai-0.5.1}/src/mbxai/__init__.py +1 -1
- {mbxai-0.4.0 → mbxai-0.5.1}/src/mbxai/mcp/client.py +31 -10
- {mbxai-0.4.0 → mbxai-0.5.1}/src/mbxai/mcp/server.py +1 -1
- {mbxai-0.4.0 → mbxai-0.5.1}/uv.lock +7 -7
- {mbxai-0.4.0 → mbxai-0.5.1}/LICENSE +0 -0
- {mbxai-0.4.0 → mbxai-0.5.1}/README.md +0 -0
- {mbxai-0.4.0 → mbxai-0.5.1}/src/mbxai/core.py +0 -0
- {mbxai-0.4.0 → mbxai-0.5.1}/src/mbxai/mcp/__init__.py +0 -0
- {mbxai-0.4.0 → mbxai-0.5.1}/src/mbxai/mcp/example.py +0 -0
- {mbxai-0.4.0 → mbxai-0.5.1}/src/mbxai/openrouter/__init__.py +0 -0
- {mbxai-0.4.0 → mbxai-0.5.1}/src/mbxai/openrouter/client.py +0 -0
- {mbxai-0.4.0 → mbxai-0.5.1}/src/mbxai/openrouter/config.py +0 -0
- {mbxai-0.4.0 → mbxai-0.5.1}/src/mbxai/openrouter/models.py +0 -0
- {mbxai-0.4.0 → mbxai-0.5.1}/src/mbxai/tools/__init__.py +0 -0
- {mbxai-0.4.0 → mbxai-0.5.1}/src/mbxai/tools/client.py +0 -0
- {mbxai-0.4.0 → mbxai-0.5.1}/src/mbxai/tools/example.py +0 -0
- {mbxai-0.4.0 → mbxai-0.5.1}/src/mbxai/tools/types.py +0 -0
- {mbxai-0.4.0 → mbxai-0.5.1}/tests/test_core.py +0 -0
- {mbxai-0.4.0 → mbxai-0.5.1}/tests/test_mcp.py +0 -0
- {mbxai-0.4.0 → mbxai-0.5.1}/tests/test_openrouter.py +0 -0
- {mbxai-0.4.0 → mbxai-0.5.1}/tests/test_tools.py +0 -0
@@ -220,6 +220,15 @@
|
|
220
220
|
"detail": "httpx",
|
221
221
|
"documentation": {}
|
222
222
|
},
|
223
|
+
{
|
224
|
+
"label": "logging",
|
225
|
+
"kind": 6,
|
226
|
+
"isExtraImport": true,
|
227
|
+
"importPath": "logging",
|
228
|
+
"description": "logging",
|
229
|
+
"detail": "logging",
|
230
|
+
"documentation": {}
|
231
|
+
},
|
223
232
|
{
|
224
233
|
"label": "BaseModel",
|
225
234
|
"importPath": "pydantic",
|
@@ -725,7 +734,7 @@
|
|
725
734
|
"kind": 6,
|
726
735
|
"importPath": "src.mbxai.mcp.client",
|
727
736
|
"description": "src.mbxai.mcp.client",
|
728
|
-
"peekOfCode": "class MCPTool(Tool):\n \"\"\"MCP tool definition.\"\"\"\n internal_url: str | None = Field(default=None, description=\"The internal URL to invoke the tool\")\n service: str = Field(description=\"The service that provides the tool\")\n strict: bool = Field(default=True, description=\"Whether the tool response is strictly validated\")\n input_schema: dict[str, Any] = Field(description=\"The input schema for the tool\")\n def to_openai_function(self) -> dict[str, Any]:\n \"\"\"Convert the tool to an OpenAI function definition.\"\"\"\n return {
|
737
|
+
"peekOfCode": "class MCPTool(Tool):\n \"\"\"MCP tool definition.\"\"\"\n internal_url: str | None = Field(default=None, description=\"The internal URL to invoke the tool\")\n service: str = Field(description=\"The service that provides the tool\")\n strict: bool = Field(default=True, description=\"Whether the tool response is strictly validated\")\n input_schema: dict[str, Any] = Field(description=\"The input schema for the tool\")\n function: Callable[..., Any] | None = Field(default=None, description=\"The function that implements the tool\")\n def to_openai_function(self) -> dict[str, Any]:\n \"\"\"Convert the tool to an OpenAI function definition.\"\"\"\n return {",
|
729
738
|
"detail": "src.mbxai.mcp.client",
|
730
739
|
"documentation": {}
|
731
740
|
},
|
@@ -738,12 +747,21 @@
|
|
738
747
|
"detail": "src.mbxai.mcp.client",
|
739
748
|
"documentation": {}
|
740
749
|
},
|
750
|
+
{
|
751
|
+
"label": "logger",
|
752
|
+
"kind": 5,
|
753
|
+
"importPath": "src.mbxai.mcp.client",
|
754
|
+
"description": "src.mbxai.mcp.client",
|
755
|
+
"peekOfCode": "logger = logging.getLogger(__name__)\nT = TypeVar(\"T\", bound=BaseModel)\nclass MCPTool(Tool):\n \"\"\"MCP tool definition.\"\"\"\n internal_url: str | None = Field(default=None, description=\"The internal URL to invoke the tool\")\n service: str = Field(description=\"The service that provides the tool\")\n strict: bool = Field(default=True, description=\"Whether the tool response is strictly validated\")\n input_schema: dict[str, Any] = Field(description=\"The input schema for the tool\")\n function: Callable[..., Any] | None = Field(default=None, description=\"The function that implements the tool\")\n def to_openai_function(self) -> dict[str, Any]:",
|
756
|
+
"detail": "src.mbxai.mcp.client",
|
757
|
+
"documentation": {}
|
758
|
+
},
|
741
759
|
{
|
742
760
|
"label": "T",
|
743
761
|
"kind": 5,
|
744
762
|
"importPath": "src.mbxai.mcp.client",
|
745
763
|
"description": "src.mbxai.mcp.client",
|
746
|
-
"peekOfCode": "T = TypeVar(\"T\", bound=BaseModel)\nclass MCPTool(Tool):\n \"\"\"MCP tool definition.\"\"\"\n internal_url: str | None = Field(default=None, description=\"The internal URL to invoke the tool\")\n service: str = Field(description=\"The service that provides the tool\")\n strict: bool = Field(default=True, description=\"Whether the tool response is strictly validated\")\n input_schema: dict[str, Any] = Field(description=\"The input schema for the tool\")\n def to_openai_function(self) -> dict[str, Any]:\n \"\"\"Convert the tool to an OpenAI function definition.\"\"\"
|
764
|
+
"peekOfCode": "T = TypeVar(\"T\", bound=BaseModel)\nclass MCPTool(Tool):\n \"\"\"MCP tool definition.\"\"\"\n internal_url: str | None = Field(default=None, description=\"The internal URL to invoke the tool\")\n service: str = Field(description=\"The service that provides the tool\")\n strict: bool = Field(default=True, description=\"Whether the tool response is strictly validated\")\n input_schema: dict[str, Any] = Field(description=\"The input schema for the tool\")\n function: Callable[..., Any] | None = Field(default=None, description=\"The function that implements the tool\")\n def to_openai_function(self) -> dict[str, Any]:\n \"\"\"Convert the tool to an OpenAI function definition.\"\"\"",
|
747
765
|
"detail": "src.mbxai.mcp.client",
|
748
766
|
"documentation": {}
|
749
767
|
},
|
@@ -2,11 +2,13 @@
|
|
2
2
|
|
3
3
|
from typing import Any, TypeVar, Callable
|
4
4
|
import httpx
|
5
|
+
import logging
|
5
6
|
from pydantic import BaseModel, Field
|
6
7
|
|
7
8
|
from ..tools import ToolClient, Tool
|
8
9
|
from ..openrouter import OpenRouterClient
|
9
10
|
|
11
|
+
logger = logging.getLogger(__name__)
|
10
12
|
|
11
13
|
T = TypeVar("T", bound=BaseModel)
|
12
14
|
|
@@ -17,6 +19,7 @@ class MCPTool(Tool):
|
|
17
19
|
service: str = Field(description="The service that provides the tool")
|
18
20
|
strict: bool = Field(default=True, description="Whether the tool response is strictly validated")
|
19
21
|
input_schema: dict[str, Any] = Field(description="The input schema for the tool")
|
22
|
+
function: Callable[..., Any] | None = Field(default=None, description="The function that implements the tool")
|
20
23
|
|
21
24
|
def to_openai_function(self) -> dict[str, Any]:
|
22
25
|
"""Convert the tool to an OpenAI function definition."""
|
@@ -101,16 +104,34 @@ class MCPClient(ToolClient):
|
|
101
104
|
|
102
105
|
# Fetch tools from the server
|
103
106
|
response = await self._http_client.get(f"{base_url}/tools")
|
104
|
-
|
107
|
+
response_data = response.json()
|
108
|
+
|
109
|
+
# Extract tools array from response
|
110
|
+
tools_data = response_data.get("tools", [])
|
111
|
+
logger.info(f"Received {len(tools_data)} tools from server {name}")
|
105
112
|
|
106
113
|
# Register each tool
|
107
|
-
for tool_data in tools_data:
|
108
|
-
|
109
|
-
tool = MCPTool(**tool_data)
|
110
|
-
|
111
|
-
# Create the tool function
|
112
|
-
tool_function = self._create_tool_function(tool)
|
114
|
+
for idx, tool_data in enumerate(tools_data):
|
115
|
+
logger.debug(f"Processing tool {idx}: {tool_data}")
|
113
116
|
|
114
|
-
#
|
115
|
-
|
116
|
-
|
117
|
+
# Ensure tool_data is a dictionary
|
118
|
+
if not isinstance(tool_data, dict):
|
119
|
+
logger.error(f"Invalid tool data type: {type(tool_data)}. Expected dict, got {tool_data}")
|
120
|
+
continue
|
121
|
+
|
122
|
+
try:
|
123
|
+
# Create MCPTool instance with proper dictionary unpacking
|
124
|
+
tool = MCPTool(**tool_data)
|
125
|
+
|
126
|
+
# Create the tool function
|
127
|
+
tool_function = self._create_tool_function(tool)
|
128
|
+
|
129
|
+
# Set the function after creation
|
130
|
+
tool.function = tool_function
|
131
|
+
|
132
|
+
# Register the tool with ToolClient
|
133
|
+
self._tools[tool.name] = tool
|
134
|
+
logger.info(f"Successfully registered tool: {tool.name}")
|
135
|
+
except Exception as e:
|
136
|
+
logger.error(f"Failed to register tool: {str(e)}")
|
137
|
+
logger.error(f"Tool data that caused the error: {tool_data}")
|
@@ -292,11 +292,11 @@ wheels = [
|
|
292
292
|
|
293
293
|
[[package]]
|
294
294
|
name = "httpx-sse"
|
295
|
-
version = "0.
|
295
|
+
version = "0.5.1"
|
296
296
|
source = { registry = "https://pypi.org/simple" }
|
297
|
-
sdist = { url = "https://files.pythonhosted.org/packages/4c/60/8f4281fa9bbf3c8034fd54c0e7412e66edbab6bc74c4996bd616f8d0406e/httpx-sse-0.
|
297
|
+
sdist = { url = "https://files.pythonhosted.org/packages/4c/60/8f4281fa9bbf3c8034fd54c0e7412e66edbab6bc74c4996bd616f8d0406e/httpx-sse-0.5.1.tar.gz", hash = "sha256:1e81a3a3070ce322add1d3529ed42eb5f70817f45ed6ec915ab753f961139721", size = 12624 }
|
298
298
|
wheels = [
|
299
|
-
{ url = "https://files.pythonhosted.org/packages/e1/9b/a181f281f65d776426002f330c31849b86b31fc9d848db62e16f03ff739f/httpx_sse-0.
|
299
|
+
{ url = "https://files.pythonhosted.org/packages/e1/9b/a181f281f65d776426002f330c31849b86b31fc9d848db62e16f03ff739f/httpx_sse-0.5.1-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.1
|
449
|
+
version = "0.5.1"
|
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.
|
983
|
+
version = "0.5.1"
|
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.
|
988
|
+
sdist = { url = "https://files.pythonhosted.org/packages/82/5c/e6082df02e215b846b4b8c0b887a64d7d08ffaba30605502639d44c06b82/typing_inspection-0.5.1.tar.gz", hash = "sha256:9765c87de36671694a67904bf2c96e395be9c6439bb6c87b5142569dcdd65122", size = 76222 }
|
989
989
|
wheels = [
|
990
|
-
{ url = "https://files.pythonhosted.org/packages/31/08/aa4fdfb71f7de5176385bd9e90852eaf6b5d622735020ad600f2bab54385/typing_inspection-0.
|
990
|
+
{ url = "https://files.pythonhosted.org/packages/31/08/aa4fdfb71f7de5176385bd9e90852eaf6b5d622735020ad600f2bab54385/typing_inspection-0.5.1-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
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|