rasa-pro 3.14.0rc2__py3-none-any.whl → 3.14.0rc4__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.

Files changed (82) hide show
  1. rasa/agents/protocol/a2a/a2a_agent.py +50 -42
  2. rasa/agents/protocol/mcp/mcp_base_agent.py +15 -1
  3. rasa/agents/utils.py +27 -5
  4. rasa/agents/validation.py +64 -13
  5. rasa/api.py +1 -2
  6. rasa/builder/copilot/constants.py +4 -0
  7. rasa/builder/copilot/copilot.py +37 -1
  8. rasa/builder/copilot/copilot_templated_message_provider.py +23 -0
  9. rasa/builder/copilot/models.py +43 -49
  10. rasa/builder/copilot/prompts/copilot_system_prompt.jinja2 +33 -12
  11. rasa/builder/copilot/prompts/latest_user_message_context_prompt.jinja2 +59 -29
  12. rasa/builder/copilot/telemetry.py +8 -0
  13. rasa/builder/copilot/templated_messages/copilot_templated_responses.yml +3 -0
  14. rasa/builder/copilot/templated_messages/copilot_welcome_messages.yml +56 -0
  15. rasa/builder/jobs.py +162 -5
  16. rasa/builder/models.py +3 -0
  17. rasa/builder/service.py +1 -0
  18. rasa/cli/dialogue_understanding_test.py +1 -0
  19. rasa/cli/e2e_test.py +1 -0
  20. rasa/cli/inspect.py +1 -0
  21. rasa/cli/project_templates/basic/tests/e2e_test_cases/without_stub/general/feedback.yml +46 -0
  22. rasa/cli/project_templates/basic/tests/e2e_test_cases/without_stub/general/goodbye.yml +9 -0
  23. rasa/cli/project_templates/basic/tests/e2e_test_cases/without_stub/general/help.yml +8 -0
  24. rasa/cli/project_templates/basic/tests/e2e_test_cases/without_stub/general/human_handoff.yml +41 -0
  25. rasa/cli/project_templates/basic/tests/e2e_test_cases/without_stub/general/patterns.yml +32 -0
  26. rasa/cli/project_templates/basic/tests/e2e_test_cases/without_stub/general/show_faqs.yml +8 -0
  27. rasa/cli/project_templates/telco/data/network/flow_solve_internet_issue.yml +2 -2
  28. rasa/cli/project_templates/telco/domain/network/solve_internet_issue.yml +1 -2
  29. rasa/cli/project_templates/telco/tests/e2e_test_cases/with_stub/network/solve_internet_not_slow.yml +33 -0
  30. rasa/cli/project_templates/telco/tests/e2e_test_cases/with_stub/network/solve_internet_slow.yml +47 -0
  31. rasa/cli/project_templates/telco/tests/e2e_test_cases/without_stub/general/hello.yml +8 -0
  32. rasa/cli/run.py +1 -5
  33. rasa/cli/shell.py +1 -0
  34. rasa/cli/train.py +1 -0
  35. rasa/cli/validation/bot_config.py +9 -2
  36. rasa/core/available_agents.py +65 -55
  37. rasa/core/config/available_endpoints.py +6 -3
  38. rasa/core/config/configuration.py +36 -1
  39. rasa/core/policies/flows/agent_executor.py +16 -8
  40. rasa/dialogue_understanding/commands/start_flow_command.py +10 -3
  41. rasa/dialogue_understanding/commands/utils.py +15 -4
  42. rasa/dialogue_understanding/generator/llm_based_command_generator.py +4 -2
  43. rasa/dialogue_understanding/generator/single_step/compact_llm_command_generator.py +4 -4
  44. rasa/dialogue_understanding/generator/single_step/search_ready_llm_command_generator.py +4 -4
  45. rasa/dialogue_understanding/generator/single_step/single_step_based_llm_command_generator.py +2 -2
  46. rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml +22 -20
  47. rasa/dialogue_understanding_test/du_test_runner.py +2 -2
  48. rasa/e2e_test/e2e_test_runner.py +2 -2
  49. rasa/engine/validation.py +6 -2
  50. rasa/shared/agents/auth/auth_strategy/oauth2_auth_strategy.py +10 -4
  51. rasa/shared/agents/auth/constants.py +1 -0
  52. rasa/shared/agents/auth/utils.py +85 -0
  53. rasa/shared/constants.py +3 -0
  54. rasa/shared/core/flows/steps/call.py +2 -2
  55. rasa/shared/utils/llm.py +33 -0
  56. rasa/telemetry.py +3 -3
  57. rasa/utils/pypred.py +7 -0
  58. rasa/validator.py +127 -2
  59. rasa/version.py +1 -1
  60. {rasa_pro-3.14.0rc2.dist-info → rasa_pro-3.14.0rc4.dist-info}/METADATA +19 -7
  61. {rasa_pro-3.14.0rc2.dist-info → rasa_pro-3.14.0rc4.dist-info}/RECORD +81 -71
  62. rasa/cli/project_templates/telco/tests/e2e_test_cases/network/solve_internet_issue.yml +0 -57
  63. /rasa/cli/project_templates/{finance/tests/e2e_test_cases → basic/tests/e2e_test_cases/without_stub}/general/hello.yml +0 -0
  64. /rasa/cli/project_templates/finance/tests/e2e_test_cases/{accounts → without_stub/accounts}/check_balance.yml +0 -0
  65. /rasa/cli/project_templates/finance/tests/e2e_test_cases/{accounts → without_stub/accounts}/download_statements.yml +0 -0
  66. /rasa/cli/project_templates/finance/tests/e2e_test_cases/{cards → without_stub/cards}/block_card.yml +0 -0
  67. /rasa/cli/project_templates/finance/tests/e2e_test_cases/{general → without_stub/general}/bot_challenge.yml +0 -0
  68. /rasa/cli/project_templates/finance/tests/e2e_test_cases/{general → without_stub/general}/feedback.yml +0 -0
  69. /rasa/cli/project_templates/finance/tests/e2e_test_cases/{general → without_stub/general}/goodbye.yml +0 -0
  70. /rasa/cli/project_templates/{telco/tests/e2e_test_cases → finance/tests/e2e_test_cases/without_stub}/general/hello.yml +0 -0
  71. /rasa/cli/project_templates/finance/tests/e2e_test_cases/{general → without_stub/general}/human_handoff.yml +0 -0
  72. /rasa/cli/project_templates/finance/tests/e2e_test_cases/{general → without_stub/general}/patterns.yml +0 -0
  73. /rasa/cli/project_templates/finance/tests/e2e_test_cases/{transfers → without_stub/transfers}/transfer_money.yml +0 -0
  74. /rasa/cli/project_templates/telco/tests/e2e_test_cases/{billing → without_stub/billing}/understand_bill.yml +0 -0
  75. /rasa/cli/project_templates/telco/tests/e2e_test_cases/{general → without_stub/general}/bot_challenge.yml +0 -0
  76. /rasa/cli/project_templates/telco/tests/e2e_test_cases/{general → without_stub/general}/feedback.yml +0 -0
  77. /rasa/cli/project_templates/telco/tests/e2e_test_cases/{general → without_stub/general}/goodbye.yml +0 -0
  78. /rasa/cli/project_templates/telco/tests/e2e_test_cases/{general → without_stub/general}/human_handoff.yml +0 -0
  79. /rasa/cli/project_templates/telco/tests/e2e_test_cases/{general → without_stub/general}/patterns.yml +0 -0
  80. {rasa_pro-3.14.0rc2.dist-info → rasa_pro-3.14.0rc4.dist-info}/NOTICE +0 -0
  81. {rasa_pro-3.14.0rc2.dist-info → rasa_pro-3.14.0rc4.dist-info}/WHEEL +0 -0
  82. {rasa_pro-3.14.0rc2.dist-info → rasa_pro-3.14.0rc4.dist-info}/entry_points.txt +0 -0
