rasa-pro 3.14.0a12__py3-none-any.whl → 3.14.0a14__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.

Potentially problematic release.


This version of rasa-pro might be problematic. Click here for more details.

rasa/builder/main.py CHANGED
@@ -22,9 +22,6 @@ from rasa.builder.logging_utils import (
22
22
  log_request_start,
23
23
  )
24
24
  from rasa.builder.service import bp, setup_project_generator
25
- from rasa.builder.template_cache import (
26
- background_download_template_caches,
27
- )
28
25
  from rasa.builder.training_service import try_load_existing_agent, update_agent
29
26
  from rasa.core.channels.studio_chat import StudioChatInput
30
27
  from rasa.server import configure_cors
@@ -150,16 +147,6 @@ def create_app(project_folder: str) -> Sanic:
150
147
  except Exception as e:
151
148
  structlogger.warning("Failed to load agent on server startup", error=str(e))
152
149
 
153
- if config.HELLO_RASA_PROJECT_ID and app.ctx.project_generator.is_empty():
154
- app.register_listener(background_download_template_caches, "after_server_start")
155
- else:
156
- structlogger.debug(
157
- "builder.main.background_cache_download.disabled",
158
- event_info=(
159
- "No hello rasa project id set; skipping background cache download"
160
- ),
161
- )
162
-
163
150
  return app
164
151
 
165
152
 
@@ -60,7 +60,7 @@ class ProjectGenerator:
60
60
  create_initial_project(self.project_folder.as_posix(), template)
61
61
  # If a local cache for this template exists, copy it into the project.
62
62
  # We no longer download here to avoid blocking project creation.
63
- copy_cache_for_template_if_available(template, self.project_folder)
63
+ await copy_cache_for_template_if_available(template, self.project_folder)
64
64
  # needs to happen after caching, as we download/copy .rasa and that would
65
65
  # overwrite the project info file in .rasa
66
66
  ensure_first_used(self.project_folder)
@@ -339,6 +339,8 @@ class ProjectGenerator:
339
339
  for filename in os.listdir(self.project_folder):
340
340
  file_path = os.path.join(self.project_folder, filename)
341
341
  try:
342
+ if filename == "lost+found":
343
+ continue
342
344
  if os.path.isfile(file_path) or os.path.islink(file_path):
343
345
  os.unlink(file_path)
344
346
  elif os.path.isdir(file_path):
@@ -1,18 +1,11 @@
1
- import asyncio
2
1
  import os
3
- import shutil
4
- import tarfile
5
- import tempfile
6
2
  from pathlib import Path
7
- from typing import Generator
8
3
 
9
4
  import aiofiles
10
- import aiohttp
5
+ import aiofiles.os
6
+ import aioshutil
11
7
  import structlog
12
- from sanic import Sanic
13
8
 
14
- import rasa.version
15
- from rasa.builder.logging_utils import capture_exception_with_context
16
9
  from rasa.cli.scaffold import ProjectTemplateName
17
10
 
18
11
  structlogger = structlog.get_logger()
@@ -20,64 +13,15 @@ structlogger = structlog.get_logger()
20
13
  CACHE_BUCKET_URL = "https://trained-templates.s3.us-east-1.amazonaws.com"
21
14
 
22
15
  # Root directory for storing downloaded template caches on disk.
23
- _CACHE_ROOT_DIR = Path(
24
- os.getenv(
25
- "RASA_TEMPLATE_CACHE_DIR",
26
- Path.home().joinpath(".rasa", "template-cache").as_posix(),
27
- )
28
- )
16
+ _CACHE_ROOT_DIR = Path(os.getenv("RASA_TEMPLATE_CACHE_DIR", "/templates"))
29
17
 
30
18
 
31
19
  def _template_cache_dir(template: ProjectTemplateName) -> Path:
32
20
  """Return the local cache directory for a given template and version."""
33
- return _CACHE_ROOT_DIR / rasa.version.__version__ / template.value
21
+ return _CACHE_ROOT_DIR / template.value
34
22
 
35
23
 
