agent-afk 5.221.6 → 5.222.1
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/dist/agent/spine/spine-classifier.d.ts +1 -0
- package/dist/cli.mjs +641 -641
- package/dist/index.mjs +1 -1
- package/dist/telegram.mjs +249 -249
- package/dist/web-ui-assets/assets/index-CMdRmKqT.js +153 -0
- package/dist/web-ui-assets/assets/{index-Cp0j8w9U.js → index-Q48Eod_3.js} +73 -73
- package/dist/web-ui-assets/index.html +1 -1
- package/package.json +1 -1
- package/dist/web-ui-assets/assets/index-C7ktp0DS.js +0 -13
package/dist/index.mjs
CHANGED
|
@@ -270,7 +270,7 @@ Send a message to start one, or /new for a fresh session.`}function x_(e){return
|
|
|
270
270
|
|
|
271
271
|
${t}`}var nG,Om=m(()=>{"use strict";nG=new Set(["script","style","noscript","template","svg"])});function sG(e,t){return new Promise((n,r)=>{if(t?.aborted){r(t.reason??new Error("aborted"));return}let o=()=>{clearTimeout(s),r(t?.reason??new Error("aborted"))},s=setTimeout(()=>{t?.removeEventListener("abort",o),n()},e);t?.addEventListener("abort",o,{once:!0})})}function N_(e,t,n){let r=Math.min(t*2**e,n);return Math.round(Math.random()*r)}function iG(e,t){let n=e.headers.get("retry-after");if(n===null)return null;let r=Number(n.trim());return!Number.isFinite(r)||r<0?null:Math.min(r*1e3,t)}async function U_(e,t,n={},r={}){let o=r.retries??3,s=r.baseDelayMs??500,i=r.maxDelayMs??1e4,a=r.sleep??sG,c=n.signal??void 0,l;for(let d=0;d<=o;d++){if(c?.aborted)throw c.reason??new Error("aborted");try{let u=await e(t,n);if(!oG.has(u.status)||d===o)return u;let p=iG(u,i)??N_(d,s,i);O("[web/retryFetch] retrying",{url:t,attempt:d,status:u.status,waitMs:p}),await u.body?.cancel().catch(()=>{}),await a(p,c)}catch(u){if(c?.aborted||(l=u,d===o))throw u;let p=N_(d,s,i);O("[web/retryFetch] retrying after error",{url:t,attempt:d,waitMs:p}),await a(p,c)}}throw l??new Error("retryFetch: exhausted without a result")}var oG,$_=m(()=>{"use strict";V();oG=new Set([429,502,503,504])});import{BlockList as aG,isIP as Fm}from"node:net";import{lookup as cG}from"node:dns/promises";import{Agent as lG}from"undici";function j_(){let e=w.AFK_WEB_ALLOW_PRIVATE_HOSTS?.trim().toLowerCase();return e==="1"||e==="true"}function fG(e){return e.startsWith("[")&&e.endsWith("]")?e.slice(1,-1):e}function Dm(e){let t=Fm(e);return t===0?!1:pG.check(e,t===4?"ipv4":"ipv6")}async function H_(e){return cG(e,{all:!0,verbatim:!0})}async function Yn(e,t={}){if(t.allowPrivateHosts??j_())return{allowed:!0};let n;try{n=new URL(e)}catch{return{allowed:!1,reason:`"${e}" is not a valid absolute URL`}}if(n.protocol!=="http:"&&n.protocol!=="https:")return{allowed:!1,reason:`protocol "${n.protocol}" not supported (http/https only)`};let r=fG(n.hostname),o=(a,c)=>`refusing to fetch ${c} \u2014 internal/private address ${a} (loopback, link-local, cloud metadata, or RFC1918 space). Set AFK_WEB_ALLOW_PRIVATE_HOSTS=1 to allow private-host access.`;if(Fm(r)!==0)return Dm(r)?{allowed:!1,reason:o(r,r)}:{allowed:!0};let s=t.lookupFn??H_,i;try{i=await s(r)}catch{return{allowed:!0}}for(let a of i)if(Dm(a.address))return{allowed:!1,reason:o(a.address,`${r} (resolved)`)};return{allowed:!0}}async function Vs(e,t={}){let n=await Yn(e,t);if(!n.allowed)throw new Te(n.reason)}async function ln(e,t,n={},r={}){let o={...r.lookupFn!==void 0?{lookupFn:r.lookupFn}:{},...r.allowPrivateHosts!==void 0?{allowPrivateHosts:r.allowPrivateHosts}:{}},s=t;for(let i=0;i<=B_;i++){await Vs(s,o);let a={...n,redirect:"manual",...e===globalThis.fetch&&!(r.allowPrivateHosts??j_())?{dispatcher:mG}:{}},c=await U_(e,s,a,r.retry??{});if(!gG.has(c.status))return c;let l=c.headers.get("location");if(l===null||l.trim()==="")return c;let d;try{d=new URL(l,c.url||s).toString()}catch{return c}await c.body?.cancel().catch(()=>{}),s=d}throw new Te(`too many redirects (>${B_}) starting from ${t}`)}var dG,uG,pG,Te,mG,B_,gG,Qn=m(()=>{"use strict";P();$_();dG=[["0.0.0.0",8],["10.0.0.0",8],["100.64.0.0",10],["127.0.0.0",8],["169.254.0.0",16],["172.16.0.0",12],["192.168.0.0",16]],uG=[["::",96],["64:ff9b::",96],["fc00::",7],["fe80::",10]],pG=(()=>{let e=new aG;for(let[t,n]of dG)e.addSubnet(t,n,"ipv4");for(let[t,n]of uG)e.addSubnet(t,n,"ipv6");return e})(),Te=class extends Error{constructor(t){super(t),this.name="EgressBlockedError"}};mG=new lG({connect:{lookup(e,t,n){H_(e).then(r=>{let o=r.find(i=>Dm(i.address));if(o!==void 0){n(new Te(`refusing to connect to ${e} (resolved) \u2014 internal/private address ${o.address} (loopback, link-local, cloud metadata, or RFC1918 space). Set AFK_WEB_ALLOW_PRIVATE_HOSTS=1 to allow private-host access.`),"",0);return}let s=r[0];if(s===void 0){n(new Error(`DNS lookup returned no addresses for ${e}`),"",0);return}n(null,s.address,Fm(s.address))},r=>n(r,"",0))}}});B_=20,gG=new Set([301,302,303,307,308])});var Nm={};zo(Nm,{enforceDomainPolicy:()=>ft,loadBrowserConfig:()=>Lm});import{readFileSync as hG}from"node:fs";import{join as yG}from"path";function bG(e){let n=e.replace(/[.+?()[\]{}/\\^$|]/g,"\\$&").replace(/\*/g,"[^.]*");return new RegExp(`^${n}$`,"i")}function W_(e,t){return bG(t).test(e)}function kG(e,t){if(e!==void 0){let n=e.trim().toLowerCase();if(n==="1"||n==="true"||n==="yes")return!0;if(n==="0"||n==="false"||n==="no")return!1}if(t!==void 0){if(wG.has(t))return!0;if(SG.has(t))return!1}return!1}function K_(e){return e===void 0||e.trim()===""?[]:e.split(",").map(t=>t.trim().toLowerCase()).filter(t=>t.length>0)}function vG(e){if(e===void 0||e==="")return"auto";if(e==="playwright"||e==="agent-browser"||e==="auto")return e;throw new Error(`AFK_BROWSER_BACKEND: must be "playwright", "agent-browser", or "auto", got: ${e}`)}function G_(e){let t=e===void 0||e.trim()===""?"default":e.trim();return Rp(t),t}function TG(e){if(e===void 0)return!1;let t=e.trim().toLowerCase();return t==="1"||t==="true"||t==="yes"}function _G(e){try{return hG(e,"utf8")}catch(t){if(t.code==="ENOENT")return;throw t}}function EG(e,t){let n={...e};if(typeof t.headless=="boolean"&&(n.headless=t.headless),Array.isArray(t.allowedDomains)&&(n.allowedDomains=t.allowedDomains.filter(r=>typeof r=="string").map(r=>r.trim().toLowerCase()).filter(r=>r.length>0)),Array.isArray(t.blockedDomains)&&(n.blockedDomains=t.blockedDomains.filter(r=>typeof r=="string").map(r=>r.trim().toLowerCase()).filter(r=>r.length>0)),typeof t.domSnapshots=="boolean"&&(n.domSnapshots=t.domSnapshots),t.backend==="playwright"||t.backend==="agent-browser"||t.backend==="auto")n.backend=t.backend;else if(t.backend!==void 0)throw new Error(`AFK_BROWSER_BACKEND: must be "playwright", "agent-browser", or "auto", got: ${String(t.backend)}`);return typeof t.defaultProfile=="string"&&(n.defaultProfile=G_(t.defaultProfile)),n}function Lm(e){let t=e?.env??w,n=e?.readFileSync??_G,r=e?.surface??t.AGENT_SURFACE,o=kG(t.AFK_BROWSER_HEADLESS,r),s=K_(t.AFK_BROWSER_ALLOWED_DOMAINS),i=K_(t.AFK_BROWSER_BLOCKED_DOMAINS),a=TG(t.AFK_BROWSER_DOM_SNAPSHOTS),c=vG(t.AFK_BROWSER_BACKEND),l=G_(t.AFK_BROWSER_DEFAULT_PROFILE),d={headless:o,allowedDomains:s,blockedDomains:i,domSnapshots:a,backend:c,configPath:null,defaultProfile:l},u=t.AFK_BROWSER_CONFIG,p=u!==void 0&&u.trim()!==""?u.trim():yG(ns(),"browser.json"),f=n(p);if(f===void 0)return d;let g;try{g=JSON.parse(f)}catch(y){throw new Error(`Failed to parse browser config at ${p}: ${String(y)}`)}if(typeof g!="object"||g===null||Array.isArray(g))throw new Error(`Browser config at ${p} must be a JSON object`);let h=EG(d,g);return h.configPath=p,h}function ft(e,t){let n;try{n=new URL(e).hostname.toLowerCase()}catch{return{allowed:!1,reason:`invalid URL: ${e}`}}for(let r of t.blockedDomains)if(W_(n,r))return{allowed:!1,reason:`blocked by AFK_BROWSER_BLOCKED_DOMAINS: ${r}`};return t.allowedDomains.length>0&&!t.allowedDomains.some(o=>W_(n,o))?{allowed:!1,reason:"not in AFK_BROWSER_ALLOWED_DOMAINS"}:{allowed:!0}}var wG,SG,dn=m(()=>{"use strict";P();M();wG=new Set(["daemon","subagent","telegram","afk"]),SG=new Set(["repl","interactive","cli"])});import{readFileSync as xG}from"node:fs";import{join as AG}from"node:path";import{homedir as RG}from"node:os";function CG(e){let t=e??IG,n;try{n=xG(t,"utf8")}catch{return null}let r;try{r=JSON.parse(n)}catch{return null}if(typeof r!="object"||r===null||Array.isArray(r))return null;let o=r;if(typeof o.url!="string"||typeof o.token!="string"||typeof o.pid!="number")return null;let s;try{s=new URL(o.url)}catch{return null}let{hostname:i,protocol:a}=s;if(!(i==="127.0.0.1"||i==="localhost"||i==="::1")||a!=="http:")throw new Error(`Agent Browser connection file contains an untrusted URL: ${o.url}. Only http://127.0.0.1 or http://localhost is permitted.`);return{url:o.url,token:o.token,pid:o.pid,version:typeof o.version=="string"?o.version:"unknown"}}function PG(e){try{return process.kill(e,0),!0}catch{return!1}}async function MG(e,t,n=2e3){try{let r=new AbortController,o=setTimeout(()=>r.abort(),n),s=await fetch(`${e}/health`,{method:"GET",headers:{Authorization:`Bearer ${t}`,Host:"127.0.0.1:8833"},signal:r.signal});return clearTimeout(o),s.ok}catch{return!1}}async function Um(e){let t=CG(e);return t===null?{available:!1,connection:null,reason:"connection file missing or invalid"}:PG(t.pid)?await MG(t.url,t.token)?{available:!0,connection:t,reason:null}:{available:!1,connection:t,reason:`health probe failed at ${t.url}`}:{available:!1,connection:t,reason:`stale connection file: PID ${t.pid} not alive`}}var IG,q_=m(()=>{"use strict";IG=AG(RG(),".config","agent-browser","connection.json")});async function X_(e){let{config:t,surface:n}=e;if(t.backend==="playwright")return{backend:"playwright",reason:"explicit config: backend=playwright",probeMs:0,availability:null};if(t.backend==="agent-browser"){let i=Date.now(),a=await Um(),c=Date.now()-i;if(!a.available)throw new Error(`AFK_BROWSER_BACKEND=agent-browser but Agent Browser is not available: ${a.reason}`);return{backend:"agent-browser",reason:"explicit config: backend=agent-browser",probeMs:c,availability:a}}if(n&&OG.has(n))return{backend:"playwright",reason:`auto: surface "${n}" excluded from Agent Browser`,probeMs:0,availability:null};if(t.headless)return{backend:"playwright",reason:"auto: headless mode requires Playwright",probeMs:0,availability:null};let r=Date.now(),o=await Um(),s=Date.now()-r;return o.available?{backend:"agent-browser",reason:"auto: Agent Browser available and preferred",probeMs:s,availability:o}:{backend:"playwright",reason:`auto: Agent Browser unavailable (${o.reason})`,probeMs:s,availability:o}}var OG,z_=m(()=>{"use strict";q_();OG=new Set(["daemon","subagent"])});import{createHash as DG}from"crypto";function J_(e){return!!(e.role==="textbox"&&e.kind==="password"||e.label&&FG.test(e.label))}function V_(e){return DG("sha256").update(e,"utf8").digest("hex").slice(0,8)}function Y_(e){let t=e.replace(/\s+/g," ").trim();return t.length<=80?t:t.slice(0,77)+"..."}var FG,Yc=m(()=>{"use strict";FG=/password|secret|token|api[_-]?key|otp|2fa/i});import{randomBytes as LG}from"crypto";import{mkdir as NG,stat as UG,writeFile as $G}from"fs/promises";import{join as $m}from"path";import{gzip as BG}from"zlib";import{promisify as jG}from"util";function HG(e){return $m(ht(e),"browser")}function WG(e){return $m(HG(e),"screenshots")}function KG(){return new Date().toISOString().replace(/[:.]/g,"-")}function GG(){return LG(3).toString("hex")}async function Vr(e,t,n){if(t.length>Q_)throw new Error(`writeScreenshotSidecar: buffer exceeds ${Q_} byte cap (received ${t.length} bytes). Refusing to write oversized screenshot.`);let r=WG(e);await NG(r,{recursive:!0});let o=`${KG()}-${GG()}-${n}.png`,s=$m(r,o);await $G(s,t);let{size:i}=await UG(s);return{path:s,bytes:i}}var ece,Q_,Bm=m(()=>{"use strict";M();Yc();ece=jG(BG);Q_=5*1024*1024});var Qc,Z_=m(()=>{"use strict";V();Qc=class{baseUrl;token;constructor(t){this.baseUrl=t.url,this.token=t.token}async call(t,n,r=3e4){let o={version:1,method:t,params:n},s=new AbortController,i=setTimeout(()=>s.abort(),r);try{let a=await fetch(`${this.baseUrl}/agent`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.token}`,Host:new URL(this.baseUrl).host},body:JSON.stringify(o),signal:s.signal});if(!a.ok){let l=await a.text().catch(()=>"");throw new Error(`Agent Browser ${t} failed (HTTP ${a.status}): ${l}`)}let c=await a.json();if(c.ok===!1){let l=c.error,d=l?.code??"UNKNOWN",u=l?.message??JSON.stringify(c);throw new Error(`Agent Browser ${t} failed: [${String(d)}] ${String(u)}`)}return c.result}finally{clearTimeout(i)}}async listTabs(){return this.call("tabs.list",null)}async openTab(t){return{tabId:(await this.call("tabs.open",{url:t},6e4)).id}}async closeTab(t){await this.call("page.eval",{id:t,script:"window.close()"}).catch(n=>{O("[browser/agent-browser] closeTab window.close() failed (tab leak expected)",{tabId:t,err:n})})}async read(t,n){return this.call("page.read",{id:t,mode:n?.mode??"main",...n?.query?{query:n.query}:{},...n?.budget?{budget:n.budget}:{}})}async inspect(t,n){return this.call("page.inspect",{id:t,mode:n?.mode??"interactive",...n?.query?{query:n.query}:{},...n?.limit?{limit:n.limit}:{}})}async click(t,n){await this.call("page.click",{id:t,elementId:n})}async fill(t,n,r){await this.call("page.fill",{id:t,elementId:n,value:r})}async press(t,n,r){await this.call("page.press",{id:t,key:n,...r?{elementId:r}:{}})}async select(t,n,r){await this.call("page.select",{id:t,elementId:n,value:r})}async waitFor(t,n,r){await this.call("page.wait",{id:t,condition:n,...r?.value?{value:r.value}:{},...r?.timeout?{timeout:r.timeout}:{}},(r?.timeout??3e4)+5e3)}async evalScript(t,n){return this.call("page.eval",{id:t,script:n})}async screenshot(t){return this.call("page.screenshot",{id:t})}}});function jm(e){return{id:e.id,role:e.role,label:e.label,kind:e.kind,value:e.value,state:{disabled:e.disabled,...e.checked!==void 0?{checked:e.checked}:{},...e.selected!==void 0?{selected:e.selected}:{},...e.expanded!==void 0?{expanded:e.expanded}:{}},bbox:e.bbox,...e.selector?{selector:e.selector}:{}}}function eE(e,t){switch(t.kind){case"element_id":if(e.has(t.elementId))return t.elementId;throw new Error(`Element ${t.elementId} not found in current observation. Call browser_observe to refresh.`);case"selector":return null;case"semantic":return null}}async function Hm(e,t,n,r,o,s){switch(n){case"click":await e.click(t,r);break;case"fill":if(o===void 0)throw new Error("fill requires a value");await e.fill(t,r,o);break;case"press":if(o===void 0)throw new Error("press requires a value (key combo)");await e.press(t,o,r);break;case"select":if(o===void 0)throw new Error("select requires a value");await e.select(t,r,o);break;case"hover":throw new Error("hover is not supported by Agent Browser; use element_id from a prior observation to target clicks instead");case"scroll_to":{let i=r.replace(/\\/g,"\\\\").replace(/"/g,'\\"');await e.evalScript(t,`document.querySelector('[data-element-id="${i}"]')?.scrollIntoView({behavior:'smooth',block:'center'})`);break}case"wait_for":await e.waitFor(t,"element",{value:r,timeout:s??1e4});break;default:throw new Error(`Unknown action: ${n}`)}}async function tE(e,t){if(t.target.kind!=="semantic")throw new Error("resolveSemanticAndAct called with non-semantic target");let{elements:n}=await e.client.inspect(e.tabId,{mode:"interactive",query:t.target.text,limit:10}),r=n;if(t.target.role){let c=t.target.role.toLowerCase();r=n.filter(l=>l.role.toLowerCase()===c)}if(r.length===0)throw new Error(`No element found matching semantic target: text="${t.target.text}"`+(t.target.role?`, role="${t.target.role}"`:""));if(r.length>1)return{outcome:"ambiguous_target",query:{text:t.target.text,...t.target.role?{role:t.target.role}:{}},candidates:r.slice(0,5).map(jm)};let s=r[0].id;await Hm(e.client,e.tabId,t.action,s,t.value,t.timeoutMs);let i=await e.client.read(e.tabId,{mode:"main"}),a=ft(i.url,e.config);return a.allowed?{elementId:s}:{outcome:"blocked_by_policy",url:i.url,reason:`action navigated to blocked domain: ${a.reason}`}}var nE=m(()=>{"use strict";dn()});var rE={};zo(rE,{AgentBrowserProvider:()=>Wm});var Wm,oE=m(()=>{"use strict";dn();Bm();Z_();nE();Wm=class{name="agent-browser";config;client;sessions=new Map;constructor(t,n){this.config=t,this.client=new Qc(n)}async open(t){let n=ft(t.url,this.config);if(!n.allowed)return{outcome:"blocked_by_policy",url:t.url,reason:n.reason};let r=this.sessions.get(t.sessionId);if(r)await this.client.evalScript(r.tabId,`window.location.href = ${JSON.stringify(t.url)}`),await this.client.waitFor(r.tabId,"load",{timeout:t.timeoutMs??3e4});else{let{tabId:i}=await this.client.openTab(t.url);await this.client.waitFor(i,"load",{timeout:t.timeoutMs??3e4}),r={tabId:i,observationCounter:0,knownElements:new Map,lastAction:null,lastActionAt:null,currentUrl:null,currentTitle:null},this.sessions.set(t.sessionId,r)}let o=await this.client.read(r.tabId,{mode:"main"}),s=ft(o.url,this.config);return s.allowed?this.buildObservation(r,t.sessionId,t.screenshot,void 0,"browser_open"):(await this.client.evalScript(r.tabId,"window.location.href = 'about:blank'").catch(()=>{}),{outcome:"blocked_by_policy",url:o.url,reason:`redirected to blocked domain: ${s.reason}`})}async observe(t){let n=this.sessions.get(t.sessionId);if(!n)throw new Error(`No Agent Browser tab open for session ${t.sessionId}. Call browser_open first.`);return this.buildObservation(n,t.sessionId,t.screenshot,t.maxElements,"browser_observe")}async act(t){let n=this.sessions.get(t.sessionId);if(!n)throw new Error(`No Agent Browser tab open for session ${t.sessionId}. Call browser_open first.`);let r=eE(n.knownElements,t.target);if(r===null){if(t.target.kind==="semantic"){let i=await tE({client:this.client,config:this.config,tabId:n.tabId},t);return"outcome"in i?i:(n.lastAction=`browser_act:${t.action}`,n.lastActionAt=new Date().toISOString(),this.buildObservation(n,t.sessionId,t.screenshot,void 0,"browser_act"))}throw t.target.kind==="selector"?new Error("selector targets are not supported by Agent Browser; use element_id or semantic targets"):new Error(`Cannot resolve target: ${JSON.stringify(t.target)}`)}await Hm(this.client,n.tabId,t.action,r,t.value,t.timeoutMs),n.lastAction=`browser_act:${t.action}`,n.lastActionAt=new Date().toISOString();let o=await this.client.read(n.tabId,{mode:"main"}),s=ft(o.url,this.config);return s.allowed?this.buildObservation(n,t.sessionId,t.screenshot,void 0,"browser_act"):(await this.client.evalScript(n.tabId,"window.location.href = 'about:blank'").catch(()=>{}),{outcome:"blocked_by_policy",url:o.url,reason:`action navigated to blocked domain: ${s.reason}`})}async render(t){throw new Error("AgentBrowserProvider does not support render(). Use PlaywrightProvider for one-shot content fetches.")}async screenshot(t){let n=this.sessions.get(t.sessionId);if(!n)throw new Error(`No Agent Browser tab open for session ${t.sessionId}. Call browser_open first.`);if(t.target!==void 0||t.fullPage)throw new Error("Agent Browser does not support element or full-page screenshots; omit target and fullPage.");let r=await this.client.screenshot(n.tabId),o=Buffer.from(r.data,"base64"),s=o.length>=24?o.readUInt32BE(16):0,i=o.length>=24?o.readUInt32BE(20):0;return{path:(await Vr(t.sessionId,o,"browser_screenshot")).path,bytes:o.length,width:s,height:i,dataBase64:r.data,mediaType:"image/png"}}async extract(t){throw new Error("AgentBrowserProvider does not support extract() yet.")}async close(t){let n=this.sessions.get(t.sessionId);if(n){try{await this.client.closeTab(n.tabId)}catch{}this.sessions.delete(t.sessionId)}}describe(t){let n=this.sessions.get(t);return n?{active:!0,url:n.currentUrl,title:n.currentTitle,lastAction:n.lastAction,lastActionAt:n.lastActionAt,openTabs:1}:null}async shutdown(){let t=Array.from(this.sessions.entries()).map(async([,n])=>{try{await this.client.closeTab(n.tabId)}catch{}});await Promise.all(t),this.sessions.clear()}async buildObservation(t,n,r,o,s="browser_open"){let[i,a]=await Promise.all([this.client.read(t.tabId,{mode:"main",budget:4e3}),this.client.inspect(t.tabId,{mode:"interactive",limit:o??80})]),c=a.elements.map(jm),l=o??80,d=c.slice(0,l);t.observationCounter+=1,t.knownElements=new Map(d.map(h=>[h.id,h])),t.currentUrl=i.url,t.currentTitle=i.title;let u=[];c.length>l&&u.push(`page has ${c.length} interactive elements; showing first ${l}`);let p=null;if(r)try{let h=await this.client.screenshot(t.tabId),y=Buffer.from(h.data,"base64");p=(await Vr(n,y,s)).path}catch{u.push("screenshot capture failed")}let f=`obs_${t.observationCounter.toString(36)}`,g={httpStatus:null,loadingState:"idle",hasDialog:!1,consoleErrors:0};return{observationId:f,url:i.url,title:i.title,textSummary:i.content.slice(0,4e3),interactive:d,status:g,warnings:u,screenshotPath:p,capturedAt:new Date().toISOString()}}}});import{existsSync as qG,readFileSync as XG}from"node:fs";import{createRequire as zG}from"node:module";import{dirname as JG,join as VG}from"node:path";function aE(e){if(typeof e=="string")return e;let t=[],n=e;for(let r=0;r<QG&&n instanceof Error;r++)t.push(n.message),n=n.cause;return t.length>0?t.join(" | "):String(e)}function Ue(e){let t=aE(e);return iE.some(n=>t.includes(n))}function ZG(){try{let t=zG(import.meta.url).resolve("playwright/package.json"),n=JSON.parse(XG(t,"utf8"));if(typeof n!="object"||n===null)return;let r=n.bin,o=typeof r=="string"?r:typeof r=="object"&&r!==null?r.playwright:void 0;if(typeof o!="string"||o.length===0)return;let s=VG(JG(t),o);return qG(s)?`node ${/\s/.test(s)?`"${s}"`:s} install chromium`:void 0}catch{return}}function Ys(){return sE??=ZG()??YG,sE}function Km(e){return e.includes("install chromium")}function rt(e,t){let n=aE(e),r=t?.latched===!0?` ${eq}`:"";if(n.includes("Executable doesn't exist")){let o="";return t?.headless===!0?o=" This launch was headless, which needs the `chromium_headless_shell-*` build.":t?.headless===!1&&(o=" This launch was headed, which needs the full `chromium-*` build \u2014 the headless shell alone does not satisfy it."),`browser tools require the Playwright chromium binary. Install via: ${Ys()}.${o}${r}`}return`browser tools require the optional \`playwright\` peer dependency. Install via: pnpm add playwright (then ${Ys()}). Or pick a different tool.${r}`}function Zc(e,t,n=!1){if(!Ue(e))return e;let r=e instanceof Error?e.message:String(e);return new Error(`${r}
|
|
272
272
|
|
|
273
|
-
${rt(e,{headless:t,latched:n})}`,{cause:e})}var iE,YG,QG,sE,eq,Gm=m(()=>{"use strict";iE=["Cannot find package","ERR_MODULE_NOT_FOUND","Executable doesn't exist"],YG="pnpm exec playwright install chromium",QG=4;eq="This session already latched the failure, so browser tools keep fast-failing with this same error \u2014 after installing, call browser_close once to retry."});import Zn from"node:fs";import el from"node:path";import{randomBytes as tq}from"node:crypto";function nq(){try{return"5.221.6"}catch{}try{let e=el.resolve(import.meta.dirname,"../../../package.json"),t=Zn.readFileSync(e,"utf8"),n=JSON.parse(t);return typeof n.version=="string"?n.version:"unknown"}catch{return"unknown"}}var rq,tl,cE=m(()=>{"use strict";Gm();M();V();rq=nq(),tl=class{config;browser;sessions=new Map;launchPromise;launchFailure;shutdownComplete=!1;constructor(t){this.config=t}clearLaunchFailure(){this.launchFailure=void 0}latchLaunchFailure(t){this.launchFailure={error:t}}async ensureBrowser(){if(this.browser!==void 0&&this.browser.isConnected())return this.browser;if(this.launchFailure!==void 0)throw this.launchFailure.error;return this.browser!==void 0&&!this.browser.isConnected()&&(this.browser=void 0,this.launchPromise=void 0),this.launchPromise!==void 0?this.launchPromise:(this.launchPromise=(async()=>{let t;try{({chromium:t}=await import("playwright"))}catch(n){let r=Zc(n,this.config.headless,!0);throw this.latchLaunchFailure(r),this.launchPromise=void 0,r}try{let n=await t.launch({headless:this.config.headless});return this.browser=n,this.clearLaunchFailure(),n}catch(n){let r=Zc(n,this.config.headless,!0);throw this.latchLaunchFailure(r),r}finally{this.launchPromise=void 0}})(),this.launchPromise)}isBrowserActive(){return this.browser!==void 0&&this.browser.isConnected()}async ensureContext(t){let n=this.sessions.get(t);if(n!==void 0)return n.context;let r=await this.ensureBrowser(),o=this.loadStorageState(this.config.defaultProfile),s=await r.newContext({...this.contextOptions(),...o!==void 0?{storageState:o}:{}}),i={context:s,page:void 0,consoleErrors:0,lastHttpStatus:null,openDialog:void 0};return this.sessions.set(t,i),s}async ensurePage(t){let n=this.sessions.get(t);if(n!==void 0&&n.page!==void 0)return n.page;await this.ensureContext(t);let r=this.sessions.get(t);if(r===void 0)throw new Error(`[BrowserLauncher] session entry disappeared for sessionId=${t}`);if(r.page!==void 0)return r.page;let o=await r.context.newPage();return r.page=o,o.on("console",s=>{s.type()==="error"&&(r.consoleErrors+=1)}),o.on("request",s=>{s.isNavigationRequest()&&s.frame()===o.mainFrame()&&(r.lastHttpStatus=null)}),o.on("response",s=>{s.frame()===o.mainFrame()&&s.request().isNavigationRequest()&&(r.lastHttpStatus=s.status())}),o.on("dialog",s=>{r.openDialog=s}),o}getPage(t){return this.sessions.get(t)?.page}async renderHtml(t,n){let o=await(await this.ensureBrowser()).newContext(this.contextOptions()),s;n.requestGuard!==void 0&&await o.route("**/*",async a=>{try{await n.requestGuard(a.request().url()),await a.continue()}catch(c){s=c,await a.abort("blockedbyclient")}});let i=()=>{o.close().catch(()=>{})};if(n.signal?.aborted===!0)throw await o.close().catch(()=>{}),new Error("render aborted");n.signal!==void 0&&n.signal.addEventListener("abort",i,{once:!0});try{let a=await o.newPage(),c;try{c=await a.goto(t,{timeout:n.timeoutMs,waitUntil:n.waitUntil})}catch(p){throw s??p}if(s!==void 0)throw s;let l=await a.content();if(s!==void 0)throw s;let d=a.url(),u=c!==null?c.status():null;return{html:l,finalUrl:d,httpStatus:u}}finally{n.signal!==void 0&&n.signal.removeEventListener("abort",i),await o.close().catch(()=>{})}}getConsoleErrorCount(t){return this.sessions.get(t)?.consoleErrors??0}getLastHttpStatus(t){return this.sessions.get(t)?.lastHttpStatus??null}hasOpenDialog(t){return this.sessions.get(t)?.openDialog!==void 0}async dismissDialog(t,n=!0){let r=this.sessions.get(t);if(r===void 0||r.openDialog===void 0)return;let o=r.openDialog;r.openDialog=void 0,n?await o.accept():await o.dismiss()}async closeSession(t){this.clearLaunchFailure();let n=this.sessions.get(t);n!==void 0&&(this.sessions.delete(t),await this.saveStorageState(this.config.defaultProfile,n.context),n.page!==void 0&&await n.page.close().catch(()=>{}),await n.context.close().catch(()=>{}))}async shutdown(){if(this.clearLaunchFailure(),this.shutdownComplete)return;this.shutdownComplete=!0;let t=[...this.sessions.keys()];if(await Promise.all(t.map(n=>this.closeSession(n))),this.browser!==void 0){let n=this.browser;this.browser=void 0,await n.close().catch(()=>{})}}activeSessions(){return this.sessions.size}contextOptions(){return{viewport:{width:1280,height:800},userAgent:`Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 agent-afk/${rq}`}}loadStorageState(t){let n=Ip(t);try{if(!Zn.existsSync(n))return;let r=JSON.parse(Zn.readFileSync(n,"utf8"));return O("[browser/vault] restored session",{profile:t,file:n}),r}catch(r){O("[browser/vault] ignoring unreadable vault",{profile:t,file:n,err:r});return}}async saveStorageState(t,n){try{let r=Ip(t);if(!Zn.existsSync(r))return;let o=await n.storageState(),s=el.join(el.dirname(r),`.${el.basename(r)}.${process.pid}.${tq(4).toString("hex")}.tmp`);Zn.writeFileSync(s,JSON.stringify(o),{mode:384}),Zn.chmodSync(s,384),Zn.renameSync(s,r),O("[browser/vault] saved session",{profile:t,file:r})}catch(r){O("[browser/vault] save failed",{profile:t,err:r})}}}});import{createHash as oq}from"node:crypto";function sq(e){return e?e.replace(/\s+/g," ").trim().slice(0,200):""}function iq(e,t,n){return`el_${oq("sha256").update(`${e}:${t}:${n}`).digest("hex").slice(0,6)}`}function aq(e){let t=e.replace(/\s+/g," ").trim(),n=4e3;return t.length<=n?t:t.slice(0,n)+"\u2026[truncated]"}function lE(e){return e.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function uE(e,t){let n=e.role??"",r=e.name??"";dE.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&t.push(e);for(let s of e.children??[])uE(s,t)}async function cq(e){return e.evaluate(t=>{let n=Array.from(document.querySelectorAll(t)),r=[];for(let o of n){let s=o.getBoundingClientRect(),i=o;if(s.width===0&&s.height===0){let d=window.getComputedStyle(i);if(d.display==="none"||d.visibility==="hidden")continue}let a=o.tagName.toLowerCase(),c=o.getAttribute("aria-label")??o.getAttribute("placeholder")??(o.textContent??"").replace(/\s+/g," ").trim().slice(0,100),l=a==="input"?o.type||null:o.getAttribute("type");r.push({name:c,tagName:a,type:l,id:o.id||null,testId:o.getAttribute("data-testid"),bbox:{x:Math.round(s.left),y:Math.round(s.top),w:Math.round(s.width),h:Math.round(s.height)}})}return r},pE).catch(()=>[])}async function lq(e){return e.evaluate(t=>{let n={button:"button",a:"link",input:"textbox",textarea:"textbox",select:"combobox"},r=Array.from(document.querySelectorAll(t)),o=[];for(let s of r){let i=s.tagName.toLowerCase(),a=s.getAttribute("role")??"",c=s.getAttribute("aria-label")??s.getAttribute("placeholder")??(s.textContent??"").replace(/\s+/g," ").trim().slice(0,100),l=a||(n[i]??"");if(i==="input"){let h=s.type;h==="checkbox"?l="checkbox":h==="radio"?l="radio":h==="button"||h==="submit"||h==="reset"?l="button":h==="search"?l="searchbox":l="textbox"}if(!l)continue;let d="value"in s?s.value:void 0,u=d!==void 0?String(d):void 0,p=s.disabled??!1,f=i==="input"?s.checked:void 0,g={role:l,name:c,disabled:p};u!==void 0&&(g.value=u),f!==void 0&&(g.checked=f),o.push(g)}return o},pE).catch(()=>[])}function dq(e){let n=e.accessibility;return n!==null&&typeof n=="object"?n:null}async function nl(e,t){let n=t.maxElements??80,r=t.includeHidden??!1,o=[],s=dq(e),i=s?s.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=cq(e),c=e.evaluate(()=>document.body?.innerText??"").catch(()=>""),l=Promise.resolve(e.url()),d=e.title().catch(()=>""),[u,p,f,g,h]=await Promise.all([i,a,c,l,d]),y,b=!1;u!==null?(y=[],uE(u,y)):(o.push("observation skipped accessibility tree (returned null)"),b=!0,y=(await lq(e)).filter(C=>dE.has(C.role??"")));let S=new Map;for(let _ of p){let C=lE(_.name),N=S.get(C);(!N||N.bbox.w===0&&_.bbox.w>0)&&S.set(C,_)}let k=y.map(_=>({ax:_,dom:S.get(lE(_.name??""))})),T=r?k:k.filter(_=>_.dom?_.dom.bbox.w>0||_.dom.bbox.h>0:!0);T.sort((_,C)=>{let N=_.dom?.bbox.y??0,D=C.dom?.bbox.y??0;if(N!==D)return N-D;let U=_.dom?.bbox.x??0,L=C.dom?.bbox.x??0;return U-L}),T.length>200&&o.push("page has 200+ interactive elements; consider scoping");let R=T.slice(0,n).map((_,C)=>{let N=_.ax.role??"generic",D=_.ax.name??"",U=iq(N,D,C),L=_.dom?.bbox??{x:0,y:0,w:0,h:0},$=_.dom?.type??null,q=null;_.ax.value!==void 0&&_.ax.value!==null&&(q=String(_.ax.value)),_.ax.checked!==void 0&&(q=String(_.ax.checked)),J_({role:N,kind:$})&&(q="[redacted]");let K={disabled:_.ax.disabled??!1};_.ax.checked!==void 0&&(K.checked=_.ax.checked===!0||_.ax.checked==="mixed"),_.ax.selected!==void 0&&(K.selected=_.ax.selected),_.ax.expanded!==void 0&&(K.expanded=_.ax.expanded);let ne;_.dom?.testId?ne=`[data-testid="${_.dom.testId}"]`:_.dom?.id&&(ne=`#${_.dom.id}`);let In={id:U,role:N,label:sq(D),kind:$,value:q,state:K,bbox:L};return ne!==void 0&&(In.selector=ne),In}),x="idle";try{let _=await e.evaluate(()=>document.readyState);_==="loading"?x="loading":_==="interactive"?x="navigating":x="idle"}catch{x="navigating"}x!=="idle"&&o.push("page is still loading \u2014 observation may be incomplete"),b&&!o.includes("observation skipped accessibility tree (returned null)")&&o.push("observation skipped accessibility tree (returned null)");let F=aq(f),v=`obs_${t.observationCounter.toString(36)}`,A=new Date().toISOString();return{observationId:v,url:g,title:h,textSummary:F,interactive:R,status:{httpStatus:t.httpStatus??null,loadingState:x,hasDialog:t.hasDialog??!1,consoleErrors:t.consoleErrors??0},warnings:o,screenshotPath:t.screenshotPath??null,capturedAt:A}}var dE,pE,fE=m(()=>{"use strict";Yc();dE=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);pE="a[href], button, input, select, textarea, [role], [tabindex], label"});async function mE(e,t){try{let n=await e.nth(t).evaluate(i=>{let a=i,c=a.getAttribute("role")??a.tagName.toLowerCase(),l=a.getAttribute("aria-label")??a.getAttribute("placeholder")??(a.innerText!=null?a.innerText.trim().slice(0,200):"")??a.getAttribute("title")??"",d=a.getBoundingClientRect();return{role:c,label:l,x:Math.round(d.x),y:Math.round(d.y),w:Math.round(d.width),h:Math.round(d.height)}}),r=`${n.role}:${n.label}:${t}`,o=0;for(let i=0;i<r.length;i++)o=o*31+r.charCodeAt(i)>>>0;return{id:`el_${o.toString(16).padStart(6,"0").slice(0,6)}`,role:n.role,label:n.label,kind:null,value:null,state:{disabled:!1},bbox:{x:n.x,y:n.y,w:n.w,h:n.h}}}catch{return null}}async function qm(e,t){let n=Math.min(t,5);return(await Promise.all(Array.from({length:n},(o,s)=>mE(e,s)))).filter(o=>o!==null)}async function uq(e){let t=new Set,n=[];for(let{loc:r,count:o}of e)for(let s=0;s<o;s++){let i;try{i=await r.nth(s).evaluate(a=>{let c=a,l=c.getBoundingClientRect();return`${c.tagName}@${Math.round(l.x)},${Math.round(l.y)}`})}catch{continue}t.has(i)||(t.add(i),n.push({key:i,locator:r,index:s}))}return n}async function Xm(e,t,n){switch(t.kind){case"element_id":return pq(e,t,n);case"selector":return fq(e,t);case"semantic":return mq(e,t)}}async function pq(e,t,n){let r=n.get(t.elementId);if(r===void 0)return{outcome:"not_found",query:t};if(r.selector!==void 0){let c=e.locator(r.selector);if(await c.count()===1)return{outcome:"resolved",locator:c}}let o=e.getByRole(r.role,{name:r.label,exact:!0}),s=await o.count();if(s===0)return{outcome:"not_found",query:t};if(s===1)return{outcome:"resolved",locator:o};let i=await qm(o,s);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:i}}async function fq(e,t){let n=e.locator(t.selector),r=await n.count();if(r===0)return{outcome:"not_found",query:t};if(r===1)return{outcome:"resolved",locator:n};let o=await qm(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${t.selector}]`},candidates:o}}async function mq(e,t){return t.role!==void 0?gq(e,t.text,t.role):hq(e,t.text,t)}async function gq(e,t,n){let r=e.getByRole(n,{name:t}),o=await r.count();if(o===0)return{outcome:"not_found",query:{kind:"semantic",text:t,role:n}};if(o===1)return{outcome:"resolved",locator:r};let s=await qm(r,o);return{outcome:"ambiguous_target",query:{text:t,role:n},candidates:s}}async function hq(e,t,n){let r=e.getByRole("button",{name:t}),o=e.getByRole("link",{name:t}),s=e.getByLabel(t,{exact:!1}),[i,a,c]=await Promise.all([r.count(),o.count(),s.count()]);if(i+a+c===0)return{outcome:"not_found",query:n};let d=[];i>0&&d.push({loc:r,count:i}),a>0&&d.push({loc:o,count:a}),c>0&&d.push({loc:s,count:c});let u=await uq(d);if(u.length===0)return{outcome:"not_found",query:n};if(u.length===1){let h=u[0];return h===void 0?{outcome:"not_found",query:n}:{outcome:"resolved",locator:h.locator.nth(h.index)}}let p=u.slice(0,5),f=[];for(let h=0;h<p.length;h++){let y=p[h];if(y===void 0)continue;let b=await mE(y.locator,y.index);if(b!==null){let S=`${b.role}:${b.label}:${h}`,k=0;for(let T=0;T<S.length;T++)k=k*31+S.charCodeAt(T)>>>0;f.push({...b,id:`el_${k.toString(16).padStart(6,"0").slice(0,6)}`})}}return{outcome:"ambiguous_target",query:{text:t},candidates:f}}var gE=m(()=>{"use strict"});async function zm(e,t,n,r){let o=e.url();if(o===n)return null;let s=ft(o,t);if(s.allowed)return null;try{await e.goBack()}catch{await r()}return{outcome:"blocked_by_policy",url:o,reason:s.reason}}var hE=m(()=>{"use strict";dn()});var Vm={};zo(Vm,{PlaywrightProvider:()=>Jm});function yE(e){switch(e.kind){case"semantic":return e.role!==void 0?`semantic('${e.text}', role='${e.role}')`:`semantic('${e.text}')`;case"element_id":return`element_id(${e.elementId})`;case"selector":return`selector(${e.selector})`}}var Jm,Ym=m(()=>{"use strict";cE();fE();gE();dn();hE();Bm();Jm=class{name="playwright";config;launcher;sessions=new Map;constructor(t){this.config=t,this.launcher=new tl(t)}async open(t){let n=ft(t.url,this.config);if(!n.allowed)return{outcome:"blocked_by_policy",url:t.url,reason:n.reason};let{sessionId:r}=t,o=await this.launcher.ensurePage(r),s=this.ensureSessionState(r),i=null,a=null;try{await o.goto(t.url,{timeout:t.timeoutMs??3e4,waitUntil:t.waitFor??"load"})}catch(u){a=u}let c=o.url();if(!(a!==null&&(c===""||c==="about:blank"))){let u=await zm(o,this.config,t.url,()=>this.close({sessionId:r}));if(u!==null)return u}(t.screenshot===!0||a!==null)&&(i=await this.captureScreenshot(o,r,"browser_open")),s.observationCounter+=1;let d=await nl(o,{observationCounter:s.observationCounter,screenshotPath:i,consoleErrors:this.launcher.getConsoleErrorCount(r),httpStatus:this.launcher.getLastHttpStatus(r),hasDialog:this.launcher.hasOpenDialog(r)});if(this.updateSessionFromObservation(s,d.interactive,d.url,d.title,"browser_open"),a!==null)throw a;return d}async observe(t){let{sessionId:n}=t,r=this.launcher.getPage(n);if(r===void 0)throw new Error(`browser_observe: no page open for session ${n}`);let o=this.ensureSessionState(n),s=null;t.screenshot===!0&&(s=await this.captureScreenshot(r,n,"browser_observe")),o.observationCounter+=1;let i=await nl(r,{observationCounter:o.observationCounter,screenshotPath:s,consoleErrors:this.launcher.getConsoleErrorCount(n),httpStatus:this.launcher.getLastHttpStatus(n),hasDialog:this.launcher.hasOpenDialog(n),includeHidden:t.includeHidden,maxElements:t.maxElements});return this.updateSessionFromObservation(o,i.interactive,i.url,i.title,"browser_observe"),i}async act(t){let{sessionId:n}=t,r=this.launcher.getPage(n);if(r===void 0)throw new Error(`browser_act: no page open for session ${n}`);let o=this.ensureSessionState(n),s=r.url(),i=t.timeoutMs??3e4,a=await Xm(r,t.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${yE(t.target)}`);if(a.outcome==="ambiguous_target")return a;let{locator:c}=a,l=null,d=async()=>{switch(t.action){case"click":await c.click({timeout:i});break;case"fill":await c.fill(t.value??"");break;case"press":await c.press(t.value??"");break;case"select":await c.selectOption(t.value??"");break;case"hover":await c.hover({timeout:i});break;case"scroll_to":await c.scrollIntoViewIfNeeded({timeout:i});break;case"wait_for":await c.waitFor({timeout:i,state:"visible"});break}};try{await d()}catch(h){if(h instanceof Error&&/navigation|net::ERR/i.test(h.message))try{await d()}catch(y){l=y}else l=h}let u=await zm(r,this.config,s,()=>this.close({sessionId:n}));if(u!==null)return u;let p=null;(t.screenshot===!0||l!==null)&&(p=await this.captureScreenshot(r,n,"browser_act")),o.observationCounter+=1;let f=await nl(r,{observationCounter:o.observationCounter,screenshotPath:p,consoleErrors:this.launcher.getConsoleErrorCount(n),httpStatus:this.launcher.getLastHttpStatus(n),hasDialog:this.launcher.hasOpenDialog(n)}),g=`browser_act:${t.action}`;if(this.updateSessionFromObservation(o,f.interactive,f.url,f.title,g),l!==null)throw l;return f}async render(t){return this.launcher.renderHtml(t.url,{timeoutMs:t.timeoutMs??3e4,waitUntil:t.waitFor??"load",signal:t.signal,requestGuard:t.requestGuard})}async screenshot(t){let{sessionId:n}=t,r=this.launcher.getPage(n);if(r===void 0)throw new Error(`browser_screenshot: no page open for session ${n}`);let o=this.ensureSessionState(n),s;if(t.target!==void 0){let d=await Xm(r,t.target,o.knownElements);if(d.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${yE(t.target)}`);if(d.outcome==="ambiguous_target")throw new Error("screenshot target ambiguous; specify element_id or selector");s=await d.locator.screenshot()}else s=await r.screenshot({fullPage:t.fullPage??!1});let{path:i,bytes:a}=await Vr(n,s,"browser_screenshot"),c=0,l=0;if(t.fullPage===!0)try{let d=await r.evaluate(()=>({w:document.documentElement.scrollWidth,h:document.documentElement.scrollHeight}));c=d.w,l=d.h}catch{let d=r.viewportSize();c=d?.width??0,l=d?.height??0}else{let d=r.viewportSize();c=d?.width??0,l=d?.height??0}return{path:i,bytes:a,width:c,height:l,dataBase64:s.toString("base64"),mediaType:"image/png"}}async extract(t){throw new Error("browser_extract not implemented in Phase 1")}async close(t){await this.launcher.closeSession(t.sessionId),this.sessions.delete(t.sessionId)}describe(t){let n=this.sessions.get(t);if(n===void 0)return null;let r=this.launcher.getPage(t);return{active:r!==void 0,url:n.currentUrl,title:n.currentTitle,lastAction:n.lastAction,lastActionAt:n.lastActionAt,openTabs:r!==void 0?1:0}}async shutdown(){this.sessions.clear(),await this.launcher.shutdown()}ensureSessionState(t){let n=this.sessions.get(t);if(n!==void 0)return n;let r={observationCounter:0,knownElements:new Map,lastAction:null,lastActionAt:null,currentUrl:null,currentTitle:null};return this.sessions.set(t,r),r}updateSessionFromObservation(t,n,r,o,s){t.knownElements=new Map(n.map(i=>[i.id,i])),t.currentUrl=r,t.currentTitle=o,t.lastAction=s,t.lastActionAt=new Date().toISOString()}async captureScreenshot(t,n,r){try{let o=await t.screenshot({fullPage:!1}),{path:s}=await Vr(n,o,r);return s}catch{return null}}}});var tr={};zo(tr,{__resetBrowserRegistryForTests:()=>vq,browserProviderActive:()=>wq,closeBrowserProvider:()=>Zm,getBrowserProvider:()=>bq,getLastRoutingDecision:()=>kq,peekBrowserProvider:()=>Sq});function bE(){Promise.resolve(Zm()).then(()=>{process.exit(130)})}function wE(){Promise.resolve(Zm()).then(()=>{process.exit(143)})}function SE(){Et=null}function yq(){rl||(process.on("SIGINT",bE),process.on("SIGTERM",wE),process.on("exit",SE),rl=!0)}function kE(){rl&&(process.removeListener("SIGINT",bE),process.removeListener("SIGTERM",wE),process.removeListener("exit",SE),rl=!1)}async function bq(e){return Et!==null?Et:(er!==null||(er=(async()=>{let t=Lm(e),n=e?.surface??(e?.env??{}).AGENT_SURFACE??w.AGENT_SURFACE,r=await X_({config:t,surface:n});Qm=r;let o;if(r.backend==="agent-browser"){let{AgentBrowserProvider:s}=await Promise.resolve().then(()=>(oE(),rE)),i=r.availability.connection;o=new s(t,i)}else{let{PlaywrightProvider:s}=await Promise.resolve().then(()=>(Ym(),Vm));o=new s(t)}return yq(),Et=o,er=null,o})()),er)}async function Zm(){if(Et===null)return;let e=Et;Et=null,er=null,kE(),await e.shutdown()}function wq(){return Et!==null}function Sq(){return Et}function kq(){return Qm}function vq(){Et=null,er=null,Qm=null,kE()}var Et,er,rl,Qm,nr=m(()=>{"use strict";dn();z_();P();Et=null,er=null,rl=!1,Qm=null});async function vE(e,t){try{return await D_(e,t)}catch(n){return O("[web/scrape] extraction failed",{url:t,err:n}),{title:"",markdown:"",textLength:0,usedFallback:!0}}}async function Rq(e,t){let{getBrowserProvider:n}=await Promise.resolve().then(()=>(nr(),tr)),r=await n();try{return await r.render({url:e,timeoutMs:t.timeoutMs,signal:t.signal,requestGuard:t.requestGuard})}catch(o){if(r.name==="agent-browser"){let{PlaywrightProvider:s}=await Promise.resolve().then(()=>(Ym(),Vm)),{loadBrowserConfig:i}=await Promise.resolve().then(()=>(dn(),Nm)),a=i(),c=new s(a);try{return await c.render({url:e,timeoutMs:t.timeoutMs,signal:t.signal,requestGuard:t.requestGuard})}finally{await c.shutdown()}}throw o}}async function TE(e,t){let n=t.fetchFn??globalThis.fetch,r=t.renderFn??Rq,o=t.lookupFn!==void 0?{lookupFn:t.lookupFn}:{},s=null,i="",a=e,c=null,l=null;try{let u=await ln(n,e,{headers:Aq,signal:t.signal},o);c=u.status,a=u.url||e;let p=u.headers.get("content-type")??"";if(u.ok){if(xq.test(p))throw new Error(`web_scrape markdown mode received binary content (${p.split(";")[0]}). Use mode: "raw" to fetch the bytes, or a different tool.`);let f=await u.text();if(Eq.test(p)&&!_q.test(p))return{title:"",markdown:f.trim(),finalUrl:a,usedRender:!1};if(i=f,s=await vE(f,a),t.signal.aborted)throw t.signal.reason??new Error("aborted")}}catch(u){if(t.signal.aborted||u instanceof Te||u instanceof Error&&u.message.startsWith("web_scrape markdown mode received binary"))throw u;l=u}if(!(s===null||s.textLength<200)&&s!==null){let u=Mm({html:i,extractedTextLength:s.textLength});return{title:s.title,markdown:s.markdown,finalUrl:a,usedRender:!1,...u!==void 0?{advisory:u}:{}}}try{await Vs(e,o);let u=await r(e,{timeoutMs:t.timeoutMs,signal:t.signal,requestGuard:f=>Vs(f,o)});u.finalUrl!==e&&/^https?:\/\//i.test(u.finalUrl)&&await Vs(u.finalUrl,o);let p=await vE(u.html,u.finalUrl);if(t.signal.aborted)throw t.signal.reason??new Error("aborted");if(s===null||p.textLength>=s.textLength){let f=Mm({html:u.html,extractedTextLength:p.textLength});return{title:p.title,markdown:p.markdown,finalUrl:u.finalUrl,usedRender:!0,...f!==void 0?{advisory:f}:{}}}}catch(u){if(t.signal.aborted||u instanceof Te)throw u;if(s===null){let p=u instanceof Error?u.message:String(u),f=l instanceof Error?l.message:`HTTP ${c??"error"}`,g=new Error(`web_scrape could not retrieve ${e}: fetch failed (${f}) and render failed (${p}).`);throw g.cause=u,g}}if(s!==null)return{title:s.title,markdown:s.markdown,finalUrl:a,usedRender:!1};throw new Error(`web_scrape could not retrieve any content from ${e} (HTTP ${c??"error"}).`)}var _q,Eq,xq,Aq,_E=m(()=>{"use strict";F_();Om();Qn();V();_q=/(text\/html|application\/xhtml\+xml)/i,Eq=/(application\/json|\/xml|\+xml|text\/|application\/(java|ecma)script|csv)/i,xq=/(image\/|audio\/|video\/|application\/pdf|application\/zip|application\/octet-stream|font\/)/i,Aq={"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 agent-afk/web_scrape",Accept:"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"}});function Pq(e){let t=e.fetchFn??globalThis.fetch;return{name:"exa",async search(n,{limit:r,signal:o}){let s=await t(Iq,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json","x-api-key":e.apiKey,"User-Agent":"agent-afk/web_scrape"},body:JSON.stringify({query:n,type:"auto",numResults:Math.min(Math.max(r,1),Cq),contents:{highlights:{numSentences:3,highlightsPerUrl:1}}}),signal:o});if(!s.ok){let c="";try{let d=await s.text(),u=ue(d);u&&(c=`: ${u.length>200?u.slice(0,200)+"\u2026":u}`)}catch{}let l=s.statusText?` ${s.statusText}`:"";throw new Error(`Exa Search HTTP ${s.status}${l}${c}`)}let i;try{i=await s.json()}catch(c){throw new Error(`Exa Search response was not JSON: ${c instanceof Error?c.message:String(c)}`)}return(i.results??[]).slice(0,r).map(c=>({title:(c.title??"").trim()||"(untitled)",url:c.url??"",description:(c.highlights?.[0]??"").trim()})).filter(c=>c.url.length>0)}}}function EE(e){return e.exaApiKey!==void 0&&e.exaApiKey.trim()!==""?Pq({apiKey:e.exaApiKey,fetchFn:e.fetchFn}):{error:'web_scrape search mode requires a search backend. Set EXA_API_KEY (free tier at https://exa.ai) to enable it. Use mode: "markdown" to read a known URL, or mode: "raw" for a direct fetch.'}}function xE(e,t){if(t.length===0)return`# Search results for "${e}"
|
|
273
|
+
${rt(e,{headless:t,latched:n})}`,{cause:e})}var iE,YG,QG,sE,eq,Gm=m(()=>{"use strict";iE=["Cannot find package","ERR_MODULE_NOT_FOUND","Executable doesn't exist"],YG="pnpm exec playwright install chromium",QG=4;eq="This session already latched the failure, so browser tools keep fast-failing with this same error \u2014 after installing, call browser_close once to retry."});import Zn from"node:fs";import el from"node:path";import{randomBytes as tq}from"node:crypto";function nq(){try{return"5.222.1"}catch{}try{let e=el.resolve(import.meta.dirname,"../../../package.json"),t=Zn.readFileSync(e,"utf8"),n=JSON.parse(t);return typeof n.version=="string"?n.version:"unknown"}catch{return"unknown"}}var rq,tl,cE=m(()=>{"use strict";Gm();M();V();rq=nq(),tl=class{config;browser;sessions=new Map;launchPromise;launchFailure;shutdownComplete=!1;constructor(t){this.config=t}clearLaunchFailure(){this.launchFailure=void 0}latchLaunchFailure(t){this.launchFailure={error:t}}async ensureBrowser(){if(this.browser!==void 0&&this.browser.isConnected())return this.browser;if(this.launchFailure!==void 0)throw this.launchFailure.error;return this.browser!==void 0&&!this.browser.isConnected()&&(this.browser=void 0,this.launchPromise=void 0),this.launchPromise!==void 0?this.launchPromise:(this.launchPromise=(async()=>{let t;try{({chromium:t}=await import("playwright"))}catch(n){let r=Zc(n,this.config.headless,!0);throw this.latchLaunchFailure(r),this.launchPromise=void 0,r}try{let n=await t.launch({headless:this.config.headless});return this.browser=n,this.clearLaunchFailure(),n}catch(n){let r=Zc(n,this.config.headless,!0);throw this.latchLaunchFailure(r),r}finally{this.launchPromise=void 0}})(),this.launchPromise)}isBrowserActive(){return this.browser!==void 0&&this.browser.isConnected()}async ensureContext(t){let n=this.sessions.get(t);if(n!==void 0)return n.context;let r=await this.ensureBrowser(),o=this.loadStorageState(this.config.defaultProfile),s=await r.newContext({...this.contextOptions(),...o!==void 0?{storageState:o}:{}}),i={context:s,page:void 0,consoleErrors:0,lastHttpStatus:null,openDialog:void 0};return this.sessions.set(t,i),s}async ensurePage(t){let n=this.sessions.get(t);if(n!==void 0&&n.page!==void 0)return n.page;await this.ensureContext(t);let r=this.sessions.get(t);if(r===void 0)throw new Error(`[BrowserLauncher] session entry disappeared for sessionId=${t}`);if(r.page!==void 0)return r.page;let o=await r.context.newPage();return r.page=o,o.on("console",s=>{s.type()==="error"&&(r.consoleErrors+=1)}),o.on("request",s=>{s.isNavigationRequest()&&s.frame()===o.mainFrame()&&(r.lastHttpStatus=null)}),o.on("response",s=>{s.frame()===o.mainFrame()&&s.request().isNavigationRequest()&&(r.lastHttpStatus=s.status())}),o.on("dialog",s=>{r.openDialog=s}),o}getPage(t){return this.sessions.get(t)?.page}async renderHtml(t,n){let o=await(await this.ensureBrowser()).newContext(this.contextOptions()),s;n.requestGuard!==void 0&&await o.route("**/*",async a=>{try{await n.requestGuard(a.request().url()),await a.continue()}catch(c){s=c,await a.abort("blockedbyclient")}});let i=()=>{o.close().catch(()=>{})};if(n.signal?.aborted===!0)throw await o.close().catch(()=>{}),new Error("render aborted");n.signal!==void 0&&n.signal.addEventListener("abort",i,{once:!0});try{let a=await o.newPage(),c;try{c=await a.goto(t,{timeout:n.timeoutMs,waitUntil:n.waitUntil})}catch(p){throw s??p}if(s!==void 0)throw s;let l=await a.content();if(s!==void 0)throw s;let d=a.url(),u=c!==null?c.status():null;return{html:l,finalUrl:d,httpStatus:u}}finally{n.signal!==void 0&&n.signal.removeEventListener("abort",i),await o.close().catch(()=>{})}}getConsoleErrorCount(t){return this.sessions.get(t)?.consoleErrors??0}getLastHttpStatus(t){return this.sessions.get(t)?.lastHttpStatus??null}hasOpenDialog(t){return this.sessions.get(t)?.openDialog!==void 0}async dismissDialog(t,n=!0){let r=this.sessions.get(t);if(r===void 0||r.openDialog===void 0)return;let o=r.openDialog;r.openDialog=void 0,n?await o.accept():await o.dismiss()}async closeSession(t){this.clearLaunchFailure();let n=this.sessions.get(t);n!==void 0&&(this.sessions.delete(t),await this.saveStorageState(this.config.defaultProfile,n.context),n.page!==void 0&&await n.page.close().catch(()=>{}),await n.context.close().catch(()=>{}))}async shutdown(){if(this.clearLaunchFailure(),this.shutdownComplete)return;this.shutdownComplete=!0;let t=[...this.sessions.keys()];if(await Promise.all(t.map(n=>this.closeSession(n))),this.browser!==void 0){let n=this.browser;this.browser=void 0,await n.close().catch(()=>{})}}activeSessions(){return this.sessions.size}contextOptions(){return{viewport:{width:1280,height:800},userAgent:`Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 agent-afk/${rq}`}}loadStorageState(t){let n=Ip(t);try{if(!Zn.existsSync(n))return;let r=JSON.parse(Zn.readFileSync(n,"utf8"));return O("[browser/vault] restored session",{profile:t,file:n}),r}catch(r){O("[browser/vault] ignoring unreadable vault",{profile:t,file:n,err:r});return}}async saveStorageState(t,n){try{let r=Ip(t);if(!Zn.existsSync(r))return;let o=await n.storageState(),s=el.join(el.dirname(r),`.${el.basename(r)}.${process.pid}.${tq(4).toString("hex")}.tmp`);Zn.writeFileSync(s,JSON.stringify(o),{mode:384}),Zn.chmodSync(s,384),Zn.renameSync(s,r),O("[browser/vault] saved session",{profile:t,file:r})}catch(r){O("[browser/vault] save failed",{profile:t,err:r})}}}});import{createHash as oq}from"node:crypto";function sq(e){return e?e.replace(/\s+/g," ").trim().slice(0,200):""}function iq(e,t,n){return`el_${oq("sha256").update(`${e}:${t}:${n}`).digest("hex").slice(0,6)}`}function aq(e){let t=e.replace(/\s+/g," ").trim(),n=4e3;return t.length<=n?t:t.slice(0,n)+"\u2026[truncated]"}function lE(e){return e.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function uE(e,t){let n=e.role??"",r=e.name??"";dE.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&t.push(e);for(let s of e.children??[])uE(s,t)}async function cq(e){return e.evaluate(t=>{let n=Array.from(document.querySelectorAll(t)),r=[];for(let o of n){let s=o.getBoundingClientRect(),i=o;if(s.width===0&&s.height===0){let d=window.getComputedStyle(i);if(d.display==="none"||d.visibility==="hidden")continue}let a=o.tagName.toLowerCase(),c=o.getAttribute("aria-label")??o.getAttribute("placeholder")??(o.textContent??"").replace(/\s+/g," ").trim().slice(0,100),l=a==="input"?o.type||null:o.getAttribute("type");r.push({name:c,tagName:a,type:l,id:o.id||null,testId:o.getAttribute("data-testid"),bbox:{x:Math.round(s.left),y:Math.round(s.top),w:Math.round(s.width),h:Math.round(s.height)}})}return r},pE).catch(()=>[])}async function lq(e){return e.evaluate(t=>{let n={button:"button",a:"link",input:"textbox",textarea:"textbox",select:"combobox"},r=Array.from(document.querySelectorAll(t)),o=[];for(let s of r){let i=s.tagName.toLowerCase(),a=s.getAttribute("role")??"",c=s.getAttribute("aria-label")??s.getAttribute("placeholder")??(s.textContent??"").replace(/\s+/g," ").trim().slice(0,100),l=a||(n[i]??"");if(i==="input"){let h=s.type;h==="checkbox"?l="checkbox":h==="radio"?l="radio":h==="button"||h==="submit"||h==="reset"?l="button":h==="search"?l="searchbox":l="textbox"}if(!l)continue;let d="value"in s?s.value:void 0,u=d!==void 0?String(d):void 0,p=s.disabled??!1,f=i==="input"?s.checked:void 0,g={role:l,name:c,disabled:p};u!==void 0&&(g.value=u),f!==void 0&&(g.checked=f),o.push(g)}return o},pE).catch(()=>[])}function dq(e){let n=e.accessibility;return n!==null&&typeof n=="object"?n:null}async function nl(e,t){let n=t.maxElements??80,r=t.includeHidden??!1,o=[],s=dq(e),i=s?s.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=cq(e),c=e.evaluate(()=>document.body?.innerText??"").catch(()=>""),l=Promise.resolve(e.url()),d=e.title().catch(()=>""),[u,p,f,g,h]=await Promise.all([i,a,c,l,d]),y,b=!1;u!==null?(y=[],uE(u,y)):(o.push("observation skipped accessibility tree (returned null)"),b=!0,y=(await lq(e)).filter(C=>dE.has(C.role??"")));let S=new Map;for(let _ of p){let C=lE(_.name),N=S.get(C);(!N||N.bbox.w===0&&_.bbox.w>0)&&S.set(C,_)}let k=y.map(_=>({ax:_,dom:S.get(lE(_.name??""))})),T=r?k:k.filter(_=>_.dom?_.dom.bbox.w>0||_.dom.bbox.h>0:!0);T.sort((_,C)=>{let N=_.dom?.bbox.y??0,D=C.dom?.bbox.y??0;if(N!==D)return N-D;let U=_.dom?.bbox.x??0,L=C.dom?.bbox.x??0;return U-L}),T.length>200&&o.push("page has 200+ interactive elements; consider scoping");let R=T.slice(0,n).map((_,C)=>{let N=_.ax.role??"generic",D=_.ax.name??"",U=iq(N,D,C),L=_.dom?.bbox??{x:0,y:0,w:0,h:0},$=_.dom?.type??null,q=null;_.ax.value!==void 0&&_.ax.value!==null&&(q=String(_.ax.value)),_.ax.checked!==void 0&&(q=String(_.ax.checked)),J_({role:N,kind:$})&&(q="[redacted]");let K={disabled:_.ax.disabled??!1};_.ax.checked!==void 0&&(K.checked=_.ax.checked===!0||_.ax.checked==="mixed"),_.ax.selected!==void 0&&(K.selected=_.ax.selected),_.ax.expanded!==void 0&&(K.expanded=_.ax.expanded);let ne;_.dom?.testId?ne=`[data-testid="${_.dom.testId}"]`:_.dom?.id&&(ne=`#${_.dom.id}`);let In={id:U,role:N,label:sq(D),kind:$,value:q,state:K,bbox:L};return ne!==void 0&&(In.selector=ne),In}),x="idle";try{let _=await e.evaluate(()=>document.readyState);_==="loading"?x="loading":_==="interactive"?x="navigating":x="idle"}catch{x="navigating"}x!=="idle"&&o.push("page is still loading \u2014 observation may be incomplete"),b&&!o.includes("observation skipped accessibility tree (returned null)")&&o.push("observation skipped accessibility tree (returned null)");let F=aq(f),v=`obs_${t.observationCounter.toString(36)}`,A=new Date().toISOString();return{observationId:v,url:g,title:h,textSummary:F,interactive:R,status:{httpStatus:t.httpStatus??null,loadingState:x,hasDialog:t.hasDialog??!1,consoleErrors:t.consoleErrors??0},warnings:o,screenshotPath:t.screenshotPath??null,capturedAt:A}}var dE,pE,fE=m(()=>{"use strict";Yc();dE=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);pE="a[href], button, input, select, textarea, [role], [tabindex], label"});async function mE(e,t){try{let n=await e.nth(t).evaluate(i=>{let a=i,c=a.getAttribute("role")??a.tagName.toLowerCase(),l=a.getAttribute("aria-label")??a.getAttribute("placeholder")??(a.innerText!=null?a.innerText.trim().slice(0,200):"")??a.getAttribute("title")??"",d=a.getBoundingClientRect();return{role:c,label:l,x:Math.round(d.x),y:Math.round(d.y),w:Math.round(d.width),h:Math.round(d.height)}}),r=`${n.role}:${n.label}:${t}`,o=0;for(let i=0;i<r.length;i++)o=o*31+r.charCodeAt(i)>>>0;return{id:`el_${o.toString(16).padStart(6,"0").slice(0,6)}`,role:n.role,label:n.label,kind:null,value:null,state:{disabled:!1},bbox:{x:n.x,y:n.y,w:n.w,h:n.h}}}catch{return null}}async function qm(e,t){let n=Math.min(t,5);return(await Promise.all(Array.from({length:n},(o,s)=>mE(e,s)))).filter(o=>o!==null)}async function uq(e){let t=new Set,n=[];for(let{loc:r,count:o}of e)for(let s=0;s<o;s++){let i;try{i=await r.nth(s).evaluate(a=>{let c=a,l=c.getBoundingClientRect();return`${c.tagName}@${Math.round(l.x)},${Math.round(l.y)}`})}catch{continue}t.has(i)||(t.add(i),n.push({key:i,locator:r,index:s}))}return n}async function Xm(e,t,n){switch(t.kind){case"element_id":return pq(e,t,n);case"selector":return fq(e,t);case"semantic":return mq(e,t)}}async function pq(e,t,n){let r=n.get(t.elementId);if(r===void 0)return{outcome:"not_found",query:t};if(r.selector!==void 0){let c=e.locator(r.selector);if(await c.count()===1)return{outcome:"resolved",locator:c}}let o=e.getByRole(r.role,{name:r.label,exact:!0}),s=await o.count();if(s===0)return{outcome:"not_found",query:t};if(s===1)return{outcome:"resolved",locator:o};let i=await qm(o,s);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:i}}async function fq(e,t){let n=e.locator(t.selector),r=await n.count();if(r===0)return{outcome:"not_found",query:t};if(r===1)return{outcome:"resolved",locator:n};let o=await qm(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${t.selector}]`},candidates:o}}async function mq(e,t){return t.role!==void 0?gq(e,t.text,t.role):hq(e,t.text,t)}async function gq(e,t,n){let r=e.getByRole(n,{name:t}),o=await r.count();if(o===0)return{outcome:"not_found",query:{kind:"semantic",text:t,role:n}};if(o===1)return{outcome:"resolved",locator:r};let s=await qm(r,o);return{outcome:"ambiguous_target",query:{text:t,role:n},candidates:s}}async function hq(e,t,n){let r=e.getByRole("button",{name:t}),o=e.getByRole("link",{name:t}),s=e.getByLabel(t,{exact:!1}),[i,a,c]=await Promise.all([r.count(),o.count(),s.count()]);if(i+a+c===0)return{outcome:"not_found",query:n};let d=[];i>0&&d.push({loc:r,count:i}),a>0&&d.push({loc:o,count:a}),c>0&&d.push({loc:s,count:c});let u=await uq(d);if(u.length===0)return{outcome:"not_found",query:n};if(u.length===1){let h=u[0];return h===void 0?{outcome:"not_found",query:n}:{outcome:"resolved",locator:h.locator.nth(h.index)}}let p=u.slice(0,5),f=[];for(let h=0;h<p.length;h++){let y=p[h];if(y===void 0)continue;let b=await mE(y.locator,y.index);if(b!==null){let S=`${b.role}:${b.label}:${h}`,k=0;for(let T=0;T<S.length;T++)k=k*31+S.charCodeAt(T)>>>0;f.push({...b,id:`el_${k.toString(16).padStart(6,"0").slice(0,6)}`})}}return{outcome:"ambiguous_target",query:{text:t},candidates:f}}var gE=m(()=>{"use strict"});async function zm(e,t,n,r){let o=e.url();if(o===n)return null;let s=ft(o,t);if(s.allowed)return null;try{await e.goBack()}catch{await r()}return{outcome:"blocked_by_policy",url:o,reason:s.reason}}var hE=m(()=>{"use strict";dn()});var Vm={};zo(Vm,{PlaywrightProvider:()=>Jm});function yE(e){switch(e.kind){case"semantic":return e.role!==void 0?`semantic('${e.text}', role='${e.role}')`:`semantic('${e.text}')`;case"element_id":return`element_id(${e.elementId})`;case"selector":return`selector(${e.selector})`}}var Jm,Ym=m(()=>{"use strict";cE();fE();gE();dn();hE();Bm();Jm=class{name="playwright";config;launcher;sessions=new Map;constructor(t){this.config=t,this.launcher=new tl(t)}async open(t){let n=ft(t.url,this.config);if(!n.allowed)return{outcome:"blocked_by_policy",url:t.url,reason:n.reason};let{sessionId:r}=t,o=await this.launcher.ensurePage(r),s=this.ensureSessionState(r),i=null,a=null;try{await o.goto(t.url,{timeout:t.timeoutMs??3e4,waitUntil:t.waitFor??"load"})}catch(u){a=u}let c=o.url();if(!(a!==null&&(c===""||c==="about:blank"))){let u=await zm(o,this.config,t.url,()=>this.close({sessionId:r}));if(u!==null)return u}(t.screenshot===!0||a!==null)&&(i=await this.captureScreenshot(o,r,"browser_open")),s.observationCounter+=1;let d=await nl(o,{observationCounter:s.observationCounter,screenshotPath:i,consoleErrors:this.launcher.getConsoleErrorCount(r),httpStatus:this.launcher.getLastHttpStatus(r),hasDialog:this.launcher.hasOpenDialog(r)});if(this.updateSessionFromObservation(s,d.interactive,d.url,d.title,"browser_open"),a!==null)throw a;return d}async observe(t){let{sessionId:n}=t,r=this.launcher.getPage(n);if(r===void 0)throw new Error(`browser_observe: no page open for session ${n}`);let o=this.ensureSessionState(n),s=null;t.screenshot===!0&&(s=await this.captureScreenshot(r,n,"browser_observe")),o.observationCounter+=1;let i=await nl(r,{observationCounter:o.observationCounter,screenshotPath:s,consoleErrors:this.launcher.getConsoleErrorCount(n),httpStatus:this.launcher.getLastHttpStatus(n),hasDialog:this.launcher.hasOpenDialog(n),includeHidden:t.includeHidden,maxElements:t.maxElements});return this.updateSessionFromObservation(o,i.interactive,i.url,i.title,"browser_observe"),i}async act(t){let{sessionId:n}=t,r=this.launcher.getPage(n);if(r===void 0)throw new Error(`browser_act: no page open for session ${n}`);let o=this.ensureSessionState(n),s=r.url(),i=t.timeoutMs??3e4,a=await Xm(r,t.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${yE(t.target)}`);if(a.outcome==="ambiguous_target")return a;let{locator:c}=a,l=null,d=async()=>{switch(t.action){case"click":await c.click({timeout:i});break;case"fill":await c.fill(t.value??"");break;case"press":await c.press(t.value??"");break;case"select":await c.selectOption(t.value??"");break;case"hover":await c.hover({timeout:i});break;case"scroll_to":await c.scrollIntoViewIfNeeded({timeout:i});break;case"wait_for":await c.waitFor({timeout:i,state:"visible"});break}};try{await d()}catch(h){if(h instanceof Error&&/navigation|net::ERR/i.test(h.message))try{await d()}catch(y){l=y}else l=h}let u=await zm(r,this.config,s,()=>this.close({sessionId:n}));if(u!==null)return u;let p=null;(t.screenshot===!0||l!==null)&&(p=await this.captureScreenshot(r,n,"browser_act")),o.observationCounter+=1;let f=await nl(r,{observationCounter:o.observationCounter,screenshotPath:p,consoleErrors:this.launcher.getConsoleErrorCount(n),httpStatus:this.launcher.getLastHttpStatus(n),hasDialog:this.launcher.hasOpenDialog(n)}),g=`browser_act:${t.action}`;if(this.updateSessionFromObservation(o,f.interactive,f.url,f.title,g),l!==null)throw l;return f}async render(t){return this.launcher.renderHtml(t.url,{timeoutMs:t.timeoutMs??3e4,waitUntil:t.waitFor??"load",signal:t.signal,requestGuard:t.requestGuard})}async screenshot(t){let{sessionId:n}=t,r=this.launcher.getPage(n);if(r===void 0)throw new Error(`browser_screenshot: no page open for session ${n}`);let o=this.ensureSessionState(n),s;if(t.target!==void 0){let d=await Xm(r,t.target,o.knownElements);if(d.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${yE(t.target)}`);if(d.outcome==="ambiguous_target")throw new Error("screenshot target ambiguous; specify element_id or selector");s=await d.locator.screenshot()}else s=await r.screenshot({fullPage:t.fullPage??!1});let{path:i,bytes:a}=await Vr(n,s,"browser_screenshot"),c=0,l=0;if(t.fullPage===!0)try{let d=await r.evaluate(()=>({w:document.documentElement.scrollWidth,h:document.documentElement.scrollHeight}));c=d.w,l=d.h}catch{let d=r.viewportSize();c=d?.width??0,l=d?.height??0}else{let d=r.viewportSize();c=d?.width??0,l=d?.height??0}return{path:i,bytes:a,width:c,height:l,dataBase64:s.toString("base64"),mediaType:"image/png"}}async extract(t){throw new Error("browser_extract not implemented in Phase 1")}async close(t){await this.launcher.closeSession(t.sessionId),this.sessions.delete(t.sessionId)}describe(t){let n=this.sessions.get(t);if(n===void 0)return null;let r=this.launcher.getPage(t);return{active:r!==void 0,url:n.currentUrl,title:n.currentTitle,lastAction:n.lastAction,lastActionAt:n.lastActionAt,openTabs:r!==void 0?1:0}}async shutdown(){this.sessions.clear(),await this.launcher.shutdown()}ensureSessionState(t){let n=this.sessions.get(t);if(n!==void 0)return n;let r={observationCounter:0,knownElements:new Map,lastAction:null,lastActionAt:null,currentUrl:null,currentTitle:null};return this.sessions.set(t,r),r}updateSessionFromObservation(t,n,r,o,s){t.knownElements=new Map(n.map(i=>[i.id,i])),t.currentUrl=r,t.currentTitle=o,t.lastAction=s,t.lastActionAt=new Date().toISOString()}async captureScreenshot(t,n,r){try{let o=await t.screenshot({fullPage:!1}),{path:s}=await Vr(n,o,r);return s}catch{return null}}}});var tr={};zo(tr,{__resetBrowserRegistryForTests:()=>vq,browserProviderActive:()=>wq,closeBrowserProvider:()=>Zm,getBrowserProvider:()=>bq,getLastRoutingDecision:()=>kq,peekBrowserProvider:()=>Sq});function bE(){Promise.resolve(Zm()).then(()=>{process.exit(130)})}function wE(){Promise.resolve(Zm()).then(()=>{process.exit(143)})}function SE(){Et=null}function yq(){rl||(process.on("SIGINT",bE),process.on("SIGTERM",wE),process.on("exit",SE),rl=!0)}function kE(){rl&&(process.removeListener("SIGINT",bE),process.removeListener("SIGTERM",wE),process.removeListener("exit",SE),rl=!1)}async function bq(e){return Et!==null?Et:(er!==null||(er=(async()=>{let t=Lm(e),n=e?.surface??(e?.env??{}).AGENT_SURFACE??w.AGENT_SURFACE,r=await X_({config:t,surface:n});Qm=r;let o;if(r.backend==="agent-browser"){let{AgentBrowserProvider:s}=await Promise.resolve().then(()=>(oE(),rE)),i=r.availability.connection;o=new s(t,i)}else{let{PlaywrightProvider:s}=await Promise.resolve().then(()=>(Ym(),Vm));o=new s(t)}return yq(),Et=o,er=null,o})()),er)}async function Zm(){if(Et===null)return;let e=Et;Et=null,er=null,kE(),await e.shutdown()}function wq(){return Et!==null}function Sq(){return Et}function kq(){return Qm}function vq(){Et=null,er=null,Qm=null,kE()}var Et,er,rl,Qm,nr=m(()=>{"use strict";dn();z_();P();Et=null,er=null,rl=!1,Qm=null});async function vE(e,t){try{return await D_(e,t)}catch(n){return O("[web/scrape] extraction failed",{url:t,err:n}),{title:"",markdown:"",textLength:0,usedFallback:!0}}}async function Rq(e,t){let{getBrowserProvider:n}=await Promise.resolve().then(()=>(nr(),tr)),r=await n();try{return await r.render({url:e,timeoutMs:t.timeoutMs,signal:t.signal,requestGuard:t.requestGuard})}catch(o){if(r.name==="agent-browser"){let{PlaywrightProvider:s}=await Promise.resolve().then(()=>(Ym(),Vm)),{loadBrowserConfig:i}=await Promise.resolve().then(()=>(dn(),Nm)),a=i(),c=new s(a);try{return await c.render({url:e,timeoutMs:t.timeoutMs,signal:t.signal,requestGuard:t.requestGuard})}finally{await c.shutdown()}}throw o}}async function TE(e,t){let n=t.fetchFn??globalThis.fetch,r=t.renderFn??Rq,o=t.lookupFn!==void 0?{lookupFn:t.lookupFn}:{},s=null,i="",a=e,c=null,l=null;try{let u=await ln(n,e,{headers:Aq,signal:t.signal},o);c=u.status,a=u.url||e;let p=u.headers.get("content-type")??"";if(u.ok){if(xq.test(p))throw new Error(`web_scrape markdown mode received binary content (${p.split(";")[0]}). Use mode: "raw" to fetch the bytes, or a different tool.`);let f=await u.text();if(Eq.test(p)&&!_q.test(p))return{title:"",markdown:f.trim(),finalUrl:a,usedRender:!1};if(i=f,s=await vE(f,a),t.signal.aborted)throw t.signal.reason??new Error("aborted")}}catch(u){if(t.signal.aborted||u instanceof Te||u instanceof Error&&u.message.startsWith("web_scrape markdown mode received binary"))throw u;l=u}if(!(s===null||s.textLength<200)&&s!==null){let u=Mm({html:i,extractedTextLength:s.textLength});return{title:s.title,markdown:s.markdown,finalUrl:a,usedRender:!1,...u!==void 0?{advisory:u}:{}}}try{await Vs(e,o);let u=await r(e,{timeoutMs:t.timeoutMs,signal:t.signal,requestGuard:f=>Vs(f,o)});u.finalUrl!==e&&/^https?:\/\//i.test(u.finalUrl)&&await Vs(u.finalUrl,o);let p=await vE(u.html,u.finalUrl);if(t.signal.aborted)throw t.signal.reason??new Error("aborted");if(s===null||p.textLength>=s.textLength){let f=Mm({html:u.html,extractedTextLength:p.textLength});return{title:p.title,markdown:p.markdown,finalUrl:u.finalUrl,usedRender:!0,...f!==void 0?{advisory:f}:{}}}}catch(u){if(t.signal.aborted||u instanceof Te)throw u;if(s===null){let p=u instanceof Error?u.message:String(u),f=l instanceof Error?l.message:`HTTP ${c??"error"}`,g=new Error(`web_scrape could not retrieve ${e}: fetch failed (${f}) and render failed (${p}).`);throw g.cause=u,g}}if(s!==null)return{title:s.title,markdown:s.markdown,finalUrl:a,usedRender:!1};throw new Error(`web_scrape could not retrieve any content from ${e} (HTTP ${c??"error"}).`)}var _q,Eq,xq,Aq,_E=m(()=>{"use strict";F_();Om();Qn();V();_q=/(text\/html|application\/xhtml\+xml)/i,Eq=/(application\/json|\/xml|\+xml|text\/|application\/(java|ecma)script|csv)/i,xq=/(image\/|audio\/|video\/|application\/pdf|application\/zip|application\/octet-stream|font\/)/i,Aq={"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 agent-afk/web_scrape",Accept:"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"}});function Pq(e){let t=e.fetchFn??globalThis.fetch;return{name:"exa",async search(n,{limit:r,signal:o}){let s=await t(Iq,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json","x-api-key":e.apiKey,"User-Agent":"agent-afk/web_scrape"},body:JSON.stringify({query:n,type:"auto",numResults:Math.min(Math.max(r,1),Cq),contents:{highlights:{numSentences:3,highlightsPerUrl:1}}}),signal:o});if(!s.ok){let c="";try{let d=await s.text(),u=ue(d);u&&(c=`: ${u.length>200?u.slice(0,200)+"\u2026":u}`)}catch{}let l=s.statusText?` ${s.statusText}`:"";throw new Error(`Exa Search HTTP ${s.status}${l}${c}`)}let i;try{i=await s.json()}catch(c){throw new Error(`Exa Search response was not JSON: ${c instanceof Error?c.message:String(c)}`)}return(i.results??[]).slice(0,r).map(c=>({title:(c.title??"").trim()||"(untitled)",url:c.url??"",description:(c.highlights?.[0]??"").trim()})).filter(c=>c.url.length>0)}}}function EE(e){return e.exaApiKey!==void 0&&e.exaApiKey.trim()!==""?Pq({apiKey:e.exaApiKey,fetchFn:e.fetchFn}):{error:'web_scrape search mode requires a search backend. Set EXA_API_KEY (free tier at https://exa.ai) to enable it. Use mode: "markdown" to read a known URL, or mode: "raw" for a direct fetch.'}}function xE(e,t){if(t.length===0)return`# Search results for "${e}"
|
|
274
274
|
|
|
275
275
|
(no results)`;let n=[`# Search results for "${e}"`,""];return t.forEach((r,o)=>{n.push(`## ${o+1}. ${r.title}`),r.url&&n.push(r.url),r.description&&n.push(r.description),n.push("")}),n.join(`
|
|
276
276
|
`).trimEnd()}var Iq,Cq,AE=m(()=>{"use strict";Je();Iq="https://api.exa.ai/search",Cq=10});function ol(e){if(e instanceof Error&&e.name==="TimeoutError")return"timeout";let t=e instanceof Error?e.message:String(e);return/Timeout\s+\d+\s*ms exceeded/i.test(t)?"timeout":void 0}var rr=m(()=>{"use strict";Gm()});function Nq(e){if(!e||typeof e!="object")return{error:"Invalid input: expected an object"};let t=e,n=t.mode??"markdown";if(n!=="markdown"&&n!=="raw"&&n!=="search")return{error:`Invalid input: mode must be one of "markdown", "raw", "search" (got ${JSON.stringify(n)})`};let r=n,o,s;if(r==="search"){if(typeof t.query!="string"||t.query.length===0)return{error:'Invalid input: search mode requires a non-empty "query" string'};s=t.query}else{if(typeof t.url!="string"||t.url.length===0)return{error:`Invalid input: ${r} mode requires a non-empty "url" string`};let c;try{c=new URL(t.url)}catch{return{error:`Invalid input: "${t.url}" is not a valid absolute URL`}}if(c.protocol!=="http:"&&c.protocol!=="https:")return{error:`Invalid input: protocol "${c.protocol}" not supported (http/https only)`};o=c.toString()}let i=Mq;if(t.timeout_ms!==void 0){if(typeof t.timeout_ms!="number"||!Number.isFinite(t.timeout_ms)||t.timeout_ms<=0)return{error:"Invalid input: timeout_ms must be a positive finite number"};i=Math.min(t.timeout_ms,Oq)}let a=Dq;if(t.max_bytes!==void 0){if(typeof t.max_bytes!="number"||!Number.isFinite(t.max_bytes)||t.max_bytes<=0)return{error:"Invalid input: max_bytes must be a positive finite number"};a=Math.min(t.max_bytes,Fq)}return{mode:r,url:o,query:s,timeoutMs:i,maxBytes:a}}function eg(e,t){return Buffer.byteLength(e,"utf8")<=t?{content:e,truncated:!1}:{content:kt(e,t),truncated:!0}}function Uq(e={}){let t=e.fetchFn??globalThis.fetch,n=e.env??process.env,r=e.lookupFn!==void 0?{lookupFn:e.lookupFn}:{};return async(o,s)=>{if(typeof t!="function")return{content:"web_scrape unavailable: global fetch() is not present in this runtime (agent-afk requires Node 20+).",isError:!0};let i=Nq(o);if("error"in i)return{content:i.error,isError:!0};if(s.aborted){let u=s.reason;return{content:`web_scrape aborted: ${u instanceof Error?u.message:String(u??"aborted")}`,isError:!0}}let a=new AbortController,c=()=>{a.abort(s.reason)},l,d=()=>{let u=a.signal.reason;return u instanceof Error?u.message:String(u??"aborted")};try{if(s.addEventListener("abort",c,{once:!0}),l=setTimeout(()=>{a.abort(new Error(`web_scrape timeout after ${i.timeoutMs}ms`))},i.timeoutMs),i.url!==void 0){let p=await Yn(i.url,r);if(a.signal.aborted)return{content:`web_scrape aborted: ${d()}`,isError:!0};if(!p.allowed)return{content:`web_scrape blocked: ${p.reason}`,isError:!0}}if(i.mode==="raw"){let p;try{let h={method:"GET",headers:{"User-Agent":"agent-afk/web_scrape",Accept:"*/*"},signal:a.signal};p=await ln(t,i.url,h,r)}catch(h){return a.signal.aborted?{content:`web_scrape aborted: ${d()}`,isError:!0}:h instanceof Te?{content:`web_scrape blocked: ${h.message}`,isError:!0}:{content:`web_scrape network error: ${h instanceof Error?h.message:String(h)}`,isError:!0}}if(!p.ok)return{content:`web_scrape HTTP ${p.status} ${p.statusText||""}`.trimEnd()+` for ${i.url}`,isError:!0};let f;try{f=await p.text()}catch(h){return{content:`web_scrape read error: ${h instanceof Error?h.message:String(h)}`,isError:!0}}let g=eg(f,i.maxBytes);return{content:g.content,...g.truncated?{truncated:!0}:{}}}if(i.mode==="markdown")try{let p=await TE(i.url,{fetchFn:t,renderFn:e.renderFn,timeoutMs:i.timeoutMs,signal:a.signal,...e.lookupFn!==void 0?{lookupFn:e.lookupFn}:{}});if(p.markdown.trim().length===0)return{content:`web_scrape extracted no readable content from ${i.url}.`,isError:!0};let f=eg(L_(p.markdown,p.advisory),i.maxBytes);return{content:f.content,...f.truncated?{truncated:!0}:{}}}catch(p){if(a.signal.aborted)return{content:`web_scrape aborted: ${d()}`,isError:!0};if(p instanceof Te)return{content:`web_scrape blocked: ${p.message}`,isError:!0};let f=p instanceof Error?p.message:String(p),g=Ue(p)&&!Km(f)?` (the render fallback needs the optional Playwright browser \u2014 run \`${Ys()}\`)`:"";return{content:`web_scrape markdown error: ${f}${g}`,isError:!0}}let u=EE({exaApiKey:n.EXA_API_KEY,fetchFn:t});if("error"in u)return{content:u.error,isError:!0};try{let p=await u.search(i.query,{limit:Lq,timeoutMs:i.timeoutMs,signal:a.signal}),f=eg(xE(i.query,p),i.maxBytes);return{content:f.content,...f.truncated?{truncated:!0}:{}}}catch(p){return a.signal.aborted?{content:`web_scrape aborted: ${d()}`,isError:!0}:{content:`web_scrape search error (${u.name}): ${p instanceof Error?p.message:String(p)}`,isError:!0}}}finally{l!==void 0&&clearTimeout(l),s.removeEventListener("abort",c)}}}var Mq,Oq,Dq,Fq,Lq,RE,IE=m(()=>{"use strict";_E();AE();Qn();vt();Om();rr();Mq=3e4,Oq=12e4,Dq=1e5,Fq=1e6,Lq=10;RE=Uq()});function jq(e){return $q.has(e)?"low":e==="DELETE"?"high":"medium"}function Hq(e){return Bq.has(e)}function Gq(e){let t={};return e.forEach((n,r)=>{let o=r.toLowerCase();Kq.has(o)||Wq.some(s=>o.startsWith(s))||(t[r]=n)}),t}function qq(e,t){if(e==null)return{serialized:void 0,inferredContentType:void 0};let n=Object.keys(t).some(o=>o.toLowerCase()==="content-type");return typeof e=="string"?{serialized:e,inferredContentType:n?void 0:"text/plain"}:{serialized:JSON.stringify(e),inferredContentType:n?void 0:"application/json"}}function Xq(e,t,n){let r=Buffer.byteLength(e,"utf8"),o=e,s=!1;if(r>n&&(o=kt(e,n),s=!0),!s&&/application\/json/i.test(t))try{return{body:JSON.parse(o),truncated:!1}}catch{}return{body:o,truncated:s}}async function ME(e){let{url:t,method:n,signal:r,domainCheck:o,recordEffect:s}=e,i=Math.min(e.maxResponseBytes??tg,ng),a={...e.headers},c=e.fetchFn??globalThis.fetch,l=e.lookupFn!==void 0?{lookupFn:e.lookupFn}:{},d=jq(n);if(o!==void 0){let v=o(t);if(!v.allowed)throw Object.assign(new Error(`web_request blocked by domain policy: ${v.reason}`),{name:"DomainPolicyError"})}let u=await Yn(t,l);if(!u.allowed)throw new Te(u.reason);let{serialized:p,inferredContentType:f}=qq(e.body,a);f!==void 0&&(a["content-type"]=f);let g={method:n,headers:Object.keys(a).length>0?a:void 0,body:p,signal:r},y=Hq(n)?{retries:2,baseDelayMs:300,maxDelayMs:5e3}:{retries:0},b=Date.now(),S;try{S=await ln(c,t,g,{...l,retry:y})}catch(v){throw v instanceof Te,v}let k=Date.now()-b,T=S.headers.get("content-type")??"",E;try{let v=S.body?.getReader();if(!v)E="";else{let A=[],_=0,C=i*2;for(;;){let{done:N,value:D}=await v.read();if(N||!D)break;if(A.push(D),_+=D.byteLength,_>=C){await v.cancel();break}}E=new TextDecoder().decode(Buffer.concat(A,_))}}catch{E=""}let{body:R,truncated:x}=Xq(E,T,i),F=Gq(S.headers);return s!==void 0&&Promise.resolve(s({url:t,method:n,status:S.status,risk:d,timing_ms:k})).catch(()=>{}),{status:S.status,headers:F,body:R,truncated:x,timing_ms:k,risk:d}}function OE(e){if(typeof e!="string"||e.trim().length===0)return{error:"method must be a non-empty string (GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS)"};let t=e.trim().toUpperCase(),n=["GET","POST","PUT","PATCH","DELETE","HEAD","OPTIONS"];return n.includes(t)?t:{error:`method "${e}" is not supported \u2014 must be one of: ${n.join(", ")}`}}var CE,PE,tg,ng,$q,Bq,Wq,Kq,DE=m(()=>{"use strict";Qn();vt();CE=3e4,PE=12e4,tg=1e5,ng=1e6,$q=new Set(["GET","HEAD","OPTIONS"]),Bq=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]);Wq=["set-cookie","x-"],Kq=new Set(["server","via","age","vary","authorization","www-authenticate"])});function zq(e){if(!e||typeof e!="object")return{error:"Invalid input: expected an object"};let t=e;if(typeof t.url!="string"||t.url.length===0)return{error:'Invalid input: "url" must be a non-empty string'};let n;try{n=new URL(t.url)}catch{return{error:`Invalid input: "${t.url}" is not a valid absolute URL`}}if(n.protocol!=="http:"&&n.protocol!=="https:")return{error:`Invalid input: protocol "${n.protocol}" not supported (http/https only)`};n.username="",n.password="";let r=n.toString(),o=OE(t.method);if(typeof o=="object"&&"error"in o)return{error:`Invalid input: ${o.error}`};let s=o,i;if(t.body!==void 0&&t.body!==null){if(typeof t.body!="string"&&typeof t.body!="object")return{error:'Invalid input: "body" must be a string, object, or array'};i=t.body}let a={};if(t.headers!==void 0){if(typeof t.headers!="object"||t.headers===null||Array.isArray(t.headers))return{error:'Invalid input: "headers" must be a string-keyed object'};let u=t.headers;for(let[p,f]of Object.entries(u)){if(typeof f!="string")return{error:`Invalid input: header value for "${p}" must be a string`};a[p]=f}}let c=CE;if(t.timeout_ms!==void 0){if(typeof t.timeout_ms!="number"||!Number.isFinite(t.timeout_ms)||t.timeout_ms<=0)return{error:'Invalid input: "timeout_ms" must be a positive finite number'};c=Math.min(t.timeout_ms,PE)}let l=tg;if(t.max_response_bytes!==void 0){if(typeof t.max_response_bytes!="number"||!Number.isFinite(t.max_response_bytes)||t.max_response_bytes<=0)return{error:'Invalid input: "max_response_bytes" must be a positive finite number'};l=Math.min(t.max_response_bytes,ng)}let d;if(t.credential!==void 0){if(typeof t.credential!="string"||t.credential.length===0)return{error:'Invalid input: "credential" must be a non-empty string (an env var name)'};d=t.credential}return{url:r,method:s,body:i,headers:a,timeoutMs:c,maxResponseBytes:l,credential:d}}function Jq(e={}){let t=e.fetchFn??globalThis.fetch,n=e.env??process.env;async function r(){if(e.domainCheck!==void 0)return e.domainCheck;try{let{loadBrowserConfig:o,enforceDomainPolicy:s}=await Promise.resolve().then(()=>(dn(),Nm)),i=o();return a=>s(a,i)}catch{return}}return async(o,s)=>{if(typeof t!="function")return{content:"web_request unavailable: global fetch() is not present (agent-afk requires Node 20+).",isError:!0};let i=zq(o);if("error"in i)return{content:i.error,isError:!0};if(s.aborted){let p=s.reason;return{content:`web_request aborted: ${p instanceof Error?p.message:String(p??"aborted")}`,isError:!0}}let a={...i.headers};if(i.credential!==void 0){let p=n[i.credential];if(p===void 0||p.trim().length===0)return{content:`web_request credential error: environment variable "${i.credential}" is not set. Set it in afk.env or export it in the shell before starting AFK.`,isError:!0};if(Object.keys(a).some(g=>g.toLowerCase()==="authorization"))return{content:'web_request credential error: both "credential" and an explicit Authorization header were provided. Use one or the other.',isError:!0};a.Authorization=`Bearer ${p}`}let c=new AbortController,l=()=>c.abort(s.reason),d,u=()=>{let p=c.signal.reason;return p instanceof Error?p.message:String(p??"aborted")};try{s.addEventListener("abort",l,{once:!0}),d=setTimeout(()=>{c.abort(new Error(`web_request timeout after ${i.timeoutMs}ms`))},i.timeoutMs);let p=await r(),f={url:i.url,method:i.method,body:i.body,headers:a,maxResponseBytes:i.maxResponseBytes,signal:c.signal,fetchFn:t,lookupFn:e.lookupFn,domainCheck:p,recordEffect:e.recordEffect},g;try{g=await ME(f)}catch(S){if(c.signal.aborted)return{content:`web_request aborted: ${u()}`,isError:!0};if(S instanceof Te)return{content:`web_request blocked: ${S.message}`,isError:!0};let k=S instanceof Error&&S.name==="DomainPolicyError"?"blocked":"network error",T=S instanceof Error?S.message:String(S);return{content:`web_request ${k}: ${T}`,isError:!0}}if(c.signal.aborted)return{content:`web_request aborted: ${u()}`,isError:!0};let h=g.body;if(typeof h=="string")h=bt(h);else if(typeof h=="object"&&h!==null){let S=bt(JSON.stringify(h));try{h=JSON.parse(S)}catch{h=S}}let y={status:g.status,headers:g.headers,body:h,timing_ms:g.timing_ms,...g.truncated?{truncated:!0}:{}};return{content:JSON.stringify(y,null,2),...g.truncated?{truncated:!0}:{}}}finally{d!==void 0&&clearTimeout(d),s.removeEventListener("abort",l)}}}var FE,LE=m(()=>{"use strict";DE();Qn();$n();FE=Jq()});import{existsSync as UE,mkdirSync as Vq,readFileSync as Yq,renameSync as Qq,unlinkSync as Zq,writeFileSync as e2}from"node:fs";import{dirname as NE,join as t2}from"node:path";import{randomBytes as n2}from"node:crypto";function or(e){let t=e??_p();if(!UE(t))return[];try{let n=Yq(t,"utf-8");return JSON.parse(n)}catch(n){let r=n instanceof Error?n.message:String(n);return console.error(`[schedule-store] failed to parse ${t}: ${r}`),[]}}function Qs(e,t){let n=t??_p();Vq(NE(n),{recursive:!0});let r=t2(NE(n),`.schedules.json.${process.pid}.${n2(4).toString("hex")}.tmp`),o=JSON.stringify(e,null,2);try{e2(r,o,"utf-8"),Qq(r,n)}catch(s){try{UE(r)&&Zq(r)}catch{}throw s}}function $E(e,t){let n=or(t),r=n.map(c=>c.id),o=r2(e.name),s=o2(o,r),i=new Date().toISOString(),a={...e,notifyOn:e.notifyOn??"failure",id:s,createdAt:i,updatedAt:i};return n.push(a),Qs(n,t),a}function BE(e,t){let n=or(t),r=n.length,o=n.filter(s=>s.id!==e);return o.length===r?!1:(Qs(o,t),!0)}function jE(e,t){return or(t).find(n=>n.id===e)}function r2(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/-{2,}/g,"-").replace(/^-+|-+$/g,"")}function o2(e,t){if(!t.includes(e))return e;let n=2;for(;t.includes(`${e}-${n}`);)n+=1;return`${e}-${n}`}function HE(e){return{taskId:e.id,command:e.command,trigger:e.trigger??"cron",...e.executor!==void 0?{executor:e.executor}:{},...e.cron!==void 0?{cronExpression:e.cron}:{},...e.notifyOn!==void 0?{notifyOn:e.notifyOn}:{},...e.notifyChat!==void 0?{notifyChat:e.notifyChat}:{}}}var WE=m(()=>{"use strict";M()});import{existsSync as s2,readFileSync as i2}from"node:fs";import{join as a2}from"node:path";async function Yr(e,t,n){let r,o;try{let s=a2(Aw("default"),"port");if(!s2(s))return{synced:!1,detail:"daemon-not-detected (no port file)"};let i=i2(s,"utf-8").trim(),a=c2(i);if(!a)return{synced:!1,detail:"daemon-not-detected (invalid port file)"};({host:r,port:o}=a)}catch{return{synced:!1,detail:"daemon-not-detected (unreadable port file)"}}try{let s=r.includes(":")?`[${r}]`:r,i=await fetch(`http://${s}:${o}${t}`,{method:e,headers:{"Content-Type":"application/json"},body:n!==void 0?JSON.stringify(n):void 0,signal:AbortSignal.timeout(2e3)});return i.ok?{synced:!0,detail:"synced"}:e==="POST"&&i.status===409?{synced:!0,detail:"already-registered"}:e==="DELETE"&&i.status===404?{synced:!0,detail:"not-registered"}:{synced:!1,detail:`daemon-rejected (HTTP ${i.status})`}}catch{return{synced:!1,detail:"daemon-unreachable (stale port file or network error)"}}}function c2(e){let t=parseInt(e,10);if(String(t)===e&&!Number.isNaN(t))return t<1||t>65535?null:{host:"localhost",port:t};let n=e.lastIndexOf(":");if(n<1)return null;let r=e.slice(0,n),o=e.slice(n+1);if(!/^\d+$/.test(o))return null;let s=parseInt(o,10);return Number.isNaN(s)||s<1||s>65535||/^:+$/.test(r)?null:{host:r.startsWith("[")&&r.endsWith("]")?r.slice(1,-1):r,port:s}}var rg,KE=m(()=>{"use strict";M();rg="Change saved to schedules.json, but a running daemon (if any) did not pick it up \u2014 it will apply on the next daemon (re)start."});import{existsSync as l2}from"node:fs";import{readFile as d2}from"node:fs/promises";var GE,qE,XE,zE,JE=m(()=>{"use strict";WE();M();KE();GE=async(e,t)=>{if(!e||typeof e!="object")return{content:"Invalid input: expected object",isError:!0};let n=e;if(typeof n.name!="string"||!n.name)return{content:"Invalid input: name required",isError:!0};if(typeof n.command!="string"||!n.command)return{content:"Invalid input: command required",isError:!0};if(typeof n.cron!="string"||!n.cron)return{content:"Invalid input: cron required",isError:!0};let r=n.cron.trim().split(/\s+/);if(r.length!==5&&r.length!==6)return{content:"Invalid input: cron must be a 5 or 6-field expression",isError:!0};let o=n.notifyChat;if(o!==void 0&&typeof o!="number"&&typeof o!="string")return{content:"Invalid input: notifyChat must be a number (chat id) or string (chat id or alias name)",isError:!0};let s=n.executor;if(s!==void 0&&s!=="agent"&&s!=="shell")return{content:'Invalid input: executor must be "agent" or "shell"',isError:!0};let i=$E({name:n.name,command:n.command,cron:n.cron,...s!==void 0?{executor:s}:{},trigger:n.trigger??"cron",notifyOn:n.notifyOn,...o!==void 0?{notifyChat:o}:{},enabled:typeof n.enabled=="boolean"?n.enabled:!0}),a=i.enabled?await Yr("POST","/tasks",{taskId:i.id,command:i.command,cron:i.cron,...i.executor!==void 0?{executor:i.executor}:{},trigger:i.trigger,notifyOn:i.notifyOn,...i.notifyChat!==void 0?{notifyChat:i.notifyChat}:{}}):await Yr("DELETE",`/tasks/${i.id}`);return{content:JSON.stringify({id:i.id,name:i.name,cron:i.cron,enabled:i.enabled,daemonSynced:a.synced,syncDetail:a.detail,...a.synced?{}:{syncNote:rg}})}},qE=async(e,t)=>{let n=or();return{content:JSON.stringify(n.map(r=>({id:r.id,name:r.name,cron:r.cron,executor:r.executor??"agent",trigger:r.trigger,enabled:r.enabled,notifyOn:r.notifyOn})))}},XE=async(e,t)=>{if(!e||typeof e!="object")return{content:"Invalid input: expected object",isError:!0};let n=e;if(typeof n.taskId!="string"||!n.taskId)return{content:"Invalid input: taskId required",isError:!0};let r=n.taskId,o=typeof n.limit=="number"?Math.min(Math.max(1,n.limit),50):10,s=Ea();if(!l2(s))return{content:JSON.stringify([])};let i;try{let l=await d2(s);i=(l.length>1048576?l.subarray(l.length-1048576):l).toString("utf-8")}catch{return{content:JSON.stringify([])}}let a=i.split(`
|