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/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(12e4),
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 ?? 12e4)),
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 = 12e4;
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
- async space(session) {
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 (memory2) => {
6654
+ }).then(async (memory) => {
6755
6655
  try {
6756
6656
  try {
6757
- await memory2.resumePendingWork({ deferDerivation: true, threadId: String(session.id) });
6758
- const contexts = memory2.getBlockContext(String(session.id));
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(memory2);
6661
+ await this.persistSuccessfulResponses(memory);
6762
6662
  }
6763
- this.scheduleGraphMigration(session, memory2);
6764
- this.scheduleBlockDerivation(session, memory2);
6765
- return memory2;
6663
+ this.scheduleGraphMigration(session, memory);
6664
+ this.scheduleBlockDerivation(session, memory);
6665
+ return memory;
6766
6666
  } catch (error) {
6767
- await memory2.close().catch(() => {
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
- const memory = await opening;
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, options = {}) {
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.57";
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.summaryJobs.filter(({ status }) => status === "failed").length + snapshot.extractionJobs.filter(({ status }) => status === "failed").length + snapshot.graphProjectionJobs.filter(({ status }) => status === "failed").length;
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 = summary?.status === "failed" ? "failed" : summary?.status === "pending" || summary?.status === "running" || !summary && source.processingStatus === "pending" ? "processing" : extraction?.status === "failed" || failedProjection ? "failed" : extraction?.status === "succeeded" || extraction?.status === "skipped" ? pendingProjection ? "processing" : "organized" : needsExtraction ? "waiting" : "organized";
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");