@lmzhen/dsh-evolution-feedback 0.3.62 → 0.3.64
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 +1 -0
- package/lib/index.js +33 -5
- package/lib/types/index.d.ts +24 -3
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -22,3 +22,4 @@ Independent of request-prefix construction. This package does not alter the asse
|
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
- Persists through the IO seam; quality propagation into skill usage requires the `skillUsage` service.
|
|
25
|
+
- P1-1 (v15): feedback writes the FEEDBACK-OWNED `feedback_score`/`feedback_warn` usage fields. The lifecycle engine and the scope view read the union `quality_warn || feedback_warn`, so a negative feedback shortens the stale window even though the curator's six-factor run always recomputes `quality_warn` itself.
|
package/lib/index.js
CHANGED
|
@@ -6,8 +6,15 @@ import { join } from "node:path";
|
|
|
6
6
|
* Feedback-to-quality scoring for self-evolution.
|
|
7
7
|
*
|
|
8
8
|
* Feedback is durable through `ctx.evolutionIo` (when mounted) and skill
|
|
9
|
-
* feedback feeds `
|
|
10
|
-
*
|
|
9
|
+
* feedback feeds the FEEDBACK-OWNED `feedback_score` / `feedback_warn` pair on
|
|
10
|
+
* the usage record. P1-1 (v15): this package used to write
|
|
11
|
+
* `quality_score`/`quality_warn` — but the curator's six-factor `scoreTree`
|
|
12
|
+
* overwrote those fields on every run BEFORE the lifecycle engine read them,
|
|
13
|
+
* so the advertised "curator decisions consume feedback deterministically"
|
|
14
|
+
* channel was dead. The lifecycle engine and the scope view now read the
|
|
15
|
+
* union `quality_warn || feedback_warn`, and the curator never writes the
|
|
16
|
+
* feedback pair (field-ownership contract on `UsageRecord` in
|
|
17
|
+
* evolution-core/usage.ts).
|
|
11
18
|
*
|
|
12
19
|
* Persistence (rc.68): the EVENTS LOG (`evolution/events.json`, via
|
|
13
20
|
* `evolution-core/evolution-events.ts`) is the single source of truth —
|
|
@@ -123,6 +130,18 @@ var EvolutionFeedback = class EvolutionFeedback {
|
|
|
123
130
|
} catch {}
|
|
124
131
|
});
|
|
125
132
|
}
|
|
133
|
+
/** External-producer contract (审计 B-4, v18): nothing inside the family
|
|
134
|
+
* calls `record` — the upstream `/feedback` command only appends a
|
|
135
|
+
* `feedback/record` session event carrying free text, which cannot be mapped
|
|
136
|
+
* to a (target, rating) pair without inventing semantics. A host that wants
|
|
137
|
+
* feedback-driven curation wires its own command/event to this method; the
|
|
138
|
+
* curator's union read (`feedback_warn`) then shortens the stale window.
|
|
139
|
+
* `feedback.spec.ts` pins that channel end to end.
|
|
140
|
+
* @param target - skill name or session id the rating belongs to.
|
|
141
|
+
* @param rating - `positive` or `negative`; other values are refused.
|
|
142
|
+
* @param note - optional free-text note carried into the durable event.
|
|
143
|
+
* @param kind - `skill` (default `session`) selects the score table.
|
|
144
|
+
*/
|
|
126
145
|
record(target, rating, note, kind = "session") {
|
|
127
146
|
const mode = kind === "skill" ? "skills" : "sessions";
|
|
128
147
|
const table = this.state[mode];
|
|
@@ -187,9 +206,14 @@ var EvolutionFeedback = class EvolutionFeedback {
|
|
|
187
206
|
return (record.positive - record.negative) / total;
|
|
188
207
|
}
|
|
189
208
|
snapshot() {
|
|
209
|
+
const copyRecords = (table) => {
|
|
210
|
+
const out = {};
|
|
211
|
+
for (const [key, record] of Object.entries(table)) out[key] = { ...record };
|
|
212
|
+
return out;
|
|
213
|
+
};
|
|
190
214
|
return {
|
|
191
|
-
skills:
|
|
192
|
-
sessions:
|
|
215
|
+
skills: copyRecords(this.state.skills),
|
|
216
|
+
sessions: copyRecords(this.state.sessions)
|
|
193
217
|
};
|
|
194
218
|
}
|
|
195
219
|
/** Await the pending record-task chain (unload safety; rc.66). */
|
|
@@ -360,6 +384,10 @@ function foldWithDelta(cache, events, warn = () => {}) {
|
|
|
360
384
|
}
|
|
361
385
|
function applyFeedbackEvent(state, event, warn = () => {}) {
|
|
362
386
|
if (event.type !== "feedback") return;
|
|
387
|
+
if (event.kind !== "skill" && event.kind !== "session") {
|
|
388
|
+
warn(`evolution-feedback: skipping feedback event with invalid kind: ${String(event.kind)}`);
|
|
389
|
+
return;
|
|
390
|
+
}
|
|
363
391
|
if (event.rating !== "positive" && event.rating !== "negative") {
|
|
364
392
|
warn(`evolution-feedback: skipping feedback event with invalid rating: ${String(event.rating)}`);
|
|
365
393
|
return;
|
|
@@ -458,7 +486,7 @@ function apply(ctx, rawConfig = {}) {
|
|
|
458
486
|
if (kind !== "skill") return;
|
|
459
487
|
const score = feedback.score(target, "skill");
|
|
460
488
|
const warn = score < qualityWarnThreshold;
|
|
461
|
-
skillUsage.
|
|
489
|
+
skillUsage.setFeedbackQuality(target, score, warn).catch((error) => {
|
|
462
490
|
skillCtx.logger.warn(error);
|
|
463
491
|
});
|
|
464
492
|
};
|
package/lib/types/index.d.ts
CHANGED
|
@@ -2,8 +2,15 @@
|
|
|
2
2
|
* Feedback-to-quality scoring for self-evolution.
|
|
3
3
|
*
|
|
4
4
|
* Feedback is durable through `ctx.evolutionIo` (when mounted) and skill
|
|
5
|
-
* feedback feeds `
|
|
6
|
-
*
|
|
5
|
+
* feedback feeds the FEEDBACK-OWNED `feedback_score` / `feedback_warn` pair on
|
|
6
|
+
* the usage record. P1-1 (v15): this package used to write
|
|
7
|
+
* `quality_score`/`quality_warn` — but the curator's six-factor `scoreTree`
|
|
8
|
+
* overwrote those fields on every run BEFORE the lifecycle engine read them,
|
|
9
|
+
* so the advertised "curator decisions consume feedback deterministically"
|
|
10
|
+
* channel was dead. The lifecycle engine and the scope view now read the
|
|
11
|
+
* union `quality_warn || feedback_warn`, and the curator never writes the
|
|
12
|
+
* feedback pair (field-ownership contract on `UsageRecord` in
|
|
13
|
+
* evolution-core/usage.ts).
|
|
7
14
|
*
|
|
8
15
|
* Persistence (rc.68): the EVENTS LOG (`evolution/events.json`, via
|
|
9
16
|
* `evolution-core/evolution-events.ts`) is the single source of truth —
|
|
@@ -63,6 +70,18 @@ export declare class EvolutionFeedback {
|
|
|
63
70
|
private noteKey;
|
|
64
71
|
private mutate;
|
|
65
72
|
restore(io: IoLike): Promise<void>;
|
|
73
|
+
/** External-producer contract (审计 B-4, v18): nothing inside the family
|
|
74
|
+
* calls `record` — the upstream `/feedback` command only appends a
|
|
75
|
+
* `feedback/record` session event carrying free text, which cannot be mapped
|
|
76
|
+
* to a (target, rating) pair without inventing semantics. A host that wants
|
|
77
|
+
* feedback-driven curation wires its own command/event to this method; the
|
|
78
|
+
* curator's union read (`feedback_warn`) then shortens the stale window.
|
|
79
|
+
* `feedback.spec.ts` pins that channel end to end.
|
|
80
|
+
* @param target - skill name or session id the rating belongs to.
|
|
81
|
+
* @param rating - `positive` or `negative`; other values are refused.
|
|
82
|
+
* @param note - optional free-text note carried into the durable event.
|
|
83
|
+
* @param kind - `skill` (default `session`) selects the score table.
|
|
84
|
+
*/
|
|
66
85
|
record(target: string, rating: 'positive' | 'negative', note?: string, kind?: 'skill' | 'session'): void;
|
|
67
86
|
score(target: string, kind?: 'skill' | 'session'): number;
|
|
68
87
|
snapshot(): FeedbackState;
|
|
@@ -86,7 +105,9 @@ export declare class EvolutionFeedback {
|
|
|
86
105
|
export declare function migrateFeedbackEvents(io: IoLike, eventsPath: string, aggregate: FeedbackState): Promise<void>;
|
|
87
106
|
export declare const name = "evolution-feedback";
|
|
88
107
|
export interface Config {
|
|
89
|
-
/** Score below which
|
|
108
|
+
/** Score below which the FEEDBACK pair flips to warned (P1-1, v15: written
|
|
109
|
+
* to `feedback_score`/`feedback_warn`; the lifecycle engine reads the union
|
|
110
|
+
* with the curator-owned `quality_warn`). */
|
|
90
111
|
qualityWarnThreshold?: number;
|
|
91
112
|
/** Explicit boot-cache file path; empty derives $DSH_HOME/evolution/feedback.json.
|
|
92
113
|
* The event log always stays at $DSH_HOME/evolution/events.json (derived from
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lmzhen/dsh-evolution-feedback",
|
|
3
3
|
"description": "Feedback-to-quality scoring for self-evolution (community build)",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.64",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -31,18 +31,18 @@
|
|
|
31
31
|
"license": "MIT",
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@deepseek-ai/schemastery": "^3.18.1",
|
|
34
|
-
"@lmzhen/dsh-evolution-core": "^0.3.
|
|
34
|
+
"@lmzhen/dsh-evolution-core": "^0.3.64"
|
|
35
35
|
},
|
|
36
36
|
"peerDependencies": {
|
|
37
37
|
"@deepseek-ai/dsh-invariants": "^0.1.1-rc.2",
|
|
38
38
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
39
|
-
"@lmzhen/dsh-evolution-io": "^0.3.
|
|
40
|
-
"@lmzhen/dsh-skill-usage": "^0.3.
|
|
39
|
+
"@lmzhen/dsh-evolution-io": "^0.3.64",
|
|
40
|
+
"@lmzhen/dsh-skill-usage": "^0.3.64"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@deepseek-ai/dsh-invariants": "^0.1.1-rc.2",
|
|
44
|
-
"@lmzhen/dsh-evolution-io": "^0.3.
|
|
45
|
-
"@lmzhen/dsh-evolution-io-node": "^0.3.
|
|
46
|
-
"@lmzhen/dsh-skill-usage": "^0.3.
|
|
44
|
+
"@lmzhen/dsh-evolution-io": "^0.3.64",
|
|
45
|
+
"@lmzhen/dsh-evolution-io-node": "^0.3.64",
|
|
46
|
+
"@lmzhen/dsh-skill-usage": "^0.3.64"
|
|
47
47
|
}
|
|
48
48
|
}
|