page-agent 1.5.7 β 1.5.8
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/LICENSE +2 -2
- package/README.md +7 -7
- package/dist/iife/page-agent.demo.js +2 -2
- package/package.json +5 -5
package/LICENSE
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2026
|
|
4
|
-
Copyright (c) 2026
|
|
3
|
+
Copyright (c) 2026 SimonLuvRamen
|
|
4
|
+
Copyright (c) 2026 Alibaba Group Holding Limited
|
|
5
5
|
|
|
6
6
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
7
|
of this software and associated documentation files (the "Software"), to deal
|
package/README.md
CHANGED
|
@@ -5,13 +5,13 @@
|
|
|
5
5
|
<img alt="Page Agent Banner" src="https://img.alicdn.com/imgextra/i1/O1CN01NCMKXj1Gn4tkFTsxf_!!6000000000666-2-tps-1280-256.png">
|
|
6
6
|
</picture>
|
|
7
7
|
|
|
8
|
-
[](https://opensource.org/licenses/MIT) [](http://www.typescriptlang.org/) [](https://bundlephobia.com/package/page-agent) [](https://www.npmjs.com/package/page-agent) [](https://github.com/alibaba/page-agent)
|
|
9
9
|
|
|
10
10
|
The GUI Agent Living in Your Webpage. Control web interfaces with natural language.
|
|
11
11
|
|
|
12
12
|
π **English** | [δΈζ](./docs/README-zh.md)
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
<a href="https://alibaba.github.io/page-agent/" target="_blank"><b>π Demo</b></a> | <a href="https://alibaba.github.io/page-agent/docs/introduction/overview" target="_blank"><b>π Docs</b></a> | <a href="https://news.ycombinator.com/item?id=47264138" target="_blank"><b>π’ HN Discussion</b></a> | <a href="https://x.com/simonluvramen" target="_blank"><b>π Follow on X</b></a>
|
|
15
15
|
|
|
16
16
|
<video id="demo-video" src="https://github.com/user-attachments/assets/a1f2eae2-13fb-4aae-98cf-a3fc1620a6c2" controls crossorigin muted></video>
|
|
17
17
|
|
|
@@ -49,8 +49,8 @@ Fastest way to try PageAgent with our free Demo LLM:
|
|
|
49
49
|
|
|
50
50
|
| Mirrors | URL |
|
|
51
51
|
| ------- | ---------------------------------------------------------------------------------- |
|
|
52
|
-
| Global | https://cdn.jsdelivr.net/npm/page-agent@1.5.
|
|
53
|
-
| China | https://registry.npmmirror.com/page-agent/1.5.
|
|
52
|
+
| Global | https://cdn.jsdelivr.net/npm/page-agent@1.5.8/dist/iife/page-agent.demo.js |
|
|
53
|
+
| China | https://registry.npmmirror.com/page-agent/1.5.8/files/dist/iife/page-agent.demo.js |
|
|
54
54
|
|
|
55
55
|
### NPM Installation
|
|
56
56
|
|
|
@@ -112,8 +112,8 @@ file and in the node_modules directory after installation.
|
|
|
112
112
|
|
|
113
113
|
<a href="https://www.star-history.com/?repos=alibaba%2Fpage-agent&type=date">
|
|
114
114
|
<picture>
|
|
115
|
-
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/image?repos=alibaba/page-agent&type=date&theme=dark&legend=top-left&v=
|
|
116
|
-
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/image?repos=alibaba/page-agent&type=date&legend=top-left&v=
|
|
117
|
-
<img alt="Star History Chart" src="https://api.star-history.com/image?repos=alibaba/page-agent&type=date&legend=top-left&v=
|
|
115
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/image?repos=alibaba/page-agent&type=date&theme=dark&legend=top-left&v=7" />
|
|
116
|
+
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/image?repos=alibaba/page-agent&type=date&legend=top-left&v=7" />
|
|
117
|
+
<img alt="Star History Chart" src="https://api.star-history.com/image?repos=alibaba/page-agent&type=date&legend=top-left&v=7" />
|
|
118
118
|
</picture>
|
|
119
119
|
</a>
|
|
@@ -195,7 +195,7 @@ Here are examples of good output patterns. Use them as reference but never copy
|
|
|
195
195
|
}
|
|
196
196
|
}
|
|
197
197
|
</output>
|
|
198
|
-
`,log=console.log.bind(console,chalk.yellow("[autoFixer]"));function normalizeResponse(e,t){let o=null;const n=e.choices?.[0];if(!n)throw new Error("No choices in response");const r=n.message;if(!r)throw new Error("No message in choice");const i=r.tool_calls?.[0];if(i?.function?.arguments)o=safeJsonParse(i.function.arguments),i.function.name&&i.function.name!=="AgentOutput"&&(log("#1: fixing tool_call"),o={action:safeJsonParse(o)});else if(r.content){const s=r.content.trim(),c=retrieveJsonFromString(s);if(c)o=safeJsonParse(c),o?.name==="AgentOutput"&&(log("#2: fixing tool_call"),o=safeJsonParse(o.arguments)),o?.type==="function"&&(log("#3: fixing tool_call"),o=safeJsonParse(o.function.arguments)),!o?.action&&!o?.evaluation_previous_goal&&!o?.memory&&!o?.next_goal&&!o?.thinking&&(log("#4: fixing tool_call"),o={action:safeJsonParse(o)});else throw new Error("No tool_call and the message content does not contain valid JSON")}else throw new Error("No tool_call nor message content is present");return o=safeJsonParse(o),o.action&&(o.action=safeJsonParse(o.action)),o.action&&t&&(o.action=validateAction(o.action,t)),o.action||(log("#5: fixing tool_call"),o.action={name:"wait",input:{seconds:1}}),{...e,choices:[{...n,message:{...r,tool_calls:[{...i||{},function:{...i?.function||{},name:"AgentOutput",arguments:JSON.stringify(o)}}]}}]}}a(normalizeResponse,"normalizeResponse");function validateAction(e,t){if(typeof e!="object"||e===null)return e;const o=Object.keys(e)[0];if(!o)return e;const n=t.get(o);if(!n){const c=Array.from(t.keys()).join(", ");throw new InvokeError(InvokeErrorType.INVALID_TOOL_ARGS,`Unknown action "${o}". Available: ${c}`)}let r=e[o];const i=n.inputSchema;if(i instanceof ZodObject&&r!==null&&typeof r!="object"){const c=Object.keys(i.shape).find(l=>!i.shape[l].safeParse(void 0).success);c&&(log(`coercing primitive action input for "${o}"`),r={[c]:r})}const s=i.safeParse(r);if(!s.success)throw new InvokeError(InvokeErrorType.INVALID_TOOL_ARGS,`Invalid input for action "${o}": ${prettifyError(s.error)}`);return{[o]:s.data}}a(validateAction,"validateAction");function safeJsonParse(e){if(typeof e=="string")try{return JSON.parse(e.trim())}catch{return e}return e}a(safeJsonParse,"safeJsonParse");function retrieveJsonFromString(e){try{const t=/({[\s\S]*})/.exec(e)??[];return t.length===0?null:JSON.parse(t[0])}catch{return null}}a(retrieveJsonFromString,"retrieveJsonFromString");async function waitFor$1(e){await new Promise(t=>setTimeout(t,e*1e3))}a(waitFor$1,"waitFor$1");function truncate$1(e,t){return e.length>t?e.substring(0,t)+"...":e}a(truncate$1,"truncate$1");function randomID(e){let t=Math.random().toString(36).substring(2,11);if(!e)return t;const o=1e3;let n=0;for(;e.includes(t);)if(t=Math.random().toString(36).substring(2,11),n++,n>o)throw new Error("randomID: too many tries");return t}a(randomID,"randomID");const _global=globalThis;_global.__PAGE_AGENT_IDS__||(_global.__PAGE_AGENT_IDS__=[]);const ids=_global.__PAGE_AGENT_IDS__;function uid(){const e=randomID(ids);return ids.push(e),e}a(uid,"uid");const llmsTxtCache=new Map;async function fetchLlmsTxt(e){let t;try{t=new URL(e).origin}catch{return null}if(t==="null")return null;if(llmsTxtCache.has(t))return llmsTxtCache.get(t);const o=`${t}/llms.txt`;let n=null;try{console.log(chalk.gray(`[llms.txt] Fetching ${o}`));const r=await fetch(o,{signal:AbortSignal.timeout(3e3)});r.ok?(n=await r.text(),console.log(chalk.green(`[llms.txt] Found (${n.length} chars)`)),n.length>1e3&&(console.log(chalk.yellow("[llms.txt] Truncating to 1000 chars")),n=truncate$1(n,1e3))):console.debug(chalk.gray(`[llms.txt] ${r.status} for ${o}`))}catch(r){console.debug(chalk.gray(`[llms.txt] not found for ${o}`),r)}return llmsTxtCache.set(t,n),n}a(fetchLlmsTxt,"fetchLlmsTxt");function assert(e,t,o){if(!e){const n=t??"Assertion failed";throw console.error(chalk.red(`β assert: ${n}`)),new Error(n)}}a(assert,"assert");function tool(e){return e}a(tool,"tool");const tools=new Map;tools.set("done",{description:"Complete task. Text is your final response to the user β keep it concise unless the user explicitly asks for detail.",inputSchema:object({text:string(),success:boolean().default(!0)}),execute:a(async function(e){return Promise.resolve("Task completed")},"execute")}),tools.set("wait",{description:"Wait for x seconds. Can be used to wait until the page or data is fully loaded.",inputSchema:object({seconds:number().min(1).max(10).default(1)}),execute:a(async function(e){const t=await this.pageController.getLastUpdateTime(),o=Math.max(0,e.seconds-(Date.now()-t)/1e3);return console.log(`actualWaitTime: ${o} seconds`),await waitFor$1(o),`β
Waited for ${e.seconds} seconds.`},"execute")}),tools.set("ask_user",{description:"Ask the user a question and wait for their answer. Use this if you need more information or clarification.",inputSchema:object({question:string()}),execute:a(async function(e){if(!this.onAskUser)throw new Error("ask_user tool requires onAskUser callback to be set");return`User answered: ${await this.onAskUser(e.question)}`},"execute")}),tools.set("click_element_by_index",{description:"Click element by index",inputSchema:object({index:int().min(0)}),execute:a(async function(e){return(await this.pageController.clickElement(e.index)).message},"execute")}),tools.set("input_text",{description:"Click and type text into an interactive input element",inputSchema:object({index:int().min(0),text:string()}),execute:a(async function(e){return(await this.pageController.inputText(e.index,e.text)).message},"execute")}),tools.set("select_dropdown_option",{description:"Select dropdown option for interactive element index by the text of the option you want to select",inputSchema:object({index:int().min(0),text:string()}),execute:a(async function(e){return(await this.pageController.selectOption(e.index,e.text)).message},"execute")}),tools.set("scroll",{description:"Scroll the page vertically. Use index for scroll elements (dropdowns/custom UI).",inputSchema:object({down:boolean().default(!0),num_pages:number().min(0).max(10).optional().default(.1),pixels:number().int().min(0).optional(),index:number().int().min(0).optional()}),execute:a(async function(e){return(await this.pageController.scroll({...e,numPages:e.num_pages})).message},"execute")}),tools.set("scroll_horizontally",{description:"Scroll the page horizontally, or within a specific element by index. Useful for wide tables.",inputSchema:object({right:boolean().default(!0),pixels:number().int().min(0),index:number().int().min(0).optional()}),execute:a(async function(e){return(await this.pageController.scrollHorizontally(e)).message},"execute")}),tools.set("execute_javascript",{description:"Execute JavaScript code on the current page. Supports async/await syntax. Use with caution!",inputSchema:object({script:string()}),execute:a(async function(e){return(await this.pageController.executeJavascript(e.script)).message},"execute")});const ut=class ut extends EventTarget{constructor(o){super();Z(this,R);oe(this,"id",uid());oe(this,"config");oe(this,"tools");oe(this,"pageController");oe(this,"task","");oe(this,"taskId","");oe(this,"history",[]);oe(this,"disposed",!1);oe(this,"onAskUser");Z(this,Ue,"idle");Z(this,Oe);Z(this,se,new AbortController);Z(this,Ee,[]);Z(this,X,{totalWaitTime:0,lastURL:"",browserState:null});if(this.config={...o,maxSteps:o.maxSteps??40},S(this,Oe,new LLM(this.config)),this.tools=new Map(tools),this.pageController=o.pageController,p(this,Oe).addEventListener("retry",n=>{const{attempt:r,maxAttempts:i}=n.detail;b(this,R,Me).call(this,{type:"retrying",attempt:r,maxAttempts:i}),this.history.push({type:"retry",message:`LLM retry attempt ${r} of ${i}`,attempt:r,maxAttempts:i}),b(this,R,Pe).call(this)}),p(this,Oe).addEventListener("error",n=>{const r=n.detail.error;if(r?.rawError?.name==="AbortError")return;const i=String(r);b(this,R,Me).call(this,{type:"error",message:i}),this.history.push({type:"error",message:i,rawResponse:r.rawResponse}),b(this,R,Pe).call(this)}),this.config.customTools)for(const[n,r]of Object.entries(this.config.customTools)){if(r===null){this.tools.delete(n);continue}this.tools.set(n,r)}this.config.experimentalScriptExecutionTool||this.tools.delete("execute_javascript")}get status(){return p(this,Ue)}pushObservation(o){p(this,Ee).push(o)}stop(){this.pageController.cleanUpHighlights(),this.pageController.hideMask(),p(this,se).abort()}async execute(o){if(this.disposed)throw new Error("PageAgent has been disposed. Create a new instance.");if(!o)throw new Error("Task is required");this.task=o,this.taskId=uid(),this.onAskUser||this.tools.delete("ask_user");const n=this.config.onBeforeStep,r=this.config.onAfterStep,i=this.config.onBeforeTask,s=this.config.onAfterTask;await i?.(this),await this.pageController.showMask(),p(this,se)&&(p(this,se).abort(),S(this,se,new AbortController)),this.history=[],b(this,R,_t).call(this,"running"),b(this,R,Pe).call(this),S(this,Ee,[]),S(this,X,{totalWaitTime:0,lastURL:"",browserState:null});let c=0;for(;;){try{console.group(`step: ${c}`),await n?.(this,c),console.log(chalk.blue.bold("π Observing...")),p(this,X).browserState=await this.pageController.getBrowserState(),await b(this,R,At).call(this,c);const l=[{role:"system",content:b(this,R,It).call(this)},{role:"user",content:await b(this,R,Pt).call(this)}],d={AgentOutput:b(this,R,Tt).call(this)};console.log(chalk.blue.bold("π§ Thinking...")),b(this,R,Me).call(this,{type:"thinking"});const h=await p(this,Oe).invoke(l,d,p(this,se).signal,{toolChoiceName:"AgentOutput",normalizeResponse:a(C=>normalizeResponse(C,this.tools),"normalizeResponse")}),f=h.toolResult,g=f.input,m=f.output,T={evaluation_previous_goal:g.evaluation_previous_goal,memory:g.memory,next_goal:g.next_goal},I=Object.keys(g.action)[0],A={name:I,input:g.action[I],output:m};if(this.history.push({type:"step",stepIndex:c,reflection:T,action:A,usage:h.usage,rawResponse:h.rawResponse,rawRequest:h.rawRequest}),b(this,R,Pe).call(this),await r?.(this,this.history),console.groupEnd(),I==="done"){const C=A.input?.success??!1,D=A.input?.text||"no text provided";console.log(chalk.green.bold("Task completed"),C,D),b(this,R,st).call(this,C);const v={success:C,data:D,history:this.history};return await s?.(this,v),v}}catch(l){console.groupEnd();const d=l?.rawError?.name==="AbortError";console.error("Task failed",l);const h=d?"Task stopped":String(l);b(this,R,Me).call(this,{type:"error",message:h}),this.history.push({type:"error",message:h,rawResponse:l}),b(this,R,Pe).call(this),b(this,R,st).call(this,!1);const f={success:!1,data:h,history:this.history};return await s?.(this,f),f}if(c++,c>this.config.maxSteps){const l="Step count exceeded maximum limit";this.history.push({type:"error",message:l}),b(this,R,Pe).call(this),b(this,R,st).call(this,!1);const d={success:!1,data:l,history:this.history};return await s?.(this,d),d}await waitFor$1(.4)}}dispose(){console.log("Disposing PageAgent..."),this.disposed=!0,this.pageController.dispose(),p(this,se).abort(),this.dispatchEvent(new Event("dispose")),this.config.onDispose?.(this)}};Ue=new WeakMap,Oe=new WeakMap,se=new WeakMap,Ee=new WeakMap,X=new WeakMap,R=new WeakSet,St=a(function(){this.dispatchEvent(new Event("statuschange"))},"#emitStatusChange"),Pe=a(function(){this.dispatchEvent(new Event("historychange"))},"#emitHistoryChange"),Me=a(function(o){this.dispatchEvent(new CustomEvent("activity",{detail:o}))},"#emitActivity"),_t=a(function(o){p(this,Ue)!==o&&(S(this,Ue,o),b(this,R,St).call(this))},"#setStatus"),Tt=a(function(){const o=this.tools,n=Array.from(o.entries()).map(([s,c])=>object({[s]:c.inputSchema}).describe(c.description)),r=union(n);return{description:"You MUST call this tool every step!",inputSchema:object({evaluation_previous_goal:string().optional(),memory:string().optional(),next_goal:string().optional(),action:r}),execute:a(async s=>{if(p(this,se).signal.aborted)throw new Error("AbortError");console.log(chalk.blue.bold("MacroTool input"),s);const c=s.action,l=Object.keys(c)[0],d=c[l],h=[];s.evaluation_previous_goal&&h.push(`β
: ${s.evaluation_previous_goal}`),s.memory&&h.push(`πΎ: ${s.memory}`),s.next_goal&&h.push(`π―: ${s.next_goal}`);const f=h.length>0?h.join(`
|
|
198
|
+
`,log=console.log.bind(console,chalk.yellow("[autoFixer]"));function normalizeResponse(e,t){let o=null;const n=e.choices?.[0];if(!n)throw new Error("No choices in response");const r=n.message;if(!r)throw new Error("No message in choice");const i=r.tool_calls?.[0];if(i?.function?.arguments)o=safeJsonParse(i.function.arguments),i.function.name&&i.function.name!=="AgentOutput"&&(log("#1: fixing tool_call"),o={action:safeJsonParse(o)});else if(r.content){const s=r.content.trim(),c=retrieveJsonFromString(s);if(c)o=safeJsonParse(c),o?.name==="AgentOutput"&&(log("#2: fixing tool_call"),o=safeJsonParse(o.arguments)),o?.type==="function"&&(log("#3: fixing tool_call"),o=safeJsonParse(o.function.arguments)),!o?.action&&!o?.evaluation_previous_goal&&!o?.memory&&!o?.next_goal&&!o?.thinking&&(log("#4: fixing tool_call"),o={action:safeJsonParse(o)});else throw new Error("No tool_call and the message content does not contain valid JSON")}else throw new Error("No tool_call nor message content is present");return o=safeJsonParse(o),o.action&&(o.action=safeJsonParse(o.action)),o.action&&t&&(o.action=validateAction(o.action,t)),o.action||(log("#5: fixing tool_call"),o.action={name:"wait",input:{seconds:1}}),{...e,choices:[{...n,message:{...r,tool_calls:[{...i||{},function:{...i?.function||{},name:"AgentOutput",arguments:JSON.stringify(o)}}]}}]}}a(normalizeResponse,"normalizeResponse");function validateAction(e,t){if(typeof e!="object"||e===null)return e;const o=Object.keys(e)[0];if(!o)return e;const n=t.get(o);if(!n){const c=Array.from(t.keys()).join(", ");throw new InvokeError(InvokeErrorType.INVALID_TOOL_ARGS,`Unknown action "${o}". Available: ${c}`)}let r=e[o];const i=n.inputSchema;if(i instanceof ZodObject&&r!==null&&typeof r!="object"){const c=Object.keys(i.shape).find(l=>!i.shape[l].safeParse(void 0).success);c&&(log(`coercing primitive action input for "${o}"`),r={[c]:r})}const s=i.safeParse(r);if(!s.success)throw new InvokeError(InvokeErrorType.INVALID_TOOL_ARGS,`Invalid input for action "${o}": ${prettifyError(s.error)}`);return{[o]:s.data}}a(validateAction,"validateAction");function safeJsonParse(e){if(typeof e=="string")try{return JSON.parse(e.trim())}catch{return e}return e}a(safeJsonParse,"safeJsonParse");function retrieveJsonFromString(e){try{const t=/({[\s\S]*})/.exec(e)??[];return t.length===0?null:JSON.parse(t[0])}catch{return null}}a(retrieveJsonFromString,"retrieveJsonFromString");async function waitFor$1(e){await new Promise(t=>setTimeout(t,e*1e3))}a(waitFor$1,"waitFor$1");function truncate$1(e,t){return e.length>t?e.substring(0,t)+"...":e}a(truncate$1,"truncate$1");function randomID(e){let t=Math.random().toString(36).substring(2,11);if(!e)return t;const o=1e3;let n=0;for(;e.includes(t);)if(t=Math.random().toString(36).substring(2,11),n++,n>o)throw new Error("randomID: too many tries");return t}a(randomID,"randomID");const _global=globalThis;_global.__PAGE_AGENT_IDS__||(_global.__PAGE_AGENT_IDS__=[]);const ids=_global.__PAGE_AGENT_IDS__;function uid(){const e=randomID(ids);return ids.push(e),e}a(uid,"uid");const llmsTxtCache=new Map;async function fetchLlmsTxt(e){let t;try{t=new URL(e).origin}catch{return null}if(t==="null")return null;if(llmsTxtCache.has(t))return llmsTxtCache.get(t);const o=`${t}/llms.txt`;let n=null;try{console.log(chalk.gray(`[llms.txt] Fetching ${o}`));const r=await fetch(o,{signal:AbortSignal.timeout(3e3)});r.ok?(n=await r.text(),console.log(chalk.green(`[llms.txt] Found (${n.length} chars)`)),n.length>1e3&&(console.log(chalk.yellow("[llms.txt] Truncating to 1000 chars")),n=truncate$1(n,1e3))):console.debug(chalk.gray(`[llms.txt] ${r.status} for ${o}`))}catch(r){console.debug(chalk.gray(`[llms.txt] not found for ${o}`),r)}return llmsTxtCache.set(t,n),n}a(fetchLlmsTxt,"fetchLlmsTxt");function assert(e,t,o){if(!e){const n=t??"Assertion failed";throw console.error(chalk.red(`β assert: ${n}`)),new Error(n)}}a(assert,"assert");function tool(e){return e}a(tool,"tool");const tools=new Map;tools.set("done",{description:"Complete task. Text is your final response to the user β keep it concise unless the user explicitly asks for detail.",inputSchema:object({text:string(),success:boolean().default(!0)}),execute:a(async function(e){return Promise.resolve("Task completed")},"execute")}),tools.set("wait",{description:"Wait for x seconds. Can be used to wait until the page or data is fully loaded.",inputSchema:object({seconds:number().min(1).max(10).default(1)}),execute:a(async function(e){const t=await this.pageController.getLastUpdateTime(),o=Math.max(0,e.seconds-(Date.now()-t)/1e3);return console.log(`actualWaitTime: ${o} seconds`),await waitFor$1(o),`β
Waited for ${e.seconds} seconds.`},"execute")}),tools.set("ask_user",{description:"Ask the user a question and wait for their answer. Use this if you need more information or clarification.",inputSchema:object({question:string()}),execute:a(async function(e){if(!this.onAskUser)throw new Error("ask_user tool requires onAskUser callback to be set");return`User answered: ${await this.onAskUser(e.question)}`},"execute")}),tools.set("click_element_by_index",{description:"Click element by index",inputSchema:object({index:int().min(0)}),execute:a(async function(e){return(await this.pageController.clickElement(e.index)).message},"execute")}),tools.set("input_text",{description:"Click and type text into an interactive input element",inputSchema:object({index:int().min(0),text:string()}),execute:a(async function(e){return(await this.pageController.inputText(e.index,e.text)).message},"execute")}),tools.set("select_dropdown_option",{description:"Select dropdown option for interactive element index by the text of the option you want to select",inputSchema:object({index:int().min(0),text:string()}),execute:a(async function(e){return(await this.pageController.selectOption(e.index,e.text)).message},"execute")}),tools.set("scroll",{description:"Scroll the page vertically. Use index for scroll elements (dropdowns/custom UI).",inputSchema:object({down:boolean().default(!0),num_pages:number().min(0).max(10).optional().default(.1),pixels:number().int().min(0).optional(),index:number().int().min(0).optional()}),execute:a(async function(e){return(await this.pageController.scroll({...e,numPages:e.num_pages})).message},"execute")}),tools.set("scroll_horizontally",{description:"Scroll the page horizontally, or within a specific element by index. Useful for wide tables.",inputSchema:object({right:boolean().default(!0),pixels:number().int().min(0),index:number().int().min(0).optional()}),execute:a(async function(e){return(await this.pageController.scrollHorizontally(e)).message},"execute")}),tools.set("execute_javascript",{description:"Execute JavaScript code on the current page. Supports async/await syntax. Use with caution!",inputSchema:object({script:string()}),execute:a(async function(e){return(await this.pageController.executeJavascript(e.script)).message},"execute")});const ut=class ut extends EventTarget{constructor(o){super();Z(this,R);oe(this,"id",uid());oe(this,"config");oe(this,"tools");oe(this,"pageController");oe(this,"task","");oe(this,"taskId","");oe(this,"history",[]);oe(this,"disposed",!1);oe(this,"onAskUser");Z(this,Ue,"idle");Z(this,Oe);Z(this,se,new AbortController);Z(this,Ee,[]);Z(this,X,{totalWaitTime:0,lastURL:"",browserState:null});if(this.config={...o,maxSteps:o.maxSteps??40},S(this,Oe,new LLM(this.config)),this.tools=new Map(tools),this.pageController=o.pageController,p(this,Oe).addEventListener("retry",n=>{const{attempt:r,maxAttempts:i}=n.detail;b(this,R,Me).call(this,{type:"retrying",attempt:r,maxAttempts:i}),this.history.push({type:"retry",message:`LLM retry attempt ${r} of ${i}`,attempt:r,maxAttempts:i}),b(this,R,Pe).call(this)}),p(this,Oe).addEventListener("error",n=>{const r=n.detail.error;if(r?.rawError?.name==="AbortError")return;const i=String(r);b(this,R,Me).call(this,{type:"error",message:i}),this.history.push({type:"error",message:i,rawResponse:r.rawResponse}),b(this,R,Pe).call(this)}),this.config.customTools)for(const[n,r]of Object.entries(this.config.customTools)){if(r===null){this.tools.delete(n);continue}this.tools.set(n,r)}this.config.experimentalScriptExecutionTool||this.tools.delete("execute_javascript")}get status(){return p(this,Ue)}pushObservation(o){p(this,Ee).push(o)}stop(){this.pageController.cleanUpHighlights(),this.pageController.hideMask(),p(this,se).abort()}async execute(o){if(this.disposed)throw new Error("PageAgent has been disposed. Create a new instance.");if(!o)throw new Error("Task is required");this.task=o,this.taskId=uid(),this.onAskUser||this.tools.delete("ask_user");const n=this.config.onBeforeStep,r=this.config.onAfterStep,i=this.config.onBeforeTask,s=this.config.onAfterTask;await i?.(this),await this.pageController.showMask(),p(this,se)&&(p(this,se).abort(),S(this,se,new AbortController)),this.history=[],b(this,R,_t).call(this,"running"),b(this,R,Pe).call(this),S(this,Ee,[]),S(this,X,{totalWaitTime:0,lastURL:"",browserState:null});let c=0;for(;;){try{console.group(`step: ${c}`),await n?.(this,c),console.log(chalk.blue.bold("π Observing...")),p(this,X).browserState=await this.pageController.getBrowserState(),await b(this,R,At).call(this,c);const l=[{role:"system",content:b(this,R,It).call(this)},{role:"user",content:await b(this,R,Pt).call(this)}],d={AgentOutput:b(this,R,Tt).call(this)};console.log(chalk.blue.bold("π§ Thinking...")),b(this,R,Me).call(this,{type:"thinking"});const h=await p(this,Oe).invoke(l,d,p(this,se).signal,{toolChoiceName:"AgentOutput",normalizeResponse:a(C=>normalizeResponse(C,this.tools),"normalizeResponse")}),f=h.toolResult,g=f.input,m=f.output,T={evaluation_previous_goal:g.evaluation_previous_goal,memory:g.memory,next_goal:g.next_goal},I=Object.keys(g.action)[0],A={name:I,input:g.action[I],output:m};if(this.history.push({type:"step",stepIndex:c,reflection:T,action:A,usage:h.usage,rawResponse:h.rawResponse,rawRequest:h.rawRequest}),b(this,R,Pe).call(this),await r?.(this,this.history),console.groupEnd(),I==="done"){const C=A.input?.success??!1,D=A.input?.text||"no text provided";console.log(chalk.green.bold("Task completed"),C,D),b(this,R,st).call(this,C);const v={success:C,data:D,history:this.history};return await s?.(this,v),v}}catch(l){console.groupEnd();const d=l?.rawError?.name==="AbortError";console.error("Task failed",l);const h=d?"Task stopped":String(l);b(this,R,Me).call(this,{type:"error",message:h}),this.history.push({type:"error",message:h,rawResponse:l}),b(this,R,Pe).call(this),b(this,R,st).call(this,!1);const f={success:!1,data:h,history:this.history};return await s?.(this,f),f}if(c++,c>this.config.maxSteps){const l="Step count exceeded maximum limit";this.history.push({type:"error",message:l}),b(this,R,Pe).call(this),b(this,R,st).call(this,!1);const d={success:!1,data:l,history:this.history};return await s?.(this,d),d}await waitFor$1(this.config.stepDelay??.4)}}dispose(){console.log("Disposing PageAgent..."),this.disposed=!0,this.pageController.dispose(),p(this,se).abort(),this.dispatchEvent(new Event("dispose")),this.config.onDispose?.(this)}};Ue=new WeakMap,Oe=new WeakMap,se=new WeakMap,Ee=new WeakMap,X=new WeakMap,R=new WeakSet,St=a(function(){this.dispatchEvent(new Event("statuschange"))},"#emitStatusChange"),Pe=a(function(){this.dispatchEvent(new Event("historychange"))},"#emitHistoryChange"),Me=a(function(o){this.dispatchEvent(new CustomEvent("activity",{detail:o}))},"#emitActivity"),_t=a(function(o){p(this,Ue)!==o&&(S(this,Ue,o),b(this,R,St).call(this))},"#setStatus"),Tt=a(function(){const o=this.tools,n=Array.from(o.entries()).map(([s,c])=>object({[s]:c.inputSchema}).describe(c.description)),r=union(n);return{description:"You MUST call this tool every step!",inputSchema:object({evaluation_previous_goal:string().optional(),memory:string().optional(),next_goal:string().optional(),action:r}),execute:a(async s=>{if(p(this,se).signal.aborted)throw new Error("AbortError");console.log(chalk.blue.bold("MacroTool input"),s);const c=s.action,l=Object.keys(c)[0],d=c[l],h=[];s.evaluation_previous_goal&&h.push(`β
: ${s.evaluation_previous_goal}`),s.memory&&h.push(`πΎ: ${s.memory}`),s.next_goal&&h.push(`π―: ${s.next_goal}`);const f=h.length>0?h.join(`
|
|
199
199
|
`):"";f&&console.log(f);const g=o.get(l);assert(g,`Tool ${l} not found`),console.log(chalk.blue.bold(`Executing tool: ${l}`),d),b(this,R,Me).call(this,{type:"executing",tool:l,input:d});const m=Date.now(),T=await g.execute.bind(this)(d),I=Date.now()-m;return console.log(chalk.green.bold(`Tool (${l}) executed for ${I}ms`),T),b(this,R,Me).call(this,{type:"executed",tool:l,input:d,output:T,duration:I}),l==="wait"?p(this,X).totalWaitTime+=d?.seconds||0:p(this,X).totalWaitTime=0,{input:s,output:T}},"execute")}},"#packMacroTool"),It=a(function(){if(this.config.customSystemPrompt)return this.config.customSystemPrompt;const o=this.config.language==="zh-CN"?"δΈζ":"English";return SYSTEM_PROMPT.replace(/Default working language: \*\*.*?\*\*/,`Default working language: **${o}**`)},"#getSystemPrompt"),zt=a(async function(){const{instructions:o,experimentalLlmsTxt:n}=this.config,r=o?.system?.trim();let i;const s=p(this,X).browserState?.url||"";if(o?.getPageInstructions&&s)try{i=o.getPageInstructions(s)?.trim()}catch(d){console.error(chalk.red("[PageAgent] Failed to execute getPageInstructions callback:"),d)}const c=n&&s?await fetchLlmsTxt(s):void 0;if(!r&&!i&&!c)return"";let l=`<instructions>
|
|
200
200
|
`;return r&&(l+=`<system_instructions>
|
|
201
201
|
${r}
|
|
@@ -236,7 +236,7 @@ ${c}
|
|
|
236
236
|
|
|
237
237
|
`,n+=`</browser_state>
|
|
238
238
|
|
|
239
|
-
`,n},"#assembleUserPrompt"),st=a(function(o=!0){this.pageController.cleanUpHighlights(),this.pageController.hideMask(),b(this,R,_t).call(this,o?"completed":"error"),p(this,se).abort()},"#onDone"),a(ut,"PageAgentCore");let PageAgentCore=ut;async function waitFor(e){await new Promise(t=>setTimeout(t,e*1e3))}a(waitFor,"waitFor");async function movePointerToElement(e){const t=e.getBoundingClientRect(),o=t.left+t.width/2,n=t.top+t.height/2;window.dispatchEvent(new CustomEvent("PageAgent::MovePointerTo",{detail:{x:o,y:n}})),await waitFor(.3)}a(movePointerToElement,"movePointerToElement");function getElementByIndex(e,t){const o=e.get(t);if(!o)throw new Error(`No interactive element found at index ${t}`);const n=o.ref;if(!n)throw new Error(`Element at index ${t} does not have a reference`);if(!(n instanceof HTMLElement))throw new Error(`Element at index ${t} is not an HTMLElement`);return n}a(getElementByIndex,"getElementByIndex");let lastClickedElement=null;function blurLastClickedElement(){lastClickedElement&&(lastClickedElement.blur(),lastClickedElement.dispatchEvent(new MouseEvent("mouseout",{bubbles:!0,cancelable:!0})),lastClickedElement=null)}a(blurLastClickedElement,"blurLastClickedElement");async function clickElement(e){blurLastClickedElement(),lastClickedElement=e,await scrollIntoViewIfNeeded(e),await movePointerToElement(e),window.dispatchEvent(new CustomEvent("PageAgent::ClickPointer")),await waitFor(.1),e.dispatchEvent(new MouseEvent("mouseenter",{bubbles:!0,cancelable:!0})),e.dispatchEvent(new MouseEvent("mouseover",{bubbles:!0,cancelable:!0})),e.dispatchEvent(new MouseEvent("mousedown",{bubbles:!0,cancelable:!0})),e.focus(),e.dispatchEvent(new MouseEvent("mouseup",{bubbles:!0,cancelable:!0})),e.dispatchEvent(new MouseEvent("click",{bubbles:!0,cancelable:!0})),await waitFor(.2)}a(clickElement,"clickElement");const nativeInputValueSetter=Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype,"value").set,nativeTextAreaValueSetter=Object.getOwnPropertyDescriptor(window.HTMLTextAreaElement.prototype,"value").set;async function inputTextElement(e,t){const o=e.isContentEditable;if(!(e instanceof HTMLInputElement)&&!(e instanceof HTMLTextAreaElement)&&!o)throw new Error("Element is not an input, textarea, or contenteditable");await clickElement(e),o?(e.dispatchEvent(new InputEvent("beforeinput",{bubbles:!0,cancelable:!0,inputType:"deleteContent"}))&&(e.innerText="",e.dispatchEvent(new InputEvent("input",{bubbles:!0,inputType:"deleteContent"}))),e.dispatchEvent(new InputEvent("beforeinput",{bubbles:!0,cancelable:!0,inputType:"insertText",data:t}))&&(e.innerText=t,e.dispatchEvent(new InputEvent("input",{bubbles:!0,inputType:"insertText",data:t}))),e.dispatchEvent(new Event("change",{bubbles:!0})),e.blur()):e instanceof HTMLTextAreaElement?nativeTextAreaValueSetter.call(e,t):nativeInputValueSetter.call(e,t),o||e.dispatchEvent(new Event("input",{bubbles:!0})),await waitFor(.1),blurLastClickedElement()}a(inputTextElement,"inputTextElement");async function selectOptionElement(e,t){if(!(e instanceof HTMLSelectElement))throw new Error("Element is not a select element");const n=Array.from(e.options).find(r=>r.textContent?.trim()===t.trim());if(!n)throw new Error(`Option with text "${t}" not found in select element`);e.value=n.value,e.dispatchEvent(new Event("change",{bubbles:!0})),await waitFor(.1)}a(selectOptionElement,"selectOptionElement");async function scrollIntoViewIfNeeded(e){const t=e;t.scrollIntoViewIfNeeded?t.scrollIntoViewIfNeeded():t.scrollIntoView({behavior:"auto",block:"center",inline:"nearest"})}a(scrollIntoViewIfNeeded,"scrollIntoViewIfNeeded");async function scrollVertically(e,t,o){if(o){const c=o;let l=c,d=!1,h=null,f=0,g=0;const m=t;for(;l&&g<10;){const T=window.getComputedStyle(l),I=/(auto|scroll|overlay)/.test(T.overflowY),A=l.scrollHeight>l.clientHeight;if(I&&A){const C=l.scrollTop,D=l.scrollHeight-l.clientHeight;let v=m/3;v>0?v=Math.min(v,D-C):v=Math.max(v,-C),l.scrollTop=C+v;const O=l.scrollTop-C;if(Math.abs(O)>.5){d=!0,h=l,f=O;break}}if(l===document.body||l===document.documentElement)break;l=l.parentElement,g++}return d?`Scrolled container (${h?.tagName}) by ${f}px`:`No scrollable container found for element (${c.tagName})`}const n=t,r=a(c=>c.clientHeight>=window.innerHeight*.5,"bigEnough"),i=a(c=>c&&/(auto|scroll|overlay)/.test(getComputedStyle(c).overflowY)&&c.scrollHeight>c.clientHeight&&r(c),"canScroll");let s=document.activeElement;for(;s&&!i(s)&&s!==document.body;)s=s.parentElement;if(s=i(s)?s:Array.from(document.querySelectorAll("*")).find(i)||document.scrollingElement||document.documentElement,s===document.scrollingElement||s===document.documentElement||s===document.body){const c=window.scrollY,l=document.documentElement.scrollHeight-window.innerHeight;window.scrollBy(0,n);const d=window.scrollY,h=d-c;if(Math.abs(h)<1)return n>0?"β οΈ Already at the bottom of the page, cannot scroll down further.":"β οΈ Already at the top of the page, cannot scroll up further.";const f=n>0&&d>=l-1,g=n<0&&d<=1;return f?`β
Scrolled page by ${h}px. Reached the bottom of the page.`:g?`β
Scrolled page by ${h}px. Reached the top of the page.`:`β
Scrolled page by ${h}px.`}else{const c=s.scrollTop,l=s.scrollHeight-s.clientHeight;s.scrollBy({top:n,behavior:"smooth"}),await waitFor(.1);const d=s.scrollTop,h=d-c;if(Math.abs(h)<1)return n>0?`β οΈ Already at the bottom of container (${s.tagName}), cannot scroll down further.`:`β οΈ Already at the top of container (${s.tagName}), cannot scroll up further.`;const f=n>0&&d>=l-1,g=n<0&&d<=1;return f?`β
Scrolled container (${s.tagName}) by ${h}px. Reached the bottom.`:g?`β
Scrolled container (${s.tagName}) by ${h}px. Reached the top.`:`β
Scrolled container (${s.tagName}) by ${h}px.`}}a(scrollVertically,"scrollVertically");async function scrollHorizontally(e,t,o){if(o){const c=o;let l=c,d=!1,h=null,f=0,g=0;const m=e?t:-t;for(;l&&g<10;){const T=window.getComputedStyle(l),I=/(auto|scroll|overlay)/.test(T.overflowX),A=l.scrollWidth>l.clientWidth;if(I&&A){const C=l.scrollLeft,D=l.scrollWidth-l.clientWidth;let v=m/3;v>0?v=Math.min(v,D-C):v=Math.max(v,-C),l.scrollLeft=C+v;const O=l.scrollLeft-C;if(Math.abs(O)>.5){d=!0,h=l,f=O;break}}if(l===document.body||l===document.documentElement)break;l=l.parentElement,g++}return d?`Scrolled container (${h?.tagName}) horizontally by ${f}px`:`No horizontally scrollable container found for element (${c.tagName})`}const n=e?t:-t,r=a(c=>c.clientWidth>=window.innerWidth*.5,"bigEnough"),i=a(c=>c&&/(auto|scroll|overlay)/.test(getComputedStyle(c).overflowX)&&c.scrollWidth>c.clientWidth&&r(c),"canScroll");let s=document.activeElement;for(;s&&!i(s)&&s!==document.body;)s=s.parentElement;if(s=i(s)?s:Array.from(document.querySelectorAll("*")).find(i)||document.scrollingElement||document.documentElement,s===document.scrollingElement||s===document.documentElement||s===document.body){const c=window.scrollX,l=document.documentElement.scrollWidth-window.innerWidth;window.scrollBy(n,0);const d=window.scrollX,h=d-c;if(Math.abs(h)<1)return n>0?"β οΈ Already at the right edge of the page, cannot scroll right further.":"β οΈ Already at the left edge of the page, cannot scroll left further.";const f=n>0&&d>=l-1,g=n<0&&d<=1;return f?`β
Scrolled page by ${h}px. Reached the right edge of the page.`:g?`β
Scrolled page by ${h}px. Reached the left edge of the page.`:`β
Scrolled page horizontally by ${h}px.`}else{const c=s.scrollLeft,l=s.scrollWidth-s.clientWidth;s.scrollBy({left:n,behavior:"smooth"}),await waitFor(.1);const d=s.scrollLeft,h=d-c;if(Math.abs(h)<1)return n>0?`β οΈ Already at the right edge of container (${s.tagName}), cannot scroll right further.`:`β οΈ Already at the left edge of container (${s.tagName}), cannot scroll left further.`;const f=n>0&&d>=l-1,g=n<0&&d<=1;return f?`β
Scrolled container (${s.tagName}) by ${h}px. Reached the right edge.`:g?`β
Scrolled container (${s.tagName}) by ${h}px. Reached the left edge.`:`β
Scrolled container (${s.tagName}) horizontally by ${h}px.`}}a(scrollHorizontally,"scrollHorizontally");const domTree=a((e={doHighlightElements:!0,focusHighlightIndex:-1,viewportExpansion:0,debugMode:!1,interactiveBlacklist:[],interactiveWhitelist:[],highlightOpacity:.1,highlightLabelOpacity:.5})=>{const{interactiveBlacklist:t,interactiveWhitelist:o,highlightOpacity:n,highlightLabelOpacity:r}=e,{doHighlightElements:i,focusHighlightIndex:s,viewportExpansion:c,debugMode:l}=e;let d=0;const h=new WeakMap;function f(u,y){!u||u.nodeType!==Node.ELEMENT_NODE||h.set(u,{...h.get(u),...y})}a(f,"addExtraData");const g={boundingRects:new WeakMap,clientRects:new WeakMap,computedStyles:new WeakMap,clearCache:a(()=>{g.boundingRects=new WeakMap,g.clientRects=new WeakMap,g.computedStyles=new WeakMap},"clearCache")};function m(u){if(!u)return null;if(g.boundingRects.has(u))return g.boundingRects.get(u);const y=u.getBoundingClientRect();return y&&g.boundingRects.set(u,y),y}a(m,"getCachedBoundingRect");function T(u){if(!u)return null;if(g.computedStyles.has(u))return g.computedStyles.get(u);const y=window.getComputedStyle(u);return y&&g.computedStyles.set(u,y),y}a(T,"getCachedComputedStyle");function I(u){if(!u)return null;if(g.clientRects.has(u))return g.clientRects.get(u);const y=u.getClientRects();return y&&g.clientRects.set(u,y),y}a(I,"getCachedClientRects");const A={},C={current:0},D="playwright-highlight-container";function v(u,y,P=null){if(!u)return y;const w=[];let E=null,N=20,x=16,z=null;try{let $=document.getElementById(D);$||($=document.createElement("div"),$.id=D,$.style.position="fixed",$.style.pointerEvents="none",$.style.top="0",$.style.left="0",$.style.width="100%",$.style.height="100%",$.style.zIndex="2147483640",$.style.backgroundColor="transparent",document.body.appendChild($));const L=u.getClientRects();if(!L||L.length===0)return y;const Y=["#FF0000","#00FF00","#0000FF","#FFA500","#800080","#008080","#FF69B4","#4B0082","#FF4500","#2E8B57","#DC143C","#4682B4"],J=y%Y.length;let ze=Y[J];const ee=ze+Math.floor(n*255).toString(16).padStart(2,"0");ze=ze+Math.floor(r*255).toString(16).padStart(2,"0");let re={x:0,y:0};if(P){const V=P.getBoundingClientRect();re.x=V.left,re.y=V.top}const ge=document.createDocumentFragment();for(const V of L){if(V.width===0||V.height===0)continue;const G=document.createElement("div");G.style.position="fixed",G.style.border=`2px solid ${ze}`,G.style.backgroundColor=ee,G.style.pointerEvents="none",G.style.boxSizing="border-box";const U=V.top+re.y,ke=V.left+re.x;G.style.top=`${U}px`,G.style.left=`${ke}px`,G.style.width=`${V.width}px`,G.style.height=`${V.height}px`,ge.appendChild(G),w.push({element:G,initialRect:V})}const me=L[0];E=document.createElement("div"),E.className="playwright-highlight-label",E.style.position="fixed",E.style.background=ze,E.style.color="white",E.style.padding="1px 4px",E.style.borderRadius="4px",E.style.fontSize=`${Math.min(12,Math.max(8,me.height/2))}px`,E.textContent=y.toString(),N=E.offsetWidth>0?E.offsetWidth:N,x=E.offsetHeight>0?E.offsetHeight:x;const Le=me.top+re.y,et=me.left+re.x;let nt=Le+2,We=et+me.width-N-2;(me.width<N+4||me.height<x+4)&&(nt=Le-x-2,We=et+me.width-N,We<re.x&&(We=et)),nt=Math.max(0,Math.min(nt,window.innerHeight-x)),We=Math.max(0,Math.min(We,window.innerWidth-N)),E.style.top=`${nt}px`,E.style.left=`${We}px`,ge.appendChild(E);const rt=a((V,G)=>{let U=0;return(...ke)=>{const te=performance.now();if(!(te-U<G))return U=te,V(...ke)}},"throttleFunction")(a(()=>{const V=u.getClientRects();let G={x:0,y:0};if(P){const U=P.getBoundingClientRect();G.x=U.left,G.y=U.top}if(w.forEach((U,ke)=>{if(ke<V.length){const te=V[ke],Ve=te.top+G.y,Ae=te.left+G.x;U.element.style.top=`${Ve}px`,U.element.style.left=`${Ae}px`,U.element.style.width=`${te.width}px`,U.element.style.height=`${te.height}px`,U.element.style.display=te.width===0||te.height===0?"none":"block"}else U.element.style.display="none"}),V.length<w.length)for(let U=V.length;U<w.length;U++)w[U].element.style.display="none";if(E&&V.length>0){const U=V[0],ke=U.top+G.y,te=U.left+G.x;let Ve=ke+2,Ae=te+U.width-N-2;(U.width<N+4||U.height<x+4)&&(Ve=ke-x-2,Ae=te+U.width-N,Ae<G.x&&(Ae=te)),Ve=Math.max(0,Math.min(Ve,window.innerHeight-x)),Ae=Math.max(0,Math.min(Ae,window.innerWidth-N)),E.style.top=`${Ve}px`,E.style.left=`${Ae}px`,E.style.display="block"}else E&&(E.style.display="none")},"updatePositions"),16);return window.addEventListener("scroll",rt,!0),window.addEventListener("resize",rt),z=a(()=>{window.removeEventListener("scroll",rt,!0),window.removeEventListener("resize",rt),w.forEach(V=>V.element.remove()),E&&E.remove()},"cleanupFn"),$.appendChild(ge),y+1}finally{z&&(window._highlightCleanupFunctions=window._highlightCleanupFunctions||[]).push(z)}}a(v,"highlightElement");function k(u){if(!u||u.nodeType!==Node.ELEMENT_NODE)return null;const y=T(u);if(!y)return null;const P=y.display;if(P==="inline"||P==="inline-block")return null;const w=y.overflowX,E=y.overflowY,N=w==="auto"||w==="scroll",x=E==="auto"||E==="scroll";if(!N&&!x)return null;const z=u.scrollWidth-u.clientWidth,$=u.scrollHeight-u.clientHeight,L=4;if(z<L&&$<L||!x&&z<L||!N&&$<L)return null;const Y=u.scrollTop,J=u.scrollLeft,ze=u.scrollWidth-u.clientWidth-u.scrollLeft,ee=u.scrollHeight-u.clientHeight-u.scrollTop,re={top:Y,right:ze,bottom:ee,left:J};return f(u,{scrollable:!0,scrollData:re}),re}a(k,"isScrollableElement");function O(u){try{if(c===-1){const x=u.parentElement;if(!x)return!1;try{return x.checkVisibility({checkOpacity:!0,checkVisibilityCSS:!0})}catch{const $=window.getComputedStyle(x);return $.display!=="none"&&$.visibility!=="hidden"&&$.opacity!=="0"}}const y=document.createRange();y.selectNodeContents(u);const P=y.getClientRects();if(!P||P.length===0)return!1;let w=!1,E=!1;for(const x of P)if(x.width>0&&x.height>0&&(w=!0,!(x.bottom<-c||x.top>window.innerHeight+c||x.right<-c||x.left>window.innerWidth+c))){E=!0;break}if(!w||!E)return!1;const N=u.parentElement;if(!N)return!1;try{return N.checkVisibility({checkOpacity:!0,checkVisibilityCSS:!0})}catch{const z=window.getComputedStyle(N);return z.display!=="none"&&z.visibility!=="hidden"&&z.opacity!=="0"}}catch(y){return console.warn("Error checking text node visibility:",y),!1}}a(O,"isTextNodeVisible");function Ie(u){if(!u||!u.tagName)return!1;const y=new Set(["body","div","main","article","section","nav","header","footer"]),P=u.tagName.toLowerCase();return y.has(P)?!0:!new Set(["svg","script","style","link","meta","noscript","template"]).has(P)}a(Ie,"isElementAccepted");function H(u){const y=T(u);return u.offsetWidth>0&&u.offsetHeight>0&&y?.visibility!=="hidden"&&y?.display!=="none"}a(H,"isElementVisible");function le(u){if(!u||u.nodeType!==Node.ELEMENT_NODE||t.includes(u))return!1;if(o.includes(u))return!0;const y=u.tagName.toLowerCase(),P=T(u),w=new Set(["pointer","move","text","grab","grabbing","cell","copy","alias","all-scroll","col-resize","context-menu","crosshair","e-resize","ew-resize","help","n-resize","ne-resize","nesw-resize","ns-resize","nw-resize","nwse-resize","row-resize","s-resize","se-resize","sw-resize","vertical-text","w-resize","zoom-in","zoom-out"]),E=new Set(["not-allowed","no-drop","wait","progress","initial","inherit"]);function N(ee){return ee.tagName.toLowerCase()==="html"?!1:!!(P?.cursor&&w.has(P.cursor))}if(a(N,"doesElementHaveInteractivePointer"),N(u))return!0;const z=new Set(["a","button","input","select","textarea","details","summary","label","option","optgroup","fieldset","legend"]),$=new Set(["disabled","readonly"]);if(z.has(y)){if(P?.cursor&&E.has(P.cursor))return!1;for(const ee of $)if(u.hasAttribute(ee)||u.getAttribute(ee)==="true"||u.getAttribute(ee)==="")return!1;return!(u.disabled||u.readOnly||u.inert)}const L=u.getAttribute("role"),Y=u.getAttribute("aria-role");if(u.getAttribute("contenteditable")==="true"||u.isContentEditable||u.classList&&(u.classList.contains("button")||u.classList.contains("dropdown-toggle")||u.getAttribute("data-index")||u.getAttribute("data-toggle")==="dropdown"||u.getAttribute("aria-haspopup")==="true"))return!0;const J=new Set(["button","menu","menubar","menuitem","menuitemradio","menuitemcheckbox","radio","checkbox","tab","switch","slider","spinbutton","combobox","searchbox","textbox","listbox","option","scrollbar"]);if(z.has(y)||L&&J.has(L)||Y&&J.has(Y))return!0;try{if(typeof getEventListeners=="function"){const ge=getEventListeners(u),me=["click","mousedown","mouseup","dblclick"];for(const Le of me)if(ge[Le]&&ge[Le].length>0)return!0}const ee=u?.ownerDocument?.defaultView?.getEventListenersForNode||window.getEventListenersForNode;if(typeof ee=="function"){const ge=ee(u),me=["click","mousedown","mouseup","keydown","keyup","submit","change","input","focus","blur"];for(const Le of me)for(const et of ge)if(et.type===Le)return!0}const re=["onclick","onmousedown","onmouseup","ondblclick"];for(const ge of re)if(u.hasAttribute(ge)||typeof u[ge]=="function")return!0}catch{}return!!k(u)}a(le,"isInteractiveElement");function ue(u){if(c===-1)return!0;const y=I(u);if(!y||y.length===0)return!1;let P=!1;for(const $ of y)if($.width>0&&$.height>0&&!($.bottom<-c||$.top>window.innerHeight+c||$.right<-c||$.left>window.innerWidth+c)){P=!0;break}if(!P)return!1;if(u.ownerDocument!==window.document)return!0;let E=Array.from(y).find($=>$.width>0&&$.height>0);if(!E)return!1;const N=u.getRootNode();if(N instanceof ShadowRoot){const $=E.left+E.width/2,L=E.top+E.height/2;try{const Y=N.elementFromPoint($,L);if(!Y)return!1;let J=Y;for(;J&&J!==N;){if(J===u)return!0;J=J.parentElement}return!1}catch{return!0}}const x=5;return[{x:E.left+E.width/2,y:E.top+E.height/2},{x:E.left+x,y:E.top+x},{x:E.right-x,y:E.bottom-x}].some(({x:$,y:L})=>{try{const Y=document.elementFromPoint($,L);if(!Y)return!1;let J=Y;for(;J&&J!==document.documentElement;){if(J===u)return!0;J=J.parentElement}return!1}catch{return!0}})}a(ue,"isTopElement");function K(u,y){if(y===-1)return!0;const P=u.getClientRects();if(!P||P.length===0){const w=m(u);return!w||w.width===0||w.height===0?!1:!(w.bottom<-y||w.top>window.innerHeight+y||w.right<-y||w.left>window.innerWidth+y)}for(const w of P)if(!(w.width===0||w.height===0)&&!(w.bottom<-y||w.top>window.innerHeight+y||w.right<-y||w.left>window.innerWidth+y))return!0;return!1}a(K,"isInExpandedViewport");function de(u){if(!u||u.nodeType!==Node.ELEMENT_NODE)return!1;const y=u.tagName.toLowerCase();return new Set(["a","button","input","select","textarea","details","summary","label"]).has(y)?!0:u.hasAttribute("onclick")||u.hasAttribute("role")||u.hasAttribute("tabindex")||u.hasAttribute("aria-")||u.hasAttribute("data-action")||u.getAttribute("contenteditable")==="true"}a(de,"isInteractiveCandidate");const pe=new Set(["a","button","input","select","textarea","summary","details","label","option"]),Ke=new Set(["button","link","menuitem","menuitemradio","menuitemcheckbox","radio","checkbox","tab","switch","slider","spinbutton","combobox","searchbox","textbox","listbox","option","scrollbar"]);function he(u){if(!u||u.nodeType!==Node.ELEMENT_NODE||!H(u))return!1;const y=u.hasAttribute("role")||u.hasAttribute("tabindex")||u.hasAttribute("onclick")||typeof u.onclick=="function",P=/\b(btn|clickable|menu|item|entry|link)\b/i.test(u.className||""),w=!!u.closest('button,a,[role="button"],.menu,.dropdown,.list,.toolbar'),E=[...u.children].some(H),N=u.parentElement&&u.parentElement.isSameNode(document.body);return(le(u)||y||P)&&E&&w&&!N}a(he,"isHeuristicallyInteractive");function Xe(u){if(!u||u.nodeType!==Node.ELEMENT_NODE)return!1;const y=u.tagName.toLowerCase(),P=u.getAttribute("role");if(y==="iframe"||pe.has(y)||P&&Ke.has(P)||u.isContentEditable||u.getAttribute("contenteditable")==="true"||u.hasAttribute("data-testid")||u.hasAttribute("data-cy")||u.hasAttribute("data-test")||u.hasAttribute("onclick")||typeof u.onclick=="function")return!0;try{const w=u?.ownerDocument?.defaultView?.getEventListenersForNode||window.getEventListenersForNode;if(typeof w=="function"){const N=w(u),x=["click","mousedown","mouseup","keydown","keyup","submit","change","input","focus","blur"];for(const z of x)for(const $ of N)if($.type===z)return!0}if(["onmousedown","onmouseup","onkeydown","onkeyup","onsubmit","onchange","oninput","onfocus","onblur"].some(N=>u.hasAttribute(N)))return!0}catch{}return!!he(u)}a(Xe,"isElementDistinctInteraction");function Qe(u,y,P,w){if(!u.isInteractive)return!1;let E=!1;return w?Xe(y)?E=!0:E=!1:E=!0,E&&(u.isInViewport=K(y,c),(u.isInViewport||c===-1)&&(u.highlightIndex=d++,i))?(s>=0?s===u.highlightIndex&&v(y,u.highlightIndex,P):v(y,u.highlightIndex,P),!0):!1}a(Qe,"handleHighlighting");function _e(u,y=null,P=!1){if(!u||u.id===D||u.nodeType!==Node.ELEMENT_NODE&&u.nodeType!==Node.TEXT_NODE||!u||u.id===D||u.dataset?.browserUseIgnore==="true"||u.dataset?.pageAgentIgnore==="true"||u.getAttribute&&u.getAttribute("aria-hidden")==="true")return null;if(u===document.body){const x={tagName:"body",attributes:{},xpath:"/body",children:[]};for(const $ of u.childNodes){const L=_e($,y,!1);L&&x.children.push(L)}const z=`${C.current++}`;return A[z]=x,z}if(u.nodeType!==Node.ELEMENT_NODE&&u.nodeType!==Node.TEXT_NODE)return null;if(u.nodeType===Node.TEXT_NODE){const x=u.textContent?.trim();if(!x)return null;const z=u.parentElement;if(!z||z.tagName.toLowerCase()==="script")return null;const $=`${C.current++}`;return A[$]={type:"TEXT_NODE",text:x,isVisible:O(u)},$}if(u.nodeType===Node.ELEMENT_NODE&&!Ie(u))return null;if(c!==-1&&!u.shadowRoot){const x=m(u),z=T(u),$=z&&(z.position==="fixed"||z.position==="sticky"),L=u.offsetWidth>0||u.offsetHeight>0;if(!x||!$&&!L&&(x.bottom<-c||x.top>window.innerHeight+c||x.right<-c||x.left>window.innerWidth+c))return null}const w={tagName:u.tagName.toLowerCase(),attributes:{},children:[]};if(de(u)||u.tagName.toLowerCase()==="iframe"||u.tagName.toLowerCase()==="body"){const x=u.getAttributeNames?.()||[];for(const z of x){const $=u.getAttribute(z);w.attributes[z]=$}u.tagName.toLowerCase()==="input"&&(u.type==="checkbox"||u.type==="radio")&&(w.attributes.checked=u.checked?"true":"false")}let E=!1;if(u.nodeType===Node.ELEMENT_NODE&&(w.isVisible=H(u),w.isVisible)){w.isTopElement=ue(u);const x=u.getAttribute("role"),z=x==="menu"||x==="menubar"||x==="listbox";if((w.isTopElement||z)&&(w.isInteractive=le(u),E=Qe(w,u,y,P),w.ref=u,w.isInteractive&&Object.keys(w.attributes).length===0)){const $=u.getAttributeNames?.()||[];for(const L of $){const Y=u.getAttribute(L);w.attributes[L]=Y}}}if(u.tagName){const x=u.tagName.toLowerCase();if(x==="iframe")try{const z=u.contentDocument||u.contentWindow?.document;if(z)for(const $ of z.childNodes){const L=_e($,u,!1);L&&w.children.push(L)}}catch(z){console.warn("Unable to access iframe:",z)}else if(u.isContentEditable||u.getAttribute("contenteditable")==="true"||u.id==="tinymce"||u.classList.contains("mce-content-body")||x==="body"&&u.getAttribute("data-id")?.startsWith("mce_"))for(const z of u.childNodes){const $=_e(z,y,E);$&&w.children.push($)}else{if(u.shadowRoot){w.shadowRoot=!0;for(const z of u.shadowRoot.childNodes){const $=_e(z,y,E);$&&w.children.push($)}}for(const z of u.childNodes){const L=_e(z,y,E||P);L&&w.children.push(L)}}}if(w.tagName==="a"&&w.children.length===0&&!w.attributes.href){const x=m(u);if(!(x&&x.width>0&&x.height>0||u.offsetWidth>0||u.offsetHeight>0))return null}w.extra=h.get(u)||null;const N=`${C.current++}`;return A[N]=w,N}a(_e,"buildDomTree");const fe=_e(document.body);return g.clearCache(),{rootId:fe,map:A}},"domTree"),DEFAULT_VIEWPORT_EXPANSION=-1;function resolveViewportExpansion(e){return e??DEFAULT_VIEWPORT_EXPANSION}a(resolveViewportExpansion,"resolveViewportExpansion");const newElementsCache=new WeakMap;function getFlatTree(e){const t=resolveViewportExpansion(e.viewportExpansion),o=[];for(const s of e.interactiveBlacklist||[])typeof s=="function"?o.push(s()):o.push(s);const n=[];for(const s of e.interactiveWhitelist||[])typeof s=="function"?n.push(s()):n.push(s);const r=domTree({doHighlightElements:!0,debugMode:!0,focusHighlightIndex:-1,viewportExpansion:t,interactiveBlacklist:o,interactiveWhitelist:n,highlightOpacity:e.highlightOpacity??0,highlightLabelOpacity:e.highlightLabelOpacity??.1}),i=window.location.href;for(const s in r.map){const c=r.map[s];if(c.isInteractive&&c.ref){const l=c.ref;newElementsCache.has(l)||(newElementsCache.set(l,i),c.isNew=!0)}}return r}a(getFlatTree,"getFlatTree");const globRegexCache=new Map;function globToRegex(e){let t=globRegexCache.get(e);if(!t){const o=e.replace(/[.+^${}()|[\]\\]/g,"\\$&");t=new RegExp(`^${o.replace(/\*/g,".*")}$`),globRegexCache.set(e,t)}return t}a(globToRegex,"globToRegex");function matchAttributes(e,t){const o={};for(const n of t)if(n.includes("*")){const r=globToRegex(n);for(const i of Object.keys(e))r.test(i)&&e[i].trim()&&(o[i]=e[i].trim())}else{const r=e[n];r&&r.trim()&&(o[n]=r.trim())}return o}a(matchAttributes,"matchAttributes");function flatTreeToString(e,t){const o=["title","type","checked","name","role","value","placeholder","data-date-format","alt","aria-label","aria-expanded","data-state","aria-checked","id","for","target","aria-haspopup","aria-controls","aria-owns","contenteditable"],n=[...t||[],...o],r=a((f,g)=>f.length>g?f.substring(0,g)+"...":f,"capTextLength"),i=a(f=>{const g=e.map[f];if(!g)return null;if(g.type==="TEXT_NODE"){const m=g;return{type:"text",text:m.text,isVisible:m.isVisible,parent:null,children:[]}}else{const m=g,T=[];if(m.children)for(const I of m.children){const A=i(I);A&&(A.parent=null,T.push(A))}return{type:"element",tagName:m.tagName,attributes:m.attributes??{},isVisible:m.isVisible??!1,isInteractive:m.isInteractive??!1,isTopElement:m.isTopElement??!1,isNew:m.isNew??!1,highlightIndex:m.highlightIndex,parent:null,children:T,extra:m.extra??{}}}},"buildTreeNode"),s=a((f,g=null)=>{f.parent=g;for(const m of f.children)s(m,f)},"setParentReferences"),c=i(e.rootId);if(!c)return"";s(c);const l=a(f=>{let g=f.parent;for(;g;){if(g.type==="element"&&g.highlightIndex!==void 0)return!0;g=g.parent}return!1},"hasParentWithHighlightIndex"),d=a((f,g,m)=>{let T=g;const I=" ".repeat(g);if(f.type==="element"){if(f.highlightIndex!==void 0){T+=1;const A=getAllTextTillNextClickableElement(f);let C="";if(n.length>0&&f.attributes){const k=matchAttributes(f.attributes,n),O=Object.keys(k);if(O.length>1){const H=new Set,le={};for(const ue of O){const K=k[ue];K.length>5&&(K in le?H.add(ue):le[K]=ue)}for(const ue of H)delete k[ue]}k.role===f.tagName&&delete k.role;const Ie=["aria-label","placeholder","title"];for(const H of Ie)k[H]&&k[H].toLowerCase().trim()===A.toLowerCase().trim()&&delete k[H];Object.keys(k).length>0&&(C=Object.entries(k).map(([H,le])=>`${H}=${r(le,20)}`).join(" "))}const D=f.isNew?`*[${f.highlightIndex}]`:`[${f.highlightIndex}]`;let v=`${I}${D}<${f.tagName??""}`;if(C&&(v+=` ${C}`),f.extra&&f.extra.scrollable){let k="";f.extra.scrollData?.left&&(k+=`left=${f.extra.scrollData.left}, `),f.extra.scrollData?.top&&(k+=`top=${f.extra.scrollData.top}, `),f.extra.scrollData?.right&&(k+=`right=${f.extra.scrollData.right}, `),f.extra.scrollData?.bottom&&(k+=`bottom=${f.extra.scrollData.bottom}`),v+=` data-scrollable="${k}"`}if(A){const k=A.trim();C||(v+=" "),v+=`>${k}`}else C||(v+=" ");v+=" />",m.push(v)}for(const A of f.children)d(A,T,m)}else if(f.type==="text"){if(l(f))return;f.parent&&f.parent.type==="element"&&f.parent.isVisible&&f.parent.isTopElement&&m.push(`${I}${f.text??""}`)}},"processNode"),h=[];return d(c,0,h),h.join(`
|
|
239
|
+
`,n},"#assembleUserPrompt"),st=a(function(o=!0){this.pageController.cleanUpHighlights(),this.pageController.hideMask(),b(this,R,_t).call(this,o?"completed":"error"),p(this,se).abort()},"#onDone"),a(ut,"PageAgentCore");let PageAgentCore=ut;async function waitFor(e){await new Promise(t=>setTimeout(t,e*1e3))}a(waitFor,"waitFor");async function movePointerToElement(e){const t=e.getBoundingClientRect(),o=t.left+t.width/2,n=t.top+t.height/2;window.dispatchEvent(new CustomEvent("PageAgent::MovePointerTo",{detail:{x:o,y:n}})),await waitFor(.3)}a(movePointerToElement,"movePointerToElement");function getElementByIndex(e,t){const o=e.get(t);if(!o)throw new Error(`No interactive element found at index ${t}`);const n=o.ref;if(!n)throw new Error(`Element at index ${t} does not have a reference`);if(!(n instanceof HTMLElement))throw new Error(`Element at index ${t} is not an HTMLElement`);return n}a(getElementByIndex,"getElementByIndex");let lastClickedElement=null;function blurLastClickedElement(){lastClickedElement&&(lastClickedElement.blur(),lastClickedElement.dispatchEvent(new MouseEvent("mouseout",{bubbles:!0,cancelable:!0})),lastClickedElement=null)}a(blurLastClickedElement,"blurLastClickedElement");async function clickElement(e){blurLastClickedElement(),lastClickedElement=e,await scrollIntoViewIfNeeded(e),await movePointerToElement(e),window.dispatchEvent(new CustomEvent("PageAgent::ClickPointer")),await waitFor(.1),e.dispatchEvent(new MouseEvent("mouseenter",{bubbles:!0,cancelable:!0})),e.dispatchEvent(new MouseEvent("mouseover",{bubbles:!0,cancelable:!0})),e.dispatchEvent(new MouseEvent("mousedown",{bubbles:!0,cancelable:!0})),e.focus(),e.dispatchEvent(new MouseEvent("mouseup",{bubbles:!0,cancelable:!0})),e.dispatchEvent(new MouseEvent("click",{bubbles:!0,cancelable:!0})),await waitFor(.2)}a(clickElement,"clickElement");const nativeInputValueSetter=Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype,"value").set,nativeTextAreaValueSetter=Object.getOwnPropertyDescriptor(window.HTMLTextAreaElement.prototype,"value").set;async function inputTextElement(e,t){const o=e.isContentEditable;if(!(e instanceof HTMLInputElement)&&!(e instanceof HTMLTextAreaElement)&&!o)throw new Error("Element is not an input, textarea, or contenteditable");await clickElement(e),o?(e.dispatchEvent(new InputEvent("beforeinput",{bubbles:!0,cancelable:!0,inputType:"deleteContent"}))&&(e.innerText="",e.dispatchEvent(new InputEvent("input",{bubbles:!0,inputType:"deleteContent"}))),e.dispatchEvent(new InputEvent("beforeinput",{bubbles:!0,cancelable:!0,inputType:"insertText",data:t}))&&(e.innerText=t,e.dispatchEvent(new InputEvent("input",{bubbles:!0,inputType:"insertText",data:t}))),e.dispatchEvent(new Event("change",{bubbles:!0})),e.blur()):e instanceof HTMLTextAreaElement?nativeTextAreaValueSetter.call(e,t):nativeInputValueSetter.call(e,t),o||e.dispatchEvent(new Event("input",{bubbles:!0})),await waitFor(.1),blurLastClickedElement()}a(inputTextElement,"inputTextElement");async function selectOptionElement(e,t){if(!(e instanceof HTMLSelectElement))throw new Error("Element is not a select element");const n=Array.from(e.options).find(r=>r.textContent?.trim()===t.trim());if(!n)throw new Error(`Option with text "${t}" not found in select element`);e.value=n.value,e.dispatchEvent(new Event("change",{bubbles:!0})),await waitFor(.1)}a(selectOptionElement,"selectOptionElement");async function scrollIntoViewIfNeeded(e){const t=e;typeof t.scrollIntoViewIfNeeded=="function"?t.scrollIntoViewIfNeeded():e.scrollIntoView({behavior:"auto",block:"center",inline:"nearest"})}a(scrollIntoViewIfNeeded,"scrollIntoViewIfNeeded");async function scrollVertically(e,t,o){if(o){const c=o;let l=c,d=!1,h=null,f=0,g=0;const m=t;for(;l&&g<10;){const T=window.getComputedStyle(l),I=/(auto|scroll|overlay)/.test(T.overflowY),A=l.scrollHeight>l.clientHeight;if(I&&A){const C=l.scrollTop,D=l.scrollHeight-l.clientHeight;let v=m/3;v>0?v=Math.min(v,D-C):v=Math.max(v,-C),l.scrollTop=C+v;const O=l.scrollTop-C;if(Math.abs(O)>.5){d=!0,h=l,f=O;break}}if(l===document.body||l===document.documentElement)break;l=l.parentElement,g++}return d?`Scrolled container (${h?.tagName}) by ${f}px`:`No scrollable container found for element (${c.tagName})`}const n=t,r=a(c=>c.clientHeight>=window.innerHeight*.5,"bigEnough"),i=a(c=>c&&/(auto|scroll|overlay)/.test(getComputedStyle(c).overflowY)&&c.scrollHeight>c.clientHeight&&r(c),"canScroll");let s=document.activeElement;for(;s&&!i(s)&&s!==document.body;)s=s.parentElement;if(s=i(s)?s:Array.from(document.querySelectorAll("*")).find(i)||document.scrollingElement||document.documentElement,s===document.scrollingElement||s===document.documentElement||s===document.body){const c=window.scrollY,l=document.documentElement.scrollHeight-window.innerHeight;window.scrollBy(0,n);const d=window.scrollY,h=d-c;if(Math.abs(h)<1)return n>0?"β οΈ Already at the bottom of the page, cannot scroll down further.":"β οΈ Already at the top of the page, cannot scroll up further.";const f=n>0&&d>=l-1,g=n<0&&d<=1;return f?`β
Scrolled page by ${h}px. Reached the bottom of the page.`:g?`β
Scrolled page by ${h}px. Reached the top of the page.`:`β
Scrolled page by ${h}px.`}else{const c=s.scrollTop,l=s.scrollHeight-s.clientHeight;s.scrollBy({top:n,behavior:"smooth"}),await waitFor(.1);const d=s.scrollTop,h=d-c;if(Math.abs(h)<1)return n>0?`β οΈ Already at the bottom of container (${s.tagName}), cannot scroll down further.`:`β οΈ Already at the top of container (${s.tagName}), cannot scroll up further.`;const f=n>0&&d>=l-1,g=n<0&&d<=1;return f?`β
Scrolled container (${s.tagName}) by ${h}px. Reached the bottom.`:g?`β
Scrolled container (${s.tagName}) by ${h}px. Reached the top.`:`β
Scrolled container (${s.tagName}) by ${h}px.`}}a(scrollVertically,"scrollVertically");async function scrollHorizontally(e,t,o){if(o){const c=o;let l=c,d=!1,h=null,f=0,g=0;const m=e?t:-t;for(;l&&g<10;){const T=window.getComputedStyle(l),I=/(auto|scroll|overlay)/.test(T.overflowX),A=l.scrollWidth>l.clientWidth;if(I&&A){const C=l.scrollLeft,D=l.scrollWidth-l.clientWidth;let v=m/3;v>0?v=Math.min(v,D-C):v=Math.max(v,-C),l.scrollLeft=C+v;const O=l.scrollLeft-C;if(Math.abs(O)>.5){d=!0,h=l,f=O;break}}if(l===document.body||l===document.documentElement)break;l=l.parentElement,g++}return d?`Scrolled container (${h?.tagName}) horizontally by ${f}px`:`No horizontally scrollable container found for element (${c.tagName})`}const n=e?t:-t,r=a(c=>c.clientWidth>=window.innerWidth*.5,"bigEnough"),i=a(c=>c&&/(auto|scroll|overlay)/.test(getComputedStyle(c).overflowX)&&c.scrollWidth>c.clientWidth&&r(c),"canScroll");let s=document.activeElement;for(;s&&!i(s)&&s!==document.body;)s=s.parentElement;if(s=i(s)?s:Array.from(document.querySelectorAll("*")).find(i)||document.scrollingElement||document.documentElement,s===document.scrollingElement||s===document.documentElement||s===document.body){const c=window.scrollX,l=document.documentElement.scrollWidth-window.innerWidth;window.scrollBy(n,0);const d=window.scrollX,h=d-c;if(Math.abs(h)<1)return n>0?"β οΈ Already at the right edge of the page, cannot scroll right further.":"β οΈ Already at the left edge of the page, cannot scroll left further.";const f=n>0&&d>=l-1,g=n<0&&d<=1;return f?`β
Scrolled page by ${h}px. Reached the right edge of the page.`:g?`β
Scrolled page by ${h}px. Reached the left edge of the page.`:`β
Scrolled page horizontally by ${h}px.`}else{const c=s.scrollLeft,l=s.scrollWidth-s.clientWidth;s.scrollBy({left:n,behavior:"smooth"}),await waitFor(.1);const d=s.scrollLeft,h=d-c;if(Math.abs(h)<1)return n>0?`β οΈ Already at the right edge of container (${s.tagName}), cannot scroll right further.`:`β οΈ Already at the left edge of container (${s.tagName}), cannot scroll left further.`;const f=n>0&&d>=l-1,g=n<0&&d<=1;return f?`β
Scrolled container (${s.tagName}) by ${h}px. Reached the right edge.`:g?`β
Scrolled container (${s.tagName}) by ${h}px. Reached the left edge.`:`β
Scrolled container (${s.tagName}) horizontally by ${h}px.`}}a(scrollHorizontally,"scrollHorizontally");const domTree=a((e={doHighlightElements:!0,focusHighlightIndex:-1,viewportExpansion:0,debugMode:!1,interactiveBlacklist:[],interactiveWhitelist:[],highlightOpacity:.1,highlightLabelOpacity:.5})=>{const{interactiveBlacklist:t,interactiveWhitelist:o,highlightOpacity:n,highlightLabelOpacity:r}=e,{doHighlightElements:i,focusHighlightIndex:s,viewportExpansion:c,debugMode:l}=e;let d=0;const h=new WeakMap;function f(u,y){!u||u.nodeType!==Node.ELEMENT_NODE||h.set(u,{...h.get(u),...y})}a(f,"addExtraData");const g={boundingRects:new WeakMap,clientRects:new WeakMap,computedStyles:new WeakMap,clearCache:a(()=>{g.boundingRects=new WeakMap,g.clientRects=new WeakMap,g.computedStyles=new WeakMap},"clearCache")};function m(u){if(!u)return null;if(g.boundingRects.has(u))return g.boundingRects.get(u);const y=u.getBoundingClientRect();return y&&g.boundingRects.set(u,y),y}a(m,"getCachedBoundingRect");function T(u){if(!u)return null;if(g.computedStyles.has(u))return g.computedStyles.get(u);const y=window.getComputedStyle(u);return y&&g.computedStyles.set(u,y),y}a(T,"getCachedComputedStyle");function I(u){if(!u)return null;if(g.clientRects.has(u))return g.clientRects.get(u);const y=u.getClientRects();return y&&g.clientRects.set(u,y),y}a(I,"getCachedClientRects");const A={},C={current:0},D="playwright-highlight-container";function v(u,y,P=null){if(!u)return y;const w=[];let E=null,N=20,x=16,z=null;try{let $=document.getElementById(D);$||($=document.createElement("div"),$.id=D,$.style.position="fixed",$.style.pointerEvents="none",$.style.top="0",$.style.left="0",$.style.width="100%",$.style.height="100%",$.style.zIndex="2147483640",$.style.backgroundColor="transparent",document.body.appendChild($));const L=u.getClientRects();if(!L||L.length===0)return y;const Y=["#FF0000","#00FF00","#0000FF","#FFA500","#800080","#008080","#FF69B4","#4B0082","#FF4500","#2E8B57","#DC143C","#4682B4"],J=y%Y.length;let ze=Y[J];const ee=ze+Math.floor(n*255).toString(16).padStart(2,"0");ze=ze+Math.floor(r*255).toString(16).padStart(2,"0");let re={x:0,y:0};if(P){const V=P.getBoundingClientRect();re.x=V.left,re.y=V.top}const ge=document.createDocumentFragment();for(const V of L){if(V.width===0||V.height===0)continue;const G=document.createElement("div");G.style.position="fixed",G.style.border=`2px solid ${ze}`,G.style.backgroundColor=ee,G.style.pointerEvents="none",G.style.boxSizing="border-box";const U=V.top+re.y,ke=V.left+re.x;G.style.top=`${U}px`,G.style.left=`${ke}px`,G.style.width=`${V.width}px`,G.style.height=`${V.height}px`,ge.appendChild(G),w.push({element:G,initialRect:V})}const me=L[0];E=document.createElement("div"),E.className="playwright-highlight-label",E.style.position="fixed",E.style.background=ze,E.style.color="white",E.style.padding="1px 4px",E.style.borderRadius="4px",E.style.fontSize=`${Math.min(12,Math.max(8,me.height/2))}px`,E.textContent=y.toString(),N=E.offsetWidth>0?E.offsetWidth:N,x=E.offsetHeight>0?E.offsetHeight:x;const Le=me.top+re.y,et=me.left+re.x;let nt=Le+2,We=et+me.width-N-2;(me.width<N+4||me.height<x+4)&&(nt=Le-x-2,We=et+me.width-N,We<re.x&&(We=et)),nt=Math.max(0,Math.min(nt,window.innerHeight-x)),We=Math.max(0,Math.min(We,window.innerWidth-N)),E.style.top=`${nt}px`,E.style.left=`${We}px`,ge.appendChild(E);const rt=a((V,G)=>{let U=0;return(...ke)=>{const te=performance.now();if(!(te-U<G))return U=te,V(...ke)}},"throttleFunction")(a(()=>{const V=u.getClientRects();let G={x:0,y:0};if(P){const U=P.getBoundingClientRect();G.x=U.left,G.y=U.top}if(w.forEach((U,ke)=>{if(ke<V.length){const te=V[ke],Ve=te.top+G.y,Ae=te.left+G.x;U.element.style.top=`${Ve}px`,U.element.style.left=`${Ae}px`,U.element.style.width=`${te.width}px`,U.element.style.height=`${te.height}px`,U.element.style.display=te.width===0||te.height===0?"none":"block"}else U.element.style.display="none"}),V.length<w.length)for(let U=V.length;U<w.length;U++)w[U].element.style.display="none";if(E&&V.length>0){const U=V[0],ke=U.top+G.y,te=U.left+G.x;let Ve=ke+2,Ae=te+U.width-N-2;(U.width<N+4||U.height<x+4)&&(Ve=ke-x-2,Ae=te+U.width-N,Ae<G.x&&(Ae=te)),Ve=Math.max(0,Math.min(Ve,window.innerHeight-x)),Ae=Math.max(0,Math.min(Ae,window.innerWidth-N)),E.style.top=`${Ve}px`,E.style.left=`${Ae}px`,E.style.display="block"}else E&&(E.style.display="none")},"updatePositions"),16);return window.addEventListener("scroll",rt,!0),window.addEventListener("resize",rt),z=a(()=>{window.removeEventListener("scroll",rt,!0),window.removeEventListener("resize",rt),w.forEach(V=>V.element.remove()),E&&E.remove()},"cleanupFn"),$.appendChild(ge),y+1}finally{z&&(window._highlightCleanupFunctions=window._highlightCleanupFunctions||[]).push(z)}}a(v,"highlightElement");function k(u){if(!u||u.nodeType!==Node.ELEMENT_NODE)return null;const y=T(u);if(!y)return null;const P=y.display;if(P==="inline"||P==="inline-block")return null;const w=y.overflowX,E=y.overflowY,N=w==="auto"||w==="scroll",x=E==="auto"||E==="scroll";if(!N&&!x)return null;const z=u.scrollWidth-u.clientWidth,$=u.scrollHeight-u.clientHeight,L=4;if(z<L&&$<L||!x&&z<L||!N&&$<L)return null;const Y=u.scrollTop,J=u.scrollLeft,ze=u.scrollWidth-u.clientWidth-u.scrollLeft,ee=u.scrollHeight-u.clientHeight-u.scrollTop,re={top:Y,right:ze,bottom:ee,left:J};return f(u,{scrollable:!0,scrollData:re}),re}a(k,"isScrollableElement");function O(u){try{if(c===-1){const x=u.parentElement;if(!x)return!1;try{return x.checkVisibility({checkOpacity:!0,checkVisibilityCSS:!0})}catch{const $=window.getComputedStyle(x);return $.display!=="none"&&$.visibility!=="hidden"&&$.opacity!=="0"}}const y=document.createRange();y.selectNodeContents(u);const P=y.getClientRects();if(!P||P.length===0)return!1;let w=!1,E=!1;for(const x of P)if(x.width>0&&x.height>0&&(w=!0,!(x.bottom<-c||x.top>window.innerHeight+c||x.right<-c||x.left>window.innerWidth+c))){E=!0;break}if(!w||!E)return!1;const N=u.parentElement;if(!N)return!1;try{return N.checkVisibility({checkOpacity:!0,checkVisibilityCSS:!0})}catch{const z=window.getComputedStyle(N);return z.display!=="none"&&z.visibility!=="hidden"&&z.opacity!=="0"}}catch(y){return console.warn("Error checking text node visibility:",y),!1}}a(O,"isTextNodeVisible");function Ie(u){if(!u||!u.tagName)return!1;const y=new Set(["body","div","main","article","section","nav","header","footer"]),P=u.tagName.toLowerCase();return y.has(P)?!0:!new Set(["svg","script","style","link","meta","noscript","template"]).has(P)}a(Ie,"isElementAccepted");function H(u){const y=T(u);return u.offsetWidth>0&&u.offsetHeight>0&&y?.visibility!=="hidden"&&y?.display!=="none"}a(H,"isElementVisible");function le(u){if(!u||u.nodeType!==Node.ELEMENT_NODE||t.includes(u))return!1;if(o.includes(u))return!0;const y=u.tagName.toLowerCase(),P=T(u),w=new Set(["pointer","move","text","grab","grabbing","cell","copy","alias","all-scroll","col-resize","context-menu","crosshair","e-resize","ew-resize","help","n-resize","ne-resize","nesw-resize","ns-resize","nw-resize","nwse-resize","row-resize","s-resize","se-resize","sw-resize","vertical-text","w-resize","zoom-in","zoom-out"]),E=new Set(["not-allowed","no-drop","wait","progress","initial","inherit"]);function N(ee){return ee.tagName.toLowerCase()==="html"?!1:!!(P?.cursor&&w.has(P.cursor))}if(a(N,"doesElementHaveInteractivePointer"),N(u))return!0;const z=new Set(["a","button","input","select","textarea","details","summary","label","option","optgroup","fieldset","legend"]),$=new Set(["disabled","readonly"]);if(z.has(y)){if(P?.cursor&&E.has(P.cursor))return!1;for(const ee of $)if(u.hasAttribute(ee)||u.getAttribute(ee)==="true"||u.getAttribute(ee)==="")return!1;return!(u.disabled||u.readOnly||u.inert)}const L=u.getAttribute("role"),Y=u.getAttribute("aria-role");if(u.getAttribute("contenteditable")==="true"||u.isContentEditable||u.classList&&(u.classList.contains("button")||u.classList.contains("dropdown-toggle")||u.getAttribute("data-index")||u.getAttribute("data-toggle")==="dropdown"||u.getAttribute("aria-haspopup")==="true"))return!0;const J=new Set(["button","menu","menubar","menuitem","menuitemradio","menuitemcheckbox","radio","checkbox","tab","switch","slider","spinbutton","combobox","searchbox","textbox","listbox","option","scrollbar"]);if(z.has(y)||L&&J.has(L)||Y&&J.has(Y))return!0;try{if(typeof getEventListeners=="function"){const ge=getEventListeners(u),me=["click","mousedown","mouseup","dblclick"];for(const Le of me)if(ge[Le]&&ge[Le].length>0)return!0}const ee=u?.ownerDocument?.defaultView?.getEventListenersForNode||window.getEventListenersForNode;if(typeof ee=="function"){const ge=ee(u),me=["click","mousedown","mouseup","keydown","keyup","submit","change","input","focus","blur"];for(const Le of me)for(const et of ge)if(et.type===Le)return!0}const re=["onclick","onmousedown","onmouseup","ondblclick"];for(const ge of re)if(u.hasAttribute(ge)||typeof u[ge]=="function")return!0}catch{}return!!k(u)}a(le,"isInteractiveElement");function ue(u){if(c===-1)return!0;const y=I(u);if(!y||y.length===0)return!1;let P=!1;for(const $ of y)if($.width>0&&$.height>0&&!($.bottom<-c||$.top>window.innerHeight+c||$.right<-c||$.left>window.innerWidth+c)){P=!0;break}if(!P)return!1;if(u.ownerDocument!==window.document)return!0;let E=Array.from(y).find($=>$.width>0&&$.height>0);if(!E)return!1;const N=u.getRootNode();if(N instanceof ShadowRoot){const $=E.left+E.width/2,L=E.top+E.height/2;try{const Y=N.elementFromPoint($,L);if(!Y)return!1;let J=Y;for(;J&&J!==N;){if(J===u)return!0;J=J.parentElement}return!1}catch{return!0}}const x=5;return[{x:E.left+E.width/2,y:E.top+E.height/2},{x:E.left+x,y:E.top+x},{x:E.right-x,y:E.bottom-x}].some(({x:$,y:L})=>{try{const Y=document.elementFromPoint($,L);if(!Y)return!1;let J=Y;for(;J&&J!==document.documentElement;){if(J===u)return!0;J=J.parentElement}return!1}catch{return!0}})}a(ue,"isTopElement");function K(u,y){if(y===-1)return!0;const P=u.getClientRects();if(!P||P.length===0){const w=m(u);return!w||w.width===0||w.height===0?!1:!(w.bottom<-y||w.top>window.innerHeight+y||w.right<-y||w.left>window.innerWidth+y)}for(const w of P)if(!(w.width===0||w.height===0)&&!(w.bottom<-y||w.top>window.innerHeight+y||w.right<-y||w.left>window.innerWidth+y))return!0;return!1}a(K,"isInExpandedViewport");function de(u){if(!u||u.nodeType!==Node.ELEMENT_NODE)return!1;const y=u.tagName.toLowerCase();return new Set(["a","button","input","select","textarea","details","summary","label"]).has(y)?!0:u.hasAttribute("onclick")||u.hasAttribute("role")||u.hasAttribute("tabindex")||u.hasAttribute("aria-")||u.hasAttribute("data-action")||u.getAttribute("contenteditable")==="true"}a(de,"isInteractiveCandidate");const pe=new Set(["a","button","input","select","textarea","summary","details","label","option"]),Ke=new Set(["button","link","menuitem","menuitemradio","menuitemcheckbox","radio","checkbox","tab","switch","slider","spinbutton","combobox","searchbox","textbox","listbox","option","scrollbar"]);function he(u){if(!u||u.nodeType!==Node.ELEMENT_NODE||!H(u))return!1;const y=u.hasAttribute("role")||u.hasAttribute("tabindex")||u.hasAttribute("onclick")||typeof u.onclick=="function",P=/\b(btn|clickable|menu|item|entry|link)\b/i.test(u.className||""),w=!!u.closest('button,a,[role="button"],.menu,.dropdown,.list,.toolbar'),E=[...u.children].some(H),N=u.parentElement&&u.parentElement.isSameNode(document.body);return(le(u)||y||P)&&E&&w&&!N}a(he,"isHeuristicallyInteractive");function Xe(u){if(!u||u.nodeType!==Node.ELEMENT_NODE)return!1;const y=u.tagName.toLowerCase(),P=u.getAttribute("role");if(y==="iframe"||pe.has(y)||P&&Ke.has(P)||u.isContentEditable||u.getAttribute("contenteditable")==="true"||u.hasAttribute("data-testid")||u.hasAttribute("data-cy")||u.hasAttribute("data-test")||u.hasAttribute("onclick")||typeof u.onclick=="function")return!0;try{const w=u?.ownerDocument?.defaultView?.getEventListenersForNode||window.getEventListenersForNode;if(typeof w=="function"){const N=w(u),x=["click","mousedown","mouseup","keydown","keyup","submit","change","input","focus","blur"];for(const z of x)for(const $ of N)if($.type===z)return!0}if(["onmousedown","onmouseup","onkeydown","onkeyup","onsubmit","onchange","oninput","onfocus","onblur"].some(N=>u.hasAttribute(N)))return!0}catch{}return!!he(u)}a(Xe,"isElementDistinctInteraction");function Qe(u,y,P,w){if(!u.isInteractive)return!1;let E=!1;return w?Xe(y)?E=!0:E=!1:E=!0,E&&(u.isInViewport=K(y,c),(u.isInViewport||c===-1)&&(u.highlightIndex=d++,i))?(s>=0?s===u.highlightIndex&&v(y,u.highlightIndex,P):v(y,u.highlightIndex,P),!0):!1}a(Qe,"handleHighlighting");function _e(u,y=null,P=!1){if(!u||u.id===D||u.nodeType!==Node.ELEMENT_NODE&&u.nodeType!==Node.TEXT_NODE||!u||u.id===D||u.dataset?.browserUseIgnore==="true"||u.dataset?.pageAgentIgnore==="true"||u.getAttribute&&u.getAttribute("aria-hidden")==="true")return null;if(u===document.body){const x={tagName:"body",attributes:{},xpath:"/body",children:[]};for(const $ of u.childNodes){const L=_e($,y,!1);L&&x.children.push(L)}const z=`${C.current++}`;return A[z]=x,z}if(u.nodeType!==Node.ELEMENT_NODE&&u.nodeType!==Node.TEXT_NODE)return null;if(u.nodeType===Node.TEXT_NODE){const x=u.textContent?.trim();if(!x)return null;const z=u.parentElement;if(!z||z.tagName.toLowerCase()==="script")return null;const $=`${C.current++}`;return A[$]={type:"TEXT_NODE",text:x,isVisible:O(u)},$}if(u.nodeType===Node.ELEMENT_NODE&&!Ie(u))return null;if(c!==-1&&!u.shadowRoot){const x=m(u),z=T(u),$=z&&(z.position==="fixed"||z.position==="sticky"),L=u.offsetWidth>0||u.offsetHeight>0;if(!x||!$&&!L&&(x.bottom<-c||x.top>window.innerHeight+c||x.right<-c||x.left>window.innerWidth+c))return null}const w={tagName:u.tagName.toLowerCase(),attributes:{},children:[]};if(de(u)||u.tagName.toLowerCase()==="iframe"||u.tagName.toLowerCase()==="body"){const x=u.getAttributeNames?.()||[];for(const z of x){const $=u.getAttribute(z);w.attributes[z]=$}u.tagName.toLowerCase()==="input"&&(u.type==="checkbox"||u.type==="radio")&&(w.attributes.checked=u.checked?"true":"false")}let E=!1;if(u.nodeType===Node.ELEMENT_NODE&&(w.isVisible=H(u),w.isVisible)){w.isTopElement=ue(u);const x=u.getAttribute("role"),z=x==="menu"||x==="menubar"||x==="listbox";if((w.isTopElement||z)&&(w.isInteractive=le(u),E=Qe(w,u,y,P),w.ref=u,w.isInteractive&&Object.keys(w.attributes).length===0)){const $=u.getAttributeNames?.()||[];for(const L of $){const Y=u.getAttribute(L);w.attributes[L]=Y}}}if(u.tagName){const x=u.tagName.toLowerCase();if(x==="iframe")try{const z=u.contentDocument||u.contentWindow?.document;if(z)for(const $ of z.childNodes){const L=_e($,u,!1);L&&w.children.push(L)}}catch(z){console.warn("Unable to access iframe:",z)}else if(u.isContentEditable||u.getAttribute("contenteditable")==="true"||u.id==="tinymce"||u.classList.contains("mce-content-body")||x==="body"&&u.getAttribute("data-id")?.startsWith("mce_"))for(const z of u.childNodes){const $=_e(z,y,E);$&&w.children.push($)}else{if(u.shadowRoot){w.shadowRoot=!0;for(const z of u.shadowRoot.childNodes){const $=_e(z,y,E);$&&w.children.push($)}}for(const z of u.childNodes){const L=_e(z,y,E||P);L&&w.children.push(L)}}}if(w.tagName==="a"&&w.children.length===0&&!w.attributes.href){const x=m(u);if(!(x&&x.width>0&&x.height>0||u.offsetWidth>0||u.offsetHeight>0))return null}w.extra=h.get(u)||null;const N=`${C.current++}`;return A[N]=w,N}a(_e,"buildDomTree");const fe=_e(document.body);return g.clearCache(),{rootId:fe,map:A}},"domTree"),DEFAULT_VIEWPORT_EXPANSION=-1;function resolveViewportExpansion(e){return e??DEFAULT_VIEWPORT_EXPANSION}a(resolveViewportExpansion,"resolveViewportExpansion");const newElementsCache=new WeakMap;function getFlatTree(e){const t=resolveViewportExpansion(e.viewportExpansion),o=[];for(const s of e.interactiveBlacklist||[])typeof s=="function"?o.push(s()):o.push(s);const n=[];for(const s of e.interactiveWhitelist||[])typeof s=="function"?n.push(s()):n.push(s);const r=domTree({doHighlightElements:!0,debugMode:!0,focusHighlightIndex:-1,viewportExpansion:t,interactiveBlacklist:o,interactiveWhitelist:n,highlightOpacity:e.highlightOpacity??0,highlightLabelOpacity:e.highlightLabelOpacity??.1}),i=window.location.href;for(const s in r.map){const c=r.map[s];if(c.isInteractive&&c.ref){const l=c.ref;newElementsCache.has(l)||(newElementsCache.set(l,i),c.isNew=!0)}}return r}a(getFlatTree,"getFlatTree");const globRegexCache=new Map;function globToRegex(e){let t=globRegexCache.get(e);if(!t){const o=e.replace(/[.+^${}()|[\]\\]/g,"\\$&");t=new RegExp(`^${o.replace(/\*/g,".*")}$`),globRegexCache.set(e,t)}return t}a(globToRegex,"globToRegex");function matchAttributes(e,t){const o={};for(const n of t)if(n.includes("*")){const r=globToRegex(n);for(const i of Object.keys(e))r.test(i)&&e[i].trim()&&(o[i]=e[i].trim())}else{const r=e[n];r&&r.trim()&&(o[n]=r.trim())}return o}a(matchAttributes,"matchAttributes");function flatTreeToString(e,t){const o=["title","type","checked","name","role","value","placeholder","data-date-format","alt","aria-label","aria-expanded","data-state","aria-checked","id","for","target","aria-haspopup","aria-controls","aria-owns","contenteditable"],n=[...t||[],...o],r=a((f,g)=>f.length>g?f.substring(0,g)+"...":f,"capTextLength"),i=a(f=>{const g=e.map[f];if(!g)return null;if(g.type==="TEXT_NODE"){const m=g;return{type:"text",text:m.text,isVisible:m.isVisible,parent:null,children:[]}}else{const m=g,T=[];if(m.children)for(const I of m.children){const A=i(I);A&&(A.parent=null,T.push(A))}return{type:"element",tagName:m.tagName,attributes:m.attributes??{},isVisible:m.isVisible??!1,isInteractive:m.isInteractive??!1,isTopElement:m.isTopElement??!1,isNew:m.isNew??!1,highlightIndex:m.highlightIndex,parent:null,children:T,extra:m.extra??{}}}},"buildTreeNode"),s=a((f,g=null)=>{f.parent=g;for(const m of f.children)s(m,f)},"setParentReferences"),c=i(e.rootId);if(!c)return"";s(c);const l=a(f=>{let g=f.parent;for(;g;){if(g.type==="element"&&g.highlightIndex!==void 0)return!0;g=g.parent}return!1},"hasParentWithHighlightIndex"),d=a((f,g,m)=>{let T=g;const I=" ".repeat(g);if(f.type==="element"){if(f.highlightIndex!==void 0){T+=1;const A=getAllTextTillNextClickableElement(f);let C="";if(n.length>0&&f.attributes){const k=matchAttributes(f.attributes,n),O=Object.keys(k);if(O.length>1){const H=new Set,le={};for(const ue of O){const K=k[ue];K.length>5&&(K in le?H.add(ue):le[K]=ue)}for(const ue of H)delete k[ue]}k.role===f.tagName&&delete k.role;const Ie=["aria-label","placeholder","title"];for(const H of Ie)k[H]&&k[H].toLowerCase().trim()===A.toLowerCase().trim()&&delete k[H];Object.keys(k).length>0&&(C=Object.entries(k).map(([H,le])=>`${H}=${r(le,20)}`).join(" "))}const D=f.isNew?`*[${f.highlightIndex}]`:`[${f.highlightIndex}]`;let v=`${I}${D}<${f.tagName??""}`;if(C&&(v+=` ${C}`),f.extra&&f.extra.scrollable){let k="";f.extra.scrollData?.left&&(k+=`left=${f.extra.scrollData.left}, `),f.extra.scrollData?.top&&(k+=`top=${f.extra.scrollData.top}, `),f.extra.scrollData?.right&&(k+=`right=${f.extra.scrollData.right}, `),f.extra.scrollData?.bottom&&(k+=`bottom=${f.extra.scrollData.bottom}`),v+=` data-scrollable="${k}"`}if(A){const k=A.trim();C||(v+=" "),v+=`>${k}`}else C||(v+=" ");v+=" />",m.push(v)}for(const A of f.children)d(A,T,m)}else if(f.type==="text"){if(l(f))return;f.parent&&f.parent.type==="element"&&f.parent.isVisible&&f.parent.isTopElement&&m.push(`${I}${f.text??""}`)}},"processNode"),h=[];return d(c,0,h),h.join(`
|
|
240
240
|
`)}a(flatTreeToString,"flatTreeToString");const getAllTextTillNextClickableElement=a((e,t=-1)=>{const o=[],n=a((r,i)=>{if(!(t!==-1&&i>t)&&!(r.type==="element"&&r!==e&&r.highlightIndex!==void 0)){if(r.type==="text"&&r.text)o.push(r.text);else if(r.type==="element")for(const s of r.children)n(s,i+1)}},"collectText");return n(e,0),o.join(`
|
|
241
241
|
`).trim()},"getAllTextTillNextClickableElement");function getSelectorMap(e){const t=new Map,o=Object.keys(e.map);for(const n of o){const r=e.map[n];r.isInteractive&&typeof r.highlightIndex=="number"&&t.set(r.highlightIndex,r)}return t}a(getSelectorMap,"getSelectorMap");function getElementTextMap(e){const t=e.split(`
|
|
242
242
|
`).map(n=>n.trim()).filter(n=>n.length>0),o=new Map;for(const n of t){const i=/^\[(\d+)\]<[^>]+>([^<]*)/.exec(n);if(i){const s=parseInt(i[1],10);o.set(s,n)}}return o}a(getElementTextMap,"getElementTextMap");function cleanUpHighlights(){const e=window._highlightCleanupFunctions||[];for(const t of e)typeof t=="function"&&t();window._highlightCleanupFunctions=[]}a(cleanUpHighlights,"cleanUpHighlights"),window.addEventListener("popstate",()=>{cleanUpHighlights()}),window.addEventListener("hashchange",()=>{cleanUpHighlights()}),window.addEventListener("beforeunload",()=>{cleanUpHighlights()});const navigation=window.navigation;if(navigation&&typeof navigation.addEventListener=="function")navigation.addEventListener("navigate",()=>{cleanUpHighlights()});else{let e=window.location.href;setInterval(()=>{window.location.href!==e&&(e=window.location.href,cleanUpHighlights())},500)}function getPageInfo(){const e=window.innerWidth,t=window.innerHeight,o=Math.max(document.documentElement.scrollWidth,document.body.scrollWidth||0),n=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight||0),r=window.scrollX||window.pageXOffset||document.documentElement.scrollLeft||0,i=window.scrollY||window.pageYOffset||document.documentElement.scrollTop||0,s=Math.max(0,n-(window.innerHeight+i)),c=Math.max(0,o-(window.innerWidth+r));return{viewport_width:e,viewport_height:t,page_width:o,page_height:n,scroll_x:r,scroll_y:i,pixels_above:i,pixels_below:s,pages_above:t>0?i/t:0,pages_below:t>0?s/t:0,total_pages:t>0?n/t:0,current_page_position:i/Math.max(1,n-t),pixels_left:r,pixels_right:c}}a(getPageInfo,"getPageInfo");function patchReact(e){const t=document.querySelectorAll('[data-reactroot], [data-reactid], [data-react-checksum], #root, #app, [id^="root-"], [id^="app-"], #adex-wrapper, #adex-root');for(const o of t)o.setAttribute("data-page-agent-not-interactive","true")}a(patchReact,"patchReact");const _PageController=class _PageController extends EventTarget{config;flatTree=null;selectorMap=new Map;elementTextMap=new Map;simplifiedHTML="<EMPTY>";lastTimeUpdate=0;isIndexed=!1;mask=null;maskReady=null;constructor(e={}){super(),this.config=e,patchReact(),e.enableMask&&this.initMask()}initMask(){this.maskReady===null&&(this.maskReady=(async()=>{const{SimulatorMask:e}=await Promise.resolve().then(()=>SimulatorMask$1);this.mask=new e})())}async getCurrentUrl(){return window.location.href}async getLastUpdateTime(){return this.lastTimeUpdate}async getBrowserState(){const e=window.location.href,t=document.title,o=getPageInfo(),n=resolveViewportExpansion(this.config.viewportExpansion);await this.updateTree();const r=this.simplifiedHTML,i=`Current Page: [${t}](${e})`,s=`Page info: ${o.viewport_width}x${o.viewport_height}px viewport, ${o.page_width}x${o.page_height}px total page size, ${o.pages_above.toFixed(1)} pages above, ${o.pages_below.toFixed(1)} pages below, ${o.total_pages.toFixed(1)} total pages, at ${(o.current_page_position*100).toFixed(0)}% of page`,c=n===-1?"Interactive elements from top layer of the current page (full page):":"Interactive elements from top layer of the current page inside the viewport:",d=o.pixels_above>4&&n!==-1?`... ${o.pixels_above} pixels above (${o.pages_above.toFixed(1)} pages) - scroll to see more ...`:"[Start of page]",h=`${i}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "page-agent",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "1.5.
|
|
4
|
+
"version": "1.5.8",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/esm/page-agent.js",
|
|
7
7
|
"module": "./dist/esm/page-agent.js",
|
|
@@ -44,10 +44,10 @@
|
|
|
44
44
|
"postpublish": "node -e \"['README.md','LICENSE'].forEach(f=>{try{require('fs').unlinkSync(f)}catch{}})\""
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@page-agent/core": "1.5.
|
|
48
|
-
"@page-agent/llms": "1.5.
|
|
49
|
-
"@page-agent/page-controller": "1.5.
|
|
50
|
-
"@page-agent/ui": "1.5.
|
|
47
|
+
"@page-agent/core": "1.5.8",
|
|
48
|
+
"@page-agent/llms": "1.5.8",
|
|
49
|
+
"@page-agent/page-controller": "1.5.8",
|
|
50
|
+
"@page-agent/ui": "1.5.8",
|
|
51
51
|
"chalk": "^5.6.2"
|
|
52
52
|
},
|
|
53
53
|
"peerDependencies": {
|