@roll-agent/browser-use-agent 0.7.6 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,55 @@
1
+ import type { NativeCdpController, NativeCdpMouseEventInput } from "@roll-agent/browser";
2
+ export type NativeMousePoint = {
3
+ readonly x: number;
4
+ readonly y: number;
5
+ };
6
+ export type NativeMouseMotionPreview = {
7
+ readonly points: readonly NativeMousePoint[];
8
+ readonly durationMs: number;
9
+ };
10
+ export type NativeMouseClickPreview = {
11
+ readonly point: NativeMousePoint;
12
+ readonly durationMs: number;
13
+ };
14
+ export type NativeMouseMotionObserver = {
15
+ previewMouseMotion(preview: NativeMouseMotionPreview): Promise<void>;
16
+ previewMouseClick?(preview: NativeMouseClickPreview): Promise<void>;
17
+ };
18
+ export type NativeMouseMotionControllerOptions = {
19
+ readonly sleep?: (ms: number) => Promise<void>;
20
+ readonly stepDelayMs?: number;
21
+ };
22
+ export type NativeMouseMoveOptions = {
23
+ readonly button?: NativeCdpMouseEventInput["button"];
24
+ readonly buttons?: number;
25
+ readonly motionObserver?: NativeMouseMotionObserver;
26
+ readonly stepDelayMs?: number;
27
+ };
28
+ export type NativeMouseClickOptions = {
29
+ readonly button?: NativeCdpMouseEventInput["button"];
30
+ readonly clickCount?: number;
31
+ readonly motionObserver?: NativeMouseMotionObserver;
32
+ readonly preClickDelayMs?: number;
33
+ readonly pressDurationMs?: number;
34
+ readonly settleMs?: number;
35
+ };
36
+ export type NativeMouseDragOptions = {
37
+ readonly motionObserver?: NativeMouseMotionObserver;
38
+ readonly pressDurationMs?: number;
39
+ readonly stepDelayMs?: number;
40
+ };
41
+ type NativeMouseDispatcher = Pick<NativeCdpController, "dispatchMouseEvent">;
42
+ export declare function createNativeMousePath(currentPoint: NativeMousePoint | undefined, targetPoint: NativeMousePoint): readonly NativeMousePoint[];
43
+ export declare class NativeMouseMotionController {
44
+ private readonly dispatcher;
45
+ private readonly sleep;
46
+ private readonly defaultStepDelayMs;
47
+ private lastPoint;
48
+ constructor(dispatcher: NativeMouseDispatcher, options?: NativeMouseMotionControllerOptions);
49
+ reset(point?: NativeMousePoint): void;
50
+ moveTo(targetPoint: NativeMousePoint, options?: NativeMouseMoveOptions): Promise<NativeMouseMotionPreview>;
51
+ click(targetPoint: NativeMousePoint, options?: NativeMouseClickOptions): Promise<void>;
52
+ drag(fromPoint: NativeMousePoint, toPoint: NativeMousePoint, options?: NativeMouseDragOptions): Promise<void>;
53
+ private delayIfPositive;
54
+ }
55
+ export {};
@@ -1,4 +1,5 @@
1
1
  import type { VisualActivityTone } from "./visual-activity.ts";
2
+ import type { NativeMouseClickPreview, NativeMouseMotionObserver, NativeMouseMotionPreview } from "./native-mouse-motion.ts";
2
3
  type NativeVisualTarget = {
3
4
  evaluateJson<T = unknown>(expression: string): Promise<T>;
4
5
  };
@@ -7,15 +8,13 @@ type NativeVisualHighlightOptions = {
7
8
  readonly padding?: number;
8
9
  readonly tone?: VisualActivityTone;
9
10
  };
