stratagate-dsh 0.2.84 → 0.2.86

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/plugin.js CHANGED
@@ -11,6 +11,9 @@ var StructuredReasoningEffortSettings = z.object({
11
11
  showShortTermStatus: z.boolean().default(true).description("\u663E\u793A\u77ED\u671F\u8BB0\u5FC6\u5757\u72B6\u6001").comment("\u63A7\u5236\u77ED\u671F\u8BB0\u5FC6\u5757\u8FDB\u5EA6\u3001Block \u5C01\u5B58\u4E0E\u6574\u7406\u72B6\u6001\u7684\u804A\u5929\u5185\u63D0\u793A\uFF1B\u540E\u53F0\u5904\u7406\u4E0D\u53D7\u5F71\u54CD\u3002"),
12
12
  showRetrievalStatus: z.boolean().default(true).description("\u663E\u793A\u8BB0\u5FC6\u68C0\u7D22\u72B6\u6001").comment("\u63A7\u5236\u68C0\u7D22\u6B21\u6570\u3001\u8FD4\u56DE\u6570\u91CF\u548C\u8BB0\u5FC6\u91C7\u7528\u4FE1\u606F\u7684\u804A\u5929\u5185\u63D0\u793A\uFF1B\u68C0\u7D22\u4E0E\u91C7\u7528\u4E0D\u53D7\u5F71\u54CD\u3002")
13
13
  });
