diff --git a/packages/core/src/PageAgentCore.ts b/packages/core/src/PageAgentCore.ts index 3a150b7..f5dc5f3 100644 --- a/packages/core/src/PageAgentCore.ts +++ b/packages/core/src/PageAgentCore.ts @@ -73,7 +73,7 @@ export class PageAgentCore extends EventTarget { #observations: string[] = [] /** internal states of a single task execution */ - states = { + #states = { /** Accumulated wait time in seconds */ totalWaitTime: 0, /** Last known URL for detecting navigation */ @@ -201,11 +201,8 @@ export class PageAgentCore extends EventTarget { this.#setStatus('running') this.#emitHistoryChange() - // Reset states - this.states = { - totalWaitTime: 0, - lastURL: '', - } + // Reset internal states + this.#states = { totalWaitTime: 0, lastURL: '' } let step = 0 @@ -213,18 +210,10 @@ export class PageAgentCore extends EventTarget { try { console.group(`step: ${step}`) - await this.#systemObservations(step) - - if (this.#observations.length > 0) { - for (const content of this.#observations) { - this.history.push({ type: 'observation', content }) - } - this.#observations = [] - this.#emitHistoryChange() - } - await onBeforeStep?.(this, step) + await this.#handleObservations(step) + // abort if (this.#abortController.signal.aborted) throw new Error('AbortError') @@ -405,9 +394,11 @@ export class PageAgentCore extends EventTarget { duration, }) - // Reset wait time for non-wait tools - if (toolName !== 'wait') { - this.states.totalWaitTime = 0 + // counting wait time + if (toolName === 'wait') { + this.#states.totalWaitTime += toolInput?.seconds || 0 + } else { + this.#states.totalWaitTime = 0 } // Return structured result @@ -476,22 +467,27 @@ export class PageAgentCore extends EventTarget { /** * Generate system observations before each step - * - URL change detection - * - Too many steps warning * @todo loop detection * @todo console error */ - async #systemObservations(stepCount: number): Promise { + async #handleObservations(step: number): Promise { + // Accumulated wait time warning + if (this.#states.totalWaitTime >= 3) { + this.pushObservation( + `You have waited ${this.#states.totalWaitTime} seconds accumulatively. DO NOT wait any longer unless you have a good reason.` + ) + } + // Detect URL change const currentURL = await this.pageController.getCurrentUrl() - if (currentURL !== this.states.lastURL) { + if (currentURL !== this.#states.lastURL) { this.pushObservation(`Page navigated to → ${currentURL}`) - this.states.lastURL = currentURL + this.#states.lastURL = currentURL await waitFor(0.5) // wait for page to stabilize } - // Warn about remaining steps - const remaining = this.config.maxSteps - stepCount + // Remaining steps warning + const remaining = this.config.maxSteps - step if (remaining === 5) { this.pushObservation( `⚠️ Only ${remaining} steps remaining. Consider wrapping up or calling done with partial results.` @@ -501,6 +497,15 @@ export class PageAgentCore extends EventTarget { `⚠️ Critical: Only ${remaining} steps left! You must finish the task or call done immediately.` ) } + + // Push observations to history and emit + if (this.#observations.length > 0) { + for (const content of this.#observations) { + this.history.push({ type: 'observation', content }) + } + this.#observations = [] + this.#emitHistoryChange() + } } async #assembleUserPrompt(): Promise { diff --git a/packages/core/src/tools/index.ts b/packages/core/src/tools/index.ts index bf95b61..a39c56d 100644 --- a/packages/core/src/tools/index.ts +++ b/packages/core/src/tools/index.ts @@ -38,7 +38,6 @@ tools.set( }), execute: async function (this: PageAgentCore, input) { // @note main loop will handle this one - // this.onDone(input.text, input.success) return Promise.resolve('Task completed') }, }) @@ -52,19 +51,12 @@ tools.set( seconds: zod.number().min(1).max(10).default(1), }), execute: async function (this: PageAgentCore, input) { + // try to subtract LLM calling time from the actual wait time const lastTimeUpdate = await this.pageController.getLastUpdateTime() const actualWaitTime = Math.max(0, input.seconds - (Date.now() - lastTimeUpdate) / 1000) console.log(`actualWaitTime: ${actualWaitTime} seconds`) await waitFor(actualWaitTime) - this.states.totalWaitTime += input.seconds - - if (this.states.totalWaitTime >= 3) { - this.pushObservation( - `You have waited ${this.states.totalWaitTime} seconds accumulatively. Do NOT wait any longer unless you have a good reason.` - ) - } - return `✅ Waited for ${input.seconds} seconds.` }, })