@reconcrap/boss-recommend-mcp 2.0.14 → 2.0.15
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/package.json +1 -1
- package/src/domains/chat/run-service.js +176 -40
package/package.json
CHANGED
|
@@ -203,6 +203,115 @@ function createSkippedDetailResult(cardCandidate, reason, error = null) {
|
|
|
203
203
|
};
|
|
204
204
|
}
|
|
205
205
|
|
|
206
|
+
const CHAT_FULL_CV_DOM_MIN_TEXT_LENGTH = 500;
|
|
207
|
+
const CHAT_FULL_CV_DOM_MIN_SECTION_TEXT_LENGTH = 180;
|
|
208
|
+
const CHAT_FULL_CV_SECTION_PATTERNS = Object.freeze([
|
|
209
|
+
/教育(?:经历|背景|经验)?/i,
|
|
210
|
+
/工作(?:经历|经验)?/i,
|
|
211
|
+
/项目(?:经历|经验)?/i,
|
|
212
|
+
/实习(?:经历|经验)?/i,
|
|
213
|
+
/科研(?:经历|经验)?/i,
|
|
214
|
+
/论文|会议|专利/i,
|
|
215
|
+
/个人(?:优势|总结|介绍|评价)/i,
|
|
216
|
+
/专业技能|技能(?:特长|标签)?/i,
|
|
217
|
+
/求职(?:期望|意向)/i,
|
|
218
|
+
/校园经历|在校经历|竞赛|证书/i
|
|
219
|
+
]);
|
|
220
|
+
|
|
221
|
+
function detailTextForFullCvCheck(detailResult = {}) {
|
|
222
|
+
return [
|
|
223
|
+
detailResult?.detail?.popup_text,
|
|
224
|
+
detailResult?.detail?.content_text,
|
|
225
|
+
detailResult?.detail?.resume_iframe_text
|
|
226
|
+
].filter(Boolean).join("\n\n");
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function resumeSectionMatchCount(text = "") {
|
|
230
|
+
const normalized = normalizeText(text);
|
|
231
|
+
if (!normalized) return 0;
|
|
232
|
+
return CHAT_FULL_CV_SECTION_PATTERNS
|
|
233
|
+
.filter((pattern) => pattern.test(normalized))
|
|
234
|
+
.length;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
function hasResumeLikeDomText(text = "") {
|
|
238
|
+
const normalized = normalizeText(text);
|
|
239
|
+
if (normalized.length >= CHAT_FULL_CV_DOM_MIN_TEXT_LENGTH) return true;
|
|
240
|
+
return normalized.length >= CHAT_FULL_CV_DOM_MIN_SECTION_TEXT_LENGTH
|
|
241
|
+
&& resumeSectionMatchCount(normalized) >= 2;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
function networkProfileTextLength(profileResult = {}) {
|
|
245
|
+
return normalizeText(profileResult?.profile?.text || "").length;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
function isFullCvNetworkProfile(profileResult = {}) {
|
|
249
|
+
if (!profileResult?.ok) return false;
|
|
250
|
+
const sourceKeys = profileResult.profile?.source_keys || {};
|
|
251
|
+
const textLength = networkProfileTextLength(profileResult);
|
|
252
|
+
const sectionCount = resumeSectionMatchCount(profileResult.profile?.text || "");
|
|
253
|
+
|
|
254
|
+
if (sourceKeys.geek_detail_info || sourceKeys.geek_detail) return true;
|
|
255
|
+
if (sourceKeys.network_html_text) {
|
|
256
|
+
return textLength >= CHAT_FULL_CV_DOM_MIN_TEXT_LENGTH
|
|
257
|
+
|| sectionCount >= 2;
|
|
258
|
+
}
|
|
259
|
+
if (sourceKeys.chat_history_resume) {
|
|
260
|
+
const educationCount = Number(sourceKeys.education_count) || 0;
|
|
261
|
+
const workCount = Number(sourceKeys.work_count) || 0;
|
|
262
|
+
return (educationCount + workCount) > 0
|
|
263
|
+
&& (textLength >= CHAT_FULL_CV_DOM_MIN_SECTION_TEXT_LENGTH || sectionCount >= 2);
|
|
264
|
+
}
|
|
265
|
+
return false;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
function hasUsableImageEvidence(imageEvidence = null) {
|
|
269
|
+
if (!imageEvidence || imageEvidence.ok === false) return false;
|
|
270
|
+
return Boolean(
|
|
271
|
+
(Array.isArray(imageEvidence.llm_file_paths) && imageEvidence.llm_file_paths.length)
|
|
272
|
+
|| (Array.isArray(imageEvidence.file_paths) && imageEvidence.file_paths.length)
|
|
273
|
+
|| Number(imageEvidence.llm_screenshot_count) > 0
|
|
274
|
+
|| Number(imageEvidence.unique_screenshot_count) > 0
|
|
275
|
+
|| Number(imageEvidence.screenshot_count) > 0
|
|
276
|
+
|| Number(imageEvidence.capture_count) > 0
|
|
277
|
+
);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
export function summarizeChatFullCvEvidence({
|
|
281
|
+
detailResult = null,
|
|
282
|
+
contentWait = null,
|
|
283
|
+
imageEvidence = null
|
|
284
|
+
} = {}) {
|
|
285
|
+
const parsedProfiles = (detailResult?.parsed_network_profiles || []).filter((item) => item?.ok);
|
|
286
|
+
const fullNetworkProfiles = parsedProfiles.filter(isFullCvNetworkProfile);
|
|
287
|
+
const profileOnlyCount = Math.max(0, parsedProfiles.length - fullNetworkProfiles.length);
|
|
288
|
+
const detailText = detailTextForFullCvCheck(detailResult);
|
|
289
|
+
const domTextLength = detailText.length;
|
|
290
|
+
const domSectionCount = resumeSectionMatchCount(detailText);
|
|
291
|
+
const domFullCv = Boolean(contentWait?.ok) && hasResumeLikeDomText(detailText);
|
|
292
|
+
const imageFullCv = hasUsableImageEvidence(imageEvidence);
|
|
293
|
+
const source = fullNetworkProfiles.length
|
|
294
|
+
? "network"
|
|
295
|
+
: domFullCv
|
|
296
|
+
? "dom"
|
|
297
|
+
: imageFullCv
|
|
298
|
+
? "image"
|
|
299
|
+
: null;
|
|
300
|
+
return {
|
|
301
|
+
full_cv_acquired: Boolean(source),
|
|
302
|
+
source,
|
|
303
|
+
network_full_cv_count: fullNetworkProfiles.length,
|
|
304
|
+
network_profile_only_count: profileOnlyCount,
|
|
305
|
+
parsed_network_profile_count: parsedProfiles.length,
|
|
306
|
+
dom_full_cv: domFullCv,
|
|
307
|
+
dom_text_length: domTextLength,
|
|
308
|
+
dom_section_count: domSectionCount,
|
|
309
|
+
content_wait_ok: Boolean(contentWait?.ok),
|
|
310
|
+
image_full_cv: imageFullCv,
|
|
311
|
+
image_summary: summarizeImageEvidence(imageEvidence)
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
|
|
206
315
|
async function resolveFreshChatCardNodeId(client, {
|
|
207
316
|
fallbackNodeId,
|
|
208
317
|
candidate,
|
|
@@ -773,11 +882,12 @@ export async function runChatWorkflow({
|
|
|
773
882
|
});
|
|
774
883
|
addTiming(timings, "late_network_retry_ms", detailResult.network_parse_retry_elapsed_ms);
|
|
775
884
|
parsedNetworkProfileCount = countParsedNetworkProfiles(detailResult);
|
|
776
|
-
|
|
885
|
+
const networkEvidence = summarizeChatFullCvEvidence({ detailResult, contentWait });
|
|
886
|
+
if (networkEvidence.network_full_cv_count > 0) {
|
|
777
887
|
contentWait = {
|
|
778
888
|
ok: true,
|
|
779
889
|
skipped: true,
|
|
780
|
-
reason: "
|
|
890
|
+
reason: "network_full_cv_parsed_before_dom_wait",
|
|
781
891
|
elapsed_ms: 0,
|
|
782
892
|
text_length: 0
|
|
783
893
|
};
|
|
@@ -819,8 +929,9 @@ export async function runChatWorkflow({
|
|
|
819
929
|
let imageEvidence = null;
|
|
820
930
|
let llmResult = null;
|
|
821
931
|
const captureNodeId = captureNodeIdFromResumeState(resumeState);
|
|
932
|
+
let fullCvEvidence = summarizeChatFullCvEvidence({ detailResult, contentWait });
|
|
822
933
|
const shouldCaptureImage = normalizedDetailSource === "image"
|
|
823
|
-
|| (normalizedDetailSource === "cascade" &&
|
|
934
|
+
|| (normalizedDetailSource === "cascade" && !fullCvEvidence.full_cv_acquired);
|
|
824
935
|
if (shouldCaptureImage) {
|
|
825
936
|
if (captureNodeId) {
|
|
826
937
|
detailStep = "capture_image_fallback";
|
|
@@ -861,12 +972,20 @@ export async function runChatWorkflow({
|
|
|
861
972
|
}
|
|
862
973
|
}));
|
|
863
974
|
source = "image";
|
|
975
|
+
fullCvEvidence = summarizeChatFullCvEvidence({
|
|
976
|
+
detailResult,
|
|
977
|
+
contentWait,
|
|
978
|
+
imageEvidence
|
|
979
|
+
});
|
|
864
980
|
recordCvImageFallback(cvAcquisitionState, {
|
|
981
|
+
reason: fullCvEvidence.network_profile_only_count > 0
|
|
982
|
+
? "profile_only_network_image_fallback"
|
|
983
|
+
: "network_miss_image_fallback",
|
|
865
984
|
parsedNetworkProfileCount,
|
|
866
985
|
waitResult: networkWait,
|
|
867
986
|
imageEvidence
|
|
868
987
|
});
|
|
869
|
-
if (callLlmOnImage) {
|
|
988
|
+
if (callLlmOnImage && fullCvEvidence.full_cv_acquired) {
|
|
870
989
|
detailStep = "llm_image_screening";
|
|
871
990
|
if (!llmConfig) {
|
|
872
991
|
llmResult = createMissingLlmConfigResult();
|
|
@@ -888,14 +1007,39 @@ export async function runChatWorkflow({
|
|
|
888
1007
|
}
|
|
889
1008
|
} else {
|
|
890
1009
|
source = "missing_capture_node";
|
|
1010
|
+
fullCvEvidence = summarizeChatFullCvEvidence({
|
|
1011
|
+
detailResult,
|
|
1012
|
+
contentWait,
|
|
1013
|
+
imageEvidence
|
|
1014
|
+
});
|
|
891
1015
|
recordCvNetworkMiss(cvAcquisitionState, {
|
|
892
1016
|
reason: "network_miss_no_capture_node",
|
|
893
1017
|
parsedNetworkProfileCount,
|
|
894
1018
|
waitResult: networkWait
|
|
895
1019
|
});
|
|
896
1020
|
}
|
|
897
|
-
} else if (
|
|
1021
|
+
} else if (fullCvEvidence.network_full_cv_count > 0) {
|
|
1022
|
+
source = "network";
|
|
898
1023
|
recordCvNetworkHit(cvAcquisitionState, {
|
|
1024
|
+
reason: "full_cv_network_profile",
|
|
1025
|
+
parsedNetworkProfileCount,
|
|
1026
|
+
waitResult: networkWait
|
|
1027
|
+
});
|
|
1028
|
+
} else if (fullCvEvidence.dom_full_cv) {
|
|
1029
|
+
source = "dom";
|
|
1030
|
+
if (normalizedDetailSource !== "dom") {
|
|
1031
|
+
recordCvNetworkMiss(cvAcquisitionState, {
|
|
1032
|
+
reason: parsedNetworkProfileCount > 0
|
|
1033
|
+
? "profile_only_network_dom_fallback"
|
|
1034
|
+
: "network_miss_dom_fallback",
|
|
1035
|
+
parsedNetworkProfileCount,
|
|
1036
|
+
waitResult: networkWait
|
|
1037
|
+
});
|
|
1038
|
+
}
|
|
1039
|
+
} else if (parsedNetworkProfileCount > 0) {
|
|
1040
|
+
source = "profile_only_network";
|
|
1041
|
+
recordCvNetworkMiss(cvAcquisitionState, {
|
|
1042
|
+
reason: "profile_only_network_not_full_cv",
|
|
899
1043
|
parsedNetworkProfileCount,
|
|
900
1044
|
waitResult: networkWait
|
|
901
1045
|
});
|
|
@@ -909,25 +1053,29 @@ export async function runChatWorkflow({
|
|
|
909
1053
|
}
|
|
910
1054
|
|
|
911
1055
|
if (useLlmScreening && !llmResult) {
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
llmResult = createMissingLlmConfigResult();
|
|
1056
|
+
if (!fullCvEvidence.full_cv_acquired) {
|
|
1057
|
+
detailUnavailableReason = "full_cv_not_acquired";
|
|
915
1058
|
} else {
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
1059
|
+
detailStep = "llm_screening";
|
|
1060
|
+
if (!llmConfig) {
|
|
1061
|
+
llmResult = createMissingLlmConfigResult();
|
|
1062
|
+
} else {
|
|
1063
|
+
try {
|
|
1064
|
+
const llmTimingKey = imageEvidence?.file_paths?.length
|
|
1065
|
+
? "vision_model_ms"
|
|
1066
|
+
: "text_model_ms";
|
|
1067
|
+
llmResult = await measureTiming(timings, llmTimingKey, () => callScreeningLlm({
|
|
1068
|
+
candidate: detailResult.candidate,
|
|
1069
|
+
criteria,
|
|
1070
|
+
config: llmConfig,
|
|
1071
|
+
timeoutMs: llmTimeoutMs,
|
|
1072
|
+
imageEvidence,
|
|
1073
|
+
maxImages: llmImageLimit,
|
|
1074
|
+
imageDetail: llmImageDetail
|
|
1075
|
+
}));
|
|
1076
|
+
} catch (error) {
|
|
1077
|
+
llmResult = createFailedLlmResult(error);
|
|
1078
|
+
}
|
|
931
1079
|
}
|
|
932
1080
|
}
|
|
933
1081
|
}
|
|
@@ -955,7 +1103,8 @@ export async function runChatWorkflow({
|
|
|
955
1103
|
text_length: contentWait.text_length
|
|
956
1104
|
},
|
|
957
1105
|
parsed_network_profile_count: parsedNetworkProfileCount,
|
|
958
|
-
image_evidence: summarizeImageEvidence(imageEvidence)
|
|
1106
|
+
image_evidence: summarizeImageEvidence(imageEvidence),
|
|
1107
|
+
full_cv_evidence: fullCvEvidence
|
|
959
1108
|
};
|
|
960
1109
|
}
|
|
961
1110
|
} catch (error) {
|
|
@@ -979,22 +1128,9 @@ export async function runChatWorkflow({
|
|
|
979
1128
|
runControl.setPhase("chat:screening");
|
|
980
1129
|
let cardOnlyLlmResult = null;
|
|
981
1130
|
if (useLlmScreening && !detailUnavailableReason && !detailResult?.llm_result) {
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
try {
|
|
986
|
-
cardOnlyLlmResult = await measureTiming(timings, "text_model_ms", () => callScreeningLlm({
|
|
987
|
-
candidate: screeningCandidate,
|
|
988
|
-
criteria,
|
|
989
|
-
config: llmConfig,
|
|
990
|
-
timeoutMs: llmTimeoutMs,
|
|
991
|
-
maxImages: llmImageLimit,
|
|
992
|
-
imageDetail: llmImageDetail
|
|
993
|
-
}));
|
|
994
|
-
} catch (error) {
|
|
995
|
-
cardOnlyLlmResult = createFailedLlmResult(error);
|
|
996
|
-
}
|
|
997
|
-
}
|
|
1131
|
+
detailUnavailableReason = detailResult
|
|
1132
|
+
? "full_cv_not_acquired"
|
|
1133
|
+
: "detail_not_opened_full_cv_required";
|
|
998
1134
|
}
|
|
999
1135
|
const effectiveLlmResult = detailResult?.llm_result || cardOnlyLlmResult;
|
|
1000
1136
|
const screening = detailUnavailableReason
|