Compare commits

...

16 Commits

Author SHA1 Message Date
Simon 536e5076da chore(version): bump version to 1.0.0-beta.3 2026-01-21 17:00:08 +08:00
Simon 81807e17ca feat: add stepIndex to history events 2026-01-21 16:59:22 +08:00
Simon 6944bedf85 chore: correct formatting in markdown 2026-01-21 01:30:27 +08:00
Simon 897b919044 chore(version): bump version to 1.0.0-beta.2 2026-01-21 01:23:42 +08:00
Simon 3a3bb0e58c fix: use spaces for JSON formatting in version sync script 2026-01-21 01:23:07 +08:00
Simon bc7ccf47ff fix: handle version in sync script 2026-01-21 01:15:58 +08:00
Simon c781eba986 feat: fixed version in CDN URL 2026-01-21 01:08:19 +08:00
Simon efe131660a fix: demo not showing panel; docs updated 2026-01-21 00:44:09 +08:00
Simon 22516dec74 feat: unify InvokeError; add rawResponse to historical ErrorEvent 2026-01-20 20:16:34 +08:00
Simon 1f8953c450 feat: add llm rawResponse to history 2026-01-20 19:56:40 +08:00
Simon d6a57f3e20 chore: merge .gitignore from feat/ext 2026-01-20 19:53:52 +08:00
Simon e0027f99c4 Merge pull request #121 from alibaba/dependabot/npm_and_yarn/development-dependencies-0b42ca76aa
chore(deps-dev): bump the development-dependencies group with 6 updates
2026-01-20 14:14:40 +08:00
Simon b234868bc1 Merge pull request #120 from alibaba/dependabot/npm_and_yarn/production-dependencies-f96e18e569
chore(deps): bump the production-dependencies group with 2 updates
2026-01-20 14:13:47 +08:00
dependabot[bot] 10ae34a677 chore(deps-dev): bump the development-dependencies group with 6 updates
Bumps the development-dependencies group with 6 updates:

