@lmzhen/dsh-tool-skill-manage 0.11.3 → 0.13.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/README.md +19 -6
- package/lib/index.js +90 -11
- package/lib/types/index.d.ts +10 -0
- package/lib/types/write-gates.d.ts +29 -0
- package/package.json +8 -8
package/README.md
CHANGED
|
@@ -34,12 +34,25 @@ write whose target the session never read is refused with `E-318`, and only a re
|
|
|
34
34
|
counts. A session log the tool cannot read proceeds with one warning rather than blocking every
|
|
35
35
|
autonomous write.
|
|
36
36
|
|
|
37
|
-
A foreground `create`, or a bare foreground `delete`,
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
37
|
+
A foreground `create`, or a bare foreground `delete`, is the ONE write this tool puts to a human
|
|
38
|
+
before writing; a `delete` carrying `absorbed_into` is the merge protocol and does not ask. WHAT
|
|
39
|
+
that confirmation does is the `skillWriteConfirm` parameter (`/evolution params`, and the
|
|
40
|
+
技能写入规则 card):
|
|
41
|
+
|
|
42
|
+
| Mode | What happens |
|
|
43
|
+
|---|---|
|
|
44
|
+
| `auto` (**the default**) | the write proceeds with no prompt — an unattended run (a background pass, a scheduled review, a headless session) must not park a tool call on a question nobody will answer |
|
|
45
|
+
| `ask` | the question waits for as long as it takes; the answer is `Create`/`Delete` to proceed, `Cancel` (or a dismissed card) to refuse with `E-317` |
|
|
46
|
+
| `timeout` | the question is asked with a deadline of `skillWriteConfirmTimeoutSeconds` (default 120 s); an unanswered prompt cancels the write with `E-319`, which names the three knobs |
|
|
47
|
+
|
|
48
|
+
The deadline is enforced by the gate itself, not only by the abort signal it hands the question
|
|
49
|
+
service: a prompt that outlives it returns anyway, and the timer is unref'd and cleared, so an
|
|
50
|
+
answered prompt leaves neither a parked call nor a live timer behind. This gate is UX, not a
|
|
51
|
+
security door: it is admission-only (a replayed record already carries the human release that staged
|
|
52
|
+
it), and — in the two modes that ask at all — an unmounted question service, a caller that is not
|
|
53
|
+
the registry's exact live root agent, or a failing ask all PROCEED with one warning. The shipped
|
|
54
|
+
`auto` mode asks nothing, so it never reaches those fallbacks; the operator's own session stays the
|
|
55
|
+
authority that asked for the write.
|
|
43
56
|
|
|
44
57
|
### Approval seam
|
|
45
58
|
|
package/lib/index.js
CHANGED
|
@@ -32,6 +32,16 @@ import { DEFAULT_ARCHIVE_RETENTION_POLICY, DEFAULT_CITATION_POLICY, DEFAULT_REFE
|
|
|
32
32
|
const CONFIRM_QUESTION_ID = "evolution-skill-write";
|
|
33
33
|
/** The cancel label every confirm question offers. */
|
|
34
34
|
const CANCEL_LABEL = "Cancel";
|
|
35
|
+
/** What a `timeout`-mode deadline settles with: comparable by identity against the seam's
|
|
36
|
+
* boolean, so the two outcomes stay distinguishable without a mutable flag (which a linter
|
|
37
|
+
* cannot follow through a timer callback, and a reader cannot either). */
|
|
38
|
+
const CONFIRM_TIMED_OUT = "confirm-timed-out";
|
|
39
|
+
/** The mode a deployment that configures nothing gets. */
|
|
40
|
+
const DEFAULT_WRITE_CONFIRM_MODE = "auto";
|
|
41
|
+
/** A usable deadline: the configured value when it is a positive finite number, else the default. */
|
|
42
|
+
function timeoutSecondsOf(configured) {
|
|
43
|
+
return configured !== void 0 && Number.isFinite(configured) && configured >= 1 ? Math.floor(configured) : 120;
|
|
44
|
+
}
|
|
35
45
|
/** The scalar fields the tool schema types as strings; the replay channel has no schema.
|
|
36
46
|
* `action` is one of them: a non-string action used to fall through to the library as "Unknown
|
|
37
47
|
* action" while the read gate re-defaulted it to `patch` and refused with E-318 (review
|
|
@@ -120,26 +130,54 @@ const GATES = [
|
|
|
120
130
|
{
|
|
121
131
|
id: "human-confirm",
|
|
122
132
|
appliesTo: ["admission"],
|
|
123
|
-
run: async ({ view, origin, confirm, warn }) => {
|
|
133
|
+
run: async ({ view, origin, confirm, warn, confirmMode, confirmTimeoutSeconds, describeTarget }) => {
|
|
124
134
|
const action = view.action;
|
|
125
135
|
if (action === void 0 || origin !== "foreground" || view.name === "") return null;
|
|
126
136
|
if (!(action === "create" || action === "delete" && view.absorbedInto === void 0)) return null;
|
|
137
|
+
const mode = confirmMode ?? "auto";
|
|
138
|
+
if (mode === "auto") return null;
|
|
127
139
|
if (confirm === void 0) {
|
|
128
140
|
warn("skill_manage: no confirmation channel is mounted, so the write proceeds unconfirmed.");
|
|
129
141
|
return null;
|
|
130
142
|
}
|
|
131
143
|
const confirmLabel = action === "create" ? "Create" : "Delete";
|
|
132
|
-
|
|
144
|
+
const seconds = timeoutSecondsOf(confirmTimeoutSeconds);
|
|
145
|
+
const cancel = new AbortController();
|
|
146
|
+
let timer;
|
|
147
|
+
const deadline = mode === "timeout" ? new Promise((resolve) => {
|
|
148
|
+
timer = setTimeout(() => {
|
|
149
|
+
cancel.abort();
|
|
150
|
+
resolve(CONFIRM_TIMED_OUT);
|
|
151
|
+
}, seconds * 1e3);
|
|
152
|
+
timer.unref();
|
|
153
|
+
}) : void 0;
|
|
154
|
+
const context = await describeTarget?.();
|
|
155
|
+
const details = [context?.description === void 0 || context.description === "" ? null : "What it does: " + context.description, context?.versions === void 0 ? null : "Content versions recorded: " + String(context.versions)].filter((line) => line !== null);
|
|
156
|
+
const consequence = action === "create" ? `Create skill "${view.name}"? A new skill directory is written into the family tree.` : `Delete skill "${view.name}"? It is archived under .archive and leaves the catalog.`;
|
|
157
|
+
const asked = confirm({
|
|
133
158
|
action,
|
|
134
159
|
name: view.name,
|
|
135
160
|
confirmLabel,
|
|
136
161
|
question: {
|
|
137
162
|
id: CONFIRM_QUESTION_ID,
|
|
138
163
|
header: "Confirm",
|
|
139
|
-
question:
|
|
164
|
+
question: details.length === 0 ? consequence : consequence + " " + details.join(" · "),
|
|
140
165
|
options: [{ label: confirmLabel }, { label: CANCEL_LABEL }]
|
|
141
|
-
}
|
|
142
|
-
|
|
166
|
+
},
|
|
167
|
+
...mode === "timeout" ? { signal: cancel.signal } : {}
|
|
168
|
+
});
|
|
169
|
+
let outcome;
|
|
170
|
+
try {
|
|
171
|
+
outcome = deadline === void 0 ? await asked : await Promise.race([asked, deadline]);
|
|
172
|
+
} finally {
|
|
173
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
174
|
+
}
|
|
175
|
+
if (outcome === true) return null;
|
|
176
|
+
if (outcome === CONFIRM_TIMED_OUT || cancel.signal.aborted) return errorText("e-319-skill-write-confirm-timed-out", {
|
|
177
|
+
a1: view.name,
|
|
178
|
+
a2: action === "create" ? "created" : "deleted",
|
|
179
|
+
a3: String(seconds)
|
|
180
|
+
});
|
|
143
181
|
return errorText("e-317-skill-write-not-confirmed", {
|
|
144
182
|
a1: view.name,
|
|
145
183
|
a2: action === "create" ? "created" : "deleted"
|
|
@@ -214,7 +252,13 @@ const Config = z.object({
|
|
|
214
252
|
descriptionStrict: z.boolean().default(false),
|
|
215
253
|
threatExemptLabels: z.array(z.string()).default([]),
|
|
216
254
|
strictCrossSource: z.boolean().default(false),
|
|
217
|
-
skillVersionKeep: z.number().min(1).default(DEFAULT_SKILL_LIMITS.versionKeep ?? DEFAULT_SKILL_VERSION_KEEP)
|
|
255
|
+
skillVersionKeep: z.number().min(1).default(DEFAULT_SKILL_LIMITS.versionKeep ?? DEFAULT_SKILL_VERSION_KEEP),
|
|
256
|
+
skillWriteConfirm: z.union([
|
|
257
|
+
z.const("auto"),
|
|
258
|
+
z.const("ask"),
|
|
259
|
+
z.const("timeout")
|
|
260
|
+
]).default(DEFAULT_WRITE_CONFIRM_MODE),
|
|
261
|
+
skillWriteConfirmTimeoutSeconds: z.number().min(1).default(120)
|
|
218
262
|
});
|
|
219
263
|
/** Schema the platform validates the user layer against; defaults mirror the core
|
|
220
264
|
* constants and the row schema, so an empty document resolves to today's behaviour. */
|
|
@@ -226,7 +270,13 @@ const SKILLS_SETTINGS_SCHEMA = z.object({
|
|
|
226
270
|
descriptionStrict: z.boolean().default(false),
|
|
227
271
|
strictCrossSource: z.boolean().default(false),
|
|
228
272
|
citationPolicy: z.union([z.const("verify"), z.const("refuse")]).default(DEFAULT_CITATION_POLICY),
|
|
229
|
-
supportFileCharPolicy: z.union([z.const("report"), z.const("enforce")]).default(DEFAULT_SUPPORT_FILE_CHAR_POLICY)
|
|
273
|
+
supportFileCharPolicy: z.union([z.const("report"), z.const("enforce")]).default(DEFAULT_SUPPORT_FILE_CHAR_POLICY),
|
|
274
|
+
skillWriteConfirm: z.union([
|
|
275
|
+
z.const("auto"),
|
|
276
|
+
z.const("ask"),
|
|
277
|
+
z.const("timeout")
|
|
278
|
+
]).default(DEFAULT_WRITE_CONFIRM_MODE),
|
|
279
|
+
skillWriteConfirmTimeoutSeconds: z.number().min(1).default(120)
|
|
230
280
|
});
|
|
231
281
|
/** The four caps a user may only tighten, in schema order (the sentry reads it). */
|
|
232
282
|
const SKILL_SETTINGS_CAPS = [
|
|
@@ -245,6 +295,18 @@ const SKILL_SETTINGS_CAPS = [
|
|
|
245
295
|
function validateSkillSettings(value, ceilings) {
|
|
246
296
|
for (const key of SKILL_SETTINGS_CAPS) if (value[key] > ceilings[key]) throw new Error(`${key} may only be tightened: ${value[key]} exceeds the deployment value ${ceilings[key]}`);
|
|
247
297
|
}
|
|
298
|
+
/** One abort signal that carries BOTH cancellations: the call's own (the operator cancelled the
|
|
299
|
+
* turn) and the gate's deadline (`skillWriteConfirm: 'timeout'`). `undefined` when neither exists —
|
|
300
|
+
* the platform's `ask()` then waits without a signal, which is the `ask` mode.
|
|
301
|
+
* @param call - this call's cancellation signal, when the exec context carries one.
|
|
302
|
+
* @param deadline - the gate's own deadline signal, when the mode imposes one.
|
|
303
|
+
* @returns the request field to spread, or undefined when neither signal exists.
|
|
304
|
+
*/
|
|
305
|
+
function combinedSignal(call, deadline) {
|
|
306
|
+
if (call === void 0) return deadline === void 0 ? void 0 : { signal: deadline };
|
|
307
|
+
if (deadline === void 0) return { signal: call };
|
|
308
|
+
return { signal: AbortSignal.any([call, deadline]) };
|
|
309
|
+
}
|
|
248
310
|
/** The platform error code a question-service failure carries, when it carries one. */
|
|
249
311
|
function questionErrorCode(error) {
|
|
250
312
|
const code = error?.code;
|
|
@@ -348,7 +410,7 @@ function apply(ctx, rawConfig = {}) {
|
|
|
348
410
|
options: request.question.options.map((option) => ({ label: option.label }))
|
|
349
411
|
}],
|
|
350
412
|
agent,
|
|
351
|
-
...exec.signal
|
|
413
|
+
...combinedSignal(exec.signal, request.signal) ?? {}
|
|
352
414
|
});
|
|
353
415
|
const declared = exec.agent;
|
|
354
416
|
if (declared !== void 0) try {
|
|
@@ -396,7 +458,9 @@ function apply(ctx, rawConfig = {}) {
|
|
|
396
458
|
descriptionStrict: rawConfig.descriptionStrict ?? false,
|
|
397
459
|
strictCrossSource: rawConfig.strictCrossSource ?? false,
|
|
398
460
|
citationPolicy: libraryLimits.citationPolicy ?? DEFAULT_CITATION_POLICY,
|
|
399
|
-
supportFileCharPolicy: libraryLimits.supportFileCharPolicy ?? DEFAULT_SUPPORT_FILE_CHAR_POLICY
|
|
461
|
+
supportFileCharPolicy: libraryLimits.supportFileCharPolicy ?? DEFAULT_SUPPORT_FILE_CHAR_POLICY,
|
|
462
|
+
skillWriteConfirm: rawConfig.skillWriteConfirm ?? "auto",
|
|
463
|
+
skillWriteConfirmTimeoutSeconds: rawConfig.skillWriteConfirmTimeoutSeconds ?? 120
|
|
400
464
|
};
|
|
401
465
|
const section = {};
|
|
402
466
|
const settings = () => {
|
|
@@ -412,7 +476,9 @@ function apply(ctx, rawConfig = {}) {
|
|
|
412
476
|
descriptionStrict: pick("descriptionStrict"),
|
|
413
477
|
strictCrossSource: pick("strictCrossSource"),
|
|
414
478
|
citationPolicy: overridden("citationPolicy") ?? stages.citationPolicy ?? settingsBase.citationPolicy,
|
|
415
|
-
supportFileCharPolicy: overridden("supportFileCharPolicy") ?? stages.supportFileCharPolicy ?? settingsBase.supportFileCharPolicy
|
|
479
|
+
supportFileCharPolicy: overridden("supportFileCharPolicy") ?? stages.supportFileCharPolicy ?? settingsBase.supportFileCharPolicy,
|
|
480
|
+
skillWriteConfirm: pick("skillWriteConfirm"),
|
|
481
|
+
skillWriteConfirmTimeoutSeconds: pick("skillWriteConfirmTimeoutSeconds")
|
|
416
482
|
};
|
|
417
483
|
};
|
|
418
484
|
const applyLimits = () => {
|
|
@@ -748,6 +814,19 @@ function apply(ctx, rawConfig = {}) {
|
|
|
748
814
|
protectedNames: protectedSkillNamesOf(),
|
|
749
815
|
readNames: sessionReadSkillNames(exec.agent?.session),
|
|
750
816
|
confirm: async (request) => confirmSkillWrite(request, exec),
|
|
817
|
+
confirmMode: settings().skillWriteConfirm,
|
|
818
|
+
confirmTimeoutSeconds: settings().skillWriteConfirmTimeoutSeconds,
|
|
819
|
+
describeTarget: async () => {
|
|
820
|
+
const versions = typeof args.name === "string" && args.name !== "" ? (await library.listVersions(args.name).catch(() => [])).length : 0;
|
|
821
|
+
const body = typeof args.content === "string" && args.content !== "" ? args.content : typeof args.name === "string" && args.name !== "" ? await library.read(args.name).catch(() => null) : null;
|
|
822
|
+
const frontmatter = body === null ? null : parseFrontmatter(body)?.frontmatter ?? null;
|
|
823
|
+
const parsedDescription = frontmatter === null ? void 0 : frontmatter.description;
|
|
824
|
+
const description = typeof parsedDescription === "string" ? parsedDescription : "";
|
|
825
|
+
return {
|
|
826
|
+
...description === "" ? {} : { description },
|
|
827
|
+
...versions === 0 ? {} : { versions }
|
|
828
|
+
};
|
|
829
|
+
},
|
|
751
830
|
warn: warnWriteGateOnce
|
|
752
831
|
});
|
|
753
832
|
if (refusal !== null) return {
|
|
@@ -786,7 +865,7 @@ function apply(ctx, rawConfig = {}) {
|
|
|
786
865
|
});
|
|
787
866
|
if (decision.action === "staged") return {
|
|
788
867
|
ok: true,
|
|
789
|
-
message: decision.message,
|
|
868
|
+
message: decision.pendingId === void 0 ? decision.message : decision.message + " (staged id: " + decision.pendingId + " — /evolution pending lists it)",
|
|
790
869
|
skills: [],
|
|
791
870
|
...decision.pendingId !== void 0 ? { pending_id: decision.pendingId } : {}
|
|
792
871
|
};
|
package/lib/types/index.d.ts
CHANGED
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
import type { Context } from '@deepseek-ai/cordis';
|
|
21
21
|
import z from '@deepseek-ai/schemastery';
|
|
22
22
|
import type { CitationPolicy, SupportFileCharPolicy } from '@lmzhen/dsh-evolution-core';
|
|
23
|
+
import { type WriteConfirmMode } from './write-gates.ts';
|
|
23
24
|
export declare const name = "tool-skill-manage";
|
|
24
25
|
export declare const inject: string[];
|
|
25
26
|
export interface Config {
|
|
@@ -50,6 +51,11 @@ export interface Config {
|
|
|
50
51
|
* like the four caps above — the settings layer deliberately has no card for it (retention is
|
|
51
52
|
* storage policy, not an authoring knob). */
|
|
52
53
|
skillVersionKeep?: number;
|
|
54
|
+
/** What the ONE confirmation before a create or a bare delete does (registry `skillWriteConfirm`).
|
|
55
|
+
* Default `auto`: an unattended run must not park a tool call on a question nobody will answer. */
|
|
56
|
+
skillWriteConfirm?: WriteConfirmMode;
|
|
57
|
+
/** Seconds a `timeout`-mode prompt waits for an answer before the write is cancelled. */
|
|
58
|
+
skillWriteConfirmTimeoutSeconds?: number;
|
|
53
59
|
}
|
|
54
60
|
export declare const Config: z<Config>;
|
|
55
61
|
/** Write behaviour a user may change (G3/S3.4). Field names are the CANONICAL
|
|
@@ -73,6 +79,10 @@ export interface SkillSettings {
|
|
|
73
79
|
citationPolicy: CitationPolicy;
|
|
74
80
|
/** Warn about an oversize support file, or refuse the write. */
|
|
75
81
|
supportFileCharPolicy: SupportFileCharPolicy;
|
|
82
|
+
/** What the confirmation before a create or a bare delete does (0.12.0). */
|
|
83
|
+
skillWriteConfirm: WriteConfirmMode;
|
|
84
|
+
/** Seconds a `timeout`-mode confirmation waits before the write is cancelled. */
|
|
85
|
+
skillWriteConfirmTimeoutSeconds: number;
|
|
76
86
|
}
|
|
77
87
|
/** Schema the platform validates the user layer against; defaults mirror the core
|
|
78
88
|
* constants and the row schema, so an empty document resolves to today's behaviour. */
|
|
@@ -25,6 +25,25 @@
|
|
|
25
25
|
import { type WriteOrigin } from '@lmzhen/dsh-evolution-core';
|
|
26
26
|
/** The point whose verdict is being taken. */
|
|
27
27
|
export type WriteGatePoint = 'admission' | 'execution';
|
|
28
|
+
/**
|
|
29
|
+
* How the ONE confirmation behaves (registry `skillWriteConfirm`).
|
|
30
|
+
*
|
|
31
|
+
* `auto` writes without asking — the default, because an unattended run (a background pass, a
|
|
32
|
+
* scheduled review, a headless session) must not park a tool call on a question nobody will answer.
|
|
33
|
+
* `ask` waits for as long as it takes, which is the deployment that wants the gate in the loop.
|
|
34
|
+
* `timeout` asks and cancels the write on its own deadline.
|
|
35
|
+
*/
|
|
36
|
+
export type WriteConfirmMode = 'auto' | 'ask' | 'timeout';
|
|
37
|
+
/** The mode a deployment that configures nothing gets. */
|
|
38
|
+
export declare const DEFAULT_WRITE_CONFIRM_MODE: WriteConfirmMode;
|
|
39
|
+
/** Seconds a `timeout`-mode prompt waits before the write is cancelled. */
|
|
40
|
+
export declare const DEFAULT_WRITE_CONFIRM_TIMEOUT_SECONDS = 120;
|
|
41
|
+
/** What the operator is told about the target before answering. Every field is optional: a target
|
|
42
|
+
* with no frontmatter, or one the library cannot read, simply carries less. */
|
|
43
|
+
export interface ConfirmContext {
|
|
44
|
+
readonly description?: string | undefined;
|
|
45
|
+
readonly versions?: number | undefined;
|
|
46
|
+
}
|
|
28
47
|
/** One confirm question, as the gate writes it and the seam asks it. */
|
|
29
48
|
export interface WriteConfirmRequest {
|
|
30
49
|
/** The action being confirmed (`create` or `delete`). */
|
|
@@ -42,6 +61,9 @@ export interface WriteConfirmRequest {
|
|
|
42
61
|
};
|
|
43
62
|
/** The option label that means "proceed". */
|
|
44
63
|
readonly confirmLabel: string;
|
|
64
|
+
/** A deadline the gate imposes on itself (`timeout` mode); the seam combines it with the call's
|
|
65
|
+
* own cancellation. An abort is a dismissal, never a consent. */
|
|
66
|
+
readonly signal?: AbortSignal;
|
|
45
67
|
}
|
|
46
68
|
/**
|
|
47
69
|
* Ask the human to confirm one irreversible skill write.
|
|
@@ -68,6 +90,13 @@ export interface WriteGateContext {
|
|
|
68
90
|
readonly readNames: ReadonlySet<string> | undefined;
|
|
69
91
|
/** The human confirm seam — read only by the gates that apply to `'admission'`. */
|
|
70
92
|
readonly confirm: WriteConfirm | undefined;
|
|
93
|
+
/** The registry's `skillWriteConfirm`: `auto` (the default) skips the question entirely. */
|
|
94
|
+
readonly confirmMode?: WriteConfirmMode;
|
|
95
|
+
/** The registry's `skillWriteConfirmTimeoutSeconds`, read only in `timeout` mode. */
|
|
96
|
+
readonly confirmTimeoutSeconds?: number;
|
|
97
|
+
/** Read the target's own words for the confirmation card. LAZY on purpose: a write that is not
|
|
98
|
+
* asked about must not pay a read for a question nobody sees. Absent means "say nothing extra". */
|
|
99
|
+
readonly describeTarget?: (() => Promise<ConfirmContext | undefined>) | undefined;
|
|
71
100
|
/** Report a degraded gate; must not throw. The implementation decides how often it speaks — the
|
|
72
101
|
* shipped seam latches once per PROCESS, because the conditions it reports (no question service,
|
|
73
102
|
* an unreadable session log) belong to the deployment, not to one write. */
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lmzhen/dsh-tool-skill-manage",
|
|
3
3
|
"description": "Model-facing skill_manage tool (community build)",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.13.0",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -27,24 +27,24 @@
|
|
|
27
27
|
"license": "MIT",
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@deepseek-ai/schemastery": "^3.18.1",
|
|
30
|
-
"@lmzhen/dsh-evolution-approval": "^0.
|
|
31
|
-
"@lmzhen/dsh-evolution-core": "^0.
|
|
30
|
+
"@lmzhen/dsh-evolution-approval": "^0.13.0",
|
|
31
|
+
"@lmzhen/dsh-evolution-core": "^0.13.0"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
34
34
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
35
35
|
"@deepseek-ai/dsh-skill": "^0.1.5-rc.2",
|
|
36
36
|
"@deepseek-ai/dsh-system-prompt": "^0.1.5-rc.2",
|
|
37
37
|
"@deepseek-ai/dsh-tools": "^0.1.5-rc.2",
|
|
38
|
-
"@lmzhen/dsh-evolution-io": "^0.
|
|
39
|
-
"@lmzhen/dsh-skill-usage": "^0.
|
|
38
|
+
"@lmzhen/dsh-evolution-io": "^0.13.0",
|
|
39
|
+
"@lmzhen/dsh-skill-usage": "^0.13.0"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@deepseek-ai/dsh-agent-loop-testkit": "^0.1.5-rc.2",
|
|
43
43
|
"@deepseek-ai/dsh-skill": "^0.1.5-rc.2",
|
|
44
44
|
"@deepseek-ai/dsh-system-prompt": "^0.1.5-rc.2",
|
|
45
45
|
"@deepseek-ai/dsh-tools": "^0.1.5-rc.2",
|
|
46
|
-
"@lmzhen/dsh-evolution-core": "^0.
|
|
47
|
-
"@lmzhen/dsh-evolution-io": "^0.
|
|
48
|
-
"@lmzhen/dsh-skill-usage": "^0.
|
|
46
|
+
"@lmzhen/dsh-evolution-core": "^0.13.0",
|
|
47
|
+
"@lmzhen/dsh-evolution-io": "^0.13.0",
|
|
48
|
+
"@lmzhen/dsh-skill-usage": "^0.13.0"
|
|
49
49
|
}
|
|
50
50
|
}
|