momentic-mobile 0.33.4 → 0.34.0
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.
- package/bin/cli.js +8 -8
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/run-viewer-static/assets/{index-B8NU8UVQ.js → index-0f3EEOkO.js} +369 -314
- package/run-viewer-static/assets/index-Xpo7R1Vd.css +1 -0
- package/run-viewer-static/index.html +2 -2
- package/static/assets/index-MSD4LMU5.css +1 -0
- package/static/assets/{index-7j8aE_Ua.js → index-UGymVG4Z.js} +128 -128
- package/static/index.html +2 -2
- package/run-viewer-static/assets/index--9yCUhP7.css +0 -1
- package/static/assets/index-It9sxKF9.css +0 -1
package/bin/cli.js
CHANGED
|
@@ -34,11 +34,11 @@ ${this.decisions.map(e=>e.toString()).join(`
|
|
|
34
34
|
To resolve the conflict:`,gS(l,e))),i=c):Z.warn("A view or instrument with the name ",e.name,` has already been registered and is incompatible with another registered view.
|
|
35
35
|
`,`Details:
|
|
36
36
|
`,pS(l,e),`To resolve the conflict:
|
|
37
|
-
`,gS(l,e))}}catch(u){n={error:u}}finally{try{s&&!s.done&&(o=a.return)&&o.call(a)}finally{if(n)throw n.error}}return i},r}();var c_=function(){function r(e){this._backingStorages=e}return r.prototype.record=function(e,t,n,o){this._backingStorages.forEach(function(i){i.record(e,t,n,o)})},r}();rt();rt();var u_=function(){function r(e,t){this._instrumentName=e,this._valueType=t,this._buffer=new yn}return r.prototype.observe=function(e,t){if(t===void 0&&(t={}),typeof e!="number"){Z.warn("non-number value provided to metric "+this._instrumentName+": "+e);return}this._valueType===Or.INT&&!Number.isInteger(e)&&(Z.warn("INT value type cannot accept a floating-point value for "+this._instrumentName+", ignoring the fractional digits."),e=Math.trunc(e),!Number.isInteger(e))||this._buffer.set(t,e)},r}();var d_=function(){function r(){this._buffer=new Map}return r.prototype.observe=function(e,t,n){if(n===void 0&&(n={}),!!Gc(e)){var o=this._buffer.get(e);if(o==null&&(o=new yn,this._buffer.set(e,o)),typeof t!="number"){Z.warn("non-number value provided to metric "+e._descriptor.name+": "+t);return}e._descriptor.valueType===Or.INT&&!Number.isInteger(t)&&(Z.warn("INT value type cannot accept a floating-point value for "+e._descriptor.name+", ignoring the fractional digits."),t=Math.trunc(t),!Number.isInteger(t))||o.set(n,t)}},r}();var fS=function(r,e,t,n){function o(i){return i instanceof t?i:new t(function(a){a(i)})}return new(t||(t=Promise))(function(i,a){function s(u){try{l(n.next(u))}catch(d){a(d)}}function c(u){try{l(n.throw(u))}catch(d){a(d)}}function l(u){u.done?i(u.value):o(u.value).then(s,c)}l((n=n.apply(r,e||[])).next())})},SS=function(r,e){var t={label:0,sent:function(){if(i[0]&1)throw i[1];return i[1]},trys:[],ops:[]},n,o,i,a;return a={next:s(0),throw:s(1),return:s(2)},typeof Symbol=="function"&&(a[Symbol.iterator]=function(){return this}),a;function s(l){return function(u){return c([l,u])}}function c(l){if(n)throw new TypeError("Generator is already executing.");for(;t;)try{if(n=1,o&&(i=l[0]&2?o.return:l[0]?o.throw||((i=o.return)&&i.call(o),0):o.next)&&!(i=i.call(o,l[1])).done)return i;switch(o=0,i&&(l=[l[0]&2,i.value]),l[0]){case 0:case 1:i=l;break;case 4:return t.label++,{value:l[1],done:!1};case 5:t.label++,o=l[1],l=[0];continue;case 7:l=t.ops.pop(),t.trys.pop();continue;default:if(i=t.trys,!(i=i.length>0&&i[i.length-1])&&(l[0]===6||l[0]===2)){t=0;continue}if(l[0]===3&&(!i||l[1]>i[0]&&l[1]<i[3])){t.label=l[1];break}if(l[0]===6&&t.label<i[1]){t.label=i[1],i=l;break}if(i&&t.label<i[2]){t.label=i[2],t.ops.push(l);break}i[2]&&t.ops.pop(),t.trys.pop();continue}l=e.call(r,t)}catch(u){l=[6,u],o=0}finally{n=i=0}if(l[0]&5)throw l[1];return{value:l[0]?l[1]:void 0,done:!0}}},m_=function(r,e){var t=typeof Symbol=="function"&&r[Symbol.iterator];if(!t)return r;var n=t.call(r),o,i=[],a;try{for(;(e===void 0||e-- >0)&&!(o=n.next()).done;)i.push(o.value)}catch(s){a={error:s}}finally{try{o&&!o.done&&(t=n.return)&&t.call(n)}finally{if(a)throw a.error}}return i},p_=function(r,e,t){if(t||arguments.length===2)for(var n=0,o=e.length,i;n<o;n++)(i||!(n in e))&&(i||(i=Array.prototype.slice.call(e,0,n)),i[n]=e[n]);return r.concat(i||Array.prototype.slice.call(e))},g_=function(){function r(){this._callbacks=[],this._batchCallbacks=[]}return r.prototype.addCallback=function(e,t){var n=this._findCallback(e,t);n>=0||this._callbacks.push({callback:e,instrument:t})},r.prototype.removeCallback=function(e,t){var n=this._findCallback(e,t);n<0||this._callbacks.splice(n,1)},r.prototype.addBatchCallback=function(e,t){var n=new Set(t.filter(Gc));if(n.size===0){Z.error("BatchObservableCallback is not associated with valid instruments",t);return}var o=this._findBatchCallback(e,n);o>=0||this._batchCallbacks.push({callback:e,instruments:n})},r.prototype.removeBatchCallback=function(e,t){var n=new Set(t.filter(Gc)),o=this._findBatchCallback(e,n);o<0||this._batchCallbacks.splice(o,1)},r.prototype.observe=function(e,t){return fS(this,void 0,void 0,function(){var n,o,i,a;return SS(this,function(s){switch(s.label){case 0:return n=this._observeCallbacks(e,t),o=this._observeBatchCallbacks(e,t),[4,mx(p_(p_([],m_(n),!1),m_(o),!1))];case 1:return i=s.sent(),a=i.filter(px).map(function(c){return c.reason}),[2,a]}})})},r.prototype._observeCallbacks=function(e,t){var n=this;return this._callbacks.map(function(o){var i=o.callback,a=o.instrument;return fS(n,void 0,void 0,function(){var s,c;return SS(this,function(l){switch(l.label){case 0:return s=new u_(a._descriptor.name,a._descriptor.valueType),c=Promise.resolve(i(s)),t!=null&&(c=Vo(c,t)),[4,c];case 1:return l.sent(),a._metricStorages.forEach(function(u){u.record(s._buffer,e)}),[2]}})})})},r.prototype._observeBatchCallbacks=function(e,t){var n=this;return this._batchCallbacks.map(function(o){var i=o.callback,a=o.instruments;return fS(n,void 0,void 0,function(){var s,c;return SS(this,function(l){switch(l.label){case 0:return s=new d_,c=Promise.resolve(i(s)),t!=null&&(c=Vo(c,t)),[4,c];case 1:return l.sent(),a.forEach(function(u){var d=s._buffer.get(u);d!=null&&u._metricStorages.forEach(function(p){p.record(d,e)})}),[2]}})})})},r.prototype._findCallback=function(e,t){return this._callbacks.findIndex(function(n){return n.callback===e&&n.instrument===t})},r.prototype._findBatchCallback=function(e,t){return this._batchCallbacks.findIndex(function(n){return n.callback===e&&gx(n.instruments,t)})},r}();var aj=function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(n,o){n.__proto__=o}||function(n,o){for(var i in o)Object.prototype.hasOwnProperty.call(o,i)&&(n[i]=o[i])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function n(){this.constructor=e}e.prototype=t===null?Object.create(t):(n.prototype=t.prototype,new n)}}(),h_=function(r){aj(e,r);function e(t,n,o,i,a){var s=r.call(this,t)||this;return s._attributesProcessor=o,s._aggregationCardinalityLimit=a,s._deltaMetricStorage=new fm(n,s._aggregationCardinalityLimit),s._temporalMetricStorage=new Sm(n,i),s}return e.prototype.record=function(t,n,o,i){n=this._attributesProcessor.process(n,o),this._deltaMetricStorage.record(t,n,o,i)},e.prototype.collect=function(t,n){var o=this._deltaMetricStorage.collect();return this._temporalMetricStorage.buildMetrics(t,this._instrumentDescriptor,o,n)},e}(hm);var f_=function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(n,o){n.__proto__=o}||function(n,o){for(var i in o)Object.prototype.hasOwnProperty.call(o,i)&&(n[i]=o[i])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function n(){this.constructor=e}e.prototype=t===null?Object.create(t):(n.prototype=t.prototype,new n)}}(),ws=function(){function r(){}return r.Noop=function(){return lj},r}();var sj=function(r){f_(e,r);function e(){return r!==null&&r.apply(this,arguments)||this}return e.prototype.process=function(t,n){return t},e}(ws);var S_=function(r){f_(e,r);function e(t){var n=r.call(this)||this;return n._allowedAttributeNames=t,n}return e.prototype.process=function(t,n){var o=this,i={};return Object.keys(t).filter(function(a){return o._allowedAttributeNames.includes(a)}).forEach(function(a){return i[a]=t[a]}),i},e}(ws);var lj=new sj;var cj=function(r,e,t,n){function o(i){return i instanceof t?i:new t(function(a){a(i)})}return new(t||(t=Promise))(function(i,a){function s(u){try{l(n.next(u))}catch(d){a(d)}}function c(u){try{l(n.throw(u))}catch(d){a(d)}}function l(u){u.done?i(u.value):o(u.value).then(s,c)}l((n=n.apply(r,e||[])).next())})},uj=function(r,e){var t={label:0,sent:function(){if(i[0]&1)throw i[1];return i[1]},trys:[],ops:[]},n,o,i,a;return a={next:s(0),throw:s(1),return:s(2)},typeof Symbol=="function"&&(a[Symbol.iterator]=function(){return this}),a;function s(l){return function(u){return c([l,u])}}function c(l){if(n)throw new TypeError("Generator is already executing.");for(;t;)try{if(n=1,o&&(i=l[0]&2?o.return:l[0]?o.throw||((i=o.return)&&i.call(o),0):o.next)&&!(i=i.call(o,l[1])).done)return i;switch(o=0,i&&(l=[l[0]&2,i.value]),l[0]){case 0:case 1:i=l;break;case 4:return t.label++,{value:l[1],done:!1};case 5:t.label++,o=l[1],l=[0];continue;case 7:l=t.ops.pop(),t.trys.pop();continue;default:if(i=t.trys,!(i=i.length>0&&i[i.length-1])&&(l[0]===6||l[0]===2)){t=0;continue}if(l[0]===3&&(!i||l[1]>i[0]&&l[1]<i[3])){t.label=l[1];break}if(l[0]===6&&t.label<i[1]){t.label=i[1],i=l;break}if(i&&t.label<i[2]){t.label=i[2],t.ops.push(l);break}i[2]&&t.ops.pop(),t.trys.pop();continue}l=e.call(r,t)}catch(u){l=[6,u],o=0}finally{n=i=0}if(l[0]&5)throw l[1];return{value:l[0]?l[1]:void 0,done:!0}}},dj=function(r,e){var t=typeof Symbol=="function"&&r[Symbol.iterator];if(!t)return r;var n=t.call(r),o,i=[],a;try{for(;(e===void 0||e-- >0)&&!(o=n.next()).done;)i.push(o.value)}catch(s){a={error:s}}finally{try{o&&!o.done&&(t=n.return)&&t.call(n)}finally{if(a)throw a.error}}return i},y_=function(){function r(e,t){this._meterProviderSharedState=e,this._instrumentationScope=t,this.metricStorageRegistry=new l_,this.observableRegistry=new g_,this.meter=new o_(this)}return r.prototype.registerMetricStorage=function(e){var t=this._registerMetricStorage(e,h_);return t.length===1?t[0]:new c_(t)},r.prototype.registerAsyncMetricStorage=function(e){var t=this._registerMetricStorage(e,s_);return t},r.prototype.collect=function(e,t,n){return cj(this,void 0,void 0,function(){var o,i,a;return uj(this,function(s){switch(s.label){case 0:return[4,this.observableRegistry.observe(t,n?.timeoutMillis)];case 1:return o=s.sent(),i=this.metricStorageRegistry.getStorages(e),i.length===0?[2,null]:(a=i.map(function(c){return c.collect(e,t)}).filter(ux),a.length===0?[2,{errors:o}]:[2,{scopeMetrics:{scope:this._instrumentationScope,metrics:a},errors:o}])}})})},r.prototype._registerMetricStorage=function(e,t){var n=this,o=this._meterProviderSharedState.viewRegistry.findViews(e,this._instrumentationScope),i=o.map(function(c){var l=Sx(c,e),u=n.metricStorageRegistry.findOrUpdateCompatibleStorage(l);if(u!=null)return u;var d=c.aggregation.createAggregator(l),p=new t(l,d,c.attributesProcessor,n._meterProviderSharedState.metricCollectors,c.aggregationCardinalityLimit);return n.metricStorageRegistry.register(p),p});if(i.length===0){var a=this._meterProviderSharedState.selectAggregations(e.type),s=a.map(function(c){var l=dj(c,2),u=l[0],d=l[1],p=n.metricStorageRegistry.findOrUpdateCompatibleCollectorStorage(u,e);if(p!=null)return p;var m=d.createAggregator(e),g=u.selectCardinalityLimit(e.type),h=new t(e,m,ws.Noop(),[u],g);return n.metricStorageRegistry.registerForCollector(u,h),h});i=i.concat(s)}return i},r}();var mj=function(r){var e=typeof Symbol=="function"&&Symbol.iterator,t=e&&r[e],n=0;if(t)return t.call(r);if(r&&typeof r.length=="number")return{next:function(){return r&&n>=r.length&&(r=void 0),{value:r&&r[n++],done:!r}}};throw new TypeError(e?"Object is not iterable.":"Symbol.iterator is not defined.")},b_=function(){function r(e){this.resource=e,this.viewRegistry=new Xx,this.metricCollectors=[],this.meterSharedStates=new Map}return r.prototype.getMeterSharedState=function(e){var t=dx(e),n=this.meterSharedStates.get(t);return n==null&&(n=new y_(this,e),this.meterSharedStates.set(t,n)),n},r.prototype.selectAggregations=function(e){var t,n,o=[];try{for(var i=mj(this.metricCollectors),a=i.next();!a.done;a=i.next()){var s=a.value;o.push([s,s.selectAggregation(e)])}}catch(c){t={error:c}}finally{try{a&&!a.done&&(n=i.return)&&n.call(i)}finally{if(t)throw t.error}}return o},r}();var ym=function(r,e,t,n){function o(i){return i instanceof t?i:new t(function(a){a(i)})}return new(t||(t=Promise))(function(i,a){function s(u){try{l(n.next(u))}catch(d){a(d)}}function c(u){try{l(n.throw(u))}catch(d){a(d)}}function l(u){u.done?i(u.value):o(u.value).then(s,c)}l((n=n.apply(r,e||[])).next())})},bm=function(r,e){var t={label:0,sent:function(){if(i[0]&1)throw i[1];return i[1]},trys:[],ops:[]},n,o,i,a;return a={next:s(0),throw:s(1),return:s(2)},typeof Symbol=="function"&&(a[Symbol.iterator]=function(){return this}),a;function s(l){return function(u){return c([l,u])}}function c(l){if(n)throw new TypeError("Generator is already executing.");for(;t;)try{if(n=1,o&&(i=l[0]&2?o.return:l[0]?o.throw||((i=o.return)&&i.call(o),0):o.next)&&!(i=i.call(o,l[1])).done)return i;switch(o=0,i&&(l=[l[0]&2,i.value]),l[0]){case 0:case 1:i=l;break;case 4:return t.label++,{value:l[1],done:!1};case 5:t.label++,o=l[1],l=[0];continue;case 7:l=t.ops.pop(),t.trys.pop();continue;default:if(i=t.trys,!(i=i.length>0&&i[i.length-1])&&(l[0]===6||l[0]===2)){t=0;continue}if(l[0]===3&&(!i||l[1]>i[0]&&l[1]<i[3])){t.label=l[1];break}if(l[0]===6&&t.label<i[1]){t.label=i[1],i=l;break}if(i&&t.label<i[2]){t.label=i[2],t.ops.push(l);break}i[2]&&t.ops.pop(),t.trys.pop();continue}l=e.call(r,t)}catch(u){l=[6,u],o=0}finally{n=i=0}if(l[0]&5)throw l[1];return{value:l[0]?l[1]:void 0,done:!0}}},pj=function(r,e){var t=typeof Symbol=="function"&&r[Symbol.iterator];if(!t)return r;var n=t.call(r),o,i=[],a;try{for(;(e===void 0||e-- >0)&&!(o=n.next()).done;)i.push(o.value)}catch(s){a={error:s}}finally{try{o&&!o.done&&(t=n.return)&&t.call(n)}finally{if(a)throw a.error}}return i},gj=function(r,e,t){if(t||arguments.length===2)for(var n=0,o=e.length,i;n<o;n++)(i||!(n in e))&&(i||(i=Array.prototype.slice.call(e,0,n)),i[n]=e[n]);return r.concat(i||Array.prototype.slice.call(e))},E_=function(){function r(e,t){this._sharedState=e,this._metricReader=t}return r.prototype.collect=function(e){return ym(this,void 0,void 0,function(){var t,n,o,i,a=this;return bm(this,function(s){switch(s.label){case 0:return t=Zi(Date.now()),n=[],o=[],i=Array.from(this._sharedState.meterSharedStates.values()).map(function(c){return ym(a,void 0,void 0,function(){var l;return bm(this,function(u){switch(u.label){case 0:return[4,c.collect(this,t,e)];case 1:return l=u.sent(),l?.scopeMetrics!=null&&n.push(l.scopeMetrics),l?.errors!=null&&o.push.apply(o,gj([],pj(l.errors),!1)),[2]}})})}),[4,Promise.all(i)];case 1:return s.sent(),[2,{resourceMetrics:{resource:this._sharedState.resource,scopeMetrics:n},errors:o}]}})})},r.prototype.forceFlush=function(e){return ym(this,void 0,void 0,function(){return bm(this,function(t){switch(t.label){case 0:return[4,this._metricReader.forceFlush(e)];case 1:return t.sent(),[2]}})})},r.prototype.shutdown=function(e){return ym(this,void 0,void 0,function(){return bm(this,function(t){switch(t.label){case 0:return[4,this._metricReader.shutdown(e)];case 1:return t.sent(),[2]}})})},r.prototype.selectAggregationTemporality=function(e){return this._metricReader.selectAggregationTemporality(e)},r.prototype.selectAggregation=function(e){return this._metricReader.selectAggregation(e)},r.prototype.selectCardinalityLimit=function(e){var t,n,o;return(o=(n=(t=this._metricReader).selectCardinalityLimit)===null||n===void 0?void 0:n.call(t,e))!==null&&o!==void 0?o:2e3},r}();var T_=function(r,e,t,n){function o(i){return i instanceof t?i:new t(function(a){a(i)})}return new(t||(t=Promise))(function(i,a){function s(u){try{l(n.next(u))}catch(d){a(d)}}function c(u){try{l(n.throw(u))}catch(d){a(d)}}function l(u){u.done?i(u.value):o(u.value).then(s,c)}l((n=n.apply(r,e||[])).next())})},v_=function(r,e){var t={label:0,sent:function(){if(i[0]&1)throw i[1];return i[1]},trys:[],ops:[]},n,o,i,a;return a={next:s(0),throw:s(1),return:s(2)},typeof Symbol=="function"&&(a[Symbol.iterator]=function(){return this}),a;function s(l){return function(u){return c([l,u])}}function c(l){if(n)throw new TypeError("Generator is already executing.");for(;t;)try{if(n=1,o&&(i=l[0]&2?o.return:l[0]?o.throw||((i=o.return)&&i.call(o),0):o.next)&&!(i=i.call(o,l[1])).done)return i;switch(o=0,i&&(l=[l[0]&2,i.value]),l[0]){case 0:case 1:i=l;break;case 4:return t.label++,{value:l[1],done:!1};case 5:t.label++,o=l[1],l=[0];continue;case 7:l=t.ops.pop(),t.trys.pop();continue;default:if(i=t.trys,!(i=i.length>0&&i[i.length-1])&&(l[0]===6||l[0]===2)){t=0;continue}if(l[0]===3&&(!i||l[1]>i[0]&&l[1]<i[3])){t.label=l[1];break}if(l[0]===6&&t.label<i[1]){t.label=i[1],i=l;break}if(i&&t.label<i[2]){t.label=i[2],t.ops.push(l);break}i[2]&&t.ops.pop(),t.trys.pop();continue}l=e.call(r,t)}catch(u){l=[6,u],o=0}finally{n=i=0}if(l[0]&5)throw l[1];return{value:l[0]?l[1]:void 0,done:!0}}},A_=function(r){var e=typeof Symbol=="function"&&Symbol.iterator,t=e&&r[e],n=0;if(t)return t.call(r);if(r&&typeof r.length=="number")return{next:function(){return r&&n>=r.length&&(r=void 0),{value:r&&r[n++],done:!r}}};throw new TypeError(e?"Object is not iterable.":"Symbol.iterator is not defined.")};function hj(r,e){var t=e??mm.empty();return r?mm.default().merge(t):t}var yS=function(){function r(e){var t,n,o,i,a;if(this._shutdown=!1,this._sharedState=new b_(hj((a=e?.mergeResourceWithDefaults)!==null&&a!==void 0?a:!0,e?.resource)),e?.views!=null&&e.views.length>0)try{for(var s=A_(e.views),c=s.next();!c.done;c=s.next()){var l=c.value;this._sharedState.viewRegistry.addView(l)}}catch(m){t={error:m}}finally{try{c&&!c.done&&(n=s.return)&&n.call(s)}finally{if(t)throw t.error}}if(e?.readers!=null&&e.readers.length>0)try{for(var u=A_(e.readers),d=u.next();!d.done;d=u.next()){var p=d.value;this.addMetricReader(p)}}catch(m){o={error:m}}finally{try{d&&!d.done&&(i=u.return)&&i.call(u)}finally{if(o)throw o.error}}}return r.prototype.getMeter=function(e,t,n){return t===void 0&&(t=""),n===void 0&&(n={}),this._shutdown?(Z.warn("A shutdown MeterProvider cannot provide a Meter"),Af()):this._sharedState.getMeterSharedState({name:e,version:t,schemaUrl:n.schemaUrl}).meter},r.prototype.addMetricReader=function(e){var t=new E_(this._sharedState,e);e.setMetricProducer(t),this._sharedState.metricCollectors.push(t)},r.prototype.shutdown=function(e){return T_(this,void 0,void 0,function(){return v_(this,function(t){switch(t.label){case 0:return this._shutdown?(Z.warn("shutdown may only be called once per MeterProvider"),[2]):(this._shutdown=!0,[4,Promise.all(this._sharedState.metricCollectors.map(function(n){return n.shutdown(e)}))]);case 1:return t.sent(),[2]}})})},r.prototype.forceFlush=function(e){return T_(this,void 0,void 0,function(){return v_(this,function(t){switch(t.label){case 0:return this._shutdown?(Z.warn("invalid attempt to force flush after MeterProvider shutdown"),[2]):[4,Promise.all(this._sharedState.metricCollectors.map(function(n){return n.forceFlush(e)}))];case 1:return t.sent(),[2]}})})},r}();var fj=/[\^$\\.+?()[\]{}|]/g,Em=function(){function r(e){e==="*"?(this._matchAll=!0,this._regexp=/.*/):(this._matchAll=!1,this._regexp=new RegExp(r.escapePattern(e)))}return r.prototype.match=function(e){return this._matchAll?!0:this._regexp.test(e)},r.escapePattern=function(e){return"^"+e.replace(fj,"\\$&").replace("*",".*")+"$"},r.hasWildcard=function(e){return e.includes("*")},r}();var Cs=function(){function r(e){this._matchAll=e===void 0,this._pattern=e}return r.prototype.match=function(e){return!!(this._matchAll||e===this._pattern)},r}();var R_=function(){function r(e){var t;this._nameFilter=new Em((t=e?.name)!==null&&t!==void 0?t:"*"),this._type=e?.type,this._unitFilter=new Cs(e?.unit)}return r.prototype.getType=function(){return this._type},r.prototype.getNameFilter=function(){return this._nameFilter},r.prototype.getUnitFilter=function(){return this._unitFilter},r}();var w_=function(){function r(e){this._nameFilter=new Cs(e?.name),this._versionFilter=new Cs(e?.version),this._schemaUrlFilter=new Cs(e?.schemaUrl)}return r.prototype.getNameFilter=function(){return this._nameFilter},r.prototype.getVersionFilter=function(){return this._versionFilter},r.prototype.getSchemaUrlFilter=function(){return this._schemaUrlFilter},r}();function Sj(r){return r.instrumentName==null&&r.instrumentType==null&&r.instrumentUnit==null&&r.meterName==null&&r.meterVersion==null&&r.meterSchemaUrl==null}var Tm=function(){function r(e){var t;if(Sj(e))throw new Error("Cannot create view with no selector arguments supplied");if(e.name!=null&&(e?.instrumentName==null||Em.hasWildcard(e.instrumentName)))throw new Error("Views with a specified name must be declared with an instrument selector that selects at most one instrument per meter.");e.attributeKeys!=null?this.attributesProcessor=new S_(e.attributeKeys):this.attributesProcessor=ws.Noop(),this.name=e.name,this.description=e.description,this.aggregation=(t=e.aggregation)!==null&&t!==void 0?t:en.Default(),this.instrumentSelector=new R_({name:e.instrumentName,type:e.instrumentType,unit:e.instrumentUnit}),this.meterSelector=new w_({name:e.meterName,version:e.meterVersion,schemaUrl:e.meterSchemaUrl}),this.aggregationCardinalityLimit=e.aggregationCardinalityLimit}return r}();var hCe=process.env.APP||"unknown";rt();import{v4 as yj}from"uuid";function bj(){return new sx({url:"https://us-west.metrics.momentic.ai/v1/metrics",headers:{"x-momentic-metrics-api-key":"c60c6a0f-60da-41a7-a61b-07969a0aa303"},temporalityPreference:Xi.DELTA})}var Ej=[new Tm({instrumentName:"test_event_duration",instrumentType:Ue.HISTOGRAM,aggregation:new Hc([100,500,1e3,2e3,3e3,4e3,5e3,7500,1e4,15e3,2e4],!1)}),new Tm({instrumentName:"test_step_duration",instrumentType:Ue.HISTOGRAM,aggregation:new Hc([100,500,1e3,2e3,3e3,4e3,5e3,7500,1e4,15e3,2e4],!1)})],vm=class{globalAttributes;provider;meter;counterCache=new Map;histogramCache=new Map;observableGaugeCache=new Map;gaugeValues=new Map;getCounter(e){let t=this.counterCache.get(e);if(t)return t;let n=this.meter.createCounter(e);return this.counterCache.set(e,n),n}getHistogram(e){let t=this.histogramCache.get(e);if(t)return t;let n=this.meter.createHistogram(e);return this.histogramCache.set(e,n),n}ensureObservableGauge(e){let t=this.observableGaugeCache.get(e);if(t)return t;let n=this.meter.createObservableGauge(e);return n.addCallback(o=>{let i=this.gaugeValues.get(e);i!==void 0&&o.observe(i,this.globalAttributes)}),this.observableGaugeCache.set(e,n),n}constructor(e){this.globalAttributes={...e.globalAttributes??{}};let t=typeof process<"u"?"production":"unknown",n=new Hf({[zd]:e.serviceName,[nC]:t,[iC]:typeof process<"u"&&process.env.SERVICE_INSTANCE_ID?process.env.SERVICE_INSTANCE_ID:yj()}),o=bj(),i=new dS({exporter:o,exportIntervalMillis:e.exportIntervalMs??6e4});this.provider=new yS({resource:n,readers:[i],views:Ej}),kd.setGlobalMeterProvider(this.provider),this.meter=kd.getMeter("momentic-serverless")}increment(e,t,n){try{let o=Ld(n,this.globalAttributes);this.getCounter(e).add(typeof t=="number"?t:1,o)}catch{}}gauge(e,t){try{this.ensureObservableGauge(e),this.gaugeValues.set(e,t)}catch{}}distribution(e,t,n){try{let o=Ld(n,this.globalAttributes);this.getHistogram(e).record(t,o)}catch{}}async flush(){try{await this.provider.forceFlush()}catch{}}async recordDuration({fn:e,name:t,tags:n}){let o=Date.now();try{return await Promise.resolve(e())}finally{this.distribution(t,Date.now()-o,n)}}};var nt=new Od;function C_(r){r.disabled||(nt=new vm(r))}import{exec as Tj}from"child_process";import{platform as x_}from"os";var vj=1e4;async function Wc(r){return new Promise(e=>{Tj(r,{timeout:vj},(t,n,o)=>{e({command:r,stdout:n,stderr:o,error:t?.message??null,timedOut:t?.killed??!1})})})}async function Aj(r){if(x_()==="win32")return Wc(`tracert ${r}`);let t=await Wc(`traceroute ${r}`);return t.stderr.includes("not found")||t.error?.includes("not found")?Wc(`tracepath ${r}`):t}async function Am(r){let t=x_()==="win32",n=t?`ping -n 3 ${r}`:`ping -c 3 ${r}`,i=`curl -w "\\n\\ntime_namelookup: %{time_namelookup}s\\ntime_connect: %{time_connect}s\\ntime_appconnect: %{time_appconnect}s\\ntime_starttransfer: %{time_starttransfer}s\\ntime_total: %{time_total}s\\n" -o ${t?"NUL":"/dev/null"} -s ${r}`,[a,s,c]=await Promise.all([Wc(n),Aj(r),Wc(i)]);return{ping:a,traceroute:s,curl:c}}var bS=!1;try{let r=await import("@sentry/node");r.init({dsn:"https://67a6ef469598f8880478f33863d05873@o4506426201800704.ingest.us.sentry.io/4510914396291072",environment:"production",release:"07f1ccd0b67577d56e0105f00baa9c6517636f17",tracesSampleRate:0,sendDefaultPii:!0}),pw(r.captureException),bS=!0}catch{}import{Argument as xu,Command as P6,Option as hg}from"@commander-js/extra-typings";import{confirm as Rj,input as wj}from"@inquirer/prompts";import{existsSync as axe,mkdirSync as sxe,statSync as Cj}from"fs";var xj=!1,__=(()=>{try{return Cj("/.dockerenv"),!0}catch{return!1}})();async function Rm(r){return Vi||xj||__?!0:(await P.flush(),await new Promise(t=>setTimeout(t,100)),await Rj({message:r}))}async function M_(r,e){return Vi||__?e:(await wj({message:r,default:e})).trim()||e}import _s,{supportsColor as Mj}from"chalk";import{Console as P_}from"console";import{format as jc}from"util";var ES=class extends Error{constructor(e,t,n){let o=Error.stackTraceLimit;n&&(Error.stackTraceLimit=Math.max(n,o||10)),super(e),Error.captureStackTrace&&Error.captureStackTrace(this,t),Error.stackTraceLimit=o}},wm=class r extends P_{_buffer=[];_groupDepth=0;Console=P_;constructor(){super({write:e=>(r.write(this._buffer,"log",e),!0)})}static write(e,t,n,o=2){let i=new ES(void 0,r.write).stack;if(!i)return e;let a=i.split(`
|
|
37
|
+
`,gS(l,e))}}catch(u){n={error:u}}finally{try{s&&!s.done&&(o=a.return)&&o.call(a)}finally{if(n)throw n.error}}return i},r}();var c_=function(){function r(e){this._backingStorages=e}return r.prototype.record=function(e,t,n,o){this._backingStorages.forEach(function(i){i.record(e,t,n,o)})},r}();rt();rt();var u_=function(){function r(e,t){this._instrumentName=e,this._valueType=t,this._buffer=new yn}return r.prototype.observe=function(e,t){if(t===void 0&&(t={}),typeof e!="number"){Z.warn("non-number value provided to metric "+this._instrumentName+": "+e);return}this._valueType===Or.INT&&!Number.isInteger(e)&&(Z.warn("INT value type cannot accept a floating-point value for "+this._instrumentName+", ignoring the fractional digits."),e=Math.trunc(e),!Number.isInteger(e))||this._buffer.set(t,e)},r}();var d_=function(){function r(){this._buffer=new Map}return r.prototype.observe=function(e,t,n){if(n===void 0&&(n={}),!!Gc(e)){var o=this._buffer.get(e);if(o==null&&(o=new yn,this._buffer.set(e,o)),typeof t!="number"){Z.warn("non-number value provided to metric "+e._descriptor.name+": "+t);return}e._descriptor.valueType===Or.INT&&!Number.isInteger(t)&&(Z.warn("INT value type cannot accept a floating-point value for "+e._descriptor.name+", ignoring the fractional digits."),t=Math.trunc(t),!Number.isInteger(t))||o.set(n,t)}},r}();var fS=function(r,e,t,n){function o(i){return i instanceof t?i:new t(function(a){a(i)})}return new(t||(t=Promise))(function(i,a){function s(u){try{l(n.next(u))}catch(d){a(d)}}function c(u){try{l(n.throw(u))}catch(d){a(d)}}function l(u){u.done?i(u.value):o(u.value).then(s,c)}l((n=n.apply(r,e||[])).next())})},SS=function(r,e){var t={label:0,sent:function(){if(i[0]&1)throw i[1];return i[1]},trys:[],ops:[]},n,o,i,a;return a={next:s(0),throw:s(1),return:s(2)},typeof Symbol=="function"&&(a[Symbol.iterator]=function(){return this}),a;function s(l){return function(u){return c([l,u])}}function c(l){if(n)throw new TypeError("Generator is already executing.");for(;t;)try{if(n=1,o&&(i=l[0]&2?o.return:l[0]?o.throw||((i=o.return)&&i.call(o),0):o.next)&&!(i=i.call(o,l[1])).done)return i;switch(o=0,i&&(l=[l[0]&2,i.value]),l[0]){case 0:case 1:i=l;break;case 4:return t.label++,{value:l[1],done:!1};case 5:t.label++,o=l[1],l=[0];continue;case 7:l=t.ops.pop(),t.trys.pop();continue;default:if(i=t.trys,!(i=i.length>0&&i[i.length-1])&&(l[0]===6||l[0]===2)){t=0;continue}if(l[0]===3&&(!i||l[1]>i[0]&&l[1]<i[3])){t.label=l[1];break}if(l[0]===6&&t.label<i[1]){t.label=i[1],i=l;break}if(i&&t.label<i[2]){t.label=i[2],t.ops.push(l);break}i[2]&&t.ops.pop(),t.trys.pop();continue}l=e.call(r,t)}catch(u){l=[6,u],o=0}finally{n=i=0}if(l[0]&5)throw l[1];return{value:l[0]?l[1]:void 0,done:!0}}},m_=function(r,e){var t=typeof Symbol=="function"&&r[Symbol.iterator];if(!t)return r;var n=t.call(r),o,i=[],a;try{for(;(e===void 0||e-- >0)&&!(o=n.next()).done;)i.push(o.value)}catch(s){a={error:s}}finally{try{o&&!o.done&&(t=n.return)&&t.call(n)}finally{if(a)throw a.error}}return i},p_=function(r,e,t){if(t||arguments.length===2)for(var n=0,o=e.length,i;n<o;n++)(i||!(n in e))&&(i||(i=Array.prototype.slice.call(e,0,n)),i[n]=e[n]);return r.concat(i||Array.prototype.slice.call(e))},g_=function(){function r(){this._callbacks=[],this._batchCallbacks=[]}return r.prototype.addCallback=function(e,t){var n=this._findCallback(e,t);n>=0||this._callbacks.push({callback:e,instrument:t})},r.prototype.removeCallback=function(e,t){var n=this._findCallback(e,t);n<0||this._callbacks.splice(n,1)},r.prototype.addBatchCallback=function(e,t){var n=new Set(t.filter(Gc));if(n.size===0){Z.error("BatchObservableCallback is not associated with valid instruments",t);return}var o=this._findBatchCallback(e,n);o>=0||this._batchCallbacks.push({callback:e,instruments:n})},r.prototype.removeBatchCallback=function(e,t){var n=new Set(t.filter(Gc)),o=this._findBatchCallback(e,n);o<0||this._batchCallbacks.splice(o,1)},r.prototype.observe=function(e,t){return fS(this,void 0,void 0,function(){var n,o,i,a;return SS(this,function(s){switch(s.label){case 0:return n=this._observeCallbacks(e,t),o=this._observeBatchCallbacks(e,t),[4,mx(p_(p_([],m_(n),!1),m_(o),!1))];case 1:return i=s.sent(),a=i.filter(px).map(function(c){return c.reason}),[2,a]}})})},r.prototype._observeCallbacks=function(e,t){var n=this;return this._callbacks.map(function(o){var i=o.callback,a=o.instrument;return fS(n,void 0,void 0,function(){var s,c;return SS(this,function(l){switch(l.label){case 0:return s=new u_(a._descriptor.name,a._descriptor.valueType),c=Promise.resolve(i(s)),t!=null&&(c=Vo(c,t)),[4,c];case 1:return l.sent(),a._metricStorages.forEach(function(u){u.record(s._buffer,e)}),[2]}})})})},r.prototype._observeBatchCallbacks=function(e,t){var n=this;return this._batchCallbacks.map(function(o){var i=o.callback,a=o.instruments;return fS(n,void 0,void 0,function(){var s,c;return SS(this,function(l){switch(l.label){case 0:return s=new d_,c=Promise.resolve(i(s)),t!=null&&(c=Vo(c,t)),[4,c];case 1:return l.sent(),a.forEach(function(u){var d=s._buffer.get(u);d!=null&&u._metricStorages.forEach(function(p){p.record(d,e)})}),[2]}})})})},r.prototype._findCallback=function(e,t){return this._callbacks.findIndex(function(n){return n.callback===e&&n.instrument===t})},r.prototype._findBatchCallback=function(e,t){return this._batchCallbacks.findIndex(function(n){return n.callback===e&&gx(n.instruments,t)})},r}();var aj=function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(n,o){n.__proto__=o}||function(n,o){for(var i in o)Object.prototype.hasOwnProperty.call(o,i)&&(n[i]=o[i])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function n(){this.constructor=e}e.prototype=t===null?Object.create(t):(n.prototype=t.prototype,new n)}}(),h_=function(r){aj(e,r);function e(t,n,o,i,a){var s=r.call(this,t)||this;return s._attributesProcessor=o,s._aggregationCardinalityLimit=a,s._deltaMetricStorage=new fm(n,s._aggregationCardinalityLimit),s._temporalMetricStorage=new Sm(n,i),s}return e.prototype.record=function(t,n,o,i){n=this._attributesProcessor.process(n,o),this._deltaMetricStorage.record(t,n,o,i)},e.prototype.collect=function(t,n){var o=this._deltaMetricStorage.collect();return this._temporalMetricStorage.buildMetrics(t,this._instrumentDescriptor,o,n)},e}(hm);var f_=function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(n,o){n.__proto__=o}||function(n,o){for(var i in o)Object.prototype.hasOwnProperty.call(o,i)&&(n[i]=o[i])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function n(){this.constructor=e}e.prototype=t===null?Object.create(t):(n.prototype=t.prototype,new n)}}(),ws=function(){function r(){}return r.Noop=function(){return lj},r}();var sj=function(r){f_(e,r);function e(){return r!==null&&r.apply(this,arguments)||this}return e.prototype.process=function(t,n){return t},e}(ws);var S_=function(r){f_(e,r);function e(t){var n=r.call(this)||this;return n._allowedAttributeNames=t,n}return e.prototype.process=function(t,n){var o=this,i={};return Object.keys(t).filter(function(a){return o._allowedAttributeNames.includes(a)}).forEach(function(a){return i[a]=t[a]}),i},e}(ws);var lj=new sj;var cj=function(r,e,t,n){function o(i){return i instanceof t?i:new t(function(a){a(i)})}return new(t||(t=Promise))(function(i,a){function s(u){try{l(n.next(u))}catch(d){a(d)}}function c(u){try{l(n.throw(u))}catch(d){a(d)}}function l(u){u.done?i(u.value):o(u.value).then(s,c)}l((n=n.apply(r,e||[])).next())})},uj=function(r,e){var t={label:0,sent:function(){if(i[0]&1)throw i[1];return i[1]},trys:[],ops:[]},n,o,i,a;return a={next:s(0),throw:s(1),return:s(2)},typeof Symbol=="function"&&(a[Symbol.iterator]=function(){return this}),a;function s(l){return function(u){return c([l,u])}}function c(l){if(n)throw new TypeError("Generator is already executing.");for(;t;)try{if(n=1,o&&(i=l[0]&2?o.return:l[0]?o.throw||((i=o.return)&&i.call(o),0):o.next)&&!(i=i.call(o,l[1])).done)return i;switch(o=0,i&&(l=[l[0]&2,i.value]),l[0]){case 0:case 1:i=l;break;case 4:return t.label++,{value:l[1],done:!1};case 5:t.label++,o=l[1],l=[0];continue;case 7:l=t.ops.pop(),t.trys.pop();continue;default:if(i=t.trys,!(i=i.length>0&&i[i.length-1])&&(l[0]===6||l[0]===2)){t=0;continue}if(l[0]===3&&(!i||l[1]>i[0]&&l[1]<i[3])){t.label=l[1];break}if(l[0]===6&&t.label<i[1]){t.label=i[1],i=l;break}if(i&&t.label<i[2]){t.label=i[2],t.ops.push(l);break}i[2]&&t.ops.pop(),t.trys.pop();continue}l=e.call(r,t)}catch(u){l=[6,u],o=0}finally{n=i=0}if(l[0]&5)throw l[1];return{value:l[0]?l[1]:void 0,done:!0}}},dj=function(r,e){var t=typeof Symbol=="function"&&r[Symbol.iterator];if(!t)return r;var n=t.call(r),o,i=[],a;try{for(;(e===void 0||e-- >0)&&!(o=n.next()).done;)i.push(o.value)}catch(s){a={error:s}}finally{try{o&&!o.done&&(t=n.return)&&t.call(n)}finally{if(a)throw a.error}}return i},y_=function(){function r(e,t){this._meterProviderSharedState=e,this._instrumentationScope=t,this.metricStorageRegistry=new l_,this.observableRegistry=new g_,this.meter=new o_(this)}return r.prototype.registerMetricStorage=function(e){var t=this._registerMetricStorage(e,h_);return t.length===1?t[0]:new c_(t)},r.prototype.registerAsyncMetricStorage=function(e){var t=this._registerMetricStorage(e,s_);return t},r.prototype.collect=function(e,t,n){return cj(this,void 0,void 0,function(){var o,i,a;return uj(this,function(s){switch(s.label){case 0:return[4,this.observableRegistry.observe(t,n?.timeoutMillis)];case 1:return o=s.sent(),i=this.metricStorageRegistry.getStorages(e),i.length===0?[2,null]:(a=i.map(function(c){return c.collect(e,t)}).filter(ux),a.length===0?[2,{errors:o}]:[2,{scopeMetrics:{scope:this._instrumentationScope,metrics:a},errors:o}])}})})},r.prototype._registerMetricStorage=function(e,t){var n=this,o=this._meterProviderSharedState.viewRegistry.findViews(e,this._instrumentationScope),i=o.map(function(c){var l=Sx(c,e),u=n.metricStorageRegistry.findOrUpdateCompatibleStorage(l);if(u!=null)return u;var d=c.aggregation.createAggregator(l),p=new t(l,d,c.attributesProcessor,n._meterProviderSharedState.metricCollectors,c.aggregationCardinalityLimit);return n.metricStorageRegistry.register(p),p});if(i.length===0){var a=this._meterProviderSharedState.selectAggregations(e.type),s=a.map(function(c){var l=dj(c,2),u=l[0],d=l[1],p=n.metricStorageRegistry.findOrUpdateCompatibleCollectorStorage(u,e);if(p!=null)return p;var m=d.createAggregator(e),g=u.selectCardinalityLimit(e.type),h=new t(e,m,ws.Noop(),[u],g);return n.metricStorageRegistry.registerForCollector(u,h),h});i=i.concat(s)}return i},r}();var mj=function(r){var e=typeof Symbol=="function"&&Symbol.iterator,t=e&&r[e],n=0;if(t)return t.call(r);if(r&&typeof r.length=="number")return{next:function(){return r&&n>=r.length&&(r=void 0),{value:r&&r[n++],done:!r}}};throw new TypeError(e?"Object is not iterable.":"Symbol.iterator is not defined.")},b_=function(){function r(e){this.resource=e,this.viewRegistry=new Xx,this.metricCollectors=[],this.meterSharedStates=new Map}return r.prototype.getMeterSharedState=function(e){var t=dx(e),n=this.meterSharedStates.get(t);return n==null&&(n=new y_(this,e),this.meterSharedStates.set(t,n)),n},r.prototype.selectAggregations=function(e){var t,n,o=[];try{for(var i=mj(this.metricCollectors),a=i.next();!a.done;a=i.next()){var s=a.value;o.push([s,s.selectAggregation(e)])}}catch(c){t={error:c}}finally{try{a&&!a.done&&(n=i.return)&&n.call(i)}finally{if(t)throw t.error}}return o},r}();var ym=function(r,e,t,n){function o(i){return i instanceof t?i:new t(function(a){a(i)})}return new(t||(t=Promise))(function(i,a){function s(u){try{l(n.next(u))}catch(d){a(d)}}function c(u){try{l(n.throw(u))}catch(d){a(d)}}function l(u){u.done?i(u.value):o(u.value).then(s,c)}l((n=n.apply(r,e||[])).next())})},bm=function(r,e){var t={label:0,sent:function(){if(i[0]&1)throw i[1];return i[1]},trys:[],ops:[]},n,o,i,a;return a={next:s(0),throw:s(1),return:s(2)},typeof Symbol=="function"&&(a[Symbol.iterator]=function(){return this}),a;function s(l){return function(u){return c([l,u])}}function c(l){if(n)throw new TypeError("Generator is already executing.");for(;t;)try{if(n=1,o&&(i=l[0]&2?o.return:l[0]?o.throw||((i=o.return)&&i.call(o),0):o.next)&&!(i=i.call(o,l[1])).done)return i;switch(o=0,i&&(l=[l[0]&2,i.value]),l[0]){case 0:case 1:i=l;break;case 4:return t.label++,{value:l[1],done:!1};case 5:t.label++,o=l[1],l=[0];continue;case 7:l=t.ops.pop(),t.trys.pop();continue;default:if(i=t.trys,!(i=i.length>0&&i[i.length-1])&&(l[0]===6||l[0]===2)){t=0;continue}if(l[0]===3&&(!i||l[1]>i[0]&&l[1]<i[3])){t.label=l[1];break}if(l[0]===6&&t.label<i[1]){t.label=i[1],i=l;break}if(i&&t.label<i[2]){t.label=i[2],t.ops.push(l);break}i[2]&&t.ops.pop(),t.trys.pop();continue}l=e.call(r,t)}catch(u){l=[6,u],o=0}finally{n=i=0}if(l[0]&5)throw l[1];return{value:l[0]?l[1]:void 0,done:!0}}},pj=function(r,e){var t=typeof Symbol=="function"&&r[Symbol.iterator];if(!t)return r;var n=t.call(r),o,i=[],a;try{for(;(e===void 0||e-- >0)&&!(o=n.next()).done;)i.push(o.value)}catch(s){a={error:s}}finally{try{o&&!o.done&&(t=n.return)&&t.call(n)}finally{if(a)throw a.error}}return i},gj=function(r,e,t){if(t||arguments.length===2)for(var n=0,o=e.length,i;n<o;n++)(i||!(n in e))&&(i||(i=Array.prototype.slice.call(e,0,n)),i[n]=e[n]);return r.concat(i||Array.prototype.slice.call(e))},E_=function(){function r(e,t){this._sharedState=e,this._metricReader=t}return r.prototype.collect=function(e){return ym(this,void 0,void 0,function(){var t,n,o,i,a=this;return bm(this,function(s){switch(s.label){case 0:return t=Zi(Date.now()),n=[],o=[],i=Array.from(this._sharedState.meterSharedStates.values()).map(function(c){return ym(a,void 0,void 0,function(){var l;return bm(this,function(u){switch(u.label){case 0:return[4,c.collect(this,t,e)];case 1:return l=u.sent(),l?.scopeMetrics!=null&&n.push(l.scopeMetrics),l?.errors!=null&&o.push.apply(o,gj([],pj(l.errors),!1)),[2]}})})}),[4,Promise.all(i)];case 1:return s.sent(),[2,{resourceMetrics:{resource:this._sharedState.resource,scopeMetrics:n},errors:o}]}})})},r.prototype.forceFlush=function(e){return ym(this,void 0,void 0,function(){return bm(this,function(t){switch(t.label){case 0:return[4,this._metricReader.forceFlush(e)];case 1:return t.sent(),[2]}})})},r.prototype.shutdown=function(e){return ym(this,void 0,void 0,function(){return bm(this,function(t){switch(t.label){case 0:return[4,this._metricReader.shutdown(e)];case 1:return t.sent(),[2]}})})},r.prototype.selectAggregationTemporality=function(e){return this._metricReader.selectAggregationTemporality(e)},r.prototype.selectAggregation=function(e){return this._metricReader.selectAggregation(e)},r.prototype.selectCardinalityLimit=function(e){var t,n,o;return(o=(n=(t=this._metricReader).selectCardinalityLimit)===null||n===void 0?void 0:n.call(t,e))!==null&&o!==void 0?o:2e3},r}();var T_=function(r,e,t,n){function o(i){return i instanceof t?i:new t(function(a){a(i)})}return new(t||(t=Promise))(function(i,a){function s(u){try{l(n.next(u))}catch(d){a(d)}}function c(u){try{l(n.throw(u))}catch(d){a(d)}}function l(u){u.done?i(u.value):o(u.value).then(s,c)}l((n=n.apply(r,e||[])).next())})},v_=function(r,e){var t={label:0,sent:function(){if(i[0]&1)throw i[1];return i[1]},trys:[],ops:[]},n,o,i,a;return a={next:s(0),throw:s(1),return:s(2)},typeof Symbol=="function"&&(a[Symbol.iterator]=function(){return this}),a;function s(l){return function(u){return c([l,u])}}function c(l){if(n)throw new TypeError("Generator is already executing.");for(;t;)try{if(n=1,o&&(i=l[0]&2?o.return:l[0]?o.throw||((i=o.return)&&i.call(o),0):o.next)&&!(i=i.call(o,l[1])).done)return i;switch(o=0,i&&(l=[l[0]&2,i.value]),l[0]){case 0:case 1:i=l;break;case 4:return t.label++,{value:l[1],done:!1};case 5:t.label++,o=l[1],l=[0];continue;case 7:l=t.ops.pop(),t.trys.pop();continue;default:if(i=t.trys,!(i=i.length>0&&i[i.length-1])&&(l[0]===6||l[0]===2)){t=0;continue}if(l[0]===3&&(!i||l[1]>i[0]&&l[1]<i[3])){t.label=l[1];break}if(l[0]===6&&t.label<i[1]){t.label=i[1],i=l;break}if(i&&t.label<i[2]){t.label=i[2],t.ops.push(l);break}i[2]&&t.ops.pop(),t.trys.pop();continue}l=e.call(r,t)}catch(u){l=[6,u],o=0}finally{n=i=0}if(l[0]&5)throw l[1];return{value:l[0]?l[1]:void 0,done:!0}}},A_=function(r){var e=typeof Symbol=="function"&&Symbol.iterator,t=e&&r[e],n=0;if(t)return t.call(r);if(r&&typeof r.length=="number")return{next:function(){return r&&n>=r.length&&(r=void 0),{value:r&&r[n++],done:!r}}};throw new TypeError(e?"Object is not iterable.":"Symbol.iterator is not defined.")};function hj(r,e){var t=e??mm.empty();return r?mm.default().merge(t):t}var yS=function(){function r(e){var t,n,o,i,a;if(this._shutdown=!1,this._sharedState=new b_(hj((a=e?.mergeResourceWithDefaults)!==null&&a!==void 0?a:!0,e?.resource)),e?.views!=null&&e.views.length>0)try{for(var s=A_(e.views),c=s.next();!c.done;c=s.next()){var l=c.value;this._sharedState.viewRegistry.addView(l)}}catch(m){t={error:m}}finally{try{c&&!c.done&&(n=s.return)&&n.call(s)}finally{if(t)throw t.error}}if(e?.readers!=null&&e.readers.length>0)try{for(var u=A_(e.readers),d=u.next();!d.done;d=u.next()){var p=d.value;this.addMetricReader(p)}}catch(m){o={error:m}}finally{try{d&&!d.done&&(i=u.return)&&i.call(u)}finally{if(o)throw o.error}}}return r.prototype.getMeter=function(e,t,n){return t===void 0&&(t=""),n===void 0&&(n={}),this._shutdown?(Z.warn("A shutdown MeterProvider cannot provide a Meter"),Af()):this._sharedState.getMeterSharedState({name:e,version:t,schemaUrl:n.schemaUrl}).meter},r.prototype.addMetricReader=function(e){var t=new E_(this._sharedState,e);e.setMetricProducer(t),this._sharedState.metricCollectors.push(t)},r.prototype.shutdown=function(e){return T_(this,void 0,void 0,function(){return v_(this,function(t){switch(t.label){case 0:return this._shutdown?(Z.warn("shutdown may only be called once per MeterProvider"),[2]):(this._shutdown=!0,[4,Promise.all(this._sharedState.metricCollectors.map(function(n){return n.shutdown(e)}))]);case 1:return t.sent(),[2]}})})},r.prototype.forceFlush=function(e){return T_(this,void 0,void 0,function(){return v_(this,function(t){switch(t.label){case 0:return this._shutdown?(Z.warn("invalid attempt to force flush after MeterProvider shutdown"),[2]):[4,Promise.all(this._sharedState.metricCollectors.map(function(n){return n.forceFlush(e)}))];case 1:return t.sent(),[2]}})})},r}();var fj=/[\^$\\.+?()[\]{}|]/g,Em=function(){function r(e){e==="*"?(this._matchAll=!0,this._regexp=/.*/):(this._matchAll=!1,this._regexp=new RegExp(r.escapePattern(e)))}return r.prototype.match=function(e){return this._matchAll?!0:this._regexp.test(e)},r.escapePattern=function(e){return"^"+e.replace(fj,"\\$&").replace("*",".*")+"$"},r.hasWildcard=function(e){return e.includes("*")},r}();var Cs=function(){function r(e){this._matchAll=e===void 0,this._pattern=e}return r.prototype.match=function(e){return!!(this._matchAll||e===this._pattern)},r}();var R_=function(){function r(e){var t;this._nameFilter=new Em((t=e?.name)!==null&&t!==void 0?t:"*"),this._type=e?.type,this._unitFilter=new Cs(e?.unit)}return r.prototype.getType=function(){return this._type},r.prototype.getNameFilter=function(){return this._nameFilter},r.prototype.getUnitFilter=function(){return this._unitFilter},r}();var w_=function(){function r(e){this._nameFilter=new Cs(e?.name),this._versionFilter=new Cs(e?.version),this._schemaUrlFilter=new Cs(e?.schemaUrl)}return r.prototype.getNameFilter=function(){return this._nameFilter},r.prototype.getVersionFilter=function(){return this._versionFilter},r.prototype.getSchemaUrlFilter=function(){return this._schemaUrlFilter},r}();function Sj(r){return r.instrumentName==null&&r.instrumentType==null&&r.instrumentUnit==null&&r.meterName==null&&r.meterVersion==null&&r.meterSchemaUrl==null}var Tm=function(){function r(e){var t;if(Sj(e))throw new Error("Cannot create view with no selector arguments supplied");if(e.name!=null&&(e?.instrumentName==null||Em.hasWildcard(e.instrumentName)))throw new Error("Views with a specified name must be declared with an instrument selector that selects at most one instrument per meter.");e.attributeKeys!=null?this.attributesProcessor=new S_(e.attributeKeys):this.attributesProcessor=ws.Noop(),this.name=e.name,this.description=e.description,this.aggregation=(t=e.aggregation)!==null&&t!==void 0?t:en.Default(),this.instrumentSelector=new R_({name:e.instrumentName,type:e.instrumentType,unit:e.instrumentUnit}),this.meterSelector=new w_({name:e.meterName,version:e.meterVersion,schemaUrl:e.meterSchemaUrl}),this.aggregationCardinalityLimit=e.aggregationCardinalityLimit}return r}();var hCe=process.env.APP||"unknown";rt();import{v4 as yj}from"uuid";function bj(){return new sx({url:"https://us-west.metrics.momentic.ai/v1/metrics",headers:{"x-momentic-metrics-api-key":"c60c6a0f-60da-41a7-a61b-07969a0aa303"},temporalityPreference:Xi.DELTA})}var Ej=[new Tm({instrumentName:"test_event_duration",instrumentType:Ue.HISTOGRAM,aggregation:new Hc([100,500,1e3,2e3,3e3,4e3,5e3,7500,1e4,15e3,2e4],!1)}),new Tm({instrumentName:"test_step_duration",instrumentType:Ue.HISTOGRAM,aggregation:new Hc([100,500,1e3,2e3,3e3,4e3,5e3,7500,1e4,15e3,2e4],!1)})],vm=class{globalAttributes;provider;meter;counterCache=new Map;histogramCache=new Map;observableGaugeCache=new Map;gaugeValues=new Map;getCounter(e){let t=this.counterCache.get(e);if(t)return t;let n=this.meter.createCounter(e);return this.counterCache.set(e,n),n}getHistogram(e){let t=this.histogramCache.get(e);if(t)return t;let n=this.meter.createHistogram(e);return this.histogramCache.set(e,n),n}ensureObservableGauge(e){let t=this.observableGaugeCache.get(e);if(t)return t;let n=this.meter.createObservableGauge(e);return n.addCallback(o=>{let i=this.gaugeValues.get(e);i!==void 0&&o.observe(i,this.globalAttributes)}),this.observableGaugeCache.set(e,n),n}constructor(e){this.globalAttributes={...e.globalAttributes??{}};let t=typeof process<"u"?"production":"unknown",n=new Hf({[zd]:e.serviceName,[nC]:t,[iC]:typeof process<"u"&&process.env.SERVICE_INSTANCE_ID?process.env.SERVICE_INSTANCE_ID:yj()}),o=bj(),i=new dS({exporter:o,exportIntervalMillis:e.exportIntervalMs??6e4});this.provider=new yS({resource:n,readers:[i],views:Ej}),kd.setGlobalMeterProvider(this.provider),this.meter=kd.getMeter("momentic-serverless")}increment(e,t,n){try{let o=Ld(n,this.globalAttributes);this.getCounter(e).add(typeof t=="number"?t:1,o)}catch{}}gauge(e,t){try{this.ensureObservableGauge(e),this.gaugeValues.set(e,t)}catch{}}distribution(e,t,n){try{let o=Ld(n,this.globalAttributes);this.getHistogram(e).record(t,o)}catch{}}async flush(){try{await this.provider.forceFlush()}catch{}}async recordDuration({fn:e,name:t,tags:n}){let o=Date.now();try{return await Promise.resolve(e())}finally{this.distribution(t,Date.now()-o,n)}}};var nt=new Od;function C_(r){r.disabled||(nt=new vm(r))}import{exec as Tj}from"child_process";import{platform as x_}from"os";var vj=1e4;async function Wc(r){return new Promise(e=>{Tj(r,{timeout:vj},(t,n,o)=>{e({command:r,stdout:n,stderr:o,error:t?.message??null,timedOut:t?.killed??!1})})})}async function Aj(r){if(x_()==="win32")return Wc(`tracert ${r}`);let t=await Wc(`traceroute ${r}`);return t.stderr.includes("not found")||t.error?.includes("not found")?Wc(`tracepath ${r}`):t}async function Am(r){let t=x_()==="win32",n=t?`ping -n 3 ${r}`:`ping -c 3 ${r}`,i=`curl -w "\\n\\ntime_namelookup: %{time_namelookup}s\\ntime_connect: %{time_connect}s\\ntime_appconnect: %{time_appconnect}s\\ntime_starttransfer: %{time_starttransfer}s\\ntime_total: %{time_total}s\\n" -o ${t?"NUL":"/dev/null"} -s ${r}`,[a,s,c]=await Promise.all([Wc(n),Aj(r),Wc(i)]);return{ping:a,traceroute:s,curl:c}}var bS=!1;try{let r=await import("@sentry/node");r.init({dsn:"https://67a6ef469598f8880478f33863d05873@o4506426201800704.ingest.us.sentry.io/4510914396291072",environment:"production",release:"ab3ea4c12964faac9da27c7eb933410207c59c0d",tracesSampleRate:0,sendDefaultPii:!0}),pw(r.captureException),bS=!0}catch{}import{Argument as xu,Command as P6,Option as hg}from"@commander-js/extra-typings";import{confirm as Rj,input as wj}from"@inquirer/prompts";import{existsSync as axe,mkdirSync as sxe,statSync as Cj}from"fs";var xj=!1,__=(()=>{try{return Cj("/.dockerenv"),!0}catch{return!1}})();async function Rm(r){return Vi||xj||__?!0:(await P.flush(),await new Promise(t=>setTimeout(t,100)),await Rj({message:r}))}async function M_(r,e){return Vi||__?e:(await wj({message:r,default:e})).trim()||e}import _s,{supportsColor as Mj}from"chalk";import{Console as P_}from"console";import{format as jc}from"util";var ES=class extends Error{constructor(e,t,n){let o=Error.stackTraceLimit;n&&(Error.stackTraceLimit=Math.max(n,o||10)),super(e),Error.captureStackTrace&&Error.captureStackTrace(this,t),Error.stackTraceLimit=o}},wm=class r extends P_{_buffer=[];_groupDepth=0;Console=P_;constructor(){super({write:e=>(r.write(this._buffer,"log",e),!0)})}static write(e,t,n,o=2){let i=new ES(void 0,r.write).stack;if(!i)return e;let a=i.split(`
|
|
38
38
|
`).slice(o).filter(Boolean).join(`
|
|
39
39
|
`);return e.push({message:n,origin:a,type:t}),e}_log(e,t){r.write(this._buffer,e," ".repeat(this._groupDepth)+t,3)}debug(e,...t){this._log("debug",jc(e,...t))}error(e,...t){this._log("error",jc(e,...t))}info(e,...t){this._log("info",jc(e,...t))}log(e,...t){this._log("log",jc(e,...t))}warn(e,...t){this._log("warn",jc(e,...t))}getBuffer(){return this._buffer.length>0?this._buffer:void 0}};function I_(r){let e=globalThis.console,t=new wm;globalThis.console=t;try{r()}finally{let o=t.getBuffer()?.map(i=>i.message).join(`
|
|
40
40
|
`);process.stderr.write(`${o}
|
|
41
|
-
`),globalThis.console=e}}var xs=" ".repeat(6);import{hostname as _j}from"os";var yr=ms({app:"cli",hostname:_j(),disableConsoleLogs:!0,captureExceptions:!0}).child({cliVersion:"0.
|
|
41
|
+
`),globalThis.console=e}}var xs=" ".repeat(6);import{hostname as _j}from"os";var yr=ms({app:"cli",hostname:_j(),disableConsoleLogs:!0,captureExceptions:!0}).child({cliVersion:"0.34.0"});function TS(r){if(!r)return;r=r.toLowerCase();let e=Rd.safeParse(r);if(e.success)return P.setMinLevel(e.data),e.data}function O_({results:r,startTime:e,entity:t,getDisplayLine:n,onFailed:o}){let i=r.filter(u=>u.status==="PASSED"&&u.quarantined),a=r.filter(u=>u.status==="PASSED"&&!u.quarantined),s=r.filter(u=>u.status==="FAILED"&&u.quarantined),c=r.filter(u=>u.status==="FAILED"&&!u.quarantined),l=r.filter(u=>u.status==="CANCELLED");return I_(()=>{if(c.forEach(u=>{P.log(""),o(u)}),c.length){P.log("");let u=c.length===1?"":"s";P.error(`${c.length} ${t}${u} failed:`),c.forEach(d=>{P.dimmed(n(d))})}if(l.length){P.log("");let u=l.length===1?"":"s";P.warn(`${l.length} ${t}${u} cancelled:`),l.forEach(d=>{P.dimmed(n(d))})}if(a.length){P.log("");let u=a.length===1?"":"s";P.success(`${a.length} ${t}${u} passed:`),a.forEach(d=>{P.dimmed(n(d))})}if(s.length){P.log("");let u=s.length===1?"":"s";P.warn(`${s.length} quarantined ${t}${u} failed:`),s.forEach(d=>{P.dimmed(n(d))})}if(i.length){P.log("");let u=i.length===1?"":"s";P.warn(`${i.length} quarantined ${t}${u} passed:`),i.forEach(d=>{P.dimmed(n(d))})}P.log(""),P.dimmed(`Total time: ${Math.round((Date.now()-e)/1e3)}s`)}),{quarantinedPassed:i.length,passed:a.length,quarantinedFailed:s.length,failed:c.length,cancelled:l.length}}var Vc=({status:r,testLogRef:e,getRunningTestsCount:t,getTotalTestsCount:n,additionalText:o})=>{r=r.toUpperCase();let i=r,a;r.includes("FAIL")?(i=_s.bgRed.white("FAIL"),a=3):r.includes("PASS")?(i=_s.bgGreen.white("PASS"),a=3):r.includes("START")?(i=_s.bgBlue.white("START"),a=2):r.includes("CANCEL")?(i=_s.bgRgb(191,68,11).white("CANCEL"),a=1):r.includes("RETRY")?(i=_s.bgRgb(191,68,11).white("RETRY"),a=2):r.includes("RUN")||r.includes("PROG")?(i=_s.bgMagenta.white("RUNNING"),a=0):(P.warn(`Unknown status tried to be logged in run test locally: ${r}`),a=0),Mj||(i=`${i}`),P.log(`${i}${" ".repeat(a)} ${e} ${o?`${o} `:""}(${t()}/${n()})`)};import Pj from"fs";import{platform as Ij,tmpdir as Oj}from"os";import Lj from"path";import{program as Nj}from"playwright-core/lib/cli/program";import{registry as $c}from"playwright-core/lib/server";import L_ from"proper-lockfile";var N_=Lj.join(Oj(),"momenticBrowserInstallation");var vS=["chrome","chromium","chrome-for-testing","ffmpeg"],Dj={Chromium:"chromium","Google Chrome":"chrome","Chrome for Testing":"chrome-for-testing"},D_={chrome:"chrome",chromium:"chromium","chrome-for-testing":"chromium-headless-shell",ffmpeg:"ffmpeg"};function k_(r){if(r==="Org Default")return!1;let e=D_[Dj[r]??""]??"",t=$c.findExecutable(e);return!t||t.installType==="none"?!1:AS(t)}function AS(r){let e=r.executablePath();return Pj.existsSync(e)}function kj(r,e){let t=D_[r];if(!t)throw new Error(`Requested install of unknown browser type ${r}`);let n=$c.findExecutable(t);if(!n||n.installType==="none")throw new Error(`Requested install of unknown browser type ${r}`);if(!(!e&&AS(n)))return n}async function Fj({browser:r,force:e}){let t=kj(r,e);if(!t){P.info(`Browser '${r}' is already installed, skipping...`);return}P.info(`Installing browser '${r}'...`);try{await $c.installDeps([t],!1),await $c.install([t],!1)}catch(n){if(n.message.includes("Lock file is already being held")){P.warn("Another process is installing Playwright browsers. Waiting for completion before proceeding..");let o=$c.findExecutable(r),i=5*60*1e3,a=Date.now();for(;Date.now()-a<i&&!AS(o);)P.info("Waiting for browser to finish installing..."),await new Promise(s=>setTimeout(s,5e3))}else throw n}}async function Uj(){if(Ij()==="win32"){P.info("Installing Windows dependencies for Playwright...");try{await Nj.parseAsync(["","","install","winldd"])}catch(r){P.warn(`Failed to install Windows dependencies: ${r}. Continuing with browser installation...`)}}}async function Cm({rawBrowsers:r,force:e=!1,all:t=!1}){await Uj();let n=t?vS:Array.from(new Set(r));try{await L_.lock(N_,{stale:1e3*60*5,update:1e3*60,realpath:!1,retries:{retries:30,factor:2,maxTimeout:15e3,minTimeout:500}})}catch(i){P.warn(`Failed to acquire lock to install browsers. Please ensure that any other process installing browsers completes within 5 minutes: ${i}. Continuing without installation...`);return}let o;try{for(let i of n)try{await Fj({browser:i,force:e})}catch(a){o=a,P.error(`Failed to install the ${i} browser: ${a}`)}}finally{await L_.unlock(N_,{realpath:!1})}if(o)throw o}import{createServer as Bj}from"http";async function Yo(r,e,t=30){for(let n=0;n<t;n+=1){let o=r+n;if(await xm(o))return o}P.error(`Could not find an available port for ${e} starting from ${r} after ${t} attempts`),process.exit(1)}async function xm(r){return new Promise((e,t)=>{let n=Bj();n.once("error",o=>{o.code==="EADDRINUSE"?e(!1):(P.warn({err:o},"Unexpected error checking for open ports, continuing..."),n.close(),e(!0))}),n.once("listening",()=>{n.close(()=>{e(!0)})}),n.listen(r)})}import t_e from"blocked-at";import n_e from"why-is-node-running";function F_(r){let e=r?.shardIndex??1,t=r?.shardCount??1;if(e<1)throw new Error("Shard index must be greater than 0.");if(t<1)throw new Error("Shard count must be greater than 0.");if(e>t)throw new Error("Shard index cannot be greater than shard count")}function zj(r,e,t,n){if(t>r.length&&(P.warn(`Shard count ${t} is greater than the number of tests ${r.length}! Some workers won't have any tests to run.`),t=Math.max(t,r.length),e>t))return[];let o=Math.floor((e-1)*(r.length/t)),i=Math.floor(e*(r.length/t));return(n?[...r].sort((s,c)=>n(s).localeCompare(n(c))):[...r].sort()).filter((s,c)=>c>=o&&c<i)}function U_(r){let{items:e,shardIndex:t,shardCount:n,sortKey:o}=r;return n>1?zj(e,t,n,o):e}function RS({regenerateCache:r,saveCache:e,disableCache:t}){if(t){if(r)throw new Error("--disable-cache and --regenerate-cache cannot be used together.");if(e)throw new Error("--disable-cache and --save-cache cannot be used together.")}}function B_(r,e,t){return r instanceof vi?(r.zodIssues.forEach(n=>{t.push({file:e,stepIndex:typeof n.path[0]=="number"?n.path[0]:void 0,field:n.path.slice(1).join(".")||n.path.join("."),issue:n.message})}),!0):!1}function wS({parsingErrors:r,parsingErrorDetails:e,failedTestFilePaths:t,failedModuleFilePaths:n}){if(P.error(`
|
|
42
42
|
Found ${r} file(s) with validation errors that must be fixed manually:
|
|
43
43
|
`),e.length>0){let o=new Map;e.forEach(i=>{let a=o.get(i.file)||[];a.push(i),o.set(i.file,a)}),o.forEach((i,a)=>{P.error(` ${a}`),i.forEach(({stepIndex:s,field:c,issue:l})=>{let u=s!==void 0?`Step ${s}`:"File",d=c?`, field "${c}"`:"";P.error(` ${u}${d}:`),P.error(` \u2192 ${l}`)})})}else t.size>0&&P.error(`Failed test files:
|
|
44
44
|
${[...t].map(o=>`${xs}- ${o}`).join(`
|
|
@@ -4580,9 +4580,9 @@ ${r}`;case"ELEMENT_CHECK":return`${ZI}
|
|
|
4580
4580
|
${r}`;default:return r}}async function an({frameConfig:r,action:e,browser:t}){let n=t.getActiveFrameConfig();r?t.setActiveFrameConfig(r):n?.type==="auto"&&t.setActiveFrameConfig(void 0);try{return await e()}finally{t.setActiveFrameConfig(n)}}var W2=["NAVIGATE","NEW_TAB","TAB","REFRESH","WAIT_FOR_URL"];async function tO({beforeUrl:r,beforePages:e,browser:t,command:n,logger:o}){if(W2.includes(n.type))return;let s=("cache"in n&&n.cache&&"target"in n.cache?n.cache.target:void 0)?.nodeOnlySerializedHtml?.includes("<a")??!1?300:3e3,c=Date.now(),l=0;for(;l===0||Date.now()-c<s;){await J(250),l++;let u=(await t.getOpenPages()).map(p=>p.url),d=t.url();if(u.length!==e.length)for(let p=u.length-1;p>=e.length;p--){let m=u[p];if(ra(m,o)&&m!==r&&m!==d){o.info({beforePages:e,afterPages:u,beforeUrl:r},"Auto-following new tab after preset action"),await t.switchToPage({type:"INDEX",index:String(p)});break}}}}async function jn(r,e={}){let t=await r.getBrowserState(e);return{serializedTree:t.serialize(e.serializationOpts),tree:t}}var rO=r=>!!r&&Aa(r),nO=r=>{let{cache:e,description:t,disableSecondaryCacheResolution:n,logger:o}=r,i=e,a=!1;return i&&n&&i.targetSource==="HEURISTIC_HEALED"&&(a=!0,i=void 0),i?.inputDescription&&!QI(t,i.inputDescription)&&(o.warn({old:i.inputDescription,new:t},"Target cache was generated with a different description, clearing it automatically"),a=!0,i=void 0),{cache:i,cacheBustedBeforeAction:a}};import{randomUUID as Y2}from"crypto";var iO={minChunkTokenCount:500,acceptableChunkTokenCount:3e3,maxChunkTokenCount:8e3,maxLineLength:4e3},aO={minChunkTokenCount:5e3,acceptableChunkTokenCount:1e4,maxChunkTokenCount:3e4,maxLineLength:500},oO=/<(\S+) id="(\d+)".*?>/g,j2=/(<\/(\S+)>)|(<(\S+).*?\/>)/g,sO=["h1","h2","section","footer","nav","aside","form","label","dialog"],V2=[...sO,"span","div","h3"],$2=["table","select","form","ul","ol","menu","pre","code","dialog"],q2=["table","form","dialog","nav","section","ul","select"];function ip(r){return K2(r)}function K2({logger:r,serializedTree:e,options:t}){let{minChunkTokenCount:n,acceptableChunkTokenCount:o,maxChunkTokenCount:i,maxLineLength:a}=t,s=[],c=e.split(`
|
|
4581
4581
|
`),l=0,u=[],d=0,p=[],m=[],g=!1;for(;l<c.length;){g&&(s.push({ids:p,content:u.join(`
|
|
4582
4582
|
`),tokenLength:d}),u=[],d=0,p=m.length?[m[m.length-1].id]:[],g=!1);let h=c[l],f=bn(h);d+=f,h.length>a&&(h=h.slice(0,a));let b=Array.from(h.matchAll(oO)).map(K=>K&&K.length>=3?{tagName:K[1],id:K[2]}:void 0).filter(K=>!!K),M=Array.from(h.matchAll(j2)).map(K=>K&&(K[2]||K[4])).filter(K=>!!K);M.reverse();let O=h.replace(/ id="[0-9]+"/g,"");u.push(O);for(let K of b)p.push(K.id),m.push(K);for(let K of M){let ge=m[m.length-1];ge&&ge.tagName===K&&m.pop()}let v=m.some(K=>$2.includes(K.tagName)),C=c[l+1]??"",F=bn(C),B=Array.from(C.matchAll(oO)).map(K=>K&&K.length>2?K[1]:void 0).filter(K=>!!K),D=B.some(K=>sO.includes(K)),ee=B.some(K=>V2.includes(K));d+F>=i&&(g=!0),d>=n&&(D&&!v||M.some(K=>q2.includes(K)))&&(g=!0),d>=o&&ee&&!v&&(g=!0),l++}return u.length&&s.push({ids:p,content:u.join(`
|
|
4583
|
-
`),tokenLength:d}),s.forEach((h,f)=>{let y=h.ids[0],E=h.ids[h.ids.length-1];r.debug({tokenLength:h.tokenLength,minId:y,maxId:E},`Chunk for page filtering (index ${f+1}/${s.length})`)}),{chunks:s}}var X2=75e4,ap=3e5;async function la(r){let{options:e,fixtures:t,screenshot:n}=r,{aiPageFiltering:o}=e,{logger:i,generator:a,orgId:s,signal:c}=t,l=r.tree,u=r.serializedTree,d=bn(u);if(d>X2)try{let p=ip({serializedTree:u,options:{minChunkTokenCount:1e4,maxChunkTokenCount:1e5,acceptableChunkTokenCount:5e4,maxLineLength:4e3},logger:i});l=await Z2({...r,tokenLimit:ap-1e4,chunks:p.chunks}),u=l.serialize();let m=bn(u);i.info({oldTokens:d,newTokens:m},"Filtered page using keywords"),d=m}catch(p){i.warn({err:p},"Error filtering page using keyword matching, using naive truncation"),l=l.pruneToSerializedCharLimit(ap*Xo),u=l.serialize();let m=bn(u);i.info({oldTokens:d,newTokens:m},"Filtered page using naive truncation"),d=m}if(d>ap)try{if(o){let p=ip({serializedTree:u,options:aO,logger:i}),m=Y2();l=await Y(J2({...r,chunks:p.chunks,callId:m}),{milliseconds:12e3,signal:c}),u=l.serialize();let g=bn(u);i.info({oldTokens:d,newTokens:g,langfuseCallId:m},"Filtered page using AI chunk ranking"),d=g}else{let p=ip({serializedTree:u,options:iO,logger:i});l=await Y(Q2({...r,chunkResult:p,tokenLimit:4e4}),{milliseconds:12e3,signal:c}),u=l.serialize();let m=bn(u);i.info({oldTokens:d,newTokens:m},"Filtered page using RAG"),d=m}}catch(p){i.warn({err:p},"Error filtering page using RAG/AI, using naive truncation"),l=l.pruneToSerializedCharLimit(ap*Xo),u=l.serialize(),i.info("Filtered page using naive truncation")}return u}async function J2({type:r,callId:e,chunks:t,description:n,fixtures:o,tree:i}){let{generator:a,signal:s,logger:c}=o,l=await a.rankChunksWithAi({chunks:t,description:n,type:r,softTokenLimit:4e4,hardTokenLimit:8e4,callId:e},{abortSignal:s,logger:c,loggerTags:ye(c)}),u=[];return t.forEach((p,m)=>{l.indices.includes(m)&&(u=u.concat(p.ids))}),i.pruneUsingRelevantIds(new Set(u))}async function Z2(r){let{description:e,fixtures:t,tree:n}=r,{generator:o,logger:i,signal:a}=t;if(!e.trim())throw new Error("Empty description passed to page filtering");let s=await o.getExtractedKeywords({goal:e},{logger:i,loggerTags:ye(i),abortSignal:a});i.info({keywordsResult:s},"Got keywords for page filtering");for(let c of s.keywords){let l=r.chunks.filter(m=>m.content.toLowerCase().includes(c.toLowerCase()));if(!l.length||l.reduce((m,g)=>m+g.tokenLength,0)>r.tokenLimit&&l.length>1)continue;let d=l.flatMap(m=>m.ids);return n.pruneUsingRelevantIds(new Set(d))}throw new Error("No keywords were unique enough for page filtering")}async function Q2(r){let{description:e,fixtures:t,chunkResult:n,tokenLimit:o,tree:i}=r,{generator:a,logger:s,signal:c}=t,l=await a.rankChunksWithRag({description:e,chunks:n.chunks,tokenLimit:o},{abortSignal:c,logger:s,loggerTags:ye(s)});if(l.ids.length===0)throw new Error("RAG returned no important ids");return i.pruneUsingRelevantIds(new Set(l.ids.map(d=>`${d}`)))}async function Uy(r,e){if(!r.description)throw new R("UserConfigurationError","Cannot locate element with empty description");return an({action:async()=>eK(r,e),frameConfig:r.iframeUrl?{type:"url",url:r.iframeUrl}:void 0,browser:e.browser,logger:r.logger})}async function eK(r,e){let{disableCache:t,testContext:n,filterByViewport:o,skipWait:i,source:a,memory:s,aiPageFiltering:c,logger:l,allowNotActionableNodesOverride:u,skipSavingVisualAttributes:d}=r,{orgId:p,browser:m,localCodeEvalTools:g,generator:h,abortSignal:f}=e,y=r.description,E=na(),b=r.useMemory&&!t;n&&(y=await Xc({orgId:p,s:y,context:n,localTools:g,signal:f,logger:l})),a&&(y=eO(y,a));let{serializedTree:_,tree:M}=await E.startAsyncSpan("GET_PAGE_STATE",async()=>jn(m,{allowNotActionableNodesOverride:u,filterByViewport:o,abortSignal:f,skipWait:i,logger:l}),{}),O=await E.startAsyncSpan("GET_PAGE_SCREENSHOT",async()=>{let U,W=Date.now(),ue;for(;!U&&Date.now()-W<3e3;){f.throwIfAborted();try{U=await m.screenshot({clearHighlights:!0,respectActiveFrame:!0,retries:2})}catch(le){ue=le}}if(!U)throw new R("ActionFailureError",`Failed to take screenshot of page to locate element. The page may be unresponsive, or your machine might be severely resource constrained. Error: ${ue?.message}`);return U}),v=_,C=!1,I=`data:image/jpeg;base64,${O.toString("base64")}`;v=await la({type:"locator",description:y,screenshot:I,serializedTree:_,options:{aiPageFiltering:c},tree:M,fixtures:{generator:h,signal:f,logger:l,orgId:p}}),v!==_&&(C=!0);let B=await E.startAsyncSpan("AI_LOCATOR_CALL",async U=>{let W=await h.getElementLocation({browserState:v,goal:y,screenshot:I,source:a,memory:b?s:void 0},{disableCache:t,abortSignal:f,loggerTags:ye(l),useMemory:b});return U.result=W,W});if(l.debug({usedRag:C,result:B},"Got locator result"),!(B.id>0))throw new Ro(`Could not find any relevant element: ${B.thoughts}`,B.updatedMemory?{type:"GCS_TRACES",traces:B.updatedMemory}:void 0);let{resolution:ee,target:K,frameConfig:ge}=await E.startAsyncSpan("TARGET_RESOLUTION",async U=>{let W=await m.createTargetFromA11yId({id:B.id,requirements:B.requirements,additionalElements:B.additionalElements,description:y,targetSource:"AI",logger:l,skipSavingVisualAttributes:d});return U.result={serializedElement:W.target.nodeOnlySerializedHtml??"Unknown HTML element"},W});if(ee.a11yNode?.properties?.hidden&&ee.a11yNode?.properties?.hidden!=="false")throw new R("ActionFailureError",`Momentic's AI found a relevant element to interact with, but it is explicitly marked with an 'aria-hidden' attribute. Please remove this attribute or adjust the element description to locate a different element. Element chosen: ${ee.displayString}`);return b&&(B.updatedMemory?K.memory={type:"GCS_TRACES",traces:B.updatedMemory}:s&&(K.memory=s)),{thoughts:B.thoughts,target:K,resolution:ee,frameConfig:ge,screenshot:I}}var tK=15;async function sp({command:r,aiPageFiltering:e,logger:t,fixtures:n,useMemory:o,maxRetries:i=tK}){if(!r.assertion.trim())throw new R("ActionFailureError","Assertion command is missing the assertion content");let a=oh.optional().catch(void 0).parse(r.source);r.source&&!a&&t.warn(`Invalid source ${r.source} for AI assertion, ignoring...`);let{browser:s}=n,c=r.timeout?r.timeout*1e3:s.smartWaitingTimeout,l=dP(c,i-1),u=0,d=Date.now(),p=d+c,m=d,g,h,f;try{await an({action:()=>s.clearHighlights(),frameConfig:r.iframeUrl?{type:"url",url:r.iframeUrl}:void 0,browser:s,logger:t})}catch(y){t.warn({err:y},"Failed to clear highlights before AI check, continuing...")}for(;u<i;){n.abortSignal.throwIfAborted();let y=Date.now();if(u>0){if(y>=p)break;let _=p-y,M=m-y,O=Math.min(M,_);O>0&&await J(O,n.abortSignal)}let E=Date.now();if(u>0&&E>=p)break;let b=!1;try{if(g=await an({action:async()=>{let M=await lO(s,t,n.abortSignal);return h&&h.serializedTree===M.serializedTree&&h.screenshotBuff.equals(M.screenshotBuff)?(b=!0,g):(h=M,cO({command:r,state:M,fixtures:n,useMemory:o,useConsensus:!1,highlightElementsOnFailure:!1,attemptNumber:u,aiPageFiltering:e,logger:t,source:a}))},frameConfig:r.iframeUrl?{type:"url",url:r.iframeUrl}:void 0,logger:t,browser:s}),g?.success){g?.updatedMemory&&Jc(r,g.updatedMemory,t);break}else throw g?.thoughts?new R("AssertionFailureError",g.thoughts):new R("InternalPlatformError","No thoughts were provided for AI assertion failure")}catch(_){n.abortSignal.throwIfAborted(),f=_ instanceof Error?_:new Error(`${_}`),b?t.info(`AI check attempt ${u} failed (re-used previous result)`):t.info({err:_},`AI check assert attempt ${u} failed, retrying...`)}finally{u++,m=E+l}}if(!g?.success){let y=p-Date.now();y>0&&await J(y,n.abortSignal)}if(!g?.success)try{g=await an({action:async()=>cO({command:r,state:await lO(s,t,n.abortSignal),fixtures:n,useMemory:o,useConsensus:!0,highlightElementsOnFailure:!0,attemptNumber:u,aiPageFiltering:e,logger:t}),frameConfig:r.iframeUrl?{type:"url",url:r.iframeUrl}:void 0,logger:t,browser:s})}catch(y){n.abortSignal.throwIfAborted(),f=y instanceof Error?y:new Error(`${y}`)}finally{u++}if(g?.updatedMemory&&Jc(r,g.updatedMemory,t),!g?.success){let y=`AI check still failing after ${u} attempts.`;throw f&&(y+=` Latest result: ${f.message}`),new R("AssertionFailureError",y)}return{...g,succeedImmediately:!1,urlAfterCommand:s.url()}}async function lO(r,e,t){let[n,o]=await Promise.all([jn(r,{abortSignal:t,skipWait:!0,skipWaitForPageLoad:!0,logger:e}),r.screenshot({retries:1,respectActiveFrame:!0})]);return{...n,screenshotBuff:o}}async function cO({command:r,state:e,fixtures:t,useConsensus:n,useMemory:o,highlightElementsOnFailure:i,aiPageFiltering:a,attemptNumber:s,source:c,logger:l}){let{browser:u,generator:d,abortSignal:p}=t,m={type:"ASSERTION"},{serializedTree:g,tree:h}=e,f=e.screenshotBuff,y=f.toString("base64"),E=u.url(),b=r.contextChoice??"MULTIMODAL",_=g;b!=="VISION_ONLY"&&(_=await la({type:"assertion",serializedTree:g,tree:h,description:r.assertion,screenshot:y,options:{aiPageFiltering:a},fixtures:{generator:d,signal:p,logger:l,orgId:t.orgId}}),_!==g&&(m.ragUsed=!0),m.pageState=_);let M={goal:r.assertion,url:E,memory:o?r.cache?.memory:void 0,browserState:_,screenshot:y,contextChoice:b,source:c},v=await(b==="VISION_ONLY"?(C,F)=>d.getVisualAssertionResult(C,F):(C,F)=>d.getAssertionResult(C,F))(M,{useConsensus:n,attemptNumber:s,useMemory:o,disableCache:!!r.disableCache,abortSignal:p,logger:l,loggerTags:ye(l)});return(v.result||i)&&v.relevantElements&&(m.relevantElementsSerialized=v.relevantElements.map(C=>u.getSerializedFormFromA11yId(C)).filter(C=>!!C),await rK(v.relevantElements,u,l)),{success:v.result,thoughts:v.thoughts,afterScreenshotOverride:f,updatedMemory:o?v.updatedMemory:void 0}}async function rK(r,e,t){let n=Date.now();for(let o of r){if(Date.now()-n>2e3){t.debug("Highlighting relevant elements took over 2s, aborting...");return}try{let i=new AbortController;await Y(e.highlightA11yId(o),{milliseconds:1e3,fallback:()=>{throw i.abort(),new Error("Timed out waiting for highlighting to complete")}})}catch(i){t.debug({err:i},"Failed to highlight relevant element after assertion, continuing...");return}}}var nK=1e5,lp=class extends Error{constructor(){super("The page content exceeds the maximum token limit for AI smart waiting."),this.name="ExceededMaxAISmartWaitingTokensError"}};async function uO(r,e){let{logger:t}=r,{abortSignal:n,browser:o}=e,i=Date.now();try{await oK(i,r,e)}catch(a){if(a instanceof Error&&(a.name==="AbortError"||a.name==="TimeoutError")||n.aborted)return;a instanceof lp?t.warn("Skipping AI smart waiting due to excessive page size - falling back to naive waiting"):t.warn({err:a},"Unexpected error occurred during AI smart waiting");let s=o.smartWaitingTimeout-(Date.now()-i);s>0&&await J(s,n)}finally{t.debug({durationMs:Date.now()-i},"AI smart waiting complete")}}async function oK(r,e,t){let{abortSignal:n,browser:o}=t;if(o.smartWaitingTimeout<3e3){await J(o.smartWaitingTimeout,n);return}if(!e.description)throw new R("UserConfigurationError","Cannot locate element with empty description");await Y(iK(r,e,t),{milliseconds:o.smartWaitingTimeout})}async function iK(r,e,t){let{logger:n,iframeUrl:o}=e,{browser:i}=t;for(;Date.now()-r<i.smartWaitingTimeout;)if(await an({action:async()=>aK(e,t),frameConfig:o?{type:"url",url:o}:void 0,browser:i,logger:n}))return}async function aK(r,e){let{testContext:t,logger:n,filterByViewport:o,allowNotActionableNodesOverride:i}=r,{browser:a,abortSignal:s,localCodeEvalTools:c,orgId:l,generator:u}=e,d=r.description;t&&(d=await Xc({orgId:l,s:d,context:t,localTools:c,signal:s,logger:n}));let{serializedTree:p}=await jn(a,{allowNotActionableNodesOverride:i,filterByViewport:o,abortSignal:s,logger:n});if(bn(p)>nK)throw new lp;s.throwIfAborted();let g;try{g=await a.screenshot({clearHighlights:!0,respectActiveFrame:!0,retries:2})}catch(E){throw new R("ActionFailureError",`Failed to take screenshot of page to perform smart waiting. The page may be unresponsive, or your machine might be severely resource constrained. Error: ${E instanceof Error?E.message:E}`)}let f=`data:image/jpeg;base64,${g.toString("base64")}`;s.throwIfAborted();let y=await u.getSmartWaitingDecision({browserState:p,description:d,screenshot:f},{abortSignal:s,loggerTags:ye(n)});return n.debug({result:y},"Got smart waiting result"),y.isPageReady}import{cloneDeep as mO}from"lodash-es";async function pO(r){let{command:e,timeoutMs:t,fixtures:n}=r,{abortSignal:o}=n,i=()=>Iu(e.cache)?e.cache:void 0,a=i(),s=mO(a),c=(h=!1)=>{if(a=i(),!!a)if(h){let f=EM(s,a);a.target=f.target,a.updatedAt=f.updatedAt}else{if(!s){a=void 0;return}a.target=s.target,a.updatedAt=s.updatedAt}},l=Date.now(),u=0,d,p=500,m=!1;for(;u<2||Date.now()-l<t;){u++,u>1&&await J(p,o),o?.throwIfAborted(),a=i();let{result:h,elementWasFound:f}=await dO({cacheToUse:a,params:r});if(d=h,m=f,h.success)break;c(),p=Math.min(p*2,1e4)}if(!d)throw new R("InternalPlatformError",`Failed to evaluate manual element assertion in ${t}ms.`);if(o?.throwIfAborted(),!d.success&&a?.target&&Aa(a.target)){let h=a?.target?.memory?{target:{id:-1,memory:a.target.memory}}:void 0,{result:f}=await dO({cacheToUse:h,params:r});d=f,d.success||c(!0)}let g=i();return d.success&&g?.target&&!m&&(g.target=FS(g.target),g.updatedAt=new Date),d}async function dO({cacheToUse:r,params:e}){let{command:t,disableCache:n,fixtures:o,tracer:i,targetingWrapper:a}=e,{logger:s}=o;if(t.target&&!vo(t.target))throw new Error("Element assertion with x/y is not supported yet");let c=Nm(t.assertion),l,u=!1,d=mO(r);try{let{elementInteractedDisplayString:p,result:m,thoughts:g}=await a({ctx:o.ctx,tracer:i,command:t,target:t.target,cache:d?.target,action:async h=>sK(h.locator,e),options:{...t,allowNotActionableNodesOverride:!0,disableCache:n,memory:d?.target?.memory,disableGlobalLocatorRedirect:!0,source:Ol(t),targetName:"target"}});return l={success:m.success,data:m.data,err:m.err,elementInteractedDisplayString:p,thoughts:g},u=!0,m.success||(s.warn({aiThoughts:g,elementString:p,err:m.err},"Element check found an element but failed"),l={...m,thoughts:g}),{result:l,elementWasFound:u}}catch(p){if(c)return l={success:!0,thoughts:`The element described does not exist on the page: ${p.message}`,err:void 0,data:void 0},{result:l,elementWasFound:u};if(!(p instanceof R)||p.reason!="ActionFailureError")throw p;return l={success:!1,err:p,data:void 0,thoughts:void 0},s.warn({err:p},"Element check did not find an element and failed"),{result:l,elementWasFound:u}}}async function sK(r,{command:e,fixtures:t}){return await t.browser.highlight(r),await lK(r,e.assertion)}async function lK(r,e){let t=!0,n,o;switch(e.type){case"ELEMENT_CONTENT":{let a=await r.textContent()??"";if(o={elementTextContent:Vt(a,500,!0)},!Bn(a,e.value,e.operation,{negated:!!e.negated,ignoreCase:!1})){let s=tn(e);t=!1,n=new R("AssertionFailureError",`The content ${s} '${e.value}': ${a}`)}break}case"ELEMENT_ATTRIBUTE":{o={elementOuterHtml:Vt(await r.evaluate(s=>s.cloneNode(!1).outerHTML),500,!0)};let a=null;try{a=await r.getAttribute(e.attr,{timeout:3e3})}catch(s){n=new R("AssertionFailureError",s instanceof Error?s.message:String(s)),t=!1;break}if(!Bn(a,e.value,e.operation,{negated:!!e.negated,ignoreCase:!1})){let s=tn(e);t=!1,e.operation==="EXISTS"?n=new R("AssertionFailureError",`The attribute ${e.attr} ${s}`):n=new R("AssertionFailureError",`The attribute ${e.attr} ${s} '${e.value}': ${a}`)}break}case"ELEMENT_EXISTENCE":{switch(e.condition){case"VISIBLE":{t=await r.evaluate(async(s,c)=>{let l=Date.now();for(;Date.now()-l<c;){await new Promise(d=>setTimeout(d,250));let u=s.getBoundingClientRect();if(!(u.width===0||u.height===0)&&window.getComputedStyle(s).visibility!=="hidden"&&window.getComputedStyle(s).display!=="none")return!0}return!1},dr*1e3);break}case"EDITABLE":{t=await r.isEditable({timeout:dr*1e3});break}case"EXISTS":{t=!0;break}case"ENABLED":{t=await r.isEnabled({timeout:dr*1e3});break}case"FOCUSED":{t=await r.evaluate(s=>s===document.activeElement);break}default:return(s=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(e.condition)}if(t=e.negated?!t:t,!t){let a=tn(e);n=new R("AssertionFailureError",`The element ${a}`)}break}case"ELEMENT_NAME":{let a=await r.evaluate(s=>s.tagName);if(!Bn(a,e.value,e.operation,{negated:!!e.negated,ignoreCase:!0})){let s=tn(e);t=!1,n=new R("AssertionFailureError",`The element tag name ${s} '${e.value}': ${a}`)}break}case"ELEMENT_STYLE":{let a=await r.evaluate((s,c)=>window.getComputedStyle(s).getPropertyValue(c),e.property);if(!Bn(a,e.value,e.operation,{negated:!!e.negated,ignoreCase:!1})){let s=tn(e);t=!1,e.operation==="EXISTS"?n=new R("AssertionFailureError",`The style property ${e.property} ${s}`):n=new R("AssertionFailureError",`The style property ${e.property} ${s} '${e.value}': ${a}`)}break}default:return(a=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(e)}return{thoughts:void 0,success:t,data:o,err:n}}function gO(r){return r.type==="ELEMENT_EXISTENCE"&&r.negated&&r.condition==="EXISTS"}import{Jimp as cK}from"jimp";async function su(r,e){let t=await r.screenshot(e),n=await cK.fromBuffer(t);return{buffer:t,width:Math.ceil(n.bitmap.width??0),height:Math.ceil(n.bitmap.height??0)}}import{Jimp as hO}from"jimp";import By from"jpeg-js";import uK from"pixelmatch";async function fO({ctx:r,tracer:e,command:t,disableCache:n,browser:o,targetingWrapper:i,logger:a,screenshotStorage:s}){if(t.target&&!vo(t.target))throw new Error("Visual Diff with x/y is not supported yet");await o.waitForStability({logger:a});let c={clearHighlights:!0,hideCaret:!0},l;t.target?.elementDescriptor?l=(await i({ctx:r,tracer:e,command:t,target:t.target,cache:t.cache?.target,action:async B=>su(o,{locator:B.locator,...c}),options:{...t,disableCache:n,disableGlobalLocatorRedirect:!0,memory:t.cache?.target?.memory,targetName:"target"}})).result:l=await su(o,c);let u=await s.prepareGoldenScreenshotForComparison(a,t,l);if((l.height!==u.height||l.width!==u.width)&&a.warn({currHeight:l.height,currWidth:l.width,savedHeight:u.height,savedWidth:u.width},"Mismatched before and after visual diff screenshot sizes"),Math.abs(l.height-u.height)>10||Math.abs(l.width-u.width)>10){let I=`${l.width}x${l.height}`,B=`${u.width}x${u.height}`;return{fail:!0,thoughts:`Current screenshot (${I}) does not match saved screenshot dimensions (${B}) - did you change the size of the target or the viewport?`,beforeScreenshotOverride:u.buffer,afterScreenshotOverride:l.buffer,succeedImmediately:!1,urlAfterCommand:o.url()}}let d=await hO.fromBuffer(l.buffer),p={width:l.width,height:l.height},m=await hO.fromBuffer(u.buffer),g={width:u.width,height:u.height},h,f=p.width*p.height,y=g.width*g.height,E=Math.abs(p.height-g.height),b=Math.abs(p.width-g.width);if(f>y){let I=d.cover({w:g.width,h:g.height});l.buffer=await I.getBuffer("image/jpeg"),h="current",l.width=g.width,l.height=g.height}else if(y>f){let I=m.cover({w:p.width,h:p.height});u.buffer=await I.getBuffer("image/jpeg"),h="saved"}let _={data:Buffer.alloc(l.width*l.height*4),width:l.width,height:l.height},M=t.threshold??.1,v=uK(By.decode(u.buffer).data,By.decode(l.buffer).data,_.data,l.width,l.height,{threshold:M,diffColorAlt:[0,255,0]})/(l.width*l.height)*100,C=v>M*100,F=`Visual diff of ${v.toFixed(2)}% detected, which is ${C?"over":"under"} the threshold of ${M*100}%.`;if(h&&(F+=` The ${h} screenshot was cropped since it was taller by ${E} pixels and wider by ${b} pixels.`),C)throw new R("ActionFailureError",F);return{fail:C,thoughts:F,beforeScreenshotOverride:l.buffer,afterScreenshotOverride:By.encode(_,75).data,succeedImmediately:!1,urlAfterCommand:o.url()}}var dK=3e4;function mK(r){if(!r.body)return{};switch(r.body.type){case"json":return{content:r.body.content,contentType:"application/json"};case"form-urlencoded":{let e=new URLSearchParams;return Object.entries(r.body.content).forEach(([t,n])=>{e.append(t,n)}),{content:e.toString(),contentType:"application/x-www-form-urlencoded;charset=UTF-8"}}}}async function cp({command:r,logger:e,baseUrl:t,fetchImplementation:n=fetch}){let o=r.timeout??dK/1e3,i=Object.fromEntries(Object.entries(r.headers||{}).filter(([g,h])=>g&&h)),a=new URLSearchParams;Object.entries(r.params||{}).filter(([g,h])=>g&&h).forEach(([g,h])=>{a.append(g,h)});let s=a.toString(),c;if(Ls(r.url)&&(c=r.url),t&&Ns(r.url,t)&&(c=new URL(r.url,t).toString()),!c)throw new R("ActionFailureError",`Invalid URL: ${r.url}`);let l=c;e.info({url:l,searchParams:s,headers:i,body:r.body,method:r.method},"Making HTTP request");let d=await Y((async()=>{let g=s?`${l}?${s}`:l;try{let h=mK(r),f=new Headers(i);return h.contentType&&!f.has("Content-Type")&&f.set("Content-Type",h.contentType),await n(g,{headers:f,method:r.method,body:h.content})}catch(h){throw new Error(`Failed to make HTTP request: ${h}`,{cause:h})}})(),{milliseconds:o*1e3,fallback:()=>{throw new R("ActionFailureError",`Fetch request timed out after ${o} seconds`)}});if(!d.ok){let g;try{g=await d.text()}catch(h){g=`Failed to read response body: ${h}`}throw new R("ActionFailureError",`Fetch request failed with status ${d.status}: ${g}`)}let p={};d.headers.forEach((g,h)=>{p[h]=g});let m={status:d.status,headers:p,request:{url:d.url,method:r.method,headers:i}};if(r.body?.type==="json"&&r.body.content)try{m.request.json=JSON.parse(r.body.content)}catch{}if(d.headers.get("content-type")?.includes("json"))try{m.json=await d.json()}catch{}else d.headers.get("content-type")?.includes("text")&&(m.text=await d.text());return m}var pK=5e3;async function yO({timeout:r=dr,...e}){let t=Date.now(),n=r*1e3,o=n+1e4,i,a=0,s=500;for(;a-t<n;){if(Date.now()-t>o){e.logger.warn("Exceeded max system timeout for page assertion, exiting...");break}e.signal?.throwIfAborted();let c=Date.now();i=await up(e),a=Date.now();let l=a-c;if(l>1e3&&e.logger.warn({pageAssertDuration:l},"Page assertion took longer than expected"),!i.success)await J(s,e.signal),s=Math.min(Math.floor(s*1.5),pK);else return i}return i=await up(e),i}async function up({assertion:r,browser:e,autoExpandIframes:t}){switch(r.type){case"CONTENT":case"CONTENT":{let o,i=!1,a;try{let s;if(t){let c=await e.evaluateFunctionInAllFrames(SO,{value:r.value,negated:!!r.negated,returnHtml:!1});i=r.negated?c.every(l=>l.evaluation):c.some(l=>l.evaluation),s=c.find(l=>l.pageHtml)?.pageHtml}else({evaluation:i,pageHtml:s}=await e.evaluateFunctionInPage(SO,{value:r.value,negated:!!r.negated,returnHtml:!0},"checking page content"));if(!i){let c=r.negated?uo.CONTAINS:mo.CONTAINS;a=new R("AssertionFailureError",`The page ${c} '${r.value}'.`),o=s}}catch(s){a=new R("AssertionFailureError",`Failed to evaluate page content assertion: ${s instanceof Error?s.message:`${s}`}`)}return{success:i,err:a,data:i||!o?void 0:{pageContent:o}}}default:return(o=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(r)}}function SO({value:r,negated:e,returnHtml:t}){let n=document.body.innerHTML,o=n.includes(r)===!e;return n.length>1e4&&(n=n.slice(0,1e4)+"...TRUNCATED"),{evaluation:o,pageHtml:!o&&t?n:void 0}}var gK=3e4;async function bO({command:r,logger:e,baseUrl:t,fetchImplementation:n=fetch}){let o=r.timeout??gK/1e3,i=new AbortController,a=Object.fromEntries(Object.entries(r.headers||{}).filter(([d,p])=>d&&p));a["Content-Type"]="application/json";let s;if(Ls(r.url)&&(s=r.url),t&&Ns(r.url,t)&&(s=new URL(r.url,t).toString()),!s)throw new R("ActionFailureError",`Invalid URL: ${r.url}`);let l=await Y((async()=>{try{return await n(s,{headers:a,method:"POST",body:JSON.stringify({query:r.query,variables:r.variables?JSON.parse(r.variables):void 0}),signal:i.signal})}catch(d){throw new Error(`Failed to make HTTP request: ${d}`,{cause:d})}})(),{milliseconds:o*1e3});if(!l)throw new R("ActionFailureError",`GraphQL request timed out after ${o} seconds`);if(!l.ok){let d,p=await l.text();try{d=JSON.parse(p)}catch{throw new R("ActionFailureError",`GraphQL request failed with status ${l.status}: ${p}`)}throw d?.errors?.length&&d?.errors[0]?.message?new R("ActionFailureError",`GraphQL request failed with status ${l.status}: ${d.errors[0].message}`):new R("ActionFailureError",`GraphQL request failed with status ${l.status}: ${p}`)}let u={};return l.headers.forEach((d,p)=>{u[p]=d}),{status:l.status,headers:u,json:await l.json()}}var dp=class{orgId;options;storage;localCodeEvalTools;uploadedFileStorage;visualDiffScreenshotStorage;browser;generator;executeAbortController=new AbortController;logger;recordAbortController=null;registeredListeners={};recordedRequests={};constructor({browser:e,generator:t,logger:n,storage:o,orgId:i,localCodeEvalTools:a,uploadedFileStorage:s,visualDiffScreenshotStorage:c,options:l}){this.orgId=i,this.options=l,this.browser=e,this.browser.registerAbortSignal(this.executeAbortController.signal),this.storage=o,this.uploadedFileStorage=s,this.visualDiffScreenshotStorage=c,this.localCodeEvalTools=a,this.generator=t,this.logger=n}setOpen(){this.executeAbortController=new AbortController,this.browser.registerAbortSignal(this.executeAbortController.signal)}setClosed(){this.executeAbortController.abort()}throwIfClosed(){this.executeAbortController.signal.throwIfAborted()}get closed(){return this.executeAbortController.signal.aborted}async evaluateAiAction({goal:e,startingScreenshot:t,history:n,disableCache:o,langfuseSessionId:i,lastError:a,logger:s=this.logger}){let[c,l]=await Promise.all([jn(this.browser,{abortSignal:this.executeAbortController.signal,skipWait:!0,skipWaitForPageLoad:!0,logger:s}),this.browser.screenshot({retries:1,clearHighlights:!0})]),u=`data:image/jpeg;base64,${l.toString("base64")}`,d=await la({type:"ai-action",description:e,screenshot:u,serializedTree:c.serializedTree,tree:c.tree,options:{aiPageFiltering:!!this.options?.aiPageFiltering},fixtures:{generator:this.generator,signal:this.executeAbortController.signal,logger:s,orgId:this.orgId}}),p={url:this.browser.url(),browserState:d,startingScreenshot:t,history:n,goal:e,screenshot:u,lastError:a};return await this.generator.getMultiturnAiActionEvaluation(p,{disableCache:o,abortSignal:this.executeAbortController.signal,loggerTags:{...ye(s)},langfuseSessionId:i})}async promptToCommand({goal:e,startingScreenshot:t,history:n,actionHint:o,disableCache:i,logger:a=this.logger,langfuseSessionId:s}){let c=this.browser.url(),[l,u]=await Promise.all([jn(this.browser,{abortSignal:this.executeAbortController.signal,skipWait:!0,skipWaitForPageLoad:!0,logger:a}),this.browser.screenshot({retries:1,clearHighlights:!0})]),d=`data:image/jpeg;base64,${u.toString("base64")}`,p=await la({type:"ai-action",description:e,screenshot:d,serializedTree:l.serializedTree,tree:l.tree,options:{aiPageFiltering:!!this.options?.aiPageFiltering},fixtures:{generator:this.generator,signal:this.executeAbortController.signal,logger:a,orgId:this.orgId}}),m={url:c,browserState:p,startingScreenshot:t,history:n,goal:e,actionHint:o,screenshot:d};try{return await this.generator.getMultiturnAiActionCommand(m,{disableCache:i,abortSignal:this.executeAbortController.signal,loggerTags:{...ye(a)},langfuseSessionId:s})}catch(g){throw new R("InternalWebAgentError",`Error generating command: ${g instanceof Error?g.message:g}`,{errOptions:{cause:g}})}}async getBrowserState(e){return jn(this.browser,e)}async locateElement(e){return await Uy({...e,aiPageFiltering:!!this.options?.aiPageFiltering},this.getControllerFixtures())}async locateElementWithSelector(e,t){return an({action:async()=>{let n=await this.browser.resolveHardcodedCssSelector({ctx:null,selector:e,timeoutMs:2e3,logger:this.logger});return{thoughts:"Located element with selector",target:{id:-1,selector:e,targetSource:"USER_CSS_SELECTOR",targetUpdateTime:new Date().toUTCString()},resolution:n}},frameConfig:t?{type:"url",url:t}:void 0,browser:this.browser,logger:this.logger})}getControllerFixtures(e){return{ctx:e??null,browser:this.browser,generator:this.generator,logger:this.logger,orgId:this.orgId,storage:this.storage,localCodeEvalTools:this.localCodeEvalTools,abortSignal:this.executeAbortController.signal}}shouldUseMemory(){return this.options?.useMemory??(this.orgId==="org_01HMSCJQBCCG51M2ZF65YC5B8W"||this.orgId==="org_01HMJTX4GT1KG94KZRCT8MZ6YB")}async wrapMultiElementTargetingCommand({ctx:e,tracer:t,command:n,targetNames:o,descriptions:i,caches:a,action:s,options:c,retriesWithAI:l=1}){let u=[];for(let d=0;d<i.length;d++){let p=i[d],m=await this.wrapElementTargetingCommand({ctx:e,tracer:t,command:n,target:p,cache:a[d],action:async g=>g,options:{...c,targetName:o[d]}});u.push(m)}try{let d=await s(...u.map(g=>g.result)),p=g=>g==="fromTarget"?"From Target":g==="toTarget"?"To Target":"Target",m=u.map((g,h)=>g.thoughts?`${p(o[h])}: ${g.thoughts}`:void 0).filter(g=>!!g).join(" -------------- ")||void 0;return{result:d,elementInteractedDisplayStrings:u.map(g=>g.elementInteractedDisplayString),thoughts:m}}catch(d){if(this.throwIfClosed(),l>0)return this.logger.warn({err:d},"Failed to execute action with multiple cached targets, retrying with AI"),this.wrapMultiElementTargetingCommand({ctx:e,tracer:t,command:n,targetNames:o,descriptions:i,caches:i.map(()=>{}),action:s,options:c,retriesWithAI:l-1});throw new R("ActionFailureError",d.message,{errOptions:{cause:d}})}}async wrapHardcodedCssTargetingCommandHelper({ctx:e,target:t,action:n,options:o,command:i}){let a=this.logger.child({commandId:i.id}),{targetName:s}=o;if(t.type!=="description")throw new R("ActionFailureError","Cannot use selector with non-description target");let c,l=Date.now(),u=Date.now();for(;Date.now()-u<this.browser.smartWaitingTimeout;){l=Date.now();try{let d=await this.browser.resolveHardcodedCssSelector({ctx:e,selector:t.elementDescriptor,targetName:s,logger:a});return{result:await n({locator:d.locator,originalElementLocationResult:void 0,serverSideBoundingBox:null}),elementInteractedDisplayString:d.displayString}}catch(d){if(d.name==="AbortError")throw d;c=d,a.warn({err:d},"Failed to action on hardcoded css selector"),Date.now()-l<500&&await J(500)}}throw c}async scrollIntoViewAndResolveFinalTarget(e){let{resolutionResult:t,disableGlobalLocatorRedirect:n,logger:o}=e,i=na(),a=!n&&this.browser.userBrowserSettings.globalLocatorRedirect!==!1;(this.browser.userBrowserSettings.visualActions||a)&&await i.startAsyncSpan("SCROLL_ELEMENT_INTO_VIEW",async()=>{await this.browser.scrollIntoViewIfNeeded(t.locator)});let s;return a&&(s=await i.startAsyncSpan("LOCATOR_REDIRECT",async()=>this.browser.performTargetRedirection(t,o))),s||(s={locator:t.locator,serverSideBoundingBox:await t.locator.boundingBox({timeout:ae}),originalElementLocationResult:t.originalElementLocationResult}),s}async resolveCachedTargetForAction(e){let{ctx:t,cache:n,options:o,logger:i}=e,s=await na().startAsyncSpan("CACHE_RESOLUTION",async l=>{let u=await this.browser.resolveTarget(t,n,{allowNotActionableNodesOverride:o.allowNotActionableNodesOverride,logger:i,signal:this.executeAbortController.signal,...o.resolveTargetOptions});return l.attributes.targetDisplayString=u.displayString,u}),c=await this.scrollIntoViewAndResolveFinalTarget({resolutionResult:s,disableGlobalLocatorRedirect:o.disableGlobalLocatorRedirect,logger:i});return await s.revalidator?.(),{resolutionResult:s,finalTarget:c}}async wrapElementTargetingCommand(e){return await an({action:()=>this.wrapElementTargetingCommandHelper(e),frameConfig:e.options.iframeUrl?{type:"url",url:e.options.iframeUrl}:void 0,browser:this.browser,logger:this.logger})}async wrapElementTargetingCommandHelper(e){let{ctx:t,tracer:n,target:o,action:i,options:a,command:s,finalAttempt:c=!1,originalCache:l=e.cache}=e,{retriesWithAI:u=1}=e,{disableCache:d,useSelector:p,targetName:m}=a,g=na(),h=this.logger.child({commandId:s.id}),f=this.shouldUseMemory(),y=EO(e.cache);if((!y||d)&&!yg(o))throw new R("ActionFailureError","Cannot target element with no cached data or element descriptor");if(p)return this.wrapHardcodedCssTargetingCommandHelper(e);let E=!1;d&&(h.info("Cache explicitly disabled for this step"),E=!0,y=void 0);let b=nO({cache:y,description:o.elementDescriptor,disableSecondaryCacheResolution:!!this.browser.userBrowserSettings.disableSecondaryCacheResolution,logger:h});y=b.cache,E=E||b.cacheBustedBeforeAction;let _=!0;if(!rO(y))return u--,_=!1,this.executeTargetingCommandWithAI({ctx:t,tracer:g,stepTracer:n,target:o,options:a,command:s,action:i,originalCache:l,logger:h,useMemory:f,cacheBustedBeforeAction:E});try{let{resolutionResult:M,finalTarget:O}=await this.resolveCachedTargetForAction({ctx:t,cache:y,options:a,logger:h}),v=await i(O);if(nt.increment("cache_target_resolution_v2",1,["outcome:hit","platform:web",`hasRequirements:${!!y.requirements}`,`hasAdditionalElements:${!!y.additionalElements}`,`orgId:${this.orgId}`,"cliVersion:0.33.4"]),km({cmd:s,key:m,newTarget:y,logger:h,updatedWithAI:!1}),_){let C=M.decisions.filter(F=>F.matched);if(C.length!==1)h.warn({decisions:M.decisions},"Expected exactly 1 matching method for element location, got more or less");else{let F=C[0].type;n.recordTargetAutoHeal({healType:F})}}return{result:v,elementInteractedDisplayString:M.displayString}}catch(M){this.throwIfClosed();let O=Ng(M);if(O&&!c)return h.warn({err:M},"Encountered error that is retryable with cache"),this.wrapElementTargetingCommandHelper({ctx:t,tracer:n,command:s,target:o,action:i,cache:l,originalCache:l,retriesWithAI:u,finalAttempt:!0,options:a});if(M instanceof R&&!O)throw h.warn({err:M},"Failed to execute command with target (fatal)"),M;if(u>0&&o){h.info({err:M},"Failed to execute action with cached target, retrying with AI"),nt.increment("cache_target_resolution_v2",1,["outcome:miss","platform:web",`hasRequirements:${!!y.requirements}`,`hasAdditionalElements:${!!y.additionalElements}`,`orgId:${this.orgId}`,"cliVersion:0.33.4",`missReason:${M instanceof gt?M.cacheMissReason:"unknown"}`]);let v;return y.memory&&gE(y.memory)&&(v=y.memory),this.wrapElementTargetingCommandHelper({ctx:t,tracer:n,command:s,target:o,cache:void 0,action:i,originalCache:l,retriesWithAI:u,finalAttempt:!0,options:{...a,memory:v,targetHealingInProgress:!0}})}throw new R("ActionFailureError",`Failed to execute interactive command: ${M instanceof Error?M.message:`${M}`}`,{errOptions:{cause:M}})}}async executeTargetingCommandWithAI(e){let{ctx:t,tracer:n,stepTracer:o,target:i,options:a,command:s,action:c,originalCache:l,logger:u,useMemory:d,cacheBustedBeforeAction:p}=e;u.info({description:i.elementDescriptor,targetHealingInProgress:a.targetHealingInProgress,cacheBustedBeforeAction:p,memory:a.memory,useMemory:d},"Prompting AI for an updated element location"),(p||!l)&&await n.startAsyncSpan("SMART_WAITING",async()=>await uO({description:i.elementDescriptor,iframeUrl:a.iframeUrl,source:a.source,logger:u,allowNotActionableNodesOverride:a.allowNotActionableNodesOverride},this.getControllerFixtures(t)));let m=2;for(let g=1;g<=m;g++){let h=!1,f=this.browser.getActiveFrameConfig();try{let y;try{y=await Uy({description:i.elementDescriptor,disableCache:!!a.disableCache,iframeUrl:a.iframeUrl,source:a.source,useMemory:d,memory:d?a.memory:void 0,aiPageFiltering:!!this.options?.aiPageFiltering,allowNotActionableNodesOverride:a.allowNotActionableNodesOverride,logger:u},this.getControllerFixtures(t))}catch(_){if(_ instanceof Ro&&_.updatedLocatorMemory){let M={id:-1,...l,memory:_.updatedLocatorMemory};km({cmd:s,key:a.targetName,newTarget:M,logger:u,updatedWithAI:!0})}throw _}y.frameConfig&&(this.browser.setActiveFrameConfig(y.frameConfig),h=!0);let E=await this.scrollIntoViewAndResolveFinalTarget({resolutionResult:y.resolution,disableGlobalLocatorRedirect:a.disableGlobalLocatorRedirect,logger:u}),b=await c(E);return km({cmd:s,key:a.targetName,newTarget:y.target,logger:u,updatedWithAI:!0}),a.targetHealingInProgress&&(o.recordTargetAutoHeal({healType:"AI"}),y.target.targetSource="AI_HEALED",y.target.targetUpdateTime=new Date().toUTCString(),y.target.targetUpdateLoggerTags=ye(u)),{result:b,elementInteractedDisplayString:y.resolution.displayString,thoughts:y.thoughts}}catch(y){if(h&&this.browser.setActiveFrameConfig(f),this.throwIfClosed(),g<m&&Ng(y)){u.warn({err:y,aiAttempt:g},"Encountered retryable AI targeting error; retrying with AI once");continue}throw y instanceof R?y:new R("ActionFailureError",y.message)}}throw new R("ActionFailureError","Failed to execute AI targeting after retry")}async screenshotWithDimensions(e){return su(this.browser,e)}async executePresetCommand(e,t,n,o,i){this.options?.slowMoMs&&await J(this.options.slowMoMs);let a=await this.browser.getOpenPages(),s=this.browser.url(),c;try{c=await this.resolveCommandTemplateStrings(n,o)}catch(l){throw this.throwIfClosed(),new R("ActionFailureError",`Failed to substitute template strings in command: ${l.message}`,{errOptions:{cause:l}})}try{let l=await this.executePresetCommandHelper(e,t,n,o,i);return this.options?.autoFollowNewTabs&&await tO({beforeUrl:s,command:n,beforePages:a.map(u=>u.url),browser:this.browser,logger:this.logger}),l}catch(l){throw l.name!=="AbortError"&&this.logger.error({err:l},"Error thrown in action controller"),l}finally{Is(n,c)}}createCallbacksForBrowser(e){return{createIsolatedFolder:()=>ly(e)}}async resolveCommandTemplateStrings(e,t){return Ps({obj:e,context:t,bannedKeys:["type","a11yData","thoughts","cache","code"],orgId:this.orgId,logger:this.logger,signal:this.executeAbortController.signal,localTools:this.localCodeEvalTools})}async executePresetCommandHelper(e,t,n,o,i){i=i||"disableCache"in n&&!!n.disableCache;let a=this.logger.child({commandId:n.id});switch(n.type){case"SUCCESS":let s=n.condition;return s?.assertion.trim()?sp({command:s,fixtures:this.getControllerFixtures(e),useMemory:this.shouldUseMemory(),aiPageFiltering:!!this.options?.aiPageFiltering,logger:a}):{succeedImmediately:!1,urlAfterCommand:this.browser.url()};case"AI_ASSERTION":{if(!n.assertion.trim())throw new R("ActionFailureError","Missing assertion");if(n.timeout&&n.timeout>1800)throw new R("AssertionFailureError",`AI check timeout of ${n.timeout} exceeds the maximum allowed value of 30 minutes.`);return sp({command:n,fixtures:this.getControllerFixtures(e),useMemory:this.shouldUseMemory(),aiPageFiltering:!!this.options?.aiPageFiltering,logger:a})}case"AI_EXTRACT":{if(!n.goal.trim())throw new R("ActionFailureError","Cannot perform AI extraction without goal");if(n.schema){let h=iw(n.schema);if(h)throw new R("UserConfigurationError",h)}let m=await this.browser.getCondensedHtml(),g=await this.browser.screenshot({retries:2});try{let h=await this.generator.getTextExtraction({goal:n.goal,browserState:m,returnSchema:n.schema,screenshot:`data:image/jpeg;base64,${g.toString("base64")}`},{disableCache:i,abortSignal:this.executeAbortController.signal,loggerTags:ye(a)});if(h.result==="NOT_FOUND")throw new R("ActionFailureError","No relevant data found for extraction goal on this page");if(h.thoughts?.includes("MaxGenerationLengthExceededError"))throw new R("UserConfigurationError",h.thoughts);return{thoughts:h.thoughts||void 0,data:h.result,succeedImmediately:!1,urlAfterCommand:this.browser.url()}}catch(h){let f=h.message;throw f.includes("MaxGenerationLengthExceededError")?new R("UserConfigurationError","You tried to extract too much data. Please rephrase your query to limit the results returned or use a JavaScript step in the browser instead."):f.includes("AIProviderError")&&f.includes("time")?new R("AIProviderError","The AI provider responded with an error. This may be because you tried to extract too much data. Please limit extraction results to 2000 characters.",{errOptions:{cause:h}}):h}}case"NAVIGATE":if(!Ls(n.url)&&!Ns(n.url,this.browser.baseUrl))throw new R("ActionFailureError",`Invalid URL provided to navigate command: ${n.url}`);await this.browser.navigate({url:n.url,loadTimeoutMs:n.loadTimeout?n.loadTimeout*1e3:void 0});break;case"DIALOG":this.browser.registerDialogHandler(n.action);break;case"CAPTCHA":throw new R("UserConfigurationError","Captcha solving is no longer available on Momentic");case"GO_BACK":await this.browser.goBack();break;case"GO_FORWARD":await this.browser.goForward();break;case"SCROLL_LEFT":case"SCROLL_RIGHT":case"SCROLL_DOWN":case"SCROLL_UP":{let m,g;if(n.target&&An(n.target))await this.browser.hoverUsingVisualCoordinates(n.target.pixels);else if(n.target&&n.target.elementDescriptor.trim()){let{elementInteractedDisplayString:y,thoughts:E}=await this.wrapElementTargetingCommand({ctx:e,tracer:t,command:n,target:n.target,cache:n.cache?.target,action:b=>this.browser.hover(b),options:{...n,targetName:"target",disableGlobalLocatorRedirect:!0,disableCache:i}});m=y,g=E}let h=this.browser.getViewport()?.height??Po.height,f=this.browser.getViewport()?.width??Po.width;switch(n.type){case"SCROLL_UP":await this.browser.scrollVertical(-(n.deltaY??h));break;case"SCROLL_DOWN":await this.browser.scrollVertical(n.deltaY??h);break;case"SCROLL_LEFT":await this.browser.scrollHorizontal(-(n.deltaX??f));break;case"SCROLL_RIGHT":await this.browser.scrollHorizontal(n.deltaX??f);break}return{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:m,thoughts:g}}case"WAIT_FOR_URL":{if(n.timeout&&n.timeout>1800)throw new R("UserConfigurationError",`Wait for URL timeout of ${n.timeout} exceeds the maximum allowed value of 30 minutes.`);let m=n.matcher;await this.browser.waitForUrl({beforeUrl:this.browser.url(),matcher:m},{timeout:n.timeout?n.timeout*1e3:void 0,negated:n.negated,caseInsensitive:n.caseInsensitive});break}case"WAIT":if(n.delay>1800)throw new R("UserConfigurationError",`Wait timeout of ${n.delay} seconds exceeds the maximum allowed value of 30 minutes`);let c=n.delay*1e3;await J(c,this.executeAbortController.signal);break;case"REFRESH":await this.browser.refresh({loadTimeoutMs:n.loadTimeout?n.loadTimeout*1e3:void 0});break;case"CLICK":{if(An(n.target)){await this.browser.clickUsingVisualCoordinates(n.target.pixels,n);break}let m=this.browser.url(),{elementInteractedDisplayString:g,result:h,thoughts:f}=await this.wrapElementTargetingCommand({ctx:e,tracer:t,target:n.target,command:n,cache:n.cache?.target,action:E=>this.browser.click(E,this.createCallbacksForBrowser(this.orgId),n),options:{disableCache:i,targetName:"target",...n}}),y={urlAfterCommand:this.browser.url(),succeedImmediately:!1,elementInteracted:g,thoughts:f,data:h.downloadedFile?{downloadedFile:h.downloadedFile}:void 0};return Wm(m,y.urlAfterCommand)&&(y.succeedImmediately=!0,y.succeedImmediatelyReason="URL changed"),y}case"COPY":return await this.browser.copy(n.value),{succeedImmediately:!1,data:n.value,urlAfterCommand:this.browser.url()};case"PASTE":{await this.browser.paste();break}case"DRAG":{if(An(n.fromTarget)&&An(n.toTarget)){await this.browser.dragAndDropUsingVisualCoordinates(n.fromTarget.pixels,n.toTarget.pixels,{hoverDurationMs:n.hoverSeconds?n.hoverSeconds*1e3:void 0});break}if(An(n.fromTarget)||An(n.toTarget))throw new Error("Drag and drop targets must be both coordinates or both descriptions");let{elementInteractedDisplayStrings:m,thoughts:g}=await this.wrapMultiElementTargetingCommand({ctx:e,tracer:t,command:n,targetNames:["fromTarget","toTarget"],descriptions:[n.fromTarget,n.toTarget],caches:[n.cache?.fromTarget,n.cache?.toTarget],action:(h,f)=>this.browser.dragAndDrop(h,f,{hoverDurationMs:n.hoverSeconds?n.hoverSeconds*1e3:void 0,steps:n.steps}),options:{useSelector:!!n.useSelector,disableCache:i}});return{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:m[0],thoughts:g}}case"MOUSE_DRAG":{let m=parseInt(n.deltaX),g=parseInt(n.deltaY),h=n.steps??5;if(isNaN(m)||isNaN(g))throw new R("ActionFailureError",`Invalid pixel values passed to mouse drag command: (${n.deltaX}, ${n.deltaY})`);if(n.target&&An(n.target)){await this.browser.mouseDragUsingVisualCoordinates({deltaX:m,deltaY:g,steps:h,fromTarget:n.target.pixels});break}let f,y;if(n.target?.elementDescriptor){let{elementInteractedDisplayString:E,thoughts:b}=await this.wrapElementTargetingCommand({ctx:e,tracer:t,command:n,target:n.target,cache:n.cache?.target,action:async _=>this.browser.mouseDrag(m,g,h,_.locator,{force:n.force}),options:{disableCache:i,targetName:"target",...n}});f=E,y=b}else await this.browser.mouseDrag(m,g,h,void 0,{force:n.force});return{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:f,thoughts:y}}case"SELECT_OPTION":{if(!vo(n.target))throw new Error("Select with x/y is not supported yet");let m=n.target.elementDescriptor,g=n.choice,{elementInteractedDisplayString:h,thoughts:f}=await this.wrapElementTargetingCommand({ctx:e,tracer:t,command:n,target:{type:"description",elementDescriptor:m},cache:n.cache?.target,action:y=>this.browser.selectOption(y,g,n.force),options:{...n,targetName:"target",disableCache:i,source:Ol(n)}});return{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:h,thoughts:f}}case"TAB":{let m={loadTimeoutMs:n.loadTimeout?n.loadTimeout*1e3:void 0,retry:!0};await this.browser.switchToPage(n.action,m);break}case"NEW_TAB":await this.browser.createNewTab(n.url,{loadTimeoutMs:n.loadTimeout?n.loadTimeout*1e3:void 0});break;case"COOKIE":if(!n.value)break;let l=await this.browser.setCookie(n.value);a.debug({results:l},"Set cookies");break;case"LOCAL_STORAGE":if(!n.value||!n.key)break;await this.browser.setLocalStorage(n.key,n.value);break;case"JAVASCRIPT":{let m;try{n.environment==="BROWSER"?(m=await this.browser.evaluateCodeInPage({code:n.code,fragment:n.fragment??!1,context:o.toObjectCopy(),timeoutMs:n.timeout?n.timeout*1e3:void 0}),a.info({result:m},"Executed JavaScript in browser")):m=await Un({orgId:this.orgId,code:n.code,fragment:!!n.fragment,context:o,timeoutMs:n.timeout?n.timeout*1e3:void 0,logger:a,localTools:this.localCodeEvalTools,signal:this.executeAbortController.signal,callbacks:{onPersistentVariableUpdates:async g=>{if(!this.options?.scratchPadId){a.warn({updates:g},"Got persistent variable updates but scratch pad is not available");return}await this.storage.savePersistentVariables?.({scratchPadId:this.options?.scratchPadId,orgId:this.orgId,updates:g,logger:a})}}})}catch(g){throw this.throwIfClosed(),new R("ActionFailureError",g instanceof Error?g.message:`${g}`,{errOptions:{cause:g}})}try{JSON.stringify(m)}catch(g){throw new R("ActionFailureError",`Return value is not serializable: ${g instanceof Error?g.message:`${g}`}`,{errOptions:{cause:g}})}return{urlAfterCommand:this.browser.url(),succeedImmediately:!1,data:m}}case"TYPE":{if(n.target&&An(n.target)){await this.browser.clickUsingVisualCoordinates(n.target.pixels,n),await this.browser.type(n.value,{force:n.force,clearContent:n.clearContent,forceClearContent:n.forceClearContent,delay:n.delay,pressEnter:n.pressEnter},!0);break}let m=this.browser.url(),g,h,f=EO(n.target),y=this.browser.userBrowserSettings.globalLocatorRedirect===void 0||this.browser.userBrowserSettings.globalLocatorRedirect==="always";if(f){let{elementInteractedDisplayString:b,thoughts:_}=await this.wrapElementTargetingCommand({ctx:e,tracer:t,command:n,target:f,cache:n.cache?.target,action:M=>this.browser.typeIntoTarget(n.value,M,{force:n.force,clearContent:n.clearContent,forceClearContent:n.forceClearContent,delay:n.delay,pressEnter:n.pressEnter,relativePosition:n.relativePosition}),options:{...n,targetName:"target",disableCache:i,disableGlobalLocatorRedirect:!y,source:Ol(n)}});g=b,h=_}else await this.browser.type(n.value,{force:n.force,clearContent:n.clearContent,forceClearContent:n.forceClearContent,delay:n.delay,pressEnter:n.pressEnter},!0);let E={urlAfterCommand:this.browser.url(),succeedImmediately:!1,elementInteracted:g,thoughts:h};return Wm(m,E.urlAfterCommand)&&(E.succeedImmediately=!0,E.succeedImmediatelyReason="URL changed"),E}case"HOVER":{if(An(n.target)){await this.browser.hoverUsingVisualCoordinates(n.target.pixels);break}let{elementInteractedDisplayString:m,thoughts:g}=await this.wrapElementTargetingCommand({ctx:e,tracer:t,command:n,target:n.target,cache:n.cache?.target,action:h=>this.browser.hover(h),options:{...n,targetName:"target",disableCache:i}});return{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:m,thoughts:g}}case"FOCUS":{if(!vo(n.target))throw new Error("Focus with x/y is not supported yet");let{elementInteractedDisplayString:m,thoughts:g}=await this.wrapElementTargetingCommand({ctx:e,tracer:t,command:n,target:n.target,cache:n.cache?.target,action:h=>this.browser.focus(h),options:{...n,targetName:"target",disableCache:i}});return{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:m,thoughts:g}}case"BLUR":{if(n.target&&!vo(n.target))throw new Error("Blur with x/y is not supported yet");if(!n.target||!n.target.elementDescriptor)return await this.browser.blur(null),{succeedImmediately:!1,urlAfterCommand:this.browser.url()};let{elementInteractedDisplayString:m,thoughts:g}=await this.wrapElementTargetingCommand({ctx:e,tracer:t,target:n.target,command:n,cache:n.cache?.target,action:h=>this.browser.blur(h),options:{...n,targetName:"target",disableCache:i}});return{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:m,thoughts:g}}case"PRESS":let u=this.browser.url();await this.browser.press(n.value,{repeat:n.repeat,convertMeta:n.convertMeta??!0,delayMs:n.delayMs});let d={urlAfterCommand:this.browser.url(),succeedImmediately:!1};return Wm(u,d.urlAfterCommand)&&(d.succeedImmediately=!0,d.succeedImmediatelyReason="URL changed"),d;case"KEY_DOWN":return await this.browser.keyDown(n.value,{convertMeta:n.convertMeta??!0}),{urlAfterCommand:this.browser.url(),succeedImmediately:!1};case"KEY_UP":return await this.browser.keyUp(n.value,{convertMeta:n.convertMeta??!0}),{urlAfterCommand:this.browser.url(),succeedImmediately:!1};case"REQUEST":{let m=new fK,g=hK(fetch,m),h;try{h=new URL(n.url).hostname}catch{}let f=await cp({command:n,baseUrl:this.browser.baseUrl,logger:a,fetchImplementation:g});return{data:bl.parse({...f,cookies:md(m,h)}),succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"GRAPHQL_REQUEST":return{data:await bO({command:n,baseUrl:this.browser.baseUrl,logger:a}),succeedImmediately:!1,urlAfterCommand:this.browser.url()};case"VISUAL_DIFF":return fO({ctx:e,tracer:t,command:n,disableCache:i,browser:this.browser,logger:a,screenshotStorage:this.visualDiffScreenshotStorage,targetingWrapper:m=>this.wrapElementTargetingCommand(m)});case"FILE_UPLOAD":{let m,g;if(n.fileSource.type==="URL"?(g=n.fileSource.url,m=await IP({uri:n.fileSource.url,logger:a,orgId:this.orgId})):n.fileSource.type==="USER_FILE"&&(g=n.fileSource.name,m=await this.uploadedFileStorage?.getFileForUpload(n.fileSource.name,this.orgId)),!m)throw new R("UserConfigurationError",`Attempted to use non-existent file for upload step: ${g}`);await this.browser.setFileChooserHandler({...m,filename:n.filename});break}case"AUTH_SAVE":return{data:await this.browser.saveAuthState(),succeedImmediately:!1,urlAfterCommand:this.browser.url()};case"AUTH_LOAD":{let m;if(!n.storageState.trim())m=void 0;else if(m=await Un({orgId:this.orgId,code:n.storageState,fragment:!1,context:o,logger:a,localTools:this.localCodeEvalTools,signal:this.executeAbortController.signal}),typeof m!="object")throw new R("ActionFailureError",`Credentials must evaluate to an object (received ${typeof m} instead)`);let g;try{g=cA.optional().parse(m)}catch(h){throw new R("ActionFailureError",`Credentials provided do not follow the required format: ${h}`)}await this.browser.loadAuthState(g);break}case"ELEMENT_CHECK":{let m=(n.timeout??dr)*1e3,g=this.generator.getAgentConfig()?.assertion;if(gO(n.assertion)&&!n.useSelector&&n.target.type==="description"&&g&&g!=="v1"){let f={id:n.id,type:"AI_ASSERTION",assertion:`There is no element on the page closely matches the following description. If the description has single quotes, remember that requires an exact text substring match. Description: ${n.target.elementDescriptor}`,iframeUrl:n.iframeUrl,timeout:n.timeout,source:"NEGATED_CHECK",cache:n.cache&&"memory"in n.cache?{memory:n.cache?.memory}:void 0};try{let y=await sp({command:f,logger:a,aiPageFiltering:!!this.options?.aiPageFiltering,fixtures:this.getControllerFixtures(e),useMemory:this.shouldUseMemory()});return{succeedImmediately:!1,thoughts:`The element described does not exist on the page: ${y.thoughts}`,urlAfterCommand:this.browser.url(),afterScreenshotOverride:y.afterScreenshotOverride}}finally{f.cache?.memory&&Jc(n,f.cache?.memory.traces,a)}}let h=await pO({command:n,tracer:t,timeoutMs:m,targetingWrapper:f=>this.wrapElementTargetingCommand(f),fixtures:this.getControllerFixtures(e),disableCache:i});return{fail:!h.success,data:h.data,elementInteracted:h.elementInteractedDisplayString,thoughts:h.err?.message??h.thoughts??`Element assertion ${h.success?"succeeded":"failed"}.`,succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"PAGE_CHECK":{let m=await an({action:async()=>yO({assertion:n.assertion,browser:this.browser,logger:a,timeout:n.timeout,signal:this.executeAbortController.signal,autoExpandIframes:!!this.browser.userBrowserSettings.autoExpandIframes}),frameConfig:n.iframeUrl?{type:"url",url:n.iframeUrl}:void 0,browser:this.browser,logger:a});return{fail:!m.success,data:m.data,thoughts:m.success?"Page assertion passed.":m.err?.message??`Page assertion still failing after ${n.timeout} seconds.`,urlAfterCommand:this.browser.url(),succeedImmediately:!1}}case"REGISTER_REQUEST_LISTENER":{let m=new ei(n.requestMatcher),g=this.browser.registerRequestListener(m);return this.registeredListeners[n.key]=g.then(async h=>await py(h)).catch(h=>{a.error({err:h},"Failed to get request listener response")}),{succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"AWAIT_LISTENER":{let m=this.registeredListeners[n.key];if(!m)throw new R("ActionFailureError",`No listener registered with key: ${n.key}`);let g=n.timeout??10;return{data:await Y(m,{milliseconds:g*1e3,message:`Request listener timed out after ${g} seconds`}),succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"RECORD_REQUESTS":{let m=new ei(n.requestMatcher);return this.recordedRequests[n.key]={},this.browser.registerRequestRecorder(n.key,{matches:g=>m.matches({url:g.request.url,method:g.request.method}),onRequestStart:(g,h)=>{this.recordedRequests[n.key][g]=Ym(h)},onRequestComplete:(g,h)=>{this.recordedRequests[n.key]?.[g]&&(this.recordedRequests[n.key][g]=Ym(h))}}),{succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"GET_RECORDED_REQUESTS":{let m=this.recordedRequests[n.key];if(!m)throw new R("ActionFailureError",`No recorder registered with key: ${n.key}`);return delete this.recordedRequests[n.key],{data:Object.values(m),succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"SET_HEADER":{let m;return n.requestMatcher&&(m=new ei(n.requestMatcher)),this.browser.setHeader(n.name,n.value,m),{succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"MOCK_ROUTE":return{data:{key:this.browser.registerMock(n.key,new ei(n.requestMatcher),async(g,h)=>{let f=await Un({orgId:this.orgId,code:n.responseGenerator,fragment:!1,context:o,timeoutMs:void 0,logger:a,localTools:this.localCodeEvalTools,mock:{request:g,response:h},disallowVariableUpdates:!0,responseSerialization:"RESPONSE"}),y=NA.parse(f);return new Response(y.body,{status:y.status,headers:y.headers})},n.fetchOriginalResponse??!1)},succeedImmediately:!1,urlAfterCommand:this.browser.url()};case"REMOVE_ROUTE_MOCK":return this.browser.removeMock(n.key),{succeedImmediately:!1,urlAfterCommand:this.browser.url()};case"OFFLINE_MODE":return await this.browser.setOfflineMode(n.enable),{succeedImmediately:!1,urlAfterCommand:this.browser.url()};default:return(m=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(n)}return{succeedImmediately:!1,urlAfterCommand:this.browser.url()}}async getReverseMappedDescription({browserState:e,targetId:t,disableCache:n,screenshot:o}){return(await this.generator.getReverseMappedDescription({browserState:e,target:t,screenshot:o},{disableCache:n,abortSignal:this.executeAbortController.signal,loggerTags:ye(this.logger)})).phrase}async stopRecordMode(){this.recordAbortController?.abort(),await this.browser.clearAllCdpHighlights()}async startRecordMode({params:e,abortController:t,isClickToRecord:n}){this.recordAbortController=t;let o=new tp({signal:t.signal,...e});return await this.browser.startRecording(this.recordAbortController.signal,o,n),o}async runSectionAutohealing(e){return this.generator.getAutohealingProposal(e,{disableCache:!0,abortSignal:this.executeAbortController.signal,loggerTags:ye(this.logger)})}async getFailureRecoveryPlan(e){return this.generator.getFailureRecoveryPlan(e,{disableCache:!0,abortSignal:this.executeAbortController.signal,loggerTags:ye(this.logger)})}};import{mkdirSync as BK}from"fs";import{tmpdir as zK}from"os";import PO from"path";import{diff as UK}from"deep-object-diff";import{cloneDeep as Hy}from"lodash-es";import wO from"fontoxpath";import SK from"@prettier/plugin-xml";import yK from"prettier";import{DOMParser as bK,XMLSerializer as EK}from"slimdom";var TK=new Set(["android.webkit.webview","com.facebook.react.views.webview.reactwebview","com.tencent.smtt.sdk.webview","com.tencent.smtt.sdk.x5webview","org.xwalk.core.xwalkview","com.uc.webview.export.webview"]);function vK(r){let e=r.toLowerCase();return e.endsWith("webview")||TK.has(e)}function lu(r){return!!(vK(r.tagName)||r.getAttribute("package")==="com.android.chrome"&&r.getAttribute("content-desc")==="Web View"&&TO(r.tagName.toLowerCase()).startsWith("frame"))}function TO(r){let e=["android.widget.","android.view.","android.webkit.","android.app.","android.support.","androidx.","com.android.inputmethod."];for(let t of e)if(r.startsWith(t))return r.substring(t.length);return r}var AK=new Set(["index","package","a11y-important","screen-reader-focusabl"]),RK=new Set(["selected","checked","checkable","clickable","enabled","focusable","focused","long-clickable","password","scrollable","selected","showing-hint","context-clickable","multiline","text-entry-key","heading","dismissable","screen-reader-focusable","content-invalid","a11y-focused"]),wK=new Set(["text","hint"]),CK=new Set(["live-region","drawing-order"]),xK=new Set(["displayed","enabled"]);function _K(r,e){let t={};for(let[n,o]of Object.entries(e))AK.has(n)||n==="class"&&r===o||n==="focusable"&&o==="true"&&e.clickable==="true"||RK.has(n)&&o==="false"||wK.has(n)&&o===""||xK.has(n)&&o==="true"||CK.has(n)&&o==="0"||n!=="id"&&(t[n]=o);return t}function vO(r,e,t){let{prunedDocument:n,idToElement:o,prunedIdToElement:i,idCounter:a,opts:s}=r,c=a.value++;t.setAttribute("id",String(c));let l={};for(let p of e.attributes){let m=p.name,g=p.value;g!=null&&(l[m]=String(g))}let u=_K(e.tagName,l);for(let[p,m]of Object.entries(u))t.setAttribute(p,m);if(o.set(c,e),i.set(c,t),lu(e)){let p=s?.injectedWebviewContent??"";if(s?.removeWebviewContent){for(;t.firstChild;)t.removeChild(t.firstChild);return}else if(!s?.disableMomenticAccessibilityTree&&p.trim().length>0){for(;t.firstChild;)t.removeChild(t.firstChild);p.trim().length>0&&t.appendChild(n.createCDATASection(`
|
|
4583
|
+
`),tokenLength:d}),s.forEach((h,f)=>{let y=h.ids[0],E=h.ids[h.ids.length-1];r.debug({tokenLength:h.tokenLength,minId:y,maxId:E},`Chunk for page filtering (index ${f+1}/${s.length})`)}),{chunks:s}}var X2=75e4,ap=3e5;async function la(r){let{options:e,fixtures:t,screenshot:n}=r,{aiPageFiltering:o}=e,{logger:i,generator:a,orgId:s,signal:c}=t,l=r.tree,u=r.serializedTree,d=bn(u);if(d>X2)try{let p=ip({serializedTree:u,options:{minChunkTokenCount:1e4,maxChunkTokenCount:1e5,acceptableChunkTokenCount:5e4,maxLineLength:4e3},logger:i});l=await Z2({...r,tokenLimit:ap-1e4,chunks:p.chunks}),u=l.serialize();let m=bn(u);i.info({oldTokens:d,newTokens:m},"Filtered page using keywords"),d=m}catch(p){i.warn({err:p},"Error filtering page using keyword matching, using naive truncation"),l=l.pruneToSerializedCharLimit(ap*Xo),u=l.serialize();let m=bn(u);i.info({oldTokens:d,newTokens:m},"Filtered page using naive truncation"),d=m}if(d>ap)try{if(o){let p=ip({serializedTree:u,options:aO,logger:i}),m=Y2();l=await Y(J2({...r,chunks:p.chunks,callId:m}),{milliseconds:12e3,signal:c}),u=l.serialize();let g=bn(u);i.info({oldTokens:d,newTokens:g,langfuseCallId:m},"Filtered page using AI chunk ranking"),d=g}else{let p=ip({serializedTree:u,options:iO,logger:i});l=await Y(Q2({...r,chunkResult:p,tokenLimit:4e4}),{milliseconds:12e3,signal:c}),u=l.serialize();let m=bn(u);i.info({oldTokens:d,newTokens:m},"Filtered page using RAG"),d=m}}catch(p){i.warn({err:p},"Error filtering page using RAG/AI, using naive truncation"),l=l.pruneToSerializedCharLimit(ap*Xo),u=l.serialize(),i.info("Filtered page using naive truncation")}return u}async function J2({type:r,callId:e,chunks:t,description:n,fixtures:o,tree:i}){let{generator:a,signal:s,logger:c}=o,l=await a.rankChunksWithAi({chunks:t,description:n,type:r,softTokenLimit:4e4,hardTokenLimit:8e4,callId:e},{abortSignal:s,logger:c,loggerTags:ye(c)}),u=[];return t.forEach((p,m)=>{l.indices.includes(m)&&(u=u.concat(p.ids))}),i.pruneUsingRelevantIds(new Set(u))}async function Z2(r){let{description:e,fixtures:t,tree:n}=r,{generator:o,logger:i,signal:a}=t;if(!e.trim())throw new Error("Empty description passed to page filtering");let s=await o.getExtractedKeywords({goal:e},{logger:i,loggerTags:ye(i),abortSignal:a});i.info({keywordsResult:s},"Got keywords for page filtering");for(let c of s.keywords){let l=r.chunks.filter(m=>m.content.toLowerCase().includes(c.toLowerCase()));if(!l.length||l.reduce((m,g)=>m+g.tokenLength,0)>r.tokenLimit&&l.length>1)continue;let d=l.flatMap(m=>m.ids);return n.pruneUsingRelevantIds(new Set(d))}throw new Error("No keywords were unique enough for page filtering")}async function Q2(r){let{description:e,fixtures:t,chunkResult:n,tokenLimit:o,tree:i}=r,{generator:a,logger:s,signal:c}=t,l=await a.rankChunksWithRag({description:e,chunks:n.chunks,tokenLimit:o},{abortSignal:c,logger:s,loggerTags:ye(s)});if(l.ids.length===0)throw new Error("RAG returned no important ids");return i.pruneUsingRelevantIds(new Set(l.ids.map(d=>`${d}`)))}async function Uy(r,e){if(!r.description)throw new R("UserConfigurationError","Cannot locate element with empty description");return an({action:async()=>eK(r,e),frameConfig:r.iframeUrl?{type:"url",url:r.iframeUrl}:void 0,browser:e.browser,logger:r.logger})}async function eK(r,e){let{disableCache:t,testContext:n,filterByViewport:o,skipWait:i,source:a,memory:s,aiPageFiltering:c,logger:l,allowNotActionableNodesOverride:u,skipSavingVisualAttributes:d}=r,{orgId:p,browser:m,localCodeEvalTools:g,generator:h,abortSignal:f}=e,y=r.description,E=na(),b=r.useMemory&&!t;n&&(y=await Xc({orgId:p,s:y,context:n,localTools:g,signal:f,logger:l})),a&&(y=eO(y,a));let{serializedTree:_,tree:M}=await E.startAsyncSpan("GET_PAGE_STATE",async()=>jn(m,{allowNotActionableNodesOverride:u,filterByViewport:o,abortSignal:f,skipWait:i,logger:l}),{}),O=await E.startAsyncSpan("GET_PAGE_SCREENSHOT",async()=>{let U,W=Date.now(),ue;for(;!U&&Date.now()-W<3e3;){f.throwIfAborted();try{U=await m.screenshot({clearHighlights:!0,respectActiveFrame:!0,retries:2})}catch(le){ue=le}}if(!U)throw new R("ActionFailureError",`Failed to take screenshot of page to locate element. The page may be unresponsive, or your machine might be severely resource constrained. Error: ${ue?.message}`);return U}),v=_,C=!1,I=`data:image/jpeg;base64,${O.toString("base64")}`;v=await la({type:"locator",description:y,screenshot:I,serializedTree:_,options:{aiPageFiltering:c},tree:M,fixtures:{generator:h,signal:f,logger:l,orgId:p}}),v!==_&&(C=!0);let B=await E.startAsyncSpan("AI_LOCATOR_CALL",async U=>{let W=await h.getElementLocation({browserState:v,goal:y,screenshot:I,source:a,memory:b?s:void 0},{disableCache:t,abortSignal:f,loggerTags:ye(l),useMemory:b});return U.result=W,W});if(l.debug({usedRag:C,result:B},"Got locator result"),!(B.id>0))throw new Ro(`Could not find any relevant element: ${B.thoughts}`,B.updatedMemory?{type:"GCS_TRACES",traces:B.updatedMemory}:void 0);let{resolution:ee,target:K,frameConfig:ge}=await E.startAsyncSpan("TARGET_RESOLUTION",async U=>{let W=await m.createTargetFromA11yId({id:B.id,requirements:B.requirements,additionalElements:B.additionalElements,description:y,targetSource:"AI",logger:l,skipSavingVisualAttributes:d});return U.result={serializedElement:W.target.nodeOnlySerializedHtml??"Unknown HTML element"},W});if(ee.a11yNode?.properties?.hidden&&ee.a11yNode?.properties?.hidden!=="false")throw new R("ActionFailureError",`Momentic's AI found a relevant element to interact with, but it is explicitly marked with an 'aria-hidden' attribute. Please remove this attribute or adjust the element description to locate a different element. Element chosen: ${ee.displayString}`);return b&&(B.updatedMemory?K.memory={type:"GCS_TRACES",traces:B.updatedMemory}:s&&(K.memory=s)),{thoughts:B.thoughts,target:K,resolution:ee,frameConfig:ge,screenshot:I}}var tK=15;async function sp({command:r,aiPageFiltering:e,logger:t,fixtures:n,useMemory:o,maxRetries:i=tK}){if(!r.assertion.trim())throw new R("ActionFailureError","Assertion command is missing the assertion content");let a=oh.optional().catch(void 0).parse(r.source);r.source&&!a&&t.warn(`Invalid source ${r.source} for AI assertion, ignoring...`);let{browser:s}=n,c=r.timeout?r.timeout*1e3:s.smartWaitingTimeout,l=dP(c,i-1),u=0,d=Date.now(),p=d+c,m=d,g,h,f;try{await an({action:()=>s.clearHighlights(),frameConfig:r.iframeUrl?{type:"url",url:r.iframeUrl}:void 0,browser:s,logger:t})}catch(y){t.warn({err:y},"Failed to clear highlights before AI check, continuing...")}for(;u<i;){n.abortSignal.throwIfAborted();let y=Date.now();if(u>0){if(y>=p)break;let _=p-y,M=m-y,O=Math.min(M,_);O>0&&await J(O,n.abortSignal)}let E=Date.now();if(u>0&&E>=p)break;let b=!1;try{if(g=await an({action:async()=>{let M=await lO(s,t,n.abortSignal);return h&&h.serializedTree===M.serializedTree&&h.screenshotBuff.equals(M.screenshotBuff)?(b=!0,g):(h=M,cO({command:r,state:M,fixtures:n,useMemory:o,useConsensus:!1,highlightElementsOnFailure:!1,attemptNumber:u,aiPageFiltering:e,logger:t,source:a}))},frameConfig:r.iframeUrl?{type:"url",url:r.iframeUrl}:void 0,logger:t,browser:s}),g?.success){g?.updatedMemory&&Jc(r,g.updatedMemory,t);break}else throw g?.thoughts?new R("AssertionFailureError",g.thoughts):new R("InternalPlatformError","No thoughts were provided for AI assertion failure")}catch(_){n.abortSignal.throwIfAborted(),f=_ instanceof Error?_:new Error(`${_}`),b?t.info(`AI check attempt ${u} failed (re-used previous result)`):t.info({err:_},`AI check assert attempt ${u} failed, retrying...`)}finally{u++,m=E+l}}if(!g?.success){let y=p-Date.now();y>0&&await J(y,n.abortSignal)}if(!g?.success)try{g=await an({action:async()=>cO({command:r,state:await lO(s,t,n.abortSignal),fixtures:n,useMemory:o,useConsensus:!0,highlightElementsOnFailure:!0,attemptNumber:u,aiPageFiltering:e,logger:t}),frameConfig:r.iframeUrl?{type:"url",url:r.iframeUrl}:void 0,logger:t,browser:s})}catch(y){n.abortSignal.throwIfAborted(),f=y instanceof Error?y:new Error(`${y}`)}finally{u++}if(g?.updatedMemory&&Jc(r,g.updatedMemory,t),!g?.success){let y=`AI check still failing after ${u} attempts.`;throw f&&(y+=` Latest result: ${f.message}`),new R("AssertionFailureError",y)}return{...g,succeedImmediately:!1,urlAfterCommand:s.url()}}async function lO(r,e,t){let[n,o]=await Promise.all([jn(r,{abortSignal:t,skipWait:!0,skipWaitForPageLoad:!0,logger:e}),r.screenshot({retries:1,respectActiveFrame:!0})]);return{...n,screenshotBuff:o}}async function cO({command:r,state:e,fixtures:t,useConsensus:n,useMemory:o,highlightElementsOnFailure:i,aiPageFiltering:a,attemptNumber:s,source:c,logger:l}){let{browser:u,generator:d,abortSignal:p}=t,m={type:"ASSERTION"},{serializedTree:g,tree:h}=e,f=e.screenshotBuff,y=f.toString("base64"),E=u.url(),b=r.contextChoice??"MULTIMODAL",_=g;b!=="VISION_ONLY"&&(_=await la({type:"assertion",serializedTree:g,tree:h,description:r.assertion,screenshot:y,options:{aiPageFiltering:a},fixtures:{generator:d,signal:p,logger:l,orgId:t.orgId}}),_!==g&&(m.ragUsed=!0),m.pageState=_);let M={goal:r.assertion,url:E,memory:o?r.cache?.memory:void 0,browserState:_,screenshot:y,contextChoice:b,source:c},v=await(b==="VISION_ONLY"?(C,F)=>d.getVisualAssertionResult(C,F):(C,F)=>d.getAssertionResult(C,F))(M,{useConsensus:n,attemptNumber:s,useMemory:o,disableCache:!!r.disableCache,abortSignal:p,logger:l,loggerTags:ye(l)});return(v.result||i)&&v.relevantElements&&(m.relevantElementsSerialized=v.relevantElements.map(C=>u.getSerializedFormFromA11yId(C)).filter(C=>!!C),await rK(v.relevantElements,u,l)),{success:v.result,thoughts:v.thoughts,afterScreenshotOverride:f,updatedMemory:o?v.updatedMemory:void 0}}async function rK(r,e,t){let n=Date.now();for(let o of r){if(Date.now()-n>2e3){t.debug("Highlighting relevant elements took over 2s, aborting...");return}try{let i=new AbortController;await Y(e.highlightA11yId(o),{milliseconds:1e3,fallback:()=>{throw i.abort(),new Error("Timed out waiting for highlighting to complete")}})}catch(i){t.debug({err:i},"Failed to highlight relevant element after assertion, continuing...");return}}}var nK=1e5,lp=class extends Error{constructor(){super("The page content exceeds the maximum token limit for AI smart waiting."),this.name="ExceededMaxAISmartWaitingTokensError"}};async function uO(r,e){let{logger:t}=r,{abortSignal:n,browser:o}=e,i=Date.now();try{await oK(i,r,e)}catch(a){if(a instanceof Error&&(a.name==="AbortError"||a.name==="TimeoutError")||n.aborted)return;a instanceof lp?t.warn("Skipping AI smart waiting due to excessive page size - falling back to naive waiting"):t.warn({err:a},"Unexpected error occurred during AI smart waiting");let s=o.smartWaitingTimeout-(Date.now()-i);s>0&&await J(s,n)}finally{t.debug({durationMs:Date.now()-i},"AI smart waiting complete")}}async function oK(r,e,t){let{abortSignal:n,browser:o}=t;if(o.smartWaitingTimeout<3e3){await J(o.smartWaitingTimeout,n);return}if(!e.description)throw new R("UserConfigurationError","Cannot locate element with empty description");await Y(iK(r,e,t),{milliseconds:o.smartWaitingTimeout})}async function iK(r,e,t){let{logger:n,iframeUrl:o}=e,{browser:i}=t;for(;Date.now()-r<i.smartWaitingTimeout;)if(await an({action:async()=>aK(e,t),frameConfig:o?{type:"url",url:o}:void 0,browser:i,logger:n}))return}async function aK(r,e){let{testContext:t,logger:n,filterByViewport:o,allowNotActionableNodesOverride:i}=r,{browser:a,abortSignal:s,localCodeEvalTools:c,orgId:l,generator:u}=e,d=r.description;t&&(d=await Xc({orgId:l,s:d,context:t,localTools:c,signal:s,logger:n}));let{serializedTree:p}=await jn(a,{allowNotActionableNodesOverride:i,filterByViewport:o,abortSignal:s,logger:n});if(bn(p)>nK)throw new lp;s.throwIfAborted();let g;try{g=await a.screenshot({clearHighlights:!0,respectActiveFrame:!0,retries:2})}catch(E){throw new R("ActionFailureError",`Failed to take screenshot of page to perform smart waiting. The page may be unresponsive, or your machine might be severely resource constrained. Error: ${E instanceof Error?E.message:E}`)}let f=`data:image/jpeg;base64,${g.toString("base64")}`;s.throwIfAborted();let y=await u.getSmartWaitingDecision({browserState:p,description:d,screenshot:f},{abortSignal:s,loggerTags:ye(n)});return n.debug({result:y},"Got smart waiting result"),y.isPageReady}import{cloneDeep as mO}from"lodash-es";async function pO(r){let{command:e,timeoutMs:t,fixtures:n}=r,{abortSignal:o}=n,i=()=>Iu(e.cache)?e.cache:void 0,a=i(),s=mO(a),c=(h=!1)=>{if(a=i(),!!a)if(h){let f=EM(s,a);a.target=f.target,a.updatedAt=f.updatedAt}else{if(!s){a=void 0;return}a.target=s.target,a.updatedAt=s.updatedAt}},l=Date.now(),u=0,d,p=500,m=!1;for(;u<2||Date.now()-l<t;){u++,u>1&&await J(p,o),o?.throwIfAborted(),a=i();let{result:h,elementWasFound:f}=await dO({cacheToUse:a,params:r});if(d=h,m=f,h.success)break;c(),p=Math.min(p*2,1e4)}if(!d)throw new R("InternalPlatformError",`Failed to evaluate manual element assertion in ${t}ms.`);if(o?.throwIfAborted(),!d.success&&a?.target&&Aa(a.target)){let h=a?.target?.memory?{target:{id:-1,memory:a.target.memory}}:void 0,{result:f}=await dO({cacheToUse:h,params:r});d=f,d.success||c(!0)}let g=i();return d.success&&g?.target&&!m&&(g.target=FS(g.target),g.updatedAt=new Date),d}async function dO({cacheToUse:r,params:e}){let{command:t,disableCache:n,fixtures:o,tracer:i,targetingWrapper:a}=e,{logger:s}=o;if(t.target&&!vo(t.target))throw new Error("Element assertion with x/y is not supported yet");let c=Nm(t.assertion),l,u=!1,d=mO(r);try{let{elementInteractedDisplayString:p,result:m,thoughts:g}=await a({ctx:o.ctx,tracer:i,command:t,target:t.target,cache:d?.target,action:async h=>sK(h.locator,e),options:{...t,allowNotActionableNodesOverride:!0,disableCache:n,memory:d?.target?.memory,disableGlobalLocatorRedirect:!0,source:Ol(t),targetName:"target"}});return l={success:m.success,data:m.data,err:m.err,elementInteractedDisplayString:p,thoughts:g},u=!0,m.success||(s.warn({aiThoughts:g,elementString:p,err:m.err},"Element check found an element but failed"),l={...m,thoughts:g}),{result:l,elementWasFound:u}}catch(p){if(c)return l={success:!0,thoughts:`The element described does not exist on the page: ${p.message}`,err:void 0,data:void 0},{result:l,elementWasFound:u};if(!(p instanceof R)||p.reason!="ActionFailureError")throw p;return l={success:!1,err:p,data:void 0,thoughts:void 0},s.warn({err:p},"Element check did not find an element and failed"),{result:l,elementWasFound:u}}}async function sK(r,{command:e,fixtures:t}){return await t.browser.highlight(r),await lK(r,e.assertion)}async function lK(r,e){let t=!0,n,o;switch(e.type){case"ELEMENT_CONTENT":{let a=await r.textContent()??"";if(o={elementTextContent:Vt(a,500,!0)},!Bn(a,e.value,e.operation,{negated:!!e.negated,ignoreCase:!1})){let s=tn(e);t=!1,n=new R("AssertionFailureError",`The content ${s} '${e.value}': ${a}`)}break}case"ELEMENT_ATTRIBUTE":{o={elementOuterHtml:Vt(await r.evaluate(s=>s.cloneNode(!1).outerHTML),500,!0)};let a=null;try{a=await r.getAttribute(e.attr,{timeout:3e3})}catch(s){n=new R("AssertionFailureError",s instanceof Error?s.message:String(s)),t=!1;break}if(!Bn(a,e.value,e.operation,{negated:!!e.negated,ignoreCase:!1})){let s=tn(e);t=!1,e.operation==="EXISTS"?n=new R("AssertionFailureError",`The attribute ${e.attr} ${s}`):n=new R("AssertionFailureError",`The attribute ${e.attr} ${s} '${e.value}': ${a}`)}break}case"ELEMENT_EXISTENCE":{switch(e.condition){case"VISIBLE":{t=await r.evaluate(async(s,c)=>{let l=Date.now();for(;Date.now()-l<c;){await new Promise(d=>setTimeout(d,250));let u=s.getBoundingClientRect();if(!(u.width===0||u.height===0)&&window.getComputedStyle(s).visibility!=="hidden"&&window.getComputedStyle(s).display!=="none")return!0}return!1},dr*1e3);break}case"EDITABLE":{t=await r.isEditable({timeout:dr*1e3});break}case"EXISTS":{t=!0;break}case"ENABLED":{t=await r.isEnabled({timeout:dr*1e3});break}case"FOCUSED":{t=await r.evaluate(s=>s===document.activeElement);break}default:return(s=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(e.condition)}if(t=e.negated?!t:t,!t){let a=tn(e);n=new R("AssertionFailureError",`The element ${a}`)}break}case"ELEMENT_NAME":{let a=await r.evaluate(s=>s.tagName);if(!Bn(a,e.value,e.operation,{negated:!!e.negated,ignoreCase:!0})){let s=tn(e);t=!1,n=new R("AssertionFailureError",`The element tag name ${s} '${e.value}': ${a}`)}break}case"ELEMENT_STYLE":{let a=await r.evaluate((s,c)=>window.getComputedStyle(s).getPropertyValue(c),e.property);if(!Bn(a,e.value,e.operation,{negated:!!e.negated,ignoreCase:!1})){let s=tn(e);t=!1,e.operation==="EXISTS"?n=new R("AssertionFailureError",`The style property ${e.property} ${s}`):n=new R("AssertionFailureError",`The style property ${e.property} ${s} '${e.value}': ${a}`)}break}default:return(a=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(e)}return{thoughts:void 0,success:t,data:o,err:n}}function gO(r){return r.type==="ELEMENT_EXISTENCE"&&r.negated&&r.condition==="EXISTS"}import{Jimp as cK}from"jimp";async function su(r,e){let t=await r.screenshot(e),n=await cK.fromBuffer(t);return{buffer:t,width:Math.ceil(n.bitmap.width??0),height:Math.ceil(n.bitmap.height??0)}}import{Jimp as hO}from"jimp";import By from"jpeg-js";import uK from"pixelmatch";async function fO({ctx:r,tracer:e,command:t,disableCache:n,browser:o,targetingWrapper:i,logger:a,screenshotStorage:s}){if(t.target&&!vo(t.target))throw new Error("Visual Diff with x/y is not supported yet");await o.waitForStability({logger:a});let c={clearHighlights:!0,hideCaret:!0},l;t.target?.elementDescriptor?l=(await i({ctx:r,tracer:e,command:t,target:t.target,cache:t.cache?.target,action:async B=>su(o,{locator:B.locator,...c}),options:{...t,disableCache:n,disableGlobalLocatorRedirect:!0,memory:t.cache?.target?.memory,targetName:"target"}})).result:l=await su(o,c);let u=await s.prepareGoldenScreenshotForComparison(a,t,l);if((l.height!==u.height||l.width!==u.width)&&a.warn({currHeight:l.height,currWidth:l.width,savedHeight:u.height,savedWidth:u.width},"Mismatched before and after visual diff screenshot sizes"),Math.abs(l.height-u.height)>10||Math.abs(l.width-u.width)>10){let I=`${l.width}x${l.height}`,B=`${u.width}x${u.height}`;return{fail:!0,thoughts:`Current screenshot (${I}) does not match saved screenshot dimensions (${B}) - did you change the size of the target or the viewport?`,beforeScreenshotOverride:u.buffer,afterScreenshotOverride:l.buffer,succeedImmediately:!1,urlAfterCommand:o.url()}}let d=await hO.fromBuffer(l.buffer),p={width:l.width,height:l.height},m=await hO.fromBuffer(u.buffer),g={width:u.width,height:u.height},h,f=p.width*p.height,y=g.width*g.height,E=Math.abs(p.height-g.height),b=Math.abs(p.width-g.width);if(f>y){let I=d.cover({w:g.width,h:g.height});l.buffer=await I.getBuffer("image/jpeg"),h="current",l.width=g.width,l.height=g.height}else if(y>f){let I=m.cover({w:p.width,h:p.height});u.buffer=await I.getBuffer("image/jpeg"),h="saved"}let _={data:Buffer.alloc(l.width*l.height*4),width:l.width,height:l.height},M=t.threshold??.1,v=uK(By.decode(u.buffer).data,By.decode(l.buffer).data,_.data,l.width,l.height,{threshold:M,diffColorAlt:[0,255,0]})/(l.width*l.height)*100,C=v>M*100,F=`Visual diff of ${v.toFixed(2)}% detected, which is ${C?"over":"under"} the threshold of ${M*100}%.`;if(h&&(F+=` The ${h} screenshot was cropped since it was taller by ${E} pixels and wider by ${b} pixels.`),C)throw new R("ActionFailureError",F);return{fail:C,thoughts:F,beforeScreenshotOverride:l.buffer,afterScreenshotOverride:By.encode(_,75).data,succeedImmediately:!1,urlAfterCommand:o.url()}}var dK=3e4;function mK(r){if(!r.body)return{};switch(r.body.type){case"json":return{content:r.body.content,contentType:"application/json"};case"form-urlencoded":{let e=new URLSearchParams;return Object.entries(r.body.content).forEach(([t,n])=>{e.append(t,n)}),{content:e.toString(),contentType:"application/x-www-form-urlencoded;charset=UTF-8"}}}}async function cp({command:r,logger:e,baseUrl:t,fetchImplementation:n=fetch}){let o=r.timeout??dK/1e3,i=Object.fromEntries(Object.entries(r.headers||{}).filter(([g,h])=>g&&h)),a=new URLSearchParams;Object.entries(r.params||{}).filter(([g,h])=>g&&h).forEach(([g,h])=>{a.append(g,h)});let s=a.toString(),c;if(Ls(r.url)&&(c=r.url),t&&Ns(r.url,t)&&(c=new URL(r.url,t).toString()),!c)throw new R("ActionFailureError",`Invalid URL: ${r.url}`);let l=c;e.info({url:l,searchParams:s,headers:i,body:r.body,method:r.method},"Making HTTP request");let d=await Y((async()=>{let g=s?`${l}?${s}`:l;try{let h=mK(r),f=new Headers(i);return h.contentType&&!f.has("Content-Type")&&f.set("Content-Type",h.contentType),await n(g,{headers:f,method:r.method,body:h.content})}catch(h){throw new Error(`Failed to make HTTP request: ${h}`,{cause:h})}})(),{milliseconds:o*1e3,fallback:()=>{throw new R("ActionFailureError",`Fetch request timed out after ${o} seconds`)}});if(!d.ok){let g;try{g=await d.text()}catch(h){g=`Failed to read response body: ${h}`}throw new R("ActionFailureError",`Fetch request failed with status ${d.status}: ${g}`)}let p={};d.headers.forEach((g,h)=>{p[h]=g});let m={status:d.status,headers:p,request:{url:d.url,method:r.method,headers:i}};if(r.body?.type==="json"&&r.body.content)try{m.request.json=JSON.parse(r.body.content)}catch{}if(d.headers.get("content-type")?.includes("json"))try{m.json=await d.json()}catch{}else d.headers.get("content-type")?.includes("text")&&(m.text=await d.text());return m}var pK=5e3;async function yO({timeout:r=dr,...e}){let t=Date.now(),n=r*1e3,o=n+1e4,i,a=0,s=500;for(;a-t<n;){if(Date.now()-t>o){e.logger.warn("Exceeded max system timeout for page assertion, exiting...");break}e.signal?.throwIfAborted();let c=Date.now();i=await up(e),a=Date.now();let l=a-c;if(l>1e3&&e.logger.warn({pageAssertDuration:l},"Page assertion took longer than expected"),!i.success)await J(s,e.signal),s=Math.min(Math.floor(s*1.5),pK);else return i}return i=await up(e),i}async function up({assertion:r,browser:e,autoExpandIframes:t}){switch(r.type){case"CONTENT":case"CONTENT":{let o,i=!1,a;try{let s;if(t){let c=await e.evaluateFunctionInAllFrames(SO,{value:r.value,negated:!!r.negated,returnHtml:!1});i=r.negated?c.every(l=>l.evaluation):c.some(l=>l.evaluation),s=c.find(l=>l.pageHtml)?.pageHtml}else({evaluation:i,pageHtml:s}=await e.evaluateFunctionInPage(SO,{value:r.value,negated:!!r.negated,returnHtml:!0},"checking page content"));if(!i){let c=r.negated?uo.CONTAINS:mo.CONTAINS;a=new R("AssertionFailureError",`The page ${c} '${r.value}'.`),o=s}}catch(s){a=new R("AssertionFailureError",`Failed to evaluate page content assertion: ${s instanceof Error?s.message:`${s}`}`)}return{success:i,err:a,data:i||!o?void 0:{pageContent:o}}}default:return(o=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(r)}}function SO({value:r,negated:e,returnHtml:t}){let n=document.body.innerHTML,o=n.includes(r)===!e;return n.length>1e4&&(n=n.slice(0,1e4)+"...TRUNCATED"),{evaluation:o,pageHtml:!o&&t?n:void 0}}var gK=3e4;async function bO({command:r,logger:e,baseUrl:t,fetchImplementation:n=fetch}){let o=r.timeout??gK/1e3,i=new AbortController,a=Object.fromEntries(Object.entries(r.headers||{}).filter(([d,p])=>d&&p));a["Content-Type"]="application/json";let s;if(Ls(r.url)&&(s=r.url),t&&Ns(r.url,t)&&(s=new URL(r.url,t).toString()),!s)throw new R("ActionFailureError",`Invalid URL: ${r.url}`);let l=await Y((async()=>{try{return await n(s,{headers:a,method:"POST",body:JSON.stringify({query:r.query,variables:r.variables?JSON.parse(r.variables):void 0}),signal:i.signal})}catch(d){throw new Error(`Failed to make HTTP request: ${d}`,{cause:d})}})(),{milliseconds:o*1e3});if(!l)throw new R("ActionFailureError",`GraphQL request timed out after ${o} seconds`);if(!l.ok){let d,p=await l.text();try{d=JSON.parse(p)}catch{throw new R("ActionFailureError",`GraphQL request failed with status ${l.status}: ${p}`)}throw d?.errors?.length&&d?.errors[0]?.message?new R("ActionFailureError",`GraphQL request failed with status ${l.status}: ${d.errors[0].message}`):new R("ActionFailureError",`GraphQL request failed with status ${l.status}: ${p}`)}let u={};return l.headers.forEach((d,p)=>{u[p]=d}),{status:l.status,headers:u,json:await l.json()}}var dp=class{orgId;options;storage;localCodeEvalTools;uploadedFileStorage;visualDiffScreenshotStorage;browser;generator;executeAbortController=new AbortController;logger;recordAbortController=null;registeredListeners={};recordedRequests={};constructor({browser:e,generator:t,logger:n,storage:o,orgId:i,localCodeEvalTools:a,uploadedFileStorage:s,visualDiffScreenshotStorage:c,options:l}){this.orgId=i,this.options=l,this.browser=e,this.browser.registerAbortSignal(this.executeAbortController.signal),this.storage=o,this.uploadedFileStorage=s,this.visualDiffScreenshotStorage=c,this.localCodeEvalTools=a,this.generator=t,this.logger=n}setOpen(){this.executeAbortController=new AbortController,this.browser.registerAbortSignal(this.executeAbortController.signal)}setClosed(){this.executeAbortController.abort()}throwIfClosed(){this.executeAbortController.signal.throwIfAborted()}get closed(){return this.executeAbortController.signal.aborted}async evaluateAiAction({goal:e,startingScreenshot:t,history:n,disableCache:o,langfuseSessionId:i,lastError:a,logger:s=this.logger}){let[c,l]=await Promise.all([jn(this.browser,{abortSignal:this.executeAbortController.signal,skipWait:!0,skipWaitForPageLoad:!0,logger:s}),this.browser.screenshot({retries:1,clearHighlights:!0})]),u=`data:image/jpeg;base64,${l.toString("base64")}`,d=await la({type:"ai-action",description:e,screenshot:u,serializedTree:c.serializedTree,tree:c.tree,options:{aiPageFiltering:!!this.options?.aiPageFiltering},fixtures:{generator:this.generator,signal:this.executeAbortController.signal,logger:s,orgId:this.orgId}}),p={url:this.browser.url(),browserState:d,startingScreenshot:t,history:n,goal:e,screenshot:u,lastError:a};return await this.generator.getMultiturnAiActionEvaluation(p,{disableCache:o,abortSignal:this.executeAbortController.signal,loggerTags:{...ye(s)},langfuseSessionId:i})}async promptToCommand({goal:e,startingScreenshot:t,history:n,actionHint:o,disableCache:i,logger:a=this.logger,langfuseSessionId:s}){let c=this.browser.url(),[l,u]=await Promise.all([jn(this.browser,{abortSignal:this.executeAbortController.signal,skipWait:!0,skipWaitForPageLoad:!0,logger:a}),this.browser.screenshot({retries:1,clearHighlights:!0})]),d=`data:image/jpeg;base64,${u.toString("base64")}`,p=await la({type:"ai-action",description:e,screenshot:d,serializedTree:l.serializedTree,tree:l.tree,options:{aiPageFiltering:!!this.options?.aiPageFiltering},fixtures:{generator:this.generator,signal:this.executeAbortController.signal,logger:a,orgId:this.orgId}}),m={url:c,browserState:p,startingScreenshot:t,history:n,goal:e,actionHint:o,screenshot:d};try{return await this.generator.getMultiturnAiActionCommand(m,{disableCache:i,abortSignal:this.executeAbortController.signal,loggerTags:{...ye(a)},langfuseSessionId:s})}catch(g){throw new R("InternalWebAgentError",`Error generating command: ${g instanceof Error?g.message:g}`,{errOptions:{cause:g}})}}async getBrowserState(e){return jn(this.browser,e)}async locateElement(e){return await Uy({...e,aiPageFiltering:!!this.options?.aiPageFiltering},this.getControllerFixtures())}async locateElementWithSelector(e,t){return an({action:async()=>{let n=await this.browser.resolveHardcodedCssSelector({ctx:null,selector:e,timeoutMs:2e3,logger:this.logger});return{thoughts:"Located element with selector",target:{id:-1,selector:e,targetSource:"USER_CSS_SELECTOR",targetUpdateTime:new Date().toUTCString()},resolution:n}},frameConfig:t?{type:"url",url:t}:void 0,browser:this.browser,logger:this.logger})}getControllerFixtures(e){return{ctx:e??null,browser:this.browser,generator:this.generator,logger:this.logger,orgId:this.orgId,storage:this.storage,localCodeEvalTools:this.localCodeEvalTools,abortSignal:this.executeAbortController.signal}}shouldUseMemory(){return this.options?.useMemory??(this.orgId==="org_01HMSCJQBCCG51M2ZF65YC5B8W"||this.orgId==="org_01HMJTX4GT1KG94KZRCT8MZ6YB")}async wrapMultiElementTargetingCommand({ctx:e,tracer:t,command:n,targetNames:o,descriptions:i,caches:a,action:s,options:c,retriesWithAI:l=1}){let u=[];for(let d=0;d<i.length;d++){let p=i[d],m=await this.wrapElementTargetingCommand({ctx:e,tracer:t,command:n,target:p,cache:a[d],action:async g=>g,options:{...c,targetName:o[d]}});u.push(m)}try{let d=await s(...u.map(g=>g.result)),p=g=>g==="fromTarget"?"From Target":g==="toTarget"?"To Target":"Target",m=u.map((g,h)=>g.thoughts?`${p(o[h])}: ${g.thoughts}`:void 0).filter(g=>!!g).join(" -------------- ")||void 0;return{result:d,elementInteractedDisplayStrings:u.map(g=>g.elementInteractedDisplayString),thoughts:m}}catch(d){if(this.throwIfClosed(),l>0)return this.logger.warn({err:d},"Failed to execute action with multiple cached targets, retrying with AI"),this.wrapMultiElementTargetingCommand({ctx:e,tracer:t,command:n,targetNames:o,descriptions:i,caches:i.map(()=>{}),action:s,options:c,retriesWithAI:l-1});throw new R("ActionFailureError",d.message,{errOptions:{cause:d}})}}async wrapHardcodedCssTargetingCommandHelper({ctx:e,target:t,action:n,options:o,command:i}){let a=this.logger.child({commandId:i.id}),{targetName:s}=o;if(t.type!=="description")throw new R("ActionFailureError","Cannot use selector with non-description target");let c,l=Date.now(),u=Date.now();for(;Date.now()-u<this.browser.smartWaitingTimeout;){l=Date.now();try{let d=await this.browser.resolveHardcodedCssSelector({ctx:e,selector:t.elementDescriptor,targetName:s,logger:a});return{result:await n({locator:d.locator,originalElementLocationResult:void 0,serverSideBoundingBox:null}),elementInteractedDisplayString:d.displayString}}catch(d){if(d.name==="AbortError")throw d;c=d,a.warn({err:d},"Failed to action on hardcoded css selector"),Date.now()-l<500&&await J(500)}}throw c}async scrollIntoViewAndResolveFinalTarget(e){let{resolutionResult:t,disableGlobalLocatorRedirect:n,logger:o}=e,i=na(),a=!n&&this.browser.userBrowserSettings.globalLocatorRedirect!==!1;(this.browser.userBrowserSettings.visualActions||a)&&await i.startAsyncSpan("SCROLL_ELEMENT_INTO_VIEW",async()=>{await this.browser.scrollIntoViewIfNeeded(t.locator)});let s;return a&&(s=await i.startAsyncSpan("LOCATOR_REDIRECT",async()=>this.browser.performTargetRedirection(t,o))),s||(s={locator:t.locator,serverSideBoundingBox:await t.locator.boundingBox({timeout:ae}),originalElementLocationResult:t.originalElementLocationResult}),s}async resolveCachedTargetForAction(e){let{ctx:t,cache:n,options:o,logger:i}=e,s=await na().startAsyncSpan("CACHE_RESOLUTION",async l=>{let u=await this.browser.resolveTarget(t,n,{allowNotActionableNodesOverride:o.allowNotActionableNodesOverride,logger:i,signal:this.executeAbortController.signal,...o.resolveTargetOptions});return l.attributes.targetDisplayString=u.displayString,u}),c=await this.scrollIntoViewAndResolveFinalTarget({resolutionResult:s,disableGlobalLocatorRedirect:o.disableGlobalLocatorRedirect,logger:i});return await s.revalidator?.(),{resolutionResult:s,finalTarget:c}}async wrapElementTargetingCommand(e){return await an({action:()=>this.wrapElementTargetingCommandHelper(e),frameConfig:e.options.iframeUrl?{type:"url",url:e.options.iframeUrl}:void 0,browser:this.browser,logger:this.logger})}async wrapElementTargetingCommandHelper(e){let{ctx:t,tracer:n,target:o,action:i,options:a,command:s,finalAttempt:c=!1,originalCache:l=e.cache}=e,{retriesWithAI:u=1}=e,{disableCache:d,useSelector:p,targetName:m}=a,g=na(),h=this.logger.child({commandId:s.id}),f=this.shouldUseMemory(),y=EO(e.cache);if((!y||d)&&!yg(o))throw new R("ActionFailureError","Cannot target element with no cached data or element descriptor");if(p)return this.wrapHardcodedCssTargetingCommandHelper(e);let E=!1;d&&(h.info("Cache explicitly disabled for this step"),E=!0,y=void 0);let b=nO({cache:y,description:o.elementDescriptor,disableSecondaryCacheResolution:!!this.browser.userBrowserSettings.disableSecondaryCacheResolution,logger:h});y=b.cache,E=E||b.cacheBustedBeforeAction;let _=!0;if(!rO(y))return u--,_=!1,this.executeTargetingCommandWithAI({ctx:t,tracer:g,stepTracer:n,target:o,options:a,command:s,action:i,originalCache:l,logger:h,useMemory:f,cacheBustedBeforeAction:E});try{let{resolutionResult:M,finalTarget:O}=await this.resolveCachedTargetForAction({ctx:t,cache:y,options:a,logger:h}),v=await i(O);if(nt.increment("cache_target_resolution_v2",1,["outcome:hit","platform:web",`hasRequirements:${!!y.requirements}`,`hasAdditionalElements:${!!y.additionalElements}`,`orgId:${this.orgId}`,"cliVersion:0.34.0"]),km({cmd:s,key:m,newTarget:y,logger:h,updatedWithAI:!1}),_){let C=M.decisions.filter(F=>F.matched);if(C.length!==1)h.warn({decisions:M.decisions},"Expected exactly 1 matching method for element location, got more or less");else{let F=C[0].type;n.recordTargetAutoHeal({healType:F})}}return{result:v,elementInteractedDisplayString:M.displayString}}catch(M){this.throwIfClosed();let O=Ng(M);if(O&&!c)return h.warn({err:M},"Encountered error that is retryable with cache"),this.wrapElementTargetingCommandHelper({ctx:t,tracer:n,command:s,target:o,action:i,cache:l,originalCache:l,retriesWithAI:u,finalAttempt:!0,options:a});if(M instanceof R&&!O)throw h.warn({err:M},"Failed to execute command with target (fatal)"),M;if(u>0&&o){h.info({err:M},"Failed to execute action with cached target, retrying with AI"),nt.increment("cache_target_resolution_v2",1,["outcome:miss","platform:web",`hasRequirements:${!!y.requirements}`,`hasAdditionalElements:${!!y.additionalElements}`,`orgId:${this.orgId}`,"cliVersion:0.34.0",`missReason:${M instanceof gt?M.cacheMissReason:"unknown"}`]);let v;return y.memory&&gE(y.memory)&&(v=y.memory),this.wrapElementTargetingCommandHelper({ctx:t,tracer:n,command:s,target:o,cache:void 0,action:i,originalCache:l,retriesWithAI:u,finalAttempt:!0,options:{...a,memory:v,targetHealingInProgress:!0}})}throw new R("ActionFailureError",`Failed to execute interactive command: ${M instanceof Error?M.message:`${M}`}`,{errOptions:{cause:M}})}}async executeTargetingCommandWithAI(e){let{ctx:t,tracer:n,stepTracer:o,target:i,options:a,command:s,action:c,originalCache:l,logger:u,useMemory:d,cacheBustedBeforeAction:p}=e;u.info({description:i.elementDescriptor,targetHealingInProgress:a.targetHealingInProgress,cacheBustedBeforeAction:p,memory:a.memory,useMemory:d},"Prompting AI for an updated element location"),(p||!l)&&await n.startAsyncSpan("SMART_WAITING",async()=>await uO({description:i.elementDescriptor,iframeUrl:a.iframeUrl,source:a.source,logger:u,allowNotActionableNodesOverride:a.allowNotActionableNodesOverride},this.getControllerFixtures(t)));let m=2;for(let g=1;g<=m;g++){let h=!1,f=this.browser.getActiveFrameConfig();try{let y;try{y=await Uy({description:i.elementDescriptor,disableCache:!!a.disableCache,iframeUrl:a.iframeUrl,source:a.source,useMemory:d,memory:d?a.memory:void 0,aiPageFiltering:!!this.options?.aiPageFiltering,allowNotActionableNodesOverride:a.allowNotActionableNodesOverride,logger:u},this.getControllerFixtures(t))}catch(_){if(_ instanceof Ro&&_.updatedLocatorMemory){let M={id:-1,...l,memory:_.updatedLocatorMemory};km({cmd:s,key:a.targetName,newTarget:M,logger:u,updatedWithAI:!0})}throw _}y.frameConfig&&(this.browser.setActiveFrameConfig(y.frameConfig),h=!0);let E=await this.scrollIntoViewAndResolveFinalTarget({resolutionResult:y.resolution,disableGlobalLocatorRedirect:a.disableGlobalLocatorRedirect,logger:u}),b=await c(E);return km({cmd:s,key:a.targetName,newTarget:y.target,logger:u,updatedWithAI:!0}),a.targetHealingInProgress&&(o.recordTargetAutoHeal({healType:"AI"}),y.target.targetSource="AI_HEALED",y.target.targetUpdateTime=new Date().toUTCString(),y.target.targetUpdateLoggerTags=ye(u)),{result:b,elementInteractedDisplayString:y.resolution.displayString,thoughts:y.thoughts}}catch(y){if(h&&this.browser.setActiveFrameConfig(f),this.throwIfClosed(),g<m&&Ng(y)){u.warn({err:y,aiAttempt:g},"Encountered retryable AI targeting error; retrying with AI once");continue}throw y instanceof R?y:new R("ActionFailureError",y.message)}}throw new R("ActionFailureError","Failed to execute AI targeting after retry")}async screenshotWithDimensions(e){return su(this.browser,e)}async executePresetCommand(e,t,n,o,i){this.options?.slowMoMs&&await J(this.options.slowMoMs);let a=await this.browser.getOpenPages(),s=this.browser.url(),c;try{c=await this.resolveCommandTemplateStrings(n,o)}catch(l){throw this.throwIfClosed(),new R("ActionFailureError",`Failed to substitute template strings in command: ${l.message}`,{errOptions:{cause:l}})}try{let l=await this.executePresetCommandHelper(e,t,n,o,i);return this.options?.autoFollowNewTabs&&await tO({beforeUrl:s,command:n,beforePages:a.map(u=>u.url),browser:this.browser,logger:this.logger}),l}catch(l){throw l.name!=="AbortError"&&this.logger.error({err:l},"Error thrown in action controller"),l}finally{Is(n,c)}}createCallbacksForBrowser(e){return{createIsolatedFolder:()=>ly(e)}}async resolveCommandTemplateStrings(e,t){return Ps({obj:e,context:t,bannedKeys:["type","a11yData","thoughts","cache","code"],orgId:this.orgId,logger:this.logger,signal:this.executeAbortController.signal,localTools:this.localCodeEvalTools})}async executePresetCommandHelper(e,t,n,o,i){i=i||"disableCache"in n&&!!n.disableCache;let a=this.logger.child({commandId:n.id});switch(n.type){case"SUCCESS":let s=n.condition;return s?.assertion.trim()?sp({command:s,fixtures:this.getControllerFixtures(e),useMemory:this.shouldUseMemory(),aiPageFiltering:!!this.options?.aiPageFiltering,logger:a}):{succeedImmediately:!1,urlAfterCommand:this.browser.url()};case"AI_ASSERTION":{if(!n.assertion.trim())throw new R("ActionFailureError","Missing assertion");if(n.timeout&&n.timeout>1800)throw new R("AssertionFailureError",`AI check timeout of ${n.timeout} exceeds the maximum allowed value of 30 minutes.`);return sp({command:n,fixtures:this.getControllerFixtures(e),useMemory:this.shouldUseMemory(),aiPageFiltering:!!this.options?.aiPageFiltering,logger:a})}case"AI_EXTRACT":{if(!n.goal.trim())throw new R("ActionFailureError","Cannot perform AI extraction without goal");if(n.schema){let h=iw(n.schema);if(h)throw new R("UserConfigurationError",h)}let m=await this.browser.getCondensedHtml(),g=await this.browser.screenshot({retries:2});try{let h=await this.generator.getTextExtraction({goal:n.goal,browserState:m,returnSchema:n.schema,screenshot:`data:image/jpeg;base64,${g.toString("base64")}`},{disableCache:i,abortSignal:this.executeAbortController.signal,loggerTags:ye(a)});if(h.result==="NOT_FOUND")throw new R("ActionFailureError","No relevant data found for extraction goal on this page");if(h.thoughts?.includes("MaxGenerationLengthExceededError"))throw new R("UserConfigurationError",h.thoughts);return{thoughts:h.thoughts||void 0,data:h.result,succeedImmediately:!1,urlAfterCommand:this.browser.url()}}catch(h){let f=h.message;throw f.includes("MaxGenerationLengthExceededError")?new R("UserConfigurationError","You tried to extract too much data. Please rephrase your query to limit the results returned or use a JavaScript step in the browser instead."):f.includes("AIProviderError")&&f.includes("time")?new R("AIProviderError","The AI provider responded with an error. This may be because you tried to extract too much data. Please limit extraction results to 2000 characters.",{errOptions:{cause:h}}):h}}case"NAVIGATE":if(!Ls(n.url)&&!Ns(n.url,this.browser.baseUrl))throw new R("ActionFailureError",`Invalid URL provided to navigate command: ${n.url}`);await this.browser.navigate({url:n.url,loadTimeoutMs:n.loadTimeout?n.loadTimeout*1e3:void 0});break;case"DIALOG":this.browser.registerDialogHandler(n.action);break;case"CAPTCHA":throw new R("UserConfigurationError","Captcha solving is no longer available on Momentic");case"GO_BACK":await this.browser.goBack();break;case"GO_FORWARD":await this.browser.goForward();break;case"SCROLL_LEFT":case"SCROLL_RIGHT":case"SCROLL_DOWN":case"SCROLL_UP":{let m,g;if(n.target&&An(n.target))await this.browser.hoverUsingVisualCoordinates(n.target.pixels);else if(n.target&&n.target.elementDescriptor.trim()){let{elementInteractedDisplayString:y,thoughts:E}=await this.wrapElementTargetingCommand({ctx:e,tracer:t,command:n,target:n.target,cache:n.cache?.target,action:b=>this.browser.hover(b),options:{...n,targetName:"target",disableGlobalLocatorRedirect:!0,disableCache:i}});m=y,g=E}let h=this.browser.getViewport()?.height??Po.height,f=this.browser.getViewport()?.width??Po.width;switch(n.type){case"SCROLL_UP":await this.browser.scrollVertical(-(n.deltaY??h));break;case"SCROLL_DOWN":await this.browser.scrollVertical(n.deltaY??h);break;case"SCROLL_LEFT":await this.browser.scrollHorizontal(-(n.deltaX??f));break;case"SCROLL_RIGHT":await this.browser.scrollHorizontal(n.deltaX??f);break}return{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:m,thoughts:g}}case"WAIT_FOR_URL":{if(n.timeout&&n.timeout>1800)throw new R("UserConfigurationError",`Wait for URL timeout of ${n.timeout} exceeds the maximum allowed value of 30 minutes.`);let m=n.matcher;await this.browser.waitForUrl({beforeUrl:this.browser.url(),matcher:m},{timeout:n.timeout?n.timeout*1e3:void 0,negated:n.negated,caseInsensitive:n.caseInsensitive});break}case"WAIT":if(n.delay>1800)throw new R("UserConfigurationError",`Wait timeout of ${n.delay} seconds exceeds the maximum allowed value of 30 minutes`);let c=n.delay*1e3;await J(c,this.executeAbortController.signal);break;case"REFRESH":await this.browser.refresh({loadTimeoutMs:n.loadTimeout?n.loadTimeout*1e3:void 0});break;case"CLICK":{if(An(n.target)){await this.browser.clickUsingVisualCoordinates(n.target.pixels,n);break}let m=this.browser.url(),{elementInteractedDisplayString:g,result:h,thoughts:f}=await this.wrapElementTargetingCommand({ctx:e,tracer:t,target:n.target,command:n,cache:n.cache?.target,action:E=>this.browser.click(E,this.createCallbacksForBrowser(this.orgId),n),options:{disableCache:i,targetName:"target",...n}}),y={urlAfterCommand:this.browser.url(),succeedImmediately:!1,elementInteracted:g,thoughts:f,data:h.downloadedFile?{downloadedFile:h.downloadedFile}:void 0};return Wm(m,y.urlAfterCommand)&&(y.succeedImmediately=!0,y.succeedImmediatelyReason="URL changed"),y}case"COPY":return await this.browser.copy(n.value),{succeedImmediately:!1,data:n.value,urlAfterCommand:this.browser.url()};case"PASTE":{await this.browser.paste();break}case"DRAG":{if(An(n.fromTarget)&&An(n.toTarget)){await this.browser.dragAndDropUsingVisualCoordinates(n.fromTarget.pixels,n.toTarget.pixels,{hoverDurationMs:n.hoverSeconds?n.hoverSeconds*1e3:void 0});break}if(An(n.fromTarget)||An(n.toTarget))throw new Error("Drag and drop targets must be both coordinates or both descriptions");let{elementInteractedDisplayStrings:m,thoughts:g}=await this.wrapMultiElementTargetingCommand({ctx:e,tracer:t,command:n,targetNames:["fromTarget","toTarget"],descriptions:[n.fromTarget,n.toTarget],caches:[n.cache?.fromTarget,n.cache?.toTarget],action:(h,f)=>this.browser.dragAndDrop(h,f,{hoverDurationMs:n.hoverSeconds?n.hoverSeconds*1e3:void 0,steps:n.steps}),options:{useSelector:!!n.useSelector,disableCache:i}});return{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:m[0],thoughts:g}}case"MOUSE_DRAG":{let m=parseInt(n.deltaX),g=parseInt(n.deltaY),h=n.steps??5;if(isNaN(m)||isNaN(g))throw new R("ActionFailureError",`Invalid pixel values passed to mouse drag command: (${n.deltaX}, ${n.deltaY})`);if(n.target&&An(n.target)){await this.browser.mouseDragUsingVisualCoordinates({deltaX:m,deltaY:g,steps:h,fromTarget:n.target.pixels});break}let f,y;if(n.target?.elementDescriptor){let{elementInteractedDisplayString:E,thoughts:b}=await this.wrapElementTargetingCommand({ctx:e,tracer:t,command:n,target:n.target,cache:n.cache?.target,action:async _=>this.browser.mouseDrag(m,g,h,_.locator,{force:n.force}),options:{disableCache:i,targetName:"target",...n}});f=E,y=b}else await this.browser.mouseDrag(m,g,h,void 0,{force:n.force});return{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:f,thoughts:y}}case"SELECT_OPTION":{if(!vo(n.target))throw new Error("Select with x/y is not supported yet");let m=n.target.elementDescriptor,g=n.choice,{elementInteractedDisplayString:h,thoughts:f}=await this.wrapElementTargetingCommand({ctx:e,tracer:t,command:n,target:{type:"description",elementDescriptor:m},cache:n.cache?.target,action:y=>this.browser.selectOption(y,g,n.force),options:{...n,targetName:"target",disableCache:i,source:Ol(n)}});return{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:h,thoughts:f}}case"TAB":{let m={loadTimeoutMs:n.loadTimeout?n.loadTimeout*1e3:void 0,retry:!0};await this.browser.switchToPage(n.action,m);break}case"NEW_TAB":await this.browser.createNewTab(n.url,{loadTimeoutMs:n.loadTimeout?n.loadTimeout*1e3:void 0});break;case"COOKIE":if(!n.value)break;let l=await this.browser.setCookie(n.value);a.debug({results:l},"Set cookies");break;case"LOCAL_STORAGE":if(!n.value||!n.key)break;await this.browser.setLocalStorage(n.key,n.value);break;case"JAVASCRIPT":{let m;try{n.environment==="BROWSER"?(m=await this.browser.evaluateCodeInPage({code:n.code,fragment:n.fragment??!1,context:o.toObjectCopy(),timeoutMs:n.timeout?n.timeout*1e3:void 0}),a.info({result:m},"Executed JavaScript in browser")):m=await Un({orgId:this.orgId,code:n.code,fragment:!!n.fragment,context:o,timeoutMs:n.timeout?n.timeout*1e3:void 0,logger:a,localTools:this.localCodeEvalTools,signal:this.executeAbortController.signal,callbacks:{onPersistentVariableUpdates:async g=>{if(!this.options?.scratchPadId){a.warn({updates:g},"Got persistent variable updates but scratch pad is not available");return}await this.storage.savePersistentVariables?.({scratchPadId:this.options?.scratchPadId,orgId:this.orgId,updates:g,logger:a})}}})}catch(g){throw this.throwIfClosed(),new R("ActionFailureError",g instanceof Error?g.message:`${g}`,{errOptions:{cause:g}})}try{JSON.stringify(m)}catch(g){throw new R("ActionFailureError",`Return value is not serializable: ${g instanceof Error?g.message:`${g}`}`,{errOptions:{cause:g}})}return{urlAfterCommand:this.browser.url(),succeedImmediately:!1,data:m}}case"TYPE":{if(n.target&&An(n.target)){await this.browser.clickUsingVisualCoordinates(n.target.pixels,n),await this.browser.type(n.value,{force:n.force,clearContent:n.clearContent,forceClearContent:n.forceClearContent,delay:n.delay,pressEnter:n.pressEnter},!0);break}let m=this.browser.url(),g,h,f=EO(n.target),y=this.browser.userBrowserSettings.globalLocatorRedirect===void 0||this.browser.userBrowserSettings.globalLocatorRedirect==="always";if(f){let{elementInteractedDisplayString:b,thoughts:_}=await this.wrapElementTargetingCommand({ctx:e,tracer:t,command:n,target:f,cache:n.cache?.target,action:M=>this.browser.typeIntoTarget(n.value,M,{force:n.force,clearContent:n.clearContent,forceClearContent:n.forceClearContent,delay:n.delay,pressEnter:n.pressEnter,relativePosition:n.relativePosition}),options:{...n,targetName:"target",disableCache:i,disableGlobalLocatorRedirect:!y,source:Ol(n)}});g=b,h=_}else await this.browser.type(n.value,{force:n.force,clearContent:n.clearContent,forceClearContent:n.forceClearContent,delay:n.delay,pressEnter:n.pressEnter},!0);let E={urlAfterCommand:this.browser.url(),succeedImmediately:!1,elementInteracted:g,thoughts:h};return Wm(m,E.urlAfterCommand)&&(E.succeedImmediately=!0,E.succeedImmediatelyReason="URL changed"),E}case"HOVER":{if(An(n.target)){await this.browser.hoverUsingVisualCoordinates(n.target.pixels);break}let{elementInteractedDisplayString:m,thoughts:g}=await this.wrapElementTargetingCommand({ctx:e,tracer:t,command:n,target:n.target,cache:n.cache?.target,action:h=>this.browser.hover(h),options:{...n,targetName:"target",disableCache:i}});return{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:m,thoughts:g}}case"FOCUS":{if(!vo(n.target))throw new Error("Focus with x/y is not supported yet");let{elementInteractedDisplayString:m,thoughts:g}=await this.wrapElementTargetingCommand({ctx:e,tracer:t,command:n,target:n.target,cache:n.cache?.target,action:h=>this.browser.focus(h),options:{...n,targetName:"target",disableCache:i}});return{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:m,thoughts:g}}case"BLUR":{if(n.target&&!vo(n.target))throw new Error("Blur with x/y is not supported yet");if(!n.target||!n.target.elementDescriptor)return await this.browser.blur(null),{succeedImmediately:!1,urlAfterCommand:this.browser.url()};let{elementInteractedDisplayString:m,thoughts:g}=await this.wrapElementTargetingCommand({ctx:e,tracer:t,target:n.target,command:n,cache:n.cache?.target,action:h=>this.browser.blur(h),options:{...n,targetName:"target",disableCache:i}});return{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:m,thoughts:g}}case"PRESS":let u=this.browser.url();await this.browser.press(n.value,{repeat:n.repeat,convertMeta:n.convertMeta??!0,delayMs:n.delayMs});let d={urlAfterCommand:this.browser.url(),succeedImmediately:!1};return Wm(u,d.urlAfterCommand)&&(d.succeedImmediately=!0,d.succeedImmediatelyReason="URL changed"),d;case"KEY_DOWN":return await this.browser.keyDown(n.value,{convertMeta:n.convertMeta??!0}),{urlAfterCommand:this.browser.url(),succeedImmediately:!1};case"KEY_UP":return await this.browser.keyUp(n.value,{convertMeta:n.convertMeta??!0}),{urlAfterCommand:this.browser.url(),succeedImmediately:!1};case"REQUEST":{let m=new fK,g=hK(fetch,m),h;try{h=new URL(n.url).hostname}catch{}let f=await cp({command:n,baseUrl:this.browser.baseUrl,logger:a,fetchImplementation:g});return{data:bl.parse({...f,cookies:md(m,h)}),succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"GRAPHQL_REQUEST":return{data:await bO({command:n,baseUrl:this.browser.baseUrl,logger:a}),succeedImmediately:!1,urlAfterCommand:this.browser.url()};case"VISUAL_DIFF":return fO({ctx:e,tracer:t,command:n,disableCache:i,browser:this.browser,logger:a,screenshotStorage:this.visualDiffScreenshotStorage,targetingWrapper:m=>this.wrapElementTargetingCommand(m)});case"FILE_UPLOAD":{let m,g;if(n.fileSource.type==="URL"?(g=n.fileSource.url,m=await IP({uri:n.fileSource.url,logger:a,orgId:this.orgId})):n.fileSource.type==="USER_FILE"&&(g=n.fileSource.name,m=await this.uploadedFileStorage?.getFileForUpload(n.fileSource.name,this.orgId)),!m)throw new R("UserConfigurationError",`Attempted to use non-existent file for upload step: ${g}`);await this.browser.setFileChooserHandler({...m,filename:n.filename});break}case"AUTH_SAVE":return{data:await this.browser.saveAuthState(),succeedImmediately:!1,urlAfterCommand:this.browser.url()};case"AUTH_LOAD":{let m;if(!n.storageState.trim())m=void 0;else if(m=await Un({orgId:this.orgId,code:n.storageState,fragment:!1,context:o,logger:a,localTools:this.localCodeEvalTools,signal:this.executeAbortController.signal}),typeof m!="object")throw new R("ActionFailureError",`Credentials must evaluate to an object (received ${typeof m} instead)`);let g;try{g=cA.optional().parse(m)}catch(h){throw new R("ActionFailureError",`Credentials provided do not follow the required format: ${h}`)}await this.browser.loadAuthState(g);break}case"ELEMENT_CHECK":{let m=(n.timeout??dr)*1e3,g=this.generator.getAgentConfig()?.assertion;if(gO(n.assertion)&&!n.useSelector&&n.target.type==="description"&&g&&g!=="v1"){let f={id:n.id,type:"AI_ASSERTION",assertion:`There is no element on the page closely matches the following description. If the description has single quotes, remember that requires an exact text substring match. Description: ${n.target.elementDescriptor}`,iframeUrl:n.iframeUrl,timeout:n.timeout,source:"NEGATED_CHECK",cache:n.cache&&"memory"in n.cache?{memory:n.cache?.memory}:void 0};try{let y=await sp({command:f,logger:a,aiPageFiltering:!!this.options?.aiPageFiltering,fixtures:this.getControllerFixtures(e),useMemory:this.shouldUseMemory()});return{succeedImmediately:!1,thoughts:`The element described does not exist on the page: ${y.thoughts}`,urlAfterCommand:this.browser.url(),afterScreenshotOverride:y.afterScreenshotOverride}}finally{f.cache?.memory&&Jc(n,f.cache?.memory.traces,a)}}let h=await pO({command:n,tracer:t,timeoutMs:m,targetingWrapper:f=>this.wrapElementTargetingCommand(f),fixtures:this.getControllerFixtures(e),disableCache:i});return{fail:!h.success,data:h.data,elementInteracted:h.elementInteractedDisplayString,thoughts:h.err?.message??h.thoughts??`Element assertion ${h.success?"succeeded":"failed"}.`,succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"PAGE_CHECK":{let m=await an({action:async()=>yO({assertion:n.assertion,browser:this.browser,logger:a,timeout:n.timeout,signal:this.executeAbortController.signal,autoExpandIframes:!!this.browser.userBrowserSettings.autoExpandIframes}),frameConfig:n.iframeUrl?{type:"url",url:n.iframeUrl}:void 0,browser:this.browser,logger:a});return{fail:!m.success,data:m.data,thoughts:m.success?"Page assertion passed.":m.err?.message??`Page assertion still failing after ${n.timeout} seconds.`,urlAfterCommand:this.browser.url(),succeedImmediately:!1}}case"REGISTER_REQUEST_LISTENER":{let m=new ei(n.requestMatcher),g=this.browser.registerRequestListener(m);return this.registeredListeners[n.key]=g.then(async h=>await py(h)).catch(h=>{a.error({err:h},"Failed to get request listener response")}),{succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"AWAIT_LISTENER":{let m=this.registeredListeners[n.key];if(!m)throw new R("ActionFailureError",`No listener registered with key: ${n.key}`);let g=n.timeout??10;return{data:await Y(m,{milliseconds:g*1e3,message:`Request listener timed out after ${g} seconds`}),succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"RECORD_REQUESTS":{let m=new ei(n.requestMatcher);return this.recordedRequests[n.key]={},this.browser.registerRequestRecorder(n.key,{matches:g=>m.matches({url:g.request.url,method:g.request.method}),onRequestStart:(g,h)=>{this.recordedRequests[n.key][g]=Ym(h)},onRequestComplete:(g,h)=>{this.recordedRequests[n.key]?.[g]&&(this.recordedRequests[n.key][g]=Ym(h))}}),{succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"GET_RECORDED_REQUESTS":{let m=this.recordedRequests[n.key];if(!m)throw new R("ActionFailureError",`No recorder registered with key: ${n.key}`);return delete this.recordedRequests[n.key],{data:Object.values(m),succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"SET_HEADER":{let m;return n.requestMatcher&&(m=new ei(n.requestMatcher)),this.browser.setHeader(n.name,n.value,m),{succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"MOCK_ROUTE":return{data:{key:this.browser.registerMock(n.key,new ei(n.requestMatcher),async(g,h)=>{let f=await Un({orgId:this.orgId,code:n.responseGenerator,fragment:!1,context:o,timeoutMs:void 0,logger:a,localTools:this.localCodeEvalTools,mock:{request:g,response:h},disallowVariableUpdates:!0,responseSerialization:"RESPONSE"}),y=NA.parse(f);return new Response(y.body,{status:y.status,headers:y.headers})},n.fetchOriginalResponse??!1)},succeedImmediately:!1,urlAfterCommand:this.browser.url()};case"REMOVE_ROUTE_MOCK":return this.browser.removeMock(n.key),{succeedImmediately:!1,urlAfterCommand:this.browser.url()};case"OFFLINE_MODE":return await this.browser.setOfflineMode(n.enable),{succeedImmediately:!1,urlAfterCommand:this.browser.url()};default:return(m=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(n)}return{succeedImmediately:!1,urlAfterCommand:this.browser.url()}}async getReverseMappedDescription({browserState:e,targetId:t,disableCache:n,screenshot:o}){return(await this.generator.getReverseMappedDescription({browserState:e,target:t,screenshot:o},{disableCache:n,abortSignal:this.executeAbortController.signal,loggerTags:ye(this.logger)})).phrase}async stopRecordMode(){this.recordAbortController?.abort(),await this.browser.clearAllCdpHighlights()}async startRecordMode({params:e,abortController:t,isClickToRecord:n}){this.recordAbortController=t;let o=new tp({signal:t.signal,...e});return await this.browser.startRecording(this.recordAbortController.signal,o,n),o}async runSectionAutohealing(e){return this.generator.getAutohealingProposal(e,{disableCache:!0,abortSignal:this.executeAbortController.signal,loggerTags:ye(this.logger)})}async getFailureRecoveryPlan(e){return this.generator.getFailureRecoveryPlan(e,{disableCache:!0,abortSignal:this.executeAbortController.signal,loggerTags:ye(this.logger)})}};import{mkdirSync as BK}from"fs";import{tmpdir as zK}from"os";import PO from"path";import{diff as UK}from"deep-object-diff";import{cloneDeep as Hy}from"lodash-es";import wO from"fontoxpath";import SK from"@prettier/plugin-xml";import yK from"prettier";import{DOMParser as bK,XMLSerializer as EK}from"slimdom";var TK=new Set(["android.webkit.webview","com.facebook.react.views.webview.reactwebview","com.tencent.smtt.sdk.webview","com.tencent.smtt.sdk.x5webview","org.xwalk.core.xwalkview","com.uc.webview.export.webview"]);function vK(r){let e=r.toLowerCase();return e.endsWith("webview")||TK.has(e)}function lu(r){return!!(vK(r.tagName)||r.getAttribute("package")==="com.android.chrome"&&r.getAttribute("content-desc")==="Web View"&&TO(r.tagName.toLowerCase()).startsWith("frame"))}function TO(r){let e=["android.widget.","android.view.","android.webkit.","android.app.","android.support.","androidx.","com.android.inputmethod."];for(let t of e)if(r.startsWith(t))return r.substring(t.length);return r}var AK=new Set(["index","package","a11y-important","screen-reader-focusabl"]),RK=new Set(["selected","checked","checkable","clickable","enabled","focusable","focused","long-clickable","password","scrollable","selected","showing-hint","context-clickable","multiline","text-entry-key","heading","dismissable","screen-reader-focusable","content-invalid","a11y-focused"]),wK=new Set(["text","hint"]),CK=new Set(["live-region","drawing-order"]),xK=new Set(["displayed","enabled"]);function _K(r,e){let t={};for(let[n,o]of Object.entries(e))AK.has(n)||n==="class"&&r===o||n==="focusable"&&o==="true"&&e.clickable==="true"||RK.has(n)&&o==="false"||wK.has(n)&&o===""||xK.has(n)&&o==="true"||CK.has(n)&&o==="0"||n!=="id"&&(t[n]=o);return t}function vO(r,e,t){let{prunedDocument:n,idToElement:o,prunedIdToElement:i,idCounter:a,opts:s}=r,c=a.value++;t.setAttribute("id",String(c));let l={};for(let p of e.attributes){let m=p.name,g=p.value;g!=null&&(l[m]=String(g))}let u=_K(e.tagName,l);for(let[p,m]of Object.entries(u))t.setAttribute(p,m);if(o.set(c,e),i.set(c,t),lu(e)){let p=s?.injectedWebviewContent??"";if(s?.removeWebviewContent){for(;t.firstChild;)t.removeChild(t.firstChild);return}else if(!s?.disableMomenticAccessibilityTree&&p.trim().length>0){for(;t.firstChild;)t.removeChild(t.firstChild);p.trim().length>0&&t.appendChild(n.createCDATASection(`
|
|
4584
4584
|
${p}
|
|
4585
|
-
`));return}}let d=Array.from(e.childNodes??[]);for(let p of d){let m=p.nodeType;if(m===3){let g=p.nodeValue;g&&g.trim().length>0&&t.appendChild(n.createTextNode(g));continue}if(m===1){let g=p;if(!IK(g,s?.viewportBounds))continue;let h=n.createElement(TO(g.tagName));vO(r,g,h),t.appendChild(h)}}}function MK(r,e,t,n){let o=r.parseFromString("<hierarchy/>","text/xml"),i=new Map,a={prunedDocument:o,idToElement:t,prunedIdToElement:i,idCounter:{value:0},opts:n},s=o.documentElement;vO(a,e,s);let c=new EK().serializeToString(o);return{prunedDocument:o,prunedIdToElement:i,xml:c}}async function AO(r,e){let t=new bK,n=t.parseFromString(r,"text/xml"),o=new Map,i=n.documentElement;if(!i)throw new R("InternalWebAgentError","No root element found in XML");if(i.tagName!=="hierarchy")throw new R("InternalWebAgentError","No hierarchy element found in XML");let{prunedDocument:a,prunedIdToElement:s,xml:c}=MK(t,i,o,e);return{xml:await yK.format(c,{parser:"xml",plugins:[SK],printWidth:120,tabWidth:1,singleAttributePerLine:!1}),originalXml:r,document:n,idToElement:o,prunedDocument:a,prunedIdToElement:s}}function PK(r){let e=[],t=r;for(;t;){let n=t.tagName,o=t.parentElement,i=1;if(o){let a=Array.from(o.children).filter(s=>s.tagName===n);for(let s=0;s<a.length;s++)if(a[s]===t){i=s+1;break}}e.unshift(`${n}[${i}]`),t=o}return`/${e.join("/")}`}function mp(r,e){let t=r.idToElement.get(e);if(t)return PK(t)}function zy(r,e){let t=r.idToElement.get(e);if(!t)return;let n=t.cloneNode(!0);for(let o of Array.from(n.children)){let i=o;for(let a of Array.from(i.children))i.removeChild(a)}return n.outerHTML}function ca(r){if(!r.hasAttribute("bounds"))return;let e=r.getAttribute("bounds");if(!e)return;let t=e.match(/\[(\d+),(\d+)\]\[(\d+),(\d+)\]/);if(t){let n=parseInt(t[1],10),o=parseInt(t[2],10),i=parseInt(t[3],10),a=parseInt(t[4],10);if(Number.isFinite(n)&&Number.isFinite(o)&&Number.isFinite(i)&&Number.isFinite(a))return[n,o,i,a]}}function IK(r,e){if(!e)return!0;let t=ca(r);if(!t||t.length<4)return!0;let n=t[0],o=t[1],i=t[2],a=t[3];return!(i<=e.left||n>=e.right||a<=e.top||o>=e.bottom)}function RO(r,e){if(r&&!(!e||e.length===0))return Object.fromEntries(e.map(t=>[t,r.getAttribute(t)]).filter(([,t])=>t!==null))}function CO({requirements:r,element:e}){let t;if((r?.positionSpecificity||r?.shapeSpecificity)&&(t=ca(e),!t))throw new R("ActionFailureError","Element to cache has no bounds or unexpected bounds format");return{requiredText:r?.textRequired?e.getAttribute("text")??void 0:void 0,requiredAttributes:RO(e,r?.attributesRequired),requiredBounds:r?.boundsRequired,position:r?.positionSpecificity?{x1:t[0],y1:t[1],x2:t[2],y2:t[3],tolerance:r?.positionSpecificity}:void 0,shape:r?.shapeSpecificity?{width:t[2]-t[0],height:t[3]-t[1],tolerance:r?.shapeSpecificity}:void 0}}function _O({aiResponse:r,description:e,emulatorState:t,memory:n,useMemory:o}){let i=t.graph.idToElement.get(r.id);if(!i)throw new R("InternalWebAgentError",`Could not find node with id: ${r.id}`);let a=ca(i);if(!a)throw new R("InternalWebAgentError",`Node ${r.id} has no bounding box: ${i.outerHTML}`);let s=mp(t.graph,r.id)??"",c=zy(t.graph,r.id)??"",l=CO({requirements:r.requirements,element:i}),u=[];r.additionalElements&&(u=r.additionalElements.map(({id:p,requirements:m})=>{let g=t.graph.idToElement.get(p);if(!g)return;let h=mp(t.graph,p);return h?{xPath:h,requirements:CO({requirements:m,element:g})}:void 0}).filter(p=>!!p));let d;if(lu(i)&&r.inWebview!==!1?d={type:"WEBVIEW",resolvedDescription:e,xPath:s}:d={type:"NATIVE",bounds:a,resolvedDescription:e,xPath:s,elementOnlySerializedXml:c,requirements:l,requiredRelatedElements:u},o)if(r.updatedMemory){let p={type:"GCS_TRACES",traces:r.updatedMemory};d.memory=p}else n&&(d.memory=n);return{target:d,resolvedNode:i}}function MO(r){return r?.type==="WEBVIEW"?r.browserCache?.memory:void 0}var OK=.1,LK=.25;function pp(r,e,t,n){let o=Math.abs(e-t);switch(r){case"precise":return o<=n;case"narrow":return o<=Math.abs(e)*OK;case"broad":return o<=Math.abs(e)*LK;case"irrelevant":return!0}}function NK(r,e){let t=e.x2-e.x1,n=(e.x1+e.x2)/2,o=(r[0]+r[2])/2;if(!pp(e.tolerance,n,o,Math.min(1,t)))return!1;let i=e.y2-e.y1,a=(e.y1+e.y2)/2,s=(r[1]+r[3])/2;return pp(e.tolerance,a,s,Math.min(1,i))}function DK(r,e){return pp(e.tolerance,e.width,r[2]-r[0],Math.min(1,e.width))?pp(e.tolerance,e.height,r[3]-r[1],Math.min(1,e.height)):!1}var xO=(r,e,t)=>{if(!e)return;let{requiredAttributes:n,requiredText:o,requiredBounds:i,position:a,shape:s}=e;if(o!==void 0&&o.length>0){let c=Yc(r);if(c!==o)throw new gt(`Resolved element text mismatch: expected ${o}, got ${c}`)}if(n)for(let[c,l]of Object.entries(n)){let u=r.getAttribute(c)??void 0;if(u!==l)throw new gt(`Attribute ${c} mismatch: expected ${l}, got ${u}`)}if(i&&t&&!t.targetBounds.every((l,u)=>l===t.newElementBounds[u]))throw new gt(`Bounds changed from [${t.targetBounds.join(",")} ] to [${t.newElementBounds.join(",")} ]`);if(a&&t&&!NK(t.newElementBounds,a))throw new gt(`Position mismatch: expected ${JSON.stringify(a)}, got ${JSON.stringify(t.newElementBounds)}`);if(s&&t&&!DK(t.newElementBounds,s))throw new gt(`Shape mismatch: expected ${JSON.stringify(s)}, got ${JSON.stringify(t.newElementBounds)}`)};async function gp(r){let{target:e,domState:t}=r,{graph:n}=t,{document:o}=n,i=se();if(e.type==="WEBVIEW")return kK(e,r);if(!e.xPath)throw new R("ActionFailureError","Native element cache has no XPath");let a=wO.evaluateXPathToFirstNode(e.xPath,o,null,null);if(!a)throw new gt(`Could not resolve cached target via XPath: ${e.xPath}`);if(e.requiredRelatedElements){let p=e.requiredRelatedElements;i.startSection("Validate related elements are similar enough to past runs",()=>{for(let m of p){let g=wO.evaluateXPathToFirstNode(m.xPath,o);if(!g)throw new gt(`Required related element not found for XPath: ${m.xPath}`);xO(g,m.requirements)}})}let s=ca(a);if(!s)throw new gt("Resolved native element has no bounding box");if(!e.bounds)throw new gt("Native element cache has no bounds");xO(a,e.requirements,{targetBounds:e.bounds,newElementBounds:s});let c;for(let[p,m]of n.idToElement.entries())if(m===a){c=p;break}let l=e.elementOnlySerializedXml,u=e.xPath;return c!==void 0&&(l=zy(n,c)??l,u=mp(n,c)??u),{resolvedTarget:{...e,resolvedNode:a,bounds:s,elementOnlySerializedXml:l,xPath:u}}}async function kK(r,e){let{stateManager:t,logger:n,signal:o}=e,i=se(),a=await t.getActiveWebview();if(!a||!a.browserController)throw n.error({webview:a?{...a,browserController:!!a.browserController}:void 0},"resolveTargetCacheInWebView: No browser controller attached"),new gt("No browser controller is attached to the requested webview");let s=a.browserController;if(!r.browserCache)throw n.error({target:r},"resolveTargetCacheInWebView: No browser target available on cache"),new gt("No browser target available on cache");let c=r.browserCache,{finalTarget:l}=await i.startAsyncSection("Resolve target in webview",()=>s.resolveCachedTargetForAction({ctx:null,cache:c,options:{disableGlobalLocatorRedirect:e.disableTargetRedirection,resolveTargetOptions:{logger:n,signal:o,skipWaitForPageLoad:!0,skipSavingVisualAttributes:!0}},logger:n}));return{resolvedTarget:{...r,controller:a.browserController,browserTarget:l}}}function ua(r){let{command:e,cacheKey:t="cache",targetName:n="target",updatedCache:o}=r;zi(e)&&(e[t]={...e[t],[n]:Va.parse(o)},r.updatedWithAI&&(e[t].updatedAt=new Date,e[t].updatedAtLoggerTags=ye(r.logger)))}function hp(r){if(r.type==="WEBVIEW")return{type:"WEBVIEW",resolvedDescription:r.resolvedDescription,xPath:r.xPath,browserCache:r.browserCache,memory:r.memory};let{resolvedNode:e,...t}=r;return{...t}}var Rt=class{driver;generator;stateManager;logger;fixtures;aborter;orgId;aiSettings;options;constructor(e){this.stateManager=e.stateManager,this.generator=e.generator,this.driver=e.driver,this.logger=e.logger,this.fixtures=e.fixtures,this.aborter=e.aborter,this.orgId=e.orgId,this.aiSettings=e.aiSettings,this.options=e.options}shouldUseMemoryForCommand(e){return this.aiSettings?.useMemory&&!e?.disableCache}async findElement({description:e,tracer:t,skipFetchingFullWebviewContent:n=!1,removeWebviewContent:o=!1,useMemory:i=!1,memory:a,webviewMemory:s,metadata:c}){let l=this.logger.child({...c}),u=await t.startAsyncSection("Get emulator state",async()=>{let f=await this.stateManager.getDomState({skipFetchingFullWebviewContent:n,removeWebviewContent:o}),y=await this.stateManager.getCurrentScreenshotPngString();return{emulatorState:f,screenshot:y}}),d;try{d=await t.startAsyncSpan("AI_LOCATOR_CALL",async f=>{let y=await this.generator.getAndroidElementLocation({description:e,screenXml:u.emulatorState.graph.xml,screenshot:u.screenshot,memory:i?a:void 0},{logger:l,loggerTags:ye(l),abortSignal:this.aborter.controller?.signal,useMemory:i,agentConfigVersion:this.aiSettings.agentConfig?.["android-locator"]});return f.result=y,y})}catch(f){throw this.throwIfAborted(),l.error({err:f},"Failed to locate element"),new R("InternalWebAgentError",`Failed to locate element: ${f instanceof Error?f.message:f}`,{errOptions:{cause:f}})}if(d.id===-1){let f=d.updatedMemory?{type:"GCS_TRACES",traces:d.updatedMemory}:void 0;return{success:!1,thoughts:d.thoughts??"No matching element found",updatedLocatorMemory:f}}let{target:p,resolvedNode:m}=_O({aiResponse:d,description:e,emulatorState:u.emulatorState,memory:a,useMemory:i});if(p.type==="NATIVE")return t.addSpan({type:"TARGET_RESOLUTION",startTime:Date.now(),endTime:Date.now(),result:{serializedElement:p.elementOnlySerializedXml??"Unknown element"},attributes:{},subSpans:[]}),{success:!0,resolvedTarget:{...p,resolvedNode:m},thoughts:d.thoughts};let{browserLocateResult:g,browserController:h}=await t.startWebviewTrace(async()=>{let f=await this.stateManager.getActiveWebview();if(!f||!f.browserController)throw new R("InternalWebAgentError","No browser controller is attached to the requested webview");return{browserLocateResult:await f.browserController.locateElement({description:e,disableCache:!1,useMemory:i,memory:i?s:void 0,logger:this.logger,skipWait:!0,skipSavingVisualAttributes:!0}),browserController:f.browserController}});return t.addSpan({type:"TARGET_RESOLUTION",startTime:Date.now(),endTime:Date.now(),result:{serializedElement:g.target.nodeOnlySerializedHtml??"Unknown HTML element in webview"},attributes:{},subSpans:[]}),{success:!0,resolvedTarget:{...p,controller:h,browserTarget:{...g.resolution,serverSideBoundingBox:await g.resolution.locator.boundingBox({timeout:5e3})},browserCache:g.target},thoughts:g.thoughts}}async targetingActionWithAILocator(e){let{action:t,command:n,description:o,tracer:i,cacheKey:a,targetName:s,cache:c,skipFetchingFullWebviewContent:l,removeWebviewContent:u,metadata:d}=e,p=await this.findElement({description:o,tracer:i,skipFetchingFullWebviewContent:l,removeWebviewContent:u,useMemory:this.shouldUseMemoryForCommand(n),memory:c?.memory,webviewMemory:MO(c),metadata:d});if(!p.success){if(p.updatedLocatorMemory&&c){let h={...c,memory:p.updatedLocatorMemory};ua({command:n,cacheKey:a,targetName:s,updatedCache:h,updatedWithAI:!0,logger:this.logger})}throw new R("NoMatchingElementError",p.thoughts??"No matching element found")}let m=p.thoughts,g=await t(p.resolvedTarget);return ua({command:n,cacheKey:a,targetName:s,updatedCache:p.resolvedTarget,updatedWithAI:!0,logger:this.logger}),{result:g,thoughts:m}}async wrapTargetingAction(e){let{action:t,description:n,command:o,cacheKey:i="cache",targetName:a="target",cacheIsInvalidAfterResolution:s,tracer:c,skipFetchingFullWebviewContent:l=!1,removeWebviewContent:u=!1,disableTargetRedirection:d=!1}=e,p,m={commandId:o.id};if(i==="cache"&&"cache"in o&&o.cache){let b=o.cache;a==="target"&&"target"in b?p=b.target:a==="fromTarget"&&"fromTarget"in b?p=b.fromTarget:a==="toTarget"&&"toTarget"in b&&(p=b.toTarget)}let g=!1,h=Hy(p);if(o.disableCache&&(this.logger.debug({command:o},"Cache explicitly disabled for command"),g=!0,h=void 0),s&&(g=!0,h=void 0),h&&h?.resolvedDescription!==n&&(this.logger.info({description:n,cacheDescription:h?.resolvedDescription},"Cache description mismatch, clearing it automatically"),g=!0,h=void 0),!h)return this.logger.info({description:n,cacheBustedBeforeAction:g},"Prompting AI for a new element location"),this.targetingActionWithAILocator({action:t,command:o,description:n,tracer:c,cacheKey:i,targetName:a,cache:p,skipFetchingFullWebviewContent:l,removeWebviewContent:u,metadata:m});let f=h.type==="NATIVE"?!!h.requirements:!!h.browserCache?.requirements,y=h.type==="NATIVE"?!!h.requiredRelatedElements?.length:!!h.browserCache?.additionalElements?.length,E;try{this.options?.emulator?.waitForStability&&await this.stateManager.waitForPageSourceStability({timeoutMs:3e3,signal:this.aborter.controller?.signal,reason:"Waiting for stability before cache resolution"});let{resolvedTarget:b,updatedCache:_}=await c.startAsyncSpan("CACHE_RESOLUTION",async O=>{let v=Date.now(),C;for(;Date.now()-v<3e3;){E=await this.stateManager.getDomState({skipFetchingFullWebviewContent:h?.type==="NATIVE"});let F;try{F=(await gp({target:h,domState:E,stateManager:this.stateManager,logger:this.logger,disableTargetRedirection:d})).resolvedTarget}catch(D){if(C=D,D instanceof gt){this.logger.warn({err:D},"Failed to resolve target cache, retrying");continue}throw this.logger.error({err:D},"Failed to resolve target cache"),D}let I=hp(F),B=UK(h,I);return B&&Object.keys(B).length>0&&this.logger.info({cacheDiffs:B},"Successfully resolved target with cache"),O.attributes.serializedElement=F.type==="WEBVIEW"?F.browserCache?.nodeOnlySerializedHtml??"Unknown HTML element in webview":F.elementOnlySerializedXml??"Unknown element",{resolvedTarget:F,updatedCache:I}}throw C}),M=await t(b);return ua({command:o,cacheKey:i,targetName:a,updatedCache:_,updatedWithAI:!1,logger:this.logger}),nt.increment("cache_target_resolution_v2",1,["outcome:hit",`platform:mobile-${h.type.toLowerCase()}`,`hasRequirements:${f}`,`hasAdditionalElements:${y}`,`orgId:${this.orgId}`,"cliVersion:0.33.4"]),{result:M,thoughts:"Successfully executed preset action with cache"}}catch(b){if(this.throwIfAborted(),b instanceof R&&b.reason!=="InternalWebAgentError")throw this.logger.error({err:b},"Failed to execute action with target cache (fatal)"),b;return nt.increment("cache_target_resolution_v2",1,["outcome:miss",`platform:mobile-${h.type.toLowerCase()}`,`hasRequirements:${f}`,`hasAdditionalElements:${y}`,`orgId:${this.orgId}`,"cliVersion:0.33.4"]),this.logger.warn({err:b},"Failed to execute action with target cache, retrying with AI"),this.targetingActionWithAILocator({action:t,command:o,description:n,tracer:c,cacheKey:i,targetName:a,cache:h,skipFetchingFullWebviewContent:l,removeWebviewContent:u,metadata:m})}}constructPerformerParams(){return{stateManager:this.stateManager,generator:this.generator,driver:this.driver,logger:this.logger,fixtures:this.fixtures,aborter:this.aborter,orgId:this.orgId,aiSettings:this.aiSettings,options:this.options}}getBoundsFromNativeCache(e){if(!e.bounds)throw new R("ActionFailureError","Native element cache has no bounds");let[t,n,o,i]=e.bounds;if(t===void 0||n===void 0||o===void 0||i===void 0)throw new R("ActionFailureError",`Native element cache has incomplete bounds: [${e.bounds.join(", ")}]`);return{left:t,top:n,width:o-t,height:i-n}}calculateSwipeCoordinates({containerBounds:e,direction:t,desiredDelta:n,edgeMarginPercent:o=.1}){let i=e.left+e.width/2,a=e.top+e.height/2;if(t==="up"||t==="down"){let s=e.height*o,c=e.top+s,l=e.top+e.height-s,u=l-c,d=Math.min(Math.abs(n),u);return{startX:i,startY:t==="down"?l:c,actualDelta:d}}else{let s=e.width*o,c=e.left+s,l=e.left+e.width-s,u=l-c,d=Math.min(Math.abs(n),u);return{startX:t==="right"?l:c,startY:a,actualDelta:d}}}invertDirection(e){if(e==="up")return"down";if(e==="down")return"up";if(e==="left")return"right";if(e==="right")return"left";throw new Error(`Unreachable code: ${e}`)}async performRawSwipe({startX:e,startY:t,deltaPixels:n,direction:o,durationMs:i=300}){let a=Math.abs(n),s=e,c=t;o==="up"||o==="down"?c=o==="up"?t-a:t+a:s=o==="left"?e-a:e+a,await this.driver.performActions([{type:"pointer",id:"finger1",parameters:{pointerType:"touch"},actions:[{type:"pointerMove",duration:0,x:e,y:t},{type:"pointerDown",button:0},{type:"pause",duration:100},{type:"pointerMove",duration:i,x:s,y:c},{type:"pointerUp",button:0}]}]),await this.driver.releaseActions()}throwIfAborted(){this.aborter.controller?.signal.throwIfAborted()}get abortSignal(){return this.aborter.controller?.signal}get aiSettingsCopy(){return Hy(this.aiSettings)}get optionsCopy(){return Hy(this.options)}};function IO(r){return"iterations"in r}function HK(r){let e={relativePosition:r.relativePosition};if(r.iterations!==void 0&&(!Number.isInteger(r.iterations)||r.iterations<1))throw new Error("UserConfigurationError: iterations must be a positive integer");if(r.tapDelayMs!==void 0&&(!Number.isInteger(r.tapDelayMs)||r.tapDelayMs<0))throw new Error("UserConfigurationError: tapDelayMs must be >= 0");if(r.iterations&&r.iterations>1&&r.longPress)throw new Error("UserConfigurationError: Cannot specify both more than one tap iteration and long press at the same time");if(r.tapDelayMs!==void 0&&(!r.iterations||r.iterations<2))throw new Error("UserConfigurationError: tapDelayMs requires iterations >= 2");if(r.longPress){if(r.tapDelayMs!==void 0)throw new Error("UserConfigurationError: tapDelayMs cannot be used with longPress");return{...e,longPress:!0,longPressDurationMs:r.longPressDurationMs}}return r.iterations!==void 0?{...e,iterations:r.iterations,tapDelayMs:r.tapDelayMs}:e}var Hs=class extends Rt{async tapOnNativeCoordinates(e){let t=e.x,n=e.y;if(this.logger.info({x:t,y:n},"Tap at coordinates"),"longPress"in e&&e.longPress)return await this.driver.executeScript("mobile: longClickGesture",[{x:t,y:n,duration:e.longPressDurationMs??2e3}]);if(IO(e)){let o=e.tapDelayMs??100;for(let i=0;i<e.iterations;i++)await this.driver.tap({x:t,y:n}),i<e.iterations-1&&await new Promise(a=>setTimeout(a,o));return}await this.driver.tap({x:t,y:n})}async tapOnNativeTarget(e,t){let[n,o,i,a]=e.bounds,s=i-n,c=a-o,l=t?.relativePosition?.x??s/2,u=t?.relativePosition?.y??c/2;l=Math.max(0,Math.min(l,s)),u=Math.max(0,Math.min(u,c));let d=n+l,p=o+u;return await this.tapOnNativeCoordinates({x:d,y:p,...t}),{x:d,y:p}}async tapOnWebviewTarget(e,t){let{controller:n}=e,o,i=1;return t&&IO(t)?(o=t.tapDelayMs,i=t.iterations):t&&"longPress"in t&&(o=t.longPressDurationMs),(await n.browser.click(e.browserTarget,{createIsolatedFolder:()=>{let s=Math.random().toString(36).substring(4),c=PO.join(zK(),"momentic","downloads"),l=PO.join(c,this.orgId,s);return BK(l,{recursive:!0}),l}},{delayMs:o,relativePosition:t?.relativePosition,iterations:i})).coordinates}async tapOnTarget({target:e,options:t}){return await se().startAsyncSpan("EMULATOR_INTERACTION",async o=>{o.attributes.options=t,"type"in e&&e.type==="NATIVE"?o.attributes.point=await this.tapOnNativeTarget(e,t):(o.withinWebview=!0,o.attributes.point=await this.tapOnWebviewTarget(e,t))},{name:"Tap on target"})}async executeTap({command:e}){let t=se(),n=HK(e);if(e.target.type==="coordinates"){let a=await this.driver.getWindowSize(),s=e.target.xPercent*a.width,c=e.target.yPercent*a.height;return await t.startAsyncSpan("EMULATOR_INTERACTION",async()=>{await this.tapOnNativeCoordinates({...n,x:s,y:c})},{name:`Tap at coordinates ${s}, ${c}`}),{success:!0,message:`Tapped at ${s}, ${c}`}}let o=e.target.description,{thoughts:i}=await this.wrapTargetingAction({command:e,tracer:t,action:a=>this.tapOnTarget({target:a,options:n}),description:o});return{success:!0,message:i}}};var ni=class extends Rt{async doPress({keycode:e,longPress:t}){await se().startAsyncSpan("EMULATOR_INTERACTION",async()=>this.driver.executeScript("mobile: pressKey",[{keycode:e,isLongPress:t}]),{name:"Send key events to emulator"})}};var da=25,fp=class extends Rt{async doType(e){let t=se();if(!e.target){if(e.clearContent)throw new R("UserConfigurationError","Clearing content is only supported when a target is provided to the Type step");return await this.stateManager.waitForPageSourceStability({timeoutMs:2e3,signal:this.aborter.controller?.signal,reason:"Waiting for page to stabilize before typing"}),await this.sendKeys(e),{success:!0,message:"Successfully executed type action"}}if(e.target.type!=="description")throw new R("UserConfigurationError","x/y targets are not supported for the Type step");let{thoughts:n}=await this.wrapTargetingAction({command:e,tracer:t,action:async o=>{"type"in o&&o.type==="NATIVE"?await this.doNativeType(e,o):await this.doWebviewType(e,o)},description:e.target.description});return{success:!0,message:n}}async doWebviewType(e,t){await se().startAsyncSpan("EMULATOR_INTERACTION",async o=>{o.withinWebview=!0;let i={clearContent:e.clearContent,forceClearContent:e.forceClearContent,delay:e.keyPressDelayMs??da};o.attributes.options=i;let{controller:a,browserTarget:s}=t;await a.browser.typeIntoTarget(e.text,s,i)},{name:"Typing within web view"})}async doNativeType(e,t){let n=new Hs(this.constructPerformerParams());e.clearContent?(await n.tapOnNativeTarget(t,{longPress:!0}),await this.clearContent()):await n.tapOnNativeTarget(t),await this.stateManager.waitForPageSourceStability({timeoutMs:2e3,signal:this.aborter.controller?.signal,reason:"Waiting for keyboard to appear before typing"}),await this.sendKeys(e)}async sendKeys(e){let t=se(),n=e.keyPressDelayMs??da;await t.startAsyncSection("Waiting for system keyboard to open",async(o,i)=>{let a=Date.now();for(;Date.now()-a<2e3;){this.throwIfAborted();let s=Date.now();if(await this.driver.isKeyboardShown())return;let c=Date.now()-s;c<500&&await new Promise(l=>setTimeout(l,500-c))}i.attributes.timedOut=!0}),n!==da?await t.startAsyncSpan("EMULATOR_INTERACTION",async()=>{await this.driver.updateSettings({keyInjectionDelay:n}),await this.driver.keys(e.text),await this.driver.updateSettings({keyInjectionDelay:da})},{name:`Typing with a ${n}ms delay`}):await t.startAsyncSpan("EMULATOR_INTERACTION",async()=>{await this.driver.keys(e.text)},{name:`Typing with a ${da}ms delay`})}async clearContent(){let e=se();try{await e.startAsyncSection("Clearing any content from the focused field",()=>this.clearContentHelper())}catch(t){this.logger.warn({err:t},"Failed to find select all button, continuing...")}}async clearContentHelper(){let e=this.driver.$('//android.widget.LinearLayout[@content-desc="Select all" and @clickable="true"]');await e.waitForExist({timeout:750}),await e.click(),await new ni(this.constructPerformerParams()).doPress({keycode:67})}};import Nr from"zod";var OO=.8,oi=.2,GK=Nr.object({navigationBar:Nr.object({visible:Nr.boolean(),x:Nr.number(),y:Nr.number(),width:Nr.number(),height:Nr.number()}),statusBar:Nr.object({visible:Nr.boolean(),x:Nr.number(),y:Nr.number(),width:Nr.number(),height:Nr.number()})}),Gs=class extends Rt{async getHardcodedScrollableElementBounds(e,t){let n;switch(e.type){case"SCREEN":n=this.getInsetBoundsFromViewport(t);break;case"OPEN_APP":try{let o=GK.parse(await this.driver.executeScript("mobile: getSystemBars",[]));n=this.getInsetBoundsFromViewport(t),o.navigationBar.visible&&(n.height=Math.max(1,n.height-o.navigationBar.height)),o.statusBar.visible&&(n.top+=o.statusBar.height,n.height=Math.max(1,n.height-o.statusBar.height))}catch(o){this.logger.warn({err:o},"Failed to get system bars, using hardcoded bounds"),n=this.getInsetBoundsFromViewport(t)}break;case"OPEN_WEBVIEW":{let o=await this.stateManager.getActiveWebviewNodes();if(o.length===0&&(await this.stateManager.refreshWebviewsManually("get active webview nodes"),o=await this.stateManager.getActiveWebviewNodes()),o.length===0)throw new Error("No active webviews found");if(o.length>1){let a=o.map(s=>({id:s.id,ele:s.originalElement.outerHTML,bounds:s.bounds}));throw new Error(`Multiple active webviews found. Momentic currently only supports a single active webview at a time. Discovered nodes: ${JSON.stringify(a)}`)}let i=o[0]?.bounds;if(!i)throw new Error("No bounds found for active webview");n=this.getInsetBoundsFromBounds(i);break}default:{let o=e;throw new Error("If Typescript complains about the line above, you missed a switch case")}}return n}getInsetBoundsFromViewport(e){let t=Math.floor(e.width*oi),n=Math.floor(e.height*oi);return{left:e.x+t,top:e.y+n,width:Math.max(1,e.width-t*2),height:Math.max(1,e.height-n*2)}}getInsetBoundsFromBounds(e){let t=e[0],n=e[1],o=e[2],i=e[3],a=o-t,s=i-n,c=Math.floor(a*oi),l=Math.floor(s*oi);return{left:t+c,top:n+l,width:Math.max(1,a-c*2),height:Math.max(1,s-l*2)}}async executeSwipe(e){let t=se();if(e.scrollableElement.type==="CUSTOM_COORDINATES"){let{startX:o,startY:i,deltaPixels:a}=e.scrollableElement;return await t.startAsyncSpan("EMULATOR_INTERACTION",async s=>{s.attributes.startX=o,s.attributes.startY=i,s.attributes.deltaPixels=a,s.attributes.direction=e.direction,await this.performRawSwipe({startX:o,startY:i,deltaPixels:a,direction:e.direction,durationMs:e.durationMs})},{name:`Swipe ${e.direction} using raw coordinates`}),{success:!0,message:"Successfully executed swipe action"}}if(e.scrollableElement.type!=="CUSTOM"){let o=await this.driver.getWindowRect(),i=await this.getHardcodedScrollableElementBounds(e.scrollableElement,o);return await t.startAsyncSpan("EMULATOR_INTERACTION",async a=>{await this.swipeByAbsoluteCoordinates({span:a,direction:e.direction,percent:e.viewportPercent,durationMs:e.durationMs,containerBounds:i})},{name:`Swipe ${e.direction} in the entire ${e.scrollableElement.type.toLowerCase()}`}),{success:!0,message:"Successfully executed swipe action"}}let{thoughts:n}=await this.wrapTargetingAction({command:e,description:e.scrollableElement.target.description,action:async o=>se().startAsyncSpan("EMULATOR_INTERACTION",async a=>"type"in o&&o.type==="NATIVE"?this.scrollInNativeContainer({span:a,cmd:e,target:o}):(a.withinWebview=!0,this.swipeInWebview({span:a,cmd:e,target:o})),{name:`Swipe ${e.direction} in the specified container`}),tracer:t});return{success:!0,message:n}}async scrollInNativeContainer({span:e,cmd:t,target:n}){if(!n.bounds||n.bounds.length<4)throw new R("ActionFailureError","Native container cache has no bounds");let o=n.bounds,i=o[2]-o[0],a=o[3]-o[1],s=Math.floor(i*oi),c=Math.floor(a*oi);await this.swipeByAbsoluteCoordinates({span:e,direction:t.direction,percent:t.viewportPercent,durationMs:t.durationMs,containerBounds:{left:o[0]+s,top:o[1]+c,width:Math.max(1,i-s*2),height:Math.max(1,a-c*2)}})}async swipeInWebview({span:e,cmd:t,target:n}){let{controller:o,browserTarget:i}=n;if(!o.browser.getViewport())throw new Error("Failed to get viewport size from webview");let s=t.direction==="down"||t.direction==="up",c=await i.locator.boundingBox();if(!c)throw new Error("Failed to get bounds for webview container");let l=Math.floor(c.width*oi),u=Math.floor(c.height*oi),d=Math.max(1,c.width-l*2),p=Math.max(1,c.height-u*2),m={x:c.x+l+d/2,y:c.y+u+p/2},g=(s?p:d)*(t.viewportPercent??OO)*(s?t.direction==="down"?1:-1:t.direction==="right"?1:-1);e.attributes.startPoint=m,e.attributes.scrollPixelAmount=g,await o.browser.mouseDragUsingVisualCoordinates({deltaX:s?0:g,deltaY:s?g:0,steps:10,dragDurationMs:t.durationMs,fromTarget:m})}async swipeByAbsoluteCoordinates({span:e,direction:t,percent:n=OO,durationMs:o=500,containerBounds:i}){e.attributes.containerBounds=i;let a,s;t==="up"||t==="down"?(a=i.height*n,s=Math.floor(a/(o/1e3))):(a=i.width*n,s=Math.floor(a/(o/1e3))),e.attributes.pixelDelta=a,e.attributes.pixelsPerSecond=s,await this.driver.executeScript("mobile: swipeGesture",[{...i,direction:t,percent:n,speed:s}])}};var LO=5,NO=.8,WK=1,Sp=class extends Gs{async executeScrollTo(e){let t=e.target.description,n=e.scrollStepPercent??NO,o=await this.tryUseCachedScrollPosition(e,t);return o||this.searchForElement(e,t,n)}async resolveContainer({scrollableElement:e,containerCache:t,aiMetadata:n}){let o=await this.driver.getWindowRect();if(e.type==="CUSTOM_COORDINATES")return{bounds:{left:0,top:0,width:o.width,height:o.height}};if(e.type!=="CUSTOM")return{bounds:await this.getHardcodedScrollableElementBounds(e,o)};let i=se(),a=e.target.description;if(t){let u=this.getBoundsFromNativeCache(t);return this.logger.info({bounds:u},"Got container bounds from native cache"),{bounds:u,cache:t}}let s=await this.findElement({description:a,tracer:i,metadata:n});if(!s.success)throw new R("NoMatchingElementError",s.thoughts??"No matching element found");let{resolvedTarget:c}=s;if(c.type!=="NATIVE")throw new Error(`ActionFailureError: Custom scroll container "${a}" resolved to a webview element. Custom containers must be native elements.`);let l=this.getBoundsFromNativeCache(c);return this.logger.info({bounds:l},"Got container bounds from AI"),{bounds:l,cache:c}}async tryUseCachedScrollPosition(e,t){let n=e.cache?.target;return n?n.type==="WEBVIEW"?this.tryUseWebviewCache(e,t):n.scrollDetails?this.tryUseNativeScrollCache(e,t,n):null:null}async tryUseWebviewCache(e,t){let n=se();try{let{thoughts:o}=await this.wrapTargetingAction({command:e,tracer:n,description:t,action:async i=>{if(i.type==="NATIVE")throw new Error("Expected WEBVIEW target but got NATIVE");await this.scrollWebviewTargetIntoView(i)}});return{success:!0,message:o}}catch(o){return this.logger.warn({err:o},"Failed to use webview cache, falling back to search"),null}}async tryUseNativeScrollCache(e,t,n){let o=n.scrollDetails,i=se(),a=e.scrollStepPercent??NO,s=o.scrollableElement.type==="CUSTOM"?o.scrollableElement.cache:void 0;await this.scrollByPixelDelta({pixelDelta:o.pixelDelta,scrollableElement:o.scrollableElement,containerCache:s,direction:o.direction,scrollStepPercent:a,aiMetadata:{commandId:e.id}});try{let l=await this.tryFindElement({cmd:e,description:t,tracer:i,scrollDetails:o,useAIIfCacheFails:!1});if(l)return l;this.logger.info("Element not found at cached position, undoing scroll")}catch(l){this.logger.warn({err:l},"Error finding element at cached position, will undo scroll")}let c=o.direction==="down"?"up":"down";return this.logger.info({pixelDelta:o.pixelDelta,originalDirection:o.direction,undoDirection:c,scrollableElementType:o.scrollableElement.type},"Undoing scroll"),await this.scrollByPixelDelta({pixelDelta:o.pixelDelta,scrollableElement:o.scrollableElement,containerCache:s,direction:c,scrollStepPercent:a,aiMetadata:{commandId:e.id}}),null}async tryFindElement({cmd:e,description:t,tracer:n,scrollDetails:o,useAIIfCacheFails:i=!0}){let a,s,c=e.cache?.target;if(c&&c.resolvedDescription===t&&!e.disableCache){let u=await this.stateManager.getDomState({skipFetchingFullWebviewContent:!0,removeWebviewContent:!0});try{let{resolvedTarget:d}=await gp({target:c,domState:u,stateManager:this.stateManager,logger:this.logger});a=d,s="Successfully resolved scroll to target with cache.",this.logger.info("Successfully resolved scroll to target from cache")}catch(d){this.logger.warn({err:d},"Failed to resolve target from cache")}}if(!a&&!i)return null;if(!a)try{let u=await this.findElement({description:t,tracer:n,metadata:{commandId:e.id}});if(!u.success)return null;a=u.resolvedTarget,s=u.thoughts}catch(u){if(u instanceof R&&u.reason==="NoMatchingElementError")return null;throw this.logger.warn({err:u},"Failed to find scroll-to target with AI"),u}return a.type==="WEBVIEW"?(await this.scrollWebviewTargetIntoView(a),ua({command:e,updatedCache:hp(a),updatedWithAI:!0,logger:this.logger}),{success:!0,message:s}):(ua({command:e,updatedCache:{...a,scrollDetails:o},updatedWithAI:!0,logger:this.logger}),{success:!0,message:s})}async searchForElement(e,t,n){let o=se(),i=await this.resolveContainer({scrollableElement:e.scrollableElement,aiMetadata:{commandId:e.id}});return this.scrollAndSearch(e,t,o,n,i)}async scrollAndSearch(e,t,n,o,i){let a=0,s=i.bounds,c=s.height*o,l=!0;for(let u=0;u<LO;u++){this.throwIfAborted();let d=this.buildScrollDetails(e,a,i.cache),p=await this.tryFindElement({cmd:e,description:t,tracer:n,scrollDetails:d});if(p)return p;if(!l)throw new Error(`ActionFailureError: Could not find element "${t}" after scrolling to the end`);this.logger.debug({attempt:u,cumulativePixelDelta:a},"Element not found, scrolling further");let m=jK(e.scrollableElement);l=await this.scrollByPage({direction:e.direction,containerBounds:s,scrollStepPercent:o,rawCoordinates:m}),a+=e.direction==="down"?c:-c}throw new Error(`ActionFailureError: Could not find element "${t}" after ${LO} scroll attempts`)}buildScrollDetails(e,t,n){return e.scrollableElement.type==="CUSTOM"?{pixelDelta:t,scrollableElement:{type:"CUSTOM",target:e.scrollableElement.target,cache:n},direction:e.direction}:e.scrollableElement.type==="CUSTOM_COORDINATES"?{pixelDelta:t,scrollableElement:e.scrollableElement,direction:e.direction}:{pixelDelta:t,scrollableElement:e.scrollableElement,direction:e.direction}}async scrollWebviewTargetIntoView(e){let{controller:t,browserTarget:n}=e;await t.browser.hover(n)}async scrollByPage({direction:e,containerBounds:t,scrollStepPercent:n,rawCoordinates:o}){return se().startAsyncSpan("EMULATOR_INTERACTION",async a=>(a.attributes.containerBounds=t,a.attributes.direction=e,this.executeScrollGesture({direction:e,containerBounds:t,scrollStepPercent:n,rawCoordinates:o})),{name:`Scroll ${e} by one page`})}async scrollByPixelDelta({pixelDelta:e,scrollableElement:t,containerCache:n,direction:o,scrollStepPercent:i,aiMetadata:a}){if(e===0)return;let s=se(),c,l,u;if(t.type==="CUSTOM_COORDINATES")c=t.startX,l=t.startY,u=t.deltaPixels;else{let m=(await this.resolveContainer({scrollableElement:t,containerCache:n,aiMetadata:a})).bounds,g=m.height*i,h=this.calculateSwipeCoordinates({containerBounds:m,direction:o,desiredDelta:g});c=h.startX,l=h.startY,u=h.actualDelta}let d=Math.ceil(Math.abs(e)/u);this.logger.debug({pixelDelta:e,direction:o,scrollableElementType:t.type,startX:c,startY:l,maxScrollPerStep:u,numScrolls:d},"scrollByPixelDelta calculated parameters"),await s.startAsyncSpan("EMULATOR_INTERACTION",async p=>{p.attributes.pixelDelta=e,p.attributes.numScrolls=d,p.attributes.maxScrollPerStep=u,p.attributes.startX=c,p.attributes.startY=l;let m=0;for(let g=0;g<d;g++){this.throwIfAborted();let h=Math.abs(e)-m,f=Math.min(u,h);await this.performRawSwipe({startX:c,startY:l,deltaPixels:f,direction:this.invertDirection(o)}),m+=f}},{name:`Scroll ${o} by ${e}px`})}async executeScrollGesture({direction:e,containerBounds:t,scrollStepPercent:n,diffThresholdPercent:o=WK,rawCoordinates:i}){let a=await this.stateManager.getRawScreenshotBase64(),s,c,l;if(i)s=i.startX,c=i.startY,l=i.deltaPixels;else{let m=t.height*n,g=this.calculateSwipeCoordinates({containerBounds:t,direction:e,desiredDelta:m});s=g.startX,c=g.startY,l=g.actualDelta}await this.performRawSwipe({startX:s,startY:c,deltaPixels:l,direction:this.invertDirection(e)});let u=await this.stateManager.getRawScreenshotBase64(),d=Ms(a,u),p=d>o;return this.logger.debug({diffPercent:d,diffThresholdPercent:o,canScrollMore:p,direction:e,actualDelta:l,rawCoordinates:i},"Scroll gesture visual diff result"),p}};function jK(r){if(r.type==="CUSTOM_COORDINATES")return r}import{randomUUID as VK}from"crypto";import uu from"fs";import{tmpdir as $K}from"os";import Ws from"path";var yp=class extends Rt{async doInstallApk(e){return await this.installApkFromUri(e.uri),{success:!0,message:"Installed APK."}}async installApkFromUri(e){let t=await this.resolveUriToLocalApk(e);try{await this.stateManager.executeRawADBCommand(`install -r ${Ws.resolve(t.localPath)}`),this.logger.info({uri:e,localPath:t.localPath},"Installed APK on device")}finally{t.cleanup()}}async resolveUriToLocalApk(e){try{let t=new URL(e);if(t.protocol==="file:"){let n=t.href.slice(7),o;if(uu.existsSync(n))o=n;else if(uu.existsSync(Ws.join("/",n)))o=Ws.join("/",n);else throw new R("UserConfigurationError",`APK not found at path: ${n}`);return this.assertFileExists(o),{localPath:o,cleanup:()=>{}}}if(t.protocol==="http:"||t.protocol==="https:"){let n=await this.fetchWithTimeout(t);if(!n.ok)throw new R("UserInfrastructureError",`Failed to download APK from ${e} (status ${n.status})`);let o=await n.arrayBuffer(),i=Buffer.from(o),a=await this.writeBufferToTempFile(i,t.pathname);return{localPath:a,cleanup:()=>{try{uu.unlinkSync(a)}catch(s){this.logger.warn({err:s,path:a},"Failed to remove temporary APK file")}}}}throw new R("UserConfigurationError",`Unsupported URI scheme for APK installation: ${t.protocol}`)}catch(t){if(t instanceof TypeError){let n=Ws.resolve(e);return this.assertFileExists(n),{localPath:n,cleanup:()=>{}}}throw t}}assertFileExists(e){try{uu.accessSync(e)}catch{throw new R("UserConfigurationError",`APK not found at path: ${e}`)}}async fetchWithTimeout(e){let t=AbortSignal.timeout(9e4);return await fetch(e,{signal:t})}async writeBufferToTempFile(e,t){let n=Ws.extname(t)||".apk",o=Ws.join($K(),`momentic-apk-${VK()}${n}`);return uu.writeFileSync(o,e),o}};import{existsSync as qK,readFileSync as KK}from"fs";import YK from"zod";var XK=YK.string().url();async function DO(r){if(XK.safeParse(r).success){let e=new AbortController,t=setTimeout(()=>e.abort(),1e4),n;try{n=await fetch(r,{signal:e.signal})}catch(i){throw new R("UserInfrastructureError",`Fetch failed or timed out for URL: ${r}`,{errOptions:{cause:i}})}finally{clearTimeout(t)}if(!n.ok)throw new R("UserInfrastructureError",`Failed to fetch file from URL: ${r}, status: ${n.status}`);let o=await n.arrayBuffer();return Buffer.from(o).toString("base64")}if(!qK(r))throw new R("UserInfrastructureError",`File does not exist at path: ${r}`);return KK(r).toString("base64")}var bp=class extends Rt{async dragNative(e,t,n){let{left:o,top:i,width:a,height:s}=this.getBoundsFromNativeCache(e),{left:c,top:l,width:u,height:d}=this.getBoundsFromNativeCache(t),p=o+a/2,m=i+s/2,g=c+u/2,h=l+d/2,f=n?.hoverDuration??500,y=n?.dragDuration??1e3;await this.driver.performActions([{type:"pointer",id:"finger1",parameters:{pointerType:"touch"},actions:[{type:"pointerMove",duration:0,x:p,y:m},{type:"pointerDown",button:0},{type:"pause",duration:f},{type:"pointerMove",duration:y,x:g,y:h},{type:"pointerUp",button:0}]}]),await this.driver.releaseActions()}async dragWebview(e,t,n){let{controller:o}=e;if(e.controller!==t.controller)throw new R("UserConfigurationError","Cannot drag and drop between different webviews");let i=n?.dragDuration??1e3,a=n?.hoverDuration??1e3,s;n?.dragDuration&&(s=Math.max(1,Math.floor(i/200))),await o.browser.dragAndDrop(e.browserTarget,t.browserTarget,{hoverDurationMs:a,steps:s,dragDurationMs:i})}async executeDragAndDrop({command:e}){let t=se();if(e.fromTarget.type!=="description"||e.toTarget.type!=="description")throw new R("UserConfigurationError","Drag and drop only supports description targets for now");let n=e.fromTarget.description,{result:o,thoughts:i}=await this.wrapTargetingAction({command:e,tracer:t,description:n,cacheKey:"cache",targetName:"fromTarget",action:async l=>l}),a=e.toTarget.description,{result:s,thoughts:c}=await this.wrapTargetingAction({command:e,tracer:t,description:a,cacheKey:"cache",targetName:"toTarget",action:async l=>l});if(o.type!==s.type)throw new R("UserConfigurationError",`Drag and drop targets must be in the same context (both native or both webview). Found: From=${o.type}, To=${s.type}`);return await t.startAsyncSpan("EMULATOR_INTERACTION",async l=>{o.type==="NATIVE"&&s.type==="NATIVE"?await this.dragNative(o,s,{hoverDuration:e.hoverDuration,dragDuration:e.dragDuration}):o.type==="WEBVIEW"&&s.type==="WEBVIEW"&&(l.withinWebview=!0,await this.dragWebview(o,s,{hoverDuration:e.hoverDuration,dragDuration:e.dragDuration}))},{name:"Drag and drop"}),{success:!0,message:`${i}
|
|
4585
|
+
`));return}}let d=Array.from(e.childNodes??[]);for(let p of d){let m=p.nodeType;if(m===3){let g=p.nodeValue;g&&g.trim().length>0&&t.appendChild(n.createTextNode(g));continue}if(m===1){let g=p;if(!IK(g,s?.viewportBounds))continue;let h=n.createElement(TO(g.tagName));vO(r,g,h),t.appendChild(h)}}}function MK(r,e,t,n){let o=r.parseFromString("<hierarchy/>","text/xml"),i=new Map,a={prunedDocument:o,idToElement:t,prunedIdToElement:i,idCounter:{value:0},opts:n},s=o.documentElement;vO(a,e,s);let c=new EK().serializeToString(o);return{prunedDocument:o,prunedIdToElement:i,xml:c}}async function AO(r,e){let t=new bK,n=t.parseFromString(r,"text/xml"),o=new Map,i=n.documentElement;if(!i)throw new R("InternalWebAgentError","No root element found in XML");if(i.tagName!=="hierarchy")throw new R("InternalWebAgentError","No hierarchy element found in XML");let{prunedDocument:a,prunedIdToElement:s,xml:c}=MK(t,i,o,e);return{xml:await yK.format(c,{parser:"xml",plugins:[SK],printWidth:120,tabWidth:1,singleAttributePerLine:!1}),originalXml:r,document:n,idToElement:o,prunedDocument:a,prunedIdToElement:s}}function PK(r){let e=[],t=r;for(;t;){let n=t.tagName,o=t.parentElement,i=1;if(o){let a=Array.from(o.children).filter(s=>s.tagName===n);for(let s=0;s<a.length;s++)if(a[s]===t){i=s+1;break}}e.unshift(`${n}[${i}]`),t=o}return`/${e.join("/")}`}function mp(r,e){let t=r.idToElement.get(e);if(t)return PK(t)}function zy(r,e){let t=r.idToElement.get(e);if(!t)return;let n=t.cloneNode(!0);for(let o of Array.from(n.children)){let i=o;for(let a of Array.from(i.children))i.removeChild(a)}return n.outerHTML}function ca(r){if(!r.hasAttribute("bounds"))return;let e=r.getAttribute("bounds");if(!e)return;let t=e.match(/\[(\d+),(\d+)\]\[(\d+),(\d+)\]/);if(t){let n=parseInt(t[1],10),o=parseInt(t[2],10),i=parseInt(t[3],10),a=parseInt(t[4],10);if(Number.isFinite(n)&&Number.isFinite(o)&&Number.isFinite(i)&&Number.isFinite(a))return[n,o,i,a]}}function IK(r,e){if(!e)return!0;let t=ca(r);if(!t||t.length<4)return!0;let n=t[0],o=t[1],i=t[2],a=t[3];return!(i<=e.left||n>=e.right||a<=e.top||o>=e.bottom)}function RO(r,e){if(r&&!(!e||e.length===0))return Object.fromEntries(e.map(t=>[t,r.getAttribute(t)]).filter(([,t])=>t!==null))}function CO({requirements:r,element:e}){let t;if((r?.positionSpecificity||r?.shapeSpecificity)&&(t=ca(e),!t))throw new R("ActionFailureError","Element to cache has no bounds or unexpected bounds format");return{requiredText:r?.textRequired?e.getAttribute("text")??void 0:void 0,requiredAttributes:RO(e,r?.attributesRequired),requiredBounds:r?.boundsRequired,position:r?.positionSpecificity?{x1:t[0],y1:t[1],x2:t[2],y2:t[3],tolerance:r?.positionSpecificity}:void 0,shape:r?.shapeSpecificity?{width:t[2]-t[0],height:t[3]-t[1],tolerance:r?.shapeSpecificity}:void 0}}function _O({aiResponse:r,description:e,emulatorState:t,memory:n,useMemory:o}){let i=t.graph.idToElement.get(r.id);if(!i)throw new R("InternalWebAgentError",`Could not find node with id: ${r.id}`);let a=ca(i);if(!a)throw new R("InternalWebAgentError",`Node ${r.id} has no bounding box: ${i.outerHTML}`);let s=mp(t.graph,r.id)??"",c=zy(t.graph,r.id)??"",l=CO({requirements:r.requirements,element:i}),u=[];r.additionalElements&&(u=r.additionalElements.map(({id:p,requirements:m})=>{let g=t.graph.idToElement.get(p);if(!g)return;let h=mp(t.graph,p);return h?{xPath:h,requirements:CO({requirements:m,element:g})}:void 0}).filter(p=>!!p));let d;if(lu(i)&&r.inWebview!==!1?d={type:"WEBVIEW",resolvedDescription:e,xPath:s}:d={type:"NATIVE",bounds:a,resolvedDescription:e,xPath:s,elementOnlySerializedXml:c,requirements:l,requiredRelatedElements:u},o)if(r.updatedMemory){let p={type:"GCS_TRACES",traces:r.updatedMemory};d.memory=p}else n&&(d.memory=n);return{target:d,resolvedNode:i}}function MO(r){return r?.type==="WEBVIEW"?r.browserCache?.memory:void 0}var OK=.1,LK=.25;function pp(r,e,t,n){let o=Math.abs(e-t);switch(r){case"precise":return o<=n;case"narrow":return o<=Math.abs(e)*OK;case"broad":return o<=Math.abs(e)*LK;case"irrelevant":return!0}}function NK(r,e){let t=e.x2-e.x1,n=(e.x1+e.x2)/2,o=(r[0]+r[2])/2;if(!pp(e.tolerance,n,o,Math.min(1,t)))return!1;let i=e.y2-e.y1,a=(e.y1+e.y2)/2,s=(r[1]+r[3])/2;return pp(e.tolerance,a,s,Math.min(1,i))}function DK(r,e){return pp(e.tolerance,e.width,r[2]-r[0],Math.min(1,e.width))?pp(e.tolerance,e.height,r[3]-r[1],Math.min(1,e.height)):!1}var xO=(r,e,t)=>{if(!e)return;let{requiredAttributes:n,requiredText:o,requiredBounds:i,position:a,shape:s}=e;if(o!==void 0&&o.length>0){let c=Yc(r);if(c!==o)throw new gt(`Resolved element text mismatch: expected ${o}, got ${c}`)}if(n)for(let[c,l]of Object.entries(n)){let u=r.getAttribute(c)??void 0;if(u!==l)throw new gt(`Attribute ${c} mismatch: expected ${l}, got ${u}`)}if(i&&t&&!t.targetBounds.every((l,u)=>l===t.newElementBounds[u]))throw new gt(`Bounds changed from [${t.targetBounds.join(",")} ] to [${t.newElementBounds.join(",")} ]`);if(a&&t&&!NK(t.newElementBounds,a))throw new gt(`Position mismatch: expected ${JSON.stringify(a)}, got ${JSON.stringify(t.newElementBounds)}`);if(s&&t&&!DK(t.newElementBounds,s))throw new gt(`Shape mismatch: expected ${JSON.stringify(s)}, got ${JSON.stringify(t.newElementBounds)}`)};async function gp(r){let{target:e,domState:t}=r,{graph:n}=t,{document:o}=n,i=se();if(e.type==="WEBVIEW")return kK(e,r);if(!e.xPath)throw new R("ActionFailureError","Native element cache has no XPath");let a=wO.evaluateXPathToFirstNode(e.xPath,o,null,null);if(!a)throw new gt(`Could not resolve cached target via XPath: ${e.xPath}`);if(e.requiredRelatedElements){let p=e.requiredRelatedElements;i.startSection("Validate related elements are similar enough to past runs",()=>{for(let m of p){let g=wO.evaluateXPathToFirstNode(m.xPath,o);if(!g)throw new gt(`Required related element not found for XPath: ${m.xPath}`);xO(g,m.requirements)}})}let s=ca(a);if(!s)throw new gt("Resolved native element has no bounding box");if(!e.bounds)throw new gt("Native element cache has no bounds");xO(a,e.requirements,{targetBounds:e.bounds,newElementBounds:s});let c;for(let[p,m]of n.idToElement.entries())if(m===a){c=p;break}let l=e.elementOnlySerializedXml,u=e.xPath;return c!==void 0&&(l=zy(n,c)??l,u=mp(n,c)??u),{resolvedTarget:{...e,resolvedNode:a,bounds:s,elementOnlySerializedXml:l,xPath:u}}}async function kK(r,e){let{stateManager:t,logger:n,signal:o}=e,i=se(),a=await t.getActiveWebview();if(!a||!a.browserController)throw n.error({webview:a?{...a,browserController:!!a.browserController}:void 0},"resolveTargetCacheInWebView: No browser controller attached"),new gt("No browser controller is attached to the requested webview");let s=a.browserController;if(!r.browserCache)throw n.error({target:r},"resolveTargetCacheInWebView: No browser target available on cache"),new gt("No browser target available on cache");let c=r.browserCache,{finalTarget:l}=await i.startAsyncSection("Resolve target in webview",()=>s.resolveCachedTargetForAction({ctx:null,cache:c,options:{disableGlobalLocatorRedirect:e.disableTargetRedirection,resolveTargetOptions:{logger:n,signal:o,skipWaitForPageLoad:!0,skipSavingVisualAttributes:!0}},logger:n}));return{resolvedTarget:{...r,controller:a.browserController,browserTarget:l}}}function ua(r){let{command:e,cacheKey:t="cache",targetName:n="target",updatedCache:o}=r;zi(e)&&(e[t]={...e[t],[n]:Va.parse(o)},r.updatedWithAI&&(e[t].updatedAt=new Date,e[t].updatedAtLoggerTags=ye(r.logger)))}function hp(r){if(r.type==="WEBVIEW")return{type:"WEBVIEW",resolvedDescription:r.resolvedDescription,xPath:r.xPath,browserCache:r.browserCache,memory:r.memory};let{resolvedNode:e,...t}=r;return{...t}}var Rt=class{driver;generator;stateManager;logger;fixtures;aborter;orgId;aiSettings;options;constructor(e){this.stateManager=e.stateManager,this.generator=e.generator,this.driver=e.driver,this.logger=e.logger,this.fixtures=e.fixtures,this.aborter=e.aborter,this.orgId=e.orgId,this.aiSettings=e.aiSettings,this.options=e.options}shouldUseMemoryForCommand(e){return this.aiSettings?.useMemory&&!e?.disableCache}async findElement({description:e,tracer:t,skipFetchingFullWebviewContent:n=!1,removeWebviewContent:o=!1,useMemory:i=!1,memory:a,webviewMemory:s,metadata:c}){let l=this.logger.child({...c}),u=await t.startAsyncSection("Get emulator state",async()=>{let f=await this.stateManager.getDomState({skipFetchingFullWebviewContent:n,removeWebviewContent:o}),y=await this.stateManager.getCurrentScreenshotPngString();return{emulatorState:f,screenshot:y}}),d;try{d=await t.startAsyncSpan("AI_LOCATOR_CALL",async f=>{let y=await this.generator.getAndroidElementLocation({description:e,screenXml:u.emulatorState.graph.xml,screenshot:u.screenshot,memory:i?a:void 0},{logger:l,loggerTags:ye(l),abortSignal:this.aborter.controller?.signal,useMemory:i,agentConfigVersion:this.aiSettings.agentConfig?.["android-locator"]});return f.result=y,y})}catch(f){throw this.throwIfAborted(),l.error({err:f},"Failed to locate element"),new R("InternalWebAgentError",`Failed to locate element: ${f instanceof Error?f.message:f}`,{errOptions:{cause:f}})}if(d.id===-1){let f=d.updatedMemory?{type:"GCS_TRACES",traces:d.updatedMemory}:void 0;return{success:!1,thoughts:d.thoughts??"No matching element found",updatedLocatorMemory:f}}let{target:p,resolvedNode:m}=_O({aiResponse:d,description:e,emulatorState:u.emulatorState,memory:a,useMemory:i});if(p.type==="NATIVE")return t.addSpan({type:"TARGET_RESOLUTION",startTime:Date.now(),endTime:Date.now(),result:{serializedElement:p.elementOnlySerializedXml??"Unknown element"},attributes:{},subSpans:[]}),{success:!0,resolvedTarget:{...p,resolvedNode:m},thoughts:d.thoughts};let{browserLocateResult:g,browserController:h}=await t.startWebviewTrace(async()=>{let f=await this.stateManager.getActiveWebview();if(!f||!f.browserController)throw new R("InternalWebAgentError","No browser controller is attached to the requested webview");return{browserLocateResult:await f.browserController.locateElement({description:e,disableCache:!1,useMemory:i,memory:i?s:void 0,logger:this.logger,skipWait:!0,skipSavingVisualAttributes:!0}),browserController:f.browserController}});return t.addSpan({type:"TARGET_RESOLUTION",startTime:Date.now(),endTime:Date.now(),result:{serializedElement:g.target.nodeOnlySerializedHtml??"Unknown HTML element in webview"},attributes:{},subSpans:[]}),{success:!0,resolvedTarget:{...p,controller:h,browserTarget:{...g.resolution,serverSideBoundingBox:await g.resolution.locator.boundingBox({timeout:5e3})},browserCache:g.target},thoughts:g.thoughts}}async targetingActionWithAILocator(e){let{action:t,command:n,description:o,tracer:i,cacheKey:a,targetName:s,cache:c,skipFetchingFullWebviewContent:l,removeWebviewContent:u,metadata:d}=e,p=await this.findElement({description:o,tracer:i,skipFetchingFullWebviewContent:l,removeWebviewContent:u,useMemory:this.shouldUseMemoryForCommand(n),memory:c?.memory,webviewMemory:MO(c),metadata:d});if(!p.success){if(p.updatedLocatorMemory&&c){let h={...c,memory:p.updatedLocatorMemory};ua({command:n,cacheKey:a,targetName:s,updatedCache:h,updatedWithAI:!0,logger:this.logger})}throw new R("NoMatchingElementError",p.thoughts??"No matching element found")}let m=p.thoughts,g=await t(p.resolvedTarget);return ua({command:n,cacheKey:a,targetName:s,updatedCache:p.resolvedTarget,updatedWithAI:!0,logger:this.logger}),{result:g,thoughts:m}}async wrapTargetingAction(e){let{action:t,description:n,command:o,cacheKey:i="cache",targetName:a="target",cacheIsInvalidAfterResolution:s,tracer:c,skipFetchingFullWebviewContent:l=!1,removeWebviewContent:u=!1,disableTargetRedirection:d=!1}=e,p,m={commandId:o.id};if(i==="cache"&&"cache"in o&&o.cache){let b=o.cache;a==="target"&&"target"in b?p=b.target:a==="fromTarget"&&"fromTarget"in b?p=b.fromTarget:a==="toTarget"&&"toTarget"in b&&(p=b.toTarget)}let g=!1,h=Hy(p);if(o.disableCache&&(this.logger.debug({command:o},"Cache explicitly disabled for command"),g=!0,h=void 0),s&&(g=!0,h=void 0),h&&h?.resolvedDescription!==n&&(this.logger.info({description:n,cacheDescription:h?.resolvedDescription},"Cache description mismatch, clearing it automatically"),g=!0,h=void 0),!h)return this.logger.info({description:n,cacheBustedBeforeAction:g},"Prompting AI for a new element location"),this.targetingActionWithAILocator({action:t,command:o,description:n,tracer:c,cacheKey:i,targetName:a,cache:p,skipFetchingFullWebviewContent:l,removeWebviewContent:u,metadata:m});let f=h.type==="NATIVE"?!!h.requirements:!!h.browserCache?.requirements,y=h.type==="NATIVE"?!!h.requiredRelatedElements?.length:!!h.browserCache?.additionalElements?.length,E;try{this.options?.emulator?.waitForStability&&await this.stateManager.waitForPageSourceStability({timeoutMs:3e3,signal:this.aborter.controller?.signal,reason:"Waiting for stability before cache resolution"});let{resolvedTarget:b,updatedCache:_}=await c.startAsyncSpan("CACHE_RESOLUTION",async O=>{let v=Date.now(),C;for(;Date.now()-v<3e3;){E=await this.stateManager.getDomState({skipFetchingFullWebviewContent:h?.type==="NATIVE"});let F;try{F=(await gp({target:h,domState:E,stateManager:this.stateManager,logger:this.logger,disableTargetRedirection:d})).resolvedTarget}catch(D){if(C=D,D instanceof gt){this.logger.warn({err:D},"Failed to resolve target cache, retrying");continue}throw this.logger.error({err:D},"Failed to resolve target cache"),D}let I=hp(F),B=UK(h,I);return B&&Object.keys(B).length>0&&this.logger.info({cacheDiffs:B},"Successfully resolved target with cache"),O.attributes.serializedElement=F.type==="WEBVIEW"?F.browserCache?.nodeOnlySerializedHtml??"Unknown HTML element in webview":F.elementOnlySerializedXml??"Unknown element",{resolvedTarget:F,updatedCache:I}}throw C}),M=await t(b);return ua({command:o,cacheKey:i,targetName:a,updatedCache:_,updatedWithAI:!1,logger:this.logger}),nt.increment("cache_target_resolution_v2",1,["outcome:hit",`platform:mobile-${h.type.toLowerCase()}`,`hasRequirements:${f}`,`hasAdditionalElements:${y}`,`orgId:${this.orgId}`,"cliVersion:0.34.0"]),{result:M,thoughts:"Successfully executed preset action with cache"}}catch(b){if(this.throwIfAborted(),b instanceof R&&b.reason!=="InternalWebAgentError")throw this.logger.error({err:b},"Failed to execute action with target cache (fatal)"),b;return nt.increment("cache_target_resolution_v2",1,["outcome:miss",`platform:mobile-${h.type.toLowerCase()}`,`hasRequirements:${f}`,`hasAdditionalElements:${y}`,`orgId:${this.orgId}`,"cliVersion:0.34.0"]),this.logger.warn({err:b},"Failed to execute action with target cache, retrying with AI"),this.targetingActionWithAILocator({action:t,command:o,description:n,tracer:c,cacheKey:i,targetName:a,cache:h,skipFetchingFullWebviewContent:l,removeWebviewContent:u,metadata:m})}}constructPerformerParams(){return{stateManager:this.stateManager,generator:this.generator,driver:this.driver,logger:this.logger,fixtures:this.fixtures,aborter:this.aborter,orgId:this.orgId,aiSettings:this.aiSettings,options:this.options}}getBoundsFromNativeCache(e){if(!e.bounds)throw new R("ActionFailureError","Native element cache has no bounds");let[t,n,o,i]=e.bounds;if(t===void 0||n===void 0||o===void 0||i===void 0)throw new R("ActionFailureError",`Native element cache has incomplete bounds: [${e.bounds.join(", ")}]`);return{left:t,top:n,width:o-t,height:i-n}}calculateSwipeCoordinates({containerBounds:e,direction:t,desiredDelta:n,edgeMarginPercent:o=.1}){let i=e.left+e.width/2,a=e.top+e.height/2;if(t==="up"||t==="down"){let s=e.height*o,c=e.top+s,l=e.top+e.height-s,u=l-c,d=Math.min(Math.abs(n),u);return{startX:i,startY:t==="down"?l:c,actualDelta:d}}else{let s=e.width*o,c=e.left+s,l=e.left+e.width-s,u=l-c,d=Math.min(Math.abs(n),u);return{startX:t==="right"?l:c,startY:a,actualDelta:d}}}invertDirection(e){if(e==="up")return"down";if(e==="down")return"up";if(e==="left")return"right";if(e==="right")return"left";throw new Error(`Unreachable code: ${e}`)}async performRawSwipe({startX:e,startY:t,deltaPixels:n,direction:o,durationMs:i=300}){let a=Math.abs(n),s=e,c=t;o==="up"||o==="down"?c=o==="up"?t-a:t+a:s=o==="left"?e-a:e+a,await this.driver.performActions([{type:"pointer",id:"finger1",parameters:{pointerType:"touch"},actions:[{type:"pointerMove",duration:0,x:e,y:t},{type:"pointerDown",button:0},{type:"pause",duration:100},{type:"pointerMove",duration:i,x:s,y:c},{type:"pointerUp",button:0}]}]),await this.driver.releaseActions()}throwIfAborted(){this.aborter.controller?.signal.throwIfAborted()}get abortSignal(){return this.aborter.controller?.signal}get aiSettingsCopy(){return Hy(this.aiSettings)}get optionsCopy(){return Hy(this.options)}};function IO(r){return"iterations"in r}function HK(r){let e={relativePosition:r.relativePosition};if(r.iterations!==void 0&&(!Number.isInteger(r.iterations)||r.iterations<1))throw new Error("UserConfigurationError: iterations must be a positive integer");if(r.tapDelayMs!==void 0&&(!Number.isInteger(r.tapDelayMs)||r.tapDelayMs<0))throw new Error("UserConfigurationError: tapDelayMs must be >= 0");if(r.iterations&&r.iterations>1&&r.longPress)throw new Error("UserConfigurationError: Cannot specify both more than one tap iteration and long press at the same time");if(r.tapDelayMs!==void 0&&(!r.iterations||r.iterations<2))throw new Error("UserConfigurationError: tapDelayMs requires iterations >= 2");if(r.longPress){if(r.tapDelayMs!==void 0)throw new Error("UserConfigurationError: tapDelayMs cannot be used with longPress");return{...e,longPress:!0,longPressDurationMs:r.longPressDurationMs}}return r.iterations!==void 0?{...e,iterations:r.iterations,tapDelayMs:r.tapDelayMs}:e}var Hs=class extends Rt{async tapOnNativeCoordinates(e){let t=e.x,n=e.y;if(this.logger.info({x:t,y:n},"Tap at coordinates"),"longPress"in e&&e.longPress)return await this.driver.executeScript("mobile: longClickGesture",[{x:t,y:n,duration:e.longPressDurationMs??2e3}]);if(IO(e)){let o=e.tapDelayMs??100;for(let i=0;i<e.iterations;i++)await this.driver.tap({x:t,y:n}),i<e.iterations-1&&await new Promise(a=>setTimeout(a,o));return}await this.driver.tap({x:t,y:n})}async tapOnNativeTarget(e,t){let[n,o,i,a]=e.bounds,s=i-n,c=a-o,l=t?.relativePosition?.x??s/2,u=t?.relativePosition?.y??c/2;l=Math.max(0,Math.min(l,s)),u=Math.max(0,Math.min(u,c));let d=n+l,p=o+u;return await this.tapOnNativeCoordinates({x:d,y:p,...t}),{x:d,y:p}}async tapOnWebviewTarget(e,t){let{controller:n}=e,o,i=1;return t&&IO(t)?(o=t.tapDelayMs,i=t.iterations):t&&"longPress"in t&&(o=t.longPressDurationMs),(await n.browser.click(e.browserTarget,{createIsolatedFolder:()=>{let s=Math.random().toString(36).substring(4),c=PO.join(zK(),"momentic","downloads"),l=PO.join(c,this.orgId,s);return BK(l,{recursive:!0}),l}},{delayMs:o,relativePosition:t?.relativePosition,iterations:i})).coordinates}async tapOnTarget({target:e,options:t}){return await se().startAsyncSpan("EMULATOR_INTERACTION",async o=>{o.attributes.options=t,"type"in e&&e.type==="NATIVE"?o.attributes.point=await this.tapOnNativeTarget(e,t):(o.withinWebview=!0,o.attributes.point=await this.tapOnWebviewTarget(e,t))},{name:"Tap on target"})}async executeTap({command:e}){let t=se(),n=HK(e);if(e.target.type==="coordinates"){let a=await this.driver.getWindowSize(),s=e.target.xPercent*a.width,c=e.target.yPercent*a.height;return await t.startAsyncSpan("EMULATOR_INTERACTION",async()=>{await this.tapOnNativeCoordinates({...n,x:s,y:c})},{name:`Tap at coordinates ${s}, ${c}`}),{success:!0,message:`Tapped at ${s}, ${c}`}}let o=e.target.description,{thoughts:i}=await this.wrapTargetingAction({command:e,tracer:t,action:a=>this.tapOnTarget({target:a,options:n}),description:o});return{success:!0,message:i}}};var ni=class extends Rt{async doPress({keycode:e,longPress:t}){await se().startAsyncSpan("EMULATOR_INTERACTION",async()=>this.driver.executeScript("mobile: pressKey",[{keycode:e,isLongPress:t}]),{name:"Send key events to emulator"})}};var da=25,fp=class extends Rt{async doType(e){let t=se();if(!e.target){if(e.clearContent)throw new R("UserConfigurationError","Clearing content is only supported when a target is provided to the Type step");return await this.stateManager.waitForPageSourceStability({timeoutMs:2e3,signal:this.aborter.controller?.signal,reason:"Waiting for page to stabilize before typing"}),await this.sendKeys(e),{success:!0,message:"Successfully executed type action"}}if(e.target.type!=="description")throw new R("UserConfigurationError","x/y targets are not supported for the Type step");let{thoughts:n}=await this.wrapTargetingAction({command:e,tracer:t,action:async o=>{"type"in o&&o.type==="NATIVE"?await this.doNativeType(e,o):await this.doWebviewType(e,o)},description:e.target.description});return{success:!0,message:n}}async doWebviewType(e,t){await se().startAsyncSpan("EMULATOR_INTERACTION",async o=>{o.withinWebview=!0;let i={clearContent:e.clearContent,forceClearContent:e.forceClearContent,delay:e.keyPressDelayMs??da};o.attributes.options=i;let{controller:a,browserTarget:s}=t;await a.browser.typeIntoTarget(e.text,s,i)},{name:"Typing within web view"})}async doNativeType(e,t){let n=new Hs(this.constructPerformerParams());e.clearContent?(await n.tapOnNativeTarget(t,{longPress:!0}),await this.clearContent()):await n.tapOnNativeTarget(t),await this.stateManager.waitForPageSourceStability({timeoutMs:2e3,signal:this.aborter.controller?.signal,reason:"Waiting for keyboard to appear before typing"}),await this.sendKeys(e)}async sendKeys(e){let t=se(),n=e.keyPressDelayMs??da;await t.startAsyncSection("Waiting for system keyboard to open",async(o,i)=>{let a=Date.now();for(;Date.now()-a<2e3;){this.throwIfAborted();let s=Date.now();if(await this.driver.isKeyboardShown())return;let c=Date.now()-s;c<500&&await new Promise(l=>setTimeout(l,500-c))}i.attributes.timedOut=!0}),n!==da?await t.startAsyncSpan("EMULATOR_INTERACTION",async()=>{await this.driver.updateSettings({keyInjectionDelay:n}),await this.driver.keys(e.text),await this.driver.updateSettings({keyInjectionDelay:da})},{name:`Typing with a ${n}ms delay`}):await t.startAsyncSpan("EMULATOR_INTERACTION",async()=>{await this.driver.keys(e.text)},{name:`Typing with a ${da}ms delay`})}async clearContent(){let e=se();try{await e.startAsyncSection("Clearing any content from the focused field",()=>this.clearContentHelper())}catch(t){this.logger.warn({err:t},"Failed to find select all button, continuing...")}}async clearContentHelper(){let e=this.driver.$('//android.widget.LinearLayout[@content-desc="Select all" and @clickable="true"]');await e.waitForExist({timeout:750}),await e.click(),await new ni(this.constructPerformerParams()).doPress({keycode:67})}};import Nr from"zod";var OO=.8,oi=.2,GK=Nr.object({navigationBar:Nr.object({visible:Nr.boolean(),x:Nr.number(),y:Nr.number(),width:Nr.number(),height:Nr.number()}),statusBar:Nr.object({visible:Nr.boolean(),x:Nr.number(),y:Nr.number(),width:Nr.number(),height:Nr.number()})}),Gs=class extends Rt{async getHardcodedScrollableElementBounds(e,t){let n;switch(e.type){case"SCREEN":n=this.getInsetBoundsFromViewport(t);break;case"OPEN_APP":try{let o=GK.parse(await this.driver.executeScript("mobile: getSystemBars",[]));n=this.getInsetBoundsFromViewport(t),o.navigationBar.visible&&(n.height=Math.max(1,n.height-o.navigationBar.height)),o.statusBar.visible&&(n.top+=o.statusBar.height,n.height=Math.max(1,n.height-o.statusBar.height))}catch(o){this.logger.warn({err:o},"Failed to get system bars, using hardcoded bounds"),n=this.getInsetBoundsFromViewport(t)}break;case"OPEN_WEBVIEW":{let o=await this.stateManager.getActiveWebviewNodes();if(o.length===0&&(await this.stateManager.refreshWebviewsManually("get active webview nodes"),o=await this.stateManager.getActiveWebviewNodes()),o.length===0)throw new Error("No active webviews found");if(o.length>1){let a=o.map(s=>({id:s.id,ele:s.originalElement.outerHTML,bounds:s.bounds}));throw new Error(`Multiple active webviews found. Momentic currently only supports a single active webview at a time. Discovered nodes: ${JSON.stringify(a)}`)}let i=o[0]?.bounds;if(!i)throw new Error("No bounds found for active webview");n=this.getInsetBoundsFromBounds(i);break}default:{let o=e;throw new Error("If Typescript complains about the line above, you missed a switch case")}}return n}getInsetBoundsFromViewport(e){let t=Math.floor(e.width*oi),n=Math.floor(e.height*oi);return{left:e.x+t,top:e.y+n,width:Math.max(1,e.width-t*2),height:Math.max(1,e.height-n*2)}}getInsetBoundsFromBounds(e){let t=e[0],n=e[1],o=e[2],i=e[3],a=o-t,s=i-n,c=Math.floor(a*oi),l=Math.floor(s*oi);return{left:t+c,top:n+l,width:Math.max(1,a-c*2),height:Math.max(1,s-l*2)}}async executeSwipe(e){let t=se();if(e.scrollableElement.type==="CUSTOM_COORDINATES"){let{startX:o,startY:i,deltaPixels:a}=e.scrollableElement;return await t.startAsyncSpan("EMULATOR_INTERACTION",async s=>{s.attributes.startX=o,s.attributes.startY=i,s.attributes.deltaPixels=a,s.attributes.direction=e.direction,await this.performRawSwipe({startX:o,startY:i,deltaPixels:a,direction:e.direction,durationMs:e.durationMs})},{name:`Swipe ${e.direction} using raw coordinates`}),{success:!0,message:"Successfully executed swipe action"}}if(e.scrollableElement.type!=="CUSTOM"){let o=await this.driver.getWindowRect(),i=await this.getHardcodedScrollableElementBounds(e.scrollableElement,o);return await t.startAsyncSpan("EMULATOR_INTERACTION",async a=>{await this.swipeByAbsoluteCoordinates({span:a,direction:e.direction,percent:e.viewportPercent,durationMs:e.durationMs,containerBounds:i})},{name:`Swipe ${e.direction} in the entire ${e.scrollableElement.type.toLowerCase()}`}),{success:!0,message:"Successfully executed swipe action"}}let{thoughts:n}=await this.wrapTargetingAction({command:e,description:e.scrollableElement.target.description,action:async o=>se().startAsyncSpan("EMULATOR_INTERACTION",async a=>"type"in o&&o.type==="NATIVE"?this.scrollInNativeContainer({span:a,cmd:e,target:o}):(a.withinWebview=!0,this.swipeInWebview({span:a,cmd:e,target:o})),{name:`Swipe ${e.direction} in the specified container`}),tracer:t});return{success:!0,message:n}}async scrollInNativeContainer({span:e,cmd:t,target:n}){if(!n.bounds||n.bounds.length<4)throw new R("ActionFailureError","Native container cache has no bounds");let o=n.bounds,i=o[2]-o[0],a=o[3]-o[1],s=Math.floor(i*oi),c=Math.floor(a*oi);await this.swipeByAbsoluteCoordinates({span:e,direction:t.direction,percent:t.viewportPercent,durationMs:t.durationMs,containerBounds:{left:o[0]+s,top:o[1]+c,width:Math.max(1,i-s*2),height:Math.max(1,a-c*2)}})}async swipeInWebview({span:e,cmd:t,target:n}){let{controller:o,browserTarget:i}=n;if(!o.browser.getViewport())throw new Error("Failed to get viewport size from webview");let s=t.direction==="down"||t.direction==="up",c=await i.locator.boundingBox();if(!c)throw new Error("Failed to get bounds for webview container");let l=Math.floor(c.width*oi),u=Math.floor(c.height*oi),d=Math.max(1,c.width-l*2),p=Math.max(1,c.height-u*2),m={x:c.x+l+d/2,y:c.y+u+p/2},g=(s?p:d)*(t.viewportPercent??OO)*(s?t.direction==="down"?1:-1:t.direction==="right"?1:-1);e.attributes.startPoint=m,e.attributes.scrollPixelAmount=g,await o.browser.mouseDragUsingVisualCoordinates({deltaX:s?0:g,deltaY:s?g:0,steps:10,dragDurationMs:t.durationMs,fromTarget:m})}async swipeByAbsoluteCoordinates({span:e,direction:t,percent:n=OO,durationMs:o=500,containerBounds:i}){e.attributes.containerBounds=i;let a,s;t==="up"||t==="down"?(a=i.height*n,s=Math.floor(a/(o/1e3))):(a=i.width*n,s=Math.floor(a/(o/1e3))),e.attributes.pixelDelta=a,e.attributes.pixelsPerSecond=s,await this.driver.executeScript("mobile: swipeGesture",[{...i,direction:t,percent:n,speed:s}])}};var LO=5,NO=.8,WK=1,Sp=class extends Gs{async executeScrollTo(e){let t=e.target.description,n=e.scrollStepPercent??NO,o=await this.tryUseCachedScrollPosition(e,t);return o||this.searchForElement(e,t,n)}async resolveContainer({scrollableElement:e,containerCache:t,aiMetadata:n}){let o=await this.driver.getWindowRect();if(e.type==="CUSTOM_COORDINATES")return{bounds:{left:0,top:0,width:o.width,height:o.height}};if(e.type!=="CUSTOM")return{bounds:await this.getHardcodedScrollableElementBounds(e,o)};let i=se(),a=e.target.description;if(t){let u=this.getBoundsFromNativeCache(t);return this.logger.info({bounds:u},"Got container bounds from native cache"),{bounds:u,cache:t}}let s=await this.findElement({description:a,tracer:i,metadata:n});if(!s.success)throw new R("NoMatchingElementError",s.thoughts??"No matching element found");let{resolvedTarget:c}=s;if(c.type!=="NATIVE")throw new Error(`ActionFailureError: Custom scroll container "${a}" resolved to a webview element. Custom containers must be native elements.`);let l=this.getBoundsFromNativeCache(c);return this.logger.info({bounds:l},"Got container bounds from AI"),{bounds:l,cache:c}}async tryUseCachedScrollPosition(e,t){let n=e.cache?.target;return n?n.type==="WEBVIEW"?this.tryUseWebviewCache(e,t):n.scrollDetails?this.tryUseNativeScrollCache(e,t,n):null:null}async tryUseWebviewCache(e,t){let n=se();try{let{thoughts:o}=await this.wrapTargetingAction({command:e,tracer:n,description:t,action:async i=>{if(i.type==="NATIVE")throw new Error("Expected WEBVIEW target but got NATIVE");await this.scrollWebviewTargetIntoView(i)}});return{success:!0,message:o}}catch(o){return this.logger.warn({err:o},"Failed to use webview cache, falling back to search"),null}}async tryUseNativeScrollCache(e,t,n){let o=n.scrollDetails,i=se(),a=e.scrollStepPercent??NO,s=o.scrollableElement.type==="CUSTOM"?o.scrollableElement.cache:void 0;await this.scrollByPixelDelta({pixelDelta:o.pixelDelta,scrollableElement:o.scrollableElement,containerCache:s,direction:o.direction,scrollStepPercent:a,aiMetadata:{commandId:e.id}});try{let l=await this.tryFindElement({cmd:e,description:t,tracer:i,scrollDetails:o,useAIIfCacheFails:!1});if(l)return l;this.logger.info("Element not found at cached position, undoing scroll")}catch(l){this.logger.warn({err:l},"Error finding element at cached position, will undo scroll")}let c=o.direction==="down"?"up":"down";return this.logger.info({pixelDelta:o.pixelDelta,originalDirection:o.direction,undoDirection:c,scrollableElementType:o.scrollableElement.type},"Undoing scroll"),await this.scrollByPixelDelta({pixelDelta:o.pixelDelta,scrollableElement:o.scrollableElement,containerCache:s,direction:c,scrollStepPercent:a,aiMetadata:{commandId:e.id}}),null}async tryFindElement({cmd:e,description:t,tracer:n,scrollDetails:o,useAIIfCacheFails:i=!0}){let a,s,c=e.cache?.target;if(c&&c.resolvedDescription===t&&!e.disableCache){let u=await this.stateManager.getDomState({skipFetchingFullWebviewContent:!0,removeWebviewContent:!0});try{let{resolvedTarget:d}=await gp({target:c,domState:u,stateManager:this.stateManager,logger:this.logger});a=d,s="Successfully resolved scroll to target with cache.",this.logger.info("Successfully resolved scroll to target from cache")}catch(d){this.logger.warn({err:d},"Failed to resolve target from cache")}}if(!a&&!i)return null;if(!a)try{let u=await this.findElement({description:t,tracer:n,metadata:{commandId:e.id}});if(!u.success)return null;a=u.resolvedTarget,s=u.thoughts}catch(u){if(u instanceof R&&u.reason==="NoMatchingElementError")return null;throw this.logger.warn({err:u},"Failed to find scroll-to target with AI"),u}return a.type==="WEBVIEW"?(await this.scrollWebviewTargetIntoView(a),ua({command:e,updatedCache:hp(a),updatedWithAI:!0,logger:this.logger}),{success:!0,message:s}):(ua({command:e,updatedCache:{...a,scrollDetails:o},updatedWithAI:!0,logger:this.logger}),{success:!0,message:s})}async searchForElement(e,t,n){let o=se(),i=await this.resolveContainer({scrollableElement:e.scrollableElement,aiMetadata:{commandId:e.id}});return this.scrollAndSearch(e,t,o,n,i)}async scrollAndSearch(e,t,n,o,i){let a=0,s=i.bounds,c=s.height*o,l=!0;for(let u=0;u<LO;u++){this.throwIfAborted();let d=this.buildScrollDetails(e,a,i.cache),p=await this.tryFindElement({cmd:e,description:t,tracer:n,scrollDetails:d});if(p)return p;if(!l)throw new Error(`ActionFailureError: Could not find element "${t}" after scrolling to the end`);this.logger.debug({attempt:u,cumulativePixelDelta:a},"Element not found, scrolling further");let m=jK(e.scrollableElement);l=await this.scrollByPage({direction:e.direction,containerBounds:s,scrollStepPercent:o,rawCoordinates:m}),a+=e.direction==="down"?c:-c}throw new Error(`ActionFailureError: Could not find element "${t}" after ${LO} scroll attempts`)}buildScrollDetails(e,t,n){return e.scrollableElement.type==="CUSTOM"?{pixelDelta:t,scrollableElement:{type:"CUSTOM",target:e.scrollableElement.target,cache:n},direction:e.direction}:e.scrollableElement.type==="CUSTOM_COORDINATES"?{pixelDelta:t,scrollableElement:e.scrollableElement,direction:e.direction}:{pixelDelta:t,scrollableElement:e.scrollableElement,direction:e.direction}}async scrollWebviewTargetIntoView(e){let{controller:t,browserTarget:n}=e;await t.browser.hover(n)}async scrollByPage({direction:e,containerBounds:t,scrollStepPercent:n,rawCoordinates:o}){return se().startAsyncSpan("EMULATOR_INTERACTION",async a=>(a.attributes.containerBounds=t,a.attributes.direction=e,this.executeScrollGesture({direction:e,containerBounds:t,scrollStepPercent:n,rawCoordinates:o})),{name:`Scroll ${e} by one page`})}async scrollByPixelDelta({pixelDelta:e,scrollableElement:t,containerCache:n,direction:o,scrollStepPercent:i,aiMetadata:a}){if(e===0)return;let s=se(),c,l,u;if(t.type==="CUSTOM_COORDINATES")c=t.startX,l=t.startY,u=t.deltaPixels;else{let m=(await this.resolveContainer({scrollableElement:t,containerCache:n,aiMetadata:a})).bounds,g=m.height*i,h=this.calculateSwipeCoordinates({containerBounds:m,direction:o,desiredDelta:g});c=h.startX,l=h.startY,u=h.actualDelta}let d=Math.ceil(Math.abs(e)/u);this.logger.debug({pixelDelta:e,direction:o,scrollableElementType:t.type,startX:c,startY:l,maxScrollPerStep:u,numScrolls:d},"scrollByPixelDelta calculated parameters"),await s.startAsyncSpan("EMULATOR_INTERACTION",async p=>{p.attributes.pixelDelta=e,p.attributes.numScrolls=d,p.attributes.maxScrollPerStep=u,p.attributes.startX=c,p.attributes.startY=l;let m=0;for(let g=0;g<d;g++){this.throwIfAborted();let h=Math.abs(e)-m,f=Math.min(u,h);await this.performRawSwipe({startX:c,startY:l,deltaPixels:f,direction:this.invertDirection(o)}),m+=f}},{name:`Scroll ${o} by ${e}px`})}async executeScrollGesture({direction:e,containerBounds:t,scrollStepPercent:n,diffThresholdPercent:o=WK,rawCoordinates:i}){let a=await this.stateManager.getRawScreenshotBase64(),s,c,l;if(i)s=i.startX,c=i.startY,l=i.deltaPixels;else{let m=t.height*n,g=this.calculateSwipeCoordinates({containerBounds:t,direction:e,desiredDelta:m});s=g.startX,c=g.startY,l=g.actualDelta}await this.performRawSwipe({startX:s,startY:c,deltaPixels:l,direction:this.invertDirection(e)});let u=await this.stateManager.getRawScreenshotBase64(),d=Ms(a,u),p=d>o;return this.logger.debug({diffPercent:d,diffThresholdPercent:o,canScrollMore:p,direction:e,actualDelta:l,rawCoordinates:i},"Scroll gesture visual diff result"),p}};function jK(r){if(r.type==="CUSTOM_COORDINATES")return r}import{randomUUID as VK}from"crypto";import uu from"fs";import{tmpdir as $K}from"os";import Ws from"path";var yp=class extends Rt{async doInstallApk(e){return await this.installApkFromUri(e.uri),{success:!0,message:"Installed APK."}}async installApkFromUri(e){let t=await this.resolveUriToLocalApk(e);try{await this.stateManager.executeRawADBCommand(`install -r ${Ws.resolve(t.localPath)}`),this.logger.info({uri:e,localPath:t.localPath},"Installed APK on device")}finally{t.cleanup()}}async resolveUriToLocalApk(e){try{let t=new URL(e);if(t.protocol==="file:"){let n=t.href.slice(7),o;if(uu.existsSync(n))o=n;else if(uu.existsSync(Ws.join("/",n)))o=Ws.join("/",n);else throw new R("UserConfigurationError",`APK not found at path: ${n}`);return this.assertFileExists(o),{localPath:o,cleanup:()=>{}}}if(t.protocol==="http:"||t.protocol==="https:"){let n=await this.fetchWithTimeout(t);if(!n.ok)throw new R("UserInfrastructureError",`Failed to download APK from ${e} (status ${n.status})`);let o=await n.arrayBuffer(),i=Buffer.from(o),a=await this.writeBufferToTempFile(i,t.pathname);return{localPath:a,cleanup:()=>{try{uu.unlinkSync(a)}catch(s){this.logger.warn({err:s,path:a},"Failed to remove temporary APK file")}}}}throw new R("UserConfigurationError",`Unsupported URI scheme for APK installation: ${t.protocol}`)}catch(t){if(t instanceof TypeError){let n=Ws.resolve(e);return this.assertFileExists(n),{localPath:n,cleanup:()=>{}}}throw t}}assertFileExists(e){try{uu.accessSync(e)}catch{throw new R("UserConfigurationError",`APK not found at path: ${e}`)}}async fetchWithTimeout(e){let t=AbortSignal.timeout(9e4);return await fetch(e,{signal:t})}async writeBufferToTempFile(e,t){let n=Ws.extname(t)||".apk",o=Ws.join($K(),`momentic-apk-${VK()}${n}`);return uu.writeFileSync(o,e),o}};import{existsSync as qK,readFileSync as KK}from"fs";import YK from"zod";var XK=YK.string().url();async function DO(r){if(XK.safeParse(r).success){let e=new AbortController,t=setTimeout(()=>e.abort(),1e4),n;try{n=await fetch(r,{signal:e.signal})}catch(i){throw new R("UserInfrastructureError",`Fetch failed or timed out for URL: ${r}`,{errOptions:{cause:i}})}finally{clearTimeout(t)}if(!n.ok)throw new R("UserInfrastructureError",`Failed to fetch file from URL: ${r}, status: ${n.status}`);let o=await n.arrayBuffer();return Buffer.from(o).toString("base64")}if(!qK(r))throw new R("UserInfrastructureError",`File does not exist at path: ${r}`);return KK(r).toString("base64")}var bp=class extends Rt{async dragNative(e,t,n){let{left:o,top:i,width:a,height:s}=this.getBoundsFromNativeCache(e),{left:c,top:l,width:u,height:d}=this.getBoundsFromNativeCache(t),p=o+a/2,m=i+s/2,g=c+u/2,h=l+d/2,f=n?.hoverDuration??500,y=n?.dragDuration??1e3;await this.driver.performActions([{type:"pointer",id:"finger1",parameters:{pointerType:"touch"},actions:[{type:"pointerMove",duration:0,x:p,y:m},{type:"pointerDown",button:0},{type:"pause",duration:f},{type:"pointerMove",duration:y,x:g,y:h},{type:"pointerUp",button:0}]}]),await this.driver.releaseActions()}async dragWebview(e,t,n){let{controller:o}=e;if(e.controller!==t.controller)throw new R("UserConfigurationError","Cannot drag and drop between different webviews");let i=n?.dragDuration??1e3,a=n?.hoverDuration??1e3,s;n?.dragDuration&&(s=Math.max(1,Math.floor(i/200))),await o.browser.dragAndDrop(e.browserTarget,t.browserTarget,{hoverDurationMs:a,steps:s,dragDurationMs:i})}async executeDragAndDrop({command:e}){let t=se();if(e.fromTarget.type!=="description"||e.toTarget.type!=="description")throw new R("UserConfigurationError","Drag and drop only supports description targets for now");let n=e.fromTarget.description,{result:o,thoughts:i}=await this.wrapTargetingAction({command:e,tracer:t,description:n,cacheKey:"cache",targetName:"fromTarget",action:async l=>l}),a=e.toTarget.description,{result:s,thoughts:c}=await this.wrapTargetingAction({command:e,tracer:t,description:a,cacheKey:"cache",targetName:"toTarget",action:async l=>l});if(o.type!==s.type)throw new R("UserConfigurationError",`Drag and drop targets must be in the same context (both native or both webview). Found: From=${o.type}, To=${s.type}`);return await t.startAsyncSpan("EMULATOR_INTERACTION",async l=>{o.type==="NATIVE"&&s.type==="NATIVE"?await this.dragNative(o,s,{hoverDuration:e.hoverDuration,dragDuration:e.dragDuration}):o.type==="WEBVIEW"&&s.type==="WEBVIEW"&&(l.withinWebview=!0,await this.dragWebview(o,s,{hoverDuration:e.hoverDuration,dragDuration:e.dragDuration}))},{name:"Drag and drop"}),{success:!0,message:`${i}
|
|
4586
4586
|
${c}`}}};import{cloneDeep as kO}from"lodash-es";var Ep=class{async getTextContent(e){return await e.textContent()??""}async getAttribute(e,t){return await e.getAttribute(t,{timeout:3e3})??""}async getTagName(e){return await e.evaluate(t=>t.tagName)}async isEditable(e){return await e.isEditable({timeout:dr*1e3})}async isEnabled(e){return await e.isEnabled({timeout:dr*1e3})}async isFocused(e){return await e.evaluate(t=>t===document.activeElement)}async getStyleProperty(e,t){return await e.evaluate((n,o)=>window.getComputedStyle(n).getPropertyValue(o),t)}},Tp=class{async getTextContent(e){return Yc(e)}async getAttribute(e,t){return e.getAttribute(t)??""}async getTagName(e){return e.tagName}async isEditable(e){throw new Error("Cannot perform editable check on native element")}async isEnabled(e){return e.getAttribute("enabled")==="true"}async isFocused(e){return e.getAttribute("focused")==="true"}async getStyleProperty(e,t){throw new Error("Cannot perform computed style checks on native element")}};var JK=5e3,vp=class extends Rt{async executeElementCheck(e){let t=Date.now(),n=(e.timeout??dr)*1e3,o=n+1e4,i,a=0,s=500,c=kO(e.cache);if(e.target.type!=="description")throw new R("UserConfigurationError","x/y targets are not supported for the Element Check step");for(;a-t<n;){if(Date.now()-t>o){this.logger.warn("Exceeded max system timeout for element check, exiting...");break}if(this.throwIfAborted(),i=await this.executeElementCheckHelper(e),a=Date.now(),!i.success)e.cache=c,c=kO(c),await J(s,this.abortSignal),s=Math.min(Math.floor(s*1.5),JK);else return i}let l=await this.executeElementCheckHelper(e,{cacheIsInvalidAfterResolution:!0});if(!l.success&&c&&e.cache){let u=Qc({logger:this.logger,originalTarget:Bi(c)?c.target:void 0,newTarget:e.cache.target});u&&Os(c.target,u)&&(e.cache={target:u,updatedAt:e.cache.updatedAt})}return l}async executeElementCheckHelper(e,t){let n=se();if(e.target.type!=="description")throw new R("UserConfigurationError","x/y targets are not supported for the Element Check step");let o=Nm(e.assertion);try{return(await this.wrapTargetingAction({...t??{},command:e,tracer:n,action:async a=>"type"in a&&a.type==="NATIVE"?await this.executeNativeElementCheck(e,a):await this.executeWebviewElementCheck(e,a),description:e.target.description,skipFetchingFullWebviewContent:!0,removeWebviewContent:!0,disableTargetRedirection:!0})).result}catch(i){return o&&(i instanceof R&&i.reason==="NoMatchingElementError"||i instanceof Ro)?{success:!0}:{success:!1,message:`Failed to evaluate element content assertion: ${i instanceof Error?i.message:`${i}`}`}}}async executeNativeElementCheck(e,t){let n=se(),{assertion:o}=e,i=t.resolvedNode;return await n.startAsyncSpan("ELEMENT_ASSERTION",async a=>{let s=await this.executeElementAssertion({assertion:o,element:i,elementPropertyAccessors:new Tp,span:a});return a.result=s,s},{name:"Native element check"})}async executeWebviewElementCheck(e,t){let n=se(),o=t.browserTarget.locator,i=e.assertion;return await n.startAsyncSpan("ELEMENT_ASSERTION",async a=>{await t.controller.browser.highlight(o);let s=await this.executeElementAssertion({assertion:i,element:o,elementPropertyAccessors:new Ep,span:a});return a.result=s,s},{name:"Webview element check"})}async executeElementAssertion({assertion:e,element:t,elementPropertyAccessors:n,span:o}){switch(e.type){case"ELEMENT_CONTENT":{let i=await n.getTextContent(t)??"";return o.attributes.elementTextContent=Vt(i,500,!0),Bn(i,e.value,e.operation,{negated:!!e.negated,ignoreCase:!1})?{success:!0}:{success:!1,message:`The content ${tn(e)} '${e.value}': ${i}`}}case"ELEMENT_ATTRIBUTE":{"evaluate"in t&&(o.attributes.elementOuterHtml=Vt(await t.evaluate(a=>a.cloneNode(!1).outerHTML),500,!0));let i;try{i=await n.getAttribute(t,e.attr)}catch{i=null}if(!Bn(i,e.value,e.operation,{negated:!!e.negated,ignoreCase:!1})){let a=tn(e);return{success:!1,message:`The attribute ${e.attr} ${a}${e.operation==="EXISTS"?"":` '${e.value}': ${i}`}`}}return{success:!0}}case"ELEMENT_EXISTENCE":{let i=!1;switch(e.condition){case"EDITABLE":i=await n.isEditable(t);break;case"VISIBLE":case"EXISTS":i=!0;break;case"ENABLED":{i=await n.isEnabled(t);break}case"FOCUSED":i=await n.isFocused(t);break;default:throw e.condition,new Error("Unrecognized element condition type")}return i=e.negated?!i:i,i?{success:!0}:{success:!1,message:`The element ${tn(e)}`}}case"ELEMENT_NAME":{let i=await n.getTagName(t);return Bn(i,e.value,e.operation,{negated:!!e.negated,ignoreCase:!0})?{success:!0}:{success:!1,message:`The element tag name ${tn(e)} '${e.value}': ${i}`}}case"ELEMENT_STYLE":{let i=await n.getStyleProperty(t,e.property);if(!Bn(i,e.value,e.operation,{negated:!!e.negated,ignoreCase:!1})){let a=tn(e);return{success:!1,message:`The style property ${e.property} ${a}${e.operation==="EXISTS"?"":` '${e.value}': ${i}`}`}}return{success:!0}}default:throw new Error("Unrecognized element assertion type")}}};var ZK=5e3,Ap=class extends Rt{async executeScreenCheck(e){let{timeout:t}=e,n=Date.now(),o=(t??dr)*1e3,i=o+1e4,a=0,s=500;for(;a-n<o;){if(Date.now()-n>i){this.logger.warn("Exceeded max system timeout for screen check, exiting...");break}this.throwIfAborted();let c=await this.executeScreenCheckHelper(e);if(a=Date.now(),!c.success)await J(s,this.abortSignal),s=Math.min(Math.floor(s*1.5),ZK);else return c}return await this.executeScreenCheckHelper(e)}async executeScreenCheckHelper(e){return await se().startAsyncSection("Execute screen check",async(n,o)=>{let[i,a]=await Promise.all([this.executeNativeScreenCheckHelper({span:o,command:e}),this.executeWebviewScreenCheckHelper(e)]);return a?e.assertion.negated?i.success&&a.success?i:i.success?a:i:i.success?i:a:i})}async executeNativeScreenCheckHelper({span:e,command:t}){let{assertion:n}=t;switch(n.type){case"CONTENT":try{let o=(await this.stateManager.getDomState({skipFetchingFullWebviewContent:!0,removeWebviewContent:!0})).graph.document.documentElement?.outerHTML;if(!o)throw new Error("Failed to get screen HTML");let i=o.includes(n.value)===!n.negated;return o.length>1e4&&(o=o.slice(0,1e4)+"...TRUNCATED"),i?{success:!0}:(e.attributes.screenContent=o,{success:!1,message:`The screen ${LS(n)}.`})}catch(o){return{success:!1,message:`Failed to evaluate screen content assertion: ${o instanceof Error?o.message:`${o}`}`}}default:return n.type,{success:!1,message:`Unsupported screen check assertion type: ${n.type}`}}}async executeWebviewScreenCheckHelper(e){let t=await this.stateManager.getActiveWebview();if(!t||!t.browserController)return;let n=t.browserController.browser;return await up({assertion:e.assertion,logger:this.logger,browser:n,autoExpandIframes:!!n.userBrowserSettings.autoExpandIframes})}};var Rp=class extends Rt{async doUninstallApk(e){return await this.uninstallApkPackage(e.packageName),{success:!0,message:"Uninstalled APK."}}async uninstallApkPackage(e){let t=e.replace(/^package:/,""),n=await this.stateManager.executeRawADBCommand(`shell pm list packages | grep -E "^package:${t}$" || true`);if(!n||n.length===0)throw new R("UserConfigurationError",`Package ${t} not found`);if(n.split(`
|
|
4587
4587
|
`).filter(i=>!!i).length>1)throw new R("UserConfigurationError",`Multiple packages found for ${t}`);try{await this.stateManager.executeRawADBCommand(`uninstall ${t}`)}catch(i){throw new R("UserInfrastructureError",`Failed to uninstall package ${t}: ${i}`)}}};import{createHash as eY}from"crypto";import{_android as tY,chromium as rY}from"playwright";import{z as St}from"zod";var FO=St.object({"Android-Package":St.string(),Browser:St.string(),"Protocol-Version":St.string(),"User-Agent":St.string(),"V8-Version":St.string(),"WebKit-Version":St.string(),webSocketDebuggerUrl:St.string()}),UO=St.object({description:St.string(),devtoolsFrontendUrl:St.string(),id:St.string(),title:St.string(),type:St.string(),url:St.string(),webSocketDebuggerUrl:St.string()}),BO=St.object({proc:St.string(),webview:St.string(),webviewName:St.string()}),zO=St.array(BO.extend({info:FO.optional(),pages:St.array(UO).optional()})),FYe=St.array(BO.extend({info:FO,pages:St.array(UO)}));var wp=class r{driver;limbarClient;device;currentContext;logger;webviews=new Map;fixtures;orgId;options;aborter;constructor({driver:e,context:t,limbarClient:n,logger:o,device:i,fixtures:a,orgId:s,options:c,aborter:l}){this.driver=e,this.limbarClient=n,this.device=i,this.currentContext=t,this.logger=o,this.fixtures=a,this.orgId=s,this.options=c,this.aborter=l;for(let u of["SIGINT","SIGTERM"])process.on(u,async()=>{await this.cleanupWebviews()})}static async init({driver:e,logger:t,fixtures:n,limbarClient:o,orgId:i,adbPort:a,options:s,aborter:c,playwrightDevice:l}){let u=await e.getContext(),d=typeof u=="string"?u:u.id,p;if(l)p=l;else{let g=(await tY.devices()).filter(h=>h._initializer?.serial?.endsWith(a.toString())||h._initializer?.serial?.endsWith((a-1).toString()));if(t.warn({devices:g.map(h=>({serial:h._initializer?.serial,model:h._initializer?.model}))},"No playwright device provided, using ADB to find device"),g.length===0)throw new R("UserInfrastructureError",`Momentic found no devices listening on port ${a} or ${a-1}. This can occur if Android Studio reuses existing emulators. Please run 'adb emu kill' and 'adb disconnect' and retry.`);if(g.length>1)throw new R("UserInfrastructureError",`Momentic found multiple devices on the ports ${a} or ${a-1}. This can occur if Android Studio reuses existing emulators. Please run 'adb emu kill' and 'adb disconnect' and retry.`);p=g[0]}let m=new r({driver:e,context:d,logger:t,device:p,fixtures:n,orgId:i,options:s,aborter:c,limbarClient:o});return m.startWebviewRefreshInterval(),m}async getContexts(){let e=await this.driver.getContexts({}),t=Array.from(this.webviews.values());return{contexts:e,webviews:t.map(n=>({contextId:n.contextId,packageName:n.packageName,active:n.active,hasPlaywright:!!n.browserController,lastSeen:n.lastSeen,socketName:n.socketName}))}}async getRawScreenshotBase64(e=2){let t=se(),n;for(let o=0;o<e;o++)try{return await t.startAsyncSpan("EMULATOR_READ_STATE",async()=>await this.driver.takeScreenshot(),{name:"Take screenshot",signal:this.aborter.controller?.signal,timeoutMs:2e3})}catch(i){if(n=i,this.logger.warn({err:i},"Failed to take screenshot"),o===e-1)throw i}throw new R("InternalWebAgentError",`Failed to take screenshot: ${n}`)}async getCurrentScreenshotPngString(){return`data:image/png;base64,${await this.getRawScreenshotBase64(1)}`}async waitForScreenshotStability({timeoutMs:e,signal:t,reason:n,tolerancePercent:o=1}){await se().startAsyncSpan("WAIT_FOR_SCREENSHOT_STABILITY",async i=>{i.attributes.reason=n;let a=Date.now(),s,c,l=!1;for(;Date.now()-a<e;){c&&c<500&&await J(500-c,t),t?.throwIfAborted();let u=Date.now();if(!s){s=await this.getRawScreenshotBase64(),c=u-a;continue}let d=await this.getRawScreenshotBase64();if(c=u-a,Ms(s,d)<=o){l=!0;break}s=d}l||(i.attributes.timedOut=!0,this.logger.warn({purpose:n},"Timed out waiting for screenshot stability"))})}async waitForPageSourceStability({timeoutMs:e,signal:t,reason:n}){await se().startAsyncSpan("WAIT_FOR_PAGE_STABILITY",async o=>{o.attributes.reason=n;let i=Date.now(),a,s,c=!1;for(;Date.now()-i<e;){s&&s<250&&await J(250-s,t),t?.throwIfAborted();let l=Date.now(),u;try{u=await this.getPageSource()}catch(p){this.logger.warn({err:p},"Failed to get page source during stability wait"),s=Date.now()-l;continue}let d=eY("md5").update(u).digest("hex");if(s=Date.now()-l,a&&a===d){c=!0;break}a=d}c||(o.attributes.timedOut=!0,this.logger.warn({purpose:n},"Timed out waiting for page source stability"))})}async getCurrentPackage(){let e=await this.driver.execute("mobile: getCurrentPackage");return typeof e=="string"?e:void 0}async getActiveWebviewNodes(){let t=(await this.getDomState({skipFetchingFullWebviewContent:!0,removeWebviewContent:!0})).graph,n=[];for(let[o,i]of t.idToElement.entries())n.some(a=>a.id===o)||lu(i)&&n.push({id:o,originalElement:i,bounds:ca(i)});return n}async getActiveWebviewContent(){let e=await this.getActiveWebview();if(!e||!e.browserController)return;this.throwIfAborted();let t=e.browserController;return(await se().startAsyncSpan("EMULATOR_READ_STATE",()=>t.getBrowserState({abortSignal:this.aborter.controller?.signal,skipWait:!0,skipWaitForPageLoad:!0,logger:this.logger,serializationOpts:{noId:!0}}),{name:"Get webview content",signal:this.aborter.controller?.signal})).serializedTree}async getDomState(e){return await se().startAsyncSection("Get emulator state XML",async()=>{let n;if(!e?.skipFetchingFullWebviewContent)try{n=await this.getActiveWebviewContent()}catch(c){this.logger.error({err:c},"Could not get webview info to get the nested DOM state")}this.throwIfAborted();let i=e?.filterOffscreenElements??!0?await this.getViewportBounds():void 0,a=await this.getPageSource();return{graph:await AO(a,{injectedWebviewContent:n,disableMomenticAccessibilityTree:this.options.disableMomenticAccessibilityTree,removeWebviewContent:e?.removeWebviewContent,viewportBounds:i}),context:this.currentContext}},{timeoutMs:15e3})}async getPageSource(){return await se().startAsyncSpan("EMULATOR_READ_STATE",()=>this.driver.getPageSource(),{name:"Get Android page source",signal:this.aborter.controller?.signal})}async getViewportBounds(){let e=await this.driver.getWindowRect();return{left:e.x,top:e.y,right:e.x+e.width,bottom:e.y+e.height}}refreshPromise;refreshInterval;async refreshWebviewsManually(e){if(this.refreshPromise){await this.refreshPromise;return}clearInterval(this.refreshInterval),this.refreshPromise=this.doRefreshWebview(e).catch(t=>{this.logger.warn({err:t},"Error refreshing webviews, continuing...")}).finally(()=>{this.refreshPromise=void 0,this.startWebviewRefreshInterval()})}startWebviewRefreshInterval(){this.refreshInterval||(this.refreshInterval=setInterval(()=>{this.refreshPromise=this.doRefreshWebview("auto refresh").catch(e=>{this.logger.warn({err:e},"Error refreshing webviews, continuing...")}).finally(()=>{this.refreshPromise=void 0})},15e3))}async doRefreshWebview(e){this.logger.info({reason:e},"Refreshing webviews"),await this.getPageSource(),this.throwIfAborted();let t=await this.getCurrentPackage();if(t==="com.android.permissioncontroller")return;let n=await this.getDetailedContexts();if(!n){this.logger.warn("No context details, not proceeding with refreshing webviews");return}let o=Date.now(),i=new Set;for(let a of n){if(this.throwIfAborted(),a.webview==="NATIVE_APP")continue;let s=a.info["Android-Package"];if(t&&s!==t&&this.logger.warn({packageName:s,currentPkgName:t},"Ignoring webview not in the active package"),i.add(a.webview),!this.webviews.has(a.webview)||!this.webviews.get(a.webview)?.active){let c={contextId:a.webview,packageName:s,active:!1,lastSeen:o,socketName:a.proc.startsWith("@")?a.proc.substring(1):a.proc};this.logger.info({contextId:c.contextId,packageName:c.packageName,socketName:c.socketName},"New webview detected"),this.webviews.set(a.webview,c);let l;if(s==="com.android.chrome"?(this.logger.info({webviewInfo:c},`Connecting Playwright to Android Chrome: ${a.webview}`),l=await this.connectPlaywrightToChrome(c),this.logger.info(`Connected Playwright to Android Chrome: ${a.webview}`)):(this.logger.info({webviewInfo:c},`Connecting Playwright to webview: ${a.webview}`),l=await this.connectPlaywrightToWebview(s,c.socketName),l&&this.logger.info(`Connected Playwright to webview ${a.webview}`)),!l)continue;c.browserController=l,c.active=!0}}for(let[a,s]of this.webviews.entries())!i.has(a)&&s.active&&(this.logger.info(`Disconnecting dead webview ${a}`),this.disconnectPlaywrightFromWebview(s),s.active=!1);this.logger.info("Refreshed webviews")}async getActiveWebview(){await this.refreshPromise;let e=await this.driver.execute("mobile: getCurrentPackage"),t=async()=>{e!==void 0&&typeof e!="string"&&this.logger.warn({currentPkg:e},"Unexpected getCurrentPackage result"),this.logger.info({currentPkg:e,allWebviews:Array.from(this.webviews.values()).map(i=>({contextId:i.contextId,packageName:i.packageName,active:i.active}))},"getActiveWebview: filtering webviews");let o=[];for(let i of this.webviews.values())i.packageName===e&&i.active&&o.push(i);return this.logger.info(`getActiveWebview: found ${o.length} matching webviews`),o},n=await t();if(n.length===0&&(await se().startAsyncSection("Refresh webviews",async()=>{await this.refreshWebviewsManually("no matching webview during getActiveWebview")}),n=await t()),n.length>1)throw new R("UserInfrastructureError","Multiple active webviews in a single package is currently not supported");return n[0]}getDeviceSerial(){let e=this.driver.capabilities,t=n=>{if(!e||typeof e!="object")return;let o=e[n];return typeof o=="string"?o:void 0};return t("deviceUDID")||t("udid")||t("appium:udid")||t("appium:deviceUDID")}async executeRawADBCommand(e){let t=this.getDeviceSerial(),n=e.trim().split(/\s+/).filter(i=>i.length>0);this.logger.info({serial:t,cmdArgs:n},"Executing ADB command");let o=await kt(n,{serial:t,timeoutMs:15e3,throwOnError:!0});return this.logger.info({result:o},"ADB command result"),o}async cleanupWebviews(){this.refreshInterval&&(clearInterval(this.refreshInterval),this.refreshInterval=void 0);for(let[e,t]of this.webviews.entries())this.logger.info(`Disconnecting webview ${e}`),this.disconnectPlaywrightFromWebview(t),t.active=!1}async getDetailedContexts(){return await se().startAsyncSpan("EMULATOR_READ_STATE",async()=>{let t=await this.driver.execute("mobile: getContexts");this.aborter.controller?.signal.throwIfAborted();let n;try{n=zO.parse(t)}catch(o){throw new R("InternalWebAgentError",`Failed to parse contexts. Original error:
|
|
4588
4588
|
${o}
|
|
@@ -4593,7 +4593,7 @@ ${n.map(o=>o.configFilePath)}`);if(n.length===0)throw new Error("No valid Moment
|
|
|
4593
4593
|
`)){let o=n.indexOf("=");if(o===-1)continue;let i=n.slice(0,o),a=n.slice(o+1).trim();t[i]=a}return t}async function WY(r,e,t){try{let o=t["github.user"]||void 0;if(o)return o}catch{}let n;try{if(e?.startsWith("http://")||e?.startsWith("https://"))n=new URL(e).host;else if(e?.startsWith("git@")){let o=e.indexOf("@"),i=e.indexOf(":",o+1);o!==-1&&i!==-1&&(n=e.slice(o+1,i))}}catch{}if(n=n?.toLowerCase(),!!n){try{if(e?.startsWith("git@")&&n?.includes("github")){let{stdout:o,stderr:i}=await ZO("ssh",["-T","-o","BatchMode=yes",`git@${n}`],{timeout:5e3}),s=`${o??""}${i??""}`.trim().match(/Hi\s+([A-Za-z0-9_-]+)!/);if(s?.[1])return s[1]}}catch{}try{let o=n&&n!=="github.com"?["api","--hostname",n,"user","-q",".login"]:["api","user","-q",".login"],{stdout:i}=await ZO("gh",o,{timeout:5e3}),a=i?.toString().trim();if(a)return a}catch{}}}async function jY(r,e,t){let n=e?.includes("github.com"),o=e?.includes("gitlab.com");try{if(n)return WY(r,e,t);if(o)return}catch{}}function Mp(r){if(r.startsWith("git@")){let e=r.split(":");if(e.length===2){let t=e[1].replace(".git","").split("/");if(t.length===2){let n=t[0],o=t[1];return`${n}/${o}`}}}else if(r.startsWith("http")||r.startsWith("https")){let t=new URL(r).pathname.split("/").filter(Boolean);if(t.length>=2){let n=t[0],o=t[1].replace(".git","");return`${n}/${o}`}}}function VY(r){if(!(r instanceof Error))return!1;let e=r.message;return e.includes("not a git repository")||e.includes("ENOENT")}async function st(r,e){try{return(await e).trim()}catch(t){if(VY(t))return;r.error({err:t},"Failed to run git command");return}}function $Y(){if(process.env.GITHUB_ACTION)return"GithubActions";if(process.env.GITLAB_CI)return"GitlabCI";if(process.env.CIRCLECI)return"CircleCI";if(process.env.BUILDKITE)return"Buildkite";if(process.env["System.CollectionUri"]?.includes("azure"))return"AzureDevOps";if(process.env.PROJECT_ID&&process.env.BUILD_ID)return"GCPCloudBuild";if(process.env.MOMENTIC_GIT_OVERRIDE)return"Custom"}async function qY(r){let[e,t,n]=await Promise.all([st(r,at.show(["--no-patch","--format=%ci"])),st(r,at.show(["-s","--pretty=%B"])),st(r,at.show(["-s","--pretty=%an"]))]),o=process.env.GITHUB_SERVER_URL&&process.env.GITHUB_REPOSITORY?`${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}`:void 0;return{ciProvider:"GithubActions",gitCommitSha:process.env.GITHUB_SHA,gitCommitShaShort:process.env.GITHUB_SHA?.slice(0,6),gitCommitTimestamp:e?fo(e):void 0,gitBranchName:process.env.GITHUB_HEAD_REF||process.env.GITHUB_REF_NAME,gitOriginUrl:o,gitCommitMessage:t,gitCommitAuthorName:n,githubRepository:process.env.GITHUB_REPOSITORY,pipelineId:process.env.GITHUB_RUN_ID}}async function KY(r){let[e,t,n]=await Promise.all([st(r,at.listRemote(["--get-url","origin"])),st(r,at.show(["-s","--pretty=%B"])),st(r,at.show(["-s","--pretty=%an"]))]);return{ciProvider:"GitlabCI",gitCommitSha:process.env.CI_COMMIT_SHA,gitCommitShaShort:process.env.CI_COMMIT_SHORT_SHA,gitCommitTimestamp:process.env.CI_COMMIT_TIMESTAMP?fo(process.env.CI_COMMIT_TIMESTAMP):void 0,gitBranchName:process.env.CI_COMMIT_BRANCH||process.env.CI_COMMIT_REF_NAME,gitOriginUrl:e,gitCommitMessage:t,gitCommitAuthorName:n,gitlabProjectPath:process.env.CI_PROJECT_PATH,pipelineId:`${process.env.CI_PIPELINE_ID}:${process.env.CI_JOB_ID}`}}async function YY(r){let[e,t,n,o]=await Promise.all([st(r,at.show(["--no-patch","--format=%ci"])),st(r,at.listRemote(["--get-url","origin"])),st(r,at.show(["-s","--pretty=%B"])),st(r,at.show(["-s","--pretty=%an"]))]),i=process.env.CIRCLE_REPOSITORY_URL??t,a=i?.includes("github.com"),s=i?.includes("gitlab.com"),c=i?Mp(i):void 0;return{ciProvider:"CircleCI",gitCommitSha:process.env.CIRCLE_SHA1,gitCommitShaShort:process.env.CIRCLE_SHA1?.slice(0,6),gitCommitTimestamp:e?fo(e):void 0,gitBranchName:process.env.CIRCLE_BRANCH,gitOriginUrl:i,gitCommitMessage:n,gitCommitAuthorName:o,githubRepository:a?c:void 0,gitlabProjectPath:s?c:void 0,pipelineId:process.env.CIRCLE_PIPELINE_ID}}async function XY(r){let[e,t,n]=await Promise.all([st(r,at.show(["--no-patch","--format=%ci"])),st(r,at.show(["-s","--pretty=%B"])),st(r,at.show(["-s","--pretty=%an"]))]),o=process.env.BUILDKITE_REPO,i=o?.includes("github.com"),a=o?.includes("gitlab.com"),s=o?Mp(o):void 0;return{ciProvider:"Buildkite",gitCommitSha:process.env.BUILDKITE_COMMIT,gitCommitShaShort:process.env.BUILDKITE_COMMIT?.slice(0,6),gitCommitTimestamp:e?fo(e):void 0,gitBranchName:process.env.BUILDKITE_BRANCH,gitOriginUrl:o,gitCommitMessage:t,gitCommitAuthorName:n,githubRepository:i?s:void 0,gitlabProjectPath:a?s:void 0,pipelineId:`${process.env.BUILDKITE_PIPELINE_ID}:${process.env.BUILDKITE_BUILD_ID}:${process.env.BUILDKITE_JOB_ID}`}}async function JY(r){let[e,t,n]=await Promise.all([st(r,at.show(["--no-patch","--format=%ci"])),st(r,at.show(["-s","--pretty=%B"])),st(r,at.show(["-s","--pretty=%an"]))]),o=process.env["Build.Repository.Uri"],i=o?.includes("github.com"),a=o?.includes("gitlab.com"),s=o?Mp(o):void 0;return{ciProvider:"AzureDevOps",gitCommitSha:process.env["Build.SourceVersion"],gitCommitShaShort:process.env["Build.SourceVersion"]?.slice(0,6),gitCommitTimestamp:e?fo(e):void 0,gitBranchName:process.env["System.PullRequest.SourceBranch"]??process.env["Build.SourceBranchName"],gitOriginUrl:o,gitCommitMessage:t,gitCommitAuthorName:n,githubRepository:i?s:void 0,gitlabProjectPath:a?s:void 0,pipelineId:`${process.env["System.JobId"]}:${process.env["System.JobAttempt"]}`}}async function ZY(r,e){let[t,n,o,i,a,s,c,l,u]=await Promise.all([st(r,at.revparse(["HEAD"])),st(r,at.revparse(["--short","HEAD"])),st(r,at.revparse(["--abbrev-ref","HEAD"])),st(r,at.listRemote(["--get-url","origin"])),st(r,at.show(["--no-patch","--format=%ci"])),st(r,at.show(["-s","--pretty=%B"])),st(r,at.show(["-s","--pretty=%an"])),e?st(r,at.raw(["merge-base","--fork-point",e])):Promise.resolve(void 0),GY(r)]),d=l?await st(r,at.show(["--no-patch","--format=%ci",l])):void 0,p=i?.includes("github.com"),m=i?.includes("gitlab.com"),g=i?Mp(i):void 0,h=u["user.email"]||void 0,f=u["user.name"]||void 0,y=u["user.username"]||void 0,E=await jY(r,i,u)??y??void 0;return{ciProvider:"none",gitCommitSha:t,gitCommitShaShort:n,gitBranchName:o,gitOriginUrl:i,gitCommitTimestamp:a?fo(a):void 0,gitCommitMessage:s,gitCommitAuthorName:c,gitLocalUsername:E,gitLocalEmail:h,gitLocalName:f,lastCommitOnMainSha:l,lastCommitOnMainTimestamp:d?fo(d):void 0,githubRepository:p?g:void 0,gitlabProjectPath:m?g:void 0,pipelineId:void 0}}async function QY(){let r=process.env._HEAD_REPO_URL;return{ciProvider:"GCPCloudBuild",gitCommitSha:process.env.COMMIT_SHA,gitCommitShaShort:process.env.COMMIT_SHA?.slice(0,6),gitBranchName:process.env.BRANCH_NAME,gitOriginUrl:r?process.env._HEAD_REPO_URL:void 0,gitCommitTimestamp:void 0,gitCommitMessage:void 0,gitCommitAuthorName:void 0,githubRepository:r?process.env.REPO_FULL_NAME:void 0,pipelineId:`${process.env.PROJECT_ID}:${process.env.BUILD_ID}`}}function e4(){return{ciProvider:"Custom",gitCommitSha:process.env.GIT_COMMIT_SHA,gitCommitShaShort:process.env.GIT_COMMIT_SHA_SHORT??process.env.GIT_COMMIT_SHA?.slice(0,6),gitCommitTimestamp:fo(process.env.GIT_COMMIT_TIMESTAMP),gitBranchName:process.env.GIT_BRANCH_NAME,gitOriginUrl:process.env.GIT_ORIGIN_URL,gitCommitAuthorName:process.env.GIT_COMMIT_AUTHOR_NAME,gitCommitMessage:process.env.GIT_COMMIT_MESSAGE,lastCommitOnMainSha:process.env.LAST_COMMIT_ON_MAIN_SHA,lastCommitOnMainTimestamp:fo(process.env.LAST_COMMIT_ON_MAIN_TIMESTAMP),mergedGitBranchName:process.env.MERGED_GIT_BRANCH_NAME,githubRepository:process.env.GITHUB_REPOSITORY,gitlabProjectPath:process.env.GITLAB_PROJECT_PATH,gitLocalUsername:process.env.GIT_USERNAME,gitLocalEmail:process.env.GIT_EMAIL,gitLocalName:process.env.GIT_NAME}}async function t4(r){let e=[...r.config.gitProtectedBranches??[]];return r.config.gitMainBranch&&e.push(r.config.gitMainBranch),{gitMainBranch:r.config.gitMainBranch,gitProtectedBranches:e}}async function mu(r,e){let t=$Y();if(!t)return ZY(r,e);switch(t){case"GithubActions":return qY(r);case"GitlabCI":return KY(r);case"CircleCI":return YY(r);case"Buildkite":return XY(r);case"AzureDevOps":return JY(r);case"GCPCloudBuild":return QY();case"Custom":return e4()}}async function r4(r,e,t,n){let o=n;if(!n.gitCommitSha)return o;if(n.gitMainBranch&&(!o.lastCommitOnMainSha||!o.lastCommitOnMainTimestamp))try{let i=await e.getMergeBaseCommitFromGitlab(t,n.gitMainBranch,n.gitCommitSha);o={...o,lastCommitOnMainSha:i.sha,lastCommitOnMainTimestamp:i.committer.date}}catch(i){r.warn({err:i},"Failed to get merge base commit from Gitlab")}if(!o.gitCommitTimestamp||!o.gitCommitAuthorName||!o.gitCommitMessage||!o.gitCommitAuthorName)try{let i=await e.getCommitFromGitlab(t,n.gitCommitSha);i&&(o={...o,gitCommitTimestamp:o.gitCommitTimestamp??i.committer.date,gitCommitAuthorName:o.gitCommitAuthorName??i.author.name,gitCommitMessage:o.gitCommitMessage??i.message})}catch(i){r.warn({err:i},"Failed to get commit from Gitlab")}if(n.gitBranchName&&n.gitBranchName===n.gitMainBranch&&!o.mergedGitBranchName)try{let i=await e.getMergedBranchFromGitlab(t,n.gitBranchName??"",n.gitCommitSha);i.mergedBranch&&(o={...o,mergedGitBranchName:i.mergedBranch})}catch(i){r.warn({err:i},"Failed to get merged branch from Gitlab")}return o}async function n4(r,e,t,n,o){let i=o;if(!o.gitCommitSha)return i;if(o.gitMainBranch&&(!i.lastCommitOnMainSha||!i.lastCommitOnMainTimestamp))try{let a=await e.getMergeBaseCommitFromGithub(t,n,o.gitMainBranch,o.gitCommitSha);i={...i,lastCommitOnMainSha:a.sha,lastCommitOnMainTimestamp:a.committer.date}}catch(a){r.warn({err:a},"Failed to get merge base commit from GitHub")}if(!i.gitCommitTimestamp||!i.gitCommitAuthorName||!i.gitCommitMessage||!i.gitCommitAuthorName)try{let a=await e.getCommitFromGithub(t,n,o.gitCommitSha);a&&(i={...i,gitCommitTimestamp:i.gitCommitTimestamp??a.committer.date,gitCommitAuthorName:i.gitCommitAuthorName??a.author.name,gitCommitMessage:i.gitCommitMessage??a.message})}catch(a){r.warn({err:a},"Failed to get commit from GitHub")}if(o.gitBranchName&&o.gitBranchName===o.gitMainBranch&&!i.mergedGitBranchName)try{let a=await e.getMergedBranchFromGithub(t,n,o.gitBranchName??"",o.gitCommitSha);a.mergedBranch&&(i={...i,mergedGitBranchName:a.mergedBranch})}catch(a){r.warn({err:a},"Failed to get merged branch from GitHub")}return i}async function o4(r,e,t){try{if(t.githubRepository){let[n,o]=t.githubRepository.split("/");return await n4(r,e,n,o,t)}else if(t.gitlabProjectPath)return await r4(r,e,t.gitlabProjectPath,t)}catch(n){r.warn({err:n},"Failed to get remote git metadata")}return t}async function sn(r,e,t){let n=await t4(t),o=await mu(r,n.gitMainBranch),i={...n,...o};(!i.lastCommitOnMainSha||!i.lastCommitOnMainTimestamp)&&i.gitBranchName===n.gitMainBranch&&(i.lastCommitOnMainSha=i.gitCommitSha,i.lastCommitOnMainTimestamp=i.gitCommitTimestamp);let a=await o4(r,e,i);return{...n,...o,...a}}import{diff as QO}from"deep-object-diff";import ai from"fs";import{cloneDeep as i4}from"lodash-es";import Pp from"path";import{v4 as a4}from"uuid";import pu from"yaml";function eL(r,e){let t=`${gn(e)}.module.yaml`,n=Pp.join(Pp.dirname(r),t);if(ai.existsSync(n))throw new Error(`A conflicting file already exists at the following path: ${n}`);return ai.renameSync(r,n),n}function tL({content:r,schemaVersion:e,momenticFiles:t,project:n,forceSaveOnNoDiffs:o}){let i=t.mobileModules[r.moduleId]?.fullFilePath,a=t.mobileModules[r.moduleId]?.name;if(!i||!ai.existsSync(i))throw new Error(`Tried to update mobile module ${r.moduleId} that could not be found on disk`);let s=ai.readFileSync(i,"utf-8"),c=pu.parse(s),l={...c,...r,schemaVersion:e},u=po({fileType:Xe.MOBILE_MODULE,...cc.parse(l),steps:Kr.array().parse(r.steps)}),d=!!r.name&&r.name!==a,p=QO(u,c);if(p&&Object.keys(p).length===0&&!o&&!d)return;let m=pu.stringify(u);ai.writeFileSync(i,m,"utf-8");let g;d&&(g=eL(i,r.name)),Vn(g||i,n.config)}function rL({moduleId:r,patch:e,momenticFiles:t,project:n,logger:o}){let i=t.mobileModules[r]?.fullFilePath;if(!i)throw new Error(`Tried to update mobile module ${r} that could not be found on disk`);let a=gu(i,o),s={...a,...e},c=po({fileType:Xe.MOBILE_MODULE,...hd.parse(s)}),l=QO(c,a);if(l&&Object.keys(l).length===0)return;let u=pu.stringify(c);ai.writeFileSync(i,u,"utf-8");let d;e.name&&(d=eL(i,e.name)),Vn(d||i,n.config)}async function nL({name:r,description:e,enabled:t,steps:n,folder:o,project:i}){let a=gn(r),s=Pp.join(o,`${a}.module.yaml`),c=a4(),{stepsToSave:l}=await zn({platform:"ANDROID",steps:n}),u={schemaVersion:xo,moduleId:c,description:e,enabled:t},d={fileType:Xe.MOBILE_MODULE,...u,steps:l},p=pu.stringify(TA.parse(d));return ai.writeFileSync(s,p,"utf-8"),Vn(s,i.config),{moduleId:c,name:r,description:e||void 0,steps:n}}function gu(r,e){let t=ai.readFileSync(r,"utf-8"),n=pu.parse(t);try{return{...hd.parse(n),name:Pp.basename(r,".module.yaml")}}catch(o){throw e.error({err:o,moduleFilePath:r,moduleContents:t},`${r} does not parse as a valid Momentic mobile module`),o}}async function qy(r,e,t,n){let o=gu(r.fullFilePath,t),{resolvedSteps:i}=await Zc({rawSteps:o.steps,resolvedModuleCache:n||{},onFetchModule:async s=>{let c=e.mobileModules[s]?.fullFilePath;if(!c)throw new Error(`Could not find mobile module with id ${s}`);return gu(c,t)},logger:t,metadata:{id:o.moduleId,schemaVersion:o.schemaVersion}}),a={...o,name:r.name,description:o.description||void 0,steps:i};return n&&(n[r.id]=i4(a)),a}async function oL(r,e){let t={};return await Promise.all(Object.values(r.mobileModules).map(async n=>{await qy(n,r,e,t)})),Array.from(Object.values(t))}import{randomUUID as s4}from"crypto";import ln from"fs";import si from"path";import qs from"yaml";import $s from"zod";function iL({name:r,description:e="",steps:t=[],settings:n={},folder:o}){let a=`${gn(r)}.test.yaml`,s=si.join(o,a);if(ln.existsSync(s))throw new Error(`A test named '${r}' already exists at path '${s}'. Choose a different name.`);let c={fileType:Xe.MOBILE_TEST,id:s4(),description:e,schemaVersion:_o,platform:"ANDROID",settings:n,steps:t},l=qs.stringify(c);return ln.writeFileSync(s,l,"utf-8"),{fullPath:s,testId:c.id}}function Ky(r){if(!ln.existsSync(r))throw new Error(`Test file not found: ${r}`);let e=ln.readFileSync(r,"utf-8").replace(/\r\n|\r/g,`
|
|
4594
4594
|
`),t=qs.parse(e);if(!t.steps||!Array.isArray(t.steps))throw new Error(`Test ${r} is missing steps`);return t}async function So(r,e,t){let n=Ky(r),o;try{o=Do.parse(n)}catch(i){throw new Error(`Mobile test ${r} is missing metadata or has invalid metadata: ${i}`)}switch(o.platform){case"ANDROID":return l4(r,e,t);case"IOS":return c4(r,e,t)}}async function l4(r,e,t){let n=Ky(r),o;try{o=as.parse(n)}catch(s){throw new Error(`Mobile test ${r} is missing metadata or has invalid metadata: ${s}`)}let{resolvedStepLists:i}=await WS({rawStepLists:{steps:n.steps,beforeSteps:n.beforeSteps,afterSteps:n.afterSteps},logger:e,testMetadata:o,onFetchModule:async s=>{let c=t.mobileModules[s]?.fullFilePath;if(!c)throw new Error(`Mobile module ${s} not found`);return gu(c,e)}});return{...o,steps:i.steps}}async function c4(r,e,t){let n=Ky(r),o;try{o=ss.parse(n)}catch(s){throw new Error(`Mobile test ${r} is missing metadata or has invalid metadata: ${s}`)}let{resolvedStepLists:i}=await GS({rawStepLists:{steps:n.steps,beforeSteps:n.beforeSteps,afterSteps:n.afterSteps},logger:e,testMetadata:o,onFetchModule:async s=>{throw new Error("iOS modules are not yet supported")}});return{...o,steps:i.steps}}async function aL({filePath:r,steps:e,settings:t,labels:n,folder:o,project:i,momenticFiles:a,schemaVersion:s}){let c=si.isAbsolute(r)?r:si.join(o,r);if(!ln.existsSync(c))throw new Error(`Test file not found: ${c}`);let l=ln.readFileSync(c,"utf-8").replace(/\r\n|\r/g,`
|
|
4595
4595
|
`),u=qs.parse(l),d=uc.extend({steps:$s.record($s.string(),$s.unknown()).array()}).parse({...u,schemaVersion:s});if(d.fileType!==Xe.MOBILE_TEST)throw new Error(`File at '${c}' is not a mobile test (fileType=${d.fileType}).`);let p;e&&(p=await zn({platform:d.platform,steps:e}));let m={...d,...p?.stepsToSave!==void 0?{steps:p.stepsToSave}:{steps:d.steps},...n!==void 0?{labels:n}:{}};t&&(m.settings=t);let g=qs.stringify(m);for(let h of p?.moduleUpdates??[])tL({content:h,schemaVersion:_o,momenticFiles:a,project:i});ln.writeFileSync(c,g,"utf-8"),Vn(c,i.config)}function sL(r,e,t){let n=si.join(t.rootDir,r);if(!ln.existsSync(n))throw new Error(`Test not found at path '${r}' in project '${t.rootDir}'`);let o=ln.readFileSync(n,"utf-8").replace(/\r\n|\r/g,`
|
|
4596
|
-
`),i=qs.parse(o),a=uc.extend({steps:$s.record($s.string(),$s.unknown()).array()}).parse(i),s=si.basename(r,".test.yaml"),c,l;if(e.name&&e.name!==s){let p=`${gn(e.name)}.test.yaml`;if(c=si.join(si.dirname(r),p),l=si.join(t.rootDir,c),ln.existsSync(l))throw new Error(`Test with name '${e.name}' already exists at path '${l}'`)}let u={...a,...e};if(delete u.name,u.fileType!==Xe.MOBILE_TEST)throw new Error(`File at '${n}' is not a mobile test (fileType=${u.fileType}).`);let d=qs.stringify(u);return ln.writeFileSync(n,d,"utf-8"),l&&l!==n?(ln.renameSync(n,l),Vn(l,t.config)):Vn(n,t.config),{newRelativeTestPath:c}}import{randomUUID as u4}from"crypto";import li from"fs";import Ks from"path";var lL=new Set([".DS_Store","__MACOSX"]),cL={status:(r,e)=>{if(r.status===e.status)return r.status;if(r.status==="FAILED"||e.status==="FAILED")return"FAILED";if(r.status==="CANCELLED"||e.status==="CANCELLED")return"CANCELLED";if(r.status==="RETRYING"||e.status==="RETRYING")return"RETRYING";if(r.status==="RUNNING"||e.status==="RUNNING")return"RUNNING";if(r.status==="PENDING"||e.status==="PENDING")return"PENDING";throw new Error(`Invalid run status merge: ${r.status} and ${e.status}`)},startedAt:(r,e)=>r.startedAt<e.startedAt?r.startedAt:e.startedAt,updatedAt:(r,e)=>r.updatedAt>e.updatedAt?r.updatedAt:e.updatedAt,finishedAt:(r,e)=>!r.finishedAt||!e.finishedAt?new Date:r.finishedAt>e.finishedAt?r.finishedAt:e.finishedAt,gitCommitTimestamp:(r,e)=>{if(!(!r&&!e)){if(!r.gitCommitTimestamp||!e.gitCommitTimestamp||r.gitCommitTimestamp.getTime()!==e.gitCommitTimestamp.getTime())throw new Error(`Git commit timestamps must match to be merged: ${r.gitCommitTimestamp} and ${e.gitCommitTimestamp}`);return r.gitCommitTimestamp}},pipelineId:(r,e)=>r.pipelineId===e.pipelineId?r.pipelineId:!r.pipelineId&&e.pipelineId?e.pipelineId:!e.pipelineId&&r.pipelineId?r.pipelineId:r.startedAt<e.startedAt?e.pipelineId:r.pipelineId,labels:(r,e)=>{let t=new Set([...r.labels??[],...e.labels??[]]);return Array.from(t)}};function d4(r,e,t){if(cL[t]){let i=cL[t];return i(r,e)}let n=r[t],o=e[t];if(n!==o)throw new Error(`Metadata values for key "${t}" do not match: "${n}" vs "${o}"`);return n}var Yy=class extends Error{constructor(e,t){let n=`${e} contains invalid Momentic results: ${t}. Please ensure that the path points to a folder containing only valid results. If you passed \`--output-dir test-results/results-1\` to the \`run\` command, your results path for merging should be \`test-results\`.`;super(n),this.name="InvalidMomenticResultsPathError"}};function uL(r,e){try{let t=Ks.join(e,"metadata.json");return us.parse(JSON.parse(li.readFileSync(t,"utf-8")))}catch{throw new Yy(r,e)}}function dL(r,e,t){let n=u4(),o=r.child({runGroupId:n});li.rmSync(e,{recursive:!0,force:!0});let i=li.readdirSync(t).filter(c=>!lL.has(c)).map(c=>Ks.join(t,c));if(i.length===0)throw new Error(`No run groups found in results path: ${t}`);li.mkdirSync(e,{recursive:!0});let a={...uL(t,i[0]),id:n};for(let c of i){let l=Ks.join(c,"runs");if(!li.existsSync(l))continue;let u=uL(t,c);o.info({oldRunGroupId:u.id},"Merging run groups");for(let p in u){if(p==="id")continue;let m=p;a[m]=d4(a,u,m)}let d=li.readdirSync(l);for(let p of d){if(lL.has(p))continue;let m=Ks.join(l,p),g=Ks.join(e,"runs",p);li.cpSync(m,g,{recursive:!0})}}let s=Ks.join(e,"metadata.json");li.writeFileSync(s,JSON.stringify(a,null,2))}import t0 from"adm-zip";import Sb from"fs";import{z as e3}from"zod";var j="v1",Xy="mobile-cli",ha="0.
|
|
4596
|
+
`),i=qs.parse(o),a=uc.extend({steps:$s.record($s.string(),$s.unknown()).array()}).parse(i),s=si.basename(r,".test.yaml"),c,l;if(e.name&&e.name!==s){let p=`${gn(e.name)}.test.yaml`;if(c=si.join(si.dirname(r),p),l=si.join(t.rootDir,c),ln.existsSync(l))throw new Error(`Test with name '${e.name}' already exists at path '${l}'`)}let u={...a,...e};if(delete u.name,u.fileType!==Xe.MOBILE_TEST)throw new Error(`File at '${n}' is not a mobile test (fileType=${u.fileType}).`);let d=qs.stringify(u);return ln.writeFileSync(n,d,"utf-8"),l&&l!==n?(ln.renameSync(n,l),Vn(l,t.config)):Vn(n,t.config),{newRelativeTestPath:c}}import{randomUUID as u4}from"crypto";import li from"fs";import Ks from"path";var lL=new Set([".DS_Store","__MACOSX"]),cL={status:(r,e)=>{if(r.status===e.status)return r.status;if(r.status==="FAILED"||e.status==="FAILED")return"FAILED";if(r.status==="CANCELLED"||e.status==="CANCELLED")return"CANCELLED";if(r.status==="RETRYING"||e.status==="RETRYING")return"RETRYING";if(r.status==="RUNNING"||e.status==="RUNNING")return"RUNNING";if(r.status==="PENDING"||e.status==="PENDING")return"PENDING";throw new Error(`Invalid run status merge: ${r.status} and ${e.status}`)},startedAt:(r,e)=>r.startedAt<e.startedAt?r.startedAt:e.startedAt,updatedAt:(r,e)=>r.updatedAt>e.updatedAt?r.updatedAt:e.updatedAt,finishedAt:(r,e)=>!r.finishedAt||!e.finishedAt?new Date:r.finishedAt>e.finishedAt?r.finishedAt:e.finishedAt,gitCommitTimestamp:(r,e)=>{if(!(!r&&!e)){if(!r.gitCommitTimestamp||!e.gitCommitTimestamp||r.gitCommitTimestamp.getTime()!==e.gitCommitTimestamp.getTime())throw new Error(`Git commit timestamps must match to be merged: ${r.gitCommitTimestamp} and ${e.gitCommitTimestamp}`);return r.gitCommitTimestamp}},pipelineId:(r,e)=>r.pipelineId===e.pipelineId?r.pipelineId:!r.pipelineId&&e.pipelineId?e.pipelineId:!e.pipelineId&&r.pipelineId?r.pipelineId:r.startedAt<e.startedAt?e.pipelineId:r.pipelineId,labels:(r,e)=>{let t=new Set([...r.labels??[],...e.labels??[]]);return Array.from(t)}};function d4(r,e,t){if(cL[t]){let i=cL[t];return i(r,e)}let n=r[t],o=e[t];if(n!==o)throw new Error(`Metadata values for key "${t}" do not match: "${n}" vs "${o}"`);return n}var Yy=class extends Error{constructor(e,t){let n=`${e} contains invalid Momentic results: ${t}. Please ensure that the path points to a folder containing only valid results. If you passed \`--output-dir test-results/results-1\` to the \`run\` command, your results path for merging should be \`test-results\`.`;super(n),this.name="InvalidMomenticResultsPathError"}};function uL(r,e){try{let t=Ks.join(e,"metadata.json");return us.parse(JSON.parse(li.readFileSync(t,"utf-8")))}catch{throw new Yy(r,e)}}function dL(r,e,t){let n=u4(),o=r.child({runGroupId:n});li.rmSync(e,{recursive:!0,force:!0});let i=li.readdirSync(t).filter(c=>!lL.has(c)).map(c=>Ks.join(t,c));if(i.length===0)throw new Error(`No run groups found in results path: ${t}`);li.mkdirSync(e,{recursive:!0});let a={...uL(t,i[0]),id:n};for(let c of i){let l=Ks.join(c,"runs");if(!li.existsSync(l))continue;let u=uL(t,c);o.info({oldRunGroupId:u.id},"Merging run groups");for(let p in u){if(p==="id")continue;let m=p;a[m]=d4(a,u,m)}let d=li.readdirSync(l);for(let p of d){if(lL.has(p))continue;let m=Ks.join(l,p),g=Ks.join(e,"runs",p);li.cpSync(m,g,{recursive:!0})}}let s=Ks.join(e,"metadata.json");li.writeFileSync(s,JSON.stringify(a,null,2))}import t0 from"adm-zip";import Sb from"fs";import{z as e3}from"zod";var j="v1",Xy="mobile-cli",ha="0.34.0";var m4=9e4,p4=3,g4=1500,h4=15e3,En=class extends Error{status;rawError;constructor(e,t,n,o={}){super(n,o),this.status=e,this.rawError=t}};async function f4(r){return r.text().then(e=>{try{return JSON.parse(e).error}catch{return e}})}var Jy=class{baseUrl;logger;constructor(e){this.baseUrl=e.baseUrl,this.logger=e.logger}getHeaders(){let e={"Content-Type":"application/json"};return ha&&(e[xd]=ha),Xy&&(e[uR]=Xy),e}async sendRequest(e,t){let{retries:n=p4,requestTimeoutMs:o=m4,initialRetryDelayMs:i=g4,maxRetryDelayMs:a=h4,onFailedRequest:s}=t,c=n,l=n,u,d={path:e,baseUrl:this.baseUrl,method:t.method};for(;c>0;)try{return c--,await this.sendSingleRequestHelper(e,t,o)}catch(p){u=p;try{s?.(u)}catch{}if(p instanceof En&&p.status>=400&&p.status<500)throw p;if(p instanceof Error&&p.name==="AbortError"&&(u=new Ho),c===0)throw u;let m=l-c,g=Math.min(i*Math.pow(2,m-1),a);await new Promise(h=>setTimeout(h,g))}throw this.logger.warn({...d,err:u},"Got fatal error response from Momentic server"),u}async sendSingleRequestHelper(e,t,n){let o={path:e,baseUrl:this.baseUrl,method:t.method},i=new AbortController,a=setTimeout(()=>i.abort(),n),s=()=>i.abort();t.signal&&t.signal.addEventListener("abort",s,{once:!0});let c=Date.now(),l={...this.getHeaders(),...t.extraHeaders};try{let u=await fetch(`${this.baseUrl}${e}`,{method:t.method,body:t.body?JSON.stringify(t.body):void 0,headers:l,signal:i.signal});if(!u.ok){let m=await f4(u);throw new En(u.status,m,`Request to ${t.method} ${e} failed with status ${u.status}: ${m}`)}let d;if(u.status===204)d={};else if(t.responseType==="buffer"){let m=await u.arrayBuffer();d=Buffer.from(m)}else{let m=await u.text();try{d=JSON.parse(m)}catch{d=m}}this.logger&&t.logResponse===!0&&d&&this.logger.debug({result:d,status:u.status,durationMs:Date.now()-c,...o},"Got response from Momentic server");let p=t.responseHeadersObject;return p&&u.headers.forEach((m,g)=>{p[g.toLowerCase()]=m}),d}finally{clearTimeout(a),t.signal&&t.signal.removeEventListener("abort",s)}}},$n=class extends Jy{apiKey;mode;constructor(e){super(e),this.apiKey=e.apiKey,this.mode=e.mode}getHeaders(){return{...super.getHeaders(),Authorization:`Bearer ${this.apiKey}`,[cR]:this.mode??""}}};import{createAnthropic as QX}from"@ai-sdk/anthropic";var zL="vercel.ai.error",S4=Symbol.for(zL),mL,pL,lt=class HL extends(pL=Error,mL=S4,pL){constructor({name:e,message:t,cause:n}){super(t),this[mL]=!0,this.name=e,this.cause=n}static isInstance(e){return HL.hasMarker(e,zL)}static hasMarker(e,t){let n=Symbol.for(t);return e!=null&&typeof e=="object"&&n in e&&typeof e[n]=="boolean"&&e[n]===!0}},GL="AI_APICallError",WL=`vercel.ai.error.${GL}`,y4=Symbol.for(WL),gL,hL,ar=class extends(hL=lt,gL=y4,hL){constructor({message:r,url:e,requestBodyValues:t,statusCode:n,responseHeaders:o,responseBody:i,cause:a,isRetryable:s=n!=null&&(n===408||n===409||n===429||n>=500),data:c}){super({name:GL,message:r,cause:a}),this[gL]=!0,this.url=e,this.requestBodyValues=t,this.statusCode=n,this.responseHeaders=o,this.responseBody=i,this.isRetryable=s,this.data=c}static isInstance(r){return lt.hasMarker(r,WL)}},jL="AI_EmptyResponseBodyError",VL=`vercel.ai.error.${jL}`,b4=Symbol.for(VL),fL,SL,$L=class extends(SL=lt,fL=b4,SL){constructor({message:r="Empty response body"}={}){super({name:jL,message:r}),this[fL]=!0}static isInstance(r){return lt.hasMarker(r,VL)}};function qL(r){return r==null?"unknown error":typeof r=="string"?r:r instanceof Error?r.message:JSON.stringify(r)}var KL="AI_InvalidArgumentError",YL=`vercel.ai.error.${KL}`,E4=Symbol.for(YL),yL,bL,Ip=class extends(bL=lt,yL=E4,bL){constructor({message:r,cause:e,argument:t}){super({name:KL,message:r,cause:e}),this[yL]=!0,this.argument=t}static isInstance(r){return lt.hasMarker(r,YL)}},XL="AI_InvalidPromptError",JL=`vercel.ai.error.${XL}`,T4=Symbol.for(JL),EL,TL,ZL=class extends(TL=lt,EL=T4,TL){constructor({prompt:r,message:e,cause:t}){super({name:XL,message:`Invalid prompt: ${e}`,cause:t}),this[EL]=!0,this.prompt=r}static isInstance(r){return lt.hasMarker(r,JL)}},QL="AI_InvalidResponseDataError",eN=`vercel.ai.error.${QL}`,v4=Symbol.for(eN),vL,AL,Op=class extends(AL=lt,vL=v4,AL){constructor({data:r,message:e=`Invalid response data: ${JSON.stringify(r)}.`}){super({name:QL,message:e}),this[vL]=!0,this.data=r}static isInstance(r){return lt.hasMarker(r,eN)}},tN="AI_JSONParseError",rN=`vercel.ai.error.${tN}`,A4=Symbol.for(rN),RL,wL,hu=class extends(wL=lt,RL=A4,wL){constructor({text:r,cause:e}){super({name:tN,message:`JSON parsing failed: Text: ${r}.
|
|
4597
4597
|
Error message: ${qL(e)}`,cause:e}),this[RL]=!0,this.text=r}static isInstance(r){return lt.hasMarker(r,rN)}},nN="AI_LoadAPIKeyError",oN=`vercel.ai.error.${nN}`,R4=Symbol.for(oN),CL,xL,fu=class extends(xL=lt,CL=R4,xL){constructor({message:r}){super({name:nN,message:r}),this[CL]=!0}static isInstance(r){return lt.hasMarker(r,oN)}},iN="AI_LoadSettingError",aN=`vercel.ai.error.${iN}`,w4=Symbol.for(aN),_L,ML,H3e=class extends(ML=lt,_L=w4,ML){constructor({message:r}){super({name:iN,message:r}),this[_L]=!0}static isInstance(r){return lt.hasMarker(r,aN)}},sN="AI_NoContentGeneratedError",lN=`vercel.ai.error.${sN}`,C4=Symbol.for(lN),PL,IL,G3e=class extends(IL=lt,PL=C4,IL){constructor({message:r="No content generated."}={}){super({name:sN,message:r}),this[PL]=!0}static isInstance(r){return lt.hasMarker(r,lN)}},cN="AI_NoSuchModelError",uN=`vercel.ai.error.${cN}`,x4=Symbol.for(uN),OL,LL,W3e=class extends(LL=lt,OL=x4,LL){constructor({errorName:r=cN,modelId:e,modelType:t,message:n=`No such ${t}: ${e}`}){super({name:r,message:n}),this[OL]=!0,this.modelId=e,this.modelType=t}static isInstance(r){return lt.hasMarker(r,uN)}},dN="AI_TooManyEmbeddingValuesForCallError",mN=`vercel.ai.error.${dN}`,_4=Symbol.for(mN),NL,DL,pN=class extends(DL=lt,NL=_4,DL){constructor(r){super({name:dN,message:`Too many values for a single embedding call. The ${r.provider} model "${r.modelId}" can only embed up to ${r.maxEmbeddingsPerCall} values per call, but ${r.values.length} values were provided.`}),this[NL]=!0,this.provider=r.provider,this.modelId=r.modelId,this.maxEmbeddingsPerCall=r.maxEmbeddingsPerCall,this.values=r.values}static isInstance(r){return lt.hasMarker(r,mN)}},gN="AI_TypeValidationError",hN=`vercel.ai.error.${gN}`,M4=Symbol.for(hN),kL,FL,ci=class Zy extends(FL=lt,kL=M4,FL){constructor({value:e,cause:t}){super({name:gN,message:`Type validation failed: Value: ${JSON.stringify(e)}.
|
|
4598
4598
|
Error message: ${qL(t)}`,cause:t}),this[kL]=!0,this.value=e}static isInstance(e){return lt.hasMarker(e,hN)}static wrap({value:e,cause:t}){return Zy.isInstance(t)&&t.value===e?t:new Zy({value:e,cause:t})}},fN="AI_UnsupportedFunctionalityError",SN=`vercel.ai.error.${fN}`,P4=Symbol.for(SN),UL,BL,xr=class extends(BL=lt,UL=P4,BL){constructor({functionality:r,message:e=`'${r}' functionality not supported.`}){super({name:fN,message:e}),this[UL]=!0,this.functionality=r}static isInstance(r){return lt.hasMarker(r,SN)}};var Lp=class extends Error{constructor(e,t){super(e),this.name="ParseError",this.type=t.type,this.field=t.field,this.value=t.value,this.line=t.line}};function Qy(r){}function yN(r){if(typeof r=="function")throw new TypeError("`callbacks` must be an object, got a function instead. Did you mean `{onEvent: fn}`?");let{onEvent:e=Qy,onError:t=Qy,onRetry:n=Qy,onComment:o}=r,i="",a=!0,s,c="",l="";function u(h){let f=a?h.replace(/^\xEF\xBB\xBF/,""):h,[y,E]=I4(`${i}${f}`);for(let b of y)d(b);i=E,a=!1}function d(h){if(h===""){m();return}if(h.startsWith(":")){o&&o(h.slice(h.startsWith(": ")?2:1));return}let f=h.indexOf(":");if(f!==-1){let y=h.slice(0,f),E=h[f+1]===" "?2:1,b=h.slice(f+E);p(y,b,h);return}p(h,"",h)}function p(h,f,y){switch(h){case"event":l=f;break;case"data":c=`${c}${f}
|
|
4599
4599
|
`;break;case"id":s=f.includes("\0")?void 0:f;break;case"retry":/^\d+$/.test(f)?n(parseInt(f,10)):t(new Lp(`Invalid \`retry\` value: "${f}"`,{type:"invalid-retry",value:f,line:y}));break;default:t(new Lp(`Unknown field "${h.length>20?`${h.slice(0,20)}\u2026`:h}"`,{type:"unknown-field",field:h,value:f,line:y}));break}}function m(){c.length>0&&e({id:s,event:l||void 0,data:c.endsWith(`
|
|
@@ -4614,7 +4614,7 @@ ${a}
|
|
|
4614
4614
|
`;break}case"tool":throw new xr({functionality:"tool messages"});default:{let a=o;throw new Error(`Unsupported role: ${a}`)}}return n+=`${t}:
|
|
4615
4615
|
`,{prompt:n,stopSequences:[`
|
|
4616
4616
|
${e}:`]}}function UN({id:r,model:e,created:t}){return{id:r??void 0,modelId:e??void 0,timestamp:t!=null?new Date(t*1e3):void 0}}function BN(r){switch(r){case"stop":return"stop";case"length":return"length";case"content_filter":return"content-filter";case"function_call":case"tool_calls":return"tool-calls";default:return"unknown"}}var X5=ot(()=>me(be.object({id:be.string().nullish(),created:be.number().nullish(),model:be.string().nullish(),choices:be.array(be.object({text:be.string(),finish_reason:be.string(),logprobs:be.object({tokens:be.array(be.string()),token_logprobs:be.array(be.number()),top_logprobs:be.array(be.record(be.string(),be.number())).nullish()}).nullish()})),usage:be.object({prompt_tokens:be.number(),completion_tokens:be.number(),total_tokens:be.number()}).nullish()}))),J5=ot(()=>me(be.union([be.object({id:be.string().nullish(),created:be.number().nullish(),model:be.string().nullish(),choices:be.array(be.object({text:be.string(),finish_reason:be.string().nullish(),index:be.number(),logprobs:be.object({tokens:be.array(be.string()),token_logprobs:be.array(be.number()),top_logprobs:be.array(be.record(be.string(),be.number())).nullish()}).nullish()})),usage:be.object({prompt_tokens:be.number(),completion_tokens:be.number(),total_tokens:be.number()}).nullish()}),mb]))),zN=ot(()=>me(Kn.object({echo:Kn.boolean().optional(),logitBias:Kn.record(Kn.string(),Kn.number()).optional(),suffix:Kn.string().optional(),user:Kn.string().optional(),logprobs:Kn.union([Kn.boolean(),Kn.number()]).optional()}))),Z5=class{constructor(r,e){this.specificationVersion="v2",this.supportedUrls={},this.modelId=r,this.config=e}get providerOptionsName(){return this.config.provider.split(".")[0].trim()}get provider(){return this.config.provider}async getArgs({prompt:r,maxOutputTokens:e,temperature:t,topP:n,topK:o,frequencyPenalty:i,presencePenalty:a,stopSequences:s,responseFormat:c,tools:l,toolChoice:u,seed:d,providerOptions:p}){let m=[],g={...await Tr({provider:"openai",providerOptions:p,schema:zN}),...await Tr({provider:this.providerOptionsName,providerOptions:p,schema:zN})};o!=null&&m.push({type:"unsupported-setting",setting:"topK"}),l?.length&&m.push({type:"unsupported-setting",setting:"tools"}),u!=null&&m.push({type:"unsupported-setting",setting:"toolChoice"}),c!=null&&c.type!=="text"&&m.push({type:"unsupported-setting",setting:"responseFormat",details:"JSON response format is not supported."});let{prompt:h,stopSequences:f}=Y5({prompt:r}),y=[...f??[],...s??[]];return{args:{model:this.modelId,echo:g.echo,logit_bias:g.logitBias,logprobs:g?.logprobs===!0?0:g?.logprobs===!1?void 0:g?.logprobs,suffix:g.suffix,user:g.user,max_tokens:e,temperature:t,top_p:n,frequency_penalty:i,presence_penalty:a,seed:d,prompt:h,stop:y.length>0?y:void 0},warnings:m}}async doGenerate(r){var e,t,n;let{args:o,warnings:i}=await this.getArgs(r),{responseHeaders:a,value:s,rawValue:c}=await vr({url:this.config.url({path:"/completions",modelId:this.modelId}),headers:Qt(this.config.headers(),r.headers),body:o,failedResponseHandler:Yn,successfulResponseHandler:un(X5),abortSignal:r.abortSignal,fetch:this.config.fetch}),l=s.choices[0],u={openai:{}};return l.logprobs!=null&&(u.openai.logprobs=l.logprobs),{content:[{type:"text",text:l.text}],usage:{inputTokens:(e=s.usage)==null?void 0:e.prompt_tokens,outputTokens:(t=s.usage)==null?void 0:t.completion_tokens,totalTokens:(n=s.usage)==null?void 0:n.total_tokens},finishReason:BN(l.finish_reason),request:{body:o},response:{...UN(s),headers:a,body:c},providerMetadata:u,warnings:i}}async doStream(r){let{args:e,warnings:t}=await this.getArgs(r),n={...e,stream:!0,stream_options:{include_usage:!0}},{responseHeaders:o,value:i}=await vr({url:this.config.url({path:"/completions",modelId:this.modelId}),headers:Qt(this.config.headers(),r.headers),body:n,failedResponseHandler:Yn,successfulResponseHandler:Ys(J5),abortSignal:r.abortSignal,fetch:this.config.fetch}),a="unknown",s={openai:{}},c={inputTokens:void 0,outputTokens:void 0,totalTokens:void 0},l=!0;return{stream:i.pipeThrough(new TransformStream({start(u){u.enqueue({type:"stream-start",warnings:t})},transform(u,d){if(r.includeRawChunks&&d.enqueue({type:"raw",rawValue:u.rawValue}),!u.success){a="error",d.enqueue({type:"error",error:u.error});return}let p=u.value;if("error"in p){a="error",d.enqueue({type:"error",error:p.error});return}l&&(l=!1,d.enqueue({type:"response-metadata",...UN(p)}),d.enqueue({type:"text-start",id:"0"})),p.usage!=null&&(c.inputTokens=p.usage.prompt_tokens,c.outputTokens=p.usage.completion_tokens,c.totalTokens=p.usage.total_tokens);let m=p.choices[0];m?.finish_reason!=null&&(a=BN(m.finish_reason)),m?.logprobs!=null&&(s.openai.logprobs=m.logprobs),m?.text!=null&&m.text.length>0&&d.enqueue({type:"text-delta",id:"0",delta:m.text})},flush(u){l||u.enqueue({type:"text-end",id:"0"}),u.enqueue({type:"finish",finishReason:a,providerMetadata:s,usage:c})}})),request:{body:n},response:{headers:o}}}},Q5=ot(()=>me(cb.object({dimensions:cb.number().optional(),user:cb.string().optional()}))),eX=ot(()=>me(fa.object({data:fa.array(fa.object({embedding:fa.array(fa.number())})),usage:fa.object({prompt_tokens:fa.number()}).nullish()}))),tX=class{constructor(r,e){this.specificationVersion="v2",this.maxEmbeddingsPerCall=2048,this.supportsParallelCalls=!0,this.modelId=r,this.config=e}get provider(){return this.config.provider}async doEmbed({values:r,headers:e,abortSignal:t,providerOptions:n}){var o;if(r.length>this.maxEmbeddingsPerCall)throw new pN({provider:this.provider,modelId:this.modelId,maxEmbeddingsPerCall:this.maxEmbeddingsPerCall,values:r});let i=(o=await Tr({provider:"openai",providerOptions:n,schema:Q5}))!=null?o:{},{responseHeaders:a,value:s,rawValue:c}=await vr({url:this.config.url({path:"/embeddings",modelId:this.modelId}),headers:Qt(this.config.headers(),e),body:{model:this.modelId,input:r,encoding_format:"float",dimensions:i.dimensions,user:i.user},failedResponseHandler:Yn,successfulResponseHandler:un(eX),abortSignal:t,fetch:this.config.fetch});return{embeddings:s.data.map(l=>l.embedding),usage:s.usage?{tokens:s.usage.prompt_tokens}:void 0,response:{headers:a,body:c}}}},rX=ot(()=>me(er.object({created:er.number().nullish(),data:er.array(er.object({b64_json:er.string(),revised_prompt:er.string().nullish()})),background:er.string().nullish(),output_format:er.string().nullish(),size:er.string().nullish(),quality:er.string().nullish(),usage:er.object({input_tokens:er.number().nullish(),output_tokens:er.number().nullish(),total_tokens:er.number().nullish(),input_tokens_details:er.object({image_tokens:er.number().nullish(),text_tokens:er.number().nullish()}).nullish()}).nullish()}))),nX={"dall-e-3":1,"dall-e-2":10,"gpt-image-1":10,"gpt-image-1-mini":10,"gpt-image-1.5":10},oX=new Set(["gpt-image-1","gpt-image-1-mini","gpt-image-1.5"]),iX=class{constructor(r,e){this.modelId=r,this.config=e,this.specificationVersion="v2"}get maxImagesPerCall(){var r;return(r=nX[this.modelId])!=null?r:1}get provider(){return this.config.provider}async doGenerate({prompt:r,n:e,size:t,aspectRatio:n,seed:o,providerOptions:i,headers:a,abortSignal:s}){var c,l,u,d;let p=[];n!=null&&p.push({type:"unsupported-setting",setting:"aspectRatio",details:"This model does not support aspect ratio. Use `size` instead."}),o!=null&&p.push({type:"unsupported-setting",setting:"seed"});let m=(u=(l=(c=this.config._internal)==null?void 0:c.currentDate)==null?void 0:l.call(c))!=null?u:new Date,{value:g,responseHeaders:h}=await vr({url:this.config.url({path:"/images/generations",modelId:this.modelId}),headers:Qt(this.config.headers(),a),body:{model:this.modelId,prompt:r,n:e,size:t,...(d=i.openai)!=null?d:{},...oX.has(this.modelId)?{}:{response_format:"b64_json"}},failedResponseHandler:Yn,successfulResponseHandler:un(rX),abortSignal:s,fetch:this.config.fetch});return{images:g.data.map(f=>f.b64_json),warnings:p,response:{timestamp:m,modelId:this.modelId,headers:h},providerMetadata:{openai:{images:g.data.map(f=>({...f.revised_prompt?{revisedPrompt:f.revised_prompt}:{},...g.created!=null?{created:g.created}:{},...g.size!=null?{size:g.size}:{},...g.quality!=null?{quality:g.quality}:{},...g.background!=null?{background:g.background}:{},...g.output_format!=null?{outputFormat:g.output_format}:{}}))}}}}},aX=wt(()=>me(qt.object({code:qt.string().nullish(),containerId:qt.string()}))),sX=wt(()=>me(qt.object({outputs:qt.array(qt.discriminatedUnion("type",[qt.object({type:qt.literal("logs"),logs:qt.string()}),qt.object({type:qt.literal("image"),url:qt.string()})])).nullish()}))),lX=wt(()=>me(qt.object({container:qt.union([qt.string(),qt.object({fileIds:qt.array(qt.string()).optional()})]).optional()}))),cX=cn({id:"openai.code_interpreter",name:"code_interpreter",inputSchema:aX,outputSchema:sX}),uX=(r={})=>cX(r),qN=ze.object({key:ze.string(),type:ze.enum(["eq","ne","gt","gte","lt","lte","in","nin"]),value:ze.union([ze.string(),ze.number(),ze.boolean(),ze.array(ze.string())])}),KN=ze.object({type:ze.enum(["and","or"]),filters:ze.array(ze.union([qN,ze.lazy(()=>KN)]))}),dX=wt(()=>me(ze.object({vectorStoreIds:ze.array(ze.string()),maxNumResults:ze.number().optional(),ranking:ze.object({ranker:ze.string().optional(),scoreThreshold:ze.number().optional()}).optional(),filters:ze.union([qN,KN]).optional()}))),mX=wt(()=>me(ze.object({queries:ze.array(ze.string()),results:ze.array(ze.object({attributes:ze.record(ze.string(),ze.unknown()),fileId:ze.string(),filename:ze.string(),score:ze.number(),text:ze.string()})).nullable()}))),pX=cn({id:"openai.file_search",name:"file_search",inputSchema:ze.object({}),outputSchema:mX}),gX=wt(()=>me(sr.object({background:sr.enum(["auto","opaque","transparent"]).optional(),inputFidelity:sr.enum(["low","high"]).optional(),inputImageMask:sr.object({fileId:sr.string().optional(),imageUrl:sr.string().optional()}).optional(),model:sr.string().optional(),moderation:sr.enum(["auto"]).optional(),outputCompression:sr.number().int().min(0).max(100).optional(),outputFormat:sr.enum(["png","jpeg","webp"]).optional(),partialImages:sr.number().int().min(0).max(3).optional(),quality:sr.enum(["auto","low","medium","high"]).optional(),size:sr.enum(["1024x1024","1024x1536","1536x1024","auto"]).optional()}).strict())),hX=wt(()=>me(sr.object({}))),fX=wt(()=>me(sr.object({result:sr.string()}))),SX=cn({id:"openai.image_generation",name:"image_generation",inputSchema:hX,outputSchema:fX}),yX=(r={})=>SX(r),YN=wt(()=>me(Fr.object({action:Fr.object({type:Fr.literal("exec"),command:Fr.array(Fr.string()),timeoutMs:Fr.number().optional(),user:Fr.string().optional(),workingDirectory:Fr.string().optional(),env:Fr.record(Fr.string(),Fr.string()).optional()})}))),XN=wt(()=>me(Fr.object({output:Fr.string()}))),bX=cn({id:"openai.local_shell",name:"local_shell",inputSchema:YN,outputSchema:XN}),EX=wt(()=>me(Ve.object({externalWebAccess:Ve.boolean().optional(),filters:Ve.object({allowedDomains:Ve.array(Ve.string()).optional()}).optional(),searchContextSize:Ve.enum(["low","medium","high"]).optional(),userLocation:Ve.object({type:Ve.literal("approximate"),country:Ve.string().optional(),city:Ve.string().optional(),region:Ve.string().optional(),timezone:Ve.string().optional()}).optional()}))),TX=wt(()=>me(Ve.object({}))),vX=wt(()=>me(Ve.object({action:Ve.discriminatedUnion("type",[Ve.object({type:Ve.literal("search"),query:Ve.string().optional()}),Ve.object({type:Ve.literal("openPage"),url:Ve.string().nullish()}),Ve.object({type:Ve.literal("findInPage"),url:Ve.string().nullish(),pattern:Ve.string().nullish()})]),sources:Ve.array(Ve.discriminatedUnion("type",[Ve.object({type:Ve.literal("url"),url:Ve.string()}),Ve.object({type:Ve.literal("api"),name:Ve.string()})])).optional()}))),AX=cn({id:"openai.web_search",name:"web_search",inputSchema:TX,outputSchema:vX}),RX=(r={})=>AX(r),wX=wt(()=>me(Lt.object({searchContextSize:Lt.enum(["low","medium","high"]).optional(),userLocation:Lt.object({type:Lt.literal("approximate"),country:Lt.string().optional(),city:Lt.string().optional(),region:Lt.string().optional(),timezone:Lt.string().optional()}).optional()}))),CX=wt(()=>me(Lt.object({}))),xX=wt(()=>me(Lt.object({action:Lt.discriminatedUnion("type",[Lt.object({type:Lt.literal("search"),query:Lt.string().optional()}),Lt.object({type:Lt.literal("openPage"),url:Lt.string().nullish()}),Lt.object({type:Lt.literal("findInPage"),url:Lt.string().nullish(),pattern:Lt.string().nullish()})])}))),_X=cn({id:"openai.web_search_preview",name:"web_search_preview",inputSchema:CX,outputSchema:xX}),MX={codeInterpreter:uX,fileSearch:pX,imageGeneration:yX,localShell:bX,webSearchPreview:_X,webSearch:RX};function HN(r,e){return e?e.some(t=>r.startsWith(t)):!1}async function PX({prompt:r,systemMessageMode:e,fileIdPrefixes:t,store:n,hasLocalShellTool:o=!1}){var i,a,s,c;let l=[],u=[];for(let{role:d,content:p}of r)switch(d){case"system":{switch(e){case"system":{l.push({role:"system",content:p});break}case"developer":{l.push({role:"developer",content:p});break}case"remove":{u.push({type:"other",message:"system messages are removed for this model"});break}default:{let m=e;throw new Error(`Unsupported system message mode: ${m}`)}}break}case"user":{l.push({role:"user",content:p.map((m,g)=>{var h,f,y;switch(m.type){case"text":return{type:"input_text",text:m.text};case"file":if(m.mediaType.startsWith("image/")){let E=m.mediaType==="image/*"?"image/jpeg":m.mediaType;return{type:"input_image",...m.data instanceof URL?{image_url:m.data.toString()}:typeof m.data=="string"&&HN(m.data,t)?{file_id:m.data}:{image_url:`data:${E};base64,${ui(m.data)}`},detail:(f=(h=m.providerOptions)==null?void 0:h.openai)==null?void 0:f.imageDetail}}else{if(m.mediaType==="application/pdf")return m.data instanceof URL?{type:"input_file",file_url:m.data.toString()}:{type:"input_file",...typeof m.data=="string"&&HN(m.data,t)?{file_id:m.data}:{filename:(y=m.filename)!=null?y:`part-${g}.pdf`,file_data:`data:application/pdf;base64,${ui(m.data)}`}};throw new xr({functionality:`file part media type ${m.mediaType}`})}}})});break}case"assistant":{let m={},g={};for(let h of p)switch(h.type){case"text":{let f=(a=(i=h.providerOptions)==null?void 0:i.openai)==null?void 0:a.itemId;if(n&&f!=null){l.push({type:"item_reference",id:f});break}l.push({role:"assistant",content:[{type:"output_text",text:h.text}],id:f});break}case"tool-call":{if(g[h.toolCallId]=h,h.providerExecuted)break;let f=(c=(s=h.providerOptions)==null?void 0:s.openai)==null?void 0:c.itemId;if(n&&f!=null){l.push({type:"item_reference",id:f});break}if(o&&h.toolName==="local_shell"){let y=await qn({value:h.input,schema:YN});l.push({type:"local_shell_call",call_id:h.toolCallId,id:f,action:{type:"exec",command:y.action.command,timeout_ms:y.action.timeoutMs,user:y.action.user,working_directory:y.action.workingDirectory,env:y.action.env}});break}l.push({type:"function_call",call_id:h.toolCallId,name:h.toolName,arguments:JSON.stringify(h.input),id:f});break}case"tool-result":{n?l.push({type:"item_reference",id:h.toolCallId}):u.push({type:"other",message:`Results for OpenAI tool ${h.toolName} are not sent to the API when store is false`});break}case"reasoning":{let f=await Tr({provider:"openai",providerOptions:h.providerOptions,schema:IX}),y=f?.itemId;if(y!=null){let E=m[y];if(n)E===void 0&&(l.push({type:"item_reference",id:y}),m[y]={type:"reasoning",id:y,summary:[]});else{let b=[];h.text.length>0?b.push({type:"summary_text",text:h.text}):E!==void 0&&u.push({type:"other",message:`Cannot append empty reasoning part to existing reasoning sequence. Skipping reasoning part: ${JSON.stringify(h)}.`}),E===void 0?(m[y]={type:"reasoning",id:y,encrypted_content:f?.reasoningEncryptedContent,summary:b},l.push(m[y])):(E.summary.push(...b),f?.reasoningEncryptedContent!=null&&(E.encrypted_content=f.reasoningEncryptedContent))}}else u.push({type:"other",message:`Non-OpenAI reasoning parts are not supported. Skipping reasoning part: ${JSON.stringify(h)}.`});break}}break}case"tool":{for(let m of p){let g=m.output;if(o&&m.toolName==="local_shell"&&g.type==="json"){let f=await qn({value:g.value,schema:XN});l.push({type:"local_shell_call_output",call_id:m.toolCallId,output:f.output});break}let h;switch(g.type){case"text":case"error-text":h=g.value;break;case"json":case"error-json":h=JSON.stringify(g.value);break;case"content":h=g.value.map(f=>{switch(f.type){case"text":return{type:"input_text",text:f.text};case"media":return f.mediaType.startsWith("image/")?{type:"input_image",image_url:`data:${f.mediaType};base64,${f.data}`}:{type:"input_file",filename:"data",file_data:`data:${f.mediaType};base64,${f.data}`}}});break}l.push({type:"function_call_output",call_id:m.toolCallId,output:h})}break}default:{let m=d;throw new Error(`Unsupported role: ${m}`)}}return{input:l,warnings:u}}var IX=ub.object({itemId:ub.string().nullish(),reasoningEncryptedContent:ub.string().nullish()});function GN({finishReason:r,hasFunctionCall:e}){switch(r){case void 0:case null:return e?"tool-calls":"stop";case"max_output_tokens":return"length";case"content_filter":return"content-filter";default:return e?"tool-calls":"unknown"}}var OX=ot(()=>me(S.union([S.object({type:S.literal("response.output_text.delta"),item_id:S.string(),delta:S.string(),logprobs:S.array(S.object({token:S.string(),logprob:S.number(),top_logprobs:S.array(S.object({token:S.string(),logprob:S.number()}))})).nullish()}),S.object({type:S.enum(["response.completed","response.incomplete"]),response:S.object({incomplete_details:S.object({reason:S.string()}).nullish(),usage:S.object({input_tokens:S.number(),input_tokens_details:S.object({cached_tokens:S.number().nullish()}).nullish(),output_tokens:S.number(),output_tokens_details:S.object({reasoning_tokens:S.number().nullish()}).nullish()}),service_tier:S.string().nullish()})}),S.object({type:S.literal("response.created"),response:S.object({id:S.string(),created_at:S.number(),model:S.string(),service_tier:S.string().nullish()})}),S.object({type:S.literal("response.output_item.added"),output_index:S.number(),item:S.discriminatedUnion("type",[S.object({type:S.literal("message"),id:S.string()}),S.object({type:S.literal("reasoning"),id:S.string(),encrypted_content:S.string().nullish()}),S.object({type:S.literal("function_call"),id:S.string(),call_id:S.string(),name:S.string(),arguments:S.string()}),S.object({type:S.literal("web_search_call"),id:S.string(),status:S.string()}),S.object({type:S.literal("computer_call"),id:S.string(),status:S.string()}),S.object({type:S.literal("file_search_call"),id:S.string()}),S.object({type:S.literal("image_generation_call"),id:S.string()}),S.object({type:S.literal("code_interpreter_call"),id:S.string(),container_id:S.string(),code:S.string().nullable(),outputs:S.array(S.discriminatedUnion("type",[S.object({type:S.literal("logs"),logs:S.string()}),S.object({type:S.literal("image"),url:S.string()})])).nullable(),status:S.string()})])}),S.object({type:S.literal("response.output_item.done"),output_index:S.number(),item:S.discriminatedUnion("type",[S.object({type:S.literal("message"),id:S.string()}),S.object({type:S.literal("reasoning"),id:S.string(),encrypted_content:S.string().nullish()}),S.object({type:S.literal("function_call"),id:S.string(),call_id:S.string(),name:S.string(),arguments:S.string(),status:S.literal("completed")}),S.object({type:S.literal("code_interpreter_call"),id:S.string(),code:S.string().nullable(),container_id:S.string(),outputs:S.array(S.discriminatedUnion("type",[S.object({type:S.literal("logs"),logs:S.string()}),S.object({type:S.literal("image"),url:S.string()})])).nullable()}),S.object({type:S.literal("image_generation_call"),id:S.string(),result:S.string()}),S.object({type:S.literal("web_search_call"),id:S.string(),status:S.string(),action:S.discriminatedUnion("type",[S.object({type:S.literal("search"),query:S.string().nullish(),sources:S.array(S.discriminatedUnion("type",[S.object({type:S.literal("url"),url:S.string()}),S.object({type:S.literal("api"),name:S.string()})])).nullish()}),S.object({type:S.literal("open_page"),url:S.string().nullish()}),S.object({type:S.literal("find_in_page"),url:S.string().nullish(),pattern:S.string().nullish()})])}),S.object({type:S.literal("file_search_call"),id:S.string(),queries:S.array(S.string()),results:S.array(S.object({attributes:S.record(S.string(),S.unknown()),file_id:S.string(),filename:S.string(),score:S.number(),text:S.string()})).nullish()}),S.object({type:S.literal("local_shell_call"),id:S.string(),call_id:S.string(),action:S.object({type:S.literal("exec"),command:S.array(S.string()),timeout_ms:S.number().optional(),user:S.string().optional(),working_directory:S.string().optional(),env:S.record(S.string(),S.string()).optional()})}),S.object({type:S.literal("computer_call"),id:S.string(),status:S.literal("completed")})])}),S.object({type:S.literal("response.function_call_arguments.delta"),item_id:S.string(),output_index:S.number(),delta:S.string()}),S.object({type:S.literal("response.image_generation_call.partial_image"),item_id:S.string(),output_index:S.number(),partial_image_b64:S.string()}),S.object({type:S.literal("response.code_interpreter_call_code.delta"),item_id:S.string(),output_index:S.number(),delta:S.string()}),S.object({type:S.literal("response.code_interpreter_call_code.done"),item_id:S.string(),output_index:S.number(),code:S.string()}),S.object({type:S.literal("response.output_text.annotation.added"),annotation:S.discriminatedUnion("type",[S.object({type:S.literal("url_citation"),start_index:S.number(),end_index:S.number(),url:S.string(),title:S.string()}),S.object({type:S.literal("file_citation"),file_id:S.string(),filename:S.string().nullish(),index:S.number().nullish(),start_index:S.number().nullish(),end_index:S.number().nullish(),quote:S.string().nullish()})])}),S.object({type:S.literal("response.reasoning_summary_part.added"),item_id:S.string(),summary_index:S.number()}),S.object({type:S.literal("response.reasoning_summary_text.delta"),item_id:S.string(),summary_index:S.number(),delta:S.string()}),S.object({type:S.literal("response.reasoning_summary_part.done"),item_id:S.string(),summary_index:S.number()}),S.object({type:S.literal("error"),sequence_number:S.number(),error:S.object({type:S.string(),code:S.string(),message:S.string(),param:S.string().nullish()})}),S.object({type:S.string()}).loose().transform(r=>({type:"unknown_chunk",message:r.type}))]))),LX=ot(()=>me(S.object({id:S.string().optional(),created_at:S.number().optional(),error:S.object({message:S.string(),type:S.string(),param:S.string().nullish(),code:S.string()}).nullish(),model:S.string().optional(),output:S.array(S.discriminatedUnion("type",[S.object({type:S.literal("message"),role:S.literal("assistant"),id:S.string(),content:S.array(S.object({type:S.literal("output_text"),text:S.string(),logprobs:S.array(S.object({token:S.string(),logprob:S.number(),top_logprobs:S.array(S.object({token:S.string(),logprob:S.number()}))})).nullish(),annotations:S.array(S.discriminatedUnion("type",[S.object({type:S.literal("url_citation"),start_index:S.number(),end_index:S.number(),url:S.string(),title:S.string()}),S.object({type:S.literal("file_citation"),file_id:S.string(),filename:S.string().nullish(),index:S.number().nullish(),start_index:S.number().nullish(),end_index:S.number().nullish(),quote:S.string().nullish()}),S.object({type:S.literal("container_file_citation"),container_id:S.string(),file_id:S.string(),filename:S.string().nullish(),start_index:S.number().nullish(),end_index:S.number().nullish(),index:S.number().nullish()}),S.object({type:S.literal("file_path"),file_id:S.string(),index:S.number().nullish()})]))}))}),S.object({type:S.literal("web_search_call"),id:S.string(),status:S.string(),action:S.discriminatedUnion("type",[S.object({type:S.literal("search"),query:S.string().nullish(),sources:S.array(S.discriminatedUnion("type",[S.object({type:S.literal("url"),url:S.string()}),S.object({type:S.literal("api"),name:S.string()})])).nullish()}),S.object({type:S.literal("open_page"),url:S.string().nullish()}),S.object({type:S.literal("find_in_page"),url:S.string().nullish(),pattern:S.string().nullish()})])}),S.object({type:S.literal("file_search_call"),id:S.string(),queries:S.array(S.string()),results:S.array(S.object({attributes:S.record(S.string(),S.union([S.string(),S.number(),S.boolean()])),file_id:S.string(),filename:S.string(),score:S.number(),text:S.string()})).nullish()}),S.object({type:S.literal("code_interpreter_call"),id:S.string(),code:S.string().nullable(),container_id:S.string(),outputs:S.array(S.discriminatedUnion("type",[S.object({type:S.literal("logs"),logs:S.string()}),S.object({type:S.literal("image"),url:S.string()})])).nullable()}),S.object({type:S.literal("image_generation_call"),id:S.string(),result:S.string()}),S.object({type:S.literal("local_shell_call"),id:S.string(),call_id:S.string(),action:S.object({type:S.literal("exec"),command:S.array(S.string()),timeout_ms:S.number().optional(),user:S.string().optional(),working_directory:S.string().optional(),env:S.record(S.string(),S.string()).optional()})}),S.object({type:S.literal("function_call"),call_id:S.string(),name:S.string(),arguments:S.string(),id:S.string()}),S.object({type:S.literal("computer_call"),id:S.string(),status:S.string().optional()}),S.object({type:S.literal("reasoning"),id:S.string(),encrypted_content:S.string().nullish(),summary:S.array(S.object({type:S.literal("summary_text"),text:S.string()}))})])).optional(),service_tier:S.string().nullish(),incomplete_details:S.object({reason:S.string()}).nullish(),usage:S.object({input_tokens:S.number(),input_tokens_details:S.object({cached_tokens:S.number().nullish()}).nullish(),output_tokens:S.number(),output_tokens_details:S.object({reasoning_tokens:S.number().nullish()}).nullish()}).optional()}))),JN=20,NX=["o1","o1-2024-12-17","o3","o3-2025-04-16","o3-deep-research","o3-deep-research-2025-06-26","o3-mini","o3-mini-2025-01-31","o4-mini","o4-mini-2025-04-16","o4-mini-deep-research","o4-mini-deep-research-2025-06-26","codex-mini-latest","computer-use-preview","gpt-5","gpt-5-2025-08-07","gpt-5-codex","gpt-5-mini","gpt-5-mini-2025-08-07","gpt-5-nano","gpt-5-nano-2025-08-07","gpt-5-pro","gpt-5-pro-2025-10-06","gpt-5.1","gpt-5.1-chat-latest","gpt-5.1-codex-mini","gpt-5.1-codex","gpt-5.1-codex-max","gpt-5.2","gpt-5.2-chat-latest","gpt-5.2-pro"],h6e=["gpt-4.1","gpt-4.1-2025-04-14","gpt-4.1-mini","gpt-4.1-mini-2025-04-14","gpt-4.1-nano","gpt-4.1-nano-2025-04-14","gpt-4o","gpt-4o-2024-05-13","gpt-4o-2024-08-06","gpt-4o-2024-11-20","gpt-4o-audio-preview","gpt-4o-audio-preview-2024-10-01","gpt-4o-audio-preview-2024-12-17","gpt-4o-search-preview","gpt-4o-search-preview-2025-03-11","gpt-4o-mini-search-preview","gpt-4o-mini-search-preview-2025-03-11","gpt-4o-mini","gpt-4o-mini-2024-07-18","gpt-4-turbo","gpt-4-turbo-2024-04-09","gpt-4-turbo-preview","gpt-4-0125-preview","gpt-4-1106-preview","gpt-4","gpt-4-0613","gpt-4.5-preview","gpt-4.5-preview-2025-02-27","gpt-3.5-turbo-0125","gpt-3.5-turbo","gpt-3.5-turbo-1106","chatgpt-4o-latest","gpt-5-chat-latest",...NX],DX=ot(()=>me(Tt.object({conversation:Tt.string().nullish(),include:Tt.array(Tt.enum(["reasoning.encrypted_content","file_search_call.results","message.output_text.logprobs"])).nullish(),instructions:Tt.string().nullish(),logprobs:Tt.union([Tt.boolean(),Tt.number().min(1).max(JN)]).optional(),maxToolCalls:Tt.number().nullish(),metadata:Tt.any().nullish(),parallelToolCalls:Tt.boolean().nullish(),previousResponseId:Tt.string().nullish(),promptCacheKey:Tt.string().nullish(),promptCacheRetention:Tt.enum(["in_memory","24h"]).nullish(),reasoningEffort:Tt.string().nullish(),reasoningSummary:Tt.string().nullish(),safetyIdentifier:Tt.string().nullish(),serviceTier:Tt.enum(["auto","flex","priority","default"]).nullish(),store:Tt.boolean().nullish(),strictJsonSchema:Tt.boolean().nullish(),textVerbosity:Tt.enum(["low","medium","high"]).nullish(),truncation:Tt.enum(["auto","disabled"]).nullish(),user:Tt.string().nullish()})));async function kX({tools:r,toolChoice:e,strictJsonSchema:t}){r=r?.length?r:void 0;let n=[];if(r==null)return{tools:void 0,toolChoice:void 0,toolWarnings:n};let o=[];for(let a of r)switch(a.type){case"function":o.push({type:"function",name:a.name,description:a.description,parameters:a.inputSchema,strict:t});break;case"provider-defined":{switch(a.id){case"openai.file_search":{let s=await qn({value:a.args,schema:dX});o.push({type:"file_search",vector_store_ids:s.vectorStoreIds,max_num_results:s.maxNumResults,ranking_options:s.ranking?{ranker:s.ranking.ranker,score_threshold:s.ranking.scoreThreshold}:void 0,filters:s.filters});break}case"openai.local_shell":{o.push({type:"local_shell"});break}case"openai.web_search_preview":{let s=await qn({value:a.args,schema:wX});o.push({type:"web_search_preview",search_context_size:s.searchContextSize,user_location:s.userLocation});break}case"openai.web_search":{let s=await qn({value:a.args,schema:EX});o.push({type:"web_search",filters:s.filters!=null?{allowed_domains:s.filters.allowedDomains}:void 0,external_web_access:s.externalWebAccess,search_context_size:s.searchContextSize,user_location:s.userLocation});break}case"openai.code_interpreter":{let s=await qn({value:a.args,schema:lX});o.push({type:"code_interpreter",container:s.container==null?{type:"auto",file_ids:void 0}:typeof s.container=="string"?s.container:{type:"auto",file_ids:s.container.fileIds}});break}case"openai.image_generation":{let s=await qn({value:a.args,schema:gX});o.push({type:"image_generation",background:s.background,input_fidelity:s.inputFidelity,input_image_mask:s.inputImageMask?{file_id:s.inputImageMask.fileId,image_url:s.inputImageMask.imageUrl}:void 0,model:s.model,size:s.size,quality:s.quality,moderation:s.moderation,output_format:s.outputFormat,output_compression:s.outputCompression});break}}break}default:n.push({type:"unsupported-tool",tool:a});break}if(e==null)return{tools:o,toolChoice:void 0,toolWarnings:n};let i=e.type;switch(i){case"auto":case"none":case"required":return{tools:o,toolChoice:i,toolWarnings:n};case"tool":return{tools:o,toolChoice:e.toolName==="code_interpreter"||e.toolName==="file_search"||e.toolName==="image_generation"||e.toolName==="web_search_preview"||e.toolName==="web_search"?{type:e.toolName}:{type:"function",name:e.toolName},toolWarnings:n};default:{let a=i;throw new xr({functionality:`tool choice type: ${a}`})}}}var FX=class{constructor(r,e){this.specificationVersion="v2",this.supportedUrls={"image/*":[/^https?:\/\/.*$/],"application/pdf":[/^https?:\/\/.*$/]},this.modelId=r,this.config=e}get provider(){return this.config.provider}async getArgs({maxOutputTokens:r,temperature:e,stopSequences:t,topP:n,topK:o,presencePenalty:i,frequencyPenalty:a,seed:s,prompt:c,providerOptions:l,tools:u,toolChoice:d,responseFormat:p}){var m,g,h,f;let y=[],E=$N(this.modelId);o!=null&&y.push({type:"unsupported-setting",setting:"topK"}),s!=null&&y.push({type:"unsupported-setting",setting:"seed"}),i!=null&&y.push({type:"unsupported-setting",setting:"presencePenalty"}),a!=null&&y.push({type:"unsupported-setting",setting:"frequencyPenalty"}),t!=null&&y.push({type:"unsupported-setting",setting:"stopSequences"});let b=await Tr({provider:"openai",providerOptions:l,schema:DX});b?.conversation&&b?.previousResponseId&&y.push({type:"unsupported-setting",setting:"conversation",details:"conversation and previousResponseId cannot be used together"});let{input:_,warnings:M}=await PX({prompt:c,systemMessageMode:E.systemMessageMode,fileIdPrefixes:this.config.fileIdPrefixes,store:(m=b?.store)!=null?m:!0,hasLocalShellTool:F("openai.local_shell")});y.push(...M);let O=(g=b?.strictJsonSchema)!=null?g:!1,v=b?.include;function C(W){v==null?v=[W]:v.includes(W)||(v=[...v,W])}function F(W){return u?.find(ue=>ue.type==="provider-defined"&&ue.id===W)!=null}let I=typeof b?.logprobs=="number"?b?.logprobs:b?.logprobs===!0?JN:void 0;I&&C("message.output_text.logprobs");let B=(h=u?.find(W=>W.type==="provider-defined"&&(W.id==="openai.web_search"||W.id==="openai.web_search_preview")))==null?void 0:h.name;B&&C("web_search_call.action.sources"),F("openai.code_interpreter")&&C("code_interpreter_call.outputs");let D=b?.store;D===!1&&E.isReasoningModel&&C("reasoning.encrypted_content");let ee={model:this.modelId,input:_,temperature:e,top_p:n,max_output_tokens:r,...(p?.type==="json"||b?.textVerbosity)&&{text:{...p?.type==="json"&&{format:p.schema!=null?{type:"json_schema",strict:O,name:(f=p.name)!=null?f:"response",description:p.description,schema:p.schema}:{type:"json_object"}},...b?.textVerbosity&&{verbosity:b.textVerbosity}}},conversation:b?.conversation,max_tool_calls:b?.maxToolCalls,metadata:b?.metadata,parallel_tool_calls:b?.parallelToolCalls,previous_response_id:b?.previousResponseId,store:D,user:b?.user,instructions:b?.instructions,service_tier:b?.serviceTier,include:v,prompt_cache_key:b?.promptCacheKey,prompt_cache_retention:b?.promptCacheRetention,safety_identifier:b?.safetyIdentifier,top_logprobs:I,truncation:b?.truncation,...E.isReasoningModel&&(b?.reasoningEffort!=null||b?.reasoningSummary!=null)&&{reasoning:{...b?.reasoningEffort!=null&&{effort:b.reasoningEffort},...b?.reasoningSummary!=null&&{summary:b.reasoningSummary}}}};E.isReasoningModel?b?.reasoningEffort==="none"&&E.supportsNonReasoningParameters||(ee.temperature!=null&&(ee.temperature=void 0,y.push({type:"unsupported-setting",setting:"temperature",details:"temperature is not supported for reasoning models"})),ee.top_p!=null&&(ee.top_p=void 0,y.push({type:"unsupported-setting",setting:"topP",details:"topP is not supported for reasoning models"}))):(b?.reasoningEffort!=null&&y.push({type:"unsupported-setting",setting:"reasoningEffort",details:"reasoningEffort is not supported for non-reasoning models"}),b?.reasoningSummary!=null&&y.push({type:"unsupported-setting",setting:"reasoningSummary",details:"reasoningSummary is not supported for non-reasoning models"})),b?.serviceTier==="flex"&&!E.supportsFlexProcessing&&(y.push({type:"unsupported-setting",setting:"serviceTier",details:"flex processing is only available for o3, o4-mini, and gpt-5 models"}),delete ee.service_tier),b?.serviceTier==="priority"&&!E.supportsPriorityProcessing&&(y.push({type:"unsupported-setting",setting:"serviceTier",details:"priority processing is only available for supported models (gpt-4, gpt-5, gpt-5-mini, o3, o4-mini) and requires Enterprise access. gpt-5-nano is not supported"}),delete ee.service_tier);let{tools:K,toolChoice:ge,toolWarnings:U}=await kX({tools:u,toolChoice:d,strictJsonSchema:O});return{webSearchToolName:B,args:{...ee,tools:K,tool_choice:ge},warnings:[...y,...U],store:D}}async doGenerate(r){var e,t,n,o,i,a,s,c,l,u,d,p,m,g,h,f,y,E,b,_,M,O,v,C,F,I,B,D;let{args:ee,warnings:K,webSearchToolName:ge}=await this.getArgs(r),U=this.config.url({path:"/responses",modelId:this.modelId}),W=this.config.provider.replace(".responses",""),{responseHeaders:ue,value:le,rawValue:He}=await vr({url:U,headers:Qt(this.config.headers(),r.headers),body:ee,failedResponseHandler:Yn,successfulResponseHandler:un(LX),abortSignal:r.abortSignal,fetch:this.config.fetch});if(le.error)throw new ar({message:le.error.message,url:U,requestBodyValues:ee,statusCode:400,responseHeaders:ue,responseBody:He,isRetryable:!1});let ve=[],q=[],fe=!1;for(let x of le.output)switch(x.type){case"reasoning":{x.summary.length===0&&x.summary.push({type:"summary_text",text:""});for(let ne of x.summary)ve.push({type:"reasoning",text:ne.text,providerMetadata:{[W]:{itemId:x.id,reasoningEncryptedContent:(e=x.encrypted_content)!=null?e:null}}});break}case"image_generation_call":{ve.push({type:"tool-call",toolCallId:x.id,toolName:"image_generation",input:"{}",providerExecuted:!0}),ve.push({type:"tool-result",toolCallId:x.id,toolName:"image_generation",result:{result:x.result},providerExecuted:!0});break}case"local_shell_call":{ve.push({type:"tool-call",toolCallId:x.call_id,toolName:"local_shell",input:JSON.stringify({action:x.action}),providerMetadata:{[W]:{itemId:x.id}}});break}case"message":{for(let ne of x.content){(n=(t=r.providerOptions)==null?void 0:t.openai)!=null&&n.logprobs&&ne.logprobs&&q.push(ne.logprobs),ve.push({type:"text",text:ne.text,providerMetadata:{[W]:{itemId:x.id}}});for(let pe of ne.annotations)pe.type==="url_citation"?ve.push({type:"source",sourceType:"url",id:(a=(i=(o=this.config).generateId)==null?void 0:i.call(o))!=null?a:kr(),url:pe.url,title:pe.title}):pe.type==="file_citation"?ve.push({type:"source",sourceType:"document",id:(l=(c=(s=this.config).generateId)==null?void 0:c.call(s))!=null?l:kr(),mediaType:"text/plain",title:(d=(u=pe.quote)!=null?u:pe.filename)!=null?d:"Document",filename:(p=pe.filename)!=null?p:pe.file_id,...pe.file_id?{providerMetadata:{[W]:{fileId:pe.file_id}}}:{}}):pe.type==="container_file_citation"?ve.push({type:"source",sourceType:"document",id:(h=(g=(m=this.config).generateId)==null?void 0:g.call(m))!=null?h:kr(),mediaType:"text/plain",title:(y=(f=pe.filename)!=null?f:pe.file_id)!=null?y:"Document",filename:(E=pe.filename)!=null?E:pe.file_id,providerMetadata:{[W]:{fileId:pe.file_id,containerId:pe.container_id,...pe.index!=null?{index:pe.index}:{}}}}):pe.type==="file_path"&&ve.push({type:"source",sourceType:"document",id:(M=(_=(b=this.config).generateId)==null?void 0:_.call(b))!=null?M:kr(),mediaType:"application/octet-stream",title:pe.file_id,filename:pe.file_id,providerMetadata:{[W]:{fileId:pe.file_id,...pe.index!=null?{index:pe.index}:{}}}})}break}case"function_call":{fe=!0,ve.push({type:"tool-call",toolCallId:x.call_id,toolName:x.name,input:x.arguments,providerMetadata:{[W]:{itemId:x.id}}});break}case"web_search_call":{ve.push({type:"tool-call",toolCallId:x.id,toolName:ge??"web_search",input:JSON.stringify({}),providerExecuted:!0}),ve.push({type:"tool-result",toolCallId:x.id,toolName:ge??"web_search",result:jN(x.action),providerExecuted:!0});break}case"computer_call":{ve.push({type:"tool-call",toolCallId:x.id,toolName:"computer_use",input:"",providerExecuted:!0}),ve.push({type:"tool-result",toolCallId:x.id,toolName:"computer_use",result:{type:"computer_use_tool_result",status:x.status||"completed"},providerExecuted:!0});break}case"file_search_call":{ve.push({type:"tool-call",toolCallId:x.id,toolName:"file_search",input:"{}",providerExecuted:!0}),ve.push({type:"tool-result",toolCallId:x.id,toolName:"file_search",result:{queries:x.queries,results:(v=(O=x.results)==null?void 0:O.map(ne=>({attributes:ne.attributes,fileId:ne.file_id,filename:ne.filename,score:ne.score,text:ne.text})))!=null?v:null},providerExecuted:!0});break}case"code_interpreter_call":{ve.push({type:"tool-call",toolCallId:x.id,toolName:"code_interpreter",input:JSON.stringify({code:x.code,containerId:x.container_id}),providerExecuted:!0}),ve.push({type:"tool-result",toolCallId:x.id,toolName:"code_interpreter",result:{outputs:x.outputs},providerExecuted:!0});break}}let it={[W]:{...le.id!=null?{responseId:le.id}:{}}};q.length>0&&(it[W].logprobs=q),typeof le.service_tier=="string"&&(it[W].serviceTier=le.service_tier);let Ae=le.usage;return{content:ve,finishReason:GN({finishReason:(C=le.incomplete_details)==null?void 0:C.reason,hasFunctionCall:fe}),usage:{inputTokens:Ae.input_tokens,outputTokens:Ae.output_tokens,totalTokens:Ae.input_tokens+Ae.output_tokens,reasoningTokens:(I=(F=Ae.output_tokens_details)==null?void 0:F.reasoning_tokens)!=null?I:void 0,cachedInputTokens:(D=(B=Ae.input_tokens_details)==null?void 0:B.cached_tokens)!=null?D:void 0},request:{body:ee},response:{id:le.id,timestamp:new Date(le.created_at*1e3),modelId:le.model,headers:ue,body:He},providerMetadata:it,warnings:K}}async doStream(r){let{args:e,warnings:t,webSearchToolName:n,store:o}=await this.getArgs(r),{responseHeaders:i,value:a}=await vr({url:this.config.url({path:"/responses",modelId:this.modelId}),headers:Qt(this.config.headers(),r.headers),body:{...e,stream:!0},failedResponseHandler:Yn,successfulResponseHandler:Ys(OX),abortSignal:r.abortSignal,fetch:this.config.fetch}),s=this,c=this.config.provider.replace(".responses",""),l="unknown",u={inputTokens:void 0,outputTokens:void 0,totalTokens:void 0},d=[],p=null,m={},g=[],h=!1,f={},y;return{stream:a.pipeThrough(new TransformStream({start(E){E.enqueue({type:"stream-start",warnings:t})},transform(E,b){var _,M,O,v,C,F,I,B,D,ee,K,ge,U,W,ue,le,He,ve,q,fe,it,Ae;if(r.includeRawChunks&&b.enqueue({type:"raw",rawValue:E.rawValue}),!E.success){l="error",b.enqueue({type:"error",error:E.error});return}let x=E.value;if(WN(x))x.item.type==="function_call"?(m[x.output_index]={toolName:x.item.name,toolCallId:x.item.call_id},b.enqueue({type:"tool-input-start",id:x.item.call_id,toolName:x.item.name})):x.item.type==="web_search_call"?(m[x.output_index]={toolName:n??"web_search",toolCallId:x.item.id},b.enqueue({type:"tool-input-start",id:x.item.id,toolName:n??"web_search",providerExecuted:!0}),b.enqueue({type:"tool-input-end",id:x.item.id}),b.enqueue({type:"tool-call",toolCallId:x.item.id,toolName:n??"web_search",input:JSON.stringify({}),providerExecuted:!0})):x.item.type==="computer_call"?(m[x.output_index]={toolName:"computer_use",toolCallId:x.item.id},b.enqueue({type:"tool-input-start",id:x.item.id,toolName:"computer_use",providerExecuted:!0})):x.item.type==="code_interpreter_call"?(m[x.output_index]={toolName:"code_interpreter",toolCallId:x.item.id,codeInterpreter:{containerId:x.item.container_id}},b.enqueue({type:"tool-input-start",id:x.item.id,toolName:"code_interpreter",providerExecuted:!0}),b.enqueue({type:"tool-input-delta",id:x.item.id,delta:`{"containerId":"${x.item.container_id}","code":"`})):x.item.type==="file_search_call"?b.enqueue({type:"tool-call",toolCallId:x.item.id,toolName:"file_search",input:"{}",providerExecuted:!0}):x.item.type==="image_generation_call"?b.enqueue({type:"tool-call",toolCallId:x.item.id,toolName:"image_generation",input:"{}",providerExecuted:!0}):x.item.type==="message"?(g.splice(0,g.length),b.enqueue({type:"text-start",id:x.item.id,providerMetadata:{[c]:{itemId:x.item.id}}})):WN(x)&&x.item.type==="reasoning"&&(f[x.item.id]={encryptedContent:x.item.encrypted_content,summaryParts:{0:"active"}},b.enqueue({type:"reasoning-start",id:`${x.item.id}:0`,providerMetadata:{[c]:{itemId:x.item.id,reasoningEncryptedContent:(_=x.item.encrypted_content)!=null?_:null}}}));else if(BX(x)){if(x.item.type==="message")b.enqueue({type:"text-end",id:x.item.id,providerMetadata:{[c]:{itemId:x.item.id,...g.length>0&&{annotations:g}}}});else if(x.item.type==="function_call")m[x.output_index]=void 0,h=!0,b.enqueue({type:"tool-input-end",id:x.item.call_id}),b.enqueue({type:"tool-call",toolCallId:x.item.call_id,toolName:x.item.name,input:x.item.arguments,providerMetadata:{[c]:{itemId:x.item.id}}});else if(x.item.type==="web_search_call")m[x.output_index]=void 0,b.enqueue({type:"tool-result",toolCallId:x.item.id,toolName:n??"web_search",result:jN(x.item.action),providerExecuted:!0});else if(x.item.type==="computer_call")m[x.output_index]=void 0,b.enqueue({type:"tool-input-end",id:x.item.id}),b.enqueue({type:"tool-call",toolCallId:x.item.id,toolName:"computer_use",input:"",providerExecuted:!0}),b.enqueue({type:"tool-result",toolCallId:x.item.id,toolName:"computer_use",result:{type:"computer_use_tool_result",status:x.item.status||"completed"},providerExecuted:!0});else if(x.item.type==="file_search_call")m[x.output_index]=void 0,b.enqueue({type:"tool-result",toolCallId:x.item.id,toolName:"file_search",result:{queries:x.item.queries,results:(O=(M=x.item.results)==null?void 0:M.map(ne=>({attributes:ne.attributes,fileId:ne.file_id,filename:ne.filename,score:ne.score,text:ne.text})))!=null?O:null},providerExecuted:!0});else if(x.item.type==="code_interpreter_call")m[x.output_index]=void 0,b.enqueue({type:"tool-result",toolCallId:x.item.id,toolName:"code_interpreter",result:{outputs:x.item.outputs},providerExecuted:!0});else if(x.item.type==="image_generation_call")b.enqueue({type:"tool-result",toolCallId:x.item.id,toolName:"image_generation",result:{result:x.item.result},providerExecuted:!0});else if(x.item.type==="local_shell_call")m[x.output_index]=void 0,b.enqueue({type:"tool-call",toolCallId:x.item.call_id,toolName:"local_shell",input:JSON.stringify({action:{type:"exec",command:x.item.action.command,timeoutMs:x.item.action.timeout_ms,user:x.item.action.user,workingDirectory:x.item.action.working_directory,env:x.item.action.env}}),providerMetadata:{[c]:{itemId:x.item.id}}});else if(x.item.type==="reasoning"){let ne=f[x.item.id],pe=Object.entries(ne.summaryParts).filter(([Ur,hi])=>hi==="active"||hi==="can-conclude").map(([Ur])=>Ur);for(let Ur of pe)b.enqueue({type:"reasoning-end",id:`${x.item.id}:${Ur}`,providerMetadata:{[c]:{itemId:x.item.id,reasoningEncryptedContent:(v=x.item.encrypted_content)!=null?v:null}}});delete f[x.item.id]}}else if(GX(x)){let ne=m[x.output_index];ne!=null&&b.enqueue({type:"tool-input-delta",id:ne.toolCallId,delta:x.delta})}else if(WX(x)){let ne=m[x.output_index];ne!=null&&b.enqueue({type:"tool-input-delta",id:ne.toolCallId,delta:JSON.stringify(x.delta).slice(1,-1)})}else if(jX(x)){let ne=m[x.output_index];ne!=null&&(b.enqueue({type:"tool-input-delta",id:ne.toolCallId,delta:'"}'}),b.enqueue({type:"tool-input-end",id:ne.toolCallId}),b.enqueue({type:"tool-call",toolCallId:ne.toolCallId,toolName:"code_interpreter",input:JSON.stringify({code:x.code,containerId:ne.codeInterpreter.containerId}),providerExecuted:!0}))}else if(HX(x))p=x.response.id,b.enqueue({type:"response-metadata",id:x.response.id,timestamp:new Date(x.response.created_at*1e3),modelId:x.response.model});else if(UX(x))b.enqueue({type:"text-delta",id:x.item_id,delta:x.delta}),(F=(C=r.providerOptions)==null?void 0:C.openai)!=null&&F.logprobs&&x.logprobs&&d.push(x.logprobs);else if(x.type==="response.reasoning_summary_part.added"){if(x.summary_index>0){let ne=f[x.item_id];ne.summaryParts[x.summary_index]="active";for(let pe of Object.keys(ne.summaryParts))ne.summaryParts[pe]==="can-conclude"&&(b.enqueue({type:"reasoning-end",id:`${x.item_id}:${pe}`,providerMetadata:{[c]:{itemId:x.item_id}}}),ne.summaryParts[pe]="concluded");b.enqueue({type:"reasoning-start",id:`${x.item_id}:${x.summary_index}`,providerMetadata:{[c]:{itemId:x.item_id,reasoningEncryptedContent:(B=(I=f[x.item_id])==null?void 0:I.encryptedContent)!=null?B:null}}})}}else x.type==="response.reasoning_summary_text.delta"?b.enqueue({type:"reasoning-delta",id:`${x.item_id}:${x.summary_index}`,delta:x.delta,providerMetadata:{[c]:{itemId:x.item_id}}}):x.type==="response.reasoning_summary_part.done"?o?(b.enqueue({type:"reasoning-end",id:`${x.item_id}:${x.summary_index}`,providerMetadata:{[c]:{itemId:x.item_id}}}),f[x.item_id].summaryParts[x.summary_index]="concluded"):f[x.item_id].summaryParts[x.summary_index]="can-conclude":zX(x)?(l=GN({finishReason:(D=x.response.incomplete_details)==null?void 0:D.reason,hasFunctionCall:h}),u.inputTokens=x.response.usage.input_tokens,u.outputTokens=x.response.usage.output_tokens,u.totalTokens=x.response.usage.input_tokens+x.response.usage.output_tokens,u.reasoningTokens=(K=(ee=x.response.usage.output_tokens_details)==null?void 0:ee.reasoning_tokens)!=null?K:void 0,u.cachedInputTokens=(U=(ge=x.response.usage.input_tokens_details)==null?void 0:ge.cached_tokens)!=null?U:void 0,typeof x.response.service_tier=="string"&&(y=x.response.service_tier)):VX(x)?(g.push(x.annotation),x.annotation.type==="url_citation"?b.enqueue({type:"source",sourceType:"url",id:(le=(ue=(W=s.config).generateId)==null?void 0:ue.call(W))!=null?le:kr(),url:x.annotation.url,title:x.annotation.title}):x.annotation.type==="file_citation"&&b.enqueue({type:"source",sourceType:"document",id:(q=(ve=(He=s.config).generateId)==null?void 0:ve.call(He))!=null?q:kr(),mediaType:"text/plain",title:(it=(fe=x.annotation.quote)!=null?fe:x.annotation.filename)!=null?it:"Document",filename:(Ae=x.annotation.filename)!=null?Ae:x.annotation.file_id,...x.annotation.file_id?{providerMetadata:{[c]:{fileId:x.annotation.file_id}}}:{}})):$X(x)&&b.enqueue({type:"error",error:x})},flush(E){let b={[c]:{responseId:p}};d.length>0&&(b[c].logprobs=d),y!==void 0&&(b[c].serviceTier=y),E.enqueue({type:"finish",finishReason:l,usage:u,providerMetadata:b})}})),request:{body:e},response:{headers:i}}}};function UX(r){return r.type==="response.output_text.delta"}function BX(r){return r.type==="response.output_item.done"}function zX(r){return r.type==="response.completed"||r.type==="response.incomplete"}function HX(r){return r.type==="response.created"}function GX(r){return r.type==="response.function_call_arguments.delta"}function WX(r){return r.type==="response.code_interpreter_call_code.delta"}function jX(r){return r.type==="response.code_interpreter_call_code.done"}function WN(r){return r.type==="response.output_item.added"}function VX(r){return r.type==="response.output_text.annotation.added"}function $X(r){return r.type==="error"}function jN(r){var e;switch(r.type){case"search":return{action:{type:"search",query:(e=r.query)!=null?e:void 0},...r.sources!=null&&{sources:r.sources}};case"open_page":return{action:{type:"openPage",url:r.url}};case"find_in_page":return{action:{type:"findInPage",url:r.url,pattern:r.pattern}}}}var qX=ot(()=>me(db.object({instructions:db.string().nullish(),speed:db.number().min(.25).max(4).default(1).nullish()}))),KX=class{constructor(r,e){this.modelId=r,this.config=e,this.specificationVersion="v2"}get provider(){return this.config.provider}async getArgs({text:r,voice:e="alloy",outputFormat:t="mp3",speed:n,instructions:o,language:i,providerOptions:a}){let s=[],c=await Tr({provider:"openai",providerOptions:a,schema:qX}),l={model:this.modelId,input:r,voice:e,response_format:"mp3",speed:n,instructions:o};if(t&&(["mp3","opus","aac","flac","wav","pcm"].includes(t)?l.response_format=t:s.push({type:"unsupported-setting",setting:"outputFormat",details:`Unsupported output format: ${t}. Using mp3 instead.`})),c){let u={};for(let d in u){let p=u[d];p!==void 0&&(l[d]=p)}}return i&&s.push({type:"unsupported-setting",setting:"language",details:`OpenAI speech models do not support language selection. Language parameter "${i}" was ignored.`}),{requestBody:l,warnings:s}}async doGenerate(r){var e,t,n;let o=(n=(t=(e=this.config._internal)==null?void 0:e.currentDate)==null?void 0:t.call(e))!=null?n:new Date,{requestBody:i,warnings:a}=await this.getArgs(r),{value:s,responseHeaders:c,rawValue:l}=await vr({url:this.config.url({path:"/audio/speech",modelId:this.modelId}),headers:Qt(this.config.headers(),r.headers),body:i,failedResponseHandler:Yn,successfulResponseHandler:MN(),abortSignal:r.abortSignal,fetch:this.config.fetch});return{audio:s,warnings:a,request:{body:JSON.stringify(i)},response:{timestamp:o,modelId:this.modelId,headers:c,body:l}}}},YX=ot(()=>me(Ct.object({text:Ct.string(),language:Ct.string().nullish(),duration:Ct.number().nullish(),words:Ct.array(Ct.object({word:Ct.string(),start:Ct.number(),end:Ct.number()})).nullish(),segments:Ct.array(Ct.object({id:Ct.number(),seek:Ct.number(),start:Ct.number(),end:Ct.number(),text:Ct.string(),tokens:Ct.array(Ct.number()),temperature:Ct.number(),avg_logprob:Ct.number(),compression_ratio:Ct.number(),no_speech_prob:Ct.number()})).nullish()}))),XX=ot(()=>me(mi.object({include:mi.array(mi.string()).optional(),language:mi.string().optional(),prompt:mi.string().optional(),temperature:mi.number().min(0).max(1).default(0).optional(),timestampGranularities:mi.array(mi.enum(["word","segment"])).default(["segment"]).optional()}))),VN={afrikaans:"af",arabic:"ar",armenian:"hy",azerbaijani:"az",belarusian:"be",bosnian:"bs",bulgarian:"bg",catalan:"ca",chinese:"zh",croatian:"hr",czech:"cs",danish:"da",dutch:"nl",english:"en",estonian:"et",finnish:"fi",french:"fr",galician:"gl",german:"de",greek:"el",hebrew:"he",hindi:"hi",hungarian:"hu",icelandic:"is",indonesian:"id",italian:"it",japanese:"ja",kannada:"kn",kazakh:"kk",korean:"ko",latvian:"lv",lithuanian:"lt",macedonian:"mk",malay:"ms",marathi:"mr",maori:"mi",nepali:"ne",norwegian:"no",persian:"fa",polish:"pl",portuguese:"pt",romanian:"ro",russian:"ru",serbian:"sr",slovak:"sk",slovenian:"sl",spanish:"es",swahili:"sw",swedish:"sv",tagalog:"tl",tamil:"ta",thai:"th",turkish:"tr",ukrainian:"uk",urdu:"ur",vietnamese:"vi",welsh:"cy"},JX=class{constructor(r,e){this.modelId=r,this.config=e,this.specificationVersion="v2"}get provider(){return this.config.provider}async getArgs({audio:r,mediaType:e,providerOptions:t}){let n=[],o=await Tr({provider:"openai",providerOptions:t,schema:XX}),i=new FormData,a=r instanceof Uint8Array?new Blob([r]):new Blob([DN(r)]);i.append("model",this.modelId);let s=RN(e);if(i.append("file",new File([a],"audio",{type:e}),`audio.${s}`),o){let c={include:o.include,language:o.language,prompt:o.prompt,response_format:["gpt-4o-transcribe","gpt-4o-mini-transcribe"].includes(this.modelId)?"json":"verbose_json",temperature:o.temperature,timestamp_granularities:o.timestampGranularities};for(let[l,u]of Object.entries(c))if(u!=null)if(Array.isArray(u))for(let d of u)i.append(`${l}[]`,String(d));else i.append(l,String(u))}return{formData:i,warnings:n}}async doGenerate(r){var e,t,n,o,i,a,s,c;let l=(n=(t=(e=this.config._internal)==null?void 0:e.currentDate)==null?void 0:t.call(e))!=null?n:new Date,{formData:u,warnings:d}=await this.getArgs(r),{value:p,responseHeaders:m,rawValue:g}=await CN({url:this.config.url({path:"/audio/transcriptions",modelId:this.modelId}),headers:Qt(this.config.headers(),r.headers),formData:u,failedResponseHandler:Yn,successfulResponseHandler:un(YX),abortSignal:r.abortSignal,fetch:this.config.fetch}),h=p.language!=null&&p.language in VN?VN[p.language]:void 0;return{text:p.text,segments:(s=(a=(o=p.segments)==null?void 0:o.map(f=>({text:f.text,startSecond:f.start,endSecond:f.end})))!=null?a:(i=p.words)==null?void 0:i.map(f=>({text:f.word,startSecond:f.start,endSecond:f.end})))!=null?s:[],language:h,durationInSeconds:(c=p.duration)!=null?c:void 0,warnings:d,response:{timestamp:l,modelId:this.modelId,headers:m,body:g}}}},ZX="2.0.89";function pb(r={}){var e,t;let n=(e=kN(AN({settingValue:r.baseURL,environmentVariableName:"OPENAI_BASE_URL"})))!=null?e:"https://api.openai.com/v1",o=(t=r.name)!=null?t:"openai",i=()=>ob({Authorization:`Bearer ${vN({apiKey:r.apiKey,environmentVariableName:"OPENAI_API_KEY",description:"OpenAI"})}`,"OpenAI-Organization":r.organization,"OpenAI-Project":r.project,...r.headers},`ai-sdk/openai/${ZX}`),a=h=>new K5(h,{provider:`${o}.chat`,url:({path:f})=>`${n}${f}`,headers:i,fetch:r.fetch}),s=h=>new Z5(h,{provider:`${o}.completion`,url:({path:f})=>`${n}${f}`,headers:i,fetch:r.fetch}),c=h=>new tX(h,{provider:`${o}.embedding`,url:({path:f})=>`${n}${f}`,headers:i,fetch:r.fetch}),l=h=>new iX(h,{provider:`${o}.image`,url:({path:f})=>`${n}${f}`,headers:i,fetch:r.fetch}),u=h=>new JX(h,{provider:`${o}.transcription`,url:({path:f})=>`${n}${f}`,headers:i,fetch:r.fetch}),d=h=>new KX(h,{provider:`${o}.speech`,url:({path:f})=>`${n}${f}`,headers:i,fetch:r.fetch}),p=h=>{if(new.target)throw new Error("The OpenAI model function cannot be called with the new keyword.");return m(h)},m=h=>new FX(h,{provider:`${o}.responses`,url:({path:f})=>`${n}${f}`,headers:i,fetch:r.fetch,fileIdPrefixes:["file-"]}),g=function(h){return p(h)};return g.languageModel=p,g.chat=a,g.completion=s,g.responses=m,g.embedding=c,g.textEmbedding=c,g.textEmbeddingModel=c,g.image=l,g.imageModel=l,g.transcription=u,g.transcriptionModel=u,g.speech=d,g.speechModel=d,g.tools=MX,g}var C6e=pb();function ZN(r){let{apiKey:e,sessionId:t,extraHeaders:n,loggerTags:o}=r,i={Authorization:`Bearer ${e}`,[xd]:ha??"",...t&&{[mR]:t},...n||{}};return o&&(i[dR]=JSON.stringify(o)),i}var Bp=r=>e=>{let t=ZN(r);return QX({baseURL:`${r.baseUrl}/v1/llm/anthropic/${e}`,headers:t,apiKey:r.apiKey})(e)},QN=r=>e=>{let t=ZN(r);return pb({baseURL:`${r.baseUrl}/v1/llm/openai/${e}`,headers:t,apiKey:r.apiKey})(e)};var Sa=class extends $n{agentConfig;constructor(e,t){let n={...zv,...e};super(t),this.agentConfig=n}getAgentConfig(){return this.agentConfig}async rankChunksWithAi(e,t){let n={...e,loggerTags:t.loggerTags},o=await this.sendRequest(`/${j}/web-agent/recommend-chunks-ai`,{method:"POST",body:n,signal:t.abortSignal});return wv.parse(o)}async rankChunksWithRag(e,t){let n=await this.sendRequest(`/${j}/web-agent/recommend-chunks`,{method:"POST",body:{cliVersion:ha,...e},signal:t.abortSignal});return Rv.parse(n)}async getScreenshotFromS3(e){let t=await this.sendRequest(`/${j}/s3/visual-diff-screenshot`,{method:"POST",body:{url:e}});return e3.string().parse(t)}async getElementLocation(e,t){let n={...e,disableCache:t.disableCache,loggerTags:t.loggerTags,useMemory:t.useMemory,agentConfigVersion:this.agentConfig?.locator},o=await this.sendRequest(`/${j}/web-agent/locate-element`,{method:"POST",body:n,signal:t.abortSignal});return yR.parse(o)}async getAssertionResult(e,t){let n={...e,disableCache:!!t.disableCache,useConsensus:!!t.useConsensus,attemptNumber:t.attemptNumber,loggerTags:t.loggerTags,useMemory:t.useMemory,agentConfigVersion:this.agentConfig?.assertion},o=await this.sendRequest(`/${j}/web-agent/assertion`,{method:"POST",body:n,signal:t.abortSignal});return nf.parse(o)}async getLintStepResult(e,t){let n={...e,disableCache:!!t.disableCache,loggerTags:t.loggerTags},o=await this.sendRequest(`/${j}/web-agent/lint/step`,{method:"POST",body:n,signal:t.abortSignal});return SR.parse(o)}async getLintMcpCopilotMessageResult(e,t){let n={message:e.message,disableCache:!!t.disableCache,loggerTags:t.loggerTags},o=await this.sendRequest(`/${j}/web-agent/lint/mcp-copilot`,{method:"POST",body:n,signal:t.abortSignal});return gR.parse(o)}async getMcpCopilotConversationEvaluation(e,t){let n={messagesAndToolCalls:e.messagesAndToolCalls,disableCache:!!t.disableCache,loggerTags:t.loggerTags},o=await this.sendRequest(`/${j}/web-agent/mcp-copilot-conversation-evaluator`,{method:"POST",body:n,signal:t.abortSignal});return hR.parse(o)}async getMcpCopilotChatSummary(e,t){let n={messagesAndToolCalls:e.messagesAndToolCalls,disableCache:!!t.disableCache,loggerTags:t.loggerTags},o=await this.sendRequest(`/${j}/web-agent/mcp-copilot-chat-summary`,{method:"POST",body:n,signal:t.abortSignal});return fR.parse(o)}async getVisualAssertionResult(e,t){let n={...e,disableCache:!!t.disableCache,useConsensus:!!t.useConsensus,attemptNumber:t.attemptNumber,loggerTags:t.loggerTags,useMemory:t.useMemory,agentConfigVersion:this.agentConfig?.["visual-assertion"]},o=await this.sendRequest(`/${j}/web-agent/visual-assertion`,{method:"POST",body:n,signal:t.abortSignal});return nf.parse(o)}async getAiActionCommand(e,t){let n=await this.sendRequest(`/${j}/web-agent/next-command-dynamic`,{method:"POST",body:{...e,disableCache:t.disableCache,loggerTags:t.loggerTags},signal:t.abortSignal});return pR.parse(n)}async getMultiturnAiActionCommand(e,t){return await this.sendRequest(`/${j}/web-agent/ai-action/next-command`,{method:"POST",body:{...e,disableCache:t.disableCache,loggerTags:t.loggerTags},signal:t.abortSignal})}async getMultiturnAiActionEvaluation(e,t){let n=await this.sendRequest(`/${j}/web-agent/ai-action/evaluate`,{method:"POST",body:{...e,disableCache:t.disableCache,loggerTags:t.loggerTags},signal:t.abortSignal});return jg.parse(n)}async getReverseMappedDescription(e,t){let n=await this.sendRequest(`/${j}/web-agent/reverse-mapped-description`,{method:"POST",body:{...e,disableCache:t.disableCache,loggerTags:t.loggerTags},signal:t.abortSignal});return bR.parse(n)}async getTextExtraction(e,t){let n={...e,disableCache:t.disableCache,loggerTags:t.loggerTags,agentConfigVersion:this.agentConfig?.["text-extraction"]},o=await this.sendRequest(`/${j}/web-agent/text-extraction`,{method:"POST",body:n,signal:t.abortSignal});return Wg.parse(o)}async getPageSummary(e,t){let n={...e,disableCache:t.disableCache,loggerTags:t.loggerTags},o=await this.sendRequest(`/${j}/web-agent/page-summary`,{method:"POST",body:n,signal:t.abortSignal});return nv.parse(o)}async getSmartWaitingDecision(e,t){let n={...e,disableCache:t.disableCache,loggerTags:t.loggerTags},o=await this.sendRequest(`/${j}/web-agent/smart-waiting`,{method:"POST",body:n,signal:t.abortSignal});return ov.parse(o)}async getTestResultClassification(e,t){let n=await this.sendRequest(`/${j}/web-agent/result-classification`,{method:"POST",body:{...e,loggerTags:t.loggerTags},signal:t.abortSignal});return Og.parse(n)}async getExtractedKeywords(e,t){let n=await this.sendRequest(`/${j}/web-agent/extract-keywords`,{method:"POST",body:e,signal:t.abortSignal});return Bv.parse(n)}async getAutohealingProposal(e,t){let n=await this.sendRequest(`/${j}/web-agent/autoheal-section`,{method:"POST",body:{...e,loggerTags:t.loggerTags},signal:t.abortSignal});return ZT.parse(n)}async getFailureRecoveryProposal(e,t){let n=await this.sendRequest(`/${j}/web-agent/failure-recovery`,{method:"POST",body:{...e,loggerTags:t.loggerTags},signal:t.abortSignal});return tv.parse(n)}async getFailureRecoveryPlan(e,t){let n=await this.sendRequest(`/${j}/web-agent/failure-recovery-plan`,{method:"POST",body:{...e,loggerTags:t.loggerTags},signal:t.abortSignal});return ev.parse(n)}async getIframeRegex(e,t){let n=await this.sendRequest(`/${j}/web-agent/iframe-regex`,{method:"POST",body:e,signal:t.abortSignal});return dE.parse(n)}getVercelAnthropicModelFactory(e){let{sessionId:t,logger:n}=e;return Bp({baseUrl:this.baseUrl,apiKey:this.apiKey,loggerTags:ye(n),sessionId:t})}getVercelOpenAIModelFactory(e){let{sessionId:t,logger:n}=e;return QN({baseUrl:this.baseUrl,apiKey:this.apiKey,loggerTags:ye(n),sessionId:t})}};import{z as gb}from"zod";var _r=class extends $n{constructor(e){super({...e,mode:void 0})}getAppUrl(){return yc(this.baseUrl)}async getAuthInfo(){let e=await this.sendRequest(`/${j}/auth/check`,{method:"GET",retries:10,requestTimeoutMs:5e3,onFailedRequest:t=>{P.warn(`API key check failed: ${t.message}`)}});return OR.parse(e)}async bulkGetRunStatus(e){let t=await this.sendRequest(`/${j}/runs/status`,{method:"POST",body:e,retries:3,requestTimeoutMs:1e4});return _R.parse(t)}async getTestYAMLExport(e){let t=await this.sendRequest(`/${j}/tests/export`,{method:"POST",body:e,retries:3,requestTimeoutMs:3e4});return TR.parse(t)}async updateStepCaches(e,t){await this.sendRequest(`/${j}/cache`,{method:"PATCH",body:e,extraHeaders:t,retries:3,requestTimeoutMs:1e4,initialRetryDelayMs:3e3})}async getStepCacheForTest(e,t){let n=await this.sendRequest(`/${j}/cache`,{method:"POST",body:e,extraHeaders:t,retries:10,requestTimeoutMs:3e4,initialRetryDelayMs:3e3});return AR.parse(n)}async getWebStepCacheMemoryTraces(e){let t=await this.sendRequest(`/${j}/cache/traces`,{method:"POST",body:e,retries:10,requestTimeoutMs:3e4,initialRetryDelayMs:3e3});return of.parse(t)}async getMobileStepCacheMemoryTraces(e){let t=await this.sendRequest(`/${j}/mobile-cache/traces`,{method:"POST",body:e,retries:10,requestTimeoutMs:3e4,initialRetryDelayMs:3e3});return of.parse(t)}async updateMobileStepCaches(e,t){await this.sendRequest(`/${j}/mobile-cache`,{method:"PATCH",body:e,extraHeaders:t,retries:3,requestTimeoutMs:1e4,initialRetryDelayMs:3e3})}async getMobileStepCacheForTest(e,t){let n=await this.sendRequest(`/${j}/mobile-cache`,{method:"POST",body:e,extraHeaders:t,retries:10,requestTimeoutMs:3e4,initialRetryDelayMs:3e3});return RR.parse(n)}async queueTests(e){let t=await this.sendRequest(`/${j}/tests/queue`,{method:"POST",body:e,retries:3,requestTimeoutMs:1e4});return ER.parse(t)}async uploadScreenshot(e){let t=await this.sendRequest(`/${j}/screenshots`,{method:"POST",body:e,retries:3,requestTimeoutMs:5e3});return IR.parse(t)}async uploadOnDemandScreenshot(e){return await this.sendRequest(`/${j}/on-demand-screenshots`,{method:"POST",body:e,retries:3,requestTimeoutMs:5e3}),{apiServerUrl:`${this.baseUrl}/${j}/on-demand-screenshots/${e.id}`}}async fetchOnDemandScreenshot(e){let t={};return{data:await this.sendRequest(`/${j}/on-demand-screenshots/${encodeURIComponent(e)}`,{method:"GET",retries:3,requestTimeoutMs:5e3,responseType:"buffer",responseHeadersObject:t}),contentType:t["content-type"]??"image/jpeg"}}async getAllEnvironments(){let e=await this.sendRequest(`/${j}/environments`,{method:"GET",retries:3,requestTimeoutMs:5e3});return LR.parse(e)}async acquireCacheLock(e,t){let n=await this.sendRequest(`/${j}/result-cache/lock`,{method:"POST",body:e,signal:t,retries:3,requestTimeoutMs:3e4});return JR.parse(n)}async releaseCacheLock(e){await this.sendRequest(`/${j}/result-cache/lock`,{method:"DELETE",body:{key:e},retries:3,requestTimeoutMs:5e3})}async deleteCacheResult(e){await this.sendRequest(`/${j}/result-cache/entry`,{method:"DELETE",body:e,retries:3,requestTimeoutMs:5e3})}async setCacheResult(e){await this.sendRequest(`/${j}/result-cache/entry`,{method:"PATCH",body:e,retries:3,requestTimeoutMs:5e3})}async getCacheResult(e){try{return await this.sendRequest(`/${j}/result-cache/entry`,{method:"POST",body:e,retries:3,requestTimeoutMs:5e3})}catch(t){if(t instanceof Error&&t.message.includes("404"))return null;throw t}}async queueSuiteRuns(e){let t=await this.sendRequest(`/${j}/suites/queue`,{method:"POST",body:e,retries:3,requestTimeoutMs:5e3});return NR.parse(t)}async bulkGetRunGroupStatus(e){let t={runGroupIds:e},n=await this.sendRequest(`/${j}/run-groups/status`,{method:"POST",body:t,retries:3,requestTimeoutMs:5e3});return Ev.array().parse(n)}async uploadProposedSteps(e,t){try{await this.sendRequest(`/${j}/test-fragments/`,{method:"POST",body:e,retries:3,requestTimeoutMs:1e4})}catch(n){t.error({err:n},"Failed to upload proposed steps")}}async reportBillableEvents(e,t){try{await this.sendRequest(`/${j}/billing/events`,{method:"POST",body:t,retries:10,requestTimeoutMs:1e4})}catch(n){e.error({err:n},"Failed to report billable event")}}async fetchTestFragment(e){let t=await this.sendRequest(`/${j}/test-fragments/${e}`,{method:"GET",retries:3,requestTimeoutMs:1e4});return DR.parse(t)}async patchTestFragment(e,t){await this.sendRequest(`/${j}/test-fragments/${e}`,{method:"PATCH",body:t,retries:3,requestTimeoutMs:1e4})}async getPastTestResults(e,t){let n=await this.sendRequest(`/${j}/results/tests/${e}`,{method:"POST",body:t,retries:3,requestTimeoutMs:1e4});return kR.parse(n)}async generateTestResultsUploadUrl(){let e=await this.sendRequest(`/${j}/results/uploads`,{method:"POST",retries:3,requestTimeoutMs:1e4});return FR.parse(e)}async startProcessingResultsUpload(e,t){let n=await this.sendRequest(`/${j}/results/uploads/${e}/process`,{method:"POST",body:t,retries:3,requestTimeoutMs:1e4});return UR.parse(n)}async fetchIconKnowledgeBase(e){try{let t=await this.sendRequest(`/${j}/knowledge-base/icons`,{method:"GET",retries:3,requestTimeoutMs:5e3});return ew.parse(t)}catch(t){return e.error({err:t},"Failed to fetch icon knowledge base"),null}}async saveNewIcons(e,t){try{await this.sendRequest(`/${j}/knowledge-base/icons`,{method:"POST",body:e,retries:3,requestTimeoutMs:5e3})}catch(n){t.error({err:n},"Failed to save new icons to icon knowledge base")}}async getMergeBaseCommitFromGithub(e,t,n,o){let i=new URLSearchParams;i.set("base",n),i.set("head",o);let a=await this.sendRequest(`/${j}/git/github/${e}/${t}/merge-base-commit?${i.toString()}`,{method:"GET",retries:3,requestTimeoutMs:1e4});return Sc.parse(a)}async getCommitFromGithub(e,t,n){let o=await this.sendRequest(`/${j}/git/github/${e}/${t}/commits/${n}`,{method:"GET",retries:3,requestTimeoutMs:1e4});return Sc.parse(o)}async getMergedBranchFromGithub(e,t,n,o){let i=encodeURIComponent(n),a=await this.sendRequest(`/${j}/git/github/${e}/${t}/${i}/${o}/merged-branch`,{method:"GET",retries:3,requestTimeoutMs:1e4});return lf.parse(a)}async getMergeBaseCommitFromGitlab(e,t,n){let o=new URLSearchParams;o.set("base",t),o.set("head",n);let i=encodeURIComponent(e),a=await this.sendRequest(`/${j}/git/gitlab/${i}/merge-base-commit?${o.toString()}`,{method:"GET",retries:3,requestTimeoutMs:5e3});return Sc.parse(a)}async getCommitFromGitlab(e,t){let n=encodeURIComponent(e),o=await this.sendRequest(`/${j}/git/gitlab/${n}/commits/${t}`,{method:"GET",retries:3,requestTimeoutMs:1e4});return Sc.parse(o)}async getMergedBranchFromGitlab(e,t,n){let o=encodeURIComponent(t),i=encodeURIComponent(e),a=await this.sendRequest(`/${j}/git/gitlab/${i}/${o}/${n}/merged-branch`,{method:"GET",retries:3,requestTimeoutMs:1e4});return lf.parse(a)}async getAgentConfig(){let e=await this.sendRequest(`/${j}/web-agent/agent-config`,{method:"GET",retries:3,requestTimeoutMs:5e3});return gb.record(gb.string(),gb.string()).parse(e)}async getQuarantinedTests(){let e=await this.sendRequest(`/${j}/quarantine`,{method:"GET"});return BR.parse(e)}async quarantineTest(e,t,n){await this.sendRequest(`/${j}/quarantine`,{method:"POST",body:{testId:e.id,testName:e.name,reason:t,...n??{}},retries:3,requestTimeoutMs:1e4})}async unquarantineTest(e,t,n){await this.sendRequest(`/${j}/quarantine/${e.id}`,{method:"DELETE",body:{testName:e.name,reason:t,...n??{}},retries:3,requestTimeoutMs:1e4})}async createAndroidEmulator(e){let t=await this.sendRequest(`/${j}/limbar/android`,{method:"POST",retries:3,body:e,requestTimeoutMs:9e4,initialRetryDelayMs:5e3,maxRetryDelayMs:15e3});return zR.parse(t)}async extendAndroidEmulatorTtl(e){try{await this.sendRequest(`/${j}/limbar/android/${e}/keepalive`,{method:"POST",retries:3,requestTimeoutMs:15e3})}catch{}}async generateAndroidAssetUrls({channel:e,tag:t,md5:n}){let o={channel:e,tag:t,md5:n},i=await this.sendRequest(`/${j}/limbar/android/upload-url`,{method:"POST",retries:3,body:o,requestTimeoutMs:15e3,logResponse:!0});return GR.parse(i)}async deleteAndroidEmulator(e){await this.sendRequest(`/${j}/limbar/android/${e}`,{method:"DELETE",retries:3,requestTimeoutMs:3e4})}async getAndroidAssets(){let e=await this.sendRequest(`/${j}/limbar/assets`,{method:"GET",retries:3,requestTimeoutMs:1e4});return WR.parse(e)}async getLimbarAssetDownloadUrl(e,t){let n=await this.sendRequest(`/${j}/limbar/assets/${e}/${t}/download-url`,{method:"GET",retries:2,requestTimeoutMs:3e4});return jR.parse(n)}async deleteAndroidAsset(e,t){await this.sendRequest(`/${j}/limbar/assets/${e}/${t}`,{method:"DELETE",retries:3,requestTimeoutMs:1e4})}async createIosEmulator(e){let t=await this.sendRequest(`/${j}/limbar/ios`,{method:"POST",retries:3,body:e,requestTimeoutMs:9e4,initialRetryDelayMs:5e3,maxRetryDelayMs:15e3});return HR.parse(t)}async extendIosEmulatorTtl(e){try{await this.sendRequest(`/${j}/limbar/ios/${e}/keepalive`,{method:"POST",retries:3,requestTimeoutMs:15e3})}catch{}}async deleteIosEmulator(e){await this.sendRequest(`/${j}/limbar/ios/${e}`,{method:"DELETE",retries:3,requestTimeoutMs:3e4})}async generateMobileLogcatUploadUrl(e){let t=await this.sendRequest(`/${j}/logcat/mobile/upload`,{method:"POST",body:e,retries:3,requestTimeoutMs:1e4});return LA.parse(t)}};async function hb(r){let e=process.versions.node,t=parseInt(e.split(".")[0]);(isNaN(t)||t<18)&&(P.error(`Node.js version 20 or higher is required to run the CLI. Detected: ${process.versions.node}.`),process.exit(1)),P.debug(`Identified node version ${e}`);let n=await r.client.getAuthInfo();return P.debug("Got auth info from API"),n}var zp=class{apiClient;constructor(e){this.apiClient=e}async reportBillableEvents(e,t){await this.apiClient.reportBillableEvents(e,t)}};var Xs=class extends $n{generator;constructor(e,t){super(e),this.generator=t}async runTemplateMatching(e,t={}){let n=await this.sendRequest(`/${j}/web-agent/template-matching`,{method:"POST",body:e,signal:t?.signal});return mE.parse(n)}async constructIframeRegex(e,t={}){return this.generator.getIframeRegex(e,{abortSignal:t.signal})}};var Js=class{constructor(e,t){this.client=e;this.orgId=t}getApiServerUrl(){return this.client.baseUrl}getAppServerUrl(){let e=this.getApiServerUrl();return yc(e)}async acquireCacheLock(e,t){return this.client.acquireCacheLock(e,t)}async createOnDemandScreenshot(e,t,n){let{apiServerUrl:o}=await this.client.uploadOnDemandScreenshot({id:e,screenshot:t.toString("base64"),contentType:n});return{apiServerUrl:o,appServerUrl:`${this.getAppServerUrl()}/api/on-demand-screenshots/${e}`,universalHandle:{id:e,contentType:n}}}async fetchOnDemandScreenshot(e){return this.client.fetchOnDemandScreenshot(e.id)}async releaseCacheLock(e){return this.client.releaseCacheLock(e)}async deleteCacheResult(e){return this.client.deleteCacheResult(e)}async setCacheResult(e){return this.client.setCacheResult(e)}async getCacheResult(e){return this.client.getCacheResult(e)}fetchIconKnowledgeBase(e){return this.client.fetchIconKnowledgeBase(e)}saveNewIcons(e,t){return this.client.saveNewIcons(e,t)}};import{Faker as t3,en as r3}from"@faker-js/faker";var Zs="v1",Qs=class{httpClient;fakerInstance;type="API_CLIENT";sms={send:this.sendSms.bind(this),fetchLatest:this.fetchLatestSms.bind(this)};email={send:this.sendEmail.bind(this),fetchLatest:this.fetchLatestEmail.bind(this),fetchAll:this.fetchAllEmails.bind(this)};ai={generate:this.sendAiGenerate.bind(this)};constructor(e){this.httpClient=e.httpClient,e.fakerSeed&&(this.fakerInstance=new t3({locale:r3}),this.fakerInstance.seed(e.fakerSeed))}async sendAiGenerate(e){let t=typeof e=="string"?{input:e}:e;return this.httpClient.sendRequest(`/${Zs}/tools/ai/generate`,{method:"POST",body:t}).catch(n=>{throw n instanceof En?new Error(n.rawError):new Error(`Failed to send AI generation: ${n.message}`)})}async sendSms(e){return this.httpClient.sendRequest(`/${Zs}/tools/sms/send`,{method:"POST",body:e}).then(()=>{}).catch(t=>{throw t instanceof En?new Error(t.rawError):new Error(`Failed to send sms: ${t.message}`)})}async fetchLatestSms(e){return this.httpClient.sendRequest(`/${Zs}/tools/sms/fetchLatest`,{method:"POST",body:e}).catch(t=>{throw t instanceof En?new Error(t.rawError):t})}async sendEmail(e){return this.httpClient.sendRequest(`/${Zs}/tools/email/send`,{method:"POST",body:e}).then(()=>{}).catch(t=>{throw t instanceof En?new Error(t.rawError):new Error(`Failed to send email: ${t.message}`)})}async fetchAllEmails(e){return this.httpClient.sendRequest(`/${Zs}/tools/email/fetchAll`,{method:"POST",body:e}).catch(t=>{throw t instanceof En?new Error(t.rawError):new Error(`Failed to fetch all emails: ${t.message}`)})}async fetchLatestEmail(e){return this.httpClient.sendRequest(`/${Zs}/tools/email/fetchLatest`,{method:"POST",body:e}).catch(t=>{throw t instanceof En?new Error(t.rawError):new Error(`Failed to fetch latest emails: ${t.message}`)})}};function e0(r,e,t){return fetch(r,{method:"PUT",body:t,headers:{"Content-Type":e}})}var Hp=class{constructor(e){this.client=e}async uploadResultsArchive(e,t){let{uploadUrl:n,id:o}=await this.client.generateTestResultsUploadUrl(),i=await e0(n,"application/zip",t);if(!i.ok)throw new Error(`Failed to upload test results: ${await i.text()}`);let{runGroupId:a}=await this.client.startProcessingResultsUpload(o,{runGroupId:e});return a}};var el=class extends $n{constructor(e){super(e)}async getAndroidElementLocation(e,t){let n={...e,disableCache:t.disableCache,useMemory:t.useMemory,agentConfigVersion:t.agentConfigVersion,loggerTags:t.loggerTags},o=await this.sendRequest(`/${j}/mobile-agent/locate-element`,{method:"POST",body:n,signal:t.abortSignal});return Nh.parse(o)}async evaluateAndroidAssertion(e,t){let n={...e,disableCache:t.disableCache,useMemory:t.useMemory,agentConfigVersion:t.agentConfigVersion,loggerTags:t.loggerTags},o=await this.sendRequest(`/${j}/mobile-agent/assertion`,{method:"POST",body:n,signal:t.abortSignal});return Dh.parse(o)}async getAndroidFailureRecoveryPlan(e,t){let n=await this.sendRequest(`/${j}/mobile-agent/failure-recovery-plan`,{method:"POST",body:{...e,loggerTags:t.loggerTags},signal:t.abortSignal});return kh.parse(n)}async getIosElementLocation(e,t){let n={...e,disableCache:t.disableCache,useMemory:t.useMemory,agentConfigVersion:t.agentConfigVersion,loggerTags:t.loggerTags},o=await this.sendRequest(`/${j}/ios-agent/locate-element`,{method:"POST",body:n,signal:t.abortSignal});return Nh.parse(o)}async evaluateIosAssertion(e,t){let n={...e,disableCache:t.disableCache,useMemory:t.useMemory,agentConfigVersion:t.agentConfigVersion,loggerTags:t.loggerTags},o=await this.sendRequest(`/${j}/ios-agent/assertion`,{method:"POST",body:n,signal:t.abortSignal});return Dh.parse(o)}async getIosFailureRecoveryPlan(e,t){let n=await this.sendRequest(`/${j}/ios-agent/failure-recovery-plan`,{method:"POST",body:{...e,loggerTags:t.loggerTags},signal:t.abortSignal});return kh.parse(n)}getVercelAnthropicModelFactory(e){let{logger:t,sessionId:n}=e;return Bp({baseUrl:this.baseUrl,apiKey:this.apiKey,sessionId:n,loggerTags:ye(t)})}};function pi({logger:r,orgId:e,client:t,gitMetadata:n,regenerateCache:o,alwaysSaveCache:i,noCache:a}){return a?new Pd:new fb(r,e,t,n,{alwaysSaveCache:i,regenerateCache:o})}var fb=class{constructor(e,t,n,o,i){this.orgId=t;this.client=n;let{regenerateCache:a,alwaysSaveCache:s}=i,{gitBranchName:c,gitProtectedBranches:l}=o;this.cacheHeaders=fc(o),this.readCaches=!a,e.info({options:i,gitBranchName:c,gitProtectedBranches:l},"Cache storage initialization options");let u=c&&l.includes(c);s||!u?this.writeCaches=!0:this.writeCaches=!1}cacheHeaders;readCaches;writeCaches;async saveEntries({entries:e,testId:t,logger:n}){if(!this.writeCaches){n.debug("Skipping cache storage because branch is protected");return}try{await this.client.updateMobileStepCaches({entries:e,testId:t},this.cacheHeaders)}catch(o){n.warn({err:o},"Failed to save mobile step cache entries, continuing...")}}async resolveEntries(e){if(!this.readCaches){e.logger.debug("Skipping cache resolution because of regenerate flag");return}let t=await this.client.getMobileStepCacheForTest({testId:e.testId},this.cacheHeaders),{steps:n}=e.stepLists;n&&NS({steps:n,stepCacheEntries:t,logger:e.logger})}async populateCacheForRun(e){if(!this.readCaches){e.logger.debug("Skipping cache resolution because of regenerate flag");return}let{steps:t}=e.stepLists;if(e.skipFetchingCacheFromStorage||await this.resolveEntries(e),!this.writeCaches){e.logger.info("Skipping mobile cache last used at update because branch is protected");return}let{cachesToSave:n}=await zn({platform:e.platform,steps:t,cacheCreationParams:{testId:e.testId,orgId:this.orgId}});try{await this.client.updateMobileStepCaches({entries:n,testId:e.testId},this.cacheHeaders)}catch(o){e.logger.warn({err:o},"Failed to update mobile step cache entries, continuing...")}}async getCacheKeyForStep(e){let t=await this.client.getMobileStepCacheForTest({testId:e.testId},this.cacheHeaders);return DS({step:e.step,stepCacheEntries:t,parentStepIdChain:e.parentStepIdChain,logger:e.logger,options:{ignoreCacheValueOnStep:!0}})}};import Gp from"path";function n3(r){let e=new t0,t=Gp.join(r,"metadata.json"),n=us.parse(JSON.parse(Sb.readFileSync(t,"utf-8")));e.addLocalFile(t);for(let o of Sb.readdirSync(Gp.join(r,"runs"))){if(!o.endsWith(".zip"))continue;let i=o.replace(/\.zip$/,""),a=new t0(Gp.join(r,"runs",o));for(let s of a.getEntries())s.isDirectory||e.addFile(Gp.join("runs",i,s.entryName),s.getData())}return{runGroupId:n.id,buffer:e.toBuffer()}}async function Wp(r){let{client:e,consoleLogger:t,resultsPath:n}=r;if(!Sb.existsSync(n)){t.warn("Results path does not exist, skipping upload.");return}let o=new Hp(e);try{let{runGroupId:i,buffer:a}=n3(n),s=await o.uploadResultsArchive(i,a),c=`${e.getAppUrl()}/run-groups/${s}`;t.success(`Successfully uploaded test results. Once processed, your results can be found at ${c}`);return}catch(i){let a;i instanceof Error?a=i.message:typeof i=="string"?a=i:a="Unknown error",t.error(`Failed to upload test results: ${a}.`);return}}import o3 from"adm-zip";import lr from"fs";import dn from"path";var yu=class r{constructor(e){this.filePath=e;lr.rmSync(this.filePath,{recursive:!0,force:!0}),lr.mkdirSync(this.filePath,{recursive:!0})}children=[];streams=[];close(){for(let e of this.children)e.close();for(let e of this.streams)e.end()}cd(e){let t=new r(dn.join(this.filePath,e));return this.children.push(t),t}cwd(){return this.filePath}mkdir(e){lr.mkdirSync(dn.join(this.filePath,e),{recursive:!0})}readFile(e){let t=dn.join(this.filePath,e);if(lr.existsSync(t))return lr.readFileSync(t)}storeFile(e){let{name:t,contents:n}=e,o=dn.join(this.filePath,t);try{lr.writeFileSync(o,n)}catch{}}createFileStream(e){let t=dn.join(this.filePath,e),n=lr.createWriteStream(t);return this.streams.push(n),n}createRunArchive(e){let t=new yb(dn.join(this.filePath,"runs"),e);return this.children.push(t),t}},yb=class{children=[];tempPath;finalPath;constructor(e,t){this.tempPath=dn.join(e,`temp-storage-${t}`),this.finalPath=dn.join(e,`${t}.zip`),lr.rmSync(this.tempPath,{recursive:!0,force:!0}),lr.rmSync(this.finalPath,{recursive:!0,force:!0}),lr.mkdirSync(this.tempPath,{recursive:!0})}readFile(e){let t=dn.join(this.tempPath,e);if(lr.existsSync(t))return lr.readFileSync(t)}mkdir(e){lr.mkdirSync(dn.join(this.tempPath,e),{recursive:!0})}cd(e){let t=new yu(dn.join(this.tempPath,e));return this.children.push(t),t}cwd(){return this.tempPath}storeFile(e){let{name:t,contents:n}=e,o=dn.join(this.tempPath,t);lr.writeFileSync(o,n)}close(){for(let n of this.children)n.close();let e=new o3;e.addLocalFolder(this.tempPath,void 0,n=>n!==".DS_Store");let t=e.toBuffer();lr.writeFileSync(this.finalPath,t),lr.rmSync(this.tempPath,{recursive:!0,force:!0})}};import i3 from"adm-zip";import{randomUUID as a3}from"crypto";import Ht from"fs";import tr from"path";function i0(r){try{return Ht.existsSync(r)?JSON.parse(Ht.readFileSync(r,"utf-8")):void 0}catch{return}}function r0(r){return Ht.existsSync(r)?Ht.readFileSync(r,"utf-8").split(`
|
|
4617
|
-
`).map(t=>t.trim()).filter(t=>t.length>0):[]}function s3(r,e){let t=r.attemptIdToAttemptNumber.get(e);if(t)return tr.join(r.inflatedPath,"attempts",t);let n=tr.join(r.inflatedPath,"attempts");if(!Ht.existsSync(n))return;let o=Ht.readdirSync(n,{withFileTypes:!0}).filter(i=>i.isDirectory()).map(i=>i.name);for(let i of o){let a=tr.join(n,i,"metadata.json"),s=i0(a);if(typeof s!="object"||s===null)continue;let c=s.id;if(typeof c=="string"&&c===e)return r.attemptIdToAttemptNumber.set(e,i),tr.join(n,i)}}function n0(r,e,t){let n=tr.join(r,"attempts");if(!Ht.existsSync(n))return;let o=Ht.readdirSync(n,{withFileTypes:!0}).filter(i=>i.isDirectory()).map(i=>i.name);for(let i of o){let a=tr.join(n,i,"assets",`${e}.${t}`);if(Ht.existsSync(a))return a}}var jp=class{constructor(e,t,n){this.outputDir=e;this.runId=t;this.runAttemptId=n;this.runsDir=tr.join(e,"runs"),this.zipPath=tr.join(this.runsDir,`${t}.zip`)}inflatedByRunId=new Map;zipPath;runsDir;ensureInflatedRun(e){let t=this.inflatedByRunId.get(e);if(t)return t;if(e!==this.runId||!Ht.existsSync(this.zipPath))return;let n=tr.join(this.runsDir,`temp-unzipped-${e}-${a3()}`);Ht.mkdirSync(n,{recursive:!0}),new i3(this.zipPath).extractAllTo(n,!0);let i={runId:e,zipPath:this.zipPath,inflatedPath:n,attemptIdToAttemptNumber:new Map};return this.inflatedByRunId.set(e,i),i}close(){for(let e of this.inflatedByRunId.values())Ht.rmSync(e.inflatedPath,{recursive:!0,force:!0});this.inflatedByRunId.clear()}getAttemptDir(){let e=this.ensureInflatedRun(this.runId);if(e)return s3(e,this.runAttemptId)}listVideoAssetPaths(){let e=this.getAttemptDir();if(!e)return[];let t=tr.join(e,"assets");return Ht.existsSync(t)?Ht.readdirSync(t,{withFileTypes:!0}).filter(o=>o.isFile()).map(o=>tr.join(t,o.name)).filter(o=>{let i=tr.extname(o).toLowerCase();return i===".webm"||i===".mp4"}):[]}readAttemptAssetText(e,t){let n=this.getAttemptDir();if(!n)return;let o=tr.join(n,"assets",`${e}.${t}`);if(Ht.existsSync(o))try{return Ht.readFileSync(o,"utf-8")}catch{return}}async getConsoleLogsForRunAttempt(e,t,n){if(t!==this.runId||n!==this.runAttemptId)return;let o=this.getAttemptDir();if(!o)return;let i=i0(tr.join(o,"console.json")),a=Jh.safeParse(i);return a.success?a.data:void 0}async getNetworkLogsForRunAttempt(e,t,n){if(t!==this.runId||n!==this.runAttemptId)return;let o=this.getAttemptDir();if(!o)return;let i=tr.join(o,"assets","har-pages.log"),a=tr.join(o,"assets","har-entries.log"),s={};for(let u of r0(i)){let d=dc.safeParse(o0(u));d.success&&(s[d.data.id]=d.data)}let c={},l=r0(a);for(let u=0;u<l.length;u++){let d=l[u],p=mc.safeParse(o0(d));if(!p.success)continue;let m=`${p.data.startedDateTime}-${u}`;c[m]=p.data}if(Object.keys(c).length!==0)return Qh(s,c)}async getHtmlSnapshot(e,t){let n=this.readAttemptAssetText(t,"html");if(n)return n;let o=this.ensureInflatedRun(this.runId);if(!o)return;let i=n0(o.inflatedPath,t,"html");if(i)try{return Ht.readFileSync(i,"utf-8")}catch{return}}async getA11yTreeSnapshot(e,t){let n=this.readAttemptAssetText(t,"xml");if(n)return n;let o=this.ensureInflatedRun(this.runId);if(!o)return;let i=n0(o.inflatedPath,t,"xml");if(i)try{return Ht.readFileSync(i,"utf-8")}catch{return}}async getScreenshot(e,t){if(!this.ensureInflatedRun(this.runId))return;let o=this.getAttemptDir(),i=o?tr.join(o,"assets",`${t}.jpeg`):void 0;if(i)try{return Ht.readFileSync(i)}catch{return}}};function o0(r){try{return JSON.parse(r)}catch{return}}import Ta from"fs";import $p from"fs";import f3 from"open";import Eb from"path";import h3 from"express";import l3 from"adm-zip";import{Router as c3}from"express";import tl from"fs";import bu from"path";function a0(r){let e=c3(),t=bu.join(r,"runs");return e.get("/",async(n,o)=>{try{let i=u3(r);if(!i){o.status(404).json({error:"No run group found"});return}if(!tl.existsSync(t)){o.status(404).json({error:"No runs found for run group"});return}let a=d3(t,i),s={...i,id:i.id??"local-run-group",createdAt:i.startedAt,runs:a};o.status(200).json(s)}catch(i){o.status(500).json({error:`Error loading run group: ${i.message}`})}}),e}function u3(r){let e=bu.join(r,"metadata.json");if(!tl.existsSync(e))return P.error("Run group metadata file not found"),null;try{let t=tl.readFileSync(e,"utf-8");return us.parse(JSON.parse(t))}catch(t){return P.error({err:t},"Error reading run group metadata"),null}}function d3(r,e){let t=tl.readdirSync(r).filter(o=>o.endsWith(".zip")).sort((o,i)=>{let a=tl.statSync(bu.join(r,o));return tl.statSync(bu.join(r,i)).mtime.getTime()-a.mtime.getTime()}),n=[];for(let o of t){let i=bu.join(r,o),a=o.replace(/\.zip$/i,"");n.push(m3(i,a,e))}return n}function m3(r,e,t){let o=new l3(r).getEntry("metadata.json");if(!o)throw new Error(`No entry found for file ${r}/metadata.json`);try{let i=o.getData().toString("utf-8"),a=JSON.parse(i),s=mw.parse(a);return pP(s,e,{runGroupMetadata:t,runAttempts:[],organizationId:"local"})}catch(i){throw P.error({err:i,zipPath:r},"Error parsing metadata.json for run"),new Error(`Error parsing metadata.json for run ${r}`)}}import{Router as p3}from"express";import s0 from"fs";import Vp from"path";function l0(r){let e=p3(),t=Vp.join(r,"runs");return e.get("/:filename",(n,o)=>{let i=n.params.filename;if(!i||!i.endsWith(".zip")){o.status(404).send("Not found");return}let a=Vp.join(t,i),s=Vp.resolve(a),c=Vp.resolve(t);if(!s.startsWith(c)){o.status(403).send("Forbidden");return}if(!s0.existsSync(a)){o.status(404).send("File not found");return}try{o.setHeader("Content-Type","application/zip"),o.setHeader("Content-Disposition",`attachment; filename="${i}"`);let l=s0.readFileSync(a);o.send(l)}catch(l){o.status(500).send(`Error reading file: ${l.message}`)}}),e}import{Router as g3}from"express";import bb from"fs";import rl from"path";function c0(r){let e=g3();return e.get("*",(t,n)=>{let o=t.path==="/"?rl.join(r,"index.html"):rl.join(r,t.path),i=rl.resolve(o),a=rl.resolve(r);if(!i.startsWith(a)){n.status(403).send("Forbidden");return}if(!bb.existsSync(o)&&(o=rl.join(r,"index.html"),!bb.existsSync(o))){n.status(404).send("File not found");return}try{let s=rl.extname(o).toLowerCase(),c=pc[s]||"application/octet-stream";n.setHeader("Content-Type",c);let l=bb.readFileSync(o);n.send(l)}catch(s){n.status(500).send(`Error reading file: ${s.message}`)}}),e}async function u0(r,e,t){let n=e??await Yo(vd,"local-run-viewer-server"),o=h3();return o.use((i,a,s)=>{a.setHeader("Access-Control-Allow-Origin","*"),a.setHeader("Cache-Control","no-cache"),s()}),o.use("/api/runs",l0(r)),o.use("/api/run-group",a0(r)),t&&o.use("/",c0(t)),new Promise((i,a)=>{let s=o.listen(n,()=>{let c=`http://localhost:${n}`;i({port:n,url:c,stop:()=>{s.close()}})});s.on("error",c=>{a(c)})})}async function Tb(r){let{staticDir:e,resultsPath:t,runId:n,port:o}=r,i=Eb.resolve(t),a=Eb.join(i,"runs"),s;if(n){s=`${n.replace(/\.zip$/i,"")}.zip`;let l=Eb.join(a,s);if(!$p.existsSync(l)){let u=[];if($p.existsSync(a))for(let d of $p.readdirSync(a))d.endsWith(".zip")&&u.push(d.replace(/\.zip$/i,""));P.error(`Run not found: ${s} in ${a}`),u.length>0&&P.error(`Available runs: ${u.join(", ")}`),process.exit(1)}}$p.existsSync(e)||(P.error(`Static frontend files not found at ${e}. Please ensure the CLI is properly built.`),process.exit(1));try{let l=(await u0(i,o,e)).url;P.info(`Run viewer running at ${l}`);let u=new URL(l);s&&u.searchParams.set("zipUrl",`${l}/api/runs/${s}`),await f3(u.toString())}catch(c){P.error(`Failed to start run viewer: ${c.message}`),process.exit(1)}}import oD from"body-parser";import MJ from"cors";import PJ from"dedent";import{Router as v3}from"express";import qp from"fs";import S3 from"path";var y3=new Mm(30,60*1e3),wb="https://api.momentic.ai",Ab,m0,p0=r=>{wb=r},Cb=()=>wb;var g0=r=>{m0=r},h0=()=>m0,Mr=()=>Ab;var nl,Rb,d0,f0=async r=>{if(Ab&&nl&&d0)return nl;let e=new _r({baseUrl:wb,apiKey:r,logger:P});Ab=e;try{let t=await e.getAuthInfo();return nl=t.orgId,Rb=t.userId,d0=r,nl}catch(t){throw new Error(`Error checking API key against server: ${t}`)}},Xn=()=>{if(!nl)throw new Error("Your organization ID is invalid.");return nl},Kp=()=>{if(!Rb)throw new Error("Your user ID is invalid.");return Rb};var xb,vb,S0=(r,e)=>{xb=r,vb?.abort(),vb=new AbortController;let t=vb.signal,n=[r.configFilePath];r.config.environments?.forEach(o=>{if(!o.envFile)return;let i=S3.resolve(r.rootDir,o.envFile);try{if(qp.lstatSync(i).isSymbolicLink())return;qp.existsSync(i)&&n.push(i)}catch(a){P.warn({err:a},`Failed to check if env file ${i} exists`)}});try{b3({filesToWatch:n,revalidator:e,signal:t,project:r})}catch(o){P.error({err:o},"Failed to start config file watchers")}},je=()=>xb;function b3({filesToWatch:r,revalidator:e,signal:t,project:n}){P.debug("Starting watch on the following files:"),r.forEach(o=>{P.debug(`- ${o}`)}),r.forEach(o=>{let i=async(s,c)=>{s.mtime.getTime()!==c.mtime.getTime()&&(y3.increment("setLocalProject")&&P.warn(`A file change under the ${n.rootDir} directory has caused Momentic to reload its configuration more than 30 times in the last minute. Rapid changes to files may indicate your momentic.config.yaml 'include' glob is incorrect. Please ensure temporary, library, and auto-generated files are not included in Momentic's context.`),xb=await Promise.resolve(e(n.configFilePath)))};qp.watchFile(o,{persistent:!1},i);let a=()=>{qp.unwatchFile(o,i),t.removeEventListener("abort",a)};t.addEventListener("abort",a),process.once("SIGUSR2",()=>{a(),process.kill(process.pid,"SIGUSR2")})})}function De(r){return function(...e){let t=e[e.length-1],n=r(...e);Promise.resolve(n).catch(t)}}import{hostname as E3}from"os";var T3="0.33.4",ya=ms({app:"desktop-server",hostname:E3(),disableConsoleLogs:!0,captureExceptions:!0}).child({cliVersion:T3});(async()=>{try{let r=await mu(ya);r.gitBranchName&&ya.addBinding("branch",r.gitBranchName)}catch{}})();var y0=v3();y0.get("/",async(r,e)=>{let t=je(),n=Mr();if(!n){e.status(500).json({message:"API client not initialized"});return}let o=await sn(ya,n,t),i=o?.gitProtectedBranches&&o?.gitBranchName&&o.gitProtectedBranches.includes(o.gitBranchName),{noCache:a,alwaysSaveCache:s}=h0(),c=!a&&(s||!i);e.status(200).json({saveCaches:c,checkedOutBranch:o?.gitBranchName})});var _b=y0;import{Router as A3}from"express";import Ar from"fs";import{globSync as R3}from"glob";import Kt from"path";var Tu=A3();function Eu(r){let e=je(),t=Kt.dirname(e.configFilePath);return Kt.join(t,...r)}function w3(r){let e=je(),t=Kt.dirname(e.configFilePath),n=Kt.relative(t,r);return n?n.split(Kt.sep):[]}function C3(r,e){let t=Ar.statSync(r),n=w3(r);return ef.parse({name:e,absolutePath:r,relativePath:n.join(Kt.sep),pathSegments:n,isDirectory:t.isDirectory(),size:t.size,createdAt:t.birthtime,modifiedAt:t.mtime,accessedAt:t.atime})}Tu.post("/",De(async(r,e,t)=>{let n;try{n=VA.parse(r.body).pathSegments}catch(d){e.status(400).json({error:`Failed to parse folder read body: ${d}`});return}let o=Eu(n);if(!Ar.existsSync(o)){e.status(404).json({error:`Path not found: ${n.join(Kt.sep)}`});return}if(!Ar.statSync(o).isDirectory()){e.status(400).json({error:`Path is not a directory: ${n.join(Kt.sep)}`});return}let a=je(),s=Array.from(a.config.exclude??[]).concat(Td),l=R3("*",{absolute:!1,cwd:o,ignore:s,dotRelative:!1,maxDepth:1,nodir:!1}).map(d=>{let p=Kt.join(o,d);return C3(p,d)}),u={absolutePath:o,pathSegments:n,contents:l};e.status(200).json(u)}));Tu.put("/",De(async(r,e,t)=>{let n;try{n=$A.parse(r.body).pathSegments}catch(a){e.status(400).json({error:`Failed to parse folder create body: ${a}`});return}let o=Eu(n);if(Ar.existsSync(o)){e.status(200).json({success:!0,message:`Folder already exists: ${n.join(Kt.sep)}`,pathSegments:n});return}Ar.mkdirSync(o,{recursive:!0});let i={success:!0,message:`Folder created: ${n.join(Kt.sep)}`,pathSegments:n};e.status(201).json(i)}));Tu.patch("/",De(async(r,e,t)=>{let n,o;try{let l=qA.parse(r.body);n=l.pathSegments,o=l.newPathSegments}catch(l){e.status(400).json({error:`Failed to parse folder update body: ${l}`});return}let i=Eu(n),a=Eu(o);if(!Ar.existsSync(i)){e.status(400).json({error:`Folder not found: ${n.join(Kt.sep)}`});return}if(Ar.existsSync(a)){e.status(400).json({error:`Destination already exists: ${o.join(Kt.sep)}`});return}let s=Kt.dirname(a);Ar.existsSync(s)||Ar.mkdirSync(s,{recursive:!0}),Ar.renameSync(i,a);let c={success:!0,message:`Folder moved from ${n.join(Kt.sep)} to ${o.join(Kt.sep)}`,pathSegments:o};e.status(200).json(c)}));Tu.delete("/",De(async(r,e,t)=>{let n,o=!0;try{let c=KA.parse(r.body);n=c.pathSegments,o=c.recursive??!0}catch(c){e.status(400).json({error:`Failed to parse folder delete body: ${c}`});return}let i=Eu(n);if(!Ar.existsSync(i)){e.status(200).json({success:!0,message:`Folder not found: ${n.join(Kt.sep)}`,pathSegments:n});return}if(!Ar.statSync(i).isDirectory()){e.status(400).json({error:`Path is not a directory: ${n.join(Kt.sep)}`});return}if(o)Ar.rmSync(i,{recursive:!0,force:!0});else{if(Ar.readdirSync(i).length>0){e.status(409).json({error:`Cannot delete non-empty directory without recursive flag: ${n.join("/")}`});return}Ar.rmdirSync(i)}let s={success:!0,message:`Folder deleted: ${n.join("/")}`,pathSegments:n};e.status(200).json(s)}));var Mb=Tu;import{Router as x3}from"express";var b0=x3();b0.get("/",async(r,e)=>{let t=je(),n=Mr();if(!n){e.status(500).json({message:"API client not initialized"});return}let o=await sn(ya,n,t);e.status(200).json(o)});var Pb=b0;import IJ from"events";import iD,{Router as OJ}from"express";import LJ from"http";import{cloneDeep as Y3}from"lodash-es";import{randomUUID as _3}from"crypto";var M3=3;async function E0(r){let{results:e,fixtures:t,work:n}=r,{logger:o}=t,i=e[e.length-1],a=I3(i,n);if(a)return o.info({failedResult:i,isNotEligible:a},"Skipping failure recovery because of ineligible failure"),{type:"NOT_ELIGIBLE",message:`The failed step is not eligible for failure recovery: ${a}`};o.info({failedResult:i},"Attempting failure recovery"),n.state.failureRecoveryAttempts=(n.state.failureRecoveryAttempts??0)+1;try{return await P3(r)}catch(s){return o.warn({err:s},"Error during failure recovery attempt, continuing..."),null}}async function P3(r){let{fixtures:e,results:t,failedStep:n,nextSteps:o,stepTracer:i,work:a}=r,{controller:s,logger:c}=e,l=i.parentTracer,{testMetadata:u}=r.inputs;if(!t.length)throw new Error("Attempted failure recovery with no failed results");let d=await s.getScreenshotPngString(),p=await s.getEmulatorDomState(),{results:m}=await cP(c,l,t,{numStepsWithScreenshots:8,addIndices:!0,includeBeforeScreenshots:!1}),g=o.map(C=>ta(C)),h=u.description.trim(),f=u?.settings?.ai?.failureRecoveryInstructions?.trim()||void 0,{scenario:y,thoughts:E,instructions:b}=await s.getMobileFailureRecoveryPlan({currentScreenshot:d,failedResults:m,currentScreenXml:p,nextStepsSerialized:g,testDescription:h,customInstructions:f});if(y!=="RECOVERABLE")return c.info({scenario:y,thoughts:E,instructions:b},"Failure recovery is not applicable"),{type:"NOT_ELIGIBLE",message:`Momentic's failure recovery agent determined that this failure is not eligible for recovery: ${E}`};if(!b)throw new Error("Momentic's failure recovery agent did not provide any instructions for recovery");let _={id:_3(),type:"MOBILE_AI_ACTION_STEP",text:b},M,O=a.state.failureRecoveryDisabled;O||(a.state.failureRecoveryDisabled=!0),c.info("executing mobile step list");try{M=await r.executeMobileStepList({...r,fixtures:{...r.fixtures},listParams:{steps:[_,n],containerName:"AI-recovered step list",tracer:l}})}finally{O||(a.state.failureRecoveryDisabled=O)}let v=M.results[0];if(v&&v.type==="MOBILE_AI_ACTION_STEP")if(qS({results:M.results,onPresetAction:C=>{C.aiSuggested=!0},onSimpleStepContainer:C=>{C.aiSuggested=!0}}),M.status==="SUCCESS"){let C=`The following steps were automatically executed by the failure recovery agent. Analysis: ${E}`;return v.message=C,nt.increment("test_event",1,["name:failure_recovery_success","platform:native",`orgId:${r.inputs.orgId}`]),c.info({thoughts:E},"Failure recovery succeeded"),{type:"ATTEMPTED",status:"SUCCESS",result:M,message:C}}else{nt.increment("test_event",1,["name:failure_recovery_failure","platform:native",`orgId:${r.inputs.orgId}`]);let C=`The following steps were unsuccessfully attempted by the failure recovery agent. Analysis: ${E}`;return v.message=C,c.info({thoughts:E},"Failure recovery failed"),{type:"ATTEMPTED",status:"FAILED",result:M,message:C}}return null}function I3(r,e){if(!r)return"There is no failed result";if(r.type!=="MOBILE_PRESET_STEP")return"The failed step is not a preset action";let t=r.message;return t?t.includes("AbortError:")?"The user aborted the test":CT.some(n=>t.includes(n))?"The failed step is an irrecoverable configuration error":(e.state.failureRecoveryAttempts??0)>M3?"Too many failure recovery attempts":"":"There is no error message available on the failed step"}async function T0(r){let e=Date.now(),t=r.fixtures.controller;try{return await O3(r)}catch(n){let o=t.isAborted()||n instanceof DOMException&&n.name==="AbortError";return{...r.moduleParams.step,steps:[],type:"MOBILE_MODULE_STEP",startTime:e,endTime:Date.now(),status:o?"CANCELLED":"FAILED",message:o?"Step cancelled.":`${n}`}}}async function O3({moduleParams:r,...e}){let t=Date.now(),{step:n,stepTracer:o,executeMobileStepList:i}=r,a=await L3({step:n,params:e}),s={};Object.entries(a).forEach(([p,m])=>{s[p]=JSON.stringify(m)});let c={...n,type:"MOBILE_MODULE_STEP",inputs:s,startTime:t,steps:[],endTime:Date.now(),status:"SUCCESS"},l=await o.startSubSteps(),{status:u,results:d}=await i({...e,listParams:{steps:n.steps,containerName:`module ('${n.name}')`,tracer:l}});return c.steps=d,c.status=u,c.endTime=Date.now(),sP({result:c,...aP(d)}),c}async function L3({step:r,params:e}){let t={},{logger:n,controller:o}=e.fixtures;for(let i of r.parameters?.parameterNames??[]){let a=r.inputs?.[i]??r.parameters?.defaultParameters?.[i];if(!a){n.warn({k:i},"No value found for parameter in module");continue}t[i]=await Un({orgId:e.inputs.orgId,code:a,fragment:!0,logger:n,context:o.context,localTools:o.localCodeEvalTools})}return t}import{randomUUID as v0}from"crypto";import{diff as N3}from"deep-object-diff";import{cloneDeep as D3}from"lodash-es";async function A0({fixtures:r,step:e,inputs:t,stepTracer:n,work:o}){let i=Date.now(),{logger:a,controller:s}=r,c,l="",u,d=s.emulatorSettings?.disableXmlSnapshots??!1;if(!t.interactive){if(o.lastScreenshot)c=o.lastScreenshot.screenshot,l=o.lastScreenshot.snapshotId;else{l=v0();try{c=Buffer.from(await s.getScreenshotBase64(),"base64")}catch(h){a.warn({err:h},"Failed to take before screenshot")}}if(!d)if(o.lastScreenXml)u=o.lastScreenXml.screenXml;else try{u=await s.getEmulatorDomState()}catch(h){a.debug({err:h},"Failed to capture before XML snapshot")}}let p=VS(e.command,a),m=D3(p?.cache??{}),g={...e,status:"SUCCESS",startTime:i,endTime:Date.now()};try{let h=await s.executeCommand({command:e.command});g={...e,status:h.success?"SUCCESS":"FAILED",message:h.message,startTime:i,endTime:Date.now(),data:h.output}}catch(h){h instanceof Error&&h.name==="AbortError"||s.isAborted()?g={...e,status:"CANCELLED",message:"Step cancelled.",startTime:i,endTime:Date.now()}:(a.error({err:h},"Failed to execute preset step"),g={...e,status:"FAILED",message:h instanceof Error?h.message:String(h),startTime:i,endTime:Date.now()})}finally{if(!t.interactive){c&&(g.beforeSnapshot=l,n.attachBeforeScreenshot({snapshotId:l,screenshot:c}),!d&&u&&n.attachBeforeXmlSnapshot({snapshotId:l,xml:u}));let y=v0();try{let E=await s.getScreenshotBase64();g.afterSnapshot=y;let b=Buffer.from(E,"base64");n.attachAfterScreenshot({snapshotId:y,screenshot:b}),o.lastScreenshot={snapshotId:y,screenshot:b}}catch(E){a.warn({err:E},"Failed to take after screenshot"),o.lastScreenshot=void 0}if(!d)try{let E=await s.getEmulatorDomState();n.attachAfterXmlSnapshot({snapshotId:y,xml:E}),o.lastScreenXml={snapshotId:y,screenXml:E}}catch(E){a.debug({err:E},"Failed to capture after XML snapshot"),o.lastScreenXml=void 0}}let h="cache"in e.command?e.command.cache??{}:{};g.status==="FAILED"&&rP({logger:a,step:e,originalMobileCommandCache:p});let f=N3(m,h);f&&Object.keys(f).length>0&&a.info({diffs:rs(f)},"Updated cache")}return g}import{streamText as $3}from"ai";import{randomUUID as q3}from"crypto";var Yp=class{controller;logger;rootStep;subStepIndex=0;callbacks;finalState=void 0;results=[];constructor(e){let{controller:t,logger:n,callbacks:o,rootStep:i}=e;this.controller=t,this.logger=n,this.callbacks=o,this.rootStep=i}async createAndExecuteStep(e){this.callbacks.onAiActionEvent?.({type:"SUBSTEP_CREATED",rootStep:this.rootStep,step:e});let t=this.subStepIndex++,n=await this.callbacks.executeStep(e,t);return this.results.push(n),n}recordGenericToolCall(e){this.callbacks.onAiActionEvent?.({type:"GENERIC_TOOL_CALLED",toolName:e,rootStep:this.rootStep})}};import{hasToolCall as j3,stepCountIs as V3}from"ai";import R0 from"dedent";var F3=R0`
|
|
4617
|
+
`).map(t=>t.trim()).filter(t=>t.length>0):[]}function s3(r,e){let t=r.attemptIdToAttemptNumber.get(e);if(t)return tr.join(r.inflatedPath,"attempts",t);let n=tr.join(r.inflatedPath,"attempts");if(!Ht.existsSync(n))return;let o=Ht.readdirSync(n,{withFileTypes:!0}).filter(i=>i.isDirectory()).map(i=>i.name);for(let i of o){let a=tr.join(n,i,"metadata.json"),s=i0(a);if(typeof s!="object"||s===null)continue;let c=s.id;if(typeof c=="string"&&c===e)return r.attemptIdToAttemptNumber.set(e,i),tr.join(n,i)}}function n0(r,e,t){let n=tr.join(r,"attempts");if(!Ht.existsSync(n))return;let o=Ht.readdirSync(n,{withFileTypes:!0}).filter(i=>i.isDirectory()).map(i=>i.name);for(let i of o){let a=tr.join(n,i,"assets",`${e}.${t}`);if(Ht.existsSync(a))return a}}var jp=class{constructor(e,t,n){this.outputDir=e;this.runId=t;this.runAttemptId=n;this.runsDir=tr.join(e,"runs"),this.zipPath=tr.join(this.runsDir,`${t}.zip`)}inflatedByRunId=new Map;zipPath;runsDir;ensureInflatedRun(e){let t=this.inflatedByRunId.get(e);if(t)return t;if(e!==this.runId||!Ht.existsSync(this.zipPath))return;let n=tr.join(this.runsDir,`temp-unzipped-${e}-${a3()}`);Ht.mkdirSync(n,{recursive:!0}),new i3(this.zipPath).extractAllTo(n,!0);let i={runId:e,zipPath:this.zipPath,inflatedPath:n,attemptIdToAttemptNumber:new Map};return this.inflatedByRunId.set(e,i),i}close(){for(let e of this.inflatedByRunId.values())Ht.rmSync(e.inflatedPath,{recursive:!0,force:!0});this.inflatedByRunId.clear()}getAttemptDir(){let e=this.ensureInflatedRun(this.runId);if(e)return s3(e,this.runAttemptId)}listVideoAssetPaths(){let e=this.getAttemptDir();if(!e)return[];let t=tr.join(e,"assets");return Ht.existsSync(t)?Ht.readdirSync(t,{withFileTypes:!0}).filter(o=>o.isFile()).map(o=>tr.join(t,o.name)).filter(o=>{let i=tr.extname(o).toLowerCase();return i===".webm"||i===".mp4"}):[]}readAttemptAssetText(e,t){let n=this.getAttemptDir();if(!n)return;let o=tr.join(n,"assets",`${e}.${t}`);if(Ht.existsSync(o))try{return Ht.readFileSync(o,"utf-8")}catch{return}}async getConsoleLogsForRunAttempt(e,t,n){if(t!==this.runId||n!==this.runAttemptId)return;let o=this.getAttemptDir();if(!o)return;let i=i0(tr.join(o,"console.json")),a=Jh.safeParse(i);return a.success?a.data:void 0}async getNetworkLogsForRunAttempt(e,t,n){if(t!==this.runId||n!==this.runAttemptId)return;let o=this.getAttemptDir();if(!o)return;let i=tr.join(o,"assets","har-pages.log"),a=tr.join(o,"assets","har-entries.log"),s={};for(let u of r0(i)){let d=dc.safeParse(o0(u));d.success&&(s[d.data.id]=d.data)}let c={},l=r0(a);for(let u=0;u<l.length;u++){let d=l[u],p=mc.safeParse(o0(d));if(!p.success)continue;let m=`${p.data.startedDateTime}-${u}`;c[m]=p.data}if(Object.keys(c).length!==0)return Qh(s,c)}async getHtmlSnapshot(e,t){let n=this.readAttemptAssetText(t,"html");if(n)return n;let o=this.ensureInflatedRun(this.runId);if(!o)return;let i=n0(o.inflatedPath,t,"html");if(i)try{return Ht.readFileSync(i,"utf-8")}catch{return}}async getA11yTreeSnapshot(e,t){let n=this.readAttemptAssetText(t,"xml");if(n)return n;let o=this.ensureInflatedRun(this.runId);if(!o)return;let i=n0(o.inflatedPath,t,"xml");if(i)try{return Ht.readFileSync(i,"utf-8")}catch{return}}async getScreenshot(e,t){if(!this.ensureInflatedRun(this.runId))return;let o=this.getAttemptDir(),i=o?tr.join(o,"assets",`${t}.jpeg`):void 0;if(i)try{return Ht.readFileSync(i)}catch{return}}};function o0(r){try{return JSON.parse(r)}catch{return}}import Ta from"fs";import $p from"fs";import f3 from"open";import Eb from"path";import h3 from"express";import l3 from"adm-zip";import{Router as c3}from"express";import tl from"fs";import bu from"path";function a0(r){let e=c3(),t=bu.join(r,"runs");return e.get("/",async(n,o)=>{try{let i=u3(r);if(!i){o.status(404).json({error:"No run group found"});return}if(!tl.existsSync(t)){o.status(404).json({error:"No runs found for run group"});return}let a=d3(t,i),s={...i,id:i.id??"local-run-group",createdAt:i.startedAt,runs:a};o.status(200).json(s)}catch(i){o.status(500).json({error:`Error loading run group: ${i.message}`})}}),e}function u3(r){let e=bu.join(r,"metadata.json");if(!tl.existsSync(e))return P.error("Run group metadata file not found"),null;try{let t=tl.readFileSync(e,"utf-8");return us.parse(JSON.parse(t))}catch(t){return P.error({err:t},"Error reading run group metadata"),null}}function d3(r,e){let t=tl.readdirSync(r).filter(o=>o.endsWith(".zip")).sort((o,i)=>{let a=tl.statSync(bu.join(r,o));return tl.statSync(bu.join(r,i)).mtime.getTime()-a.mtime.getTime()}),n=[];for(let o of t){let i=bu.join(r,o),a=o.replace(/\.zip$/i,"");n.push(m3(i,a,e))}return n}function m3(r,e,t){let o=new l3(r).getEntry("metadata.json");if(!o)throw new Error(`No entry found for file ${r}/metadata.json`);try{let i=o.getData().toString("utf-8"),a=JSON.parse(i),s=mw.parse(a);return pP(s,e,{runGroupMetadata:t,runAttempts:[],organizationId:"local"})}catch(i){throw P.error({err:i,zipPath:r},"Error parsing metadata.json for run"),new Error(`Error parsing metadata.json for run ${r}`)}}import{Router as p3}from"express";import s0 from"fs";import Vp from"path";function l0(r){let e=p3(),t=Vp.join(r,"runs");return e.get("/:filename",(n,o)=>{let i=n.params.filename;if(!i||!i.endsWith(".zip")){o.status(404).send("Not found");return}let a=Vp.join(t,i),s=Vp.resolve(a),c=Vp.resolve(t);if(!s.startsWith(c)){o.status(403).send("Forbidden");return}if(!s0.existsSync(a)){o.status(404).send("File not found");return}try{o.setHeader("Content-Type","application/zip"),o.setHeader("Content-Disposition",`attachment; filename="${i}"`);let l=s0.readFileSync(a);o.send(l)}catch(l){o.status(500).send(`Error reading file: ${l.message}`)}}),e}import{Router as g3}from"express";import bb from"fs";import rl from"path";function c0(r){let e=g3();return e.get("*",(t,n)=>{let o=t.path==="/"?rl.join(r,"index.html"):rl.join(r,t.path),i=rl.resolve(o),a=rl.resolve(r);if(!i.startsWith(a)){n.status(403).send("Forbidden");return}if(!bb.existsSync(o)&&(o=rl.join(r,"index.html"),!bb.existsSync(o))){n.status(404).send("File not found");return}try{let s=rl.extname(o).toLowerCase(),c=pc[s]||"application/octet-stream";n.setHeader("Content-Type",c);let l=bb.readFileSync(o);n.send(l)}catch(s){n.status(500).send(`Error reading file: ${s.message}`)}}),e}async function u0(r,e,t){let n=e??await Yo(vd,"local-run-viewer-server"),o=h3();return o.use((i,a,s)=>{a.setHeader("Access-Control-Allow-Origin","*"),a.setHeader("Cache-Control","no-cache"),s()}),o.use("/api/runs",l0(r)),o.use("/api/run-group",a0(r)),t&&o.use("/",c0(t)),new Promise((i,a)=>{let s=o.listen(n,()=>{let c=`http://localhost:${n}`;i({port:n,url:c,stop:()=>{s.close()}})});s.on("error",c=>{a(c)})})}async function Tb(r){let{staticDir:e,resultsPath:t,runId:n,port:o}=r,i=Eb.resolve(t),a=Eb.join(i,"runs"),s;if(n){s=`${n.replace(/\.zip$/i,"")}.zip`;let l=Eb.join(a,s);if(!$p.existsSync(l)){let u=[];if($p.existsSync(a))for(let d of $p.readdirSync(a))d.endsWith(".zip")&&u.push(d.replace(/\.zip$/i,""));P.error(`Run not found: ${s} in ${a}`),u.length>0&&P.error(`Available runs: ${u.join(", ")}`),process.exit(1)}}$p.existsSync(e)||(P.error(`Static frontend files not found at ${e}. Please ensure the CLI is properly built.`),process.exit(1));try{let l=(await u0(i,o,e)).url;P.info(`Run viewer running at ${l}`);let u=new URL(l);s&&u.searchParams.set("zipUrl",`${l}/api/runs/${s}`),await f3(u.toString())}catch(c){P.error(`Failed to start run viewer: ${c.message}`),process.exit(1)}}import oD from"body-parser";import MJ from"cors";import PJ from"dedent";import{Router as v3}from"express";import qp from"fs";import S3 from"path";var y3=new Mm(30,60*1e3),wb="https://api.momentic.ai",Ab,m0,p0=r=>{wb=r},Cb=()=>wb;var g0=r=>{m0=r},h0=()=>m0,Mr=()=>Ab;var nl,Rb,d0,f0=async r=>{if(Ab&&nl&&d0)return nl;let e=new _r({baseUrl:wb,apiKey:r,logger:P});Ab=e;try{let t=await e.getAuthInfo();return nl=t.orgId,Rb=t.userId,d0=r,nl}catch(t){throw new Error(`Error checking API key against server: ${t}`)}},Xn=()=>{if(!nl)throw new Error("Your organization ID is invalid.");return nl},Kp=()=>{if(!Rb)throw new Error("Your user ID is invalid.");return Rb};var xb,vb,S0=(r,e)=>{xb=r,vb?.abort(),vb=new AbortController;let t=vb.signal,n=[r.configFilePath];r.config.environments?.forEach(o=>{if(!o.envFile)return;let i=S3.resolve(r.rootDir,o.envFile);try{if(qp.lstatSync(i).isSymbolicLink())return;qp.existsSync(i)&&n.push(i)}catch(a){P.warn({err:a},`Failed to check if env file ${i} exists`)}});try{b3({filesToWatch:n,revalidator:e,signal:t,project:r})}catch(o){P.error({err:o},"Failed to start config file watchers")}},je=()=>xb;function b3({filesToWatch:r,revalidator:e,signal:t,project:n}){P.debug("Starting watch on the following files:"),r.forEach(o=>{P.debug(`- ${o}`)}),r.forEach(o=>{let i=async(s,c)=>{s.mtime.getTime()!==c.mtime.getTime()&&(y3.increment("setLocalProject")&&P.warn(`A file change under the ${n.rootDir} directory has caused Momentic to reload its configuration more than 30 times in the last minute. Rapid changes to files may indicate your momentic.config.yaml 'include' glob is incorrect. Please ensure temporary, library, and auto-generated files are not included in Momentic's context.`),xb=await Promise.resolve(e(n.configFilePath)))};qp.watchFile(o,{persistent:!1},i);let a=()=>{qp.unwatchFile(o,i),t.removeEventListener("abort",a)};t.addEventListener("abort",a),process.once("SIGUSR2",()=>{a(),process.kill(process.pid,"SIGUSR2")})})}function De(r){return function(...e){let t=e[e.length-1],n=r(...e);Promise.resolve(n).catch(t)}}import{hostname as E3}from"os";var T3="0.34.0",ya=ms({app:"desktop-server",hostname:E3(),disableConsoleLogs:!0,captureExceptions:!0}).child({cliVersion:T3});(async()=>{try{let r=await mu(ya);r.gitBranchName&&ya.addBinding("branch",r.gitBranchName)}catch{}})();var y0=v3();y0.get("/",async(r,e)=>{let t=je(),n=Mr();if(!n){e.status(500).json({message:"API client not initialized"});return}let o=await sn(ya,n,t),i=o?.gitProtectedBranches&&o?.gitBranchName&&o.gitProtectedBranches.includes(o.gitBranchName),{noCache:a,alwaysSaveCache:s}=h0(),c=!a&&(s||!i);e.status(200).json({saveCaches:c,checkedOutBranch:o?.gitBranchName})});var _b=y0;import{Router as A3}from"express";import Ar from"fs";import{globSync as R3}from"glob";import Kt from"path";var Tu=A3();function Eu(r){let e=je(),t=Kt.dirname(e.configFilePath);return Kt.join(t,...r)}function w3(r){let e=je(),t=Kt.dirname(e.configFilePath),n=Kt.relative(t,r);return n?n.split(Kt.sep):[]}function C3(r,e){let t=Ar.statSync(r),n=w3(r);return ef.parse({name:e,absolutePath:r,relativePath:n.join(Kt.sep),pathSegments:n,isDirectory:t.isDirectory(),size:t.size,createdAt:t.birthtime,modifiedAt:t.mtime,accessedAt:t.atime})}Tu.post("/",De(async(r,e,t)=>{let n;try{n=VA.parse(r.body).pathSegments}catch(d){e.status(400).json({error:`Failed to parse folder read body: ${d}`});return}let o=Eu(n);if(!Ar.existsSync(o)){e.status(404).json({error:`Path not found: ${n.join(Kt.sep)}`});return}if(!Ar.statSync(o).isDirectory()){e.status(400).json({error:`Path is not a directory: ${n.join(Kt.sep)}`});return}let a=je(),s=Array.from(a.config.exclude??[]).concat(Td),l=R3("*",{absolute:!1,cwd:o,ignore:s,dotRelative:!1,maxDepth:1,nodir:!1}).map(d=>{let p=Kt.join(o,d);return C3(p,d)}),u={absolutePath:o,pathSegments:n,contents:l};e.status(200).json(u)}));Tu.put("/",De(async(r,e,t)=>{let n;try{n=$A.parse(r.body).pathSegments}catch(a){e.status(400).json({error:`Failed to parse folder create body: ${a}`});return}let o=Eu(n);if(Ar.existsSync(o)){e.status(200).json({success:!0,message:`Folder already exists: ${n.join(Kt.sep)}`,pathSegments:n});return}Ar.mkdirSync(o,{recursive:!0});let i={success:!0,message:`Folder created: ${n.join(Kt.sep)}`,pathSegments:n};e.status(201).json(i)}));Tu.patch("/",De(async(r,e,t)=>{let n,o;try{let l=qA.parse(r.body);n=l.pathSegments,o=l.newPathSegments}catch(l){e.status(400).json({error:`Failed to parse folder update body: ${l}`});return}let i=Eu(n),a=Eu(o);if(!Ar.existsSync(i)){e.status(400).json({error:`Folder not found: ${n.join(Kt.sep)}`});return}if(Ar.existsSync(a)){e.status(400).json({error:`Destination already exists: ${o.join(Kt.sep)}`});return}let s=Kt.dirname(a);Ar.existsSync(s)||Ar.mkdirSync(s,{recursive:!0}),Ar.renameSync(i,a);let c={success:!0,message:`Folder moved from ${n.join(Kt.sep)} to ${o.join(Kt.sep)}`,pathSegments:o};e.status(200).json(c)}));Tu.delete("/",De(async(r,e,t)=>{let n,o=!0;try{let c=KA.parse(r.body);n=c.pathSegments,o=c.recursive??!0}catch(c){e.status(400).json({error:`Failed to parse folder delete body: ${c}`});return}let i=Eu(n);if(!Ar.existsSync(i)){e.status(200).json({success:!0,message:`Folder not found: ${n.join(Kt.sep)}`,pathSegments:n});return}if(!Ar.statSync(i).isDirectory()){e.status(400).json({error:`Path is not a directory: ${n.join(Kt.sep)}`});return}if(o)Ar.rmSync(i,{recursive:!0,force:!0});else{if(Ar.readdirSync(i).length>0){e.status(409).json({error:`Cannot delete non-empty directory without recursive flag: ${n.join("/")}`});return}Ar.rmdirSync(i)}let s={success:!0,message:`Folder deleted: ${n.join("/")}`,pathSegments:n};e.status(200).json(s)}));var Mb=Tu;import{Router as x3}from"express";var b0=x3();b0.get("/",async(r,e)=>{let t=je(),n=Mr();if(!n){e.status(500).json({message:"API client not initialized"});return}let o=await sn(ya,n,t);e.status(200).json(o)});var Pb=b0;import IJ from"events";import iD,{Router as OJ}from"express";import LJ from"http";import{cloneDeep as Y3}from"lodash-es";import{randomUUID as _3}from"crypto";var M3=3;async function E0(r){let{results:e,fixtures:t,work:n}=r,{logger:o}=t,i=e[e.length-1],a=I3(i,n);if(a)return o.info({failedResult:i,isNotEligible:a},"Skipping failure recovery because of ineligible failure"),{type:"NOT_ELIGIBLE",message:`The failed step is not eligible for failure recovery: ${a}`};o.info({failedResult:i},"Attempting failure recovery"),n.state.failureRecoveryAttempts=(n.state.failureRecoveryAttempts??0)+1;try{return await P3(r)}catch(s){return o.warn({err:s},"Error during failure recovery attempt, continuing..."),null}}async function P3(r){let{fixtures:e,results:t,failedStep:n,nextSteps:o,stepTracer:i,work:a}=r,{controller:s,logger:c}=e,l=i.parentTracer,{testMetadata:u}=r.inputs;if(!t.length)throw new Error("Attempted failure recovery with no failed results");let d=await s.getScreenshotPngString(),p=await s.getEmulatorDomState(),{results:m}=await cP(c,l,t,{numStepsWithScreenshots:8,addIndices:!0,includeBeforeScreenshots:!1}),g=o.map(C=>ta(C)),h=u.description.trim(),f=u?.settings?.ai?.failureRecoveryInstructions?.trim()||void 0,{scenario:y,thoughts:E,instructions:b}=await s.getMobileFailureRecoveryPlan({currentScreenshot:d,failedResults:m,currentScreenXml:p,nextStepsSerialized:g,testDescription:h,customInstructions:f});if(y!=="RECOVERABLE")return c.info({scenario:y,thoughts:E,instructions:b},"Failure recovery is not applicable"),{type:"NOT_ELIGIBLE",message:`Momentic's failure recovery agent determined that this failure is not eligible for recovery: ${E}`};if(!b)throw new Error("Momentic's failure recovery agent did not provide any instructions for recovery");let _={id:_3(),type:"MOBILE_AI_ACTION_STEP",text:b},M,O=a.state.failureRecoveryDisabled;O||(a.state.failureRecoveryDisabled=!0),c.info("executing mobile step list");try{M=await r.executeMobileStepList({...r,fixtures:{...r.fixtures},listParams:{steps:[_,n],containerName:"AI-recovered step list",tracer:l}})}finally{O||(a.state.failureRecoveryDisabled=O)}let v=M.results[0];if(v&&v.type==="MOBILE_AI_ACTION_STEP")if(qS({results:M.results,onPresetAction:C=>{C.aiSuggested=!0},onSimpleStepContainer:C=>{C.aiSuggested=!0}}),M.status==="SUCCESS"){let C=`The following steps were automatically executed by the failure recovery agent. Analysis: ${E}`;return v.message=C,nt.increment("test_event",1,["name:failure_recovery_success","platform:native",`orgId:${r.inputs.orgId}`]),c.info({thoughts:E},"Failure recovery succeeded"),{type:"ATTEMPTED",status:"SUCCESS",result:M,message:C}}else{nt.increment("test_event",1,["name:failure_recovery_failure","platform:native",`orgId:${r.inputs.orgId}`]);let C=`The following steps were unsuccessfully attempted by the failure recovery agent. Analysis: ${E}`;return v.message=C,c.info({thoughts:E},"Failure recovery failed"),{type:"ATTEMPTED",status:"FAILED",result:M,message:C}}return null}function I3(r,e){if(!r)return"There is no failed result";if(r.type!=="MOBILE_PRESET_STEP")return"The failed step is not a preset action";let t=r.message;return t?t.includes("AbortError:")?"The user aborted the test":CT.some(n=>t.includes(n))?"The failed step is an irrecoverable configuration error":(e.state.failureRecoveryAttempts??0)>M3?"Too many failure recovery attempts":"":"There is no error message available on the failed step"}async function T0(r){let e=Date.now(),t=r.fixtures.controller;try{return await O3(r)}catch(n){let o=t.isAborted()||n instanceof DOMException&&n.name==="AbortError";return{...r.moduleParams.step,steps:[],type:"MOBILE_MODULE_STEP",startTime:e,endTime:Date.now(),status:o?"CANCELLED":"FAILED",message:o?"Step cancelled.":`${n}`}}}async function O3({moduleParams:r,...e}){let t=Date.now(),{step:n,stepTracer:o,executeMobileStepList:i}=r,a=await L3({step:n,params:e}),s={};Object.entries(a).forEach(([p,m])=>{s[p]=JSON.stringify(m)});let c={...n,type:"MOBILE_MODULE_STEP",inputs:s,startTime:t,steps:[],endTime:Date.now(),status:"SUCCESS"},l=await o.startSubSteps(),{status:u,results:d}=await i({...e,listParams:{steps:n.steps,containerName:`module ('${n.name}')`,tracer:l}});return c.steps=d,c.status=u,c.endTime=Date.now(),sP({result:c,...aP(d)}),c}async function L3({step:r,params:e}){let t={},{logger:n,controller:o}=e.fixtures;for(let i of r.parameters?.parameterNames??[]){let a=r.inputs?.[i]??r.parameters?.defaultParameters?.[i];if(!a){n.warn({k:i},"No value found for parameter in module");continue}t[i]=await Un({orgId:e.inputs.orgId,code:a,fragment:!0,logger:n,context:o.context,localTools:o.localCodeEvalTools})}return t}import{randomUUID as v0}from"crypto";import{diff as N3}from"deep-object-diff";import{cloneDeep as D3}from"lodash-es";async function A0({fixtures:r,step:e,inputs:t,stepTracer:n,work:o}){let i=Date.now(),{logger:a,controller:s}=r,c,l="",u,d=s.emulatorSettings?.disableXmlSnapshots??!1;if(!t.interactive){if(o.lastScreenshot)c=o.lastScreenshot.screenshot,l=o.lastScreenshot.snapshotId;else{l=v0();try{c=Buffer.from(await s.getScreenshotBase64(),"base64")}catch(h){a.warn({err:h},"Failed to take before screenshot")}}if(!d)if(o.lastScreenXml)u=o.lastScreenXml.screenXml;else try{u=await s.getEmulatorDomState()}catch(h){a.debug({err:h},"Failed to capture before XML snapshot")}}let p=VS(e.command,a),m=D3(p?.cache??{}),g={...e,status:"SUCCESS",startTime:i,endTime:Date.now()};try{let h=await s.executeCommand({command:e.command});g={...e,status:h.success?"SUCCESS":"FAILED",message:h.message,startTime:i,endTime:Date.now(),data:h.output}}catch(h){h instanceof Error&&h.name==="AbortError"||s.isAborted()?g={...e,status:"CANCELLED",message:"Step cancelled.",startTime:i,endTime:Date.now()}:(a.error({err:h},"Failed to execute preset step"),g={...e,status:"FAILED",message:h instanceof Error?h.message:String(h),startTime:i,endTime:Date.now()})}finally{if(!t.interactive){c&&(g.beforeSnapshot=l,n.attachBeforeScreenshot({snapshotId:l,screenshot:c}),!d&&u&&n.attachBeforeXmlSnapshot({snapshotId:l,xml:u}));let y=v0();try{let E=await s.getScreenshotBase64();g.afterSnapshot=y;let b=Buffer.from(E,"base64");n.attachAfterScreenshot({snapshotId:y,screenshot:b}),o.lastScreenshot={snapshotId:y,screenshot:b}}catch(E){a.warn({err:E},"Failed to take after screenshot"),o.lastScreenshot=void 0}if(!d)try{let E=await s.getEmulatorDomState();n.attachAfterXmlSnapshot({snapshotId:y,xml:E}),o.lastScreenXml={snapshotId:y,screenXml:E}}catch(E){a.debug({err:E},"Failed to capture after XML snapshot"),o.lastScreenXml=void 0}}let h="cache"in e.command?e.command.cache??{}:{};g.status==="FAILED"&&rP({logger:a,step:e,originalMobileCommandCache:p});let f=N3(m,h);f&&Object.keys(f).length>0&&a.info({diffs:rs(f)},"Updated cache")}return g}import{streamText as $3}from"ai";import{randomUUID as q3}from"crypto";var Yp=class{controller;logger;rootStep;subStepIndex=0;callbacks;finalState=void 0;results=[];constructor(e){let{controller:t,logger:n,callbacks:o,rootStep:i}=e;this.controller=t,this.logger=n,this.callbacks=o,this.rootStep=i}async createAndExecuteStep(e){this.callbacks.onAiActionEvent?.({type:"SUBSTEP_CREATED",rootStep:this.rootStep,step:e});let t=this.subStepIndex++,n=await this.callbacks.executeStep(e,t);return this.results.push(n),n}recordGenericToolCall(e){this.callbacks.onAiActionEvent?.({type:"GENERIC_TOOL_CALLED",toolName:e,rootStep:this.rootStep})}};import{hasToolCall as j3,stepCountIs as V3}from"ai";import R0 from"dedent";var F3=R0`
|
|
4618
4618
|
You cannot interact with the user directly. If you feel like you need to ask the user for clarification, or you are stuck, call the "finish" tool with success=false. Never output text without calling a tool.
|
|
4619
4619
|
`,w0=r=>R0`
|
|
4620
4620
|
<background>
|
|
@@ -4647,7 +4647,7 @@ Momentic users value the following:
|
|
|
4647
4647
|
b) There is a loading state that blocks you from proceeding with generation, and you need to wait until the state changes. In this case, you can generate an AI_CHECK step for the anticipated "done" state (e.g. "There is no loading spinner visible"). Unless explicitly specified by the user, you can generate and retry an assertion up to 3 times with a timeout up to 30 seconds each.
|
|
4648
4648
|
If the max. allowed retries is exceeded, fail the generation cycle by calling "finish".
|
|
4649
4649
|
</rules>
|
|
4650
|
-
`;import{tool as z3}from"ai";import{randomUUID as H3}from"crypto";import G3 from"zod";import{tool as U3}from"ai";import B3 from"zod";var Ib="get_emulator_state";var C0=r=>{let e=U3({description:"Get the current state of the emulator (XML + screenshot)",inputSchema:B3.object({}),toModelOutput:t=>t,execute:async()=>{let{controller:t,logger:n,contextManager:o}=r;return o.recordGenericToolCall(Ib),n.info("AI action tool called (get_emulator_state)"),Ob(t)}});return{name:Ib,tool:e}};async function Ob(r){let e=await r.getEmulatorDomState(),t=await r.getScreenshotBase64();return{type:"content",value:[{type:"text",text:"<emulatorXml>"},{type:"text",text:e},{type:"text",text:"</emulatorXml>"},{type:"text",text:"<screenshot>"},{type:"media",data:t,mediaType:"image/png"},{type:"text",text:"</screenshot>"}]}}var x0=r=>({name:"create_execute_step",tool:z3({description:"Create and immediately execute a new Momentic step in the Android emulator, returning the result from the step and the state of the emulator after the step finished executing.",inputSchema:G3.object({step:Wh}),toModelOutput:t=>t,execute:async({step:t})=>{let{contextManager:n,logger:o,controller:i}=r;o.info({step:t},"AI action tool called (create_execute_step)");let a=mA(t),s={id:H3(),type:"MOBILE_PRESET_STEP",command:a},c=await n.createAndExecuteStep(s);c.status==="SUCCESS"&&i.optionsCopy?.emulator?.waitForStability&&await i.waitForPageSourceStability({reason:"Waiting for stability after executing AI-generated sub-step"});let l={...c,trace:void 0,beforeSnapshot:void 0,afterSnapshot:void 0},u=await Ob(i);return{type:"content",value:[{type:"text",text:"<result>"},{type:"text",text:JSON.stringify(l,null,2)},{type:"text",text:"</result>"},{type:"text",text:"<stateAfter>"},...u.value,{type:"text",text:"</stateAfter>"}]}}})});import{tool as W3}from"ai";import Lb from"zod";var _0=r=>{let e=W3({description:"Signal that the AI action has reached a terminal state (either success or failure).",inputSchema:Lb.object({message:Lb.string(),success:Lb.boolean()}),toModelOutput:t=>t,execute:async({message:t,success:n})=>{let{contextManager:o,logger:i}=r;return i.info({message:t,success:n},"AI action tool called (finish)"),o.finalState={message:t,status:n?"SUCCESS":"FAILED"},{type:"content",value:[{type:"text",text:"Done"}]}}});return{name:_u,tool:e}};var M0=[x0,C0,_0];function P0(r){let{logger:e,controller:t,contextManager:n,aiActionSessionId:o}=r,i={};for(let c of M0){let l=c({contextManager:n,logger:e,controller:t});i[l.name]=l.tool}let a=t.generator.getVercelAnthropicModelFactory({logger:e,sessionId:o}),s=c=>{let{messages:l}=c,u=!1;for(let d=l.length-1;d>=0;d--){let p=l[d];for(let m of p.content)if(!(typeof m!="object"||!("type"in m))&&!(m.type!=="tool-result"||m.output.type!=="content")&&!(m.output.value.length<3))for(let g=0;g<m.output.value.length;g++){let h=m.output.value[g];if(h.type==="text"&&h.text.includes("<emulatorXml>"))if(u){let f=m.output.value[g+1];f.type==="text"?f.text="TRUNCATED DUE TO CONVERSATION LENGTH":e.warn({msg:f},"Got unexpected part when truncating emulator state message")}else{u=!0;continue}}}return c};return{model:a("claude-haiku-4-5-20251001"),tools:i,prepareStep:s,stopWhen:[V3(15),j3(_u)],system:w0(!1)}}async function I0(r){let e=Date.now(),{controller:t,logger:n}=r.fixtures;try{return await K3(r)}catch(o){let i=t.isAborted()||o instanceof DOMException&&o.name==="AbortError";return i||n.error({err:o},"Failed to execute mobile AI action"),{...r.aiActionParams.step,steps:[],type:"MOBILE_AI_ACTION_STEP",startTime:e,endTime:Date.now(),status:i?"CANCELLED":"FAILED",message:i?"Step cancelled.":`${o}`}}}async function K3(r){let{platform:e}=r,{step:t,stepTracer:n,executeMobileStepList:o}=r.aiActionParams,{controller:i,logger:a}=r.fixtures,{step:s}=r.callbacks,c=await n.startSubSteps(),l=q3(),u=a.child({stepId:t.id,aiActionSessionId:l}),d=Date.now();if(e!=="ANDROID"||!(i instanceof ii))throw new R("UserConfigurationError","AI action steps are only supported on Android platform.");let p=async(y,E)=>{let b=await o({...r,listParams:{steps:[y],tracer:c,containerName:`AI action sub-step ${E}`}});if(b.results.length!==1)throw new R("InternalWebAgentError","Expected exactly one result from executeMobileStepList");return b.results[0]},m={stepId:t.id,parentStepIdChain:n.getParentStepIdChain()},g=new Yp({controller:i,callbacks:{onAiActionEvent:s?.onAiActionEvent,executeStep:p},logger:u,rootStep:m}),h=P0({controller:i,logger:u,contextManager:g,aiActionSessionId:l}),f=$3({...h,messages:[{role:"user",content:t.text}],abortSignal:i.abortSignal});for await(let y of f.fullStream)switch(i.throwIfAborted(),y.type){case"text-delta":s?.onAiActionEvent?.({type:"LLM_TEXT_OUTPUT",text:y.text,rootStep:m})}if(await f.response,i.throwIfAborted(),!g.finalState)throw new R("InternalWebAgentError","The AI agent never reached a final state. This could be because the maximum number of steps was reached.");return{...t,status:g.finalState.status,startTime:d,endTime:Date.now(),message:g.finalState.message,steps:g.results}}var X3=60*60*1e3;async function vu(r){let{fixtures:e,inputs:t,listParams:n,work:o}=r,{containerName:i,steps:a,tracer:s}=n,{logger:c,controller:l,usageTracker:u}=e,d=s.getParentStepIdChain(),p=[],m,g="SUCCESS",h,{fromStep:f,toStep:y}=t;for(let E=0;E<a.length;E++){let b=a[E];if(b.skipped)continue;if(o.fastForwardingToStep&&f){let C=JSON.stringify(d);if(b.id===f.fromStepId&&C===JSON.stringify(f.parentStepIdChain))o.fastForwardingToStep=!1;else if(!iP({currentStep:b,currentParentChain:d,desiredStepId:f.fromStepId,desiredStepParentChain:f.parentStepIdChain}))continue}let _=0,M=1,O=Date.now();b.retries&&b.retries>0&&(M+=b.retries);let v=[];for(;_<M&&Date.now()-O<X3;){_++;let C=`Executing step index ${E} in ${i} - ${ta(b)}`;_!==1&&(C+=` (attempt ${_})`),c.info({step:b},C);let F=Date.now(),I=await s.startStep({logger:c,step:b,attempt:_,parentStepIdChain:d});u.trackStepExecution(b);let B=Y3(b),D=await J3({step:b,stepTracer:I,params:r}),{trace:ee}=await I.finish({parentStepIdChain:d,result:D});if(D.trace=ee,C=`Finished step index ${E} in ${i} - ${ta(b)}`,_!==1&&(C+=` (attempt ${_})`),c.info({step:{id:b.id},trace:D.trace,status:D.status},C),D.status!=="SUCCESS"&&_<M){v.push(D),Date.now()-F<1e3&&await J(1e3-(Date.now()-F));continue}if(v.length>0&&(D.previousAttempts=v),p.push(D),h=await Z3({result:D,step:b,originalStep:B,steps:a,currentStepIndex:E,params:r,stepTracer:I,isLastAttempt:_===M,results:p}),D.status!=="SUCCESS"&&h!=="SUCCESS")return g=D.status,m=D,{results:p,status:g,terminalResult:m};if(b.envKey&&l.context.setVariable(b.envKey,D.data),y){let K=JSON.stringify(d);if(b.id===y.toStepId&&K===JSON.stringify(y.parentStepIdChain))return o.shouldStopExecuting=!0,{results:p,status:g,terminalResult:m}}if(o.shouldStopExecuting)return{results:p,status:g,terminalResult:m};break}}return{results:p,status:g,terminalResult:m}}async function J3({step:r,params:e,stepTracer:t}){let{fixtures:n,inputs:o,callbacks:i,work:a}=e,s;switch(r.type){case"MOBILE_PRESET_STEP":{s=await A0({platform:e.platform,fixtures:n,inputs:o,step:r,stepTracer:t,callbacks:i,work:a});break}case"RESOLVED_MOBILE_MODULE":{s=await T0({...e,moduleParams:{step:r,stepTracer:t,executeMobileStepList:vu}});break}case"MOBILE_AI_ACTION_STEP":{s=await I0({...e,aiActionParams:{step:r,stepTracer:t,executeMobileStepList:vu}});break}}return s}async function Z3({result:r,step:e,originalStep:t,steps:n,currentStepIndex:o,params:i,stepTracer:a,isLastAttempt:s,results:c}){let l,u;if(s&&r.status==="FAILED"&&!i.work.state.failureRecoveryDisabled){let d=await E0({...i,stepTracer:a,step:e,steps:n,currentStepIndex:o,isLastAttempt:s,executeMobileStepList:vu,failedStep:t,nextSteps:n.slice(o+1),results:c.concat(r)});d&&(d.type==="ATTEMPTED"?(l=d.result.results,u=d.status):d.type==="NOT_ELIGIBLE"&&(r.message=r.message?`${r.message} ${d.message}`:d.message),r.type==="MOBILE_PRESET_STEP"&&(r.failureRecoveryStatus={type:d.type,message:d.message}))}return l&&c.push(...l),u}import{diff as Q3}from"deep-object-diff";import{cloneDeep as eJ}from"lodash-es";async function ol(r){let{tracer:e,containerName:t}=r,{steps:n,testMetadata:o}=r.inputs,{cacheStorage:i,logger:a}=r.fixtures,s=a.child({testId:r.inputs.testMetadata.id,testName:r.inputs.testName});await i.populateCacheForRun({logger:s,platform:o.platform,testId:o.id,stepLists:{steps:n},skipFetchingCacheFromStorage:r.inputs.interactive});let c=eJ(n);s.info({testMetadata:Do.parse(o)},"Starting mobile test");let l=await e.startMainStepList(),u=Aw(s);s.info({cpu:u?.cpuMetadata,platform:u?.platform},`Starting execution of ${t}`);let{status:d,results:p,terminalResult:m}=await vu({...r,listParams:{containerName:t,tracer:l,steps:c}});return clearInterval(u?.interval),await tJ({steps:n,stepsToExecute:c,logger:s,cacheStorage:i,orgId:r.inputs.orgId,testId:o.id,platform:o.platform}),d==="SUCCESS"?{status:"PASSED",results:p,failureRecoveryDetails:r.work.state.failureRecoveryAttempts?{attempts:r.work.state.failureRecoveryAttempts}:void 0}:d==="CANCELLED"?{status:"CANCELLED",results:p}:{status:"FAILED",results:p,terminalResult:m}}async function tJ({steps:r,stepsToExecute:e,logger:t,cacheStorage:n,orgId:o,testId:i,platform:a}){let s=Q3(r,e);if(s&&Object.keys(s).length>0){t.info({diffs:rs(s)},"Saving mobile step cache entries");let{cachesToSave:c}=await zn({platform:a,steps:e,cacheCreationParams:{orgId:o,testId:i}});await n.saveEntries({logger:t,testId:i,entries:c})}else t.info("No cache entries to update")}import{Server as dJ}from"socket.io";import{tmpdir as rJ}from"os";import O0 from"path";async function L0({socket:r,logger:e,orgId:t,testMetadata:n,globalOrgSettings:o,androidDriverFactory:i,mobileGeneratorFactory:a,browserGeneratorFactory:s,browserEnricherFactory:c,storageFactory:l,localToolsFactory:u,globalStateManager:d,getGitMetadata:p}){let m=r.id,g=await p(),h=r.handshake.query?.fileName,f=h?O0.basename(h,".test.yaml"):"",y=n.id,E=n.settings?.defaultChannel,b=n.settings?.defaultTag;e=e.child({sessionId:m,testId:y,orgId:t,branch:g.gitBranchName});let _=await l(t),M=n.settings?.defaultEnv,O={};M&&(O=(await _.fetchEnvironment(M,e))?.variables??{});let v=os.parse(O[Mi]),C=os.parse(O[Dl]),F={...o.emulator,...n.settings?.emulator},I=n.settings?.defaultApkFilePath?.trim()||C,B=d.getSession(m);if(B){if(e.info("Reconnecting to existing Android session"),B.local)return r.emit("session",B.metadata),B.softDeleted=!1,B.metadata;throw new Error("Restoring existing remote emulator sessions is not supported. Please reconnect to a new emulator.")}let D;if(F.region==="local"){if(await d.clearSoftDeletedLocalSessions(e),d.hasActiveLocalSession())throw new Error("Another local emulator session is already active. Please close the existing session before creating a new one.");let fi=n.settings?.emulator?.localEmulatorSettings?.avdId?.trim()||v;if(!fi)throw new Error(`AVD ID is required when using a local emulator. Set it on the test (Options \u2192 Emulator \u2192 Local AVD ID) or on the environment via ${Mi}.`);D={avdId:fi,apkToInstall:E?{channel:E,tag:b}:void 0,apkFilePath:I}}else D={region:F.region,apkToInstall:E?{channel:E,tag:b}:void 0,osVersion:F.remoteEmulatorSettings?.androidVersion};let ee=Date.now(),{driver:K,cleanup:ge,emulatorName:U,adbPort:W,limbarClient:ue,limbarToken:le,limbarUrl:He,playwrightDevice:ve}=await i({socket:r,logger:e,creationOpts:D}),q=O0.join(rJ(),`logcat-logs-${t}-${y}-${m}.txt`),fe=await Om({driver:K,onLogs:fi=>{r.emit("logcatLogs",fi)},logFilePath:q});e.info({adbPort:W,apkChannel:E,apkTag:b,duration:Date.now()-ee,emulatorName:U},"Android emulator session initiated"),e=e.child({emulator:U});let it=await a(t,e),Ae=await s(t,e),x=await c(t,e),ne=u?await u(t):void 0,pe=new No({variablesFromEnvironment:O,envName:M,testName:f}),Ur=await ii.init({driver:K,generator:it,logger:e,limbarClient:ue,playwrightDevice:ve,aiSettings:{...o.ai,useMemory:o.ai?.useMemory!==!1,...n.settings?.ai},options:{emulator:{...F,browserSettings:o.browser}},fixtures:{storage:_,browserEnricher:x,browserGenerator:Ae,localCodeEvalTools:ne,testContext:pe},orgId:t,adbPort:W,abortController:new AbortController}),hi=await Ur.getViewportBounds();if(!r.connected)throw await Ur.cleanup(),await fe(),await ge(),new Error("Socket not connected anymore, not proceeding with Android session setup");let qD=nJ({socket:r,testContext:pe}),KD=async()=>{clearInterval(qD);try{await Promise.allSettled([Ur.cleanup(),fe(),ge()])}catch(fi){e.warn({err:fi},"Failed to clean up emulator in socket server")}},ie={sessionId:m,testId:y,orgId:t,emulatorName:U,testName:f,limbarUrl:He,limbarToken:le,viewportBounds:hi};return d.registerSession(m,{controller:Ur,cleanup:KD,emulatorName:U,local:F.region==="local",metadata:ie,logFilePath:q}),r.emit("session",ie),ie}function nJ({socket:r,testContext:e}){return setInterval(()=>{let t=e.toEditorDisplayCopy();r.emit("emulatorState",{context:t})},3e3)}import Xp from"fs/promises";async function N0({socket:r,logger:e,globalStateManager:t,authorization:n}){let o=r.id,i=t.getSession(o);i&&n&&i.logFilePath&&oJ({testId:i.metadata.testId,sessionId:o,logFilePath:i.logFilePath,authorization:n,logger:e}),await t.removeSession(o,e)}async function oJ({testId:r,sessionId:e,logFilePath:t,authorization:n,logger:o}){try{let i;try{i=await Xp.stat(t)}catch{o.debug({logFilePath:t},"No logcat file found to upload");return}if(i.size===0){o.debug({logFilePath:t},"Logcat file is empty, skipping upload"),await Xp.unlink(t);return}let a=new _r(n),{uploadUrl:s}=await a.generateMobileLogcatUploadUrl({testId:r,sessionId:e}),c=await Xp.readFile(t),l=await fetch(s,{headers:{"Content-Length":c.length.toString(),"Content-Type":"text/plain"},method:"PUT",body:c});if(l.status!==200)throw new Error(`Failed to upload logcat: ${l.status} ${await l.text()}`);o.info({testId:r,sessionId:e},"Logcat file uploaded successfully")}catch(i){o.warn({err:i,testId:r,sessionId:e},"Failed to upload logcat file")}finally{try{await Xp.unlink(t)}catch(i){o.warn({err:i,logFilePath:t},"Failed to delete temp logcat file")}}}var iJ=({socket:r,globalStateManager:e})=>async()=>{let t=e.getSession(r.id);if(!t)throw new Error("No active Android session found");t.controller.abort()},D0={event:"cancel",createHandler:iJ};var aJ=({logger:r,globalStateManager:e,socket:t})=>async(n,o)=>{let i=e.getSession(t.id);if(!i){o({err:"No active Android session found"});return}try{let s=await i.controller.getEmulatorDomState();o({screenXml:s})}catch(a){r.error({err:a},"Error fetching screen XML from the session controller"),o({err:a.message})}},k0={event:"fetchScreenXml",createHandler:aJ};var Nb=class{parentTracer;socket;step;orgId;interactionTracer;constructor({step:e,socket:t,parentTracer:n,orgId:o}){this.socket=t,this.parentTracer=n,this.step=e,this.orgId=o,this.interactionTracer=new Jo,rn.initializeRootTracerContext(this.interactionTracer)}attachBeforeScreenshot(){}attachAfterScreenshot(){}attachBeforeXmlSnapshot(){}attachAfterXmlSnapshot(){}recordStepDuration(e){let{durationMs:t,step:n}=e,o=n.type!=="MOBILE_PRESET_STEP"?n.type:n.command.type;nt.distribution("test_step_duration",t,[`type:${o}`,"platform:mobile","executor:editor",`orgId:${this.orgId}`])}async finish(e){this.interactionTracer.finish();let t=this.interactionTracer.getRootSpan(),n={...sw.parse(e),trace:Xh.parse(t)};switch(n.result.status){case"SUCCESS":this.socket.emit("success",n);break;case"FAILED":this.socket.emit("failure",n);break;case"CANCELLED":this.socket.emit("cancelled",n);break}return{trace:t}}getParentStepIdChain(){return this.parentTracer?this.parentTracer?.getParentStepIdChain()??[]:[]}async startSubSteps(){return new il({parentStep:this.step,socket:this.socket,parentTracer:this,orgId:this.orgId})}},il=class{parentTracer;parentStep;socket;orgId;constructor({parentStep:e,socket:t,parentTracer:n,orgId:o}){this.parentTracer=n,this.parentStep=e,this.socket=t,this.orgId=o}getParentStepIdChain(){return this.parentStep?[...this.parentTracer?.getParentStepIdChain()??[],this.parentStep.id]:[]}async startStep(e){return this.socket.emit("started",{stepId:e.step.id,parentStepIdChain:e.parentStepIdChain,attempt:e.attempt}),new Nb({step:e.step,parentTracer:this,socket:this.socket,orgId:this.orgId})}async getScreenshot(e){}},Jp=class{constructor(e,t){this.socket=e;this.orgId=t}appendLogs(){}async finish(){this.socket.emit("finished")}async startBeforeStepList(){return new il({parentStep:null,parentTracer:null,socket:this.socket,orgId:this.orgId})}async startMainStepList(){return new il({parentStep:null,parentTracer:null,socket:this.socket,orgId:this.orgId})}async startAfterStepList(){return new il({parentStep:null,parentTracer:null,socket:this.socket,orgId:this.orgId})}};var sJ=({metadata:r,logger:e,globalStateManager:t,socket:n,cacheStorageFactory:o,getGitMetadata:i})=>async(a,s)=>{let c=t.getSession(n.id);if(!c)throw new Error("No active Android session found");if(a.testMetadata.platform!=="ANDROID")throw new Error("Non-android tests aren't supported yet");let l=await i(),u=e.child({testId:a.testMetadata.id,branch:l.gitBranchName}),d=await o(r.orgId,l),p=c.controller;p.resetAbortController();let m=new Jp(n,r.orgId),g=await ol({platform:"ANDROID",work:{fastForwardingToStep:!!a.fromStep,state:{failureRecoveryDisabled:!0,failureRecoveryAttempts:0}},fixtures:{controller:p,logger:u,cacheStorage:d,usageTracker:new ud},containerName:"entire test",inputs:{steps:a.steps,fromStep:a.fromStep,toStep:a.toStep,orgId:r.orgId,testName:r.testName,testMetadata:a.testMetadata,interactive:!0},tracer:m,callbacks:{step:{onAiActionEvent:f=>{n.emit("aiActionEvent",f)}}}});await m.finish();let h={results:Sr.array().parse(g.results),status:g.status};s?.(h)},F0={event:"execute",createHandler:sJ};import{debounce as lJ}from"ts-debounce";var cJ=({socket:r,globalStateManager:e,keepSessionAlive:t})=>{let n=lJ(t,3e4,{maxWait:6e4});return async()=>{let o=e.getSession(r.id);if(!o)throw new Error("No active Android session found");o.emulatorName&&(o.local||n(o.emulatorName))}},U0={event:"keepalive",createHandler:cJ};var uJ=({socket:r,globalStateManager:e,logger:t})=>async(n,o)=>{let i=e.getSession(r.id);if(!i){let s="No active Android session found";t.error(s),o?.({success:!1,err:s});return}let a=i.controller;a.abort(),a.resetAbortController(),t.info("Resetting emulator state");try{await a.softReset(),t.info("Emulator reset completed"),o?.({success:!0,message:"Emulator reset successfully"})}catch(s){let c=s instanceof Error?s.message:String(s);t.error({err:s},"Failed to reset emulator"),o?.({success:!1,err:`Failed to reset emulator: ${c}`})}},B0={event:"reset",createHandler:uJ};var z0=[F0,D0,B0,U0,k0];var Zp=class{sessions=new Map;registerSession(e,t){this.sessions.set(e,t)}getSession(e){return this.sessions.get(e)}async clearSoftDeletedLocalSessions(e){for(let t of this.sessions.values())t.softDeleted===!0&&t.local===!0&&await this.removeSession(t.metadata.sessionId,e)}hasActiveLocalSession(){for(let e of this.sessions.values())if(e.local===!0)return!0;return!1}async removeSession(e,t){let n=this.sessions.get(e);if(n)try{await n.cleanup?.(),t.info({sessionId:e,emulatorName:n.emulatorName},"Android emulator cleaned up by removeSession")}catch(o){t.error({err:o},"Error during Android session cleanup")}finally{this.sessions.delete(e)}}async removeAllSessions(e){let t=Array.from(this.sessions.keys());await Promise.all(t.map(n=>this.removeSession(n,e)))}};function H0(r){let{logger:e,baseServer:t,globalStateManager:n,settingsFactory:o,getOrgId:i}=r,a=new dJ(t,{cors:{origin:"*",methods:["GET","POST"]},pingTimeout:15*60*1e3,pingInterval:15*60*1e3,maxHttpBufferSize:1e7,perMessageDeflate:!0,connectionStateRecovery:{maxDisconnectionDuration:60*60*1e3,skipMiddlewares:!0}}),s=async()=>{await n.removeAllSessions(e)};a.on("connection",async l=>{let u=l.id,d=e.child({sessionId:u});d.info({event:"connection",transport:l.conn.transport.name},"Android websocket connection initiated"),l.on("disconnect",async g=>{if(e.info({reason:g},"Disconnect received"),g.includes("namespace disconnect")){await N0({socket:l,globalStateManager:n,logger:d,authorization:r.authorization});return}let h=n.getSession(u);h&&(h.softDeleted=!0)});let p,m;try{let g=l.handshake.query?.testMetadata,h=Do.parse(JSON.parse(g??"")),f=h.id,y=await i({testId:f});m=await o(y,e),p=await L0({...r,orgId:y,socket:l,globalStateManager:n,logger:d,globalOrgSettings:m,testMetadata:h})}catch(g){d.error({err:g},"Failed to setup Android connection"),l.emit("error",{message:g instanceof Error?g.message:JSON.stringify(g)}),l.disconnect(!0);return}z0.forEach(g=>c(g,{...r,socket:l,metadata:p,globalOrgSettings:m,logger:d}))});let c=(l,u)=>{let d=l.createHandler(u),p=(...m)=>{l.event!=="keepalive"&&u.logger.debug({event:l.event},`Websocket event (${l.event})`);let g=h=>{u.logger.error({event:l.event,err:h instanceof Error?h:new Error(`${h}`)},"Unhandled exception in socket handler"),u.socket.emit("error",{message:h instanceof Error?h.message:typeof h=="string"?h:JSON.stringify(h)})};try{let h=d.apply(this,m);h&&typeof h.catch=="function"&&h.catch(g)}catch(h){g(h)}};u.socket.on(l.event,p)};return{server:a,dispose:s}}import NJ from"path";var Qp=new Zp;import{Router as pJ}from"express";import{existsSync as gJ}from"fs";import hJ from"path";import{hostname as mJ}from"os";var Db="0.33.4",Ze=ms({app:"mobile-desktop-server",hostname:mJ(),disableConsoleLogs:!0,captureExceptions:!0}).child({cliVersion:Db});(async()=>{try{let r=await mu(Ze);r.gitBranchName&&Ze.addBinding("branch",r.gitBranchName)}catch{}})();var kb=pJ();kb.get("/",De(async(r,e)=>{let t=Mr();if(!t){e.status(500).json({message:"API client not initialized"});return}let n=await t.getAndroidAssets();e.status(200).json(n)}));kb.post("/upload-url",De(async(r,e)=>{let t;try{t=tR.parse(r.body)}catch(i){e.status(400).json({error:`Invalid request body: ${i}`});return}let n=Mr();if(!n){e.status(500).json({error:"API client not initialized"});return}let o=hJ.resolve(t.filePath);if(!gJ(o)){e.status(400).json({error:`File not found: ${o}`});return}await Im({tag:t.tag,channel:t.channel,filePath:o,apiClient:n,logger:Ze}),e.sendStatus(204)}));var G0=kb;import{Router as yJ}from"express";import{Router as fJ}from"express";import W0 from"fs";import SJ from"path";var al=fJ();async function eg(r){return(await oL(r,Ze)).map(n=>{let o=r.mobileModules[n.moduleId];if(!o){P.warn(`Found a dangling mobile module with ID ${n.moduleId} that could not be found on disk.`);return}return{...o,content:n}}).filter(n=>n!==void 0)}al.get("/",De(async(r,e)=>{let t=je(),n=await Zt(t),o=await eg(n);e.status(200).json(o)}));al.get("/tests-join",De(async(r,e)=>{let t=je(),n=await Zt(t),o=await eg(n),i={};for(let s of o)i[s.id]={...s,tests:[]};let a=await Promise.all(Object.values(n.mobileTests).map(async s=>({id:s.id,name:s.name,relativePath:s.relativePath,test:await So(s.fullFilePath,Ze,n)})));for(let{id:s,name:c,relativePath:l,test:u}of a){let d=new Set;$S({steps:u.steps,onPreset:()=>!1,onModule:p=>(d.add(p.moduleId),!1)});for(let p of d){let m=i[p];m&&m.tests.push({id:s,name:c,relativePath:l})}}e.status(200).json(i)}));al.get("/:moduleId",De(async(r,e)=>{if(!r.params.moduleId){e.status(400).json({error:"Missing moduleId in url path."});return}let t=await Zt(je()),n=t.mobileModules[r.params.moduleId];if(!n){e.status(404).json({error:"Mobile module not found."});return}try{let o=await qy(n,t,P);e.json(o)}catch(o){e.status(400).json({err:o})}}));al.patch("/:moduleId/metadata",De(async(r,e)=>{if(!r.params.moduleId){e.status(400).json({error:"Missing moduleId in url path."});return}let t;try{t=nR.parse(r.body)}catch(i){e.status(400).json({error:`Invalid request body: ${i}`});return}let n=je(),o=await Zt(n);rL({moduleId:r.params.moduleId,patch:t,momenticFiles:o,logger:P,project:n}),e.status(201).json({message:"ok"})}));al.post("/",De(async(r,e)=>{let t;try{t=oR.parse(r.body)}catch(c){e.status(400).json({error:`Invalid request body: ${c}`});return}try{Mo(t.name)}catch(c){e.status(400).json({error:`Invalid module name: ${c}`});return}let n=je(),i=(await Zt(n)).mobileModules;if(Object.values(i).find(c=>c.name===t.name)){e.status(400).json({error:`A mobile module with the name "${t.name}" already exists. Please choose a different name.`});return}let a=SJ.join(n.rootDir,t.folderPath??"");if(!W0.existsSync(a)||!W0.statSync(a).isDirectory()){e.status(400).json({error:`The folder configured for mobile module creation does not exist: ${a}`});return}let s=await nL({...t,folder:a,project:n});e.status(201).json(s)}));var j0=al;var V0=yJ();V0.get("/",De(async(r,e)=>{let t=je(),n=await Zt(t),o=await eg(n),i=new Set;n?.mobileTests&&Object.values(n.mobileTests).forEach(l=>{l.labels?.forEach(u=>i.add(u))});let a=Array.from(i).sort(),s=Object.values(n.mobileTests),c={labels:a,modules:o,tests:s};e.status(200).json(c)}));var $0=V0;import{Router as bJ}from"express";var tg=bJ();tg.get("/",De((r,e)=>{let t=jO(je(),Ze);e.status(200).json(t)}));tg.get("/names",De((r,e)=>{let n=je().config.environments?.map(o=>o.name)??[];e.status(200).json(n)}));tg.post("/",De((r,e)=>{let t;try{t=rR.parse(r.body)}catch(s){e.status(400).json({error:`Invalid request body: ${s}`});return}try{Mo(t.name)}catch(s){e.status(400).json({error:`Invalid environment name: ${s}`});return}let n=je();if(n.config.environments?.find(s=>s.name===t.name)){e.status(400).json({error:`An environment with the name "${t.name}" already exists. Please choose a different name.`});return}let i={...n.config,environments:[...n.config.environments??[],{name:t.name}]};n.config=i,_p(i,n.configFilePath);let a=pa(t.name,n,Ze);e.status(201).json(a)}));var q0=tg;import{Router as EJ}from"express";var K0=EJ();K0.get("/",(r,e)=>{e.status(200).json({userId:Kp(),orgId:Xn(),cliVersion:Db??"0.0.0"})});var Y0=K0;import{Router as TJ}from"express";var X0=TJ();X0.get("/",De(async(r,e)=>{let t=r.query.sessionId;if(!t){e.status(400).json({packages:[]});return}let n=Qp.getSession(t);if(!n?.controller){e.status(200).json({packages:[]});return}try{let a=(await n.controller.executeRawADBCommand("shell pm list packages -3"))?.split(`
|
|
4650
|
+
`;import{tool as z3}from"ai";import{randomUUID as H3}from"crypto";import G3 from"zod";import{tool as U3}from"ai";import B3 from"zod";var Ib="get_emulator_state";var C0=r=>{let e=U3({description:"Get the current state of the emulator (XML + screenshot)",inputSchema:B3.object({}),toModelOutput:t=>t,execute:async()=>{let{controller:t,logger:n,contextManager:o}=r;return o.recordGenericToolCall(Ib),n.info("AI action tool called (get_emulator_state)"),Ob(t)}});return{name:Ib,tool:e}};async function Ob(r){let e=await r.getEmulatorDomState(),t=await r.getScreenshotBase64();return{type:"content",value:[{type:"text",text:"<emulatorXml>"},{type:"text",text:e},{type:"text",text:"</emulatorXml>"},{type:"text",text:"<screenshot>"},{type:"media",data:t,mediaType:"image/png"},{type:"text",text:"</screenshot>"}]}}var x0=r=>({name:"create_execute_step",tool:z3({description:"Create and immediately execute a new Momentic step in the Android emulator, returning the result from the step and the state of the emulator after the step finished executing.",inputSchema:G3.object({step:Wh}),toModelOutput:t=>t,execute:async({step:t})=>{let{contextManager:n,logger:o,controller:i}=r;o.info({step:t},"AI action tool called (create_execute_step)");let a=mA(t),s={id:H3(),type:"MOBILE_PRESET_STEP",command:a},c=await n.createAndExecuteStep(s);c.status==="SUCCESS"&&i.optionsCopy?.emulator?.waitForStability&&await i.waitForPageSourceStability({reason:"Waiting for stability after executing AI-generated sub-step"});let l={...c,trace:void 0,beforeSnapshot:void 0,afterSnapshot:void 0},u=await Ob(i);return{type:"content",value:[{type:"text",text:"<result>"},{type:"text",text:JSON.stringify(l,null,2)},{type:"text",text:"</result>"},{type:"text",text:"<stateAfter>"},...u.value,{type:"text",text:"</stateAfter>"}]}}})});import{tool as W3}from"ai";import Lb from"zod";var _0=r=>{let e=W3({description:"Signal that the AI action has reached a terminal state (either success or failure).",inputSchema:Lb.object({message:Lb.string(),success:Lb.boolean()}),toModelOutput:t=>t,execute:async({message:t,success:n})=>{let{contextManager:o,logger:i}=r;return i.info({message:t,success:n},"AI action tool called (finish)"),o.finalState={message:t,status:n?"SUCCESS":"FAILED"},{type:"content",value:[{type:"text",text:"Done"}]}}});return{name:_u,tool:e}};var M0=[x0,C0,_0];function P0(r){let{logger:e,controller:t,contextManager:n,aiActionSessionId:o}=r,i={};for(let c of M0){let l=c({contextManager:n,logger:e,controller:t});i[l.name]=l.tool}let a=t.generator.getVercelAnthropicModelFactory({logger:e,sessionId:o}),s=c=>{let{messages:l}=c,u=!1;for(let d=l.length-1;d>=0;d--){let p=l[d];for(let m of p.content)if(!(typeof m!="object"||!("type"in m))&&!(m.type!=="tool-result"||m.output.type!=="content")&&!(m.output.value.length<3))for(let g=0;g<m.output.value.length;g++){let h=m.output.value[g];if(h.type==="text"&&h.text.includes("<emulatorXml>"))if(u){let f=m.output.value[g+1];f.type==="text"?f.text="TRUNCATED DUE TO CONVERSATION LENGTH":e.warn({msg:f},"Got unexpected part when truncating emulator state message")}else{u=!0;continue}}}return c};return{model:a("claude-haiku-4-5-20251001"),tools:i,prepareStep:s,stopWhen:[V3(15),j3(_u)],system:w0(!1)}}async function I0(r){let e=Date.now(),{controller:t,logger:n}=r.fixtures;try{return await K3(r)}catch(o){let i=t.isAborted()||o instanceof DOMException&&o.name==="AbortError";return i||n.error({err:o},"Failed to execute mobile AI action"),{...r.aiActionParams.step,steps:[],type:"MOBILE_AI_ACTION_STEP",startTime:e,endTime:Date.now(),status:i?"CANCELLED":"FAILED",message:i?"Step cancelled.":`${o}`}}}async function K3(r){let{platform:e}=r,{step:t,stepTracer:n,executeMobileStepList:o}=r.aiActionParams,{controller:i,logger:a}=r.fixtures,{step:s}=r.callbacks,c=await n.startSubSteps(),l=q3(),u=a.child({stepId:t.id,aiActionSessionId:l}),d=Date.now();if(e!=="ANDROID"||!(i instanceof ii))throw new R("UserConfigurationError","AI action steps are only supported on Android platform.");let p=async(y,E)=>{let b=await o({...r,listParams:{steps:[y],tracer:c,containerName:`AI action sub-step ${E}`}});if(b.results.length!==1)throw new R("InternalWebAgentError","Expected exactly one result from executeMobileStepList");return b.results[0]},m={stepId:t.id,parentStepIdChain:n.getParentStepIdChain()},g=new Yp({controller:i,callbacks:{onAiActionEvent:s?.onAiActionEvent,executeStep:p},logger:u,rootStep:m}),h=P0({controller:i,logger:u,contextManager:g,aiActionSessionId:l}),f=$3({...h,messages:[{role:"user",content:t.text}],abortSignal:i.abortSignal});for await(let y of f.fullStream)switch(i.throwIfAborted(),y.type){case"text-delta":s?.onAiActionEvent?.({type:"LLM_TEXT_OUTPUT",text:y.text,rootStep:m})}if(await f.response,i.throwIfAborted(),!g.finalState)throw new R("InternalWebAgentError","The AI agent never reached a final state. This could be because the maximum number of steps was reached.");return{...t,status:g.finalState.status,startTime:d,endTime:Date.now(),message:g.finalState.message,steps:g.results}}var X3=60*60*1e3;async function vu(r){let{fixtures:e,inputs:t,listParams:n,work:o}=r,{containerName:i,steps:a,tracer:s}=n,{logger:c,controller:l,usageTracker:u}=e,d=s.getParentStepIdChain(),p=[],m,g="SUCCESS",h,{fromStep:f,toStep:y}=t;for(let E=0;E<a.length;E++){let b=a[E];if(b.skipped)continue;if(o.fastForwardingToStep&&f){let C=JSON.stringify(d);if(b.id===f.fromStepId&&C===JSON.stringify(f.parentStepIdChain))o.fastForwardingToStep=!1;else if(!iP({currentStep:b,currentParentChain:d,desiredStepId:f.fromStepId,desiredStepParentChain:f.parentStepIdChain}))continue}let _=0,M=1,O=Date.now();b.retries&&b.retries>0&&(M+=b.retries);let v=[];for(;_<M&&Date.now()-O<X3;){_++;let C=`Executing step index ${E} in ${i} - ${ta(b)}`;_!==1&&(C+=` (attempt ${_})`),c.info({step:b},C);let F=Date.now(),I=await s.startStep({logger:c,step:b,attempt:_,parentStepIdChain:d});u.trackStepExecution(b);let B=Y3(b),D=await J3({step:b,stepTracer:I,params:r}),{trace:ee}=await I.finish({parentStepIdChain:d,result:D});if(D.trace=ee,C=`Finished step index ${E} in ${i} - ${ta(b)}`,_!==1&&(C+=` (attempt ${_})`),c.info({step:{id:b.id},trace:D.trace,status:D.status},C),D.status!=="SUCCESS"&&_<M){v.push(D),Date.now()-F<1e3&&await J(1e3-(Date.now()-F));continue}if(v.length>0&&(D.previousAttempts=v),p.push(D),h=await Z3({result:D,step:b,originalStep:B,steps:a,currentStepIndex:E,params:r,stepTracer:I,isLastAttempt:_===M,results:p}),D.status!=="SUCCESS"&&h!=="SUCCESS")return g=D.status,m=D,{results:p,status:g,terminalResult:m};if(b.envKey&&l.context.setVariable(b.envKey,D.data),y){let K=JSON.stringify(d);if(b.id===y.toStepId&&K===JSON.stringify(y.parentStepIdChain))return o.shouldStopExecuting=!0,{results:p,status:g,terminalResult:m}}if(o.shouldStopExecuting)return{results:p,status:g,terminalResult:m};break}}return{results:p,status:g,terminalResult:m}}async function J3({step:r,params:e,stepTracer:t}){let{fixtures:n,inputs:o,callbacks:i,work:a}=e,s;switch(r.type){case"MOBILE_PRESET_STEP":{s=await A0({platform:e.platform,fixtures:n,inputs:o,step:r,stepTracer:t,callbacks:i,work:a});break}case"RESOLVED_MOBILE_MODULE":{s=await T0({...e,moduleParams:{step:r,stepTracer:t,executeMobileStepList:vu}});break}case"MOBILE_AI_ACTION_STEP":{s=await I0({...e,aiActionParams:{step:r,stepTracer:t,executeMobileStepList:vu}});break}}return s}async function Z3({result:r,step:e,originalStep:t,steps:n,currentStepIndex:o,params:i,stepTracer:a,isLastAttempt:s,results:c}){let l,u;if(s&&r.status==="FAILED"&&!i.work.state.failureRecoveryDisabled){let d=await E0({...i,stepTracer:a,step:e,steps:n,currentStepIndex:o,isLastAttempt:s,executeMobileStepList:vu,failedStep:t,nextSteps:n.slice(o+1),results:c.concat(r)});d&&(d.type==="ATTEMPTED"?(l=d.result.results,u=d.status):d.type==="NOT_ELIGIBLE"&&(r.message=r.message?`${r.message} ${d.message}`:d.message),r.type==="MOBILE_PRESET_STEP"&&(r.failureRecoveryStatus={type:d.type,message:d.message}))}return l&&c.push(...l),u}import{diff as Q3}from"deep-object-diff";import{cloneDeep as eJ}from"lodash-es";async function ol(r){let{tracer:e,containerName:t}=r,{steps:n,testMetadata:o}=r.inputs,{cacheStorage:i,logger:a}=r.fixtures,s=a.child({testId:r.inputs.testMetadata.id,testName:r.inputs.testName});await i.populateCacheForRun({logger:s,platform:o.platform,testId:o.id,stepLists:{steps:n},skipFetchingCacheFromStorage:r.inputs.interactive});let c=eJ(n);s.info({testMetadata:Do.parse(o)},"Starting mobile test");let l=await e.startMainStepList(),u=Aw(s);s.info({cpu:u?.cpuMetadata,platform:u?.platform},`Starting execution of ${t}`);let{status:d,results:p,terminalResult:m}=await vu({...r,listParams:{containerName:t,tracer:l,steps:c}});return clearInterval(u?.interval),await tJ({steps:n,stepsToExecute:c,logger:s,cacheStorage:i,orgId:r.inputs.orgId,testId:o.id,platform:o.platform}),d==="SUCCESS"?{status:"PASSED",results:p,failureRecoveryDetails:r.work.state.failureRecoveryAttempts?{attempts:r.work.state.failureRecoveryAttempts}:void 0}:d==="CANCELLED"?{status:"CANCELLED",results:p}:{status:"FAILED",results:p,terminalResult:m}}async function tJ({steps:r,stepsToExecute:e,logger:t,cacheStorage:n,orgId:o,testId:i,platform:a}){let s=Q3(r,e);if(s&&Object.keys(s).length>0){t.info({diffs:rs(s)},"Saving mobile step cache entries");let{cachesToSave:c}=await zn({platform:a,steps:e,cacheCreationParams:{orgId:o,testId:i}});await n.saveEntries({logger:t,testId:i,entries:c})}else t.info("No cache entries to update")}import{Server as dJ}from"socket.io";import{tmpdir as rJ}from"os";import O0 from"path";async function L0({socket:r,logger:e,orgId:t,testMetadata:n,globalOrgSettings:o,androidDriverFactory:i,mobileGeneratorFactory:a,browserGeneratorFactory:s,browserEnricherFactory:c,storageFactory:l,localToolsFactory:u,globalStateManager:d,getGitMetadata:p}){let m=r.id,g=await p(),h=r.handshake.query?.fileName,f=h?O0.basename(h,".test.yaml"):"",y=n.id,E=n.settings?.defaultChannel,b=n.settings?.defaultTag;e=e.child({sessionId:m,testId:y,orgId:t,branch:g.gitBranchName});let _=await l(t),M=n.settings?.defaultEnv,O={};M&&(O=(await _.fetchEnvironment(M,e))?.variables??{});let v=os.parse(O[Mi]),C=os.parse(O[Dl]),F={...o.emulator,...n.settings?.emulator},I=n.settings?.defaultApkFilePath?.trim()||C,B=d.getSession(m);if(B){if(e.info("Reconnecting to existing Android session"),B.local)return r.emit("session",B.metadata),B.softDeleted=!1,B.metadata;throw new Error("Restoring existing remote emulator sessions is not supported. Please reconnect to a new emulator.")}let D;if(F.region==="local"){if(await d.clearSoftDeletedLocalSessions(e),d.hasActiveLocalSession())throw new Error("Another local emulator session is already active. Please close the existing session before creating a new one.");let fi=n.settings?.emulator?.localEmulatorSettings?.avdId?.trim()||v;if(!fi)throw new Error(`AVD ID is required when using a local emulator. Set it on the test (Options \u2192 Emulator \u2192 Local AVD ID) or on the environment via ${Mi}.`);D={avdId:fi,apkToInstall:E?{channel:E,tag:b}:void 0,apkFilePath:I}}else D={region:F.region,apkToInstall:E?{channel:E,tag:b}:void 0,osVersion:F.remoteEmulatorSettings?.androidVersion};let ee=Date.now(),{driver:K,cleanup:ge,emulatorName:U,adbPort:W,limbarClient:ue,limbarToken:le,limbarUrl:He,playwrightDevice:ve}=await i({socket:r,logger:e,creationOpts:D}),q=O0.join(rJ(),`logcat-logs-${t}-${y}-${m}.txt`),fe=await Om({driver:K,onLogs:fi=>{r.emit("logcatLogs",fi)},logFilePath:q});e.info({adbPort:W,apkChannel:E,apkTag:b,duration:Date.now()-ee,emulatorName:U},"Android emulator session initiated"),e=e.child({emulator:U});let it=await a(t,e),Ae=await s(t,e),x=await c(t,e),ne=u?await u(t):void 0,pe=new No({variablesFromEnvironment:O,envName:M,testName:f}),Ur=await ii.init({driver:K,generator:it,logger:e,limbarClient:ue,playwrightDevice:ve,aiSettings:{...o.ai,useMemory:o.ai?.useMemory!==!1,...n.settings?.ai},options:{emulator:{...F,browserSettings:o.browser}},fixtures:{storage:_,browserEnricher:x,browserGenerator:Ae,localCodeEvalTools:ne,testContext:pe},orgId:t,adbPort:W,abortController:new AbortController}),hi=await Ur.getViewportBounds();if(!r.connected)throw await Ur.cleanup(),await fe(),await ge(),new Error("Socket not connected anymore, not proceeding with Android session setup");let qD=nJ({socket:r,testContext:pe}),KD=async()=>{clearInterval(qD);try{await Promise.allSettled([Ur.cleanup(),fe(),ge()])}catch(fi){e.warn({err:fi},"Failed to clean up emulator in socket server")}},ie={sessionId:m,testId:y,orgId:t,emulatorName:U,testName:f,limbarUrl:He,limbarToken:le,viewportBounds:hi};return d.registerSession(m,{controller:Ur,cleanup:KD,emulatorName:U,local:F.region==="local",metadata:ie,logFilePath:q}),r.emit("session",ie),ie}function nJ({socket:r,testContext:e}){return setInterval(()=>{let t=e.toEditorDisplayCopy();r.emit("emulatorState",{context:t})},3e3)}import Xp from"fs/promises";async function N0({socket:r,logger:e,globalStateManager:t,authorization:n}){let o=r.id,i=t.getSession(o);i&&n&&i.logFilePath&&oJ({testId:i.metadata.testId,sessionId:o,logFilePath:i.logFilePath,authorization:n,logger:e}),await t.removeSession(o,e)}async function oJ({testId:r,sessionId:e,logFilePath:t,authorization:n,logger:o}){try{let i;try{i=await Xp.stat(t)}catch{o.debug({logFilePath:t},"No logcat file found to upload");return}if(i.size===0){o.debug({logFilePath:t},"Logcat file is empty, skipping upload"),await Xp.unlink(t);return}let a=new _r(n),{uploadUrl:s}=await a.generateMobileLogcatUploadUrl({testId:r,sessionId:e}),c=await Xp.readFile(t),l=await fetch(s,{headers:{"Content-Length":c.length.toString(),"Content-Type":"text/plain"},method:"PUT",body:c});if(l.status!==200)throw new Error(`Failed to upload logcat: ${l.status} ${await l.text()}`);o.info({testId:r,sessionId:e},"Logcat file uploaded successfully")}catch(i){o.warn({err:i,testId:r,sessionId:e},"Failed to upload logcat file")}finally{try{await Xp.unlink(t)}catch(i){o.warn({err:i,logFilePath:t},"Failed to delete temp logcat file")}}}var iJ=({socket:r,globalStateManager:e})=>async()=>{let t=e.getSession(r.id);if(!t)throw new Error("No active Android session found");t.controller.abort()},D0={event:"cancel",createHandler:iJ};var aJ=({logger:r,globalStateManager:e,socket:t})=>async(n,o)=>{let i=e.getSession(t.id);if(!i){o({err:"No active Android session found"});return}try{let s=await i.controller.getEmulatorDomState();o({screenXml:s})}catch(a){r.error({err:a},"Error fetching screen XML from the session controller"),o({err:a.message})}},k0={event:"fetchScreenXml",createHandler:aJ};var Nb=class{parentTracer;socket;step;orgId;interactionTracer;constructor({step:e,socket:t,parentTracer:n,orgId:o}){this.socket=t,this.parentTracer=n,this.step=e,this.orgId=o,this.interactionTracer=new Jo,rn.initializeRootTracerContext(this.interactionTracer)}attachBeforeScreenshot(){}attachAfterScreenshot(){}attachBeforeXmlSnapshot(){}attachAfterXmlSnapshot(){}recordStepDuration(e){let{durationMs:t,step:n}=e,o=n.type!=="MOBILE_PRESET_STEP"?n.type:n.command.type;nt.distribution("test_step_duration",t,[`type:${o}`,"platform:mobile","executor:editor",`orgId:${this.orgId}`])}async finish(e){this.interactionTracer.finish();let t=this.interactionTracer.getRootSpan(),n={...sw.parse(e),trace:Xh.parse(t)};switch(n.result.status){case"SUCCESS":this.socket.emit("success",n);break;case"FAILED":this.socket.emit("failure",n);break;case"CANCELLED":this.socket.emit("cancelled",n);break}return{trace:t}}getParentStepIdChain(){return this.parentTracer?this.parentTracer?.getParentStepIdChain()??[]:[]}async startSubSteps(){return new il({parentStep:this.step,socket:this.socket,parentTracer:this,orgId:this.orgId})}},il=class{parentTracer;parentStep;socket;orgId;constructor({parentStep:e,socket:t,parentTracer:n,orgId:o}){this.parentTracer=n,this.parentStep=e,this.socket=t,this.orgId=o}getParentStepIdChain(){return this.parentStep?[...this.parentTracer?.getParentStepIdChain()??[],this.parentStep.id]:[]}async startStep(e){return this.socket.emit("started",{stepId:e.step.id,parentStepIdChain:e.parentStepIdChain,attempt:e.attempt}),new Nb({step:e.step,parentTracer:this,socket:this.socket,orgId:this.orgId})}async getScreenshot(e){}},Jp=class{constructor(e,t){this.socket=e;this.orgId=t}appendLogs(){}async finish(){this.socket.emit("finished")}async startBeforeStepList(){return new il({parentStep:null,parentTracer:null,socket:this.socket,orgId:this.orgId})}async startMainStepList(){return new il({parentStep:null,parentTracer:null,socket:this.socket,orgId:this.orgId})}async startAfterStepList(){return new il({parentStep:null,parentTracer:null,socket:this.socket,orgId:this.orgId})}};var sJ=({metadata:r,logger:e,globalStateManager:t,socket:n,cacheStorageFactory:o,getGitMetadata:i})=>async(a,s)=>{let c=t.getSession(n.id);if(!c)throw new Error("No active Android session found");if(a.testMetadata.platform!=="ANDROID")throw new Error("Non-android tests aren't supported yet");let l=await i(),u=e.child({testId:a.testMetadata.id,branch:l.gitBranchName}),d=await o(r.orgId,l),p=c.controller;p.resetAbortController();let m=new Jp(n,r.orgId),g=await ol({platform:"ANDROID",work:{fastForwardingToStep:!!a.fromStep,state:{failureRecoveryDisabled:!0,failureRecoveryAttempts:0}},fixtures:{controller:p,logger:u,cacheStorage:d,usageTracker:new ud},containerName:"entire test",inputs:{steps:a.steps,fromStep:a.fromStep,toStep:a.toStep,orgId:r.orgId,testName:r.testName,testMetadata:a.testMetadata,interactive:!0},tracer:m,callbacks:{step:{onAiActionEvent:f=>{n.emit("aiActionEvent",f)}}}});await m.finish();let h={results:Sr.array().parse(g.results),status:g.status};s?.(h)},F0={event:"execute",createHandler:sJ};import{debounce as lJ}from"ts-debounce";var cJ=({socket:r,globalStateManager:e,keepSessionAlive:t})=>{let n=lJ(t,3e4,{maxWait:6e4});return async()=>{let o=e.getSession(r.id);if(!o)throw new Error("No active Android session found");o.emulatorName&&(o.local||n(o.emulatorName))}},U0={event:"keepalive",createHandler:cJ};var uJ=({socket:r,globalStateManager:e,logger:t})=>async(n,o)=>{let i=e.getSession(r.id);if(!i){let s="No active Android session found";t.error(s),o?.({success:!1,err:s});return}let a=i.controller;a.abort(),a.resetAbortController(),t.info("Resetting emulator state");try{await a.softReset(),t.info("Emulator reset completed"),o?.({success:!0,message:"Emulator reset successfully"})}catch(s){let c=s instanceof Error?s.message:String(s);t.error({err:s},"Failed to reset emulator"),o?.({success:!1,err:`Failed to reset emulator: ${c}`})}},B0={event:"reset",createHandler:uJ};var z0=[F0,D0,B0,U0,k0];var Zp=class{sessions=new Map;registerSession(e,t){this.sessions.set(e,t)}getSession(e){return this.sessions.get(e)}async clearSoftDeletedLocalSessions(e){for(let t of this.sessions.values())t.softDeleted===!0&&t.local===!0&&await this.removeSession(t.metadata.sessionId,e)}hasActiveLocalSession(){for(let e of this.sessions.values())if(e.local===!0)return!0;return!1}async removeSession(e,t){let n=this.sessions.get(e);if(n)try{await n.cleanup?.(),t.info({sessionId:e,emulatorName:n.emulatorName},"Android emulator cleaned up by removeSession")}catch(o){t.error({err:o},"Error during Android session cleanup")}finally{this.sessions.delete(e)}}async removeAllSessions(e){let t=Array.from(this.sessions.keys());await Promise.all(t.map(n=>this.removeSession(n,e)))}};function H0(r){let{logger:e,baseServer:t,globalStateManager:n,settingsFactory:o,getOrgId:i}=r,a=new dJ(t,{cors:{origin:"*",methods:["GET","POST"]},pingTimeout:15*60*1e3,pingInterval:15*60*1e3,maxHttpBufferSize:1e7,perMessageDeflate:!0,connectionStateRecovery:{maxDisconnectionDuration:60*60*1e3,skipMiddlewares:!0}}),s=async()=>{await n.removeAllSessions(e)};a.on("connection",async l=>{let u=l.id,d=e.child({sessionId:u});d.info({event:"connection",transport:l.conn.transport.name},"Android websocket connection initiated"),l.on("disconnect",async g=>{if(e.info({reason:g},"Disconnect received"),g.includes("namespace disconnect")){await N0({socket:l,globalStateManager:n,logger:d,authorization:r.authorization});return}let h=n.getSession(u);h&&(h.softDeleted=!0)});let p,m;try{let g=l.handshake.query?.testMetadata,h=Do.parse(JSON.parse(g??"")),f=h.id,y=await i({testId:f});m=await o(y,e),p=await L0({...r,orgId:y,socket:l,globalStateManager:n,logger:d,globalOrgSettings:m,testMetadata:h})}catch(g){d.error({err:g},"Failed to setup Android connection"),l.emit("error",{message:g instanceof Error?g.message:JSON.stringify(g)}),l.disconnect(!0);return}z0.forEach(g=>c(g,{...r,socket:l,metadata:p,globalOrgSettings:m,logger:d}))});let c=(l,u)=>{let d=l.createHandler(u),p=(...m)=>{l.event!=="keepalive"&&u.logger.debug({event:l.event},`Websocket event (${l.event})`);let g=h=>{u.logger.error({event:l.event,err:h instanceof Error?h:new Error(`${h}`)},"Unhandled exception in socket handler"),u.socket.emit("error",{message:h instanceof Error?h.message:typeof h=="string"?h:JSON.stringify(h)})};try{let h=d.apply(this,m);h&&typeof h.catch=="function"&&h.catch(g)}catch(h){g(h)}};u.socket.on(l.event,p)};return{server:a,dispose:s}}import NJ from"path";var Qp=new Zp;import{Router as pJ}from"express";import{existsSync as gJ}from"fs";import hJ from"path";import{hostname as mJ}from"os";var Db="0.34.0",Ze=ms({app:"mobile-desktop-server",hostname:mJ(),disableConsoleLogs:!0,captureExceptions:!0}).child({cliVersion:Db});(async()=>{try{let r=await mu(Ze);r.gitBranchName&&Ze.addBinding("branch",r.gitBranchName)}catch{}})();var kb=pJ();kb.get("/",De(async(r,e)=>{let t=Mr();if(!t){e.status(500).json({message:"API client not initialized"});return}let n=await t.getAndroidAssets();e.status(200).json(n)}));kb.post("/upload-url",De(async(r,e)=>{let t;try{t=tR.parse(r.body)}catch(i){e.status(400).json({error:`Invalid request body: ${i}`});return}let n=Mr();if(!n){e.status(500).json({error:"API client not initialized"});return}let o=hJ.resolve(t.filePath);if(!gJ(o)){e.status(400).json({error:`File not found: ${o}`});return}await Im({tag:t.tag,channel:t.channel,filePath:o,apiClient:n,logger:Ze}),e.sendStatus(204)}));var G0=kb;import{Router as yJ}from"express";import{Router as fJ}from"express";import W0 from"fs";import SJ from"path";var al=fJ();async function eg(r){return(await oL(r,Ze)).map(n=>{let o=r.mobileModules[n.moduleId];if(!o){P.warn(`Found a dangling mobile module with ID ${n.moduleId} that could not be found on disk.`);return}return{...o,content:n}}).filter(n=>n!==void 0)}al.get("/",De(async(r,e)=>{let t=je(),n=await Zt(t),o=await eg(n);e.status(200).json(o)}));al.get("/tests-join",De(async(r,e)=>{let t=je(),n=await Zt(t),o=await eg(n),i={};for(let s of o)i[s.id]={...s,tests:[]};let a=await Promise.all(Object.values(n.mobileTests).map(async s=>({id:s.id,name:s.name,relativePath:s.relativePath,test:await So(s.fullFilePath,Ze,n)})));for(let{id:s,name:c,relativePath:l,test:u}of a){let d=new Set;$S({steps:u.steps,onPreset:()=>!1,onModule:p=>(d.add(p.moduleId),!1)});for(let p of d){let m=i[p];m&&m.tests.push({id:s,name:c,relativePath:l})}}e.status(200).json(i)}));al.get("/:moduleId",De(async(r,e)=>{if(!r.params.moduleId){e.status(400).json({error:"Missing moduleId in url path."});return}let t=await Zt(je()),n=t.mobileModules[r.params.moduleId];if(!n){e.status(404).json({error:"Mobile module not found."});return}try{let o=await qy(n,t,P);e.json(o)}catch(o){e.status(400).json({err:o})}}));al.patch("/:moduleId/metadata",De(async(r,e)=>{if(!r.params.moduleId){e.status(400).json({error:"Missing moduleId in url path."});return}let t;try{t=nR.parse(r.body)}catch(i){e.status(400).json({error:`Invalid request body: ${i}`});return}let n=je(),o=await Zt(n);rL({moduleId:r.params.moduleId,patch:t,momenticFiles:o,logger:P,project:n}),e.status(201).json({message:"ok"})}));al.post("/",De(async(r,e)=>{let t;try{t=oR.parse(r.body)}catch(c){e.status(400).json({error:`Invalid request body: ${c}`});return}try{Mo(t.name)}catch(c){e.status(400).json({error:`Invalid module name: ${c}`});return}let n=je(),i=(await Zt(n)).mobileModules;if(Object.values(i).find(c=>c.name===t.name)){e.status(400).json({error:`A mobile module with the name "${t.name}" already exists. Please choose a different name.`});return}let a=SJ.join(n.rootDir,t.folderPath??"");if(!W0.existsSync(a)||!W0.statSync(a).isDirectory()){e.status(400).json({error:`The folder configured for mobile module creation does not exist: ${a}`});return}let s=await nL({...t,folder:a,project:n});e.status(201).json(s)}));var j0=al;var V0=yJ();V0.get("/",De(async(r,e)=>{let t=je(),n=await Zt(t),o=await eg(n),i=new Set;n?.mobileTests&&Object.values(n.mobileTests).forEach(l=>{l.labels?.forEach(u=>i.add(u))});let a=Array.from(i).sort(),s=Object.values(n.mobileTests),c={labels:a,modules:o,tests:s};e.status(200).json(c)}));var $0=V0;import{Router as bJ}from"express";var tg=bJ();tg.get("/",De((r,e)=>{let t=jO(je(),Ze);e.status(200).json(t)}));tg.get("/names",De((r,e)=>{let n=je().config.environments?.map(o=>o.name)??[];e.status(200).json(n)}));tg.post("/",De((r,e)=>{let t;try{t=rR.parse(r.body)}catch(s){e.status(400).json({error:`Invalid request body: ${s}`});return}try{Mo(t.name)}catch(s){e.status(400).json({error:`Invalid environment name: ${s}`});return}let n=je();if(n.config.environments?.find(s=>s.name===t.name)){e.status(400).json({error:`An environment with the name "${t.name}" already exists. Please choose a different name.`});return}let i={...n.config,environments:[...n.config.environments??[],{name:t.name}]};n.config=i,_p(i,n.configFilePath);let a=pa(t.name,n,Ze);e.status(201).json(a)}));var q0=tg;import{Router as EJ}from"express";var K0=EJ();K0.get("/",(r,e)=>{e.status(200).json({userId:Kp(),orgId:Xn(),cliVersion:Db??"0.0.0"})});var Y0=K0;import{Router as TJ}from"express";var X0=TJ();X0.get("/",De(async(r,e)=>{let t=r.query.sessionId;if(!t){e.status(400).json({packages:[]});return}let n=Qp.getSession(t);if(!n?.controller){e.status(200).json({packages:[]});return}try{let a=(await n.controller.executeRawADBCommand("shell pm list packages -3"))?.split(`
|
|
4651
4651
|
`).filter(s=>s.trim().startsWith("package:")).map(s=>s.replace("package:","").trim()).filter(s=>s.length>0&&!s.startsWith("io.appium"))||[];e.status(200).json({packages:a})}catch(o){Ze.error({err:o},"Error fetching installed packages from the session controller"),e.status(200).json({packages:[]})}}));var J0=X0;import{Router as vJ}from"express";var Fb=vJ(),AJ=async({steps:r,cacheStorage:e,stepId:t,parentStepIdChain:n,testId:o})=>{let{result:i}=KS(r,t,n);if(i)return await e.getCacheKeyForStep({logger:Ze,testId:o,parentStepIdChain:n,step:i})};Fb.patch("/",De(async(r,e)=>{let t=je(),n=Xn(),o=Mr();if(!o){e.status(500).json({error:"API client not initialized"});return}let i;try{i=aR.parse(r.body)}catch(l){e.status(400).json({error:`Invalid request body: ${l}`});return}let a=await sn(Ze,o,t),s=pi({logger:Ze,orgId:n,client:o,gitMetadata:a,regenerateCache:!1,noCache:!1,alwaysSaveCache:!1}),c=await AJ({cacheStorage:s,steps:i.steps,stepId:i.stepId,parentStepIdChain:i.parentStepIdChain,testId:i.testId});if(!c){e.status(400).json({error:"Cache-supporting step not found"});return}await o.updateMobileStepCaches({entries:[{key:c,organizationId:n,value:i.value,testId:i.testId}],testId:i.testId},fc(a)),e.status(204).send()}));Fb.post("/traces",De(async(r,e)=>{let t=Mr();if(!t){e.status(500).json({error:"API client not initialized"});return}let n;try{n=_d.parse(r.body)}catch(i){e.status(400).json({error:`Invalid request body: ${i}`});return}let o=await t.getMobileStepCacheMemoryTraces(n);e.status(200).json(o)}));var Z0=Fb;import{Router as RJ}from"express";import Ub from"fs";import gi from"path";import{v4 as wJ}from"uuid";import CJ from"yaml";var sl=RJ();sl.patch("/:testPath",De(async(r,e)=>{let t=r.params.testPath;if(!t){e.status(400).json({error:"Missing testPath in path"});return}let n;try{n=QA.parse(r.body)}catch(c){e.status(400).json({error:`Invalid request body: ${c}`});return}if(n.steps===void 0&&n.settings===void 0&&n.labels===void 0){e.status(400).json({error:"At least one of steps, settings, or labels is required"});return}let o=je(),i=t.endsWith(".test.yaml")?t:`${t}.test.yaml`,a=await Zt(o);await aL({filePath:i,steps:n.steps,settings:n.settings,labels:n.labels,folder:o.rootDir,project:o,momenticFiles:a,schemaVersion:_o});let s={message:"ok"};e.status(200).json(s)}));sl.post("/",De((r,e)=>{let t;try{t=ZA.parse(r.body)}catch(g){e.status(400).json({error:`Invalid request body: ${g}`});return}let{name:n,description:o,settings:i,pathSegments:a}=t;if(!n||typeof n!="string"){e.status(400).json({error:"Missing or invalid 'name' in body"});return}try{Mo(n)}catch(g){e.status(400).json({error:g.message});return}let s=je(),c=gi.join(s.rootDir,...a),{fullPath:l,testId:u}=iL({name:n,description:o,steps:[],settings:i,folder:c}),d=gi.basename(l),p=gi.relative(s.rootDir,l),m={id:u,fileName:d,fullPath:l,relativeFilePath:p};e.status(201).json(m)}));sl.get("/:fileName",De(async(r,e)=>{let t=Mr(),n=Xn(),o=r.params.fileName;if(!o){e.status(400).json({error:"Missing fileName in path"});return}if(!t){e.status(500).json({error:"API client not initialized"});return}let i=o.endsWith(".test.yaml")?o:`${o}.test.yaml`,a=gi.basename(i).replace(".test.yaml",""),s=je(),c=await Zt(s),l=await So(i,Ze,c),u=await sn(Ze,t,s);await pi({logger:Ze,orgId:n,client:t,gitMetadata:u,regenerateCache:!1,noCache:!1,alwaysSaveCache:!1}).resolveEntries({logger:Ze,platform:l.platform,testId:l.id,stepLists:{steps:l.steps}});let p={...l,name:a};e.status(200).json(p)}));sl.patch("/:testPath/metadata",De(async(r,e)=>{let t=r.params.testPath;if(!t){e.status(400).json({error:"Missing testPath in path"});return}let n;try{n=eR.parse(r.body)}catch(c){e.status(400).json({error:`Invalid request body: ${c}`});return}let o=je(),i=t.endsWith(".test.yaml")?t:`${t}.test.yaml`,s={message:"ok",newRelativeTestPath:sL(i,n,o).newRelativeTestPath};e.status(200).json(s)}));sl.post("/:testPath/duplicate",De(async(r,e)=>{let{testPath:t}=r.params;if(!t){e.status(400).json({error:"Missing testPath in url path."});return}let n;try{n=iR.parse(r.body)}catch(h){e.status(400).json({error:`Invalid request body: ${h}`});return}try{Mo(n.name)}catch(h){e.status(400).json({error:h.message});return}let o=je(),i=gi.join(o.rootDir,t);if(!Ub.existsSync(i)){e.status(404).json({error:"Test not found."});return}let a=await Zt(o),s;try{s=await So(i,Ze,a)}catch(h){e.status(400).json({error:h.message});return}let c=wJ(),{stepsToSave:l}=await zn({...s,createNewCacheIds:!0}),u=po({fileType:Xe.MOBILE_TEST,id:c,schemaVersion:_o,description:s.description,platform:s.platform,settings:s.settings,labels:s.labels,steps:l});_A.parse(u);let d=gi.dirname(i),p=gi.join(d,`${n.name}.test.yaml`);if(Ub.existsSync(p)){e.status(409).send("A test with this name already exists");return}let m=CJ.stringify(u);Ub.writeFileSync(p,m,"utf-8");let g={relativeFilePath:gi.relative(o.rootDir,p)};e.status(201).json(g)}));var Q0=sl;import{Router as xJ}from"express";var eD=xJ();eD.get("/",De((r,e)=>{let t=je(),n={ai:t.config.ai,displayRoot:t.config.displayRoot};e.status(200).json(n)}));var tD=eD;import{Router as _J}from"express";var rD=_J();rD.post("/traces",De(async(r,e)=>{let t=Mr();if(!t){e.status(500).json({error:"API client not initialized"});return}let n;try{n=_d.parse(r.body)}catch(i){e.status(400).json({error:`Invalid request body: ${i}`});return}let o=await t.getWebStepCacheMemoryTraces(n);e.status(200).json(o)}));var nD=rD;var rg=class extends Js{constructor(t,n){super(t,n);this.client=t;this.orgId=n}async fetchEnvironment(t,n){let o=je();return pa(t,o,P)}};var aD="10mb";async function sD(r){let{serverPort:e,apiKey:t,momenticServerUrl:n,staticDir:o,initialProject:i,driverLogLevel:a,regenerateCache:s,alwaysSaveCache:c,noCache:l}=r;n&&p0(n),g0({noCache:l,alwaysSaveCache:c}),await f0(t);let u=Xn(),d=Kp(),p=r.logger.child({orgId:u,userId:d});S0(i,v=>Vs({configFilePath:v}));let m=iD();m.use(MJ()),m.use(oD.json({limit:aD})),m.use(oD.urlencoded({extended:!1,limit:aD}));let g=OJ();if(g.use("/folders",Mb),g.use("/entities",$0),g.use("/identify",Y0),g.use("/mobile-tests",Q0),g.use("/mobile-modules",j0),g.use("/mobile-cache",Z0),g.use("/web-cache",nD),g.use("/assets",G0),g.use("/git",Pb),g.use("/cache-config",_b),g.use("/environments",q0),g.use("/installed-packages",J0),g.use("/settings",tD),m.use("/api",g),m.use((v,C,F)=>{P.debug({url:v.url,path:v.path,query:v.query,method:v.method,body:v.body,headers:v.rawHeaders,client:v.ip},"Incoming request on mobile-desktop-server"),C.on("close",()=>{C.statusCode>=400&&(P.error({url:v.url,method:v.method,statusCode:C.statusCode},"Request completed in error on mobile-desktop-server"),Ze.error({url:v.url,method:v.method,statusCode:C.statusCode},"Request completed in error on mobile-desktop-server"))}),F()}),m.use((v,C,F,I)=>{if(v instanceof Error&&v.message.includes("BadRequestError: request aborted")){F.status(400).send("Client disconnected");return}P.error({stack:v.stack,msg:v.message,err:v,url:C.url,method:C.method},"Unhandled exception leading to 500 on mobile-desktop-server"),Ze.error({stack:v.stack,msg:v.message,err:v,url:C.url,method:C.method},"Unhandled exception leading to 500 on mobile-desktop-server"),F.status(500).send(`Internal Server Error: ${v.message}`)}),o){m.use((C,F,I)=>{if(C.path==="/run-viewer"||C.path.startsWith("/run-viewer/"))return F.status(404).send("Not Found");I()});let v=iD.static(o,{setHeaders:C=>{C.setHeader("Cache-Control","no-cache")},redirect:!1});m.use(v),m.use("*",(C,F)=>{F.sendFile(NJ.join(o,"index.html"))})}let h=LJ.createServer(m),f=`http://localhost:${e}`;await new Promise(v=>{try{h.listen(e,()=>{p.info(`Mobile desktop server is running at ${f}`),v()})}catch(C){C.message.includes("EADDRINUSE")?DJ(e):P.error(`An unexpected error occurred while starting the server: ${C.message}`),process.exit(1)}});let E={type:"API_KEY",baseUrl:Cb(),apiKey:t,logger:p},b=new _r(E),_=je(),M={...E,mode:"interactive"},{dispose:O}=H0({baseServer:h,logger:p,authorization:E,globalStateManager:Qp,getOrgId:()=>Xn(),getGitMetadata:async()=>await sn(p,b,_),androidDriverFactory:async({socket:v,logger:C,creationOpts:F})=>{let I=Math.floor(Math.random()*1e4)+4e4,B=await Yo(I,"appium");return Pm({logger:C,driverLogLevel:a,apiClient:b,creationOpts:F,socket:v,appiumPort:B,sessionId:v.id,orgId:Xn(),callbacks:{onStatusUpdate:D=>{C.info({status:D},"Emulator status update"),v.emit("connectionStatusUpdate",{message:D,type:"info"})},onHeartbeatFailure:()=>{v.emit("connectionStatusUpdate",{message:"Emulator connection lost \u2014 possible ADB tunnel/emulator failure",type:"disconnected"})},onHeartbeatRestored:()=>{v.emit("connectionStatusUpdate",{message:"Emulator connection restored",type:"connected"})},onLimbarConnectionStateChange:D=>{D==="disconnected"?v.emit("connectionStatusUpdate",{message:"Emulator connection lost.",type:"disconnected"}):D==="reconnecting"||D==="connecting"?v.emit("connectionStatusUpdate",{message:"Reconnecting to emulator...",type:D==="reconnecting"?"reconnecting":"connecting"}):D==="connected"&&v.emit("connectionStatusUpdate",{message:"Emulator connection restored",type:"connected"})}}})},mobileGeneratorFactory:async v=>new el({baseUrl:Cb(),apiKey:t,logger:p,mode:"interactive"}),browserGeneratorFactory:async v=>new Sa(_.config.ai?.agentConfig,M),browserEnricherFactory:async v=>new Xs(M,new Sa(_.config.ai?.agentConfig,M)),storageFactory:async v=>new rg(b,v),cacheStorageFactory:async(v,C)=>pi({logger:p,orgId:v,client:b,gitMetadata:C,regenerateCache:s,noCache:l,alwaysSaveCache:c}),localToolsFactory:async()=>new Qs({httpClient:b,fakerSeed:_.config.advanced?.fakerConstantSeed?fd:void 0}),keepSessionAlive:v=>b.extendAndroidEmulatorTtl(v),settingsFactory:async()=>({emulator:{},ai:{},browser:{},..._.config})});process.once("SIGUSR2",async()=>{return;try{await O(),await nt.flush()}catch(v){P.error({err:v},"Error during session dispose on SIGUSR2")}try{h.close(()=>{process.kill(process.pid,"SIGUSR2")})}catch{process.kill(process.pid,"SIGUSR2")}}),process.once("SIGTERM",async()=>{let v="SIGTERM in Momentic mobile app received";P.info(v),p.info(v);try{await O(),await nt.flush()}finally{h.close(()=>process.exit(0))}}),process.once("SIGINT",async()=>{P.info("SIGINT in Momentic mobile app received");try{await O(),await nt.flush()}finally{h.close(()=>process.exit(0))}})}IJ.setMaxListeners(25);process.on("warning",r=>{Ze.warn({err:r},`Node warning received on mobile-desktop-server: ${r.message}`)});process.on("uncaughtException",r=>{Ze.error({err:r},"Uncaught exception on mobile-desktop-server"),P.error(`Oh no! The Momentic mobile desktop app encountered a fatal error \u{1F61E}. Error logs: ${r.message}`)});process.on("unhandledRejection",r=>{Ze.error({reason:`${r}`,stack:r?.stack},"Uncaught exception on mobile-desktop-server (promise rejection)"),P.error(`Oh no! The Momentic mobile desktop app encountered an asynchronous error \u{1F61E}. Error logs: ${r}`)});function DJ(r){P.error(PJ`Port ${r} is already in use by another process. Please close the other process and try again.
|
|
4652
4652
|
Using Bash on MacOS or Linux:
|
|
4653
4653
|
lsof -t -i :58888 | xargs kill -9
|
|
@@ -4657,7 +4657,7 @@ Momentic users value the following:
|
|
|
4657
4657
|
`)}import{Readable as O6}from"node:stream";import L6 from"open";import bo,{dirname as N6,resolve as D6}from"path";import{pipeline as k6}from"stream/promises";import{fileURLToPath as cE}from"url";import Bb from"fs";import ng from"path";import{cwd as kJ}from"process";async function zb({tests:r,momenticFiles:e,project:t,yes:n,include:o,exclude:i,labels:a,logger:s,quarantinedTestsMetadata:c}){let l=new Set;if(r&&r.length>0){let d=r.some(m=>Bb.existsSync(m)),p=kJ();d?(p!==t.rootDir&&s.warn(`The current working directory ('${p}') is different from the project root directory ('${t.rootDir}'). All test path arguments will be resolved relative to the current working directory and only those tests matched by the project inclusion configuration will be ran. To avoid confusion, Momentic strongly recommends running the CLI from the project root directory or using substring filters rather than file paths.`),s.info(`Reading tests from the following local file paths:
|
|
4658
4658
|
- ${r.join(`
|
|
4659
4659
|
- `)}
|
|
4660
|
-
`),r.forEach(m=>{if(!Bb.existsSync(m))throw new Error(`Path '${m}' does not exist.`);let g,h;try{g=Bb.statSync(m),h=g.isDirectory()}catch(y){s.warn({err:y},`Skipping path ${m} because it cannot be read`);return}let f=ng.resolve(m);Object.values(e.mobileTests).filter(y=>h?y.fullFilePath.startsWith(f):y.fullFilePath===f).forEach(y=>{l.add(y.fullFilePath)})})):(s.info("The arguments provided don't appear to be valid paths. Treating them as substrings instead... "),Object.values(e.mobileTests).forEach(m=>{r.some(g=>m.relativePath.includes(g))&&l.add(m.fullFilePath)}))}else{!n&&!await Rm("No test paths or substrings were provided. Do you want to run all tests?")&&(s.error("Cancelled by user."),process.exit(1));let d=Object.values(e.mobileTests);s.info(`Reading all ${d.length} mobile tests in the project from local disk.`),d.forEach(p=>{l.add(p.fullFilePath)})}for(let d of Array.from(l)){let p=ng.relative(t.rootDir,d);o&&!o.some(m=>new RegExp(m).test(p))&&l.delete(d),i&&i.some(m=>new RegExp(m).test(p))&&l.delete(d)}return(await Promise.all(Array.from(l).map(async d=>{try{let p=ng.relative(t.rootDir,d),m=await So(d,s,e),g=ng.basename(d,".test.yaml");if(m.disabled)return null;if(a&&a.length>0){let f=m.labels||[];if(!a.some(E=>f.includes(E)))return null}let h={id:m.id,name:g,description:m.description,schemaVersion:m.schemaVersion,settings:m.settings,fullFilePath:d,relativeFilePath:p,quarantined:!!c[m.id],quarantinedMetadata:c[m.id],labels:m.labels};switch(m.platform){case"ANDROID":return{...h,platform:"ANDROID",steps:m.steps};case"IOS":return{...h,platform:"IOS",steps:m.steps};default:return(y=>{throw new Error("You missed a case in the switch above")})(m)}}catch(p){s.error(`Failed to read and resolve mobile test at '${d}': ${p}`),process.exit(1)}}))).filter(d=>!!d)}import{InvalidArgumentError as og,Option as Qe}from"@commander-js/extra-typings";import{z as FJ}from"zod";var lD=58890;function ll(r){let e=parseInt(r,10);if(isNaN(e))throw new og("Not a number.");return e}var ba=new Qe("--api-key <key>","Momentic API key").env("MOMENTIC_API_KEY").argParser(r=>{if(!r)throw new og("API key is required.");return r}).makeOptionMandatory(),ig=new Qe("-c, --config <configPath>","Absolute or relative path to a Momentic configuration file."),Hb=new Qe("-f, --filter <filter>","Run tests within the project that has a name equal to the filter provided. This option cannot be used together with file path or directory arguments, but substring matches are allowed."),Ea=new Qe("--server <server>","Momentic server to use.").env("MOMENTIC_SERVER").default("https://api.momentic.ai").argParser(r=>{try{return FJ.string().url().parse(r),r}catch{throw new og("Not a valid URL.")}}),Gb=new Qe("-y, --yes","Skip all confirmation prompts.").env("CI"),Wb=new Qe("--regenerate-cache","Regenerate all caches by starting from an empty cache state. This flag is useful for completely regenerating caches after changing configuration options. Warning: using this option will cause all steps to run without any cached data, resulting in significantly longer execution times."),jb=new Qe("--save-cache","Always save updated step caches after successful test runs. By default, caches are not saved when running on protected branches.").env("CI"),Vb=new Qe("--disable-cache","Disable using step caches completely. Using this option may lead to non-deterministic behavior and significantly longer runtimes.").implies({saveCache:!1}),$b=new Qe("--tag <tag>","Tag identifier for the asset."),cD=new Qe("--channel <channel>","Channel name for the asset."),qb=new Qe("--channel <channel>","Channel name for the asset.").makeOptionMandatory(),uD=new Qe("--tag <tag>","Tag identifier for the asset.").makeOptionMandatory(),dD=new Qe("--env <env>","Environment to run all tests in (overrides test-level configuration)."),Au="closest",mD=new Qe("--region <region>",`Region to run all tests in (overrides all other configuration). Valid values: ${Object.values(Hi).join(", ")}, ${Au}, ${Object.values(Gi).join(", ")}.`),pD=new Qe("--local-avd-id <localAvdId>","Force tests to use a specific local Android Virtual Device (AVD) instead of remote emulators."),gD=new Qe("--local-apk-path <localApkPath>","Path to a local APK file to install when running tests with a local emulator. Overrides remote asset configuration."),hD=new Qe("-p, --parallel <parallel>","The number of tests to run in parallel. Defaults to 1.").argParser(ll),fD=new Qe("--shard-index <shardIndex>","The index of the shard to run tests for. Defaults to 1.").default(1).argParser(r=>{let e=ll(r);if(e<1)throw new og("Shard index must be greater than 0.");return e}),SD=new Qe("--shard-count <shardCount>","The number of shards that tests are being run on. Defaults to 1.").default(1).argParser(ll),Kb=new Qe("--output-dir <outputDir>","Output directory to store run artifacts such as screenshots, results, and logs."),Yb=new Qe("--include <includePatterns...>","Only include tests that match the provided regex patterns. Multiple patterns can be provided. The patterns will be matched against the test file paths and the pattern only needs to match a part of the path for the test to be included."),Xb=new Qe("--exclude <excludePatterns...>","The inverted version of --include: a test that matches any of the provided exclusion patterns will be excluded from running."),yD=new Qe("--upload-results","Upload test results to Momentic Cloud.").default(!1),Jb=new Qe("--log-level <logLevel>","Log level for Momentic and dependent services.").choices(["error","warn","info","debug"]),bD=new Qe("--ignore-quarantine","Run all tests even if they are quarantined. This is useful for validating that quarantined tests are fixed before moving them out of quarantine.").implies({skipQuarantined:!1,onlyQuarantined:!1}),ED=new Qe("--timeout-minutes <timeoutMinutes>","Maximum number of minutes to run tests before stopping. When the timeout is reached, tests will stop and current results will be printed.").argParser(ll),TD=new Qe("--reporter <reporter>","Output report files in a standardized format to a local directory.").choices(Object.values(zl)),vD=new Qe("--reporter-dir <reporterDir>","Output directory to store report files. Relative paths are resolved relative to the project root, which is defined by the detected momentic.config.yaml.").default("reports"),AD=new Qe("--name <name>","A name to associate with this run for easier identification in the Momentic dashboard.");import{randomUUID as x6}from"crypto";import{existsSync as _6}from"fs";import{dirname as S6}from"path";import{randomUUID as BJ}from"crypto";import{existsSync as zJ,statSync as HJ}from"fs";import RD from"path";import GJ from"zod";async function wD({runTracer:r,metadata:{orgId:e,runId:t},fixtures:{logger:n,apiClient:o,mobileGenerator:i,storage:a,cacheStorage:s,usageTracker:c,browserEnricher:l,browserGenerator:u,localCodeEvalTools:d},inputs:{channel:p,tag:m,project:g,testDefinition:h},env:{envName:f,envVariables:y},settings:{emulatorSettings:E,aiSettings:b},options:{logLevel:_,localAvdId:M,localApkPath:O,region:v}}){let C=Math.floor(Math.random()*1e4)+4e4,F=await Yo(C,"appium"),I=es.or(GJ.literal(Au)).optional().parse(v??E.region),B=I==="local",D;if(B){let q;if(O&&(q=RD.resolve(O),!zJ(q)||!HJ(q).isFile()))throw new Error(`Local APK path "${q}" does not exist. Provide a valid file path via --local-apk-path.`);let fe,it=h.settings?.defaultApkFilePath;if(it){let hi=it.trim();hi&&(fe=hi)}let Ae=typeof y[Mi]=="string"?y[Mi].trim():void 0,x=typeof y[Dl]=="string"?y[Dl].trim():void 0,ne;x&&(ne=RD.resolve(x));let pe=q??fe??ne,Ur=M??E.localEmulatorSettings?.avdId??Ae;if(!Ur)throw new Error(`An AVD ID is required when using a local region. Provide --local-avd-id, configure a default local AVD ID on the test's settings, or set the ${Mi} key on the environment.`);D={avdId:Ur,apkFilePath:pe}}else D={region:I==="closest"?void 0:I,apkToInstall:p?{channel:p,tag:m}:void 0,osVersion:E.remoteEmulatorSettings?.androidVersion??fA};let ee=BJ(),K=n.child({runAttemptId:ee}),ge;try{ge=await Pm({apiClient:o,logger:n,driverLogLevel:_,creationOpts:D,callbacks:{onStatusUpdate:q=>{n.debug({status:q},"Emulator status update")},onHeartbeatFailure:()=>{let q="Appium heartbeat connection lost \u2014 possible ADB tunnel/emulator failure";P.warn(q)},onHeartbeatRestored:()=>{let q="Appium heartbeat connection restored";P.info(q)},onLimbarConnectionStateChange:q=>{q==="disconnected"?P.warn("Emulator websocket connection lost. Emulator may be unavailable."):(q==="reconnecting"||q==="connecting")&&P.info("Emulator websocket is reconnecting...")}},appiumPort:F,orgId:e,sessionId:ee})}catch(q){let fe=`Fatal error creating Android driver, failing test run attempt (runId: ${t})`;return n.error({err:q},fe),P.error({err:q},fe),{status:"FAILED",results:[],error:new R("UserConfigurationError",`Fatal error creating Android driver: ${q.message}`)}}let U=await r.startAttempt({emulatorName:ge.emulatorName,runAttemptId:ee});K=K.child(U.loggerBindings||{});let W=await Om({driver:ge.driver,onLogs:q=>{U.appendLogs(q)}}),ue=new No({variablesFromEnvironment:y,envName:f,testName:h.name}),le=await ii.init({driver:ge.driver,generator:i,logger:K,limbarClient:ge.limbarClient,playwrightDevice:ge.playwrightDevice,orgId:e,adbPort:ge.adbPort,options:{emulator:{...E,browserSettings:g.config.browser}},aiSettings:b,fixtures:{storage:a,browserEnricher:l,browserGenerator:u,localCodeEvalTools:d,testContext:ue}}),He;try{He=await ol({platform:"ANDROID",containerName:`android test ${h.name}`,fixtures:{controller:le,logger:K,cacheStorage:s,usageTracker:c},work:{state:{failureRecoveryDisabled:b.failureRecovery===!1,failureRecoveryAttempts:0}},inputs:{testName:h.name,steps:h.steps,orgId:e,testMetadata:h},tracer:U,callbacks:{}})}finally{await W(),await ge.cleanup(),await le.cleanup()}await U.finish({logger:K,results:He.results,status:He.status,assetDetails:{avdId:"avdId"in D?D.avdId:void 0,tag:"apkToInstall"in D?D.apkToInstall?.tag:void 0,channel:"apkToInstall"in D?D.apkToInstall?.channel:void 0}});let ve;if(He.status==="FAILED"&&He.terminalResult){let q=He.terminalResult.message;q?ve=R.fromMessage(q):ve=new R("UnknownError",q||"Unknown failure")}return{...He,error:ve}}import{randomUUID as d6}from"crypto";import{remote as VJ}from"webdriverio";var ag="NATIVE_APP";var sg=class{constructor(e){this.driver=e}async executeWebViewScript(e,t,...n){return this.executeInContext(e,async o=>{let i=new Function("...args",`${tu.safariUtilsLibJs}; const userFn = ${t.toString()}; return userFn(momenticFunctions, ...args);`);return o.execute(i,...n)})}async executeInNativeContext(e){return this.executeInContext(ag,e)}async executeInContext(e,t){return await this.driver.switchContext(e),await t(this.driver)}};import{createInstanceClient as WJ}from"@limrun/api/ios-client";import{hostname as jJ}from"os";async function CD(r){let{apiClient:e,logger:t,creationOpts:n,logLevel:o,orgId:i,sessionId:a,onConnectionStateChange:s}=r,{token:c,webRtcUrl:l,wdaUrl:u,apiUrl:d,id:p,region:m}=await e.createIosEmulator({...n,hostname:jJ(),sessionId:a});t.info({emulatorName:p,region:m,sessionId:a},"ios instance creation ok");let g=await nt.recordDuration({fn:async()=>await WJ({apiUrl:d,token:c,logLevel:o}),name:"test_event_duration",tags:["name:limbar-client-creation","clientOs:ios",`orgId:${i}`]});return s&&g.onConnectionStateChange(s),{close:()=>{g.disconnect()},limbarToken:c,limbarWebRtcUrl:l,limbarApiUrl:d,limbarWdaUrl:u,emulatorName:p,limbarClient:g}}async function xD({wdaUrl:r,token:e}){try{let t=new AbortController;return setTimeout(()=>t.abort(),3e3),await fetch(r+"/status",{headers:{Authorization:`Bearer ${e}`},signal:t.signal}),!0}catch{return!1}}async function _D({creationOpts:r,apiClient:e,logger:t,driverLogLevel:n,appiumPort:o,orgId:i,sessionId:a,callbacks:s}){let c=Date.now();t.info("Starting ios driver creation");let{onLimbarConnectionStateChange:l}=s,u=[],d=await CD({apiClient:e,logger:t,creationOpts:r,orgId:i,sessionId:a,onConnectionStateChange:l}),p=d.emulatorName;u.push(()=>e.deleteIosEmulator(p),d.close);let m=async()=>{for(let g=u.length-1;g>=0;g-=1)try{await u[g]()}catch(h){if(h instanceof Error&&["ECONNREFUSED","ECONNRESET","UND_ERR_CLOSED"].some(f=>h.message.includes(f)))continue;t.warn({err:h},"Error running cleanup task")}};try{let g=await $J({logger:t,driverLogLevel:n,appiumPort:o,emulatorStart:c,emulatorCreationParams:d,apiClient:e,creationOpts:r,orgId:i,sessionId:a,callbacks:s});return u.push(g.appiumClose),u.push(async()=>g.driver.deleteSession()),g.driver.getPageSource().catch(()=>{}),{...d,...g,driver:new sg(g.driver),cleanup:m,appiumPort:o}}catch(g){throw await m(),new Error(`Failed to start Appium driver: ${g}`)}}async function $J({logger:r,driverLogLevel:e="warn",emulatorStart:t,appiumPort:n,emulatorCreationParams:o,callbacks:{onStatusUpdate:i,onLimbarConnectionStateChange:a}}){let s=[],{emulatorName:c,limbarWdaUrl:l,limbarApiUrl:u,limbarToken:d,limbarClient:p}=o,m=Date.now(),{close:g,logFile:h}=await qc({logger:r,logLevel:e,appiumPort:n});await xD({wdaUrl:l,token:d})||(r.debug({emulatorName:c},"WDA is not running on the Limbar iOS emulator"),await p.simctl(["launch","booted","com.facebook.WebDriverAgentRunner.xctrunner"]).wait(),r.debug({emulatorName:c},"WDA launched"));let f={platformName:"iOS","appium:automationName":"XCUITest","appium:noReset":!0,"appium:fullReset":!1,"appium:webDriverAgentUrl":l,"appium:wdaLocalPort":443,"appium:useNewWDA":!1,"appium:usePreinstalledWDA":!0,"appium:newCommandTimeout":3600,"appium:autoWebview":!1,"appium:webviewConnectTimeout":500,"appium:webviewConnectRetries":5,"appium:includeSafariInWebviews":!0,"appium:fullContextList":!1,"appium:additionalWebviewBundleIds":["*"],"appium:waitForQuiescence":!1,"appium:settings":{customSnapshotTimeout:0},"appium:limInstanceApiUrl":u,"appium:limInstanceToken":d,"appium:wdaRequestHeaders":{Authorization:`Bearer ${d}`}},y=Date.now(),E=await VJ({capabilities:f,hostname:"localhost",port:n,path:"/",protocol:"http",logLevel:e}),b=new Map;return E.on("command",M=>{b.set(M.command,Date.now())}),E.on("result",M=>{let O=b.get(M.command);if(!O)return;let v=Date.now()-O;M.result instanceof Error?r.warn({err:M.result,command:M.command,args:M.body,durationMs:v},"Appium cmd failed"):v>1e4&&r.warn({command:M.command,args:M.body,durationMs:v},"Appium cmd took very long"),b.delete(M.command)}),r.info({timings:{emulatorDuration:m-t,appiumDuration:y-m,wdioDuration:Date.now()-y},capabilities:f,emulatorName:c},"Started Appium driver"),{onStatusUpdate:i,driver:E,appiumClose:async()=>{await g(),await Promise.all(s.map(M=>M()))},appiumPort:n,appiumLogFile:h,emulatorName:c}}import{createHash as s6}from"crypto";import l6 from"jpeg-js";import{PNG as kD}from"pngjs";import e6 from"@prettier/plugin-xml";import t6 from"prettier";import{DOMParser as r6,XMLSerializer as n6}from"slimdom";import{reduce as qJ}from"lodash-es";var KJ=new Set(["id","processId","bundleId","type","accessible","index","x","y","width","height"]),YJ=new Set([]),XJ=new Set(["name","label","traits"]),JJ=new Set(["live-region","drawing-order"]),ZJ=new Set(["visible","enabled"]);function MD(r){let e={},t=r.tagName,n=qJ(r.attributes,(o,i)=>(o[i.name]=i.value,o),{});for(let[o,i]of Object.entries(n))KJ.has(o)||o==="class"&&t===i||o==="focusable"&&i==="true"&&n.clickable==="true"||YJ.has(o)&&i==="false"||XJ.has(o)&&i===""||ZJ.has(o)&&i==="true"||JJ.has(o)&&i==="0"||(e[o]=i);return e.name&&e.label&&e.name===e.label&&delete e.label,e.name&&e.value&&e.name===e.value&&delete e.value,e}function lg(r){let e=r.getAttribute("x"),t=r.getAttribute("y"),n=r.getAttribute("width"),o=r.getAttribute("height");if(e===null||t===null||n===null||o===null)return;let i=parseFloat(e),a=parseFloat(t),s=parseFloat(n),c=parseFloat(o);if(!(isNaN(i)||isNaN(a)||isNaN(s)||isNaN(c)))return[i,a,i+s,a+c]}function Zb(r,e){let[t,n,o,i]=e;r.setAttribute("bounds",`[${t}, ${n}, ${o}, ${i}]`)}function QJ(r){let e=r.match(/\[\s*([-\d.]+)\s*,\s*([-\d.]+)\s*,\s*([-\d.]+)\s*,\s*([-\d.]+)\s*\]/);if(!e)return;let t=parseFloat(e[1]),n=parseFloat(e[2]),o=parseFloat(e[3]),i=parseFloat(e[4]);if(!(isNaN(t)||isNaN(n)||isNaN(o)||isNaN(i)||o<t||i<n))return[t,n,o,i]}function PD(r){let e=r.getAttribute("bounds");if(e)return QJ(e)}function ID(r,e){if(!e)return!0;let t=lg(r);return t?Qb(t,e):!0}function Qb(r,e){if(!e)return!0;let[t,n,o,i]=r;return!(o<e.left||t>e.right||i<e.top||n>e.bottom)}var OD=new Set(["XCUIElementTypeWebView"]);function o6(r){if(OD.has(r.tagName))return!0;let e=r.getAttribute("name");if(e&&(e.startsWith("TabDocument")||e.startsWith("BrowserView"))){let t=e.match(/UUID=([A-F0-9-]+)/),n=e.match(/WebViewProcessID=(\d+)/);if(t&&n)return!0}return!1}function i6(r){let e=["android.widget.","android.view.","android.webkit.","android.app.","android.support.","androidx.","com.android.inputmethod."];for(let t of e)if(r.startsWith(t))return r.substring(t.length);return r}function eE(r,e){let{idCounter:t,idToElement:n}=r,o=t.value++;e.setAttribute("id",String(o)),n.set(o,e)}function tE(r){if(OD.has(r.tagName))return r.children.length>0?tE(r.children[0]):void 0;if(r.tagName==="XCUIElementTypeOther"&&r.hasAttribute("name")&&r.hasAttribute("label"))return lg(r);if(r.children.length===1){let e=r.children[0];return tE(e)}}function LD(r,e,t,n){let{document:o}=t,{parentFrameBounds:i,pruneElementsOutsideBounds:a}=n;if(e.type==="element"){let s=o.createElement(e.role||e.tag);if(e.name&&s.setAttribute("name",e.name),e.description&&s.setAttribute("description",e.description),e.classes&&e.classes.length>0&&s.setAttribute("classes",e.classes.join(" ")),e.attrs)for(let[u,d]of Object.entries(e.attrs))s.setAttribute(u,d);let c=e.boundingRect,l=[i[0]+c.x,i[1]+c.y,i[0]+c.x+c.width,i[1]+c.y+c.height];if(!Qb(l,a))return;Zb(s,l),eE(t,s),r.appendChild(s);for(let u of e.children)LD(s,u,t,n)}else if(e.type==="text"){let s=o.createElement("text");eE(t,s),r.appendChild(s);let c=o.createTextNode(e.text);s.appendChild(c)}}function ND(r,e,t,n){let{pruneElementsOutsideBounds:o}=n,{document:i}=t;eE(t,e);let a=MD(r);for(let[l,u]of Object.entries(a))e.setAttribute(l,u);let s=lg(r);if(s&&Zb(e,s),o6(r)){let{removeWebviewContent:l,injectedWebviewContent:u}=n;if(l)return;if(u){let d=tE(r);if(d){LD(e,u,t,{parentFrameBounds:d,pruneElementsOutsideBounds:o});return}}}let c=Array.from(r.childNodes??[]);for(let l of c){let u=l.nodeType;if(u===3){let d=l.nodeValue;d&&d.trim().length>0&&e.appendChild(i.createTextNode(d));continue}if(u===1){let d=l;if(!ID(d,o))continue;let p=i.createElement(i6(d.tagName));ND(d,p,t,n),e.appendChild(p)}}}async function a6(r,e,t){let n=r.parseFromString("<AppiumAUT/>","text/xml"),o=new Map,i={document:n,idToElement:o,idCounter:{value:0}},a=n.documentElement;ND(e,a,i,t);let s=new n6().serializeToString(n),c=await t6.format(s,{parser:"xml",plugins:[e6],printWidth:120,tabWidth:1,singleAttributePerLine:!1});return{prunedDocument:n,idToElement:o,prunedXml:c}}async function DD(r,e){let t=new r6,o=t.parseFromString(r,"text/xml").documentElement;if(!o)throw new Error("No root element found in XML");if(o.tagName!=="AppiumAUT")throw new Error("No AppiumAUT element found in XML");let{prunedXml:i,idToElement:a,prunedDocument:s}=await a6(t,o,e);return{xml:i,idToElement:a,document:s}}var cg=class r{driver;limbarClient;orgId;options;aborter;constructor({driver:e,limbarClient:t,orgId:n,options:o,aborter:i}){this.driver=e,this.limbarClient=t,this.orgId=n,this.options=o,this.aborter=i}static async init({driver:e,limbarClient:t,orgId:n,options:o,aborter:i}){return new r({driver:e,orgId:n,options:o,aborter:i,limbarClient:t})}async getContexts(){let e=await this.driver.executeInNativeContext(async n=>await n.getContexts({})),t=e.filter(n=>n!==ag);return{contexts:e.map(n=>n),webviews:t}}async getRawScreenshotBase64(e,t=2){let n=se(),o;for(let i=0;i<t;i++)try{return await n.startAsyncSpan("EMULATOR_READ_STATE",async()=>{let a=await this.limbarClient.screenshot(),s=Buffer.from(a.base64,"base64"),c=l6.decode(s),l=new kD({width:c.width,height:c.height});return l.data=Buffer.from(c.data),kD.sync.write(l).toString("base64")},{name:"Take screenshot",signal:this.aborter.controller?.signal,timeoutMs:3e3})}catch(a){if(o=a,e.warn({err:a},"Failed to take screenshot"),i===t-1)throw a}throw new R("InternalWebAgentError",`Failed to take screenshot: ${o}`)}async getCurrentScreenshotPngString(e){return`data:image/png;base64,${await this.getRawScreenshotBase64(e,1)}`}async waitForScreenshotStability({logger:e,timeoutMs:t,signal:n,reason:o,tolerancePercent:i=1}){let a=Date.now(),s,c=!1;for(;Date.now()-a<t;){if(n?.throwIfAborted(),!s){s=await this.getRawScreenshotBase64(e);continue}let l=await this.getRawScreenshotBase64(e);if(Ms(s,l)<=i){c=!0;break}s=l,await J(250,n)}c||e.warn({purpose:o},"Timed out waiting for screenshot stability")}async waitForPageSourceStability({logger:e,timeoutMs:t,signal:n,reason:o}){await se().startAsyncSpan("WAIT_FOR_PAGE_STABILITY",async i=>{i.attributes.reason=o;let a=Date.now(),s,c,l=!1;for(;Date.now()-a<t;){c&&c<250&&await J(250-c,n),n?.throwIfAborted();let u=Date.now(),d;try{d=await this.limbarClient.elementTree()}catch(m){e.warn({err:m},"Failed to get page source during stability wait"),c=Date.now()-u;continue}let p=s6("md5").update(d).digest("hex");if(c=Date.now()-u,s&&s===p){l=!0;break}s=p}l||(i.attributes.timedOut=!0,e.warn({purpose:o},"Timed out waiting for page source stability"))})}async getActiveWebview(){let t=(await this.getContexts()).webviews;if(t.length>1)throw new R("UserInfrastructureError","Multiple active webviews in a single package is currently not supported");return t[0]}async getActiveWebviewContent(){let e=await this.getActiveWebview();if(!e)return;this.throwIfAborted();let t=await this.driver.executeWebViewScript(e,n=>n.dumpA11yTree());if(t)return JSON.parse(t)}async getDomState(e,t){let o=t?.filterOffscreenElements??!0?await this.getViewportBounds():void 0,i=await this.getPageSource();this.throwIfAborted();let a;if(!t?.skipFetchingFullWebviewContent)try{a=await this.getActiveWebviewContent()}catch(c){e.error({err:c},"Could not get webview info to get the nested DOM state")}return this.throwIfAborted(),{graph:await DD(i,{injectedWebviewContent:a,removeWebviewContent:t?.removeWebviewContent,pruneElementsOutsideBounds:o})}}async getPageSource(){return await se().startAsyncSpan("EMULATOR_READ_STATE",()=>this.driver.executeInNativeContext(async n=>n.getPageSource()),{name:"Get iOS page source",signal:this.aborter.controller?.signal})}async getViewportBounds(){let e=await this.driver.executeInNativeContext(async t=>t.getWindowRect());return{left:e.x,top:e.y,right:e.x+e.width,bottom:e.y+e.height}}throwIfAborted(){this.aborter.controller?.signal.throwIfAborted()}};function FD({aiResponse:r,description:e,emulatorState:t}){let n=t.graph.idToElement.get(r.id);if(!n)throw new Error(`Could not find node with id: ${r.id}`);let o=PD(n);if(!o)throw new Error(`Could not determine bounds for element with id: ${r.id}, description: ${e}`);return{target:{type:"NATIVE",bounds:o},resolvedNode:n}}var Jn=class{limbarClient;driver;stateManager;generator;fixtures;orgId;aiSettings;aborter;constructor(e){this.stateManager=e.stateManager,this.driver=e.driver,this.limbarClient=e.limbarClient,this.aborter=e.aborter,this.fixtures=e.fixtures,this.orgId=e.orgId,this.generator=e.generator,this.aiSettings=e.aiSettings}async findElement({logger:e,description:t,skipFetchingFullWebviewContent:n=!1,removeWebviewContent:o=!1,useMemory:i=!1,metadata:a}){let s=e.child({...a});await this.stateManager.waitForScreenshotStability({logger:e,timeoutMs:5e3,signal:this.aborter.controller?.signal,reason:"Waiting for stability before locating an element with AI"});let c=await this.stateManager.getDomState(e,{skipFetchingFullWebviewContent:n,removeWebviewContent:o}),l=await this.stateManager.getCurrentScreenshotPngString(e),u;try{u=await this.generator.getIosElementLocation({description:t,screenXml:c.graph.xml,screenshot:l},{logger:s,loggerTags:ye(s),abortSignal:this.aborter.controller?.signal,useMemory:i,agentConfigVersion:this.aiSettings.agentConfig?.["ios-locator"]})}catch(m){throw this.throwIfAborted(),s.error({err:m},"Failed to locate element"),new Error(`ActionFailureError: Failed to locate element: ${m instanceof Error?m.message:m}`)}if(u.id===-1)throw new R("NoMatchingElementError",u.thoughts??"No matching element found");let{target:d,resolvedNode:p}=FD({aiResponse:u,description:t,emulatorState:c});return{resolvedTarget:{...d,resolvedNode:p},thoughts:u.thoughts}}async wrapTargetingAction(e){let{logger:t,action:n,description:o,command:i,cacheIsInvalidAfterResolution:a,skipFetchingFullWebviewContent:s=!1,removeWebviewContent:c=!1}=e,l={commandId:i.id},u=!1,d;i.disableCache&&(t.debug({command:i},"Cache explicitly disabled for command"),u=!0,d=void 0),a&&(u=!0,d=void 0),d&&d?.resolvedDescription!==o&&(t.info({description:o,cacheDescription:d?.resolvedDescription},"Cache description mismatch, clearing it automatically"),u=!0,d=void 0),t.info({description:o,cacheBustedBeforeAction:u},"Prompting AI for a new element location");let p=await this.findElement({logger:t,description:o,skipFetchingFullWebviewContent:s,removeWebviewContent:c,metadata:l}),m=p.thoughts;return{result:await n(p.resolvedTarget),thoughts:m}}constructPerformerParams(){return{limbarClient:this.limbarClient,stateManager:this.stateManager,driver:this.driver,fixtures:this.fixtures,aborter:this.aborter,orgId:this.orgId,generator:this.generator,aiSettings:this.aiSettings}}throwIfAborted(){this.aborter.controller?.signal.throwIfAborted()}get abortSignal(){return this.aborter.controller?.signal}};var ug=class extends Jn{async doPress({name:e,longPress:t}){return this.driver.executeInNativeContext(n=>n.executeScript("mobile: pressButton",[{name:e,isLongPress:t}]))}};function c6(r){let e={relativePosition:r.relativePosition};if(r.doubleTap&&r.longPress)throw new Error("UserConfigurationError: Cannot specify both doubleTap and longPress");return r.doubleTap?{...e,doubleTap:!0,doubleTapDelayMs:r.doubleTapDelayMs}:r.longPress?{...e,longPress:!0,longPressDurationMs:r.longPressDurationMs}:e}var cl=class extends Jn{async tapOnAbsoluteCoordinates(e,t){let n=t.x,o=t.y;if(e.info({x:n,y:o},"Tap at coordinates"),t.longPress){let i=t.longPressDurationMs??2e3;await this.driver.executeInNativeContext(a=>a.tap({x:n,y:o,duration:i}));return}if(t.doubleTap){await this.driver.executeInNativeContext(a=>a.tap({x:n,y:o}));let i=t.doubleTapDelayMs??100;await new Promise(a=>setTimeout(a,i))}await this.driver.executeInNativeContext(i=>i.tap({x:n,y:o}))}async tapOnNativeTarget(e,t,n){let[o,i,a,s]=t.bounds,c=a-o,l=s-i,u=n?.relativePosition?.x??c/2,d=n?.relativePosition?.y??l/2;u=Math.max(0,Math.min(u,c)),d=Math.max(0,Math.min(d,l));let p=o+u,m=i+d;return await this.tapOnAbsoluteCoordinates(e,{x:p,y:m,...n}),{x:p,y:m}}async tapOnTarget({logger:e,target:t,options:n}){if("type"in t&&t.type==="NATIVE")await this.tapOnNativeTarget(e,t,n);else throw new Error("Not implemented yet")}async executeTap({logger:e,command:t}){let n=c6(t);if(t.target.type==="coordinates"){let a=await this.driver.executeInNativeContext(async l=>l.getWindowSize()),s=t.target.xPercent*a.width,c=t.target.yPercent*a.height;return await this.tapOnAbsoluteCoordinates(e,{...n,x:s,y:c}),{success:!0,message:`Tapped at ${s}, ${c}`}}let o=t.target.description,{thoughts:i}=await this.wrapTargetingAction({logger:e,command:t,action:a=>this.tapOnTarget({logger:e,target:a,options:n}),description:o});return{success:!0,message:i}}};var u6=25,dg=class extends Jn{async doType(e,t){if(!t.target){if(t.clearContent)throw new Error("UserConfigurationError: clearing content is only supported when a target is provided to the Type step");return await this.stateManager.waitForScreenshotStability({logger:e,timeoutMs:3e3,signal:this.aborter.controller?.signal,reason:"Waiting for page to stabilize before typing"}),await this.sendKeys(t),{success:!0,message:"Successfully executed type action"}}if(t.target.type!=="description")throw new Error("UserConfigurationError: x/y targets are not supported for the Type step");let{thoughts:n}=await this.wrapTargetingAction({logger:e,command:t,action:async o=>{if("type"in o&&o.type==="NATIVE")await this.doNativeType(e,t,o);else throw new Error("UserConfigurationError: Webview targets are not supported for the Type step on iOS devices")},description:t.target.description});return{success:!0,message:n}}async doNativeType(e,t,n){let o=new cl(this.constructPerformerParams());t.clearContent?(await o.tapOnNativeTarget(e,n,{longPress:!0}),await this.clearContent()):await o.tapOnNativeTarget(e,n),await this.stateManager.waitForScreenshotStability({logger:e,timeoutMs:3e3,signal:this.aborter.controller?.signal,reason:"Waiting for keyboard to appear before typing"}),await this.sendKeys(t)}async sendKeys(e){let t=e.keyPressDelayMs??u6,n=Date.now();for(;Date.now()-n<3e3&&(this.throwIfAborted(),!await this.driver.executeInNativeContext(o=>o.isKeyboardShown()));)await new Promise(o=>setTimeout(o,500));t?await this.driver.executeInNativeContext(async o=>{await o.updateSettings({keyInjectionDelay:t}),await o.keys(e.text),await o.updateSettings({keyInjectionDelay:0})}):await this.driver.executeInNativeContext(async o=>{await o.keys(e.text)})}async clearContent(){await this.clearContentHelper()}async clearContentHelper(){}};var mg=class r extends Jn{emulatorSettings;logger;constructor(e){super(e),this.logger=e.logger,this.emulatorSettings=e.emulatorSettings}static async init({driver:e,logger:t,fixtures:n,orgId:o,options:i,abortController:a,limbarClient:s,generator:c,aiSettings:l}){let u={controller:a},d=i?.emulator??{},p=await cg.init({driver:e,orgId:o,limbarClient:s,options:d,aborter:u}),m=new r({generator:c,aiSettings:l,limbarClient:s,driver:e,stateManager:p,logger:t,fixtures:n,aborter:u,orgId:o,emulatorSettings:d});return await m.initializeSettings(),m}async executeCommand(e){let t=["type","a11yData","thoughts","cache","code"],n;try{n=await Ps({obj:e.command,context:this.fixtures.testContext,bannedKeys:t,orgId:this.orgId,logger:this.logger,signal:this.abortSignal,localTools:this.fixtures.localCodeEvalTools})}catch(o){throw this.throwIfAborted(),new Error(`ActionFailureError: Failed to substitute template strings in command: ${o.message}`,{cause:o})}try{return await this.executeCommandHelper(e)}catch(o){throw o.name!=="AbortError"&&this.logger.error({err:o},"Error thrown in action controller"),o}finally{Is(e.command,n)}}async executeCommandHelper({command:e}){let t=se();switch(e.type){case"TAP":return new cl(this.constructPerformerParams()).executeTap({logger:this.logger,command:e});case"TYPE":return new dg(this.constructPerformerParams()).doType(this.logger,e);case"STATE":{let n=await this.stateManager.getDomState(this.logger),o=await this.stateManager.getContexts();return{output:{xml:n.graph.xml,contexts:o},success:!0}}case"OPEN_APP":return await this.limbarClient.launchApp(e.packageName),{success:!0};case"PRESS":{let n=new ug(this.constructPerformerParams());switch(e.key){case"HOME":await n.doPress({name:"home"});break;case"POWER":await this.driver.executeInNativeContext(o=>o.isLocked())?await this.driver.executeInNativeContext(o=>o.unlock()):await this.driver.executeInNativeContext(o=>o.lock());break}return{success:!0}}case"AI_CHECK":{let o=e.timeoutSecs?e.timeoutSecs*1e3:5e3,i=Hm(o),a=Date.now(),s=0,c,l=!1,u;for(;s<15&&!l;){this.throwIfAborted(),l||c&&c-a>=o&&(l=!0),s!==0&&await J(i,this.abortSignal),c=Date.now();try{let d="",p="";await t.startAsyncSpan("EMULATOR_READ_STATE",async()=>{d=await this.getEmulatorDomState(),p=await this.getScreenshotBase64()},{name:"Get emulator state"});let m=await this.generator.evaluateIosAssertion({assertion:e.assertion,screenXml:d,screenshot:p},{logger:this.logger,loggerTags:ye(this.logger),agentConfigVersion:this.aiSettings.agentConfig?.["ios-assertion"]});if(m.result)return{success:m.result,message:m.thoughts};{let g=`AssertionFailureError: ${m.thoughts}`;u=new Error(g)}}catch(d){this.throwIfAborted(),this.logger.info({err:d},`AI check assert attempt ${s} failed, retrying...`),u=d instanceof Error?d:new Error(`${d}`)}finally{s++}}return{success:!1,message:u?.message}}default:throw new Error(`Unsupported mobile command type: ${e.type}`)}}async getMobileFailureRecoveryPlan(e){return{thoughts:"Failure recovery is not yet supported for iOS.",scenario:"INELIGIBLE",instructions:void 0}}async waitForPageSourceStability(e){return this.stateManager.waitForPageSourceStability({logger:this.logger,timeoutMs:e.timeoutMs??5e3,reason:e.reason,signal:this.aborter.controller?.signal})}async listInstalledApps(){let e=await this.driver.executeInNativeContext(n=>n.execute("mobile: listApps"));return Object.keys(e).filter(n=>!n.startsWith("com.apple.")&&!n.startsWith("io.appium"))}async initializeSettings(){}async getScreenshotBase64(){return this.stateManager.getRawScreenshotBase64(this.logger)}async getScreenshotPngString(){return this.stateManager.getCurrentScreenshotPngString(this.logger)}async getEmulatorDomState(){return(await this.stateManager.getDomState(this.logger)).graph.xml}async getViewportBounds(){return this.stateManager.getViewportBounds()}async waitForScreenshotStability(e){return this.stateManager.waitForScreenshotStability({logger:this.logger,timeoutMs:e.timeoutMs??5e3,reason:e.reason,signal:this.aborter.controller?.signal})}resetAbortController(e){this.aborter.controller=e??new AbortController}isAborted(){return this.aborter.controller?.signal.aborted}abort(){this.aborter.controller?.abort()}async cleanup(){}get abortSignal(){return this.aborter.controller?.signal}get context(){return this.fixtures.testContext}get localCodeEvalTools(){return this.fixtures.localCodeEvalTools}};import m6 from"zod";async function UD({runTracer:r,metadata:{orgId:e,runId:t},fixtures:{logger:n,apiClient:o,mobileGenerator:i,storage:a,cacheStorage:s,usageTracker:c,browserEnricher:l,browserGenerator:u,localCodeEvalTools:d},inputs:{project:p,testDefinition:m},env:{envName:g,envVariables:h},settings:{emulatorSettings:f,aiSettings:y},options:{logLevel:E,region:b}}){let _=Math.floor(Math.random()*1e4)+4e4,M=await Yo(_,"appium"),O=es.or(m6.literal(Au)).optional().parse(b??f.region);if(O==="local")throw new Error("Local region is not supported for iOS tests, as we do not support local iOS emulators.");let C={region:O==="closest"?void 0:O},F=d6(),I=n.child({runAttemptId:F}),B;try{B=await _D({apiClient:o,logger:n,driverLogLevel:E,creationOpts:C,callbacks:{onStatusUpdate:W=>{n.debug({status:W},"Emulator status update")},onLimbarConnectionStateChange:W=>{W==="disconnected"?P.warn("Emulator websocket connection lost. Emulator may be unavailable."):(W==="reconnecting"||W==="connecting")&&P.info("Emulator websocket is reconnecting...")}},appiumPort:M,orgId:e,sessionId:F})}catch(W){let ue=`Fatal error creating iOS driver, failing test run attempt (runId: ${t})`;return n.error({err:W},ue),P.error({err:W},ue),{status:"FAILED",results:[],error:new R("UserConfigurationError",`Fatal error creating iOS driver: ${W.message}`)}}let D=await r.startAttempt({emulatorName:B.emulatorName,runAttemptId:F});I=I.child(D.loggerBindings||{});let ee=new No({variablesFromEnvironment:h,envName:g,testName:m.name}),K=await mg.init({driver:B.driver,generator:i,logger:I,limbarClient:B.limbarClient,orgId:e,options:{emulator:{...f,browserSettings:p.config.browser}},aiSettings:y,fixtures:{storage:a,browserEnricher:l,browserGenerator:u,localCodeEvalTools:d,testContext:ee}}),ge;try{ge=await ol({platform:"IOS",containerName:`ios test ${m.name}`,fixtures:{controller:K,logger:I,cacheStorage:s,usageTracker:c},work:{state:{failureRecoveryDisabled:y.failureRecovery===!1,failureRecoveryAttempts:0}},inputs:{testName:m.name,steps:m.steps,orgId:e,testMetadata:m},tracer:D,callbacks:{}})}finally{await B.cleanup(),await K.cleanup()}await D.finish({logger:I,results:ge.results,status:ge.status});let U;if(ge.status==="FAILED"&&ge.terminalResult){let W=ge.terminalResult.message;W?U=R.fromMessage(W):U=new R("UnknownError",W||"Unknown failure")}return{...ge,error:U}}import{cloneDeep as p6}from"lodash-es";import{debounce as g6}from"ts-debounce";var Cu="0.33.4";function h6(r){switch(r){case"PASSED":return"SUCCESS";case"FAILED":return"FAILED";case"CANCELLED":return"CANCELLED";case"RUNNING":case"PENDING":case"RETRYING":case"WAITING_FOR_USER":return"RUNNING"}}function f6(r){switch(r){case"SUCCESS":return"PASSED";case"FAILED":return"FAILED";case"CANCELLED":return"CANCELLED";case"RUNNING":return"RUNNING";case"IDLE":return"PENDING"}}var nE=class{constructor(e,t,n,o,i,a){this.keepalive=e;this.testId=t;this.testName=n;this.diskStorage=o;this.parentTracer=i;this.orgId=a;this.interactionTracer=new Jo,rn.initializeRootTracerContext(this.interactionTracer)}children=[];finished=!1;interactionTracer;getParentStepIdChain(){return[]}recordStepDuration(e){let{durationMs:t,step:n}=e,o=n.type!=="MOBILE_PRESET_STEP"?n.type:n.command.type;nt.distribution("test_step_duration",t,[`type:${o}`,"platform:mobile","executor:cli",`orgId:${this.orgId}`])}attachBeforeScreenshot(e){let{snapshotId:t,screenshot:n}=e;this.diskStorage.storeFile({name:`${zo}/${t}.jpeg`,contents:n})}attachAfterScreenshot(e){let{snapshotId:t,screenshot:n}=e;this.diskStorage.storeFile({name:`${zo}/${t}.jpeg`,contents:n})}attachBeforeXmlSnapshot(e){let{snapshotId:t,xml:n}=e;this.diskStorage.storeFile({name:`${zo}/${t}.xml`,contents:n})}attachAfterXmlSnapshot(e){let{snapshotId:t,xml:n}=e;this.diskStorage.storeFile({name:`${zo}/${t}.xml`,contents:n})}async finishInternal(e){this.finished||(this.finished=!0,this.interactionTracer.finish(),await Promise.all(this.children.map(t=>t.finish({status:f6(e.status),finishedAt:e.finishedAt}))))}async finish(e){return await this.finishInternal({status:e.result.status,finishedAt:new Date(e.result.endTime)}),{trace:this.interactionTracer.getRootSpan()}}async startSubSteps(){let e=new ul(this.keepalive,this.testId,this.testName,this.diskStorage,this.orgId);return this.children.push(e),e}},ul=class{constructor(e,t,n,o,i){this.keepalive=e;this.testId=t;this.testName=n;this.diskStorage=o;this.orgId=i}children=[];finished=!1;async getScreenshot(e){return this.diskStorage.readFile(`${zo}/${e}.jpeg`)}getParentStepIdChain(){return[]}async startStep(e){this.keepalive();let t=new nE(this.keepalive,this.testId,this.testName,this.diskStorage,this,this.orgId);return this.children.push(t),t}async finish(e){this.finished||(this.finished=!0,await Promise.all(this.children.map(t=>t.finishInternal({status:h6(e.status),finishedAt:e.finishedAt}))))}},oE=class{constructor(e,t,n,o,i,a,s){this.keepalive=e;this.testId=t;this.testName=n;this.runAttemptId=o;this.metadata=i;this.diskStorage=a;this.orgId=s;this.diskStorage.mkdir("assets"),this.logStream=this.diskStorage.createFileStream("assets/logs.logcat"),this.resourceUsageStream=this.diskStorage.createFileStream(`${zo}/resource-usage.ndjson`),this.resourceUsageSampler=vw({keepSamples:!1,onSample:c=>{this.resourceUsageStream.write(`${JSON.stringify(c)}
|
|
4660
|
+
`),r.forEach(m=>{if(!Bb.existsSync(m))throw new Error(`Path '${m}' does not exist.`);let g,h;try{g=Bb.statSync(m),h=g.isDirectory()}catch(y){s.warn({err:y},`Skipping path ${m} because it cannot be read`);return}let f=ng.resolve(m);Object.values(e.mobileTests).filter(y=>h?y.fullFilePath.startsWith(f):y.fullFilePath===f).forEach(y=>{l.add(y.fullFilePath)})})):(s.info("The arguments provided don't appear to be valid paths. Treating them as substrings instead... "),Object.values(e.mobileTests).forEach(m=>{r.some(g=>m.relativePath.includes(g))&&l.add(m.fullFilePath)}))}else{!n&&!await Rm("No test paths or substrings were provided. Do you want to run all tests?")&&(s.error("Cancelled by user."),process.exit(1));let d=Object.values(e.mobileTests);s.info(`Reading all ${d.length} mobile tests in the project from local disk.`),d.forEach(p=>{l.add(p.fullFilePath)})}for(let d of Array.from(l)){let p=ng.relative(t.rootDir,d);o&&!o.some(m=>new RegExp(m).test(p))&&l.delete(d),i&&i.some(m=>new RegExp(m).test(p))&&l.delete(d)}return(await Promise.all(Array.from(l).map(async d=>{try{let p=ng.relative(t.rootDir,d),m=await So(d,s,e),g=ng.basename(d,".test.yaml");if(m.disabled)return null;if(a&&a.length>0){let f=m.labels||[];if(!a.some(E=>f.includes(E)))return null}let h={id:m.id,name:g,description:m.description,schemaVersion:m.schemaVersion,settings:m.settings,fullFilePath:d,relativeFilePath:p,quarantined:!!c[m.id],quarantinedMetadata:c[m.id],labels:m.labels};switch(m.platform){case"ANDROID":return{...h,platform:"ANDROID",steps:m.steps};case"IOS":return{...h,platform:"IOS",steps:m.steps};default:return(y=>{throw new Error("You missed a case in the switch above")})(m)}}catch(p){s.error(`Failed to read and resolve mobile test at '${d}': ${p}`),process.exit(1)}}))).filter(d=>!!d)}import{InvalidArgumentError as og,Option as Qe}from"@commander-js/extra-typings";import{z as FJ}from"zod";var lD=58890;function ll(r){let e=parseInt(r,10);if(isNaN(e))throw new og("Not a number.");return e}var ba=new Qe("--api-key <key>","Momentic API key").env("MOMENTIC_API_KEY").argParser(r=>{if(!r)throw new og("API key is required.");return r}).makeOptionMandatory(),ig=new Qe("-c, --config <configPath>","Absolute or relative path to a Momentic configuration file."),Hb=new Qe("-f, --filter <filter>","Run tests within the project that has a name equal to the filter provided. This option cannot be used together with file path or directory arguments, but substring matches are allowed."),Ea=new Qe("--server <server>","Momentic server to use.").env("MOMENTIC_SERVER").default("https://api.momentic.ai").argParser(r=>{try{return FJ.string().url().parse(r),r}catch{throw new og("Not a valid URL.")}}),Gb=new Qe("-y, --yes","Skip all confirmation prompts.").env("CI"),Wb=new Qe("--regenerate-cache","Regenerate all caches by starting from an empty cache state. This flag is useful for completely regenerating caches after changing configuration options. Warning: using this option will cause all steps to run without any cached data, resulting in significantly longer execution times."),jb=new Qe("--save-cache","Always save updated step caches after successful test runs. By default, caches are not saved when running on protected branches.").env("CI"),Vb=new Qe("--disable-cache","Disable using step caches completely. Using this option may lead to non-deterministic behavior and significantly longer runtimes.").implies({saveCache:!1}),$b=new Qe("--tag <tag>","Tag identifier for the asset."),cD=new Qe("--channel <channel>","Channel name for the asset."),qb=new Qe("--channel <channel>","Channel name for the asset.").makeOptionMandatory(),uD=new Qe("--tag <tag>","Tag identifier for the asset.").makeOptionMandatory(),dD=new Qe("--env <env>","Environment to run all tests in (overrides test-level configuration)."),Au="closest",mD=new Qe("--region <region>",`Region to run all tests in (overrides all other configuration). Valid values: ${Object.values(Hi).join(", ")}, ${Au}, ${Object.values(Gi).join(", ")}.`),pD=new Qe("--local-avd-id <localAvdId>","Force tests to use a specific local Android Virtual Device (AVD) instead of remote emulators."),gD=new Qe("--local-apk-path <localApkPath>","Path to a local APK file to install when running tests with a local emulator. Overrides remote asset configuration."),hD=new Qe("-p, --parallel <parallel>","The number of tests to run in parallel. Defaults to 1.").argParser(ll),fD=new Qe("--shard-index <shardIndex>","The index of the shard to run tests for. Defaults to 1.").default(1).argParser(r=>{let e=ll(r);if(e<1)throw new og("Shard index must be greater than 0.");return e}),SD=new Qe("--shard-count <shardCount>","The number of shards that tests are being run on. Defaults to 1.").default(1).argParser(ll),Kb=new Qe("--output-dir <outputDir>","Output directory to store run artifacts such as screenshots, results, and logs."),Yb=new Qe("--include <includePatterns...>","Only include tests that match the provided regex patterns. Multiple patterns can be provided. The patterns will be matched against the test file paths and the pattern only needs to match a part of the path for the test to be included."),Xb=new Qe("--exclude <excludePatterns...>","The inverted version of --include: a test that matches any of the provided exclusion patterns will be excluded from running."),yD=new Qe("--upload-results","Upload test results to Momentic Cloud.").default(!1),Jb=new Qe("--log-level <logLevel>","Log level for Momentic and dependent services.").choices(["error","warn","info","debug"]),bD=new Qe("--ignore-quarantine","Run all tests even if they are quarantined. This is useful for validating that quarantined tests are fixed before moving them out of quarantine.").implies({skipQuarantined:!1,onlyQuarantined:!1}),ED=new Qe("--timeout-minutes <timeoutMinutes>","Maximum number of minutes to run tests before stopping. When the timeout is reached, tests will stop and current results will be printed.").argParser(ll),TD=new Qe("--reporter <reporter>","Output report files in a standardized format to a local directory.").choices(Object.values(zl)),vD=new Qe("--reporter-dir <reporterDir>","Output directory to store report files. Relative paths are resolved relative to the project root, which is defined by the detected momentic.config.yaml.").default("reports"),AD=new Qe("--name <name>","A name to associate with this run for easier identification in the Momentic dashboard.");import{randomUUID as x6}from"crypto";import{existsSync as _6}from"fs";import{dirname as S6}from"path";import{randomUUID as BJ}from"crypto";import{existsSync as zJ,statSync as HJ}from"fs";import RD from"path";import GJ from"zod";async function wD({runTracer:r,metadata:{orgId:e,runId:t},fixtures:{logger:n,apiClient:o,mobileGenerator:i,storage:a,cacheStorage:s,usageTracker:c,browserEnricher:l,browserGenerator:u,localCodeEvalTools:d},inputs:{channel:p,tag:m,project:g,testDefinition:h},env:{envName:f,envVariables:y},settings:{emulatorSettings:E,aiSettings:b},options:{logLevel:_,localAvdId:M,localApkPath:O,region:v}}){let C=Math.floor(Math.random()*1e4)+4e4,F=await Yo(C,"appium"),I=es.or(GJ.literal(Au)).optional().parse(v??E.region),B=I==="local",D;if(B){let q;if(O&&(q=RD.resolve(O),!zJ(q)||!HJ(q).isFile()))throw new Error(`Local APK path "${q}" does not exist. Provide a valid file path via --local-apk-path.`);let fe,it=h.settings?.defaultApkFilePath;if(it){let hi=it.trim();hi&&(fe=hi)}let Ae=typeof y[Mi]=="string"?y[Mi].trim():void 0,x=typeof y[Dl]=="string"?y[Dl].trim():void 0,ne;x&&(ne=RD.resolve(x));let pe=q??fe??ne,Ur=M??E.localEmulatorSettings?.avdId??Ae;if(!Ur)throw new Error(`An AVD ID is required when using a local region. Provide --local-avd-id, configure a default local AVD ID on the test's settings, or set the ${Mi} key on the environment.`);D={avdId:Ur,apkFilePath:pe}}else D={region:I==="closest"?void 0:I,apkToInstall:p?{channel:p,tag:m}:void 0,osVersion:E.remoteEmulatorSettings?.androidVersion??fA};let ee=BJ(),K=n.child({runAttemptId:ee}),ge;try{ge=await Pm({apiClient:o,logger:n,driverLogLevel:_,creationOpts:D,callbacks:{onStatusUpdate:q=>{n.debug({status:q},"Emulator status update")},onHeartbeatFailure:()=>{let q="Appium heartbeat connection lost \u2014 possible ADB tunnel/emulator failure";P.warn(q)},onHeartbeatRestored:()=>{let q="Appium heartbeat connection restored";P.info(q)},onLimbarConnectionStateChange:q=>{q==="disconnected"?P.warn("Emulator websocket connection lost. Emulator may be unavailable."):(q==="reconnecting"||q==="connecting")&&P.info("Emulator websocket is reconnecting...")}},appiumPort:F,orgId:e,sessionId:ee})}catch(q){let fe=`Fatal error creating Android driver, failing test run attempt (runId: ${t})`;return n.error({err:q},fe),P.error({err:q},fe),{status:"FAILED",results:[],error:new R("UserConfigurationError",`Fatal error creating Android driver: ${q.message}`)}}let U=await r.startAttempt({emulatorName:ge.emulatorName,runAttemptId:ee});K=K.child(U.loggerBindings||{});let W=await Om({driver:ge.driver,onLogs:q=>{U.appendLogs(q)}}),ue=new No({variablesFromEnvironment:y,envName:f,testName:h.name}),le=await ii.init({driver:ge.driver,generator:i,logger:K,limbarClient:ge.limbarClient,playwrightDevice:ge.playwrightDevice,orgId:e,adbPort:ge.adbPort,options:{emulator:{...E,browserSettings:g.config.browser}},aiSettings:b,fixtures:{storage:a,browserEnricher:l,browserGenerator:u,localCodeEvalTools:d,testContext:ue}}),He;try{He=await ol({platform:"ANDROID",containerName:`android test ${h.name}`,fixtures:{controller:le,logger:K,cacheStorage:s,usageTracker:c},work:{state:{failureRecoveryDisabled:b.failureRecovery===!1,failureRecoveryAttempts:0}},inputs:{testName:h.name,steps:h.steps,orgId:e,testMetadata:h},tracer:U,callbacks:{}})}finally{await W(),await ge.cleanup(),await le.cleanup()}await U.finish({logger:K,results:He.results,status:He.status,assetDetails:{avdId:"avdId"in D?D.avdId:void 0,tag:"apkToInstall"in D?D.apkToInstall?.tag:void 0,channel:"apkToInstall"in D?D.apkToInstall?.channel:void 0}});let ve;if(He.status==="FAILED"&&He.terminalResult){let q=He.terminalResult.message;q?ve=R.fromMessage(q):ve=new R("UnknownError",q||"Unknown failure")}return{...He,error:ve}}import{randomUUID as d6}from"crypto";import{remote as VJ}from"webdriverio";var ag="NATIVE_APP";var sg=class{constructor(e){this.driver=e}async executeWebViewScript(e,t,...n){return this.executeInContext(e,async o=>{let i=new Function("...args",`${tu.safariUtilsLibJs}; const userFn = ${t.toString()}; return userFn(momenticFunctions, ...args);`);return o.execute(i,...n)})}async executeInNativeContext(e){return this.executeInContext(ag,e)}async executeInContext(e,t){return await this.driver.switchContext(e),await t(this.driver)}};import{createInstanceClient as WJ}from"@limrun/api/ios-client";import{hostname as jJ}from"os";async function CD(r){let{apiClient:e,logger:t,creationOpts:n,logLevel:o,orgId:i,sessionId:a,onConnectionStateChange:s}=r,{token:c,webRtcUrl:l,wdaUrl:u,apiUrl:d,id:p,region:m}=await e.createIosEmulator({...n,hostname:jJ(),sessionId:a});t.info({emulatorName:p,region:m,sessionId:a},"ios instance creation ok");let g=await nt.recordDuration({fn:async()=>await WJ({apiUrl:d,token:c,logLevel:o}),name:"test_event_duration",tags:["name:limbar-client-creation","clientOs:ios",`orgId:${i}`]});return s&&g.onConnectionStateChange(s),{close:()=>{g.disconnect()},limbarToken:c,limbarWebRtcUrl:l,limbarApiUrl:d,limbarWdaUrl:u,emulatorName:p,limbarClient:g}}async function xD({wdaUrl:r,token:e}){try{let t=new AbortController;return setTimeout(()=>t.abort(),3e3),await fetch(r+"/status",{headers:{Authorization:`Bearer ${e}`},signal:t.signal}),!0}catch{return!1}}async function _D({creationOpts:r,apiClient:e,logger:t,driverLogLevel:n,appiumPort:o,orgId:i,sessionId:a,callbacks:s}){let c=Date.now();t.info("Starting ios driver creation");let{onLimbarConnectionStateChange:l}=s,u=[],d=await CD({apiClient:e,logger:t,creationOpts:r,orgId:i,sessionId:a,onConnectionStateChange:l}),p=d.emulatorName;u.push(()=>e.deleteIosEmulator(p),d.close);let m=async()=>{for(let g=u.length-1;g>=0;g-=1)try{await u[g]()}catch(h){if(h instanceof Error&&["ECONNREFUSED","ECONNRESET","UND_ERR_CLOSED"].some(f=>h.message.includes(f)))continue;t.warn({err:h},"Error running cleanup task")}};try{let g=await $J({logger:t,driverLogLevel:n,appiumPort:o,emulatorStart:c,emulatorCreationParams:d,apiClient:e,creationOpts:r,orgId:i,sessionId:a,callbacks:s});return u.push(g.appiumClose),u.push(async()=>g.driver.deleteSession()),g.driver.getPageSource().catch(()=>{}),{...d,...g,driver:new sg(g.driver),cleanup:m,appiumPort:o}}catch(g){throw await m(),new Error(`Failed to start Appium driver: ${g}`)}}async function $J({logger:r,driverLogLevel:e="warn",emulatorStart:t,appiumPort:n,emulatorCreationParams:o,callbacks:{onStatusUpdate:i,onLimbarConnectionStateChange:a}}){let s=[],{emulatorName:c,limbarWdaUrl:l,limbarApiUrl:u,limbarToken:d,limbarClient:p}=o,m=Date.now(),{close:g,logFile:h}=await qc({logger:r,logLevel:e,appiumPort:n});await xD({wdaUrl:l,token:d})||(r.debug({emulatorName:c},"WDA is not running on the Limbar iOS emulator"),await p.simctl(["launch","booted","com.facebook.WebDriverAgentRunner.xctrunner"]).wait(),r.debug({emulatorName:c},"WDA launched"));let f={platformName:"iOS","appium:automationName":"XCUITest","appium:noReset":!0,"appium:fullReset":!1,"appium:webDriverAgentUrl":l,"appium:wdaLocalPort":443,"appium:useNewWDA":!1,"appium:usePreinstalledWDA":!0,"appium:newCommandTimeout":3600,"appium:autoWebview":!1,"appium:webviewConnectTimeout":500,"appium:webviewConnectRetries":5,"appium:includeSafariInWebviews":!0,"appium:fullContextList":!1,"appium:additionalWebviewBundleIds":["*"],"appium:waitForQuiescence":!1,"appium:settings":{customSnapshotTimeout:0},"appium:limInstanceApiUrl":u,"appium:limInstanceToken":d,"appium:wdaRequestHeaders":{Authorization:`Bearer ${d}`}},y=Date.now(),E=await VJ({capabilities:f,hostname:"localhost",port:n,path:"/",protocol:"http",logLevel:e}),b=new Map;return E.on("command",M=>{b.set(M.command,Date.now())}),E.on("result",M=>{let O=b.get(M.command);if(!O)return;let v=Date.now()-O;M.result instanceof Error?r.warn({err:M.result,command:M.command,args:M.body,durationMs:v},"Appium cmd failed"):v>1e4&&r.warn({command:M.command,args:M.body,durationMs:v},"Appium cmd took very long"),b.delete(M.command)}),r.info({timings:{emulatorDuration:m-t,appiumDuration:y-m,wdioDuration:Date.now()-y},capabilities:f,emulatorName:c},"Started Appium driver"),{onStatusUpdate:i,driver:E,appiumClose:async()=>{await g(),await Promise.all(s.map(M=>M()))},appiumPort:n,appiumLogFile:h,emulatorName:c}}import{createHash as s6}from"crypto";import l6 from"jpeg-js";import{PNG as kD}from"pngjs";import e6 from"@prettier/plugin-xml";import t6 from"prettier";import{DOMParser as r6,XMLSerializer as n6}from"slimdom";import{reduce as qJ}from"lodash-es";var KJ=new Set(["id","processId","bundleId","type","accessible","index","x","y","width","height"]),YJ=new Set([]),XJ=new Set(["name","label","traits"]),JJ=new Set(["live-region","drawing-order"]),ZJ=new Set(["visible","enabled"]);function MD(r){let e={},t=r.tagName,n=qJ(r.attributes,(o,i)=>(o[i.name]=i.value,o),{});for(let[o,i]of Object.entries(n))KJ.has(o)||o==="class"&&t===i||o==="focusable"&&i==="true"&&n.clickable==="true"||YJ.has(o)&&i==="false"||XJ.has(o)&&i===""||ZJ.has(o)&&i==="true"||JJ.has(o)&&i==="0"||(e[o]=i);return e.name&&e.label&&e.name===e.label&&delete e.label,e.name&&e.value&&e.name===e.value&&delete e.value,e}function lg(r){let e=r.getAttribute("x"),t=r.getAttribute("y"),n=r.getAttribute("width"),o=r.getAttribute("height");if(e===null||t===null||n===null||o===null)return;let i=parseFloat(e),a=parseFloat(t),s=parseFloat(n),c=parseFloat(o);if(!(isNaN(i)||isNaN(a)||isNaN(s)||isNaN(c)))return[i,a,i+s,a+c]}function Zb(r,e){let[t,n,o,i]=e;r.setAttribute("bounds",`[${t}, ${n}, ${o}, ${i}]`)}function QJ(r){let e=r.match(/\[\s*([-\d.]+)\s*,\s*([-\d.]+)\s*,\s*([-\d.]+)\s*,\s*([-\d.]+)\s*\]/);if(!e)return;let t=parseFloat(e[1]),n=parseFloat(e[2]),o=parseFloat(e[3]),i=parseFloat(e[4]);if(!(isNaN(t)||isNaN(n)||isNaN(o)||isNaN(i)||o<t||i<n))return[t,n,o,i]}function PD(r){let e=r.getAttribute("bounds");if(e)return QJ(e)}function ID(r,e){if(!e)return!0;let t=lg(r);return t?Qb(t,e):!0}function Qb(r,e){if(!e)return!0;let[t,n,o,i]=r;return!(o<e.left||t>e.right||i<e.top||n>e.bottom)}var OD=new Set(["XCUIElementTypeWebView"]);function o6(r){if(OD.has(r.tagName))return!0;let e=r.getAttribute("name");if(e&&(e.startsWith("TabDocument")||e.startsWith("BrowserView"))){let t=e.match(/UUID=([A-F0-9-]+)/),n=e.match(/WebViewProcessID=(\d+)/);if(t&&n)return!0}return!1}function i6(r){let e=["android.widget.","android.view.","android.webkit.","android.app.","android.support.","androidx.","com.android.inputmethod."];for(let t of e)if(r.startsWith(t))return r.substring(t.length);return r}function eE(r,e){let{idCounter:t,idToElement:n}=r,o=t.value++;e.setAttribute("id",String(o)),n.set(o,e)}function tE(r){if(OD.has(r.tagName))return r.children.length>0?tE(r.children[0]):void 0;if(r.tagName==="XCUIElementTypeOther"&&r.hasAttribute("name")&&r.hasAttribute("label"))return lg(r);if(r.children.length===1){let e=r.children[0];return tE(e)}}function LD(r,e,t,n){let{document:o}=t,{parentFrameBounds:i,pruneElementsOutsideBounds:a}=n;if(e.type==="element"){let s=o.createElement(e.role||e.tag);if(e.name&&s.setAttribute("name",e.name),e.description&&s.setAttribute("description",e.description),e.classes&&e.classes.length>0&&s.setAttribute("classes",e.classes.join(" ")),e.attrs)for(let[u,d]of Object.entries(e.attrs))s.setAttribute(u,d);let c=e.boundingRect,l=[i[0]+c.x,i[1]+c.y,i[0]+c.x+c.width,i[1]+c.y+c.height];if(!Qb(l,a))return;Zb(s,l),eE(t,s),r.appendChild(s);for(let u of e.children)LD(s,u,t,n)}else if(e.type==="text"){let s=o.createElement("text");eE(t,s),r.appendChild(s);let c=o.createTextNode(e.text);s.appendChild(c)}}function ND(r,e,t,n){let{pruneElementsOutsideBounds:o}=n,{document:i}=t;eE(t,e);let a=MD(r);for(let[l,u]of Object.entries(a))e.setAttribute(l,u);let s=lg(r);if(s&&Zb(e,s),o6(r)){let{removeWebviewContent:l,injectedWebviewContent:u}=n;if(l)return;if(u){let d=tE(r);if(d){LD(e,u,t,{parentFrameBounds:d,pruneElementsOutsideBounds:o});return}}}let c=Array.from(r.childNodes??[]);for(let l of c){let u=l.nodeType;if(u===3){let d=l.nodeValue;d&&d.trim().length>0&&e.appendChild(i.createTextNode(d));continue}if(u===1){let d=l;if(!ID(d,o))continue;let p=i.createElement(i6(d.tagName));ND(d,p,t,n),e.appendChild(p)}}}async function a6(r,e,t){let n=r.parseFromString("<AppiumAUT/>","text/xml"),o=new Map,i={document:n,idToElement:o,idCounter:{value:0}},a=n.documentElement;ND(e,a,i,t);let s=new n6().serializeToString(n),c=await t6.format(s,{parser:"xml",plugins:[e6],printWidth:120,tabWidth:1,singleAttributePerLine:!1});return{prunedDocument:n,idToElement:o,prunedXml:c}}async function DD(r,e){let t=new r6,o=t.parseFromString(r,"text/xml").documentElement;if(!o)throw new Error("No root element found in XML");if(o.tagName!=="AppiumAUT")throw new Error("No AppiumAUT element found in XML");let{prunedXml:i,idToElement:a,prunedDocument:s}=await a6(t,o,e);return{xml:i,idToElement:a,document:s}}var cg=class r{driver;limbarClient;orgId;options;aborter;constructor({driver:e,limbarClient:t,orgId:n,options:o,aborter:i}){this.driver=e,this.limbarClient=t,this.orgId=n,this.options=o,this.aborter=i}static async init({driver:e,limbarClient:t,orgId:n,options:o,aborter:i}){return new r({driver:e,orgId:n,options:o,aborter:i,limbarClient:t})}async getContexts(){let e=await this.driver.executeInNativeContext(async n=>await n.getContexts({})),t=e.filter(n=>n!==ag);return{contexts:e.map(n=>n),webviews:t}}async getRawScreenshotBase64(e,t=2){let n=se(),o;for(let i=0;i<t;i++)try{return await n.startAsyncSpan("EMULATOR_READ_STATE",async()=>{let a=await this.limbarClient.screenshot(),s=Buffer.from(a.base64,"base64"),c=l6.decode(s),l=new kD({width:c.width,height:c.height});return l.data=Buffer.from(c.data),kD.sync.write(l).toString("base64")},{name:"Take screenshot",signal:this.aborter.controller?.signal,timeoutMs:3e3})}catch(a){if(o=a,e.warn({err:a},"Failed to take screenshot"),i===t-1)throw a}throw new R("InternalWebAgentError",`Failed to take screenshot: ${o}`)}async getCurrentScreenshotPngString(e){return`data:image/png;base64,${await this.getRawScreenshotBase64(e,1)}`}async waitForScreenshotStability({logger:e,timeoutMs:t,signal:n,reason:o,tolerancePercent:i=1}){let a=Date.now(),s,c=!1;for(;Date.now()-a<t;){if(n?.throwIfAborted(),!s){s=await this.getRawScreenshotBase64(e);continue}let l=await this.getRawScreenshotBase64(e);if(Ms(s,l)<=i){c=!0;break}s=l,await J(250,n)}c||e.warn({purpose:o},"Timed out waiting for screenshot stability")}async waitForPageSourceStability({logger:e,timeoutMs:t,signal:n,reason:o}){await se().startAsyncSpan("WAIT_FOR_PAGE_STABILITY",async i=>{i.attributes.reason=o;let a=Date.now(),s,c,l=!1;for(;Date.now()-a<t;){c&&c<250&&await J(250-c,n),n?.throwIfAborted();let u=Date.now(),d;try{d=await this.limbarClient.elementTree()}catch(m){e.warn({err:m},"Failed to get page source during stability wait"),c=Date.now()-u;continue}let p=s6("md5").update(d).digest("hex");if(c=Date.now()-u,s&&s===p){l=!0;break}s=p}l||(i.attributes.timedOut=!0,e.warn({purpose:o},"Timed out waiting for page source stability"))})}async getActiveWebview(){let t=(await this.getContexts()).webviews;if(t.length>1)throw new R("UserInfrastructureError","Multiple active webviews in a single package is currently not supported");return t[0]}async getActiveWebviewContent(){let e=await this.getActiveWebview();if(!e)return;this.throwIfAborted();let t=await this.driver.executeWebViewScript(e,n=>n.dumpA11yTree());if(t)return JSON.parse(t)}async getDomState(e,t){let o=t?.filterOffscreenElements??!0?await this.getViewportBounds():void 0,i=await this.getPageSource();this.throwIfAborted();let a;if(!t?.skipFetchingFullWebviewContent)try{a=await this.getActiveWebviewContent()}catch(c){e.error({err:c},"Could not get webview info to get the nested DOM state")}return this.throwIfAborted(),{graph:await DD(i,{injectedWebviewContent:a,removeWebviewContent:t?.removeWebviewContent,pruneElementsOutsideBounds:o})}}async getPageSource(){return await se().startAsyncSpan("EMULATOR_READ_STATE",()=>this.driver.executeInNativeContext(async n=>n.getPageSource()),{name:"Get iOS page source",signal:this.aborter.controller?.signal})}async getViewportBounds(){let e=await this.driver.executeInNativeContext(async t=>t.getWindowRect());return{left:e.x,top:e.y,right:e.x+e.width,bottom:e.y+e.height}}throwIfAborted(){this.aborter.controller?.signal.throwIfAborted()}};function FD({aiResponse:r,description:e,emulatorState:t}){let n=t.graph.idToElement.get(r.id);if(!n)throw new Error(`Could not find node with id: ${r.id}`);let o=PD(n);if(!o)throw new Error(`Could not determine bounds for element with id: ${r.id}, description: ${e}`);return{target:{type:"NATIVE",bounds:o},resolvedNode:n}}var Jn=class{limbarClient;driver;stateManager;generator;fixtures;orgId;aiSettings;aborter;constructor(e){this.stateManager=e.stateManager,this.driver=e.driver,this.limbarClient=e.limbarClient,this.aborter=e.aborter,this.fixtures=e.fixtures,this.orgId=e.orgId,this.generator=e.generator,this.aiSettings=e.aiSettings}async findElement({logger:e,description:t,skipFetchingFullWebviewContent:n=!1,removeWebviewContent:o=!1,useMemory:i=!1,metadata:a}){let s=e.child({...a});await this.stateManager.waitForScreenshotStability({logger:e,timeoutMs:5e3,signal:this.aborter.controller?.signal,reason:"Waiting for stability before locating an element with AI"});let c=await this.stateManager.getDomState(e,{skipFetchingFullWebviewContent:n,removeWebviewContent:o}),l=await this.stateManager.getCurrentScreenshotPngString(e),u;try{u=await this.generator.getIosElementLocation({description:t,screenXml:c.graph.xml,screenshot:l},{logger:s,loggerTags:ye(s),abortSignal:this.aborter.controller?.signal,useMemory:i,agentConfigVersion:this.aiSettings.agentConfig?.["ios-locator"]})}catch(m){throw this.throwIfAborted(),s.error({err:m},"Failed to locate element"),new Error(`ActionFailureError: Failed to locate element: ${m instanceof Error?m.message:m}`)}if(u.id===-1)throw new R("NoMatchingElementError",u.thoughts??"No matching element found");let{target:d,resolvedNode:p}=FD({aiResponse:u,description:t,emulatorState:c});return{resolvedTarget:{...d,resolvedNode:p},thoughts:u.thoughts}}async wrapTargetingAction(e){let{logger:t,action:n,description:o,command:i,cacheIsInvalidAfterResolution:a,skipFetchingFullWebviewContent:s=!1,removeWebviewContent:c=!1}=e,l={commandId:i.id},u=!1,d;i.disableCache&&(t.debug({command:i},"Cache explicitly disabled for command"),u=!0,d=void 0),a&&(u=!0,d=void 0),d&&d?.resolvedDescription!==o&&(t.info({description:o,cacheDescription:d?.resolvedDescription},"Cache description mismatch, clearing it automatically"),u=!0,d=void 0),t.info({description:o,cacheBustedBeforeAction:u},"Prompting AI for a new element location");let p=await this.findElement({logger:t,description:o,skipFetchingFullWebviewContent:s,removeWebviewContent:c,metadata:l}),m=p.thoughts;return{result:await n(p.resolvedTarget),thoughts:m}}constructPerformerParams(){return{limbarClient:this.limbarClient,stateManager:this.stateManager,driver:this.driver,fixtures:this.fixtures,aborter:this.aborter,orgId:this.orgId,generator:this.generator,aiSettings:this.aiSettings}}throwIfAborted(){this.aborter.controller?.signal.throwIfAborted()}get abortSignal(){return this.aborter.controller?.signal}};var ug=class extends Jn{async doPress({name:e,longPress:t}){return this.driver.executeInNativeContext(n=>n.executeScript("mobile: pressButton",[{name:e,isLongPress:t}]))}};function c6(r){let e={relativePosition:r.relativePosition};if(r.doubleTap&&r.longPress)throw new Error("UserConfigurationError: Cannot specify both doubleTap and longPress");return r.doubleTap?{...e,doubleTap:!0,doubleTapDelayMs:r.doubleTapDelayMs}:r.longPress?{...e,longPress:!0,longPressDurationMs:r.longPressDurationMs}:e}var cl=class extends Jn{async tapOnAbsoluteCoordinates(e,t){let n=t.x,o=t.y;if(e.info({x:n,y:o},"Tap at coordinates"),t.longPress){let i=t.longPressDurationMs??2e3;await this.driver.executeInNativeContext(a=>a.tap({x:n,y:o,duration:i}));return}if(t.doubleTap){await this.driver.executeInNativeContext(a=>a.tap({x:n,y:o}));let i=t.doubleTapDelayMs??100;await new Promise(a=>setTimeout(a,i))}await this.driver.executeInNativeContext(i=>i.tap({x:n,y:o}))}async tapOnNativeTarget(e,t,n){let[o,i,a,s]=t.bounds,c=a-o,l=s-i,u=n?.relativePosition?.x??c/2,d=n?.relativePosition?.y??l/2;u=Math.max(0,Math.min(u,c)),d=Math.max(0,Math.min(d,l));let p=o+u,m=i+d;return await this.tapOnAbsoluteCoordinates(e,{x:p,y:m,...n}),{x:p,y:m}}async tapOnTarget({logger:e,target:t,options:n}){if("type"in t&&t.type==="NATIVE")await this.tapOnNativeTarget(e,t,n);else throw new Error("Not implemented yet")}async executeTap({logger:e,command:t}){let n=c6(t);if(t.target.type==="coordinates"){let a=await this.driver.executeInNativeContext(async l=>l.getWindowSize()),s=t.target.xPercent*a.width,c=t.target.yPercent*a.height;return await this.tapOnAbsoluteCoordinates(e,{...n,x:s,y:c}),{success:!0,message:`Tapped at ${s}, ${c}`}}let o=t.target.description,{thoughts:i}=await this.wrapTargetingAction({logger:e,command:t,action:a=>this.tapOnTarget({logger:e,target:a,options:n}),description:o});return{success:!0,message:i}}};var u6=25,dg=class extends Jn{async doType(e,t){if(!t.target){if(t.clearContent)throw new Error("UserConfigurationError: clearing content is only supported when a target is provided to the Type step");return await this.stateManager.waitForScreenshotStability({logger:e,timeoutMs:3e3,signal:this.aborter.controller?.signal,reason:"Waiting for page to stabilize before typing"}),await this.sendKeys(t),{success:!0,message:"Successfully executed type action"}}if(t.target.type!=="description")throw new Error("UserConfigurationError: x/y targets are not supported for the Type step");let{thoughts:n}=await this.wrapTargetingAction({logger:e,command:t,action:async o=>{if("type"in o&&o.type==="NATIVE")await this.doNativeType(e,t,o);else throw new Error("UserConfigurationError: Webview targets are not supported for the Type step on iOS devices")},description:t.target.description});return{success:!0,message:n}}async doNativeType(e,t,n){let o=new cl(this.constructPerformerParams());t.clearContent?(await o.tapOnNativeTarget(e,n,{longPress:!0}),await this.clearContent()):await o.tapOnNativeTarget(e,n),await this.stateManager.waitForScreenshotStability({logger:e,timeoutMs:3e3,signal:this.aborter.controller?.signal,reason:"Waiting for keyboard to appear before typing"}),await this.sendKeys(t)}async sendKeys(e){let t=e.keyPressDelayMs??u6,n=Date.now();for(;Date.now()-n<3e3&&(this.throwIfAborted(),!await this.driver.executeInNativeContext(o=>o.isKeyboardShown()));)await new Promise(o=>setTimeout(o,500));t?await this.driver.executeInNativeContext(async o=>{await o.updateSettings({keyInjectionDelay:t}),await o.keys(e.text),await o.updateSettings({keyInjectionDelay:0})}):await this.driver.executeInNativeContext(async o=>{await o.keys(e.text)})}async clearContent(){await this.clearContentHelper()}async clearContentHelper(){}};var mg=class r extends Jn{emulatorSettings;logger;constructor(e){super(e),this.logger=e.logger,this.emulatorSettings=e.emulatorSettings}static async init({driver:e,logger:t,fixtures:n,orgId:o,options:i,abortController:a,limbarClient:s,generator:c,aiSettings:l}){let u={controller:a},d=i?.emulator??{},p=await cg.init({driver:e,orgId:o,limbarClient:s,options:d,aborter:u}),m=new r({generator:c,aiSettings:l,limbarClient:s,driver:e,stateManager:p,logger:t,fixtures:n,aborter:u,orgId:o,emulatorSettings:d});return await m.initializeSettings(),m}async executeCommand(e){let t=["type","a11yData","thoughts","cache","code"],n;try{n=await Ps({obj:e.command,context:this.fixtures.testContext,bannedKeys:t,orgId:this.orgId,logger:this.logger,signal:this.abortSignal,localTools:this.fixtures.localCodeEvalTools})}catch(o){throw this.throwIfAborted(),new Error(`ActionFailureError: Failed to substitute template strings in command: ${o.message}`,{cause:o})}try{return await this.executeCommandHelper(e)}catch(o){throw o.name!=="AbortError"&&this.logger.error({err:o},"Error thrown in action controller"),o}finally{Is(e.command,n)}}async executeCommandHelper({command:e}){let t=se();switch(e.type){case"TAP":return new cl(this.constructPerformerParams()).executeTap({logger:this.logger,command:e});case"TYPE":return new dg(this.constructPerformerParams()).doType(this.logger,e);case"STATE":{let n=await this.stateManager.getDomState(this.logger),o=await this.stateManager.getContexts();return{output:{xml:n.graph.xml,contexts:o},success:!0}}case"OPEN_APP":return await this.limbarClient.launchApp(e.packageName),{success:!0};case"PRESS":{let n=new ug(this.constructPerformerParams());switch(e.key){case"HOME":await n.doPress({name:"home"});break;case"POWER":await this.driver.executeInNativeContext(o=>o.isLocked())?await this.driver.executeInNativeContext(o=>o.unlock()):await this.driver.executeInNativeContext(o=>o.lock());break}return{success:!0}}case"AI_CHECK":{let o=e.timeoutSecs?e.timeoutSecs*1e3:5e3,i=Hm(o),a=Date.now(),s=0,c,l=!1,u;for(;s<15&&!l;){this.throwIfAborted(),l||c&&c-a>=o&&(l=!0),s!==0&&await J(i,this.abortSignal),c=Date.now();try{let d="",p="";await t.startAsyncSpan("EMULATOR_READ_STATE",async()=>{d=await this.getEmulatorDomState(),p=await this.getScreenshotBase64()},{name:"Get emulator state"});let m=await this.generator.evaluateIosAssertion({assertion:e.assertion,screenXml:d,screenshot:p},{logger:this.logger,loggerTags:ye(this.logger),agentConfigVersion:this.aiSettings.agentConfig?.["ios-assertion"]});if(m.result)return{success:m.result,message:m.thoughts};{let g=`AssertionFailureError: ${m.thoughts}`;u=new Error(g)}}catch(d){this.throwIfAborted(),this.logger.info({err:d},`AI check assert attempt ${s} failed, retrying...`),u=d instanceof Error?d:new Error(`${d}`)}finally{s++}}return{success:!1,message:u?.message}}default:throw new Error(`Unsupported mobile command type: ${e.type}`)}}async getMobileFailureRecoveryPlan(e){return{thoughts:"Failure recovery is not yet supported for iOS.",scenario:"INELIGIBLE",instructions:void 0}}async waitForPageSourceStability(e){return this.stateManager.waitForPageSourceStability({logger:this.logger,timeoutMs:e.timeoutMs??5e3,reason:e.reason,signal:this.aborter.controller?.signal})}async listInstalledApps(){let e=await this.driver.executeInNativeContext(n=>n.execute("mobile: listApps"));return Object.keys(e).filter(n=>!n.startsWith("com.apple.")&&!n.startsWith("io.appium"))}async initializeSettings(){}async getScreenshotBase64(){return this.stateManager.getRawScreenshotBase64(this.logger)}async getScreenshotPngString(){return this.stateManager.getCurrentScreenshotPngString(this.logger)}async getEmulatorDomState(){return(await this.stateManager.getDomState(this.logger)).graph.xml}async getViewportBounds(){return this.stateManager.getViewportBounds()}async waitForScreenshotStability(e){return this.stateManager.waitForScreenshotStability({logger:this.logger,timeoutMs:e.timeoutMs??5e3,reason:e.reason,signal:this.aborter.controller?.signal})}resetAbortController(e){this.aborter.controller=e??new AbortController}isAborted(){return this.aborter.controller?.signal.aborted}abort(){this.aborter.controller?.abort()}async cleanup(){}get abortSignal(){return this.aborter.controller?.signal}get context(){return this.fixtures.testContext}get localCodeEvalTools(){return this.fixtures.localCodeEvalTools}};import m6 from"zod";async function UD({runTracer:r,metadata:{orgId:e,runId:t},fixtures:{logger:n,apiClient:o,mobileGenerator:i,storage:a,cacheStorage:s,usageTracker:c,browserEnricher:l,browserGenerator:u,localCodeEvalTools:d},inputs:{project:p,testDefinition:m},env:{envName:g,envVariables:h},settings:{emulatorSettings:f,aiSettings:y},options:{logLevel:E,region:b}}){let _=Math.floor(Math.random()*1e4)+4e4,M=await Yo(_,"appium"),O=es.or(m6.literal(Au)).optional().parse(b??f.region);if(O==="local")throw new Error("Local region is not supported for iOS tests, as we do not support local iOS emulators.");let C={region:O==="closest"?void 0:O},F=d6(),I=n.child({runAttemptId:F}),B;try{B=await _D({apiClient:o,logger:n,driverLogLevel:E,creationOpts:C,callbacks:{onStatusUpdate:W=>{n.debug({status:W},"Emulator status update")},onLimbarConnectionStateChange:W=>{W==="disconnected"?P.warn("Emulator websocket connection lost. Emulator may be unavailable."):(W==="reconnecting"||W==="connecting")&&P.info("Emulator websocket is reconnecting...")}},appiumPort:M,orgId:e,sessionId:F})}catch(W){let ue=`Fatal error creating iOS driver, failing test run attempt (runId: ${t})`;return n.error({err:W},ue),P.error({err:W},ue),{status:"FAILED",results:[],error:new R("UserConfigurationError",`Fatal error creating iOS driver: ${W.message}`)}}let D=await r.startAttempt({emulatorName:B.emulatorName,runAttemptId:F});I=I.child(D.loggerBindings||{});let ee=new No({variablesFromEnvironment:h,envName:g,testName:m.name}),K=await mg.init({driver:B.driver,generator:i,logger:I,limbarClient:B.limbarClient,orgId:e,options:{emulator:{...f,browserSettings:p.config.browser}},aiSettings:y,fixtures:{storage:a,browserEnricher:l,browserGenerator:u,localCodeEvalTools:d,testContext:ee}}),ge;try{ge=await ol({platform:"IOS",containerName:`ios test ${m.name}`,fixtures:{controller:K,logger:I,cacheStorage:s,usageTracker:c},work:{state:{failureRecoveryDisabled:y.failureRecovery===!1,failureRecoveryAttempts:0}},inputs:{testName:m.name,steps:m.steps,orgId:e,testMetadata:m},tracer:D,callbacks:{}})}finally{await B.cleanup(),await K.cleanup()}await D.finish({logger:I,results:ge.results,status:ge.status});let U;if(ge.status==="FAILED"&&ge.terminalResult){let W=ge.terminalResult.message;W?U=R.fromMessage(W):U=new R("UnknownError",W||"Unknown failure")}return{...ge,error:U}}import{cloneDeep as p6}from"lodash-es";import{debounce as g6}from"ts-debounce";var Cu="0.34.0";function h6(r){switch(r){case"PASSED":return"SUCCESS";case"FAILED":return"FAILED";case"CANCELLED":return"CANCELLED";case"RUNNING":case"PENDING":case"RETRYING":case"WAITING_FOR_USER":return"RUNNING"}}function f6(r){switch(r){case"SUCCESS":return"PASSED";case"FAILED":return"FAILED";case"CANCELLED":return"CANCELLED";case"RUNNING":return"RUNNING";case"IDLE":return"PENDING"}}var nE=class{constructor(e,t,n,o,i,a){this.keepalive=e;this.testId=t;this.testName=n;this.diskStorage=o;this.parentTracer=i;this.orgId=a;this.interactionTracer=new Jo,rn.initializeRootTracerContext(this.interactionTracer)}children=[];finished=!1;interactionTracer;getParentStepIdChain(){return[]}recordStepDuration(e){let{durationMs:t,step:n}=e,o=n.type!=="MOBILE_PRESET_STEP"?n.type:n.command.type;nt.distribution("test_step_duration",t,[`type:${o}`,"platform:mobile","executor:cli",`orgId:${this.orgId}`])}attachBeforeScreenshot(e){let{snapshotId:t,screenshot:n}=e;this.diskStorage.storeFile({name:`${zo}/${t}.jpeg`,contents:n})}attachAfterScreenshot(e){let{snapshotId:t,screenshot:n}=e;this.diskStorage.storeFile({name:`${zo}/${t}.jpeg`,contents:n})}attachBeforeXmlSnapshot(e){let{snapshotId:t,xml:n}=e;this.diskStorage.storeFile({name:`${zo}/${t}.xml`,contents:n})}attachAfterXmlSnapshot(e){let{snapshotId:t,xml:n}=e;this.diskStorage.storeFile({name:`${zo}/${t}.xml`,contents:n})}async finishInternal(e){this.finished||(this.finished=!0,this.interactionTracer.finish(),await Promise.all(this.children.map(t=>t.finish({status:f6(e.status),finishedAt:e.finishedAt}))))}async finish(e){return await this.finishInternal({status:e.result.status,finishedAt:new Date(e.result.endTime)}),{trace:this.interactionTracer.getRootSpan()}}async startSubSteps(){let e=new ul(this.keepalive,this.testId,this.testName,this.diskStorage,this.orgId);return this.children.push(e),e}},ul=class{constructor(e,t,n,o,i){this.keepalive=e;this.testId=t;this.testName=n;this.diskStorage=o;this.orgId=i}children=[];finished=!1;async getScreenshot(e){return this.diskStorage.readFile(`${zo}/${e}.jpeg`)}getParentStepIdChain(){return[]}async startStep(e){this.keepalive();let t=new nE(this.keepalive,this.testId,this.testName,this.diskStorage,this,this.orgId);return this.children.push(t),t}async finish(e){this.finished||(this.finished=!0,await Promise.all(this.children.map(t=>t.finishInternal({status:h6(e.status),finishedAt:e.finishedAt}))))}},oE=class{constructor(e,t,n,o,i,a,s){this.keepalive=e;this.testId=t;this.testName=n;this.runAttemptId=o;this.metadata=i;this.diskStorage=a;this.orgId=s;this.diskStorage.mkdir("assets"),this.logStream=this.diskStorage.createFileStream("assets/logs.logcat"),this.resourceUsageStream=this.diskStorage.createFileStream(`${zo}/resource-usage.ndjson`),this.resourceUsageSampler=vw({keepSamples:!1,onSample:c=>{this.resourceUsageStream.write(`${JSON.stringify(c)}
|
|
4661
4661
|
`)}})}finished=!1;children=[];logStream;resourceUsageStream;resourceUsageSampler;get loggerBindings(){return{runAttemptId:this.runAttemptId}}appendLogs(e){let t=e.join(`
|
|
4662
4662
|
`);this.logStream.write(t+`
|
|
4663
4663
|
`)}async finish(e){if(this.finished)return;this.finished=!0;let{logger:t,status:n,results:o,beforeResults:i,afterResults:a}=e,s={...this.metadata,status:n,assetDetails:e.assetDetails,finishedAt:new Date,results:_m(o,t),beforeResults:i?_m(i,t):void 0,afterResults:a?_m(a,t):void 0};await Promise.all(this.children.map(c=>c.finish({status:s.status,finishedAt:s.finishedAt})));try{this.logStream.end()}catch{}try{this.resourceUsageSampler.stop(),this.resourceUsageStream.end()}catch{}this.diskStorage.storeFile({name:"metadata.json",contents:JSON.stringify(s,null,2)})}async startBeforeStepList(){let e=new ul(this.keepalive,this.testId,this.testName,this.diskStorage,this.orgId);return this.children.push(e),e}async startMainStepList(){let e=new ul(this.keepalive,this.testId,this.testName,this.diskStorage,this.orgId);return this.children.push(e),e}async startAfterStepList(){let e=new ul(this.keepalive,this.testId,this.testName,this.diskStorage,this.orgId);return this.children.push(e),e}async getScreenshot(e,t){return this.diskStorage.readFile(`${zo}/${t}.jpeg`)}},iE=class{constructor(e,t,n,o,i,a,s){this.client=e;this.testId=t;this.testName=n;this.runId=o;this.metadata=i;this.diskStorage=a;this.orgId=s}children=[];finished=!1;get loggerBindings(){return{runId:this.runId}}async finish(e){if(this.finished)return;this.finished=!0;let t={...this.metadata,finishedAt:e.finishedAt||new Date,status:e.status,failureDetails:e.failureDetails,failureReason:e.failureReason,flake:e.isFlake||!1,failureRecoveryDetails:e.failureRecoveryDetails};await Promise.all(this.children.map(n=>n.finish({logger:e.logger,status:t.status,results:[],beforeResults:[],afterResults:[]}))),this.diskStorage.storeFile({name:"metadata.json",contents:JSON.stringify(t,null,2)}),this.diskStorage.close()}async startAttempt(e){let{runAttemptId:t}=e;this.metadata.attempts=this.metadata.attempts+1,this.metadata.status="RUNNING",this.diskStorage.storeFile({name:"metadata.json",contents:JSON.stringify(this.metadata,null,2)});let n=this.diskStorage.cd(`attempts/${this.metadata.attempts}`),o={id:t,schemaVersion:xo,runAttemptSchemaVersion:lw,startedAt:new Date,status:"RUNNING"};n.storeFile({name:"metadata.json",contents:JSON.stringify(o,null,2)});let i=g6(async()=>{await this.client.extendAndroidEmulatorTtl(e.emulatorName)},3e4,{maxWait:6e4}),a=new oE(()=>void i(),this.testId,this.testName,t,o,n,this.orgId);return this.children.push(a),a}},pg=class r{constructor(e,t,n,o,i){this.orgId=e;this.runGroupId=t;this.metadata=n;this.client=o;this.diskStorage=i}children=[];finished=!1;get loggerBindings(){return{orgId:this.orgId,runGroupId:this.runGroupId,branch:this.metadata.gitBranchName}}static async start({orgId:e,runGroupId:t,outputDir:n,client:o,gitMetadata:i,labels:a,suiteName:s}){let c={...i,suiteName:s,id:t,trigger:Rr.CLI,startedAt:new Date,status:"RUNNING",cliVersion:Cu,labels:a??[]},l=new yu(n);return l.storeFile({name:"metadata.json",contents:JSON.stringify(c,null,2)}),new r(e,t,c,o,l)}async finish(e){if(this.finished)return;this.finished=!0;let{status:t}=e,n={...this.metadata,status:t,updatedAt:new Date,finishedAt:new Date};await Promise.all(this.children.map(o=>o.finish({logger:e.logger,status:n.status,finishedAt:n.finishedAt}))),this.diskStorage.storeFile({name:"metadata.json",contents:JSON.stringify(n,null,2)})}async startRun(e){let t=this.diskStorage.createRunArchive(e.runId),n={stepsSnapshot:e.originalSteps.steps,runGroupId:this.runGroupId,testId:e.testId,testName:e.testName,testDescription:e.testDescription,directory:e.directory,labels:e.testLabels,trigger:"CLI",status:"RUNNING",environmentName:e.environmentName,cliVersion:Cu,schemaVersion:e.schemaVersion,startedAt:new Date,attempts:0,quarantined:e.quarantined,quarantinedReason:e.quarantinedReason,executionType:Fl(e.platform),aiSettings:e.aiSettings};t.storeFile({name:"metadata.json",contents:JSON.stringify(n,null,2)});let o=new iE(this.client,e.testId,e.testName,e.runId,n,t,this.orgId);return this.children.push(o),o}};function BD(r){return{platform:r.platform,originalSteps:{steps:p6(r.steps),beforeSteps:void 0,afterSteps:void 0}}}async function zD(r){let{inputs:e,fixtures:t,metadata:n}=r,{tracer:o,logger:i}=t,{runId:a}=n,{platform:s,testDefinition:c,project:l}=e,u=new Date,d=await o.startRun({...BD(c),logger:i,testId:c.id,testName:c.name,directory:S6(c.relativeFilePath),runId:a,testDescription:c.description,testLabels:c.labels,schemaVersion:c.schemaVersion,quarantined:c.quarantined,quarantinedReason:c.quarantinedMetadata?.quarantinedReason,aiSettings:l.config.ai}),p=i.child(d.loggerBindings||{}),m=1+(c.settings?.retries??l.config.retries??1);for(let g=0;g<m;g++){let h=new Date,f=await y6({...r,runTracer:d,fixtures:{...t,logger:p},constants:{attemptNumber:g,totalAttempts:m}}),y=new Date;if(f.status!=="FAILED")return await d.finish({logger:p,status:f.status,failureRecoveryDetails:f.failureRecoveryDetails,finishedAt:y}),{...f,testMetadata:c,platformType:Fl(s),steps:c.steps,startedAt:u,lastAttemptStartedAt:h,finishedAt:y,runId:a,attempts:g+1,filePath:c.relativeFilePath,quarantined:c.quarantined,quarantinedMetadata:c.quarantinedMetadata,status:f.status};if(g!==m-1){p.warn("Retrying failed mobile run");continue}p.error("Mobile test failed after all exhausting attempts");let E={failureReason:f.error?.reason,failureDetails:f.error?{errorMessage:f.error.message,errorStack:f.error.stack}:void 0};return await d.finish({logger:p,status:f.status,...E,finishedAt:y}),{...f,testMetadata:c,platformType:Fl(s),steps:c.steps,startedAt:u,lastAttemptStartedAt:h,finishedAt:y,runId:a,...E,attempts:g+1,filePath:c.relativeFilePath,quarantined:c.quarantined,quarantinedMetadata:c.quarantinedMetadata,status:f.status}}throw new Error("This code should not be reachable")}async function y6(r){let{runTracer:e,metadata:t,constants:n,fixtures:o,inputs:i,options:a}=r,{attemptNumber:s,totalAttempts:c}=n,{orgId:l,gitMetadata:u}=t,{apiClient:d,logger:p,usageTracker:m}=o,{testDefinition:g,logUpdate:h,project:f,envOverride:y}=i,{regenerateCache:E,alwaysSaveCache:b,noCache:_}=a;s!==0&&h("RETRY",`attempt ${s}/${c}`);let M={...i.project.config.emulator,...g.settings?.emulator},O={...f.config.ai,useMemory:f.config.ai?.useMemory!==!1,...g.settings?.ai},v=y||g.settings?.defaultEnv,F=(v?pa(v,f,p):void 0)?.variables??{},I=pi({logger:p,orgId:l,client:d,gitMetadata:u,regenerateCache:E,alwaysSaveCache:b,noCache:_}),B=new Js(d,l),D={type:"API_KEY",baseUrl:d.baseUrl,apiKey:d.apiKey,logger:p,mode:"runner"},ee=new el(D),K=new Sa(O.agentConfig,D),ge=new Xs(D,K),U=new Qs({httpClient:d,fakerSeed:f.config.advanced?.fakerConstantSeed?fd:void 0}),W={orgId:l,runTracer:e,metadata:t,options:a,fixtures:{logger:p,apiClient:d,mobileGenerator:ee,storage:B,cacheStorage:I,usageTracker:m,browserEnricher:ge,browserGenerator:K,localCodeEvalTools:U},env:{envName:v,envVariables:F},settings:{aiSettings:O,emulatorSettings:M}};switch(i.platform){case"ANDROID":return await wD({...W,inputs:i});case"IOS":return await UD({...W,inputs:i})}}import{existsSync as v6,mkdirSync as A6,statSync as R6}from"fs";import w6 from"path";import{z as Uut}from"zod";import b6 from"junit-report-builder";import gg from"path";function HD(r,e){r.property("quarantined","true"),r.property("dd_tags[quarantined]","true"),e.quarantinedReason&&(r.property("quarantined_reason",e.quarantinedReason),r.property("dd_tags[quarantined_reason]",e.quarantinedReason)),e.quarantinedAt&&(r.property("quarantined_at",e.quarantinedAt.toISOString()),r.property("dd_tags[quarantined_at]",e.quarantinedAt.toISOString()))}function E6(r,e){if(e.name(r.testName).className(r.testName).file(gg.relative(".",r.filePath)).property("id",r.testId).property("dd_tags[id]",r.testId),r.labels&&(e.property("labels",r.labels.join(",")),r.labels.forEach(t=>{e.property("dd_tags[label]",t)})),r.baseUrl&&(e.property("base_url",r.baseUrl),e.property("dd_tags[base_url]",r.baseUrl)),r.runId&&(e.property("run_url",`https://app.momentic.ai/runs/${r.runId}`),e.property("dd_tags[run_url]",`https://app.momentic.ai/runs/${r.runId}`)),r.quarantinedMetadata&&HD(e,r.quarantinedMetadata),r.setupFailed&&(e.property("setup_failed","true"),e.property("dd_tags[setup_failed]","true")),r.mainFailed&&(e.property("main_failed","true"),e.property("dd_tags[main_failed]","true")),r.teardownFailed&&(e.property("teardown_failed","true"),e.property("dd_tags[teardown_failed]","true")),r.status==="FAILED"){if(r.failureReason){let t=Ig[r.failureDetails?.classification?.reason||r.failureReason],n=r.failureDetails?.classification?.summary||zu[r.failureReason];r.runId&&(n+=` Visit https://app.momentic.ai/runs/${r.runId} for more details.`),e.failure(n,t)}r.failureDetails?.errorStack&&e.stacktrace(r.failureDetails.errorStack)}else r.status==="CANCELLED"&&e.skipped();return e.time((r.finishedAt.getTime()-r.lastAttemptStartedAt.getTime())/1e3).property("started_at",r.lastAttemptStartedAt.toISOString()).property("dd_tags[started_at]",r.lastAttemptStartedAt.toISOString()).property("finished_at",r.finishedAt.toISOString()).property("dd_tags[finished_at]",r.finishedAt.toISOString()),e.property("attempts",r.attempts.toString()).property("dd_tags[attempts]",r.attempts.toString()),r.parameters?.envName&&(e.property("environment",r.parameters.envName),e.property("dd_tags[environment]",r.parameters.envName)),r.parameters?.urlOverride&&e.property("url_override",r.parameters.urlOverride),e}function T6(r,e,t){let{suiteId:n,suiteName:o,startedAt:i,finishedAt:a,testsToSkip:s,quarantinedTestsToSkip:c,quarantinedTestsMetadata:l}=e,u=r.testSuite().name(o);n&&u.property("id",n),u.timestamp(i).property("startedAt",i.toISOString()).property("finishedAt",a.toISOString()).time((a.getTime()-i.getTime())/1e3);for(let d of t){let p=u.testCase();E6(d,p)}for(let d of s){let p=u.testCase();p.name(d.name).className(d.name).file(gg.relative(".",d.relativeFilePath)).property("id",d.id),d.baseUrl&&p.property("baseUrl",d.baseUrl),d.labels&&(p.property("labels",d.labels.join(",")),d.labels.forEach(m=>{p.property("dd_tags[label]",m)})),p.skipped()}for(let d of c){let p=u.testCase();p.name(d.name).className(d.name).file(gg.relative(".",d.relativeFilePath)).property("id",d.id);let m=l[d.id];m&&HD(p,m),d.baseUrl&&p.property("baseUrl",d.baseUrl),d.labels&&(p.property("labels",d.labels.join(",")),d.labels.forEach(g=>{p.property("dd_tags[label]",g)})),p.skipped()}return u}function aE(r,e,t){let n=b6.newBuilder();T6(n,e,t),n.writeTo(gg.join(r,`${e.suiteName}.xml`))}function C6(r){return{testName:w6.basename(r.filePath,".test.yaml")||r.filePath.split("/").pop()?.replace(".yaml","")||r.filePath,testId:r.testMetadata.id,filePath:r.filePath,labels:r.testMetadata.labels,baseUrl:void 0,runId:r.runId,quarantined:r.quarantined,quarantinedMetadata:r.quarantinedMetadata,status:r.status,setupFailed:void 0,mainFailed:void 0,teardownFailed:void 0,failureDetails:r.failureDetails,failureReason:r.failureReason,finishedAt:r.finishedAt,lastAttemptStartedAt:r.lastAttemptStartedAt,attempts:r.attempts,parameters:r.parameters}}async function GD({format:r,params:e,runs:t,folder:n}){switch(v6(n)?R6(n).isDirectory()||(P.error(`The specified reporter output directory '${n}' exists on disk but is not a folder. Please move or delete the existing object or specify a different reporter path.`),process.exit(1)):(P.info(`Reporter output directory '${n}' does not exist on disk, creating it now...`),A6(n,{recursive:!0})),r){case"junit":{let o=t.map(C6);aE(n,e,o);return}case"allure":case"allure-json":P.error(`The specified reporter format '${r}' is not supported for mobile tests.`);return;case"playwright-json":P.error(`The specified reporter format '${r}' is not supported for mobile tests.`);return;default:throw new Error(`Unknown reporter format requested: '${r}'`)}}async function WD(r,e,t){if(t)return{};try{return(await e.getQuarantinedTests()).quarantined.reduce((o,i)=>(o[i.testId]={quarantinedAt:i.quarantinedAt,quarantinedReason:i.quarantinedReason},o),{})}catch(n){return r.warn({err:n},"Failed to fetch quarantined tests, proceeding without them."),{}}}async function yo(){try{await Y(Promise.all([fw(),nt.flush()]),{milliseconds:5e3})}catch{}}async function jD(r){let{options:e,fixtures:t,inputs:n,metadata:o}=r,{project:i,apiClient:a,logger:s}=t,{orgId:c,runGroupId:l,gitMetadata:u}=o,{suiteName:d,outputDir:p,parallel:m}=e;_6(p)&&P.warn(`Output directory ${p} already exists, removing before test execution...`);let g=U_({items:n.testDefinitions,shardIndex:e.shardIndex??1,shardCount:e.shardCount??1,sortKey:D=>D.relativeFilePath}),h=new Set;n.testDefinitions.forEach(D=>{D.labels?.forEach(ee=>h.add(ee))});let f=s.child({orgId:c,runGroupId:l,branch:u.gitBranchName}),y=await pg.start({suiteName:d,logger:f,orgId:c,runGroupId:l,outputDir:p,client:a,gitMetadata:u,labels:Array.from(h)}),E=[],b=new Date,_=new Set,M=async()=>M6({runResults:E,startTime:b,ranTests:_,apiClient:a,uploadResults:e.uploadResults??!1,outputDir:p}),O=async D=>{P.warn(`${D} Stopping tests and printing latest results.`),await y.finish({logger:f,status:"CANCELLED"}),await M(),await yo(),process.exit(1)},v=async()=>{await O("SIGINT received.")};process.once("SIGINT",v);let C;if(e.timeoutMinutes!==void 0&&e.timeoutMinutes>0){let D=e.timeoutMinutes*60*1e3;C=setTimeout(()=>{O(`Timeout of ${e.timeoutMinutes} minute(s) reached.`)},D)}let F={};for(let D=0;D<g.length;D++){let ee=Object.values(F);ee.length===m&&await Promise.race(ee.map(U=>U.promise));let K=g[D],ge=`test-${D}`;F[ge]={done:!1,promise:(async({testDefinition:U})=>{_.add(ge);let W=U.relativeFilePath.includes("..")?U.fullFilePath:U.relativeFilePath;Vc({status:"START",testLogRef:W,getRunningTestsCount:()=>_.size,getTotalTestsCount:()=>g.length});let ue=setInterval(()=>Vc({status:"RUN",testLogRef:W,getRunningTestsCount:()=>_.size,getTotalTestsCount:()=>g.length}),5*60*1e3),le=x6(),He=f.child({testId:U.id,runId:le}),ve=new jm({logger:He,reporter:new zp(a),runType:"mobile-test-run",runId:le,testMetadata:U,suiteMetadata:void 0});try{let q={platform:U.platform,testDefinition:U},fe=await zD({metadata:{...o,runId:le},fixtures:{...t,tracer:y,logger:He,usageTracker:ve},inputs:{...n,...q,project:i,channel:n.channel??U.settings?.defaultChannel,tag:n.tag??U.settings?.defaultTag,logUpdate:(it,Ae)=>Vc({status:it,testLogRef:W,getRunningTestsCount:()=>_.size,getTotalTestsCount:()=>g.length,additionalText:Ae})},options:e});Vc({status:fe.status,testLogRef:W,getRunningTestsCount:()=>_.size,getTotalTestsCount:()=>g.length}),E.push(fe)}catch(q){let fe=`Encountered unexpected fatal error when running test '${U.name}': ${q.message}
|