@reconcrap/boss-recommend-mcp 2.1.4 → 2.1.5

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.
package/README.md CHANGED
@@ -160,16 +160,16 @@ boss-recommend-mcp schedule-status --schedule-id <schedule_id>
160
160
  - 学历支持单选与多选语义:如“本科及以上”会展开为 `本科/硕士/博士`;如“大专、本科”只勾选这两项
161
161
  - 执行前会先补齐筛选值、岗位、后置动作和休息强度,然后只做一次总确认
162
162
  - 页面就绪(已登录且在 recommend 页)后,会先提取岗位栏全部岗位,使用精确岗位名填入 run payload,再进入总确认
163
- - 在真正开始 search/screen 或创建 cron 前,总确认需包含岗位、全部筛选参数、criteria、target_count、post_actionmax_greet_count、restLevel 和定时信息(如适用)
163
+ - 在真正开始 search/screen 或创建 cron 前,总确认需包含岗位、全部筛选参数、criteria、target_count、post_action、可选 max_greet_count、restLevel 和定时信息(如适用)
164
164
  - npm 全局安装后会自动执行 install:生成 skill、导出 MCP 模板,并自动尝试写入已检测到的外部 agent MCP 配置(含 Trae / trae-cn / Cursor / Claude / OpenClaw)
165
165
  - 2.x installer 会迁移已存在的 legacy Boss MCP 配置:把 `boss-recommend` 指向统一 `@reconcrap/boss-recommend-mcp`,并从同一个 `mcp.json` 中移除旧 `boss-recruit-mcp` / standalone `boss-chat` / 本地 legacy Boss 路径;写入前会生成 `.boss-mcp-migration-*.bak` 备份
166
166
  - 2.x installer 会刷新外部 agent skills:`boss-recommend-pipeline`、`boss-recruit-pipeline`、`boss-chat` 都来自当前包,旧 recruit/chat skill 会被覆盖为统一 MCP 路由
167
167
  - npm / npx 安装后会自动初始化 `screening-config.json` 模板(优先写入 workspace 的 `config/`,不可写时回退到用户目录)
168
168
  - npm 安装流程会预创建运行目录(跨平台):`~/.boss-recommend-mcp`、`~/.boss-recommend-mcp/runs`、`~/.boss-recommend-mcp/boss-chat` 及其 `logs/runs/profiles/reports/artifacts/state`
169
- - `post_action`、`target_count` `max_greet_count`(当 `post_action=greet`)通过同一次总确认锁定
169
+ - `post_action`、`target_count` 和可选 `max_greet_count` 通过同一次总确认锁定
170
170
  - 新流程中 `confirmation.final_confirmed=true` 是总确认;旧版逐字段 `*_confirmed` JSON 仍兼容但不是推荐写法
171
171
  - 一旦确认 `post_action`,本次运行内所有通过人选都统一按该动作执行
172
- - 若达到 `max_greet_count` 但流程仍需继续,后续通过人选会自动改为收藏
172
+ - 若达到可选 `max_greet_count` 但流程仍需继续,后续通过人选会继续筛选但不再执行打招呼动作
173
173
  - 不会对每位候选人重复确认
174
174
  - 推荐页详情处理完成后,会强制关闭详情页并确认已关闭
175
175
  - 简历提取优先使用 Network 响应;没有可解析 Network CV 时,回退到完整滚动截图序列再交给多模态模型判断
@@ -501,8 +501,7 @@ Trae-CN / 长对话防循环建议:
501
501
  "criteria": "候选人需要有 AI Agent 或 MCP 工具开发经验",
502
502
  "job": "算法工程师(视频/图像模型方向) _ 杭州",
503
503
  "target_count": 20,
504
- "post_action": "greet",
505
- "max_greet_count": 10
504
+ "post_action": "greet"
506
505
  },