@@ -86,9 +86,9 @@ and panels.
86
86
  ***
87
87
 
88
88
  ## Layout
89
- - **Left Panel Copilot Chat:** Where the user asks you for help, guidance, or troubleshooting.
90
- - **Center Panel Playground Preview:** Main workspace with Chat Mode (default) or Inspect Mode.
91
- - **Right Panel Inspector Visualization:** Real-time diagram of conversation logic (only in Inspect Mode).
89
+ - **Left Panel - Copilot Chat:** Where the user asks you for help, guidance, or troubleshooting.
90
+ - **Center Panel - Playground Preview:** Main workspace with Chat Mode (default) or Inspect Mode.
91
+ - **Right Panel - Inspector Visualization:** Real-time diagram of conversation logic (only in Inspect Mode).
92
92
 
93
93
  ***
94
94
 
@@ -140,19 +140,40 @@ response.
140
140
 
141
141
  ***
142
142
 
143
+ ### 5. Sharing Attachments
144
+
145
+ Users can share additional context with Copilot by clicking the "Ask Copilot" button
146
+ while "Inspect Mode" is open. This sends selected conversation state as an attachment
147
+ together with their question.
148
+
149
+ The attachments are typically tracker events, which can be:
150
+ - User messages - what the user typed or said.
151
+ - Assistant messages - what the assistant responded with.
152
+ - Actions - operations the assistant executed, including how they were chosen.
153
+ - Slots - what slots were set or updated during the exchange.
154
+ - Flows - when a flow starts, is interrupted, resumes, or completes.
155
+ - Sessions - the beginning or end of a conversation session.
156
+
157
+ **Tip:** Encourage users to use attachments to get to know the Rasa workings better. If
158
+ user is facing issues, these attachments will give Copilot a ground-truth trace of what
159
+ actually happened in the assistant, making attachments a powerful tool for debugging.
160
+
161
+ ***
162
+
143
163
  ## Rasa CLI to Hello Rasa UI Mapping
