@remnic/core 9.3.680 → 9.3.682
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/access-boundary.d.ts +178 -0
- package/dist/access-boundary.js +121 -0
- package/dist/access-cli.js +115 -101
- package/dist/access-cli.js.map +1 -1
- package/dist/access-http.d.ts +1 -1
- package/dist/access-http.js +48 -46
- package/dist/access-mcp.d.ts +1 -1
- package/dist/access-mcp.js +44 -42
- package/dist/access-operations.d.ts +127 -0
- package/dist/access-operations.js +115 -0
- package/dist/access-operations.js.map +1 -0
- package/dist/access-schema.d.ts +34 -34
- package/dist/access-schema.js +6 -6
- package/dist/{access-service-S9oGKPZc.d.ts → access-service-DvA6jyHL.d.ts} +1 -1
- package/dist/access-service.d.ts +1 -1
- package/dist/access-service.js +40 -40
- package/dist/access-surface-catalog.d.ts +125 -0
- package/dist/access-surface-catalog.js +162 -0
- package/dist/access-surface-catalog.js.map +1 -0
- package/dist/adapters/index.js +7 -7
- package/dist/adapters/registry.js +3 -3
- package/dist/auto-sync-5CJBJMPZ.js +1 -1
- package/dist/briefing.js +8 -8
- package/dist/{capsule-crypto-YO5QJ6L3.js → capsule-crypto-7FJQINUR.js} +2 -2
- package/dist/capsule-crypto-7FJQINUR.js.map +1 -0
- package/dist/causal-behavior.js +5 -5
- package/dist/causal-chain.js +3 -3
- package/dist/causal-consolidation.js +16 -16
- package/dist/causal-retrieval.js +3 -3
- package/dist/causal-trajectory.js +1 -1
- package/dist/{chunk-BXLOS5AJ.js → chunk-2NLLXCJG.js} +2 -2
- package/dist/{chunk-JBPKEARU.js → chunk-2QSZNTDO.js} +7 -7
- package/dist/{chunk-3OKWZT7F.js → chunk-3IND7N4X.js} +2 -2
- package/dist/{chunk-GYSYLGNE.js → chunk-7MOTEVAA.js} +2 -2
- package/dist/{chunk-6T4LTI2F.js → chunk-7XH7VJN4.js} +4 -4
- package/dist/{chunk-AGNBY3VG.js → chunk-APJQ6UEA.js} +4 -4
- package/dist/{chunk-LZSMQHXC.js → chunk-ARLRTZZZ.js} +5 -5
- package/dist/{chunk-DL6H3D7S.js → chunk-ARV3AUOM.js} +2 -2
- package/dist/{chunk-Q2H5U37U.js → chunk-B2B2IHUH.js} +2 -2
- package/dist/{chunk-SECQS4G4.js → chunk-BTVX7ZXZ.js} +5 -5
- package/dist/{chunk-DGEZKYVI.js → chunk-DOCTITOP.js} +4 -4
- package/dist/{chunk-EQYP3HA6.js → chunk-EG4TCVMU.js} +2 -2
- package/dist/{chunk-SLTKP5WJ.js → chunk-EW5KFXHL.js} +4 -4
- package/dist/{chunk-5TEYIXMP.js → chunk-FDSOMA6M.js} +28 -41
- package/dist/chunk-FDSOMA6M.js.map +1 -0
- package/dist/{chunk-CTCPB57O.js → chunk-G7Z3C2X6.js} +2 -2
- package/dist/{chunk-OBM7EVFU.js → chunk-H4BDNIKQ.js} +53 -53
- package/dist/{chunk-MTJ2LFAJ.js → chunk-H6PMGMNP.js} +2 -2
- package/dist/{chunk-7AAKSHDG.js → chunk-I3HSKQT7.js} +136 -136
- package/dist/{chunk-NXBXM7Q6.js → chunk-I75DF4FZ.js} +2 -2
- package/dist/{chunk-RC3AFF6Z.js → chunk-JD4SCARD.js} +1 -1
- package/dist/{chunk-LVTTO3VC.js → chunk-KACIOX42.js} +2 -2
- package/dist/{chunk-VDX2J7OX.js → chunk-KQAFEZQX.js} +2 -2
- package/dist/{chunk-ATRB6Q25.js → chunk-KV6CX4ON.js} +2 -2
- package/dist/{chunk-VL5JJOOY.js → chunk-L5MUA6Q7.js} +5 -5
- package/dist/{chunk-W67ZZDHO.js → chunk-M4I3TREG.js} +75 -75
- package/dist/chunk-NHFXF4ZO.js +107 -0
- package/dist/chunk-NHFXF4ZO.js.map +1 -0
- package/dist/{chunk-MNUPGYIV.js → chunk-NQMBSSWW.js} +2 -2
- package/dist/{chunk-V4ZHKCGA.js → chunk-O2WELT5C.js} +5 -5
- package/dist/{chunk-Z6SEG36L.js → chunk-OUWAQVDJ.js} +4 -4
- package/dist/{chunk-57ME5VSI.js → chunk-Q5ZU3RNY.js} +4 -4
- package/dist/{chunk-ACYX37IM.js → chunk-QUA2JPH2.js} +6 -6
- package/dist/{chunk-DWQPM67F.js → chunk-QVWM4C24.js} +37 -32
- package/dist/chunk-QVWM4C24.js.map +1 -0
- package/dist/{chunk-2AP4QJX5.js → chunk-TOQEZ63C.js} +8 -8
- package/dist/{chunk-EUM7CZFM.js → chunk-TY5NT3T3.js} +17 -17
- package/dist/{chunk-ZCVPFDHB.js → chunk-UAODC6GJ.js} +14 -14
- package/dist/{chunk-JI6HWBYL.js → chunk-UDJLF3BO.js} +2 -2
- package/dist/{chunk-YJ4J2JJ2.js → chunk-UJDV2NLT.js} +9 -9
- package/dist/chunk-V254FAT5.js +85 -0
- package/dist/chunk-V254FAT5.js.map +1 -0
- package/dist/{chunk-3IE22DJ2.js → chunk-WEPMT6SC.js} +10 -10
- package/dist/{chunk-DQEMWVMT.js → chunk-X7Y7WX73.js} +1 -1
- package/dist/{chunk-EZ25VE3G.js → chunk-YNDLCWXS.js} +4 -4
- package/dist/{cli-B2Ve7R22.d.ts → cli-feUe-x3I.d.ts} +1 -1
- package/dist/cli.d.ts +2 -2
- package/dist/cli.js +75 -73
- package/dist/compounding/engine.js +9 -9
- package/dist/connectors/codex-materialize-runner.js +9 -9
- package/dist/connectors/index.js +9 -9
- package/dist/consolidation-provenance-check.js +2 -2
- package/dist/dashboard-runtime.js +2 -2
- package/dist/entity-retrieval.js +7 -7
- package/dist/extraction.js +2 -2
- package/dist/{first-start-migration-PG5HBC3K.js → first-start-migration-FF7YFGRP.js} +4 -4
- package/dist/index.d.ts +2 -2
- package/dist/index.js +209 -207
- package/dist/index.js.map +1 -1
- package/dist/lcm/engine.js +4 -4
- package/dist/lcm/index.js +12 -12
- package/dist/maintenance/memory-governance.js +8 -8
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +7 -7
- package/dist/maintenance/rebuild-memory-projection.js +9 -9
- package/dist/mcp-memory-inspector-app.d.ts +1 -1
- package/dist/namespaces/migrate.js +17 -17
- package/dist/namespaces/search.js +8 -8
- package/dist/namespaces/storage.js +8 -8
- package/dist/operator-toolkit.js +22 -22
- package/dist/orchestrator.js +70 -70
- package/dist/resume-bundles.js +1 -1
- package/dist/schemas.d.ts +28 -28
- package/dist/search/factory.js +7 -7
- package/dist/search/index.js +11 -11
- package/dist/search/lancedb-backend.js +3 -3
- package/dist/search/meilisearch-backend.js +3 -3
- package/dist/search/orama-backend.js +3 -3
- package/dist/semantic-consolidation.js +11 -11
- package/dist/semantic-rule-promotion.js +7 -7
- package/dist/semantic-rule-verifier.js +8 -8
- package/dist/storage.js +6 -6
- package/dist/transfer/backup.js +4 -4
- package/dist/transfer/capsule-export.js +4 -4
- package/dist/transfer/capsule-import.js +3 -3
- package/dist/transfer/import-sqlite.js +2 -2
- package/dist/transfer/types.d.ts +20 -20
- package/dist/verified-recall.js +8 -8
- package/package.json +2 -2
- package/src/access-boundary.test.ts +212 -0
- package/src/access-boundary.ts +235 -0
- package/src/access-cli.ts +32 -15
- package/src/access-http.ts +38 -28
- package/src/access-mcp.ts +41 -35
- package/src/access-operations.ts +157 -0
- package/src/access-surface-catalog.test.ts +772 -0
- package/src/access-surface-catalog.ts +218 -0
- package/dist/chunk-5TEYIXMP.js.map +0 -1
- package/dist/chunk-DWQPM67F.js.map +0 -1
- /package/dist/{capsule-crypto-YO5QJ6L3.js.map → access-boundary.js.map} +0 -0
- /package/dist/{chunk-BXLOS5AJ.js.map → chunk-2NLLXCJG.js.map} +0 -0
- /package/dist/{chunk-JBPKEARU.js.map → chunk-2QSZNTDO.js.map} +0 -0
- /package/dist/{chunk-3OKWZT7F.js.map → chunk-3IND7N4X.js.map} +0 -0
- /package/dist/{chunk-GYSYLGNE.js.map → chunk-7MOTEVAA.js.map} +0 -0
- /package/dist/{chunk-6T4LTI2F.js.map → chunk-7XH7VJN4.js.map} +0 -0
- /package/dist/{chunk-AGNBY3VG.js.map → chunk-APJQ6UEA.js.map} +0 -0
- /package/dist/{chunk-LZSMQHXC.js.map → chunk-ARLRTZZZ.js.map} +0 -0
- /package/dist/{chunk-DL6H3D7S.js.map → chunk-ARV3AUOM.js.map} +0 -0
- /package/dist/{chunk-Q2H5U37U.js.map → chunk-B2B2IHUH.js.map} +0 -0
- /package/dist/{chunk-SECQS4G4.js.map → chunk-BTVX7ZXZ.js.map} +0 -0
- /package/dist/{chunk-DGEZKYVI.js.map → chunk-DOCTITOP.js.map} +0 -0
- /package/dist/{chunk-EQYP3HA6.js.map → chunk-EG4TCVMU.js.map} +0 -0
- /package/dist/{chunk-SLTKP5WJ.js.map → chunk-EW5KFXHL.js.map} +0 -0
- /package/dist/{chunk-CTCPB57O.js.map → chunk-G7Z3C2X6.js.map} +0 -0
- /package/dist/{chunk-OBM7EVFU.js.map → chunk-H4BDNIKQ.js.map} +0 -0
- /package/dist/{chunk-MTJ2LFAJ.js.map → chunk-H6PMGMNP.js.map} +0 -0
- /package/dist/{chunk-7AAKSHDG.js.map → chunk-I3HSKQT7.js.map} +0 -0
- /package/dist/{chunk-NXBXM7Q6.js.map → chunk-I75DF4FZ.js.map} +0 -0
- /package/dist/{chunk-RC3AFF6Z.js.map → chunk-JD4SCARD.js.map} +0 -0
- /package/dist/{chunk-LVTTO3VC.js.map → chunk-KACIOX42.js.map} +0 -0
- /package/dist/{chunk-VDX2J7OX.js.map → chunk-KQAFEZQX.js.map} +0 -0
- /package/dist/{chunk-ATRB6Q25.js.map → chunk-KV6CX4ON.js.map} +0 -0
- /package/dist/{chunk-VL5JJOOY.js.map → chunk-L5MUA6Q7.js.map} +0 -0
- /package/dist/{chunk-W67ZZDHO.js.map → chunk-M4I3TREG.js.map} +0 -0
- /package/dist/{chunk-MNUPGYIV.js.map → chunk-NQMBSSWW.js.map} +0 -0
- /package/dist/{chunk-V4ZHKCGA.js.map → chunk-O2WELT5C.js.map} +0 -0
- /package/dist/{chunk-Z6SEG36L.js.map → chunk-OUWAQVDJ.js.map} +0 -0
- /package/dist/{chunk-57ME5VSI.js.map → chunk-Q5ZU3RNY.js.map} +0 -0
- /package/dist/{chunk-ACYX37IM.js.map → chunk-QUA2JPH2.js.map} +0 -0
- /package/dist/{chunk-2AP4QJX5.js.map → chunk-TOQEZ63C.js.map} +0 -0
- /package/dist/{chunk-EUM7CZFM.js.map → chunk-TY5NT3T3.js.map} +0 -0
- /package/dist/{chunk-ZCVPFDHB.js.map → chunk-UAODC6GJ.js.map} +0 -0
- /package/dist/{chunk-JI6HWBYL.js.map → chunk-UDJLF3BO.js.map} +0 -0
- /package/dist/{chunk-YJ4J2JJ2.js.map → chunk-UJDV2NLT.js.map} +0 -0
- /package/dist/{chunk-3IE22DJ2.js.map → chunk-WEPMT6SC.js.map} +0 -0
- /package/dist/{chunk-DQEMWVMT.js.map → chunk-X7Y7WX73.js.map} +0 -0
- /package/dist/{chunk-EZ25VE3G.js.map → chunk-YNDLCWXS.js.map} +0 -0
- /package/dist/{first-start-migration-PG5HBC3K.js.map → first-start-migration-FF7YFGRP.js.map} +0 -0
package/src/access-mcp.ts
CHANGED
|
@@ -9,11 +9,15 @@ import {
|
|
|
9
9
|
type CapsuleImportRequest,
|
|
10
10
|
type CapsuleListRequest,
|
|
11
11
|
type DaySummaryRequest,
|
|
12
|
-
type MemoryStoreRequest,
|
|
13
12
|
type SchemaName,
|
|
14
13
|
type SchemaTypeFor,
|
|
15
14
|
type SuggestionSubmitRequest,
|
|
16
15
|
} from "./access-schema.js";
|
|
16
|
+
// Importing access-operations registers the pilot boundary operations
|
|
17
|
+
// (memory_get / memory_search / memory_store) as a side effect; callTool
|
|
18
|
+
// dispatches migrated tools through the registry (issue #1525).
|
|
19
|
+
import { getOperation, type OperationName } from "./access-boundary.js";
|
|
20
|
+
import "./access-operations.js";
|
|
17
21
|
import { readEnvVar } from "./runtime/env.js";
|
|
18
22
|
import type { RecallDisclosure, RecallPlanMode } from "./types.js";
|
|
19
23
|
import { validateBriefingFormat } from "./briefing.js";
|
|
@@ -94,6 +98,19 @@ function withToolAliases(tool: McpTool, emitLegacyTools = true): McpTool[] {
|
|
|
94
98
|
return emitLegacyTools ? [canonicalTool, tool] : [canonicalTool];
|
|
95
99
|
}
|
|
96
100
|
|
|
101
|
+
/**
|
|
102
|
+
* MCP tool name (legacy `engram.*` form, since {@link toLegacyToolName}
|
|
103
|
+
* canonicalizes incoming calls) → boundary operation it dispatches through.
|
|
104
|
+
* A tool appears here once its `access-operations.ts` registration lands and
|
|
105
|
+
* its surface-local validation is deleted. The fitness test
|
|
106
|
+
* (`access-surface-catalog.test.ts`) asserts this map and the catalog agree.
|
|
107
|
+
*/
|
|
108
|
+
const MCP_MIGRATED_OPERATIONS: Readonly<Record<string, OperationName>> = {
|
|
109
|
+
"engram.memory_get": "memory_get",
|
|
110
|
+
"engram.memory_search": "memory_search",
|
|
111
|
+
"engram.memory_store": "memory_store",
|
|
112
|
+
};
|
|
113
|
+
|
|
97
114
|
function resolveChatGptInspectorRecallSessionKey(
|
|
98
115
|
explicitSessionKey: string | undefined,
|
|
99
116
|
authenticatedPrincipal: string | undefined,
|
|
@@ -2278,6 +2295,29 @@ export class EngramMcpServer {
|
|
|
2278
2295
|
}
|
|
2279
2296
|
|
|
2280
2297
|
private async callTool(name: string, args: Record<string, unknown>, effectivePrincipal?: string, mcpSessionId?: string): Promise<unknown> {
|
|
2298
|
+
// Migrated operations dispatch through the access boundary (issue #1525):
|
|
2299
|
+
// one registry entry owns schema validation, normalization (rules
|
|
2300
|
+
// 17/28/36/48/51), and error mapping for every surface. The switch
|
|
2301
|
+
// below still serves the not-yet-migrated tools. memory_store keeps its
|
|
2302
|
+
// parseMcpRequest strict-keys guard (MCP transport contract) before the
|
|
2303
|
+
// boundary re-validates the cleaned body.
|
|
2304
|
+
const migrated = MCP_MIGRATED_OPERATIONS[toLegacyToolName(name)];
|
|
2305
|
+
if (migrated) {
|
|
2306
|
+
const op = getOperation(migrated);
|
|
2307
|
+
if (!op) {
|
|
2308
|
+
throw new EngramAccessInputError(`access-boundary: operation not registered: ${migrated}`);
|
|
2309
|
+
}
|
|
2310
|
+
const envelope =
|
|
2311
|
+
migrated === "memory_store" ? parseMcpRequest("memoryStore", args) : args;
|
|
2312
|
+
// The registry erases In/Out at the Map boundary; the caller knows the
|
|
2313
|
+
// concrete output shape ({ result: <service response> }) so the cast is
|
|
2314
|
+
// the type-erasure seam, not a leap of faith.
|
|
2315
|
+
const output = (await op.run(envelope, {
|
|
2316
|
+
service: this.service,
|
|
2317
|
+
authenticatedPrincipal: effectivePrincipal,
|
|
2318
|
+
})) as { result: unknown };
|
|
2319
|
+
return output.result;
|
|
2320
|
+
}
|
|
2281
2321
|
switch (toLegacyToolName(name)) {
|
|
2282
2322
|
case "engram.recall": {
|
|
2283
2323
|
// Forward `disclosure` only when the caller actually supplied it,
|
|
@@ -2744,12 +2784,6 @@ export class EngramMcpServer {
|
|
|
2744
2784
|
},
|
|
2745
2785
|
effectivePrincipal,
|
|
2746
2786
|
);
|
|
2747
|
-
case "engram.memory_get":
|
|
2748
|
-
return this.service.memoryGet(
|
|
2749
|
-
typeof args.memoryId === "string" ? args.memoryId : "",
|
|
2750
|
-
typeof args.namespace === "string" ? args.namespace : undefined,
|
|
2751
|
-
effectivePrincipal,
|
|
2752
|
-
);
|
|
2753
2787
|
case "engram.memory_timeline": {
|
|
2754
2788
|
const limit = typeof args.limit === "number" && Number.isFinite(args.limit) ? args.limit : 200;
|
|
2755
2789
|
return this.service.memoryTimeline(
|
|
@@ -2759,26 +2793,6 @@ export class EngramMcpServer {
|
|
|
2759
2793
|
effectivePrincipal,
|
|
2760
2794
|
);
|
|
2761
2795
|
}
|
|
2762
|
-
case "engram.memory_store": {
|
|
2763
|
-
const body: MemoryStoreRequest = parseMcpRequest("memoryStore", args);
|
|
2764
|
-
return this.service.memoryStore({
|
|
2765
|
-
schemaVersion: body.schemaVersion,
|
|
2766
|
-
idempotencyKey: body.idempotencyKey,
|
|
2767
|
-
dryRun: body.dryRun,
|
|
2768
|
-
sessionKey: body.sessionKey,
|
|
2769
|
-
authenticatedPrincipal: effectivePrincipal,
|
|
2770
|
-
content: body.content,
|
|
2771
|
-
category: body.category,
|
|
2772
|
-
confidence: body.confidence,
|
|
2773
|
-
namespace: body.namespace,
|
|
2774
|
-
tags: body.tags,
|
|
2775
|
-
entityRef: body.entityRef,
|
|
2776
|
-
ttl: body.ttl,
|
|
2777
|
-
sourceReason: body.sourceReason,
|
|
2778
|
-
cwd: body.cwd,
|
|
2779
|
-
projectTag: body.projectTag,
|
|
2780
|
-
});
|
|
2781
|
-
}
|
|
2782
2796
|
case "engram.suggestion_submit": {
|
|
2783
2797
|
const body: SuggestionSubmitRequest = parseMcpRequest("suggestionSubmit", args);
|
|
2784
2798
|
return this.service.suggestionSubmit({
|
|
@@ -3017,14 +3031,6 @@ export class EngramMcpServer {
|
|
|
3017
3031
|
expectedGuidelineVersion: typeof args.expectedGuidelineVersion === "number" ? args.expectedGuidelineVersion : undefined,
|
|
3018
3032
|
});
|
|
3019
3033
|
// ── Memory search & debug tools ──────────────────────────────────
|
|
3020
|
-
case "engram.memory_search":
|
|
3021
|
-
return this.service.memorySearch({
|
|
3022
|
-
query: typeof args.query === "string" ? args.query : "",
|
|
3023
|
-
namespace: typeof args.namespace === "string" ? args.namespace : undefined,
|
|
3024
|
-
maxResults: typeof args.maxResults === "number" && Number.isFinite(args.maxResults) ? args.maxResults : undefined,
|
|
3025
|
-
collection: typeof args.collection === "string" ? args.collection : undefined,
|
|
3026
|
-
principal: effectivePrincipal,
|
|
3027
|
-
});
|
|
3028
3034
|
case "engram.memory_profile":
|
|
3029
3035
|
return this.service.memoryProfile(
|
|
3030
3036
|
typeof args.namespace === "string" ? args.namespace : undefined,
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pilot operation definitions for the access boundary (issue #1525).
|
|
3
|
+
*
|
|
4
|
+
* Three operations migrate through the registry in this PR — `memory_get`,
|
|
5
|
+
* `memory_search`, and the `memory_store` write op — so the boundary's
|
|
6
|
+
* normalization matrix (rules 17/28/36/48/51) and shared error mapping reach
|
|
7
|
+
* MCP, HTTP, and CLI from one place. Domain-group migrations (memory ops →
|
|
8
|
+
* connectors → namespaces …) land as follow-up PRs that add `defineOperation`
|
|
9
|
+
* calls here and delete the surface-local validation they replace.
|
|
10
|
+
*
|
|
11
|
+
* Importing this module for its side effects registers the pilot operations;
|
|
12
|
+
* surfaces then dispatch via {@link getOperation} from `./access-boundary.js`.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { z } from "zod";
|
|
16
|
+
|
|
17
|
+
import { defineOperation } from "./access-boundary.js";
|
|
18
|
+
import { memoryStoreRequestSchema, type MemoryStoreRequest } from "./access-schema.js";
|
|
19
|
+
import type {
|
|
20
|
+
EngramAccessMemoryResponse,
|
|
21
|
+
EngramAccessWriteResponse,
|
|
22
|
+
} from "./access-service.js";
|
|
23
|
+
|
|
24
|
+
// ---------------------------------------------------------------------------
|
|
25
|
+
// memory_get — fetch one memory by id
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* `memoryId` is required and non-empty (rule 51: the MCP dispatcher previously
|
|
30
|
+
* fell back to `typeof args.memoryId === "string" ? args.memoryId : ""`,
|
|
31
|
+
* silently passing an empty id into the service). `namespace` is
|
|
32
|
+
* `.nullable().optional()` because MCP clients send `null` (gotcha #2).
|
|
33
|
+
* `namespace` has no `.min(1)` because the pre-boundary handlers forwarded
|
|
34
|
+
* empty/whitespace strings, and `resolveNamespace` treats empty identically
|
|
35
|
+
* to absent (both trim to falsy → default namespace). Rejecting empty would
|
|
36
|
+
* break HTTP callers that send a bare `?namespace=` (Cursor review).
|
|
37
|
+
*/
|
|
38
|
+
const memoryGetSchema = z.object({
|
|
39
|
+
memoryId: z.string().trim().min(1, "memoryId is required").max(512),
|
|
40
|
+
namespace: z.string().trim().max(256).nullable().optional(),
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
export interface MemoryGetInput {
|
|
44
|
+
readonly memoryId: string;
|
|
45
|
+
readonly namespace?: string | null;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface MemoryGetOutput {
|
|
49
|
+
readonly result: EngramAccessMemoryResponse;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export const memoryGetOperation = defineOperation<MemoryGetInput, MemoryGetOutput>({
|
|
53
|
+
name: "memory_get",
|
|
54
|
+
description: "Fetch one memory by id.",
|
|
55
|
+
schema: memoryGetSchema,
|
|
56
|
+
handler: async (input, ctx) => {
|
|
57
|
+
const result = await ctx.service.memoryGet(
|
|
58
|
+
input.memoryId,
|
|
59
|
+
input.namespace ?? undefined,
|
|
60
|
+
ctx.authenticatedPrincipal,
|
|
61
|
+
);
|
|
62
|
+
return { result };
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// ---------------------------------------------------------------------------
|
|
67
|
+
// memory_search — semantic search across memories
|
|
68
|
+
// ---------------------------------------------------------------------------
|
|
69
|
+
|
|
70
|
+
const memorySearchSchema = z.object({
|
|
71
|
+
query: z.string().trim().min(1, "query is required").max(2048),
|
|
72
|
+
namespace: z.string().trim().max(256).nullable().optional(),
|
|
73
|
+
// No upper cap: the pre-boundary MCP handler forwarded any finite number to
|
|
74
|
+
// memorySearch, and the QMD/search backends honor large limits. Capping at
|
|
75
|
+
// 100 would reject existing clients that request larger result sets.
|
|
76
|
+
maxResults: z.number().int().min(1).nullable().optional(),
|
|
77
|
+
collection: z.string().trim().min(1).max(256).nullable().optional(),
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
export interface MemorySearchInput {
|
|
81
|
+
readonly query: string;
|
|
82
|
+
readonly namespace?: string | null;
|
|
83
|
+
readonly maxResults?: number | null;
|
|
84
|
+
readonly collection?: string | null;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export interface MemorySearchOutput {
|
|
88
|
+
readonly result: {
|
|
89
|
+
readonly query: string;
|
|
90
|
+
readonly results: ReadonlyArray<{ path: string; score: number; snippet: string }>;
|
|
91
|
+
readonly count: number;
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export const memorySearchOperation = defineOperation<MemorySearchInput, MemorySearchOutput>({
|
|
96
|
+
name: "memory_search",
|
|
97
|
+
description: "Search memories across readable namespaces.",
|
|
98
|
+
schema: memorySearchSchema,
|
|
99
|
+
handler: async (input, ctx) => {
|
|
100
|
+
const result = await ctx.service.memorySearch({
|
|
101
|
+
query: input.query,
|
|
102
|
+
namespace: input.namespace ?? undefined,
|
|
103
|
+
maxResults: input.maxResults ?? undefined,
|
|
104
|
+
collection: input.collection ?? undefined,
|
|
105
|
+
principal: ctx.authenticatedPrincipal,
|
|
106
|
+
});
|
|
107
|
+
return { result };
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
// ---------------------------------------------------------------------------
|
|
112
|
+
// memory_store — the pilot WRITE op
|
|
113
|
+
// ---------------------------------------------------------------------------
|
|
114
|
+
|
|
115
|
+
export type MemoryStoreInput = MemoryStoreRequest;
|
|
116
|
+
|
|
117
|
+
export interface MemoryStoreOutput {
|
|
118
|
+
readonly result: EngramAccessWriteResponse;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export const memoryStoreOperation = defineOperation<MemoryStoreInput, MemoryStoreOutput>({
|
|
122
|
+
name: "memory_store",
|
|
123
|
+
description: "Store an explicit memory through the access layer.",
|
|
124
|
+
// Reuse the existing schema verbatim — the migration is behavior-preserving;
|
|
125
|
+
// the schema's external contract is NOT changing in this PR (per the issue's
|
|
126
|
+
// pitfall note).
|
|
127
|
+
schema: memoryStoreRequestSchema,
|
|
128
|
+
handler: async (input, ctx) => {
|
|
129
|
+
const result = await ctx.service.memoryStore(
|
|
130
|
+
{
|
|
131
|
+
...input,
|
|
132
|
+
authenticatedPrincipal: ctx.authenticatedPrincipal,
|
|
133
|
+
},
|
|
134
|
+
// Forward transport-level hooks (e.g. HTTP's atomic write-quota gate)
|
|
135
|
+
// so the hook still fires inside the service's idempotent-write lock —
|
|
136
|
+
// never before, never on a replay (#1434 invariant preserved by the
|
|
137
|
+
// boundary migration).
|
|
138
|
+
ctx.hooks,
|
|
139
|
+
);
|
|
140
|
+
return { result };
|
|
141
|
+
},
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
// ---------------------------------------------------------------------------
|
|
145
|
+
// Surface registration map — what each transport calls the pilot ops
|
|
146
|
+
// ---------------------------------------------------------------------------
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* The canonical short names (no `engram.`/`remnic.` prefix) of the operations
|
|
150
|
+
* the boundary owns today. The fitness test treats this set as the migrated
|
|
151
|
+
* set; everything else on a surface is unmigrated and counted by the ratchet.
|
|
152
|
+
*/
|
|
153
|
+
export const REGISTERED_OPERATIONS = [
|
|
154
|
+
memoryGetOperation.spec.name,
|
|
155
|
+
memorySearchOperation.spec.name,
|
|
156
|
+
memoryStoreOperation.spec.name,
|
|
157
|
+
] as const;
|