rasa-pro 3.14.0.dev5__py3-none-any.whl → 3.14.0.dev6__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/agents/agent_factory.py +122 -0
- rasa/agents/agent_manager.py +163 -0
- rasa/agents/constants.py +40 -0
- rasa/agents/core/agent_protocol.py +107 -0
- rasa/agents/core/types.py +70 -0
- rasa/agents/exceptions.py +8 -0
- rasa/agents/protocol/__init__.py +5 -0
- rasa/agents/protocol/a2a/a2a_agent.py +662 -0
- rasa/agents/protocol/mcp/mcp_base_agent.py +684 -0
- rasa/agents/protocol/mcp/mcp_open_agent.py +290 -0
- rasa/agents/protocol/mcp/mcp_task_agent.py +484 -0
- rasa/agents/schemas/__init__.py +12 -0
- rasa/agents/schemas/agent_input.py +38 -0
- rasa/agents/schemas/agent_output.py +26 -0
- rasa/agents/schemas/agent_tool_result.py +67 -0
- rasa/agents/schemas/agent_tool_schema.py +134 -0
- rasa/agents/templates/mcp_open_agent_prompt_template.jinja2 +15 -0
- rasa/agents/templates/mcp_task_agent_prompt_template.jinja2 +17 -0
- rasa/agents/utils.py +72 -0
- rasa/api.py +5 -0
- rasa/cli/arguments/default_arguments.py +12 -0
- rasa/cli/arguments/run.py +2 -0
- rasa/cli/dialogue_understanding_test.py +4 -0
- rasa/cli/e2e_test.py +4 -0
- rasa/cli/inspect.py +3 -0
- rasa/cli/llm_fine_tuning.py +5 -0
- rasa/cli/project_templates/tutorial/config.yml +1 -2
- rasa/cli/run.py +4 -0
- rasa/cli/scaffold.py +2 -46
- rasa/cli/shell.py +3 -0
- rasa/constants.py +6 -0
- rasa/core/actions/action.py +56 -10
- rasa/core/agent.py +19 -1
- rasa/core/available_agents.py +199 -0
- rasa/core/available_endpoints.py +30 -0
- rasa/core/channels/channel.py +3 -4
- rasa/core/channels/development_inspector.py +4 -4
- rasa/core/channels/hangouts.py +2 -2
- rasa/core/channels/inspector/dist/assets/{arc-18042c22.js → arc-63212852.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{blockDiagram-38ab4fdb-fdd6bcfa.js → blockDiagram-38ab4fdb-eecf6b13.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{c4Diagram-3d4e48cf-f5ae6786.js → c4Diagram-3d4e48cf-8f798a9a.js} +1 -1
- rasa/core/channels/inspector/dist/assets/channel-0cd70adf.js +1 -0
- rasa/core/channels/inspector/dist/assets/{classDiagram-70f12bd4-81efba3e.js → classDiagram-70f12bd4-df71a04c.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{classDiagram-v2-f2320105-3b6b6a92.js → classDiagram-v2-f2320105-9b275968.js} +1 -1
- rasa/core/channels/inspector/dist/assets/clone-a0f9c4ed.js +1 -0
- rasa/core/channels/inspector/dist/assets/{createText-2e5e7dd3-31422447.js → createText-2e5e7dd3-1c669cad.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{edges-e0da2a9e-518a90db.js → edges-e0da2a9e-b1553799.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{erDiagram-9861fffd-a6d3c25a.js → erDiagram-9861fffd-112388d6.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{flowDb-956e92f1-e048c2be.js → flowDb-956e92f1-fdebec47.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{flowDiagram-66a62f08-c7474c91.js → flowDiagram-66a62f08-6280ede1.js} +1 -1
- rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-de9cc4aa.js +1 -0
- rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-4a651766-cb4d8723.js → flowchart-elk-definition-4a651766-e1dc03e5.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{ganttDiagram-c361ad54-346636a2.js → ganttDiagram-c361ad54-83f68c51.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-72cf32ee-7c508874.js → gitGraphDiagram-72cf32ee-22f8666f.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{graph-14702d8a.js → graph-ca9e6217.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{index-3862675e-f18b534b.js → index-3862675e-c5ceb692.js} +1 -1
- rasa/core/channels/inspector/dist/assets/index-3e293924.js +1353 -0
- rasa/core/channels/inspector/dist/assets/{infoDiagram-f8f76790-64154b83.js → infoDiagram-f8f76790-faa9999b.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{journeyDiagram-49397b02-833a5f95.js → journeyDiagram-49397b02-c4dda8d9.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{layout-5a3b2123.js → layout-d4307784.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{line-2272a8c7.js → line-0567aaa7.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{linear-35bcf273.js → linear-c11b95cf.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{mindmap-definition-fc14e90a-92dcb0e9.js → mindmap-definition-fc14e90a-0c7d3ca9.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{pieDiagram-8a3498a8-94dbc900.js → pieDiagram-8a3498a8-34b433fa.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{quadrantDiagram-120e2f19-8b7a9c33.js → quadrantDiagram-120e2f19-4cab816e.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{requirementDiagram-deff3bca-6f7eab81.js → requirementDiagram-deff3bca-8c22fa9e.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{sankeyDiagram-04a897e0-f43e581d.js → sankeyDiagram-04a897e0-70ce9e8e.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{sequenceDiagram-704730f1-0bcbefc3.js → sequenceDiagram-704730f1-fbcd7fc9.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{stateDiagram-587899a1-b8a74083.js → stateDiagram-587899a1-45f05ea6.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-d93cdb3a-2070218f.js → stateDiagram-v2-d93cdb3a-beab1ea6.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-6aaf32cf-f1d54e34.js → styles-6aaf32cf-2f29dbd5.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-9a916d00-980de489.js → styles-9a916d00-951eac83.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-c10674c1-3c03abde.js → styles-c10674c1-897fbfdd.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{svgDrawCommon-08f97a94-46ba068f.js → svgDrawCommon-08f97a94-d667fac1.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{timeline-definition-85554ec2-901f5e3d.js → timeline-definition-85554ec2-e3205144.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{xychartDiagram-e933f94c-acbc628a.js → xychartDiagram-e933f94c-4abeb0e2.js} +1 -1
- rasa/core/channels/inspector/dist/index.html +2 -2
- rasa/core/channels/inspector/index.html +1 -1
- rasa/core/channels/inspector/src/App.tsx +11 -10
- rasa/core/channels/inspector/src/components/DialogueInformation.tsx +3 -12
- rasa/core/channels/inspector/src/components/DialogueStack.tsx +6 -4
- rasa/core/channels/inspector/src/helpers/formatters.ts +24 -3
- rasa/core/channels/inspector/src/theme/base/styles.ts +19 -1
- rasa/core/channels/inspector/src/types.ts +4 -0
- rasa/core/channels/socketio.py +51 -212
- rasa/core/channels/studio_chat.py +29 -49
- rasa/core/channels/voice_stream/genesys.py +1 -1
- rasa/core/channels/voice_stream/voice_channel.py +3 -5
- rasa/core/constants.py +4 -0
- rasa/core/policies/enterprise_search_policy.py +11 -6
- rasa/core/policies/flow_policy.py +4 -4
- rasa/core/policies/flows/flow_executor.py +470 -45
- rasa/core/policies/flows/mcp_tool_executor.py +277 -0
- rasa/core/policies/intentless_policy.py +1 -1
- rasa/core/policies/unexpected_intent_policy.py +1 -0
- rasa/core/processor.py +18 -15
- rasa/core/run.py +11 -14
- rasa/core/tracker_stores/tracker_store.py +3 -7
- rasa/core/train.py +1 -1
- rasa/core/training/interactive.py +16 -16
- rasa/core/training/story_conflict.py +5 -5
- rasa/core/utils.py +21 -1
- rasa/dialogue_understanding/commands/__init__.py +8 -0
- rasa/dialogue_understanding/commands/cancel_flow_command.py +97 -4
- rasa/dialogue_understanding/commands/chit_chat_answer_command.py +11 -0
- rasa/dialogue_understanding/commands/clarify_command.py +10 -0
- rasa/dialogue_understanding/commands/continue_agent_command.py +91 -0
- rasa/dialogue_understanding/commands/knowledge_answer_command.py +11 -0
- rasa/dialogue_understanding/commands/restart_agent_command.py +162 -0
- rasa/dialogue_understanding/commands/start_flow_command.py +164 -8
- rasa/dialogue_understanding/commands/utils.py +6 -2
- rasa/dialogue_understanding/generator/command_parser.py +4 -0
- rasa/dialogue_understanding/generator/flow_retrieval.py +9 -10
- 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 +61 -0
- rasa/{cli/project_templates/telco/prompts/command-generator.jinja2 → dialogue_understanding/generator/prompt_templates/agent_command_prompt_v2_gpt_4o_2024_11_20_template.jinja2} +7 -3
- rasa/dialogue_understanding/generator/prompt_templates/agent_command_prompt_v3_claude_3_5_sonnet_20240620_template.jinja2 +81 -0
- rasa/dialogue_understanding/generator/prompt_templates/agent_command_prompt_v3_gpt_4o_2024_11_20_template.jinja2 +81 -0
- rasa/dialogue_understanding/generator/single_step/compact_llm_command_generator.py +7 -6
- rasa/dialogue_understanding/generator/single_step/search_ready_llm_command_generator.py +7 -6
- rasa/dialogue_understanding/generator/single_step/single_step_based_llm_command_generator.py +41 -2
- rasa/dialogue_understanding/patterns/continue_interrupted.py +163 -1
- rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml +52 -8
- rasa/dialogue_understanding/processor/command_processor.py +31 -15
- rasa/dialogue_understanding/stack/dialogue_stack.py +123 -2
- rasa/dialogue_understanding/stack/frames/flow_stack_frame.py +57 -0
- rasa/dialogue_understanding/stack/utils.py +17 -2
- rasa/dialogue_understanding_test/du_test_runner.py +7 -2
- rasa/e2e_test/e2e_test_runner.py +12 -2
- rasa/engine/caching.py +2 -2
- rasa/engine/recipes/default_components.py +10 -18
- rasa/engine/storage/local_model_storage.py +2 -45
- rasa/graph_components/validators/default_recipe_validator.py +134 -134
- rasa/hooks.py +5 -5
- rasa/llm_fine_tuning/utils.py +2 -2
- rasa/model_manager/model_api.py +5 -4
- rasa/model_manager/runner_service.py +1 -1
- rasa/model_manager/socket_bridge.py +14 -20
- rasa/model_manager/trainer_service.py +9 -12
- rasa/model_manager/utils.py +29 -1
- rasa/model_manager/warm_rasa_process.py +1 -1
- rasa/nlu/extractors/extractor.py +2 -1
- rasa/plugin.py +8 -8
- rasa/privacy/privacy_manager.py +11 -2
- rasa/server.py +14 -2
- rasa/shared/agents/utils.py +35 -0
- rasa/shared/constants.py +5 -0
- rasa/shared/core/constants.py +12 -1
- rasa/shared/core/domain.py +11 -58
- rasa/shared/core/events.py +327 -0
- rasa/shared/core/flows/flow_step.py +1 -7
- rasa/shared/core/flows/flows_list.py +15 -5
- rasa/shared/core/flows/flows_yaml_schema.json +112 -186
- rasa/shared/core/flows/steps/call.py +53 -5
- rasa/shared/core/flows/validation.py +177 -7
- rasa/shared/core/flows/yaml_flows_io.py +9 -17
- rasa/shared/core/slots.py +2 -6
- rasa/shared/core/trackers.py +5 -2
- rasa/shared/exceptions.py +4 -0
- rasa/shared/importers/importer.py +0 -6
- rasa/shared/importers/rasa.py +1 -1
- rasa/shared/importers/utils.py +10 -80
- rasa/shared/providers/_utils.py +44 -60
- rasa/shared/providers/embedding/default_litellm_embedding_client.py +0 -2
- rasa/shared/providers/llm/_base_litellm_client.py +39 -7
- rasa/shared/providers/llm/default_litellm_llm_client.py +0 -2
- 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/llm.py +28 -5
- rasa/shared/utils/mcp/server_connection.py +166 -0
- rasa/shared/utils/schemas/events.py +42 -0
- rasa/shared/utils/yaml.py +3 -1
- rasa/studio/upload.py +47 -16
- rasa/telemetry.py +23 -97
- rasa/tracing/instrumentation/instrumentation.py +14 -10
- rasa/tracing/instrumentation/intentless_policy_instrumentation.py +4 -4
- rasa/utils/common.py +79 -0
- rasa/utils/io.py +9 -27
- rasa/utils/json_utils.py +1 -6
- rasa/utils/log_utils.py +2 -6
- rasa/utils/ml_utils.py +1 -1
- rasa/utils/tensorflow/rasa_layers.py +1 -1
- rasa/utils/train_utils.py +15 -15
- rasa/validator.py +19 -21
- rasa/version.py +1 -1
- {rasa_pro-3.14.0.dev5.dist-info → rasa_pro-3.14.0.dev6.dist-info}/METADATA +14 -17
- {rasa_pro-3.14.0.dev5.dist-info → rasa_pro-3.14.0.dev6.dist-info}/RECORD +201 -432
- rasa/builder/README.md +0 -120
- rasa/builder/auth.py +0 -176
- rasa/builder/config.py +0 -115
- rasa/builder/copilot/constants.py +0 -25
- rasa/builder/copilot/copilot.py +0 -372
- rasa/builder/copilot/copilot_response_handler.py +0 -487
- rasa/builder/copilot/copilot_templated_message_provider.py +0 -58
- rasa/builder/copilot/exceptions.py +0 -20
- rasa/builder/copilot/models.py +0 -431
- rasa/builder/copilot/prompts/copilot_system_prompt.jinja2 +0 -726
- rasa/builder/copilot/telemetry.py +0 -195
- rasa/builder/copilot/templated_messages/copilot_internal_messages_templates.yml +0 -16
- rasa/builder/copilot/templated_messages/copilot_templated_responses.yml +0 -26
- rasa/builder/document_retrieval/constants.py +0 -15
- rasa/builder/document_retrieval/inkeep-rag-response-schema.json +0 -64
- rasa/builder/document_retrieval/inkeep_document_retrieval.py +0 -238
- rasa/builder/document_retrieval/models.py +0 -62
- rasa/builder/download.py +0 -140
- rasa/builder/exceptions.py +0 -55
- rasa/builder/guardrails/__init__.py +0 -1
- rasa/builder/guardrails/constants.py +0 -3
- rasa/builder/guardrails/exceptions.py +0 -4
- rasa/builder/guardrails/lakera.py +0 -206
- rasa/builder/guardrails/models.py +0 -199
- rasa/builder/guardrails/utils.py +0 -305
- rasa/builder/job_manager.py +0 -87
- rasa/builder/jobs.py +0 -234
- rasa/builder/llm_service.py +0 -246
- rasa/builder/logging_utils.py +0 -209
- rasa/builder/main.py +0 -174
- rasa/builder/models.py +0 -197
- rasa/builder/project_generator.py +0 -450
- rasa/builder/project_info.py +0 -72
- rasa/builder/scrape_rasa_docs.py +0 -97
- rasa/builder/service.py +0 -1142
- rasa/builder/shared/tracker_context.py +0 -212
- rasa/builder/skill_to_bot_prompt.jinja2 +0 -164
- rasa/builder/training_service.py +0 -132
- rasa/builder/validation_service.py +0 -93
- rasa/cli/project_templates/basic/actions/action_api.py +0 -15
- rasa/cli/project_templates/basic/actions/action_human_handoff.py +0 -44
- rasa/cli/project_templates/basic/config.yml +0 -23
- rasa/cli/project_templates/basic/credentials.yml +0 -34
- rasa/cli/project_templates/basic/data/general/feedback.yml +0 -20
- rasa/cli/project_templates/basic/data/general/goodbye.yml +0 -6
- rasa/cli/project_templates/basic/data/general/hello.yml +0 -7
- rasa/cli/project_templates/basic/data/general/help.yml +0 -6
- rasa/cli/project_templates/basic/data/general/human_handoff.yml +0 -16
- rasa/cli/project_templates/basic/data/general/welcome.yml +0 -9
- rasa/cli/project_templates/basic/data/system/pattern_completed.yml +0 -7
- rasa/cli/project_templates/basic/data/system/pattern_correction.yml +0 -7
- rasa/cli/project_templates/basic/data/system/pattern_search.yml +0 -8
- rasa/cli/project_templates/basic/data/system/pattern_session_start.yml +0 -8
- rasa/cli/project_templates/basic/docs/rasa_assistant_qa.txt +0 -65
- rasa/cli/project_templates/basic/docs/template.txt +0 -7
- rasa/cli/project_templates/basic/domain/general/assistant_details.yml +0 -12
- rasa/cli/project_templates/basic/domain/general/bot_identity.yml +0 -5
- rasa/cli/project_templates/basic/domain/general/cannot_handle.yml +0 -5
- rasa/cli/project_templates/basic/domain/general/feedback.yml +0 -28
- rasa/cli/project_templates/basic/domain/general/goodbye.yml +0 -7
- rasa/cli/project_templates/basic/domain/general/help.yml +0 -5
- rasa/cli/project_templates/basic/domain/general/human_handoff_domain.yml +0 -35
- rasa/cli/project_templates/basic/domain/general/utils.yml +0 -13
- rasa/cli/project_templates/basic/domain/general/welcome.yml +0 -7
- rasa/cli/project_templates/basic/endpoints.yml +0 -73
- rasa/cli/project_templates/basic/prompts/rephraser_demo_personality_prompt.jinja2 +0 -19
- rasa/cli/project_templates/finance/actions/__init__.py +0 -46
- rasa/cli/project_templates/finance/actions/accounts/action_ask_account.py +0 -47
- rasa/cli/project_templates/finance/actions/accounts/action_check_balance.py +0 -40
- rasa/cli/project_templates/finance/actions/action_session_start.py +0 -74
- rasa/cli/project_templates/finance/actions/cards/action_ask_card.py +0 -48
- rasa/cli/project_templates/finance/actions/cards/action_check_card_existence.py +0 -36
- rasa/cli/project_templates/finance/actions/cards/action_update_card_status.py +0 -54
- rasa/cli/project_templates/finance/actions/database.py +0 -277
- rasa/cli/project_templates/finance/actions/transfers/__init__.py +0 -0
- rasa/cli/project_templates/finance/actions/transfers/action_add_payee.py +0 -52
- rasa/cli/project_templates/finance/actions/transfers/action_ask_account_from.py +0 -51
- rasa/cli/project_templates/finance/actions/transfers/action_check_payee_existence.py +0 -40
- rasa/cli/project_templates/finance/actions/transfers/action_check_sufficient_funds.py +0 -40
- rasa/cli/project_templates/finance/actions/transfers/action_list_payees.py +0 -46
- rasa/cli/project_templates/finance/actions/transfers/action_process_immediate_payment.py +0 -18
- rasa/cli/project_templates/finance/actions/transfers/action_remove_payee.py +0 -49
- rasa/cli/project_templates/finance/actions/transfers/action_schedule_payment.py +0 -19
- rasa/cli/project_templates/finance/actions/transfers/action_validate_payment_date.py +0 -36
- rasa/cli/project_templates/finance/config.yml +0 -21
- rasa/cli/project_templates/finance/credentials.yml +0 -32
- rasa/cli/project_templates/finance/csvs/accounts.csv +0 -8
- rasa/cli/project_templates/finance/csvs/advisors.csv +0 -7
- rasa/cli/project_templates/finance/csvs/appointments.csv +0 -211
- rasa/cli/project_templates/finance/csvs/branches.csv +0 -10
- rasa/cli/project_templates/finance/csvs/cards.csv +0 -11
- rasa/cli/project_templates/finance/csvs/payees.csv +0 -11
- rasa/cli/project_templates/finance/csvs/transactions.csv +0 -71
- rasa/cli/project_templates/finance/csvs/users.csv +0 -4
- rasa/cli/project_templates/finance/data/accounts/check_balance.yml +0 -10
- rasa/cli/project_templates/finance/data/cards/block_card.yml +0 -66
- rasa/cli/project_templates/finance/data/cards/select_card.yml +0 -12
- rasa/cli/project_templates/finance/data/general/bot_identity.yml +0 -6
- rasa/cli/project_templates/finance/data/general/feedback.yml +0 -20
- rasa/cli/project_templates/finance/data/general/goodbye.yml +0 -6
- rasa/cli/project_templates/finance/data/general/hello.yml +0 -7
- rasa/cli/project_templates/finance/data/general/help.yml +0 -9
- rasa/cli/project_templates/finance/data/general/human_handoff.yml +0 -16
- rasa/cli/project_templates/finance/data/general/welcome.yml +0 -9
- rasa/cli/project_templates/finance/data/system/patterns/pattern_chitchat.yml +0 -5
- rasa/cli/project_templates/finance/data/system/patterns/pattern_completed.yml +0 -7
- rasa/cli/project_templates/finance/data/system/patterns/pattern_correction.yml +0 -7
- rasa/cli/project_templates/finance/data/system/patterns/pattern_search.yml +0 -8
- rasa/cli/project_templates/finance/data/system/patterns/pattern_session_start.yml +0 -8
- rasa/cli/project_templates/finance/data/system/source/accounts.json +0 -51
- rasa/cli/project_templates/finance/data/system/source/advisors.json +0 -44
- rasa/cli/project_templates/finance/data/system/source/appointments.json +0 -1474
- rasa/cli/project_templates/finance/data/system/source/branches.json +0 -47
- rasa/cli/project_templates/finance/data/system/source/cards.json +0 -72
- rasa/cli/project_templates/finance/data/system/source/payees.json +0 -74
- rasa/cli/project_templates/finance/data/system/source/transactions.json +0 -492
- rasa/cli/project_templates/finance/data/system/source/users.json +0 -29
- rasa/cli/project_templates/finance/data/transfers/add_payee.yml +0 -29
- rasa/cli/project_templates/finance/data/transfers/list_payees.yml +0 -5
- rasa/cli/project_templates/finance/data/transfers/remove_payee.yml +0 -21
- rasa/cli/project_templates/finance/data/transfers/transfer_money.yml +0 -67
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/consequences_of_blocking_card.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/reasons_to_block_card.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/recovering_from_card_fraud.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/tips_for_card_security.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/what_to_do_if_card_is_lost.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/account_balance_security.txt +0 -7
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/common_balance_inquiries.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/methods_to_check_balance.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/understanding_balance_updates.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/what_to_do_if_balance_is_incorrect.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/benefits_of_authorised_payees.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/common_issues_with_payees.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/general_payee_information.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/payee_management_tips.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/understanding_payee_types.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/common_transfer_errors.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/fees_for_transfers.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/general_transfer_information.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/security_tips_for_transfers.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/transfer_processing_times.txt +0 -8
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part1.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part10.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part11.txt +0 -48
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part12.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part13.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part14.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part15.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part16.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part17.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part18.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part19.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part2.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part20.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part21.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part22.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part23.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part24.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part25.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part26.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part27.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part28.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part29.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part3.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part30.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part31.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part32.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part33.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part34.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part35.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part36.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part37.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part38.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part39.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part4.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part40.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part41.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part42.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part43.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part44.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part45.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part46.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part47.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part48.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part49.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part5.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part50.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part51.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part52.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part53.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part54.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part55.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part56.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part57.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part58.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part59.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part6.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part60.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part61.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part7.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part8.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part9.txt +0 -47
- rasa/cli/project_templates/finance/domain/accounts/check_balance.yml +0 -11
- rasa/cli/project_templates/finance/domain/cards/block_card.yml +0 -101
- rasa/cli/project_templates/finance/domain/cards/select_card.yml +0 -12
- rasa/cli/project_templates/finance/domain/general/assistant_details.yml +0 -12
- rasa/cli/project_templates/finance/domain/general/bot_identity.yml +0 -5
- rasa/cli/project_templates/finance/domain/general/cannot_handle.yml +0 -5
- rasa/cli/project_templates/finance/domain/general/defaults.yml +0 -24
- rasa/cli/project_templates/finance/domain/general/feedback.yml +0 -28
- rasa/cli/project_templates/finance/domain/general/goodbye.yml +0 -7
- rasa/cli/project_templates/finance/domain/general/help.yml +0 -5
- rasa/cli/project_templates/finance/domain/general/human_handoff.yml +0 -30
- rasa/cli/project_templates/finance/domain/general/utils.yml +0 -13
- rasa/cli/project_templates/finance/domain/general/welcome.yml +0 -8
- rasa/cli/project_templates/finance/domain/transfers/add_payee.yml +0 -47
- rasa/cli/project_templates/finance/domain/transfers/list_payees.yml +0 -4
- rasa/cli/project_templates/finance/domain/transfers/remove_payee.yml +0 -16
- rasa/cli/project_templates/finance/domain/transfers/transfer_money.yml +0 -79
- rasa/cli/project_templates/finance/endpoints.yml +0 -63
- rasa/cli/project_templates/finance/prompts/rephraser_demo_personality_prompt.jinja2 +0 -19
- rasa/cli/project_templates/telco/actions/__init__.py +0 -0
- rasa/cli/project_templates/telco/actions/actions_billing.py +0 -204
- rasa/cli/project_templates/telco/actions/actions_get_data_from_db.py +0 -48
- rasa/cli/project_templates/telco/actions/actions_run_diagnostics.py +0 -28
- rasa/cli/project_templates/telco/actions/actions_session_start.py +0 -18
- rasa/cli/project_templates/telco/config.yml +0 -25
- rasa/cli/project_templates/telco/credentials.yml +0 -33
- rasa/cli/project_templates/telco/csvs/billing.csv +0 -10
- rasa/cli/project_templates/telco/csvs/customers.csv +0 -5
- rasa/cli/project_templates/telco/data/flows/flow_global.yml +0 -5
- rasa/cli/project_templates/telco/data/flows/flow_reboot_router.yml +0 -8
- rasa/cli/project_templates/telco/data/flows/flow_reset_router.yml +0 -7
- rasa/cli/project_templates/telco/data/flows/flow_solve_internet_issue.yml +0 -73
- rasa/cli/project_templates/telco/data/flows/flow_undertand_bill.yml +0 -45
- rasa/cli/project_templates/telco/data/patterns/pattern_completed.yml +0 -7
- rasa/cli/project_templates/telco/data/patterns/pattern_human_handoff.yml +0 -6
- rasa/cli/project_templates/telco/data/patterns/pattern_search.yml +0 -7
- rasa/cli/project_templates/telco/data/patterns/pattern_session_start.yml +0 -9
- rasa/cli/project_templates/telco/docs/reset_vs_rboot_router.txt +0 -1
- rasa/cli/project_templates/telco/docs/restart_router.txt +0 -6
- rasa/cli/project_templates/telco/docs/run_speed_test.txt +0 -6
- rasa/cli/project_templates/telco/domain/domain_global.yml +0 -29
- rasa/cli/project_templates/telco/domain/domain_patterns.yml +0 -17
- rasa/cli/project_templates/telco/domain/domain_reboot_router.yml +0 -20
- rasa/cli/project_templates/telco/domain/domain_reset_router.yml +0 -11
- rasa/cli/project_templates/telco/domain/domain_run_speed_test.yml +0 -24
- rasa/cli/project_templates/telco/domain/domain_solve_internet_issue.yml +0 -74
- rasa/cli/project_templates/telco/domain/domain_undertand_bill.yml +0 -102
- rasa/cli/project_templates/telco/endpoints.yml +0 -60
- rasa/cli/project_templates/telco/tests/e2e_results_failed.yml +0 -62
- rasa/cli/project_templates/telco/tests/e2e_results_passed.yml +0 -130
- rasa/cli/project_templates/telco/tests/e2e_test_cases/billing_test_cases.yml +0 -68
- rasa/cli/project_templates/telco/tests/e2e_test_cases/global_test_cases.yml +0 -13
- rasa/cli/project_templates/telco/tests/e2e_test_cases/internet_slow_test_case.yml +0 -47
- rasa/cli/project_templates/telco/tests/e2e_test_cases/out_of_scope_test_case.yml +0 -21
- rasa/cli/project_templates/telco/tests/e2e_test_cases/patterns_test_cases.yml +0 -15
- rasa/core/channels/constants.py +0 -3
- rasa/core/channels/inspector/dist/assets/channel-b9b536fc.js +0 -1
- rasa/core/channels/inspector/dist/assets/clone-78d2ddcf.js +0 -1
- rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-8b09c060.js +0 -1
- rasa/core/channels/inspector/dist/assets/index-4d4bdf3a.js +0 -1335
- rasa/utils/openapi.py +0 -144
- /rasa/{builder → agents}/__init__.py +0 -0
- /rasa/{builder/copilot → agents/core}/__init__.py +0 -0
- /rasa/{builder/copilot/prompts → agents/protocol/a2a}/__init__.py +0 -0
- /rasa/{builder/copilot/templated_messages → agents/protocol/mcp}/__init__.py +0 -0
- /rasa/{builder/document_retrieval → agents/templates}/__init__.py +0 -0
- /rasa/{cli/project_templates/finance/actions/accounts → shared/agents}/__init__.py +0 -0
- /rasa/{cli/project_templates/finance/actions/cards → shared/utils/mcp}/__init__.py +0 -0
- {rasa_pro-3.14.0.dev5.dist-info → rasa_pro-3.14.0.dev6.dist-info}/NOTICE +0 -0
- {rasa_pro-3.14.0.dev5.dist-info → rasa_pro-3.14.0.dev6.dist-info}/WHEEL +0 -0
- {rasa_pro-3.14.0.dev5.dist-info → rasa_pro-3.14.0.dev6.dist-info}/entry_points.txt +0 -0
rasa/builder/service.py
DELETED
|
@@ -1,1142 +0,0 @@
|
|
|
1
|
-
# mypy: disable-error-code=misc
|
|
2
|
-
import asyncio
|
|
3
|
-
import sys
|
|
4
|
-
import time
|
|
5
|
-
from http import HTTPStatus
|
|
6
|
-
from typing import Any, Optional
|
|
7
|
-
|
|
8
|
-
import structlog
|
|
9
|
-
from sanic import Blueprint, HTTPResponse, response
|
|
10
|
-
from sanic.request import Request
|
|
11
|
-
from sanic_openapi import openapi
|
|
12
|
-
|
|
13
|
-
from rasa.builder.auth import HEADER_USER_ID, is_auth_required_now, protected
|
|
14
|
-
from rasa.builder.config import (
|
|
15
|
-
COPILOT_ASSISTANT_TRACKER_MAX_TURNS,
|
|
16
|
-
COPILOT_HANDLER_ROLLING_BUFFER_SIZE,
|
|
17
|
-
HELLO_RASA_PROJECT_ID,
|
|
18
|
-
)
|
|
19
|
-
from rasa.builder.copilot.constants import ROLE_USER
|
|
20
|
-
from rasa.builder.copilot.exceptions import CopilotStreamError
|
|
21
|
-
from rasa.builder.copilot.models import (
|
|
22
|
-
CopilotContext,
|
|
23
|
-
CopilotRequest,
|
|
24
|
-
GeneratedContent,
|
|
25
|
-
ReferenceEntry,
|
|
26
|
-
ReferenceSection,
|
|
27
|
-
ResponseCategory,
|
|
28
|
-
ResponseCompleteness,
|
|
29
|
-
)
|
|
30
|
-
from rasa.builder.copilot.telemetry import CopilotTelemetry
|
|
31
|
-
from rasa.builder.download import create_bot_project_archive
|
|
32
|
-
from rasa.builder.guardrails.utils import (
|
|
33
|
-
check_assistant_chat_for_policy_violations,
|
|
34
|
-
check_copilot_chat_for_policy_violations,
|
|
35
|
-
)
|
|
36
|
-
from rasa.builder.job_manager import job_manager
|
|
37
|
-
from rasa.builder.jobs import (
|
|
38
|
-
run_prompt_to_bot_job,
|
|
39
|
-
run_template_to_bot_job,
|
|
40
|
-
run_update_files_job,
|
|
41
|
-
)
|
|
42
|
-
from rasa.builder.llm_service import llm_service
|
|
43
|
-
from rasa.builder.logging_utils import (
|
|
44
|
-
capture_exception_with_context,
|
|
45
|
-
get_recent_logs,
|
|
46
|
-
)
|
|
47
|
-
from rasa.builder.models import (
|
|
48
|
-
ApiErrorResponse,
|
|
49
|
-
AssistantInfo,
|
|
50
|
-
BotData,
|
|
51
|
-
JobCreateResponse,
|
|
52
|
-
JobStatus,
|
|
53
|
-
JobStatusEvent,
|
|
54
|
-
PromptRequest,
|
|
55
|
-
ServerSentEvent,
|
|
56
|
-
TemplateRequest,
|
|
57
|
-
)
|
|
58
|
-
from rasa.builder.project_generator import ProjectGenerator
|
|
59
|
-
from rasa.builder.shared.tracker_context import TrackerContext
|
|
60
|
-
from rasa.core.agent import Agent
|
|
61
|
-
from rasa.core.channels.studio_chat import StudioChatInput
|
|
62
|
-
from rasa.core.exceptions import AgentNotReady
|
|
63
|
-
from rasa.shared.core.flows.flows_list import FlowsList
|
|
64
|
-
from rasa.shared.core.flows.yaml_flows_io import get_flows_as_json
|
|
65
|
-
from rasa.shared.core.trackers import DialogueStateTracker
|
|
66
|
-
from rasa.shared.importers.utils import DOMAIN_KEYS
|
|
67
|
-
from rasa.utils.json_utils import extract_values
|
|
68
|
-
from rasa.utils.openapi import model_to_schema
|
|
69
|
-
|
|
70
|
-
structlogger = structlog.get_logger()
|
|
71
|
-
|
|
72
|
-
# Create the blueprint
|
|
73
|
-
bp = Blueprint("bot_builder", url_prefix="/api")
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
def setup_project_generator(project_folder: Optional[str] = None) -> ProjectGenerator:
|
|
77
|
-
"""Initialize and return a ProjectGenerator instance."""
|
|
78
|
-
if project_folder is None:
|
|
79
|
-
import tempfile
|
|
80
|
-
|
|
81
|
-
project_folder = tempfile.mkdtemp(prefix="rasa_builder_")
|
|
82
|
-
|
|
83
|
-
# Ensure the project folder is in sys.path
|
|
84
|
-
if project_folder not in sys.path:
|
|
85
|
-
sys.path.insert(0, project_folder)
|
|
86
|
-
|
|
87
|
-
structlogger.info(
|
|
88
|
-
"bot_builder_service.service_initialized", project_folder=project_folder
|
|
89
|
-
)
|
|
90
|
-
|
|
91
|
-
return ProjectGenerator(project_folder)
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
def get_project_generator(request: Request) -> ProjectGenerator:
|
|
95
|
-
"""Get the project generator from app context."""
|
|
96
|
-
return request.app.ctx.project_generator
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
def get_input_channel(request: Request) -> StudioChatInput:
|
|
100
|
-
"""Get the input channel from app context."""
|
|
101
|
-
return request.app.ctx.input_channel
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
async def extract_bot_data_from_agent(agent: Agent) -> BotData:
|
|
105
|
-
"""Extract BotData from an Agent.
|
|
106
|
-
|
|
107
|
-
Args:
|
|
108
|
-
agent: The agent to extract data from
|
|
109
|
-
|
|
110
|
-
Returns:
|
|
111
|
-
BotData containing flows, domain, config, endpoints, and nlu data
|
|
112
|
-
"""
|
|
113
|
-
domain = agent.domain.as_dict() if agent.domain else {}
|
|
114
|
-
flows = (
|
|
115
|
-
await agent.processor.get_flows()
|
|
116
|
-
if agent.processor
|
|
117
|
-
else FlowsList(underlying_flows=[])
|
|
118
|
-
)
|
|
119
|
-
return BotData(
|
|
120
|
-
flows=get_flows_as_json(flows),
|
|
121
|
-
domain=extract_values(domain, DOMAIN_KEYS),
|
|
122
|
-
)
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
# Health check endpoint
|
|
126
|
-
@bp.route("/", methods=["GET"])
|
|
127
|
-
@openapi.summary("Health check endpoint")
|
|
128
|
-
@openapi.description("Returns the health status of the Bot Builder service")
|
|
129
|
-
@openapi.tag("health")
|
|
130
|
-
@openapi.response(200, {"application/json": {"status": str, "service": str}})
|
|
131
|
-
async def health(request: Request) -> HTTPResponse:
|
|
132
|
-
"""Health check endpoint."""
|
|
133
|
-
project_generator = get_project_generator(request)
|
|
134
|
-
return response.json(
|
|
135
|
-
{
|
|
136
|
-
"status": "ok",
|
|
137
|
-
"service": "bot-builder",
|
|
138
|
-
"auth_required": is_auth_required_now(
|
|
139
|
-
project_info=project_generator.project_info
|
|
140
|
-
),
|
|
141
|
-
}
|
|
142
|
-
)
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
@bp.route("/job-events/<job_id>", methods=["GET"])
|
|
146
|
-
@openapi.summary("Stream job progress events")
|
|
147
|
-
@openapi.description(
|
|
148
|
-
"Stream server-sent events (SSE) tracking real-time job progress.\n\n"
|
|
149
|
-
"**Connect with:** `Accept: text/event-stream`.\n\n"
|
|
150
|
-
"**SSE Event Example:**\n"
|
|
151
|
-
"```text\n"
|
|
152
|
-
"event: received\n"
|
|
153
|
-
'data: {"status": "received"}\n'
|
|
154
|
-
"```\n\n"
|
|
155
|
-
)
|
|
156
|
-
@openapi.tag("job-events")
|
|
157
|
-
@openapi.parameter(
|
|
158
|
-
"job_id", str, location="path", description="The id of the job to stream events for"
|
|
159
|
-
)
|
|
160
|
-
@openapi.response(
|
|
161
|
-
200,
|
|
162
|
-
{"text/event-stream": str},
|
|
163
|
-
description="Server-sent events stream. See documentation for event types.",
|
|
164
|
-
example=(
|
|
165
|
-
"event: received\n"
|
|
166
|
-
'data: {"status": "received"}\n'
|
|
167
|
-
"\n"
|
|
168
|
-
"event: generating\n"
|
|
169
|
-
'data: {"status": "generating"}\n'
|
|
170
|
-
),
|
|
171
|
-
)
|
|
172
|
-
@openapi.response(
|
|
173
|
-
404,
|
|
174
|
-
{"application/json": model_to_schema(ApiErrorResponse)},
|
|
175
|
-
description="Unknown job_id: No such job exists.",
|
|
176
|
-
)
|
|
177
|
-
@openapi.parameter(
|
|
178
|
-
HEADER_USER_ID,
|
|
179
|
-
description=(
|
|
180
|
-
"Optional user id to associate requests (e.g., for telemetry/guardrails)."
|
|
181
|
-
),
|
|
182
|
-
_in="header",
|
|
183
|
-
required=False,
|
|
184
|
-
schema=str,
|
|
185
|
-
)
|
|
186
|
-
async def job_events(request: Request, job_id: str) -> HTTPResponse:
|
|
187
|
-
try:
|
|
188
|
-
job = job_manager.get_job(job_id)
|
|
189
|
-
if job is None:
|
|
190
|
-
return response.json(
|
|
191
|
-
ApiErrorResponse(
|
|
192
|
-
error="Job not found", details={"job_id": job_id}
|
|
193
|
-
).model_dump(),
|
|
194
|
-
status=404,
|
|
195
|
-
)
|
|
196
|
-
|
|
197
|
-
stream = await request.respond(content_type="text/event-stream")
|
|
198
|
-
|
|
199
|
-
try:
|
|
200
|
-
async for evt in job.event_stream():
|
|
201
|
-
await stream.send(evt.format())
|
|
202
|
-
except Exception as exc:
|
|
203
|
-
# Handle exceptions within the SSE stream context
|
|
204
|
-
capture_exception_with_context(
|
|
205
|
-
exc,
|
|
206
|
-
"bot_builder_service.job_events.streaming_error",
|
|
207
|
-
extra={"job_id": job_id},
|
|
208
|
-
tags={"endpoint": "/api/job-events/<job_id>"},
|
|
209
|
-
)
|
|
210
|
-
# Send error event in SSE format instead of JSON response
|
|
211
|
-
error_event = JobStatusEvent.from_status(
|
|
212
|
-
status=JobStatus.error.value,
|
|
213
|
-
message=f"Failed to stream job events: {exc}",
|
|
214
|
-
).format()
|
|
215
|
-
await stream.send(error_event)
|
|
216
|
-
finally:
|
|
217
|
-
await stream.eof()
|
|
218
|
-
|
|
219
|
-
return stream
|
|
220
|
-
except Exception as exc:
|
|
221
|
-
# This exception handler only applies before stream.respond() is called
|
|
222
|
-
capture_exception_with_context(
|
|
223
|
-
exc,
|
|
224
|
-
"bot_builder_service.job_events.unexpected_error",
|
|
225
|
-
extra={"job_id": job_id},
|
|
226
|
-
tags={"endpoint": "/api/job-events/<job_id>"},
|
|
227
|
-
)
|
|
228
|
-
return response.json(
|
|
229
|
-
ApiErrorResponse(
|
|
230
|
-
error="Failed to stream job events", details={"error": str(exc)}
|
|
231
|
-
).model_dump(),
|
|
232
|
-
status=HTTPStatus.INTERNAL_SERVER_ERROR,
|
|
233
|
-
)
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
@bp.route("/prompt-to-bot", methods=["POST"])
|
|
237
|
-
@openapi.summary("Generate bot from natural language prompt")
|
|
238
|
-
@openapi.description(
|
|
239
|
-
"Creates a complete conversational AI bot from a natural language prompt. "
|
|
240
|
-
"Returns immediately with a job ID. Connect to `/job-events/<job_id>` to "
|
|
241
|
-
"receive server-sent events (SSE) for real-time progress tracking "
|
|
242
|
-
"throughout the bot creation process.\n\n"
|
|
243
|
-
"**SSE Event Flow** (via `/job-events/<job_id>`):\n"
|
|
244
|
-
"1. `received` - Request received by server\n"
|
|
245
|
-
"2. `generating` - Generating bot project files\n"
|
|
246
|
-
"3. `generation_success` - Bot generation completed successfully\n"
|
|
247
|
-
"4. `training` - Training the bot model\n"
|
|
248
|
-
"5. `train_success` - Model training completed\n"
|
|
249
|
-
"6. `done` - Bot creation completed\n\n"
|
|
250
|
-
"**Error Events:**\n"
|
|
251
|
-
"- `generation_error` - Failed to generate bot from prompt\n"
|
|
252
|
-
"- `train_error` - Bot generated but training failed\n"
|
|
253
|
-
"- `validation_error` - Generated bot configuration is invalid\n"
|
|
254
|
-
"- `error` - Unexpected error occurred\n\n"
|
|
255
|
-
"**Usage:**\n"
|
|
256
|
-
"1. Send POST request with Content-Type: application/json\n"
|
|
257
|
-
"2. The response will be a JSON object `{job_id: ...}`\n"
|
|
258
|
-
"3. Connect to `/job-events/<job_id>` for a server-sent event stream of progress."
|
|
259
|
-
)
|
|
260
|
-
@openapi.tag("bot-generation")
|
|
261
|
-
@openapi.body(
|
|
262
|
-
{"application/json": model_to_schema(PromptRequest)},
|
|
263
|
-
description="Prompt request with natural language description.",
|
|
264
|
-
required=True,
|
|
265
|
-
)
|
|
266
|
-
@openapi.response(
|
|
267
|
-
200,
|
|
268
|
-
{"application/json": model_to_schema(JobCreateResponse)},
|
|
269
|
-
description="Job created. Poll or subscribe to /job-events/<job_id> for progress.",
|
|
270
|
-
)
|
|
271
|
-
@openapi.response(
|
|
272
|
-
400,
|
|
273
|
-
{"application/json": model_to_schema(ApiErrorResponse)},
|
|
274
|
-
description="Validation error in request payload",
|
|
275
|
-
)
|
|
276
|
-
@openapi.response(
|
|
277
|
-
500,
|
|
278
|
-
{"application/json": model_to_schema(ApiErrorResponse)},
|
|
279
|
-
description="Internal server error",
|
|
280
|
-
)
|
|
281
|
-
@openapi.parameter(
|
|
282
|
-
HEADER_USER_ID,
|
|
283
|
-
description=(
|
|
284
|
-
"Optional user id to associate requests (e.g., for telemetry/guardrails)."
|
|
285
|
-
),
|
|
286
|
-
_in="header",
|
|
287
|
-
required=False,
|
|
288
|
-
schema=str,
|
|
289
|
-
)
|
|
290
|
-
async def handle_prompt_to_bot(request: Request) -> HTTPResponse:
|
|
291
|
-
"""Handle prompt-to-bot generation requests."""
|
|
292
|
-
try:
|
|
293
|
-
payload = PromptRequest(**request.json)
|
|
294
|
-
except Exception as exc:
|
|
295
|
-
return response.json(
|
|
296
|
-
ApiErrorResponse(
|
|
297
|
-
error="Invalid request", details={"error": str(exc)}
|
|
298
|
-
).model_dump(),
|
|
299
|
-
status=400,
|
|
300
|
-
)
|
|
301
|
-
|
|
302
|
-
try:
|
|
303
|
-
# Allocate job and schedule background task
|
|
304
|
-
job = job_manager.create_job()
|
|
305
|
-
request.app.add_task(run_prompt_to_bot_job(request.app, job, payload.prompt))
|
|
306
|
-
return response.json(JobCreateResponse(job_id=job.id).model_dump(), status=200)
|
|
307
|
-
except Exception as exc:
|
|
308
|
-
capture_exception_with_context(
|
|
309
|
-
exc,
|
|
310
|
-
"bot_builder_service.prompt_to_bot.unexpected_error",
|
|
311
|
-
tags={"endpoint": "/api/prompt-to-bot"},
|
|
312
|
-
)
|
|
313
|
-
return response.json(
|
|
314
|
-
ApiErrorResponse(
|
|
315
|
-
error="Failed to create prompt-to-bot job",
|
|
316
|
-
details={"error": str(exc)},
|
|
317
|
-
).model_dump(),
|
|
318
|
-
status=HTTPStatus.INTERNAL_SERVER_ERROR,
|
|
319
|
-
)
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
@bp.route("/template-to-bot", methods=["POST"])
|
|
323
|
-
@openapi.summary("Generate bot from predefined template")
|
|
324
|
-
@openapi.description(
|
|
325
|
-
"Creates a complete conversational AI bot from a predefined template. "
|
|
326
|
-
"Returns immediately with a job ID. Connect to `/job-events/<job_id>` to "
|
|
327
|
-
"receive server-sent events (SSE) for real-time progress tracking "
|
|
328
|
-
"throughout the bot creation process.\n\n"
|
|
329
|
-
"**SSE Event Flow** (via `/job-events/<job_id>`):\n"
|
|
330
|
-
"1. `received` - Request received by server\n"
|
|
331
|
-
"2. `generating` - Initializing bot from template\n"
|
|
332
|
-
"3. `generation_success` - Template initialization completed successfully\n"
|
|
333
|
-
"4. `training` - Training the bot model\n"
|
|
334
|
-
"5. `train_success` - Model training completed\n"
|
|
335
|
-
"6. `done` - Bot creation completed\n\n"
|
|
336
|
-
"**Error Events:**\n"
|
|
337
|
-
"- `generation_error` - Failed to initialize bot from template\n"
|
|
338
|
-
"- `train_error` - Template loaded but training failed\n"
|
|
339
|
-
"- `validation_error` - Template configuration is invalid\n"
|
|
340
|
-
"- `error` - Unexpected error occurred\n\n"
|
|
341
|
-
"**Usage:**\n"
|
|
342
|
-
"1. Send POST request with Content-Type: application/json\n"
|
|
343
|
-
"2. The response will be a JSON object `{job_id: ...}`\n"
|
|
344
|
-
"3. Connect to `/job-events/<job_id>` for a server-sent event stream of progress."
|
|
345
|
-
)
|
|
346
|
-
@openapi.tag("bot-generation")
|
|
347
|
-
@openapi.body(
|
|
348
|
-
{"application/json": model_to_schema(TemplateRequest)},
|
|
349
|
-
description="Template request with template name.",
|
|
350
|
-
required=True,
|
|
351
|
-
)
|
|
352
|
-
@openapi.response(
|
|
353
|
-
200,
|
|
354
|
-
{"application/json": model_to_schema(JobCreateResponse)},
|
|
355
|
-
description="Job created. Poll or subscribe to /job-events/<job_id> for progress.",
|
|
356
|
-
)
|
|
357
|
-
@openapi.response(
|
|
358
|
-
400,
|
|
359
|
-
{"application/json": model_to_schema(ApiErrorResponse)},
|
|
360
|
-
description="Validation error in request payload or invalid template name",
|
|
361
|
-
)
|
|
362
|
-
@openapi.response(
|
|
363
|
-
500,
|
|
364
|
-
{"application/json": model_to_schema(ApiErrorResponse)},
|
|
365
|
-
description="Internal server error",
|
|
366
|
-
)
|
|
367
|
-
@openapi.parameter(
|
|
368
|
-
HEADER_USER_ID,
|
|
369
|
-
description=(
|
|
370
|
-
"Optional user id to associate requests (e.g., for telemetry/guardrails)."
|
|
371
|
-
),
|
|
372
|
-
_in="header",
|
|
373
|
-
required=False,
|
|
374
|
-
schema=str,
|
|
375
|
-
)
|
|
376
|
-
async def handle_template_to_bot(request: Request) -> HTTPResponse:
|
|
377
|
-
"""Create a new template-to-bot job and return job_id immediately."""
|
|
378
|
-
try:
|
|
379
|
-
template_data = TemplateRequest(**request.json)
|
|
380
|
-
except Exception as exc:
|
|
381
|
-
return response.json(
|
|
382
|
-
ApiErrorResponse(
|
|
383
|
-
error="Invalid request", details={"error": str(exc)}
|
|
384
|
-
).model_dump(),
|
|
385
|
-
status=400,
|
|
386
|
-
)
|
|
387
|
-
|
|
388
|
-
try:
|
|
389
|
-
# allocate job and schedule background task
|
|
390
|
-
job = job_manager.create_job()
|
|
391
|
-
request.app.add_task(
|
|
392
|
-
run_template_to_bot_job(request.app, job, template_data.template_name)
|
|
393
|
-
)
|
|
394
|
-
return response.json(JobCreateResponse(job_id=job.id).model_dump(), status=200)
|
|
395
|
-
except Exception as exc:
|
|
396
|
-
capture_exception_with_context(
|
|
397
|
-
exc,
|
|
398
|
-
"bot_builder_service.template_to_bot.unexpected_error",
|
|
399
|
-
tags={"endpoint": "/api/template-to-bot"},
|
|
400
|
-
)
|
|
401
|
-
return response.json(
|
|
402
|
-
ApiErrorResponse(
|
|
403
|
-
error="Failed to create template-to-bot job",
|
|
404
|
-
details={"error": str(exc)},
|
|
405
|
-
).model_dump(),
|
|
406
|
-
status=HTTPStatus.INTERNAL_SERVER_ERROR,
|
|
407
|
-
)
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
@bp.route("/files", methods=["GET"])
|
|
411
|
-
@openapi.summary("Get bot files")
|
|
412
|
-
@openapi.description("Retrieves the current bot configuration files and data")
|
|
413
|
-
@openapi.tag("bot-files")
|
|
414
|
-
@openapi.response(
|
|
415
|
-
200,
|
|
416
|
-
{"application/json": {str: Optional[str]}},
|
|
417
|
-
description="Bot files retrieved successfully",
|
|
418
|
-
)
|
|
419
|
-
@openapi.response(
|
|
420
|
-
500,
|
|
421
|
-
{"application/json": model_to_schema(ApiErrorResponse)},
|
|
422
|
-
description="Internal server error",
|
|
423
|
-
)
|
|
424
|
-
@openapi.parameter(
|
|
425
|
-
HEADER_USER_ID,
|
|
426
|
-
description=(
|
|
427
|
-
"Optional user id to associate requests (e.g., for telemetry/guardrails)."
|
|
428
|
-
),
|
|
429
|
-
_in="header",
|
|
430
|
-
required=False,
|
|
431
|
-
schema=str,
|
|
432
|
-
)
|
|
433
|
-
async def get_bot_files(request: Request) -> HTTPResponse:
|
|
434
|
-
"""Get current bot files."""
|
|
435
|
-
try:
|
|
436
|
-
project_generator = get_project_generator(request)
|
|
437
|
-
bot_files = project_generator.get_bot_files()
|
|
438
|
-
return response.json(bot_files)
|
|
439
|
-
except Exception as exc:
|
|
440
|
-
capture_exception_with_context(
|
|
441
|
-
exc,
|
|
442
|
-
"bot_builder_service.get_bot_files.unexpected_error",
|
|
443
|
-
tags={"endpoint": "/api/files", "method": "GET"},
|
|
444
|
-
)
|
|
445
|
-
return response.json(
|
|
446
|
-
ApiErrorResponse(
|
|
447
|
-
error="Failed to retrieve bot files", details={"error": str(exc)}
|
|
448
|
-
).model_dump(),
|
|
449
|
-
status=HTTPStatus.INTERNAL_SERVER_ERROR,
|
|
450
|
-
)
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
@bp.route("/files", methods=["PUT"])
|
|
454
|
-
@openapi.summary("Update bot files")
|
|
455
|
-
@openapi.description(
|
|
456
|
-
"Updates the bot configuration files and retrains the model. "
|
|
457
|
-
"Returns immediately with a job ID. Connect to `/job-events/<job_id>` "
|
|
458
|
-
"for real-time SSE progress tracking."
|
|
459
|
-
"\n\n"
|
|
460
|
-
"**SSE Event Flow:** (available via /job-events/<job_id>)\n"
|
|
461
|
-
"1. `received` - Request received by server\n"
|
|
462
|
-
"2. `validating` - Validating bot configuration files\n"
|
|
463
|
-
"3. `validation_success` - File validation completed successfully\n"
|
|
464
|
-
"4. `training` - Training the bot model with updated files\n"
|
|
465
|
-
"5. `train_success` - Model training completed\n"
|
|
466
|
-
"6. `done` - Bot files update completed\n\n"
|
|
467
|
-
"**Error Events (can occur at any time):**\n"
|
|
468
|
-
"- `validation_error` - Bot configuration files are invalid\n"
|
|
469
|
-
"- `train_error` - Files updated but training failed\n"
|
|
470
|
-
"- `error` - Unexpected error occurred\n\n"
|
|
471
|
-
"**Usage:**\n"
|
|
472
|
-
"1. Send PUT request with Content-Type: application/json\n"
|
|
473
|
-
"2. The response will be a JSON object `{job_id: ...}`\n"
|
|
474
|
-
"3. Connect to `/job-events/<job_id>` for a server-sent event stream of progress."
|
|
475
|
-
)
|
|
476
|
-
@openapi.tag("bot-files")
|
|
477
|
-
@openapi.body(
|
|
478
|
-
{"application/json": {"file_name": str}},
|
|
479
|
-
description="A dictionary mapping file names to their updated content. "
|
|
480
|
-
"The file name should be the name of the file in the project folder. "
|
|
481
|
-
"Files that are not in the request will not be updated.",
|
|
482
|
-
required=True,
|
|
483
|
-
)
|
|
484
|
-
@openapi.response(
|
|
485
|
-
200,
|
|
486
|
-
{"application/json": model_to_schema(JobCreateResponse)},
|
|
487
|
-
description=(
|
|
488
|
-
"Job created. Poll or subscribe to /job-events/<job_id> "
|
|
489
|
-
"for progress and SSE updates."
|
|
490
|
-
),
|
|
491
|
-
)
|
|
492
|
-
@openapi.response(
|
|
493
|
-
400,
|
|
494
|
-
{"application/json": model_to_schema(ApiErrorResponse)},
|
|
495
|
-
description="Validation error in bot files",
|
|
496
|
-
)
|
|
497
|
-
@openapi.response(
|
|
498
|
-
500,
|
|
499
|
-
{"application/json": model_to_schema(ApiErrorResponse)},
|
|
500
|
-
description="Internal server error",
|
|
501
|
-
)
|
|
502
|
-
@openapi.response(
|
|
503
|
-
401,
|
|
504
|
-
{"application/json": model_to_schema(ApiErrorResponse)},
|
|
505
|
-
description=(
|
|
506
|
-
"Authentication failed - Authorization header missing or invalid. "
|
|
507
|
-
"Auth may be conditionally required depending on server "
|
|
508
|
-
"configuration."
|
|
509
|
-
),
|
|
510
|
-
)
|
|
511
|
-
@openapi.parameter(
|
|
512
|
-
"Authorization",
|
|
513
|
-
description=(
|
|
514
|
-
"Bearer token for authentication. Required after auth start window "
|
|
515
|
-
"or if configured."
|
|
516
|
-
),
|
|
517
|
-
_in="header",
|
|
518
|
-
required=False,
|
|
519
|
-
schema=str,
|
|
520
|
-
)
|
|
521
|
-
@openapi.parameter(
|
|
522
|
-
HEADER_USER_ID,
|
|
523
|
-
description=(
|
|
524
|
-
"Optional user id to associate requests (e.g., for telemetry/guardrails)."
|
|
525
|
-
),
|
|
526
|
-
_in="header",
|
|
527
|
-
required=False,
|
|
528
|
-
schema=str,
|
|
529
|
-
)
|
|
530
|
-
@protected()
|
|
531
|
-
async def update_bot_files(request: Request) -> HTTPResponse:
|
|
532
|
-
"""Update bot files with server-sent events for progress tracking."""
|
|
533
|
-
try:
|
|
534
|
-
bot_files = request.json
|
|
535
|
-
except Exception as exc:
|
|
536
|
-
return response.json(
|
|
537
|
-
ApiErrorResponse(
|
|
538
|
-
error="Invalid request", details={"error": str(exc)}
|
|
539
|
-
).model_dump(),
|
|
540
|
-
status=400,
|
|
541
|
-
)
|
|
542
|
-
|
|
543
|
-
try:
|
|
544
|
-
job = job_manager.create_job()
|
|
545
|
-
request.app.add_task(run_update_files_job(request.app, job, bot_files))
|
|
546
|
-
return response.json(JobCreateResponse(job_id=job.id).model_dump(), status=200)
|
|
547
|
-
except Exception as exc:
|
|
548
|
-
capture_exception_with_context(
|
|
549
|
-
exc,
|
|
550
|
-
"bot_builder_service.update_bot_files.unexpected_error",
|
|
551
|
-
tags={"endpoint": "/api/files", "method": "PUT"},
|
|
552
|
-
)
|
|
553
|
-
return response.json(
|
|
554
|
-
ApiErrorResponse(
|
|
555
|
-
error="Failed to update bot files", details={"error": str(exc)}
|
|
556
|
-
).model_dump(),
|
|
557
|
-
status=HTTPStatus.INTERNAL_SERVER_ERROR,
|
|
558
|
-
)
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
@bp.route("/data", methods=["GET"])
|
|
562
|
-
@openapi.summary("Get bot data")
|
|
563
|
-
@openapi.description(
|
|
564
|
-
"Retrieves the current bot data in CALM import format with flows, domain, "
|
|
565
|
-
"config, endpoints, and NLU data"
|
|
566
|
-
)
|
|
567
|
-
@openapi.tag("bot-data")
|
|
568
|
-
@openapi.response(
|
|
569
|
-
200,
|
|
570
|
-
{"application/json": model_to_schema(BotData)},
|
|
571
|
-
description="Bot data retrieved successfully",
|
|
572
|
-
)
|
|
573
|
-
@openapi.response(
|
|
574
|
-
409,
|
|
575
|
-
{"application/json": model_to_schema(ApiErrorResponse)},
|
|
576
|
-
description="Agent not ready",
|
|
577
|
-
)
|
|
578
|
-
@openapi.response(
|
|
579
|
-
500,
|
|
580
|
-
{"application/json": model_to_schema(ApiErrorResponse)},
|
|
581
|
-
description="Internal server error",
|
|
582
|
-
)
|
|
583
|
-
@openapi.parameter(
|
|
584
|
-
HEADER_USER_ID,
|
|
585
|
-
description=(
|
|
586
|
-
"Optional user id to associate requests (e.g., for telemetry/guardrails)."
|
|
587
|
-
),
|
|
588
|
-
_in="header",
|
|
589
|
-
required=False,
|
|
590
|
-
schema=str,
|
|
591
|
-
)
|
|
592
|
-
async def get_bot_data(request: Request) -> HTTPResponse:
|
|
593
|
-
"""Get current bot data in CALM import format."""
|
|
594
|
-
try:
|
|
595
|
-
agent: Optional[Agent] = request.app.ctx.agent
|
|
596
|
-
if not agent:
|
|
597
|
-
raise AgentNotReady(
|
|
598
|
-
"Can't retrieve the data without an agent being loaded."
|
|
599
|
-
)
|
|
600
|
-
|
|
601
|
-
bot_data = await extract_bot_data_from_agent(agent)
|
|
602
|
-
|
|
603
|
-
return response.json(bot_data.model_dump())
|
|
604
|
-
except AgentNotReady as e:
|
|
605
|
-
return response.json(
|
|
606
|
-
ApiErrorResponse(
|
|
607
|
-
error="Agent not ready",
|
|
608
|
-
details={"error": str(e)},
|
|
609
|
-
).model_dump(),
|
|
610
|
-
status=HTTPStatus.CONFLICT,
|
|
611
|
-
)
|
|
612
|
-
except Exception as exc:
|
|
613
|
-
capture_exception_with_context(
|
|
614
|
-
exc,
|
|
615
|
-
"bot_builder_service.get_bot_data.unexpected_error",
|
|
616
|
-
tags={"endpoint": "/api/data"},
|
|
617
|
-
)
|
|
618
|
-
return response.json(
|
|
619
|
-
ApiErrorResponse(
|
|
620
|
-
error="Failed to retrieve bot data",
|
|
621
|
-
details={"error": str(exc)},
|
|
622
|
-
).model_dump(),
|
|
623
|
-
status=HTTPStatus.INTERNAL_SERVER_ERROR,
|
|
624
|
-
)
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
@bp.route("/assistant", methods=["GET"])
|
|
628
|
-
@openapi.summary("Get assistant info")
|
|
629
|
-
@openapi.description(
|
|
630
|
-
"Returns basic information about the loaded assistant, including the assistant id "
|
|
631
|
-
"as configured in the model's metadata (from config.yml)."
|
|
632
|
-
)
|
|
633
|
-
@openapi.tag("assistant")
|
|
634
|
-
@openapi.response(
|
|
635
|
-
200,
|
|
636
|
-
{"application/json": model_to_schema(AssistantInfo)},
|
|
637
|
-
description="Assistant info retrieved successfully",
|
|
638
|
-
)
|
|
639
|
-
@openapi.response(
|
|
640
|
-
409,
|
|
641
|
-
{"application/json": model_to_schema(ApiErrorResponse)},
|
|
642
|
-
description="Agent not ready",
|
|
643
|
-
)
|
|
644
|
-
@openapi.response(
|
|
645
|
-
500,
|
|
646
|
-
{"application/json": model_to_schema(ApiErrorResponse)},
|
|
647
|
-
description="Internal server error",
|
|
648
|
-
)
|
|
649
|
-
@openapi.parameter(
|
|
650
|
-
HEADER_USER_ID,
|
|
651
|
-
description=(
|
|
652
|
-
"Optional user id to associate requests (e.g., for telemetry/guardrails)."
|
|
653
|
-
),
|
|
654
|
-
_in="header",
|
|
655
|
-
required=False,
|
|
656
|
-
schema=str,
|
|
657
|
-
)
|
|
658
|
-
async def get_bot_info(request: Request) -> HTTPResponse:
|
|
659
|
-
"""Return assistant info including assistant id from model metadata."""
|
|
660
|
-
try:
|
|
661
|
-
agent: Optional[Agent] = request.app.ctx.agent
|
|
662
|
-
if not agent:
|
|
663
|
-
raise AgentNotReady("Can't retrieve bot info without a loaded agent.")
|
|
664
|
-
|
|
665
|
-
assistant_id: Optional[str] = (
|
|
666
|
-
agent.processor.model_metadata.assistant_id
|
|
667
|
-
if agent.processor
|
|
668
|
-
and agent.processor.model_metadata
|
|
669
|
-
and hasattr(agent.processor.model_metadata, "assistant_id")
|
|
670
|
-
else None
|
|
671
|
-
)
|
|
672
|
-
|
|
673
|
-
return response.json(AssistantInfo(assistant_id=assistant_id).model_dump())
|
|
674
|
-
except AgentNotReady as e:
|
|
675
|
-
return response.json(
|
|
676
|
-
ApiErrorResponse(
|
|
677
|
-
error="Agent not ready",
|
|
678
|
-
details={"error": str(e)},
|
|
679
|
-
).model_dump(),
|
|
680
|
-
status=HTTPStatus.CONFLICT,
|
|
681
|
-
)
|
|
682
|
-
except Exception as exc:
|
|
683
|
-
capture_exception_with_context(
|
|
684
|
-
exc,
|
|
685
|
-
"bot_builder_service.get_bot_info.unexpected_error",
|
|
686
|
-
tags={"endpoint": "/api/assistant"},
|
|
687
|
-
)
|
|
688
|
-
return response.json(
|
|
689
|
-
ApiErrorResponse(
|
|
690
|
-
error="Failed to retrieve bot info",
|
|
691
|
-
details={"error": str(exc)},
|
|
692
|
-
).model_dump(),
|
|
693
|
-
status=HTTPStatus.INTERNAL_SERVER_ERROR,
|
|
694
|
-
)
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
@bp.route("/download", methods=["GET"])
|
|
698
|
-
@openapi.summary("Download bot project as tar.gz")
|
|
699
|
-
@openapi.description(
|
|
700
|
-
"Downloads the current bot project files as a compressed tar.gz archive. "
|
|
701
|
-
"Includes all configuration files and a .env file with RASA_PRO_LICENSE. "
|
|
702
|
-
"Requires valid JWT token in Authorization header."
|
|
703
|
-
)
|
|
704
|
-
@openapi.tag("bot-files")
|
|
705
|
-
@openapi.parameter(
|
|
706
|
-
"Authorization",
|
|
707
|
-
description="Bearer token for authentication",
|
|
708
|
-
_in="header",
|
|
709
|
-
required=True,
|
|
710
|
-
schema=str,
|
|
711
|
-
)
|
|
712
|
-
@openapi.parameter(
|
|
713
|
-
HEADER_USER_ID,
|
|
714
|
-
description=(
|
|
715
|
-
"Optional user id to associate requests (e.g., for telemetry/guardrails)."
|
|
716
|
-
),
|
|
717
|
-
_in="header",
|
|
718
|
-
required=False,
|
|
719
|
-
schema=str,
|
|
720
|
-
)
|
|
721
|
-
@openapi.parameter(
|
|
722
|
-
"project_name",
|
|
723
|
-
description="Name of the project for the archive filename and pyproject.toml",
|
|
724
|
-
_in="query",
|
|
725
|
-
required=False,
|
|
726
|
-
schema=str,
|
|
727
|
-
)
|
|
728
|
-
@openapi.response(
|
|
729
|
-
200,
|
|
730
|
-
{"application/gzip": bytes},
|
|
731
|
-
description="Bot project downloaded successfully as tar.gz",
|
|
732
|
-
)
|
|
733
|
-
@openapi.response(
|
|
734
|
-
401,
|
|
735
|
-
{"application/json": model_to_schema(ApiErrorResponse)},
|
|
736
|
-
description="Authentication failed - invalid or missing token",
|
|
737
|
-
)
|
|
738
|
-
@openapi.response(
|
|
739
|
-
500,
|
|
740
|
-
{"application/json": model_to_schema(ApiErrorResponse)},
|
|
741
|
-
description="Internal server error",
|
|
742
|
-
)
|
|
743
|
-
@protected(always_required=True)
|
|
744
|
-
async def download_bot_project(request: Request) -> HTTPResponse:
|
|
745
|
-
"""Download bot project as tar.gz archive."""
|
|
746
|
-
try:
|
|
747
|
-
# Token verification is enforced by the
|
|
748
|
-
# protected(always_required=True) decorator.
|
|
749
|
-
|
|
750
|
-
# Get bot files
|
|
751
|
-
project_generator = get_project_generator(request)
|
|
752
|
-
bot_files = project_generator.get_bot_files()
|
|
753
|
-
|
|
754
|
-
# Get project name from query parameters, default to "bot-project"
|
|
755
|
-
project_name = request.args.get("project_name", "bot-project")
|
|
756
|
-
|
|
757
|
-
# Create tar.gz archive
|
|
758
|
-
tar_data = create_bot_project_archive(bot_files, project_name)
|
|
759
|
-
|
|
760
|
-
structlogger.info(
|
|
761
|
-
"bot_builder_service.download_bot_project.success",
|
|
762
|
-
user_sub=(getattr(request.ctx, "auth_payload", None) or {}).get("sub"),
|
|
763
|
-
files_count=len(bot_files),
|
|
764
|
-
archive_size=len(tar_data),
|
|
765
|
-
payload=getattr(request.ctx, "auth_payload", None),
|
|
766
|
-
project_name=project_name,
|
|
767
|
-
)
|
|
768
|
-
|
|
769
|
-
return response.raw(
|
|
770
|
-
tar_data,
|
|
771
|
-
content_type="application/gzip",
|
|
772
|
-
headers={
|
|
773
|
-
"Content-Disposition": f"attachment; filename={project_name}.tar.gz"
|
|
774
|
-
},
|
|
775
|
-
)
|
|
776
|
-
|
|
777
|
-
except Exception as exc:
|
|
778
|
-
capture_exception_with_context(
|
|
779
|
-
exc,
|
|
780
|
-
"bot_builder_service.download_bot_project.unexpected_error",
|
|
781
|
-
tags={"endpoint": "/api/download"},
|
|
782
|
-
)
|
|
783
|
-
return response.json(
|
|
784
|
-
ApiErrorResponse(
|
|
785
|
-
error="Failed to create bot project archive",
|
|
786
|
-
details={"error": str(exc)},
|
|
787
|
-
).model_dump(),
|
|
788
|
-
status=500,
|
|
789
|
-
)
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
@bp.route("/copilot", methods=["POST"])
|
|
793
|
-
@openapi.summary("AI copilot for bot building")
|
|
794
|
-
@openapi.description(
|
|
795
|
-
"Provides LLM-powered copilot assistance with streaming markdown responses. "
|
|
796
|
-
"Returns server-sent events (SSE) for real-time streaming of copilot responses.\n\n"
|
|
797
|
-
"The event's `event` field is the type of event. For this endpoint it will always "
|
|
798
|
-
"be: `copilot_response`.\n\n"
|
|
799
|
-
)
|
|
800
|
-
@openapi.tag("copilot")
|
|
801
|
-
@openapi.body(
|
|
802
|
-
{"application/json": model_to_schema(CopilotRequest)},
|
|
803
|
-
description=(
|
|
804
|
-
"Copilot request containing: "
|
|
805
|
-
"1. conversation history between user and copilot, "
|
|
806
|
-
"2. session ID for tracking conversation context with the bot being built."
|
|
807
|
-
),
|
|
808
|
-
required=True,
|
|
809
|
-
)
|
|
810
|
-
@openapi.response(
|
|
811
|
-
200,
|
|
812
|
-
{"text/event-stream": model_to_schema(ServerSentEvent)},
|
|
813
|
-
description=(
|
|
814
|
-
"Server-sent events stream with copilot responses and references. "
|
|
815
|
-
"The event's `event` field is the type "
|
|
816
|
-
"of event. For this endpoint it will always be: `copilot_response`. "
|
|
817
|
-
"The event's data field is a JSON dump. The following describes the event data "
|
|
818
|
-
"field:\n"
|
|
819
|
-
"- `response_category` can be one of the following:\n"
|
|
820
|
-
" - `copilot` - Stream token generated by the copilot.\n"
|
|
821
|
-
" - `out_of_scope_detection` - Response coming from the the out of scope detection.\n" # noqa: E501
|
|
822
|
-
" - `roleplay_detection` - Response coming from the the roleplay detection.\n"
|
|
823
|
-
" - `reference` - Reference section.\n"
|
|
824
|
-
" - `training_error_log_analysis` - Used to flag the responses that are training error log analysis.\n" # noqa: E501
|
|
825
|
-
" - `e2e_testing_error_log_analysis` - Used to flag the responses that are e2e testing error log analysis.\n" # noqa: E501
|
|
826
|
-
" - `guardrail_policy_violation` - Used to flag the responses that are flagged as a violation of the guardrail policy.\n\n" # noqa: E501
|
|
827
|
-
"- `completeness`: Whether this is a streaming token or complete response.\n\n"
|
|
828
|
-
"- `content`: The actual response content (for streaming tokens).\n\n"
|
|
829
|
-
"- `references`: (Only for `reference` response category) List of reference entries. Each reference entry is a dictionary with the following keys:\n\n" # noqa: E501
|
|
830
|
-
" - `index`: Reference index as an integer number.\n"
|
|
831
|
-
" - `title`: Reference title as a string.\n"
|
|
832
|
-
" - `url`: Reference URL as a string.\n\n"
|
|
833
|
-
),
|
|
834
|
-
examples={
|
|
835
|
-
"Streaming token from copilot": {
|
|
836
|
-
"summary": "Streaming token from copilot",
|
|
837
|
-
"value": GeneratedContent(
|
|
838
|
-
content="<token generated by the copilot>",
|
|
839
|
-
response_category=ResponseCategory.COPILOT,
|
|
840
|
-
response_completeness=ResponseCompleteness.TOKEN,
|
|
841
|
-
)
|
|
842
|
-
.to_sse_event()
|
|
843
|
-
.model_dump(),
|
|
844
|
-
},
|
|
845
|
-
"Complete response for the following response categories: out_of_scope_detection / roleplay_detection / training_error_log_analysis / e2e_testing_error_log_analysis / guardrail_policy_violation": { # noqa: E501
|
|
846
|
-
"summary": "Complete response from copilot",
|
|
847
|
-
"value": GeneratedContent(
|
|
848
|
-
content="<response from the out of scope detection>",
|
|
849
|
-
response_category=ResponseCategory.OUT_OF_SCOPE_DETECTION,
|
|
850
|
-
response_completeness=ResponseCompleteness.COMPLETE,
|
|
851
|
-
)
|
|
852
|
-
.to_sse_event()
|
|
853
|
-
.model_dump(),
|
|
854
|
-
},
|
|
855
|
-
"Response with the references": {
|
|
856
|
-
"summary": "Reference section with all references",
|
|
857
|
-
"value": ReferenceSection(
|
|
858
|
-
references=[
|
|
859
|
-
ReferenceEntry(
|
|
860
|
-
index=1,
|
|
861
|
-
title="Title of the reference",
|
|
862
|
-
url="https://rasa.com/docs/...",
|
|
863
|
-
),
|
|
864
|
-
ReferenceEntry(
|
|
865
|
-
index=2,
|
|
866
|
-
title="Title of another reference",
|
|
867
|
-
url="https://rasa.com/docs/...",
|
|
868
|
-
),
|
|
869
|
-
],
|
|
870
|
-
response_category=ResponseCategory.REFERENCE,
|
|
871
|
-
response_completeness=ResponseCompleteness.COMPLETE,
|
|
872
|
-
)
|
|
873
|
-
.to_sse_event()
|
|
874
|
-
.model_dump(),
|
|
875
|
-
},
|
|
876
|
-
},
|
|
877
|
-
)
|
|
878
|
-
@openapi.response(
|
|
879
|
-
400,
|
|
880
|
-
{"application/json": model_to_schema(ApiErrorResponse)},
|
|
881
|
-
description="Validation error in request",
|
|
882
|
-
)
|
|
883
|
-
@openapi.response(
|
|
884
|
-
502,
|
|
885
|
-
{"application/json": model_to_schema(ApiErrorResponse)},
|
|
886
|
-
description="LLM generation failed.",
|
|
887
|
-
)
|
|
888
|
-
@openapi.response(
|
|
889
|
-
500,
|
|
890
|
-
{"application/json": model_to_schema(ApiErrorResponse)},
|
|
891
|
-
description="Internal server error.",
|
|
892
|
-
)
|
|
893
|
-
@openapi.response(
|
|
894
|
-
401,
|
|
895
|
-
{"application/json": model_to_schema(ApiErrorResponse)},
|
|
896
|
-
description=(
|
|
897
|
-
"Authentication failed - Authorization header missing or invalid. "
|
|
898
|
-
"Auth may be conditionally required depending on server "
|
|
899
|
-
"configuration."
|
|
900
|
-
),
|
|
901
|
-
)
|
|
902
|
-
@openapi.parameter(
|
|
903
|
-
"Authorization",
|
|
904
|
-
description=(
|
|
905
|
-
"Bearer token for authentication. Required after auth start window "
|
|
906
|
-
"or if configured."
|
|
907
|
-
),
|
|
908
|
-
_in="header",
|
|
909
|
-
required=False,
|
|
910
|
-
schema=str,
|
|
911
|
-
)
|
|
912
|
-
@openapi.parameter(
|
|
913
|
-
HEADER_USER_ID,
|
|
914
|
-
description=(
|
|
915
|
-
"Optional user id to associate requests (e.g., for telemetry/guardrails)."
|
|
916
|
-
),
|
|
917
|
-
_in="header",
|
|
918
|
-
required=False,
|
|
919
|
-
schema=str,
|
|
920
|
-
)
|
|
921
|
-
@protected()
|
|
922
|
-
async def copilot(request: Request) -> None:
|
|
923
|
-
"""Handle copilot requests with streaming markdown responses."""
|
|
924
|
-
sse = await request.respond(content_type="text/event-stream")
|
|
925
|
-
project_generator = get_project_generator(request)
|
|
926
|
-
|
|
927
|
-
try:
|
|
928
|
-
# 1. Validate and unpack input
|
|
929
|
-
req = CopilotRequest(**request.json)
|
|
930
|
-
|
|
931
|
-
telemetry = CopilotTelemetry(
|
|
932
|
-
project_id=HELLO_RASA_PROJECT_ID,
|
|
933
|
-
user_id=request.headers.get(HEADER_USER_ID),
|
|
934
|
-
)
|
|
935
|
-
structlogger.debug("builder.copilot.telemetry.request.init")
|
|
936
|
-
|
|
937
|
-
if req.last_message and req.last_message.role == ROLE_USER:
|
|
938
|
-
structlogger.debug("builder.copilot.telemetry.request.user_turn")
|
|
939
|
-
# Offload telemetry logging to a background task
|
|
940
|
-
request.app.add_task(
|
|
941
|
-
asyncio.to_thread(
|
|
942
|
-
telemetry.log_user_turn, req.last_message.get_text_content()
|
|
943
|
-
)
|
|
944
|
-
)
|
|
945
|
-
|
|
946
|
-
# 2. Get the necessary context for the copilot
|
|
947
|
-
tracker = await current_tracker_from_input_channel(request.app, req.session_id)
|
|
948
|
-
tracker_context = TrackerContext.from_tracker(
|
|
949
|
-
tracker, max_turns=COPILOT_ASSISTANT_TRACKER_MAX_TURNS
|
|
950
|
-
)
|
|
951
|
-
if tracker_context is not None:
|
|
952
|
-
tracker_context = await check_assistant_chat_for_policy_violations(
|
|
953
|
-
tracker_context=tracker_context,
|
|
954
|
-
hello_rasa_user_id=request.headers.get(HEADER_USER_ID),
|
|
955
|
-
hello_rasa_project_id=HELLO_RASA_PROJECT_ID,
|
|
956
|
-
)
|
|
957
|
-
|
|
958
|
-
# Copilot doesn't need to know about the docs and any file that is not a core
|
|
959
|
-
# assistant file
|
|
960
|
-
relevant_assistant_files = project_generator.get_bot_files(
|
|
961
|
-
exclude_docs_directory=True,
|
|
962
|
-
allowed_file_extensions=["yaml", "yml", "py", "jinja", "jinja2"],
|
|
963
|
-
)
|
|
964
|
-
context = CopilotContext(
|
|
965
|
-
tracker_context=tracker_context,
|
|
966
|
-
assistant_logs=get_recent_logs(),
|
|
967
|
-
assistant_files=relevant_assistant_files,
|
|
968
|
-
copilot_chat_history=req.copilot_chat_history,
|
|
969
|
-
)
|
|
970
|
-
|
|
971
|
-
# 3. Run guardrail policy checks. If any policy violations are detected,
|
|
972
|
-
# send a response and end the stream.
|
|
973
|
-
guardrail_response: Optional[
|
|
974
|
-
GeneratedContent
|
|
975
|
-
] = await check_copilot_chat_for_policy_violations(
|
|
976
|
-
context=context,
|
|
977
|
-
hello_rasa_user_id=request.headers.get(HEADER_USER_ID),
|
|
978
|
-
hello_rasa_project_id=HELLO_RASA_PROJECT_ID,
|
|
979
|
-
)
|
|
980
|
-
if guardrail_response is not None:
|
|
981
|
-
await sse.send(guardrail_response.to_sse_event().format())
|
|
982
|
-
await sse.eof()
|
|
983
|
-
return
|
|
984
|
-
|
|
985
|
-
# 4. Get the original response stream from copilot and handle it with the
|
|
986
|
-
# copilot response handler
|
|
987
|
-
start_timestamp = time.perf_counter()
|
|
988
|
-
copilot_client = llm_service.instantiate_copilot()
|
|
989
|
-
(
|
|
990
|
-
original_stream,
|
|
991
|
-
used_documents,
|
|
992
|
-
) = await copilot_client.generate_response(context)
|
|
993
|
-
|
|
994
|
-
copilot_response_handler = llm_service.instantiate_handler(
|
|
995
|
-
COPILOT_HANDLER_ROLLING_BUFFER_SIZE
|
|
996
|
-
)
|
|
997
|
-
intercepted_stream = copilot_response_handler.handle_response(original_stream)
|
|
998
|
-
|
|
999
|
-
# 5. Stream the intercepted response
|
|
1000
|
-
async for token in intercepted_stream:
|
|
1001
|
-
await sse.send(token.to_sse_event().format())
|
|
1002
|
-
|
|
1003
|
-
# Offload telemetry logging to a background task
|
|
1004
|
-
request.app.add_task(
|
|
1005
|
-
asyncio.to_thread(
|
|
1006
|
-
telemetry.log_copilot_from_handler,
|
|
1007
|
-
handler=copilot_response_handler,
|
|
1008
|
-
used_documents=used_documents,
|
|
1009
|
-
latency_ms=int((time.perf_counter() - start_timestamp) * 1000),
|
|
1010
|
-
**copilot_client.usage_statistics.model_dump(),
|
|
1011
|
-
)
|
|
1012
|
-
)
|
|
1013
|
-
|
|
1014
|
-
# 6. Once the stream is over, extract and send references
|
|
1015
|
-
# if any documents were used
|
|
1016
|
-
if used_documents:
|
|
1017
|
-
reference_section = copilot_response_handler.extract_references(
|
|
1018
|
-
used_documents
|
|
1019
|
-
)
|
|
1020
|
-
await sse.send(reference_section.to_sse_event().format())
|
|
1021
|
-
|
|
1022
|
-
except CopilotStreamError as e:
|
|
1023
|
-
capture_exception_with_context(
|
|
1024
|
-
e,
|
|
1025
|
-
"bot_builder_service.copilot.generation_error",
|
|
1026
|
-
extra={"session_id": req.session_id},
|
|
1027
|
-
tags={"endpoint": "/api/copilot"},
|
|
1028
|
-
)
|
|
1029
|
-
await sse.send(
|
|
1030
|
-
ServerSentEvent(
|
|
1031
|
-
event="error",
|
|
1032
|
-
data={"error": str(e)},
|
|
1033
|
-
).format()
|
|
1034
|
-
)
|
|
1035
|
-
|
|
1036
|
-
except Exception as exc:
|
|
1037
|
-
capture_exception_with_context(
|
|
1038
|
-
exc,
|
|
1039
|
-
"bot_builder_service.copilot.unexpected_error",
|
|
1040
|
-
extra={"session_id": req.session_id if "req" in locals() else None},
|
|
1041
|
-
tags={"endpoint": "/api/copilot"},
|
|
1042
|
-
)
|
|
1043
|
-
await sse.send(
|
|
1044
|
-
ServerSentEvent(
|
|
1045
|
-
event="error",
|
|
1046
|
-
data={"error": str(exc)},
|
|
1047
|
-
).format()
|
|
1048
|
-
)
|
|
1049
|
-
|
|
1050
|
-
finally:
|
|
1051
|
-
await sse.eof()
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
@bp.route("/copilot/internal_message_templates/<template_name>", methods=["GET"])
|
|
1055
|
-
@openapi.summary("Get templated response for copilot internal message")
|
|
1056
|
-
@openapi.description(
|
|
1057
|
-
"Returns the templated response text for a given template name from the "
|
|
1058
|
-
"copilot internal message formatter. This endpoint provides access to the "
|
|
1059
|
-
"predefined templates used for formatting internal system messages."
|
|
1060
|
-
)
|
|
1061
|
-
@openapi.tag("copilot")
|
|
1062
|
-
@openapi.parameter(
|
|
1063
|
-
"template_name",
|
|
1064
|
-
str,
|
|
1065
|
-
location="path",
|
|
1066
|
-
description=(
|
|
1067
|
-
"The template name to get the template for."
|
|
1068
|
-
"(e.g., 'training_error_log_analysis', 'e2e_testing_error_log_analysis')",
|
|
1069
|
-
),
|
|
1070
|
-
)
|
|
1071
|
-
@openapi.response(
|
|
1072
|
-
200,
|
|
1073
|
-
{"application/json": {"template": str, "template_name": str}},
|
|
1074
|
-
description="Successfully retrieved the template for the given template name",
|
|
1075
|
-
example={
|
|
1076
|
-
"template": "The assistant training failed. Your task is ...",
|
|
1077
|
-
"template_name": "training_error_log_analysis",
|
|
1078
|
-
},
|
|
1079
|
-
)
|
|
1080
|
-
@openapi.response(
|
|
1081
|
-
404,
|
|
1082
|
-
{"application/json": model_to_schema(ApiErrorResponse)},
|
|
1083
|
-
description="Template not found for the given template name",
|
|
1084
|
-
)
|
|
1085
|
-
@openapi.parameter(
|
|
1086
|
-
HEADER_USER_ID,
|
|
1087
|
-
description=(
|
|
1088
|
-
"Optional user id to associate requests (e.g., for telemetry/guardrails)."
|
|
1089
|
-
),
|
|
1090
|
-
_in="header",
|
|
1091
|
-
required=False,
|
|
1092
|
-
schema=str,
|
|
1093
|
-
)
|
|
1094
|
-
async def get_copilot_internal_message_template(
|
|
1095
|
-
request: Request, template_name: str
|
|
1096
|
-
) -> HTTPResponse:
|
|
1097
|
-
"""Get templated response for copilot internal message formatter."""
|
|
1098
|
-
try:
|
|
1099
|
-
# Try to get the template for the given template name
|
|
1100
|
-
template = llm_service.copilot_internal_message_templates.get(template_name)
|
|
1101
|
-
structlogger.info(
|
|
1102
|
-
"bot_builder_service.get_copilot_internal_message_template.template_found",
|
|
1103
|
-
template_name=template_name,
|
|
1104
|
-
template=template,
|
|
1105
|
-
)
|
|
1106
|
-
|
|
1107
|
-
if template is None:
|
|
1108
|
-
structlogger.warning(
|
|
1109
|
-
"bot_builder_service.get_copilot_internal_message_template.not_found",
|
|
1110
|
-
template_name=template_name,
|
|
1111
|
-
)
|
|
1112
|
-
return response.json(
|
|
1113
|
-
ApiErrorResponse(
|
|
1114
|
-
error="Template not found", details={"template_name": template_name}
|
|
1115
|
-
).model_dump(),
|
|
1116
|
-
status=404,
|
|
1117
|
-
)
|
|
1118
|
-
|
|
1119
|
-
return response.json({"template": template, "template_name": template_name})
|
|
1120
|
-
|
|
1121
|
-
except Exception as e:
|
|
1122
|
-
structlogger.error(
|
|
1123
|
-
"bot_builder_service.get_copilot_internal_message_template.error",
|
|
1124
|
-
error=str(e),
|
|
1125
|
-
template_name=template_name,
|
|
1126
|
-
)
|
|
1127
|
-
return response.json(
|
|
1128
|
-
ApiErrorResponse(
|
|
1129
|
-
error="Internal server error", details={"template_name": template_name}
|
|
1130
|
-
).model_dump(),
|
|
1131
|
-
status=500,
|
|
1132
|
-
)
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
async def current_tracker_from_input_channel(
|
|
1136
|
-
app: Any, session_id: str
|
|
1137
|
-
) -> Optional[DialogueStateTracker]:
|
|
1138
|
-
"""Generate chat bot context from current conversation."""
|
|
1139
|
-
if app.ctx.agent and session_id:
|
|
1140
|
-
return await app.ctx.agent.tracker_store.retrieve(session_id)
|
|
1141
|
-
else:
|
|
1142
|
-
return None
|