rasa-pro 3.14.0.dev20250922__py3-none-any.whl → 3.14.0rc1__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 +15 -3
- rasa/agents/__init__.py +0 -0
- rasa/agents/agent_factory.py +122 -0
- rasa/agents/agent_manager.py +211 -0
- rasa/agents/constants.py +43 -0
- rasa/agents/core/__init__.py +0 -0
- rasa/agents/core/agent_protocol.py +107 -0
- rasa/agents/core/types.py +81 -0
- rasa/agents/exceptions.py +38 -0
- rasa/agents/protocol/__init__.py +5 -0
- rasa/agents/protocol/a2a/__init__.py +0 -0
- rasa/agents/protocol/a2a/a2a_agent.py +879 -0
- rasa/agents/protocol/mcp/__init__.py +0 -0
- rasa/agents/protocol/mcp/mcp_base_agent.py +726 -0
- rasa/agents/protocol/mcp/mcp_open_agent.py +327 -0
- rasa/agents/protocol/mcp/mcp_task_agent.py +522 -0
- rasa/agents/schemas/__init__.py +13 -0
- rasa/agents/schemas/agent_input.py +38 -0
- rasa/agents/schemas/agent_output.py +26 -0
- rasa/agents/schemas/agent_tool_result.py +65 -0
- rasa/agents/schemas/agent_tool_schema.py +186 -0
- rasa/agents/templates/__init__.py +0 -0
- rasa/agents/templates/mcp_open_agent_prompt_template.jinja2 +20 -0
- rasa/agents/templates/mcp_task_agent_prompt_template.jinja2 +22 -0
- rasa/agents/utils.py +206 -0
- rasa/agents/validation.py +485 -0
- rasa/api.py +24 -9
- rasa/builder/config.py +6 -2
- rasa/builder/guardrails/{lakera.py → clients.py} +55 -5
- rasa/builder/guardrails/constants.py +3 -0
- rasa/builder/guardrails/models.py +45 -10
- rasa/builder/guardrails/policy_checker.py +324 -0
- rasa/builder/guardrails/utils.py +42 -276
- rasa/builder/llm_service.py +32 -5
- rasa/builder/models.py +1 -0
- rasa/builder/project_generator.py +6 -1
- rasa/builder/service.py +16 -13
- rasa/builder/training_service.py +18 -24
- rasa/builder/validation_service.py +1 -1
- rasa/cli/arguments/default_arguments.py +12 -0
- rasa/cli/arguments/run.py +2 -0
- rasa/cli/arguments/train.py +2 -0
- rasa/cli/data.py +10 -8
- rasa/cli/dialogue_understanding_test.py +10 -7
- rasa/cli/e2e_test.py +9 -6
- rasa/cli/evaluate.py +4 -2
- rasa/cli/export.py +5 -2
- rasa/cli/inspect.py +8 -4
- rasa/cli/interactive.py +5 -4
- rasa/cli/llm_fine_tuning.py +11 -6
- rasa/cli/project_templates/tutorial/credentials.yml +10 -0
- rasa/cli/run.py +12 -10
- rasa/cli/scaffold.py +4 -4
- rasa/cli/shell.py +9 -5
- rasa/cli/studio/studio.py +1 -1
- rasa/cli/test.py +34 -14
- rasa/cli/train.py +41 -28
- rasa/cli/utils.py +1 -393
- rasa/cli/validation/__init__.py +0 -0
- rasa/cli/validation/bot_config.py +223 -0
- rasa/cli/validation/config_path_validation.py +257 -0
- rasa/cli/x.py +8 -4
- rasa/constants.py +7 -1
- rasa/core/actions/action.py +51 -10
- rasa/core/actions/grpc_custom_action_executor.py +1 -1
- rasa/core/agent.py +19 -2
- rasa/core/available_agents.py +229 -0
- rasa/core/channels/__init__.py +82 -35
- rasa/core/channels/development_inspector.py +3 -3
- rasa/core/channels/inspector/README.md +25 -13
- rasa/core/channels/inspector/dist/assets/{arc-35222594.js → arc-6177260a.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{blockDiagram-38ab4fdb-a0efbfd3.js → blockDiagram-38ab4fdb-b054f038.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{c4Diagram-3d4e48cf-0584c0f2.js → c4Diagram-3d4e48cf-f25427d5.js} +1 -1
- rasa/core/channels/inspector/dist/assets/channel-bf9cbb34.js +1 -0
- rasa/core/channels/inspector/dist/assets/{classDiagram-70f12bd4-39f40dbe.js → classDiagram-70f12bd4-c7a2af53.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{classDiagram-v2-f2320105-1ad755f3.js → classDiagram-v2-f2320105-58db65c0.js} +1 -1
- rasa/core/channels/inspector/dist/assets/clone-8f9083bb.js +1 -0
- rasa/core/channels/inspector/dist/assets/{createText-2e5e7dd3-b0f4f0fe.js → createText-2e5e7dd3-088372e2.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{edges-e0da2a9e-9039bff9.js → edges-e0da2a9e-58676240.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{erDiagram-9861fffd-65c9b127.js → erDiagram-9861fffd-0c14d7c6.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{flowDb-956e92f1-4f08b38e.js → flowDb-956e92f1-ea63f85c.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{flowDiagram-66a62f08-e95c362a.js → flowDiagram-66a62f08-a2af48cd.js} +1 -1
- rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-9ecd5b59.js +1 -0
- rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-4a651766-703c3015.js → flowchart-elk-definition-4a651766-6937abe7.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{ganttDiagram-c361ad54-699328ea.js → ganttDiagram-c361ad54-7473f357.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-72cf32ee-04cf4b05.js → gitGraphDiagram-72cf32ee-d0c9405e.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{graph-ee94449e.js → graph-0a6f8466.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{index-3862675e-940162b4.js → index-3862675e-7610671a.js} +1 -1
- rasa/core/channels/inspector/dist/assets/index-74e01d94.js +1354 -0
- rasa/core/channels/inspector/dist/assets/{infoDiagram-f8f76790-c79c2866.js → infoDiagram-f8f76790-be397dc7.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{journeyDiagram-49397b02-84489d30.js → journeyDiagram-49397b02-4cefbf62.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{layout-a9aa9858.js → layout-e7fbc2bf.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{line-eb73cf26.js → line-a8aa457c.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{linear-b3399f9a.js → linear-3351e0d2.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{mindmap-definition-fc14e90a-b095bf1a.js → mindmap-definition-fc14e90a-b8cbf605.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{pieDiagram-8a3498a8-07644b66.js → pieDiagram-8a3498a8-f327f774.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{quadrantDiagram-120e2f19-573a3f9c.js → quadrantDiagram-120e2f19-2854c591.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{requirementDiagram-deff3bca-d457e1e1.js → requirementDiagram-deff3bca-964985d5.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{sankeyDiagram-04a897e0-9d26e1a2.js → sankeyDiagram-04a897e0-edeb4f33.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{sequenceDiagram-704730f1-3a9cde10.js → sequenceDiagram-704730f1-fcf70125.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{stateDiagram-587899a1-4f3e8cec.js → stateDiagram-587899a1-0e770395.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-d93cdb3a-e617e5bf.js → stateDiagram-v2-d93cdb3a-af8dcd22.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-6aaf32cf-eab30d2f.js → styles-6aaf32cf-36a9e70d.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-9a916d00-09994be2.js → styles-9a916d00-884a8b5b.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-c10674c1-b7110364.js → styles-c10674c1-dc097813.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{svgDrawCommon-08f97a94-3ebc92ad.js → svgDrawCommon-08f97a94-5a2c7eed.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{timeline-definition-85554ec2-7d13d2f2.js → timeline-definition-85554ec2-e89c4f6e.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{xychartDiagram-e933f94c-488385e1.js → xychartDiagram-e933f94c-afb6fe56.js} +1 -1
- rasa/core/channels/inspector/dist/index.html +1 -1
- rasa/core/channels/inspector/package.json +18 -18
- rasa/core/channels/inspector/src/App.tsx +29 -4
- rasa/core/channels/inspector/src/components/DialogueAgentStack.tsx +108 -0
- rasa/core/channels/inspector/src/components/{DialogueStack.tsx → DialogueHistoryStack.tsx} +4 -2
- rasa/core/channels/inspector/src/helpers/audio/audiostream.ts +7 -4
- rasa/core/channels/inspector/src/helpers/formatters.test.ts +4 -0
- rasa/core/channels/inspector/src/helpers/formatters.ts +24 -3
- rasa/core/channels/inspector/src/helpers/utils.test.ts +127 -0
- rasa/core/channels/inspector/src/helpers/utils.ts +66 -1
- rasa/core/channels/inspector/src/theme/base/styles.ts +19 -1
- rasa/core/channels/inspector/src/types.ts +21 -0
- rasa/core/channels/inspector/yarn.lock +336 -189
- rasa/core/channels/studio_chat.py +6 -6
- rasa/core/channels/telegram.py +4 -9
- rasa/core/channels/voice_stream/genesys.py +1 -1
- rasa/core/channels/voice_stream/tts/deepgram.py +140 -0
- rasa/core/channels/voice_stream/twilio_media_streams.py +5 -1
- rasa/core/channels/voice_stream/voice_channel.py +3 -0
- rasa/core/config/__init__.py +0 -0
- rasa/core/{available_endpoints.py → config/available_endpoints.py} +51 -16
- rasa/core/config/configuration.py +260 -0
- rasa/core/config/credentials.py +19 -0
- rasa/core/config/message_procesing_config.py +34 -0
- rasa/core/constants.py +4 -0
- rasa/core/policies/enterprise_search_policy.py +5 -3
- rasa/core/policies/flow_policy.py +4 -4
- rasa/core/policies/flows/agent_executor.py +632 -0
- rasa/core/policies/flows/flow_executor.py +136 -75
- rasa/core/policies/flows/mcp_tool_executor.py +298 -0
- rasa/core/policies/intentless_policy.py +1 -1
- rasa/core/policies/ted_policy.py +20 -12
- rasa/core/policies/unexpected_intent_policy.py +6 -0
- rasa/core/processor.py +68 -44
- rasa/core/run.py +37 -8
- rasa/core/test.py +4 -0
- rasa/core/tracker_stores/tracker_store.py +3 -7
- rasa/core/train.py +1 -1
- rasa/core/training/interactive.py +20 -18
- rasa/core/training/story_conflict.py +5 -5
- rasa/core/utils.py +22 -23
- rasa/dialogue_understanding/commands/__init__.py +8 -0
- rasa/dialogue_understanding/commands/cancel_flow_command.py +19 -5
- rasa/dialogue_understanding/commands/chit_chat_answer_command.py +21 -2
- rasa/dialogue_understanding/commands/clarify_command.py +20 -2
- rasa/dialogue_understanding/commands/continue_agent_command.py +91 -0
- rasa/dialogue_understanding/commands/knowledge_answer_command.py +21 -2
- rasa/dialogue_understanding/commands/restart_agent_command.py +162 -0
- rasa/dialogue_understanding/commands/start_flow_command.py +68 -7
- rasa/dialogue_understanding/commands/utils.py +124 -2
- rasa/dialogue_understanding/generator/command_parser.py +4 -0
- rasa/dialogue_understanding/generator/llm_based_command_generator.py +50 -12
- rasa/dialogue_understanding/generator/llm_command_generator.py +1 -1
- rasa/dialogue_understanding/generator/multi_step/multi_step_llm_command_generator.py +1 -1
- rasa/dialogue_understanding/generator/prompt_templates/agent_command_prompt_v2_claude_3_5_sonnet_20240620_template.jinja2 +66 -0
- rasa/dialogue_understanding/generator/prompt_templates/agent_command_prompt_v2_gpt_4o_2024_11_20_template.jinja2 +66 -0
- rasa/dialogue_understanding/generator/prompt_templates/agent_command_prompt_v3_claude_3_5_sonnet_20240620_template.jinja2 +89 -0
- rasa/dialogue_understanding/generator/prompt_templates/agent_command_prompt_v3_gpt_4o_2024_11_20_template.jinja2 +88 -0
- rasa/dialogue_understanding/generator/single_step/compact_llm_command_generator.py +42 -7
- rasa/dialogue_understanding/generator/single_step/search_ready_llm_command_generator.py +40 -3
- rasa/dialogue_understanding/generator/single_step/single_step_based_llm_command_generator.py +20 -3
- rasa/dialogue_understanding/patterns/cancel.py +27 -6
- rasa/dialogue_understanding/patterns/clarify.py +3 -14
- rasa/dialogue_understanding/patterns/continue_interrupted.py +239 -6
- rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml +46 -8
- rasa/dialogue_understanding/processor/command_processor.py +136 -15
- rasa/dialogue_understanding/stack/dialogue_stack.py +98 -2
- rasa/dialogue_understanding/stack/frames/flow_stack_frame.py +57 -0
- rasa/dialogue_understanding/stack/utils.py +57 -3
- rasa/dialogue_understanding/utils.py +24 -4
- rasa/dialogue_understanding_test/du_test_runner.py +8 -3
- rasa/e2e_test/e2e_test_runner.py +13 -3
- rasa/engine/caching.py +2 -2
- rasa/engine/constants.py +1 -1
- rasa/engine/recipes/default_components.py +138 -49
- rasa/engine/recipes/default_recipe.py +108 -11
- rasa/engine/runner/dask.py +8 -5
- rasa/engine/validation.py +19 -6
- rasa/graph_components/validators/default_recipe_validator.py +86 -28
- rasa/hooks.py +5 -5
- rasa/llm_fine_tuning/utils.py +2 -2
- rasa/model_training.py +60 -47
- rasa/nlu/classifiers/diet_classifier.py +198 -98
- rasa/nlu/classifiers/logistic_regression_classifier.py +1 -4
- rasa/nlu/classifiers/mitie_intent_classifier.py +3 -0
- rasa/nlu/classifiers/sklearn_intent_classifier.py +1 -3
- rasa/nlu/extractors/crf_entity_extractor.py +9 -10
- rasa/nlu/extractors/mitie_entity_extractor.py +3 -0
- rasa/nlu/extractors/spacy_entity_extractor.py +3 -0
- rasa/nlu/featurizers/dense_featurizer/convert_featurizer.py +4 -0
- rasa/nlu/featurizers/dense_featurizer/lm_featurizer.py +5 -0
- rasa/nlu/featurizers/dense_featurizer/mitie_featurizer.py +2 -0
- rasa/nlu/featurizers/dense_featurizer/spacy_featurizer.py +3 -0
- rasa/nlu/featurizers/sparse_featurizer/count_vectors_featurizer.py +4 -2
- rasa/nlu/featurizers/sparse_featurizer/lexical_syntactic_featurizer.py +4 -0
- rasa/nlu/selectors/response_selector.py +10 -2
- rasa/nlu/tokenizers/jieba_tokenizer.py +3 -4
- rasa/nlu/tokenizers/mitie_tokenizer.py +3 -2
- rasa/nlu/tokenizers/spacy_tokenizer.py +3 -2
- rasa/nlu/utils/mitie_utils.py +3 -0
- rasa/nlu/utils/spacy_utils.py +3 -2
- rasa/plugin.py +8 -8
- rasa/privacy/privacy_manager.py +12 -3
- rasa/server.py +15 -3
- rasa/shared/agents/__init__.py +0 -0
- rasa/shared/agents/auth/__init__.py +0 -0
- rasa/shared/agents/auth/agent_auth_factory.py +105 -0
- rasa/shared/agents/auth/agent_auth_manager.py +92 -0
- rasa/shared/agents/auth/auth_strategy/__init__.py +19 -0
- rasa/shared/agents/auth/auth_strategy/agent_auth_strategy.py +52 -0
- rasa/shared/agents/auth/auth_strategy/api_key_auth_strategy.py +42 -0
- rasa/shared/agents/auth/auth_strategy/bearer_token_auth_strategy.py +28 -0
- rasa/shared/agents/auth/auth_strategy/oauth2_auth_strategy.py +167 -0
- rasa/shared/agents/auth/constants.py +12 -0
- rasa/shared/agents/auth/types.py +12 -0
- rasa/shared/agents/utils.py +35 -0
- rasa/shared/constants.py +8 -0
- rasa/shared/core/constants.py +16 -1
- rasa/shared/core/domain.py +0 -7
- rasa/shared/core/events.py +327 -0
- rasa/shared/core/flows/constants.py +5 -0
- rasa/shared/core/flows/flows_list.py +21 -5
- rasa/shared/core/flows/flows_yaml_schema.json +119 -184
- rasa/shared/core/flows/steps/call.py +49 -5
- rasa/shared/core/flows/steps/collect.py +98 -13
- rasa/shared/core/flows/validation.py +372 -8
- rasa/shared/core/flows/yaml_flows_io.py +3 -2
- rasa/shared/core/slots.py +2 -2
- rasa/shared/core/trackers.py +5 -2
- rasa/shared/exceptions.py +16 -0
- rasa/shared/importers/rasa.py +1 -1
- rasa/shared/importers/utils.py +9 -3
- rasa/shared/providers/llm/_base_litellm_client.py +41 -9
- rasa/shared/providers/llm/litellm_router_llm_client.py +8 -4
- rasa/shared/providers/llm/llm_client.py +7 -3
- rasa/shared/providers/llm/llm_response.py +66 -0
- rasa/shared/providers/llm/self_hosted_llm_client.py +8 -4
- rasa/shared/utils/common.py +24 -0
- rasa/shared/utils/health_check/health_check.py +7 -3
- rasa/shared/utils/llm.py +39 -16
- rasa/shared/utils/mcp/__init__.py +0 -0
- rasa/shared/utils/mcp/server_connection.py +247 -0
- rasa/shared/utils/mcp/utils.py +20 -0
- rasa/shared/utils/schemas/events.py +42 -0
- rasa/shared/utils/yaml.py +3 -1
- rasa/studio/pull/pull.py +3 -2
- rasa/studio/train.py +8 -7
- rasa/studio/upload.py +3 -6
- rasa/telemetry.py +69 -5
- rasa/tracing/config.py +45 -12
- rasa/tracing/constants.py +14 -0
- rasa/tracing/instrumentation/attribute_extractors.py +142 -9
- rasa/tracing/instrumentation/instrumentation.py +626 -21
- rasa/tracing/instrumentation/intentless_policy_instrumentation.py +4 -4
- rasa/tracing/instrumentation/metrics.py +32 -0
- rasa/tracing/metric_instrument_provider.py +68 -0
- rasa/utils/common.py +92 -1
- rasa/utils/endpoints.py +11 -2
- rasa/utils/log_utils.py +96 -5
- rasa/utils/ml_utils.py +1 -1
- rasa/utils/tensorflow/__init__.py +7 -0
- rasa/utils/tensorflow/callback.py +136 -101
- rasa/utils/tensorflow/crf.py +1 -1
- rasa/utils/tensorflow/data_generator.py +21 -8
- rasa/utils/tensorflow/layers.py +21 -11
- rasa/utils/tensorflow/metrics.py +7 -3
- rasa/utils/tensorflow/models.py +56 -8
- rasa/utils/tensorflow/rasa_layers.py +8 -6
- rasa/utils/tensorflow/transformer.py +2 -3
- rasa/utils/train_utils.py +54 -24
- rasa/validator.py +5 -5
- rasa/version.py +1 -1
- {rasa_pro-3.14.0.dev20250922.dist-info → rasa_pro-3.14.0rc1.dist-info}/METADATA +46 -41
- {rasa_pro-3.14.0.dev20250922.dist-info → rasa_pro-3.14.0rc1.dist-info}/RECORD +285 -226
- rasa/builder/scrape_rasa_docs.py +0 -97
- rasa/core/channels/inspector/dist/assets/channel-8e08bed9.js +0 -1
- rasa/core/channels/inspector/dist/assets/clone-78c82dea.js +0 -1
- rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-2b08f601.js +0 -1
- rasa/core/channels/inspector/dist/assets/index-c941dcb3.js +0 -1336
- {rasa_pro-3.14.0.dev20250922.dist-info → rasa_pro-3.14.0rc1.dist-info}/NOTICE +0 -0
- {rasa_pro-3.14.0.dev20250922.dist-info → rasa_pro-3.14.0rc1.dist-info}/WHEEL +0 -0
- {rasa_pro-3.14.0.dev20250922.dist-info → rasa_pro-3.14.0rc1.dist-info}/entry_points.txt +0 -0
|
@@ -37,7 +37,7 @@ def _instrument_select_response_examples(
|
|
|
37
37
|
|
|
38
38
|
return wrapper
|
|
39
39
|
|
|
40
|
-
policy_class.select_response_examples = tracing_select_response_examples_wrapper( # type: ignore[
|
|
40
|
+
policy_class.select_response_examples = tracing_select_response_examples_wrapper( # type: ignore[method-assign]
|
|
41
41
|
policy_class.select_response_examples
|
|
42
42
|
)
|
|
43
43
|
|
|
@@ -72,7 +72,7 @@ def _instrument_select_few_shot_conversations(
|
|
|
72
72
|
|
|
73
73
|
return wrapper
|
|
74
74
|
|
|
75
|
-
policy_class.select_few_shot_conversations = ( # type: ignore[
|
|
75
|
+
policy_class.select_few_shot_conversations = ( # type: ignore[method-assign]
|
|
76
76
|
tracing_select_few_shot_conversations_wrapper(
|
|
77
77
|
policy_class.select_few_shot_conversations
|
|
78
78
|
)
|
|
@@ -104,7 +104,7 @@ def _instrument_extract_ai_responses(
|
|
|
104
104
|
|
|
105
105
|
return wrapper
|
|
106
106
|
|
|
107
|
-
policy_class.extract_ai_responses = tracing_extract_ai_responses_wrapper( # type: ignore[
|
|
107
|
+
policy_class.extract_ai_responses = tracing_extract_ai_responses_wrapper( # type: ignore[method-assign]
|
|
108
108
|
policy_class.extract_ai_responses
|
|
109
109
|
)
|
|
110
110
|
|
|
@@ -137,7 +137,7 @@ def _instrument_generate_answer(
|
|
|
137
137
|
|
|
138
138
|
return wrapper
|
|
139
139
|
|
|
140
|
-
policy_class.generate_answer = tracing_generate_answer_wrapper( # type: ignore[
|
|
140
|
+
policy_class.generate_answer = tracing_generate_answer_wrapper( # type: ignore[method-assign]
|
|
141
141
|
policy_class.generate_answer
|
|
142
142
|
)
|
|
143
143
|
|
|
@@ -2,6 +2,7 @@ from typing import Any, Dict
|
|
|
2
2
|
|
|
3
3
|
import psutil
|
|
4
4
|
|
|
5
|
+
from rasa.agents.protocol.mcp.mcp_base_agent import MCPBaseAgent
|
|
5
6
|
from rasa.core.nlg.contextual_response_rephraser import ContextualResponseRephraser
|
|
6
7
|
from rasa.core.policies.enterprise_search_policy import EnterpriseSearchPolicy
|
|
7
8
|
from rasa.core.policies.intentless_policy import IntentlessPolicy
|
|
@@ -27,6 +28,10 @@ from rasa.tracing.constants import (
|
|
|
27
28
|
LLM_COMMAND_GENERATOR_LLM_RESPONSE_DURATION_METRIC_NAME,
|
|
28
29
|
LLM_COMMAND_GENERATOR_MEMORY_USAGE_METRIC_NAME,
|
|
29
30
|
LLM_COMMAND_GENERATOR_PROMPT_TOKEN_USAGE_METRIC_NAME,
|
|
31
|
+
MCP_AGENT_LLM_CPU_USAGE_METRIC_NAME,
|
|
32
|
+
MCP_AGENT_LLM_MEMORY_USAGE_METRIC_NAME,
|
|
33
|
+
MCP_AGENT_LLM_PROMPT_TOKEN_USAGE_METRIC_NAME,
|
|
34
|
+
MCP_AGENT_LLM_RESPONSE_DURATION_METRIC_NAME,
|
|
30
35
|
MULTI_STEP_LLM_COMMAND_GENERATOR_CPU_USAGE_METRIC_NAME,
|
|
31
36
|
MULTI_STEP_LLM_COMMAND_GENERATOR_LLM_RESPONSE_DURATION_METRIC_NAME,
|
|
32
37
|
MULTI_STEP_LLM_COMMAND_GENERATOR_MEMORY_USAGE_METRIC_NAME,
|
|
@@ -385,6 +390,11 @@ def record_callable_duration_metrics(
|
|
|
385
390
|
)
|
|
386
391
|
attributes = {"url": kwargs.get("url")}
|
|
387
392
|
|
|
393
|
+
if isinstance(self, MCPBaseAgent):
|
|
394
|
+
metric_instrument = instrument_provider.get_instrument(
|
|
395
|
+
MCP_AGENT_LLM_RESPONSE_DURATION_METRIC_NAME
|
|
396
|
+
)
|
|
397
|
+
|
|
388
398
|
if not metric_instrument:
|
|
389
399
|
return None
|
|
390
400
|
|
|
@@ -416,3 +426,25 @@ def record_request_size_in_bytes(attributes: Dict[str, Any]) -> None:
|
|
|
416
426
|
|
|
417
427
|
request_body_size = attributes.pop(REQUEST_BODY_SIZE_IN_BYTES_ATTRIBUTE_NAME, 0)
|
|
418
428
|
metric_instrument.record(amount=request_body_size, attributes=attributes)
|
|
429
|
+
|
|
430
|
+
|
|
431
|
+
def record_mcp_agent_llm_metrics(attributes: Dict[str, Any]) -> None:
|
|
432
|
+
"""Record MCP agent LLM metrics."""
|
|
433
|
+
instrument_provider = MetricInstrumentProvider()
|
|
434
|
+
|
|
435
|
+
if not instrument_provider.instruments:
|
|
436
|
+
return None
|
|
437
|
+
|
|
438
|
+
# Use MCP agent specific metric names
|
|
439
|
+
record_llm_based_component_cpu_usage(
|
|
440
|
+
instrument_provider, MCP_AGENT_LLM_CPU_USAGE_METRIC_NAME
|
|
441
|
+
)
|
|
442
|
+
record_llm_based_component_memory_usage(
|
|
443
|
+
instrument_provider, MCP_AGENT_LLM_MEMORY_USAGE_METRIC_NAME
|
|
444
|
+
)
|
|
445
|
+
record_llm_based_component_prompt_token(
|
|
446
|
+
instrument_provider,
|
|
447
|
+
attributes,
|
|
448
|
+
MCP_AGENT_LLM_PROMPT_TOKEN_USAGE_METRIC_NAME,
|
|
449
|
+
)
|
|
450
|
+
return None
|
|
@@ -4,6 +4,7 @@ from opentelemetry.metrics import get_meter_provider
|
|
|
4
4
|
from opentelemetry.sdk.metrics import Meter
|
|
5
5
|
|
|
6
6
|
from rasa.tracing.constants import (
|
|
7
|
+
AGENT_EXECUTION_DURATION_METRIC_NAME,
|
|
7
8
|
COMPACT_LLM_COMMAND_GENERATOR_CPU_USAGE_METRIC_NAME,
|
|
8
9
|
COMPACT_LLM_COMMAND_GENERATOR_LLM_RESPONSE_DURATION_METRIC_NAME,
|
|
9
10
|
COMPACT_LLM_COMMAND_GENERATOR_MEMORY_USAGE_METRIC_NAME,
|
|
@@ -20,6 +21,11 @@ from rasa.tracing.constants import (
|
|
|
20
21
|
LLM_COMMAND_GENERATOR_LLM_RESPONSE_DURATION_METRIC_NAME,
|
|
21
22
|
LLM_COMMAND_GENERATOR_MEMORY_USAGE_METRIC_NAME,
|
|
22
23
|
LLM_COMMAND_GENERATOR_PROMPT_TOKEN_USAGE_METRIC_NAME,
|
|
24
|
+
MCP_AGENT_LLM_CPU_USAGE_METRIC_NAME,
|
|
25
|
+
MCP_AGENT_LLM_MEMORY_USAGE_METRIC_NAME,
|
|
26
|
+
MCP_AGENT_LLM_PROMPT_TOKEN_USAGE_METRIC_NAME,
|
|
27
|
+
MCP_AGENT_LLM_RESPONSE_DURATION_METRIC_NAME,
|
|
28
|
+
MCP_TOOL_EXECUTION_DURATION_METRIC_NAME,
|
|
23
29
|
MULTI_STEP_LLM_COMMAND_GENERATOR_CPU_USAGE_METRIC_NAME,
|
|
24
30
|
MULTI_STEP_LLM_COMMAND_GENERATOR_LLM_RESPONSE_DURATION_METRIC_NAME,
|
|
25
31
|
MULTI_STEP_LLM_COMMAND_GENERATOR_MEMORY_USAGE_METRIC_NAME,
|
|
@@ -59,6 +65,8 @@ class MetricInstrumentProvider(metaclass=Singleton):
|
|
|
59
65
|
**self._create_multi_step_llm_command_generator_instruments(meter),
|
|
60
66
|
**self._create_enterprise_search_policy_instruments(meter),
|
|
61
67
|
**self._create_llm_response_duration_instruments(meter),
|
|
68
|
+
**self._create_mcp_and_a2a_agent_instruments(meter),
|
|
69
|
+
**self._create_mcp_agent_llm_instruments(meter),
|
|
62
70
|
**self._create_client_request_instruments(meter),
|
|
63
71
|
}
|
|
64
72
|
|
|
@@ -295,6 +303,28 @@ class MetricInstrumentProvider(metaclass=Singleton):
|
|
|
295
303
|
CONTEXTUAL_RESPONSE_REPHRASER_LLM_RESPONSE_DURATION_METRIC_NAME: llm_response_duration_contextual_nlg, # noqa: E501
|
|
296
304
|
}
|
|
297
305
|
|
|
306
|
+
@staticmethod
|
|
307
|
+
def _create_mcp_and_a2a_agent_instruments(
|
|
308
|
+
meter: Meter,
|
|
309
|
+
) -> Dict[str, Any]:
|
|
310
|
+
"""Create instruments for MCP tool execution and agent execution."""
|
|
311
|
+
mcp_tool_execution_duration = meter.create_histogram(
|
|
312
|
+
name=MCP_TOOL_EXECUTION_DURATION_METRIC_NAME,
|
|
313
|
+
description="The duration of MCP tool execution",
|
|
314
|
+
unit=DURATION_UNIT_NAME,
|
|
315
|
+
)
|
|
316
|
+
|
|
317
|
+
agent_execution_duration = meter.create_histogram(
|
|
318
|
+
name=AGENT_EXECUTION_DURATION_METRIC_NAME,
|
|
319
|
+
description="The duration of agent execution",
|
|
320
|
+
unit=DURATION_UNIT_NAME,
|
|
321
|
+
)
|
|
322
|
+
|
|
323
|
+
return {
|
|
324
|
+
MCP_TOOL_EXECUTION_DURATION_METRIC_NAME: mcp_tool_execution_duration,
|
|
325
|
+
AGENT_EXECUTION_DURATION_METRIC_NAME: agent_execution_duration,
|
|
326
|
+
}
|
|
327
|
+
|
|
298
328
|
@staticmethod
|
|
299
329
|
def _create_client_request_instruments(
|
|
300
330
|
meter: Meter,
|
|
@@ -315,3 +345,41 @@ class MetricInstrumentProvider(metaclass=Singleton):
|
|
|
315
345
|
RASA_CLIENT_REQUEST_DURATION_METRIC_NAME: client_request_duration,
|
|
316
346
|
RASA_CLIENT_REQUEST_BODY_SIZE_METRIC_NAME: client_request_body_size,
|
|
317
347
|
}
|
|
348
|
+
|
|
349
|
+
@staticmethod
|
|
350
|
+
def _create_mcp_agent_llm_instruments(meter: Meter) -> Dict[str, Any]:
|
|
351
|
+
"""Create instruments for MCP agent LLM calls."""
|
|
352
|
+
mcp_agent_llm_cpu_usage = meter.create_histogram(
|
|
353
|
+
name=MCP_AGENT_LLM_CPU_USAGE_METRIC_NAME,
|
|
354
|
+
description="CPU usage during MCP agent LLM calls",
|
|
355
|
+
unit=LLM_BASED_COMMAND_GENERATOR_CPU_MEMORY_USAGE_UNIT_NAME,
|
|
356
|
+
)
|
|
357
|
+
|
|
358
|
+
mcp_agent_llm_memory_usage = meter.create_histogram(
|
|
359
|
+
name=MCP_AGENT_LLM_MEMORY_USAGE_METRIC_NAME,
|
|
360
|
+
description="Memory usage during MCP agent LLM calls",
|
|
361
|
+
unit=LLM_BASED_COMMAND_GENERATOR_CPU_MEMORY_USAGE_UNIT_NAME,
|
|
362
|
+
)
|
|
363
|
+
|
|
364
|
+
mcp_agent_llm_prompt_token_usage = meter.create_histogram(
|
|
365
|
+
name=MCP_AGENT_LLM_PROMPT_TOKEN_USAGE_METRIC_NAME,
|
|
366
|
+
description="Prompt token usage for MCP agent LLM calls",
|
|
367
|
+
unit="token",
|
|
368
|
+
)
|
|
369
|
+
|
|
370
|
+
mcp_agent_llm_response_duration = meter.create_histogram(
|
|
371
|
+
name=MCP_AGENT_LLM_RESPONSE_DURATION_METRIC_NAME,
|
|
372
|
+
description="Duration of MCP agent LLM calls",
|
|
373
|
+
unit=DURATION_UNIT_NAME,
|
|
374
|
+
)
|
|
375
|
+
|
|
376
|
+
return {
|
|
377
|
+
MCP_AGENT_LLM_CPU_USAGE_METRIC_NAME: mcp_agent_llm_cpu_usage,
|
|
378
|
+
MCP_AGENT_LLM_MEMORY_USAGE_METRIC_NAME: mcp_agent_llm_memory_usage,
|
|
379
|
+
MCP_AGENT_LLM_PROMPT_TOKEN_USAGE_METRIC_NAME: (
|
|
380
|
+
mcp_agent_llm_prompt_token_usage
|
|
381
|
+
),
|
|
382
|
+
MCP_AGENT_LLM_RESPONSE_DURATION_METRIC_NAME: (
|
|
383
|
+
mcp_agent_llm_response_duration
|
|
384
|
+
),
|
|
385
|
+
}
|
rasa/utils/common.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import copy
|
|
2
2
|
import inspect
|
|
3
|
+
import json
|
|
3
4
|
import logging
|
|
4
5
|
import logging.config
|
|
5
6
|
import logging.handlers
|
|
@@ -34,7 +35,9 @@ from rasa.constants import (
|
|
|
34
35
|
ENV_LOG_LEVEL_KAFKA,
|
|
35
36
|
ENV_LOG_LEVEL_LIBRARIES,
|
|
36
37
|
ENV_LOG_LEVEL_MATPLOTLIB,
|
|
38
|
+
ENV_LOG_LEVEL_MCP,
|
|
37
39
|
ENV_LOG_LEVEL_RABBITMQ,
|
|
40
|
+
ENV_MCP_LOGGING_ENABLED,
|
|
38
41
|
)
|
|
39
42
|
from rasa.shared.constants import DEFAULT_LOG_LEVEL, ENV_LOG_LEVEL, TCP_PROTOCOL
|
|
40
43
|
from rasa.shared.exceptions import RasaException
|
|
@@ -49,7 +52,7 @@ EXPECTED_WARNINGS: List[Tuple[Type[Warning], str]] = [
|
|
|
49
52
|
# TODO (issue #9932)
|
|
50
53
|
# DM1 warnings
|
|
51
54
|
(
|
|
52
|
-
np.VisibleDeprecationWarning,
|
|
55
|
+
np.exceptions.VisibleDeprecationWarning,
|
|
53
56
|
"Creating an ndarray from ragged nested sequences.*",
|
|
54
57
|
),
|
|
55
58
|
# raised by magic_filter, google rpc
|
|
@@ -129,6 +132,18 @@ EXPECTED_WARNINGS: List[Tuple[Type[Warning], str]] = [
|
|
|
129
132
|
FutureWarning,
|
|
130
133
|
"'request_timeout' is deprecated and will be removed in 4.0.0. Use 'timeout'*",
|
|
131
134
|
),
|
|
135
|
+
(
|
|
136
|
+
FutureWarning,
|
|
137
|
+
"TEDPolicy is deprecated and will be removed in a future version.*",
|
|
138
|
+
),
|
|
139
|
+
(
|
|
140
|
+
FutureWarning,
|
|
141
|
+
"DIETClassifier is deprecated and will be removed in a future version.*",
|
|
142
|
+
),
|
|
143
|
+
(
|
|
144
|
+
FutureWarning,
|
|
145
|
+
"ResponseSelector is deprecated and will be removed in a future version.*",
|
|
146
|
+
),
|
|
132
147
|
]
|
|
133
148
|
|
|
134
149
|
PYTHON_LOGGING_SCHEMA_DOCS = (
|
|
@@ -281,6 +296,7 @@ def configure_library_logging() -> None:
|
|
|
281
296
|
update_kafka_log_level(library_log_level)
|
|
282
297
|
update_rabbitmq_log_level(library_log_level)
|
|
283
298
|
update_websockets_log_level(library_log_level)
|
|
299
|
+
update_mcp_log_level()
|
|
284
300
|
|
|
285
301
|
|
|
286
302
|
def update_apscheduler_log_level() -> None:
|
|
@@ -415,6 +431,56 @@ def update_websockets_log_level(library_log_level: Text) -> None:
|
|
|
415
431
|
logging.getLogger("websockets").propagate = False
|
|
416
432
|
|
|
417
433
|
|
|
434
|
+
def update_mcp_log_level() -> None:
|
|
435
|
+
"""Set the log level for MCP-related loggers.
|
|
436
|
+
|
|
437
|
+
This function configures logging levels for MCP (Model Context Protocol) related
|
|
438
|
+
loggers to reduce noise from HTTP and MCP client libraries.
|
|
439
|
+
|
|
440
|
+
Environment Variables:
|
|
441
|
+
LOG_LEVEL_MCP: Set the log level for MCP-related loggers.
|
|
442
|
+
Valid values: DEBUG, INFO, WARNING, ERROR, CRITICAL
|
|
443
|
+
Default: ERROR
|
|
444
|
+
|
|
445
|
+
MCP_LOGGING_ENABLED: Enable or disable MCP logging completely.
|
|
446
|
+
Valid values: true, false
|
|
447
|
+
Default: true
|
|
448
|
+
|
|
449
|
+
Examples:
|
|
450
|
+
# Show only ERROR and above for MCP logs
|
|
451
|
+
export LOG_LEVEL_MCP=ERROR
|
|
452
|
+
|
|
453
|
+
# Show DEBUG level MCP logs (very verbose)
|
|
454
|
+
export LOG_LEVEL_MCP=DEBUG
|
|
455
|
+
|
|
456
|
+
# Completely disable MCP logging
|
|
457
|
+
export MCP_LOGGING_ENABLED=false
|
|
458
|
+
"""
|
|
459
|
+
# Check if MCP logging is completely disabled
|
|
460
|
+
mcp_logging_enabled = (
|
|
461
|
+
os.environ.get(ENV_MCP_LOGGING_ENABLED, "true").lower() == "true"
|
|
462
|
+
)
|
|
463
|
+
|
|
464
|
+
# Default to ERROR level for MCP logs to reduce noise
|
|
465
|
+
mcp_log_level: Union[int, str] = os.environ.get(ENV_LOG_LEVEL_MCP, "ERROR")
|
|
466
|
+
if not mcp_logging_enabled:
|
|
467
|
+
# Completely disable MCP logging
|
|
468
|
+
mcp_log_level = logging.CRITICAL + 1 # Higher than CRITICAL to disable all logs
|
|
469
|
+
|
|
470
|
+
# MCP client and HTTP-related loggers that are commonly noisy
|
|
471
|
+
mcp_loggers = [
|
|
472
|
+
"mcp.client.streamable_http",
|
|
473
|
+
"mcp.client",
|
|
474
|
+
"httpcore.connection",
|
|
475
|
+
"httpcore.http11",
|
|
476
|
+
"httpx",
|
|
477
|
+
]
|
|
478
|
+
|
|
479
|
+
for logger_name in mcp_loggers:
|
|
480
|
+
logging.getLogger(logger_name).setLevel(mcp_log_level)
|
|
481
|
+
logging.getLogger(logger_name).propagate = False
|
|
482
|
+
|
|
483
|
+
|
|
418
484
|
def sort_list_of_dicts_by_first_key(dicts: List[Dict]) -> List[Dict]:
|
|
419
485
|
"""Sorts a list of dictionaries by their first key."""
|
|
420
486
|
return sorted(dicts, key=lambda d: next(iter(d.keys())))
|
|
@@ -646,3 +712,28 @@ def get_bool_env_variable(variable_name: str, default_variable_value: bool) -> b
|
|
|
646
712
|
f"Available values are `{true_values + false_values}`"
|
|
647
713
|
)
|
|
648
714
|
return value.lower() in true_values
|
|
715
|
+
|
|
716
|
+
|
|
717
|
+
def try_parse_json(value: Any) -> Any:
|
|
718
|
+
"""If value is a JSON string, parse it into a dict/list, else return as-is."""
|
|
719
|
+
if isinstance(value, str):
|
|
720
|
+
try:
|
|
721
|
+
return json.loads(value)
|
|
722
|
+
except json.JSONDecodeError:
|
|
723
|
+
return value
|
|
724
|
+
return value
|
|
725
|
+
|
|
726
|
+
|
|
727
|
+
def ensure_jsonified_iterable(value: Any) -> Any:
|
|
728
|
+
"""Convert iterables to JSON strings, flatten nested JSON strings in dicts/lists."""
|
|
729
|
+
if isinstance(value, dict):
|
|
730
|
+
# Recursively process dict values
|
|
731
|
+
return {
|
|
732
|
+
key: ensure_jsonified_iterable(try_parse_json(val))
|
|
733
|
+
for key, val in value.items()
|
|
734
|
+
}
|
|
735
|
+
elif isinstance(value, list):
|
|
736
|
+
# Recursively process each item
|
|
737
|
+
return [ensure_jsonified_iterable(try_parse_json(val)) for val in value]
|
|
738
|
+
# Keep primitives as-is
|
|
739
|
+
return value
|
rasa/utils/endpoints.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import ssl
|
|
3
|
+
from pathlib import Path
|
|
3
4
|
from types import ModuleType
|
|
4
5
|
from typing import Any, Dict, List, Optional, Text, Union
|
|
5
6
|
|
|
@@ -16,7 +17,7 @@ structlogger = structlog.get_logger()
|
|
|
16
17
|
|
|
17
18
|
|
|
18
19
|
def read_endpoint_config(
|
|
19
|
-
filename:
|
|
20
|
+
filename: Union[str, Path], endpoint_type: Text
|
|
20
21
|
) -> Optional["EndpointConfig"]:
|
|
21
22
|
"""Read an endpoint configuration file from disk and extract one config."""
|
|
22
23
|
if not filename:
|
|
@@ -25,6 +26,14 @@ def read_endpoint_config(
|
|
|
25
26
|
try:
|
|
26
27
|
content = read_config_file(filename)
|
|
27
28
|
|
|
29
|
+
structlogger.debug(
|
|
30
|
+
"endpoint.read.success",
|
|
31
|
+
filename=os.path.abspath(filename),
|
|
32
|
+
endpoint_type=endpoint_type,
|
|
33
|
+
event_info="Successfully read endpoint configuration file.",
|
|
34
|
+
content=content,
|
|
35
|
+
)
|
|
36
|
+
|
|
28
37
|
if content.get(endpoint_type) is None:
|
|
29
38
|
return None
|
|
30
39
|
|
|
@@ -42,7 +51,7 @@ def read_endpoint_config(
|
|
|
42
51
|
|
|
43
52
|
|
|
44
53
|
def read_property_config_from_endpoints_file(
|
|
45
|
-
filename: str, property_name: str
|
|
54
|
+
filename: Union[str, Path], property_name: str
|
|
46
55
|
) -> Optional[Union[Dict[str, Any], List]]:
|
|
47
56
|
"""Read a property from an endpoint configuration file."""
|
|
48
57
|
if not filename:
|
rasa/utils/log_utils.py
CHANGED
|
@@ -19,19 +19,110 @@ from rasa.shared.constants import (
|
|
|
19
19
|
)
|
|
20
20
|
|
|
21
21
|
FORCE_JSON_LOGGING = os.environ.get("FORCE_JSON_LOGGING")
|
|
22
|
+
ANSI_CYAN_BOLD = "\033[1;36m"
|
|
23
|
+
ANSI_RESET = "\033[0m"
|
|
22
24
|
|
|
23
25
|
|
|
24
26
|
class HumanConsoleRenderer(ConsoleRenderer):
|
|
25
27
|
"""Console renderer that outputs human-readable logs."""
|
|
26
28
|
|
|
27
29
|
def __call__(self, logger: WrappedLogger, name: str, event_dict: EventDict) -> str:
|
|
30
|
+
should_highlight = event_dict.get("highlight", False)
|
|
31
|
+
terminal_width = self._get_terminal_width()
|
|
32
|
+
|
|
33
|
+
# Use event_info as title for the log entry
|
|
28
34
|
if "event_info" in event_dict:
|
|
29
35
|
event_key = event_dict["event"]
|
|
30
36
|
event_dict["event"] = event_dict["event_info"]
|
|
31
37
|
event_dict["event_key"] = event_key
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
38
|
+
event_dict.pop("event_info", None)
|
|
39
|
+
|
|
40
|
+
# In case the log entry should be highlighted
|
|
41
|
+
# make sure to surround the log entry with ===
|
|
42
|
+
event_dict = self._highlight_log_entry(
|
|
43
|
+
event_dict, terminal_width, should_highlight
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
# Format JSON data for better readability
|
|
47
|
+
event_dict = self._format_json_data(event_dict)
|
|
48
|
+
|
|
49
|
+
# Render the log entry first
|
|
50
|
+
result = super().__call__(logger, name, event_dict)
|
|
51
|
+
|
|
52
|
+
# ensure that newlines are properly rendered
|
|
53
|
+
result = "\n".join(result.split("\\n"))
|
|
54
|
+
|
|
55
|
+
# Add closing === if we highlighted this entry
|
|
56
|
+
if should_highlight:
|
|
57
|
+
result += f"\n{'=' * terminal_width}"
|
|
58
|
+
|
|
59
|
+
return result
|
|
60
|
+
|
|
61
|
+
def _highlight_log_entry(
|
|
62
|
+
self, event_dict: EventDict, terminal_width: int, should_highlight: bool
|
|
63
|
+
) -> EventDict:
|
|
64
|
+
if should_highlight:
|
|
65
|
+
# Only highlight if log level is DEBUG
|
|
66
|
+
# structlog passes log level as 'level' or 'levelname'
|
|
67
|
+
level = event_dict.get("level", event_dict.get("levelname", "")).upper()
|
|
68
|
+
if level == "DEBUG":
|
|
69
|
+
# Add opening === before the event info
|
|
70
|
+
if "event" in event_dict and isinstance(event_dict["event"], str):
|
|
71
|
+
event_info = event_dict["event"]
|
|
72
|
+
event_dict["event"] = (
|
|
73
|
+
f"\n{'=' * terminal_width}\n"
|
|
74
|
+
f"{ANSI_CYAN_BOLD}{event_info}{ANSI_RESET}\n"
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
event_dict.pop("highlight", None)
|
|
78
|
+
|
|
79
|
+
return event_dict
|
|
80
|
+
|
|
81
|
+
def _format_json_data(self, event_dict: EventDict) -> EventDict:
|
|
82
|
+
"""Format JSON data in the event dict for better readability."""
|
|
83
|
+
# Get the list of fields to format from the event dict
|
|
84
|
+
fields_to_format = event_dict.get("json_formatting", [])
|
|
85
|
+
|
|
86
|
+
if not fields_to_format:
|
|
87
|
+
return event_dict
|
|
88
|
+
|
|
89
|
+
import json
|
|
90
|
+
|
|
91
|
+
# Format only the specified fields
|
|
92
|
+
for key in fields_to_format:
|
|
93
|
+
if key in event_dict:
|
|
94
|
+
value = event_dict[key]
|
|
95
|
+
|
|
96
|
+
try:
|
|
97
|
+
# Try to parse as JSON if it's a string
|
|
98
|
+
if isinstance(value, str):
|
|
99
|
+
parsed = json.loads(value)
|
|
100
|
+
# If it's a dict or list, format it nicely
|
|
101
|
+
if isinstance(parsed, (dict, list)):
|
|
102
|
+
formatted = json.dumps(parsed, indent=2, ensure_ascii=False)
|
|
103
|
+
event_dict[key] = formatted
|
|
104
|
+
elif isinstance(value, (dict, list)):
|
|
105
|
+
# Format JSON with indentation for better readability
|
|
106
|
+
formatted = json.dumps(value, indent=2, ensure_ascii=False)
|
|
107
|
+
event_dict[key] = formatted
|
|
108
|
+
except (TypeError, ValueError, json.JSONDecodeError):
|
|
109
|
+
# If it's not JSON serializable or if it's not valid JSON,
|
|
110
|
+
# leave it as is
|
|
111
|
+
pass
|
|
112
|
+
|
|
113
|
+
# Remove the json_formatting key from the output
|
|
114
|
+
event_dict.pop("json_formatting", None)
|
|
115
|
+
|
|
116
|
+
return event_dict
|
|
117
|
+
|
|
118
|
+
def _get_terminal_width(self) -> int:
|
|
119
|
+
"""Get the width of the terminal."""
|
|
120
|
+
import shutil
|
|
121
|
+
|
|
122
|
+
try:
|
|
123
|
+
return shutil.get_terminal_size((80, 20)).columns
|
|
124
|
+
except Exception:
|
|
125
|
+
return 80
|
|
35
126
|
|
|
36
127
|
|
|
37
128
|
def configure_structlog(
|
|
@@ -52,7 +143,7 @@ def configure_structlog(
|
|
|
52
143
|
level=log_level,
|
|
53
144
|
)
|
|
54
145
|
|
|
55
|
-
shared_processors = [
|
|
146
|
+
shared_processors: List[structlog.typing.Processor] = [
|
|
56
147
|
# Processors that have nothing to do with output,
|
|
57
148
|
# e.g., add timestamps or log level names.
|
|
58
149
|
# If log level is too low, abort pipeline and throw away log entry.
|
|
@@ -94,7 +185,7 @@ def configure_structlog(
|
|
|
94
185
|
]
|
|
95
186
|
|
|
96
187
|
structlog.configure(
|
|
97
|
-
processors=processors,
|
|
188
|
+
processors=processors,
|
|
98
189
|
context_class=dict,
|
|
99
190
|
# `logger_factory` is used to create wrapped loggers that are used for
|
|
100
191
|
# OUTPUT. This one returns a `logging.Logger`. The final value (a JSON
|
rasa/utils/ml_utils.py
CHANGED
|
@@ -119,7 +119,7 @@ def response_for_template(
|
|
|
119
119
|
rsps = responses.get(template_name, [])
|
|
120
120
|
usuable_responses = [r for r in rsps if r.get(KEY_RESPONSES_TEXT)]
|
|
121
121
|
if usuable_responses:
|
|
122
|
-
selected_response = np.random.choice(usuable_responses)
|
|
122
|
+
selected_response = np.random.choice(usuable_responses)
|
|
123
123
|
return selected_response.get(KEY_RESPONSES_TEXT)
|
|
124
124
|
else:
|
|
125
125
|
structlogger.warning(
|