docs: update advanced docs; rm best-practice

This commit is contained in:
Simon
2026-03-04 21:13:10 +08:00
parent e5437b445a
commit 53c2c19d69
13 changed files with 480 additions and 329 deletions

View File

@@ -1,6 +1,6 @@
import { APIDivider, APIReference } from '@/components/APIReference'
import CodeEditor from '@/components/CodeEditor'
import { Heading } from '@/components/Heading'
import { APIDivider, APIReference } from '@/components/ui/api-reference'
import { useLanguage } from '@/i18n/context'
export default function CustomUIDocs() {

View File

@@ -1,6 +1,8 @@
import { Link } from 'wouter'
import { APIDivider, APIReference, TypeRef } from '@/components/APIReference'
import CodeEditor from '@/components/CodeEditor'
import { Heading } from '@/components/Heading'
import { APIDivider, APIReference, TypeRef } from '@/components/ui/api-reference'
import { useLanguage } from '@/i18n/context'
export default function PageAgentCoreDocs() {
@@ -50,19 +52,13 @@ const agent = new PageAgentCore({
baseURL: 'https://api.openai.com/v1',
apiKey: 'your-api-key',
model: 'gpt-5.2',
language: 'en-US',
})
// Listen to events for UI display
agent.addEventListener('statuschange', () => {
console.log('Status:', agent.status)
})
agent.addEventListener('historychange', () => {
console.log('History:', agent.history)
})
agent.addEventListener('activity', (e) => {
const activity = (e as CustomEvent).detail
console.log('Activity:', activity.type)
@@ -75,14 +71,54 @@ const result = await agent.execute('Fill in the form with test data')`}
<APIDivider title={isZh ? '配置' : 'Configuration'} />
{/* LLM Configuration */}
{/* Configuration */}
<section className="mb-10">
<Heading id="llmconfig">LLMConfig</Heading>
<Heading id="configuration">PageAgentCoreConfig</Heading>
<p className="text-gray-600 dark:text-gray-400 mb-4">
{isZh
? '配置与大语言模型的连接参数。支持 OpenAI 兼容的 API。'
: 'Configure connection parameters for the language model. Supports OpenAI-compatible APIs.'}
? 'PageAgentCoreConfig = AgentConfig & { pageController: PageController }。AgentConfig 包含以下配置项:'
: 'PageAgentCoreConfig = AgentConfig & { pageController: PageController }. AgentConfig contains the following options:'}
</p>
{/* PageController */}
<h3 className="text-lg font-semibold mt-6 mb-3 text-gray-800 dark:text-gray-200">
PageController
</h3>
<APIReference
properties={[
{
name: 'pageController',
type: 'PageController',
required: true,
description: isZh ? (
<>
<Link
href="/advanced/page-controller"
className="text-blue-600 dark:text-blue-400 hover:underline"
>
PageController
</Link>{' '}
DOM
</>
) : (
<>
<Link
href="/advanced/page-controller"
className="text-blue-600 dark:text-blue-400 hover:underline"
>
PageController
</Link>{' '}
instance for DOM operations and element interaction.
</>
),
},
]}
/>
{/* LLM Config */}
<h3 className="text-lg font-semibold mt-6 mb-3 text-gray-800 dark:text-gray-200">
{isZh ? 'LLM 配置' : 'LLM Config'}
</h3>
<APIReference
properties={[
{
@@ -110,7 +146,6 @@ const result = await agent.execute('Fill in the form with test data')`}
{
name: 'temperature',
type: 'number',
defaultValue: '0',
description: isZh
? '模型温度参数,控制输出随机性'
: 'Model temperature, controls output randomness',
@@ -130,16 +165,11 @@ const result = await agent.execute('Fill in the form with test data')`}
},
]}
/>
</section>
{/* Agent Configuration */}
<section className="mb-10">
<Heading id="agentconfig">AgentConfig</Heading>
<p className="text-gray-600 dark:text-gray-400 mb-4">
{isZh
? '配置 Agent 的行为、生命周期钩子和扩展能力。'
: 'Configure agent behavior, lifecycle hooks, and extension capabilities.'}
</p>
{/* Agent Config */}
<h3 className="text-lg font-semibold mt-6 mb-3 text-gray-800 dark:text-gray-200">
{isZh ? 'Agent 配置' : 'Agent Config'}
</h3>
<APIReference
properties={[
{
@@ -166,8 +196,8 @@ const result = await agent.execute('Fill in the form with test data')`}
name: 'instructions',
type: 'InstructionsConfig',
description: isZh
? '指导 Agent 行为的指令配置'
: 'Instructions to guide agent behavior',
? '指导 Agent 行为的指令配置,见下方类型定义'
: 'Instructions to guide agent behavior, see type definition below',
},
{
name: 'transformPageContent',
@@ -177,7 +207,15 @@ const result = await agent.execute('Fill in the form with test data')`}
: 'Transform page content before sending to LLM, useful for data masking',
},
{
name: 'experimentalScriptExecutionTool',
name: 'customSystemPrompt',
type: 'string',
status: 'experimental',
description: isZh
? '完全覆盖默认系统提示词。谨慎使用。'
: 'Completely override the default system prompt. Use with caution.',
},
{
name: 'experimentalScript\nExecutionTool',
type: 'boolean',
defaultValue: 'false',
status: 'experimental',
@@ -191,137 +229,52 @@ const result = await agent.execute('Fill in the form with test data')`}
defaultValue: 'false',
status: 'experimental',
description: isZh
? '从当前站点根目录获取 /llms.txt 并作为上下文提供给 LLM,每个 origin 仅请求一次'
: 'Fetch /llms.txt from site origin and include as LLM context, fetched once per origin',
? '从当前站点根目录获取 /llms.txt 并作为上下文提供给 LLM'
: 'Fetch /llms.txt from site origin and include as LLM context',
},
]}
/>
<h3 className="text-lg font-semibold mt-6 mb-3">InstructionsConfig</h3>
<APIReference
properties={[
{
name: 'system',
type: 'string',
description: isZh
? '全局系统级指令,应用于所有任务'
: 'Global system-level instructions, applied to all tasks',
},
{
name: 'getPageInstructions',
type: '(url: string) => string | undefined | null',
description: isZh
? '动态页面级指令回调,在每个步骤前调用'
: 'Dynamic page-level instructions callback, called before each step',
},
]}
/>
</section>
{/* Lifecycle Hooks */}
<section className="mb-10">
<Heading id="lifecycle-hooks">{isZh ? '生命周期钩子' : 'Lifecycle Hooks'}</Heading>
{/* Lifecycle Hooks */}
<h3 className="text-lg font-semibold mt-6 mb-3 text-gray-800 dark:text-gray-200">
{isZh ? '生命周期钩子' : 'Lifecycle Hooks'}
<span className="ml-2 text-xs font-normal text-amber-600 dark:text-amber-400">
experimental
</span>
</h3>
<div className="bg-amber-50 dark:bg-amber-900/20 border border-amber-200 dark:border-amber-800 rounded-lg p-4 mb-4">
<p className="text-amber-800 dark:text-amber-200 text-sm">
<strong> {isZh ? '警告' : 'Warning'}:</strong>{' '}
{isZh
? '这些接口高度实验性,可能在未来版本中发生变化。建议优先使用事件系统Events来监听 Agent 状态。'
: 'These APIs are highly experimental and may change in future versions. Prefer using the Events system for monitoring agent state.'}
? '这些接口高度实验性,可能在未来版本中发生变化。'
: 'These APIs are highly experimental and may change in future versions. '}
</p>
</div>
<p className="text-gray-600 dark:text-gray-400 mb-4">
{isZh
? '所有生命周期钩子都接收 agent 实例作为第一个参数,便于在回调中访问 Agent 状态和方法。'
: 'All lifecycle hooks receive the agent instance as first parameter, making it easy to access agent state and methods in callbacks.'}
</p>
<APIReference
properties={[
{
name: 'onBeforeStep',
type: '(agent: PageAgentCore, stepCount: number) => void | Promise<void>',
type: '(agent, stepCount) => void | Promise<void>',
description: isZh ? '每个步骤执行前调用' : 'Called before each step execution',
status: 'experimental',
},
{
name: 'onAfterStep',
type: '(agent: PageAgentCore, history: HistoricalEvent[]) => void | Promise<void>',
type: '(agent, history) => void | Promise<void>',
description: isZh ? '每个步骤执行后调用' : 'Called after each step execution',
status: 'experimental',
},
{
name: 'onBeforeTask',
type: '(agent: PageAgentCore) => void | Promise<void>',
type: '(agent) => void | Promise<void>',
description: isZh ? '任务开始前调用' : 'Called before task starts',
status: 'experimental',
},
{
name: 'onAfterTask',
type: '(agent: PageAgentCore, result: ExecutionResult) => void | Promise<void>',
type: '(agent, result) => void | Promise<void>',
description: isZh ? '任务结束后调用' : 'Called after task ends',
status: 'experimental',
},
{
name: 'onDispose',
type: '(agent: PageAgentCore, reason?: string) => void',
type: '(agent, reason?) => void',
description: isZh ? 'Agent 销毁时调用' : 'Called when agent is disposed',
status: 'experimental',
},
]}
/>
</section>
{/* PageController Configuration */}
<section className="mb-10">
<Heading id="pagecontrollerconfig">PageControllerConfig</Heading>
<p className="text-gray-600 dark:text-gray-400 mb-4">
{isZh
? '配置 DOM 提取、元素交互和视觉反馈。'
: 'Configure DOM extraction, element interaction, and visual feedback.'}
</p>
<APIReference
properties={[
{
name: 'pageController',
type: 'PageController',
status: 'experimental',
description: isZh
? '自定义 PageController 实例。如不提供,将创建默认实例。'
: 'Custom PageController instance. If not provided, a default one will be created.',
},
{
name: 'enableMask',
type: 'boolean',
defaultValue: 'true',
description: isZh
? '启用视觉遮罩覆盖层,阻止用户在自动化期间操作'
: 'Enable visual mask overlay that blocks user interaction during automation',
},
{
name: 'viewportExpansion',
type: 'number',
defaultValue: '0',
description: isZh
? '视口扩展像素数,-1 表示提取整个页面'
: 'Viewport expansion in pixels, -1 means extract entire page',
},
{
name: 'interactiveBlacklist',
type: '(Element | (() => Element))[]',
description: isZh ? '要排除的交互元素列表' : 'Elements to exclude from interaction',
},
{
name: 'interactiveWhitelist',
type: '(Element | (() => Element))[]',
description: isZh
? '要强制包含的交互元素列表'
: 'Elements to force include for interaction',
},
{
name: 'includeAttributes',
type: 'string[]',
description: isZh
? '在 DOM 提取中包含的额外属性'
: 'Additional attributes to include in DOM extraction',
},
]}
/>
@@ -378,16 +331,24 @@ const result = await agent.execute('Fill in the form with test data')`}
<section className="mb-10">
<Heading id="methods">{isZh ? '方法' : 'Methods'}</Heading>
<APIReference
variant="methods"
properties={[
{
name: 'execute(task: string)',
name: 'execute(task)',
type: 'Promise<ExecutionResult>',
description: isZh
? '执行任务并返回结果。包含 success、data 和 history 字段。'
: 'Execute a task and return result. Contains success, data, and history fields.',
},
{
name: 'dispose(reason?: string)',
name: 'stop()',
type: 'void',
description: isZh
? '停止当前任务。Agent 仍可复用。'
: 'Stop the current task. Agent remains reusable.',
},
{
name: 'dispose()',
type: 'void',
description: isZh
? '销毁 Agent 并清理资源'
@@ -452,11 +413,8 @@ const result = await agent.execute('Fill in the form with test data')`}
<CodeEditor
language="typescript"
code={`interface ExecutionResult {
/** Whether the task completed successfully */
success: boolean
/** Result description from the agent */
data: string
/** Full execution history */
history: HistoricalEvent[]
}`}
/>
@@ -476,50 +434,21 @@ const result = await agent.execute('Fill in the form with test data')`}
/>
</section>
<APIDivider title={isZh ? '无头模式' : 'Headless Mode'} />
{/* Headless Usage */}
{/* InstructionsConfig */}
<section className="mb-10">
<Heading id="headless-mode">{isZh ? '无头模式' : 'Headless Mode'}</Heading>
<p className="text-gray-600 dark:text-gray-400 mb-4">
{isZh
? '在非 DOM 环境中,你必须实现自定义的 PageController例如远程操作页面或 Puppeteer。'
: 'In non-DOM environments, you must implement a custom PageController (e.g., remote page control or Puppeteer).'}
</p>
<Heading id="instructionsconfig">InstructionsConfig</Heading>
<CodeEditor
language="typescript"
code={`import { PageAgentCore } from '@page-agent/core'
import type { PageController } from '@page-agent/page-controller'
code={`interface InstructionsConfig {
/** Global system-level instructions, applied to all tasks */
system?: string
class MyRemotePageController implements PageController {
// Implement required methods for DOM extraction and interaction
}
const agent = new PageAgentCore({
pageController: new MyRemotePageController(),
baseURL: 'https://api.openai.com/v1',
apiKey: 'your-api-key',
model: 'gpt-5.2',
language: 'en-US',
})
// Listen to events for UI display
agent.addEventListener('statuschange', () => {
console.log('Status:', agent.status)
})
agent.addEventListener('historychange', () => {
console.log('History:', agent.history)
})
agent.addEventListener('activity', (e) => {
const activity = (e as CustomEvent).detail
console.log('Activity:', activity.type)
})
// Execute task
const result = await agent.execute('Fill in the form with test data')`}
/**
* Dynamic page-level instructions callback.
* Called before each step to get instructions for the current page.
*/
getPageInstructions?: (url: string) => string | undefined
}`}
/>
</section>
</div>

View File

@@ -2,7 +2,6 @@ import { Link } from 'wouter'
import CodeEditor from '@/components/CodeEditor'
import { Heading } from '@/components/Heading'
import { APIReference, TypeRef } from '@/components/ui/api-reference'
import { useLanguage } from '@/i18n/context'
export default function PageAgentDocs() {
@@ -14,8 +13,8 @@ export default function PageAgentDocs() {
<p className="text-xl text-gray-600 dark:text-gray-300 mb-8 leading-relaxed">
{isZh
? 'PageAgent 是带有内置 UI 面板的完整 Agent 类。它继承自 PageAgentCore并自动创建交互面板。'
: 'PageAgent is the complete Agent class with built-in UI panel. It extends PageAgentCore and automatically creates an interactive panel.'}
? 'PageAgent 是带有内置 UI 面板的完整 Agent 类。它继承自 PageAgentCore并自动创建交互面板和 PageController。'
: 'PageAgent is the complete Agent class with built-in UI panel. It extends PageAgentCore and automatically creates an interactive panel and PageController.'}
</p>
{/* When to use */}
@@ -29,6 +28,11 @@ export default function PageAgentDocs() {
: 'In most cases, you should use PageAgent. It provides a complete out-of-the-box experience:'}
</p>
<ul className="list-disc list-inside text-gray-600 dark:text-gray-400 space-y-2 mb-6">
<li>
{isZh
? '自动创建 PageController处理 DOM 提取和元素操作'
: 'Automatically creates PageController for DOM extraction and element actions'}
</li>
<li>
{isZh
? '内置 UI 面板显示任务进度、Agent 思考过程和操作结果'
@@ -74,9 +78,8 @@ console.log(result.history) // Full execution history`}
<CodeEditor
language="typescript"
code={`class PageAgent extends PageAgentCore {
/** The UI panel instance */
panel: Panel
pageController: PageController
constructor(config: PageAgentConfig)
}`}
/>
@@ -90,7 +93,21 @@ console.log(result.history) // Full execution history`}
>
PageAgentCore
</Link>
API PageAgentCore
{' '}
<Link
href="/advanced/page-agent-core#configuration"
className="text-blue-600 dark:text-blue-400 hover:underline"
>
AgentConfig
</Link>{' '}
{' '}
<Link
href="/advanced/page-controller#configuration"
className="text-blue-600 dark:text-blue-400 hover:underline"
>
PageControllerConfig
</Link>
</>
) : (
<>
@@ -101,71 +118,34 @@ console.log(result.history) // Full execution history`}
>
PageAgentCore
</Link>
. All core methods and events are available. See PageAgentCore docs for detailed API
reference.
</>
)}
</p>
</section>
{/* Configuration */}
<section className="mb-10">
<Heading id="configuration">{isZh ? '配置' : 'Configuration'}</Heading>
<p className="text-gray-600 dark:text-gray-400 mb-4">
{isZh
? 'PageAgent 使用与 PageAgentCore 相同的配置接口。'
: 'PageAgent uses the same configuration interface as PageAgentCore.'}
</p>
<p className="text-gray-600 dark:text-gray-400 mb-4">
{isZh ? (
<>
{' '}
. All core methods and events are available. Config merges{' '}
<Link
href="/advanced/page-agent-core"
href="/advanced/page-agent-core#configuration"
className="text-blue-600 dark:text-blue-400 hover:underline"
>
PageAgentCore
</Link>
</>
) : (
<>
See{' '}
<Link
href="/advanced/page-agent-core"
className="text-blue-600 dark:text-blue-400 hover:underline"
>
PageAgentCore configuration docs
AgentConfig
</Link>{' '}
for complete reference.
and{' '}
<Link
href="/advanced/page-controller#configuration"
className="text-blue-600 dark:text-blue-400 hover:underline"
>
PageControllerConfig
</Link>
.
</>
)}
</p>
</section>
{/* Panel Property */}
{/* Panel */}
<section className="mb-10">
<Heading id="panel-property">{isZh ? 'Panel 属性' : 'Panel Property'}</Heading>
<Heading id="panel">{isZh ? 'UI 面板' : 'UI Panel'}</Heading>
<p className="text-gray-600 dark:text-gray-400 mb-4">
{isZh
? 'PageAgent 自动创建一个 Panel 实例。你可以通过 panel 属性访问它来控制 UI'
: 'PageAgent automatically creates a Panel instance. You can access it via the panel property to control the UI:'}
? 'PageAgent 自动创建一个 Panel 实例。你可以通过 panel 属性控制 UI'
: 'PageAgent automatically creates a Panel instance. You can control the UI via the panel property:'}
</p>
<APIReference
properties={[
{
name: 'panel',
type: 'Panel',
required: true,
description: isZh
? '内置的 UI 面板实例,用于显示任务进度和接收用户输入。'
: 'The built-in UI panel instance for displaying task progress and receiving user input.',
},
]}
/>
<h3 className="text-lg font-semibold mt-6 mb-3">{isZh ? 'Panel 方法' : 'Panel Methods'}</h3>
<CodeEditor
language="typescript"
code={`// Show/hide the panel
@@ -212,16 +192,16 @@ agent.panel.dispose()`}
</tr>
<tr className="bg-white dark:bg-gray-900">
<td className="px-4 py-3 text-gray-600 dark:text-gray-400">
{isZh ? 'Headless 模式' : 'Headless Mode'}
{isZh ? '自动创建 PageController' : 'Auto-creates PageController'}
</td>
<td className="px-4 py-3 text-center text-gray-400 dark:text-gray-600">-</td>
<td className="px-4 py-3 text-center text-green-600 dark:text-green-400"></td>
<td className="px-4 py-3 text-center text-gray-400 dark:text-gray-600">-</td>
</tr>
<tr className="bg-white dark:bg-gray-900">
<td className="px-4 py-3 text-gray-600 dark:text-gray-400">
{isZh ? '自定义 PageController' : 'Custom PageController'}
{isZh ? 'Headless 模式' : 'Headless Mode'}
</td>
<td className="px-4 py-3 text-center text-green-600 dark:text-green-400"></td>
<td className="px-4 py-3 text-center text-gray-400 dark:text-gray-600">-</td>
<td className="px-4 py-3 text-center text-green-600 dark:text-green-400"></td>
</tr>
<tr className="bg-white dark:bg-gray-900">

