rasa-pro 3.13.7__py3-none-any.whl → 3.14.0.dev2__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/__init__.py +0 -0
- rasa/agents/agent_factory.py +122 -0
- rasa/agents/agent_manager.py +162 -0
- rasa/agents/constants.py +31 -0
- rasa/agents/core/__init__.py +0 -0
- rasa/agents/core/agent_protocol.py +108 -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/__init__.py +0 -0
- rasa/agents/protocol/a2a/a2a_agent.py +51 -0
- rasa/agents/protocol/mcp/__init__.py +0 -0
- rasa/agents/protocol/mcp/mcp_base_agent.py +697 -0
- rasa/agents/protocol/mcp/mcp_open_agent.py +275 -0
- rasa/agents/protocol/mcp/mcp_task_agent.py +447 -0
- rasa/agents/schemas/__init__.py +6 -0
- rasa/agents/schemas/agent_input.py +24 -0
- rasa/agents/schemas/agent_output.py +26 -0
- rasa/agents/schemas/agent_tool_result.py +51 -0
- rasa/agents/schemas/agent_tool_schema.py +112 -0
- rasa/agents/templates/__init__.py +0 -0
- rasa/agents/templates/mcp_open_agent_prompt_template.jinja2 +15 -0
- rasa/agents/templates/mcp_task_agent_prompt_template.jinja2 +13 -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/run.py +4 -0
- rasa/cli/shell.py +3 -0
- rasa/cli/train.py +2 -2
- rasa/constants.py +6 -0
- rasa/core/actions/action.py +69 -39
- rasa/core/actions/action_run_slot_rejections.py +1 -1
- rasa/core/agent.py +16 -0
- rasa/core/available_agents.py +196 -0
- rasa/core/available_endpoints.py +30 -0
- rasa/core/channels/development_inspector.py +47 -14
- rasa/core/channels/inspector/dist/assets/{arc-0b11fe30.js → arc-2e78c586.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{blockDiagram-38ab4fdb-9eef30a7.js → blockDiagram-38ab4fdb-806b712e.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{c4Diagram-3d4e48cf-03e94f28.js → c4Diagram-3d4e48cf-0745efa9.js} +1 -1
- rasa/core/channels/inspector/dist/assets/channel-c436ca7c.js +1 -0
- rasa/core/channels/inspector/dist/assets/{classDiagram-70f12bd4-95c09eba.js → classDiagram-70f12bd4-7bd1082b.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{classDiagram-v2-f2320105-38e8446c.js → classDiagram-v2-f2320105-d937ba49.js} +1 -1
- rasa/core/channels/inspector/dist/assets/clone-50dd656b.js +1 -0
- rasa/core/channels/inspector/dist/assets/{createText-2e5e7dd3-57dc3038.js → createText-2e5e7dd3-a2a564ca.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{edges-e0da2a9e-4bac0545.js → edges-e0da2a9e-b5256940.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{erDiagram-9861fffd-81795c90.js → erDiagram-9861fffd-e6883ad2.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{flowDb-956e92f1-89489ae6.js → flowDb-956e92f1-e576fc02.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{flowDiagram-66a62f08-cd152627.js → flowDiagram-66a62f08-2e298d01.js} +1 -1
- rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-2b2aeaf8.js +1 -0
- rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-4a651766-3da369bc.js → flowchart-elk-definition-4a651766-dd7b150a.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{ganttDiagram-c361ad54-85ec16f8.js → ganttDiagram-c361ad54-5b79575c.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-72cf32ee-495bc140.js → gitGraphDiagram-72cf32ee-3016f40a.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{graph-1ec4d266.js → graph-3e19170f.js} +1 -1
- rasa/core/channels/inspector/dist/assets/index-1bd9135e.js +1353 -0
- rasa/core/channels/inspector/dist/assets/{index-3862675e-0a0e97c9.js → index-3862675e-eb9c86de.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{infoDiagram-f8f76790-4d54bcde.js → infoDiagram-f8f76790-b4280e4d.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{journeyDiagram-49397b02-dc097114.js → journeyDiagram-49397b02-556091f8.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{layout-1a08981e.js → layout-08436411.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{line-95f7f1d3.js → line-683c4f3b.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{linear-97e69543.js → linear-cee6d791.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{mindmap-definition-fc14e90a-8c71ff03.js → mindmap-definition-fc14e90a-a0bf0b1a.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{pieDiagram-8a3498a8-f14c71c7.js → pieDiagram-8a3498a8-3730d5c4.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{quadrantDiagram-120e2f19-f1d3c9ff.js → quadrantDiagram-120e2f19-12a20fed.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{requirementDiagram-deff3bca-bfa2412f.js → requirementDiagram-deff3bca-b9732102.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{sankeyDiagram-04a897e0-53f2c97b.js → sankeyDiagram-04a897e0-a2e72776.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{sequenceDiagram-704730f1-319d7c0e.js → sequenceDiagram-704730f1-8b7a76bb.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{stateDiagram-587899a1-76a09418.js → stateDiagram-587899a1-e65853ac.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-d93cdb3a-a67f15d4.js → stateDiagram-v2-d93cdb3a-6f58a44b.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-6aaf32cf-0654e7c3.js → styles-6aaf32cf-df25b934.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-9a916d00-1394bb9d.js → styles-9a916d00-88357141.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-c10674c1-e4c5bdae.js → styles-c10674c1-d600174d.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{svgDrawCommon-08f97a94-50957104.js → svgDrawCommon-08f97a94-4adc3e0b.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{timeline-definition-85554ec2-b0885a6a.js → timeline-definition-85554ec2-42816fa1.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{xychartDiagram-e933f94c-79e6541a.js → xychartDiagram-e933f94c-621eb66a.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 +53 -7
- rasa/core/channels/inspector/src/components/Chat.tsx +3 -2
- rasa/core/channels/inspector/src/components/DiagramFlow.tsx +1 -1
- rasa/core/channels/inspector/src/components/DialogueStack.tsx +7 -5
- rasa/core/channels/inspector/src/components/LatencyDisplay.tsx +268 -0
- rasa/core/channels/inspector/src/components/LoadingSpinner.tsx +6 -2
- rasa/core/channels/inspector/src/helpers/audio/audiostream.ts +8 -3
- 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 +12 -0
- rasa/core/channels/studio_chat.py +125 -34
- rasa/core/channels/voice_ready/twilio_voice.py +1 -1
- rasa/core/channels/voice_stream/audiocodes.py +9 -6
- rasa/core/channels/voice_stream/browser_audio.py +39 -4
- rasa/core/channels/voice_stream/call_state.py +13 -2
- rasa/core/channels/voice_stream/genesys.py +16 -13
- rasa/core/channels/voice_stream/jambonz.py +13 -11
- rasa/core/channels/voice_stream/twilio_media_streams.py +14 -13
- rasa/core/channels/voice_stream/util.py +11 -1
- rasa/core/channels/voice_stream/voice_channel.py +101 -29
- rasa/core/constants.py +4 -0
- rasa/core/nlg/contextual_response_rephraser.py +11 -7
- rasa/core/nlg/generator.py +21 -5
- rasa/core/nlg/response.py +43 -6
- rasa/core/nlg/translate.py +8 -0
- rasa/core/policies/enterprise_search_policy.py +4 -2
- rasa/core/policies/flow_policy.py +2 -2
- rasa/core/policies/flows/flow_executor.py +374 -35
- rasa/core/policies/flows/mcp_tool_executor.py +240 -0
- rasa/core/processor.py +6 -1
- rasa/core/run.py +8 -1
- 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 +129 -8
- rasa/dialogue_understanding/commands/utils.py +6 -2
- rasa/dialogue_understanding/generator/command_parser.py +4 -0
- rasa/dialogue_understanding/generator/llm_based_command_generator.py +50 -12
- rasa/dialogue_understanding/generator/prompt_templates/agent_command_prompt_v2_claude_3_5_sonnet_20240620_template.jinja2 +61 -0
- rasa/dialogue_understanding/generator/prompt_templates/agent_command_prompt_v2_gpt_4o_2024_11_20_template.jinja2 +61 -0
- 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 +51 -7
- 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 +3 -2
- rasa/dialogue_understanding_test/du_test_runner.py +7 -2
- rasa/dialogue_understanding_test/du_test_schema.yml +3 -3
- rasa/e2e_test/e2e_test_runner.py +5 -0
- rasa/e2e_test/e2e_test_schema.yml +3 -3
- rasa/model_manager/model_api.py +1 -1
- rasa/model_manager/socket_bridge.py +8 -2
- rasa/server.py +10 -0
- rasa/shared/agents/__init__.py +0 -0
- 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 +5 -5
- rasa/shared/core/events.py +319 -0
- rasa/shared/core/flows/flows_list.py +2 -2
- rasa/shared/core/flows/flows_yaml_schema.json +101 -186
- rasa/shared/core/flows/steps/call.py +51 -5
- rasa/shared/core/flows/validation.py +45 -7
- rasa/shared/core/flows/yaml_flows_io.py +3 -3
- rasa/shared/providers/llm/_base_litellm_client.py +39 -7
- 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 +49 -0
- rasa/shared/providers/llm/self_hosted_llm_client.py +8 -4
- rasa/shared/utils/common.py +2 -1
- rasa/shared/utils/llm.py +28 -5
- rasa/shared/utils/mcp/__init__.py +0 -0
- rasa/shared/utils/mcp/server_connection.py +157 -0
- rasa/shared/utils/schemas/events.py +42 -0
- rasa/studio/upload.py +4 -7
- rasa/tracing/instrumentation/instrumentation.py +4 -2
- rasa/utils/common.py +53 -0
- rasa/utils/licensing.py +21 -10
- rasa/utils/plotting.py +1 -1
- rasa/version.py +1 -1
- {rasa_pro-3.13.7.dist-info → rasa_pro-3.14.0.dev2.dist-info}/METADATA +16 -15
- {rasa_pro-3.13.7.dist-info → rasa_pro-3.14.0.dev2.dist-info}/RECORD +175 -138
- rasa/core/channels/inspector/dist/assets/channel-51d02e9e.js +0 -1
- rasa/core/channels/inspector/dist/assets/clone-cc738fa6.js +0 -1
- rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-0c716443.js +0 -1
- rasa/core/channels/inspector/dist/assets/index-c804b295.js +0 -1335
- {rasa_pro-3.13.7.dist-info → rasa_pro-3.14.0.dev2.dist-info}/NOTICE +0 -0
- {rasa_pro-3.13.7.dist-info → rasa_pro-3.14.0.dev2.dist-info}/WHEEL +0 -0
- {rasa_pro-3.13.7.dist-info → rasa_pro-3.14.0.dev2.dist-info}/entry_points.txt +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{Z as zt,_ as ot,X as wt,W as Ft,s as Nt,g as Xt,C as Yt,D as St,a as Ht,b as $t,E as Ut,l as Ct,U as qt,i as jt,d as Gt}from"./index-
|
|
1
|
+
import{Z as zt,_ as ot,X as wt,W as Ft,s as Nt,g as Xt,C as Yt,D as St,a as Ht,b as $t,E as Ut,l as Ct,U as qt,i as jt,d as Gt}from"./index-1bd9135e.js";import{c as Qt}from"./createText-2e5e7dd3-a2a564ca.js";import{i as Kt}from"./init-77b53fdd.js";import{o as Zt}from"./ordinal-ba9b4969.js";import{l as ft}from"./linear-cee6d791.js";import{l as pt}from"./line-683c4f3b.js";import"./array-9f3ba611.js";import"./path-53f90ab3.js";function Jt(e,t,i){e=+e,t=+t,i=(n=arguments.length)<2?(t=e,e=0,1):n<3?1:+i;for(var s=-1,n=Math.max(0,Math.ceil((t-e)/i))|0,o=new Array(n);++s<n;)o[s]=e+s*i;return o}function st(){var e=Zt().unknown(void 0),t=e.domain,i=e.range,s=0,n=1,o,c,f=!1,d=0,R=0,_=.5;delete e.unknown;function A(){var m=t().length,T=n<s,S=T?n:s,P=T?s:n;o=(P-S)/Math.max(1,m-d+R*2),f&&(o=Math.floor(o)),S+=(P-S-o*(m-d))*_,c=o*(1-d),f&&(S=Math.round(S),c=Math.round(c));var p=Jt(m).map(function(C){return S+o*C});return i(T?p.reverse():p)}return e.domain=function(m){return arguments.length?(t(m),A()):t()},e.range=function(m){return arguments.length?([s,n]=m,s=+s,n=+n,A()):[s,n]},e.rangeRound=function(m){return[s,n]=m,s=+s,n=+n,f=!0,A()},e.bandwidth=function(){return c},e.step=function(){return o},e.round=function(m){return arguments.length?(f=!!m,A()):f},e.padding=function(m){return arguments.length?(d=Math.min(1,R=+m),A()):d},e.paddingInner=function(m){return arguments.length?(d=Math.min(1,m),A()):d},e.paddingOuter=function(m){return arguments.length?(R=+m,A()):R},e.align=function(m){return arguments.length?(_=Math.max(0,Math.min(1,m)),A()):_},e.copy=function(){return st(t(),[s,n]).round(f).paddingInner(d).paddingOuter(R).align(_)},Kt.apply(A(),arguments)}var nt=function(){var e=function(V,r,l,u){for(l=l||{},u=V.length;u--;l[V[u]]=r);return l},t=[1,10,12,14,16,18,19,21,23],i=[2,6],s=[1,3],n=[1,5],o=[1,6],c=[1,7],f=[1,5,10,12,14,16,18,19,21,23,34,35,36],d=[1,25],R=[1,26],_=[1,28],A=[1,29],m=[1,30],T=[1,31],S=[1,32],P=[1,33],p=[1,34],C=[1,35],h=[1,36],L=[1,37],z=[1,43],lt=[1,42],ct=[1,47],$=[1,50],w=[1,10,12,14,16,18,19,21,23,34,35,36],Q=[1,10,12,14,16,18,19,21,23,24,26,27,28,34,35,36],E=[1,10,12,14,16,18,19,21,23,24,26,27,28,34,35,36,41,42,43,44,45,46,47,48,49,50],ut=[1,64],K={trace:function(){},yy:{},symbols_:{error:2,start:3,eol:4,XYCHART:5,chartConfig:6,document:7,CHART_ORIENTATION:8,statement:9,title:10,text:11,X_AXIS:12,parseXAxis:13,Y_AXIS:14,parseYAxis:15,LINE:16,plotData:17,BAR:18,acc_title:19,acc_title_value:20,acc_descr:21,acc_descr_value:22,acc_descr_multiline_value:23,SQUARE_BRACES_START:24,commaSeparatedNumbers:25,SQUARE_BRACES_END:26,NUMBER_WITH_DECIMAL:27,COMMA:28,xAxisData:29,bandData:30,ARROW_DELIMITER:31,commaSeparatedTexts:32,yAxisData:33,NEWLINE:34,SEMI:35,EOF:36,alphaNum:37,STR:38,MD_STR:39,alphaNumToken:40,AMP:41,NUM:42,ALPHA:43,PLUS:44,EQUALS:45,MULT:46,DOT:47,BRKT:48,MINUS:49,UNDERSCORE:50,$accept:0,$end:1},terminals_:{2:"error",5:"XYCHART",8:"CHART_ORIENTATION",10:"title",12:"X_AXIS",14:"Y_AXIS",16:"LINE",18:"BAR",19:"acc_title",20:"acc_title_value",21:"acc_descr",22:"acc_descr_value",23:"acc_descr_multiline_value",24:"SQUARE_BRACES_START",26:"SQUARE_BRACES_END",27:"NUMBER_WITH_DECIMAL",28:"COMMA",31:"ARROW_DELIMITER",34:"NEWLINE",35:"SEMI",36:"EOF",38:"STR",39:"MD_STR",41:"AMP",42:"NUM",43:"ALPHA",44:"PLUS",45:"EQUALS",46:"MULT",47:"DOT",48:"BRKT",49:"MINUS",50:"UNDERSCORE"},productions_:[0,[3,2],[3,3],[3,2],[3,1],[6,1],[7,0],[7,2],[9,2],[9,2],[9,2],[9,2],[9,2],[9,3],[9,2],[9,3],[9,2],[9,2],[9,1],[17,3],[25,3],[25,1],[13,1],[13,2],[13,1],[29,1],[29,3],[30,3],[32,3],[32,1],[15,1],[15,2],[15,1],[33,3],[4,1],[4,1],[4,1],[11,1],[11,1],[11,1],[37,1],[37,2],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1]],performAction:function(r,l,u,g,b,a,F){var x=a.length-1;switch(b){case 5:g.setOrientation(a[x]);break;case 9:g.setDiagramTitle(a[x].text.trim());break;case 12:g.setLineData({text:"",type:"text"},a[x]);break;case 13:g.setLineData(a[x-1],a[x]);break;case 14:g.setBarData({text:"",type:"text"},a[x]);break;case 15:g.setBarData(a[x-1],a[x]);break;case 16:this.$=a[x].trim(),g.setAccTitle(this.$);break;case 17:case 18:this.$=a[x].trim(),g.setAccDescription(this.$);break;case 19:this.$=a[x-1];break;case 20:this.$=[Number(a[x-2]),...a[x]];break;case 21:this.$=[Number(a[x])];break;case 22:g.setXAxisTitle(a[x]);break;case 23:g.setXAxisTitle(a[x-1]);break;case 24:g.setXAxisTitle({type:"text",text:""});break;case 25:g.setXAxisBand(a[x]);break;case 26:g.setXAxisRangeData(Number(a[x-2]),Number(a[x]));break;case 27:this.$=a[x-1];break;case 28:this.$=[a[x-2],...a[x]];break;case 29:this.$=[a[x]];break;case 30:g.setYAxisTitle(a[x]);break;case 31:g.setYAxisTitle(a[x-1]);break;case 32:g.setYAxisTitle({type:"text",text:""});break;case 33:g.setYAxisRangeData(Number(a[x-2]),Number(a[x]));break;case 37:this.$={text:a[x],type:"text"};break;case 38:this.$={text:a[x],type:"text"};break;case 39:this.$={text:a[x],type:"markdown"};break;case 40:this.$=a[x];break;case 41:this.$=a[x-1]+""+a[x];break}},table:[e(t,i,{3:1,4:2,7:4,5:s,34:n,35:o,36:c}),{1:[3]},e(t,i,{4:2,7:4,3:8,5:s,34:n,35:o,36:c}),e(t,i,{4:2,7:4,6:9,3:10,5:s,8:[1,11],34:n,35:o,36:c}),{1:[2,4],9:12,10:[1,13],12:[1,14],14:[1,15],16:[1,16],18:[1,17],19:[1,18],21:[1,19],23:[1,20]},e(f,[2,34]),e(f,[2,35]),e(f,[2,36]),{1:[2,1]},e(t,i,{4:2,7:4,3:21,5:s,34:n,35:o,36:c}),{1:[2,3]},e(f,[2,5]),e(t,[2,7],{4:22,34:n,35:o,36:c}),{11:23,37:24,38:d,39:R,40:27,41:_,42:A,43:m,44:T,45:S,46:P,47:p,48:C,49:h,50:L},{11:39,13:38,24:z,27:lt,29:40,30:41,37:24,38:d,39:R,40:27,41:_,42:A,43:m,44:T,45:S,46:P,47:p,48:C,49:h,50:L},{11:45,15:44,27:ct,33:46,37:24,38:d,39:R,40:27,41:_,42:A,43:m,44:T,45:S,46:P,47:p,48:C,49:h,50:L},{11:49,17:48,24:$,37:24,38:d,39:R,40:27,41:_,42:A,43:m,44:T,45:S,46:P,47:p,48:C,49:h,50:L},{11:52,17:51,24:$,37:24,38:d,39:R,40:27,41:_,42:A,43:m,44:T,45:S,46:P,47:p,48:C,49:h,50:L},{20:[1,53]},{22:[1,54]},e(w,[2,18]),{1:[2,2]},e(w,[2,8]),e(w,[2,9]),e(Q,[2,37],{40:55,41:_,42:A,43:m,44:T,45:S,46:P,47:p,48:C,49:h,50:L}),e(Q,[2,38]),e(Q,[2,39]),e(E,[2,40]),e(E,[2,42]),e(E,[2,43]),e(E,[2,44]),e(E,[2,45]),e(E,[2,46]),e(E,[2,47]),e(E,[2,48]),e(E,[2,49]),e(E,[2,50]),e(E,[2,51]),e(w,[2,10]),e(w,[2,22],{30:41,29:56,24:z,27:lt}),e(w,[2,24]),e(w,[2,25]),{31:[1,57]},{11:59,32:58,37:24,38:d,39:R,40:27,41:_,42:A,43:m,44:T,45:S,46:P,47:p,48:C,49:h,50:L},e(w,[2,11]),e(w,[2,30],{33:60,27:ct}),e(w,[2,32]),{31:[1,61]},e(w,[2,12]),{17:62,24:$},{25:63,27:ut},e(w,[2,14]),{17:65,24:$},e(w,[2,16]),e(w,[2,17]),e(E,[2,41]),e(w,[2,23]),{27:[1,66]},{26:[1,67]},{26:[2,29],28:[1,68]},e(w,[2,31]),{27:[1,69]},e(w,[2,13]),{26:[1,70]},{26:[2,21],28:[1,71]},e(w,[2,15]),e(w,[2,26]),e(w,[2,27]),{11:59,32:72,37:24,38:d,39:R,40:27,41:_,42:A,43:m,44:T,45:S,46:P,47:p,48:C,49:h,50:L},e(w,[2,33]),e(w,[2,19]),{25:73,27:ut},{26:[2,28]},{26:[2,20]}],defaultActions:{8:[2,1],10:[2,3],21:[2,2],72:[2,28],73:[2,20]},parseError:function(r,l){if(l.recoverable)this.trace(r);else{var u=new Error(r);throw u.hash=l,u}},parse:function(r){var l=this,u=[0],g=[],b=[null],a=[],F=this.table,x="",U=0,gt=0,Vt=2,xt=1,Wt=a.slice.call(arguments,1),k=Object.create(this.lexer),W={yy:{}};for(var J in this.yy)Object.prototype.hasOwnProperty.call(this.yy,J)&&(W.yy[J]=this.yy[J]);k.setInput(r,W.yy),W.yy.lexer=k,W.yy.parser=this,typeof k.yylloc>"u"&&(k.yylloc={});var tt=k.yylloc;a.push(tt);var Bt=k.options&&k.options.ranges;typeof W.yy.parseError=="function"?this.parseError=W.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Ot(){var I;return I=g.pop()||k.lex()||xt,typeof I!="number"&&(I instanceof Array&&(g=I,I=g.pop()),I=l.symbols_[I]||I),I}for(var D,B,v,it,O={},q,M,dt,j;;){if(B=u[u.length-1],this.defaultActions[B]?v=this.defaultActions[B]:((D===null||typeof D>"u")&&(D=Ot()),v=F[B]&&F[B][D]),typeof v>"u"||!v.length||!v[0]){var et="";j=[];for(q in F[B])this.terminals_[q]&&q>Vt&&j.push("'"+this.terminals_[q]+"'");k.showPosition?et="Parse error on line "+(U+1)+`:
|
|
2
2
|
`+k.showPosition()+`
|
|
3
3
|
Expecting `+j.join(", ")+", got '"+(this.terminals_[D]||D)+"'":et="Parse error on line "+(U+1)+": Unexpected "+(D==xt?"end of input":"'"+(this.terminals_[D]||D)+"'"),this.parseError(et,{text:k.match,token:this.terminals_[D]||D,line:k.yylineno,loc:tt,expected:j})}if(v[0]instanceof Array&&v.length>1)throw new Error("Parse Error: multiple actions possible at state: "+B+", token: "+D);switch(v[0]){case 1:u.push(D),b.push(k.yytext),a.push(k.yylloc),u.push(v[1]),D=null,gt=k.yyleng,x=k.yytext,U=k.yylineno,tt=k.yylloc;break;case 2:if(M=this.productions_[v[1]][1],O.$=b[b.length-M],O._$={first_line:a[a.length-(M||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(M||1)].first_column,last_column:a[a.length-1].last_column},Bt&&(O._$.range=[a[a.length-(M||1)].range[0],a[a.length-1].range[1]]),it=this.performAction.apply(O,[x,gt,U,W.yy,v[1],b,a].concat(Wt)),typeof it<"u")return it;M&&(u=u.slice(0,-1*M*2),b=b.slice(0,-1*M),a=a.slice(0,-1*M)),u.push(this.productions_[v[1]][0]),b.push(O.$),a.push(O._$),dt=F[u[u.length-2]][u[u.length-1]],u.push(dt);break;case 3:return!0}}return!0}},It=function(){var V={EOF:1,parseError:function(l,u){if(this.yy.parser)this.yy.parser.parseError(l,u);else throw new Error(l)},setInput:function(r,l){return this.yy=l||this.yy||{},this._input=r,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var r=this._input[0];this.yytext+=r,this.yyleng++,this.offset++,this.match+=r,this.matched+=r;var l=r.match(/(?:\r\n?|\n).*/g);return l?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),r},unput:function(r){var l=r.length,u=r.split(/(?:\r\n?|\n)/g);this._input=r+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-l),this.offset-=l;var g=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),u.length-1&&(this.yylineno-=u.length-1);var b=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:u?(u.length===g.length?this.yylloc.first_column:0)+g[g.length-u.length].length-u[0].length:this.yylloc.first_column-l},this.options.ranges&&(this.yylloc.range=[b[0],b[0]+this.yyleng-l]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).
|
|
4
4
|
`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},less:function(r){this.unput(this.match.slice(r))},pastInput:function(){var r=this.matched.substr(0,this.matched.length-this.match.length);return(r.length>20?"...":"")+r.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var r=this.match;return r.length<20&&(r+=this._input.substr(0,20-r.length)),(r.substr(0,20)+(r.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var r=this.pastInput(),l=new Array(r.length+1).join("-");return r+this.upcomingInput()+`
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
7
|
<link rel="icon" href="data:image/x-icon;base64,AAABAAEAICAQAAEABADoAgAAFgAAACgAAAAgAAAAQAAAAAEABAAAAAAAAAIAAOwAAADsAAAAEAAAABAAAABxaUwAwoyZAMOJmADBi5kAwoyZAMKMmQDCjJkAwoyZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADQAAAAAAAAAAAAAAAAAACV3AAAAAAAAAAAAAAAAAAYXdwAAAAAAAAAAAAAAAANHd3cAAAAAAAEREREREREXd3d3ERAAAAAHd3d3d3d3d3FXd3dwAAAAB3d3d3d3d3dDB3d3cAAAAAd3IiIiIiIiAAIid3AAAAAHdwAAAAAAAAAAAHdwAAAAB3cAAAAAAAAAAAB3cAAAAAd3AAd3AABnd0AAd3AAAAAHdwAHdwADF3QgAHdwAAAAB3cAB3dTMXcSAAB3cAAAAAd3AAd3dxdxMAAAd3AAAAAHdwAHd3d3dGAAAHdwAAAAB3cAB3dHd3dxUAB3cAAAAAd3AAd3A1F3d3AAd3AAAAAHdwAHdwAANXdwAHdwAAAAB3cAB3cAAAAXcAB3cAAAAAd3AAd3d3d3d3AAd3AAAAAHdwAHd3d3d3dwAHdwAAAAB3cAB3d3d3d3cAB3cAAAAAd3AAAAAAAAAAAAd3AAAAAHdwAAAAAAAAAAAHdwAAAAB3cAAAAAAAAAAAB3cAAAAAd3d3d3d3d3d3d3d3AAAAAHd3d3d3d3d3d3d3dwAAAAB3d3d3d3d3d3d3d3cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///5////4f///8H///8B/8AAAD/AAAA/wAAQP8AAcD/H//4/x//+P8ceDj/HHA4/xwAeP8cAPj/HAD4/xwAOP8cQDj/HHg4/xx+OP8cADj/HAA4/xwAOP8f//j/H//4/x//+P8AAAD/AAAA/wAAAP/////////////////////w==" sizes="32x32">
|
|
8
8
|
<title>Rasa inspector</title>
|
|
9
|
-
<script type="module" crossorigin src="./assets/index-
|
|
9
|
+
<script type="module" crossorigin src="./assets/index-1bd9135e.js"></script>
|
|
10
10
|
<link rel="stylesheet" href="./assets/index-3ee28881.css">
|
|
11
11
|
</head>
|
|
12
12
|
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
const chatDiv = document.getElementById("rasa-chat-widget");
|
|
21
21
|
const websocketUrl = window.location.origin.replace("http", "ws");
|
|
22
22
|
const initialPayload = "/session_start";
|
|
23
|
-
const maxHeight = document.documentElement.scrollHeight -
|
|
23
|
+
const maxHeight = document.documentElement.scrollHeight - 200;
|
|
24
24
|
// 21 and 25 are the rem number we're using for the columns. We add 0.75rem for the padding
|
|
25
25
|
// A potential improvement would be to add a onresize event for both width and height
|
|
26
26
|
let remReference = 21.75;
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
const chatDiv = document.getElementById("rasa-chat-widget");
|
|
19
19
|
const websocketUrl = window.location.origin.replace("http", "ws");
|
|
20
20
|
const initialPayload = "/session_start";
|
|
21
|
-
const maxHeight = document.documentElement.scrollHeight -
|
|
21
|
+
const maxHeight = document.documentElement.scrollHeight - 200;
|
|
22
22
|
// 21 and 25 are the rem number we're using for the columns. We add 0.75rem for the padding
|
|
23
23
|
// A potential improvement would be to add a onresize event for both width and height
|
|
24
24
|
let remReference = 21.75;
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
useColorModeValue,
|
|
6
6
|
useToast,
|
|
7
7
|
} from '@chakra-ui/react'
|
|
8
|
-
import { useEffect, useState } from 'react'
|
|
8
|
+
import { useEffect, useState, useCallback } from 'react'
|
|
9
9
|
import axios from 'axios'
|
|
10
10
|
import { useOurTheme } from './theme'
|
|
11
11
|
import { Welcome } from './components/Welcome'
|
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
} from './helpers/utils'
|
|
24
24
|
import queryString from 'query-string'
|
|
25
25
|
import { Chat } from './components/Chat'
|
|
26
|
+
import { LatencyDisplay } from './components/LatencyDisplay'
|
|
26
27
|
import useWebSocket, { ReadyState } from 'react-use-websocket'
|
|
27
28
|
|
|
28
29
|
export function App() {
|
|
@@ -35,6 +36,7 @@ export function App() {
|
|
|
35
36
|
const [story, setStory] = useState<string>('')
|
|
36
37
|
const [stack, setStack] = useState<Stack[]>([])
|
|
37
38
|
const [frame, setFrame] = useState<SelectedStack | undefined>(undefined)
|
|
39
|
+
const [latency, setLatency] = useState<any>(null)
|
|
38
40
|
|
|
39
41
|
// State to control the visibility of the RecruitmentPanel
|
|
40
42
|
const [showRecruitmentPanel, setShowRecruitmentPanel] = useState(true)
|
|
@@ -127,6 +129,13 @@ export function App() {
|
|
|
127
129
|
!rasaChatSessionId ||
|
|
128
130
|
lastJsonMessage?.sender_id === rasaChatSessionId
|
|
129
131
|
) {
|
|
132
|
+
if (lastJsonMessage.latency) {
|
|
133
|
+
console.log('Latency update:', lastJsonMessage.latency)
|
|
134
|
+
setLatency((prevLatency: any) => ({
|
|
135
|
+
...prevLatency,
|
|
136
|
+
...lastJsonMessage.latency,
|
|
137
|
+
}))
|
|
138
|
+
}
|
|
130
139
|
setSlots(formatSlots(lastJsonMessage.slots))
|
|
131
140
|
setEvents(lastJsonMessage.events)
|
|
132
141
|
const updatedStack = createHistoricalStack(
|
|
@@ -175,6 +184,21 @@ export function App() {
|
|
|
175
184
|
: 'max-content minmax(10rem, 17.5rem) minmax(10rem, auto)',
|
|
176
185
|
gridRowGap: rasaSpace[1],
|
|
177
186
|
}
|
|
187
|
+
const rightColumnSx = {
|
|
188
|
+
height: '100%',
|
|
189
|
+
overflow: 'hidden',
|
|
190
|
+
gridTemplateColumns: '1fr',
|
|
191
|
+
gridTemplateRows: 'max-content 1fr',
|
|
192
|
+
gridRowGap: rasaSpace[1],
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const chatContainerSx = {
|
|
196
|
+
...borderRadiusSx,
|
|
197
|
+
padding: rasaSpace[1],
|
|
198
|
+
bg: useColorModeValue('neutral.50', 'neutral.50'),
|
|
199
|
+
overflow: 'auto', // Allow scrolling for chat
|
|
200
|
+
height: '100%',
|
|
201
|
+
}
|
|
178
202
|
|
|
179
203
|
const onFrameSelected = (stack: Stack) => {
|
|
180
204
|
setFrame({
|
|
@@ -188,8 +212,25 @@ export function App() {
|
|
|
188
212
|
setShowRecruitmentPanel(false)
|
|
189
213
|
}
|
|
190
214
|
|
|
215
|
+
const onLatencyUpdate = useCallback((newLatency: any) => {
|
|
216
|
+
setLatency((prevLatency: any) => ({
|
|
217
|
+
...prevLatency,
|
|
218
|
+
...newLatency,
|
|
219
|
+
}))
|
|
220
|
+
}, [])
|
|
221
|
+
|
|
222
|
+
// Make latency update function available globally for audio stream
|
|
223
|
+
useEffect(() => {
|
|
224
|
+
if (window.location.href.includes('browser_audio')) {
|
|
225
|
+
;(window as any).updateLatency = onLatencyUpdate
|
|
226
|
+
}
|
|
227
|
+
return () => {
|
|
228
|
+
delete (window as any).updateLatency
|
|
229
|
+
}
|
|
230
|
+
}, [onLatencyUpdate])
|
|
231
|
+
|
|
191
232
|
if (!rasaChatSessionId && !window.location.href.includes('socketio'))
|
|
192
|
-
return <LoadingSpinner />
|
|
233
|
+
return <LoadingSpinner onLatencyUpdate={onLatencyUpdate} />
|
|
193
234
|
|
|
194
235
|
return (
|
|
195
236
|
<Grid sx={gridSx}>
|
|
@@ -222,11 +263,16 @@ export function App() {
|
|
|
222
263
|
slots={slots}
|
|
223
264
|
/>
|
|
224
265
|
</GridItem>
|
|
225
|
-
|
|
226
|
-
<
|
|
227
|
-
<
|
|
228
|
-
|
|
229
|
-
|
|
266
|
+
<GridItem overflow="hidden">
|
|
267
|
+
<Grid sx={rightColumnSx}>
|
|
268
|
+
<LatencyDisplay latency={latency} sx={boxSx} />
|
|
269
|
+
{shouldShowTranscript && (
|
|
270
|
+
<GridItem sx={chatContainerSx}>
|
|
271
|
+
<Chat events={events || []} />
|
|
272
|
+
</GridItem>
|
|
273
|
+
)}
|
|
274
|
+
</Grid>
|
|
275
|
+
</GridItem>
|
|
230
276
|
</Grid>
|
|
231
277
|
)
|
|
232
278
|
}
|
|
@@ -5,6 +5,7 @@ import { Command, Event } from '../types'
|
|
|
5
5
|
|
|
6
6
|
interface Props extends FlexProps {
|
|
7
7
|
events: Event[]
|
|
8
|
+
hasLatencyDisplay?: boolean
|
|
8
9
|
}
|
|
9
10
|
|
|
10
11
|
export const Chat = ({ sx, events, ...props }: Props) => {
|
|
@@ -12,9 +13,9 @@ export const Chat = ({ sx, events, ...props }: Props) => {
|
|
|
12
13
|
...sx,
|
|
13
14
|
p: 0,
|
|
14
15
|
flexDirection: 'column',
|
|
16
|
+
height: '100%',
|
|
15
17
|
}
|
|
16
18
|
|
|
17
|
-
const maxHeight = document.documentElement.scrollHeight - 64
|
|
18
19
|
// 21 and 25 are the rem number we're using for the columns. We add 0.75rem for the padding
|
|
19
20
|
// A potential improvement would be to add a onresize event for both width and height
|
|
20
21
|
let remReference = 21.75
|
|
@@ -110,7 +111,7 @@ export const Chat = ({ sx, events, ...props }: Props) => {
|
|
|
110
111
|
borderRadius: '10px',
|
|
111
112
|
border: 'none',
|
|
112
113
|
width: columnWidth,
|
|
113
|
-
height:
|
|
114
|
+
height: '100%',
|
|
114
115
|
}}
|
|
115
116
|
history={messages}
|
|
116
117
|
demo={true}
|
|
@@ -52,6 +52,8 @@ function StackRow({
|
|
|
52
52
|
},
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
+
const agentOrStep = stack.agent_id ?? stack.step_id;
|
|
56
|
+
|
|
55
57
|
return (
|
|
56
58
|
<Tr
|
|
57
59
|
sx={
|
|
@@ -61,16 +63,16 @@ function StackRow({
|
|
|
61
63
|
>
|
|
62
64
|
<Td>
|
|
63
65
|
<Tooltip label={`${stack.flow_id} (${stack.frame_id})`} hasArrow>
|
|
64
|
-
<Text noOfLines={1}>{stack.
|
|
66
|
+
<Text noOfLines={1}>{stack.step_id}</Text>
|
|
65
67
|
</Tooltip>
|
|
66
68
|
</Td>
|
|
67
69
|
<Td>
|
|
68
|
-
{shouldShowTooltip(
|
|
69
|
-
<Tooltip label={stack.step_id} hasArrow>
|
|
70
|
-
<Text noOfLines={1}>{
|
|
70
|
+
{shouldShowTooltip(agentOrStep) ? (
|
|
71
|
+
<Tooltip label={`${agentOrStep} ${stack.agent_id && `(${stack.step_id})`}`} hasArrow>
|
|
72
|
+
<Text noOfLines={1}>{agentOrStep}</Text>
|
|
71
73
|
</Tooltip>
|
|
72
74
|
) : (
|
|
73
|
-
<Text noOfLines={1}>{
|
|
75
|
+
<Text noOfLines={1}>{agentOrStep}</Text>
|
|
74
76
|
)}
|
|
75
77
|
</Td>
|
|
76
78
|
</Tr>
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Box,
|
|
3
|
+
Flex,
|
|
4
|
+
FlexProps,
|
|
5
|
+
Text,
|
|
6
|
+
useColorModeValue,
|
|
7
|
+
Tooltip,
|
|
8
|
+
Table,
|
|
9
|
+
Tbody,
|
|
10
|
+
Tr,
|
|
11
|
+
Td,
|
|
12
|
+
} from '@chakra-ui/react'
|
|
13
|
+
import { useOurTheme } from '../theme'
|
|
14
|
+
import { LatencyData } from '../types'
|
|
15
|
+
|
|
16
|
+
interface Props extends FlexProps {
|
|
17
|
+
latency: LatencyData
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Simple latency display for text-only conversations.
|
|
22
|
+
* Shows a single response time value.
|
|
23
|
+
*/
|
|
24
|
+
const MinimalDisplay = ({ latency, sx, ...props }: Props) => {
|
|
25
|
+
const containerSx = {
|
|
26
|
+
...sx,
|
|
27
|
+
display: 'flex',
|
|
28
|
+
alignItems: 'center',
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const getLatencyColor = (latency: number) => {
|
|
32
|
+
if (latency < 1500) return 'green.500'
|
|
33
|
+
if (latency < 2500) return 'orange.500'
|
|
34
|
+
return 'red.500'
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const value = Math.round(latency.rasa_processing_latency_ms || 0);
|
|
38
|
+
const color = getLatencyColor(value);
|
|
39
|
+
|
|
40
|
+
return (
|
|
41
|
+
<Flex sx={containerSx} {...props}>
|
|
42
|
+
<Text fontSize="md" color={useColorModeValue('gray.700', 'gray.300')}>
|
|
43
|
+
Response latency:
|
|
44
|
+
<Text as="span" ml={2} fontWeight="bold" color={color}>
|
|
45
|
+
{value}ms
|
|
46
|
+
</Text>
|
|
47
|
+
</Text>
|
|
48
|
+
</Flex>
|
|
49
|
+
)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Detailed latency waterfall chart for voice conversations.
|
|
54
|
+
* Displays processing times for ASR, Rasa, and TTS components.
|
|
55
|
+
*/
|
|
56
|
+
const WaterfallDisplay = ({ latency, sx, ...props }: Props) => {
|
|
57
|
+
const { rasaSpace } = useOurTheme()
|
|
58
|
+
|
|
59
|
+
const containerSx = {
|
|
60
|
+
...sx,
|
|
61
|
+
flexDirection: 'column',
|
|
62
|
+
gap: rasaSpace[1],
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const headerSx = {
|
|
66
|
+
fontSize: 'sm',
|
|
67
|
+
fontWeight: 'bold',
|
|
68
|
+
color: useColorModeValue('gray.700', 'gray.300'),
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const waterfallBarSx = {
|
|
72
|
+
height: '24px',
|
|
73
|
+
borderRadius: '4px',
|
|
74
|
+
overflow: 'hidden',
|
|
75
|
+
border: '1px solid',
|
|
76
|
+
borderColor: useColorModeValue('gray.200', 'gray.600'),
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const legendTableSx = {
|
|
80
|
+
size: 'sm',
|
|
81
|
+
mt: rasaSpace[0.5]
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const getLatencyColor = (type: string) => {
|
|
85
|
+
const colors: { [key: string]: string } = {
|
|
86
|
+
asr: 'blue.500',
|
|
87
|
+
rasa: 'purple.500',
|
|
88
|
+
tts_first: 'orange.500',
|
|
89
|
+
tts_complete: 'green.500',
|
|
90
|
+
}
|
|
91
|
+
return colors[type] || 'gray.500'
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const getLatencyDescription = (type: string) => {
|
|
95
|
+
const descriptions: { [key: string]: string } = {
|
|
96
|
+
asr: 'Time from the first Partial Transcript event to the Final Transcript event from Speech Recognition. It also includes the time taken by the user to speak.',
|
|
97
|
+
rasa: 'Time taken by Rasa to process the text from the Final Transcript event from Speech Recognition until a text response is generated.',
|
|
98
|
+
tts_first: 'Time between the request sent to Text-to-Speech processing and the first byte of audio received by Rasa.',
|
|
99
|
+
tts_complete: 'Time taken by Text-to-Speech to complete audio generation. It depends on the length of the text and could overlap with the Bot speaking time.'
|
|
100
|
+
}
|
|
101
|
+
return descriptions[type] || ''
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Metrics for proportional display (only actual processing latencies)
|
|
105
|
+
const chartMetrics = [
|
|
106
|
+
latency.asr_latency_ms && {
|
|
107
|
+
type: 'asr',
|
|
108
|
+
label: 'ASR',
|
|
109
|
+
value: latency.asr_latency_ms,
|
|
110
|
+
},
|
|
111
|
+
latency.rasa_processing_latency_ms && {
|
|
112
|
+
type: 'rasa',
|
|
113
|
+
label: 'Rasa',
|
|
114
|
+
value: latency.rasa_processing_latency_ms,
|
|
115
|
+
},
|
|
116
|
+
latency.tts_complete_latency_ms && {
|
|
117
|
+
type: 'tts_complete',
|
|
118
|
+
label: 'TTS',
|
|
119
|
+
value: latency.tts_complete_latency_ms,
|
|
120
|
+
},
|
|
121
|
+
].filter(Boolean)
|
|
122
|
+
|
|
123
|
+
// All metrics for legend display
|
|
124
|
+
const allMetrics = [
|
|
125
|
+
latency.asr_latency_ms && {
|
|
126
|
+
type: 'asr',
|
|
127
|
+
label: 'ASR',
|
|
128
|
+
value: latency.asr_latency_ms,
|
|
129
|
+
},
|
|
130
|
+
latency.rasa_processing_latency_ms && {
|
|
131
|
+
type: 'rasa',
|
|
132
|
+
label: 'Rasa',
|
|
133
|
+
value: latency.rasa_processing_latency_ms,
|
|
134
|
+
},
|
|
135
|
+
latency.tts_first_byte_latency_ms && {
|
|
136
|
+
type: 'tts_first',
|
|
137
|
+
label: 'TTS First Byte',
|
|
138
|
+
value: latency.tts_first_byte_latency_ms,
|
|
139
|
+
},
|
|
140
|
+
latency.tts_complete_latency_ms && {
|
|
141
|
+
type: 'tts_complete',
|
|
142
|
+
label: 'TTS Complete',
|
|
143
|
+
value: latency.tts_complete_latency_ms,
|
|
144
|
+
},
|
|
145
|
+
].filter(Boolean)
|
|
146
|
+
|
|
147
|
+
// Calculate total for proportional sizing (only processing latencies)
|
|
148
|
+
const totalLatency = chartMetrics.reduce(
|
|
149
|
+
(sum: number, metric: any) => sum + metric.value,
|
|
150
|
+
0,
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
// Calculate total latency for title (Rasa + TTS First Byte)
|
|
154
|
+
const totalDisplayLatency =
|
|
155
|
+
(latency.rasa_processing_latency_ms || 0) +
|
|
156
|
+
(latency.tts_first_byte_latency_ms || 0);
|
|
157
|
+
|
|
158
|
+
return (
|
|
159
|
+
<Flex sx={containerSx} {...props}>
|
|
160
|
+
<Text sx={headerSx}>
|
|
161
|
+
Response latency: ~{Math.round(totalDisplayLatency)}ms
|
|
162
|
+
</Text>
|
|
163
|
+
|
|
164
|
+
{/* Waterfall Bar */}
|
|
165
|
+
<Box>
|
|
166
|
+
<Flex sx={waterfallBarSx}>
|
|
167
|
+
{chartMetrics.map((metric: any) => {
|
|
168
|
+
const widthPercentage =
|
|
169
|
+
totalLatency > 0 ? (metric.value / totalLatency) * 100 : 0
|
|
170
|
+
return (
|
|
171
|
+
<Tooltip
|
|
172
|
+
key={metric.type}
|
|
173
|
+
label={
|
|
174
|
+
<Box>
|
|
175
|
+
<Text fontWeight="bold">
|
|
176
|
+
{metric.label}: {Math.round(metric.value)}ms
|
|
177
|
+
</Text>
|
|
178
|
+
<Text fontSize="xs" mt={1}>
|
|
179
|
+
{getLatencyDescription(metric.type)}
|
|
180
|
+
</Text>
|
|
181
|
+
</Box>
|
|
182
|
+
}
|
|
183
|
+
hasArrow
|
|
184
|
+
placement="top"
|
|
185
|
+
>
|
|
186
|
+
<Box
|
|
187
|
+
bg={getLatencyColor(metric.type)}
|
|
188
|
+
width={`${widthPercentage}%`}
|
|
189
|
+
height="100%"
|
|
190
|
+
minWidth="40px" // Increased minimum width for better visibility
|
|
191
|
+
cursor="pointer"
|
|
192
|
+
_hover={{ opacity: 0.8 }}
|
|
193
|
+
/>
|
|
194
|
+
</Tooltip>
|
|
195
|
+
)
|
|
196
|
+
})}
|
|
197
|
+
</Flex>
|
|
198
|
+
|
|
199
|
+
{/* Legend */}
|
|
200
|
+
<Table sx={legendTableSx}>
|
|
201
|
+
<Tbody>
|
|
202
|
+
{/* Split metrics into pairs for 2x2 table */}
|
|
203
|
+
{Array.from(
|
|
204
|
+
{ length: Math.ceil(allMetrics.length / 2) },
|
|
205
|
+
(_, rowIndex) => (
|
|
206
|
+
<Tr key={rowIndex}>
|
|
207
|
+
{allMetrics
|
|
208
|
+
.slice(rowIndex * 2, rowIndex * 2 + 2)
|
|
209
|
+
.map((metric: any) => (
|
|
210
|
+
<Td key={metric.type} p={rasaSpace[0.25]} border="none">
|
|
211
|
+
<Flex align="center" gap={rasaSpace[0.25]}>
|
|
212
|
+
<Box
|
|
213
|
+
width="8px"
|
|
214
|
+
height="8px"
|
|
215
|
+
bg={getLatencyColor(metric.type)}
|
|
216
|
+
borderRadius="2px"
|
|
217
|
+
flexShrink={0}
|
|
218
|
+
/>
|
|
219
|
+
<Text
|
|
220
|
+
fontSize="xs"
|
|
221
|
+
color={useColorModeValue('gray.600', 'gray.400')}
|
|
222
|
+
noOfLines={1}
|
|
223
|
+
>
|
|
224
|
+
{metric.label}: {Math.round(metric.value)}ms
|
|
225
|
+
</Text>
|
|
226
|
+
</Flex>
|
|
227
|
+
</Td>
|
|
228
|
+
))}
|
|
229
|
+
{/* Fill empty cell if odd number of metrics */}
|
|
230
|
+
{allMetrics.length % 2 !== 0 &&
|
|
231
|
+
rowIndex === Math.ceil(allMetrics.length / 2) - 1 && (
|
|
232
|
+
<Td p={rasaSpace[0.25]} border="none" />
|
|
233
|
+
)}
|
|
234
|
+
</Tr>
|
|
235
|
+
),
|
|
236
|
+
)}
|
|
237
|
+
</Tbody>
|
|
238
|
+
</Table>
|
|
239
|
+
</Box>
|
|
240
|
+
</Flex>
|
|
241
|
+
)
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Displays processing latency information for the conversation.
|
|
246
|
+
* Shows either a detailed waterfall chart for voice conversations or
|
|
247
|
+
* a simpler display for text-only conversations.
|
|
248
|
+
*/
|
|
249
|
+
export const LatencyDisplay = ({
|
|
250
|
+
sx,
|
|
251
|
+
latency,
|
|
252
|
+
...props
|
|
253
|
+
}: Props) => {
|
|
254
|
+
if (!latency) {
|
|
255
|
+
console.warn('Latency data is not available')
|
|
256
|
+
return null
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// Show waterfall if voice metrics are available, otherwise show minimal display
|
|
260
|
+
const isVoiceMetricsAvailable =
|
|
261
|
+
latency.asr_latency_ms && latency.tts_complete_latency_ms
|
|
262
|
+
|
|
263
|
+
if (isVoiceMetricsAvailable) {
|
|
264
|
+
return <WaterfallDisplay latency={latency} sx={sx} {...props} />
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
return <MinimalDisplay latency={latency} sx={sx} {...props} />
|
|
268
|
+
}
|
|
@@ -8,7 +8,11 @@ import {
|
|
|
8
8
|
import { useOurTheme } from '../theme'
|
|
9
9
|
import { createAudioConnection } from '../helpers/audio/audiostream.ts'
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
interface LoadingSpinnerProps {
|
|
12
|
+
onLatencyUpdate?: (latency: any) => void
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const LoadingSpinner = ({ onLatencyUpdate }: LoadingSpinnerProps) => {
|
|
12
16
|
const { rasaSpace } = useOurTheme()
|
|
13
17
|
const isVoice = window.location.href.includes('browser_audio')
|
|
14
18
|
const text = isVoice
|
|
@@ -27,7 +31,7 @@ export const LoadingSpinner = () => {
|
|
|
27
31
|
{isVoice ? (
|
|
28
32
|
<Button
|
|
29
33
|
onClick={async () =>
|
|
30
|
-
await createAudioConnection(window.location.href)
|
|
34
|
+
await createAudioConnection(window.location.href, onLatencyUpdate)
|
|
31
35
|
}
|
|
32
36
|
>
|
|
33
37
|
Go
|
|
@@ -187,7 +187,7 @@ const setupAudioPlayback = async (socket: WebSocket): Promise<AudioQueue> => {
|
|
|
187
187
|
}
|
|
188
188
|
|
|
189
189
|
const addDataToAudioQueue =
|
|
190
|
-
(audioQueue: AudioQueue) => (message: MessageEvent<any>) => {
|
|
190
|
+
(audioQueue: AudioQueue, onLatencyUpdate?: (latency: any) => void) => (message: MessageEvent<any>) => {
|
|
191
191
|
try {
|
|
192
192
|
const data = JSON.parse(message.data.toString())
|
|
193
193
|
if (data['error']) {
|
|
@@ -199,6 +199,10 @@ const addDataToAudioQueue =
|
|
|
199
199
|
const audioData = intToFloatArray(int32Data)
|
|
200
200
|
audioQueue.write(audioData)
|
|
201
201
|
} else if (data['marker']) {
|
|
202
|
+
if (data['latency'] && onLatencyUpdate) {
|
|
203
|
+
onLatencyUpdate(data['latency'])
|
|
204
|
+
}
|
|
205
|
+
console.log('Voice Latency Metrics:', data['latency'])
|
|
202
206
|
audioQueue.addMarker(data['marker'])
|
|
203
207
|
}
|
|
204
208
|
} catch (error) {
|
|
@@ -231,8 +235,9 @@ function getWebSocketUrl(baseUrl: string) {
|
|
|
231
235
|
* Creates a WebSocket connection for browser audio and streams microphone input to the server
|
|
232
236
|
*
|
|
233
237
|
* @param baseUrl - The base URL (e.g., "https://example.com" or "http://localhost:5005")
|
|
238
|
+
* @param onLatencyUpdate - Optional callback function to receive latency updates
|
|
234
239
|
*/
|
|
235
|
-
export async function createAudioConnection(baseUrl: string) {
|
|
240
|
+
export async function createAudioConnection(baseUrl: string, onLatencyUpdate?: (latency: any) => void) {
|
|
236
241
|
const websocketURL = getWebSocketUrl(baseUrl)
|
|
237
242
|
const socket = new WebSocket(websocketURL)
|
|
238
243
|
|
|
@@ -241,5 +246,5 @@ export async function createAudioConnection(baseUrl: string) {
|
|
|
241
246
|
}
|
|
242
247
|
|
|
243
248
|
const audioQueue = await setupAudioPlayback(socket)
|
|
244
|
-
socket.onmessage = addDataToAudioQueue(audioQueue)
|
|
249
|
+
socket.onmessage = addDataToAudioQueue(audioQueue, onLatencyUpdate)
|
|
245
250
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type {
|
|
1
|
+
import {rasaColors} from '../theme/base/colors'
|
|
2
|
+
import type {Event, Flow, Slot, Stack} from '../types'
|
|
3
3
|
|
|
4
4
|
export function formatSlots(slots: { [key: string]: unknown }) {
|
|
5
5
|
if (!slots) {
|
|
@@ -13,7 +13,7 @@ export function formatSlots(slots: { [key: string]: unknown }) {
|
|
|
13
13
|
slotDuple[0] !== 'flow_hashes' &&
|
|
14
14
|
slotDuple[1] != null,
|
|
15
15
|
)
|
|
16
|
-
.map((slotDuple) => ({
|
|
16
|
+
.map((slotDuple) => ({name: slotDuple[0], value: slotDuple[1]}))
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export const formatTestCases = (events: Event[], sessionId: string) => {
|
|
@@ -85,11 +85,14 @@ export const formatFlow = (
|
|
|
85
85
|
`flowchart TD
|
|
86
86
|
classDef collect stroke-width:1px
|
|
87
87
|
classDef action fill:#FBFCFD,stroke:#A0B8CF
|
|
88
|
+
classDef noop fill:#FBFCFD
|
|
89
|
+
classDef callstep fill:#FBFCFD
|
|
88
90
|
classDef link fill:#f43
|
|
89
91
|
classDef slot fill:#e8f3db,stroke:#c5e1a5
|
|
90
92
|
classDef endstep fill:#ccc,stroke:#444
|
|
91
93
|
classDef previous stroke:${rasaColors.rasaOrange[400]},stroke-width:1px
|
|
92
94
|
classDef active stroke:${rasaColors.rasaOrange[400]},stroke-width:3px,fill:${rasaColors.warning[50]}
|
|
95
|
+
classDef pulse animation:pulse 2s infinite
|
|
93
96
|
`,
|
|
94
97
|
]
|
|
95
98
|
try {
|
|
@@ -210,6 +213,24 @@ function renderStepSequence(
|
|
|
210
213
|
)}"]:::slot\n`
|
|
211
214
|
}
|
|
212
215
|
|
|
216
|
+
if (step.call) {
|
|
217
|
+
const isAgentWaitingOnInput = !!currentStack?.agent_id && currentStack?.state === 'waiting_for_input'
|
|
218
|
+
mermaidTextFragment += `${mermaidId}["${encodeDoubleQuotes(
|
|
219
|
+
stepId,
|
|
220
|
+
)} 🤖"]:::callstep\n`
|
|
221
|
+
|
|
222
|
+
if (isAgentWaitingOnInput) {
|
|
223
|
+
mermaidTextFragment += `class ${mermaidId} pulse\n`
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
if (step.noop) {
|
|
228
|
+
mermaidTextFragment += `${mermaidId}["${parseFieldUsingStack(
|
|
229
|
+
stepId,
|
|
230
|
+
currentStack
|
|
231
|
+
)}"]:::noop\n`
|
|
232
|
+
}
|
|
233
|
+
|
|
213
234
|
if (activeStep && stepId === activeStep) {
|
|
214
235
|
mermaidTextFragment += `class ${mermaidId} active\n`
|
|
215
236
|
} else if (stepTrail?.includes(stepId)) {
|
|
@@ -1,4 +1,19 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {mode, StyleFunctionProps} from '@chakra-ui/theme-tools'
|
|
2
|
+
import {keyframes} from "@chakra-ui/react";
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
const pulse = keyframes`
|
|
6
|
+
0% {
|
|
7
|
+
opacity: 1;
|
|
8
|
+
}
|
|
9
|
+
50% {
|
|
10
|
+
opacity: 0.5;
|
|
11
|
+
}
|
|
12
|
+
100% {
|
|
13
|
+
opacity: 1;
|
|
14
|
+
}
|
|
15
|
+
`;
|
|
16
|
+
|
|
2
17
|
|
|
3
18
|
export const styles = {
|
|
4
19
|
global: {
|
|
@@ -9,5 +24,8 @@ export const styles = {
|
|
|
9
24
|
fontSize: theme.rasaFontSizes.md,
|
|
10
25
|
letterSpacing: '0.025rem',
|
|
11
26
|
}),
|
|
27
|
+
'.pulse': {
|
|
28
|
+
animation: `${pulse} 2s infinite`,
|
|
29
|
+
},
|
|
12
30
|
},
|
|
13
31
|
}
|