Skip to content
Open
Show file tree
Hide file tree
Changes from 33 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
861224d
agent steaming
tkattkat Nov 21, 2025
1fa6093
put behind experimental
tkattkat Nov 22, 2025
a0c8ddf
update typing
tkattkat Nov 22, 2025
8d4f29d
add streaming example
tkattkat Nov 22, 2025
e9c63f6
lint
tkattkat Nov 22, 2025
f0bfffe
update types
tkattkat Nov 22, 2025
b21cd59
change default max steps to 20
tkattkat Nov 22, 2025
c5c60f1
Merge remote-tracking branch 'origin/main' into agent-steaming
tkattkat Nov 25, 2025
57ec8c1
manually bump version
tkattkat Nov 25, 2025
e31d2df
Update packages/core/examples/agent_stream_example.ts
tkattkat Nov 25, 2025
ef9a78e
changeset
tkattkat Nov 25, 2025
5b5619c
change example to verbose 0
tkattkat Nov 25, 2025
e782674
add caching
tkattkat Nov 26, 2025
1b7d126
format
tkattkat Nov 26, 2025
51877dd
add wrapStreamForCaching
tkattkat Nov 26, 2025
ebd814f
consolidate shared logic
tkattkat Nov 26, 2025
0d06078
remove version change
tkattkat Nov 26, 2025
eeee0dd
agents streaming
tkattkat Nov 26, 2025
7f88860
update example
tkattkat Nov 26, 2025
ae01423
update changeset
tkattkat Nov 26, 2025
269d7fc
update example
tkattkat Nov 26, 2025
1e7af15
greptile suggestions
tkattkat Nov 26, 2025
4ad4efc
format
tkattkat Nov 26, 2025
05bdf3c
throw error when stream is used with cua
tkattkat Nov 26, 2025
3744a71
add test for streaming
tkattkat Nov 26, 2025
c14d736
update test
tkattkat Nov 26, 2025
c1e3bae
lint
tkattkat Nov 26, 2025
b832be9
add support for callbacks in agent
tkattkat Nov 26, 2025
41aa84b
format
tkattkat Nov 26, 2025
1b403df
add try catch
tkattkat Nov 26, 2025
ab26f6c
Merge remote-tracking branch 'origin/main' into agent-callbacks
tkattkat Nov 26, 2025
3166208
format
tkattkat Nov 26, 2025
eed6abd
add changeset
tkattkat Nov 26, 2025
e4cc3ec
put callbacks behind experimental
tkattkat Nov 27, 2025
bc1d2a6
update types
tkattkat Nov 27, 2025
f732adc
lint
tkattkat Dec 1, 2025
9dbcb93
Merge remote-tracking branch 'origin/main' into agent-callbacks
tkattkat Dec 1, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/shiny-wings-reply.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@browserbasehq/stagehand": patch
---

Add support for callbacks in stagehand agent
4 changes: 2 additions & 2 deletions packages/core/lib/v3/cache/AgentCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import type {
AgentResult,
AgentStreamResult,
AgentConfig,
AgentExecuteOptions,
AgentExecuteOptionsBase,
Logger,
} from "../types/public";
import type { Page } from "../understudy/page";
Expand Down Expand Up @@ -74,7 +74,7 @@ export class AgentCache {
}

sanitizeExecuteOptions(
options?: AgentExecuteOptions,
options?: AgentExecuteOptionsBase,
): SanitizedAgentExecuteOptions {
if (!options) return {};
const sanitized: SanitizedAgentExecuteOptions = {};
Expand Down
39 changes: 32 additions & 7 deletions packages/core/lib/v3/handlers/v3AgentHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,14 @@
import { LLMClient } from "../llm/LLMClient";
import {
AgentExecuteOptions,
AgentStreamExecuteOptions,
AgentExecuteOptionsBase,
AgentResult,
AgentContext,
AgentState,
AgentStreamResult,
AgentExecuteCallbacks,

Check failure on line 22 in packages/core/lib/v3/handlers/v3AgentHandler.ts

View workflow job for this annotation

GitHub Actions / run-lint

'AgentExecuteCallbacks' is defined but never used
AgentStreamCallbacks,
} from "../types/public/agent";
import { V3FunctionName } from "../types/public/methods";
import { mapToolResultToActions } from "../agent/utils/actionMapping";
Expand Down Expand Up @@ -47,7 +51,7 @@
}

private async prepareAgent(
instructionOrOptions: string | AgentExecuteOptions,
instructionOrOptions: string | AgentExecuteOptionsBase,
): Promise<AgentContext> {
try {
const options =
Expand Down Expand Up @@ -102,7 +106,10 @@
}
}

private createStepHandler(state: AgentState) {
private createStepHandler(
state: AgentState,
userCallback?: (event: StepResult<ToolSet>) => PromiseLike<void> | void,
) {
return async (event: StepResult<ToolSet>) => {
this.logger({
category: "agent",
Expand Down Expand Up @@ -150,6 +157,10 @@
}
state.currentPageUrl = (await this.v3.context.awaitActivePage()).url();
}

if (userCallback) {
await userCallback(event);
}
};
}

Expand All @@ -158,6 +169,7 @@
): Promise<AgentResult> {
const startTime = Date.now();
const {
options,

Check failure on line 172 in packages/core/lib/v3/handlers/v3AgentHandler.ts

View workflow job for this annotation

GitHub Actions / run-lint

'options' is assigned a value but never used
maxSteps,
systemPrompt,
allTools,
Expand All @@ -166,6 +178,7 @@
initialPageUrl,
} = await this.prepareAgent(instructionOrOptions);

const callbacks = (instructionOrOptions as AgentExecuteOptions).callbacks;
const state: AgentState = {
collectedReasoning: [],
actions: [],
Expand All @@ -183,7 +196,8 @@
stopWhen: (result) => this.handleStop(result, maxSteps),
temperature: 1,
toolChoice: "auto",
onStepFinish: this.createStepHandler(state),
prepareStep: callbacks?.prepareStep,
onStepFinish: this.createStepHandler(state, callbacks?.onStepFinish),
});

return this.consolidateMetricsAndResult(startTime, state, result);
Expand All @@ -204,7 +218,7 @@
}

public async stream(
instructionOrOptions: string | AgentExecuteOptions,
instructionOrOptions: string | AgentStreamExecuteOptions,
): Promise<AgentStreamResult> {
const {
maxSteps,
Expand All @@ -215,6 +229,9 @@
initialPageUrl,
} = await this.prepareAgent(instructionOrOptions);

const callbacks = (instructionOrOptions as AgentStreamExecuteOptions)
.callbacks as AgentStreamCallbacks | undefined;

const state: AgentState = {
collectedReasoning: [],
actions: [],
Expand Down Expand Up @@ -250,11 +267,19 @@
stopWhen: (result) => this.handleStop(result, maxSteps),
temperature: 1,
toolChoice: "auto",
onStepFinish: this.createStepHandler(state),
onError: ({ error }) => {
handleError(error);
prepareStep: callbacks?.prepareStep,
onStepFinish: this.createStepHandler(state, callbacks?.onStepFinish),
onError: (event) => {
if (callbacks?.onError) {
callbacks.onError(event);
}
handleError(event.error);
},
onChunk: callbacks?.onChunk,
onFinish: (event) => {
if (callbacks?.onFinish) {
callbacks.onFinish(event);
}
try {
const result = this.consolidateMetricsAndResult(
startTime,
Expand Down
Loading
Loading