View File

@@ -0,0 +1,286 @@
import { Link } from 'wouter'
import { APIDivider, APIReference } from '@/components/APIReference'
import CodeEditor from '@/components/CodeEditor'
import { Heading } from '@/components/Heading'
import { useLanguage } from '@/i18n/context'
export default function PageControllerDocs() {
const { isZh } = useLanguage()
return (
<div>
<h1 className="text-4xl font-bold mb-6">PageController</h1>
<p className="text-xl text-gray-600 dark:text-gray-300 mb-8 leading-relaxed">
{isZh
? 'PageController 负责 DOM 提取和元素交互,独立于 LLM。它将页面状态结构化为 LLM 可消费的格式,并执行元素级操作。'
: 'PageController handles DOM extraction and element interaction, independent of LLM. It structures page state into LLM-consumable format and executes element-level actions.'}
</p>
{/* Basic Usage */}
<section className="mb-10">
<Heading id="basic-usage">{isZh ? '基本用法' : 'Basic Usage'}</Heading>
<p className="text-gray-600 dark:text-gray-400 mb-4">
{isZh
? 'PageAgent 接受 PageController 配置项:'
: 'PageAgent accepts PageController options:'}
</p>
<CodeEditor
language="typescript"
code={`import { PageAgent } from 'page-agent'
const agent = new PageAgent({
baseURL: 'https://api.openai.com/v1',
apiKey: 'your-api-key',
model: 'gpt-5.2',
// PageController options
enableMask: true,
viewportExpansion: 0,
})`}
/>
<p className="text-gray-600 dark:text-gray-400 mt-4">
{isZh
? 'PageAgentCore 接受 PageController 实例:'
: 'PageAgentCore accepts a PageController instance:'}
</p>
<CodeEditor
language="typescript"
code={`import { PageAgentCore } from '@page-agent/core'
import { PageController } from '@page-agent/page-controller'
const pageController = new PageController({
enableMask: true,
viewportExpansion: -1, // extract full page
})
const agent = new PageAgentCore({
pageController,
baseURL: 'https://api.openai.com/v1',
apiKey: 'your-api-key',
model: 'gpt-5.2',
})`}
/>
</section>
<APIDivider title={isZh ? '配置' : 'Configuration'} />
{/* Configuration */}
<section className="mb-10">
<Heading id="configuration">PageControllerConfig</Heading>
<APIReference
properties={[
{
name: 'enableMask',
type: 'boolean',
defaultValue: 'false',
description: isZh
? '启用视觉遮罩覆盖层,在自动化期间阻止用户操作页面。通过 PageAgent 创建时默认为 true。'
: 'Enable visual mask overlay that blocks user interaction during automation. Defaults to true when created via PageAgent.',
},
{
name: 'viewportExpansion',
type: 'number',
defaultValue: '0',
description: isZh
? '向视口外扩展提取的像素数。设为 -1 表示提取整个页面。'
: 'Pixels to expand extraction beyond viewport. Set to -1 to extract the entire page.',
},
{
name: 'interactiveBlacklist',
type: '(Element | (() => Element))[]',
description: isZh
? '要排除的交互元素列表。支持元素引用或返回元素的函数(延迟求值)。'
: 'Elements to exclude from interaction. Supports element references or functions returning elements (lazy evaluation).',
},
{
name: 'interactiveWhitelist',
type: '(Element | (() => Element))[]',
description: isZh
? '要强制包含的交互元素列表。支持元素引用或返回元素的函数。'
: 'Elements to force include for interaction. Supports element references or functions returning elements.',
},
{
name: 'includeAttributes',
type: 'string[]',
description: isZh
? '在 DOM 提取中包含的额外 HTML 属性(如 data-testid。默认已包含常见属性如 role, aria-label 等。'
: 'Additional HTML attributes to include in DOM extraction (e.g. data-testid). Common attributes like role, aria-label are included by default.',
},
]}
/>
</section>
<APIDivider title={isZh ? '方法' : 'Methods'} />
{/* Methods */}
<section className="mb-10">
<Heading id="methods">{isZh ? '方法' : 'Methods'}</Heading>
<h3 className="text-lg font-semibold mt-6 mb-3">{isZh ? '状态查询' : 'State Queries'}</h3>
<APIReference
variant="methods"
properties={[
{
name: 'getBrowserState()',
type: 'Promise<BrowserState>',
description: isZh
? '获取结构化的浏览器状态URL、标题、简化 HTML 等),自动调用 updateTree() 刷新 DOM。这是 Agent 在每步使用的主要方法。'
: 'Get structured browser state (URL, title, simplified HTML, etc.), automatically calls updateTree() to refresh DOM. This is the primary method the agent uses each step.',
},
{
name: 'updateTree()',
type: 'Promise<string>',
description: isZh
? '刷新 DOM 树并返回简化 HTML。通常不需要手动调用 —— getBrowserState() 会自动调用。'
: 'Refresh DOM tree and return simplified HTML. Usually not needed manually — getBrowserState() calls it automatically.',
},
{
name: 'getCurrentUrl()',
type: 'Promise<string>',
description: isZh ? '获取当前页面 URL。' : 'Get current page URL.',
},
]}
/>
<h3 className="text-lg font-semibold mt-6 mb-3">{isZh ? '元素操作' : 'Element Actions'}</h3>
<APIReference
variant="methods"
properties={[
{
name: 'clickElement(index)',
type: 'Promise<ActionResult>',
description: isZh
? '按索引点击元素。索引来自简化 HTML 中的 [N] 标记。'
: 'Click element by index. Index comes from [N] markers in simplified HTML.',
},
{
name: 'inputText(index, text)',
type: 'Promise<ActionResult>',
description: isZh ? '向输入框元素填入文本。' : 'Input text into a form element.',
},
{
name: 'selectOption(index, optionText)',
type: 'Promise<ActionResult>',
description: isZh ? '在下拉框中选择选项。' : 'Select option in a dropdown element.',
},
{
name: 'scroll(options)',
type: 'Promise<ActionResult>',
description: isZh
? '垂直滚动页面或指定元素。'
: 'Scroll page or specific element vertically.',
},
{
name: 'scrollHorizontally(options)',
type: 'Promise<ActionResult>',
description: isZh
? '水平滚动页面或指定元素。'
: 'Scroll page or specific element horizontally.',
},
]}
/>
<h3 className="text-lg font-semibold mt-6 mb-3">{isZh ? '遮罩控制' : 'Mask Control'}</h3>
<APIReference
variant="methods"
properties={[
{
name: 'showMask()',
type: 'Promise<void>',
description: isZh
? '显示视觉遮罩。需要 enableMask: true。'
: 'Show visual mask overlay. Requires enableMask: true.',
},
{
name: 'hideMask()',
type: 'Promise<void>',
description: isZh ? '隐藏视觉遮罩。' : 'Hide visual mask overlay.',
},
]}
/>
<h3 className="text-lg font-semibold mt-6 mb-3">{isZh ? '生命周期' : 'Lifecycle'}</h3>
<APIReference
variant="methods"
properties={[
{
name: 'dispose()',
type: 'void',
description: isZh
? '清理所有资源DOM 高亮、遮罩等。Agent 销毁时自动调用。'
: 'Clean up all resources (DOM highlights, mask, etc.). Called automatically when agent disposes.',
},
]}
/>
</section>
<APIDivider title={isZh ? '类型定义' : 'Type Definitions'} />
{/* BrowserState */}
<section className="mb-10">
<Heading id="browser-state">BrowserState</Heading>
<p className="text-gray-600 dark:text-gray-400 mb-4">
{isZh
? 'getBrowserState() 返回的结构化浏览器状态,直接用于构建 LLM prompt。'
: 'Structured browser state returned by getBrowserState(), used directly to build LLM prompts.'}
</p>
<CodeEditor
language="typescript"
code={`interface BrowserState {
url: string
title: string
header: string // page info + scroll position
content: string // simplified HTML of interactive elements
footer: string // scroll hint
}`}
/>
</section>
{/* ActionResult */}
<section className="mb-10">
<Heading id="action-result">ActionResult</Heading>
<CodeEditor
language="typescript"
code={`interface ActionResult {
success: boolean
message: string
}`}
/>
</section>
{/* Custom PageController */}
<section className="mb-10">
<Heading id="custom-implementation">
{isZh ? '自定义实现' : 'Custom Implementation'}
</Heading>
<p className="text-gray-600 dark:text-gray-400 mb-4">
{isZh
? '在非浏览器环境(如 Puppeteer、Playwright你可以实现自定义 PageController。需要实现 Agent 使用的核心方法:'
: 'In non-browser environments (e.g. Puppeteer, Playwright), you can implement a custom PageController. Implement the core methods used by the agent:'}
</p>
<CodeEditor
language="typescript"
code={`import { PageAgentCore } from '@page-agent/core'
import type { PageController } from '@page-agent/page-controller'
class PuppeteerPageController implements PageController {
async getBrowserState() { /* ... */ }
async clickElement(index: number) { /* ... */ }
async inputText(index: number, text: string) { /* ... */ }
async scroll(options: { down: boolean; numPages: number }) { /* ... */ }
// ... other methods
}
const agent = new PageAgentCore({
pageController: new PuppeteerPageController(),
baseURL: 'https://api.openai.com/v1',
apiKey: 'your-api-key',
model: 'gpt-5.2',
})`}
/>
</section>
</div>
)
}

