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

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.
@@ -1,28 +1,37 @@
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" | "succeed" | "fail">;
5
+ type ZhipinGetCandidateInfoDeps = {
6
+ readonly openNativePagePort: typeof openZhipinNativePagePort;
7
+ readonly createNativeVisualActivitySession: (page: ZhipinNativePagePort) => NativeVisualActivitySessionLike;
8
+ };
9
+ export declare function setZhipinGetCandidateInfoDepsForTests(override: Partial<ZhipinGetCandidateInfoDeps> | undefined): void;
1
10
  export declare const zhipinGetCandidateInfo: import("@roll-agent/sdk").ToolDefinition<{
11
+ index?: number | undefined;
2
12
  conversationId?: string | undefined;
3
13
  candidateName?: string | undefined;
4
- index?: number | undefined;
5
14
  maxMessages?: number | undefined;
6
15
  }, {
7
16
  success: boolean;
8
17
  conversationId: string;
9
18
  candidateId: string;
10
- stats: {
11
- totalMessages: number;
12
- candidateMessages: number;
13
- recruiterMessages: number;
14
- systemMessages: number;
15
- };
16
19
  candidateInfo: {
17
20
  name: string;
18
- expectedLocation: string;
19
- expectedPosition: string;
20
21
  age: string;
21
22
  experience: string;
22
23
  education: string;
23
- communicationPosition: string;
24
+ expectedLocation: string;
25
+ expectedPosition: string;
24
26
  expectedSalary: string;
25
27
  tags: string[];
28
+ communicationPosition: string;
29
+ };
30
+ stats: {
31
+ totalMessages: number;
32
+ candidateMessages: number;
33
+ recruiterMessages: number;
34
+ systemMessages: number;
26
35
  };
27
36
  chatMessages: {
28
37
  time: string;
@@ -35,3 +44,4 @@ export declare const zhipinGetCandidateInfo: import("@roll-agent/sdk").ToolDefin
35
44
  error?: string | undefined;
36
45
  preferredBrand?: string | undefined;
37
46
  }>;
47
+ export {};
@@ -1,13 +1,10 @@
1
- import { getRecommendTarget, waitForRecommendList } from "../pages/zhipin/recommend-list.ts";
2
- import { getContextManager } from "../runtime-holder.ts";
3
- import { VisualActivitySession } from "../visual-activity-session.ts";
4
- type RecommendTarget = ReturnType<typeof getRecommendTarget>;
5
- type VisualActivitySessionLike = Pick<VisualActivitySession, "begin" | "highlightSelector" | "succeed" | "fail" | "retarget">;
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" | "succeed" | "fail">;
6
5
  type ZhipinGetCandidateListDeps = {
7
- readonly getContextManager: typeof getContextManager;
8
- readonly getRecommendTarget: typeof getRecommendTarget;
9
- readonly waitForRecommendList: typeof waitForRecommendList;
10
- readonly createVisualActivitySession: (target: RecommendTarget) => VisualActivitySessionLike;
6
+ readonly openNativePagePort: typeof openZhipinNativePagePort;
7
+ readonly createNativeVisualActivitySession: (page: ZhipinNativePagePort) => NativeVisualActivitySessionLike;
11
8
  };
12
9
  export declare function setZhipinGetCandidateListDepsForTests(override: Partial<ZhipinGetCandidateListDeps> | undefined): void;
13
10
  export declare const zhipinGetCandidateList: import("@roll-agent/sdk").ToolDefinition<{
@@ -18,18 +15,18 @@ export declare const zhipinGetCandidateList: import("@roll-agent/sdk").ToolDefin
18
15
  success: boolean;
19
16
  candidates: {
20
17
  name: string;
21
- candidateId: string;
22
18
  index: number;
23
- expectedLocation: string;
24
- expectedPosition: string;
19
+ candidateId: string;
25
20
  age: string;
26
21
  experience: string;
27
22
  education: string;
28
- expectedSalary: string;
29
- tags: string[];
30
23
  workStatus: string;
31
24
  company: string;
32
25
  currentPosition: string;
26
+ expectedLocation: string;
27
+ expectedPosition: string;
28
+ expectedSalary: string;
29
+ tags: string[];
33
30
  buttonText: string;
34
31
  }[];
35
32
  total: number;
@@ -1,13 +1,11 @@
1
- import type { Page } from "@roll-agent/browser";
2
- import { getCurrentZhipinRecruiterIdentity } from "../pages/zhipin/recruiter-identity.ts";
3
- import { findHeaderScope } from "../pages/zhipin/username.ts";
4
- import { getContextManager } from "../runtime-holder.ts";
5
- import { VisualActivitySession } from "../visual-activity-session.ts";
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
+ import { pickBestUsername } from "../pages/zhipin/username.ts";
6
5
  type ZhipinGetUsernameDeps = {
7
- readonly getContextManager: typeof getContextManager;
8
- readonly findHeaderScope: typeof findHeaderScope;
9
- readonly getCurrentZhipinRecruiterIdentity: typeof getCurrentZhipinRecruiterIdentity;
10
- readonly createVisualActivitySession: (page: Page) => VisualActivitySession;
6
+ readonly openNativePagePort: typeof openZhipinNativePagePort;
7
+ readonly pickBestUsername: typeof pickBestUsername;
8
+ readonly createNativeVisualActivitySession: (page: ZhipinNativePagePort) => NativeVisualActivitySession;
11
9
  };
12
10
  export declare function setZhipinGetUsernameDepsForTests(override: Partial<ZhipinGetUsernameDeps> | undefined): void;
13
11
  export declare const zhipinGetUsername: import("@roll-agent/sdk").ToolDefinition<{}, {
@@ -2,10 +2,10 @@ export declare const zhipinLocateResumeCanvas: import("@roll-agent/sdk").ToolDef
2
2
  success: boolean;
3
3
  error?: string | undefined;
4
4
  screenshotArea?: {
5
- width: number;
6
- height: number;
7
5
  x: number;
8
6
  y: number;
7
+ width: number;
8
+ height: number;
9
9
  } | undefined;
10
10
  canvasInfo?: {
11
11
  width: number;
@@ -1,21 +1,14 @@
1
- import type { Page } from "@roll-agent/browser";
2
- import { randomDelay } from "../pages/zhipin/anti-detection.ts";
3
- import { findZhipinSidebarSectionLink, isZhipinChatSurfaceOpen, waitForZhipinChatSurface } from "../pages/zhipin/sidebar-navigation.ts";
4
- import { toAttachedPageInfo } from "../page-info.ts";
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";
5
4
  import { getContextManager } from "../runtime-holder.ts";
6
- import { VisualActivitySession } from "../visual-activity-session.ts";
7
- import { moveVisualCursorToLocator, showVisualClickOnLocator } from "../visual-cursor.ts";
8
- type VisualActivitySessionLike = Pick<VisualActivitySession, "begin" | "highlightSelector" | "succeed" | "fail">;
5
+ type NativeVisualActivitySessionLike = Pick<NativeVisualActivitySession, "begin" | "highlightSelector" | "succeed" | "fail"> & {
6
+ readonly highlightPoint?: NativeVisualActivitySession["highlightPoint"];
7
+ };
9
8
  type ZhipinOpenChatPageDeps = {
10
9
  readonly getContextManager: typeof getContextManager;
11
- readonly findZhipinSidebarSectionLink: typeof findZhipinSidebarSectionLink;
12
- readonly isZhipinChatSurfaceOpen: typeof isZhipinChatSurfaceOpen;
13
- readonly waitForZhipinChatSurface: typeof waitForZhipinChatSurface;
14
- readonly moveVisualCursorToLocator: typeof moveVisualCursorToLocator;
15
- readonly showVisualClickOnLocator: typeof showVisualClickOnLocator;
16
- readonly randomDelay: typeof randomDelay;
17
- readonly toAttachedPageInfo: typeof toAttachedPageInfo;
18
- readonly createVisualActivitySession: (page: Page) => VisualActivitySessionLike;
10
+ readonly openNativePagePort: typeof openZhipinNativePagePort;
11
+ readonly createNativeVisualActivitySession: (page: ZhipinNativePagePort) => NativeVisualActivitySessionLike;
19
12
  };
20
13
  export declare function setZhipinOpenChatPageDepsForTests(override: Partial<ZhipinOpenChatPageDeps> | undefined): void;
21
14
  export declare const zhipinOpenChatPage: import("@roll-agent/sdk").ToolDefinition<{}, {
@@ -1,17 +1,27 @@
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" | "succeed" | "fail">;
5
+ type ZhipinOpenChatDeps = {
6
+ readonly openNativePagePort: typeof openZhipinNativePagePort;
7
+ readonly createNativeVisualActivitySession: (page: ZhipinNativePagePort) => NativeVisualActivitySessionLike;
8
+ };
9
+ export declare function setZhipinOpenChatDepsForTests(override: Partial<ZhipinOpenChatDeps> | undefined): void;
1
10
  export declare const zhipinOpenChat: import("@roll-agent/sdk").ToolDefinition<{
11
+ index?: number | undefined;
2
12
  conversationId?: string | undefined;
3
13
  candidateName?: string | undefined;
4
- index?: number | undefined;
5
14
  preferUnread?: boolean | undefined;
6
15
  }, {
16
+ index: number;
7
17
  success: boolean;
8
18
  conversationId: string;
9
19
  candidateId: string;
10
20
  candidateName: string;
11
- index: number;
12
21
  hasUnread: boolean;
13
22
  unreadCount: number;
14
23
  lastMessageTime: string;
15
24
  messagePreview: string;
16
25
  error?: string | undefined;
17
26
  }>;
27
+ export {};
@@ -1,23 +1,14 @@
1
- import { randomDelay } from "../pages/zhipin/anti-detection.ts";
2
- import { getRecommendTarget } from "../pages/zhipin/recommend-list.ts";
3
- import { findZhipinSidebarSectionLink, isZhipinRecommendSurfaceOpen, waitForZhipinRecommendSurface } from "../pages/zhipin/sidebar-navigation.ts";
4
- import { toAttachedPageInfo } from "../page-info.ts";
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";
5
4
  import { getContextManager } from "../runtime-holder.ts";
6
- import { VisualActivitySession } from "../visual-activity-session.ts";
7
- import { moveVisualCursorToLocator, showVisualClickOnLocator } from "../visual-cursor.ts";
8
- type RecommendTarget = ReturnType<typeof getRecommendTarget>;
9
- type VisualActivitySessionLike = Pick<VisualActivitySession, "begin" | "highlightSelector" | "retarget" | "succeed" | "fail">;
5
+ type NativeVisualActivitySessionLike = Pick<NativeVisualActivitySession, "begin" | "highlightSelector" | "succeed" | "fail"> & {
6
+ readonly highlightPoint?: NativeVisualActivitySession["highlightPoint"];
7
+ };
10
8
  type ZhipinOpenRecommendPageDeps = {
11
9
  readonly getContextManager: typeof getContextManager;
12
- readonly getRecommendTarget: typeof getRecommendTarget;
13
- readonly findZhipinSidebarSectionLink: typeof findZhipinSidebarSectionLink;
14
- readonly isZhipinRecommendSurfaceOpen: typeof isZhipinRecommendSurfaceOpen;
15
- readonly waitForZhipinRecommendSurface: typeof waitForZhipinRecommendSurface;
16
- readonly moveVisualCursorToLocator: typeof moveVisualCursorToLocator;
17
- readonly showVisualClickOnLocator: typeof showVisualClickOnLocator;
18
- readonly randomDelay: typeof randomDelay;
19
- readonly toAttachedPageInfo: typeof toAttachedPageInfo;
20
- readonly createVisualActivitySession: (target: RecommendTarget) => VisualActivitySessionLike;
10
+ readonly openNativePagePort: typeof openZhipinNativePagePort;
11
+ readonly createNativeVisualActivitySession: (page: ZhipinNativePagePort) => NativeVisualActivitySessionLike;
21
12
  };
22
13
  export declare function setZhipinOpenRecommendPageDepsForTests(override: Partial<ZhipinOpenRecommendPageDeps> | undefined): void;
23
14
  export declare const zhipinOpenRecommendPage: import("@roll-agent/sdk").ToolDefinition<{}, {
@@ -1,3 +1,11 @@
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 ZhipinReadMessagesDeps = {
5
+ readonly openNativePagePort: typeof openZhipinNativePagePort;
6
+ readonly createNativeVisualActivitySession: (page: ZhipinNativePagePort) => NativeVisualActivitySession;
7
+ };
8
+ export declare function setZhipinReadMessagesDepsForTests(override: Partial<ZhipinReadMessagesDeps> | undefined): void;
1
9
  export declare const zhipinReadMessages: import("@roll-agent/sdk").ToolDefinition<{
2
10
  limit?: number | undefined;
3
11
  onlyUnread?: boolean | undefined;
@@ -23,3 +31,4 @@ export declare const zhipinReadMessages: import("@roll-agent/sdk").ToolDefinitio
23
31
  withUnread: number;
24
32
  };
25
33
  }>;
34
+ export {};
@@ -1,38 +1,28 @@
1
- import { getContextManager } from "../runtime-holder.ts";
2
- import { humanDelay, shouldAddRandomBehavior, performRandomScroll } from "../pages/zhipin/anti-detection.ts";
3
- import { getRecommendTarget, inspectRecommendCard, waitForRecommendList } from "../pages/zhipin/recommend-list.ts";
4
- import { VisualActivitySession } from "../visual-activity-session.ts";
5
- import { moveVisualCursorToLocator, showVisualClickOnLocator } from "../visual-cursor.ts";
6
- type RecommendTarget = ReturnType<typeof getRecommendTarget>;
7
- type VisualActivitySessionLike = Pick<VisualActivitySession, "begin" | "highlightSelector" | "highlightLocator" | "succeed" | "fail" | "retarget">;
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" | "highlightPoint" | "succeed" | "fail">;
8
5
  type ZhipinSayHelloDeps = {
9
- readonly getContextManager: typeof getContextManager;
10
- readonly getRecommendTarget: typeof getRecommendTarget;
11
- readonly waitForRecommendList: typeof waitForRecommendList;
12
- readonly inspectRecommendCard: typeof inspectRecommendCard;
13
- readonly moveVisualCursorToLocator: typeof moveVisualCursorToLocator;
14
- readonly showVisualClickOnLocator: typeof showVisualClickOnLocator;
15
- readonly humanDelay: typeof humanDelay;
16
- readonly shouldAddRandomBehavior: typeof shouldAddRandomBehavior;
17
- readonly performRandomScroll: typeof performRandomScroll;
18
- readonly createVisualActivitySession: (target: RecommendTarget) => VisualActivitySessionLike;
6
+ readonly openNativePagePort: typeof openZhipinNativePagePort;
7
+ readonly createNativeVisualActivitySession: (page: ZhipinNativePagePort) => NativeVisualActivitySessionLike;
8
+ readonly sleep: (ms: number) => Promise<void>;
19
9
  };
20
10
  export declare function setZhipinSayHelloDepsForTests(override: Partial<ZhipinSayHelloDeps> | undefined): void;
21
11
  export declare const zhipinSayHello: import("@roll-agent/sdk").ToolDefinition<{
22
12
  indices: number[];
23
13
  }, {
24
- summary: {
25
- failed: number;
26
- total: number;
27
- succeeded: number;
28
- };
29
14
  success: boolean;
30
15
  results: {
16
+ index: number;
31
17
  success: boolean;
32
18
  candidateId: string;
33
19
  candidateName: string;
34
- index: number;
35
20
  error?: string | undefined;
36
21
  }[];
22
+ summary: {
23
+ total: number;
24
+ succeeded: number;
25
+ failed: number;
26
+ };
37
27
  }>;
38
28
  export {};
@@ -1,3 +1,12 @@
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" | "succeed" | "fail">;
5
+ type ZhipinScrollViewDeps = {
6
+ readonly openNativePagePort: typeof openZhipinNativePagePort;
7
+ readonly createNativeVisualActivitySession: (page: ZhipinNativePagePort) => NativeVisualActivitySessionLike;
8
+ };
9
+ export declare function setZhipinScrollViewDepsForTests(override: Partial<ZhipinScrollViewDeps> | undefined): void;
1
10
  export declare const zhipinScrollView: import("@roll-agent/sdk").ToolDefinition<{
2
11
  surface: "chat-list" | "chat-history" | "recommend-list";
3
12
  direction?: "up" | "down" | undefined;
@@ -6,9 +15,6 @@ export declare const zhipinScrollView: import("@roll-agent/sdk").ToolDefinition<
6
15
  settleMs?: number | undefined;
7
16
  }, {
8
17
  success: boolean;
9
- direction: "up" | "down";
10
- stepsRequested: number;
11
- stepsCompleted: number;
12
18
  before: {
13
19
  containerFound: boolean;
14
20
  containerLabel: string;
@@ -29,7 +35,11 @@ export declare const zhipinScrollView: import("@roll-agent/sdk").ToolDefinition<
29
35
  atEnd: boolean;
30
36
  itemCount: number;
31
37
  };
38
+ direction: "up" | "down";
39
+ stepsRequested: number;
40
+ stepsCompleted: number;
32
41
  reachedBoundary: boolean;
33
42
  surface: "chat-list" | "chat-history" | "recommend-list";
34
43
  error?: string | undefined;
35
44
  }>;
45
+ export {};
@@ -1,13 +1,21 @@
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
+ import { getReplyAuthorityKeysLoaded } from "../runtime-holder.ts";
5
+ type NativeVisualActivitySessionLike = Pick<NativeVisualActivitySession, "begin" | "highlightPoint" | "succeed" | "fail">;
6
+ type ZhipinSendReplyDeps = {
7
+ readonly getReplyAuthorityKeysLoaded: typeof getReplyAuthorityKeysLoaded;
8
+ readonly openNativePagePort: typeof openZhipinNativePagePort;
9
+ readonly createNativeVisualActivitySession: (page: ZhipinNativePagePort) => NativeVisualActivitySessionLike;
10
+ };
11
+ export declare function setZhipinSendReplyDepsForTests(override: Partial<ZhipinSendReplyDeps> | undefined): void;
1
12
  export declare const zhipinSendReply: import("@roll-agent/sdk").ToolDefinition<{
2
13
  signedEnvelope: string;
3
- candidateName?: string | undefined;
4
14
  index?: number | undefined;
15
+ candidateName?: string | undefined;
5
16
  }, {
6
17
  success: boolean;
7
18
  sentMessage: string;
8
- error: string | undefined;
9
- } | {
10
- success: boolean;
11
- sentMessage: string;
12
- error?: never;
19
+ error?: string | undefined;
13
20
  }>;
21
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@roll-agent/browser-use-agent",
3
- "version": "0.7.4",
3
+ "version": "0.7.6",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",
@@ -46,7 +46,7 @@
46
46
  "dependencies": {
47
47
  "zod": "^3.25.76",
48
48
  "@roll-agent/sdk": "0.1.6",
49
- "@roll-agent/browser": "0.2.0"
49
+ "@roll-agent/browser": "0.3.0"
50
50
  },
51
51
  "devDependencies": {
52
52
  "@types/node": "^22.0.0"
@@ -0,0 +1,77 @@
1
+ # BOSS直聘 CDP/风控诊断
2
+
3
+ `zhipin_diagnose_browser_state` 用于把 BOSS 页面回退/风控触发点拆成可观测阶段。它不是业务读取工具,也不负责规避检测。
4
+
5
+ ## 触发场景
6
+
7
+ - 调用 BOSS 工具后页面自动 `history.goBack()` 或回到上一页。
8
+ - 某个账号或浏览器 profile 触发异常,其它账号不触发。
9
+ - 需要判断异常来自 native CDP 连接、Playwright attach、`Runtime.evaluate`、DOM 读取、storage/cookie 读取还是网络上报。
10
+
11
+ ## 阶段模型
12
+
13
+ ```text
14
+ 低侵入:
15
+ native -> native-watch
16
+
17
+ native CDP page WebSocket:
18
+ native -> native-ws-connect -> native-page-bring-front
19
+ native -> native-ws-connect -> native-evaluate-url-no-runtime-enable
20
+ native -> native-ws-connect -> native-dom-read-no-runtime-enable
21
+ native -> native-ws-connect -> native-input-move-no-runtime-enable
22
+ native -> native-ws-connect -> native-runtime-enable -> native-evaluate-url -> native-dom-read
23
+
24
+ Playwright attach:
25
+ native -> browser-attach -> browser-attach-watch -> page-attach -> network-watch
26
+ native -> browser-attach -> browser-attach-watch -> page-attach -> page-evaluate -> detector-fingerprint -> storage-summary
27
+ ```
28
+
29
+ ## Phase 说明
30
+
31
+ | `phase` | 动作 | 诊断问题 |
32
+ | --- | --- | --- |
33
+ | `native` | 只调用原生 CDP `/json/list` 枚举页面 | 当前有哪些 BOSS target;最低风险默认阶段。 |
34
+ | `native-watch` | 不 attach,在 `watchMs` 内重复读取 URL/title | 不连接 Playwright 时页面是否自己跳转。 |
35
+ | `native-ws-connect` | 连接目标页 `webSocketDebuggerUrl`,不调用 Playwright/Puppeteer | 仅建立 native page WebSocket 是否触发。 |
36
+ | `native-page-bring-front` | 发送 `Page.bringToFront`,不调用 `Runtime.enable` | Page domain 前台切换是否触发。 |
37
+ | `native-evaluate-url-no-runtime-enable` | 直接 `Runtime.evaluate` 读取 URL/title,不先 `Runtime.enable` | 是 `Runtime.enable` 独有触发,还是 evaluate 本身触发。 |
38
+ | `native-dom-read-no-runtime-enable` | 直接 `DOM.getDocument`,不先 `Runtime.enable` / `DOM.enable` | DOM domain 最小读取是否触发。 |
39
+ | `native-input-move-no-runtime-enable` | 直接 `Input.dispatchMouseEvent(mouseMoved)` | Input domain 最小事件是否触发。 |
40
+ | `native-runtime-enable` | 发送 `Runtime.enable` | Runtime domain 是否触发。 |
41
+ | `native-evaluate-url` | 读取 `location.href`、`document.title`、可见状态 | 最小页面 JS evaluate 是否触发。 |
42
+ | `native-dom-read` | DOM 摘要读取,只返回数量/长度 | DOM 读取是否触发。 |
43
+ | `browser-attach` | 执行 `runtime.getBrowser()` 并观察 native URL/title | Playwright Browser CDP 连接是否触发异步回退。 |
44
+ | `page-attach` | 执行 `ctxManager.getPage("zhipin")` | 绑定具体页面/context 是否触发。 |
45
+ | `network-watch` | 监听相关 request/response 和 frame navigation | attach 后是否出现 APM/security 上报或 URL 自动变化。 |
46
+ | `page-evaluate` | Playwright 页面内最小 evaluate | 页面 JS evaluate 是否触发。 |
47
+ | `detector-fingerprint` | 读取 `navigator.webdriver`、`window.cdc_*`、Playwright binding 标记 | 是否暴露自动化指纹。 |
48
+ | `storage-summary` | 读取 storage/cookie 脱敏摘要 | storage/cookie 读取是否触发。 |
49
+
50
+ ## 推进规则
51
+
52
+ 1. 先调用 `zhipin_diagnose_browser_state()` 或 `phase="native"`。
53
+ 2. `nativePages` 只有一个 BOSS 页时可递进;多个 BOSS 页时后续必须传 `targetPageId`。
54
+ 3. 高风险账号先跑 `native-watch`。
55
+ 4. 验证 native CDP 时先跑 `native-ws-connect`,再跑 no-`Runtime.enable` 分支。
56
+ 5. 每次只推进一个阶段,并在每次调用后观察 `nativeTimeline`。
57
+ 6. `browser-attach` 失败,或 `browser-attach-watch` 出现 `urlChangedFromPrevious=true` 时,停止调用 Playwright-backed BOSS 工具。
58
+ 7. 任意 `native-*-watch` 快照出现 `urlChangedFromPrevious=true` 时,停止加深 native CDP 实验。
59
+ 8. 只有需要复现 `Runtime.enable` 红线时才跑 `native-runtime-enable`。
60
+ 9. 要验证网络上报,只在 `browser-attach` 未触发 URL 变化后继续跑 `page-attach` / `network-watch`。
61
+ 10. `storage-summary` 只返回脱敏摘要;禁止要求或传播 cookie/localStorage/sessionStorage 原始值。
62
+
63
+ ## 返回字段
64
+
65
+ | 字段 | 含义 |
66
+ | --- | --- |
67
+ | `nativePages` | 原生 CDP 页面列表,`pageId` 可作为后续 `targetPageId`。 |
68
+ | `targetPage` | 本次绑定或诊断的 BOSS 页面。 |
69
+ | `browserAttached` / `pageAttached` | 是否进入 Playwright attach 阶段。 |
70
+ | `nativeTimeline` | 每个阶段后的 native URL/title 快照;`urlChangedFromPrevious=true` 是关键触发证据。 |
71
+ | `nativeCdp` | native CDP 探测摘要,不包含页面正文。 |
72
+ | `networkEvents` | APM/security 请求摘要,不抓请求体。 |
73
+ | `navigationEvents` | attach 后 frame URL 变化。 |
74
+ | `detectorFingerprint` | 自动化相关公开标志。 |
75
+ | `phases` | 阶段成功状态、耗时、错误。 |
76
+ | `warnings` | 多页面、目标页缺失、URL 变化等边界提示。 |
77
+ | `storage` | storage/cookie 脱敏形状、长度和计数器差分。 |
@@ -0,0 +1,102 @@
1
+ # BOSS直聘业务编排细节
2
+
3
+ ## 聊天主键
4
+
5
+ `conversationId` / `candidateId` 是跨 tool 的稳定主键,`index` 只表示当前 DOM 快照。
6
+
7
+ 错误做法:
8
+
9
+ - 把 `zhipin_read_messages` 返回数组里的 `index` 当作后续点击主键。
10
+ - 手动滚动或列表重排后继续使用旧 `index`。
11
+ - 用 `candidateName` 模糊匹配会话后,把历史 `candidateId` 假定为同一人。
12
+ - 由 orchestrator 自己重建 `target.conversationId` / `target.candidateId`。
13
+
14
+ 推荐做法:
15
+
16
+ 1. `zhipin_read_messages` 记录 `conversationId + candidateId + candidateName`。
17
+ 2. `zhipin_open_chat(conversationId)`。
18
+ 3. `zhipin_get_candidate_info(conversationId)`。
19
+ 4. `smart-reply-agent.generate_reply(..., target)`。
20
+ 5. `zhipin_send_reply(signedEnvelope)`。
21
+
22
+ ## 动态列表
23
+
24
+ BOSS 页面通常不是整页滚动,而是内部容器滚动:
25
+
26
+ ```text
27
+ chat-list -> 左侧消息列表,默认向下滚动,去重主键 conversationId
28
+ chat-history -> 右侧聊天记录,默认向上滚动,用于加载更早历史
29
+ recommend-list -> 推荐牛人列表,默认向下滚动,去重主键 candidateId/data-geek
30
+ ```
31
+
32
+ 规则:
33
+
34
+ 1. 业务读取优先用自带 `autoScroll` 的工具:`zhipin_read_messages`、`zhipin_get_candidate_list`。
35
+ 2. `zhipin_scroll_view` 只用于显式翻页、调试和补救。
36
+ 3. `onlyUnread=true` 时不要依赖 `limit` 提前停止;未读会话可能在首屏之后。
37
+ 4. `maxScrolls` 用于成本控制,需要更完整列表时显式调大。
38
+ 5. 推荐列表若 `total < maxResults`,先看 `scrollStats.stopReason`:
39
+ - `target-count`:已达到目标数量。
40
+ - `boundary`:触底并等待追加数据后仍无新增。
41
+ - `no-new-items`:连续滚动没有新去重项。
42
+ - `max-steps`:达到滚动步数上限。
43
+
44
+ ## preferredBrand
45
+
46
+ `zhipin_get_candidate_info` 会从 `candidateInfo.communicationPosition` 中解析:
47
+
48
+ - `expectedLocation`
49
+ - `expectedPosition`
50
+ - `preferredBrand`
51
+
52
+ `preferredBrand` 规则:
53
+
54
+ - 仅当 `communicationPosition` 含连字符类分隔符时输出:`-` / `-` / `—` / `–`。
55
+ - 取分隔符前的第一段,例如 `肯德基-服务员` -> `preferredBrand: "肯德基"`。
56
+ - 没有分隔符时不输出。
57
+ - 禁止用通用岗位名或 `zhipin_get_candidate_list.company` 伪造品牌。
58
+
59
+ ## Reply Authority
60
+
61
+ `zhipin_send_reply` 只接受 Reply Authority Service 签发的 `signedEnvelope`。
62
+
63
+ 发送前校验:
64
+
65
+ 1. 启动期公钥预加载状态:`browser_status.replyAuthorityKeysLoaded`。
66
+ 2. Ed25519 签名。
67
+ 3. envelope 过期时间。
68
+ 4. replay `jti` 是否已消费。
69
+ 5. 当前选中聊天是否匹配 `conversationId + candidateId`。
70
+ 6. 当前登录招聘者是否匹配 `recruiterBinding`。
71
+
72
+ `generate_reply` 的 `target` 两种模式:
73
+
74
+ ```json
75
+ {
76
+ "platform": "zhipin",
77
+ "tenantId": "tenant-001",
78
+ "conversationId": "conversation-1",
79
+ "candidateId": "candidate-1",
80
+ "recruiterBinding": { "platform": "zhipin", "username": "郭晓阳" }
81
+ }
82
+ ```
83
+
84
+ ```json
85
+ {
86
+ "platform": "zhipin",
87
+ "conversationId": "conversation-1",
88
+ "candidateId": "candidate-1",
89
+ "recruiterUsername": "郭晓阳"
90
+ }
91
+ ```
92
+
93
+ 第二种代理模式由 `smart-reply-agent` 调用 Reply Authority resolver 解析 `tenantId + recruiterBinding`。
94
+
95
+ ## 推荐候选人链路
96
+
97
+ 1. `zhipin_open_recommend_page()`。
98
+ 2. `zhipin_filter_recommend_candidates(ageMin?, ageMax?, gender?, activity?)`。
99
+ 3. `zhipin_get_candidate_list(maxResults?, autoScroll=true, maxScrolls=4)`。
100
+ 4. `zhipin_say_hello(indices)`。
101
+
102
+ `zhipin_say_hello(indices)` 的 `indices` 也是当前 DOM 快照索引;筛选、滚动或列表刷新后必须重新读取列表。