14
+ function volatileIfSupported(schema) {
15
+ return schema.volatile?.() ?? schema;
16
+ }
14
17
  var Config = z.object({
15
18
  database: z.string().required(),
16
19
  sessionRoot: z.string(),
@@ -24,11 +27,17 @@ var Config = z.object({
24
27
  model: z.string(),
25
28
  maxOutputTokens: z.natural().min(256).default(2048),
26
29
  structuredTaskTimeoutMs: z.natural().min(1e3).default(12e4),
27
- structuredReasoningEffort: z.union(["auto", "force-off"]).default("auto"),
28
- showStrataGateStatus: z.boolean().default(true),
29
- showShortTermStatus: z.boolean().default(true),
30
- showRetrievalStatus: z.boolean().default(true)
30
+ structuredReasoningEffort: volatileIfSupported(z.union(["auto", "force-off"]).default("auto")),
31
+ showStrataGateStatus: volatileIfSupported(z.boolean().default(true)),
32
+ showShortTermStatus: volatileIfSupported(z.boolean().default(true)),
33
+ showRetrievalStatus: volatileIfSupported(z.boolean().default(true))
31
34
  });
35
+ function liveConfigValue(value) {
36
+ return value && typeof value === "object" && "get" in value && typeof value.get === "function" ? value.get() : value;
37
+ }
38
+ function isLiveConfigValue(value) {
39
+ return value !== null && typeof value === "object" && "get" in value && typeof value.get === "function";
40
+ }
32
41
  function resolveConfig(config) {
33
42
  const database = config.database?.trim() ?? "";
34
43
  const sessionRoot = config.sessionRoot?.trim();
@@ -52,10 +61,10 @@ function resolveConfig(config) {
52
61
  ...provider && model ? { provider, model } : {},
53
62
  maxOutputTokens: Math.max(256, Math.floor(config.maxOutputTokens ?? 2048)),
54
63
  structuredTaskTimeoutMs: Math.max(1e3, Math.floor(config.structuredTaskTimeoutMs ?? 12e4)),
55
- structuredReasoningEffort: config.structuredReasoningEffort ?? "auto",
56
- showStrataGateStatus: config.showStrataGateStatus ?? true,
57
- showShortTermStatus: config.showShortTermStatus ?? true,
58
- showRetrievalStatus: config.showRetrievalStatus ?? true
64
+ structuredReasoningEffort: liveConfigValue(config.structuredReasoningEffort) ?? "auto",
65
+ showStrataGateStatus: liveConfigValue(config.showStrataGateStatus) ?? true,
66
+ showShortTermStatus: liveConfigValue(config.showShortTermStatus) ?? true,
67
+ showRetrievalStatus: liveConfigValue(config.showRetrievalStatus) ?? true
59
68
  };
60
69
  }
61
70
 
@@ -5573,6 +5582,125 @@ var StrataGate = class _StrataGate {
5573
5582
  }
5574
5583
  };
5575
5584
 
5585
+ // src/dsh-compatibility.ts
5586
+ import { readFileSync } from "node:fs";
5587
+ import { createRequire } from "node:module";
5588
+ var nodeRequire = createRequire(import.meta.url);
5589
+ var RUNTIME_PACKAGES = [
5590
+ "@deepseek-ai/cordis",
5591
+ "@deepseek-ai/dsh-agent-default-model",
5592
+ "@deepseek-ai/dsh-client-ui-conversation",
5593
+ "@deepseek-ai/dsh-llm",
5594
+ "@deepseek-ai/dsh-native-command",
5595
+ "@deepseek-ai/dsh-session",
5596
+ "@deepseek-ai/dsh-settings",
5597
+ "@deepseek-ai/dsh-system-prompt",
5598
+ "@deepseek-ai/dsh-tools",
5599
+ "@deepseek-ai/schemastery"
5600
+ ];
5601
+ var SUPPORTED_RUNTIME_FAMILIES = [
5602
+ {
5603
+ cli: "0.1.2-rc.1",
5604
+ versions: {
5605
+ "@deepseek-ai/cordis": "4.0.2",
5606
+ "@deepseek-ai/dsh-agent-default-model": "0.1.2-rc.1",
5607
+ "@deepseek-ai/dsh-client-ui-conversation": "0.1.2-rc.1",
5608
+ "@deepseek-ai/dsh-llm": "0.1.2-rc.1",
5609
+ "@deepseek-ai/dsh-native-command": "0.1.2-rc.1",
5610
+ "@deepseek-ai/dsh-session": "0.1.2-rc.1",
5611
+ "@deepseek-ai/dsh-settings": "0.1.2-rc.1",
5612
+ "@deepseek-ai/dsh-system-prompt": "0.1.2-rc.1",
5613
+ "@deepseek-ai/dsh-tools": "0.1.2-rc.1",
5614
+ "@deepseek-ai/schemastery": "3.18.2"
5615
+ }
5616
+ },
5617
+ {
5618
+ cli: "0.1.5-rc.1",
5619
+ versions: {
5620
+ "@deepseek-ai/cordis": "4.0.2",
5621
+ "@deepseek-ai/dsh-agent-default-model": "0.1.5-rc.2",
5622
+ "@deepseek-ai/dsh-client-ui-conversation": "0.1.5-rc.2",
5623
+ "@deepseek-ai/dsh-llm": "0.1.5-rc.2",
5624
+ "@deepseek-ai/dsh-native-command": "0.1.5-rc.2",
5625
+ "@deepseek-ai/dsh-session": "0.1.5-rc.2",
5626
+ "@deepseek-ai/dsh-settings": "0.1.5-rc.2",
5627
+ "@deepseek-ai/dsh-system-prompt": "0.1.5-rc.2",
5628
+ "@deepseek-ai/dsh-tools": "0.1.5-rc.2",
5629
+ "@deepseek-ai/schemastery": "3.18.2"
5630
+ }
5631
+ },
5632
+ {
5633
+ cli: "0.1.6-alpha.1",
5634
+ versions: {
5635
+ "@deepseek-ai/cordis": "4.0.2",
5636
+ "@deepseek-ai/dsh-agent-default-model": "0.1.6-alpha.1",
5637
+ "@deepseek-ai/dsh-client-ui-conversation": "0.1.6-alpha.1",
5638
+ "@deepseek-ai/dsh-llm": "0.1.6-alpha.1",
5639
+ "@deepseek-ai/dsh-native-command": "0.1.6-alpha.1",
5640
+ "@deepseek-ai/dsh-session": "0.1.6-alpha.1",
5641
+ "@deepseek-ai/dsh-settings": "0.1.6-alpha.1",
5642
+ "@deepseek-ai/dsh-system-prompt": "0.1.6-alpha.1",
5643
+ "@deepseek-ai/dsh-tools": "0.1.6-alpha.1",
5644
+ "@deepseek-ai/schemastery": "3.18.2"
5645
+ }
5646
+ },
5647
+ {
5648
+ cli: "0.1.7-rc.1",
5649
+ versions: {
5650
+ "@deepseek-ai/cordis": "4.0.4",
5651
+ "@deepseek-ai/dsh-agent-default-model": "0.1.7-rc.1",
5652
+ "@deepseek-ai/dsh-client-ui-conversation": "0.1.7-rc.1",
5653
+ "@deepseek-ai/dsh-llm": "0.1.7-rc.1",
5654
+ "@deepseek-ai/dsh-native-command": "0.1.7-rc.1",
5655
+ "@deepseek-ai/dsh-session": "0.1.7-rc.1",
5656
+ "@deepseek-ai/dsh-settings": "0.1.7-rc.1",
5657
+ "@deepseek-ai/dsh-system-prompt": "0.1.7-rc.1",
5658
+ "@deepseek-ai/dsh-tools": "0.1.7-rc.1",
5659
+ "@deepseek-ai/schemastery": "3.18.4"
5660
+ }
5661
+ }
5662
+ ];
5663
+ var STRATAGATE_MESSAGE_SOURCE_KIND = "plugin:stratagate-memory";
5664
+ function buildDshMessageSource(version, form) {
5665
+ const source = version === "0.1.7-rc.1" ? { kind: STRATAGATE_MESSAGE_SOURCE_KIND } : { kind: "plugin", plugin: "stratagate-memory" };
5666
+ return form ? { ...source, form } : source;
5667
+ }
5668
+ function installedVersion(packageName) {
5669
+ try {
5670
+ const manifestPath = nodeRequire.resolve(`${packageName}/package.json`);
5671
+ const manifest = JSON.parse(readFileSync(manifestPath, "utf8"));
5672
+ if (typeof manifest.version === "string" && manifest.version.length > 0) return manifest.version;
5673
+ } catch {
5674
+ }
5675
+ return "<missing>";
5676
+ }
5677
+ function buildDshReplaceSurfaceOp(version, start, end) {
5678
+ return version === "0.1.2-rc.1" ? { op: "replace", start, end } : { op: "replace", startSeq: start, endSeq: end };
5679
+ }
5680
+ function dshReplaceSurfaceOp(start, end) {
5681
+ return buildDshReplaceSurfaceOp(installedVersion("@deepseek-ai/dsh-session"), start, end);
5682
+ }
5683
+ function dshMessageSource(form) {
5684
+ return buildDshMessageSource(installedVersion("@deepseek-ai/dsh-session"), form);
5685
+ }
5686
+ function isStrataGateMessageSource(source) {
5687
+ if (!source || typeof source !== "object") return false;
5688
+ const value = source;
5689
+ return value.kind === STRATAGATE_MESSAGE_SOURCE_KIND || value.kind === "plugin" && value.plugin === "stratagate-memory";
5690
+ }
5691
+ function classifyDshRuntime(packageVersions) {
5692
+ const family = SUPPORTED_RUNTIME_FAMILIES.find(({ versions }) => RUNTIME_PACKAGES.every((name2) => packageVersions[name2] === versions[name2]));
5693
+ if (family) return { cliVersion: family.cli, packageVersions };
5694
+ const found = RUNTIME_PACKAGES.map((name2) => `${name2}@${packageVersions[name2]}`).join(", ");
5695
+ throw new Error(
5696
+ `StrataGate cannot start because this DSH profile resolves an unsupported or mixed core runtime. Resolved: ${found}. Supported tested hosts are @deepseek-ai/dsh@0.1.2-rc.1 (internal DSH packages 0.1.2-rc.1) and @deepseek-ai/dsh@0.1.5-rc.1 (its real dependency tree uses internal DSH packages 0.1.5-rc.2), and @deepseek-ai/dsh@0.1.6-alpha.1 (internal DSH packages 0.1.6-alpha.1), and @deepseek-ai/dsh@0.1.7-rc.1 (internal DSH packages 0.1.7-rc.1). Reinstall or update stratagate-dsh through \`dsh plugin --profile <name> add <package>\` so the host supplies its peers.`
5697
+ );
5698
+ }
5699
+ function assertCompatibleDshRuntime() {
5700
+ const packageVersions = Object.fromEntries(RUNTIME_PACKAGES.map((name2) => [name2, installedVersion(name2)]));
5701
+ return classifyDshRuntime(packageVersions);
5702
+ }
5703
+
5576
5704
  // src/json-response.ts
5577
5705
  var RESPONSE_PREVIEW_LIMIT = 500;
5578
5706
  function truncateResponsePreview(value) {
@@ -5994,9 +6122,10 @@ function compactGraphProjectionContext(context) {
5994
6122
  };
5995
6123
  }
5996
6124
  var DshModelBridge = class {
5997
- constructor(ctx, config) {
6125
+ constructor(ctx, config, liveStructuredReasoningEffort) {
5998
6126
  this.ctx = ctx;
5999
6127
  this.config = config;
6128
+ this.liveStructuredReasoningEffort = liveStructuredReasoningEffort;
6000
6129
  this.structuredReasoningEffort = config.structuredReasoningEffort ?? "auto";
6001
6130
  this.ctx.on?.("llm/adapters-updated", () => {
6002
6131
  this.offCapabilities.clear();
@@ -6005,6 +6134,7 @@ var DshModelBridge = class {
6005
6134
  }
6006
6135
  ctx;
6007
6136
  config;
6137
+ liveStructuredReasoningEffort;
6008
6138
  sessions = new AsyncLocalStorage();
6009
6139
  successfulResponses = [];
6010
6140
  offCapabilities = /* @__PURE__ */ new Map();
@@ -6030,6 +6160,9 @@ var DshModelBridge = class {
6030
6160
  setStructuredReasoningEffort(mode) {
6031
6161
  this.structuredReasoningEffort = mode;
6032
6162
  }
6163
+ currentStructuredReasoningEffort() {
6164
+ return this.liveStructuredReasoningEffort?.() ?? this.structuredReasoningEffort;
6165
+ }
6033
6166
  run(session, operation) {
6034
6167
  return this.sessions.run({ session, sessionId: session.id }, operation);
6035
6168
  }
@@ -6258,7 +6391,7 @@ var DshModelBridge = class {
6258
6391
  attemptsUsed = attempt;
6259
6392
  const message = createUserMessage({
6260
6393
  content: [{ type: "text", text: JSON.stringify(payload) }],
6261
- source: { kind: "plugin", plugin: "stratagate-memory" }
6394
+ source: dshMessageSource()
6262
6395
  });
6263
6396
  const assembler = new BlockAssembler();
6264
6397
  const request = {
@@ -6392,14 +6525,14 @@ ${JSON_RETRY_INSTRUCTION}`,
6392
6525
  const key = `${route.provider}\0${route.model}`;
6393
6526
  const cached = this.offCapabilities.get(key);
6394
6527
  if (cached) {
6395
- if (cached === "unsupported" && this.structuredReasoningEffort === "force-off") {
6528
+ if (cached === "unsupported" && this.currentStructuredReasoningEffort() === "force-off") {
6396
6529
  this.warnOffFallbackOnce(key, `${route.provider}/${route.model} does not support reasoningEffort=off; using the model default`);
6397
6530
  }
6398
6531
  return cached === "supported";
6399
6532
  }
6400
6533
  if (typeof this.ctx.llm.resolveModelInfo !== "function") {
6401
6534
  this.offCapabilities.set(key, "unsupported");
6402
- if (this.structuredReasoningEffort === "force-off") {
6535
+ if (this.currentStructuredReasoningEffort() === "force-off") {
6403
6536
  this.warnOffFallbackOnce(key, `${route.provider}/${route.model} capabilities are unavailable; using the model default`);
6404
6537
  }
6405
6538
  return false;
@@ -6418,16 +6551,16 @@ ${JSON_RETRY_INSTRUCTION}`,
6418
6551
  timer.unref?.();
6419
6552
  })
6420
6553
  ]);
6421
- if (!info.reasoning) return this.structuredReasoningEffort === "force-off";
6554
+ if (!info.reasoning) return this.currentStructuredReasoningEffort() === "force-off";
6422
6555
  const supported = info.reasoning.efforts.some(({ id }) => String(id) === "off");
6423
6556
  this.offCapabilities.set(key, supported ? "supported" : "unsupported");
6424
- if (!supported && this.structuredReasoningEffort === "force-off") {
6557
+ if (!supported && this.currentStructuredReasoningEffort() === "force-off") {
6425
6558
  this.warnOffFallbackOnce(key, `${route.provider}/${route.model} does not support reasoningEffort=off; using the model default`);
6426
6559
  }
6427
6560
  return supported;
6428
6561
  } catch {
6429
6562
  this.offCapabilities.set(key, "unsupported");
6430
- if (this.structuredReasoningEffort === "force-off") {
6563
+ if (this.currentStructuredReasoningEffort() === "force-off") {
6431
6564
  this.warnOffFallbackOnce(key, `${route.provider}/${route.model} capability lookup failed; using the model default`);
6432
6565
  }
6433
6566
  return false;
@@ -6516,13 +6649,14 @@ function renderBlocks(blocks) {
6516
6649
  break;
6517
6650
  case "tool-call":
6518
6651
  break;
6519
- case "tool-result": {
6520
- const nested = renderBlocks(block.content);
6521
- if (nested) output.push(nested);
6652
+ default: {
6653
+ const legacy = block;
6654
+ if (legacy.type === "tool-result" && legacy.content) {
6655
+ const nested = renderBlocks(legacy.content);
6656
+ if (nested) output.push(nested);
6657
+ }
6522
6658
  break;
6523
6659
  }
6524
- default:
6525
- break;
6526
6660
  }
6527
6661
  }
6528
6662
  return output.join("\n").trim();
@@ -6574,6 +6708,7 @@ var TurnFolder = class {
6574
6708
  return null;
6575
6709
  }
6576
6710
  case "tool/result": {
6711
+ if (event.surfaceOp && event.surfaceOp !== "append") return null;
6577
6712
  const callId = String(event.data.message.source.callId);
6578
6713
  const pending = this.pending(sessionId, event.data.turn);
6579
6714
  if (pending.ignoredTools.has(callId)) return null;
@@ -6618,93 +6753,6 @@ var TurnFolder = class {
6618
6753
  }
6619
6754
  };
6620
6755
 
6621
- // src/dsh-compatibility.ts
6622
- import { readFileSync } from "node:fs";
6623
- import { createRequire } from "node:module";
6624
- var nodeRequire = createRequire(import.meta.url);
6625
- var RUNTIME_PACKAGES = [
6626
- "@deepseek-ai/cordis",
6627
- "@deepseek-ai/dsh-agent-default-model",
6628
- "@deepseek-ai/dsh-client-ui-conversation",
6629
- "@deepseek-ai/dsh-llm",
6630
- "@deepseek-ai/dsh-session",
6631
- "@deepseek-ai/dsh-settings",
6632
- "@deepseek-ai/dsh-system-prompt",
6633
- "@deepseek-ai/dsh-tools",
6634
- "@deepseek-ai/schemastery"
6635
- ];
6636
- var SUPPORTED_RUNTIME_FAMILIES = [
6637
- {
6638
- cli: "0.1.2-rc.1",
6639
- versions: {
6640
- "@deepseek-ai/cordis": "4.0.2",
6641
- "@deepseek-ai/dsh-agent-default-model": "0.1.2-rc.1",
6642
- "@deepseek-ai/dsh-client-ui-conversation": "0.1.2-rc.1",
6643
- "@deepseek-ai/dsh-llm": "0.1.2-rc.1",
6644
- "@deepseek-ai/dsh-session": "0.1.2-rc.1",
6645
- "@deepseek-ai/dsh-settings": "0.1.2-rc.1",
6646
- "@deepseek-ai/dsh-system-prompt": "0.1.2-rc.1",
6647
- "@deepseek-ai/dsh-tools": "0.1.2-rc.1",
6648
- "@deepseek-ai/schemastery": "3.18.2"
6649
- }
6650
- },
6651
- {
6652
- cli: "0.1.5-rc.1",
6653
- versions: {
6654
- "@deepseek-ai/cordis": "4.0.2",
6655
- "@deepseek-ai/dsh-agent-default-model": "0.1.5-rc.2",
6656
- "@deepseek-ai/dsh-client-ui-conversation": "0.1.5-rc.2",
6657
- "@deepseek-ai/dsh-llm": "0.1.5-rc.2",
6658
- "@deepseek-ai/dsh-session": "0.1.5-rc.2",
6659
- "@deepseek-ai/dsh-settings": "0.1.5-rc.2",
6660
- "@deepseek-ai/dsh-system-prompt": "0.1.5-rc.2",
6661
- "@deepseek-ai/dsh-tools": "0.1.5-rc.2",
6662
- "@deepseek-ai/schemastery": "3.18.2"
6663
- }
6664
- },
6665
- {
6666
- cli: "0.1.6-alpha.1",
6667
- versions: {
6668
- "@deepseek-ai/cordis": "4.0.2",
6669
- "@deepseek-ai/dsh-agent-default-model": "0.1.6-alpha.1",
6670
- "@deepseek-ai/dsh-client-ui-conversation": "0.1.6-alpha.1",
6671
- "@deepseek-ai/dsh-llm": "0.1.6-alpha.1",
6672
- "@deepseek-ai/dsh-session": "0.1.6-alpha.1",
6673
- "@deepseek-ai/dsh-settings": "0.1.6-alpha.1",
6674
- "@deepseek-ai/dsh-system-prompt": "0.1.6-alpha.1",
6675
- "@deepseek-ai/dsh-tools": "0.1.6-alpha.1",
6676
- "@deepseek-ai/schemastery": "3.18.2"
6677
- }
6678
- }
6679
- ];
6680
- function installedVersion(packageName) {
6681
- try {
6682
- const manifestPath = nodeRequire.resolve(`${packageName}/package.json`);
6683
- const manifest = JSON.parse(readFileSync(manifestPath, "utf8"));
6684
- if (typeof manifest.version === "string" && manifest.version.length > 0) return manifest.version;
6685
- } catch {
6686
- }
6687
- return "<missing>";
6688
- }
6689
- function buildDshReplaceSurfaceOp(version, start, end) {
6690
- return version === "0.1.2-rc.1" ? { op: "replace", start, end } : { op: "replace", startSeq: start, endSeq: end };
6691
- }
6692
- function dshReplaceSurfaceOp(start, end) {
6693
- return buildDshReplaceSurfaceOp(installedVersion("@deepseek-ai/dsh-session"), start, end);
6694
- }
6695
- function classifyDshRuntime(packageVersions) {
6696
- const family = SUPPORTED_RUNTIME_FAMILIES.find(({ versions }) => RUNTIME_PACKAGES.every((name2) => packageVersions[name2] === versions[name2]));
6697
- if (family) return { cliVersion: family.cli, packageVersions };
6698
- const found = RUNTIME_PACKAGES.map((name2) => `${name2}@${packageVersions[name2]}`).join(", ");
6699
- throw new Error(
6700
- `StrataGate cannot start because this DSH profile resolves an unsupported or mixed core runtime. Resolved: ${found}. Supported tested hosts are @deepseek-ai/dsh@0.1.2-rc.1 (internal DSH packages 0.1.2-rc.1) and @deepseek-ai/dsh@0.1.5-rc.1 (its real dependency tree uses internal DSH packages 0.1.5-rc.2), and @deepseek-ai/dsh@0.1.6-alpha.1 (internal DSH packages 0.1.6-alpha.1). Reinstall or update stratagate-dsh through \`dsh plugin --profile <name> add <package>\` so the host supplies its peers.`
6701
- );
6702
- }
6703
- function assertCompatibleDshRuntime() {
6704
- const packageVersions = Object.fromEntries(RUNTIME_PACKAGES.map((name2) => [name2, installedVersion(name2)]));
6705
- return classifyDshRuntime(packageVersions);
6706
- }
6707
-
6708
6756
  // src/metadata.ts
6709
6757
  import { DatabaseSync as DatabaseSync2 } from "node:sqlite";
6710
6758
  var METADATA_SCHEMA = `
@@ -6818,7 +6866,6 @@ function graphProjectionCanRun(job, now = Date.now()) {
6818
6866
  var AUTO_EVENT_LIMIT = 4;
6819
6867
  var AUTO_ELEMENT_LIMIT = 4;
6820
6868
  var AUTO_MEMORY_TOKEN_BUDGET = 900;
6821
- var COMPACTION_SOURCE_PLUGIN = "stratagate-memory";
6822
6869
  var FEEDBACK_PROMPT_COOLDOWN_MS = 5 * 24 * 60 * 60 * 1e3;
6823
6870
  function projectKey(cwd) {
6824
6871
  const canonical = resolve(cwd ?? process.cwd()).replaceAll("\\", "/").toLowerCase();
@@ -7483,7 +7530,7 @@ var StrataGateRuntime = class {
7483
7530
  const memory = await this.space(session);
7484
7531
  const threadId = String(session.id);
7485
7532
  const blockContexts = memory.getBlockContext(threadId);
7486
- if (this.syncDecayedBlockSurface(session, blockContexts)) {
7533
+ if (this.syncDecayedBlockSurface(session, memory, blockContexts)) {
7487
7534
  await this.flushNativeSession(session);
7488
7535
  }
7489
7536
  const openTail = memory.listOpenTail(threadId);
@@ -7526,32 +7573,54 @@ var StrataGateRuntime = class {
7526
7573
  * while deriveMessages() sees only this compressed checkpoint.
7527
7574
  */
7528
7575
  replaceSealedSurface(session, block, context, endTurn) {
7529
- const sourceEventSeqs = sealedSurfaceSeqs(session, endTurn, block.endTurn - block.startTurn + 1);
7576
+ if (endTurn === null || hostCompactionActive(session)) return false;
7577
+ const sourceEventSeqs = sealedSurfaceSeqs(session, endTurn, block);
7578
+ if (!sourceEventSeqs) return false;
7530
7579
  const start = sourceEventSeqs[0];
7531
7580
  const end = sourceEventSeqs.at(-1);
7532
- if (start === void 0 || end === void 0) {
7533
- throw new Error(`Cannot compact StrataGate block ${block.id}: no DSH surface range was found`);
7534
- }
7581
+ if (start === void 0 || end === void 0) return false;
7582
+ const selected = selectCompressedBlockSurface(session, sourceEventSeqs, block, context);
7583
+ if (!selected) return false;
7535
7584
  session.append("user/message", createUserMessage2({
7536
- content: [{ type: "text", text: renderBlockSurfaceMessage(context) }],
7537
- source: { kind: "plugin", plugin: COMPACTION_SOURCE_PLUGIN }
7585
+ content: [{ type: "text", text: selected }],
7586
+ source: dshMessageSource()
7538
7587
  }), {
7539
7588
  surfaceOp: dshReplaceSurfaceOp(start, end),
7540
7589
  sourceEventSeqs
7541
7590
  });
7591
+ return true;
7542
7592
  }
7543
7593
  /** Keep each native Block checkpoint synchronized with its current decay pointer. */
7544
- syncDecayedBlockSurface(session, contexts) {
7594
+ syncDecayedBlockSurface(session, memory, contexts) {
7595
+ if (hostCompactionActive(session)) return false;
7545
7596
  const current = currentBlockSurfaceMessages(session);
7597
+ const blocks = new Map(memory.listBlocks().map((block) => [block.id, block]));
7598
+ const checkpointLimit = surfaceCheckpointLimit(session);
7546
7599
  let changed = false;
7547
7600
  for (const context of contexts) {
7548
7601
  const node = current.get(context.id);
7549
7602
  if (!node) continue;
7550
- const text3 = renderBlockSurfaceMessage(context);
7603
+ const currentLevel = Number(node.text.match(/^Level: L([0-5]) /mu)?.[1] ?? -1);
7604
+ const currentTokens = surfaceCheckpointTokens(node.text);
7605
+ const sourceTokens = originalCheckpointSourceTokens(session, node.seq);
7606
+ const violatesLimit = currentTokens > checkpointLimit || sourceTokens !== null && !worthwhileSurfaceReduction(sourceTokens, currentTokens);
7607
+ if (context.level >= currentLevel && currentLevel >= 0 && !violatesLimit) continue;
7608
+ const block = blocks.get(context.id);
7609
+ if (!block) continue;
7610
+ const highestLevel = currentLevel >= 0 ? Math.min(context.level, currentLevel) : context.level;
7611
+ const text3 = selectCompressedBlockSurfaceText(
7612
+ node.text,
7613
+ context,
7614
+ block,
7615
+ highestLevel,
7616
+ sourceTokens,
7617
+ checkpointLimit
7618
+ );
7619
+ if (!text3) continue;
7551
7620
  if (node.text === text3) continue;
7552
7621
  session.append("user/message", createUserMessage2({
7553
7622
  content: [{ type: "text", text: text3 }],
7554
- source: { kind: "plugin", plugin: COMPACTION_SOURCE_PLUGIN }
7623
+ source: dshMessageSource()
7555
7624
  }), {
7556
7625
  surfaceOp: dshReplaceSurfaceOp(node.seq, node.seq),
7557
7626
  sourceEventSeqs: [node.seq]
@@ -7562,6 +7631,7 @@ var StrataGateRuntime = class {
7562
7631
  }
7563
7632
  /** Finish native-surface replacement when an admin retry ran without the target session loaded. */
7564
7633
  async syncPendingRetrySurface(session, memory) {
7634
+ if (hostCompactionActive(session)) return;
7565
7635
  const namespace = this.namespaceFor(session);
7566
7636
  const threadId = String(session.id);
7567
7637
  const pending = [...this.pendingSurfaceSync.entries()].filter(([, item]) => item.namespace === namespace);
@@ -7578,9 +7648,8 @@ var StrataGateRuntime = class {
7578
7648
  const context = contexts.get(blockId);
7579
7649
  if (!block || block.processingStatus !== "ready" || !context) continue;
7580
7650
  try {
7581
- this.replaceSealedSurface(session, block, context, dshTurnAtBlockEnd(session, block));
7651
+ changed = this.replaceSealedSurface(session, block, context, dshTurnAtBlockEnd(session, block)) || changed;
7582
7652
  this.pendingSurfaceSync.delete(key);
7583
- changed = true;
7584
7653
  } catch (error) {
7585
7654
  this.onIngestError(error);
7586
7655
  }
@@ -8286,7 +8355,9 @@ var StrataGateRuntime = class {
8286
8355
  try {
8287
8356
  await memory2.resumePendingWork({ deferDerivation: true, threadId: String(session.id) });
8288
8357
  const contexts = memory2.getBlockContext(String(session.id));
8289
- this.syncDecayedBlockSurface(session, contexts);
8358
+ if (this.syncDecayedBlockSurface(session, memory2, contexts)) {
8359
+ await this.flushNativeSession(session);
8360
+ }
8290
8361
  } finally {
8291
8362
  await this.persistSuccessfulResponses(memory2);
8292
8363
  }
@@ -8382,14 +8453,22 @@ var StrataGateRuntime = class {
8382
8453
  await this.persistSuccessfulResponses(memory);
8383
8454
  this.noteNewCoreJobFailures(session, failedBefore, memory);
8384
8455
  const contexts = memory.getBlockContext(threadId);
8456
+ let changed = false;
8385
8457
  for (const block of resumed.readyBlocks) {
8386
8458
  if (block.threadId !== threadId) continue;
8387
8459
  const context = contexts.find(({ id }) => id === block.id);
8388
8460
  if (!context) throw new Error(`Missing context for ready StrataGate block ${block.id}`);
8389
- this.replaceSealedSurface(session, block, context, dshTurnAtBlockEnd(session, block));
8461
+ if (hostCompactionActive(session)) {
8462
+ this.pendingSurfaceSync.set(`${this.namespaceFor(session)}\0${block.id}`, {
8463
+ namespace: this.namespaceFor(session),
8464
+ blockId: block.id
8465
+ });
8466
+ continue;
8467
+ }
8468
+ changed = this.replaceSealedSurface(session, block, context, dshTurnAtBlockEnd(session, block)) || changed;
8390
8469
  }
8391
- const changed = this.syncDecayedBlockSurface(session, contexts);
8392
- if (resumed.readyBlocks.length > 0 || changed) await this.flushNativeSession(session);
8470
+ changed = this.syncDecayedBlockSurface(session, memory, contexts) || changed;
8471
+ if (changed) await this.flushNativeSession(session);
8393
8472
  }).catch((error) => {
8394
8473
  this.notePluginError(session, error);
8395
8474
  this.onIngestError(error);
@@ -8551,8 +8630,11 @@ function renderContent(content) {
8551
8630
  output.push(block.text.trim());
8552
8631
  } else if (block.type === "image") {
8553
8632
  output.push("[image]");
8554
- } else if (block.type === "tool-result" && Array.isArray(block.content)) {
8555
- output.push(renderContent(block.content));
8633
+ } else {
8634
+ const legacy = block;
8635
+ if (legacy.type === "tool-result" && Array.isArray(legacy.content)) {
8636
+ output.push(renderContent(legacy.content));
8637
+ }
8556
8638
  }
8557
8639
  }
8558
8640
  return output.filter(Boolean).join("\n");
@@ -8580,11 +8662,10 @@ function dshTurnAtBlockEnd(session, block) {
8580
8662
  const event = events[index];
8581
8663
  if (event?.type === "turn/end" && event.time === blockEnd) return event.data.turn;
8582
8664
  }
8583
- throw new Error(`Cannot match StrataGate block ${block.id} to its completed DSH turn`);
8665
+ return null;
8584
8666
  }
8585
- function sealedSurfaceSeqs(session, endTurn, turnCount) {
8667
+ function sealedSurfaceSeqs(session, endTurn, block) {
8586
8668
  const currentSurface = [...session.surface.nodes];
8587
- const currentSet = new Set(currentSurface);
8588
8669
  const completed = [];
8589
8670
  let open2;
8590
8671
  const events = session.snapshotEvents();
@@ -8599,30 +8680,122 @@ function sealedSurfaceSeqs(session, endTurn, turnCount) {
8599
8680
  if (hasHumanMessage && event.data.turn <= endTurn) {
8600
8681
  completed.push({
8601
8682
  turn: event.data.turn,
8683
+ endTime: event.time,
8602
8684
  start: open2.start,
8603
8685
  end: event.seq,
8604
- nodes: currentSurface.filter((seq) => seq > open2.start && seq < event.seq && currentSet.has(seq))
8686
+ nodes: currentSurface.filter((seq) => {
8687
+ if (seq > open2.start && seq < event.seq) return true;
8688
+ const current = session.eventAt(seq);
8689
+ return current?.type === "tool/result" && current.surfaceOp !== "append" && current.sourceEventSeqs?.some((source) => source > open2.start && source < event.seq);
8690
+ })
8605
8691
  });
8606
8692
  }
8607
8693
  open2 = void 0;
8608
8694
  }
8695
+ const sourceTimes = block.l5Raw.filter((message) => message.role === "user").map((message) => Date.parse(message.createdAt));
8696
+ const turnCount = block.endTurn - block.startTurn + 1;
8609
8697
  const selected = completed.slice(-turnCount);
8610
- if (selected.length !== turnCount || selected.at(-1)?.turn !== endTurn) {
8611
- throw new Error(`Cannot identify ${turnCount} completed DSH turns ending at turn ${endTurn}`);
8612
- }
8698
+ if (selected.length !== turnCount || selected.at(-1)?.turn !== endTurn || sourceTimes.length !== turnCount || selected.some((turn, index) => turn.endTime !== sourceTimes[index])) return null;
8699
+ const firstTurn = selected[0];
8700
+ const lastTurn = selected.at(-1);
8701
+ if (events.some((event) => {
8702
+ const hostEvent = event;
8703
+ return hostEvent.type === "compaction/summary" && hostEvent.data.shadowedSeqs?.some((seq) => seq >= firstTurn.start && seq <= lastTurn.end);
8704
+ })) return null;
8613
8705
  const emptyTurn = selected.find((turn) => turn.nodes.length === 0);
8614
- if (emptyTurn) {
8615
- throw new Error(`Cannot compact DSH turn ${emptyTurn.turn}: its original messages are no longer on the surface`);
8616
- }
8706
+ if (emptyTurn) return null;
8617
8707
  const start = selected[0].nodes[0];
8618
8708
  const end = selected.at(-1).nodes.at(-1);
8619
8709
  const startIndex = currentSurface.indexOf(start);
8620
8710
  const endIndex = currentSurface.indexOf(end);
8621
- if (startIndex < 0 || endIndex < startIndex) {
8622
- throw new Error(`Cannot identify a contiguous DSH surface range ending at turn ${endTurn}`);
8623
- }
8711
+ if (startIndex < 0 || endIndex < startIndex) return null;
8624
8712
  return currentSurface.slice(startIndex, endIndex + 1);
8625
8713
  }
8714
+ function hostCompactionActive(session) {
8715
+ let lastBoundary;
8716
+ let lastSeed;
8717
+ for (let seq = session.seq - 1; seq >= 0; seq -= 1) {
8718
+ const event = session.eventAt(seq);
8719
+ if (!event) continue;
8720
+ if (lastSeed === void 0 && event.type === "session/end-seed") lastSeed = seq;
8721
+ if (!lastBoundary && (String(event.type) === "compaction/start" || String(event.type) === "compaction/end")) lastBoundary = event;
8722
+ if (lastSeed !== void 0 && lastBoundary) break;
8723
+ }
8724
+ return lastBoundary?.type === "compaction/start" && (lastSeed === void 0 || lastBoundary.seq > lastSeed);
8725
+ }
8726
+ var SURFACE_MIN_SAVED_TOKENS = 32;
8727
+ var SURFACE_MAX_REPLACEMENT_RATIO = 0.9;
8728
+ var SURFACE_MAX_WINDOW_FRACTION = 0.04;
8729
+ var SURFACE_CHECKPOINT_CEILING_TOKENS = 4096;
8730
+ function surfaceCheckpointLimit(session) {
8731
+ const window = typeof session.requestContext === "function" ? session.requestContext()?.contextWindow : void 0;
8732
+ return typeof window === "number" && Number.isInteger(window) && window > 0 ? Math.max(1, Math.min(SURFACE_CHECKPOINT_CEILING_TOKENS, Math.floor(window * SURFACE_MAX_WINDOW_FRACTION))) : SURFACE_CHECKPOINT_CEILING_TOKENS;
8733
+ }
8734
+ function surfaceCheckpointTokens(text3) {
8735
+ return estimateTokens(JSON.stringify(createUserMessage2({
8736
+ content: [{ type: "text", text: text3 }],
8737
+ source: dshMessageSource()
8738
+ })));
8739
+ }
8740
+ function originalCheckpointSourceTokens(session, seq) {
8741
+ const visited = /* @__PURE__ */ new Set();
8742
+ const visit = (sourceSeq) => {
8743
+ if (visited.has(sourceSeq)) return null;
8744
+ visited.add(sourceSeq);
8745
+ const event = session.eventAt(sourceSeq);
8746
+ if (!event) return null;
8747
+ if (event.type === "user/message" && isStrataGateMessageSource(event.data.source)) {
8748
+ const sources2 = event.sourceEventSeqs;
8749
+ if (!sources2?.length) return null;
8750
+ let total = 0;
8751
+ for (const source of sources2) {
8752
+ const tokens = visit(source);
8753
+ if (tokens === null) return null;
8754
+ total += tokens;
8755
+ }
8756
+ return total;
8757
+ }
8758
+ const message = session.deriveEventMessage(event);
8759
+ return message ? estimateTokens(JSON.stringify(message)) : null;
8760
+ };
8761
+ return visit(seq);
8762
+ }
8763
+ function worthwhileSurfaceReduction(before, after) {
8764
+ return before - after >= SURFACE_MIN_SAVED_TOKENS && after <= before * SURFACE_MAX_REPLACEMENT_RATIO;
8765
+ }
8766
+ function selectCompressedBlockSurfaceText(currentText, context, block, highestLevel, sourceTokens, checkpointLimit) {
8767
+ const before = surfaceCheckpointTokens(currentText);
8768
+ for (let level = highestLevel; level >= 0; level -= 1) {
8769
+ const candidate = renderBlockSurfaceMessage({
8770
+ ...context,
8771
+ level,
8772
+ label: blockLevelLabel(level),
8773
+ content: level === context.level ? context.content : renderBlock(block, level)
8774
+ });
8775
+ const tokens = surfaceCheckpointTokens(candidate);
8776
+ if (tokens <= checkpointLimit && worthwhileSurfaceReduction(before, tokens) && (sourceTokens === null || worthwhileSurfaceReduction(sourceTokens, tokens))) return candidate;
8777
+ }
8778
+ return null;
8779
+ }
8780
+ function selectCompressedBlockSurface(session, sourceSeqs, block, context) {
8781
+ const before = sourceSeqs.reduce((sum, seq) => {
8782
+ const event = session.eventAt(seq);
8783
+ const message = event && session.deriveEventMessage(event);
8784
+ return sum + (message ? estimateTokens(JSON.stringify(message)) : 0);
8785
+ }, 0);
8786
+ const checkpointLimit = surfaceCheckpointLimit(session);
8787
+ for (let level = context.level; level >= 0; level -= 1) {
8788
+ const candidate = renderBlockSurfaceMessage({
8789
+ ...context,
8790
+ level,
8791
+ label: blockLevelLabel(level),
8792
+ content: level === context.level ? context.content : renderBlock(block, level)
8793
+ });
8794
+ const tokens = surfaceCheckpointTokens(candidate);
8795
+ if (tokens <= checkpointLimit && worthwhileSurfaceReduction(before, tokens)) return candidate;
8796
+ }
8797
+ return null;
8798
+ }
8626
8799
  function renderBlockSurfaceMessage(context) {
8627
8800
  return [
8628
8801
  "[StrataGate conversation block]",
@@ -8723,7 +8896,7 @@ function currentBlockSurfaceMessages(session) {
8723
8896
  if (!session.surface?.nodes) return blocks;
8724
8897
  for (const seq of session.surface.nodes) {
8725
8898
  const event = session.eventAt(seq);
8726
- if (event?.type !== "user/message" || event.data.source.kind !== "plugin" || event.data.source.plugin !== COMPACTION_SOURCE_PLUGIN) continue;
8899
+ if (event?.type !== "user/message" || !isStrataGateMessageSource(event.data.source)) continue;
8727
8900
  const text3 = event.data.content.flatMap((block) => block.type === "text" ? [block.text] : []).join("\n");
8728
8901
  const blockId = text3.match(/^\[StrataGate conversation block\]\nBlock: ([^\n]+)/u)?.[1] ?? text3.match(/^\[StrataGate compressed conversation\]\nBlock ([^;\n]+);/u)?.[1];
8729
8902
  if (blockId) blocks.set(blockId, { seq, text: text3 });
@@ -10390,7 +10563,7 @@ import {
10390
10563
  } from "node:fs/promises";
10391
10564
  import { basename, dirname as dirname2, join } from "node:path";
10392
10565
  import { createHash as createHash3, randomUUID } from "node:crypto";
10393
- import { encodeSeqRanges } from "@deepseek-ai/dsh-session";
10566
+ import { encodeSeqRanges, KNOWN_SESSION_EVENT_TYPES } from "@deepseek-ai/dsh-session";
10394
10567
  var LEGACY_EVENT_TYPE = "stratagate/memory-citations";
10395
10568
  var COMPAT_EVENT_TYPE = "feedback/record";
10396
10569
  var ZSTD_MAGIC = 4247762216;
@@ -10544,12 +10717,24 @@ function prepareLegacyCitationGeneration(sourceBytes, compression, modules) {
10544
10717
  if (decodedCut !== migratedCut) throw new Error("StrataGate compatibility migration changed the inherited Session cut");
10545
10718
  const physicalHeader = { ...headerValue, version: 1 };
10546
10719
  modules.releasedV1SessionFormatCodec.decodeHeader(physicalHeader);
10547
- const restore = modules.sessionFormatCatalog.createRestore(physicalHeader, {
10548
- recovery: "strict",
10549
- validation: "transformed"
10550
- });
10551
- for (const row of outputRows) restore.decodeRow(row);
10552
- const current = restore.finish();
10720
+ const v1 = modules.releasedV1SessionFormatCodec.createDecoder(physicalHeader, "strict");
10721
+ const v1Events = [];
10722
+ const v1Context = {
10723
+ emitEvent(event) {
10724
+ v1Events.push(event);
10725
+ },
10726
+ emitRun(run) {
10727
+ for (const event of run.expand()) v1Events.push(event);
10728
+ }
10729
+ };
10730
+ for (const row of outputRows) v1.decodeRow(row, v1Context);
10731
+ const v1Cut = v1.finish(v1Context);
10732
+ if (v1Cut !== decodedCut) throw new Error("StrataGate compatibility migration changed the inherited Session cut");
10733
+ const current = modules.restoreReleasedV1Artifact({
10734
+ header: v1.header,
10735
+ inheritedEventCount: v1Cut,
10736
+ events: v1Events
10737
+ }, KNOWN_SESSION_EVENT_TYPES);
10553
10738
  return {
10554
10739
  bytes: encodeGeneration(physicalHeader, outputRows, compression),
10555
10740
  citationSeqs,
@@ -10558,15 +10743,12 @@ function prepareLegacyCitationGeneration(sourceBytes, compression, modules) {
10558
10743
  }
10559
10744
  async function loadMigrationModules() {
10560
10745
  try {
10561
- const [edge, catalog] = await Promise.all([
10562
- import("@deepseek-ai/dsh-session-format-v0-to-v1"),
10563
- import("@deepseek-ai/dsh-session-format-catalog")
10564
- ]);
10746
+ const edge = await import("@deepseek-ai/dsh-session-format-v0-to-v1");
10565
10747
  return {
10566
10748
  releasedV0SessionFormatCodec: edge.releasedV0SessionFormatCodec,
10567
10749
  releasedV1SessionFormatCodec: edge.releasedV1SessionFormatCodec,
10568
10750
  sessionFormatV0ToV1: edge.sessionFormatV0ToV1,
10569
- sessionFormatCatalog: catalog.sessionFormatCatalog
10751
+ restoreReleasedV1Artifact: edge.restoreReleasedV1Artifact
10570
10752
  };
10571
10753
  } catch (error) {
10572
10754
  if (error?.code === "ERR_MODULE_NOT_FOUND") return void 0;
@@ -10728,7 +10910,11 @@ async function apply(ctx, config) {
10728
10910
  ctx.logger.info(`stratagate-memory prepared ${legacyMigration.migrated} legacy Session generation(s) for DSH ${compatibility.cliVersion}`);
10729
10911
  }
10730
10912
  await mkdir2(dirname3(resolved.database), { recursive: true });
10731
- const models = new DshModelBridge(ctx, resolved);
10913
+ const models = new DshModelBridge(
10914
+ ctx,
10915
+ resolved,
10916
+ isLiveConfigValue(config.structuredReasoningEffort) ? () => liveConfigValue(config.structuredReasoningEffort) ?? "auto" : void 0
10917
+ );
10732
10918
  const runtime = new StrataGateRuntime(resolved, models, (error) => {
10733
10919
  ctx.logger.error(`stratagate-memory ingestion failed: ${renderError(error)}`);
10734
10920
  }, async (session) => {
@@ -10743,18 +10929,17 @@ async function apply(ctx, config) {
10743
10929
  };
10744
10930
  let effortSource = () => effortEntry;
10745
10931
  ctx.inject(["settings"], (settingsCtx) => {
10746
- settingsCtx.settings.installSection(
10747
- ctx,
10748
- STRATAGATE_SETTINGS_NAMESPACE,
10749
- StructuredReasoningEffortSettings,
10750
- effortEntry,
10751
- {
10932
+ const settings = settingsCtx.settings;
10933
+ if (settings.installSection) {
10934
+ settings.installSection(ctx, STRATAGATE_SETTINGS_NAMESPACE, StructuredReasoningEffortSettings, effortEntry, {
10752
10935
  setSource: (current) => {
10753
10936
  effortSource = current;
10754
10937
  },
10755
10938
  onChange: () => models.setStructuredReasoningEffort(effortSource().structuredReasoningEffort)
10756
- }
10757
- );
10939
+ });
10940
+ } else if (settings.configure) {
10941
+ settingsCtx.effect(() => settings.configure({ auto: false }, ctx.fiber));
10942
+ }
10758
10943
  });
10759
10944
  ctx.systemPrompt.section({ name: "tool:stratagate-memory", order: 113, text: MEMORY_PROTOCOL });
10760
10945
  ctx.systemPrompt.section({ name: "tool:stratagate-feedback", order: 114, text: FEEDBACK_PROTOCOL });
@@ -10788,7 +10973,7 @@ async function apply(ctx, config) {
10788
10973
  type: "text",
10789
10974
  text: `StrataGate retrieval batches are still unresolved: ${runtime.pendingBatchIds(agent.session).join(", ")}. Before ending this turn, close each one with memory_record_use using its batch_id and evidence_refs set to exactly the refs from that batch used in the answer, or [] if none were used.`
10790
10975
  }],
10791
- source: { kind: "plugin", plugin: name, form: "instructions" }
10976
+ source: dshMessageSource("instructions")
10792
10977
  }));
10793
10978
  });
10794
10979
  registerMemoryTools(ctx, runtime);