36
- def _cache_root_dir() -> Path:
37
- return Path(
38
- os.getenv(
39
- "RASA_TEMPLATE_CACHE_DIR",
40
- Path.home().joinpath(".rasa", "template-cache").as_posix(),
41
- )
42
- )
43
-
44
-
45
- def _safe_tar_members(
46
- tar: tarfile.TarFile, destination_directory: Path
47
- ) -> Generator[tarfile.TarInfo, None, None]:
48
- """Yield safe members for extraction to prevent path traversal and links.
49
-
50
- Args:
51
- tar: Open tar file handle
52
- destination_directory: Directory to which files will be extracted
53
-
54
- Yields:
55
- Members that are safe to extract within destination_directory
56
- """
57
- base_path = destination_directory.resolve()
58
-
59
- for member in tar.getmembers():
60
- name = member.name
61
- # Skip empty names and absolute paths
62
- if not name or name.startswith("/") or name.startswith("\\"):
63
- continue
64
-
65
- # Disallow symlinks and hardlinks
66
- if member.issym() or member.islnk():
67
- continue
68
-
69
- # Compute the final path and ensure it's within base_path
70
- target_path = (base_path / name).resolve()
71
- try:
72
- target_path.relative_to(base_path)
73
- except ValueError:
74
- # Member would escape the destination directory
75
- continue
76
-
77
- yield member
78
-
79
-
80
- def _copytree(src: Path, dst: Path) -> None:
24
+ async def _copytree(src: Path, dst: Path) -> None:
81
25
  """Copy directory tree from src to dst, merging into dst.
82
26
 
83
27
  Existing files are overwritten. Hidden files and directories are included, as
@@ -87,132 +31,14 @@ def _copytree(src: Path, dst: Path) -> None:
87
31
  for root, dirs, files in os.walk(src):
88
32
  rel_path = Path(root).relative_to(src)
89
33
  target_dir = dst / rel_path
90
- target_dir.mkdir(parents=True, exist_ok=True)
34
+ await aiofiles.os.makedirs(target_dir, exist_ok=True)
91
35
  for filename in files:
92
36
  src_file = Path(root) / filename
93
37
  dst_file = target_dir / filename
94
- shutil.copy2(src_file, dst_file)
95
-
96
-
97
- async def download_cache_for_template(
98
- template: ProjectTemplateName, target_dir: str
99
- ) -> None:
100
- # get a temp path for the cache file download
101
- temporary_cache_file = tempfile.NamedTemporaryFile(suffix=".tar.gz", delete=False)
102
-
103
- try:
104
- url = f"{CACHE_BUCKET_URL}/{rasa.version.__version__}-{template.value}.tar.gz"
105
- async with aiohttp.ClientSession() as session:
106
- async with session.get(url) as response:
107
- response.raise_for_status()
108
- async with aiofiles.open(temporary_cache_file.name, "wb") as f:
109
- async for chunk in response.content.iter_chunked(1024 * 1024):
110
- await f.write(chunk)
111
-
112
- # extract the cache to the project folder using safe member filtering
113
- with tarfile.open(temporary_cache_file.name, "r:gz") as tar:
114
- destination = Path(target_dir)
115
- destination.mkdir(parents=True, exist_ok=True)
116
- tar.extractall(
117
- path=destination,
118
- members=_safe_tar_members(tar, destination),
119
- )
120
-
121
- structlogger.info(
122
- "project_generator.download_cache_for_template.success",
123
- template=template,
124
- event_info=(
125
- "Downloaded cache for template, extracted to target directory."
126
- ),
127
- target_dir=target_dir,
128
- )
129
- except aiohttp.ClientResponseError as e:
130
- if e.status == 403:
131
- structlogger.debug(
132
- "project_generator.download_cache_for_template.no_cache_found",
133
- template=template,
134
- event_info=("No cache found for template, continuing without it."),
135
- target_dir=target_dir,
136
- )
137
- else:
138
- capture_exception_with_context(
139
- e,
140
- "project_generator.download_cache_for_template.response_error",
141
- extra={
142
- "template": template.value,
143
- "status": str(e.status),
144
- "target_dir": target_dir,
145
- },
146
- )
147
- except Exception as exc:
148
- capture_exception_with_context(
149
- exc,
150
- "project_generator.download_cache_for_template.unexpected_error",
151
- extra={"template": template.value, "target_dir": target_dir},
152
- )
153
- finally:
154
- # Clean up the temporary file
155
- try:
156
- Path(temporary_cache_file.name).unlink(missing_ok=True)
157
- except Exception as exc:
158
- structlogger.debug(
159
- "project_generator.download_cache_for_template.cleanup_error",
160
- error=str(exc),
161
- template=template,
162
- event_info=("Failed to cleanup cache for template, ignoring."),
163
- )
164
-
165
-
166
- async def background_download_template_caches(
167
- app: Sanic, loop: asyncio.AbstractEventLoop
168
- ) -> None:
169
- """Kick off background downloads of template caches if enabled."""
170
- try:
171
- structlogger.info(
172
- "builder.main.background_cache_download.start",
173
- event_info=(
174
- "Starting background download of template caches for this " "version"
175
- ),
176
- )
177
-
178
- # Ensure cache root exists
179
- _cache_root_dir().mkdir(parents=True, exist_ok=True)
180
-
181
- async def _download(template: ProjectTemplateName) -> None:
182
- try:
183
- target_dir = _template_cache_dir(template)
184
- if target_dir.exists() and any(target_dir.iterdir()):
185
- structlogger.debug(
186
- "builder.main.background_cache_download.skipped",
187
- template=template,
188
- event_info=(
189
- "Skipping download of template cache because it "
190
- "already exists."
191
- ),
192
- target_dir=target_dir,
193
- )
194
- return
195
-
196
- target_dir.mkdir(parents=True, exist_ok=True)
197
- await download_cache_for_template(template, target_dir.as_posix())
198
- except Exception as exc:
199
- structlogger.debug(
200
- "builder.main.background_cache_download.error",
201
- template=template,
202
- error=str(exc),
203
- )
204
-
205
- # schedule downloads concurrently without blocking startup
206
- for template in ProjectTemplateName:
207
- loop.create_task(_download(template))
208
- except Exception as exc:
209
- structlogger.debug(
210
- "builder.main.background_cache_download.unexpected_error",
211
- error=str(exc),
212
- )
38
+ await aioshutil.copy2(src_file, dst_file)
213
39
 
214
40
 
215
- def copy_cache_for_template_if_available(
41
+ async def copy_cache_for_template_if_available(
216
42
  template: ProjectTemplateName, project_folder: Path
217
43
  ) -> None:
218
44
  """Copy a previously downloaded cache for `template` into `project_folder`.
