@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/README.md +34 -5
- package/package.json +8 -7
- package/skills/boss-chat/README.md +2 -2
- package/skills/boss-chat/SKILL.md +7 -7
- package/skills/boss-recruit-pipeline/SKILL.md +23 -1
- package/src/chat-mcp.js +127 -88
- package/src/core/greet-quota/index.js +17 -0
- package/src/core/reporting/legacy-csv.js +5 -1
- package/src/domains/chat/detail.js +79 -47
- package/src/domains/chat/run-service.js +400 -158
- package/src/domains/recommend/colleague-contact.js +333 -0
- package/src/domains/recommend/index.js +1 -0
- package/src/domains/recommend/run-service.js +166 -77
- package/src/domains/recruit/constants.js +69 -0
- package/src/domains/recruit/instruction-parser.js +403 -86
- package/src/domains/recruit/run-service.js +320 -11
- package/src/domains/recruit/search.js +2118 -306
- package/src/index.js +38 -23
- package/src/parser.js +45 -2
- package/src/recommend-mcp.js +92 -18
- package/src/recruit-mcp.js +236 -3
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
|
-
|
|
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
|
-
|
|
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: "筛选引擎;默认 llm
|
|
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"
|
|
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_count
|
|
1564
|
+
description: "异步启动一次 boss-chat/chat-only 任务。必须一次性提供 job、start_from、target_count;criteria 可留空,留空时自动收集缺失简历而不触发 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
|
|
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
|
|
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: "
|
|
1754
|
+
description: "Boss 搜索页/search/recruit 专用入口;Trae-CN split-server 下应调用 boss-recruit/run_recruit_pipeline。默认 async,sync 模式会等待终态。必须提供搜索页岗位 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
|
|
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"
|
|
1815
|
-
return "criteria must be a
|
|
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,
|
package/src/recommend-mcp.js
CHANGED
|
@@ -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.
|
|
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.
|
|
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
|
-
|
|
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
|
};
|