rasa-pro 3.11.9__py3-none-any.whl → 3.11.10__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/core/channels/voice_ready/audiocodes.py +34 -17
- rasa/shared/core/flows/flow.py +122 -126
- rasa/version.py +1 -1
- {rasa_pro-3.11.9.dist-info → rasa_pro-3.11.10.dist-info}/METADATA +1 -1
- {rasa_pro-3.11.9.dist-info → rasa_pro-3.11.10.dist-info}/RECORD +8 -8
- {rasa_pro-3.11.9.dist-info → rasa_pro-3.11.10.dist-info}/NOTICE +0 -0
- {rasa_pro-3.11.9.dist-info → rasa_pro-3.11.10.dist-info}/WHEEL +0 -0
- {rasa_pro-3.11.9.dist-info → rasa_pro-3.11.10.dist-info}/entry_points.txt +0 -0
|
@@ -139,6 +139,12 @@ class Conversation:
|
|
|
139
139
|
structlogger.warning(
|
|
140
140
|
"audiocodes.handle.activities.duplicate_activity",
|
|
141
141
|
activity_id=activity[ACTIVITY_ID_KEY],
|
|
142
|
+
event_info=(
|
|
143
|
+
"Audiocodes might send duplicate activities if the bot has not "
|
|
144
|
+
"responded to the previous one or responded too late. Please "
|
|
145
|
+
"consider enabling the `use_websocket` option to use"
|
|
146
|
+
" Audiocodes Asynchronous API."
|
|
147
|
+
),
|
|
142
148
|
)
|
|
143
149
|
continue
|
|
144
150
|
self.activity_ids.append(activity[ACTIVITY_ID_KEY])
|
|
@@ -390,30 +396,41 @@ class AudiocodesInput(InputChannel):
|
|
|
390
396
|
"audiocodes.on_activities.no_conversation", request=request.json
|
|
391
397
|
)
|
|
392
398
|
return response.json({})
|
|
393
|
-
|
|
399
|
+
|
|
400
|
+
if self.use_websocket:
|
|
401
|
+
# send an empty response for this request
|
|
402
|
+
# activities are processed in the background
|
|
403
|
+
# chat response is sent via the websocket
|
|
394
404
|
ac_output: Union[WebsocketOutput, AudiocodesOutput] = WebsocketOutput(
|
|
395
405
|
conversation.ws, conversation_id
|
|
396
406
|
)
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
407
|
+
self._create_task(
|
|
408
|
+
conversation_id,
|
|
409
|
+
conversation.handle_activities(
|
|
410
|
+
request.json,
|
|
411
|
+
input_channel_name=self.name(),
|
|
412
|
+
output_channel=ac_output,
|
|
413
|
+
on_new_message=on_new_message,
|
|
414
|
+
),
|
|
415
|
+
)
|
|
416
|
+
return response.json({})
|
|
417
|
+
|
|
418
|
+
# without websockets, this becomes a blocking call
|
|
419
|
+
# and the response is sent back to the Audiocodes server
|
|
420
|
+
# after the activities are processed
|
|
421
|
+
ac_output = AudiocodesOutput()
|
|
422
|
+
await conversation.handle_activities(
|
|
423
|
+
request.json,
|
|
424
|
+
input_channel_name=self.name(),
|
|
425
|
+
output_channel=ac_output,
|
|
426
|
+
on_new_message=on_new_message,
|
|
427
|
+
)
|
|
428
|
+
return response.json(
|
|
429
|
+
{
|
|
402
430
|
"conversation": conversation_id,
|
|
403
431
|
"activities": ac_output.messages,
|
|
404
432
|
}
|
|
405
|
-
|
|
406
|
-
# start a background task to handle activities
|
|
407
|
-
self._create_task(
|
|
408
|
-
conversation_id,
|
|
409
|
-
conversation.handle_activities(
|
|
410
|
-
request.json,
|
|
411
|
-
input_channel_name=self.name(),
|
|
412
|
-
output_channel=ac_output,
|
|
413
|
-
on_new_message=on_new_message,
|
|
414
|
-
),
|
|
415
433
|
)
|
|
416
|
-
return response.json(response_json)
|
|
417
434
|
|
|
418
435
|
@ac_webhook.route(
|
|
419
436
|
"/conversation/<conversation_id>/disconnect", methods=["POST"]
|
rasa/shared/core/flows/flow.py
CHANGED
|
@@ -22,10 +22,11 @@ from rasa.shared.core.flows.flow_step_links import (
|
|
|
22
22
|
from rasa.shared.core.flows.flow_step_sequence import FlowStepSequence
|
|
23
23
|
from rasa.shared.core.flows.nlu_trigger import NLUTriggers
|
|
24
24
|
from rasa.shared.core.flows.steps import (
|
|
25
|
+
ActionFlowStep,
|
|
26
|
+
CallFlowStep,
|
|
25
27
|
CollectInformationFlowStep,
|
|
26
28
|
EndFlowStep,
|
|
27
29
|
StartFlowStep,
|
|
28
|
-
ActionFlowStep,
|
|
29
30
|
)
|
|
30
31
|
from rasa.shared.core.flows.steps.constants import (
|
|
31
32
|
CONTINUE_STEP_PREFIX,
|
|
@@ -402,161 +403,156 @@ class Flow:
|
|
|
402
403
|
and a set of visited step IDs to prevent revisiting steps.
|
|
403
404
|
It calls `go_over_steps` to recursively explore and fill the paths list.
|
|
404
405
|
"""
|
|
405
|
-
|
|
406
|
-
|
|
406
|
+
all_paths = FlowPathsList(self.id, paths=[])
|
|
407
|
+
start_step: FlowStep = self.first_step_in_flow()
|
|
407
408
|
current_path: FlowPath = FlowPath(flow=self.id, nodes=[])
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
self._go_over_steps(steps, current_path, flow_paths_list, step_ids_visited)
|
|
409
|
+
visited_step_ids: Set[str] = set()
|
|
411
410
|
|
|
412
|
-
|
|
413
|
-
flow_paths_list.paths.append(copy.deepcopy(current_path))
|
|
411
|
+
self._go_over_steps(start_step, current_path, all_paths, visited_step_ids)
|
|
414
412
|
|
|
415
413
|
structlogger.debug(
|
|
416
414
|
"shared.core.flows.flow.extract_all_paths",
|
|
417
415
|
comment="Extraction complete",
|
|
418
|
-
number_of_paths=len(
|
|
416
|
+
number_of_paths=len(all_paths.paths),
|
|
419
417
|
flow_name=self.name,
|
|
420
418
|
)
|
|
421
|
-
return
|
|
419
|
+
return all_paths
|
|
422
420
|
|
|
423
421
|
def _go_over_steps(
|
|
424
422
|
self,
|
|
425
|
-
|
|
423
|
+
current_step: FlowStep,
|
|
426
424
|
current_path: FlowPath,
|
|
427
|
-
|
|
428
|
-
|
|
425
|
+
all_paths: FlowPathsList,
|
|
426
|
+
visited_step_ids: Set[str],
|
|
429
427
|
) -> None:
|
|
430
428
|
"""Processes the flow steps recursively.
|
|
431
429
|
|
|
432
|
-
Either following direct step IDs or handling conditions, and adds complete
|
|
433
|
-
paths to the collected_paths.
|
|
434
|
-
|
|
435
430
|
Args:
|
|
436
|
-
|
|
431
|
+
current_step: The current step being processed.
|
|
437
432
|
current_path: The current path being constructed.
|
|
438
|
-
|
|
439
|
-
|
|
433
|
+
all_paths: The list where completed paths are added.
|
|
434
|
+
visited_step_ids: A set of steps that have been visited to avoid cycles.
|
|
440
435
|
|
|
441
436
|
Returns:
|
|
442
|
-
None: This function modifies
|
|
437
|
+
None: This function modifies all_paths in place by appending new paths
|
|
443
438
|
as they are found.
|
|
444
439
|
"""
|
|
445
|
-
#
|
|
446
|
-
#
|
|
447
|
-
#
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
# We only create new path nodes for ActionFlowStep and
|
|
462
|
-
# CollectInformationFlowStep because these are externally visible
|
|
463
|
-
# changes in the assistant's behaviour (trackable in the e2e tests).
|
|
464
|
-
# For other flow steps, we only follow their links.
|
|
465
|
-
# We decided to ignore calls to other flows in our coverage analysis.
|
|
466
|
-
if not isinstance(step, (CollectInformationFlowStep, ActionFlowStep)):
|
|
467
|
-
self._handle_links(
|
|
468
|
-
step.next.links,
|
|
469
|
-
current_path,
|
|
470
|
-
completed_paths,
|
|
471
|
-
step_ids_visited,
|
|
472
|
-
)
|
|
473
|
-
continue
|
|
474
|
-
|
|
475
|
-
# 2. Check if already visited this custom step id
|
|
476
|
-
# in order to keep track of loops
|
|
477
|
-
if step.custom_id is not None and step.custom_id in step_ids_visited:
|
|
478
|
-
if not completed_paths.is_path_part_of_list(current_path):
|
|
479
|
-
completed_paths.paths.append(copy.deepcopy(current_path))
|
|
480
|
-
return # Stop traversing this path if we've revisited a step
|
|
481
|
-
elif step.custom_id is not None:
|
|
482
|
-
step_ids_visited.add(step.custom_id)
|
|
483
|
-
|
|
484
|
-
# 3. Append step info to the path
|
|
485
|
-
current_path.nodes.append(
|
|
486
|
-
PathNode(
|
|
487
|
-
flow=current_path.flow,
|
|
488
|
-
step_id=step.id,
|
|
489
|
-
lines=step.metadata["line_numbers"],
|
|
490
|
-
)
|
|
440
|
+
# Check if the step is relevant for testable_paths extraction.
|
|
441
|
+
# We only create new path nodes for ActionFlowStep, CallFlowStep and
|
|
442
|
+
# CollectInformationFlowStep because these are externally visible
|
|
443
|
+
# changes in the assistant's behaviour (trackable in the e2e tests).
|
|
444
|
+
# For other flow steps, we only follow their links.
|
|
445
|
+
# We decided to ignore calls to other flows in our coverage analysis.
|
|
446
|
+
should_add_node = isinstance(
|
|
447
|
+
current_step, (CollectInformationFlowStep, ActionFlowStep, CallFlowStep)
|
|
448
|
+
)
|
|
449
|
+
if should_add_node:
|
|
450
|
+
# Add current step to the current path that is being constructed.
|
|
451
|
+
current_path.nodes.append(
|
|
452
|
+
PathNode(
|
|
453
|
+
flow=current_path.flow,
|
|
454
|
+
step_id=current_step.id,
|
|
455
|
+
lines=current_step.metadata["line_numbers"],
|
|
491
456
|
)
|
|
457
|
+
)
|
|
492
458
|
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
)
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
459
|
+
if current_step.id in visited_step_ids or self.is_end_of_path(current_step):
|
|
460
|
+
# Found a cycle, or reached an end step, do not proceed further.
|
|
461
|
+
all_paths.paths.append(copy.deepcopy(current_path))
|
|
462
|
+
# Remove the last node from the path if it was added.
|
|
463
|
+
if should_add_node:
|
|
464
|
+
current_path.nodes.pop()
|
|
465
|
+
return
|
|
466
|
+
|
|
467
|
+
# Mark current step as visited in this path.
|
|
468
|
+
visited_step_ids.add(current_step.id)
|
|
469
|
+
|
|
470
|
+
# Iterate over all links of the current step.
|
|
471
|
+
for link in current_step.next.links:
|
|
472
|
+
self._handle_link(
|
|
473
|
+
current_path,
|
|
474
|
+
all_paths,
|
|
475
|
+
visited_step_ids,
|
|
476
|
+
link,
|
|
477
|
+
)
|
|
509
478
|
|
|
510
|
-
|
|
479
|
+
# Backtrack the current step and remove it from the path.
|
|
480
|
+
visited_step_ids.remove(current_step.id)
|
|
481
|
+
|
|
482
|
+
# Remove the last node from the path if it was added.
|
|
483
|
+
if should_add_node:
|
|
484
|
+
current_path.nodes.pop()
|
|
485
|
+
|
|
486
|
+
def _handle_link(
|
|
511
487
|
self,
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
488
|
+
current_path: FlowPath,
|
|
489
|
+
all_paths: FlowPathsList,
|
|
490
|
+
visited_step_ids: Set[str],
|
|
491
|
+
link: FlowStepLink,
|
|
516
492
|
) -> None:
|
|
517
|
-
"""
|
|
518
|
-
|
|
519
|
-
Potentially recursively calling itself to handle conditional paths and
|
|
520
|
-
branching.
|
|
493
|
+
"""Handles the next step in a flow.
|
|
521
494
|
|
|
522
495
|
Args:
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
to avoid loops.
|
|
496
|
+
current_path: The current path being constructed.
|
|
497
|
+
all_paths: The list where completed paths are added.
|
|
498
|
+
visited_step_ids: A set of steps that have been visited to avoid cycles.
|
|
499
|
+
link: The link to be followed.
|
|
528
500
|
|
|
529
501
|
Returns:
|
|
530
|
-
None:
|
|
531
|
-
as they are
|
|
502
|
+
None: This function modifies all_paths in place by appending new paths
|
|
503
|
+
as they are found.
|
|
532
504
|
"""
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
if isinstance(link, StaticFlowStepLink):
|
|
538
|
-
# Find this id in the flow steps and restart from there
|
|
539
|
-
for i, step in enumerate(steps):
|
|
540
|
-
if step.id == link.target_step_id:
|
|
541
|
-
self._go_over_steps(
|
|
542
|
-
steps[i:],
|
|
543
|
-
copy.deepcopy(path),
|
|
544
|
-
collected_paths,
|
|
545
|
-
copy.deepcopy(step_ids_visited),
|
|
546
|
-
)
|
|
547
|
-
|
|
548
|
-
# If conditions
|
|
549
|
-
elif isinstance(link, (IfFlowStepLink, ElseFlowStepLink)):
|
|
550
|
-
# Handling conditional paths
|
|
551
|
-
target_steps: Union[str, List[FlowStep]]
|
|
552
|
-
if isinstance(link.target_reference, FlowStepSequence):
|
|
553
|
-
target_steps = link.target_reference.child_steps
|
|
554
|
-
else:
|
|
555
|
-
target_steps = link.target_reference
|
|
556
|
-
|
|
505
|
+
# StaticFlowStepLink is a direct link to the next step.
|
|
506
|
+
if isinstance(link, StaticFlowStepLink):
|
|
507
|
+
# Find the step by its id and continue the path.
|
|
508
|
+
if step := self._get_step_by_step_id(link.target_step_id):
|
|
557
509
|
self._go_over_steps(
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
510
|
+
step,
|
|
511
|
+
current_path,
|
|
512
|
+
all_paths,
|
|
513
|
+
visited_step_ids,
|
|
562
514
|
)
|
|
515
|
+
return
|
|
516
|
+
# IfFlowStepLink and ElseFlowStepLink are conditional links.
|
|
517
|
+
elif isinstance(link, (IfFlowStepLink, ElseFlowStepLink)):
|
|
518
|
+
if isinstance(link.target_reference, FlowStepSequence):
|
|
519
|
+
# If the target is a FlowStepSequence, we need to go over all
|
|
520
|
+
# child steps of the sequence.
|
|
521
|
+
for child_step in link.target_reference.child_steps:
|
|
522
|
+
self._go_over_steps(
|
|
523
|
+
child_step,
|
|
524
|
+
current_path,
|
|
525
|
+
all_paths,
|
|
526
|
+
visited_step_ids,
|
|
527
|
+
)
|
|
528
|
+
return
|
|
529
|
+
else:
|
|
530
|
+
# Find the step by its id and continue the path.
|
|
531
|
+
if step := self._get_step_by_step_id(link.target_reference):
|
|
532
|
+
self._go_over_steps(
|
|
533
|
+
step,
|
|
534
|
+
current_path,
|
|
535
|
+
all_paths,
|
|
536
|
+
visited_step_ids,
|
|
537
|
+
)
|
|
538
|
+
return
|
|
539
|
+
|
|
540
|
+
def is_end_of_path(self, step: FlowStep) -> bool:
|
|
541
|
+
"""Check if there is no path available from the current step."""
|
|
542
|
+
if (
|
|
543
|
+
len(step.next.links) == 1
|
|
544
|
+
and isinstance(step.next.links[0], StaticFlowStepLink)
|
|
545
|
+
and step.next.links[0].target == END_STEP
|
|
546
|
+
):
|
|
547
|
+
return True
|
|
548
|
+
return False
|
|
549
|
+
|
|
550
|
+
def _get_step_by_step_id(
|
|
551
|
+
self,
|
|
552
|
+
step_id: Optional[str],
|
|
553
|
+
) -> Optional[FlowStep]:
|
|
554
|
+
"""Get a step by its id from a list of steps."""
|
|
555
|
+
for step in self.steps:
|
|
556
|
+
if step.id == step_id:
|
|
557
|
+
return step
|
|
558
|
+
return None
|
rasa/version.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: rasa-pro
|
|
3
|
-
Version: 3.11.
|
|
3
|
+
Version: 3.11.10
|
|
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
|
|
@@ -265,7 +265,7 @@ rasa/core/channels/telegram.py,sha256=5BrNECFM3qe9XjNpDb8Q9fbqCT5aKr5L6IH21W8sum
|
|
|
265
265
|
rasa/core/channels/twilio.py,sha256=GsdjfplZdBj0fRB60bSggPF1DXFZ_x18V_dlcDy5VFs,5943
|
|
266
266
|
rasa/core/channels/vier_cvg.py,sha256=PfvSluQqgJbP0JzZPFUvum3z7H55JPPeobcD-z5zCkw,13544
|
|
267
267
|
rasa/core/channels/voice_ready/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
268
|
-
rasa/core/channels/voice_ready/audiocodes.py,sha256=
|
|
268
|
+
rasa/core/channels/voice_ready/audiocodes.py,sha256=jJmLkqI2RciTvB7cAsvRJi_EL70dRyiwNwPWzVPSUj0,21888
|
|
269
269
|
rasa/core/channels/voice_ready/jambonz.py,sha256=S7yjdj7nYwQWMalqcGv8eomZGj0c2Dza-51tiNHEpVM,4784
|
|
270
270
|
rasa/core/channels/voice_ready/jambonz_protocol.py,sha256=OzW-6YMU2SIc88Mur_wktbiE46igHR8vH17DCfRijIU,13139
|
|
271
271
|
rasa/core/channels/voice_ready/twilio_voice.py,sha256=z2pdausxQnXQP9htGh8AL2q9AvcMIx70Y5tErWpssV4,16224
|
|
@@ -594,7 +594,7 @@ rasa/shared/core/conversation.py,sha256=tw1fD2XB3gOdQjDI8hHo5TAAmE2JYNogQGWe3rE9
|
|
|
594
594
|
rasa/shared/core/domain.py,sha256=bGjonMV54wbwGLPjKHI2NoWwxr2wyUZwhEvjBWhP-W0,81710
|
|
595
595
|
rasa/shared/core/events.py,sha256=zdGSP1bNV1RyKC9Z54S7EbQ8TfGne_n9XKj64aoghdI,85803
|
|
596
596
|
rasa/shared/core/flows/__init__.py,sha256=HszhIvEARpmyxABFc1MKYvj8oy04WiZW1xmCdToakbs,181
|
|
597
|
-
rasa/shared/core/flows/flow.py,sha256=
|
|
597
|
+
rasa/shared/core/flows/flow.py,sha256=6RR-CdOR6xS31zCiOe3Fcz-ajCQ-H0M7FxfMa63Ka7A,20820
|
|
598
598
|
rasa/shared/core/flows/flow_path.py,sha256=xstwahZBU5cfMY46mREA4NoOGlKLBRAqeP_mJ3UZqOI,2283
|
|
599
599
|
rasa/shared/core/flows/flow_step.py,sha256=6hoVOMXryTKHgT7-p7jzTqH2r9QREmy_6d6bX2OyxI0,4550
|
|
600
600
|
rasa/shared/core/flows/flow_step_links.py,sha256=zMZV_9rWVjEa8kHIFSIbXCWA1qaUvp8r4uSCK_NsKKs,10548
|
|
@@ -779,9 +779,9 @@ rasa/utils/train_utils.py,sha256=f1NWpp5y6al0dzoQyyio4hc4Nf73DRoRSHDzEK6-C4E,212
|
|
|
779
779
|
rasa/utils/url_tools.py,sha256=JQcHL2aLqLHu82k7_d9imUoETCm2bmlHaDpOJ-dKqBc,1218
|
|
780
780
|
rasa/utils/yaml.py,sha256=KjbZq5C94ZP7Jdsw8bYYF7HASI6K4-C_kdHfrnPLpSI,2000
|
|
781
781
|
rasa/validator.py,sha256=O1wjCeV7ITJ0luvb3GCWy8x1fGgzWVbClEMlPnLBowQ,67265
|
|
782
|
-
rasa/version.py,sha256=
|
|
783
|
-
rasa_pro-3.11.
|
|
784
|
-
rasa_pro-3.11.
|
|
785
|
-
rasa_pro-3.11.
|
|
786
|
-
rasa_pro-3.11.
|
|
787
|
-
rasa_pro-3.11.
|
|
782
|
+
rasa/version.py,sha256=pyAPlQXkP-rQmG_UV6VI6hvQcb20q31MmlJ3pMgkNik,118
|
|
783
|
+
rasa_pro-3.11.10.dist-info/METADATA,sha256=qWOhRdBx8QpPqHsZGkp2NQaj5blpEUsPyd6VX50_32A,10729
|
|
784
|
+
rasa_pro-3.11.10.dist-info/NOTICE,sha256=7HlBoMHJY9CL2GlYSfTQ-PZsVmLmVkYmMiPlTjhuCqA,218
|
|
785
|
+
rasa_pro-3.11.10.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
|
|
786
|
+
rasa_pro-3.11.10.dist-info/entry_points.txt,sha256=ckJ2SfEyTPgBqj_I6vm_tqY9dZF_LAPJZA335Xp0Q9U,43
|
|
787
|
+
rasa_pro-3.11.10.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|