@lmzhen/dsh-evolution-review 0.4.0 → 0.4.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/lib/index.js +67 -18
- package/lib/types/index.d.ts +21 -12
- package/package.json +11 -11
package/lib/index.js
CHANGED
|
@@ -213,7 +213,7 @@ function apply(ctx, rawConfig = {}) {
|
|
|
213
213
|
return;
|
|
214
214
|
}
|
|
215
215
|
if (event.type !== "turn/end") return;
|
|
216
|
-
if (turnStarts.size >= COUNTER_SWEEP_THRESHOLD || cumulativeToolCalls.size >= COUNTER_SWEEP_THRESHOLD || completionInjected.size >= COUNTER_SWEEP_THRESHOLD || pendingCadenceReviews.size >= COUNTER_SWEEP_THRESHOLD || skipNextCadenceFire.size >= COUNTER_SWEEP_THRESHOLD || cadenceResetWarned.size >= COUNTER_SWEEP_THRESHOLD || lastTurnStart.size >= COUNTER_SWEEP_THRESHOLD) {
|
|
216
|
+
if (turnStarts.size >= COUNTER_SWEEP_THRESHOLD || pendingCadenceWarned.size >= COUNTER_SWEEP_THRESHOLD || cumulativeToolCalls.size >= COUNTER_SWEEP_THRESHOLD || completionInjected.size >= COUNTER_SWEEP_THRESHOLD || pendingCadenceReviews.size >= COUNTER_SWEEP_THRESHOLD || skipNextCadenceFire.size >= COUNTER_SWEEP_THRESHOLD || cadenceResetWarned.size >= COUNTER_SWEEP_THRESHOLD || lastTurnStart.size >= COUNTER_SWEEP_THRESHOLD) {
|
|
217
217
|
const isAlive = (id) => ctx.agents.get(id) !== void 0;
|
|
218
218
|
sweepDeadSessionEntries(turnStarts, isAlive);
|
|
219
219
|
sweepDeadSessionEntries(lastTurnStart, isAlive);
|
|
@@ -1113,24 +1113,56 @@ function resultCallIdOf(event) {
|
|
|
1113
1113
|
return null;
|
|
1114
1114
|
}
|
|
1115
1115
|
/**
|
|
1116
|
-
* V10-10 (P2-11): render one `[result]` evidence line from
|
|
1117
|
-
* event payload. The former read (`data.output`) targeted a
|
|
1118
|
-
* not exist on the
|
|
1119
|
-
*
|
|
1120
|
-
*
|
|
1121
|
-
*
|
|
1122
|
-
*
|
|
1123
|
-
*
|
|
1124
|
-
*
|
|
1125
|
-
*
|
|
1126
|
-
*
|
|
1116
|
+
* V10-10 (P2-11) / A1 (audit P1-1): render one `[result]` evidence line from
|
|
1117
|
+
* a tool-result event payload. The former read (`data.output`) targeted a
|
|
1118
|
+
* field that does not exist on the rc.2 payload; the current contract covers
|
|
1119
|
+
* BOTH rc.2 result shapes:
|
|
1120
|
+
* - native `tool/result`: the outcome lives in `message.content`
|
|
1121
|
+
* tool-result blocks (inner text blocks joined); a failure is marked by
|
|
1122
|
+
* the payload-level `error` OR a block-level `isError`;
|
|
1123
|
+
* - PTC `tool/ptc-dispatch` settle: the outcome lives at the TOP level —
|
|
1124
|
+
* `content` is the logged ContentBlock list and `isError` the flag; there
|
|
1125
|
+
* is no `message` wrapper. (Before A1 this shape rendered an empty line,
|
|
1126
|
+
* so every PTC session's evidence block starved while its plan prompt
|
|
1127
|
+
* still demanded evidence.)
|
|
1128
|
+
* The legacy pre-rc.2 shape (neither `message` nor a PTC settle marker) is
|
|
1129
|
+
* tolerated as an empty payload — it never throws. `identity`, when given, is
|
|
1130
|
+
* the dispatched tool's name + raw arguments, prepended so a settled dispatch
|
|
1131
|
+
* keeps the call identity its `[call]` line would have had. Budget: 500 chars
|
|
1132
|
+
* per line (the 12-line cap lives in buildReviewRequest and is unchanged).
|
|
1127
1133
|
*/
|
|
1128
|
-
function renderToolResultLine(data) {
|
|
1134
|
+
function renderToolResultLine(data, identity) {
|
|
1129
1135
|
const shape = data;
|
|
1130
|
-
const
|
|
1131
|
-
const resultBlocks =
|
|
1132
|
-
|
|
1133
|
-
|
|
1136
|
+
const nativeContent = shape?.message?.content;
|
|
1137
|
+
const resultBlocks = Array.isArray(nativeContent) ? nativeContent.filter((block) => block.type === "tool-result") : [];
|
|
1138
|
+
let output;
|
|
1139
|
+
let failed;
|
|
1140
|
+
if (shape?.message !== void 0) {
|
|
1141
|
+
output = resultBlocks.map((block) => Array.isArray(block.content) ? block.content.map((inner) => inner.type === "text" && typeof inner.text === "string" ? inner.text : "").join(" ") : typeof block.text === "string" ? block.text : "").join(" ").trim();
|
|
1142
|
+
failed = Boolean(shape.error) || resultBlocks.some((block) => block.isError === true);
|
|
1143
|
+
} else if (typeof shape?.subCallId === "string" && typeof shape.isError === "boolean") {
|
|
1144
|
+
output = textOfLoggedContent(shape.content);
|
|
1145
|
+
failed = shape.isError;
|
|
1146
|
+
} else {
|
|
1147
|
+
output = "";
|
|
1148
|
+
failed = false;
|
|
1149
|
+
}
|
|
1150
|
+
const head = identity === void 0 ? "" : `${identity.name} ${identity.argsRaw.slice(0, 200)} → `;
|
|
1151
|
+
return `[result]${failed ? " [ERROR]" : ""} ${head}${output.slice(0, 500)}`;
|
|
1152
|
+
}
|
|
1153
|
+
/** Text of a PTC settle `content` payload (the logged ContentBlock list):
|
|
1154
|
+
* text blocks and plain strings joined, anything else skipped. */
|
|
1155
|
+
function textOfLoggedContent(content) {
|
|
1156
|
+
if (typeof content === "string") return content.trim();
|
|
1157
|
+
if (!Array.isArray(content)) return "";
|
|
1158
|
+
return content.map((block) => {
|
|
1159
|
+
if (typeof block === "string") return block;
|
|
1160
|
+
if (block !== null && typeof block === "object") {
|
|
1161
|
+
const candidate = block;
|
|
1162
|
+
if (candidate.type === "text" && typeof candidate.text === "string") return candidate.text;
|
|
1163
|
+
}
|
|
1164
|
+
return "";
|
|
1165
|
+
}).join(" ").trim();
|
|
1134
1166
|
}
|
|
1135
1167
|
/**
|
|
1136
1168
|
* PLAN S4.1 (2026-09-16, audit P2-12): text of one persisted content block,
|
|
@@ -1157,6 +1189,17 @@ function buildReviewRequest(session, kind, signal, maxMessages, maxMessageChars)
|
|
|
1157
1189
|
}
|
|
1158
1190
|
const toolLines = [];
|
|
1159
1191
|
const events = session.snapshotEvents();
|
|
1192
|
+
const callIdentity = /* @__PURE__ */ new Map();
|
|
1193
|
+
const identityWindowStart = Math.max(0, events.length - 2e3);
|
|
1194
|
+
for (let index = events.length - 1; index >= identityWindowStart; index -= 1) {
|
|
1195
|
+
const event = events[index];
|
|
1196
|
+
const opened = readDispatchSignal(event);
|
|
1197
|
+
if (opened === null || callIdentity.has(opened.callId)) continue;
|
|
1198
|
+
callIdentity.set(opened.callId, {
|
|
1199
|
+
name: opened.name,
|
|
1200
|
+
argsRaw: typeof opened.arguments === "string" ? opened.arguments : JSON.stringify(opened.arguments ?? {})
|
|
1201
|
+
});
|
|
1202
|
+
}
|
|
1160
1203
|
const openedCallIds = /* @__PURE__ */ new Set();
|
|
1161
1204
|
for (let index = events.length - 1; index >= 0 && toolLines.length < 12; index -= 1) {
|
|
1162
1205
|
const event = events[index];
|
|
@@ -1164,7 +1207,13 @@ function buildReviewRequest(session, kind, signal, maxMessages, maxMessageChars)
|
|
|
1164
1207
|
if (answeredCallId !== null) {
|
|
1165
1208
|
if (openedCallIds.has(answeredCallId)) continue;
|
|
1166
1209
|
openedCallIds.add(answeredCallId);
|
|
1167
|
-
|
|
1210
|
+
const rawSettle = event?.data;
|
|
1211
|
+
const settleData = rawSettle !== null && typeof rawSettle === "object" ? rawSettle : void 0;
|
|
1212
|
+
const identity = settleData !== void 0 && typeof settleData.name === "string" && settleData.name !== "" ? {
|
|
1213
|
+
name: settleData.name,
|
|
1214
|
+
argsRaw: typeof settleData.arguments === "string" ? settleData.arguments : JSON.stringify(settleData.arguments ?? {})
|
|
1215
|
+
} : callIdentity.get(answeredCallId);
|
|
1216
|
+
toolLines.push(renderToolResultLine(event?.data, identity));
|
|
1168
1217
|
continue;
|
|
1169
1218
|
}
|
|
1170
1219
|
const opened = readDispatchSignal(event);
|
package/lib/types/index.d.ts
CHANGED
|
@@ -151,19 +151,28 @@ export declare function filterUnreadSkillOps(ops: Array<{
|
|
|
151
151
|
name?: string;
|
|
152
152
|
}>, readNames: ReadonlySet<string>): number;
|
|
153
153
|
/**
|
|
154
|
-
* V10-10 (P2-11): render one `[result]` evidence line from
|
|
155
|
-
* event payload. The former read (`data.output`) targeted a
|
|
156
|
-
* not exist on the
|
|
157
|
-
*
|
|
158
|
-
*
|
|
159
|
-
*
|
|
160
|
-
*
|
|
161
|
-
*
|
|
162
|
-
*
|
|
163
|
-
*
|
|
164
|
-
*
|
|
154
|
+
* V10-10 (P2-11) / A1 (audit P1-1): render one `[result]` evidence line from
|
|
155
|
+
* a tool-result event payload. The former read (`data.output`) targeted a
|
|
156
|
+
* field that does not exist on the rc.2 payload; the current contract covers
|
|
157
|
+
* BOTH rc.2 result shapes:
|
|
158
|
+
* - native `tool/result`: the outcome lives in `message.content`
|
|
159
|
+
* tool-result blocks (inner text blocks joined); a failure is marked by
|
|
160
|
+
* the payload-level `error` OR a block-level `isError`;
|
|
161
|
+
* - PTC `tool/ptc-dispatch` settle: the outcome lives at the TOP level —
|
|
162
|
+
* `content` is the logged ContentBlock list and `isError` the flag; there
|
|
163
|
+
* is no `message` wrapper. (Before A1 this shape rendered an empty line,
|
|
164
|
+
* so every PTC session's evidence block starved while its plan prompt
|
|
165
|
+
* still demanded evidence.)
|
|
166
|
+
* The legacy pre-rc.2 shape (neither `message` nor a PTC settle marker) is
|
|
167
|
+
* tolerated as an empty payload — it never throws. `identity`, when given, is
|
|
168
|
+
* the dispatched tool's name + raw arguments, prepended so a settled dispatch
|
|
169
|
+
* keeps the call identity its `[call]` line would have had. Budget: 500 chars
|
|
170
|
+
* per line (the 12-line cap lives in buildReviewRequest and is unchanged).
|
|
165
171
|
*/
|
|
166
|
-
export declare function renderToolResultLine(data: unknown
|
|
172
|
+
export declare function renderToolResultLine(data: unknown, identity?: {
|
|
173
|
+
name: string;
|
|
174
|
+
argsRaw: string;
|
|
175
|
+
}): string;
|
|
167
176
|
export declare function buildReviewRequest(session: Session, kind: ReviewKind, signal: {
|
|
168
177
|
toolCalls: number;
|
|
169
178
|
userChars: number;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lmzhen/dsh-evolution-review",
|
|
3
3
|
"description": "Background review orchestration (community build)",
|
|
4
|
-
"version": "0.4.
|
|
4
|
+
"version": "0.4.1",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -27,9 +27,9 @@
|
|
|
27
27
|
"license": "MIT",
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@deepseek-ai/schemastery": "^3.18.1",
|
|
30
|
-
"@lmzhen/dsh-evolution-approval": "^0.4.
|
|
31
|
-
"@lmzhen/dsh-evolution-core": "^0.4.
|
|
32
|
-
"@lmzhen/dsh-evolution-plan-validator": "^0.4.
|
|
30
|
+
"@lmzhen/dsh-evolution-approval": "^0.4.1",
|
|
31
|
+
"@lmzhen/dsh-evolution-core": "^0.4.1",
|
|
32
|
+
"@lmzhen/dsh-evolution-plan-validator": "^0.4.1"
|
|
33
33
|
},
|
|
34
34
|
"peerDependencies": {
|
|
35
35
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
@@ -37,8 +37,8 @@
|
|
|
37
37
|
"@deepseek-ai/dsh-llm": "^0.1.5-rc.2",
|
|
38
38
|
"@deepseek-ai/dsh-session": "^0.1.5-rc.2",
|
|
39
39
|
"@deepseek-ai/dsh-tools": "^0.1.5-rc.2",
|
|
40
|
-
"@lmzhen/dsh-evolution-state": "^0.4.
|
|
41
|
-
"@lmzhen/dsh-evolution-policy": "^0.4.
|
|
40
|
+
"@lmzhen/dsh-evolution-state": "^0.4.1",
|
|
41
|
+
"@lmzhen/dsh-evolution-policy": "^0.4.1"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"@deepseek-ai/dsh-agent": "^0.1.5-rc.2",
|
|
@@ -48,10 +48,10 @@
|
|
|
48
48
|
"@deepseek-ai/dsh-session-persistence": "^0.1.5-rc.2",
|
|
49
49
|
"@deepseek-ai/dsh-session-persistence-jsonl": "^0.1.5-rc.2",
|
|
50
50
|
"@deepseek-ai/dsh-tools": "^0.1.5-rc.2",
|
|
51
|
-
"@lmzhen/dsh-evolution-approval": "^0.4.
|
|
52
|
-
"@lmzhen/dsh-evolution-core": "^0.4.
|
|
53
|
-
"@lmzhen/dsh-evolution-curator": "^0.4.
|
|
54
|
-
"@lmzhen/dsh-evolution-plan-validator": "^0.4.
|
|
55
|
-
"@lmzhen/dsh-evolution-state": "^0.4.
|
|
51
|
+
"@lmzhen/dsh-evolution-approval": "^0.4.1",
|
|
52
|
+
"@lmzhen/dsh-evolution-core": "^0.4.1",
|
|
53
|
+
"@lmzhen/dsh-evolution-curator": "^0.4.1",
|
|
54
|
+
"@lmzhen/dsh-evolution-plan-validator": "^0.4.1",
|
|
55
|
+
"@lmzhen/dsh-evolution-state": "^0.4.1"
|
|
56
56
|
}
|
|
57
57
|
}
|