page-agent 1.0.0-beta.3 → 1.0.0-beta.5
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/README.md +15 -17
- package/dist/iife/page-agent.demo.js +4 -4
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -19,35 +19,39 @@ The GUI Agent Living in Your Webpage. Control web interfaces with natural langua
|
|
|
19
19
|
|
|
20
20
|
## ✨ Features
|
|
21
21
|
|
|
22
|
-
- **🎯 Easy Integration**
|
|
22
|
+
- **🎯 Easy Integration**
|
|
23
|
+
- No python. No headless browser. No browser extension. Just in-page scripts.
|
|
23
24
|
- **🔐 Client-Side Processing**
|
|
24
25
|
- **🧠 DOM Extraction**
|
|
25
26
|
- **💬 Natural Language Interface**
|
|
26
27
|
- **🎨 UI with Human in the loop**
|
|
27
28
|
|
|
28
|
-
|
|
29
|
+
And 😉
|
|
29
30
|
|
|
30
|
-
|
|
31
|
+
- **🧪 `cross-page` control with an experimental chrome extension** - `-b feat/ext`
|
|
32
|
+
|
|
33
|
+
👉 [**🗺️ Roadmap**](https://github.com/alibaba/page-agent/issues/96)
|
|
31
34
|
|
|
32
35
|
## 🚀 Quick Start
|
|
33
36
|
|
|
34
|
-
###
|
|
37
|
+
### One-line integration
|
|
35
38
|
|
|
36
|
-
Fastest way to try PageAgent:
|
|
39
|
+
Fastest way to try PageAgent with our free Demo LLM:
|
|
37
40
|
|
|
38
41
|
```html
|
|
39
42
|
<script
|
|
40
|
-
src="https://cdn.jsdelivr.net/npm/page-agent@1.0.0-beta.
|
|
43
|
+
src="https://cdn.jsdelivr.net/npm/page-agent@1.0.0-beta.5/dist/iife/page-agent.demo.js"
|
|
41
44
|
crossorigin="true"
|
|
42
45
|
></script>
|
|
43
46
|
```
|
|
44
47
|
|
|
45
|
-
>
|
|
48
|
+
> - **⚠️ For technical evaluation only.** Demo LLM has rate limits and usage restrictions. May change without notice.
|
|
49
|
+
> - **🌷 Bring your own LLM API.**
|
|
46
50
|
|
|
47
51
|
| Mirrors | URL |
|
|
48
52
|
| ------- | ----------------------------------------------------------------------------------------- |
|
|
49
|
-
| Global | https://cdn.jsdelivr.net/npm/page-agent@1.0.0-beta.
|
|
50
|
-
| China | https://registry.npmmirror.com/page-agent/1.0.0-beta.
|
|
53
|
+
| Global | https://cdn.jsdelivr.net/npm/page-agent@1.0.0-beta.5/dist/iife/page-agent.demo.js |
|
|
54
|
+
| China | https://registry.npmmirror.com/page-agent/1.0.0-beta.5/files/dist/iife/page-agent.demo.js |
|
|
51
55
|
|
|
52
56
|
### NPM Installation
|
|
53
57
|
|
|
@@ -84,15 +88,9 @@ packages/
|
|
|
84
88
|
|
|
85
89
|
## 🤝 Contributing
|
|
86
90
|
|
|
87
|
-
We welcome contributions from the community!
|
|
88
|
-
|
|
89
|
-
1. Fork and clone. `git clone https://github.com/alibaba/page-agent.git && cd page-agent`
|
|
90
|
-
2. Install dependencies: `npm install`
|
|
91
|
-
3. Start development: `npm start`
|
|
92
|
-
|
|
93
|
-
More details in [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
91
|
+
We welcome contributions from the community! Follow our instructions in [CONTRIBUTING.md](CONTRIBUTING.md) for environment setup and local development.
|
|
94
92
|
|
|
95
|
-
Please read
|
|
93
|
+
Please read [Code of Conduct](CODE_OF_CONDUCT.md) before contributing.
|
|
96
94
|
|
|
97
95
|
## 👏 Acknowledgments
|
|
98
96
|
|
|
@@ -199,7 +199,7 @@ You must ALWAYS respond with a valid JSON in this exact format:
|
|
|
199
199
|
</output>
|
|
200
200
|
`;function normalizeResponse(e){let n=null;const r=e.choices?.[0];if(!r)throw new Error("No choices in response");const o=r.message;if(!o)throw new Error("No message in choice");const t=o.tool_calls?.[0];if(t?.function?.arguments)n=safeJsonParse(t.function.arguments),t.function.name&&t.function.name!=="AgentOutput"&&(console.log(chalk.yellow("[normalizeResponse] #1: fixing tool_call")),n={action:safeJsonParse(n)});else if(o.content){const i=o.content.trim(),a=retrieveJsonFromString(i);if(a)n=safeJsonParse(a),n?.name==="AgentOutput"&&(console.log(chalk.yellow("[normalizeResponse] #2: fixing tool_call")),n=safeJsonParse(n.arguments)),n?.type==="function"&&(console.log(chalk.yellow("[normalizeResponse] #3: fixing tool_call")),n=safeJsonParse(n.function.arguments)),!n?.action&&!n?.evaluation_previous_goal&&!n?.memory&&!n?.next_goal&&!n?.thinking&&(console.log(chalk.yellow("[normalizeResponse] #4: fixing tool_call")),n={action:safeJsonParse(n)});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 n=safeJsonParse(n),n.action&&(n.action=safeJsonParse(n.action)),n.action||(console.log(chalk.yellow("[normalizeResponse] #5: fixing tool_call")),n.action={name:"wait",input:{seconds:1}}),{...e,choices:[{...r,message:{...o,tool_calls:[{...t||{},function:{...t?.function||{},name:"AgentOutput",arguments:JSON.stringify(n)}}]}}]}}s(normalizeResponse,"normalizeResponse");function safeJsonParse(e){if(typeof e=="string")try{return JSON.parse(e.trim())}catch{return e}return e}s(safeJsonParse,"safeJsonParse");function retrieveJsonFromString(e){try{const n=/({[\s\S]*})/.exec(e)??[];return n.length===0?null:JSON.parse(n[0])}catch{return null}}s(retrieveJsonFromString,"retrieveJsonFromString");async function waitFor$1(e){await new Promise(n=>setTimeout(n,e*1e3))}s(waitFor$1,"waitFor$1");function trimLines(e){return e.split(`
|
|
201
201
|
`).map(n=>n.trim()).join(`
|
|
202
|
-
`)}s(trimLines,"trimLines");function randomID(e){let n=Math.random().toString(36).substring(2,11);if(!e)return n;const r=1e3;let o=0;for(;e.includes(n);)if(n=Math.random().toString(36).substring(2,11),o++,o>r)throw new Error("randomID: too many try");return n}s(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}s(uid,"uid");function tool(e){return e}s(tool,"tool");const tools=new Map;tools.set("done",{description:"Complete task - provide a summary of results for the user. Set success=True if task completed successfully, false otherwise. Text should be your response to the user summarizing results.",inputSchema:z.object({text:z.string(),success:z.boolean().default(!0)}),execute:s(async function(e){return Promise.resolve("Task completed")},"execute")}),tools.set("wait",{description:"Wait for x seconds. default 1s (max 10 seconds, min 1 second). This can be used to wait until the page or data is fully loaded.",inputSchema:z.object({seconds:z.number().min(1).max(10).default(1)}),execute:s(async function(e){const n=await this.pageController.getLastUpdateTime(),r=Math.max(0,e.seconds-(Date.now()-n)/1e3);return console.log(`actualWaitTime: ${r} seconds`),await waitFor$1(r),this.states.totalWaitTime+=e.seconds,this.states.totalWaitTime>=3&&this.pushObservation(`You have waited ${this.states.totalWaitTime} seconds accumulatively. Do NOT wait any longer unless you have a good reason.`),`✅ 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:z.object({question:z.string()}),execute:s(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:z.object({index:z.int().min(0)}),execute:s(async function(e){return(await this.pageController.clickElement(e.index)).message},"execute")}),tools.set("input_text",{description:"Click and input text into a input interactive element",inputSchema:z.object({index:z.int().min(0),text:z.string()}),execute:s(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:z.object({index:z.int().min(0),text:z.string()}),execute:s(async function(e){return(await this.pageController.selectOption(e.index,e.text)).message},"execute")}),tools.set("scroll",{description:"Scroll the page by specified number of pages (set down=True to scroll down, down=False to scroll up, num_pages=number of pages to scroll like 0.5 for half page, 1.0 for one page, etc.). Optional index parameter to scroll within a specific element or its scroll container (works well for dropdowns and custom UI components). Optional pixels parameter to scroll by a specific number of pixels instead of pages.",inputSchema:z.object({down:z.boolean().default(!0),num_pages:z.number().min(0).max(10).optional().default(.1),pixels:z.number().int().min(0).optional(),index:z.number().int().min(0).optional()}),execute:s(async function(e){return(await this.pageController.scroll({...e,numPages:e.num_pages})).message},"execute")}),tools.set("scroll_horizontally",{description:"Scroll the page or element horizontally (set right=True to scroll right, right=False to scroll left, pixels=number of pixels to scroll). Optional index parameter to scroll within a specific element or its scroll container (works well for wide tables).",inputSchema:z.object({right:z.boolean().default(!0),pixels:z.number().int().min(0),index:z.number().int().min(0).optional()}),execute:s(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:z.object({script:z.string()}),execute:s(async function(e){return(await this.pageController.executeJavascript(e.script)).message},"execute")});function assert(e,n,r){if(!e){const o=n??"Assertion failed";throw console.error(chalk.red(`❌ assert: ${o}`)),new Error(o)}}s(assert,"assert");const ht=class ht extends EventTarget{constructor(r){super();N(this,C);re(this,"config");re(this,"id",uid());re(this,"tools");re(this,"disposed",!1);re(this,"task","");re(this,"taskId","");N(this,Fe,"idle");re(this,"onAskUser");N(this,Oe);N(this,ae,new AbortController);re(this,"pageController");re(this,"states",{totalWaitTime:0,lastURL:""});re(this,"history",[]);if(this.config={...r,maxSteps:r.maxSteps||DEFAULT_MAX_STEPS},E(this,Oe,new LLM(this.config)),this.tools=new Map(tools),this.pageController=r.pageController,g(this,Oe).addEventListener("retry",o=>{const{attempt:t,maxAttempts:i}=o.detail;this.emitActivity({type:"retrying",attempt:t,maxAttempts:i}),this.history.push({type:"
|
|
202
|
+
`)}s(trimLines,"trimLines");function randomID(e){let n=Math.random().toString(36).substring(2,11);if(!e)return n;const r=1e3;let o=0;for(;e.includes(n);)if(n=Math.random().toString(36).substring(2,11),o++,o>r)throw new Error("randomID: too many try");return n}s(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}s(uid,"uid");function tool(e){return e}s(tool,"tool");const tools=new Map;tools.set("done",{description:"Complete task - provide a summary of results for the user. Set success=True if task completed successfully, false otherwise. Text should be your response to the user summarizing results.",inputSchema:z.object({text:z.string(),success:z.boolean().default(!0)}),execute:s(async function(e){return Promise.resolve("Task completed")},"execute")}),tools.set("wait",{description:"Wait for x seconds. default 1s (max 10 seconds, min 1 second). This can be used to wait until the page or data is fully loaded.",inputSchema:z.object({seconds:z.number().min(1).max(10).default(1)}),execute:s(async function(e){const n=await this.pageController.getLastUpdateTime(),r=Math.max(0,e.seconds-(Date.now()-n)/1e3);return console.log(`actualWaitTime: ${r} seconds`),await waitFor$1(r),this.states.totalWaitTime+=e.seconds,this.states.totalWaitTime>=3&&this.pushObservation(`You have waited ${this.states.totalWaitTime} seconds accumulatively. Do NOT wait any longer unless you have a good reason.`),`✅ 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:z.object({question:z.string()}),execute:s(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:z.object({index:z.int().min(0)}),execute:s(async function(e){return(await this.pageController.clickElement(e.index)).message},"execute")}),tools.set("input_text",{description:"Click and input text into a input interactive element",inputSchema:z.object({index:z.int().min(0),text:z.string()}),execute:s(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:z.object({index:z.int().min(0),text:z.string()}),execute:s(async function(e){return(await this.pageController.selectOption(e.index,e.text)).message},"execute")}),tools.set("scroll",{description:"Scroll the page by specified number of pages (set down=True to scroll down, down=False to scroll up, num_pages=number of pages to scroll like 0.5 for half page, 1.0 for one page, etc.). Optional index parameter to scroll within a specific element or its scroll container (works well for dropdowns and custom UI components). Optional pixels parameter to scroll by a specific number of pixels instead of pages.",inputSchema:z.object({down:z.boolean().default(!0),num_pages:z.number().min(0).max(10).optional().default(.1),pixels:z.number().int().min(0).optional(),index:z.number().int().min(0).optional()}),execute:s(async function(e){return(await this.pageController.scroll({...e,numPages:e.num_pages})).message},"execute")}),tools.set("scroll_horizontally",{description:"Scroll the page or element horizontally (set right=True to scroll right, right=False to scroll left, pixels=number of pixels to scroll). Optional index parameter to scroll within a specific element or its scroll container (works well for wide tables).",inputSchema:z.object({right:z.boolean().default(!0),pixels:z.number().int().min(0),index:z.number().int().min(0).optional()}),execute:s(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:z.object({script:z.string()}),execute:s(async function(e){return(await this.pageController.executeJavascript(e.script)).message},"execute")});function assert(e,n,r){if(!e){const o=n??"Assertion failed";throw console.error(chalk.red(`❌ assert: ${o}`)),new Error(o)}}s(assert,"assert");const ht=class ht extends EventTarget{constructor(r){super();N(this,C);re(this,"config");re(this,"id",uid());re(this,"tools");re(this,"disposed",!1);re(this,"task","");re(this,"taskId","");N(this,Fe,"idle");re(this,"onAskUser");N(this,Oe);N(this,ae,new AbortController);re(this,"pageController");re(this,"states",{totalWaitTime:0,lastURL:""});re(this,"history",[]);if(this.config={...r,maxSteps:r.maxSteps||DEFAULT_MAX_STEPS},E(this,Oe,new LLM(this.config)),this.tools=new Map(tools),this.pageController=r.pageController,g(this,Oe).addEventListener("retry",o=>{const{attempt:t,maxAttempts:i}=o.detail;this.emitActivity({type:"retrying",attempt:t,maxAttempts:i}),this.history.push({type:"retry",message:`LLM retry attempt ${t} of ${i}`,attempt:t,maxAttempts:i}),y(this,C,Je).call(this)}),g(this,Oe).addEventListener("error",o=>{const t=o.detail.error,i=String(t);this.emitActivity({type:"error",message:i}),this.history.push({type:"error",message:i,rawResponse:t.rawResponse}),y(this,C,Je).call(this)}),this.config.customTools)for(const[o,t]of Object.entries(this.config.customTools)){if(t===null){this.tools.delete(o);continue}this.tools.set(o,t)}this.config.experimentalScriptExecutionTool||this.tools.delete("execute_javascript")}get status(){return g(this,Fe)}emitActivity(r){this.dispatchEvent(new CustomEvent("activity",{detail:r}))}pushObservation(r){this.history.push({type:"observation",content:r}),y(this,C,Je).call(this)}async execute(r){if(!r)throw new Error("Task is required");this.task=r,this.taskId=uid(),this.onAskUser||this.tools.delete("ask_user");const o=this.config.onBeforeStep,t=this.config.onAfterStep,i=this.config.onBeforeTask,a=this.config.onAfterTask;await i?.(this),await this.pageController.showMask(),g(this,ae)&&(g(this,ae).abort(),E(this,ae,new AbortController)),this.history=[],y(this,C,kt).call(this,"running"),y(this,C,Je).call(this),this.states={totalWaitTime:0,lastURL:""};try{let c=0;for(;;){if(await y(this,C,jt).call(this,c),await o?.(this,c),console.group(`step: ${c}`),g(this,ae).signal.aborted)throw new Error("AbortError");console.log(chalk.blue("Thinking...")),this.emitActivity({type:"thinking"});const l=await g(this,Oe).invoke([{role:"system",content:y(this,C,Dt).call(this)},{role:"user",content:await y(this,C,At).call(this)}],{AgentOutput:y(this,C,Ut).call(this)},g(this,ae).signal,{toolChoiceName:"AgentOutput",normalizeResponse}),u=l.toolResult,d=u.input,p=u.output,f={evaluation_previous_goal:d.evaluation_previous_goal,memory:d.memory,next_goal:d.next_goal},h=Object.keys(d.action)[0],$={name:h,input:d.action[h],output:p};if(this.history.push({type:"step",stepIndex:c,reflection:f,action:$,usage:l.usage,rawResponse:l.rawResponse}),y(this,C,Je).call(this),console.log(chalk.green("Step finished:"),h),console.groupEnd(),await t?.(this,this.history),c++,c>this.config.maxSteps){y(this,C,st).call(this,"Step count exceeded maximum limit",!1);const k={success:!1,data:"Step count exceeded maximum limit",history:this.history};return await a?.(this,k),k}if(h==="done"){const k=$.input?.success??!1,Z=$.input?.text||"no text provided";console.log(chalk.green.bold("Task completed"),k,Z),y(this,C,st).call(this,Z,k);const D={success:k,data:Z,history:this.history};return await a?.(this,D),D}}}catch(c){console.error("Task failed",c);const l=String(c);this.emitActivity({type:"error",message:l}),y(this,C,st).call(this,l,!1);const u={success:!1,data:l,history:this.history};return await a?.(this,u),u}}dispose(r){console.log("Disposing PageAgent..."),this.disposed=!0,this.pageController.dispose(),this.history=[],g(this,ae).abort(r??"PageAgent disposed"),this.dispatchEvent(new Event("dispose")),this.config.onDispose?.(this,r)}};Fe=new WeakMap,Oe=new WeakMap,ae=new WeakMap,C=new WeakSet,Ot=s(function(){this.dispatchEvent(new Event("statuschange"))},"#emitStatusChange"),Je=s(function(){this.dispatchEvent(new Event("historychange"))},"#emitHistoryChange"),kt=s(function(r){g(this,Fe)!==r&&(E(this,Fe,r),y(this,C,Ot).call(this))},"#setStatus"),Ut=s(function(){const r=this.tools,o=Array.from(r.entries()).map(([a,c])=>z.object({[a]:c.inputSchema}).describe(c.description)),t=z.union(o);return{description:"You MUST call this tool every step. Outputs your reflections and next action.",inputSchema:z.object({evaluation_previous_goal:z.string().optional(),memory:z.string().optional(),next_goal:z.string().optional(),action:t}),execute:s(async a=>{if(g(this,ae).signal.aborted)throw new Error("AbortError");console.log(chalk.blue.bold("MacroTool execute"),a);const c=a.action,l=Object.keys(c)[0],u=c[l],d=[];a.evaluation_previous_goal&&d.push(`✅: ${a.evaluation_previous_goal}`),a.memory&&d.push(`💾: ${a.memory}`),a.next_goal&&d.push(`🎯: ${a.next_goal}`);const p=d.length>0?d.join(`
|
|
203
203
|
`):"";p&&console.log(p);const f=r.get(l);assert(f,`Tool ${l} not found. (@note should have been caught before this!!!)`),console.log(chalk.blue.bold(`Executing tool: ${l}`),u),this.emitActivity({type:"executing",tool:l,input:u});const h=Date.now(),$=await f.execute.bind(this)(u),k=Date.now()-h;return console.log(chalk.green.bold(`Tool (${l}) executed for ${k}ms`),$),this.emitActivity({type:"executed",tool:l,input:u,output:$,duration:k}),l!=="wait"&&(this.states.totalWaitTime=0),{input:a,output:$}},"execute")}},"#packMacroTool"),Dt=s(function(){let r=SYSTEM_PROMPT;const o=this.config.language==="zh-CN"?"中文":"English";return r=r.replace(/Default working language: \*\*.*?\*\*/,`Default working language: **${o}**`),r},"#getSystemPrompt"),Nt=s(async function(){const{instructions:r}=this.config;if(!r)return"";const o=r.system?.trim(),t=await this.pageController.getCurrentUrl();let i;if(r.getPageInstructions)try{i=r.getPageInstructions(t)?.trim()}catch(c){console.error(chalk.red("[PageAgent] Failed to execute getPageInstructions callback:"),c)}if(!o&&!i)return"";let a=`<instructions>
|
|
204
204
|
`;return o&&(a+=`<system_instructions>
|
|
205
205
|
${o}
|
|
@@ -241,11 +241,11 @@ ${i}
|
|
|
241
241
|
`)},"#getBrowserState"),s(ht,"PageAgentCore");let PageAgentCore=ht;async function waitFor(e){await new Promise(n=>setTimeout(n,e*1e3))}s(waitFor,"waitFor");async function movePointerToElement(e){const n=e.getBoundingClientRect(),r=n.left+n.width/2,o=n.top+n.height/2;window.dispatchEvent(new CustomEvent("PageAgent::MovePointerTo",{detail:{x:r,y:o}})),await waitFor(.3)}s(movePointerToElement,"movePointerToElement");function getElementByIndex(e,n){const r=e.get(n);if(!r)throw new Error(`No interactive element found at index ${n}`);const o=r.ref;if(!o)throw new Error(`Element at index ${n} does not have a reference`);if(!(o instanceof HTMLElement))throw new Error(`Element at index ${n} is not an HTMLElement`);return o}s(getElementByIndex,"getElementByIndex");let lastClickedElement=null;function blurLastClickedElement(){lastClickedElement&&(lastClickedElement.blur(),lastClickedElement.dispatchEvent(new MouseEvent("mouseout",{bubbles:!0,cancelable:!0})),lastClickedElement=null)}s(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(.1)}s(clickElement,"clickElement");const nativeInputValueSetter=Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype,"value").set,nativeTextAreaValueSetter=Object.getOwnPropertyDescriptor(window.HTMLTextAreaElement.prototype,"value").set;async function inputTextElement(e,n){if(!(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement))throw new Error("Element is not an input or textarea");await clickElement(e),e instanceof HTMLTextAreaElement?nativeTextAreaValueSetter.call(e,n):nativeInputValueSetter.call(e,n);const r=new Event("input",{bubbles:!0});e.dispatchEvent(r),await waitFor(.1),blurLastClickedElement()}s(inputTextElement,"inputTextElement");async function selectOptionElement(e,n){if(!(e instanceof HTMLSelectElement))throw new Error("Element is not a select element");const o=Array.from(e.options).find(t=>t.textContent?.trim()===n.trim());if(!o)throw new Error(`Option with text "${n}" not found in select element`);e.value=o.value,e.dispatchEvent(new Event("change",{bubbles:!0})),await waitFor(.1)}s(selectOptionElement,"selectOptionElement");async function scrollIntoViewIfNeeded(e){const n=e;n.scrollIntoViewIfNeeded?n.scrollIntoViewIfNeeded():n.scrollIntoView({behavior:"auto",block:"center",inline:"nearest"})}s(scrollIntoViewIfNeeded,"scrollIntoViewIfNeeded");async function scrollVertically(e,n,r){if(r){const c=r;console.log("[SCROLL DEBUG] Starting direct container scroll for element:",c.tagName);let l=c,u=!1,d=null,p=0,f=0;const h=n;for(;l&&f<10;){const $=window.getComputedStyle(l),k=/(auto|scroll|overlay)/.test($.overflowY),Z=l.scrollHeight>l.clientHeight;if(console.log("[SCROLL DEBUG] Checking element:",l.tagName,"hasScrollableY:",k,"canScrollVertically:",Z,"scrollHeight:",l.scrollHeight,"clientHeight:",l.clientHeight),k&&Z){const D=l.scrollTop,B=l.scrollHeight-l.clientHeight;let x=h/3;x>0?x=Math.min(x,B-D):x=Math.max(x,-D),l.scrollTop=D+x;const w=l.scrollTop,O=w-D;if(console.log("[SCROLL DEBUG] Scroll attempt:",l.tagName,"before:",D,"after:",w,"delta:",O),Math.abs(O)>.5){u=!0,d=l,p=O,console.log("[SCROLL DEBUG] Successfully scrolled container:",l.tagName,"delta:",O);break}}if(l===document.body||l===document.documentElement)break;l=l.parentElement,f++}return u?`Scrolled container (${d?.tagName}) by ${p}px`:`No scrollable container found for element (${c.tagName})`}const o=n,t=s(c=>c.clientHeight>=window.innerHeight*.5,"bigEnough"),i=s(c=>c&&/(auto|scroll|overlay)/.test(getComputedStyle(c).overflowY)&&c.scrollHeight>c.clientHeight&&t(c),"canScroll");let a=document.activeElement;for(;a&&!i(a)&&a!==document.body;)a=a.parentElement;if(a=i(a)?a:Array.from(document.querySelectorAll("*")).find(i)||document.scrollingElement||document.documentElement,a===document.scrollingElement||a===document.documentElement||a===document.body){const c=window.scrollY,l=document.documentElement.scrollHeight-window.innerHeight;window.scrollBy(0,o);const u=window.scrollY,d=u-c;if(Math.abs(d)<1)return o>0?"⚠️ Already at the bottom of the page, cannot scroll down further.":"⚠️ Already at the top of the page, cannot scroll up further.";const p=o>0&&u>=l-1,f=o<0&&u<=1;return p?`✅ Scrolled page by ${d}px. Reached the bottom of the page.`:f?`✅ Scrolled page by ${d}px. Reached the top of the page.`:`✅ Scrolled page by ${d}px.`}else{const c=a.scrollTop,l=a.scrollHeight-a.clientHeight;a.scrollBy({top:o,behavior:"smooth"}),await waitFor(.1);const u=a.scrollTop,d=u-c;if(Math.abs(d)<1)return o>0?`⚠️ Already at the bottom of container (${a.tagName}), cannot scroll down further.`:`⚠️ Already at the top of container (${a.tagName}), cannot scroll up further.`;const p=o>0&&u>=l-1,f=o<0&&u<=1;return p?`✅ Scrolled container (${a.tagName}) by ${d}px. Reached the bottom.`:f?`✅ Scrolled container (${a.tagName}) by ${d}px. Reached the top.`:`✅ Scrolled container (${a.tagName}) by ${d}px.`}}s(scrollVertically,"scrollVertically");async function scrollHorizontally(e,n,r){if(r){const c=r;console.log("[SCROLL DEBUG] Starting direct container scroll for element:",c.tagName);let l=c,u=!1,d=null,p=0,f=0;const h=e?n:-n;for(;l&&f<10;){const $=window.getComputedStyle(l),k=/(auto|scroll|overlay)/.test($.overflowX),Z=l.scrollWidth>l.clientWidth;if(console.log("[SCROLL DEBUG] Checking element:",l.tagName,"hasScrollableX:",k,"canScrollHorizontally:",Z,"scrollWidth:",l.scrollWidth,"clientWidth:",l.clientWidth),k&&Z){const D=l.scrollLeft,B=l.scrollWidth-l.clientWidth;let x=h/3;x>0?x=Math.min(x,B-D):x=Math.max(x,-D),l.scrollLeft=D+x;const w=l.scrollLeft,O=w-D;if(console.log("[SCROLL DEBUG] Scroll attempt:",l.tagName,"before:",D,"after:",w,"delta:",O),Math.abs(O)>.5){u=!0,d=l,p=O,console.log("[SCROLL DEBUG] Successfully scrolled container:",l.tagName,"delta:",O);break}}if(l===document.body||l===document.documentElement)break;l=l.parentElement,f++}return u?`Scrolled container (${d?.tagName}) horizontally by ${p}px`:`No horizontally scrollable container found for element (${c.tagName})`}const o=e?n:-n,t=s(c=>c.clientWidth>=window.innerWidth*.5,"bigEnough"),i=s(c=>c&&/(auto|scroll|overlay)/.test(getComputedStyle(c).overflowX)&&c.scrollWidth>c.clientWidth&&t(c),"canScroll");let a=document.activeElement;for(;a&&!i(a)&&a!==document.body;)a=a.parentElement;if(a=i(a)?a:Array.from(document.querySelectorAll("*")).find(i)||document.scrollingElement||document.documentElement,a===document.scrollingElement||a===document.documentElement||a===document.body){const c=window.scrollX,l=document.documentElement.scrollWidth-window.innerWidth;window.scrollBy(o,0);const u=window.scrollX,d=u-c;if(Math.abs(d)<1)return o>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 p=o>0&&u>=l-1,f=o<0&&u<=1;return p?`✅ Scrolled page by ${d}px. Reached the right edge of the page.`:f?`✅ Scrolled page by ${d}px. Reached the left edge of the page.`:`✅ Scrolled page horizontally by ${d}px.`}else{const c=a.scrollLeft,l=a.scrollWidth-a.clientWidth;a.scrollBy({left:o,behavior:"smooth"}),await waitFor(.1);const u=a.scrollLeft,d=u-c;if(Math.abs(d)<1)return o>0?`⚠️ Already at the right edge of container (${a.tagName}), cannot scroll right further.`:`⚠️ Already at the left edge of container (${a.tagName}), cannot scroll left further.`;const p=o>0&&u>=l-1,f=o<0&&u<=1;return p?`✅ Scrolled container (${a.tagName}) by ${d}px. Reached the right edge.`:f?`✅ Scrolled container (${a.tagName}) by ${d}px. Reached the left edge.`:`✅ Scrolled container (${a.tagName}) horizontally by ${d}px.`}}s(scrollHorizontally,"scrollHorizontally");const VIEWPORT_EXPANSION=-1,domTree=s((e={doHighlightElements:!0,focusHighlightIndex:-1,viewportExpansion:0,debugMode:!1,interactiveBlacklist:[],interactiveWhitelist:[],highlightOpacity:.1,highlightLabelOpacity:.5})=>{const{interactiveBlacklist:n,interactiveWhitelist:r,highlightOpacity:o,highlightLabelOpacity:t}=e,{doHighlightElements:i,focusHighlightIndex:a,viewportExpansion:c,debugMode:l}=e;let u=0;const d=new WeakMap;function p(m,_){!m||m.nodeType!==Node.ELEMENT_NODE||d.set(m,{...d.get(m),..._})}s(p,"addExtraData");const f={boundingRects:new WeakMap,clientRects:new WeakMap,computedStyles:new WeakMap,clearCache:s(()=>{f.boundingRects=new WeakMap,f.clientRects=new WeakMap,f.computedStyles=new WeakMap},"clearCache")};function h(m){if(!m)return null;if(f.boundingRects.has(m))return f.boundingRects.get(m);const _=m.getBoundingClientRect();return _&&f.boundingRects.set(m,_),_}s(h,"getCachedBoundingRect");function $(m){if(!m)return null;if(f.computedStyles.has(m))return f.computedStyles.get(m);const _=window.getComputedStyle(m);return _&&f.computedStyles.set(m,_),_}s($,"getCachedComputedStyle");function k(m){if(!m)return null;if(f.clientRects.has(m))return f.clientRects.get(m);const _=m.getClientRects();return _&&f.clientRects.set(m,_),_}s(k,"getCachedClientRects");const Z={},D={current:0},B="playwright-highlight-container";function x(m,_,U=null){if(!m)return _;const b=[];let S=null,j=20,I=16,P=null;try{let T=document.getElementById(B);T||(T=document.createElement("div"),T.id=B,T.style.position="fixed",T.style.pointerEvents="none",T.style.top="0",T.style.left="0",T.style.width="100%",T.style.height="100%",T.style.zIndex="2147483640",T.style.backgroundColor="transparent",document.body.appendChild(T));const L=m.getClientRects();if(!L||L.length===0)return _;const Q=["#FF0000","#00FF00","#0000FF","#FFA500","#800080","#008080","#FF69B4","#4B0082","#FF4500","#2E8B57","#DC143C","#4682B4"],K=_%Q.length;let Ze=Q[K];const te=Ze+Math.floor(o*255).toString(16).padStart(2,"0");Ze=Ze+Math.floor(t*255).toString(16).padStart(2,"0");let oe={x:0,y:0};if(U){const J=U.getBoundingClientRect();oe.x=J.left,oe.y=J.top}const ve=document.createDocumentFragment();for(const J of L){if(J.width===0||J.height===0)continue;const G=document.createElement("div");G.style.position="fixed",G.style.border=`2px solid ${Ze}`,G.style.backgroundColor=te,G.style.pointerEvents="none",G.style.boxSizing="border-box";const F=J.top+oe.y,Se=J.left+oe.x;G.style.top=`${F}px`,G.style.left=`${Se}px`,G.style.width=`${J.width}px`,G.style.height=`${J.height}px`,ve.appendChild(G),b.push({element:G,initialRect:J})}const _e=L[0];S=document.createElement("div"),S.className="playwright-highlight-label",S.style.position="fixed",S.style.background=Ze,S.style.color="white",S.style.padding="1px 4px",S.style.borderRadius="4px",S.style.fontSize=`${Math.min(12,Math.max(8,_e.height/2))}px`,S.textContent=_.toString(),j=S.offsetWidth>0?S.offsetWidth:j,I=S.offsetHeight>0?S.offsetHeight:I;const Ce=_e.top+oe.y,tt=_e.left+oe.x;let ot=Ce+2,Ve=tt+_e.width-j-2;(_e.width<j+4||_e.height<I+4)&&(ot=Ce-I-2,Ve=tt+_e.width-j,Ve<oe.x&&(Ve=tt)),ot=Math.max(0,Math.min(ot,window.innerHeight-I)),Ve=Math.max(0,Math.min(Ve,window.innerWidth-j)),S.style.top=`${ot}px`,S.style.left=`${Ve}px`,ve.appendChild(S);const at=s((J,G)=>{let F=0;return(...Se)=>{const ne=performance.now();if(!(ne-F<G))return F=ne,J(...Se)}},"throttleFunction")(s(()=>{const J=m.getClientRects();let G={x:0,y:0};if(U){const F=U.getBoundingClientRect();G.x=F.left,G.y=F.top}if(b.forEach((F,Se)=>{if(Se<J.length){const ne=J[Se],We=ne.top+G.y,Pe=ne.left+G.x;F.element.style.top=`${We}px`,F.element.style.left=`${Pe}px`,F.element.style.width=`${ne.width}px`,F.element.style.height=`${ne.height}px`,F.element.style.display=ne.width===0||ne.height===0?"none":"block"}else F.element.style.display="none"}),J.length<b.length)for(let F=J.length;F<b.length;F++)b[F].element.style.display="none";if(S&&J.length>0){const F=J[0],Se=F.top+G.y,ne=F.left+G.x;let We=Se+2,Pe=ne+F.width-j-2;(F.width<j+4||F.height<I+4)&&(We=Se-I-2,Pe=ne+F.width-j,Pe<G.x&&(Pe=ne)),We=Math.max(0,Math.min(We,window.innerHeight-I)),Pe=Math.max(0,Math.min(Pe,window.innerWidth-j)),S.style.top=`${We}px`,S.style.left=`${Pe}px`,S.style.display="block"}else S&&(S.style.display="none")},"updatePositions"),16);return window.addEventListener("scroll",at,!0),window.addEventListener("resize",at),P=s(()=>{window.removeEventListener("scroll",at,!0),window.removeEventListener("resize",at),b.forEach(J=>J.element.remove()),S&&S.remove()},"cleanupFn"),T.appendChild(ve),_+1}finally{P&&(window._highlightCleanupFunctions=window._highlightCleanupFunctions||[]).push(P)}}s(x,"highlightElement");function w(m){if(!m||m.nodeType!==Node.ELEMENT_NODE)return null;const _=$(m);if(!_)return null;const U=_.display;if(U==="inline"||U==="inline-block")return null;const b=_.overflowX,S=_.overflowY,j=b==="auto"||b==="scroll",I=S==="auto"||S==="scroll";if(!j&&!I)return null;const P=m.scrollWidth-m.clientWidth,T=m.scrollHeight-m.clientHeight,L=4;if(P<L&&T<L||!I&&P<L||!j&&T<L)return null;const Q=m.scrollTop,K=m.scrollLeft,Ze=m.scrollWidth-m.clientWidth-m.scrollLeft,te=m.scrollHeight-m.clientHeight-m.scrollTop,oe={top:Q,right:Ze,bottom:te,left:K};return p(m,{scrollable:!0,scrollData:oe}),oe}s(w,"isScrollableElement");function O(m){try{if(c===-1){const I=m.parentElement;if(!I)return!1;try{return I.checkVisibility({checkOpacity:!0,checkVisibilityCSS:!0})}catch{const T=window.getComputedStyle(I);return T.display!=="none"&&T.visibility!=="hidden"&&T.opacity!=="0"}}const _=document.createRange();_.selectNodeContents(m);const U=_.getClientRects();if(!U||U.length===0)return!1;let b=!1,S=!1;for(const I of U)if(I.width>0&&I.height>0&&(b=!0,!(I.bottom<-c||I.top>window.innerHeight+c||I.right<-c||I.left>window.innerWidth+c))){S=!0;break}if(!b||!S)return!1;const j=m.parentElement;if(!j)return!1;try{return j.checkVisibility({checkOpacity:!0,checkVisibilityCSS:!0})}catch{const P=window.getComputedStyle(j);return P.display!=="none"&&P.visibility!=="hidden"&&P.opacity!=="0"}}catch(_){return console.warn("Error checking text node visibility:",_),!1}}s(O,"isTextNodeVisible");function Ee(m){if(!m||!m.tagName)return!1;const _=new Set(["body","div","main","article","section","nav","header","footer"]),U=m.tagName.toLowerCase();return _.has(U)?!0:!new Set(["svg","script","style","link","meta","noscript","template"]).has(U)}s(Ee,"isElementAccepted");function M(m){const _=$(m);return m.offsetWidth>0&&m.offsetHeight>0&&_?.visibility!=="hidden"&&_?.display!=="none"}s(M,"isElementVisible");function Y(m){if(!m||m.nodeType!==Node.ELEMENT_NODE||n.includes(m))return!1;if(r.includes(m))return!0;const _=m.tagName.toLowerCase(),U=$(m),b=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"]),S=new Set(["not-allowed","no-drop","wait","progress","initial","inherit"]);function j(te){return te.tagName.toLowerCase()==="html"?!1:!!(U?.cursor&&b.has(U.cursor))}if(s(j,"doesElementHaveInteractivePointer"),j(m))return!0;const P=new Set(["a","button","input","select","textarea","details","summary","label","option","optgroup","fieldset","legend"]),T=new Set(["disabled","readonly"]);if(P.has(_)){if(U?.cursor&&S.has(U.cursor))return!1;for(const te of T)if(m.hasAttribute(te)||m.getAttribute(te)==="true"||m.getAttribute(te)==="")return!1;return!(m.disabled||m.readOnly||m.inert)}const L=m.getAttribute("role"),Q=m.getAttribute("aria-role");if(m.getAttribute("contenteditable")==="true"||m.isContentEditable||m.classList&&(m.classList.contains("button")||m.classList.contains("dropdown-toggle")||m.getAttribute("data-index")||m.getAttribute("data-toggle")==="dropdown"||m.getAttribute("aria-haspopup")==="true"))return!0;const K=new Set(["button","menu","menubar","menuitem","menuitemradio","menuitemcheckbox","radio","checkbox","tab","switch","slider","spinbutton","combobox","searchbox","textbox","listbox","option","scrollbar"]);if(P.has(_)||L&&K.has(L)||Q&&K.has(Q))return!0;try{if(typeof getEventListeners=="function"){const ve=getEventListeners(m),_e=["click","mousedown","mouseup","dblclick"];for(const Ce of _e)if(ve[Ce]&&ve[Ce].length>0)return!0}const te=m?.ownerDocument?.defaultView?.getEventListenersForNode||window.getEventListenersForNode;if(typeof te=="function"){const ve=te(m),_e=["click","mousedown","mouseup","keydown","keyup","submit","change","input","focus","blur"];for(const Ce of _e)for(const tt of ve)if(tt.type===Ce)return!0}const oe=["onclick","onmousedown","onmouseup","ondblclick"];for(const ve of oe)if(m.hasAttribute(ve)||typeof m[ve]=="function")return!0}catch{}return!!w(m)}s(Y,"isInteractiveElement");function ue(m){if(c===-1)return!0;const _=k(m);if(!_||_.length===0)return!1;let U=!1;for(const T of _)if(T.width>0&&T.height>0&&!(T.bottom<-c||T.top>window.innerHeight+c||T.right<-c||T.left>window.innerWidth+c)){U=!0;break}if(!U)return!1;if(m.ownerDocument!==window.document)return!0;let S=Array.from(_).find(T=>T.width>0&&T.height>0);if(!S)return!1;const j=m.getRootNode();if(j instanceof ShadowRoot){const T=S.left+S.width/2,L=S.top+S.height/2;try{const Q=j.elementFromPoint(T,L);if(!Q)return!1;let K=Q;for(;K&&K!==j;){if(K===m)return!0;K=K.parentElement}return!1}catch{return!0}}const I=5;return[{x:S.left+S.width/2,y:S.top+S.height/2},{x:S.left+I,y:S.top+I},{x:S.right-I,y:S.bottom-I}].some(({x:T,y:L})=>{try{const Q=document.elementFromPoint(T,L);if(!Q)return!1;let K=Q;for(;K&&K!==document.documentElement;){if(K===m)return!0;K=K.parentElement}return!1}catch{return!0}})}s(ue,"isTopElement");function X(m,_){if(_===-1)return!0;const U=m.getClientRects();if(!U||U.length===0){const b=h(m);return!b||b.width===0||b.height===0?!1:!(b.bottom<-_||b.top>window.innerHeight+_||b.right<-_||b.left>window.innerWidth+_)}for(const b of U)if(!(b.width===0||b.height===0)&&!(b.bottom<-_||b.top>window.innerHeight+_||b.right<-_||b.left>window.innerWidth+_))return!0;return!1}s(X,"isInExpandedViewport");function me(m){if(!m||m.nodeType!==Node.ELEMENT_NODE)return!1;const _=m.tagName.toLowerCase();return new Set(["a","button","input","select","textarea","details","summary","label"]).has(_)?!0:m.hasAttribute("onclick")||m.hasAttribute("role")||m.hasAttribute("tabindex")||m.hasAttribute("aria-")||m.hasAttribute("data-action")||m.getAttribute("contenteditable")==="true"}s(me,"isInteractiveCandidate");const pe=new Set(["a","button","input","select","textarea","summary","details","label","option"]),Xe=new Set(["button","link","menuitem","menuitemradio","menuitemcheckbox","radio","checkbox","tab","switch","slider","spinbutton","combobox","searchbox","textbox","listbox","option","scrollbar"]);function fe(m){if(!m||m.nodeType!==Node.ELEMENT_NODE||!M(m))return!1;const _=m.hasAttribute("role")||m.hasAttribute("tabindex")||m.hasAttribute("onclick")||typeof m.onclick=="function",U=/\b(btn|clickable|menu|item|entry|link)\b/i.test(m.className||""),b=!!m.closest('button,a,[role="button"],.menu,.dropdown,.list,.toolbar'),S=[...m.children].some(M),j=m.parentElement&&m.parentElement.isSameNode(document.body);return(Y(m)||_||U)&&S&&b&&!j}s(fe,"isHeuristicallyInteractive");function Qe(m){if(!m||m.nodeType!==Node.ELEMENT_NODE)return!1;const _=m.tagName.toLowerCase(),U=m.getAttribute("role");if(_==="iframe"||pe.has(_)||U&&Xe.has(U)||m.isContentEditable||m.getAttribute("contenteditable")==="true"||m.hasAttribute("data-testid")||m.hasAttribute("data-cy")||m.hasAttribute("data-test")||m.hasAttribute("onclick")||typeof m.onclick=="function")return!0;try{const b=m?.ownerDocument?.defaultView?.getEventListenersForNode||window.getEventListenersForNode;if(typeof b=="function"){const j=b(m),I=["click","mousedown","mouseup","keydown","keyup","submit","change","input","focus","blur"];for(const P of I)for(const T of j)if(T.type===P)return!0}if(["onmousedown","onmouseup","onkeydown","onkeyup","onsubmit","onchange","oninput","onfocus","onblur"].some(j=>m.hasAttribute(j)))return!0}catch{}return!!fe(m)}s(Qe,"isElementDistinctInteraction");function et(m,_,U,b){if(!m.isInteractive)return!1;let S=!1;return b?Qe(_)?S=!0:S=!1:S=!0,S&&(m.isInViewport=X(_,c),(m.isInViewport||c===-1)&&(m.highlightIndex=u++,i))?(a>=0?a===m.highlightIndex&&x(_,m.highlightIndex,U):x(_,m.highlightIndex,U),!0):!1}s(et,"handleHighlighting");function $e(m,_=null,U=!1){if(!m||m.id===B||m.nodeType!==Node.ELEMENT_NODE&&m.nodeType!==Node.TEXT_NODE||!m||m.id===B||m.dataset?.browserUseIgnore==="true"||m.getAttribute&&m.getAttribute("aria-hidden")==="true")return null;if(m===document.body){const I={tagName:"body",attributes:{},xpath:"/body",children:[]};for(const T of m.childNodes){const L=$e(T,_,!1);L&&I.children.push(L)}const P=`${D.current++}`;return Z[P]=I,P}if(m.nodeType!==Node.ELEMENT_NODE&&m.nodeType!==Node.TEXT_NODE)return null;if(m.nodeType===Node.TEXT_NODE){const I=m.textContent?.trim();if(!I)return null;const P=m.parentElement;if(!P||P.tagName.toLowerCase()==="script")return null;const T=`${D.current++}`;return Z[T]={type:"TEXT_NODE",text:I,isVisible:O(m)},T}if(m.nodeType===Node.ELEMENT_NODE&&!Ee(m))return null;if(c!==-1&&!m.shadowRoot){const I=h(m),P=$(m),T=P&&(P.position==="fixed"||P.position==="sticky"),L=m.offsetWidth>0||m.offsetHeight>0;if(!I||!T&&!L&&(I.bottom<-c||I.top>window.innerHeight+c||I.right<-c||I.left>window.innerWidth+c))return null}const b={tagName:m.tagName.toLowerCase(),attributes:{},children:[]};if(me(m)||m.tagName.toLowerCase()==="iframe"||m.tagName.toLowerCase()==="body"){const I=m.getAttributeNames?.()||[];for(const P of I){const T=m.getAttribute(P);b.attributes[P]=T}m.tagName.toLowerCase()==="input"&&(m.type==="checkbox"||m.type==="radio")&&(b.attributes.checked=m.checked?"true":"false")}let S=!1;if(m.nodeType===Node.ELEMENT_NODE&&(b.isVisible=M(m),b.isVisible)){b.isTopElement=ue(m);const I=m.getAttribute("role"),P=I==="menu"||I==="menubar"||I==="listbox";(b.isTopElement||P)&&(b.isInteractive=Y(m),S=et(b,m,_,U),b.ref=m)}if(m.tagName){const I=m.tagName.toLowerCase();if(I==="iframe")try{const P=m.contentDocument||m.contentWindow?.document;if(P)for(const T of P.childNodes){const L=$e(T,m,!1);L&&b.children.push(L)}}catch(P){console.warn("Unable to access iframe:",P)}else if(m.isContentEditable||m.getAttribute("contenteditable")==="true"||m.id==="tinymce"||m.classList.contains("mce-content-body")||I==="body"&&m.getAttribute("data-id")?.startsWith("mce_"))for(const P of m.childNodes){const T=$e(P,_,S);T&&b.children.push(T)}else{if(m.shadowRoot){b.shadowRoot=!0;for(const P of m.shadowRoot.childNodes){const T=$e(P,_,S);T&&b.children.push(T)}}for(const P of m.childNodes){const L=$e(P,_,S||U);L&&b.children.push(L)}}}if(b.tagName==="a"&&b.children.length===0&&!b.attributes.href){const I=h(m);if(!(I&&I.width>0&&I.height>0||m.offsetWidth>0||m.offsetHeight>0))return null}b.extra=d.get(m)||null;const j=`${D.current++}`;return Z[j]=b,j}s($e,"buildDomTree");const ge=$e(document.body);return f.clearCache(),{rootId:ge,map:Z}},"domTree"),newElementsCache=new WeakMap;function getFlatTree(e){const n=[];for(const i of e.interactiveBlacklist||[])typeof i=="function"?n.push(i()):n.push(i);const r=[];for(const i of e.interactiveWhitelist||[])typeof i=="function"?r.push(i()):r.push(i);const o=domTree({doHighlightElements:!0,debugMode:!0,focusHighlightIndex:-1,viewportExpansion:VIEWPORT_EXPANSION,interactiveBlacklist:n,interactiveWhitelist:r,highlightOpacity:e.highlightOpacity??0,highlightLabelOpacity:e.highlightLabelOpacity??.1}),t=window.location.href;for(const i in o.map){const a=o.map[i];if(a.isInteractive&&a.ref){const c=a.ref;newElementsCache.has(c)||(newElementsCache.set(c,t),a.isNew=!0)}}return o}s(getFlatTree,"getFlatTree");function flatTreeToString(e,n){const r=["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"],o=[...n||[],...r],t=s((p,f)=>p.length>f?p.substring(0,f)+"...":p,"capTextLength"),i=s(p=>{const f=e.map[p];if(!f)return null;if(f.type==="TEXT_NODE"){const h=f;return{type:"text",text:h.text,isVisible:h.isVisible,parent:null,children:[]}}else{const h=f,$=[];if(h.children)for(const k of h.children){const Z=i(k);Z&&(Z.parent=null,$.push(Z))}return{type:"element",tagName:h.tagName,attributes:h.attributes??{},isVisible:h.isVisible??!1,isInteractive:h.isInteractive??!1,isTopElement:h.isTopElement??!1,isNew:h.isNew??!1,highlightIndex:h.highlightIndex,parent:null,children:$,extra:h.extra??{}}}},"buildTreeNode"),a=s((p,f=null)=>{p.parent=f;for(const h of p.children)a(h,p)},"setParentReferences"),c=i(e.rootId);if(!c)return"";a(c);const l=s(p=>{let f=p.parent;for(;f;){if(f.type==="element"&&f.highlightIndex!==void 0)return!0;f=f.parent}return!1},"hasParentWithHighlightIndex"),u=s((p,f,h)=>{let $=f;const k=" ".repeat(f);if(p.type==="element"){if(p.highlightIndex!==void 0){$+=1;const Z=getAllTextTillNextClickableElement(p);let D="";if(o.length>0&&p.attributes){const w={};for(const M of o){const Y=p.attributes[M];Y&&Y.trim()!==""&&(w[M]=Y.trim())}const O=o.filter(M=>M in w);if(O.length>1){const M=new Set,Y={};for(const ue of O){const X=w[ue];X.length>5&&(X in Y?M.add(ue):Y[X]=ue)}for(const ue of M)delete w[ue]}w.role===p.tagName&&delete w.role;const Ee=["aria-label","placeholder","title"];for(const M of Ee)w[M]&&w[M].toLowerCase().trim()===Z.toLowerCase().trim()&&delete w[M];Object.keys(w).length>0&&(D=Object.entries(w).map(([M,Y])=>`${M}=${t(Y,20)}`).join(" "))}const B=p.isNew?`*[${p.highlightIndex}]`:`[${p.highlightIndex}]`;let x=`${k}${B}<${p.tagName??""}`;if(D&&(x+=` ${D}`),p.extra&&p.extra.scrollable){let w="";p.extra.scrollData?.left&&(w+=`left=${p.extra.scrollData.left}, `),p.extra.scrollData?.top&&(w+=`top=${p.extra.scrollData.top}, `),p.extra.scrollData?.right&&(w+=`right=${p.extra.scrollData.right}, `),p.extra.scrollData?.bottom&&(w+=`bottom=${p.extra.scrollData.bottom}`),x+=` data-scrollable="${w}"`}if(Z){const w=Z.trim();D||(x+=" "),x+=`>${w}`}else D||(x+=" ");x+=" />",h.push(x)}for(const Z of p.children)u(Z,$,h)}else if(p.type==="text"){if(l(p))return;p.parent&&p.parent.type==="element"&&p.parent.isVisible&&p.parent.isTopElement&&h.push(`${k}${p.text??""}`)}},"processNode"),d=[];return u(c,0,d),d.join(`
|
|
242
242
|
`)}s(flatTreeToString,"flatTreeToString");const getAllTextTillNextClickableElement=s((e,n=-1)=>{const r=[],o=s((t,i)=>{if(!(n!==-1&&i>n)&&!(t.type==="element"&&t!==e&&t.highlightIndex!==void 0)){if(t.type==="text"&&t.text)r.push(t.text);else if(t.type==="element")for(const a of t.children)o(a,i+1)}},"collectText");return o(e,0),r.join(`
|
|
243
243
|
`).trim()},"getAllTextTillNextClickableElement");function getSelectorMap(e){const n=new Map,r=Object.keys(e.map);for(const o of r){const t=e.map[o];t.isInteractive&&typeof t.highlightIndex=="number"&&n.set(t.highlightIndex,t)}return n}s(getSelectorMap,"getSelectorMap");function getElementTextMap(e){const n=e.split(`
|
|
244
|
-
`).map(o=>o.trim()).filter(o=>o.length>0),r=new Map;for(const o of n){const i=/^\[(\d+)\]<[^>]+>([^<]*)/.exec(o);if(i){const a=parseInt(i[1],10);r.set(a,o)}}return r}s(getElementTextMap,"getElementTextMap");function cleanUpHighlights(){const e=window._highlightCleanupFunctions||[];for(const n of e)typeof n=="function"&&n();window._highlightCleanupFunctions=[]}s(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,n=window.innerHeight,r=Math.max(document.documentElement.scrollWidth,document.body.scrollWidth||0),o=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight||0),t=window.scrollX||window.pageXOffset||document.documentElement.scrollLeft||0,i=window.scrollY||window.pageYOffset||document.documentElement.scrollTop||0,a=Math.max(0,o-(window.innerHeight+i)),c=Math.max(0,r-(window.innerWidth+t));return{viewport_width:e,viewport_height:n,page_width:r,page_height:o,scroll_x:t,scroll_y:i,pixels_above:i,pixels_below:a,pages_above:n>0?i/n:0,pages_below:n>0?a/n:0,total_pages:n>0?o/n:0,current_page_position:i/Math.max(1,o-n),pixels_left:t,pixels_right:c}}s(getPageInfo,"getPageInfo");function patchReact(e){const n=document.querySelectorAll('[data-reactroot], [data-reactid], [data-react-checksum], #root, #app, [id^="root-"], [id^="app-"], #adex-wrapper, #adex-root');for(const r of n)r.setAttribute("data-page-agent-not-interactive","true")}s(patchReact,"patchReact");const _PageController=class _PageController extends EventTarget{config;flatTree=null;selectorMap=new Map;elementTextMap=new Map;simplifiedHTML="<EMPTY>";lastTimeUpdate=0;mask=null;maskReady=null;constructor(e={}){super(),this.config=e,patchReact(),e.enableMask&&(this.maskReady=this.initMask())}async initMask(){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,n=document.title,r=getPageInfo(),o=this.config.viewportExpansion??VIEWPORT_EXPANSION;await this.updateTree();const t=this.simplifiedHTML,i=`Page info: ${r.viewport_width}x${r.viewport_height}px viewport, ${r.page_width}x${r.page_height}px total page size, ${r.pages_above.toFixed(1)} pages above, ${r.pages_below.toFixed(1)} pages below, ${r.total_pages.toFixed(1)} total pages, at ${(r.current_page_position*100).toFixed(0)}% of page`,a=o===-1?"Interactive elements from top layer of the current page (full page):":"Interactive elements from top layer of the current page inside the viewport:",l=r.pixels_above>4&&o!==-1?`... ${r.pixels_above} pixels above (${r.pages_above.toFixed(1)} pages) - scroll to see more ...`:"[Start of page]",u=`${i}
|
|
244
|
+
`).map(o=>o.trim()).filter(o=>o.length>0),r=new Map;for(const o of n){const i=/^\[(\d+)\]<[^>]+>([^<]*)/.exec(o);if(i){const a=parseInt(i[1],10);r.set(a,o)}}return r}s(getElementTextMap,"getElementTextMap");function cleanUpHighlights(){const e=window._highlightCleanupFunctions||[];for(const n of e)typeof n=="function"&&n();window._highlightCleanupFunctions=[]}s(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,n=window.innerHeight,r=Math.max(document.documentElement.scrollWidth,document.body.scrollWidth||0),o=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight||0),t=window.scrollX||window.pageXOffset||document.documentElement.scrollLeft||0,i=window.scrollY||window.pageYOffset||document.documentElement.scrollTop||0,a=Math.max(0,o-(window.innerHeight+i)),c=Math.max(0,r-(window.innerWidth+t));return{viewport_width:e,viewport_height:n,page_width:r,page_height:o,scroll_x:t,scroll_y:i,pixels_above:i,pixels_below:a,pages_above:n>0?i/n:0,pages_below:n>0?a/n:0,total_pages:n>0?o/n:0,current_page_position:i/Math.max(1,o-n),pixels_left:t,pixels_right:c}}s(getPageInfo,"getPageInfo");function patchReact(e){const n=document.querySelectorAll('[data-reactroot], [data-reactid], [data-react-checksum], #root, #app, [id^="root-"], [id^="app-"], #adex-wrapper, #adex-root');for(const r of n)r.setAttribute("data-page-agent-not-interactive","true")}s(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.maskReady=this.initMask())}async initMask(){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,n=document.title,r=getPageInfo(),o=this.config.viewportExpansion??VIEWPORT_EXPANSION;await this.updateTree();const t=this.simplifiedHTML,i=`Page info: ${r.viewport_width}x${r.viewport_height}px viewport, ${r.page_width}x${r.page_height}px total page size, ${r.pages_above.toFixed(1)} pages above, ${r.pages_below.toFixed(1)} pages below, ${r.total_pages.toFixed(1)} total pages, at ${(r.current_page_position*100).toFixed(0)}% of page`,a=o===-1?"Interactive elements from top layer of the current page (full page):":"Interactive elements from top layer of the current page inside the viewport:",l=r.pixels_above>4&&o!==-1?`... ${r.pixels_above} pixels above (${r.pages_above.toFixed(1)} pages) - scroll to see more ...`:"[Start of page]",u=`${i}
|
|
245
245
|
|
|
246
246
|
${a}
|
|
247
247
|
|
|
248
|
-
${l}`,p=r.pixels_below>4&&o!==-1?`... ${r.pixels_below} pixels below (${r.pages_below.toFixed(1)} pages) - scroll to see more ...`:"[End of page]";return{url:e,title:n,header:u,content:t,footer:p}}async updateTree(){this.dispatchEvent(new Event("beforeUpdate")),this.lastTimeUpdate=Date.now(),this.mask&&(this.mask.wrapper.style.pointerEvents="none"),cleanUpHighlights();const e=[...this.config.interactiveBlacklist||[],...document.querySelectorAll("[data-page-agent-not-interactive]").values()];return this.flatTree=getFlatTree({...this.config,interactiveBlacklist:e}),this.simplifiedHTML=flatTreeToString(this.flatTree,this.config.include_attributes),this.selectorMap.clear(),this.selectorMap=getSelectorMap(this.flatTree),this.elementTextMap.clear(),this.elementTextMap=getElementTextMap(this.simplifiedHTML),this.mask&&(this.mask.wrapper.style.pointerEvents="auto"),this.dispatchEvent(new Event("afterUpdate")),this.simplifiedHTML}async cleanUpHighlights(){cleanUpHighlights()}async clickElement(e){try{const n=getElementByIndex(this.selectorMap,e),r=this.elementTextMap.get(e);return await clickElement(n),n instanceof HTMLAnchorElement&&n.target==="_blank"?{success:!0,message:`✅ Clicked element (${r??e}). ⚠️ Link opens in a new tab. You are not capable of reading new tabs.`}:{success:!0,message:`✅ Clicked element (${r??e}).`}}catch(n){return{success:!1,message:`❌ Failed to click element: ${n}`}}}async inputText(e,n){try{const r=getElementByIndex(this.selectorMap,e),o=this.elementTextMap.get(e);return await inputTextElement(r,n),{success:!0,message:`✅ Input text (${n}) into element (${o??e}).`}}catch(r){return{success:!1,message:`❌ Failed to input text: ${r}`}}}async selectOption(e,n){try{const r=getElementByIndex(this.selectorMap,e),o=this.elementTextMap.get(e);return await selectOptionElement(r,n),{success:!0,message:`✅ Selected option (${n}) in element (${o??e}).`}}catch(r){return{success:!1,message:`❌ Failed to select option: ${r}`}}}async scroll(e){try{const{down:n,numPages:r,pixels:o,index:t}=e
|
|
248
|
+
${l}`,p=r.pixels_below>4&&o!==-1?`... ${r.pixels_below} pixels below (${r.pages_below.toFixed(1)} pages) - scroll to see more ...`:"[End of page]";return{url:e,title:n,header:u,content:t,footer:p}}async updateTree(){this.dispatchEvent(new Event("beforeUpdate")),this.lastTimeUpdate=Date.now(),this.mask&&(this.mask.wrapper.style.pointerEvents="none"),cleanUpHighlights();const e=[...this.config.interactiveBlacklist||[],...document.querySelectorAll("[data-page-agent-not-interactive]").values()];return this.flatTree=getFlatTree({...this.config,interactiveBlacklist:e}),this.simplifiedHTML=flatTreeToString(this.flatTree,this.config.include_attributes),this.selectorMap.clear(),this.selectorMap=getSelectorMap(this.flatTree),this.elementTextMap.clear(),this.elementTextMap=getElementTextMap(this.simplifiedHTML),this.isIndexed=!0,this.mask&&(this.mask.wrapper.style.pointerEvents="auto"),this.dispatchEvent(new Event("afterUpdate")),this.simplifiedHTML}async cleanUpHighlights(){cleanUpHighlights()}assertIndexed(){if(!this.isIndexed)throw new Error("DOM tree not indexed. Can not perform actions on elements.")}async clickElement(e){try{this.assertIndexed();const n=getElementByIndex(this.selectorMap,e),r=this.elementTextMap.get(e);return await clickElement(n),n instanceof HTMLAnchorElement&&n.target==="_blank"?{success:!0,message:`✅ Clicked element (${r??e}). ⚠️ Link opens in a new tab. You are not capable of reading new tabs.`}:{success:!0,message:`✅ Clicked element (${r??e}).`}}catch(n){return{success:!1,message:`❌ Failed to click element: ${n}`}}}async inputText(e,n){try{this.assertIndexed();const r=getElementByIndex(this.selectorMap,e),o=this.elementTextMap.get(e);return await inputTextElement(r,n),{success:!0,message:`✅ Input text (${n}) into element (${o??e}).`}}catch(r){return{success:!1,message:`❌ Failed to input text: ${r}`}}}async selectOption(e,n){try{this.assertIndexed();const r=getElementByIndex(this.selectorMap,e),o=this.elementTextMap.get(e);return await selectOptionElement(r,n),{success:!0,message:`✅ Selected option (${n}) in element (${o??e}).`}}catch(r){return{success:!1,message:`❌ Failed to select option: ${r}`}}}async scroll(e){try{const{down:n,numPages:r,pixels:o,index:t}=e;this.assertIndexed();const i=o??r*(n?1:-1)*window.innerHeight,a=t!==void 0?getElementByIndex(this.selectorMap,t):null;return{success:!0,message:await scrollVertically(n,i,a)}}catch(n){return{success:!1,message:`❌ Failed to scroll: ${n}`}}}async scrollHorizontally(e){try{const{right:n,pixels:r,index:o}=e;this.assertIndexed();const t=r*(n?1:-1),i=o!==void 0?getElementByIndex(this.selectorMap,o):null;return{success:!0,message:await scrollHorizontally(n,t,i)}}catch(n){return{success:!1,message:`❌ Failed to scroll horizontally: ${n}`}}}async executeJavascript(script){try{const asyncFunction=eval(`(async () => { ${script} })`),result=await asyncFunction();return{success:!0,message:`✅ Executed JavaScript. Result: ${result}`}}catch(e){return{success:!1,message:`❌ Error executing JavaScript: ${e}`}}}async showMask(){await this.maskReady,this.mask?.show()}async hideMask(){await this.maskReady,this.mask?.hide()}dispose(){cleanUpHighlights(),this.flatTree=null,this.selectorMap.clear(),this.elementTextMap.clear(),this.simplifiedHTML="<EMPTY>",this.isIndexed=!1,this.mask?.dispose(),this.mask=null}};s(_PageController,"PageController");let PageController=_PageController;const enUS={ui:{panel:{ready:"Ready",thinking:"Thinking...",taskInput:"Enter new task, describe steps in detail, press Enter to submit",userAnswerPrompt:"Please answer the question above, press Enter to submit",taskTerminated:"Task terminated",taskCompleted:"Task completed",userAnswer:"User answer: {{input}}",question:"Question: {{question}}",waitingPlaceholder:"Waiting for task to start...",stop:"Stop",expand:"Expand history",collapse:"Collapse history",step:"Step {{number}} · {{time}}{{duration}}"},tools:{clicking:"Clicking element [{{index}}]...",inputting:"Inputting text to element [{{index}}]...",selecting:'Selecting option "{{text}}"...',scrolling:"Scrolling page...",waiting:"Waiting {{seconds}} seconds...",askingUser:"Asking user...",done:"Task done",clicked:"🖱️ Clicked element [{{index}}]",inputted:'⌨️ Inputted text "{{text}}"',selected:'☑️ Selected option "{{text}}"',scrolled:"🛞 Page scrolled",waited:"⌛️ Wait completed",executing:"Executing {{toolName}}...",resultSuccess:"success",resultFailure:"failed",resultError:"error"},errors:{elementNotFound:"No interactive element found at index {{index}}",taskRequired:"Task description is required",executionFailed:"Task execution failed",notInputElement:"Element is not an input or textarea",notSelectElement:"Element is not a select element",optionNotFound:'Option "{{text}}" not found'}}},zhCN={ui:{panel:{ready:"准备就绪",thinking:"正在思考...",taskInput:"输入新任务,详细描述步骤,回车提交",userAnswerPrompt:"请回答上面问题,回车提交",taskTerminated:"任务已终止",taskCompleted:"任务结束",userAnswer:"用户回答: {{input}}",question:"询问: {{question}}",waitingPlaceholder:"等待任务开始...",stop:"终止",expand:"展开历史",collapse:"收起历史",step:"步骤 {{number}} · {{time}}{{duration}}"},tools:{clicking:"正在点击元素 [{{index}}]...",inputting:"正在输入文本到元素 [{{index}}]...",selecting:'正在选择选项 "{{text}}"...',scrolling:"正在滚动页面...",waiting:"等待 {{seconds}} 秒...",askingUser:"正在询问用户...",done:"结束任务",clicked:"🖱️ 已点击元素 [{{index}}]",inputted:'⌨️ 已输入文本 "{{text}}"',selected:'☑️ 已选择选项 "{{text}}"',scrolled:"🛞 页面滚动完成",waited:"⌛️ 等待完成",executing:"正在执行 {{toolName}}...",resultSuccess:"成功",resultFailure:"失败",resultError:"错误"},errors:{elementNotFound:"未找到索引为 {{index}} 的交互元素",taskRequired:"任务描述不能为空",executionFailed:"任务执行失败",notInputElement:"元素不是输入框或文本域",notSelectElement:"元素不是选择框",optionNotFound:'未找到选项 "{{text}}"'}}},locales={"en-US":enUS,"zh-CN":zhCN},vt=class vt{language;translations;constructor(n="en-US"){this.language=n in locales?n:"en-US",this.translations=locales[this.language]}t(n,r){const o=this.getNestedValue(this.translations,n);return o?r?this.interpolate(o,r):o:(console.warn(`Translation key "${n}" not found for language "${this.language}"`),n)}getNestedValue(n,r){return r.split(".").reduce((o,t)=>o?.[t],n)}interpolate(n,r){return n.replace(/\{\{(\w+)\}\}/g,(o,t)=>r[t]!=null?r[t].toString():o)}getLanguage(){return this.language}};s(vt,"I18n");let I18n=vt;function truncate(e,n){return e.length>n?e.substring(0,n)+"...":e}s(truncate,"truncate");function escapeHtml(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}s(escapeHtml,"escapeHtml");const wrapper$1="_wrapper_gtdpc_1",background="_background_gtdpc_39",header="_header_gtdpc_99",pulse="_pulse_gtdpc_1",retryPulse="_retryPulse_gtdpc_1",statusTextFadeOut="_statusTextFadeOut_gtdpc_1",statusTextFadeIn="_statusTextFadeIn_gtdpc_1",statusSection="_statusSection_gtdpc_121",indicator="_indicator_gtdpc_128",thinking="_thinking_gtdpc_137",tool_executing="_tool_executing_gtdpc_142",retry="_retry_gtdpc_147",completed="_completed_gtdpc_153",input="_input_gtdpc_154",output="_output_gtdpc_155",error="_error_gtdpc_160",statusText="_statusText_gtdpc_166",fadeOut="_fadeOut_gtdpc_178",fadeIn="_fadeIn_gtdpc_182",controls="_controls_gtdpc_188",controlButton="_controlButton_gtdpc_193",stopButton="_stopButton_gtdpc_212",historySectionWrapper="_historySectionWrapper_gtdpc_246",shimmer="_shimmer_gtdpc_1",celebrate="_celebrate_gtdpc_1",expanded="_expanded_gtdpc_278",historySection="_historySection_gtdpc_246",historyItem="_historyItem_gtdpc_297",observation="_observation_gtdpc_355",question="_question_gtdpc_360",doneSuccess="_doneSuccess_gtdpc_366",historyContent="_historyContent_gtdpc_402",statusIcon="_statusIcon_gtdpc_403",doneError="_doneError_gtdpc_412",reflectionLines="_reflectionLines_gtdpc_462",historyMeta="_historyMeta_gtdpc_469",inputSectionWrapper="_inputSectionWrapper_gtdpc_539",hidden="_hidden_gtdpc_562",inputSection="_inputSection_gtdpc_539",taskInput="_taskInput_gtdpc_573",styles$1={wrapper:wrapper$1,"mask-running":"_mask-running_gtdpc_1",background,header,pulse,retryPulse,statusTextFadeOut,statusTextFadeIn,statusSection,indicator,thinking,tool_executing,retry,completed,input,output,error,statusText,fadeOut,fadeIn,controls,controlButton,stopButton,historySectionWrapper,shimmer,celebrate,expanded,historySection,historyItem,observation,question,doneSuccess,historyContent,statusIcon,doneError,reflectionLines,historyMeta,inputSectionWrapper,hidden,inputSection,taskInput};function createCard({icon:e,content:n,meta:r,type:o}){const t=o?styles$1[o]:"",i=Array.isArray(n)?`<div class="${styles$1.reflectionLines}">${n.join("")}</div>`:`<span>${escapeHtml(n)}</span>`;return`
|
|
249
249
|
<div class="${styles$1.historyItem} ${t}">
|
|
250
250
|
<div class="${styles$1.historyContent}">
|
|
251
251
|
<span class="${styles$1.statusIcon}">${e}</span>
|
|
@@ -288,7 +288,7 @@ ${l}`,p=r.pixels_below>4&&o!==-1?`... ${r.pixels_below} pixels below (${r.pages_
|
|
|
288
288
|
/>
|
|
289
289
|
</div>
|
|
290
290
|
</div>
|
|
291
|
-
`,document.body.appendChild(n),n},"#createWrapper"),qt=s(function(){this.wrapper.querySelector(`.${styles$1.header}`).addEventListener("click",r=>{r.target.closest(`.${styles$1.controlButton}`)||y(this,v,It).call(this)}),g(this,Ue).addEventListener("click",r=>{r.stopPropagation(),y(this,v,It).call(this)}),g(this,Ge).addEventListener("click",r=>{r.stopPropagation(),y(this,v,Bt).call(this)}),g(this,we).addEventListener("keydown",r=>{r.isComposing||r.key==="Enter"&&(r.preventDefault(),y(this,v,Vt).call(this))}),g(this,De).addEventListener("click",r=>{r.stopPropagation()})},"#setupEventListeners"),It=s(function(){g(this,xe)?y(this,v,ct).call(this):y(this,v,rt).call(this)},"#toggle"),rt=s(function(){E(this,xe,!0),this.wrapper.classList.add(styles$1.expanded),g(this,Ue).textContent="▲"},"#expand"),ct=s(function(){E(this,xe,!1),this.wrapper.classList.remove(styles$1.expanded),g(this,Ue).textContent="▼"},"#collapse"),Kt=s(function(){E(this,je,setInterval(()=>{y(this,v,Yt).call(this)},450))},"#startHeaderUpdateLoop"),Ht=s(function(){g(this,je)&&(clearInterval(g(this,je)),E(this,je,null))},"#stopHeaderUpdateLoop"),Yt=s(function(){if(!g(this,ee)||g(this,Be))return;if(g(this,se).textContent===g(this,ee)){E(this,ee,null);return}const n=g(this,ee);E(this,ee,null),y(this,v,Xt).call(this,n)},"#checkAndUpdateHeader"),Xt=s(function(n){E(this,Be,!0),g(this,se).classList.add(styles$1.fadeOut),setTimeout(()=>{g(this,se).textContent=n,g(this,se).classList.remove(styles$1.fadeOut),g(this,se).classList.add(styles$1.fadeIn),setTimeout(()=>{g(this,se).classList.remove(styles$1.fadeIn),E(this,Be,!1)},300)},150)},"#animateTextChange"),Re=s(function(n){g(this,Me).className=styles$1.indicator,g(this,Me).classList.add(styles$1[n])},"#updateStatusIndicator"),zt=s(function(){setTimeout(()=>{g(this,ye).scrollTop=g(this,ye).scrollHeight},0)},"#scrollToBottom"),Tt=s(function(){const n=[],r=g(this,q).task;r&&n.push(y(this,v,Qt).call(this,r));const o=g(this,q).history;for(const t of o)n.push(...y(this,v,tn).call(this,t));g(this,ye).innerHTML=n.join(""),y(this,v,zt).call(this)},"#renderHistory"),Qt=s(function(n){return createCard({icon:"🎯",content:n,type:"input"})},"#createTaskCard"),tn=s(function(n){const r=[],o=formatTime(g(this,Ne).language??"en-US"),t=n.type==="step"&&n.stepIndex!==void 0?g(this,W).t("ui.panel.step",{number:(n.stepIndex+1).toString(),time:o,duration:""}):o;if(n.type==="step"){if(n.reflection){const a=createReflectionLines(n.reflection);a.length>0&&r.push(createCard({icon:"🧠",content:a,meta:t}))}const i=n.action;i&&r.push(...y(this,v,nn).call(this,i,t))}else n.type==="observation"
|
|
291
|
+
`,document.body.appendChild(n),n},"#createWrapper"),qt=s(function(){this.wrapper.querySelector(`.${styles$1.header}`).addEventListener("click",r=>{r.target.closest(`.${styles$1.controlButton}`)||y(this,v,It).call(this)}),g(this,Ue).addEventListener("click",r=>{r.stopPropagation(),y(this,v,It).call(this)}),g(this,Ge).addEventListener("click",r=>{r.stopPropagation(),y(this,v,Bt).call(this)}),g(this,we).addEventListener("keydown",r=>{r.isComposing||r.key==="Enter"&&(r.preventDefault(),y(this,v,Vt).call(this))}),g(this,De).addEventListener("click",r=>{r.stopPropagation()})},"#setupEventListeners"),It=s(function(){g(this,xe)?y(this,v,ct).call(this):y(this,v,rt).call(this)},"#toggle"),rt=s(function(){E(this,xe,!0),this.wrapper.classList.add(styles$1.expanded),g(this,Ue).textContent="▲"},"#expand"),ct=s(function(){E(this,xe,!1),this.wrapper.classList.remove(styles$1.expanded),g(this,Ue).textContent="▼"},"#collapse"),Kt=s(function(){E(this,je,setInterval(()=>{y(this,v,Yt).call(this)},450))},"#startHeaderUpdateLoop"),Ht=s(function(){g(this,je)&&(clearInterval(g(this,je)),E(this,je,null))},"#stopHeaderUpdateLoop"),Yt=s(function(){if(!g(this,ee)||g(this,Be))return;if(g(this,se).textContent===g(this,ee)){E(this,ee,null);return}const n=g(this,ee);E(this,ee,null),y(this,v,Xt).call(this,n)},"#checkAndUpdateHeader"),Xt=s(function(n){E(this,Be,!0),g(this,se).classList.add(styles$1.fadeOut),setTimeout(()=>{g(this,se).textContent=n,g(this,se).classList.remove(styles$1.fadeOut),g(this,se).classList.add(styles$1.fadeIn),setTimeout(()=>{g(this,se).classList.remove(styles$1.fadeIn),E(this,Be,!1)},300)},150)},"#animateTextChange"),Re=s(function(n){g(this,Me).className=styles$1.indicator,g(this,Me).classList.add(styles$1[n])},"#updateStatusIndicator"),zt=s(function(){setTimeout(()=>{g(this,ye).scrollTop=g(this,ye).scrollHeight},0)},"#scrollToBottom"),Tt=s(function(){const n=[],r=g(this,q).task;r&&n.push(y(this,v,Qt).call(this,r));const o=g(this,q).history;for(const t of o)n.push(...y(this,v,tn).call(this,t));g(this,ye).innerHTML=n.join(""),y(this,v,zt).call(this)},"#renderHistory"),Qt=s(function(n){return createCard({icon:"🎯",content:n,type:"input"})},"#createTaskCard"),tn=s(function(n){const r=[],o=formatTime(g(this,Ne).language??"en-US"),t=n.type==="step"&&n.stepIndex!==void 0?g(this,W).t("ui.panel.step",{number:(n.stepIndex+1).toString(),time:o,duration:""}):o;if(n.type==="step"){if(n.reflection){const a=createReflectionLines(n.reflection);a.length>0&&r.push(createCard({icon:"🧠",content:a,meta:t}))}const i=n.action;i&&r.push(...y(this,v,nn).call(this,i,t))}else if(n.type==="observation")r.push(createCard({icon:"👁️",content:n.content||"",meta:t,type:"observation"}));else if(n.type==="user_takeover")r.push(createCard({icon:"👤",content:"User takeover",meta:t,type:"input"}));else if(n.type==="retry"){const i=`${n.message||"Retrying"} (${n.attempt}/${n.maxAttempts})`;r.push(createCard({icon:"🔄",content:i,meta:t,type:"observation"}))}else n.type==="error"&&r.push(createCard({icon:"❌",content:n.message||"Error",meta:t,type:"observation"}));return r},"#createHistoryCards"),nn=s(function(n,r){const o=[];if(n.name==="done"){const i=n.input.text||n.output||"";i&&o.push(createCard({icon:"🤖",content:i,meta:r,type:"output"}))}else if(n.name==="ask_user"){const t=n.input,i=n.output.replace(/^User answered:\s*/i,"");o.push(createCard({icon:"❓",content:`Question: ${t.question||""}`,meta:r,type:"question"})),o.push(createCard({icon:"💬",content:`Answer: ${i}`,meta:r,type:"input"}))}else{const t=y(this,v,St).call(this,n.name,n.input);o.push(createCard({icon:"🔨",content:t,meta:r})),n.output?.length>0&&o.push(createCard({icon:"🔨",content:n.output,meta:r,type:"output"}))}return o},"#createActionCards"),s(_t,"Panel");let Panel=_t;const $t=class $t extends PageAgentCore{panel;constructor(n){const r=new PageController({...n,enableMask:n.enableMask??!0});super({...n,pageController:r}),this.panel=new Panel(this,{language:n.language})}};s($t,"PageAgent");let PageAgent=$t;window.pageAgent&&window.pageAgent.dispose(),window.PageAgent=PageAgent,console.log("🚀 page-agent.js loaded!");const DEMO_MODEL="PAGE-AGENT-FREE-TESTING-RANDOM",DEMO_BASE_URL="https://hwcxiuzfylggtcktqgij.supabase.co/functions/v1/llm-testing-proxy",DEMO_API_KEY="PAGE-AGENT-FREE-TESTING-RANDOM";setTimeout(()=>{const e=document.currentScript;let n;if(e){console.log("🚀 page-agent.js detected current script:",e.src);const r=new URL(e.src),o=r.searchParams.get("model")||DEMO_MODEL,t=r.searchParams.get("baseURL")||DEMO_BASE_URL,i=r.searchParams.get("apiKey")||DEMO_API_KEY,a=r.searchParams.get("lang")||"zh-CN";n={model:o,baseURL:t,apiKey:i,language:a}}else console.log("🚀 page-agent.js no current script detected, using default demo config"),n={model:DEMO_MODEL,baseURL:DEMO_BASE_URL,apiKey:DEMO_API_KEY};window.pageAgent=new PageAgent(n),window.pageAgent.panel.show(),console.log("🚀 page-agent.js initialized with config:",window.pageAgent.config)});function computeBorderGeometry(e,n,r,o){const t=Math.max(1,Math.min(e,n)),i=Math.min(r,20),c=Math.min(i+o,t),l=Math.min(c,Math.floor(e/2)),u=Math.min(c,Math.floor(n/2)),d=s(b=>b/e*2-1,"toClipX"),p=s(b=>b/n*2-1,"toClipY"),f=0,h=e,$=0,k=n,Z=l,D=e-l,B=u,x=n-u,w=d(f),O=d(h),Ee=p($),M=p(k),Y=d(Z),ue=d(D),X=p(B),me=p(x),pe=0,Xe=0,fe=1,Qe=1,et=l/e,$e=1-l/e,ge=u/n,m=1-u/n,_=new Float32Array([w,Ee,O,Ee,w,X,w,X,O,Ee,O,X,w,me,O,me,w,M,w,M,O,me,O,M,w,X,Y,X,w,me,w,me,Y,X,Y,me,ue,X,O,X,ue,me,ue,me,O,X,O,me]),U=new Float32Array([pe,Xe,fe,Xe,pe,ge,pe,ge,fe,Xe,fe,ge,pe,m,fe,m,pe,Qe,pe,Qe,fe,m,fe,Qe,pe,ge,et,ge,pe,m,pe,m,et,ge,et,m,$e,ge,fe,ge,$e,m,$e,m,fe,ge,fe,m]);return{positions:_,uvs:U}}s(computeBorderGeometry,"computeBorderGeometry");function compileShader(e,n,r){const o=e.createShader(n);if(!o)throw new Error("Failed to create shader");if(e.shaderSource(o,r),e.compileShader(o),!e.getShaderParameter(o,e.COMPILE_STATUS)){const t=e.getShaderInfoLog(o)||"Unknown shader error";throw e.deleteShader(o),new Error(t)}return o}s(compileShader,"compileShader");function createProgram(e,n,r){const o=compileShader(e,e.VERTEX_SHADER,n),t=compileShader(e,e.FRAGMENT_SHADER,r),i=e.createProgram();if(!i)throw new Error("Failed to create program");if(e.attachShader(i,o),e.attachShader(i,t),e.linkProgram(i),!e.getProgramParameter(i,e.LINK_STATUS)){const a=e.getProgramInfoLog(i)||"Unknown link error";throw e.deleteProgram(i),e.deleteShader(o),e.deleteShader(t),new Error(a)}return e.deleteShader(o),e.deleteShader(t),i}s(createProgram,"createProgram");const fragmentShaderSource=`#version 300 es
|
|
292
292
|
precision lowp float;
|
|
293
293
|
in vec2 vUV;
|
|
294
294
|
out vec4 outColor;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "page-agent",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "1.0.0-beta.
|
|
4
|
+
"version": "1.0.0-beta.5",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/esm/page-agent.js",
|
|
7
7
|
"module": "./dist/esm/page-agent.js",
|
|
@@ -46,9 +46,9 @@
|
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"chalk": "^5.6.2",
|
|
48
48
|
"zod": "^4.3.5",
|
|
49
|
-
"@page-agent/llms": "1.0.0-beta.
|
|
50
|
-
"@page-agent/page-controller": "1.0.0-beta.
|
|
51
|
-
"@page-agent/core": "1.0.0-beta.
|
|
52
|
-
"@page-agent/ui": "1.0.0-beta.
|
|
49
|
+
"@page-agent/llms": "1.0.0-beta.5",
|
|
50
|
+
"@page-agent/page-controller": "1.0.0-beta.5",
|
|
51
|
+
"@page-agent/core": "1.0.0-beta.5",
|
|
52
|
+
"@page-agent/ui": "1.0.0-beta.5"
|
|
53
53
|
}
|
|
54
54
|
}
|