beamlit 0.0.41rc86__py3-none-any.whl → 0.0.42rc88__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.
@@ -6,39 +6,59 @@ import pydantic
6
6
  import pydantic_core
7
7
  import requests
8
8
  import typing_extensions as t
9
- from langchain_core.tools.base import BaseTool, BaseToolkit, ToolException
10
- from mcp import ListToolsResult
11
-
12
9
  from beamlit.authentication.authentication import AuthenticatedClient
13
10
  from beamlit.common.settings import get_settings
11
+ from langchain_core.tools.base import BaseTool, BaseToolkit, ToolException
12
+ from mcp.types import CallToolResult, ListToolsResult
13
+ from pydantic.json_schema import JsonSchemaValue
14
+ from pydantic_core import core_schema as cs
14
15
 
15
16
  settings = get_settings()
16
17
 
17
- def create_dynamic_schema(name: str, schema: dict[str, t.Any]) -> type[pydantic.BaseModel]:
18
- field_definitions = {}
19
- for k, v in schema["properties"].items():
20
- field_type = str
21
- if v["type"] == "number":
22
- field_type = float
23
- elif v["type"] == "integer":
24
- field_type = int
25
- elif v["type"] == "boolean":
26
- field_type = bool
27
- description = v.get("description") or ""
28
- default_ = v.get("default")
29
- fields = {}
30
- if default_ is not None:
31
- fields["default"] = default_
32
- if description is not None:
33
- fields["description"] = description
34
- field_definitions[k] = (
35
- field_type,
36
- pydantic.Field(**fields)
37
- )
38
- return pydantic.create_model(
39
- f"{name}Schema",
40
- **field_definitions
41
- )
18
+ TYPE_MAP = {
19
+ "integer": int,
20
+ "number": float,
21
+ "array": list,
22
+ "boolean": bool,
23
+ "string": str,
24
+ "null": type(None),
25
+ }
26
+
27
+ FIELD_DEFAULTS = {
28
+ int: 0,
29
+ float: 0.0,
30
+ list: [],
31
+ bool: False,
32
+ str: "",
33
+ type(None): None,
34
+ }
35
+
36
+ def configure_field(name: str, type_: dict[str, t.Any], required: list[str]) -> tuple[type, t.Any]:
37
+ field_type = TYPE_MAP[type_["type"]]
38
+ default_ = FIELD_DEFAULTS.get(field_type) if name not in required else ...
39
+ return field_type, default_
40
+
41
+ def create_schema_model(name: str, schema: dict[str, t.Any]) -> type[pydantic.BaseModel]:
42
+ # Create a new model class that returns our JSON schema.
43
+ # LangChain requires a BaseModel class.
44
+ class SchemaBase(pydantic.BaseModel):
45
+ model_config = pydantic.ConfigDict(extra="allow")
46
+
47
+ @t.override
48
+ @classmethod
49
+ def __get_pydantic_json_schema__(
50
+ cls, core_schema: cs.CoreSchema, handler: pydantic.GetJsonSchemaHandler
51
+ ) -> JsonSchemaValue:
52
+ return schema
53
+
54
+ # Since this langchain patch, we need to synthesize pydantic fields from the schema
55
+ # https://github.com/langchain-ai/langchain/commit/033ac417609297369eb0525794d8b48a425b8b33
56
+ required = schema.get("required", [])
57
+ fields: dict[str, t.Any] = {
58
+ name: configure_field(name, type_, required) for name, type_ in schema["properties"].items()
59
+ }
60
+
61
+ return pydantic.create_model(f"{name}Schema", __base__=SchemaBase, **fields)
42
62
 
43
63
 
44
64
 
@@ -83,9 +103,10 @@ class MCPTool(BaseTool):
83
103
  async def _arun(self, *args: t.Any, **kwargs: t.Any) -> t.Any:
84
104
  result = self.client.call_tool(self.name, arguments=kwargs)
85
105
  response = result.json()
86
- content = pydantic_core.to_json(response["content"]).decode()
87
- if response["isError"]:
88
- raise ToolException(content)
106
+ result = CallToolResult(**response)
107
+ if result.isError:
108
+ raise ToolException(result.content)
109
+ content = pydantic_core.to_json(result.content).decode()
89
110
  return content
90
111
 
91
112
  @t.override
@@ -122,7 +143,7 @@ class MCPToolkit(BaseToolkit):
122
143
  client=self.client,
