From 6f0ff1fd33f1f30d27a400fac53c1c09dc21cf7f Mon Sep 17 00:00:00 2001 From: Simon <10131203+gaomeng1900@users.noreply.github.com> Date: Mon, 9 Feb 2026 17:49:10 +0800 Subject: [PATCH] refactor: zod tree-shaking; better error handling in agent steps --- package-lock.json | 11 +++ package.json | 3 +- packages/core/src/PageAgentCore.ts | 69 ++++++++++--------- packages/core/src/tools/index.ts | 4 +- packages/core/src/utils/assert.ts | 17 ----- packages/core/src/utils/index.ts | 18 +++++ packages/extension/src/agent/tabTools.ts | 2 +- packages/llms/src/utils.ts | 2 +- packages/page-agent/package.json | 8 +-- packages/page-agent/vite.iife.config.js | 8 ++- .../pages/docs/features/custom-tools/page.tsx | 2 +- .../introduction/troubleshooting/page.tsx | 5 -- 12 files changed, 82 insertions(+), 67 deletions(-) delete mode 100644 packages/core/src/utils/assert.ts diff --git a/package-lock.json b/package-lock.json index e0cc8d8..be34bc2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -41,6 +41,7 @@ "typescript-eslint": "^8.54.0", "unplugin-dts": "^1.0.0-beta.6", "vite": "^7.3.1", + "vite-bundle-analyzer": "^1.3.6", "vite-plugin-css-injected-by-js": "^3.5.2" }, "engines": { @@ -10411,6 +10412,16 @@ } } }, + "node_modules/vite-bundle-analyzer": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/vite-bundle-analyzer/-/vite-bundle-analyzer-1.3.6.tgz", + "integrity": "sha512-elFXkF9oGy4CJEeOdP1DSEHRDKWfmaEDfT9/GuF4jmyfmUF6nC//iN+ythqMEVvrtchOEHGKLumZwnu1NjoI0w==", + "dev": true, + "license": "MIT", + "bin": { + "analyze": "dist/bin.js" + } + }, "node_modules/vite-node": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-5.3.0.tgz", diff --git a/package.json b/package.json index 3ee9c0a..c21a6df 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,8 @@ "typescript-eslint": "^8.54.0", "unplugin-dts": "^1.0.0-beta.6", "vite": "^7.3.1", - "vite-plugin-css-injected-by-js": "^3.5.2" + "vite-plugin-css-injected-by-js": "^3.5.2", + "vite-bundle-analyzer": "^1.3.6" }, "overrides": { "typescript": "^5.9.3" diff --git a/packages/core/src/PageAgentCore.ts b/packages/core/src/PageAgentCore.ts index ee38e47..c069e97 100644 --- a/packages/core/src/PageAgentCore.ts +++ b/packages/core/src/PageAgentCore.ts @@ -5,13 +5,13 @@ import { InvokeError, LLM, type Tool } from '@page-agent/llms' import type { PageController } from '@page-agent/page-controller' import chalk from 'chalk' -import zod from 'zod' +import * as zod from 'zod' import { type PageAgentConfig } from './config' import { DEFAULT_MAX_STEPS } from './config/constants' import SYSTEM_PROMPT from './prompts/system_prompt.md?raw' import { tools } from './tools' -import { +import type { AgentActivity, AgentReflection, AgentStatus, @@ -21,8 +21,7 @@ import { MacroToolInput, MacroToolResult, } from './types' -import { normalizeResponse, trimLines, uid, waitFor } from './utils' -import { assert } from './utils/assert' +import { assert, normalizeResponse, trimLines, uid, waitFor } from './utils' export { type PageAgentConfig } export { tool, type PageAgentTool } from './tools' @@ -209,20 +208,20 @@ export class PageAgentCore extends EventTarget { lastURL: '', } - try { - let step = 0 + let step = 0 + + while (true) { + try { + console.group(`step: ${step}`) - while (true) { await this.#generateObservations(step) await onBeforeStep?.(this, step) - console.group(`step: ${step}`) - // abort if (this.#abortController.signal.aborted) throw new Error('AbortError') - // Thinking + // status console.log(chalk.blue('Thinking...')) this.#emitActivity({ type: 'thinking' }) @@ -270,22 +269,13 @@ export class PageAgentCore extends EventTarget { // + await onAfterStep?.(this, this.history) + console.log(chalk.green('Step finished:'), actionName) console.groupEnd() - await onAfterStep?.(this, this.history) + // finish task if done - step++ - if (step > this.config.maxSteps) { - this.#onDone(false) - const result: ExecutionResult = { - success: false, - data: 'Step count exceeded maximum limit', - history: this.history, - } - await onAfterTask?.(this, result) - return result - } if (actionName === 'done') { const success = action.input?.success ?? false const text = action.input?.text || 'no text provided' @@ -299,19 +289,32 @@ export class PageAgentCore extends EventTarget { await onAfterTask?.(this, result) return result } + } catch (error: unknown) { + console.groupEnd() // to prevent nested groups + console.error('Task failed', error) + const errorMessage = String(error) + this.#emitActivity({ type: 'error', message: errorMessage }) + this.#onDone(false) + const result: ExecutionResult = { + success: false, + data: errorMessage, + history: this.history, + } + await onAfterTask?.(this, result) + return result } - } catch (error: unknown) { - console.error('Task failed', error) - const errorMessage = String(error) - this.#emitActivity({ type: 'error', message: errorMessage }) - this.#onDone(false) - const result: ExecutionResult = { - success: false, - data: errorMessage, - history: this.history, + + step++ + if (step > this.config.maxSteps) { + this.#onDone(false) + const result: ExecutionResult = { + success: false, + data: 'Step count exceeded maximum limit', + history: this.history, + } + await onAfterTask?.(this, result) + return result } - await onAfterTask?.(this, result) - return result } } diff --git a/packages/core/src/tools/index.ts b/packages/core/src/tools/index.ts index 3358cd0..458f9fd 100644 --- a/packages/core/src/tools/index.ts +++ b/packages/core/src/tools/index.ts @@ -2,7 +2,7 @@ * Internal tools for PageAgent. * @note Adapted from browser-use */ -import zod, { type z } from 'zod' +import * as zod from 'zod' import type { PageAgentCore } from '../PageAgentCore' import { waitFor } from '../utils' @@ -13,7 +13,7 @@ import { waitFor } from '../utils' export interface PageAgentTool { // name: string description: string - inputSchema: z.ZodType + inputSchema: zod.ZodType execute: (this: PageAgentCore, args: TParams) => Promise } diff --git a/packages/core/src/utils/assert.ts b/packages/core/src/utils/assert.ts deleted file mode 100644 index e8c20e6..0000000 --- a/packages/core/src/utils/assert.ts +++ /dev/null @@ -1,17 +0,0 @@ -import chalk from 'chalk' - -/** - * Simple assertion function that throws an error if the condition is falsy - * @param condition - The condition to assert - * @param message - Optional error message - * @throws Error if condition is falsy - */ -export function assert(condition: unknown, message?: string, silent?: boolean): asserts condition { - if (!condition) { - const errorMessage = message ?? 'Assertion failed' - - if (!silent) console.error(chalk.red(`❌ assert: ${errorMessage}`)) - - throw new Error(errorMessage) - } -} diff --git a/packages/core/src/utils/index.ts b/packages/core/src/utils/index.ts index 9efc1b6..3ad473b 100644 --- a/packages/core/src/utils/index.ts +++ b/packages/core/src/utils/index.ts @@ -1,3 +1,5 @@ +import chalk from 'chalk' + export { normalizeResponse } from './autoFixer' /** @@ -85,3 +87,19 @@ export function uid() { ids.push(id) return id } + +/** + * Simple assertion function that throws an error if the condition is falsy + * @param condition - The condition to assert + * @param message - Optional error message + * @throws Error if condition is falsy + */ +export function assert(condition: unknown, message?: string, silent?: boolean): asserts condition { + if (!condition) { + const errorMessage = message ?? 'Assertion failed' + + if (!silent) console.error(chalk.red(`❌ assert: ${errorMessage}`)) + + throw new Error(errorMessage) + } +} diff --git a/packages/extension/src/agent/tabTools.ts b/packages/extension/src/agent/tabTools.ts index 89998e8..210ffdd 100644 --- a/packages/extension/src/agent/tabTools.ts +++ b/packages/extension/src/agent/tabTools.ts @@ -6,7 +6,7 @@ * - switch_to_tab: Switch to an existing tab * - close_tab: Close a tab (optionally switch to another) */ -import zod from 'zod' +import * as zod from 'zod' import type { TabsController } from './TabsController' diff --git a/packages/llms/src/utils.ts b/packages/llms/src/utils.ts index 0a03c74..88bd8d6 100644 --- a/packages/llms/src/utils.ts +++ b/packages/llms/src/utils.ts @@ -2,7 +2,7 @@ * Utility functions for LLM integration */ import chalk from 'chalk' -import { z } from 'zod' +import * as z from 'zod' import type { Tool } from './types' diff --git a/packages/page-agent/package.json b/packages/page-agent/package.json index 32b36a4..ce164e5 100644 --- a/packages/page-agent/package.json +++ b/packages/page-agent/package.json @@ -44,11 +44,11 @@ "postpublish": "node -e \"['README.md','LICENSE'].forEach(f=>{try{require('fs').unlinkSync(f)}catch{}})\"" }, "dependencies": { - "chalk": "^5.6.2", - "zod": "^4.3.5", + "@page-agent/core": "1.1.1", "@page-agent/llms": "1.1.1", "@page-agent/page-controller": "1.1.1", - "@page-agent/core": "1.1.1", - "@page-agent/ui": "1.1.1" + "@page-agent/ui": "1.1.1", + "chalk": "^5.6.2", + "zod": "^4.3.5" } } diff --git a/packages/page-agent/vite.iife.config.js b/packages/page-agent/vite.iife.config.js index 625eb1f..22f882f 100644 --- a/packages/page-agent/vite.iife.config.js +++ b/packages/page-agent/vite.iife.config.js @@ -3,6 +3,7 @@ import { config as dotenvConfig } from 'dotenv' import { dirname, resolve } from 'path' import { fileURLToPath } from 'url' import { defineConfig } from 'vite' +// import { analyzer } from 'vite-bundle-analyzer' import cssInjectedByJsPlugin from 'vite-plugin-css-injected-by-js' const __dirname = dirname(fileURLToPath(import.meta.url)) @@ -14,8 +15,11 @@ dotenvConfig({ path: resolve(__dirname, '../../.env') }) // - alias all local packages so that they can be build in // - no external // - no d.ts. dts does not work with monorepo aliasing -export default defineConfig(({ mode }) => ({ - plugins: [cssInjectedByJsPlugin({ relativeCSSInjection: true })], +export default defineConfig(() => ({ + plugins: [ + cssInjectedByJsPlugin({ relativeCSSInjection: true }), + // analyzer() + ], publicDir: false, esbuild: { keepNames: true, diff --git a/packages/website/src/pages/docs/features/custom-tools/page.tsx b/packages/website/src/pages/docs/features/custom-tools/page.tsx index 29e5a1f..6ffcb64 100644 --- a/packages/website/src/pages/docs/features/custom-tools/page.tsx +++ b/packages/website/src/pages/docs/features/custom-tools/page.tsx @@ -25,7 +25,7 @@ export default function CustomTools() {

Troubleshooting

- {/*

- {isZh - ? '遇到问题了?按症状查找解决方案。' - : 'Running into issues? Find solutions by symptom.'} -

*/} {/* Two-column: content + TOC */}