@reconcrap/boss-recommend-mcp 2.1.14 → 2.1.16

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/src/index.js CHANGED
@@ -800,11 +800,13 @@ function createRunInputSchema() {
800
800
  enum: ["不限", "男", "女"]
801
801
  },
802
802
  recent_not_view_confirmed: { type: "boolean" },
803
- recent_not_view_value: {
804
- type: "string",
805
- enum: ["不限", "近14天没有"]
806
- },
807
- criteria_confirmed: { type: "boolean" },
803
+ recent_not_view_value: {
804
+ type: "string",
805
+ enum: ["不限", "近14天没有"]
806
+ },
807
+ skip_recent_colleague_contacted_confirmed: { type: "boolean" },
808
+ skip_recent_colleague_contacted_value: { type: "boolean" },
809
+ criteria_confirmed: { type: "boolean" },
808
810
  target_count_confirmed: { type: "boolean" },
809
811
  target_count_value: {
810
812
  type: "integer",
@@ -874,11 +876,15 @@ function createRunInputSchema() {
874
876
  type: "string",
875
877
  enum: ["不限", "男", "女"]
876
878
  },
877
- recent_not_view: {
878
- type: "string",
879
- enum: ["不限", "近14天没有"]
880
- },
881
- criteria: { type: "string" },
879
+ recent_not_view: {
880
+ type: "string",
881
+ enum: ["不限", "近14天没有"]
882
+ },
883
+ skip_recent_colleague_contacted: {
884
+ type: "boolean",
885
+ description: "默认 true。推荐页跳过近14天同事沟通过的人选;搜索页使用近30天未和同事交换简历过滤。"
886
+ },
887
+ criteria: { type: "string" },
882
888
  job: { type: "string" },
883
889
  target_count: { type: "integer", minimum: 1 },
884
890
  max_greet_count: { type: "integer", minimum: 1 },
@@ -1074,7 +1080,7 @@ function createBossChatStartInputSchema({ requireFullInput = false } = {}) {
1074
1080
  },
1075
1081
  criteria: {
1076
1082
  type: "string",
1077
- description: "boss-chat 的筛选 criteria"
1083
+ description: "boss-chat 的筛选 criteria;可留空,留空时进入 collect_cv 模式:不触发 LLM 筛选,只向没有在线/附件简历的人选求简历"
1078
1084
  },
1079
1085
  greeting_text: {
1080
1086
  type: "string",
@@ -1133,8 +1139,8 @@ function createBossChatStartInputSchema({ requireFullInput = false } = {}) {
1133
1139
  },
1134
1140
  screening_mode: {
1135
1141
  type: "string",
1136
- enum: ["llm", "deterministic"],
1137
- description: "筛选引擎;默认 llmdeterministic 仅限 debug_test_mode=true"
1142
+ enum: ["llm", "deterministic", "collect_cv"],
1143
+ description: "筛选引擎;默认 llm。有 criteria 时 deterministic 仅限 debug_test_mode=true;criteria 留空时自动 collect_cv"
1138
1144
  },
1139
1145
  debug_test_mode: {
1140
1146
  type: "boolean",
@@ -1222,11 +1228,17 @@ function createBossChatStartInputSchema({ requireFullInput = false } = {}) {
1222
1228
  start_from: "unread",
1223
1229
  target_count: 20,
1224
1230
  criteria: "请筛选 20 位符合条件的人选"
1231
+ },
1232
+ {
1233
+ job: "530272634",
1234
+ start_from: "all",
1235
+ target_count: "all",
1236
+ criteria: ""
1225
1237
  }
1226
1238
  ]
1227
1239
  };
1228
1240
  if (requireFullInput) {
1229
- schema.required = ["job", "start_from", "criteria"];
1241
+ schema.required = ["job", "start_from"];
1230
1242
  schema.anyOf = [
1231
1243
  { required: ["target_count"] },
1232
1244
  { required: ["targetCount"] }
@@ -1376,7 +1388,9 @@ function createCompactRunInputSchema() {
1376
1388
  final_confirmed: {
1377
1389
  type: "boolean",
1378
1390
  description: "用户完成总确认后传 true"
1379
- }
1391
+ },
1392
+ skip_recent_colleague_contacted_confirmed: { type: "boolean" },
1393
+ skip_recent_colleague_contacted_value: { type: "boolean" }
1380
1394
  },
1381
1395
  additionalProperties: true
1382
1396
  },
@@ -1398,6 +1412,7 @@ function createCompactRunInputSchema() {
1398
1412
  },
1399
1413
  gender: { type: "string" },
1400
1414
  recent_not_view: { type: "string" },
1415
+ skip_recent_colleague_contacted: { type: "boolean" },
1401
1416
  criteria: { type: "string" },
1402
1417
  target_count: targetCountSchema,
1403
1418
  post_action: { type: "string", enum: ["greet", "none"] },
@@ -1546,7 +1561,7 @@ function createToolsSchema(toolset = getConfiguredMcpToolset()) {
1546
1561
  },
1547
1562
  {
1548
1563
  name: TOOL_BOSS_CHAT_START_RUN,
1549
- description: "异步启动一次 boss-chat/chat-only 任务。必须一次性提供 job、start_from、target_countcriteria;若用户选择扫到底/不限/全部候选人,必须字面传 target_count=\"all\"。严禁改用 start_recommend_pipeline_run。",
1564
+ description: "异步启动一次 boss-chat/chat-only 任务。必须一次性提供 job、start_from、target_countcriteria 可留空,留空时自动收集缺失简历而不触发 LLM 筛选。若用户选择扫到底/不限/全部候选人,必须字面传 target_count=\"all\"。严禁改用 start_recommend_pipeline_run。",
1550
1565
  inputSchema: createBossChatStartInputSchema({ requireFullInput: true })
1551
1566
  },
1552
1567
  {
@@ -1603,17 +1618,17 @@ function createToolsSchema(toolset = getConfiguredMcpToolset()) {
1603
1618
  },
1604
1619
  {
1605
1620
  name: TOOL_LIST_RECOMMEND_JOBS,
1606
- description: "CDP-only 读取 Boss 推荐页岗位下拉框,返回所有可用岗位完整名称,方便 recommend/推荐页 cron/一次性任务提前填写 job 参数。不会启动筛选任务。chat-only、未读、全部聊天、求简历任务严禁调用本工具,必须用 list_boss_chat_jobs 或 prepare_boss_chat_run。",
1621
+ description: "CDP-only 读取 Boss 推荐页岗位下拉框,返回所有可用岗位完整名称,方便 recommend/推荐页 cron/一次性任务提前填写 job 参数。不会启动筛选任务。chat-only、未读、全部聊天、求简历任务严禁调用本工具,必须用 list_boss_chat_jobs 或 prepare_boss_chat_run。搜索页/search/recruit、/web/chat/search 任务也严禁调用本工具,必须用 boss-recruit/run_recruit_pipeline 或 boss-recruit/start_recruit_pipeline_run。",
1607
1622
  inputSchema: createListRecommendJobsInputSchema()
1608
1623
  },
1609
1624
  {
1610
1625
  name: TOOL_RUN_RECOMMEND,
1611
- description: "立即通过原生 MCP 启动 Boss 推荐页筛选。它是 start_recommend_pipeline_run 的短别名;用户已经确认并要现在启动时,优先调用本工具,不需要先调用 prepare_recommend_pipeline_run。必须作为 MCP tool call 调用,禁止通过 terminal/shell/run_command/PowerShell/CLI/manual JSON-RPC 代替,也不要用 schedule_recommend_pipeline_run 冒充立即启动。",
1626
+ description: "立即通过原生 MCP 启动 Boss 推荐页筛选。仅用于 boss-recommend/推荐页,不用于搜索页。搜索页/search/recruit、/web/chat/search 任务必须调用 boss-recruit/run_recruit_pipeline 或 boss-recruit/start_recruit_pipeline_run。它是 start_recommend_pipeline_run 的短别名;用户已经确认并要现在启动时,优先调用本工具,不需要先调用 prepare_recommend_pipeline_run。必须作为 MCP tool call 调用,禁止通过 terminal/shell/run_command/PowerShell/CLI/manual JSON-RPC 代替,也不要用 schedule_recommend_pipeline_run 冒充立即启动。",
1612
1627
  inputSchema: runInputSchema
1613
1628
  },
1614
1629
  {
1615
1630
  name: TOOL_START_RUN,
1616
- description: "立即通过原生 MCP 异步启动 Boss 推荐页流水线(含同步门禁预检)。用户已经确认并要现在启动时,优先调用本工具或 run_recommend,不需要先调用 prepare_recommend_pipeline_run。必须作为 MCP tool call 调用,禁止通过 terminal/shell/run_command/PowerShell/CLI/manual JSON-RPC 代替,也不要用 schedule_recommend_pipeline_run 冒充立即启动。",
1631
+ description: "立即通过原生 MCP 异步启动 Boss 推荐页流水线(含同步门禁预检)。仅用于 boss-recommend/推荐页,不用于搜索页。搜索页/search/recruit、/web/chat/search 任务必须调用 boss-recruit/start_recruit_pipeline_run 或 boss-recruit/run_recruit_pipeline。用户已经确认并要现在启动时,优先调用本工具或 run_recommend,不需要先调用 prepare_recommend_pipeline_run。必须作为 MCP tool call 调用,禁止通过 terminal/shell/run_command/PowerShell/CLI/manual JSON-RPC 代替,也不要用 schedule_recommend_pipeline_run 冒充立即启动。",
1617
1632
  inputSchema: runInputSchema
1618
1633
  },
1619
1634
  {
@@ -1736,12 +1751,12 @@ function createToolsSchema(toolset = getConfiguredMcpToolset()) {
1736
1751
  },
1737
1752
  {
1738
1753
  name: TOOL_RUN_RECRUIT_PIPELINE,
1739
- description: "兼容 Boss recruit 入口:默认 asyncsync 模式会等待终态。所有浏览器动作走共享 CDP-only recruit service。",
1754
+ description: "Boss 搜索页/search/recruit 专用入口;Trae-CN split-server 下应调用 boss-recruit/run_recruit_pipeline。默认 asyncsync 模式会等待终态。必须提供搜索页岗位 job(关键词输入框旁边的岗位选择)和 keyword/search intent;不要改用 boss-recommend/run_recommend 或 boss-recommend/start_recommend_pipeline_run。所有浏览器动作走共享 CDP-only recruit service。",
1740
1755
  inputSchema: createRecruitPipelineInputSchema()
1741
1756
  },
1742
1757
  {
1743
1758
  name: TOOL_START_RECRUIT_PIPELINE_RUN,
1744
- description: "异步启动 Boss recruit 流水线;先完成参数/criteria/default 确认门禁,再连接 Chrome search 页执行。",
1759
+ description: "异步启动 Boss 搜索页/search/recruit 流水线;Trae-CN split-server 下应调用 boss-recruit/start_recruit_pipeline_run。必须提供搜索页岗位 job(关键词输入框旁边的岗位选择)和 keyword/search intent;先完成参数/criteria/default 确认门禁,再连接 Chrome search 页执行。不要改用 boss-recommend/start_recommend_pipeline_run。",
1745
1760
  inputSchema: createRecruitPipelineInputSchema()
1746
1761
  },
1747
1762
  {
@@ -1811,8 +1826,8 @@ function validateBossChatStartArgs(args) {
1811
1826
  }
1812
1827
  }
1813
1828
  if (Object.prototype.hasOwnProperty.call(args, "criteria")) {
1814
- if (typeof args.criteria !== "string" || !normalizeText(args.criteria)) {
1815
- return "criteria must be a non-empty string when provided";
1829
+ if (typeof args.criteria !== "string") {
1830
+ return "criteria must be a string when provided";
1816
1831
  }
1817
1832
  }
1818
1833
  if (
package/src/parser.js CHANGED
@@ -302,6 +302,16 @@ function normalizeRecentNotView(value) {
302
302
  return RECENT_NOT_VIEW_OPTIONS.includes(normalized) ? normalized : null;
303
303
  }
304
304
 
305
+ function normalizeBooleanOverride(value) {
306
+ if (typeof value === "boolean") return value;
307
+ if (typeof value === "number") return value !== 0;
308
+ const normalized = normalizeText(value).toLowerCase();
309
+ if (!normalized) return null;
310
+ if (["true", "yes", "y", "1", "on", "enable", "enabled", "需要", "是", "开启"].includes(normalized)) return true;
311
+ if (["false", "no", "n", "0", "off", "disable", "disabled", "不需要", "否", "关闭"].includes(normalized)) return false;
312
+ return null;
313
+ }
314
+
305
315
  function normalizePostAction(value) {
306
316
  const normalized = normalizeText(value).toLowerCase();
307
317
  if (!normalized) return null;
@@ -658,6 +668,16 @@ export function parseRecommendInstruction({ instruction, confirmation, overrides
658
668
  || ""
659
669
  );
660
670
  const pageScopeResolution = resolvePageScope({ instruction: text, confirmation, overrides, finalConfirmed });
671
+ const hasSkipRecentColleagueOverride = Object.prototype.hasOwnProperty.call(
672
+ overrides || {},
673
+ "skip_recent_colleague_contacted"
674
+ );
675
+ const confirmationSkipRecentColleagueContacted = normalizeBooleanOverride(
676
+ confirmation?.skip_recent_colleague_contacted_value
677
+ );
678
+ const skipRecentColleagueContacted = hasSkipRecentColleagueOverride
679
+ ? normalizeBooleanOverride(overrides?.skip_recent_colleague_contacted) ?? true
680
+ : confirmationSkipRecentColleagueContacted ?? true;
661
681
 
662
682
  const inferredSchoolTag = detectedSchoolTags.length > 0
663
683
  ? sortSchoolTagSelections(detectedSchoolTags)
@@ -680,7 +700,9 @@ export function parseRecommendInstruction({ instruction, confirmation, overrides
680
700
  criteria: criteriaResolution.raw || criteriaResolution.normalized || null,
681
701
  target_count: null,
682
702
  post_action: null,
683
- max_greet_count: null
703
+ max_greet_count: null,
704
+ skip_recent_colleague_contacted: skipRecentColleagueContacted,
705
+ colleague_contact_window_days: 14
684
706
  };
685
707
  const targetCountResolution = resolveTargetCount({ instruction: text, confirmation, overrides, finalConfirmed });
686
708
  screenParams.target_count = targetCountResolution.target_count;
@@ -722,6 +744,12 @@ export function parseRecommendInstruction({ instruction, confirmation, overrides
722
744
  const needs_post_action_confirmation = postActionResolution.needs_post_action_confirmation;
723
745
  const needs_max_greet_count_confirmation = maxGreetCountResolution.needs_max_greet_count_confirmation;
724
746
  const needs_page_confirmation = pageScopeResolution.needs_page_confirmation;
747
+ const needs_skip_recent_colleague_contacted_confirmation = (
748
+ !finalConfirmed
749
+ && !hasSkipRecentColleagueOverride
750
+ && confirmationSkipRecentColleagueContacted === null
751
+ && confirmation?.skip_recent_colleague_contacted_confirmed !== true
752
+ );
725
753
  const pending_questions = [];
726
754
 
727
755
  if (needs_page_confirmation) {
@@ -829,6 +857,18 @@ export function parseRecommendInstruction({ instruction, confirmation, overrides
829
857
  });
830
858
  }
831
859
 
860
+ if (needs_skip_recent_colleague_contacted_confirmation) {
861
+ pending_questions.push({
862
+ field: "skip_recent_colleague_contacted",
863
+ question: "是否跳过最近已被同事联系过的人选?推荐页会检查近14天同事沟通记录。",
864
+ value: true,
865
+ options: [
866
+ { label: "跳过(推荐)", value: true },
867
+ { label: "不跳过", value: false }
868
+ ]
869
+ });
870
+ }
871
+
832
872
  return {
833
873
  searchParams,
834
874
  screenParams,
@@ -844,6 +884,7 @@ export function parseRecommendInstruction({ instruction, confirmation, overrides
844
884
  needs_post_action_confirmation,
845
885
  needs_max_greet_count_confirmation,
846
886
  needs_page_confirmation,
887
+ needs_skip_recent_colleague_contacted_confirmation,
847
888
  criteria_normalized: criteriaResolution.normalized,
848
889
  proposed_target_count: targetCountResolution.proposed_target_count,
849
890
  proposed_post_action: postActionResolution.proposed_post_action,
@@ -860,7 +901,9 @@ export function parseRecommendInstruction({ instruction, confirmation, overrides
860
901
  criteria_normalized: criteriaResolution.normalized,
861
902
  target_count: targetCountResolution.proposed_target_count,
862
903
  post_action: postActionResolution.proposed_post_action,
863
- max_greet_count: maxGreetCountResolution.proposed_max_greet_count
904
+ max_greet_count: maxGreetCountResolution.proposed_max_greet_count,
905
+ skip_recent_colleague_contacted: screenParams.skip_recent_colleague_contacted,
906
+ colleague_contact_window_days: screenParams.colleague_contact_window_days
864
907
  },
865
908
  current_page_scope: pageScopeResolution.page_scope,
866
909
  current_search_params: searchParams,
@@ -102,7 +102,71 @@ function findRouteSignals(text, patterns = []) {
102
102
  return signals;
103
103
  }
104
104
 
105
+ function detectExplicitNonRecommendScope(args = {}) {
106
+ const fields = [
107
+ ["page_scope", args.page_scope],
108
+ ["confirmation.page_value", args.confirmation?.page_value],
109
+ ["overrides.page_scope", args.overrides?.page_scope],
110
+ ["target_url_includes", args.target_url_includes],
111
+ ["overrides.target_url_includes", args.overrides?.target_url_includes]
112
+ ];
113
+ for (const [field, value] of fields) {
114
+ const normalized = normalizeText(value).toLowerCase();
115
+ if (!normalized) continue;
116
+ if (/\/web\/chat\/index|chat\/index/.test(normalized) || ["chat", "chat-page", "boss-chat"].includes(normalized)) {
117
+ return {
118
+ domain: "chat",
119
+ signals: [`${field}:chat`],
120
+ text: normalized
121
+ };
122
+ }
123
+ if (/\/web\/chat\/search|chat\/search/.test(normalized) || ["search", "search-page", "recruit", "recruit-page", "boss-recruit"].includes(normalized)) {
124
+ return {
125
+ domain: "search",
126
+ signals: [`${field}:search`],
127
+ text: normalized
128
+ };
129
+ }
130
+ }
131
+ return null;
132
+ }
133
+
134
+ function detectRecruitShapedRecommendArgs(args = {}) {
135
+ const checks = [
136
+ ["keyword", args.keyword],
137
+ ["search_keyword", args.search_keyword],
138
+ ["city", args.city],
139
+ ["confirmation.keyword_value", args.confirmation?.keyword_value],
140
+ ["confirmation.keyword_confirmed", args.confirmation?.keyword_confirmed],
141
+ ["confirmation.search_params_confirmed", args.confirmation?.search_params_confirmed],
142
+ ["overrides.keyword", args.overrides?.keyword],
143
+ ["overrides.search_keyword", args.overrides?.search_keyword],
144
+ ["overrides.city", args.overrides?.city],
145
+ ["overrides.filter_recent_viewed", args.overrides?.filter_recent_viewed],
146
+ ["overrides.schools", args.overrides?.schools],
147
+ ["overrides.school_tags", args.overrides?.school_tags]
148
+ ];
149
+ const signals = [];
150
+ for (const [field, value] of checks) {
151
+ if (value === undefined || value === null) continue;
152
+ if (Array.isArray(value) && value.length === 0) continue;
153
+ if (typeof value === "string" && !normalizeText(value)) continue;
154
+ signals.push(field);
155
+ }
156
+ if (!signals.length) return null;
157
+ return {
158
+ domain: "search",
159
+ signals: signals.map((field) => `${field}:recruit_arg`),
160
+ text: signals.join(" ")
161
+ };
162
+ }
163
+
105
164
  function detectNonRecommendRoute(args = {}) {
165
+ const explicitRoute = detectExplicitNonRecommendScope(args);
166
+ if (explicitRoute) return explicitRoute;
167
+ const recruitArgRoute = detectRecruitShapedRecommendArgs(args);
168
+ if (recruitArgRoute) return recruitArgRoute;
169
+
106
170
  const text = collectRecommendRouteText(args);
107
171
  if (!text) return null;
108
172
  const chatSignals = findRouteSignals(text, [
@@ -126,6 +190,7 @@ function detectNonRecommendRoute(args = {}) {
126
190
  const searchSignals = findRouteSignals(text, [
127
191
  { label: "search-only", pattern: /\bsearch[-\s]?only\b/i },
128
192
  { label: "search page", pattern: /\bsearch\s+page\b/i },
193
+ { label: "search keyword", pattern: /搜索关键词|关键词|keyword/i },
129
194
  { label: "recruit pipeline", pattern: /\brecruit\s+pipeline\b/i },
130
195
  { label: "chat/search", pattern: /(?:\/web\/chat\/search|chat\/search)/i },
131
196
  { label: "搜索页", pattern: /搜索页/ },
@@ -148,16 +213,18 @@ function buildWrongRecommendRouteResponse(route) {
148
213
  route_guard: true,
149
214
  error: {
150
215
  code: "WRONG_BOSS_TOOL_FOR_CHAT",
151
- message: "This request is explicitly chat-only/chat-page work. Do not use recommend tools. Use boss_chat_health_check, then list_boss_chat_jobs or prepare_boss_chat_run, then start_boss_chat_run.",
216
+ message: "This request is explicitly chat-only/chat-page work. In Trae-CN split toolsets, call boss-chat/boss_chat_health_check, then boss-chat/list_boss_chat_jobs or boss-chat/prepare_boss_chat_run, then boss-chat/start_boss_chat_run. Do not call boss-recommend tools.",
152
217
  retryable: false
153
218
  },
154
219
  detected_domain: "chat",
155
220
  detected_signals: route.signals || [],
221
+ wrong_server: "boss-recommend",
222
+ recommended_server: "boss-chat",
156
223
  recommended_tool_sequence: [
157
- "boss_chat_health_check",
158
- "list_boss_chat_jobs",
159
- "prepare_boss_chat_run",
160
- "start_boss_chat_run"
224
+ "boss-chat/boss_chat_health_check",
225
+ "boss-chat/list_boss_chat_jobs",
226
+ "boss-chat/prepare_boss_chat_run",
227
+ "boss-chat/start_boss_chat_run"
161
228
  ]
162
229
  };
163
230
  }
@@ -167,14 +234,16 @@ function buildWrongRecommendRouteResponse(route) {
167
234
  route_guard: true,
168
235
  error: {
169
236
  code: "WRONG_BOSS_TOOL_FOR_SEARCH",
170
- message: "This request is explicitly search/recruit-page work. Do not use recommend tools. Use run_recruit_pipeline or start_recruit_pipeline_run.",
237
+ message: "This request is explicitly search/recruit-page work. In Trae-CN split toolsets, call boss-recruit/run_recruit_pipeline or boss-recruit/start_recruit_pipeline_run. Do not call boss-recommend/run_recommend or boss-recommend/start_recommend_pipeline_run.",
171
238
  retryable: false
172
239
  },
173
240
  detected_domain: "search",
174
241
  detected_signals: route.signals || [],
242
+ wrong_server: "boss-recommend",
243
+ recommended_server: "boss-recruit",
175
244
  recommended_tool_sequence: [
176
- "run_recruit_pipeline",
177
- "start_recruit_pipeline_run"
245
+ "boss-recruit/run_recruit_pipeline",
246
+ "boss-recruit/start_recruit_pipeline_run"
178
247
  ]
179
248
  };
180
249
  }
@@ -1315,6 +1384,7 @@ function buildRequiredConfirmations(parsed, args = {}) {
1315
1384
  if (parsed.needs_criteria_confirmation) required.push("criteria");
1316
1385
  if (parsed.needs_target_count_confirmation) required.push("target_count");
1317
1386
  if (parsed.needs_post_action_confirmation) required.push("post_action");
1387
+ if (parsed.needs_skip_recent_colleague_contacted_confirmation) required.push("skip_recent_colleague_contacted");
1318
1388
  if ((parsed.suspicious_fields || []).length) required.push("suspicious_fields");
1319
1389
 
1320
1390
  const confirmation = args.confirmation || {};
@@ -1522,14 +1592,16 @@ function normalizeRecommendStartInput(args = {}, parsed, configResolution = null
1522
1592
  targetCount,
1523
1593
  job: normalizeText(confirmation.job_value || overrides.job || ""),
1524
1594
  pageScope: parsed.page_scope || "recommend",
1525
- filter: buildRecommendFilter(parsed, args),
1526
- postAction: parsed.screenParams?.post_action || "none",
1527
- maxGreetCount: Number.isInteger(parsed.screenParams?.max_greet_count)
1528
- ? parsed.screenParams.max_greet_count
1529
- : null,
1530
- screeningMode: normalizeScreeningModeArg(args)
1531
- };
1532
- }
1595
+ filter: buildRecommendFilter(parsed, args),
1596
+ postAction: parsed.screenParams?.post_action || "none",
1597
+ maxGreetCount: Number.isInteger(parsed.screenParams?.max_greet_count)
1598
+ ? parsed.screenParams.max_greet_count
1599
+ : null,
1600
+ skipRecentColleagueContacted: parsed.screenParams?.skip_recent_colleague_contacted !== false,
1601
+ colleagueContactWindowDays: 14,
1602
+ screeningMode: normalizeScreeningModeArg(args)
1603
+ };
1604
+ }
1533
1605
 
1534
1606
  function getRunOptions(args, parsed, normalized, session, configResolution = null) {
1535
1607
  const slowLive = args.slow_live === true;
@@ -1567,8 +1639,8 @@ function getRunOptions(args, parsed, normalized, session, configResolution = nul
1567
1639
  executePostAction,
1568
1640
  actionTimeoutMs: parsePositiveInteger(args.action_timeout_ms, slowLive ? 12000 : 8000),
1569
1641
  actionIntervalMs: parsePositiveInteger(args.action_interval_ms, 500),
1570
- actionAfterClickDelayMs: parseNonNegativeInteger(args.action_after_click_delay_ms, slowLive ? 1200 : 900),
1571
- screeningMode: normalized.screeningMode,
1642
+ actionAfterClickDelayMs: parseNonNegativeInteger(args.action_after_click_delay_ms, slowLive ? 1200 : 900),
1643
+ screeningMode: normalized.screeningMode,
1572
1644
  llmConfig: normalized.screeningMode === "llm" && configResolution?.ok ? {
1573
1645
  ...configResolution.config
1574
1646
  } : null,
@@ -1586,6 +1658,8 @@ function getRunOptions(args, parsed, normalized, session, configResolution = nul
1586
1658
  imageOutputDir: resolveBossConfiguredOutputDir("", getRunsDir()),
1587
1659
  humanRestEnabled: humanBehavior.restEnabled,
1588
1660
  humanBehavior,
1661
+ skipRecentColleagueContacted: normalized.skipRecentColleagueContacted,
1662
+ colleagueContactWindowDays: normalized.colleagueContactWindowDays,
1589
1663
  name: "mcp-recommend-pipeline-run",
1590
1664
  parsed
1591
1665
  };