rasa-pro 3.12.10.dev1__py3-none-any.whl → 3.12.12.dev1__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.

Files changed (37) hide show
  1. rasa/__init__.py +0 -6
  2. rasa/api.py +4 -0
  3. rasa/cli/arguments/default_arguments.py +13 -1
  4. rasa/cli/arguments/train.py +2 -0
  5. rasa/cli/train.py +1 -0
  6. rasa/constants.py +2 -0
  7. rasa/core/actions/action.py +1 -1
  8. rasa/core/channels/voice_ready/audiocodes.py +71 -31
  9. rasa/core/persistor.py +55 -20
  10. rasa/core/policies/intentless_policy.py +1 -3
  11. rasa/dialogue_understanding/coexistence/llm_based_router.py +1 -0
  12. rasa/dialogue_understanding/generator/llm_based_command_generator.py +4 -15
  13. rasa/dialogue_understanding/generator/llm_command_generator.py +1 -3
  14. rasa/dialogue_understanding/generator/multi_step/multi_step_llm_command_generator.py +4 -44
  15. rasa/dialogue_understanding/generator/single_step/compact_llm_command_generator.py +1 -14
  16. rasa/hooks.py +0 -55
  17. rasa/keys +1 -0
  18. rasa/model_manager/config.py +3 -1
  19. rasa/model_manager/model_api.py +1 -2
  20. rasa/model_manager/runner_service.py +8 -4
  21. rasa/model_manager/trainer_service.py +1 -0
  22. rasa/model_training.py +12 -3
  23. rasa/nlu/extractors/crf_entity_extractor.py +66 -16
  24. rasa/shared/constants.py +0 -5
  25. rasa/shared/providers/constants.py +0 -9
  26. rasa/shared/providers/llm/_base_litellm_client.py +4 -14
  27. rasa/shared/providers/llm/litellm_router_llm_client.py +7 -17
  28. rasa/shared/providers/llm/llm_client.py +15 -24
  29. rasa/shared/providers/llm/self_hosted_llm_client.py +2 -10
  30. rasa/tracing/instrumentation/attribute_extractors.py +2 -2
  31. rasa/version.py +1 -1
  32. {rasa_pro-3.12.10.dev1.dist-info → rasa_pro-3.12.12.dev1.dist-info}/METADATA +2 -3
  33. {rasa_pro-3.12.10.dev1.dist-info → rasa_pro-3.12.12.dev1.dist-info}/RECORD +36 -36
  34. rasa/monkey_patches.py +0 -91
  35. {rasa_pro-3.12.10.dev1.dist-info → rasa_pro-3.12.12.dev1.dist-info}/NOTICE +0 -0
  36. {rasa_pro-3.12.10.dev1.dist-info → rasa_pro-3.12.12.dev1.dist-info}/WHEEL +0 -0
  37. {rasa_pro-3.12.10.dev1.dist-info → rasa_pro-3.12.12.dev1.dist-info}/entry_points.txt +0 -0
rasa/hooks.py CHANGED
@@ -1,20 +1,8 @@
1
1
  import argparse
2
2
  import logging
3
- import os
4
3
  from typing import TYPE_CHECKING, List, Optional, Text, Union
5
4
 
6
- import litellm
7
5
  import pluggy
8
- import structlog
9
-
10
- from rasa.shared.providers.constants import (
11
- LANGFUSE_CALLBACK_NAME,
12
- LANGFUSE_HOST_ENV_VAR,
13
- LANGFUSE_PROJECT_ID_ENV_VAR,
14
- LANGFUSE_PUBLIC_KEY_ENV_VAR,
15
- LANGFUSE_SECRET_KEY_ENV_VAR,
16
- RASA_LANGFUSE_INTEGRATION_ENABLED_ENV_VAR,
17
- )
18
6
 
19
7
  # IMPORTANT: do not import anything from rasa here - use scoped imports
20
8
  # this avoids circular imports, as the hooks are used in different places
@@ -30,7 +18,6 @@ if TYPE_CHECKING:
30
18
 
31
19
  hookimpl = pluggy.HookimplMarker("rasa")
32
20
  logger = logging.getLogger(__name__)
