feat: support custom tools
This commit is contained in:
@@ -15,23 +15,23 @@ The development progress and future plans for PageAgent.
|
|||||||
- [x] **Working homepage with live LLM API**
|
- [x] **Working homepage with live LLM API**
|
||||||
- [x] **~~free~~ CDN**
|
- [x] **~~free~~ CDN**
|
||||||
- [x] **Free evaluation plan?**
|
- [x] **Free evaluation plan?**
|
||||||
- [ ] **Hooks for Task and HITL**
|
- [x] **Custom actions and HITL**
|
||||||
|
- [ ] **Hooks and Events**
|
||||||
- [ ] **Hijacking `page_open` event**
|
- [ ] **Hijacking `page_open` event**
|
||||||
- [ ] **Custom knowledge base and instructions**
|
- [ ] **Custom knowledge base and instructions**
|
||||||
- [ ] **Black/white-list safeguard**
|
- [ ] **Black/white-list safeguard**
|
||||||
- [ ] **Data-masking**
|
- [ ] **Data-masking**
|
||||||
- [ ] **Custom actions**
|
|
||||||
- [ ] **Optimize for popular UI frameworks**
|
- [ ] **Optimize for popular UI frameworks**
|
||||||
- [ ] **Testing suits**
|
- [ ] **Testing suits**
|
||||||
- [ ] **Support custom llm fetch**
|
- [ ] **Support custom llm fetch**
|
||||||
- [ ] **Refactor: Separate Agent and Page-Controller** - Agent can run w/o dom
|
- [ ] **Refactor: Separate Agent and Page-Controller** - Agent should run w/o dom
|
||||||
|
|
||||||
♻️ Following browser-use's update and contribute back
|
♻️ Following browser-use's update and contribute back
|
||||||
|
|
||||||
## 📋 Pending Features
|
## 📋 Pending Features
|
||||||
|
|
||||||
- [ ] **Same-origin multi-page-app rally**
|
|
||||||
- [ ] **Chrome-ext wrapper**
|
- [ ] **Chrome-ext wrapper**
|
||||||
|
- [ ] **Same-origin multi-page-app rally**
|
||||||
- [ ] **Local MCP proxy**
|
- [ ] **Local MCP proxy**
|
||||||
|
|
||||||
## 🤔 To Be Decided
|
## 🤔 To Be Decided
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import { assert } from './utils/assert'
|
|||||||
import { getEventBus } from './utils/bus'
|
import { getEventBus } from './utils/bus'
|
||||||
|
|
||||||
export type { PageAgentConfig }
|
export type { PageAgentConfig }
|
||||||
|
export { tool, type PageAgentTool } from './tools'
|
||||||
|
|
||||||
export interface AgentBrain {
|
export interface AgentBrain {
|
||||||
// thinking?: string
|
// thinking?: string
|
||||||
@@ -76,6 +77,7 @@ export class PageAgent extends EventTarget {
|
|||||||
bus = getEventBus(this.id)
|
bus = getEventBus(this.id)
|
||||||
i18n: I18n
|
i18n: I18n
|
||||||
panel: Panel
|
panel: Panel
|
||||||
|
tools: typeof tools
|
||||||
paused = false
|
paused = false
|
||||||
disposed = false
|
disposed = false
|
||||||
task = ''
|
task = ''
|
||||||
@@ -98,8 +100,6 @@ export class PageAgent extends EventTarget {
|
|||||||
/** last time the tree was updated */
|
/** last time the tree was updated */
|
||||||
lastTimeUpdate = 0
|
lastTimeUpdate = 0
|
||||||
|
|
||||||
/** Corresponds to actions in browser-use */
|
|
||||||
tools = new Map(tools)
|
|
||||||
/** Fullscreen mask */
|
/** Fullscreen mask */
|
||||||
mask = new SimulatorMask()
|
mask = new SimulatorMask()
|
||||||
/** History records */
|
/** History records */
|
||||||
@@ -112,6 +112,17 @@ export class PageAgent extends EventTarget {
|
|||||||
this.#llm = new LLM(this.config, this.id)
|
this.#llm = new LLM(this.config, this.id)
|
||||||
this.i18n = new I18n(this.config.language)
|
this.i18n = new I18n(this.config.language)
|
||||||
this.panel = new Panel(this)
|
this.panel = new Panel(this)
|
||||||
|
this.tools = new Map(tools)
|
||||||
|
|
||||||
|
if (this.config.customTools) {
|
||||||
|
for (const [name, tool] of Object.entries(this.config.customTools)) {
|
||||||
|
if (tool === null) {
|
||||||
|
this.tools.delete(name)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
this.tools.set(name, tool)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
patchReact(this)
|
patchReact(this)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import type { DomConfig } from '@/dom'
|
import type { DomConfig } from '@/dom'
|
||||||
import type { SupportedLanguage } from '@/i18n'
|
import type { SupportedLanguage } from '@/i18n'
|
||||||
|
import type { PageAgentTool } from '@/tools'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
DEFAULT_API_KEY,
|
DEFAULT_API_KEY,
|
||||||
@@ -22,6 +23,30 @@ export interface LLMConfig {
|
|||||||
export interface UIConfig {
|
export interface UIConfig {
|
||||||
// theme?: 'light' | 'dark'
|
// theme?: 'light' | 'dark'
|
||||||
language?: SupportedLanguage
|
language?: SupportedLanguage
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
* 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}` + (await getSystemInfo())
|
||||||
|
* },
|
||||||
|
* })
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
customTools?: Record<string, PageAgentTool | null>
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PageAgentConfig = LLMConfig & DomConfig & UIConfig
|
export type PageAgentConfig = LLMConfig & DomConfig & UIConfig
|
||||||
|
|||||||
Reference in New Issue
Block a user