507
506
  "human_behavior": {
508
507
  "restLevel": "medium"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reconcrap/boss-recommend-mcp",
3
- "version": "2.1.4",
3
+ "version": "2.1.5",
4
4
  "description": "Unified MCP pipeline for recommend-page filtering and screening on Boss Zhipin",
5
5
  "keywords": [
6
6
  "boss",
@@ -6,7 +6,7 @@
6
6
 
7
7
  - 先确认推荐页 filters
8
8
  - 再确认筛选 criteria
9
- - 再确认本次运行统一动作 `favorite` 或 `greet`
9
+ - 再确认本次运行统一动作 `greet` 或 `none`
10
10
  - 每次运行都要让用户明确选择休息强度 `low` / `medium` / `high`,并传入 `human_behavior.restLevel`
11
11
  - 只确认一次 `post_action`,不要逐个候选人反复确认
12
12
  - 运行中临时中断请使用 `pause_recommend_pipeline_run`(按 run_id),不要靠自然语言“暂停/继续”指令
@@ -7,7 +7,7 @@ description: "Use when users want Boss recommend-page filtering/screening via bo
7
7
 
8
8
  ## Goal
9
9
 
10
- 当用户要在 Boss 推荐页筛人时,必须走 `start_recommend_pipeline_run`;若是稍后/cron 启动,必须走 `schedule_recommend_pipeline_run`。先补齐缺失值并读取岗位列表,然后展示一次包含岗位、筛选项、criteria、目标人数、后置动作、最大招呼数、休息强度和定时信息的总确认;用户确认后设置 `final_confirmed=true` 即可启动或创建定时任务。2.0 CDP-only 路径不再支持 legacy recommend -> chat 自动衔接;若用户要聊天页筛选或求简历,必须在推荐页任务完成后显式改用 `boss-chat` 工具。
10
+ 当用户要在 Boss 推荐页筛人时,必须走 `start_recommend_pipeline_run`;若是稍后/cron 启动,必须走 `schedule_recommend_pipeline_run`。先补齐缺失值并读取岗位列表,然后展示一次包含岗位、筛选项、criteria、目标人数、后置动作、可选最大招呼数、休息强度和定时信息的总确认;用户确认后设置 `final_confirmed=true` 即可启动或创建定时任务。2.0 CDP-only 路径不再支持 legacy recommend -> chat 自动衔接;若用户要聊天页筛选或求简历,必须在推荐页任务完成后显式改用 `boss-chat` 工具。
11
11
 
12
12
  ## Hard Rules (Must Follow)
13
13
 
@@ -31,7 +31,7 @@ description: "Use when users want Boss recommend-page filtering/screening via bo
31
31
 
32
32
  - **参数确认**
33
33
  - `criteria` 必须是用户开放式自然语言;禁止“严格/宽松执行”等预设替代。
34
- - `post_action=greet` 时,`max_greet_count` 必须出现在总确认里;禁止未告知用户就自动默认为 `target_count`。
34
+ - `max_greet_count` 仅是可选的 `post_action=greet` 上限;禁止未告知用户就自动默认为 `target_count`。
35
35
  - 正式执行前必须 `final_confirmed=true`。
36
36
  - 真实筛选禁止传 `detail_limit: 0`;recommend 默认必须打开候选人详情/CV。只有用户明确要求“卡片-only 调试”时,才允许同时传 `detail_limit: 0` 和 `allow_card_only_screening: true`。
37
37
 
@@ -49,8 +49,8 @@ description: "Use when users want Boss recommend-page filtering/screening via bo
49
49
  - `school_tag`、`degree`、`gender`、`recent_not_view`
50
50
  - `criteria`(开放文本)
51
51
  - `target_count`(可空)
52
- - `post_action`:`favorite|greet|none`
53
- - `max_greet_count`(仅当 `post_action=greet`)
52
+ - `post_action`:`greet|none`
53
+ - `max_greet_count`(可选,仅当 `post_action=greet`)
54
54
  - `rest_level`:`low|medium|high`
55
55
  - `job`(来自 `list_recommend_jobs` / `job_options` 的精确岗位名)
56
56
  - cron/定时任务的启动时间(如适用)
@@ -84,7 +84,7 @@ description: "Use when users want Boss recommend-page filtering/screening via bo
84
84
  - `degree`: `不限/初中及以下/中专/中技/高中/大专/本科/硕士/博士`
85
85
  - `gender`: `不限/男/女`
86
86
  - `recent_not_view`: `不限/近14天没有`
87
- - `post_action`: `favorite/greet/none`
87
+ - `post_action`: `greet/none`
88
88
  - `rest_level`: `low/medium/high`
89
89
 
90
90
  ## Tool Usage
@@ -123,7 +123,7 @@ description: "Use when users want Boss recommend-page filtering/screening via bo
123
123
  创建 cron 时必须在设置 cron 的当下完成全部交互:
124
124
 
125
125
  1. 锁定用户原始 instruction,不改写、不摘要,criteria 放入 `overrides.criteria` 时必须逐字保留。
126
- 2. 收集全部筛选项、`target_count`、`post_action`、`max_greet_count`(如需要)和本次 `rest_level`。
126
+ 2. 收集全部筛选项、`target_count`、`post_action`、可选 `max_greet_count` 和本次 `rest_level`。
127
127
  3. 调用 `list_recommend_jobs`;若 Chrome 未打开,工具会尝试自动打开本机 9222 Chrome 并进入推荐页。若返回 `BOSS_LOGIN_REQUIRED` 或页面不可用,停止 cron 创建,让用户登录/修复后重试。
128
128
  4. 用 `job_names` 中的精确岗位名填入 `overrides.job`,展示包含启动时间的最终总确认;用户确认后写入 `final_confirmed=true`。
129
129
  5. 调用 `prepare_recommend_pipeline_run` 传入将来要执行的完整 payload;只有 `READY + cron_ready=true` 才能继续。
@@ -29,8 +29,7 @@ description: "Use when users want Boss search/recruit-page screening via the uni
29
29
  - 只有工具返回 `BOSS_LOGIN_REQUIRED` / `requires_login=true` 时,才要求用户在自动打开的 Chrome 窗口人工登录 Boss 后重试;不要把“没开 9222 Chrome”当作缺参。
30
30
  - 若本机找不到 Chrome,可提示用户设置 `BOSS_MCP_CHROME_PATH` 或 `BOSS_RECOMMEND_CHROME_PATH`;非本机 debug host 不自动启动。
31
31
  - 若用户未提供岗位,必须先询问岗位。搜索页岗位选择在关键词输入框旁边;不要猜测默认岗位。
32
- - 若用户提供城市、学历、学校、关键词、过滤已看、人选目标数、筛选条件、post action、max greet 等参数,必须逐项传入或确认。
33
- - `post_action=greet` 时必须确认 `max_greet_count`;不要默认等于 `target_count`。
32
+ - 若用户提供城市、学历、学校、关键词、过滤已看、人选目标数、筛选条件等参数,必须逐项传入或确认。
34
33
  - 搜索页和推荐页一样支持多选筛选条件;不要把多选降级成单选。
35
34
  - 每次 run 必须明确询问用户本次休息强度 `rest_level`:`low`(旧策略)/ `medium`(约 5 小时或 700 人累计休息 30 分钟)/ `high`(约 5 小时或 700 人累计休息 1 小时);不得默认使用配置文件里的值替用户决定。
36
35
 
@@ -48,8 +47,6 @@ description: "Use when users want Boss search/recruit-page screening via the uni
48
47
  - `degree`
49
48
  - `school_tag`
50
49
  - `recent_not_view`
51
- - `post_action`
52
- - `max_greet_count`
53
50
  - `port`
54
51
 
55
52
  启动工具时,把用户确认的休息强度写入 `human_behavior.restLevel`,例如:
@@ -22,7 +22,7 @@ import {
22
22
  import { waitForRecommendDetail } from "./detail.js";
23
23
  import { getRecommendRoots } from "./roots.js";
24
24
 
25
- const POST_ACTIONS = new Set(["none", "favorite", "greet"]);
25
+ const POST_ACTIONS = new Set(["none", "greet"]);
26
26
  const GREET_EXACT_LABEL_PATTERN = /^(?:打招呼|聊一聊|立即沟通(?:[\((]\d+\s*[//]\s*\d+[\))])?|沟通)$/i;
27
27
  export const RECOMMEND_DETAIL_ACTION_TEXT_SELECTORS = Object.freeze([
28
28
  "button",
@@ -94,7 +94,6 @@ function bestControl(controls, exactLabelPattern) {
94
94
  export function normalizeRecommendPostAction(value) {
95
95
  const normalized = normalizeText(value).toLowerCase();
96
96
  if (["", "none", "skip", "no", "不执行", "无"].includes(normalized)) return "none";
97
- if (["favorite", "fav", "collect", "收藏", "感兴趣"].includes(normalized)) return "favorite";
98
97
  if (["greet", "chat", "打招呼", "直接沟通", "沟通"].includes(normalized)) return "greet";
99
98
  return POST_ACTIONS.has(normalized) ? normalized : "";
100
99
  }
@@ -110,7 +109,7 @@ export function resolveRecommendPostAction({
110
109
  if (requested === "greet" && limit !== null && currentGreetCount >= limit) {
111
110
  return {
112
111
  requested,
113
- effective: "favorite",
112
+ effective: "none",
114
113
  reason: "greet_limit_reached",
115
114
  greet_count: currentGreetCount,
116
115
  max_greet_count: limit
@@ -283,22 +283,22 @@ async function runRecommendPostAction({
283
283
  reason: ""
284
284
  };
285
285
 
286
- if (!screening?.passed) {
287
- result.reason = "screening_not_passed";
288
- return result;
289
- }
290
- if (plan.effective === "none") {
291
- result.reason = "post_action_none";
292
- return result;
293
- }
294
-
295
- const summary = actionDiscovery?.summary || {};
296
- const control = plan.effective === "favorite" ? summary.favorite : summary.greet;
297
- if (!control?.found) {
298
- result.reason = `${plan.effective}_control_not_found`;
299
- return result;
300
- }
301
- result.control = control;
286
+ if (!screening?.passed) {
287
+ result.reason = "screening_not_passed";
288
+ return result;
289
+ }
290
+ if (plan.effective === "none") {
291
+ result.reason = plan.reason === "greet_limit_reached" ? "greet_limit_reached" : "post_action_none";
292
+ return result;
293
+ }
294
+
295
+ const summary = actionDiscovery?.summary || {};
296
+ const control = summary.greet;
297
+ if (!control?.found) {
298
+ result.reason = `${plan.effective}_control_not_found`;
299
+ return result;
300
+ }
301
+ result.control = control;
302
302
 
303
303
  if (plan.effective === "greet" && control.continue_chat) {
304
304
  result.reason = "already_connected_continue_chat";
@@ -315,15 +315,10 @@ async function runRecommendPostAction({
315
315
  result.reason = "greet_control_not_available";
316
316
  return result;
317
317
  }
318
- if (plan.effective === "favorite" && control.active) {
319
- result.reason = "already_favorited";
320
- result.already_favorited = true;
321
- return result;
322
- }
323
- if (control.disabled) {
324
- result.reason = `${plan.effective}_control_disabled`;
325
- return result;
326
- }
318
+ if (control.disabled) {
319
+ result.reason = `${plan.effective}_control_disabled`;
320
+ return result;
321
+ }
327
322
  if (!executePostAction) {
328
323
  result.reason = "dry_run_post_action";
329
324
  result.would_click = true;
@@ -358,23 +353,18 @@ async function runRecommendPostAction({
358
353
  timeoutMs: 2500,
359
354
  intervalMs: 300,
360
355
  requireAny: false
361
- });
362
- const afterSummary = afterDiscovery?.summary || {};
363
- const afterControl = plan.effective === "favorite" ? afterSummary.favorite : afterSummary.greet;
364
- result.action_discovery_after = compactActionDiscovery(afterDiscovery);
365
- result.control_after = afterControl || null;
366
- if (plan.effective === "greet") {
367
- result.verified_after_click = Boolean(
368
- afterControl?.continue_chat
369
- || String(afterControl?.label || "").includes("继续沟通")
370
- );
371
- } else if (plan.effective === "favorite") {
372
- result.verified_after_click = Boolean(
373
- afterControl?.active
374
- || String(afterControl?.label || "").includes("已")
375
- );
376
- }
377
- } catch (error) {
356
+ });
357
+ const afterSummary = afterDiscovery?.summary || {};
358
+ const afterControl = afterSummary.greet;
359
+ result.action_discovery_after = compactActionDiscovery(afterDiscovery);
360
+ result.control_after = afterControl || null;
361
+ if (plan.effective === "greet") {
362
+ result.verified_after_click = Boolean(
363
+ afterControl?.continue_chat
364
+ || String(afterControl?.label || "").includes("继续沟通")
365
+ );
366
+ }
367
+ } catch (error) {
378
368
  result.verify_error = {
379
369
  message: error?.message || String(error)
380
370
  };
package/src/index.js CHANGED
@@ -581,13 +581,13 @@ function createRunInputSchema() {
581
581
  minimum: 1
582
582
  },
583
583
  post_action_confirmed: { type: "boolean" },
584
- post_action_value: {
585
- type: "string",
586
- enum: ["favorite", "greet", "none"]
587
- },
584
+ post_action_value: {
585
+ type: "string",
586
+ enum: ["greet", "none"]
587
+ },
588
588
  final_confirmed: {
589
589
  type: "boolean",
590
- description: "用户已确认包含岗位、筛选项、criteria、目标、动作、最大招呼数和 restLevel 的总览。"
590
+ description: "用户已确认包含岗位、筛选项、criteria、目标、动作、可选最大招呼数和 restLevel 的总览。"
591
591
  },
592
592
  job_confirmed: { type: "boolean" },
593
593
  job_value: { type: "string" },
@@ -652,10 +652,10 @@ function createRunInputSchema() {
652
652
  job: { type: "string" },
653
653
  target_count: { type: "integer", minimum: 1 },
654
654
  max_greet_count: { type: "integer", minimum: 1 },
655
- post_action: {
656
- type: "string",
657
- enum: ["favorite", "greet", "none"]
658
- }
655
+ post_action: {
656
+ type: "string",
657
+ enum: ["greet", "none"]
658
+ }
659
659
  },
660
660
  additionalProperties: false
661
661
  },
@@ -781,26 +781,26 @@ function createRunInputSchema() {
781
781
  },
782
782
  execute_post_action: {
783
783
  type: "boolean",
784
- description: "可选,是否实际执行通过后的 recommend 后置动作 favorite/greet;默认 true"
784
+ description: "可选,是否实际执行通过后的 recommend 后置动作 greet;默认 true"
785
785
  },
786
786
  dry_run_post_action: {
787
787
  type: "boolean",
788
- description: "可选,只验证 recommend 后置动作发现/配额/可点击路径,不实际点击 favorite/greet"
788
+ description: "可选,只验证 recommend 打招呼动作发现/配额/可点击路径,不实际点击"
789
789
  },
790
790
  action_timeout_ms: {
791
791
  type: "integer",
792
792
  minimum: 1000,
793
- description: "可选,等待详情页 favorite/greet 控件出现的超时时间"
793
+ description: "可选,等待详情页 greet 控件出现的超时时间"
794
794
  },
795
795
  action_interval_ms: {
796
796
  type: "integer",
797
797
  minimum: 100,
798
- description: "可选,轮询详情页 favorite/greet 控件的间隔"
798
+ description: "可选,轮询详情页 greet 控件的间隔"
799
799
  },
800
800
  action_after_click_delay_ms: {
801
801
  type: "integer",
802
802
  minimum: 0,
803
- description: "可选,点击 favorite/greet 后等待页面状态稳定的时间"
803
+ description: "可选,点击 greet 后等待页面状态稳定的时间"
804
804
  },
805
805
  no_filter: {
806
806
  type: "boolean",
@@ -2437,7 +2437,7 @@ async function handleRunFeaturedCalibrationTool({ workspaceRoot, args }) {
2437
2437
  calibration_resolution: getFeaturedCalibrationResolution(workspaceRoot),
2438
2438
  guidance: {
2439
2439
  current_workaround: "Use an existing favorite-calibration.json if present; get_featured_calibration_status reports whether it is usable.",
2440
- next_development_task: "Implement CDP-only featured calibration with explicit user approval for any mutating favorite/greet action."
2440
+ next_development_task: "Implement CDP-only featured calibration with explicit user approval for any calibration click."
2441
2441
  }
2442
2442
  };
2443
2443
  }
package/src/parser.js CHANGED
@@ -32,9 +32,8 @@ const FILTER_CONFIRM_OPTIONS = [
32
32
  { label: "筛选项无误,继续", value: "confirm" },
33
33
  { label: "筛选项需要调整", value: "revise" }
34
34
  ];
35
- const POST_ACTION_OPTIONS = ["favorite", "greet", "none"];
35
+ const POST_ACTION_OPTIONS = ["greet", "none"];
36
36
  const POST_ACTION_LABELS = {
37
- favorite: "收藏",
38
37
  greet: "直接沟通",
39
38
  none: "什么也不做"
40
39
  };
@@ -306,7 +305,6 @@ function normalizeRecentNotView(value) {
306
305
  function normalizePostAction(value) {
307
306
  const normalized = normalizeText(value).toLowerCase();
308
307
  if (!normalized) return null;
309
- if (["favorite", "fav", "收藏"].includes(normalized)) return "favorite";
310
308
  if (["greet", "chat", "打招呼", "直接沟通", "沟通"].includes(normalized)) return "greet";
311
309
  if (["none", "noop", "no-op", "什么也不做", "不做任何操作", "不操作", "仅筛选", "只筛选"].includes(normalized)) {
312
310
  return "none";
@@ -551,9 +549,7 @@ function resolvePostAction({ instruction, confirmation, overrides, finalConfirme
551
549
  const confirmationValue = normalizePostAction(confirmation?.post_action_value);
552
550
  const overrideValue = normalizePostAction(overrides?.post_action);
553
551
  const instructionValue =
554
- /收藏/.test(instruction) && !/取消收藏/.test(instruction)
555
- ? "favorite"
556
- : /打招呼|直接沟通|沟通/.test(instruction)
552
+ /打招呼|直接沟通|沟通/.test(instruction)
557
553
  ? "greet"
558
554
  : /什么也不做|不做任何操作|不操作|仅筛选|只筛选/.test(instruction)
559
555
  ? "none"
@@ -596,37 +592,16 @@ function resolveMaxGreetCount({ instruction, confirmation, overrides, postAction
596
592
  }
597
593
 
598
594
  const overrideValue = parsePositiveIntegerValue(overrides?.max_greet_count);
599
- const confirmed = confirmation?.max_greet_count_confirmed === true;
600
595
  const confirmationValue = parsePositiveIntegerValue(confirmation?.max_greet_count_value);
601
596
  const instructionValue = extractMaxGreetCount(instruction);
602
- const targetCountHint = (
603
- parsePositiveIntegerValue(confirmation?.target_count_value)
604
- || parsePositiveIntegerValue(overrides?.target_count)
605
- || extractTargetCount(instruction)
606
- || null
607
- );
608
597
  const proposed = confirmationValue || overrideValue || instructionValue || null;
609
- const resolved = (confirmed || finalConfirmed)
610
- ? (confirmationValue || overrideValue || instructionValue || null)
611
- : null;
612
- const suspiciousAutoFill = Boolean(
613
- !confirmed
614
- && !finalConfirmed
615
- && Number.isInteger(proposed)
616
- && proposed > 0
617
- && !Number.isInteger(instructionValue)
618
- && Number.isInteger(targetCountHint)
619
- && targetCountHint > 0
620
- && proposed === targetCountHint
621
- );
622
- const hasProposedValue = Number.isInteger(proposed) && proposed > 0;
623
- const needsConfirmation = !hasProposedValue;
598
+ const resolved = confirmationValue || overrideValue || instructionValue || null;
624
599
 
625
600
  return {
626
- max_greet_count: (confirmed || finalConfirmed) && hasProposedValue ? resolved : null,
601
+ max_greet_count: resolved,
627
602
  proposed_max_greet_count: proposed,
628
- needs_max_greet_count_confirmation: needsConfirmation,
629
- suspicious_auto_fill: suspiciousAutoFill
603
+ needs_max_greet_count_confirmation: false,
604
+ suspicious_auto_fill: false
630
605
  };
631
606
  }
632
607
 
@@ -838,7 +813,6 @@ export function parseRecommendInstruction({ instruction, confirmation, overrides
838
813
  question: "请确认本次运行对通过人选统一执行的动作。",
839
814
  value: postActionResolution.proposed_post_action,
840
815
  options: [
841
- { label: POST_ACTION_LABELS.favorite, value: "favorite" },
842
816
  { label: POST_ACTION_LABELS.greet, value: "greet" },
843
817
  { label: POST_ACTION_LABELS.none, value: "none" }
844
818
  ]
@@ -850,7 +824,7 @@ export function parseRecommendInstruction({ instruction, confirmation, overrides
850
824
  field: "max_greet_count",
851
825
  question: maxGreetCountResolution.suspicious_auto_fill
852
826
  ? "检测到最大打招呼人数可能是自动默认值,请明确确认本次最多打招呼多少位候选人(必须为正整数)。"
853
- : "本次选择直接沟通时,最多打招呼多少位候选人?达到上限后会自动改为收藏。",
827
+ : "本次选择直接沟通时,最多打招呼多少位候选人?可留空表示不单独限制打招呼人数。",
854
828
  value: maxGreetCountResolution.proposed_max_greet_count
855
829
  });
856
830
  }
@@ -1088,10 +1088,9 @@ function buildRequiredConfirmations(parsed, args = {}) {
1088
1088
  if (parsed.needs_degree_confirmation) required.push("degree");
1089
1089
  if (parsed.needs_gender_confirmation) required.push("gender");
1090
1090
  if (parsed.needs_recent_not_view_confirmation) required.push("recent_not_view");
1091
- if (parsed.needs_criteria_confirmation) required.push("criteria");
1092
- if (parsed.needs_target_count_confirmation) required.push("target_count");
1091
+ if (parsed.needs_criteria_confirmation) required.push("criteria");
1092
+ if (parsed.needs_target_count_confirmation) required.push("target_count");
1093
1093
  if (parsed.needs_post_action_confirmation) required.push("post_action");
1094
- if (parsed.needs_max_greet_count_confirmation) required.push("max_greet_count");
1095
1094
  if ((parsed.suspicious_fields || []).length) required.push("suspicious_fields");
1096
1095
 
1097
1096
  const confirmation = args.confirmation || {};