2025-10-21 20:05:39 +08:00
|
|
|
import type { AgentHistory, ExecutionResult, PageAgent } from '@/PageAgent'
|
2025-09-29 16:33:15 +08:00
|
|
|
import type { DomConfig } from '@/dom'
|
|
|
|
|
import type { SupportedLanguage } from '@/i18n'
|
2025-10-21 19:29:13 +08:00
|
|
|
import type { PageAgentTool } from '@/tools'
|
2025-09-29 16:33:15 +08:00
|
|
|
|
2025-10-20 22:44:02 +08:00
|
|
|
import {
|
|
|
|
|
DEFAULT_API_KEY,
|
|
|
|
|
DEFAULT_BASE_URL,
|
|
|
|
|
DEFAULT_MAX_TOKENS,
|
|
|
|
|
DEFAULT_MODEL_NAME,
|
|
|
|
|
DEFAULT_TEMPERATURE,
|
|
|
|
|
LLM_MAX_RETRIES,
|
|
|
|
|
} from './constants'
|
2025-10-10 17:46:40 +08:00
|
|
|
|
2025-10-17 18:43:41 +08:00
|
|
|
export interface LLMConfig {
|
|
|
|
|
baseURL?: string
|
|
|
|
|
apiKey?: string
|
2025-10-21 15:13:16 +08:00
|
|
|
model?: string
|
2025-10-17 18:43:41 +08:00
|
|
|
temperature?: number
|
|
|
|
|
maxTokens?: number
|
|
|
|
|
maxRetries?: number
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-29 16:33:15 +08:00
|
|
|
export interface UIConfig {
|
|
|
|
|
// theme?: 'light' | 'dark'
|
|
|
|
|
language?: SupportedLanguage
|
2025-10-21 19:29:13 +08:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 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
|
2025-10-21 20:05:39 +08:00
|
|
|
* // override internal tool
|
2025-10-21 19:29:13 +08:00
|
|
|
* 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)
|
2025-10-21 21:53:24 +08:00
|
|
|
* return `✅ Received user answer: ${answer}`
|
2025-10-21 19:29:13 +08:00
|
|
|
* },
|
|
|
|
|
* })
|
|
|
|
|
* }
|
2025-10-21 20:05:39 +08:00
|
|
|
*
|
|
|
|
|
* @example
|
|
|
|
|
* // remove internal tool
|
|
|
|
|
* const customTools = {
|
|
|
|
|
* ask_user: null // never ask user questions
|
|
|
|
|
* }
|
2025-10-21 19:29:13 +08:00
|
|
|
*/
|
|
|
|
|
customTools?: Record<string, PageAgentTool | null>
|
2025-10-21 19:39:06 +08:00
|
|
|
|
2025-10-21 20:05:39 +08:00
|
|
|
// lifecycle hooks
|
2025-10-21 21:31:35 +08:00
|
|
|
// @todo: use event instead of hooks
|
2025-10-21 19:39:06 +08:00
|
|
|
|
|
|
|
|
onBeforeStep?: (this: PageAgent, stepCnt: number) => Promise<void> | void
|
|
|
|
|
onAfterStep?: (this: PageAgent, stepCnt: number, history: AgentHistory[]) => Promise<void> | void
|
2025-10-21 21:31:35 +08:00
|
|
|
onBeforeTask?: (this: PageAgent) => Promise<void> | void
|
|
|
|
|
onAfterTask?: (this: PageAgent, result: ExecutionResult) => Promise<void> | void
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @note this hook can block the disposal process
|
2025-10-21 21:32:49 +08:00
|
|
|
* @note when dispose caused by page unload, `reason` will be 'PAGE_UNLOADING'. this method CANNOT block unloading. async operations may be cut.
|
2025-10-21 21:31:35 +08:00
|
|
|
*/
|
|
|
|
|
onDispose?: (this: PageAgent, reason?: string) => void
|
2025-10-21 20:05:39 +08:00
|
|
|
|
|
|
|
|
// page behavior hooks
|
|
|
|
|
|
2025-10-21 21:31:35 +08:00
|
|
|
/**
|
|
|
|
|
* 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
|
2025-09-29 16:33:15 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export type PageAgentConfig = LLMConfig & DomConfig & UIConfig
|
2025-10-10 17:46:40 +08:00
|
|
|
|
|
|
|
|
export function parseLLMConfig(config: LLMConfig): Required<LLMConfig> {
|
|
|
|
|
return {
|
|
|
|
|
baseURL: config.baseURL ?? DEFAULT_BASE_URL,
|
|
|
|
|
apiKey: config.apiKey ?? DEFAULT_API_KEY,
|
2025-10-21 15:13:16 +08:00
|
|
|
model: config.model ?? DEFAULT_MODEL_NAME,
|
2025-10-20 22:44:02 +08:00
|
|
|
temperature: config.temperature ?? DEFAULT_TEMPERATURE,
|
|
|
|
|
maxTokens: config.maxTokens ?? DEFAULT_MAX_TOKENS,
|
2025-10-10 17:46:40 +08:00
|
|
|
maxRetries: config.maxRetries ?? LLM_MAX_RETRIES,
|
|
|
|
|
}
|
|
|
|
|
}
|