@michengai/dsh-archive-manager 1.0.9 → 1.0.11
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/CHANGELOG.md +8 -0
- package/CHANGELOG.zh-CN.md +8 -0
- package/lib/client.js +57 -57
- package/lib/workspace.js +40 -8
- package/package.json +1 -1
package/lib/workspace.js
CHANGED
|
@@ -273,6 +273,24 @@ function hostEvent(ctx, name) {
|
|
|
273
273
|
const caller = ctx[name];
|
|
274
274
|
return typeof caller === "function" ? caller : void 0;
|
|
275
275
|
}
|
|
276
|
+
const fileUploadResolverRestart = Symbol.for("dsh-archive-manager.file-upload-resolver-restart");
|
|
277
|
+
const staleFileUploadResolver = "file-upload: Agent resolver is already registered";
|
|
278
|
+
function tolerateStaleFileUploadResolver(ctx) {
|
|
279
|
+
const uploads = ctx.get?.("fileUploads");
|
|
280
|
+
const original = uploads?.registerAgentResolver;
|
|
281
|
+
if (uploads === void 0 || typeof original !== "function" || original[fileUploadResolverRestart] === true) return;
|
|
282
|
+
const registerAgentResolver = function(resolve2) {
|
|
283
|
+
try {
|
|
284
|
+
return original.call(this, resolve2);
|
|
285
|
+
} catch (error) {
|
|
286
|
+
if (!(error instanceof Error) || error.message !== staleFileUploadResolver || !Object.hasOwn(this, "agentResolver")) throw error;
|
|
287
|
+
this.agentResolver = void 0;
|
|
288
|
+
return original.call(this, resolve2);
|
|
289
|
+
}
|
|
290
|
+
};
|
|
291
|
+
registerAgentResolver[fileUploadResolverRestart] = true;
|
|
292
|
+
uploads.registerAgentResolver = registerAgentResolver;
|
|
293
|
+
}
|
|
276
294
|
var ArchiveWorkspaceRegistry = class extends WorkspaceRegistry {
|
|
277
295
|
static inject = [
|
|
278
296
|
"storageDomain",
|
|
@@ -292,6 +310,7 @@ var ArchiveWorkspaceRegistry = class extends WorkspaceRegistry {
|
|
|
292
310
|
archivedSessionPathIndexKey;
|
|
293
311
|
constructor(ctx) {
|
|
294
312
|
super(ctx);
|
|
313
|
+
tolerateStaleFileUploadResolver(ctx);
|
|
295
314
|
const indexedPath = this.host.sessionPath;
|
|
296
315
|
this.host.sessionPath = (id) => {
|
|
297
316
|
const path = indexedPath(id);
|
|
@@ -800,9 +819,17 @@ var ArchiveWorkspaceRegistry = class extends WorkspaceRegistry {
|
|
|
800
819
|
const deletedSessionIds = [];
|
|
801
820
|
const skippedSessionIds = [];
|
|
802
821
|
const failures = [];
|
|
822
|
+
let descendantHeaders;
|
|
823
|
+
try {
|
|
824
|
+
descendantHeaders = await this.listStoredHeaders();
|
|
825
|
+
} catch (error) {
|
|
826
|
+
this.ctx.logger.warn(
|
|
827
|
+
`archive-manager: batch descendant listing failed; each cascade will retry: ${String(error)}`
|
|
828
|
+
);
|
|
829
|
+
}
|
|
803
830
|
for (const sessionId of requestedSessionIds) {
|
|
804
831
|
try {
|
|
805
|
-
const result = await this.deleteSessionCore(sessionId);
|
|
832
|
+
const result = await this.deleteSessionCore(sessionId, descendantHeaders);
|
|
806
833
|
if (result?.skipped) skippedSessionIds.push(sessionId);
|
|
807
834
|
else deletedSessionIds.push(sessionId);
|
|
808
835
|
} catch (error) {
|
|
@@ -880,7 +907,7 @@ var ArchiveWorkspaceRegistry = class extends WorkspaceRegistry {
|
|
|
880
907
|
});
|
|
881
908
|
}
|
|
882
909
|
/** 串行化后的删除主体(级联路径复用:它已持有操作链,绝不能再入队)。 */
|
|
883
|
-
async deleteSessionCore(sessionId) {
|
|
910
|
+
async deleteSessionCore(sessionId, descendantHeaders) {
|
|
884
911
|
if (!await this.sessionKnown(sessionId)) {
|
|
885
912
|
await this.cleanupUnknownArchivedSession(sessionId);
|
|
886
913
|
return { deleted: true, skipped: true };
|
|
@@ -897,7 +924,7 @@ var ArchiveWorkspaceRegistry = class extends WorkspaceRegistry {
|
|
|
897
924
|
const projCache = this.ctx.get("sessionProjectionCache");
|
|
898
925
|
await projCache?.whenIdle?.();
|
|
899
926
|
if (projCache !== void 0) await projCache.delete(sessionId);
|
|
900
|
-
await this.deleteDescendants(sessionId);
|
|
927
|
+
await this.deleteDescendants(sessionId, descendantHeaders);
|
|
901
928
|
await this.cleanSpill(sessionId);
|
|
902
929
|
await this.removeTranscriptDirectory(sessionId);
|
|
903
930
|
const state = this.requireState();
|
|
@@ -1127,23 +1154,28 @@ var ArchiveWorkspaceRegistry = class extends WorkspaceRegistry {
|
|
|
1127
1154
|
/** 尽力而为的级联删除:删除 `sessionId` 的 SUBAGENT 子会话。
|
|
1128
1155
|
* 仅头部标记 `origin: "subagent"` 的会话参与:单凭 `parentSession` 有歧义
|
|
1129
1156
|
*(fork 分支也携带它),而 fork 分支是独立的用户会话,绝不能被级联删除。 */
|
|
1130
|
-
async deleteDescendants(sessionId) {
|
|
1157
|
+
async deleteDescendants(sessionId, storedHeaders) {
|
|
1131
1158
|
try {
|
|
1132
1159
|
const descendants = [];
|
|
1160
|
+
const collected = /* @__PURE__ */ new Set();
|
|
1133
1161
|
const sessions = this.ctx.get("sessions");
|
|
1134
1162
|
if (sessions !== void 0)
|
|
1135
1163
|
for (const session of sessions.list()) {
|
|
1136
|
-
if (session.header.parentSession === sessionId && session.header.origin === "subagent")
|
|
1164
|
+
if (session.header.parentSession === sessionId && session.header.origin === "subagent") {
|
|
1137
1165
|
descendants.push(session.id);
|
|
1166
|
+
collected.add(session.id);
|
|
1167
|
+
}
|
|
1138
1168
|
}
|
|
1139
|
-
for (const header of await this.listStoredHeaders()) {
|
|
1140
|
-
if (header.parentSession === sessionId && header.origin === "subagent" && !
|
|
1169
|
+
for (const header of storedHeaders ?? await this.listStoredHeaders()) {
|
|
1170
|
+
if (header.parentSession === sessionId && header.origin === "subagent" && !collected.has(header.id)) {
|
|
1141
1171
|
descendants.push(header.id);
|
|
1172
|
+
collected.add(header.id);
|
|
1173
|
+
}
|
|
1142
1174
|
}
|
|
1143
1175
|
for (const childId of descendants) {
|
|
1144
1176
|
try {
|
|
1145
1177
|
if (!await this.sessionKnown(childId)) continue;
|
|
1146
|
-
await this.deleteSessionCore(childId);
|
|
1178
|
+
await this.deleteSessionCore(childId, storedHeaders);
|
|
1147
1179
|
} catch (error) {
|
|
1148
1180
|
this.ctx.logger.warn(
|
|
1149
1181
|
`archive-manager: cascade delete of subagent session "${childId}" (child of "${sessionId}") failed: ${String(error)}`
|