beamlit 0.0.33rc49__py3-none-any.whl → 0.0.34rc51__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
@@ -6,9 +6,10 @@ import importlib
6
6
  import os
7
7
  from logging import getLogger
8
8
 
9
- from langchain_core.tools import Tool
9
+ from langchain_core.tools import StructuredTool
10
10
  from langgraph.checkpoint.memory import MemorySaver
11
11
  from langgraph.prebuilt import create_react_agent
12
+ from langchain_core.tools.base import create_schema_from_function
12
13
 
13
14
  from beamlit.api.models import get_model
14
15
  from beamlit.authentication import new_client
@@ -94,19 +95,21 @@ def get_functions(client, dir="src/functions", from_decorator="function", remote
94
95
  else:
95
96
  if asyncio.iscoroutinefunction(func):
96
97
  functions.append(
97
- Tool(
98
+ StructuredTool(
98
99
  name=func.__name__,
99
100
  description=func.__doc__,
100
101
  func=func,
101
102
  coroutine=func,
103
+ args_schema=create_schema_from_function(func.__name__, func)
102
104
  )
103
105
  )
104
106
  else:
105
107
  functions.append(
106
- Tool(
108
+ StructuredTool(
107
109
  name=func.__name__,
108
110
  description=func.__doc__,
109
111
  func=func,
112
+ args_schema=create_schema_from_function(func.__name__, func)
110
113
  )
111
114
  )
112
115
  except Exception as e:
@@ -1,7 +1,7 @@
1
1
  from .error import HTTPError
2
2
  from .logger import init as init_logger
3
3
  from .secrets import Secret
4
- from .settings import Settings, get_settings, init, init_agent
4
+ from .settings import Settings, get_settings, init
5
5
  from .slugify import slugify
6
6
  from .utils import copy_folder
7
7
 
@@ -9,7 +9,6 @@ __all__ = [
9
9
  "Secret",
10
10
  "Settings",
11
11
  "get_settings",
12
- "init_agent",
13
12
  "init",
14
13
  "copy_folder",
15
14
  "init_logger",
@@ -1,5 +1,4 @@
1
1
  import os
2
- from logging import getLogger
3
2
  from typing import Tuple, Type, Union
4
3
 
5
4
  from langchain_core.language_models.chat_models import BaseChatModel
@@ -12,22 +11,17 @@ from pydantic_settings import (
12
11
  YamlConfigSettingsSource,
13
12
  )
14
13
 
15
- from beamlit.api.agents import get_agent
16
- from beamlit.api.functions import get_function
17
- from beamlit.api.models import get_model
18
- from beamlit.client import AuthenticatedClient
19
14
  from beamlit.common.logger import init as init_logger
20
15
  from beamlit.models import Agent, Function, Model
21
- from beamlit.types import UNSET, Unset
22
16
 
23
17
  global SETTINGS
24
18
  SETTINGS = None
25
19
 
26
20
  class SettingsAgent(BaseSettings):
27
- agent: Union[None, CompiledGraph, BaseChatModel] = None
28
- chain: Union[Unset, list[Agent]] = UNSET
29
- model: Union[Unset, Model] = UNSET
30
- functions: Union[Unset, list[Function]] = UNSET
21
+ agent: Union[None, CompiledGraph] = None
22
+ chain: Union[None, list[Agent]] = None
23
+ model: Union[None, Model] = None
24
+ functions: Union[None, list[Function]] = None
31
25
  functions_directory: str = Field(default="src/functions")
32
26
  chat_model: Union[None, BaseChatModel] = None
33
27
  module: str = Field(default="main.main")
@@ -100,59 +94,6 @@ class Settings(BaseSettings):
100
94
  def get_settings() -> Settings:
101
95
  return SETTINGS
102
96
 
103
-
104
- def init_agent(
105
- client: AuthenticatedClient,
106
- destination: str = f"{os.getcwd()}/src/beamlit_generated.py",
107
- ):
108
- from beamlit.common.generate import generate
109
-
110
- logger = getLogger(__name__)
111
- settings = get_settings()
112
- # Init configuration from environment variables
113
- if settings.agent.functions or settings.agent.chain:
114
- return
115
-
116
- # Init configuration from beamlit control plane
117
- name = settings.name
118
- env = settings.environment
119
-
120
- agent = get_agent.sync(name, environment=env, client=client)
121
- if not agent:
122
- raise ValueError(f"Agent {name} not found")
123
- functions: list[Function] = []
124
- agents_chain: list[Agent] = []
125
- if agent.spec.functions:
126
- for function in agent.spec.functions:
127
- function = get_function.sync(function, environment=env, client=client)
128
- if function:
129
- functions.append(function)
130
- settings.agent.functions = functions
131
-
132
- if agent.spec.agentChain:
133
- for chain in agent.spec.agentChain:
134
- if chain.enabled:
135
- agentChain = get_agent.sync(chain.name, environment=env, client=client)
136
- if chain.description:
137
- agentChain.spec.description = chain.description
138
- agents_chain.append(agentChain)
139
- settings.agent.chain = agents_chain
140
- if agent.spec.model:
141
- model = get_model.sync(agent.spec.model, environment=env, client=client)
142
- settings.agent.model = model
143
-
144
- content_generate = generate(destination, dry_run=True)
145
- compared_content = None
146
- if os.path.exists(destination):
147
- compared_content = open(destination).read()
148
-
149
- if not os.path.exists(destination) or (
150
- compared_content and content_generate != compared_content
151
- ):
152
- logger.info("Generating agent code")
153
- generate(destination)
154
-
155
-
156
97
  def init() -> Settings:
157
98
  """Parse the beamlit.yaml file to get configurations."""
158
99
  from beamlit.authentication.credentials import current_context
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: beamlit
3
- Version: 0.0.33rc49
3
+ Version: 0.0.34rc51
4
4
  Summary: Add your description here
5
5
  Author-email: cploujoux <ch.ploujoux@gmail.com>
6
6
  Requires-Python: >=3.12
@@ -7,7 +7,7 @@ beamlit/types.py,sha256=E1hhDh_zXfsSQ0NCt9-uw90_Mr5iIlsdfnfvxv5HarU,1005
7
7
  beamlit/agents/__init__.py,sha256=nf1iwQwGtCG6nDqyVhxfWoqR6dv6X3bvSpCeqkTCFaM,101
8
8
  beamlit/agents/chain.py,sha256=vfCjiFHuu02uTTGicxMlFzjyICQkIjpXrBGs-7uJEsg,2826
9
9
  beamlit/agents/chat.py,sha256=gVyv4FGBdQTDhdutX8l64OUNa6Fdqaw4eCfEDRH0IPQ,3558
10
- beamlit/agents/decorator.py,sha256=PUw5xfG4KmmVeSbgI-Ac7KAm5n0addPhg5MysfxLpWk,10297
10
+ beamlit/agents/decorator.py,sha256=n3sETKu8V2g3GDJ0f17kUowyqaRJvpg3n_BGRRVuNGY,10619
11
11
  beamlit/api/__init__.py,sha256=zTSiG_ujSjAqWPyc435YXaX9XTlpMjiJWBbV-f-YtdA,45
12
12
  beamlit/api/agents/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
13
  beamlit/api/agents/create_agent.py,sha256=t5Pr62My2EhQlcIY71MrI73-0_q5Djr3a_Ybt9MIiQQ,3587
@@ -128,13 +128,12 @@ beamlit/authentication/authentication.py,sha256=ODQCc00RvCOZNaiGG5ctylNnE-JVCuge
128
128
  beamlit/authentication/clientcredentials.py,sha256=cxZPPu--CgizwqX0pdfFQ91gJt1EFKwyy-aBB_dXX7I,3990
129
129
  beamlit/authentication/credentials.py,sha256=p_1xenabCbQuRz7BiFk7oTK4uCxAt_zoyku5o-jcKGE,5343
130
130
  beamlit/authentication/device_mode.py,sha256=tmr22gllKOZwBRub_QjF5pYa425x-nE8tQNpZ_EGR6g,3644
131
- beamlit/common/__init__.py,sha256=UjOMfg6BeoXqalI3p98qMpgdh__AstwvdUz_9lx8lUY,384
131
+ beamlit/common/__init__.py,sha256=saX5X3hRCJ9erSlXuSkZ2VGgquvpgdcofAU_9sM4bCE,354
132
132
  beamlit/common/error.py,sha256=f9oJDFxhoHK-vpjxBgEp0NwWIk0N_THPemUI7uQxVzU,270
133
- beamlit/common/generate.py,sha256=LtdCju_QayRS4lZrrb_0VHqWWvTcv4Mbf-iV1TB_Qko,7522
134
133
  beamlit/common/instrumentation.py,sha256=GVYeat7qCcqzDoKSYig3s8ZCC172R9JiQIr3Evv3kik,4293
135
134
  beamlit/common/logger.py,sha256=nN_dSOl4bs13QU3Rod-w3e3jYOnlSrHx3_bs-ACY6Aw,1115
136
135
  beamlit/common/secrets.py,sha256=sid81bOe3LflkMKDHwBsBs9nIju8bp5-v9qU9gkyNMc,212
137
- beamlit/common/settings.py,sha256=_4oCVrJZOMaTZoK2Zzo2DWqtUyBsspuOH3iAJ_nU0tw,5923
136
+ beamlit/common/settings.py,sha256=b2rvby-ufG3M0AB1ReoWFM-1EzF1LaE-gbokO9HvQDI,3810
138
137
  beamlit/common/slugify.py,sha256=nR29r37IdWS2i44ZC6ZsXRgqKPYmvMGtFQ7BuIQUTlc,90
139
138
  beamlit/common/utils.py,sha256=jouz5igBvT37Xn_e94-foCHyQczVim-UzVcoIF6RWJ4,657
140
139
  beamlit/deploy/__init__.py,sha256=GS7l7Jtm2yKs7iNLKcfjYO-rAhUzggQ3xiYSf3oxLBY,91
@@ -257,6 +256,6 @@ beamlit/serve/app.py,sha256=DXWxQoMeuA5FYvBMyLrP94OEWQbwLf4GZk3I9fkwSPA,3523
257
256
  beamlit/serve/middlewares/__init__.py,sha256=1dVmnOmhAQWvWktqHkKSIX-YoF6fmMU8xkUQuhg_rJU,148
258
257
  beamlit/serve/middlewares/accesslog.py,sha256=Mu4T4_9OvHybjA0ApzZFpgi2C8f3X1NbUk-76v634XM,631
259
258
  beamlit/serve/middlewares/processtime.py,sha256=lDAaIasZ4bwvN-HKHvZpaD9r-yrkVNZYx4abvbjbrCg,411
260
- beamlit-0.0.33rc49.dist-info/METADATA,sha256=5_QMzORLYGZDg98cqBd7UP0O94nUxM1VXacm933d1PA,2405
261
- beamlit-0.0.33rc49.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
262
- beamlit-0.0.33rc49.dist-info/RECORD,,
259
+ beamlit-0.0.34rc51.dist-info/METADATA,sha256=912n-eb3Gn8qEASD4KQYpO_lConoEVI06AixnfojXuA,2405
260
+ beamlit-0.0.34rc51.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
261
+ beamlit-0.0.34rc51.dist-info/RECORD,,
@@ -1,196 +0,0 @@
1
- from typing import Tuple
2
-
3
- from beamlit.common.settings import Settings, get_settings
4
- from beamlit.models import Agent, Function, FunctionMetadata, FunctionSpec
5
- from beamlit.models.function_kit import FunctionKit
6
-
7
-
8
- def get_titles_name(name: str) -> str:
9
- return name.title().replace("-", "").replace("_", "")
10
-
11
-
12
- def generate_kit_function_code(
13
- settings: Settings, function: Function, kit: FunctionKit
14
- ) -> Tuple[str, str]:
15
- export_code = ""
16
- code = ""
17
- for kit in kit:
18
- fn = Function(
19
- metadata=FunctionMetadata(
20
- name=kit.name,
21
- workspace=settings.workspace,
22
- environment=settings.environment,
23
- ),
24
- spec=FunctionSpec(
25
- parameters=kit.parameters,
26
- description=kit.description,
27
- ),
28
- )
29
- new_code, export = generate_function_code(
30
- settings, fn, force_name_in_endpoint=function.metadata.name, kit=True
31
- )
32
- code += new_code
33
- export_code += export
34
- return code, export_code
35
-
36
-
37
- def generate_function_code(
38
- settings: Settings,
39
- function: Function,
40
- force_name_in_endpoint: str = "",
41
- kit: bool = False,
42
- ) -> Tuple[str, str]:
43
- name = get_titles_name(function.metadata.name)
44
- if function.spec.parameters and len(function.spec.parameters) > 0:
45
- args_list = ", ".join(f"{param.name}: str" for param in function.spec.parameters)
46
- args_list += ", "
47
- else:
48
- args_list = ""
49
- args_schema = ""
50
- if function.spec.parameters:
51
- for param in function.spec.parameters:
52
- args_schema += f'{param.name}: str = Field(description="""{param.description}""")\n '
53
- if len(args_schema) == 0:
54
- args_schema = "pass"
55
-
56
- # TODO: add return direct in function configuration
57
- return_direct = False
58
- endpoint_name = force_name_in_endpoint or function.metadata.name
59
- body = "{}"
60
- if function.spec.parameters:
61
- body = f'{", ".join(f'"{param.name}": {param.name}' for param in function.spec.parameters)}'
62
- if kit is True:
63
- has_name = False
64
- if function.spec.parameters:
65
- for param in function.spec.parameters:
66
- if param.name == "name":
67
- has_name = True
68
- break
69
- if not has_name:
70
- if len(body) > 0:
71
- body += ", "
72
- body += f'"name": "{function.metadata.name}"'
73
- return (
74
- f'''
75
-
76
- class Beamlit{name}Input(BaseModel):
77
- {args_schema}
78
-
79
- class Beamlit{name}(BaseTool):
80
- name: str = "beamlit_{function.metadata.name.replace("-", "_")}"
81
- description: str = """{function.spec.description}"""
82
- args_schema: Type[BaseModel] = Beamlit{name}Input
83
-
84
- response_format: Literal["content_and_artifact"] = "content_and_artifact"
85
- return_direct: bool = {return_direct}
86
-
87
- def _run(self, {args_list} run_manager: Optional[CallbackManagerForToolRun] = None) -> Tuple[Union[List[Dict[str, str]], str], Dict]:
88
- try:
89
- params = self.metadata.get("params", {{}})
90
- response = run_client.run("function", "{endpoint_name}", settings.environment, "POST", json={{{body}}})
91
- if response.status_code >= 400:
92
- logger.error(f"Failed to run function {name}, {{response.status_code}}::{{response.text}}")
93
- raise Exception(f"Failed to run function {name}, {{response.status_code}}::{{response.text}}")
94
- return response.json(), {{}}
95
- except Exception as e:
96
- return repr(e), {{}}
97
- ''',
98
- f"Beamlit{get_titles_name(function.metadata.name)},",
99
- )
100
-
101
-
102
- def generate_chain_code(settings: Settings, agent: Agent) -> Tuple[str, str]:
103
- name = get_titles_name(agent.metadata.name)
104
- # TODO: add return direct in agent configuration
105
- return_direct = False
106
- return (
107
- f'''
108
- class BeamlitChain{name}Input(BaseModel):
109
- input: str = Field(description='{agent.spec.description}')
110
-
111
- class BeamlitChain{name}(BaseTool):
112
- name: str = "beamlit_chain_{agent.metadata.name.replace("-", "_")}"
113
- description: str = """{agent.spec.description}"""
114
- args_schema: Type[BaseModel] = BeamlitChain{name}Input
115
-
116
- response_format: Literal["content_and_artifact"] = "content_and_artifact"
117
- return_direct: bool = {return_direct}
118
-
119
- def _run(
120
- self,
121
- input: str,
122
- run_manager: Optional[CallbackManagerForToolRun] = None,
123
- ) -> Tuple[Union[List[Dict[str, str]], str], Dict]:
124
- try:
125
- params = self.metadata.get("params", {{}})
126
- response = run_client.run("agent", "{agent.metadata.name}", settings.environment, "POST", json={{"input": input}})
127
- if response.status_code >= 400:
128
- logger.error(f"Failed to run tool {agent.metadata.name}, {{response.status_code}}::{{response.text}}")
129
- raise Exception(f"Failed to run tool {agent.metadata.name}, {{response.status_code}}::{{response.text}}")
130
- if response.headers.get("Content-Type") == "application/json":
131
- return response.json(), {{}}
132
- else:
133
- return response.text, {{}}
134
- except Exception as e:
135
- return repr(e), {{}}
136
- ''',
137
- f"BeamlitChain{name},",
138
- )
139
-
140
-
141
- def generate(destination: str, dry_run: bool = False):
142
- imports = """from logging import getLogger
143
- from typing import Dict, List, Literal, Optional, Tuple, Type, Union
144
-
145
- from langchain_core.callbacks import CallbackManagerForToolRun
146
- from langchain_core.tools import BaseTool
147
- from pydantic import BaseModel, Field
148
- from beamlit.authentication import (RunClientWithCredentials,
149
- load_credentials_from_settings,
150
- new_client_with_credentials)
151
- from beamlit.common.settings import get_settings
152
- from beamlit.run import RunClient
153
-
154
- logger = getLogger(__name__)
155
- settings = get_settings()
156
- credentials = load_credentials_from_settings(settings)
157
-
158
- client_config = RunClientWithCredentials(
159
- credentials=credentials,
160
- workspace=settings.workspace,
161
- )
162
- client = new_client_with_credentials(client_config)
163
- run_client = RunClient(client=client)
164
- """
165
- settings = get_settings()
166
- export_code = "\n\nfunctions = ["
167
- export_chain = "\n\nchains = ["
168
- code = imports
169
- if settings.agent.functions and len(settings.agent.functions) > 0:
170
- for function_config in settings.agent.functions:
171
- if function_config.spec.kit and len(function_config.spec.kit) > 0:
172
- new_code, export = generate_kit_function_code(
173
- settings, function_config, function_config.spec.kit
174
- )
175
- code += new_code
176
- export_code += export
177
- else:
178
- new_code, export = generate_function_code(settings, function_config)
179
- code += new_code
180
- export_code += export
181
- if settings.agent.chain and len(settings.agent.chain) > 0:
182
- for agent in settings.agent.chain:
183
- new_code, export = generate_chain_code(settings, agent)
184
- code += new_code
185
- export_chain += export
186
- if settings.agent.functions and len(settings.agent.functions) > 0:
187
- export_code = export_code[:-1]
188
- export_code += "]"
189
- if settings.agent.chain and len(settings.agent.chain) > 0:
190
- export_chain = export_chain[:-1]
191
- export_chain += "]"
192
- content = code + export_code + export_chain
193
- if not dry_run:
194
- with open(destination, "w") as f:
195
- f.write(content)
196
- return content