rasa-pro 3.13.0.dev2__py3-none-any.whl → 3.13.0.dev3__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/cli/run.py +10 -6
- rasa/cli/utils.py +7 -0
- rasa/core/channels/channel.py +30 -0
- rasa/core/channels/voice_ready/jambonz.py +25 -5
- rasa/core/channels/voice_ready/jambonz_protocol.py +4 -0
- rasa/core/information_retrieval/faiss.py +7 -68
- rasa/core/information_retrieval/information_retrieval.py +2 -40
- rasa/core/information_retrieval/milvus.py +2 -7
- rasa/core/information_retrieval/qdrant.py +2 -7
- rasa/core/nlg/contextual_response_rephraser.py +3 -0
- rasa/core/policies/enterprise_search_policy.py +310 -61
- rasa/core/policies/intentless_policy.py +3 -0
- rasa/dialogue_understanding/coexistence/llm_based_router.py +8 -0
- rasa/dialogue_understanding/commands/knowledge_answer_command.py +2 -2
- rasa/dialogue_understanding/generator/command_parser.py +1 -1
- rasa/dialogue_understanding/generator/flow_retrieval.py +1 -4
- rasa/dialogue_understanding/generator/llm_based_command_generator.py +1 -2
- rasa/dialogue_understanding/generator/multi_step/multi_step_llm_command_generator.py +13 -0
- rasa/dialogue_understanding/generator/prompt_templates/command_prompt_template.jinja2 +1 -1
- rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v2_claude_3_5_sonnet_20240620_template.jinja2 +1 -1
- rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v2_gpt_4o_2024_11_20_template.jinja2 +2 -24
- rasa/dialogue_understanding/generator/single_step/compact_llm_command_generator.py +22 -17
- rasa/dialogue_understanding/generator/single_step/single_step_llm_command_generator.py +27 -12
- rasa/dialogue_understanding_test/io.py +8 -13
- rasa/e2e_test/utils/validation.py +3 -3
- rasa/engine/recipes/default_components.py +0 -2
- rasa/llm_fine_tuning/paraphrasing/conversation_rephraser.py +3 -0
- rasa/shared/utils/constants.py +3 -0
- rasa/shared/utils/llm.py +70 -24
- rasa/tracing/instrumentation/attribute_extractors.py +7 -10
- rasa/tracing/instrumentation/instrumentation.py +12 -12
- rasa/version.py +1 -1
- {rasa_pro-3.13.0.dev2.dist-info → rasa_pro-3.13.0.dev3.dist-info}/METADATA +2 -2
- {rasa_pro-3.13.0.dev2.dist-info → rasa_pro-3.13.0.dev3.dist-info}/RECORD +37 -48
- rasa/document_retrieval/__init__.py +0 -0
- rasa/document_retrieval/constants.py +0 -32
- rasa/document_retrieval/document_post_processor.py +0 -351
- rasa/document_retrieval/document_post_processor_prompt_template.jinja2 +0 -0
- rasa/document_retrieval/document_retriever.py +0 -333
- rasa/document_retrieval/knowledge_base_connectors/__init__.py +0 -0
- rasa/document_retrieval/knowledge_base_connectors/api_connector.py +0 -39
- rasa/document_retrieval/knowledge_base_connectors/knowledge_base_connector.py +0 -34
- rasa/document_retrieval/knowledge_base_connectors/vector_store_connector.py +0 -226
- rasa/document_retrieval/query_rewriter.py +0 -234
- rasa/document_retrieval/query_rewriter_prompt_template.jinja2 +0 -8
- {rasa_pro-3.13.0.dev2.dist-info → rasa_pro-3.13.0.dev3.dist-info}/NOTICE +0 -0
- {rasa_pro-3.13.0.dev2.dist-info → rasa_pro-3.13.0.dev3.dist-info}/WHEEL +0 -0
- {rasa_pro-3.13.0.dev2.dist-info → rasa_pro-3.13.0.dev3.dist-info}/entry_points.txt +0 -0
rasa/cli/run.py
CHANGED
|
@@ -64,12 +64,16 @@ def run_actions(args: argparse.Namespace) -> None:
|
|
|
64
64
|
|
|
65
65
|
def _validate_model_path(model_path: Text, parameter: Text, default: Text) -> Text:
|
|
66
66
|
if model_path is not None and not os.path.exists(model_path):
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
67
|
+
raise ModelNotFound(
|
|
68
|
+
f"The provided model path '{model_path}' could not be found. "
|
|
69
|
+
"Provide an existing model path."
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
if model_path is None:
|
|
73
|
+
logger.debug(
|
|
74
|
+
f"Parameter '{parameter}' not set. "
|
|
75
|
+
"Using default location '{default}' instead."
|
|
76
|
+
)
|
|
73
77
|
os.makedirs(default, exist_ok=True)
|
|
74
78
|
model_path = default
|
|
75
79
|
|
rasa/cli/utils.py
CHANGED
|
@@ -14,6 +14,7 @@ import structlog
|
|
|
14
14
|
import rasa.shared.utils.cli
|
|
15
15
|
import rasa.shared.utils.io
|
|
16
16
|
from rasa import telemetry
|
|
17
|
+
from rasa.exceptions import ModelNotFound
|
|
17
18
|
from rasa.shared.constants import (
|
|
18
19
|
ASSISTANT_ID_DEFAULT_VALUE,
|
|
19
20
|
ASSISTANT_ID_KEY,
|
|
@@ -77,6 +78,12 @@ def get_validated_path(
|
|
|
77
78
|
if current and os.path.exists(current):
|
|
78
79
|
return current
|
|
79
80
|
|
|
81
|
+
if parameter == "model":
|
|
82
|
+
raise ModelNotFound(
|
|
83
|
+
f"The provided model path '{current}' could not be found. "
|
|
84
|
+
"Provide an existing model path."
|
|
85
|
+
)
|
|
86
|
+
|
|
80
87
|
# try to find a valid option among the defaults
|
|
81
88
|
if isinstance(default, str) or isinstance(default, Path):
|
|
82
89
|
default_options = [str(default)]
|
rasa/core/channels/channel.py
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
import hmac
|
|
1
2
|
import json
|
|
2
3
|
import logging
|
|
3
4
|
import uuid
|
|
5
|
+
from base64 import b64encode
|
|
6
|
+
from functools import wraps
|
|
4
7
|
from typing import (
|
|
5
8
|
Any,
|
|
6
9
|
Awaitable,
|
|
@@ -15,6 +18,7 @@ from typing import (
|
|
|
15
18
|
|
|
16
19
|
import jwt
|
|
17
20
|
from sanic import Blueprint, Sanic
|
|
21
|
+
from sanic.exceptions import Unauthorized
|
|
18
22
|
from sanic.request import Request
|
|
19
23
|
|
|
20
24
|
from rasa.cli import utils as cli_utils
|
|
@@ -454,3 +458,29 @@ class CollectingOutputChannel(OutputChannel):
|
|
|
454
458
|
self, recipient_id: Text, json_message: Dict[Text, Any], **kwargs: Any
|
|
455
459
|
) -> None:
|
|
456
460
|
await self._persist_message(self._message(recipient_id, custom=json_message))
|
|
461
|
+
|
|
462
|
+
|
|
463
|
+
def requires_basic_auth(username: Optional[Text], password: Optional[Text]) -> Callable:
|
|
464
|
+
"""Decorator to require basic auth for a route."""
|
|
465
|
+
|
|
466
|
+
def decorator(func: Callable) -> Callable:
|
|
467
|
+
@wraps(func)
|
|
468
|
+
async def wrapper(request: Request, *args: Any, **kwargs: Any) -> Any:
|
|
469
|
+
if not username or not password:
|
|
470
|
+
return await func(request, *args, **kwargs)
|
|
471
|
+
|
|
472
|
+
auth = request.headers.get("Authorization")
|
|
473
|
+
if not auth or not auth.startswith("Basic "):
|
|
474
|
+
logger.error("Missing or invalid authorization header.")
|
|
475
|
+
raise Unauthorized("Missing or invalid authorization header.") # type: ignore[no-untyped-call]
|
|
476
|
+
|
|
477
|
+
encoded = b64encode(f"{username}:{password}".encode()).decode()
|
|
478
|
+
if not hmac.compare_digest(auth[6:], encoded):
|
|
479
|
+
logger.error("Invalid username or password.")
|
|
480
|
+
raise Unauthorized("Invalid username or password.") # type: ignore[no-untyped-call]
|
|
481
|
+
|
|
482
|
+
return await func(request, *args, **kwargs)
|
|
483
|
+
|
|
484
|
+
return wrapper
|
|
485
|
+
|
|
486
|
+
return decorator
|
|
@@ -5,8 +5,14 @@ from sanic import Blueprint, Websocket, response # type: ignore[attr-defined]
|
|
|
5
5
|
from sanic.request import Request
|
|
6
6
|
from sanic.response import HTTPResponse
|
|
7
7
|
|
|
8
|
-
from rasa.core.channels.channel import
|
|
8
|
+
from rasa.core.channels.channel import (
|
|
9
|
+
InputChannel,
|
|
10
|
+
OutputChannel,
|
|
11
|
+
UserMessage,
|
|
12
|
+
requires_basic_auth,
|
|
13
|
+
)
|
|
9
14
|
from rasa.core.channels.voice_ready.jambonz_protocol import (
|
|
15
|
+
CHANNEL_NAME,
|
|
10
16
|
send_ws_hangup_message,
|
|
11
17
|
send_ws_text_message,
|
|
12
18
|
websocket_message_handler,
|
|
@@ -18,8 +24,6 @@ from rasa.utils.io import remove_emojis
|
|
|
18
24
|
|
|
19
25
|
structlogger = structlog.get_logger()
|
|
20
26
|
|
|
21
|
-
CHANNEL_NAME = "jambonz"
|
|
22
|
-
|
|
23
27
|
DEFAULT_HANGUP_DELAY_SECONDS = 1
|
|
24
28
|
|
|
25
29
|
|
|
@@ -32,12 +36,27 @@ class JambonzVoiceReadyInput(InputChannel):
|
|
|
32
36
|
|
|
33
37
|
@classmethod
|
|
34
38
|
def from_credentials(cls, credentials: Optional[Dict[Text, Any]]) -> InputChannel:
|
|
35
|
-
|
|
39
|
+
if not credentials:
|
|
40
|
+
return cls()
|
|
41
|
+
|
|
42
|
+
username = credentials.get("username")
|
|
43
|
+
password = credentials.get("password")
|
|
44
|
+
if (username is None) != (password is None):
|
|
45
|
+
raise RasaException(
|
|
46
|
+
"In Jambonz channel, either both username and password "
|
|
47
|
+
"or neither should be provided. "
|
|
48
|
+
)
|
|
36
49
|
|
|
37
|
-
|
|
50
|
+
return cls(username, password)
|
|
51
|
+
|
|
52
|
+
def __init__(
|
|
53
|
+
self, username: Optional[Text] = None, password: Optional[Text] = None
|
|
54
|
+
) -> None:
|
|
38
55
|
"""Initializes the JambonzVoiceReadyInput channel."""
|
|
39
56
|
mark_as_beta_feature("Jambonz Channel")
|
|
40
57
|
validate_voice_license_scope()
|
|
58
|
+
self.username = username
|
|
59
|
+
self.password = password
|
|
41
60
|
|
|
42
61
|
def blueprint(
|
|
43
62
|
self, on_new_message: Callable[[UserMessage], Awaitable[Any]]
|
|
@@ -50,6 +69,7 @@ class JambonzVoiceReadyInput(InputChannel):
|
|
|
50
69
|
return response.json({"status": "ok"})
|
|
51
70
|
|
|
52
71
|
@jambonz_webhook.websocket("/websocket", subprotocols=["ws.jambonz.org"]) # type: ignore
|
|
72
|
+
@requires_basic_auth(self.username, self.password)
|
|
53
73
|
async def websocket(request: Request, ws: Websocket) -> None:
|
|
54
74
|
"""Triggered on new websocket connection."""
|
|
55
75
|
async for message in ws:
|
|
@@ -10,6 +10,7 @@ from rasa.core.channels.channel import UserMessage
|
|
|
10
10
|
from rasa.core.channels.voice_ready.utils import CallParameters
|
|
11
11
|
|
|
12
12
|
structlogger = structlog.get_logger()
|
|
13
|
+
CHANNEL_NAME = "jambonz"
|
|
13
14
|
|
|
14
15
|
|
|
15
16
|
@dataclass
|
|
@@ -206,6 +207,7 @@ async def handle_new_session(
|
|
|
206
207
|
output_channel=output_channel,
|
|
207
208
|
sender_id=message.call_sid,
|
|
208
209
|
metadata=asdict(message.call_params),
|
|
210
|
+
input_channel=CHANNEL_NAME,
|
|
209
211
|
)
|
|
210
212
|
await send_config_ack(message.message_id, ws)
|
|
211
213
|
await on_new_message(user_msg)
|
|
@@ -238,6 +240,7 @@ async def handle_gather_completed(
|
|
|
238
240
|
output_channel = JambonzWebsocketOutput(ws, transcript_result.call_sid)
|
|
239
241
|
user_msg = UserMessage(
|
|
240
242
|
text=most_likely_transcript.text,
|
|
243
|
+
input_channel=CHANNEL_NAME,
|
|
241
244
|
output_channel=output_channel,
|
|
242
245
|
sender_id=transcript_result.call_sid,
|
|
243
246
|
metadata={},
|
|
@@ -288,6 +291,7 @@ async def handle_call_status(
|
|
|
288
291
|
output_channel = JambonzWebsocketOutput(ws, call_status.call_sid)
|
|
289
292
|
user_msg = UserMessage(
|
|
290
293
|
text="/session_end",
|
|
294
|
+
input_channel=CHANNEL_NAME,
|
|
291
295
|
output_channel=output_channel,
|
|
292
296
|
sender_id=call_status.call_sid,
|
|
293
297
|
metadata={},
|
|
@@ -31,12 +31,10 @@ class FAISS_Store(InformationRetrieval):
|
|
|
31
31
|
index_path: str,
|
|
32
32
|
docs_folder: Optional[str],
|
|
33
33
|
create_index: Optional[bool] = False,
|
|
34
|
-
use_llm: bool = False,
|
|
35
34
|
):
|
|
36
35
|
"""Initializes the FAISS Store."""
|
|
37
36
|
self.chunk_size = 1000
|
|
38
37
|
self.chunk_overlap = 20
|
|
39
|
-
self.use_llm = use_llm
|
|
40
38
|
|
|
41
39
|
path = Path(index_path) / "documents_faiss"
|
|
42
40
|
if create_index:
|
|
@@ -73,57 +71,6 @@ class FAISS_Store(InformationRetrieval):
|
|
|
73
71
|
|
|
74
72
|
return loader.load()
|
|
75
73
|
|
|
76
|
-
def _format_faqs(self, docs: List["Document"]) -> List["Document"]:
|
|
77
|
-
"""Splits each loaded file into individual FAQs.
|
|
78
|
-
|
|
79
|
-
Args:
|
|
80
|
-
docs: Documents representing whole files containing FAQs.
|
|
81
|
-
|
|
82
|
-
Returns:
|
|
83
|
-
List of Document objects, each containing a separate FAQ.
|
|
84
|
-
|
|
85
|
-
Examples:
|
|
86
|
-
An example of a file containing FAQs:
|
|
87
|
-
|
|
88
|
-
Q: Who is Finley?
|
|
89
|
-
A: Finley is your smart assistant for the FinX App. You can add him to your
|
|
90
|
-
favorite messenger and tell him what you need help with.
|
|
91
|
-
|
|
92
|
-
Q: How does Finley work?
|
|
93
|
-
A: Finley is powered by the latest chatbot technology leveraging a unique
|
|
94
|
-
interplay of large language models and secure logic.
|
|
95
|
-
|
|
96
|
-
More details in documentation: https://rasa.com/docs/reference/config/policies/extractive-search/
|
|
97
|
-
"""
|
|
98
|
-
structured_faqs = []
|
|
99
|
-
from langchain.schema import Document
|
|
100
|
-
|
|
101
|
-
for doc in docs:
|
|
102
|
-
faq_chunks = doc.page_content.strip().split("\n\n")
|
|
103
|
-
|
|
104
|
-
for chunk in faq_chunks:
|
|
105
|
-
lines = chunk.strip().split("\n")
|
|
106
|
-
if len(lines) < 2:
|
|
107
|
-
continue # Skip if something unexpected
|
|
108
|
-
|
|
109
|
-
question_line = lines[0].strip()
|
|
110
|
-
answer_line = lines[1].strip()
|
|
111
|
-
|
|
112
|
-
question = question_line.replace("Q: ", "").strip()
|
|
113
|
-
answer = answer_line.replace("A: ", "").strip()
|
|
114
|
-
|
|
115
|
-
doc_obj = Document(
|
|
116
|
-
page_content=question,
|
|
117
|
-
metadata={
|
|
118
|
-
"title": question.lower().replace(" ", "_")[:-1],
|
|
119
|
-
"type": "faq",
|
|
120
|
-
"answer": answer,
|
|
121
|
-
},
|
|
122
|
-
)
|
|
123
|
-
|
|
124
|
-
structured_faqs.append(doc_obj)
|
|
125
|
-
return structured_faqs
|
|
126
|
-
|
|
127
74
|
def _create_document_index(
|
|
128
75
|
self, docs_folder: Optional[str], embedding: "Embeddings"
|
|
129
76
|
) -> FAISS:
|
|
@@ -140,15 +87,12 @@ class FAISS_Store(InformationRetrieval):
|
|
|
140
87
|
raise ValueError("parameter `docs_folder` needs to be specified")
|
|
141
88
|
|
|
142
89
|
docs = self.load_documents(docs_folder)
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
doc_chunks = splitter.split_documents(docs)
|
|
150
|
-
else:
|
|
151
|
-
doc_chunks = self._format_faqs(docs)
|
|
90
|
+
splitter = RecursiveCharacterTextSplitter(
|
|
91
|
+
chunk_size=self.chunk_size,
|
|
92
|
+
chunk_overlap=self.chunk_overlap,
|
|
93
|
+
length_function=len,
|
|
94
|
+
)
|
|
95
|
+
doc_chunks = splitter.split_documents(docs)
|
|
152
96
|
|
|
153
97
|
logger.info(
|
|
154
98
|
"information_retrieval.faiss_store._create_document_index",
|
|
@@ -169,15 +113,10 @@ class FAISS_Store(InformationRetrieval):
|
|
|
169
113
|
pass
|
|
170
114
|
|
|
171
115
|
async def search(
|
|
172
|
-
self,
|
|
173
|
-
query: Text,
|
|
174
|
-
tracker_state: Dict[str, Any],
|
|
175
|
-
threshold: float = 0.0,
|
|
176
|
-
k: int = 1,
|
|
116
|
+
self, query: Text, tracker_state: Dict[str, Any], threshold: float = 0.0
|
|
177
117
|
) -> SearchResultList:
|
|
178
118
|
logger.debug("information_retrieval.faiss_store.search", query=query)
|
|
179
119
|
try:
|
|
180
|
-
# TODO: make use of k
|
|
181
120
|
documents = await self.index.as_retriever().ainvoke(query)
|
|
182
121
|
except Exception as exc:
|
|
183
122
|
raise InformationRetrievalException from exc
|
|
@@ -36,19 +36,6 @@ class SearchResult:
|
|
|
36
36
|
"""Construct a SearchResult object from Langchain Document object."""
|
|
37
37
|
return cls(text=document.page_content, metadata=document.metadata)
|
|
38
38
|
|
|
39
|
-
@classmethod
|
|
40
|
-
def from_dict(cls, data: dict[str, Any]) -> "SearchResult":
|
|
41
|
-
"""Construct a SearchResult object from a JSON object."""
|
|
42
|
-
return cls(text=data["text"], metadata=data["metadata"], score=data["score"])
|
|
43
|
-
|
|
44
|
-
def to_dict(self) -> dict[str, Any]:
|
|
45
|
-
"""Convert the SearchResult object to a dictionary."""
|
|
46
|
-
return {
|
|
47
|
-
"text": self.text,
|
|
48
|
-
"metadata": self.metadata,
|
|
49
|
-
"score": self.score,
|
|
50
|
-
}
|
|
51
|
-
|
|
52
39
|
|
|
53
40
|
@dataclass
|
|
54
41
|
class SearchResultList:
|
|
@@ -57,7 +44,8 @@ class SearchResultList:
|
|
|
57
44
|
|
|
58
45
|
@classmethod
|
|
59
46
|
def from_document_list(cls, documents: List["Document"]) -> "SearchResultList":
|
|
60
|
-
"""
|
|
47
|
+
"""
|
|
48
|
+
Convert a list of Langchain Documents to a SearchResultList object.
|
|
61
49
|
|
|
62
50
|
Args:
|
|
63
51
|
documents: List of Langchain Documents.
|
|
@@ -70,31 +58,6 @@ class SearchResultList:
|
|
|
70
58
|
metadata={"total_results": len(documents)},
|
|
71
59
|
)
|
|
72
60
|
|
|
73
|
-
@classmethod
|
|
74
|
-
def from_dict(cls, data: dict[str, Any]) -> "SearchResultList":
|
|
75
|
-
"""Convert a JSON object to a SearchResultList object.
|
|
76
|
-
|
|
77
|
-
Args:
|
|
78
|
-
data: JSON object.
|
|
79
|
-
|
|
80
|
-
Returns:
|
|
81
|
-
SearchResultList object.
|
|
82
|
-
"""
|
|
83
|
-
if not data:
|
|
84
|
-
return cls(results=[], metadata={})
|
|
85
|
-
|
|
86
|
-
return cls(
|
|
87
|
-
results=[SearchResult.from_dict(result) for result in data["results"]],
|
|
88
|
-
metadata=data["metadata"],
|
|
89
|
-
)
|
|
90
|
-
|
|
91
|
-
def to_dict(self) -> dict[str, Any]:
|
|
92
|
-
"""Convert the SearchResultList object to a dictionary."""
|
|
93
|
-
return {
|
|
94
|
-
"results": [result.to_dict() for result in self.results],
|
|
95
|
-
"metadata": self.metadata,
|
|
96
|
-
}
|
|
97
|
-
|
|
98
61
|
|
|
99
62
|
class InformationRetrievalException(RasaException):
|
|
100
63
|
"""Base class for exceptions raised by InformationRetrieval operations."""
|
|
@@ -126,7 +89,6 @@ class InformationRetrieval:
|
|
|
126
89
|
query: Text,
|
|
127
90
|
tracker_state: dict[str, Any],
|
|
128
91
|
threshold: float = 0.0,
|
|
129
|
-
k: int = 1,
|
|
130
92
|
) -> SearchResultList:
|
|
131
93
|
"""Search for a document in the InformationRetrieval system."""
|
|
132
94
|
raise NotImplementedError(
|
|
@@ -31,25 +31,20 @@ class Milvus_Store(InformationRetrieval):
|
|
|
31
31
|
)
|
|
32
32
|
|
|
33
33
|
async def search(
|
|
34
|
-
self,
|
|
35
|
-
query: Text,
|
|
36
|
-
tracker_state: Dict[str, Any],
|
|
37
|
-
threshold: float = 0.0,
|
|
38
|
-
k: int = 1,
|
|
34
|
+
self, query: Text, tracker_state: Dict[str, Any], threshold: float = 0.0
|
|
39
35
|
) -> SearchResultList:
|
|
40
36
|
"""Search for documents in the Milvus store.
|
|
41
37
|
|
|
42
38
|
Args:
|
|
43
39
|
query: The query to search for.
|
|
44
40
|
threshold: minimum similarity score to consider a document a match.
|
|
45
|
-
k: number of results to return.
|
|
46
41
|
|
|
47
42
|
Returns:
|
|
48
43
|
A list of documents that match the query.
|
|
49
44
|
"""
|
|
50
45
|
logger.debug("information_retrieval.milvus_store.search", query=query)
|
|
51
46
|
try:
|
|
52
|
-
hits = await self.client.asimilarity_search_with_score(query, k=
|
|
47
|
+
hits = await self.client.asimilarity_search_with_score(query, k=4)
|
|
53
48
|
except Exception as exc:
|
|
54
49
|
raise InformationRetrievalException from exc
|
|
55
50
|
|
|
@@ -66,18 +66,13 @@ class Qdrant_Store(InformationRetrieval):
|
|
|
66
66
|
)
|
|
67
67
|
|
|
68
68
|
async def search(
|
|
69
|
-
self,
|
|
70
|
-
query: Text,
|
|
71
|
-
tracker_state: Dict[str, Any],
|
|
72
|
-
threshold: float = 0.0,
|
|
73
|
-
k: int = 1,
|
|
69
|
+
self, query: Text, tracker_state: Dict[str, Any], threshold: float = 0.0
|
|
74
70
|
) -> SearchResultList:
|
|
75
71
|
"""Search for a document in the Qdrant vector store.
|
|
76
72
|
|
|
77
73
|
Args:
|
|
78
74
|
query: The query to search for.
|
|
79
75
|
threshold: minimum similarity score to consider a document a match.
|
|
80
|
-
k: number of results to return.
|
|
81
76
|
|
|
82
77
|
Returns:
|
|
83
78
|
A list of documents that match the query.
|
|
@@ -85,7 +80,7 @@ class Qdrant_Store(InformationRetrieval):
|
|
|
85
80
|
logger.debug("information_retrieval.qdrant_store.search", query=query)
|
|
86
81
|
try:
|
|
87
82
|
hits = await self.client.asimilarity_search(
|
|
88
|
-
query, k=
|
|
83
|
+
query, k=4, score_threshold=threshold
|
|
89
84
|
)
|
|
90
85
|
except ValidationError as e:
|
|
91
86
|
raise PayloadNotFoundException(
|
|
@@ -27,6 +27,7 @@ from rasa.shared.nlu.constants import (
|
|
|
27
27
|
PROMPTS,
|
|
28
28
|
)
|
|
29
29
|
from rasa.shared.providers.llm.llm_response import LLMResponse, measure_llm_latency
|
|
30
|
+
from rasa.shared.utils.constants import LOG_COMPONENT_SOURCE_METHOD_INIT
|
|
30
31
|
from rasa.shared.utils.health_check.llm_health_check_mixin import LLMHealthCheckMixin
|
|
31
32
|
from rasa.shared.utils.llm import (
|
|
32
33
|
DEFAULT_OPENAI_GENERATE_MODEL_NAME,
|
|
@@ -105,6 +106,8 @@ class ContextualResponseRephraser(
|
|
|
105
106
|
self.prompt_template = get_prompt_template(
|
|
106
107
|
self.nlg_endpoint.kwargs.get(PROMPT_CONFIG_KEY),
|
|
107
108
|
DEFAULT_RESPONSE_VARIATION_PROMPT_TEMPLATE,
|
|
109
|
+
log_source_component=ContextualResponseRephraser.__name__,
|
|
110
|
+
log_source_method=LOG_COMPONENT_SOURCE_METHOD_INIT,
|
|
108
111
|
)
|
|
109
112
|
self.rephrase_all = self.nlg_endpoint.kwargs.get(
|
|
110
113
|
"rephrase_all", DEFAULT_REPHRASE_ALL
|