144
164
 
145
165
  Map available features to **Rasa CLI** to the **Hello Rasa Action**, so users see
146
166
  continuity.
147
167
 
148
- | Feature | Rasa CLI | Hello Rasa Action |
149
- |----------------------|-----------------------|---------------------------|
150
- | Train assistant | `rasa train` | Apply Changes |
151
- | Test conversation | `rasa shell` | Chat Mode |
152
- | Debug conversation | `rasa shell --debug` | Inspect Mode |
153
- | Run custom actions | `rasa run actions` | Code Mode + Apply Changes |
154
- | Export project files | — | Download button |
155
- | Edit project files | — | Code Mode |
168
+ | Feature | Rasa CLI | Hello Rasa Action |
169
+ |--------------------------|-----------------------|------------------------------------|
170
+ | Train assistant | `rasa train` | Apply Changes |
171
+ | Test conversation | `rasa shell` | Chat Mode |
172
+ | Debug conversation | `rasa shell --debug` | Inspect Mode |
173
+ | Run custom actions | `rasa run actions` | Code Mode + Apply Changes |
174
+ | Export project files | — | Download button |
175
+ | Edit project files | — | Code Mode |
176
+ | Share conversation trace | `rasa shell --debug` | Ask Copilot button in Inspect Mode |
156
177
 
157
178
  **Note:** Ignore any references to *Rasa Studio*.
158
179
 
@@ -181,7 +202,7 @@ code change, or reference). It should be:
181
202
  - **Friendly, but Focused**: Use a warm and conversational style, but stay precise and technically correct.
182
203
  - **Confident & Trustworthy**: Present guidance as clear and reliable; avoid hedging unless there's genuine uncertainty (in which case, ask clarifying questions).
183
204
  - **Brand-Positive**: Highlight the strengths of **Rasa** and **Hello Rasa**, when appropriate, framing them as powerful and easy to use.
184
- - **Code-style references** You MUST wrap all flow names, slot names, variables, and any part of the user's code in backticks (e.g., `slot_name`, `flow_name`, `variable_name`). This is mandatory formatting.
205
+ - **Code-style references**: You MUST wrap all flow names, slot names, variables, and any part of the user's code in backticks (e.g., `slot_name`, `flow_name`, `variable_name`). This is mandatory formatting.
185
206
 
186
207
  ***
187
208
 
@@ -1,30 +1,33 @@
1
- # Context Available to You
2
- Treat everything **below** as **current-turn context** to apply under those rules. You
3
- have access to:
1
+ # Context Priority
2
+ When interpreting user questions (especially vague ones like *"What's this?"*), follow
3
+ this order of priority:
4
4
 
5
- {% if current_conversation %}
6
- ## Current Conversation and Conversation State between the user and the assistant
5
+ | Priority | Context Source | Usage |
6
+ |----------|----------------|-------|
7
+ | 1 | **Attachments** | Highest priority. If attachments exist, assume the user's question refers to them. Always ground explanations in attachment content first. |
8
+ | 2 | **Assistant State / Current Conversation** | Use this when attachments are not present. Supplement attachment knowledge with state info if needed. |
9
+ | 3 | **Assistant Files** | Use when neither attachments nor state provide enough context. |
10
+ | 4 | **Documentation Results** | Use to explain Rasa features and validate facts. Must always be cited inline. |
11
+ | 5 | **Assistant Logs** | Lowest priority. Use only if directly relevant to the user’s issue. |
7
12
 
8
- **Conversation History:**
9
- ```json
10
- {{ current_conversation }}
11
- ```
13
+ ---
12
14
 
