rasa-pro 3.14.0.dev20250922__py3-none-any.whl → 3.14.0rc2__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/copilot/constants.py +4 -1
- rasa/builder/copilot/copilot.py +155 -79
- rasa/builder/copilot/models.py +304 -108
- rasa/builder/copilot/prompts/copilot_training_error_handler_prompt.jinja2 +53 -0
- 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/jobs.py +182 -12
- rasa/builder/llm_service.py +32 -5
- rasa/builder/models.py +13 -3
- rasa/builder/project_generator.py +6 -1
- rasa/builder/service.py +31 -15
- 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/finance/domain/general/help.yml +0 -0
- 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/brokers/kafka.py +5 -1
- 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/concurrent_lock_store.py +38 -21
- 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 +10 -0
- rasa/core/iam_credentials_providers/aws_iam_credentials_providers.py +69 -4
- rasa/core/iam_credentials_providers/credentials_provider_protocol.py +2 -1
- rasa/core/lock_store.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/redis_connection_factory.py +7 -2
- rasa/core/run.py +37 -8
- rasa/core/test.py +4 -0
- rasa/core/tracker_stores/redis_tracker_store.py +4 -0
- rasa/core/tracker_stores/sql_tracker_store.py +3 -1
- 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.0rc2.dist-info}/METADATA +47 -41
- {rasa_pro-3.14.0.dev20250922.dist-info → rasa_pro-3.14.0rc2.dist-info}/RECORD +299 -238
- 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.0rc2.dist-info}/NOTICE +0 -0
- {rasa_pro-3.14.0.dev20250922.dist-info → rasa_pro-3.14.0rc2.dist-info}/WHEEL +0 -0
- {rasa_pro-3.14.0.dev20250922.dist-info → rasa_pro-3.14.0rc2.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
from typing import Any, Callable, Dict, Optional
|
|
2
|
+
|
|
3
|
+
from mcp import Tool
|
|
4
|
+
from pydantic import BaseModel
|
|
5
|
+
|
|
6
|
+
from rasa.agents.constants import (
|
|
7
|
+
TOOL_ADDITIONAL_PROPERTIES_KEY,
|
|
8
|
+
TOOL_DESCRIPTION_KEY,
|
|
9
|
+
TOOL_EXECUTOR_KEY,
|
|
10
|
+
TOOL_INPUT_SCHEMA_KEY,
|
|
11
|
+
TOOL_NAME_KEY,
|
|
12
|
+
TOOL_PARAMETERS_KEY,
|
|
13
|
+
TOOL_PROPERTIES_KEY,
|
|
14
|
+
TOOL_PROPERTY_TYPE_KEY,
|
|
15
|
+
TOOL_REQUIRED_KEY,
|
|
16
|
+
TOOL_STRICT_KEY,
|
|
17
|
+
TOOL_TYPE_FUNCTION_KEY,
|
|
18
|
+
TOOL_TYPE_KEY,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class AgentToolSchema(BaseModel):
|
|
23
|
+
name: str
|
|
24
|
+
parameters: dict[str, Any]
|
|
25
|
+
strict: bool
|
|
26
|
+
description: Optional[str] = None
|
|
27
|
+
type: str = "function"
|
|
28
|
+
|
|
29
|
+
@classmethod
|
|
30
|
+
def from_mcp_tool(cls, tool: Tool) -> "AgentToolSchema":
|
|
31
|
+
"""Convert MCP Tool to AgentToolSchema."""
|
|
32
|
+
parameters = tool.inputSchema.copy() if tool.inputSchema else {}
|
|
33
|
+
|
|
34
|
+
if parameters:
|
|
35
|
+
cls._validate_and_fix_parameters(parameters)
|
|
36
|
+
|
|
37
|
+
return cls(
|
|
38
|
+
name=tool.name,
|
|
39
|
+
description=tool.description,
|
|
40
|
+
parameters=parameters,
|
|
41
|
+
strict=False,
|
|
42
|
+
type=TOOL_TYPE_FUNCTION_KEY,
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
@classmethod
|
|
46
|
+
def from_litellm_json_format(cls, tool: Dict[str, Any]) -> "AgentToolSchema":
|
|
47
|
+
"""Convert OpenAI dict format to AgentToolSchema."""
|
|
48
|
+
references = (
|
|
49
|
+
"Refer: \n"
|
|
50
|
+
"- LiteLLM JSON Format - https://docs.litellm.ai/docs/completion/function_call#full-code---parallel-function-calling-with-gpt-35-turbo-1106\n"
|
|
51
|
+
"- OpenAI Tool JSON Format - https://platform.openai.com/docs/guides/tools?tool-type=function-calling\n"
|
|
52
|
+
)
|
|
53
|
+
expected_structure = (
|
|
54
|
+
"{\n"
|
|
55
|
+
" 'type': 'function',\n"
|
|
56
|
+
" 'function': {\n"
|
|
57
|
+
" 'name': 'string',\n"
|
|
58
|
+
" 'description': 'string',\n"
|
|
59
|
+
" 'parameters': {\n"
|
|
60
|
+
" 'type': 'object',\n"
|
|
61
|
+
" 'properties': {'string': 'string'},\n"
|
|
62
|
+
" 'required': ['string']\n"
|
|
63
|
+
" }\n"
|
|
64
|
+
" }\n"
|
|
65
|
+
"}"
|
|
66
|
+
)
|
|
67
|
+
if (
|
|
68
|
+
TOOL_NAME_KEY in tool
|
|
69
|
+
and TOOL_DESCRIPTION_KEY in tool
|
|
70
|
+
and TOOL_INPUT_SCHEMA_KEY in tool
|
|
71
|
+
):
|
|
72
|
+
raise ValueError(
|
|
73
|
+
"Anthropic Tool format is not supported yet. Please use the LiteLLM "
|
|
74
|
+
"Tool format, which is based on OpenAI's format.\n"
|
|
75
|
+
"The expected structure is:\n"
|
|
76
|
+
f"{expected_structure}\n"
|
|
77
|
+
f"{references}"
|
|
78
|
+
)
|
|
79
|
+
if not (TOOL_TYPE_FUNCTION_KEY in tool and TOOL_TYPE_KEY in tool):
|
|
80
|
+
raise ValueError(
|
|
81
|
+
"Invalid tool format. Expected a dictionary with 'type' and "
|
|
82
|
+
"'function' keys. Expected LiteLLM Tool format that is based on OpenAI "
|
|
83
|
+
"format which has the following structure: \n"
|
|
84
|
+
f"{expected_structure}\n"
|
|
85
|
+
f"{references}"
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
function_data = tool[TOOL_TYPE_FUNCTION_KEY]
|
|
89
|
+
|
|
90
|
+
if not (
|
|
91
|
+
TOOL_NAME_KEY in function_data and TOOL_DESCRIPTION_KEY in function_data
|
|
92
|
+
):
|
|
93
|
+
raise ValueError(
|
|
94
|
+
"Invalid tool format. 'function' must contain 'name' and "
|
|
95
|
+
"'description' keys. Expected LiteLLM Tool format that is based on "
|
|
96
|
+
"OpenAI format which has the following structure: \n"
|
|
97
|
+
f"{expected_structure}\n"
|
|
98
|
+
f"{references}"
|
|
99
|
+
)
|
|
100
|
+
parameters = function_data.get(TOOL_PARAMETERS_KEY, {})
|
|
101
|
+
|
|
102
|
+
if parameters:
|
|
103
|
+
cls._validate_and_fix_parameters(parameters)
|
|
104
|
+
|
|
105
|
+
return cls(
|
|
106
|
+
name=function_data[TOOL_NAME_KEY],
|
|
107
|
+
description=function_data[TOOL_DESCRIPTION_KEY],
|
|
108
|
+
parameters=parameters,
|
|
109
|
+
strict=function_data.get(TOOL_STRICT_KEY, False),
|
|
110
|
+
type=tool[TOOL_TYPE_KEY],
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
@staticmethod
|
|
114
|
+
def _validate_and_fix_parameters(parameters: Dict[str, Any]) -> None:
|
|
115
|
+
"""Validate and fix parameters to ensure they meet OpenAI function calling
|
|
116
|
+
requirements."""
|
|
117
|
+
if not parameters:
|
|
118
|
+
return
|
|
119
|
+
|
|
120
|
+
# Ensure additionalProperties is set at the top level
|
|
121
|
+
if TOOL_ADDITIONAL_PROPERTIES_KEY not in parameters:
|
|
122
|
+
parameters[TOOL_ADDITIONAL_PROPERTIES_KEY] = False
|
|
123
|
+
|
|
124
|
+
# Ensure required is set at the top level
|
|
125
|
+
if TOOL_REQUIRED_KEY not in parameters:
|
|
126
|
+
parameters[TOOL_REQUIRED_KEY] = []
|
|
127
|
+
|
|
128
|
+
# Ensure all properties have types, required field and additionalProperties
|
|
129
|
+
if TOOL_PROPERTIES_KEY in parameters:
|
|
130
|
+
AgentToolSchema._ensure_property_types(parameters)
|
|
131
|
+
|
|
132
|
+
@staticmethod
|
|
133
|
+
def _ensure_property_types(parameters: Dict[str, Any]) -> None:
|
|
134
|
+
"""Ensure all properties in parameters have a type defined and
|
|
135
|
+
additionalProperties is set."""
|
|
136
|
+
properties = parameters[TOOL_PROPERTIES_KEY]
|
|
137
|
+
|
|
138
|
+
if not properties:
|
|
139
|
+
return
|
|
140
|
+
|
|
141
|
+
for _, prop_schema in properties.items():
|
|
142
|
+
if not isinstance(prop_schema, dict):
|
|
143
|
+
continue
|
|
144
|
+
|
|
145
|
+
# Ensure the property has a type
|
|
146
|
+
if TOOL_PROPERTY_TYPE_KEY not in prop_schema:
|
|
147
|
+
prop_schema[TOOL_PROPERTY_TYPE_KEY] = "string"
|
|
148
|
+
|
|
149
|
+
# If it's an object type, ensure additionalProperties and required
|
|
150
|
+
# fields are set
|
|
151
|
+
if prop_schema[TOOL_PROPERTY_TYPE_KEY] == "object":
|
|
152
|
+
if TOOL_ADDITIONAL_PROPERTIES_KEY not in prop_schema:
|
|
153
|
+
prop_schema[TOOL_ADDITIONAL_PROPERTIES_KEY] = False
|
|
154
|
+
|
|
155
|
+
# Ensure required key exists for object properties
|
|
156
|
+
if TOOL_REQUIRED_KEY not in prop_schema:
|
|
157
|
+
prop_schema[TOOL_REQUIRED_KEY] = []
|
|
158
|
+
|
|
159
|
+
def to_litellm_json_format(self) -> Dict[str, Any]:
|
|
160
|
+
"""Convert AgentToolSchema to OpenAI format."""
|
|
161
|
+
# Ensure the schema is valid before conversion
|
|
162
|
+
return {
|
|
163
|
+
TOOL_TYPE_KEY: TOOL_TYPE_FUNCTION_KEY,
|
|
164
|
+
TOOL_TYPE_FUNCTION_KEY: self.model_dump(exclude={TOOL_TYPE_KEY}),
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
class CustomToolSchema(BaseModel):
|
|
169
|
+
"""A class that represents the schema of a custom agent tool."""
|
|
170
|
+
|
|
171
|
+
tool_name: str
|
|
172
|
+
tool_definition: AgentToolSchema
|
|
173
|
+
tool_executor: Callable
|
|
174
|
+
|
|
175
|
+
@classmethod
|
|
176
|
+
def from_dict(cls, config: Dict[str, Any]) -> "CustomToolSchema":
|
|
177
|
+
"""Convert a custom tool config to CustomToolSchema."""
|
|
178
|
+
agent_tool_schema = AgentToolSchema.from_litellm_json_format(config)
|
|
179
|
+
if TOOL_EXECUTOR_KEY not in config:
|
|
180
|
+
raise ValueError("Custom tool executor is required.")
|
|
181
|
+
|
|
182
|
+
return cls(
|
|
183
|
+
tool_name=agent_tool_schema.name,
|
|
184
|
+
tool_definition=agent_tool_schema,
|
|
185
|
+
tool_executor=config[TOOL_EXECUTOR_KEY],
|
|
186
|
+
)
|
|
File without changes
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
You are a helpful assistant that should assist the user in the best possible way.
|
|
2
|
+
|
|
3
|
+
### Primary Task
|
|
4
|
+
{{ description }}
|
|
5
|
+
|
|
6
|
+
### Instructions
|
|
7
|
+
* Always make sure to output responses to the user in a clear, helpful format.
|
|
8
|
+
* Always avoid asking multiple questions at once. Ask questions sequentially one at a time and wait for the user's response before proceeding to next question.
|
|
9
|
+
* Always avoid making assumptions about what values to pass into tools. Ask for clarification if a user's request is ambiguous.
|
|
10
|
+
* Once your primary task, described above, is completed, you must call the `task_completed` tool to signal that you have finished assisting the user. Do not end the conversation or indicate completion without the `task_completed` tool call.
|
|
11
|
+
* Do NOT call the `task_completed` tool unless you're absolutely certain that your primary task (NOT the slot corrections, updates, etc), described above, is fully completed. Focus on the task given in the task description above.
|
|
12
|
+
* Strictly avoid making up information or ability to take some action which is not available in `tool` provided.
|
|
13
|
+
|
|
14
|
+
### Context
|
|
15
|
+
- Current date: {{ current_date }} (YYYY-MM-DD)
|
|
16
|
+
- Current time: {{ current_time }} (HH:MM:SS, 24-hour format)
|
|
17
|
+
- Current day: {{ current_day }} (Day of week)
|
|
18
|
+
|
|
19
|
+
### Conversation history
|
|
20
|
+
{{ conversation_history }}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
You are a helpful assistant that should assist the user in the best possible way.
|
|
2
|
+
|
|
3
|
+
### Description of your capabilities
|
|
4
|
+
{{ description }}
|
|
5
|
+
|
|
6
|
+
### Task
|
|
7
|
+
* Use the tools available to gather the required information to set the following slots: {{ slot_names }}.
|
|
8
|
+
* In order to set the slot values, use the `set_slot_<slot_name>` tool.
|
|
9
|
+
|
|
10
|
+
### Instructions
|
|
11
|
+
* Always make sure to output responses to the user in a clear, helpful format.
|
|
12
|
+
* Always avoid asking multiple questions at once. Ask questions sequentially one at a time and wait for the user's response before proceeding to next question.
|
|
13
|
+
* Always avoid making assumptions about what values to pass into tools. Ask for clarification if a user's request is ambiguous.
|
|
14
|
+
* Strictly avoid making up information or ability to take some action which is not available in `tool` provided.
|
|
15
|
+
|
|
16
|
+
### Context
|
|
17
|
+
- Current date: {{ current_date }} (YYYY-MM-DD)
|
|
18
|
+
- Current time: {{ current_time }} (HH:MM:SS, 24-hour format)
|
|
19
|
+
- Current day: {{ current_day }} (Day of week)
|
|
20
|
+
|
|
21
|
+
### Conversation history
|
|
22
|
+
{{ conversation_history }}
|
rasa/agents/utils.py
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
from typing import Dict, List, Optional
|
|
2
|
+
|
|
3
|
+
import structlog
|
|
4
|
+
|
|
5
|
+
from rasa.agents.agent_manager import AgentManager
|
|
6
|
+
from rasa.agents.exceptions import AgentNotFoundException
|
|
7
|
+
from rasa.agents.validation import validate_agent_names_not_conflicting_with_flows
|
|
8
|
+
from rasa.core.available_agents import (
|
|
9
|
+
AgentConfig,
|
|
10
|
+
AgentMCPServerConfig,
|
|
11
|
+
AvailableAgents,
|
|
12
|
+
)
|
|
13
|
+
from rasa.core.config.available_endpoints import AvailableEndpoints
|
|
14
|
+
from rasa.core.config.configuration import Configuration
|
|
15
|
+
from rasa.shared.agents.utils import get_protocol_type
|
|
16
|
+
from rasa.shared.core.events import AgentCompleted, AgentStarted
|
|
17
|
+
from rasa.shared.core.flows import FlowsList
|
|
18
|
+
from rasa.shared.core.flows.steps import CallFlowStep
|
|
19
|
+
from rasa.shared.core.trackers import DialogueStateTracker
|
|
20
|
+
|
|
21
|
+
structlogger = structlog.get_logger()
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def resolve_agent_config(
|
|
25
|
+
agent_config: AgentConfig,
|
|
26
|
+
available_endpoints: AvailableEndpoints,
|
|
27
|
+
) -> Optional[AgentConfig]:
|
|
28
|
+
if agent_config is None:
|
|
29
|
+
return None
|
|
30
|
+
|
|
31
|
+
connections = agent_config.connections
|
|
32
|
+
mcp_connections: List[AgentMCPServerConfig] = (
|
|
33
|
+
connections.mcp_servers
|
|
34
|
+
if connections and connections.mcp_servers is not None
|
|
35
|
+
else []
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
for mcp_server in mcp_connections:
|
|
39
|
+
for mcp_server_endpoint in available_endpoints.mcp_servers or []:
|
|
40
|
+
if mcp_server_endpoint.name == mcp_server.name:
|
|
41
|
+
mcp_server.url = mcp_server_endpoint.url
|
|
42
|
+
mcp_server.type = mcp_server_endpoint.type
|
|
43
|
+
mcp_server.additional_params = mcp_server_endpoint.additional_params
|
|
44
|
+
|
|
45
|
+
return agent_config
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
async def initialize_agents(
|
|
49
|
+
flows: FlowsList,
|
|
50
|
+
sub_agents: AvailableAgents,
|
|
51
|
+
) -> None:
|
|
52
|
+
"""Iterate over flows and create/connect the referenced agents."""
|
|
53
|
+
agent_manager: AgentManager = AgentManager()
|
|
54
|
+
endpoints = Configuration.get_instance().endpoints
|
|
55
|
+
|
|
56
|
+
agent_used = False
|
|
57
|
+
mcp_tool_used = False
|
|
58
|
+
|
|
59
|
+
# Validate agent names don't conflict with flow names
|
|
60
|
+
flow_names = {flow.id for flow in flows.underlying_flows}
|
|
61
|
+
validate_agent_names_not_conflicting_with_flows(sub_agents.agents, flow_names)
|
|
62
|
+
|
|
63
|
+
for flow in flows.underlying_flows:
|
|
64
|
+
for step in flow.steps:
|
|
65
|
+
if isinstance(step, CallFlowStep):
|
|
66
|
+
if flows.flow_by_id(step.call) is not None:
|
|
67
|
+
continue
|
|
68
|
+
|
|
69
|
+
if step.is_calling_mcp_tool():
|
|
70
|
+
# The call step is calling an MCP tool, so we don't need to
|
|
71
|
+
# initialize any agent.
|
|
72
|
+
mcp_tool_used = True
|
|
73
|
+
continue
|
|
74
|
+
|
|
75
|
+
if not step.is_calling_agent():
|
|
76
|
+
raise AgentNotFoundException(step.call)
|
|
77
|
+
|
|
78
|
+
agent_used = True
|
|
79
|
+
|
|
80
|
+
agent_name = step.call
|
|
81
|
+
agent_config = sub_agents.get_agent_config(agent_name)
|
|
82
|
+
resolved_agent_config = resolve_agent_config(agent_config, endpoints)
|
|
83
|
+
protocol_type = get_protocol_type(step, agent_config)
|
|
84
|
+
|
|
85
|
+
await agent_manager.connect_agent(
|
|
86
|
+
agent_name,
|
|
87
|
+
protocol_type,
|
|
88
|
+
resolved_agent_config,
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
_log_beta_feature_warning(mcp_tool_used, agent_used)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def _log_beta_feature_warning(mcp_tool_used: bool, agent_used: bool) -> None:
|
|
95
|
+
"""Log a warning if an agent or MCP tool is used in the flow(s)."""
|
|
96
|
+
if mcp_tool_used:
|
|
97
|
+
structlogger.info(
|
|
98
|
+
"rasa.agents.utils.initialize_agents",
|
|
99
|
+
event_info="Beta Feature",
|
|
100
|
+
message=(
|
|
101
|
+
"An MCP tool is being called in at least one of the flows. "
|
|
102
|
+
"This feature is currently under beta development. "
|
|
103
|
+
"It might undergo upgrades / breaking changes in future "
|
|
104
|
+
"releases to graduate it to GA."
|
|
105
|
+
),
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
if agent_used:
|
|
109
|
+
structlogger.info(
|
|
110
|
+
"rasa.agents.utils.initialize_agents",
|
|
111
|
+
event_info="Beta Feature",
|
|
112
|
+
message=(
|
|
113
|
+
"A sub-agent is being called from a flow. "
|
|
114
|
+
"This feature is currently under beta development. "
|
|
115
|
+
"It might undergo upgrades / breaking changes in future "
|
|
116
|
+
"releases to graduate it to GA."
|
|
117
|
+
),
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def is_agent_valid(agent_id: str) -> bool:
|
|
122
|
+
"""Check if an agent ID references a valid agent.
|
|
123
|
+
|
|
124
|
+
Args:
|
|
125
|
+
agent_id: The agent ID to validate.
|
|
126
|
+
|
|
127
|
+
Returns:
|
|
128
|
+
True if the agent exists, False otherwise.
|
|
129
|
+
"""
|
|
130
|
+
agent_config = AvailableAgents.get_agent_config(agent_id)
|
|
131
|
+
return agent_config is not None
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def is_agent_completed(tracker: DialogueStateTracker, agent_id: str) -> bool:
|
|
135
|
+
"""Check if an agent has been completed.
|
|
136
|
+
|
|
137
|
+
Args:
|
|
138
|
+
tracker: The dialogue state tracker.
|
|
139
|
+
agent_id: The agent ID to check.
|
|
140
|
+
|
|
141
|
+
Returns:
|
|
142
|
+
True if the agent has been completed, False otherwise.
|
|
143
|
+
"""
|
|
144
|
+
# Look for AgentCompleted events for this agent
|
|
145
|
+
for event in reversed(tracker.events):
|
|
146
|
+
if isinstance(event, AgentCompleted) and event.agent_id == agent_id:
|
|
147
|
+
return True
|
|
148
|
+
elif isinstance(event, AgentStarted) and event.agent_id == agent_id:
|
|
149
|
+
return False
|
|
150
|
+
return False
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def get_agent_info(agent_id: str) -> Optional[Dict[str, str]]:
|
|
154
|
+
"""Get basic agent information (name and description).
|
|
155
|
+
|
|
156
|
+
Args:
|
|
157
|
+
agent_id: The agent ID to get information for.
|
|
158
|
+
|
|
159
|
+
Returns:
|
|
160
|
+
Dictionary with agent name and description if found, None otherwise.
|
|
161
|
+
"""
|
|
162
|
+
agent_config = AvailableAgents.get_agent_config(agent_id)
|
|
163
|
+
if agent_config is None:
|
|
164
|
+
return None
|
|
165
|
+
|
|
166
|
+
return {
|
|
167
|
+
"name": agent_config.agent.name,
|
|
168
|
+
"description": agent_config.agent.description,
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
def get_completed_agents_info(tracker: DialogueStateTracker) -> List[Dict[str, str]]:
|
|
173
|
+
"""Get information for all completed agents.
|
|
174
|
+
|
|
175
|
+
Args:
|
|
176
|
+
tracker: The dialogue state tracker.
|
|
177
|
+
|
|
178
|
+
Returns:
|
|
179
|
+
List of dictionaries containing agent information for completed agents.
|
|
180
|
+
"""
|
|
181
|
+
completed_agents = []
|
|
182
|
+
for event in reversed(tracker.events):
|
|
183
|
+
if isinstance(event, AgentCompleted):
|
|
184
|
+
agent_info = get_agent_info(event.agent_id)
|
|
185
|
+
if agent_info:
|
|
186
|
+
completed_agents.append(agent_info)
|
|
187
|
+
return completed_agents
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
def get_active_agent_info(
|
|
191
|
+
tracker: DialogueStateTracker, flow_id: str
|
|
192
|
+
) -> Optional[Dict[str, str]]:
|
|
193
|
+
"""Get information for the active agent in a specific flow.
|
|
194
|
+
|
|
195
|
+
Args:
|
|
196
|
+
tracker: The dialogue state tracker.
|
|
197
|
+
flow_id: The flow ID to get the active agent for.
|
|
198
|
+
|
|
199
|
+
Returns:
|
|
200
|
+
Dictionary with agent name and description if an agent is active,
|
|
201
|
+
None otherwise.
|
|
202
|
+
"""
|
|
203
|
+
agent_frame = tracker.stack.find_active_agent_stack_frame_for_flow(flow_id)
|
|
204
|
+
if agent_frame:
|
|
205
|
+
return get_agent_info(agent_frame.agent_id)
|
|
206
|
+
return None
|