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.
@@ -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
+ ]
@@ -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
- logger.warn(f"Functions directory {dir} not found")
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(dir=settings.agent.functions_directory)
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(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Optional[Any]:
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(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Response[Any]:
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[Any]:
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[Any]
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[Any]:
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[Any]
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(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Optional[Any]:
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(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Response[Any]:
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[Any]:
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[Any]
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[Any]:
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[Any]
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(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Optional[Any]:
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(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Response[Any]:
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[Any]:
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[Any]
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[Any]:
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[Any]
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
- Credentials,
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 = "https://api.beamlit.com/v0"
31
- run_url: str = "https://run.beamlit.com/v0"
25
+ api_url: str = ""
26
+ run_url: str = ""
32
27
 
33
28
  def __post_init__(self):
34
- if os.getenv('BL_ENV') == 'dev':
35
- self.api_url = "https://api.beamlit.dev/v0"
36
- self.run_url = "https://run.beamlit.dev/v0"
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=default_base_url)
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=default_base_url)
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:
@@ -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://serverless-registry-production.beamlit.workers.com")
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://serverless-registry-production.beamlit.workers.dev"
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.displayName:
33
- deployment.metadata.displayName = deployment.metadata.name
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.displayName or agent.metadata.name}
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.agentChain)}
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.displayName or function.metadata.name}
148
+ displayName: {function.metadata.display_name or function.metadata.name}
149
149
  environment: {settings.environment}
150
150
  spec:
151
151
  enabled: true
@@ -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=create_schema_model(tool.inputSchema),
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 typing import Any, Callable
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.models.function import Function
12
- from langchain_core.tools.base import BaseTool, BaseToolkit, ToolException
13
- from pydantic.json_schema import JsonSchemaValue
14
- from pydantic_core import core_schema as cs
15
-
16
-
17
- def create_schema_model(schema: dict[str, t.Any]) -> type[pydantic.BaseModel]:
18
- # Create a new model class that returns our JSON schema.
19
- # LangChain requires a BaseModel class.
20
- class Schema(pydantic.BaseModel):
21
- model_config = pydantic.ConfigDict(extra="allow")
22
-
23
- @t.override
24
- @classmethod
25
- def __get_pydantic_json_schema__(
26
- cls, core_schema: cs.CoreSchema, handler: pydantic.GetJsonSchemaHandler
27
- ) -> JsonSchemaValue:
28
- return schema
29
-
30
- return Schema
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: AuthenticatedClient
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
- result = self.client.call_tool(self.name, arguments=kwargs)
52
- response = result.json()
53
- content = pydantic_core.to_json(response["content"]).decode()
54
- if response["isError"]:
55
- raise ToolException(content)
56
- return content
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
- class RemoteToolkit(BaseToolkit):
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._tools is None:
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
- client=self.client,
89
- name=func.name,
90
- description=func.description or "",
91
- args_schema=create_schema_model(func.parameters),
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=create_schema_model(self._function.spec.parameters),
117
+ args_schema=create_dynamic_schema(
118
+ self._function.metadata.name,
119
+ self._function.spec.parameters
120
+ ),
102
121
  )
103
122
  ]
@@ -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,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: beamlit
3
- Version: 0.0.28rc25
3
+ Version: 0.0.29
4
4
  Summary: Add your description here
5
5
  Author-email: cploujoux <ch.ploujoux@gmail.com>
6
6
  Requires-Python: >=3.12
@@ -1,12 +1,13 @@
1
1
  beamlit/__init__.py,sha256=545gFC-wLLwUktWcOAjUWe_Glha40tBetRTOYSfHnbI,164
2
- beamlit/client.py,sha256=SmJ46egRqKwRrLXCHmwrik0D_dD6s46-87YeVhBgxSU,12817
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=WiE6zfRv4Ywf1wH-rUaGjBNGjIDRdgoEH_8Yl26IM6U,9263
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=5VXdgE7wveS-K-kcJpk2_SzKPh5vcs9kOkYLO74Nx6M,2729
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=MaTT6TGTJZTNkBn6Li9KfMrhpTaIM_GnTBbg-Bp_jiw,2768
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=7LuYPCmmt98BwrMGVZBK5E4izXA7iGZ21pHmx03-YG4,2729
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=a29-iD92T8_q8Kpx25VXEyyASlCaFsSg0s8y-SWPtns,3311
127
- beamlit/authentication/clientcredentials.py,sha256=6kbfTjwUkXUArJX8XZLe9ZzbEicQc19tSXBvsTpiXMk,3954
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=Z-UBDQKp_pAusWgwmoIwK5nl_z9xfOYYEeCCuYafr0M,5821
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=rXpiAqlO36Ul1eadBEiwiil-6R2DkbaYHzw-qcqZ0g4,9183
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=uGqNOwEgIKdvtVPmCf9Nf_YI_k7zioLvc6jVOpszrg4,4104
150
- beamlit/functions/remote/remote.py,sha256=W60VNSNfBcVed8HVifOjcWN20StmhDjSV06AT35STaY,3276
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=O16oX1-oBJqB5LZEHAfu_hZZZh6_PX2LqZpVl4fNQRs,7730
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.28rc25.dist-info/METADATA,sha256=JLFUlrvUKeIJWwQT1lX7St9EBkt7-xRZwQu_UGKUotg,2405
257
- beamlit-0.0.28rc25.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
258
- beamlit-0.0.28rc25.dist-info/RECORD,,
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,,