dsh-mnemon 0.3.4 → 0.3.6

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/lib/index.js CHANGED
@@ -23,6 +23,17 @@ const MNEMON_SETTINGS_CHANNEL = "/dsh-mnemon-settings";
23
23
  const MNEMON_SETTINGS_NAMESPACE = "mnemon";
24
24
  const DEFAULT_EMBEDDING_ENDPOINT = "http://localhost:11434";
25
25
  const DEFAULT_EMBEDDING_MODEL = "nomic-embed-text";
26
+ const EMBEDDING_PROTOCOL_AUTO = "auto";
27
+ const EMBEDDING_PROTOCOL_OLLAMA = "ollama";
28
+ const EMBEDDING_PROTOCOL_OPENAI = "openai";
29
+ /** Default protocol defers to Mnemon's /v1 auto-detection. */
30
+ const DEFAULT_EMBEDDING_PROTOCOL = EMBEDDING_PROTOCOL_AUTO;
31
+ /** Wire protocols accepted by the embedding protocol override; single source for schema, resolver, and UI validation. */
32
+ const MNEMON_EMBEDDING_PROTOCOLS = [
33
+ EMBEDDING_PROTOCOL_AUTO,
34
+ EMBEDDING_PROTOCOL_OLLAMA,
35
+ EMBEDDING_PROTOCOL_OPENAI
36
+ ];
26
37
  const CATEGORIES = [
27
38
  "preference",
28
39
  "decision",
@@ -114,7 +125,9 @@ const TaskAgentModelSchema = z.object({
114
125
  const MnemonEmbeddingSchema = z.object({
115
126
  enabled: z.boolean().default(false),
116
127
  endpoint: z.string().default(DEFAULT_EMBEDDING_ENDPOINT),
117
- model: z.string().default(DEFAULT_EMBEDDING_MODEL)
128
+ model: z.string().default(DEFAULT_EMBEDDING_MODEL),
129
+ apiKey: z.string().default(""),
130
+ protocol: z.union(MNEMON_EMBEDDING_PROTOCOLS).default(DEFAULT_EMBEDDING_PROTOCOL)
118
131
  });
119
132
  const RecallQualitySchema = z.object({
120
133
  policy: z.string().default(DEFAULT_RECALL_QUALITY_POLICY),
@@ -175,7 +188,9 @@ const Config = z.object({
175
188
  embedding: MnemonEmbeddingSchema.default({
176
189
  enabled: false,
177
190
  endpoint: DEFAULT_EMBEDDING_ENDPOINT,
178
- model: DEFAULT_EMBEDDING_MODEL
191
+ model: DEFAULT_EMBEDDING_MODEL,
192
+ apiKey: "",
193
+ protocol: DEFAULT_EMBEDDING_PROTOCOL
179
194
  }),
180
195
  memoryTopology: MemoryTopologySchema,
181
196
  recallQuality: RecallQualitySchema.default({
@@ -325,10 +340,16 @@ function resolveEmbedding(value) {
325
340
  const normalizedEndpoint = endpoint.replace(/\/+$/u, "");
326
341
  const model = optionalText$1(value?.model) ?? "nomic-embed-text";
327
342
  if (model.length > 200 || /[\u0000-\u001f\u007f]/u.test(model)) throw new Error("dsh-mnemon: embedding model must contain 1..200 characters without control characters");
343
+ const apiKey = optionalText$1(value?.apiKey) ?? "";
344
+ if (apiKey.length > 2048 || /[\u0000-\u001f\u007f]/u.test(apiKey)) throw new Error("dsh-mnemon: embedding API key must contain 0..2048 characters without control characters");
345
+ const protocol = value?.protocol ?? "auto";
346
+ if (!MNEMON_EMBEDDING_PROTOCOLS.includes(protocol)) throw new Error(`dsh-mnemon: unsupported embedding protocol: ${String(protocol)}`);
328
347
  return {
329
348
  enabled: value?.enabled === true,
330
349
  endpoint: normalizedEndpoint,
331
- model
350
+ model,
351
+ apiKey,
352
+ protocol
332
353
  };
333
354
  }
334
355
  function resolveRecallQuality(value) {
@@ -1930,20 +1951,7 @@ function applyAgentMemoryViewWake(assembly, wake) {
1930
1951
  name: RUNTIME_MEMORY_PROTOCOL_SECTION_NAME,
1931
1952
  text: protocol
1932
1953
  });
1933
- const rendered = wake === void 0 ? "" : memoryPromptText(wake.text);
1934
- let found = false;
1935
- const contexts = assembly.contexts.map((context) => {
1936
- if (context.name !== "mnemon:runtime-memory") return context;
1937
- found = true;
1938
- return {
1939
- ...context,
1940
- text: rendered
1941
- };
1942
- });
1943
- if (!found) contexts.push({
1944
- name: RUNTIME_MEMORY_CONTEXT_NAME,
1945
- text: rendered
1946
- });
1954
+ const contexts = assembly.contexts.filter((context) => context.name !== RUNTIME_MEMORY_CONTEXT_NAME);
1947
1955
  return {
1948
1956
  ...assembly,
1949
1957
  sections,
@@ -1963,21 +1971,12 @@ function registerGuidance(ctx, config) {
1963
1971
  }
1964
1972
  /** Project only the immutable Wake pinned by the root Agent lifecycle. */
1965
1973
  function registerAgentMemoryViewContext(agent, wake) {
1966
- const prompt = scopedSystemPrompt(agent);
1967
- const stopProtocol = prompt?.section?.({
1974
+ const stopProtocol = scopedSystemPrompt(agent)?.section?.({
1968
1975
  name: RUNTIME_MEMORY_PROTOCOL_SECTION_NAME,
1969
1976
  order: 145,
1970
1977
  text: () => wakeHasRuntimeMemory(wake()) ? RUNTIME_MEMORY_PROTOCOL : ""
1971
1978
  });
1972
- const stopContext = prompt?.context?.({
1973
- name: RUNTIME_MEMORY_CONTEXT_NAME,
1974
- order: 145,
1975
- text: () => {
1976
- const current = wake();
1977
- return current === void 0 ? "" : memoryPromptText(current.text);
1978
- }
1979
- });
1980
- return disposer(stopProtocol, stopContext);
1979
+ return disposer(stopProtocol);
1981
1980
  }
1982
1981
  //#endregion
1983
1982
  //#region src/pack.ts
@@ -2820,20 +2819,25 @@ function findMnemonCommand(config, options = {}) {
2820
2819
  const env = options.env ?? process.env;
2821
2820
  const home = options.home ?? homedir();
2822
2821
  const isExecutable = options.isExecutable ?? ((path) => executable$1(path, platform));
2823
- if (config.cliPath !== void 0) return expandHome$1(config.cliPath, home, platform);
2824
- const envPath = envValue(env, "MNEMON_CLI_PATH", platform)?.trim();
2825
- if (envPath !== void 0 && envPath !== "") {
2826
- const path = expandHome$1(envPath, home, platform);
2827
- if (isExecutable(path)) return path;
2828
- }
2829
2822
  const paths = pathApi(platform);
2830
- for (const directory of (envValue(env, "PATH", platform) ?? "").split(paths.delimiter)) {
2831
- if (directory === "") continue;
2832
- for (const name of platform === "win32" ? ["mnemon.exe"] : ["mnemon"]) {
2823
+ const resolveCommand = (command) => {
2824
+ const expanded = expandHome$1(command, home, platform);
2825
+ if (expanded.includes("/") || expanded.includes("\\")) return expanded;
2826
+ const name = platform === "win32" && paths.extname(expanded) === "" ? `${expanded}.exe` : expanded;
2827
+ for (const directory of (envValue(env, "PATH", platform) ?? "").split(paths.delimiter)) {
2828
+ if (directory === "") continue;
2833
2829
  const path = paths.join(directory, name);
2834
2830
  if (isExecutable(path)) return path;
2835
2831
  }
2832
+ };
2833
+ if (config.cliPath !== void 0) return resolveCommand(config.cliPath);
2834
+ const envPath = envValue(env, "MNEMON_CLI_PATH", platform)?.trim();
2835
+ if (envPath !== void 0 && envPath !== "") {
2836
+ const path = resolveCommand(envPath);
2837
+ if (path !== void 0 && isExecutable(path)) return path;
2836
2838
  }
2839
+ const fromPath = resolveCommand("mnemon");
2840
+ if (fromPath !== void 0) return fromPath;
2837
2841
  for (const path of commonCliPaths(platform, env, home)) if (isExecutable(path)) return path;
2838
2842
  }
2839
2843
  var MnemonCliError = class extends Error {
@@ -2846,19 +2850,25 @@ var MnemonCliError = class extends Error {
2846
2850
  this.stderr = stderr;
2847
2851
  }
2848
2852
  };
2849
- const EMBEDDING_ENVIRONMENT_KEYS = /* @__PURE__ */ new Set(["MNEMON_EMBED_ENDPOINT", "MNEMON_EMBED_MODEL"]);
2853
+ const EMBEDDING_ENVIRONMENT_KEYS = /* @__PURE__ */ new Set([
2854
+ "MNEMON_EMBED_ENDPOINT",
2855
+ "MNEMON_EMBED_MODEL",
2856
+ "MNEMON_EMBED_API_KEY",
2857
+ "MNEMON_EMBED_PROTOCOL"
2858
+ ]);
2850
2859
  /** Preserve the Host environment while making saved embedding overrides authoritative. */
2851
2860
  function processEnvironment(config) {
2852
2861
  if (!config.embedding.enabled) return void 0;
2853
2862
  return {
2854
2863
  ...Object.fromEntries(Object.entries(process.env).filter(([key]) => !EMBEDDING_ENVIRONMENT_KEYS.has(key.toUpperCase()))),
2855
2864
  MNEMON_EMBED_ENDPOINT: config.embedding.endpoint,
2856
- MNEMON_EMBED_MODEL: config.embedding.model
2865
+ MNEMON_EMBED_MODEL: config.embedding.model,
2866
+ MNEMON_EMBED_API_KEY: config.embedding.apiKey,
2867
+ ...config.embedding.protocol === "auto" ? {} : { MNEMON_EMBED_PROTOCOL: config.embedding.protocol }
2857
2868
  };
2858
2869
  }
2859
2870
  function createRunner(config, processRunner = runProcess, workspaceRoot) {
2860
- const found = findMnemonCommand(config);
2861
- const command = found ?? config.cliPath ?? "mnemon";
2871
+ const currentCommand = () => findMnemonCommand(config) ?? config.cliPath ?? "mnemon";
2862
2872
  let processQueue = Promise.resolve();
2863
2873
  const globalArgs = (store) => {
2864
2874
  const args = [];
@@ -2891,7 +2901,7 @@ function createRunner(config, processRunner = runProcess, workspaceRoot) {
2891
2901
  };
2892
2902
  let result;
2893
2903
  try {
2894
- result = await processRunner(command, argv, processOptions);
2904
+ result = await processRunner(currentCommand(), argv, processOptions);
2895
2905
  } catch (error) {
2896
2906
  throw new MnemonCliError(`${error instanceof Error ? error.message : String(error)}. ${process.platform === "win32" ? "Install the official Mnemon Windows release, ensure mnemon.exe is on PATH or under %LOCALAPPDATA%\\Programs\\mnemon, or set MNEMON_CLI_PATH or mnemon.cliPath to its absolute path." : "Install Mnemon and ensure \"mnemon\" is on PATH, or set MNEMON_CLI_PATH or mnemon.cliPath."}`);
2897
2907
  }
@@ -2907,8 +2917,13 @@ function createRunner(config, processRunner = runProcess, workspaceRoot) {
2907
2917
  return result;
2908
2918
  };
2909
2919
  return {
2910
- command,
2911
- commandFound: found !== void 0 && executable$1(found),
2920
+ get command() {
2921
+ return currentCommand();
2922
+ },
2923
+ get commandFound() {
2924
+ const found = findMnemonCommand(config);
2925
+ return found !== void 0 && executable$1(found);
2926
+ },
2912
2927
  config,
2913
2928
  async runJson(args, options) {
2914
2929
  const stdout = await execute(args, options);
@@ -4318,8 +4333,9 @@ var MnemonService = class {
4318
4333
  /** Probe the effective Mnemon embedding runtime and its default Store coverage. */
4319
4334
  async embeddingStatus(signal) {
4320
4335
  const output = record$1(await this.runner.runJson(["embed", "--status"], signal === void 0 ? {} : { signal }));
4321
- const available = output?.ollama_available;
4336
+ const available = output?.embedding_available ?? output?.ollama_available;
4322
4337
  const model = text$1(output?.model)?.trim();
4338
+ const protocol = text$1(output?.protocol)?.trim();
4323
4339
  const totalInsights = number(output?.total_insights);
4324
4340
  const embedded = number(output?.embedded);
4325
4341
  const coverage = text$1(output?.coverage)?.trim();
@@ -4329,7 +4345,8 @@ var MnemonService = class {
4329
4345
  model,
4330
4346
  totalInsights,
4331
4347
  embedded,
4332
- coverage
4348
+ coverage,
4349
+ ...protocol !== void 0 && protocol.length <= 32 && !/[\u0000-\u001f\u007f]/u.test(protocol) ? { protocol } : {}
4333
4350
  };
4334
4351
  }
4335
4352
  async status(signal) {
@@ -6412,8 +6429,16 @@ function boundedModelText(value, maximum) {
6412
6429
  function insightDigest(result) {
6413
6430
  return sha256(result.content.trim().replace(/\s+/gu, " "));
6414
6431
  }
6415
- function recallQueryDigest(query) {
6416
- return sha256((query.match(/[\p{L}\p{N}]+/gu) ?? []).join(" ").toLocaleLowerCase());
6432
+ function recallQueryDigest(request) {
6433
+ const lexical = (request.query.match(/[\p{L}\p{N}]+/gu) ?? []).join(" ").toLocaleLowerCase();
6434
+ return sha256(JSON.stringify({
6435
+ query: lexical,
6436
+ memoryBodyIds: [...request.memoryBodyIds ?? []].sort()
6437
+ }));
6438
+ }
6439
+ /** A replay must still respect the current call's selected Source subset. */
6440
+ function replayEvidence(results, memoryBodyIds) {
6441
+ return structuredClone(memoryBodyIds === void 0 ? results : results.filter((result) => result.memoryBodyId !== void 0 && memoryBodyIds.includes(result.memoryBodyId)));
6417
6442
  }
6418
6443
  /** Admit a small, deduplicated evidence envelope after Provider quality policy. */
6419
6444
  function boundedModelInsights(results, admission = {}) {
@@ -6863,7 +6888,7 @@ var MnemonSubagentCoordinator = class {
6863
6888
  };
6864
6889
  runtimeQueue = Promise.resolve();
6865
6890
  documentQueue = Promise.resolve();
6866
- retrievalTurns = /* @__PURE__ */ new Map();
6891
+ retrievalTurns = /* @__PURE__ */ new WeakMap();
6867
6892
  constructor(subagents, runtimeMemoryOrSource, documents, resultRuntime, taskAgentModelResolver, runtimeMaintenanceMaxTokensResolver) {
6868
6893
  this.subagents = subagents;
6869
6894
  this.runtimeMemoryOrSource = runtimeMemoryOrSource;
@@ -6887,17 +6912,19 @@ var MnemonSubagentCoordinator = class {
6887
6912
  ...limit === void 0 ? {} : { limit }
6888
6913
  });
6889
6914
  }
6890
- /** Admit at most one model-facing Documents query for one root turn. */
6915
+ /** Admit at most one model-facing Documents query for one executing turn. */
6891
6916
  claimDocumentSearch(parent) {
6892
6917
  const authority = this.turnAuthority(parent, false);
6893
6918
  if (authority === void 0) return true;
6894
- const retrieval = this.turnRetrievalState(authority.turnId);
6919
+ const retrieval = this.turnRetrievalState(authority.context);
6895
6920
  if (retrieval.documentSearchClaimed === true) return false;
6896
6921
  retrieval.documentSearchClaimed = true;
6897
6922
  return true;
6898
6923
  }
6899
6924
  async recall(parent, request, signal, options = {}) {
6925
+ signal.throwIfAborted();
6900
6926
  const authority = this.recallAuthority(parent, options.requirePinnedView === true);
6927
+ const service = authority?.service ?? this.serviceFor(parent);
6901
6928
  const limited = {
6902
6929
  query: request.query,
6903
6930
  ...request.mode === void 0 ? {} : { mode: request.mode },
@@ -6905,15 +6932,15 @@ var MnemonSubagentCoordinator = class {
6905
6932
  ...request.memoryBodyIds === void 0 ? {} : { memoryBodyIds: request.memoryBodyIds }
6906
6933
  };
6907
6934
  const scoped = this.scopeRecallWithAuthority(limited, authority);
6908
- const digest = authority === void 0 ? void 0 : recallQueryDigest(scoped.query);
6909
- const retrieval = authority === void 0 ? void 0 : this.turnRetrievalState(authority.turnId);
6935
+ const digest = authority === void 0 ? void 0 : recallQueryDigest(scoped);
6936
+ const retrieval = authority === void 0 ? void 0 : this.turnRetrievalState(authority.context);
6910
6937
  const repeated = digest === void 0 ? void 0 : retrieval?.recallAttempts.find((attempt) => attempt.queryDigest === digest);
6911
6938
  if (repeated !== void 0) {
6912
6939
  const previous = repeated.result ?? await repeated.pending;
6913
6940
  return {
6914
6941
  query: previous?.query ?? scoped.query,
6915
6942
  mode: previous?.mode ?? scoped.mode ?? "smart",
6916
- results: structuredClone(previous?.results ?? []),
6943
+ results: replayEvidence(previous?.results ?? [], scoped.memoryBodyIds),
6917
6944
  hint: retrieval?.recallAttempts.length === MODEL_RECALL_ATTEMPT_LIMIT ? "This Recall query already ran. The Host replayed its admitted evidence without another Provider query. The turn Recall budget is closed; stop retrieval and answer from the evidence or state what remains unknown." : "This Recall query already ran. The Host replayed its admitted evidence without another Provider query. If this evidence is insufficient, use at most one materially different focused query; otherwise stop retrieval."
6918
6945
  };
6919
6946
  }
@@ -6923,7 +6950,7 @@ var MnemonSubagentCoordinator = class {
6923
6950
  return {
6924
6951
  query: previous?.query ?? scoped.query,
6925
6952
  mode: previous?.mode ?? scoped.mode ?? "smart",
6926
- results: structuredClone(previous?.results ?? []),
6953
+ results: replayEvidence(previous?.results ?? [], scoped.memoryBodyIds),
6927
6954
  hint: "The two-query turn Recall budget is exhausted. The Host replayed the latest admitted evidence without another Provider query; stop retrieval and answer from the evidence or state what remains unknown."
6928
6955
  };
6929
6956
  }
@@ -6933,7 +6960,8 @@ var MnemonSubagentCoordinator = class {
6933
6960
  if (attempt !== void 0 && retrieval !== void 0) retrieval.recallAttempts.push(attempt);
6934
6961
  const operation = (async () => {
6935
6962
  if (predecessor !== void 0) await predecessor;
6936
- const result = await this.serviceFor(parent).search(scoped, signal);
6963
+ signal.throwIfAborted();
6964
+ const result = await service.search(scoped, signal);
6937
6965
  const priorResults = (retrieval?.recallAttempts.slice(0, attemptIndex) ?? []).flatMap((entry) => entry.result?.results ?? []);
6938
6966
  const priorContentCharacters = priorResults.reduce((total, insight) => total + insight.content.length, 0);
6939
6967
  const requestedLimit = Math.min(limited.limit ?? MODEL_RECALL_RESULT_LIMIT, MODEL_RECALL_RESULT_LIMIT);
@@ -6974,7 +7002,7 @@ var MnemonSubagentCoordinator = class {
6974
7002
  if (attempt?.pending === operation) delete attempt.pending;
6975
7003
  }
6976
7004
  }
6977
- /** Bind a model read to the Source state pinned by its root turn. */
7005
+ /** Bind a model read to the Source state pinned by its own executing turn. */
6978
7006
  scopeRecallRequest(agent, request, requirePinnedView = false) {
6979
7007
  const authority = this.recallAuthority(agent, requirePinnedView);
6980
7008
  return this.scopeRecallWithAuthority(request, authority);
@@ -7004,9 +7032,11 @@ var MnemonSubagentCoordinator = class {
7004
7032
  return requested;
7005
7033
  }
7006
7034
  async related(parent, id, memoryBodyId, signal, options = {}) {
7035
+ signal.throwIfAborted();
7007
7036
  const authority = this.recallAuthority(parent, options.requirePinnedView === true);
7037
+ const service = authority?.service ?? this.serviceFor(parent);
7008
7038
  const selected = this.scopeRelatedWithAuthority(memoryBodyId, authority);
7009
- const retrieval = authority === void 0 ? void 0 : this.turnRetrievalState(authority.turnId);
7039
+ const retrieval = authority === void 0 ? void 0 : this.turnRetrievalState(authority.context);
7010
7040
  const reference = `${selected ?? ""}/${id}`;
7011
7041
  if (retrieval !== void 0 && !retrieval.evidenceReferences.has(reference)) return {
7012
7042
  query: `related:${id}`,
@@ -7025,13 +7055,13 @@ var MnemonSubagentCoordinator = class {
7025
7055
  return {
7026
7056
  query: previous?.query ?? `related:${id}`,
7027
7057
  mode: previous?.mode ?? "related",
7028
- results: structuredClone(previous?.results ?? []),
7058
+ results: replayEvidence(previous?.results ?? [], selected === void 0 ? void 0 : [selected]),
7029
7059
  hint: retrieval.relatedDigest === digest ? "This exact Related traversal already ran. The Host replayed its admitted evidence without another Provider query; stop retrieval and answer from it." : "Related traversal is complete for this turn. The Host replayed the admitted evidence; stop retrieval and answer from it."
7030
7060
  };
7031
7061
  }
7032
7062
  if (retrieval !== void 0 && digest !== void 0) retrieval.relatedDigest = digest;
7033
7063
  const operation = (async () => {
7034
- const admitted = boundedModelInsights(await this.serviceFor(parent).related(id, options.depth, options.edge, signal, selected), {
7064
+ const admitted = boundedModelInsights(await service.related(id, options.depth, options.edge, signal, selected), {
7035
7065
  resultLimit: 4,
7036
7066
  totalContentLimit: 4e3,
7037
7067
  mediumLimit: 4,
@@ -7630,45 +7660,38 @@ Completion protocol: call \`${resultToolName}\` exactly once with the final resu
7630
7660
  }
7631
7661
  recallAuthority(agent, required) {
7632
7662
  const authority = this.turnAuthority(agent, required);
7633
- if (authority === void 0 || !isAgentRuntimeSource$1(this.runtimeMemoryOrSource)) return void 0;
7634
- const value = optionalObject(this.runtimeMemoryOrSource.forAgent(agent).memoryViews.sourceState(authority.viewId, "memory-spaces"));
7635
- if (value === void 0 || !Array.isArray(value.memoryBodyIds) || value.memoryBodyIds.some((id) => typeof id !== "string" || id.trim() === "")) throw new Error(`pinned MemorySource has invalid recall authority: ${authority.viewId}`);
7663
+ if (authority === void 0) return void 0;
7664
+ const { context, graph } = authority;
7665
+ const value = optionalObject(graph.memoryViews.sourceState(context.viewId, "memory-spaces"));
7666
+ if (value === void 0 || !Array.isArray(value.memoryBodyIds) || value.memoryBodyIds.some((id) => typeof id !== "string" || id.trim() === "")) throw new Error(`pinned MemorySource has invalid recall authority: ${context.viewId}`);
7636
7667
  const memoryBodyIds = [...new Set(value.memoryBodyIds.map((id) => String(id).trim()))];
7637
- if (memoryBodyIds.length === 0) throw new Error(`pinned MemorySource has no recall-authorized Memory Spaces: ${authority.viewId}`);
7668
+ if (memoryBodyIds.length === 0) throw new Error(`pinned MemorySource has no recall-authorized Memory Spaces: ${context.viewId}`);
7638
7669
  return {
7639
- ...authority,
7640
- memoryBodyIds
7670
+ context,
7671
+ viewId: context.viewId,
7672
+ memoryBodyIds,
7673
+ service: graph.service
7641
7674
  };
7642
7675
  }
7643
7676
  turnAuthority(agent, required) {
7644
7677
  if (!isAgentRuntimeSource$1(this.runtimeMemoryOrSource)) return void 0;
7645
- const views = this.runtimeMemoryOrSource.forAgent(agent).memoryViews;
7646
- const parentId = isSubagent(agent) ? agent.session.header?.parentSession?.trim() : void 0;
7647
- const ownerId = parentId === void 0 || parentId === "" ? agent.id : parentId;
7648
- const pinned = views.activeTurn(ownerId);
7649
- if (pinned === void 0) {
7650
- if (required) throw new Error("Recall requires the MemorySource generation pinned to the current turn");
7651
- return;
7652
- }
7653
- return {
7654
- turnId: pinned.turnId,
7655
- viewId: pinned.viewId
7678
+ const graph = this.runtimeMemoryOrSource.forAgent(agent);
7679
+ const context = graph.memoryViews.activeTurn(agent.id);
7680
+ if (context !== void 0) return {
7681
+ context,
7682
+ graph
7656
7683
  };
7684
+ if (required) throw new Error("Recall requires the MemorySource generation pinned to the current turn");
7657
7685
  }
7658
- turnRetrievalState(turnId) {
7659
- const current = this.retrievalTurns.get(turnId);
7686
+ turnRetrievalState(context) {
7687
+ const current = this.retrievalTurns.get(context);
7660
7688
  if (current !== void 0) return current;
7661
- while (this.retrievalTurns.size >= 128) {
7662
- const oldest = this.retrievalTurns.keys().next().value;
7663
- if (oldest === void 0) break;
7664
- this.retrievalTurns.delete(oldest);
7665
- }
7666
7689
  const created = {
7667
7690
  recallAttempts: [],
7668
7691
  evidenceDigests: /* @__PURE__ */ new Set(),
7669
7692
  evidenceReferences: /* @__PURE__ */ new Set()
7670
7693
  };
7671
- this.retrievalTurns.set(turnId, created);
7694
+ this.retrievalTurns.set(context, created);
7672
7695
  return created;
7673
7696
  }
7674
7697
  recordRecall() {
@@ -7829,6 +7852,148 @@ var TurnActivityProjection = class {
7829
7852
  }
7830
7853
  };
7831
7854
  //#endregion
7855
+ //#region src/agent-memory-turn.ts
7856
+ function agentMemoryScope(agent, graph) {
7857
+ const cwd = agent.session.header?.cwd?.trim();
7858
+ return {
7859
+ storage: graph.config.storageScope,
7860
+ ...cwd === void 0 || cwd === "" ? {} : { workspaceId: resolve(cwd) },
7861
+ sessionId: agent.id,
7862
+ agentId: agent.id
7863
+ };
7864
+ }
7865
+ /** The durable log, not a parent session id, identifies the executing turn. */
7866
+ function openAgentTurn(agent) {
7867
+ let open;
7868
+ for (const event of agent.session.events) {
7869
+ const turn = typeof event.data.turn === "number" ? event.data.turn : void 0;
7870
+ if (event.type === "turn/start" && turn !== void 0) open = turn;
7871
+ else if (event.type === "turn/end" && turn === open) open = void 0;
7872
+ }
7873
+ return open;
7874
+ }
7875
+ /**
7876
+ * One Agent owns each turn pin. A child additionally retains its delegation
7877
+ * across parent completion, collection, and runtime swaps until it is disposed.
7878
+ */
7879
+ var AgentMemoryTurn = class {
7880
+ agent;
7881
+ runtime;
7882
+ delegation;
7883
+ pinned;
7884
+ pending;
7885
+ generation = 0;
7886
+ closed = false;
7887
+ releaseDelegation;
7888
+ constructor(agent, runtime, delegation) {
7889
+ this.agent = agent;
7890
+ this.runtime = runtime;
7891
+ this.delegation = delegation;
7892
+ if (delegation === void 0) return;
7893
+ const releaseView = delegation.viewId === void 0 ? void 0 : delegation.graph.memoryViews.retainView(delegation.viewId);
7894
+ try {
7895
+ const releaseRuntime = runtime.bindAgentRuntime(agent.id, delegation.graph);
7896
+ this.releaseDelegation = () => {
7897
+ try {
7898
+ releaseView?.();
7899
+ } finally {
7900
+ releaseRuntime();
7901
+ }
7902
+ };
7903
+ } catch (error) {
7904
+ releaseView?.();
7905
+ throw error;
7906
+ }
7907
+ }
7908
+ get current() {
7909
+ return this.pinned;
7910
+ }
7911
+ /** Capture now; descendants must not resolve a later parent turn on demand. */
7912
+ delegate() {
7913
+ if (this.closed) throw new Error("memory Agent lifetime has ended");
7914
+ if (this.pinned !== void 0) return {
7915
+ graph: this.pinned.graph,
7916
+ scope: this.pinned.context.scope,
7917
+ viewId: this.pinned.context.viewId
7918
+ };
7919
+ if (this.delegation !== void 0) return this.delegation;
7920
+ const graph = this.runtime.forAgent(this.agent);
7921
+ return {
7922
+ graph,
7923
+ scope: agentMemoryScope(this.agent, graph)
7924
+ };
7925
+ }
7926
+ async begin(turn, signal) {
7927
+ if (this.closed) throw new Error("memory Agent lifetime has ended");
7928
+ signal?.throwIfAborted();
7929
+ if (this.pinned?.turn === turn) return;
7930
+ if (this.pending?.turn === turn) return this.pending.result;
7931
+ this.end();
7932
+ const generation = this.generation;
7933
+ const result = this.pin(turn, generation, signal);
7934
+ this.pending = {
7935
+ turn,
7936
+ generation,
7937
+ result
7938
+ };
7939
+ try {
7940
+ await result;
7941
+ } finally {
7942
+ if (this.pending?.generation === generation) this.pending = void 0;
7943
+ }
7944
+ }
7945
+ end(turn) {
7946
+ if (turn !== void 0 && this.pinned?.turn !== turn && this.pending?.turn !== turn) return;
7947
+ this.generation += 1;
7948
+ this.pending = void 0;
7949
+ const pinned = this.pinned;
7950
+ this.pinned = void 0;
7951
+ if (pinned === void 0) return;
7952
+ try {
7953
+ if (pinned.manager.turn(pinned.context.turnId) === pinned.context) pinned.manager.endTurn(pinned.context.turnId);
7954
+ } finally {
7955
+ pinned.releaseRuntime?.();
7956
+ }
7957
+ }
7958
+ dispose() {
7959
+ if (this.closed) return;
7960
+ this.closed = true;
7961
+ try {
7962
+ this.end();
7963
+ } finally {
7964
+ this.releaseDelegation?.();
7965
+ }
7966
+ }
7967
+ async pin(turn, generation, signal) {
7968
+ const graph = this.delegation?.graph ?? this.runtime.forAgent(this.agent);
7969
+ const manager = graph.memoryViews;
7970
+ const scope = this.delegation === void 0 ? agentMemoryScope(this.agent, graph) : {
7971
+ ...this.delegation.scope,
7972
+ sessionId: this.agent.id,
7973
+ agentId: this.agent.id
7974
+ };
7975
+ const turnId = `${this.agent.id}:${turn}`;
7976
+ const context = this.delegation?.viewId === void 0 ? await manager.beginTurn(turnId, scope) : manager.pinTurn(turnId, scope, this.delegation.viewId);
7977
+ let releaseRuntime;
7978
+ try {
7979
+ if (this.closed || this.generation !== generation) throw new Error("memory turn ended during View preparation");
7980
+ signal?.throwIfAborted();
7981
+ if (this.delegation === void 0) releaseRuntime = this.runtime.bindAgentRuntime(this.agent.id, graph);
7982
+ this.pinned = {
7983
+ turn,
7984
+ graph,
7985
+ manager,
7986
+ context,
7987
+ ...releaseRuntime === void 0 ? {} : { releaseRuntime }
7988
+ };
7989
+ } catch (error) {
7990
+ if (manager.turn(context.turnId) === context) manager.endTurn(context.turnId);
7991
+ releaseRuntime?.();
7992
+ throw error;
7993
+ }
7994
+ }
7995
+ };
7996
+ //#endregion
7832
7997
  //#region src/lifecycle.ts
7833
7998
  function modelService(value) {
7834
7999
  if (typeof value !== "object" || value === null || !("currentSelection" in value) || typeof value.currentSelection !== "function") return void 0;
@@ -7935,7 +8100,7 @@ var MnemonAgentLifecycle = class {
7935
8100
  coordinator;
7936
8101
  config;
7937
8102
  counters;
7938
- runtimeSource;
8103
+ memoryTurn;
7939
8104
  primePending = true;
7940
8105
  startSource;
7941
8106
  guidedTurns = /* @__PURE__ */ new Set();
@@ -7947,6 +8112,14 @@ var MnemonAgentLifecycle = class {
7947
8112
  * actually see, which is what makes a rewind self-correcting.
7948
8113
  */
7949
8114
  cueInjected = false;
8115
+ /**
8116
+ * Text of the runtime memory snapshot most recently injected as this
8117
+ * plugin's own message. `.context()` used to get supersede-on-change for free
8118
+ * from the host's runtime-context projection; carrying the snapshot as an own
8119
+ * message means re-emitting on change is this plugin's responsibility, and
8120
+ * the rendered text (which carries the revision digest) is the key.
8121
+ */
8122
+ injectedMemoryText;
7950
8123
  idleReviewTimer;
7951
8124
  reviewController;
7952
8125
  reviewRunning = false;
@@ -7957,13 +8130,12 @@ var MnemonAgentLifecycle = class {
7957
8130
  lastPhase = "idle";
7958
8131
  lastAt;
7959
8132
  lastError;
7960
- pinnedView;
7961
- constructor(agent, coordinator, config, counters, source, runtimeSource) {
8133
+ constructor(agent, coordinator, config, counters, source, memoryTurn) {
7962
8134
  this.agent = agent;
7963
8135
  this.coordinator = coordinator;
7964
8136
  this.config = config;
7965
8137
  this.counters = counters;
7966
- this.runtimeSource = runtimeSource;
8138
+ this.memoryTurn = memoryTurn;
7967
8139
  this.startSource = source;
7968
8140
  }
7969
8141
  start() {
@@ -7981,7 +8153,7 @@ var MnemonAgentLifecycle = class {
7981
8153
  })),
7982
8154
  this.agent.ctx.on("session/event", ((session, event) => this.sessionEvent(session, event))),
7983
8155
  this.agent.ctx.on("system-prompt/assemble", ((assembly, context, next) => this.assemblePrompt(assembly, context, next))),
7984
- this.agent.ctx.on("agent/pre-step", ((payload, next) => this.preStep(payload, next))),
8156
+ this.agent.ctx.on("agent/pre-step", ((payload, next) => this.preStep(payload, next)), { prepend: true }),
7985
8157
  this.agent.ctx.on("agent/turn-stopping", ((payload) => this.finishTurn(payload)))
7986
8158
  ];
7987
8159
  return () => {
@@ -8023,7 +8195,7 @@ var MnemonAgentLifecycle = class {
8023
8195
  return assistantMessageText(this.agent.session.events, messageId);
8024
8196
  }
8025
8197
  memoryWake() {
8026
- const pinned = this.pinnedView;
8198
+ const pinned = this.memoryTurn?.current;
8027
8199
  return pinned === void 0 ? void 0 : pinned.manager.wake(pinned.context.viewId);
8028
8200
  }
8029
8201
  /**
@@ -8044,6 +8216,23 @@ var MnemonAgentLifecycle = class {
8044
8216
  for (const seq of nodes) if (isOwnUserMessageEvent(this.agent.session.events[seq])) return true;
8045
8217
  return false;
8046
8218
  }
8219
+ /**
8220
+ * The runtime memory snapshot, as this plugin's own message, when it changed.
8221
+ *
8222
+ * `.context()` used to carry this inside the host's shared runtime-context
8223
+ * projection. Carrying it here instead attributes it to dsh-mnemon and keeps
8224
+ * a memory write from re-emitting other contributors' sections; supersede
8225
+ * stays intact because the block is still a complete state replacing its
8226
+ * predecessor, keyed on the rendered text's revision digest.
8227
+ */
8228
+ memorySnapshotMessage() {
8229
+ const wake = this.memoryWake();
8230
+ if (wake === void 0) return void 0;
8231
+ const text = memoryPromptText(wake.text);
8232
+ if (text.trim() === "" || text === this.injectedMemoryText) return void 0;
8233
+ this.injectedMemoryText = text;
8234
+ return createPluginMessage(text, "recall", "Runtime memory snapshot");
8235
+ }
8047
8236
  async preStep(payload, next) {
8048
8237
  if (payload.step === 1) this.cancelIdleReview(true);
8049
8238
  const decision = await next();
@@ -8059,14 +8248,22 @@ var MnemonAgentLifecycle = class {
8059
8248
  return source.kind === "plugin" && source.plugin === "dsh-mnemon";
8060
8249
  })) return decision;
8061
8250
  if (decision.messages.length === 0) return decision;
8251
+ const snapshot = this.memorySnapshotMessage();
8252
+ const withSnapshot = (messages) => snapshot === void 0 ? messages : [...messages, snapshot];
8062
8253
  if (this.primePending) {
8063
8254
  this.primePending = false;
8064
8255
  this.counters.primes += 1;
8065
8256
  this.mark("prime");
8066
8257
  }
8067
- if (this.cueAlreadyVisible()) return decision;
8258
+ if (this.cueAlreadyVisible()) return {
8259
+ kind: "enter",
8260
+ messages: withSnapshot(decision.messages)
8261
+ };
8068
8262
  const reminder = guidedReminder(this.config);
8069
- if (reminder === void 0) return decision;
8263
+ if (reminder === void 0) return {
8264
+ kind: "enter",
8265
+ messages: withSnapshot(decision.messages)
8266
+ };
8070
8267
  this.cueInjected = true;
8071
8268
  this.guidedTurns.add(payload.turn);
8072
8269
  if (this.config.recallMode === "guided") this.counters.recallCues += 1;
@@ -8074,63 +8271,21 @@ var MnemonAgentLifecycle = class {
8074
8271
  this.mark(this.config.recallMode === "guided" ? "recall" : "writeback");
8075
8272
  return {
8076
8273
  kind: "enter",
8077
- messages: [...decision.messages, createPluginMessage(reminder, "instructions", "Optional memory recall and remember reminder")]
8274
+ messages: withSnapshot([...decision.messages, createPluginMessage(reminder, "instructions", "Optional memory recall and remember reminder")])
8078
8275
  };
8079
8276
  }
8080
8277
  async assemblePrompt(assembly, context, next) {
8081
8278
  if (context.agent !== void 0 && context.agent.id !== this.agent.id) return next();
8082
8279
  const turn = this.openTurn();
8083
8280
  if (turn === void 0 || context.signal?.aborted === true) return next();
8084
- await this.pinView(turn);
8281
+ await this.memoryTurn?.begin(turn, context.signal);
8085
8282
  return applyAgentMemoryViewWake(await next(), this.memoryWake());
8086
8283
  }
8087
8284
  openTurn() {
8088
- let open;
8089
- for (const event of this.agent.session.events) {
8090
- const turn = eventTurn(event);
8091
- if (event.type === "turn/start" && turn !== void 0) open = turn;
8092
- else if (event.type === "turn/end" && turn === open) open = void 0;
8093
- }
8094
- return open;
8095
- }
8096
- async pinView(turn) {
8097
- if (this.pinnedView?.turn === turn) return;
8098
- this.releaseView();
8099
- const graph = this.runtimeSource?.forAgent(this.agent);
8100
- const manager = graph?.memoryViews;
8101
- if (manager === void 0 || graph === void 0 || this.runtimeSource === void 0) return;
8102
- const cwd = this.agent.session.header?.cwd?.trim();
8103
- const scope = {
8104
- storage: this.config.storageScope,
8105
- ...cwd === void 0 || cwd === "" ? {} : { workspaceId: resolve(cwd) },
8106
- sessionId: this.agent.id,
8107
- agentId: this.agent.id
8108
- };
8109
- const context = await manager.beginTurn(`${this.agent.id}:${turn}`, scope);
8110
- let releaseRuntime;
8111
- try {
8112
- releaseRuntime = this.runtimeSource.bindAgentRuntime(this.agent.id, graph);
8113
- this.pinnedView = {
8114
- turn,
8115
- manager,
8116
- context,
8117
- releaseRuntime
8118
- };
8119
- } catch (error) {
8120
- manager.endTurn(context.turnId);
8121
- releaseRuntime?.();
8122
- throw error;
8123
- }
8285
+ return openAgentTurn(this.agent);
8124
8286
  }
8125
8287
  releaseView(turn) {
8126
- const pinned = this.pinnedView;
8127
- if (pinned === void 0 || turn !== void 0 && pinned.turn !== turn) return;
8128
- this.pinnedView = void 0;
8129
- try {
8130
- pinned.manager.endTurn(pinned.context.turnId);
8131
- } finally {
8132
- pinned.releaseRuntime();
8133
- }
8288
+ this.memoryTurn?.end(turn);
8134
8289
  }
8135
8290
  async finishTurn(payload) {
8136
8291
  this.scheduleIdleReview(payload.turn);
@@ -8138,7 +8293,8 @@ var MnemonAgentLifecycle = class {
8138
8293
  sessionEvent(session, event) {
8139
8294
  if (session !== this.agent.session || event.type !== "turn/end") return;
8140
8295
  const turn = eventTurn(event);
8141
- const pinned = turn === void 0 || this.pinnedView?.turn !== turn ? void 0 : this.pinnedView;
8296
+ const current = this.memoryTurn?.current;
8297
+ const pinned = turn === void 0 || current?.turn !== turn ? void 0 : current;
8142
8298
  if (pinned === void 0) return;
8143
8299
  this.releaseView(turn);
8144
8300
  pinned.manager.reconcile(pinned.context.scope).catch((error) => this.fail(error));
@@ -8267,6 +8423,8 @@ var MnemonLifecycle = class {
8267
8423
  config;
8268
8424
  runtimeSource;
8269
8425
  owners = /* @__PURE__ */ new Map();
8426
+ children = /* @__PURE__ */ new Map();
8427
+ memoryTurns = /* @__PURE__ */ new Map();
8270
8428
  counters = {
8271
8429
  primes: 0,
8272
8430
  recallCues: 0,
@@ -8291,8 +8449,11 @@ var MnemonLifecycle = class {
8291
8449
  for (const agent of this.ctx.agents.roots()) this.install(agent, "adopted");
8292
8450
  return () => {
8293
8451
  stopCreated();
8452
+ for (const dispose of [...this.children.values()].reverse()) dispose();
8294
8453
  for (const owner of [...this.owners.values()].reverse()) owner.dispose();
8454
+ this.children.clear();
8295
8455
  this.owners.clear();
8456
+ this.memoryTurns.clear();
8296
8457
  };
8297
8458
  }
8298
8459
  snapshot(sessionId, workspaceRoot) {
@@ -8634,22 +8795,93 @@ var MnemonLifecycle = class {
8634
8795
  return this.taskAgentModelRoute(fallbackSessionId, workspaceRoot)?.options;
8635
8796
  }
8636
8797
  install(agent, source) {
8637
- if (this.taskAgentIds.has(agent.id) || this.owners.has(agent) || !this.ctx.agents.roots().includes(agent)) return;
8638
- const lifecycle = new MnemonAgentLifecycle(agent, this.coordinator, this.config, this.counters, source, this.runtimeSource);
8798
+ if (this.taskAgentIds.has(agent.id) || this.owners.has(agent) || this.children.has(agent)) return;
8799
+ if (agent.session.header?.origin === "subagent") {
8800
+ this.installChild(agent);
8801
+ return;
8802
+ }
8803
+ if (!this.ctx.agents.roots().includes(agent)) return;
8804
+ const memoryTurn = this.runtimeSource === void 0 ? void 0 : new AgentMemoryTurn(agent, this.runtimeSource);
8805
+ const lifecycle = new MnemonAgentLifecycle(agent, this.coordinator, this.config, this.counters, source, memoryTurn);
8639
8806
  let dispose;
8640
8807
  dispose = agent.ctx.effect(() => {
8641
8808
  const stop = lifecycle.start();
8642
8809
  const stopRuntimeContext = this.runtimeSource === void 0 ? () => {} : registerAgentMemoryViewContext(agent, () => lifecycle.memoryWake());
8643
8810
  return () => {
8644
- stopRuntimeContext();
8645
- stop();
8646
- if (this.owners.get(agent)?.dispose === dispose) this.owners.delete(agent);
8811
+ try {
8812
+ stopRuntimeContext();
8813
+ stop();
8814
+ } finally {
8815
+ memoryTurn?.dispose();
8816
+ if (this.owners.get(agent)?.dispose === dispose) this.owners.delete(agent);
8817
+ if (this.memoryTurns.get(agent) === memoryTurn) this.memoryTurns.delete(agent);
8818
+ }
8647
8819
  };
8648
8820
  }, "dsh-mnemon.lifecycle()");
8649
8821
  this.owners.set(agent, {
8650
8822
  lifecycle,
8651
8823
  dispose
8652
8824
  });
8825
+ if (memoryTurn !== void 0) this.memoryTurns.set(agent, memoryTurn);
8826
+ }
8827
+ /** Child memory ownership is independent of root-only reminders and idle review. */
8828
+ installChild(agent) {
8829
+ const runtime = this.runtimeSource;
8830
+ const parentId = agent.session.header?.parentSession?.trim();
8831
+ const parent = parentId === void 0 || parentId === "" ? void 0 : this.ctx.agents.get(parentId);
8832
+ if (runtime === void 0 || parent === void 0 || parent === agent) return;
8833
+ const parentMemory = this.memoryTurns.get(parent);
8834
+ let delegation;
8835
+ if (parentMemory !== void 0) delegation = parentMemory.delegate();
8836
+ else {
8837
+ const graph = runtime.forAgent(parent);
8838
+ const parentPin = graph.memoryViews.activeTurn(parent.id);
8839
+ delegation = {
8840
+ graph,
8841
+ scope: parentPin?.scope ?? agentMemoryScope(parent, graph),
8842
+ ...parentPin === void 0 ? {} : { viewId: parentPin.viewId }
8843
+ };
8844
+ }
8845
+ let dispose;
8846
+ dispose = agent.ctx.effect(() => {
8847
+ const memory = new AgentMemoryTurn(agent, runtime, delegation);
8848
+ this.memoryTurns.set(agent, memory);
8849
+ const stops = [];
8850
+ const cleanup = () => {
8851
+ try {
8852
+ for (const stop of stops.reverse()) stop();
8853
+ } finally {
8854
+ try {
8855
+ memory.dispose();
8856
+ } finally {
8857
+ if (this.memoryTurns.get(agent) === memory) this.memoryTurns.delete(agent);
8858
+ if (this.children.get(agent) === dispose) this.children.delete(agent);
8859
+ }
8860
+ }
8861
+ };
8862
+ try {
8863
+ stops.push(agent.ctx.on("agent/session-start", (() => memory.end())));
8864
+ stops.push(agent.ctx.on("system-prompt/assemble", (async (_assembly, context, next) => {
8865
+ if (context.agent !== void 0 && context.agent !== agent) return next();
8866
+ const turn = openAgentTurn(agent);
8867
+ if (turn !== void 0) await memory.begin(turn, context.signal);
8868
+ return next();
8869
+ })));
8870
+ stops.push(agent.ctx.on("agent/pre-step", (async (payload, next) => {
8871
+ const decision = await next();
8872
+ if (decision.kind === "reject" || payload.signal.aborted) memory.end(payload.turn);
8873
+ return decision;
8874
+ })));
8875
+ stops.push(agent.ctx.on("session/event", ((session, event) => {
8876
+ if (session === agent.session && event.type === "turn/end") memory.end(eventTurn(event));
8877
+ })));
8878
+ } catch (error) {
8879
+ cleanup();
8880
+ throw error;
8881
+ }
8882
+ return cleanup;
8883
+ }, "dsh-mnemon.child-memory()");
8884
+ this.children.set(agent, dispose);
8653
8885
  }
8654
8886
  };
8655
8887
  //#endregion
@@ -9324,11 +9556,7 @@ const ACTIVATION_PAYLOAD_FIELDS = /* @__PURE__ */ new Set([
9324
9556
  "sessionId",
9325
9557
  "workspaceId"
9326
9558
  ]);
9327
- /**
9328
- * Expose only DSH read-routing activation to trusted Web hosts. Metadata,
9329
- * provider connections, credentials, and durable memory writes stay on the
9330
- * loopback-only write channel.
9331
- */
9559
+ /** Keep activation on a narrow, independently validated control endpoint. */
9332
9560
  function createActivationHandler(input) {
9333
9561
  return async (endpoint, rawPayload) => {
9334
9562
  try {
@@ -9566,7 +9794,7 @@ function createWriteHandler(input, lifecycle, runtimeMemory, versions) {
9566
9794
  }
9567
9795
  };
9568
9796
  }
9569
- /** Backup payloads contain private memory and use the deployment's management authority. */
9797
+ /** Backup payloads contain private memory and stay behind DSH browser authentication. */
9570
9798
  function createPackHandler(input, writeEnabled = true) {
9571
9799
  return async (endpoint, rawPayload) => {
9572
9800
  try {
@@ -9585,7 +9813,11 @@ function createPackHandler(input, writeEnabled = true) {
9585
9813
  }
9586
9814
  };
9587
9815
  }
9588
- /** Reads and activation use trusted hosts; other privileged channels require explicit promotion. */
9816
+ /**
9817
+ * Register one call shape across DSH rc.2 and 0.1.2-alpha.1. The former
9818
+ * enforces channel authority; the latter ignores the trailing options object
9819
+ * after applying its uniform browser-session authentication boundary.
9820
+ */
9589
9821
  function registerRpc(connection, input, lifecycle, runtimeMemory, storage, packs, versions, managementAuthority = "loopback") {
9590
9822
  const versionManager = versions ?? new VersionUpdateManager({ mnemonCliPath: () => findVersionCli(input) });
9591
9823
  connection.rpc.handle(MNEMON_READ_CHANNEL, createReadHandler(input, lifecycle, runtimeMemory, storage, versionManager), { authority: "trusted-host" });
@@ -9850,7 +10082,7 @@ function requireAgent(exec) {
9850
10082
  function isAgentRuntimeSource(value) {
9851
10083
  return "forAgent" in value && typeof value.forAgent === "function";
9852
10084
  }
9853
- /** Root calls delegate to a bounded child; memory-worker calls reach the deterministic service. */
10085
+ /** Model tools use the executing Agent's pinned runtime and deterministic service. */
9854
10086
  function registerTools(ctx, serviceOrSource, coordinator, runtimeMemory, documents) {
9855
10087
  const runtimeFor = (exec) => {
9856
10088
  if (isAgentRuntimeSource(serviceOrSource)) return serviceOrSource.forAgent(requireAgent(exec));
@@ -10029,7 +10261,7 @@ function registerTools(ctx, serviceOrSource, coordinator, runtimeMemory, documen
10029
10261
  }));
10030
10262
  ctx.tools.register(definition({
10031
10263
  name: "mnemon_document_search",
10032
- description: "Run one focused search over project-scoped managed Documents before durable Recall. The Host admits only one Documents query for the root turn, shared with child and parallel calls. Results contain bounded query-local evidence, not complete records. Cold archives are excluded unless a known archive reference requires them.",
10264
+ description: "Run one focused search over project-scoped managed Documents before durable Recall. The Host admits only one Documents query per executing Agent turn; parallel calls share that slot, while child turns have independent budgets. Results contain bounded query-local evidence, not complete records. Cold archives are excluded unless a known archive reference requires them.",
10033
10265
  parameters: {
10034
10266
  type: "object",
10035
10267
  properties: {
@@ -10060,7 +10292,7 @@ function registerTools(ctx, serviceOrSource, coordinator, runtimeMemory, documen
10060
10292
  includeArchived: args.includeArchived === true,
10061
10293
  notRun: true,
10062
10294
  results: [],
10063
- hint: "The root turn already used its Documents search slot, so no second disk query ran. Use the admitted evidence, make one focused mnemon_recall only if exact durable history is still missing, or answer with appropriate uncertainty."
10295
+ hint: "This Agent turn already used its Documents search slot, so no second disk query ran. Use the admitted evidence, make one focused mnemon_recall only if exact durable history is still missing, or answer with appropriate uncertainty."
10064
10296
  };
10065
10297
  const result = await controller.search(args.query, {
10066
10298
  ...args.includeArchived === void 0 ? {} : { includeArchived: args.includeArchived },