View File

@@ -0,0 +1,89 @@
import BetaNotice from '@/components/BetaNotice'
import { Heading } from '@/components/Heading'
import { useLanguage } from '@/i18n/context'
export default function SecurityPermissions() {
const { isZh } = useLanguage()
return (
<div>
<BetaNotice />
<h1 className="text-4xl font-bold mb-6">{isZh ? '安全与权限' : 'Security & Permissions'}</h1>
<p className="text-xl text-gray-600 dark:text-gray-300 mb-8 leading-relaxed">
{isZh
? 'page-agent 提供多种安全机制,确保 AI 操作在可控范围内进行。'
: 'page-agent provides multiple security mechanisms to ensure AI operations stay within controlled boundaries.'}
</p>
<div className="space-y-6">
<section>
<Heading id="element-interaction-allowlist-blocklist" className="text-2xl font-bold mb-3">
{isZh ? '元素操作黑白名单' : 'Element Interaction Allowlist/Blocklist'}
</Heading>
<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">
🚫 {isZh ? '操作黑名单' : 'Blocklist'}
</h3>
<p className="text-gray-600 dark:text-gray-300">
{isZh
? '禁止 AI 操作敏感元素,如删除按钮、支付按钮等。'
: 'Prevent AI from interacting with sensitive elements like delete buttons, payment buttons, etc.'}
</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">
{isZh ? '操作白名单' : 'Allowlist'}
</h3>
<p className="text-gray-600 dark:text-gray-300">
{isZh
? '明确定义 AI 可以操作的元素范围。'
: 'Explicitly define which elements AI can interact with.'}
</p>
</div>
</div>
</section>
<section>
<Heading id="instruction-safety-constraints" className="text-2xl font-bold mb-3">
{isZh ? 'Instruction 安全约束' : 'Instruction Safety Constraints'}
</Heading>
<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">
{isZh ? '高危操作控制' : 'High-Risk Operation Control'}
</h3>
<p className="text-gray-600 dark:text-gray-300 mb-3">
{isZh
? '在 AI 指令中明确列举高危操作,通过两种策略进行控制:'
: 'Define high-risk operations in AI instructions and control them through two strategies:'}
</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">
{isZh ? '完全禁止操作' : 'Completely Forbidden'}
</p>
<p className="text-sm text-gray-500 dark:text-gray-400">
{isZh
? '对极高风险操作明确禁止执行'
: 'Explicitly prohibit execution of extremely high-risk operations'}
</p>
</div>
<div className="pl-3 border-l-2 border-orange-400">
<p className="font-medium text-orange-700 dark:text-orange-300">
{isZh ? '需用户确认操作' : 'Requires User Confirmation'}
</p>
<p className="text-sm text-gray-500 dark:text-gray-400">
{isZh
? '对中等风险操作要求用户明确同意'
: 'Require explicit user consent for medium-risk operations'}
</p>
</div>
</div>
</div>
</section>
</div>
</div>
)
}