| Package | From | To |
| --- | --- | --- |
| [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `25.0.7` | `25.0.9` |
| [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/HEAD/packages/plugins/eslint-plugin-react-dom) | `2.5.7` | `2.7.2` |
| [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/HEAD/packages/plugins/eslint-plugin-react-x) | `2.5.7` | `2.7.2` |
| [prettier](https://github.com/prettier/prettier) | `3.7.4` | `3.8.0` |
| [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) | `8.53.0` | `8.53.1` |
| [react-i18next](https://github.com/i18next/react-i18next) | `16.5.2` | `16.5.3` |


Updates `@types/node` from 25.0.7 to 25.0.9
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `eslint-plugin-react-dom` from 2.5.7 to 2.7.2
- [Release notes](https://github.com/Rel1cx/eslint-react/releases)
- [Changelog](https://github.com/Rel1cx/eslint-react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/Rel1cx/eslint-react/commits/v2.7.2/packages/plugins/eslint-plugin-react-dom)

Updates `eslint-plugin-react-x` from 2.5.7 to 2.7.2
- [Release notes](https://github.com/Rel1cx/eslint-react/releases)
- [Changelog](https://github.com/Rel1cx/eslint-react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/Rel1cx/eslint-react/commits/v2.7.2/packages/plugins/eslint-plugin-react-x)

Updates `prettier` from 3.7.4 to 3.8.0
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/3.7.4...3.8.0)

Updates `typescript-eslint` from 8.53.0 to 8.53.1
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.53.1/packages/typescript-eslint)

Updates `react-i18next` from 16.5.2 to 16.5.3
- [Changelog](https://github.com/i18next/react-i18next/blob/master/CHANGELOG.md)
- [Commits](https://github.com/i18next/react-i18next/compare/v16.5.2...v16.5.3)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 25.0.9
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: development-dependencies
- dependency-name: eslint-plugin-react-dom
  dependency-version: 2.7.2
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: development-dependencies
- dependency-name: eslint-plugin-react-x
  dependency-version: 2.7.2
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: development-dependencies
- dependency-name: prettier
  dependency-version: 3.8.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: development-dependencies
- dependency-name: typescript-eslint
  dependency-version: 8.53.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: development-dependencies
- dependency-name: react-i18next
  dependency-version: 16.5.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: development-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-20 06:11:50 +00:00
dependabot[bot] 2fb01b7315 chore(deps): bump the production-dependencies group with 2 updates
Bumps the production-dependencies group with 2 updates: [motion](https://github.com/motiondivision/motion) and [simple-icons](https://github.com/simple-icons/simple-icons).


Updates `motion` from 12.26.1 to 12.27.1
- [Changelog](https://github.com/motiondivision/motion/blob/main/CHANGELOG.md)
- [Commits](https://github.com/motiondivision/motion/compare/v12.26.1...v12.27.1)

Updates `simple-icons` from 16.5.0 to 16.6.0
- [Release notes](https://github.com/simple-icons/simple-icons/releases)
- [Commits](https://github.com/simple-icons/simple-icons/compare/16.5.0...16.6.0)

---
updated-dependencies:
- dependency-name: motion
  dependency-version: 12.27.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-dependencies
- dependency-name: simple-icons
  dependency-version: 16.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-20 06:11:18 +00:00
Simon 5c80f2b002 chore: prettier json indentation 2026-01-20 14:08:42 +08:00
25 changed files with 8715 additions and 8662 deletions
+7 -3
View File
@@ -25,11 +25,15 @@ dist-ssr
*.sw?
.qoder
#
# env files
.env
.env.*
# Copied files for npm publish (generated by prepublishOnly)
packages/page-agent/README.md
packages/page-agent/README-zh.md
packages/page-agent/LICENSE
packages/page-agent/LICENSE
# extension
.output
.wxt
+1
View File
@@ -6,6 +6,7 @@
"HITL",
"innerhtml",
"llms",
"npmmirror",
"onwarn",
"opensource",
"qwen",
+4 -18
View File
@@ -72,28 +72,14 @@ const pageInfo = await this.pageController.getPageInfo()
3. **LLM Processing**: AI returns action plans (page-agent)
4. **Indexed Operations**: PageAgent calls PageController by element index
### IIFE Builds (`packages/page-agent/dist/iife/`)
Two IIFE builds for script tag usage:
| Build | File | Description |
| ----- | -------------------- | -------------------------------- |
| Demo | `page-agent.demo.js` | Auto-init with built-in test API |
| Full | `page-agent.js` | Exposes `PageAgent` class only |
Demo build supports query params (e.g., `?model=gpt-4&lang=en-US`).
Build with `npm run build:iife --workspace=page-agent`.
## Key Files Reference
### Page Agent (`packages/page-agent/`)
| File | Description |
| ------------------------ | -------------------------------------------- |
| `src/PageAgent.ts` | ⭐ Main class with UI, extends PageAgentCore |
| `src/entry-iife.ts` | IIFE entry (exposes PageAgent class) |
| `src/entry-iife-demo.ts` | IIFE demo entry (auto-init with demo API) |
| File | Description |
| ------------------ | -------------------------------------------- |
| `src/PageAgent.ts` | ⭐ Main class with UI, extends PageAgentCore |
| `src/demo.ts` | IIFE demo entry (auto-init with demo API) |
### Core (`packages/core/`)
+2 -2
View File
@@ -69,10 +69,10 @@ members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][https://www.contributor-covenant.org], version 1.4,
This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org), version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
----
---
> Chinese Version
> 《阿里巴巴开源行为准则》
+2 -2
View File
@@ -122,13 +122,13 @@ npm start
- Start and serve a local `iife` script
```bash
npm run dev:iife # Serving IIFE with auto rebuild at http://localhost:5174/page-agent.js
npm run dev:demo # Serving IIFE with auto rebuild at http://localhost:5174/page-agent.demo.js
```
- Add a new bookmark
```javascript
javascript:(function(){var s=document.createElement('script');s.src=`http://localhost:5174/page-agent.js?t=${Math.random()}`;s.onload=()=>console.log(%27PageAgent ready!%27);document.head.appendChild(s);})();
javascript:(function(){var s=document.createElement('script');s.src=`http://localhost:5174/page-agent.demo.js?t=${Math.random()}`;s.onload=()=>console.log(%27PageAgent ready!%27);document.head.appendChild(s);})();
```
- Click the bookmark on any page to load Page-Agent
+5 -5
View File
@@ -37,17 +37,17 @@
```html
<script
src="https://registry.npmmirror.com/@page-agent/cdn/latest/files/dist/page-agent.demo.js"
src="https://registry.npmmirror.com/page-agent/1.0.0-beta.3/files/dist/iife/page-agent.demo.js"
crossorigin="true"
></script>
```
> ⚠️ **仅用于技术评估。** Demo 模型有速率限制和使用限制,生产环境请使用 NPM 方式。
| 镜像 | URL |
| ------ | ----------------------------------------------------------------------------------- |
| Global | https://cdn.jsdelivr.net/npm/page-agent/dist/iife/page-agent.demo.js |
| China | https://registry.npmmirror.com/page-agent/latest/files/dist/iife/page-agent.demo.js |
| 镜像 | URL |
| ------ | ----------------------------------------------------------------------------------------- |
| Global | https://cdn.jsdelivr.net/npm/page-agent@1.0.0-beta.3/dist/iife/page-agent.demo.js |
| China | https://registry.npmmirror.com/page-agent/1.0.0-beta.3/files/dist/iife/page-agent.demo.js |
### NPM 安装
+5 -5
View File
@@ -37,17 +37,17 @@ Fastest way to try PageAgent:
```html
<script
src="https://cdn.jsdelivr.net/npm/page-agent/dist/iife/page-agent.demo.js"
src="https://cdn.jsdelivr.net/npm/page-agent@1.0.0-beta.3/dist/iife/page-agent.demo.js"
crossorigin="true"
></script>
```
> ⚠️ **For technical evaluation only.** Demo model has rate limits and usage restrictions. Use NPM for production.
| Mirrors | URL |
| ------- | ----------------------------------------------------------------------------------- |
| Global | https://cdn.jsdelivr.net/npm/page-agent/dist/iife/page-agent.demo.js |
| China | https://registry.npmmirror.com/page-agent/latest/files/dist/iife/page-agent.demo.js |
| Mirrors | URL |
| ------- | ----------------------------------------------------------------------------------------- |
| Global | https://cdn.jsdelivr.net/npm/page-agent@1.0.0-beta.3/dist/iife/page-agent.demo.js |
| China | https://registry.npmmirror.com/page-agent/1.0.0-beta.3/files/dist/iife/page-agent.demo.js |
### NPM Installation
+8221 -8221
View File
File diff suppressed because it is too large Load Diff
+121 -121
View File
@@ -1,123 +1,123 @@
{
"name": "root",
"private": true,
"version": "1.0.0-beta.1",
"type": "module",
"workspaces": [
"packages/page-controller",
"packages/ui",
"packages/llms",
"packages/core",
"packages/page-agent",
"packages/website"
],
"description": "AI-powered UI agent for web applications",
"author": "Simon<gaomeng1900>",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/alibaba/page-agent.git"
},
"homepage": "https://alibaba.github.io/page-agent/",
"engines": {
"node": ">=20.0.0",
"npm": ">=10.0.0"
},
"scripts": {
"cleanup": "rm -rf packages/*/dist",
"start": "npm run dev --workspace=@page-agent/website",
"build:website": "npm run build:website --workspace=@page-agent/website",
"build:libs": "npm run build --workspaces --if-present",
"build": "npm run build:libs && npm run build:website",
"dev:iife": "npm run dev:iife --workspace=page-agent",
"version": "node scripts/sync-version.js",
"lint": "eslint .",
"prepare": "husky"
},
"devDependencies": {
"@commitlint/cli": "^20.3.1",
"@commitlint/config-conventional": "^20.3.1",
"@eslint/js": "^9.39.2",
"@microsoft/api-extractor": "^7.55.2",
"@trivago/prettier-plugin-sort-imports": "^6.0.2",
"@types/node": "^25.0.7",
"concurrently": "^9.2.1",
"dotenv": "^17.2.3",
"eslint": "^9.39.2",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-react-dom": "^2.5.7",
"eslint-plugin-react-hooks": "^7.0.1",
"eslint-plugin-react-refresh": "^0.4.26",
"eslint-plugin-react-x": "^2.5.7",
"globals": "^17.0.0",
"husky": "^9.1.7",
"lint-staged": "^16.2.4",
"prettier": "^3.7.4",
"typescript": "^5.9.3",
"typescript-eslint": "^8.53.0",
"unplugin-dts": "^1.0.0-beta.6",
"vite": "^7.3.1",
"vite-plugin-css-injected-by-js": "^3.5.2"
},
"overrides": {
"typescript": "^5.9.3"
},
"lint-staged": {
"*.{js,ts,cjs,cts,mjs,mts}": [
"npx prettier --write --ignore-unknown",
"npx eslint --quiet"
],
"*.{jsx,tsx}": [
"npx prettier --write --ignore-unknown",
"npx eslint --quiet"
],
"*.css": [
"npx prettier --write --ignore-unknown"
]
},
"commitlint": {
"extends": [
"@commitlint/config-conventional"
],
"rules": {
"subject-case": [
0,
"never"
]
}
},
"prettier": {
"singleQuote": true,
"semi": false,
"useTabs": true,
"printWidth": 100,
"trailingComma": "es5",
"plugins": [
"@trivago/prettier-plugin-sort-imports"
],
"importOrder": [
"<THIRD_PARTY_MODULES>",
"^(@/).*(?<!css)$",
"^[./].*(?<!css)$",
".css$"
],
"importOrderSeparation": true,
"importOrderSortSpecifiers": true,
"overrides": [
{
"files": "*.md",
"options": {
"useTabs": false,
"tabWidth": 4
}
},
{
"files": "*.json",
"options": {
"useTabs": false,
"tabWidth": 4
}
}
]
}
"name": "root",
"private": true,
"version": "1.0.0-beta.3",
"type": "module",
"workspaces": [
"packages/page-controller",
"packages/ui",
"packages/llms",
"packages/core",
"packages/page-agent",
"packages/website"
],
"description": "AI-powered UI agent for web applications",
"author": "Simon<gaomeng1900>",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/alibaba/page-agent.git"
},
"homepage": "https://alibaba.github.io/page-agent/",
"engines": {
"node": ">=20.0.0",
"npm": ">=10.0.0"
},
"scripts": {
"cleanup": "rm -rf packages/*/dist",
"start": "npm run dev --workspace=@page-agent/website",
"build:website": "npm run build:website --workspace=@page-agent/website",
"build:libs": "npm run build --workspaces --if-present",
"build": "npm run build:libs && npm run build:website",
"dev:demo": "npm run dev:demo --workspace=page-agent",
"version": "node scripts/sync-version.js",
"lint": "eslint .",
"prepare": "husky"
},
"devDependencies": {
"@commitlint/cli": "^20.3.1",
"@commitlint/config-conventional": "^20.3.1",
"@eslint/js": "^9.39.2",
"@microsoft/api-extractor": "^7.55.2",
"@trivago/prettier-plugin-sort-imports": "^6.0.2",
"@types/node": "^25.0.9",
"concurrently": "^9.2.1",
"dotenv": "^17.2.3",
"eslint": "^9.39.2",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-react-dom": "^2.7.2",
"eslint-plugin-react-hooks": "^7.0.1",
"eslint-plugin-react-refresh": "^0.4.26",
"eslint-plugin-react-x": "^2.7.2",
"globals": "^17.0.0",
"husky": "^9.1.7",
"lint-staged": "^16.2.4",
"prettier": "^3.8.0",
"typescript": "^5.9.3",
"typescript-eslint": "^8.53.1",
"unplugin-dts": "^1.0.0-beta.6",
"vite": "^7.3.1",
"vite-plugin-css-injected-by-js": "^3.5.2"
},
"overrides": {
"typescript": "^5.9.3"
},
"lint-staged": {
"*.{js,ts,cjs,cts,mjs,mts}": [
"npx prettier --write --ignore-unknown",
"npx eslint --quiet"
],
"*.{jsx,tsx}": [
"npx prettier --write --ignore-unknown",
"npx eslint --quiet"
],
"*.css": [
"npx prettier --write --ignore-unknown"
]
},
"commitlint": {
"extends": [
"@commitlint/config-conventional"
],
"rules": {
"subject-case": [
0,
"never"
]
}
},
"prettier": {
"singleQuote": true,
"semi": false,
"useTabs": true,
"printWidth": 100,
"trailingComma": "es5",
"plugins": [
"@trivago/prettier-plugin-sort-imports"
],
"importOrder": [
"<THIRD_PARTY_MODULES>",
"^(@/).*(?<!css)$",
"^[./].*(?<!css)$",
".css$"
],
"importOrderSeparation": true,
"importOrderSortSpecifiers": true,
"overrides": [
{
"files": "*.md",
"options": {
"useTabs": false,
"tabWidth": 4
}
},
{
"files": "*.json",
"options": {
"useTabs": false,
"tabWidth": 4
}
}
]
}
}
+49 -49
View File
@@ -1,51 +1,51 @@
{
"name": "@page-agent/core",
"private": false,
"version": "1.0.0-beta.1",
"type": "module",
"main": "./dist/esm/page-agent-core.js",
"module": "./dist/esm/page-agent-core.js",
"types": "./dist/esm/PageAgentCore.d.ts",
"exports": {
".": {
"types": "./dist/esm/PageAgentCore.d.ts",
"import": "./dist/esm/page-agent-core.js",
"default": "./dist/esm/page-agent-core.js"
}
},
"files": [
"dist/"
],
"description": "GUI agent for web applications - add intelligent automation to any webpage with a single script",
"keywords": [
"ai",
"automation",
"ui-agent",
"GUI-agent",
"browser-automation",
"web-agent",
"llm",
"dom-interaction",
"web-automation",
"GUI-simulation"
],
"author": "Simon<gaomeng1900>",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/alibaba/page-agent.git"
},
"homepage": "https://alibaba.github.io/page-agent/",
"scripts": {
"build": "vite build",
"dev:iife": "concurrently \"vite build --config vite.iife.config.js --watch\" \"npx serve dist/iife -p 5174\"",
"prepublishOnly": "node -e \"const fs=require('fs');['README.md','LICENSE'].forEach(f=>fs.copyFileSync('../../'+f,f))\"",
"postpublish": "node -e \"['README.md','LICENSE'].forEach(f=>{try{require('fs').unlinkSync(f)}catch{}})\""
},
"dependencies": {
"chalk": "^5.6.2",
"zod": "^4.3.5",
"@page-agent/llms": "1.0.0-beta.1",
"@page-agent/page-controller": "1.0.0-beta.1"
}
"name": "@page-agent/core",
"private": false,
"version": "1.0.0-beta.3",
"type": "module",
"main": "./dist/esm/page-agent-core.js",
"module": "./dist/esm/page-agent-core.js",
"types": "./dist/esm/PageAgentCore.d.ts",
"exports": {
".": {
"types": "./dist/esm/PageAgentCore.d.ts",
"import": "./dist/esm/page-agent-core.js",
"default": "./dist/esm/page-agent-core.js"
}
},
"files": [
"dist/"
],
"description": "GUI agent for web applications - add intelligent automation to any webpage with a single script",
"keywords": [
"ai",
"automation",
"ui-agent",
"GUI-agent",
"browser-automation",
"web-agent",
"llm",
"dom-interaction",
"web-automation",
"GUI-simulation"
],
"author": "Simon<gaomeng1900>",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/alibaba/page-agent.git"
},
"homepage": "https://alibaba.github.io/page-agent/",
"scripts": {
"build": "vite build",
"dev:iife": "concurrently \"vite build --config vite.iife.config.js --watch\" \"npx serve dist/iife -p 5174\"",
"prepublishOnly": "node -e \"const fs=require('fs');['README.md','LICENSE'].forEach(f=>fs.copyFileSync('../../'+f,f))\"",
"postpublish": "node -e \"['README.md','LICENSE'].forEach(f=>{try{require('fs').unlinkSync(f)}catch{}})\""
},
"dependencies": {
"chalk": "^5.6.2",
"zod": "^4.3.5",
"@page-agent/llms": "1.0.0-beta.3",
"@page-agent/page-controller": "1.0.0-beta.3"
}
}
+5 -2
View File
@@ -2,7 +2,7 @@
* Copyright (C) 2025 Alibaba Group Holding Limited
* All rights reserved.
*/
import { LLM, type Tool } from '@page-agent/llms'
import { InvokeError, LLM, type Tool } from '@page-agent/llms'
import type { PageController } from '@page-agent/page-controller'
import chalk from 'chalk'
import zod from 'zod'
@@ -107,7 +107,7 @@ export class PageAgentCore extends EventTarget {
this.#emitHistoryChange()
})
this.#llm.addEventListener('error', (e) => {
const { error } = (e as CustomEvent).detail
const error = (e as CustomEvent).detail.error as Error | InvokeError
const message = String(error)
this.emitActivity({ type: 'error', message })
// Also push to history for panel rendering
@@ -115,6 +115,7 @@ export class PageAgentCore extends EventTarget {
type: 'error',
errorType: 'error',
message,
rawResponse: (error as InvokeError).rawResponse,
})
this.#emitHistoryChange()
})
@@ -262,9 +263,11 @@ export class PageAgentCore extends EventTarget {
this.history.push({
type: 'step',
stepIndex: step,
reflection,
action,
usage: result.usage,
rawResponse: result.rawResponse,
} as AgentStep)
this.#emitHistoryChange()
+4
View File
@@ -35,6 +35,7 @@ export interface MacroToolResult {
*/
export interface AgentStep {
type: 'step'
stepIndex: number
reflection: Partial<AgentReflection>
action: {
name: string
@@ -48,6 +49,8 @@ export interface AgentStep {
cachedTokens?: number
reasoningTokens?: number
}
/** Raw LLM response for debugging */
rawResponse?: unknown
}
/**
@@ -74,6 +77,7 @@ export interface ErrorEvent {
message: string
attempt?: number
maxAttempts?: number
rawResponse?: unknown
}
/**
+41 -41
View File
@@ -1,43 +1,43 @@
{
"name": "@page-agent/llms",
"version": "1.0.0-beta.1",
"type": "module",
"main": "./dist/lib/page-agent-llms.js",
"module": "./dist/lib/page-agent-llms.js",
"types": "./dist/lib/index.d.ts",
"exports": {
".": {
"types": "./dist/lib/index.d.ts",
"import": "./dist/lib/page-agent-llms.js",
"default": "./dist/lib/page-agent-llms.js"
}
},
"files": [
"dist/"
],
"description": "LLM client with reflection-before-action mental model for page-agent",
"keywords": [
"page-agent",
"llm",
"openai",
"tool-calling",
"agent"
],
"author": "Simon<gaomeng1900>",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/alibaba/page-agent.git",
"directory": "packages/llms"
},
"homepage": "https://alibaba.github.io/page-agent/",
"scripts": {
"build": "vite build",
"prepublishOnly": "node -e \"const fs=require('fs');['LICENSE'].forEach(f=>fs.copyFileSync('../../'+f,f))\"",
"postpublish": "node -e \"['LICENSE'].forEach(f=>{try{require('fs').unlinkSync(f)}catch{}})\""
},
"dependencies": {
"chalk": "^5.6.2",
"zod": "^4.3.5"
}
"name": "@page-agent/llms",
"version": "1.0.0-beta.3",
"type": "module",
"main": "./dist/lib/page-agent-llms.js",
"module": "./dist/lib/page-agent-llms.js",
"types": "./dist/lib/index.d.ts",
"exports": {
".": {
"types": "./dist/lib/index.d.ts",
"import": "./dist/lib/page-agent-llms.js",
"default": "./dist/lib/page-agent-llms.js"
}
},
"files": [
"dist/"
],
"description": "LLM client with reflection-before-action mental model for page-agent",
"keywords": [
"page-agent",
"llm",
"openai",
"tool-calling",
"agent"
],
"author": "Simon<gaomeng1900>",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/alibaba/page-agent.git",
"directory": "packages/llms"
},
"homepage": "https://alibaba.github.io/page-agent/",
"scripts": {
"build": "vite build",
"prepublishOnly": "node -e \"const fs=require('fs');['LICENSE'].forEach(f=>fs.copyFileSync('../../'+f,f))\"",
"postpublish": "node -e \"['LICENSE'].forEach(f=>{try{require('fs').unlinkSync(f)}catch{}})\""
},
"dependencies": {
"chalk": "^5.6.2",
"zod": "^4.3.5"
}
}
+24 -9
View File
@@ -107,14 +107,23 @@ export class OpenAIClient implements LLMClient {
case 'length':
throw new InvokeError(
InvokeErrorType.CONTEXT_LENGTH,
'Response truncated: max tokens reached'
'Response truncated: max tokens reached',
undefined,
data
)
case 'content_filter':
throw new InvokeError(InvokeErrorType.CONTENT_FILTER, 'Content filtered by safety system')
throw new InvokeError(
InvokeErrorType.CONTENT_FILTER,
'Content filtered by safety system',
undefined,
data
)
default:
throw new InvokeError(
InvokeErrorType.UNKNOWN,
`Unexpected finish_reason: ${choice.finish_reason}`
`Unexpected finish_reason: ${choice.finish_reason}`,
undefined,
data
)
}
@@ -128,7 +137,8 @@ export class OpenAIClient implements LLMClient {
throw new InvokeError(
InvokeErrorType.NO_TOOL_CALL,
'No tool call found in response',
normalizedData
undefined,
data
)
}
@@ -137,7 +147,8 @@ export class OpenAIClient implements LLMClient {
throw new InvokeError(
InvokeErrorType.UNKNOWN,
`Tool "${toolCallName}" not found in tools`,
normalizedData
undefined,
data
)
}
@@ -147,7 +158,8 @@ export class OpenAIClient implements LLMClient {
throw new InvokeError(
InvokeErrorType.INVALID_TOOL_ARGS,
'No tool call arguments found',
normalizedData
undefined,
data
)
}
@@ -158,7 +170,8 @@ export class OpenAIClient implements LLMClient {
throw new InvokeError(
InvokeErrorType.INVALID_TOOL_ARGS,
'Failed to parse tool arguments as JSON',
error
error,
data
)
}
@@ -169,7 +182,8 @@ export class OpenAIClient implements LLMClient {
throw new InvokeError(
InvokeErrorType.INVALID_TOOL_ARGS,
'Tool arguments validation failed',
validation.error
validation.error,
data
)
}
const toolInput = validation.data
@@ -182,7 +196,8 @@ export class OpenAIClient implements LLMClient {
throw new InvokeError(
InvokeErrorType.TOOL_EXECUTION_ERROR,
`Tool execution failed: ${(e as Error).message}`,
e
e,
data
)
}
+5 -1
View File
@@ -25,14 +25,18 @@ export class InvokeError extends Error {
type: InvokeErrorType
retryable: boolean
statusCode?: number
/* raw error (provided if this error is caused by another error) */
rawError?: unknown
/* raw response from the API (provided if this error is caused by an API calling) */
rawResponse?: unknown
constructor(type: InvokeErrorType, message: string, rawError?: unknown) {
constructor(type: InvokeErrorType, message: string, rawError?: unknown, rawResponse?: unknown) {
super(message)
this.name = 'InvokeError'
this.type = type
this.retryable = this.isRetryable(type)
this.rawError = rawError
this.rawResponse = rawResponse
}
private isRetryable(type: InvokeErrorType): boolean {
+1 -1
View File
@@ -3,7 +3,7 @@ import { DEFAULT_TEMPERATURE, LLM_MAX_RETRIES } from './constants'
import { InvokeError } from './errors'
import type { InvokeOptions, InvokeResult, LLMClient, LLMConfig, Message, Tool } from './types'
export type { InvokeOptions, InvokeResult, LLMClient, LLMConfig, Message, Tool }
export type { InvokeError, InvokeOptions, InvokeResult, LLMClient, LLMConfig, Message, Tool }
export function parseLLMConfig(config: LLMConfig): Required<LLMConfig> {
// Runtime validation as defensive programming (types already guarantee these)
+52 -52
View File
@@ -1,54 +1,54 @@
{
"name": "page-agent",
"private": false,
"version": "1.0.0-beta.1",
"type": "module",
"main": "./dist/esm/page-agent.js",
"module": "./dist/esm/page-agent.js",
"types": "./dist/esm/PageAgent.d.ts",
"exports": {
".": {
"types": "./dist/esm/PageAgent.d.ts",
"import": "./dist/esm/page-agent.js",
"default": "./dist/esm/page-agent.js"
}
},
"files": [
"dist/"
],
"description": "GUI agent for web applications - add intelligent automation to any webpage with a single script",
"keywords": [
"ai",
"automation",
"ui-agent",
"GUI-agent",
"browser-automation",
"web-agent",
"llm",
"dom-interaction",
"web-automation",
"GUI-simulation"
],
"author": "Simon<gaomeng1900>",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/alibaba/page-agent.git"
},
"homepage": "https://alibaba.github.io/page-agent/",
"scripts": {
"build": "vite build && npm run build:demo",
"build:demo": "vite build --config vite.iife.config.js",
"dev:demo": "concurrently \"vite build --config vite.iife.config.js --watch\" \"npx serve dist/iife -p 5174\"",
"prepublishOnly": "node -e \"const fs=require('fs');['README.md','LICENSE'].forEach(f=>fs.copyFileSync('../../'+f,f))\"",
"postpublish": "node -e \"['README.md','LICENSE'].forEach(f=>{try{require('fs').unlinkSync(f)}catch{}})\""
},
"dependencies": {
"chalk": "^5.6.2",
"zod": "^4.3.5",
"@page-agent/llms": "1.0.0-beta.1",
"@page-agent/page-controller": "1.0.0-beta.1",
"@page-agent/core": "1.0.0-beta.1",
"@page-agent/ui": "1.0.0-beta.1"
}
"name": "page-agent",
"private": false,
"version": "1.0.0-beta.3",
"type": "module",
"main": "./dist/esm/page-agent.js",
"module": "./dist/esm/page-agent.js",
"types": "./dist/esm/PageAgent.d.ts",
"exports": {
".": {
"types": "./dist/esm/PageAgent.d.ts",
"import": "./dist/esm/page-agent.js",
"default": "./dist/esm/page-agent.js"
}
},
"files": [
"dist/"
],
"description": "GUI agent for web applications - add intelligent automation to any webpage with a single script",
"keywords": [
"ai",
"automation",
"ui-agent",
"GUI-agent",
"browser-automation",
"web-agent",
"llm",
"dom-interaction",
"web-automation",
"GUI-simulation"
],
"author": "Simon<gaomeng1900>",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/alibaba/page-agent.git"
},
"homepage": "https://alibaba.github.io/page-agent/",
"scripts": {
"build": "vite build && npm run build:demo",
"build:demo": "vite build --config vite.iife.config.js",
"dev:demo": "concurrently \"vite build --config vite.iife.config.js --watch\" \"npx serve dist/iife -p 5174\"",
"prepublishOnly": "node -e \"const fs=require('fs');['README.md','LICENSE'].forEach(f=>fs.copyFileSync('../../'+f,f))\"",
"postpublish": "node -e \"['README.md','LICENSE'].forEach(f=>{try{require('fs').unlinkSync(f)}catch{}})\""
},
"dependencies": {
"chalk": "^5.6.2",
"zod": "^4.3.5",
"@page-agent/llms": "1.0.0-beta.3",
"@page-agent/page-controller": "1.0.0-beta.3",
"@page-agent/core": "1.0.0-beta.3",
"@page-agent/ui": "1.0.0-beta.3"
}
}
+1
View File
@@ -41,6 +41,7 @@ setTimeout(() => {
// Create agent
window.pageAgent = new PageAgent(config)
window.pageAgent.panel.show()
console.log('🚀 page-agent.js initialized with config:', window.pageAgent.config)
})
+39 -39
View File
@@ -1,41 +1,41 @@
{
"name": "@page-agent/page-controller",
"version": "1.0.0-beta.1",
"type": "module",
"main": "./dist/lib/page-controller.js",
"module": "./dist/lib/page-controller.js",
"types": "./dist/lib/PageController.d.ts",
"exports": {
".": {
"types": "./dist/lib/PageController.d.ts",
"import": "./dist/lib/page-controller.js",
"default": "./dist/lib/page-controller.js"
}
},
"files": [
"dist/"
],
"description": "Page controller for page-agent - DOM operations and element interactions",
"keywords": [
"page-agent",
"dom",
"browser-automation",
"web-automation"
],
"author": "Simon<gaomeng1900>",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/alibaba/page-agent.git",
"directory": "packages/page-controller"
},
"homepage": "https://alibaba.github.io/page-agent/",
"scripts": {
"build": "vite build",
"prepublishOnly": "node -e \"const fs=require('fs');['LICENSE'].forEach(f=>fs.copyFileSync('../../'+f,f))\"",
"postpublish": "node -e \"['LICENSE'].forEach(f=>{try{require('fs').unlinkSync(f)}catch{}})\""
},
"dependencies": {
"ai-motion": "^0.4.8"
}
"name": "@page-agent/page-controller",
"version": "1.0.0-beta.3",
"type": "module",
"main": "./dist/lib/page-controller.js",
"module": "./dist/lib/page-controller.js",
"types": "./dist/lib/PageController.d.ts",
"exports": {
".": {
"types": "./dist/lib/PageController.d.ts",
"import": "./dist/lib/page-controller.js",
"default": "./dist/lib/page-controller.js"
}
},
"files": [
"dist/"
],
"description": "Page controller for page-agent - DOM operations and element interactions",
"keywords": [
"page-agent",
"dom",
"browser-automation",
"web-automation"
],
"author": "Simon<gaomeng1900>",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/alibaba/page-agent.git",
"directory": "packages/page-controller"
},
"homepage": "https://alibaba.github.io/page-agent/",
"scripts": {
"build": "vite build",
"prepublishOnly": "node -e \"const fs=require('fs');['LICENSE'].forEach(f=>fs.copyFileSync('../../'+f,f))\"",
"postpublish": "node -e \"['LICENSE'].forEach(f=>{try{require('fs').unlinkSync(f)}catch{}})\""
},
"dependencies": {
"ai-motion": "^0.4.8"
}
}
+36 -36
View File
@@ -1,38 +1,38 @@
{
"name": "@page-agent/ui",
"version": "1.0.0-beta.1",
"type": "module",
"main": "./dist/lib/page-agent-ui.js",
"module": "./dist/lib/page-agent-ui.js",
"types": "./dist/lib/index.d.ts",
"exports": {
".": {
"types": "./dist/lib/index.d.ts",
"import": "./dist/lib/page-agent-ui.js",
"default": "./dist/lib/page-agent-ui.js"
}
},
"files": [
"dist/"
],
"description": "UI components for page-agent - Panel and i18n",
"keywords": [
"page-agent",
"ui",
"panel",
"i18n"
],
"author": "Simon<gaomeng1900>",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/alibaba/page-agent.git",
"directory": "packages/ui"
},
"homepage": "https://alibaba.github.io/page-agent/",
"scripts": {
"build": "vite build",
"prepublishOnly": "node -e \"const fs=require('fs');['LICENSE'].forEach(f=>fs.copyFileSync('../../'+f,f))\"",
"postpublish": "node -e \"['LICENSE'].forEach(f=>{try{require('fs').unlinkSync(f)}catch{}})\""
}
"name": "@page-agent/ui",
"version": "1.0.0-beta.3",
"type": "module",
"main": "./dist/lib/page-agent-ui.js",
"module": "./dist/lib/page-agent-ui.js",
"types": "./dist/lib/index.d.ts",
"exports": {
".": {
"types": "./dist/lib/index.d.ts",
"import": "./dist/lib/page-agent-ui.js",
"default": "./dist/lib/page-agent-ui.js"
}
},
"files": [
"dist/"
],
"description": "UI components for page-agent - Panel and i18n",
"keywords": [
"page-agent",
"ui",
"panel",
"i18n"
],
"author": "Simon<gaomeng1900>",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/alibaba/page-agent.git",
"directory": "packages/ui"
},
"homepage": "https://alibaba.github.io/page-agent/",
"scripts": {
"build": "vite build",
"prepublishOnly": "node -e \"const fs=require('fs');['LICENSE'].forEach(f=>fs.copyFileSync('../../'+f,f))\"",
"postpublish": "node -e \"['LICENSE'].forEach(f=>{try{require('fs').unlinkSync(f)}catch{}})\""
}
}
+11 -9
View File
@@ -563,9 +563,8 @@ export class Panel {
// 2. Render each history event
const history = this.#agent.history
for (let i = 0; i < history.length; i++) {
const event = history[i]
items.push(...this.#createHistoryCards(event, i + 1))
for (const event of history) {
items.push(...this.#createHistoryCards(event))
}
this.#historySection.innerHTML = items.join('')
@@ -577,14 +576,17 @@ export class Panel {
}
/** Create cards for a history event */
#createHistoryCards(event: PanelAgentAdapter['history'][number], stepNumber: number): string[] {
#createHistoryCards(event: PanelAgentAdapter['history'][number]): string[] {
const cards: string[] = []
const time = formatTime(this.#config.language ?? 'en-US')
const meta = this.#i18n.t('ui.panel.step', {
number: stepNumber.toString(),
time,
duration: '',
})
const meta =
event.type === 'step' && event.stepIndex !== undefined
? this.#i18n.t('ui.panel.step', {
number: (event.stepIndex + 1).toString(),
time,
duration: '',
})
: time
if (event.type === 'step') {
// Reflection card
+1
View File
@@ -34,6 +34,7 @@ export interface PanelAgentAdapter extends EventTarget {
/** History of agent events */
readonly history: readonly {
type: 'step' | 'observation' | 'user_takeover' | 'error'
stepIndex?: number
/** For 'step' type */
reflection?: {
evaluation_previous_goal?: string
+40 -40
View File
@@ -1,42 +1,42 @@
{
"name": "@page-agent/website",
"private": true,
"version": "1.0.0-beta.1",
"type": "module",
"scripts": {
"dev": "vite --host 0.0.0.0",
"build:website": "vite build",
"preview": "vite preview",
"typecheck": "tsc --noEmit"
},
"devDependencies": {
"@tailwindcss/vite": "^4.1.18",
"@types/react": "^19.2.8",
"@types/react-dom": "^19.2.1",
"@vitejs/plugin-react-swc": "^4.1.0",
"i18next": "^25.7.4",
"i18next-browser-languagedetector": "^8.2.0",
"react": "^19.2.3",
"react-dom": "^19.2.3",
"react-i18next": "^16.5.2",
"tailwindcss": "^4.1.14",
"tw-animate-css": "^1.4.0",
"wouter": "^3.9.0"
},
"dependencies": {
"@radix-ui/react-icons": "^1.3.2",
"@radix-ui/react-separator": "^1.1.8",
"@radix-ui/react-slot": "^1.2.4",
"@radix-ui/react-switch": "^1.2.6",
"@radix-ui/react-tooltip": "^1.2.8",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"lucide-react": "^0.562.0",
"motion": "^12.26.1",
"next-themes": "^0.4.6",
"rough-notation": "^0.5.1",
"simple-icons": "^16.5.0",
"sonner": "^2.0.7",
"tailwind-merge": "^3.4.0"
}
"name": "@page-agent/website",
"private": true,
"version": "1.0.0-beta.3",
"type": "module",
"scripts": {
"dev": "vite --host 0.0.0.0",
"build:website": "vite build",
"preview": "vite preview",
"typecheck": "tsc --noEmit"
},
"devDependencies": {
"@tailwindcss/vite": "^4.1.18",
"@types/react": "^19.2.8",
"@types/react-dom": "^19.2.1",
"@vitejs/plugin-react-swc": "^4.1.0",
"i18next": "^25.7.4",
"i18next-browser-languagedetector": "^8.2.0",
"react": "^19.2.3",
"react-dom": "^19.2.3",
"react-i18next": "^16.5.3",
"tailwindcss": "^4.1.14",
"tw-animate-css": "^1.4.0",
"wouter": "^3.9.0"
},
"dependencies": {
"@radix-ui/react-icons": "^1.3.2",
"@radix-ui/react-separator": "^1.1.8",
"@radix-ui/react-slot": "^1.2.4",
"@radix-ui/react-switch": "^1.2.6",
"@radix-ui/react-tooltip": "^1.2.8",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"lucide-react": "^0.562.0",
"motion": "^12.27.1",
"next-themes": "^0.4.6",
"rough-notation": "^0.5.1",
"simple-icons": "^16.6.0",
"sonner": "^2.0.7",
"tailwind-merge": "^3.4.0"
}
}
+3 -2
View File
@@ -1,7 +1,8 @@
// Demo build (auto-init with demo LLM, for quick testing)
export const CDN_DEMO_URL = 'https://cdn.jsdelivr.net/npm/page-agent/dist/iife/page-agent.demo.js'
export const CDN_DEMO_URL =
'https://cdn.jsdelivr.net/npm/page-agent@1.0.0-beta.3/dist/iife/page-agent.demo.js'
export const CDN_DEMO_CN_URL =
'https://registry.npmmirror.com/page-agent/latest/files/dist/iife/page-agent.demo.js'
'https://registry.npmmirror.com/page-agent/1.0.0-beta.3/files/dist/iife/page-agent.demo.js'
// Demo LLM for website testing
export const DEMO_MODEL = 'PAGE-AGENT-FREE-TESTING-RANDOM'
+35 -4
View File
@@ -9,6 +9,7 @@
import chalk from 'chalk'
import { existsSync, readFileSync, readdirSync, writeFileSync } from 'fs'
import { dirname, join } from 'path'
import { exit } from 'process'
import { fileURLToPath } from 'url'
const __dirname = dirname(fileURLToPath(import.meta.url))
@@ -17,17 +18,23 @@ const rootDir = join(__dirname, '..')
// Parse arguments
const versionArg = process.argv[2]
if (!versionArg) {
console.log(chalk.yellow('⚠️ No version specified.\n'))
exit(1)
}
// Read root package.json
const rootPkgPath = join(rootDir, 'package.json')
const rootPkg = JSON.parse(readFileSync(rootPkgPath, 'utf-8'))
const newVersion = versionArg || rootPkg.version
const oldVersion = rootPkg.version
const newVersion = versionArg
console.log(chalk.cyan.bold('\n📦 Syncing version\n'))
// Update root package.json if new version specified
if (versionArg) {
rootPkg.version = newVersion
writeFileSync(rootPkgPath, JSON.stringify(rootPkg, null, '\t') + '\n')
writeFileSync(rootPkgPath, JSON.stringify(rootPkg, null, ' ') + '\n')
console.log(chalk.green('✓') + ` ${chalk.bold('root')}${chalk.yellow(newVersion)}`)
} else {
console.log(chalk.dim(' root:') + ` ${chalk.yellow(newVersion)} ${chalk.dim('(source)')}`)
@@ -69,7 +76,6 @@ for (const pkg of packages) {
if (!existsSync(pkgPath)) continue
const pkgJson = JSON.parse(readFileSync(pkgPath, 'utf-8'))
const oldVersion = pkgJson.version
let pkgChanged = false
// Update package version
@@ -88,7 +94,7 @@ for (const pkg of packages) {
continue
}
writeFileSync(pkgPath, JSON.stringify(pkgJson, null, '\t') + '\n')
writeFileSync(pkgPath, JSON.stringify(pkgJson, null, ' ') + '\n')
console.log(
chalk.green('✓') +
` ${chalk.bold(pkgJson.name)}: ${chalk.dim(oldVersion)}${chalk.yellow(newVersion)}`
@@ -96,6 +102,31 @@ for (const pkg of packages) {
hasChanges = true
}
// Update CDN URLs in documentation and source files
const CDN_DEMO_URL_OLD = `https://cdn.jsdelivr.net/npm/page-agent@${oldVersion}/dist/iife/page-agent.demo.js`
const CDN_DEMO_URL_NEW = `https://cdn.jsdelivr.net/npm/page-agent@${newVersion}/dist/iife/page-agent.demo.js`
const CDN_DEMO_CN_URL_OLD = `https://registry.npmmirror.com/page-agent/${oldVersion}/files/dist/iife/page-agent.demo.js`
const CDN_DEMO_CN_URL_NEW = `https://registry.npmmirror.com/page-agent/${newVersion}/files/dist/iife/page-agent.demo.js`
const filesToUpdateCdn = ['README.md', 'README-zh.md', 'packages/website/src/constants.ts']
for (const relPath of filesToUpdateCdn) {
const filePath = join(rootDir, relPath)
if (!existsSync(filePath)) continue
let content = readFileSync(filePath, 'utf-8')
const original = content
content = content.replaceAll(CDN_DEMO_URL_OLD, CDN_DEMO_URL_NEW)
content = content.replaceAll(CDN_DEMO_CN_URL_OLD, CDN_DEMO_CN_URL_NEW)
if (content !== original) {
writeFileSync(filePath, content)
console.log(chalk.green('✓') + ` ${chalk.bold(relPath)}: CDN URLs updated`)
hasChanges = true
}
}
console.log(chalk.green.bold(`\n✓ Version synced: ${newVersion}\n`))
// Show git commands hint