@@ -222,7 +48,7 @@ def copy_cache_for_template_if_available(
222
48
  try:
223
49
  cache_dir = _template_cache_dir(template)
224
50
  if cache_dir.exists() and any(cache_dir.iterdir()):
225
- _copytree(cache_dir, project_folder)
51
+ await _copytree(cache_dir, project_folder)
226
52
  structlogger.info(
227
53
  "project_generator.copy_cache_for_template.success",
228
54
  template=template,
rasa/version.py CHANGED
@@ -1,3 +1,3 @@
1
1
  # this file will automatically be changed,
2
2
  # do not add anything but the version number here!
3
- __version__ = "3.14.0a12"
3
+ __version__ = "3.14.0a14"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: rasa-pro
3
- Version: 3.14.0a12
3
+ Version: 3.14.0a14
4
4
  Summary: State-of-the-art open-core Conversational AI framework for Enterprises that natively leverages generative AI for effortless assistant development.
5
5
  Keywords: nlp,machine-learning,machine-learning-library,bot,bots,botkit,rasa conversational-agents,conversational-ai,chatbot,chatbot-framework,bot-framework
6
6
  Author: Rasa Technologies GmbH
@@ -28,6 +28,7 @@ Requires-Dist: absl-py (>=2.0,<2.1)
28
28
  Requires-Dist: aio-pika (>=8.2.3,<9.4.4)
29
29
  Requires-Dist: aiogram (>=3.15,<3.16)
30
30
  Requires-Dist: aiohttp (>=3.10,<3.11)
31
+ Requires-Dist: aioshutil (>=1.5,<2.0)
31
32
  Requires-Dist: apscheduler (>=3.10,<3.11)
32
33
  Requires-Dist: attrs (>=23.1,<23.2)
33
34
  Requires-Dist: azure-identity (>=1.19.0,<1.20.0)
@@ -37,15 +37,15 @@ rasa/builder/job_manager.py,sha256=eQ5HRff-U4Cj3joHKqpjDcfCMWj4nz4D_oQmoozpwPM,2
37
37
  rasa/builder/jobs.py,sha256=KgqWNW5e8Nh5kYBm3Fm0wZWspbPRe5Qr1cRfrVKnYlM,9346
38
38
  rasa/builder/llm_service.py,sha256=y3CPQS0qHGFhe6Z4lbs2HkEVztYYVZtnWiTNjghlBdE,8859
39
39
  rasa/builder/logging_utils.py,sha256=E1YZs5BdHT9TrnoA2758sFMD1Xw7e5mnAtqWSAZs1gk,9296
40
- rasa/builder/main.py,sha256=7UhHynU4pTiWj6v7_c9bfRutfT8TIFIZmQs3BRy2aKY,7946
40
+ rasa/builder/main.py,sha256=_LrQrka_zsgHoPWS2sglVgPKsmqYEouOvVJMsZB-QkM,7459
41
41
  rasa/builder/models.py,sha256=UWMN1Z20Btrc2fBK4y4eAyRmx3RVyQiqiUHYQTJfyIE,5937
42
- rasa/builder/project_generator.py,sha256=1CMFZxhOD0pmrTIC-1nMRdQRqDvUgW0zMFNBwVuT-Og,13834
42
+ rasa/builder/project_generator.py,sha256=d7ZAMX1NIR-lzznBtEV_S0MODRGJ-kmzVyHI0HtYCcs,13914
43
43
  rasa/builder/project_info.py,sha256=ZBwFCigZLSo1RBMhlZDYBoVl2G-9OnhRrYxdMWHn6S4,2093
44
44
  rasa/builder/scrape_rasa_docs.py,sha256=iR_uThYA_kjDeIFY7AdpXcP-30P2vOHQ65gH4S1OjLw,2485
45
45
  rasa/builder/service.py,sha256=DBIZeF9IDS-C0SWDfDwo8ieU6Ok9q5N417S3Mz82eLc,46649
46
46
  rasa/builder/shared/tracker_context.py,sha256=2P-DsWjWEkZ32dqrx6s4zVxdo0_mokZNrU3LYisu6MY,7691
47
47
  rasa/builder/skill_to_bot_prompt.jinja2,sha256=h2Fgoh9k3XinN0blEEqMuOWuvwXxJifP3GJs-GczgBU,5530
48
- rasa/builder/template_cache.py,sha256=GFI7o0peOFbbV4RQECsx7s60rhCc5FDOPM5a0DAfpuQ,8592
48
+ rasa/builder/template_cache.py,sha256=Lrn_AjiDTdwG1ydBNKeuCtydTlwOfYs7i2J1Vk9djpM,2424
49
49
  rasa/builder/training_service.py,sha256=kmcxgCxZzklxr4RKqan3aA_BU3pRE7WS_q-AO5sFyxM,5975
50
50
  rasa/builder/validation_service.py,sha256=FAHSf2tQZ8yDlckWWjqMqhjb0rANbXR2DJTybh4fHnM,3099
51
51
  rasa/cli/__init__.py,sha256=eO5vp9rFCANtbTVU-pxN3iMBKw4p9WRcgzytt9MzinY,115
@@ -1123,9 +1123,9 @@ rasa/utils/train_utils.py,sha256=ClJx-6x3-h3Vt6mskacgkcCUJTMXjFPe3zAcy_DfmaU,212
1123
1123
  rasa/utils/url_tools.py,sha256=dZ1HGkVdWTJB7zYEdwoDIrEuyX9HE5WsxKKFVsXBLE0,1218
1124
1124
  rasa/utils/yaml.py,sha256=KjbZq5C94ZP7Jdsw8bYYF7HASI6K4-C_kdHfrnPLpSI,2000
1125
1125
  rasa/validator.py,sha256=_5IjhhzG-_LM5_Bpa09siEQATgFRYEsPp9FbOwXzVmM,83275
1126
- rasa/version.py,sha256=Cwf73DCZiOAF-zeBSpScxpoQsF7If2Rg7TeXms4Jihk,120
1127
- rasa_pro-3.14.0a12.dist-info/METADATA,sha256=DTaiRiz_xMk8gTDkwth-WBv5eqYem13tvAhuqQuplXE,10153
1128
- rasa_pro-3.14.0a12.dist-info/NOTICE,sha256=7HlBoMHJY9CL2GlYSfTQ-PZsVmLmVkYmMiPlTjhuCqA,218
1129
- rasa_pro-3.14.0a12.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
1130
- rasa_pro-3.14.0a12.dist-info/entry_points.txt,sha256=ckJ2SfEyTPgBqj_I6vm_tqY9dZF_LAPJZA335Xp0Q9U,43
1131
- rasa_pro-3.14.0a12.dist-info/RECORD,,
1126
+ rasa/version.py,sha256=swo0Q6PztYkxOIZHWlEfLcETFHTje68-yoUGlZIBVd4,120
1127
+ rasa_pro-3.14.0a14.dist-info/METADATA,sha256=mHkfVyM2suR66EHcHkMGRt-hm86DortyU-LKqNSgJfU,10191
1128
+ rasa_pro-3.14.0a14.dist-info/NOTICE,sha256=7HlBoMHJY9CL2GlYSfTQ-PZsVmLmVkYmMiPlTjhuCqA,218
1129
+ rasa_pro-3.14.0a14.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
1130
+ rasa_pro-3.14.0a14.dist-info/entry_points.txt,sha256=ckJ2SfEyTPgBqj_I6vm_tqY9dZF_LAPJZA335Xp0Q9U,43
1131
+ rasa_pro-3.14.0a14.dist-info/RECORD,,