@lmzhen/dsh-evolution-maintenance 0.26.26 → 0.27.0

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/lib/index.js CHANGED
@@ -528,7 +528,6 @@ function formatPlan(validated, runId) {
528
528
  }
529
529
  /** Run one maintenance scan and return display text plus validation metadata. */
530
530
  async function runMaintain(runtime, options = {}) {
531
- let abortSignal;
532
531
  try {
533
532
  if (!verifyPromptBundle(PROMPT_BUNDLE)) return {
534
533
  ok: false,
@@ -578,22 +577,18 @@ ${MAINTAIN_OUTPUT_INSTRUCTION}`;
578
577
  recommendationCount: 0,
579
578
  error: `maintain:--timeout 必须是以毫秒为单位的正整数,最大 ${MAX_TIMER_DELAY_MS};收到 ${String(timeoutMs)}`
580
579
  };
581
- const signal = options.signal !== void 0 ? AbortSignal.any([AbortSignal.timeout(timeoutMs), options.signal]) : AbortSignal.timeout(timeoutMs);
582
- abortSignal = signal;
583
580
  const agentOptions = { model: options.model ?? runtime.evolutionPolicy?.get()?.curatorModel ?? DEFAULT_CURATOR_MODEL };
584
581
  if (options.provider) agentOptions.provider = options.provider;
585
- const run = await runtime.subagents.start("spawn", {
586
- label: "dsh-evolution-maintain",
587
- prompt: [{
588
- type: "text",
589
- text: prompt
590
- }],
582
+ const outcome = await runtime.channel.run({
591
583
  parent: runtime.parent,
592
- signal,
584
+ label: "dsh-evolution-maintain",
585
+ promptText: template + "\n\n" + prompt,
586
+ kind: "maintainer",
587
+ allow: [...toolAllow],
593
588
  maxDepth: typeof options.maxDepth === "number" && Number.isFinite(options.maxDepth) && options.maxDepth >= 1 ? options.maxDepth : 1,
594
589
  agentOptions,
595
- persona: template,
596
- toolFilter: { allow: [...toolAllow] },
590
+ timeoutMs,
591
+ ...options.signal === void 0 ? {} : { signal: options.signal },
597
592
  outputSchema: {
598
593
  type: "object",
599
594
  additionalProperties: false,
@@ -664,53 +659,47 @@ ${MAINTAIN_OUTPUT_INSTRUCTION}`;
664
659
  }
665
660
  }
666
661
  });
