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
rasa/__main__.py
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import argparse
|
|
2
|
+
|
|
3
|
+
# Check TensorFlow availability without importing the module
|
|
4
|
+
import importlib.util
|
|
2
5
|
import os
|
|
3
6
|
import platform
|
|
4
7
|
import sys
|
|
@@ -10,7 +13,6 @@ from rasa_sdk import __version__ as rasa_sdk_version
|
|
|
10
13
|
import rasa.telemetry
|
|
11
14
|
import rasa.utils.io
|
|
12
15
|
import rasa.utils.licensing
|
|
13
|
-
import rasa.utils.tensorflow.environment as tf_env
|
|
14
16
|
from rasa import version
|
|
15
17
|
from rasa.cli import (
|
|
16
18
|
data,
|
|
@@ -40,6 +42,14 @@ from rasa.shared.exceptions import RasaException
|
|
|
40
42
|
from rasa.utils.common import configure_logging_and_warnings
|
|
41
43
|
from rasa.utils.log_utils import configure_structlog
|
|
42
44
|
|
|
45
|
+
TENSORFLOW_AVAILABLE = importlib.util.find_spec("tensorflow") is not None
|
|
46
|
+
|
|
47
|
+
# Only import TensorFlow modules if TensorFlow is available
|
|
48
|
+
if TENSORFLOW_AVAILABLE:
|
|
49
|
+
import rasa.utils.tensorflow.environment as tf_env
|
|
50
|
+
else:
|
|
51
|
+
tf_env = None # type: ignore[assignment]
|
|
52
|
+
|
|
43
53
|
structlogger = structlog.get_logger()
|
|
44
54
|
|
|
45
55
|
|
|
@@ -123,8 +133,10 @@ def main(raw_arguments: Optional[List[str]] = None) -> None:
|
|
|
123
133
|
rasa.utils.io.configure_colored_logging(log_level)
|
|
124
134
|
configure_structlog(log_level)
|
|
125
135
|
|
|
126
|
-
|
|
127
|
-
tf_env
|
|
136
|
+
# Only setup TensorFlow environment if TensorFlow is available
|
|
137
|
+
if TENSORFLOW_AVAILABLE and tf_env is not None:
|
|
138
|
+
tf_env.setup_tf_environment()
|
|
139
|
+
tf_env.check_deterministic_ops()
|
|
128
140
|
|
|
129
141
|
# insert current path in syspath so custom modules are found
|
|
130
142
|
sys.path.insert(1, os.getcwd())
|
rasa/agents/__init__.py
ADDED
|
File without changes
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
from typing import Any, ClassVar, Dict, List, Type
|
|
2
|
+
|
|
3
|
+
import structlog
|
|
4
|
+
|
|
5
|
+
from rasa.agents.core.agent_protocol import AgentProtocol
|
|
6
|
+
from rasa.agents.core.types import ProtocolType
|
|
7
|
+
from rasa.agents.protocol import A2AAgent, MCPOpenAgent, MCPTaskAgent
|
|
8
|
+
from rasa.core.available_agents import AgentConfig
|
|
9
|
+
from rasa.shared.utils.common import class_from_module_path
|
|
10
|
+
|
|
11
|
+
structlogger = structlog.get_logger()
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class AgentFactory:
|
|
15
|
+
"""Factory for creating agent instances based on the protocol type."""
|
|
16
|
+
|
|
17
|
+
_protocols: ClassVar[Dict[ProtocolType, Type[AgentProtocol]]] = {
|
|
18
|
+
ProtocolType.A2A: A2AAgent,
|
|
19
|
+
ProtocolType.MCP_OPEN: MCPOpenAgent,
|
|
20
|
+
ProtocolType.MCP_TASK: MCPTaskAgent,
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
@classmethod
|
|
24
|
+
def create_client(
|
|
25
|
+
cls, protocol_type: ProtocolType, config: AgentConfig
|
|
26
|
+
) -> AgentProtocol:
|
|
27
|
+
"""Create an agent instance based on the protocol type.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
protocol_type: The protocol type of the agent.
|
|
31
|
+
config: The configuration for the agent as an AgentConfig object.
|
|
32
|
+
|
|
33
|
+
Returns:
|
|
34
|
+
An instance of the agent.
|
|
35
|
+
"""
|
|
36
|
+
# If the agent is a custom agent, we need to create it from the module
|
|
37
|
+
if config.configuration and config.configuration.module:
|
|
38
|
+
agent_class: Type[AgentProtocol] = class_from_module_path(
|
|
39
|
+
config.configuration.module
|
|
40
|
+
)
|
|
41
|
+
if not cls._is_valid_custom_agent(agent_class, protocol_type):
|
|
42
|
+
raise ValueError(
|
|
43
|
+
f"Agent class `{agent_class}` does not subclass the "
|
|
44
|
+
f"{cls._get_agent_class_from_protocol(protocol_type).__name__} "
|
|
45
|
+
f"agent class."
|
|
46
|
+
)
|
|
47
|
+
structlogger.debug(
|
|
48
|
+
"agent_factory.create_client.custom_agent",
|
|
49
|
+
event_info=(
|
|
50
|
+
f"Initializing `{agent_class.__name__}` for agent "
|
|
51
|
+
f"`{config.agent.name}` with protocol `{protocol_type.value}`"
|
|
52
|
+
),
|
|
53
|
+
agent_name=config.agent.name,
|
|
54
|
+
protocol_type=protocol_type.value,
|
|
55
|
+
agent_class=agent_class.__name__,
|
|
56
|
+
)
|
|
57
|
+
return agent_class.from_config(config)
|
|
58
|
+
|
|
59
|
+
# If the agent is a built-in agent, we need to create it from the protocol class
|
|
60
|
+
protocol_class = cls._get_agent_class_from_protocol(protocol_type)
|
|
61
|
+
if protocol_class is None:
|
|
62
|
+
raise ValueError(
|
|
63
|
+
f"Unsupported protocol: {protocol_type}. "
|
|
64
|
+
f"Supported protocols: {cls.get_supported_protocols()}"
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
structlogger.debug(
|
|
68
|
+
"agent_factory.create_client",
|
|
69
|
+
event_info=(
|
|
70
|
+
f"Initializing `{protocol_class.__name__}` for agent "
|
|
71
|
+
f"`{config.agent.name}` with protocol `{protocol_type.value}`"
|
|
72
|
+
),
|
|
73
|
+
agent_name=config.agent.name,
|
|
74
|
+
protocol_type=protocol_type.value,
|
|
75
|
+
agent_class=protocol_class.__name__,
|
|
76
|
+
)
|
|
77
|
+
return protocol_class.from_config(config)
|
|
78
|
+
|
|
79
|
+
@classmethod
|
|
80
|
+
def register_protocol(
|
|
81
|
+
cls, protocol_type: ProtocolType, protocol_class: Type[AgentProtocol]
|
|
82
|
+
) -> None:
|
|
83
|
+
"""Register new protocol implementation.
|
|
84
|
+
|
|
85
|
+
Args:
|
|
86
|
+
protocol_type: The protocol type of the agent.
|
|
87
|
+
protocol_class: The class that implements the protocol.
|
|
88
|
+
"""
|
|
89
|
+
if cls.is_protocol_supported(protocol_type):
|
|
90
|
+
raise ValueError(f"Protocol {protocol_type.name} already registered.")
|
|
91
|
+
cls._protocols[protocol_type] = protocol_class
|
|
92
|
+
|
|
93
|
+
@classmethod
|
|
94
|
+
def get_supported_protocols(cls) -> List[ProtocolType]:
|
|
95
|
+
"""Get all supported protocol types."""
|
|
96
|
+
return list(cls._protocols.keys())
|
|
97
|
+
|
|
98
|
+
@classmethod
|
|
99
|
+
def _get_agent_class_from_protocol(
|
|
100
|
+
cls, protocol_type: ProtocolType
|
|
101
|
+
) -> Type[AgentProtocol]:
|
|
102
|
+
"""Get the class that implements the protocol."""
|
|
103
|
+
if not cls.is_protocol_supported(protocol_type):
|
|
104
|
+
raise ValueError(
|
|
105
|
+
f"Unsupported protocol: {protocol_type}. "
|
|
106
|
+
f"Supported protocols: {cls.get_supported_protocols()}"
|
|
107
|
+
)
|
|
108
|
+
return cls._protocols[protocol_type]
|
|
109
|
+
|
|
110
|
+
@classmethod
|
|
111
|
+
def is_protocol_supported(cls, protocol_type: ProtocolType) -> bool:
|
|
112
|
+
"""Check if the protocol is supported."""
|
|
113
|
+
return protocol_type in cls._protocols
|
|
114
|
+
|
|
115
|
+
@classmethod
|
|
116
|
+
def _is_valid_custom_agent(
|
|
117
|
+
cls, agent_class: Any, protocol_type: ProtocolType
|
|
118
|
+
) -> bool:
|
|
119
|
+
"""Check if the agent class is valid."""
|
|
120
|
+
return issubclass(
|
|
121
|
+
agent_class, cls._get_agent_class_from_protocol(protocol_type)
|
|
122
|
+
)
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
from typing import ClassVar, Dict
|
|
2
|
+
|
|
3
|
+
import structlog
|
|
4
|
+
|
|
5
|
+
from rasa.agents.agent_factory import AgentFactory
|
|
6
|
+
from rasa.agents.core.agent_protocol import AgentProtocol
|
|
7
|
+
from rasa.agents.core.types import AgentIdentifier, ProtocolType
|
|
8
|
+
from rasa.agents.schemas import AgentInput, AgentOutput
|
|
9
|
+
from rasa.core.available_agents import AgentConfig
|
|
10
|
+
from rasa.shared.agents.utils import make_agent_identifier
|
|
11
|
+
from rasa.shared.exceptions import AgentInitializationException
|
|
12
|
+
from rasa.utils.singleton import Singleton
|
|
13
|
+
|
|
14
|
+
structlogger = structlog.get_logger()
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class AgentManager(metaclass=Singleton):
|
|
18
|
+
"""High-level agent management with protocol abstraction"""
|
|
19
|
+
|
|
20
|
+
agents: ClassVar[Dict[AgentIdentifier, AgentProtocol]] = {}
|
|
21
|
+
|
|
22
|
+
def _add_agent(
|
|
23
|
+
self, agent_identifier: AgentIdentifier, agent: AgentProtocol
|
|
24
|
+
) -> None:
|
|
25
|
+
"""Add an agent to the manager.
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
agent_identifier: The identifier of the agent.
|
|
29
|
+
agent: The agent to add.
|
|
30
|
+
"""
|
|
31
|
+
if agent_identifier in self.agents:
|
|
32
|
+
raise ValueError(f"Agent {agent_identifier} already exists")
|
|
33
|
+
self.agents[agent_identifier] = agent
|
|
34
|
+
|
|
35
|
+
def _remove_agent(self, agent_identifier: AgentIdentifier) -> None:
|
|
36
|
+
"""Remove an agent from the manager.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
agent_identifier: The identifier of the agent.
|
|
40
|
+
|
|
41
|
+
Raises:
|
|
42
|
+
ValueError: If the agent is not connected.
|
|
43
|
+
"""
|
|
44
|
+
if agent_identifier not in self.agents:
|
|
45
|
+
raise ValueError(f"Agent {agent_identifier} is not available")
|
|
46
|
+
del self.agents[agent_identifier]
|
|
47
|
+
|
|
48
|
+
def get_agent(self, agent_name: str, protocol_type: ProtocolType) -> AgentProtocol:
|
|
49
|
+
"""Retrieve connected agent instance.
|
|
50
|
+
|
|
51
|
+
Args:
|
|
52
|
+
agent_name: The name of the agent.
|
|
53
|
+
protocol_type: The protocol type of the agent.
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
The agent.
|
|
57
|
+
|
|
58
|
+
Raises:
|
|
59
|
+
ValueError: If the agent is not connected.
|
|
60
|
+
"""
|
|
61
|
+
agent_identifier = make_agent_identifier(agent_name, protocol_type)
|
|
62
|
+
if agent_identifier not in self.agents:
|
|
63
|
+
raise ValueError(f"Agent {agent_identifier} is not available")
|
|
64
|
+
return self.agents[agent_identifier]
|
|
65
|
+
|
|
66
|
+
async def connect_agent(
|
|
67
|
+
self, agent_name: str, protocol_type: ProtocolType, config: AgentConfig
|
|
68
|
+
) -> None:
|
|
69
|
+
"""Connect to agent using specified protocol, load the default resources
|
|
70
|
+
and persist the agent to the manager in a ready-to-use state so that
|
|
71
|
+
it can be used immediately to send messages to the agent.
|
|
72
|
+
|
|
73
|
+
Args:
|
|
74
|
+
agent_name: The name of the agent.
|
|
75
|
+
protocol_type: The protocol type of the agent.
|
|
76
|
+
config: The configuration for the agent as an AgentConfig object.
|
|
77
|
+
|
|
78
|
+
Raises:
|
|
79
|
+
ConnectionError: If the agent connection fails.
|
|
80
|
+
"""
|
|
81
|
+
# Add the agent to the manager
|
|
82
|
+
agent_identifier = make_agent_identifier(agent_name, protocol_type)
|
|
83
|
+
if agent_identifier in self.agents:
|
|
84
|
+
structlogger.info(
|
|
85
|
+
"agent_manager.connect_agent.already_connected",
|
|
86
|
+
agent_id=str(agent_identifier),
|
|
87
|
+
agent_name=agent_name,
|
|
88
|
+
event_info=f"Agent {agent_identifier} already connected",
|
|
89
|
+
)
|
|
90
|
+
return
|
|
91
|
+
try:
|
|
92
|
+
# Create the agent client
|
|
93
|
+
client = AgentFactory.create_client(protocol_type, config)
|
|
94
|
+
|
|
95
|
+
# Connect the agent client
|
|
96
|
+
await client.connect()
|
|
97
|
+
|
|
98
|
+
self._add_agent(agent_identifier, client)
|
|
99
|
+
structlogger.info(
|
|
100
|
+
"agent_manager.connect_agent.success",
|
|
101
|
+
agent_id=str(agent_identifier),
|
|
102
|
+
agent_name=agent_name,
|
|
103
|
+
event_info=f"Connected to agent - `{agent_identifier}` successfully",
|
|
104
|
+
)
|
|
105
|
+
except Exception as e:
|
|
106
|
+
event_info = f"Failed to connect agent {agent_identifier}"
|
|
107
|
+
structlogger.error(
|
|
108
|
+
"agent_manager.connect_agent.failed_to_connect",
|
|
109
|
+
agent_id=str(agent_identifier),
|
|
110
|
+
event_info=event_info,
|
|
111
|
+
)
|
|
112
|
+
raise AgentInitializationException(e) from e
|
|
113
|
+
|
|
114
|
+
async def run_agent(
|
|
115
|
+
self, agent_name: str, protocol_type: ProtocolType, context: AgentInput
|
|
116
|
+
) -> AgentOutput:
|
|
117
|
+
"""Run an agent, send the input to the agent and return the agent response.
|
|
118
|
+
|
|
119
|
+
Args:
|
|
120
|
+
agent_name: The name of the agent.
|
|
121
|
+
protocol_type: The protocol type of the agent.
|
|
122
|
+
context: The input to the agent as an AgentInput object.
|
|
123
|
+
|
|
124
|
+
Returns:
|
|
125
|
+
The response from the agent.
|
|
126
|
+
"""
|
|
127
|
+
agent = self.get_agent(agent_name, protocol_type)
|
|
128
|
+
|
|
129
|
+
structlogger.debug(
|
|
130
|
+
"agent_manager.run_agent.input",
|
|
131
|
+
event_info="Processing agent input before sending...",
|
|
132
|
+
agent_name=agent_name,
|
|
133
|
+
protocol_type=protocol_type,
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
# Process input before sending
|
|
137
|
+
try:
|
|
138
|
+
processed_input = await agent.process_input(context)
|
|
139
|
+
except Exception as e:
|
|
140
|
+
structlogger.error(
|
|
141
|
+
"agent_manager.run_agent.process_input_failed",
|
|
142
|
+
agent_name=agent_name,
|
|
143
|
+
protocol_type=protocol_type,
|
|
144
|
+
event_info=(
|
|
145
|
+
f"Failed to process input for agent '{agent_name}'. "
|
|
146
|
+
"Please check your custom implementation."
|
|
147
|
+
),
|
|
148
|
+
error_message=str(e),
|
|
149
|
+
)
|
|
150
|
+
raise
|
|
151
|
+
|
|
152
|
+
# Send message to agent
|
|
153
|
+
output = await agent.run(processed_input)
|
|
154
|
+
|
|
155
|
+
structlogger.debug(
|
|
156
|
+
"agent_manager.run_agent.output",
|
|
157
|
+
event_info="Agent output received. Processing output...",
|
|
158
|
+
agent_name=agent_name,
|
|
159
|
+
protocol_type=protocol_type,
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
# Process output before returning
|
|
163
|
+
try:
|
|
164
|
+
processed_output = await agent.process_output(output)
|
|
165
|
+
except Exception as e:
|
|
166
|
+
structlogger.error(
|
|
167
|
+
"agent_manager.run_agent.process_output_failed",
|
|
168
|
+
agent_name=agent_name,
|
|
169
|
+
protocol_type=protocol_type,
|
|
170
|
+
event_info=(
|
|
171
|
+
f"Failed to process output for agent '{agent_name}'. "
|
|
172
|
+
"Please check your custom implementation."
|
|
173
|
+
),
|
|
174
|
+
error_message=str(e),
|
|
175
|
+
)
|
|
176
|
+
raise
|
|
177
|
+
|
|
178
|
+
return processed_output
|
|
179
|
+
|
|
180
|
+
async def disconnect_agent(
|
|
181
|
+
self, agent_name: str, protocol_type: ProtocolType
|
|
182
|
+
) -> None:
|
|
183
|
+
"""Disconnect agent and remove from agent manager.
|
|
184
|
+
|
|
185
|
+
Args:
|
|
186
|
+
agent_name: The name of the agent.
|
|
187
|
+
protocol_type: The protocol type of the agent.
|
|
188
|
+
|
|
189
|
+
Raises:
|
|
190
|
+
ValueError: If the agent is not available.
|
|
191
|
+
ConnectionError: If the agent disconnection fails.
|
|
192
|
+
"""
|
|
193
|
+
agent_identifier = make_agent_identifier(agent_name, protocol_type)
|
|
194
|
+
if agent_identifier not in self.agents:
|
|
195
|
+
raise ValueError(f"Agent {agent_identifier} is not available")
|
|
196
|
+
try:
|
|
197
|
+
await self.get_agent(agent_name, protocol_type).disconnect()
|
|
198
|
+
self._remove_agent(agent_identifier)
|
|
199
|
+
structlogger.info(
|
|
200
|
+
"agent_manager.disconnect_agent.success",
|
|
201
|
+
agent_id=str(agent_identifier),
|
|
202
|
+
event_info=f"Disconnected from agent - {agent_identifier} successfully",
|
|
203
|
+
)
|
|
204
|
+
except Exception as e:
|
|
205
|
+
event_info = f"Failed to disconnect agent {agent_identifier}"
|
|
206
|
+
structlogger.error(
|
|
207
|
+
"agent_manager.disconnect_agent.failed_to_disconnect",
|
|
208
|
+
agent_id=str(agent_identifier),
|
|
209
|
+
event_info=event_info,
|
|
210
|
+
)
|
|
211
|
+
raise ConnectionError(e)
|
rasa/agents/constants.py
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Agent configuration constants
|
|
2
|
+
AGENT_DEFAULT_MAX_RETRIES = 5
|
|
3
|
+
AGENT_DEFAULT_TIMEOUT_SECONDS = 30
|
|
4
|
+
MAX_AGENT_RETRY_DELAY_SECONDS = 5
|
|
5
|
+
|
|
6
|
+
# MCP Tool related constants (primary)
|
|
7
|
+
TOOL_TYPE_KEY = "type"
|
|
8
|
+
TOOL_NAME_KEY = "name"
|
|
9
|
+
TOOL_DESCRIPTION_KEY = "description"
|
|
10
|
+
TOOL_PARAMETERS_KEY = "parameters"
|
|
11
|
+
TOOL_STRICT_KEY = "strict"
|
|
12
|
+
TOOL_TYPE_FUNCTION_KEY = "function"
|
|
13
|
+
TOOL_EXECUTOR_KEY = "tool_executor"
|
|
14
|
+
|
|
15
|
+
# MCP Tool related constants (secondary)
|
|
16
|
+
TOOL_ADDITIONAL_PROPERTIES_KEY = "additionalProperties"
|
|
17
|
+
TOOL_PROPERTIES_KEY = "properties"
|
|
18
|
+
TOOL_REQUIRED_KEY = "required"
|
|
19
|
+
TOOL_PROPERTY_TYPE_KEY = "type"
|
|
20
|
+
|
|
21
|
+
# MCP Tool Anthropic format related constants
|
|
22
|
+
TOOL_INPUT_SCHEMA_KEY = "input_schema"
|
|
23
|
+
|
|
24
|
+
# MCP Message related constants
|
|
25
|
+
KEY_ROLE = "role"
|
|
26
|
+
KEY_CONTENT = "content"
|
|
27
|
+
|
|
28
|
+
# MCP Tool call related constants
|
|
29
|
+
KEY_TOOL_CALL_ID = "tool_call_id"
|
|
30
|
+
KEY_FUNCTION = "function"
|
|
31
|
+
KEY_NAME = "name"
|
|
32
|
+
KEY_ARGUMENTS = "arguments"
|
|
33
|
+
KEY_ID = "id"
|
|
34
|
+
KEY_TYPE = "type"
|
|
35
|
+
KEY_TOOL_CALLS = "tool_calls"
|
|
36
|
+
|
|
37
|
+
# Agent output metadata related constants
|
|
38
|
+
AGENT_METADATA_AGENT_RESPONSE_KEY = "agent_response"
|
|
39
|
+
AGENT_METADATA_STRUCTURED_RESULTS_KEY = "structured_results"
|
|
40
|
+
AGENT_METADATA_EXIT_IF_KEY = "exit_if"
|
|
41
|
+
# A2A-specific constants
|
|
42
|
+
A2A_AGENT_CONTEXT_ID_KEY = "context_id"
|
|
43
|
+
A2A_AGENT_TASK_ID_KEY = "task_id"
|
|
File without changes
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, Protocol, runtime_checkable
|
|
4
|
+
|
|
5
|
+
if TYPE_CHECKING:
|
|
6
|
+
from rasa.agents.core.types import ProtocolType
|
|
7
|
+
from rasa.agents.schemas.agent_input import AgentInput
|
|
8
|
+
from rasa.agents.schemas.agent_output import AgentOutput
|
|
9
|
+
from rasa.core.available_agents import AgentConfig
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@runtime_checkable
|
|
13
|
+
class AgentProtocol(Protocol):
|
|
14
|
+
"""
|
|
15
|
+
Python protocol for interfacing with agent clients that implement the
|
|
16
|
+
agent communication protocols like MCP, A2A, ACP, etc.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
@classmethod
|
|
20
|
+
def from_config(cls, config: AgentConfig) -> AgentProtocol:
|
|
21
|
+
"""Initialize the Agent with the given configuration.
|
|
22
|
+
|
|
23
|
+
This class method should be implemented to parse the given
|
|
24
|
+
configuration and create an instance of an agent.
|
|
25
|
+
|
|
26
|
+
Args:
|
|
27
|
+
config: The configuration for the agent as an AgentConfig object.
|
|
28
|
+
|
|
29
|
+
Returns:
|
|
30
|
+
An instance of the agent.
|
|
31
|
+
"""
|
|
32
|
+
...
|
|
33
|
+
|
|
34
|
+
@property
|
|
35
|
+
def protocol_type(self) -> "ProtocolType":
|
|
36
|
+
"""
|
|
37
|
+
Returns the protocol type of the agent.
|
|
38
|
+
|
|
39
|
+
This property should be implemented to return the protocol type of the agent.
|
|
40
|
+
This is used to determine the type of agent to create in the AgentFactory.
|
|
41
|
+
"""
|
|
42
|
+
...
|
|
43
|
+
|
|
44
|
+
async def connect(self) -> None:
|
|
45
|
+
"""
|
|
46
|
+
Establish connection to agent/server.
|
|
47
|
+
|
|
48
|
+
This method should be implemented to establish a connection to the agent/server
|
|
49
|
+
and load any necessary resources.
|
|
50
|
+
"""
|
|
51
|
+
...
|
|
52
|
+
|
|
53
|
+
async def disconnect(self) -> None:
|
|
54
|
+
"""
|
|
55
|
+
Close connection to agent/server.
|
|
56
|
+
|
|
57
|
+
This method should be implemented to close the connection to the agent/server
|
|
58
|
+
and release any necessary resources.
|
|
59
|
+
"""
|
|
60
|
+
...
|
|
61
|
+
|
|
62
|
+
async def process_input(self, input: "AgentInput") -> "AgentInput":
|
|
63
|
+
"""
|
|
64
|
+
Pre-process the input before sending it to the agent.
|
|
65
|
+
|
|
66
|
+
This method should be implemented to pre-process the input before sending it
|
|
67
|
+
to the agent. This can be used to add any necessary metadata or context to the
|
|
68
|
+
input, or to filter the input.
|
|
69
|
+
|
|
70
|
+
Args:
|
|
71
|
+
input: The input to the agent as an AgentInput object.
|
|
72
|
+
|
|
73
|
+
Returns:
|
|
74
|
+
The processed input to the agent as an AgentInput object.
|
|
75
|
+
"""
|
|
76
|
+
...
|
|
77
|
+
|
|
78
|
+
async def run(self, input: "AgentInput") -> "AgentOutput":
|
|
79
|
+
"""
|
|
80
|
+
Send a message to Agent/server and return response.
|
|
81
|
+
|
|
82
|
+
This method should be implemented to send a message to the agent/server and
|
|
83
|
+
return the response in an AgentOutput object.
|
|
84
|
+
|
|
85
|
+
Args:
|
|
86
|
+
input: The input to the agent as an AgentInput object.
|
|
87
|
+
|
|
88
|
+
Returns:
|
|
89
|
+
The output from the agent as an AgentOutput object.
|
|
90
|
+
"""
|
|
91
|
+
...
|
|
92
|
+
|
|
93
|
+
async def process_output(self, output: "AgentOutput") -> "AgentOutput":
|
|
94
|
+
"""
|
|
95
|
+
Post-process the output before returning it to Rasa.
|
|
96
|
+
|
|
97
|
+
This method should be implemented to post-process the output before returning
|
|
98
|
+
it to Rasa. This can be used to add any necessary metadata or context to the
|
|
99
|
+
output, or to filter the output.
|
|
100
|
+
|
|
101
|
+
Args:
|
|
102
|
+
output: The output from the agent as an AgentOutput object.
|
|
103
|
+
|
|
104
|
+
Returns:
|
|
105
|
+
The processed output from the agent as an AgentOutput object.
|
|
106
|
+
"""
|
|
107
|
+
...
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"""Fundamental types for the agent protocol."""
|
|
2
|
+
|
|
3
|
+
from enum import Enum
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ProtocolType(Enum):
|
|
7
|
+
"""An Enum class that represents the supported protocol types."""
|
|
8
|
+
|
|
9
|
+
MCP_OPEN = "mcp_open"
|
|
10
|
+
MCP_TASK = "mcp_task"
|
|
11
|
+
A2A = "a2a"
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class AgentIdentifier:
|
|
15
|
+
"""Represents a unique agent identifier combining agent_id and protocol_type."""
|
|
16
|
+
|
|
17
|
+
SEPARATOR = "::"
|
|
18
|
+
|
|
19
|
+
def __init__(self, agent_name: str, protocol_type: ProtocolType):
|
|
20
|
+
self.agent_name = agent_name
|
|
21
|
+
self.protocol_type = protocol_type
|
|
22
|
+
|
|
23
|
+
def __str__(self) -> str:
|
|
24
|
+
return f"{self.agent_name}{self.SEPARATOR}{self.protocol_type.value}"
|
|
25
|
+
|
|
26
|
+
def __repr__(self) -> str:
|
|
27
|
+
return (
|
|
28
|
+
f"AgentIdentifier(agent_name='{self.agent_name}', "
|
|
29
|
+
f"protocol_type='{self.protocol_type.value}')"
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
def __eq__(self, other: object) -> bool:
|
|
33
|
+
if isinstance(other, AgentIdentifier):
|
|
34
|
+
return (
|
|
35
|
+
self.agent_name == other.agent_name
|
|
36
|
+
and self.protocol_type == other.protocol_type
|
|
37
|
+
)
|
|
38
|
+
elif isinstance(other, str):
|
|
39
|
+
return str(self) == other
|
|
40
|
+
return False
|
|
41
|
+
|
|
42
|
+
def __hash__(self) -> int:
|
|
43
|
+
return hash((self.agent_name, self.protocol_type))
|
|
44
|
+
|
|
45
|
+
@classmethod
|
|
46
|
+
def from_string(cls, identifier: str) -> "AgentIdentifier":
|
|
47
|
+
"""Create an AgentIdentifier from a string representation."""
|
|
48
|
+
if cls.SEPARATOR not in identifier:
|
|
49
|
+
raise ValueError(f"Invalid agent identifier format: {identifier}")
|
|
50
|
+
|
|
51
|
+
parts = identifier.split(cls.SEPARATOR, 1)
|
|
52
|
+
if len(parts) != 2:
|
|
53
|
+
raise ValueError(f"Invalid agent identifier format: {identifier}")
|
|
54
|
+
|
|
55
|
+
agent_name, protocol_str = parts
|
|
56
|
+
try:
|
|
57
|
+
protocol_type = ProtocolType(protocol_str)
|
|
58
|
+
except ValueError:
|
|
59
|
+
raise ValueError(f"Invalid protocol type: {protocol_str}")
|
|
60
|
+
|
|
61
|
+
return cls(agent_name, protocol_type)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class AgentStatus(Enum):
|
|
65
|
+
"""A Enum class that represents the status of the agent."""
|
|
66
|
+
|
|
67
|
+
COMPLETED = "completed"
|
|
68
|
+
INPUT_REQUIRED = "input_required"
|
|
69
|
+
FATAL_ERROR = "fatal_error"
|
|
70
|
+
RECOVERABLE_ERROR = "recoverable_error"
|
|
71
|
+
|
|
72
|
+
def __str__(self) -> str:
|
|
73
|
+
return self.value
|
|
74
|
+
|
|
75
|
+
def __repr__(self) -> str:
|
|
76
|
+
return f"AgentStatus.{self.value}"
|
|
77
|
+
|
|
78
|
+
def __eq__(self, other: object) -> bool:
|
|
79
|
+
if isinstance(other, AgentStatus):
|
|
80
|
+
return self.value == other.value
|
|
81
|
+
return False
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from rasa.exceptions import RasaException, ValidationError
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class AgentNotFoundException(RasaException):
|
|
5
|
+
"""Raised when an agent is not found."""
|
|
6
|
+
|
|
7
|
+
def __init__(self, agent_name: str):
|
|
8
|
+
super().__init__(f"The agent {agent_name} is not defined.")
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class DuplicatedAgentNameException(ValidationError):
|
|
12
|
+
"""Raised when agent names are duplicated."""
|
|
13
|
+
|
|
14
|
+
def __init__(self, duplicated_names: list[str]) -> None:
|
|
15
|
+
"""Initialize the exception."""
|
|
16
|
+
event_info = f"Agent names are duplicated: {', '.join(duplicated_names)}"
|
|
17
|
+
|
|
18
|
+
super().__init__(
|
|
19
|
+
code="agent.duplicated_name",
|
|
20
|
+
event_info=event_info,
|
|
21
|
+
duplicated_names=duplicated_names,
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class AgentNameFlowConflictException(ValidationError):
|
|
26
|
+
"""Raised when agent names conflict with flow names."""
|
|
27
|
+
|
|
28
|
+
def __init__(self, conflicting_names: list[str]) -> None:
|
|
29
|
+
"""Initialize the exception."""
|
|
30
|
+
event_info = (
|
|
31
|
+
f"Agent names conflict with flow names: {', '.join(conflicting_names)}"
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
super().__init__(
|
|
35
|
+
code="agent.flow_name_conflict",
|
|
36
|
+
event_info=event_info,
|
|
37
|
+
conflicting_names=conflicting_names,
|
|
38
|
+
)
|
|
File without changes
|