stratagate-dsh 0.2.83 → 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) {
@@ -5755,12 +5883,26 @@ var STRUCTURED_FIELDS = {
5755
5883
  var STRING_ARRAY = { type: "array", items: { type: "string" } };
5756
5884
  var OPEN_OBJECT = { type: "object", additionalProperties: true };
5757
5885
  var SUMMARIZER_PARAMETERS = {
5758
- l0Title: { type: "string", required: true },
5759
- l0Tags: { ...STRING_ARRAY, required: true },
5760
- l1Summary: { type: "string", required: true },
5761
- l2Keypoints: { ...STRING_ARRAY, required: true },
5762
- shouldExtract: { type: "boolean", required: true }
5886
+ l0Title: { type: "string", description: "L0: a short phrase naming the Block's central subject for quick recognition; do not turn it into a sentence-length summary.", required: true },
5887
+ l0Tags: { ...STRING_ARRAY, description: "L0: a few distinctive topical labels (usually 2-5) for rapid recognition of the Block, such as named people, projects, organizations, tools, technical topics, or specific task concepts; omit generic labels such as discussion, conversation, problem, or task.", required: true },
5888
+ l1Summary: { type: "string", description: "L1: a compact, self-contained overview of what happened across the Block, its conclusions or results, significant state changes, and key unresolved work; richer than L0 but still quick to read.", required: true },
5889
+ l2Keypoints: { ...STRING_ARRAY, description: "L2: specific, self-contained points needed to recover context later. Make each point mostly atomic: one decision, constraint, preference, fact, result, failure reason, or open item. Add detail beyond L1 without splitting or repeating its sentences.", required: true },
5890
+ shouldExtract: { type: "boolean", description: "High-recall pre-screen for Event extraction, not the final Event decision. True when this Block clearly contains or may reasonably contain a long-term Event; when uncertain, use true so the Event Extractor can decide. False only when it clearly lacks lasting value, such as greetings, repeated confirmations, or disposable process noise. Mere presence of a fact is not sufficient.", required: true }
5763
5891
  };
5892
+ var SUMMARIZER_SYSTEM_PROMPT = `You are the Block Summarizer in StrataGate's memory pipeline. Compress one sealed conversation Block, typically about six turns, from the supplied provenance-preserving derivation messages into L0-L2 layered memory and decide whether it warrants later Event extraction. You are a background model, not the main Agent; you have no other conversation context. L5 retains the complete original source, while L3/L4 are produced separately. Your L0-L2 may later replace detailed chat in the Agent's context, so preserve what future work needs without inventing missing context.
5893
+
5894
+ L0 -> L1 -> L2 are progressively higher-resolution views of the same history, not three independent or repetitive summaries:
5895
+ - L0: l0Title is a short subject phrase for rapid recognition, ideally under about 60 characters; l0Tags are a few distinctive topical labels for rapid recognition, usually 2-5. Prefer named people, projects, organizations, tools, technical topics, and specific task concepts. Avoid generic tags such as discussion, conversation, problem, or task.
5896
+ - L1: l1Summary is a compact, self-contained overview of the whole Block: what happened, conclusions or results, meaningful state changes, and key unresolved work. Usually 1-3 sentences; do not retell the conversation turn by turn.
5897
+ - L2: l2Keypoints retain concrete details needed to resume work. Usually 3-8 concise points when there is enough substance, fewer for a thin Block. Each point should stand alone and express mainly one decision, constraint, preference, fact, result, significant failure reason, or open item. Be more specific than L1; do not merely split L1 into repeated sentences.
5898
+
5899
+ Prioritize important decisions, constraints, user preferences, final outcomes, significant failure causes, and unresolved work; then task-relevant process details. Omit repetition, greetings, and disposable execution noise. Do not discard a constraint or conclusion that would change how later work is understood just to shorten the output.
5900
+
5901
+ Keep provenance and uncertainty. Distinguish what the user stated or decided, what the assistant only proposed or suspected, and what a tool actually observed. Do not promote an assistant hypothesis or a recollection of older memory into a verified fact or new outcome. Preserve uncertainty about timing, causes, status, results, and relationships. Ordinary user/assistant text is retained, but large tool arguments or results may be compacted; use only retained tool names, evidence summaries, and excerpts, and never guess omitted payload details.
5902
+
5903
+ shouldExtract is a high-recall pre-screen, not the final Event decision. If it is false, Event extraction is skipped entirely; if true, the Event Extractor makes the final evidence-based decision. Set true when this Block clearly contains or may reasonably contain a long-term Event, such as a decision, stable preference, material project change, meaningful task result, important failure and possible cause, future-useful fact, or open item worth tracking. When uncertain whether a plausible candidate has lasting value, choose true and let the Event Extractor decide. Set false only when the Block clearly lacks such value, for example greetings, repeated confirmations, or disposable execution noise. Do not set true merely because some fact appears; an unsupported assistant suggestion or recap of older memory alone does not establish a new Event candidate.
5904
+
5905
+ Call stratagate_summarize_block exactly once with l0Title, l0Tags, l1Summary, l2Keypoints, and shouldExtract. Do not return the summary as ordinary text.`;
5764
5906
  var EVENT_ITEM = {
5765
5907
  type: "object",
5766
5908
  additionalProperties: false,
@@ -5890,7 +6032,7 @@ var PROFILE_MAINTENANCE_PARAMETERS = Object.fromEntries(
5890
6032
  var STRUCTURED_TOOLS = {
5891
6033
  summarizer: {
5892
6034
  name: "stratagate_summarize_block",
5893
- description: "Submit the completed durable summary for the supplied conversation block.",
6035
+ description: "Submit the L0-L2 layered compression of one sealed StrataGate conversation Block and decide whether it should proceed to Event extraction.",
5894
6036
  parameters: SUMMARIZER_PARAMETERS
5895
6037
  },
5896
6038
  extractor: {
@@ -5980,9 +6122,10 @@ function compactGraphProjectionContext(context) {
5980
6122
  };
5981
6123
  }
5982
6124
  var DshModelBridge = class {
5983
- constructor(ctx, config) {
6125
+ constructor(ctx, config, liveStructuredReasoningEffort) {
5984
6126
  this.ctx = ctx;
5985
6127
  this.config = config;
6128
+ this.liveStructuredReasoningEffort = liveStructuredReasoningEffort;
5986
6129
  this.structuredReasoningEffort = config.structuredReasoningEffort ?? "auto";
5987
6130
  this.ctx.on?.("llm/adapters-updated", () => {
5988
6131
  this.offCapabilities.clear();
@@ -5991,6 +6134,7 @@ var DshModelBridge = class {
5991
6134
  }
5992
6135
  ctx;
5993
6136
  config;
6137
+ liveStructuredReasoningEffort;
5994
6138
  sessions = new AsyncLocalStorage();
5995
6139
  successfulResponses = [];
5996
6140
  offCapabilities = /* @__PURE__ */ new Map();
@@ -6016,6 +6160,9 @@ var DshModelBridge = class {
6016
6160
  setStructuredReasoningEffort(mode) {
6017
6161
  this.structuredReasoningEffort = mode;
6018
6162
  }
6163
+ currentStructuredReasoningEffort() {
6164
+ return this.liveStructuredReasoningEffort?.() ?? this.structuredReasoningEffort;
6165
+ }
6019
6166
  run(session, operation) {
6020
6167
  return this.sessions.run({ session, sessionId: session.id }, operation);
6021
6168
  }
@@ -6029,7 +6176,7 @@ var DshModelBridge = class {
6029
6176
  summarizer = async (messages) => {
6030
6177
  const raw = object(await this.callStructured(
6031
6178
  "summarizer",
6032
- `You compress agent conversations into durable memory blocks. Read the supplied provenance-preserving derivation messages and call ${STRUCTURED_TOOLS.summarizer.name} exactly once with l0Title, l0Tags, l1Summary, l2Keypoints, and shouldExtract. Preserve decisions, constraints, preferences, outcomes, and unresolved work. Tool code and oversized tool payloads may be marked compacted; use the retained tool names, evidence summaries, and excerpts without inventing omitted details. shouldExtract is true only when durable events or facts exist. Do not return the summary as text.`,
6179
+ SUMMARIZER_SYSTEM_PROMPT,
6033
6180
  { messages: buildMemoryDerivationMessages(messages) }
6034
6181
  ));
6035
6182
  return {
@@ -6244,7 +6391,7 @@ var DshModelBridge = class {
6244
6391
  attemptsUsed = attempt;
6245
6392
  const message = createUserMessage({
6246
6393
  content: [{ type: "text", text: JSON.stringify(payload) }],
6247
- source: { kind: "plugin", plugin: "stratagate-memory" }
6394
+ source: dshMessageSource()
6248
6395
  });
6249
6396
  const assembler = new BlockAssembler();
6250
6397
  const request = {
@@ -6378,14 +6525,14 @@ ${JSON_RETRY_INSTRUCTION}`,
6378
6525
  const key = `${route.provider}\0${route.model}`;
6379
6526
  const cached = this.offCapabilities.get(key);
6380
6527
  if (cached) {
6381
- if (cached === "unsupported" && this.structuredReasoningEffort === "force-off") {
6528
+ if (cached === "unsupported" && this.currentStructuredReasoningEffort() === "force-off") {
6382
6529
  this.warnOffFallbackOnce(key, `${route.provider}/${route.model} does not support reasoningEffort=off; using the model default`);
6383
6530
  }
6384
6531
  return cached === "supported";
6385
6532
  }
6386
6533
  if (typeof this.ctx.llm.resolveModelInfo !== "function") {
6387
6534
  this.offCapabilities.set(key, "unsupported");
6388
- if (this.structuredReasoningEffort === "force-off") {
6535
+ if (this.currentStructuredReasoningEffort() === "force-off") {
6389
6536
  this.warnOffFallbackOnce(key, `${route.provider}/${route.model} capabilities are unavailable; using the model default`);
6390
6537
  }
6391
6538
  return false;
@@ -6404,16 +6551,16 @@ ${JSON_RETRY_INSTRUCTION}`,
6404
6551
  timer.unref?.();
6405
6552
  })
6406
6553
  ]);
6407
- if (!info.reasoning) return this.structuredReasoningEffort === "force-off";
6554
+ if (!info.reasoning) return this.currentStructuredReasoningEffort() === "force-off";
6408
6555
  const supported = info.reasoning.efforts.some(({ id }) => String(id) === "off");
6409
6556
  this.offCapabilities.set(key, supported ? "supported" : "unsupported");
6410
- if (!supported && this.structuredReasoningEffort === "force-off") {
6557
+ if (!supported && this.currentStructuredReasoningEffort() === "force-off") {
6411
6558
  this.warnOffFallbackOnce(key, `${route.provider}/${route.model} does not support reasoningEffort=off; using the model default`);
6412
6559
  }
6413
6560
  return supported;
6414
6561
  } catch {
6415
6562
  this.offCapabilities.set(key, "unsupported");
6416
- if (this.structuredReasoningEffort === "force-off") {
6563
+ if (this.currentStructuredReasoningEffort() === "force-off") {
6417
6564
  this.warnOffFallbackOnce(key, `${route.provider}/${route.model} capability lookup failed; using the model default`);
6418
6565
  }
6419
6566
  return false;
@@ -6502,13 +6649,14 @@ function renderBlocks(blocks) {
6502
6649
  break;
6503
6650
  case "tool-call":
6504
6651
  break;
6505
- case "tool-result": {
6506
- const nested = renderBlocks(block.content);
6507
- 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
+ }
6508
6658
  break;
6509
6659
  }
6510
- default:
6511
- break;
6512
6660
  }
6513
6661
  }
6514
6662
  return output.join("\n").trim();
@@ -6560,6 +6708,7 @@ var TurnFolder = class {
6560
6708
  return null;
6561
6709
  }
6562
6710
  case "tool/result": {
6711
+ if (event.surfaceOp && event.surfaceOp !== "append") return null;
6563
6712
  const callId = String(event.data.message.source.callId);
6564
6713
  const pending = this.pending(sessionId, event.data.turn);
6565
6714
  if (pending.ignoredTools.has(callId)) return null;
@@ -6604,93 +6753,6 @@ var TurnFolder = class {
6604
6753
  }
6605
6754
  };
6606
6755
 
6607
- // src/dsh-compatibility.ts
6608
- import { readFileSync } from "node:fs";
6609
- import { createRequire } from "node:module";
6610
- var nodeRequire = createRequire(import.meta.url);
6611
- var RUNTIME_PACKAGES = [
6612
- "@deepseek-ai/cordis",
6613
- "@deepseek-ai/dsh-agent-default-model",
6614
- "@deepseek-ai/dsh-client-ui-conversation",
6615
- "@deepseek-ai/dsh-llm",
6616
- "@deepseek-ai/dsh-session",
6617
- "@deepseek-ai/dsh-settings",
6618
- "@deepseek-ai/dsh-system-prompt",
6619
- "@deepseek-ai/dsh-tools",
6620
- "@deepseek-ai/schemastery"
6621
- ];
6622
- var SUPPORTED_RUNTIME_FAMILIES = [
6623
- {
6624
- cli: "0.1.2-rc.1",
6625
- versions: {
6626
- "@deepseek-ai/cordis": "4.0.2",
6627
- "@deepseek-ai/dsh-agent-default-model": "0.1.2-rc.1",
6628
- "@deepseek-ai/dsh-client-ui-conversation": "0.1.2-rc.1",
6629
- "@deepseek-ai/dsh-llm": "0.1.2-rc.1",
6630
- "@deepseek-ai/dsh-session": "0.1.2-rc.1",
6631
- "@deepseek-ai/dsh-settings": "0.1.2-rc.1",
6632
- "@deepseek-ai/dsh-system-prompt": "0.1.2-rc.1",
6633
- "@deepseek-ai/dsh-tools": "0.1.2-rc.1",
6634
- "@deepseek-ai/schemastery": "3.18.2"
6635
- }
6636
- },
6637
- {
6638
- cli: "0.1.5-rc.1",
6639
- versions: {
6640
- "@deepseek-ai/cordis": "4.0.2",
6641
- "@deepseek-ai/dsh-agent-default-model": "0.1.5-rc.2",
6642
- "@deepseek-ai/dsh-client-ui-conversation": "0.1.5-rc.2",
6643
- "@deepseek-ai/dsh-llm": "0.1.5-rc.2",
6644
- "@deepseek-ai/dsh-session": "0.1.5-rc.2",
6645
- "@deepseek-ai/dsh-settings": "0.1.5-rc.2",
6646
- "@deepseek-ai/dsh-system-prompt": "0.1.5-rc.2",
6647
- "@deepseek-ai/dsh-tools": "0.1.5-rc.2",
6648
- "@deepseek-ai/schemastery": "3.18.2"
6649
- }
6650
- },
6651
- {
6652
- cli: "0.1.6-alpha.1",
6653
- versions: {
6654
- "@deepseek-ai/cordis": "4.0.2",
6655
- "@deepseek-ai/dsh-agent-default-model": "0.1.6-alpha.1",
6656
- "@deepseek-ai/dsh-client-ui-conversation": "0.1.6-alpha.1",
6657
- "@deepseek-ai/dsh-llm": "0.1.6-alpha.1",
6658
- "@deepseek-ai/dsh-session": "0.1.6-alpha.1",
6659
- "@deepseek-ai/dsh-settings": "0.1.6-alpha.1",
6660
- "@deepseek-ai/dsh-system-prompt": "0.1.6-alpha.1",
6661
- "@deepseek-ai/dsh-tools": "0.1.6-alpha.1",
6662
- "@deepseek-ai/schemastery": "3.18.2"
6663
- }
6664
- }
6665
- ];
6666
- function installedVersion(packageName) {
6667
- try {
6668
- const manifestPath = nodeRequire.resolve(`${packageName}/package.json`);
6669
- const manifest = JSON.parse(readFileSync(manifestPath, "utf8"));
6670
- if (typeof manifest.version === "string" && manifest.version.length > 0) return manifest.version;
6671
- } catch {
6672
- }
6673
- return "<missing>";
6674
- }
6675
- function buildDshReplaceSurfaceOp(version, start, end) {
6676
- return version === "0.1.2-rc.1" ? { op: "replace", start, end } : { op: "replace", startSeq: start, endSeq: end };
6677
- }
6678
- function dshReplaceSurfaceOp(start, end) {
6679
- return buildDshReplaceSurfaceOp(installedVersion("@deepseek-ai/dsh-session"), start, end);
6680
- }
6681
- function classifyDshRuntime(packageVersions) {
6682
- const family = SUPPORTED_RUNTIME_FAMILIES.find(({ versions }) => RUNTIME_PACKAGES.every((name2) => packageVersions[name2] === versions[name2]));
6683
- if (family) return { cliVersion: family.cli, packageVersions };
6684
- const found = RUNTIME_PACKAGES.map((name2) => `${name2}@${packageVersions[name2]}`).join(", ");
6685
- throw new Error(
6686
- `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.`
6687
- );
6688
- }
6689
- function assertCompatibleDshRuntime() {
6690
- const packageVersions = Object.fromEntries(RUNTIME_PACKAGES.map((name2) => [name2, installedVersion(name2)]));
6691
- return classifyDshRuntime(packageVersions);
6692
- }
6693
-
6694
6756
  // src/metadata.ts
6695
6757
  import { DatabaseSync as DatabaseSync2 } from "node:sqlite";
6696
6758
  var METADATA_SCHEMA = `
@@ -6804,7 +6866,6 @@ function graphProjectionCanRun(job, now = Date.now()) {
6804
6866
  var AUTO_EVENT_LIMIT = 4;
6805
6867
  var AUTO_ELEMENT_LIMIT = 4;
6806
6868
  var AUTO_MEMORY_TOKEN_BUDGET = 900;
6807
- var COMPACTION_SOURCE_PLUGIN = "stratagate-memory";
6808
6869
  var FEEDBACK_PROMPT_COOLDOWN_MS = 5 * 24 * 60 * 60 * 1e3;
6809
6870
  function projectKey(cwd) {
6810
6871
  const canonical = resolve(cwd ?? process.cwd()).replaceAll("\\", "/").toLowerCase();
@@ -7469,7 +7530,7 @@ var StrataGateRuntime = class {
7469
7530
  const memory = await this.space(session);
7470
7531
  const threadId = String(session.id);
7471
7532
  const blockContexts = memory.getBlockContext(threadId);
7472
- if (this.syncDecayedBlockSurface(session, blockContexts)) {
7533
+ if (this.syncDecayedBlockSurface(session, memory, blockContexts)) {
7473
7534
  await this.flushNativeSession(session);
7474
7535
  }
7475
7536
  const openTail = memory.listOpenTail(threadId);
@@ -7512,32 +7573,54 @@ var StrataGateRuntime = class {
7512
7573
  * while deriveMessages() sees only this compressed checkpoint.
7513
7574
  */
7514
7575
  replaceSealedSurface(session, block, context, endTurn) {
7515
- 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;
7516
7579
  const start = sourceEventSeqs[0];
7517
7580
  const end = sourceEventSeqs.at(-1);
7518
- if (start === void 0 || end === void 0) {
7519
- throw new Error(`Cannot compact StrataGate block ${block.id}: no DSH surface range was found`);
7520
- }
7581
+ if (start === void 0 || end === void 0) return false;
7582
+ const selected = selectCompressedBlockSurface(session, sourceEventSeqs, block, context);
7583
+ if (!selected) return false;
7521
7584
  session.append("user/message", createUserMessage2({
7522
- content: [{ type: "text", text: renderBlockSurfaceMessage(context) }],
7523
- source: { kind: "plugin", plugin: COMPACTION_SOURCE_PLUGIN }
7585
+ content: [{ type: "text", text: selected }],
7586
+ source: dshMessageSource()
7524
7587
  }), {
7525
7588
  surfaceOp: dshReplaceSurfaceOp(start, end),
7526
7589
  sourceEventSeqs
7527
7590
  });
7591
+ return true;
7528
7592
  }
7529
7593
  /** Keep each native Block checkpoint synchronized with its current decay pointer. */
7530
- syncDecayedBlockSurface(session, contexts) {
7594
+ syncDecayedBlockSurface(session, memory, contexts) {
7595
+ if (hostCompactionActive(session)) return false;
7531
7596
  const current = currentBlockSurfaceMessages(session);
7597
+ const blocks = new Map(memory.listBlocks().map((block) => [block.id, block]));
7598
+ const checkpointLimit = surfaceCheckpointLimit(session);
7532
7599
  let changed = false;
7533
7600
  for (const context of contexts) {
7534
7601
  const node = current.get(context.id);
7535
7602
  if (!node) continue;
7536
- 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;
7537
7620
  if (node.text === text3) continue;
7538
7621
  session.append("user/message", createUserMessage2({
7539
7622
  content: [{ type: "text", text: text3 }],
7540
- source: { kind: "plugin", plugin: COMPACTION_SOURCE_PLUGIN }
7623
+ source: dshMessageSource()
7541
7624
  }), {
7542
7625
  surfaceOp: dshReplaceSurfaceOp(node.seq, node.seq),
7543
7626
  sourceEventSeqs: [node.seq]
@@ -7548,6 +7631,7 @@ var StrataGateRuntime = class {
7548
7631
  }
7549
7632
  /** Finish native-surface replacement when an admin retry ran without the target session loaded. */
7550
7633
  async syncPendingRetrySurface(session, memory) {
7634
+ if (hostCompactionActive(session)) return;
7551
7635
  const namespace = this.namespaceFor(session);
7552
7636
  const threadId = String(session.id);
7553
7637
  const pending = [...this.pendingSurfaceSync.entries()].filter(([, item]) => item.namespace === namespace);
@@ -7564,9 +7648,8 @@ var StrataGateRuntime = class {
7564
7648
  const context = contexts.get(blockId);
7565
7649
  if (!block || block.processingStatus !== "ready" || !context) continue;
7566
7650
  try {
7567
- this.replaceSealedSurface(session, block, context, dshTurnAtBlockEnd(session, block));
7651
+ changed = this.replaceSealedSurface(session, block, context, dshTurnAtBlockEnd(session, block)) || changed;
7568
7652
  this.pendingSurfaceSync.delete(key);
7569
- changed = true;
7570
7653
  } catch (error) {
7571
7654
  this.onIngestError(error);
7572
7655
  }
@@ -8272,7 +8355,9 @@ var StrataGateRuntime = class {
8272
8355
  try {
8273
8356
  await memory2.resumePendingWork({ deferDerivation: true, threadId: String(session.id) });
8274
8357
  const contexts = memory2.getBlockContext(String(session.id));
8275
- this.syncDecayedBlockSurface(session, contexts);
8358
+ if (this.syncDecayedBlockSurface(session, memory2, contexts)) {
8359
+ await this.flushNativeSession(session);
8360
+ }
8276
8361
  } finally {
8277
8362
  await this.persistSuccessfulResponses(memory2);
8278
8363
  }
@@ -8368,14 +8453,22 @@ var StrataGateRuntime = class {
8368
8453
  await this.persistSuccessfulResponses(memory);
8369
8454
  this.noteNewCoreJobFailures(session, failedBefore, memory);
8370
8455
  const contexts = memory.getBlockContext(threadId);
8456
+ let changed = false;
8371
8457
  for (const block of resumed.readyBlocks) {
8372
8458
  if (block.threadId !== threadId) continue;
8373
8459
  const context = contexts.find(({ id }) => id === block.id);
8374
8460
  if (!context) throw new Error(`Missing context for ready StrataGate block ${block.id}`);
8375
- 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;
8376
8469
  }
8377
- const changed = this.syncDecayedBlockSurface(session, contexts);
8378
- 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);
8379
8472
  }).catch((error) => {
8380
8473
  this.notePluginError(session, error);
8381
8474
  this.onIngestError(error);
@@ -8537,8 +8630,11 @@ function renderContent(content) {
8537
8630
  output.push(block.text.trim());
8538
8631
  } else if (block.type === "image") {
8539
8632
  output.push("[image]");
8540
- } else if (block.type === "tool-result" && Array.isArray(block.content)) {
8541
- 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
+ }
8542
8638
  }
8543
8639
  }
8544
8640
  return output.filter(Boolean).join("\n");
@@ -8566,11 +8662,10 @@ function dshTurnAtBlockEnd(session, block) {
8566
8662
  const event = events[index];
8567
8663
  if (event?.type === "turn/end" && event.time === blockEnd) return event.data.turn;
8568
8664
  }
8569
- throw new Error(`Cannot match StrataGate block ${block.id} to its completed DSH turn`);
8665
+ return null;
8570
8666
  }
8571
- function sealedSurfaceSeqs(session, endTurn, turnCount) {
8667
+ function sealedSurfaceSeqs(session, endTurn, block) {
8572
8668
  const currentSurface = [...session.surface.nodes];
8573
- const currentSet = new Set(currentSurface);
8574
8669
  const completed = [];
8575
8670
  let open2;
8576
8671
  const events = session.snapshotEvents();
@@ -8585,30 +8680,122 @@ function sealedSurfaceSeqs(session, endTurn, turnCount) {
8585
8680
  if (hasHumanMessage && event.data.turn <= endTurn) {
8586
8681
  completed.push({
8587
8682
  turn: event.data.turn,
8683
+ endTime: event.time,
8588
8684
  start: open2.start,
8589
8685
  end: event.seq,
8590
- 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
+ })
8591
8691
  });
8592
8692
  }
8593
8693
  open2 = void 0;
8594
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;
8595
8697
  const selected = completed.slice(-turnCount);
8596
- if (selected.length !== turnCount || selected.at(-1)?.turn !== endTurn) {
8597
- throw new Error(`Cannot identify ${turnCount} completed DSH turns ending at turn ${endTurn}`);
8598
- }
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;
8599
8705
  const emptyTurn = selected.find((turn) => turn.nodes.length === 0);
8600
- if (emptyTurn) {
8601
- throw new Error(`Cannot compact DSH turn ${emptyTurn.turn}: its original messages are no longer on the surface`);
8602
- }
8706
+ if (emptyTurn) return null;
8603
8707
  const start = selected[0].nodes[0];
8604
8708
  const end = selected.at(-1).nodes.at(-1);
8605
8709
  const startIndex = currentSurface.indexOf(start);
8606
8710
  const endIndex = currentSurface.indexOf(end);
8607
- if (startIndex < 0 || endIndex < startIndex) {
8608
- throw new Error(`Cannot identify a contiguous DSH surface range ending at turn ${endTurn}`);
8609
- }
8711
+ if (startIndex < 0 || endIndex < startIndex) return null;
8610
8712
  return currentSurface.slice(startIndex, endIndex + 1);
8611
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
+ }
8612
8799
  function renderBlockSurfaceMessage(context) {
8613
8800
  return [
8614
8801
  "[StrataGate conversation block]",
@@ -8709,7 +8896,7 @@ function currentBlockSurfaceMessages(session) {
8709
8896
  if (!session.surface?.nodes) return blocks;
8710
8897
  for (const seq of session.surface.nodes) {
8711
8898
  const event = session.eventAt(seq);
8712
- 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;
8713
8900
  const text3 = event.data.content.flatMap((block) => block.type === "text" ? [block.text] : []).join("\n");
8714
8901
  const blockId = text3.match(/^\[StrataGate conversation block\]\nBlock: ([^\n]+)/u)?.[1] ?? text3.match(/^\[StrataGate compressed conversation\]\nBlock ([^;\n]+);/u)?.[1];
8715
8902
  if (blockId) blocks.set(blockId, { seq, text: text3 });
@@ -10376,7 +10563,7 @@ import {
10376
10563
  } from "node:fs/promises";
10377
10564
  import { basename, dirname as dirname2, join } from "node:path";
10378
10565
  import { createHash as createHash3, randomUUID } from "node:crypto";
10379
- import { encodeSeqRanges } from "@deepseek-ai/dsh-session";
10566
+ import { encodeSeqRanges, KNOWN_SESSION_EVENT_TYPES } from "@deepseek-ai/dsh-session";
10380
10567
  var LEGACY_EVENT_TYPE = "stratagate/memory-citations";
10381
10568
  var COMPAT_EVENT_TYPE = "feedback/record";
10382
10569
  var ZSTD_MAGIC = 4247762216;
@@ -10530,12 +10717,24 @@ function prepareLegacyCitationGeneration(sourceBytes, compression, modules) {
10530
10717
  if (decodedCut !== migratedCut) throw new Error("StrataGate compatibility migration changed the inherited Session cut");
10531
10718
  const physicalHeader = { ...headerValue, version: 1 };
10532
10719
  modules.releasedV1SessionFormatCodec.decodeHeader(physicalHeader);
10533
- const restore = modules.sessionFormatCatalog.createRestore(physicalHeader, {
10534
- recovery: "strict",
10535
- validation: "transformed"
10536
- });
10537
- for (const row of outputRows) restore.decodeRow(row);
10538
- 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);
10539
10738
  return {
10540
10739
  bytes: encodeGeneration(physicalHeader, outputRows, compression),
10541
10740
  citationSeqs,
@@ -10544,15 +10743,12 @@ function prepareLegacyCitationGeneration(sourceBytes, compression, modules) {
10544
10743
  }
10545
10744
  async function loadMigrationModules() {
10546
10745
  try {
10547
- const [edge, catalog] = await Promise.all([
10548
- import("@deepseek-ai/dsh-session-format-v0-to-v1"),
10549
- import("@deepseek-ai/dsh-session-format-catalog")
10550
- ]);
10746
+ const edge = await import("@deepseek-ai/dsh-session-format-v0-to-v1");
10551
10747
  return {
10552
10748
  releasedV0SessionFormatCodec: edge.releasedV0SessionFormatCodec,
10553
10749
  releasedV1SessionFormatCodec: edge.releasedV1SessionFormatCodec,
10554
10750
  sessionFormatV0ToV1: edge.sessionFormatV0ToV1,
10555
- sessionFormatCatalog: catalog.sessionFormatCatalog
10751
+ restoreReleasedV1Artifact: edge.restoreReleasedV1Artifact
10556
10752
  };
10557
10753
  } catch (error) {
10558
10754
  if (error?.code === "ERR_MODULE_NOT_FOUND") return void 0;
@@ -10714,7 +10910,11 @@ async function apply(ctx, config) {
10714
10910
  ctx.logger.info(`stratagate-memory prepared ${legacyMigration.migrated} legacy Session generation(s) for DSH ${compatibility.cliVersion}`);
10715
10911
  }
10716
10912
  await mkdir2(dirname3(resolved.database), { recursive: true });
10717
- 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
+ );
10718
10918
  const runtime = new StrataGateRuntime(resolved, models, (error) => {
10719
10919
  ctx.logger.error(`stratagate-memory ingestion failed: ${renderError(error)}`);
10720
10920
  }, async (session) => {
@@ -10729,18 +10929,17 @@ async function apply(ctx, config) {
10729
10929
  };
10730
10930
  let effortSource = () => effortEntry;
10731
10931
  ctx.inject(["settings"], (settingsCtx) => {
10732
- settingsCtx.settings.installSection(
10733
- ctx,
10734
- STRATAGATE_SETTINGS_NAMESPACE,
10735
- StructuredReasoningEffortSettings,
10736
- effortEntry,
10737
- {
10932
+ const settings = settingsCtx.settings;
10933
+ if (settings.installSection) {
10934
+ settings.installSection(ctx, STRATAGATE_SETTINGS_NAMESPACE, StructuredReasoningEffortSettings, effortEntry, {
10738
10935
  setSource: (current) => {
10739
10936
  effortSource = current;
10740
10937
  },
10741
10938
  onChange: () => models.setStructuredReasoningEffort(effortSource().structuredReasoningEffort)
10742
- }
10743
- );
10939
+ });
10940
+ } else if (settings.configure) {
10941
+ settingsCtx.effect(() => settings.configure({ auto: false }, ctx.fiber));
10942
+ }
10744
10943
  });
10745
10944
  ctx.systemPrompt.section({ name: "tool:stratagate-memory", order: 113, text: MEMORY_PROTOCOL });
10746
10945
  ctx.systemPrompt.section({ name: "tool:stratagate-feedback", order: 114, text: FEEDBACK_PROTOCOL });
@@ -10774,7 +10973,7 @@ async function apply(ctx, config) {
10774
10973
  type: "text",
10775
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.`
10776
10975
  }],
10777
- source: { kind: "plugin", plugin: name, form: "instructions" }
10976
+ source: dshMessageSource("instructions")
10778
10977
  }));
10779
10978
  });
10780
10979
  registerMemoryTools(ctx, runtime);