@roll-agent/browser-use-agent 0.7.7 → 0.9.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.
@@ -76,12 +76,51 @@ export type NativeRecommendCardInspection = {
76
76
  readonly cardSelector: string;
77
77
  readonly candidateId: string;
78
78
  readonly name: string;
79
+ readonly age?: string;
80
+ readonly experience?: string;
81
+ readonly education?: string;
82
+ readonly workStatus?: string;
83
+ readonly company?: string;
84
+ readonly currentPosition?: string;
85
+ readonly expectedLocation?: string;
86
+ readonly expectedPosition?: string;
87
+ readonly expectedSalary?: string;
79
88
  readonly hasGreetButton: boolean;
80
89
  readonly error?: string;
81
90
  };
82
91
  export type NativeRecommendGreetResult = NativeRecommendCardInspection & {
83
92
  readonly clicked: boolean;
84
93
  };
94
+ export type NativeRecommendJobOption = {
95
+ readonly index: number;
96
+ readonly value: string;
97
+ readonly label: string;
98
+ readonly isCurrent: boolean;
99
+ };
100
+ export type NativeRecommendJobSelectorState = {
101
+ readonly found: boolean;
102
+ readonly isOpen: boolean;
103
+ readonly currentLabel: string;
104
+ readonly currentValue: string;
105
+ readonly options: readonly NativeRecommendJobOption[];
106
+ };
107
+ export type NativeRecommendJobSelectRequest = {
108
+ readonly jobValue?: string;
109
+ readonly jobName?: string;
110
+ readonly index?: number;
111
+ readonly searchKeyword?: string;
112
+ readonly useSearch?: boolean;
113
+ };
114
+ export type NativeRecommendJobSelectResult = {
115
+ readonly success: boolean;
116
+ readonly status: "selected" | "already_selected" | "not_found" | "recommend_not_ready" | "selector_not_found";
117
+ readonly requested: NativeRecommendJobSelectRequest;
118
+ readonly current?: NativeRecommendJobOption;
119
+ readonly selected?: NativeRecommendJobOption;
120
+ readonly options: readonly NativeRecommendJobOption[];
121
+ readonly matchedCount: number;
122
+ readonly error?: string;
123
+ };
85
124
  export type NativeWechatExchangeResult = {
86
125
  readonly success: boolean;
87
126
  readonly exchanged: boolean;
@@ -137,6 +176,14 @@ export declare class ZhipinNativePagePort {
137
176
  private dispatchNativeClick;
138
177
  hasRecommendList(): Promise<boolean>;
139
178
  waitForRecommendList(timeoutMs?: number): Promise<boolean>;
179
+ readRecommendJobSelectorState(): Promise<NativeRecommendJobSelectorState>;
180
+ private openRecommendJobSelector;
181
+ private setRecommendJobSearch;
182
+ private selectRecommendJobMatch;
183
+ private getCurrentRecommendJobOption;
184
+ private currentRecommendJobMatchesRequest;
185
+ private clickRecommendJobOption;
186
+ selectRecommendJob(request: NativeRecommendJobSelectRequest, options?: NativeClickOptions): Promise<NativeRecommendJobSelectResult>;
140
187
  clickSidebarSection(section: "chat" | "recommend", options?: NativeClickOptions): Promise<boolean>;
141
188
  scrollSurface(surface: ZhipinListSurface, options?: {
142
189
  readonly direction?: ScrollDirection;
@@ -0,0 +1,41 @@
1
+ import type { AgentLogger } from "@roll-agent/sdk";
2
+ export declare const RECRUITMENT_EVENT_TYPES: readonly ["message_received", "message_sent", "candidate_contacted", "wechat_exchanged"];
3
+ type RecruitmentEventType = (typeof RECRUITMENT_EVENT_TYPES)[number];
4
+ type RecruitmentCandidate = {
5
+ readonly name: string;
6
+ readonly position: string;
7
+ readonly age?: string;
8
+ readonly gender?: string;
9
+ readonly education?: string;
10
+ readonly expectedSalary?: string;
11
+ readonly expectedLocation?: string;
12
+ };
13
+ type RecruitmentJob = {
14
+ readonly jobId?: number;
15
+ readonly jobName?: string;
16
+ };
17
+ type RecruitmentEventDetails = Readonly<Record<string, string | number | boolean | undefined>>;
18
+ export type RecruitmentEventPayload = {
19
+ readonly idempotencyKey: string;
20
+ readonly agentId: string;
21
+ readonly sourcePlatform: "zhipin";
22
+ readonly dataSource: "api_callback";
23
+ readonly eventType: RecruitmentEventType;
24
+ readonly eventTime: string;
25
+ readonly candidate: RecruitmentCandidate;
26
+ readonly job?: RecruitmentJob;
27
+ readonly details: RecruitmentEventDetails;
28
+ };
29
+ export type RecruitmentEventDraft = Omit<RecruitmentEventPayload, "agentId" | "eventTime"> & {
30
+ readonly eventTime?: string;
31
+ };
32
+ type RecruitmentEventPostDeps = {
33
+ readonly fetch: typeof fetch;
34
+ readonly env: NodeJS.ProcessEnv;
35
+ };
36
+ type RecruitmentEventRecorder = (event: RecruitmentEventDraft, logger: AgentLogger) => Promise<void> | void;
37
+ export declare function buildRecruitmentIdempotencyKey(prefix: string, parts: ReadonlyArray<string | number | boolean | undefined>): string;
38
+ export declare function recordRecruitmentEventAsync(event: RecruitmentEventDraft, logger: AgentLogger): void;
39
+ export declare function setRecruitmentEventRecorderForTests(recorder: RecruitmentEventRecorder | undefined): void;
40
+ export declare function setRecruitmentEventPostDepsForTests(deps: Partial<RecruitmentEventPostDeps> | undefined): void;
41
+ export {};
@@ -0,0 +1,34 @@
1
+ import type { AgentLogger } from "@roll-agent/sdk";
2
+ import type { NativeCandidateChatDetails, NativeRecommendGreetResult } from "../pages/zhipin/native-page.ts";
3
+ type ZhipinUnreadCandidate = {
4
+ readonly conversationId: string;
5
+ readonly candidateId: string;
6
+ readonly name: string;
7
+ readonly position: string;
8
+ readonly preview: string;
9
+ readonly unreadCount: number;
10
+ readonly hasUnread: boolean;
11
+ };
12
+ type ZhipinMessageSentInput = {
13
+ readonly conversationId: string;
14
+ readonly candidateId: string;
15
+ readonly replyId: string;
16
+ readonly candidateName: string;
17
+ readonly message: string;
18
+ readonly unreadCountBeforeReply: number;
19
+ readonly candidateDetails?: NativeCandidateChatDetails;
20
+ };
21
+ type ZhipinWechatRequestedInput = {
22
+ readonly conversationId: string;
23
+ readonly candidateId: string;
24
+ readonly candidateName: string;
25
+ readonly exchangeType?: "requested" | "accepted";
26
+ readonly wechatNumber?: string;
27
+ readonly candidateDetails?: NativeCandidateChatDetails;
28
+ };
29
+ export declare function recordZhipinMessageReceivedEvents(candidates: ReadonlyArray<ZhipinUnreadCandidate>, logger: AgentLogger): void;
30
+ export declare function recordZhipinMessageSentEvent(input: ZhipinMessageSentInput, logger: AgentLogger): void;
31
+ export declare function recordZhipinCandidateContactedEvent(result: NativeRecommendGreetResult, logger: AgentLogger): void;
32
+ export declare function recordZhipinWechatRequestedEvent(input: ZhipinWechatRequestedInput, logger: AgentLogger): void;
33
+ export declare function recordZhipinWechatCompletedEvents(details: NativeCandidateChatDetails, conversationId: string, candidateId: string, logger: AgentLogger): void;
34
+ export {};
@@ -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 {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@roll-agent/browser-use-agent",
3
- "version": "0.7.7",
3
+ "version": "0.9.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"
@@ -2,7 +2,21 @@ required:
2
2
  - name: REPLY_AUTHORITY_KEYS_URL
3
3
  purpose: Reply Authority Service 公钥分发端点;`zhipin_send_reply` 启动预热和本地 Ed25519 验签都依赖它
4
4
  example: https://reply-authority.duliday.com/.well-known/reply-authority-keys
5
+ - name: RECRUITMENT_EVENTS_DEFAULT_AGENT_ID
6
+ purpose: 单 browser-use 实例 / 单 Boss 账号部署下的默认招聘业务 Agent ID;招聘事件默认启用,上报时必须用它做归因
7
+ example: zhipin-shanghai-kfc-001
8
+ - name: RECRUITMENT_EVENTS_API_TOKEN
9
+ purpose: 招聘事件 Open API Bearer token;公开 npm 包不内置兜底 token,必须由部署环境提供
10
+ example: token_xxx
5
11
  optional:
12
+ - name: RECRUITMENT_EVENTS_ENABLED
13
+ purpose: 是否启用招聘事件埋点上报;未设置时默认启用,设为 `"false"` 可关闭
14
+ default: "true"
15
+ example: "false"
16
+ - name: RECRUITMENT_EVENTS_API_BASE_URL
17
+ purpose: 招聘事件 Open API base URL;工具成功后会调用 `/api/v1/recruitment-events`
18
+ default: https://huajune.duliday.com
19
+ example: https://example.com
6
20
  - name: BROWSER_VISUAL_CURSOR
7
21
  purpose: 在可见浏览器页面内显示 browser-use 的页内虚拟指针和点击波纹;默认开启,设为 `"false"` 可关闭
8
22
  default: "true"
@@ -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`:连续滚动没有新去重项。