@reconcrap/boss-recommend-mcp 2.0.45 → 2.0.47
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/bin/boss-recommend-mcp.js +4 -4
- package/config/screening-config.example.json +27 -27
- package/package.json +1 -1
- package/scripts/postinstall.cjs +44 -44
- package/skills/boss-chat/README.md +39 -39
- package/skills/boss-chat/SKILL.md +93 -93
- package/skills/boss-recommend-pipeline/README.md +12 -12
- package/skills/boss-recommend-pipeline/SKILL.md +180 -180
- package/skills/boss-recruit-pipeline/README.md +17 -17
- package/skills/boss-recruit-pipeline/SKILL.md +58 -58
- package/src/chat-mcp.js +1780 -1780
- package/src/chat-runtime-config.js +749 -749
- package/src/cli.js +3054 -3054
- package/src/core/boss-cards/index.js +199 -199
- package/src/core/browser/index.js +1453 -1446
- package/src/core/capture/index.js +1201 -1201
- package/src/core/cv-acquisition/index.js +238 -238
- package/src/core/cv-capture-target/index.js +299 -299
- package/src/core/greet-quota/index.js +54 -54
- package/src/core/infinite-list/index.js +1326 -1326
- package/src/core/reporting/legacy-csv.js +341 -341
- package/src/core/run/timing.js +33 -33
- package/src/core/screening/index.js +50 -3
- package/src/core/self-heal/index.js +973 -973
- package/src/core/self-heal/viewport.js +564 -564
- package/src/domains/chat/cards.js +137 -137
- package/src/domains/chat/constants.js +221 -221
- package/src/domains/chat/detail.js +1668 -1661
- package/src/domains/chat/index.js +7 -7
- package/src/domains/chat/jobs.js +592 -588
- package/src/domains/chat/page-guard.js +98 -98
- package/src/domains/chat/roots.js +56 -56
- package/src/domains/chat/run-service.js +1977 -1955
- package/src/domains/recommend/actions.js +457 -457
- package/src/domains/recommend/cards.js +243 -243
- package/src/domains/recommend/constants.js +165 -165
- package/src/domains/recommend/detail.js +36 -28
- package/src/domains/recommend/filters.js +610 -581
- package/src/domains/recommend/index.js +10 -10
- package/src/domains/recommend/jobs.js +316 -263
- package/src/domains/recommend/refresh.js +472 -472
- package/src/domains/recommend/roots.js +80 -80
- package/src/domains/recommend/run-service.js +75 -35
- package/src/domains/recommend/scopes.js +246 -245
- package/src/domains/recruit/actions.js +277 -277
- package/src/domains/recruit/cards.js +74 -74
- package/src/domains/recruit/constants.js +167 -167
- package/src/domains/recruit/detail.js +461 -460
- package/src/domains/recruit/index.js +9 -9
- package/src/domains/recruit/instruction-parser.js +451 -451
- package/src/domains/recruit/refresh.js +44 -44
- package/src/domains/recruit/roots.js +68 -68
- package/src/domains/recruit/run-service.js +1207 -1161
- package/src/domains/recruit/search.js +1202 -1149
- package/src/recommend-mcp.js +22 -22
- package/src/recruit-mcp.js +1338 -1338
package/src/core/run/timing.js
CHANGED
|
@@ -1,33 +1,33 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
|
-
|
|
3
|
-
export function addTiming(timings, key, value) {
|
|
4
|
-
if (!timings || !key) return;
|
|
5
|
-
const numeric = Number(value);
|
|
6
|
-
if (!Number.isFinite(numeric) || numeric < 0) return;
|
|
7
|
-
timings[key] = (Number(timings[key]) || 0) + Math.round(numeric);
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export async function measureTiming(timings, key, task) {
|
|
11
|
-
const started = Date.now();
|
|
12
|
-
try {
|
|
13
|
-
return await task();
|
|
14
|
-
} finally {
|
|
15
|
-
addTiming(timings, key, Date.now() - started);
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export function imageEvidenceFilePath({
|
|
20
|
-
imageOutputDir = "",
|
|
21
|
-
domain = "candidate",
|
|
22
|
-
runId = "",
|
|
23
|
-
index = 0,
|
|
24
|
-
extension = "png"
|
|
25
|
-
} = {}) {
|
|
26
|
-
const dir = String(imageOutputDir || "").trim();
|
|
27
|
-
if (!dir) return "";
|
|
28
|
-
const safeDomain = String(domain || "candidate").replace(/[^\w.-]+/g, "_");
|
|
29
|
-
const safeRunId = String(runId || `${safeDomain}-run`).replace(/[^\w.-]+/g, "_");
|
|
30
|
-
const safeIndex = String((Number(index) || 0) + 1).padStart(3, "0");
|
|
31
|
-
const safeExt = String(extension || "png").replace(/^\./, "") || "png";
|
|
32
|
-
return path.join(dir, safeRunId, `${safeDomain}-candidate-${safeIndex}.${safeExt}`);
|
|
33
|
-
}
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
|
|
3
|
+
export function addTiming(timings, key, value) {
|
|
4
|
+
if (!timings || !key) return;
|
|
5
|
+
const numeric = Number(value);
|
|
6
|
+
if (!Number.isFinite(numeric) || numeric < 0) return;
|
|
7
|
+
timings[key] = (Number(timings[key]) || 0) + Math.round(numeric);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export async function measureTiming(timings, key, task) {
|
|
11
|
+
const started = Date.now();
|
|
12
|
+
try {
|
|
13
|
+
return await task();
|
|
14
|
+
} finally {
|
|
15
|
+
addTiming(timings, key, Date.now() - started);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function imageEvidenceFilePath({
|
|
20
|
+
imageOutputDir = "",
|
|
21
|
+
domain = "candidate",
|
|
22
|
+
runId = "",
|
|
23
|
+
index = 0,
|
|
24
|
+
extension = "png"
|
|
25
|
+
} = {}) {
|
|
26
|
+
const dir = String(imageOutputDir || "").trim();
|
|
27
|
+
if (!dir) return "";
|
|
28
|
+
const safeDomain = String(domain || "candidate").replace(/[^\w.-]+/g, "_");
|
|
29
|
+
const safeRunId = String(runId || `${safeDomain}-run`).replace(/[^\w.-]+/g, "_");
|
|
30
|
+
const safeIndex = String((Number(index) || 0) + 1).padStart(3, "0");
|
|
31
|
+
const safeExt = String(extension || "png").replace(/^\./, "") || "png";
|
|
32
|
+
return path.join(dir, safeRunId, `${safeDomain}-candidate-${safeIndex}.${safeExt}`);
|
|
33
|
+
}
|
|
@@ -189,6 +189,44 @@ function normalizeBlockText(input) {
|
|
|
189
189
|
return String(input ?? "").trim();
|
|
190
190
|
}
|
|
191
191
|
|
|
192
|
+
function normalizeReasoningKey(input) {
|
|
193
|
+
return normalizeBlockText(input).replace(/\s+/g, " ");
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
function collapseRepeatedReasoningText(input) {
|
|
197
|
+
const text = normalizeBlockText(input);
|
|
198
|
+
if (!text) return "";
|
|
199
|
+
const chunks = text.split(/\n{2,}/).map(normalizeBlockText).filter(Boolean);
|
|
200
|
+
if (chunks.length >= 2 && chunks.length % 2 === 0) {
|
|
201
|
+
const midpoint = chunks.length / 2;
|
|
202
|
+
const first = chunks.slice(0, midpoint);
|
|
203
|
+
const second = chunks.slice(midpoint);
|
|
204
|
+
if (normalizeReasoningKey(first.join("\n\n")) === normalizeReasoningKey(second.join("\n\n"))) {
|
|
205
|
+
return first.join("\n\n");
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
const compacted = normalizeReasoningKey(text);
|
|
210
|
+
if (compacted.length < 160) return text;
|
|
211
|
+
const midpoint = Math.floor(compacted.length / 2);
|
|
212
|
+
for (let offset = -32; offset <= 32; offset += 1) {
|
|
213
|
+
const split = midpoint + offset;
|
|
214
|
+
if (split <= 80 || split >= compacted.length - 80) continue;
|
|
215
|
+
const first = compacted.slice(0, split).trim();
|
|
216
|
+
const second = compacted.slice(split).trim();
|
|
217
|
+
if (first && first === second) return first;
|
|
218
|
+
}
|
|
219
|
+
return text;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
function firstReasoningText(lines) {
|
|
223
|
+
for (const line of lines) {
|
|
224
|
+
const cleaned = collapseRepeatedReasoningText(line);
|
|
225
|
+
if (cleaned) return cleaned;
|
|
226
|
+
}
|
|
227
|
+
return "";
|
|
228
|
+
}
|
|
229
|
+
|
|
192
230
|
function compact(input) {
|
|
193
231
|
return normalizeText(input).toLowerCase();
|
|
194
232
|
}
|
|
@@ -472,7 +510,9 @@ function flattenChatMessageContent(content) {
|
|
|
472
510
|
|
|
473
511
|
function collectLlmReasoningText(choice = {}) {
|
|
474
512
|
const message = choice?.message || {};
|
|
475
|
-
|
|
513
|
+
const seen = new Set();
|
|
514
|
+
const unique = [];
|
|
515
|
+
for (const item of [
|
|
476
516
|
message.reasoning_content,
|
|
477
517
|
message.provider_specific_fields?.reasoning_content,
|
|
478
518
|
message.reasoning,
|
|
@@ -489,7 +529,14 @@ function collectLlmReasoningText(choice = {}) {
|
|
|
489
529
|
choice.provider_specific_fields?.cot,
|
|
490
530
|
choice.chain_of_thought,
|
|
491
531
|
choice.provider_specific_fields?.chain_of_thought
|
|
492
|
-
]
|
|
532
|
+
]) {
|
|
533
|
+
const text = collapseRepeatedReasoningText(flattenChatMessageContent(item));
|
|
534
|
+
const key = normalizeReasoningKey(text);
|
|
535
|
+
if (!key || seen.has(key)) continue;
|
|
536
|
+
seen.add(key);
|
|
537
|
+
unique.push(text);
|
|
538
|
+
}
|
|
539
|
+
return collapseRepeatedReasoningText(unique.join("\n\n"));
|
|
493
540
|
}
|
|
494
541
|
|
|
495
542
|
function mimeTypeForImagePath(filePath) {
|
|
@@ -1621,7 +1668,7 @@ async function callScreeningLlmWithProvider({
|
|
|
1621
1668
|
const evidence = Array.isArray(parsed?.evidence)
|
|
1622
1669
|
? parsed.evidence.map(normalizeText).filter(Boolean)
|
|
1623
1670
|
: [];
|
|
1624
|
-
const decisionCot =
|
|
1671
|
+
const decisionCot = firstReasoningText([
|
|
1625
1672
|
parsed?.cot,
|
|
1626
1673
|
parsed?.decision_cot,
|
|
1627
1674
|
parsed?.reasoning,
|