agent-afk 5.169.2 → 5.169.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/providers/anthropic-direct/provider-grants.d.ts +0 -1
- package/dist/agent/providers/openai-compatible/index.d.ts +1 -1
- package/dist/agent/tools/dispatcher.d.ts +3 -3
- package/dist/agent/tools/grant-manager.d.ts +1 -0
- package/dist/cli/render/divider.d.ts +1 -1
- package/dist/cli/render/index.d.ts +2 -0
- package/dist/cli.mjs +545 -541
- package/dist/index.mjs +11 -7
- package/dist/telegram.mjs +11 -7
- package/package.json +1 -1
- /package/dist/cli/{context-bar.d.ts → render/context-bar.d.ts} +0 -0
- /package/dist/cli/{context-sparkline.d.ts → render/context-sparkline.d.ts} +0 -0
package/dist/telegram.mjs
CHANGED
|
@@ -150,8 +150,8 @@ ${e.join(`
|
|
|
150
150
|
|
|
151
151
|
Tap one to switch. /new starts a fresh session.`}function Bv(){return`\u{1F5C2}\uFE0F No saved sessions yet.
|
|
152
152
|
|
|
153
|
-
Send a message to start one, or /new for a fresh session.`}function jv(t){return`\u21A9\uFE0F Switched to ${t.name?`<b>${Ve(t.name)}</b>`:"that session"}. Your next message continues it.`}function Hv(){return"\u{1F195} Started a fresh session. Your previous one is saved \u2014 /sessions to switch back."}function Zf(){return"\u23F3 Finish or wait for the current turn before switching sessions."}function Wv(){return z("That session could no longer be found. /sessions to see the current list.")}function Kv(){return"\u2705 You're already on that session."}var Ae=g(()=>{"use strict"});var Je,Ee,Uc,Y,nt,mn,qr,re=g(()=>{"use strict";Je=class extends Error{constructor(e){super(e),this.name="AbortError"}},Ee=class extends Error{constructor(n,r){super(n);this.timeoutMs=r;this.name="TimeoutError"}timeoutMs},Uc=class extends Ee{constructor(e,n){super(e,n),this.name="IdleWatchdogError"}},Y=class extends Error{constructor(n,r,o,s){super(n);this.event=r;this.reason=o;this.name="HookBlockedError",s?.cause!==void 0&&(this.cause=s.cause),s?.injectContext!==void 0&&(this.injectContext=s.injectContext)}event;reason;cause;injectContext},nt=class extends Error{toolResultsGathered;constructor(e){super(e),this.name="StreamIncompleteError"}},mn=class extends Error{constructor(n,r,o){super(o??`Budget ceiling reached: $${n.toFixed(4)} cumulative >= $${r.toFixed(4)} limit`);this.runningCostUsd=n;this.maxBudgetUsd=r;this.name="BudgetExceededError"}runningCostUsd;maxBudgetUsd},qr=class extends Error{constructor(e){super(e),this.name="DenialCircuitBreakerError"}}});function Gv(t){let e=[...t.oauthEntries??[],...t.effort?[t.effortEntry]:[],...t.extendedCacheTtl?[t.extendedCacheEntry]:[],...t.fast?[ZB]:[]].filter(Boolean);return[...new Set(e)].join(",")||void 0}var ZB,qv=g(()=>{"use strict";ZB="fast-mode-2026-02-01"});function Xr(t){return t.startsWith("sk-ant-oat01-")?"oauth":"api-key"}function Us(t,e,n,r){let o=e==="oauth"?{authToken:t}:{apiKey:t},s=typeof n=="string"&&n.length>0?{...o,baseURL:n}:o;return r?{...s,fetch:r}:s}function gn(t,e,n,r,o,s){let i=Gv({oauthEntries:t==="oauth"?ej.split(","):[],effort:t==="oauth"&&r===!0,extendedCacheTtl:o,fast:s,effortEntry:tj,extendedCacheEntry:Xv});return t!=="oauth"?i?{"anthropic-beta":i}:{}:{"anthropic-beta":i,"x-app":"cli","User-Agent":nj,"X-Claude-Code-Session-Id":e,"x-client-request-id":n}}function zv(t){return t!=="oauth"?null:[{type:"text",text:rj}]}var Xv,ej,tj,nj,rj,hn=g(()=>{"use strict";qv();Xv="extended-cache-ttl-2025-04-11",ej=`claude-code-20250219,oauth-2025-04-20,interleaved-thinking-2025-05-14,${Xv}`,tj="effort-2025-11-24",nj="claude-cli/1.0.0 (external, cli)",rj="x-anthropic-billing-header: cc_version=1.0.0.test; cc_entrypoint=cli; cch=00000;"});function Bc(t){om=t}function nm(t){if(t===void 0)return;let e=t.trim();return e.length>0?e:void 0}function $c(t,e,n){let r={},o=nm(t);o&&(r.id=o);let s=nm(e);s&&(r.baseUrl=s);let i=nm(n);return i&&(r.apiKey=i),r}function ij(){return{local:$c(S.AFK_MODEL_LOCAL,S.AFK_MODEL_LOCAL_BASE_URL,S.AFK_MODEL_LOCAL_API_KEY),small:$c(S.AFK_MODEL_SMALL,S.AFK_MODEL_SMALL_BASE_URL,S.AFK_MODEL_SMALL_API_KEY),medium:$c(S.AFK_MODEL_MEDIUM,S.AFK_MODEL_MEDIUM_BASE_URL,S.AFK_MODEL_MEDIUM_API_KEY),large:$c(S.AFK_MODEL_LARGE,S.AFK_MODEL_LARGE_BASE_URL,S.AFK_MODEL_LARGE_API_KEY)}}function am(t){let e=ij(),n={};for(let r of Bs){let o=Kn[r],s=t?.[r],i=e[r],a={id:i.id??s?.id??o.id},c=s?.name;c&&(a.name=c);let l=s?.provider;l&&(a.provider=l);let d=i.baseUrl??s?.baseUrl;d&&(a.baseUrl=d);let u=i.apiKey??s?.apiKey;u&&(a.apiKey=u),n[r]=a}return n}function Vr(t){return t||om||am()}function Jr(t,e=Vr()){let n=t.trim().toLowerCase();if(!(!n||n===Yv)){for(let r of Bs){let o=e[r].name;if(o&&o.trim().toLowerCase()===n)return r}if(n==="local"||n==="small"||n==="medium"||n==="large")return n}}function qn(t,e=Vr()){if(t===void 0)return{id:""};let n=Jr(t,e);if(n)return e[n];let r=im[t.trim().toLowerCase()];return r?{id:r}:{id:t}}function Ot(t,e=Vr()){if(t!==void 0)return qn(t,e).id}function Qv(t,e=Vr()){if(t===void 0)return;let n=Jr(t,e);if(n&&e[n].id.trim()===""){let r=n.toUpperCase();return`The "${n}" model tier is not configured (no model id). Set AFK_MODEL_${r}=<id> (optionally AFK_MODEL_${r}_BASE_URL / AFK_MODEL_${r}_API_KEY) or "models.${n}" in afk.config.json, then retry.`}}function Zv(t){let e={};if(!t||typeof t!="object")return e;let n=t;for(let r of Bs){let o=cj(n[r]);o&&(e[r]=o)}return e}function ek(t){if(typeof t!="string")return;let e=t.trim().toLowerCase();if(e==="anthropic"||e==="anthropic-direct")return"anthropic";if(e==="openai"||e==="openai-compatible")return"openai";if(e==="chatgpt-oauth"||e==="chatgpt")return"chatgpt-oauth";if(e==="xai")return"xai";if(e==="xai-oauth"||e==="xai_oauth")return"xai-oauth"}function zr(t){return typeof t=="string"?t.trim():""}function Vv(t){return/[\x00-\x1f\x7f]/.test(t)}function cj(t){if(typeof t=="string"){let e=t.trim();return e?{id:e}:void 0}if(t&&typeof t=="object"){let e=t,n=zr(e.id);if(!n)return;let r={id:n},o=zr(e.name);o&&(r.name=o);let s=ek(e.provider);s&&(r.provider=s);let i=zr(e.baseUrl);i&&(r.baseUrl=i);let a=zr(e.apiKey);return a&&(r.apiKey=a),r}}function tk(t){if(!t||typeof t!="object"||Array.isArray(t))return{ok:!1,error:'model binding must be an object with at least an "id"'};let e=t;if("apiKey"in e||"api_key"in e)return{ok:!1,error:"per-slot API keys are credentials; set AFK_MODEL_<TIER>_API_KEY via `afk config env set` instead of afk.config.json"};if("baseUrl"in e||"base_url"in e)return{ok:!1,error:"per-slot baseUrl is an endpoint-redirect credential vector; set AFK_MODEL_<TIER>_BASE_URL via `afk config env set` instead of afk.config.json"};let n=zr(e.id);if(!n)return{ok:!1,error:'model binding requires a non-empty "id"'};if(Vv(n))return{ok:!1,error:'model binding "id" must not contain control characters'};let r={id:n},o=zr(e.name);if(o){if(Vv(o))return{ok:!1,error:'model binding "name" must not contain control characters'};if(aj.has(o.trim().toLowerCase()))return{ok:!1,error:`model binding "name" must not shadow a built-in alias ("${o}")`};r.name=o}if(e.provider!==void 0&&e.provider!==""){let s=ek(e.provider);if(!s)return{ok:!1,error:'model binding "provider" must be one of: anthropic, openai (aliases: anthropic-direct, openai-compatible)'};r.provider=s}return{ok:!0,value:r}}var Bs,Jv,$s,rm,sm,oj,Kn,Yv,im,sj,Gn,om,aj,Ce=g(()=>{"use strict";L();Bs=["local","small","medium","large"],Jv="claude-haiku-4-5-20251001",$s="claude-sonnet-4-6",rm="claude-opus-5",sm="claude-fable-5",oj="grok-4.6",Kn={local:{id:""},small:{id:Jv},medium:{id:$s},large:{id:rm}},Yv="auto",im={opus:rm,opus_1m:rm,sonnet:$s,sonnet_1m:$s,haiku:Jv,fable:sm,grok:oj},sj=["gpt-5.6-sol","gpt-5.6-terra","gpt-5.6-luna","gpt-5.5"],Gn=[...Bs,...Object.keys(im),...sj];aj=new Set([...Bs,Yv,...Object.keys(im)])});function js(t){return t in cm}function we(t){return Ot(t)}var cm,rt=g(()=>{"use strict";Ce();cm={opus:Kn.large.id,opus_1m:Kn.large.id,sonnet:Kn.medium.id,sonnet_1m:Kn.medium.id,haiku:Kn.small.id,fable:sm}});import lj from"@anthropic-ai/sdk";import{randomUUID as nk}from"node:crypto";async function rk(t){let{token:e,model:n,system:r,user:o,maxTokens:s=64,signal:i,clientFactory:a}=t;if(!e)throw new Error("oneShotCompletion: token required");let c=Xr(e),l=Us(e,c),d=a?a(l):new lj(l),u=nk(),p=nk(),f=gn(c,u,p),m=we(n)??n,h={};Object.keys(f).length>0&&(h.headers=f),i&&(h.signal=i);let y=await d.messages.create({model:m,max_tokens:s,system:r,messages:[{role:"user",content:o}]},Object.keys(h).length>0?h:void 0),b=[];for(let _ of y.content)_.type==="text"&&b.push(_.text);let k=b.join("").trim();return k.length===0&&console.warn("oneShotCompletion: response contained no text blocks \u2014 returning empty string"),k}var ok=g(()=>{"use strict";hn();rt()});function pj(){let t=S.AFK_VISION_MODELS,e=[],n=[];if(t)for(let r of t.split(",")){let o=r.trim().toLowerCase();if(o)if(o.startsWith("!")){let s=o.slice(1).trim();s&&n.push(s)}else e.push(o)}return{enable:e,disable:n}}function sk(t,e){return t===e||t.includes(e)}function jc(t){if(!t)return!1;let e=(Ot(t)??t).trim();if(!e)return!1;let n=e.toLowerCase(),{enable:r,disable:o}=pj();return o.some(s=>sk(n,s))?!1:r.some(s=>sk(n,s))||dj.has(n)?!0:uj.some(s=>s.test(e))}function ik(t){let e=t.trim().toLowerCase();return e.includes("/")?e.slice(e.lastIndexOf("/")+1):e}function Xn(t){return t?/^o[0-9]/.test(ik(t)):!1}function Hs(t){if(!t)return!1;if(Xn(t))return!0;let e=ik(t);return fj.some(n=>n.test(e))}var dj,uj,fj,zn=g(()=>{"use strict";L();Ce();dj=new Set(["gpt-4o","gpt-4o-mini","gpt-4.1","gpt-4.1-mini","gpt-4.1-nano","gpt-4-turbo","o1","o3","o4-mini"]),uj=[/^claude-/i,/^gpt-4o/i,/^gpt-4\.1/i,/^gpt-4-turbo/i,/^gpt-4-vision/i,/^gpt-5/i,/(?:^|[/_-])(?:vl|vlm)(?:[/_.-]|$)/i,/(?:^|[/_-])(?:llava|pixtral|internvl|cogvlm|idefics|moondream|janus)/i,/(?:vision|minicpm-?[vo]|qwen[\d.]*-?vl|llama-?3\.2-\d+b-vision|gemma-3|phi-3\.5-vision|phi-4-multimodal)/i];fj=[/^gpt-5/]});function um(t){let e=String(t).trim().toLowerCase(),n=lm[e];if(e.endsWith("_1m")&&n!==void 0)return n;let r=Ot(t)??String(t);return lm[r]??lm[r.toLowerCase()]}function Yr(t){return um(t)??mj}function yj(t){if(!t)return!1;let e=t.trim().toLowerCase();return e?!!(e.includes("/")||e.startsWith("gpt-")||e.startsWith("gpt_")||Xn(e)||e.startsWith("codex-")||e.startsWith("codex_")||e==="codex"||e==="grok"||e.startsWith("grok-")||e.startsWith("grok_")):!1}function yt(t){let e=String(t).trim().toLowerCase(),n=dm[e];if(e.endsWith("_1m")&&n!==void 0)return n;let r=Ot(t)??String(t),o=dm[r]??dm[r.toLowerCase()];return o!==void 0?o:yj(r)?hj:gj}function Yt(t){let e=yt(t);if(String(t).trim().toLowerCase().endsWith("_1m"))return e;let r=Ot(t)??String(t),o=ak[r]??ak[r.toLowerCase()];return o!==void 0?Math.min(e,o):e}var lm,mj,dm,gj,hj,ak,Dt=g(()=>{"use strict";Ce();zn();lm={opus:128e3,opus_1m:128e3,sonnet:128e3,sonnet_1m:128e3,haiku:64e3,fable:128e3,"claude-opus-5":128e3,"claude-opus-4-8":128e3,"claude-opus-4-7":128e3,"claude-opus-4-6":128e3,"claude-sonnet-5":128e3,"claude-sonnet-4-6":128e3,"claude-haiku-4-5-20251001":64e3,"claude-fable-5":128e3,"gpt-5.5":128e3,"gpt-5.6":128e3,"gpt-5.6-sol":128e3,"gpt-5.6-terra":128e3,"gpt-5.6-luna":128e3},mj=64e3;dm={opus:1e6,opus_1m:1e6,sonnet:1e6,sonnet_1m:1e6,haiku:2e5,fable:1e6,"claude-fable-5":1e6,"claude-sonnet-5":1e6,"claude-opus-5":1e6,"claude-opus-4-8":1e6,"claude-opus-4-7":1e6,"claude-opus-4-6":1e6,"claude-sonnet-4-6":1e6,"gpt-4o":128e3,"gpt-4o-mini":128e3,"gpt-4.1":1e6,"gpt-4.1-mini":1e6,"gpt-5.5":1e6,"gpt-5.6":1e6,"gpt-5.6-sol":1e6,"gpt-5.6-terra":1e6,"gpt-5.6-luna":1e6,o1:2e5,"o1-mini":128e3,o3:2e5,"o3-mini":2e5,"o4-mini":2e5,"mlx-community/qwen3-30b-a3b-4bit":128e3,"mlx-community/qwen3-32b-4bit":128e3,"mlx-community/qwen2.5-coder-32b-instruct-4bit":131072,"grok-4.6":5e5,"grok-4.5":5e5,"grok-4.3":1e6,"grok-4.20-0309-reasoning":1e6,"grok-4.20-0309-non-reasoning":1e6,"grok-4.20-multi-agent-0309":1e6,"grok-build-0.1":256e3},gj=2e5,hj=262144;ak={"claude-sonnet-5":2e5,"claude-opus-5":2e5,"claude-sonnet-4-6":2e5,"claude-opus-4-8":2e5,"claude-opus-4-7":2e5,"claude-opus-4-6":2e5}});function ck(t){return(t.inputTokens??0)+(t.outputTokens??0)}function Se(t){return t.contextWindowTokens??ck(t)}function Ws(t){return t?{totalTokens:Se(t),apiUsage:{input_tokens:t.inputTokens??0,output_tokens:t.outputTokens??0,cache_read_input_tokens:t.cachedInputTokens??0,cache_creation_input_tokens:t.cacheCreationTokens??0,context_window_tokens:Se(t)}}:{totalTokens:0,apiUsage:null}}function Ks(t,e,n){return e<=0||t<=0||n<=0||n>=1?!1:t/e>=n}function Gs(t,e){return e<=0||t<=0?0:t/e}function lk(t){let e=yt(t),n=Yt(t),r=Yr(t);if(e<=0||r<=0||n<e)return Hc;let o=(e-r)/e-bj;return o>0?o:Hc}function qs(t,e,n,r){if(t<=0||n<=0||e<=0)return;let o=t+e;if(!(o<=n))throw new Error(`[afk] Context-window overflow: the conversation already used ~${t.toLocaleString()} tokens (last-turn API count) and the configured output ceiling is ${e.toLocaleString()} tokens \u2014 together they exceed the ${r} context window of ${n.toLocaleString()} tokens by ${(o-n).toLocaleString()} tokens. The provider would reject this request with HTTP 400. To continue: run /compact to summarise the conversation history, or start a new session.`)}function Xs(t,e){if(t===void 0||t===!1)return;let n=e!==void 0?lk(e):1;if(t===!0)return Math.min(Hc,n);let r=t.threshold;if(!(typeof r!="number"||!Number.isFinite(r)||r<=0||r>=1))return Math.min(r,n)}var Hc,bj,Qr=g(()=>{"use strict";Dt();Hc=.9,bj=.04});function uk(t){if(t!==void 0&&!(!Number.isFinite(t)||t<0)){if(t>Wc){let e=`temp:${t}`;return dk.has(e)||(dk.add(e),console.warn(`[afk] temperature ${t} exceeds the Anthropic maximum (${Wc}); clamping to ${Wc}.`)),Wc}return t}}function Gc(t,e){let n=Yr(e),r=t.maxOutputTokens;if(typeof r=="number"&&Number.isFinite(r)&&r>0){let o=Math.floor(r);if(o>n){let s=`max:${e}:${o}`;return Kc.has(s)||(Kc.add(s),console.warn(`[afk] maxOutputTokens ${o} exceeds the ${e} output ceiling (${n}); clamping to ${n}.`)),n}return o}return n}function pk(t){if(!t||t.length===0)return;let e=[];for(let n of t)n.user.length>0&&e.push({role:"user",content:n.user}),n.assistant.length>0&&e.push({role:"assistant",content:n.assistant});return e.length>0?e:void 0}function qc(t,e,n){switch(t.type){case"adaptive":return{type:"adaptive",display:"summarized"};case"disabled":return{type:"disabled"};case"enabled":{if(typeof n=="string"&&Sj(n))return{type:"adaptive",display:"summarized"};if(e<=1024)throw new Error(`[afk] Extended thinking requires max_tokens > 1024 (the API constraint is 1024 <= budget_tokens < max_tokens), but the resolved output cap is ${e}. Raise --max-output-tokens / AFK_MAX_OUTPUT_TOKENS above 1024, or disable thinking with --thinking disabled.`);let r=Math.floor(e*vj),o=Math.max(1024,e-1-r),s=t.budgetTokens!==void 0&&Number.isFinite(t.budgetTokens)?Math.floor(t.budgetTokens):void 0,i=Math.min(Math.max(s??o,1024),o);if(s!==void 0&&s>o){let a=`think:${n??"default"}:${s}:${e}`;Kc.has(a)||(Kc.add(a),console.warn(`[afk] thinking budgetTokens ${s} leaves too little of max_tokens ${e} for the reply; clamping to ${o}.`))}return{type:"enabled",budget_tokens:i,display:"summarized"}}}}function Xc(t,e){if(t!==void 0)return t;let n=e.toLowerCase();if(/(claude-)?(opus|sonnet)-(4-[678]|5)/.test(n))return"max"}var wj,Sj,Kc,dk,Wc,vj,zc=g(()=>{"use strict";Dt();Qr();wj=t=>/opus-4-(7|[89])/.test(t),Sj=t=>wj(t)||/(claude-)?(opus|sonnet)-5/.test(t),Kc=new Set,dk=new Set,Wc=1;vj=.25});import pm from"path";import{dirname as kj}from"path";import{appendFileSync as _j,mkdirSync as Aj}from"fs";var yn,Vc=g(()=>{"use strict";j();yn=class{hooks;constructor(e){this.hooks=e}addReadRoot(e,n="slash",r){this.hooks.ensureInitialized?.();let o=this.hooks.getReadRoots();if(!o)return;let s=pm.resolve(e);o.includes(s)||(o.push(s),this.appendAuditLog({action:"grant-read",path:s,source:n,sessionId:r}))}addWriteRoot(e,n="slash",r){this.hooks.ensureInitialized?.();let o=this.hooks.getReadRoots(),s=this.hooks.getWriteRoots();if(!o||!s)return;let i=pm.resolve(e);o.includes(i)||o.push(i),s.includes(i)||(s.push(i),this.appendAuditLog({action:"grant-write",path:i,source:n,sessionId:r}))}revokeRoot(e,n="slash",r){let o=this.hooks.getReadRoots();if(!o)return;let s=pm.resolve(e),i=this.hooks.getProtectedRoot();if(i!==void 0&&s===i)return;let a=o.indexOf(s);a!==-1&&o.splice(a,1);let c=this.hooks.getWriteRoots();if(c){let l=c.indexOf(s);l!==-1&&c.splice(l,1)}this.appendAuditLog({action:"revoke",path:s,source:n,sessionId:r})}getGrants(){return{resolveBase:this.hooks.getProtectedRoot(),readRoots:this.hooks.getReadRoots()?.slice()??[],writeRoots:this.hooks.getWriteRoots()?.slice()??[],allowAll:this.hooks.getAllowAll()}}appendAuditLog(e){try{let n=ic();Aj(kj(n),{recursive:!0});let r=JSON.stringify({timestamp:new Date().toISOString(),sessionId:e.sessionId??this.hooks.getDefaultSessionId?.()??null,action:e.action,path:e.path,source:e.source});_j(n,r+`
|
|
154
|
-
`)}catch{}}}});function bt(t){return t==="bypassPermissions"||t==="autonomous"}var Zr=g(()=>{"use strict"});var Jc,fk=g(()=>{"use strict";Vc();Zr();Jc=class{_readRoots;_writeRoots;
|
|
153
|
+
Send a message to start one, or /new for a fresh session.`}function jv(t){return`\u21A9\uFE0F Switched to ${t.name?`<b>${Ve(t.name)}</b>`:"that session"}. Your next message continues it.`}function Hv(){return"\u{1F195} Started a fresh session. Your previous one is saved \u2014 /sessions to switch back."}function Zf(){return"\u23F3 Finish or wait for the current turn before switching sessions."}function Wv(){return z("That session could no longer be found. /sessions to see the current list.")}function Kv(){return"\u2705 You're already on that session."}var Ae=g(()=>{"use strict"});var Je,Ee,Uc,Y,nt,mn,qr,re=g(()=>{"use strict";Je=class extends Error{constructor(e){super(e),this.name="AbortError"}},Ee=class extends Error{constructor(n,r){super(n);this.timeoutMs=r;this.name="TimeoutError"}timeoutMs},Uc=class extends Ee{constructor(e,n){super(e,n),this.name="IdleWatchdogError"}},Y=class extends Error{constructor(n,r,o,s){super(n);this.event=r;this.reason=o;this.name="HookBlockedError",s?.cause!==void 0&&(this.cause=s.cause),s?.injectContext!==void 0&&(this.injectContext=s.injectContext)}event;reason;cause;injectContext},nt=class extends Error{toolResultsGathered;constructor(e){super(e),this.name="StreamIncompleteError"}},mn=class extends Error{constructor(n,r,o){super(o??`Budget ceiling reached: $${n.toFixed(4)} cumulative >= $${r.toFixed(4)} limit`);this.runningCostUsd=n;this.maxBudgetUsd=r;this.name="BudgetExceededError"}runningCostUsd;maxBudgetUsd},qr=class extends Error{constructor(e){super(e),this.name="DenialCircuitBreakerError"}}});function Gv(t){let e=[...t.oauthEntries??[],...t.effort?[t.effortEntry]:[],...t.extendedCacheTtl?[t.extendedCacheEntry]:[],...t.fast?[ZB]:[]].filter(Boolean);return[...new Set(e)].join(",")||void 0}var ZB,qv=g(()=>{"use strict";ZB="fast-mode-2026-02-01"});function Xr(t){return t.startsWith("sk-ant-oat01-")?"oauth":"api-key"}function Us(t,e,n,r){let o=e==="oauth"?{authToken:t}:{apiKey:t},s=typeof n=="string"&&n.length>0?{...o,baseURL:n}:o;return r?{...s,fetch:r}:s}function gn(t,e,n,r,o,s){let i=Gv({oauthEntries:t==="oauth"?ej.split(","):[],effort:t==="oauth"&&r===!0,extendedCacheTtl:o,fast:s,effortEntry:tj,extendedCacheEntry:Xv});return t!=="oauth"?i?{"anthropic-beta":i}:{}:{"anthropic-beta":i,"x-app":"cli","User-Agent":nj,"X-Claude-Code-Session-Id":e,"x-client-request-id":n}}function zv(t){return t!=="oauth"?null:[{type:"text",text:rj}]}var Xv,ej,tj,nj,rj,hn=g(()=>{"use strict";qv();Xv="extended-cache-ttl-2025-04-11",ej=`claude-code-20250219,oauth-2025-04-20,interleaved-thinking-2025-05-14,${Xv}`,tj="effort-2025-11-24",nj="claude-cli/1.0.0 (external, cli)",rj="x-anthropic-billing-header: cc_version=1.0.0.test; cc_entrypoint=cli; cch=00000;"});function Bc(t){om=t}function nm(t){if(t===void 0)return;let e=t.trim();return e.length>0?e:void 0}function $c(t,e,n){let r={},o=nm(t);o&&(r.id=o);let s=nm(e);s&&(r.baseUrl=s);let i=nm(n);return i&&(r.apiKey=i),r}function ij(){return{local:$c(S.AFK_MODEL_LOCAL,S.AFK_MODEL_LOCAL_BASE_URL,S.AFK_MODEL_LOCAL_API_KEY),small:$c(S.AFK_MODEL_SMALL,S.AFK_MODEL_SMALL_BASE_URL,S.AFK_MODEL_SMALL_API_KEY),medium:$c(S.AFK_MODEL_MEDIUM,S.AFK_MODEL_MEDIUM_BASE_URL,S.AFK_MODEL_MEDIUM_API_KEY),large:$c(S.AFK_MODEL_LARGE,S.AFK_MODEL_LARGE_BASE_URL,S.AFK_MODEL_LARGE_API_KEY)}}function am(t){let e=ij(),n={};for(let r of Bs){let o=Kn[r],s=t?.[r],i=e[r],a={id:i.id??s?.id??o.id},c=s?.name;c&&(a.name=c);let l=s?.provider;l&&(a.provider=l);let d=i.baseUrl??s?.baseUrl;d&&(a.baseUrl=d);let u=i.apiKey??s?.apiKey;u&&(a.apiKey=u),n[r]=a}return n}function Vr(t){return t||om||am()}function Jr(t,e=Vr()){let n=t.trim().toLowerCase();if(!(!n||n===Yv)){for(let r of Bs){let o=e[r].name;if(o&&o.trim().toLowerCase()===n)return r}if(n==="local"||n==="small"||n==="medium"||n==="large")return n}}function qn(t,e=Vr()){if(t===void 0)return{id:""};let n=Jr(t,e);if(n)return e[n];let r=im[t.trim().toLowerCase()];return r?{id:r}:{id:t}}function Ot(t,e=Vr()){if(t!==void 0)return qn(t,e).id}function Qv(t,e=Vr()){if(t===void 0)return;let n=Jr(t,e);if(n&&e[n].id.trim()===""){let r=n.toUpperCase();return`The "${n}" model tier is not configured (no model id). Set AFK_MODEL_${r}=<id> (optionally AFK_MODEL_${r}_BASE_URL / AFK_MODEL_${r}_API_KEY) or "models.${n}" in afk.config.json, then retry.`}}function Zv(t){let e={};if(!t||typeof t!="object")return e;let n=t;for(let r of Bs){let o=cj(n[r]);o&&(e[r]=o)}return e}function ek(t){if(typeof t!="string")return;let e=t.trim().toLowerCase();if(e==="anthropic"||e==="anthropic-direct")return"anthropic";if(e==="openai"||e==="openai-compatible")return"openai";if(e==="chatgpt-oauth"||e==="chatgpt")return"chatgpt-oauth";if(e==="xai")return"xai";if(e==="xai-oauth"||e==="xai_oauth")return"xai-oauth"}function zr(t){return typeof t=="string"?t.trim():""}function Vv(t){return/[\x00-\x1f\x7f]/.test(t)}function cj(t){if(typeof t=="string"){let e=t.trim();return e?{id:e}:void 0}if(t&&typeof t=="object"){let e=t,n=zr(e.id);if(!n)return;let r={id:n},o=zr(e.name);o&&(r.name=o);let s=ek(e.provider);s&&(r.provider=s);let i=zr(e.baseUrl);i&&(r.baseUrl=i);let a=zr(e.apiKey);return a&&(r.apiKey=a),r}}function tk(t){if(!t||typeof t!="object"||Array.isArray(t))return{ok:!1,error:'model binding must be an object with at least an "id"'};let e=t;if("apiKey"in e||"api_key"in e)return{ok:!1,error:"per-slot API keys are credentials; set AFK_MODEL_<TIER>_API_KEY via `afk config env set` instead of afk.config.json"};if("baseUrl"in e||"base_url"in e)return{ok:!1,error:"per-slot baseUrl is an endpoint-redirect credential vector; set AFK_MODEL_<TIER>_BASE_URL via `afk config env set` instead of afk.config.json"};let n=zr(e.id);if(!n)return{ok:!1,error:'model binding requires a non-empty "id"'};if(Vv(n))return{ok:!1,error:'model binding "id" must not contain control characters'};let r={id:n},o=zr(e.name);if(o){if(Vv(o))return{ok:!1,error:'model binding "name" must not contain control characters'};if(aj.has(o.trim().toLowerCase()))return{ok:!1,error:`model binding "name" must not shadow a built-in alias ("${o}")`};r.name=o}if(e.provider!==void 0&&e.provider!==""){let s=ek(e.provider);if(!s)return{ok:!1,error:'model binding "provider" must be one of: anthropic, openai (aliases: anthropic-direct, openai-compatible)'};r.provider=s}return{ok:!0,value:r}}var Bs,Jv,$s,rm,sm,oj,Kn,Yv,im,sj,Gn,om,aj,Ce=g(()=>{"use strict";L();Bs=["local","small","medium","large"],Jv="claude-haiku-4-5-20251001",$s="claude-sonnet-4-6",rm="claude-opus-5",sm="claude-fable-5",oj="grok-4.6",Kn={local:{id:""},small:{id:Jv},medium:{id:$s},large:{id:rm}},Yv="auto",im={opus:rm,opus_1m:rm,sonnet:$s,sonnet_1m:$s,haiku:Jv,fable:sm,grok:oj},sj=["gpt-5.6-sol","gpt-5.6-terra","gpt-5.6-luna","gpt-5.5"],Gn=[...Bs,...Object.keys(im),...sj];aj=new Set([...Bs,Yv,...Object.keys(im)])});function js(t){return t in cm}function we(t){return Ot(t)}var cm,rt=g(()=>{"use strict";Ce();cm={opus:Kn.large.id,opus_1m:Kn.large.id,sonnet:Kn.medium.id,sonnet_1m:Kn.medium.id,haiku:Kn.small.id,fable:sm}});import lj from"@anthropic-ai/sdk";import{randomUUID as nk}from"node:crypto";async function rk(t){let{token:e,model:n,system:r,user:o,maxTokens:s=64,signal:i,clientFactory:a}=t;if(!e)throw new Error("oneShotCompletion: token required");let c=Xr(e),l=Us(e,c),d=a?a(l):new lj(l),u=nk(),p=nk(),f=gn(c,u,p),m=we(n)??n,h={};Object.keys(f).length>0&&(h.headers=f),i&&(h.signal=i);let y=await d.messages.create({model:m,max_tokens:s,system:r,messages:[{role:"user",content:o}]},Object.keys(h).length>0?h:void 0),b=[];for(let _ of y.content)_.type==="text"&&b.push(_.text);let k=b.join("").trim();return k.length===0&&console.warn("oneShotCompletion: response contained no text blocks \u2014 returning empty string"),k}var ok=g(()=>{"use strict";hn();rt()});function pj(){let t=S.AFK_VISION_MODELS,e=[],n=[];if(t)for(let r of t.split(",")){let o=r.trim().toLowerCase();if(o)if(o.startsWith("!")){let s=o.slice(1).trim();s&&n.push(s)}else e.push(o)}return{enable:e,disable:n}}function sk(t,e){return t===e||t.includes(e)}function jc(t){if(!t)return!1;let e=(Ot(t)??t).trim();if(!e)return!1;let n=e.toLowerCase(),{enable:r,disable:o}=pj();return o.some(s=>sk(n,s))?!1:r.some(s=>sk(n,s))||dj.has(n)?!0:uj.some(s=>s.test(e))}function ik(t){let e=t.trim().toLowerCase();return e.includes("/")?e.slice(e.lastIndexOf("/")+1):e}function Xn(t){return t?/^o[0-9]/.test(ik(t)):!1}function Hs(t){if(!t)return!1;if(Xn(t))return!0;let e=ik(t);return fj.some(n=>n.test(e))}var dj,uj,fj,zn=g(()=>{"use strict";L();Ce();dj=new Set(["gpt-4o","gpt-4o-mini","gpt-4.1","gpt-4.1-mini","gpt-4.1-nano","gpt-4-turbo","o1","o3","o4-mini"]),uj=[/^claude-/i,/^gpt-4o/i,/^gpt-4\.1/i,/^gpt-4-turbo/i,/^gpt-4-vision/i,/^gpt-5/i,/(?:^|[/_-])(?:vl|vlm)(?:[/_.-]|$)/i,/(?:^|[/_-])(?:llava|pixtral|internvl|cogvlm|idefics|moondream|janus)/i,/(?:vision|minicpm-?[vo]|qwen[\d.]*-?vl|llama-?3\.2-\d+b-vision|gemma-3|phi-3\.5-vision|phi-4-multimodal)/i];fj=[/^gpt-5/]});function um(t){let e=String(t).trim().toLowerCase(),n=lm[e];if(e.endsWith("_1m")&&n!==void 0)return n;let r=Ot(t)??String(t);return lm[r]??lm[r.toLowerCase()]}function Yr(t){return um(t)??mj}function yj(t){if(!t)return!1;let e=t.trim().toLowerCase();return e?!!(e.includes("/")||e.startsWith("gpt-")||e.startsWith("gpt_")||Xn(e)||e.startsWith("codex-")||e.startsWith("codex_")||e==="codex"||e==="grok"||e.startsWith("grok-")||e.startsWith("grok_")):!1}function yt(t){let e=String(t).trim().toLowerCase(),n=dm[e];if(e.endsWith("_1m")&&n!==void 0)return n;let r=Ot(t)??String(t),o=dm[r]??dm[r.toLowerCase()];return o!==void 0?o:yj(r)?hj:gj}function Yt(t){let e=yt(t);if(String(t).trim().toLowerCase().endsWith("_1m"))return e;let r=Ot(t)??String(t),o=ak[r]??ak[r.toLowerCase()];return o!==void 0?Math.min(e,o):e}var lm,mj,dm,gj,hj,ak,Dt=g(()=>{"use strict";Ce();zn();lm={opus:128e3,opus_1m:128e3,sonnet:128e3,sonnet_1m:128e3,haiku:64e3,fable:128e3,"claude-opus-5":128e3,"claude-opus-4-8":128e3,"claude-opus-4-7":128e3,"claude-opus-4-6":128e3,"claude-sonnet-5":128e3,"claude-sonnet-4-6":128e3,"claude-haiku-4-5-20251001":64e3,"claude-fable-5":128e3,"gpt-5.5":128e3,"gpt-5.6":128e3,"gpt-5.6-sol":128e3,"gpt-5.6-terra":128e3,"gpt-5.6-luna":128e3},mj=64e3;dm={opus:1e6,opus_1m:1e6,sonnet:1e6,sonnet_1m:1e6,haiku:2e5,fable:1e6,"claude-fable-5":1e6,"claude-sonnet-5":1e6,"claude-opus-5":1e6,"claude-opus-4-8":1e6,"claude-opus-4-7":1e6,"claude-opus-4-6":1e6,"claude-sonnet-4-6":1e6,"gpt-4o":128e3,"gpt-4o-mini":128e3,"gpt-4.1":1e6,"gpt-4.1-mini":1e6,"gpt-5.5":1e6,"gpt-5.6":1e6,"gpt-5.6-sol":1e6,"gpt-5.6-terra":1e6,"gpt-5.6-luna":1e6,o1:2e5,"o1-mini":128e3,o3:2e5,"o3-mini":2e5,"o4-mini":2e5,"mlx-community/qwen3-30b-a3b-4bit":128e3,"mlx-community/qwen3-32b-4bit":128e3,"mlx-community/qwen2.5-coder-32b-instruct-4bit":131072,"grok-4.6":5e5,"grok-4.5":5e5,"grok-4.3":1e6,"grok-4.20-0309-reasoning":1e6,"grok-4.20-0309-non-reasoning":1e6,"grok-4.20-multi-agent-0309":1e6,"grok-build-0.1":256e3},gj=2e5,hj=262144;ak={"claude-sonnet-5":2e5,"claude-opus-5":2e5,"claude-sonnet-4-6":2e5,"claude-opus-4-8":2e5,"claude-opus-4-7":2e5,"claude-opus-4-6":2e5}});function ck(t){return(t.inputTokens??0)+(t.outputTokens??0)}function Se(t){return t.contextWindowTokens??ck(t)}function Ws(t){return t?{totalTokens:Se(t),apiUsage:{input_tokens:t.inputTokens??0,output_tokens:t.outputTokens??0,cache_read_input_tokens:t.cachedInputTokens??0,cache_creation_input_tokens:t.cacheCreationTokens??0,context_window_tokens:Se(t)}}:{totalTokens:0,apiUsage:null}}function Ks(t,e,n){return e<=0||t<=0||n<=0||n>=1?!1:t/e>=n}function Gs(t,e){return e<=0||t<=0?0:t/e}function lk(t){let e=yt(t),n=Yt(t),r=Yr(t);if(e<=0||r<=0||n<e)return Hc;let o=(e-r)/e-bj;return o>0?o:Hc}function qs(t,e,n,r){if(t<=0||n<=0||e<=0)return;let o=t+e;if(!(o<=n))throw new Error(`[afk] Context-window overflow: the conversation already used ~${t.toLocaleString()} tokens (last-turn API count) and the configured output ceiling is ${e.toLocaleString()} tokens \u2014 together they exceed the ${r} context window of ${n.toLocaleString()} tokens by ${(o-n).toLocaleString()} tokens. The provider would reject this request with HTTP 400. To continue: run /compact to summarise the conversation history, or start a new session.`)}function Xs(t,e){if(t===void 0||t===!1)return;let n=e!==void 0?lk(e):1;if(t===!0)return Math.min(Hc,n);let r=t.threshold;if(!(typeof r!="number"||!Number.isFinite(r)||r<=0||r>=1))return Math.min(r,n)}var Hc,bj,Qr=g(()=>{"use strict";Dt();Hc=.9,bj=.04});function uk(t){if(t!==void 0&&!(!Number.isFinite(t)||t<0)){if(t>Wc){let e=`temp:${t}`;return dk.has(e)||(dk.add(e),console.warn(`[afk] temperature ${t} exceeds the Anthropic maximum (${Wc}); clamping to ${Wc}.`)),Wc}return t}}function Gc(t,e){let n=Yr(e),r=t.maxOutputTokens;if(typeof r=="number"&&Number.isFinite(r)&&r>0){let o=Math.floor(r);if(o>n){let s=`max:${e}:${o}`;return Kc.has(s)||(Kc.add(s),console.warn(`[afk] maxOutputTokens ${o} exceeds the ${e} output ceiling (${n}); clamping to ${n}.`)),n}return o}return n}function pk(t){if(!t||t.length===0)return;let e=[];for(let n of t)n.user.length>0&&e.push({role:"user",content:n.user}),n.assistant.length>0&&e.push({role:"assistant",content:n.assistant});return e.length>0?e:void 0}function qc(t,e,n){switch(t.type){case"adaptive":return{type:"adaptive",display:"summarized"};case"disabled":return{type:"disabled"};case"enabled":{if(typeof n=="string"&&Sj(n))return{type:"adaptive",display:"summarized"};if(e<=1024)throw new Error(`[afk] Extended thinking requires max_tokens > 1024 (the API constraint is 1024 <= budget_tokens < max_tokens), but the resolved output cap is ${e}. Raise --max-output-tokens / AFK_MAX_OUTPUT_TOKENS above 1024, or disable thinking with --thinking disabled.`);let r=Math.floor(e*vj),o=Math.max(1024,e-1-r),s=t.budgetTokens!==void 0&&Number.isFinite(t.budgetTokens)?Math.floor(t.budgetTokens):void 0,i=Math.min(Math.max(s??o,1024),o);if(s!==void 0&&s>o){let a=`think:${n??"default"}:${s}:${e}`;Kc.has(a)||(Kc.add(a),console.warn(`[afk] thinking budgetTokens ${s} leaves too little of max_tokens ${e} for the reply; clamping to ${o}.`))}return{type:"enabled",budget_tokens:i,display:"summarized"}}}}function Xc(t,e){if(t!==void 0)return t;let n=e.toLowerCase();if(/(claude-)?(opus|sonnet)-(4-[678]|5)/.test(n))return"max"}var wj,Sj,Kc,dk,Wc,vj,zc=g(()=>{"use strict";Dt();Qr();wj=t=>/opus-4-(7|[89])/.test(t),Sj=t=>wj(t)||/(claude-)?(opus|sonnet)-5/.test(t),Kc=new Set,dk=new Set,Wc=1;vj=.25});import pm from"path";import{dirname as kj}from"path";import{appendFileSync as _j,mkdirSync as Aj}from"fs";var yn,Vc=g(()=>{"use strict";j();yn=class{hooks;constructor(e){this.hooks=e}addReadRoot(e,n="slash",r){this.hooks.ensureInitialized?.();let o=this.hooks.getReadRoots();if(!o)return;let s=pm.resolve(e);o.includes(s)||(o.push(s),this.appendAuditLog({action:"grant-read",path:s,source:n,sessionId:r}))}addWriteRoot(e,n="slash",r){this.hooks.ensureInitialized?.();let o=this.hooks.getReadRoots(),s=this.hooks.getWriteRoots();if(!o||!s)return;let i=pm.resolve(e);o.includes(i)||o.push(i),s.includes(i)||(s.push(i),this.appendAuditLog({action:"grant-write",path:i,source:n,sessionId:r}))}revokeRoot(e,n="slash",r){let o=this.hooks.getReadRoots();if(!o)return;let s=pm.resolve(e),i=this.hooks.getProtectedRoot();if(i!==void 0&&s===i)return;let a=o.indexOf(s),c=a!==-1;c&&o.splice(a,1);let l=this.hooks.getWriteRoots(),d=!1;if(l){let u=l.indexOf(s);d=u!==-1,d&&l.splice(u,1)}(c||d)&&this.appendAuditLog({action:"revoke",path:s,source:n,sessionId:r})}getGrants(){return{resolveBase:this.hooks.getDisplayResolveBase?this.hooks.getDisplayResolveBase():this.hooks.getProtectedRoot(),readRoots:this.hooks.getReadRoots()?.slice()??[],writeRoots:this.hooks.getWriteRoots()?.slice()??[],allowAll:this.hooks.getAllowAll()}}appendAuditLog(e){try{let n=ic();Aj(kj(n),{recursive:!0});let r=JSON.stringify({timestamp:new Date().toISOString(),sessionId:e.sessionId??this.hooks.getDefaultSessionId?.()??null,action:e.action,path:e.path,source:e.source});_j(n,r+`
|
|
154
|
+
`)}catch{}}}});function bt(t){return t==="bypassPermissions"||t==="autonomous"}var Zr=g(()=>{"use strict"});var Jc,fk=g(()=>{"use strict";Vc();Zr();Jc=class{_readRoots;_writeRoots;_currentCwd;_permissionMode="default";manager=new yn({getReadRoots:()=>this._readRoots,getWriteRoots:()=>this._writeRoots,ensureInitialized:()=>this.ensureInitialized(),getProtectedRoot:()=>this._currentCwd,getAllowAll:()=>bt(this._permissionMode)});get readRoots(){return this._readRoots}get writeRoots(){return this._writeRoots}get currentCwd(){return this._currentCwd}set currentCwd(e){this._currentCwd=e}get permissionMode(){return this._permissionMode}set permissionMode(e){this._permissionMode=e}ensureInitialized(e){if(!this._readRoots){let n=e?[e]:[];this._readRoots=n.slice(),this._writeRoots=n.slice(),e&&!this._currentCwd&&(this._currentCwd=e)}}}});import Ej from"better-sqlite3";function Rj(t){let e=[...new Set(t.toLowerCase().split(/\W+/).filter(n=>n.length>=3))].slice(0,25);return e.length===0?"":e.map(n=>`"${n}"`).join(" OR ")}var Tj,zs,fm=g(()=>{"use strict";Tj=`
|
|
155
155
|
CREATE TABLE IF NOT EXISTS workspace_entries (
|
|
156
156
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
157
157
|
session_id TEXT NOT NULL,
|
|
@@ -226,7 +226,11 @@ ${n}`:n}}}return{...t,systemPrompt:n}}function Fj(t){return t.length===0?t:(t[0]
|
|
|
226
226
|
\u2026 [${n.length-i.length-a.length} bytes truncated: showing first ${i.length} + last ${a.length} of ${n.length}] \u2026
|
|
227
227
|
|
|
228
228
|
`;return i.toString("utf8")+l+a.toString("utf8")}function nr(t){return Buffer.byteLength(t,"utf8")<=1e5?{content:t,truncated:!1}:{content:tr(t,1e5),truncated:!0}}var $H,qk,wn=g(()=>{"use strict";$H=160;qk=`
|
|
229
|
-
[output truncated \u2014 command exceeded the 8000000-byte output cap and was terminated]`});var Xk,zk,Vk=g(()=>{"use strict";Xk={name:"read_witness",category:"read",concurrencySafe:!0,description:"Read and filter events from a session's witness trace (the durable record of everything the agent did). Returns structured trace events in chronological order. Use to inspect tool calls, errors, subagent lifecycles, costs, and session phases from a specific session. Defaults to the most recent session.",input_schema:{type:"object",properties:{session:{type:"string",description:'Session ID to read, or "latest" (default). Use search_witness to find session IDs.'},kinds:{type:"array",items:{type:"string"},description:"Filter by event kind(s). Values: tool_call, subagent_lifecycle, session_phase, closure, abort, budget, hook_decision, browser_event, claim, compaction, background_agent, queued_user_message, session_sealed."},tool_name:{type:"string",description:'Filter tool_call events to only this tool name (e.g. "bash", "edit_file").'},errors_only:{type:"boolean",description:"When true, show only error events: failed tool calls and failed subagents. Default: false."},limit:{type:"number",description:"Max events to return (default: 50, max: 200). Returns the N most recent matching events."}},required:[]}},zk={name:"search_witness",category:"read",concurrencySafe:!0,description:"Search across multiple sessions' witness traces for a text pattern. Returns matching trace events grouped by session. Use to find patterns across sessions \u2014 recurring errors, specific tool usage, cost spikes, or any text that appears in trace event payloads. Scans the N most recent sessions (default 20). Results are capped at 200 total matches across all scanned sessions.",input_schema:{type:"object",properties:{query:{type:"string",description:"Text pattern to search for (case-insensitive substring match)."},sessions:{type:"number",description:'Number of recent sessions to scan (default: 20, max: 100). The result includes sessionsAvailable (sessions in this window before any since filter) and sessionsSearched (sessions actually read after the since filter) so you can distinguish "few sessions exist" from "the date filter excluded most of them".'},kinds:{type:"array",items:{type:"string"},description:"Filter results to specific event kinds (same values as read_witness)."},since:{type:"string",description:"ISO date string \u2014 only search sessions modified after this date."},tool_name:{type:"string",description:'Filter tool_call events to only this tool name (e.g. "bash", "edit_file"). Non-tool_call events are excluded when set.'}},required:["query"]}}});var km,Jk=g(()=>{"use strict";km={name:"cancel_background_job",category:"subagent",concurrencySafe:!1,description:'Cancel a running background subagent job that this model created with the agent tool in mode="background". Use when new context makes an in-flight model-dispatched job obsolete or harmful to continue. Do not use for jobs backgrounded by the user with Ctrl+B: those are user-owned and this tool will refuse; ask the user to run /bgsub:cancel instead. A concrete reason is required and is recorded in the witness trace. Completed, failed, or already-cancelled jobs return an informative non-error result.',input_schema:{type:"object",properties:{jobId:{type:"string",description:"The background job id returned by an earlier agent call in background mode."},reason:{type:"string",description:"Required explanation of why the running job is now obsolete or should stop."}},required:["jobId","reason"]}}});var Yk=g(()=>{"use strict";Jk()});var BH,jH,HH,WH,KH,GH,qH,XH,zH,VH,Ye,rr,or,JH,YH,QH,ZH,eW,tW,nW,rW,oW,sW,iW,aW,cW,lW,Lt,wt,uoe,st=g(()=>{"use strict";Vk();Yk();BH={name:"bash",category:"shell",concurrencySafe:!1,description:"Execute a shell command and return its stdout and stderr. Use for running programs, installing packages, git operations, and any task that requires a shell. Commands run through /bin/sh (Node spawn with shell:true) \u2014 NOT bash and NOT your $SHELL; /bin/sh is bash-in-POSIX-mode on macOS but dash on Debian/Ubuntu. Only process substitution <(...) reliably fails closed (exit 2, nothing runs). Other bashisms are nonportable and are NOT dependable refusals: [[ ]] runs on macOS but is a not-found command on dash while the rest of the line still executes; {a,b} expands on macOS but passes through literally on dash (silently wrong argument); arrays run on macOS but are a syntax error on dash. So never assume a bashism-containing command was side-effect-free \u2014 prefer a temp file or a POSIX equivalent. Long-running commands should use timeout_ms. Output is capped to a ~100KB head+tail view (the start and end are kept, the middle elided with a notice), so the command still runs to completion and you keep the real exit code and the tail (test/build summaries, final errors). For the full body of a verbose command, filter it (`| tail -n`, `--quiet`, narrower flags) or redirect to a file and read slices. Commands emitting extreme output (>8MB) are terminated. For reading or writing files \u2014 especially anything sensitive \u2014 prefer the typed file tools (read_file, write_file, edit_file): they support per-call user approval, and interpreter one-liners (python -c, node -e, sh -c, ...) that reference credential paths (SSH keys, cloud credentials, /etc/shadow) are blocked by the path-approval policy on interactive surfaces.",input_schema:{type:"object",properties:{command:{type:"string",description:"The shell command to execute."},timeout_ms:{type:"number",description:"Optional timeout in milliseconds (default 120000, max 600000). The command is killed if it exceeds this duration."}},required:["command"]}},jH={name:"read_file",category:"read",concurrencySafe:!0,description:"Read a file from the filesystem. Returns the file content with line numbers. Use offset and limit to read specific sections of large files. When the read returns a partial view, the response ends with a `... (showing lines X-Y of Z [\u2014 pass offset=N to continue])` annotation indicating the full file size and how to continue. Binary files are detected and rejected \u2014 use extract_document for .docx, .pdf, .xlsx, .pptx, and .zip files. Missing files return an error.",input_schema:{type:"object",properties:{file_path:{type:"string",description:"Absolute path to the file to read."},offset:{type:"number",description:"Line number to start reading from (1-based). Defaults to 1."},limit:{type:"number",description:"Maximum number of lines to read. Defaults to 2000."}},required:["file_path"]}},HH={name:"extract_document",category:"read",concurrencySafe:!0,description:'Extract text from binary document formats that read_file rejects. Supports .docx, .xlsx, .pptx (Office/OOXML \u2014 zero external dependencies), .pdf (requires pdftotext from poppler-utils; emits install instructions if missing), and .zip (lists members and extracts text-file contents). Use this when read_file reports "File appears to be binary" on a document you need to read. Returns plain text extracted from the document. Security: 4 MB decompression cap, zip-slip path containment, no shell execution. Output is capped at 512 KB of text; larger documents are truncated with a marker.',input_schema:{type:"object",properties:{file_path:{type:"string",description:"Absolute path to the document file to extract text from."}},required:["file_path"]}},WH={name:"write_file",category:"write",concurrencySafe:!1,description:"Write content to a file, creating it if it does not exist or overwriting if it does. Parent directories are created automatically. Prefer edit_file for modifying existing files \u2014 use write_file only for new files or complete rewrites.",input_schema:{type:"object",properties:{file_path:{type:"string",description:"Absolute path to the file to write."},content:{type:"string",description:"The full content to write to the file."}},required:["file_path","content"]}},KH={name:"edit_file",category:"write",concurrencySafe:!1,description:"Perform an exact string replacement in a file. Finds old_string and replaces it with new_string. The edit fails if old_string is not found or matches multiple locations (unless replace_all is true). Always use read_file first to verify the exact content before editing.",input_schema:{type:"object",properties:{file_path:{type:"string",description:"Absolute path to the file to edit."},old_string:{type:"string",description:"The exact string to find and replace. Must match file content exactly."},new_string:{type:"string",description:"The replacement string."},replace_all:{type:"boolean",description:"If true, replace all occurrences. If false (default), fail when multiple matches exist."}},required:["file_path","old_string","new_string"]}},GH={name:"glob",category:"read",concurrencySafe:!0,description:'Find files matching a glob pattern. Returns matching file paths, capped at 500 results. Use for discovering files before reading them. Patterns follow standard glob syntax (e.g., "src/**/*.ts", "*.json"). Skips node_modules/.git/.hg/.svn by default; name such a directory literally in the pattern (e.g. "node_modules/**/*.js") to search it.',input_schema:{type:"object",properties:{pattern:{type:"string",description:'Glob pattern to match (e.g., "src/**/*.ts").'},path:{type:"string",description:"Base directory to search from. Defaults to the current working directory."}},required:["pattern"]}},qH={name:"grep",category:"read",concurrencySafe:!0,description:"Search file contents for lines matching a pattern. Returns matches in file:line:content format. Runs on ripgrep: `|` `+` `?` `(` `)` `{` `}` are regex metacharacters by default (e.g. `foo|bar` alternates, matching either branch) \u2014 escape with a backslash for the literal character. Honors .gitignore (so build/dependency dirs like node_modules are skipped) but DOES search hidden files/dirs like .github and .env; the .git directory and binary files are skipped. Output is capped to a ~100KB head+tail view; if a search is truncated, narrow it (a more specific pattern, an `include` glob, or a subdirectory `path`) rather than re-running the same broad query. Use for finding symbols, strings, or patterns across the codebase.",input_schema:{type:"object",properties:{pattern:{type:"string",description:'Search pattern (ripgrep regex syntax). `|` `+` `?` `(` `)` `{` `}` are metacharacters \u2014 e.g. `foo|bar` matches either "foo" or "bar". Escape with a backslash (e.g. `\\|`) to match the literal character.'},path:{type:"string",description:"Directory or file to search. Defaults to current working directory."},include:{type:"string",description:'File glob to restrict search (e.g., "*.ts"). Passed as -g to ripgrep.'}},required:["pattern"]}},XH={name:"list_directory",category:"read",concurrencySafe:!0,description:"List the contents of a directory. Returns file and subdirectory names with type annotations (directories end with /). Use for exploring project structure.",input_schema:{type:"object",properties:{path:{type:"string",description:"Absolute path to the directory to list."}},required:["path"]}},zH={name:"send_telegram",category:"web",concurrencySafe:!1,riskClass:"caution",description:'Send a Telegram message to the operator. Use to surface terminal-state notifications, blocking questions, or important status updates when the user is away from keyboard (AFK). The message is delivered through the same Telegram bot the operator uses to drive this session. By default the message goes to your primary chat (the first private chat in `AFK_TELEGRAM_ALLOWED_CHAT_IDS`, or `AFK_TELEGRAM_PRIMARY_CHAT_ID` if set); set `telegram.notify` in afk.config.json to broadcast to all allowed chats or target a custom set.\n\nPlain text only \u2014 Telegram\'s 4096-character limit per message is enforced. Returns an error if Telegram is not configured (missing `TELEGRAM_BOT_TOKEN` or empty allowlist) so the tool is safe to attempt unconditionally.\n\nUse sparingly: this is a real push notification to a human. Reserve for terminal states (Done/Blocked/Asking) and material progress, not running commentary. When running inside the Telegram bot, prefer replying normally \u2014 your response already reaches the operator through the bot. Use this tool only from CLI or daemon sessions.\n\nOptionally set `chat` to route to a SPECIFIC chat instead of the default primary target: pass a numeric chat id (e.g. -1001234567890 for a group) or a chat alias name defined in afk.config.json `telegram.chatAliases` (e.g. "ops"). An explicitly-targeted chat must be in the inbound allowlist (AFK_TELEGRAM_ALLOWED_CHAT_IDS) \u2014 a non-allowlisted target is rejected (fail-closed). Omit `chat` for the default behavior (unchanged).\n\nFor supergroups with topics enabled, set `thread_id` alongside `chat` to send to a specific topic thread.',input_schema:{type:"object",properties:{message:{type:"string",description:"Plain-text message body to send to the operator. Max 4096 characters (Telegram API limit). Must be non-empty."},chat:{type:["number","string"],description:"Optional. Target a specific chat instead of the default primary target. A number (or numeric string) is a raw Telegram chat id; a non-numeric string is looked up as a name in afk.config.json `telegram.chatAliases`. The resolved chat must be allowlisted (AFK_TELEGRAM_ALLOWED_CHAT_IDS) or the send is rejected. Omit to send to the configured default (primary DM chat / notify targets)."},thread_id:{type:"number",description:"Optional. Telegram message_thread_id for sending to a specific topic in a supergroup with topics enabled. Pass the numeric thread/topic ID. Ignored when the target chat is not a supergroup with topics. Requires `chat` to be set explicitly (thread targeting without a chat target is ambiguous)."}},required:["message"]}},VH={name:"web_scrape",category:"web",concurrencySafe:!0,description:'Scrape a web page or run a web search and return text content suitable for reasoning over. Three modes:\n\n- `markdown` (default): fetches the URL and extracts the main content as clean markdown (Readability + Turndown). Handles JS-rendered pages: if the plain fetch yields thin content, it escalates to a headless-browser render and re-extracts. Use this for articles, docs, blog posts, and most "I want to read this page" cases. No API key required (the render fallback needs the Playwright chromium binary; if it is absent the error names the exact install command for this installation).\n- `raw`: GETs the URL directly and returns the response body as decoded text, with no markdown transformation. Use for JSON APIs, robots.txt, RSS, or plain-text endpoints. Not byte-preserving \u2014 binary payloads are decoded as text, so do not rely on this for exact bytes. No API key required.\n- `search`: runs a web search and returns ranked markdown results. Use when you need to FIND a URL, not read one. Provide `query` instead of `url`. Requires `EXA_API_KEY` (free tier at https://exa.ai); the handler returns a clear error if it is unset.\n\nOutputs are capped at `max_bytes` UTF-8 bytes (default 100KB, ceiling 1MB); content over the cap is reduced to head+tail with a `\u2026 [N bytes truncated: \u2026] \u2026` marker so both ends survive. The request is aborted after `timeout_ms` (default 30000, ceiling 120000).',input_schema:{type:"object",properties:{mode:{type:"string",enum:["markdown","raw","search"],description:'Fetch mode. Defaults to "markdown".'},url:{type:"string",description:"Absolute http(s) URL. Required for markdown and raw modes. Ignored in search mode."},query:{type:"string",description:"Search query string. Required for search mode. Ignored otherwise."},timeout_ms:{type:"number",description:"Request timeout in milliseconds (default 30000, clamped to 120000)."},max_bytes:{type:"number",description:"Maximum UTF-8 bytes returned. Content beyond this is reduced to head+tail with a truncation marker (both ends preserved). Default 100000, clamped to 1000000."}},required:[]}},Ye={name:"agent",category:"subagent",concurrencySafe:!0,description:`Dispatch an independent subagent with its own context window and tool access. Use for tasks that protect the main session's context: codebase exploration, multi-file inspection, repo search, verification, debugging, failing-test investigation, PR review, parallel hypothesis testing, independent re-derivation of a claim, audit work, stale-path detection, feature-wiring checks, and any research-shaped investigation.
|
|
229
|
+
[output truncated \u2014 command exceeded the 8000000-byte output cap and was terminated]`});var Xk,zk,Vk=g(()=>{"use strict";Xk={name:"read_witness",category:"read",concurrencySafe:!0,description:`Read and filter events from a session's witness trace (the durable record of everything the agent did). Returns structured trace events in chronological order. Use to inspect tool calls, errors, subagent lifecycles, costs, and session phases from a specific session. Defaults to the most recent session.
|
|
230
|
+
|
|
231
|
+
SCOPE: trace events record which tools fired, timing, byte counts, error/success, session phases, and some semantic snippets (e.g. subagent promptHead, compaction summaries, claims). They do NOT contain full conversation text, user/assistant messages, complete tool arguments, or tool output. To find a session by what was *discussed*, search transcripts or session events via bash (paths vary with AFK_STATE_DIR). To recall cross-session context by topic, use memory_search.`,input_schema:{type:"object",properties:{session:{type:"string",description:'Session ID to read, or "latest" (default). Use search_witness to find session IDs.'},kinds:{type:"array",items:{type:"string"},description:"Filter by event kind(s). Values: tool_call, subagent_lifecycle, session_phase, closure, abort, budget, hook_decision, browser_event, claim, compaction, background_agent, queued_user_message, session_sealed."},tool_name:{type:"string",description:'Filter tool_call events to only this tool name (e.g. "bash", "edit_file").'},errors_only:{type:"boolean",description:"When true, show only error events: failed tool calls and failed subagents. Default: false."},limit:{type:"number",description:"Max events to return (default: 50, max: 200). Returns the N most recent matching events."}},required:[]}},zk={name:"search_witness",category:"read",concurrencySafe:!0,description:`Search across multiple sessions' witness traces for a text pattern. Returns matching trace events grouped by session. Use to find patterns across sessions \u2014 recurring errors, specific tool usage, cost spikes, or any text that appears in trace event payloads. Scans the N most recent sessions (default 20). Results are capped at 200 total matches across all scanned sessions.
|
|
232
|
+
|
|
233
|
+
SCOPE: searches trace event payloads \u2014 tool names, session phases, subagent IDs, error classes, timing, and semantic snippets like subagent promptHead (first 80 chars), compaction summaries, and claims. Does NOT contain full conversation text, user/assistant messages, complete tool arguments, or tool output. To find a prior session by topic or what was said, search transcripts or session events via bash (paths vary with AFK_STATE_DIR), or use memory_search for cross-session topic recall.`,input_schema:{type:"object",properties:{query:{type:"string",description:"Text pattern to search for (case-insensitive substring match)."},sessions:{type:"number",description:'Number of recent sessions to scan (default: 20, max: 100). The result includes sessionsAvailable (sessions in this window before any since filter) and sessionsSearched (sessions actually read after the since filter) so you can distinguish "few sessions exist" from "the date filter excluded most of them".'},kinds:{type:"array",items:{type:"string"},description:"Filter results to specific event kinds (same values as read_witness)."},since:{type:"string",description:"ISO date string \u2014 only search sessions modified after this date."},tool_name:{type:"string",description:'Filter tool_call events to only this tool name (e.g. "bash", "edit_file"). Non-tool_call events are excluded when set.'}},required:["query"]}}});var km,Jk=g(()=>{"use strict";km={name:"cancel_background_job",category:"subagent",concurrencySafe:!1,description:'Cancel a running background subagent job that this model created with the agent tool in mode="background". Use when new context makes an in-flight model-dispatched job obsolete or harmful to continue. Do not use for jobs backgrounded by the user with Ctrl+B: those are user-owned and this tool will refuse; ask the user to run /bgsub:cancel instead. A concrete reason is required and is recorded in the witness trace. Completed, failed, or already-cancelled jobs return an informative non-error result.',input_schema:{type:"object",properties:{jobId:{type:"string",description:"The background job id returned by an earlier agent call in background mode."},reason:{type:"string",description:"Required explanation of why the running job is now obsolete or should stop."}},required:["jobId","reason"]}}});var Yk=g(()=>{"use strict";Jk()});var BH,jH,HH,WH,KH,GH,qH,XH,zH,VH,Ye,rr,or,JH,YH,QH,ZH,eW,tW,nW,rW,oW,sW,iW,aW,cW,lW,Lt,wt,uoe,st=g(()=>{"use strict";Vk();Yk();BH={name:"bash",category:"shell",concurrencySafe:!1,description:"Execute a shell command and return its stdout and stderr. Use for running programs, installing packages, git operations, and any task that requires a shell. Commands run through /bin/sh (Node spawn with shell:true) \u2014 NOT bash and NOT your $SHELL; /bin/sh is bash-in-POSIX-mode on macOS but dash on Debian/Ubuntu. Only process substitution <(...) reliably fails closed (exit 2, nothing runs). Other bashisms are nonportable and are NOT dependable refusals: [[ ]] runs on macOS but is a not-found command on dash while the rest of the line still executes; {a,b} expands on macOS but passes through literally on dash (silently wrong argument); arrays run on macOS but are a syntax error on dash. So never assume a bashism-containing command was side-effect-free \u2014 prefer a temp file or a POSIX equivalent. Long-running commands should use timeout_ms. Output is capped to a ~100KB head+tail view (the start and end are kept, the middle elided with a notice), so the command still runs to completion and you keep the real exit code and the tail (test/build summaries, final errors). For the full body of a verbose command, filter it (`| tail -n`, `--quiet`, narrower flags) or redirect to a file and read slices. Commands emitting extreme output (>8MB) are terminated. For reading or writing files \u2014 especially anything sensitive \u2014 prefer the typed file tools (read_file, write_file, edit_file): they support per-call user approval, and interpreter one-liners (python -c, node -e, sh -c, ...) that reference credential paths (SSH keys, cloud credentials, /etc/shadow) are blocked by the path-approval policy on interactive surfaces.",input_schema:{type:"object",properties:{command:{type:"string",description:"The shell command to execute."},timeout_ms:{type:"number",description:"Optional timeout in milliseconds (default 120000, max 600000). The command is killed if it exceeds this duration."}},required:["command"]}},jH={name:"read_file",category:"read",concurrencySafe:!0,description:"Read a file from the filesystem. Returns the file content with line numbers. Use offset and limit to read specific sections of large files. When the read returns a partial view, the response ends with a `... (showing lines X-Y of Z [\u2014 pass offset=N to continue])` annotation indicating the full file size and how to continue. Binary files are detected and rejected \u2014 use extract_document for .docx, .pdf, .xlsx, .pptx, and .zip files. Missing files return an error.",input_schema:{type:"object",properties:{file_path:{type:"string",description:"Absolute path to the file to read."},offset:{type:"number",description:"Line number to start reading from (1-based). Defaults to 1."},limit:{type:"number",description:"Maximum number of lines to read. Defaults to 2000."}},required:["file_path"]}},HH={name:"extract_document",category:"read",concurrencySafe:!0,description:'Extract text from binary document formats that read_file rejects. Supports .docx, .xlsx, .pptx (Office/OOXML \u2014 zero external dependencies), .pdf (requires pdftotext from poppler-utils; emits install instructions if missing), and .zip (lists members and extracts text-file contents). Use this when read_file reports "File appears to be binary" on a document you need to read. Returns plain text extracted from the document. Security: 4 MB decompression cap, zip-slip path containment, no shell execution. Output is capped at 512 KB of text; larger documents are truncated with a marker.',input_schema:{type:"object",properties:{file_path:{type:"string",description:"Absolute path to the document file to extract text from."}},required:["file_path"]}},WH={name:"write_file",category:"write",concurrencySafe:!1,description:"Write content to a file, creating it if it does not exist or overwriting if it does. Parent directories are created automatically. Prefer edit_file for modifying existing files \u2014 use write_file only for new files or complete rewrites.",input_schema:{type:"object",properties:{file_path:{type:"string",description:"Absolute path to the file to write."},content:{type:"string",description:"The full content to write to the file."}},required:["file_path","content"]}},KH={name:"edit_file",category:"write",concurrencySafe:!1,description:"Perform an exact string replacement in a file. Finds old_string and replaces it with new_string. The edit fails if old_string is not found or matches multiple locations (unless replace_all is true). Always use read_file first to verify the exact content before editing.",input_schema:{type:"object",properties:{file_path:{type:"string",description:"Absolute path to the file to edit."},old_string:{type:"string",description:"The exact string to find and replace. Must match file content exactly."},new_string:{type:"string",description:"The replacement string."},replace_all:{type:"boolean",description:"If true, replace all occurrences. If false (default), fail when multiple matches exist."}},required:["file_path","old_string","new_string"]}},GH={name:"glob",category:"read",concurrencySafe:!0,description:'Find files matching a glob pattern. Returns matching file paths, capped at 500 results. Use for discovering files before reading them. Patterns follow standard glob syntax (e.g., "src/**/*.ts", "*.json"). Skips node_modules/.git/.hg/.svn by default; name such a directory literally in the pattern (e.g. "node_modules/**/*.js") to search it.',input_schema:{type:"object",properties:{pattern:{type:"string",description:'Glob pattern to match (e.g., "src/**/*.ts").'},path:{type:"string",description:"Base directory to search from. Defaults to the current working directory."}},required:["pattern"]}},qH={name:"grep",category:"read",concurrencySafe:!0,description:"Search file contents for lines matching a pattern. Returns matches in file:line:content format. Runs on ripgrep: `|` `+` `?` `(` `)` `{` `}` are regex metacharacters by default (e.g. `foo|bar` alternates, matching either branch) \u2014 escape with a backslash for the literal character. Honors .gitignore (so build/dependency dirs like node_modules are skipped) but DOES search hidden files/dirs like .github and .env; the .git directory and binary files are skipped. Output is capped to a ~100KB head+tail view; if a search is truncated, narrow it (a more specific pattern, an `include` glob, or a subdirectory `path`) rather than re-running the same broad query. Use for finding symbols, strings, or patterns across the codebase.",input_schema:{type:"object",properties:{pattern:{type:"string",description:'Search pattern (ripgrep regex syntax). `|` `+` `?` `(` `)` `{` `}` are metacharacters \u2014 e.g. `foo|bar` matches either "foo" or "bar". Escape with a backslash (e.g. `\\|`) to match the literal character.'},path:{type:"string",description:"Directory or file to search. Defaults to current working directory."},include:{type:"string",description:'File glob to restrict search (e.g., "*.ts"). Passed as -g to ripgrep.'}},required:["pattern"]}},XH={name:"list_directory",category:"read",concurrencySafe:!0,description:"List the contents of a directory. Returns file and subdirectory names with type annotations (directories end with /). Use for exploring project structure.",input_schema:{type:"object",properties:{path:{type:"string",description:"Absolute path to the directory to list."}},required:["path"]}},zH={name:"send_telegram",category:"web",concurrencySafe:!1,riskClass:"caution",description:'Send a Telegram message to the operator. Use to surface terminal-state notifications, blocking questions, or important status updates when the user is away from keyboard (AFK). The message is delivered through the same Telegram bot the operator uses to drive this session. By default the message goes to your primary chat (the first private chat in `AFK_TELEGRAM_ALLOWED_CHAT_IDS`, or `AFK_TELEGRAM_PRIMARY_CHAT_ID` if set); set `telegram.notify` in afk.config.json to broadcast to all allowed chats or target a custom set.\n\nPlain text only \u2014 Telegram\'s 4096-character limit per message is enforced. Returns an error if Telegram is not configured (missing `TELEGRAM_BOT_TOKEN` or empty allowlist) so the tool is safe to attempt unconditionally.\n\nUse sparingly: this is a real push notification to a human. Reserve for terminal states (Done/Blocked/Asking) and material progress, not running commentary. When running inside the Telegram bot, prefer replying normally \u2014 your response already reaches the operator through the bot. Use this tool only from CLI or daemon sessions.\n\nOptionally set `chat` to route to a SPECIFIC chat instead of the default primary target: pass a numeric chat id (e.g. -1001234567890 for a group) or a chat alias name defined in afk.config.json `telegram.chatAliases` (e.g. "ops"). An explicitly-targeted chat must be in the inbound allowlist (AFK_TELEGRAM_ALLOWED_CHAT_IDS) \u2014 a non-allowlisted target is rejected (fail-closed). Omit `chat` for the default behavior (unchanged).\n\nFor supergroups with topics enabled, set `thread_id` alongside `chat` to send to a specific topic thread.',input_schema:{type:"object",properties:{message:{type:"string",description:"Plain-text message body to send to the operator. Max 4096 characters (Telegram API limit). Must be non-empty."},chat:{type:["number","string"],description:"Optional. Target a specific chat instead of the default primary target. A number (or numeric string) is a raw Telegram chat id; a non-numeric string is looked up as a name in afk.config.json `telegram.chatAliases`. The resolved chat must be allowlisted (AFK_TELEGRAM_ALLOWED_CHAT_IDS) or the send is rejected. Omit to send to the configured default (primary DM chat / notify targets)."},thread_id:{type:"number",description:"Optional. Telegram message_thread_id for sending to a specific topic in a supergroup with topics enabled. Pass the numeric thread/topic ID. Ignored when the target chat is not a supergroup with topics. Requires `chat` to be set explicitly (thread targeting without a chat target is ambiguous)."}},required:["message"]}},VH={name:"web_scrape",category:"web",concurrencySafe:!0,description:'Scrape a web page or run a web search and return text content suitable for reasoning over. Three modes:\n\n- `markdown` (default): fetches the URL and extracts the main content as clean markdown (Readability + Turndown). Handles JS-rendered pages: if the plain fetch yields thin content, it escalates to a headless-browser render and re-extracts. Use this for articles, docs, blog posts, and most "I want to read this page" cases. No API key required (the render fallback needs the Playwright chromium binary; if it is absent the error names the exact install command for this installation).\n- `raw`: GETs the URL directly and returns the response body as decoded text, with no markdown transformation. Use for JSON APIs, robots.txt, RSS, or plain-text endpoints. Not byte-preserving \u2014 binary payloads are decoded as text, so do not rely on this for exact bytes. No API key required.\n- `search`: runs a web search and returns ranked markdown results. Use when you need to FIND a URL, not read one. Provide `query` instead of `url`. Requires `EXA_API_KEY` (free tier at https://exa.ai); the handler returns a clear error if it is unset.\n\nOutputs are capped at `max_bytes` UTF-8 bytes (default 100KB, ceiling 1MB); content over the cap is reduced to head+tail with a `\u2026 [N bytes truncated: \u2026] \u2026` marker so both ends survive. The request is aborted after `timeout_ms` (default 30000, ceiling 120000).',input_schema:{type:"object",properties:{mode:{type:"string",enum:["markdown","raw","search"],description:'Fetch mode. Defaults to "markdown".'},url:{type:"string",description:"Absolute http(s) URL. Required for markdown and raw modes. Ignored in search mode."},query:{type:"string",description:"Search query string. Required for search mode. Ignored otherwise."},timeout_ms:{type:"number",description:"Request timeout in milliseconds (default 30000, clamped to 120000)."},max_bytes:{type:"number",description:"Maximum UTF-8 bytes returned. Content beyond this is reduced to head+tail with a truncation marker (both ends preserved). Default 100000, clamped to 1000000."}},required:[]}},Ye={name:"agent",category:"subagent",concurrencySafe:!0,description:`Dispatch an independent subagent with its own context window and tool access. Use for tasks that protect the main session's context: codebase exploration, multi-file inspection, repo search, verification, debugging, failing-test investigation, PR review, parallel hypothesis testing, independent re-derivation of a claim, audit work, stale-path detection, feature-wiring checks, and any research-shaped investigation.
|
|
230
234
|
|
|
231
235
|
Parallelize: dispatch multiple \`agent\` calls in a single tool-use turn to run independent investigations concurrently.
|
|
232
236
|
|
|
@@ -254,7 +258,7 @@ ${n}
|
|
|
254
258
|
Remedy: these paths are outside the fork's granted read roots. Re-dispatch with the needed paths inside the child's cwd/worktree, or pass explicit readRoots granting them. If this worker is deliberately confined (e.g. an \`afk farm\` branch worker), this failure is expected \u2014 the paths are outside its assigned scope; widen the scope or narrow the task.`}var to,c_,Fm,oi=g(()=>{"use strict";to="denial-breaker",c_=new Set(["read_file","list_directory","glob","grep"]),Fm="Sub-agent path access denied:"});import{createHash as AW}from"node:crypto";function p_(){return{recent:[],firedFingerprints:new Set}}function gl(t){let e;try{e=TW(t.input)}catch{e=String(t.input)}return AW("sha256").update(t.name).update("\0").update(e).digest("hex")}function TW(t){return JSON.stringify(Lm(t))??"null"}function Lm(t){if(Array.isArray(t))return t.map(Lm);if(t!==null&&typeof t=="object"){let e=t,n={};for(let r of Object.keys(e).sort())n[r]=Lm(e[r]);return n}return t}function RW(t,e){let n=0;for(let r of t)r===e&&(n+=1);return n}function f_(t,e){t.recent.push(e),t.recent.length>Nm&&t.recent.shift();let n=RW(t.recent,e);return n>=EW&&!t.firedFingerprints.has(e)?(t.firedFingerprints.add(e),{fired:!0,count:n}):{fired:!1,count:n}}var EW,Nm,Um=g(()=>{"use strict";EW=5,Nm=20});function IW(t){if(t===null||typeof t!="object"||Array.isArray(t))return t;let e={};for(let[n,r]of Object.entries(t))xW.has(n)||(e[n]=r);return e}function si(t){return gl({...t,input:IW(t.input)})}function CW(t){let e=t.content.split(`
|
|
255
259
|
`).find(n=>n.trim()!=="")?.trim()??"";return e.length<=m_?e:`${e.slice(0,m_)}\u2026`}var $m,xW,m_,hl,Bm=g(()=>{"use strict";Um();$m=3,xW=new Set(["timeout_ms","timeoutMs","timeout"]),m_=240;hl=class{streaks=new Map;check(e){let n=this.streaks.get(si(e));return n===void 0||n.count<$m?null:{count:n.count,tool:e.name,result:{content:`Repeat-failure guard: "${e.name}" has already failed ${n.count} times in a row with the same arguments, so this call was NOT executed again. The last failure was: ${n.lastError}
|
|
256
260
|
|
|
257
|
-
Retrying it verbatim will fail the same way. Fix the underlying cause, change the arguments, use a different tool, or stop and report the blocker.`,isError:!0,failureClass:"repeat-failure"}}}note(e,n){let r=si(e);if(n.isError!==!0){this.streaks.delete(r);return}let o=this.streaks.get(r);this.streaks.set(r,{count:(o?.count??0)+1,lastError:CW(n)})}streakFor(e){return this.streaks.get(si(e))?.count??0}}});async function no(t,e,n){let r=new Array(t.length),o=Math.min(Math.max(1,Math.floor(e)),t.length),s=0,i=[];for(let a=0;a<o;a++)i.push((async()=>{for(;s<t.length;){let c=s++;try{r[c]={status:"fulfilled",value:await n(t[c])}}catch(l){r[c]={status:"rejected",reason:l}}}})());return await Promise.all(i),r}var yl=g(()=>{"use strict";Qc()});function g_(t,e,n){if(n.has(t.name))return null;let r=e.check(t);return r===null?null:(O(`[repeat-failure-guard #723] refused ${r.tool} after ${r.count} identical failures`),r.result)}async function PW(t,e,n){let{call:r,originalIndex:o}=e[t];return r.signal.aborted?{result:{content:"Tool call aborted",isError:!0,failureClass:Pe(r.signal)},originalIndex:o}:{result:await n(r),originalIndex:o}}function MW(t,e,n,r){for(let o of t)if(o.status==="fulfilled")r[o.value.originalIndex]=o.value.result;else{let s=o.reason instanceof Error?o.reason.message:String(o.reason),i=e[t.indexOf(o)];r[n[i].originalIndex]={content:`Tool execution error: ${s}`,isError:!0}}}function h_(t,e,n){let r=t.indices.length;for(let o=0;o<t.indices.length;o++){let s=t.indices[o],i=n[e[s].originalIndex];i&&(i.batchIndex=o+1,i.batchSize=r)}}async function y_(t,e,n,r){let o=[...t.indices];for(;o.length>0;){let s=new Map,i=[],a=[];for(let d of o){let{call:u,originalIndex:p}=e[d],f=g_(u,r.repeatFailureGuard,r.repeatBreakerExemptTools);if(f){n[p]=f;continue}if(r.repeatBreakerExemptTools.has(u.name)){i.push(d);continue}let m=si(u),h=$m-r.repeatFailureGuard.streakFor(u),y=s.get(m)??0;y<h?(s.set(m,y+1),i.push(d)):a.push(d)}o=a;let c=i.map(d=>e[d]?.call).filter(d=>d!==void 0&&d.name==="agent");if(c.length>=2&&r.subagentExecutor)try{r.subagentExecutor.notifyWaveStart(c,r.sessionId??"",null)}catch{}let l=await no(i,r.maxConcurrentSafeCalls,d=>PW(d,e,r.executeCore));MW(l,i,e,n);for(let d of i){let{call:u,originalIndex:p}=e[d],f=n[p];f!==void 0&&f.failureClass!=="abort"&&r.repeatFailureGuard.note(u,f)}if(c.length>=2&&r.subagentExecutor)try{r.subagentExecutor.notifyWaveEnd()}catch{}}}async function b_(t,e,n,r){for(let o of t.indices){let{call:s,originalIndex:i}=e[o];if(s.signal.aborted){n[i]={content:"Tool call aborted",isError:!0,failureClass:Pe(s.signal)};continue}let a=g_(s,r.repeatFailureGuard,r.repeatBreakerExemptTools);if(a){n[i]=a;continue}let c=await r.executeCore(s);n[i]=c,r.repeatFailureGuard.note(s,c)}}var w_=g(()=>{"use strict";bn();yl();se();Bm()});function S_(t){return t==="agent"||t==="cancel_background_job"}async function v_(t,e){if(!t)return{result:{content:e.name==="agent"?"Agent tool is not available in this session configuration":"Background mode is not available in this session configuration",isError:!0}};try{return{result:e.name==="agent"?await t.execute(e):await t.cancelBackgroundJob(e)}}catch(n){let r=n instanceof Error?n.message:String(n);return{result:{content:`${e.name==="agent"?"Agent":"Background cancellation"} tool error: ${r}`,isError:!0},thrownMessage:r}}}var k_=g(()=>{"use strict"});var DW,jm,Nt,bl=g(()=>{"use strict";Qc();se();re();bn();nl();sl();vm();wn();Vc();V();Dm();a_();oi();Um();Bm();w_();k_();Dm();DW=8,jm=new Set,Nt=class{handlers;schemas;hookRegistry;permissions;canUseTool;subagentExecutor;skillExecutor;composeExecutor;classifier;maxConcurrentSafeCalls;resolveBase;_readRoots;_writeRoots;_allowAll;_env;sessionId;parentSessionId;subagentId;sessionGrantManager;traceWriter;readOnlyBash;maxOutputBytes;repeatBreaker=null;repeatFailureGuard=new hl;denialBreaker=null;suspectedLoopWindow=null;grantManager;constructor(e){this.handlers=e.handlers,this.schemas=e.schemas,this.hookRegistry=e.hookRegistry,this.permissions=e.permissions,this.canUseTool=e.canUseTool,this.subagentExecutor=e.subagentExecutor,this.skillExecutor=e.skillExecutor,this.composeExecutor=e.composeExecutor,this.classifier=e.concurrencyClassifier??Om,this.maxConcurrentSafeCalls=typeof e.maxConcurrentSafeCalls=="number"&&Number.isFinite(e.maxConcurrentSafeCalls)&&e.maxConcurrentSafeCalls>=1?Math.floor(e.maxConcurrentSafeCalls):Ek(),this.resolveBase=e.cwd,this._env=e.env,this.sessionId=e.sessionId,this.parentSessionId=e.parentSessionId,this.subagentId=e.subagentId,this.sessionGrantManager=e.sessionGrantManager,this.traceWriter=e.traceWriter,this.readOnlyBash=e.readOnlyBash===!0,this.maxOutputBytes=typeof e.maxOutputBytes=="number"&&Number.isFinite(e.maxOutputBytes)&&e.maxOutputBytes>0?e.maxOutputBytes:void 0,this._allowAll=e.allowAll===!0;let n=e.cwd?[e.cwd]:[];this._readRoots=e.readRoots??n.slice(),this._writeRoots=e.writeRoots??n.slice(),this.grantManager=new yn({getReadRoots:()=>this._readRoots,getWriteRoots:()=>this._writeRoots,getProtectedRoot:()=>this.resolveBase,getAllowAll:()=>this._allowAll,getDefaultSessionId:()=>this.sessionId})}get handlerContext(){return{cwd:this.resolveBase,resolveBase:this.resolveBase,readRoots:this._readRoots.slice(),writeRoots:this._writeRoots.slice(),...this._allowAll?{allowAll:!0}:{},...this._env!==void 0?{env:this._env}:{},...this.sessionId!==void 0?{sessionId:this.sessionId}:{}}}callHandlerContext(e){return{...this.handlerContext,toolUseId:e.id,...this.traceWriter!==void 0?{traceWriter:this.traceWriter}:{}}}addReadRoot(e,n="slash"){this.grantManager.addReadRoot(e,n)}addWriteRoot(e,n="slash"){this.grantManager.addWriteRoot(e,n)}revokeRoot(e,n="slash"){this.grantManager.revokeRoot(e,n)}getGrants(){return this.grantManager.getGrants()}setAllowAll(e){this._allowAll=e}setResolveBase(e){let n=this.resolveBase;if(n!==e){if(this.resolveBase=e,n!==void 0){let r=this._readRoots.indexOf(n);r!==-1?this._readRoots[r]=e:this._readRoots.includes(e)||this._readRoots.push(e);let o=this._writeRoots.indexOf(n);o!==-1?this._writeRoots[o]=e:this._writeRoots.includes(e)||this._writeRoots.push(e)}else this._readRoots.includes(e)||this._readRoots.push(e),this._writeRoots.includes(e)||this._writeRoots.push(e);this.subagentExecutor?.setCwd(e),this.skillExecutor?.setCwd(e),this.composeExecutor?.setCwd(e)}}get toolDefs(){let e=this.subagentExecutor?.supportsBackgroundJobs?.()?this.schemas:this.schemas.filter(o=>o.name!=="cancel_background_job"),n=this.permissions?.allowedTools;if(!n)return e;let r=new Set(n);return e.filter(o=>r.has(o.name))}denialReason(e,n){return this.isRegisteredTool(e)?n??`Tool "${e}" is not permitted`:this.unknownToolMessage(e)}isRegisteredTool(e){return this.handlers.has(e)||e==="agent"&&this.subagentExecutor!==void 0||e==="cancel_background_job"&&this.subagentExecutor?.supportsBackgroundJobs?.()===!0||e==="skill"&&this.skillExecutor!==void 0||e==="compose"&&this.composeExecutor!==void 0}unknownToolMessage(e){let n=this.toolDefs.map(o=>o.name).join(", "),r=n.length>0?`Available tools: ${n}. Do NOT retry "${e}" or a variant of it; use one of the tools listed above.`:`Do NOT retry "${e}" or a variant of it.`;return`Unknown tool "${e}" \u2014 it does not exist in this session. ${r}`}async checkReadOnlyBash(e){if(!this.readOnlyBash||e.name!=="bash")return null;let n=e.input,r=typeof n=="object"&&n!==null?n.command:void 0;if(typeof r!="string")return null;let o=cl(r);if(!o.mutating)return null;let s=`Bash command blocked: read-only skill may not run mutating commands (${o.reason??"mutation detected"}). Allowed: read-only recon (git status/log/diff/show/ls-remote, ls, cat, find, grep, gh pr view/diff). For a remote ref you have not fetched, \`gh pr diff <n>\`, \`gh pr view <n>\` and \`git ls-remote\` need no local ref \u2014 \`git fetch\` is blocked. Do NOT retry variants of a blocked command: if the task genuinely requires a mutation, stop and report that requirement to your caller instead.`;return await this.emitPreToolUseBlock(e.name,s),{content:s,isError:!0,failureClass:"permission-denied"}}async emitPreToolUseBlock(e,n){await ot(this.traceWriter,{hookEvent:"PreToolUse",decision:"block",blockedTool:e,reason:n,...this.subagentId!==void 0?{subagentId:this.subagentId}:{}})}checkRepeatCircuitBreaker(e){if(jm.has(e.name))return null;let n=i_(e);return this.repeatBreaker!==null&&this.repeatBreaker.fingerprint===n?this.repeatBreaker.count+=1:this.repeatBreaker={fingerprint:n,count:1},this.repeatBreaker.count<DW?null:{content:`Loop circuit breaker: "${e.name}" has been called ${this.repeatBreaker.count} times in a row with byte-identical input. The result will not change. Stop repeating this call \u2014 reuse the previous result, change the input, try a different tool, or end the turn.`,isError:!0,circuitBreaker:!0}}checkRepeatFailureGuard(e){if(jm.has(e.name))return null;let n=this.repeatFailureGuard.check(e);return n===null?null:(O(`[repeat-failure-guard #723] refused ${n.tool} after ${n.count} identical failures`),n.result)}observeSuspectedLoop(e){if(this.parentSessionId===void 0)return;this.suspectedLoopWindow===null&&(this.suspectedLoopWindow=p_());let n=gl(e),r=f_(this.suspectedLoopWindow,n);r.fired&&W(this.traceWriter,{phase:"suspected_loop",metadata:{tool:e.name,count:r.count,windowSize:Nm}})}recordForkReadDenial(e,n,r){if(this.parentSessionId===void 0||!c_.has(e.name)||!l_(n))return r;let o=this.denialBreaker??{count:0,deniedPaths:[]};o.count+=1;let s=d_(e);return o.deniedPaths.includes(s)||o.deniedPaths.push(s),this.denialBreaker=o,o.count<5?r:{content:u_(o.deniedPaths,o.count),isError:!0,failureClass:to}}resetDenialBreaker(){this.denialBreaker=null}async runCanUseTool(e){if(!this.canUseTool)return null;let n;try{n=await this.canUseTool(e.name,e.input??{},{signal:e.signal,toolUseID:e.id})}catch(r){let o=`Tool "${e.name}" denied by canUseTool (threw): ${r instanceof Error?r.message:String(r)}`;return await this.emitPreToolUseBlock(e.name,o),{content:o,isError:!0,failureClass:"permission-denied"}}if(n.behavior==="deny"){let r=n.message||`Tool "${e.name}" denied by permission policy`;return await this.emitPreToolUseBlock(e.name,r),{content:r,isError:!0,failureClass:"permission-denied"}}return n.updatedInput!==void 0&&(e.input=n.updatedInput),null}async runPreDispatchGates(e){if(this.hookRegistry){let a={event:"PreToolUse",toolName:e.name,input:e.input,...this.sessionId!==void 0?{sessionId:this.sessionId}:{},...this.resolveBase!==void 0?{cwd:this.resolveBase}:{},...this.parentSessionId!==void 0?{parentSessionId:this.parentSessionId}:{},...this.sessionGrantManager!==void 0?{grantManager:this.sessionGrantManager}:{},...e.id!==void 0?{toolUseId:e.id}:{}};try{await Fk(this.hookRegistry,a,{signal:e.signal,...this.traceWriter?{traceWriter:this.traceWriter}:{}})}catch(c){if(c instanceof Y)return this.recordForkReadDenial(e,c.reason,{content:`Tool "${e.name}" blocked by PreToolUse hook${c.reason?`: ${c.reason}`:""}${c.injectContext?`
|
|
261
|
+
Retrying it verbatim will fail the same way. Fix the underlying cause, change the arguments, use a different tool, or stop and report the blocker.`,isError:!0,failureClass:"repeat-failure"}}}note(e,n){let r=si(e);if(n.isError!==!0){this.streaks.delete(r);return}let o=this.streaks.get(r);this.streaks.set(r,{count:(o?.count??0)+1,lastError:CW(n)})}streakFor(e){return this.streaks.get(si(e))?.count??0}}});async function no(t,e,n){let r=new Array(t.length),o=Math.min(Math.max(1,Math.floor(e)),t.length),s=0,i=[];for(let a=0;a<o;a++)i.push((async()=>{for(;s<t.length;){let c=s++;try{r[c]={status:"fulfilled",value:await n(t[c])}}catch(l){r[c]={status:"rejected",reason:l}}}})());return await Promise.all(i),r}var yl=g(()=>{"use strict";Qc()});function g_(t,e,n){if(n.has(t.name))return null;let r=e.check(t);return r===null?null:(O(`[repeat-failure-guard #723] refused ${r.tool} after ${r.count} identical failures`),r.result)}async function PW(t,e,n){let{call:r,originalIndex:o}=e[t];return r.signal.aborted?{result:{content:"Tool call aborted",isError:!0,failureClass:Pe(r.signal)},originalIndex:o}:{result:await n(r),originalIndex:o}}function MW(t,e,n,r){for(let o of t)if(o.status==="fulfilled")r[o.value.originalIndex]=o.value.result;else{let s=o.reason instanceof Error?o.reason.message:String(o.reason),i=e[t.indexOf(o)];r[n[i].originalIndex]={content:`Tool execution error: ${s}`,isError:!0}}}function h_(t,e,n){let r=t.indices.length;for(let o=0;o<t.indices.length;o++){let s=t.indices[o],i=n[e[s].originalIndex];i&&(i.batchIndex=o+1,i.batchSize=r)}}async function y_(t,e,n,r){let o=[...t.indices];for(;o.length>0;){let s=new Map,i=[],a=[];for(let d of o){let{call:u,originalIndex:p}=e[d],f=g_(u,r.repeatFailureGuard,r.repeatBreakerExemptTools);if(f){n[p]=f;continue}if(r.repeatBreakerExemptTools.has(u.name)){i.push(d);continue}let m=si(u),h=$m-r.repeatFailureGuard.streakFor(u),y=s.get(m)??0;y<h?(s.set(m,y+1),i.push(d)):a.push(d)}o=a;let c=i.map(d=>e[d]?.call).filter(d=>d!==void 0&&d.name==="agent");if(c.length>=2&&r.subagentExecutor)try{r.subagentExecutor.notifyWaveStart(c,r.sessionId??"",null)}catch{}let l=await no(i,r.maxConcurrentSafeCalls,d=>PW(d,e,r.executeCore));MW(l,i,e,n);for(let d of i){let{call:u,originalIndex:p}=e[d],f=n[p];f!==void 0&&f.failureClass!=="abort"&&r.repeatFailureGuard.note(u,f)}if(c.length>=2&&r.subagentExecutor)try{r.subagentExecutor.notifyWaveEnd()}catch{}}}async function b_(t,e,n,r){for(let o of t.indices){let{call:s,originalIndex:i}=e[o];if(s.signal.aborted){n[i]={content:"Tool call aborted",isError:!0,failureClass:Pe(s.signal)};continue}let a=g_(s,r.repeatFailureGuard,r.repeatBreakerExemptTools);if(a){n[i]=a;continue}let c=await r.executeCore(s);n[i]=c,r.repeatFailureGuard.note(s,c)}}var w_=g(()=>{"use strict";bn();yl();se();Bm()});function S_(t){return t==="agent"||t==="cancel_background_job"}async function v_(t,e){if(!t)return{result:{content:e.name==="agent"?"Agent tool is not available in this session configuration":"Background mode is not available in this session configuration",isError:!0}};try{return{result:e.name==="agent"?await t.execute(e):await t.cancelBackgroundJob(e)}}catch(n){let r=n instanceof Error?n.message:String(n);return{result:{content:`${e.name==="agent"?"Agent":"Background cancellation"} tool error: ${r}`,isError:!0},thrownMessage:r}}}var k_=g(()=>{"use strict"});var DW,jm,Nt,bl=g(()=>{"use strict";Qc();se();re();bn();nl();sl();vm();wn();Vc();V();Dm();a_();oi();Um();Bm();w_();k_();Dm();DW=8,jm=new Set,Nt=class{handlers;schemas;hookRegistry;permissions;canUseTool;subagentExecutor;skillExecutor;composeExecutor;classifier;maxConcurrentSafeCalls;resolveBase;_readRoots;_writeRoots;_allowAll;_env;sessionId;parentSessionId;subagentId;sessionGrantManager;traceWriter;readOnlyBash;maxOutputBytes;repeatBreaker=null;repeatFailureGuard=new hl;denialBreaker=null;suspectedLoopWindow=null;grantManager;constructor(e){this.handlers=e.handlers,this.schemas=e.schemas,this.hookRegistry=e.hookRegistry,this.permissions=e.permissions,this.canUseTool=e.canUseTool,this.subagentExecutor=e.subagentExecutor,this.skillExecutor=e.skillExecutor,this.composeExecutor=e.composeExecutor,this.classifier=e.concurrencyClassifier??Om,this.maxConcurrentSafeCalls=typeof e.maxConcurrentSafeCalls=="number"&&Number.isFinite(e.maxConcurrentSafeCalls)&&e.maxConcurrentSafeCalls>=1?Math.floor(e.maxConcurrentSafeCalls):Ek(),this.resolveBase=e.cwd,this._env=e.env,this.sessionId=e.sessionId,this.parentSessionId=e.parentSessionId,this.subagentId=e.subagentId,this.sessionGrantManager=e.sessionGrantManager,this.traceWriter=e.traceWriter,this.readOnlyBash=e.readOnlyBash===!0,this.maxOutputBytes=typeof e.maxOutputBytes=="number"&&Number.isFinite(e.maxOutputBytes)&&e.maxOutputBytes>0?e.maxOutputBytes:void 0,this._allowAll=e.allowAll===!0;let n=e.cwd?[e.cwd]:[];this._readRoots=e.readRoots??n.slice(),this._writeRoots=e.writeRoots??n.slice(),this.grantManager=new yn({getReadRoots:()=>this._readRoots,getWriteRoots:()=>this._writeRoots,getProtectedRoot:()=>this.resolveBase,getAllowAll:()=>this._allowAll,getDefaultSessionId:()=>this.sessionId})}get handlerContext(){return{cwd:this.resolveBase,resolveBase:this.resolveBase,readRoots:this._readRoots.slice(),writeRoots:this._writeRoots.slice(),...this._allowAll?{allowAll:!0}:{},...this._env!==void 0?{env:this._env}:{},...this.sessionId!==void 0?{sessionId:this.sessionId}:{}}}callHandlerContext(e){return{...this.handlerContext,toolUseId:e.id,...this.traceWriter!==void 0?{traceWriter:this.traceWriter}:{}}}addReadRoot(e,n="slash",r){this.grantManager.addReadRoot(e,n,r)}addWriteRoot(e,n="slash",r){this.grantManager.addWriteRoot(e,n,r)}revokeRoot(e,n="slash",r){this.grantManager.revokeRoot(e,n,r)}getGrants(){return this.grantManager.getGrants()}setAllowAll(e){this._allowAll=e}setResolveBase(e){let n=this.resolveBase;if(n!==e){if(this.resolveBase=e,n!==void 0){let r=this._readRoots.indexOf(n);r!==-1?this._readRoots[r]=e:this._readRoots.includes(e)||this._readRoots.push(e);let o=this._writeRoots.indexOf(n);o!==-1?this._writeRoots[o]=e:this._writeRoots.includes(e)||this._writeRoots.push(e)}else this._readRoots.includes(e)||this._readRoots.push(e),this._writeRoots.includes(e)||this._writeRoots.push(e);this.subagentExecutor?.setCwd(e),this.skillExecutor?.setCwd(e),this.composeExecutor?.setCwd(e)}}get toolDefs(){let e=this.subagentExecutor?.supportsBackgroundJobs?.()?this.schemas:this.schemas.filter(o=>o.name!=="cancel_background_job"),n=this.permissions?.allowedTools;if(!n)return e;let r=new Set(n);return e.filter(o=>r.has(o.name))}denialReason(e,n){return this.isRegisteredTool(e)?n??`Tool "${e}" is not permitted`:this.unknownToolMessage(e)}isRegisteredTool(e){return this.handlers.has(e)||e==="agent"&&this.subagentExecutor!==void 0||e==="cancel_background_job"&&this.subagentExecutor?.supportsBackgroundJobs?.()===!0||e==="skill"&&this.skillExecutor!==void 0||e==="compose"&&this.composeExecutor!==void 0}unknownToolMessage(e){let n=this.toolDefs.map(o=>o.name).join(", "),r=n.length>0?`Available tools: ${n}. Do NOT retry "${e}" or a variant of it; use one of the tools listed above.`:`Do NOT retry "${e}" or a variant of it.`;return`Unknown tool "${e}" \u2014 it does not exist in this session. ${r}`}async checkReadOnlyBash(e){if(!this.readOnlyBash||e.name!=="bash")return null;let n=e.input,r=typeof n=="object"&&n!==null?n.command:void 0;if(typeof r!="string")return null;let o=cl(r);if(!o.mutating)return null;let s=`Bash command blocked: read-only skill may not run mutating commands (${o.reason??"mutation detected"}). Allowed: read-only recon (git status/log/diff/show/ls-remote, ls, cat, find, grep, gh pr view/diff). For a remote ref you have not fetched, \`gh pr diff <n>\`, \`gh pr view <n>\` and \`git ls-remote\` need no local ref \u2014 \`git fetch\` is blocked. Do NOT retry variants of a blocked command: if the task genuinely requires a mutation, stop and report that requirement to your caller instead.`;return await this.emitPreToolUseBlock(e.name,s),{content:s,isError:!0,failureClass:"permission-denied"}}async emitPreToolUseBlock(e,n){await ot(this.traceWriter,{hookEvent:"PreToolUse",decision:"block",blockedTool:e,reason:n,...this.subagentId!==void 0?{subagentId:this.subagentId}:{}})}checkRepeatCircuitBreaker(e){if(jm.has(e.name))return null;let n=i_(e);return this.repeatBreaker!==null&&this.repeatBreaker.fingerprint===n?this.repeatBreaker.count+=1:this.repeatBreaker={fingerprint:n,count:1},this.repeatBreaker.count<DW?null:{content:`Loop circuit breaker: "${e.name}" has been called ${this.repeatBreaker.count} times in a row with byte-identical input. The result will not change. Stop repeating this call \u2014 reuse the previous result, change the input, try a different tool, or end the turn.`,isError:!0,circuitBreaker:!0}}checkRepeatFailureGuard(e){if(jm.has(e.name))return null;let n=this.repeatFailureGuard.check(e);return n===null?null:(O(`[repeat-failure-guard #723] refused ${n.tool} after ${n.count} identical failures`),n.result)}observeSuspectedLoop(e){if(this.parentSessionId===void 0)return;this.suspectedLoopWindow===null&&(this.suspectedLoopWindow=p_());let n=gl(e),r=f_(this.suspectedLoopWindow,n);r.fired&&W(this.traceWriter,{phase:"suspected_loop",metadata:{tool:e.name,count:r.count,windowSize:Nm}})}recordForkReadDenial(e,n,r){if(this.parentSessionId===void 0||!c_.has(e.name)||!l_(n))return r;let o=this.denialBreaker??{count:0,deniedPaths:[]};o.count+=1;let s=d_(e);return o.deniedPaths.includes(s)||o.deniedPaths.push(s),this.denialBreaker=o,o.count<5?r:{content:u_(o.deniedPaths,o.count),isError:!0,failureClass:to}}resetDenialBreaker(){this.denialBreaker=null}async runCanUseTool(e){if(!this.canUseTool)return null;let n;try{n=await this.canUseTool(e.name,e.input??{},{signal:e.signal,toolUseID:e.id})}catch(r){let o=`Tool "${e.name}" denied by canUseTool (threw): ${r instanceof Error?r.message:String(r)}`;return await this.emitPreToolUseBlock(e.name,o),{content:o,isError:!0,failureClass:"permission-denied"}}if(n.behavior==="deny"){let r=n.message||`Tool "${e.name}" denied by permission policy`;return await this.emitPreToolUseBlock(e.name,r),{content:r,isError:!0,failureClass:"permission-denied"}}return n.updatedInput!==void 0&&(e.input=n.updatedInput),null}async runPreDispatchGates(e){if(this.hookRegistry){let a={event:"PreToolUse",toolName:e.name,input:e.input,...this.sessionId!==void 0?{sessionId:this.sessionId}:{},...this.resolveBase!==void 0?{cwd:this.resolveBase}:{},...this.parentSessionId!==void 0?{parentSessionId:this.parentSessionId}:{},...this.sessionGrantManager!==void 0?{grantManager:this.sessionGrantManager}:{},...e.id!==void 0?{toolUseId:e.id}:{}};try{await Fk(this.hookRegistry,a,{signal:e.signal,...this.traceWriter?{traceWriter:this.traceWriter}:{}})}catch(c){if(c instanceof Y)return this.recordForkReadDenial(e,c.reason,{content:`Tool "${e.name}" blocked by PreToolUse hook${c.reason?`: ${c.reason}`:""}${c.injectContext?`
|
|
258
262
|
|
|
259
263
|
${c.injectContext}`:""}`,isError:!0,failureClass:"hook-block"});throw c}}let n=Uk(e.name,this.permissions);if(!n.allowed){let a=this.denialReason(e.name,n.reason);return await this.emitPreToolUseBlock(e.name,a),{content:a,isError:!0,failureClass:"permission-denied"}}let r=await this.runCanUseTool(e);if(r)return r;let o=await this.checkReadOnlyBash(e);if(o)return o;let s=this.checkRepeatCircuitBreaker(e);if(s)return s;let i=this.checkRepeatFailureGuard(e);return i||(this.observeSuspectedLoop(e),null)}async execute(e){if(e.signal.aborted)return{content:"Tool call aborted",isError:!0,failureClass:Pe(e.signal)};let n=await this.runPreDispatchGates(e);if(n)return n;let r=await this.executeCore(e);return this.repeatFailureGuard.note(e,r),r.isError!==!0&&this.resetDenialBreaker(),r}async executeBatch(e){if(e.length===0)return[];if(e.length===1)return[await this.execute(e[0])];let n=new Array(e.length),r=new Set;for(let a=0;a<e.length;a++){let c=e[a];if(c.signal.aborted){n[a]={content:"Tool call aborted",isError:!0,failureClass:Pe(c.signal)},r.add(a);continue}let l=await this.runPreDispatchGates(c);if(l){n[a]=l,r.add(a);continue}}let o=e.map((a,c)=>({call:a,originalIndex:c})).filter((a,c)=>!r.has(c));if(o.length===0)return n;let s=s_(o.map(a=>a.call),this.classifier),i={repeatFailureGuard:this.repeatFailureGuard,repeatBreakerExemptTools:jm,executeCore:a=>this.executeCore(a),subagentExecutor:this.subagentExecutor,sessionId:this.sessionId,maxConcurrentSafeCalls:this.maxConcurrentSafeCalls};for(let a of s)a.isConcurrencySafe?await y_(a,o,n,i):await b_(a,o,n,i),h_(a,o,n);return n.some(a=>a!==void 0&&a.isError!==!0)&&this.resetDenialBreaker(),n}async executeCore(e){let n=await this.executeCoreInner(e);return this.applyOutputCap(n)}applyOutputCap(e){let n=this.maxOutputBytes;if(n===void 0)return e;let r=Buffer.byteLength(e.content,"utf8");return r<=n||(e.content=tr(e.content,n),e.truncated=!0,O(`[output-cap #661] fork tool result capped: original=${r}B capped=${Buffer.byteLength(e.content,"utf8")}B (cap=${n}B)`)),e}async executeCoreInner(e){if(S_(e.name)){let i=await v_(this.subagentExecutor,e);return i.thrownMessage!==void 0?this.firePostToolUseFailure(e.name,i.thrownMessage,e.signal,e.input):this.firePostToolUse(e.name,i.result.content,e.signal,e.input,i.result),i.result}if(e.name==="skill"){if(!this.skillExecutor)return{content:"Skill tool is not available in this session configuration",isError:!0};let i,a=!1,c="";try{i=await this.skillExecutor.execute(e)}catch(l){a=!0,c=l instanceof Error?l.message:String(l),i={content:`Skill tool error: ${c}`,isError:!0}}return a?this.firePostToolUseFailure(e.name,c,e.signal,e.input):this.firePostToolUse(e.name,i.content,e.signal,e.input,i),i}if(e.name==="compose"){let i=await this.executeCompose(e);return this.firePostToolUse(e.name,i.content,e.signal,e.input,i),i}let n=this.handlers.get(e.name);if(!n){let i=this.unknownToolMessage(e.name);return await this.emitPreToolUseBlock(e.name,i),{content:i,isError:!0,failureClass:"permission-denied"}}let r,o=!1,s="";try{r=await n(e.input,e.signal,this.callHandlerContext(e))}catch(i){o=!0,s=i instanceof Error?i.message:String(i),r={content:`Tool execution error: ${s}`,isError:!0}}return o?this.firePostToolUseFailure(e.name,s,e.signal,e.input):this.firePostToolUse(e.name,r.content,e.signal,e.input,r),r}async executeCompose(e){if(!this.composeExecutor)return{content:"Compose tool is not available in this session configuration",isError:!0};try{return await this.composeExecutor.execute(e)}catch(n){return{content:`Compose tool error: ${n instanceof Error?n.message:String(n)}`,isError:!0}}}firePostToolUse(e,n,r,o,s){if(!this.hookRegistry)return;let i={event:"PostToolUse",toolName:e,output:n,...o!==void 0?{input:o}:{},...this.parentSessionId!==void 0?{parentSessionId:this.parentSessionId}:{},...this.sessionGrantManager!==void 0?{grantManager:this.sessionGrantManager}:{},...s?.incomplete===!0?{incomplete:!0}:{},...s?.incompleteReason?{incompleteReason:s.incompleteReason}:{}};Lk(this.hookRegistry,i,{signal:r,...this.traceWriter?{traceWriter:this.traceWriter}:{}}).catch(()=>{})}firePostToolUseFailure(e,n,r,o){if(!this.hookRegistry)return;let s={event:"PostToolUseFailure",toolName:e,error:n,...o!==void 0?{input:o}:{},...this.parentSessionId!==void 0?{parentSessionId:this.parentSessionId}:{}};Nk(this.hookRegistry,s,{signal:r,...this.traceWriter?{traceWriter:this.traceWriter}:{}}).catch(i=>{O(`firePostToolUseFailure outer catch (tool=${e}): ${String(i)}`)})}}});import{mkdir as FW,writeFile as LW}from"fs/promises";import{dirname as NW,join as UW}from"path";function $W(){return UW(gt(),"routing-decisions.jsonl")}function BW(t){let e={surface:"afk"};for(let[n,r]of Object.entries(t))r!==void 0&&(e[n]=r);return e}async function te(t){if(!(S.VITEST||S.NODE_ENV==="test"))try{let e=$W();await FW(NW(e),{recursive:!0});let n=new Date().toISOString().split(".")[0]+"Z",r=JSON.stringify({ts:n,...BW(t)})+`
|
|
260
264
|
`;await LW(e,r,{flag:"a"})}catch{}}var vt=g(()=>{"use strict";L();j()});function YW(t){let e=t.match(jW);if(!e)return null;let n=parseInt(e[1]??"0",10),r=parseInt(e[2]??"0",10),o=e[3]!==void 0?parseInt(e[3],10):void 0;return{runner:"vitest",passed:n,failed:r,...o!==void 0?{skipped:o}:{}}}function QW(t){let e=t.match(HW);if(!e)return null;let n=parseInt(e[1]??"0",10);return{runner:"jest",passed:parseInt(e[2]??"0",10),failed:n}}function ZW(t){let e=t.match(WW);if(!e)return null;if(e[2]!==void 0){let n=parseInt(e[2],10),r=parseInt(e[1]??"0",10);return{runner:"pytest",passed:n,failed:r}}return e[4]!==void 0?{runner:"pytest",passed:parseInt(e[4],10),failed:0}:null}function eK(t){let e=t.match(KW);if(!e)return null;let n=parseInt(e[1]??"0",10),r=t.match(GW),o=r?parseInt(r[1]??"0",10):0;return{runner:"mocha",passed:n,failed:o}}function tK(t){let e=[...t.matchAll(qW)];if(e.length===0)return null;let n=0,r=0;for(let o of e)o[1]==="ok"?n++:o[1]==="FAIL"&&r++;return{runner:"go-test",passed:n,failed:r}}function nK(t){let e=t.match(XW);if(!e)return null;let n=parseInt(e[1]??"0",10),r=parseInt(e[2]??"0",10),o=e[3]!==void 0?parseInt(e[3],10):void 0;return{runner:"cargo",passed:n,failed:r,...o!==void 0?{skipped:o}:{}}}function rK(t){let e=t.match(zW);if(!e)return null;let n=parseInt(e[1]??"0",10),r=parseInt(e[2]??"0",10);return{runner:"rspec",passed:n-r,failed:r}}function oK(t){let e=t.match(VW);if(e)return{runner:"phpunit",passed:parseInt(e[1]??"0",10),failed:0};let n=t.match(JW);if(n){let r=parseInt(n[1]??"0",10),o=parseInt(n[2]??"0",10);return{runner:"phpunit",passed:r-o,failed:o}}return null}function Hm(t){return YW(t)??QW(t)??ZW(t)??eK(t)??tK(t)??nK(t)??rK(t)??oK(t)??null}var jW,HW,WW,KW,GW,qW,XW,zW,VW,JW,__=g(()=>{"use strict";jW=/Tests\s+(\d+)\s+passed(?:\s*\|\s*(\d+)\s+failed)?(?:\s*\|\s*(\d+)\s+skipped)?/,HW=/Tests:\s+(?:(\d+)\s+failed,\s*)?(\d+)\s+passed,\s*\d+\s+total/,WW=/={3,}\s*(?:(\d+)\s+failed,\s*)?(\d+)\s+passed(?:,\s*(\d+)\s+warning)?.*in\s+[\d.]+s\s*={3,}|={3,}\s*(\d+)\s+passed.*in\s+[\d.]+s\s*={3,}/,KW=/(\d+)\s+passing/,GW=/(\d+)\s+failing/,qW=/^(ok|FAIL)\s+\S+\s+[\d.]+s/gm,XW=/test result: (?:ok|FAILED)\. (\d+) passed; (\d+) failed(?:; (\d+) ignored)?/,zW=/(\d+) examples?, (\d+) failures?/,VW=/OK \((\d+) tests?/,JW=/Tests:\s*(\d+)[^]*?Failures:\s*(\d+)/});import{statSync as sK}from"node:fs";function ii(t){if(typeof t!="object"||t===null)return!1;let e=t;return e.code==="ENOENT"&&typeof e.syscall=="string"&&e.syscall.startsWith("spawn")}function iK(t){if(t===void 0)return!1;try{return sK(t),!1}catch{return!0}}function ro(t,e){let n=t instanceof Error?t.message:typeof t?.message=="string"?String(t.message):String(t);return ii(t)&&iK(e)?`working directory does not exist: ${e} (deleted worktree?) \u2014 underlying: ${n}`:n}var Wm=g(()=>{"use strict"});function Ut(t){let e=t instanceof Error?t.message:String(t);A_.has(e)||(A_.add(e),console.warn(`[afk-home] Malformed AFK home/state env var ignored while deriving the credential floor: ${e}. The relocated tree is NOT protected \u2014 the default ~/.afk entries still apply. Fix the env var to restore coverage.`))}var A_,ai=g(()=>{"use strict";A_=new Set});import{statSync as Gm}from"node:fs";import{homedir as aK}from"node:os";import{basename as cK,dirname as T_,join as lK}from"node:path";function R_(t){return typeof t=="object"&&t!==null&&"code"in t?String(t.code):void 0}function dK(t){let e=cK(t),n=e===e.toLowerCase()?e.toUpperCase():e.toLowerCase();if(n===e)return;let r;try{r=Gm(t)}catch{return}let o=Km.get(r.dev);if(o!==void 0)return o;try{let s=Gm(lK(T_(t),n)),i=r.dev===s.dev&&r.ino===s.ino;return Km.set(r.dev,i),i}catch(s){let i=R_(s);return i==="ENOENT"||i==="ENOTDIR"?(Km.set(r.dev,!1),!1):void 0}}function x_(t=aK()){if(E_!==void 0)return E_;let e=t;for(;;)try{return Gm(e),dK(e)??!0}catch(n){let r=R_(n);if(r!=="ENOENT"&&r!=="ENOTDIR")return!0;let o=T_(e);if(o===e)return!0;e=o}}function oo(t,e,n=e){if(t===e||t.startsWith(e+"/")||t.startsWith(e+"\\"))return!0;if(!x_(n))return!1;let r=t.toLowerCase(),o=e.toLowerCase();return r===o||r.startsWith(o+"/")||r.startsWith(o+"\\")}function wl(t,e){return t.includes(e)?!0:x_(e)?t.toLowerCase().includes(e.toLowerCase()):!1}var E_,Km,Sl=g(()=>{"use strict";Km=new Map});import{realpathSync as I_}from"fs";import{dirname as uK,resolve as ir,join as kl}from"path";import{homedir as it}from"os";function fK(){let t=[];try{let e=ne();t.push(ir(kl(e,"config"))),t.push(ir(kl(e,"state")))}catch(e){Ut(e)}try{t.push(ir(ae()))}catch(e){Ut(e)}return t}function qm(){let t=`${S.AFK_WRITE_DENYLIST??""}\0${S.AFK_HOME??""}\0${S.AFK_STATE_DIR??""}`;if(!vl||vl.key!==t){let e=S.AFK_WRITE_DENYLIST,n=process.platform==="win32"?";":":",r=e?e.split(n).map(o=>o.trim()).filter(Boolean).map(o=>o==="~"||o.startsWith("~/")||o.startsWith("~\\")?kl(it(),o.slice(2)):o).map(o=>ir(o)).filter(Boolean):[];vl={key:t,unresolved:[...new Set([...pK.map(o=>ir(o)),...fK()]),...r]}}return[...new Set(vl.unresolved.map(e=>De(e)))]}function De(t){let e=ir(t);try{return I_(e)}catch{}let n=[],r=e;for(let o=0;o<64;o++){let s=uK(r);if(s===r)break;n.unshift(r.slice(s.length+1)),r=s;try{let i=I_(r);return kl(i,...n)}catch{}}return e}function _l(t,e="write_file"){let n=De(ir(t));for(let r of qm())if(oo(n,r))throw new Error(`${e}: refusing to write to protected path: ${n} (matches denylist entry: ${r})`)}var pK,vl,so=g(()=>{"use strict";L();j();ai();Sl();pK=[`${it()}/.ssh`,`${it()}/.aws`,`${it()}/.gnupg`,`${it()}/.config/gcloud`,"/etc","/System","/private/etc","/usr/local/etc",`${it()}/.afk/config`,`${it()}/.afk/state`,`${it()}/.npmrc`,`${it()}/.docker/config.json`,`${it()}/Library/LaunchAgents`,`${it()}/Library/LaunchDaemons`,"/Library/LaunchAgents","/Library/LaunchDaemons",`${it()}/.config/systemd`,...process.platform==="win32"&&S.APPDATA?[`${S.APPDATA}\\gcloud`,`${S.APPDATA}\\Docker`]:[],...process.platform==="win32"&&S.USERPROFILE?[`${S.USERPROFILE}\\.ssh`,`${S.USERPROFILE}\\.aws`,`${S.USERPROFILE}\\.gnupg`]:[]]});import{isAbsolute as mK,relative as gK,sep as hK}from"node:path";import{homedir as Al}from"node:os";function yK(t,e){let n=gK(e,t);return n===""||n!==".."&&!n.startsWith(`..${hK}`)&&!mK(n)}function Xm(t,e){return t.filter(n=>!e.some(r=>yK(n,r)))}function bK(t,e){return t.filter(({source:n})=>n!==e).map(({root:n})=>n)}function C_(t,e){return t.flatMap(({rel:n,resolved:r})=>Xm([r],bK(e,wK[n])))}var wK,P_=g(()=>{"use strict";wK={".afk/config/mcp.json":`${Al()}/.afk/config`,".afk/config/schedules.json":`${Al()}/.afk/config`,".ssh/config":`${Al()}/.ssh`,".ssh/known_hosts":`${Al()}/.ssh`}});import{isAbsolute as zse,resolve as SK}from"path";import{homedir as M_}from"os";function io(t){return t==="~"?M_():t.startsWith("~/")?SK(M_(),t.slice(2)):t}var zm=g(()=>{"use strict"});import{basename as vK,dirname as kK,join as El,relative as _K,resolve as ao,sep as ci}from"path";import{homedir as de}from"os";function D_(t){let e=ao(t);return El(De(kK(e)),vK(e))}function Jm(t){if(!t)return[];let e=process.platform==="win32"?";":":";return t.split(e).map(n=>n.trim()).filter(Boolean).map(n=>n==="~"||n.startsWith("~/")||n.startsWith("~\\")?io(n.replace(/^~[/\\]+/,"~/")):n).map(n=>ao(n))}function EK(){try{return[De(ao(El(ne(),"config")))]}catch(t){return Ut(t),[]}}function TK(){try{let t=ne();return ar.filter(e=>e.startsWith(O_)).map(e=>D_(El(t,e.slice(O_.length))))}catch(t){return Ut(t),[]}}function F_(){let t=`${S.AFK_READ_DENYLIST??""}\0${S.AFK_HOME??""}`;if(li&&li.key===t)return li;let e=Jm(S.AFK_READ_DENYLIST).map(i=>De(i)).filter(Boolean),n=Vm.map(i=>({source:i,root:De(ao(i))})),r=EK(),o=[...new Set([...n.map(({root:i})=>i),...r])],s=n.filter(({source:i,root:a})=>i!==AK||!r.includes(a)).map(({root:i})=>i);return li={key:t,builtins:o,extras:e,allow:[...new Set([...C_(ar.map(i=>({rel:i,resolved:D_(`${de()}/${i}`)})),n),...Xm(TK(),s)])]},li}function Ym(){let{builtins:t,extras:e}=F_();return[...t,...e]}function L_(t){let e=De(ao(t));return Ym().filter(n=>n!==e&&oo(n,e,n)).map(n=>(n.startsWith(e+ci)?_K(e,n):n.split(ci).slice(e.split(ci).length).join(ci)).split(ci).join("/"))}function at(t){let e=De(ao(t)),{builtins:n,extras:r,allow:o}=F_();for(let s of r)if(oo(e,s))return{denied:!0,matched:s};if(o.includes(e))return{denied:!1};for(let s of n)if(oo(e,s))return{denied:!0,matched:s};return{denied:!1}}var Vm,ar,AK,iie,li,O_,co,Tl,Sn=g(()=>{"use strict";L();so();j();ai();P_();Sl();zm();Vm=[`${de()}/.ssh`,`${de()}/.aws`,`${de()}/.gnupg`,`${de()}/.config/gcloud`,`${de()}/.afk/config`,`${de()}/.npmrc`,`${de()}/.docker/config.json`,`${de()}/.git-credentials`,`${de()}/.netrc`,`${de()}/.config/gh/hosts.yml`,`${de()}/.kube/config`,"/etc/shadow","/etc/sudoers","/private/etc/master.passwd",`${de()}/.password-store`,`${de()}/Library/Application Support/Google/Chrome`,`${de()}/Library/Application Support/Chromium`,`${de()}/Library/Application Support/BraveSoftware`,`${de()}/Library/Application Support/Microsoft Edge`,`${de()}/Library/Application Support/Arc`,`${de()}/Library/Application Support/Firefox`,...process.platform==="win32"&&S.USERPROFILE?[`${S.USERPROFILE}\\.ssh`,`${S.USERPROFILE}\\.aws`,`${S.USERPROFILE}\\.gnupg`]:[],...process.platform==="win32"&&S.APPDATA?[`${S.APPDATA}\\gcloud`,`${S.APPDATA}\\Docker`,`${S.APPDATA}\\Mozilla\\Firefox`]:[],...process.platform==="win32"&&S.LOCALAPPDATA?[`${S.LOCALAPPDATA}\\Google\\Chrome`,`${S.LOCALAPPDATA}\\Chromium`,`${S.LOCALAPPDATA}\\BraveSoftware`,`${S.LOCALAPPDATA}\\Microsoft\\Edge`]:[]],ar=[".afk/config/mcp.json",".afk/config/schedules.json",".ssh/config",".ssh/known_hosts"],AK=`${de()}/.afk/config`,iie=ar.map(t=>El(de(),t));O_=".afk/";co="read-denylist entry:",Tl="is a protected credential/secret path"});import cr from"path";import{realpathSync as RK}from"fs";function Fe(t){try{return RK.native(t)}catch{let e=cr.dirname(t),n=cr.basename(t);return e===t?t:cr.join(Fe(e),n)}}function xK(t){let e=N_.get(t);if(e!==void 0)return e;let n=Fe(t);return N_.set(t,n),n}function U_(t,e,n,r){let o=e?.resolveBase??e?.cwd??r,s=cr.isAbsolute(t)?t:cr.resolve(o??process.cwd(),t);if(e?.allowAll===!0)return{restricted:!1,resolved:s,roots:[]};if(o===void 0)return{restricted:!1,resolved:s,roots:[]};let i=Fe(s),a=n==="read"?e?.readRoots??[o]:e?.writeRoots??[o];for(let c of a){let l=xK(c),d=cr.relative(l,i);if(!d.startsWith("..")&&!cr.isAbsolute(d))return{restricted:!1,resolved:s,roots:a}}return{restricted:!0,resolved:s,roots:a}}function Te(t,e,n="read",r){let{restricted:o,resolved:s,roots:i}=U_(t,e,n,r);if(n==="read"){let a=at(s);if(a.denied)throw new Error(`Path \`${t}\` ${Tl} (${co} \`${a.matched}\`) and cannot be read.`)}if(o){let a=i.map(l=>`\`${l}\``).join(", "),c=n==="read"?"read roots":"write roots";throw new Error(`Path \`${t}\` is outside the allowed ${c} [${a}].`)}return s}function di(t,e,n="read",r){return U_(t,e,n,r)}function $_(t){let e=new Set,n=[];for(let r of t.split(/\s+/)){if(r.length===0)continue;let o=r.replace(/^\d*[<>|&]+/,"").replace(/^['"]/,"").replace(/['";,)]+$/,"");if(o.length===0)continue;let s=o.startsWith("/"),i=o==="~"||o.startsWith("~/");!s&&!i||e.has(o)||(e.add(o),n.push(o))}return n}var N_,Be=g(()=>{"use strict";Sn();N_=new Map});import{execFileSync as IK}from"node:child_process";function ui(t,e="SIGKILL"){if(!(t<=0))try{process.platform==="win32"?IK("taskkill",["/F","/T","/PID",String(t)],{stdio:"ignore",timeout:5e3}):process.kill(-t,e)}catch{}}var Qm=g(()=>{"use strict"});import{spawn as CK}from"child_process";import PK from"os";function MK(t){if(typeof t!="object"||t===null)throw new Error("Input must be an object");let e=t;if(typeof e.command!="string")throw new Error('Input must have a "command" field of type string');let n=12e4;if(e.timeout_ms!==void 0){if(typeof e.timeout_ms!="number")throw new Error("timeout_ms must be a number");if(e.timeout_ms<0||e.timeout_ms>6e5)throw new Error("timeout_ms must be between 0 and 600000");n=e.timeout_ms}return{command:e.command,timeout_ms:n}}function Rl(t,e){let n=!1,r=!1;function o(){n||t==="bypassPermissions"&&(n=!0,console.warn("[security] bash handler: shell=true with bypassPermissions \u2014 all shell metacharacters are interpreted without confirmation. Migrate to execFile to eliminate this risk (tracked: C4)."))}function s(i,a){if(r)return;let c=a.resolveBase??a.cwd??e,l=PK.homedir(),d=[];for(let u of $_(i)){let p=u==="~"?l:u.startsWith("~/")?l+u.slice(1):u,f=di(p,a,"write",c);f.restricted&&d.push(f.resolved)}d.length!==0&&(r=!0,console.warn(`[security] bash: command references path(s) outside writeRoots: ${d.join(", ")} \u2014 bash containment is best-effort (tracked C4); use file tools for contained writes.`),te({event:"tool.bash_path_escape",tool:"bash",restricted_count:d.length,mode:"write"}))}return async(i,a,c)=>{let{command:l,timeout_ms:d}=MK(i);if(a.aborted)return{content:"Command aborted",isError:!0};if(o(),c!==void 0)try{s(l,c)}catch{}return new Promise(u=>{let p=!1;function f(T){p||(p=!0,clearTimeout(h),a.removeEventListener("abort",R),u(T))}let m=CK(l,{shell:!0,detached:!0,stdio:["ignore","pipe","pipe"],...(c?.resolveBase??c?.cwd??e)!==void 0?{cwd:c?.resolveBase??c?.cwd??e}:{},...c?.env!==void 0?{env:{...process.env,...c.env}}:{}});m.unref();let h=setTimeout(()=>{m.pid!==void 0&&ui(m.pid),f({content:`Command timed out after ${d}ms`,isError:!0})},d),y="",b="",k=0,_=!1;function E(T){if(_||p||k<8e6)return;_=!0,console.warn(`[bash] overflow kill: stream=${T} totalBytes=${k} command="${l}"`),te({event:"tool.overflow_kill",tool:"bash",total_bytes:k,stream:T}),m.kill("SIGKILL");let I=Xe((y+b).trimEnd()),x=Hm(I)??void 0,v=tr(I,1e5)+qk;f({content:v,truncated:!0,...x!==void 0?{testResult:x}:{}})}m.stdout.on("data",T=>{let I=8e6-k,x=T.length<=I?T:T.subarray(0,Math.max(0,I));k+=x.length,y+=x.toString("utf8"),E("stdout")}),m.stderr.on("data",T=>{let I=8e6-k,x=T.length<=I?T:T.subarray(0,Math.max(0,I));k+=x.length,b+=x.toString("utf8"),E("stderr")});let R=()=>{m.pid!==void 0&&ui(m.pid),f({content:"Command aborted",isError:!0})};a.addEventListener("abort",R),a.aborted&&R(),m.on("close",T=>{if(a.aborted){f({content:"Command aborted",isError:!0});return}if(T!==null&&T!==0){let A=nr(b.trimEnd()||y.trimEnd());f({content:`Command exited with code ${T}${A.content?`
|
|
@@ -311,7 +315,7 @@ ${o}`,paths:[e,n]}:o!==null?s={content:o,paths:[n]}:r!==null?s={content:r,paths:
|
|
|
311
315
|
|
|
312
316
|
${e}`}var FG,Tg=g(()=>{"use strict";FG=new Set(["script","style","noscript","template","svg"])});function UG(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 SE(t,e,n){let r=Math.min(e*2**t,n);return Math.round(Math.random()*r)}function $G(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 vE(t,e,n={},r={}){let o=r.retries??3,s=r.baseDelayMs??500,i=r.maxDelayMs??1e4,a=r.sleep??UG,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(!NG.has(u.status)||d===o)return u;let p=$G(u,i)??SE(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=SE(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 NG,kE=g(()=>{"use strict";se();NG=new Set([429,502,503,504])});import{BlockList as BG,isIP as xg}from"node:net";import{lookup as jG}from"node:dns/promises";import{Agent as HG}from"undici";function AE(){let t=S.AFK_WEB_ALLOW_PRIVATE_HOSTS?.trim().toLowerCase();return t==="1"||t==="true"}function qG(t){return t.startsWith("[")&&t.endsWith("]")?t.slice(1,-1):t}function Rg(t){let e=xg(t);return e===0?!1:GG.check(t,e===4?"ipv4":"ipv6")}async function EE(t){return jG(t,{all:!0,verbatim:!0})}async function Ig(t,e={}){if(e.allowPrivateHosts??AE())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=qG(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(xg(r)!==0)return Rg(r)?{allowed:!1,reason:o(r,r)}:{allowed:!0};let s=e.lookupFn??EE,i;try{i=await s(r)}catch{return{allowed:!0}}for(let a of i)if(Rg(a.address))return{allowed:!1,reason:o(a.address,`${r} (resolved)`)};return{allowed:!0}}async function ki(t,e={}){let n=await Ig(t,e);if(!n.allowed)throw new kt(n.reason)}async function jl(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<=_E;i++){await ki(s,o);let a={...n,redirect:"manual",...t===globalThis.fetch&&!(r.allowPrivateHosts??AE())?{dispatcher:XG}:{}},c=await vE(t,s,a,r.retry??{});if(!zG.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 kt(`too many redirects (>${_E}) starting from ${e}`)}var WG,KG,GG,kt,XG,_E,zG,Cg=g(()=>{"use strict";L();kE();WG=[["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]],KG=[["::",96],["64:ff9b::",96],["fc00::",7],["fe80::",10]],GG=(()=>{let t=new BG;for(let[e,n]of WG)t.addSubnet(e,n,"ipv4");for(let[e,n]of KG)t.addSubnet(e,n,"ipv6");return t})(),kt=class extends Error{constructor(e){super(e),this.name="EgressBlockedError"}};XG=new HG({connect:{lookup(t,e,n){EE(t).then(r=>{let o=r.find(i=>Rg(i.address));if(o!==void 0){n(new kt(`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,xg(s.address))},r=>n(r,"",0))}}});_E=20,zG=new Set([301,302,303,307,308])});var IE={};_s(IE,{enforceDomainPolicy:()=>_t,loadBrowserConfig:()=>Pg});import{readFileSync as VG}from"node:fs";import{join as JG}from"path";function YG(t){let n=t.replace(/[.+?()[\]{}/\\^$|]/g,"\\$&").replace(/\*/g,"[^.]*");return new RegExp(`^${n}$`,"i")}function TE(t,e){return YG(e).test(t)}function eq(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(QG.has(e))return!0;if(ZG.has(e))return!1}return!1}function RE(t){return t===void 0||t.trim()===""?[]:t.split(",").map(e=>e.trim().toLowerCase()).filter(e=>e.length>0)}function tq(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 xE(t){let e=t===void 0||t.trim()===""?"default":t.trim();return Pf(e),e}function nq(t){if(t===void 0)return!1;let e=t.trim().toLowerCase();return e==="1"||e==="true"||e==="yes"}function rq(t){try{return VG(t,"utf8")}catch(e){if(e.code==="ENOENT")return;throw e}}function oq(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=xE(e.defaultProfile)),n}function Pg(t){let e=t?.env??S,n=t?.readFileSync??rq,r=t?.surface??e.AGENT_SURFACE,o=eq(e.AFK_BROWSER_HEADLESS,r),s=RE(e.AFK_BROWSER_ALLOWED_DOMAINS),i=RE(e.AFK_BROWSER_BLOCKED_DOMAINS),a=nq(e.AFK_BROWSER_DOM_SNAPSHOTS),c=tq(e.AFK_BROWSER_BACKEND),l=xE(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():JG(Vt(),"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 h=oq(d,m);return h.configPath=p,h}function _t(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(TE(n,r))return{allowed:!1,reason:`blocked by AFK_BROWSER_BLOCKED_DOMAINS: ${r}`};return e.allowedDomains.length>0&&!e.allowedDomains.some(o=>TE(n,o))?{allowed:!1,reason:"not in AFK_BROWSER_ALLOWED_DOMAINS"}:{allowed:!0}}var QG,ZG,pr=g(()=>{"use strict";L();j();QG=new Set(["daemon","subagent","telegram","afk"]),ZG=new Set(["repl","interactive","cli"])});import{readFileSync as sq}from"node:fs";import{join as iq}from"node:path";import{homedir as aq}from"node:os";function lq(t){let e=t??cq,n;try{n=sq(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 dq(t){try{return process.kill(t,0),!0}catch{return!1}}async function uq(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 Mg(t){let e=lq(t);return e===null?{available:!1,connection:null,reason:"connection file missing or invalid"}:dq(e.pid)?await uq(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 cq,CE=g(()=>{"use strict";cq=iq(aq(),".config","agent-browser","connection.json")});async function PE(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 Mg(),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&&pq.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 Mg(),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 pq,ME=g(()=>{"use strict";CE();pq=new Set(["daemon","subagent"])});import{createHash as fq}from"crypto";function OE(t){return!!(t.role==="textbox"&&t.kind==="password"||t.label&&mq.test(t.label))}function DE(t){return fq("sha256").update(t,"utf8").digest("hex").slice(0,8)}function FE(t){let e=t.replace(/\s+/g," ").trim();return e.length<=80?e:e.slice(0,77)+"..."}var mq,Hl=g(()=>{"use strict";mq=/password|secret|token|api[_-]?key|otp|2fa/i});import{randomBytes as gq}from"crypto";import{mkdir as hq,stat as yq,writeFile as bq}from"fs/promises";import{join as Og}from"path";import{gzip as wq}from"zlib";import{promisify as Sq}from"util";function vq(t){return Og(Ct(t),"browser")}function kq(t){return Og(vq(t),"screenshots")}function _q(){return new Date().toISOString().replace(/[:.]/g,"-")}function Aq(){return gq(3).toString("hex")}async function wo(t,e,n){if(e.length>LE)throw new Error(`writeScreenshotSidecar: buffer exceeds ${LE} byte cap (received ${e.length} bytes). Refusing to write oversized screenshot.`);let r=kq(t);await hq(r,{recursive:!0});let o=`${_q()}-${Aq()}-${n}.png`,s=Og(r,o);await bq(s,e);let{size:i}=await yq(s);return{path:s,bytes:i}}var rde,LE,Dg=g(()=>{"use strict";j();Hl();rde=Sq(wq);LE=5*1024*1024});var Wl,NE=g(()=>{"use strict";Wl=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 c=await a.text().catch(()=>"");throw new Error(`Agent Browser ${e} failed (HTTP ${a.status}): ${c}`)}return await a.json()}finally{clearTimeout(i)}}async listTabs(){return(await this.call("tabs.list",null)).tabs}async openTab(e){return{tabId:(await this.call("tabs.open",{url:e},6e4)).tab_id}}async closeTab(e){await this.call("tabs.close",{tab_id:e})}async read(e,n){return this.call("page.read",{tab_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",{tab_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",{tab_id:e,element_id:n})}async fill(e,n,r){await this.call("page.fill",{tab_id:e,element_id:n,value:r})}async press(e,n,r){await this.call("page.press",{tab_id:e,key:n,...r?{element_id:r}:{}})}async select(e,n,r){await this.call("page.select",{tab_id:e,element_id:n,value:r})}async waitFor(e,n,r){await this.call("page.wait",{tab_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",{tab_id:e,script:n})}async screenshot(e){return this.call("page.screenshot",{tab_id:e})}}});function Fg(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 UE(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 Lg(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 $E(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(Fg)};let s=r[0].id;await Lg(t.client,t.tabId,e.action,s,e.value,e.timeoutMs);let i=await t.client.read(t.tabId,{mode:"main"}),a=_t(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 BE=g(()=>{"use strict";pr()});var jE={};_s(jE,{AgentBrowserProvider:()=>Ng});var Ng,HE=g(()=>{"use strict";pr();Dg();NE();BE();Ng=class{name="agent-browser";config;client;sessions=new Map;constructor(e,n){this.config=e,this.client=new Wl(n)}async open(e){let n=_t(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=_t(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=UE(n.knownElements,e.target);if(r===null){if(e.target.kind==="semantic"){let i=await $E({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 Lg(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=_t(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 wo(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(Fg),l=o??80,d=c.slice(0,l);e.observationCounter+=1,e.knownElements=new Map(d.map(h=>[h.id,h])),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 h=await this.client.screenshot(e.tabId),y=Buffer.from(h.data,"base64");p=(await wo(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 Eq,readFileSync as Tq}from"node:fs";import{createRequire as Rq}from"node:module";import{dirname as xq,join as Iq}from"node:path";function GE(t){if(typeof t=="string")return t;let e=[],n=t;for(let r=0;r<Pq&&n instanceof Error;r++)e.push(n.message),n=n.cause;return e.length>0?e.join(" | "):String(t)}function He(t){let e=GE(t);return KE.some(n=>e.includes(n))}function Mq(){try{let e=Rq(import.meta.url).resolve("playwright/package.json"),n=JSON.parse(Tq(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=Iq(xq(e),o);return Eq(s)?`node ${/\s/.test(s)?`"${s}"`:s} install chromium`:void 0}catch{return}}function _i(){return WE??=Mq()??Cq,WE}function Ug(t){return t.includes("install chromium")}function ct(t,e){let n=GE(t),r=e?.latched===!0?` ${Oq}`:"";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: ${_i()}.${o}${r}`}return`browser tools require the optional \`playwright\` peer dependency. Install via: pnpm add playwright (then ${_i()}). Or pick a different tool.${r}`}function $g(t,e,n=!1){if(!He(t))return t;let r=t instanceof Error?t.message:String(t);return new Error(`${r}
|
|
313
317
|
|
|
314
|
-
${ct(t,{headless:e,latched:n})}`,{cause:t})}var KE,Cq,Pq,WE,Oq,Bg=g(()=>{"use strict";KE=["Cannot find package","ERR_MODULE_NOT_FOUND","Executable doesn't exist"],Cq="pnpm exec playwright install chromium",Pq=4;Oq="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 fr from"node:fs";import Kl from"node:path";import{randomBytes as Dq}from"node:crypto";import{chromium as Fq}from"playwright";function Lq(){try{return"5.169.2"}catch{}try{let t=Kl.resolve(import.meta.dirname,"../../../package.json"),e=fr.readFileSync(t,"utf8"),n=JSON.parse(e);return typeof n.version=="string"?n.version:"unknown"}catch{return"unknown"}}var Nq,Gl,qE=g(()=>{"use strict";Bg();j();se();Nq=Lq(),Gl=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=Fq.launch({headless:this.config.headless}).then(e=>(this.browser=e,this.launchPromise=void 0,this.clearLaunchFailure(),e)).catch(e=>{this.launchPromise=void 0;let n=$g(e,this.config.headless,!0);throw this.latchLaunchFailure(n),n}),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/${Nq}`}}loadStorageState(e){let n=Mf(e);try{if(!fr.existsSync(n))return;let r=JSON.parse(fr.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=Mf(e);if(!fr.existsSync(r))return;let o=await n.storageState(),s=Kl.join(Kl.dirname(r),`.${Kl.basename(r)}.${process.pid}.${Dq(4).toString("hex")}.tmp`);fr.writeFileSync(s,JSON.stringify(o),{mode:384}),fr.chmodSync(s,384),fr.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 Uq}from"node:crypto";function $q(t){return t?t.replace(/\s+/g," ").trim().slice(0,200):""}function Bq(t,e,n){return`el_${Uq("sha256").update(`${t}:${e}:${n}`).digest("hex").slice(0,6)}`}function jq(t){let e=t.replace(/\s+/g," ").trim(),n=4e3;return e.length<=n?e:e.slice(0,n)+"\u2026[truncated]"}function XE(t){return t.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function VE(t,e){let n=t.role??"",r=t.name??"";zE.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&e.push(t);for(let s of t.children??[])VE(s,e)}async function Hq(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},JE).catch(()=>[])}async function Wq(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 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,m={role:l,name:c,disabled:p};u!==void 0&&(m.value=u),f!==void 0&&(m.checked=f),o.push(m)}return o},JE).catch(()=>[])}function Kq(t){let n=t.accessibility;return n!==null&&typeof n=="object"?n:null}async function ql(t,e){let n=e.maxElements??80,r=e.includeHidden??!1,o=[],s=Kq(t),i=s?s.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=Hq(t),c=t.evaluate(()=>document.body?.innerText??"").catch(()=>""),l=Promise.resolve(t.url()),d=t.title().catch(()=>""),[u,p,f,m,h]=await Promise.all([i,a,c,l,d]),y,b=!1;u!==null?(y=[],VE(u,y)):(o.push("observation skipped accessibility tree (returned null)"),b=!0,y=(await Wq(t)).filter(P=>zE.has(P.role??"")));let k=new Map;for(let C of p){let P=XE(C.name),G=k.get(P);(!G||G.bbox.w===0&&C.bbox.w>0)&&k.set(P,C)}let _=y.map(C=>({ax:C,dom:k.get(XE(C.name??""))})),E=r?_:_.filter(C=>C.dom?C.dom.bbox.w>0||C.dom.bbox.h>0:!0);E.sort((C,P)=>{let G=C.dom?.bbox.y??0,M=P.dom?.bbox.y??0;if(G!==M)return G-M;let $=C.dom?.bbox.x??0,D=P.dom?.bbox.x??0;return $-D}),E.length>200&&o.push("page has 200+ interactive elements; consider scoping");let T=E.slice(0,n).map((C,P)=>{let G=C.ax.role??"generic",M=C.ax.name??"",$=Bq(G,M,P),D=C.dom?.bbox??{x:0,y:0,w:0,h:0},N=C.dom?.type??null,B=null;C.ax.value!==void 0&&C.ax.value!==null&&(B=String(C.ax.value)),C.ax.checked!==void 0&&(B=String(C.ax.checked)),OE({role:G,kind:N})&&(B="[redacted]");let K={disabled:C.ax.disabled??!1};C.ax.checked!==void 0&&(K.checked=C.ax.checked===!0||C.ax.checked==="mixed"),C.ax.selected!==void 0&&(K.selected=C.ax.selected),C.ax.expanded!==void 0&&(K.expanded=C.ax.expanded);let Q;C.dom?.testId?Q=`[data-testid="${C.dom.testId}"]`:C.dom?.id&&(Q=`#${C.dom.id}`);let Ne={id:$,role:G,label:$q(M),kind:N,value:B,state:K,bbox:D};return Q!==void 0&&(Ne.selector=Q),Ne}),I="idle";try{let C=await t.evaluate(()=>document.readyState);C==="loading"?I="loading":C==="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 x=jq(f),v=`obs_${e.observationCounter.toString(36)}`,A=new Date().toISOString();return{observationId:v,url:m,title:h,textSummary:x,interactive:T,status:{httpStatus:e.httpStatus??null,loadingState:I,hasDialog:e.hasDialog??!1,consoleErrors:e.consoleErrors??0},warnings:o,screenshotPath:e.screenshotPath??null,capturedAt:A}}var zE,JE,YE=g(()=>{"use strict";Hl();zE=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);JE="a[href], button, input, select, textarea, [role], [tabindex], label"});async function QE(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 jg(t,e){let n=Math.min(e,5);return(await Promise.all(Array.from({length:n},(o,s)=>QE(t,s)))).filter(o=>o!==null)}async function Gq(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 Hg(t,e,n){switch(e.kind){case"element_id":return qq(t,e,n);case"selector":return Xq(t,e);case"semantic":return zq(t,e)}}async function qq(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 jg(o,s);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:i}}async function Xq(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 jg(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${e.selector}]`},candidates:o}}async function zq(t,e){return e.role!==void 0?Vq(t,e.text,e.role):Jq(t,e.text,e)}async function Vq(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 jg(r,o);return{outcome:"ambiguous_target",query:{text:e,role:n},candidates:s}}async function Jq(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 Gq(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 QE(y.locator,y.index);if(b!==null){let k=`${b.role}:${b.label}:${h}`,_=0;for(let E=0;E<k.length;E++)_=_*31+k.charCodeAt(E)>>>0;f.push({...b,id:`el_${_.toString(16).padStart(6,"0").slice(0,6)}`})}}return{outcome:"ambiguous_target",query:{text:e},candidates:f}}var ZE=g(()=>{"use strict"});async function Wg(t,e,n,r){let o=t.url();if(o===n)return null;let s=_t(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 eT=g(()=>{"use strict";pr()});var Gg={};_s(Gg,{PlaywrightProvider:()=>Kg});function tT(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 Kg,qg=g(()=>{"use strict";qE();YE();ZE();pr();eT();Dg();Kg=class{name="playwright";config;launcher;sessions=new Map;constructor(e){this.config=e,this.launcher=new Gl(e)}async open(e){let n=_t(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 Wg(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 ql(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 ql(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 Hg(r,e.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${tT(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(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 Wg(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 ql(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 Hg(r,e.target,o.knownElements);if(d.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${tT(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 wo(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 wo(n,o,r);return s}catch{return null}}}});var gr={};_s(gr,{__resetBrowserRegistryForTests:()=>n2,browserProviderActive:()=>Zq,closeBrowserProvider:()=>zg,getBrowserProvider:()=>Qq,getLastRoutingDecision:()=>t2,peekBrowserProvider:()=>e2});function nT(){Promise.resolve(zg()).then(()=>{process.exit(130)})}function rT(){Promise.resolve(zg()).then(()=>{process.exit(143)})}function oT(){jt=null}function Yq(){Xl||(process.on("SIGINT",nT),process.on("SIGTERM",rT),process.on("exit",oT),Xl=!0)}function sT(){Xl&&(process.removeListener("SIGINT",nT),process.removeListener("SIGTERM",rT),process.removeListener("exit",oT),Xl=!1)}async function Qq(t){return jt!==null?jt:(mr!==null||(mr=(async()=>{let e=Pg(t),n=t?.surface??(t?.env??{}).AGENT_SURFACE??S.AGENT_SURFACE,r=await PE({config:e,surface:n});Xg=r;let o;if(r.backend==="agent-browser"){let{AgentBrowserProvider:s}=await Promise.resolve().then(()=>(HE(),jE)),i=r.availability.connection;o=new s(e,i)}else{let{PlaywrightProvider:s}=await Promise.resolve().then(()=>(qg(),Gg));o=new s(e)}return Yq(),jt=o,mr=null,o})()),mr)}async function zg(){if(jt===null)return;let t=jt;jt=null,mr=null,sT(),await t.shutdown()}function Zq(){return jt!==null}function e2(){return jt}function t2(){return Xg}function n2(){jt=null,mr=null,Xg=null,sT()}var jt,mr,Xl,Xg,hr=g(()=>{"use strict";pr();ME();L();jt=null,mr=null,Xl=!1,Xg=null});async function iT(t,e){try{return await yE(t,e)}catch(n){return O("[web/scrape] extraction failed",{url:e,err:n}),{title:"",markdown:"",textLength:0,usedFallback:!0}}}async function c2(t,e){let{getBrowserProvider:n}=await Promise.resolve().then(()=>(hr(),gr)),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(()=>(qg(),Gg)),{loadBrowserConfig:i}=await Promise.resolve().then(()=>(pr(),IE)),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 aT(t,e){let n=e.fetchFn??globalThis.fetch,r=e.renderFn??c2,o=e.lookupFn!==void 0?{lookupFn:e.lookupFn}:{},s=null,i="",a=t,c=null,l=null;try{let u=await jl(n,t,{headers:a2,signal:e.signal},o);c=u.status,a=u.url||t;let p=u.headers.get("content-type")??"";if(u.ok){if(i2.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(s2.test(p)&&!o2.test(p))return{title:"",markdown:f.trim(),finalUrl:a,usedRender:!1};if(i=f,s=await iT(f,a),e.signal.aborted)throw e.signal.reason??new Error("aborted")}}catch(u){if(e.signal.aborted||u instanceof kt||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=Eg({html:i,extractedTextLength:s.textLength});return{title:s.title,markdown:s.markdown,finalUrl:a,usedRender:!1,...u!==void 0?{advisory:u}:{}}}try{await ki(t,o);let u=await r(t,{timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:f=>ki(f,o)});u.finalUrl!==t&&/^https?:\/\//i.test(u.finalUrl)&&await ki(u.finalUrl,o);let p=await iT(u.html,u.finalUrl);if(e.signal.aborted)throw e.signal.reason??new Error("aborted");if(s===null||p.textLength>=s.textLength){let f=Eg({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 kt)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 o2,s2,i2,a2,cT=g(()=>{"use strict";bE();Tg();Cg();se();o2=/(text\/html|application\/xhtml\+xml)/i,s2=/(application\/json|\/xml|\+xml|text\/|application\/(java|ecma)script|csv)/i,i2=/(image\/|audio\/|video\/|application\/pdf|application\/zip|application\/octet-stream|font\/)/i,a2={"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 u2(t){let e=t.fetchFn??globalThis.fetch;return{name:"exa",async search(n,{limit:r,signal:o}){let s=await e(l2,{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),d2),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 lT(t){return t.exaApiKey!==void 0&&t.exaApiKey.trim()!==""?u2({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 dT(t,e){if(e.length===0)return`# Search results for "${t}"
|
|
318
|
+
${ct(t,{headless:e,latched:n})}`,{cause:t})}var KE,Cq,Pq,WE,Oq,Bg=g(()=>{"use strict";KE=["Cannot find package","ERR_MODULE_NOT_FOUND","Executable doesn't exist"],Cq="pnpm exec playwright install chromium",Pq=4;Oq="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 fr from"node:fs";import Kl from"node:path";import{randomBytes as Dq}from"node:crypto";import{chromium as Fq}from"playwright";function Lq(){try{return"5.169.4"}catch{}try{let t=Kl.resolve(import.meta.dirname,"../../../package.json"),e=fr.readFileSync(t,"utf8"),n=JSON.parse(e);return typeof n.version=="string"?n.version:"unknown"}catch{return"unknown"}}var Nq,Gl,qE=g(()=>{"use strict";Bg();j();se();Nq=Lq(),Gl=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=Fq.launch({headless:this.config.headless}).then(e=>(this.browser=e,this.launchPromise=void 0,this.clearLaunchFailure(),e)).catch(e=>{this.launchPromise=void 0;let n=$g(e,this.config.headless,!0);throw this.latchLaunchFailure(n),n}),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/${Nq}`}}loadStorageState(e){let n=Mf(e);try{if(!fr.existsSync(n))return;let r=JSON.parse(fr.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=Mf(e);if(!fr.existsSync(r))return;let o=await n.storageState(),s=Kl.join(Kl.dirname(r),`.${Kl.basename(r)}.${process.pid}.${Dq(4).toString("hex")}.tmp`);fr.writeFileSync(s,JSON.stringify(o),{mode:384}),fr.chmodSync(s,384),fr.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 Uq}from"node:crypto";function $q(t){return t?t.replace(/\s+/g," ").trim().slice(0,200):""}function Bq(t,e,n){return`el_${Uq("sha256").update(`${t}:${e}:${n}`).digest("hex").slice(0,6)}`}function jq(t){let e=t.replace(/\s+/g," ").trim(),n=4e3;return e.length<=n?e:e.slice(0,n)+"\u2026[truncated]"}function XE(t){return t.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function VE(t,e){let n=t.role??"",r=t.name??"";zE.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&e.push(t);for(let s of t.children??[])VE(s,e)}async function Hq(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},JE).catch(()=>[])}async function Wq(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 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,m={role:l,name:c,disabled:p};u!==void 0&&(m.value=u),f!==void 0&&(m.checked=f),o.push(m)}return o},JE).catch(()=>[])}function Kq(t){let n=t.accessibility;return n!==null&&typeof n=="object"?n:null}async function ql(t,e){let n=e.maxElements??80,r=e.includeHidden??!1,o=[],s=Kq(t),i=s?s.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=Hq(t),c=t.evaluate(()=>document.body?.innerText??"").catch(()=>""),l=Promise.resolve(t.url()),d=t.title().catch(()=>""),[u,p,f,m,h]=await Promise.all([i,a,c,l,d]),y,b=!1;u!==null?(y=[],VE(u,y)):(o.push("observation skipped accessibility tree (returned null)"),b=!0,y=(await Wq(t)).filter(P=>zE.has(P.role??"")));let k=new Map;for(let C of p){let P=XE(C.name),G=k.get(P);(!G||G.bbox.w===0&&C.bbox.w>0)&&k.set(P,C)}let _=y.map(C=>({ax:C,dom:k.get(XE(C.name??""))})),E=r?_:_.filter(C=>C.dom?C.dom.bbox.w>0||C.dom.bbox.h>0:!0);E.sort((C,P)=>{let G=C.dom?.bbox.y??0,M=P.dom?.bbox.y??0;if(G!==M)return G-M;let $=C.dom?.bbox.x??0,D=P.dom?.bbox.x??0;return $-D}),E.length>200&&o.push("page has 200+ interactive elements; consider scoping");let T=E.slice(0,n).map((C,P)=>{let G=C.ax.role??"generic",M=C.ax.name??"",$=Bq(G,M,P),D=C.dom?.bbox??{x:0,y:0,w:0,h:0},N=C.dom?.type??null,B=null;C.ax.value!==void 0&&C.ax.value!==null&&(B=String(C.ax.value)),C.ax.checked!==void 0&&(B=String(C.ax.checked)),OE({role:G,kind:N})&&(B="[redacted]");let K={disabled:C.ax.disabled??!1};C.ax.checked!==void 0&&(K.checked=C.ax.checked===!0||C.ax.checked==="mixed"),C.ax.selected!==void 0&&(K.selected=C.ax.selected),C.ax.expanded!==void 0&&(K.expanded=C.ax.expanded);let Q;C.dom?.testId?Q=`[data-testid="${C.dom.testId}"]`:C.dom?.id&&(Q=`#${C.dom.id}`);let Ne={id:$,role:G,label:$q(M),kind:N,value:B,state:K,bbox:D};return Q!==void 0&&(Ne.selector=Q),Ne}),I="idle";try{let C=await t.evaluate(()=>document.readyState);C==="loading"?I="loading":C==="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 x=jq(f),v=`obs_${e.observationCounter.toString(36)}`,A=new Date().toISOString();return{observationId:v,url:m,title:h,textSummary:x,interactive:T,status:{httpStatus:e.httpStatus??null,loadingState:I,hasDialog:e.hasDialog??!1,consoleErrors:e.consoleErrors??0},warnings:o,screenshotPath:e.screenshotPath??null,capturedAt:A}}var zE,JE,YE=g(()=>{"use strict";Hl();zE=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);JE="a[href], button, input, select, textarea, [role], [tabindex], label"});async function QE(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 jg(t,e){let n=Math.min(e,5);return(await Promise.all(Array.from({length:n},(o,s)=>QE(t,s)))).filter(o=>o!==null)}async function Gq(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 Hg(t,e,n){switch(e.kind){case"element_id":return qq(t,e,n);case"selector":return Xq(t,e);case"semantic":return zq(t,e)}}async function qq(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 jg(o,s);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:i}}async function Xq(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 jg(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${e.selector}]`},candidates:o}}async function zq(t,e){return e.role!==void 0?Vq(t,e.text,e.role):Jq(t,e.text,e)}async function Vq(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 jg(r,o);return{outcome:"ambiguous_target",query:{text:e,role:n},candidates:s}}async function Jq(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 Gq(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 QE(y.locator,y.index);if(b!==null){let k=`${b.role}:${b.label}:${h}`,_=0;for(let E=0;E<k.length;E++)_=_*31+k.charCodeAt(E)>>>0;f.push({...b,id:`el_${_.toString(16).padStart(6,"0").slice(0,6)}`})}}return{outcome:"ambiguous_target",query:{text:e},candidates:f}}var ZE=g(()=>{"use strict"});async function Wg(t,e,n,r){let o=t.url();if(o===n)return null;let s=_t(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 eT=g(()=>{"use strict";pr()});var Gg={};_s(Gg,{PlaywrightProvider:()=>Kg});function tT(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 Kg,qg=g(()=>{"use strict";qE();YE();ZE();pr();eT();Dg();Kg=class{name="playwright";config;launcher;sessions=new Map;constructor(e){this.config=e,this.launcher=new Gl(e)}async open(e){let n=_t(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 Wg(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 ql(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 ql(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 Hg(r,e.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${tT(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(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 Wg(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 ql(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 Hg(r,e.target,o.knownElements);if(d.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${tT(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 wo(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 wo(n,o,r);return s}catch{return null}}}});var gr={};_s(gr,{__resetBrowserRegistryForTests:()=>n2,browserProviderActive:()=>Zq,closeBrowserProvider:()=>zg,getBrowserProvider:()=>Qq,getLastRoutingDecision:()=>t2,peekBrowserProvider:()=>e2});function nT(){Promise.resolve(zg()).then(()=>{process.exit(130)})}function rT(){Promise.resolve(zg()).then(()=>{process.exit(143)})}function oT(){jt=null}function Yq(){Xl||(process.on("SIGINT",nT),process.on("SIGTERM",rT),process.on("exit",oT),Xl=!0)}function sT(){Xl&&(process.removeListener("SIGINT",nT),process.removeListener("SIGTERM",rT),process.removeListener("exit",oT),Xl=!1)}async function Qq(t){return jt!==null?jt:(mr!==null||(mr=(async()=>{let e=Pg(t),n=t?.surface??(t?.env??{}).AGENT_SURFACE??S.AGENT_SURFACE,r=await PE({config:e,surface:n});Xg=r;let o;if(r.backend==="agent-browser"){let{AgentBrowserProvider:s}=await Promise.resolve().then(()=>(HE(),jE)),i=r.availability.connection;o=new s(e,i)}else{let{PlaywrightProvider:s}=await Promise.resolve().then(()=>(qg(),Gg));o=new s(e)}return Yq(),jt=o,mr=null,o})()),mr)}async function zg(){if(jt===null)return;let t=jt;jt=null,mr=null,sT(),await t.shutdown()}function Zq(){return jt!==null}function e2(){return jt}function t2(){return Xg}function n2(){jt=null,mr=null,Xg=null,sT()}var jt,mr,Xl,Xg,hr=g(()=>{"use strict";pr();ME();L();jt=null,mr=null,Xl=!1,Xg=null});async function iT(t,e){try{return await yE(t,e)}catch(n){return O("[web/scrape] extraction failed",{url:e,err:n}),{title:"",markdown:"",textLength:0,usedFallback:!0}}}async function c2(t,e){let{getBrowserProvider:n}=await Promise.resolve().then(()=>(hr(),gr)),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(()=>(qg(),Gg)),{loadBrowserConfig:i}=await Promise.resolve().then(()=>(pr(),IE)),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 aT(t,e){let n=e.fetchFn??globalThis.fetch,r=e.renderFn??c2,o=e.lookupFn!==void 0?{lookupFn:e.lookupFn}:{},s=null,i="",a=t,c=null,l=null;try{let u=await jl(n,t,{headers:a2,signal:e.signal},o);c=u.status,a=u.url||t;let p=u.headers.get("content-type")??"";if(u.ok){if(i2.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(s2.test(p)&&!o2.test(p))return{title:"",markdown:f.trim(),finalUrl:a,usedRender:!1};if(i=f,s=await iT(f,a),e.signal.aborted)throw e.signal.reason??new Error("aborted")}}catch(u){if(e.signal.aborted||u instanceof kt||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=Eg({html:i,extractedTextLength:s.textLength});return{title:s.title,markdown:s.markdown,finalUrl:a,usedRender:!1,...u!==void 0?{advisory:u}:{}}}try{await ki(t,o);let u=await r(t,{timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:f=>ki(f,o)});u.finalUrl!==t&&/^https?:\/\//i.test(u.finalUrl)&&await ki(u.finalUrl,o);let p=await iT(u.html,u.finalUrl);if(e.signal.aborted)throw e.signal.reason??new Error("aborted");if(s===null||p.textLength>=s.textLength){let f=Eg({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 kt)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 o2,s2,i2,a2,cT=g(()=>{"use strict";bE();Tg();Cg();se();o2=/(text\/html|application\/xhtml\+xml)/i,s2=/(application\/json|\/xml|\+xml|text\/|application\/(java|ecma)script|csv)/i,i2=/(image\/|audio\/|video\/|application\/pdf|application\/zip|application\/octet-stream|font\/)/i,a2={"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 u2(t){let e=t.fetchFn??globalThis.fetch;return{name:"exa",async search(n,{limit:r,signal:o}){let s=await e(l2,{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),d2),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 lT(t){return t.exaApiKey!==void 0&&t.exaApiKey.trim()!==""?u2({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 dT(t,e){if(e.length===0)return`# Search results for "${t}"
|
|
315
319
|
|
|
316
320
|
(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(`
|
|
317
321
|
`).trimEnd()}var l2,d2,uT=g(()=>{"use strict";ht();l2="https://api.exa.ai/search",d2=10});function zl(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 yr=g(()=>{"use strict";Bg()});function y2(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=p2;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,f2)}let a=m2;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,g2)}return{mode:r,url:o,query:s,timeoutMs:i,maxBytes:a}}function Vg(t,e){return Buffer.byteLength(t,"utf8")<=e?{content:t,truncated:!1}:{content:tr(t,e),truncated:!0}}function b2(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=y2(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 Ig(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 jl(e,i.url,h,r)}catch(h){return a.signal.aborted?{content:`web_scrape aborted: ${d()}`,isError:!0}:h instanceof kt?{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 m=Vg(f,i.maxBytes);return{content:m.content,...m.truncated?{truncated:!0}:{}}}if(i.mode==="markdown")try{let p=await aT(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=Vg(wE(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 kt)return{content:`web_scrape blocked: ${p.message}`,isError:!0};let f=p instanceof Error?p.message:String(p),m=He(p)&&!Ug(f)?` (the render fallback needs the optional Playwright browser \u2014 run \`${_i()}\`)`:"";return{content:`web_scrape markdown error: ${f}${m}`,isError:!0}}let u=lT({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:h2,timeoutMs:i.timeoutMs,signal:a.signal}),f=Vg(dT(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 p2,f2,m2,g2,h2,pT,fT=g(()=>{"use strict";cT();uT();Cg();wn();Tg();yr();p2=3e4,f2=12e4,m2=1e5,g2=1e6,h2=10;pT=b2()});import{existsSync as gT,mkdirSync as w2,readFileSync as S2,renameSync as v2,unlinkSync as k2,writeFileSync as _2}from"node:fs";import{dirname as mT,join as A2}from"node:path";import{randomBytes as E2}from"node:crypto";function br(t){let e=t??Ef();if(!gT(e))return[];try{let n=S2(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 Ai(t,e){let n=e??Ef();w2(mT(n),{recursive:!0});let r=A2(mT(n),`.schedules.json.${process.pid}.${E2(4).toString("hex")}.tmp`),o=JSON.stringify(t,null,2);try{_2(r,o,"utf-8"),v2(r,n)}catch(s){try{gT(r)&&k2(r)}catch{}throw s}}function hT(t,e){let n=br(e),r=n.map(c=>c.id),o=T2(t.name),s=R2(o,r),i=new Date().toISOString(),a={...t,notifyOn:t.notifyOn??"failure",id:s,createdAt:i,updatedAt:i};return n.push(a),Ai(n,e),a}function yT(t,e){let n=br(e),r=n.length,o=n.filter(s=>s.id!==t);return o.length===r?!1:(Ai(o,e),!0)}function bT(t,e){return br(e).find(n=>n.id===t)}function T2(t){return t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/-{2,}/g,"-").replace(/^-+|-+$/g,"")}function R2(t,e){if(!e.includes(t))return t;let n=2;for(;e.includes(`${t}-${n}`);)n+=1;return`${t}-${n}`}function wT(t){return{taskId:t.id,command:t.command,trigger:t.trigger??"cron",...t.cron!==void 0?{cronExpression:t.cron}:{},...t.notifyOn!==void 0?{notifyOn:t.notifyOn}:{},...t.notifyChat!==void 0?{notifyChat:t.notifyChat}:{}}}var ST=g(()=>{"use strict";j()});import{existsSync as x2,readFileSync as I2}from"node:fs";import{join as C2}from"node:path";async function So(t,e,n){let r,o;try{let s=C2(AS("default"),"port");if(!x2(s))return{synced:!1,detail:"daemon-not-detected (no port file)"};let i=I2(s,"utf-8").trim(),a=P2(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 P2(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 Jg,vT=g(()=>{"use strict";j();Jg="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 M2}from"node:fs";import{readFile as O2}from"node:fs/promises";var kT,_T,AT,ET,TT=g(()=>{"use strict";ST();j();vT();kT=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=hT({name:n.name,command:n.command,cron:n.cron,trigger:n.trigger??"cron",notifyOn:n.notifyOn,...o!==void 0?{notifyChat:o}:{},enabled:typeof n.enabled=="boolean"?n.enabled:!0}),i=s.enabled?await So("POST","/tasks",{taskId:s.id,command:s.command,cron:s.cron,trigger:s.trigger,notifyOn:s.notifyOn,...s.notifyChat!==void 0?{notifyChat:s.notifyChat}:{}}):await So("DELETE",`/tasks/${s.id}`);return{content:JSON.stringify({id:s.id,name:s.name,cron:s.cron,enabled:s.enabled,daemonSynced:i.synced,syncDetail:i.detail,...i.synced?{}:{syncNote:Jg}})}},_T=async(t,e)=>{let n=br();return{content:JSON.stringify(n.map(r=>({id:r.id,name:r.name,cron:r.cron,trigger:r.trigger,enabled:r.enabled,notifyOn:r.notifyOn})))}},AT=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=tc();if(!M2(s))return{content:JSON.stringify([])};let i;try{let l=await O2(s);i=(l.length>1048576?l.subarray(l.length-1048576):l).toString("utf-8")}catch{return{content:JSON.stringify([])}}let a=i.split(`
|
|
@@ -1103,9 +1107,9 @@ ${b.content}`,isError:!0,...b.truncated===!0?{truncated:!0}:{}}),p.push({call:y,
|
|
|
1103
1107
|
|
|
1104
1108
|
${y}`:c,sessionId:this.initSessionId}:(yield{type:"assistant.message",text:c,sessionId:this.initSessionId},y!==null&&(yield{type:"notice",text:y,kind:"truncation",sessionId:this.initSessionId})),yield*this.finishTurn(p!==null?{...a,stopReason:p}:a,r)}*finishTurn(e,n){this.lastUsage=e,yield{type:"turn.completed",usage:{...e,durationMs:Date.now()-n},sessionId:this.initSessionId}}clarifyResponsesError(e,n){let r=e instanceof Error?e:new Error(String(e));if(!n||(e&&typeof e=="object"&&"status"in e?e.status:void 0)!==400&&!/\b400\b/.test(r.message))return r;let s,i=e?.error;if(i&&typeof i=="object"){let a=i;typeof a.detail=="string"?s=a.detail:typeof a.message=="string"&&(s=a.message)}return new Error(`ChatGPT/Codex backend rejected model "${this.currentModel}" (HTTP 400). A ChatGPT subscription only serves certain OpenAI models on this backend (gpt-5.6 and gpt-5.5 work; gpt-5, gpt-5.1, gpt-5.2 and *-codex do not). `+(s?`Backend said: ${s}`:"No error body was returned."))}async*runIteration(e,n,r=null){let o=vC({config:this.opts.config,...this.opts.config.resumeHistory!==void 0?{resumeHistory:this.opts.config.resumeHistory}:{},priorTurns:this.priorTurns,vision:n});if(o[0]?.role==="system"){let a=this.currentPermissionMode==="plan"?cu:this.currentPermissionMode==="autonomous"?lu:null;a!==null&&(o[0]={...o[0],content:o[0].content+`
|
|
1105
1109
|
|
|
1106
|
-
`+a})}if(r!==null){let a=r===Tt?gu:Od;o.push({role:"user",content:a})}let s=r!==null?void 0:this.activeOpenAITools(),i={controller:e,traceWriter:this.traceWriter,initSessionId:this.initSessionId,currentModel:this.currentModel,isClosed:()=>this.closed};if(this.wireMode==="responses"){let a=this.opts.auth.source==="chatgpt-oauth";if(a&&Yd(this.currentModel))return yield{type:"error",error:new Error(`Model "${this.currentModel}" can't run on a ChatGPT subscription \u2014 the ChatGPT/Codex backend only supports OpenAI gpt-5.x models. This usually means a subagent or skill requested a Claude model. Pass a gpt-5.x model to it (e.g. model: "gpt-5.5"); for an auto-dispatched agent you can't pass a model to (e.g. git-investigator), set AFK_DEFAULT_SUBAGENT_MODEL to a gpt-5.x id. Or run it on a provider configured with the matching API key.`)},null;let c=nu({model:this.currentModel,messages:o,activeTools:s,maxOutputTokens:this.opts.config.maxOutputTokens,effort:this.opts.config.effort,temperature:this.opts.config.temperature,isChatGptBackend:a});return yield*Cy(i,{createStream:async l=>await this.client.responses.create(c,{signal:l}),translate:(l,d)=>Jd(l,d,this.initSessionId),clarifyError:l=>this.clarifyResponsesError(l,a)})}else{let a=JC({model:this.currentModel,messages:o,activeTools:s,maxOutputTokens:this.opts.config.maxOutputTokens,effort:this.opts.config.effort,temperature:this.opts.config.temperature});return yield*Cy(i,{createStream:async c=>await this.client.chat.completions.create(a,{signal:c}),translate:(c,l)=>TC(c,l,this.initSessionId),clarifyError:c=>c instanceof Error?c:new Error(String(c))})}}async*dispatchAndAppend(e,n,r){return yield*sP({state:e,signal:n,vision:r,toolDispatcher:this.toolDispatcher,traceWriter:this.traceWriter,priorTurns:this.priorTurns,sessionId:this.initSessionId,subagentId:this.opts.config.subagentId})}async interrupt(e="interrupted"){this.abort.requestAbort(e)}async compact(){let e=await this.compactHistory("manual");return e.compacted&&(this.lastUsage=null),e}async compactHistory(e){let n=this.priorTurns.length;if(this.opts.auth.apiKey===null)return{compacted:!1,reason:"no-usable-auth",messagesBefore:n,messagesAfter:n};if(this.wireMode==="responses"&&this.responsesCompactionUnavailable){let s=Lo(S.AFK_MICROCOMPACT_TOOL_RESULT_BYTES,S.AFK_MICROCOMPACT_KEEP_LAST),{blocksCleared:i,bytesReclaimed:a}=wy(this.priorTurns,s);return i>0?{compacted:!1,reason:"microcompacted",messagesBefore:n,messagesAfter:this.priorTurns.length,microcompaction:{blocksCleared:i,bytesReclaimed:a}}:{compacted:!1,reason:"responses-compaction-unavailable",messagesBefore:n,messagesAfter:n}}let r=S.AFK_COMPACT_MODEL??this.currentModel,o=Gs(Se(this.lastUsage??{}),Yt(this.currentModel));return WC({priorTurns:this.priorTurns,usedFraction:o,shrinkAtFraction:HC(),summarize:(s,i)=>this.wireMode==="responses"?this.summarizeViaResponses(s,i,r):ou({client:this.client,model:r,system:Gi,user:zi(s),maxTokens:1024,signal:i}),isClosed:this.closed,isIdle:this.abort.isIdle(),beginAbort:()=>this.abort.begin(),clearAbort:s=>this.abort.clear(s),trigger:e,traceWriter:this.traceWriter})}async summarizeViaResponses(e,n,r){try{return await QC({client:this.client,model:r,system:Gi,user:zi(e),isChatGptBackend:this.opts.auth.source==="chatgpt-oauth",maxTokens:1024,signal:n})}catch(o){if(!n.aborted&&gP(o)){this.responsesCompactionUnavailable=!0;let s=Cn(o);W(this.traceWriter,{phase:"compaction_disabled",metadata:{wire:"responses",reason:"responses-compaction-unavailable",error:o instanceof Error?o.message:String(o),...s!==void 0?{status:s}:{}}})}throw o}}async setModel(e){e!==void 0&&(this.currentModel=we(e)??e)}async setPermissionMode(e){this.currentPermissionMode=Sy(e);let n=bt(this.currentPermissionMode);this.toolDispatcher?.setAllowAll?.(n),this.onPermissionMode?.(this.currentPermissionMode)}setCwd(e){this.toolDispatcher?.setResolveBase?.(e),this.onCwdChange?.(e)}async supportedCommands(){return Gd()}async supportedModels(){return[{value:"gpt-5.6",displayName:"GPT-5.6 (Sol)",description:"OpenAI flagship \u2014 alias for gpt-5.6-sol"},{value:"gpt-5.6-sol",displayName:"GPT-5.6 Sol",description:"Frontier capability"},{value:"gpt-5.6-terra",displayName:"GPT-5.6 Terra",description:"Balanced intelligence/cost"},{value:"gpt-5.6-luna",displayName:"GPT-5.6 Luna",description:"Fast, high-volume workloads"},{value:"gpt-5.5",displayName:"GPT-5.5",description:"Prior flagship (ChatGPT backend)"},{value:"gpt-4o",displayName:"GPT-4o",description:"OpenAI flagship multimodal"},{value:"gpt-4o-mini",displayName:"GPT-4o mini",description:"Fast/cheap GPT-4o"},{value:"gpt-4.1",displayName:"GPT-4.1",description:"Long-context GPT-4"},{value:"gpt-4.1-mini",displayName:"GPT-4.1 mini",description:"Fast 4.1 variant"},{value:"o1",displayName:"o1",description:"Reasoning model"},{value:"o1-mini",displayName:"o1 mini",description:"Fast reasoning"},{value:"o3-mini",displayName:"o3 mini",description:"Newer reasoning, faster"}]}async supportedAgents(){return[]}async getContextUsage(){let e=this.lastUsage,n=yt(this.currentModel),r;if(e&&n>0){let i=Se(e);r=Math.min(100,Math.max(0,i/n*100))}let{totalTokens:o,apiUsage:s}=Ws(e);return{tools:[],agents:[],isAutoCompactEnabled:this.autoCompactThreshold!==void 0,apiUsage:s,totalTokens:o,...r!==void 0?{percentage:r}:{},maxTokens:n}}async mcpServerStatus(){return this.opts.mcpManager?this.opts.mcpManager.getServerStates().map(e=>({name:e.serverName,status:e.status})):[]}async accountInfo(){return{authSource:this.opts.auth.source}}async rewindFiles(e,n){return{canRewind:!1,error:`${Py} provider does not support file checkpoint rewind yet.`}}close(){this.closed=!0,this.abort.requestAbort("closed"),this.abort.markClosed(),O(`\u{1F7E2} ${Py}: closed`)}}});var Oy,ke,M4,Bo=g(()=>{"use strict";hd();sl();bl();Vc();Zr();Ah();vr();st();Pt();Vn();ey();xn();My();su();Oe();Oh();Hi();My();Oy="openai-compatible",ke=class{name=Oy;providerOpts;memoryStore;workspaceStore;schemas;_defaultHeaders;_sharedReadRoots;_sharedWriteRoots;_currentPermissionMode="default";_initialResolveBase;_presenceSessionId=null;_mintedSessionId=null;constructor(e={}){this.providerOpts=e,this._defaultHeaders=e.defaultHeaders,this.memoryStore=e.memoryStore??new qe,this.workspaceStore=e.workspaceStore;let n=[...Lt];e.subagentExecutor&&n.push(e.subagentExecutor.describeAgentTool?.()??Ye),e.skillExecutor&&n.push(rr),e.composeExecutor&&n.push(or),e.readOnlyMemory===!0?n.push(Wr):n.push(...un),n.push(...this.workspaceStore!==void 0?Vs:[],St);for(let r of e.customTools??[])n.some(o=>o.name===r.schema.name)||n.push(r.schema);this.schemas=n}setEndpointDefaults(e){e.baseURL!==void 0&&(this.providerOpts.baseURL=e.baseURL),e.defaultHeaders!==void 0&&(this._defaultHeaders=e.defaultHeaders)}query(e){let n=e.config,r=n.permissionMode??"default";this._currentPermissionMode=r,this.ensureSharedRoots(n.cwd),n.readRoots&&this._sharedReadRoots&&this._sharedReadRoots.length<=1&&(this._sharedReadRoots.length=0,this._sharedReadRoots.push(...n.readRoots)),n.writeRoots&&this._sharedWriteRoots&&this._sharedWriteRoots.length<=1&&(this._sharedWriteRoots.length=0,this._sharedWriteRoots.push(...n.writeRoots));let o,s=typeof n.model=="string"?n.model:String(n.model),i=n.cwd??process.cwd(),a=ei({surface:this.providerOpts.surface??"cli",getCwd:()=>i,modelName:s,providerName:Oy,permissionMode:r,...n.sessionId!==void 0?{sessionId:n.sessionId}:{},...n.parentSessionId!==void 0?{parentSessionId:n.parentSessionId}:{},...n.depth!==void 0?{depth:n.depth}:{},...n.maxDepth!==void 0?{maxDepth:n.maxDepth}:{},...n.phaseRole!==void 0?{phaseRole:n.phaseRole}:{},getEnabledToolNames:()=>o instanceof Nt?o.toolDefs.map(E=>E.name):[],getMcpTools:()=>this.providerOpts.mcpManager?.getMcpTools()??[],getSubagents:()=>this.providerOpts.subagentExecutor?this.providerOpts.subagentExecutor.getSubagentsLite():{active:[],backgroundJobs:[]}});o=this.providerOpts.tools?ti(this.providerOpts.tools,a):this.buildDispatcher(r,{...n.cwd!==void 0?{cwd:n.cwd}:{},...this._sharedReadRoots!==void 0?{readRoots:this._sharedReadRoots}:{},...this._sharedWriteRoots!==void 0?{writeRoots:this._sharedWriteRoots}:{},...n.sessionId!==void 0?{sessionId:n.sessionId}:{},...n.parentSessionId!==void 0?{parentSessionId:n.parentSessionId}:{},...n.subagentId!==void 0?{subagentId:n.subagentId}:{},...n.subagentToolOutputCapBytes!==void 0?{subagentToolOutputCapBytes:n.subagentToolOutputCapBytes}:{},...n.traceWriter!==void 0?{traceWriter:n.traceWriter}:{},runtimeStateSource:a,...n.isSkillDispatch?{isSkillDispatch:!0}:{},...n.isNonInteractive?{isNonInteractive:!0}:{},...n.hookRegistry!==void 0?{hookRegistry:n.hookRegistry}:{},...n.planExitControls!==void 0?{planExitControls:n.planExitControls}:{}});let c=Oi({sessionId:n.sessionId,resume:n.resume,depth:n.depth,parentSessionId:n.parentSessionId,surface:this.providerOpts.surface??"cli",memoized:this._mintedSessionId});this._mintedSessionId=c.memoized;let l={};c.id!==void 0&&(l.sessionIdOverride=c.id);let d=n.openaiBaseUrl??this.providerOpts.baseURL;d!==void 0&&(l.baseURL=d),this._defaultHeaders!==void 0&&(l.defaultHeaders=this._defaultHeaders),l.toolDispatcher=o,l.onPermissionMode=E=>{this._currentPermissionMode=E},this.providerOpts.mcpManager!==void 0&&(l.mcpManager=this.providerOpts.mcpManager),this._presenceSessionId=Di({depth:n.depth,parentSessionId:n.parentSessionId,sessionId:c.id,currentPresenceSessionId:this._presenceSessionId,runtimeStateSource:a,surface:this.providerOpts.surface??"cli",cwd:n.cwd,providerName:Oy,model:s});let u=Hd(n.isSkillDispatch),p=Wd(this.providerOpts.readOnlyMemory),f=this.providerOpts.skillExecutor?Su(void 0,{...typeof n.cwd=="string"&&n.cwd.length>0?{cwd:n.cwd}:{},...typeof n.skillDispatchName=="string"&&n.skillDispatchName.length>0?{excludeName:n.skillDispatchName}:{}}):"",m=typeof n.hotMemory=="string"?n.hotMemory:"",h=typeof n.systemPrompt=="string"?n.systemPrompt:void 0,y=E=>{let R=[u];h!==void 0&&h.length>0&&R.push(h),R.push(p);let T=Kd(this.workspaceStore!==void 0);return T&&R.push(T),m.length>0&&R.push(m),R.push(E),f.length>0&&R.push(f),R.join(`
|
|
1110
|
+
`+a})}if(r!==null){let a=r===Tt?gu:Od;o.push({role:"user",content:a})}let s=r!==null?void 0:this.activeOpenAITools(),i={controller:e,traceWriter:this.traceWriter,initSessionId:this.initSessionId,currentModel:this.currentModel,isClosed:()=>this.closed};if(this.wireMode==="responses"){let a=this.opts.auth.source==="chatgpt-oauth";if(a&&Yd(this.currentModel))return yield{type:"error",error:new Error(`Model "${this.currentModel}" can't run on a ChatGPT subscription \u2014 the ChatGPT/Codex backend only supports OpenAI gpt-5.x models. This usually means a subagent or skill requested a Claude model. Pass a gpt-5.x model to it (e.g. model: "gpt-5.5"); for an auto-dispatched agent you can't pass a model to (e.g. git-investigator), set AFK_DEFAULT_SUBAGENT_MODEL to a gpt-5.x id. Or run it on a provider configured with the matching API key.`)},null;let c=nu({model:this.currentModel,messages:o,activeTools:s,maxOutputTokens:this.opts.config.maxOutputTokens,effort:this.opts.config.effort,temperature:this.opts.config.temperature,isChatGptBackend:a});return yield*Cy(i,{createStream:async l=>await this.client.responses.create(c,{signal:l}),translate:(l,d)=>Jd(l,d,this.initSessionId),clarifyError:l=>this.clarifyResponsesError(l,a)})}else{let a=JC({model:this.currentModel,messages:o,activeTools:s,maxOutputTokens:this.opts.config.maxOutputTokens,effort:this.opts.config.effort,temperature:this.opts.config.temperature});return yield*Cy(i,{createStream:async c=>await this.client.chat.completions.create(a,{signal:c}),translate:(c,l)=>TC(c,l,this.initSessionId),clarifyError:c=>c instanceof Error?c:new Error(String(c))})}}async*dispatchAndAppend(e,n,r){return yield*sP({state:e,signal:n,vision:r,toolDispatcher:this.toolDispatcher,traceWriter:this.traceWriter,priorTurns:this.priorTurns,sessionId:this.initSessionId,subagentId:this.opts.config.subagentId})}async interrupt(e="interrupted"){this.abort.requestAbort(e)}async compact(){let e=await this.compactHistory("manual");return e.compacted&&(this.lastUsage=null),e}async compactHistory(e){let n=this.priorTurns.length;if(this.opts.auth.apiKey===null)return{compacted:!1,reason:"no-usable-auth",messagesBefore:n,messagesAfter:n};if(this.wireMode==="responses"&&this.responsesCompactionUnavailable){let s=Lo(S.AFK_MICROCOMPACT_TOOL_RESULT_BYTES,S.AFK_MICROCOMPACT_KEEP_LAST),{blocksCleared:i,bytesReclaimed:a}=wy(this.priorTurns,s);return i>0?{compacted:!1,reason:"microcompacted",messagesBefore:n,messagesAfter:this.priorTurns.length,microcompaction:{blocksCleared:i,bytesReclaimed:a}}:{compacted:!1,reason:"responses-compaction-unavailable",messagesBefore:n,messagesAfter:n}}let r=S.AFK_COMPACT_MODEL??this.currentModel,o=Gs(Se(this.lastUsage??{}),Yt(this.currentModel));return WC({priorTurns:this.priorTurns,usedFraction:o,shrinkAtFraction:HC(),summarize:(s,i)=>this.wireMode==="responses"?this.summarizeViaResponses(s,i,r):ou({client:this.client,model:r,system:Gi,user:zi(s),maxTokens:1024,signal:i}),isClosed:this.closed,isIdle:this.abort.isIdle(),beginAbort:()=>this.abort.begin(),clearAbort:s=>this.abort.clear(s),trigger:e,traceWriter:this.traceWriter})}async summarizeViaResponses(e,n,r){try{return await QC({client:this.client,model:r,system:Gi,user:zi(e),isChatGptBackend:this.opts.auth.source==="chatgpt-oauth",maxTokens:1024,signal:n})}catch(o){if(!n.aborted&&gP(o)){this.responsesCompactionUnavailable=!0;let s=Cn(o);W(this.traceWriter,{phase:"compaction_disabled",metadata:{wire:"responses",reason:"responses-compaction-unavailable",error:o instanceof Error?o.message:String(o),...s!==void 0?{status:s}:{}}})}throw o}}async setModel(e){e!==void 0&&(this.currentModel=we(e)??e)}async setPermissionMode(e){this.currentPermissionMode=Sy(e);let n=bt(this.currentPermissionMode);this.toolDispatcher?.setAllowAll?.(n),this.onPermissionMode?.(this.currentPermissionMode)}setCwd(e){this.toolDispatcher?.setResolveBase?.(e),this.onCwdChange?.(e)}async supportedCommands(){return Gd()}async supportedModels(){return[{value:"gpt-5.6",displayName:"GPT-5.6 (Sol)",description:"OpenAI flagship \u2014 alias for gpt-5.6-sol"},{value:"gpt-5.6-sol",displayName:"GPT-5.6 Sol",description:"Frontier capability"},{value:"gpt-5.6-terra",displayName:"GPT-5.6 Terra",description:"Balanced intelligence/cost"},{value:"gpt-5.6-luna",displayName:"GPT-5.6 Luna",description:"Fast, high-volume workloads"},{value:"gpt-5.5",displayName:"GPT-5.5",description:"Prior flagship (ChatGPT backend)"},{value:"gpt-4o",displayName:"GPT-4o",description:"OpenAI flagship multimodal"},{value:"gpt-4o-mini",displayName:"GPT-4o mini",description:"Fast/cheap GPT-4o"},{value:"gpt-4.1",displayName:"GPT-4.1",description:"Long-context GPT-4"},{value:"gpt-4.1-mini",displayName:"GPT-4.1 mini",description:"Fast 4.1 variant"},{value:"o1",displayName:"o1",description:"Reasoning model"},{value:"o1-mini",displayName:"o1 mini",description:"Fast reasoning"},{value:"o3-mini",displayName:"o3 mini",description:"Newer reasoning, faster"}]}async supportedAgents(){return[]}async getContextUsage(){let e=this.lastUsage,n=yt(this.currentModel),r;if(e&&n>0){let i=Se(e);r=Math.min(100,Math.max(0,i/n*100))}let{totalTokens:o,apiUsage:s}=Ws(e);return{tools:[],agents:[],isAutoCompactEnabled:this.autoCompactThreshold!==void 0,apiUsage:s,totalTokens:o,...r!==void 0?{percentage:r}:{},maxTokens:n}}async mcpServerStatus(){return this.opts.mcpManager?this.opts.mcpManager.getServerStates().map(e=>({name:e.serverName,status:e.status})):[]}async accountInfo(){return{authSource:this.opts.auth.source}}async rewindFiles(e,n){return{canRewind:!1,error:`${Py} provider does not support file checkpoint rewind yet.`}}close(){this.closed=!0,this.abort.requestAbort("closed"),this.abort.markClosed(),O(`\u{1F7E2} ${Py}: closed`)}}});var Oy,ke,M4,Bo=g(()=>{"use strict";hd();sl();bl();Vc();Zr();Ah();vr();st();Pt();Vn();ey();xn();My();su();Oe();Oh();Hi();My();Oy="openai-compatible",ke=class{name=Oy;providerOpts;memoryStore;workspaceStore;schemas;_defaultHeaders;_sharedReadRoots;_sharedWriteRoots;_currentPermissionMode="default";_sharedCurrentCwd;_presenceSessionId=null;_mintedSessionId=null;constructor(e={}){this.providerOpts=e,this._defaultHeaders=e.defaultHeaders,this.memoryStore=e.memoryStore??new qe,this.workspaceStore=e.workspaceStore;let n=[...Lt];e.subagentExecutor&&n.push(e.subagentExecutor.describeAgentTool?.()??Ye),e.skillExecutor&&n.push(rr),e.composeExecutor&&n.push(or),e.readOnlyMemory===!0?n.push(Wr):n.push(...un),n.push(...this.workspaceStore!==void 0?Vs:[],St);for(let r of e.customTools??[])n.some(o=>o.name===r.schema.name)||n.push(r.schema);this.schemas=n}setEndpointDefaults(e){e.baseURL!==void 0&&(this.providerOpts.baseURL=e.baseURL),e.defaultHeaders!==void 0&&(this._defaultHeaders=e.defaultHeaders)}query(e){let n=e.config,r=n.permissionMode??"default";this._currentPermissionMode=r,this.ensureSharedRoots(n.cwd),n.readRoots&&this._sharedReadRoots&&this._sharedReadRoots.length<=1&&(this._sharedReadRoots.length=0,this._sharedReadRoots.push(...n.readRoots)),n.writeRoots&&this._sharedWriteRoots&&this._sharedWriteRoots.length<=1&&(this._sharedWriteRoots.length=0,this._sharedWriteRoots.push(...n.writeRoots));let o,s=typeof n.model=="string"?n.model:String(n.model),i=n.cwd??process.cwd(),a=ei({surface:this.providerOpts.surface??"cli",getCwd:()=>i,modelName:s,providerName:Oy,permissionMode:r,...n.sessionId!==void 0?{sessionId:n.sessionId}:{},...n.parentSessionId!==void 0?{parentSessionId:n.parentSessionId}:{},...n.depth!==void 0?{depth:n.depth}:{},...n.maxDepth!==void 0?{maxDepth:n.maxDepth}:{},...n.phaseRole!==void 0?{phaseRole:n.phaseRole}:{},getEnabledToolNames:()=>o instanceof Nt?o.toolDefs.map(E=>E.name):[],getMcpTools:()=>this.providerOpts.mcpManager?.getMcpTools()??[],getSubagents:()=>this.providerOpts.subagentExecutor?this.providerOpts.subagentExecutor.getSubagentsLite():{active:[],backgroundJobs:[]}});o=this.providerOpts.tools?ti(this.providerOpts.tools,a):this.buildDispatcher(r,{...n.cwd!==void 0?{cwd:n.cwd}:{},...this._sharedReadRoots!==void 0?{readRoots:this._sharedReadRoots}:{},...this._sharedWriteRoots!==void 0?{writeRoots:this._sharedWriteRoots}:{},...n.sessionId!==void 0?{sessionId:n.sessionId}:{},...n.parentSessionId!==void 0?{parentSessionId:n.parentSessionId}:{},...n.subagentId!==void 0?{subagentId:n.subagentId}:{},...n.subagentToolOutputCapBytes!==void 0?{subagentToolOutputCapBytes:n.subagentToolOutputCapBytes}:{},...n.traceWriter!==void 0?{traceWriter:n.traceWriter}:{},runtimeStateSource:a,...n.isSkillDispatch?{isSkillDispatch:!0}:{},...n.isNonInteractive?{isNonInteractive:!0}:{},...n.hookRegistry!==void 0?{hookRegistry:n.hookRegistry}:{},...n.planExitControls!==void 0?{planExitControls:n.planExitControls}:{}});let c=Oi({sessionId:n.sessionId,resume:n.resume,depth:n.depth,parentSessionId:n.parentSessionId,surface:this.providerOpts.surface??"cli",memoized:this._mintedSessionId});this._mintedSessionId=c.memoized;let l={};c.id!==void 0&&(l.sessionIdOverride=c.id);let d=n.openaiBaseUrl??this.providerOpts.baseURL;d!==void 0&&(l.baseURL=d),this._defaultHeaders!==void 0&&(l.defaultHeaders=this._defaultHeaders),l.toolDispatcher=o,l.onPermissionMode=E=>{this._currentPermissionMode=E},this.providerOpts.mcpManager!==void 0&&(l.mcpManager=this.providerOpts.mcpManager),this._presenceSessionId=Di({depth:n.depth,parentSessionId:n.parentSessionId,sessionId:c.id,currentPresenceSessionId:this._presenceSessionId,runtimeStateSource:a,surface:this.providerOpts.surface??"cli",cwd:n.cwd,providerName:Oy,model:s});let u=Hd(n.isSkillDispatch),p=Wd(this.providerOpts.readOnlyMemory),f=this.providerOpts.skillExecutor?Su(void 0,{...typeof n.cwd=="string"&&n.cwd.length>0?{cwd:n.cwd}:{},...typeof n.skillDispatchName=="string"&&n.skillDispatchName.length>0?{excludeName:n.skillDispatchName}:{}}):"",m=typeof n.hotMemory=="string"?n.hotMemory:"",h=typeof n.systemPrompt=="string"?n.systemPrompt:void 0,y=E=>{let R=[u];h!==void 0&&h.length>0&&R.push(h),R.push(p);let T=Kd(this.workspaceStore!==void 0);return T&&R.push(T),m.length>0&&R.push(m),R.push(E),f.length>0&&R.push(f),R.join(`
|
|
1107
1111
|
|
|
1108
|
-
`)},b=()=>Zs({cwd:i,...n.sessionId!==void 0?{sessionId:n.sessionId}:{},surface:this.providerOpts.surface??"cli",...n.depth!==void 0?{depth:n.depth}:{},...n.maxDepth!==void 0?{maxDepth:n.maxDepth}:{},workspace:a.getWorkspace()}),k={...n,systemPrompt:y(b())},_=E=>{i=E,k.systemPrompt=y(b())};return l.onCwdChange=_,yP(k,e.prompt,l)}buildDispatcher(e,n){let r=pd(e,n.cwd),o=Ps(this.memoryStore,void 0,this.providerOpts.surface??"cli");for(let[d,u]of o)this.providerOpts.readOnlyMemory===!0&&d!=="memory_search"||r.set(d,u);if(this.workspaceStore!==void 0)for(let[d,u]of Js(this.workspaceStore,n.sessionId??"",n.subagentId))r.set(d,u);n.runtimeStateSource&&r.set("get_runtime_state",eo(n.runtimeStateSource));for(let d of this.providerOpts.customTools??[])r.has(d.schema.name)||r.set(d.schema.name,d.handler);let s=n.planExitControls;s&&r.set(dt,md(s));let i=this.providerOpts.mcpManager?this.providerOpts.mcpManager.getMcpTools():[];if(this.providerOpts.mcpManager)for(let[d,u]of this.providerOpts.mcpManager.getMcpHandlers())r.set(d,u);let a=n.isSkillDispatch?this.schemas.filter(d=>d.name!=="ask_question"&&d.name!=="terminal_font_size"):n.isNonInteractive?this.schemas.filter(d=>d.name!=="ask_question"):this.schemas,c={handlers:r,schemas:[...a,...i,...s?[fd]:[]],hookRegistry:gd(n.hookRegistry,this.providerOpts.hookRegistry)},l=ol(this.providerOpts.mcpManager?rl(this.providerOpts.permissions,this.providerOpts.mcpManager.getMcpToolWireNames()):this.providerOpts.permissions,(this.providerOpts.customTools??[]).map(d=>d.schema.name));return l!==void 0&&(c.permissions=l),this.providerOpts.subagentExecutor!==void 0&&(c.subagentExecutor=this.providerOpts.subagentExecutor),this.providerOpts.skillExecutor!==void 0&&(c.skillExecutor=this.providerOpts.skillExecutor),this.providerOpts.composeExecutor!==void 0&&(c.composeExecutor=this.providerOpts.composeExecutor),this.providerOpts.canUseTool!==void 0&&(c.canUseTool=this.providerOpts.canUseTool),n.cwd!==void 0&&(c.cwd=n.cwd),n.readRoots!==void 0&&(c.readRoots=n.readRoots),n.writeRoots!==void 0&&(c.writeRoots=n.writeRoots),n.sessionId!==void 0&&(c.sessionId=n.sessionId),n.parentSessionId!==void 0&&(c.parentSessionId=n.parentSessionId),n.subagentId!==void 0&&(c.subagentId=n.subagentId),n.subagentToolOutputCapBytes!==void 0&&(c.maxOutputBytes=n.subagentToolOutputCapBytes),n.traceWriter!==void 0&&(c.traceWriter=n.traceWriter),this.providerOpts.readOnlyBash===!0&&(c.readOnlyBash=!0),c.allowAll=bt(e),c.sessionGrantManager=this,new Nt(c)}ensureSharedRoots(e){if(!this._sharedReadRoots){let n=e?[e]:[];this._sharedReadRoots=n.slice(),this._sharedWriteRoots=n.slice(),e&&!this.
|
|
1112
|
+
`)},b=()=>Zs({cwd:i,...n.sessionId!==void 0?{sessionId:n.sessionId}:{},surface:this.providerOpts.surface??"cli",...n.depth!==void 0?{depth:n.depth}:{},...n.maxDepth!==void 0?{maxDepth:n.maxDepth}:{},workspace:a.getWorkspace()}),k={...n,systemPrompt:y(b())},_=E=>{i=E,this._sharedCurrentCwd=E,k.systemPrompt=y(b())};return l.onCwdChange=_,yP(k,e.prompt,l)}buildDispatcher(e,n){let r=pd(e,n.cwd),o=Ps(this.memoryStore,void 0,this.providerOpts.surface??"cli");for(let[d,u]of o)this.providerOpts.readOnlyMemory===!0&&d!=="memory_search"||r.set(d,u);if(this.workspaceStore!==void 0)for(let[d,u]of Js(this.workspaceStore,n.sessionId??"",n.subagentId))r.set(d,u);n.runtimeStateSource&&r.set("get_runtime_state",eo(n.runtimeStateSource));for(let d of this.providerOpts.customTools??[])r.has(d.schema.name)||r.set(d.schema.name,d.handler);let s=n.planExitControls;s&&r.set(dt,md(s));let i=this.providerOpts.mcpManager?this.providerOpts.mcpManager.getMcpTools():[];if(this.providerOpts.mcpManager)for(let[d,u]of this.providerOpts.mcpManager.getMcpHandlers())r.set(d,u);let a=n.isSkillDispatch?this.schemas.filter(d=>d.name!=="ask_question"&&d.name!=="terminal_font_size"):n.isNonInteractive?this.schemas.filter(d=>d.name!=="ask_question"):this.schemas,c={handlers:r,schemas:[...a,...i,...s?[fd]:[]],hookRegistry:gd(n.hookRegistry,this.providerOpts.hookRegistry)},l=ol(this.providerOpts.mcpManager?rl(this.providerOpts.permissions,this.providerOpts.mcpManager.getMcpToolWireNames()):this.providerOpts.permissions,(this.providerOpts.customTools??[]).map(d=>d.schema.name));return l!==void 0&&(c.permissions=l),this.providerOpts.subagentExecutor!==void 0&&(c.subagentExecutor=this.providerOpts.subagentExecutor),this.providerOpts.skillExecutor!==void 0&&(c.skillExecutor=this.providerOpts.skillExecutor),this.providerOpts.composeExecutor!==void 0&&(c.composeExecutor=this.providerOpts.composeExecutor),this.providerOpts.canUseTool!==void 0&&(c.canUseTool=this.providerOpts.canUseTool),n.cwd!==void 0&&(c.cwd=n.cwd),n.readRoots!==void 0&&(c.readRoots=n.readRoots),n.writeRoots!==void 0&&(c.writeRoots=n.writeRoots),n.sessionId!==void 0&&(c.sessionId=n.sessionId),n.parentSessionId!==void 0&&(c.parentSessionId=n.parentSessionId),n.subagentId!==void 0&&(c.subagentId=n.subagentId),n.subagentToolOutputCapBytes!==void 0&&(c.maxOutputBytes=n.subagentToolOutputCapBytes),n.traceWriter!==void 0&&(c.traceWriter=n.traceWriter),this.providerOpts.readOnlyBash===!0&&(c.readOnlyBash=!0),c.allowAll=bt(e),c.sessionGrantManager=this,new Nt(c)}ensureSharedRoots(e){if(!this._sharedReadRoots){let n=e?[e]:[];this._sharedReadRoots=n.slice(),this._sharedWriteRoots=n.slice(),e&&!this._sharedCurrentCwd&&(this._sharedCurrentCwd=e)}}grantManager=new yn({getReadRoots:()=>this._sharedReadRoots,getWriteRoots:()=>this._sharedWriteRoots,ensureInitialized:()=>this.ensureSharedRoots(),getProtectedRoot:()=>this._sharedCurrentCwd,getAllowAll:()=>bt(this._currentPermissionMode)});addReadRoot(e,n="slash",r){this.grantManager.addReadRoot(e,n,r)}addWriteRoot(e,n="slash",r){this.grantManager.addWriteRoot(e,n,r)}revokeRoot(e,n="slash",r){this.grantManager.revokeRoot(e,n,r)}getGrants(){return this.grantManager.getGrants()}close(){this.memoryStore.close(),this.workspaceStore?.close()}async complete(e){let n={model:e.model??"gpt-4o-mini",system:e.system,user:e.user,maxTokens:e.maxTokens??64};e.apiKey!==void 0&&(n.apiKey=e.apiKey);let r=e.baseUrl??this.providerOpts.baseURL;return r!==void 0&&(n.baseURL=r),this._defaultHeaders!==void 0&&(n.defaultHeaders=this._defaultHeaders),e.signal&&(n.signal=e.signal),ou(n)}},M4=new ke});function Mn(t,e){if(t.has(e))return!0;let n=e.charAt(0).toUpperCase()+e.slice(1);return n!==e&&t.has(n)}function vu(t){return t.startsWith("mcp__")||t.startsWith("MCP__")?"mcp":Mn(O4,t)?"read":Mn(D4,t)?"write":Mn(F4,t)?"shell":Mn(bP,t)?"subagent":Mn(wP,t)?"skill":Mn(SP,t)?"dag":Mn(L4,t)?"web":N4.has(t)?"browser":Mn(U4,t)?"planning":$4.has(t)?"schedule":"other"}var O4,D4,F4,bP,wP,SP,mSe,L4,N4,U4,$4,Dy,vP,ea=g(()=>{"use strict";ul();O4=new Set(["Read","Glob","Grep","NotebookRead","LS","read_file","extract_document","glob","grep","list_directory","config_get","memory_search","workspace_query","read_witness","search_witness"]),D4=new Set(["Write","Edit","NotebookEdit","MultiEdit","write_file","edit_file","memory_update","procedure_write","terminal_font_size","config_set","workspace_publish"]),F4=new Set(["Bash","BashOutput","KillBash","bash"]),bP=new Set(["Agent","Task","agent","cancel_background_job"]),wP=new Set(["Skill","skill"]),SP=new Set(["Compose","compose"]),mSe=new Set([...bP,...SP,...wP]),L4=new Set(["WebFetch","WebSearch","send_telegram","web_scrape"]),N4=new Set(["browser_open","browser_observe","browser_act","browser_screenshot","browser_extract","browser_close"]),U4=new Set(["TaskCreate","TaskUpdate","TaskList","TaskGet","TaskOutput","TaskStop","EnterPlanMode","ExitPlanMode","ToolSearch"]),$4=new Set(["create_schedule","list_schedules","get_schedule_history","cancel_schedule"]);Dy=["Read","Glob","Grep","NotebookRead","LS","read_file","extract_document","glob","grep","list_directory","config_get","memory_search","read_witness","search_witness","workspace_publish","workspace_query",...Me],vP=[...Dy,"web_scrape","agent"]});function kP(t,e){return`Skill tool not available at nesting depth ${t} (max ${e}). ${Fy}`}function _P(t,e){return`Agent tool not available at nesting depth ${t} (max ${e}). ${Fy}`}function AP(t,e){return`Compose tool not available at nesting depth ${t} (max ${e}). ${Fy}`}var Fy,ku=g(()=>{"use strict";Fy="You are too deeply nested to delegate further \u2014 perform the work inline with your own tools instead of calling skill/agent/compose."});function EP(t){return B4.has(t)}var B4,TP=g(()=>{"use strict";B4=new Set});function RP(t){for(let e of j4)e(t)}function xP(t){for(let e of H4)e(t)}var j4,H4,IP=g(()=>{"use strict";j4=new Set,H4=new Set});function _u(t){return W4.has(t)}function CP(t,e=K4){return t.length<=e?t:t.slice(0,e)+"\u2026"}function jo(t){return t.surface!==void 0?{origin:ln(t.surface),actor:dn(t.depth)}:{}}var W4,K4,Ly=g(()=>{"use strict";Hn();W4=new Set(["ask-gate","fanout-pace","right-size-delegation","premise-gate","long-bash-gate","exploration-gate","irreversible-action-gate","safe-destruct","plan-probe"]);K4=240});function PP(t){let e=[],n="",r=null,o=!1;for(let s of t){if(r!==null){s===r?r=null:n+=s;continue}if(s==='"'||s==="'"){r=s,o=!0;continue}if(/\s/.test(s)){o&&(e.push(n),n="",o=!1);continue}n+=s,o=!0}return o&&e.push(n),e}function On(t,e){let n=e??"",r;return t.replace(/(\\?)\$(ARGUMENTS?\b|\{(\d+)\})/g,(o,s,i,a)=>{if(s==="\\")return o.slice(1);if(i==="ARGUMENT"||i==="ARGUMENTS")return n;let c=Number(a);return c<1?o:(r??=PP(n),r[c-1]??o)})}var Au=g(()=>{"use strict"});function MP(t,e,n){let r=n&&n.trim().length>0?n.trim():"(none)";return{content:`${`[Skill "${t}" loaded into your current context \u2014 act on it now]
|
|
1109
1113
|
The instructions below are your operating procedure for THIS task. Execute them immediately, in this session, using the tools you already have. This is an instruction set, not reference material: follow it directly \u2014 do not merely summarize or describe it. No sub-agent was forked; you are the one carrying it out.
|
|
1110
1114
|
Arguments: ${r}`}
|
|
1111
1115
|
|