mbxai 0.6.22__py3-none-any.whl → 0.6.24__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.6.22"
5
+ __version__ = "0.6.24"
mbxai/mcp/client.py CHANGED
@@ -24,8 +24,8 @@ class MCPTool(Tool):
24
24
 
25
25
  def to_openai_function(self) -> dict[str, Any]:
26
26
  """Convert the tool to an OpenAI function definition."""
27
- # Use the base Tool's schema conversion
28
- strict_schema = convert_to_strict_schema(self.input_schema, strict=self.strict)
27
+ # Use the unified schema conversion with keep_input_wrapper=True for MCP tools
28
+ strict_schema = convert_to_strict_schema(self.input_schema, strict=self.strict, keep_input_wrapper=True)
29
29
  logger.info(f"Converted schema for {self.name}: {json.dumps(strict_schema, indent=2)}")
30
30
 
31
31
  return {
@@ -56,11 +56,13 @@ class MCPTool(Tool):
56
56
  # Handle input wrapper
57
57
  if "properties" in mcp_schema and "input" in mcp_schema["properties"]:
58
58
  input_schema = mcp_schema["properties"]["input"]
59
+ logger.info(f"Found input wrapper. Input schema: {json.dumps(input_schema, indent=2)}")
59
60
 
60
61
  # If input has a $ref, resolve it
61
62
  if "$ref" in input_schema:
62
63
  ref = input_schema["$ref"].split("/")[-1]
63
64
  input_schema = mcp_schema.get("$defs", {}).get(ref, {})
65
+ logger.info(f"Resolved $ref to: {json.dumps(input_schema, indent=2)}")
64
66
 
65
67
  # Create the input property schema
66
68
  input_prop_schema = {
@@ -88,10 +90,12 @@ class MCPTool(Tool):
88
90
  new_prop[key] = value
89
91
 
90
92
  input_prop_schema["properties"][prop_name] = new_prop
93
+ logger.info(f"Added property {prop_name}: {json.dumps(new_prop, indent=2)}")
91
94
 
92
95
  # Copy over required fields for input schema
93
96
  if "required" in input_schema:
94
97
  input_prop_schema["required"] = input_schema["required"]
98
+ logger.info(f"Added required fields for input schema: {input_prop_schema['required']}")
95
99
 
96
100
  # Add the input property to the main schema
97
101
  strict_schema["properties"]["input"] = input_prop_schema
@@ -99,7 +103,9 @@ class MCPTool(Tool):
99
103
  # Copy over required fields for main schema
100
104
  if "required" in mcp_schema:
101
105
  strict_schema["required"] = mcp_schema["required"]
106
+ logger.info(f"Added required fields for main schema: {strict_schema['required']}")
102
107
 
108
+ logger.info(f"Final strict schema: {json.dumps(strict_schema, indent=2)}")
103
109
  return strict_schema
104
110
 
105
111
 
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.6.22",
34
+ version="0.6.24",
35
35
  )
36
36
 
37
37
  # Initialize MCP server
mbxai/tools/types.py CHANGED
@@ -9,18 +9,19 @@ import json
9
9
 
10
10
  logger = logging.getLogger(__name__)
11
11
 
12
- def convert_to_strict_schema(schema: dict[str, Any], strict: bool = True) -> dict[str, Any]:
12
+ def convert_to_strict_schema(schema: dict[str, Any], strict: bool = True, keep_input_wrapper: bool = False) -> dict[str, Any]:
13
13
  """Convert a schema to strict format required by OpenAI.
14
14
 
15
15
  Args:
16
16
  schema: The input schema to validate and convert
17
17
  strict: Whether to enforce strict validation with additionalProperties: false
18
+ keep_input_wrapper: Whether to keep the input wrapper (for MCP tools)
18
19
 
19
20
  Returns:
20
21
  A schema in strict format
21
22
  """
22
23
  logger.info(f"Converting schema to strict format. Input schema: {json.dumps(schema, indent=2)}")
23
- logger.info(f"Strict mode: {strict}")
24
+ logger.info(f"Strict mode: {strict}, Keep input wrapper: {keep_input_wrapper}")
24
25
 
25
26
  if not schema:
26
27
  return {"type": "object", "properties": {}, "required": []}
@@ -47,41 +48,76 @@ def convert_to_strict_schema(schema: dict[str, Any], strict: bool = True) -> dic
47
48
  input_schema = schema.get("$defs", {}).get(ref, {})
48
49
  logger.info(f"Resolved $ref to: {json.dumps(input_schema, indent=2)}")
49
50
 
50
- # Create the input property schema
51
- input_prop_schema = {
52
- "type": "object",
53
- "properties": {},
54
- "required": []
55
- }
56
-
57
- # Add additionalProperties: false for input schema
58
- if strict:
59
- input_prop_schema["additionalProperties"] = False
60
-
61
- # Copy over input properties
62
- if "properties" in input_schema:
63
- for prop_name, prop in input_schema["properties"].items():
51
+ if keep_input_wrapper:
52
+ # Create the input property schema
53
+ input_prop_schema = {
54
+ "type": "object",
55
+ "properties": {},
56
+ "required": []
57
+ }
58
+
59
+ # Add additionalProperties: false for input schema
60
+ if strict:
61
+ input_prop_schema["additionalProperties"] = False
62
+
63
+ # Copy over input properties
64
+ if "properties" in input_schema:
65
+ for prop_name, prop in input_schema["properties"].items():
66
+ # Create a new property object with only allowed fields
67
+ new_prop = {
68
+ "type": prop.get("type", "string"),
69
+ "description": prop.get("description", f"The {prop_name} parameter")
70
+ }
71
+
72
+ input_prop_schema["properties"][prop_name] = new_prop
73
+ logger.info(f"Added property {prop_name}: {json.dumps(new_prop, indent=2)}")
74
+
75
+ # Copy over required fields for input schema
76
+ if "required" in input_schema:
77
+ input_prop_schema["required"] = input_schema["required"]
78
+ logger.info(f"Added required fields for input schema: {input_prop_schema['required']}")
79
+
80
+ # Add the input property to the main schema
81
+ strict_schema["properties"]["input"] = input_prop_schema
82
+
83
+ # Copy over required fields for main schema
84
+ if "required" in schema:
85
+ strict_schema["required"] = schema["required"]
86
+ logger.info(f"Added required fields for main schema: {strict_schema['required']}")
87
+ else:
88
+ # If not keeping input wrapper, use input schema directly
89
+ if "properties" in input_schema:
90
+ for prop_name, prop in input_schema["properties"].items():
91
+ # Create a new property object with only allowed fields
92
+ new_prop = {
93
+ "type": prop.get("type", "string"),
94
+ "description": prop.get("description", f"The {prop_name} parameter")
95
+ }
96
+
97
+ strict_schema["properties"][prop_name] = new_prop
98
+ logger.info(f"Added property {prop_name}: {json.dumps(new_prop, indent=2)}")
99
+
100
+ # Copy over required fields
101
+ if "required" in input_schema:
102
+ strict_schema["required"] = input_schema["required"]
103
+ logger.info(f"Added required fields: {strict_schema['required']}")
104
+ else:
105
+ # If no input wrapper, use the schema as is
106
+ if "properties" in schema:
107
+ for prop_name, prop in schema["properties"].items():
64
108
  # Create a new property object with only allowed fields
65
109
  new_prop = {
66
110
  "type": prop.get("type", "string"),
67
111
  "description": prop.get("description", f"The {prop_name} parameter")
68
112
  }
69
113
 
70
- input_prop_schema["properties"][prop_name] = new_prop
114
+ strict_schema["properties"][prop_name] = new_prop
71
115
  logger.info(f"Added property {prop_name}: {json.dumps(new_prop, indent=2)}")
72
116
 
73
- # Copy over required fields for input schema
74
- if "required" in input_schema:
75
- input_prop_schema["required"] = input_schema["required"]
76
- logger.info(f"Added required fields for input schema: {input_prop_schema['required']}")
77
-
78
- # Add the input property to the main schema
79
- strict_schema["properties"]["input"] = input_prop_schema
80
-
81
- # Copy over required fields for main schema
117
+ # Copy over required fields
82
118
  if "required" in schema:
83
119
  strict_schema["required"] = schema["required"]
84
- logger.info(f"Added required fields for main schema: {strict_schema['required']}")
120
+ logger.info(f"Added required fields: {strict_schema['required']}")
85
121
 
86
122
  logger.info(f"Final strict schema: {json.dumps(strict_schema, indent=2)}")
87
123
  return strict_schema
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mbxai
3
- Version: 0.6.22
3
+ Version: 0.6.24
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,9 +1,9 @@
1
- mbxai/__init__.py,sha256=yg4sZUYaTu5lJqkUoW6bkIZhWpjbkcSLbNTkfDhD_5I,48
1
+ mbxai/__init__.py,sha256=0Ot9ioJB-MPkuEkKuIsq66dI-9eofSMLmYCndf90ZTc,48
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=EtgrKiTsHHeAzmnsYCOJMiu-i-k06kJZqR_L2bz91pw,7843
4
+ mbxai/mcp/client.py,sha256=2aX5zMe0vSxZSdvfxoHDA5p_aQSqV1bhX_-QopG2uX8,8477
5
5
  mbxai/mcp/example.py,sha256=oaol7AvvZnX86JWNz64KvPjab5gg1VjVN3G8eFSzuaE,2350
6
- mbxai/mcp/server.py,sha256=oFDL4CHXJxIpH1btcWTlxm4mLztfrY6X8cKI30HZxj0,3463
6
+ mbxai/mcp/server.py,sha256=KfhNlyeFx5nwQNc_w7ZWX3yqqHYbLanWTP4QJrNTMjg,3463
7
7
  mbxai/openrouter/__init__.py,sha256=Ito9Qp_B6q-RLGAQcYyTJVWwR2YAZvNqE-HIYXxhtD8,298
8
8
  mbxai/openrouter/client.py,sha256=nusxYObyLAMGQd6J9u2uLfkRXyE5kZmdIGdlU-76HPo,13529
9
9
  mbxai/openrouter/config.py,sha256=Ia93s-auim9Sq71eunVDbn9ET5xX2zusXpV4JBdHAzs,3251
@@ -11,8 +11,8 @@ mbxai/openrouter/models.py,sha256=b3IjjtZAjeGOf2rLsdnCD1HacjTnS8jmv_ZXorc-KJQ,26
11
11
  mbxai/tools/__init__.py,sha256=ogxrHvgJ7OR62Lmd5x9Eh5d2C0jqWyQis7Zy3yKpZ78,218
12
12
  mbxai/tools/client.py,sha256=qOf8MiQ8_flPUNiMioOyjeEaV8rN1EBWb98T8qTC3D4,17582
13
13
  mbxai/tools/example.py,sha256=1HgKK39zzUuwFbnp3f0ThyWVfA_8P28PZcTwaUw5K78,2232
14
- mbxai/tools/types.py,sha256=iyoSnRwr_Anf7qBybAQ_-dqFnDmABmrtPpgef3R7PV0,4193
15
- mbxai-0.6.22.dist-info/METADATA,sha256=sK-8ps0-u6T-8CaR8Rfgw1ZZ3wg7SI3On1ZwMQ7PQ2I,4148
16
- mbxai-0.6.22.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
17
- mbxai-0.6.22.dist-info/licenses/LICENSE,sha256=hEyhc4FxwYo3NQ40yNgZ7STqwVk-1_XcTXOnAPbGJAw,1069
18
- mbxai-0.6.22.dist-info/RECORD,,
14
+ mbxai/tools/types.py,sha256=ISm4k2USFXq_cO3C6UHaa96l0_Qo_mryezOXZV30yVA,6260
15
+ mbxai-0.6.24.dist-info/METADATA,sha256=Lu3jCm2klY8uxSWnL05LHwHYX1Y7MKUK_nUZBWgtBJY,4148
16
+ mbxai-0.6.24.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
17
+ mbxai-0.6.24.dist-info/licenses/LICENSE,sha256=hEyhc4FxwYo3NQ40yNgZ7STqwVk-1_XcTXOnAPbGJAw,1069
18
+ mbxai-0.6.24.dist-info/RECORD,,
File without changes