beamlit 0.0.28rc25__py3-none-any.whl → 0.0.29__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- beamlit/agents/chain.py +93 -0
- beamlit/agents/decorator.py +14 -4
- beamlit/api/agents/get_agent_trace_ids.py +71 -6
- beamlit/api/functions/get_function_trace_ids.py +71 -6
- beamlit/api/models/get_model_trace_ids.py +71 -6
- beamlit/authentication/authentication.py +14 -17
- beamlit/authentication/clientcredentials.py +1 -1
- beamlit/client.py +14 -13
- beamlit/common/settings.py +8 -10
- beamlit/deploy/deploy.py +5 -5
- beamlit/functions/mcp/mcp.py +26 -18
- beamlit/functions/remote/remote.py +58 -39
- beamlit/models/__init__.py +2 -0
- beamlit/models/trace_ids_response.py +63 -0
- {beamlit-0.0.28rc25.dist-info → beamlit-0.0.29.dist-info}/METADATA +1 -1
- {beamlit-0.0.28rc25.dist-info → beamlit-0.0.29.dist-info}/RECORD +17 -15
- {beamlit-0.0.28rc25.dist-info → beamlit-0.0.29.dist-info}/WHEEL +0 -0
beamlit/agents/chain.py
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
import asyncio
|
2
|
+
from dataclasses import dataclass
|
3
|
+
import warnings
|
4
|
+
from typing import Any, Callable
|
5
|
+
|
6
|
+
import pydantic
|
7
|
+
import typing_extensions as t
|
8
|
+
from beamlit.api.agents import list_agents
|
9
|
+
from beamlit.authentication.authentication import AuthenticatedClient
|
10
|
+
from beamlit.models import Agent, AgentChain
|
11
|
+
from beamlit.run import RunClient
|
12
|
+
from beamlit.common.settings import get_settings
|
13
|
+
from langchain_core.tools.base import BaseTool, ToolException
|
14
|
+
|
15
|
+
|
16
|
+
|
17
|
+
class ChainTool(BaseTool):
|
18
|
+
"""
|
19
|
+
Chain tool
|
20
|
+
"""
|
21
|
+
|
22
|
+
client: RunClient
|
23
|
+
handle_tool_error: bool | str | Callable[[ToolException], str] | None = True
|
24
|
+
|
25
|
+
@t.override
|
26
|
+
def _run(self, *args: t.Any, **kwargs: t.Any) -> t.Any:
|
27
|
+
warnings.warn(
|
28
|
+
"Invoke this tool asynchronousely using `ainvoke`. This method exists only to satisfy standard tests.",
|
29
|
+
stacklevel=1,
|
30
|
+
)
|
31
|
+
return asyncio.run(self._arun(*args, **kwargs))
|
32
|
+
|
33
|
+
@t.override
|
34
|
+
async def _arun(self, *args: t.Any, **kwargs: t.Any) -> t.Any:
|
35
|
+
settings = get_settings()
|
36
|
+
result = self.client.run(
|
37
|
+
"agent",
|
38
|
+
self.name,
|
39
|
+
settings.environment,
|
40
|
+
"POST",
|
41
|
+
json=kwargs,
|
42
|
+
)
|
43
|
+
return result.text
|
44
|
+
|
45
|
+
@t.override
|
46
|
+
@property
|
47
|
+
def tool_call_schema(self) -> type[pydantic.BaseModel]:
|
48
|
+
assert self.args_schema is not None # noqa: S101
|
49
|
+
return self.args_schema
|
50
|
+
|
51
|
+
class ChainInput(pydantic.BaseModel):
|
52
|
+
inputs: str
|
53
|
+
|
54
|
+
@dataclass
|
55
|
+
class ChainToolkit:
|
56
|
+
"""
|
57
|
+
Remote toolkit
|
58
|
+
"""
|
59
|
+
client: AuthenticatedClient
|
60
|
+
chain: list[AgentChain]
|
61
|
+
_chain: list[Agent] | None = None
|
62
|
+
|
63
|
+
model_config = pydantic.ConfigDict(arbitrary_types_allowed=True)
|
64
|
+
|
65
|
+
def initialize(self) -> None:
|
66
|
+
"""Initialize the session and retrieve tools list"""
|
67
|
+
if self._chain is None:
|
68
|
+
agents = list_agents.sync_detailed(
|
69
|
+
client=self.client,
|
70
|
+
).parsed
|
71
|
+
chain_enabled = [chain for chain in self.chain if chain.enabled]
|
72
|
+
agents_chain = []
|
73
|
+
for chain in chain_enabled:
|
74
|
+
agent = [agent for agent in agents if agent.metadata.name == chain.name]
|
75
|
+
if agent:
|
76
|
+
agent[0].spec.description = chain.description or agent[0].spec.description
|
77
|
+
agents_chain.append(agent[0])
|
78
|
+
self._chain = agents_chain
|
79
|
+
|
80
|
+
@t.override
|
81
|
+
def get_tools(self) -> list[BaseTool]:
|
82
|
+
if self._chain is None:
|
83
|
+
raise RuntimeError("Must initialize the toolkit first")
|
84
|
+
|
85
|
+
return [
|
86
|
+
ChainTool(
|
87
|
+
client=RunClient(self.client),
|
88
|
+
name=agent.metadata.name,
|
89
|
+
description=agent.spec.description or "",
|
90
|
+
args_schema=ChainInput,
|
91
|
+
)
|
92
|
+
for agent in self._chain
|
93
|
+
]
|
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 .chain import ChainToolkit
|
20
21
|
from .chat import get_chat_model
|
21
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:
|
@@ -178,7 +184,6 @@ def agent(
|
|
178
184
|
logger.warn(f"Failed to initialize MCP server {server}: {e!s}")
|
179
185
|
|
180
186
|
if remote_functions:
|
181
|
-
|
182
187
|
for function in remote_functions:
|
183
188
|
try:
|
184
189
|
toolkit = RemoteToolkit(client, function)
|
@@ -187,6 +192,11 @@ def agent(
|
|
187
192
|
except Exception as e:
|
188
193
|
logger.warn(f"Failed to initialize remote function {function}: {e!s}")
|
189
194
|
|
195
|
+
if agent.spec.agent_chain:
|
196
|
+
toolkit = ChainToolkit(client, agent.spec.agent_chain)
|
197
|
+
toolkit.initialize()
|
198
|
+
functions.extend(toolkit.get_tools())
|
199
|
+
|
190
200
|
if override_agent is None and len(functions) == 0:
|
191
201
|
raise ValueError(
|
192
202
|
"You must define at least one function, you can define this function in directory "
|
@@ -5,6 +5,7 @@ import httpx
|
|
5
5
|
|
6
6
|
from ... import errors
|
7
7
|
from ...client import AuthenticatedClient, Client
|
8
|
+
from ...models.trace_ids_response import TraceIdsResponse
|
8
9
|
from ...types import UNSET, Response, Unset
|
9
10
|
|
10
11
|
|
@@ -28,14 +29,22 @@ def _get_kwargs(
|
|
28
29
|
return _kwargs
|
29
30
|
|
30
31
|
|
31
|
-
def _parse_response(
|
32
|
+
def _parse_response(
|
33
|
+
*, client: Union[AuthenticatedClient, Client], response: httpx.Response
|
34
|
+
) -> Optional[TraceIdsResponse]:
|
35
|
+
if response.status_code == 200:
|
36
|
+
response_200 = TraceIdsResponse.from_dict(response.json())
|
37
|
+
|
38
|
+
return response_200
|
32
39
|
if client.raise_on_unexpected_status:
|
33
40
|
raise errors.UnexpectedStatus(response.status_code, response.content)
|
34
41
|
else:
|
35
42
|
return None
|
36
43
|
|
37
44
|
|
38
|
-
def _build_response(
|
45
|
+
def _build_response(
|
46
|
+
*, client: Union[AuthenticatedClient, Client], response: httpx.Response
|
47
|
+
) -> Response[TraceIdsResponse]:
|
39
48
|
return Response(
|
40
49
|
status_code=HTTPStatus(response.status_code),
|
41
50
|
content=response.content,
|
@@ -49,7 +58,7 @@ def sync_detailed(
|
|
49
58
|
*,
|
50
59
|
client: AuthenticatedClient,
|
51
60
|
environment: Union[Unset, str] = UNSET,
|
52
|
-
) -> Response[
|
61
|
+
) -> Response[TraceIdsResponse]:
|
53
62
|
"""Get agent trace IDs
|
54
63
|
|
55
64
|
Args:
|
@@ -61,7 +70,7 @@ def sync_detailed(
|
|
61
70
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
62
71
|
|
63
72
|
Returns:
|
64
|
-
Response[
|
73
|
+
Response[TraceIdsResponse]
|
65
74
|
"""
|
66
75
|
|
67
76
|
kwargs = _get_kwargs(
|
@@ -76,12 +85,39 @@ def sync_detailed(
|
|
76
85
|
return _build_response(client=client, response=response)
|
77
86
|
|
78
87
|
|
88
|
+
def sync(
|
89
|
+
agent_name: str,
|
90
|
+
*,
|
91
|
+
client: AuthenticatedClient,
|
92
|
+
environment: Union[Unset, str] = UNSET,
|
93
|
+
) -> Optional[TraceIdsResponse]:
|
94
|
+
"""Get agent trace IDs
|
95
|
+
|
96
|
+
Args:
|
97
|
+
agent_name (str):
|
98
|
+
environment (Union[Unset, str]):
|
99
|
+
|
100
|
+
Raises:
|
101
|
+
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
102
|
+
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
103
|
+
|
104
|
+
Returns:
|
105
|
+
TraceIdsResponse
|
106
|
+
"""
|
107
|
+
|
108
|
+
return sync_detailed(
|
109
|
+
agent_name=agent_name,
|
110
|
+
client=client,
|
111
|
+
environment=environment,
|
112
|
+
).parsed
|
113
|
+
|
114
|
+
|
79
115
|
async def asyncio_detailed(
|
80
116
|
agent_name: str,
|
81
117
|
*,
|
82
118
|
client: AuthenticatedClient,
|
83
119
|
environment: Union[Unset, str] = UNSET,
|
84
|
-
) -> Response[
|
120
|
+
) -> Response[TraceIdsResponse]:
|
85
121
|
"""Get agent trace IDs
|
86
122
|
|
87
123
|
Args:
|
@@ -93,7 +129,7 @@ async def asyncio_detailed(
|
|
93
129
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
94
130
|
|
95
131
|
Returns:
|
96
|
-
Response[
|
132
|
+
Response[TraceIdsResponse]
|
97
133
|
"""
|
98
134
|
|
99
135
|
kwargs = _get_kwargs(
|
@@ -104,3 +140,32 @@ async def asyncio_detailed(
|
|
104
140
|
response = await client.get_async_httpx_client().request(**kwargs)
|
105
141
|
|
106
142
|
return _build_response(client=client, response=response)
|
143
|
+
|
144
|
+
|
145
|
+
async def asyncio(
|
146
|
+
agent_name: str,
|
147
|
+
*,
|
148
|
+
client: AuthenticatedClient,
|
149
|
+
environment: Union[Unset, str] = UNSET,
|
150
|
+
) -> Optional[TraceIdsResponse]:
|
151
|
+
"""Get agent trace IDs
|
152
|
+
|
153
|
+
Args:
|
154
|
+
agent_name (str):
|
155
|
+
environment (Union[Unset, str]):
|
156
|
+
|
157
|
+
Raises:
|
158
|
+
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
159
|
+
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
160
|
+
|
161
|
+
Returns:
|
162
|
+
TraceIdsResponse
|
163
|
+
"""
|
164
|
+
|
165
|
+
return (
|
166
|
+
await asyncio_detailed(
|
167
|
+
agent_name=agent_name,
|
168
|
+
client=client,
|
169
|
+
environment=environment,
|
170
|
+
)
|
171
|
+
).parsed
|
@@ -5,6 +5,7 @@ import httpx
|
|
5
5
|
|
6
6
|
from ... import errors
|
7
7
|
from ...client import AuthenticatedClient, Client
|
8
|
+
from ...models.trace_ids_response import TraceIdsResponse
|
8
9
|
from ...types import UNSET, Response, Unset
|
9
10
|
|
10
11
|
|
@@ -28,14 +29,22 @@ def _get_kwargs(
|
|
28
29
|
return _kwargs
|
29
30
|
|
30
31
|
|
31
|
-
def _parse_response(
|
32
|
+
def _parse_response(
|
33
|
+
*, client: Union[AuthenticatedClient, Client], response: httpx.Response
|
34
|
+
) -> Optional[TraceIdsResponse]:
|
35
|
+
if response.status_code == 200:
|
36
|
+
response_200 = TraceIdsResponse.from_dict(response.json())
|
37
|
+
|
38
|
+
return response_200
|
32
39
|
if client.raise_on_unexpected_status:
|
33
40
|
raise errors.UnexpectedStatus(response.status_code, response.content)
|
34
41
|
else:
|
35
42
|
return None
|
36
43
|
|
37
44
|
|
38
|
-
def _build_response(
|
45
|
+
def _build_response(
|
46
|
+
*, client: Union[AuthenticatedClient, Client], response: httpx.Response
|
47
|
+
) -> Response[TraceIdsResponse]:
|
39
48
|
return Response(
|
40
49
|
status_code=HTTPStatus(response.status_code),
|
41
50
|
content=response.content,
|
@@ -49,7 +58,7 @@ def sync_detailed(
|
|
49
58
|
*,
|
50
59
|
client: AuthenticatedClient,
|
51
60
|
environment: Union[Unset, str] = UNSET,
|
52
|
-
) -> Response[
|
61
|
+
) -> Response[TraceIdsResponse]:
|
53
62
|
"""Get function trace IDs
|
54
63
|
|
55
64
|
Args:
|
@@ -61,7 +70,7 @@ def sync_detailed(
|
|
61
70
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
62
71
|
|
63
72
|
Returns:
|
64
|
-
Response[
|
73
|
+
Response[TraceIdsResponse]
|
65
74
|
"""
|
66
75
|
|
67
76
|
kwargs = _get_kwargs(
|
@@ -76,12 +85,39 @@ def sync_detailed(
|
|
76
85
|
return _build_response(client=client, response=response)
|
77
86
|
|
78
87
|
|
88
|
+
def sync(
|
89
|
+
function_name: str,
|
90
|
+
*,
|
91
|
+
client: AuthenticatedClient,
|
92
|
+
environment: Union[Unset, str] = UNSET,
|
93
|
+
) -> Optional[TraceIdsResponse]:
|
94
|
+
"""Get function trace IDs
|
95
|
+
|
96
|
+
Args:
|
97
|
+
function_name (str):
|
98
|
+
environment (Union[Unset, str]):
|
99
|
+
|
100
|
+
Raises:
|
101
|
+
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
102
|
+
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
103
|
+
|
104
|
+
Returns:
|
105
|
+
TraceIdsResponse
|
106
|
+
"""
|
107
|
+
|
108
|
+
return sync_detailed(
|
109
|
+
function_name=function_name,
|
110
|
+
client=client,
|
111
|
+
environment=environment,
|
112
|
+
).parsed
|
113
|
+
|
114
|
+
|
79
115
|
async def asyncio_detailed(
|
80
116
|
function_name: str,
|
81
117
|
*,
|
82
118
|
client: AuthenticatedClient,
|
83
119
|
environment: Union[Unset, str] = UNSET,
|
84
|
-
) -> Response[
|
120
|
+
) -> Response[TraceIdsResponse]:
|
85
121
|
"""Get function trace IDs
|
86
122
|
|
87
123
|
Args:
|
@@ -93,7 +129,7 @@ async def asyncio_detailed(
|
|
93
129
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
94
130
|
|
95
131
|
Returns:
|
96
|
-
Response[
|
132
|
+
Response[TraceIdsResponse]
|
97
133
|
"""
|
98
134
|
|
99
135
|
kwargs = _get_kwargs(
|
@@ -104,3 +140,32 @@ async def asyncio_detailed(
|
|
104
140
|
response = await client.get_async_httpx_client().request(**kwargs)
|
105
141
|
|
106
142
|
return _build_response(client=client, response=response)
|
143
|
+
|
144
|
+
|
145
|
+
async def asyncio(
|
146
|
+
function_name: str,
|
147
|
+
*,
|
148
|
+
client: AuthenticatedClient,
|
149
|
+
environment: Union[Unset, str] = UNSET,
|
150
|
+
) -> Optional[TraceIdsResponse]:
|
151
|
+
"""Get function trace IDs
|
152
|
+
|
153
|
+
Args:
|
154
|
+
function_name (str):
|
155
|
+
environment (Union[Unset, str]):
|
156
|
+
|
157
|
+
Raises:
|
158
|
+
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
159
|
+
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
160
|
+
|
161
|
+
Returns:
|
162
|
+
TraceIdsResponse
|
163
|
+
"""
|
164
|
+
|
165
|
+
return (
|
166
|
+
await asyncio_detailed(
|
167
|
+
function_name=function_name,
|
168
|
+
client=client,
|
169
|
+
environment=environment,
|
170
|
+
)
|
171
|
+
).parsed
|
@@ -5,6 +5,7 @@ import httpx
|
|
5
5
|
|
6
6
|
from ... import errors
|
7
7
|
from ...client import AuthenticatedClient, Client
|
8
|
+
from ...models.trace_ids_response import TraceIdsResponse
|
8
9
|
from ...types import UNSET, Response, Unset
|
9
10
|
|
10
11
|
|
@@ -28,14 +29,22 @@ def _get_kwargs(
|
|
28
29
|
return _kwargs
|
29
30
|
|
30
31
|
|
31
|
-
def _parse_response(
|
32
|
+
def _parse_response(
|
33
|
+
*, client: Union[AuthenticatedClient, Client], response: httpx.Response
|
34
|
+
) -> Optional[TraceIdsResponse]:
|
35
|
+
if response.status_code == 200:
|
36
|
+
response_200 = TraceIdsResponse.from_dict(response.json())
|
37
|
+
|
38
|
+
return response_200
|
32
39
|
if client.raise_on_unexpected_status:
|
33
40
|
raise errors.UnexpectedStatus(response.status_code, response.content)
|
34
41
|
else:
|
35
42
|
return None
|
36
43
|
|
37
44
|
|
38
|
-
def _build_response(
|
45
|
+
def _build_response(
|
46
|
+
*, client: Union[AuthenticatedClient, Client], response: httpx.Response
|
47
|
+
) -> Response[TraceIdsResponse]:
|
39
48
|
return Response(
|
40
49
|
status_code=HTTPStatus(response.status_code),
|
41
50
|
content=response.content,
|
@@ -49,7 +58,7 @@ def sync_detailed(
|
|
49
58
|
*,
|
50
59
|
client: AuthenticatedClient,
|
51
60
|
environment: Union[Unset, str] = UNSET,
|
52
|
-
) -> Response[
|
61
|
+
) -> Response[TraceIdsResponse]:
|
53
62
|
"""Get model trace IDs
|
54
63
|
|
55
64
|
Args:
|
@@ -61,7 +70,7 @@ def sync_detailed(
|
|
61
70
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
62
71
|
|
63
72
|
Returns:
|
64
|
-
Response[
|
73
|
+
Response[TraceIdsResponse]
|
65
74
|
"""
|
66
75
|
|
67
76
|
kwargs = _get_kwargs(
|
@@ -76,12 +85,39 @@ def sync_detailed(
|
|
76
85
|
return _build_response(client=client, response=response)
|
77
86
|
|
78
87
|
|
88
|
+
def sync(
|
89
|
+
model_name: str,
|
90
|
+
*,
|
91
|
+
client: AuthenticatedClient,
|
92
|
+
environment: Union[Unset, str] = UNSET,
|
93
|
+
) -> Optional[TraceIdsResponse]:
|
94
|
+
"""Get model trace IDs
|
95
|
+
|
96
|
+
Args:
|
97
|
+
model_name (str):
|
98
|
+
environment (Union[Unset, str]):
|
99
|
+
|
100
|
+
Raises:
|
101
|
+
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
102
|
+
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
103
|
+
|
104
|
+
Returns:
|
105
|
+
TraceIdsResponse
|
106
|
+
"""
|
107
|
+
|
108
|
+
return sync_detailed(
|
109
|
+
model_name=model_name,
|
110
|
+
client=client,
|
111
|
+
environment=environment,
|
112
|
+
).parsed
|
113
|
+
|
114
|
+
|
79
115
|
async def asyncio_detailed(
|
80
116
|
model_name: str,
|
81
117
|
*,
|
82
118
|
client: AuthenticatedClient,
|
83
119
|
environment: Union[Unset, str] = UNSET,
|
84
|
-
) -> Response[
|
120
|
+
) -> Response[TraceIdsResponse]:
|
85
121
|
"""Get model trace IDs
|
86
122
|
|
87
123
|
Args:
|
@@ -93,7 +129,7 @@ async def asyncio_detailed(
|
|
93
129
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
94
130
|
|
95
131
|
Returns:
|
96
|
-
Response[
|
132
|
+
Response[TraceIdsResponse]
|
97
133
|
"""
|
98
134
|
|
99
135
|
kwargs = _get_kwargs(
|
@@ -104,3 +140,32 @@ async def asyncio_detailed(
|
|
104
140
|
response = await client.get_async_httpx_client().request(**kwargs)
|
105
141
|
|
106
142
|
return _build_response(client=client, response=response)
|
143
|
+
|
144
|
+
|
145
|
+
async def asyncio(
|
146
|
+
model_name: str,
|
147
|
+
*,
|
148
|
+
client: AuthenticatedClient,
|
149
|
+
environment: Union[Unset, str] = UNSET,
|
150
|
+
) -> Optional[TraceIdsResponse]:
|
151
|
+
"""Get model trace IDs
|
152
|
+
|
153
|
+
Args:
|
154
|
+
model_name (str):
|
155
|
+
environment (Union[Unset, str]):
|
156
|
+
|
157
|
+
Raises:
|
158
|
+
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
159
|
+
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
160
|
+
|
161
|
+
Returns:
|
162
|
+
TraceIdsResponse
|
163
|
+
"""
|
164
|
+
|
165
|
+
return (
|
166
|
+
await asyncio_detailed(
|
167
|
+
model_name=model_name,
|
168
|
+
client=client,
|
169
|
+
environment=environment,
|
170
|
+
)
|
171
|
+
).parsed
|
@@ -1,20 +1,15 @@
|
|
1
|
+
import os
|
1
2
|
from dataclasses import dataclass
|
2
3
|
from typing import Dict, Generator
|
3
|
-
import os
|
4
|
-
|
5
|
-
from httpx import Auth, Request, Response
|
6
4
|
|
7
5
|
from beamlit.common.settings import Settings, get_settings
|
6
|
+
from httpx import Auth, Request, Response
|
8
7
|
|
9
8
|
from ..client import AuthenticatedClient
|
10
9
|
from .apikey import ApiKeyProvider
|
11
10
|
from .clientcredentials import ClientCredentials
|
12
|
-
from .credentials import (
|
13
|
-
|
14
|
-
current_context,
|
15
|
-
load_credentials,
|
16
|
-
load_credentials_from_settings,
|
17
|
-
)
|
11
|
+
from .credentials import (Credentials, current_context, load_credentials,
|
12
|
+
load_credentials_from_settings)
|
18
13
|
from .device_mode import BearerToken
|
19
14
|
|
20
15
|
|
@@ -27,13 +22,15 @@ class PublicProvider(Auth):
|
|
27
22
|
class RunClientWithCredentials:
|
28
23
|
credentials: Credentials
|
29
24
|
workspace: str
|
30
|
-
api_url: str = "
|
31
|
-
run_url: str = "
|
25
|
+
api_url: str = ""
|
26
|
+
run_url: str = ""
|
32
27
|
|
33
28
|
def __post_init__(self):
|
34
|
-
|
35
|
-
|
36
|
-
|
29
|
+
from ..common.settings import get_settings
|
30
|
+
|
31
|
+
settings = get_settings()
|
32
|
+
self.api_url = settings.base_url
|
33
|
+
self.run_url = settings.run_url
|
37
34
|
|
38
35
|
|
39
36
|
def new_client_from_settings(settings: Settings):
|
@@ -47,15 +44,15 @@ def new_client_from_settings(settings: Settings):
|
|
47
44
|
|
48
45
|
|
49
46
|
def new_client():
|
47
|
+
settings = get_settings()
|
50
48
|
context = current_context()
|
51
|
-
if context.workspace:
|
49
|
+
if context.workspace and not settings.authentication.client.credentials:
|
52
50
|
credentials = load_credentials(context.workspace)
|
53
51
|
client_config = RunClientWithCredentials(
|
54
52
|
credentials=credentials,
|
55
53
|
workspace=context.workspace,
|
56
54
|
)
|
57
55
|
else:
|
58
|
-
settings = get_settings()
|
59
56
|
credentials = load_credentials_from_settings(settings)
|
60
57
|
client_config = RunClientWithCredentials(
|
61
58
|
credentials=credentials,
|
@@ -80,7 +77,7 @@ def new_client_with_credentials(config: RunClientWithCredentials):
|
|
80
77
|
|
81
78
|
def get_authentication_headers(settings: Settings) -> Dict[str, str]:
|
82
79
|
context = current_context()
|
83
|
-
if context.workspace:
|
80
|
+
if context.workspace and not settings.authentication.client.credentials:
|
84
81
|
credentials = load_credentials(context.workspace)
|
85
82
|
else:
|
86
83
|
settings = get_settings()
|
@@ -37,7 +37,7 @@ class ClientCredentials(Auth):
|
|
37
37
|
def refresh_if_needed(self) -> Optional[Exception]:
|
38
38
|
settings = get_settings()
|
39
39
|
if self.credentials.client_credentials and not self.credentials.refresh_token:
|
40
|
-
headers = {"Authorization": f"Basic {self.credentials.client_credentials}"}
|
40
|
+
headers = {"Authorization": f"Basic {self.credentials.client_credentials}", "Content-Type": "application/json"}
|
41
41
|
body = {"grant_type": "client_credentials"}
|
42
42
|
response = requests.post(f"{settings.base_url}/oauth/token", headers=headers, json=body)
|
43
43
|
response.raise_for_status()
|
beamlit/client.py
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
import os
|
2
1
|
import ssl
|
3
2
|
from typing import Any, Optional, Union
|
4
3
|
|
@@ -38,13 +37,8 @@ class Client:
|
|
38
37
|
|
39
38
|
"""
|
40
39
|
|
41
|
-
# Determine the base URL based on the environment
|
42
|
-
default_base_url = "https://api.beamlit.com/v0"
|
43
|
-
if os.getenv("BL_ENV") == "dev":
|
44
|
-
default_base_url = "https://api.beamlit.dev/v0"
|
45
|
-
|
46
40
|
raise_on_unexpected_status: bool = field(default=True, kw_only=True)
|
47
|
-
_base_url: str = field(alias="base_url", default=
|
41
|
+
_base_url: str = field(alias="base_url", default="")
|
48
42
|
_cookies: dict[str, str] = field(factory=dict, kw_only=True, alias="cookies")
|
49
43
|
_headers: dict[str, str] = field(factory=dict, kw_only=True, alias="headers")
|
50
44
|
_provider: httpx.Auth = field(default=None, alias="provider")
|
@@ -55,6 +49,12 @@ class Client:
|
|
55
49
|
_client: Optional[httpx.Client] = field(default=None, init=False)
|
56
50
|
_async_client: Optional[httpx.AsyncClient] = field(default=None, init=False)
|
57
51
|
|
52
|
+
def __post_init__(self):
|
53
|
+
from .common.settings import get_settings
|
54
|
+
|
55
|
+
settings = get_settings()
|
56
|
+
self._base_url = settings.base_url
|
57
|
+
|
58
58
|
def with_headers(self, headers: dict[str, str]) -> "Client":
|
59
59
|
"""Get a new client matching this one with additional headers"""
|
60
60
|
if self._client is not None:
|
@@ -175,13 +175,8 @@ class AuthenticatedClient:
|
|
175
175
|
provider: AuthProvider to use for authentication
|
176
176
|
"""
|
177
177
|
|
178
|
-
# Determine the base URL based on the environment
|
179
|
-
default_base_url = "https://api.beamlit.com/v0"
|
180
|
-
if os.getenv("BL_ENV") == "dev":
|
181
|
-
default_base_url = "https://api.beamlit.dev/v0"
|
182
|
-
|
183
178
|
raise_on_unexpected_status: bool = field(default=True, kw_only=True)
|
184
|
-
_base_url: str = field(alias="base_url", default=
|
179
|
+
_base_url: str = field(alias="base_url", default="")
|
185
180
|
_cookies: dict[str, str] = field(factory=dict, kw_only=True, alias="cookies")
|
186
181
|
_headers: dict[str, str] = field(factory=dict, kw_only=True, alias="headers")
|
187
182
|
_provider: httpx.Auth = field(default=None, alias="provider")
|
@@ -192,6 +187,12 @@ class AuthenticatedClient:
|
|
192
187
|
_client: Optional[httpx.Client] = field(default=None, init=False)
|
193
188
|
_async_client: Optional[httpx.AsyncClient] = field(default=None, init=False)
|
194
189
|
|
190
|
+
def __post_init__(self):
|
191
|
+
from .common.settings import get_settings
|
192
|
+
|
193
|
+
settings = get_settings()
|
194
|
+
self._base_url = settings.base_url
|
195
|
+
|
195
196
|
def with_headers(self, headers: dict[str, str]) -> "AuthenticatedClient":
|
196
197
|
"""Get a new client matching this one with additional headers"""
|
197
198
|
if self._client is not None:
|
beamlit/common/settings.py
CHANGED
@@ -18,11 +18,6 @@ from pydantic_settings import (BaseSettings, PydanticBaseSettingsSource,
|
|
18
18
|
global SETTINGS
|
19
19
|
SETTINGS = None
|
20
20
|
|
21
|
-
|
22
|
-
def get_settings():
|
23
|
-
return SETTINGS
|
24
|
-
|
25
|
-
|
26
21
|
class SettingsAgent(BaseSettings):
|
27
22
|
agent: Union[None, CompiledGraph, BaseChatModel] = None
|
28
23
|
chain: Union[Unset, list[Agent]] = UNSET
|
@@ -65,7 +60,7 @@ class Settings(BaseSettings):
|
|
65
60
|
base_url: str = Field(default="https://api.beamlit.com/v0")
|
66
61
|
run_url: str = Field(default="https://run.beamlit.com")
|
67
62
|
mcp_hub_url: str = Field(default="https://mcp-hub-server.beamlit.workers.com")
|
68
|
-
registry_url: str = Field(default="https://
|
63
|
+
registry_url: str = Field(default="https://us.registry.beamlit.com")
|
69
64
|
log_level: str = Field(default="INFO")
|
70
65
|
agent: SettingsAgent = SettingsAgent()
|
71
66
|
server: SettingsServer = SettingsServer()
|
@@ -74,10 +69,10 @@ class Settings(BaseSettings):
|
|
74
69
|
def __init__(self, **data):
|
75
70
|
super().__init__(**data)
|
76
71
|
if os.getenv('BL_ENV') == 'dev':
|
77
|
-
self.base_url = "https://api.beamlit.dev/v0"
|
78
|
-
self.run_url = "https://run.beamlit.dev"
|
79
|
-
self.mcp_hub_url = "https://mcp-hub-server.beamlit.workers.dev"
|
80
|
-
self.registry_url = "https://
|
72
|
+
self.base_url = os.getenv('BL_BASE_URL') or "https://api.beamlit.dev/v0"
|
73
|
+
self.run_url = os.getenv('BL_RUN_URL') or "https://run.beamlit.dev"
|
74
|
+
self.mcp_hub_url = os.getenv('BL_MCP_HUB_URL') or "https://mcp-hub-server.beamlit.workers.dev"
|
75
|
+
self.registry_url = os.getenv('BL_REGISTRY_URL') or "https://eu.registry.beamlit.dev"
|
81
76
|
|
82
77
|
@classmethod
|
83
78
|
def settings_customise_sources(
|
@@ -96,6 +91,9 @@ class Settings(BaseSettings):
|
|
96
91
|
init_settings,
|
97
92
|
)
|
98
93
|
|
94
|
+
def get_settings() -> Settings:
|
95
|
+
return SETTINGS
|
96
|
+
|
99
97
|
|
100
98
|
def init_agent(
|
101
99
|
client: AuthenticatedClient,
|
beamlit/deploy/deploy.py
CHANGED
@@ -29,8 +29,8 @@ def set_default_values(resource: Resource, deployment: Agent | Function):
|
|
29
29
|
deployment.metadata.environment = settings.environment
|
30
30
|
if not deployment.metadata.name:
|
31
31
|
deployment.metadata.name = resource.name
|
32
|
-
if not deployment.metadata.
|
33
|
-
deployment.metadata.
|
32
|
+
if not deployment.metadata.display_name:
|
33
|
+
deployment.metadata.display_name = deployment.metadata.name
|
34
34
|
if not deployment.spec.description:
|
35
35
|
deployment.spec.description = get_description(None, resource)
|
36
36
|
if not deployment.spec.runtime:
|
@@ -111,14 +111,14 @@ apiVersion: beamlit.com/v1alpha1
|
|
111
111
|
kind: Agent
|
112
112
|
metadata:
|
113
113
|
name: {agent.metadata.name}
|
114
|
-
displayName: {agent.metadata.
|
114
|
+
displayName: {agent.metadata.display_name or agent.metadata.name}
|
115
115
|
environment: {settings.environment}
|
116
116
|
workspace: {settings.workspace}
|
117
117
|
spec:
|
118
118
|
enabled: true
|
119
119
|
policies: [{", ".join(agent.spec.policies or [])}]
|
120
120
|
functions: [{", ".join([f"{function.metadata.name}" for (_, function) in functions])}]
|
121
|
-
agentChain: {format_agent_chain(agent.spec.
|
121
|
+
agentChain: {format_agent_chain(agent.spec.agent_chain)}
|
122
122
|
model: {agent.spec.model}
|
123
123
|
runtime:
|
124
124
|
image: {agent.spec.runtime.image}
|
@@ -145,7 +145,7 @@ apiVersion: beamlit.com/v1alpha1
|
|
145
145
|
kind: Function
|
146
146
|
metadata:
|
147
147
|
name: {function.metadata.name}
|
148
|
-
displayName: {function.metadata.
|
148
|
+
displayName: {function.metadata.display_name or function.metadata.name}
|
149
149
|
environment: {settings.environment}
|
150
150
|
spec:
|
151
151
|
enabled: true
|
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,33 +1,37 @@
|
|
1
1
|
import asyncio
|
2
|
-
import urllib.parse
|
3
2
|
import warnings
|
4
|
-
from
|
3
|
+
from dataclasses import dataclass
|
4
|
+
from typing import Callable, Literal
|
5
5
|
|
6
6
|
import pydantic
|
7
|
-
import pydantic_core
|
8
7
|
import typing_extensions as t
|
9
8
|
from beamlit.api.functions import get_function
|
10
9
|
from beamlit.authentication.authentication import AuthenticatedClient
|
11
|
-
from beamlit.
|
12
|
-
from
|
13
|
-
from
|
14
|
-
from
|
15
|
-
|
16
|
-
|
17
|
-
def
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
10
|
+
from beamlit.common.settings import get_settings
|
11
|
+
from beamlit.models import Function, StoreFunctionParameter
|
12
|
+
from beamlit.run import RunClient
|
13
|
+
from langchain_core.tools.base import BaseTool, ToolException
|
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
|
+
)
|
31
35
|
|
32
36
|
|
33
37
|
class RemoteTool(BaseTool):
|
@@ -35,7 +39,9 @@ class RemoteTool(BaseTool):
|
|
35
39
|
Remote tool
|
36
40
|
"""
|
37
41
|
|
38
|
-
client:
|
42
|
+
client: RunClient
|
43
|
+
resource_name: str
|
44
|
+
kit: bool = False
|
39
45
|
handle_tool_error: bool | str | Callable[[ToolException], str] | None = True
|
40
46
|
|
41
47
|
@t.override
|
@@ -48,12 +54,18 @@ class RemoteTool(BaseTool):
|
|
48
54
|
|
49
55
|
@t.override
|
50
56
|
async def _arun(self, *args: t.Any, **kwargs: t.Any) -> t.Any:
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
+
settings = get_settings()
|
58
|
+
body = {**kwargs}
|
59
|
+
if self.kit:
|
60
|
+
body["name"] = self.name
|
61
|
+
result = self.client.run(
|
62
|
+
"function",
|
63
|
+
self.resource_name,
|
64
|
+
settings.environment,
|
65
|
+
"POST",
|
66
|
+
json=body
|
67
|
+
)
|
68
|
+
return result.text
|
57
69
|
|
58
70
|
@t.override
|
59
71
|
@property
|
@@ -61,7 +73,8 @@ class RemoteTool(BaseTool):
|
|
61
73
|
assert self.args_schema is not None # noqa: S101
|
62
74
|
return self.args_schema
|
63
75
|
|
64
|
-
|
76
|
+
@dataclass
|
77
|
+
class RemoteToolkit:
|
65
78
|
"""
|
66
79
|
Remote toolkit
|
67
80
|
"""
|
@@ -75,29 +88,35 @@ class RemoteToolkit(BaseToolkit):
|
|
75
88
|
def initialize(self) -> None:
|
76
89
|
"""Initialize the session and retrieve tools list"""
|
77
90
|
if self._function is None:
|
78
|
-
self._function = get_function(self.function, client=self.client)
|
91
|
+
self._function = get_function.sync_detailed(self.function, client=self.client).parsed
|
79
92
|
|
80
93
|
@t.override
|
81
94
|
def get_tools(self) -> list[BaseTool]:
|
82
|
-
if self.
|
95
|
+
if self._function is None:
|
83
96
|
raise RuntimeError("Must initialize the toolkit first")
|
84
97
|
|
85
98
|
if self._function.spec.kit:
|
86
99
|
return [
|
87
100
|
RemoteTool(
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
101
|
+
client=RunClient(self.client),
|
102
|
+
name=func.name,
|
103
|
+
resource_name=self._function.metadata.name,
|
104
|
+
kit=True,
|
105
|
+
description=func.description or "",
|
106
|
+
args_schema=create_dynamic_schema(func.name, func.parameters),
|
92
107
|
)
|
93
108
|
for func in self._function.spec.kit
|
94
109
|
]
|
95
110
|
|
96
111
|
return [
|
97
112
|
RemoteTool(
|
98
|
-
client=self.client,
|
113
|
+
client=RunClient(self.client),
|
99
114
|
name=self._function.metadata.name,
|
115
|
+
resource_name=self._function.metadata.name,
|
100
116
|
description=self._function.spec.description or "",
|
101
|
-
args_schema=
|
117
|
+
args_schema=create_dynamic_schema(
|
118
|
+
self._function.metadata.name,
|
119
|
+
self._function.spec.parameters
|
120
|
+
),
|
102
121
|
)
|
103
122
|
]
|
beamlit/models/__init__.py
CHANGED
@@ -93,6 +93,7 @@ from .store_function_kit import StoreFunctionKit
|
|
93
93
|
from .store_function_labels import StoreFunctionLabels
|
94
94
|
from .store_function_parameter import StoreFunctionParameter
|
95
95
|
from .time_fields import TimeFields
|
96
|
+
from .trace_ids_response import TraceIdsResponse
|
96
97
|
from .update_workspace_service_account_body import UpdateWorkspaceServiceAccountBody
|
97
98
|
from .update_workspace_service_account_response_200 import UpdateWorkspaceServiceAccountResponse200
|
98
99
|
from .update_workspace_user_role_body import UpdateWorkspaceUserRoleBody
|
@@ -191,6 +192,7 @@ __all__ = (
|
|
191
192
|
"StoreFunctionLabels",
|
192
193
|
"StoreFunctionParameter",
|
193
194
|
"TimeFields",
|
195
|
+
"TraceIdsResponse",
|
194
196
|
"UpdateWorkspaceServiceAccountBody",
|
195
197
|
"UpdateWorkspaceServiceAccountResponse200",
|
196
198
|
"UpdateWorkspaceUserRoleBody",
|
@@ -0,0 +1,63 @@
|
|
1
|
+
from typing import Any, TypeVar, Union, cast
|
2
|
+
|
3
|
+
from attrs import define as _attrs_define
|
4
|
+
from attrs import field as _attrs_field
|
5
|
+
|
6
|
+
from ..types import UNSET, Unset
|
7
|
+
|
8
|
+
T = TypeVar("T", bound="TraceIdsResponse")
|
9
|
+
|
10
|
+
|
11
|
+
@_attrs_define
|
12
|
+
class TraceIdsResponse:
|
13
|
+
"""Response containing trace IDs
|
14
|
+
|
15
|
+
Attributes:
|
16
|
+
trace_ids (Union[Unset, list[str]]): List of trace IDs
|
17
|
+
"""
|
18
|
+
|
19
|
+
trace_ids: Union[Unset, list[str]] = UNSET
|
20
|
+
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
|
21
|
+
|
22
|
+
def to_dict(self) -> dict[str, Any]:
|
23
|
+
trace_ids: Union[Unset, list[str]] = UNSET
|
24
|
+
if not isinstance(self.trace_ids, Unset):
|
25
|
+
trace_ids = self.trace_ids
|
26
|
+
|
27
|
+
field_dict: dict[str, Any] = {}
|
28
|
+
field_dict.update(self.additional_properties)
|
29
|
+
field_dict.update({})
|
30
|
+
if trace_ids is not UNSET:
|
31
|
+
field_dict["trace_ids"] = trace_ids
|
32
|
+
|
33
|
+
return field_dict
|
34
|
+
|
35
|
+
@classmethod
|
36
|
+
def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T:
|
37
|
+
if not src_dict:
|
38
|
+
return None
|
39
|
+
d = src_dict.copy()
|
40
|
+
trace_ids = cast(list[str], d.pop("trace_ids", UNSET))
|
41
|
+
|
42
|
+
trace_ids_response = cls(
|
43
|
+
trace_ids=trace_ids,
|
44
|
+
)
|
45
|
+
|
46
|
+
trace_ids_response.additional_properties = d
|
47
|
+
return trace_ids_response
|
48
|
+
|
49
|
+
@property
|
50
|
+
def additional_keys(self) -> list[str]:
|
51
|
+
return list(self.additional_properties.keys())
|
52
|
+
|
53
|
+
def __getitem__(self, key: str) -> Any:
|
54
|
+
return self.additional_properties[key]
|
55
|
+
|
56
|
+
def __setitem__(self, key: str, value: Any) -> None:
|
57
|
+
self.additional_properties[key] = value
|
58
|
+
|
59
|
+
def __delitem__(self, key: str) -> None:
|
60
|
+
del self.additional_properties[key]
|
61
|
+
|
62
|
+
def __contains__(self, key: str) -> bool:
|
63
|
+
return key in self.additional_properties
|
@@ -1,12 +1,13 @@
|
|
1
1
|
beamlit/__init__.py,sha256=545gFC-wLLwUktWcOAjUWe_Glha40tBetRTOYSfHnbI,164
|
2
|
-
beamlit/client.py,sha256=
|
2
|
+
beamlit/client.py,sha256=PnR6ybZk5dLIJPnDKAf2epHOeQC_7yL0fG4muvphHjA,12695
|
3
3
|
beamlit/errors.py,sha256=gO8GBmKqmSNgAg-E5oT-oOyxztvp7V_6XG7OUTT15q0,546
|
4
4
|
beamlit/py.typed,sha256=8ZJUsxZiuOy1oJeVhsTWQhTG_6pTVHVXk5hJL79ebTk,25
|
5
5
|
beamlit/run.py,sha256=RLwMv5f_S8lw7Wq7O6DvEcOl0nGYh769qjGl_SmR9Z0,1338
|
6
6
|
beamlit/types.py,sha256=E1hhDh_zXfsSQ0NCt9-uw90_Mr5iIlsdfnfvxv5HarU,1005
|
7
7
|
beamlit/agents/__init__.py,sha256=nf1iwQwGtCG6nDqyVhxfWoqR6dv6X3bvSpCeqkTCFaM,101
|
8
|
+
beamlit/agents/chain.py,sha256=HzBs3nI4xaH86I_r-M-HGGp6roXsJxMx-qXl_GrJaY0,2831
|
8
9
|
beamlit/agents/chat.py,sha256=gVyv4FGBdQTDhdutX8l64OUNa6Fdqaw4eCfEDRH0IPQ,3558
|
9
|
-
beamlit/agents/decorator.py,sha256=
|
10
|
+
beamlit/agents/decorator.py,sha256=4KxPcu6hPoB__1OdzpEJVD5N3QVa_syKd_Y6n6lVEjQ,9715
|
10
11
|
beamlit/api/__init__.py,sha256=zTSiG_ujSjAqWPyc435YXaX9XTlpMjiJWBbV-f-YtdA,45
|
11
12
|
beamlit/api/agents/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
12
13
|
beamlit/api/agents/create_agent.py,sha256=t5Pr62My2EhQlcIY71MrI73-0_q5Djr3a_Ybt9MIiQQ,3587
|
@@ -17,7 +18,7 @@ beamlit/api/agents/get_agent.py,sha256=IBMiNb36CyNKKyW-RvMSakmOaGrP2hSm3HRa_Gm_c
|
|
17
18
|
beamlit/api/agents/get_agent_environment_logs.py,sha256=Fdd_mvlJXO17BQHbnl0YpUbXcX-1BsuZI2WKz6cgacA,3759
|
18
19
|
beamlit/api/agents/get_agent_history.py,sha256=sDKZQhul8wrSbuRY8WNI6jRNYgFcYtCnaU2fgR1owM8,3846
|
19
20
|
beamlit/api/agents/get_agent_metrics.py,sha256=IRdex5XAekCHSep6T7KQHB9T1J1f9egDx-MaiNynRVU,4344
|
20
|
-
beamlit/api/agents/get_agent_trace_ids.py,sha256=
|
21
|
+
beamlit/api/agents/get_agent_trace_ids.py,sha256=nCYXzCCmu8VXeLvPRX8Rc6N2JKMLVTTObbKtiCOzIg0,4365
|
21
22
|
beamlit/api/agents/list_agent_history.py,sha256=ZMTG5PSSkfd4OLmVHDIvDZy13bElrhQivF7QtBDLK9w,3775
|
22
23
|
beamlit/api/agents/list_agents.py,sha256=d6j_LM-8--2nfTHFjueRkoimHf02RRMAOWTpt8anJGg,4101
|
23
24
|
beamlit/api/agents/put_agent_history.py,sha256=lt1_9yFW_vEgeS_jlh-4EumgbTZCdcZYy9GbA91gewU,4590
|
@@ -42,7 +43,7 @@ beamlit/api/functions/delete_function.py,sha256=dzCBAL50Yg18bDUpcC1COjwFstnfBpqt
|
|
42
43
|
beamlit/api/functions/get_function.py,sha256=U4dXy47eKQh7spED7hyyHOepj6bU2U6QFJ0a2RS2y_8,4301
|
43
44
|
beamlit/api/functions/get_function_environment_logs.py,sha256=Ia7bDcx8k7qCBhxsm8jdDSbYGKwdTDYhkAcgv25Zz-o,3816
|
44
45
|
beamlit/api/functions/get_function_metrics.py,sha256=8FC7OCyj2QTXKRHyY7BPKfF2EAzXw0rg-r8yM19fQSc,4413
|
45
|
-
beamlit/api/functions/get_function_trace_ids.py,sha256=
|
46
|
+
beamlit/api/functions/get_function_trace_ids.py,sha256=Sz0DNr7K7z0Qzs9wJ8KYb7C8_vZj1aqoFk38MRYC_Xw,4434
|
46
47
|
beamlit/api/functions/list_functions.py,sha256=Z9PaBzpRCv4cfEMSiBaVLnKzRoWCBys4jOXXBWOzEU8,4167
|
47
48
|
beamlit/api/functions/update_function.py,sha256=sH-Oy2epz-X-59_eDnazzeeUsZMVNqG5J8VPe6nYJkg,4084
|
48
49
|
beamlit/api/history/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -77,7 +78,7 @@ beamlit/api/models/delete_model.py,sha256=4uENeuBKoIooCfniM1uZFjScqgHzlEDxl7aLjA
|
|
77
78
|
beamlit/api/models/get_model.py,sha256=sTE7fGpJ91svBMSKy7PGySqSOVy5g1YH3oHjhWbMr9s,4285
|
78
79
|
beamlit/api/models/get_model_environment_logs.py,sha256=Xi4c3I0y7y_JbqUDeZEH64oLom9DZ1Uk735j47QvDT0,3939
|
79
80
|
beamlit/api/models/get_model_metrics.py,sha256=06BcFFYS1Ml0tifIbDos9EqH6gSgGnwssKq75vhO5eU,4516
|
80
|
-
beamlit/api/models/get_model_trace_ids.py,sha256=
|
81
|
+
beamlit/api/models/get_model_trace_ids.py,sha256=xIUVeVf3oa1j8m3x7PO58bB3P3y_5mskKEOpWeJteIk,4365
|
81
82
|
beamlit/api/models/list_models.py,sha256=Keqg_qyTTGB-aJNA6JiMGnLdNwUSLIkzr08sdhhXxo4,4297
|
82
83
|
beamlit/api/models/release_model.py,sha256=ik1HHjOUVnaVJEvbbSS1ByQ2TMzkkUbNiGUXmlTiwBo,3893
|
83
84
|
beamlit/api/models/update_model.py,sha256=odMblGfUK6EAJHpu5mWUtpSNjFB8NvyTgqDp0JUygDA,4521
|
@@ -123,8 +124,8 @@ beamlit/api/workspaces/update_workspace.py,sha256=qa5DV2UJSUYuB_ibALb4E9ghKpT1Ha
|
|
123
124
|
beamlit/api/workspaces/update_workspace_user_role.py,sha256=Yn9iuJ4tKtauzBiJyU4-wYUMS9g98X2Om8zs7UkzrY8,4917
|
124
125
|
beamlit/authentication/__init__.py,sha256=wiXqRbc7E-ulrH_ueA9duOGFvXeo7-RvhSD1XbFogMo,1020
|
125
126
|
beamlit/authentication/apikey.py,sha256=KNBTgdi0VBzBAAmSwU2X1QoB58vRbg8wkXb8-GTZCQo,657
|
126
|
-
beamlit/authentication/authentication.py,sha256=
|
127
|
-
beamlit/authentication/clientcredentials.py,sha256=
|
127
|
+
beamlit/authentication/authentication.py,sha256=8R-3WdQSykNjCbebAW2p8Glvw5nlAmSEZr6Ylo-vPuc,3377
|
128
|
+
beamlit/authentication/clientcredentials.py,sha256=cxZPPu--CgizwqX0pdfFQ91gJt1EFKwyy-aBB_dXX7I,3990
|
128
129
|
beamlit/authentication/credentials.py,sha256=p_1xenabCbQuRz7BiFk7oTK4uCxAt_zoyku5o-jcKGE,5343
|
129
130
|
beamlit/authentication/device_mode.py,sha256=tmr22gllKOZwBRub_QjF5pYa425x-nE8tQNpZ_EGR6g,3644
|
130
131
|
beamlit/common/__init__.py,sha256=yDoMJDKj-xjTGl7U1YI59KpWxiOV65HSiUulgO8xdTA,277
|
@@ -132,10 +133,10 @@ beamlit/common/generate.py,sha256=LtdCju_QayRS4lZrrb_0VHqWWvTcv4Mbf-iV1TB_Qko,75
|
|
132
133
|
beamlit/common/instrumentation.py,sha256=MsBDfFcMYqGDiHHj4j5hLHE4EWxZExkhmCeFS3SKzJY,3181
|
133
134
|
beamlit/common/logger.py,sha256=VFRbaZh93n8ZGugeeYKe88IP2nI3g2JNa7XN4j8wVJE,1116
|
134
135
|
beamlit/common/secrets.py,sha256=sid81bOe3LflkMKDHwBsBs9nIju8bp5-v9qU9gkyNMc,212
|
135
|
-
beamlit/common/settings.py,sha256=
|
136
|
+
beamlit/common/settings.py,sha256=bxgQxMV5ncNqDGcWS_Wj3nzOF8FgAmC6alMP2fOdEDU,5895
|
136
137
|
beamlit/common/utils.py,sha256=jouz5igBvT37Xn_e94-foCHyQczVim-UzVcoIF6RWJ4,657
|
137
138
|
beamlit/deploy/__init__.py,sha256=GS7l7Jtm2yKs7iNLKcfjYO-rAhUzggQ3xiYSf3oxLBY,91
|
138
|
-
beamlit/deploy/deploy.py,sha256=
|
139
|
+
beamlit/deploy/deploy.py,sha256=on1i93SdECKrLVRMm3V2BRW5JeolPPq1dJHa4Evp0ns,9188
|
139
140
|
beamlit/deploy/format.py,sha256=78tOoeNPJ8969AhQTeFlIwZgQ3un8gmTSMmrYbRQSds,1818
|
140
141
|
beamlit/deploy/parser.py,sha256=uT-bezLX6yjyxr1ogm1GXIT_MeREqHDUBlKiyav5qg0,6912
|
141
142
|
beamlit/functions/__init__.py,sha256=_RPG1Bfg54JGdIPnViAU6n9zD7E1cDNsdXi8oYGskzE,138
|
@@ -146,11 +147,11 @@ beamlit/functions/github/kit/__init__.py,sha256=jBwPqZv6C23_utukohxqXZwrlicNlI7P
|
|
146
147
|
beamlit/functions/github/kit/pull_request.py,sha256=wQVeRBakiqu-2ouflO8p1z7D5u07KNsitwyNRrp0KjM,1357
|
147
148
|
beamlit/functions/math/__init__.py,sha256=wie4WME8jT-WpFRrtu-lDlHW31Mg6K2cwstjkUdLF3o,43
|
148
149
|
beamlit/functions/math/math.py,sha256=CpoLJGwuvwCPGnVC8k9GYuIyvfUYPDQHKlZg3cx-z-A,1049
|
149
|
-
beamlit/functions/mcp/mcp.py,sha256=
|
150
|
-
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
|
151
152
|
beamlit/functions/search/__init__.py,sha256=5NAthQ9PBwrkNg1FpLRx4flauvv0HyWuwaVS589c1Pw,49
|
152
153
|
beamlit/functions/search/search.py,sha256=8s9ECltq7YE17j6rTxb12uY2EQY4_eTLHmwlIMThI0w,515
|
153
|
-
beamlit/models/__init__.py,sha256=
|
154
|
+
beamlit/models/__init__.py,sha256=0BldOldXzMn1A6d1bOhsU8mk7i3uRmh33_U-0IYjIRY,7803
|
154
155
|
beamlit/models/acl.py,sha256=tH67gsl_BMaviSbTaaIkO1g9cWZgJ6VgAnYVjQSzGZY,3952
|
155
156
|
beamlit/models/agent.py,sha256=oGZBwd2Hy-i6q_up4WQ0IvOmxqouR5I1Gk8vXvfLKvc,3384
|
156
157
|
beamlit/models/agent_chain.py,sha256=8PN8wVSayS-LoBN2nahZsOmr6r3t62H_LPDK_8fnkM8,2255
|
@@ -242,6 +243,7 @@ beamlit/models/store_function_kit.py,sha256=S0i3KMHkJ6FwWwMcPqUOYfXi8AYZ21WC7TLI
|
|
242
243
|
beamlit/models/store_function_labels.py,sha256=ZoEKD_CUDs7HcdHEobDsPz8OcUAZ11pFW3pVYrbz0KQ,1274
|
243
244
|
beamlit/models/store_function_parameter.py,sha256=0iuvA6WVExwzqt5HRNusS9PFtke5_qwVu8fT2MFOH8c,2553
|
244
245
|
beamlit/models/time_fields.py,sha256=5X-SFQ1-cfs5gTvyFjuQ8tfMJJrAGoK0OBZLuOM5phY,2006
|
246
|
+
beamlit/models/trace_ids_response.py,sha256=fmXsxlIc6dNEduKjCG-Yd-oC6MhsI2VSUWkWk9MSQ0s,1806
|
245
247
|
beamlit/models/update_workspace_service_account_body.py,sha256=fz2MGqwRfrYkMmL8PaFHQdsu3RQcRljvP6n6JIru45o,2004
|
246
248
|
beamlit/models/update_workspace_service_account_response_200.py,sha256=nCLPHFP_iR1MIpicgQMpbiyme97ZMfTFhyQUEbhzkHI,2968
|
247
249
|
beamlit/models/update_workspace_user_role_body.py,sha256=FyLCWy9oRgUxoFPxxtrDvwzh1kHLkoTZ1pL5w3ayexM,1572
|
@@ -253,6 +255,6 @@ beamlit/serve/app.py,sha256=OpwPjRdyHZK6J-ziPwhiRDGGa2mvCrFVcBFE6alJVOM,3071
|
|
253
255
|
beamlit/serve/middlewares/__init__.py,sha256=1dVmnOmhAQWvWktqHkKSIX-YoF6fmMU8xkUQuhg_rJU,148
|
254
256
|
beamlit/serve/middlewares/accesslog.py,sha256=Mu4T4_9OvHybjA0ApzZFpgi2C8f3X1NbUk-76v634XM,631
|
255
257
|
beamlit/serve/middlewares/processtime.py,sha256=lDAaIasZ4bwvN-HKHvZpaD9r-yrkVNZYx4abvbjbrCg,411
|
256
|
-
beamlit-0.0.
|
257
|
-
beamlit-0.0.
|
258
|
-
beamlit-0.0.
|
258
|
+
beamlit-0.0.29.dist-info/METADATA,sha256=6io1k9UDgo25M3N_TnaI5udexlJ9LVZPIH6Uv2xO0zU,2401
|
259
|
+
beamlit-0.0.29.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
260
|
+
beamlit-0.0.29.dist-info/RECORD,,
|
File without changes
|