@lmzhen/dsh-skill-usage 0.1.0-rc.49 → 0.1.0-rc.50
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 +27 -27
- package/lib/types/index.d.ts +10 -7
- package/package.json +5 -5
package/lib/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Service } from "@deepseek-ai/cordis";
|
|
2
2
|
import z from "@deepseek-ai/schemastery";
|
|
3
|
-
import { bumpPatch, bumpUse, bumpView, evolutionIoAdapter, getRecord, loadUsage, markAgentCreated,
|
|
3
|
+
import { bumpPatch, bumpUse, bumpView, evolutionIoAdapter, getRecord, loadUsage, markAgentCreated, mutateUsage, skillsRoot } from "@lmzhen/dsh-evolution-core";
|
|
4
4
|
//#region lib/types/index.js
|
|
5
5
|
/**
|
|
6
6
|
* Skill usage telemetry service for the evolution family.
|
|
@@ -11,41 +11,45 @@ var SkillUsageRegistry = class extends Service {
|
|
|
11
11
|
static Config = z.object({ root: z.string().default("") });
|
|
12
12
|
root;
|
|
13
13
|
io;
|
|
14
|
-
usage = null;
|
|
15
14
|
chain = Promise.resolve();
|
|
16
15
|
constructor(ctx, config = {}) {
|
|
17
16
|
super(ctx, "skillUsage");
|
|
18
17
|
this.root = config.root || skillsRoot();
|
|
19
18
|
this.io = evolutionIoAdapter(() => ctx.evolutionIo.provider());
|
|
20
19
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
28
|
-
/** Serialize read-modify-write cycles so concurrent record calls never lose updates. */
|
|
20
|
+
/**
|
|
21
|
+
* Serialize read-modify-write cycles so concurrent record calls never lose
|
|
22
|
+
* updates, then run each cycle as ONE atomic transact (rc.50 P2-2): the map
|
|
23
|
+
* is read from disk inside the lock, so a second process that shares
|
|
24
|
+
* DSH_HOME cannot interleave its own RMW between our read and write.
|
|
25
|
+
*/
|
|
29
26
|
mutate(task) {
|
|
30
|
-
const run = this.chain.then(async () =>
|
|
27
|
+
const run = this.chain.then(async () => {
|
|
28
|
+
let outcome = void 0;
|
|
29
|
+
await mutateUsage(this.root, this.io, async (map) => {
|
|
30
|
+
outcome = await task(map);
|
|
31
|
+
});
|
|
32
|
+
return outcome;
|
|
33
|
+
});
|
|
31
34
|
this.chain = run.then(() => void 0, () => void 0);
|
|
32
35
|
return run;
|
|
33
36
|
}
|
|
34
37
|
async record(name, kind, at = /* @__PURE__ */ new Date()) {
|
|
35
|
-
await this.mutate(
|
|
38
|
+
await this.mutate((map) => {
|
|
36
39
|
if (kind === "use") bumpUse(map, name, at);
|
|
37
40
|
else if (kind === "view") bumpView(map, name, at);
|
|
38
41
|
else bumpPatch(map, name, at);
|
|
39
|
-
await this.flush();
|
|
40
42
|
});
|
|
41
43
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
+
/** Read-only snapshot of the sidecar (no disk write — reading never mutates). */
|
|
45
|
+
async report() {
|
|
46
|
+
const run = this.chain.then(async () => new Map(await loadUsage(this.root, this.io)));
|
|
47
|
+
this.chain = run.then(() => void 0, () => void 0);
|
|
48
|
+
return run;
|
|
44
49
|
}
|
|
45
50
|
async markAgentCreated(name) {
|
|
46
|
-
await this.mutate(
|
|
51
|
+
await this.mutate((map) => {
|
|
47
52
|
markAgentCreated(map, name);
|
|
48
|
-
await this.flush();
|
|
49
53
|
});
|
|
50
54
|
}
|
|
51
55
|
/**
|
|
@@ -55,9 +59,8 @@ var SkillUsageRegistry = class extends Service {
|
|
|
55
59
|
* mutation maturity is not inflated by mere creation.
|
|
56
60
|
*/
|
|
57
61
|
async ensureRecord(name) {
|
|
58
|
-
await this.mutate(
|
|
62
|
+
await this.mutate((map) => {
|
|
59
63
|
getRecord(map, name);
|
|
60
|
-
await this.flush();
|
|
61
64
|
});
|
|
62
65
|
}
|
|
63
66
|
/**
|
|
@@ -66,32 +69,29 @@ var SkillUsageRegistry = class extends Service {
|
|
|
66
69
|
* a state transition, not a content mutation.
|
|
67
70
|
*/
|
|
68
71
|
async markArchived(name, at = /* @__PURE__ */ new Date()) {
|
|
69
|
-
await this.mutate(
|
|
72
|
+
await this.mutate((map) => {
|
|
70
73
|
const record = map.get(name);
|
|
71
74
|
if (record) {
|
|
72
75
|
record.state = "archived";
|
|
73
76
|
record.archived_at = at.toISOString();
|
|
74
77
|
}
|
|
75
|
-
await this.flush();
|
|
76
78
|
});
|
|
77
79
|
}
|
|
78
80
|
/**
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
* next
|
|
81
|
+
* Barrier for external writers: every mutate reads the sidecar fresh from
|
|
82
|
+
* disk (rc.50 P2-2 transact), so a curator direct-write is visible on the
|
|
83
|
+
* next call without a cache flush; this waits for queued work to drain.
|
|
82
84
|
*/
|
|
83
85
|
async invalidate() {
|
|
84
86
|
await this.chain;
|
|
85
|
-
this.usage = null;
|
|
86
87
|
}
|
|
87
88
|
/** Write feedback-derived quality onto the usage sidecar; curator reads it. */
|
|
88
89
|
async setQuality(name, score, warn) {
|
|
89
|
-
await this.mutate(
|
|
90
|
+
await this.mutate((map) => {
|
|
90
91
|
const record = map.get(name);
|
|
91
92
|
if (!record) return;
|
|
92
93
|
record.quality_score = score;
|
|
93
94
|
record.quality_warn = warn;
|
|
94
|
-
await this.flush();
|
|
95
95
|
});
|
|
96
96
|
}
|
|
97
97
|
};
|
package/lib/types/index.d.ts
CHANGED
|
@@ -18,14 +18,17 @@ export declare class SkillUsageRegistry extends Service {
|
|
|
18
18
|
static Config: Schema<Config>;
|
|
19
19
|
readonly root: string;
|
|
20
20
|
private readonly io;
|
|
21
|
-
private usage;
|
|
22
21
|
private chain;
|
|
23
22
|
constructor(ctx: Context, config?: Config);
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
/**
|
|
24
|
+
* Serialize read-modify-write cycles so concurrent record calls never lose
|
|
25
|
+
* updates, then run each cycle as ONE atomic transact (rc.50 P2-2): the map
|
|
26
|
+
* is read from disk inside the lock, so a second process that shares
|
|
27
|
+
* DSH_HOME cannot interleave its own RMW between our read and write.
|
|
28
|
+
*/
|
|
27
29
|
private mutate;
|
|
28
30
|
record(name: string, kind: 'use' | 'view' | 'patch', at?: Date): Promise<void>;
|
|
31
|
+
/** Read-only snapshot of the sidecar (no disk write — reading never mutates). */
|
|
29
32
|
report(): Promise<UsageMap>;
|
|
30
33
|
markAgentCreated(name: string): Promise<void>;
|
|
31
34
|
/**
|
|
@@ -42,9 +45,9 @@ export declare class SkillUsageRegistry extends Service {
|
|
|
42
45
|
*/
|
|
43
46
|
markArchived(name: string, at?: Date): Promise<void>;
|
|
44
47
|
/**
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
* next
|
|
48
|
+
* Barrier for external writers: every mutate reads the sidecar fresh from
|
|
49
|
+
* disk (rc.50 P2-2 transact), so a curator direct-write is visible on the
|
|
50
|
+
* next call without a cache flush; this waits for queued work to drain.
|
|
48
51
|
*/
|
|
49
52
|
invalidate(): Promise<void>;
|
|
50
53
|
/** Write feedback-derived quality onto the usage sidecar; curator reads it. */
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lmzhen/dsh-skill-usage",
|
|
3
3
|
"description": "Skill usage telemetry service (community build)",
|
|
4
|
-
"version": "0.1.0-rc.
|
|
4
|
+
"version": "0.1.0-rc.50",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -33,16 +33,16 @@
|
|
|
33
33
|
"license": "MIT",
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"@deepseek-ai/schemastery": "^3.18.1",
|
|
36
|
-
"@lmzhen/dsh-evolution-core": "^0.1.0-rc.
|
|
36
|
+
"@lmzhen/dsh-evolution-core": "^0.1.0-rc.50"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
39
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
40
40
|
"@deepseek-ai/dsh-invariants": "^0.1.0-rc.6",
|
|
41
|
-
"@lmzhen/dsh-evolution-io": "^0.1.0-rc.
|
|
41
|
+
"@lmzhen/dsh-evolution-io": "^0.1.0-rc.50"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"@deepseek-ai/dsh-invariants": "^0.1.0-rc.6",
|
|
45
|
-
"@lmzhen/dsh-evolution-core": "^0.1.0-rc.
|
|
46
|
-
"@lmzhen/dsh-evolution-io": "^0.1.0-rc.
|
|
45
|
+
"@lmzhen/dsh-evolution-core": "^0.1.0-rc.50",
|
|
46
|
+
"@lmzhen/dsh-evolution-io": "^0.1.0-rc.50"
|
|
47
47
|
}
|
|
48
48
|
}
|