33
- structlogger = structlog.get_logger()
34
21
 
35
22
 
36
23
  @hookimpl # type: ignore[misc]
@@ -70,8 +57,6 @@ def configure_commandline(cmdline_arguments: argparse.Namespace) -> Optional[Tex
70
57
  config.configure_tracing(tracer_provider)
71
58
  config.configure_metrics(endpoints_file)
72
59
 
73
- _init_langfuse_integration()
74
-
75
60
  return endpoints_file
76
61
 
77
62
 
@@ -130,43 +115,3 @@ def after_server_stop() -> None:
130
115
 
131
116
  if anon_pipeline is not None:
132
117
  anon_pipeline.stop()
133
-
134
-
135
- def _is_langfuse_integration_enabled() -> bool:
136
- return (
137
- os.environ.get(RASA_LANGFUSE_INTEGRATION_ENABLED_ENV_VAR, "false").lower()
138
- == "true"
139
- )
140
-
141
-
142
- def _init_langfuse_integration() -> None:
143
- if not _is_langfuse_integration_enabled():
144
- structlogger.info(
145
- "hooks._init_langfuse_integration.disabled",
146
- event_info="Langfuse integration is disabled.",
147
- )
148
- return
149
-
150
- if (
151
- not os.environ.get(LANGFUSE_HOST_ENV_VAR)
152
- or not os.environ.get(LANGFUSE_PROJECT_ID_ENV_VAR)
153
- or not os.environ.get(LANGFUSE_PUBLIC_KEY_ENV_VAR)
154
- or not os.environ.get(LANGFUSE_SECRET_KEY_ENV_VAR)
155
- ):
156
- structlogger.warning(
157
- "hooks._init_langfuse_integration.missing_langfuse_keys",
158
- event_info=(
159
- "Langfuse integration is enabled, but some environment variables "
160
- "are missing. Please set LANGFUSE_HOST, LANGFUSE_PROJECT_ID, "
161
- "LANGFUSE_PUBLIC_KEY and LANGFUSE_SECRET_KEY environment "
162
- "variables to use Langfuse integration."
163
- ),
164
- )
165
- return
166
-
167
- litellm.success_callback = [LANGFUSE_CALLBACK_NAME]
168
- litellm.failure_callback = [LANGFUSE_CALLBACK_NAME]
169
- structlogger.info(
170
- "hooks.langfuse_callbacks_initialized",
171
- event_info="Langfuse integration initialized.",
172
- )
rasa/keys ADDED
@@ -0,0 +1 @@
1
+ {"segment": "CcvVD1I68Nkkxrv93cIqv1twIwrwG8nz", "sentry": "a283f1fde04347b099c8d729109dd450@o251570"}
@@ -1,6 +1,8 @@
1
1
  import os
2
2
  import sys
3
3
 
4
+ from rasa.constants import RASA_REMOTE_STORAGE_ENV_VAR_NAME
5
+
4
6
  DEFAULT_SERVER_BASE_WORKING_DIRECTORY = "working-data"
5
7
 
6
8
  SERVER_BASE_WORKING_DIRECTORY = os.environ.get(
@@ -12,7 +14,7 @@ SERVER_PORT = os.environ.get("RASA_MODEL_SERVER_PORT", 8000)
12
14
  SERVER_BASE_URL = os.environ.get("RASA_MODEL_SERVER_BASE_URL", None)
13
15
 
14
16
  # defaults to storing on the local hard drive
15
- SERVER_MODEL_REMOTE_STORAGE = os.environ.get("RASA_REMOTE_STORAGE", None)
17
+ SERVER_MODEL_REMOTE_STORAGE = os.environ.get(RASA_REMOTE_STORAGE_ENV_VAR_NAME, None)
16
18
 
17
19
  # The path to the python executable that is running this script
18
20
  # we will use the same python to run training / bots
@@ -532,8 +532,7 @@ def size_of_model(model_name: str) -> Optional[int]:
532
532
  model_name=model_file_name,
533
533
  )
534
534
  return fetch_size_of_remote_model(
535
- model_file_name,
536
- config.SERVER_MODEL_REMOTE_STORAGE,
535
+ model_file_name, config.SERVER_MODEL_REMOTE_STORAGE, model_path
537
536
  )
538
537
  raise ModelNotFound("Model not found.")
539
538
 
@@ -166,13 +166,13 @@ def fetch_remote_model_to_dir(
166
166
  ) -> str:
167
167
  """Fetch the model from remote storage.
168
168
 
169
- Returns the path to the model diretory.
169
+ Returns the path to the model directory.
170
170
  """
171
171
  from rasa.core.persistor import get_persistor
172
172
 
173
173
  persistor = get_persistor(storage_type)
174
174
 
175
- # we now there must be a persistor, because the config is set
175
+ # we know there must be a persistor, because the config is set
176
176
  # this is here to please the type checker for the call below
177
177
  assert persistor is not None
178
178
 
@@ -182,7 +182,9 @@ def fetch_remote_model_to_dir(
182
182
  raise ModelNotFound() from e
183
183
 
184
184
 
185
- def fetch_size_of_remote_model(model_name: str, storage_type: str) -> int:
185
+ def fetch_size_of_remote_model(
186
+ model_name: str, storage_type: str, model_path: str
187
+ ) -> int:
186
188
  """Fetch the size of the model from remote storage."""
187
189
  from rasa.core.persistor import get_persistor
188
190
 
@@ -192,7 +194,9 @@ def fetch_size_of_remote_model(model_name: str, storage_type: str) -> int:
192
194
  # this is here to please the type checker for the call below
193
195
  assert persistor is not None
194
196
 
195
- return persistor.size_of_persisted_model(model_name=model_name)
197
+ return persistor.size_of_persisted_model(
198
+ model_name=model_name, target_path=model_path
199
+ )
196
200
 
197
201
 
198
202
  def start_bot_process(
@@ -278,6 +278,7 @@ def start_training_process(
278
278
  "--keep-local-model-copy",
279
279
  "--remote-storage",
280
280
  config.SERVER_MODEL_REMOTE_STORAGE,
281
+ "--remote-root-only",
281
282
  ]
282
283
  )
283
284
 
rasa/model_training.py CHANGED
@@ -160,6 +160,7 @@ async def train(
160
160
  remote_storage: Optional[StorageType] = None,
161
161
  file_importer: Optional[TrainingDataImporter] = None,
162
162
  keep_local_model_copy: bool = False,
163
+ remote_root_only: bool = False,
163
164
  ) -> TrainingResult:
164
165
  """Trains a Rasa model (Core and NLU).
165
166
 
@@ -187,6 +188,8 @@ async def train(
187
188
  If it is not provided, a new instance will be created.
188
189
  keep_local_model_copy: If `True` the model will be stored locally even if
189
190
  remote storage is configured.
191
+ remote_root_only: If `True`, the model will be stored in the root of the
192
+ remote model storage.
190
193
 
191
194
  Returns:
192
195
  An instance of `TrainingResult`.
@@ -269,6 +272,7 @@ async def train(
269
272
  dry_run=dry_run,
270
273
  remote_storage=remote_storage,
271
274
  keep_local_model_copy=keep_local_model_copy,
275
+ remote_root_only=remote_root_only,
272
276
  **(core_additional_arguments or {}),
273
277
  **(nlu_additional_arguments or {}),
274
278
  )
@@ -284,6 +288,7 @@ async def _train_graph(
284
288
  dry_run: bool = False,
285
289
  remote_storage: Optional[StorageType] = None,
286
290
  keep_local_model_copy: bool = False,
291
+ remote_root_only: bool = False,
287
292
  **kwargs: Any,
288
293
  ) -> TrainingResult:
289
294
  if model_to_finetune:
@@ -363,7 +368,9 @@ async def _train_graph(
363
368
  is_finetuning=is_finetuning,
364
369
  )
365
370
  if remote_storage:
366
- push_model_to_remote_storage(full_model_path, remote_storage)
371
+ push_model_to_remote_storage(
372
+ full_model_path, remote_storage, remote_root_only
373
+ )
367
374
  if not keep_local_model_copy:
368
375
  full_model_path.unlink()
369
376
  structlogger.info(
@@ -581,14 +588,16 @@ async def train_nlu(
581
588
  ).model
582
589
 
583
590
 
584
- def push_model_to_remote_storage(model_path: Path, remote_storage: StorageType) -> None:
591
+ def push_model_to_remote_storage(
592
+ model_path: Path, remote_storage: StorageType, remote_root_only: bool = False
593
+ ) -> None:
585
594
  """Push model to remote storage."""
586
595
  from rasa.core.persistor import get_persistor
587
596
 
588
597
  persistor = get_persistor(remote_storage)
589
598
 
590
599
  if persistor is not None:
591
- persistor.persist(str(model_path))
600
+ persistor.persist(str(model_path), remote_root_only)
592
601
 
593
602
  else:
594
603
  raise RasaException(
@@ -1,9 +1,11 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import logging
4
+ import shutil
4
5
  import typing
5
6
  from collections import OrderedDict
6
7
  from enum import Enum
8
+ from pathlib import Path
7
9
  from typing import Any, Callable, Dict, List, Optional, Text, Tuple, Type
8
10
 
9
11
  import numpy as np
@@ -43,6 +45,10 @@ if typing.TYPE_CHECKING:
43
45
 
44
46
  CONFIG_FEATURES = "features"
45
47
 
48
+ TAGGERS_DIR = "taggers"
49
+ CRFSUITE_MODEL_FILE_NAME = "model.crfsuite"
50
+ PLAIN_CRF_MODEL_FILE_NAME = "model.txt"
51
+
46
52
 
47
53
  class CRFToken:
48
54
  def __init__(
@@ -419,19 +425,11 @@ class CRFEntityExtractor(GraphComponent, EntityExtractorMixin):
419
425
  """Loads trained component (see parent class for full docstring)."""
420
426
  try:
421
427
  with model_storage.read_from(resource) as model_dir:
422
- dataset = rasa.shared.utils.io.read_json_file(
423
- model_dir / "crf_dataset.json"
424
- )
425
428
  crf_order = rasa.shared.utils.io.read_json_file(
426
429
  model_dir / "crf_order.json"
427
430
  )
428
431
 
429
- dataset = [
430
- [CRFToken.create_from_dict(token_data) for token_data in sub_list]
431
- for sub_list in dataset
432
- ]
433
-
434
- entity_taggers = cls.train_model(dataset, config, crf_order)
432
+ entity_taggers = cls._load_taggers(model_dir, config)
435
433
 
436
434
  entity_extractor = cls(config, model_storage, resource, entity_taggers)
437
435
  entity_extractor.crf_order = crf_order
@@ -443,19 +441,71 @@ class CRFEntityExtractor(GraphComponent, EntityExtractorMixin):
443
441
  )
444
442
  return cls(config, model_storage, resource)
445
443
 
444
+ @classmethod
445
+ def _load_taggers(
446
+ cls, model_dir: Path, config: Dict[Text, Any]
447
+ ) -> Dict[str, "CRF"]:
448
+ """
449
+ Load taggers from model directory that persists trained binary
450
+ `model.crfsuite` files.
451
+ """
452
+
453
+ import pycrfsuite
454
+ import sklearn_crfsuite
455
+
456
+ # Get tagger directories
457
+ taggers_base = model_dir / TAGGERS_DIR
458
+ if not taggers_base.exists():
459
+ return {}
460
+
461
+ taggers_dirs = [
462
+ directory for directory in taggers_base.iterdir() if directory.is_dir()
463
+ ]
464
+
465
+ entity_taggers: Dict[str, "CRF"] = {}
466
+
467
+ for tagger_dir in taggers_dirs:
468
+ # Instantiate sklearns CRF wrapper for the pycrfsuite's Tagger
469
+ entity_tagger = sklearn_crfsuite.CRF(
470
+ algorithm="lbfgs",
471
+ # coefficient for L1 penalty
472
+ c1=config["L1_c"],
473
+ # coefficient for L2 penalty
474
+ c2=config["L2_c"],
475
+ # stop earlier
476
+ max_iterations=config["max_iterations"],
477
+ # include transitions that are possible, but not observed
478
+ all_possible_transitions=True,
479
+ )
480
+
481
+ # Load pycrfsuite tagger from the persisted binary model.crfsuite file
482
+ entity_tagger._tagger = pycrfsuite.Tagger()
483
+ entity_tagger._tagger.open(str(tagger_dir / CRFSUITE_MODEL_FILE_NAME))
484
+
485
+ entity_taggers[tagger_dir.name] = entity_tagger
486
+
487
+ return entity_taggers
488
+
446
489
  def persist(self, dataset: List[List[CRFToken]]) -> None:
447
490
  """Persist this model into the passed directory."""
448
491
  with self._model_storage.write_to(self._resource) as model_dir:
449
- data_to_store = [
450
- [token.to_dict() for token in sub_list] for sub_list in dataset
451
- ]
452
-
453
- rasa.shared.utils.io.dump_obj_as_json_to_file(
454
- model_dir / "crf_dataset.json", data_to_store
455
- )
456
492
  rasa.shared.utils.io.dump_obj_as_json_to_file(
457
493
  model_dir / "crf_order.json", self.crf_order
458
494
  )
495
+ if self.entity_taggers is not None:
496
+ for tag_name, entity_tagger in self.entity_taggers.items():
497
+ # Create the directories for storing the CRF model
498
+ tagger_dir = model_dir / TAGGERS_DIR / tag_name
499
+ tagger_dir.mkdir(parents=True, exist_ok=True)
500
+ # Create a plain text version of the CRF model
501
+ entity_tagger.tagger_.dump(
502
+ str(tagger_dir / PLAIN_CRF_MODEL_FILE_NAME)
503
+ )
504
+ # Persist binary version of the model.crfsuite
505
+ shutil.copy2(
506
+ src=entity_tagger.modelfile.name,
507
+ dst=tagger_dir / CRFSUITE_MODEL_FILE_NAME,
508
+ )
459
509
 
460
510
  @classmethod
461
511
  def _crf_tokens_to_features(
rasa/shared/constants.py CHANGED
@@ -339,8 +339,3 @@ ROLE_SYSTEM = "system"
339
339
  # Used for key values in ValidateSlotPatternFlowStackFrame
340
340
  REFILL_UTTER = "refill_utter"
341
341
  REJECTIONS = "rejections"
342
-
343
- LANGFUSE_METADATA_USER_ID = "trace_user_id"
344
- LANGFUSE_METADATA_SESSION_ID = "session_id"
345
- LANGFUSE_CUSTOM_METADATA_DICT = "trace_metadata"
346
- LANGFUSE_TAGS = "tags"
@@ -4,12 +4,3 @@ LITE_LLM_API_KEY_FIELD = "api_key"
4
4
  LITE_LLM_API_VERSION_FIELD = "api_version"
5
5
  LITE_LLM_MODEL_FIELD = "model"
6
6
  LITE_LLM_AZURE_AD_TOKEN = "azure_ad_token"
7
-
8
- # Enable or disable Langfuse integration
9
- RASA_LANGFUSE_INTEGRATION_ENABLED_ENV_VAR = "RASA_LANGFUSE_INTEGRATION_ENABLED"
10
- # Langfuse configuration
11
- LANGFUSE_CALLBACK_NAME = "langfuse"
12
- LANGFUSE_HOST_ENV_VAR = "LANGFUSE_HOST"
13
- LANGFUSE_PROJECT_ID_ENV_VAR = "LANGFUSE_PROJECT_ID"
14
- LANGFUSE_PUBLIC_KEY_ENV_VAR = "LANGFUSE_PUBLIC_KEY"
15
- LANGFUSE_SECRET_KEY_ENV_VAR = "LANGFUSE_SECRET_KEY"
@@ -2,7 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  import logging
4
4
  from abc import abstractmethod
5
- from typing import Any, Dict, List, Optional, Union, cast
5
+ from typing import Any, Dict, List, Union, cast
6
6
 
7
7
  import structlog
8
8
  from litellm import acompletion, completion, validate_environment
@@ -123,11 +123,7 @@ class _BaseLiteLLMClient:
123
123
  raise ProviderClientValidationError(event_info)
124
124
 
125
125
  @suppress_logs(log_level=logging.WARNING)
126
- def completion(
127
- self,
128
- messages: Union[List[dict], List[str], str],
129
- metadata: Optional[Dict[str, Any]] = None,
130
- ) -> LLMResponse:
126
+ def completion(self, messages: Union[List[dict], List[str], str]) -> LLMResponse:
131
127
  """Synchronously generate completions for given list of messages.
132
128
 
133
129
  Args:
@@ -139,7 +135,6 @@ class _BaseLiteLLMClient:
139
135
  - a list of messages. Each message is a string and will be formatted
140
136
  as a user message.
141
137
  - a single message as a string which will be formatted as user message.
142
- metadata: Optional metadata to be passed to the LLM call.
143
138
 
144
139
  Returns:
145
140
  List of message completions.
@@ -157,9 +152,7 @@ class _BaseLiteLLMClient:
157
152
 
158
153
  @suppress_logs(log_level=logging.WARNING)
159
154
  async def acompletion(
160
- self,
161
- messages: Union[List[dict], List[str], str],
162
- metadata: Optional[Dict[str, Any]] = None,
155
+ self, messages: Union[List[dict], List[str], str]
163
156
  ) -> LLMResponse:
164
157
  """Asynchronously generate completions for given list of messages.
165
158
 
@@ -172,7 +165,6 @@ class _BaseLiteLLMClient:
172
165
  - a list of messages. Each message is a string and will be formatted
173
166
  as a user message.
174
167
  - a single message as a string which will be formatted as user message.
175
- metadata: Optional metadata to be passed to the LLM call.
176
168
 
177
169
  Returns:
178
170
  List of message completions.
@@ -183,9 +175,7 @@ class _BaseLiteLLMClient:
183
175
  try:
184
176
  formatted_messages = self._get_formatted_messages(messages)
185
177
  arguments = resolve_environment_variables(self._completion_fn_args)
186
- response = await acompletion(
187
- messages=formatted_messages, metadata=metadata, **arguments
188
- )
178
+ response = await acompletion(messages=formatted_messages, **arguments)
189
179
  return self._format_response(response)
190
180
  except Exception as e:
191
181
  message = ""
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import logging
4
- from typing import Any, Dict, List, Optional, Union
4
+ from typing import Any, Dict, List, Union
5
5
 
6
6
  import structlog
7
7
 
@@ -122,12 +122,9 @@ class LiteLLMRouterLLMClient(_BaseLiteLLMRouterClient, _BaseLiteLLMClient):
122
122
  raise ProviderClientAPIException(e)
123
123
 
124
124
  @suppress_logs(log_level=logging.WARNING)
125
- def completion(
126
- self,
127
- messages: Union[List[dict], List[str], str],
128
- metadata: Optional[Dict[str, Any]] = None,
129
- ) -> LLMResponse:
130
- """Synchronously generate completions for given list of messages.
125
+ def completion(self, messages: Union[List[dict], List[str], str]) -> LLMResponse:
126
+ """
127
+ Synchronously generate completions for given list of messages.
131
128
 
132
129
  Method overrides the base class method to call the appropriate
133
130
  completion method based on the configuration. If the chat completions
@@ -143,11 +140,8 @@ class LiteLLMRouterLLMClient(_BaseLiteLLMRouterClient, _BaseLiteLLMClient):
143
140
  - a list of messages. Each message is a string and will be formatted
144
141
  as a user message.
145
142
  - a single message as a string which will be formatted as user message.
146
- metadata: Optional metadata to be passed to the LLM call.
147
-
148
143
  Returns:
149
144
  List of message completions.
150
-
151
145
  Raises:
152
146
  ProviderClientAPIException: If the API request fails.
153
147
  """
@@ -164,11 +158,10 @@ class LiteLLMRouterLLMClient(_BaseLiteLLMRouterClient, _BaseLiteLLMClient):
164
158
 
165
159
  @suppress_logs(log_level=logging.WARNING)
166
160
  async def acompletion(
167
- self,
168
- messages: Union[List[dict], List[str], str],
169
- metadata: Optional[Dict[str, Any]] = None,
161
+ self, messages: Union[List[dict], List[str], str]
170
162
  ) -> LLMResponse:
171
- """Asynchronously generate completions for given list of messages.
163
+ """
164
+ Asynchronously generate completions for given list of messages.
172
165
 
173
166
  Method overrides the base class method to call the appropriate
174
167
  completion method based on the configuration. If the chat completions
@@ -184,11 +177,8 @@ class LiteLLMRouterLLMClient(_BaseLiteLLMRouterClient, _BaseLiteLLMClient):
184
177
  - a list of messages. Each message is a string and will be formatted
185
178
  as a user message.
186
179
  - a single message as a string which will be formatted as user message.
187
- metadata: Optional metadata to be passed to the LLM call.
188
-
189
180
  Returns:
190
181
  List of message completions.
191
-
192
182
  Raises:
193
183
  ProviderClientAPIException: If the API request fails.
194
184
  """
@@ -1,19 +1,21 @@
1
1
  from __future__ import annotations
2
2
 
3
- from typing import Any, Dict, List, Optional, Protocol, Union, runtime_checkable
3
+ from typing import Dict, List, Protocol, Union, runtime_checkable
4
4
 
5
5
  from rasa.shared.providers.llm.llm_response import LLMResponse
6
6
 
7
7
 
8
8
  @runtime_checkable
9
9
  class LLMClient(Protocol):
10
- """Protocol for an LLM client that specifies the interface for interacting
10
+ """
11
+ Protocol for an LLM client that specifies the interface for interacting
11
12
  with the API.
12
13
  """
13
14
 
14
15
  @classmethod
15
16
  def from_config(cls, config: dict) -> LLMClient:
16
- """Initializes the llm client with the given configuration.
17
+ """
18
+ Initializes the llm client with the given configuration.
17
19
 
18
20
  This class method should be implemented to parse the given
19
21
  configuration and create an instance of an llm client.
@@ -22,24 +24,17 @@ class LLMClient(Protocol):
22
24
 
23
25
  @property
24
26
  def config(self) -> Dict:
25
- """Returns the configuration for that the llm client is initialized with.
27
+ """
28
+ Returns the configuration for that the llm client is initialized with.
26
29
 
27
30
  This property should be implemented to return a dictionary containing
28
31
  the configuration settings for the llm client.
29
32
  """
30
33
  ...
31
34
 
32
- def completion(
33
- self,
34
- messages: Union[List[dict], List[str], str],
35
- metadata: Optional[Dict[str, Any]] = None,
36
- ) -> LLMResponse:
37
- """Synchronously generate completions for given list of messages.
38
- def completion(
39
- self,
40
- messages: Union[List[dict], List[str], str],
41
- metadata: Optional[Dict[str, Any]] = None,
42
- ) -> LLMResponse:
35
+ def completion(self, messages: Union[List[dict], List[str], str]) -> LLMResponse:
36
+ """
37
+ Synchronously generate completions for given list of messages.
43
38
 
44
39
  This method should be implemented to take a list of messages (as
45
40
  strings) and return a list of completions (as strings).
@@ -53,19 +48,16 @@ class LLMClient(Protocol):
53
48
  - a list of messages. Each message is a string and will be formatted
54
49
  as a user message.
55
50
  - a single message as a string which will be formatted as user message.
56
- metadata: Optional metadata to be passed to the LLM call.
57
-
58
51
  Returns:
59
52
  LLMResponse
60
53
  """
61
54
  ...
62
55
 
63
56
  async def acompletion(
64
- self,
65
- messages: Union[List[dict], List[str], str],
66
- metadata: Optional[Dict[str, Any]] = None,
57
+ self, messages: Union[List[dict], List[str], str]
67
58
  ) -> LLMResponse:
68
- """Asynchronously generate completions for given list of messages.
59
+ """
60
+ Asynchronously generate completions for given list of messages.
69
61
 
70
62
  This method should be implemented to take a list of messages (as
71
63
  strings) and return a list of completions (as strings).
@@ -79,15 +71,14 @@ class LLMClient(Protocol):
79
71
  - a list of messages. Each message is a string and will be formatted
80
72
  as a user message.
81
73
  - a single message as a string which will be formatted as user message.
82
- metadata: Optional metadata to be passed to the LLM call.
83
-
84
74
  Returns:
85
75
  LLMResponse
86
76
  """
87
77
  ...
88
78
 
89
79
  def validate_client_setup(self, *args, **kwargs) -> None: # type: ignore
90
- """Perform client setup validation.
80
+ """
81
+ Perform client setup validation.
91
82
 
92
83
  This method should be implemented to validate whether the client can be
93
84
  used with the parameters provided through configuration or environment
@@ -237,9 +237,7 @@ class SelfHostedLLMClient(_BaseLiteLLMClient):
237
237
  raise ProviderClientAPIException(e)
238
238
 
239
239
  async def acompletion(
240
- self,
241
- messages: Union[List[dict], List[str], str],
242
- metadata: Optional[Dict[str, Any]] = None,
240
+ self, messages: Union[List[dict], List[str], str]
243
241
  ) -> LLMResponse:
244
242
  """Asynchronous completion of the model with the given messages.
245
243
 
@@ -257,7 +255,6 @@ class SelfHostedLLMClient(_BaseLiteLLMClient):
257
255
  - a list of messages. Each message is a string and will be formatted
258
256
  as a user message.
259
257
  - a single message as a string which will be formatted as user message.
260
- metadata: Optional metadata to be passed to the LLM call.
261
258
 
262
259
  Returns:
263
260
  The completion response.
@@ -266,11 +263,7 @@ class SelfHostedLLMClient(_BaseLiteLLMClient):
266
263
  return await super().acompletion(messages)
267
264
  return await self._atext_completion(messages)
268
265
 
269
- def completion(
270
- self,
271
- messages: Union[List[dict], List[str], str],
272
- metadata: Optional[Dict[str, Any]] = None,
273
- ) -> LLMResponse:
266
+ def completion(self, messages: Union[List[dict], List[str], str]) -> LLMResponse:
274
267
  """Completion of the model with the given messages.
275
268
 
276
269
  Method overrides the base class method to call the appropriate
@@ -280,7 +273,6 @@ class SelfHostedLLMClient(_BaseLiteLLMClient):
280
273
 
281
274
  Args:
282
275
  messages: The messages to be used for completion.
283
- metadata: Optional metadata to be passed to the LLM call.
284
276
 
285
277
  Returns:
286
278
  The completion response.
@@ -372,7 +372,6 @@ def extract_llm_config(
372
372
  def extract_attrs_for_llm_based_command_generator(
373
373
  self: "LLMBasedCommandGenerator",
374
374
  prompt: str,
375
- metadata: Optional[Dict[str, Any]] = None,
376
375
  ) -> Dict[str, Any]:
377
376
  from rasa.dialogue_understanding.generator.flow_retrieval import (
378
377
  DEFAULT_EMBEDDINGS_CONFIG,
@@ -388,7 +387,8 @@ def extract_attrs_for_llm_based_command_generator(
388
387
 
389
388
 
390
389
  def extract_attrs_for_contextual_response_rephraser(
391
- self: Any, prompt: str
390
+ self: Any,
391
+ prompt: str,
392
392
  ) -> Dict[str, Any]:
393
393
  from rasa.core.nlg.contextual_response_rephraser import DEFAULT_LLM_CONFIG
394
394
 
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.12.10.dev1"
3
+ __version__ = "3.12.12.dev1"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: rasa-pro
3
- Version: 3.12.10.dev1
3
+ Version: 3.12.12.dev1
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
@@ -63,8 +63,7 @@ Requires-Dist: keras (==2.14.0)
63
63
  Requires-Dist: langchain (>=0.2.17,<0.3.0)
64
64
  Requires-Dist: langchain-community (>=0.2.19,<0.3.0)
65
65
  Requires-Dist: langcodes (>=3.5.0,<4.0.0)
66
- Requires-Dist: langfuse (>=2.60.2,<2.61.0)
67
- Requires-Dist: litellm (>=1.68.0,<1.69.0)
66
+ Requires-Dist: litellm (>=1.69.0,<1.70.0)
68
67
  Requires-Dist: matplotlib (>=3.7,<3.8)
69
68
  Requires-Dist: mattermostwrapper (>=2.2,<2.3)
70
69
  Requires-Dist: networkx (>=3.1,<3.2)