@@ -49,6 +49,17 @@ import { setDebugOptions } from "@/debug/options";
4949import { initializeRuntimeContext } from "./shared/runtime-context" ;
5050import { performAction } from "./actions/shared/perform-action" ;
5151
52+ type ActionDebugMetadata = {
53+ elementMetadata ?: {
54+ xpath ?: string ;
55+ } ;
56+ } ;
57+
58+ const hasElementMetadata = ( debugData : unknown ) : debugData is ActionDebugMetadata =>
59+ typeof debugData === "object" &&
60+ debugData !== null &&
61+ "elementMetadata" in debugData ;
62+
5263export class HyperAgent < T extends BrowserProviders = "Local" > {
5364 // aiAction configuration constants
5465 private static readonly AIACTION_CONFIG = {
@@ -202,7 +213,7 @@ export class HyperAgent<T extends BrowserProviders = "Local"> {
202213 * @returns
203214 */
204215 private getActions (
205- outputSchema ?: z . ZodType < any >
216+ outputSchema ?: z . ZodType < unknown >
206217 ) : Array < AgentActionDefinition > {
207218 if ( outputSchema ) {
208219 return [
@@ -764,7 +775,7 @@ export class HyperAgent<T extends BrowserProviders = "Local"> {
764775 public async executeSingleAction (
765776 instruction : string ,
766777 pageOrGetter : Page | ( ( ) => Page ) ,
767- _params ?: TaskParams
778+ params ?: TaskParams
768779 ) : Promise < TaskOutput > {
769780 const actionStart = performance . now ( ) ;
770781 const startTime = new Date ( ) . toISOString ( ) ;
@@ -869,7 +880,7 @@ export class HyperAgent<T extends BrowserProviders = "Local"> {
869880 }
870881 : undefined ,
871882 // These are required by ActionContext but not used by performAction
872- debugDir : undefined ,
883+ debugDir : params ?. debugDir ,
873884 mcpClient : this . mcpClient ,
874885 variables : Object . values ( this . _variables ) ,
875886 invalidateDomCache : ( ) => markDomSnapshotDirty ( initialPage ) ,
@@ -887,9 +898,10 @@ export class HyperAgent<T extends BrowserProviders = "Local"> {
887898 if (
888899 actionOutput . debug &&
889900 typeof actionOutput . debug === "object" &&
890- "requestedAction" in actionOutput . debug
901+ "requestedAction" in actionOutput . debug &&
902+ hasElementMetadata ( actionOutput . debug )
891903 ) {
892- actionXPath = ( actionOutput . debug as any ) . elementMetadata ?. xpath ;
904+ actionXPath = actionOutput . debug . elementMetadata ?. xpath ;
893905 }
894906
895907 if ( ! actionOutput . success ) {
@@ -1140,11 +1152,15 @@ export class HyperAgent<T extends BrowserProviders = "Local"> {
11401152 }
11411153
11421154 private setupHyperPage ( page : Page ) : HyperPage {
1143- const hyperPage = page as HyperPage ;
1155+ type ScopedHyperPage = HyperPage & {
1156+ _scopeListenerCleanup ?: ( ) => void ;
1157+ } ;
1158+
1159+ const hyperPage = page as ScopedHyperPage ;
11441160
11451161 // Clean up existing listener if this page was already setup
1146- if ( ( hyperPage as any ) . _scopeListenerCleanup ) {
1147- ( hyperPage as any ) . _scopeListenerCleanup ( ) ;
1162+ if ( hyperPage . _scopeListenerCleanup ) {
1163+ hyperPage . _scopeListenerCleanup ( ) ;
11481164 }
11491165
11501166 // History Stack: [Root, Tab1, Tab2, ...]
@@ -1187,27 +1203,32 @@ export class HyperAgent<T extends BrowserProviders = "Local"> {
11871203
11881204 // Attach a persistent listener to track page flow for the lifetime of this wrapper
11891205 page . context ( ) . on ( "page" , onPage ) ;
1190- ( hyperPage as any ) . _scopeListenerCleanup = ( ) => {
1206+ hyperPage . _scopeListenerCleanup = ( ) => {
11911207 page . context ( ) . off ( "page" , onPage ) ;
11921208 } ;
11931209
1194- const executeSingleActionWithRetry = async (
1195- instruction : string ,
1196- params ?: TaskParams
1197- ) => {
1198- const maxRetries = 3 ;
1199- for ( let i = 0 ; i < maxRetries ; i ++ ) {
1200- try {
1201- return await this . executeSingleAction (
1202- instruction ,
1203- getActivePage ,
1204- params
1205- ) ;
1206- } catch ( err : any ) {
1207- if (
1208- err . statusCode === 409 ||
1209- ( err . message && err . message . includes ( "Page context switched" ) )
1210- ) {
1210+ const executeSingleActionWithRetry = async (
1211+ instruction : string ,
1212+ params ?: TaskParams
1213+ ) => {
1214+ const maxRetries = 3 ;
1215+ for ( let i = 0 ; i < maxRetries ; i ++ ) {
1216+ try {
1217+ return await this . executeSingleAction (
1218+ instruction ,
1219+ getActivePage ,
1220+ params
1221+ ) ;
1222+ } catch ( err : unknown ) {
1223+ const maybeError = err as {
1224+ statusCode ?: number ;
1225+ message ?: string ;
1226+ } ;
1227+ if (
1228+ maybeError ?. statusCode === 409 ||
1229+ ( maybeError ?. message &&
1230+ maybeError . message . includes ( "Page context switched" ) )
1231+ ) {
12111232 if ( this . debug ) {
12121233 console . log (
12131234 "[HyperPage] Action aborted due to tab switch, retrying on new page..."
0 commit comments