rasa-pro 3.11.0rc3__py3-none-any.whl → 3.11.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of rasa-pro might be problematic. Click here for more details.
- rasa/__main__.py +9 -3
- rasa/cli/llm_fine_tuning.py +19 -11
- rasa/cli/project_templates/tutorial/config.yml +1 -3
- rasa/cli/project_templates/tutorial/endpoints.yml +8 -3
- rasa/cli/studio/upload.py +0 -15
- rasa/cli/train.py +9 -0
- rasa/cli/utils.py +1 -1
- rasa/core/channels/development_inspector.py +4 -1
- rasa/core/channels/inspector/dist/assets/{arc-bc141fb2.js → arc-861ddd57.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{c4Diagram-d0fbc5ce-be2db283.js → c4Diagram-d0fbc5ce-921f02db.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{classDiagram-936ed81e-55366915.js → classDiagram-936ed81e-b436c4f8.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{classDiagram-v2-c3cb15f1-bb529518.js → classDiagram-v2-c3cb15f1-511a23cb.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{createText-62fc7601-b0ec81d6.js → createText-62fc7601-ef476ecd.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{edges-f2ad444c-6166330c.js → edges-f2ad444c-f1878e0a.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{erDiagram-9d236eb7-5ccc6a8e.js → erDiagram-9d236eb7-fac75185.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{flowDb-1972c806-fca3bfe4.js → flowDb-1972c806-201c5bbc.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{flowDiagram-7ea5b25a-4739080f.js → flowDiagram-7ea5b25a-f904ae41.js} +1 -1
- rasa/core/channels/inspector/dist/assets/flowDiagram-v2-855bc5b3-b080d6f2.js +1 -0
- rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-abe16c3d-7c1b0e0f.js → flowchart-elk-definition-abe16c3d-1813da66.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{ganttDiagram-9b5ea136-772fd050.js → ganttDiagram-9b5ea136-872af172.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-99d0ae7c-8eae1dc9.js → gitGraphDiagram-99d0ae7c-34a0af5a.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{index-2c4b9a3b-f55afcdf.js → index-2c4b9a3b-42ba3e3d.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{index-e7cef9de.js → index-37817b51.js} +68 -68
- rasa/core/channels/inspector/dist/assets/{infoDiagram-736b4530-124d4a14.js → infoDiagram-736b4530-6b731386.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{journeyDiagram-df861f2b-7c4fae44.js → journeyDiagram-df861f2b-e8579ac6.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{layout-b9885fb6.js → layout-89e6403a.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{line-7c59abb6.js → line-dc73d3fc.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{linear-4776f780.js → linear-f5b1d2bc.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{mindmap-definition-beec6740-2332c46c.js → mindmap-definition-beec6740-82cb74fa.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{pieDiagram-dbbf0591-8fb39303.js → pieDiagram-dbbf0591-bdf5f29b.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{quadrantDiagram-4d7f4fd6-3c7180a2.js → quadrantDiagram-4d7f4fd6-c7a0cbe4.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{requirementDiagram-6fc4c22a-e910bcb8.js → requirementDiagram-6fc4c22a-7ec5410f.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{sankeyDiagram-8f13d901-ead16c89.js → sankeyDiagram-8f13d901-caee5554.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{sequenceDiagram-b655622a-29a02a19.js → sequenceDiagram-b655622a-2935f8db.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{stateDiagram-59f0c015-042b3137.js → stateDiagram-59f0c015-8f5d9693.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-2b26beab-2178c0f3.js → stateDiagram-v2-2b26beab-d565d1de.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-080da4f6-23ffa4fc.js → styles-080da4f6-75ad421d.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-3dcbcfbf-94f59763.js → styles-3dcbcfbf-7e764226.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-9c745c82-78a6bebc.js → styles-9c745c82-7a4e0e61.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{svgDrawCommon-4835440b-eae2a6f6.js → svgDrawCommon-4835440b-4019d1bf.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{timeline-definition-5b62e21b-5c968d92.js → timeline-definition-5b62e21b-01ea12df.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{xychartDiagram-2b33534f-fd3db0d5.js → xychartDiagram-2b33534f-89407137.js} +1 -1
- rasa/core/channels/inspector/dist/index.html +1 -1
- rasa/core/channels/inspector/src/components/LoadingSpinner.tsx +1 -1
- rasa/core/channels/inspector/src/helpers/audiostream.ts +28 -2
- rasa/core/channels/voice_stream/asr/asr_engine.py +19 -1
- rasa/core/channels/voice_stream/asr/azure.py +13 -3
- rasa/core/channels/voice_stream/asr/deepgram.py +4 -3
- rasa/core/channels/voice_stream/tts/azure.py +3 -1
- rasa/core/channels/voice_stream/tts/cartesia.py +3 -3
- rasa/core/channels/voice_stream/tts/tts_engine.py +10 -1
- rasa/core/information_retrieval/qdrant.py +1 -0
- rasa/core/persistor.py +93 -49
- rasa/core/policies/flows/flow_executor.py +18 -8
- rasa/core/processor.py +7 -5
- rasa/core/utils.py +3 -1
- rasa/e2e_test/aggregate_test_stats_calculator.py +11 -1
- rasa/e2e_test/assertions.py +183 -19
- rasa/e2e_test/assertions_schema.yml +23 -0
- rasa/e2e_test/e2e_test_runner.py +4 -3
- rasa/engine/graph.py +9 -3
- rasa/engine/loader.py +12 -0
- rasa/engine/validation.py +345 -85
- rasa/model_manager/config.py +8 -0
- rasa/model_manager/model_api.py +166 -61
- rasa/model_manager/runner_service.py +31 -26
- rasa/model_manager/trainer_service.py +14 -23
- rasa/model_manager/warm_rasa_process.py +187 -0
- rasa/model_service.py +3 -5
- rasa/model_training.py +3 -1
- rasa/shared/constants.py +27 -0
- rasa/shared/core/domain.py +8 -5
- rasa/shared/core/flows/yaml_flows_io.py +13 -4
- rasa/shared/importers/importer.py +19 -2
- rasa/shared/importers/rasa.py +5 -1
- rasa/shared/nlu/training_data/formats/rasa_yaml.py +18 -3
- rasa/shared/providers/_utils.py +79 -0
- rasa/shared/providers/embedding/default_litellm_embedding_client.py +24 -0
- rasa/shared/providers/llm/default_litellm_llm_client.py +24 -0
- rasa/shared/utils/common.py +29 -2
- rasa/shared/utils/health_check/health_check.py +26 -24
- rasa/shared/utils/yaml.py +116 -31
- rasa/studio/data_handler.py +3 -1
- rasa/studio/upload.py +119 -57
- rasa/validator.py +40 -4
- rasa/version.py +1 -1
- {rasa_pro-3.11.0rc3.dist-info → rasa_pro-3.11.2.dist-info}/METADATA +2 -2
- {rasa_pro-3.11.0rc3.dist-info → rasa_pro-3.11.2.dist-info}/RECORD +91 -89
- rasa/core/channels/inspector/dist/assets/flowDiagram-v2-855bc5b3-736177bf.js +0 -1
- {rasa_pro-3.11.0rc3.dist-info → rasa_pro-3.11.2.dist-info}/NOTICE +0 -0
- {rasa_pro-3.11.0rc3.dist-info → rasa_pro-3.11.2.dist-info}/WHEEL +0 -0
- {rasa_pro-3.11.0rc3.dist-info → rasa_pro-3.11.2.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,B 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,B 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-37817b51.js";import{c as Qt}from"./createText-62fc7601-ef476ecd.js";import{i as Kt}from"./init-77b53fdd.js";import{o as Zt}from"./ordinal-ba9b4969.js";import{l as ft}from"./linear-f5b1d2bc.js";import{l as pt}from"./line-dc73d3fc.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,Bt=a.slice.call(arguments,1),k=Object.create(this.lexer),B={yy:{}};for(var J in this.yy)Object.prototype.hasOwnProperty.call(this.yy,J)&&(B.yy[J]=this.yy[J]);k.setInput(r,B.yy),B.yy.lexer=k,B.yy.parser=this,typeof k.yylloc>"u"&&(k.yylloc={});var tt=k.yylloc;a.push(tt);var Wt=k.options&&k.options.ranges;typeof B.yy.parseError=="function"?this.parseError=B.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,W,v,it,O={},q,M,dt,j;;){if(W=u[u.length-1],this.defaultActions[W]?v=this.defaultActions[W]:((D===null||typeof D>"u")&&(D=Ot()),v=F[W]&&F[W][D]),typeof v>"u"||!v.length||!v[0]){var et="";j=[];for(q in F[W])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: "+W+", 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},Wt&&(O._$.range=[a[a.length-(M||1)].range[0],a[a.length-1].range[1]]),it=this.performAction.apply(O,[x,gt,U,B.yy,v[1],b,a].concat(Bt)),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-37817b51.js"></script>
|
|
10
10
|
<link rel="stylesheet" href="./assets/index-3ee28881.css">
|
|
11
11
|
</head>
|
|
12
12
|
|
|
@@ -16,7 +16,7 @@ export const LoadingSpinner = () => {
|
|
|
16
16
|
mb={rasaSpace[1]}
|
|
17
17
|
/>
|
|
18
18
|
<Text fontSize="lg">{text}</Text>
|
|
19
|
-
{isVoice ? <Button onClick={createAudioConnection}>Go</Button> : null}
|
|
19
|
+
{isVoice ? <Button onClick={async () => await createAudioConnection(window.location.href)}>Go</Button> : null}
|
|
20
20
|
</Center>
|
|
21
21
|
);
|
|
22
22
|
};
|
|
@@ -156,8 +156,34 @@ const addDataToAudioQueue = (audioQueue: AudioQueue) => (message: MessageEvent<a
|
|
|
156
156
|
}
|
|
157
157
|
}
|
|
158
158
|
|
|
159
|
-
|
|
160
|
-
|
|
159
|
+
/**
|
|
160
|
+
* Constructs a WebSocket URL for browser audio from a base HTTP/HTTPS URL
|
|
161
|
+
*
|
|
162
|
+
* @param baseUrl - The base URL (e.g., "https://example.com" or "http://localhost:5005")
|
|
163
|
+
* @returns WebSocket URL for browser audio endpoint
|
|
164
|
+
*
|
|
165
|
+
* @example
|
|
166
|
+
* getWebSocketUrl("https://example.com")
|
|
167
|
+
* // Returns: "wss://example.com/webhooks/browser_audio/websocket"
|
|
168
|
+
*
|
|
169
|
+
* getWebSocketUrl("http://localhost:5005")
|
|
170
|
+
* // Returns: "ws://localhost:5005/webhooks/browser_audio/websocket"
|
|
171
|
+
*
|
|
172
|
+
* @throws {TypeError} If baseUrl is not a valid URL
|
|
173
|
+
*/
|
|
174
|
+
export function getWebSocketUrl(baseUrl: string) {
|
|
175
|
+
const url = new URL(baseUrl);
|
|
176
|
+
const wsProtocol = url.protocol === 'https:' ? 'wss:' : 'ws:';
|
|
177
|
+
return `${wsProtocol}//${url.host}/webhooks/browser_audio/websocket`;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Creates a WebSocket connection for browser audio and streams microphone input to the server
|
|
182
|
+
*
|
|
183
|
+
* @param baseUrl - The base URL (e.g., "https://example.com" or "http://localhost:5005")
|
|
184
|
+
*/
|
|
185
|
+
export async function createAudioConnection(baseUrl: string) {
|
|
186
|
+
const websocketURL = getWebSocketUrl(baseUrl)
|
|
161
187
|
const socket = new WebSocket(websocketURL)
|
|
162
188
|
socket.onopen = async () => { await streamMicrophoneToServer(socket)}
|
|
163
189
|
const audioQueue = setupAudioPlayback(socket)
|
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
from dataclasses import dataclass
|
|
2
|
-
from typing import
|
|
2
|
+
from typing import (
|
|
3
|
+
Dict,
|
|
4
|
+
AsyncIterator,
|
|
5
|
+
Any,
|
|
6
|
+
Generic,
|
|
7
|
+
Optional,
|
|
8
|
+
Tuple,
|
|
9
|
+
Type,
|
|
10
|
+
TypeVar,
|
|
11
|
+
)
|
|
3
12
|
|
|
4
13
|
from websockets.legacy.client import WebSocketClientProtocol
|
|
5
14
|
|
|
@@ -7,6 +16,7 @@ from rasa.core.channels.voice_stream.asr.asr_event import ASREvent
|
|
|
7
16
|
from rasa.core.channels.voice_stream.audio_bytes import RasaAudioBytes
|
|
8
17
|
from rasa.core.channels.voice_stream.util import MergeableConfig
|
|
9
18
|
from rasa.shared.exceptions import ConnectionException
|
|
19
|
+
from rasa.shared.utils.common import validate_environment
|
|
10
20
|
|
|
11
21
|
T = TypeVar("T", bound="ASREngineConfig")
|
|
12
22
|
E = TypeVar("E", bound="ASREngine")
|
|
@@ -18,9 +28,17 @@ class ASREngineConfig(MergeableConfig):
|
|
|
18
28
|
|
|
19
29
|
|
|
20
30
|
class ASREngine(Generic[T]):
|
|
31
|
+
required_env_vars: Tuple[str, ...] = ()
|
|
32
|
+
required_packages: Tuple[str, ...] = ()
|
|
33
|
+
|
|
21
34
|
def __init__(self, config: Optional[T] = None):
|
|
22
35
|
self.config = self.get_default_config().merge(config)
|
|
23
36
|
self.asr_socket: Optional[WebSocketClientProtocol] = None
|
|
37
|
+
validate_environment(
|
|
38
|
+
self.required_env_vars,
|
|
39
|
+
self.required_packages,
|
|
40
|
+
f"ASR Engine {self.__class__.__name__}",
|
|
41
|
+
)
|
|
24
42
|
|
|
25
43
|
async def connect(self) -> None:
|
|
26
44
|
self.asr_socket = await self.open_websocket_connection()
|
|
@@ -10,6 +10,7 @@ from rasa.core.channels.voice_stream.asr.asr_event import (
|
|
|
10
10
|
UserIsSpeaking,
|
|
11
11
|
)
|
|
12
12
|
from rasa.core.channels.voice_stream.audio_bytes import HERTZ, RasaAudioBytes
|
|
13
|
+
from rasa.shared.constants import AZURE_SPEECH_API_KEY_ENV_VAR
|
|
13
14
|
from rasa.shared.exceptions import ConnectionException
|
|
14
15
|
|
|
15
16
|
|
|
@@ -20,16 +21,21 @@ class AzureASRConfig(ASREngineConfig):
|
|
|
20
21
|
|
|
21
22
|
|
|
22
23
|
class AzureASR(ASREngine[AzureASRConfig]):
|
|
24
|
+
required_env_vars = (AZURE_SPEECH_API_KEY_ENV_VAR,)
|
|
25
|
+
required_packages = ("azure.cognitiveservices.speech",)
|
|
26
|
+
|
|
23
27
|
def __init__(self, config: Optional[AzureASRConfig] = None):
|
|
28
|
+
super().__init__(config)
|
|
29
|
+
|
|
24
30
|
import azure.cognitiveservices.speech as speechsdk
|
|
25
31
|
|
|
26
|
-
super().__init__(config)
|
|
27
32
|
self.speech_recognizer: Optional[speechsdk.SpeechRecognizer] = None
|
|
28
33
|
self.stream: Optional[speechsdk.audio.PushAudioInputStream] = None
|
|
29
34
|
self.is_recognizing = False
|
|
30
35
|
self.queue: asyncio.Queue[speechsdk.SpeechRecognitionEventArgs] = (
|
|
31
36
|
asyncio.Queue()
|
|
32
37
|
)
|
|
38
|
+
self.main_loop = asyncio.get_running_loop()
|
|
33
39
|
|
|
34
40
|
def signal_user_is_speaking(self, event: Any) -> None:
|
|
35
41
|
"""Replace the azure event with a generic is speaking event."""
|
|
@@ -37,13 +43,17 @@ class AzureASR(ASREngine[AzureASRConfig]):
|
|
|
37
43
|
|
|
38
44
|
def fill_queue(self, event: Any) -> None:
|
|
39
45
|
"""Either puts the event or a dedicated ASR Event into the queue."""
|
|
40
|
-
|
|
46
|
+
# This function is used by call backs of the azure speech library
|
|
47
|
+
# which seems to run separate threads/processes
|
|
48
|
+
# To properly wake up the task waiting at queue.get, we need to
|
|
49
|
+
# put to the queue in the same event loop
|
|
50
|
+
self.main_loop.call_soon_threadsafe(self.queue.put_nowait, event)
|
|
41
51
|
|
|
42
52
|
async def connect(self) -> None:
|
|
43
53
|
import azure.cognitiveservices.speech as speechsdk
|
|
44
54
|
|
|
45
55
|
speech_config = speechsdk.SpeechConfig(
|
|
46
|
-
subscription=os.environ[
|
|
56
|
+
subscription=os.environ[AZURE_SPEECH_API_KEY_ENV_VAR],
|
|
47
57
|
region=self.config.speech_region,
|
|
48
58
|
)
|
|
49
59
|
audio_format = speechsdk.audio.AudioStreamFormat(
|
|
@@ -13,8 +13,7 @@ from rasa.core.channels.voice_stream.asr.asr_event import (
|
|
|
13
13
|
UserIsSpeaking,
|
|
14
14
|
)
|
|
15
15
|
from rasa.core.channels.voice_stream.audio_bytes import HERTZ, RasaAudioBytes
|
|
16
|
-
|
|
17
|
-
DEEPGRAM_API_KEY = "DEEPGRAM_API_KEY"
|
|
16
|
+
from rasa.shared.constants import DEEPGRAM_API_KEY_ENV_VAR
|
|
18
17
|
|
|
19
18
|
|
|
20
19
|
@dataclass
|
|
@@ -28,13 +27,15 @@ class DeepgramASRConfig(ASREngineConfig):
|
|
|
28
27
|
|
|
29
28
|
|
|
30
29
|
class DeepgramASR(ASREngine[DeepgramASRConfig]):
|
|
30
|
+
required_env_vars = (DEEPGRAM_API_KEY_ENV_VAR,)
|
|
31
|
+
|
|
31
32
|
def __init__(self, config: Optional[DeepgramASRConfig] = None):
|
|
32
33
|
super().__init__(config)
|
|
33
34
|
self.accumulated_transcript = ""
|
|
34
35
|
|
|
35
36
|
async def open_websocket_connection(self) -> WebSocketClientProtocol:
|
|
36
37
|
"""Connect to the ASR system."""
|
|
37
|
-
deepgram_api_key = os.environ[
|
|
38
|
+
deepgram_api_key = os.environ[DEEPGRAM_API_KEY_ENV_VAR]
|
|
38
39
|
extra_headers = {"Authorization": f"Token {deepgram_api_key}"}
|
|
39
40
|
api_url = self._get_api_url()
|
|
40
41
|
query_params = self._get_query_params()
|
|
@@ -12,6 +12,7 @@ from rasa.core.channels.voice_stream.tts.tts_engine import (
|
|
|
12
12
|
TTSEngineConfig,
|
|
13
13
|
TTSError,
|
|
14
14
|
)
|
|
15
|
+
from rasa.shared.constants import AZURE_SPEECH_API_KEY_ENV_VAR
|
|
15
16
|
from rasa.shared.exceptions import ConnectionException
|
|
16
17
|
|
|
17
18
|
|
|
@@ -25,6 +26,7 @@ class AzureTTSConfig(TTSEngineConfig):
|
|
|
25
26
|
|
|
26
27
|
class AzureTTS(TTSEngine[AzureTTSConfig]):
|
|
27
28
|
session: Optional[aiohttp.ClientSession] = None
|
|
29
|
+
required_env_vars = (AZURE_SPEECH_API_KEY_ENV_VAR,)
|
|
28
30
|
|
|
29
31
|
def __init__(self, config: Optional[AzureTTSConfig] = None):
|
|
30
32
|
super().__init__(config)
|
|
@@ -66,7 +68,7 @@ class AzureTTS(TTSEngine[AzureTTSConfig]):
|
|
|
66
68
|
|
|
67
69
|
@staticmethod
|
|
68
70
|
def get_request_headers() -> dict[str, str]:
|
|
69
|
-
azure_speech_api_key = os.environ[
|
|
71
|
+
azure_speech_api_key = os.environ[AZURE_SPEECH_API_KEY_ENV_VAR]
|
|
70
72
|
return {
|
|
71
73
|
"Ocp-Apim-Subscription-Key": azure_speech_api_key,
|
|
72
74
|
"Content-Type": "application/ssml+xml",
|
|
@@ -11,12 +11,11 @@ from rasa.core.channels.voice_stream.tts.tts_engine import (
|
|
|
11
11
|
|
|
12
12
|
from rasa.core.channels.voice_stream.audio_bytes import HERTZ, RasaAudioBytes
|
|
13
13
|
from rasa.core.channels.voice_stream.tts.tts_engine import TTSEngine, TTSError
|
|
14
|
+
from rasa.shared.constants import CARTESIA_API_KEY_ENV_VAR
|
|
14
15
|
from rasa.shared.exceptions import ConnectionException
|
|
15
16
|
|
|
16
17
|
structlogger = structlog.get_logger()
|
|
17
18
|
|
|
18
|
-
CARTESIA_API_KEY = "CARTESIA_API_KEY"
|
|
19
|
-
|
|
20
19
|
|
|
21
20
|
@dataclass
|
|
22
21
|
class CartesiaTTSConfig(TTSEngineConfig):
|
|
@@ -26,6 +25,7 @@ class CartesiaTTSConfig(TTSEngineConfig):
|
|
|
26
25
|
|
|
27
26
|
class CartesiaTTS(TTSEngine[CartesiaTTSConfig]):
|
|
28
27
|
session: Optional[aiohttp.ClientSession] = None
|
|
28
|
+
required_env_vars = (CARTESIA_API_KEY_ENV_VAR,)
|
|
29
29
|
|
|
30
30
|
def __init__(self, config: Optional[CartesiaTTSConfig] = None):
|
|
31
31
|
super().__init__(config)
|
|
@@ -62,7 +62,7 @@ class CartesiaTTS(TTSEngine[CartesiaTTSConfig]):
|
|
|
62
62
|
|
|
63
63
|
@staticmethod
|
|
64
64
|
def get_request_headers(config: CartesiaTTSConfig) -> dict[str, str]:
|
|
65
|
-
cartesia_api_key = os.environ[
|
|
65
|
+
cartesia_api_key = os.environ[CARTESIA_API_KEY_ENV_VAR]
|
|
66
66
|
return {
|
|
67
67
|
"Cartesia-Version": str(config.version),
|
|
68
68
|
"Content-Type": "application/json",
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
from typing import AsyncIterator, Dict, Generic, Optional, Type, TypeVar
|
|
1
|
+
from typing import AsyncIterator, Dict, Generic, Optional, Tuple, Type, TypeVar
|
|
2
2
|
from dataclasses import dataclass
|
|
3
3
|
|
|
4
4
|
from rasa.core.channels.voice_stream.audio_bytes import RasaAudioBytes
|
|
5
5
|
from rasa.core.channels.voice_stream.util import MergeableConfig
|
|
6
6
|
from rasa.shared.exceptions import RasaException
|
|
7
|
+
from rasa.shared.utils.common import validate_environment
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
class TTSError(RasaException):
|
|
@@ -22,8 +23,16 @@ class TTSEngineConfig(MergeableConfig):
|
|
|
22
23
|
|
|
23
24
|
|
|
24
25
|
class TTSEngine(Generic[T]):
|
|
26
|
+
required_env_vars: Tuple[str, ...] = ()
|
|
27
|
+
required_packages: Tuple[str, ...] = ()
|
|
28
|
+
|
|
25
29
|
def __init__(self, config: Optional[T] = None):
|
|
26
30
|
self.config = self.get_default_config().merge(config)
|
|
31
|
+
validate_environment(
|
|
32
|
+
self.required_env_vars,
|
|
33
|
+
self.required_packages,
|
|
34
|
+
f"TTS Engine {self.__class__.__name__}",
|
|
35
|
+
)
|
|
27
36
|
|
|
28
37
|
async def close_connection(self) -> None:
|
|
29
38
|
"""Cleanup the connection if necessary."""
|
|
@@ -62,6 +62,7 @@ class Qdrant_Store(InformationRetrieval):
|
|
|
62
62
|
embeddings=self.embeddings,
|
|
63
63
|
content_payload_key=params.get("content_payload_key", "text"),
|
|
64
64
|
metadata_payload_key=params.get("metadata_payload_key", "metadata"),
|
|
65
|
+
vector_name=params.get("vector_name", None),
|
|
65
66
|
)
|
|
66
67
|
|
|
67
68
|
async def search(
|
rasa/core/persistor.py
CHANGED
|
@@ -4,6 +4,7 @@ import abc
|
|
|
4
4
|
import os
|
|
5
5
|
import shutil
|
|
6
6
|
from enum import Enum
|
|
7
|
+
from pathlib import Path
|
|
7
8
|
from typing import TYPE_CHECKING, List, Optional, Text, Tuple, Union
|
|
8
9
|
|
|
9
10
|
import structlog
|
|
@@ -122,7 +123,8 @@ class Persistor(abc.ABC):
|
|
|
122
123
|
|
|
123
124
|
def persist(self, trained_model: str) -> None:
|
|
124
125
|
"""Uploads a trained model persisted in the `target_dir` to cloud storage."""
|
|
125
|
-
|
|
126
|
+
absolute_file_key = self._create_file_key(trained_model)
|
|
127
|
+
file_key = Path(absolute_file_key).name
|
|
126
128
|
self._persist_tar(file_key, trained_model)
|
|
127
129
|
|
|
128
130
|
def retrieve(self, model_name: Text, target_path: Text) -> Text:
|
|
@@ -141,7 +143,8 @@ class Persistor(abc.ABC):
|
|
|
141
143
|
# ensure backward compatibility
|
|
142
144
|
tar_name = self._tar_name(model_name)
|
|
143
145
|
tar_name = self._create_file_key(tar_name)
|
|
144
|
-
|
|
146
|
+
target_filename = os.path.basename(tar_name)
|
|
147
|
+
self._retrieve_tar(target_filename)
|
|
145
148
|
self._copy(os.path.basename(tar_name), target_path)
|
|
146
149
|
|
|
147
150
|
if os.path.isdir(target_path):
|
|
@@ -149,6 +152,36 @@ class Persistor(abc.ABC):
|
|
|
149
152
|
|
|
150
153
|
return target_path
|
|
151
154
|
|
|
155
|
+
def size_of_persisted_model(self, model_name: Text) -> int:
|
|
156
|
+
"""Returns the size of the model that has been persisted to cloud storage.
|
|
157
|
+
|
|
158
|
+
Args:
|
|
159
|
+
model_name: The name of the model to retrieve.
|
|
160
|
+
"""
|
|
161
|
+
tar_name = model_name
|
|
162
|
+
if not model_name.endswith(MODEL_ARCHIVE_EXTENSION):
|
|
163
|
+
# ensure backward compatibility
|
|
164
|
+
tar_name = self._tar_name(model_name)
|
|
165
|
+
tar_name = self._create_file_key(tar_name)
|
|
166
|
+
target_filename = os.path.basename(tar_name)
|
|
167
|
+
return self._retrieve_tar_size(target_filename)
|
|
168
|
+
|
|
169
|
+
def _retrieve_tar_size(self, filename: Text) -> int:
|
|
170
|
+
"""Returns the size of the model that has been persisted to cloud storage."""
|
|
171
|
+
structlogger.warning(
|
|
172
|
+
"persistor.retrieve_tar_size.not_implemented",
|
|
173
|
+
filename=filename,
|
|
174
|
+
event_info=(
|
|
175
|
+
"This method should be implemented in the persistor. "
|
|
176
|
+
"The default implementation will download the model "
|
|
177
|
+
"to calculate the size. Most persistors should override "
|
|
178
|
+
"this method to avoid downloading the model and get the "
|
|
179
|
+
"size directly from the cloud storage."
|
|
180
|
+
),
|
|
181
|
+
)
|
|
182
|
+
self._retrieve_tar(filename)
|
|
183
|
+
return os.path.getsize(os.path.basename(filename))
|
|
184
|
+
|
|
152
185
|
@abc.abstractmethod
|
|
153
186
|
def _retrieve_tar(self, filename: Text) -> None:
|
|
154
187
|
"""Downloads a model previously persisted to cloud storage."""
|
|
@@ -197,10 +230,7 @@ class Persistor(abc.ABC):
|
|
|
197
230
|
f"{REMOTE_STORAGE_PATH_ENV} is deprecated and will be "
|
|
198
231
|
"removed in future versions. "
|
|
199
232
|
"Please use the -m path/to/model.tar.gz option to "
|
|
200
|
-
"specify the model path when loading a model."
|
|
201
|
-
"Or use --output and --fixed-model-name to specify the "
|
|
202
|
-
"output directory and the model name when saving a "
|
|
203
|
-
"trained model to remote storage.",
|
|
233
|
+
"specify the model path when loading a model.",
|
|
204
234
|
)
|
|
205
235
|
|
|
206
236
|
file_key = os.path.basename(model_path)
|
|
@@ -272,50 +302,48 @@ class AWSPersistor(Persistor):
|
|
|
272
302
|
with open(tar_path, "rb") as f:
|
|
273
303
|
self.s3.Object(self.bucket_name, file_key).put(Body=f)
|
|
274
304
|
|
|
275
|
-
def
|
|
305
|
+
def _retrieve_tar_size(self, model_path: Text) -> int:
|
|
306
|
+
"""Returns the size of the model that has been persisted to s3."""
|
|
307
|
+
try:
|
|
308
|
+
obj = self.s3.Object(self.bucket_name, model_path)
|
|
309
|
+
return obj.content_length
|
|
310
|
+
except Exception:
|
|
311
|
+
raise ModelNotFound()
|
|
312
|
+
|
|
313
|
+
def _retrieve_tar(self, target_filename: str) -> None:
|
|
276
314
|
"""Downloads a model that has previously been persisted to s3."""
|
|
277
315
|
from botocore import exceptions
|
|
278
316
|
|
|
279
|
-
target_filename = os.path.basename(model_path)
|
|
280
|
-
bucket_objects = list(self.bucket.objects.all())
|
|
281
|
-
|
|
282
|
-
model_found = False
|
|
283
|
-
|
|
284
317
|
log = (
|
|
285
318
|
f"Model '{target_filename}' not found in the specified bucket "
|
|
286
319
|
f"'{self.bucket_name}'. Please make sure the model exists "
|
|
287
320
|
f"in the bucket."
|
|
288
321
|
)
|
|
289
322
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
323
|
+
try:
|
|
324
|
+
with open(target_filename, "wb") as f:
|
|
325
|
+
self.bucket.download_fileobj(target_filename, f)
|
|
326
|
+
|
|
293
327
|
structlogger.debug(
|
|
294
|
-
"aws_persistor.retrieve_tar.object_found", object_key=
|
|
328
|
+
"aws_persistor.retrieve_tar.object_found", object_key=target_filename
|
|
295
329
|
)
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
bucket_name=self.bucket_name,
|
|
307
|
-
target_filename=target_filename,
|
|
308
|
-
event_info=log,
|
|
309
|
-
)
|
|
310
|
-
raise ModelNotFound() from exc
|
|
311
|
-
if not model_found:
|
|
330
|
+
except exceptions.ClientError as exc:
|
|
331
|
+
if self._error_code(exc) == HTTP_STATUS_NOT_FOUND:
|
|
332
|
+
structlogger.error(
|
|
333
|
+
"aws_persistor.retrieve_tar.model_not_found",
|
|
334
|
+
bucket_name=self.bucket_name,
|
|
335
|
+
target_filename=target_filename,
|
|
336
|
+
event_info=log,
|
|
337
|
+
)
|
|
338
|
+
raise ModelNotFound() from exc
|
|
339
|
+
except exceptions.BotoCoreError as exc:
|
|
312
340
|
structlogger.error(
|
|
313
|
-
"aws_persistor.retrieve_tar.
|
|
341
|
+
"aws_persistor.retrieve_tar.model_download_error",
|
|
314
342
|
bucket_name=self.bucket_name,
|
|
315
343
|
target_filename=target_filename,
|
|
316
344
|
event_info=log,
|
|
317
345
|
)
|
|
318
|
-
raise ModelNotFound()
|
|
346
|
+
raise ModelNotFound() from exc
|
|
319
347
|
|
|
320
348
|
|
|
321
349
|
class GCSPersistor(Persistor):
|
|
@@ -397,6 +425,14 @@ class GCSPersistor(Persistor):
|
|
|
397
425
|
blob = self.bucket.blob(file_key)
|
|
398
426
|
blob.upload_from_filename(tar_path)
|
|
399
427
|
|
|
428
|
+
def _retrieve_tar_size(self, target_filename: Text) -> int:
|
|
429
|
+
"""Returns the size of the model that has been persisted to GCS."""
|
|
430
|
+
try:
|
|
431
|
+
blob = self.bucket.blob(target_filename)
|
|
432
|
+
return blob.size
|
|
433
|
+
except Exception:
|
|
434
|
+
raise ModelNotFound()
|
|
435
|
+
|
|
400
436
|
def _retrieve_tar(self, target_filename: Text) -> None:
|
|
401
437
|
"""Downloads a model that has previously been persisted to GCS."""
|
|
402
438
|
from google.api_core import exceptions
|
|
@@ -404,6 +440,10 @@ class GCSPersistor(Persistor):
|
|
|
404
440
|
blob = self.bucket.blob(target_filename)
|
|
405
441
|
try:
|
|
406
442
|
blob.download_to_filename(target_filename)
|
|
443
|
+
|
|
444
|
+
structlogger.debug(
|
|
445
|
+
"gcs_persistor.retrieve_tar.object_found", object_key=target_filename
|
|
446
|
+
)
|
|
407
447
|
except exceptions.NotFound as exc:
|
|
408
448
|
log = (
|
|
409
449
|
f"Model '{target_filename}' not found in the specified bucket "
|
|
@@ -460,24 +500,28 @@ class AzurePersistor(Persistor):
|
|
|
460
500
|
with open(tar_path, "rb") as data:
|
|
461
501
|
self._container_client().upload_blob(name=file_key, data=data)
|
|
462
502
|
|
|
463
|
-
def
|
|
464
|
-
"""
|
|
503
|
+
def _retrieve_tar_size(self, target_filename: Text) -> int:
|
|
504
|
+
"""Returns the size of the model that has been persisted to Azure."""
|
|
465
505
|
try:
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
506
|
+
blob_client = self._container_client().get_blob_client(target_filename)
|
|
507
|
+
properties = blob_client.get_blob_properties()
|
|
508
|
+
return properties.size
|
|
509
|
+
except Exception:
|
|
510
|
+
raise ModelNotFound()
|
|
471
511
|
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
512
|
+
def _retrieve_tar(self, target_filename: Text) -> None:
|
|
513
|
+
"""Downloads a model that has previously been persisted to Azure."""
|
|
514
|
+
from azure.core.exceptions import AzureError
|
|
475
515
|
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
516
|
+
try:
|
|
517
|
+
with open(target_filename, "wb") as model_file:
|
|
518
|
+
blob_client = self._container_client().get_blob_client(target_filename)
|
|
519
|
+
download_stream = blob_client.download_blob()
|
|
520
|
+
model_file.write(download_stream.readall())
|
|
521
|
+
structlogger.debug(
|
|
522
|
+
"azure_persistor.retrieve_tar.blob_found", blob_name=target_filename
|
|
523
|
+
)
|
|
524
|
+
except AzureError as exc:
|
|
481
525
|
log = (
|
|
482
526
|
f"An exception occurred while trying to download "
|
|
483
527
|
f"the model '{target_filename}' in the specified container "
|
|
@@ -487,7 +487,8 @@ def validate_collect_step(
|
|
|
487
487
|
step: CollectInformationFlowStep,
|
|
488
488
|
stack: DialogueStack,
|
|
489
489
|
available_actions: List[str],
|
|
490
|
-
slots: Dict[
|
|
490
|
+
slots: Dict[str, Slot],
|
|
491
|
+
flow_name: str,
|
|
491
492
|
) -> bool:
|
|
492
493
|
"""Validate that a collect step can be executed.
|
|
493
494
|
|
|
@@ -510,12 +511,12 @@ def validate_collect_step(
|
|
|
510
511
|
slot_name=step.collect,
|
|
511
512
|
)
|
|
512
513
|
|
|
513
|
-
cancel_flow_and_push_internal_error(stack)
|
|
514
|
+
cancel_flow_and_push_internal_error(stack, flow_name)
|
|
514
515
|
|
|
515
516
|
return False
|
|
516
517
|
|
|
517
518
|
|
|
518
|
-
def cancel_flow_and_push_internal_error(stack: DialogueStack) -> None:
|
|
519
|
+
def cancel_flow_and_push_internal_error(stack: DialogueStack, flow_name: str) -> None:
|
|
519
520
|
"""Cancel the top user flow and push the internal error pattern."""
|
|
520
521
|
top_frame = stack.top()
|
|
521
522
|
|
|
@@ -527,7 +528,7 @@ def cancel_flow_and_push_internal_error(stack: DialogueStack) -> None:
|
|
|
527
528
|
canceled_frames = CancelFlowCommand.select_canceled_frames(stack)
|
|
528
529
|
stack.push(
|
|
529
530
|
CancelPatternFlowStackFrame(
|
|
530
|
-
canceled_name=
|
|
531
|
+
canceled_name=flow_name,
|
|
531
532
|
canceled_frames=canceled_frames,
|
|
532
533
|
)
|
|
533
534
|
)
|
|
@@ -539,6 +540,7 @@ def validate_custom_slot_mappings(
|
|
|
539
540
|
stack: DialogueStack,
|
|
540
541
|
tracker: DialogueStateTracker,
|
|
541
542
|
available_actions: List[str],
|
|
543
|
+
flow_name: str,
|
|
542
544
|
) -> bool:
|
|
543
545
|
"""Validate a slot with custom mappings.
|
|
544
546
|
|
|
@@ -559,7 +561,7 @@ def validate_custom_slot_mappings(
|
|
|
559
561
|
action=step.collect_action,
|
|
560
562
|
collect=step.collect,
|
|
561
563
|
)
|
|
562
|
-
cancel_flow_and_push_internal_error(stack)
|
|
564
|
+
cancel_flow_and_push_internal_error(stack, flow_name)
|
|
563
565
|
return False
|
|
564
566
|
|
|
565
567
|
return True
|
|
@@ -599,7 +601,12 @@ def run_step(
|
|
|
599
601
|
|
|
600
602
|
if isinstance(step, CollectInformationFlowStep):
|
|
601
603
|
return _run_collect_information_step(
|
|
602
|
-
available_actions,
|
|
604
|
+
available_actions,
|
|
605
|
+
initial_events,
|
|
606
|
+
stack,
|
|
607
|
+
step,
|
|
608
|
+
tracker,
|
|
609
|
+
flow.readable_name(),
|
|
603
610
|
)
|
|
604
611
|
|
|
605
612
|
elif isinstance(step, ActionFlowStep):
|
|
@@ -719,15 +726,18 @@ def _run_collect_information_step(
|
|
|
719
726
|
stack: DialogueStack,
|
|
720
727
|
step: CollectInformationFlowStep,
|
|
721
728
|
tracker: DialogueStateTracker,
|
|
729
|
+
flow_name: str,
|
|
722
730
|
) -> FlowStepResult:
|
|
723
|
-
is_step_valid = validate_collect_step(
|
|
731
|
+
is_step_valid = validate_collect_step(
|
|
732
|
+
step, stack, available_actions, tracker.slots, flow_name
|
|
733
|
+
)
|
|
724
734
|
|
|
725
735
|
if not is_step_valid:
|
|
726
736
|
# if we return any other FlowStepResult, the assistant will stay silent
|
|
727
737
|
# instead of triggering the internal error pattern
|
|
728
738
|
return ContinueFlowWithNextStep(events=initial_events)
|
|
729
739
|
is_mapping_valid = validate_custom_slot_mappings(
|
|
730
|
-
step, stack, tracker, available_actions
|
|
740
|
+
step, stack, tracker, available_actions, flow_name
|
|
731
741
|
)
|
|
732
742
|
|
|
733
743
|
if not is_mapping_valid:
|
rasa/core/processor.py
CHANGED
|
@@ -1279,11 +1279,13 @@ class MessageProcessor:
|
|
|
1279
1279
|
tracker.update(events[0])
|
|
1280
1280
|
return self.should_predict_another_action(action.name())
|
|
1281
1281
|
except Exception:
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
"
|
|
1285
|
-
"
|
|
1286
|
-
"
|
|
1282
|
+
structlogger.exception(
|
|
1283
|
+
"rasa.core.processor.run_action.exception",
|
|
1284
|
+
event_info=f"Encountered an exception while "
|
|
1285
|
+
f"running action '{action.name()}'."
|
|
1286
|
+
f"Bot will continue, but the actions events are lost. "
|
|
1287
|
+
f"Please check the logs of your action server for "
|
|
1288
|
+
f"more information.",
|
|
1287
1289
|
)
|
|
1288
1290
|
events = []
|
|
1289
1291
|
|