Compare commits

...

23 Commits

Author SHA1 Message Date
Simon af36f43104 chore(version): bump version to 0.2.5 2026-01-17 17:47:50 +08:00
Simon b5f260207c chore: wording 2026-01-17 17:47:04 +08:00
Simon 9075204c29 Merge pull request #118 from alibaba/feat/make-panel-optional
feat: make all ui optional
2026-01-17 17:43:40 +08:00
Simon ce3a80bc53 docs: typo 2026-01-17 17:30:16 +08:00
Simon 64c36f67bb docs: update config; instructions for programmatic usage 2026-01-17 17:28:28 +08:00
Simon 78d4919289 feat: make panel optional 2026-01-17 17:24:17 +08:00
Simon 1af2607cca feat: remove ask_user tool from sys_prompt 2026-01-17 17:18:31 +08:00
Simon ab713f3d3a chore(version): bump version to 0.2.4 2026-01-17 16:22:45 +08:00
Simon 05cc4f36c8 chore: add .prettierignore for system_prompt.md 2026-01-17 16:22:28 +08:00
Simon 54e9bdad7d chore: prettier json and markdowns 2026-01-17 16:15:36 +08:00
Simon 0fc88c0080 chore(version): bump version to 0.2.3 2026-01-17 16:03:11 +08:00
Simon 02f97ef2fa chore: banner 2026-01-17 15:57:22 +08:00
Simon 0853ffbbc6 chore: banner 2026-01-17 15:48:30 +08:00
Simon 60ac6da09f chore: new demo video 2026-01-17 15:17:14 +08:00
Simon 11a9fb1181 chore: new demo video 2026-01-17 15:15:48 +08:00
Simon 3762d0f1e0 chore: refine docs 2026-01-17 14:59:09 +08:00
Simon ebbe92f7ca fix(website): update links to use relative paths 2026-01-17 02:13:19 +08:00
Simon 9f239b2de3 chore: comment out unused config 2026-01-17 02:05:30 +08:00
Simon 2410c27b55 chore(website): update config docs 2026-01-17 02:05:09 +08:00
Simon 6d6c82648c chore: cleanup 2026-01-17 01:46:35 +08:00
Simon f41119c1ad fix(website): fix router 2026-01-17 01:36:15 +08:00
Simon 9e6e1b996c chore(website): simplify chunks 2026-01-17 01:27:19 +08:00
Simon 1ab23e181f chore: clean up 2026-01-17 01:23:23 +08:00
46 changed files with 639 additions and 590 deletions
+1 -1
View File
@@ -58,4 +58,4 @@ body:
- label: I have read the Code of Conduct. / 我已阅读行为准则。 - label: I have read the Code of Conduct. / 我已阅读行为准则。
required: true required: true
validations: validations:
required: true required: true
+1 -1
View File
@@ -44,4 +44,4 @@ body:
- label: I have read the CODE_OF_CONDUCT.md and CONTRIBUTING.md. / 我已阅读行为准则。 - label: I have read the CODE_OF_CONDUCT.md and CONTRIBUTING.md. / 我已阅读行为准则。
required: true required: true
validations: validations:
required: true required: true
+3 -3
View File
@@ -6,7 +6,7 @@ on:
- 'v*' - 'v*'
permissions: permissions:
id-token: write # Required for OIDC id-token: write # Required for OIDC
contents: read contents: read
jobs: jobs:
@@ -24,7 +24,7 @@ jobs:
# Ensure npm 11.5.1 or later is installed # Ensure npm 11.5.1 or later is installed
- name: Update npm - name: Update npm
run: npm install -g npm@latest run: npm install -g npm@latest
- name: Install dependencies - name: Install dependencies
run: npm ci run: npm ci
@@ -32,4 +32,4 @@ jobs:
run: npm run build:libs run: npm run build:libs
- name: Publish all public packages - name: Publish all public packages
run: npm publish --workspaces --access public run: npm publish --workspaces --access public
+1 -1
View File
@@ -1,3 +1,3 @@
{ {
"recommendations": ["dbaeumer.vscode-eslint", "prettier.prettier-vscode"] "recommendations": ["dbaeumer.vscode-eslint", "prettier.prettier-vscode"]
} }
+27 -27
View File
@@ -1,29 +1,29 @@
{ {
"editor.fontLigatures": true, "editor.fontLigatures": true,
"cSpell.words": [ "cSpell.words": [
"deepseek", "deepseek",
"HITL", "HITL",
"innerhtml", "innerhtml",
"llms", "llms",
"onwarn", "onwarn",
"opensource", "opensource",
"qwen", "qwen",
"retryable", "retryable",
"shadcn", "shadcn",
"wouter" "wouter"
], ],
"markdownlint.config": { "markdownlint.config": {
// "comment": "Relaxed rules", // "comment": "Relaxed rules",
"default": true, "default": true,
"whitespace": false, "whitespace": false,
"line_length": false, "line_length": false,
"ul-indent": false, "ul-indent": false,
"no-inline-html": false, "no-inline-html": false,
"no-bare-urls": false, "no-bare-urls": false,
"fenced-code-language": false, "fenced-code-language": false,
"first-line-h1": false, "first-line-h1": false,
"block-spacing": false, "block-spacing": false,
"blanks-around-lists": false, "blanks-around-lists": false,
"ol-prefix": false "ol-prefix": false
} }
} }
+39 -39
View File
@@ -7,16 +7,16 @@ Thank you for your interest in contributing to Page-Agent! We welcome contributi
### Development Setup ### Development Setup
1. **Prerequisites** 1. **Prerequisites**
- `node.js >= 20` with `npm >= 10` - `node.js >= 20` with `npm >= 10`
- An editor that supports `ts/eslint/prettier` - An editor that supports `ts/eslint/prettier`
- Make sure `eslint`, `prettier` and `commitlint` work well - Make sure `eslint`, `prettier` and `commitlint` work well
2. **Setup** 2. **Setup**
```bash ```bash
npm ci npm ci
npm start # Start demo and documentation site npm start # Start demo and documentation site
``` ```
### Project Structure ### Project Structure
@@ -44,39 +44,39 @@ We use a simplified monorepo solution with `native npm-workspace + ts reference
1. **Fork and Clone** 1. **Fork and Clone**
```bash ```bash
git clone https://github.com/your-username/page-agent.git git clone https://github.com/your-username/page-agent.git
cd page-agent cd page-agent
``` ```
2. **Create Feature Branch** 2. **Create Feature Branch**
```bash ```bash
git checkout -b feat/your-feature-name git checkout -b feat/your-feature-name
``` ```
3. **Make Changes** 3. **Make Changes**
- Follow existing code style and patterns - Follow existing code style and patterns
- Add tests for new functionality - Add tests for new functionality
- Update documentation as needed - Update documentation as needed
4. **Test Your Changes** 4. **Test Your Changes**
- Test in our demo website - Test in our demo website
- Test it on other websites if applicable - Test it on other websites if applicable
- `@TODO: test suite` - `@TODO: test suite`
5. **Commit and Push** 5. **Commit and Push**
```bash ```bash
git add . git add .
git commit -m "feat: add awesome feature" git commit -m "feat: add awesome feature"
git push origin feat/your-feature-name git push origin feat/your-feature-name
``` ```
6. **Create Pull Request** 6. **Create Pull Request**
- Provide clear description of changes - Provide clear description of changes
- Link related issues - Link related issues
- Include screenshots for UI changes - Include screenshots for UI changes
## 📝 Code Style ## 📝 Code Style
@@ -101,11 +101,11 @@ We use a simplified monorepo solution with `native npm-workspace + ts reference
- Create a `.env` file in the repo root with your LLM API config - Create a `.env` file in the repo root with your LLM API config
```env ```env
LLM_MODEL_NAME=gpt-5.2 LLM_MODEL_NAME=gpt-5.2
LLM_API_KEY=your-api-key LLM_API_KEY=your-api-key
LLM_BASE_URL=https://api.your-llm-provider.com/v1 LLM_BASE_URL=https://api.your-llm-provider.com/v1
``` ```
- Restart the dev server to load new env vars - Restart the dev server to load new env vars
- If not provided, the demo will the free testing proxy by default - If not provided, the demo will the free testing proxy by default
@@ -120,15 +120,15 @@ npm start
- Start and serve a local `iife` script - Start and serve a local `iife` script
```bash ```bash
npm run dev:iife # Serving IIFE with auto rebuild at http://localhost:5174/page-agent.js npm run dev:iife # Serving IIFE with auto rebuild at http://localhost:5174/page-agent.js
``` ```
- Add a new bookmark - Add a new bookmark
```javascript ```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.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 - Click the bookmark on any page to load Page-Agent
+32 -50
View File
@@ -1,8 +1,11 @@
# PageAgent 🤖🪄 # PageAgent 🤖🪄
![banner](https://img.alicdn.com/imgextra/i1/O1CN01RY0Wvh26ATVeDIX7v_!!6000000007621-0-tps-1672-512.jpg) <picture>
<source media="(prefers-color-scheme: dark)" srcset="https://img.alicdn.com/imgextra/i4/O1CN01qKig1P1FnhpFKNdi6_!!6000000000532-2-tps-1280-256.png">
<img alt="Page Agent Banner" src="https://img.alicdn.com/imgextra/i1/O1CN01NCMKXj1Gn4tkFTsxf_!!6000000000666-2-tps-1280-256.png">
</picture>
[![npm version](https://badge.fury.io/js/page-agent.svg)](https://badge.fury.io/js/page-agent) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-%230074c1.svg)](http://www.typescriptlang.org/) [![Downloads](https://img.shields.io/npm/dt/page-agent.svg)](https://www.npmjs.com/package/page-agent) [![Bundle Size](https://img.shields.io/bundlephobia/minzip/page-agent)](https://bundlephobia.com/package/page-agent) [![GitHub stars](https://img.shields.io/github/stars/alibaba/page-agent.svg)](https://github.com/alibaba/page-agent) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-%230074c1.svg)](http://www.typescriptlang.org/) [![Downloads](https://img.shields.io/npm/dt/page-agent.svg)](https://www.npmjs.com/package/page-agent) [![Bundle Size](https://img.shields.io/bundlephobia/minzip/page-agent)](https://bundlephobia.com/package/page-agent) [![GitHub stars](https://img.shields.io/github/stars/alibaba/page-agent.svg)](https://github.com/alibaba/page-agent)
纯 JS 实现的 GUI agent。使用自然语言操作你的 Web 应用。无须后端、客户端、浏览器插件。 纯 JS 实现的 GUI agent。使用自然语言操作你的 Web 应用。无须后端、客户端、浏览器插件。
@@ -10,7 +13,7 @@
👉 <a href="https://alibaba.github.io/page-agent/" target="_blank"><b>🚀 Demo</b></a> | <a href="https://alibaba.github.io/page-agent/#/docs/introduction/overview" target="_blank"><b>📖 Documentation</b></a> 👉 <a href="https://alibaba.github.io/page-agent/" target="_blank"><b>🚀 Demo</b></a> | <a href="https://alibaba.github.io/page-agent/#/docs/introduction/overview" target="_blank"><b>📖 Documentation</b></a>
<video id="demo-video" src="https://github.com/user-attachments/assets/141bbb01-8022-4d1f-919d-9efc9a1dc1cf" width="640" crossorigin muted autoplay loop></video> <video id="demo-video" src="https://github.com/user-attachments/assets/34d8444d-cbfb-44a3-a24e-fd5c167bb0bf" controls crossorigin muted></video>
--- ---
@@ -28,22 +31,25 @@
## 🚀 快速开始 ## 🚀 快速开始
### 快速体验 (Demo CDN) ### 快速体验 (With Testing LLM)
最快的体验方式: 最快的体验方式:
```html ```html
<script src="https://registry.npmmirror.com/@page-agent/cdn/latest/files/dist/page-agent.demo.js" crossorigin="true"></script> <script
src="https://registry.npmmirror.com/@page-agent/cdn/latest/files/dist/page-agent.demo.js"
crossorigin="true"
></script>
``` ```
> ⚠️ **仅用于技术评估。** Demo 模型有速率限制和使用限制,生产环境请使用 NPM 方式。 > ⚠️ **仅用于技术评估。** Demo 模型有速率限制和使用限制,生产环境请使用 NPM 方式。
| 位置 | URL | | Mirrors | URL |
| ------ | --------------------------------------------------------------------------------------- | | ------- | ----------------------------------------------------------------------------------- |
| 全球 | https://cdn.jsdelivr.net/npm/@page-agent/cdn/dist/page-agent.demo.js | | Global | https://cdn.jsdelivr.net/npm/@page-agent/cdn/dist/page-agent.demo.js |
| 中国 | https://registry.npmmirror.com/@page-agent/cdn/latest/files/dist/page-agent.demo.js | | China | https://registry.npmmirror.com/@page-agent/cdn/latest/files/dist/page-agent.demo.js |
### NPM 安装(推荐) ### NPM 安装
```bash ```bash
npm install page-agent npm install page-agent
@@ -53,35 +59,16 @@ npm install page-agent
import { PageAgent } from 'page-agent' import { PageAgent } from 'page-agent'
const agent = new PageAgent({ const agent = new PageAgent({
model: 'deepseek-chat', model: 'deepseek-chat',
baseURL: 'https://api.deepseek.com', baseURL: 'https://api.deepseek.com',
apiKey: 'YOUR_API_KEY', apiKey: 'YOUR_API_KEY',
language: 'zh-CN', language: 'zh-CN',
}) })
await agent.execute('点击登录按钮') await agent.execute('点击登录按钮')
``` ```
### CDN 引入 适用于无法使用 NPM 的环境,我们也提供了 IIFE 构建的 CDN 方式。[@see CDN Usage](https://alibaba.github.io/page-agent/#/docs/integration/cdn-setup)
适用于无法使用 NPM 的环境,用法与 NPM 一致:
```html
<script src="https://registry.npmmirror.com/@page-agent/cdn/latest/files/dist/page-agent.js" crossorigin="true"></script>
<script>
const agent = new PageAgent({
model: 'deepseek-chat',
baseURL: 'https://api.deepseek.com',
apiKey: 'YOUR_API_KEY',
})
await agent.execute('点击登录按钮')
</script>
```
| 位置 | URL |
| ------ | ----------------------------------------------------------------------------------- |
| 全球 | https://cdn.jsdelivr.net/npm/@page-agent/cdn/dist/page-agent.js |
| 中国 | https://registry.npmmirror.com/@page-agent/cdn/latest/files/dist/page-agent.js |
## 🏗️ 架构设计 ## 🏗️ 架构设计
@@ -101,28 +88,19 @@ packages/
欢迎社区贡献!以下是参与方式: 欢迎社区贡献!以下是参与方式:
### 开发环境 1. Fork 并 clone。`git clone https://github.com/alibaba/page-agent.git && cd page-agent`
2. 安装依赖: `npm install`
3. 启动开发: `npm start`
1. Fork 项目仓库 更多详情请参阅 [CONTRIBUTING.md](CONTRIBUTING.md)。
2. Clone or fork: `git clone https://github.com/alibaba/page-agent.git && cd page-agent`
3. 安装依赖: `npm install`
4. 启动开发: `npm start`
### 贡献指南 请在贡献前阅读我们的[行为准则](CODE_OF_CONDUCT.md)。
请在贡献前阅读我们的[行为准则](CODE_OF_CONDUCT.md)和[贡献指南](CONTRIBUTING.md)。
## 👏 致谢 ## 👏 致谢
本项目基于以下优秀项目构建 本项目基于 **[`browser-use`](https://github.com/browser-use/browser-use)** 的优秀工作构建
- **[browser-use](https://github.com/browser-use/browser-use)** `PageAgent` 专为**客户端网页增强**设计,不是服务端自动化工具。
PageAgent 专为**客户端网页增强**设计,不是服务端自动化工具。
## 📄 许可证
MIT 许可证 - 详见 [LICENSE](LICENSE) 文件。
``` ```
DOM processing components and prompt are derived from browser-use: DOM processing components and prompt are derived from browser-use:
@@ -141,6 +119,10 @@ Third-party dependencies and their licenses can be found in the package.json
file and in the node_modules directory after installation. file and in the node_modules directory after installation.
``` ```
## 📄 许可证
[MIT License](LICENSE)
--- ---
**⭐ 如果觉得 PageAgent 有用或有趣,请给项目点个星!** **⭐ 如果觉得 PageAgent 有用或有趣,请给项目点个星!**
+32 -50
View File
@@ -1,8 +1,11 @@
# PageAgent 🤖🪄 # PageAgent 🤖🪄
![banner](https://img.alicdn.com/imgextra/i3/O1CN01MyVCS21EoKkIHUT1s_!!6000000000398-49-tps-1280-353.webp) <picture>
<source media="(prefers-color-scheme: dark)" srcset="https://img.alicdn.com/imgextra/i4/O1CN01qKig1P1FnhpFKNdi6_!!6000000000532-2-tps-1280-256.png">
<img alt="Page Agent Banner" src="https://img.alicdn.com/imgextra/i1/O1CN01NCMKXj1Gn4tkFTsxf_!!6000000000666-2-tps-1280-256.png">
</picture>
[![npm version](https://badge.fury.io/js/page-agent.svg)](https://badge.fury.io/js/page-agent) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-%230074c1.svg)](http://www.typescriptlang.org/) [![Downloads](https://img.shields.io/npm/dt/page-agent.svg)](https://www.npmjs.com/package/page-agent) [![Bundle Size](https://img.shields.io/bundlephobia/minzip/page-agent)](https://bundlephobia.com/package/page-agent) [![GitHub stars](https://img.shields.io/github/stars/alibaba/page-agent.svg)](https://github.com/alibaba/page-agent) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-%230074c1.svg)](http://www.typescriptlang.org/) [![Downloads](https://img.shields.io/npm/dt/page-agent.svg)](https://www.npmjs.com/package/page-agent) [![Bundle Size](https://img.shields.io/bundlephobia/minzip/page-agent)](https://bundlephobia.com/package/page-agent) [![GitHub stars](https://img.shields.io/github/stars/alibaba/page-agent.svg)](https://github.com/alibaba/page-agent)
The GUI Agent Living in Your Webpage. Control web interfaces with natural language. The GUI Agent Living in Your Webpage. Control web interfaces with natural language.
@@ -10,7 +13,7 @@ The GUI Agent Living in Your Webpage. Control web interfaces with natural langua
👉 <a href="https://alibaba.github.io/page-agent/" target="_blank"><b>🚀 Demo</b></a> | <a href="https://alibaba.github.io/page-agent/#/docs/introduction/overview" target="_blank"><b>📖 Documentation</b></a> 👉 <a href="https://alibaba.github.io/page-agent/" target="_blank"><b>🚀 Demo</b></a> | <a href="https://alibaba.github.io/page-agent/#/docs/introduction/overview" target="_blank"><b>📖 Documentation</b></a>
<video id="demo-video" src="https://github.com/user-attachments/assets/de8d1964-8bde-494f-a52f-2975469557a5" width="640" crossorigin muted autoplay loop></video> <video id="demo-video" src="https://github.com/user-attachments/assets/34d8444d-cbfb-44a3-a24e-fd5c167bb0bf" controls crossorigin muted></video>
--- ---
@@ -28,22 +31,25 @@ The GUI Agent Living in Your Webpage. Control web interfaces with natural langua
## 🚀 Quick Start ## 🚀 Quick Start
### Quick Try (Demo CDN) ### Quick Try (With Testing LLM)
Fastest way to try PageAgent: Fastest way to try PageAgent:
```html ```html
<script src="https://cdn.jsdelivr.net/npm/@page-agent/cdn/dist/page-agent.demo.js" crossorigin="true"></script> <script
src="https://cdn.jsdelivr.net/npm/@page-agent/cdn/dist/page-agent.demo.js"
crossorigin="true"
></script>
``` ```
> ⚠️ **For technical evaluation only.** Demo model has rate limits and usage restrictions. Use NPM for production. > ⚠️ **For technical evaluation only.** Demo model has rate limits and usage restrictions. Use NPM for production.
| Location | URL | | Mirrors | URL |
| -------- | --------------------------------------------------------------------------------------- | | ------- | ----------------------------------------------------------------------------------- |
| Global | https://cdn.jsdelivr.net/npm/@page-agent/cdn/dist/page-agent.demo.js | | Global | https://cdn.jsdelivr.net/npm/@page-agent/cdn/dist/page-agent.demo.js |
| China | https://registry.npmmirror.com/@page-agent/cdn/latest/files/dist/page-agent.demo.js | | China | https://registry.npmmirror.com/@page-agent/cdn/latest/files/dist/page-agent.demo.js |
### NPM Installation (Recommended) ### NPM Installation
```bash ```bash
npm install page-agent npm install page-agent
@@ -53,35 +59,16 @@ npm install page-agent
import { PageAgent } from 'page-agent' import { PageAgent } from 'page-agent'
const agent = new PageAgent({ const agent = new PageAgent({
model: 'deepseek-chat', model: 'deepseek-chat',
baseURL: 'https://api.deepseek.com', baseURL: 'https://api.deepseek.com',
apiKey: 'YOUR_API_KEY', apiKey: 'YOUR_API_KEY',
language: 'en-US', language: 'en-US',
}) })
await agent.execute('Click the login button') await agent.execute('Click the login button')
``` ```
### CDN Build For environments where NPM is not available. We do offer a IIFE build via CDN. [@see CDN Usage](https://alibaba.github.io/page-agent/#/docs/integration/cdn-setup)
For environments where NPM is not available. Usage is identical to NPM:
```html
<script src="https://cdn.jsdelivr.net/npm/@page-agent/cdn/dist/page-agent.js" crossorigin="true"></script>
<script>
const agent = new PageAgent({
model: 'deepseek-chat',
baseURL: 'https://api.deepseek.com',
apiKey: 'YOUR_API_KEY',
})
await agent.execute('Click the login button')
</script>
```
| Location | URL |
| -------- | ----------------------------------------------------------------------------------- |
| Global | https://cdn.jsdelivr.net/npm/@page-agent/cdn/dist/page-agent.js |
| China | https://registry.npmmirror.com/@page-agent/cdn/latest/files/dist/page-agent.js |
## 🏗️ Structure ## 🏗️ Structure
@@ -101,28 +88,19 @@ packages/
We welcome contributions from the community! Here's how to get started: We welcome contributions from the community! Here's how to get started:
### Setup 1. Fork and clone. `git clone https://github.com/alibaba/page-agent.git && cd page-agent`
2. Install dependencies: `npm install`
3. Start development: `npm start`
1. Fork the repository More details in [CONTRIBUTING.md](CONTRIBUTING.md).
2. Clone your fork: `git clone https://github.com/alibaba/page-agent.git && cd page-agent`
3. Install dependencies: `npm install`
4. Start development: `npm start`
### Contributing Guidelines Please read our [Code of Conduct](CODE_OF_CONDUCT.md) before contributing.
Please read our [Code of Conduct](CODE_OF_CONDUCT.md) and [Contributing Guide](CONTRIBUTING.md) before contributing.
## 👏 Acknowledgments ## 👏 Acknowledgments
This project builds upon the excellent work of: This project builds upon the excellent work of **[`browser-use`](https://github.com/browser-use/browser-use)**.
- **[browser-use](https://github.com/browser-use/browser-use)** `PageAgent` is designed for **client-side web enhancement**, not server-side automation.
PageAgent is designed for **client-side web enhancement**, not server-side automation.
## 📄 License
MIT License - see the [LICENSE](LICENSE) file for details.
``` ```
DOM processing components and prompt are derived from browser-use: DOM processing components and prompt are derived from browser-use:
@@ -141,6 +119,10 @@ Third-party dependencies and their licenses can be found in the package.json
file and in the node_modules directory after installation. file and in the node_modules directory after installation.
``` ```
## 📄 License
[MIT License](LICENSE)
--- ---
**⭐ Star this repo if you find PageAgent helpful!** **⭐ Star this repo if you find PageAgent helpful!**
+12 -12
View File
@@ -1,12 +1,12 @@
{ {
"name": "root", "name": "root",
"version": "0.2.2", "version": "0.2.5",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "root", "name": "root",
"version": "0.2.2", "version": "0.2.5",
"license": "MIT", "license": "MIT",
"workspaces": [ "workspaces": [
"packages/page-controller", "packages/page-controller",
@@ -8133,15 +8133,15 @@
}, },
"packages/cdn": { "packages/cdn": {
"name": "@page-agent/cdn", "name": "@page-agent/cdn",
"version": "0.2.2", "version": "0.2.5",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"page-agent": "0.2.2" "page-agent": "0.2.5"
} }
}, },
"packages/llms": { "packages/llms": {
"name": "@page-agent/llms", "name": "@page-agent/llms",
"version": "0.2.2", "version": "0.2.5",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"chalk": "^5.6.2", "chalk": "^5.6.2",
@@ -8149,19 +8149,19 @@
} }
}, },
"packages/page-agent": { "packages/page-agent": {
"version": "0.2.2", "version": "0.2.5",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@page-agent/llms": "0.2.2", "@page-agent/llms": "0.2.5",
"@page-agent/page-controller": "0.2.2", "@page-agent/page-controller": "0.2.5",
"@page-agent/ui": "0.2.2", "@page-agent/ui": "0.2.5",
"chalk": "^5.6.2", "chalk": "^5.6.2",
"zod": "^4.3.5" "zod": "^4.3.5"
} }
}, },
"packages/page-controller": { "packages/page-controller": {
"name": "@page-agent/page-controller", "name": "@page-agent/page-controller",
"version": "0.2.2", "version": "0.2.5",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"ai-motion": "^0.4.8" "ai-motion": "^0.4.8"
@@ -8169,12 +8169,12 @@
}, },
"packages/ui": { "packages/ui": {
"name": "@page-agent/ui", "name": "@page-agent/ui",
"version": "0.2.2", "version": "0.2.5",
"license": "MIT" "license": "MIT"
}, },
"packages/website": { "packages/website": {
"name": "@page-agent/website", "name": "@page-agent/website",
"version": "0.2.2", "version": "0.2.5",
"dependencies": { "dependencies": {
"@radix-ui/react-icons": "^1.3.2", "@radix-ui/react-icons": "^1.3.2",
"@radix-ui/react-separator": "^1.1.8", "@radix-ui/react-separator": "^1.1.8",
+18 -2
View File
@@ -1,7 +1,7 @@
{ {
"name": "root", "name": "root",
"private": true, "private": true,
"version": "0.2.2", "version": "0.2.5",
"type": "module", "type": "module",
"workspaces": [ "workspaces": [
"packages/page-controller", "packages/page-controller",
@@ -102,6 +102,22 @@
".css$" ".css$"
], ],
"importOrderSeparation": true, "importOrderSeparation": true,
"importOrderSortSpecifiers": true "importOrderSortSpecifiers": true,
"overrides": [
{
"files": "*.md",
"options": {
"useTabs": false,
"tabWidth": 4
}
},
{
"files": "*.json",
"options": {
"useTabs": false,
"tabWidth": 4
}
}
]
} }
} }
+2 -2
View File
@@ -1,7 +1,7 @@
{ {
"name": "@page-agent/cdn", "name": "@page-agent/cdn",
"private": false, "private": false,
"version": "0.2.2", "version": "0.2.5",
"type": "module", "type": "module",
"files": [ "files": [
"dist/" "dist/"
@@ -18,6 +18,6 @@
"build": "vite build && vite build --mode demo" "build": "vite build && vite build --mode demo"
}, },
"dependencies": { "dependencies": {
"page-agent": "0.2.2" "page-agent": "0.2.5"
} }
} }
-41
View File
@@ -1,41 +0,0 @@
# @page-agent/llms
LLM client with a **reflection-before-action** mental model for page-agent.
## Why This Package Exists
The LLM module and the agent logic are inherently coupled. This package exists not to decouple them, but to **define the interface contract** between the LLM and the agent.
The core abstraction is the `MacroToolInput` — a structured output format that **forces the model to reflect before acting**.
## The Reflection-Before-Action Model
Every tool call must first output its reasoning state before the actual action:
```typescript
interface MacroToolInput {
// Reflection (mandatory before any action)
evaluation_previous_goal?: string // How well did the previous action work?
memory?: string // Key information to remember
next_goal?: string // What to accomplish next
// Action (the actual operation)
action: Record<string, any>
}
```
This design ensures that:
1. **The model evaluates its previous action** before deciding the next step
2. **Working memory is explicitly maintained** across conversation turns
3. **Goals are clearly stated**, making the agent's reasoning transparent and debuggable
## Key Components
| Export | Description |
|--------|-------------|
| `LLM` | Main LLM client class with retry logic |
| `MacroToolInput` | The reflection-before-action input schema |
| `AgentBrain` | Agent's thinking state (eval, memory, goal) |
| `LLMConfig` | Configuration for LLM connection |
| `parseLLMConfig` | Parse and apply defaults to config |
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@page-agent/llms", "name": "@page-agent/llms",
"version": "0.2.2", "version": "0.2.5",
"type": "module", "type": "module",
"main": "./dist/lib/page-agent-llms.js", "main": "./dist/lib/page-agent-llms.js",
"module": "./dist/lib/page-agent-llms.js", "module": "./dist/lib/page-agent-llms.js",
+7 -8
View File
@@ -1,10 +1,9 @@
{ {
"extends": "./tsconfig.json", "extends": "./tsconfig.json",
"compilerOptions": { "compilerOptions": {
// @workaround DTS bug // @workaround DTS bug
// dts do not work with monorepo path mapping // dts do not work with monorepo path mapping
// disable path mapping for it // disable path mapping for it
"paths": {} "paths": {}
} }
} }
+10 -11
View File
@@ -1,13 +1,12 @@
{ {
"extends": "../../tsconfig.base.json", "extends": "../../tsconfig.base.json",
"compilerOptions": { "compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.tsbuildinfo", "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.tsbuildinfo",
"noEmit": false, "noEmit": false,
"allowImportingTsExtensions": false, "allowImportingTsExtensions": false,
"baseUrl": ".", "baseUrl": ".",
"outDir": "dist" "outDir": "dist"
}, },
"include": ["**/*.ts"], "include": ["**/*.ts"],
"exclude": ["dist", "node_modules"] "exclude": ["dist", "node_modules"]
} }
+4 -4
View File
@@ -1,7 +1,7 @@
{ {
"name": "page-agent", "name": "page-agent",
"private": false, "private": false,
"version": "0.2.2", "version": "0.2.5",
"type": "module", "type": "module",
"main": "./dist/esm/page-agent.js", "main": "./dist/esm/page-agent.js",
"module": "./dist/esm/page-agent.js", "module": "./dist/esm/page-agent.js",
@@ -45,8 +45,8 @@
"dependencies": { "dependencies": {
"chalk": "^5.6.2", "chalk": "^5.6.2",
"zod": "^4.3.5", "zod": "^4.3.5",
"@page-agent/llms": "0.2.2", "@page-agent/llms": "0.2.5",
"@page-agent/page-controller": "0.2.2", "@page-agent/page-controller": "0.2.5",
"@page-agent/ui": "0.2.2" "@page-agent/ui": "0.2.5"
} }
} }
+32 -24
View File
@@ -90,9 +90,6 @@ export interface UserTakeoverEvent {
*/ */
export type HistoryEvent = AgentStep | ObservationEvent | UserTakeoverEvent export type HistoryEvent = AgentStep | ObservationEvent | UserTakeoverEvent
/** @deprecated Use AgentStep instead */
export type AgentHistory = AgentStep
export interface ExecutionResult { export interface ExecutionResult {
success: boolean success: boolean
data: string data: string
@@ -102,7 +99,7 @@ export interface ExecutionResult {
export class PageAgent extends EventTarget { export class PageAgent extends EventTarget {
config: PageAgentConfig config: PageAgentConfig
id = uid() id = uid()
panel: Panel panel: Panel | null = null
tools: typeof tools tools: typeof tools
disposed = false disposed = false
task = '' task = ''
@@ -125,7 +122,7 @@ export class PageAgent extends EventTarget {
lastURL: '', lastURL: '',
} }
/** History event stream */ /** History events */
history: HistoryEvent[] = [] history: HistoryEvent[] = []
constructor(config: PageAgentConfig) { constructor(config: PageAgentConfig) {
@@ -133,11 +130,17 @@ export class PageAgent extends EventTarget {
this.config = config this.config = config
this.#llm = new LLM(this.config) this.#llm = new LLM(this.config)
this.panel = new Panel({
language: this.config.language, // Conditionally initialize Panel
onExecuteTask: (task) => this.execute(task), if (this.config.enablePanel !== false) {
onStop: () => this.dispose(), this.panel = new Panel({
}) language: this.config.language,
onExecuteTask: (task) => this.execute(task),
onStop: () => this.dispose(),
promptForNextTask: this.config.promptForNextTask,
})
}
this.tools = new Map(tools) this.tools = new Map(tools)
// Initialize PageController with config (mask enabled by default) // Initialize PageController with config (mask enabled by default)
@@ -149,11 +152,11 @@ export class PageAgent extends EventTarget {
// Listen to LLM events // Listen to LLM events
this.#llmRetryListener = (e) => { this.#llmRetryListener = (e) => {
const { current, max } = (e as CustomEvent).detail const { current, max } = (e as CustomEvent).detail
this.panel.update({ type: 'retry', current, max }) this.panel?.update({ type: 'retry', current, max })
} }
this.#llmErrorListener = (e) => { this.#llmErrorListener = (e) => {
const { error } = (e as CustomEvent).detail const { error } = (e as CustomEvent).detail
this.panel.update({ type: 'error', message: `step failed: ${error.message}` }) this.panel?.update({ type: 'error', message: `step failed: ${error.message}` })
} }
this.#llm.addEventListener('retry', this.#llmRetryListener) this.#llm.addEventListener('retry', this.#llmRetryListener)
this.#llm.addEventListener('error', this.#llmErrorListener) this.#llm.addEventListener('error', this.#llmErrorListener)
@@ -172,6 +175,11 @@ export class PageAgent extends EventTarget {
this.tools.delete('execute_javascript') this.tools.delete('execute_javascript')
} }
// Disable ask_user tool if enableAskUser is false or if panel is disabled
if (this.config.enableAskUser === false || this.config.enablePanel === false) {
this.tools.delete('ask_user')
}
this.#beforeUnloadListener = (e) => { this.#beforeUnloadListener = (e) => {
if (!this.disposed) this.dispose('PAGE_UNLOADING') if (!this.disposed) this.dispose('PAGE_UNLOADING')
} }
@@ -184,7 +192,7 @@ export class PageAgent extends EventTarget {
*/ */
pushObservation(content: string): void { pushObservation(content: string): void {
this.history.push({ type: 'observation', content }) this.history.push({ type: 'observation', content })
this.panel.update({ type: 'observation', content }) this.panel?.update({ type: 'observation', content })
} }
async execute(task: string): Promise<ExecutionResult> { async execute(task: string): Promise<ExecutionResult> {
@@ -202,10 +210,10 @@ export class PageAgent extends EventTarget {
// Show mask and panel // Show mask and panel
this.pageController.showMask() this.pageController.showMask()
this.panel.show() this.panel?.show()
this.panel.reset() this.panel?.reset()
this.panel.update({ type: 'input', task: this.task }) this.panel?.update({ type: 'input', task: this.task })
if (this.#abortController) { if (this.#abortController) {
this.#abortController.abort() this.#abortController.abort()
@@ -235,7 +243,7 @@ export class PageAgent extends EventTarget {
// Update status to thinking // Update status to thinking
console.log(chalk.blue('Thinking...')) console.log(chalk.blue('Thinking...'))
this.panel.update({ type: 'thinking' }) this.panel?.update({ type: 'thinking' })
const result = await this.#llm.invoke( const result = await this.#llm.invoke(
[ [
@@ -373,7 +381,7 @@ export class PageAgent extends EventTarget {
if (reflectionText) { if (reflectionText) {
console.log(reflectionText) console.log(reflectionText)
this.panel.update({ type: 'thinking', text: reflectionText }) this.panel?.update({ type: 'thinking', text: reflectionText })
} }
// Find the corresponding tool // Find the corresponding tool
@@ -381,7 +389,7 @@ export class PageAgent extends EventTarget {
assert(tool, `Tool ${toolName} not found. (@note should have been caught before this!!!)`) assert(tool, `Tool ${toolName} not found. (@note should have been caught before this!!!)`)
console.log(chalk.blue.bold(`Executing tool: ${toolName}`), toolInput) console.log(chalk.blue.bold(`Executing tool: ${toolName}`), toolInput)
this.panel.update({ type: 'toolExecuting', toolName, args: toolInput }) this.panel?.update({ type: 'toolExecuting', toolName, args: toolInput })
const startTime = Date.now() const startTime = Date.now()
@@ -397,7 +405,7 @@ export class PageAgent extends EventTarget {
} }
// Briefly display execution result // Briefly display execution result
this.panel.update({ this.panel?.update({
type: 'toolCompleted', type: 'toolCompleted',
toolName, toolName,
args: toolInput, args: toolInput,
@@ -560,13 +568,13 @@ export class PageAgent extends EventTarget {
// Update panel status // Update panel status
if (success) { if (success) {
this.panel.update({ type: 'output', text }) this.panel?.update({ type: 'output', text })
} else { } else {
this.panel.update({ type: 'error', message: text }) this.panel?.update({ type: 'error', message: text })
} }
// Task completed // Task completed
this.panel.update({ type: 'completed' }) this.panel?.update({ type: 'completed' })
this.pageController.hideMask() this.pageController.hideMask()
@@ -596,7 +604,7 @@ export class PageAgent extends EventTarget {
console.log('Disposing PageAgent...') console.log('Disposing PageAgent...')
this.disposed = true this.disposed = true
this.pageController.dispose() this.pageController.dispose()
this.panel.dispose() this.panel?.dispose()
this.history = [] this.history = []
this.#abortController.abort(reason ?? 'PageAgent disposed') this.#abortController.abort(reason ?? 'PageAgent disposed')
+23 -2
View File
@@ -11,6 +11,27 @@ export interface AgentConfig {
// theme?: 'light' | 'dark' // theme?: 'light' | 'dark'
language?: SupportedLanguage language?: SupportedLanguage
/**
* Whether to prompt for next task after task completion
* @default true
*/
promptForNextTask?: boolean
/**
* Enable the UI panel for visual feedback and user interaction
* When disabled, the panel will not be created and all UI operations will be skipped.
* Useful for automated testing or when integrating PageAgent as a library.
* @default true
*/
enablePanel?: boolean
/**
* Enable the ask_user tool for agent to ask questions
* When disabled, the agent cannot ask user questions during execution.
* @default true
*/
enableAskUser?: boolean
/** /**
* Custom tools to extend PageAgent capabilities * Custom tools to extend PageAgent capabilities
* @experimental * @experimental
@@ -108,14 +129,14 @@ export interface AgentConfig {
* @note PageAgent will try to detect new pages and decide if it's caused by an action. But not very reliable. * @note PageAgent will try to detect new pages and decide if it's caused by an action. But not very reliable.
* @todo remove `this` binding, pass agent as explicit parameter instead * @todo remove `this` binding, pass agent as explicit parameter instead
*/ */
onNewPageOpen?: (this: PageAgent, url: string) => Promise<void> | void // onNewPageOpen?: (this: PageAgent, url: string) => Promise<void> | void
/** /**
* TODO: @unimplemented * TODO: @unimplemented
* try to navigate to a new page instead of opening a new tab/window. * try to navigate to a new page instead of opening a new tab/window.
* @note will unload the current page when a action tries to open a new page. so that things keep in the same tab/window. * @note will unload the current page when a action tries to open a new page. so that things keep in the same tab/window.
*/ */
experimentalPreventNewPage?: boolean // experimentalPreventNewPage?: boolean
} }
export type PageAgentConfig = LLMConfig & AgentConfig & PageControllerConfig export type PageAgentConfig = LLMConfig & AgentConfig & PageControllerConfig
@@ -0,0 +1 @@
system_prompt.md
@@ -92,7 +92,6 @@ Strictly follow these rules while using the browser and navigating the web:
- User can be wrong. If the request of user is not achievable, inappropriate or you do not have enough information or tools to achieve it. Tell user to make a better request. - User can be wrong. If the request of user is not achievable, inappropriate or you do not have enough information or tools to achieve it. Tell user to make a better request.
- Webpage can be broken. All webpages or apps have bugs. Some bug will make it hard for your job. It's encouraged to tell user the problem of current page. Your feedbacks (including failing) are valuable for user. - Webpage can be broken. All webpages or apps have bugs. Some bug will make it hard for your job. It's encouraged to tell user the problem of current page. Your feedbacks (including failing) are valuable for user.
- Trying to hard can be harmful. Repeating some action back and forth or pushing for a complex procedure with little knowledge can cause unwanted result and harmful side-effects. User would rather you to complete the task with a fail. - Trying to hard can be harmful. Repeating some action back and forth or pushing for a complex procedure with little knowledge can cause unwanted result and harmful side-effects. User would rather you to complete the task with a fail.
- If you are not clear about the request or steps. `ask_user` to clarify it.
- If you do not have knowledge for the current webpage or task. You must require user to give specific instructions and detailed steps. - If you do not have knowledge for the current webpage or task. You must require user to give specific instructions and detailed steps.
</capability> </capability>
@@ -120,7 +119,7 @@ Exhibit the following reasoning patterns to successfully achieve the <user_reque
- Analyze all relevant items in <agent_history> and <browser_state> to understand your state. - Analyze all relevant items in <agent_history> and <browser_state> to understand your state.
- Explicitly judge success/failure/uncertainty of the last action. Never assume an action succeeded just because it appears to be executed in your last step in <agent_history>. If the expected change is missing, mark the last action as failed (or uncertain) and plan a recovery. - Explicitly judge success/failure/uncertainty of the last action. Never assume an action succeeded just because it appears to be executed in your last step in <agent_history>. If the expected change is missing, mark the last action as failed (or uncertain) and plan a recovery.
- Analyze whether you are stuck, e.g. when you repeat the same actions multiple times without any progress. Then consider alternative approaches e.g. scrolling for more context or ask user for help. - Analyze whether you are stuck, e.g. when you repeat the same actions multiple times without any progress. Then consider alternative approaches e.g. scrolling for more context or ask user for help.
- `ask_user` for help if you have any difficulty. Users want to be kept in the loop. - Ask user for help if you have any difficulty. Keep user in the loop.
- If you see information relevant to <user_request>, plan saving the information to memory. - If you see information relevant to <user_request>, plan saving the information to memory.
- Always reason about the <user_request>. Make sure to carefully analyze the specific steps and information required. E.g. specific filters, specific form fields, specific information to search. Make sure to always compare the current trajectory with the user request and think carefully if thats how the user requested it. - Always reason about the <user_request>. Make sure to carefully analyze the specific steps and information required. E.g. specific filters, specific form fields, specific information to search. Make sure to always compare the current trajectory with the user request and think carefully if thats how the user requested it.
</reasoning_rules> </reasoning_rules>
+3
View File
@@ -80,6 +80,9 @@ tools.set(
question: zod.string(), question: zod.string(),
}), }),
execute: async function (this: PageAgent, input) { execute: async function (this: PageAgent, input) {
if (!this.panel) {
throw new Error('ask_user tool requires panel to be enabled')
}
const answer = await this.panel.askUser(input.question) const answer = await this.panel.askUser(input.question)
return `✅ Received user answer: ${answer}` return `✅ Received user answer: ${answer}`
}, },
+7 -7
View File
@@ -1,9 +1,9 @@
{ {
"extends": "./tsconfig.json", "extends": "./tsconfig.json",
"compilerOptions": { "compilerOptions": {
// @workaround DTS bug // @workaround DTS bug
// dts do not work with monorepo path mapping // dts do not work with monorepo path mapping
// disable path mapping for it // disable path mapping for it
"paths": {} "paths": {}
} }
} }
+22 -22
View File
@@ -1,24 +1,24 @@
{ {
"extends": "../../tsconfig.base.json", "extends": "../../tsconfig.base.json",
"compilerOptions": { "compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.tsbuildinfo", "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.tsbuildinfo",
"noEmit": false, "noEmit": false,
"allowImportingTsExtensions": false, "allowImportingTsExtensions": false,
"baseUrl": ".", "baseUrl": ".",
"outDir": "dist", "outDir": "dist",
"paths": { "paths": {
// //
"@page-agent/llms": ["../llms/src/index.ts"], "@page-agent/llms": ["../llms/src/index.ts"],
"@page-agent/page-controller": ["../page-controller/src/PageController.ts"], "@page-agent/page-controller": ["../page-controller/src/PageController.ts"],
"@page-agent/ui": ["../ui/src/index.ts"] "@page-agent/ui": ["../ui/src/index.ts"]
} }
}, },
"include": ["**/*.ts"], "include": ["**/*.ts"],
"exclude": ["dist", "node_modules"], "exclude": ["dist", "node_modules"],
"references": [ "references": [
// //
{ "path": "../llms" }, { "path": "../llms" },
{ "path": "../page-controller" }, { "path": "../page-controller" },
{ "path": "../ui" } { "path": "../ui" }
] ]
} }
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@page-agent/page-controller", "name": "@page-agent/page-controller",
"version": "0.2.2", "version": "0.2.5",
"type": "module", "type": "module",
"main": "./dist/lib/page-controller.js", "main": "./dist/lib/page-controller.js",
"module": "./dist/lib/page-controller.js", "module": "./dist/lib/page-controller.js",
+7 -7
View File
@@ -1,9 +1,9 @@
{ {
"extends": "./tsconfig.json", "extends": "./tsconfig.json",
"compilerOptions": { "compilerOptions": {
// @workaround DTS bug // @workaround DTS bug
// dts do not work with monorepo path mapping // dts do not work with monorepo path mapping
// disable path mapping for it // disable path mapping for it
"paths": {} "paths": {}
} }
} }
+10 -10
View File
@@ -1,12 +1,12 @@
{ {
"extends": "../../tsconfig.base.json", "extends": "../../tsconfig.base.json",
"compilerOptions": { "compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.tsbuildinfo", "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.tsbuildinfo",
"noEmit": false, "noEmit": false,
"allowImportingTsExtensions": false, "allowImportingTsExtensions": false,
"baseUrl": ".", "baseUrl": ".",
"outDir": "dist" "outDir": "dist"
}, },
"include": ["**/*.ts", "**/*.js"], "include": ["**/*.ts", "**/*.js"],
"exclude": ["dist", "node_modules"] "exclude": ["dist", "node_modules"]
} }
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@page-agent/ui", "name": "@page-agent/ui",
"version": "0.2.2", "version": "0.2.5",
"type": "module", "type": "module",
"main": "./dist/lib/page-agent-ui.js", "main": "./dist/lib/page-agent-ui.js",
"module": "./dist/lib/page-agent-ui.js", "module": "./dist/lib/page-agent-ui.js",
+13 -1
View File
@@ -11,6 +11,11 @@ export interface PanelConfig {
language?: SupportedLanguage language?: SupportedLanguage
onExecuteTask: (task: string) => void onExecuteTask: (task: string) => void
onStop: () => void onStop: () => void
/**
* Whether to prompt for next task after task completion
* @default true
*/
promptForNextTask?: boolean
} }
/** /**
@@ -358,7 +363,14 @@ export class Panel {
} }
const lastStep = steps[steps.length - 1] const lastStep = steps[steps.length - 1]
return lastStep.type === 'completed' || lastStep.type === 'error' const isTaskEnded = lastStep.type === 'completed' || lastStep.type === 'error'
// Only show input area after task completion if configured to do so
if (isTaskEnded) {
return this.#config.promptForNextTask ?? true
}
return false
} }
#createWrapper(): HTMLElement { #createWrapper(): HTMLElement {
+1 -1
View File
@@ -2,4 +2,4 @@ This is the CSS implementation of ai-motion.
Easy to use but Terrible performance. Causing full screen glitching in some browsers. Easy to use but Terrible performance. Causing full screen glitching in some browsers.
Use it only in a small area. Use it only in a small area.
+7 -8
View File
@@ -1,10 +1,9 @@
{ {
"extends": "./tsconfig.json", "extends": "./tsconfig.json",
"compilerOptions": { "compilerOptions": {
// @workaround DTS bug // @workaround DTS bug
// dts do not work with monorepo path mapping // dts do not work with monorepo path mapping
// disable path mapping for it // disable path mapping for it
"paths": {} "paths": {}
} }
} }
+10 -11
View File
@@ -1,13 +1,12 @@
{ {
"extends": "../../tsconfig.base.json", "extends": "../../tsconfig.base.json",
"compilerOptions": { "compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.tsbuildinfo", "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.tsbuildinfo",
"noEmit": false, "noEmit": false,
"allowImportingTsExtensions": false, "allowImportingTsExtensions": false,
"baseUrl": ".", "baseUrl": ".",
"outDir": "dist" "outDir": "dist"
}, },
"include": ["**/*.ts", "**/*.js"], "include": ["**/*.ts", "**/*.js"],
"exclude": ["dist", "node_modules"] "exclude": ["dist", "node_modules"]
} }
-1
View File
@@ -1 +0,0 @@
# Landing Page & Docs
+22 -22
View File
@@ -1,24 +1,24 @@
{ {
"$schema": "https://ui.shadcn.com/schema.json", "$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york", "style": "new-york",
"rsc": false, "rsc": false,
"tsx": true, "tsx": true,
"tailwind": { "tailwind": {
"config": "", "config": "",
"css": "src/index.css", "css": "src/index.css",
"baseColor": "neutral", "baseColor": "neutral",
"cssVariables": true, "cssVariables": true,
"prefix": "" "prefix": ""
}, },
"iconLibrary": "lucide", "iconLibrary": "lucide",
"aliases": { "aliases": {
"components": "@/components", "components": "@/components",
"utils": "@/lib/utils", "utils": "@/lib/utils",
"ui": "@/components/ui", "ui": "@/components/ui",
"lib": "@/lib", "lib": "@/lib",
"hooks": "@/hooks" "hooks": "@/hooks"
}, },
"registries": { "registries": {
"@magicui": "https://magicui.design/r/{name}.json" "@magicui": "https://magicui.design/r/{name}.json"
} }
} }
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"name": "@page-agent/website", "name": "@page-agent/website",
"private": true, "private": true,
"version": "0.2.2", "version": "0.2.5",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite --host 0.0.0.0", "dev": "vite --host 0.0.0.0",
+4 -4
View File
@@ -22,7 +22,7 @@ export default function Header() {
<div className="flex items-center justify-between gap-2"> <div className="flex items-center justify-between gap-2">
{/* Logo */} {/* Logo */}
<Link <Link
href="/" href="~/"
className="flex items-center gap-2 sm:gap-3 group shrink-0" className="flex items-center gap-2 sm:gap-3 group shrink-0"
aria-label={t('header.logo_alt')} aria-label={t('header.logo_alt')}
onClick={() => setMobileMenuOpen(false)} onClick={() => setMobileMenuOpen(false)}
@@ -55,7 +55,7 @@ export default function Header() {
aria-label="Mobile navigation" aria-label="Mobile navigation"
> >
<Link <Link
href="/docs/introduction/overview" href="~/docs/introduction/overview"
className="p-2 rounded-lg text-gray-600 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 hover:text-blue-600 dark:hover:text-blue-400 transition-colors duration-200 shrink-0" className="p-2 rounded-lg text-gray-600 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 hover:text-blue-600 dark:hover:text-blue-400 transition-colors duration-200 shrink-0"
aria-label={t('header.nav_docs')} aria-label={t('header.nav_docs')}
> >
@@ -89,7 +89,7 @@ export default function Header() {
{import.meta.env.VERSION} {import.meta.env.VERSION}
</span> </span>
<Link <Link
href="/docs/introduction/overview" href="~/docs/introduction/overview"
className="flex items-center gap-1.5 text-gray-600 dark:text-gray-300 hover:text-blue-600 dark:hover:text-blue-400 transition-colors duration-200" className="flex items-center gap-1.5 text-gray-600 dark:text-gray-300 hover:text-blue-600 dark:hover:text-blue-400 transition-colors duration-200"
> >
<BookOpen className="w-4 h-4" /> <BookOpen className="w-4 h-4" />
@@ -137,7 +137,7 @@ export default function Header() {
role="navigation" role="navigation"
> >
<Link <Link
href="/docs/introduction/overview" href="~/docs/introduction/overview"
className="flex items-center gap-2 px-3 py-2 rounded-lg text-gray-600 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 hover:text-blue-600 dark:hover:text-blue-400 transition-colors duration-200" className="flex items-center gap-2 px-3 py-2 rounded-lg text-gray-600 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 hover:text-blue-600 dark:hover:text-blue-400 transition-colors duration-200"
onClick={() => setMobileMenuOpen(false)} onClick={() => setMobileMenuOpen(false)}
> >
+3 -4
View File
@@ -28,9 +28,9 @@ pages/i18n/
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
function MyComponent() { function MyComponent() {
const { t } = useTranslation('common') // 指定命名空间 const { t } = useTranslation('common') // 指定命名空间
return <h1>{t('header.nav_docs')}</h1> return <h1>{t('header.nav_docs')}</h1>
} }
``` ```
@@ -71,4 +71,3 @@ t('common:header.nav_docs')
- [ ] 文档页翻译(`docs.json` - [ ] 文档页翻译(`docs.json`
- [ ] DocsLayout 导航结构国际化 - [ ] DocsLayout 导航结构国际化
- [ ] 404 页面国际化 - [ ] 404 页面国际化
+5 -1
View File
@@ -89,6 +89,10 @@ export default function HomePage() {
import.meta.env.DEV && import.meta.env.LLM_API_KEY import.meta.env.DEV && import.meta.env.LLM_API_KEY
? import.meta.env.LLM_API_KEY ? import.meta.env.LLM_API_KEY
: DEMO_API_KEY, : DEMO_API_KEY,
// enableAskUser: false,
// promptForNextTask: false,
// enablePanel: false,
}) })
} }
@@ -103,7 +107,7 @@ export default function HomePage() {
{/* Hero Section */} {/* Hero Section */}
<main id="main-content"> <main id="main-content">
<section <section
className="relative px-6 py-22 lg:py-28 overflow-hidden" className="relative px-6 py-22 pb-18 lg:py-28 overflow-hidden"
aria-labelledby="hero-heading" aria-labelledby="hero-heading"
> >
<div className="max-w-7xl mx-auto text-center"> <div className="max-w-7xl mx-auto text-center">
+13 -13
View File
@@ -24,38 +24,38 @@ export default function DocsLayout({ children }: DocsLayoutProps) {
{ {
title: t('nav.introduction'), title: t('nav.introduction'),
items: [ items: [
{ title: t('nav.overview'), path: '/docs/introduction/overview' }, { title: t('nav.overview'), path: '/introduction/overview' },
{ title: t('nav.quick_start'), path: '/docs/introduction/quick-start' }, { title: t('nav.quick_start'), path: '/introduction/quick-start' },
{ title: t('nav.limitations'), path: '/docs/introduction/limitations' }, { title: t('nav.limitations'), path: '/introduction/limitations' },
], ],
}, },
{ {
title: t('nav.features'), title: t('nav.features'),
items: [ items: [
{ title: t('nav.models'), path: '/docs/features/models' }, { title: t('nav.models'), path: '/features/models' },
{ title: t('nav.custom_tools'), path: '/docs/features/custom-tools' }, { title: t('nav.custom_tools'), path: '/features/custom-tools' },
{ title: t('nav.knowledge_injection'), path: '/docs/features/custom-instructions' }, { title: t('nav.knowledge_injection'), path: '/features/custom-instructions' },
{ title: t('nav.data_masking'), path: '/docs/features/data-masking' }, { title: t('nav.data_masking'), path: '/features/data-masking' },
], ],
}, },
{ {
title: t('nav.integration'), title: t('nav.integration'),
items: [ items: [
{ title: t('nav.configuration'), path: '/docs/integration/configuration' }, { title: t('nav.configuration'), path: '/integration/configuration' },
{ title: t('nav.third_party_agent'), path: '/docs/integration/third-party-agent' }, { title: t('nav.third_party_agent'), path: '/integration/third-party-agent' },
{ title: t('nav.cdn_setup'), path: '/docs/integration/cdn-setup' }, { title: t('nav.cdn_setup'), path: '/integration/cdn-setup' },
{ {
title: '🚧 ' + t('nav.security_permissions'), title: '🚧 ' + t('nav.security_permissions'),
path: '/docs/integration/security-permissions', path: '/integration/security-permissions',
}, },
{ title: '🚧 ' + t('nav.best_practices'), path: '/docs/integration/best-practices' }, { title: '🚧 ' + t('nav.best_practices'), path: '/integration/best-practices' },
], ],
}, },
] ]
return ( return (
<div className="max-w-7xl mx-auto px-6 py-8 overflow-x-auto"> <div className="max-w-7xl mx-auto px-6 py-8 overflow-x-auto">
<div className="flex gap-8 min-w-[900px]"> <div className="flex gap-8 min-w-225">
{/* Sidebar */} {/* Sidebar */}
<aside className="w-64 shrink-0" role="complementary" aria-label="文档导航"> <aside className="w-64 shrink-0" role="complementary" aria-label="文档导航">
<div className="sticky"> <div className="sticky">
+110
View File
@@ -0,0 +1,110 @@
import { Suspense } from 'react'
import { Route, Switch } from 'wouter'
import Header from '../../components/Header'
import DocsLayout from './Layout'
import Instructions from './features/custom-instructions/page'
// Features
import CustomTools from './features/custom-tools/page'
import DataMasking from './features/data-masking/page'
import Models from './features/models/page'
import BestPractices from './integration/best-practices/page'
// Integration
import CdnSetup from './integration/cdn-setup/page'
import Configuration from './integration/configuration/page'
import SecurityPermissions from './integration/security-permissions/page'
import ThirdPartyAgent from './integration/third-party-agent/page'
import Limitations from './introduction/limitations/page'
// Introduction
import Overview from './introduction/overview/page'
import QuickStart from './introduction/quick-start/page'
function DocsPage({ children }: { children: React.ReactNode }) {
return (
<div className="min-h-screen bg-white dark:bg-gray-900">
<Header />
<DocsLayout>
<Suspense>{children}</Suspense>
</DocsLayout>
</div>
)
}
export default function DocsRouter() {
return (
<Switch>
{/* Introduction */}
<Route path="/introduction/overview">
<DocsPage>
<Overview />
</DocsPage>
</Route>
<Route path="/introduction/quick-start">
<DocsPage>
<QuickStart />
</DocsPage>
</Route>
<Route path="/introduction/limitations">
<DocsPage>
<Limitations />
</DocsPage>
</Route>
{/* Features */}
<Route path="/features/custom-tools">
<DocsPage>
<CustomTools />
</DocsPage>
</Route>
<Route path="/features/data-masking">
<DocsPage>
<DataMasking />
</DocsPage>
</Route>
<Route path="/features/custom-instructions">
<DocsPage>
<Instructions />
</DocsPage>
</Route>
<Route path="/features/models">
<DocsPage>
<Models />
</DocsPage>
</Route>
{/* Integration */}
<Route path="/integration/cdn-setup">
<DocsPage>
<CdnSetup />
</DocsPage>
</Route>
<Route path="/integration/security-permissions">
<DocsPage>
<SecurityPermissions />
</DocsPage>
</Route>
<Route path="/integration/configuration">
<DocsPage>
<Configuration />
</DocsPage>
</Route>
<Route path="/integration/best-practices">
<DocsPage>
<BestPractices />
</DocsPage>
</Route>
<Route path="/integration/third-party-agent">
<DocsPage>
<ThirdPartyAgent />
</DocsPage>
</Route>
{/* Default redirect or 404 */}
<Route path="/docs">
<DocsPage>
<Overview />
</DocsPage>
</Route>
</Switch>
)
}
@@ -28,15 +28,17 @@ export default function Configuration() {
className="mb-4" className="mb-4"
language="typescript" language="typescript"
code={`interface LLMConfig { code={`interface LLMConfig {
baseURL?: string baseURL: string
apiKey?: string apiKey: string
model?: string model: string
temperature?: number temperature?: number
maxRetries?: number maxRetries?: number
/** /**
* Custom fetch function for LLM API requests. * Custom fetch function for LLM API requests.
* Use this to customize headers, credentials, proxy, etc. * Use this to customize headers, credentials, proxy, etc.
* The response should follow OpenAI API format.
*/ */
customFetch?: typeof globalThis.fetch customFetch?: typeof globalThis.fetch
}`} }`}
@@ -59,6 +61,27 @@ export default function Configuration() {
code={`interface AgentConfig { code={`interface AgentConfig {
language?: 'en-US' | 'zh-CN' language?: 'en-US' | 'zh-CN'
/**
* Whether to prompt for next task after task completion
* @default true
*/
promptForNextTask?: boolean
/**
* Enable the UI panel for visual feedback and user interaction
* When disabled, the panel will not be created and all UI operations will be skipped.
* Useful for automated testing or when integrating PageAgent as a library.
* @default true
*/
enablePanel?: boolean
/**
* Enable the ask_user tool for agent to ask questions
* When disabled, the agent cannot ask user questions during execution.
* @default true
*/
enableAskUser?: boolean
/** Custom tools to extend or override built-in tools */ /** Custom tools to extend or override built-in tools */
customTools?: Record<string, PageAgentTool | null> customTools?: Record<string, PageAgentTool | null>
@@ -71,12 +94,12 @@ export default function Configuration() {
getPageInstructions?: (url: string) => string | undefined | null getPageInstructions?: (url: string) => string | undefined | null
} }
// Lifecycle hooks // Lifecycle hooks (with \`this\` bound to PageAgent instance)
onBeforeStep?: (stepCnt: number) => Promise<void> | void onBeforeStep?: (this: PageAgent, stepCnt: number) => Promise<void> | void
onAfterStep?: (stepCnt: number, history: AgentHistory[]) => Promise<void> | void onAfterStep?: (this: PageAgent, stepCnt: number, history: HistoryEvent[]) => Promise<void> | void
onBeforeTask?: () => Promise<void> | void onBeforeTask?: (this: PageAgent) => Promise<void> | void
onAfterTask?: (result: ExecutionResult) => Promise<void> | void onAfterTask?: (this: PageAgent, result: ExecutionResult) => Promise<void> | void
onDispose?: (reason?: string) => void onDispose?: (this: PageAgent, reason?: string) => void
/** /**
* Transform page content before sending to LLM. * Transform page content before sending to LLM.
@@ -103,7 +126,7 @@ export default function Configuration() {
<CodeEditor <CodeEditor
className="mb-4" className="mb-4"
language="typescript" language="typescript"
code={`interface PageControllerConfig { code={`interface DomConfig {
/** Elements to exclude from interaction */ /** Elements to exclude from interaction */
interactiveBlacklist?: (Element | (() => Element))[] interactiveBlacklist?: (Element | (() => Element))[]
@@ -118,15 +141,13 @@ export default function Configuration() {
/** Highlight label opacity (0-1) */ /** Highlight label opacity (0-1) */
highlightLabelOpacity?: number highlightLabelOpacity?: number
}
/** Viewport expansion in pixels (-1 for full page) */ interface PageControllerConfig extends DomConfig {
/** Viewport expansion in pixels */
viewportExpansion?: number viewportExpansion?: number
/** /** Enable visual mask overlay during operations (default: false) */
* Enable visual mask overlay during automation.
* Blocks user interaction while agent is running.
* Default: false for PageController, true for PageAgent.
*/
enableMask?: boolean enableMask?: boolean
}`} }`}
/> />
@@ -140,6 +161,39 @@ export default function Configuration() {
code={`type PageAgentConfig = LLMConfig & AgentConfig & PageControllerConfig`} code={`type PageAgentConfig = LLMConfig & AgentConfig & PageControllerConfig`}
/> />
</section> </section>
{/* Programmatic Usage Example */}
<section className="mb-10">
<h2 className="text-2xl font-semibold mb-4">
{isZh ? '程序化使用配置' : 'Programmatic Usage'}
</h2>
<p className="text-gray-600 dark:text-gray-400 mb-4">
{isZh
? '对于程序化集成场景,可以禁用 UI。'
: 'For programmatic integration, you can disable UI.'}
</p>
<CodeEditor
language="typescript"
code={`const agent = new PageAgent({
baseURL: 'https://api.openai.com/v1',
apiKey: 'your-api-key',
model: 'your-model-name',
// Disable all UI features for pure programmatic usage
enablePanel: false, // Don't create Panel UI
enableMask: false, // Don't show visual overlay (mask and pointer)
// enableAskUser is automatically disabled when enablePanel is false
// Or keep Panel but disable post-task prompts
// enablePanel: true,
// promptForNextTask: false,
})
// Pure programmatic execution
const result = await agent.execute('search for TypeScript documentation')
console.log(result.success, result.data, result.history)`}
/>
</section>
</div> </div>
) )
} }
@@ -36,7 +36,7 @@ const pageAgentTool = {
}, },
execute: async (params) => { execute: async (params) => {
const result = await pageAgent.execute(params.instruction) const result = await pageAgent.execute(params.instruction)
return { success: result.success, message: result.message } return { success: result.success, message: result.data }
} }
} }
@@ -22,13 +22,6 @@ export default function Overview() {
{/* Status Badges */} {/* Status Badges */}
<div className="flex flex-wrap gap-2 items-center"> <div className="flex flex-wrap gap-2 items-center">
<a
href="https://www.npmjs.com/package/page-agent"
target="_blank"
rel="noopener noreferrer"
>
<img src="https://badge.fury.io/js/page-agent.svg" alt="npm version" />
</a>
<a href="https://opensource.org/licenses/MIT" target="_blank" rel="noopener noreferrer"> <a href="https://opensource.org/licenses/MIT" target="_blank" rel="noopener noreferrer">
<img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="MIT License" /> <img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="MIT License" />
</a> </a>
+4 -93
View File
@@ -1,37 +1,9 @@
import { Suspense, lazy } from 'react' import { Suspense, lazy } from 'react'
import { Route, Switch } from 'wouter' import { Route, Switch } from 'wouter'
import Header from './components/Header'
import DocsLayout from './pages/docs/Layout'
// Lazy load pages // Lazy load pages
const HomePage = lazy(() => import('./pages/Home')) const HomePage = lazy(() => import('./pages/Home'))
// Introduction const DocsPages = lazy(() => import('./pages/docs/index'))
const Overview = lazy(() => import('./pages/docs/introduction/overview/page'))
const QuickStart = lazy(() => import('./pages/docs/introduction/quick-start/page'))
const Limitations = lazy(() => import('./pages/docs/introduction/limitations/page'))
// Features
const CustomTools = lazy(() => import('./pages/docs/features/custom-tools/page'))
const DataMasking = lazy(() => import('./pages/docs/features/data-masking/page'))
const Instructions = lazy(() => import('./pages/docs/features/custom-instructions/page'))
const Models = lazy(() => import('./pages/docs/features/models/page'))
// Integration
const CdnSetup = lazy(() => import('./pages/docs/integration/cdn-setup/page'))
const SecurityPermissions = lazy(() => import('./pages/docs/integration/security-permissions/page'))
const Configuration = lazy(() => import('./pages/docs/integration/configuration/page'))
const BestPractices = lazy(() => import('./pages/docs/integration/best-practices/page'))
const ThirdPartyAgent = lazy(() => import('./pages/docs/integration/third-party-agent/page'))
function DocsPage({ children }: { children: React.ReactNode }) {
return (
<div className="min-h-screen bg-white dark:bg-gray-900">
<Header />
<DocsLayout>
<Suspense>{children}</Suspense>
</DocsLayout>
</div>
)
}
export default function Router() { export default function Router() {
return ( return (
@@ -42,70 +14,9 @@ export default function Router() {
<HomePage /> <HomePage />
</Route> </Route>
{/* Introduction */} {/* All docs pages */}
<Route path="/docs/introduction/overview"> <Route path="/docs" nest>
<DocsPage> <DocsPages />
<Overview />
</DocsPage>
</Route>
<Route path="/docs/introduction/quick-start">
<DocsPage>
<QuickStart />
</DocsPage>
</Route>
<Route path="/docs/introduction/limitations">
<DocsPage>
<Limitations />
</DocsPage>
</Route>
{/* Features */}
<Route path="/docs/features/custom-tools">
<DocsPage>
<CustomTools />
</DocsPage>
</Route>
<Route path="/docs/features/data-masking">
<DocsPage>
<DataMasking />
</DocsPage>
</Route>
<Route path="/docs/features/custom-instructions">
<DocsPage>
<Instructions />
</DocsPage>
</Route>
<Route path="/docs/features/models">
<DocsPage>
<Models />
</DocsPage>
</Route>
{/* Integration */}
<Route path="/docs/integration/cdn-setup">
<DocsPage>
<CdnSetup />
</DocsPage>
</Route>
<Route path="/docs/integration/security-permissions">
<DocsPage>
<SecurityPermissions />
</DocsPage>
</Route>
<Route path="/docs/integration/configuration">
<DocsPage>
<Configuration />
</DocsPage>
</Route>
<Route path="/docs/integration/best-practices">
<DocsPage>
<BestPractices />
</DocsPage>
</Route>
<Route path="/docs/integration/third-party-agent">
<DocsPage>
<ThirdPartyAgent />
</DocsPage>
</Route> </Route>
{/* 404 */} {/* 404 */}
+26 -26
View File
@@ -1,29 +1,29 @@
{ {
"extends": "../../tsconfig.base.json", "extends": "../../tsconfig.base.json",
"compilerOptions": { "compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.tsbuildinfo", "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.tsbuildinfo",
"noEmit": false, "noEmit": false,
"allowImportingTsExtensions": false, "allowImportingTsExtensions": false,
"baseUrl": ".", "baseUrl": ".",
"outDir": "dist", "outDir": "dist",
"paths": { "paths": {
// Self root // Self root
"@/*": ["src/*"], "@/*": ["src/*"],
// Simplified monorepo solution (raw npm workspace with hoisting) // Simplified monorepo solution (raw npm workspace with hoisting)
"page-agent": ["../page-agent/src/PageAgent.ts"], "page-agent": ["../page-agent/src/PageAgent.ts"],
"@page-agent/llms": ["../llms/src/index.ts"], "@page-agent/llms": ["../llms/src/index.ts"],
"@page-agent/page-controller": ["../page-controller/src/PageController.ts"], "@page-agent/page-controller": ["../page-controller/src/PageController.ts"],
"@page-agent/ui": ["../ui/src/index.ts"] "@page-agent/ui": ["../ui/src/index.ts"]
} }
}, },
"include": ["**/*.ts", "**/*.tsx"], "include": ["**/*.ts", "**/*.tsx"],
"exclude": ["dist", "node_modules"], "exclude": ["dist", "node_modules"],
"references": [ "references": [
// //
{ "path": "../llms" }, { "path": "../llms" },
{ "path": "../page-agent" }, { "path": "../page-agent" },
{ "path": "../page-controller" }, { "path": "../page-controller" },
{ "path": "../ui" } { "path": "../ui" }
] ]
} }
+41 -41
View File
@@ -1,47 +1,47 @@
{ {
"compilerOptions": { "compilerOptions": {
"composite": true, "composite": true,
"target": "ES2024", "target": "ES2024",
"useDefineForClassFields": true, "useDefineForClassFields": true,
"lib": ["ES2024", "DOM", "DOM.Iterable"], "lib": ["ES2024", "DOM", "DOM.Iterable"],
"module": "ESNext", "module": "ESNext",
"skipLibCheck": true, "skipLibCheck": true,
"allowJs": true, "allowJs": true,
// "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.tsbuildinfo", // "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.tsbuildinfo",
// "baseUrl": "src", // "baseUrl": "src",
"baseUrl": ".", "baseUrl": ".",
"outDir": "dist", "outDir": "dist",
// "incremental": true, // "incremental": true,
/* Bundler mode */ /* Bundler mode */
"moduleResolution": "bundler", "moduleResolution": "bundler",
"verbatimModuleSyntax": false, "verbatimModuleSyntax": false,
"noEmit": true, "noEmit": true,
"jsx": "react-jsx", "jsx": "react-jsx",
"allowImportingTsExtensions": true, "allowImportingTsExtensions": true,
/* Linting */ /* Linting */
"strict": true, "strict": true,
"noUnusedLocals": false, "noUnusedLocals": false,
"noUnusedParameters": false, "noUnusedParameters": false,
"erasableSyntaxOnly": true, "erasableSyntaxOnly": true,
"noFallthroughCasesInSwitch": true, "noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true "noUncheckedSideEffectImports": true
// "paths": { // "paths": {
// // Simplified monorepo solution (raw npm workspace with hoisting) // // Simplified monorepo solution (raw npm workspace with hoisting)
// "@page-agent/page-controller": ["./packages/page-controller/src/PageController.ts"], // "@page-agent/page-controller": ["./packages/page-controller/src/PageController.ts"],
// "page-agent": ["./packages/page-agent/src/PageAgent.ts"] // "page-agent": ["./packages/page-agent/src/PageAgent.ts"]
// } // }
} }
// "references": [ // "references": [
// { "path": "./packages/page-controller" }, // { "path": "./packages/page-controller" },
// { "path": "./packages/page-agent" }, // { "path": "./packages/page-agent" },
// { "path": "./packages/website" } // { "path": "./packages/website" }
// ], // ],
// "include": ["packages/*/src/**/*.ts", "packages/*/src/**/*.tsx"], // "include": ["packages/*/src/**/*.ts", "packages/*/src/**/*.tsx"],
// "exclude": ["node_modules", "dist", "packages/*/dist"] // "exclude": ["node_modules", "dist", "packages/*/dist"]
// "files": ["env.d.ts"] // "files": ["env.d.ts"]
// "files": [] // "files": []
} }
+10 -10
View File
@@ -1,12 +1,12 @@
{ {
"extends": "./tsconfig.base.json", "extends": "./tsconfig.base.json",
"references": [ "references": [
{ "path": "./packages/page-controller" }, { "path": "./packages/page-controller" },
{ "path": "./packages/ui" }, { "path": "./packages/ui" },
{ "path": "./packages/llms" }, { "path": "./packages/llms" },
{ "path": "./packages/page-agent" }, { "path": "./packages/page-agent" },
{ "path": "./packages/website" } { "path": "./packages/website" }
], ],
"include": ["packages/*/src/**/*.ts", "packages/*/src/**/*.tsx"], "include": ["packages/*/src/**/*.ts", "packages/*/src/**/*.tsx"],
"exclude": ["node_modules", "dist", "packages/*/dist"] "exclude": ["node_modules", "dist", "packages/*/dist"]
} }