10
- type NativeVisualPointOptions = {
11
- readonly durationMs?: number;
12
- };
13
- export declare class NativeVisualActivitySession {
11
+ export declare class NativeVisualActivitySession implements NativeMouseMotionObserver {
14
12
  private readonly target;
15
13
  constructor(target: NativeVisualTarget);
16
14
  begin(label: string, tone?: VisualActivityTone): Promise<boolean>;
17
15
  highlightSelector(selector: string, options?: NativeVisualHighlightOptions): Promise<boolean>;
18
- highlightPoint(x: number, y: number, options?: NativeVisualPointOptions): Promise<boolean>;
16
+ previewMouseMotion(preview: NativeMouseMotionPreview): Promise<void>;
17
+ previewMouseClick(preview: NativeMouseClickPreview): Promise<void>;
19
18
  succeed(label: string, lingerMs?: number): Promise<boolean>;
20
19
  fail(label: string, lingerMs?: number): Promise<boolean>;
21
20
  clear(): Promise<boolean>;
@@ -1,4 +1,5 @@
1
1
  import type { BrowserContextManager, BrowserInspectablePage, BrowserRuntime, NativeCdpController } from "@roll-agent/browser";
2
+ import { type NativeMouseMotionObserver } from "../../native-mouse-motion.ts";
2
3
  import type { DynamicListCollectionStopReason, DynamicListScrollResult, ScrollDirection } from "../shared/dynamic-list-scroller.ts";
3
4
  import { type ChatListItem, type ChatTarget, type OpenChatResult } from "./chat-navigation.ts";
4
5
  import { type ZhipinListSurface } from "./list-surfaces.ts";
@@ -37,6 +38,7 @@ export type ReadNativeRecommendCandidatesOptions = {
37
38
  export type OpenNativeChatOptions = ChatTarget & {
38
39
  readonly preferUnread?: boolean;
39
40
  readonly maxScrolls?: number;
41
+ readonly motionObserver?: NativeMouseMotionObserver;
40
42
  };
41
43
  export type NativeChatMessage = {
42
44
  readonly index: number;
@@ -80,6 +82,36 @@ export type NativeRecommendCardInspection = {
80
82
  export type NativeRecommendGreetResult = NativeRecommendCardInspection & {
81
83
  readonly clicked: boolean;
82
84
  };
85
+ export type NativeRecommendJobOption = {
86
+ readonly index: number;
87
+ readonly value: string;
88
+ readonly label: string;
89
+ readonly isCurrent: boolean;
90
+ };
91
+ export type NativeRecommendJobSelectorState = {
92
+ readonly found: boolean;
93
+ readonly isOpen: boolean;
94
+ readonly currentLabel: string;
95
+ readonly currentValue: string;
96
+ readonly options: readonly NativeRecommendJobOption[];
97
+ };
98
+ export type NativeRecommendJobSelectRequest = {
99
+ readonly jobValue?: string;
100
+ readonly jobName?: string;
101
+ readonly index?: number;
102
+ readonly searchKeyword?: string;
103
+ readonly useSearch?: boolean;
104
+ };
105
+ export type NativeRecommendJobSelectResult = {
106
+ readonly success: boolean;
107
+ readonly status: "selected" | "already_selected" | "not_found" | "recommend_not_ready" | "selector_not_found";
108
+ readonly requested: NativeRecommendJobSelectRequest;
109
+ readonly current?: NativeRecommendJobOption;
110
+ readonly selected?: NativeRecommendJobOption;
111
+ readonly options: readonly NativeRecommendJobOption[];
112
+ readonly matchedCount: number;
113
+ readonly error?: string;
114
+ };
83
115
  export type NativeWechatExchangeResult = {
84
116
  readonly success: boolean;
85
117
  readonly exchanged: boolean;
@@ -97,13 +129,8 @@ export type NativeDynamicListCollectionResult<TItem> = DynamicListScrollResult &
97
129
  readonly noNewRounds: number;
98
130
  readonly stopReason: DynamicListCollectionStopReason;
99
131
  };
100
- type NativeClickTarget = {
101
- readonly found: boolean;
102
- readonly x: number;
103
- readonly y: number;
104
- };
105
132
  type NativeClickOptions = {
106
- readonly onTargetResolved?: (target: NativeClickTarget) => Promise<void>;
133
+ readonly motionObserver?: NativeMouseMotionObserver;
107
134
  readonly preClickDelayMs?: number;
108
135
  readonly pressDurationMs?: number;
109
136
  readonly settleMs?: number;
@@ -118,6 +145,7 @@ export declare function openZhipinNativePagePort(options?: NativePageResolutionO
118
145
  export declare class ZhipinNativePagePort {
119
146
  private readonly target;
120
147
  private readonly controller;
148
+ private readonly mouse;
121
149
  private recommendFrameContextId;
122
150
  private recommendFrameContextFrameId;
123
151
  constructor(options: ZhipinNativePagePortOptions);
@@ -139,6 +167,14 @@ export declare class ZhipinNativePagePort {
139
167
  private dispatchNativeClick;
140
168
  hasRecommendList(): Promise<boolean>;
141
169
  waitForRecommendList(timeoutMs?: number): Promise<boolean>;
170
+ readRecommendJobSelectorState(): Promise<NativeRecommendJobSelectorState>;
171
+ private openRecommendJobSelector;
172
+ private setRecommendJobSearch;
173
+ private selectRecommendJobMatch;
174
+ private getCurrentRecommendJobOption;
175
+ private currentRecommendJobMatchesRequest;
176
+ private clickRecommendJobOption;
177
+ selectRecommendJob(request: NativeRecommendJobSelectRequest, options?: NativeClickOptions): Promise<NativeRecommendJobSelectResult>;
142
178
  clickSidebarSection(section: "chat" | "recommend", options?: NativeClickOptions): Promise<boolean>;
143
179
  scrollSurface(surface: ZhipinListSurface, options?: {
144
180
  readonly direction?: ScrollDirection;
@@ -1,7 +1,7 @@
1
1
  import { NativeVisualActivitySession } from "../native-visual-activity-session.ts";
2
2
  import { openZhipinNativePagePort } from "../pages/zhipin/native-page.ts";
3
3
  import type { ZhipinNativePagePort } from "../pages/zhipin/native-page.ts";
4
- type NativeVisualActivitySessionLike = Pick<NativeVisualActivitySession, "begin" | "highlightPoint" | "succeed" | "fail">;
4
+ type NativeVisualActivitySessionLike = Pick<NativeVisualActivitySession, "begin" | "previewMouseMotion" | "succeed" | "fail">;
5
5
  type ZhipinExchangeWechatDeps = {
6
6
  readonly openNativePagePort: typeof openZhipinNativePagePort;
7
7
  readonly createNativeVisualActivitySession: (page: ZhipinNativePagePort) => NativeVisualActivitySessionLike;
@@ -1,7 +1,7 @@
1
1
  import { NativeVisualActivitySession } from "../native-visual-activity-session.ts";
2
2
  import { openZhipinNativePagePort } from "../pages/zhipin/native-page.ts";
3
3
  import type { ZhipinNativePagePort } from "../pages/zhipin/native-page.ts";
4
- type NativeVisualActivitySessionLike = Pick<NativeVisualActivitySession, "begin" | "highlightSelector" | "highlightPoint" | "succeed" | "fail">;
4
+ type NativeVisualActivitySessionLike = Pick<NativeVisualActivitySession, "begin" | "highlightSelector" | "previewMouseMotion" | "succeed" | "fail">;
5
5
  type ZhipinFilterRecommendCandidatesDeps = {
6
6
  readonly openNativePagePort: typeof openZhipinNativePagePort;
7
7
  readonly createNativeVisualActivitySession: (page: ZhipinNativePagePort) => NativeVisualActivitySessionLike;
@@ -2,9 +2,7 @@ import { NativeVisualActivitySession } from "../native-visual-activity-session.t
2
2
  import { openZhipinNativePagePort } from "../pages/zhipin/native-page.ts";
3
3
  import type { ZhipinNativePagePort } from "../pages/zhipin/native-page.ts";
4
4
  import { getContextManager } from "../runtime-holder.ts";
5
- type NativeVisualActivitySessionLike = Pick<NativeVisualActivitySession, "begin" | "highlightSelector" | "succeed" | "fail"> & {
6
- readonly highlightPoint?: NativeVisualActivitySession["highlightPoint"];
7
- };
5
+ type NativeVisualActivitySessionLike = Pick<NativeVisualActivitySession, "begin" | "highlightSelector" | "previewMouseMotion" | "succeed" | "fail">;
8
6
  type ZhipinOpenChatPageDeps = {
9
7
  readonly getContextManager: typeof getContextManager;
10
8
  readonly openNativePagePort: typeof openZhipinNativePagePort;
@@ -1,7 +1,7 @@
1
1
  import { NativeVisualActivitySession } from "../native-visual-activity-session.ts";
2
2
  import { openZhipinNativePagePort } from "../pages/zhipin/native-page.ts";
3
3
  import type { ZhipinNativePagePort } from "../pages/zhipin/native-page.ts";
4
- type NativeVisualActivitySessionLike = Pick<NativeVisualActivitySession, "begin" | "highlightSelector" | "succeed" | "fail">;
4
+ type NativeVisualActivitySessionLike = Pick<NativeVisualActivitySession, "begin" | "highlightSelector" | "previewMouseMotion" | "succeed" | "fail">;
5
5
  type ZhipinOpenChatDeps = {
6
6
  readonly openNativePagePort: typeof openZhipinNativePagePort;
7
7
  readonly createNativeVisualActivitySession: (page: ZhipinNativePagePort) => NativeVisualActivitySessionLike;
@@ -2,9 +2,7 @@ import { NativeVisualActivitySession } from "../native-visual-activity-session.t
2
2
  import { openZhipinNativePagePort } from "../pages/zhipin/native-page.ts";
3
3
  import type { ZhipinNativePagePort } from "../pages/zhipin/native-page.ts";
4
4
  import { getContextManager } from "../runtime-holder.ts";
5
- type NativeVisualActivitySessionLike = Pick<NativeVisualActivitySession, "begin" | "highlightSelector" | "succeed" | "fail"> & {
6
- readonly highlightPoint?: NativeVisualActivitySession["highlightPoint"];
7
- };
5
+ type NativeVisualActivitySessionLike = Pick<NativeVisualActivitySession, "begin" | "highlightSelector" | "previewMouseMotion" | "succeed" | "fail">;
8
6
  type ZhipinOpenRecommendPageDeps = {
9
7
  readonly getContextManager: typeof getContextManager;
10
8
  readonly openNativePagePort: typeof openZhipinNativePagePort;
@@ -1,7 +1,7 @@
1
1
  import { NativeVisualActivitySession } from "../native-visual-activity-session.ts";
2
2
  import { openZhipinNativePagePort } from "../pages/zhipin/native-page.ts";
3
3
  import type { ZhipinNativePagePort } from "../pages/zhipin/native-page.ts";
4
- type NativeVisualActivitySessionLike = Pick<NativeVisualActivitySession, "begin" | "highlightSelector" | "highlightPoint" | "succeed" | "fail">;
4
+ type NativeVisualActivitySessionLike = Pick<NativeVisualActivitySession, "begin" | "highlightSelector" | "previewMouseMotion" | "succeed" | "fail">;
5
5
  type ZhipinSayHelloDeps = {
6
6
  readonly openNativePagePort: typeof openZhipinNativePagePort;
7
7
  readonly createNativeVisualActivitySession: (page: ZhipinNativePagePort) => NativeVisualActivitySessionLike;
@@ -35,11 +35,16 @@ export declare const zhipinScrollView: import("@roll-agent/sdk").ToolDefinition<
35
35
  atEnd: boolean;
36
36
  itemCount: number;
37
37
  };
38
+ position: "unknown" | "middle" | "top" | "bottom" | "only-page";
38
39
  direction: "up" | "down";
39
40
  stepsRequested: number;
40
41
  stepsCompleted: number;
41
42
  reachedBoundary: boolean;
42
43
  surface: "chat-list" | "chat-history" | "recommend-list";
44
+ atTop: boolean;
45
+ atBottom: boolean;
46
+ canScrollUp: boolean;
47
+ canScrollDown: boolean;
43
48
  error?: string | undefined;
44
49
  }>;
45
50
  export {};
@@ -0,0 +1,47 @@
1
+ import { NativeVisualActivitySession } from "../native-visual-activity-session.ts";
2
+ import { openZhipinNativePagePort } from "../pages/zhipin/native-page.ts";
3
+ import type { ZhipinNativePagePort } from "../pages/zhipin/native-page.ts";
4
+ type NativeVisualActivitySessionLike = Pick<NativeVisualActivitySession, "begin" | "highlightSelector" | "previewMouseMotion" | "succeed" | "fail">;
5
+ type ZhipinSelectRecommendJobDeps = {
6
+ readonly openNativePagePort: typeof openZhipinNativePagePort;
7
+ readonly createNativeVisualActivitySession: (page: ZhipinNativePagePort) => NativeVisualActivitySessionLike;
8
+ };
9
+ export declare function setZhipinSelectRecommendJobDepsForTests(override: Partial<ZhipinSelectRecommendJobDeps> | undefined): void;
10
+ export declare const zhipinSelectRecommendJob: import("@roll-agent/sdk").ToolDefinition<{
11
+ index?: number | undefined;
12
+ jobValue?: string | undefined;
13
+ jobName?: string | undefined;
14
+ searchKeyword?: string | undefined;
15
+ useSearch?: boolean | undefined;
16
+ }, {
17
+ options: {
18
+ value: string;
19
+ index: number;
20
+ label: string;
21
+ isCurrent: boolean;
22
+ }[];
23
+ status: "not_found" | "recommend_not_ready" | "selected" | "already_selected" | "selector_not_found";
24
+ success: boolean;
25
+ requested: {
26
+ index?: number | undefined;
27
+ jobValue?: string | undefined;
28
+ jobName?: string | undefined;
29
+ searchKeyword?: string | undefined;
30
+ useSearch?: boolean | undefined;
31
+ };
32
+ matchedCount: number;
33
+ error?: string | undefined;
34
+ current?: {
35
+ value: string;
36
+ index: number;
37
+ label: string;
38
+ isCurrent: boolean;
39
+ } | undefined;
40
+ selected?: {
41
+ value: string;
42
+ index: number;
43
+ label: string;
44
+ isCurrent: boolean;
45
+ } | undefined;
46
+ }>;
47
+ export {};
@@ -2,7 +2,7 @@ import { NativeVisualActivitySession } from "../native-visual-activity-session.t
2
2
  import { openZhipinNativePagePort } from "../pages/zhipin/native-page.ts";
3
3
  import type { ZhipinNativePagePort } from "../pages/zhipin/native-page.ts";
4
4
  import { getReplyAuthorityKeysLoaded } from "../runtime-holder.ts";
5
- type NativeVisualActivitySessionLike = Pick<NativeVisualActivitySession, "begin" | "highlightPoint" | "succeed" | "fail">;
5
+ type NativeVisualActivitySessionLike = Pick<NativeVisualActivitySession, "begin" | "previewMouseMotion" | "succeed" | "fail">;
6
6
  type ZhipinSendReplyDeps = {
7
7
  readonly getReplyAuthorityKeysLoaded: typeof getReplyAuthorityKeysLoaded;
8
8
  readonly openNativePagePort: typeof openZhipinNativePagePort;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@roll-agent/browser-use-agent",
3
- "version": "0.7.6",
3
+ "version": "0.8.0",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",
@@ -45,8 +45,8 @@
45
45
  },
46
46
  "dependencies": {
47
47
  "zod": "^3.25.76",
48
- "@roll-agent/sdk": "0.1.6",
49
- "@roll-agent/browser": "0.3.0"
48
+ "@roll-agent/browser": "0.3.0",
49
+ "@roll-agent/sdk": "0.1.6"
50
50
  },
51
51
  "devDependencies": {
52
52
  "@types/node": "^22.0.0"
@@ -19,6 +19,25 @@
19
19
  4. `smart-reply-agent.generate_reply(..., target)`。
20
20
  5. `zhipin_send_reply(signedEnvelope)`。
21
21
 
22
+ ## 推荐岗位筛选
23
+
24
+ 推荐牛人页顶部岗位下拉的稳定主键是 `.job-list .job-item[value]`。
25
+
26
+ 优先级:
27
+
28
+ 1. 已知岗位 `value` 时,调用 `zhipin_select_recommend_job({ jobValue })`。
29
+ 2. 只知道标题时,调用 `zhipin_select_recommend_job({ jobName })`;工具会先匹配当前下拉项,未命中再使用下拉搜索框。
30
+ 3. `index` 只表示当前下拉快照顺序,筛选、搜索或岗位列表刷新后必须重新读取/选择,不要跨步骤长期保存。
31
+
32
+ 推荐链路:
33
+
34
+ ```text
35
+ zhipin_open_recommend_page()
36
+ -> zhipin_select_recommend_job({ jobValue | jobName })
37
+ -> zhipin_filter_recommend_candidates(...)
38
+ -> zhipin_get_candidate_list(...)
39
+ ```
40
+
22
41
  ## 动态列表
23
42
 
24
43
  BOSS 页面通常不是整页滚动,而是内部容器滚动:
@@ -33,9 +52,10 @@ recommend-list -> 推荐牛人列表,默认向下滚动,去重主键 candid
33
52
 
34
53
  1. 业务读取优先用自带 `autoScroll` 的工具:`zhipin_read_messages`、`zhipin_get_candidate_list`。
35
54
  2. `zhipin_scroll_view` 只用于显式翻页、调试和补救。
36
- 3. `onlyUnread=true` 时不要依赖 `limit` 提前停止;未读会话可能在首屏之后。
37
- 4. `maxScrolls` 用于成本控制,需要更完整列表时显式调大。
38
- 5. 推荐列表若 `total < maxResults`,先看 `scrollStats.stopReason`:
55
+ 3. 只想检查聊天列表是否到顶/到底时调用 `zhipin_scroll_view({ surface: "chat-list", steps: 0 })`,读取顶层 `atTop` / `atBottom` / `canScrollUp` / `canScrollDown` / `position`。
56
+ 4. `onlyUnread=true` 时不要依赖 `limit` 提前停止;未读会话可能在首屏之后。
57
+ 5. `maxScrolls` 用于成本控制,需要更完整列表时显式调大。
58
+ 6. 推荐列表若 `total < maxResults`,先看 `scrollStats.stopReason`:
39
59
  - `target-count`:已达到目标数量。
40
60
  - `boundary`:触底并等待追加数据后仍无新增。
41
61
  - `no-new-items`:连续滚动没有新去重项。