Skip to content

Commit 4def102

Browse files
committed
fix model
1 parent 70be553 commit 4def102

File tree

5 files changed

+30
-101
lines changed

5 files changed

+30
-101
lines changed

examples/retrieve.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ async function structured() {
6161
const rsp = await browseruse.tasks.create({
6262
task: 'Extract top 10 Hacker News posts and return the title, url, and score',
6363
schema: TaskOutput,
64-
agentSettings: { llm: 'gemini-2.5-flash' },
64+
agentSettings: { llm: 'gpt-4.1' },
6565
});
6666

6767
poll: do {

examples/run.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ async function structured() {
4141
const rsp = await browseruse.tasks.run({
4242
task: 'Search for the top 10 Hacker News posts and return the title, url, and score',
4343
schema: TaskOutput,
44-
agentSettings: { llm: 'gemini-2.5-flash' },
44+
agentSettings: { llm: 'gpt-4.1' },
4545
});
4646

4747
const posts = rsp.parsedOutput?.posts;

examples/stream.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ async function basic() {
2525
console.log(
2626
`Basic: ${msg.data.status} ${msg.data.session.liveUrl} ${msg.data.steps[msg.data.steps.length - 1]?.nextGoal}`,
2727
);
28+
29+
if (msg.data.status === 'finished') {
30+
console.log(`Basic: ${msg.data.doneOutput}`);
31+
}
2832
}
2933

3034
console.log('\nBasic: Stream completed');
@@ -50,7 +54,7 @@ async function structured() {
5054
const task = await browseruse.tasks.create({
5155
task: 'Extract top 10 Hacker News posts and return the title, url, and score',
5256
schema: TaskOutput,
53-
agentSettings: { llm: 'gemini-2.5-flash' },
57+
agentSettings: { llm: 'gpt-4.1' },
5458
});
5559

5660
const stream = browseruse.tasks.stream({

src/lib/stream.ts

Lines changed: 13 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1,86 +1,14 @@
1-
import type { TaskView, TaskStepView } from '../resources/tasks';
2-
import { type DeepMutable, ExhaustiveSwitchCheck } from './types';
3-
4-
export type ReducerEvent = TaskView | null;
5-
6-
export type BrowserState = Readonly<{
7-
taskId: string;
8-
sessionId: string;
9-
10-
liveUrl: string | null;
11-
steps: ReadonlyArray<TaskStepView>;
12-
doneOutput: string | null;
13-
}> | null;
14-
15-
type BrowserAction = {
16-
kind: 'status';
17-
status: TaskView;
18-
};
19-
20-
export function reducer(state: BrowserState, action: BrowserAction): [BrowserState, ReducerEvent] {
21-
switch (action.kind) {
22-
case 'status': {
23-
// INIT
24-
25-
if (state == null) {
26-
const liveUrl = action.status.session.liveUrl ?? null;
27-
const doneOutput = action.status.doneOutput ?? null;
28-
29-
const state: BrowserState = {
30-
taskId: action.status.id,
31-
sessionId: action.status.sessionId,
32-
liveUrl: liveUrl,
33-
steps: action.status.steps,
34-
doneOutput: doneOutput,
35-
};
36-
37-
return [state, action.status];
38-
}
39-
40-
// UPDATE
41-
42-
const liveUrl = action.status.session.liveUrl ?? state.liveUrl;
43-
const doneOutput = action.status.doneOutput ?? state.doneOutput;
44-
45-
const steps: TaskStepView[] = [...state.steps];
46-
if (action.status.steps != null) {
47-
const newSteps = action.status.steps.slice(state.steps.length);
48-
49-
for (const step of newSteps) {
50-
steps.push(step);
51-
}
52-
}
53-
54-
const newState: DeepMutable<BrowserState> = {
55-
...state,
56-
liveUrl,
57-
steps,
58-
doneOutput,
59-
};
60-
61-
// CHANGES
62-
63-
if (
64-
(state.liveUrl == null && liveUrl != null) ||
65-
state.steps.length !== steps.length ||
66-
state.doneOutput != doneOutput
67-
) {
68-
const update: ReducerEvent = {
69-
...action.status,
70-
steps: newState.steps,
71-
session: {
72-
...action.status.session,
73-
liveUrl: newState.liveUrl,
74-
},
75-
doneOutput: newState.doneOutput,
76-
};
77-
78-
return [newState, update];
79-
}
80-
81-
return [newState, null];
82-
}
83-
default:
84-
throw new ExhaustiveSwitchCheck(action.kind);
85-
}
1+
import { createHash } from 'crypto';
2+
import stringify from 'fast-json-stable-stringify';
3+
4+
import type { TaskView } from '../resources';
5+
6+
/**
7+
* Hashes the task view to detect changes.
8+
* Uses fast-json-stable-stringify for deterministic JSON, then SHA-256.
9+
*/
10+
export function getTaskViewHash(view: TaskView): string {
11+
const dump = stringify(view);
12+
const hash = createHash('sha256').update(dump).digest('hex');
13+
return hash;
8614
}

src/resources/tasks.ts

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212
type TaskCreateParamsWithSchema,
1313
type TaskViewWithSchema,
1414
} from '../lib/parse';
15-
import { BrowserState, reducer } from '../lib/stream';
15+
import { getTaskViewHash } from '../lib/stream';
1616

1717
export class Tasks extends APIResource {
1818
/**
@@ -131,29 +131,26 @@ export class Tasks extends APIResource {
131131
config: { interval: number },
132132
options?: RequestOptions,
133133
): AsyncGenerator<{ event: 'status'; data: TaskView }> {
134-
const tick: { current: number } = { current: 0 };
135-
const state: { current: BrowserState } = { current: null };
134+
const hash: { current: string | null } = { current: null };
136135

137136
poll: do {
138137
if (options?.signal?.aborted) {
139138
break poll;
140139
}
141140

142-
tick.current++;
141+
const res = await this.retrieve(taskId);
143142

144-
const status = await this.retrieve(taskId);
143+
const resHash = getTaskViewHash(res);
145144

146-
const [newState, event] = reducer(state.current, { kind: 'status', status });
145+
if (hash.current == null || resHash !== hash.current) {
146+
hash.current = resHash;
147147

148-
if (event != null) {
149-
yield { event: 'status', data: event };
150-
151-
if (event.status === 'finished') {
152-
break;
153-
}
148+
yield { event: 'status', data: res };
154149
}
155150

156-
state.current = newState;
151+
if (res.status === 'finished') {
152+
break poll;
153+
}
157154

158155
await new Promise((resolve) => setTimeout(resolve, config.interval));
159156
} while (true);

0 commit comments

Comments
 (0)