@lmzhen/dsh-evolution-merge 0.37.1 → 0.38.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 +40 -66
- package/lib/types/adapters/model-runner.d.ts +18 -17
- package/lib/types/adapters/model-runner.js +14 -35
- package/lib/types/index.js +1 -1
- package/lib/types/merge-tool.d.ts +2 -14
- package/lib/types/merge-tool.js +10 -14
- package/package.json +7 -6
package/lib/index.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { dirname, join } from "node:path";
|
|
2
2
|
import z from "@deepseek-ai/schemastery";
|
|
3
3
|
import { pairKeyOf, screen, selectCandidates } from "@lmzhen/dsh-evolution-merge-engine";
|
|
4
|
+
import { createUserMessage } from "@deepseek-ai/dsh-llm";
|
|
4
5
|
import { DEFAULT_SKILL_LIMITS, SkillLibrary, UnitTransactions, authorityFrom, contentHash, createSubagentChannel, errorText, evolutionHome, evolutionIoAdapter, executeUnitUndo, isPresent, isProcessAlive, newRunRegistry, newSkillLibrary, parseFrontmatter, planUnitUndoAcross, policyStageLimits, probeAbsent, probeList, probePresent, probeText, probeUnknown, readTreeLock, readUnitEvidence, readUnitJournal, registerOwnerSettings, reportsSweepLockTarget, revisionAnchorOf, revisionFingerprint, revisionSupportDigest, runsFile, scanContentThreats, skillLibraryUnitBackend, supportRefs, sweepReports, transactIo, validateFrontmatter, validateSupportPath } from "@lmzhen/dsh-evolution-core";
|
|
5
6
|
import { HOST_ROUTES, json, methodNotAllowed, registerHostRoutes } from "@lmzhen/dsh-evolution-core/http-routes";
|
|
6
7
|
import { createHash, randomUUID } from "node:crypto";
|
|
7
8
|
import { chmod, mkdir, open, readFile, stat, unlink } from "node:fs/promises";
|
|
8
9
|
import { aliasRegistration, buildSurface, parseCommand } from "@lmzhen/dsh-evolution-commands";
|
|
9
10
|
import { readFileSync } from "node:fs";
|
|
11
|
+
import { defineTool } from "@lmzhen/dsh-evolution-core/platform";
|
|
10
12
|
//#region lib/types/adapters/select.js
|
|
11
13
|
/** Host selector correction: engine selector does not route judge errors to candidates. */
|
|
12
14
|
function selectWithErrors(report) {
|
|
@@ -101,56 +103,32 @@ function normalizeProviderKey(value) {
|
|
|
101
103
|
//#endregion
|
|
102
104
|
//#region lib/types/adapters/model-runner.js
|
|
103
105
|
/**
|
|
104
|
-
* DeepSeek judge runner over the
|
|
105
|
-
* runner(prompt, cfg) and expects raw model text; the
|
|
106
|
-
* selection,
|
|
106
|
+
* DeepSeek judge runner over the family LLM runtime. The engine calls
|
|
107
|
+
* runner(prompt, cfg) and expects raw model text; the runtime owns provider
|
|
108
|
+
* selection, purpose, transport and timeout.
|
|
107
109
|
*/
|
|
108
|
-
function append(chunk, text) {
|
|
109
|
-
if (chunk.type === "text-delta" || chunk.type === "text") return text + (chunk.text ?? "");
|
|
110
|
-
if (chunk.type === "finish" && chunk.reason?.kind === "error") throw new Error("model call failed: " + (chunk.reason.failure?.message ?? "unknown"));
|
|
111
|
-
return text;
|
|
112
|
-
}
|
|
113
110
|
function createEngineRunner(llm, route) {
|
|
114
111
|
return async (prompt, cfg, runSignal) => {
|
|
112
|
+
if (!llm.available()) throw new Error("llm service unavailable: evolutionLlm is degraded");
|
|
115
113
|
const selection = route();
|
|
116
114
|
const timeout = Number(cfg?.timeoutMs);
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
if (llm.stream !== void 0) {
|
|
121
|
-
for await (const chunk of llm.stream({
|
|
115
|
+
return await llm.text({
|
|
116
|
+
purpose: "evolution-merge-engine",
|
|
117
|
+
route: {
|
|
122
118
|
provider: normalizeProviderKey(selection.provider),
|
|
123
|
-
model: selection.model
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
content: [{
|
|
127
|
-
type: "text",
|
|
128
|
-
text: prompt
|
|
129
|
-
}]
|
|
130
|
-
}],
|
|
131
|
-
temperature: 0,
|
|
132
|
-
...signal === void 0 ? {} : { signal }
|
|
133
|
-
})) text = append(chunk, text);
|
|
134
|
-
return text;
|
|
135
|
-
}
|
|
136
|
-
if (llm.prepareCall === void 0) throw new Error("llm service has neither stream nor prepareCall");
|
|
137
|
-
const call = await llm.prepareCall({
|
|
138
|
-
provider: normalizeProviderKey(selection.provider),
|
|
139
|
-
model: selection.model,
|
|
140
|
-
temperature: 0
|
|
141
|
-
}, signal);
|
|
142
|
-
for await (const chunk of call.stream({
|
|
143
|
-
...call.config,
|
|
144
|
-
messages: [{
|
|
145
|
-
role: "user",
|
|
119
|
+
model: selection.model
|
|
120
|
+
},
|
|
121
|
+
messages: [createUserMessage({
|
|
146
122
|
content: [{
|
|
147
123
|
type: "text",
|
|
148
124
|
text: prompt
|
|
149
|
-
}]
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
125
|
+
}],
|
|
126
|
+
source: { kind: "user" }
|
|
127
|
+
})],
|
|
128
|
+
temperature: 0,
|
|
129
|
+
...runSignal === void 0 ? {} : { signal: runSignal },
|
|
130
|
+
...Number.isFinite(timeout) && timeout > 0 ? { timeoutMs: timeout } : {}
|
|
131
|
+
});
|
|
154
132
|
};
|
|
155
133
|
}
|
|
156
134
|
//#endregion
|
|
@@ -10307,33 +10285,29 @@ function operation(args) {
|
|
|
10307
10285
|
return shapeError("op must be list/read/write/copy");
|
|
10308
10286
|
}
|
|
10309
10287
|
function createMergeStageTool(io, home, context, diagnose) {
|
|
10310
|
-
return {
|
|
10288
|
+
return defineTool({
|
|
10311
10289
|
name: MERGE_STAGE_TOOL_NAME,
|
|
10312
10290
|
description: "Read source copies and write the merged skill into the staging tree. list/read use area=sources|merged plus source (for sources); write/copy paths are relative to merged/<target> (for example path=SKILL.md, from=SKILL.md, to=references/x.md). Write/copy are only allowed in the author phase.",
|
|
10313
10291
|
parameters: {
|
|
10314
|
-
|
|
10315
|
-
|
|
10316
|
-
|
|
10317
|
-
|
|
10318
|
-
|
|
10319
|
-
|
|
10320
|
-
|
|
10321
|
-
|
|
10322
|
-
|
|
10323
|
-
]
|
|
10324
|
-
},
|
|
10325
|
-
area: {
|
|
10326
|
-
type: "string",
|
|
10327
|
-
enum: ["sources", "merged"]
|
|
10328
|
-
},
|
|
10329
|
-
path: { type: "string" },
|
|
10330
|
-
source: { type: "string" },
|
|
10331
|
-
content: { type: "string" },
|
|
10332
|
-
from: { type: "string" },
|
|
10333
|
-
to: { type: "string" }
|
|
10292
|
+
op: {
|
|
10293
|
+
type: "string",
|
|
10294
|
+
required: true,
|
|
10295
|
+
enum: [
|
|
10296
|
+
"list",
|
|
10297
|
+
"read",
|
|
10298
|
+
"write",
|
|
10299
|
+
"copy"
|
|
10300
|
+
]
|
|
10334
10301
|
},
|
|
10335
|
-
|
|
10336
|
-
|
|
10302
|
+
area: {
|
|
10303
|
+
type: "string",
|
|
10304
|
+
enum: ["sources", "merged"]
|
|
10305
|
+
},
|
|
10306
|
+
path: { type: "string" },
|
|
10307
|
+
source: { type: "string" },
|
|
10308
|
+
content: { type: "string" },
|
|
10309
|
+
from: { type: "string" },
|
|
10310
|
+
to: { type: "string" }
|
|
10337
10311
|
},
|
|
10338
10312
|
output: {
|
|
10339
10313
|
schema: { type: "string" },
|
|
@@ -10354,7 +10328,7 @@ function createMergeStageTool(io, home, context, diagnose) {
|
|
|
10354
10328
|
});
|
|
10355
10329
|
return JSON.stringify(await applyStageTool(io, home, ctx, op));
|
|
10356
10330
|
}
|
|
10357
|
-
};
|
|
10331
|
+
});
|
|
10358
10332
|
}
|
|
10359
10333
|
//#endregion
|
|
10360
10334
|
//#region lib/types/supersede.js
|
|
@@ -10762,7 +10736,7 @@ function apply(ctx, rawConfig = {}) {
|
|
|
10762
10736
|
const stage = new StageToolRegistry();
|
|
10763
10737
|
const engineInput = resolveEngineInput({ modelsRoot: startupParams.mergeModelsRoot });
|
|
10764
10738
|
const engineConfig = engineConfigFromRoot(engineInput.modelsRoot);
|
|
10765
|
-
const llm = ctx.get("
|
|
10739
|
+
const llm = ctx.get("evolutionLlm");
|
|
10766
10740
|
const defaultModel = ctx.get("agentDefaultModel");
|
|
10767
10741
|
const runner = llm === void 0 || defaultModel === void 0 ? void 0 : createEngineRunner(llm, () => defaultModel.currentSelection());
|
|
10768
10742
|
const engineScreening = createEngineScreening({
|
|
@@ -1,23 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DeepSeek judge runner over the family LLM runtime. The engine calls
|
|
3
|
+
* runner(prompt, cfg) and expects raw model text; the runtime owns provider
|
|
4
|
+
* selection, purpose, transport and timeout.
|
|
5
|
+
*/
|
|
6
|
+
import { createUserMessage } from '@deepseek-ai/dsh-llm';
|
|
1
7
|
export interface ModelRoute {
|
|
2
8
|
readonly provider: string;
|
|
3
9
|
readonly model: string;
|
|
4
10
|
}
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
readonly
|
|
10
|
-
readonly
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
/** The runtime service surface the merge engine consumes. */
|
|
12
|
+
export interface EvolutionLlmLike {
|
|
13
|
+
available(): boolean;
|
|
14
|
+
text(input: {
|
|
15
|
+
readonly purpose: 'evolution-merge-engine';
|
|
16
|
+
readonly route: ModelRoute;
|
|
17
|
+
readonly messages: ReturnType<typeof createUserMessage>[];
|
|
18
|
+
readonly temperature: number;
|
|
19
|
+
readonly signal?: AbortSignal | undefined;
|
|
20
|
+
readonly timeoutMs?: number | undefined;
|
|
21
|
+
}): Promise<string>;
|
|
14
22
|
}
|
|
15
|
-
export
|
|
16
|
-
stream?(options: Record<string, unknown>): AsyncIterable<LlmChunkLike>;
|
|
17
|
-
prepareCall?(config: Record<string, unknown>, signal?: AbortSignal): Promise<{
|
|
18
|
-
readonly config: Record<string, unknown>;
|
|
19
|
-
stream(input: Record<string, unknown>): AsyncIterable<LlmChunkLike>;
|
|
20
|
-
}>;
|
|
21
|
-
}
|
|
22
|
-
export declare function createEngineRunner(llm: LlmServiceLike, route: () => ModelRoute): (prompt: string, cfg?: Record<string, unknown>, signal?: AbortSignal | undefined) => Promise<string>;
|
|
23
|
+
export declare function createEngineRunner(llm: EvolutionLlmLike, route: () => ModelRoute): (prompt: string, cfg?: Record<string, unknown>, signal?: AbortSignal | undefined) => Promise<string>;
|
|
23
24
|
//# sourceMappingURL=model-runner.d.ts.map
|
|
@@ -1,45 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* DeepSeek judge runner over the
|
|
3
|
-
* runner(prompt, cfg) and expects raw model text; the
|
|
4
|
-
* selection,
|
|
2
|
+
* DeepSeek judge runner over the family LLM runtime. The engine calls
|
|
3
|
+
* runner(prompt, cfg) and expects raw model text; the runtime owns provider
|
|
4
|
+
* selection, purpose, transport and timeout.
|
|
5
5
|
*/
|
|
6
|
+
import { createUserMessage } from '@deepseek-ai/dsh-llm';
|
|
6
7
|
import { normalizeProviderKey } from "../domain/provider-key.js";
|
|
7
|
-
function append(chunk, text) {
|
|
8
|
-
if (chunk.type === 'text-delta' || chunk.type === 'text')
|
|
9
|
-
return text + (chunk.text ?? '');
|
|
10
|
-
if (chunk.type === 'finish' && chunk.reason?.kind === 'error') {
|
|
11
|
-
throw new Error('model call failed: ' + (chunk.reason.failure?.message ?? 'unknown'));
|
|
12
|
-
}
|
|
13
|
-
return text;
|
|
14
|
-
}
|
|
15
8
|
export function createEngineRunner(llm, route) {
|
|
16
9
|
return async (prompt, cfg, runSignal) => {
|
|
10
|
+
if (!llm.available())
|
|
11
|
+
throw new Error('llm service unavailable: evolutionLlm is degraded');
|
|
17
12
|
const selection = route();
|
|
18
13
|
const timeout = Number(cfg?.timeoutMs);
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
temperature: 0,
|
|
28
|
-
...(signal === undefined ? {} : { signal }),
|
|
29
|
-
}))
|
|
30
|
-
text = append(chunk, text);
|
|
31
|
-
return text;
|
|
32
|
-
}
|
|
33
|
-
if (llm.prepareCall === undefined)
|
|
34
|
-
throw new Error('llm service has neither stream nor prepareCall');
|
|
35
|
-
const call = await llm.prepareCall({ provider: normalizeProviderKey(selection.provider), model: selection.model, temperature: 0 }, signal);
|
|
36
|
-
for await (const chunk of call.stream({
|
|
37
|
-
...call.config,
|
|
38
|
-
messages: [{ role: 'user', content: [{ type: 'text', text: prompt }] }],
|
|
39
|
-
...(signal === undefined ? {} : { signal }),
|
|
40
|
-
}))
|
|
41
|
-
text = append(chunk, text);
|
|
42
|
-
return text;
|
|
14
|
+
return await llm.text({
|
|
15
|
+
purpose: 'evolution-merge-engine',
|
|
16
|
+
route: { provider: normalizeProviderKey(selection.provider), model: selection.model },
|
|
17
|
+
messages: [createUserMessage({ content: [{ type: 'text', text: prompt }], source: { kind: 'user' } })],
|
|
18
|
+
temperature: 0,
|
|
19
|
+
...(runSignal === undefined ? {} : { signal: runSignal }),
|
|
20
|
+
...(Number.isFinite(timeout) && timeout > 0 ? { timeoutMs: timeout } : {}),
|
|
21
|
+
});
|
|
43
22
|
};
|
|
44
23
|
}
|
|
45
24
|
//# sourceMappingURL=model-runner.js.map
|
package/lib/types/index.js
CHANGED
|
@@ -254,7 +254,7 @@ export function apply(ctx, rawConfig = {}) {
|
|
|
254
254
|
const stage = new StageToolRegistry();
|
|
255
255
|
const engineInput = resolveEngineInput({ modelsRoot: startupParams.mergeModelsRoot });
|
|
256
256
|
const engineConfig = engineConfigFromRoot(engineInput.modelsRoot);
|
|
257
|
-
const llm = ctx.get('
|
|
257
|
+
const llm = ctx.get('evolutionLlm');
|
|
258
258
|
const defaultModel = ctx.get('agentDefaultModel');
|
|
259
259
|
const runner = llm === undefined || defaultModel === undefined
|
|
260
260
|
? undefined
|
|
@@ -3,20 +3,8 @@
|
|
|
3
3
|
* this module owns the argument schema and the JSON result. All policy remains in applyStageTool.
|
|
4
4
|
*/
|
|
5
5
|
import type { EvolutionIoLike } from '@lmzhen/dsh-evolution-core';
|
|
6
|
+
import { defineTool } from '@lmzhen/dsh-evolution-core/platform';
|
|
6
7
|
import { type StageToolContext } from './stage-tool.ts';
|
|
7
8
|
export declare const MERGE_STAGE_TOOL_NAME = "merge_stage";
|
|
8
|
-
export
|
|
9
|
-
readonly name: string;
|
|
10
|
-
readonly description: string;
|
|
11
|
-
readonly parameters: Record<string, unknown>;
|
|
12
|
-
readonly output: {
|
|
13
|
-
readonly schema: Record<string, unknown>;
|
|
14
|
-
readonly render: (args: unknown, value: string) => readonly {
|
|
15
|
-
readonly type: 'text';
|
|
16
|
-
readonly text: string;
|
|
17
|
-
}[];
|
|
18
|
-
};
|
|
19
|
-
readonly execute: (args: Record<string, unknown>, exec: unknown) => Promise<string>;
|
|
20
|
-
}
|
|
21
|
-
export declare function createMergeStageTool(io: EvolutionIoLike, home: string, context: (exec: unknown) => StageToolContext | undefined, diagnose?: (exec: unknown) => unknown): ToolDefinitionLike;
|
|
9
|
+
export declare function createMergeStageTool(io: EvolutionIoLike, home: string, context: (exec: unknown) => StageToolContext | undefined, diagnose?: (exec: unknown) => unknown): ReturnType<typeof defineTool>;
|
|
22
10
|
//# sourceMappingURL=merge-tool.d.ts.map
|
package/lib/types/merge-tool.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { defineTool } from '@lmzhen/dsh-evolution-core/platform';
|
|
1
2
|
import { applyStageTool } from "./stage-tool.js";
|
|
2
3
|
export const MERGE_STAGE_TOOL_NAME = 'merge_stage';
|
|
3
4
|
function shapeError(message) {
|
|
@@ -34,22 +35,17 @@ function operation(args) {
|
|
|
34
35
|
return shapeError('op must be list/read/write/copy');
|
|
35
36
|
}
|
|
36
37
|
export function createMergeStageTool(io, home, context, diagnose) {
|
|
37
|
-
return {
|
|
38
|
+
return defineTool({
|
|
38
39
|
name: MERGE_STAGE_TOOL_NAME,
|
|
39
40
|
description: 'Read source copies and write the merged skill into the staging tree. list/read use area=sources|merged plus source (for sources); write/copy paths are relative to merged/<target> (for example path=SKILL.md, from=SKILL.md, to=references/x.md). Write/copy are only allowed in the author phase.',
|
|
40
41
|
parameters: {
|
|
41
|
-
type: '
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
from: { type: 'string' },
|
|
49
|
-
to: { type: 'string' },
|
|
50
|
-
},
|
|
51
|
-
required: ['op'],
|
|
52
|
-
additionalProperties: false,
|
|
42
|
+
op: { type: 'string', required: true, enum: ['list', 'read', 'write', 'copy'] },
|
|
43
|
+
area: { type: 'string', enum: ['sources', 'merged'] },
|
|
44
|
+
path: { type: 'string' },
|
|
45
|
+
source: { type: 'string' },
|
|
46
|
+
content: { type: 'string' },
|
|
47
|
+
from: { type: 'string' },
|
|
48
|
+
to: { type: 'string' },
|
|
53
49
|
},
|
|
54
50
|
output: {
|
|
55
51
|
schema: { type: 'string' },
|
|
@@ -64,6 +60,6 @@ export function createMergeStageTool(io, home, context, diagnose) {
|
|
|
64
60
|
return JSON.stringify({ ok: false, code: 'not-merge-child', message: 'merge_stage is only available to an active merge child', ...(diagnose === undefined ? {} : { diagnostic: diagnose(exec) }) });
|
|
65
61
|
return JSON.stringify(await applyStageTool(io, home, ctx, op));
|
|
66
62
|
},
|
|
67
|
-
};
|
|
63
|
+
});
|
|
68
64
|
}
|
|
69
65
|
//# sourceMappingURL=merge-tool.js.map
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lmzhen/dsh-evolution-merge",
|
|
3
3
|
"description": "Skill auto-merge domain: screening, two-round authoring, queues and commit orchestration (community build)",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.38.0",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -32,14 +32,15 @@
|
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@deepseek-ai/schemastery": "^3.18.5",
|
|
35
|
-
"@lmzhen/dsh-evolution-core": "^0.
|
|
36
|
-
"@lmzhen/dsh-evolution-commands": "^0.
|
|
37
|
-
"@lmzhen/dsh-evolution-merge-engine": "0.
|
|
35
|
+
"@lmzhen/dsh-evolution-core": "^0.38.0",
|
|
36
|
+
"@lmzhen/dsh-evolution-commands": "^0.38.0",
|
|
37
|
+
"@lmzhen/dsh-evolution-merge-engine": "0.38.0"
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|
|
40
|
-
"@deepseek-ai/cordis": "^4.0.5"
|
|
40
|
+
"@deepseek-ai/cordis": "^4.0.5",
|
|
41
|
+
"@deepseek-ai/dsh-llm": "^0.2.2-rc.0"
|
|
41
42
|
},
|
|
42
43
|
"engines": {
|
|
43
|
-
"dsh": ">=0.2.
|
|
44
|
+
"dsh": ">=0.2.2-rc.0 <0.2.3-0"
|
|
44
45
|
}
|
|
45
46
|
}
|