stratagate-dsh 0.2.60 → 0.2.61
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 +10 -30
- package/LICENSE +21 -21
- package/README.zh-CN.md +43 -43
- package/dist/client.js +4 -4
- package/dist/index.js +18 -156
- package/dist/index.js.map +1 -1
- package/docs/ARCHITECTURE.md +29 -29
- package/docs/DSH.md +13 -14
- package/docs/DSH.zh-CN.md +11 -12
- package/docs/EXTERNAL_MEMORY_IMPORT.zh-CN.md +54 -54
- package/package.json +23 -23
- package/screenshots.json +4 -4
package/dist/index.js
CHANGED
|
@@ -19,7 +19,7 @@ var Config = z.object({
|
|
|
19
19
|
provider: z.string(),
|
|
20
20
|
model: z.string(),
|
|
21
21
|
maxOutputTokens: z.natural().min(256).default(2048),
|
|
22
|
-
structuredTaskTimeoutMs: z.natural().min(1e3).default(
|
|
22
|
+
structuredTaskTimeoutMs: z.natural().min(1e3).default(45e3),
|
|
23
23
|
structuredReasoningEffort: z.union(["auto", "force-off"]).default("auto")
|
|
24
24
|
});
|
|
25
25
|
function resolveConfig(config) {
|
|
@@ -42,7 +42,7 @@ function resolveConfig(config) {
|
|
|
42
42
|
ingestSubagents: config.ingestSubagents ?? false,
|
|
43
43
|
...provider && model ? { provider, model } : {},
|
|
44
44
|
maxOutputTokens: Math.max(256, Math.floor(config.maxOutputTokens ?? 2048)),
|
|
45
|
-
structuredTaskTimeoutMs: Math.max(1e3, Math.floor(config.structuredTaskTimeoutMs ??
|
|
45
|
+
structuredTaskTimeoutMs: Math.max(1e3, Math.floor(config.structuredTaskTimeoutMs ?? 45e3)),
|
|
46
46
|
structuredReasoningEffort: config.structuredReasoningEffort ?? "auto"
|
|
47
47
|
};
|
|
48
48
|
}
|
|
@@ -2991,35 +2991,6 @@ var StrataGate = class _StrataGate {
|
|
|
2991
2991
|
listSummaryJobs() {
|
|
2992
2992
|
return [...this.summaryJobs.values()];
|
|
2993
2993
|
}
|
|
2994
|
-
/** Give one terminally failed Block Summary job a fresh, user-requested retry budget. */
|
|
2995
|
-
async retryBlockSummary(id) {
|
|
2996
|
-
const blockId = id.trim();
|
|
2997
|
-
if (!blockId) throw new TypeError("Block id must not be empty");
|
|
2998
|
-
const block = this.blocks.find((candidate) => candidate.id === blockId);
|
|
2999
|
-
if (!block) throw new Error(`Unknown block: ${blockId}`);
|
|
3000
|
-
if (block.processingStatus !== "pending") throw new Error(`Block ${blockId} is already ready`);
|
|
3001
|
-
await this.commitMutation(() => {
|
|
3002
|
-
const job = this.summaryJobs.get(blockId);
|
|
3003
|
-
if (!job) throw new Error(`Missing summary job for block: ${blockId}`);
|
|
3004
|
-
if (job.status !== "failed" || job.nextRetryAt !== null) {
|
|
3005
|
-
throw new Error(`Block ${blockId} Summary has not exhausted automatic retries`);
|
|
3006
|
-
}
|
|
3007
|
-
this.summaryJobs.set(blockId, {
|
|
3008
|
-
...job,
|
|
3009
|
-
status: "pending",
|
|
3010
|
-
attempts: 0,
|
|
3011
|
-
lastError: null,
|
|
3012
|
-
nextRetryAt: null,
|
|
3013
|
-
updatedAt: toUtc8Iso(this.now())
|
|
3014
|
-
});
|
|
3015
|
-
});
|
|
3016
|
-
const extractedEvents = await this.processBlock(block, { retryFailed: false });
|
|
3017
|
-
const processed = this.blocks.find((candidate) => candidate.id === blockId);
|
|
3018
|
-
const readyBlocks = processed?.processingStatus === "ready" ? [processed] : [];
|
|
3019
|
-
const projectedElements = await this.projectEligibleElements() ?? [];
|
|
3020
|
-
await this.projectEligibleGraph();
|
|
3021
|
-
return { sealedBlocks: [], readyBlocks, extractedEvents, projectedElements };
|
|
3022
|
-
}
|
|
3023
2994
|
listElementProjectionJobs() {
|
|
3024
2995
|
return [...this.elementProjectionJobs.values()];
|
|
3025
2996
|
}
|
|
@@ -4749,7 +4720,7 @@ function extractorPayload(context) {
|
|
|
4749
4720
|
}
|
|
4750
4721
|
var JSON_RESPONSE_ATTEMPTS = 2;
|
|
4751
4722
|
var JSON_RETRY_INSTRUCTION = "Your previous response did not make one valid call to the requested tool. Do not spend output on analysis or reasoning. Immediately call that tool exactly once with complete arguments. Do not return an answer as text or markdown.";
|
|
4752
|
-
var DEFAULT_STRUCTURED_TIMEOUT_MS =
|
|
4723
|
+
var DEFAULT_STRUCTURED_TIMEOUT_MS = 45e3;
|
|
4753
4724
|
var STRUCTURED_FIELDS = {
|
|
4754
4725
|
summarizer: ["l0Title", "l0Tags", "l1Summary", "l2Keypoints", "shouldExtract"],
|
|
4755
4726
|
extractor: ["shouldExtract", "reason", "events"],
|
|
@@ -5633,8 +5604,6 @@ var StrataGateRuntime = class {
|
|
|
5633
5604
|
migrationTimers = /* @__PURE__ */ new Map();
|
|
5634
5605
|
derivationTimers = /* @__PURE__ */ new Map();
|
|
5635
5606
|
derivationRuns = /* @__PURE__ */ new Map();
|
|
5636
|
-
knownSessions = /* @__PURE__ */ new Map();
|
|
5637
|
-
pendingSurfaceSync = /* @__PURE__ */ new Map();
|
|
5638
5607
|
adminSnapshotCache = /* @__PURE__ */ new Map();
|
|
5639
5608
|
externalImportRuns = /* @__PURE__ */ new Map();
|
|
5640
5609
|
feedbackDrafts = /* @__PURE__ */ new Map();
|
|
@@ -5712,10 +5681,7 @@ var StrataGateRuntime = class {
|
|
|
5712
5681
|
timer.unref?.();
|
|
5713
5682
|
this.drainTimers.set(key, timer);
|
|
5714
5683
|
}
|
|
5715
|
-
/**
|
|
5716
|
-
* Persist one detached batch. On failure, the failed and unvisited turns are
|
|
5717
|
-
* restored ahead of turns that arrived meanwhile, preserving original order.
|
|
5718
|
-
*/
|
|
5684
|
+
/** Restore failed and unvisited turns ahead of turns that arrived during the drain. */
|
|
5719
5685
|
async drain(session) {
|
|
5720
5686
|
const key = String(session.id);
|
|
5721
5687
|
const turns = this.pendingTurns.get(key);
|
|
@@ -6078,33 +6044,6 @@ var StrataGateRuntime = class {
|
|
|
6078
6044
|
}
|
|
6079
6045
|
return changed;
|
|
6080
6046
|
}
|
|
6081
|
-
/** Finish native-surface replacement when an admin retry ran without the target session loaded. */
|
|
6082
|
-
async syncPendingRetrySurface(session, memory) {
|
|
6083
|
-
const namespace = this.namespaceFor(session);
|
|
6084
|
-
const threadId = String(session.id);
|
|
6085
|
-
const pending = [...this.pendingSurfaceSync.entries()].filter(([, item]) => item.namespace === namespace);
|
|
6086
|
-
if (pending.length === 0) return;
|
|
6087
|
-
const contexts = new Map(memory.getBlockContext(threadId).map((context) => [context.id, context]));
|
|
6088
|
-
const existing = currentBlockSurfaceMessages(session);
|
|
6089
|
-
let changed = false;
|
|
6090
|
-
for (const [key, { blockId }] of pending) {
|
|
6091
|
-
if (existing.has(blockId)) {
|
|
6092
|
-
this.pendingSurfaceSync.delete(key);
|
|
6093
|
-
continue;
|
|
6094
|
-
}
|
|
6095
|
-
const block = memory.listBlocks().find((candidate) => candidate.id === blockId && candidate.threadId === threadId);
|
|
6096
|
-
const context = contexts.get(blockId);
|
|
6097
|
-
if (!block || block.processingStatus !== "ready" || !context) continue;
|
|
6098
|
-
try {
|
|
6099
|
-
this.replaceSealedSurface(session, block, context, dshTurnAtBlockEnd(session, block));
|
|
6100
|
-
this.pendingSurfaceSync.delete(key);
|
|
6101
|
-
changed = true;
|
|
6102
|
-
} catch (error) {
|
|
6103
|
-
this.onIngestError(error);
|
|
6104
|
-
}
|
|
6105
|
-
}
|
|
6106
|
-
if (changed) await this.flushNativeSession(session);
|
|
6107
|
-
}
|
|
6108
6047
|
// Keep the ingestion error for callers that explicitly require a flushed run.
|
|
6109
6048
|
async settleIngestion() {
|
|
6110
6049
|
do {
|
|
@@ -6636,44 +6575,6 @@ var StrataGateRuntime = class {
|
|
|
6636
6575
|
});
|
|
6637
6576
|
return update;
|
|
6638
6577
|
}
|
|
6639
|
-
async adminRetryBlockSummary(namespace, id) {
|
|
6640
|
-
const key = namespace.trim();
|
|
6641
|
-
const blockId = id.trim();
|
|
6642
|
-
if (!key) throw new TypeError("StrataGate admin namespace must not be empty");
|
|
6643
|
-
if (!blockId) throw new TypeError("Block id must not be empty");
|
|
6644
|
-
const update = this.settingsTail.catch(() => {
|
|
6645
|
-
}).then(async () => {
|
|
6646
|
-
await this.flush();
|
|
6647
|
-
const { memory, owned } = await this.openAdminMemory(key, { derivation: true });
|
|
6648
|
-
try {
|
|
6649
|
-
await this.refreshExternalImportMemory(key, memory);
|
|
6650
|
-
const block = memory.listBlocks().find((candidate) => candidate.id === blockId);
|
|
6651
|
-
if (!block) throw new Error(`Unknown block: ${blockId}`);
|
|
6652
|
-
const threadId = block.threadId ?? `admin-summary-retry:${blockId}`;
|
|
6653
|
-
const session = block.threadId ? this.knownSessions.get(block.threadId)?.deref() : void 0;
|
|
6654
|
-
const resumed = session && this.namespaceFor(session) === key ? await this.models.run(session, () => memory.retryBlockSummary(blockId)) : await this.models.runDetached(threadId, () => memory.retryBlockSummary(blockId));
|
|
6655
|
-
await this.persistSuccessfulResponses(memory);
|
|
6656
|
-
if (resumed.readyBlocks.some(({ id: readyId }) => readyId === blockId) && block.threadId) {
|
|
6657
|
-
this.pendingSurfaceSync.set(`${key}\0${blockId}`, { namespace: key, blockId });
|
|
6658
|
-
if (session && this.namespaceFor(session) === key) await this.syncPendingRetrySurface(session, memory);
|
|
6659
|
-
}
|
|
6660
|
-
const summaryJob = memory.listSummaryJobs().find(({ blockId: candidateId }) => candidateId === blockId);
|
|
6661
|
-
return {
|
|
6662
|
-
blockId,
|
|
6663
|
-
processingStatus: block.processingStatus,
|
|
6664
|
-
ready: block.processingStatus === "ready",
|
|
6665
|
-
summaryJob: summaryJob ?? null,
|
|
6666
|
-
surfaceUpdated: !this.pendingSurfaceSync.has(`${key}\0${blockId}`)
|
|
6667
|
-
};
|
|
6668
|
-
} finally {
|
|
6669
|
-
if (owned) await memory.close();
|
|
6670
|
-
}
|
|
6671
|
-
});
|
|
6672
|
-
this.settingsTail = update.then(() => {
|
|
6673
|
-
}, () => {
|
|
6674
|
-
});
|
|
6675
|
-
return update;
|
|
6676
|
-
}
|
|
6677
6578
|
async applyBlockDecayLambda(value) {
|
|
6678
6579
|
await this.flush();
|
|
6679
6580
|
this.blockDecayLambda = value;
|
|
@@ -6736,9 +6637,8 @@ var StrataGateRuntime = class {
|
|
|
6736
6637
|
}
|
|
6737
6638
|
}
|
|
6738
6639
|
}
|
|
6739
|
-
|
|
6640
|
+
space(session) {
|
|
6740
6641
|
const namespace = this.namespaceFor(session);
|
|
6741
|
-
this.knownSessions.set(String(session.id), new WeakRef(session));
|
|
6742
6642
|
this.rememberWorkspace(namespace, session.header.cwd);
|
|
6743
6643
|
let opening = this.spaces.get(namespace);
|
|
6744
6644
|
if (!opening) {
|
|
@@ -6751,20 +6651,20 @@ var StrataGateRuntime = class {
|
|
|
6751
6651
|
extractor: this.models.extractor,
|
|
6752
6652
|
graphProjector: this.models.graphProjector,
|
|
6753
6653
|
disableElementProjection: true
|
|
6754
|
-
}).then(async (
|
|
6654
|
+
}).then(async (memory) => {
|
|
6755
6655
|
try {
|
|
6756
6656
|
try {
|
|
6757
|
-
await
|
|
6758
|
-
const contexts =
|
|
6657
|
+
await memory.resumePendingWork({ deferDerivation: true, threadId: String(session.id) });
|
|
6658
|
+
const contexts = memory.getBlockContext(String(session.id));
|
|
6759
6659
|
this.syncDecayedBlockSurface(session, contexts);
|
|
6760
6660
|
} finally {
|
|
6761
|
-
await this.persistSuccessfulResponses(
|
|
6661
|
+
await this.persistSuccessfulResponses(memory);
|
|
6762
6662
|
}
|
|
6763
|
-
this.scheduleGraphMigration(session,
|
|
6764
|
-
this.scheduleBlockDerivation(session,
|
|
6765
|
-
return
|
|
6663
|
+
this.scheduleGraphMigration(session, memory);
|
|
6664
|
+
this.scheduleBlockDerivation(session, memory);
|
|
6665
|
+
return memory;
|
|
6766
6666
|
} catch (error) {
|
|
6767
|
-
await
|
|
6667
|
+
await memory.close().catch(() => {
|
|
6768
6668
|
});
|
|
6769
6669
|
throw error;
|
|
6770
6670
|
}
|
|
@@ -6774,9 +6674,7 @@ var StrataGateRuntime = class {
|
|
|
6774
6674
|
if (this.spaces.get(namespace) === opening) this.spaces.delete(namespace);
|
|
6775
6675
|
});
|
|
6776
6676
|
}
|
|
6777
|
-
|
|
6778
|
-
await this.syncPendingRetrySurface(session, memory);
|
|
6779
|
-
return memory;
|
|
6677
|
+
return opening;
|
|
6780
6678
|
}
|
|
6781
6679
|
async searchGraph(session, query, limit = 8) {
|
|
6782
6680
|
await this.flush();
|
|
@@ -6880,7 +6778,7 @@ var StrataGateRuntime = class {
|
|
|
6880
6778
|
noteNewCoreJobFailures(session, before, memory) {
|
|
6881
6779
|
if ([...this.failedCoreJobs(memory)].some((failure) => !before.has(failure))) this.notePluginError(session);
|
|
6882
6780
|
}
|
|
6883
|
-
async openAdminMemory(namespace
|
|
6781
|
+
async openAdminMemory(namespace) {
|
|
6884
6782
|
const active = this.spaces.get(namespace);
|
|
6885
6783
|
if (active) return { memory: await active, owned: false };
|
|
6886
6784
|
if (this.config.database === ":memory:" || !existsSync(this.config.database)) {
|
|
@@ -6892,10 +6790,6 @@ var StrataGateRuntime = class {
|
|
|
6892
6790
|
namespace,
|
|
6893
6791
|
blockTurnSize: this.blockTurnSize,
|
|
6894
6792
|
blockDecayLambda: this.blockDecayLambda,
|
|
6895
|
-
...options.derivation ? {
|
|
6896
|
-
summarizer: this.models.summarizer,
|
|
6897
|
-
extractor: this.models.extractor
|
|
6898
|
-
} : {},
|
|
6899
6793
|
graphProjector: this.models.graphProjector,
|
|
6900
6794
|
disableElementProjection: true
|
|
6901
6795
|
}),
|
|
@@ -7544,7 +7438,7 @@ function clusterKnowledgeGraph(rawNodes, rawEdges) {
|
|
|
7544
7438
|
}
|
|
7545
7439
|
|
|
7546
7440
|
// src/web.ts
|
|
7547
|
-
var STRATAGATE_DSH_VERSION = "0.2.
|
|
7441
|
+
var STRATAGATE_DSH_VERSION = "0.2.52";
|
|
7548
7442
|
var LEGACY_THREAD_ID = "__legacy__";
|
|
7549
7443
|
var nodeRequire = createRequire(import.meta.url);
|
|
7550
7444
|
function installedPackageVersion(names) {
|
|
@@ -7687,24 +7581,9 @@ async function overview(runtime, cachedEntries) {
|
|
|
7687
7581
|
const rows = [];
|
|
7688
7582
|
for (const { namespace, snapshot } of entries) {
|
|
7689
7583
|
if (!snapshot) continue;
|
|
7690
|
-
const failedJobs = snapshot.
|
|
7584
|
+
const failedJobs = snapshot.extractionJobs.filter(({ status }) => status === "failed").length + snapshot.graphProjectionJobs.filter(({ status }) => status === "failed").length;
|
|
7691
7585
|
const processingJobs = snapshot.summaryJobs.filter(({ status, nextRetryAt }) => status === "pending" || status === "running" || status === "failed" && nextRetryAt !== null).length + snapshot.extractionJobs.filter(({ status, nextRetryAt }) => status === "running" || status === "failed" && nextRetryAt !== null).length + snapshot.graphProjectionJobs.filter(({ status }) => status === "pending" || status === "running").length;
|
|
7692
7586
|
const failedJobDetails = [
|
|
7693
|
-
...snapshot.summaryJobs.filter(({ status }) => status === "failed").map((job) => {
|
|
7694
|
-
const block = snapshot.blocks.find(({ id }) => id === job.blockId);
|
|
7695
|
-
return {
|
|
7696
|
-
id: job.blockId,
|
|
7697
|
-
kind: "block-summary",
|
|
7698
|
-
attempts: job.attempts,
|
|
7699
|
-
nextRetryAt: job.nextRetryAt,
|
|
7700
|
-
lastError: job.lastError?.slice(0, 500) ?? null,
|
|
7701
|
-
lastErrorFull: job.lastError,
|
|
7702
|
-
updatedAt: job.updatedAt,
|
|
7703
|
-
threadId: block?.threadId ?? null,
|
|
7704
|
-
sequence: block?.sequence ?? null,
|
|
7705
|
-
turnRange: block ? [block.startTurn, block.endTurn] : null
|
|
7706
|
-
};
|
|
7707
|
-
}),
|
|
7708
7587
|
...snapshot.extractionJobs.filter(({ status }) => status === "failed").map((job) => ({
|
|
7709
7588
|
id: job.blockId,
|
|
7710
7589
|
kind: "event-extraction",
|
|
@@ -8099,7 +7978,7 @@ async function memories(runtime, url) {
|
|
|
8099
7978
|
const failedProjection = projections.find(({ status: status2 }) => status2 === "failed");
|
|
8100
7979
|
const pendingProjection = projections.some(({ status: status2 }) => status2 === "pending" || status2 === "running");
|
|
8101
7980
|
const needsExtraction = source.shouldExtract === true;
|
|
8102
|
-
const status =
|
|
7981
|
+
const status = extraction?.status === "failed" || failedProjection ? "failed" : extraction?.status === "succeeded" || extraction?.status === "skipped" ? pendingProjection ? "processing" : "organized" : needsExtraction ? "waiting" : "organized";
|
|
8103
7982
|
const blockPosition = scopedBlocks.findIndex(({ id }) => id === block.id) + 1;
|
|
8104
7983
|
const latestBlockPosition = scopedBlocks.length;
|
|
8105
7984
|
const currentLevel = getDecayedBlockLevel(
|
|
@@ -8257,20 +8136,6 @@ async function expandBlock(runtime, url) {
|
|
|
8257
8136
|
if (!/^L?[0-5]$/i.test(target)) throw new AdminHttpError(400, "level must be L0 through L5");
|
|
8258
8137
|
return runtime.adminExpandBlock(namespace, blockId, target);
|
|
8259
8138
|
}
|
|
8260
|
-
async function retryBlockSummary(runtime, url) {
|
|
8261
|
-
const namespace = url.searchParams.get("namespace")?.trim() ?? "";
|
|
8262
|
-
const blockId = url.searchParams.get("blockId")?.trim() ?? "";
|
|
8263
|
-
if (!namespace) throw new AdminHttpError(400, "namespace is required");
|
|
8264
|
-
if (!blockId) throw new AdminHttpError(400, "blockId is required");
|
|
8265
|
-
if (blockId.startsWith("virtual:")) throw new AdminHttpError(409, "Recovered legacy fragments cannot be retried");
|
|
8266
|
-
const snapshot = await requiredSnapshot(runtime, namespace);
|
|
8267
|
-
const job = snapshot.summaryJobs.find(({ blockId: candidateId }) => candidateId === blockId);
|
|
8268
|
-
if (!job) throw new AdminHttpError(404, `Unknown Block Summary job: ${blockId}`);
|
|
8269
|
-
if (job.status !== "failed" || job.nextRetryAt !== null) {
|
|
8270
|
-
throw new AdminHttpError(409, "Block Summary is not in a terminal failed state");
|
|
8271
|
-
}
|
|
8272
|
-
return runtime.adminRetryBlockSummary(namespace, blockId);
|
|
8273
|
-
}
|
|
8274
8139
|
function receiptSources(snapshot, receipt) {
|
|
8275
8140
|
const events = snapshot.events.filter(({ id }) => receipt.eventIds.includes(id));
|
|
8276
8141
|
const elements = snapshot.elements.filter(({ id }) => receipt.elementIds.includes(id));
|
|
@@ -8383,9 +8248,6 @@ async function handleAdminRequest(runtime, req, res) {
|
|
|
8383
8248
|
} else if (path === "/api/stratagate/blocks/expand") {
|
|
8384
8249
|
if (req.method !== "PATCH") throw new AdminHttpError(405, "StrataGate Block expansion requires PATCH");
|
|
8385
8250
|
sendJson(res, 200, await expandBlock(runtime, url));
|
|
8386
|
-
} else if (path === "/api/stratagate/blocks/retry-summary") {
|
|
8387
|
-
if (req.method !== "POST") throw new AdminHttpError(405, "StrataGate Block Summary retry requires POST");
|
|
8388
|
-
sendJson(res, 200, await retryBlockSummary(runtime, url));
|
|
8389
8251
|
} else if (path === "/api/stratagate/import") {
|
|
8390
8252
|
if (req.method === "GET") {
|
|
8391
8253
|
const operation = url.searchParams.get("operation");
|