beamlit 0.0.28rc25__py3-none-any.whl → 0.0.29__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/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
|