@reconcrap/boss-recommend-mcp 2.1.19 → 2.1.20

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reconcrap/boss-recommend-mcp",
3
- "version": "2.1.19",
3
+ "version": "2.1.20",
4
4
  "description": "Unified MCP pipeline for recommend-page filtering and screening on Boss Zhipin",
5
5
  "keywords": [
6
6
  "boss",
@@ -54,6 +54,7 @@ import { DEFAULT_MAX_IMAGE_PAGES } from "./core/cv-acquisition/index.js";
54
54
  const DEFAULT_RECOMMEND_HOST = "127.0.0.1";
55
55
  const DEFAULT_RECOMMEND_PORT = 9222;
56
56
  const DEFAULT_RECOMMEND_POLL_AFTER_SEC = 10;
57
+ const STATUS_METHOD_LOG_TAIL_LIMIT = 25;
57
58
  const TARGET_COUNT_SEMANTICS = "target_count means candidates that pass screening; scan continues until that many candidates pass or the list ends";
58
59
  const RUN_MODE_ASYNC = "async";
59
60
  const REST_LEVEL_OPTIONS = ["low", "medium", "high"];
@@ -302,15 +303,23 @@ function resolveRecommendDetailLimit(args = {}, normalized = {}) {
302
303
  return requested;
303
304
  }
304
305
 
305
- function methodSummary(methodLog = []) {
306
+ function methodSummary(methodLog = []) {
306
307
  const summary = {};
307
308
  for (const entry of methodLog || []) {
308
309
  summary[entry.method] = (summary[entry.method] || 0) + 1;
309
310
  }
310
- return summary;
311
- }
312
-
313
- function clonePlain(value, fallback = null) {
311
+ return summary;
312
+ }
313
+
314
+ function compactMethodLogForStatus(methodLog = []) {
315
+ if (!Array.isArray(methodLog)) return [];
316
+ return methodLog.slice(-STATUS_METHOD_LOG_TAIL_LIMIT).map((entry) => ({
317
+ method: normalizeText(entry?.method || entry || ""),
318
+ at: normalizeText(entry?.at || "")
319
+ }));
320
+ }
321
+
322
+ function clonePlain(value, fallback = null) {
314
323
  try {
315
324
  return value === undefined ? fallback : JSON.parse(JSON.stringify(value));
316
325
  } catch {
@@ -477,7 +486,7 @@ function secondsBetween(startedAt, endedAt) {
477
486
  return Math.max(1, Math.round((endMs - startMs) / 1000));
478
487
  }
479
488
 
480
- function normalizeLegacyProgress(progress = {}, summary = null) {
489
+ function normalizeLegacyProgress(progress = {}, summary = null) {
481
490
  const processed = Number.isInteger(progress.processed)
482
491
  ? progress.processed
483
492
  : Number.isInteger(summary?.processed)
@@ -502,12 +511,146 @@ function normalizeLegacyProgress(progress = {}, summary = null) {
502
511
  skipped: Number.isInteger(progress.skipped) ? progress.skipped : Math.max(processed - passed, 0),
503
512
  greet_count: Number.isInteger(progress.greet_count) ? progress.greet_count : 0,
504
513
  post_action_clicked: Number.isInteger(progress.post_action_clicked) ? progress.post_action_clicked : 0
505
- };
506
- }
507
-
508
- function completionReason(status) {
509
- if (status === RUN_STATUS_COMPLETED) return "completed";
510
- if (status === RUN_STATUS_CANCELED) return "canceled_by_user";
514
+ };
515
+ }
516
+
517
+ const STATUS_COUNT_KEYS = [
518
+ "processed",
519
+ "screened",
520
+ "detail_opened",
521
+ "passed",
522
+ "skipped",
523
+ "llm_screened",
524
+ "greet_count",
525
+ "post_action_clicked",
526
+ "image_capture_failed",
527
+ "detail_open_failed",
528
+ "transient_recovered",
529
+ "colleague_contact_checked",
530
+ "recent_colleague_contact_skipped",
531
+ "colleague_contact_panel_missing",
532
+ "context_recoveries",
533
+ "human_rest_count",
534
+ "human_rest_ms",
535
+ "card_count",
536
+ "refresh_rounds"
537
+ ];
538
+
539
+ function compactPositiveInteger(value, fallback = null) {
540
+ return Number.isInteger(value) && value >= 0 ? value : fallback;
541
+ }
542
+
543
+ function compactSmallRecord(value, fallback = null) {
544
+ const record = plainRecord(value);
545
+ if (!Object.keys(record).length) return fallback;
546
+ return clonePlain(record, fallback);
547
+ }
548
+
549
+ function compactRecommendSummaryForStatus(summary) {
550
+ if (!summary || typeof summary !== "object" || Array.isArray(summary)) return null;
551
+ const compact = {
552
+ domain: normalizeText(summary.domain || "recommend") || "recommend"
553
+ };
554
+ for (const key of STATUS_COUNT_KEYS) {
555
+ if (Number.isInteger(summary[key])) compact[key] = summary[key];
556
+ }
557
+ if (summary.target_url) compact.target_url = normalizeText(summary.target_url);
558
+ if (summary.list_end_reason) compact.list_end_reason = normalizeText(summary.list_end_reason);
559
+ if (Array.isArray(summary.results)) {
560
+ compact.results_count = summary.results.length;
561
+ } else if (Number.isInteger(summary.results_count)) {
562
+ compact.results_count = summary.results_count;
563
+ }
564
+ if (Array.isArray(summary.refresh_attempts)) {
565
+ compact.refresh_attempt_count = summary.refresh_attempts.length;
566
+ }
567
+ if (Array.isArray(summary.context_recoveries)) {
568
+ compact.context_recovery_count = summary.context_recoveries.length;
569
+ } else if (Number.isInteger(summary.context_recoveries)) {
570
+ compact.context_recoveries = summary.context_recoveries;
571
+ }
572
+ if (summary.job_selection) compact.job_selection = compactSmallRecord(summary.job_selection);
573
+ if (summary.page_scope) compact.page_scope = compactSmallRecord(summary.page_scope);
574
+ if (summary.filter) compact.filter = compactSmallRecord(summary.filter);
575
+ if (summary.candidate_list) {
576
+ const candidateList = plainRecord(summary.candidate_list);
577
+ compact.candidate_list = {
578
+ total_count: compactPositiveInteger(candidateList.total_count ?? candidateList.card_count, null),
579
+ visible_count: compactPositiveInteger(candidateList.visible_count, null),
580
+ list_end_reason: normalizeText(candidateList.list_end_reason || "")
581
+ };
582
+ }
583
+ if (summary.viewport_health?.stats) {
584
+ compact.viewport_health = {
585
+ stats: clonePlain(summary.viewport_health.stats, {})
586
+ };
587
+ }
588
+ if (summary.human_behavior) {
589
+ compact.human_behavior = {
590
+ enabled: summary.human_behavior.enabled === true,
591
+ profile: normalizeText(summary.human_behavior.profile || ""),
592
+ restLevel: normalizeText(summary.human_behavior.restLevel || summary.human_behavior.rest_level || "")
593
+ };
594
+ }
595
+ if (summary.human_rest) {
596
+ const humanRest = plainRecord(summary.human_rest);
597
+ compact.human_rest = {
598
+ enabled: humanRest.enabled === true,
599
+ restLevel: normalizeText(humanRest.restLevel || humanRest.rest_level || ""),
600
+ rest_count: compactPositiveInteger(humanRest.rest_count ?? humanRest.count, null),
601
+ total_pause_ms: compactPositiveInteger(humanRest.total_pause_ms ?? humanRest.pause_ms, null)
602
+ };
603
+ }
604
+ return compact;
605
+ }
606
+
607
+ function compactRecommendCheckpointForStatus(checkpoint) {
608
+ if (!checkpoint || typeof checkpoint !== "object" || Array.isArray(checkpoint)) return {};
609
+ const compact = {};
610
+ if (checkpoint.updatedAt || checkpoint.updated_at) {
611
+ compact.updatedAt = normalizeText(checkpoint.updatedAt || checkpoint.updated_at);
612
+ }
613
+ if (Array.isArray(checkpoint.results)) {
614
+ compact.results_count = checkpoint.results.length;
615
+ } else if (Number.isInteger(checkpoint.results_count)) {
616
+ compact.results_count = checkpoint.results_count;
617
+ }
618
+ for (const key of STATUS_COUNT_KEYS) {
619
+ if (Number.isInteger(checkpoint[key])) compact[key] = checkpoint[key];
620
+ }
621
+ return compact;
622
+ }
623
+
624
+ function compactRecommendResultForStatus(result) {
625
+ if (!result || typeof result !== "object" || Array.isArray(result)) return result || null;
626
+ const compact = {
627
+ ...result
628
+ };
629
+ if (Array.isArray(result.results)) {
630
+ compact.results_count = result.results.length;
631
+ compact.results_available = result.results.length > 0;
632
+ } else if (Number.isInteger(result.results_count)) {
633
+ compact.results_count = result.results_count;
634
+ compact.results_available = result.results_available === true || result.results_count > 0;
635
+ }
636
+ delete compact.results;
637
+ return compact;
638
+ }
639
+
640
+ export function compactRecommendRunForStatus(run) {
641
+ if (!run || typeof run !== "object" || Array.isArray(run)) return run || null;
642
+ const compact = {
643
+ ...run
644
+ };
645
+ if (compact.result) compact.result = compactRecommendResultForStatus(compact.result);
646
+ if (compact.summary) compact.summary = compactRecommendSummaryForStatus(compact.summary);
647
+ if (compact.checkpoint) compact.checkpoint = compactRecommendCheckpointForStatus(compact.checkpoint);
648
+ return compact;
649
+ }
650
+
651
+ function completionReason(status) {
652
+ if (status === RUN_STATUS_COMPLETED) return "completed";
653
+ if (status === RUN_STATUS_CANCELED) return "canceled_by_user";
511
654
  if (status === RUN_STATUS_FAILED) return "failed";
512
655
  if (status === RUN_STATUS_PAUSED) return "paused";
513
656
  return null;
@@ -685,13 +828,14 @@ function buildLegacyRecommendResult(snapshot) {
685
828
  effective_scope: meta.normalized?.pageScope || meta.parsed?.page_scope || "recommend"
686
829
  },
687
830
  search_params: clonePlain(meta.parsed?.searchParams || {}, {}),
688
- screen_params: clonePlain(meta.parsed?.screenParams || {}, {}),
689
- target_count_semantics: TARGET_COUNT_SEMANTICS,
690
- error: snapshot.error || null,
691
- recovery: buildConstrainedAgentRecovery(snapshot, meta, artifacts),
692
- results: resultRows
693
- };
694
- }
831
+ screen_params: clonePlain(meta.parsed?.screenParams || {}, {}),
832
+ target_count_semantics: TARGET_COUNT_SEMANTICS,
833
+ error: snapshot.error || null,
834
+ recovery: buildConstrainedAgentRecovery(snapshot, meta, artifacts),
835
+ results_count: resultRows.length,
836
+ results_available: resultRows.length > 0
837
+ };
838
+ }
695
839
 
696
840
  function normalizeRunSnapshot(snapshot) {
697
841
  if (!snapshot) return null;
@@ -714,10 +858,12 @@ function normalizeRunSnapshot(snapshot) {
714
858
  follow_up: clonePlain(metaArgs.follow_up ?? snapshotContext.follow_up ?? null, null),
715
859
  target_count_semantics: TARGET_COUNT_SEMANTICS
716
860
  };
717
- return {
718
- ...snapshot,
719
- progress,
720
- run_id: snapshot.runId,
861
+ return {
862
+ ...snapshot,
863
+ checkpoint: compactRecommendCheckpointForStatus(snapshot.checkpoint),
864
+ summary: compactRecommendSummaryForStatus(summary),
865
+ progress,
866
+ run_id: snapshot.runId,
721
867
  mode: RUN_MODE_ASYNC,
722
868
  state: snapshot.status,
723
869
  stage: snapshot.phase,
@@ -874,7 +1020,7 @@ function persistRecommendRunSnapshot(snapshot, {
874
1020
  normalized.control = mergePersistedControlRequest(normalized, existing);
875
1021
  normalized = coerceCanceledTerminalSnapshot(normalized, existing);
876
1022
  if (persistActiveCheckpoint) {
877
- persistRecommendCheckpointSnapshot(normalized);
1023
+ persistRecommendCheckpointSnapshot(snapshot);
878
1024
  }
879
1025
  const payload = {
880
1026
  run_id: normalized.run_id,
@@ -970,17 +1116,19 @@ function persistRecommendLifecycleSnapshot(snapshot, event = {}) {
970
1116
  });
971
1117
  }
972
1118
 
973
- function attachMethodEvidence(payload, runId) {
974
- const meta = getRecommendRunMeta(runId);
975
- assertNoForbiddenCdpCalls(meta.methodLog || []);
976
- return {
977
- ...payload,
978
- runtime_evaluate_used: false,
979
- method_summary: methodSummary(meta.methodLog || []),
980
- method_log: meta.methodLog || [],
981
- chrome: meta.chrome || null
982
- };
983
- }
1119
+ function attachMethodEvidence(payload, runId) {
1120
+ const meta = getRecommendRunMeta(runId);
1121
+ const methodLog = meta.methodLog || [];
1122
+ assertNoForbiddenCdpCalls(methodLog);
1123
+ return {
1124
+ ...payload,
1125
+ runtime_evaluate_used: false,
1126
+ method_summary: methodSummary(methodLog),
1127
+ method_log: compactMethodLogForStatus(methodLog),
1128
+ method_log_total: Array.isArray(methodLog) ? methodLog.length : 0,
1129
+ chrome: meta.chrome || null
1130
+ };
1131
+ }
984
1132
 
985
1133
  function compactRecommendJobListOption(option, index) {
986
1134
  const label = normalizeText(option?.label);
@@ -1945,19 +2093,19 @@ export function getRecommendPipelineRunTool({ args = {} } = {}) {
1945
2093
  };
1946
2094
  }
1947
2095
  try {
1948
- const run = recommendRunService.getRecommendRun(runId);
1949
- const normalizedRun = persistRecommendRunSnapshot(run);
1950
- return attachMethodEvidence({
1951
- status: "RUN_STATUS",
1952
- run: normalizedRun
1953
- }, runId);
1954
- } catch {
1955
- const persisted = readRecommendRunState(runId);
1956
- if (persisted) {
1957
- const reconciled = reconcilePersistedRecommendRunIfNeeded(persisted);
1958
- return {
1959
- status: "RUN_STATUS",
1960
- run: reconciled,
2096
+ const run = recommendRunService.getRecommendRun(runId);
2097
+ const normalizedRun = persistRecommendRunSnapshot(run);
2098
+ return attachMethodEvidence({
2099
+ status: "RUN_STATUS",
2100
+ run: compactRecommendRunForStatus(normalizedRun)
2101
+ }, runId);
2102
+ } catch {
2103
+ const persisted = readRecommendRunState(runId);
2104
+ if (persisted) {
2105
+ const reconciled = compactRecommendRunForStatus(reconcilePersistedRecommendRunIfNeeded(persisted));
2106
+ return {
2107
+ status: "RUN_STATUS",
2108
+ run: reconciled,
1961
2109
  persistence: {
1962
2110
  source: "disk",
1963
2111
  active_control_available: false,
@@ -1985,36 +2133,36 @@ export function pauseRecommendPipelineRunTool({ args = {} } = {}) {
1985
2133
  try {
1986
2134
  const before = recommendRunService.getRecommendRun(runId);
1987
2135
  if (TERMINAL_STATUSES.has(before.status)) {
1988
- const normalizedBefore = persistRecommendRunSnapshot(before);
1989
- return attachMethodEvidence({
1990
- status: "PAUSE_IGNORED",
1991
- run: normalizedBefore,
1992
- message: "目标任务已结束,无需暂停。"
1993
- }, runId);
2136
+ const normalizedBefore = persistRecommendRunSnapshot(before);
2137
+ return attachMethodEvidence({
2138
+ status: "PAUSE_IGNORED",
2139
+ run: compactRecommendRunForStatus(normalizedBefore),
2140
+ message: "目标任务已结束,无需暂停。"
2141
+ }, runId);
1994
2142
  }
1995
2143
  if (before.status === RUN_STATUS_PAUSED) {
1996
- const normalizedBefore = persistRecommendRunSnapshot(before);
1997
- return attachMethodEvidence({
1998
- status: "PAUSE_IGNORED",
1999
- run: normalizedBefore,
2000
- message: "目标任务已经处于 paused 状态。"
2001
- }, runId);
2144
+ const normalizedBefore = persistRecommendRunSnapshot(before);
2145
+ return attachMethodEvidence({
2146
+ status: "PAUSE_IGNORED",
2147
+ run: compactRecommendRunForStatus(normalizedBefore),
2148
+ message: "目标任务已经处于 paused 状态。"
2149
+ }, runId);
2002
2150
  }
2003
2151
  const run = recommendRunService.pauseRecommendRun(runId);
2004
- const normalizedRun = persistRecommendRunSnapshot(run);
2005
- return attachMethodEvidence({
2006
- status: "PAUSE_REQUESTED",
2007
- run: normalizedRun,
2008
- message: "暂停请求已接收,将在当前候选人处理完成后进入 paused。"
2009
- }, runId);
2152
+ const normalizedRun = persistRecommendRunSnapshot(run);
2153
+ return attachMethodEvidence({
2154
+ status: "PAUSE_REQUESTED",
2155
+ run: compactRecommendRunForStatus(normalizedRun),
2156
+ message: "暂停请求已接收,将在当前候选人处理完成后进入 paused。"
2157
+ }, runId);
2010
2158
  } catch {
2011
2159
  const persisted = readRecommendRunState(runId);
2012
2160
  if (persisted && TERMINAL_STATUSES.has(persisted.state)) {
2013
- return {
2014
- status: "PAUSE_IGNORED",
2015
- run: persisted,
2016
- message: "目标任务已结束,无需暂停。",
2017
- runtime_evaluate_used: false,
2161
+ return {
2162
+ status: "PAUSE_IGNORED",
2163
+ run: compactRecommendRunForStatus(persisted),
2164
+ message: "目标任务已结束,无需暂停。",
2165
+ runtime_evaluate_used: false,
2018
2166
  method_summary: {},
2019
2167
  method_log: [],
2020
2168
  chrome: null
@@ -2029,28 +2177,28 @@ export function resumeRecommendPipelineRunTool({ args = {} } = {}) {
2029
2177
  try {
2030
2178
  const before = recommendRunService.getRecommendRun(runId);
2031
2179
  if (TERMINAL_STATUSES.has(before.status)) {
2032
- const normalizedBefore = persistRecommendRunSnapshot(before);
2033
- return attachMethodEvidence({
2034
- status: "FAILED",
2180
+ const normalizedBefore = persistRecommendRunSnapshot(before);
2181
+ return attachMethodEvidence({
2182
+ status: "FAILED",
2035
2183
  error: {
2036
2184
  code: "RUN_ALREADY_TERMINATED",
2037
2185
  message: "目标任务已结束,无法继续。",
2038
2186
  retryable: false
2039
2187
  },
2040
- run: normalizedBefore
2041
- }, runId);
2188
+ run: compactRecommendRunForStatus(normalizedBefore)
2189
+ }, runId);
2042
2190
  }
2043
2191
  if (before.status !== RUN_STATUS_PAUSED) {
2044
- const normalizedBefore = persistRecommendRunSnapshot(before);
2045
- return attachMethodEvidence({
2046
- status: "FAILED",
2192
+ const normalizedBefore = persistRecommendRunSnapshot(before);
2193
+ return attachMethodEvidence({
2194
+ status: "FAILED",
2047
2195
  error: {
2048
2196
  code: "RUN_NOT_PAUSED",
2049
2197
  message: "仅 paused 状态的 run 才能继续。",
2050
2198
  retryable: true
2051
2199
  },
2052
- run: normalizedBefore
2053
- }, runId);
2200
+ run: compactRecommendRunForStatus(normalizedBefore)
2201
+ }, runId);
2054
2202
  }
2055
2203
  const run = recommendRunService.resumeRecommendRun(runId);
2056
2204
  const meta = getRecommendRunMeta(runId);
@@ -2058,12 +2206,12 @@ export function resumeRecommendPipelineRunTool({ args = {} } = {}) {
2058
2206
  meta.resumeCount = (meta.resumeCount || 0) + 1;
2059
2207
  meta.lastResumedAt = new Date().toISOString();
2060
2208
  }
2061
- const normalizedRun = persistRecommendRunSnapshot(run);
2062
- return attachMethodEvidence({
2063
- status: "RESUME_REQUESTED",
2064
- run: normalizedRun,
2065
- poll_after_sec: DEFAULT_RECOMMEND_POLL_AFTER_SEC,
2066
- message: "已恢复 Recommend run,请使用 get_recommend_pipeline_run 按需轮询。"
2209
+ const normalizedRun = persistRecommendRunSnapshot(run);
2210
+ return attachMethodEvidence({
2211
+ status: "RESUME_REQUESTED",
2212
+ run: compactRecommendRunForStatus(normalizedRun),
2213
+ poll_after_sec: DEFAULT_RECOMMEND_POLL_AFTER_SEC,
2214
+ message: "已恢复 Recommend run,请使用 get_recommend_pipeline_run 按需轮询。"
2067
2215
  }, runId);
2068
2216
  } catch {
2069
2217
  const persisted = readRecommendRunState(runId);
@@ -2077,9 +2225,9 @@ export function resumeRecommendPipelineRunTool({ args = {} } = {}) {
2077
2225
  : "该 run 只有磁盘快照,没有当前进程内的活动 CDP 会话,无法安全继续。",
2078
2226
  retryable: !TERMINAL_STATUSES.has(persisted.state)
2079
2227
  },
2080
- run: persisted,
2081
- persistence: {
2082
- source: "disk",
2228
+ run: compactRecommendRunForStatus(persisted),
2229
+ persistence: {
2230
+ source: "disk",
2083
2231
  active_control_available: false
2084
2232
  },
2085
2233
  runtime_evaluate_used: false,
@@ -2097,28 +2245,28 @@ export function cancelRecommendPipelineRunTool({ args = {} } = {}) {
2097
2245
  try {
2098
2246
  const before = recommendRunService.getRecommendRun(runId);
2099
2247
  if (TERMINAL_STATUSES.has(before.status)) {
2100
- const normalizedBefore = persistRecommendRunSnapshot(before);
2101
- return attachMethodEvidence({
2102
- status: "CANCEL_IGNORED",
2103
- run: normalizedBefore,
2104
- message: "目标任务已结束,无需取消。"
2105
- }, runId);
2248
+ const normalizedBefore = persistRecommendRunSnapshot(before);
2249
+ return attachMethodEvidence({
2250
+ status: "CANCEL_IGNORED",
2251
+ run: compactRecommendRunForStatus(normalizedBefore),
2252
+ message: "目标任务已结束,无需取消。"
2253
+ }, runId);
2106
2254
  }
2107
2255
  const run = recommendRunService.cancelRecommendRun(runId);
2108
- const normalizedRun = persistRecommendRunSnapshot(run);
2109
- return attachMethodEvidence({
2110
- status: "CANCEL_REQUESTED",
2111
- run: normalizedRun,
2112
- message: "已收到取消请求,将在当前候选人处理完成后安全停止。"
2113
- }, runId);
2256
+ const normalizedRun = persistRecommendRunSnapshot(run);
2257
+ return attachMethodEvidence({
2258
+ status: "CANCEL_REQUESTED",
2259
+ run: compactRecommendRunForStatus(normalizedRun),
2260
+ message: "已收到取消请求,将在当前候选人处理完成后安全停止。"
2261
+ }, runId);
2114
2262
  } catch {
2115
2263
  const persisted = readRecommendRunState(runId);
2116
2264
  if (persisted && TERMINAL_STATUSES.has(persisted.state)) {
2117
2265
  return {
2118
2266
  status: "CANCEL_IGNORED",
2119
- run: persisted,
2267
+ run: compactRecommendRunForStatus(persisted),
2120
2268
  message: "目标任务已结束,无需取消。",
2121
- runtime_evaluate_used: false,
2269
+ runtime_evaluate_used: false,
2122
2270
  method_summary: {},
2123
2271
  method_log: [],
2124
2272
  chrome: null
@@ -2136,7 +2284,7 @@ export function cancelRecommendPipelineRunTool({ args = {} } = {}) {
2136
2284
  if (patched) {
2137
2285
  return {
2138
2286
  status: "CANCEL_REQUESTED",
2139
- run: patched,
2287
+ run: compactRecommendRunForStatus(patched),
2140
2288
  message: cancelMessage,
2141
2289
  persistence: {
2142
2290
  source: "disk",
@@ -5,6 +5,7 @@ import { spawn } from "node:child_process";
5
5
  import { fileURLToPath } from "node:url";
6
6
  import { getStateHome } from "./run-state.js";
7
7
  import {
8
+ compactRecommendRunForStatus,
8
9
  getRecommendPipelineRunTool,
9
10
  prepareRecommendPipelineRunTool,
10
11
  startRecommendPipelineRunTool
@@ -142,6 +143,19 @@ function writeSchedule(scheduleId, patch) {
142
143
  });
143
144
  }
144
145
 
146
+ function compactScheduleForStatus(schedule) {
147
+ if (!schedule || typeof schedule !== "object" || Array.isArray(schedule)) return schedule || null;
148
+ const compact = clonePlain(schedule, schedule);
149
+ if (compact.run) compact.run = compactRecommendRunForStatus(compact.run);
150
+ if (compact.launch_payload?.run) {
151
+ compact.launch_payload = {
152
+ ...compact.launch_payload,
153
+ run: compactRecommendRunForStatus(compact.launch_payload.run)
154
+ };
155
+ }
156
+ return compact;
157
+ }
158
+
145
159
  function isProcessAlive(pid) {
146
160
  if (!Number.isInteger(pid) || pid <= 0) return false;
147
161
  try {
@@ -355,7 +369,7 @@ export function getRecommendScheduledRunTool({ args = {} } = {}) {
355
369
  return {
356
370
  status: "OK",
357
371
  schedule_id: scheduleId,
358
- schedule: next
372
+ schedule: compactScheduleForStatus(next)
359
373
  };
360
374
  }
361
375