Skip to content

Commit fbca400

Browse files
fix stagehand.history (#753)
1 parent 5680d25 commit fbca400

File tree

3 files changed

+44
-43
lines changed

3 files changed

+44
-43
lines changed

.changeset/metal-clowns-cheat.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@browserbasehq/stagehand-lib": patch
3+
---
4+
5+
fix `stagehand.history`

lib/StagehandPage.ts

Lines changed: 12 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import { Page, defaultExtractSchema } from "../types/page";
66
import {
77
ExtractOptions,
88
ExtractResult,
9-
HistoryEntry,
109
ObserveOptions,
1110
ObserveResult,
1211
} from "../types/stagehand";
@@ -46,11 +45,6 @@ export class StagehandPage {
4645
private userProvidedInstructions?: string;
4746
private waitForCaptchaSolves: boolean;
4847
private initialized: boolean = false;
49-
private _history: Array<HistoryEntry> = [];
50-
51-
public get history(): ReadonlyArray<HistoryEntry> {
52-
return Object.freeze([...this._history]);
53-
}
5448

5549
constructor(
5650
page: PlaywrightPage,
@@ -338,13 +332,15 @@ ${scriptContent} \
338332

339333
// Handle goto specially
340334
if (prop === "goto") {
335+
const rawGoto: typeof target.goto =
336+
Object.getPrototypeOf(target).goto.bind(target);
341337
return async (url: string, options: GotoOptions) => {
342338
this.intContext.setActivePage(this);
343339
const result = this.api
344340
? await this.api.goto(url, options)
345-
: await target.goto(url, options);
341+
: await rawGoto(url, options);
346342

347-
this.addToHistory("navigate", { url, options }, result);
343+
this.stagehand.addToHistory("navigate", { url, options }, result);
348344

349345
if (this.waitForCaptchaSolves) {
350346
try {
@@ -498,24 +494,6 @@ ${scriptContent} \
498494
}
499495
}
500496

501-
public addToHistory(
502-
method: HistoryEntry["method"],
503-
parameters:
504-
| ActOptions
505-
| ExtractOptions<z.AnyZodObject>
506-
| ObserveOptions
507-
| { url: string; options: GotoOptions }
508-
| string,
509-
result?: unknown,
510-
): void {
511-
this._history.push({
512-
method,
513-
parameters,
514-
result: result ?? null,
515-
timestamp: new Date().toISOString(),
516-
});
517-
}
518-
519497
async act(
520498
actionOrOptions: string | ActOptions | ObserveResult,
521499
): Promise<ActResult> {
@@ -536,7 +514,7 @@ ${scriptContent} \
536514
if (this.api) {
537515
const result = await this.api.act(observeResult);
538516
await this._refreshPageFromAPI();
539-
this.addToHistory("act", observeResult, result);
517+
this.stagehand.addToHistory("act", observeResult, result);
540518
return result;
541519
}
542520

@@ -568,7 +546,7 @@ ${scriptContent} \
568546
if (this.api) {
569547
const result = await this.api.act(actionOrOptions);
570548
await this._refreshPageFromAPI();
571-
this.addToHistory("act", actionOrOptions, result);
549+
this.stagehand.addToHistory("act", actionOrOptions, result);
572550
return result;
573551
}
574552

@@ -603,8 +581,7 @@ ${scriptContent} \
603581
llmClient,
604582
requestId,
605583
);
606-
607-
this.addToHistory("act", actionOrOptions, result);
584+
this.stagehand.addToHistory("act", actionOrOptions, result);
608585
return result;
609586
} catch (err: unknown) {
610587
if (err instanceof StagehandError || err instanceof StagehandAPIError) {
@@ -632,7 +609,7 @@ ${scriptContent} \
632609
} else {
633610
result = await this.extractHandler.extract();
634611
}
635-
this.addToHistory("extract", instructionOrOptions, result);
612+
this.stagehand.addToHistory("extract", instructionOrOptions, result);
636613
return result;
637614
}
638615

@@ -656,7 +633,7 @@ ${scriptContent} \
656633

657634
if (this.api) {
658635
const result = await this.api.extract<T>(options);
659-
this.addToHistory("extract", instructionOrOptions, result);
636+
this.stagehand.addToHistory("extract", instructionOrOptions, result);
660637
return result;
661638
}
662639

@@ -719,7 +696,7 @@ ${scriptContent} \
719696
throw e;
720697
});
721698

722-
this.addToHistory("extract", instructionOrOptions, result);
699+
this.stagehand.addToHistory("extract", instructionOrOptions, result);
723700

724701
return result;
725702
} catch (err: unknown) {
@@ -757,7 +734,7 @@ ${scriptContent} \
757734

758735
if (this.api) {
759736
const result = await this.api.observe(options);
760-
this.addToHistory("observe", instructionOrOptions, result);
737+
this.stagehand.addToHistory("observe", instructionOrOptions, result);
761738
return result;
762739
}
763740

@@ -834,7 +811,7 @@ ${scriptContent} \
834811
throw e;
835812
});
836813

837-
this.addToHistory("observe", instructionOrOptions, result);
814+
this.stagehand.addToHistory("observe", instructionOrOptions, result);
838815

839816
return result;
840817
} catch (err: unknown) {

lib/index.ts

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ import {
1717
StagehandMetrics,
1818
StagehandFunctionName,
1919
HistoryEntry,
20+
ActOptions,
21+
ExtractOptions,
22+
ObserveOptions,
2023
} from "../types/stagehand";
2124
import { StagehandContext } from "./StagehandContext";
2225
import { StagehandPage } from "./StagehandPage";
@@ -41,6 +44,8 @@ import {
4144
UnsupportedAISDKModelProviderError,
4245
InvalidAISDKModelFormatError,
4346
} from "../types/stagehandErrors";
47+
import { z } from "zod";
48+
import { GotoOptions } from "@/types/playwright";
4449

4550
dotenv.config({ path: ".env" });
4651

@@ -396,6 +401,10 @@ export class Stagehand {
396401
private _env: "LOCAL" | "BROWSERBASE";
397402
private _browser: Browser | undefined;
398403
private _isClosed: boolean = false;
404+
private _history: Array<HistoryEntry> = [];
405+
public get history(): ReadonlyArray<HistoryEntry> {
406+
return Object.freeze([...this._history]);
407+
}
399408
protected setActivePage(page: StagehandPage): void {
400409
this.stagehandPage = page;
401410
}
@@ -810,6 +819,24 @@ export class Stagehand {
810819
}
811820
}
812821

822+
public addToHistory(
823+
method: HistoryEntry["method"],
824+
parameters:
825+
| ActOptions
826+
| ExtractOptions<z.AnyZodObject>
827+
| ObserveOptions
828+
| { url: string; options: GotoOptions }
829+
| string,
830+
result?: unknown,
831+
): void {
832+
this._history.push({
833+
method,
834+
parameters,
835+
result: result ?? null,
836+
timestamp: new Date().toISOString(),
837+
});
838+
}
839+
813840
/**
814841
* Create an agent instance that can be executed with different instructions
815842
* @returns An agent instance with execute() method
@@ -897,14 +924,6 @@ export class Stagehand {
897924
},
898925
};
899926
}
900-
901-
public get history(): ReadonlyArray<HistoryEntry> {
902-
if (!this.stagehandPage) {
903-
throw new StagehandNotInitializedError("history()");
904-
}
905-
906-
return this.stagehandPage.history;
907-
}
908927
}
909928

910929
export * from "../types/browser";

0 commit comments

Comments
 (0)