rasa-pro 3.12.21__py3-none-any.whl → 3.13.0__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/__main__.py +3 -4
- rasa/api.py +1 -1
- rasa/cli/dialogue_understanding_test.py +1 -1
- rasa/cli/e2e_test.py +1 -8
- rasa/cli/evaluate.py +2 -2
- rasa/cli/export.py +5 -3
- rasa/cli/inspect.py +7 -0
- rasa/cli/llm_fine_tuning.py +1 -1
- rasa/cli/project_templates/default/config.yml +5 -32
- rasa/cli/project_templates/{calm → default}/e2e_tests/cancelations/user_cancels_during_a_correction.yml +1 -1
- rasa/cli/project_templates/{calm → default}/e2e_tests/cancelations/user_changes_mind_on_a_whim.yml +1 -1
- rasa/cli/project_templates/{calm → default}/e2e_tests/corrections/user_corrects_contact_handle.yml +1 -1
- rasa/cli/project_templates/{calm → default}/e2e_tests/corrections/user_corrects_contact_name.yml +1 -1
- rasa/cli/project_templates/{calm → default}/e2e_tests/happy_paths/user_adds_contact_to_their_list.yml +1 -1
- rasa/cli/project_templates/{calm → default}/e2e_tests/happy_paths/user_lists_contacts.yml +1 -1
- rasa/cli/project_templates/{calm → default}/e2e_tests/happy_paths/user_removes_contact.yml +1 -1
- rasa/cli/project_templates/{calm → default}/e2e_tests/happy_paths/user_removes_contact_from_list.yml +1 -1
- rasa/cli/project_templates/default/endpoints.yml +18 -2
- rasa/cli/project_templates/defaults.py +133 -0
- rasa/cli/project_templates/tutorial/config.yml +1 -1
- rasa/cli/project_templates/tutorial/endpoints.yml +1 -1
- rasa/cli/run.py +1 -1
- rasa/cli/scaffold.py +2 -3
- rasa/cli/shell.py +6 -1
- rasa/cli/studio/download.py +0 -22
- rasa/cli/studio/link.py +36 -0
- rasa/cli/studio/pull.py +79 -0
- rasa/cli/studio/push.py +78 -0
- rasa/cli/studio/studio.py +12 -0
- rasa/cli/studio/train.py +1 -5
- rasa/cli/studio/upload.py +6 -4
- rasa/cli/train.py +5 -1
- rasa/cli/utils.py +1 -1
- rasa/cli/x.py +1 -1
- rasa/constants.py +2 -0
- rasa/core/__init__.py +0 -16
- rasa/core/actions/action.py +43 -29
- rasa/core/actions/action_repeat_bot_messages.py +18 -22
- rasa/core/actions/action_run_slot_rejections.py +1 -2
- rasa/core/agent.py +24 -3
- rasa/core/available_endpoints.py +146 -0
- rasa/core/brokers/kafka.py +4 -0
- rasa/core/brokers/pika.py +5 -2
- rasa/core/brokers/sql.py +1 -1
- rasa/core/channels/__init__.py +3 -0
- rasa/core/channels/botframework.py +2 -2
- rasa/core/channels/channel.py +2 -2
- rasa/core/channels/development_inspector.py +1 -1
- rasa/core/channels/facebook.py +1 -4
- rasa/core/channels/hangouts.py +8 -5
- rasa/core/channels/inspector/.eslintrc.cjs +12 -6
- rasa/core/channels/inspector/.prettierrc +5 -0
- rasa/core/channels/inspector/README.md +11 -5
- rasa/core/channels/inspector/dist/assets/{arc-9f75cc3b.js → arc-371401b1.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{blockDiagram-38ab4fdb-7f34db23.js → blockDiagram-38ab4fdb-3f126156.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{c4Diagram-3d4e48cf-948bab2c.js → c4Diagram-3d4e48cf-12f22eb7.js} +1 -1
- rasa/core/channels/inspector/dist/assets/channel-f1efda17.js +1 -0
- rasa/core/channels/inspector/dist/assets/{classDiagram-70f12bd4-53b0dd0e.js → classDiagram-70f12bd4-03b1d386.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{classDiagram-v2-f2320105-fdf789e7.js → classDiagram-v2-f2320105-84f69d63.js} +1 -1
- rasa/core/channels/inspector/dist/assets/clone-fdf164e2.js +1 -0
- rasa/core/channels/inspector/dist/assets/{createText-2e5e7dd3-87c4ece5.js → createText-2e5e7dd3-ca47fd38.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{edges-e0da2a9e-5a8b0749.js → edges-e0da2a9e-f837ca8a.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{erDiagram-9861fffd-66da90e2.js → erDiagram-9861fffd-8717ac54.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{flowDb-956e92f1-10044f05.js → flowDb-956e92f1-94f38b83.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{flowDiagram-66a62f08-f338f66a.js → flowDiagram-66a62f08-b616f9fb.js} +1 -1
- rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-7d7a1629.js +1 -0
- rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-4a651766-b13140aa.js → flowchart-elk-definition-4a651766-f5d24bb8.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{ganttDiagram-c361ad54-f2b4a55a.js → ganttDiagram-c361ad54-b43ba8d9.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-72cf32ee-dedc298d.js → gitGraphDiagram-72cf32ee-c3aafaa5.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{graph-4ede11ff.js → graph-0d0a2c10.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{index-3862675e-65549d37.js → index-3862675e-58ea0305.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{index-3a23e736.js → index-cce6f8a1.js} +123 -123
- rasa/core/channels/inspector/dist/assets/{infoDiagram-f8f76790-65439671.js → infoDiagram-f8f76790-b8f60461.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{journeyDiagram-49397b02-56d03d98.js → journeyDiagram-49397b02-95be5545.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{layout-dd48f7f4.js → layout-da885b9b.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{line-1569ad2c.js → line-f1c817d3.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{linear-48bf4935.js → linear-d42801e6.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{mindmap-definition-fc14e90a-688504c1.js → mindmap-definition-fc14e90a-a38923a6.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{pieDiagram-8a3498a8-78b6d7e6.js → pieDiagram-8a3498a8-ca6e71e9.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{quadrantDiagram-120e2f19-048b84b3.js → quadrantDiagram-120e2f19-b290dae9.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{requirementDiagram-deff3bca-dd67f107.js → requirementDiagram-deff3bca-03f02ceb.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{sankeyDiagram-04a897e0-8128436e.js → sankeyDiagram-04a897e0-c49eee40.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{sequenceDiagram-704730f1-1a0d1461.js → sequenceDiagram-704730f1-b2cd6a3d.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{stateDiagram-587899a1-46d388ed.js → stateDiagram-587899a1-e53a2028.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-d93cdb3a-ea42951a.js → stateDiagram-v2-d93cdb3a-e1982a03.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-6aaf32cf-7427ed0c.js → styles-6aaf32cf-d0226ca5.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-9a916d00-ff5e5a16.js → styles-9a916d00-0e21dc00.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-c10674c1-7b3680cf.js → styles-c10674c1-9588494e.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{svgDrawCommon-08f97a94-f860f2ad.js → svgDrawCommon-08f97a94-be478d4f.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{timeline-definition-85554ec2-2eebf0c8.js → timeline-definition-85554ec2-74631749.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{xychartDiagram-e933f94c-5d7f4e96.js → xychartDiagram-e933f94c-a043552f.js} +1 -1
- rasa/core/channels/inspector/dist/index.html +1 -1
- rasa/core/channels/inspector/package.json +3 -1
- rasa/core/channels/inspector/src/App.tsx +91 -90
- rasa/core/channels/inspector/src/components/Chat.tsx +45 -41
- rasa/core/channels/inspector/src/components/DiagramFlow.tsx +40 -40
- rasa/core/channels/inspector/src/components/DialogueInformation.tsx +57 -57
- rasa/core/channels/inspector/src/components/DialogueStack.tsx +36 -27
- rasa/core/channels/inspector/src/components/ExpandIcon.tsx +4 -4
- rasa/core/channels/inspector/src/components/FullscreenButton.tsx +7 -7
- rasa/core/channels/inspector/src/components/LoadingSpinner.tsx +28 -12
- rasa/core/channels/inspector/src/components/NoActiveFlow.tsx +9 -9
- rasa/core/channels/inspector/src/components/RasaLogo.tsx +5 -5
- rasa/core/channels/inspector/src/components/RecruitmentPanel.tsx +55 -60
- rasa/core/channels/inspector/src/components/SaraDiagrams.tsx +5 -5
- rasa/core/channels/inspector/src/components/Slots.tsx +22 -22
- rasa/core/channels/inspector/src/components/Welcome.tsx +28 -31
- rasa/core/channels/inspector/src/helpers/audio/audiostream.ts +245 -0
- rasa/core/channels/inspector/src/helpers/audio/microphone-processor.js +12 -0
- rasa/core/channels/inspector/src/helpers/audio/playback-processor.js +36 -0
- rasa/core/channels/inspector/src/helpers/conversation.ts +7 -7
- rasa/core/channels/inspector/src/helpers/formatters.test.ts +181 -181
- rasa/core/channels/inspector/src/helpers/formatters.ts +111 -111
- rasa/core/channels/inspector/src/helpers/utils.ts +78 -61
- rasa/core/channels/inspector/src/main.tsx +8 -8
- rasa/core/channels/inspector/src/theme/Button/Button.ts +8 -8
- rasa/core/channels/inspector/src/theme/Heading/Heading.ts +7 -7
- rasa/core/channels/inspector/src/theme/Input/Input.ts +9 -9
- rasa/core/channels/inspector/src/theme/Link/Link.ts +6 -6
- rasa/core/channels/inspector/src/theme/Modal/Modal.ts +13 -13
- rasa/core/channels/inspector/src/theme/Table/Table.tsx +10 -10
- rasa/core/channels/inspector/src/theme/Tooltip/Tooltip.ts +5 -5
- rasa/core/channels/inspector/src/theme/base/breakpoints.ts +7 -7
- rasa/core/channels/inspector/src/theme/base/colors.ts +64 -64
- rasa/core/channels/inspector/src/theme/base/fonts/fontFaces.css +21 -18
- rasa/core/channels/inspector/src/theme/base/radii.ts +8 -8
- rasa/core/channels/inspector/src/theme/base/shadows.ts +5 -5
- rasa/core/channels/inspector/src/theme/base/sizes.ts +5 -5
- rasa/core/channels/inspector/src/theme/base/space.ts +12 -12
- rasa/core/channels/inspector/src/theme/base/styles.ts +5 -5
- rasa/core/channels/inspector/src/theme/base/typography.ts +12 -12
- rasa/core/channels/inspector/src/theme/base/zIndices.ts +3 -3
- rasa/core/channels/inspector/src/theme/index.ts +38 -38
- rasa/core/channels/inspector/src/types.ts +56 -50
- rasa/core/channels/inspector/yarn.lock +5 -0
- rasa/core/channels/mattermost.py +1 -1
- rasa/core/channels/rasa_chat.py +2 -4
- rasa/core/channels/rest.py +5 -4
- rasa/core/channels/socketio.py +56 -41
- rasa/core/channels/studio_chat.py +329 -68
- rasa/core/channels/vier_cvg.py +1 -2
- rasa/core/channels/voice_ready/audiocodes.py +4 -11
- rasa/core/channels/voice_ready/jambonz.py +5 -6
- rasa/core/channels/voice_ready/twilio_voice.py +13 -12
- rasa/core/channels/voice_ready/utils.py +22 -0
- rasa/core/channels/voice_stream/audiocodes.py +13 -16
- rasa/core/channels/voice_stream/browser_audio.py +1 -1
- rasa/core/channels/voice_stream/genesys.py +37 -18
- rasa/core/channels/voice_stream/jambonz.py +232 -0
- rasa/core/channels/voice_stream/tts/__init__.py +8 -0
- rasa/core/channels/voice_stream/twilio_media_streams.py +15 -12
- rasa/core/channels/voice_stream/voice_channel.py +71 -27
- rasa/core/concurrent_lock_store.py +24 -10
- rasa/core/evaluation/marker_tracker_loader.py +1 -1
- rasa/core/exporter.py +37 -1
- rasa/core/http_interpreter.py +3 -7
- rasa/core/information_retrieval/faiss.py +18 -11
- rasa/core/information_retrieval/ingestion/faq_parser.py +158 -0
- rasa/core/jobs.py +2 -1
- rasa/core/lock_store.py +151 -60
- rasa/core/nlg/contextual_response_rephraser.py +17 -7
- rasa/core/nlg/generator.py +5 -22
- rasa/core/nlg/interpolator.py +2 -3
- rasa/core/nlg/response.py +6 -43
- rasa/core/nlg/summarize.py +1 -1
- rasa/core/nlg/translate.py +0 -8
- rasa/core/policies/enterprise_search_policy.py +305 -189
- rasa/core/policies/enterprise_search_policy_config.py +241 -0
- rasa/core/policies/enterprise_search_prompt_with_relevancy_check_and_citation_template.jinja2 +67 -0
- rasa/core/policies/flow_policy.py +1 -1
- rasa/core/policies/flows/flow_executor.py +102 -17
- rasa/core/policies/intentless_policy.py +56 -17
- rasa/core/processor.py +70 -49
- rasa/core/run.py +33 -11
- rasa/core/tracker_stores/__init__.py +0 -0
- rasa/core/{auth_retry_tracker_store.py → tracker_stores/auth_retry_tracker_store.py} +66 -1
- rasa/core/tracker_stores/dynamo_tracker_store.py +256 -0
- rasa/core/tracker_stores/mongo_tracker_store.py +223 -0
- rasa/core/tracker_stores/redis_tracker_store.py +252 -0
- rasa/core/tracker_stores/sql_tracker_store.py +582 -0
- rasa/core/tracker_stores/tracker_store.py +839 -0
- rasa/core/training/interactive.py +1 -1
- rasa/core/utils.py +24 -95
- rasa/dialogue_understanding/coexistence/intent_based_router.py +2 -1
- rasa/dialogue_understanding/coexistence/llm_based_router.py +13 -11
- rasa/dialogue_understanding/commands/can_not_handle_command.py +2 -0
- rasa/dialogue_understanding/commands/cancel_flow_command.py +3 -1
- rasa/dialogue_understanding/commands/chit_chat_answer_command.py +2 -0
- rasa/dialogue_understanding/commands/clarify_command.py +6 -2
- rasa/dialogue_understanding/commands/command_syntax_manager.py +1 -0
- rasa/dialogue_understanding/commands/correct_slots_command.py +5 -6
- rasa/dialogue_understanding/commands/error_command.py +1 -1
- rasa/dialogue_understanding/commands/human_handoff_command.py +3 -3
- rasa/dialogue_understanding/commands/knowledge_answer_command.py +2 -0
- rasa/dialogue_understanding/commands/repeat_bot_messages_command.py +2 -0
- rasa/dialogue_understanding/commands/set_slot_command.py +8 -4
- rasa/dialogue_understanding/commands/skip_question_command.py +3 -3
- rasa/dialogue_understanding/commands/start_flow_command.py +7 -3
- rasa/dialogue_understanding/generator/__init__.py +7 -1
- rasa/dialogue_understanding/generator/command_generator.py +4 -2
- rasa/dialogue_understanding/generator/command_parser.py +2 -2
- rasa/dialogue_understanding/generator/command_parser_validator.py +63 -0
- rasa/dialogue_understanding/generator/llm_based_command_generator.py +1 -2
- rasa/dialogue_understanding/generator/multi_step/multi_step_llm_command_generator.py +3 -2
- rasa/dialogue_understanding/generator/nlu_command_adapter.py +2 -2
- rasa/dialogue_understanding/generator/prompt_templates/command_prompt_template.jinja2 +0 -2
- rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v2_claude_3_5_sonnet_20240620_template.jinja2 +1 -0
- rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v2_gpt_4o_2024_11_20_template.jinja2 +1 -0
- rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v3_claude_3_5_sonnet_20240620_template.jinja2 +79 -0
- rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v3_gpt_4o_2024_11_20_template.jinja2 +79 -0
- rasa/dialogue_understanding/generator/single_step/compact_llm_command_generator.py +26 -461
- rasa/dialogue_understanding/generator/single_step/search_ready_llm_command_generator.py +147 -0
- rasa/dialogue_understanding/generator/single_step/single_step_based_llm_command_generator.py +461 -0
- rasa/dialogue_understanding/generator/single_step/single_step_llm_command_generator.py +20 -64
- rasa/dialogue_understanding/patterns/cancel.py +1 -2
- rasa/dialogue_understanding/patterns/clarify.py +1 -1
- rasa/dialogue_understanding/patterns/correction.py +2 -2
- rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml +42 -27
- rasa/dialogue_understanding/patterns/domain_for_patterns.py +190 -0
- rasa/dialogue_understanding/processor/command_processor.py +6 -7
- rasa/dialogue_understanding_test/command_metric_calculation.py +7 -40
- rasa/dialogue_understanding_test/command_metrics.py +38 -0
- rasa/dialogue_understanding_test/du_test_case.py +58 -25
- rasa/dialogue_understanding_test/du_test_result.py +228 -132
- rasa/dialogue_understanding_test/du_test_runner.py +11 -2
- rasa/dialogue_understanding_test/du_test_schema.yml +3 -3
- rasa/dialogue_understanding_test/io.py +35 -8
- rasa/e2e_test/constants.py +1 -1
- rasa/e2e_test/e2e_test_runner.py +1 -1
- rasa/e2e_test/e2e_test_schema.yml +3 -3
- rasa/engine/constants.py +1 -1
- rasa/engine/graph.py +2 -2
- rasa/engine/recipes/default_recipe.py +1 -1
- rasa/engine/validation.py +3 -2
- rasa/hooks.py +2 -30
- rasa/llm_fine_tuning/paraphrasing/conversation_rephraser.py +2 -6
- rasa/model_manager/model_api.py +89 -1
- rasa/model_manager/runner_service.py +20 -4
- rasa/model_manager/socket_bridge.py +0 -7
- rasa/model_manager/trainer_service.py +10 -4
- rasa/plugin.py +2 -15
- rasa/privacy/__init__.py +0 -0
- rasa/privacy/constants.py +83 -0
- rasa/privacy/event_broker_utils.py +77 -0
- rasa/privacy/privacy_config.py +281 -0
- rasa/privacy/privacy_config_schema.json +86 -0
- rasa/privacy/privacy_filter.py +393 -0
- rasa/privacy/privacy_manager.py +594 -0
- rasa/server.py +23 -2
- rasa/shared/constants.py +17 -0
- rasa/shared/core/command_payload_reader.py +1 -5
- rasa/shared/core/constants.py +4 -3
- rasa/shared/core/domain.py +172 -11
- rasa/shared/core/events.py +100 -6
- rasa/shared/core/flows/flow.py +30 -5
- rasa/shared/core/flows/flow_step.py +19 -3
- rasa/shared/core/flows/flow_step_links.py +15 -0
- rasa/shared/core/flows/flow_step_sequence.py +6 -0
- rasa/shared/core/flows/flows_yaml_schema.json +3 -0
- rasa/shared/core/flows/nlu_trigger.py +13 -0
- rasa/shared/core/flows/steps/action.py +7 -4
- rasa/shared/core/flows/steps/call.py +11 -4
- rasa/shared/core/flows/steps/collect.py +71 -6
- rasa/shared/core/flows/steps/internal.py +6 -1
- rasa/shared/core/flows/steps/link.py +7 -4
- rasa/shared/core/flows/steps/no_operation.py +7 -4
- rasa/shared/core/flows/steps/set_slots.py +8 -4
- rasa/shared/core/flows/validation.py +25 -5
- rasa/shared/core/flows/yaml_flows_io.py +106 -5
- rasa/shared/core/slots.py +29 -1
- rasa/shared/core/trackers.py +21 -10
- rasa/shared/core/training_data/story_reader/yaml_story_reader.py +1 -4
- rasa/shared/importers/importer.py +8 -0
- rasa/shared/providers/_configs/azure_openai_client_config.py +2 -2
- rasa/shared/providers/_configs/default_litellm_client_config.py +1 -1
- rasa/shared/providers/_configs/huggingface_local_embedding_client_config.py +1 -1
- rasa/shared/providers/_configs/openai_client_config.py +1 -1
- rasa/shared/providers/_configs/rasa_llm_client_config.py +1 -1
- rasa/shared/providers/_configs/self_hosted_llm_client_config.py +1 -1
- rasa/shared/providers/_configs/utils.py +0 -99
- rasa/shared/providers/llm/default_litellm_llm_client.py +2 -2
- rasa/shared/utils/common.py +43 -1
- rasa/shared/utils/configs.py +110 -0
- rasa/shared/utils/constants.py +0 -3
- rasa/shared/utils/llm.py +245 -8
- rasa/shared/utils/pykwalify_extensions.py +0 -9
- rasa/shared/utils/yaml.py +32 -0
- rasa/studio/constants.py +1 -0
- rasa/studio/data_handler.py +33 -12
- rasa/studio/download.py +117 -435
- rasa/studio/link.py +211 -0
- rasa/studio/prompts.py +221 -0
- rasa/studio/pull/__init__.py +0 -0
- rasa/studio/pull/data.py +222 -0
- rasa/studio/pull/domains.py +60 -0
- rasa/studio/pull/pull.py +239 -0
- rasa/studio/push.py +138 -0
- rasa/studio/results_logger.py +6 -1
- rasa/studio/train.py +1 -1
- rasa/studio/upload.py +243 -72
- rasa/studio/utils.py +33 -0
- rasa/telemetry.py +83 -26
- rasa/tracing/config.py +4 -5
- rasa/tracing/constants.py +19 -1
- rasa/tracing/instrumentation/attribute_extractors.py +68 -16
- rasa/tracing/instrumentation/instrumentation.py +54 -3
- rasa/tracing/instrumentation/metrics.py +98 -15
- rasa/tracing/metric_instrument_provider.py +75 -3
- rasa/utils/common.py +43 -22
- rasa/utils/endpoints.py +22 -1
- rasa/utils/licensing.py +2 -3
- rasa/utils/log_utils.py +1 -45
- rasa/validator.py +2 -8
- rasa/version.py +1 -1
- {rasa_pro-3.12.21.dist-info → rasa_pro-3.13.0.dist-info}/METADATA +13 -14
- {rasa_pro-3.12.21.dist-info → rasa_pro-3.13.0.dist-info}/RECORD +333 -309
- rasa/anonymization/__init__.py +0 -2
- rasa/anonymization/anonymisation_rule_yaml_reader.py +0 -91
- rasa/anonymization/anonymization_pipeline.py +0 -286
- rasa/anonymization/anonymization_rule_executor.py +0 -266
- rasa/anonymization/anonymization_rule_orchestrator.py +0 -119
- rasa/anonymization/schemas/config.yml +0 -47
- rasa/anonymization/utils.py +0 -118
- rasa/cli/project_templates/calm/config.yml +0 -10
- rasa/cli/project_templates/calm/credentials.yml +0 -33
- rasa/cli/project_templates/calm/endpoints.yml +0 -58
- rasa/cli/project_templates/default/actions/actions.py +0 -27
- rasa/cli/project_templates/default/data/nlu.yml +0 -91
- rasa/cli/project_templates/default/data/rules.yml +0 -13
- rasa/cli/project_templates/default/data/stories.yml +0 -30
- rasa/cli/project_templates/default/domain.yml +0 -34
- rasa/cli/project_templates/default/tests/test_stories.yml +0 -91
- rasa/core/channels/inspector/dist/assets/channel-dfa68278.js +0 -1
- rasa/core/channels/inspector/dist/assets/clone-edb7f119.js +0 -1
- rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-65e7c670.js +0 -1
- rasa/core/channels/inspector/src/helpers/audiostream.ts +0 -191
- rasa/core/tracker_store.py +0 -1792
- /rasa/cli/project_templates/{calm → default}/actions/action_template.py +0 -0
- /rasa/cli/project_templates/{calm → default}/actions/add_contact.py +0 -0
- /rasa/cli/project_templates/{calm → default}/actions/db.py +0 -0
- /rasa/cli/project_templates/{calm → default}/actions/list_contacts.py +0 -0
- /rasa/cli/project_templates/{calm → default}/actions/remove_contact.py +0 -0
- /rasa/cli/project_templates/{calm → default}/data/flows/add_contact.yml +0 -0
- /rasa/cli/project_templates/{calm → default}/data/flows/list_contacts.yml +0 -0
- /rasa/cli/project_templates/{calm → default}/data/flows/remove_contact.yml +0 -0
- /rasa/cli/project_templates/{calm → default}/db/contacts.json +0 -0
- /rasa/cli/project_templates/{calm → default}/domain/add_contact.yml +0 -0
- /rasa/cli/project_templates/{calm → default}/domain/list_contacts.yml +0 -0
- /rasa/cli/project_templates/{calm → default}/domain/remove_contact.yml +0 -0
- /rasa/cli/project_templates/{calm → default}/domain/shared.yml +0 -0
- /rasa/{cli/project_templates/calm/actions → core/information_retrieval/ingestion}/__init__.py +0 -0
- {rasa_pro-3.12.21.dist-info → rasa_pro-3.13.0.dist-info}/NOTICE +0 -0
- {rasa_pro-3.12.21.dist-info → rasa_pro-3.13.0.dist-info}/WHEEL +0 -0
- {rasa_pro-3.12.21.dist-info → rasa_pro-3.13.0.dist-info}/entry_points.txt +0 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import dataclasses
|
|
1
2
|
import glob
|
|
2
3
|
import importlib.resources
|
|
3
4
|
import json
|
|
@@ -11,10 +12,8 @@ from jinja2 import Template
|
|
|
11
12
|
from pydantic import ValidationError
|
|
12
13
|
|
|
13
14
|
import rasa.shared.utils.io
|
|
15
|
+
from rasa.core.available_endpoints import AvailableEndpoints
|
|
14
16
|
from rasa.core.constants import (
|
|
15
|
-
POLICY_MAX_HISTORY,
|
|
16
|
-
POLICY_PRIORITY,
|
|
17
|
-
SEARCH_POLICY_PRIORITY,
|
|
18
17
|
UTTER_SOURCE_METADATA_KEY,
|
|
19
18
|
)
|
|
20
19
|
from rasa.core.information_retrieval import (
|
|
@@ -24,8 +23,15 @@ from rasa.core.information_retrieval import (
|
|
|
24
23
|
create_from_endpoint_config,
|
|
25
24
|
)
|
|
26
25
|
from rasa.core.information_retrieval.faiss import FAISS_Store
|
|
26
|
+
from rasa.core.policies.enterprise_search_policy_config import (
|
|
27
|
+
DEFAULT_EMBEDDINGS_CONFIG,
|
|
28
|
+
DEFAULT_ENTERPRISE_SEARCH_CONFIG,
|
|
29
|
+
DEFAULT_LLM_CONFIG,
|
|
30
|
+
DEFAULT_VECTOR_STORE_TYPE,
|
|
31
|
+
SOURCE_PROPERTY,
|
|
32
|
+
EnterpriseSearchPolicyConfig,
|
|
33
|
+
)
|
|
27
34
|
from rasa.core.policies.policy import Policy, PolicyPrediction
|
|
28
|
-
from rasa.core.utils import AvailableEndpoints
|
|
29
35
|
from rasa.dialogue_understanding.generator.constants import (
|
|
30
36
|
LLM_CONFIG_KEY,
|
|
31
37
|
)
|
|
@@ -48,16 +54,11 @@ from rasa.graph_components.providers.forms_provider import Forms
|
|
|
48
54
|
from rasa.graph_components.providers.responses_provider import Responses
|
|
49
55
|
from rasa.shared.constants import (
|
|
50
56
|
EMBEDDINGS_CONFIG_KEY,
|
|
51
|
-
MAX_COMPLETION_TOKENS_CONFIG_KEY,
|
|
52
|
-
MAX_RETRIES_CONFIG_KEY,
|
|
53
57
|
MODEL_CONFIG_KEY,
|
|
54
58
|
MODEL_GROUP_ID_CONFIG_KEY,
|
|
55
59
|
MODEL_NAME_CONFIG_KEY,
|
|
56
|
-
OPENAI_PROVIDER,
|
|
57
|
-
PROMPT_CONFIG_KEY,
|
|
58
60
|
PROVIDER_CONFIG_KEY,
|
|
59
|
-
|
|
60
|
-
TIMEOUT_CONFIG_KEY,
|
|
61
|
+
RASA_PATTERN_CANNOT_HANDLE_NO_RELEVANT_ANSWER,
|
|
61
62
|
)
|
|
62
63
|
from rasa.shared.core.constants import (
|
|
63
64
|
ACTION_CANCEL_FLOW,
|
|
@@ -80,7 +81,6 @@ from rasa.shared.nlu.training_data.training_data import TrainingData
|
|
|
80
81
|
from rasa.shared.providers.embedding._langchain_embedding_client_adapter import (
|
|
81
82
|
_LangchainEmbeddingClientAdapter,
|
|
82
83
|
)
|
|
83
|
-
from rasa.shared.providers.llm.llm_client import LLMClient
|
|
84
84
|
from rasa.shared.providers.llm.llm_response import LLMResponse, measure_llm_latency
|
|
85
85
|
from rasa.shared.utils.cli import print_error_and_exit
|
|
86
86
|
from rasa.shared.utils.constants import (
|
|
@@ -93,12 +93,9 @@ from rasa.shared.utils.health_check.embeddings_health_check_mixin import (
|
|
|
93
93
|
from rasa.shared.utils.health_check.llm_health_check_mixin import LLMHealthCheckMixin
|
|
94
94
|
from rasa.shared.utils.io import deep_container_fingerprint
|
|
95
95
|
from rasa.shared.utils.llm import (
|
|
96
|
-
DEFAULT_OPENAI_CHAT_MODEL_NAME,
|
|
97
|
-
DEFAULT_OPENAI_EMBEDDING_MODEL_NAME,
|
|
98
96
|
embedder_factory,
|
|
99
97
|
get_prompt_template,
|
|
100
98
|
llm_factory,
|
|
101
|
-
resolve_model_client_config,
|
|
102
99
|
sanitize_message_for_prompt,
|
|
103
100
|
tracker_as_readable_transcript,
|
|
104
101
|
)
|
|
@@ -115,41 +112,10 @@ if TYPE_CHECKING:
|
|
|
115
112
|
|
|
116
113
|
from rasa.utils.log_utils import log_llm
|
|
117
114
|
|
|
118
|
-
|
|
115
|
+
structlogger = structlog.get_logger()
|
|
119
116
|
|
|
120
117
|
dotenv.load_dotenv("./.env")
|
|
121
118
|
|
|
122
|
-
SOURCE_PROPERTY = "source"
|
|
123
|
-
VECTOR_STORE_TYPE_PROPERTY = "type"
|
|
124
|
-
VECTOR_STORE_PROPERTY = "vector_store"
|
|
125
|
-
VECTOR_STORE_THRESHOLD_PROPERTY = "threshold"
|
|
126
|
-
TRACE_TOKENS_PROPERTY = "trace_prompt_tokens"
|
|
127
|
-
CITATION_ENABLED_PROPERTY = "citation_enabled"
|
|
128
|
-
USE_LLM_PROPERTY = "use_generative_llm"
|
|
129
|
-
MAX_MESSAGES_IN_QUERY_KEY = "max_messages_in_query"
|
|
130
|
-
|
|
131
|
-
DEFAULT_VECTOR_STORE_TYPE = "faiss"
|
|
132
|
-
DEFAULT_VECTOR_STORE_THRESHOLD = 0.0
|
|
133
|
-
DEFAULT_VECTOR_STORE = {
|
|
134
|
-
VECTOR_STORE_TYPE_PROPERTY: DEFAULT_VECTOR_STORE_TYPE,
|
|
135
|
-
SOURCE_PROPERTY: "./docs",
|
|
136
|
-
VECTOR_STORE_THRESHOLD_PROPERTY: DEFAULT_VECTOR_STORE_THRESHOLD,
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
DEFAULT_LLM_CONFIG = {
|
|
140
|
-
PROVIDER_CONFIG_KEY: OPENAI_PROVIDER,
|
|
141
|
-
MODEL_CONFIG_KEY: DEFAULT_OPENAI_CHAT_MODEL_NAME,
|
|
142
|
-
TIMEOUT_CONFIG_KEY: 10,
|
|
143
|
-
TEMPERATURE_CONFIG_KEY: 0.0,
|
|
144
|
-
MAX_COMPLETION_TOKENS_CONFIG_KEY: 256,
|
|
145
|
-
MAX_RETRIES_CONFIG_KEY: 1,
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
DEFAULT_EMBEDDINGS_CONFIG = {
|
|
149
|
-
PROVIDER_CONFIG_KEY: OPENAI_PROVIDER,
|
|
150
|
-
MODEL_CONFIG_KEY: DEFAULT_OPENAI_EMBEDDING_MODEL_NAME,
|
|
151
|
-
}
|
|
152
|
-
|
|
153
119
|
ENTERPRISE_SEARCH_PROMPT_FILE_NAME = "enterprise_search_policy_prompt.jinja2"
|
|
154
120
|
ENTERPRISE_SEARCH_CONFIG_FILE_NAME = "config.json"
|
|
155
121
|
|
|
@@ -164,6 +130,15 @@ DEFAULT_ENTERPRISE_SEARCH_PROMPT_WITH_CITATION_TEMPLATE = importlib.resources.re
|
|
|
164
130
|
"rasa.core.policies", "enterprise_search_prompt_with_citation_template.jinja2"
|
|
165
131
|
)
|
|
166
132
|
|
|
133
|
+
DEFAULT_ENTERPRISE_SEARCH_PROMPT_WITH_RELEVANCY_CHECK_AND_CITATION_TEMPLATE = (
|
|
134
|
+
importlib.resources.read_text(
|
|
135
|
+
"rasa.core.policies",
|
|
136
|
+
"enterprise_search_prompt_with_relevancy_check_and_citation_template.jinja2",
|
|
137
|
+
)
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
_ENTERPRISE_SEARCH_ANSWER_NOT_RELEVANT_PATTERN = re.compile(r"\[NO_RAG_ANSWER\]")
|
|
141
|
+
|
|
167
142
|
_ENTERPRISE_SEARCH_CITATION_PATTERN = re.compile(r"\[([^\]]+)\]")
|
|
168
143
|
|
|
169
144
|
|
|
@@ -175,6 +150,12 @@ class VectorStoreConfigurationError(RasaException):
|
|
|
175
150
|
"""Exception raised for errors in vector store configuration."""
|
|
176
151
|
|
|
177
152
|
|
|
153
|
+
@dataclasses.dataclass
|
|
154
|
+
class _RelevancyCheckResponse:
|
|
155
|
+
answer: Optional[str]
|
|
156
|
+
relevant: bool
|
|
157
|
+
|
|
158
|
+
|
|
178
159
|
@DefaultV1Recipe.register(
|
|
179
160
|
DefaultV1Recipe.ComponentType.POLICY_WITH_END_TO_END_SUPPORT, is_trainable=True
|
|
180
161
|
)
|
|
@@ -206,10 +187,7 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
|
|
|
206
187
|
@staticmethod
|
|
207
188
|
def get_default_config() -> Dict[str, Any]:
|
|
208
189
|
"""Returns the default config of the policy."""
|
|
209
|
-
return
|
|
210
|
-
POLICY_PRIORITY: SEARCH_POLICY_PRIORITY,
|
|
211
|
-
VECTOR_STORE_PROPERTY: DEFAULT_VECTOR_STORE,
|
|
212
|
-
}
|
|
190
|
+
return DEFAULT_ENTERPRISE_SEARCH_CONFIG
|
|
213
191
|
|
|
214
192
|
def __init__(
|
|
215
193
|
self,
|
|
@@ -224,76 +202,71 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
|
|
|
224
202
|
"""Constructs a new Policy object."""
|
|
225
203
|
super().__init__(config, model_storage, resource, execution_context, featurizer)
|
|
226
204
|
|
|
227
|
-
|
|
228
|
-
self.config[LLM_CONFIG_KEY] = resolve_model_client_config(
|
|
229
|
-
self.config.get(LLM_CONFIG_KEY), EnterpriseSearchPolicy.__name__
|
|
230
|
-
)
|
|
231
|
-
# Resolve embeddings config
|
|
232
|
-
self.config[EMBEDDINGS_CONFIG_KEY] = resolve_model_client_config(
|
|
233
|
-
self.config.get(EMBEDDINGS_CONFIG_KEY), EnterpriseSearchPolicy.__name__
|
|
234
|
-
)
|
|
205
|
+
parsed_config = EnterpriseSearchPolicyConfig.from_dict(config)
|
|
235
206
|
|
|
236
207
|
# Vector store object and configuration
|
|
237
208
|
self.vector_store = vector_store
|
|
238
|
-
self.vector_store_config =
|
|
239
|
-
|
|
240
|
-
|
|
209
|
+
self.vector_store_config = parsed_config.vector_store_config
|
|
210
|
+
self.vector_search_threshold = parsed_config.vector_store_threshold
|
|
211
|
+
self.vector_store_type = parsed_config.vector_store_type
|
|
241
212
|
|
|
242
|
-
#
|
|
243
|
-
self.embeddings_config =
|
|
244
|
-
self.config[EMBEDDINGS_CONFIG_KEY] or DEFAULT_EMBEDDINGS_CONFIG
|
|
245
|
-
)
|
|
213
|
+
# Resolved embeddings configuration for encoding the search query
|
|
214
|
+
self.embeddings_config = parsed_config.embeddings_config
|
|
246
215
|
|
|
247
|
-
# LLM Configuration for response generation
|
|
248
|
-
self.llm_config =
|
|
216
|
+
# Resolved LLM Configuration for response generation
|
|
217
|
+
self.llm_config = parsed_config.llm_config
|
|
249
218
|
|
|
250
219
|
# Maximum number of turns to include in the prompt
|
|
251
|
-
self.max_history =
|
|
220
|
+
self.max_history = parsed_config.max_history
|
|
252
221
|
|
|
253
222
|
# Maximum number of messages to include in the search query
|
|
254
|
-
self.max_messages_in_query =
|
|
223
|
+
self.max_messages_in_query = parsed_config.max_messages_in_query
|
|
224
|
+
|
|
225
|
+
# Boolean to enable/disable tracing of prompt tokens
|
|
226
|
+
self.trace_prompt_tokens = parsed_config.trace_prompt_tokens
|
|
255
227
|
|
|
256
|
-
#
|
|
257
|
-
self.
|
|
228
|
+
# Boolean to enable/disable the use of LLM for response generation
|
|
229
|
+
self.use_llm = parsed_config.use_generative_llm
|
|
258
230
|
|
|
259
|
-
#
|
|
260
|
-
|
|
231
|
+
# Boolean to enable/disable citation generation. This flag enables citation
|
|
232
|
+
# logic, but it only takes effect if `use_llm` is True.
|
|
233
|
+
self.citation_enabled = parsed_config.enable_citation
|
|
261
234
|
|
|
262
|
-
#
|
|
263
|
-
|
|
235
|
+
# Boolean to enable/disable the use of relevancy check alongside answer
|
|
236
|
+
# generation. This flag enables citation logic, but it only takes effect if
|
|
237
|
+
# `use_llm` is True.
|
|
238
|
+
self.relevancy_check_enabled = parsed_config.check_relevancy
|
|
264
239
|
|
|
240
|
+
# Resolve the prompt template. The prompt will only be used if the 'use_llm' is
|
|
241
|
+
# set to True.
|
|
265
242
|
self.prompt_template = prompt_template or get_prompt_template(
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
)
|
|
271
|
-
self.citation_prompt_template = get_prompt_template(
|
|
272
|
-
self.config.get(PROMPT_CONFIG_KEY),
|
|
273
|
-
DEFAULT_ENTERPRISE_SEARCH_PROMPT_WITH_CITATION_TEMPLATE,
|
|
243
|
+
jinja_file_path=parsed_config.prompt_template,
|
|
244
|
+
default_prompt_template=self._select_default_prompt_template_based_on_features(
|
|
245
|
+
parsed_config.check_relevancy, parsed_config.enable_citation
|
|
246
|
+
),
|
|
274
247
|
log_source_component=EnterpriseSearchPolicy.__name__,
|
|
275
248
|
log_source_method=LOG_COMPONENT_SOURCE_METHOD_INIT,
|
|
276
249
|
)
|
|
277
|
-
# If citation is enabled, use the citation prompt template
|
|
278
|
-
if self.citation_enabled:
|
|
279
|
-
self.prompt_template = self.citation_prompt_template
|
|
280
250
|
|
|
281
251
|
@classmethod
|
|
282
|
-
def _create_plain_embedder(cls,
|
|
252
|
+
def _create_plain_embedder(cls, embeddings_config: Dict[Text, Any]) -> "Embeddings":
|
|
283
253
|
"""Creates an embedder based on the given configuration.
|
|
284
254
|
|
|
255
|
+
Args:
|
|
256
|
+
embeddings_config: A resolved embeddings configuration. Resolved means the
|
|
257
|
+
configuration is either:
|
|
258
|
+
- A reference to a model group that has already been expanded into
|
|
259
|
+
its corresponding configuration using the information from
|
|
260
|
+
`endpoints.yml`, or
|
|
261
|
+
- A full configuration for the embedder defined directly (i.e. not
|
|
262
|
+
relying on model groups or indirections).
|
|
263
|
+
|
|
285
264
|
Returns:
|
|
286
|
-
|
|
265
|
+
The embedder.
|
|
287
266
|
"""
|
|
288
267
|
# Copy the config so original config is not modified
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
config[EMBEDDINGS_CONFIG_KEY] = resolve_model_client_config(
|
|
292
|
-
config.get(EMBEDDINGS_CONFIG_KEY), EnterpriseSearchPolicy.__name__
|
|
293
|
-
)
|
|
294
|
-
client = embedder_factory(
|
|
295
|
-
config.get(EMBEDDINGS_CONFIG_KEY), DEFAULT_EMBEDDINGS_CONFIG
|
|
296
|
-
)
|
|
268
|
+
embeddings_config = embeddings_config.copy()
|
|
269
|
+
client = embedder_factory(embeddings_config, DEFAULT_EMBEDDINGS_CONFIG)
|
|
297
270
|
# Wrap the embedding client in the adapter
|
|
298
271
|
return _LangchainEmbeddingClientAdapter(client)
|
|
299
272
|
|
|
@@ -359,18 +332,18 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
|
|
|
359
332
|
can load the policy from the resource.
|
|
360
333
|
"""
|
|
361
334
|
# Perform health checks for both LLM and embeddings client configs
|
|
362
|
-
self._perform_health_checks(
|
|
363
|
-
|
|
364
|
-
|
|
335
|
+
self._perform_health_checks(
|
|
336
|
+
self.llm_config, self.embeddings_config, "enterprise_search_policy.train"
|
|
337
|
+
)
|
|
365
338
|
|
|
366
339
|
# telemetry call to track training start
|
|
367
340
|
track_enterprise_search_policy_train_started()
|
|
368
341
|
|
|
369
342
|
# validate embedding configuration
|
|
370
343
|
try:
|
|
371
|
-
embeddings = self._create_plain_embedder(self.
|
|
344
|
+
embeddings = self._create_plain_embedder(self.embeddings_config)
|
|
372
345
|
except (ValidationError, Exception) as e:
|
|
373
|
-
|
|
346
|
+
structlogger.error(
|
|
374
347
|
"enterprise_search_policy.train.embedder_instantiation_failed",
|
|
375
348
|
message="Unable to instantiate the embedding client.",
|
|
376
349
|
error=e,
|
|
@@ -380,8 +353,8 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
|
|
|
380
353
|
f"required environment variables. Error: {e}"
|
|
381
354
|
)
|
|
382
355
|
|
|
383
|
-
if
|
|
384
|
-
|
|
356
|
+
if self.vector_store_type == DEFAULT_VECTOR_STORE_TYPE:
|
|
357
|
+
structlogger.info("enterprise_search_policy.train.faiss")
|
|
385
358
|
docs_folder = self.vector_store_config.get(SOURCE_PROPERTY)
|
|
386
359
|
self._validate_documents_folder(docs_folder)
|
|
387
360
|
with self._model_storage.write_to(self._resource) as path:
|
|
@@ -390,13 +363,17 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
|
|
|
390
363
|
embeddings=embeddings,
|
|
391
364
|
index_path=path,
|
|
392
365
|
create_index=True,
|
|
366
|
+
parse_as_faq_pairs=not self.use_llm,
|
|
393
367
|
)
|
|
394
368
|
else:
|
|
395
|
-
|
|
369
|
+
structlogger.info(
|
|
370
|
+
"enterprise_search_policy.train.custom",
|
|
371
|
+
store_type=self.vector_store_type,
|
|
372
|
+
)
|
|
396
373
|
|
|
397
374
|
# telemetry call to track training completion
|
|
398
375
|
track_enterprise_search_policy_train_completed(
|
|
399
|
-
vector_store_type=
|
|
376
|
+
vector_store_type=self.vector_store_type,
|
|
400
377
|
embeddings_type=self.embeddings_config.get(PROVIDER_CONFIG_KEY),
|
|
401
378
|
embeddings_model=self.embeddings_config.get(MODEL_CONFIG_KEY)
|
|
402
379
|
or self.embeddings_config.get(MODEL_NAME_CONFIG_KEY),
|
|
@@ -408,6 +385,7 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
|
|
|
408
385
|
or self.llm_config.get(MODEL_NAME_CONFIG_KEY),
|
|
409
386
|
llm_model_group_id=self.llm_config.get(MODEL_GROUP_ID_CONFIG_KEY),
|
|
410
387
|
citation_enabled=self.citation_enabled,
|
|
388
|
+
relevancy_check_enabled=self.relevancy_check_enabled,
|
|
411
389
|
)
|
|
412
390
|
self.persist()
|
|
413
391
|
return self._resource
|
|
@@ -418,8 +396,11 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
|
|
|
418
396
|
rasa.shared.utils.io.write_text_file(
|
|
419
397
|
self.prompt_template, path / ENTERPRISE_SEARCH_PROMPT_FILE_NAME
|
|
420
398
|
)
|
|
399
|
+
config = self.config.copy()
|
|
400
|
+
config[LLM_CONFIG_KEY] = self.llm_config
|
|
401
|
+
config[EMBEDDINGS_CONFIG_KEY] = self.embeddings_config
|
|
421
402
|
rasa.shared.utils.io.dump_obj_as_json_to_file(
|
|
422
|
-
path / ENTERPRISE_SEARCH_CONFIG_FILE_NAME,
|
|
403
|
+
path / ENTERPRISE_SEARCH_CONFIG_FILE_NAME, config
|
|
423
404
|
)
|
|
424
405
|
|
|
425
406
|
def _prepare_slots_for_template(
|
|
@@ -458,9 +439,8 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
|
|
|
458
439
|
endpoints: Endpoints configuration.
|
|
459
440
|
"""
|
|
460
441
|
config = endpoints.vector_store if endpoints else None
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
logger.error(
|
|
442
|
+
if config is None and self.vector_store_type != DEFAULT_VECTOR_STORE_TYPE:
|
|
443
|
+
structlogger.error(
|
|
464
444
|
"enterprise_search_policy._connect_vector_store_or_raise.no_config"
|
|
465
445
|
)
|
|
466
446
|
raise VectorStoreConfigurationError(
|
|
@@ -470,7 +450,7 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
|
|
|
470
450
|
try:
|
|
471
451
|
self.vector_store.connect(config) # type: ignore
|
|
472
452
|
except Exception as e:
|
|
473
|
-
|
|
453
|
+
structlogger.error(
|
|
474
454
|
"enterprise_search_policy._connect_vector_store_or_raise.connect_error",
|
|
475
455
|
error=e,
|
|
476
456
|
config=config,
|
|
@@ -496,14 +476,14 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
|
|
|
496
476
|
transcript.append(sanitize_message_for_prompt(event.text))
|
|
497
477
|
|
|
498
478
|
search_query = " ".join(transcript[-history:][::-1])
|
|
499
|
-
|
|
479
|
+
structlogger.debug("search_query", search_query=search_query)
|
|
500
480
|
return search_query
|
|
501
481
|
|
|
502
482
|
async def predict_action_probabilities( # type: ignore[override]
|
|
503
483
|
self,
|
|
504
484
|
tracker: DialogueStateTracker,
|
|
505
485
|
domain: Domain,
|
|
506
|
-
endpoints: Optional[AvailableEndpoints],
|
|
486
|
+
endpoints: Optional[AvailableEndpoints] = None,
|
|
507
487
|
rule_only_data: Optional[Dict[Text, Any]] = None,
|
|
508
488
|
**kwargs: Any,
|
|
509
489
|
) -> PolicyPrediction:
|
|
@@ -522,23 +502,20 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
|
|
|
522
502
|
The prediction.
|
|
523
503
|
"""
|
|
524
504
|
logger_key = "enterprise_search_policy.predict_action_probabilities"
|
|
525
|
-
|
|
526
|
-
VECTOR_STORE_THRESHOLD_PROPERTY, DEFAULT_VECTOR_STORE_THRESHOLD
|
|
527
|
-
)
|
|
528
|
-
llm = llm_factory(self.config.get(LLM_CONFIG_KEY), DEFAULT_LLM_CONFIG)
|
|
505
|
+
|
|
529
506
|
if not self.supports_current_stack_frame(
|
|
530
507
|
tracker, False, False
|
|
531
508
|
) or self.should_abstain_in_coexistence(tracker, True):
|
|
532
509
|
return self._prediction(self._default_predictions(domain))
|
|
533
510
|
|
|
534
511
|
if not self.vector_store:
|
|
535
|
-
|
|
512
|
+
structlogger.error(f"{logger_key}.no_vector_store")
|
|
536
513
|
return self._create_prediction_internal_error(domain, tracker)
|
|
537
514
|
|
|
538
515
|
try:
|
|
539
516
|
self._connect_vector_store_or_raise(endpoints)
|
|
540
517
|
except (VectorStoreConfigurationError, VectorStoreConnectionError) as e:
|
|
541
|
-
|
|
518
|
+
structlogger.error(f"{logger_key}.connection_error", error=e)
|
|
542
519
|
return self._create_prediction_internal_error(domain, tracker)
|
|
543
520
|
|
|
544
521
|
search_query = self._prepare_search_query(
|
|
@@ -550,20 +527,19 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
|
|
|
550
527
|
documents = await self.vector_store.search(
|
|
551
528
|
query=search_query,
|
|
552
529
|
tracker_state=tracker_state,
|
|
553
|
-
threshold=vector_search_threshold,
|
|
530
|
+
threshold=self.vector_search_threshold,
|
|
554
531
|
)
|
|
555
532
|
except InformationRetrievalException as e:
|
|
556
|
-
|
|
533
|
+
structlogger.error(f"{logger_key}.search_error", error=e)
|
|
557
534
|
return self._create_prediction_internal_error(domain, tracker)
|
|
558
535
|
|
|
559
536
|
if not documents.results:
|
|
560
|
-
|
|
537
|
+
structlogger.info(f"{logger_key}.no_documents")
|
|
561
538
|
return self._create_prediction_cannot_handle(domain, tracker)
|
|
562
539
|
|
|
563
540
|
if self.use_llm:
|
|
564
541
|
prompt = self._render_prompt(tracker, documents.results)
|
|
565
|
-
llm_response = await self.
|
|
566
|
-
llm_response = LLMResponse.ensure_llm_response(llm_response)
|
|
542
|
+
llm_response = await self._invoke_llm(prompt)
|
|
567
543
|
|
|
568
544
|
self._add_prompt_and_llm_response_to_latest_message(
|
|
569
545
|
tracker=tracker,
|
|
@@ -573,24 +549,38 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
|
|
|
573
549
|
)
|
|
574
550
|
|
|
575
551
|
if llm_response is None or not llm_response.choices:
|
|
576
|
-
|
|
552
|
+
structlogger.debug(f"{logger_key}.no_llm_response")
|
|
577
553
|
response = None
|
|
578
554
|
else:
|
|
579
555
|
llm_answer = llm_response.choices[0]
|
|
580
556
|
|
|
557
|
+
if self.relevancy_check_enabled:
|
|
558
|
+
relevancy_response = self._parse_llm_relevancy_check_response(
|
|
559
|
+
llm_answer
|
|
560
|
+
)
|
|
561
|
+
if not relevancy_response.relevant:
|
|
562
|
+
structlogger.debug(f"{logger_key}.answer_not_relevant")
|
|
563
|
+
return self._create_prediction_cannot_handle(
|
|
564
|
+
domain,
|
|
565
|
+
tracker,
|
|
566
|
+
RASA_PATTERN_CANNOT_HANDLE_NO_RELEVANT_ANSWER,
|
|
567
|
+
)
|
|
568
|
+
|
|
581
569
|
if self.citation_enabled:
|
|
582
570
|
llm_answer = self.post_process_citations(llm_answer)
|
|
583
571
|
|
|
584
|
-
|
|
572
|
+
structlogger.debug(
|
|
573
|
+
f"{logger_key}.llm_answer", prompt=prompt, llm_answer=llm_answer
|
|
574
|
+
)
|
|
585
575
|
response = llm_answer
|
|
586
576
|
else:
|
|
587
577
|
response = documents.results[0].metadata.get("answer", None)
|
|
588
578
|
if not response:
|
|
589
|
-
|
|
579
|
+
structlogger.error(
|
|
590
580
|
f"{logger_key}.answer_key_missing_in_metadata",
|
|
591
581
|
search_results=documents.results,
|
|
592
582
|
)
|
|
593
|
-
|
|
583
|
+
structlogger.debug(
|
|
594
584
|
"enterprise_search_policy.predict_action_probabilities.no_llm",
|
|
595
585
|
search_results=documents,
|
|
596
586
|
)
|
|
@@ -610,7 +600,7 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
|
|
|
610
600
|
|
|
611
601
|
# telemetry call to track policy prediction
|
|
612
602
|
track_enterprise_search_policy_predict(
|
|
613
|
-
vector_store_type=self.
|
|
603
|
+
vector_store_type=self.vector_store_type,
|
|
614
604
|
embeddings_type=self.embeddings_config.get(PROVIDER_CONFIG_KEY),
|
|
615
605
|
embeddings_model=self.embeddings_config.get(MODEL_CONFIG_KEY)
|
|
616
606
|
or self.embeddings_config.get(MODEL_NAME_CONFIG_KEY),
|
|
@@ -622,6 +612,7 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
|
|
|
622
612
|
or self.llm_config.get(MODEL_NAME_CONFIG_KEY),
|
|
623
613
|
llm_model_group_id=self.llm_config.get(MODEL_GROUP_ID_CONFIG_KEY),
|
|
624
614
|
citation_enabled=self.citation_enabled,
|
|
615
|
+
relevancy_check_enabled=self.relevancy_check_enabled,
|
|
625
616
|
)
|
|
626
617
|
return self._create_prediction(
|
|
627
618
|
domain=domain, tracker=tracker, action_metadata=action_metadata
|
|
@@ -645,11 +636,12 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
|
|
|
645
636
|
),
|
|
646
637
|
"docs": documents,
|
|
647
638
|
"slots": self._prepare_slots_for_template(tracker),
|
|
639
|
+
"check_relevancy": self.relevancy_check_enabled,
|
|
648
640
|
"citation_enabled": self.citation_enabled,
|
|
649
641
|
}
|
|
650
642
|
prompt = Template(self.prompt_template).render(**inputs)
|
|
651
643
|
log_llm(
|
|
652
|
-
logger=
|
|
644
|
+
logger=structlogger,
|
|
653
645
|
log_module="EnterpriseSearchPolicy",
|
|
654
646
|
log_event="enterprise_search_policy._render_prompt.prompt_rendered",
|
|
655
647
|
prompt=prompt,
|
|
@@ -657,9 +649,7 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
|
|
|
657
649
|
return prompt
|
|
658
650
|
|
|
659
651
|
@measure_llm_latency
|
|
660
|
-
async def
|
|
661
|
-
self, llm: LLMClient, prompt: Text
|
|
662
|
-
) -> Optional[LLMResponse]:
|
|
652
|
+
async def _invoke_llm(self, prompt: Text) -> Optional[LLMResponse]:
|
|
663
653
|
"""Fetches an LLM completion for the provided prompt.
|
|
664
654
|
|
|
665
655
|
Args:
|
|
@@ -669,17 +659,32 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
|
|
|
669
659
|
Returns:
|
|
670
660
|
An LLMResponse object, or None if the call fails.
|
|
671
661
|
"""
|
|
662
|
+
llm = llm_factory(self.llm_config, DEFAULT_LLM_CONFIG)
|
|
672
663
|
try:
|
|
673
|
-
|
|
664
|
+
response = await llm.acompletion(prompt)
|
|
665
|
+
return LLMResponse.ensure_llm_response(response)
|
|
674
666
|
except Exception as e:
|
|
675
667
|
# unfortunately, langchain does not wrap LLM exceptions which means
|
|
676
668
|
# we have to catch all exceptions here
|
|
677
|
-
|
|
669
|
+
structlogger.error(
|
|
678
670
|
"enterprise_search_policy._generate_llm_answer.llm_error",
|
|
679
671
|
error=e,
|
|
680
672
|
)
|
|
681
673
|
return None
|
|
682
674
|
|
|
675
|
+
def _parse_llm_relevancy_check_response(
|
|
676
|
+
self, llm_answer: str
|
|
677
|
+
) -> _RelevancyCheckResponse:
|
|
678
|
+
"""Checks if the LLM response is relevant by parsing it."""
|
|
679
|
+
answer_relevant = not _ENTERPRISE_SEARCH_ANSWER_NOT_RELEVANT_PATTERN.search(
|
|
680
|
+
llm_answer
|
|
681
|
+
)
|
|
682
|
+
structlogger.debug("")
|
|
683
|
+
return _RelevancyCheckResponse(
|
|
684
|
+
answer=llm_answer if answer_relevant else None,
|
|
685
|
+
relevant=answer_relevant,
|
|
686
|
+
)
|
|
687
|
+
|
|
683
688
|
def _create_prediction(
|
|
684
689
|
self,
|
|
685
690
|
domain: Domain,
|
|
@@ -714,10 +719,18 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
|
|
|
714
719
|
)
|
|
715
720
|
|
|
716
721
|
def _create_prediction_cannot_handle(
|
|
717
|
-
self,
|
|
722
|
+
self,
|
|
723
|
+
domain: Domain,
|
|
724
|
+
tracker: DialogueStateTracker,
|
|
725
|
+
reason: Optional[str] = None,
|
|
718
726
|
) -> PolicyPrediction:
|
|
727
|
+
cannot_handle_stack_frame = (
|
|
728
|
+
CannotHandlePatternFlowStackFrame(reason=reason)
|
|
729
|
+
if reason is not None
|
|
730
|
+
else CannotHandlePatternFlowStackFrame()
|
|
731
|
+
)
|
|
719
732
|
return self._create_prediction_for_pattern(
|
|
720
|
-
domain, tracker,
|
|
733
|
+
domain, tracker, cannot_handle_stack_frame
|
|
721
734
|
)
|
|
722
735
|
|
|
723
736
|
def _create_prediction_for_pattern(
|
|
@@ -775,7 +788,7 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
|
|
|
775
788
|
"Please specify a valid path to the documents source directory in the "
|
|
776
789
|
"vector_store configuration."
|
|
777
790
|
)
|
|
778
|
-
|
|
791
|
+
structlogger.error(
|
|
779
792
|
"enterprise_search_policy.train.faiss.invalid_source_directory",
|
|
780
793
|
message=error_message,
|
|
781
794
|
)
|
|
@@ -787,7 +800,7 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
|
|
|
787
800
|
f"Document source directory is empty: '{docs_folder}'. "
|
|
788
801
|
"Please add documents to this directory or specify a different one."
|
|
789
802
|
)
|
|
790
|
-
|
|
803
|
+
structlogger.error(
|
|
791
804
|
"enterprise_search_policy.train.faiss.source_directory_empty",
|
|
792
805
|
message=error_message,
|
|
793
806
|
)
|
|
@@ -803,70 +816,93 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
|
|
|
803
816
|
**kwargs: Any,
|
|
804
817
|
) -> "EnterpriseSearchPolicy":
|
|
805
818
|
"""Loads a trained policy (see parent class for full docstring)."""
|
|
819
|
+
parsed_config = EnterpriseSearchPolicyConfig.from_dict(config)
|
|
820
|
+
|
|
806
821
|
# Perform health checks for both LLM and embeddings client configs
|
|
807
|
-
cls._perform_health_checks(
|
|
822
|
+
cls._perform_health_checks(
|
|
823
|
+
parsed_config.llm_config,
|
|
824
|
+
parsed_config.embeddings_config,
|
|
825
|
+
"enterprise_search_policy.load",
|
|
826
|
+
)
|
|
808
827
|
|
|
809
|
-
prompt_template =
|
|
828
|
+
prompt_template = cls._load_prompt_template(model_storage, resource)
|
|
829
|
+
embeddings = cls._create_plain_embedder(parsed_config.embeddings_config)
|
|
830
|
+
vector_store = cls._load_vector_store(
|
|
831
|
+
embeddings,
|
|
832
|
+
parsed_config.vector_store_type,
|
|
833
|
+
parsed_config.use_generative_llm,
|
|
834
|
+
model_storage,
|
|
835
|
+
resource,
|
|
836
|
+
)
|
|
837
|
+
|
|
838
|
+
structlogger.info("enterprise_search_policy.load", config=config)
|
|
839
|
+
|
|
840
|
+
return cls(
|
|
841
|
+
config,
|
|
842
|
+
model_storage,
|
|
843
|
+
resource,
|
|
844
|
+
execution_context,
|
|
845
|
+
vector_store=vector_store,
|
|
846
|
+
prompt_template=prompt_template,
|
|
847
|
+
)
|
|
848
|
+
|
|
849
|
+
@classmethod
|
|
850
|
+
def _load_prompt_template(
|
|
851
|
+
cls, model_storage: ModelStorage, resource: Resource
|
|
852
|
+
) -> Optional[str]:
|
|
810
853
|
try:
|
|
811
854
|
with model_storage.read_from(resource) as path:
|
|
812
|
-
|
|
855
|
+
return rasa.shared.utils.io.read_file(
|
|
813
856
|
path / ENTERPRISE_SEARCH_PROMPT_FILE_NAME
|
|
814
857
|
)
|
|
815
858
|
except (FileNotFoundError, FileIOException) as e:
|
|
816
|
-
|
|
859
|
+
structlogger.warning(
|
|
817
860
|
"enterprise_search_policy.load.failed", error=e, resource=resource.name
|
|
818
861
|
)
|
|
862
|
+
return None
|
|
819
863
|
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
864
|
+
@classmethod
|
|
865
|
+
def _load_vector_store(
|
|
866
|
+
cls,
|
|
867
|
+
embeddings: "Embeddings",
|
|
868
|
+
store_type: str,
|
|
869
|
+
use_generative_llm: bool,
|
|
870
|
+
model_storage: ModelStorage,
|
|
871
|
+
resource: Resource,
|
|
872
|
+
) -> InformationRetrieval:
|
|
827
873
|
if store_type == DEFAULT_VECTOR_STORE_TYPE:
|
|
828
874
|
# if a vector store is not specified,
|
|
829
875
|
# default to using FAISS with the index stored in the model
|
|
830
876
|
# TODO figure out a way to get path without context manager
|
|
831
877
|
with model_storage.read_from(resource) as path:
|
|
832
|
-
|
|
878
|
+
return FAISS_Store(
|
|
833
879
|
embeddings=embeddings,
|
|
834
880
|
index_path=path,
|
|
835
881
|
docs_folder=None,
|
|
836
882
|
create_index=False,
|
|
883
|
+
parse_as_faq_pairs=not use_generative_llm,
|
|
837
884
|
)
|
|
838
885
|
else:
|
|
839
|
-
|
|
886
|
+
return create_from_endpoint_config(
|
|
840
887
|
config_type=store_type,
|
|
841
888
|
embeddings=embeddings,
|
|
842
|
-
)
|
|
843
|
-
|
|
844
|
-
return cls(
|
|
845
|
-
config,
|
|
846
|
-
model_storage,
|
|
847
|
-
resource,
|
|
848
|
-
execution_context,
|
|
849
|
-
vector_store=vector_store,
|
|
850
|
-
prompt_template=prompt_template,
|
|
851
|
-
)
|
|
889
|
+
)
|
|
852
890
|
|
|
853
891
|
@classmethod
|
|
854
|
-
def _get_local_knowledge_data(
|
|
892
|
+
def _get_local_knowledge_data(
|
|
893
|
+
cls, store_type: str, source: Optional[str] = None
|
|
894
|
+
) -> Optional[List[str]]:
|
|
855
895
|
"""This is required only for local knowledge base types.
|
|
856
896
|
|
|
857
897
|
e.g. FAISS, to ensure that the graph component is retrained when the knowledge
|
|
858
898
|
base is updated.
|
|
859
899
|
"""
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
return None
|
|
867
|
-
|
|
868
|
-
source = merged_config.get(VECTOR_STORE_PROPERTY, {}).get(SOURCE_PROPERTY)
|
|
869
|
-
if not source or not os.path.exists(source) or not os.path.isdir(source):
|
|
900
|
+
if (
|
|
901
|
+
store_type != DEFAULT_VECTOR_STORE_TYPE
|
|
902
|
+
or not source
|
|
903
|
+
or not os.path.exists(source)
|
|
904
|
+
or not os.path.isdir(source)
|
|
905
|
+
):
|
|
870
906
|
return None
|
|
871
907
|
|
|
872
908
|
docs = FAISS_Store.load_documents(source)
|
|
@@ -882,21 +918,28 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
|
|
|
882
918
|
@classmethod
|
|
883
919
|
def fingerprint_addon(cls, config: Dict[str, Any]) -> Optional[str]:
|
|
884
920
|
"""Add a fingerprint of enterprise search policy for the graph."""
|
|
885
|
-
|
|
921
|
+
parsed_config = EnterpriseSearchPolicyConfig.from_dict(config)
|
|
886
922
|
|
|
923
|
+
# Resolve the prompt template
|
|
924
|
+
default_prompt_template = cls._select_default_prompt_template_based_on_features(
|
|
925
|
+
parsed_config.check_relevancy, parsed_config.enable_citation
|
|
926
|
+
)
|
|
887
927
|
prompt_template = get_prompt_template(
|
|
888
|
-
|
|
889
|
-
|
|
928
|
+
jinja_file_path=parsed_config.prompt_template,
|
|
929
|
+
default_prompt_template=default_prompt_template,
|
|
890
930
|
log_source_component=EnterpriseSearchPolicy.__name__,
|
|
891
931
|
log_source_method=LOG_COMPONENT_SOURCE_METHOD_FINGERPRINT_ADDON,
|
|
892
932
|
)
|
|
893
933
|
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
embedding_config = resolve_model_client_config(
|
|
898
|
-
config.get(EMBEDDINGS_CONFIG_KEY), EnterpriseSearchPolicy.__name__
|
|
934
|
+
# Fetch the local knowledge data in case FAISS is used
|
|
935
|
+
local_knowledge_data = cls._get_local_knowledge_data(
|
|
936
|
+
parsed_config.vector_store_type, parsed_config.vector_store_source
|
|
899
937
|
)
|
|
938
|
+
|
|
939
|
+
# Get the resolved LLM and embeddings configurations
|
|
940
|
+
llm_config = parsed_config.llm_config
|
|
941
|
+
embedding_config = parsed_config.embeddings_config
|
|
942
|
+
|
|
900
943
|
return deep_container_fingerprint(
|
|
901
944
|
[prompt_template, local_knowledge_data, llm_config, embedding_config]
|
|
902
945
|
)
|
|
@@ -922,7 +965,7 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
|
|
|
922
965
|
Returns:
|
|
923
966
|
The post-processed LLM answer.
|
|
924
967
|
"""
|
|
925
|
-
|
|
968
|
+
structlogger.debug(
|
|
926
969
|
"enterprise_search_policy.post_process_citations", llm_answer=llm_answer
|
|
927
970
|
)
|
|
928
971
|
|
|
@@ -1085,24 +1128,97 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
|
|
|
1085
1128
|
|
|
1086
1129
|
@classmethod
|
|
1087
1130
|
def _perform_health_checks(
|
|
1088
|
-
cls,
|
|
1131
|
+
cls,
|
|
1132
|
+
llm_config: Dict[Text, Any],
|
|
1133
|
+
embeddings_config: Dict[Text, Any],
|
|
1134
|
+
log_source_method: str,
|
|
1089
1135
|
) -> None:
|
|
1090
|
-
|
|
1091
|
-
|
|
1136
|
+
"""
|
|
1137
|
+
Perform the health checks using resolved LLM and embeddings configurations.
|
|
1138
|
+
Resolved means the configuration is either:
|
|
1139
|
+
- A reference to a model group that has already been expanded into
|
|
1140
|
+
its corresponding configuration using the information from
|
|
1141
|
+
`endpoints.yml`, or
|
|
1142
|
+
- A full configuration for the embedder defined directly (i.e. not
|
|
1143
|
+
relying on model groups or indirections).
|
|
1144
|
+
|
|
1145
|
+
Args:
|
|
1146
|
+
llm_config: A resolved LLM configuration.
|
|
1147
|
+
embeddings_config: A resolved embeddings configuration.
|
|
1148
|
+
log_source_method: The method health checks has been called from.
|
|
1149
|
+
|
|
1150
|
+
"""
|
|
1092
1151
|
cls.perform_llm_health_check(
|
|
1093
1152
|
llm_config,
|
|
1094
1153
|
DEFAULT_LLM_CONFIG,
|
|
1095
1154
|
log_source_method,
|
|
1096
1155
|
EnterpriseSearchPolicy.__name__,
|
|
1097
1156
|
)
|
|
1098
|
-
|
|
1099
|
-
# Perform health check of the embeddings client config
|
|
1100
|
-
embeddings_config = resolve_model_client_config(
|
|
1101
|
-
config.get(EMBEDDINGS_CONFIG_KEY, {})
|
|
1102
|
-
)
|
|
1103
1157
|
cls.perform_embeddings_health_check(
|
|
1104
1158
|
embeddings_config,
|
|
1105
1159
|
DEFAULT_EMBEDDINGS_CONFIG,
|
|
1106
1160
|
log_source_method,
|
|
1107
1161
|
EnterpriseSearchPolicy.__name__,
|
|
1108
1162
|
)
|
|
1163
|
+
|
|
1164
|
+
@classmethod
|
|
1165
|
+
def get_system_default_prompt_based_on_config(cls, config: Dict[str, Any]) -> str:
|
|
1166
|
+
"""
|
|
1167
|
+
Resolves the default prompt template for Enterprise Search Policy based on
|
|
1168
|
+
the component's configuration.
|
|
1169
|
+
|
|
1170
|
+
- The old prompt is selected when both citation and relevancy check are either
|
|
1171
|
+
disabled or not set in the configuration.
|
|
1172
|
+
- The citation prompt is used when citation is enabled and relevancy check is
|
|
1173
|
+
either disabled or not set in the configuration.
|
|
1174
|
+
- The relevancy check prompt is only used when relevancy check is enabled.
|
|
1175
|
+
|
|
1176
|
+
Args:
|
|
1177
|
+
config: The component's configuration.
|
|
1178
|
+
|
|
1179
|
+
Returns:
|
|
1180
|
+
The resolved jinja prompt template as a string.
|
|
1181
|
+
"""
|
|
1182
|
+
# Get the feature flags
|
|
1183
|
+
parsed_config = EnterpriseSearchPolicyConfig.from_dict(config)
|
|
1184
|
+
# Based on the enabled features (citation, relevancy check) fetch the
|
|
1185
|
+
# appropriate default prompt
|
|
1186
|
+
default_prompt = cls._select_default_prompt_template_based_on_features(
|
|
1187
|
+
parsed_config.check_relevancy, parsed_config.enable_citation
|
|
1188
|
+
)
|
|
1189
|
+
|
|
1190
|
+
return default_prompt
|
|
1191
|
+
|
|
1192
|
+
@classmethod
|
|
1193
|
+
def _select_default_prompt_template_based_on_features(
|
|
1194
|
+
cls,
|
|
1195
|
+
relevancy_check_enabled: bool,
|
|
1196
|
+
citation_enabled: bool,
|
|
1197
|
+
) -> str:
|
|
1198
|
+
"""
|
|
1199
|
+
Returns the appropriate default prompt template based on the feature flags.
|
|
1200
|
+
|
|
1201
|
+
The selection follows this priority:
|
|
1202
|
+
1. If relevancy check is enabled, return the prompt that includes both relevancy
|
|
1203
|
+
and citation blocks.
|
|
1204
|
+
2. If only citation is enabled, return the prompt with citation blocks.
|
|
1205
|
+
3. Otherwise, fall back to the legacy default prompt template.
|
|
1206
|
+
|
|
1207
|
+
Args:
|
|
1208
|
+
relevancy_check_enabled: Whether the LLM-generated answer should undergo
|
|
1209
|
+
relevancy evaluation.
|
|
1210
|
+
citation_enabled: Whether citations should be included in the generated
|
|
1211
|
+
answer.
|
|
1212
|
+
|
|
1213
|
+
Returns:
|
|
1214
|
+
The default prompt template corresponding to the enabled features.
|
|
1215
|
+
"""
|
|
1216
|
+
if relevancy_check_enabled:
|
|
1217
|
+
# ES prompt that has relevancy check and citations blocks
|
|
1218
|
+
return DEFAULT_ENTERPRISE_SEARCH_PROMPT_WITH_RELEVANCY_CHECK_AND_CITATION_TEMPLATE # noqa: E501
|
|
1219
|
+
elif citation_enabled:
|
|
1220
|
+
# ES prompt with citation's block - backward compatibility
|
|
1221
|
+
return DEFAULT_ENTERPRISE_SEARCH_PROMPT_WITH_CITATION_TEMPLATE
|
|
1222
|
+
else:
|
|
1223
|
+
# Legacy ES prompt - backward compatibility
|
|
1224
|
+
return DEFAULT_ENTERPRISE_SEARCH_PROMPT_TEMPLATE
|