13
- **Assistant's State:**
14
- ```json
15
- {{ current_state }}
16
- ```
17
- {% endif %}
15
+ # Remember!
16
+ - Focus on accessibility and efficiency. Give guidance users can act on right away.
17
+ - Keep answers concise, cut any fluff.
18
+ - Never impersonate or role-play as the assistant being built. You are the **Rasa assistant development expert**.
19
+ - Cite documentation inline frequently — every factual statement about Rasa features, concepts, or capabilities MUST be cited.
20
+ - Only cite from current turn documentation — never from previous conversation turns.
21
+ - NEVER add a separate list of URLs or sources — only use inline citations.
22
+ - NEVER start your response with a ``` or """ or any other quoting characters.
18
23
 
19
- {% if assistant_logs %}
20
- ***
24
+ ---
21
25
 
22
- ## Assistant Logs
23
- ```
24
- {{ assistant_logs }}
25
- ```
26
- {% endif %}
26
+ # Context Available to You
27
+ Treat everything **below** as context for the user's current request.
28
+ You have access to:
27
29
 
30
+ ***
28
31
 
29
32
  ## Assistant Files (Configuration, Domain, Flows)
30
33
  {% if assistant_files %}
@@ -51,11 +54,38 @@ numbers (1, 2, 3, etc.) for inline citations:
51
54
  No relevant documentation source found.
52
55
  {% endif %}
53
56
 
54
- # Remember!
55
- - Focus on accessibility and efficiency. Give guidance users can act on right away.
56
- - Keep answers concise, cut any fluff.
57
- - Never impersonate or role-play as the assistant being built. You are the **Rasa assistant development expert**.
58
- - Cite documentation inline frequently - every factual statement about Rasa features, concepts, or capabilities MUST be cited.
59
- - Only cite from current turn documentation - never from previous conversation turns
60
- - NEVER add a separate list of URLs or sources - only use inline citations.
61
- - NEVER start your response with a ``` or """ or any other quoting characters.
57
+ {% if current_conversation %}
58
+ ***
59
+
60
+ ## Current Conversation and Conversation State between the user and the assistant
61
+
62
+ **Conversation History:**
63
+ ```json
64
+ {{ current_conversation }}
65
+ ```
66
+
67
+ **Assistant's State:**
68
+ ```json
69
+ {{ current_state }}
70
+ ```
71
+ {% endif %}
72
+
73
+ {% if assistant_logs %}
74
+ ***
75
+
76
+ ## Assistant Logs
77
+ ```
78
+ {{ assistant_logs }}
79
+ ```
80
+ {% endif %}
81
+
82
+ {% if attachments %}
83
+ ***
84
+
85
+ ## Attachments
86
+ The user clicked **Ask Copilot** in the **Inspect Mode** and included additional context
87
+ as attachments:
88
+ ```json
89
+ {{ attachments }}
90
+ ```
91
+ {% endif %}
@@ -8,6 +8,7 @@ import structlog
8
8
  from rasa import telemetry
9
9
  from rasa.builder.copilot.constants import COPILOT_SEGMENT_WRITE_KEY_ENV_VAR
10
10
  from rasa.builder.copilot.copilot_response_handler import CopilotResponseHandler
11
+ from rasa.builder.copilot.models import EventContent
11
12
  from rasa.builder.document_retrieval.models import Document
12
13
  from rasa.telemetry import (
13
14
  SEGMENT_TRACK_ENDPOINT,
@@ -100,6 +101,7 @@ class CopilotTelemetry:
100
101
  system_message: Optional[dict[str, Any]] = None,
101
102
  chat_history: Optional[list[dict[str, Any]]] = None,
102
103
  last_user_message: Optional[str] = None,
104
+ tracker_event_attachments: Optional[list[dict[str, Any]]] = None,
103
105
  ) -> None:
104
106
  """Track a copilot message in the conversation.
105
107
 
@@ -115,6 +117,7 @@ class CopilotTelemetry:
115
117
  system_message: The system message used (optional).
116
118
  chat_history: The chat history messages used (optional).
117
119
  last_user_message: The last user message used (optional).
120
+ tracker_event_attachments: The tracker event attachments used (optional).
118
121
  """
119
122
  structlogger.debug("builder.telemetry.log_copilot_turn", text=text)
120
123
 
@@ -136,6 +139,7 @@ class CopilotTelemetry:
136
139
  "total_tokens": total_tokens,
137
140
  "chat_history": chat_history,
138
141
  "last_user_message": last_user_message,
142
+ "tracker_event_attachments": tracker_event_attachments,
139
143
  "timestamp": dt.datetime.utcnow().isoformat(),
140
144
  }
141
145
 
@@ -194,6 +198,7 @@ class CopilotTelemetry:
194
198
  system_message: dict[str, Any],
195
199
  chat_history: list[dict[str, Any]],
196
200
  last_user_message: Optional[str],
201
+ tracker_event_attachments: list[EventContent],
197
202
  ) -> None:
198
203
  """Log a copilot message from the response handler.
