feat: add cdn packages for iife builds

This commit is contained in:
Simon
2026-01-13 20:52:41 +08:00
parent 8b1e91d665
commit 3b21c42cdb
9 changed files with 185 additions and 27 deletions

View File

@@ -9,6 +9,7 @@ This is a **monorepo** with npm workspaces:
Internal packages: Internal packages:
- **CDN** (`packages/cdn/`) - IIFE builds for script tag usage (npm: `@page-agent/cdn`)
- **LLMs** (`packages/llms/`) - LLM client with reflection-before-action mental model - **LLMs** (`packages/llms/`) - LLM client with reflection-before-action mental model
- **Page Controller** (`packages/page-controller/`) - DOM operations and visual feedback (SimulatorMask), independent of LLM - **Page Controller** (`packages/page-controller/`) - DOM operations and visual feedback (SimulatorMask), independent of LLM
- **UI** (`packages/ui/`) - Panel and i18n. Decoupled from PageAgent - **UI** (`packages/ui/`) - Panel and i18n. Decoupled from PageAgent
@@ -31,6 +32,7 @@ Simple monorepo solution: TypeScript references + Vite aliases. Update tsconfig
``` ```
packages/ packages/
├── page-agent/ # npm: "page-agent" ⭐ MAIN ├── page-agent/ # npm: "page-agent" ⭐ MAIN
├── cdn/ # npm: "@page-agent/cdn" (IIFE builds)
├── website/ # @page-agent/website (private) ├── website/ # @page-agent/website (private)
├── llms/ # @page-agent/llms ├── llms/ # @page-agent/llms
├── page-controller/ # @page-agent/page-controller ├── page-controller/ # @page-agent/page-controller
@@ -69,42 +71,43 @@ const pageInfo = await this.pageController.getPageInfo()
3. **LLM Processing**: AI returns action plans (page-agent) 3. **LLM Processing**: AI returns action plans (page-agent)
4. **Indexed Operations**: PageAgent calls PageController by element index 4. **Indexed Operations**: PageAgent calls PageController by element index
### CDN Auto-Injection ### CDN Builds (`packages/cdn/`)
Library auto-initializes via script tag: Two IIFE builds for script tag usage:
```html | Build | File | Description |
<script src="page-agent.js?model=gpt-4"></script> | ----- | -------------------- | -------------------------------- |
``` | Demo | `page-agent.demo.js` | Auto-init with built-in test API |
| Full | `page-agent.js` | Exposes `PageAgent` class only |
Query params configure `PageAgentConfig` in `src/umd.ts`. Demo build supports query params (e.g., `?model=gpt-4&lang=en-US`).
## Key Files Reference ## Key Files Reference
### Page Agent (`packages/page-agent/`) ### Page Agent (`packages/page-agent/`)
| File | Description | | File | Description |
|------|-------------| | ------------------ | --------------------------------------- |
| `src/PageAgent.ts` | ⭐ Main AI agent class | | `src/PageAgent.ts` | ⭐ Main AI agent class |
| `src/umd.ts` | CDN/UMD entry with auto-init | | `src/umd.ts` | CDN/UMD entry with auto-init |
| `src/tools/` | Tool definitions calling PageController | | `src/tools/` | Tool definitions calling PageController |
### LLMs (`packages/llms/`) ### LLMs (`packages/llms/`)
| File | Description | | File | Description |
|------|-------------| | ---------------------------- | ------------------------------------- |
| `src/index.ts` | ⭐ LLM class with retry logic | | `src/index.ts` | ⭐ LLM class with retry logic |
| `src/types.ts` | MacroToolInput, AgentBrain, LLMConfig | | `src/types.ts` | MacroToolInput, AgentBrain, LLMConfig |
| `src/OpenAILenientClient.ts` | OpenAI-compatible client | | `src/OpenAILenientClient.ts` | OpenAI-compatible client |
### Page Controller (`packages/page-controller/`) ### Page Controller (`packages/page-controller/`)
| File | Description | | File | Description |
|------|-------------| | --------------------------- | ---------------------------------------------------------- |
| `src/PageController.ts` | ⭐ Main controller class with optional mask support | | `src/PageController.ts` | ⭐ Main controller class with optional mask support |
| `src/SimulatorMask.ts` | Visual overlay blocking user interaction during automation | | `src/SimulatorMask.ts` | Visual overlay blocking user interaction during automation |
| `src/actions.ts` | Element interactions (click, input, scroll) | | `src/actions.ts` | Element interactions (click, input, scroll) |
| `src/dom/dom_tree/index.js` | Core DOM extraction engine | | `src/dom/dom_tree/index.js` | Core DOM extraction engine |
## Adding New Features ## Adding New Features

