page-agent
Libraryalibaba/page-agent
JavaScript library for controlling web UIs with natural language.
Overview
Page Agent is an in-page GUI agent that manipulates web interfaces through text-based DOM operations. It does not require screenshots, multi-modal models, or browser extensions, and supports custom LLMs. Easily integrate it into any webpage with a script tag or npm package.
README Preview
# Page Agent\n\n\n \n \n\n\n[](https://opensource.org/licenses/MIT) [](http://www.typescriptlang.org/) [](https://bundlephobia.com/package/page-agent) [](https://www.npmjs.com/package/page-agent) [](https://github.com/alibaba/page-agent)\n\nThe GUI Agent Living in Your Webpage. Control web interfaces with natural language.\n\n🌐 **English** | [中文](./docs/README-zh.md)\n\n🚀 Demo | 📖 Docs | 📢 HN Discussion | 𝕏 Follow on X\n\n\n\nhttps://github.com/user-attachments/assets/a1f2eae2-13fb-4aae-98cf-a3fc1620a6c2\n\n---\n\n## ✨ Features\n\n- **🎯 Easy integration**\n - No need for `browser extension` / `python` / `headless browser`.\n - Just in-page javascript. Everything happens in your web page.\n- **📖 Text-based DOM manipulation**\n - No screenshots. No multi-modal LLMs or special permissions needed.\n- **🧠 Bring your own LLMs**\n- **🐙 Optional [chrome extension](https://alibaba.github.io/page-agent/docs/features/chrome-extension) for multi-page tasks.**\n - And an [MCP Server (Beta)](https://alibaba.github.io/page-agent/docs/features/mcp-server) to control it from outside\n\n## 💡 Use Cases\n\n- **SaaS AI Copilot** — Ship an AI copilot in your product in lines of code. No backend rewrite.\n- **Smart Form Filling** — Turn 20-click workflows into one sentence. Perfect for ERP, CRM, and admin systems.\n- **Accessibility** — Make any web app accessible through natural language. Voice commands, screen readers, zero barrier.\n- **Multi-page Agent** — Extend your own web agent's reach across browser tabs [chrome extension](https://alibaba.github.io/page-agent/docs/features/chrome-extension).\n- **MCP** - Allow your agent clients to control your browser.\n\n## 🚀 Quick Start\n\n### One-line integration\n\nFastest way to try PageAgent with our free Demo LLM:\n\n```html\n\n```\n\n> **⚠️ For technical evaluation only.** This demo CDN uses our free [testing LLM API](https://alibaba.github.io/page-agent/docs/features/models#free-testing-api). By using it, you ag
FAQ (5)
TroubleshootingHow to fix 'TypeError: debug is not a function' in a Vite production build with esbuild drop console?
This affects page-agent / @page-agent/llms 1.12.1. The package binds a local logger with var debug = console.debug.bind(...). When esbuild uses drop: ['console'], that expression is rewritten to var debug = void 0, so later debug(...) calls fail in production. Setting globalThis.debug does not work because debug is module-local.
Permanent fix: upgrade page-agent and @page-agent/llms to a release containing the fix for issue #621, where the logger is wrapped in a function instead of storing the bound console.debug directly.
Temporary consumer workaround: disable console dropping for the bundle. In vite.config.ts:
export default defineConfig({
esbuild: {
drop: []
}
})
If the option is injected by VitePress or another preset, force it with a Vite plugin:
function keepConsole() {
return {
name: 'keep-console',
configResolved(config: any) {
if (config.esbuild && typeof config.esbuild === 'object') {
config.esbuild.drop = []
}
}
}
}
export default defineConfig({
plugins: [keepConsole()]
})
Alternatively, patch dist/lib/page-agent-llms.js with a safe wrapper:
var debug = (...args) => {
if (typeof console !== 'undefined' && typeof console.debug === 'function') {
console.debug(chalk.gray('[LLM]'), ...args)
}
}
Verify the built output no longer contains debug=void 0:
grep -n "debug=void 0" dist/assets/*.jsTroubleshootingWhy do Bing search suggestions fail when Page Agent types into the search box?
In Page Agent 1.12.2 on Chrome 152/macOS, inputTextElement() forces the input to blur after entering text such as weather tomorrow, so Bing does not display its suggestions. This is fixed by the PR fix(page-controller): preserve input focus. Upgrade Page Agent to a release containing that PR, or build from source with the page-controller focus fix merged. The input should remain focused after inputTextElement() runs, allowing Bing suggestions to appear. As a temporary workaround, explicitly refocus the search box after automated text entry and trigger an input event.
TroubleshootingHow to fix a browser extension becoming unresponsive and ignoring messages because its MV3 service worker is inactive?
This occurs in v1.7.1 when a Manifest V3 service worker stalls after an extension update; Chrome/Brave can clear registered alarms during updates, preventing the background worker from restarting correctly. As a workaround, open brave://extensions (or chrome://extensions), find the extension, click the Reload button, then reopen the agent chat. If it remains stuck, toggle the extension off/on or restart the browser. The permanent fix upgrades the extension to a release containing the stalled-worker health check and service-worker alarm/update fixes.
TroubleshootingHow to fix a custom MiniMax M3 model not working in v1.10.0?
Upgrade to a release containing the refactor(llms): rewrite model patching and deprecate temperature fix, or build from the latest main branch. The failure was caused by MiniMax M3 changing its parameter schema; the updated model patch sends parameters matching the current schema. After upgrading, remove any manually configured temperature setting because it is deprecated. If you use M3 through OpenRouter, tool calls may still fail because the model sometimes returns invalid int/string formats; that issue must be fixed by the model/provider, so use a supported model or direct MiniMax access as a workaround.
TroubleshootingWhy does the wait tool not reject immediately when AbortSignal is aborted?
This is fixed by the core PR fix(core): make wait honor abort during setup, which closes issue #553. Previously, wait could ignore an abort while reading page update timing before its timer started. Upgrade the core package to a release containing this fix; after upgrading, aborting the signal interrupts wait promptly during setup instead of waiting for the timer to start. Verify with an already-aborted AbortController.signal passed to wait.