199
204
 
@@ -223,4 +228,7 @@ class CopilotTelemetry:
223
228
  system_message=system_message,
224
229
  chat_history=chat_history,
225
230
  last_user_message=last_user_message,
231
+ tracker_event_attachments=[
232
+ attachment.model_dump() for attachment in tracker_event_attachments
233
+ ],
226
234
  )
@@ -36,3 +36,6 @@ responses:
36
36
  guardrail_blocked_project_response: |
37
37
  Your Copilot access has been temporarily blocked due to repeated policy violations.
38
38
  If you believe this is an error or would like to request a review, please reach out to support@rasa.com.
39
+
40
+ training_success_response: |
41
+ Your changes have been saved successfully.
@@ -0,0 +1,56 @@
1
+ welcome_messages:
2
+ copilot_intro: |
3
+ 👋 Welcome to Hello Rasa!
4
+
5
+ I'm your **Copilot** — here to help you explore Rasa and start customizing your agent.
6
+ You can ask me how your agent works, how to add new skills, or how to connect integrations.
7
+
8
+ finance: |
9
+ 👋 Welcome to Hello Rasa!
10
+
11
+ I'm your **Copilot** — here to help you explore Rasa and start customizing your agent.
12
+ You can ask me how your agent works, how to add new skills, or how to connect integrations.
13
+
14
+ Your **Banking Agent template** is now live.
15
+
16
+ ### ▶️ **First step: try it out**
17
+ Ask your agent (in the chat preview on the right):
18
+ - *What's my current balance?*
19
+ - *Send 100 dollars to James.*
20
+
21
+ telco: |
22
+ 👋 Welcome to Hello Rasa!
23
+
24
+ I'm your **Copilot** — here to help you explore Rasa and start customizing your agent.
25
+ You can ask me how your agent works, how to add new skills, or how to connect integrations.
26
+
27
+ Your **Telecom Support Agent template** is now live.
28
+
29
+ ### ▶️ **First step: try it out**
30
+ Ask your agent (in the chat preview on the right):
31
+ - *Why is my internet slow?*
32
+ - *How do i reboot my router?*
33
+
34
+ basic: |
35
+ 👋 Welcome to Hello Rasa!
36
+
37
+ I'm your **Copilot** — here to help you explore Rasa and start customizing your agent.
38
+ You can ask me how your agent works, how to add new skills, or how to connect integrations.
39
+
40
+ Your **Starter Agent template** is now live.
41
+
42
+ ### ▶️ **First step: try it out**
43
+ Ask your agent (in the chat preview on the right):
44
+ - *What can you do?*
45
+ - *Can I talk to a human?*
46
+
47
+ prompt_to_bot: |
48
+ 👋 Welcome to Hello Rasa!
49
+
50
+ I'm your **Copilot** — here to help you explore Rasa and start customizing your agent.
51
+ You can ask me how your agent works, how to add new skills, or how to connect integrations.
52
+
53
+ Your custom agent has been created and trained successfully.
54
+
55
+ ### ▶️ **First step: try it out**
56
+ Test your agent in the chat preview on the right to see how it responds to your users.
rasa/builder/jobs.py CHANGED
@@ -4,6 +4,13 @@ import structlog
4
4
  from sanic import Sanic
5
5
 
6
6
  from rasa.builder import config