View File

@@ -81,6 +81,7 @@ packages/
├── llms/ # LLM 客户端 (npm: @page-agent/llms) ├── llms/ # LLM 客户端 (npm: @page-agent/llms)
├── page-controller/ # DOM 操作 & 蒙层 & 模拟鼠标 (npm: @page-agent/page-controller) ├── page-controller/ # DOM 操作 & 蒙层 & 模拟鼠标 (npm: @page-agent/page-controller)
├── ui/ # 面板 & i18n (npm: @page-agent/ui) ├── ui/ # 面板 & i18n (npm: @page-agent/ui)
├── cdn/ # CDN IIFE builds (npm: @page-agent/cdn)
└── website/ # 文档站点 └── website/ # 文档站点
``` ```

View File

@@ -81,6 +81,7 @@ packages/
├── llms/ # LLM client (npm: @page-agent/llms) ├── llms/ # LLM client (npm: @page-agent/llms)
├── page-controller/ # DOM operations & Visual Mask (npm: @page-agent/page-controller) ├── page-controller/ # DOM operations & Visual Mask (npm: @page-agent/page-controller)
├── ui/ # Panel & i18n (npm: @page-agent/ui) ├── ui/ # Panel & i18n (npm: @page-agent/ui)
├── cdn/ # CDN IIFE builds (npm: @page-agent/cdn)
└── website/ # Demo & Documentation site └── website/ # Demo & Documentation site
``` ```

23
package-lock.json generated
View File

@@ -13,6 +13,7 @@
"packages/ui", "packages/ui",
"packages/llms", "packages/llms",
"packages/page-agent", "packages/page-agent",
"packages/cdn",
"packages/website" "packages/website"
], ],
"devDependencies": { "devDependencies": {
@@ -1597,6 +1598,10 @@
"url": "https://github.com/sponsors/epoberezkin" "url": "https://github.com/sponsors/epoberezkin"
} }
}, },
"node_modules/@page-agent/cdn": {
"resolved": "packages/cdn",
"link": true
},
"node_modules/@page-agent/llms": { "node_modules/@page-agent/llms": {
"resolved": "packages/llms", "resolved": "packages/llms",
"link": true "link": true
@@ -8140,6 +8145,14 @@
"zod": "^3.25.0 || ^4.0.0" "zod": "^3.25.0 || ^4.0.0"
} }
}, },
"packages/cdn": {
"name": "@page-agent/cdn",
"version": "0.0.21",
"license": "MIT",
"dependencies": {
"page-agent": "0.0.21"
}
},
"packages/llms": { "packages/llms": {
"name": "@page-agent/llms", "name": "@page-agent/llms",
"version": "0.0.21", "version": "0.0.21",
@@ -8163,16 +8176,16 @@
"packages/page-controller": { "packages/page-controller": {
"name": "@page-agent/page-controller", "name": "@page-agent/page-controller",
"version": "0.0.21", "version": "0.0.21",
"license": "MIT"
},
"packages/ui": {
"name": "@page-agent/ui",
"version": "0.0.21",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"ai-motion": "^0.4.8" "ai-motion": "^0.4.8"
} }
}, },
"packages/ui": {
"name": "@page-agent/ui",
"version": "0.0.21",
"license": "MIT"
},
"packages/website": { "packages/website": {
"name": "@page-agent/website", "name": "@page-agent/website",
"version": "0.0.21", "version": "0.0.21",

View File

@@ -8,6 +8,7 @@
"packages/ui", "packages/ui",
"packages/llms", "packages/llms",
"packages/page-agent", "packages/page-agent",
"packages/cdn",
"packages/website" "packages/website"
], ],
"description": "AI-powered UI agent for web applications", "description": "AI-powered UI agent for web applications",

23
packages/cdn/package.json Normal file
View File

@@ -0,0 +1,23 @@
{
"name": "@page-agent/cdn",
"private": false,
"version": "0.0.21",
"type": "module",
"files": [
"dist/"
],
"description": "CDN builds for page-agent - IIFE bundles for script tag usage",
"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 && vite build --mode demo"
},
"dependencies": {
"page-agent": "0.0.21"
}
}

