feat!: Refine lifecycle hooks; fix abortSignal
- add `stop` method. agent can be reused after stopped - agent can not be reused after disposed - extension DO NOT exposes `dispose` anymore. only `stop`. - update panel for new `stop` method - fix MultiPageAgent dispose event - better handling abortSignal
This commit is contained in:
@@ -68,6 +68,8 @@ export class PageAgentCore extends EventTarget {
|
|||||||
taskId = ''
|
taskId = ''
|
||||||
/** History events */
|
/** History events */
|
||||||
history: HistoricalEvent[] = []
|
history: HistoricalEvent[] = []
|
||||||
|
/** Whether this agent has been disposed */
|
||||||
|
disposed = false
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback for when agent needs user input (ask_user tool)
|
* Callback for when agent needs user input (ask_user tool)
|
||||||
@@ -183,7 +185,15 @@ export class PageAgentCore extends EventTarget {
|
|||||||
this.#observations.push(content)
|
this.#observations.push(content)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Stop the current task. Agent remains reusable. */
|
||||||
|
stop() {
|
||||||
|
this.pageController.cleanUpHighlights()
|
||||||
|
this.pageController.hideMask()
|
||||||
|
this.#abortController.abort()
|
||||||
|
}
|
||||||
|
|
||||||
async execute(task: string): Promise<ExecutionResult> {
|
async execute(task: string): Promise<ExecutionResult> {
|
||||||
|
if (this.disposed) throw new Error('PageAgent has been disposed. Create a new instance.')
|
||||||
if (!task) throw new Error('Task is required')
|
if (!task) throw new Error('Task is required')
|
||||||
this.task = task
|
this.task = task
|
||||||
this.taskId = uid()
|
this.taskId = uid()
|
||||||
@@ -300,9 +310,13 @@ export class PageAgentCore extends EventTarget {
|
|||||||
}
|
}
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
console.groupEnd() // to prevent nested groups
|
console.groupEnd() // to prevent nested groups
|
||||||
|
const isAbortError = (error as any)?.rawError?.name === 'AbortError'
|
||||||
|
|
||||||
console.error('Task failed', error)
|
console.error('Task failed', error)
|
||||||
const errorMessage = String(error)
|
const errorMessage = isAbortError ? 'Task stopped' : String(error)
|
||||||
this.#emitActivity({ type: 'error', message: errorMessage })
|
this.#emitActivity({ type: 'error', message: errorMessage })
|
||||||
|
this.history.push({ type: 'error', message: errorMessage, rawResponse: error })
|
||||||
|
this.#emitHistoryChange()
|
||||||
this.#onDone(false)
|
this.#onDone(false)
|
||||||
const result: ExecutionResult = {
|
const result: ExecutionResult = {
|
||||||
success: false,
|
success: false,
|
||||||
@@ -315,10 +329,13 @@ export class PageAgentCore extends EventTarget {
|
|||||||
|
|
||||||
step++
|
step++
|
||||||
if (step > this.config.maxSteps) {
|
if (step > this.config.maxSteps) {
|
||||||
|
const errorMessage = 'Step count exceeded maximum limit'
|
||||||
|
this.history.push({ type: 'error', message: errorMessage })
|
||||||
|
this.#emitHistoryChange()
|
||||||
this.#onDone(false)
|
this.#onDone(false)
|
||||||
const result: ExecutionResult = {
|
const result: ExecutionResult = {
|
||||||
success: false,
|
success: false,
|
||||||
data: 'Step count exceeded maximum limit',
|
data: errorMessage,
|
||||||
history: this.history,
|
history: this.history,
|
||||||
}
|
}
|
||||||
await onAfterTask?.(this, result)
|
await onAfterTask?.(this, result)
|
||||||
@@ -601,6 +618,7 @@ export class PageAgentCore extends EventTarget {
|
|||||||
|
|
||||||
dispose() {
|
dispose() {
|
||||||
console.log('Disposing PageAgent...')
|
console.log('Disposing PageAgent...')
|
||||||
|
this.disposed = true
|
||||||
this.pageController.dispose()
|
this.pageController.dispose()
|
||||||
// this.history = []
|
// this.history = []
|
||||||
this.#abortController.abort()
|
this.#abortController.abort()
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ Parameters:
|
|||||||
|
|
||||||
Returns: `Promise<ExecutionResult>`
|
Returns: `Promise<ExecutionResult>`
|
||||||
|
|
||||||
#### `PAGE_AGENT_EXT.dispose()`
|
#### `PAGE_AGENT_EXT.stop()`
|
||||||
|
|
||||||
Stop the current task.
|
Stop the current task.
|
||||||
|
|
||||||
@@ -124,7 +124,6 @@ export interface ExecuteConfig {
|
|||||||
onStatusChange?: (status: AgentStatus) => void
|
onStatusChange?: (status: AgentStatus) => void
|
||||||
onActivity?: (activity: AgentActivity) => void
|
onActivity?: (activity: AgentActivity) => void
|
||||||
onHistoryUpdate?: (history: HistoricalEvent[]) => void
|
onHistoryUpdate?: (history: HistoricalEvent[]) => void
|
||||||
onDispose?: () => void
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Execute = (task: string, config: ExecuteConfig) => Promise<ExecutionResult>
|
export type Execute = (task: string, config: ExecuteConfig) => Promise<ExecutionResult>
|
||||||
@@ -189,7 +188,7 @@ const result = await window.PAGE_AGENT_EXT!.execute(
|
|||||||
### Stop the Current Task
|
### Stop the Current Task
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
window.PAGE_AGENT_EXT!.dispose()
|
window.PAGE_AGENT_EXT!.stop()
|
||||||
```
|
```
|
||||||
|
|
||||||
## Window Type Declaration
|
## Window Type Declaration
|
||||||
@@ -212,7 +211,6 @@ interface ExecuteConfig {
|
|||||||
onStatusChange?: (status: AgentStatus) => void
|
onStatusChange?: (status: AgentStatus) => void
|
||||||
onActivity?: (activity: AgentActivity) => void
|
onActivity?: (activity: AgentActivity) => void
|
||||||
onHistoryUpdate?: (history: HistoricalEvent[]) => void
|
onHistoryUpdate?: (history: HistoricalEvent[]) => void
|
||||||
onDispose?: () => void
|
|
||||||
}
|
}
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
@@ -221,7 +219,7 @@ declare global {
|
|||||||
PAGE_AGENT_EXT?: {
|
PAGE_AGENT_EXT?: {
|
||||||
version: string
|
version: string
|
||||||
execute: Execute
|
execute: Execute
|
||||||
dispose: () => void
|
stop: () => void
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ token 匹配后,插件会在 `window` 上注入 API。
|
|||||||
|
|
||||||
返回:`Promise<ExecutionResult>`
|
返回:`Promise<ExecutionResult>`
|
||||||
|
|
||||||
#### `PAGE_AGENT_EXT.dispose()`
|
#### `PAGE_AGENT_EXT.stop()`
|
||||||
|
|
||||||
停止当前任务。
|
停止当前任务。
|
||||||
|
|
||||||
@@ -124,7 +124,6 @@ export interface ExecuteConfig {
|
|||||||
onStatusChange?: (status: AgentStatus) => void
|
onStatusChange?: (status: AgentStatus) => void
|
||||||
onActivity?: (activity: AgentActivity) => void
|
onActivity?: (activity: AgentActivity) => void
|
||||||
onHistoryUpdate?: (history: HistoricalEvent[]) => void
|
onHistoryUpdate?: (history: HistoricalEvent[]) => void
|
||||||
onDispose?: () => void
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Execute = (task: string, config: ExecuteConfig) => Promise<ExecutionResult>
|
export type Execute = (task: string, config: ExecuteConfig) => Promise<ExecutionResult>
|
||||||
@@ -189,7 +188,7 @@ const result = await window.PAGE_AGENT_EXT!.execute(
|
|||||||
### 停止当前任务
|
### 停止当前任务
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
window.PAGE_AGENT_EXT!.dispose()
|
window.PAGE_AGENT_EXT!.stop()
|
||||||
```
|
```
|
||||||
|
|
||||||
## Window 类型声明
|
## Window 类型声明
|
||||||
@@ -212,7 +211,6 @@ interface ExecuteConfig {
|
|||||||
onStatusChange?: (status: AgentStatus) => void
|
onStatusChange?: (status: AgentStatus) => void
|
||||||
onActivity?: (activity: AgentActivity) => void
|
onActivity?: (activity: AgentActivity) => void
|
||||||
onHistoryUpdate?: (history: HistoricalEvent[]) => void
|
onHistoryUpdate?: (history: HistoricalEvent[]) => void
|
||||||
onDispose?: () => void
|
|
||||||
}
|
}
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
@@ -221,7 +219,7 @@ declare global {
|
|||||||
PAGE_AGENT_EXT?: {
|
PAGE_AGENT_EXT?: {
|
||||||
version: string
|
version: string
|
||||||
execute: Execute
|
execute: Execute
|
||||||
dispose: () => void
|
stop: () => void
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,8 +89,7 @@ export class MultiPageAgent extends PageAgentCore {
|
|||||||
isAgentRunning: false,
|
isAgentRunning: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
// no need to dispose tabsController and pageController
|
tabsController.dispose()
|
||||||
// as they do not keep references
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ export function useAgent(): UseAgentResult {
|
|||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const stop = useCallback(() => {
|
const stop = useCallback(() => {
|
||||||
agentRef.current?.dispose()
|
agentRef.current?.stop()
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const configure = useCallback(async (newConfig: LLMConfig) => {
|
const configure = useCallback(async (newConfig: LLMConfig) => {
|
||||||
|
|||||||
@@ -71,7 +71,8 @@ async function exposeAgentToPage() {
|
|||||||
try {
|
try {
|
||||||
const { task, config } = payload
|
const { task, config } = payload
|
||||||
|
|
||||||
// create when used
|
// Dispose old instance before creating new one
|
||||||
|
multiPageAgent?.dispose()
|
||||||
|
|
||||||
multiPageAgent = new MultiPageAgent(config)
|
multiPageAgent = new MultiPageAgent(config)
|
||||||
|
|
||||||
@@ -116,17 +117,6 @@ async function exposeAgentToPage() {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
multiPageAgent.addEventListener('dispose', () => {
|
|
||||||
window.postMessage(
|
|
||||||
{
|
|
||||||
channel: 'PAGE_AGENT_EXT_RESPONSE',
|
|
||||||
id,
|
|
||||||
action: 'dispose_event',
|
|
||||||
},
|
|
||||||
'*'
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
// result
|
// result
|
||||||
|
|
||||||
const result = await multiPageAgent.execute(task)
|
const result = await multiPageAgent.execute(task)
|
||||||
@@ -155,9 +145,8 @@ async function exposeAgentToPage() {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'dispose': {
|
case 'stop': {
|
||||||
// @note stop ongoing processes but can still be re-used later
|
multiPageAgent?.stop()
|
||||||
multiPageAgent?.dispose()
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ export interface ExecuteConfig {
|
|||||||
onStatusChange?: (status: AgentStatus) => void
|
onStatusChange?: (status: AgentStatus) => void
|
||||||
onActivity?: (activity: AgentActivity) => void
|
onActivity?: (activity: AgentActivity) => void
|
||||||
onHistoryUpdate?: (history: HistoricalEvent[]) => void
|
onHistoryUpdate?: (history: HistoricalEvent[]) => void
|
||||||
onDispose?: () => void
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default defineUnlistedScript(() => {
|
export default defineUnlistedScript(() => {
|
||||||
@@ -60,12 +59,6 @@ export default defineUnlistedScript(() => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.action === 'dispose_event' && config.onDispose) {
|
|
||||||
config.onDispose()
|
|
||||||
window.removeEventListener('message', handleMessage)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.action !== 'execute_result') return
|
if (data.action !== 'execute_result') return
|
||||||
|
|
||||||
// execute_result
|
// execute_result
|
||||||
@@ -104,14 +97,14 @@ export default defineUnlistedScript(() => {
|
|||||||
return promise
|
return promise
|
||||||
}
|
}
|
||||||
|
|
||||||
const dispose = () => {
|
const stop = () => {
|
||||||
const id = getId()
|
const id = getId()
|
||||||
|
|
||||||
window.postMessage(
|
window.postMessage(
|
||||||
{
|
{
|
||||||
channel: 'PAGE_AGENT_EXT_REQUEST',
|
channel: 'PAGE_AGENT_EXT_REQUEST',
|
||||||
id,
|
id,
|
||||||
action: 'dispose',
|
action: 'stop',
|
||||||
},
|
},
|
||||||
'*'
|
'*'
|
||||||
)
|
)
|
||||||
@@ -121,6 +114,6 @@ export default defineUnlistedScript(() => {
|
|||||||
;(window as any).PAGE_AGENT_EXT = {
|
;(window as any).PAGE_AGENT_EXT = {
|
||||||
version: __EXT_VERSION__,
|
version: __EXT_VERSION__,
|
||||||
execute,
|
execute,
|
||||||
dispose,
|
stop,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -54,8 +54,10 @@ export class OpenAIClient implements LLMClient {
|
|||||||
signal: abortSignal,
|
signal: abortSignal,
|
||||||
})
|
})
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
console.error(error)
|
const isAbortError = (error as any)?.name === 'AbortError'
|
||||||
throw new InvokeError(InvokeErrorType.NETWORK_ERROR, 'Network request failed', error)
|
const errorMessage = isAbortError ? 'Network request aborted' : 'Network request failed'
|
||||||
|
if (!isAbortError) console.error(error)
|
||||||
|
throw new InvokeError(InvokeErrorType.NETWORK_ERROR, errorMessage, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Handle HTTP errors
|
// 3. Handle HTTP errors
|
||||||
|
|||||||
@@ -34,12 +34,15 @@ export class InvokeError extends Error {
|
|||||||
super(message)
|
super(message)
|
||||||
this.name = 'InvokeError'
|
this.name = 'InvokeError'
|
||||||
this.type = type
|
this.type = type
|
||||||
this.retryable = this.isRetryable(type)
|
this.retryable = this.isRetryable(type, rawError)
|
||||||
this.rawError = rawError
|
this.rawError = rawError
|
||||||
this.rawResponse = rawResponse
|
this.rawResponse = rawResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
private isRetryable(type: InvokeErrorType): boolean {
|
private isRetryable(type: InvokeErrorType, rawError?: unknown): boolean {
|
||||||
|
const isAbortError = (rawError as any)?.name === 'AbortError'
|
||||||
|
if (isAbortError) return false
|
||||||
|
|
||||||
const retryableTypes: InvokeErrorType[] = [
|
const retryableTypes: InvokeErrorType[] = [
|
||||||
InvokeErrorType.NETWORK_ERROR,
|
InvokeErrorType.NETWORK_ERROR,
|
||||||
InvokeErrorType.RATE_LIMIT,
|
InvokeErrorType.RATE_LIMIT,
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ const enUS = {
|
|||||||
question: 'Question: {{question}}',
|
question: 'Question: {{question}}',
|
||||||
waitingPlaceholder: 'Waiting for task to start...',
|
waitingPlaceholder: 'Waiting for task to start...',
|
||||||
stop: 'Stop',
|
stop: 'Stop',
|
||||||
|
close: 'Close',
|
||||||
expand: 'Expand history',
|
expand: 'Expand history',
|
||||||
collapse: 'Collapse history',
|
collapse: 'Collapse history',
|
||||||
step: 'Step {{number}} · {{time}}{{duration}}',
|
step: 'Step {{number}} · {{time}}{{duration}}',
|
||||||
@@ -59,6 +60,7 @@ const zhCN = {
|
|||||||
question: '询问: {{question}}',
|
question: '询问: {{question}}',
|
||||||
waitingPlaceholder: '等待任务开始...',
|
waitingPlaceholder: '等待任务开始...',
|
||||||
stop: '终止',
|
stop: '终止',
|
||||||
|
close: '关闭',
|
||||||
expand: '展开历史',
|
expand: '展开历史',
|
||||||
collapse: '收起历史',
|
collapse: '收起历史',
|
||||||
step: '步骤 {{number}} · {{time}}{{duration}}',
|
step: '步骤 {{number}} · {{time}}{{duration}}',
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ export class Panel {
|
|||||||
#statusText: HTMLElement
|
#statusText: HTMLElement
|
||||||
#historySection: HTMLElement
|
#historySection: HTMLElement
|
||||||
#expandButton: HTMLElement
|
#expandButton: HTMLElement
|
||||||
#stopButton: HTMLElement
|
#actionButton: HTMLElement
|
||||||
#inputSection: HTMLElement
|
#inputSection: HTMLElement
|
||||||
#taskInput: HTMLInputElement
|
#taskInput: HTMLInputElement
|
||||||
|
|
||||||
@@ -76,7 +76,7 @@ export class Panel {
|
|||||||
this.#statusText = this.#wrapper.querySelector(`.${styles.statusText}`)!
|
this.#statusText = this.#wrapper.querySelector(`.${styles.statusText}`)!
|
||||||
this.#historySection = this.#wrapper.querySelector(`.${styles.historySection}`)!
|
this.#historySection = this.#wrapper.querySelector(`.${styles.historySection}`)!
|
||||||
this.#expandButton = this.#wrapper.querySelector(`.${styles.expandButton}`)!
|
this.#expandButton = this.#wrapper.querySelector(`.${styles.expandButton}`)!
|
||||||
this.#stopButton = this.#wrapper.querySelector(`.${styles.stopButton}`)!
|
this.#actionButton = this.#wrapper.querySelector(`.${styles.stopButton}`)!
|
||||||
this.#inputSection = this.#wrapper.querySelector(`.${styles.inputSectionWrapper}`)!
|
this.#inputSection = this.#wrapper.querySelector(`.${styles.inputSectionWrapper}`)!
|
||||||
this.#taskInput = this.#wrapper.querySelector(`.${styles.taskInput}`)!
|
this.#taskInput = this.#wrapper.querySelector(`.${styles.taskInput}`)!
|
||||||
|
|
||||||
@@ -105,6 +105,15 @@ export class Panel {
|
|||||||
status === 'running' ? 'thinking' : status === 'idle' ? 'thinking' : status
|
status === 'running' ? 'thinking' : status === 'idle' ? 'thinking' : status
|
||||||
this.#updateStatusIndicator(indicatorType)
|
this.#updateStatusIndicator(indicatorType)
|
||||||
|
|
||||||
|
// Morph action button: running = stop (■), not running = close (X)
|
||||||
|
if (status === 'running') {
|
||||||
|
this.#actionButton.textContent = '■'
|
||||||
|
this.#actionButton.title = this.#i18n.t('ui.panel.stop')
|
||||||
|
} else {
|
||||||
|
this.#actionButton.textContent = 'X'
|
||||||
|
this.#actionButton.title = this.#i18n.t('ui.panel.close')
|
||||||
|
}
|
||||||
|
|
||||||
// Show/hide based on status
|
// Show/hide based on status
|
||||||
if (status === 'running') {
|
if (status === 'running') {
|
||||||
this.show()
|
this.show()
|
||||||
@@ -266,10 +275,14 @@ export class Panel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop Agent
|
* Action button handler: stop when running, close (dispose) when idle
|
||||||
*/
|
*/
|
||||||
#stopAgent(): void {
|
#handleActionButton(): void {
|
||||||
this.#agent.dispose()
|
if (this.#agent.status === 'running') {
|
||||||
|
this.#agent.stop()
|
||||||
|
} else {
|
||||||
|
this.#agent.dispose()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -383,7 +396,7 @@ export class Panel {
|
|||||||
<button class="${styles.controlButton} ${styles.expandButton}" title="${this.#i18n.t('ui.panel.expand')}">
|
<button class="${styles.controlButton} ${styles.expandButton}" title="${this.#i18n.t('ui.panel.expand')}">
|
||||||
▼
|
▼
|
||||||
</button>
|
</button>
|
||||||
<button class="${styles.controlButton} ${styles.stopButton}" title="${this.#i18n.t('ui.panel.stop')}">
|
<button class="${styles.controlButton} ${styles.stopButton}" title="${this.#i18n.t('ui.panel.close')}">
|
||||||
X
|
X
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -420,10 +433,10 @@ export class Panel {
|
|||||||
this.#toggle()
|
this.#toggle()
|
||||||
})
|
})
|
||||||
|
|
||||||
// Stop button
|
// Action button (stop / close)
|
||||||
this.#stopButton.addEventListener('click', (e) => {
|
this.#actionButton.addEventListener('click', (e) => {
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
this.#stopAgent()
|
this.#handleActionButton()
|
||||||
})
|
})
|
||||||
|
|
||||||
// Submit on Enter key in input field
|
// Submit on Enter key in input field
|
||||||
|
|||||||
@@ -68,6 +68,9 @@ export interface PanelAgentAdapter extends EventTarget {
|
|||||||
/** Execute a task */
|
/** Execute a task */
|
||||||
execute(task: string): Promise<unknown>
|
execute(task: string): Promise<unknown>
|
||||||
|
|
||||||
/** Dispose the agent */
|
/** Stop the current task (agent remains reusable) */
|
||||||
|
stop(): void
|
||||||
|
|
||||||
|
/** Dispose the agent (terminal, cannot be reused) */
|
||||||
dispose(): void
|
dispose(): void
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -206,7 +206,6 @@ interface ExecuteConfig {
|
|||||||
onStatusChange?: (status: AgentStatus) => void
|
onStatusChange?: (status: AgentStatus) => void
|
||||||
onActivity?: (activity: AgentActivity) => void
|
onActivity?: (activity: AgentActivity) => void
|
||||||
onHistoryUpdate?: (history: HistoricalEvent[]) => void
|
onHistoryUpdate?: (history: HistoricalEvent[]) => void
|
||||||
onDispose?: () => void
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Execute = (task: string, config: ExecuteConfig) => Promise<ExecutionResult>
|
type Execute = (task: string, config: ExecuteConfig) => Promise<ExecutionResult>
|
||||||
@@ -217,7 +216,7 @@ declare global {
|
|||||||
PAGE_AGENT_EXT?: {
|
PAGE_AGENT_EXT?: {
|
||||||
version: string
|
version: string
|
||||||
execute: Execute
|
execute: Execute
|
||||||
dispose: () => void
|
stop: () => void
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}`
|
}`
|
||||||
@@ -237,7 +236,6 @@ interface ExecuteConfig {
|
|||||||
onStatusChange?: (status: AgentStatus) => void
|
onStatusChange?: (status: AgentStatus) => void
|
||||||
onActivity?: (activity: AgentActivity) => void
|
onActivity?: (activity: AgentActivity) => void
|
||||||
onHistoryUpdate?: (history: HistoricalEvent[]) => void
|
onHistoryUpdate?: (history: HistoricalEvent[]) => void
|
||||||
onDispose?: () => void
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Execute = (task: string, config: ExecuteConfig) => Promise<ExecutionResult>
|
type Execute = (task: string, config: ExecuteConfig) => Promise<ExecutionResult>
|
||||||
@@ -248,7 +246,7 @@ declare global {
|
|||||||
PAGE_AGENT_EXT?: {
|
PAGE_AGENT_EXT?: {
|
||||||
version: string
|
version: string
|
||||||
execute: Execute
|
execute: Execute
|
||||||
dispose: () => void
|
stop: () => void
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}`
|
}`
|
||||||
@@ -271,8 +269,7 @@ const result = await window.PAGE_AGENT_EXT.execute(
|
|||||||
// includeInitialTab: false, // 设为 false 排除初始标签页
|
// includeInitialTab: false, // 设为 false 排除初始标签页
|
||||||
onStatusChange: status => console.log('状态变化:', status),
|
onStatusChange: status => console.log('状态变化:', status),
|
||||||
onActivity: activity => console.log('活动:', activity),
|
onActivity: activity => console.log('活动:', activity),
|
||||||
onHistoryUpdate: history => console.log('历史更新:', history),
|
onHistoryUpdate: history => console.log('历史更新:', history)
|
||||||
onDispose: () => console.log('已停止')
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -287,8 +284,7 @@ const result = await window.PAGE_AGENT_EXT.execute(
|
|||||||
// includeInitialTab: false, // Set to false to exclude initial tab
|
// includeInitialTab: false, // Set to false to exclude initial tab
|
||||||
onStatusChange: status => console.log('Status change:', status),
|
onStatusChange: status => console.log('Status change:', status),
|
||||||
onActivity: activity => console.log('Activity:', activity),
|
onActivity: activity => console.log('Activity:', activity),
|
||||||
onHistoryUpdate: history => console.log('History update:', history),
|
onHistoryUpdate: history => console.log('History update:', history)
|
||||||
onDispose: () => console.log('Disposed')
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -297,20 +293,18 @@ console.log(result) // Task execution result`
|
|||||||
language="javascript"
|
language="javascript"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<h3 className="text-xl font-semibold mt-6 mb-3">PAGE_AGENT_EXT.dispose()</h3>
|
<h3 className="text-xl font-semibold mt-6 mb-3">PAGE_AGENT_EXT.stop()</h3>
|
||||||
<p className="text-gray-600 dark:text-gray-300 mb-4">
|
<p className="text-gray-600 dark:text-gray-300 mb-4">
|
||||||
{isZh
|
{isZh ? '停止当前正在运行的任务。' : 'Stop the current running task.'}
|
||||||
? '停止当前正在运行的任务。停止后 Agent 可以重新使用。'
|
|
||||||
: 'Stop the current running task. The agent can be reused after disposal.'}
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<CodeEditor
|
<CodeEditor
|
||||||
code={
|
code={
|
||||||
isZh
|
isZh
|
||||||
? `// 停止当前任务
|
? `// 停止当前任务
|
||||||
window.PAGE_AGENT_EXT.dispose()`
|
window.PAGE_AGENT_EXT.stop()`
|
||||||
: `// Stop current task execution
|
: `// Stop current task execution
|
||||||
window.PAGE_AGENT_EXT.dispose()`
|
window.PAGE_AGENT_EXT.stop()`
|
||||||
}
|
}
|
||||||
language="javascript"
|
language="javascript"
|
||||||
/>
|
/>
|
||||||
|
|||||||
Reference in New Issue
Block a user