feat: i18n for website
This commit is contained in:
25
index.html
25
index.html
@@ -8,25 +8,38 @@
|
||||
href="https://img.alicdn.com/imgextra/i3/O1CN01uo9VaC20mamWNM2Zn_!!6000000006892-55-tps-64-64.svg"
|
||||
/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>PageAgent - 网页内的交互助手</title>
|
||||
<title>PageAgent - AI-powered UI Agent in Your Webpage</title>
|
||||
<meta
|
||||
name="description"
|
||||
content="PageAgent.js:一行 CDN 引入,为任何网站添加智能 UI Agent。现代网页 AI 自动化,极简集成,开发者专用。"
|
||||
content="PageAgent.js: One-line CDN import, add intelligent UI Agent to any website. Modern web AI automation with minimal integration."
|
||||
/>
|
||||
<meta
|
||||
name="keywords"
|
||||
content="PageAgent, AI Agent, Web Automation, UI 自动化, 前端, CDN, JavaScript, React, Vite"
|
||||
content="PageAgent, AI Agent, Web Automation, UI Automation, Frontend, CDN, JavaScript, React, Vite, LLM"
|
||||
/>
|
||||
<meta name="theme-color" content="#58c0fc" />
|
||||
<meta name="color-scheme" content="light dark" />
|
||||
<meta name="author" content="PageAgent.js Team" />
|
||||
<meta property="og:title" content="PageAgent.js" />
|
||||
<meta property="og:description" content="一行 CDN 引入,为任何网站添加智能 UI Agent。" />
|
||||
<meta property="og:title" content="PageAgent.js - AI-powered UI Agent" />
|
||||
<meta
|
||||
property="og:description"
|
||||
content="One-line CDN import, add intelligent UI Agent to any website."
|
||||
/>
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:locale" content="zh_CN" />
|
||||
<meta property="og:locale" content="en_US" />
|
||||
<meta property="og:locale:alternate" content="zh_CN" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="./pages/main.tsx"></script>
|
||||
<script>
|
||||
// Dynamically update html lang attribute based on i18n detection
|
||||
const updateHtmlLang = () => {
|
||||
const lang = localStorage.getItem('i18nextLng') || navigator.language || 'zh-CN'
|
||||
document.documentElement.lang = lang
|
||||
}
|
||||
updateHtmlLang()
|
||||
window.addEventListener('storage', updateHtmlLang)
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
102
package-lock.json
generated
102
package-lock.json
generated
@@ -32,10 +32,13 @@
|
||||
"eslint-plugin-react-x": "^2.0.6",
|
||||
"globals": "^16.4.0",
|
||||
"husky": "^9.1.7",
|
||||
"i18next": "^25.6.0",
|
||||
"i18next-browser-languagedetector": "^8.2.0",
|
||||
"lint-staged": "^16.2.4",
|
||||
"prettier": "^3.6.2",
|
||||
"react": "^19.2.0",
|
||||
"react-dom": "^19.2.0",
|
||||
"react-i18next": "^16.1.4",
|
||||
"tailwindcss": "^4.1.14",
|
||||
"typescript": "^5.9.3",
|
||||
"typescript-eslint": "^8.46.0",
|
||||
@@ -277,6 +280,16 @@
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/runtime": {
|
||||
"version": "7.28.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz",
|
||||
"integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/template": {
|
||||
"version": "7.27.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz",
|
||||
@@ -4553,6 +4566,16 @@
|
||||
"hermes-estree": "0.25.1"
|
||||
}
|
||||
},
|
||||
"node_modules/html-parse-stringify": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz",
|
||||
"integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"void-elements": "3.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/husky": {
|
||||
"version": "9.1.7",
|
||||
"resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz",
|
||||
@@ -4569,6 +4592,48 @@
|
||||
"url": "https://github.com/sponsors/typicode"
|
||||
}
|
||||
},
|
||||
"node_modules/i18next": {
|
||||
"version": "25.6.0",
|
||||
"resolved": "https://registry.npmjs.org/i18next/-/i18next-25.6.0.tgz",
|
||||
"integrity": "sha512-tTn8fLrwBYtnclpL5aPXK/tAYBLWVvoHM1zdfXoRNLcI+RvtMsoZRV98ePlaW3khHYKuNh/Q65W/+NVFUeIwVw==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://locize.com"
|
||||
},
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://locize.com/i18next.html"
|
||||
},
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.27.6"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "^5"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"typescript": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/i18next-browser-languagedetector": {
|
||||
"version": "8.2.0",
|
||||
"resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-8.2.0.tgz",
|
||||
"integrity": "sha512-P+3zEKLnOF0qmiesW383vsLdtQVyKtCNA9cjSoKCppTKPQVfKd2W8hbVo5ZhNJKDqeM7BOcvNoKJOjpHh4Js9g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.23.2"
|
||||
}
|
||||
},
|
||||
"node_modules/ignore": {
|
||||
"version": "5.3.2",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
|
||||
@@ -5874,6 +5939,33 @@
|
||||
"react": "^19.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-i18next": {
|
||||
"version": "16.1.4",
|
||||
"resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-16.1.4.tgz",
|
||||
"integrity": "sha512-0UUKZDHjKnLk6dfbYXEZ9CVqLMpNiul+dHbPVQo2z2t1GkdirkeHXb/TtdsNuv+nyNOTDl1Jp6F6uwf9M3DMcg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.27.6",
|
||||
"html-parse-stringify": "^3.0.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"i18next": ">= 25.5.2",
|
||||
"react": ">= 16.8.0",
|
||||
"typescript": "^5"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"react-dom": {
|
||||
"optional": true
|
||||
},
|
||||
"react-native": {
|
||||
"optional": true
|
||||
},
|
||||
"typescript": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/regexparam": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/regexparam/-/regexparam-3.0.0.tgz",
|
||||
@@ -6738,6 +6830,16 @@
|
||||
"url": "https://github.com/sponsors/jonschlinkert"
|
||||
}
|
||||
},
|
||||
"node_modules/void-elements": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz",
|
||||
"integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-uri": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.1.0.tgz",
|
||||
|
||||
@@ -74,10 +74,13 @@
|
||||
"eslint-plugin-react-x": "^2.0.6",
|
||||
"globals": "^16.4.0",
|
||||
"husky": "^9.1.7",
|
||||
"i18next": "^25.6.0",
|
||||
"i18next-browser-languagedetector": "^8.2.0",
|
||||
"lint-staged": "^16.2.4",
|
||||
"prettier": "^3.6.2",
|
||||
"react": "^19.2.0",
|
||||
"react-dom": "^19.2.0",
|
||||
"react-i18next": "^16.1.4",
|
||||
"tailwindcss": "^4.1.14",
|
||||
"typescript": "^5.9.3",
|
||||
"typescript-eslint": "^8.46.0",
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
export default function BetaNotice() {
|
||||
const { t } = useTranslation('common')
|
||||
|
||||
return (
|
||||
<div className="bg-orange-50 dark:bg-orange-900/20 border border-orange-200 dark:border-orange-800 rounded-lg p-4 mb-8">
|
||||
<div className="flex items-start">
|
||||
@@ -7,11 +11,9 @@ export default function BetaNotice() {
|
||||
</div>
|
||||
<div className="ml-3">
|
||||
<h3 className="text-sm font-medium text-orange-800 dark:text-orange-200 mb-1">
|
||||
Beta 阶段
|
||||
{t('beta_notice.title')}
|
||||
</h3>
|
||||
<p className="text-sm text-orange-700 dark:text-orange-300">
|
||||
当前功能未完成,接口可能随时变更。正式版本发布前请勿用于生产环境。
|
||||
</p>
|
||||
<p className="text-sm text-orange-700 dark:text-orange-300">{t('beta_notice.content')}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { ReactNode } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Link, useLocation } from 'wouter'
|
||||
|
||||
interface DocsLayoutProps {
|
||||
@@ -15,39 +16,40 @@ interface NavSection {
|
||||
items: NavItem[]
|
||||
}
|
||||
|
||||
export default function DocsLayout({ children }: DocsLayoutProps) {
|
||||
const { t } = useTranslation('common')
|
||||
const [location] = useLocation()
|
||||
|
||||
const navigationSections: NavSection[] = [
|
||||
{
|
||||
title: 'Introduction',
|
||||
title: t('nav.introduction'),
|
||||
items: [
|
||||
{ title: 'Overview', path: '/docs/introduction/overview' },
|
||||
{ title: 'Quick Start', path: '/docs/introduction/quick-start' },
|
||||
{ title: '使用限制', path: '/docs/introduction/limitations' },
|
||||
{ title: t('nav.overview'), path: '/docs/introduction/overview' },
|
||||
{ title: t('nav.quick_start'), path: '/docs/introduction/quick-start' },
|
||||
{ title: t('nav.limitations'), path: '/docs/introduction/limitations' },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Features',
|
||||
title: t('nav.features'),
|
||||
items: [
|
||||
{ title: '模型接入', path: '/docs/features/model-integration' },
|
||||
{ title: '自定义工具', path: '/docs/features/custom-tools' },
|
||||
{ title: '知识库注入', path: '/docs/features/knowledge-injection' },
|
||||
{ title: '安全与权限', path: '/docs/features/security-permissions' },
|
||||
{ title: '数据脱敏', path: '/docs/features/data-masking' },
|
||||
{ title: t('nav.model_integration'), path: '/docs/features/model-integration' },
|
||||
{ title: t('nav.custom_tools'), path: '/docs/features/custom-tools' },
|
||||
{ title: t('nav.knowledge_injection'), path: '/docs/features/knowledge-injection' },
|
||||
{ title: t('nav.security_permissions'), path: '/docs/features/security-permissions' },
|
||||
{ title: t('nav.data_masking'), path: '/docs/features/data-masking' },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Integration',
|
||||
title: t('nav.integration'),
|
||||
items: [
|
||||
{ title: 'CDN 引入', path: '/docs/integration/cdn-setup' },
|
||||
{ title: '配置选项', path: '/docs/integration/configuration' },
|
||||
{ title: '最佳实践', path: '/docs/integration/best-practices' },
|
||||
{ title: '接入第三方 Agent', path: '/docs/integration/third-party-agent' },
|
||||
{ title: t('nav.cdn_setup'), path: '/docs/integration/cdn-setup' },
|
||||
{ title: t('nav.configuration'), path: '/docs/integration/configuration' },
|
||||
{ title: t('nav.best_practices'), path: '/docs/integration/best-practices' },
|
||||
{ title: t('nav.third_party_agent'), path: '/docs/integration/third-party-agent' },
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
export default function DocsLayout({ children }: DocsLayoutProps) {
|
||||
const [location] = useLocation()
|
||||
|
||||
return (
|
||||
<div className="max-w-7xl mx-auto px-6 py-8">
|
||||
<div className="flex gap-8">
|
||||
@@ -57,7 +59,9 @@ export default function DocsLayout({ children }: DocsLayoutProps) {
|
||||
<nav className="space-y-8" role="navigation" aria-label="文档章节">
|
||||
{navigationSections.map((section) => (
|
||||
<section key={section.title}>
|
||||
<h3 className="font-semibold uppercase tracking-wider mb-3">{section.title}</h3>
|
||||
<h3 className="font-semibold text-gray-600 dark:text-gray-400 uppercase tracking-wider mb-3">
|
||||
{section.title}
|
||||
</h3>
|
||||
<ul className="space-y-2" role="list">
|
||||
{section.items.map((item) => {
|
||||
const isActive = location === item.path
|
||||
@@ -68,7 +72,7 @@ export default function DocsLayout({ children }: DocsLayoutProps) {
|
||||
className={`block px-3 py-2 rounded-lg transition-colors duration-200 ${
|
||||
isActive
|
||||
? 'bg-blue-100 dark:bg-blue-900/30 text-blue-700 dark:text-blue-300 font-medium'
|
||||
: ' hover:text-foreground hover:bg-gray-100 dark:hover:bg-gray-800'
|
||||
: 'text-gray-600 dark:text-gray-300 hover:text-gray-900 dark:hover:text-white hover:bg-gray-100 dark:hover:bg-gray-800'
|
||||
}`}
|
||||
aria-current={isActive ? 'page' : undefined}
|
||||
>
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
export default function Footer() {
|
||||
const { t } = useTranslation('common')
|
||||
|
||||
return (
|
||||
<footer
|
||||
className="bg-gray-50 dark:bg-gray-900 border-t border-gray-200 dark:border-gray-700"
|
||||
@@ -6,14 +10,14 @@ export default function Footer() {
|
||||
>
|
||||
<div className="max-w-7xl mx-auto px-6 py-6">
|
||||
<div className="flex flex-col md:flex-row justify-between items-center space-y-4 md:space-y-0">
|
||||
<p className="text-foreground/80 text-sm">© 2025 page-agent. All rights reserved.</p>
|
||||
<p className="text-gray-600 dark:text-gray-300 text-sm">{t('footer.copyright')}</p>
|
||||
<div className="flex items-center space-x-6">
|
||||
<a
|
||||
href="https://github.com/alibaba/page-agent"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-foreground/80 hover:text-foreground transition-colors duration-200"
|
||||
aria-label="访问 GitHub 仓库"
|
||||
className="text-gray-600 dark:text-gray-300 hover:text-gray-900 dark:hover:text-white transition-colors duration-200"
|
||||
aria-label={t('footer.github_label')}
|
||||
>
|
||||
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z" />
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Link } from 'wouter'
|
||||
|
||||
import LanguageSwitcher from './LanguageSwitcher'
|
||||
import ThemeSwitcher from './ThemeSwitcher'
|
||||
|
||||
export default function Header() {
|
||||
const { t } = useTranslation('common')
|
||||
return (
|
||||
<>
|
||||
<header
|
||||
className="relative z-50 bg-white/80 dark:bg-gray-900/80 backdrop-blur-md border-b border-gray-200 dark:border-gray-700"
|
||||
role="banner"
|
||||
@@ -9,46 +15,69 @@ export default function Header() {
|
||||
<div className="max-w-7xl mx-auto px-6 py-4">
|
||||
<div className="flex items-center justify-between">
|
||||
{/* Logo */}
|
||||
<Link href="/" className="flex items-center space-x-3 group" aria-label="page-agent 首页">
|
||||
<Link
|
||||
href="/"
|
||||
className="flex items-center space-x-3 group"
|
||||
aria-label={t('header.logo_alt')}
|
||||
>
|
||||
<div className="w-10 h-10 bg-gradient-to-br from-blue-500 to-purple-600 rounded-xl flex items-center justify-center group-hover:scale-110 transition-transform duration-200">
|
||||
<span className="text-white font-bold text-2xl lg:text-2xl" aria-hidden="true">
|
||||
P
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<span className="text-xl font-bold text-foreground">page-agent</span>
|
||||
<p className="text-xs text-foreground/80">UI Agent in your webpage</p>
|
||||
<span className="text-xl font-bold text-gray-900 dark:text-white">page-agent</span>
|
||||
<p className="text-xs text-gray-600 dark:text-gray-300">{t('header.slogan')}</p>
|
||||
</div>
|
||||
</Link>
|
||||
|
||||
{/* Navigation */}
|
||||
<nav
|
||||
className="hidden md:flex items-center space-x-8"
|
||||
className="hidden md:flex items-center space-x-6"
|
||||
role="navigation"
|
||||
aria-label="主导航"
|
||||
aria-label={t('header.nav_docs')}
|
||||
>
|
||||
<Link
|
||||
href="/docs/introduction/overview"
|
||||
className="text-foreground/80 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"
|
||||
>
|
||||
文档
|
||||
<svg
|
||||
className="w-4 h-4"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253"
|
||||
/>
|
||||
</svg>
|
||||
{t('header.nav_docs')}
|
||||
</Link>
|
||||
<a
|
||||
href="https://github.com/alibaba/page-agent"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-foreground/80 hover:text-blue-600 dark:hover:text-blue-400 transition-colors duration-200"
|
||||
aria-label="查看源码(在新窗口打开)"
|
||||
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"
|
||||
aria-label={t('header.nav_source')}
|
||||
>
|
||||
源码
|
||||
<svg className="w-4 h-4" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z" />
|
||||
</svg>
|
||||
{t('header.nav_source')}
|
||||
</a>
|
||||
<ThemeSwitcher />
|
||||
<LanguageSwitcher />
|
||||
</nav>
|
||||
|
||||
{/* Mobile menu button */}
|
||||
<button
|
||||
type="button"
|
||||
className="md:hidden p-2 rounded-lg text-foreground/80 hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors duration-200"
|
||||
aria-label="打开移动端菜单"
|
||||
className="md:hidden p-2 rounded-lg text-gray-600 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors duration-200"
|
||||
aria-label={t('header.mobile_menu')}
|
||||
aria-expanded="false"
|
||||
aria-controls="mobile-menu"
|
||||
>
|
||||
@@ -70,5 +99,6 @@ export default function Header() {
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3,19 +3,43 @@
|
||||
word-break: break-word;
|
||||
overflow-wrap: break-word;
|
||||
font-family: monospace;
|
||||
color: #171717;
|
||||
}
|
||||
|
||||
:global(.dark) .syntax {
|
||||
color: #e0e0e0;
|
||||
}
|
||||
|
||||
.keyword {
|
||||
color: #d73a49;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
:global(.dark) .keyword {
|
||||
color: #ff6b6b;
|
||||
}
|
||||
|
||||
.string {
|
||||
color: #1d6eca;
|
||||
}
|
||||
|
||||
:global(.dark) .string {
|
||||
color: #4fc3f7;
|
||||
}
|
||||
|
||||
.number {
|
||||
color: #00c583;
|
||||
}
|
||||
|
||||
:global(.dark) .number {
|
||||
color: #66bb6a;
|
||||
}
|
||||
|
||||
.comment {
|
||||
color: #6a737d;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
:global(.dark) .comment {
|
||||
color: #9e9e9e;
|
||||
}
|
||||
|
||||
@@ -46,19 +46,19 @@ function highlightSyntax(code: string): string {
|
||||
/^'([^'\\]|\\.)*'$/.test(token) ||
|
||||
/^`([^`\\]|\\.)*`$/.test(token)
|
||||
) {
|
||||
return `<span style="color: #1d6eca;">${token}</span>`
|
||||
return `<span class="${styles.string}">${token}</span>`
|
||||
}
|
||||
if (/^\b\d+\.?\d*\b$/.test(token)) {
|
||||
return `<span style="color: #00c583;">${token}</span>`
|
||||
return `<span class="${styles.number}">${token}</span>`
|
||||
}
|
||||
if (/^\/\/.*$/.test(token)) {
|
||||
return `<span style="color: #6a737d; font-style: italic;">${token}</span>`
|
||||
return `<span class="${styles.comment}">${token}</span>`
|
||||
}
|
||||
if (/^\/\*[\s\S]*?\*\/$/.test(token)) {
|
||||
return `<span style="color: #6a737d; font-style: italic;">${token}</span>`
|
||||
return `<span class="${styles.comment}">${token}</span>`
|
||||
}
|
||||
if (new RegExp(`\\b(?:${keywords})\\b`).test(token)) {
|
||||
return `<span style="color: #d73a49; font-weight: 600;">${token}</span>`
|
||||
return `<span class="${styles.keyword}">${token}</span>`
|
||||
}
|
||||
return token
|
||||
})
|
||||
|
||||
115
pages/components/LanguageSwitcher.tsx
Normal file
115
pages/components/LanguageSwitcher.tsx
Normal file
@@ -0,0 +1,115 @@
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
export default function LanguageSwitcher() {
|
||||
const { i18n, t } = useTranslation('common')
|
||||
const [isOpen, setIsOpen] = useState(false)
|
||||
const dropdownRef = useRef<HTMLDivElement>(null)
|
||||
|
||||
const currentLang = i18n.language
|
||||
|
||||
const languages = [
|
||||
{ code: 'zh-CN', label: '中文' },
|
||||
{ code: 'en-US', label: 'English' },
|
||||
]
|
||||
|
||||
const currentLanguage = languages.find((lang) => lang.code === currentLang) || languages[0]
|
||||
|
||||
const handleLanguageChange = (langCode: string) => {
|
||||
i18n.changeLanguage(langCode)
|
||||
setIsOpen(false)
|
||||
}
|
||||
|
||||
// Close dropdown when clicking outside
|
||||
useEffect(() => {
|
||||
const handleClickOutside = (event: MouseEvent) => {
|
||||
if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {
|
||||
setIsOpen(false)
|
||||
}
|
||||
}
|
||||
|
||||
if (isOpen) {
|
||||
document.addEventListener('mousedown', handleClickOutside)
|
||||
}
|
||||
|
||||
return () => {
|
||||
document.removeEventListener('mousedown', handleClickOutside)
|
||||
}
|
||||
}, [isOpen])
|
||||
|
||||
return (
|
||||
<div className="relative" ref={dropdownRef}>
|
||||
<button
|
||||
onClick={() => setIsOpen(!isOpen)}
|
||||
className="flex items-center gap-2 px-3 py-1.5 rounded-lg bg-gray-100 dark:bg-gray-800 hover:bg-gray-200 dark:hover:bg-gray-700 transition-colors text-sm font-medium border border-gray-200 dark:border-gray-700 text-gray-700 dark:text-gray-300"
|
||||
aria-label={t('language.switch_label')}
|
||||
aria-expanded={isOpen}
|
||||
aria-haspopup="true"
|
||||
>
|
||||
<svg
|
||||
className="w-4 h-4"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M3 5h12M9 3v2m1.048 9.5A18.022 18.022 0 016.412 9m6.088 9h7M11 21l5-10 5 10M12.751 5C11.783 10.77 8.07 15.61 3 18.129"
|
||||
/>
|
||||
</svg>
|
||||
<span>{currentLanguage.label}</span>
|
||||
<svg
|
||||
className={`w-4 h-4 transition-transform duration-200 ${isOpen ? 'rotate-180' : ''}`}
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
{isOpen && (
|
||||
<div
|
||||
className="absolute right-0 mt-2 w-40 bg-white dark:bg-gray-800 rounded-lg shadow-lg border border-gray-200 dark:border-gray-700 py-1 z-50"
|
||||
role="menu"
|
||||
aria-orientation="vertical"
|
||||
>
|
||||
{languages.map((lang) => (
|
||||
<button
|
||||
key={lang.code}
|
||||
onClick={() => handleLanguageChange(lang.code)}
|
||||
className={`w-full flex items-center gap-2 px-4 py-2 text-sm text-left hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors ${
|
||||
currentLang === lang.code
|
||||
? 'bg-blue-50 dark:bg-blue-900/20 text-blue-700 dark:text-blue-300'
|
||||
: 'text-gray-700 dark:text-gray-300'
|
||||
}`}
|
||||
role="menuitem"
|
||||
>
|
||||
<span>{lang.label}</span>
|
||||
{currentLang === lang.code && (
|
||||
<svg
|
||||
className="w-4 h-4 ml-auto"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M5 13l4 4L19 7"
|
||||
/>
|
||||
</svg>
|
||||
)}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
133
pages/components/ThemeSwitcher.tsx
Normal file
133
pages/components/ThemeSwitcher.tsx
Normal file
@@ -0,0 +1,133 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
type Theme = 'light' | 'dark'
|
||||
|
||||
export default function ThemeSwitcher() {
|
||||
const [theme, setTheme] = useState<Theme>(() => {
|
||||
// 初始化时读取保存的主题
|
||||
if (typeof window !== 'undefined') {
|
||||
const savedTheme = localStorage.getItem('theme') as Theme | null
|
||||
if (savedTheme === 'light' || savedTheme === 'dark') {
|
||||
return savedTheme
|
||||
}
|
||||
// 默认跟随系统
|
||||
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
|
||||
}
|
||||
return 'light'
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
// 应用主题
|
||||
if (theme === 'dark') {
|
||||
document.documentElement.classList.add('dark')
|
||||
document.documentElement.style.colorScheme = 'dark'
|
||||
} else {
|
||||
document.documentElement.classList.remove('dark')
|
||||
document.documentElement.style.colorScheme = 'light'
|
||||
}
|
||||
// 保存到 localStorage
|
||||
localStorage.setItem('theme', theme)
|
||||
}, [theme])
|
||||
|
||||
// 监听系统主题变化
|
||||
useEffect(() => {
|
||||
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)')
|
||||
|
||||
const handleSystemThemeChange = (e: MediaQueryListEvent) => {
|
||||
// 只有在用户未手动设置时才自动跟随系统
|
||||
const savedTheme = localStorage.getItem('theme')
|
||||
if (!savedTheme) {
|
||||
setTheme(e.matches ? 'dark' : 'light')
|
||||
}
|
||||
}
|
||||
|
||||
mediaQuery.addEventListener('change', handleSystemThemeChange)
|
||||
return () => mediaQuery.removeEventListener('change', handleSystemThemeChange)
|
||||
}, [])
|
||||
|
||||
const toggleTheme = () => {
|
||||
setTheme((prev) => (prev === 'light' ? 'dark' : 'light'))
|
||||
}
|
||||
|
||||
return (
|
||||
<button
|
||||
onClick={toggleTheme}
|
||||
className="relative inline-flex items-center h-8 w-16 rounded-full transition-colors duration-300 ease-in-out focus:outline-none"
|
||||
style={{
|
||||
backgroundColor: theme === 'dark' ? '#1e293b' : '#e0f2fe',
|
||||
}}
|
||||
aria-label={theme === 'light' ? '切换到深色模式' : '切换到浅色模式'}
|
||||
role="switch"
|
||||
aria-checked={theme === 'dark'}
|
||||
>
|
||||
{/* 滑块 */}
|
||||
<span
|
||||
className="inline-block h-6 w-6 transform rounded-full transition-all duration-300 ease-in-out shadow-md"
|
||||
style={{
|
||||
backgroundColor: theme === 'dark' ? '#475569' : '#fbbf24',
|
||||
transform: theme === 'dark' ? 'translateX(2.25rem)' : 'translateX(0.25rem)',
|
||||
}}
|
||||
>
|
||||
{/* 图标 */}
|
||||
<span className="flex items-center justify-center h-full w-full">
|
||||
{theme === 'light' ? (
|
||||
// 太阳图标
|
||||
<svg
|
||||
className="w-4 h-4 text-white"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 20 20"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
) : (
|
||||
// 月亮图标
|
||||
<svg
|
||||
className="w-4 h-4 text-slate-200"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 20 20"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path d="M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z" />
|
||||
</svg>
|
||||
)}
|
||||
</span>
|
||||
</span>
|
||||
|
||||
{/* 背景装饰 */}
|
||||
<span
|
||||
className="absolute inset-0 flex items-center justify-between px-2 pointer-events-none"
|
||||
aria-hidden="true"
|
||||
>
|
||||
{/* 左侧太阳(浅色模式时显示) */}
|
||||
<span
|
||||
className={`transition-opacity duration-300 ${
|
||||
theme === 'light' ? 'opacity-0' : 'opacity-40'
|
||||
}`}
|
||||
>
|
||||
<svg className="w-4 h-4 text-sky-400" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
{/* 右侧月亮(深色模式时显示) */}
|
||||
<span
|
||||
className={`transition-opacity duration-300 ${
|
||||
theme === 'dark' ? 'opacity-0' : 'opacity-40'
|
||||
}`}
|
||||
>
|
||||
<svg className="w-4 h-4 text-slate-400" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path d="M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z" />
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
)
|
||||
}
|
||||
@@ -1,21 +1,23 @@
|
||||
import BetaNotice from '@pages/components/BetaNotice'
|
||||
import CodeEditor from '@pages/components/CodeEditor'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
export default function CustomTools() {
|
||||
const { t } = useTranslation('docs')
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h1 className="text-4xl font-bold mb-6">自定义工具</h1>
|
||||
<h1 className="text-4xl font-bold mb-6">{t('custom_tools.title')}</h1>
|
||||
|
||||
<p className="text-xl text-foreground/80 mb-8 leading-relaxed">
|
||||
通过注册自定义工具,扩展 AI Agent 的能力边界。使用 Zod 定义严格的输入接口,让 AI
|
||||
安全调用你的业务逻辑。
|
||||
<p className="text-xl text-gray-600 dark:text-gray-300 mb-8 leading-relaxed">
|
||||
{t('custom_tools.subtitle')}
|
||||
</p>
|
||||
|
||||
<div className="space-y-8">
|
||||
<section>
|
||||
<h2 className="text-2xl font-bold mb-4">工具注册</h2>
|
||||
<p className="text-foreground/80 mb-4">
|
||||
每个自定义工具需要定义四个核心属性:name、description、input schema 和 execute 函数。
|
||||
<h2 className="text-2xl font-bold mb-4">{t('custom_tools.registration')}</h2>
|
||||
<p className="text-gray-600 dark:text-gray-300 mb-4">
|
||||
{t('custom_tools.registration_desc')}
|
||||
</p>
|
||||
|
||||
<CodeEditor
|
||||
@@ -49,13 +51,12 @@ const pageAgent = new PageAgent({customTools})
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 className="text-2xl font-bold mb-4">页面过滤器</h2>
|
||||
<h2 className="text-2xl font-bold mb-4">{t('custom_tools.page_filter')}</h2>
|
||||
|
||||
<BetaNotice />
|
||||
|
||||
<p className="text-foreground/80 mb-4">
|
||||
通过 <code className="bg-gray-200 dark:bg-gray-700 px-2 py-1 rounded">pageFilter</code>{' '}
|
||||
属性控制工具在哪些页面可见,提升安全性和用户体验。
|
||||
<p className="text-gray-600 dark:text-gray-300 mb-4">
|
||||
{t('custom_tools.page_filter_desc')}
|
||||
</p>
|
||||
|
||||
<CodeEditor
|
||||
@@ -82,16 +83,16 @@ const pageAgent = new PageAgent({customTools})
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 className="text-2xl font-bold mb-4">最佳实践</h2>
|
||||
<h2 className="text-2xl font-bold mb-4">{t('custom_tools.best_practices')}</h2>
|
||||
<div className="space-y-4">
|
||||
<div className="p-4 bg-yellow-50 dark:bg-yellow-900/20 rounded-lg">
|
||||
<h3 className="text-lg font-semibold text-yellow-900 dark:text-yellow-300 mb-2">
|
||||
⚡ 性能优化
|
||||
{t('custom_tools.bp_performance')}
|
||||
</h3>
|
||||
<ul className="text-foreground/80 space-y-1 text-sm">
|
||||
<li>• 使用 pageFilter 减少不必要的工具加载</li>
|
||||
<li>• 在 execute 函数中实现适当的缓存机制</li>
|
||||
<li>• 避免在工具中执行耗时的同步操作</li>
|
||||
<ul className="text-gray-600 dark:text-gray-300 space-y-1 text-sm">
|
||||
<li>{t('custom_tools.bp_1')}</li>
|
||||
<li>{t('custom_tools.bp_2')}</li>
|
||||
<li>{t('custom_tools.bp_3')}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -8,7 +8,7 @@ export default function DataMasking() {
|
||||
|
||||
<BetaNotice />
|
||||
|
||||
<p className="text-xl text-foreground/80 mb-6 leading-relaxed">
|
||||
<p className="text-xl text-gray-600 dark:text-gray-300 mb-6 leading-relaxed">
|
||||
保护敏感数据,确保 AI 处理过程中的数据安全。
|
||||
</p>
|
||||
|
||||
@@ -19,14 +19,18 @@ export default function DataMasking() {
|
||||
<h3 className="text-lg font-semibold mb-2 text-blue-900 dark:text-blue-300">
|
||||
🔒 自动脱敏
|
||||
</h3>
|
||||
<p className="text-foreground/80">自动识别并脱敏手机号、身份证号、银行卡号等敏感信息。</p>
|
||||
<p className="text-gray-600 dark:text-gray-300">
|
||||
自动识别并脱敏手机号、身份证号、银行卡号等敏感信息。
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="p-4 bg-purple-50 dark:bg-purple-900/20 rounded-lg">
|
||||
<h3 className="text-lg font-semibold mb-2 text-purple-900 dark:text-purple-300">
|
||||
⚙️ 自定义规则
|
||||
</h3>
|
||||
<p className="text-foreground/80">支持自定义脱敏规则,适应不同业务场景的数据保护需求。</p>
|
||||
<p className="text-gray-600 dark:text-gray-300">
|
||||
支持自定义脱敏规则,适应不同业务场景的数据保护需求。
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ export default function KnowledgeInjection() {
|
||||
|
||||
<BetaNotice />
|
||||
|
||||
<p className="text-xl text-foreground/80 mb-8 leading-relaxed">
|
||||
<p className="text-xl text-gray-600 dark:text-gray-300 mb-8 leading-relaxed">
|
||||
通过多层次的知识注入,让 AI 深度理解你的业务场景和应用逻辑,实现更精准的自动化操作。
|
||||
</p>
|
||||
|
||||
@@ -20,8 +20,10 @@ export default function KnowledgeInjection() {
|
||||
<h3 className="text-xl font-semibold mb-3 text-purple-900 dark:text-purple-300">
|
||||
🎯 系统级指令
|
||||
</h3>
|
||||
<p className="text-foreground/80 mb-4">为 AI 设定全局行为准则和工作风格。</p>
|
||||
<ul className="list-disc list-inside space-y-2 text-foreground/70">
|
||||
<p className="text-gray-600 dark:text-gray-300 mb-4">
|
||||
为 AI 设定全局行为准则和工作风格。
|
||||
</p>
|
||||
<ul className="list-disc list-inside space-y-2 text-gray-500 dark:text-gray-400">
|
||||
<li>定义 AI 的工作风格和交互方式</li>
|
||||
<li>设置安全边界和操作限制</li>
|
||||
<li>指定错误处理和异常情况的应对策略</li>
|
||||
@@ -57,13 +59,13 @@ const pageAgent = new PageAgent({
|
||||
<h3 className="text-xl font-semibold mb-3 text-blue-900 dark:text-blue-300">
|
||||
<EFBFBD> 业务领域知识
|
||||
</h3>
|
||||
<p className="text-foreground/80 mb-4">
|
||||
<p className="text-gray-600 dark:text-gray-300 mb-4">
|
||||
注入应用的核心业务知识,包括产品介绍、操作流程、术语定义等,让 AI 理解业务上下文。
|
||||
</p>
|
||||
<div className="grid md:grid-cols-2 gap-4">
|
||||
<div className="space-y-2">
|
||||
<h4 className="font-semibold text-blue-800 dark:text-blue-200">产品知识</h4>
|
||||
<ul className="list-disc list-inside text-sm text-foreground/70 space-y-1">
|
||||
<ul className="list-disc list-inside text-sm text-gray-500 dark:text-gray-400 space-y-1">
|
||||
<li>产品功能和特性介绍</li>
|
||||
<li>用户角色和权限体系</li>
|
||||
<li>业务规则和约束条件</li>
|
||||
@@ -71,7 +73,7 @@ const pageAgent = new PageAgent({
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<h4 className="font-semibold text-blue-800 dark:text-blue-200">操作指南</h4>
|
||||
<ul className="list-disc list-inside text-sm text-foreground/70 space-y-1">
|
||||
<ul className="list-disc list-inside text-sm text-gray-500 dark:text-gray-400 space-y-1">
|
||||
<li>标准操作流程定义</li>
|
||||
<li>异常情况处理方案</li>
|
||||
<li>术语和概念解释</li>
|
||||
@@ -111,21 +113,25 @@ pageAgent.knowledge.setAppKnowledge(\`
|
||||
<h3 className="text-xl font-semibold mb-3 text-green-900 dark:text-green-300">
|
||||
📄 页面级精准指导
|
||||
</h3>
|
||||
<p className="text-foreground/80 mb-4">
|
||||
<p className="text-gray-600 dark:text-gray-300 mb-4">
|
||||
为特定页面提供精确的操作指导和元素说明,让 AI 准确理解页面结构和交互逻辑。
|
||||
</p>
|
||||
<div className="grid md:grid-cols-3 gap-4">
|
||||
<div className="space-y-2">
|
||||
<h4 className="font-semibold text-green-800 dark:text-green-200">元素标注</h4>
|
||||
<p className="text-sm text-foreground/70">为页面元素添加语义化描述</p>
|
||||
<p className="text-sm text-gray-500 dark:text-gray-400">为页面元素添加语义化描述</p>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<h4 className="font-semibold text-green-800 dark:text-green-200">交互说明</h4>
|
||||
<p className="text-sm text-foreground/70">定义元素的交互行为和预期结果</p>
|
||||
<p className="text-sm text-gray-500 dark:text-gray-400">
|
||||
定义元素的交互行为和预期结果
|
||||
</p>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<h4 className="font-semibold text-green-800 dark:text-green-200">页面逻辑</h4>
|
||||
<p className="text-sm text-foreground/70">说明页面的业务逻辑和状态变化</p>
|
||||
<p className="text-sm text-gray-500 dark:text-gray-400">
|
||||
说明页面的业务逻辑和状态变化
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,69 +1,78 @@
|
||||
import BetaNotice from '@pages/components/BetaNotice'
|
||||
import CodeEditor from '@pages/components/CodeEditor'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
export default function ModelIntegration() {
|
||||
const { t } = useTranslation('docs')
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h1 className="text-4xl font-bold mb-6">模型接入</h1>
|
||||
<h1 className="text-4xl font-bold mb-6">{t('model_integration.title')}</h1>
|
||||
|
||||
<p className="text-xl text-gray-600 dark:text-gray-300 mb-6 leading-relaxed">
|
||||
当前支持符合 OpenAI 接口规范且支持 tool call 的模型,包括公有云服务和私有部署方案。
|
||||
{t('model_integration.subtitle')}
|
||||
</p>
|
||||
|
||||
<h2 className="text-2xl font-bold mb-3">推荐模型</h2>
|
||||
<h2 className="text-2xl font-bold mb-3">{t('model_integration.recommended')}</h2>
|
||||
|
||||
<div className="grid md:grid-cols-3 gap-4 mb-6">
|
||||
<div className="p-4 bg-green-50 dark:bg-green-900/20 rounded-lg">
|
||||
<h3 className="text-lg font-semibold mb-2 text-green-900 dark:text-green-300">
|
||||
⚡ gpt-4.1-mini
|
||||
{t('model_integration.model_gpt4_title')}
|
||||
</h3>
|
||||
<p className="text-sm text-foreground/80 mb-2">评估基准 ✅</p>
|
||||
<ul className="text-sm text-foreground/70 space-y-1">
|
||||
<li>• 性价比高</li>
|
||||
<li>• 速度快</li>
|
||||
<li>• 成功率高</li>
|
||||
<p className="text-sm text-gray-600 dark:text-gray-300 mb-2">
|
||||
{t('model_integration.model_gpt4_badge')}
|
||||
</p>
|
||||
<ul className="text-sm text-gray-500 dark:text-gray-400 space-y-1">
|
||||
<li>{t('model_integration.model_gpt4_1')}</li>
|
||||
<li>{t('model_integration.model_gpt4_2')}</li>
|
||||
<li>{t('model_integration.model_gpt4_3')}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="p-4 bg-purple-50 dark:bg-purple-900/20 rounded-lg">
|
||||
<h3 className="text-lg font-semibold mb-2 text-purple-900 dark:text-purple-300">
|
||||
💰 DeepSeek-3.2
|
||||
{t('model_integration.model_deepseek_title')}
|
||||
</h3>
|
||||
<p className="text-sm text-foreground/80 mb-2">经济实惠</p>
|
||||
<ul className="text-sm text-foreground/70 space-y-1">
|
||||
<li>• 价格远低于同等级其他模型</li>
|
||||
<li>• ToolCall 有出错率,通常能够自动修复</li>
|
||||
<li>• 本网站提供的免费试用为 DeepSeek</li>
|
||||
<p className="text-sm text-gray-600 dark:text-gray-300 mb-2">
|
||||
{t('model_integration.model_deepseek_badge')}
|
||||
</p>
|
||||
<ul className="text-sm text-gray-500 dark:text-gray-400 space-y-1">
|
||||
<li>{t('model_integration.model_deepseek_1')}</li>
|
||||
<li>{t('model_integration.model_deepseek_2')}</li>
|
||||
<li>{t('model_integration.model_deepseek_3')}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="p-4 bg-orange-50 dark:bg-orange-900/20 rounded-lg">
|
||||
<h3 className="text-lg font-semibold mb-2 text-orange-900 dark:text-orange-300">
|
||||
🛡️ qwen3
|
||||
{t('model_integration.model_qwen_title')}
|
||||
</h3>
|
||||
<p className="text-sm text-foreground/80 mb-2">安全合规</p>
|
||||
<ul className="text-sm text-foreground/70 space-y-1">
|
||||
<li>• 可控、效果尚可,价格合理</li>
|
||||
<li>• ToolCall 有出错率,通常能够自动修复</li>
|
||||
<li>
|
||||
• 适合能给出<strong>详细步骤</strong>的场景
|
||||
</li>
|
||||
<p className="text-sm text-gray-600 dark:text-gray-300 mb-2">
|
||||
{t('model_integration.model_qwen_badge')}
|
||||
</p>
|
||||
<ul className="text-sm text-gray-500 dark:text-gray-400 space-y-1">
|
||||
<li>{t('model_integration.model_qwen_1')}</li>
|
||||
<li>{t('model_integration.model_qwen_2')}</li>
|
||||
<li>{t('model_integration.model_qwen_3')}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="p-4 bg-orange-50 dark:bg-orange-900/20 rounded-lg">
|
||||
<h3 className="text-lg font-semibold mb-2 text-orange-900 dark:text-orange-300">
|
||||
⚡ gemini-2.5-flash
|
||||
{t('model_integration.model_gemini_title')}
|
||||
</h3>
|
||||
<p className="text-sm text-foreground/80 mb-2">极其高效,成功率高,价格合理</p>
|
||||
<p className="text-sm text-gray-600 dark:text-gray-300 mb-2">
|
||||
{t('model_integration.model_gemini_badge')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 className="text-2xl font-bold mb-3">可用模型</h2>
|
||||
<h2 className="text-2xl font-bold mb-3">{t('model_integration.available')}</h2>
|
||||
|
||||
<div className="p-4 bg-emerald-50 dark:bg-emerald-900/20 rounded-lg mb-6">
|
||||
<h3 className="text-lg font-semibold mb-3 text-emerald-900 dark:text-emerald-300">
|
||||
✅ 已验证可用
|
||||
{t('model_integration.available_verified')}
|
||||
</h3>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
<span className="inline-flex items-center rounded-full bg-emerald-100 dark:bg-emerald-900/40 text-emerald-900 dark:text-emerald-200 px-3 py-1 text-sm">
|
||||
@@ -87,20 +96,17 @@ export default function ModelIntegration() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 className="text-2xl font-bold mb-3">提示</h2>
|
||||
<h2 className="text-2xl font-bold mb-3">{t('model_integration.tips')}</h2>
|
||||
|
||||
<div className="p-4 bg-red-50 dark:bg-red-900/20 rounded-lg mb-6">
|
||||
<ul className="text-sm text-foreground/80 space-y-1 list-disc pl-5">
|
||||
<li>reasoning 模型(如 GPT-5),速度偏慢,没有必要</li>
|
||||
<li>
|
||||
不保证 json schema 的模型(openAI 以外的几乎所有模型),tool call
|
||||
有概率出错,通常能自动修复,建议 temperature 设置高一些
|
||||
</li>
|
||||
<li>小模型、nano 模型,效果不佳</li>
|
||||
<ul className="text-sm text-gray-600 dark:text-gray-300 space-y-1 list-disc pl-5">
|
||||
<li>{t('model_integration.tip_1')}</li>
|
||||
<li>{t('model_integration.tip_2')}</li>
|
||||
<li>{t('model_integration.tip_3')}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<h2 className="text-2xl font-bold mb-3">配置方式</h2>
|
||||
<h2 className="text-2xl font-bold mb-3">{t('model_integration.configuration')}</h2>
|
||||
|
||||
<CodeEditor
|
||||
code={`
|
||||
|
||||
@@ -7,7 +7,7 @@ export default function SecurityPermissions() {
|
||||
|
||||
<BetaNotice />
|
||||
|
||||
<p className="text-xl text-foreground/80 mb-8 leading-relaxed">
|
||||
<p className="text-xl text-gray-600 dark:text-gray-300 mb-8 leading-relaxed">
|
||||
page-agent 提供四种安全机制,确保 AI 操作在可控范围内进行。
|
||||
</p>
|
||||
|
||||
@@ -19,13 +19,15 @@ export default function SecurityPermissions() {
|
||||
<h3 className="text-lg font-semibold text-red-900 dark:text-red-300">
|
||||
🚫 操作黑名单
|
||||
</h3>
|
||||
<p className="text-foreground/80">禁止 AI 操作敏感元素,如删除按钮、支付按钮等。</p>
|
||||
<p className="text-gray-600 dark:text-gray-300">
|
||||
禁止 AI 操作敏感元素,如删除按钮、支付按钮等。
|
||||
</p>
|
||||
</div>
|
||||
<div className="p-4 bg-green-50 dark:bg-green-900/20 rounded-lg">
|
||||
<h3 className="text-lg font-semibold text-green-900 dark:text-green-300">
|
||||
✅ 操作白名单
|
||||
</h3>
|
||||
<p className="text-foreground/80">明确定义 AI 可以操作的元素范围。</p>
|
||||
<p className="text-gray-600 dark:text-gray-300">明确定义 AI 可以操作的元素范围。</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -37,13 +39,13 @@ export default function SecurityPermissions() {
|
||||
<h3 className="text-lg font-semibold text-red-900 dark:text-red-300">
|
||||
🚫 URL 黑名单
|
||||
</h3>
|
||||
<p className="text-foreground/80">禁止 AI 访问敏感页面和危险链接。</p>
|
||||
<p className="text-gray-600 dark:text-gray-300">禁止 AI 访问敏感页面和危险链接。</p>
|
||||
</div>
|
||||
<div className="p-4 bg-green-50 dark:bg-green-900/20 rounded-lg">
|
||||
<h3 className="text-lg font-semibold text-green-900 dark:text-green-300">
|
||||
✅ URL 白名单
|
||||
</h3>
|
||||
<p className="text-foreground/80">限制 AI 只能访问预定义的安全页面。</p>
|
||||
<p className="text-gray-600 dark:text-gray-300">限制 AI 只能访问预定义的安全页面。</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -54,17 +56,21 @@ export default function SecurityPermissions() {
|
||||
<h3 className="text-lg font-semibold mb-2 text-yellow-900 dark:text-yellow-300">
|
||||
⚠️ 高危操作控制
|
||||
</h3>
|
||||
<p className="text-foreground/80 mb-3">
|
||||
<p className="text-gray-600 dark:text-gray-300 mb-3">
|
||||
在 AI 指令中明确列举高危操作,通过两种策略进行控制:
|
||||
</p>
|
||||
<div className="space-y-2">
|
||||
<div className="pl-3 border-l-2 border-red-400">
|
||||
<p className="font-medium text-red-700 dark:text-red-300">完全禁止操作</p>
|
||||
<p className="text-sm text-foreground/70">对极高风险操作明确禁止执行</p>
|
||||
<p className="text-sm text-gray-500 dark:text-gray-400">
|
||||
对极高风险操作明确禁止执行
|
||||
</p>
|
||||
</div>
|
||||
<div className="pl-3 border-l-2 border-orange-400">
|
||||
<p className="font-medium text-orange-700 dark:text-orange-300">需用户确认操作</p>
|
||||
<p className="text-sm text-foreground/70">对中等风险操作要求用户明确同意</p>
|
||||
<p className="text-sm text-gray-500 dark:text-gray-400">
|
||||
对中等风险操作要求用户明确同意
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -19,7 +19,9 @@ export default function BestPractices() {
|
||||
<h3 className="text-lg font-semibold mb-2 text-green-900 dark:text-green-300">
|
||||
⚡ 减少 API 调用
|
||||
</h3>
|
||||
<p className="text-foreground/80 mb-3">合并多个操作指令,减少与 AI 模型的交互次数。</p>
|
||||
<p className="text-gray-600 dark:text-gray-300 mb-3">
|
||||
合并多个操作指令,减少与 AI 模型的交互次数。
|
||||
</p>
|
||||
|
||||
<CodeEditor
|
||||
code={`// 推荐:合并操作
|
||||
@@ -36,7 +38,9 @@ await pageAgent.execute('点击提交按钮');`}
|
||||
<h3 className="text-lg font-semibold mb-2 text-blue-900 dark:text-blue-300">
|
||||
🎯 精确的元素描述
|
||||
</h3>
|
||||
<p className="text-foreground/80">使用具体、明确的元素描述,提高操作成功率。</p>
|
||||
<p className="text-gray-600 dark:text-gray-300">
|
||||
使用具体、明确的元素描述,提高操作成功率。
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -45,12 +49,12 @@ await pageAgent.execute('点击提交按钮');`}
|
||||
<div className="space-y-3 mb-6">
|
||||
<div className="p-3 bg-red-50 dark:bg-red-900/20 rounded-lg border-l-4 border-red-500">
|
||||
<h3 className="font-semibold mb-1 text-red-900 dark:text-red-300">重要操作保护</h3>
|
||||
<p className="text-foreground/80">对删除、支付等敏感操作设置黑名单保护。</p>
|
||||
<p className="text-gray-600 dark:text-gray-300">对删除、支付等敏感操作设置黑名单保护。</p>
|
||||
</div>
|
||||
|
||||
<div className="p-3 bg-yellow-50 dark:bg-yellow-900/20 rounded-lg border-l-4 border-yellow-500">
|
||||
<h3 className="font-semibold mb-1 text-yellow-900 dark:text-yellow-300">数据脱敏</h3>
|
||||
<p className="text-foreground/80">启用数据脱敏功能,保护用户隐私信息。</p>
|
||||
<p className="text-gray-600 dark:text-gray-300">启用数据脱敏功能,保护用户隐私信息。</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ export default function CdnSetup() {
|
||||
<h3 className="text-lg font-semibold mb-2 text-yellow-900 dark:text-yellow-300">
|
||||
⚠️ 注意事项
|
||||
</h3>
|
||||
<ul className="text-foreground/80 space-y-1">
|
||||
<ul className="text-gray-600 dark:text-gray-300 space-y-1">
|
||||
<li>• 生产环境建议使用固定版本号</li>
|
||||
<li>• 确保 HTTPS 环境下使用</li>
|
||||
<li>• 配置 CSP 策略允许脚本执行</li>
|
||||
|
||||
@@ -4,14 +4,14 @@ export default function ThirdPartyAgentPage() {
|
||||
return (
|
||||
<div>
|
||||
<h1 className="text-4xl font-bold mb-6">接入第三方 Agent</h1>
|
||||
<p className="mb-6 leading-relaxed">
|
||||
<p className="mb-6 leading-relaxed text-gray-600 dark:text-gray-300">
|
||||
将 pageAgent 作为工具接入你的答疑助手或 Agent 系统,成为你 Agent 的眼和手。
|
||||
</p>
|
||||
|
||||
<div className="bg-blue-50 dark:bg-blue-900/20 rounded-lg p-4 mb-6">
|
||||
<h3 className="text-lg font-semibold mb-2 text-blue-900 dark:text-blue-300">💡 核心价值</h3>
|
||||
<p className="text-blue-800 dark:text-blue-200">
|
||||
让你的 Agent 不再只是"嘴巴",而是拥有"眼睛"和"手"的完整智能体。
|
||||
让你的答疑机器人不再只是"嘴巴",而是拥有"眼睛"和"手"的完整智能体。
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -49,25 +49,25 @@ const pageAgentTool = {
|
||||
<h2 className="text-2xl font-bold mb-4">应用场景</h2>
|
||||
<div className="grid md:grid-cols-2 gap-4 mb-6">
|
||||
<div className="bg-gradient-to-br from-blue-50 to-purple-50 dark:from-gray-800 dark:to-gray-700 p-4 rounded-lg">
|
||||
<h4 className="font-semibold mb-2">🤖 智能客服系统</h4>
|
||||
<h4 className="font-semibold mb-2 text-gray-900 dark:text-white">🤖 智能客服系统</h4>
|
||||
<p className="text-sm text-gray-600 dark:text-gray-300">
|
||||
客服机器人帮用户直接操作系统,如"帮我提交工单"
|
||||
</p>
|
||||
</div>
|
||||
<div className="bg-gradient-to-br from-green-50 to-blue-50 dark:from-gray-800 dark:to-gray-700 p-4 rounded-lg">
|
||||
<h4 className="font-semibold mb-2">📋 业务流程助手</h4>
|
||||
<h4 className="font-semibold mb-2 text-gray-900 dark:text-white">📋 业务流程助手</h4>
|
||||
<p className="text-sm text-gray-600 dark:text-gray-300">
|
||||
引导新员工完成复杂流程,如"完成客户入职"
|
||||
</p>
|
||||
</div>
|
||||
<div className="bg-gradient-to-br from-purple-50 to-pink-50 dark:from-gray-800 dark:to-gray-700 p-4 rounded-lg">
|
||||
<h4 className="font-semibold mb-2">🎯 个人效率助手</h4>
|
||||
<h4 className="font-semibold mb-2 text-gray-900 dark:text-white">🎯 个人效率助手</h4>
|
||||
<p className="text-sm text-gray-600 dark:text-gray-300">
|
||||
跨网站帮你完成任务,如"预订会议室"
|
||||
</p>
|
||||
</div>
|
||||
<div className="bg-gradient-to-br from-orange-50 to-red-50 dark:from-gray-800 dark:to-gray-700 p-4 rounded-lg">
|
||||
<h4 className="font-semibold mb-2">🔧 运维自动化</h4>
|
||||
<h4 className="font-semibold mb-2 text-gray-900 dark:text-white">🔧 运维自动化</h4>
|
||||
<p className="text-sm text-gray-600 dark:text-gray-300">
|
||||
通过自然语言操作管理后台,如"重启服务器"
|
||||
</p>
|
||||
@@ -77,12 +77,12 @@ const pageAgentTool = {
|
||||
<h2 className="text-2xl font-bold mb-4">最佳实践</h2>
|
||||
<div className="space-y-4 mb-6">
|
||||
<div className="p-4 bg-gray-50 dark:bg-gray-800 rounded-lg">
|
||||
<h3 className="text-lg font-semibold mb-2">错误处理</h3>
|
||||
<h3 className="text-lg font-semibold mb-2 text-gray-900 dark:text-white">错误处理</h3>
|
||||
<CodeEditor code={`// @TODO`} language="javascript" />
|
||||
</div>
|
||||
|
||||
<div className="p-4 bg-gray-50 dark:bg-gray-800 rounded-lg">
|
||||
<h3 className="text-lg font-semibold mb-2">权限控制</h3>
|
||||
<h3 className="text-lg font-semibold mb-2 text-gray-900 dark:text-white">权限控制</h3>
|
||||
<CodeEditor code={`// @TODO`} language="javascript" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -99,8 +99,10 @@ const pageAgentTool = {
|
||||
</div>
|
||||
|
||||
<div className="bg-gradient-to-r from-green-50 to-blue-50 dark:from-green-900/20 dark:to-blue-900/20 p-4 rounded-lg">
|
||||
<h3 className="text-lg font-semibold mb-2">🎉 开始集成</h3>
|
||||
<p className="mb-3">通过这种方式,你的 Agent 系统就能真正成为用户的智能助手。</p>
|
||||
<h3 className="text-lg font-semibold mb-2 text-gray-900 dark:text-white">🎉 开始集成</h3>
|
||||
<p className="mb-3 text-gray-700 dark:text-gray-300">
|
||||
通过这种方式,你的 Agent 系统就能真正成为用户的智能助手。
|
||||
</p>
|
||||
<a
|
||||
href="/docs/integration/configuration"
|
||||
className="inline-flex items-center px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors duration-200"
|
||||
|
||||
@@ -1,153 +1,141 @@
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
export default function LimitationsPage() {
|
||||
const { t } = useTranslation('docs')
|
||||
|
||||
return (
|
||||
<div className="max-w-4xl mx-auto">
|
||||
<div className="mb-8">
|
||||
<h1 className="text-4xl font-bold mb-4 text-gray-900 dark:text-white">使用限制</h1>
|
||||
<p className="text-xl text-gray-600 dark:text-gray-300">
|
||||
了解 page-agent 当前的功能边界和技术限制
|
||||
</p>
|
||||
<h1 className="text-4xl font-bold mb-4 text-gray-900 dark:text-white">
|
||||
{t('limitations.title')}
|
||||
</h1>
|
||||
<p className="text-xl text-gray-600 dark:text-gray-300">{t('limitations.subtitle')}</p>
|
||||
</div>
|
||||
|
||||
<div className="prose prose-lg dark:prose-invert max-w-none">
|
||||
<h2 className="text-2xl font-bold mb-3">页面支持限制</h2>
|
||||
<h2 className="text-2xl font-bold mb-3">{t('limitations.page_support')}</h2>
|
||||
<div className="bg-blue-50 dark:bg-blue-900/20 border-l-4 border-blue-400 p-4 mb-6">
|
||||
<h3 className="font-semibold text-blue-800 dark:text-blue-200 mb-2">单页应用限制</h3>
|
||||
<h3 className="font-semibold text-blue-800 dark:text-blue-200 mb-2">
|
||||
{t('limitations.spa_limit_title')}
|
||||
</h3>
|
||||
<ul className="text-blue-700 dark:text-blue-300 space-y-2">
|
||||
<li>
|
||||
• <strong>仅支持单页应用(SPA)</strong>:目前只能在单个页面内进行操作
|
||||
</li>
|
||||
<li>
|
||||
• <strong>多页接力功能正在设计中</strong>:暂时无法跨页面执行连续任务
|
||||
</li>
|
||||
<li>
|
||||
• <strong>无法操作未接入该能力的网站</strong>:需要目标网站主动集成 page-agent
|
||||
</li>
|
||||
<li>{t('limitations.spa_limit_1')}</li>
|
||||
<li>{t('limitations.spa_limit_2')}</li>
|
||||
<li>{t('limitations.spa_limit_3')}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<h2 className="text-2xl font-bold mb-3">交互行为限制</h2>
|
||||
<h2 className="text-2xl font-bold mb-3">{t('limitations.interaction_limits')}</h2>
|
||||
<div className="bg-gray-50 dark:bg-gray-800 rounded-lg p-6 mb-6">
|
||||
<h3 className="font-semibold mb-4">支持的操作</h3>
|
||||
<h3 className="font-semibold mb-4">{t('limitations.supported_ops')}</h3>
|
||||
<div className="grid md:grid-cols-2 gap-4 mb-6">
|
||||
<div className="space-y-2">
|
||||
<div className="flex items-center text-green-600 dark:text-green-400">
|
||||
<span className="mr-2">✅</span>
|
||||
<span>点击操作</span>
|
||||
<span>{t('limitations.op_click')}</span>
|
||||
</div>
|
||||
<div className="flex items-center text-green-600 dark:text-green-400">
|
||||
<span className="mr-2">✅</span>
|
||||
<span>文本输入</span>
|
||||
<span>{t('limitations.op_input')}</span>
|
||||
</div>
|
||||
<div className="flex items-center text-green-600 dark:text-green-400">
|
||||
<span className="mr-2">✅</span>
|
||||
<span>页面滚动</span>
|
||||
<span>{t('limitations.op_scroll')}</span>
|
||||
</div>
|
||||
<div className="flex items-center text-green-600 dark:text-green-400">
|
||||
<span className="mr-2">✅</span>
|
||||
<span>表单提交</span>
|
||||
<span>{t('limitations.op_submit')}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<div className="flex items-center text-green-600 dark:text-green-400">
|
||||
<span className="mr-2">✅</span>
|
||||
<span>选择操作</span>
|
||||
<span>{t('limitations.op_select')}</span>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center text-green-600 dark:text-green-400">
|
||||
<span className="mr-2">✅</span>
|
||||
<span>焦点切换</span>
|
||||
<span>{t('limitations.op_focus')}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3 className="font-semibold mb-4">不支持的操作</h3>
|
||||
<h3 className="font-semibold mb-4">{t('limitations.unsupported_ops')}</h3>
|
||||
<div className="grid md:grid-cols-2 gap-4">
|
||||
<div className="space-y-2">
|
||||
<div className="flex items-center text-red-600 dark:text-red-400">
|
||||
<span className="mr-2">❌</span>
|
||||
<span>鼠标悬停(hover)</span>
|
||||
<span>{t('limitations.op_hover')}</span>
|
||||
</div>
|
||||
<div className="flex items-center text-red-600 dark:text-red-400">
|
||||
<span className="mr-2">❌</span>
|
||||
<span>拖拽操作</span>
|
||||
<span>{t('limitations.op_drag')}</span>
|
||||
</div>
|
||||
<div className="flex items-center text-red-600 dark:text-red-400">
|
||||
<span className="mr-2">❌</span>
|
||||
<span>右键菜单</span>
|
||||
<span>{t('limitations.op_context')}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<div className="flex items-center text-red-600 dark:text-red-400">
|
||||
<span className="mr-2">❌</span>
|
||||
<span>图形绘制</span>
|
||||
<span>{t('limitations.op_draw')}</span>
|
||||
</div>
|
||||
<div className="flex items-center text-red-600 dark:text-red-400">
|
||||
<span className="mr-2">❌</span>
|
||||
<span>键盘快捷键</span>
|
||||
<span>{t('limitations.op_keyboard')}</span>
|
||||
</div>
|
||||
<div className="flex items-center text-red-600 dark:text-red-400">
|
||||
<span className="mr-2">❌</span>
|
||||
<span>基于点击区域或鼠标位置的控制</span>
|
||||
<span>{t('limitations.op_position')}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 className="text-2xl font-bold mb-3">网页理解限制</h2>
|
||||
<h2 className="text-2xl font-bold mb-3">{t('limitations.understanding_limits')}</h2>
|
||||
<div className="bg-red-50 dark:bg-red-900/20 border-l-4 border-red-400 p-4 mb-6">
|
||||
<h3 className="font-semibold text-red-800 dark:text-red-200 mb-2">无视觉能力</h3>
|
||||
<p className="text-red-700 dark:text-red-300 mb-3">
|
||||
page-agent 基于 DOM 结构进行理解和操作,<strong>没有视觉识别能力</strong>
|
||||
,无法理解以下内容:
|
||||
</p>
|
||||
<h3 className="font-semibold text-red-800 dark:text-red-200 mb-2">
|
||||
{t('limitations.no_vision_title')}
|
||||
</h3>
|
||||
<p className="text-red-700 dark:text-red-300 mb-3">{t('limitations.no_vision_desc')}</p>
|
||||
<ul className="text-red-700 dark:text-red-300 space-y-1">
|
||||
<li>
|
||||
• <strong>图片内容</strong>:无法识别图片中的文字、图标或视觉元素
|
||||
</li>
|
||||
<li>
|
||||
• <strong>Canvas 画布</strong>:无法理解 Canvas 中绘制的图形和内容
|
||||
</li>
|
||||
<li>
|
||||
• <strong>WebGL 3D 内容</strong>:无法操作 3D 场景中的元素
|
||||
</li>
|
||||
<li>
|
||||
• <strong>SVG 图形</strong>:无法理解 SVG 中的视觉内容和路径
|
||||
</li>
|
||||
<li>{t('limitations.no_vision_1')}</li>
|
||||
<li>{t('limitations.no_vision_2')}</li>
|
||||
<li>{t('limitations.no_vision_3')}</li>
|
||||
<li>{t('limitations.no_vision_4')}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<h2 className="text-2xl font-bold mb-3">被操作网站要求</h2>
|
||||
<h2 className="text-2xl font-bold mb-3">{t('limitations.website_requirements')}</h2>
|
||||
<div className="bg-gray-50 dark:bg-gray-800 rounded-lg p-6 mb-6">
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<h3 className="font-semibold mb-2">语义化和易用性</h3>
|
||||
<h3 className="font-semibold mb-2">{t('limitations.req_semantic_title')}</h3>
|
||||
<p className="text-gray-600 dark:text-gray-300">
|
||||
所有操作都基于 DOM 元素的语义化标签和属性。如果页面结构不够语义化,或者没有任何
|
||||
accessibility 特性,可能影响 AI 的理解准确性。
|
||||
{t('limitations.req_semantic_desc')}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold mb-2">UI/UX</h3>
|
||||
<p className="text-gray-600 dark:text-gray-300">
|
||||
反常识的交互规则、基于视觉的操作提示、复杂的鼠标交互、快速出现快速消失的元素等,都会影响
|
||||
AI 的理解和操作。
|
||||
</p>
|
||||
<h3 className="font-semibold mb-2">{t('limitations.req_ux_title')}</h3>
|
||||
<p className="text-gray-600 dark:text-gray-300">{t('limitations.req_ux_desc')}</p>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold mb-2">环境要求</h3>
|
||||
<p className="text-gray-600 dark:text-gray-300">modern browser</p>
|
||||
<h3 className="font-semibold mb-2">{t('limitations.req_env_title')}</h3>
|
||||
<p className="text-gray-600 dark:text-gray-300">{t('limitations.req_env_desc')}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2>未来规划</h2>
|
||||
<h2>{t('limitations.future')}</h2>
|
||||
<div className="bg-green-50 dark:bg-green-900/20 border-l-4 border-green-400 p-4">
|
||||
<h3 className="font-semibold text-green-800 dark:text-green-200 mb-2">即将支持</h3>
|
||||
<h3 className="font-semibold text-green-800 dark:text-green-200 mb-2">
|
||||
{t('limitations.future_title')}
|
||||
</h3>
|
||||
<ul className="text-green-700 dark:text-green-300 space-y-1">
|
||||
<li>• 多页面接力操作能力</li>
|
||||
<li>• 更丰富的鼠标交互支持</li>
|
||||
<li>• 基础的视觉理解能力</li>
|
||||
<li>• 更智能的错误恢复机制</li>
|
||||
<li>{t('limitations.future_1')}</li>
|
||||
<li>{t('limitations.future_2')}</li>
|
||||
<li>{t('limitations.future_3')}</li>
|
||||
<li>{t('limitations.future_4')}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,75 +1,117 @@
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
export default function Overview() {
|
||||
const { t } = useTranslation('docs')
|
||||
|
||||
return (
|
||||
<article>
|
||||
{/* 头图 */}
|
||||
<figure className="mb-8 rounded-xl overflow-hidden">
|
||||
<img
|
||||
src="https://img.alicdn.com/imgextra/i1/O1CN01RY0Wvh26ATVeDIX7v_!!6000000007621-0-tps-1672-512.jpg"
|
||||
alt="page-agent 概览图示"
|
||||
alt="page-agent"
|
||||
className="w-full h-64 object-cover"
|
||||
/>
|
||||
</figure>
|
||||
|
||||
<h1 className="text-4xl font-bold mb-6">Overview</h1>
|
||||
|
||||
<p className="text-xl text-foreground/80 mb-8 leading-relaxed">
|
||||
page-agent 是一个完全基于Web技术的 UI Agent,简单引入,让你的网站拥有 AI 操作员。
|
||||
<div className="mb-8">
|
||||
<h1 className="text-4xl font-bold mb-4">{t('overview.title')}</h1>
|
||||
<p className="text-xl text-gray-600 dark:text-gray-300 mb-4 leading-relaxed">
|
||||
{t('overview.subtitle')}
|
||||
</p>
|
||||
|
||||
<section>
|
||||
<h2 className="text-2xl font-bold mb-4">什么是 page-agent?</h2>
|
||||
{/* Status Badges */}
|
||||
<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">
|
||||
<img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="MIT License" />
|
||||
</a>
|
||||
<a href="http://www.typescriptlang.org/" target="_blank" rel="noopener noreferrer">
|
||||
<img
|
||||
src="https://img.shields.io/badge/%3C%2F%3E-TypeScript-%230074c1.svg"
|
||||
alt="TypeScript"
|
||||
/>
|
||||
</a>
|
||||
<a
|
||||
href="https://www.npmjs.com/package/page-agent"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<img src="https://img.shields.io/npm/dt/page-agent.svg" alt="Downloads" />
|
||||
</a>
|
||||
<a
|
||||
href="https://bundlephobia.com/package/page-agent"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<img src="https://img.shields.io/bundlephobia/minzip/page-agent" alt="Bundle Size" />
|
||||
</a>
|
||||
<a href="https://github.com/alibaba/page-agent" target="_blank" rel="noopener noreferrer">
|
||||
<img
|
||||
src="https://img.shields.io/github/stars/alibaba/page-agent.svg"
|
||||
alt="GitHub stars"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p className="text-foreground/80 mb-8 leading-relaxed ">
|
||||
page-agent 是一个<strong>页面内嵌式 UI Agent</strong>。
|
||||
与传统的浏览器自动化工具不同,page-agent 面向<strong>网站开发者</strong>
|
||||
,而非爬虫或通用Agent开发者,将 Agent 集成到你的网站中,
|
||||
让用户可以通过自然语言与页面进行交互。
|
||||
<section>
|
||||
<h2 className="text-2xl font-bold mb-4">{t('overview.what_is')}</h2>
|
||||
|
||||
<p className="text-gray-600 dark:text-gray-300 mb-8 leading-relaxed ">
|
||||
{t('overview.what_is_desc')}
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 className="text-2xl font-bold mb-3">核心特性</h2>
|
||||
<h2 className="text-2xl font-bold mb-3">{t('overview.features_title')}</h2>
|
||||
|
||||
<div className="grid md:grid-cols-2 gap-4 mb-8" role="list">
|
||||
<div className="p-4 bg-blue-50 dark:bg-blue-900/20 rounded-lg">
|
||||
<h3 className="text-lg font-semibold mb-2 text-blue-900 dark:text-blue-300">
|
||||
🧠 智能 DOM 理解
|
||||
{t('overview.feature_dom.title')}
|
||||
</h3>
|
||||
<p className="">基于 DOM 分析,高强度脱水。无需视觉识别,纯文本实现精准操作。</p>
|
||||
<p className="text-gray-700 dark:text-gray-300">{t('overview.feature_dom.desc')}</p>
|
||||
</div>
|
||||
|
||||
<div className="p-4 bg-purple-50 dark:bg-purple-900/20 rounded-lg">
|
||||
<h3 className="text-lg font-semibold mb-2 text-purple-900 dark:text-purple-300">
|
||||
🔒 安全可控
|
||||
{t('overview.feature_secure.title')}
|
||||
</h3>
|
||||
<p className="">
|
||||
支持操作黑白名单、数据脱敏保护。注入自定义知识库,让 AI 按你的规则工作。
|
||||
</p>
|
||||
<p className="text-gray-700 dark:text-gray-300">{t('overview.feature_secure.desc')}</p>
|
||||
</div>
|
||||
|
||||
<div className="p-4 bg-green-50 dark:bg-green-900/20 rounded-lg">
|
||||
<h3 className="text-lg font-semibold mb-2 text-green-900 dark:text-green-300">
|
||||
⚡ 零后端部署
|
||||
{t('overview.feature_backend.title')}
|
||||
</h3>
|
||||
<p className="">CDN 或 NPM 引入,自定义 LLM 接入点。</p>
|
||||
<p className="text-gray-700 dark:text-gray-300">{t('overview.feature_backend.desc')}</p>
|
||||
</div>
|
||||
|
||||
<div className="p-4 bg-orange-50 dark:bg-orange-900/20 rounded-lg">
|
||||
<h3 className="text-lg font-semibold mb-2 text-orange-900 dark:text-orange-300">
|
||||
♿ 普惠智能
|
||||
{t('overview.feature_accessible.title')}
|
||||
</h3>
|
||||
<p className="">为复杂 B端系统、管理后台提供自然语言入口。让每个用户都能轻松上手。</p>
|
||||
<p className="text-gray-700 dark:text-gray-300">
|
||||
{t('overview.feature_accessible.desc')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 className="text-2xl font-bold mb-4">与 browser-use 的区别</h2>
|
||||
<h2 className="text-2xl font-bold mb-4">{t('overview.vs_browser_use')}</h2>
|
||||
|
||||
<div className="overflow-x-auto mb-8">
|
||||
<table className="w-full border-collapse border border-gray-300 dark:border-gray-600">
|
||||
<thead>
|
||||
<tr className="bg-gray-50 dark:bg-gray-800">
|
||||
<th className="border border-gray-300 dark:border-gray-600 px-4 py-3 text-left">
|
||||
特性
|
||||
{t('overview.table_feature')}
|
||||
</th>
|
||||
<th className="border border-gray-300 dark:border-gray-600 px-4 py-3 text-left">
|
||||
page-agent
|
||||
@@ -82,103 +124,88 @@ export default function Overview() {
|
||||
<tbody>
|
||||
<tr>
|
||||
<td className="border border-gray-300 dark:border-gray-600 px-4 py-3 font-medium">
|
||||
部署方式
|
||||
{t('overview.table_deployment')}
|
||||
</td>
|
||||
<td className="border border-gray-300 dark:border-gray-600 px-4 py-3">
|
||||
页面内嵌组件
|
||||
{t('overview.table_deployment_pa')}
|
||||
</td>
|
||||
<td className="border border-gray-300 dark:border-gray-600 px-4 py-3">外部工具</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="border border-gray-300 dark:border-gray-600 px-4 py-3 font-medium">
|
||||
操作范围
|
||||
</td>
|
||||
<td className="border border-gray-300 dark:border-gray-600 px-4 py-3">当前页面</td>
|
||||
<td className="border border-gray-300 dark:border-gray-600 px-4 py-3">
|
||||
整个浏览器
|
||||
{t('overview.table_deployment_bu')}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="border border-gray-300 dark:border-gray-600 px-4 py-3 font-medium">
|
||||
目标用户
|
||||
{t('overview.table_scope')}
|
||||
</td>
|
||||
<td className="border border-gray-300 dark:border-gray-600 px-4 py-3">
|
||||
网站开发者
|
||||
{t('overview.table_scope_pa')}
|
||||
</td>
|
||||
<td className="border border-gray-300 dark:border-gray-600 px-4 py-3">
|
||||
爬虫/Agent 开发者
|
||||
{t('overview.table_scope_bu')}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="border border-gray-300 dark:border-gray-600 px-4 py-3 font-medium">
|
||||
使用场景
|
||||
{t('overview.table_user')}
|
||||
</td>
|
||||
<td className="border border-gray-300 dark:border-gray-600 px-4 py-3">
|
||||
用户体验增强
|
||||
{t('overview.table_user_pa')}
|
||||
</td>
|
||||
<td className="border border-gray-300 dark:border-gray-600 px-4 py-3">
|
||||
自动化任务
|
||||
{t('overview.table_user_bu')}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="border border-gray-300 dark:border-gray-600 px-4 py-3 font-medium">
|
||||
{t('overview.table_scenario')}
|
||||
</td>
|
||||
<td className="border border-gray-300 dark:border-gray-600 px-4 py-3">
|
||||
{t('overview.table_scenario_pa')}
|
||||
</td>
|
||||
<td className="border border-gray-300 dark:border-gray-600 px-4 py-3">
|
||||
{t('overview.table_scenario_bu')}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<h2 className="text-2xl font-bold mb-4">应用场景</h2>
|
||||
<h2 className="text-2xl font-bold mb-4">{t('overview.use_cases_title')}</h2>
|
||||
|
||||
<ul className="space-y-4 mb-8">
|
||||
<li className="flex items-start space-x-3">
|
||||
<span className="w-6 h-6 bg-blue-500 text-white rounded-full flex items-center justify-center font-bold mt-0.5">
|
||||
<span className="w-6 h-6 min-w-6 bg-blue-500 text-white rounded-full flex items-center justify-center font-bold text-sm mt-0.5 flex-shrink-0">
|
||||
1
|
||||
</span>
|
||||
<div className="">
|
||||
<strong>对接答疑机器人:</strong>
|
||||
把你的答疑助手变成全能Agent。客服机器人不再只说"请先点击设置按钮然后点击...",而是直接帮用户现场操作。
|
||||
<div className="text-gray-700 dark:text-gray-300">
|
||||
<strong>{t('overview.use_case1_title')}</strong> {t('overview.use_case1_desc')}
|
||||
</div>
|
||||
</li>
|
||||
<li className="flex items-start space-x-3">
|
||||
<span className="w-6 h-6 bg-green-500 text-white rounded-full flex items-center justify-center font-bold mt-0.5">
|
||||
<span className="w-6 h-6 min-w-6 bg-green-500 text-white rounded-full flex items-center justify-center font-bold text-sm mt-0.5 flex-shrink-0">
|
||||
2
|
||||
</span>
|
||||
<div className="">
|
||||
<strong>交互升级/智能化改造:</strong>
|
||||
一行代码,老应用变身Agent,产品专家帮用户操作复杂 B
|
||||
端软件。降低人工支持成本,提高用户满意度。
|
||||
<div className="text-gray-700 dark:text-gray-300">
|
||||
<strong>{t('overview.use_case2_title')}</strong> {t('overview.use_case2_desc')}
|
||||
</div>
|
||||
</li>
|
||||
<li className="flex items-start space-x-3">
|
||||
<span className="w-6 h-6 bg-purple-500 text-white rounded-full flex items-center justify-center font-bold mt-0.5">
|
||||
<span className="w-6 h-6 min-w-6 bg-purple-500 text-white rounded-full flex items-center justify-center font-bold text-sm mt-0.5 flex-shrink-0">
|
||||
3
|
||||
</span>
|
||||
<div className="">
|
||||
<strong>产品教学:</strong>
|
||||
向用户演示交互过程,边做边教。例如让AI演示"如何提交报销申请"的完整操作流程。
|
||||
<div className="text-gray-700 dark:text-gray-300">
|
||||
<strong>{t('overview.use_case3_title')}</strong> {t('overview.use_case3_desc')}
|
||||
</div>
|
||||
</li>
|
||||
<li className="flex items-start space-x-3">
|
||||
<span className="w-6 h-6 bg-orange-500 text-white rounded-full flex items-center justify-center font-bold mt-0.5">
|
||||
<span className="w-6 h-6 min-w-6 bg-orange-500 text-white rounded-full flex items-center justify-center font-bold text-sm mt-0.5 flex-shrink-0">
|
||||
4
|
||||
</span>
|
||||
<div className="">
|
||||
<strong>无障碍支持:</strong>
|
||||
为视障用户、老年用户提供自然语言交互,对接屏幕阅读器或语音助理,让软件人人可用。
|
||||
<div className="text-gray-700 dark:text-gray-300">
|
||||
<strong>{t('overview.use_case4_title')}</strong> {t('overview.use_case4_desc')}
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div className="bg-gradient-to-r from-blue-50 to-purple-50 dark:from-blue-900/20 dark:to-purple-900/20 p-4 rounded-lg">
|
||||
<h3 className="text-lg font-semibold mb-2">🚀 开始使用</h3>
|
||||
<p className="mb-3 ">
|
||||
准备好为你的网站添加 AI 操作员了吗?查看我们的快速开始指南,几分钟内完成集成。
|
||||
</p>
|
||||
<a
|
||||
href="/docs/introduction/quick-start"
|
||||
className="inline-flex items-center px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors duration-200"
|
||||
role="button"
|
||||
>
|
||||
快速开始 →
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
</article>
|
||||
)
|
||||
|
||||
@@ -1,23 +1,26 @@
|
||||
import BetaNotice from '@pages/components/BetaNotice'
|
||||
import CodeEditor from '@pages/components/CodeEditor'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
export default function QuickStart() {
|
||||
const { t } = useTranslation('docs')
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h1 className="text-4xl font-bold mb-6">Quick Start</h1>
|
||||
<h1 className="text-4xl font-bold mb-6">{t('quick_start.title')}</h1>
|
||||
|
||||
<p className=" mb-6 leading-relaxed">几分钟内完成 page-agent 的集成。</p>
|
||||
<p className=" mb-6 leading-relaxed">{t('quick_start.subtitle')}</p>
|
||||
|
||||
<h2 className="text-2xl font-bold mb-3">安装步骤</h2>
|
||||
<h2 className="text-2xl font-bold mb-3">{t('quick_start.installation')}</h2>
|
||||
|
||||
<div className="space-y-4 mb-6">
|
||||
<div className="p-4 bg-blue-50 dark:bg-blue-900/20 rounded-lg">
|
||||
<h3 className="text-lg font-semibold mb-2 text-blue-900 dark:text-blue-300">
|
||||
1. 引入方式
|
||||
{t('quick_start.step1_title')}
|
||||
</h3>
|
||||
<div className="space-y-3">
|
||||
<div>
|
||||
<p className="text-sm font-medium mb-2">CDN 引入</p>
|
||||
<p className="text-sm font-medium mb-2">{t('quick_start.step1_cdn')}</p>
|
||||
<CodeEditor
|
||||
code={`// 仅供测试使用
|
||||
<script src="https://hwcxiuzfylggtcktqgij.supabase.co/storage/v1/object/public/demo-public/v0.0.2/page-agent.js" crossorigin="true" type="text/javascript"></script>`}
|
||||
@@ -25,7 +28,7 @@ export default function QuickStart() {
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-sm font-medium mb-2">NPM 安装</p>
|
||||
<p className="text-sm font-medium mb-2">{t('quick_start.step1_npm')}</p>
|
||||
<CodeEditor
|
||||
code={`// npm install page-agent
|
||||
import PageAgent from 'page-agent'`}
|
||||
@@ -37,7 +40,7 @@ import PageAgent from 'page-agent'`}
|
||||
|
||||
<div className="p-4 bg-green-50 dark:bg-green-900/20 rounded-lg">
|
||||
<h3 className="text-lg font-semibold mb-2 text-green-900 dark:text-green-300">
|
||||
2. 初始化配置
|
||||
{t('quick_start.step2_title')}
|
||||
</h3>
|
||||
<CodeEditor
|
||||
code={`// 仅供测试使用,生产环境需要配置 LLM 接入点,本工具不提供 LLM 服务
|
||||
@@ -60,7 +63,7 @@ const agent = new PageAgent({
|
||||
|
||||
<div className="p-4 bg-purple-50 dark:bg-purple-900/20 rounded-lg">
|
||||
<h3 className="text-lg font-semibold mb-2 text-purple-900 dark:text-purple-300">
|
||||
3. 开始使用
|
||||
{t('quick_start.step3_title')}
|
||||
</h3>
|
||||
<CodeEditor
|
||||
code={`// 程序化执行自然语言指令
|
||||
|
||||
74
pages/i18n/README.md
Normal file
74
pages/i18n/README.md
Normal file
@@ -0,0 +1,74 @@
|
||||
# 国际化配置说明
|
||||
|
||||
本项目使用 `react-i18next` 实现国际化支持。
|
||||
|
||||
## 目录结构
|
||||
|
||||
```
|
||||
pages/i18n/
|
||||
├── config.ts # i18next 配置和初始化
|
||||
├── types.ts # TypeScript 类型声明
|
||||
├── locales/
|
||||
│ ├── zh-CN/ # 中文翻译
|
||||
│ │ ├── common.json # 通用组件(Header, Footer等)
|
||||
│ │ ├── home.json # 首页
|
||||
│ │ └── docs.json # 文档页(待完善)
|
||||
│ └── en-US/ # 英文翻译
|
||||
│ ├── common.json
|
||||
│ ├── home.json
|
||||
│ └── docs.json
|
||||
└── README.md # 本文件
|
||||
```
|
||||
|
||||
## 使用方法
|
||||
|
||||
### 在组件中使用
|
||||
|
||||
```tsx
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
function MyComponent() {
|
||||
const { t } = useTranslation('common') // 指定命名空间
|
||||
|
||||
return <h1>{t('header.nav_docs')}</h1>
|
||||
}
|
||||
```
|
||||
|
||||
### 使用多个命名空间
|
||||
|
||||
```tsx
|
||||
const { t } = useTranslation(['home', 'common'])
|
||||
|
||||
// 使用时指定命名空间
|
||||
t('home:hero.title')
|
||||
t('common:header.nav_docs')
|
||||
```
|
||||
|
||||
## 语言切换
|
||||
|
||||
用户可以通过以下方式切换语言:
|
||||
|
||||
1. **自动检测**:首次访问根据浏览器语言自动选择
|
||||
2. **手动切换**:点击页面右上角的语言切换按钮
|
||||
3. **持久化**:语言选择保存在 `localStorage` 中,刷新后保持
|
||||
|
||||
## 添加新翻译
|
||||
|
||||
1. 在对应的 JSON 文件中添加翻译条目(如 `zh-CN/home.json`)
|
||||
2. 在对应的英文文件中添加翻译(如 `en-US/home.json`)
|
||||
3. 在组件中使用 `t('namespace:key')` 获取翻译
|
||||
|
||||
## TypeScript 支持
|
||||
|
||||
`types.ts` 文件提供了类型声明,使得翻译 key 具有:
|
||||
|
||||
- 自动补全
|
||||
- 编译期类型检查
|
||||
- 防止拼写错误
|
||||
|
||||
## 待完成
|
||||
|
||||
- [ ] 文档页翻译(`docs.json`)
|
||||
- [ ] DocsLayout 导航结构国际化
|
||||
- [ ] 404 页面国际化
|
||||
|
||||
45
pages/i18n/config.ts
Normal file
45
pages/i18n/config.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import i18n from 'i18next'
|
||||
import LanguageDetector from 'i18next-browser-languagedetector'
|
||||
import { initReactI18next } from 'react-i18next'
|
||||
|
||||
import commonEn from './locales/en-US/common'
|
||||
import docsEn from './locales/en-US/docs'
|
||||
import homeEn from './locales/en-US/home'
|
||||
import commonZh from './locales/zh-CN/common'
|
||||
import docsZh from './locales/zh-CN/docs'
|
||||
import homeZh from './locales/zh-CN/home'
|
||||
|
||||
const resources = {
|
||||
'zh-CN': {
|
||||
common: commonZh,
|
||||
home: homeZh,
|
||||
docs: docsZh,
|
||||
},
|
||||
'en-US': {
|
||||
common: commonEn,
|
||||
home: homeEn,
|
||||
docs: docsEn,
|
||||
},
|
||||
}
|
||||
|
||||
i18n
|
||||
.use(LanguageDetector)
|
||||
.use(initReactI18next)
|
||||
.init({
|
||||
resources,
|
||||
fallbackLng: 'en-US',
|
||||
defaultNS: 'common',
|
||||
|
||||
// 语言检测配置
|
||||
detection: {
|
||||
// localStorage 优先(用户手动选择),其次检测浏览器语言
|
||||
order: ['localStorage', 'navigator'],
|
||||
caches: ['localStorage'],
|
||||
},
|
||||
|
||||
interpolation: {
|
||||
escapeValue: false, // React 已经做了 XSS 防护
|
||||
},
|
||||
})
|
||||
|
||||
export default i18n
|
||||
40
pages/i18n/locales/en-US/common.ts
Normal file
40
pages/i18n/locales/en-US/common.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
export default {
|
||||
header: {
|
||||
logo_alt: 'page-agent home',
|
||||
slogan: 'GUI Agent in your webpage',
|
||||
nav_docs: 'Docs',
|
||||
nav_source: 'GitHub',
|
||||
mobile_menu: 'Open mobile menu',
|
||||
},
|
||||
footer: {
|
||||
copyright: '© 2025 page-agent. All rights reserved.',
|
||||
github_label: 'Visit GitHub repository',
|
||||
},
|
||||
beta_notice: {
|
||||
title: 'Beta Stage',
|
||||
content:
|
||||
'Current features are incomplete and the API may change at any time. Please do not use in production environments before the official release.',
|
||||
},
|
||||
language: {
|
||||
zh: '中文',
|
||||
en: 'English',
|
||||
switch_label: 'Switch language',
|
||||
},
|
||||
nav: {
|
||||
introduction: 'Introduction',
|
||||
features: 'Features',
|
||||
integration: 'Integration',
|
||||
overview: 'Overview',
|
||||
quick_start: 'Quick Start',
|
||||
limitations: 'Limitations',
|
||||
model_integration: 'Model Integration',
|
||||
custom_tools: 'Custom Tools',
|
||||
knowledge_injection: 'Knowledge Injection',
|
||||
security_permissions: 'Security & Permissions',
|
||||
data_masking: 'Data Masking',
|
||||
cdn_setup: 'CDN Setup',
|
||||
configuration: 'Configuration',
|
||||
best_practices: 'Best Practices',
|
||||
third_party_agent: 'Third-party Agent',
|
||||
},
|
||||
}
|
||||
162
pages/i18n/locales/en-US/docs.ts
Normal file
162
pages/i18n/locales/en-US/docs.ts
Normal file
@@ -0,0 +1,162 @@
|
||||
export default {
|
||||
overview: {
|
||||
title: 'Overview',
|
||||
subtitle:
|
||||
'page-agent is a pure web-based GUI Agent. Simple integration gives your website an AI operator.',
|
||||
what_is: 'What is page-agent?',
|
||||
what_is_desc:
|
||||
'page-agent is an embedded GUI Agent. Unlike traditional browser automation tools, page-agent targets web developers, not scrapers or generic agent builders. Integrate it into your site to let users interact with pages through natural language.',
|
||||
features_title: 'Core Features',
|
||||
feature_dom: {
|
||||
title: '🧠 Smart DOM Analysis',
|
||||
desc: 'DOM-based analysis with high-intensity dehydration. No visual recognition needed—pure text for precise operations.',
|
||||
},
|
||||
feature_secure: {
|
||||
title: '🔒 Secure & Controllable',
|
||||
desc: 'Supports operation allowlists, data masking protection. Inject custom knowledge to make AI work by your rules.',
|
||||
},
|
||||
feature_backend: {
|
||||
title: '⚡ Zero Backend',
|
||||
desc: 'CDN or NPM import with custom LLM endpoints.',
|
||||
},
|
||||
feature_accessible: {
|
||||
title: '♿ Accessible Intelligence',
|
||||
desc: 'Provides natural language interface for complex B2B systems and admin panels. Makes software easy for everyone.',
|
||||
},
|
||||
vs_browser_use: 'vs. browser-use',
|
||||
table_feature: 'Feature',
|
||||
table_deployment: 'Deployment',
|
||||
table_deployment_pa: 'Embedded component',
|
||||
table_deployment_bu: 'External tool',
|
||||
table_scope: 'Scope',
|
||||
table_scope_pa: 'Current page',
|
||||
table_scope_bu: 'Entire browser',
|
||||
table_user: 'Target Users',
|
||||
table_user_pa: 'Web developers',
|
||||
table_user_bu: 'Scraper/Agent developers',
|
||||
table_scenario: 'Use Case',
|
||||
table_scenario_pa: 'UX enhancement',
|
||||
table_scenario_bu: 'Automation tasks',
|
||||
use_cases_title: 'Use Cases',
|
||||
use_case1_title: 'Connect Support Bots:',
|
||||
use_case1_desc:
|
||||
"Turn your support assistant into a full agent. Customer service bots no longer just say 'Please click the settings button then click...'—they operate for users directly.",
|
||||
use_case2_title: 'Modernize Legacy Apps:',
|
||||
use_case2_desc:
|
||||
'One line of code transforms old apps into agents. Product experts help users navigate complex B2B software. Reduce support costs and improve satisfaction.',
|
||||
use_case3_title: 'Interactive Training:',
|
||||
use_case3_desc:
|
||||
"Demonstrate workflows in real-time. Let AI show the complete process of 'how to submit an expense report.'",
|
||||
use_case4_title: 'Accessibility:',
|
||||
use_case4_desc:
|
||||
'Provide natural language interaction for visually impaired and elderly users. Connect screen readers or voice assistants to make software accessible to everyone.',
|
||||
get_started_title: '🚀 Get Started',
|
||||
get_started_desc:
|
||||
'Ready to add an AI operator to your website? Check our quick start guide for integration in minutes.',
|
||||
get_started_button: 'Quick Start →',
|
||||
},
|
||||
quick_start: {
|
||||
title: 'Quick Start',
|
||||
subtitle: 'Integrate page-agent in minutes.',
|
||||
installation: 'Installation Steps',
|
||||
step1_title: '1. Import Options',
|
||||
step1_cdn: 'CDN Import',
|
||||
step1_npm: 'NPM Install',
|
||||
step2_title: '2. Initialize Configuration',
|
||||
step3_title: '3. Start Using',
|
||||
},
|
||||
limitations: {
|
||||
title: 'Limitations',
|
||||
subtitle: "Understand page-agent's current capabilities and technical constraints",
|
||||
page_support: 'Page Support Limitations',
|
||||
spa_limit_title: 'Single Page Application Limits',
|
||||
spa_limit_1: '• SPA only: Currently operates within a single page',
|
||||
spa_limit_2: '• Multi-page relay in design: Cannot execute continuous tasks across pages yet',
|
||||
spa_limit_3: '• Requires integration: Cannot operate on sites without page-agent',
|
||||
interaction_limits: 'Interaction Limitations',
|
||||
supported_ops: 'Supported Operations',
|
||||
op_click: 'Click',
|
||||
op_input: 'Text input',
|
||||
op_scroll: 'Scroll',
|
||||
op_submit: 'Form submit',
|
||||
op_select: 'Select',
|
||||
op_focus: 'Focus',
|
||||
unsupported_ops: 'Unsupported Operations',
|
||||
op_hover: 'Mouse hover',
|
||||
op_drag: 'Drag & drop',
|
||||
op_context: 'Right-click menu',
|
||||
op_draw: 'Drawing',
|
||||
op_keyboard: 'Keyboard shortcuts',
|
||||
op_position: 'Position-based control',
|
||||
understanding_limits: 'Understanding Limitations',
|
||||
no_vision_title: 'No Visual Recognition',
|
||||
no_vision_desc:
|
||||
'page-agent operates based on DOM structure with no visual recognition. Cannot understand:',
|
||||
no_vision_1: '• Image content: Cannot recognize text, icons, or visual elements in images',
|
||||
no_vision_2: '• Canvas: Cannot understand graphics drawn on Canvas',
|
||||
no_vision_3: '• WebGL 3D: Cannot operate elements in 3D scenes',
|
||||
no_vision_4: '• SVG graphics: Cannot understand visual content and paths in SVG',
|
||||
website_requirements: 'Website Requirements',
|
||||
req_semantic_title: 'Semantic & Usability',
|
||||
req_semantic_desc:
|
||||
'All operations rely on semantic tags and attributes. Poor semantic structure or lack of accessibility features may affect AI understanding accuracy.',
|
||||
req_ux_title: 'UI/UX',
|
||||
req_ux_desc:
|
||||
'Counter-intuitive interaction rules, visual-only operation hints, complex mouse interactions, or rapidly appearing/disappearing elements can affect AI understanding and operation.',
|
||||
req_env_title: 'Environment',
|
||||
req_env_desc: 'modern browser',
|
||||
future: 'Future Plans',
|
||||
future_title: 'Coming Soon',
|
||||
future_1: '• Multi-page relay capabilities',
|
||||
future_2: '• Richer mouse interaction support',
|
||||
future_3: '• Basic visual understanding',
|
||||
future_4: '• Smarter error recovery',
|
||||
},
|
||||
model_integration: {
|
||||
title: 'Model Integration',
|
||||
subtitle:
|
||||
'Supports OpenAI-compatible models with tool call support, including public cloud services and private deployments.',
|
||||
recommended: 'Recommended Models',
|
||||
model_gpt4_title: '⚡ gpt-4.1-mini',
|
||||
model_gpt4_badge: 'Evaluation Baseline ✅',
|
||||
model_gpt4_1: '• Cost-effective',
|
||||
model_gpt4_2: '• Fast',
|
||||
model_gpt4_3: '• High success rate',
|
||||
model_deepseek_title: '💰 DeepSeek-3.2',
|
||||
model_deepseek_badge: 'Economical',
|
||||
model_deepseek_1: '• Much cheaper than similar models',
|
||||
model_deepseek_2: '• ToolCall may error but usually auto-recovers',
|
||||
model_deepseek_3: "• This site's free demo uses DeepSeek",
|
||||
model_qwen_title: '🛡️ qwen3',
|
||||
model_qwen_badge: 'Secure & Compliant',
|
||||
model_qwen_1: '• Controllable, decent results, reasonable price',
|
||||
model_qwen_2: '• ToolCall may error but usually auto-recovers',
|
||||
model_qwen_3: '• Best for scenarios with detailed steps',
|
||||
model_gemini_title: '⚡ gemini-2.5-flash',
|
||||
model_gemini_badge: 'Highly efficient, high success rate, reasonable price',
|
||||
available: 'Available Models',
|
||||
available_verified: '✅ Verified Working',
|
||||
tips: 'Tips',
|
||||
tip_1: 'Reasoning models (like GPT-5) are slower with no advantage',
|
||||
tip_2:
|
||||
"Non-OpenAI models don't guarantee JSON schema compliance—tool call may error but usually recovers. Higher temperature recommended",
|
||||
tip_3: 'Small/nano models perform poorly',
|
||||
configuration: 'Configuration',
|
||||
},
|
||||
custom_tools: {
|
||||
title: 'Custom Tools',
|
||||
subtitle:
|
||||
'Extend AI Agent capabilities by registering custom tools. Use Zod to define strict input schemas for safe business logic calls.',
|
||||
registration: 'Tool Registration',
|
||||
registration_desc:
|
||||
'Each custom tool requires four core properties: name, description, input schema, and execute function.',
|
||||
page_filter: 'Page Filter',
|
||||
page_filter_desc:
|
||||
'Control tool visibility on specific pages via the pageFilter property to enhance security and UX.',
|
||||
best_practices: 'Best Practices',
|
||||
bp_performance: '⚡ Performance Optimization',
|
||||
bp_1: '• Use pageFilter to reduce unnecessary tool loading',
|
||||
bp_2: '• Implement appropriate caching in execute functions',
|
||||
bp_3: '• Avoid long-running sync operations in tools',
|
||||
},
|
||||
}
|
||||
78
pages/i18n/locales/en-US/home.ts
Normal file
78
pages/i18n/locales/en-US/home.ts
Normal file
@@ -0,0 +1,78 @@
|
||||
export default {
|
||||
hero: {
|
||||
badge: 'GUI Agent in your webpage',
|
||||
title_line1: 'An AI Operator',
|
||||
title_line2: 'Living in Your Web Apps',
|
||||
subtitle_emoji: '🪄 One line of CDN',
|
||||
subtitle_main: ' adds intelligent GUI Agents to your website.',
|
||||
subtitle_detail: 'Users give natural language commands, AI handles the rest.',
|
||||
tab_try: '🚀 Try It Now',
|
||||
tab_other: '🌐 Try on Other Sites',
|
||||
input_placeholder: 'Describe what you want AI to do...',
|
||||
execute_button: 'Run',
|
||||
default_task: 'Navigate to docs, find data masking section, and summarize in markdown',
|
||||
},
|
||||
try_other: {
|
||||
step1_title: 'Step 1:',
|
||||
step1_content: 'Show your bookmarks bar',
|
||||
step2_title: 'Step 2:',
|
||||
step2_content: 'Drag this button to your bookmarks',
|
||||
step3_title: 'Step 3:',
|
||||
step3_content: 'Click the bookmark on any site to activate',
|
||||
notice_title: '⚠️ Heads Up',
|
||||
notice_items: {
|
||||
item1: 'Demo only—link may expire without notice',
|
||||
item2: 'This free demo uses DeepSeek API (see their terms and privacy policy)',
|
||||
item3: 'Some sites block script injection (CSP policies)',
|
||||
item4: 'Works on single-page apps only—reload required after navigation',
|
||||
item5: 'Text-only understanding—no image recognition or drag-and-drop',
|
||||
item6_prefix: 'Full limitations in',
|
||||
item6_link: 'Docs',
|
||||
},
|
||||
},
|
||||
benefits: {
|
||||
no_backend: 'Zero Backend',
|
||||
private_model: 'Your Own Models',
|
||||
data_masking: 'Built-in Privacy',
|
||||
open_source: 'MIT Open Source',
|
||||
},
|
||||
features: {
|
||||
section_title: 'Why PageAgent',
|
||||
dom_understanding: {
|
||||
title: 'Smart DOM Analysis',
|
||||
desc: 'Analyzes page structure without screenshots or vision models. Pure text understanding for fast, accurate automation.',
|
||||
},
|
||||
secure_integration: {
|
||||
title: 'Secure by Design',
|
||||
desc: 'Control what AI can access with allowlists, data masking, and custom knowledge injection. Your rules, your data.',
|
||||
},
|
||||
zero_backend: {
|
||||
title: 'Zero Backend Setup',
|
||||
desc: 'Just drop in a script tag. Works with any LLM provider—OpenAI, Anthropic, or your own models.',
|
||||
},
|
||||
accessible: {
|
||||
title: 'Natural Language UI',
|
||||
desc: 'Transform complex admin panels into chat interfaces. Make powerful tools accessible to everyone, not just experts.',
|
||||
},
|
||||
},
|
||||
use_cases: {
|
||||
section_title: 'Where It Shines',
|
||||
section_subtitle: 'From simple forms to complex workflows, AI understands and executes',
|
||||
case1: {
|
||||
title: 'Supercharge Support Bots',
|
||||
desc: 'Stop telling users where to click—let AI do it for them. Turn your chatbot from a guide into an operator that actually completes tasks.',
|
||||
},
|
||||
case2: {
|
||||
title: 'Modernize Legacy Apps',
|
||||
desc: 'Add AI superpowers to old software without rebuilding. One script tag transforms complex enterprise tools into chat-driven interfaces.',
|
||||
},
|
||||
case3: {
|
||||
title: 'Interactive Walkthroughs',
|
||||
desc: "Show, don't tell. Let AI demonstrate workflows in real-time—perfect for onboarding or training new users on complex systems.",
|
||||
},
|
||||
case4: {
|
||||
title: 'Accessibility First',
|
||||
desc: 'Make web apps accessible through natural language. Perfect for screen readers, voice control, or users who find traditional interfaces challenging.',
|
||||
},
|
||||
},
|
||||
}
|
||||
39
pages/i18n/locales/zh-CN/common.ts
Normal file
39
pages/i18n/locales/zh-CN/common.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
export default {
|
||||
header: {
|
||||
logo_alt: 'page-agent 首页',
|
||||
slogan: 'GUI Agent in your webpage',
|
||||
nav_docs: '文档',
|
||||
nav_source: 'GitHub',
|
||||
mobile_menu: '打开移动端菜单',
|
||||
},
|
||||
footer: {
|
||||
copyright: '© 2025 page-agent. All rights reserved.',
|
||||
github_label: '访问 GitHub 仓库',
|
||||
},
|
||||
beta_notice: {
|
||||
title: 'Beta 阶段',
|
||||
content: '当前功能未完成,接口可能随时变更。正式版本发布前请勿用于生产环境。',
|
||||
},
|
||||
language: {
|
||||
zh: '中文',
|
||||
en: 'English',
|
||||
switch_label: '切换语言',
|
||||
},
|
||||
nav: {
|
||||
introduction: '介绍',
|
||||
features: '功能特性',
|
||||
integration: '集成指南',
|
||||
overview: '概览',
|
||||
quick_start: '快速开始',
|
||||
limitations: '使用限制',
|
||||
model_integration: '模型接入',
|
||||
custom_tools: '自定义工具',
|
||||
knowledge_injection: '知识库注入',
|
||||
security_permissions: '安全与权限',
|
||||
data_masking: '数据脱敏',
|
||||
cdn_setup: 'CDN 引入',
|
||||
configuration: '配置选项',
|
||||
best_practices: '最佳实践',
|
||||
third_party_agent: '接入第三方 Agent',
|
||||
},
|
||||
}
|
||||
158
pages/i18n/locales/zh-CN/docs.ts
Normal file
158
pages/i18n/locales/zh-CN/docs.ts
Normal file
@@ -0,0 +1,158 @@
|
||||
export default {
|
||||
overview: {
|
||||
title: 'Overview',
|
||||
subtitle: 'page-agent 是一个完全基于Web技术的 GUI Agent,简单引入,让你的网站拥有 AI 操作员。',
|
||||
what_is: '什么是 page-agent?',
|
||||
what_is_desc:
|
||||
'page-agent 是一个页面内嵌式 GUI Agent。与传统的浏览器自动化工具不同,page-agent 面向网站开发者,而非爬虫或通用Agent开发者,将 Agent 集成到你的网站中,让用户可以通过自然语言与页面进行交互。',
|
||||
features_title: '核心特性',
|
||||
feature_dom: {
|
||||
title: '🧠 智能 DOM 理解',
|
||||
desc: '基于 DOM 分析,高强度脱水。无需视觉识别,纯文本实现精准操作。',
|
||||
},
|
||||
feature_secure: {
|
||||
title: '🔒 安全可控',
|
||||
desc: '支持操作黑白名单、数据脱敏保护。注入自定义知识库,让 AI 按你的规则工作。',
|
||||
},
|
||||
feature_backend: {
|
||||
title: '⚡ 零后端部署',
|
||||
desc: 'CDN 或 NPM 引入,自定义 LLM 接入点。',
|
||||
},
|
||||
feature_accessible: {
|
||||
title: '♿ 普惠智能',
|
||||
desc: '为复杂 B端系统、管理后台提供自然语言入口。让每个用户都能轻松上手。',
|
||||
},
|
||||
vs_browser_use: '与 browser-use 的区别',
|
||||
table_feature: '特性',
|
||||
table_deployment: '部署方式',
|
||||
table_deployment_pa: '页面内嵌组件',
|
||||
table_deployment_bu: '外部工具',
|
||||
table_scope: '操作范围',
|
||||
table_scope_pa: '当前页面',
|
||||
table_scope_bu: '整个浏览器',
|
||||
table_user: '目标用户',
|
||||
table_user_pa: '网站开发者',
|
||||
table_user_bu: '爬虫/Agent 开发者',
|
||||
table_scenario: '使用场景',
|
||||
table_scenario_pa: '用户体验增强',
|
||||
table_scenario_bu: '自动化任务',
|
||||
use_cases_title: '应用场景',
|
||||
use_case1_title: '对接答疑机器人:',
|
||||
use_case1_desc:
|
||||
'把你的答疑助手变成全能Agent。客服机器人不再只说「请先点击设置按钮然后点击...」,而是直接帮用户现场操作。',
|
||||
use_case2_title: '交互升级/智能化改造:',
|
||||
use_case2_desc:
|
||||
'一行代码,老应用变身Agent,产品专家帮用户操作复杂 B 端软件。降低人工支持成本,提高用户满意度。',
|
||||
use_case3_title: '产品教学:',
|
||||
use_case3_desc:
|
||||
'向用户演示交互过程,边做边教。例如让AI演示「如何提交报销申请」的完整操作流程。',
|
||||
use_case4_title: '无障碍支持:',
|
||||
use_case4_desc:
|
||||
'为视障用户、老年用户提供自然语言交互,对接屏幕阅读器或语音助理,让软件人人可用。',
|
||||
get_started_title: '🚀 开始使用',
|
||||
get_started_desc:
|
||||
'准备好为你的网站添加 AI 操作员了吗?查看我们的快速开始指南,几分钟内完成集成。',
|
||||
get_started_button: '快速开始 →',
|
||||
},
|
||||
quick_start: {
|
||||
title: 'Quick Start',
|
||||
subtitle: '几分钟内完成 page-agent 的集成。',
|
||||
installation: '安装步骤',
|
||||
step1_title: '1. 引入方式',
|
||||
step1_cdn: 'CDN 引入',
|
||||
step1_npm: 'NPM 安装',
|
||||
step2_title: '2. 初始化配置',
|
||||
step3_title: '3. 开始使用',
|
||||
},
|
||||
limitations: {
|
||||
title: '使用限制',
|
||||
subtitle: '了解 page-agent 当前的功能边界和技术限制',
|
||||
page_support: '页面支持限制',
|
||||
spa_limit_title: '单页应用限制',
|
||||
spa_limit_1: '• 仅支持单页应用(SPA):目前只能在单个页面内进行操作',
|
||||
spa_limit_2: '• 多页接力功能正在设计中:暂时无法跨页面执行连续任务',
|
||||
spa_limit_3: '• 无法操作未接入该能力的网站:需要目标网站主动集成 page-agent',
|
||||
interaction_limits: '交互行为限制',
|
||||
supported_ops: '支持的操作',
|
||||
op_click: '点击操作',
|
||||
op_input: '文本输入',
|
||||
op_scroll: '页面滚动',
|
||||
op_submit: '表单提交',
|
||||
op_select: '选择操作',
|
||||
op_focus: '焦点切换',
|
||||
unsupported_ops: '不支持的操作',
|
||||
op_hover: '鼠标悬停(hover)',
|
||||
op_drag: '拖拽操作',
|
||||
op_context: '右键菜单',
|
||||
op_draw: '图形绘制',
|
||||
op_keyboard: '键盘快捷键',
|
||||
op_position: '基于点击区域或鼠标位置的控制',
|
||||
understanding_limits: '网页理解限制',
|
||||
no_vision_title: '无视觉能力',
|
||||
no_vision_desc: 'page-agent 基于 DOM 结构进行理解和操作,没有视觉识别能力,无法理解以下内容:',
|
||||
no_vision_1: '• 图片内容:无法识别图片中的文字、图标或视觉元素',
|
||||
no_vision_2: '• Canvas 画布:无法理解 Canvas 中绘制的图形和内容',
|
||||
no_vision_3: '• WebGL 3D 内容:无法操作 3D 场景中的元素',
|
||||
no_vision_4: '• SVG 图形:无法理解 SVG 中的视觉内容和路径',
|
||||
website_requirements: '被操作网站要求',
|
||||
req_semantic_title: '语义化和易用性',
|
||||
req_semantic_desc:
|
||||
'所有操作都基于 DOM 元素的语义化标签和属性。如果页面结构不够语义化,或者没有任何 accessibility 特性,可能影响 AI 的理解准确性。',
|
||||
req_ux_title: 'UI/UX',
|
||||
req_ux_desc:
|
||||
'反常识的交互规则、基于视觉的操作提示、复杂的鼠标交互、快速出现快速消失的元素等,都会影响 AI 的理解和操作。',
|
||||
req_env_title: '环境要求',
|
||||
req_env_desc: 'modern browser',
|
||||
future: '未来规划',
|
||||
future_title: '即将支持',
|
||||
future_1: '• 多页面接力操作能力',
|
||||
future_2: '• 更丰富的鼠标交互支持',
|
||||
future_3: '• 基础的视觉理解能力',
|
||||
future_4: '• 更智能的错误恢复机制',
|
||||
},
|
||||
model_integration: {
|
||||
title: '模型接入',
|
||||
subtitle: '当前支持符合 OpenAI 接口规范且支持 tool call 的模型,包括公有云服务和私有部署方案。',
|
||||
recommended: '推荐模型',
|
||||
model_gpt4_title: '⚡ gpt-4.1-mini',
|
||||
model_gpt4_badge: '评估基准 ✅',
|
||||
model_gpt4_1: '• 性价比高',
|
||||
model_gpt4_2: '• 速度快',
|
||||
model_gpt4_3: '• 成功率高',
|
||||
model_deepseek_title: '💰 DeepSeek-3.2',
|
||||
model_deepseek_badge: '经济实惠',
|
||||
model_deepseek_1: '• 价格远低于同等级其他模型',
|
||||
model_deepseek_2: '• ToolCall 有出错率,通常能够自动修复',
|
||||
model_deepseek_3: '• 本网站提供的免费试用为 DeepSeek',
|
||||
model_qwen_title: '🛡️ qwen3',
|
||||
model_qwen_badge: '安全合规',
|
||||
model_qwen_1: '• 可控、效果尚可,价格合理',
|
||||
model_qwen_2: '• ToolCall 有出错率,通常能够自动修复',
|
||||
model_qwen_3: '• 适合能给出详细步骤的场景',
|
||||
model_gemini_title: '⚡ gemini-2.5-flash',
|
||||
model_gemini_badge: '极其高效,成功率高,价格合理',
|
||||
available: '可用模型',
|
||||
available_verified: '✅ 已验证可用',
|
||||
tips: '提示',
|
||||
tip_1: 'reasoning 模型(如 GPT-5),速度偏慢,没有必要',
|
||||
tip_2:
|
||||
'不保证 json schema 的模型(openAI 以外的几乎所有模型),tool call 有概率出错,通常能自动修复,建议 temperature 设置高一些',
|
||||
tip_3: '小模型、nano 模型,效果不佳',
|
||||
configuration: '配置方式',
|
||||
},
|
||||
custom_tools: {
|
||||
title: '自定义工具',
|
||||
subtitle:
|
||||
'通过注册自定义工具,扩展 AI Agent 的能力边界。使用 Zod 定义严格的输入接口,让 AI 安全调用你的业务逻辑。',
|
||||
registration: '工具注册',
|
||||
registration_desc:
|
||||
'每个自定义工具需要定义四个核心属性:name、description、input schema 和 execute 函数。',
|
||||
page_filter: '页面过滤器',
|
||||
page_filter_desc: '通过 pageFilter 属性控制工具在哪些页面可见,提升安全性和用户体验。',
|
||||
best_practices: '最佳实践',
|
||||
bp_performance: '⚡ 性能优化',
|
||||
bp_1: '• 使用 pageFilter 减少不必要的工具加载',
|
||||
bp_2: '• 在 execute 函数中实现适当的缓存机制',
|
||||
bp_3: '• 避免在工具中执行耗时的同步操作',
|
||||
},
|
||||
}
|
||||
78
pages/i18n/locales/zh-CN/home.ts
Normal file
78
pages/i18n/locales/zh-CN/home.ts
Normal file
@@ -0,0 +1,78 @@
|
||||
export default {
|
||||
hero: {
|
||||
badge: 'GUI Agent in your webpage',
|
||||
title_line1: '让你的 Web 应用',
|
||||
title_line2: '拥有 AI 操作员',
|
||||
subtitle_emoji: '🪄 一行 CDN 引入',
|
||||
subtitle_main: ',为你的网站添加智能 UI Agent。',
|
||||
subtitle_detail: '用户/答疑机器人给出文字指示,AI 帮你操作页面。',
|
||||
tab_try: '🚀 立即尝试',
|
||||
tab_other: '🌐 其他网页尝试',
|
||||
input_placeholder: '输入您想要 AI 执行的任务...',
|
||||
execute_button: '执行',
|
||||
default_task: '进入文档页,打开数据脱敏相关的文档,帮我总结成 markdown',
|
||||
},
|
||||
try_other: {
|
||||
step1_title: '步骤 1:',
|
||||
step1_content: '显示收藏夹栏',
|
||||
step2_title: '步骤 2:',
|
||||
step2_content: '拖拽下面按钮到收藏夹栏',
|
||||
step3_title: '步骤 3:',
|
||||
step3_content: '在其他网站点击收藏夹中的按钮即可使用',
|
||||
notice_title: '⚠️ 注意',
|
||||
notice_items: {
|
||||
item1: '仅做技术评估,链接定期失效',
|
||||
item2: '使用 DeepSeek 模型,参考 DeepSeek 用户协议和隐私政策',
|
||||
item3: '部分网站屏蔽了链接嵌入,将无反应',
|
||||
item4: '仅支持单页应用,页面跳转后需要重新注入',
|
||||
item5: '仅识别文本,不识别图像,不支持拖拽等复杂交互',
|
||||
item6_prefix: '详细使用限制参照',
|
||||
item6_link: '《文档》',
|
||||
},
|
||||
},
|
||||
benefits: {
|
||||
no_backend: '无需后端',
|
||||
private_model: '支持私有模型',
|
||||
data_masking: '无痛脱敏',
|
||||
open_source: 'MIT 开源',
|
||||
},
|
||||
features: {
|
||||
section_title: '核心特性',
|
||||
dom_understanding: {
|
||||
title: '智能 DOM 理解',
|
||||
desc: '基于 DOM 分析,高强度脱水。无需视觉识别,纯文本实现精准操作。',
|
||||
},
|
||||
secure_integration: {
|
||||
title: '安全可控集成',
|
||||
desc: '支持操作黑白名单、数据脱敏保护。注入自定义知识库,让 AI 按你的规则工作。',
|
||||
},
|
||||
zero_backend: {
|
||||
title: '零后端部署',
|
||||
desc: 'CDN 直接引入,自定义 LLM 接入点。从 OpenAI 到 qwen3,完全由你掌控。',
|
||||
},
|
||||
accessible: {
|
||||
title: '普惠智能交互',
|
||||
desc: '为复杂 B端系统、管理后台提供自然语言入口。让每个用户都能轻松上手。',
|
||||
},
|
||||
},
|
||||
use_cases: {
|
||||
section_title: '应用场景',
|
||||
section_subtitle: '从简单的表单填写到复杂的业务流程,AI 都能理解并执行',
|
||||
case1: {
|
||||
title: '对接答疑机器人',
|
||||
desc: '把你的答疑助手变成全能Agent。客服机器人不再只说「请先点击设置按钮然后点击...」,而是直接帮用户现场操作。',
|
||||
},
|
||||
case2: {
|
||||
title: '交互升级/智能化改造',
|
||||
desc: '一行代码,老应用变身Agent,产品专家帮用户操作复杂 B 端软件。降低人工支持成本,提高用户满意度。',
|
||||
},
|
||||
case3: {
|
||||
title: '产品教学',
|
||||
desc: '向用户演示交互过程,边做边教。例如让AI演示「如何提交报销申请」的完整操作流程。',
|
||||
},
|
||||
case4: {
|
||||
title: '无障碍支持',
|
||||
desc: '为视障用户、老年用户提供自然语言交互,对接屏幕阅读器或语音助理,让软件人人可用。',
|
||||
},
|
||||
},
|
||||
}
|
||||
16
pages/i18n/types.ts
Normal file
16
pages/i18n/types.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import 'react-i18next'
|
||||
|
||||
import type commonZh from './locales/zh-CN/common'
|
||||
import type docsZh from './locales/zh-CN/docs'
|
||||
import type homeZh from './locales/zh-CN/home'
|
||||
|
||||
declare module 'react-i18next' {
|
||||
interface CustomTypeOptions {
|
||||
defaultNS: 'common'
|
||||
resources: {
|
||||
common: typeof commonZh
|
||||
home: typeof homeZh
|
||||
docs: typeof docsZh
|
||||
}
|
||||
}
|
||||
}
|
||||
175
pages/index.css
175
pages/index.css
@@ -1,5 +1,8 @@
|
||||
@import 'tailwindcss';
|
||||
|
||||
/* 启用 class-based dark mode for Tailwind v4 */
|
||||
@variant dark (.dark &);
|
||||
|
||||
:root {
|
||||
--background: #ffffff;
|
||||
--foreground: #171717;
|
||||
@@ -8,12 +11,21 @@
|
||||
--theme-color-2: rgb(189, 69, 251);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
/* class-based dark mode - 应用到 html.dark */
|
||||
html.dark,
|
||||
:root.dark {
|
||||
--background: #0a0a0a;
|
||||
--foreground: #ededed;
|
||||
}
|
||||
|
||||
/* 同时支持系统偏好 */
|
||||
/* @media (prefers-color-scheme: dark) {
|
||||
html:not(.light),
|
||||
:root:not(.light) {
|
||||
--background: #0a0a0a;
|
||||
--foreground: #ededed;
|
||||
}
|
||||
} */
|
||||
|
||||
/* 添加 Tailwind 自定义颜色 */
|
||||
@theme {
|
||||
@@ -21,13 +33,162 @@
|
||||
--color-foreground: var(--foreground);
|
||||
}
|
||||
|
||||
@theme inline {
|
||||
--color-background: var(--background);
|
||||
--color-foreground: var(--foreground);
|
||||
}
|
||||
|
||||
body {
|
||||
background: var(--background);
|
||||
color: var(--foreground);
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
}
|
||||
|
||||
/* 确保文档页面标题在暗色模式下可见 - 只针对 prose 内的标题 */
|
||||
.prose h1,
|
||||
.prose h2,
|
||||
.prose h3,
|
||||
.prose h4,
|
||||
.prose h5,
|
||||
.prose h6 {
|
||||
color: rgba(23, 23, 23, 0.85);
|
||||
}
|
||||
|
||||
.dark .prose h1,
|
||||
.dark .prose h2,
|
||||
.dark .prose h3,
|
||||
.dark .prose h4,
|
||||
.dark .prose h5,
|
||||
.dark .prose h6 {
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
}
|
||||
|
||||
table,
|
||||
th,
|
||||
td {
|
||||
color: #171717;
|
||||
}
|
||||
|
||||
.dark table,
|
||||
.dark th,
|
||||
.dark td {
|
||||
color: #ededed;
|
||||
}
|
||||
|
||||
/* 文档页深色模式优化 */
|
||||
.dark .prose {
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
|
||||
/* @media (prefers-color-scheme: dark) {
|
||||
:root:not(.light) .prose {
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
} */
|
||||
|
||||
.dark .dark\:prose-invert {
|
||||
--tw-prose-body: rgba(255, 255, 255, 0.7);
|
||||
--tw-prose-headings: rgba(255, 255, 255, 0.95);
|
||||
--tw-prose-lead: rgba(255, 255, 255, 0.7);
|
||||
--tw-prose-links: rgba(147, 197, 253, 0.9);
|
||||
--tw-prose-bold: rgba(255, 255, 255, 0.9);
|
||||
--tw-prose-counters: rgba(255, 255, 255, 0.6);
|
||||
--tw-prose-bullets: rgba(255, 255, 255, 0.5);
|
||||
--tw-prose-hr: rgba(255, 255, 255, 0.2);
|
||||
--tw-prose-quotes: rgba(255, 255, 255, 0.8);
|
||||
--tw-prose-quote-borders: rgba(255, 255, 255, 0.3);
|
||||
--tw-prose-captions: rgba(255, 255, 255, 0.6);
|
||||
--tw-prose-code: rgba(255, 255, 255, 0.9);
|
||||
--tw-prose-pre-code: rgba(255, 255, 255, 0.95);
|
||||
--tw-prose-pre-bg: rgba(0, 0, 0, 0.5);
|
||||
--tw-prose-th-borders: rgba(255, 255, 255, 0.3);
|
||||
--tw-prose-td-borders: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
/* @media (prefers-color-scheme: dark) {
|
||||
:root:not(.light) .dark\:prose-invert {
|
||||
--tw-prose-body: rgba(255, 255, 255, 0.7);
|
||||
--tw-prose-headings: rgba(255, 255, 255, 0.95);
|
||||
--tw-prose-lead: rgba(255, 255, 255, 0.7);
|
||||
--tw-prose-links: rgba(147, 197, 253, 0.9);
|
||||
--tw-prose-bold: rgba(255, 255, 255, 0.9);
|
||||
--tw-prose-counters: rgba(255, 255, 255, 0.6);
|
||||
--tw-prose-bullets: rgba(255, 255, 255, 0.5);
|
||||
--tw-prose-hr: rgba(255, 255, 255, 0.2);
|
||||
--tw-prose-quotes: rgba(255, 255, 255, 0.8);
|
||||
--tw-prose-quote-borders: rgba(255, 255, 255, 0.3);
|
||||
--tw-prose-captions: rgba(255, 255, 255, 0.6);
|
||||
--tw-prose-code: rgba(255, 255, 255, 0.9);
|
||||
--tw-prose-pre-code: rgba(255, 255, 255, 0.95);
|
||||
--tw-prose-pre-bg: rgba(0, 0, 0, 0.5);
|
||||
--tw-prose-th-borders: rgba(255, 255, 255, 0.3);
|
||||
--tw-prose-td-borders: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
} */
|
||||
|
||||
/* 标题更清晰 */
|
||||
.dark .prose h1,
|
||||
.dark .prose h2,
|
||||
.dark .prose h3,
|
||||
.dark .prose h4 {
|
||||
color: rgba(255, 255, 255, 0.95);
|
||||
}
|
||||
|
||||
/* @media (prefers-color-scheme: dark) {
|
||||
:root:not(.light) .prose h1,
|
||||
:root:not(.light) .prose h2,
|
||||
:root:not(.light) .prose h3,
|
||||
:root:not(.light) .prose h4 {
|
||||
color: rgba(255, 255, 255, 0.95);
|
||||
}
|
||||
} */
|
||||
|
||||
/* 链接更清晰 */
|
||||
.dark .prose a {
|
||||
color: rgba(147, 197, 253, 0.9);
|
||||
}
|
||||
|
||||
/* @media (prefers-color-scheme: dark) {
|
||||
:root:not(.light) .prose a {
|
||||
color: rgba(147, 197, 253, 0.9);
|
||||
}
|
||||
} */
|
||||
|
||||
/* 代码块背景更黑 */
|
||||
.dark .prose pre {
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
|
||||
/* @media (prefers-color-scheme: dark) {
|
||||
:root:not(.light) .prose pre {
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
} */
|
||||
|
||||
/* 表格样式 */
|
||||
.dark .prose table {
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
|
||||
/* @media (prefers-color-scheme: dark) {
|
||||
:root:not(.light) .prose table {
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
} */
|
||||
|
||||
.dark .prose thead {
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
border-bottom-color: rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
|
||||
/* @media (prefers-color-scheme: dark) {
|
||||
:root:not(.light) .prose thead {
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
border-bottom-color: rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
} */
|
||||
|
||||
.dark .prose tbody tr {
|
||||
border-bottom-color: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
/* @media (prefers-color-scheme: dark) {
|
||||
:root:not(.light) .prose tbody tr {
|
||||
border-bottom-color: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
} */
|
||||
|
||||
@@ -2,6 +2,8 @@ import { createRoot } from 'react-dom/client'
|
||||
import { Route, Router, Switch } from 'wouter'
|
||||
import { useHashLocation } from 'wouter/use-hash-location'
|
||||
|
||||
import './i18n/config'
|
||||
import './i18n/types'
|
||||
import { default as PagesRouter } from './router.tsx'
|
||||
import { default as TestPagesRouter } from './test-pages/router.tsx'
|
||||
|
||||
|
||||
120
pages/page.tsx
120
pages/page.tsx
@@ -1,5 +1,6 @@
|
||||
/* eslint-disable react-dom/no-dangerously-set-innerhtml */
|
||||
import { useState } from 'react'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Link, useSearchParams } from 'wouter'
|
||||
|
||||
import { PageAgent } from '@/PageAgent.js'
|
||||
@@ -25,7 +26,14 @@ const injectionA = `
|
||||
`
|
||||
|
||||
export default function HomePage() {
|
||||
const [task, setTask] = useState('进入文档页,打开数据脱敏相关的文档,帮我总结成 markdown')
|
||||
const { t, i18n } = useTranslation(['home', 'common'])
|
||||
const [task, setTask] = useState(() => t('home:hero.default_task'))
|
||||
|
||||
// Update task when language changes
|
||||
const defaultTask = t('home:hero.default_task')
|
||||
useEffect(() => {
|
||||
setTask(defaultTask)
|
||||
}, [defaultTask])
|
||||
|
||||
const [params, setParams] = useSearchParams()
|
||||
const isOther = params.has('try_other')
|
||||
@@ -79,25 +87,25 @@ export default function HomePage() {
|
||||
className="w-2 h-2 bg-blue-500 rounded-full mr-2 animate-pulse"
|
||||
aria-hidden="true"
|
||||
></span>
|
||||
UI Agent in your webpage
|
||||
{t('home:hero.badge')}
|
||||
</div>
|
||||
|
||||
<h1
|
||||
id="hero-heading"
|
||||
className="text-5xl lg:text-7xl font-bold mb-8 bg-gradient-to-r from-blue-600 to-purple-600 bg-clip-text text-transparent"
|
||||
>
|
||||
让你的 Web 应用
|
||||
{t('home:hero.title_line1')}
|
||||
<br />
|
||||
拥有 AI 操作员
|
||||
{t('home:hero.title_line2')}
|
||||
</h1>
|
||||
|
||||
<p className="text-xl lg:text-2xl text-gray-600 dark:text-gray-300 mb-12 max-w-4xl mx-auto leading-relaxed">
|
||||
<span className="bg-gradient-to-r from-blue-500 to-purple-500 bg-clip-text text-transparent font-bold">
|
||||
🪄 一行 CDN 引入
|
||||
{t('home:hero.subtitle_emoji')}
|
||||
</span>
|
||||
,为你的网站添加智能 UI Agent。
|
||||
{t('home:hero.subtitle_main')}
|
||||
<br />
|
||||
用户/答疑机器人给出文字指示,AI 帮你操作页面。
|
||||
{t('home:hero.subtitle_detail')}
|
||||
</p>
|
||||
|
||||
{/* Try It Now Section - Tab Card */}
|
||||
@@ -114,7 +122,7 @@ export default function HomePage() {
|
||||
: 'text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white hover:bg-gray-50 dark:hover:bg-gray-700'
|
||||
}`}
|
||||
>
|
||||
🚀 立即尝试
|
||||
{t('home:hero.tab_try')}
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setActiveTab('other')}
|
||||
@@ -124,7 +132,7 @@ export default function HomePage() {
|
||||
: 'text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white hover:bg-gray-50 dark:hover:bg-gray-700'
|
||||
}`}
|
||||
>
|
||||
🌐 其他网页尝试
|
||||
{t('home:hero.tab_other')}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -136,7 +144,7 @@ export default function HomePage() {
|
||||
<input
|
||||
value={task}
|
||||
onChange={(e) => setTask(e.target.value)}
|
||||
placeholder="输入您想要 AI 执行的任务..."
|
||||
placeholder={t('home:hero.input_placeholder')}
|
||||
className="w-full px-4 py-3 pr-20 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white placeholder-gray-500 dark:placeholder-gray-400 focus:ring-2 focus:ring-blue-500 focus:border-transparent resize-none text-sm mb-0"
|
||||
data-page-agent-not-interactive
|
||||
/>
|
||||
@@ -147,7 +155,7 @@ export default function HomePage() {
|
||||
className="absolute right-2 top-2 px-5 py-1.5 bg-gradient-to-r from-blue-600 to-purple-600 text-white font-medium rounded-md hover:shadow-md transform hover:scale-105 transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed disabled:transform-none text-sm"
|
||||
data-page-agent-not-interactive
|
||||
>
|
||||
执行
|
||||
{t('home:hero.execute_button')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -160,7 +168,10 @@ export default function HomePage() {
|
||||
{/* Keyboard Shortcut Hint */}
|
||||
<div className="bg-blue-50 dark:bg-gray-700 p-4 rounded-lg">
|
||||
<p className="text-gray-700 dark:text-gray-300 text-sm mb-3">
|
||||
<span className="font-semibold">步骤 1:</span> 显示收藏夹栏
|
||||
<span className="font-semibold">
|
||||
{t('home:try_other.step1_title')}
|
||||
</span>{' '}
|
||||
{t('home:try_other.step1_content')}
|
||||
</p>
|
||||
<div className="flex items-center justify-center gap-2">
|
||||
<kbd className="px-2 py-1 bg-white dark:bg-gray-600 border border-gray-300 dark:border-gray-500 rounded text-xs font-mono">
|
||||
@@ -176,8 +187,10 @@ export default function HomePage() {
|
||||
{/* Draggable Bookmarklet */}
|
||||
<div className="bg-green-50 dark:bg-gray-700 p-4 rounded-lg">
|
||||
<p className="text-gray-700 dark:text-gray-300 text-sm mb-3">
|
||||
<span className="font-semibold">步骤 2:</span>{' '}
|
||||
拖拽下面按钮到收藏夹栏
|
||||
<span className="font-semibold">
|
||||
{t('home:try_other.step2_title')}
|
||||
</span>{' '}
|
||||
{t('home:try_other.step2_content')}
|
||||
</p>
|
||||
<div
|
||||
className="flex items-center justify-center gap-2 text-gray-500 dark:text-gray-400"
|
||||
@@ -188,8 +201,10 @@ export default function HomePage() {
|
||||
{/* Usage Instructions */}
|
||||
<div className="bg-purple-50 dark:bg-gray-700 p-4 rounded-lg">
|
||||
<p className="text-gray-700 dark:text-gray-300 text-sm">
|
||||
<span className="font-semibold">步骤 3:</span>{' '}
|
||||
在其他网站点击收藏夹中的按钮即可使用
|
||||
<span className="font-semibold">
|
||||
{t('home:try_other.step3_title')}
|
||||
</span>{' '}
|
||||
{t('home:try_other.step3_content')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -197,37 +212,37 @@ export default function HomePage() {
|
||||
{/* 右侧:注意事项 */}
|
||||
<div className="bg-yellow-50 dark:bg-gray-700 p-4 rounded-lg">
|
||||
<h4 className="font-semibold text-gray-900 dark:text-white mb-3 text-sm">
|
||||
⚠️ 注意
|
||||
{t('home:try_other.notice_title')}
|
||||
</h4>
|
||||
<ul className="space-y-2 text-sm text-gray-700 dark:text-gray-300">
|
||||
<li className="flex items-start text-left">
|
||||
<span className="w-1.5 h-1.5 bg-yellow-500 rounded-full mt-2 mr-2 flex-shrink-0 "></span>
|
||||
仅做技术评估,链接定期失效
|
||||
{t('home:try_other.notice_items.item1')}
|
||||
</li>
|
||||
<li className="flex items-start text-left">
|
||||
<span className="w-1.5 h-1.5 bg-yellow-500 rounded-full mt-2 mr-2 flex-shrink-0 "></span>
|
||||
使用 DeepSeek 模型,参考 DeepSeek 用户协议和隐私政策
|
||||
{t('home:try_other.notice_items.item2')}
|
||||
</li>
|
||||
<li className="flex items-start text-left">
|
||||
<span className="w-1.5 h-1.5 bg-yellow-500 rounded-full mt-2 mr-2 flex-shrink-0 "></span>
|
||||
部分网站屏蔽了链接嵌入,将无反应
|
||||
{t('home:try_other.notice_items.item3')}
|
||||
</li>
|
||||
<li className="flex items-start text-left">
|
||||
<span className="w-1.5 h-1.5 bg-yellow-500 rounded-full mt-2 mr-2 flex-shrink-0 "></span>
|
||||
仅支持单页应用,页面跳转后需要重新注入
|
||||
{t('home:try_other.notice_items.item4')}
|
||||
</li>
|
||||
<li className="flex items-start text-left">
|
||||
<span className="w-1.5 h-1.5 bg-yellow-500 rounded-full mt-2 mr-2 flex-shrink-0 "></span>
|
||||
仅识别文本,不识别图像,不支持拖拽等复杂交互
|
||||
{t('home:try_other.notice_items.item5')}
|
||||
</li>
|
||||
<li className="flex items-start text-left">
|
||||
<span className="w-1.5 h-1.5 bg-yellow-500 rounded-full mt-2 mr-2 flex-shrink-0 "></span>
|
||||
详细使用限制参照{' '}
|
||||
{t('home:try_other.notice_items.item6_prefix')}{' '}
|
||||
<Link
|
||||
href="/docs/introduction/limitations"
|
||||
className="text-blue-600 dark:text-blue-400 hover:underline"
|
||||
>
|
||||
《文档》
|
||||
{t('home:try_other.notice_items.item6_link')}
|
||||
</Link>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -248,28 +263,28 @@ export default function HomePage() {
|
||||
className="w-2 h-2 bg-green-500 rounded-full mr-2"
|
||||
aria-hidden="true"
|
||||
></span>
|
||||
无需后端
|
||||
{t('home:benefits.no_backend')}
|
||||
</li>
|
||||
<li className="flex items-center">
|
||||
<span
|
||||
className="w-2 h-2 bg-green-500 rounded-full mr-2"
|
||||
aria-hidden="true"
|
||||
></span>
|
||||
支持私有模型
|
||||
{t('home:benefits.private_model')}
|
||||
</li>
|
||||
<li className="flex items-center">
|
||||
<span
|
||||
className="w-2 h-2 bg-green-500 rounded-full mr-2"
|
||||
aria-hidden="true"
|
||||
></span>
|
||||
无痛脱敏
|
||||
{t('home:benefits.data_masking')}
|
||||
</li>
|
||||
<li className="flex items-center">
|
||||
<span
|
||||
className="w-2 h-2 bg-green-500 rounded-full mr-2"
|
||||
aria-hidden="true"
|
||||
></span>
|
||||
DOM 智能操作
|
||||
{t('home:benefits.open_source')}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -295,10 +310,10 @@ export default function HomePage() {
|
||||
<span className="text-white text-xl">🧠</span>
|
||||
</div>
|
||||
<h3 className="text-xl font-bold mb-4 text-gray-900 dark:text-white">
|
||||
智能 DOM 理解
|
||||
{t('home:features.dom_understanding.title')}
|
||||
</h3>
|
||||
<p className="text-gray-600 dark:text-gray-300 leading-relaxed">
|
||||
基于 DOM 分析,高强度脱水。无需视觉识别,纯文本实现精准操作。
|
||||
{t('home:features.dom_understanding.desc')}
|
||||
</p>
|
||||
</article>
|
||||
|
||||
@@ -314,10 +329,10 @@ export default function HomePage() {
|
||||
<span className="text-white text-xl">🔒</span>
|
||||
</div>
|
||||
<h3 className="text-xl font-bold mb-4 text-gray-900 dark:text-white">
|
||||
安全可控集成
|
||||
{t('home:features.secure_integration.title')}
|
||||
</h3>
|
||||
<p className="text-gray-600 dark:text-gray-300 leading-relaxed">
|
||||
支持操作黑白名单、数据脱敏保护。注入自定义知识库,让 AI 按你的规则工作。
|
||||
{t('home:features.secure_integration.desc')}
|
||||
</p>
|
||||
</article>
|
||||
|
||||
@@ -332,9 +347,11 @@ export default function HomePage() {
|
||||
>
|
||||
<span className="text-white text-xl">⚡</span>
|
||||
</div>
|
||||
<h3 className="text-xl font-bold mb-4 text-gray-900 dark:text-white">零后端部署</h3>
|
||||
<h3 className="text-xl font-bold mb-4 text-gray-900 dark:text-white">
|
||||
{t('home:features.zero_backend.title')}
|
||||
</h3>
|
||||
<p className="text-gray-600 dark:text-gray-300 leading-relaxed">
|
||||
CDN 直接引入,自定义 LLM 接入点。从 OpenAI 到 qwen3,完全由你掌控。
|
||||
{t('home:features.zero_backend.desc')}
|
||||
</p>
|
||||
</article>
|
||||
|
||||
@@ -350,10 +367,10 @@ export default function HomePage() {
|
||||
<span className="text-white text-xl">♿</span>
|
||||
</div>
|
||||
<h3 className="text-xl font-bold mb-4 text-gray-900 dark:text-white">
|
||||
普惠智能交互
|
||||
{t('home:features.accessible.title')}
|
||||
</h3>
|
||||
<p className="text-gray-600 dark:text-gray-300 leading-relaxed">
|
||||
为复杂 B端系统、管理后台提供自然语言入口。让每个用户都能轻松上手。
|
||||
{t('home:features.accessible.desc')}
|
||||
</p>
|
||||
</article>
|
||||
</div>
|
||||
@@ -368,27 +385,27 @@ export default function HomePage() {
|
||||
id="use-cases-heading"
|
||||
className="text-4xl lg:text-5xl mb-6 text-gray-900 dark:text-white"
|
||||
>
|
||||
应用场景
|
||||
{t('home:use_cases.section_title')}
|
||||
</h2>
|
||||
<p className="text-xl text-gray-600 dark:text-gray-300 max-w-3xl mx-auto">
|
||||
从简单的表单填写到复杂的业务流程,AI 都能理解并执行
|
||||
{t('home:use_cases.section_subtitle')}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid lg:grid-cols-2 gap-12" role="list">
|
||||
{/* Use Case 1 */}
|
||||
<div className="bg-gradient-to-br from-blue-100 to-purple-100 dark:from-gray-700 dark:to-gray-800 p-8 rounded-2xl">
|
||||
<div className="flex items-start space-x-4 h-20">
|
||||
<div className="flex items-start space-x-4">
|
||||
<div className="w-10 h-10 bg-blue-500 rounded-lg flex items-center justify-center flex-shrink-0">
|
||||
<span className="text-white font-bold">1</span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-xl font-bold mb-2 text-gray-900 dark:text-white">
|
||||
对接答疑机器人
|
||||
{t('home:use_cases.case1.title')}
|
||||
</h3>
|
||||
<p className="text-gray-600 dark:text-gray-300">
|
||||
把你的答疑助手变成全能Agent。客服机器人不再只说"请先点击设置按钮然后点击...",而是直接帮用户现场操作。
|
||||
{t('home:use_cases.case1.desc')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -396,17 +413,16 @@ export default function HomePage() {
|
||||
|
||||
{/* Use Case 2 */}
|
||||
<div className="bg-gradient-to-br from-green-100 to-blue-100 dark:from-gray-700 dark:to-gray-800 p-8 rounded-2xl">
|
||||
<div className="flex items-start space-x-4 h-20">
|
||||
<div className="flex items-start space-x-4">
|
||||
<div className="w-10 h-10 bg-green-500 rounded-lg flex items-center justify-center flex-shrink-0">
|
||||
<span className="text-white font-bold">2</span>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-xl font-bold mb-2 text-gray-900 dark:text-white">
|
||||
交互升级/智能化改造
|
||||
{t('home:use_cases.case2.title')}
|
||||
</h3>
|
||||
<p className="text-gray-600 dark:text-gray-300">
|
||||
一行代码,老应用变身Agent,产品专家帮用户操作复杂 B
|
||||
端软件。降低人工支持成本,提高用户满意度。
|
||||
{t('home:use_cases.case2.desc')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -414,16 +430,16 @@ export default function HomePage() {
|
||||
|
||||
{/* Use Case 3 */}
|
||||
<div className="bg-gradient-to-br from-purple-100 to-pink-100 dark:from-gray-700 dark:to-gray-800 p-8 rounded-2xl">
|
||||
<div className="flex items-start space-x-4 h-20">
|
||||
<div className="flex items-start space-x-4">
|
||||
<div className="w-10 h-10 bg-purple-500 rounded-lg flex items-center justify-center flex-shrink-0">
|
||||
<span className="text-white font-bold">3</span>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-xl font-bold mb-2 text-gray-900 dark:text-white">
|
||||
产品教学
|
||||
{t('home:use_cases.case3.title')}
|
||||
</h3>
|
||||
<p className="text-gray-600 dark:text-gray-300">
|
||||
向用户演示交互过程,边做边教。例如让AI演示"如何提交报销申请"的完整操作流程。
|
||||
{t('home:use_cases.case3.desc')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -431,16 +447,16 @@ export default function HomePage() {
|
||||
|
||||
{/* Use Case 4 */}
|
||||
<div className="bg-gradient-to-br from-orange-100 to-red-100 dark:from-gray-700 dark:to-gray-800 p-8 rounded-2xl">
|
||||
<div className="flex items-start space-x-4 h-20">
|
||||
<div className="flex items-start space-x-4">
|
||||
<div className="w-10 h-10 bg-orange-500 rounded-lg flex items-center justify-center flex-shrink-0">
|
||||
<span className="text-white font-bold">4</span>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-xl font-bold mb-2 text-gray-900 dark:text-white">
|
||||
无障碍支持
|
||||
{t('home:use_cases.case4.title')}
|
||||
</h3>
|
||||
<p className="text-gray-600 dark:text-gray-300">
|
||||
为视障用户、老年用户提供自然语言交互,对接屏幕阅读器或语音助理,让软件人人可用。
|
||||
{t('home:use_cases.case4.desc')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user