beamlit 0.0.29rc26__py3-none-any.whl → 0.0.29rc28__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.
- beamlit/agents/decorator.py +10 -4
- beamlit/authentication/authentication.py +1 -1
- beamlit/functions/mcp/mcp.py +26 -18
- beamlit/functions/remote/remote.py +39 -37
- {beamlit-0.0.29rc26.dist-info → beamlit-0.0.29rc28.dist-info}/METADATA +1 -1
- {beamlit-0.0.29rc26.dist-info → beamlit-0.0.29rc28.dist-info}/RECORD +7 -7
- {beamlit-0.0.29rc26.dist-info → beamlit-0.0.29rc28.dist-info}/WHEEL +0 -0
beamlit/agents/decorator.py
CHANGED
@@ -17,16 +17,18 @@ from langchain_core.tools import Tool
|
|
17
17
|
from langgraph.checkpoint.memory import MemorySaver
|
18
18
|
from langgraph.prebuilt import create_react_agent
|
19
19
|
|
20
|
-
from .chat import get_chat_model
|
21
20
|
from .chain import ChainToolkit
|
21
|
+
from .chat import get_chat_model
|
22
|
+
|
22
23
|
|
23
|
-
def get_functions(dir="src/functions", from_decorator="function"):
|
24
|
+
def get_functions(dir="src/functions", from_decorator="function", remote_functions_empty=True):
|
24
25
|
functions = []
|
25
26
|
logger = getLogger(__name__)
|
26
27
|
|
27
28
|
# Walk through all Python files in functions directory and subdirectories
|
28
29
|
if not os.path.exists(dir):
|
29
|
-
|
30
|
+
if remote_functions_empty:
|
31
|
+
logger.warn(f"Functions directory {dir} not found")
|
30
32
|
return []
|
31
33
|
for root, _, files in os.walk(dir):
|
32
34
|
for file in files:
|
@@ -74,6 +76,7 @@ def get_functions(dir="src/functions", from_decorator="function"):
|
|
74
76
|
kit_functions = get_functions(
|
75
77
|
dir=os.path.join(root),
|
76
78
|
from_decorator="kit",
|
79
|
+
remote_functions_empty=remote_functions_empty,
|
77
80
|
)
|
78
81
|
functions.extend(kit_functions)
|
79
82
|
|
@@ -134,7 +137,10 @@ def agent(
|
|
134
137
|
return wrapped
|
135
138
|
|
136
139
|
# Initialize functions array to store decorated functions
|
137
|
-
functions = get_functions(
|
140
|
+
functions = get_functions(
|
141
|
+
dir=settings.agent.functions_directory,
|
142
|
+
remote_functions_empty=not remote_functions,
|
143
|
+
)
|
138
144
|
settings.agent.functions = functions
|
139
145
|
|
140
146
|
if agent is not None:
|
@@ -80,7 +80,7 @@ def new_client_with_credentials(config: RunClientWithCredentials):
|
|
80
80
|
|
81
81
|
def get_authentication_headers(settings: Settings) -> Dict[str, str]:
|
82
82
|
context = current_context()
|
83
|
-
if context.workspace:
|
83
|
+
if context.workspace and not settings.authentication.client.credentials:
|
84
84
|
credentials = load_credentials(context.workspace)
|
85
85
|
else:
|
86
86
|
settings = get_settings()
|
beamlit/functions/mcp/mcp.py
CHANGED
@@ -11,26 +11,35 @@ from beamlit.authentication.authentication import AuthenticatedClient
|
|
11
11
|
from beamlit.common.settings import get_settings
|
12
12
|
from langchain_core.tools.base import BaseTool, BaseToolkit, ToolException
|
13
13
|
from mcp import ListToolsResult
|
14
|
-
from pydantic.json_schema import JsonSchemaValue
|
15
|
-
from pydantic_core import core_schema as cs
|
16
14
|
|
17
15
|
settings = get_settings()
|
18
16
|
|
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
|
+
)
|
19
42
|
|
20
|
-
def create_schema_model(schema: dict[str, t.Any]) -> type[pydantic.BaseModel]:
|
21
|
-
# Create a new model class that returns our JSON schema.
|
22
|
-
# LangChain requires a BaseModel class.
|
23
|
-
class Schema(pydantic.BaseModel):
|
24
|
-
model_config = pydantic.ConfigDict(extra="allow")
|
25
|
-
|
26
|
-
@t.override
|
27
|
-
@classmethod
|
28
|
-
def __get_pydantic_json_schema__(
|
29
|
-
cls, core_schema: cs.CoreSchema, handler: pydantic.GetJsonSchemaHandler
|
30
|
-
) -> JsonSchemaValue:
|
31
|
-
return schema
|
32
|
-
|
33
|
-
return Schema
|
34
43
|
|
35
44
|
|
36
45
|
class MCPClient:
|
@@ -42,7 +51,6 @@ class MCPClient:
|
|
42
51
|
def list_tools(self) -> requests.Response:
|
43
52
|
client = self.client.get_httpx_client()
|
44
53
|
url = urllib.parse.urljoin(settings.mcp_hub_url, f"{self.server_name}/tools/list")
|
45
|
-
|
46
54
|
response = client.request("GET", url, headers=self.headers)
|
47
55
|
response.raise_for_status()
|
48
56
|
return response
|
@@ -118,7 +126,7 @@ class MCPToolkit(BaseToolkit):
|
|
118
126
|
client=self.client,
|
119
127
|
name=tool.name,
|
120
128
|
description=tool.description or "",
|
121
|
-
args_schema=
|
129
|
+
args_schema=create_dynamic_schema(tool.name, tool.inputSchema),
|
122
130
|
)
|
123
131
|
# list_tools returns a PaginatedResult, but I don't see a way to pass the cursor to retrieve more tools
|
124
132
|
for tool in self._tools.tools
|
@@ -1,46 +1,37 @@
|
|
1
1
|
import asyncio
|
2
2
|
import warnings
|
3
|
-
from
|
3
|
+
from dataclasses import dataclass
|
4
|
+
from typing import Callable, Literal
|
4
5
|
|
5
6
|
import pydantic
|
6
7
|
import typing_extensions as t
|
7
|
-
from dataclasses import dataclass
|
8
8
|
from beamlit.api.functions import get_function
|
9
9
|
from beamlit.authentication.authentication import AuthenticatedClient
|
10
|
-
from beamlit.run import RunClient
|
11
10
|
from beamlit.common.settings import get_settings
|
12
11
|
from beamlit.models import Function, StoreFunctionParameter
|
12
|
+
from beamlit.run import RunClient
|
13
13
|
from langchain_core.tools.base import BaseTool, ToolException
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
schema["properties"][parameter.name] = {
|
36
|
-
"type": parameter.type_,
|
37
|
-
"description": parameter.description,
|
38
|
-
}
|
39
|
-
if parameter.required:
|
40
|
-
schema["required"].append(parameter.name)
|
41
|
-
return schema
|
42
|
-
|
43
|
-
return Schema
|
14
|
+
|
15
|
+
|
16
|
+
def create_dynamic_schema(name: str, parameters: list[StoreFunctionParameter]) -> type[pydantic.BaseModel]:
|
17
|
+
field_definitions = {}
|
18
|
+
for param in parameters:
|
19
|
+
field_type = str
|
20
|
+
if param.type_ == "number":
|
21
|
+
field_type = float
|
22
|
+
elif param.type_ == "integer":
|
23
|
+
field_type = int
|
24
|
+
elif param.type_ == "boolean":
|
25
|
+
field_type = bool
|
26
|
+
|
27
|
+
field_definitions[param.name] = (
|
28
|
+
field_type,
|
29
|
+
pydantic.Field(description=param.description or "")
|
30
|
+
)
|
31
|
+
return pydantic.create_model(
|
32
|
+
f"{name}Schema",
|
33
|
+
**field_definitions
|
34
|
+
)
|
44
35
|
|
45
36
|
|
46
37
|
class RemoteTool(BaseTool):
|
@@ -49,6 +40,8 @@ class RemoteTool(BaseTool):
|
|
49
40
|
"""
|
50
41
|
|
51
42
|
client: RunClient
|
43
|
+
resource_name: str
|
44
|
+
kit: bool = False
|
52
45
|
handle_tool_error: bool | str | Callable[[ToolException], str] | None = True
|
53
46
|
|
54
47
|
@t.override
|
@@ -62,12 +55,15 @@ class RemoteTool(BaseTool):
|
|
62
55
|
@t.override
|
63
56
|
async def _arun(self, *args: t.Any, **kwargs: t.Any) -> t.Any:
|
64
57
|
settings = get_settings()
|
58
|
+
body = {**kwargs}
|
59
|
+
if self.kit:
|
60
|
+
body["name"] = self.name
|
65
61
|
result = self.client.run(
|
66
62
|
"function",
|
67
|
-
self.
|
63
|
+
self.resource_name,
|
68
64
|
settings.environment,
|
69
65
|
"POST",
|
70
|
-
|
66
|
+
json=body
|
71
67
|
)
|
72
68
|
return result.text
|
73
69
|
|
@@ -104,8 +100,10 @@ class RemoteToolkit:
|
|
104
100
|
RemoteTool(
|
105
101
|
client=RunClient(self.client),
|
106
102
|
name=func.name,
|
103
|
+
resource_name=self._function.metadata.name,
|
104
|
+
kit=True,
|
107
105
|
description=func.description or "",
|
108
|
-
args_schema=
|
106
|
+
args_schema=create_dynamic_schema(func.name, func.parameters),
|
109
107
|
)
|
110
108
|
for func in self._function.spec.kit
|
111
109
|
]
|
@@ -114,7 +112,11 @@ class RemoteToolkit:
|
|
114
112
|
RemoteTool(
|
115
113
|
client=RunClient(self.client),
|
116
114
|
name=self._function.metadata.name,
|
115
|
+
resource_name=self._function.metadata.name,
|
117
116
|
description=self._function.spec.description or "",
|
118
|
-
args_schema=
|
117
|
+
args_schema=create_dynamic_schema(
|
118
|
+
self._function.metadata.name,
|
119
|
+
self._function.spec.parameters
|
120
|
+
),
|
119
121
|
)
|
120
122
|
]
|
@@ -7,7 +7,7 @@ beamlit/types.py,sha256=E1hhDh_zXfsSQ0NCt9-uw90_Mr5iIlsdfnfvxv5HarU,1005
|
|
7
7
|
beamlit/agents/__init__.py,sha256=nf1iwQwGtCG6nDqyVhxfWoqR6dv6X3bvSpCeqkTCFaM,101
|
8
8
|
beamlit/agents/chain.py,sha256=HzBs3nI4xaH86I_r-M-HGGp6roXsJxMx-qXl_GrJaY0,2831
|
9
9
|
beamlit/agents/chat.py,sha256=gVyv4FGBdQTDhdutX8l64OUNa6Fdqaw4eCfEDRH0IPQ,3558
|
10
|
-
beamlit/agents/decorator.py,sha256=
|
10
|
+
beamlit/agents/decorator.py,sha256=4KxPcu6hPoB__1OdzpEJVD5N3QVa_syKd_Y6n6lVEjQ,9715
|
11
11
|
beamlit/api/__init__.py,sha256=zTSiG_ujSjAqWPyc435YXaX9XTlpMjiJWBbV-f-YtdA,45
|
12
12
|
beamlit/api/agents/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
13
13
|
beamlit/api/agents/create_agent.py,sha256=t5Pr62My2EhQlcIY71MrI73-0_q5Djr3a_Ybt9MIiQQ,3587
|
@@ -124,7 +124,7 @@ beamlit/api/workspaces/update_workspace.py,sha256=qa5DV2UJSUYuB_ibALb4E9ghKpT1Ha
|
|
124
124
|
beamlit/api/workspaces/update_workspace_user_role.py,sha256=Yn9iuJ4tKtauzBiJyU4-wYUMS9g98X2Om8zs7UkzrY8,4917
|
125
125
|
beamlit/authentication/__init__.py,sha256=wiXqRbc7E-ulrH_ueA9duOGFvXeo7-RvhSD1XbFogMo,1020
|
126
126
|
beamlit/authentication/apikey.py,sha256=KNBTgdi0VBzBAAmSwU2X1QoB58vRbg8wkXb8-GTZCQo,657
|
127
|
-
beamlit/authentication/authentication.py,sha256=
|
127
|
+
beamlit/authentication/authentication.py,sha256=ZH3zS7PVa9kw8szZTplwZvCbhBJ-oXHsxEtnAhKjxzM,3409
|
128
128
|
beamlit/authentication/clientcredentials.py,sha256=cxZPPu--CgizwqX0pdfFQ91gJt1EFKwyy-aBB_dXX7I,3990
|
129
129
|
beamlit/authentication/credentials.py,sha256=p_1xenabCbQuRz7BiFk7oTK4uCxAt_zoyku5o-jcKGE,5343
|
130
130
|
beamlit/authentication/device_mode.py,sha256=tmr22gllKOZwBRub_QjF5pYa425x-nE8tQNpZ_EGR6g,3644
|
@@ -147,8 +147,8 @@ beamlit/functions/github/kit/__init__.py,sha256=jBwPqZv6C23_utukohxqXZwrlicNlI7P
|
|
147
147
|
beamlit/functions/github/kit/pull_request.py,sha256=wQVeRBakiqu-2ouflO8p1z7D5u07KNsitwyNRrp0KjM,1357
|
148
148
|
beamlit/functions/math/__init__.py,sha256=wie4WME8jT-WpFRrtu-lDlHW31Mg6K2cwstjkUdLF3o,43
|
149
149
|
beamlit/functions/math/math.py,sha256=CpoLJGwuvwCPGnVC8k9GYuIyvfUYPDQHKlZg3cx-z-A,1049
|
150
|
-
beamlit/functions/mcp/mcp.py,sha256=
|
151
|
-
beamlit/functions/remote/remote.py,sha256=
|
150
|
+
beamlit/functions/mcp/mcp.py,sha256=gXzvUPAKmvGQPHUKTVzMiINukxpw1BV6H8M2iOWvIGU,4348
|
151
|
+
beamlit/functions/remote/remote.py,sha256=x2eHh4oYkWwHuZWwg5XeylY-E9Opa6SzfN_0396ePZw,3775
|
152
152
|
beamlit/functions/search/__init__.py,sha256=5NAthQ9PBwrkNg1FpLRx4flauvv0HyWuwaVS589c1Pw,49
|
153
153
|
beamlit/functions/search/search.py,sha256=8s9ECltq7YE17j6rTxb12uY2EQY4_eTLHmwlIMThI0w,515
|
154
154
|
beamlit/models/__init__.py,sha256=O16oX1-oBJqB5LZEHAfu_hZZZh6_PX2LqZpVl4fNQRs,7730
|
@@ -254,6 +254,6 @@ beamlit/serve/app.py,sha256=OpwPjRdyHZK6J-ziPwhiRDGGa2mvCrFVcBFE6alJVOM,3071
|
|
254
254
|
beamlit/serve/middlewares/__init__.py,sha256=1dVmnOmhAQWvWktqHkKSIX-YoF6fmMU8xkUQuhg_rJU,148
|
255
255
|
beamlit/serve/middlewares/accesslog.py,sha256=Mu4T4_9OvHybjA0ApzZFpgi2C8f3X1NbUk-76v634XM,631
|
256
256
|
beamlit/serve/middlewares/processtime.py,sha256=lDAaIasZ4bwvN-HKHvZpaD9r-yrkVNZYx4abvbjbrCg,411
|
257
|
-
beamlit-0.0.
|
258
|
-
beamlit-0.0.
|
259
|
-
beamlit-0.0.
|
257
|
+
beamlit-0.0.29rc28.dist-info/METADATA,sha256=UVbjc-yv-ZhbPjwVM9Ngq4A0igVBwugwKpP-EoZVodQ,2405
|
258
|
+
beamlit-0.0.29rc28.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
259
|
+
beamlit-0.0.29rc28.dist-info/RECORD,,
|
File without changes
|