@lmzhen/dsh-evolution-feedback 0.3.82 → 0.3.83
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 +2 -2
- package/lib/index.js +41 -2
- package/lib/types/index.d.ts +18 -0
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# @
|
|
1
|
+
# @lmzhen/dsh-evolution-feedback
|
|
2
2
|
|
|
3
3
|
Feedback-to-quality scoring for self-evolution
|
|
4
4
|
|
|
@@ -8,7 +8,7 @@ Feedback-to-quality scoring for self-evolution
|
|
|
8
8
|
|
|
9
9
|
#### What the model sees
|
|
10
10
|
|
|
11
|
-
`@
|
|
11
|
+
`@lmzhen/dsh-evolution-feedback` registers no direct prompt or tool schema itself. Model-visible effects are owned by the packages that consume this service.
|
|
12
12
|
|
|
13
13
|
#### Token effect
|
|
14
14
|
|
package/lib/index.js
CHANGED
|
@@ -57,6 +57,21 @@ var EvolutionFeedback = class EvolutionFeedback {
|
|
|
57
57
|
* unpersisted note there, and reverting to it resurrects a value the log
|
|
58
58
|
* never held). Seeded from the fold truth, updated on successful appends. */
|
|
59
59
|
durableNote = /* @__PURE__ */ new Map();
|
|
60
|
+
/** PLAN S1.4 (2026-09-16): targets with a feedback append still IN FLIGHT,
|
|
61
|
+
* split by table, as a COUNT per target. record() increments before queueing
|
|
62
|
+
* the append and the append task decrements when it settles (landed or rolled
|
|
63
|
+
* back, finally), dropping the entry only at ZERO — the count covers exactly
|
|
64
|
+
* the optimistic window rc.66 meant to protect, including two appends for the
|
|
65
|
+
* same target in flight at once (review C-P2-1: a per-target boolean marker
|
|
66
|
+
* was cleared by the first settle, so a merge between the two appends folded
|
|
67
|
+
* the second append's increment away). restore() lets memory win ONLY for these targets — a settled
|
|
68
|
+
* target folds from the log truth, so another process's feedback for the
|
|
69
|
+
* same target (audit P1-3) is never overwritten by this process's stale
|
|
70
|
+
* record. */
|
|
71
|
+
pendingAppends = {
|
|
72
|
+
skills: /* @__PURE__ */ new Map(),
|
|
73
|
+
sessions: /* @__PURE__ */ new Map()
|
|
74
|
+
};
|
|
60
75
|
/** P2-32 (v11): process-level bound — every feedbacked session would
|
|
61
76
|
* otherwise keep one entry for the whole process lifetime (a name + note
|
|
62
77
|
* string per session); cap this map and drop the earliest-INSERTED entry on
|
|
@@ -85,6 +100,14 @@ var EvolutionFeedback = class EvolutionFeedback {
|
|
|
85
100
|
attachIo(io) {
|
|
86
101
|
this.io = io;
|
|
87
102
|
}
|
|
103
|
+
/** PLAN S4.6 (2026-09-16): whether a durable backend is attached — the
|
|
104
|
+
* plugin's quality push (`apply`) consults this before writing the
|
|
105
|
+
* feedback pair into the skill-usage sidecar. Same no-io posture as
|
|
106
|
+
* `record`/`refold`: without `ctx.evolutionIo` (when mounted) nothing may
|
|
107
|
+
* turn the optimistic in-memory aggregate into a durable side effect. */
|
|
108
|
+
get durable() {
|
|
109
|
+
return this.io !== void 0 && !!this.eventsPath;
|
|
110
|
+
}
|
|
88
111
|
/** V5-32 posture applied to the read side (C-events-dispatch-1, v43): an
|
|
89
112
|
* event a repeated read keeps reporting must not warn on each read —
|
|
90
113
|
* `refold()` calls `restore()` before every quality push. Shares the bounded
|
|
@@ -133,14 +156,23 @@ var EvolutionFeedback = class EvolutionFeedback {
|
|
|
133
156
|
const floor = events[0]?.seq ?? 0;
|
|
134
157
|
const usableCache = cache && cache.lastSeq >= floor - 1 ? cache : null;
|
|
135
158
|
const truth = usableCache ? foldWithDelta(usableCache, events, this.warn) : foldFeedbackState(events, this.warn);
|
|
159
|
+
const pickPending = (mode) => {
|
|
160
|
+
const picked = {};
|
|
161
|
+
for (const [target, inFlight] of this.pendingAppends[mode]) {
|
|
162
|
+
if (inFlight <= 0) continue;
|
|
163
|
+
const record = this.state[mode][target];
|
|
164
|
+
if (record) picked[target] = record;
|
|
165
|
+
}
|
|
166
|
+
return picked;
|
|
167
|
+
};
|
|
136
168
|
this.state = {
|
|
137
169
|
skills: {
|
|
138
170
|
...truth.skills,
|
|
139
|
-
...
|
|
171
|
+
...pickPending("skills")
|
|
140
172
|
},
|
|
141
173
|
sessions: {
|
|
142
174
|
...truth.sessions,
|
|
143
|
-
...
|
|
175
|
+
...pickPending("sessions")
|
|
144
176
|
}
|
|
145
177
|
};
|
|
146
178
|
const skillEntries = Object.entries(truth.skills);
|
|
@@ -204,6 +236,8 @@ var EvolutionFeedback = class EvolutionFeedback {
|
|
|
204
236
|
const recordIo = this.io;
|
|
205
237
|
const eventsPath = this.eventsPath;
|
|
206
238
|
if (!recordIo || !eventsPath) return;
|
|
239
|
+
const pending = this.pendingAppends[mode];
|
|
240
|
+
pending.set(target, (pending.get(target) ?? 0) + 1);
|
|
207
241
|
this.mutate(async () => {
|
|
208
242
|
try {
|
|
209
243
|
const seq = await appendEvolutionEvent(recordIo, eventsPath, {
|
|
@@ -244,6 +278,10 @@ var EvolutionFeedback = class EvolutionFeedback {
|
|
|
244
278
|
this.warn(message);
|
|
245
279
|
}
|
|
246
280
|
if (rollback) this.onRollback?.(target, kind);
|
|
281
|
+
} finally {
|
|
282
|
+
const remaining = (pending.get(target) ?? 1) - 1;
|
|
283
|
+
if (remaining > 0) pending.set(target, remaining);
|
|
284
|
+
else pending.delete(target);
|
|
247
285
|
}
|
|
248
286
|
});
|
|
249
287
|
}
|
|
@@ -617,6 +655,7 @@ function apply(ctx, rawConfig = {}) {
|
|
|
617
655
|
const skillUsage = skillCtx.skillUsage;
|
|
618
656
|
const pushQuality = (target, kind) => {
|
|
619
657
|
if (kind !== "skill") return;
|
|
658
|
+
if (!feedback.durable) return;
|
|
620
659
|
feedback.refold().then(() => {
|
|
621
660
|
const score = feedback.score(target, "skill");
|
|
622
661
|
const warn = score < qualityWarnThreshold;
|
package/lib/types/index.d.ts
CHANGED
|
@@ -50,6 +50,18 @@ export declare class EvolutionFeedback {
|
|
|
50
50
|
* unpersisted note there, and reverting to it resurrects a value the log
|
|
51
51
|
* never held). Seeded from the fold truth, updated on successful appends. */
|
|
52
52
|
private readonly durableNote;
|
|
53
|
+
/** PLAN S1.4 (2026-09-16): targets with a feedback append still IN FLIGHT,
|
|
54
|
+
* split by table, as a COUNT per target. record() increments before queueing
|
|
55
|
+
* the append and the append task decrements when it settles (landed or rolled
|
|
56
|
+
* back, finally), dropping the entry only at ZERO — the count covers exactly
|
|
57
|
+
* the optimistic window rc.66 meant to protect, including two appends for the
|
|
58
|
+
* same target in flight at once (review C-P2-1: a per-target boolean marker
|
|
59
|
+
* was cleared by the first settle, so a merge between the two appends folded
|
|
60
|
+
* the second append's increment away). restore() lets memory win ONLY for these targets — a settled
|
|
61
|
+
* target folds from the log truth, so another process's feedback for the
|
|
62
|
+
* same target (audit P1-3) is never overwritten by this process's stale
|
|
63
|
+
* record. */
|
|
64
|
+
private readonly pendingAppends;
|
|
53
65
|
/** P2-32 (v11): process-level bound — every feedbacked session would
|
|
54
66
|
* otherwise keep one entry for the whole process lifetime (a name + note
|
|
55
67
|
* string per session); cap this map and drop the earliest-INSERTED entry on
|
|
@@ -71,6 +83,12 @@ export declare class EvolutionFeedback {
|
|
|
71
83
|
constructor(io?: IoLike, home?: string, pathOverride?: string, warn?: (message: string) => void);
|
|
72
84
|
/** Bind the evolution IO backend after construction (S6.4 deferred binding). */
|
|
73
85
|
attachIo(io: IoLike): void;
|
|
86
|
+
/** PLAN S4.6 (2026-09-16): whether a durable backend is attached — the
|
|
87
|
+
* plugin's quality push (`apply`) consults this before writing the
|
|
88
|
+
* feedback pair into the skill-usage sidecar. Same no-io posture as
|
|
89
|
+
* `record`/`refold`: without `ctx.evolutionIo` (when mounted) nothing may
|
|
90
|
+
* turn the optimistic in-memory aggregate into a durable side effect. */
|
|
91
|
+
get durable(): boolean;
|
|
74
92
|
/** V5-32 posture applied to the read side (C-events-dispatch-1, v43): an
|
|
75
93
|
* event a repeated read keeps reporting must not warn on each read —
|
|
76
94
|
* `refold()` calls `restore()` before every quality push. Shares the bounded
|
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.83",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -27,16 +27,16 @@
|
|
|
27
27
|
"license": "MIT",
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@deepseek-ai/schemastery": "^3.18.1",
|
|
30
|
-
"@lmzhen/dsh-evolution-core": "^0.3.
|
|
30
|
+
"@lmzhen/dsh-evolution-core": "^0.3.83"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
33
33
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
34
|
-
"@lmzhen/dsh-evolution-io": "^0.3.
|
|
35
|
-
"@lmzhen/dsh-skill-usage": "^0.3.
|
|
34
|
+
"@lmzhen/dsh-evolution-io": "^0.3.83",
|
|
35
|
+
"@lmzhen/dsh-skill-usage": "^0.3.83"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
|
-
"@lmzhen/dsh-evolution-io": "^0.3.
|
|
39
|
-
"@lmzhen/dsh-evolution-io-node": "^0.3.
|
|
40
|
-
"@lmzhen/dsh-skill-usage": "^0.3.
|
|
38
|
+
"@lmzhen/dsh-evolution-io": "^0.3.83",
|
|
39
|
+
"@lmzhen/dsh-evolution-io-node": "^0.3.83",
|
|
40
|
+
"@lmzhen/dsh-skill-usage": "^0.3.83"
|
|
41
41
|
}
|
|
42
42
|
}
|