refactor: monorepo
This commit is contained in:
104
packages/website/src/docs/features/custom-tools/page.tsx
Normal file
104
packages/website/src/docs/features/custom-tools/page.tsx
Normal file
@@ -0,0 +1,104 @@
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
import BetaNotice from '@/components/BetaNotice'
|
||||
import CodeEditor from '@/components/CodeEditor'
|
||||
|
||||
export default function CustomTools() {
|
||||
const { t } = useTranslation('docs')
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h1 className="text-4xl font-bold mb-6">{t('custom_tools.title')}</h1>
|
||||
|
||||
<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">{t('custom_tools.registration')}</h2>
|
||||
<p className="text-gray-600 dark:text-gray-300 mb-4">
|
||||
{t('custom_tools.registration_desc')}
|
||||
</p>
|
||||
|
||||
<CodeEditor
|
||||
code={`import zod from 'zod'
|
||||
import { PageAgent, tool } from 'page-agent'
|
||||
|
||||
// override internal tool
|
||||
const customTools = {
|
||||
ask_user: tool({
|
||||
description:
|
||||
'Ask the user or parent model a question and wait for their answer. Use this if you need more information or clarification.',
|
||||
inputSchema: zod.object({
|
||||
question: zod.string(),
|
||||
}),
|
||||
execute: async function (this: PageAgent, input) {
|
||||
const answer = await do_some_thing(input.question)
|
||||
return "✅ Received user answer: " + answer
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// remove internal tool
|
||||
const customTools = {
|
||||
ask_user: null // never ask user questions
|
||||
}
|
||||
|
||||
const pageAgent = new PageAgent({customTools})
|
||||
`}
|
||||
language="javascript"
|
||||
/>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 className="text-2xl font-bold mb-4">{t('custom_tools.page_filter')}</h2>
|
||||
|
||||
<BetaNotice />
|
||||
|
||||
<p className="text-gray-600 dark:text-gray-300 mb-4">
|
||||
{t('custom_tools.page_filter_desc')}
|
||||
</p>
|
||||
|
||||
<CodeEditor
|
||||
code={`pageAgent.registerTool({
|
||||
name: 'approveOrder',
|
||||
description: '审批订单',
|
||||
input: z.object({
|
||||
orderId: z.string(),
|
||||
approved: z.boolean()
|
||||
}),
|
||||
execute: async (params) => {
|
||||
// 审批逻辑
|
||||
},
|
||||
// 可选:页面过滤器
|
||||
pageFilter: {
|
||||
// 只在订单管理页面显示
|
||||
include: ['/admin/orders', '/admin/orders/*'],
|
||||
// 排除特定页面
|
||||
exclude: ['/admin/orders/archived']
|
||||
}
|
||||
})`}
|
||||
language="javascript"
|
||||
/>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<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-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>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
48
packages/website/src/docs/features/data-masking/page.tsx
Normal file
48
packages/website/src/docs/features/data-masking/page.tsx
Normal file
@@ -0,0 +1,48 @@
|
||||
import BetaNotice from '@/components/BetaNotice'
|
||||
import CodeEditor from '@/components/CodeEditor'
|
||||
|
||||
export default function DataMasking() {
|
||||
return (
|
||||
<div>
|
||||
<h1 className="text-4xl font-bold mb-6">数据脱敏</h1>
|
||||
|
||||
<BetaNotice />
|
||||
|
||||
<p className="text-xl text-gray-600 dark:text-gray-300 mb-6 leading-relaxed">
|
||||
保护敏感数据,确保 AI 处理过程中的数据安全。
|
||||
</p>
|
||||
|
||||
<h2 className="text-2xl font-bold mb-3">脱敏策略</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">
|
||||
🔒 自动脱敏
|
||||
</h3>
|
||||
<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-gray-600 dark:text-gray-300">
|
||||
支持自定义脱敏规则,适应不同业务场景的数据保护需求。
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<CodeEditor
|
||||
code={`// 数据脱敏配置
|
||||
// @todo
|
||||
const rules = [
|
||||
{ pattern: /\\d{11}/, replacement: '***-****-****' },
|
||||
{ pattern: /\\d{4}-\\d{4}-\\d{4}-\\d{4}/, replacement: '****-****-****-****' }
|
||||
]
|
||||
pageAgent.maskData(rules)`}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
162
packages/website/src/docs/features/knowledge-injection/page.tsx
Normal file
162
packages/website/src/docs/features/knowledge-injection/page.tsx
Normal file
@@ -0,0 +1,162 @@
|
||||
import BetaNotice from '@/components/BetaNotice'
|
||||
import CodeEditor from '@/components/CodeEditor'
|
||||
|
||||
export default function KnowledgeInjection() {
|
||||
return (
|
||||
<div>
|
||||
<h1 className="text-4xl font-bold mb-6">知识库注入</h1>
|
||||
|
||||
<BetaNotice />
|
||||
|
||||
<p className="text-xl text-gray-600 dark:text-gray-300 mb-8 leading-relaxed">
|
||||
通过多层次的知识注入,让 AI 深度理解你的业务场景和应用逻辑,实现更精准的自动化操作。
|
||||
</p>
|
||||
|
||||
{/* Custom Instruction */}
|
||||
<section className="mb-12">
|
||||
<h2 className="text-3xl font-bold mb-6">Instruction - 系统指令</h2>
|
||||
|
||||
<div className="p-6 bg-purple-50 dark:bg-purple-900/20 rounded-lg mb-6">
|
||||
<h3 className="text-xl font-semibold mb-3 text-purple-900 dark:text-purple-300">
|
||||
🎯 系统级指令
|
||||
</h3>
|
||||
<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>
|
||||
<li>配置输出格式和反馈机制</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<CodeEditor
|
||||
className="mb-6"
|
||||
code={`// 构造函数中设置系统指令
|
||||
const pageAgent = new PageAgent({
|
||||
instruction: \`
|
||||
# 角色定义
|
||||
你是专业的电商运营助手。
|
||||
|
||||
# 工作风格
|
||||
- 谨慎:操作前确认
|
||||
- 准确:确保正确性
|
||||
- 高效:优化流程
|
||||
|
||||
# 错误处理
|
||||
遇到错误时暂停并报告。
|
||||
\`
|
||||
});`}
|
||||
/>
|
||||
</section>
|
||||
|
||||
{/* App Knowledge */}
|
||||
<section className="mb-12">
|
||||
<h2 className="text-3xl font-bold mb-6">App Knowledge - 应用知识</h2>
|
||||
|
||||
<div className="p-6 bg-blue-50 dark:bg-blue-900/20 rounded-lg mb-6">
|
||||
<h3 className="text-xl font-semibold mb-3 text-blue-900 dark:text-blue-300">
|
||||
<EFBFBD> 业务领域知识
|
||||
</h3>
|
||||
<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-gray-500 dark:text-gray-400 space-y-1">
|
||||
<li>产品功能和特性介绍</li>
|
||||
<li>用户角色和权限体系</li>
|
||||
<li>业务规则和约束条件</li>
|
||||
</ul>
|
||||
</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-gray-500 dark:text-gray-400 space-y-1">
|
||||
<li>标准操作流程定义</li>
|
||||
<li>异常情况处理方案</li>
|
||||
<li>术语和概念解释</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<CodeEditor
|
||||
className="mb-6"
|
||||
code={`// 应用知识
|
||||
pageAgent.knowledge.setAppKnowledge(\`
|
||||
# 产品介绍
|
||||
电商管理系统:面向中小企业的一站式解决方案。
|
||||
|
||||
# 操作流程
|
||||
## 商品上架
|
||||
1. 进入商品管理页面 2. 点击新增商品 3. 填写基本信息 4. 设置库存 5. 提交审核
|
||||
|
||||
# 术语解释
|
||||
- SKU:库存量单位
|
||||
- SPU:标准产品单位
|
||||
- 运费模板:物流费用计算规则
|
||||
|
||||
# 业务规则
|
||||
- 库存为0时自动下架
|
||||
- VIP会员享9.5折
|
||||
\`);`}
|
||||
/>
|
||||
</section>
|
||||
|
||||
{/* Page Knowledge */}
|
||||
<section className="mb-12">
|
||||
<h2 className="text-3xl font-bold mb-6">Page Knowledge - 页面知识</h2>
|
||||
|
||||
<div className="p-6 bg-green-50 dark:bg-green-900/20 rounded-lg mb-6">
|
||||
<h3 className="text-xl font-semibold mb-3 text-green-900 dark:text-green-300">
|
||||
📄 页面级精准指导
|
||||
</h3>
|
||||
<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-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-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-gray-500 dark:text-gray-400">
|
||||
说明页面的业务逻辑和状态变化
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<CodeEditor
|
||||
className="mb-6"
|
||||
code={`// 页面知识库
|
||||
// 添加页面知识
|
||||
pageAgent.knowledge.addPageKnowledge("/products", \`
|
||||
商品列表页面,包含搜索、筛选、批量操作功能。
|
||||
#add-product-btn:新增商品按钮
|
||||
.product-item:商品列表项
|
||||
#search-input:搜索框,最少2个字符
|
||||
\`);
|
||||
|
||||
pageAgent.knowledge.addPageKnowledge("/orders/*", \`
|
||||
订单详情页面。
|
||||
.order-status:订单状态标签
|
||||
#update-status-btn:状态更新按钮
|
||||
\`);
|
||||
|
||||
// 移除页面知识
|
||||
pageAgent.knowledge.removePageKnowledge("/products");`}
|
||||
/>
|
||||
</section>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
164
packages/website/src/docs/features/model-integration/page.tsx
Normal file
164
packages/website/src/docs/features/model-integration/page.tsx
Normal file
@@ -0,0 +1,164 @@
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
import BetaNotice from '@/components/BetaNotice'
|
||||
import CodeEditor from '@/components/CodeEditor'
|
||||
|
||||
export default function ModelIntegration() {
|
||||
const { t } = useTranslation('docs')
|
||||
|
||||
return (
|
||||
<div>
|
||||
<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">
|
||||
{t('model_integration.subtitle')}
|
||||
</p>
|
||||
|
||||
<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">
|
||||
{t('model_integration.model_gpt4_title')}
|
||||
</h3>
|
||||
<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">
|
||||
{t('model_integration.model_deepseek_title')}
|
||||
</h3>
|
||||
<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">
|
||||
{t('model_integration.model_qwen_title')}
|
||||
</h3>
|
||||
<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">
|
||||
{t('model_integration.model_gemini_title')}
|
||||
</h3>
|
||||
<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">{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">
|
||||
gpt-4.1-mini/4.1/5
|
||||
</span>
|
||||
<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">
|
||||
grok-4/grok-code-fast
|
||||
</span>
|
||||
<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">
|
||||
qwen3
|
||||
</span>
|
||||
<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">
|
||||
deepseek-v3.1/3.2
|
||||
</span>
|
||||
<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">
|
||||
claude-sonnet-4/4.5/haiku-4.5
|
||||
</span>
|
||||
<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">
|
||||
gemini-2.5
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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-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">{t('model_integration.security')}</h2>
|
||||
|
||||
<div className="p-4 bg-yellow-50 dark:bg-yellow-900/20 border-l-4 border-yellow-500 mb-4">
|
||||
<p className="text-sm font-semibold text-yellow-900 dark:text-yellow-200">
|
||||
{t('model_integration.security_warning')}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<p className="text-gray-600 dark:text-gray-300 mb-4">
|
||||
{t('model_integration.security_desc')}
|
||||
</p>
|
||||
|
||||
<div className="p-4 bg-blue-50 dark:bg-blue-900/20 rounded-lg mb-6">
|
||||
<h3 className="text-lg font-semibold mb-3 text-blue-900 dark:text-blue-300">
|
||||
{t('model_integration.security_backend_proxy')}
|
||||
</h3>
|
||||
<p className="text-sm text-gray-600 dark:text-gray-300 mb-3">
|
||||
{t('model_integration.security_backend_desc')}
|
||||
</p>
|
||||
<ul className="text-sm text-gray-600 dark:text-gray-300 space-y-1 list-none pl-0">
|
||||
<li>{t('model_integration.security_method_1')}</li>
|
||||
<li>{t('model_integration.security_method_2')}</li>
|
||||
<li>{t('model_integration.security_method_3')}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<h2 className="text-2xl font-bold mb-3">{t('model_integration.configuration')}</h2>
|
||||
|
||||
<CodeEditor
|
||||
code={`
|
||||
// 百炼等其他兼容服务
|
||||
const pageAgent = new PageAgent({
|
||||
baseURL: 'https://dashscope.aliyuncs.com/compatible-mode/v1',
|
||||
apiKey: 'your-api-key',
|
||||
model: 'qwen-plus'
|
||||
});
|
||||
|
||||
// 私有部署模型
|
||||
const pageAgent = new PageAgent({
|
||||
baseURL: 'http://localhost:11434/v1',
|
||||
apiKey: 'N/A', // Ollama 通常使用任意值
|
||||
model: 'qwen3:latest'
|
||||
});
|
||||
|
||||
// 测试接口
|
||||
// @note: 限流,限制 prompt 内容,限制来源,随时变更,请替换成你自己的
|
||||
// @note: 使用 DeepSeek-chat(3.2) 官方版本,使用协议和隐私策略见 DeepSeek 网站
|
||||
const DEMO_MODEL = 'PAGE-AGENT-FREE-TESTING-RANDOM'
|
||||
const DEMO_BASE_URL = 'https://hwcxiuzfylggtcktqgij.supabase.co/functions/v1/llm-testing-proxy'
|
||||
const DEMO_API_KEY = 'PAGE-AGENT-FREE-TESTING-RANDOM'
|
||||
`}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
import BetaNotice from '@/components/BetaNotice'
|
||||
|
||||
export default function SecurityPermissions() {
|
||||
return (
|
||||
<div>
|
||||
<h1 className="text-4xl font-bold mb-6">安全与权限</h1>
|
||||
|
||||
<BetaNotice />
|
||||
|
||||
<p className="text-xl text-gray-600 dark:text-gray-300 mb-8 leading-relaxed">
|
||||
page-agent 提供四种安全机制,确保 AI 操作在可控范围内进行。
|
||||
</p>
|
||||
|
||||
<div className="space-y-6">
|
||||
<section>
|
||||
<h2 className="text-2xl font-bold mb-3">元素操作黑白名单</h2>
|
||||
<div className="space-y-3">
|
||||
<div className="p-4 bg-red-50 dark:bg-red-900/20 rounded-lg">
|
||||
<h3 className="text-lg font-semibold text-red-900 dark:text-red-300">
|
||||
🚫 操作黑名单
|
||||
</h3>
|
||||
<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-gray-600 dark:text-gray-300">明确定义 AI 可以操作的元素范围。</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 className="text-2xl font-bold mb-3">URL 黑白名单</h2>
|
||||
<div className="space-y-3">
|
||||
<div className="p-4 bg-red-50 dark:bg-red-900/20 rounded-lg">
|
||||
<h3 className="text-lg font-semibold text-red-900 dark:text-red-300">
|
||||
🚫 URL 黑名单
|
||||
</h3>
|
||||
<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-gray-600 dark:text-gray-300">限制 AI 只能访问预定义的安全页面。</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 className="text-2xl font-bold mb-3">Instruction 安全约束</h2>
|
||||
<div className="p-4 bg-yellow-50 dark:bg-yellow-900/20 rounded-lg">
|
||||
<h3 className="text-lg font-semibold mb-2 text-yellow-900 dark:text-yellow-300">
|
||||
⚠️ 高危操作控制
|
||||
</h3>
|
||||
<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-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-gray-500 dark:text-gray-400">
|
||||
对中等风险操作要求用户明确同意
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
import BetaNotice from '@/components/BetaNotice'
|
||||
import CodeEditor from '@/components/CodeEditor'
|
||||
|
||||
export default function BestPractices() {
|
||||
return (
|
||||
<div>
|
||||
<h1 className="text-4xl font-bold mb-6">最佳实践</h1>
|
||||
|
||||
<BetaNotice />
|
||||
|
||||
<p className="text-xl text-gray-600 dark:text-gray-300 mb-6 leading-relaxed">
|
||||
使用 page-agent 的最佳实践和常见问题解决方案。
|
||||
</p>
|
||||
|
||||
<h2 className="text-2xl font-bold mb-3">性能优化</h2>
|
||||
|
||||
<div className="space-y-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">
|
||||
⚡ 减少 API 调用
|
||||
</h3>
|
||||
<p className="text-gray-600 dark:text-gray-300 mb-3">
|
||||
合并多个操作指令,减少与 AI 模型的交互次数。
|
||||
</p>
|
||||
|
||||
<CodeEditor
|
||||
code={`// 推荐:合并操作
|
||||
await pageAgent.execute('填写表单:姓名张三,邮箱test@example.com,然后提交');
|
||||
|
||||
// 不推荐:分别操作
|
||||
await pageAgent.execute('填写姓名张三');
|
||||
await pageAgent.execute('填写邮箱test@example.com');
|
||||
await pageAgent.execute('点击提交按钮');`}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<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">
|
||||
🎯 精确的元素描述
|
||||
</h3>
|
||||
<p className="text-gray-600 dark:text-gray-300">
|
||||
使用具体、明确的元素描述,提高操作成功率。
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 className="text-2xl font-bold mb-3">安全建议</h2>
|
||||
|
||||
<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-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-gray-600 dark:text-gray-300">启用数据脱敏功能,保护用户隐私信息。</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 className="text-2xl font-bold mb-3">调试技巧</h2>
|
||||
|
||||
<CodeEditor code={`// TODO`} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
38
packages/website/src/docs/integration/cdn-setup/page.tsx
Normal file
38
packages/website/src/docs/integration/cdn-setup/page.tsx
Normal file
@@ -0,0 +1,38 @@
|
||||
import BetaNotice from '@/components/BetaNotice'
|
||||
import CodeEditor from '@/components/CodeEditor'
|
||||
|
||||
export default function CdnSetup() {
|
||||
return (
|
||||
<div>
|
||||
<h1 className="text-4xl font-bold mb-6">CDN 引入</h1>
|
||||
|
||||
<p className="text-xl text-gray-600 dark:text-gray-300 mb-6 leading-relaxed">
|
||||
通过 CDN 快速集成 page-agent,无需复杂的构建配置。
|
||||
</p>
|
||||
|
||||
<h2 className="text-2xl font-bold mb-3">快速开始</h2>
|
||||
|
||||
<CodeEditor
|
||||
className="mb-8"
|
||||
code={`
|
||||
// 仅供测试使用,稳定 CDN 待定
|
||||
<script src="https://hwcxiuzfylggtcktqgij.supabase.co/storage/v1/object/public/demo-public/v0.0.4/page-agent.js" crossorigin="true" type="text/javascript"></script>
|
||||
|
||||
<script>
|
||||
window.pageAgent.panel.show()
|
||||
</script>`}
|
||||
/>
|
||||
|
||||
<div className="bg-yellow-50 dark:bg-yellow-900/20 p-4 rounded-lg">
|
||||
<h3 className="text-lg font-semibold mb-2 text-yellow-900 dark:text-yellow-300">
|
||||
⚠️ 注意事项
|
||||
</h3>
|
||||
<ul className="text-gray-600 dark:text-gray-300 space-y-1">
|
||||
<li>• 生产环境建议使用固定版本号</li>
|
||||
<li>• 确保 HTTPS 环境下使用</li>
|
||||
<li>• 配置 CSP 策略允许脚本执行</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
108
packages/website/src/docs/integration/configuration/page.tsx
Normal file
108
packages/website/src/docs/integration/configuration/page.tsx
Normal file
@@ -0,0 +1,108 @@
|
||||
import CodeEditor from '@/components/CodeEditor'
|
||||
|
||||
export default function Configuration() {
|
||||
return (
|
||||
<div>
|
||||
<h1 className="text-4xl font-bold mb-6">配置选项</h1>
|
||||
|
||||
<CodeEditor
|
||||
className="mb-8"
|
||||
language="typescript"
|
||||
code={`// config
|
||||
type PageAgentConfig = LLMConfig & AgentConfig & DomConfig
|
||||
|
||||
interface LLMConfig {
|
||||
baseURL?: string
|
||||
apiKey?: string
|
||||
model?: string
|
||||
temperature?: number
|
||||
maxTokens?: number
|
||||
maxRetries?: number
|
||||
}
|
||||
|
||||
interface AgentConfig {
|
||||
language?: "en-US" | "zh-CN"
|
||||
|
||||
/**
|
||||
* Custom tools to extend PageAgent capabilities
|
||||
* @experimental
|
||||
* @note You can also override or remove internal tools by using the same name.
|
||||
* @see [tools](../tools/index.ts)
|
||||
*
|
||||
* @example
|
||||
* // override internal tool
|
||||
* import { tool } from 'page-agent'
|
||||
* const customTools = {
|
||||
* ask_user: tool({
|
||||
* description:
|
||||
* 'Ask the user or parent model a question and wait for their answer. Use this if you need more information or clarification.',
|
||||
* inputSchema: zod.object({
|
||||
* question: zod.string(),
|
||||
* }),
|
||||
* execute: async function (this: PageAgent, input) {
|
||||
* const answer = await do_some_thing(input.question)
|
||||
* return "✅ Received user answer: " + answer
|
||||
* },
|
||||
* })
|
||||
* }
|
||||
*
|
||||
* @example
|
||||
* // remove internal tool
|
||||
* const customTools = {
|
||||
* ask_user: null // never ask user questions
|
||||
* }
|
||||
*/
|
||||
customTools?: Record<string, PageAgentTool | null>
|
||||
|
||||
// lifecycle hooks
|
||||
// @todo: use event instead of hooks
|
||||
|
||||
onBeforeStep?: (this: PageAgent, stepCnt: number) => Promise<void> | void
|
||||
onAfterStep?: (this: PageAgent, stepCnt: number, history: AgentHistory[]) => Promise<void> | void
|
||||
onBeforeTask?: (this: PageAgent) => Promise<void> | void
|
||||
onAfterTask?: (this: PageAgent, result: ExecutionResult) => Promise<void> | void
|
||||
|
||||
/**
|
||||
* @note this hook can block the disposal process
|
||||
* @note when dispose caused by page unload, "reason" will be 'PAGE_UNLOADING'. this method CANNOT block unloading. async operations may be cut.
|
||||
*/
|
||||
onDispose?: (this: PageAgent, reason?: string) => void
|
||||
|
||||
// page behavior hooks
|
||||
|
||||
/**
|
||||
* @experimental
|
||||
* Enable the experimental script execution tool that allows executing generated JavaScript code on the page.
|
||||
* @note Can cause unpredictable side effects.
|
||||
* @note May bypass some safe guards and data-masking mechanisms.
|
||||
*/
|
||||
experimentalScriptExecutionTool?: boolean
|
||||
|
||||
/**
|
||||
* TODO: @unimplemented
|
||||
* hook when action causes a new page to be opened
|
||||
* @note PageAgent will try to detect new pages and decide if it's caused by an action. But not very reliable.
|
||||
*/
|
||||
onNewPageOpen?: (this: PageAgent, url: string) => Promise<void> | void
|
||||
|
||||
/**
|
||||
* TODO: @unimplemented
|
||||
* try to navigate to a new page instead of opening a new tab/window.
|
||||
* @note will unload the current page when a action tries to open a new page. so that things keep in the same tab/window.
|
||||
*/
|
||||
experimentalPreventNewPage?: boolean
|
||||
}
|
||||
|
||||
interface DomConfig {
|
||||
interactiveBlacklist?: (Element | (() => Element))[]
|
||||
interactiveWhitelist?: (Element | (() => Element))[]
|
||||
include_attributes?: string[]
|
||||
highlightOpacity?: number
|
||||
highlightLabelOpacity?: number
|
||||
}
|
||||
|
||||
`}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
115
packages/website/src/docs/integration/third-party-agent/page.tsx
Normal file
115
packages/website/src/docs/integration/third-party-agent/page.tsx
Normal file
@@ -0,0 +1,115 @@
|
||||
import CodeEditor from '@/components/CodeEditor'
|
||||
|
||||
export default function ThirdPartyAgentPage() {
|
||||
return (
|
||||
<div>
|
||||
<h1 className="text-4xl font-bold mb-6">接入第三方 Agent</h1>
|
||||
<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">
|
||||
让你的答疑机器人不再只是"嘴巴",而是拥有"眼睛"和"手"的完整智能体。
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<h2 className="text-2xl font-bold mb-4">集成方式</h2>
|
||||
|
||||
<div className="space-y-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">
|
||||
1. Function Calling
|
||||
</h3>
|
||||
<CodeEditor
|
||||
code={`// 定义工具
|
||||
const pageAgentTool = {
|
||||
name: "page_agent",
|
||||
description: "执行网页操作",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
instruction: { type: "string", description: "操作指令" }
|
||||
},
|
||||
required: ["instruction"]
|
||||
},
|
||||
execute: async (params) => {
|
||||
const result = await pageAgent.execute(params.instruction)
|
||||
return { success: result.success, message: result.message }
|
||||
}
|
||||
}
|
||||
|
||||
// 注册到你的 agent 中`}
|
||||
language="javascript"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 className="text-2xl font-bold mb-4">应用场景</h2>
|
||||
<div className="grid md:grid-cols-2 gap-4 mb-6">
|
||||
<div className="bg-linear-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 text-gray-900 dark:text-white">🤖 智能客服系统</h4>
|
||||
<p className="text-sm text-gray-600 dark:text-gray-300">
|
||||
客服机器人帮用户直接操作系统,如"帮我提交工单"
|
||||
</p>
|
||||
</div>
|
||||
<div className="bg-linear-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 text-gray-900 dark:text-white">📋 业务流程助手</h4>
|
||||
<p className="text-sm text-gray-600 dark:text-gray-300">
|
||||
引导新员工完成复杂流程,如"完成客户入职"
|
||||
</p>
|
||||
</div>
|
||||
<div className="bg-linear-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 text-gray-900 dark:text-white">🎯 个人效率助手</h4>
|
||||
<p className="text-sm text-gray-600 dark:text-gray-300">
|
||||
跨网站帮你完成任务,如"预订会议室"
|
||||
</p>
|
||||
</div>
|
||||
<div className="bg-linear-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 text-gray-900 dark:text-white">🔧 运维自动化</h4>
|
||||
<p className="text-sm text-gray-600 dark:text-gray-300">
|
||||
通过自然语言操作管理后台,如"重启服务器"
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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 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 text-gray-900 dark:text-white">权限控制</h3>
|
||||
<CodeEditor code={`// @TODO`} language="javascript" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-800 rounded-lg p-4 mb-6">
|
||||
<h3 className="text-lg font-semibold text-yellow-900 dark:text-yellow-100 mb-2">
|
||||
⚠️ 注意事项
|
||||
</h3>
|
||||
<ul className="text-yellow-800 dark:text-yellow-200 space-y-1 text-sm">
|
||||
<li>• 确保目标网站允许自动化操作</li>
|
||||
<li>• 实现适当的频率限制</li>
|
||||
<li>• 敏感操作建议要求人工确认</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="bg-linear-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 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"
|
||||
>
|
||||
查看配置选项 →
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
144
packages/website/src/docs/introduction/limitations/page.tsx
Normal file
144
packages/website/src/docs/introduction/limitations/page.tsx
Normal file
@@ -0,0 +1,144 @@
|
||||
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">
|
||||
{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">{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">
|
||||
{t('limitations.spa_limit_title')}
|
||||
</h3>
|
||||
<ul className="text-blue-700 dark:text-blue-300 space-y-2">
|
||||
<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">{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">{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>{t('limitations.op_click')}</span>
|
||||
</div>
|
||||
<div className="flex items-center text-green-600 dark:text-green-400">
|
||||
<span className="mr-2">✅</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>{t('limitations.op_scroll')}</span>
|
||||
</div>
|
||||
<div className="flex items-center text-green-600 dark:text-green-400">
|
||||
<span className="mr-2">✅</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>{t('limitations.op_select')}</span>
|
||||
</div>
|
||||
<div className="flex items-center text-green-600 dark:text-green-400">
|
||||
<span className="mr-2">✅</span>
|
||||
<span>{t('limitations.op_focus')}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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>{t('limitations.op_hover')}</span>
|
||||
</div>
|
||||
<div className="flex items-center text-red-600 dark:text-red-400">
|
||||
<span className="mr-2">❌</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>{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>{t('limitations.op_draw')}</span>
|
||||
</div>
|
||||
<div className="flex items-center text-red-600 dark:text-red-400">
|
||||
<span className="mr-2">❌</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>{t('limitations.op_position')}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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">
|
||||
{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>{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">{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">{t('limitations.req_semantic_title')}</h3>
|
||||
<p className="text-gray-600 dark:text-gray-300">
|
||||
{t('limitations.req_semantic_desc')}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<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">{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>{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">
|
||||
{t('limitations.future_title')}
|
||||
</h3>
|
||||
<ul className="text-green-700 dark:text-green-300 space-y-1">
|
||||
<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>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
212
packages/website/src/docs/introduction/overview/page.tsx
Normal file
212
packages/website/src/docs/introduction/overview/page.tsx
Normal file
@@ -0,0 +1,212 @@
|
||||
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"
|
||||
className="w-full h-64 object-cover"
|
||||
/>
|
||||
</figure>
|
||||
|
||||
<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>
|
||||
|
||||
{/* 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>
|
||||
|
||||
<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">{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">
|
||||
{t('overview.feature_dom.title')}
|
||||
</h3>
|
||||
<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="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="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="text-gray-700 dark:text-gray-300">
|
||||
{t('overview.feature_accessible.desc')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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
|
||||
</th>
|
||||
<th className="border border-gray-300 dark:border-gray-600 px-4 py-3 text-left">
|
||||
browser-use
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<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">
|
||||
{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">
|
||||
{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">{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 min-w-6 bg-blue-500 text-white rounded-full flex items-center justify-center font-bold text-sm mt-0.5 shrink-0">
|
||||
1
|
||||
</span>
|
||||
<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 min-w-6 bg-green-500 text-white rounded-full flex items-center justify-center font-bold text-sm mt-0.5 shrink-0">
|
||||
2
|
||||
</span>
|
||||
<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 min-w-6 bg-purple-500 text-white rounded-full flex items-center justify-center font-bold text-sm mt-0.5 shrink-0">
|
||||
3
|
||||
</span>
|
||||
<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 min-w-6 bg-orange-500 text-white rounded-full flex items-center justify-center font-bold text-sm mt-0.5 shrink-0">
|
||||
4
|
||||
</span>
|
||||
<div className="text-gray-700 dark:text-gray-300">
|
||||
<strong>{t('overview.use_case4_title')}</strong> {t('overview.use_case4_desc')}
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
</article>
|
||||
)
|
||||
}
|
||||
82
packages/website/src/docs/introduction/quick-start/page.tsx
Normal file
82
packages/website/src/docs/introduction/quick-start/page.tsx
Normal file
@@ -0,0 +1,82 @@
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
import BetaNotice from '@/components/BetaNotice'
|
||||
import CodeEditor from '@/components/CodeEditor'
|
||||
|
||||
export default function QuickStart() {
|
||||
const { t } = useTranslation('docs')
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h1 className="text-4xl font-bold mb-6">{t('quick_start.title')}</h1>
|
||||
|
||||
<p className=" mb-6 leading-relaxed">{t('quick_start.subtitle')}</p>
|
||||
|
||||
<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">
|
||||
{t('quick_start.step1_title')}
|
||||
</h3>
|
||||
<div className="space-y-3">
|
||||
<div>
|
||||
<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.4/page-agent.js" crossorigin="true" type="text/javascript"></script>`}
|
||||
language="html"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<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'`}
|
||||
language="bash"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</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('quick_start.step2_title')}
|
||||
</h3>
|
||||
<CodeEditor
|
||||
code={`// 仅供测试使用,生产环境需要配置 LLM 接入点,本工具不提供 LLM 服务
|
||||
// 测试接口
|
||||
// @note: 限流,限制 prompt 内容,限制来源,随时变更,请替换成你自己的
|
||||
// @note: 使用 DeepSeek-chat(3.2) 官方版本,使用协议和隐私策略见 DeepSeek 网站
|
||||
const DEMO_MODEL = 'PAGE-AGENT-FREE-TESTING-RANDOM'
|
||||
const DEMO_BASE_URL = 'https://hwcxiuzfylggtcktqgij.supabase.co/functions/v1/llm-testing-proxy'
|
||||
const DEMO_API_KEY = 'PAGE-AGENT-FREE-TESTING-RANDOM'
|
||||
|
||||
const agent = new PageAgent({
|
||||
modelName: DEMO_MODEL,
|
||||
baseURL: DEMO_BASE_URL,
|
||||
apiKey: DEMO_API_KEY,
|
||||
language: 'zh-CN'
|
||||
})`}
|
||||
language="javascript"
|
||||
/>
|
||||
</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('quick_start.step3_title')}
|
||||
</h3>
|
||||
<CodeEditor
|
||||
code={`// 程序化执行自然语言指令
|
||||
await pageAgent.execute('点击提交按钮,然后填写用户名为张三');
|
||||
|
||||
// 或者显示对话框让用户输入指令
|
||||
pageAgent.panel.show()
|
||||
`}
|
||||
language="javascript"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user