667
- try {
668
- const runResult = await run.result;
669
- const raw = runResult.structured;
670
- if (raw === void 0) {
671
- if (runResult.stopReason === "aborted") return {
672
- ok: false,
673
- recommendationCount: 0,
674
- error: "维护扫描已中止(在子智能体产出计划之前运行被取消):请在会话空闲时重试;并发重交会取消上一次扫描。"
675
- };
676
- return {
677
- ok: false,
678
- recommendationCount: 0,
679
- error: "维护子智能体没有返回结构化计划(模型没有产出结构化计划,或运行在产出前结束):请重试;若反复出现,请提高 --timeout 或检查模型的输出结构。"
680
- };
681
- }
682
- const validated = validateAndNormalizeMaintainPlan(raw, report, existingSignalIds(report));
683
- if (!validated.ok) return {
684
- ok: false,
685
- recommendationCount: 0,
686
- error: `维护计划被校验器拒绝:${validated.errors.slice(0, 5).join("; ")}`
687
- };
688
- const runId = options.runId ?? randomUUID();
689
- return {
690
- ok: true,
691
- runId,
692
- verdict: validated.plan.verdict,
693
- forcedHuman: validated.forcedHuman,
694
- items: validated.plan.plan,
695
- notes: validated.plan.notes,
696
- needsHumanCount: validated.plan.plan.filter((item) => item.needs_human).length,
697
- recommendationCount: validated.plan.plan.length,
698
- text: formatPlan(validated, runId)
699
- };
700
- } finally {
701
- try {
702
- await run.dispose();
703
- } catch (disposeError) {
704
- runtime.logger?.warn(`dsh-evolution-maintenance: subagent dispose failed: ${disposeError instanceof Error ? disposeError.message : String(disposeError)}`);
705
- }
706
- }
662
+ if (outcome.kind === "unavailable") return {
663
+ ok: false,
664
+ recommendationCount: 0,
665
+ error: `维护扫描不可用(${outcome.code}):${outcome.reason}。请在已挂载 agentPresets/subagents 的宿主会话中重试。`
666
+ };
667
+ if (outcome.kind === "aborted") return {
668
+ ok: false,
669
+ recommendationCount: 0,
670
+ error: "维护扫描已中止(取消或超时),计划尚未产出 —— 在技能多、库大的场景下,请重试或提高超时(evolution-commands maintainTimeoutMs)。"
671
+ };
672
+ if (outcome.kind === "no-structured") return {
673
+ ok: false,
674
+ recommendationCount: 0,
675
+ error: "维护子智能体没有返回结构化计划(模型没有产出结构化计划,或运行在产出前结束):请重试;若反复出现,请提高 --timeout 或检查模型的输出结构。"
676
+ };
677
+ const raw = outcome.structured;
678
+ const validated = validateAndNormalizeMaintainPlan(raw, report, existingSignalIds(report));
679
+ if (!validated.ok) return {
680
+ ok: false,
681
+ recommendationCount: 0,
682
+ error: `维护计划被校验器拒绝:${validated.errors.slice(0, 5).join("; ")}`
683
+ };
684
+ const runId = options.runId ?? randomUUID();
685
+ return {
686
+ ok: true,
687
+ runId,
688
+ verdict: validated.plan.verdict,
689
+ forcedHuman: validated.forcedHuman,
690
+ items: validated.plan.plan,
691
+ notes: validated.plan.notes,
692
+ needsHumanCount: validated.plan.plan.filter((item) => item.needs_human).length,
693
+ recommendationCount: validated.plan.plan.length,
694
+ text: formatPlan(validated, runId)
695
+ };
707
696
  } catch (error) {
708
697
  const name = typeof error === "object" && error !== null ? error.name : void 0;
709
698
  const message = error instanceof Error ? error.message : String(error);
710
699
  return {
711
700
  ok: false,
712
701
  recommendationCount: 0,
713
- error: abortSignal?.aborted === true || name === "AbortError" || message === "This operation was aborted" ? "维护扫描已中止(取消或超时),计划尚未产出 —— 在技能多、库大的场景下,请重试或提高超时(evolution-commands maintainTimeoutMs)。" : `Maintenance scan failed: ${message}`
702
+ error: options.signal?.aborted === true || name === "AbortError" || message === "This operation was aborted" ? "维护扫描已中止(取消或超时),计划尚未产出 —— 在技能多、库大的场景下,请重试或提高超时(evolution-commands maintainTimeoutMs)。" : `Maintenance scan failed: ${message}`
714
703
  };
715
704
  }
716
705
  }
@@ -6,49 +6,24 @@
6
6
  */
7
7
  import { type DriftReport, type DriftSkillSnapshot } from '@lmzhen/dsh-evolution-core';
8
8
  import type { Agent } from '@deepseek-ai/dsh-agent';
9
- import type { SubagentResult, SubagentRun, SubagentStartRequest } from '@deepseek-ai/dsh-subagent';
9
+ import type { SubagentChannel } from '@lmzhen/dsh-evolution-core';
10
10
  import { type SkillLibraryLike } from './drift-scan.ts';
11
11
  import { type Enrichment } from './enrichment.ts';
12
12
  import { type StoreFootprint } from './render-facts.ts';
13
13
  import { type FootprintIo } from './footprint.ts';
14
14
  import { type MaintainPlanItem } from './validate-plan.ts';
15
15
  /**
16
- * I-5 (v37), D-09 (G1/1.8): the platform types are IMPORTED, not copied. Each view below is DERIVED from
17
- * the platform contract, so a field the platform renames fails the build here instead of drifting.
18
- *
19
- * The one thing this layer must add: `persona` and `toolFilter` are honoured at runtime (child-agent.ts
20
- * installs a `deployment:persona` system-prompt section; the README documents toolFilter as applying the
21
- * requested child tool restriction) but the CALLER-facing `SubagentStartRequest` does not declare them.
22
- * They are therefore declared here, once, as an explicit extension instead of a hand-copied whole.
16
+ * W5 G3-S4: execution goes through evolution-core's Channel (the 0.2.1 startActivation contract +
17
+ * restricted preset). The former local views of the platform subagent request/result are gone — a
18
+ * structural copy would be the second definition the contract freeze forbids.
23
19
  */