123
144
  name=tool.name,
124
145
  description=tool.description or "",
125
- args_schema=create_dynamic_schema(tool.name, tool.inputSchema),
146
+ args_schema=create_schema_model(tool.name, tool.inputSchema),
126
147
  )
127
148
  # list_tools returns a PaginatedResult, but I don't see a way to pass the cursor to retrieve more tools
128
149
  for tool in self._tools.tools
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: beamlit
3
- Version: 0.0.41rc86
3
+ Version: 0.0.42rc88
4
4
  Summary: Add your description here
5
5
  Author-email: cploujoux <ch.ploujoux@gmail.com>
6
6
  Requires-Python: >=3.12
@@ -17,7 +17,7 @@ Requires-Dist: langchain-mistralai>=0.2.5
17
17
  Requires-Dist: langchain-openai<0.4.0,>=0.3.0
18
18
  Requires-Dist: langchain-xai>=0.2.0
19
19
  Requires-Dist: langgraph<0.3.0,>=0.2.40
20
- Requires-Dist: mcp>=1.1.2
20
+ Requires-Dist: mcp>=1.2.1
21
21
  Requires-Dist: opentelemetry-api>=1.28.2
22
22
  Requires-Dist: opentelemetry-exporter-otlp>=1.28.2
23
23
  Requires-Dist: opentelemetry-instrumentation-anthropic>=0.35.0
@@ -145,7 +145,7 @@ beamlit/deploy/parser.py,sha256=Ga0poCZkoRnuTw082QnTcNGCBJncoRAnVsn8-1FsaJE,6907
145
145
  beamlit/functions/__init__.py,sha256=oejZ6GVd4-2kGKsOwRUq1u2AuSyrrn9kWIuH6WxMqhE,189
146
146
  beamlit/functions/common.py,sha256=HbP_F7IYywB2jqxobjkjFqDaIsJXym-HPeOfLzoHSBo,7014
147
147
  beamlit/functions/decorator.py,sha256=ZtSQsPLI70WKwi2jPhA7DaqREQUINpqt9BDVugeV_sg,1714
148
- beamlit/functions/mcp/mcp.py,sha256=JnkeIh9jDyiZstBA0OH57aGx2JjEJ_DPtnM17Xw6ykM,4060
148
+ beamlit/functions/mcp/mcp.py,sha256=F241qhX66DC5ZTj4mPz87YAgij5NHdvEu51f-OT4rsE,4842
149
149
  beamlit/functions/remote/remote.py,sha256=pY7gsmonkH8iN1anscMIWX-tW__OaBw14bodSUy1lCE,4845
150
150
  beamlit/models/__init__.py,sha256=DB2EBTVX5lTO7CzXvZaqiPtgc9n8SMPu59zGD5_Vvno,9652
151
151
  beamlit/models/acl.py,sha256=tH67gsl_BMaviSbTaaIkO1g9cWZgJ6VgAnYVjQSzGZY,3952
@@ -278,6 +278,6 @@ beamlit/serve/app.py,sha256=ROS_tb9cO4GvOQKCwloyAzpYraTdIb3oG6sChXikeNw,3285
278
278
  beamlit/serve/middlewares/__init__.py,sha256=1dVmnOmhAQWvWktqHkKSIX-YoF6fmMU8xkUQuhg_rJU,148
279
279
  beamlit/serve/middlewares/accesslog.py,sha256=Mu4T4_9OvHybjA0ApzZFpgi2C8f3X1NbUk-76v634XM,631
280
280
  beamlit/serve/middlewares/processtime.py,sha256=lDAaIasZ4bwvN-HKHvZpaD9r-yrkVNZYx4abvbjbrCg,411
281
- beamlit-0.0.41rc86.dist-info/METADATA,sha256=pVWwJpoKf9vfO83lbZWKk_Dek4MCfbIeA_-hBpf0aTk,3715
282
- beamlit-0.0.41rc86.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
283
- beamlit-0.0.41rc86.dist-info/RECORD,,
281
+ beamlit-0.0.42rc88.dist-info/METADATA,sha256=Dm8a_uqAJlhp4eqB1KkAFUseRmSrDAgpdsA14qoKkoU,3715
282
+ beamlit-0.0.42rc88.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
283
+ beamlit-0.0.42rc88.dist-info/RECORD,,