@lmzhen/dsh-evolution-feedback 0.1.0-rc.1
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 +24 -0
- package/lib/index.js +110 -0
- package/lib/invariant.js +8 -0
- package/lib/types/index.d.ts +51 -0
- package/lib/types/invariant.d.ts +5 -0
- package/package.json +50 -0
package/README.md
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# @deepseek-ai/dsh-evolution-feedback
|
|
2
|
+
|
|
3
|
+
Feedback-to-quality scoring for self-evolution
|
|
4
|
+
|
|
5
|
+
## Model Experience
|
|
6
|
+
|
|
7
|
+
### Indirect model surface
|
|
8
|
+
|
|
9
|
+
#### What the model sees
|
|
10
|
+
|
|
11
|
+
`@deepseek-ai/dsh-evolution-feedback` registers no direct prompt or tool schema itself. Model-visible effects are owned by the packages that consume this service.
|
|
12
|
+
|
|
13
|
+
#### Token effect
|
|
14
|
+
|
|
15
|
+
Zero direct token effect from this package; consumers add any model-visible tokens.
|
|
16
|
+
|
|
17
|
+
#### KV Cache effect
|
|
18
|
+
|
|
19
|
+
Independent of request-prefix construction. This package does not alter the assembled prompt or tool list.
|
|
20
|
+
|
|
21
|
+
## Known Limitations and Deferred Work
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
- - Persists through the IO seam; quality propagation into skill usage requires the `skillUsage` service.
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import z from "@deepseek-ai/schemastery";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
//#region lib/types/index.js
|
|
5
|
+
/**
|
|
6
|
+
* Feedback-to-quality scoring for self-evolution.
|
|
7
|
+
*
|
|
8
|
+
* Feedback is durable through `ctx.evolutionIo` (when mounted) and skill
|
|
9
|
+
* feedback feeds `quality_score` / `quality_warn` on the usage record, so
|
|
10
|
+
* curator decisions can consume it deterministically.
|
|
11
|
+
* @module @lmzhen/dsh-evolution-feedback
|
|
12
|
+
*/
|
|
13
|
+
var EvolutionFeedback = class {
|
|
14
|
+
state = {
|
|
15
|
+
skills: {},
|
|
16
|
+
sessions: {}
|
|
17
|
+
};
|
|
18
|
+
chain = Promise.resolve();
|
|
19
|
+
path;
|
|
20
|
+
constructor(io, home = process.env.DSH_HOME ?? join(homedir(), ".dsh"), pathOverride) {
|
|
21
|
+
if (io) this.path = pathOverride ?? join(home, "evolution", "feedback.json");
|
|
22
|
+
}
|
|
23
|
+
mutate(task) {
|
|
24
|
+
const run = this.chain.then(task, task);
|
|
25
|
+
this.chain = run.then(() => void 0, () => void 0);
|
|
26
|
+
return run;
|
|
27
|
+
}
|
|
28
|
+
async restore(io) {
|
|
29
|
+
const path = this.path;
|
|
30
|
+
if (!path) return;
|
|
31
|
+
await this.mutate(async () => {
|
|
32
|
+
const raw = await io.readText(path);
|
|
33
|
+
if (raw === null) return;
|
|
34
|
+
try {
|
|
35
|
+
const parsed = JSON.parse(raw);
|
|
36
|
+
this.state = {
|
|
37
|
+
skills: { ...parsed.skills },
|
|
38
|
+
sessions: { ...parsed.sessions }
|
|
39
|
+
};
|
|
40
|
+
} catch {}
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
record(target, rating, note, kind = "session", io) {
|
|
44
|
+
const table = kind === "skill" ? this.state.skills : this.state.sessions;
|
|
45
|
+
const current = table[target] ?? {
|
|
46
|
+
positive: 0,
|
|
47
|
+
negative: 0
|
|
48
|
+
};
|
|
49
|
+
current[rating] += 1;
|
|
50
|
+
if (note !== void 0) current.lastNote = note;
|
|
51
|
+
table[target] = current;
|
|
52
|
+
if (io && this.path) this.flush(io);
|
|
53
|
+
}
|
|
54
|
+
score(target, kind = "session") {
|
|
55
|
+
const record = (kind === "skill" ? this.state.skills : this.state.sessions)[target];
|
|
56
|
+
if (!record) return 0;
|
|
57
|
+
const total = record.positive + record.negative;
|
|
58
|
+
if (total === 0) return 0;
|
|
59
|
+
return (record.positive - record.negative) / total;
|
|
60
|
+
}
|
|
61
|
+
snapshot() {
|
|
62
|
+
return {
|
|
63
|
+
skills: { ...this.state.skills },
|
|
64
|
+
sessions: { ...this.state.sessions }
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
async flush(io) {
|
|
68
|
+
const path = this.path;
|
|
69
|
+
if (!path || !io) return;
|
|
70
|
+
await this.mutate(async () => {
|
|
71
|
+
await io.writeText(path, JSON.stringify(this.state, null, 2));
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
const name = "evolution-feedback";
|
|
76
|
+
const Config = z.object({
|
|
77
|
+
qualityWarnThreshold: z.number().default(-.25),
|
|
78
|
+
path: z.string().default("")
|
|
79
|
+
});
|
|
80
|
+
function apply(ctx, rawConfig = {}) {
|
|
81
|
+
const ioRegistry = ctx.get("evolutionIo");
|
|
82
|
+
const io = ioRegistry ? {
|
|
83
|
+
readText: (path) => ioRegistry.provider().readText(path),
|
|
84
|
+
writeText: (path, content) => ioRegistry.provider().writeText(path, content)
|
|
85
|
+
} : void 0;
|
|
86
|
+
const feedback = new EvolutionFeedback(io, process.env.DSH_HOME ?? join(homedir(), ".dsh"), rawConfig.path || void 0);
|
|
87
|
+
if (io) feedback.restore(io).catch((error) => {
|
|
88
|
+
ctx.logger.warn(error);
|
|
89
|
+
});
|
|
90
|
+
ctx.provide("evolutionFeedback", feedback);
|
|
91
|
+
const skillUsage = ctx.get("skillUsage");
|
|
92
|
+
if (skillUsage) {
|
|
93
|
+
const original = feedback.record.bind(feedback);
|
|
94
|
+
feedback.record = (target, rating, note, kind, recordIo) => {
|
|
95
|
+
original(target, rating, note, kind ?? "session", recordIo ?? io);
|
|
96
|
+
if (kind === "skill") {
|
|
97
|
+
const score = feedback.score(target, "skill");
|
|
98
|
+
const warn = score < (rawConfig.qualityWarnThreshold ?? -.25);
|
|
99
|
+
skillUsage.setQuality(target, score, warn).catch((error) => {
|
|
100
|
+
ctx.logger.warn(error);
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
ctx.effect(() => () => {
|
|
106
|
+
if (io) feedback.flush(io);
|
|
107
|
+
}, "evolution-feedback.flush");
|
|
108
|
+
}
|
|
109
|
+
//#endregion
|
|
110
|
+
export { Config, EvolutionFeedback, EvolutionFeedback as default, apply, name };
|
package/lib/invariant.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
//#region lib/types/invariant.js
|
|
2
|
+
const PACKAGE_NAME = "@deepseek-ai/dsh-evolution-feedback";
|
|
3
|
+
const name = "evolution-feedback-invariant";
|
|
4
|
+
const inject = ["invariants"];
|
|
5
|
+
const install = () => {};
|
|
6
|
+
const apply = (ctx) => Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install));
|
|
7
|
+
//#endregion
|
|
8
|
+
export { apply, inject, name };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Feedback-to-quality scoring for self-evolution.
|
|
3
|
+
*
|
|
4
|
+
* Feedback is durable through `ctx.evolutionIo` (when mounted) and skill
|
|
5
|
+
* feedback feeds `quality_score` / `quality_warn` on the usage record, so
|
|
6
|
+
* curator decisions can consume it deterministically.
|
|
7
|
+
* @module @deepseek-ai/dsh-evolution-feedback
|
|
8
|
+
*/
|
|
9
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
10
|
+
import z from '@deepseek-ai/schemastery';
|
|
11
|
+
declare module '@deepseek-ai/cordis' {
|
|
12
|
+
interface Context {
|
|
13
|
+
evolutionFeedback: EvolutionFeedback;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export interface FeedbackRecord {
|
|
17
|
+
positive: number;
|
|
18
|
+
negative: number;
|
|
19
|
+
lastNote?: string | undefined;
|
|
20
|
+
}
|
|
21
|
+
export interface FeedbackState {
|
|
22
|
+
skills: Record<string, FeedbackRecord>;
|
|
23
|
+
sessions: Record<string, FeedbackRecord>;
|
|
24
|
+
}
|
|
25
|
+
interface IoLike {
|
|
26
|
+
readText(path: string): Promise<string | null>;
|
|
27
|
+
writeText(path: string, content: string): Promise<void>;
|
|
28
|
+
}
|
|
29
|
+
export declare class EvolutionFeedback {
|
|
30
|
+
private state;
|
|
31
|
+
private chain;
|
|
32
|
+
private readonly path?;
|
|
33
|
+
constructor(io?: IoLike, home?: string, pathOverride?: string);
|
|
34
|
+
private mutate;
|
|
35
|
+
restore(io: IoLike): Promise<void>;
|
|
36
|
+
record(target: string, rating: 'positive' | 'negative', note?: string, kind?: 'skill' | 'session', io?: IoLike): void;
|
|
37
|
+
score(target: string, kind?: 'skill' | 'session'): number;
|
|
38
|
+
snapshot(): FeedbackState;
|
|
39
|
+
flush(io?: IoLike): Promise<void>;
|
|
40
|
+
}
|
|
41
|
+
export declare const name = "evolution-feedback";
|
|
42
|
+
export interface Config {
|
|
43
|
+
/** Score below which curator receives quality_warn for a skill. */
|
|
44
|
+
qualityWarnThreshold?: number;
|
|
45
|
+
/** Explicit feedback file path; empty derives $DSH_HOME/evolution/feedback.json. */
|
|
46
|
+
path?: string;
|
|
47
|
+
}
|
|
48
|
+
export declare const Config: z<Config>;
|
|
49
|
+
export declare function apply(ctx: Context, rawConfig?: Config): void;
|
|
50
|
+
export default EvolutionFeedback;
|
|
51
|
+
//# sourceMappingURL=index.d.ts.map
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@lmzhen/dsh-evolution-feedback",
|
|
3
|
+
"description": "Feedback-to-quality scoring for self-evolution (community build)",
|
|
4
|
+
"version": "0.1.0-rc.1",
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "public"
|
|
7
|
+
},
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/lmzhen/dsh-evolution.git",
|
|
11
|
+
"directory": "packages/dsh-evolution-feedback"
|
|
12
|
+
},
|
|
13
|
+
"type": "module",
|
|
14
|
+
"main": "lib/index.js",
|
|
15
|
+
"types": "lib/types/index.d.ts",
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./lib/types/index.d.ts",
|
|
19
|
+
"default": "./lib/index.js"
|
|
20
|
+
},
|
|
21
|
+
"./invariant": {
|
|
22
|
+
"types": "./lib/types/invariant.d.ts",
|
|
23
|
+
"default": "./lib/invariant.js"
|
|
24
|
+
},
|
|
25
|
+
"./package.json": "./package.json"
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"lib/index.js",
|
|
29
|
+
"lib/invariant.js",
|
|
30
|
+
"lib/types/**/*.d.ts",
|
|
31
|
+
"lib/types/invariant.d.ts"
|
|
32
|
+
],
|
|
33
|
+
"license": "MIT",
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"@deepseek-ai/schemastery": "^3.18.1"
|
|
36
|
+
},
|
|
37
|
+
"peerDependencies": {
|
|
38
|
+
"@deepseek-ai/dsh-invariants": "^0.1.0-rc.6",
|
|
39
|
+
"@deepseek-ai/cordis": "^4.0.1",
|
|
40
|
+
"@lmzhen/dsh-evolution-io": "^0.1.0-rc.1",
|
|
41
|
+
"@lmzhen/dsh-skill-usage": "^0.1.0-rc.1"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@deepseek-ai/dsh-invariants": "^0.1.0-rc.6",
|
|
45
|
+
"@lmzhen/dsh-evolution-io": "^0.1.0-rc.1",
|
|
46
|
+
"@lmzhen/dsh-evolution-io-node": "^0.1.0-rc.1",
|
|
47
|
+
"@lmzhen/dsh-skill-usage": "^0.1.0-rc.1",
|
|
48
|
+
"@lmzhen/dsh-evolution": "^0.1.0-rc.1"
|
|
49
|
+
}
|
|
50
|
+
}
|