24
- export type MaintainSubagentStart = SubagentStartRequest & {
25
- readonly persona?: string | undefined;
26
- readonly toolFilter?: {
27
- readonly allow: readonly string[];
28
- } | undefined;
29
- };
30
- /** The `SubagentResult` fields the outcome mapping reads (the platform result is wider). */
31
- /** The `SubagentResult` fields the outcome mapping reads. `diagnostic` is OPTIONAL here on purpose: the
32
- * platform type declares it required, but this layer reads it defensively (the mapped outcome must work
33
- * for a result that carries none), so the view states that narrower truth instead of inheriting the
34
- * platform requirement. */
35
- export type MaintainSubagentResult = Pick<SubagentResult, 'structured' | 'stopReason'> & {
36
- readonly diagnostic?: string | undefined;
37
- };
38
- /** The platform run handle the orchestrator owns (`dispose` is required and every exit path awaits it). */
39
- export type MaintainSubagentRun = SubagentRun;
40
20
  export interface MaintainRuntime {
41
21
  /** SkillLibrary-like reader for snapshot assembly. */
42
22
  library: SkillLibraryLike;
43
- /** Subagent spawner (platform `subagents` service — the request fields this
44
- * orchestrator sends, typed as the platform requires them: I-5 (v37) tightened the
45
- * request from `unknown` and `dispose` from optional to the platform's
46
- * always-present handle, so a future miss fails `tsc` instead of a runtime TypeError. */
47
- subagents: {
48
- start(kind: 'spawn', options: MaintainSubagentStart): Promise<MaintainSubagentRun>;
49
- };
50
- /** The spawning agent (platform `SubagentStartRequest.parent`, required: in-process
51
- * providers derive workspace, lineage and delegation depth from its durable session). */
23
+ /** W5 G3-S4: the ONE execution path (capability probe, restricted preset, timeout/abort and
24
+ * exactly-one dispose live in the channel; this orchestrator only maps the outcome). */
25
+ channel: SubagentChannel;
26
+ /** The spawning agent (0.2.1 `SubagentStartRequest.parent`). */
52
27
  parent: Agent;
53
28
  /** Optional logger for dispose-failure traces; when absent the failure is
54
29
  * swallowed without surfacing (the orchestrator is a pure function). */
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@lmzhen/dsh-evolution-maintenance",
3
3
  "description": "Deterministic maintenance-scan surface: skill-library snapshot assembly, drift signals and mechanical-facts rendering (design 011) (community build)",
4
- "version": "0.26.26",
4
+ "version": "0.27.0",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -30,18 +30,19 @@
30
30
  ],
31
31
  "license": "MIT",
32
32
  "dependencies": {
33
- "@deepseek-ai/schemastery": "^3.18.4",
34
- "@lmzhen/dsh-evolution-core": "^0.26.26"
33
+ "@deepseek-ai/schemastery": "^3.18.5",
34
+ "@lmzhen/dsh-evolution-core": "^0.27.0"
35
35
  },
36
36
  "peerDependencies": {
37
- "@deepseek-ai/cordis": "^4.0.1",
38
- "@deepseek-ai/dsh-agent": "^0.2.0-rc.1",
39
- "@deepseek-ai/dsh-subagent": "^0.2.0-rc.1",
40
- "@deepseek-ai/dsh-tools": "^0.2.0-rc.1"
37
+ "@deepseek-ai/cordis": "^4.0.5",
38
+ "@deepseek-ai/dsh-agent": "^0.2.1-rc.1",
39
+ "@deepseek-ai/dsh-tools": "^0.2.1-rc.1"
41
40
  },
42
41
  "devDependencies": {
43
- "@deepseek-ai/dsh-agent": "^0.2.0-rc.1",
44
- "@deepseek-ai/dsh-subagent": "^0.2.0-rc.1",
45
- "@deepseek-ai/dsh-tools": "^0.2.0-rc.1"
42
+ "@deepseek-ai/dsh-agent": "^0.2.1-rc.1",
43
+ "@deepseek-ai/dsh-tools": "^0.2.1-rc.1"
44
+ },
45
+ "engines": {
46
+ "dsh": ">=0.2.1-rc.1 <0.2.2-0"
46
47
  }
47
48
  }