[{"data":1,"prerenderedAt":716},["ShallowReactive",2],{"navigation_docs":3,"-tools-browser":139,"-tools-browser-surround":711},[4,8,12,16,20,24,28,32,59,63,117,121,135],{"title":5,"path":6,"stem":7},"Introduction","\u002Fintroduction","1.introduction",{"title":9,"path":10,"stem":11},"Memory","\u002Fmemory","10.memory",{"title":13,"path":14,"stem":15},"Customization","\u002Fcustomization","11.customization",{"title":17,"path":18,"stem":19},"Deployment","\u002Fdeployment","12.deployment",{"title":21,"path":22,"stem":23},"Reference","\u002Freference","13.reference",{"title":25,"path":26,"stem":27},"Quickstart","\u002Fquickstart","2.quickstart",{"title":29,"path":30,"stem":31},"Installation","\u002Finstallation","3.installation",{"title":33,"icon":34,"path":35,"stem":36,"children":37,"page":58},"Connectors","i-lucide-cable","\u002Fconnectors","4.connectors",[38,42,46,50,54],{"title":39,"path":40,"stem":41},"Telegram","\u002Fconnectors\u002Ftelegram","4.connectors\u002F1.telegram",{"title":43,"path":44,"stem":45},"Slack","\u002Fconnectors\u002Fslack","4.connectors\u002F2.slack",{"title":47,"path":48,"stem":49},"Email","\u002Fconnectors\u002Femail","4.connectors\u002F3.email",{"title":51,"path":52,"stem":53},"API","\u002Fconnectors\u002Fapi","4.connectors\u002F4.api",{"title":55,"path":56,"stem":57},"Terminal","\u002Fconnectors\u002Fterminal","4.connectors\u002F5.terminal",false,{"title":60,"path":61,"stem":62},"Attachments","\u002Fattachments","5.attachments",{"title":64,"icon":65,"path":66,"stem":67,"children":68,"page":58},"Tools","i-lucide-wrench","\u002Ftools","6.tools",[69,73,77,81,85,89,93,97,101,105,109,113],{"title":70,"path":71,"stem":72},"File Manager","\u002Ftools\u002Ffile-manager","6.tools\u002F1.file-manager",{"title":74,"path":75,"stem":76},"Text-to-Speech","\u002Ftools\u002Ftext-to-speech","6.tools\u002F10.text-to-speech",{"title":78,"path":79,"stem":80},"Confirmations","\u002Ftools\u002Fconfirmations","6.tools\u002F11.confirmations",{"title":82,"path":83,"stem":84},"Adding Custom Tools","\u002Ftools\u002Fadding-custom-tools","6.tools\u002F12.adding-custom-tools",{"title":86,"path":87,"stem":88},"Image Manager","\u002Ftools\u002Fimage-manager","6.tools\u002F2.image-manager",{"title":90,"path":91,"stem":92},"Web Request","\u002Ftools\u002Fweb-request","6.tools\u002F3.web-request",{"title":94,"path":95,"stem":96},"Reminders","\u002Ftools\u002Freminders","6.tools\u002F4.reminders",{"title":98,"path":99,"stem":100},"Heartbeats","\u002Ftools\u002Fheartbeats","6.tools\u002F5.heartbeats",{"title":102,"path":103,"stem":104},"Email Manager","\u002Ftools\u002Femail-manager","6.tools\u002F6.email-manager",{"title":106,"path":107,"stem":108},"Calendar","\u002Ftools\u002Fcalendar","6.tools\u002F7.calendar",{"title":110,"path":111,"stem":112},"Read Database","\u002Ftools\u002Fread-database","6.tools\u002F8.read-database",{"title":114,"path":115,"stem":116},"Headless Browser","\u002Ftools\u002Fbrowser","6.tools\u002F9.browser",{"title":118,"path":119,"stem":120},"Tinker","\u002Ftinker","7.tinker",{"title":122,"icon":123,"path":124,"stem":125,"children":126,"page":58},"Skills","i-lucide-sparkles","\u002Fskills","8.skills",[127,131],{"title":128,"path":129,"stem":130},"Overview","\u002Fskills\u002Foverview","8.skills\u002F1.overview",{"title":132,"path":133,"stem":134},"Adding Custom Skills","\u002Fskills\u002Fadding-custom-skills","8.skills\u002F2.adding-custom-skills",{"title":136,"path":137,"stem":138},"Personas","\u002Fpersonas","9.personas",{"id":140,"title":114,"body":141,"description":704,"extension":705,"links":706,"meta":707,"navigation":708,"path":115,"seo":709,"stem":116,"__hash__":710},"docs\u002F6.tools\u002F9.browser.md",{"type":142,"value":143,"toc":696},"minimark",[144,148,166,172,175,179,182,199,202,217,221,224,248,251,291,298,333,340,343,366,372,376,383,508,526,533,550,589,593,599,633,637,648,692],[145,146,5],"h2",{"id":147},"introduction",[149,150,151,152,159,160,165],"p",{},"The Headless Browser tool gives the agent a real browser. It can navigate to a URL, wait for JavaScript to render, return the page as markdown or a semantic tree, click elements, fill forms, and run JS in the page context. Built on top of ",[153,154,158],"a",{"href":155,"rel":156},"https:\u002F\u002Fgithub.com\u002Fferdiunal\u002Flarapanda",[157],"nofollow","ferdiunal\u002Flarapanda",", which wraps ",[153,161,164],{"href":162,"rel":163},"https:\u002F\u002Flightpanda.io",[157],"Lightpanda"," — a lightweight headless browser written in Zig.",[149,167,168,169,171],{},"If all you need is plain HTTP, ",[153,170,90],{"href":91}," is enough. Reach for the browser when the page is a SPA, hides content behind cookie walls, or only fills in after a network request lands.",[149,173,174],{},"It's disabled by default.",[145,176,178],{"id":177},"requirements","Requirements",[149,180,181],{},"The tool depends on two things that don't ship with laraclaw:",[183,184,185,196],"ol",{},[186,187,188,189,195],"li",{},"The ",[153,190,192],{"href":155,"rel":191},[157],[193,194,158],"code",{}," Composer package",[186,197,198],{},"A Lightpanda runtime — either the native CLI binary or Docker",[149,200,201],{},"The wizard can install both for you, or you can install them yourself and just point the wizard at them.",[203,204,205],"blockquote",{},[149,206,207,211,212,216],{},[208,209,210],"span",{},"!IMPORTANT","\nLarapanda v1.0 requires ",[213,214,215],"strong",{},"PHP 8.5",". Laraclaw itself runs on PHP 8.4, so if you're still on 8.4 you'll need to upgrade before you can enable the browser tool.",[145,218,220],{"id":219},"enabling-the-browser","Enabling the Browser",[149,222,223],{},"Run the wizard:",[225,226,231],"pre",{"className":227,"code":228,"language":229,"meta":230,"style":230},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","php artisan laraclaw:setup-browser\n","bash","",[193,232,233],{"__ignoreMap":230},[208,234,237,241,245],{"class":235,"line":236},"line",1,[208,238,240],{"class":239},"sBMFI","php",[208,242,244],{"class":243},"sfazB"," artisan",[208,246,247],{"class":243}," laraclaw:setup-browser\n",[149,249,250],{},"It walks two opt-in prompts:",[183,252,253,266],{},[186,254,255,261,262,265],{},[213,256,257,258,260],{},"Install ",[193,259,158],{}," now via composer?"," If yes, the wizard runs ",[193,263,264],{},"composer require ferdiunal\u002Flarapanda"," for you and streams the output. Composer regenerates the autoloader on disk but the running PHP process keeps its in-memory classmap, so the wizard exits after install and asks you to re-run it.",[186,267,268,271,272,275,276,278,279,282,283,286,287,290],{},[213,269,270],{},"Install the Lightpanda binary now via the official install script?"," If yes, it pipes ",[193,273,274],{},"https:\u002F\u002Fpkg.lightpanda.io\u002Finstall.sh"," to ",[193,277,229],{}," and then prefills the path prompt with the most likely install location (",[193,280,281],{},"\u002Fusr\u002Flocal\u002Fbin\u002Flightpanda",", ",[193,284,285],{},"~\u002F.lightpanda\u002Fbin\u002Flightpanda",", or ",[193,288,289],{},"~\u002F.local\u002Fbin\u002Flightpanda",").",[149,292,293,294,297],{},"Both prompts default to ",[213,295,296],{},"no",", so nothing is installed unless you explicitly say yes. If you'd rather install them yourself:",[225,299,301],{"className":227,"code":300,"language":229,"meta":230,"style":230},"composer require ferdiunal\u002Flarapanda\ncurl -fsSL https:\u002F\u002Fpkg.lightpanda.io\u002Finstall.sh | bash\n",[193,302,303,314],{"__ignoreMap":230},[208,304,305,308,311],{"class":235,"line":236},[208,306,307],{"class":239},"composer",[208,309,310],{"class":243}," require",[208,312,313],{"class":243}," ferdiunal\u002Flarapanda\n",[208,315,317,320,323,326,330],{"class":235,"line":316},2,[208,318,319],{"class":239},"curl",[208,321,322],{"class":243}," -fsSL",[208,324,325],{"class":243}," https:\u002F\u002Fpkg.lightpanda.io\u002Finstall.sh",[208,327,329],{"class":328},"sMK4o"," |",[208,331,332],{"class":239}," bash\n",[149,334,335,336,339],{},"Leave the binary path blank and Larapanda falls back to running Lightpanda in Docker via the ",[193,337,338],{},"lightpanda\u002Fbrowser:nightly"," image. Useful for containerized setups where you don't want a binary on the host.",[149,341,342],{},"The wizard writes:",[225,344,348],{"className":345,"code":346,"language":347,"meta":230,"style":230},"language-env shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","LARACLAW_BROWSER_ENABLED=true\nLARAPANDA_RUNTIME=auto\nLARAPANDA_BINARY_PATH=\u002Fusr\u002Flocal\u002Fbin\u002Flightpanda\n","env",[193,349,350,355,360],{"__ignoreMap":230},[208,351,352],{"class":235,"line":236},[208,353,354],{},"LARACLAW_BROWSER_ENABLED=true\n",[208,356,357],{"class":235,"line":316},[208,358,359],{},"LARAPANDA_RUNTIME=auto\n",[208,361,363],{"class":235,"line":362},3,[208,364,365],{},"LARAPANDA_BINARY_PATH=\u002Fusr\u002Flocal\u002Fbin\u002Flightpanda\n",[149,367,368,371],{},[193,369,370],{},"LARAPANDA_RUNTIME=auto"," lets Larapanda prefer the CLI binary when it's present and fall back to Docker otherwise.",[145,373,375],{"id":374},"what-the-agent-gets","What the Agent Gets",[149,377,378,379,382],{},"When enabled, the entire Lightpanda tool catalog from Larapanda is registered with the agent, prefixed ",[193,380,381],{},"lightpanda_",". The most common ones:",[384,385,386,399],"table",{},[387,388,389],"thead",{},[390,391,392,396],"tr",{},[393,394,395],"th",{},"Tool",[393,397,398],{},"What it does",[400,401,402,413,423,433,443,456,468,478,488,498],"tbody",{},[390,403,404,410],{},[405,406,407],"td",{},[193,408,409],{},"lightpanda_goto",[405,411,412],{},"Navigate to a URL and load it into session memory",[390,414,415,420],{},[405,416,417],{},[193,418,419],{},"lightpanda_markdown",[405,421,422],{},"Return the current page as markdown",[390,424,425,430],{},[405,426,427],{},[193,428,429],{},"lightpanda_semantic_tree",[405,431,432],{},"Return a simplified DOM tree suitable for reasoning",[390,434,435,440],{},[405,436,437],{},[193,438,439],{},"lightpanda_interactiveElements",[405,441,442],{},"List clickable \u002F focusable nodes with backend IDs",[390,444,445,450],{},[405,446,447],{},[193,448,449],{},"lightpanda_click",[405,451,452,453],{},"Click an element by its ",[193,454,455],{},"backendNodeId",[390,457,458,463],{},[405,459,460],{},[193,461,462],{},"lightpanda_fill",[405,464,465,466],{},"Fill a form input by ",[193,467,455],{},[390,469,470,475],{},[405,471,472],{},[193,473,474],{},"lightpanda_waitForSelector",[405,476,477],{},"Wait for a CSS selector to appear",[390,479,480,485],{},[405,481,482],{},[193,483,484],{},"lightpanda_evaluate",[405,486,487],{},"Run JavaScript in the page context",[390,489,490,495],{},[405,491,492],{},[193,493,494],{},"lightpanda_links",[405,496,497],{},"Extract every link from the current page",[390,499,500,505],{},[405,501,502],{},[193,503,504],{},"lightpanda_structuredData",[405,506,507],{},"Pull JSON-LD and OpenGraph metadata",[149,509,510,511,514,515,518,519,518,522,525],{},"Tools are session-aware. The agent passes a ",[193,512,513],{},"session_id"," to keep page state across calls — for example, ",[193,516,517],{},"goto"," then ",[193,520,521],{},"click",[193,523,524],{},"markdown"," all on the same session.",[149,527,528,529,532],{},"To restrict which tools the agent sees, publish the larapanda config and set ",[193,530,531],{},"integrations.ai.exposed_tools",":",[225,534,536],{"className":227,"code":535,"language":229,"meta":230,"style":230},"php artisan vendor:publish --tag=larapanda-config\n",[193,537,538],{"__ignoreMap":230},[208,539,540,542,544,547],{"class":235,"line":236},[208,541,240],{"class":239},[208,543,244],{"class":243},[208,545,546],{"class":243}," vendor:publish",[208,548,549],{"class":243}," --tag=larapanda-config\n",[225,551,554],{"className":552,"code":553,"language":240,"meta":230,"style":230},"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F config\u002Flarapanda.php\n'integrations' => [\n    'ai' => [\n        'exposed_tools' => ['goto', 'markdown', 'semantic_tree'],\n    ],\n],\n",[193,555,556,561,566,571,577,583],{"__ignoreMap":230},[208,557,558],{"class":235,"line":236},[208,559,560],{},"\u002F\u002F config\u002Flarapanda.php\n",[208,562,563],{"class":235,"line":316},[208,564,565],{},"'integrations' => [\n",[208,567,568],{"class":235,"line":362},[208,569,570],{},"    'ai' => [\n",[208,572,574],{"class":235,"line":573},4,[208,575,576],{},"        'exposed_tools' => ['goto', 'markdown', 'semantic_tree'],\n",[208,578,580],{"class":235,"line":579},5,[208,581,582],{},"    ],\n",[208,584,586],{"class":235,"line":585},6,[208,587,588],{},"],\n",[145,590,592],{"id":591},"runtime-modes","Runtime Modes",[149,594,595,596,532],{},"Larapanda resolves at request time based on ",[193,597,598],{},"LARAPANDA_RUNTIME",[600,601,602,614,622],"ul",{},[186,603,604,609,610,613],{},[213,605,606],{},[193,607,608],{},"auto"," — prefer the binary at ",[193,611,612],{},"LARAPANDA_BINARY_PATH"," when it's executable; otherwise fall back to Docker. This is what the wizard sets.",[186,615,616,621],{},[213,617,618],{},[193,619,620],{},"cli"," — require the binary. Faster cold start. Fails if the binary is missing.",[186,623,624,629,630,632],{},[213,625,626],{},[193,627,628],{},"docker"," — always run inside ",[193,631,338],{},". No binary needed, but each session pays the container start cost.",[145,634,636],{"id":635},"security-considerations","Security Considerations",[203,638,639],{},[149,640,641,644,645,647],{},[208,642,643],{},"!NOTE","\nThe browser can fetch any URL the host machine can reach. There is no internal-network blocklist, unlike ",[153,646,90],{"href":91}," which guards against private IPs. Treat it as the agent having outbound HTTP from your server.",[600,649,650,660,666,683],{},[186,651,652,655,656,659],{},[213,653,654],{},"Sessions live in memory."," The default TTL is 5 minutes (",[193,657,658],{},"LARAPANDA_AI_SESSION_TTL","); set it lower if you're paranoid about leftover page state between conversations.",[186,661,662,665],{},[213,663,664],{},"JavaScript runs in the headless context."," Pages can read cookies and local storage of the session they're in, but those are scoped per Lightpanda process, not your app.",[186,667,668,674,675,678,679,682],{},[213,669,670,673],{},[193,671,672],{},"obey_robots"," is on by default."," Larapanda will refuse to navigate to URLs disallowed by ",[193,676,677],{},"robots.txt",". Toggle with ",[193,680,681],{},"LARAPANDA_AI_OBEY_ROBOTS=false"," if you're scraping with permission.",[186,684,685,691],{},[213,686,687,688],{},"Enable ",[193,689,690],{},"LARACLAW_LOG_AGENT_REQUESTS=true"," to keep an audit trail of every fetch.",[693,694,695],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}",{"title":230,"searchDepth":316,"depth":316,"links":697},[698,699,700,701,702,703],{"id":147,"depth":316,"text":5},{"id":177,"depth":316,"text":178},{"id":219,"depth":316,"text":220},{"id":374,"depth":316,"text":375},{"id":591,"depth":316,"text":592},{"id":635,"depth":316,"text":636},"Let the agent fetch and interact with JavaScript-rendered pages through Lightpanda.","md",null,{},true,{"title":114,"description":704},"bfazZXClkKQmFV_G1ujR9RTs40ybJ3VQuSuDA9nwZPE",[712,714],{"title":110,"path":111,"stem":112,"description":713,"children":-1},"Let the agent run SELECT queries against your application database through a read-only connection.",{"title":118,"path":119,"stem":120,"description":715,"children":-1},"Let the agent evaluate PHP in the context of your running Laravel app.",1786661906119]