59
packages/cdn/src/demo.js Normal file
View File

@@ -0,0 +1,59 @@
// @ts-nocheck
/**
* Demo CDN build for page-agent
* Auto-initializes with built-in demo API for testing
*
* Usage:
* <script src="https://unpkg.com/@page-agent/cdn/dist/page-agent.demo.js"></script>
*/
import { PageAgent } from 'page-agent'
// Clean up existing instances to prevent multiple injections from bookmarklet
if (window.pageAgent) {
window.pageAgent.dispose()
}
// Mount to global window object
window.PageAgent = PageAgent
// Export for IIFE
export { PageAgent }
console.log('🚀 page-agent.js loaded!')
const DEMO_MODEL = 'PAGE-AGENT-FREE-TESTING-RANDOM'
const DEMO_BASE_URL = 'https://hwcxiuzfylggtcktqgij.supabase.co/functions/v1/llm-testing-proxy'
const DEMO_API_KEY = 'PAGE-AGENT-FREE-TESTING-RANDOM'
// Demo warning
console.log(
'%c⚠ DEMO MODE %c\n' +
'This build uses a shared testing LLM with rate limits.\n' +
'For production, use page-agent.js with your own API key:\n' +
'https://alibaba.github.io/page-agent/#/docs/features/models',
'background: #f59e0b; color: #000; font-size: 14px; font-weight: bold; padding: 4px 8px; border-radius: 4px;',
'color: #f59e0b; font-size: 12px;'
)
// in case document.x is not ready yet
setTimeout(() => {
const currentScript = document.currentScript
if (currentScript) {
console.log('🚀 page-agent.js detected current script:', currentScript.src)
const url = new URL(currentScript.src)
const model = url.searchParams.get('model') || DEMO_MODEL
const baseURL = url.searchParams.get('baseURL') || DEMO_BASE_URL
const apiKey = url.searchParams.get('apiKey') || DEMO_API_KEY
const language = url.searchParams.get('lang') || 'zh-CN'
const config = { model, baseURL, apiKey, language }
window.pageAgent = new PageAgent(config)
} else {
console.log('🚀 page-agent.js no current script detected, using default demo config')
window.pageAgent = new PageAgent()
}
console.log('🚀 page-agent.js initialized with config:', window.pageAgent.config)
window.pageAgent.panel.show()
})

15
packages/cdn/src/full.js Normal file
View File

@@ -0,0 +1,15 @@
// @ts-nocheck
/**
* Full CDN build for page-agent
* Exposes PageAgent class for manual instantiation and configuration
*
* Usage:
* <script src="https://unpkg.com/@page-agent/cdn/dist/page-agent.js"></script>
* <script>
* const agent = new PageAgent({ model: 'gpt-4o', apiKey: 'your-key' })
* agent.panel.show()
* </script>
*/
import { PageAgent } from 'page-agent'
export { PageAgent }

View File

@@ -0,0 +1,42 @@
// @ts-nocheck
import { dirname, resolve } from 'path'
import { fileURLToPath } from 'url'
import { defineConfig } from 'vite'
import cssInjectedByJsPlugin from 'vite-plugin-css-injected-by-js'
const __dirname = dirname(fileURLToPath(import.meta.url))
/**
* CDN IIFE builds for page-agent
*
* Build targets (via --mode):
* - demo: page-agent.demo.js with auto-init and built-in API
* - full (default): page-agent.js exposes PageAgent class only
*/
export default defineConfig(({ mode }) => {
const isDemo = mode === 'demo'
const entry = isDemo ? resolve(__dirname, 'src/demo.js') : resolve(__dirname, 'src/full.js')
const fileName = isDemo ? 'page-agent.demo' : 'page-agent'
return {
plugins: [cssInjectedByJsPlugin({ relativeCSSInjection: true })],
publicDir: false,
esbuild: {
keepNames: true,
},
build: {
lib: {
entry,
name: 'PageAgent',
fileName: () => `${fileName}.js`,
formats: ['iife'],
},
outDir: resolve(__dirname, 'dist'),
emptyOutDir: !isDemo, // only empty on first build (full)
minify: false,
},
define: {
'process.env.NODE_ENV': '"production"',
},
}
})