7
+ from rasa.builder.copilot.constants import (
8
+ PROMPT_TO_BOT_KEY,
9
+ )
10
+ from rasa.builder.copilot.copilot_templated_message_provider import (
11
+ load_copilot_handler_default_responses,
12
+ load_copilot_welcome_messages,
13
+ )
7
14
  from rasa.builder.copilot.models import (
8
15
  CopilotContext,
9
16
  FileContent,
@@ -80,11 +87,20 @@ async def run_prompt_to_bot_job(
80
87
  update_agent(agent, app)
81
88
  await push_job_status_event(job, JobStatus.train_success)
82
89
 
90
+ # 3. Create copilot welcome message job
91
+ copilot_welcome_job = job_manager.create_job()
92
+ app.add_task(run_copilot_welcome_message_job(app, copilot_welcome_job))
93
+
83
94
  structlogger.info(
84
95
  "bot_builder_service.prompt_to_bot.success",
85
96
  files_generated=list(bot_files.keys()),
97
+ copilot_welcome_job_id=copilot_welcome_job.id,
98
+ )
99
+ await push_job_status_event(
100
+ job=job,
101
+ status=JobStatus.done,
102
+ payload={"copilot_welcome_job_id": copilot_welcome_job.id},
86
103
  )
87
- await push_job_status_event(job, JobStatus.done)
88
104
  job_manager.mark_done(job)
89
105
 
90
106
  except TrainingError as exc:
@@ -165,12 +181,23 @@ async def run_template_to_bot_job(
165
181
  update_agent(agent, app)
166
182
  await push_job_status_event(job, JobStatus.train_success)
167
183
 
168
- # 3) Done
184
+ # 3) Create copilot welcome message job
185
+ copilot_welcome_job = job_manager.create_job()
186
+ app.add_task(
187
+ run_copilot_welcome_message_job(app, copilot_welcome_job, template_name)
188
+ )
189
+
190
+ # 4) Done - include welcome job ID in payload
169
191
  structlogger.info(
170
192
  "bot_builder_service.template_to_bot.success",
171
193
  files_generated=list(bot_files.keys()),
194
+ copilot_welcome_job_id=copilot_welcome_job.id,
195
+ )
196
+ await push_job_status_event(
197
+ job=job,
198
+ status=JobStatus.done,
199
+ payload={"copilot_welcome_job_id": copilot_welcome_job.id},
172
200
  )
173
- await push_job_status_event(job, JobStatus.done)
174
201
  job_manager.mark_done(job)
175
202
 
176
203
  except TrainingError as exc:
@@ -256,8 +283,19 @@ async def run_replace_all_files_job(
256
283
  update_agent(agent, app)
257
284
  await push_job_status_event(job, JobStatus.train_success)
258
285
 
259
- # Send final done event
260
- await push_job_status_event(job, JobStatus.done)
286
+ # Send final done event with copilot training success response job ID
287
+ copilot_training_success_job = job_manager.create_job()
288
+ app.add_task(
289
+ run_copilot_training_success_job(app, copilot_training_success_job)
290
+ )
291
+
292
+ await push_job_status_event(
293
+ job=job,
294
+ status=JobStatus.done,
295
+ payload={
296
+ "copilot_training_success_job_id": copilot_training_success_job.id
297
+ },
298
+ )
261
299
  job_manager.mark_done(job)
262
300
 
263
301
  except ValidationError as exc:
@@ -450,3 +488,122 @@ async def run_copilot_training_error_analysis_job(
450
488
  job, JobStatus.copilot_analysis_error, message=str(exc)
451
489
  )
452
490
  job_manager.mark_done(job, error=str(exc))
491
+
492
+
493
+ async def run_copilot_welcome_message_job(
494
+ app: "Sanic",
495
+ job: JobInfo,
496
+ template_name: Optional[ProjectTemplateName] = None,
497
+ ) -> None:
498
+ """Run the welcome message job in the background.
499
+
500
+ This job sends a welcome message to the user after successful bot creation.
501
+ For template-based bots, it sends a predefined message.
502
+ For prompt-based bots, it can be extended to stream generated messages.
503
+
504
+ Args:
505
+ app: The Sanic application instance.
506
+ job: The job information instance.
507
+ template_name: The template name for template-based bots, None for prompt-based.
508
+ """
509
+ try:
510
+ # Load welcome messages from YAML
511
+ welcome_messages = load_copilot_welcome_messages()
512
+
513
+ # Get the appropriate welcome message
514
+ if template_name:
515
+ welcome_message = welcome_messages.get(
516
+ template_name.value,
517
+ welcome_messages.get(PROMPT_TO_BOT_KEY),
518
+ )
519
+ else:
520
+ welcome_message = welcome_messages.get(PROMPT_TO_BOT_KEY)
521
+
522
+ # Send the welcome message as a single event
523
+ await push_job_status_event(
524
+ job,
525
+ JobStatus.copilot_welcome_message,
526
+ payload={
527
+ "content": welcome_message,
528
+ "response_category": "copilot",
529
+ "completeness": "complete",
530
+ },
531
+ )
532
+
533
+ # Mark job as done
534
+ await push_job_status_event(job, JobStatus.done)
535
+ job_manager.mark_done(job)
536
+
537
+ structlogger.info(
538
+ "copilot_welcome_message_job.success",
539
+ job_id=job.id,
540
+ template=template_name.value if template_name else PROMPT_TO_BOT_KEY,
541
+ )
542
+
543
+ except Exception as exc:
544
+ structlogger.exception(
545
+ "welcome_message_job.error",
546
+ job_id=job.id,
547
+ error=str(exc),
548
+ )
549
+ await push_job_status_event(job, JobStatus.error, message=str(exc))
550
+ job_manager.mark_done(job, error=str(exc))
551
+
552
+
553
+ async def run_copilot_training_success_job(
554
+ app: "Sanic",
555
+ job: JobInfo,
556
+ ) -> None:
557
+ """Run the training success job in the background.
558
+
559
+ This job sends a training success message to the user after successful bot training.
560
+
561
+ Args:
562
+ app: The Sanic application instance.
563
+ job: The job information instance.
564
+ """
565
+ try:
566
+ # Load copilot default messages from YAML
567
+ internal_messages = load_copilot_handler_default_responses()
568
+
569
+ # Get the appropriate training success message
570
+ training_success_message = internal_messages.get("training_success_response")
571
+
572
+ # Send the training success message
573
+ await push_job_status_event(
574
+ job,
575
+ JobStatus.train_success_message,
576
+ payload={
577
+ "content": training_success_message,
578
+ "response_category": "copilot",
579
+ "completeness": "complete",
580
+ },
581
+ )
582
+
583
+ # Send the training success category
584
+ await push_job_status_event(
585
+ job,
586
+ JobStatus.train_success_message,
587
+ payload={
588
+ "response_category": "copilot_training_success",
589
+ "completeness": "complete",
590
+ },
591
+ )
592
+
593
+ # Mark job as done
594
+ await push_job_status_event(job, JobStatus.done)
595
+ job_manager.mark_done(job)
596
+
597
+ structlogger.info(
598
+ "copilot_training_success_job.success",
599
+ job_id=job.id,
600
+ )
601
+
602
+ except Exception as exc:
603
+ structlogger.exception(
604
+ "copilot_training_success_job.error",
605
+ job_id=job.id,
606
+ error=str(exc),
607
+ )
608
+ await push_job_status_event(job, JobStatus.error, message=str(exc))
609
+ job_manager.mark_done(job, error=str(exc))
rasa/builder/models.py CHANGED
@@ -191,6 +191,7 @@ class JobStatus(str, Enum):
191
191
 
192
192
  training = "training"
193
193
  train_success = "train_success"
194
+ train_success_message = "train_success_message"
194
195
  train_error = "train_error"
195
196
 
196
197
  validating = "validating"
@@ -202,6 +203,8 @@ class JobStatus(str, Enum):
202
203
  copilot_analysis_success = "copilot_analysis_success"
203
204
  copilot_analysis_error = "copilot_analysis_error"
204
205
 
206
+ copilot_welcome_message = "copilot_welcome_message"
207
+
205
208
 
206
209
  class JobCreateResponse(BaseModel):
207
210
  job_id: str = Field(...)
rasa/builder/service.py CHANGED
@@ -1176,6 +1176,7 @@ async def copilot(request: Request) -> None:
1176
1176
  if (req.last_message and req.last_message.role == ROLE_USER)
1177
1177
  else None
1178
1178
  ),
1179
+ tracker_event_attachments=generation_context.tracker_event_attachments,
1179
1180
  **copilot_client.usage_statistics.model_dump(),
1180
1181
  )
1181
1182
  )
@@ -214,6 +214,7 @@ def execute_dialogue_understanding_tests(args: argparse.Namespace) -> None:
214
214
 
215
215
  # initialization of endpoints
216
216
  endpoints = set_up_available_endpoints(args)
217
+ Configuration.initialise_sub_agents(args.sub_agents)
217
218
 
218
219
  # set up the test runner, e.g. start the agent
219
220
  try:
rasa/cli/e2e_test.py CHANGED
@@ -160,6 +160,7 @@ def execute_e2e_tests(args: argparse.Namespace) -> None:
160
160
  endpoints = Configuration.initialise_endpoints(
161
161
  endpoints_path=EndpointsConfigPath.validate(args.endpoints)
162
162
  ).endpoints
163
+ Configuration.initialise_sub_agents(args.sub_agents)
163
164
 
164
165
  # Ignore all endpoints apart from action server, model, nlu and nlg
165
166
  # to ensure InMemoryTrackerStore is being used instead of production
rasa/cli/inspect.py CHANGED
@@ -93,6 +93,7 @@ def inspect(args: argparse.Namespace) -> None:
93
93
  # it can be used safely throughout the codebase with
94
94
  # `Configuration.get_instance().endpoints`
95
95
  Configuration.initialise_endpoints(endpoints_path=Path(args.endpoints))
96
+ Configuration.initialise_sub_agents(args.sub_agents)
96
97
 
97
98
  try:
98
99
  model = get_local_model(model)
@@ -0,0 +1,46 @@
1
+ test_cases:
2
+ - test_case: positive feedback
3
+ steps:
4
+ - user: "goodbye"
5
+ assertions:
6
+ - flow_started: "goodbye_flow"
7
+ - bot_uttered:
8
+ utter_name: "utter_goodbye"
9
+ - flow_started: "leave_feedback"
10
+ - bot_uttered:
11
+ utter_name: "utter_ask_feedback_rating"
12
+ buttons:
13
+ - title: "👍 Great"
14
+ payload: "/SetSlots(feedback_rating=thumbs_up)"
15
+ - title: "👎 Could be better"
16
+ payload: "/SetSlots(feedback_rating=thumbs_down)"
17
+ - user: "/SetSlots(feedback_rating=thumbs_up)"
18
+ assertions:
19
+ - slot_was_set:
20
+ - name: "feedback_rating"
21
+ value: "thumbs_up"
22
+ - bot_uttered:
23
+ utter_name: "utter_thankyou_positive"
24
+ #
25
+ - test_case: negative feedback
26
+ steps:
27
+ - user: "goodbye"
28
+ assertions:
29
+ - flow_started: "goodbye_flow"
30
+ - bot_uttered:
31
+ utter_name: "utter_goodbye"
32
+ - flow_started: "leave_feedback"
33
+ - bot_uttered:
34
+ utter_name: "utter_ask_feedback_rating"
35
+ buttons:
36
+ - title: "👍 Great"
37
+ payload: "/SetSlots(feedback_rating=thumbs_up)"
38
+ - title: "👎 Could be better"
39
+ payload: "/SetSlots(feedback_rating=thumbs_down)"
40
+ - user: "/SetSlots(feedback_rating=thumbs_down)"
41
+ assertions:
42
+ - slot_was_set:
43
+ - name: "feedback_rating"
44
+ value: "thumbs_down"
45
+ - bot_uttered:
46
+ utter_name: "utter_thankyou_negative"
@@ -0,0 +1,9 @@
1
+ test_cases:
2
+ - test_case: goodbye
3
+ steps:
4
+ - user: "goodbye"
5
+ assertions:
6
+ - flow_started: "goodbye_flow"
7
+ - bot_uttered:
8
+ utter_name: "utter_goodbye"
9
+ - flow_started: "leave_feedback"
@@ -0,0 +1,8 @@
1
+ test_cases:
2
+ - test_case: help
3
+ steps:
4
+ - user: "help"
5
+ assertions:
6
+ - flow_started: "help"
7
+ - bot_uttered:
8
+ utter_name: "utter_what_can_you_do"
@@ -0,0 +1,41 @@
1
+ test_cases:
2
+ - test_case: human handoff happy path
3
+ steps:
4
+ - user: "I would like to speak with a human"
5
+ assertions:
6
+ - flow_started: "human_handoff"
7
+ - bot_uttered:
8
+ utter_name: "utter_ask_confirm_human_handoff"
9
+ buttons:
10
+ - payload: "/SetSlots(confirm_human_handoff=Yes)"
11
+ title: "Yes"
12
+ - payload: "/SetSlots(confirm_human_handoff=No)"
13
+ title: "No"
14
+ - user: "/SetSlots(confirm_human_handoff=Yes)"
15
+ assertions:
16
+ - slot_was_set:
17
+ - name: "confirm_human_handoff"
18
+ value: "Yes"
19
+ - bot_uttered:
20
+ utter_name: "utter_transferring_to_human"
21
+ - action_executed: action_human_handoff
22
+ # ====================================================>
23
+ - test_case: human handoff unhappy path
24
+ steps:
25
+ - user: "I would like to speak with a human"
26
+ assertions:
27
+ - flow_started: "human_handoff"
28
+ - bot_uttered:
29
+ utter_name: "utter_ask_confirm_human_handoff"
30
+ buttons:
31
+ - payload: "/SetSlots(confirm_human_handoff=Yes)"
32
+ title: "Yes"
33
+ - payload: "/SetSlots(confirm_human_handoff=No)"
34
+ title: "No"
35
+ - user: "/SetSlots(confirm_human_handoff=No)"
36
+ assertions:
37
+ - slot_was_set:
38
+ - name: "confirm_human_handoff"
39
+ value: "No"
40
+ - bot_uttered:
41
+ utter_name: "utter_human_handoff_cancelled"