@joshuaswarren/openclaw-engram 9.2.6 → 9.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +141 -96
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6948,7 +6948,7 @@ var GraphDashboardServer = class {
|
|
|
6948
6948
|
|
|
6949
6949
|
// src/access-http.ts
|
|
6950
6950
|
import { createServer as createServer3 } from "http";
|
|
6951
|
-
import { randomUUID, timingSafeEqual as timingSafeEqual2 } from "crypto";
|
|
6951
|
+
import { randomUUID as randomUUID2, timingSafeEqual as timingSafeEqual2 } from "crypto";
|
|
6952
6952
|
import { AsyncLocalStorage } from "async_hooks";
|
|
6953
6953
|
import { existsSync } from "fs";
|
|
6954
6954
|
import { readFile as readFile14 } from "fs/promises";
|
|
@@ -6957,6 +6957,7 @@ import { fileURLToPath, URL as URL3 } from "url";
|
|
|
6957
6957
|
|
|
6958
6958
|
// src/access-mcp.ts
|
|
6959
6959
|
import { readFile as readFile13 } from "fs/promises";
|
|
6960
|
+
import { randomUUID } from "crypto";
|
|
6960
6961
|
var MCP_PROTOCOL_VERSION = "2024-11-05";
|
|
6961
6962
|
async function getMcpServerVersion() {
|
|
6962
6963
|
const envVersion = readEnvVar("OPENCLAW_ENGRAM_VERSION")?.trim() || readEnvVar("npm_package_version")?.trim();
|
|
@@ -7611,6 +7612,33 @@ var EngramMcpServer = class {
|
|
|
7611
7612
|
flushTask = null;
|
|
7612
7613
|
tools;
|
|
7613
7614
|
authenticatedPrincipal;
|
|
7615
|
+
/**
|
|
7616
|
+
* MCP client info keyed by server-assigned session ID. On each `initialize`
|
|
7617
|
+
* handshake the server generates a UUID, stores the client's clientInfo
|
|
7618
|
+
* against it, and returns the ID as `Mcp-Session-Id` in the response
|
|
7619
|
+
* metadata. Subsequent requests from the same client include this header,
|
|
7620
|
+
* allowing per-session clientInfo lookup without cross-session leaks.
|
|
7621
|
+
*/
|
|
7622
|
+
clientInfoBySession = /* @__PURE__ */ new Map();
|
|
7623
|
+
/**
|
|
7624
|
+
* Session IDs generated during initialize, keyed by caller-supplied correlation
|
|
7625
|
+
* ID (unique per HTTP request) to avoid collisions when multiple clients send
|
|
7626
|
+
* initialize with the same JSON-RPC id concurrently.
|
|
7627
|
+
*/
|
|
7628
|
+
initSessionIds = /* @__PURE__ */ new Map();
|
|
7629
|
+
/** Get clientInfo for a specific MCP session. Returns undefined for non-MCP requests. */
|
|
7630
|
+
getClientInfo(sessionId) {
|
|
7631
|
+
if (sessionId) {
|
|
7632
|
+
return this.clientInfoBySession.get(sessionId);
|
|
7633
|
+
}
|
|
7634
|
+
return void 0;
|
|
7635
|
+
}
|
|
7636
|
+
/** Pop the session ID generated during an initialize handshake, keyed by correlation ID. */
|
|
7637
|
+
popInitSessionId(correlationId) {
|
|
7638
|
+
const sid = this.initSessionIds.get(correlationId);
|
|
7639
|
+
if (sid !== void 0) this.initSessionIds.delete(correlationId);
|
|
7640
|
+
return sid;
|
|
7641
|
+
}
|
|
7614
7642
|
async handleRequest(request, options) {
|
|
7615
7643
|
const id = request.id ?? null;
|
|
7616
7644
|
const method = request.method ?? "";
|
|
@@ -7619,7 +7647,20 @@ var EngramMcpServer = class {
|
|
|
7619
7647
|
return { jsonrpc: "2.0", id, result: {} };
|
|
7620
7648
|
}
|
|
7621
7649
|
if (method === "initialize") {
|
|
7650
|
+
const params = request.params ?? {};
|
|
7651
|
+
const rawClientInfo = params.clientInfo;
|
|
7652
|
+
const newSessionId = randomUUID();
|
|
7653
|
+
if (rawClientInfo && typeof rawClientInfo.name === "string") {
|
|
7654
|
+
const info = { name: rawClientInfo.name, version: rawClientInfo.version };
|
|
7655
|
+
this.clientInfoBySession.set(newSessionId, info);
|
|
7656
|
+
if (this.clientInfoBySession.size > 1e3) {
|
|
7657
|
+
const firstKey = this.clientInfoBySession.keys().next().value;
|
|
7658
|
+
if (firstKey) this.clientInfoBySession.delete(firstKey);
|
|
7659
|
+
}
|
|
7660
|
+
}
|
|
7622
7661
|
const version = await getMcpServerVersion();
|
|
7662
|
+
const corrId = options?.correlationId;
|
|
7663
|
+
if (corrId) this.initSessionIds.set(corrId, newSessionId);
|
|
7623
7664
|
return {
|
|
7624
7665
|
jsonrpc: "2.0",
|
|
7625
7666
|
id,
|
|
@@ -8240,123 +8281,99 @@ function validateRequest(schemaName, body) {
|
|
|
8240
8281
|
return { success: false, error: formatZodError(result.error) };
|
|
8241
8282
|
}
|
|
8242
8283
|
|
|
8284
|
+
// src/adapters/types.ts
|
|
8285
|
+
function headerValue(headers, key) {
|
|
8286
|
+
const raw = headers[key];
|
|
8287
|
+
const value = Array.isArray(raw) ? raw[0] : raw;
|
|
8288
|
+
return typeof value === "string" && value.trim().length > 0 ? value.trim() : void 0;
|
|
8289
|
+
}
|
|
8290
|
+
|
|
8243
8291
|
// src/adapters/claude-code.ts
|
|
8244
8292
|
var ClaudeCodeAdapter = class {
|
|
8245
8293
|
id = "claude-code";
|
|
8246
8294
|
matches(context) {
|
|
8247
|
-
|
|
8248
|
-
|
|
8249
|
-
|
|
8250
|
-
|
|
8295
|
+
if (context.clientInfo?.name === "claude-code") return true;
|
|
8296
|
+
const ua = headerValue(context.headers, "user-agent");
|
|
8297
|
+
if (ua && ua.toLowerCase().startsWith("claude-code/")) return true;
|
|
8298
|
+
const clientId = headerValue(context.headers, "x-engram-client-id");
|
|
8299
|
+
if (clientId?.toLowerCase() === "claude-code") return true;
|
|
8251
8300
|
return false;
|
|
8252
8301
|
}
|
|
8253
8302
|
resolveIdentity(context) {
|
|
8254
|
-
const
|
|
8255
|
-
const
|
|
8256
|
-
const namespace =
|
|
8257
|
-
const principal = headerValue(context.headers, "x-engram-principal") || context.clientInfo?.name || "claude-code";
|
|
8303
|
+
const mcpSessionId = headerValue(context.headers, "mcp-session-id");
|
|
8304
|
+
const principal = headerValue(context.headers, "x-engram-principal") || "claude-code";
|
|
8305
|
+
const namespace = headerValue(context.headers, "x-engram-namespace") || "claude-code";
|
|
8258
8306
|
return {
|
|
8259
8307
|
namespace,
|
|
8260
8308
|
principal,
|
|
8261
|
-
sessionKey:
|
|
8309
|
+
sessionKey: mcpSessionId ?? context.sessionKey,
|
|
8262
8310
|
adapterId: this.id
|
|
8263
8311
|
};
|
|
8264
8312
|
}
|
|
8265
8313
|
};
|
|
8266
|
-
function headerValue(headers, key) {
|
|
8267
|
-
const raw = headers[key];
|
|
8268
|
-
const value = Array.isArray(raw) ? raw[0] : raw;
|
|
8269
|
-
return typeof value === "string" && value.trim().length > 0 ? value.trim() : void 0;
|
|
8270
|
-
}
|
|
8271
|
-
function slugify(s) {
|
|
8272
|
-
let slug = s.toLowerCase().replace(/[^a-z0-9]+/g, "-");
|
|
8273
|
-
let start = 0;
|
|
8274
|
-
while (start < slug.length && slug[start] === "-") start++;
|
|
8275
|
-
let end = slug.length;
|
|
8276
|
-
while (end > start && slug[end - 1] === "-") end--;
|
|
8277
|
-
return slug.slice(start, end).slice(0, 80) || "claude-code";
|
|
8278
|
-
}
|
|
8279
8314
|
|
|
8280
8315
|
// src/adapters/codex.ts
|
|
8281
8316
|
var CodexAdapter = class {
|
|
8282
8317
|
id = "codex";
|
|
8283
8318
|
matches(context) {
|
|
8319
|
+
if (context.clientInfo?.name === "codex-mcp-client") return true;
|
|
8284
8320
|
const clientName = context.clientInfo?.name?.toLowerCase() ?? "";
|
|
8285
|
-
if (clientName.includes("codex")) return true;
|
|
8286
|
-
const
|
|
8287
|
-
if (
|
|
8321
|
+
if (clientName.includes("codex") && clientName !== "codex-mcp-client") return true;
|
|
8322
|
+
const clientId = headerValue(context.headers, "x-engram-client-id");
|
|
8323
|
+
if (clientId?.toLowerCase() === "codex") return true;
|
|
8288
8324
|
return false;
|
|
8289
8325
|
}
|
|
8290
8326
|
resolveIdentity(context) {
|
|
8291
|
-
const
|
|
8292
|
-
const
|
|
8293
|
-
const namespace =
|
|
8294
|
-
const principal = headerValue2(context.headers, "x-engram-principal") || agentName || context.clientInfo?.name || "codex";
|
|
8327
|
+
const mcpSessionId = headerValue(context.headers, "mcp-session-id");
|
|
8328
|
+
const principal = headerValue(context.headers, "x-engram-principal") || "codex";
|
|
8329
|
+
const namespace = headerValue(context.headers, "x-engram-namespace") || "codex";
|
|
8295
8330
|
return {
|
|
8296
8331
|
namespace,
|
|
8297
8332
|
principal,
|
|
8298
|
-
sessionKey: context.sessionKey,
|
|
8333
|
+
sessionKey: mcpSessionId ?? context.sessionKey,
|
|
8299
8334
|
adapterId: this.id
|
|
8300
8335
|
};
|
|
8301
8336
|
}
|
|
8302
8337
|
};
|
|
8303
|
-
function headerValue2(headers, key) {
|
|
8304
|
-
const raw = headers[key];
|
|
8305
|
-
const value = Array.isArray(raw) ? raw[0] : raw;
|
|
8306
|
-
return typeof value === "string" && value.trim().length > 0 ? value.trim() : void 0;
|
|
8307
|
-
}
|
|
8308
|
-
function slugify2(s) {
|
|
8309
|
-
let slug = s.toLowerCase().replace(/[^a-z0-9]+/g, "-");
|
|
8310
|
-
let start = 0;
|
|
8311
|
-
while (start < slug.length && slug[start] === "-") start++;
|
|
8312
|
-
let end = slug.length;
|
|
8313
|
-
while (end > start && slug[end - 1] === "-") end--;
|
|
8314
|
-
return slug.slice(start, end).slice(0, 80) || "codex";
|
|
8315
|
-
}
|
|
8316
8338
|
|
|
8317
8339
|
// src/adapters/replit.ts
|
|
8318
8340
|
var ReplitAdapter = class {
|
|
8319
8341
|
id = "replit";
|
|
8320
8342
|
matches(context) {
|
|
8321
|
-
|
|
8322
|
-
if (
|
|
8343
|
+
const clientId = headerValue(context.headers, "x-engram-client-id");
|
|
8344
|
+
if (clientId?.toLowerCase() === "replit") return true;
|
|
8345
|
+
const clientName = context.clientInfo?.name?.toLowerCase() ?? "";
|
|
8346
|
+
if (clientName.includes("replit")) return true;
|
|
8323
8347
|
return false;
|
|
8324
8348
|
}
|
|
8325
8349
|
resolveIdentity(context) {
|
|
8326
|
-
const
|
|
8327
|
-
const
|
|
8328
|
-
const namespace =
|
|
8329
|
-
const principal = headerValue3(context.headers, "x-engram-principal") || (userId ? `replit-user-${sanitizeId(userId)}` : "replit-agent");
|
|
8350
|
+
const mcpSessionId = headerValue(context.headers, "mcp-session-id");
|
|
8351
|
+
const principal = headerValue(context.headers, "x-engram-principal") || "replit-agent";
|
|
8352
|
+
const namespace = headerValue(context.headers, "x-engram-namespace") || "replit";
|
|
8330
8353
|
return {
|
|
8331
8354
|
namespace,
|
|
8332
8355
|
principal,
|
|
8333
|
-
sessionKey: context.sessionKey,
|
|
8356
|
+
sessionKey: mcpSessionId ?? context.sessionKey,
|
|
8334
8357
|
adapterId: this.id
|
|
8335
8358
|
};
|
|
8336
8359
|
}
|
|
8337
8360
|
};
|
|
8338
|
-
function headerValue3(headers, key) {
|
|
8339
|
-
const raw = headers[key];
|
|
8340
|
-
const value = Array.isArray(raw) ? raw[0] : raw;
|
|
8341
|
-
return typeof value === "string" && value.trim().length > 0 ? value.trim() : void 0;
|
|
8342
|
-
}
|
|
8343
|
-
function sanitizeId(s) {
|
|
8344
|
-
return s.replace(/[^a-zA-Z0-9_-]/g, "").slice(0, 64);
|
|
8345
|
-
}
|
|
8346
8361
|
|
|
8347
8362
|
// src/adapters/hermes.ts
|
|
8348
8363
|
var HermesAdapter = class {
|
|
8349
8364
|
id = "hermes";
|
|
8350
8365
|
matches(context) {
|
|
8351
|
-
if (
|
|
8352
|
-
|
|
8366
|
+
if (headerValue(context.headers, "x-hermes-session-id")) return true;
|
|
8367
|
+
const clientId = headerValue(context.headers, "x-engram-client-id");
|
|
8368
|
+
if (clientId?.toLowerCase() === "hermes") return true;
|
|
8369
|
+
const clientName = context.clientInfo?.name?.toLowerCase() ?? "";
|
|
8370
|
+
if (clientName.includes("hermes")) return true;
|
|
8353
8371
|
return false;
|
|
8354
8372
|
}
|
|
8355
8373
|
resolveIdentity(context) {
|
|
8356
|
-
const sessionId =
|
|
8357
|
-
const
|
|
8358
|
-
const namespace =
|
|
8359
|
-
const principal = headerValue4(context.headers, "x-engram-principal") || profile || "hermes-agent";
|
|
8374
|
+
const sessionId = headerValue(context.headers, "x-hermes-session-id");
|
|
8375
|
+
const principal = headerValue(context.headers, "x-engram-principal") || "hermes-agent";
|
|
8376
|
+
const namespace = headerValue(context.headers, "x-engram-namespace") || "hermes";
|
|
8360
8377
|
return {
|
|
8361
8378
|
namespace,
|
|
8362
8379
|
principal,
|
|
@@ -8365,19 +8382,6 @@ var HermesAdapter = class {
|
|
|
8365
8382
|
};
|
|
8366
8383
|
}
|
|
8367
8384
|
};
|
|
8368
|
-
function headerValue4(headers, key) {
|
|
8369
|
-
const raw = headers[key];
|
|
8370
|
-
const value = Array.isArray(raw) ? raw[0] : raw;
|
|
8371
|
-
return typeof value === "string" && value.trim().length > 0 ? value.trim() : void 0;
|
|
8372
|
-
}
|
|
8373
|
-
function slugify3(s) {
|
|
8374
|
-
let slug = s.toLowerCase().replace(/[^a-z0-9]+/g, "-");
|
|
8375
|
-
let start = 0;
|
|
8376
|
-
while (start < slug.length && slug[start] === "-") start++;
|
|
8377
|
-
let end = slug.length;
|
|
8378
|
-
while (end > start && slug[end - 1] === "-") end--;
|
|
8379
|
-
return slug.slice(start, end).slice(0, 80) || "hermes";
|
|
8380
|
-
}
|
|
8381
8385
|
|
|
8382
8386
|
// src/adapters/registry.ts
|
|
8383
8387
|
var AdapterRegistry = class {
|
|
@@ -8494,7 +8498,7 @@ var EngramAccessHttpServer = class {
|
|
|
8494
8498
|
}
|
|
8495
8499
|
if (this.server) return this.status();
|
|
8496
8500
|
const server = createServer3((req, res) => {
|
|
8497
|
-
const correlationId =
|
|
8501
|
+
const correlationId = randomUUID2();
|
|
8498
8502
|
correlationIdStore.run(correlationId, () => {
|
|
8499
8503
|
void this.handle(req, res, correlationId).catch((err) => {
|
|
8500
8504
|
log.debug(`engram access HTTP request failed [${correlationId}]: ${err}`);
|
|
@@ -8558,30 +8562,60 @@ var EngramAccessHttpServer = class {
|
|
|
8558
8562
|
}
|
|
8559
8563
|
/**
|
|
8560
8564
|
* Resolve the adapter identity for the incoming request.
|
|
8565
|
+
* Includes MCP clientInfo from the last initialize handshake if available.
|
|
8561
8566
|
* Returns null if no adapter matches or adapters are disabled.
|
|
8562
8567
|
*/
|
|
8563
8568
|
resolveAdapterIdentity(req) {
|
|
8564
8569
|
if (!this.adapterRegistry) return null;
|
|
8570
|
+
const sessionId = (() => {
|
|
8571
|
+
const raw = req.headers["mcp-session-id"];
|
|
8572
|
+
return typeof raw === "string" ? raw.trim() : void 0;
|
|
8573
|
+
})();
|
|
8565
8574
|
return this.adapterRegistry.resolve({
|
|
8566
|
-
headers: req.headers
|
|
8575
|
+
headers: req.headers,
|
|
8576
|
+
clientInfo: this.mcpServer.getClientInfo(sessionId)
|
|
8567
8577
|
});
|
|
8568
8578
|
}
|
|
8569
|
-
|
|
8579
|
+
/** Cache for per-request identity resolution (avoids double adapter resolution) */
|
|
8580
|
+
identityCache = /* @__PURE__ */ new WeakMap();
|
|
8581
|
+
/** Resolve principal and namespace from request headers and adapter identity */
|
|
8582
|
+
resolveRequestIdentity(req) {
|
|
8583
|
+
const cached = this.identityCache.get(req);
|
|
8584
|
+
if (cached) return cached;
|
|
8585
|
+
let principal;
|
|
8586
|
+
let namespace;
|
|
8570
8587
|
if (this.trustPrincipalHeader) {
|
|
8571
|
-
const
|
|
8572
|
-
const raw = Array.isArray(
|
|
8588
|
+
const headerVal = req.headers["x-engram-principal"];
|
|
8589
|
+
const raw = Array.isArray(headerVal) ? headerVal[0] : headerVal;
|
|
8573
8590
|
if (typeof raw === "string") {
|
|
8574
8591
|
const trimmed = raw.trim();
|
|
8575
8592
|
if (trimmed.length > 0) {
|
|
8576
|
-
|
|
8593
|
+
principal = trimmed;
|
|
8577
8594
|
}
|
|
8578
8595
|
}
|
|
8579
8596
|
}
|
|
8580
8597
|
const adapterIdentity = this.resolveAdapterIdentity(req);
|
|
8581
8598
|
if (adapterIdentity) {
|
|
8582
|
-
|
|
8599
|
+
if (!principal) {
|
|
8600
|
+
principal = adapterIdentity.principal;
|
|
8601
|
+
}
|
|
8602
|
+
namespace = adapterIdentity.namespace;
|
|
8583
8603
|
}
|
|
8584
|
-
|
|
8604
|
+
if (!principal) {
|
|
8605
|
+
principal = this.authenticatedPrincipal;
|
|
8606
|
+
}
|
|
8607
|
+
const result = { principal, namespace };
|
|
8608
|
+
this.identityCache.set(req, result);
|
|
8609
|
+
return result;
|
|
8610
|
+
}
|
|
8611
|
+
resolveRequestPrincipal(req) {
|
|
8612
|
+
return this.resolveRequestIdentity(req).principal;
|
|
8613
|
+
}
|
|
8614
|
+
/** Resolve namespace: only use the explicit body value. Adapter-inferred namespace
|
|
8615
|
+
* is intentionally NOT used as a fallback for REST requests — omitting namespace
|
|
8616
|
+
* should default to the server's global namespace, not silently scope to an adapter. */
|
|
8617
|
+
resolveNamespace(_req, bodyNamespace) {
|
|
8618
|
+
return bodyNamespace || void 0;
|
|
8585
8619
|
}
|
|
8586
8620
|
async handle(req, res, correlationId) {
|
|
8587
8621
|
const parsed = new URL3(req.url ?? "/", `http://${hostToUrlAuthority2(this.host)}`);
|
|
@@ -8621,7 +8655,7 @@ var EngramAccessHttpServer = class {
|
|
|
8621
8655
|
const response = await this.service.recall({
|
|
8622
8656
|
query: body.query ?? "",
|
|
8623
8657
|
sessionKey: body.sessionKey,
|
|
8624
|
-
namespace: body.namespace,
|
|
8658
|
+
namespace: this.resolveNamespace(req, body.namespace),
|
|
8625
8659
|
topK: body.topK,
|
|
8626
8660
|
mode: body.mode,
|
|
8627
8661
|
includeDebug: body.includeDebug === true
|
|
@@ -8633,7 +8667,7 @@ var EngramAccessHttpServer = class {
|
|
|
8633
8667
|
const body = await this.readValidatedBody(req, "recallExplain");
|
|
8634
8668
|
const response = await this.service.recallExplain({
|
|
8635
8669
|
sessionKey: body.sessionKey,
|
|
8636
|
-
namespace: body.namespace
|
|
8670
|
+
namespace: this.resolveNamespace(req, body.namespace)
|
|
8637
8671
|
});
|
|
8638
8672
|
this.respondJson(res, 200, response);
|
|
8639
8673
|
return;
|
|
@@ -8644,7 +8678,7 @@ var EngramAccessHttpServer = class {
|
|
|
8644
8678
|
const response = await this.service.observe({
|
|
8645
8679
|
sessionKey: body.sessionKey,
|
|
8646
8680
|
messages: body.messages,
|
|
8647
|
-
namespace: body.namespace,
|
|
8681
|
+
namespace: this.resolveNamespace(req, body.namespace),
|
|
8648
8682
|
authenticatedPrincipal: this.resolveRequestPrincipal(req),
|
|
8649
8683
|
skipExtraction: body.skipExtraction === true
|
|
8650
8684
|
});
|
|
@@ -8657,7 +8691,7 @@ var EngramAccessHttpServer = class {
|
|
|
8657
8691
|
const response = await this.service.lcmSearch({
|
|
8658
8692
|
query: body.query,
|
|
8659
8693
|
sessionKey: body.sessionKey,
|
|
8660
|
-
namespace: body.namespace,
|
|
8694
|
+
namespace: this.resolveNamespace(req, body.namespace),
|
|
8661
8695
|
authenticatedPrincipal: this.resolveRequestPrincipal(req),
|
|
8662
8696
|
limit: body.limit
|
|
8663
8697
|
});
|
|
@@ -8679,7 +8713,7 @@ var EngramAccessHttpServer = class {
|
|
|
8679
8713
|
content: body.content,
|
|
8680
8714
|
category: body.category,
|
|
8681
8715
|
confidence: body.confidence,
|
|
8682
|
-
namespace: body.namespace,
|
|
8716
|
+
namespace: this.resolveNamespace(req, body.namespace),
|
|
8683
8717
|
tags: body.tags,
|
|
8684
8718
|
entityRef: body.entityRef,
|
|
8685
8719
|
ttl: body.ttl,
|
|
@@ -8707,7 +8741,7 @@ var EngramAccessHttpServer = class {
|
|
|
8707
8741
|
content: body.content,
|
|
8708
8742
|
category: body.category,
|
|
8709
8743
|
confidence: body.confidence,
|
|
8710
|
-
namespace: body.namespace,
|
|
8744
|
+
namespace: this.resolveNamespace(req, body.namespace),
|
|
8711
8745
|
tags: body.tags,
|
|
8712
8746
|
entityRef: body.entityRef,
|
|
8713
8747
|
ttl: body.ttl,
|
|
@@ -8826,7 +8860,7 @@ var EngramAccessHttpServer = class {
|
|
|
8826
8860
|
memoryId: body.memoryId,
|
|
8827
8861
|
status: body.status,
|
|
8828
8862
|
reasonCode: body.reasonCode,
|
|
8829
|
-
namespace: body.namespace,
|
|
8863
|
+
namespace: this.resolveNamespace(req, body.namespace),
|
|
8830
8864
|
authenticatedPrincipal: this.resolveRequestPrincipal(req)
|
|
8831
8865
|
});
|
|
8832
8866
|
if (this.shouldCountWriteRateLimit(response)) {
|
|
@@ -8848,7 +8882,7 @@ var EngramAccessHttpServer = class {
|
|
|
8848
8882
|
recordedAt: body.recordedAt,
|
|
8849
8883
|
summary: body.summary,
|
|
8850
8884
|
dryRun,
|
|
8851
|
-
namespace: body.namespace,
|
|
8885
|
+
namespace: this.resolveNamespace(req, body.namespace),
|
|
8852
8886
|
authenticatedPrincipal: this.resolveRequestPrincipal(req)
|
|
8853
8887
|
});
|
|
8854
8888
|
if (this.shouldCountWriteRateLimit(response)) {
|
|
@@ -8867,7 +8901,7 @@ var EngramAccessHttpServer = class {
|
|
|
8867
8901
|
scenario: body.scenario,
|
|
8868
8902
|
recordedAt: body.recordedAt,
|
|
8869
8903
|
dryRun,
|
|
8870
|
-
namespace: body.namespace,
|
|
8904
|
+
namespace: this.resolveNamespace(req, body.namespace),
|
|
8871
8905
|
authenticatedPrincipal: this.resolveRequestPrincipal(req)
|
|
8872
8906
|
});
|
|
8873
8907
|
if (this.shouldCountWriteRateLimit(response)) {
|
|
@@ -8885,8 +8919,15 @@ var EngramAccessHttpServer = class {
|
|
|
8885
8919
|
if (isMcpWrite) {
|
|
8886
8920
|
this.ensureWriteRateLimitAvailable();
|
|
8887
8921
|
}
|
|
8922
|
+
const sessionId = (() => {
|
|
8923
|
+
const raw = req.headers["mcp-session-id"];
|
|
8924
|
+
return typeof raw === "string" ? raw.trim() : void 0;
|
|
8925
|
+
})();
|
|
8926
|
+
const mcpCorrelationId = correlationIdStore.getStore() ?? randomUUID2();
|
|
8888
8927
|
const response = await this.mcpServer.handleRequest(request, {
|
|
8889
|
-
principalOverride: this.resolveRequestPrincipal(req)
|
|
8928
|
+
principalOverride: this.resolveRequestPrincipal(req),
|
|
8929
|
+
sessionId,
|
|
8930
|
+
correlationId: mcpCorrelationId
|
|
8890
8931
|
});
|
|
8891
8932
|
if (isMcpWrite && response !== null) {
|
|
8892
8933
|
const result = response.result;
|
|
@@ -8901,6 +8942,10 @@ var EngramAccessHttpServer = class {
|
|
|
8901
8942
|
res.end();
|
|
8902
8943
|
return;
|
|
8903
8944
|
}
|
|
8945
|
+
const assignedSessionId = this.mcpServer.popInitSessionId(mcpCorrelationId);
|
|
8946
|
+
if (assignedSessionId) {
|
|
8947
|
+
res.setHeader("mcp-session-id", assignedSessionId);
|
|
8948
|
+
}
|
|
8904
8949
|
this.respondJson(res, 200, response);
|
|
8905
8950
|
}
|
|
8906
8951
|
respondJson(res, status, payload) {
|