agent-afk 5.220.0 → 5.221.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/markdown-stream-format.preview.d.ts +2 -0
- package/dist/cli.mjs +544 -535
- package/dist/index.mjs +1 -1
- package/dist/telegram.mjs +3 -3
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -270,7 +270,7 @@ Send a message to start one, or /new for a fresh session.`}function E_(e){return
|
|
|
270
270
|
|
|
271
271
|
${t}`}var JK,Mm=m(()=>{"use strict";JK=new Set(["script","style","noscript","template","svg"])});function QK(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 L_(e,t,n){let r=Math.min(t*2**e,n);return Math.round(Math.random()*r)}function ZK(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 N_(e,t,n={},r={}){let o=r.retries??3,s=r.baseDelayMs??500,i=r.maxDelayMs??1e4,a=r.sleep??QK,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(!YK.has(u.status)||d===o)return u;let p=ZK(u,i)??L_(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=L_(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 YK,U_=m(()=>{"use strict";V();YK=new Set([429,502,503,504])});import{BlockList as eG,isIP as Dm}from"node:net";import{lookup as tG}from"node:dns/promises";import{Agent as nG}from"undici";function B_(){let e=w.AFK_WEB_ALLOW_PRIVATE_HOSTS?.trim().toLowerCase();return e==="1"||e==="true"}function iG(e){return e.startsWith("[")&&e.endsWith("]")?e.slice(1,-1):e}function Om(e){let t=Dm(e);return t===0?!1:sG.check(e,t===4?"ipv4":"ipv6")}async function j_(e){return tG(e,{all:!0,verbatim:!0})}async function Yn(e,t={}){if(t.allowPrivateHosts??B_())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=iG(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(Dm(r)!==0)return Om(r)?{allowed:!1,reason:o(r,r)}:{allowed:!0};let s=t.lookupFn??j_,i;try{i=await s(r)}catch{return{allowed:!0}}for(let a of i)if(Om(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<=$_;i++){await Vs(s,o);let a={...n,redirect:"manual",...e===globalThis.fetch&&!(r.allowPrivateHosts??B_())?{dispatcher:aG}:{}},c=await N_(e,s,a,r.retry??{});if(!cG.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 (>${$_}) starting from ${t}`)}var rG,oG,sG,Te,aG,$_,cG,Qn=m(()=>{"use strict";P();U_();rG=[["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]],oG=[["::",96],["64:ff9b::",96],["fc00::",7],["fe80::",10]],sG=(()=>{let e=new eG;for(let[t,n]of rG)e.addSubnet(t,n,"ipv4");for(let[t,n]of oG)e.addSubnet(t,n,"ipv6");return e})(),Te=class extends Error{constructor(t){super(t),this.name="EgressBlockedError"}};aG=new nG({connect:{lookup(e,t,n){j_(e).then(r=>{let o=r.find(i=>Om(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,Dm(s.address))},r=>n(r,"",0))}}});$_=20,cG=new Set([301,302,303,307,308])});var Lm={};zo(Lm,{enforceDomainPolicy:()=>ft,loadBrowserConfig:()=>Fm});import{readFileSync as lG}from"node:fs";import{join as dG}from"path";function uG(e){let n=e.replace(/[.+?()[\]{}/\\^$|]/g,"\\$&").replace(/\*/g,"[^.]*");return new RegExp(`^${n}$`,"i")}function H_(e,t){return uG(t).test(e)}function mG(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(pG.has(t))return!0;if(fG.has(t))return!1}return!1}function W_(e){return e===void 0||e.trim()===""?[]:e.split(",").map(t=>t.trim().toLowerCase()).filter(t=>t.length>0)}function gG(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 K_(e){let t=e===void 0||e.trim()===""?"default":e.trim();return Rp(t),t}function hG(e){if(e===void 0)return!1;let t=e.trim().toLowerCase();return t==="1"||t==="true"||t==="yes"}function yG(e){try{return lG(e,"utf8")}catch(t){if(t.code==="ENOENT")return;throw t}}function bG(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=K_(t.defaultProfile)),n}function Fm(e){let t=e?.env??w,n=e?.readFileSync??yG,r=e?.surface??t.AGENT_SURFACE,o=mG(t.AFK_BROWSER_HEADLESS,r),s=W_(t.AFK_BROWSER_ALLOWED_DOMAINS),i=W_(t.AFK_BROWSER_BLOCKED_DOMAINS),a=hG(t.AFK_BROWSER_DOM_SNAPSHOTS),c=gG(t.AFK_BROWSER_BACKEND),l=K_(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():dG(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=bG(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(H_(n,r))return{allowed:!1,reason:`blocked by AFK_BROWSER_BLOCKED_DOMAINS: ${r}`};return t.allowedDomains.length>0&&!t.allowedDomains.some(o=>H_(n,o))?{allowed:!1,reason:"not in AFK_BROWSER_ALLOWED_DOMAINS"}:{allowed:!0}}var pG,fG,dn=m(()=>{"use strict";P();M();pG=new Set(["daemon","subagent","telegram","afk"]),fG=new Set(["repl","interactive","cli"])});import{readFileSync as wG}from"node:fs";import{join as SG}from"node:path";import{homedir as kG}from"node:os";function TG(e){let t=e??vG,n;try{n=wG(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 _G(e){try{return process.kill(e,0),!0}catch{return!1}}async function EG(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 Nm(e){let t=TG(e);return t===null?{available:!1,connection:null,reason:"connection file missing or invalid"}:_G(t.pid)?await EG(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 vG,G_=m(()=>{"use strict";vG=SG(kG(),".config","agent-browser","connection.json")});async function q_(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 Nm(),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&&xG.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 Nm(),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 xG,X_=m(()=>{"use strict";G_();xG=new Set(["daemon","subagent"])});import{createHash as AG}from"crypto";function z_(e){return!!(e.role==="textbox"&&e.kind==="password"||e.label&&RG.test(e.label))}function J_(e){return AG("sha256").update(e,"utf8").digest("hex").slice(0,8)}function V_(e){let t=e.replace(/\s+/g," ").trim();return t.length<=80?t:t.slice(0,77)+"..."}var RG,Yc=m(()=>{"use strict";RG=/password|secret|token|api[_-]?key|otp|2fa/i});import{randomBytes as IG}from"crypto";import{mkdir as CG,stat as PG,writeFile as MG}from"fs/promises";import{join as Um}from"path";import{gzip as OG}from"zlib";import{promisify as DG}from"util";function FG(e){return Um(ht(e),"browser")}function LG(e){return Um(FG(e),"screenshots")}function NG(){return new Date().toISOString().replace(/[:.]/g,"-")}function UG(){return IG(3).toString("hex")}async function Vr(e,t,n){if(t.length>Y_)throw new Error(`writeScreenshotSidecar: buffer exceeds ${Y_} byte cap (received ${t.length} bytes). Refusing to write oversized screenshot.`);let r=LG(e);await CG(r,{recursive:!0});let o=`${NG()}-${UG()}-${n}.png`,s=Um(r,o);await MG(s,t);let{size:i}=await PG(s);return{path:s,bytes:i}}var qae,Y_,$m=m(()=>{"use strict";M();Yc();qae=DG(OG);Y_=5*1024*1024});var Qc,Q_=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 Bm(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 Z_(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 jm(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 eE(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(Bm)};let s=r[0].id;await jm(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 tE=m(()=>{"use strict";dn()});var nE={};zo(nE,{AgentBrowserProvider:()=>Hm});var Hm,rE=m(()=>{"use strict";dn();$m();Q_();tE();Hm=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=Z_(n.knownElements,t.target);if(r===null){if(t.target.kind==="semantic"){let i=await eE({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 jm(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(Bm),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 $G,readFileSync as BG}from"node:fs";import{createRequire as jG}from"node:module";import{dirname as HG,join as WG}from"node:path";function iE(e){if(typeof e=="string")return e;let t=[],n=e;for(let r=0;r<GG&&n instanceof Error;r++)t.push(n.message),n=n.cause;return t.length>0?t.join(" | "):String(e)}function Ue(e){let t=iE(e);return sE.some(n=>t.includes(n))}function qG(){try{let t=jG(import.meta.url).resolve("playwright/package.json"),n=JSON.parse(BG(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=WG(HG(t),o);return $G(s)?`node ${/\s/.test(s)?`"${s}"`:s} install chromium`:void 0}catch{return}}function Ys(){return oE??=qG()??KG,oE}function Wm(e){return e.includes("install chromium")}function rt(e,t){let n=iE(e),r=t?.latched===!0?` ${XG}`:"";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 sE,KG,GG,oE,XG,Km=m(()=>{"use strict";sE=["Cannot find package","ERR_MODULE_NOT_FOUND","Executable doesn't exist"],KG="pnpm exec playwright install chromium",GG=4;XG="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 zG}from"node:crypto";function JG(){try{return"5.220.0"}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 VG,tl,aE=m(()=>{"use strict";Km();M();V();VG=JG(),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/${VG}`}}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}.${zG(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 YG}from"node:crypto";function QG(e){return e?e.replace(/\s+/g," ").trim().slice(0,200):""}function ZG(e,t,n){return`el_${YG("sha256").update(`${e}:${t}:${n}`).digest("hex").slice(0,6)}`}function eq(e){let t=e.replace(/\s+/g," ").trim(),n=4e3;return t.length<=n?t:t.slice(0,n)+"\u2026[truncated]"}function cE(e){return e.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function dE(e,t){let n=e.role??"",r=e.name??"";lE.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&t.push(e);for(let s of e.children??[])dE(s,t)}async function tq(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},uE).catch(()=>[])}async function nq(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},uE).catch(()=>[])}function rq(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=rq(e),i=s?s.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=tq(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=[],dE(u,y)):(o.push("observation skipped accessibility tree (returned null)"),b=!0,y=(await nq(e)).filter(C=>lE.has(C.role??"")));let S=new Map;for(let _ of p){let C=cE(_.name),N=S.get(C);(!N||N.bbox.w===0&&_.bbox.w>0)&&S.set(C,_)}let k=y.map(_=>({ax:_,dom:S.get(cE(_.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=ZG(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)),z_({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:QG(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=eq(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 lE,uE,pE=m(()=>{"use strict";Yc();lE=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);uE="a[href], button, input, select, textarea, [role], [tabindex], label"});async function fE(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 Gm(e,t){let n=Math.min(t,5);return(await Promise.all(Array.from({length:n},(o,s)=>fE(e,s)))).filter(o=>o!==null)}async function oq(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 qm(e,t,n){switch(t.kind){case"element_id":return sq(e,t,n);case"selector":return iq(e,t);case"semantic":return aq(e,t)}}async function sq(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 Gm(o,s);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:i}}async function iq(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 Gm(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${t.selector}]`},candidates:o}}async function aq(e,t){return t.role!==void 0?cq(e,t.text,t.role):lq(e,t.text,t)}async function cq(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 Gm(r,o);return{outcome:"ambiguous_target",query:{text:t,role:n},candidates:s}}async function lq(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 oq(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 fE(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 mE=m(()=>{"use strict"});async function Xm(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 gE=m(()=>{"use strict";dn()});var Jm={};zo(Jm,{PlaywrightProvider:()=>zm});function hE(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 zm,Vm=m(()=>{"use strict";aE();pE();mE();dn();gE();$m();zm=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 Xm(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 qm(r,t.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${hE(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 Xm(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 qm(r,t.target,o.knownElements);if(d.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${hE(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:()=>gq,browserProviderActive:()=>pq,closeBrowserProvider:()=>Qm,getBrowserProvider:()=>uq,getLastRoutingDecision:()=>mq,peekBrowserProvider:()=>fq});function yE(){Promise.resolve(Qm()).then(()=>{process.exit(130)})}function bE(){Promise.resolve(Qm()).then(()=>{process.exit(143)})}function wE(){Et=null}function dq(){rl||(process.on("SIGINT",yE),process.on("SIGTERM",bE),process.on("exit",wE),rl=!0)}function SE(){rl&&(process.removeListener("SIGINT",yE),process.removeListener("SIGTERM",bE),process.removeListener("exit",wE),rl=!1)}async function uq(e){return Et!==null?Et:(er!==null||(er=(async()=>{let t=Fm(e),n=e?.surface??(e?.env??{}).AGENT_SURFACE??w.AGENT_SURFACE,r=await q_({config:t,surface:n});Ym=r;let o;if(r.backend==="agent-browser"){let{AgentBrowserProvider:s}=await Promise.resolve().then(()=>(rE(),nE)),i=r.availability.connection;o=new s(t,i)}else{let{PlaywrightProvider:s}=await Promise.resolve().then(()=>(Vm(),Jm));o=new s(t)}return dq(),Et=o,er=null,o})()),er)}async function Qm(){if(Et===null)return;let e=Et;Et=null,er=null,SE(),await e.shutdown()}function pq(){return Et!==null}function fq(){return Et}function mq(){return Ym}function gq(){Et=null,er=null,Ym=null,SE()}var Et,er,rl,Ym,nr=m(()=>{"use strict";dn();X_();P();Et=null,er=null,rl=!1,Ym=null});async function kE(e,t){try{return await O_(e,t)}catch(n){return O("[web/scrape] extraction failed",{url:t,err:n}),{title:"",markdown:"",textLength:0,usedFallback:!0}}}async function kq(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(()=>(Vm(),Jm)),{loadBrowserConfig:i}=await Promise.resolve().then(()=>(dn(),Lm)),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 vE(e,t){let n=t.fetchFn??globalThis.fetch,r=t.renderFn??kq,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:Sq,signal:t.signal},o);c=u.status,a=u.url||e;let p=u.headers.get("content-type")??"";if(u.ok){if(wq.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(bq.test(p)&&!yq.test(p))return{title:"",markdown:f.trim(),finalUrl:a,usedRender:!1};if(i=f,s=await kE(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=Pm({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 kE(u.html,u.finalUrl);if(t.signal.aborted)throw t.signal.reason??new Error("aborted");if(s===null||p.textLength>=s.textLength){let f=Pm({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 yq,bq,wq,Sq,TE=m(()=>{"use strict";D_();Mm();Qn();V();yq=/(text\/html|application\/xhtml\+xml)/i,bq=/(application\/json|\/xml|\+xml|text\/|application\/(java|ecma)script|csv)/i,wq=/(image\/|audio\/|video\/|application\/pdf|application\/zip|application\/octet-stream|font\/)/i,Sq={"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 _q(e){let t=e.fetchFn??globalThis.fetch;return{name:"exa",async search(n,{limit:r,signal:o}){let s=await t(vq,{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),Tq),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 _E(e){return e.exaApiKey!==void 0&&e.exaApiKey.trim()!==""?_q({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 EE(e,t){if(t.length===0)return`# Search results for "${e}"
|
|
273
|
+
${rt(e,{headless:t,latched:n})}`,{cause:e})}var sE,KG,GG,oE,XG,Km=m(()=>{"use strict";sE=["Cannot find package","ERR_MODULE_NOT_FOUND","Executable doesn't exist"],KG="pnpm exec playwright install chromium",GG=4;XG="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 zG}from"node:crypto";function JG(){try{return"5.221.0"}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 VG,tl,aE=m(()=>{"use strict";Km();M();V();VG=JG(),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/${VG}`}}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}.${zG(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 YG}from"node:crypto";function QG(e){return e?e.replace(/\s+/g," ").trim().slice(0,200):""}function ZG(e,t,n){return`el_${YG("sha256").update(`${e}:${t}:${n}`).digest("hex").slice(0,6)}`}function eq(e){let t=e.replace(/\s+/g," ").trim(),n=4e3;return t.length<=n?t:t.slice(0,n)+"\u2026[truncated]"}function cE(e){return e.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function dE(e,t){let n=e.role??"",r=e.name??"";lE.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&t.push(e);for(let s of e.children??[])dE(s,t)}async function tq(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},uE).catch(()=>[])}async function nq(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},uE).catch(()=>[])}function rq(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=rq(e),i=s?s.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=tq(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=[],dE(u,y)):(o.push("observation skipped accessibility tree (returned null)"),b=!0,y=(await nq(e)).filter(C=>lE.has(C.role??"")));let S=new Map;for(let _ of p){let C=cE(_.name),N=S.get(C);(!N||N.bbox.w===0&&_.bbox.w>0)&&S.set(C,_)}let k=y.map(_=>({ax:_,dom:S.get(cE(_.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=ZG(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)),z_({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:QG(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=eq(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 lE,uE,pE=m(()=>{"use strict";Yc();lE=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);uE="a[href], button, input, select, textarea, [role], [tabindex], label"});async function fE(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 Gm(e,t){let n=Math.min(t,5);return(await Promise.all(Array.from({length:n},(o,s)=>fE(e,s)))).filter(o=>o!==null)}async function oq(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 qm(e,t,n){switch(t.kind){case"element_id":return sq(e,t,n);case"selector":return iq(e,t);case"semantic":return aq(e,t)}}async function sq(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 Gm(o,s);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:i}}async function iq(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 Gm(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${t.selector}]`},candidates:o}}async function aq(e,t){return t.role!==void 0?cq(e,t.text,t.role):lq(e,t.text,t)}async function cq(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 Gm(r,o);return{outcome:"ambiguous_target",query:{text:t,role:n},candidates:s}}async function lq(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 oq(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 fE(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 mE=m(()=>{"use strict"});async function Xm(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 gE=m(()=>{"use strict";dn()});var Jm={};zo(Jm,{PlaywrightProvider:()=>zm});function hE(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 zm,Vm=m(()=>{"use strict";aE();pE();mE();dn();gE();$m();zm=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 Xm(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 qm(r,t.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${hE(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 Xm(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 qm(r,t.target,o.knownElements);if(d.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${hE(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:()=>gq,browserProviderActive:()=>pq,closeBrowserProvider:()=>Qm,getBrowserProvider:()=>uq,getLastRoutingDecision:()=>mq,peekBrowserProvider:()=>fq});function yE(){Promise.resolve(Qm()).then(()=>{process.exit(130)})}function bE(){Promise.resolve(Qm()).then(()=>{process.exit(143)})}function wE(){Et=null}function dq(){rl||(process.on("SIGINT",yE),process.on("SIGTERM",bE),process.on("exit",wE),rl=!0)}function SE(){rl&&(process.removeListener("SIGINT",yE),process.removeListener("SIGTERM",bE),process.removeListener("exit",wE),rl=!1)}async function uq(e){return Et!==null?Et:(er!==null||(er=(async()=>{let t=Fm(e),n=e?.surface??(e?.env??{}).AGENT_SURFACE??w.AGENT_SURFACE,r=await q_({config:t,surface:n});Ym=r;let o;if(r.backend==="agent-browser"){let{AgentBrowserProvider:s}=await Promise.resolve().then(()=>(rE(),nE)),i=r.availability.connection;o=new s(t,i)}else{let{PlaywrightProvider:s}=await Promise.resolve().then(()=>(Vm(),Jm));o=new s(t)}return dq(),Et=o,er=null,o})()),er)}async function Qm(){if(Et===null)return;let e=Et;Et=null,er=null,SE(),await e.shutdown()}function pq(){return Et!==null}function fq(){return Et}function mq(){return Ym}function gq(){Et=null,er=null,Ym=null,SE()}var Et,er,rl,Ym,nr=m(()=>{"use strict";dn();X_();P();Et=null,er=null,rl=!1,Ym=null});async function kE(e,t){try{return await O_(e,t)}catch(n){return O("[web/scrape] extraction failed",{url:t,err:n}),{title:"",markdown:"",textLength:0,usedFallback:!0}}}async function kq(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(()=>(Vm(),Jm)),{loadBrowserConfig:i}=await Promise.resolve().then(()=>(dn(),Lm)),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 vE(e,t){let n=t.fetchFn??globalThis.fetch,r=t.renderFn??kq,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:Sq,signal:t.signal},o);c=u.status,a=u.url||e;let p=u.headers.get("content-type")??"";if(u.ok){if(wq.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(bq.test(p)&&!yq.test(p))return{title:"",markdown:f.trim(),finalUrl:a,usedRender:!1};if(i=f,s=await kE(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=Pm({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 kE(u.html,u.finalUrl);if(t.signal.aborted)throw t.signal.reason??new Error("aborted");if(s===null||p.textLength>=s.textLength){let f=Pm({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 yq,bq,wq,Sq,TE=m(()=>{"use strict";D_();Mm();Qn();V();yq=/(text\/html|application\/xhtml\+xml)/i,bq=/(application\/json|\/xml|\+xml|text\/|application\/(java|ecma)script|csv)/i,wq=/(image\/|audio\/|video\/|application\/pdf|application\/zip|application\/octet-stream|font\/)/i,Sq={"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 _q(e){let t=e.fetchFn??globalThis.fetch;return{name:"exa",async search(n,{limit:r,signal:o}){let s=await t(vq,{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),Tq),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 _E(e){return e.exaApiKey!==void 0&&e.exaApiKey.trim()!==""?_q({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 EE(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 vq,Tq,xE=m(()=>{"use strict";Je();vq="https://api.exa.ai/search",Tq=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";Km()});function Cq(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=Eq;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,xq)}let a=Aq;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,Rq)}return{mode:r,url:o,query:s,timeoutMs:i,maxBytes:a}}function Zm(e,t){return Buffer.byteLength(e,"utf8")<=t?{content:e,truncated:!1}:{content:kt(e,t),truncated:!0}}function Pq(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=Cq(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=Zm(f,i.maxBytes);return{content:g.content,...g.truncated?{truncated:!0}:{}}}if(i.mode==="markdown")try{let p=await vE(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=Zm(F_(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)&&!Wm(f)?` (the render fallback needs the optional Playwright browser \u2014 run \`${Ys()}\`)`:"";return{content:`web_scrape markdown error: ${f}${g}`,isError:!0}}let u=_E({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:Iq,timeoutMs:i.timeoutMs,signal:a.signal}),f=Zm(EE(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 Eq,xq,Aq,Rq,Iq,AE,RE=m(()=>{"use strict";TE();xE();Qn();vt();Mm();rr();Eq=3e4,xq=12e4,Aq=1e5,Rq=1e6,Iq=10;AE=Pq()});function Dq(e){return Mq.has(e)?"low":e==="DELETE"?"high":"medium"}function Fq(e){return Oq.has(e)}function Uq(e){let t={};return e.forEach((n,r)=>{let o=r.toLowerCase();Nq.has(o)||Lq.some(s=>o.startsWith(s))||(t[r]=n)}),t}function $q(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 Bq(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 PE(e){let{url:t,method:n,signal:r,domainCheck:o,recordEffect:s}=e,i=Math.min(e.maxResponseBytes??eg,tg),a={...e.headers},c=e.fetchFn??globalThis.fetch,l=e.lookupFn!==void 0?{lookupFn:e.lookupFn}:{},d=Dq(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}=$q(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=Fq(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}=Bq(E,T,i),F=Uq(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 ME(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 IE,CE,eg,tg,Mq,Oq,Lq,Nq,OE=m(()=>{"use strict";Qn();vt();IE=3e4,CE=12e4,eg=1e5,tg=1e6,Mq=new Set(["GET","HEAD","OPTIONS"]),Oq=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]);Lq=["set-cookie","x-"],Nq=new Set(["server","via","age","vary","authorization","www-authenticate"])});function jq(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=ME(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=IE;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,CE)}let l=eg;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,tg)}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 Hq(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(),Lm)),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=jq(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 PE(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 DE,FE=m(()=>{"use strict";OE();Qn();Bn();DE=Hq()});import{existsSync as NE,mkdirSync as Wq,readFileSync as Kq,renameSync as Gq,unlinkSync as qq,writeFileSync as Xq}from"node:fs";import{dirname as LE,join as zq}from"node:path";import{randomBytes as Jq}from"node:crypto";function or(e){let t=e??_p();if(!NE(t))return[];try{let n=Kq(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();Wq(LE(n),{recursive:!0});let r=zq(LE(n),`.schedules.json.${process.pid}.${Jq(4).toString("hex")}.tmp`),o=JSON.stringify(e,null,2);try{Xq(r,o,"utf-8"),Gq(r,n)}catch(s){try{NE(r)&&qq(r)}catch{}throw s}}function UE(e,t){let n=or(t),r=n.map(c=>c.id),o=Vq(e.name),s=Yq(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 $E(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 BE(e,t){return or(t).find(n=>n.id===e)}function Vq(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/-{2,}/g,"-").replace(/^-+|-+$/g,"")}function Yq(e,t){if(!t.includes(e))return e;let n=2;for(;t.includes(`${e}-${n}`);)n+=1;return`${e}-${n}`}function jE(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 HE=m(()=>{"use strict";M()});import{existsSync as Qq,readFileSync as Zq}from"node:fs";import{join as e2}from"node:path";async function Yr(e,t,n){let r,o;try{let s=e2(Ew("default"),"port");if(!Qq(s))return{synced:!1,detail:"daemon-not-detected (no port file)"};let i=Zq(s,"utf-8").trim(),a=t2(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 t2(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 ng,WE=m(()=>{"use strict";M();ng="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 n2}from"node:fs";import{readFile as r2}from"node:fs/promises";var KE,GE,qE,XE,zE=m(()=>{"use strict";HE();M();WE();KE=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=UE({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:ng}})}},GE=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})))}},qE=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(!n2(s))return{content:JSON.stringify([])};let i;try{let l=await r2(s);i=(l.length>1048576?l.subarray(l.length-1048576):l).toString("utf-8")}catch{return{content:JSON.stringify([])}}let a=i.split(`
|
package/dist/telegram.mjs
CHANGED
|
@@ -395,7 +395,7 @@ ${o}`,paths:[e,n]}:o!==null?s={content:o,paths:[n]}:r!==null?s={content:r,paths:
|
|
|
395
395
|
|
|
396
396
|
${e}`}var u4,py=h(()=>{"use strict";u4=new Set(["script","style","noscript","template","svg"])});function m4(t,e){return new Promise((n,r)=>{if(e?.aborted){r(e.reason??new Error("aborted"));return}let o=()=>{clearTimeout(s),r(e?.reason??new Error("aborted"))},s=setTimeout(()=>{e?.removeEventListener("abort",o),n()},t);e?.addEventListener("abort",o,{once:!0})})}function _R(t,e,n){let r=Math.min(e*2**t,n);return Math.round(Math.random()*r)}function g4(t,e){let n=t.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,e)}async function xR(t,e,n={},r={}){let o=r.retries??3,s=r.baseDelayMs??500,i=r.maxDelayMs??1e4,a=r.sleep??m4,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 t(e,n);if(!f4.has(u.status)||d===o)return u;let p=g4(u,i)??_R(d,s,i);O("[web/retryFetch] retrying",{url:e,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=_R(d,s,i);O("[web/retryFetch] retrying after error",{url:e,attempt:d,waitMs:p}),await a(p,c)}}throw l??new Error("retryFetch: exhausted without a result")}var f4,AR=h(()=>{"use strict";ne();f4=new Set([429,502,503,504])});import{BlockList as h4,isIP as my}from"node:net";import{lookup as y4}from"node:dns/promises";import{Agent as b4}from"undici";function IR(){let t=k.AFK_WEB_ALLOW_PRIVATE_HOSTS?.trim().toLowerCase();return t==="1"||t==="true"}function v4(t){return t.startsWith("[")&&t.endsWith("]")?t.slice(1,-1):t}function fy(t){let e=my(t);return e===0?!1:k4.check(t,e===4?"ipv4":"ipv6")}async function PR(t){return y4(t,{all:!0,verbatim:!0})}async function Nr(t,e={}){if(e.allowPrivateHosts??IR())return{allowed:!0};let n;try{n=new URL(t)}catch{return{allowed:!1,reason:`"${t}" 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=v4(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(my(r)!==0)return fy(r)?{allowed:!1,reason:o(r,r)}:{allowed:!0};let s=e.lookupFn??PR,i;try{i=await s(r)}catch{return{allowed:!0}}for(let a of i)if(fy(a.address))return{allowed:!1,reason:o(a.address,`${r} (resolved)`)};return{allowed:!0}}async function ia(t,e={}){let n=await Nr(t,e);if(!n.allowed)throw new Pe(n.reason)}async function Bn(t,e,n={},r={}){let o={...r.lookupFn!==void 0?{lookupFn:r.lookupFn}:{},...r.allowPrivateHosts!==void 0?{allowPrivateHosts:r.allowPrivateHosts}:{}},s=e;for(let i=0;i<=RR;i++){await ia(s,o);let a={...n,redirect:"manual",...t===globalThis.fetch&&!(r.allowPrivateHosts??IR())?{dispatcher:T4}:{}},c=await xR(t,s,a,r.retry??{});if(!E4.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 Pe(`too many redirects (>${RR}) starting from ${e}`)}var w4,S4,k4,Pe,T4,RR,E4,$r=h(()=>{"use strict";F();AR();w4=[["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]],S4=[["::",96],["64:ff9b::",96],["fc00::",7],["fe80::",10]],k4=(()=>{let t=new h4;for(let[e,n]of w4)t.addSubnet(e,n,"ipv4");for(let[e,n]of S4)t.addSubnet(e,n,"ipv6");return t})(),Pe=class extends Error{constructor(e){super(e),this.name="EgressBlockedError"}};T4=new b4({connect:{lookup(t,e,n){PR(t).then(r=>{let o=r.find(i=>fy(i.address));if(o!==void 0){n(new Pe(`refusing to connect to ${t} (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 ${t}`),"",0);return}n(null,s.address,my(s.address))},r=>n(r,"",0))}}});RR=20,E4=new Set([301,302,303,307,308])});var hy={};yo(hy,{enforceDomainPolicy:()=>It,loadBrowserConfig:()=>gy});import{readFileSync as _4}from"node:fs";import{join as x4}from"path";function A4(t){let n=t.replace(/[.+?()[\]{}/\\^$|]/g,"\\$&").replace(/\*/g,"[^.]*");return new RegExp(`^${n}$`,"i")}function CR(t,e){return A4(e).test(t)}function P4(t,e){if(t!==void 0){let n=t.trim().toLowerCase();if(n==="1"||n==="true"||n==="yes")return!0;if(n==="0"||n==="false"||n==="no")return!1}if(e!==void 0){if(R4.has(e))return!0;if(I4.has(e))return!1}return!1}function MR(t){return t===void 0||t.trim()===""?[]:t.split(",").map(e=>e.trim().toLowerCase()).filter(e=>e.length>0)}function C4(t){if(t===void 0||t==="")return"auto";if(t==="playwright"||t==="agent-browser"||t==="auto")return t;throw new Error(`AFK_BROWSER_BACKEND: must be "playwright", "agent-browser", or "auto", got: ${t}`)}function OR(t){let e=t===void 0||t.trim()===""?"default":t.trim();return Ym(e),e}function M4(t){if(t===void 0)return!1;let e=t.trim().toLowerCase();return e==="1"||e==="true"||e==="yes"}function O4(t){try{return _4(t,"utf8")}catch(e){if(e.code==="ENOENT")return;throw e}}function D4(t,e){let n={...t};if(typeof e.headless=="boolean"&&(n.headless=e.headless),Array.isArray(e.allowedDomains)&&(n.allowedDomains=e.allowedDomains.filter(r=>typeof r=="string").map(r=>r.trim().toLowerCase()).filter(r=>r.length>0)),Array.isArray(e.blockedDomains)&&(n.blockedDomains=e.blockedDomains.filter(r=>typeof r=="string").map(r=>r.trim().toLowerCase()).filter(r=>r.length>0)),typeof e.domSnapshots=="boolean"&&(n.domSnapshots=e.domSnapshots),e.backend==="playwright"||e.backend==="agent-browser"||e.backend==="auto")n.backend=e.backend;else if(e.backend!==void 0)throw new Error(`AFK_BROWSER_BACKEND: must be "playwright", "agent-browser", or "auto", got: ${String(e.backend)}`);return typeof e.defaultProfile=="string"&&(n.defaultProfile=OR(e.defaultProfile)),n}function gy(t){let e=t?.env??k,n=t?.readFileSync??O4,r=t?.surface??e.AGENT_SURFACE,o=P4(e.AFK_BROWSER_HEADLESS,r),s=MR(e.AFK_BROWSER_ALLOWED_DOMAINS),i=MR(e.AFK_BROWSER_BLOCKED_DOMAINS),a=M4(e.AFK_BROWSER_DOM_SNAPSHOTS),c=C4(e.AFK_BROWSER_BACKEND),l=OR(e.AFK_BROWSER_DEFAULT_PROFILE),d={headless:o,allowedDomains:s,blockedDomains:i,domSnapshots:a,backend:c,configPath:null,defaultProfile:l},u=e.AFK_BROWSER_CONFIG,p=u!==void 0&&u.trim()!==""?u.trim():x4(sn(),"browser.json"),f=n(p);if(f===void 0)return d;let m;try{m=JSON.parse(f)}catch(y){throw new Error(`Failed to parse browser config at ${p}: ${String(y)}`)}if(typeof m!="object"||m===null||Array.isArray(m))throw new Error(`Browser config at ${p} must be a JSON object`);let g=D4(d,m);return g.configPath=p,g}function It(t,e){let n;try{n=new URL(t).hostname.toLowerCase()}catch{return{allowed:!1,reason:`invalid URL: ${t}`}}for(let r of e.blockedDomains)if(CR(n,r))return{allowed:!1,reason:`blocked by AFK_BROWSER_BLOCKED_DOMAINS: ${r}`};return e.allowedDomains.length>0&&!e.allowedDomains.some(o=>CR(n,o))?{allowed:!1,reason:"not in AFK_BROWSER_ALLOWED_DOMAINS"}:{allowed:!0}}var R4,I4,jn=h(()=>{"use strict";F();N();R4=new Set(["daemon","subagent","telegram","afk"]),I4=new Set(["repl","interactive","cli"])});import{readFileSync as F4}from"node:fs";import{join as L4}from"node:path";import{homedir as N4}from"node:os";function U4(t){let e=t??$4,n;try{n=F4(e,"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 B4(t){try{return process.kill(t,0),!0}catch{return!1}}async function j4(t,e,n=2e3){try{let r=new AbortController,o=setTimeout(()=>r.abort(),n),s=await fetch(`${t}/health`,{method:"GET",headers:{Authorization:`Bearer ${e}`,Host:"127.0.0.1:8833"},signal:r.signal});return clearTimeout(o),s.ok}catch{return!1}}async function yy(t){let e=U4(t);return e===null?{available:!1,connection:null,reason:"connection file missing or invalid"}:B4(e.pid)?await j4(e.url,e.token)?{available:!0,connection:e,reason:null}:{available:!1,connection:e,reason:`health probe failed at ${e.url}`}:{available:!1,connection:e,reason:`stale connection file: PID ${e.pid} not alive`}}var $4,DR=h(()=>{"use strict";$4=L4(N4(),".config","agent-browser","connection.json")});async function FR(t){let{config:e,surface:n}=t;if(e.backend==="playwright")return{backend:"playwright",reason:"explicit config: backend=playwright",probeMs:0,availability:null};if(e.backend==="agent-browser"){let i=Date.now(),a=await yy(),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&&H4.has(n))return{backend:"playwright",reason:`auto: surface "${n}" excluded from Agent Browser`,probeMs:0,availability:null};if(e.headless)return{backend:"playwright",reason:"auto: headless mode requires Playwright",probeMs:0,availability:null};let r=Date.now(),o=await yy(),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 H4,LR=h(()=>{"use strict";DR();H4=new Set(["daemon","subagent"])});import{createHash as W4}from"crypto";function NR(t){return!!(t.role==="textbox"&&t.kind==="password"||t.label&&K4.test(t.label))}function $R(t){return W4("sha256").update(t,"utf8").digest("hex").slice(0,8)}function UR(t){let e=t.replace(/\s+/g," ").trim();return e.length<=80?e:e.slice(0,77)+"..."}var K4,jd=h(()=>{"use strict";K4=/password|secret|token|api[_-]?key|otp|2fa/i});import{randomBytes as G4}from"crypto";import{mkdir as q4,stat as X4,writeFile as z4}from"fs/promises";import{join as by}from"path";import{gzip as J4}from"zlib";import{promisify as V4}from"util";function Y4(t){return by(at(t),"browser")}function Q4(t){return by(Y4(t),"screenshots")}function Z4(){return new Date().toISOString().replace(/[:.]/g,"-")}function eY(){return G4(3).toString("hex")}async function Qo(t,e,n){if(e.length>BR)throw new Error(`writeScreenshotSidecar: buffer exceeds ${BR} byte cap (received ${e.length} bytes). Refusing to write oversized screenshot.`);let r=Q4(t);await q4(r,{recursive:!0});let o=`${Z4()}-${eY()}-${n}.png`,s=by(r,o);await z4(s,e);let{size:i}=await X4(s);return{path:s,bytes:i}}var ySe,BR,wy=h(()=>{"use strict";N();jd();ySe=V4(J4);BR=5*1024*1024});var Hd,jR=h(()=>{"use strict";ne();Hd=class{baseUrl;token;constructor(e){this.baseUrl=e.url,this.token=e.token}async call(e,n,r=3e4){let o={version:1,method:e,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 ${e} 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 ${e} failed: [${String(d)}] ${String(u)}`)}return c.result}finally{clearTimeout(i)}}async listTabs(){return this.call("tabs.list",null)}async openTab(e){return{tabId:(await this.call("tabs.open",{url:e},6e4)).id}}async closeTab(e){await this.call("page.eval",{id:e,script:"window.close()"}).catch(n=>{O("[browser/agent-browser] closeTab window.close() failed (tab leak expected)",{tabId:e,err:n})})}async read(e,n){return this.call("page.read",{id:e,mode:n?.mode??"main",...n?.query?{query:n.query}:{},...n?.budget?{budget:n.budget}:{}})}async inspect(e,n){return this.call("page.inspect",{id:e,mode:n?.mode??"interactive",...n?.query?{query:n.query}:{},...n?.limit?{limit:n.limit}:{}})}async click(e,n){await this.call("page.click",{id:e,elementId:n})}async fill(e,n,r){await this.call("page.fill",{id:e,elementId:n,value:r})}async press(e,n,r){await this.call("page.press",{id:e,key:n,...r?{elementId:r}:{}})}async select(e,n,r){await this.call("page.select",{id:e,elementId:n,value:r})}async waitFor(e,n,r){await this.call("page.wait",{id:e,condition:n,...r?.value?{value:r.value}:{},...r?.timeout?{timeout:r.timeout}:{}},(r?.timeout??3e4)+5e3)}async evalScript(e,n){return this.call("page.eval",{id:e,script:n})}async screenshot(e){return this.call("page.screenshot",{id:e})}}});function Sy(t){return{id:t.id,role:t.role,label:t.label,kind:t.kind,value:t.value,state:{disabled:t.disabled,...t.checked!==void 0?{checked:t.checked}:{},...t.selected!==void 0?{selected:t.selected}:{},...t.expanded!==void 0?{expanded:t.expanded}:{}},bbox:t.bbox,...t.selector?{selector:t.selector}:{}}}function HR(t,e){switch(e.kind){case"element_id":if(t.has(e.elementId))return e.elementId;throw new Error(`Element ${e.elementId} not found in current observation. Call browser_observe to refresh.`);case"selector":return null;case"semantic":return null}}async function ky(t,e,n,r,o,s){switch(n){case"click":await t.click(e,r);break;case"fill":if(o===void 0)throw new Error("fill requires a value");await t.fill(e,r,o);break;case"press":if(o===void 0)throw new Error("press requires a value (key combo)");await t.press(e,o,r);break;case"select":if(o===void 0)throw new Error("select requires a value");await t.select(e,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 t.evalScript(e,`document.querySelector('[data-element-id="${i}"]')?.scrollIntoView({behavior:'smooth',block:'center'})`);break}case"wait_for":await t.waitFor(e,"element",{value:r,timeout:s??1e4});break;default:throw new Error(`Unknown action: ${n}`)}}async function WR(t,e){if(e.target.kind!=="semantic")throw new Error("resolveSemanticAndAct called with non-semantic target");let{elements:n}=await t.client.inspect(t.tabId,{mode:"interactive",query:e.target.text,limit:10}),r=n;if(e.target.role){let c=e.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="${e.target.text}"`+(e.target.role?`, role="${e.target.role}"`:""));if(r.length>1)return{outcome:"ambiguous_target",query:{text:e.target.text,...e.target.role?{role:e.target.role}:{}},candidates:r.slice(0,5).map(Sy)};let s=r[0].id;await ky(t.client,t.tabId,e.action,s,e.value,e.timeoutMs);let i=await t.client.read(t.tabId,{mode:"main"}),a=It(i.url,t.config);return a.allowed?{elementId:s}:{outcome:"blocked_by_policy",url:i.url,reason:`action navigated to blocked domain: ${a.reason}`}}var KR=h(()=>{"use strict";jn()});var GR={};yo(GR,{AgentBrowserProvider:()=>vy});var vy,qR=h(()=>{"use strict";jn();wy();jR();KR();vy=class{name="agent-browser";config;client;sessions=new Map;constructor(e,n){this.config=e,this.client=new Hd(n)}async open(e){let n=It(e.url,this.config);if(!n.allowed)return{outcome:"blocked_by_policy",url:e.url,reason:n.reason};let r=this.sessions.get(e.sessionId);if(r)await this.client.evalScript(r.tabId,`window.location.href = ${JSON.stringify(e.url)}`),await this.client.waitFor(r.tabId,"load",{timeout:e.timeoutMs??3e4});else{let{tabId:i}=await this.client.openTab(e.url);await this.client.waitFor(i,"load",{timeout:e.timeoutMs??3e4}),r={tabId:i,observationCounter:0,knownElements:new Map,lastAction:null,lastActionAt:null,currentUrl:null,currentTitle:null},this.sessions.set(e.sessionId,r)}let o=await this.client.read(r.tabId,{mode:"main"}),s=It(o.url,this.config);return s.allowed?this.buildObservation(r,e.sessionId,e.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(e){let n=this.sessions.get(e.sessionId);if(!n)throw new Error(`No Agent Browser tab open for session ${e.sessionId}. Call browser_open first.`);return this.buildObservation(n,e.sessionId,e.screenshot,e.maxElements,"browser_observe")}async act(e){let n=this.sessions.get(e.sessionId);if(!n)throw new Error(`No Agent Browser tab open for session ${e.sessionId}. Call browser_open first.`);let r=HR(n.knownElements,e.target);if(r===null){if(e.target.kind==="semantic"){let i=await WR({client:this.client,config:this.config,tabId:n.tabId},e);return"outcome"in i?i:(n.lastAction=`browser_act:${e.action}`,n.lastActionAt=new Date().toISOString(),this.buildObservation(n,e.sessionId,e.screenshot,void 0,"browser_act"))}throw e.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(e.target)}`)}await ky(this.client,n.tabId,e.action,r,e.value,e.timeoutMs),n.lastAction=`browser_act:${e.action}`,n.lastActionAt=new Date().toISOString();let o=await this.client.read(n.tabId,{mode:"main"}),s=It(o.url,this.config);return s.allowed?this.buildObservation(n,e.sessionId,e.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(e){throw new Error("AgentBrowserProvider does not support render(). Use PlaywrightProvider for one-shot content fetches.")}async screenshot(e){let n=this.sessions.get(e.sessionId);if(!n)throw new Error(`No Agent Browser tab open for session ${e.sessionId}. Call browser_open first.`);if(e.target!==void 0||e.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 Qo(e.sessionId,o,"browser_screenshot")).path,bytes:o.length,width:s,height:i,dataBase64:r.data,mediaType:"image/png"}}async extract(e){throw new Error("AgentBrowserProvider does not support extract() yet.")}async close(e){let n=this.sessions.get(e.sessionId);if(n){try{await this.client.closeTab(n.tabId)}catch{}this.sessions.delete(e.sessionId)}}describe(e){let n=this.sessions.get(e);return n?{active:!0,url:n.currentUrl,title:n.currentTitle,lastAction:n.lastAction,lastActionAt:n.lastActionAt,openTabs:1}:null}async shutdown(){let e=Array.from(this.sessions.entries()).map(async([,n])=>{try{await this.client.closeTab(n.tabId)}catch{}});await Promise.all(e),this.sessions.clear()}async buildObservation(e,n,r,o,s="browser_open"){let[i,a]=await Promise.all([this.client.read(e.tabId,{mode:"main",budget:4e3}),this.client.inspect(e.tabId,{mode:"interactive",limit:o??80})]),c=a.elements.map(Sy),l=o??80,d=c.slice(0,l);e.observationCounter+=1,e.knownElements=new Map(d.map(g=>[g.id,g])),e.currentUrl=i.url,e.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 g=await this.client.screenshot(e.tabId),y=Buffer.from(g.data,"base64");p=(await Qo(n,y,s)).path}catch{u.push("screenshot capture failed")}let f=`obs_${e.observationCounter.toString(36)}`,m={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:m,warnings:u,screenshotPath:p,capturedAt:new Date().toISOString()}}}});import{existsSync as tY,readFileSync as nY}from"node:fs";import{createRequire as rY}from"node:module";import{dirname as oY,join as sY}from"node:path";function JR(t){if(typeof t=="string")return t;let e=[],n=t;for(let r=0;r<aY&&n instanceof Error;r++)e.push(n.message),n=n.cause;return e.length>0?e.join(" | "):String(t)}function Je(t){let e=JR(t);return zR.some(n=>e.includes(n))}function cY(){try{let e=rY(import.meta.url).resolve("playwright/package.json"),n=JSON.parse(nY(e,"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=sY(oY(e),o);return tY(s)?`node ${/\s/.test(s)?`"${s}"`:s} install chromium`:void 0}catch{return}}function aa(){return XR??=cY()??iY,XR}function Ty(t){return t.includes("install chromium")}function gt(t,e){let n=JR(t),r=e?.latched===!0?` ${lY}`:"";if(n.includes("Executable doesn't exist")){let o="";return e?.headless===!0?o=" This launch was headless, which needs the `chromium_headless_shell-*` build.":e?.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: ${aa()}.${o}${r}`}return`browser tools require the optional \`playwright\` peer dependency. Install via: pnpm add playwright (then ${aa()}). Or pick a different tool.${r}`}function Wd(t,e,n=!1){if(!Je(t))return t;let r=t instanceof Error?t.message:String(t);return new Error(`${r}
|
|
397
397
|
|
|
398
|
-
${gt(t,{headless:e,latched:n})}`,{cause:t})}var zR,iY,aY,XR,lY,Ey=h(()=>{"use strict";zR=["Cannot find package","ERR_MODULE_NOT_FOUND","Executable doesn't exist"],iY="pnpm exec playwright install chromium",aY=4;lY="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 Ur from"node:fs";import Kd from"node:path";import{randomBytes as dY}from"node:crypto";function uY(){try{return"5.220.0"}catch{}try{let t=Kd.resolve(import.meta.dirname,"../../../package.json"),e=Ur.readFileSync(t,"utf8"),n=JSON.parse(e);return typeof n.version=="string"?n.version:"unknown"}catch{return"unknown"}}var pY,Gd,VR=h(()=>{"use strict";Ey();N();ne();pY=uY(),Gd=class{config;browser;sessions=new Map;launchPromise;launchFailure;shutdownComplete=!1;constructor(e){this.config=e}clearLaunchFailure(){this.launchFailure=void 0}latchLaunchFailure(e){this.launchFailure={error:e}}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 e;try{({chromium:e}=await import("playwright"))}catch(n){let r=Wd(n,this.config.headless,!0);throw this.latchLaunchFailure(r),this.launchPromise=void 0,r}try{let n=await e.launch({headless:this.config.headless});return this.browser=n,this.clearLaunchFailure(),n}catch(n){let r=Wd(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(e){let n=this.sessions.get(e);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(e,i),s}async ensurePage(e){let n=this.sessions.get(e);if(n!==void 0&&n.page!==void 0)return n.page;await this.ensureContext(e);let r=this.sessions.get(e);if(r===void 0)throw new Error(`[BrowserLauncher] session entry disappeared for sessionId=${e}`);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(e){return this.sessions.get(e)?.page}async renderHtml(e,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(e,{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(e){return this.sessions.get(e)?.consoleErrors??0}getLastHttpStatus(e){return this.sessions.get(e)?.lastHttpStatus??null}hasOpenDialog(e){return this.sessions.get(e)?.openDialog!==void 0}async dismissDialog(e,n=!0){let r=this.sessions.get(e);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(e){this.clearLaunchFailure();let n=this.sessions.get(e);n!==void 0&&(this.sessions.delete(e),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 e=[...this.sessions.keys()];if(await Promise.all(e.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/${pY}`}}loadStorageState(e){let n=Qm(e);try{if(!Ur.existsSync(n))return;let r=JSON.parse(Ur.readFileSync(n,"utf8"));return O("[browser/vault] restored session",{profile:e,file:n}),r}catch(r){O("[browser/vault] ignoring unreadable vault",{profile:e,file:n,err:r});return}}async saveStorageState(e,n){try{let r=Qm(e);if(!Ur.existsSync(r))return;let o=await n.storageState(),s=Kd.join(Kd.dirname(r),`.${Kd.basename(r)}.${process.pid}.${dY(4).toString("hex")}.tmp`);Ur.writeFileSync(s,JSON.stringify(o),{mode:384}),Ur.chmodSync(s,384),Ur.renameSync(s,r),O("[browser/vault] saved session",{profile:e,file:r})}catch(r){O("[browser/vault] save failed",{profile:e,err:r})}}}});import{createHash as fY}from"node:crypto";function mY(t){return t?t.replace(/\s+/g," ").trim().slice(0,200):""}function gY(t,e,n){return`el_${fY("sha256").update(`${t}:${e}:${n}`).digest("hex").slice(0,6)}`}function hY(t){let e=t.replace(/\s+/g," ").trim(),n=4e3;return e.length<=n?e:e.slice(0,n)+"\u2026[truncated]"}function YR(t){return t.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function ZR(t,e){let n=t.role??"",r=t.name??"";QR.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&e.push(t);for(let s of t.children??[])ZR(s,e)}async function yY(t){return t.evaluate(e=>{let n=Array.from(document.querySelectorAll(e)),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},eI).catch(()=>[])}async function bY(t){return t.evaluate(e=>{let n={button:"button",a:"link",input:"textbox",textarea:"textbox",select:"combobox"},r=Array.from(document.querySelectorAll(e)),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 g=s.type;g==="checkbox"?l="checkbox":g==="radio"?l="radio":g==="button"||g==="submit"||g==="reset"?l="button":g==="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,m={role:l,name:c,disabled:p};u!==void 0&&(m.value=u),f!==void 0&&(m.checked=f),o.push(m)}return o},eI).catch(()=>[])}function wY(t){let n=t.accessibility;return n!==null&&typeof n=="object"?n:null}async function qd(t,e){let n=e.maxElements??80,r=e.includeHidden??!1,o=[],s=wY(t),i=s?s.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=yY(t),c=t.evaluate(()=>document.body?.innerText??"").catch(()=>""),l=Promise.resolve(t.url()),d=t.title().catch(()=>""),[u,p,f,m,g]=await Promise.all([i,a,c,l,d]),y,b=!1;u!==null?(y=[],ZR(u,y)):(o.push("observation skipped accessibility tree (returned null)"),b=!0,y=(await bY(t)).filter(C=>QR.has(C.role??"")));let w=new Map;for(let E of p){let C=YR(E.name),H=w.get(C);(!H||H.bbox.w===0&&E.bbox.w>0)&&w.set(C,E)}let v=y.map(E=>({ax:E,dom:w.get(YR(E.name??""))})),x=r?v:v.filter(E=>E.dom?E.dom.bbox.w>0||E.dom.bbox.h>0:!0);x.sort((E,C)=>{let H=E.dom?.bbox.y??0,M=C.dom?.bbox.y??0;if(H!==M)return H-M;let $=E.dom?.bbox.x??0,U=C.dom?.bbox.x??0;return $-U}),x.length>200&&o.push("page has 200+ interactive elements; consider scoping");let _=x.slice(0,n).map((E,C)=>{let H=E.ax.role??"generic",M=E.ax.name??"",$=gY(H,M,C),U=E.dom?.bbox??{x:0,y:0,w:0,h:0},B=E.dom?.type??null,j=null;E.ax.value!==void 0&&E.ax.value!==null&&(j=String(E.ax.value)),E.ax.checked!==void 0&&(j=String(E.ax.checked)),NR({role:H,kind:B})&&(j="[redacted]");let K={disabled:E.ax.disabled??!1};E.ax.checked!==void 0&&(K.checked=E.ax.checked===!0||E.ax.checked==="mixed"),E.ax.selected!==void 0&&(K.selected=E.ax.selected),E.ax.expanded!==void 0&&(K.expanded=E.ax.expanded);let Y;E.dom?.testId?Y=`[data-testid="${E.dom.testId}"]`:E.dom?.id&&(Y=`#${E.dom.id}`);let Ft={id:$,role:H,label:mY(M),kind:B,value:j,state:K,bbox:U};return Y!==void 0&&(Ft.selector=Y),Ft}),I="idle";try{let E=await t.evaluate(()=>document.readyState);E==="loading"?I="loading":E==="interactive"?I="navigating":I="idle"}catch{I="navigating"}I!=="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 P=hY(f),T=`obs_${e.observationCounter.toString(36)}`,R=new Date().toISOString();return{observationId:T,url:m,title:g,textSummary:P,interactive:_,status:{httpStatus:e.httpStatus??null,loadingState:I,hasDialog:e.hasDialog??!1,consoleErrors:e.consoleErrors??0},warnings:o,screenshotPath:e.screenshotPath??null,capturedAt:R}}var QR,eI,tI=h(()=>{"use strict";jd();QR=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);eI="a[href], button, input, select, textarea, [role], [tabindex], label"});async function nI(t,e){try{let n=await t.nth(e).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}:${e}`,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 _y(t,e){let n=Math.min(e,5);return(await Promise.all(Array.from({length:n},(o,s)=>nI(t,s)))).filter(o=>o!==null)}async function SY(t){let e=new Set,n=[];for(let{loc:r,count:o}of t)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}e.has(i)||(e.add(i),n.push({key:i,locator:r,index:s}))}return n}async function xy(t,e,n){switch(e.kind){case"element_id":return kY(t,e,n);case"selector":return vY(t,e);case"semantic":return TY(t,e)}}async function kY(t,e,n){let r=n.get(e.elementId);if(r===void 0)return{outcome:"not_found",query:e};if(r.selector!==void 0){let c=t.locator(r.selector);if(await c.count()===1)return{outcome:"resolved",locator:c}}let o=t.getByRole(r.role,{name:r.label,exact:!0}),s=await o.count();if(s===0)return{outcome:"not_found",query:e};if(s===1)return{outcome:"resolved",locator:o};let i=await _y(o,s);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:i}}async function vY(t,e){let n=t.locator(e.selector),r=await n.count();if(r===0)return{outcome:"not_found",query:e};if(r===1)return{outcome:"resolved",locator:n};let o=await _y(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${e.selector}]`},candidates:o}}async function TY(t,e){return e.role!==void 0?EY(t,e.text,e.role):_Y(t,e.text,e)}async function EY(t,e,n){let r=t.getByRole(n,{name:e}),o=await r.count();if(o===0)return{outcome:"not_found",query:{kind:"semantic",text:e,role:n}};if(o===1)return{outcome:"resolved",locator:r};let s=await _y(r,o);return{outcome:"ambiguous_target",query:{text:e,role:n},candidates:s}}async function _Y(t,e,n){let r=t.getByRole("button",{name:e}),o=t.getByRole("link",{name:e}),s=t.getByLabel(e,{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 SY(d);if(u.length===0)return{outcome:"not_found",query:n};if(u.length===1){let g=u[0];return g===void 0?{outcome:"not_found",query:n}:{outcome:"resolved",locator:g.locator.nth(g.index)}}let p=u.slice(0,5),f=[];for(let g=0;g<p.length;g++){let y=p[g];if(y===void 0)continue;let b=await nI(y.locator,y.index);if(b!==null){let w=`${b.role}:${b.label}:${g}`,v=0;for(let x=0;x<w.length;x++)v=v*31+w.charCodeAt(x)>>>0;f.push({...b,id:`el_${v.toString(16).padStart(6,"0").slice(0,6)}`})}}return{outcome:"ambiguous_target",query:{text:e},candidates:f}}var rI=h(()=>{"use strict"});async function Ay(t,e,n,r){let o=t.url();if(o===n)return null;let s=It(o,e);if(s.allowed)return null;try{await t.goBack()}catch{await r()}return{outcome:"blocked_by_policy",url:o,reason:s.reason}}var oI=h(()=>{"use strict";jn()});var Iy={};yo(Iy,{PlaywrightProvider:()=>Ry});function sI(t){switch(t.kind){case"semantic":return t.role!==void 0?`semantic('${t.text}', role='${t.role}')`:`semantic('${t.text}')`;case"element_id":return`element_id(${t.elementId})`;case"selector":return`selector(${t.selector})`}}var Ry,Py=h(()=>{"use strict";VR();tI();rI();jn();oI();wy();Ry=class{name="playwright";config;launcher;sessions=new Map;constructor(e){this.config=e,this.launcher=new Gd(e)}async open(e){let n=It(e.url,this.config);if(!n.allowed)return{outcome:"blocked_by_policy",url:e.url,reason:n.reason};let{sessionId:r}=e,o=await this.launcher.ensurePage(r),s=this.ensureSessionState(r),i=null,a=null;try{await o.goto(e.url,{timeout:e.timeoutMs??3e4,waitUntil:e.waitFor??"load"})}catch(u){a=u}let c=o.url();if(!(a!==null&&(c===""||c==="about:blank"))){let u=await Ay(o,this.config,e.url,()=>this.close({sessionId:r}));if(u!==null)return u}(e.screenshot===!0||a!==null)&&(i=await this.captureScreenshot(o,r,"browser_open")),s.observationCounter+=1;let d=await qd(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(e){let{sessionId:n}=e,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;e.screenshot===!0&&(s=await this.captureScreenshot(r,n,"browser_observe")),o.observationCounter+=1;let i=await qd(r,{observationCounter:o.observationCounter,screenshotPath:s,consoleErrors:this.launcher.getConsoleErrorCount(n),httpStatus:this.launcher.getLastHttpStatus(n),hasDialog:this.launcher.hasOpenDialog(n),includeHidden:e.includeHidden,maxElements:e.maxElements});return this.updateSessionFromObservation(o,i.interactive,i.url,i.title,"browser_observe"),i}async act(e){let{sessionId:n}=e,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=e.timeoutMs??3e4,a=await xy(r,e.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${sI(e.target)}`);if(a.outcome==="ambiguous_target")return a;let{locator:c}=a,l=null,d=async()=>{switch(e.action){case"click":await c.click({timeout:i});break;case"fill":await c.fill(e.value??"");break;case"press":await c.press(e.value??"");break;case"select":await c.selectOption(e.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(g){if(g instanceof Error&&/navigation|net::ERR/i.test(g.message))try{await d()}catch(y){l=y}else l=g}let u=await Ay(r,this.config,s,()=>this.close({sessionId:n}));if(u!==null)return u;let p=null;(e.screenshot===!0||l!==null)&&(p=await this.captureScreenshot(r,n,"browser_act")),o.observationCounter+=1;let f=await qd(r,{observationCounter:o.observationCounter,screenshotPath:p,consoleErrors:this.launcher.getConsoleErrorCount(n),httpStatus:this.launcher.getLastHttpStatus(n),hasDialog:this.launcher.hasOpenDialog(n)}),m=`browser_act:${e.action}`;if(this.updateSessionFromObservation(o,f.interactive,f.url,f.title,m),l!==null)throw l;return f}async render(e){return this.launcher.renderHtml(e.url,{timeoutMs:e.timeoutMs??3e4,waitUntil:e.waitFor??"load",signal:e.signal,requestGuard:e.requestGuard})}async screenshot(e){let{sessionId:n}=e,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(e.target!==void 0){let d=await xy(r,e.target,o.knownElements);if(d.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${sI(e.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:e.fullPage??!1});let{path:i,bytes:a}=await Qo(n,s,"browser_screenshot"),c=0,l=0;if(e.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(e){throw new Error("browser_extract not implemented in Phase 1")}async close(e){await this.launcher.closeSession(e.sessionId),this.sessions.delete(e.sessionId)}describe(e){let n=this.sessions.get(e);if(n===void 0)return null;let r=this.launcher.getPage(e);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(e){let n=this.sessions.get(e);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(e,r),r}updateSessionFromObservation(e,n,r,o,s){e.knownElements=new Map(n.map(i=>[i.id,i])),e.currentUrl=r,e.currentTitle=o,e.lastAction=s,e.lastActionAt=new Date().toISOString()}async captureScreenshot(e,n,r){try{let o=await e.screenshot({fullPage:!1}),{path:s}=await Qo(n,o,r);return s}catch{return null}}}});var jr={};yo(jr,{__resetBrowserRegistryForTests:()=>CY,browserProviderActive:()=>RY,closeBrowserProvider:()=>My,getBrowserProvider:()=>AY,getLastRoutingDecision:()=>PY,peekBrowserProvider:()=>IY});function iI(){Promise.resolve(My()).then(()=>{process.exit(130)})}function aI(){Promise.resolve(My()).then(()=>{process.exit(143)})}function cI(){Jt=null}function xY(){Xd||(process.on("SIGINT",iI),process.on("SIGTERM",aI),process.on("exit",cI),Xd=!0)}function lI(){Xd&&(process.removeListener("SIGINT",iI),process.removeListener("SIGTERM",aI),process.removeListener("exit",cI),Xd=!1)}async function AY(t){return Jt!==null?Jt:(Br!==null||(Br=(async()=>{let e=gy(t),n=t?.surface??(t?.env??{}).AGENT_SURFACE??k.AGENT_SURFACE,r=await FR({config:e,surface:n});Cy=r;let o;if(r.backend==="agent-browser"){let{AgentBrowserProvider:s}=await Promise.resolve().then(()=>(qR(),GR)),i=r.availability.connection;o=new s(e,i)}else{let{PlaywrightProvider:s}=await Promise.resolve().then(()=>(Py(),Iy));o=new s(e)}return xY(),Jt=o,Br=null,o})()),Br)}async function My(){if(Jt===null)return;let t=Jt;Jt=null,Br=null,lI(),await t.shutdown()}function RY(){return Jt!==null}function IY(){return Jt}function PY(){return Cy}function CY(){Jt=null,Br=null,Cy=null,lI()}var Jt,Br,Xd,Cy,Hr=h(()=>{"use strict";jn();LR();F();Jt=null,Br=null,Xd=!1,Cy=null});async function dI(t,e){try{return await vR(t,e)}catch(n){return O("[web/scrape] extraction failed",{url:e,err:n}),{title:"",markdown:"",textLength:0,usedFallback:!0}}}async function NY(t,e){let{getBrowserProvider:n}=await Promise.resolve().then(()=>(Hr(),jr)),r=await n();try{return await r.render({url:t,timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:e.requestGuard})}catch(o){if(r.name==="agent-browser"){let{PlaywrightProvider:s}=await Promise.resolve().then(()=>(Py(),Iy)),{loadBrowserConfig:i}=await Promise.resolve().then(()=>(jn(),hy)),a=i(),c=new s(a);try{return await c.render({url:t,timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:e.requestGuard})}finally{await c.shutdown()}}throw o}}async function uI(t,e){let n=e.fetchFn??globalThis.fetch,r=e.renderFn??NY,o=e.lookupFn!==void 0?{lookupFn:e.lookupFn}:{},s=null,i="",a=t,c=null,l=null;try{let u=await Bn(n,t,{headers:LY,signal:e.signal},o);c=u.status,a=u.url||t;let p=u.headers.get("content-type")??"";if(u.ok){if(FY.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(DY.test(p)&&!OY.test(p))return{title:"",markdown:f.trim(),finalUrl:a,usedRender:!1};if(i=f,s=await dI(f,a),e.signal.aborted)throw e.signal.reason??new Error("aborted")}}catch(u){if(e.signal.aborted||u instanceof Pe||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=uy({html:i,extractedTextLength:s.textLength});return{title:s.title,markdown:s.markdown,finalUrl:a,usedRender:!1,...u!==void 0?{advisory:u}:{}}}try{await ia(t,o);let u=await r(t,{timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:f=>ia(f,o)});u.finalUrl!==t&&/^https?:\/\//i.test(u.finalUrl)&&await ia(u.finalUrl,o);let p=await dI(u.html,u.finalUrl);if(e.signal.aborted)throw e.signal.reason??new Error("aborted");if(s===null||p.textLength>=s.textLength){let f=uy({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(e.signal.aborted||u instanceof Pe)throw u;if(s===null){let p=u instanceof Error?u.message:String(u),f=l instanceof Error?l.message:`HTTP ${c??"error"}`,m=new Error(`web_scrape could not retrieve ${t}: fetch failed (${f}) and render failed (${p}).`);throw m.cause=u,m}}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 ${t} (HTTP ${c??"error"}).`)}var OY,DY,FY,LY,pI=h(()=>{"use strict";TR();py();$r();ne();OY=/(text\/html|application\/xhtml\+xml)/i,DY=/(application\/json|\/xml|\+xml|text\/|application\/(java|ecma)script|csv)/i,FY=/(image\/|audio\/|video\/|application\/pdf|application\/zip|application\/octet-stream|font\/)/i,LY={"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 BY(t){let e=t.fetchFn??globalThis.fetch;return{name:"exa",async search(n,{limit:r,signal:o}){let s=await e($Y,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json","x-api-key":t.apiKey,"User-Agent":"agent-afk/web_scrape"},body:JSON.stringify({query:n,type:"auto",numResults:Math.min(Math.max(r,1),UY),contents:{highlights:{numSentences:3,highlightsPerUrl:1}}}),signal:o});if(!s.ok){let c="";try{let d=await s.text(),u=Z(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 fI(t){return t.exaApiKey!==void 0&&t.exaApiKey.trim()!==""?BY({apiKey:t.exaApiKey,fetchFn:t.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 mI(t,e){if(e.length===0)return`# Search results for "${t}"
|
|
398
|
+
${gt(t,{headless:e,latched:n})}`,{cause:t})}var zR,iY,aY,XR,lY,Ey=h(()=>{"use strict";zR=["Cannot find package","ERR_MODULE_NOT_FOUND","Executable doesn't exist"],iY="pnpm exec playwright install chromium",aY=4;lY="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 Ur from"node:fs";import Kd from"node:path";import{randomBytes as dY}from"node:crypto";function uY(){try{return"5.221.0"}catch{}try{let t=Kd.resolve(import.meta.dirname,"../../../package.json"),e=Ur.readFileSync(t,"utf8"),n=JSON.parse(e);return typeof n.version=="string"?n.version:"unknown"}catch{return"unknown"}}var pY,Gd,VR=h(()=>{"use strict";Ey();N();ne();pY=uY(),Gd=class{config;browser;sessions=new Map;launchPromise;launchFailure;shutdownComplete=!1;constructor(e){this.config=e}clearLaunchFailure(){this.launchFailure=void 0}latchLaunchFailure(e){this.launchFailure={error:e}}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 e;try{({chromium:e}=await import("playwright"))}catch(n){let r=Wd(n,this.config.headless,!0);throw this.latchLaunchFailure(r),this.launchPromise=void 0,r}try{let n=await e.launch({headless:this.config.headless});return this.browser=n,this.clearLaunchFailure(),n}catch(n){let r=Wd(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(e){let n=this.sessions.get(e);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(e,i),s}async ensurePage(e){let n=this.sessions.get(e);if(n!==void 0&&n.page!==void 0)return n.page;await this.ensureContext(e);let r=this.sessions.get(e);if(r===void 0)throw new Error(`[BrowserLauncher] session entry disappeared for sessionId=${e}`);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(e){return this.sessions.get(e)?.page}async renderHtml(e,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(e,{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(e){return this.sessions.get(e)?.consoleErrors??0}getLastHttpStatus(e){return this.sessions.get(e)?.lastHttpStatus??null}hasOpenDialog(e){return this.sessions.get(e)?.openDialog!==void 0}async dismissDialog(e,n=!0){let r=this.sessions.get(e);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(e){this.clearLaunchFailure();let n=this.sessions.get(e);n!==void 0&&(this.sessions.delete(e),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 e=[...this.sessions.keys()];if(await Promise.all(e.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/${pY}`}}loadStorageState(e){let n=Qm(e);try{if(!Ur.existsSync(n))return;let r=JSON.parse(Ur.readFileSync(n,"utf8"));return O("[browser/vault] restored session",{profile:e,file:n}),r}catch(r){O("[browser/vault] ignoring unreadable vault",{profile:e,file:n,err:r});return}}async saveStorageState(e,n){try{let r=Qm(e);if(!Ur.existsSync(r))return;let o=await n.storageState(),s=Kd.join(Kd.dirname(r),`.${Kd.basename(r)}.${process.pid}.${dY(4).toString("hex")}.tmp`);Ur.writeFileSync(s,JSON.stringify(o),{mode:384}),Ur.chmodSync(s,384),Ur.renameSync(s,r),O("[browser/vault] saved session",{profile:e,file:r})}catch(r){O("[browser/vault] save failed",{profile:e,err:r})}}}});import{createHash as fY}from"node:crypto";function mY(t){return t?t.replace(/\s+/g," ").trim().slice(0,200):""}function gY(t,e,n){return`el_${fY("sha256").update(`${t}:${e}:${n}`).digest("hex").slice(0,6)}`}function hY(t){let e=t.replace(/\s+/g," ").trim(),n=4e3;return e.length<=n?e:e.slice(0,n)+"\u2026[truncated]"}function YR(t){return t.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function ZR(t,e){let n=t.role??"",r=t.name??"";QR.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&e.push(t);for(let s of t.children??[])ZR(s,e)}async function yY(t){return t.evaluate(e=>{let n=Array.from(document.querySelectorAll(e)),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},eI).catch(()=>[])}async function bY(t){return t.evaluate(e=>{let n={button:"button",a:"link",input:"textbox",textarea:"textbox",select:"combobox"},r=Array.from(document.querySelectorAll(e)),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 g=s.type;g==="checkbox"?l="checkbox":g==="radio"?l="radio":g==="button"||g==="submit"||g==="reset"?l="button":g==="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,m={role:l,name:c,disabled:p};u!==void 0&&(m.value=u),f!==void 0&&(m.checked=f),o.push(m)}return o},eI).catch(()=>[])}function wY(t){let n=t.accessibility;return n!==null&&typeof n=="object"?n:null}async function qd(t,e){let n=e.maxElements??80,r=e.includeHidden??!1,o=[],s=wY(t),i=s?s.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=yY(t),c=t.evaluate(()=>document.body?.innerText??"").catch(()=>""),l=Promise.resolve(t.url()),d=t.title().catch(()=>""),[u,p,f,m,g]=await Promise.all([i,a,c,l,d]),y,b=!1;u!==null?(y=[],ZR(u,y)):(o.push("observation skipped accessibility tree (returned null)"),b=!0,y=(await bY(t)).filter(C=>QR.has(C.role??"")));let w=new Map;for(let E of p){let C=YR(E.name),H=w.get(C);(!H||H.bbox.w===0&&E.bbox.w>0)&&w.set(C,E)}let v=y.map(E=>({ax:E,dom:w.get(YR(E.name??""))})),x=r?v:v.filter(E=>E.dom?E.dom.bbox.w>0||E.dom.bbox.h>0:!0);x.sort((E,C)=>{let H=E.dom?.bbox.y??0,M=C.dom?.bbox.y??0;if(H!==M)return H-M;let $=E.dom?.bbox.x??0,U=C.dom?.bbox.x??0;return $-U}),x.length>200&&o.push("page has 200+ interactive elements; consider scoping");let _=x.slice(0,n).map((E,C)=>{let H=E.ax.role??"generic",M=E.ax.name??"",$=gY(H,M,C),U=E.dom?.bbox??{x:0,y:0,w:0,h:0},B=E.dom?.type??null,j=null;E.ax.value!==void 0&&E.ax.value!==null&&(j=String(E.ax.value)),E.ax.checked!==void 0&&(j=String(E.ax.checked)),NR({role:H,kind:B})&&(j="[redacted]");let K={disabled:E.ax.disabled??!1};E.ax.checked!==void 0&&(K.checked=E.ax.checked===!0||E.ax.checked==="mixed"),E.ax.selected!==void 0&&(K.selected=E.ax.selected),E.ax.expanded!==void 0&&(K.expanded=E.ax.expanded);let Y;E.dom?.testId?Y=`[data-testid="${E.dom.testId}"]`:E.dom?.id&&(Y=`#${E.dom.id}`);let Ft={id:$,role:H,label:mY(M),kind:B,value:j,state:K,bbox:U};return Y!==void 0&&(Ft.selector=Y),Ft}),I="idle";try{let E=await t.evaluate(()=>document.readyState);E==="loading"?I="loading":E==="interactive"?I="navigating":I="idle"}catch{I="navigating"}I!=="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 P=hY(f),T=`obs_${e.observationCounter.toString(36)}`,R=new Date().toISOString();return{observationId:T,url:m,title:g,textSummary:P,interactive:_,status:{httpStatus:e.httpStatus??null,loadingState:I,hasDialog:e.hasDialog??!1,consoleErrors:e.consoleErrors??0},warnings:o,screenshotPath:e.screenshotPath??null,capturedAt:R}}var QR,eI,tI=h(()=>{"use strict";jd();QR=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);eI="a[href], button, input, select, textarea, [role], [tabindex], label"});async function nI(t,e){try{let n=await t.nth(e).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}:${e}`,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 _y(t,e){let n=Math.min(e,5);return(await Promise.all(Array.from({length:n},(o,s)=>nI(t,s)))).filter(o=>o!==null)}async function SY(t){let e=new Set,n=[];for(let{loc:r,count:o}of t)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}e.has(i)||(e.add(i),n.push({key:i,locator:r,index:s}))}return n}async function xy(t,e,n){switch(e.kind){case"element_id":return kY(t,e,n);case"selector":return vY(t,e);case"semantic":return TY(t,e)}}async function kY(t,e,n){let r=n.get(e.elementId);if(r===void 0)return{outcome:"not_found",query:e};if(r.selector!==void 0){let c=t.locator(r.selector);if(await c.count()===1)return{outcome:"resolved",locator:c}}let o=t.getByRole(r.role,{name:r.label,exact:!0}),s=await o.count();if(s===0)return{outcome:"not_found",query:e};if(s===1)return{outcome:"resolved",locator:o};let i=await _y(o,s);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:i}}async function vY(t,e){let n=t.locator(e.selector),r=await n.count();if(r===0)return{outcome:"not_found",query:e};if(r===1)return{outcome:"resolved",locator:n};let o=await _y(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${e.selector}]`},candidates:o}}async function TY(t,e){return e.role!==void 0?EY(t,e.text,e.role):_Y(t,e.text,e)}async function EY(t,e,n){let r=t.getByRole(n,{name:e}),o=await r.count();if(o===0)return{outcome:"not_found",query:{kind:"semantic",text:e,role:n}};if(o===1)return{outcome:"resolved",locator:r};let s=await _y(r,o);return{outcome:"ambiguous_target",query:{text:e,role:n},candidates:s}}async function _Y(t,e,n){let r=t.getByRole("button",{name:e}),o=t.getByRole("link",{name:e}),s=t.getByLabel(e,{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 SY(d);if(u.length===0)return{outcome:"not_found",query:n};if(u.length===1){let g=u[0];return g===void 0?{outcome:"not_found",query:n}:{outcome:"resolved",locator:g.locator.nth(g.index)}}let p=u.slice(0,5),f=[];for(let g=0;g<p.length;g++){let y=p[g];if(y===void 0)continue;let b=await nI(y.locator,y.index);if(b!==null){let w=`${b.role}:${b.label}:${g}`,v=0;for(let x=0;x<w.length;x++)v=v*31+w.charCodeAt(x)>>>0;f.push({...b,id:`el_${v.toString(16).padStart(6,"0").slice(0,6)}`})}}return{outcome:"ambiguous_target",query:{text:e},candidates:f}}var rI=h(()=>{"use strict"});async function Ay(t,e,n,r){let o=t.url();if(o===n)return null;let s=It(o,e);if(s.allowed)return null;try{await t.goBack()}catch{await r()}return{outcome:"blocked_by_policy",url:o,reason:s.reason}}var oI=h(()=>{"use strict";jn()});var Iy={};yo(Iy,{PlaywrightProvider:()=>Ry});function sI(t){switch(t.kind){case"semantic":return t.role!==void 0?`semantic('${t.text}', role='${t.role}')`:`semantic('${t.text}')`;case"element_id":return`element_id(${t.elementId})`;case"selector":return`selector(${t.selector})`}}var Ry,Py=h(()=>{"use strict";VR();tI();rI();jn();oI();wy();Ry=class{name="playwright";config;launcher;sessions=new Map;constructor(e){this.config=e,this.launcher=new Gd(e)}async open(e){let n=It(e.url,this.config);if(!n.allowed)return{outcome:"blocked_by_policy",url:e.url,reason:n.reason};let{sessionId:r}=e,o=await this.launcher.ensurePage(r),s=this.ensureSessionState(r),i=null,a=null;try{await o.goto(e.url,{timeout:e.timeoutMs??3e4,waitUntil:e.waitFor??"load"})}catch(u){a=u}let c=o.url();if(!(a!==null&&(c===""||c==="about:blank"))){let u=await Ay(o,this.config,e.url,()=>this.close({sessionId:r}));if(u!==null)return u}(e.screenshot===!0||a!==null)&&(i=await this.captureScreenshot(o,r,"browser_open")),s.observationCounter+=1;let d=await qd(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(e){let{sessionId:n}=e,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;e.screenshot===!0&&(s=await this.captureScreenshot(r,n,"browser_observe")),o.observationCounter+=1;let i=await qd(r,{observationCounter:o.observationCounter,screenshotPath:s,consoleErrors:this.launcher.getConsoleErrorCount(n),httpStatus:this.launcher.getLastHttpStatus(n),hasDialog:this.launcher.hasOpenDialog(n),includeHidden:e.includeHidden,maxElements:e.maxElements});return this.updateSessionFromObservation(o,i.interactive,i.url,i.title,"browser_observe"),i}async act(e){let{sessionId:n}=e,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=e.timeoutMs??3e4,a=await xy(r,e.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${sI(e.target)}`);if(a.outcome==="ambiguous_target")return a;let{locator:c}=a,l=null,d=async()=>{switch(e.action){case"click":await c.click({timeout:i});break;case"fill":await c.fill(e.value??"");break;case"press":await c.press(e.value??"");break;case"select":await c.selectOption(e.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(g){if(g instanceof Error&&/navigation|net::ERR/i.test(g.message))try{await d()}catch(y){l=y}else l=g}let u=await Ay(r,this.config,s,()=>this.close({sessionId:n}));if(u!==null)return u;let p=null;(e.screenshot===!0||l!==null)&&(p=await this.captureScreenshot(r,n,"browser_act")),o.observationCounter+=1;let f=await qd(r,{observationCounter:o.observationCounter,screenshotPath:p,consoleErrors:this.launcher.getConsoleErrorCount(n),httpStatus:this.launcher.getLastHttpStatus(n),hasDialog:this.launcher.hasOpenDialog(n)}),m=`browser_act:${e.action}`;if(this.updateSessionFromObservation(o,f.interactive,f.url,f.title,m),l!==null)throw l;return f}async render(e){return this.launcher.renderHtml(e.url,{timeoutMs:e.timeoutMs??3e4,waitUntil:e.waitFor??"load",signal:e.signal,requestGuard:e.requestGuard})}async screenshot(e){let{sessionId:n}=e,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(e.target!==void 0){let d=await xy(r,e.target,o.knownElements);if(d.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${sI(e.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:e.fullPage??!1});let{path:i,bytes:a}=await Qo(n,s,"browser_screenshot"),c=0,l=0;if(e.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(e){throw new Error("browser_extract not implemented in Phase 1")}async close(e){await this.launcher.closeSession(e.sessionId),this.sessions.delete(e.sessionId)}describe(e){let n=this.sessions.get(e);if(n===void 0)return null;let r=this.launcher.getPage(e);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(e){let n=this.sessions.get(e);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(e,r),r}updateSessionFromObservation(e,n,r,o,s){e.knownElements=new Map(n.map(i=>[i.id,i])),e.currentUrl=r,e.currentTitle=o,e.lastAction=s,e.lastActionAt=new Date().toISOString()}async captureScreenshot(e,n,r){try{let o=await e.screenshot({fullPage:!1}),{path:s}=await Qo(n,o,r);return s}catch{return null}}}});var jr={};yo(jr,{__resetBrowserRegistryForTests:()=>CY,browserProviderActive:()=>RY,closeBrowserProvider:()=>My,getBrowserProvider:()=>AY,getLastRoutingDecision:()=>PY,peekBrowserProvider:()=>IY});function iI(){Promise.resolve(My()).then(()=>{process.exit(130)})}function aI(){Promise.resolve(My()).then(()=>{process.exit(143)})}function cI(){Jt=null}function xY(){Xd||(process.on("SIGINT",iI),process.on("SIGTERM",aI),process.on("exit",cI),Xd=!0)}function lI(){Xd&&(process.removeListener("SIGINT",iI),process.removeListener("SIGTERM",aI),process.removeListener("exit",cI),Xd=!1)}async function AY(t){return Jt!==null?Jt:(Br!==null||(Br=(async()=>{let e=gy(t),n=t?.surface??(t?.env??{}).AGENT_SURFACE??k.AGENT_SURFACE,r=await FR({config:e,surface:n});Cy=r;let o;if(r.backend==="agent-browser"){let{AgentBrowserProvider:s}=await Promise.resolve().then(()=>(qR(),GR)),i=r.availability.connection;o=new s(e,i)}else{let{PlaywrightProvider:s}=await Promise.resolve().then(()=>(Py(),Iy));o=new s(e)}return xY(),Jt=o,Br=null,o})()),Br)}async function My(){if(Jt===null)return;let t=Jt;Jt=null,Br=null,lI(),await t.shutdown()}function RY(){return Jt!==null}function IY(){return Jt}function PY(){return Cy}function CY(){Jt=null,Br=null,Cy=null,lI()}var Jt,Br,Xd,Cy,Hr=h(()=>{"use strict";jn();LR();F();Jt=null,Br=null,Xd=!1,Cy=null});async function dI(t,e){try{return await vR(t,e)}catch(n){return O("[web/scrape] extraction failed",{url:e,err:n}),{title:"",markdown:"",textLength:0,usedFallback:!0}}}async function NY(t,e){let{getBrowserProvider:n}=await Promise.resolve().then(()=>(Hr(),jr)),r=await n();try{return await r.render({url:t,timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:e.requestGuard})}catch(o){if(r.name==="agent-browser"){let{PlaywrightProvider:s}=await Promise.resolve().then(()=>(Py(),Iy)),{loadBrowserConfig:i}=await Promise.resolve().then(()=>(jn(),hy)),a=i(),c=new s(a);try{return await c.render({url:t,timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:e.requestGuard})}finally{await c.shutdown()}}throw o}}async function uI(t,e){let n=e.fetchFn??globalThis.fetch,r=e.renderFn??NY,o=e.lookupFn!==void 0?{lookupFn:e.lookupFn}:{},s=null,i="",a=t,c=null,l=null;try{let u=await Bn(n,t,{headers:LY,signal:e.signal},o);c=u.status,a=u.url||t;let p=u.headers.get("content-type")??"";if(u.ok){if(FY.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(DY.test(p)&&!OY.test(p))return{title:"",markdown:f.trim(),finalUrl:a,usedRender:!1};if(i=f,s=await dI(f,a),e.signal.aborted)throw e.signal.reason??new Error("aborted")}}catch(u){if(e.signal.aborted||u instanceof Pe||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=uy({html:i,extractedTextLength:s.textLength});return{title:s.title,markdown:s.markdown,finalUrl:a,usedRender:!1,...u!==void 0?{advisory:u}:{}}}try{await ia(t,o);let u=await r(t,{timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:f=>ia(f,o)});u.finalUrl!==t&&/^https?:\/\//i.test(u.finalUrl)&&await ia(u.finalUrl,o);let p=await dI(u.html,u.finalUrl);if(e.signal.aborted)throw e.signal.reason??new Error("aborted");if(s===null||p.textLength>=s.textLength){let f=uy({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(e.signal.aborted||u instanceof Pe)throw u;if(s===null){let p=u instanceof Error?u.message:String(u),f=l instanceof Error?l.message:`HTTP ${c??"error"}`,m=new Error(`web_scrape could not retrieve ${t}: fetch failed (${f}) and render failed (${p}).`);throw m.cause=u,m}}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 ${t} (HTTP ${c??"error"}).`)}var OY,DY,FY,LY,pI=h(()=>{"use strict";TR();py();$r();ne();OY=/(text\/html|application\/xhtml\+xml)/i,DY=/(application\/json|\/xml|\+xml|text\/|application\/(java|ecma)script|csv)/i,FY=/(image\/|audio\/|video\/|application\/pdf|application\/zip|application\/octet-stream|font\/)/i,LY={"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 BY(t){let e=t.fetchFn??globalThis.fetch;return{name:"exa",async search(n,{limit:r,signal:o}){let s=await e($Y,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json","x-api-key":t.apiKey,"User-Agent":"agent-afk/web_scrape"},body:JSON.stringify({query:n,type:"auto",numResults:Math.min(Math.max(r,1),UY),contents:{highlights:{numSentences:3,highlightsPerUrl:1}}}),signal:o});if(!s.ok){let c="";try{let d=await s.text(),u=Z(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 fI(t){return t.exaApiKey!==void 0&&t.exaApiKey.trim()!==""?BY({apiKey:t.exaApiKey,fetchFn:t.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 mI(t,e){if(e.length===0)return`# Search results for "${t}"
|
|
399
399
|
|
|
400
400
|
(no results)`;let n=[`# Search results for "${t}"`,""];return e.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(`
|
|
401
401
|
`).trimEnd()}var $Y,UY,gI=h(()=>{"use strict";tt();$Y="https://api.exa.ai/search",UY=10});function zd(t){if(t instanceof Error&&t.name==="TimeoutError")return"timeout";let e=t instanceof Error?t.message:String(t);return/Timeout\s+\d+\s*ms exceeded/i.test(e)?"timeout":void 0}var Wr=h(()=>{"use strict";Ey()});function qY(t){if(!t||typeof t!="object")return{error:"Invalid input: expected an object"};let e=t,n=e.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 e.query!="string"||e.query.length===0)return{error:'Invalid input: search mode requires a non-empty "query" string'};s=e.query}else{if(typeof e.url!="string"||e.url.length===0)return{error:`Invalid input: ${r} mode requires a non-empty "url" string`};let c;try{c=new URL(e.url)}catch{return{error:`Invalid input: "${e.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=jY;if(e.timeout_ms!==void 0){if(typeof e.timeout_ms!="number"||!Number.isFinite(e.timeout_ms)||e.timeout_ms<=0)return{error:"Invalid input: timeout_ms must be a positive finite number"};i=Math.min(e.timeout_ms,HY)}let a=WY;if(e.max_bytes!==void 0){if(typeof e.max_bytes!="number"||!Number.isFinite(e.max_bytes)||e.max_bytes<=0)return{error:"Invalid input: max_bytes must be a positive finite number"};a=Math.min(e.max_bytes,KY)}return{mode:r,url:o,query:s,timeoutMs:i,maxBytes:a}}function Oy(t,e){return Buffer.byteLength(t,"utf8")<=e?{content:t,truncated:!1}:{content:At(t,e),truncated:!0}}function XY(t={}){let e=t.fetchFn??globalThis.fetch,n=t.env??process.env,r=t.lookupFn!==void 0?{lookupFn:t.lookupFn}:{};return async(o,s)=>{if(typeof e!="function")return{content:"web_scrape unavailable: global fetch() is not present in this runtime (agent-afk requires Node 20+).",isError:!0};let i=qY(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 Nr(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 g={method:"GET",headers:{"User-Agent":"agent-afk/web_scrape",Accept:"*/*"},signal:a.signal};p=await Bn(e,i.url,g,r)}catch(g){return a.signal.aborted?{content:`web_scrape aborted: ${d()}`,isError:!0}:g instanceof Pe?{content:`web_scrape blocked: ${g.message}`,isError:!0}:{content:`web_scrape network error: ${g instanceof Error?g.message:String(g)}`,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(g){return{content:`web_scrape read error: ${g instanceof Error?g.message:String(g)}`,isError:!0}}let m=Oy(f,i.maxBytes);return{content:m.content,...m.truncated?{truncated:!0}:{}}}if(i.mode==="markdown")try{let p=await uI(i.url,{fetchFn:e,renderFn:t.renderFn,timeoutMs:i.timeoutMs,signal:a.signal,...t.lookupFn!==void 0?{lookupFn:t.lookupFn}:{}});if(p.markdown.trim().length===0)return{content:`web_scrape extracted no readable content from ${i.url}.`,isError:!0};let f=Oy(ER(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 Pe)return{content:`web_scrape blocked: ${p.message}`,isError:!0};let f=p instanceof Error?p.message:String(p),m=Je(p)&&!Ty(f)?` (the render fallback needs the optional Playwright browser \u2014 run \`${aa()}\`)`:"";return{content:`web_scrape markdown error: ${f}${m}`,isError:!0}}let u=fI({exaApiKey:n.EXA_API_KEY,fetchFn:e});if("error"in u)return{content:u.error,isError:!0};try{let p=await u.search(i.query,{limit:GY,timeoutMs:i.timeoutMs,signal:a.signal}),f=Oy(mI(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 jY,HY,WY,KY,GY,hI,yI=h(()=>{"use strict";pI();gI();$r();Kt();py();Wr();jY=3e4,HY=12e4,WY=1e5,KY=1e6,GY=10;hI=XY()});function VY(t){return zY.has(t)?"low":t==="DELETE"?"high":"medium"}function YY(t){return JY.has(t)}function e5(t){let e={};return t.forEach((n,r)=>{let o=r.toLowerCase();ZY.has(o)||QY.some(s=>o.startsWith(s))||(e[r]=n)}),e}function t5(t,e){if(t==null)return{serialized:void 0,inferredContentType:void 0};let n=Object.keys(e).some(o=>o.toLowerCase()==="content-type");return typeof t=="string"?{serialized:t,inferredContentType:n?void 0:"text/plain"}:{serialized:JSON.stringify(t),inferredContentType:n?void 0:"application/json"}}function n5(t,e,n){let r=Buffer.byteLength(t,"utf8"),o=t,s=!1;if(r>n&&(o=At(t,n),s=!0),!s&&/application\/json/i.test(e))try{return{body:JSON.parse(o),truncated:!1}}catch{}return{body:o,truncated:s}}async function SI(t){let{url:e,method:n,signal:r,domainCheck:o,recordEffect:s}=t,i=Math.min(t.maxResponseBytes??Dy,Fy),a={...t.headers},c=t.fetchFn??globalThis.fetch,l=t.lookupFn!==void 0?{lookupFn:t.lookupFn}:{},d=VY(n);if(o!==void 0){let T=o(e);if(!T.allowed)throw Object.assign(new Error(`web_request blocked by domain policy: ${T.reason}`),{name:"DomainPolicyError"})}let u=await Nr(e,l);if(!u.allowed)throw new Pe(u.reason);let{serialized:p,inferredContentType:f}=t5(t.body,a);f!==void 0&&(a["content-type"]=f);let m={method:n,headers:Object.keys(a).length>0?a:void 0,body:p,signal:r},y=YY(n)?{retries:2,baseDelayMs:300,maxDelayMs:5e3}:{retries:0},b=Date.now(),w;try{w=await Bn(c,e,m,{...l,retry:y})}catch(T){throw T instanceof Pe,T}let v=Date.now()-b,x=w.headers.get("content-type")??"",A;try{let T=w.body?.getReader();if(!T)A="";else{let R=[],E=0,C=i*2;for(;;){let{done:H,value:M}=await T.read();if(H||!M)break;if(R.push(M),E+=M.byteLength,E>=C){await T.cancel();break}}A=new TextDecoder().decode(Buffer.concat(R,E))}}catch{A=""}let{body:_,truncated:I}=n5(A,x,i),P=e5(w.headers);return s!==void 0&&Promise.resolve(s({url:e,method:n,status:w.status,risk:d,timing_ms:v})).catch(()=>{}),{status:w.status,headers:P,body:_,truncated:I,timing_ms:v,risk:d}}function kI(t){if(typeof t!="string"||t.trim().length===0)return{error:"method must be a non-empty string (GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS)"};let e=t.trim().toUpperCase(),n=["GET","POST","PUT","PATCH","DELETE","HEAD","OPTIONS"];return n.includes(e)?e:{error:`method "${t}" is not supported \u2014 must be one of: ${n.join(", ")}`}}var bI,wI,Dy,Fy,zY,JY,QY,ZY,vI=h(()=>{"use strict";$r();Kt();bI=3e4,wI=12e4,Dy=1e5,Fy=1e6,zY=new Set(["GET","HEAD","OPTIONS"]),JY=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]);QY=["set-cookie","x-"],ZY=new Set(["server","via","age","vary","authorization","www-authenticate"])});function r5(t){if(!t||typeof t!="object")return{error:"Invalid input: expected an object"};let e=t;if(typeof e.url!="string"||e.url.length===0)return{error:'Invalid input: "url" must be a non-empty string'};let n;try{n=new URL(e.url)}catch{return{error:`Invalid input: "${e.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=kI(e.method);if(typeof o=="object"&&"error"in o)return{error:`Invalid input: ${o.error}`};let s=o,i;if(e.body!==void 0&&e.body!==null){if(typeof e.body!="string"&&typeof e.body!="object")return{error:'Invalid input: "body" must be a string, object, or array'};i=e.body}let a={};if(e.headers!==void 0){if(typeof e.headers!="object"||e.headers===null||Array.isArray(e.headers))return{error:'Invalid input: "headers" must be a string-keyed object'};let u=e.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=bI;if(e.timeout_ms!==void 0){if(typeof e.timeout_ms!="number"||!Number.isFinite(e.timeout_ms)||e.timeout_ms<=0)return{error:'Invalid input: "timeout_ms" must be a positive finite number'};c=Math.min(e.timeout_ms,wI)}let l=Dy;if(e.max_response_bytes!==void 0){if(typeof e.max_response_bytes!="number"||!Number.isFinite(e.max_response_bytes)||e.max_response_bytes<=0)return{error:'Invalid input: "max_response_bytes" must be a positive finite number'};l=Math.min(e.max_response_bytes,Fy)}let d;if(e.credential!==void 0){if(typeof e.credential!="string"||e.credential.length===0)return{error:'Invalid input: "credential" must be a non-empty string (an env var name)'};d=e.credential}return{url:r,method:s,body:i,headers:a,timeoutMs:c,maxResponseBytes:l,credential:d}}function o5(t={}){let e=t.fetchFn??globalThis.fetch,n=t.env??process.env;async function r(){if(t.domainCheck!==void 0)return t.domainCheck;try{let{loadBrowserConfig:o,enforceDomainPolicy:s}=await Promise.resolve().then(()=>(jn(),hy)),i=o();return a=>s(a,i)}catch{return}}return async(o,s)=>{if(typeof e!="function")return{content:"web_request unavailable: global fetch() is not present (agent-afk requires Node 20+).",isError:!0};let i=r5(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(m=>m.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:e,lookupFn:t.lookupFn,domainCheck:p,recordEffect:t.recordEffect},m;try{m=await SI(f)}catch(w){if(c.signal.aborted)return{content:`web_request aborted: ${u()}`,isError:!0};if(w instanceof Pe)return{content:`web_request blocked: ${w.message}`,isError:!0};let v=w instanceof Error&&w.name==="DomainPolicyError"?"blocked":"network error",x=w instanceof Error?w.message:String(w);return{content:`web_request ${v}: ${x}`,isError:!0}}if(c.signal.aborted)return{content:`web_request aborted: ${u()}`,isError:!0};let g=m.body;if(typeof g=="string")g=Ge(g);else if(typeof g=="object"&&g!==null){let w=Ge(JSON.stringify(g));try{g=JSON.parse(w)}catch{g=w}}let y={status:m.status,headers:m.headers,body:g,timing_ms:m.timing_ms,...m.truncated?{truncated:!0}:{}};return{content:JSON.stringify(y,null,2),...m.truncated?{truncated:!0}:{}}}finally{d!==void 0&&clearTimeout(d),s.removeEventListener("abort",l)}}}var TI,EI=h(()=>{"use strict";vI();$r();xn();TI=o5()});import{existsSync as xI,mkdirSync as s5,readFileSync as i5,renameSync as a5,unlinkSync as c5,writeFileSync as l5}from"node:fs";import{dirname as _I,join as d5}from"node:path";import{randomBytes as u5}from"node:crypto";function Kr(t){let e=t??Xm();if(!xI(e))return[];try{let n=i5(e,"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 ${e}: ${r}`),[]}}function ca(t,e){let n=e??Xm();s5(_I(n),{recursive:!0});let r=d5(_I(n),`.schedules.json.${process.pid}.${u5(4).toString("hex")}.tmp`),o=JSON.stringify(t,null,2);try{l5(r,o,"utf-8"),a5(r,n)}catch(s){try{xI(r)&&c5(r)}catch{}throw s}}function AI(t,e){let n=Kr(e),r=n.map(c=>c.id),o=p5(t.name),s=f5(o,r),i=new Date().toISOString(),a={...t,notifyOn:t.notifyOn??"failure",id:s,createdAt:i,updatedAt:i};return n.push(a),ca(n,e),a}function RI(t,e){let n=Kr(e),r=n.length,o=n.filter(s=>s.id!==t);return o.length===r?!1:(ca(o,e),!0)}function II(t,e){return Kr(e).find(n=>n.id===t)}function p5(t){return t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/-{2,}/g,"-").replace(/^-+|-+$/g,"")}function f5(t,e){if(!e.includes(t))return t;let n=2;for(;e.includes(`${t}-${n}`);)n+=1;return`${t}-${n}`}function PI(t){return{taskId:t.id,command:t.command,trigger:t.trigger??"cron",...t.executor!==void 0?{executor:t.executor}:{},...t.cron!==void 0?{cronExpression:t.cron}:{},...t.notifyOn!==void 0?{notifyOn:t.notifyOn}:{},...t.notifyChat!==void 0?{notifyChat:t.notifyChat}:{}}}var CI=h(()=>{"use strict";N()});import{existsSync as m5,readFileSync as g5}from"node:fs";import{join as h5}from"node:path";async function Zo(t,e,n){let r,o;try{let s=h5(eT("default"),"port");if(!m5(s))return{synced:!1,detail:"daemon-not-detected (no port file)"};let i=g5(s,"utf-8").trim(),a=y5(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}${e}`,{method:t,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"}:t==="POST"&&i.status===409?{synced:!0,detail:"already-registered"}:t==="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 y5(t){let e=parseInt(t,10);if(String(e)===t&&!Number.isNaN(e))return e<1||e>65535?null:{host:"localhost",port:e};let n=t.lastIndexOf(":");if(n<1)return null;let r=t.slice(0,n),o=t.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 Ly,MI=h(()=>{"use strict";N();Ly="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 b5}from"node:fs";import{readFile as w5}from"node:fs/promises";var OI,DI,FI,LI,NI=h(()=>{"use strict";CI();N();MI();OI=async(t,e)=>{if(!t||typeof t!="object")return{content:"Invalid input: expected object",isError:!0};let n=t;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=AI({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 Zo("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 Zo("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:Ly}})}},DI=async(t,e)=>{let n=Kr();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})))}},FI=async(t,e)=>{if(!t||typeof t!="object")return{content:"Invalid input: expected object",isError:!0};let n=t;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=Xc();if(!b5(s))return{content:JSON.stringify([])};let i;try{let l=await w5(s);i=(l.length>1048576?l.subarray(l.length-1048576):l).toString("utf-8")}catch{return{content:JSON.stringify([])}}let a=i.split(`
|
|
@@ -1571,7 +1571,7 @@ Each turn, run this loop:
|
|
|
1571
1571
|
|
|
1572
1572
|
1. **Observe.** Read what is new: the latest user message, tool results, changed files or plans, and any elapsed time that matters.
|
|
1573
1573
|
2. **Model.** Hold current world-state, objective-state, and assumption-state. If any of them is too stale for the next action, refresh it first.
|
|
1574
|
-
3. **Choose.** Take the
|
|
1574
|
+
3. **Choose.** Take the action or concurrent action set that best advances the objective, removes a load-bearing uncertainty, or reaches a terminal state. Prefer the smallest sufficient scope, not the fewest simultaneous actions.
|
|
1575
1575
|
4. **Act.** Emit the action. Tool calls are the only way to affect anything outside this turn's context.
|
|
1576
1576
|
5. **Update.** Compare result to prediction. If reality diverged, update the model before acting again.
|
|
1577
1577
|
|
|
@@ -1622,7 +1622,7 @@ Default to delegation for any task that would otherwise:
|
|
|
1622
1622
|
|
|
1623
1623
|
Stay inline for: single-file edits, localized fixes visible in <2 reads, conversational answers, explicit user requests for a direct tool call, tasks where dispatch overhead exceeds the work, and strictly sequential chains where each step genuinely requires the previous step's output as prompt input.
|
|
1624
1624
|
|
|
1625
|
-
|
|
1625
|
+
Prompt children with bounded freedom. Be precise about the objective, known state, constraints, authority, evidence required, and definition of done; stay deliberately non-prescriptive about the path to get there. Give enough context to prevent unnecessary rediscovery, but not a parent-authored solution. Include relevant paths or artifacts as starting points, not an exhaustive search boundary unless scope must actually be restricted. Pass known findings, failed approaches, and uncertainties when they materially constrain the task, distinguishing observed facts from prior conclusions. Prior conclusions are context, not truth; let the child contradict them when evidence warrants. State what the child may change, what it must not change, and when to stop. Ask for compressed findings proportional to the task. Delegate bounded investigation and execution; keep cross-agent synthesis, tradeoff resolution, and final judgment in the coordinator.
|
|
1626
1626
|
|
|
1627
1627
|
Scheduling posture: parallel is the default, serial is the exception. Before starting multi-step work, decompose it: list sub-tasks, mark genuine dependencies, dispatch all non-dependent work in a single wave. Do not serialize investigation, research, verification, or test-running that could proceed concurrently. The governing metric is wall-clock time to correct completion, not total agent compute. This posture applies to the root coordinator; child subagents should focus on their scoped task rather than recursively fanning out unless their own task independently decomposes.
|
|
1628
1628
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-afk",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.221.0",
|
|
4
4
|
"description": "Open-source coding-agent harness you can actually change — own the loop (prompts, gates, routing, skills, terminal states), use any model, run long tasks while you're away.",
|
|
5
5
|
"main": "dist/index.mjs",
|
|
6
6
|
"types": "dist/index.d.ts",
|